mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 19:37:03 +00:00
[11443] Implement SPELL_AURA_MIRROR_IMAGE (247) and related receive/reply packets
Inspired by different patches posted in forum, thanks guys for the help it was :D Signed-off-by: NoFantasy <nofantasy@nf.no>
This commit is contained in:
parent
d98b9b9670
commit
4c3b61d4f5
11 changed files with 160 additions and 6 deletions
|
|
@ -1051,8 +1051,8 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
|
||||||
/*0x3FE*/ { "MSG_GUILD_BANK_MONEY_WITHDRAWN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankMoneyWithdrawn },
|
/*0x3FE*/ { "MSG_GUILD_BANK_MONEY_WITHDRAWN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankMoneyWithdrawn },
|
||||||
/*0x3FF*/ { "MSG_GUILD_EVENT_LOG_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildEventLogQueryOpcode },
|
/*0x3FF*/ { "MSG_GUILD_EVENT_LOG_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildEventLogQueryOpcode },
|
||||||
/*0x400*/ { "CMSG_MAELSTROM_RENAME_GUILD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
|
/*0x400*/ { "CMSG_MAELSTROM_RENAME_GUILD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
|
||||||
/*0x401*/ { "CMSG_GET_MIRRORIMAGE_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
|
/*0x401*/ { "CMSG_GET_MIRRORIMAGE_DATA", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGetMirrorimageData },
|
||||||
/*0x402*/ { "SMSG_MIRRORIMAGE_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
|
/*0x402*/ { "SMSG_MIRRORIMAGE_DATA", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
|
||||||
/*0x403*/ { "SMSG_FORCE_DISPLAY_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
|
/*0x403*/ { "SMSG_FORCE_DISPLAY_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
|
||||||
/*0x404*/ { "SMSG_SPELL_CHANCE_RESIST_PUSHBACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
|
/*0x404*/ { "SMSG_SPELL_CHANCE_RESIST_PUSHBACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
|
||||||
/*0x405*/ { "CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
|
/*0x405*/ { "CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
|
||||||
|
|
|
||||||
|
|
@ -9183,6 +9183,16 @@ Item* Player::GetItemByPos( uint8 bag, uint8 slot ) const
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 Player::GetItemDisplayIdInSlot(uint8 bag, uint8 slot) const
|
||||||
|
{
|
||||||
|
const Item* pItem = GetItemByPos(bag, slot);
|
||||||
|
|
||||||
|
if (!pItem)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return pItem->GetProto()->DisplayInfoID;
|
||||||
|
}
|
||||||
|
|
||||||
Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool nonbroken, bool useable) const
|
Item* Player::GetWeaponForAttack(WeaponAttackType attackType, bool nonbroken, bool useable) const
|
||||||
{
|
{
|
||||||
uint8 slot;
|
uint8 slot;
|
||||||
|
|
|
||||||
|
|
@ -1178,6 +1178,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||||
Item* GetItemByLimitedCategory(uint32 limitedCategory) const;
|
Item* GetItemByLimitedCategory(uint32 limitedCategory) const;
|
||||||
Item* GetItemByPos( uint16 pos ) const;
|
Item* GetItemByPos( uint16 pos ) const;
|
||||||
Item* GetItemByPos( uint8 bag, uint8 slot ) const;
|
Item* GetItemByPos( uint8 bag, uint8 slot ) const;
|
||||||
|
uint32 GetItemDisplayIdInSlot(uint8 bag, uint8 slot) const;
|
||||||
Item* GetWeaponForAttack(WeaponAttackType attackType) const { return GetWeaponForAttack(attackType,false,false); }
|
Item* GetWeaponForAttack(WeaponAttackType attackType) const { return GetWeaponForAttack(attackType,false,false); }
|
||||||
Item* GetWeaponForAttack(WeaponAttackType attackType, bool nonbroken, bool useable) const;
|
Item* GetWeaponForAttack(WeaponAttackType attackType, bool nonbroken, bool useable) const;
|
||||||
Item* GetShield(bool useable = false) const;
|
Item* GetShield(bool useable = false) const;
|
||||||
|
|
|
||||||
|
|
@ -5531,6 +5531,25 @@ SpellCastResult Spell::CheckCast(bool strict)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SPELL_AURA_MIRROR_IMAGE:
|
||||||
|
{
|
||||||
|
Unit* pTarget = m_targets.getUnitTarget();
|
||||||
|
|
||||||
|
if (!pTarget)
|
||||||
|
return SPELL_FAILED_BAD_TARGETS;
|
||||||
|
|
||||||
|
if (pTarget->GetTypeId() != TYPEID_UNIT) // Target must be creature
|
||||||
|
return SPELL_FAILED_BAD_TARGETS;
|
||||||
|
|
||||||
|
if (pTarget == m_caster) // Clone self can't be accepted
|
||||||
|
return SPELL_FAILED_BAD_TARGETS;
|
||||||
|
|
||||||
|
// It is assumed that target can not be cloned if already cloned by same or other clone auras
|
||||||
|
if (!pTarget->GetAurasByType(SPELL_AURA_MIRROR_IMAGE).empty())
|
||||||
|
return SPELL_FAILED_BAD_TARGETS;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -282,7 +282,7 @@ enum AuraType
|
||||||
SPELL_AURA_COMPREHEND_LANGUAGE = 244,
|
SPELL_AURA_COMPREHEND_LANGUAGE = 244,
|
||||||
SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS = 245,
|
SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS = 245,
|
||||||
SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL = 246,
|
SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL = 246,
|
||||||
SPELL_AURA_247 = 247,
|
SPELL_AURA_MIRROR_IMAGE = 247,
|
||||||
SPELL_AURA_MOD_COMBAT_RESULT_CHANCE = 248,
|
SPELL_AURA_MOD_COMBAT_RESULT_CHANCE = 248,
|
||||||
SPELL_AURA_CONVERT_RUNE = 249,
|
SPELL_AURA_CONVERT_RUNE = 249,
|
||||||
SPELL_AURA_MOD_INCREASE_HEALTH_2 = 250,
|
SPELL_AURA_MOD_INCREASE_HEALTH_2 = 250,
|
||||||
|
|
|
||||||
|
|
@ -297,7 +297,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
|
||||||
&Aura::HandleComprehendLanguage, //244 SPELL_AURA_COMPREHEND_LANGUAGE
|
&Aura::HandleComprehendLanguage, //244 SPELL_AURA_COMPREHEND_LANGUAGE
|
||||||
&Aura::HandleNoImmediateEffect, //245 SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS implemented in Unit::CalculateAuraDuration
|
&Aura::HandleNoImmediateEffect, //245 SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS implemented in Unit::CalculateAuraDuration
|
||||||
&Aura::HandleNoImmediateEffect, //246 SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL implemented in Unit::CalculateAuraDuration
|
&Aura::HandleNoImmediateEffect, //246 SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL implemented in Unit::CalculateAuraDuration
|
||||||
&Aura::HandleNULL, //247 target to become a clone of the caster
|
&Aura::HandleAuraMirrorImage, //247 SPELL_AURA_MIRROR_IMAGE target to become a clone of the caster
|
||||||
&Aura::HandleNoImmediateEffect, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
|
&Aura::HandleNoImmediateEffect, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
|
||||||
&Aura::HandleAuraConvertRune, //249 SPELL_AURA_CONVERT_RUNE
|
&Aura::HandleAuraConvertRune, //249 SPELL_AURA_CONVERT_RUNE
|
||||||
&Aura::HandleAuraModIncreaseHealth, //250 SPELL_AURA_MOD_INCREASE_HEALTH_2
|
&Aura::HandleAuraModIncreaseHealth, //250 SPELL_AURA_MOD_INCREASE_HEALTH_2
|
||||||
|
|
@ -8032,6 +8032,44 @@ void Aura::HandleAuraOpenStable(bool apply, bool Real)
|
||||||
// client auto close stable dialog at !apply aura
|
// client auto close stable dialog at !apply aura
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Aura::HandleAuraMirrorImage(bool apply, bool Real)
|
||||||
|
{
|
||||||
|
if (!Real)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Target of aura should always be creature (ref Spell::CheckCast)
|
||||||
|
Creature* pCreature = (Creature*)GetTarget();
|
||||||
|
|
||||||
|
// Caster can be player or creature, the unit who pCreature will become an clone of.
|
||||||
|
Unit* caster = GetCaster();
|
||||||
|
|
||||||
|
if (apply)
|
||||||
|
{
|
||||||
|
pCreature->SetByteValue(UNIT_FIELD_BYTES_0, 0, caster->getRace());
|
||||||
|
pCreature->SetByteValue(UNIT_FIELD_BYTES_0, 1, caster->getClass());
|
||||||
|
pCreature->SetByteValue(UNIT_FIELD_BYTES_0, 2, caster->getGender());
|
||||||
|
pCreature->SetByteValue(UNIT_FIELD_BYTES_0, 3, caster->getPowerType());
|
||||||
|
|
||||||
|
pCreature->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_CLONED);
|
||||||
|
|
||||||
|
pCreature->SetDisplayId(caster->GetNativeDisplayId());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const CreatureInfo* cinfo = pCreature->GetCreatureInfo();
|
||||||
|
const CreatureModelInfo* minfo = sObjectMgr.GetCreatureModelInfo(pCreature->GetNativeDisplayId());
|
||||||
|
|
||||||
|
pCreature->SetByteValue(UNIT_FIELD_BYTES_0, 0, 0);
|
||||||
|
pCreature->SetByteValue(UNIT_FIELD_BYTES_0, 1, cinfo->unit_class);
|
||||||
|
pCreature->SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);
|
||||||
|
pCreature->SetByteValue(UNIT_FIELD_BYTES_0, 3, 0);
|
||||||
|
|
||||||
|
pCreature->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_CLONED);
|
||||||
|
|
||||||
|
pCreature->SetDisplayId(pCreature->GetNativeDisplayId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Aura::HandleAuraConvertRune(bool apply, bool Real)
|
void Aura::HandleAuraConvertRune(bool apply, bool Real)
|
||||||
{
|
{
|
||||||
if(!Real)
|
if(!Real)
|
||||||
|
|
|
||||||
|
|
@ -362,6 +362,7 @@ class MANGOS_DLL_SPEC Aura
|
||||||
void HandlePreventFleeing(bool apply, bool Real);
|
void HandlePreventFleeing(bool apply, bool Real);
|
||||||
void HandleManaShield(bool apply, bool Real);
|
void HandleManaShield(bool apply, bool Real);
|
||||||
void HandleArenaPreparation(bool apply, bool Real);
|
void HandleArenaPreparation(bool apply, bool Real);
|
||||||
|
void HandleAuraMirrorImage(bool apply, bool Real);
|
||||||
void HandleAuraConvertRune(bool apply, bool Real);
|
void HandleAuraConvertRune(bool apply, bool Real);
|
||||||
void HandleAuraIncreaseBaseHealthPercent(bool Apply, bool Real);
|
void HandleAuraIncreaseBaseHealthPercent(bool Apply, bool Real);
|
||||||
void HandleNoReagentUseAura(bool Apply, bool Real);
|
void HandleNoReagentUseAura(bool Apply, bool Real);
|
||||||
|
|
|
||||||
|
|
@ -609,3 +609,87 @@ void WorldSession::HandleSpellClick( WorldPacket & recv_data )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WorldSession::HandleGetMirrorimageData(WorldPacket& recv_data)
|
||||||
|
{
|
||||||
|
DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "WORLD: CMSG_GET_MIRRORIMAGE_DATA");
|
||||||
|
|
||||||
|
ObjectGuid guid;
|
||||||
|
recv_data >> guid;
|
||||||
|
|
||||||
|
Creature* pCreature = _player->GetMap()->GetAnyTypeCreature(guid);
|
||||||
|
|
||||||
|
if (!pCreature)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Unit::AuraList const& images = pCreature->GetAurasByType(SPELL_AURA_MIRROR_IMAGE);
|
||||||
|
|
||||||
|
if (images.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Unit* pCaster = images.front()->GetCaster();
|
||||||
|
|
||||||
|
WorldPacket data(SMSG_MIRRORIMAGE_DATA, 68);
|
||||||
|
|
||||||
|
data << guid;
|
||||||
|
data << (uint32)pCreature->GetDisplayId();
|
||||||
|
|
||||||
|
data << (uint8)pCreature->getRace();
|
||||||
|
data << (uint8)pCreature->getGender();
|
||||||
|
data << (uint8)pCreature->getClass();
|
||||||
|
|
||||||
|
if (pCaster->GetTypeId() == TYPEID_PLAYER)
|
||||||
|
{
|
||||||
|
Player* pPlayer = (Player*)pCaster;
|
||||||
|
|
||||||
|
// skin, face, hair, haircolor
|
||||||
|
data << (uint8)pPlayer->GetByteValue(PLAYER_BYTES, 0);
|
||||||
|
data << (uint8)pPlayer->GetByteValue(PLAYER_BYTES, 1);
|
||||||
|
data << (uint8)pPlayer->GetByteValue(PLAYER_BYTES, 2);
|
||||||
|
data << (uint8)pPlayer->GetByteValue(PLAYER_BYTES, 3);
|
||||||
|
|
||||||
|
// facial hair
|
||||||
|
data << (uint8)pPlayer->GetByteValue(PLAYER_BYTES_2, 0);
|
||||||
|
|
||||||
|
// guild id
|
||||||
|
data << (uint32)pPlayer->GetGuildId();
|
||||||
|
|
||||||
|
if (pPlayer->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM))
|
||||||
|
data << (uint32)0;
|
||||||
|
else
|
||||||
|
data << (uint32)pPlayer->GetItemDisplayIdInSlot(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_HEAD);
|
||||||
|
|
||||||
|
data << (uint32)pPlayer->GetItemDisplayIdInSlot(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_SHOULDERS);
|
||||||
|
data << (uint32)pPlayer->GetItemDisplayIdInSlot(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_BODY);
|
||||||
|
data << (uint32)pPlayer->GetItemDisplayIdInSlot(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_CHEST);
|
||||||
|
data << (uint32)pPlayer->GetItemDisplayIdInSlot(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_WAIST);
|
||||||
|
data << (uint32)pPlayer->GetItemDisplayIdInSlot(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_LEGS);
|
||||||
|
data << (uint32)pPlayer->GetItemDisplayIdInSlot(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_FEET);
|
||||||
|
data << (uint32)pPlayer->GetItemDisplayIdInSlot(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_WRISTS);
|
||||||
|
data << (uint32)pPlayer->GetItemDisplayIdInSlot(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_HANDS);
|
||||||
|
|
||||||
|
if (pPlayer->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_CLOAK))
|
||||||
|
data << (uint32)0;
|
||||||
|
else
|
||||||
|
data << (uint32)pPlayer->GetItemDisplayIdInSlot(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_BACK);
|
||||||
|
|
||||||
|
data << (uint32)pPlayer->GetItemDisplayIdInSlot(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_TABARD);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No data when cloner is not player, data is taken from CreatureDisplayInfoExtraEntry by model already
|
||||||
|
data << (uint8)0;
|
||||||
|
data << (uint8)0;
|
||||||
|
data << (uint8)0;
|
||||||
|
data << (uint8)0;
|
||||||
|
|
||||||
|
data << (uint8)0;
|
||||||
|
|
||||||
|
data << (uint32)0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 11; ++i)
|
||||||
|
data << (uint32)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendPacket(&data);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -547,7 +547,7 @@ enum UnitFlags2
|
||||||
UNIT_FLAG2_UNK1 = 0x00000002, // Hides body and body armor. Weapons and shoulder and head armor still visible
|
UNIT_FLAG2_UNK1 = 0x00000002, // Hides body and body armor. Weapons and shoulder and head armor still visible
|
||||||
UNIT_FLAG2_UNK2 = 0x00000004,
|
UNIT_FLAG2_UNK2 = 0x00000004,
|
||||||
UNIT_FLAG2_COMPREHEND_LANG = 0x00000008,
|
UNIT_FLAG2_COMPREHEND_LANG = 0x00000008,
|
||||||
UNIT_FLAG2_UNK4 = 0x00000010,
|
UNIT_FLAG2_CLONED = 0x00000010, // Used in SPELL_AURA_MIRROR_IMAGE
|
||||||
UNIT_FLAG2_UNK5 = 0x00000020,
|
UNIT_FLAG2_UNK5 = 0x00000020,
|
||||||
UNIT_FLAG2_FORCE_MOVE = 0x00000040,
|
UNIT_FLAG2_FORCE_MOVE = 0x00000040,
|
||||||
UNIT_FLAG2_DISARM_OFFHAND = 0x00000080, // also shield case
|
UNIT_FLAG2_DISARM_OFFHAND = 0x00000080, // also shield case
|
||||||
|
|
|
||||||
|
|
@ -840,6 +840,7 @@ class MANGOS_DLL_SPEC WorldSession
|
||||||
void HandleCalendarGetNumPending(WorldPacket& recv_data);
|
void HandleCalendarGetNumPending(WorldPacket& recv_data);
|
||||||
|
|
||||||
void HandleSpellClick(WorldPacket& recv_data);
|
void HandleSpellClick(WorldPacket& recv_data);
|
||||||
|
void HandleGetMirrorimageData(WorldPacket& recv_data);
|
||||||
void HandleAlterAppearanceOpcode(WorldPacket& recv_data);
|
void HandleAlterAppearanceOpcode(WorldPacket& recv_data);
|
||||||
void HandleRemoveGlyphOpcode(WorldPacket& recv_data);
|
void HandleRemoveGlyphOpcode(WorldPacket& recv_data);
|
||||||
void HandleCharCustomizeOpcode(WorldPacket& recv_data);
|
void HandleCharCustomizeOpcode(WorldPacket& recv_data);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "11442"
|
#define REVISION_NR "11443"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue