diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 465b46a508..c7ec71e5b7 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -256,15 +256,16 @@ void Object::BuildOutOfRangeUpdateBlock(UpdateData* data) const data->AddOutOfRangeGUID(GetGUID()); } -void Object::DestroyForPlayer(Player* target) const +void Object::DestroyForPlayer(Player* target, bool onDeath /*= false*/) const { ASSERT(target); - UpdateData updateData(target->GetMapId()); - BuildOutOfRangeUpdateBlock(&updateData); - WorldPacket packet; - updateData.BuildPacket(&packet); - target->SendDirectMessage(&packet); + WorldPacket data(SMSG_DESTROY_OBJECT, 8 + 1); + data << uint64(GetGUID()); + //! If the following bool is true, the client will call "void CGUnit_C::OnDeath()" for this object. + //! OnDeath() does for eg trigger death animation and interrupts certain spells/missiles/auras/sounds... + data << uint8(onDeath ? 1 : 0); + target->SendDirectMessage(&data); } int32 Object::GetInt32Value(uint16 index) const @@ -2679,7 +2680,11 @@ void WorldObject::DestroyForNearbyPlayers() if (isType(TYPEMASK_UNIT) && ToUnit()->GetCharmerGUID() == player->GetGUID()) /// @todo this is for puppet continue; - DestroyForPlayer(player); // at remove from world (destroy) show kill animation + if (GetTypeId() == TYPEID_UNIT) + DestroyForPlayer(player, ToUnit()->IsDuringRemoveFromWorld() && ToCreature()->isDead()); // at remove from world (destroy) show kill animation + else + DestroyForPlayer(player); + player->m_clientGUIDs.erase(GetGUID()); } } diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 2c7b585505..83dc4448c8 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -89,7 +89,7 @@ class TC_GAME_API Object void BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target) const; void BuildOutOfRangeUpdateBlock(UpdateData* data) const; - virtual void DestroyForPlayer(Player* target) const; + virtual void DestroyForPlayer(Player* target, bool onDeath = false) const; int32 GetInt32Value(uint16 index) const; uint32 GetUInt32Value(uint16 index) const; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 3be273399c..39340a6514 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -4056,9 +4056,9 @@ void Player::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c Unit::BuildCreateUpdateBlockForPlayer(data, target); } -void Player::DestroyForPlayer(Player* target) const +void Player::DestroyForPlayer(Player* target, bool onDeath /*= false*/) const { - Unit::DestroyForPlayer(target); + Unit::DestroyForPlayer(target, onDeath); for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) { @@ -5656,7 +5656,7 @@ inline int SkillGainChance(uint32 SkillValue, uint32 GrayLevel, uint32 GreenLeve return sWorld->getIntConfig(CONFIG_SKILL_CHANCE_GREY) * 10; if (SkillValue >= GreenLevel) return sWorld->getIntConfig(CONFIG_SKILL_CHANCE_GREEN)* 10; - if (SkillValue >= YellowLevel) + if (SkillValue >= YellowLevel) return sWorld->getIntConfig(CONFIG_SKILL_CHANCE_YELLOW) * 10; return sWorld->getIntConfig(CONFIG_SKILL_CHANCE_ORANGE) * 10; } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index a1e010d0be..af3d4f0684 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1856,7 +1856,7 @@ class TC_GAME_API Player : public Unit, public GridObject WorldSession* GetSession() const { return m_session; } void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const override; - void DestroyForPlayer(Player* target) const override; + void DestroyForPlayer(Player* target, bool onDeath = false) const override; void SendLogXPGain(uint32 GivenXP, Unit* victim, uint32 BonusXP, bool recruitAFriend = false, float group_rate=1.0f) const; // notifiers diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 0e8ebce701..7622f8cd9a 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -14665,7 +14665,7 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) data->append(fieldBuffer); } -void Unit::DestroyForPlayer(Player* target) const +void Unit::DestroyForPlayer(Player* target, bool onDeath /*= false*/) const { if (Battleground* bg = target->GetBattleground()) { diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 79b55c5dc1..ddc8cfc227 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -438,7 +438,7 @@ enum UnitState : uint32 UNIT_STATE_FOLLOW_MOVE = 0x08000000, UNIT_STATE_IGNORE_PATHFINDING = 0x10000000, // do not use pathfinding in any MovementGenerator - UNIT_STATE_ALL_STATE_SUPPORTED = UNIT_STATE_DIED | UNIT_STATE_MELEE_ATTACKING | UNIT_STATE_CHARMED | UNIT_STATE_STUNNED | UNIT_STATE_ROAMING | UNIT_STATE_CHASE + UNIT_STATE_ALL_STATE_SUPPORTED = UNIT_STATE_DIED | UNIT_STATE_MELEE_ATTACKING | UNIT_STATE_CHARMED | UNIT_STATE_STUNNED | UNIT_STATE_ROAMING | UNIT_STATE_CHASE | UNIT_STATE_FOCUSING | UNIT_STATE_FLEEING | UNIT_STATE_IN_FLIGHT | UNIT_STATE_FOLLOW | UNIT_STATE_ROOT | UNIT_STATE_CONFUSED | UNIT_STATE_DISTRACTED | UNIT_STATE_ISOLATED | UNIT_STATE_ATTACK_PLAYER | UNIT_STATE_CASTING | UNIT_STATE_POSSESSED | UNIT_STATE_CHARGING | UNIT_STATE_JUMPING | UNIT_STATE_MOVE | UNIT_STATE_ROTATING @@ -1912,7 +1912,7 @@ class TC_GAME_API Unit : public WorldObject explicit Unit (bool isWorldObject); void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const override; - void DestroyForPlayer(Player* target) const override; + void DestroyForPlayer(Player* target, bool onDeath = false) const override; UnitAI* i_AI, *i_disabledAI; diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 9cd66c1ce7..39591756f2 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -651,7 +651,7 @@ void OpcodeTable::Initialize() #define DEFINE_SERVER_OPCODE_HANDLER(opcode, status, con) \ ValidateAndSetServerOpcode(opcode, #opcode, status, con) - + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_DATA_TIMES, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_INFO_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_RESTRICTED_WARNING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); @@ -808,6 +808,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_DEATH_RELEASE_LOC, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DEBUG_RUNE_REGEN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DEFENSE_MESSAGE, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_DESTROY_OBJECT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DESTRUCTIBLE_BUILDING_DAMAGE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DIFFERENT_INSTANCE_FROM_PARTY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_DISENCHANT_CREDIT, STATUS_NEVER, CONNECTION_TYPE_REALM); diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index df7020bf53..e8b8d4b6f6 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -747,6 +747,7 @@ enum OpcodeServer SMSG_DEBUG_RUNE_REGEN = 0x31B3, SMSG_DEBUG_SERVER_GEO = 0x0235, SMSG_DEFENSE_MESSAGE = 0x0314, + SMSG_DESTROY_OBJECT = 0x4724, SMSG_DESTRUCTIBLE_BUILDING_DAMAGE = 0x4825, SMSG_DIFFERENT_INSTANCE_FROM_PARTY = 0x15B1, SMSG_DISENCHANT_CREDIT = 0x55A2,