mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16:37:01 +00:00
[11299] Handle aura durations in SpellAuraHolder
- Unit::CalculateSpellDuration split into two functions
- CalculateSpellDuration taking into account combo points and caster-side spell mods
- Unit::CalculateAuraDuration taking into account target-side spell mods
- Diminishing is now applied before duration reduction mods
- Implement saving per-effect periodic timers to DB (required for auras affected by haste)
This commit is contained in:
parent
5833d74963
commit
4687fa8cb4
19 changed files with 388 additions and 379 deletions
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
DROP TABLE IF EXISTS `character_db_version`;
|
||||
CREATE TABLE `character_db_version` (
|
||||
`required_11117_02_characters_world` bit(1) default NULL
|
||||
`required_11299_02_characters_pet_aura` bit(1) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
|
||||
|
||||
--
|
||||
|
|
@ -372,18 +372,17 @@ CREATE TABLE `character_aura` (
|
|||
`caster_guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Full Global Unique Identifier',
|
||||
`item_guid` int(11) unsigned NOT NULL default '0',
|
||||
`spell` int(11) unsigned NOT NULL default '0',
|
||||
`stackcount` int(11) NOT NULL default '1',
|
||||
`remaincharges` int(11) NOT NULL default '0',
|
||||
`stackcount` INT(11) UNSIGNED NOT NULL DEFAULT '1',
|
||||
`remaincharges` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`basepoints0` INT(11) NOT NULL DEFAULT '0',
|
||||
`basepoints1` INT(11) NOT NULL DEFAULT '0',
|
||||
`basepoints2` INT(11) NOT NULL DEFAULT '0',
|
||||
`maxduration0` INT(11) NOT NULL DEFAULT '0',
|
||||
`maxduration1` INT(11) NOT NULL DEFAULT '0',
|
||||
`maxduration2` INT(11) NOT NULL DEFAULT '0',
|
||||
`remaintime0` INT(11) NOT NULL DEFAULT '0',
|
||||
`remaintime1` INT(11) NOT NULL DEFAULT '0',
|
||||
`remaintime2` INT(11) NOT NULL DEFAULT '0',
|
||||
`effIndexMask` INT(11) NOT NULL DEFAULT '0',
|
||||
`periodictime0` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`periodictime1` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`periodictime2` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`maxduration` INT(11) NOT NULL DEFAULT '0',
|
||||
`remaintime` INT(11) NOT NULL DEFAULT '0',
|
||||
`effIndexMask` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`guid`,`caster_guid`,`item_guid`,`spell`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System';
|
||||
|
||||
|
|
@ -1565,18 +1564,17 @@ CREATE TABLE `pet_aura` (
|
|||
`caster_guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Full Global Unique Identifier',
|
||||
`item_guid` int(11) unsigned NOT NULL default '0',
|
||||
`spell` int(11) unsigned NOT NULL default '0',
|
||||
`stackcount` int(11) NOT NULL default '1',
|
||||
`remaincharges` int(11) NOT NULL default '0',
|
||||
`stackcount` INT(11) UNSIGNED NOT NULL DEFAULT '1',
|
||||
`remaincharges` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`basepoints0` INT(11) NOT NULL DEFAULT '0',
|
||||
`basepoints1` INT(11) NOT NULL DEFAULT '0',
|
||||
`basepoints2` INT(11) NOT NULL DEFAULT '0',
|
||||
`maxduration0` INT(11) NOT NULL DEFAULT '0',
|
||||
`maxduration1` INT(11) NOT NULL DEFAULT '0',
|
||||
`maxduration2` INT(11) NOT NULL DEFAULT '0',
|
||||
`remaintime0` INT(11) NOT NULL DEFAULT '0',
|
||||
`remaintime1` INT(11) NOT NULL DEFAULT '0',
|
||||
`remaintime2` INT(11) NOT NULL DEFAULT '0',
|
||||
`effIndexMask` INT(11) NOT NULL DEFAULT '0',
|
||||
`periodictime0` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`periodictime1` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`periodictime2` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`maxduration` INT(11) NOT NULL DEFAULT '0',
|
||||
`remaintime` INT(11) NOT NULL DEFAULT '0',
|
||||
`effIndexMask` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`guid`,`caster_guid`,`item_guid`,`spell`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet System';
|
||||
|
||||
|
|
|
|||
16
sql/updates/11299_01_characters_character_aura.sql
Normal file
16
sql/updates/11299_01_characters_character_aura.sql
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
ALTER TABLE character_db_version CHANGE COLUMN required_11117_02_characters_world required_11299_01_characters_character_aura bit;
|
||||
|
||||
TRUNCATE TABLE character_aura;
|
||||
ALTER TABLE character_aura
|
||||
CHANGE COLUMN `maxduration0` `maxduration` INT(11) NOT NULL DEFAULT '0',
|
||||
CHANGE COLUMN `remaintime0` `remaintime` INT(11) NOT NULL DEFAULT '0',
|
||||
ADD COLUMN `periodictime0` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `basepoints2`,
|
||||
ADD COLUMN `periodictime1` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `periodictime0`,
|
||||
ADD COLUMN `periodictime2` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `periodictime1`,
|
||||
DROP COLUMN `maxduration1`,
|
||||
DROP COLUMN `maxduration2`,
|
||||
DROP COLUMN `remaintime1`,
|
||||
DROP COLUMN `remaintime2`,
|
||||
CHANGE COLUMN `stackcount` `stackcount` INT(11) UNSIGNED NOT NULL DEFAULT '1',
|
||||
CHANGE COLUMN `remaincharges` `remaincharges` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE COLUMN `effIndexMask` `effIndexMask` INT(11) UNSIGNED NOT NULL DEFAULT '0';
|
||||
16
sql/updates/11299_02_characters_pet_aura.sql
Normal file
16
sql/updates/11299_02_characters_pet_aura.sql
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
ALTER TABLE character_db_version CHANGE COLUMN required_11299_01_characters_character_aura required_11299_02_characters_pet_aura bit;
|
||||
|
||||
TRUNCATE TABLE pet_aura;
|
||||
ALTER TABLE pet_aura
|
||||
CHANGE COLUMN `maxduration0` `maxduration` INT(11) NOT NULL DEFAULT '0',
|
||||
CHANGE COLUMN `remaintime0` `remaintime` INT(11) NOT NULL DEFAULT '0',
|
||||
ADD COLUMN `periodictime0` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `basepoints2`,
|
||||
ADD COLUMN `periodictime1` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `periodictime0`,
|
||||
ADD COLUMN `periodictime2` INT(11) UNSIGNED NOT NULL DEFAULT '0' AFTER `periodictime1`,
|
||||
DROP COLUMN `maxduration1`,
|
||||
DROP COLUMN `maxduration2`,
|
||||
DROP COLUMN `remaintime1`,
|
||||
DROP COLUMN `remaintime2`,
|
||||
CHANGE COLUMN `stackcount` `stackcount` INT(11) UNSIGNED NOT NULL DEFAULT '1',
|
||||
CHANGE COLUMN `remaincharges` `remaincharges` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
CHANGE COLUMN `effIndexMask` `effIndexMask` INT(11) UNSIGNED NOT NULL DEFAULT '0';
|
||||
|
|
@ -74,7 +74,7 @@ bool LoginQueryHolder::Initialize()
|
|||
"health, power1, power2, power3, power4, power5, power6, power7, specCount, activeSpec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars FROM characters WHERE guid = '%u'", m_guid.GetCounter());
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP, "SELECT groupId FROM group_member WHERE memberGuid ='%u'", m_guid.GetCounter());
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", m_guid.GetCounter());
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,item_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,maxduration0,maxduration1,maxduration2,remaintime0,remaintime1,remaintime2,effIndexMask FROM character_aura WHERE guid = '%u'", m_guid.GetCounter());
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,item_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,periodictime0,periodictime1,periodictime2,maxduration,remaintime,effIndexMask FROM character_aura WHERE guid = '%u'", m_guid.GetCounter());
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLS, "SELECT spell,active,disabled FROM character_spell WHERE guid = '%u'", m_guid.GetCounter());
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS, "SELECT quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4 FROM character_queststatus WHERE guid = '%u'", m_guid.GetCounter());
|
||||
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS,"SELECT quest FROM character_queststatus_daily WHERE guid = '%u'", m_guid.GetCounter());
|
||||
|
|
|
|||
|
|
@ -164,16 +164,7 @@ inline void MaNGOS::DynamicObjectUpdater::VisitHelper(Unit* target)
|
|||
|
||||
if (holder)
|
||||
{
|
||||
if (Aura* aura = holder->GetAuraByEffectIndex(eff_index))
|
||||
{
|
||||
// already exists, refresh duration
|
||||
if (aura->GetAuraDuration() >=0 && uint32(aura->GetAuraDuration()) < i_dynobject.GetDuration())
|
||||
{
|
||||
aura->SetAuraDuration(i_dynobject.GetDuration());
|
||||
holder->SendAuraUpdate(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!holder->GetAuraByEffectIndex(eff_index))
|
||||
{
|
||||
PersistentAreaAura* Aur = new PersistentAreaAura(spellInfo, eff_index, NULL, holder, target, i_dynobject.GetCaster());
|
||||
holder->AddAura(Aur, eff_index);
|
||||
|
|
@ -182,6 +173,11 @@ inline void MaNGOS::DynamicObjectUpdater::VisitHelper(Unit* target)
|
|||
Aur->ApplyModifier(true,true);
|
||||
holder->SetInUse(false);
|
||||
}
|
||||
else if (holder->GetAuraDuration() >= 0 && uint32(holder->GetAuraDuration()) < i_dynobject.GetDuration())
|
||||
{
|
||||
holder->SetAuraDuration(i_dynobject.GetDuration());
|
||||
holder->SendAuraUpdate(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1243,7 +1243,7 @@ void Pet::_LoadAuras(uint32 timediff)
|
|||
{
|
||||
RemoveAllAuras();
|
||||
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,item_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,maxduration0,maxduration1,maxduration2,remaintime0,remaintime1,remaintime2,effIndexMask FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber());
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,item_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,periodictime0,periodictime1,periodictime2,maxduration,remaintime,effIndexMask FROM pet_aura WHERE guid = '%u'", m_charmInfo->GetPetNumber());
|
||||
|
||||
if(result)
|
||||
{
|
||||
|
|
@ -1255,16 +1255,18 @@ void Pet::_LoadAuras(uint32 timediff)
|
|||
uint32 spellid = fields[2].GetUInt32();
|
||||
uint32 stackcount = fields[3].GetUInt32();
|
||||
uint32 remaincharges = fields[4].GetUInt32();
|
||||
int32 damage[MAX_EFFECT_INDEX];
|
||||
int32 maxduration[MAX_EFFECT_INDEX];
|
||||
int32 remaintime[MAX_EFFECT_INDEX];
|
||||
int32 damage[MAX_EFFECT_INDEX];
|
||||
uint32 periodicTime[MAX_EFFECT_INDEX];
|
||||
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
damage[i] = fields[i+5].GetInt32();
|
||||
maxduration[i] = fields[i+8].GetInt32();
|
||||
remaintime[i] = fields[i+11].GetInt32();
|
||||
periodicTime[i] = fields[i+8].GetUInt32();
|
||||
}
|
||||
uint32 effIndexMask = fields[14].GetUInt32();
|
||||
|
||||
int32 maxduration = fields[11].GetInt32();
|
||||
int32 remaintime = fields[12].GetInt32();
|
||||
uint32 effIndexMask = fields[13].GetUInt32();
|
||||
|
||||
SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid);
|
||||
if (!spellproto)
|
||||
|
|
@ -1277,6 +1279,14 @@ void Pet::_LoadAuras(uint32 timediff)
|
|||
if (caster_guid != GetGUID() && IsSingleTargetSpell(spellproto))
|
||||
continue;
|
||||
|
||||
if (remaintime != -1 && !IsPositiveSpell(spellproto))
|
||||
{
|
||||
if (remaintime/IN_MILLISECONDS <= int32(timediff))
|
||||
continue;
|
||||
|
||||
remaintime -= timediff*IN_MILLISECONDS;
|
||||
}
|
||||
|
||||
// prevent wrong values of remaincharges
|
||||
uint32 procCharges = spellproto->procCharges;
|
||||
if (procCharges)
|
||||
|
|
@ -1294,34 +1304,24 @@ void Pet::_LoadAuras(uint32 timediff)
|
|||
else if (!stackcount)
|
||||
stackcount = 1;
|
||||
|
||||
|
||||
SpellAuraHolder *holder = CreateSpellAuraHolder(spellproto, this, NULL);
|
||||
holder->SetLoadedState(caster_guid, ObjectGuid(HIGHGUID_ITEM, item_lowguid), stackcount, remaincharges, maxduration, remaintime);
|
||||
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
if ((effIndexMask & (1 << i)) == 0)
|
||||
continue;
|
||||
|
||||
if (remaintime[i] != -1 && !IsPositiveEffect(spellproto, SpellEffectIndex(i)))
|
||||
{
|
||||
if (remaintime[i]/IN_MILLISECONDS <= int32(timediff))
|
||||
continue;
|
||||
|
||||
remaintime[i] -= timediff*IN_MILLISECONDS;
|
||||
}
|
||||
|
||||
Aura* aura = CreateAura(spellproto, SpellEffectIndex(i), NULL, holder, this);
|
||||
if (!damage[i])
|
||||
damage[i] = aura->GetModifier()->m_amount;
|
||||
|
||||
aura->SetLoadedState(damage[i], maxduration[i], remaintime[i]);
|
||||
aura->SetLoadedState(damage[i], periodicTime[i]);
|
||||
holder->AddAura(aura, SpellEffectIndex(i));
|
||||
}
|
||||
|
||||
if (!holder->IsEmptyHolder())
|
||||
{
|
||||
holder->SetLoadedState(caster_guid, ObjectGuid(HIGHGUID_ITEM, item_lowguid), stackcount, remaincharges);
|
||||
AddSpellAuraHolder(holder);
|
||||
}
|
||||
else
|
||||
delete holder;
|
||||
}
|
||||
|
|
@ -1344,6 +1344,10 @@ void Pet::_SaveAuras()
|
|||
if (auraHolders.empty())
|
||||
return;
|
||||
|
||||
stmt = CharacterDatabase.CreateStatement(insAuras, "INSERT INTO pet_aura (guid, caster_guid, item_guid, spell, stackcount, remaincharges, "
|
||||
"basepoints0, basepoints1, basepoints2, periodictime0, periodictime1, periodictime2, maxduration, remaintime, effIndexMask) "
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
|
||||
for(SpellAuraHolderMap::const_iterator itr = auraHolders.begin(); itr != auraHolders.end(); ++itr)
|
||||
{
|
||||
SpellAuraHolder *holder = itr->second;
|
||||
|
|
@ -1365,16 +1369,14 @@ void Pet::_SaveAuras()
|
|||
//do not save single target holders (unless they were cast by the player)
|
||||
if (save && !holder->IsPassive() && !IsChanneledSpell(holder->GetSpellProto()) && (holder->GetCasterGUID() == GetGUID() || !holder->IsSingleTarget()))
|
||||
{
|
||||
int32 damage[MAX_EFFECT_INDEX];
|
||||
int32 remaintime[MAX_EFFECT_INDEX];
|
||||
int32 maxduration[MAX_EFFECT_INDEX];
|
||||
int32 damage[MAX_EFFECT_INDEX];
|
||||
uint32 periodicTime[MAX_EFFECT_INDEX];
|
||||
uint32 effIndexMask = 0;
|
||||
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
damage[i] = 0;
|
||||
remaintime[i] = 0;
|
||||
maxduration[i] = 0;
|
||||
periodicTime[i] = 0;
|
||||
|
||||
if (Aura *aur = holder->GetAuraByEffectIndex(SpellEffectIndex(i)))
|
||||
{
|
||||
|
|
@ -1383,8 +1385,7 @@ void Pet::_SaveAuras()
|
|||
continue;
|
||||
|
||||
damage[i] = aur->GetModifier()->m_amount;
|
||||
remaintime[i] = aur->GetAuraDuration();
|
||||
maxduration[i] = aur->GetAuraMaxDuration();
|
||||
periodicTime[i] = aur->GetModifier()->periodictime;
|
||||
effIndexMask |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
|
@ -1392,9 +1393,6 @@ void Pet::_SaveAuras()
|
|||
if (!effIndexMask)
|
||||
continue;
|
||||
|
||||
stmt = CharacterDatabase.CreateStatement(insAuras, "INSERT INTO pet_aura (guid, caster_guid, item_guid, spell, stackcount, remaincharges, basepoints0, basepoints1, basepoints2, maxduration0, maxduration1, maxduration2, remaintime0, remaintime1, remaintime2, effIndexMask) "
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
|
||||
stmt.addUInt32(m_charmInfo->GetPetNumber());
|
||||
stmt.addUInt64(holder->GetCasterGuid().GetRawValue());
|
||||
stmt.addUInt32(holder->GetCastItemGuid().GetCounter());
|
||||
|
|
@ -1402,15 +1400,14 @@ void Pet::_SaveAuras()
|
|||
stmt.addUInt32(holder->GetStackAmount());
|
||||
stmt.addUInt8(holder->GetAuraCharges());
|
||||
|
||||
for (int i = EFFECT_INDEX_0; i <= EFFECT_INDEX_2; ++i )
|
||||
for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
stmt.addInt32(damage[i]);
|
||||
|
||||
for (int i = EFFECT_INDEX_0; i <= EFFECT_INDEX_2; ++i )
|
||||
stmt.addInt32(maxduration[i]);
|
||||
|
||||
for (int i = EFFECT_INDEX_0; i <= EFFECT_INDEX_2; ++i )
|
||||
stmt.addInt32(remaintime[i]);
|
||||
for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
stmt.addUInt32(periodicTime[i]);
|
||||
|
||||
stmt.addInt32(holder->GetAuraMaxDuration());
|
||||
stmt.addInt32(holder->GetAuraDuration());
|
||||
stmt.addUInt32(effIndexMask);
|
||||
stmt.Execute();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4544,10 +4544,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
|
|||
|
||||
if (SpellAuraHolder* holder = GetSpellAuraHolder(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS))
|
||||
{
|
||||
for(int i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
if(Aura* Aur = holder->GetAuraByEffectIndex(SpellEffectIndex(i)))
|
||||
Aur->SetAuraDuration(delta*IN_MILLISECONDS);
|
||||
|
||||
holder->SetAuraDuration(delta*IN_MILLISECONDS);
|
||||
holder->SendAuraUpdate(false);
|
||||
}
|
||||
}
|
||||
|
|
@ -15931,7 +15928,7 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
|
|||
{
|
||||
//RemoveAllAuras(); -- some spells casted before aura load, for example in LoadSkills, aura list explicitly cleaned early
|
||||
|
||||
//QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,item_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,maxduration0,maxduration1,maxduration2,remaintime0,remaintime1,remaintime2,effIndexMask FROM character_aura WHERE guid = '%u'",GetGUIDLow());
|
||||
//QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,item_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,periodictime0,periodictime1,periodictime2,maxduration,remaintime,effIndexMask FROM character_aura WHERE guid = '%u'",GetGUIDLow());
|
||||
|
||||
if(result)
|
||||
{
|
||||
|
|
@ -15943,16 +15940,18 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
|
|||
uint32 spellid = fields[2].GetUInt32();
|
||||
uint32 stackcount = fields[3].GetUInt32();
|
||||
uint32 remaincharges = fields[4].GetUInt32();
|
||||
int32 damage[MAX_EFFECT_INDEX];
|
||||
int32 maxduration[MAX_EFFECT_INDEX];
|
||||
int32 remaintime[MAX_EFFECT_INDEX];
|
||||
int32 damage[MAX_EFFECT_INDEX];
|
||||
uint32 periodicTime[MAX_EFFECT_INDEX];
|
||||
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
damage[i] = fields[i+5].GetInt32();
|
||||
maxduration[i] = fields[i+8].GetInt32();
|
||||
remaintime[i] = fields[i+11].GetInt32();
|
||||
periodicTime[i] = fields[i+8].GetUInt32();
|
||||
}
|
||||
uint32 effIndexMask = fields[14].GetUInt32();
|
||||
|
||||
int32 maxduration = fields[11].GetInt32();
|
||||
int32 remaintime = fields[12].GetInt32();
|
||||
uint32 effIndexMask = fields[13].GetUInt32();
|
||||
|
||||
SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid);
|
||||
if (!spellproto)
|
||||
|
|
@ -15961,6 +15960,14 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (remaintime != -1 && !IsPositiveSpell(spellproto))
|
||||
{
|
||||
if (remaintime/IN_MILLISECONDS <= int32(timediff))
|
||||
continue;
|
||||
|
||||
remaintime -= timediff*IN_MILLISECONDS;
|
||||
}
|
||||
|
||||
// prevent wrong values of remaincharges
|
||||
if (spellproto->procCharges)
|
||||
{
|
||||
|
|
@ -15978,24 +15985,18 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
|
|||
stackcount = 1;
|
||||
|
||||
SpellAuraHolder *holder = CreateSpellAuraHolder(spellproto, this, NULL);
|
||||
holder->SetLoadedState(caster_guid, ObjectGuid(HIGHGUID_ITEM, item_lowguid), stackcount, remaincharges, maxduration, remaintime);
|
||||
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
if ((effIndexMask & (1 << i)) == 0)
|
||||
continue;
|
||||
|
||||
if (remaintime[i] != -1 && !IsPositiveEffect(spellproto, SpellEffectIndex(i)))
|
||||
{
|
||||
if (remaintime[i]/IN_MILLISECONDS <= int32(timediff))
|
||||
continue;
|
||||
|
||||
remaintime[i] -= timediff*IN_MILLISECONDS;
|
||||
}
|
||||
|
||||
Aura* aura = CreateAura(spellproto, SpellEffectIndex(i), NULL, holder, this);
|
||||
if (!damage[i])
|
||||
damage[i] = aura->GetModifier()->m_amount;
|
||||
|
||||
aura->SetLoadedState(damage[i], maxduration[i], remaintime[i]);
|
||||
aura->SetLoadedState(damage[i], periodicTime[i]);
|
||||
holder->AddAura(aura, SpellEffectIndex(i));
|
||||
}
|
||||
|
||||
|
|
@ -16005,7 +16006,6 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
|
|||
if (caster_guid != GetObjectGuid() && holder->IsSingleTarget())
|
||||
holder->SetIsSingleTarget(false);
|
||||
|
||||
holder->SetLoadedState(caster_guid, ObjectGuid(HIGHGUID_ITEM, item_lowguid), stackcount, remaincharges);
|
||||
AddSpellAuraHolder(holder);
|
||||
DETAIL_LOG("Added auras from spellid %u", spellproto->Id);
|
||||
}
|
||||
|
|
@ -17355,9 +17355,9 @@ void Player::_SaveAuras()
|
|||
if (auraHolders.empty())
|
||||
return;
|
||||
|
||||
stmt = CharacterDatabase.CreateStatement(insertAuras, "INSERT INTO character_aura (guid, caster_guid, item_guid, spell, stackcount, "
|
||||
"remaincharges, basepoints0,basepoints1, basepoints2, maxduration0, maxduration1, maxduration2, remaintime0, remaintime1, remaintime2, effIndexMask) "
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
stmt = CharacterDatabase.CreateStatement(insertAuras, "INSERT INTO character_aura (guid, caster_guid, item_guid, spell, stackcount, remaincharges, "
|
||||
"basepoints0, basepoints1, basepoints2, periodictime0, periodictime1, periodictime2, maxduration, remaintime, effIndexMask) "
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
|
||||
for(SpellAuraHolderMap::const_iterator itr = auraHolders.begin(); itr != auraHolders.end(); ++itr)
|
||||
{
|
||||
|
|
@ -17366,16 +17366,14 @@ void Player::_SaveAuras()
|
|||
//do not save single target holders (unless they were cast by the player)
|
||||
if (!holder->IsPassive() && !IsChanneledSpell(holder->GetSpellProto()) && (holder->GetCasterGUID() == GetGUID() || !holder->IsSingleTarget()))
|
||||
{
|
||||
int32 damage[MAX_EFFECT_INDEX];
|
||||
int32 remaintime[MAX_EFFECT_INDEX];
|
||||
int32 maxduration[MAX_EFFECT_INDEX];
|
||||
int32 damage[MAX_EFFECT_INDEX];
|
||||
uint32 periodicTime[MAX_EFFECT_INDEX];
|
||||
uint32 effIndexMask = 0;
|
||||
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
damage[i] = 0;
|
||||
remaintime[i] = 0;
|
||||
maxduration[i] = 0;
|
||||
periodicTime[i] = 0;
|
||||
|
||||
if (Aura *aur = holder->GetAuraByEffectIndex(SpellEffectIndex(i)))
|
||||
{
|
||||
|
|
@ -17384,8 +17382,7 @@ void Player::_SaveAuras()
|
|||
continue;
|
||||
|
||||
damage[i] = aur->GetModifier()->m_amount;
|
||||
remaintime[i] = aur->GetAuraDuration();
|
||||
maxduration[i] = aur->GetAuraMaxDuration();
|
||||
periodicTime[i] = aur->GetModifier()->periodictime;
|
||||
effIndexMask |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
|
@ -17399,12 +17396,15 @@ void Player::_SaveAuras()
|
|||
stmt.addUInt32(holder->GetId());
|
||||
stmt.addUInt32(holder->GetStackAmount());
|
||||
stmt.addUInt8(holder->GetAuraCharges());
|
||||
for (int k = 0; k < MAX_EFFECT_INDEX; ++k)
|
||||
stmt.addInt32(damage[k]);
|
||||
for (int k = 0; k < MAX_EFFECT_INDEX; ++k)
|
||||
stmt.addInt32(maxduration[k]);
|
||||
for (int k = 0; k < MAX_EFFECT_INDEX; ++k)
|
||||
stmt.addInt32(remaintime[k]);
|
||||
|
||||
for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
stmt.addInt32(damage[i]);
|
||||
|
||||
for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
stmt.addUInt32(periodicTime[i]);
|
||||
|
||||
stmt.addInt32(holder->GetAuraMaxDuration());
|
||||
stmt.addInt32(holder->GetAuraDuration());
|
||||
stmt.addUInt32(effIndexMask);
|
||||
stmt.Execute();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1577,7 +1577,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
ObjectGuid const& GetSelectionGuid( ) const { return m_curSelectionGuid; }
|
||||
void SetSelectionGuid(ObjectGuid guid) { m_curSelectionGuid = guid; SetTargetGuid(guid); }
|
||||
|
||||
uint8 GetComboPoints() { return m_comboPoints; }
|
||||
uint8 GetComboPoints() const { return m_comboPoints; }
|
||||
ObjectGuid const& GetComboTargetGuid() const { return m_comboTargetGuid; }
|
||||
|
||||
void AddComboPoints(Unit* target, int8 count);
|
||||
|
|
|
|||
|
|
@ -1150,7 +1150,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
|||
((Creature*)m_caster)->AI()->SpellHitTarget(unit, m_spellInfo);
|
||||
}
|
||||
|
||||
void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
|
||||
void Spell::DoSpellHitOnUnit(Unit *unit, uint32 effectMask)
|
||||
{
|
||||
if (!unit || !effectMask)
|
||||
return;
|
||||
|
|
@ -1264,9 +1264,12 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
|
|||
CastPreCastSpells(unit);
|
||||
|
||||
if (IsSpellAppliesAura(m_spellInfo, effectMask))
|
||||
spellAuraHolder = CreateSpellAuraHolder(m_spellInfo, unit, realCaster, m_CastItem);
|
||||
{
|
||||
m_spellAuraHolder = CreateSpellAuraHolder(m_spellInfo, unit, realCaster, m_CastItem);
|
||||
m_spellAuraHolder->setDiminishGroup(m_diminishGroup);
|
||||
}
|
||||
else
|
||||
spellAuraHolder = NULL;
|
||||
m_spellAuraHolder = NULL;
|
||||
|
||||
for(int effectNumber = 0; effectNumber < MAX_EFFECT_INDEX; ++effectNumber)
|
||||
{
|
||||
|
|
@ -1287,13 +1290,39 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
|
|||
}
|
||||
|
||||
// now apply all created auras
|
||||
if (spellAuraHolder)
|
||||
if (m_spellAuraHolder)
|
||||
{
|
||||
// normally shouldn't happen
|
||||
if (!spellAuraHolder->IsEmptyHolder())
|
||||
unit->AddSpellAuraHolder(spellAuraHolder);
|
||||
if (!m_spellAuraHolder->IsEmptyHolder())
|
||||
{
|
||||
int32 duration = m_spellAuraHolder->GetAuraMaxDuration();
|
||||
int32 originalDuration = duration;
|
||||
|
||||
if (duration > 0)
|
||||
{
|
||||
int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, m_spellInfo);
|
||||
unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_caster, m_diminishLevel, limitduration);
|
||||
|
||||
// Fully diminished
|
||||
if (duration == 0)
|
||||
{
|
||||
delete m_spellAuraHolder;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
duration = unit->CalculateAuraDuration(m_spellInfo, effectMask, duration, m_caster);
|
||||
|
||||
if (duration != originalDuration)
|
||||
{
|
||||
m_spellAuraHolder->SetAuraMaxDuration(duration);
|
||||
m_spellAuraHolder->SetAuraDuration(duration);
|
||||
}
|
||||
|
||||
unit->AddSpellAuraHolder(m_spellAuraHolder);
|
||||
}
|
||||
else
|
||||
delete spellAuraHolder;
|
||||
delete m_spellAuraHolder;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2771,7 +2800,7 @@ void Spell::prepare(SpellCastTargets const* targets, Aura* triggeredByAura)
|
|||
if(triggeredByAura)
|
||||
{
|
||||
SendChannelUpdate(0);
|
||||
triggeredByAura->SetAuraDuration(0);
|
||||
triggeredByAura->GetHolder()->SetAuraDuration(0);
|
||||
}
|
||||
SendCastResult(result);
|
||||
finish(false);
|
||||
|
|
@ -3126,12 +3155,10 @@ void Spell::handle_immediate()
|
|||
// start channeling if applicable
|
||||
if(IsChanneledSpell(m_spellInfo))
|
||||
{
|
||||
int32 duration = GetSpellDuration(m_spellInfo);
|
||||
if (duration)
|
||||
int32 duration = CalculateSpellDuration(m_spellInfo, m_caster);
|
||||
|
||||
if (duration > 0)
|
||||
{
|
||||
// Apply duration mod
|
||||
if(Player* modOwner = m_caster->GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
|
||||
m_spellState = SPELL_STATE_CASTING;
|
||||
SendChannelStart(duration);
|
||||
}
|
||||
|
|
@ -5694,7 +5721,7 @@ SpellCastResult Spell::CheckCasterAuras() const
|
|||
{
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
if (GetSpellMechanicMask(itr->second->GetSpellProto(), i) & mechanic_immune)
|
||||
if (GetSpellMechanicMask(itr->second->GetSpellProto(), 1 << i) & mechanic_immune)
|
||||
continue;
|
||||
if (GetSpellSchoolMask(itr->second->GetSpellProto()) & school_immune)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -542,7 +542,7 @@ class Spell
|
|||
Unit* unitTarget;
|
||||
Item* itemTarget;
|
||||
GameObject* gameObjTarget;
|
||||
SpellAuraHolder* spellAuraHolder; // spell aura holder for current target, created only if spell has aura applying effect
|
||||
SpellAuraHolder* m_spellAuraHolder; // spell aura holder for current target, created only if spell has aura applying effect
|
||||
int32 damage;
|
||||
|
||||
// this is set in Spell Hit, but used in Apply Aura handler
|
||||
|
|
|
|||
|
|
@ -282,9 +282,9 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
|
|||
&Aura::HandleNoImmediateEffect, //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE implemented in Unit::SpellDamageBonusTaken
|
||||
&Aura::HandleAuraModIncreaseMaxHealth, //230 Commanding Shout
|
||||
&Aura::HandleNoImmediateEffect, //231 SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE
|
||||
&Aura::HandleNoImmediateEffect, //232 SPELL_AURA_MECHANIC_DURATION_MOD implement in Unit::CalculateSpellDuration
|
||||
&Aura::HandleNoImmediateEffect, //232 SPELL_AURA_MECHANIC_DURATION_MOD implement in Unit::CalculateAuraDuration
|
||||
&Aura::HandleNULL, //233 set model id to the one of the creature with id m_modifier.m_miscvalue
|
||||
&Aura::HandleNoImmediateEffect, //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateSpellDuration
|
||||
&Aura::HandleNoImmediateEffect, //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateAuraDuration
|
||||
&Aura::HandleAuraModDispelResist, //235 SPELL_AURA_MOD_DISPEL_RESIST implement in Unit::MagicSpellHitResult
|
||||
&Aura::HandleAuraControlVehicle, //236 SPELL_AURA_CONTROL_VEHICLE
|
||||
&Aura::HandleModSpellDamagePercentFromAttackPower, //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER implemented in Unit::SpellBaseDamageBonusDone
|
||||
|
|
@ -295,8 +295,8 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
|
|||
&Aura::HandleUnused, //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING (only 2 test spels in 3.2.2a)
|
||||
&Aura::HandleNULL, //243 faction reaction override spells
|
||||
&Aura::HandleComprehendLanguage, //244 SPELL_AURA_COMPREHEND_LANGUAGE
|
||||
&Aura::HandleNoImmediateEffect, //245 SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS implemented in Unit::CalculateSpellDuration
|
||||
&Aura::HandleNoImmediateEffect, //246 SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL implemented in Unit::CalculateSpellDuration
|
||||
&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::HandleNoImmediateEffect, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
|
||||
&Aura::HandleAuraConvertRune, //249 SPELL_AURA_CONVERT_RUNE
|
||||
|
|
@ -372,33 +372,24 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
|
|||
static AuraType const frozenAuraTypes[] = { SPELL_AURA_MOD_ROOT, SPELL_AURA_MOD_STUN, SPELL_AURA_NONE };
|
||||
|
||||
Aura::Aura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, SpellAuraHolder *holder, Unit *target, Unit *caster, Item* castItem) :
|
||||
m_spellmod(NULL),
|
||||
m_timeCla(1000), m_periodicTimer(0), m_periodicTick(0), m_removeMode(AURA_REMOVE_BY_DEFAULT),
|
||||
m_spellmod(NULL), m_periodicTimer(0), m_periodicTick(0), m_removeMode(AURA_REMOVE_BY_DEFAULT),
|
||||
m_effIndex(eff), m_positive(false), m_isPeriodic(false), m_isAreaAura(false),
|
||||
m_isPersistent(false), m_in_use(0), m_spellAuraHolder(holder)
|
||||
{
|
||||
MANGOS_ASSERT(target);
|
||||
|
||||
MANGOS_ASSERT(spellproto && spellproto == sSpellStore.LookupEntry( spellproto->Id ) && "`info` must be pointer to sSpellStore element");
|
||||
|
||||
m_currentBasePoints = currentBasePoints ? *currentBasePoints : spellproto->CalculateSimpleValue(eff);
|
||||
|
||||
bool isPassive = IsPassiveSpell(GetSpellProto());
|
||||
bool isPermanent = false;
|
||||
m_positive = IsPositiveEffect(spellproto, m_effIndex);
|
||||
|
||||
m_applyTime = time(NULL);
|
||||
|
||||
int32 damage;
|
||||
if (!caster)
|
||||
{
|
||||
damage = m_currentBasePoints;
|
||||
m_maxduration = target->CalculateSpellDuration(spellproto, m_effIndex, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
damage = caster->CalculateSpellDamage(target, spellproto, m_effIndex, &m_currentBasePoints);
|
||||
m_maxduration = caster->CalculateSpellDuration(spellproto, m_effIndex, target);
|
||||
damage = caster->CalculateSpellDamage(target, spellproto, m_effIndex, &m_currentBasePoints);
|
||||
|
||||
if (!damage && castItem && castItem->GetItemSuffixFactor())
|
||||
{
|
||||
|
|
@ -427,32 +418,19 @@ m_isPersistent(false), m_in_use(0), m_spellAuraHolder(holder)
|
|||
}
|
||||
}
|
||||
|
||||
if (m_maxduration == -1 || (isPassive && spellproto->DurationIndex == 0))
|
||||
isPermanent = true;
|
||||
|
||||
Player* modOwner = caster ? caster->GetSpellModOwner() : NULL;
|
||||
|
||||
if (!isPermanent && modOwner)
|
||||
{
|
||||
modOwner->ApplySpellMod(spellproto->Id, SPELLMOD_DURATION, m_maxduration);
|
||||
// Get zero duration aura after - need set m_maxduration > 0 for apply/remove aura work
|
||||
if (m_maxduration<=0)
|
||||
m_maxduration = 1;
|
||||
}
|
||||
|
||||
m_duration = m_maxduration;
|
||||
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Aura: construct Spellid : %u, Aura : %u Duration : %d Target : %d Damage : %d", spellproto->Id, spellproto->EffectApplyAuraName[eff], m_maxduration, spellproto->EffectImplicitTargetA[eff],damage);
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Aura: construct Spellid : %u, Aura : %u Target : %d Damage : %d", spellproto->Id, spellproto->EffectApplyAuraName[eff], spellproto->EffectImplicitTargetA[eff], damage);
|
||||
|
||||
SetModifier(AuraType(spellproto->EffectApplyAuraName[eff]), damage, spellproto->EffectAmplitude[eff], spellproto->EffectMiscValue[eff]);
|
||||
|
||||
Player* modOwner = caster ? caster->GetSpellModOwner() : NULL;
|
||||
|
||||
// Apply periodic time mod
|
||||
if(modOwner && m_modifier.periodictime)
|
||||
if (modOwner && m_modifier.periodictime)
|
||||
modOwner->ApplySpellMod(spellproto->Id, SPELLMOD_ACTIVATION_TIME, m_modifier.periodictime);
|
||||
|
||||
// Start periodic on next tick or at aura apply
|
||||
if (!(spellproto->AttributesEx5 & SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY))
|
||||
m_periodicTimer += m_modifier.periodictime;
|
||||
m_periodicTimer = m_modifier.periodictime;
|
||||
}
|
||||
|
||||
Aura::~Aura()
|
||||
|
|
@ -569,34 +547,7 @@ void Aura::SetModifier(AuraType t, int32 a, uint32 pt, int32 miscValue)
|
|||
|
||||
void Aura::Update(uint32 diff)
|
||||
{
|
||||
if (m_duration > 0)
|
||||
{
|
||||
m_duration -= diff;
|
||||
if (m_duration < 0)
|
||||
m_duration = 0;
|
||||
m_timeCla -= diff;
|
||||
|
||||
// GetEffIndex()==0 prevent double/triple apply manaPerSecond/manaPerSecondPerLevel to same spell with many auras
|
||||
// all spells with manaPerSecond/manaPerSecondPerLevel have aura in effect 0
|
||||
if (GetEffIndex() == EFFECT_INDEX_0 && m_timeCla <= 0)
|
||||
{
|
||||
if(Unit* caster = GetCaster())
|
||||
{
|
||||
Powers powertype = Powers(GetSpellProto()->powerType);
|
||||
int32 manaPerSecond = GetSpellProto()->manaPerSecond + GetSpellProto()->manaPerSecondPerLevel * caster->getLevel();
|
||||
m_timeCla = 1*IN_MILLISECONDS;
|
||||
if (manaPerSecond)
|
||||
{
|
||||
if(powertype==POWER_HEALTH)
|
||||
caster->ModifyHealth(-manaPerSecond);
|
||||
else
|
||||
caster->ModifyPower(powertype,-manaPerSecond);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(m_isPeriodic && (m_duration >= 0 || GetHolder()->IsPassive() || GetHolder()->IsPermanent()))
|
||||
if (m_isPeriodic)
|
||||
{
|
||||
m_periodicTimer -= diff;
|
||||
if(m_periodicTimer <= 0) // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N
|
||||
|
|
@ -776,8 +727,9 @@ void AreaAura::Update(uint32 diff)
|
|||
addedToExisting = false;
|
||||
}
|
||||
|
||||
holder->SetAuraDuration(GetAuraDuration());
|
||||
|
||||
AreaAura *aur = new AreaAura(actualSpellInfo, m_effIndex, &actualBasePoints, holder, (*tIter), caster, NULL);
|
||||
aur->SetAuraDuration(GetAuraDuration());
|
||||
holder->AddAura(aur, m_effIndex);
|
||||
|
||||
if (addedToExisting)
|
||||
|
|
@ -1991,7 +1943,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
|||
// max duration is 2 minutes, but expected to be random duration
|
||||
// real time randomness is unclear, using max 30 seconds here
|
||||
// see further down for expire of this aura
|
||||
SetAuraDuration(rand()%30*IN_MILLISECONDS);
|
||||
GetHolder()->SetAuraDuration(urand(1, 30)*IN_MILLISECONDS);
|
||||
return;
|
||||
}
|
||||
// Gender spells
|
||||
|
|
@ -4371,10 +4323,10 @@ void Aura::HandleModStealth(bool apply, bool Real)
|
|||
// Overkill
|
||||
else if ((*i)->GetId() == 58426 && GetSpellProto()->SpellFamilyFlags & UI64LIT(0x0000000000400000))
|
||||
{
|
||||
if (Aura* aura = target->GetAura(58427, EFFECT_INDEX_0))
|
||||
if (SpellAuraHolder* holder = target->GetSpellAuraHolder(58427))
|
||||
{
|
||||
aura->SetAuraMaxDuration(20*IN_MILLISECONDS);
|
||||
aura->GetHolder()->RefreshHolder();
|
||||
holder->SetAuraMaxDuration(20*IN_MILLISECONDS);
|
||||
holder->RefreshHolder();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8174,20 +8126,6 @@ void Aura::HandleAuraModAllCritChance(bool apply, bool Real)
|
|||
((Player*)target)->UpdateAllSpellCritChances();
|
||||
}
|
||||
|
||||
void Aura::SetAuraMaxDuration(int32 duration)
|
||||
{
|
||||
m_maxduration = duration;
|
||||
|
||||
// possible overwrite persistent state
|
||||
if (duration > 0)
|
||||
{
|
||||
if (!(GetHolder()->IsPassive() && GetSpellProto()->DurationIndex == 0))
|
||||
GetHolder()->SetPermanent(false);
|
||||
|
||||
GetHolder()->SetAuraFlags(GetHolder()->GetAuraFlags() | AFLAG_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
bool Aura::IsLastAuraOnHolder()
|
||||
{
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
|
|
@ -8203,9 +8141,9 @@ bool Aura::HasMechanic(uint32 mechanic) const
|
|||
}
|
||||
|
||||
SpellAuraHolder::SpellAuraHolder(SpellEntry const* spellproto, Unit *target, WorldObject *caster, Item *castItem) :
|
||||
m_target(target), m_castItemGuid(castItem ? castItem->GetObjectGuid() : ObjectGuid()),
|
||||
m_spellProto(spellproto), m_target(target), m_castItemGuid(castItem ? castItem->GetObjectGuid() : ObjectGuid()),
|
||||
m_auraSlot(MAX_AURAS), m_auraFlags(AFLAG_NONE), m_auraLevel(1), m_procCharges(0),
|
||||
m_stackAmount(1), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE),
|
||||
m_stackAmount(1), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE), m_timeCla(1000),
|
||||
m_permanent(false), m_isRemovedOnShapeLost(true), m_deleted(false), m_in_use(0)
|
||||
{
|
||||
MANGOS_ASSERT(target);
|
||||
|
|
@ -8216,29 +8154,33 @@ m_permanent(false), m_isRemovedOnShapeLost(true), m_deleted(false), m_in_use(0)
|
|||
else
|
||||
{
|
||||
// remove this assert when not unit casters will be supported
|
||||
MANGOS_ASSERT(caster->GetObjectGuid().IsUnit())
|
||||
MANGOS_ASSERT(caster->isType(TYPEMASK_UNIT))
|
||||
m_casterGuid = caster->GetObjectGuid();
|
||||
}
|
||||
|
||||
m_applyTime = time(NULL);
|
||||
m_spellProto = spellproto;
|
||||
m_isPassive = IsPassiveSpell(GetId());
|
||||
m_isDeathPersist = IsDeathPersistentSpell(m_spellProto);
|
||||
m_applyTime = time(NULL);
|
||||
m_isPassive = IsPassiveSpell(spellproto);
|
||||
m_isDeathPersist = IsDeathPersistentSpell(spellproto);
|
||||
m_isSingleTarget = IsSingleTargetSpell(spellproto);
|
||||
|
||||
if (GetSpellMaxDuration(m_spellProto) == -1 || (m_isPassive && m_spellProto->DurationIndex == 0))
|
||||
m_permanent = true;
|
||||
m_procCharges = spellproto->procCharges;
|
||||
|
||||
m_isRemovedOnShapeLost = (GetCasterGuid() == m_target->GetObjectGuid() &&
|
||||
m_spellProto->Stances &&
|
||||
!(m_spellProto->AttributesEx2 & SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) &&
|
||||
!(m_spellProto->Attributes & SPELL_ATTR_NOT_SHAPESHIFT));
|
||||
|
||||
Player* modOwner = caster && caster->GetObjectGuid().IsUnit() ? ((Unit*)caster)->GetSpellModOwner() : NULL;
|
||||
Unit* unitCaster = caster && caster->isType(TYPEMASK_UNIT) ? (Unit*)caster : NULL;
|
||||
|
||||
m_procCharges = m_spellProto->procCharges;
|
||||
if(modOwner)
|
||||
modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, m_procCharges);
|
||||
m_duration = m_maxDuration = CalculateSpellDuration(spellproto, unitCaster);
|
||||
|
||||
if (m_maxDuration == -1 || (m_isPassive && spellproto->DurationIndex == 0))
|
||||
m_permanent = true;
|
||||
|
||||
if (unitCaster)
|
||||
{
|
||||
if (Player* modOwner = unitCaster->GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, m_procCharges);
|
||||
}
|
||||
|
||||
// some custom stack values at aura holder create
|
||||
switch (m_spellProto->Id)
|
||||
|
|
@ -8697,23 +8639,8 @@ void SpellAuraHolder::BuildUpdatePacket(WorldPacket& data) const
|
|||
|
||||
if(auraFlags & AFLAG_DURATION)
|
||||
{
|
||||
// take highest - to display icon even if stun fades
|
||||
uint32 max_duration = 0;
|
||||
uint32 duration = 0;
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
if (Aura *aura = m_auras[i])
|
||||
{
|
||||
if (uint32(aura->GetAuraMaxDuration()) > max_duration)
|
||||
{
|
||||
max_duration = aura->GetAuraMaxDuration();
|
||||
duration = aura->GetAuraDuration();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data << uint32(max_duration);
|
||||
data << uint32(duration);
|
||||
data << uint32(GetAuraMaxDuration());
|
||||
data << uint32(GetAuraDuration());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -9403,6 +9330,33 @@ SpellAuraHolder::~SpellAuraHolder()
|
|||
|
||||
void SpellAuraHolder::Update(uint32 diff)
|
||||
{
|
||||
if (m_duration > 0)
|
||||
{
|
||||
m_duration -= diff;
|
||||
if (m_duration < 0)
|
||||
m_duration = 0;
|
||||
|
||||
m_timeCla -= diff;
|
||||
|
||||
if (m_timeCla <= 0)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
Powers powertype = Powers(GetSpellProto()->powerType);
|
||||
int32 manaPerSecond = GetSpellProto()->manaPerSecond + GetSpellProto()->manaPerSecondPerLevel * caster->getLevel();
|
||||
m_timeCla = 1*IN_MILLISECONDS;
|
||||
|
||||
if (manaPerSecond)
|
||||
{
|
||||
if (powertype == POWER_HEALTH)
|
||||
caster->ModifyHealth(-manaPerSecond);
|
||||
else
|
||||
caster->ModifyPower(powertype, -manaPerSecond);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
if (Aura *aura = m_auras[i])
|
||||
aura->UpdateAura(diff);
|
||||
|
|
@ -9437,13 +9391,26 @@ void SpellAuraHolder::Update(uint32 diff)
|
|||
|
||||
void SpellAuraHolder::RefreshHolder()
|
||||
{
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
if (Aura *aura = m_auras[i])
|
||||
aura->SetAuraDuration(aura->GetAuraMaxDuration());
|
||||
|
||||
SetAuraDuration(GetAuraMaxDuration());
|
||||
SendAuraUpdate(false);
|
||||
}
|
||||
|
||||
void SpellAuraHolder::SetAuraMaxDuration(int32 duration)
|
||||
{
|
||||
m_maxDuration = duration;
|
||||
|
||||
// possible overwrite persistent state
|
||||
if (duration > 0)
|
||||
{
|
||||
if (!(IsPassive() && GetSpellProto()->DurationIndex == 0))
|
||||
SetPermanent(false);
|
||||
|
||||
SetAuraFlags(GetAuraFlags() | AFLAG_DURATION);
|
||||
}
|
||||
else
|
||||
SetAuraFlags(GetAuraFlags() & ~AFLAG_DURATION);
|
||||
}
|
||||
|
||||
bool SpellAuraHolder::HasMechanic(uint32 mechanic) const
|
||||
{
|
||||
if (mechanic == m_spellProto->Mechanic)
|
||||
|
|
|
|||
|
|
@ -108,10 +108,15 @@ class MANGOS_DLL_SPEC SpellAuraHolder
|
|||
void Update(uint32 diff);
|
||||
void RefreshHolder();
|
||||
|
||||
bool IsSingleTarget() const {return m_isSingleTarget; }
|
||||
bool IsSingleTarget() const { return m_isSingleTarget; }
|
||||
void SetIsSingleTarget(bool val) { m_isSingleTarget = val; }
|
||||
void UnregisterSingleCastHolder();
|
||||
|
||||
int32 GetAuraMaxDuration() const { return m_maxDuration; }
|
||||
void SetAuraMaxDuration(int32 duration);
|
||||
int32 GetAuraDuration() const { return m_duration; }
|
||||
void SetAuraDuration(int32 duration) { m_duration = duration; }
|
||||
|
||||
uint8 GetAuraSlot() const { return m_auraSlot; }
|
||||
void SetAuraSlot(uint8 slot) { m_auraSlot = slot; }
|
||||
uint8 GetAuraFlags() const { return m_auraFlags; }
|
||||
|
|
@ -140,12 +145,14 @@ class MANGOS_DLL_SPEC SpellAuraHolder
|
|||
|
||||
void SetVisibleAura(bool remove) { m_target->SetVisibleAura(m_auraSlot, remove ? 0 : GetId()); }
|
||||
void SetRemoveMode(AuraRemoveMode mode) { m_removeMode = mode; }
|
||||
void SetLoadedState(ObjectGuid const& casterGUID, ObjectGuid const& itemGUID, uint32 stackAmount, uint32 charges)
|
||||
void SetLoadedState(ObjectGuid const& casterGUID, ObjectGuid const& itemGUID, uint32 stackAmount, uint32 charges, int32 maxduration, int32 duration)
|
||||
{
|
||||
m_casterGuid = casterGUID;
|
||||
m_casterGuid = casterGUID;
|
||||
m_castItemGuid = itemGUID;
|
||||
m_procCharges = charges;
|
||||
m_stackAmount = stackAmount;
|
||||
m_procCharges = charges;
|
||||
m_stackAmount = stackAmount;
|
||||
SetAuraMaxDuration(maxduration);
|
||||
SetAuraDuration(duration);
|
||||
}
|
||||
|
||||
bool HasMechanic(uint32 mechanic) const;
|
||||
|
|
@ -165,6 +172,9 @@ class MANGOS_DLL_SPEC SpellAuraHolder
|
|||
uint8 m_auraLevel; // Aura level (store caster level for correct show level dep amount)
|
||||
uint32 m_procCharges; // Aura charges (0 for infinite)
|
||||
uint32 m_stackAmount; // Aura stack amount
|
||||
int32 m_maxDuration; // Max aura duration
|
||||
int32 m_duration; // Current time
|
||||
int32 m_timeCla; // Timer for power per sec calculation
|
||||
|
||||
AuraRemoveMode m_removeMode:8; // Store info for know remove aura reason
|
||||
DiminishingGroup m_AuraDRGroup:8; // Diminishing
|
||||
|
|
@ -380,22 +390,24 @@ class MANGOS_DLL_SPEC Aura
|
|||
SpellEffectIndex GetEffIndex() const{ return m_effIndex; }
|
||||
int32 GetBasePoints() const { return m_currentBasePoints; }
|
||||
|
||||
int32 GetAuraMaxDuration() const { return m_maxduration; }
|
||||
void SetAuraMaxDuration(int32 duration);
|
||||
int32 GetAuraDuration() const { return m_duration; }
|
||||
void SetAuraDuration(int32 duration) { m_duration = duration; }
|
||||
int32 GetAuraMaxDuration() const { return GetHolder()->GetAuraMaxDuration(); }
|
||||
int32 GetAuraDuration() const { return GetHolder()->GetAuraDuration(); }
|
||||
time_t GetAuraApplyTime() const { return m_applyTime; }
|
||||
uint32 GetAuraTicks() const { return m_periodicTick; }
|
||||
uint32 GetAuraMaxTicks() const { return m_maxduration > 0 && m_modifier.periodictime > 0 ? m_maxduration / m_modifier.periodictime : 0; }
|
||||
uint32 GetAuraMaxTicks() const
|
||||
{
|
||||
int32 maxDuration = GetAuraMaxDuration();
|
||||
return maxDuration > 0 && m_modifier.periodictime > 0 ? maxDuration / m_modifier.periodictime : 0;
|
||||
}
|
||||
uint32 GetStackAmount() const { return GetHolder()->GetStackAmount(); }
|
||||
|
||||
void SetLoadedState(int32 damage,int32 maxduration,int32 duration)
|
||||
void SetLoadedState(int32 damage, uint32 periodicTime)
|
||||
{
|
||||
m_modifier.m_amount = damage;
|
||||
SetAuraMaxDuration(maxduration);
|
||||
SetAuraDuration(duration);
|
||||
m_modifier.periodictime = periodicTime;
|
||||
|
||||
if(uint32 maxticks = GetAuraMaxTicks())
|
||||
m_periodicTick = maxticks - m_duration / m_modifier.periodictime;
|
||||
m_periodicTick = maxticks - GetAuraDuration() / m_modifier.periodictime;
|
||||
}
|
||||
|
||||
bool IsPositive() { return m_positive; }
|
||||
|
|
@ -458,9 +470,6 @@ class MANGOS_DLL_SPEC Aura
|
|||
time_t m_applyTime;
|
||||
|
||||
int32 m_currentBasePoints; // cache SpellEntry::CalculateSimpleValue and use for set custom base points
|
||||
int32 m_maxduration; // Max aura duration
|
||||
int32 m_duration; // Current time
|
||||
int32 m_timeCla; // Timer for power per sec calcultion
|
||||
int32 m_periodicTimer; // Timer for periodic auras
|
||||
uint32 m_periodicTick; // Tick count pass (including current if use in tick code) from aura apply, used for some tick count dependent aura effects
|
||||
|
||||
|
|
|
|||
|
|
@ -3521,7 +3521,7 @@ void Spell::EffectApplyAura(SpellEffectIndex eff_idx)
|
|||
Unit* caster = GetAffectiveCaster();
|
||||
if(!caster)
|
||||
{
|
||||
// FIXME: currently we can't have auras applied explIcitly by gameobjects
|
||||
// FIXME: currently we can't have auras applied explicitly by gameobjects
|
||||
// so for auras from wild gameobjects (no owner) target used
|
||||
if (m_originalCasterGUID.IsGameObject())
|
||||
caster = unitTarget;
|
||||
|
|
@ -3531,28 +3531,8 @@ void Spell::EffectApplyAura(SpellEffectIndex eff_idx)
|
|||
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell: Aura is: %u", m_spellInfo->EffectApplyAuraName[eff_idx]);
|
||||
|
||||
Aura* Aur = CreateAura(m_spellInfo, eff_idx, &m_currentBasePoints[eff_idx], spellAuraHolder, unitTarget, caster, m_CastItem);
|
||||
|
||||
// Now Reduce spell duration using data received at spell hit
|
||||
int32 duration = Aur->GetAuraMaxDuration();
|
||||
int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup,m_spellInfo);
|
||||
unitTarget->ApplyDiminishingToDuration(m_diminishGroup, duration, m_caster, m_diminishLevel,limitduration);
|
||||
spellAuraHolder->setDiminishGroup(m_diminishGroup);
|
||||
|
||||
// if Aura removed and deleted, do not continue.
|
||||
if(duration== 0 && !(spellAuraHolder->IsPermanent()))
|
||||
{
|
||||
delete Aur;
|
||||
return;
|
||||
}
|
||||
|
||||
if(duration != Aur->GetAuraMaxDuration())
|
||||
{
|
||||
Aur->SetAuraMaxDuration(duration);
|
||||
Aur->SetAuraDuration(duration);
|
||||
}
|
||||
|
||||
spellAuraHolder->AddAura(Aur, eff_idx);
|
||||
Aura* aur = CreateAura(m_spellInfo, eff_idx, &m_currentBasePoints[eff_idx], m_spellAuraHolder, unitTarget, caster, m_CastItem);
|
||||
m_spellAuraHolder->AddAura(aur, eff_idx);
|
||||
}
|
||||
|
||||
void Spell::EffectUnlearnSpecialization(SpellEffectIndex eff_idx)
|
||||
|
|
@ -4383,8 +4363,8 @@ void Spell::EffectApplyAreaAura(SpellEffectIndex eff_idx)
|
|||
if (!unitTarget->isAlive())
|
||||
return;
|
||||
|
||||
AreaAura* Aur = new AreaAura(m_spellInfo, eff_idx, &m_currentBasePoints[eff_idx], spellAuraHolder, unitTarget, m_caster, m_CastItem);
|
||||
spellAuraHolder->AddAura(Aur, eff_idx);
|
||||
AreaAura* Aur = new AreaAura(m_spellInfo, eff_idx, &m_currentBasePoints[eff_idx], m_spellAuraHolder, unitTarget, m_caster, m_CastItem);
|
||||
m_spellAuraHolder->AddAura(Aur, eff_idx);
|
||||
}
|
||||
|
||||
void Spell::EffectSummonType(SpellEffectIndex eff_idx)
|
||||
|
|
@ -4525,10 +4505,7 @@ void Spell::DoSummon(SpellEffectIndex eff_idx)
|
|||
uint32 level = m_caster->getLevel();
|
||||
Pet* spawnCreature = new Pet(SUMMON_PET);
|
||||
|
||||
int32 duration = GetSpellDuration(m_spellInfo);
|
||||
if (duration > 0)
|
||||
if (Player* modOwner = m_caster->GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
|
||||
int32 duration = CalculateSpellDuration(m_spellInfo, m_caster);
|
||||
|
||||
if (m_caster->GetTypeId()==TYPEID_PLAYER && spawnCreature->LoadPetFromDB((Player*)m_caster,pet_entry))
|
||||
{
|
||||
|
|
@ -4980,10 +4957,7 @@ void Spell::DoSummonGuardian(SpellEffectIndex eff_idx, uint32 forceFaction)
|
|||
float center_z = m_targets.m_destZ;
|
||||
|
||||
float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[eff_idx]));
|
||||
int32 duration = GetSpellDuration(m_spellInfo);
|
||||
if (duration > 0)
|
||||
if (Player* modOwner = m_caster->GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
|
||||
int32 duration = CalculateSpellDuration(m_spellInfo, m_caster);
|
||||
|
||||
int32 amount = damage > 0 ? damage : 1;
|
||||
|
||||
|
|
@ -7654,10 +7628,7 @@ void Spell::DoSummonTotem(SpellEffectIndex eff_idx, uint8 slot_dbc)
|
|||
pTotem->SetOwner(m_caster);
|
||||
pTotem->SetTypeBySummonSpell(m_spellInfo); // must be after Create call where m_spells initialized
|
||||
|
||||
int32 duration=GetSpellDuration(m_spellInfo);
|
||||
if (duration > 0)
|
||||
if (Player* modOwner = m_caster->GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
|
||||
int32 duration = CalculateSpellDuration(m_spellInfo, m_caster);
|
||||
pTotem->SetDuration(duration);
|
||||
|
||||
if (damage) // if not spell info, DB values used
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "Spell.h"
|
||||
#include "BattleGroundMgr.h"
|
||||
#include "MapManager.h"
|
||||
#include "Unit.h"
|
||||
|
||||
SpellMgr::SpellMgr()
|
||||
{
|
||||
|
|
@ -61,6 +62,29 @@ int32 GetSpellMaxDuration(SpellEntry const *spellInfo)
|
|||
return (du->Duration[2] == -1) ? -1 : abs(du->Duration[2]);
|
||||
}
|
||||
|
||||
int32 CalculateSpellDuration(SpellEntry const *spellInfo, Unit const* caster)
|
||||
{
|
||||
int32 duration = GetSpellDuration(spellInfo);
|
||||
|
||||
if (duration != -1 && caster)
|
||||
{
|
||||
int32 maxduration = GetSpellMaxDuration(spellInfo);
|
||||
|
||||
if (duration != maxduration && caster->GetTypeId() == TYPEID_PLAYER)
|
||||
duration += int32((maxduration - duration) * ((Player*)caster)->GetComboPoints() / 5);
|
||||
|
||||
if (Player* modOwner = caster->GetSpellModOwner())
|
||||
{
|
||||
modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_DURATION, duration);
|
||||
|
||||
if (duration < 0)
|
||||
duration = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return duration;
|
||||
}
|
||||
|
||||
uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell const* spell)
|
||||
{
|
||||
if (spell)
|
||||
|
|
@ -847,6 +871,11 @@ bool IsPositiveSpell(uint32 spellId)
|
|||
if (!spellproto)
|
||||
return false;
|
||||
|
||||
return IsPositiveSpell(spellproto);
|
||||
}
|
||||
|
||||
bool IsPositiveSpell(SpellEntry const *spellproto)
|
||||
{
|
||||
// spells with at least one negative effect are considered negative
|
||||
// some self-applied spells have negative effects but in self casting case negative check ignored.
|
||||
for (int i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ inline float GetSpellMaxRange(SpellRangeEntry const *range, bool friendly = fals
|
|||
inline uint32 GetSpellRecoveryTime(SpellEntry const *spellInfo) { return spellInfo->RecoveryTime > spellInfo->CategoryRecoveryTime ? spellInfo->RecoveryTime : spellInfo->CategoryRecoveryTime; }
|
||||
int32 GetSpellDuration(SpellEntry const *spellInfo);
|
||||
int32 GetSpellMaxDuration(SpellEntry const *spellInfo);
|
||||
int32 CalculateSpellDuration(SpellEntry const *spellInfo, Unit const* caster = NULL);
|
||||
uint16 GetSpellAuraMaxTicks(SpellEntry const* spellInfo);
|
||||
WeaponAttackType GetWeaponAttackType(SpellEntry const *spellInfo);
|
||||
|
||||
|
|
@ -240,6 +241,7 @@ inline bool IsNonCombatSpell(SpellEntry const *spellInfo)
|
|||
}
|
||||
|
||||
bool IsPositiveSpell(uint32 spellId);
|
||||
bool IsPositiveSpell(SpellEntry const *spellproto);
|
||||
bool IsPositiveEffect(SpellEntry const *spellInfo, SpellEffectIndex effIndex);
|
||||
bool IsPositiveTarget(uint32 targetA, uint32 targetB);
|
||||
|
||||
|
|
@ -463,13 +465,21 @@ inline SpellSchoolMask GetSpellSchoolMask(SpellEntry const* spellInfo)
|
|||
return SpellSchoolMask(spellInfo->SchoolMask);
|
||||
}
|
||||
|
||||
inline uint32 GetSpellMechanicMask(SpellEntry const* spellInfo, int32 effect)
|
||||
inline uint32 GetSpellMechanicMask(SpellEntry const* spellInfo, uint32 effectMask)
|
||||
{
|
||||
uint32 mask = 0;
|
||||
if (spellInfo->Mechanic)
|
||||
mask |= 1 << (spellInfo->Mechanic - 1);
|
||||
if (spellInfo->EffectMechanic[effect])
|
||||
mask |= 1 << (spellInfo->EffectMechanic[effect] - 1);
|
||||
|
||||
for (uint32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
if (!(effectMask & (1 << i)))
|
||||
continue;
|
||||
|
||||
if (spellInfo->EffectMechanic[i])
|
||||
mask |= 1 << (spellInfo->EffectMechanic[i]-1);
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3489,31 +3489,11 @@ void Unit::_UpdateSpells( uint32 time )
|
|||
for (SpellAuraHolderMap::iterator iter = m_spellAuraHolders.begin(); iter != m_spellAuraHolders.end();)
|
||||
{
|
||||
SpellAuraHolder *holder = iter->second;
|
||||
if (holder)
|
||||
{
|
||||
if (!(holder->IsPermanent() || holder->IsPassive()) )
|
||||
{
|
||||
bool removedAura = false;
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
if (Aura *aura = holder->GetAuraByEffectIndex(SpellEffectIndex(i)))
|
||||
{
|
||||
if (!aura->GetAuraDuration())
|
||||
{
|
||||
RemoveSingleAuraFromSpellAuraHolder(holder, aura->GetEffIndex(), AURA_REMOVE_BY_EXPIRE);
|
||||
removedAura = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!removedAura)
|
||||
++iter;
|
||||
else
|
||||
iter = m_spellAuraHolders.begin();
|
||||
}
|
||||
else
|
||||
++iter;
|
||||
if (!(holder->IsPermanent() || holder->IsPassive()) && holder->GetAuraDuration() == 0)
|
||||
{
|
||||
RemoveSpellAuraHolder(holder, AURA_REMOVE_BY_EXPIRE);
|
||||
iter = m_spellAuraHolders.begin();
|
||||
}
|
||||
else
|
||||
++iter;
|
||||
|
|
@ -4505,6 +4485,14 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit
|
|||
SpellEntry const* spellProto = sSpellStore.LookupEntry(spellId);
|
||||
SpellAuraHolder *new_holder = CreateSpellAuraHolder(spellProto, stealer, this);
|
||||
|
||||
// set its duration and maximum duration
|
||||
// max duration 2 minutes (in msecs)
|
||||
int32 dur = holder->GetAuraDuration();
|
||||
int32 max_dur = 2*MINUTE*IN_MILLISECONDS;
|
||||
int32 new_max_dur = max_dur > dur ? dur : max_dur;
|
||||
new_holder->SetAuraMaxDuration(new_max_dur);
|
||||
new_holder->SetAuraDuration(new_max_dur);
|
||||
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
Aura *aur = holder->GetAuraByEffectIndex(SpellEffectIndex(i));
|
||||
|
|
@ -4517,14 +4505,6 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit
|
|||
// some different constructors
|
||||
Aura * new_aur = CreateAura(aur->GetSpellProto(), aur->GetEffIndex(), &basePoints, new_holder, stealer, this);
|
||||
|
||||
// set its duration and maximum duration
|
||||
// max duration 2 minutes (in msecs)
|
||||
int32 dur = aur->GetAuraDuration();
|
||||
int32 max_dur = 2*MINUTE*IN_MILLISECONDS;
|
||||
int32 new_max_dur = max_dur > dur ? dur : max_dur;
|
||||
new_aur->SetAuraMaxDuration( new_max_dur );
|
||||
new_aur->SetAuraDuration( new_max_dur );
|
||||
|
||||
// set periodic to do at least one tick (for case when original aura has been at last tick preparing)
|
||||
int32 periodic = aur->GetModifier()->periodictime;
|
||||
new_aur->GetModifier()->periodictime = periodic < new_max_dur ? periodic : new_max_dur;
|
||||
|
|
@ -4885,22 +4865,19 @@ void Unit::DelaySpellAuraHolder(uint32 spellId, int32 delaytime, uint64 casterGU
|
|||
SpellAuraHolderBounds bounds = GetSpellAuraHolderBounds(spellId);
|
||||
for (SpellAuraHolderMap::iterator iter = bounds.first; iter != bounds.second; ++iter)
|
||||
{
|
||||
if (casterGUID != iter->second->GetCasterGUID())
|
||||
SpellAuraHolder* holder = iter->second;
|
||||
|
||||
if (casterGUID != holder->GetCasterGUID())
|
||||
continue;
|
||||
|
||||
for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i)
|
||||
{
|
||||
if (Aura *aur = iter->second->GetAuraByEffectIndex(SpellEffectIndex(i)))
|
||||
{
|
||||
if (aur->GetAuraDuration() < delaytime)
|
||||
aur->SetAuraDuration(0);
|
||||
else
|
||||
aur->SetAuraDuration(aur->GetAuraDuration() - delaytime);
|
||||
if (holder->GetAuraDuration() < delaytime)
|
||||
holder->SetAuraDuration(0);
|
||||
else
|
||||
holder->SetAuraDuration(holder->GetAuraDuration() - delaytime);
|
||||
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell %u, EffectIndex %u partially interrupted on unit %u, new duration: %u ms",spellId, i, GetGUIDLow(), aur->GetAuraDuration());
|
||||
}
|
||||
}
|
||||
iter->second->SendAuraUpdate(false);
|
||||
holder->SendAuraUpdate(false);
|
||||
|
||||
DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell %u partially interrupted on %s, new duration: %u ms", spellId, GetObjectGuid().GetString().c_str(), holder->GetAuraDuration());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -8729,50 +8706,45 @@ int32 Unit::CalculateSpellDamage(Unit const* target, SpellEntry const* spellProt
|
|||
return value;
|
||||
}
|
||||
|
||||
int32 Unit::CalculateSpellDuration(SpellEntry const* spellProto, SpellEffectIndex effect_index, Unit const* target)
|
||||
int32 Unit::CalculateAuraDuration(SpellEntry const* spellProto, uint32 effectMask, int32 duration, Unit const* caster)
|
||||
{
|
||||
Player* unitPlayer = (GetTypeId() == TYPEID_PLAYER) ? (Player*)this : NULL;
|
||||
if (duration <= 0)
|
||||
return duration;
|
||||
|
||||
uint8 comboPoints = unitPlayer ? unitPlayer->GetComboPoints() : 0;
|
||||
int32 mechanicMod = 0;
|
||||
uint32 mechanicMask = GetSpellMechanicMask(spellProto, effectMask);
|
||||
|
||||
int32 minduration = GetSpellDuration(spellProto);
|
||||
int32 maxduration = GetSpellMaxDuration(spellProto);
|
||||
|
||||
int32 duration;
|
||||
|
||||
if( minduration != -1 && minduration != maxduration )
|
||||
duration = minduration + int32((maxduration - minduration) * comboPoints / 5);
|
||||
else
|
||||
duration = minduration;
|
||||
|
||||
if (duration > 0)
|
||||
for(int32 mechanic = MECHANIC_CHARM; mechanic <= MECHANIC_ENRAGED; ++mechanic)
|
||||
{
|
||||
int32 mechanic = GetEffectMechanic(spellProto, effect_index);
|
||||
// Find total mod value (negative bonus)
|
||||
int32 durationMod_always = target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD, mechanic);
|
||||
// Modify from SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL aura for negative effects (stack always ?)
|
||||
if (!IsPositiveEffect(spellProto, effect_index))
|
||||
durationMod_always+=target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL, spellProto->Dispel);
|
||||
// Find max mod (negative bonus)
|
||||
int32 durationMod_not_stack = target->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK, mechanic);
|
||||
if (!(mechanicMask & (1 << (mechanic-1))))
|
||||
continue;
|
||||
|
||||
if (!IsPositiveSpell(spellProto->Id))
|
||||
durationMod_always += target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS, spellProto->DmgClass);
|
||||
int32 stackingMod = GetTotalAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD, mechanic);
|
||||
int32 nonStackingMod = GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK, mechanic);
|
||||
|
||||
int32 durationMod = 0;
|
||||
// Select strongest negative mod
|
||||
if (durationMod_always > durationMod_not_stack)
|
||||
durationMod = durationMod_not_stack;
|
||||
else
|
||||
durationMod = durationMod_always;
|
||||
|
||||
if (durationMod != 0)
|
||||
duration = int32(int64(duration) * (100+durationMod) /100);
|
||||
|
||||
if (duration < 0) duration = 0;
|
||||
mechanicMod = std::min(mechanicMod, std::min(stackingMod, nonStackingMod));
|
||||
}
|
||||
|
||||
if (duration > 0 && unitPlayer && target == this)
|
||||
int32 dispelMod = 0;
|
||||
int32 dmgClassMod = 0;
|
||||
|
||||
if (!IsPositiveSpell(spellProto))
|
||||
{
|
||||
dispelMod = GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL, spellProto->Dispel);
|
||||
dmgClassMod = GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS, spellProto->DmgClass);
|
||||
}
|
||||
|
||||
int32 durationMod = std::min(mechanicMod, std::min(dispelMod, dmgClassMod));
|
||||
|
||||
if (durationMod != 0)
|
||||
{
|
||||
duration = int32(int64(duration) * (100+durationMod) / 100);
|
||||
|
||||
if (duration < 0)
|
||||
duration = 0;
|
||||
}
|
||||
|
||||
if (caster == this)
|
||||
{
|
||||
switch(spellProto->SpellFamilyName)
|
||||
{
|
||||
|
|
@ -9838,7 +9810,7 @@ SpellSchoolMask Unit::GetMeleeDamageSchoolMask() const
|
|||
return SPELL_SCHOOL_MASK_NORMAL;
|
||||
}
|
||||
|
||||
Player* Unit::GetSpellModOwner()
|
||||
Player* Unit::GetSpellModOwner() const
|
||||
{
|
||||
if(GetTypeId()==TYPEID_PLAYER)
|
||||
return (Player*)this;
|
||||
|
|
|
|||
|
|
@ -1519,7 +1519,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
|||
}
|
||||
bool isCharmedOwnedByPlayerOrPlayer() const { return GetCharmerOrOwnerOrOwnGuid().IsPlayer(); }
|
||||
|
||||
Player* GetSpellModOwner();
|
||||
Player* GetSpellModOwner() const;
|
||||
|
||||
Unit* GetOwner() const;
|
||||
Pet* GetPet() const;
|
||||
|
|
@ -1909,7 +1909,8 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
|||
|
||||
uint32 CalcNotIgnoreAbsorbDamage( uint32 damage, SpellSchoolMask damageSchoolMask, SpellEntry const* spellInfo = NULL);
|
||||
uint32 CalcNotIgnoreDamageRedunction( uint32 damage, SpellSchoolMask damageSchoolMask);
|
||||
int32 CalculateSpellDuration(SpellEntry const* spellProto, SpellEffectIndex effect_index, Unit const* target);
|
||||
int32 CalculateAuraDuration(SpellEntry const* spellProto, uint32 effectMask, int32 duration, Unit const* caster);
|
||||
|
||||
float CalculateLevelPenalty(SpellEntry const* spellProto) const;
|
||||
|
||||
void addFollower(FollowerReference* pRef) { m_FollowingRefManager.insertFirst(pRef); }
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "11298"
|
||||
#define REVISION_NR "11299"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef __REVISION_SQL_H__
|
||||
#define __REVISION_SQL_H__
|
||||
#define REVISION_DB_CHARACTERS "required_11117_02_characters_world"
|
||||
#define REVISION_DB_CHARACTERS "required_11299_02_characters_pet_aura"
|
||||
#define REVISION_DB_MANGOS "required_11234_01_mangos_command"
|
||||
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
|
||||
#endif // __REVISION_SQL_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue