diff --git a/server/gameserver/constant.h b/server/gameserver/constant.h index a0d8733..0e3b2b9 100755 --- a/server/gameserver/constant.h +++ b/server/gameserver/constant.h @@ -166,7 +166,8 @@ enum EntitySubType_e enum PropertyType_e { - kPropTankBulletNum = 6 + kPropTankBulletNum = 6, + kPropTankOil = 7 }; const char* const PROJ_NAME_FMT = "game%d_gameserver"; diff --git a/server/gameserver/frameevent.cc b/server/gameserver/frameevent.cc index 01eddd4..49eeead 100644 --- a/server/gameserver/frameevent.cc +++ b/server/gameserver/frameevent.cc @@ -145,6 +145,20 @@ void FrameEvent::AddTankBulletNumChg(Human* hum) hum->chged_tank_bullet_nums_.push_back(idx); } +void FrameEvent::AddTankOilValueChg(Human* hum) +{ + chged_tank_oil_value_.push_back(hum); + int idx = chged_tank_oil_value_.size() - 1; + hum->chged_tank_oil_value_.push_back(idx); +} + +void FrameEvent::AddTankOilMaxChg(Human* hum) +{ + chged_tank_oil_max_.push_back(hum); + int idx = chged_tank_oil_max_.size() - 1; + hum->chged_tank_oil_max_.push_back(idx); +} + void FrameEvent::AddSmoke(Bullet* bullet, int item_id, a8::Vec2 pos) { { @@ -186,7 +200,13 @@ void FrameEvent::Clear() if (airdrops_.size() > 0) { airdrops_.Clear(); } - if (chged_tank_bullet_nums_.empty()) { + if (!chged_tank_bullet_nums_.empty()) { chged_tank_bullet_nums_.clear(); } + if (!chged_tank_oil_value_.empty()) { + chged_tank_oil_value_.clear(); + } + if (!chged_tank_oil_max_.empty()) { + chged_tank_oil_max_.clear(); + } } diff --git a/server/gameserver/frameevent.h b/server/gameserver/frameevent.h index 7285cc0..ca2b4cd 100644 --- a/server/gameserver/frameevent.h +++ b/server/gameserver/frameevent.h @@ -15,6 +15,8 @@ public: void AddSmoke(Bullet* bullet, int item_id, a8::Vec2 pos); void AddExplosionEx(Human* sender, int item_id, a8::Vec2 bomb_pos, int effect); void AddTankBulletNumChg(Human* hum); + void AddTankOilValueChg(Human* hum); + void AddTankOilMaxChg(Human* hum); void Clear(); private: @@ -25,6 +27,8 @@ private: std::vector> smokes_; std::vector> emotes_; std::vector chged_tank_bullet_nums_; + std::vector chged_tank_oil_value_; + std::vector chged_tank_oil_max_; friend class FrameMaker; }; diff --git a/server/gameserver/framemaker.cc b/server/gameserver/framemaker.cc index acbfed6..23bb935 100644 --- a/server/gameserver/framemaker.cc +++ b/server/gameserver/framemaker.cc @@ -78,6 +78,26 @@ cs::SMUpdate* FrameMaker::MakeUpdateMsg(const Human* hum) } } } + for (size_t idx : hum->chged_tank_oil_max_) { + if (idx < room->frame_event.chged_tank_oil_max_.size()) { + Human* target = room->frame_event.chged_tank_oil_max_[idx]; + auto p = msg->add_chged_property_list(); + p->set_obj_id(target->entity_uniid); + p->set_property_type(kPropTankOil); + p->set_property_subtype(1); + p->set_value(target->tank_oil_max); + } + } + for (size_t idx : hum->chged_tank_oil_value_) { + if (idx < room->frame_event.chged_tank_oil_value_.size()) { + Human* target = room->frame_event.chged_tank_oil_value_[idx]; + auto p = msg->add_chged_property_list(); + p->set_obj_id(target->entity_uniid); + p->set_property_type(kPropTankOil); + p->set_property_subtype(0); + p->set_value(target->tank_oil_value); + } + } if (room->frame_event.airdrops_.size() > 0) { *msg->mutable_airdrop() = room->frame_event.airdrops_.Get(0); } diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 305ca31..20347bb 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -1216,12 +1216,16 @@ void Human::DoGetDown() Entity* loot_entity = room->GetEntityByUniId(entity_uniid); if (loot_entity && loot_entity->entity_type == ET_Loot) { ((Loot*)loot_entity)->bullet_num = tank_weapon.ammo; + ((Loot*)loot_entity)->param1 = tank_oil_value; + ((Loot*)loot_entity)->param2 = tank_oil_max; } room->UpdateCarObject(skin_tank.tank_uniid, entity_uniid, pos); room->TakeOffCarObject(entity_uniid, pos); skin_tank = Skin(); skin_tank_meta = nullptr; tank_weapon = Weapon(); + tank_oil_value = 0.0f; + tank_oil_max = 0.0f; RecalcSelfCollider(); SyncAroundPlayers(); room->NotifyUiUpdate(); @@ -2068,6 +2072,12 @@ void Human::ClearFrameData() if (!chged_tank_bullet_nums_.empty()) { chged_tank_bullet_nums_.clear(); } + if (!chged_tank_oil_value_.empty()){ + chged_tank_oil_value_.clear(); + } + if (!chged_tank_oil_max_.empty()){ + chged_tank_oil_max_.clear(); + } } void Human::GenBattleReportData(a8::MutableXObject* params) @@ -2247,6 +2257,20 @@ void Human::SendBattleReport() void Human::ProcLootSkin(Loot* entity, MetaData::Equip* item_meta) { + auto oil_sync_func = + [] (const a8::XParams& param) + { + Human* hum = (Human*)param.sender.GetUserData(); + if (hum->skin_tank.tank_uniid != param.param1.GetInt()) { + hum->room->xtimer.DeleteTimer(hum->room->xtimer.GetRunningTimer()); + return; + } + a8::XParams& mutable_param = hum->room->xtimer.GetTimerXParams(hum->room->xtimer.GetRunningTimer()); + if (std::abs(mutable_param.param2.GetDouble() - (double)hum->tank_oil_value) > 0.1f) { + hum->room->frame_event.AddTankOilValueChg(hum); + mutable_param.param2 = hum->tank_oil_value; + } + }; if (item_meta->i->is_luck()) { if (item_meta->i->is_luck() == 2) { if (skin_tank.skin_id != 0) { @@ -2254,6 +2278,8 @@ void Human::ProcLootSkin(Loot* entity, MetaData::Equip* item_meta) Entity* loot_entity = room->GetEntityByUniId(entity_uniid); if (loot_entity && loot_entity->entity_type == ET_Loot) { ((Loot*)loot_entity)->bullet_num = tank_weapon.ammo; + ((Loot*)loot_entity)->param1 = tank_oil_value; + ((Loot*)loot_entity)->param2 = tank_oil_max; room->UpdateCarObject(skin_tank.tank_uniid, loot_entity->entity_uniid, loot_entity->pos); } } @@ -2261,6 +2287,8 @@ void Human::ProcLootSkin(Loot* entity, MetaData::Equip* item_meta) skin_tank.skin_id = item_meta->i->id(); skin_tank.skin_lv = std::max(1, GetSkinConfigLv(skin_tank.skin_id)); skin_tank_meta = item_meta; + tank_oil_value = entity->param1; + tank_oil_max = entity->param2; { tank_weapon = Weapon(); tank_weapon.weapon_idx = 100; @@ -2277,6 +2305,17 @@ void Human::ProcLootSkin(Loot* entity, MetaData::Equip* item_meta) room->TakeOnCarObject(skin_tank.tank_uniid); room->NotifyUiUpdate(); room->frame_event.AddTankBulletNumChg(this); + room->frame_event.AddTankOilMaxChg(this); + room->frame_event.AddTankOilValueChg(this); + room->xtimer.AddRepeatTimerAndAttach( + SERVER_FRAME_RATE, + a8::XParams() + .SetSender(this) + .SetParam1(skin_tank.tank_uniid) + .SetParam2(tank_oil_value), + oil_sync_func, + &xtimer_attacher.timer_list_ + ); } else { if (skin_jlf.skin_id != 0) { room->DropItem(pos, skin_jlf.skin_id, 1, skin_jlf.skin_lv); diff --git a/server/gameserver/human.h b/server/gameserver/human.h index fea8c87..63181a6 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -93,6 +93,8 @@ class Human : public Entity Weapon default_weapon; Weapon tank_weapon; + float tank_oil_value = 0.0f; + float tank_oil_max = 0.0f; std::vector weapons; Weapon* curr_weapon = nullptr; @@ -248,6 +250,8 @@ protected: std::vector explosions_; std::set observers_; std::vector chged_tank_bullet_nums_; + std::vector chged_tank_oil_value_; + std::vector chged_tank_oil_max_; Human* follow_target_ = nullptr; bool follow_synced_active_player = false; diff --git a/server/gameserver/loot.h b/server/gameserver/loot.h index ffe7754..48110e0 100644 --- a/server/gameserver/loot.h +++ b/server/gameserver/loot.h @@ -19,6 +19,8 @@ class Loot : public Entity int item_level = 0; bool pickuped = false; int bullet_num = 0; + float param1 = 0.0f; + float param2 = 0.0f; Loot(); virtual ~Loot() override; diff --git a/server/gameserver/metamgr.cc b/server/gameserver/metamgr.cc index b471462..2f1c441 100755 --- a/server/gameserver/metamgr.cc +++ b/server/gameserver/metamgr.cc @@ -117,6 +117,10 @@ public: MetaMgr::Instance()->kill_param = MetaMgr::Instance()->GetSysParamAsFloat("kill_parameter"); MetaMgr::Instance()->rank_param = MetaMgr::Instance()->GetSysParamAsFloat("rank_parameter"); MetaMgr::Instance()->fighting_mode = MetaMgr::Instance()->GetSysParamAsInt("fighting_mode", 1); + MetaMgr::Instance()->tank_damage1 = MetaMgr::Instance()->GetSysParamAsInt("tank_damage1"); + MetaMgr::Instance()->tank_damage2 = MetaMgr::Instance()->GetSysParamAsInt("tank_damage2"); + MetaMgr::Instance()->average_oil = MetaMgr::Instance()->GetSysParamAsInt("average_oil"); + MetaMgr::Instance()->max_oil = MetaMgr::Instance()->GetSysParamAsInt("max_oil"); if (MetaMgr::Instance()->K < 0.01f) { abort(); } diff --git a/server/gameserver/metamgr.h b/server/gameserver/metamgr.h index c068ce1..b4b765f 100755 --- a/server/gameserver/metamgr.h +++ b/server/gameserver/metamgr.h @@ -48,6 +48,10 @@ class MetaMgr : public a8::Singleton float kill_param = 0.0f; float rank_param = 0.0f; int fighting_mode = 0; + float tank_damage1 = 0.0f; + float tank_damage2 = 0.0f; + float average_oil = 0.0f; + float max_oil = 0.0f; private: MetaDataLoader* loader_ = nullptr; diff --git a/server/gameserver/player.cc b/server/gameserver/player.cc index bc725d1..d32a74b 100644 --- a/server/gameserver/player.cc +++ b/server/gameserver/player.cc @@ -119,12 +119,18 @@ void Player::UpdateMove() moved_frames = 0; return; } + if (tank_weapon.meta && tank_oil_value < 0.00001f) { + return; + } + a8::Vec2 old_pos = pos; _UpdateMove(std::max(1, (int)GetSpeed())); if (last_collision_door && !TestCollision(last_collision_door)) { last_collision_door = nullptr; } if (tank_weapon.meta) { CheckSkinTank(); + tank_oil_value -= old_pos.Distance(pos) * (MetaMgr::Instance()->average_oil / 100.0f); + tank_oil_value = std::max(0.0f, tank_oil_value); } } diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index f987897..5eea44d 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -360,6 +360,8 @@ void Room::CreateThings() Entity* loot_entity = GetEntityByUniId(entity_uniid); if (loot_entity && loot_entity->entity_type == ET_Loot) { ((Loot*)loot_entity)->bullet_num = equip_meta->i->clip_volume(); + ((Loot*)loot_entity)->param1 = MetaMgr::Instance()->max_oil; + ((Loot*)loot_entity)->param2 = MetaMgr::Instance()->max_oil; CarObject car; car.car_id = equip_meta->i->id(); car.pos = loot_entity->pos; diff --git a/server/tools/protobuild/cs_proto.proto b/server/tools/protobuild/cs_proto.proto index 5ef214a..7a95da2 100755 --- a/server/tools/protobuild/cs_proto.proto +++ b/server/tools/protobuild/cs_proto.proto @@ -103,6 +103,8 @@ message MFVector2D property_type: 4 技能cd时间(剩余时间) property_type: 5 技能cd时间(总时间) property_type: 6 载具剩余子弹数 + property_type: 7 载具油量 + property_subtype: 0(当前油量)1(总油量)) 在同步当前油量前必然同步过总油量! */ message MFPropertyChg {