From 8e9d2cdf01929f513e37eccbfdea952aa04e78f6 Mon Sep 17 00:00:00 2001 From: QAston Date: Sun, 10 Jan 2010 01:23:15 +0100 Subject: Update aura system: * Change system logic - unify Auras, AreaAuras and PersistentAreaAuras: * Aura has now its owner - which is the WorldObject, which applies aura (creates AuraApplication object) dependant on aura radius, and effect type * Owner can be Dynobj (DynObjAura class) for PersistentAreaAuras, or Unit (UnitAura class) for Area and nonArea auras * Aura data is shared for all units which have AuraApplication of the Aura * Because of that AuraEffect handlers , and periodic tick functions can't modify AuraEffect object (they are const now) * Remove spell source and AreaAuraEffect classes * Add AuraEffect::UpdatePeriodic function, to allow periodic aura object modification (target independant) * Add AuraEffect::CalculateAmount and AuraEffect::CalculateSpellMod function, to allow non-default amount calculation * AreaAura updates are done in owner _UpdateSpells cycle * Since now you don't need to wait an aura update cycle to get area aura applied on it's correct target list * And you can access area aura target list * Add basic support for aura amount recalculation * Save recalculation state and base amount of auras to db * Add AuraEffect::CalculatePeriodic function to determine if aura is periodic, and to set correct tick number after aura is loaded from db * Add ChangeAmount function in addition to SetAmount function, to allow easy reapplication of AuraEffect handlers on all targets * Sort aura effect handlers in SpellAuras.cpp and .h by their use * Add check for already existing aura of that type to some AuraEffect handlers, to prevent incorrect effect removal * SPELL_AURA_CONVERT_RUNE and MOD_POWER_REGEN and MOD_REGEN hacky handlers are now implemented correctly * Send aura application client update only once per unit update - prevent unnecesary packet spam * Fix ByteBuffer::appendPackGUID function - it added additionall 0s at the end of the packet * Fix memory leak at player creation (not deleted auras) * Updated some naming conventions (too many to mention) * Added Unit::GetAuraOfRankedSpell() function * Remove procflags on aura remove, use Aura::HandleAuraSpecificMods instead * Added functions to maintain owned auras (GetOwnedAuras, GetOwnedAura, RemoveOwnedAura, etc) * Implement AURA_INTERRUPT_FLAG_LANDING * Implement EffectPlayerNotification (thanks to Spp) * Remove wrong aura 304 handler * Add better handler for death runes * Remove unnecesary variables from DynamicObject class, and cleanup related code, link dynobj duration with aura * Add GetAuraEffectTriggerTarget function in CreatureAi for special target selection for periodic trigger auras used in a script * Add many assert() procection from idiots using some functions in wrong way * I am to lazy to write here anything more Thanks to Visagalis for testing this patch PS: Do not make patches like this, please --HG-- branch : trunk --- src/game/ObjectMgr.cpp | 63 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 20 deletions(-) (limited to 'src/game/ObjectMgr.cpp') diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 4197f52c689..7faca78d73a 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -781,27 +781,40 @@ void ObjectMgr::ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* { // Now add the auras, format "spellid effectindex spellid effectindex..." char *p,*s; - std::vector val; + std::map val; s=p=(char*)reinterpret_cast(addon->auras); if(p) { + uint32 currSpellId = 0; + bool spell = true; while (p[0]!=0) { ++p; - if (p[0]==' ') + if (p[0] == ' ' || p[0] == 0) { - val.push_back(atoi(s)); + if (spell) + currSpellId = atoi(s); + else + { + uint8 eff = atoi(s); + if (eff >=3) + { + sLog.outErrorDb("Creature (%s: %u) has wrong `auras` data in `%s`(too high aura effect: %d for spell: %d)",guidEntryStr,addon->guidOrEntry,table,eff,currSpellId); + } + val[currSpellId] |= 1<(addon->auras); // wrong list - if (val.size()%2) + if (!spell) { addon->auras = NULL; sLog.outErrorDb("Creature (%s: %u) has wrong `auras` data in `%s`.",guidEntryStr,addon->guidOrEntry,table); @@ -817,17 +830,17 @@ void ObjectMgr::ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* } // replace by new structures array - const_cast(addon->auras) = new CreatureDataAddonAura[val.size()/2+1]; + const_cast(addon->auras) = new CreatureDataAddonAura[val.size()+1]; uint32 i=0; - for (uint32 j = 0; j < val.size()/2; ++j) + for (std::map::iterator itr = val.begin(); itr!=val.end();++itr) { CreatureDataAddonAura& cAura = const_cast(addon->auras[i]); - cAura.spell_id = (uint32)val[2*j+0]; - cAura.effect_idx = (uint32)val[2*j+1]; - if ( cAura.effect_idx > 2 ) + cAura.spell_id = itr->first; + cAura.effectMask = itr->second; + if ( cAura.effectMask > 7 || !cAura.effectMask) { - sLog.outErrorDb("Creature (%s: %u) has wrong effect %u for spell %u in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.effect_idx,cAura.spell_id,table); + sLog.outErrorDb("Creature (%s: %u) has wrong effect for spell %u in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.spell_id,table); continue; } SpellEntry const *AdditionalSpellInfo = sSpellStore.LookupEntry(cAura.spell_id); @@ -836,11 +849,21 @@ void ObjectMgr::ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* sLog.outErrorDb("Creature (%s: %u) has wrong spell %u defined in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.spell_id,table); continue; } - - if (!AdditionalSpellInfo->Effect[cAura.effect_idx] || !AdditionalSpellInfo->EffectApplyAuraName[cAura.effect_idx]) + for (uint8 eff = 0; eff < MAX_SPELL_EFFECTS; ++eff) { - sLog.outErrorDb("Creature (%s: %u) has not aura effect %u of spell %u defined in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.effect_idx,cAura.spell_id,table); - continue; + if ((1<Effect[eff] || !AdditionalSpellInfo->EffectApplyAuraName[eff]) + { + sLog.outErrorDb("Creature (%s: %u) has not aura effect %u of spell %u defined in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,eff,cAura.spell_id,table); + continue; + } + else if (AdditionalSpellInfo->Effect[eff] == SPELL_EFFECT_PERSISTENT_AREA_AURA) + { + sLog.outErrorDb("Creature (%s: %u) has persistent area aura effect %u of spell %u defined in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,eff,cAura.spell_id,table); + continue; + } + } } ++i; @@ -849,7 +872,7 @@ void ObjectMgr::ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* // fill terminator element (after last added) CreatureDataAddonAura& endAura = const_cast(addon->auras[i]); endAura.spell_id = 0; - endAura.effect_idx = 0; + endAura.effectMask = 0; } void ObjectMgr::LoadCreatureAddons(SQLStorage& creatureaddons, char const* entryName, char const* comment) @@ -7641,9 +7664,9 @@ bool PlayerCondition::Meets(Player const * player) const } case CONDITION_AD_COMMISSION_AURA: { - Unit::AuraMap const& auras = player->GetAuras(); - for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) - if((itr->second->GetSpellProto()->Attributes & 0x1000010) && itr->second->GetSpellProto()->SpellVisual[0]==3580) + Unit::AuraApplicationMap const& auras = player->GetAppliedAuras(); + for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) + if((itr->second->GetBase()->GetSpellProto()->Attributes & 0x1000010) && itr->second->GetBase()->GetSpellProto()->SpellVisual[0]==3580) return true; return false; } -- cgit v1.2.3