diff --git a/src/game/DBCStores.cpp b/src/game/DBCStores.cpp index 33c7cc0aa..302c2b635 100644 --- a/src/game/DBCStores.cpp +++ b/src/game/DBCStores.cpp @@ -126,6 +126,7 @@ MapDifficultyMap sMapDifficultyMap; DBCStorage sMovieStore(MovieEntryfmt); +DBCStorage sOverrideSpellDataStore(OverrideSpellDatafmt); DBCStorage sQuestFactionRewardStore(QuestFactionRewardfmt); DBCStorage sQuestSortStore(QuestSortEntryfmt); DBCStorage sQuestXPLevelStore(QuestXPLevelfmt); @@ -359,7 +360,7 @@ void LoadDBCStores(const std::string& dataPath) exit(1); } - const uint32 DBCFilesCount = 89; + const uint32 DBCFilesCount = 90; barGoLink bar( (int)DBCFilesCount ); @@ -459,6 +460,7 @@ void LoadDBCStores(const std::string& dataPath) sMapDifficultyStore.Clear(); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMovieStore, dbcPath,"Movie.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sOverrideSpellDataStore, dbcPath,"OverrideSpellData.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestFactionRewardStore, dbcPath,"QuestFactionReward.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore, dbcPath,"QuestSort.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestXPLevelStore, dbcPath,"QuestXP.dbc"); diff --git a/src/game/DBCStores.h b/src/game/DBCStores.h index 8989580e8..21c1b4558 100644 --- a/src/game/DBCStores.h +++ b/src/game/DBCStores.h @@ -128,6 +128,7 @@ extern DBCStorage sMapStore; //extern DBCStorage sMapDifficultyStore; -- use GetMapDifficultyData insteed extern MapDifficultyMap sMapDifficultyMap; extern DBCStorage sMovieStore; +extern DBCStorage sOverrideSpellDataStore; extern DBCStorage sQuestFactionRewardStore; extern DBCStorage sQuestSortStore; extern DBCStorage sQuestXPLevelStore; diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h index d0b7becb7..49dcfb1ef 100644 --- a/src/game/DBCStructure.h +++ b/src/game/DBCStructure.h @@ -1196,6 +1196,15 @@ struct MovieEntry //uint32 unk2; // 2 always 100 }; +#define MAX_OVERRIDE_SPELLS 10 + +struct OverrideSpellDataEntry +{ + uint32 Id; // 0 index + uint32 Spells[MAX_OVERRIDE_SPELLS]; // 1-10 spells + //uint32 unk2; // 11 possibly flag +}; + struct PvPDifficultyEntry { //uint32 id; // 0 m_ID diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h index c26acd8d5..2402360b4 100644 --- a/src/game/DBCfmt.h +++ b/src/game/DBCfmt.h @@ -76,6 +76,7 @@ const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxssssssssssssssssx"; const char MapEntryfmt[]="nxixxssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxixx"; const char MapDifficultyEntryfmt[]="diixxxxxxxxxxxxxxxxxiix"; const char MovieEntryfmt[]="nxx"; +const char OverrideSpellDatafmt[]="niiiiiiiiiix"; const char QuestFactionRewardfmt[]="niiiiiiiiii"; const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx"; const char QuestXPLevelfmt[]="niiiiiiiiix"; diff --git a/src/game/Player.h b/src/game/Player.h index 3fbced915..11cfb40c7 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -578,11 +578,12 @@ enum PlayerFieldByteFlags PLAYER_FIELD_BYTE_NO_RELEASE_WINDOW = 0x00000010 // Display no "release spirit" window at all }; -// used in PLAYER_FIELD_BYTES2 values +// used in byte (PLAYER_FIELD_BYTES2,3) values enum PlayerFieldByte2Flags { - PLAYER_FIELD_BYTE2_NONE = 0x0000, - PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW = 0x4000 + PLAYER_FIELD_BYTE2_NONE = 0x00, + PLAYER_FIELD_BYTE2_STEALTH = 0x20, + PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW = 0x40 }; enum ActivateTaxiReplies diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index 288645d17..3d92ad751 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -328,7 +328,7 @@ enum AuraType SPELL_AURA_MOD_ALL_CRIT_CHANCE = 290, SPELL_AURA_MOD_QUEST_XP_PCT = 291, SPELL_AURA_OPEN_STABLE = 292, - SPELL_AURA_293 = 293, + SPELL_AURA_ADD_MECHANIC_ABILITIES = 293, SPELL_AURA_294 = 294, SPELL_AURA_295 = 295, SPELL_AURA_296 = 296, diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 1c091b7e9..bfcc06687 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -343,7 +343,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleAuraModAllCritChance, //290 SPELL_AURA_MOD_ALL_CRIT_CHANCE &Aura::HandleNoImmediateEffect, //291 SPELL_AURA_MOD_QUEST_XP_PCT implemented in Player::GiveXP &Aura::HandleAuraOpenStable, //292 call stabled pet - &Aura::HandleNULL, //293 3 spells + &Aura::HandleAuraAddMechanicAbilities, //293 SPELL_AURA_ADD_MECHANIC_ABILITIES replaces target's action bars with a predefined spellset &Aura::HandleNULL, //294 2 spells, possible prevent mana regen &Aura::HandleUnused, //295 unused (3.2.2a) &Aura::HandleNULL, //296 2 spells @@ -3928,7 +3928,7 @@ void Aura::HandleModStealth(bool apply, bool Real) target->SetStandFlags(UNIT_STAND_FLAGS_CREEP); if (target->GetTypeId()==TYPEID_PLAYER) - target->SetFlag(PLAYER_FIELD_BYTES2, 0x2000); + target->SetByteFlag(PLAYER_FIELD_BYTES2, 3, PLAYER_FIELD_BYTE2_STEALTH); // apply only if not in GM invisibility (and overwrite invisibility state) if (target->GetVisibility()!=VISIBILITY_OFF) @@ -3970,7 +3970,7 @@ void Aura::HandleModStealth(bool apply, bool Real) target->RemoveStandFlags(UNIT_STAND_FLAGS_CREEP); if (target->GetTypeId()==TYPEID_PLAYER) - target->RemoveFlag(PLAYER_FIELD_BYTES2, 0x2000); + target->RemoveByteFlag(PLAYER_FIELD_BYTES2, 3, PLAYER_FIELD_BYTE2_STEALTH); // restore invisibility if any if (target->HasAuraType(SPELL_AURA_MOD_INVISIBILITY)) @@ -4007,21 +4007,21 @@ void Aura::HandleInvisibility(bool apply, bool Real) { Unit *target = GetTarget(); - if(apply) + if (apply) { target->m_invisibilityMask |= (1 << m_modifier.m_miscvalue); target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); - if(Real && target->GetTypeId()==TYPEID_PLAYER) + if (Real && target->GetTypeId()==TYPEID_PLAYER) { // apply glow vision - target->SetFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW); + target->SetByteFlag(PLAYER_FIELD_BYTES2, 3, PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW); } // apply only if not in GM invisibility and not stealth - if(target->GetVisibility() == VISIBILITY_ON) + if (target->GetVisibility() == VISIBILITY_ON) { // Aura not added yet but visibility code expect temporary add aura target->SetVisibility(VISIBILITY_GROUP_NO_DETECT); @@ -4037,17 +4037,17 @@ void Aura::HandleInvisibility(bool apply, bool Real) target->m_invisibilityMask |= (1 << (*itr)->GetModifier()->m_miscvalue); // only at real aura remove and if not have different invisibility auras. - if(Real && target->m_invisibilityMask == 0) + if (Real && target->m_invisibilityMask == 0) { // remove glow vision - if(target->GetTypeId() == TYPEID_PLAYER) - target->RemoveFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW); + if (target->GetTypeId() == TYPEID_PLAYER) + target->RemoveByteFlag(PLAYER_FIELD_BYTES2, 3, PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW); // apply only if not in GM invisibility & not stealthed while invisible - if(target->GetVisibility() != VISIBILITY_OFF) + if (target->GetVisibility() != VISIBILITY_OFF) { // if have stealth aura then already have stealth visibility - if(!target->HasAuraType(SPELL_AURA_MOD_STEALTH)) + if (!target->HasAuraType(SPELL_AURA_MOD_STEALTH)) target->SetVisibility(VISIBILITY_ON); } } @@ -7574,6 +7574,42 @@ void Aura::HandleAuraControlVehicle(bool apply, bool Real) } } +void Aura::HandleAuraAddMechanicAbilities(bool apply, bool Real) +{ + if (!Real) + return; + + Unit* target = GetTarget(); + + if (!target || target->GetTypeId() != TYPEID_PLAYER) // only players should be affected by this aura + return; + + uint16 i_OverrideSetId = GetMiscValue(); + + const OverrideSpellDataEntry *spellSet = sOverrideSpellDataStore.LookupEntry(i_OverrideSetId); + if (!spellSet) + return; + + if (apply) + { + + // spell give the player a new castbar with some spells.. this is a clientside process.. + // serverside just needs to register the new spells so that player isn't kicked as cheater + for (int i = 0; i < MAX_OVERRIDE_SPELLS; i++) + if (uint32 spellId = spellSet->Spells[i]) + static_cast(target)->addSpell(spellId, true, false, false, false); + + target->SetUInt16Value(PLAYER_FIELD_BYTES2, 0, i_OverrideSetId); + } + else + { + target->SetUInt16Value(PLAYER_FIELD_BYTES2, 0, 0); + for (int i = 0; i < MAX_OVERRIDE_SPELLS; i++) + if (uint32 spellId = spellSet->Spells[i]) + static_cast(target)->removeSpell(spellId, false , false, false); + } +} + void Aura::HandleAuraOpenStable(bool apply, bool Real) { if(!Real || GetTarget()->GetTypeId() != TYPEID_PLAYER || !GetTarget()->IsInWorld()) diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index fa0dfff5b..57b89f8b3 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -364,6 +364,7 @@ class MANGOS_DLL_SPEC Aura void HandleModTargetArmorPct(bool Apply, bool Real); void HandleAuraModAllCritChance(bool Apply, bool Real); void HandleAuraOpenStable(bool apply, bool Real); + void HandleAuraAddMechanicAbilities(bool apply, bool Real); virtual ~Aura(); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 13e05d5d1..441abb8d6 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10839" + #define REVISION_NR "10840" #endif // __REVISION_NR_H__