Jump to content

NoFantasy

Members
  • Posts

    175
  • Joined

  • Last visited

    Never
  • Donations

    0.00 GBP 

Everything posted by NoFantasy

  1. 7 years later: https://github.com/mangos/mangos/commit/673aff36591cad38c45e978d36e18baa63b4ee62 Lol Thanks guys, at least it was added eventually. Thread was very helpful when making code. As a side note, the aura is implemented generic. That means Mage ability will still not work, it will probably need a few dummy effects implemented and such first. But at least now the basic things are added, that's progress.
  2. I will try make an effort to get this aura added to master. There are several things in the suggested patches that must be changed, so it can work in a more generic way, not just designed for one spell/ability explicit. So far i got the below code, to implement the aura itself and the handling of the request/response packets. diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp index c19f218..89c6668 100644 --- a/src/game/Opcodes.cpp +++ b/src/game/Opcodes.cpp @@ -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 }, diff --git a/src/game/Player.cpp b/src/game/Player.cpp index ebf0243..6e4abb6 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -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; diff --git a/src/game/Player.h b/src/game/Player.h index 817bfc5..3316c6c 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -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; diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index 0271c90..f82fd21 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -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, diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index ea63078..5267c5e 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -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 @@ -8037,6 +8037,54 @@ void Aura::HandleAuraOpenStable(bool apply, bool Real) // client auto close stable dialog at !apply aura } +void Aura::HandleAuraMirrorImage(bool apply, bool Real) +{ + Unit* target = GetTarget(); + + // target of aura is always creature + if (target->GetTypeId() != TYPEID_UNIT) + return; + + Creature* pCreature = (Creature*)target; + + // Caster can be player or creature, the unit who pCreature will become an clone of. + Unit* caster = GetCaster(); + + // Makes no sense to attempt clone self + if (caster == target) + return; + + if (apply) + { + // Can't clone when already cloned + if (pCreature->HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_CLONED)) + return; + + 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) diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index 7a60fa9..f771dd7 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -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); diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index d3ca6ca..393c3d1 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -609,3 +609,78 @@ 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(); + + 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); + 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); +} diff --git a/src/game/Unit.h b/src/game/Unit.h index 2ecd7c7..8adbf60 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -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 diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index e80f687..bf396ce 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -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); Still experimental, but i think it should at least a fair start. Edit: changed slightly, after input from other devs. Made a helper function to get the display id of item.
  3. Translate from engrish to english then...?
  4. I have no custom fixes, but can also confirm this with the mentioned ability. Edit: I find other abilities too, like Shield Bash, Shield Slam, Devastate, Rend (warrior) to mention a few. Since I'm pretty clueless how it should work, I only mention them. In a logical way, it sounds strange they can all be used when you have your back to the target. All of the mentioned spells here and in the above posts have SPELL_ATTR_EX_UNK9 0x00000200. Since I'm a noob with player abilities, I'm leaving it to others to figure out if it can be related or not.
  5. Diff below is possibly more correct. This will check if aura is present, and if it is, break; to let database process further by using spell_scripts table (summoned comes running, do some talking and complete quest). src/game/SpellEffects.cpp | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 6854496..698d66c 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -1434,6 +1434,11 @@ void Spell::EffectDummy(SpellEffectIndex eff_idx) break; } + case 45958: // Signal Alliance + { + m_caster->CastSpell(m_caster, m_spellInfo->CalculateSimpleValue(eff_idx), true); + return; + } case 45980: // Re-Cursive Transmatter Injection { if (m_caster->GetTypeId() == TYPEID_PLAYER && unitTarget) @@ -6601,6 +6606,15 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx) m_caster->SetDisplayId(display_id); return; } + case 45958: // Signal Alliance + { + // "escort" aura not present, so let nothing happen + if (!m_caster->HasAura(m_spellInfo->CalculateSimpleValue(eff_idx))) + return; + // "escort" aura is present so break; and let DB table spell_scripts be used and process further. + else + break; + } case 46203: // Goblin Weather Machine { if (!unitTarget) If aura is not present, we must assume the minipet is not present either. The "escort" aura I think we can handle in this way: src/game/SpellAuras.cpp | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 6727fae..218e051 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -1973,6 +1973,14 @@ void Aura::HandleAuraDummy(bool apply, bool Real) case 43873: // Headless Horseman Laugh target->PlayDistanceSound(11965); return; + case 45963: // Call Alliance Deserter + { + // Escorting Alliance Deserter + if (target->GetMiniPet()) + target->CastSpell(target, 45957, true); + + return; + } case 46699: // Requires No Ammo if (target->GetTypeId() == TYPEID_PLAYER) // not use ammo and not allow use @@ -2378,6 +2386,12 @@ void Aura::HandleAuraDummy(bool apply, bool Real) target->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); return; } + case 45963: // Call Alliance Deserter + { + // Escorting Alliance Deserter + target->RemoveAurasDueToSpell(45957); + return; + } case 46308: // Burning Winds { // casted only at creatures at spawn The minipet have duration 15 minutes, which makes sense (and then the dummy aura). "Escort" aura will then be removed when the minipet duration ends.
  6. Not so sure this is correct. 1: Should use CalculateSimpleValue() not base points directly. 2: Searched google for video, and it show the aura from spell 45957 is present even after using the item. I suspect this aura only goes away when the summoned is no longer there (ref dummy aura from spell 45963 (from 45975)). The script effect is probably a check for the presence of aura, a condition for something as this effect often have.
  7. As far as I can tell, this is not correct. Using Google, I found info that shows the corpses will burn (some aura) for about 30 seconds before despawning. You also need to take spell 45713 (and related gossip for another quest) in to consideration, or you may end up with some funky side effects when more than one player is doing quests related to these guys. Furthermore, you attempt to ((Player*)m_caster)->KilledMonsterCredit(unitTarget->GetEntry(), unitTarget->GetObjectGuid()); which will only work for one of the expected targets. You would need to use data from creature_template.KillCreditN to make this work properly. Sadly, i have not found the burning aura yet, but this patch is rejected in any case, based on the above.
  8. Must be much easier to make data for the exceptions rather than the general. This makes total sense.
  9. Ok, confirmed to be wrong, moved to rejected (the functionality still need to be restored, just not in this way).
  10. I can't find any examples suggesting this patch is correct. As far as i can tell, OBJECT_FIELD_CREATED_BY is never set for GO's summoned with spell effect 76. Please provide this information/examples if it really exist
  11. Rejected, use DB table spell_script_target to control/limit valid targets.
  12. Parts with lookup spell and cast time index removed, it has no real use here. Since cast time index for spell has cast time 0, it's pointless. Rest added in [11179]
  13. [11096] in a simplified version.
  14. Can use m_caster instead of unitTarget. Basically it will the same for this case, just m_caster would be more clear. [11092]
  15. After making some changes in queries using PExecuteLog, the issue came up: what style should we use for the SQL. It looks like it's pretty much about one thing: what each of us find most easy to read, in addition to the needed style for portability. A few imaginary queries: UPDATE creature_template SET unit_flags=1 WHERE entry=1; UPDATE creature_template SET unit_flags = 1 WHERE entry = 1; INSERT INTO creature_template (entry,modelid_1) VALUES (1000,150); INSERT INTO creature_template (entry, modelid_1) VALUES (1000, 150); DELETE FROM creature_template WHERE entry<1; DELETE FROM creature_template WHERE entry < 1; It is mostly about the spacing, where do we add space, where do we not add any. It doesn't appear this forum has any feature for polls, so I guess the old fashioned reply feature has to be used instead. Personally i don't care as much what the outcome is, i care more about consistency in what we do. Feel free to add your comment with the preferred style
  16. I suck in PvP, both in-game, code and database, however: I was digging up the initial data provided to database, and it was like (sample): insert into `gameobject_battleground` (`guid`, `event1`, `event2`) values('90108','253','0'); insert into `gameobject_battleground` (`guid`, `event1`, `event2`) values('90107','253','0'); insert into `gameobject_battleground` (`guid`, `event1`, `event2`) values('90110','254','0'); insert into `gameobject_battleground` (`guid`, `event1`, `event2`) values('90109','254','0'); insert into `gameobject_battleground` (`guid`, `event1`, `event2`) values('90114','253','0'); insert into `gameobject_battleground` (`guid`, `event1`, `event2`) values('90113','253','0'); insert into `gameobject_battleground` (`guid`, `event1`, `event2`) values('90116','254','0'); insert into `gameobject_battleground` (`guid`, `event1`, `event2`) values('90115','254','0'); insert into `gameobject_battleground` (`guid`, `event1`, `event2`) values('90118','253','0'); insert into `gameobject_battleground` (`guid`, `event1`, `event2`) values('90117','253','0'); I have no idea what the intention was, to use 252 or 253. All i can say is that 253 makes most sense, since then next numbers (defines) are 254 and 255 and the comments in code says that the generic events "should get a high event id". I'm voting to just change the define, makes most sense, filling the gap.
  17. An alternative way may be needed, if some non-raid bosses behave in the same way. The code can be similar, but in difference, use creature_template.flags_extra to pre-set those who can have the ability.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use