diff --git a/server/gameserver/airraid.cc b/server/gameserver/airraid.cc index bd24e7cd..dbc25be1 100644 --- a/server/gameserver/airraid.cc +++ b/server/gameserver/airraid.cc @@ -25,7 +25,7 @@ void AirRaid::Init() ( [this] (const mt::AirRaid* air_raid, bool& stop) { - room_->xtimer.SetTimeoutEx + auto timer_wp = room_->xtimer.SetTimeoutWpEx (SERVER_FRAME_RATE * air_raid->time(), [this, air_raid] (int event, const a8::Args* args) { @@ -36,6 +36,9 @@ void AirRaid::Init() } }, &room_->xtimer_attacher_); + #ifdef DEBUG + timers_.push_back(timer_wp); + #endif }); } @@ -104,12 +107,63 @@ bool AirRaid::GenAirRaidPos(const mt::AirRaid* raid_meta, glm::vec3& center) } center = point; } - room_->frame_event.AddAirRaid(raid_meta->appear_time(), center, raid_meta->rad()); + room_->frame_event.AddAirRaid(raid_meta->appear_time(), + center, + raid_meta->rad(), + std::get<0>(raid_meta->_bombing_time) + ); return true; } void AirRaid::ExecOneRoundAirRaid(const mt::AirRaid* raid_meta, const glm::vec3& pos) { + #if 1 + int continue_time = std::get<0>(raid_meta->_bombing_time); + int interval_time = std::get<1>(raid_meta->_bombing_time); + int bomb_times = continue_time / std::max(1, interval_time); + for (int i = 0; i < bomb_times; ++i) { + glm::vec3 born_pos = pos; + int num = 1; + int delay = i * interval_time * 1000; + + auto bomb_cb = + [this, raid_meta, num, delay, born_pos] + (int event, const a8::Args* args) + { + if (a8::TIMER_EXEC_EVENT == event) { + if (room_->IsGameOver()) { + return; + } + glm::vec3 center = born_pos; + room_->map_instance->Scale(center); + glm::vec3 point; + if (room_->map_instance->FindRandomPointAroundCircle + ( + center, + 100 * room_->GetMapMeta()->scale(), + point + )) { + room_->map_instance->UnScale(point); + for (auto bomb_id : raid_meta->_bomb_ids) { + RoomObstacle* obstacle = room_->CreateObstacle + ( + bomb_id, + point.x, + point.y, + point.z + ); + obstacle->Active(); + } + } + } + }; + + room_->xtimer.SetTimeoutEx + (delay / FRAME_RATE_MS, + bomb_cb, + &room_->xtimer_attacher_); + } + #else for (auto& tuple : raid_meta->_raid_waves) { int num = std::get<0>(tuple); int delay = std::get<1>(tuple); @@ -154,4 +208,20 @@ void AirRaid::ExecOneRoundAirRaid(const mt::AirRaid* raid_meta, const glm::vec3& &room_->xtimer_attacher_); } } + #endif } + +#ifdef DEBUG + +void AirRaid::NextRaid() +{ + for (size_t i = 0; i < timers_.size(); ++i) { + auto& timer_wp = timers_.at(i); + if (!timer_wp.expired()) { + room_->xtimer.ModifyTime(timer_wp, 0); + break; + } + } +} + +#endif diff --git a/server/gameserver/airraid.h b/server/gameserver/airraid.h index df9211e3..5bfe5ae0 100644 --- a/server/gameserver/airraid.h +++ b/server/gameserver/airraid.h @@ -8,6 +8,9 @@ class AirRaid AirRaid(Room* room); void Init(); +#ifdef DEBUG + void NextRaid(); +#endif private: @@ -17,4 +20,7 @@ class AirRaid private: Room* room_ = nullptr; +#ifdef DEBUG + std::vector timers_; +#endif }; diff --git a/server/gameserver/buff/callfunc.cc b/server/gameserver/buff/callfunc.cc index e288b4a8..41dc3b37 100644 --- a/server/gameserver/buff/callfunc.cc +++ b/server/gameserver/buff/callfunc.cc @@ -22,6 +22,7 @@ void CallFuncBuff::Activate() { + hold_weapon_ = owner->GetCurrWeapon(); switch ((BuffCallFunc_e)meta->_int_buff_param1) { case BuffCallFunc_e::kAddMinorMode: { @@ -179,7 +180,7 @@ void CallFuncBuff::Deactivate() break; case BuffCallFunc_e::kSetBulletBornOffset: { - owner->GetCurrWeapon()->bullet_born_offset_ptr = nullptr; + hold_weapon_->bullet_born_offset_ptr = nullptr; } break; case BuffCallFunc_e::kImmuneAllMove: @@ -194,7 +195,7 @@ void CallFuncBuff::Deactivate() break; case BuffCallFunc_e::kSetGunBuffId: { - owner->GetCurrWeapon()->buff_id = 0; + hold_weapon_->buff_id = 0; } break; case BuffCallFunc_e::kAddEnergyShield: diff --git a/server/gameserver/buff/callfunc.h b/server/gameserver/buff/callfunc.h index c070c926..98700fe5 100644 --- a/server/gameserver/buff/callfunc.h +++ b/server/gameserver/buff/callfunc.h @@ -56,4 +56,5 @@ class CallFuncBuff : public Buff void DecSkillCd(); float hold_param2_ = 0.0; + Weapon* hold_weapon_ = nullptr; }; diff --git a/server/gameserver/commands.cc b/server/gameserver/commands.cc index d531c260..75ef0507 100644 --- a/server/gameserver/commands.cc +++ b/server/gameserver/commands.cc @@ -8,6 +8,7 @@ #include "ability.h" #include "movement.h" #include "android.h" +#include "airraid.h" #include "cs_proto.pb.h" @@ -170,6 +171,11 @@ void Player::_CMExecCommand(f8::MsgHdr& hdr, const cs::CMExecCommand& msg) #if DEBUG room->debug_params[121] = 1; #endif + } else if (cmd == "next_raid") { + #if DEBUG + room->debug_params[121] = 1; + room->GetAirRaid()->NextRaid(); + #endif } else if (cmd == "autodie") { #if DEBUG if (cmds.size() >= 2) { @@ -287,4 +293,7 @@ void Player::_CMExecCommand(f8::MsgHdr& hdr, const cs::CMExecCommand& msg) skill->Accelerate(-10000000); } } +#ifdef DEBUG + a8::XPrintf("exec_cmd:%s\n", {cmd}); +#endif } diff --git a/server/gameserver/creature.cc b/server/gameserver/creature.cc index 2ed541d5..d8c68bb5 100644 --- a/server/gameserver/creature.cc +++ b/server/gameserver/creature.cc @@ -1674,10 +1674,11 @@ void Creature::SetCurrWeapon(Weapon* weapon) if (!auto_switch_weapon_timer_.expired()) { room->xtimer.Delete(auto_switch_weapon_timer_); } - if (curr_weapon_ != weapon) { - GetTrigger()->TakeonWeapon(curr_weapon_, weapon); - } + Weapon* old_weapon = curr_weapon_; curr_weapon_ = weapon; + if (old_weapon != weapon) { + GetTrigger()->TakeonWeapon(old_weapon, weapon); + } if (need_recalc) { RecalcDtoAttr(); } diff --git a/server/gameserver/frameevent.cc b/server/gameserver/frameevent.cc index 18d3ce29..dddf9f7d 100644 --- a/server/gameserver/frameevent.cc +++ b/server/gameserver/frameevent.cc @@ -21,11 +21,12 @@ void FrameEvent::AddAirDrop(int appear_time, int box_id, const glm::vec3& box_po TypeConvert::ToPb(box_pos, airdrop->mutable_pos()); } -void FrameEvent::AddAirRaid(int appear_time, const glm::vec3& raid_pos, float raid_rad) +void FrameEvent::AddAirRaid(int appear_time, const glm::vec3& raid_pos, float raid_rad, int continue_time) { cs::MFAirRaid* airraid = room->frame_event_data->airraids_.Add(); airraid->set_appear_time(appear_time); airraid->set_rad(raid_rad); + airraid->set_continue_time(continue_time); TypeConvert::ToPb(raid_pos, airraid->mutable_pos()); } diff --git a/server/gameserver/frameevent.h b/server/gameserver/frameevent.h index a9083dd9..5b7b916c 100644 --- a/server/gameserver/frameevent.h +++ b/server/gameserver/frameevent.h @@ -14,7 +14,7 @@ public: Room* room = nullptr; void AddAirDrop(int appear_time, int box_id, const glm::vec3& box_pos); - void AddAirRaid(int appear_time, const glm::vec3& raid_pos, float raid_rad); + void AddAirRaid(int appear_time, const glm::vec3& raid_pos, float raid_rad, int continue_time); void AddEmote(CreatureWeakPtr& sender, int emote_id); void AddShot(CreatureWeakPtr& sender); void AddBullet(int bullet_uniid, diff --git a/server/gameserver/guide.cc b/server/gameserver/guide.cc index 1ee30861..f3493d88 100644 --- a/server/gameserver/guide.cc +++ b/server/gameserver/guide.cc @@ -27,11 +27,7 @@ void Guide::Init(Human* owner) UpdateStep(); owner_->room->xtimer.SetTimeoutEx ( - #ifdef DEBUG - SERVER_FRAME_RATE * 1, - #else SERVER_FRAME_RATE * 60 * 10, - #endif [this] (int event, const a8::Args* args) { if (a8::TIMER_EXEC_EVENT == event) { diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index fbb64c27..24ed1504 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -2581,12 +2581,22 @@ void Human::ProcLootWeapon(AddItemDTO& dto) if (FreezeOperate()) { return; } + bool droped = false; if (weapons[GUN_SLOT1].weapon_id != 0 && weapons[GUN_SLOT2].weapon_id != 0) { if (GetCurrWeapon() == &weapons[GUN_SLOT1]) { - DropWeapon(GUN_SLOT2, 1); + if (mt::Param::s().pickup_weapon_replace_type) { + DropWeapon(GUN_SLOT2, 1); + } else { + DropWeapon(GUN_SLOT1, 1); + } } else { - DropWeapon(GUN_SLOT1, 1); + if (mt::Param::s().pickup_weapon_replace_type) { + DropWeapon(GUN_SLOT1, 1); + } else { + DropWeapon(GUN_SLOT2, 1); + } } + droped = true; } bool switch_gun = false; Weapon* weapon = TakeonWeapon(dto.item_meta); @@ -2598,6 +2608,9 @@ void Human::ProcLootWeapon(AddItemDTO& dto) if (!weapon) { return; } + if (droped && !mt::Param::s().pickup_weapon_replace_type) { + switch_gun = true; + } weapon->weapon_id = dto.item_id; weapon->meta = dto.item_meta; weapon->ammo = 0; diff --git a/server/gameserver/mt/AirRaid.cc b/server/gameserver/mt/AirRaid.cc index 9c382b94..990a1571 100644 --- a/server/gameserver/mt/AirRaid.cc +++ b/server/gameserver/mt/AirRaid.cc @@ -28,6 +28,18 @@ namespace mt ); } } + { + std::vector strings; + a8::Split(bombing_time(), strings, ':'); + if (strings.size() == 0) { + _bombing_time = std::make_tuple(0, 0); + } else if (strings.size() == 2) { + _bombing_time = std::make_tuple(a8::XValue(strings[0]).GetInt(), + a8::XValue(strings[1]).GetInt()); + } else { + abort(); + } + } } } diff --git a/server/gameserver/mt/AirRaid.h b/server/gameserver/mt/AirRaid.h index 5242ab4b..f539613c 100644 --- a/server/gameserver/mt/AirRaid.h +++ b/server/gameserver/mt/AirRaid.h @@ -15,6 +15,7 @@ namespace mt std::vector> _raid_waves; std::vector _bomb_ids; + std::tuple _bombing_time; }; diff --git a/server/gameserver/mt/Param.cc b/server/gameserver/mt/Param.cc index 83d9a79c..0a30e7ae 100644 --- a/server/gameserver/mt/Param.cc +++ b/server/gameserver/mt/Param.cc @@ -36,6 +36,7 @@ namespace mt s_.match_robot_time = GetIntParam("match_robot_time", 0); s_.match_choose_time = GetIntParam("match_choose_time", 0); s_.match_lock_time = GetIntParam("match_lock_time", 0); + s_.pickup_weapon_replace_type = GetIntParam("pickup_weapon_replace_type", 0); #if 1 s_.match_lock_time++; #endif diff --git a/server/gameserver/mt/Param.h b/server/gameserver/mt/Param.h index 870e1657..09b08679 100644 --- a/server/gameserver/mt/Param.h +++ b/server/gameserver/mt/Param.h @@ -25,6 +25,7 @@ namespace mt int newbie_room_weapon_id = 0; std::vector newbie_room_skills; std::vector newbie_room_area; + int pickup_weapon_replace_type = 0; int downed_relive_recover_hp = 0; diff --git a/server/gameserver/mtb/AirRaid.h b/server/gameserver/mtb/AirRaid.h index e9956e5c..7aaa40ef 100644 --- a/server/gameserver/mtb/AirRaid.h +++ b/server/gameserver/mtb/AirRaid.h @@ -16,6 +16,8 @@ namespace mtb const std::string bomb_id() const { return bomb_id_; }; const std::string raid_wave() const { return raid_wave_; }; float rad() const { return rad_; }; + const std::string bombing_time() const { return bombing_time_; }; + float damage() const { return damage_; }; bool has_id() const { return __flags__.test(0);}; bool has_time() const { return __flags__.test(1);}; @@ -23,6 +25,8 @@ namespace mtb bool has_bomb_id() const { return __flags__.test(3);}; bool has_raid_wave() const { return __flags__.test(4);}; bool has_rad() const { return __flags__.test(5);}; + bool has_bombing_time() const { return __flags__.test(6);}; + bool has_damage() const { return __flags__.test(7);}; protected: @@ -32,9 +36,11 @@ namespace mtb std::string bomb_id_; std::string raid_wave_; float rad_ = 0.0f; + std::string bombing_time_; + float damage_ = 0.0f; public: - std::bitset<6> __flags__; + std::bitset<8> __flags__; }; }; diff --git a/server/gameserver/mtb/mtb.all.cc b/server/gameserver/mtb/mtb.all.cc index 7811255b..e4afea28 100644 --- a/server/gameserver/mtb/mtb.all.cc +++ b/server/gameserver/mtb/mtb.all.cc @@ -521,13 +521,15 @@ namespace mtb { a8::reflect::Class* meta_class = nullptr; if (!meta_class) { - meta_class = new a8::reflect::Class("AirRaid", 6, 0); + meta_class = new a8::reflect::Class("AirRaid", 8, 0); meta_class->SetSimpleField(0, "id", a8::reflect::ET_INT32, my_offsetof2(AirRaid, id_)); meta_class->SetSimpleField(1, "time", a8::reflect::ET_INT32, my_offsetof2(AirRaid, time_)); meta_class->SetSimpleField(2, "appear_time", a8::reflect::ET_INT32, my_offsetof2(AirRaid, appear_time_)); meta_class->SetSimpleField(3, "bomb_id", a8::reflect::ET_STRING, my_offsetof2(AirRaid, bomb_id_)); meta_class->SetSimpleField(4, "raid_wave", a8::reflect::ET_STRING, my_offsetof2(AirRaid, raid_wave_)); meta_class->SetSimpleField(5, "rad", a8::reflect::ET_FLOAT, my_offsetof2(AirRaid, rad_)); + meta_class->SetSimpleField(6, "bombing_time", a8::reflect::ET_STRING, my_offsetof2(AirRaid, bombing_time_)); + meta_class->SetSimpleField(7, "damage", a8::reflect::ET_FLOAT, my_offsetof2(AirRaid, damage_)); } return meta_class; } diff --git a/server/gameserver/room.h b/server/gameserver/room.h index 05155e48..b557f9b2 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -238,6 +238,7 @@ public: int GetReportRoomMode(); int GetPvpMatchMode(); void ForceOver(); + std::shared_ptr GetAirRaid() { return air_raid_; } private: void ShuaAndroid(); diff --git a/server/gameserver/roomobstacle.cc b/server/gameserver/roomobstacle.cc index 43665f53..313ebbd4 100644 --- a/server/gameserver/roomobstacle.cc +++ b/server/gameserver/roomobstacle.cc @@ -392,16 +392,16 @@ void RoomObstacle::DetachFromMaster() { if (!detached_) { detached_ = true; + xtimer_attacher.ClearTimerList(); if (master.Get()) { - xtimer_attacher.ClearTimerList(); master.Get()->SlaveOnRemove(this); - room->grid_service->DelRoomEntity(room, this); - if (!IsDead(room)) { - Die(room); - BroadcastFullState(room); - } - room->RemoveObjectLater(this); } + room->grid_service->DelRoomEntity(room, this); + if (!IsDead(room)) { + Die(room); + BroadcastFullState(room); + } + room->RemoveObjectLater(this); } if (!list_empty(&entry)) { list_del_init(&entry); diff --git a/server/tools/protobuild/cs_proto.proto b/server/tools/protobuild/cs_proto.proto index 80afdb78..835515d9 100755 --- a/server/tools/protobuild/cs_proto.proto +++ b/server/tools/protobuild/cs_proto.proto @@ -834,6 +834,7 @@ message MFAirRaid optional int32 appear_time = 1; //空袭出现时间(毫秒) optional MFVec3 pos = 3; //空袭位置 optional float rad = 4; //空袭半径 + optional int32 continue_time = 5; //轰炸持续时间,(在空袭出现后!!!) } //buff diff --git a/server/tools/protobuild/mt.proto b/server/tools/protobuild/mt.proto index 9eadd4d9..044cbfe3 100755 --- a/server/tools/protobuild/mt.proto +++ b/server/tools/protobuild/mt.proto @@ -417,6 +417,8 @@ message AirRaid optional string bomb_id = 4; optional string raid_wave = 5; optional float rad = 6; + optional string bombling_time = 7; + optional float damage = 8; } message AirLine