diff --git a/server/gameserver/bullet.cc b/server/gameserver/bullet.cc index 1bc2337..737e1ea 100644 --- a/server/gameserver/bullet.cc +++ b/server/gameserver/bullet.cc @@ -65,7 +65,11 @@ void Bullet::Update(int delta_time) } } }//end for - if (!objects.empty() || distance > gun_meta->i->range() || + float bullet_range = gun_meta->i->range(); + if (gun_upgrade_meta && gun_upgrade_meta->attr[EA_ShotRange] > 0) { + bullet_range += gun_upgrade_meta->attr[EA_ShotRange]; + } + if (!objects.empty() || distance > bullet_range || (IsBomb() && meta->i->_inventory_slot() != 4 && distance >= fly_distance) ) { if (IsBomb()) { diff --git a/server/gameserver/bullet.h b/server/gameserver/bullet.h index 7718002..ea92298 100644 --- a/server/gameserver/bullet.h +++ b/server/gameserver/bullet.h @@ -6,6 +6,7 @@ namespace MetaData { struct Player; struct Equip; + struct EquipUpgrade; } class Human; @@ -14,6 +15,7 @@ class Bullet : public Entity { public: MetaData::Equip* gun_meta = nullptr; + MetaData::EquipUpgrade* gun_upgrade_meta = nullptr; MetaData::Equip* meta = nullptr; Human* player = nullptr; Vector2D dir; diff --git a/server/gameserver/constant.h b/server/gameserver/constant.h index 48805a8..158f8b4 100755 --- a/server/gameserver/constant.h +++ b/server/gameserver/constant.h @@ -122,13 +122,13 @@ enum VirtualPlayer_e VP_Mine = 9000003, }; -enum EquipAttr +enum EquipAttr_e { - EA_HP = 1, - EA_Dmg = 2, - EA_ShotRange = 3, - EA_ShotSpeed = 4, - EA_Def = 5, + EA_View = 1, //客户端用 + EA_ShotRange = 2, + EA_Volume = 3, + EA_AutoAngle = 4, //客户端用 + EA_BulletAngle = 5, EA_End }; diff --git a/server/gameserver/frameevent.cc b/server/gameserver/frameevent.cc index af01285..ec37fd1 100644 --- a/server/gameserver/frameevent.cc +++ b/server/gameserver/frameevent.cc @@ -68,6 +68,7 @@ void FrameEvent::AddBullet(Human* hum, Vector2D born_pos, Vector2D dir, float fl dir.ToPB(p.mutable_dir()); p.set_bulletskin(10001); p.set_gun_id(hum->curr_weapon->meta->i->id()); + p.set_gun_lv(hum->curr_weapon->weapon_lv); p.set_fly_distance(fly_distance); } { diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index f611280..bd401c6 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -25,6 +25,7 @@ Human::Human():Entity() default_weapon.weapon_lv = 1; default_weapon.ammo = 1; default_weapon.meta = MetaMgr::Instance()->GetEquip(default_weapon.weapon_id); + default_weapon.Recalc(); weapons.reserve(MAX_WEAPON_NUM); for (size_t i = 0; i < MAX_WEAPON_NUM; ++i) { auto& weapon = a8::FastAppend(weapons); @@ -195,12 +196,18 @@ void Human::Shot(Vector2D& target_dir) Vector2D bullet_born_pos = pos + bullet_born_offset; Vector2D bullet_dir = attack_dir; float bullet_angle = std::get<2>(tuple); - if (curr_weapon->meta->i->bullet_angle() >= 1.0f) { - bullet_angle += (rand() % (int)curr_weapon->meta->i->bullet_angle()) * (rand() % 2 == 0 ? 1 : -1); + if (curr_weapon->meta->i->bullet_angle() >= 0.10f) { + int angle = (int)curr_weapon->meta->i->bullet_angle() * 1000; + if (curr_weapon->upgrade_meta) { + angle -= curr_weapon->upgrade_meta->attr[EA_BulletAngle] * 1000; + } + if (angle > 0) { + bullet_angle += (rand() % angle) / 1000.0f * (rand() % 2 == 0 ? 1 : -1); + } } bullet_dir.Rotate(bullet_angle / 180.0f); room->frame_event.AddBullet(this, bullet_born_pos, attack_dir, fly_distance); - room->CreateBullet(this, curr_weapon->meta, bullet_born_pos, attack_dir, fly_distance); + room->CreateBullet(this, curr_weapon, bullet_born_pos, attack_dir, fly_distance); } --curr_weapon->ammo; int slot_id = curr_weapon->meta->i->_inventory_slot(); @@ -397,7 +404,7 @@ 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())) + (manual && curr_weapon->ammo < curr_weapon->GetClipVolume())) ) { MetaData::Equip* bullet_meta = MetaMgr::Instance()->GetEquip(curr_weapon->meta->i->use_bullet()); if (bullet_meta && @@ -727,6 +734,7 @@ void Human::Land() weapons[GUN_SLOT1].weapon_lv = 1; weapons[GUN_SLOT1].ammo = 0; weapons[GUN_SLOT1].meta = weapon_meta; + weapons[GUN_SLOT1].Recalc(); curr_weapon = &weapons[GUN_SLOT1]; } } @@ -1516,17 +1524,17 @@ void Human::UpdateAction() 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 (ammo < curr_weapon->GetClipVolume()) { if (bullet_meta->i->_inventory_slot() >= 0 && bullet_meta->i->_inventory_slot() < IS_END) { if (GetInventory(bullet_meta->i->_inventory_slot()) > 0) { int add_num = 0; if (GetInventory(bullet_meta->i->_inventory_slot()) <= - curr_weapon->meta->i->clip_volume() - ammo) { + curr_weapon->GetClipVolume() - ammo) { add_num = GetInventory(bullet_meta->i->_inventory_slot()); DecInventory(bullet_meta->i->_inventory_slot(), add_num); } else { - add_num = curr_weapon->meta->i->clip_volume() - ammo; + add_num = curr_weapon->GetClipVolume() - ammo; DecInventory(bullet_meta->i->_inventory_slot(), add_num); } curr_weapon->ammo += add_num; @@ -1649,6 +1657,12 @@ void Human::SendWxVoip() SendNotifyMsg(notifymsg); } +int Human::GetWeaponConfigLv(int weapon_id) +{ + auto itr = weapon_configs.find(weapon_id); + return itr != weapon_configs.end() ? itr->second : 0; +} + void Human::ClearFrameData() { if (!new_objects.empty()) { diff --git a/server/gameserver/human.h b/server/gameserver/human.h index fa82ebe..5ed9851 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -101,6 +101,7 @@ class Human : public Entity long long send_msg_times = 0; float def = 0.0f; + std::map weapon_configs; Human(); virtual ~Human() override; @@ -174,6 +175,7 @@ class Human : public Entity void UpdateAction(); void SendUIUpdate(); void SendWxVoip(); + int GetWeaponConfigLv(int weapon_id); private: void ClearFrameData(); diff --git a/server/gameserver/metadata.cc b/server/gameserver/metadata.cc index 09bc47e..e2390cb 100644 --- a/server/gameserver/metadata.cc +++ b/server/gameserver/metadata.cc @@ -79,6 +79,32 @@ namespace MetaData } } + void EquipUpgrade::Init() + { + std::vector attr_type; + std::vector attr_value; + { + std::vector strings; + a8::Split(i->attr_type(), strings, '|'); + for (auto& str : strings) { + attr_type.push_back(a8::XValue(str).GetInt()); + } + } + { + std::vector strings; + a8::Split(i->attr_value(), strings, '|'); + for (auto& str : strings) { + attr_value.push_back(a8::XValue(str).GetDouble()); + } + } + assert(attr_type.size() == attr_value.size()); + for (size_t i = 0; i < attr_type.size(); ++i) { + if (attr_type[i] < EA_End) { + attr[attr_type[i]] = attr_value[i]; + } + } + } + void Player::Init() { { diff --git a/server/gameserver/metadata.h b/server/gameserver/metadata.h index 1430bbf..403bf3b 100755 --- a/server/gameserver/metadata.h +++ b/server/gameserver/metadata.h @@ -52,6 +52,14 @@ namespace MetaData void Init(); }; + struct EquipUpgrade + { + const metatable::EquipUpgrade* i = nullptr; + + std::array attr = {}; + void Init(); + }; + struct Player { const metatable::Player* i = nullptr; diff --git a/server/gameserver/metamgr.cc b/server/gameserver/metamgr.cc index c41b639..f016656 100755 --- a/server/gameserver/metamgr.cc +++ b/server/gameserver/metamgr.cc @@ -39,6 +39,8 @@ public: std::list skill_list; std::list rankreward_meta_list; std::list rankreward_list; + std::list equipupgrade_meta_list; + std::list equipupgrade_list; std::map parameter_hash; std::map gamemap_hash; @@ -55,6 +57,7 @@ public: std::map dress_hash; std::map skill_hash; std::map rankreward_hash; + std::map equipupgrade_hash; void Load() { @@ -88,6 +91,7 @@ public: f8::ReadCsvMetaFile(res_path + "dress@dress.csv", dress_meta_list); f8::ReadCsvMetaFile(res_path + "skill@skill.csv", skill_meta_list); f8::ReadCsvMetaFile(res_path + "rankReward@rankReward.csv", rankreward_meta_list); + f8::ReadCsvMetaFile(res_path + "equipUpgrade@equipUpgrade.csv", equipupgrade_meta_list); BindToMetaData(); #if 1 { @@ -232,6 +236,12 @@ private: rankreward_hash[item.i->rank()] = &item; } + for (auto& meta : equipupgrade_meta_list) { + MetaData::EquipUpgrade& item = a8::FastAppend(equipupgrade_list); + item.i = &meta; + equipupgrade_hash[a8::MakeInt64(meta.id(), meta.level())] = &item; + } + } private: @@ -307,6 +317,12 @@ MetaData::Equip* MetaMgr::GetEquipBySlotId(int slot_id) return itr != loader_->equip_slot_hash.end() ? itr->second : nullptr; } +MetaData::EquipUpgrade* MetaMgr::GetEquipUpgrade(int equip_id, int equip_lv) +{ + auto itr = loader_->equipupgrade_hash.find(a8::MakeInt64(equip_id, equip_lv)); + return itr != loader_->equipupgrade_hash.end() ? itr->second : nullptr; +} + MetaData::Building* MetaMgr::GetBuilding(int building_id) { auto itr = loader_->building_hash.find(building_id); diff --git a/server/gameserver/metamgr.h b/server/gameserver/metamgr.h index 0f2b3d7..d6a3976 100755 --- a/server/gameserver/metamgr.h +++ b/server/gameserver/metamgr.h @@ -24,6 +24,7 @@ class MetaMgr : public a8::Singleton MetaData::Player* GetPlayer(int id); MetaData::Equip* GetEquip(int id); MetaData::Equip* GetEquipBySlotId(int slot_id); + MetaData::EquipUpgrade* GetEquipUpgrade(int equip_id, int equip_lv); MetaData::Building* GetBuilding(int building_id); MetaData::Drop* GetDrop(int drop_id); MetaData::SafeArea* GetSafeArea(int area_id); diff --git a/server/gameserver/player.cc b/server/gameserver/player.cc index baabccf..1232b9a 100644 --- a/server/gameserver/player.cc +++ b/server/gameserver/player.cc @@ -343,13 +343,19 @@ void Player::Shot() Vector2D bullet_born_pos = pos + bullet_born_offset; Vector2D bullet_dir = attack_dir; float bullet_angle = std::get<2>(tuple); - if (curr_weapon->meta->i->bullet_angle() >= 1.0f) { - bullet_angle += (rand() % (int)curr_weapon->meta->i->bullet_angle()) * (rand() % 2 == 0 ? 1 : -1); + if (curr_weapon->meta->i->bullet_angle() >= 0.01f) { + int angle = (int)curr_weapon->meta->i->bullet_angle() * 1000; + if (curr_weapon->upgrade_meta) { + angle -= curr_weapon->upgrade_meta->attr[EA_BulletAngle] * 1000; + } + if (angle > 0) { + bullet_angle += (rand() % angle) / 1000.0f * (rand() % 2 == 0 ? 1 : -1); + } } bullet_dir.Rotate(bullet_angle / 180.0f); room->frame_event.AddBullet(this, bullet_born_pos, bullet_dir, fly_distance); if (room->BattleStarted() || room->gas_data.gas_mode == GasJump && !a8::HasBitFlag(status, HS_Jump)) { - room->CreateBullet(this, curr_weapon->meta, bullet_born_pos, bullet_dir, fly_distance); + room->CreateBullet(this, curr_weapon, bullet_born_pos, bullet_dir, fly_distance); } } } else { @@ -498,8 +504,10 @@ void Player::LootInteraction(Loot* entity) } else { weapons[0].weapon_idx = 0; weapons[0].weapon_id = entity->item_id; - weapons[0].weapon_lv = entity->item_level; + weapons[0].weapon_lv = std::max(1, GetWeaponConfigLv(weapons[0].weapon_id)); weapons[0].ammo = 0; + weapons[0].meta = item_meta; + weapons[0].Recalc(); } need_sync_active_player = true; SyncAroundPlayers(); @@ -527,9 +535,10 @@ void Player::LootInteraction(Loot* entity) return; } weapon->weapon_id = entity->item_id; - weapon->weapon_lv = entity->item_level; + weapon->weapon_lv = std::max(1, GetWeaponConfigLv(weapon->weapon_id)); weapon->ammo = 0; weapon->meta = item_meta; + weapon->Recalc(); AutoLoadingBullet(); need_sync_active_player = true; SyncAroundPlayers(); @@ -578,6 +587,7 @@ void Player::LootInteraction(Loot* entity) weapon->weapon_lv = 1; weapon->ammo += entity->count; weapon->meta = item_meta; + weapon->Recalc(); DecInventory(item_meta->i->_inventory_slot(), add_num); } if (item_meta->i->_inventory_slot() > 12) { diff --git a/server/gameserver/playermgr.cc b/server/gameserver/playermgr.cc index 0b4439e..bad1bc5 100644 --- a/server/gameserver/playermgr.cc +++ b/server/gameserver/playermgr.cc @@ -36,6 +36,11 @@ Player* PlayerMgr::CreatePlayerByCMJoin(int socket, const cs::CMJoin& msg) // hum->basemelee = msg.basemelee(); // hum->elo_score = msg.elo_score(); // hum->gmode = msg.gmode(); + for (auto& weapon : msg.weapons()) { + if (weapon.weapon_id() != 0 && weapon.weapon_lv() > 0) { + hum->weapon_configs[weapon.weapon_id()] = weapon.weapon_lv(); + } + } socket_hash_[socket] = hum; return hum; } diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index 3f6c3c8..f7d7d7b 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -495,6 +495,22 @@ void Room::CreateLoot(int equip_id, Vector2D pos, int count, int equip_lv) entity->meta = equip_meta; entity->entity_uniid = AllocUniid(); entity->pos = pos; + #if 1 + { + if (entity->pos.x > MAP_WIDTH) { + entity->pos.x = MAP_WIDTH; + } + if (entity->pos.x <= 0.001f) { + entity->pos.x = 0.0f; + } + if (entity->pos.y > MAP_HEIGHT) { + entity->pos.y = MAP_HEIGHT; + } + if (entity->pos.y < 0.0001f) { + entity->pos.y = 0.0f; + } + } + #endif entity->item_id = equip_id; entity->count = count; entity->item_level = equip_lv; @@ -505,14 +521,15 @@ void Room::CreateLoot(int equip_id, Vector2D pos, int count, int equip_lv) } } -void Room::CreateBullet(Human* hum, MetaData::Equip* gun_meta, +void Room::CreateBullet(Human* hum, Weapon* weapon, Vector2D pos, Vector2D dir, float fly_distance) { Bullet* bullet = new Bullet(); bullet->player = hum; bullet->room = this; - bullet->gun_meta = gun_meta; - bullet->meta = MetaMgr::Instance()->GetEquip(gun_meta->i->use_bullet()); + bullet->gun_meta = weapon->meta; + bullet->gun_upgrade_meta = weapon->upgrade_meta; + bullet->meta = MetaMgr::Instance()->GetEquip(weapon->meta->i->use_bullet()); bullet->pos = pos; bullet->dir = dir; bullet->born_pos = pos; diff --git a/server/gameserver/room.h b/server/gameserver/room.h index d3f5de9..11002d3 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -78,7 +78,7 @@ public: Hero* CreateHero(Human* hum); void CreateLoot(int equip_id, Vector2D pos, int count, int equip_lv); - void CreateBullet(Human* hum, MetaData::Equip* gun_meta, + void CreateBullet(Human* hum, Weapon* weapon, Vector2D pos, Vector2D dir, float fly_distance); void OnHumanDie(Human* hum); diff --git a/server/gameserver/types.cc b/server/gameserver/types.cc index 1473792..23f07d3 100644 --- a/server/gameserver/types.cc +++ b/server/gameserver/types.cc @@ -2,9 +2,27 @@ #include "cs_proto.pb.h" +#include "metamgr.h" + void Weapon::ToPB(cs::MFWeapon* pb_obj) { pb_obj->set_weapon_id(weapon_id); pb_obj->set_weapon_lv(weapon_lv); pb_obj->set_ammo(ammo); } + +void Weapon::Recalc() +{ + upgrade_meta = MetaMgr::Instance()->GetEquipUpgrade(weapon_id, + weapon_lv); + +} + +int Weapon::GetClipVolume() +{ + if (upgrade_meta) { + return meta->i->clip_volume() + upgrade_meta->attr[EA_Volume]; + } else { + return meta->i->clip_volume(); + } +} diff --git a/server/gameserver/types.h b/server/gameserver/types.h index 7090d6d..4224fb1 100755 --- a/server/gameserver/types.h +++ b/server/gameserver/types.h @@ -13,6 +13,7 @@ namespace MetaData { struct SafeArea; struct Equip; + struct EquipUpgrade; } struct GasData @@ -38,8 +39,11 @@ struct Weapon int weapon_lv = 0; int ammo = 0; MetaData::Equip* meta = nullptr; + MetaData::EquipUpgrade* upgrade_meta = nullptr; void ToPB(cs::MFWeapon* pb_obj); + void Recalc(); + int GetClipVolume(); }; struct PlayerStats diff --git a/server/tools/protobuild/cs_proto.proto b/server/tools/protobuild/cs_proto.proto index 7c15bb5..1015520 100755 --- a/server/tools/protobuild/cs_proto.proto +++ b/server/tools/protobuild/cs_proto.proto @@ -462,12 +462,12 @@ message MFBullet optional int32 bullet_id = 2; //子弹id optional MFVector2D pos = 3; //位置 optional MFVector2D dir = 4; //方向 - optional float variance_t = 5; + optional int32 gun_lv = 5; //枪等级 optional int32 bulletskin = 6; //子弹皮肤 optional bool crit = 7; optional int32 reflect_count = 8; optional int32 reflect_objid = 9; - optional int32 gun_id = 10; //抢id + optional int32 gun_id = 10; //枪id optional float fly_distance = 11; //只有手雷和烟雾弹时这个字段才有意义 } diff --git a/server/tools/protobuild/metatable.proto b/server/tools/protobuild/metatable.proto index 3d2246d..b2d5e90 100755 --- a/server/tools/protobuild/metatable.proto +++ b/server/tools/protobuild/metatable.proto @@ -81,6 +81,15 @@ message Equip optional int32 _inventory_slot = 32; //库存槽位 } +message EquipUpgrade +{ + optional int32 id = 1; + optional int32 level = 2; + optional int32 next_level = 3; + optional string attr_type = 4; + optional string attr_value = 5; +} + message Player { optional int32 id = 1; //唯一id