diff --git a/server/gameserver/constant.h b/server/gameserver/constant.h index 30d0c88..b745cdb 100755 --- a/server/gameserver/constant.h +++ b/server/gameserver/constant.h @@ -74,7 +74,7 @@ const int SYS_RESET_TIME = 2*60; //每日两点重置 const int DEF_WEAPON_ID = 12103; -const int GAS_INACTIVE_TIME = 200; +const int GAS_INACTIVE_TIME = 30; const int SERVER_FRAME_RATE = 20; const int SYNC_FRAME_RATE = 10; diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 3062170..d7b0f81 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -72,9 +72,6 @@ void Human::FillMFObjectFull(cs::MFObjectFull* full_data) p->set_disconnected(disconnected); p->set_anim_type(anim_type); p->set_anim_seq(anim_seq); - #if 0 - p->set_action_type(action_type); - #endif p->set_skin(skin); p->set_backpack(backpack); p->set_helmet(helmet); @@ -248,8 +245,8 @@ void Human::UpdatePoisoning() } poisoning_time -= 1000; } - if (need_notify && entity_subtype != EST_Player) { - this->new_objects.insert(this); + if (need_notify && entity_subtype == EST_Player) { + SyncAroundPlayers(); } } @@ -283,3 +280,58 @@ void Human::SyncAroundPlayers() pair.second->new_objects.insert(this); } } + +void Human::AutoLoadingBullet(bool manual) +{ + if (curr_weapon->weapon_idx != 0 && + (curr_weapon->ammo <= 0 || + (manual && curr_weapon->ammo < curr_weapon->meta->i->clip_volume())) + ) { + MetaData::Equip* bullet_meta = MetaMgr::Instance()->GetEquip(curr_weapon->meta->i->use_bullet()); + if (bullet_meta && + bullet_meta->i->_inventory_slot() >= 0 && + bullet_meta->i->_inventory_slot() < MAX_INVENTORY_NUM + ) { + if (inventory[bullet_meta->i->_inventory_slot()] > 0) { + StartAction(AT_Reload, + curr_weapon->meta->i->reload_time(), + curr_weapon->weapon_id, + curr_weapon->weapon_idx); + } + } + return; + } +} + +void Human::StartAction(ActionType_e action_type, + int action_duration, + int item_id, + int target_id) +{ + if (this->action_type == action_type && + this->action_item_id == item_id && + this->action_target_id == target_id) { + return; + } + this->action_type = action_type; + this->action_frameno = room->frame_no; + this->action_duration = action_duration; + this->action_item_id = item_id; + this->action_target_id = target_id; + need_sync_active_player = true; +} + +void Human::CancelAction() +{ + ResetAction(); +} + +void Human::ResetAction() +{ + action_type = AT_None; + action_duration = 0; + action_frameno = 0; + action_item_id = 0; + action_target_id = 0; + need_sync_active_player = true; +} diff --git a/server/gameserver/human.h b/server/gameserver/human.h index 0698b7b..f788427 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -36,7 +36,9 @@ class Human : public Entity int anim_seq = 0; ActionType_e action_type = AT_None; long long action_frameno = 0; - long long action_duration = 0; + int action_duration = 0; + int action_item_id = 0; + int action_target_id = 0; int skin = 0; int backpack = 0; int helmet = 0; @@ -56,6 +58,8 @@ class Human : public Entity int curr_scope_idx = 0; std::vector inventory; + bool need_sync_active_player = false; + HumanFrameData frame_data; std::set new_objects; @@ -76,6 +80,13 @@ class Human : public Entity void UpdatePoisoning(); void DropItem(int item_id); void SyncAroundPlayers(); + void AutoLoadingBullet(bool manual = false); + void StartAction(ActionType_e action_type, + int action_duration, + int item_id, + int target_id); + void CancelAction(); + void ResetAction(); private: CircleCollider* self_collider_ = nullptr; diff --git a/server/gameserver/player.cc b/server/gameserver/player.cc index 83c2fda..6191dc3 100644 --- a/server/gameserver/player.cc +++ b/server/gameserver/player.cc @@ -60,6 +60,12 @@ void Player::Update(int delta_time) if (use_scope) { UpdateUseScope(); } + if (reload) { + UpdateReload(); + } + if (action_type != AT_None) { + UpdateAction(); + } MakeUpdateMsg(); SendNotifyMsg(*update_msg); { @@ -118,22 +124,79 @@ void Player::UpdateSelectWeapon() Weapon* weapon = &weapons[selected_weapon_idx]; if (weapon->weapon_id != 0) { curr_weapon = weapon; + ResetAction(); need_sync_active_player = true; for (auto& pair : room->human_hash_) { pair.second->new_objects.insert(this); } + AutoLoadingBullet(); } } select_weapon = false; selected_weapon_idx = 0; } +void Player::UpdateAction() +{ + int duration = std::max(0, + action_duration - + (int)((room->frame_no - action_frameno) * 1.0f / SERVER_FRAME_RATE) * 1000 + ); + if (duration <= 0) { + switch (action_type) { + case AT_Reload: + { + if (curr_weapon->weapon_idx == action_target_id && + curr_weapon->weapon_id == action_item_id && + curr_weapon->weapon_idx != 0) { + MetaData::Equip* bullet_meta = MetaMgr::Instance()->GetEquip(curr_weapon->meta->i->use_bullet()); + if (bullet_meta) { + int ammo = curr_weapon->ammo; + if (ammo < curr_weapon->meta->i->clip_volume()) { + if (bullet_meta->i->_inventory_slot() >= 0 && + bullet_meta->i->_inventory_slot() < MAX_INVENTORY_NUM) { + if (inventory[bullet_meta->i->_inventory_slot()] > 0) { + int add_num = 0; + if (inventory[bullet_meta->i->_inventory_slot()] <= + curr_weapon->meta->i->clip_volume() - ammo) { + add_num = inventory[bullet_meta->i->_inventory_slot()]; + inventory[bullet_meta->i->_inventory_slot()] -= add_num; + } else { + add_num = curr_weapon->meta->i->clip_volume() - ammo; + inventory[bullet_meta->i->_inventory_slot()] -= add_num; + } + curr_weapon->ammo += add_num; + need_sync_active_player = true;; + } + } + } + } + } + } + break; + } + ResetAction(); + } +} + +void Player::UpdateReload() +{ + AutoLoadingBullet(true); + reload = false; +} + void Player::Shot() { if (!curr_weapon->meta) { return; } + if (curr_weapon->weapon_idx != 0 && + curr_weapon->ammo <= 0) { + AutoLoadingBullet(); + return; + } + { cs::MFShot* shot = room->frame_data.shots.Add(); shot->set_player_id(entity_uniid); @@ -166,6 +229,7 @@ void Player::Shot() bullet->Initialize(); room->AddBullet(bullet); } + --curr_weapon->ammo; int slot_id = curr_weapon->meta->i->_inventory_slot(); switch (slot_id) { case 5: @@ -182,6 +246,7 @@ void Player::Shot() } else { curr_weapon = &weapons[0]; } + AutoLoadingBullet(); } need_sync_active_player = true; SyncAroundPlayers(); @@ -201,12 +266,14 @@ void Player::Shot() } else { curr_weapon = &weapons[0]; } + AutoLoadingBullet(); } need_sync_active_player = true; SyncAroundPlayers(); } break; } + need_sync_active_player = true; } void Player::ProcInteraction() @@ -284,6 +351,7 @@ void Player::LootInteraction(Loot* entity) weapons[0].weapon_id = entity->item_id; weapons[0].weapon_lv = 1; weapons[0].num = 0; + weapons[0].ammo = 0; need_sync_active_player = true; } need_sync_active_player = true; @@ -314,7 +382,9 @@ void Player::LootInteraction(Loot* entity) weapon->weapon_id = entity->item_id; weapon->weapon_lv = 1; weapon->num = 0; + weapon->ammo = 0; weapon->meta = item_meta; + AutoLoadingBullet(); need_sync_active_player = true; for (auto& pair : room->human_hash_) { pair.second->new_objects.insert(this); @@ -334,6 +404,7 @@ void Player::LootInteraction(Loot* entity) weapon->weapon_id = entity->item_id; weapon->weapon_lv = 1; weapon->num = 0; + weapon->ammo = 1 ; weapon->meta = item_meta; inventory[item_meta->i->_inventory_slot()] -= entity->count; } @@ -445,6 +516,9 @@ void Player::_CMMove(f8::MsgHdr& hdr, const cs::CMMove& msg) use_scope = true; use_scope_idx = msg.use_scope(); } + if (msg.has_reload()) { + reload = msg.reload(); + } } void Player::UpdateDropWeapon() @@ -540,6 +614,8 @@ void Player::UpdateDropWeapon() } } } + ResetAction(); + AutoLoadingBullet(); drop_weapon = false; drop_weapon_idx = 0; } @@ -584,6 +660,18 @@ void Player::_CMVoice(f8::MsgHdr& hdr, const cs::CMVoice& msg) void Player::FillMFActivePlayerData(cs::MFActivePlayerData* player_data) { + { + player_data->set_action_type(action_type); + if (action_type != AT_None) { + int duration = std::max(0, + action_duration - + (int)((room->frame_no - action_frameno) * 1.0f / SERVER_FRAME_RATE) * 1000 + ); + player_data->set_action_item_id(action_item_id); + player_data->set_action_duration(duration); + player_data->set_action_target_id(action_target_id); + } + } player_data->set_skin(skin); player_data->set_backpack(backpack); player_data->set_helmet(helmet); @@ -630,8 +718,6 @@ void Player::MakeUpdateMsg() } *update_msg->mutable_shots() = room->frame_data.shots; *update_msg->mutable_bullets() = room->frame_data.bullets; - //*update_msg->mutable_explosions() = room->frame_data.explosions; - //*update_msg->mutable_smokes() = room->frame_data.smokes; { for (auto& pair : room->frame_data.explosions_hash) { if (pair.first <= room->frame_no) { @@ -648,9 +734,6 @@ void Player::MakeUpdateMsg() } } } - if (update_msg->mutable_smokes()->size() > 0) { - int i = 0; - } for (auto& itr : new_objects) { itr->FillMFObjectFull(update_msg->add_full_objects()); #if 0 diff --git a/server/gameserver/player.h b/server/gameserver/player.h index 7bc8a7c..0d0e87f 100644 --- a/server/gameserver/player.h +++ b/server/gameserver/player.h @@ -49,7 +49,7 @@ class Player : public Human bool use_scope = false; int use_scope_idx = 0; - bool need_sync_active_player = false; + bool reload = false; ::google::protobuf::RepeatedField< ::google::protobuf::int32 > interaction_objids; @@ -68,6 +68,8 @@ class Player : public Human void UpdateSelectWeapon(); void UpdateDropWeapon(); void UpdateUseScope(); + void UpdateAction(); + void UpdateReload(); void Shot(); void ProcInteraction(); void ObstacleInteraction(Obstacle* entity); diff --git a/server/tools/protobuild/cs_proto.proto b/server/tools/protobuild/cs_proto.proto index a9e7f67..cd0c299 100755 --- a/server/tools/protobuild/cs_proto.proto +++ b/server/tools/protobuild/cs_proto.proto @@ -347,7 +347,7 @@ message MFObjectFull //活跃玩家数据(当前) message MFActivePlayerData { - optional int32 actoin_type = 3; //0: none 1:reload 2:useitem 3:relive + optional int32 action_type = 3; //0: none 1:reload 2:useitem 3:relive optional int32 action_duration = 5; //持续时间毫秒 optional int32 action_item_id = 6; optional int32 action_target_id = 7;