From 3a038a15e89ffedf64b152fff89c4091d6d56897 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Tue, 23 Jul 2019 11:19:44 +0800 Subject: [PATCH] 1 --- server/gameserver/loot.h | 1 + server/gameserver/metadata.cc | 23 ++++++++ server/gameserver/metadata.h | 12 ++++ server/gameserver/metamgr.cc | 59 ++++++++++++++++--- server/gameserver/metamgr.h | 2 + server/gameserver/room.cc | 75 ++++++++++++++++++++++++- server/gameserver/room.h | 7 ++- server/tools/protobuild/metatable.proto | 29 +++++----- 8 files changed, 183 insertions(+), 25 deletions(-) diff --git a/server/gameserver/loot.h b/server/gameserver/loot.h index 5190660..be8525b 100644 --- a/server/gameserver/loot.h +++ b/server/gameserver/loot.h @@ -17,6 +17,7 @@ class Loot : public Entity int item_id = 0; int count = 0; int item_level = 0; + int airdrop_point_id = 0; bool pickuped = false; Loot(); diff --git a/server/gameserver/metadata.cc b/server/gameserver/metadata.cc index 42c030b..01cebec 100644 --- a/server/gameserver/metadata.cc +++ b/server/gameserver/metadata.cc @@ -169,6 +169,29 @@ namespace MetaData } } + void AirDrop::Init() + { + std::vector strings; + a8::Split(i->drop(), strings, '|'); + for (std::string& tmpstr : strings) { + std::vector strings2; + a8::Split(tmpstr, strings2, ':'); + if (strings2.size() != 2) { + abort(); + } + drop_list.push_back(std::make_tuple( + a8::XValue(strings2[0]).GetInt(), + a8::XValue(strings2[1]).GetInt() + ) + ); + } + } + + void AirDrop::RandItems(std::vector>& drop_items) + { + + } + void Building::Init() { for (auto& door_meta : i->doorobj()) { diff --git a/server/gameserver/metadata.h b/server/gameserver/metadata.h index e79b319..ef748c0 100755 --- a/server/gameserver/metadata.h +++ b/server/gameserver/metadata.h @@ -100,6 +100,7 @@ namespace MetaData const metatable::Drop* i = nullptr; void Init(); + //itemid itemcount itemlv void RandItems(std::vector>& drop_items); private: @@ -107,6 +108,17 @@ namespace MetaData int total_weight = 0; }; + struct AirDrop + { + const metatable::AirDrop* i = nullptr; + + void Init(); + void RandItems(std::vector>& drop_items); + + private: + std::vector> drop_list; + }; + struct MapTplThing { const metatable::MapTplThingJson* i = nullptr; diff --git a/server/gameserver/metamgr.cc b/server/gameserver/metamgr.cc index 5139ee3..8c27166 100755 --- a/server/gameserver/metamgr.cc +++ b/server/gameserver/metamgr.cc @@ -29,6 +29,8 @@ public: std::list building_list; std::list drop_meta_list; std::list drop_list; + std::list airdrop_meta_list; + std::list airdrop_list; std::list tank_meta_list; std::list tank_list; std::list tanktank_meta_list; @@ -58,9 +60,11 @@ public: std::map mapthing_hash; std::map building_hash; std::map drop_hash; + std::map> airdrop_hash; std::map> maptpl_meta_hash; std::map> maptpl_hash; std::map> born_point_hash; + std::map> airdrop_point_hash; std::map> maptpl_size_hash; std::map tank_hash; std::map tankskin_hash; @@ -103,6 +107,7 @@ public: f8::ReadCsvMetaFile(res_path + "player@player.csv", player_meta_list); f8::ReadCsvMetaFile(res_path + "mapThing@mapThing.csv", mapthing_meta_list); f8::ReadCsvMetaFile(res_path + "drop@drop.csv", drop_meta_list); + f8::ReadCsvMetaFile(res_path + "airdrop@airdrop.csv", airdrop_meta_list); f8::ReadJsonMetaFile(res_path + "maps.json", building_meta_list); f8::ReadCsvMetaFile(res_path + "skill@skill.csv", skill_meta_list); f8::ReadCsvMetaFile(res_path + "buff@buff.csv", buff_meta_list); @@ -170,20 +175,28 @@ private: for (auto& pair : maptpl_meta_hash) { std::vector things; std::vector born_point; + std::map airdrop_point; int map_width = 0; int map_height = 0; for (auto& itr : pair.second) { - if (itr.is_born_point()) { - auto& thing = a8::FastAppend(born_point); + if (itr.object_type() == "airdrop") { + MetaData::MapTplThing thing; thing.i = &itr; thing.Init(); - } else if (itr.is_map_info()) { - map_width = itr.map_width(); - map_height = itr.map_height(); + airdrop_point[itr.object_uniid()] = thing; } else { - auto& thing = a8::FastAppend(things); - thing.i = &itr; - thing.Init(); + if (itr.is_born_point()) { + auto& thing = a8::FastAppend(born_point); + thing.i = &itr; + thing.Init(); + } else if (itr.is_map_info()) { + map_width = itr.map_width(); + map_height = itr.map_height(); + } else { + auto& thing = a8::FastAppend(things); + thing.i = &itr; + thing.Init(); + } } } if (map_width < kMAP_GRID_WIDTH || map_height < kMAP_GRID_WIDTH) { @@ -191,6 +204,7 @@ private: } maptpl_hash[pair.first] = things; born_point_hash[pair.first] = born_point; + airdrop_point_hash[pair.first] = airdrop_point; maptpl_size_hash[pair.first] = std::make_tuple(map_width, map_height); if (born_point.size() != kROOM_MAX_PLAYER_NUM) { abort(); @@ -276,6 +290,18 @@ private: drop_hash[item.i->drop_id()] = &item; } + for (auto& meta : airdrop_meta_list) { + MetaData::AirDrop& item = a8::FastAppend(airdrop_list); + item.i = &meta; + item.Init(); + auto itr = airdrop_hash.find(meta.map_id()); + if (itr != airdrop_hash.end()) { + itr->second.push_back(&item); + } else { + airdrop_hash[meta.map_id()] = std::vector({&item}); + } + } + { for (auto& meta : building_meta_list) { MetaData::Building& item = a8::FastAppend(building_list); @@ -379,6 +405,12 @@ MetaData::Map* MetaMgr::GetMap(int map_id) return itr != loader_->gamemap_hash.end() ? itr->second : nullptr; } +std::vector* MetaMgr::GetMapAirDrop(int map_id) +{ + auto itr = loader_->airdrop_hash.find(map_id); + return itr != loader_->airdrop_hash.end() ? &itr->second : nullptr; +} + MetaData::Map* MetaMgr::RandMap() { std::vector map_list; @@ -442,6 +474,16 @@ std::vector* MetaMgr::GetMapBornPoints(const std::string& return itr != loader_->born_point_hash.end() ? &itr->second : nullptr; } +MetaData::MapTplThing* MetaMgr::GetMapAirDropPoint(const std::string& map_name, int point_id) +{ + auto itr = loader_->airdrop_point_hash.find(map_name); + if (itr == loader_->airdrop_point_hash.end()) { + return nullptr; + } + auto itr2 = itr->second.find(point_id); + return itr2 != itr->second.end() ? &itr2->second : nullptr; +} + bool MetaMgr::GetMapTplSize(const std::string& map_name, int& width, int& height) { auto itr = loader_->maptpl_size_hash.find(map_name); @@ -523,4 +565,3 @@ MetaData::Robot* MetaMgr::GetRobot(int robot_id) auto itr = loader_->robot_hash.find(robot_id); return itr != loader_->robot_hash.end() ? itr->second : nullptr; } - diff --git a/server/gameserver/metamgr.h b/server/gameserver/metamgr.h index 2b5d580..cd92ba0 100755 --- a/server/gameserver/metamgr.h +++ b/server/gameserver/metamgr.h @@ -20,6 +20,7 @@ class MetaMgr : public a8::Singleton double GetSysParamAsFloat(const std::string& param_name, double def_val = 0.0f); std::string GetSysParamAsString(const std::string& param_name, const char* def_val = ""); MetaData::Map* GetMap(int map_id); + std::vector* GetMapAirDrop(int map_id); MetaData::Map* RandMap(); MetaData::MapThing* GetMapThing(int mapthing_id); MetaData::Player* GetPlayer(int id); @@ -30,6 +31,7 @@ class MetaMgr : public a8::Singleton MetaData::SafeArea* GetSafeArea(int area_id); std::vector* GetMapTplThing(const std::string& map_name); std::vector* GetMapBornPoints(const std::string& map_name); + MetaData::MapTplThing* GetMapAirDropPoint(const std::string& map_name, int point_id); bool GetMapTplSize(const std::string& map_name, int& width, int& height); MetaData::Skill* GetSkill(int skill_id); MetaData::Buff* GetBuff(int buff_id); diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index 27050d0..8a8f9d9 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -522,12 +522,12 @@ Hero* Room::CreateHero(Human* hum) return hero; } -void Room::CreateLoot(int equip_id, a8::Vec2 pos, int count, int equip_lv) +int Room::CreateLoot(int equip_id, a8::Vec2 pos, int count, int equip_lv) { MetaData::Equip* equip_meta = MetaMgr::Instance()->GetEquip(equip_id); if (equip_meta) { if (!equip_meta->CanDrop()) { - return; + return -1; } Loot* entity = new Loot(); entity->room = this; @@ -557,7 +557,9 @@ void Room::CreateLoot(int equip_id, a8::Vec2 pos, int count, int equip_lv) uniid_hash_[entity->entity_uniid] = entity; grid_service.AddEntity(entity); entity->BroadcastFullState(); + return entity->entity_uniid; } + return -1; } void Room::CreateBullet(Human* hum, MetaData::Equip* bullet_meta, @@ -845,6 +847,7 @@ void Room::UpdateGas() room->BattleReport(); }, &xtimer_attacher.timer_list_); + InitAirDrop(); } } break; @@ -1095,3 +1098,71 @@ int Room::AllocBornPoint() } return point_vec[rand() % point_vec.size()]; } + +void Room::InitAirDrop() +{ + std::vector* air_drops = MetaMgr::Instance()->GetMapAirDrop(map_meta->i->map_id()); + if (air_drops) { + for (MetaData::AirDrop* air_drop : *air_drops) { + xtimer.AddDeadLineTimerAndAttach(kSERVER_FRAME_RATE * air_drop->i->time(), + a8::XParams() + .SetSender(this) + .SetParam1(air_drop), + [] (const a8::XParams& param) + { + Room* room = (Room*)param.sender.GetUserData(); + MetaData::AirDrop* air_drop = (MetaData::AirDrop*)param.param1.GetUserData(); + if (!room->IsGameOver()) { + room->AirDrop(air_drop); + } + }, + &xtimer_attacher.timer_list_); + } + } +} + +void Room::AirDrop(MetaData::AirDrop* air_drop) +{ + std::vector> drop_items; + air_drop->RandItems(drop_items); + for (auto& tuple : drop_items) { + GenDrop(std::get<1>(tuple), std::get<0>(tuple)); + } +} + +void Room::GenDrop(int drop_id, int airdrop_point_id) +{ + if (airdrop_hash_.find(airdrop_point_id) != airdrop_hash_.end()) { + return; + } + MetaData::MapTplThing* point_meta = MetaMgr::Instance()->GetMapAirDropPoint(map_tpl_name, airdrop_point_id); + MetaData::Drop* drop_meta = MetaMgr::Instance()->GetDrop(drop_id); + if (drop_meta && point_meta) { + std::vector> drop_items; + drop_meta->RandItems(drop_items); + a8::Vec2 center = a8::Vec2(point_meta->i->x(), point_meta->i->y()); + for (auto& tuple : drop_items) { + a8::Vec2 pos = center; + if (drop_items.size() > 1) { + a8::Vec2 dir = a8::Vec2::UP; + dir.Rotate(a8::RandAngle()); + pos = pos + dir * (25 + rand() % 50); + } + int loot_id = CreateLoot(std::get<0>(tuple), + pos, + std::get<1>(tuple), + std::get<2>(tuple) + ); + Entity* entity = GetEntityByUniId(loot_id); + if (entity && entity->entity_type == kET_Loot) { + auto itr = airdrop_hash_.find(airdrop_point_id); + if (itr != airdrop_hash_.end()) { + itr->second.insert(loot_id); + } else { + airdrop_hash_[airdrop_point_id] = std::set({loot_id}); + } + } + ((Loot*)entity)->airdrop_point_id = airdrop_point_id; + } + } +} diff --git a/server/gameserver/room.h b/server/gameserver/room.h index c16154a..4bd0a62 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -19,6 +19,7 @@ namespace MetaData struct Map; struct SafeArea; struct Building; + struct AirDrop; } struct timer_list; @@ -83,7 +84,7 @@ public: void DropItem(a8::Vec2 pos, int item_id, int item_count, int item_lv); Hero* CreateHero(Human* hum); - void CreateLoot(int equip_id, a8::Vec2 pos, int count, int equip_lv); + int CreateLoot(int equip_id, a8::Vec2 pos, int count, int equip_lv); void CreateBullet(Human* hum, MetaData::Equip* bullet_meta, a8::Vec2 pos, a8::Vec2 dir, float fly_distance, int skill_id); @@ -120,6 +121,9 @@ private: void NotifyWxVoip(); void BattleReport(); int AllocBornPoint(); + void InitAirDrop(); + void AirDrop(MetaData::AirDrop* air_drop); + void GenDrop(int drop_id, int airdrop_point_id); private: int elapsed_time_ = 0; @@ -141,5 +145,6 @@ private: std::map later_add_hash_; std::map human_hash_; + std::map> airdrop_hash_; std::map removed_robot_hash_; }; diff --git a/server/tools/protobuild/metatable.proto b/server/tools/protobuild/metatable.proto index 905040e..ce9ea0c 100755 --- a/server/tools/protobuild/metatable.proto +++ b/server/tools/protobuild/metatable.proto @@ -162,10 +162,10 @@ message Drop message AirDrop { - required int32 id = 1; + required int32 map_id = 1; required int32 time = 2; required int32 appear_time = 3; - required int32 drop_id = 4; + required string drop = 4; } message AirLine @@ -277,15 +277,18 @@ message BuildingJson message MapTplThingJson { - required string layer_name = 1; - required string name = 2; - required string things = 3; - required int32 weight = 4; - required float x = 5; - required float y = 6; - required int32 is_born_point = 7; - required string born_angle = 8; - optional int32 is_map_info = 9; - optional int32 map_width = 10; - optional int32 map_height = 11; + optional string object_type = 1; + optional int32 object_uniid = 2; + + required string layer_name = 3; + required string name = 4; + required string things = 5; + required int32 weight = 6; + required float x = 7; + required float y = 8; + required int32 is_born_point = 9; + required string born_angle = 10; + optional int32 is_map_info = 11; + optional int32 map_width = 12; + optional int32 map_height = 13; } \ No newline at end of file