diff --git a/server/gameserver/creature.h b/server/gameserver/creature.h index 352caaba..006c1201 100644 --- a/server/gameserver/creature.h +++ b/server/gameserver/creature.h @@ -376,6 +376,7 @@ private: protected: bool need_sync_active_player_ = false; + std::list on_dead_remove_objects_; ActionType_e action_type = AT_None; int action_duration = 0; diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 5eb587d9..55a68422 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -1238,6 +1238,31 @@ void Human::DeadDrop() } } } + { + if (GetInventory(IS_GEMSTONE) > 0 && gemstone > 0) { + room->frame_event.AddPropChg + ( + GetWeakPtrRef(), + kPropGemstone, + 0, + 0, + false); + + const mt::Equip* gem_stone_meta = mt::Equip::GetGemStone(); + if (gem_stone_meta) { + Position drop_pos = GetPos(); + room->DropItem(drop_pos.ToGlmVec3(), gem_stone_meta->id(), gemstone, 1); + } + + SetMaxHP(GetBattleContext()->GetMaxHP()); + gemstone = 0; + DecInventory(IS_GEMSTONE, GetInventory(IS_GEMSTONE)); + SyncVolume(IS_GEMSTONE); + } + } + { + on_dead_remove_objects_.clear(); + } MarkSyncActivePlayer(__FILE__, __LINE__, __func__); } @@ -3199,7 +3224,26 @@ void Human::ProcGemStoneItem(AddItemDTO& dto) 0, gemstone, false); - GetAbility()->AddAttrRate(kHAT_Atk, dto.item_meta->_atk); + + auto context = A8_MAKE_SMART_ANON_STRUCT_SHARED + ( + CreatureWeakPtr owner; + AttrRateHandle handle; + ); + context->owner = GetWeakPtrRef(); + context->_destory_cb = + [context = context.get()] () + { + if (context->owner.Get() && + context->owner.Get()->room->IsDestorying() && + !context->handle.expired() + ) { + context->owner.Get()->GetAbility()->RemoveAttrRate(context->handle); + } + }; + context->handle = GetAbility()->AddAttrRate(kHAT_Atk, dto.item_meta->_atk); + on_dead_remove_objects_.push_back(context); + SetMaxHP(GetMaxHP() + dto.item_meta->_max_hp * GetBattleContext()->GetMaxHP()); SetHP(GetHP() + dto.item_meta->_max_hp * GetBattleContext()->GetMaxHP()); room->frame_event.AddPropChg diff --git a/server/gameserver/mt/Equip.cc b/server/gameserver/mt/Equip.cc index 542838b6..ee97b881 100644 --- a/server/gameserver/mt/Equip.cc +++ b/server/gameserver/mt/Equip.cc @@ -5,6 +5,7 @@ IMPL_TABLE(mt::Equip) std::map mt::Equip::slot_hash_; +const mt::Equip* mt::Equip::gem_stone_ = nullptr; namespace mt { @@ -324,4 +325,14 @@ namespace mt }); } + void Equip::StaticPostInit() + { + gem_stone_ = GetById(GEMSTONE_ID); + } + + const Equip* Equip::GetGemStone() + { + return gem_stone_; + } + } diff --git a/server/gameserver/mt/Equip.h b/server/gameserver/mt/Equip.h index 8518a358..2e8e5fa1 100644 --- a/server/gameserver/mt/Equip.h +++ b/server/gameserver/mt/Equip.h @@ -10,6 +10,8 @@ namespace mt "equip@equip.json", "id") public: + static const int GEMSTONE_ID = 31001; + int lock_time = 0; //0,0,0,0,后座力,是否取消定身 std::vector> _bullet_born_offset; @@ -42,8 +44,11 @@ namespace mt bool Match(EventAddBuff_e event, int val, int val2) const; static const Equip* GetByIdBySlotId(int slot_id); static void AdjustMuzzlePos(); + static const Equip* GetGemStone(); + static void StaticPostInit(); private: + static const mt::Equip* gem_stone_; static std::map slot_hash_; std::map>> _gun_muzzle_position_hash_; }; diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index 3bfdeaf9..8c1b2285 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -510,7 +510,11 @@ void Room::DropItem(const glm::vec3& pos, int item_id, int item_count, int item_ void Room::DropItemEx(const glm::vec3& born_pos, const glm::vec3& pos, int item_id, int item_count, int item_lv, bool show_anim) { const mt::Equip* equip_meta = mt::Equip::GetById(item_id); - if (equip_meta && equip_meta->group_num() > 0 && item_count > 0) { + int group_num = equip_meta->group_num(); + if (item_id == mt::Equip::GEMSTONE_ID && group_num <= 0) { + group_num = 1; + } + if (equip_meta && group_num > 0 && item_count > 0) { #if 1 if (equip_meta->equip_type() == EQUIP_TYPE_BULLET) { return; @@ -518,7 +522,7 @@ void Room::DropItemEx(const glm::vec3& born_pos, const glm::vec3& pos, int item_ #endif int total_count = item_count; while (total_count > 0) { - int drop_num = std::min(total_count, equip_meta->group_num()); + int drop_num = std::min(total_count, group_num); if (drop_num < 1) { drop_num = 1; }