mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 10: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 },
|
||||
/*0x3FF*/ { "MSG_GUILD_EVENT_LOG_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildEventLogQueryOpcode },
|
||||
/*0x400*/ { "CMSG_MAELSTROM_RENAME_GUILD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
|
||||
/*0x401*/ { "CMSG_GET_MIRRORIMAGE_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
|
||||
/*0x402*/ { "SMSG_MIRRORIMAGE_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
|
||||
/*0x401*/ { "CMSG_GET_MIRRORIMAGE_DATA", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGetMirrorimageData },
|
||||
/*0x402*/ { "SMSG_MIRRORIMAGE_DATA", STATUS_LOGGEDIN, 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 },
|
||||
/*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;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
uint8 slot;
|
||||
|
|
|
|||
|
|
@ -1178,6 +1178,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
Item* GetItemByLimitedCategory(uint32 limitedCategory) const;
|
||||
Item* GetItemByPos( uint16 pos ) 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, bool nonbroken, bool useable) const;
|
||||
Item* GetShield(bool useable = false) const;
|
||||
|
|
|
|||
|
|
@ -5531,6 +5531,25 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ enum AuraType
|
|||
SPELL_AURA_COMPREHEND_LANGUAGE = 244,
|
||||
SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS = 245,
|
||||
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_CONVERT_RUNE = 249,
|
||||
SPELL_AURA_MOD_INCREASE_HEALTH_2 = 250,
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
|
|||
&Aura::HandleComprehendLanguage, //244 SPELL_AURA_COMPREHEND_LANGUAGE
|
||||
&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::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::HandleAuraConvertRune, //249 SPELL_AURA_CONVERT_RUNE
|
||||
&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
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if(!Real)
|
||||
|
|
|
|||
|
|
@ -362,6 +362,7 @@ class MANGOS_DLL_SPEC Aura
|
|||
void HandlePreventFleeing(bool apply, bool Real);
|
||||
void HandleManaShield(bool apply, bool Real);
|
||||
void HandleArenaPreparation(bool apply, bool Real);
|
||||
void HandleAuraMirrorImage(bool apply, bool Real);
|
||||
void HandleAuraConvertRune(bool apply, bool Real);
|
||||
void HandleAuraIncreaseBaseHealthPercent(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_UNK2 = 0x00000004,
|
||||
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_FORCE_MOVE = 0x00000040,
|
||||
UNIT_FLAG2_DISARM_OFFHAND = 0x00000080, // also shield case
|
||||
|
|
|
|||
|
|
@ -840,6 +840,7 @@ class MANGOS_DLL_SPEC WorldSession
|
|||
void HandleCalendarGetNumPending(WorldPacket& recv_data);
|
||||
|
||||
void HandleSpellClick(WorldPacket& recv_data);
|
||||
void HandleGetMirrorimageData(WorldPacket& recv_data);
|
||||
void HandleAlterAppearanceOpcode(WorldPacket& recv_data);
|
||||
void HandleRemoveGlyphOpcode(WorldPacket& recv_data);
|
||||
void HandleCharCustomizeOpcode(WorldPacket& recv_data);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "11442"
|
||||
#define REVISION_NR "11443"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue