diff --git a/server/gameserver/building.cc b/server/gameserver/building.cc index f37047e..7423834 100644 --- a/server/gameserver/building.cc +++ b/server/gameserver/building.cc @@ -35,11 +35,30 @@ void Building::RecalcSelfCollider() colliders.push_back(collider); } for (auto& obj : meta->doors) { - #if 0 - MetaData::MapThing* thing = MetaMgr::Instance()->GetMapThing(obj.id()); + MetaData::MapThing* thing = MetaMgr::Instance()->GetMapThing(61018); if (thing) { + Obstacle* entity = new Obstacle(); + entity->room = room; + entity->meta = thing; + entity->entity_uniid = room->AllocUniid(); + entity->is_door = true; + entity->door_id = obj.door_id; + entity->door_state = DoorStateClose; + entity->building = this; + entity->door_house_uniid = entity_uniid; + entity->door_state0 = obj.state0; + entity->door_state1 = obj.state1; + #if 1 + entity->pos = Vector2D(pos.x + entity->door_state0->x() - meta->i->tilewidth() / 2.0, + pos.y + entity->door_state0->y() - meta->i->tileheight() / 2.0); + #endif + entity->Initialize(); + room->uniid_hash_[entity->entity_uniid] = entity; + for (auto& pair : room->human_hash_) { + pair.second->new_objects.insert(entity); + pair.second->part_objects.insert(entity); + } } - #endif } for (auto& obj : meta->i->lootobj()) { MetaData::MapThing* thing = MetaMgr::Instance()->GetMapThing(obj.id()); diff --git a/server/gameserver/constant.h b/server/gameserver/constant.h index 640ab05..73c3afc 100755 --- a/server/gameserver/constant.h +++ b/server/gameserver/constant.h @@ -44,6 +44,12 @@ enum SyncData_e SYNC_Data_Exp = 0, }; +enum DoorState_e +{ + DoorStateClose = 0, + DoorStateOpen = 1 +}; + const char* const PROJ_NAME_FMT = "game%d_gameserver"; const char* const PROJ_ROOT_FMT = "/data/logs/%s"; diff --git a/server/gameserver/metadata.cc b/server/gameserver/metadata.cc index 4e417ad..23fb135 100644 --- a/server/gameserver/metadata.cc +++ b/server/gameserver/metadata.cc @@ -68,4 +68,40 @@ namespace MetaData } } + void Building::Init() + { + for (auto& door_meta : i->doorobj()) { + Door* p_door = nullptr; + for (auto& door : doors) { + if (door.door_id == door_meta.id()) { + p_door = &door; + break; + } + } + if (!p_door) { + p_door = &a8::FastAppend(doors); + p_door->door_id = door_meta.id(); + } + switch (door_meta.type()) { + case 1: + { + p_door->state0 = &door_meta; + } + break; + case 2: + { + p_door->state1 = &door_meta; + } + break; + } + }//end for + + for (auto& door : doors) { + if (door.door_id == 0 || + !door.state0 || !door.state1) { + abort(); + } + } + } + } diff --git a/server/gameserver/metadata.h b/server/gameserver/metadata.h index 8f5718c..124c9e3 100755 --- a/server/gameserver/metadata.h +++ b/server/gameserver/metadata.h @@ -47,12 +47,13 @@ namespace MetaData int door_id = 0; const metatable::DoorObjJson* state0 = nullptr; const metatable::DoorObjJson* state1 = nullptr; - const metatable::DoorObjJson* state2 = nullptr; }; const metatable::BuildingJson* i = nullptr; std::vector doors; + + void Init(); }; struct Drop diff --git a/server/gameserver/metamgr.cc b/server/gameserver/metamgr.cc index e8bc580..139542b 100755 --- a/server/gameserver/metamgr.cc +++ b/server/gameserver/metamgr.cc @@ -121,6 +121,7 @@ private: MetaData::Building& item = a8::FastAppend(building_list); item.i = &meta; meta.set__building_id(building_id++); + item.Init(); building_hash[item.i->_building_id()] = &item; } } diff --git a/server/gameserver/obstacle.cc b/server/gameserver/obstacle.cc index abd5e28..f6b5347 100644 --- a/server/gameserver/obstacle.cc +++ b/server/gameserver/obstacle.cc @@ -5,6 +5,7 @@ #include "movement.h" #include "room.h" #include "collider.h" +#include "building.h" Obstacle::Obstacle():Entity() { @@ -58,6 +59,27 @@ void Obstacle::RecalcSelfCollider() self_collider_->rad = 32 / 2.0; } break; + case 61018: + { + if (is_door) { + //门 + if (!self_collider2_) { + self_collider2_ = new AabbCollider(); + self_collider2_->owner = this; + colliders.push_back(self_collider2_); + } + if (door_state == DoorStateClose) { + self_collider2_->_min = Vector2D(0.0f - door_state0->width() / 2.0f, + 0.0f - door_state0->height() / 2.0f); + self_collider2_->_max = Vector2D(door_state0->width() / 2.0f, door_state0->height() / 2.0f); + } else { + self_collider2_->_min = Vector2D(0.0f - door_state1->width() / 2.0f, + 0.0f - door_state1->height() / 2.0f); + self_collider2_->_max = Vector2D(door_state1->width(), door_state1->height()); + } + } + } + break; } } @@ -82,4 +104,20 @@ void Obstacle::FillMFObjectFull(cs::MFObjectFull* full_data) p->set_health(health); p->set_dead(dead); p->set_dead_at_thisframe(dead ? dead_frameno < room->frame_no : false); + + p->set_is_door(is_door); + if (is_door) { + p->set_door_id(door_id); + p->set_door_old_state((int)door_state); + p->set_door_new_state((int)door_state); + p->set_door_house_uniid(door_house_uniid); + p->set_door_house_id(building->meta->i->_building_id()); + if (door_state == DoorStateClose) { + p->set_door_width(door_state0->width()); + p->set_door_height(door_state0->height()); + } else { + p->set_door_width(door_state1->width()); + p->set_door_height(door_state1->height()); + } + } } diff --git a/server/gameserver/obstacle.h b/server/gameserver/obstacle.h index 1fca18f..1b07e73 100644 --- a/server/gameserver/obstacle.h +++ b/server/gameserver/obstacle.h @@ -7,9 +7,16 @@ namespace MetaData struct Player; struct Equip; struct MapThing; + struct Building; +} + +namespace metatable +{ + class DoorObjJson; } class Human; +class Building; class CircleCollider; class AabbCollider; class Obstacle : public Entity @@ -20,6 +27,14 @@ class Obstacle : public Entity bool dead = false; long long dead_frameno = 0; + bool is_door = false; + int door_id = 0; + DoorState_e door_state = DoorStateClose; + Building* building = nullptr; + int door_house_uniid = 0; + const metatable::DoorObjJson* door_state0 = nullptr; + const metatable::DoorObjJson* door_state1 = nullptr; + Obstacle(); virtual ~Obstacle() override; virtual void Initialize() override; diff --git a/server/gameserver/player.cc b/server/gameserver/player.cc index 5c285c1..3c8556d 100644 --- a/server/gameserver/player.cc +++ b/server/gameserver/player.cc @@ -9,6 +9,8 @@ #include "metamgr.h" #include "movement.h" #include "bullet.h" +#include "obstacle.h" +#include "building.h" const int F_del_objids = 2; const int F_full_objects = 3; @@ -61,6 +63,9 @@ void Player::Update(int delta_time) if (shot_start || shot_hold) { UpdateShot(); } + if (interaction_objids.size() > 0) { + ProcInteraction(); + } MakeUpdateMsg(); SendNotifyMsg(*update_msg); { @@ -147,6 +152,50 @@ void Player::Shot() } } +void Player::ProcInteraction() +{ + for (auto obj_id : interaction_objids) { + Entity* entity = room->GetEntityByUniId(obj_id); + if (entity) { + switch (entity->entity_type) { + case ET_Obstacle: + { + ObstacleInteraction((Obstacle*)entity); + } + break; + case ET_Loot: + { + + } + break; + default: + break; + } + } + } + interaction_objids.Clear(); +} + +void Player::ObstacleInteraction(Obstacle* entity) +{ + if (entity->is_door) { + if (entity->door_state == DoorStateClose) { + entity->door_state = DoorStateOpen; + entity->pos = Vector2D(entity->building->pos.x + entity->door_state1->x() - entity->building->meta->i->tilewidth() / 2.0, + entity->building->pos.y + entity->door_state1->y() - entity->building->meta->i->tileheight() / 2.0); + } else { + entity->door_state = DoorStateClose; + entity->pos = Vector2D(entity->building->pos.x + entity->door_state0->x() - entity->building->meta->i->tilewidth() / 2.0, + entity->building->pos.y + entity->door_state0->y() - entity->building->meta->i->tileheight() / 2.0); + } + entity->RecalcSelfCollider(); + for (auto& pair : room->human_hash_) { + pair.second->new_objects.insert(entity); + pair.second->part_objects.insert(entity); + } + } +} + void Player::_CMMove(f8::MsgHdr& hdr, const cs::CMMove& msg) { bool has_move_dir = msg.has_move_dir(); @@ -180,6 +229,10 @@ void Player::_CMMove(f8::MsgHdr& hdr, const cs::CMMove& msg) if (!shot_hold) { series_shot_frames = 0; } + if (msg.has_interaction()) { + interaction_objids = msg.interaction_objids(); + } + last_seq_id = msg.seq(); } void Player::_CMDropItem(f8::MsgHdr& hdr, const cs::CMDropItem& msg) @@ -222,6 +275,7 @@ void Player::MakeUpdateMsg() { update_msg->Clear(); { + update_msg->set_ack(last_seq_id); for (auto& obj_uniid : room->frame_data.deleted_objects) { update_msg->add_del_objids(obj_uniid); } diff --git a/server/gameserver/player.h b/server/gameserver/player.h index 401394d..aa82429 100644 --- a/server/gameserver/player.h +++ b/server/gameserver/player.h @@ -14,6 +14,7 @@ namespace cs } class Room; +class Obstacle; class Player : public Human { public: @@ -28,12 +29,14 @@ class Player : public Human bool use_touch = false; std::string avatar_url; + int last_seq_id = 0; bool moving = false; int moved_frames = 0; bool shot_start = false; bool shot_hold = false; int series_shot_frames = 0; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > interaction_objids; template void SendNotifyMsg(T& msg) @@ -48,6 +51,8 @@ class Player : public Human void UpdateMove(); void UpdateShot(); void Shot(); + void ProcInteraction(); + void ObstacleInteraction(Obstacle* entity); void _CMMove(f8::MsgHdr& hdr, const cs::CMMove& msg); void _CMDropItem(f8::MsgHdr& hdr, const cs::CMDropItem& msg); diff --git a/server/tools/protobuild/cs_proto.proto b/server/tools/protobuild/cs_proto.proto index 7811198..c40e4e0 100755 --- a/server/tools/protobuild/cs_proto.proto +++ b/server/tools/protobuild/cs_proto.proto @@ -176,6 +176,9 @@ message MFObstacleFull optional int32 door_old_state = 23; //门前一个状态 optional int32 door_new_state = 24; //门当前状态 optional int32 door_house_uniid = 25; //门所属房间唯一id + optional int32 door_house_id = 26; //门所属房间id + optional float door_width = 27; //门宽度 + optional float door_height = 28; //门高度 } @@ -582,7 +585,7 @@ message SMUpdate repeated MFShot shots = 21; //射击 repeated MFExplosion explosions = 22; //爆炸 repeated MFEmote emotes = 23; //表情 - optional int32 ack = 24; + optional int32 ack = 24; //服务器最后处理的req id optional uint32 data_flags32 = 256; }