Core/Spells: Reimplemented SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION
This commit is contained in:
@@ -101,6 +101,7 @@ DBCStorage <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore(GtChance
|
||||
DBCStorage <GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore(GtChanceToMeleeCritfmt);
|
||||
DBCStorage <GtChanceToSpellCritBaseEntry> sGtChanceToSpellCritBaseStore(GtChanceToSpellCritBasefmt);
|
||||
DBCStorage <GtChanceToSpellCritEntry> sGtChanceToSpellCritStore(GtChanceToSpellCritfmt);
|
||||
DBCStorage <GtNPCManaCostScalerEntry> sGtNPCManaCostScalerStore(GtNPCManaCostScalerfmt);
|
||||
DBCStorage <GtOCTClassCombatRatingScalarEntry> sGtOCTClassCombatRatingScalarStore(GtOCTClassCombatRatingScalarfmt);
|
||||
DBCStorage <GtOCTRegenHPEntry> sGtOCTRegenHPStore(GtOCTRegenHPfmt);
|
||||
//DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore(GtOCTRegenMPfmt); -- not used currently
|
||||
@@ -344,6 +345,7 @@ void LoadDBCStores(const std::string& dataPath)
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToMeleeCritStore, dbcPath, "gtChanceToMeleeCrit.dbc");
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritBaseStore, dbcPath, "gtChanceToSpellCritBase.dbc");
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritStore, dbcPath, "gtChanceToSpellCrit.dbc");
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sGtNPCManaCostScalerStore, dbcPath, "gtNPCManaCostScaler.dbc");
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTClassCombatRatingScalarStore, dbcPath, "gtOCTClassCombatRatingScalar.dbc");
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTRegenHPStore, dbcPath, "gtOCTRegenHP.dbc");
|
||||
//LoadDBC(dbcCount, availableDbcLocales, bad_dbc_files, sGtOCTRegenMPStore, dbcPath, "gtOCTRegenMP.dbc"); -- not used currently
|
||||
|
||||
@@ -108,6 +108,7 @@ extern DBCStorage <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore;
|
||||
extern DBCStorage <GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore;
|
||||
extern DBCStorage <GtChanceToSpellCritBaseEntry> sGtChanceToSpellCritBaseStore;
|
||||
extern DBCStorage <GtChanceToSpellCritEntry> sGtChanceToSpellCritStore;
|
||||
extern DBCStorage <GtNPCManaCostScalerEntry> sGtNPCManaCostScalerStore;
|
||||
extern DBCStorage <GtOCTClassCombatRatingScalarEntry> sGtOCTClassCombatRatingScalarStore;
|
||||
extern DBCStorage <GtOCTRegenHPEntry> sGtOCTRegenHPStore;
|
||||
//extern DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore; -- not used currently
|
||||
|
||||
@@ -1020,6 +1020,11 @@ struct GtChanceToSpellCritBaseEntry
|
||||
float base;
|
||||
};
|
||||
|
||||
struct GtNPCManaCostScalerEntry
|
||||
{
|
||||
float ratio;
|
||||
};
|
||||
|
||||
struct GtChanceToSpellCritEntry
|
||||
{
|
||||
float ratio;
|
||||
|
||||
@@ -61,6 +61,7 @@ char const GtChanceToMeleeCritBasefmt[] = "f";
|
||||
char const GtChanceToMeleeCritfmt[] = "f";
|
||||
char const GtChanceToSpellCritBasefmt[] = "f";
|
||||
char const GtChanceToSpellCritfmt[] = "f";
|
||||
char const GtNPCManaCostScalerfmt[] = "f";
|
||||
char const GtOCTClassCombatRatingScalarfmt[] = "df";
|
||||
char const GtOCTRegenHPfmt[] = "f";
|
||||
//char const GtOCTRegenMPfmt[] = "f";
|
||||
|
||||
@@ -2502,6 +2502,8 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo
|
||||
if (apply)
|
||||
{
|
||||
uint32 creatureEntry = GetMiscValue();
|
||||
uint32 displayId = 0;
|
||||
uint32 vehicleId = 0;
|
||||
|
||||
// Festive Holiday Mount
|
||||
if (target->HasAura(62061))
|
||||
@@ -2512,23 +2514,21 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo
|
||||
creatureEntry = 15665;
|
||||
}
|
||||
|
||||
CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(creatureEntry);
|
||||
if (!ci)
|
||||
if (CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creatureEntry))
|
||||
{
|
||||
sLog->outError(LOG_FILTER_SQL, "AuraMounted: `creature_template`='%u' not found in database (only need its modelid)", GetMiscValue());
|
||||
return;
|
||||
displayId = ObjectMgr::ChooseDisplayId(creatureInfo);
|
||||
sObjectMgr->GetCreatureModelRandomGender(&displayId);
|
||||
|
||||
vehicleId = creatureInfo->VehicleId;
|
||||
|
||||
//some spell has one aura of mount and one of vehicle
|
||||
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
if (GetSpellInfo()->Effects[i].Effect == SPELL_EFFECT_SUMMON
|
||||
&& GetSpellInfo()->Effects[i].MiscValue == GetMiscValue())
|
||||
displayId = 0;
|
||||
}
|
||||
|
||||
uint32 displayID = ObjectMgr::ChooseDisplayId(ci);
|
||||
sObjectMgr->GetCreatureModelRandomGender(&displayID);
|
||||
|
||||
//some spell has one aura of mount and one of vehicle
|
||||
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
if (GetSpellInfo()->Effects[i].Effect == SPELL_EFFECT_SUMMON
|
||||
&& GetSpellInfo()->Effects[i].MiscValue == GetMiscValue())
|
||||
displayID = 0;
|
||||
|
||||
target->Mount(displayID, ci->VehicleId, GetMiscValue());
|
||||
target->Mount(displayId, vehicleId, creatureEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5796,8 +5796,8 @@ void AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick(Unit* target, Unit*
|
||||
{
|
||||
if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster() ? caster : target)
|
||||
{
|
||||
int32 basepoints0 = triggeredSpellInfo->Effects[EFFECT_0].CalcValue(triggerCaster) <= 1 ? triggeredSpellInfo->Effects[EFFECT_0].CalcValue(triggerCaster) : GetAmount();
|
||||
triggerCaster->CastCustomSpell(target, triggerSpellId, &basepoints0, 0, 0, true, 0, this);
|
||||
int32 basepoints = GetAmount();
|
||||
triggerCaster->CastCustomSpell(target, triggerSpellId, &basepoints, &basepoints, &basepoints, true, 0, this);
|
||||
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick: Spell %u Trigger %u", GetId(), triggeredSpellInfo->Id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -938,12 +938,9 @@ void Spell::EffectTriggerSpell(SpellEffIndex effIndex)
|
||||
// set basepoints for trigger with value effect
|
||||
if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE)
|
||||
{
|
||||
if (m_spellInfo->Effects[effIndex].BasePoints == 0)
|
||||
{
|
||||
values.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
|
||||
values.AddSpellMod(SPELLVALUE_BASE_POINT1, damage);
|
||||
values.AddSpellMod(SPELLVALUE_BASE_POINT2, damage);
|
||||
}
|
||||
values.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
|
||||
values.AddSpellMod(SPELLVALUE_BASE_POINT1, damage);
|
||||
values.AddSpellMod(SPELLVALUE_BASE_POINT2, damage);
|
||||
}
|
||||
|
||||
// Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
|
||||
|
||||
@@ -450,17 +450,56 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const
|
||||
value = caster->ApplyEffectModifiers(_spellInfo, _effIndex, value);
|
||||
|
||||
// amount multiplication based on caster's level
|
||||
if (!basePointsPerLevel && (_spellInfo->Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION && _spellInfo->SpellLevel) &&
|
||||
Effect != SPELL_EFFECT_WEAPON_PERCENT_DAMAGE &&
|
||||
Effect != SPELL_EFFECT_KNOCK_BACK &&
|
||||
Effect != SPELL_EFFECT_ADD_EXTRA_ATTACKS &&
|
||||
ApplyAuraName != SPELL_AURA_MOD_SPEED_ALWAYS &&
|
||||
ApplyAuraName != SPELL_AURA_MOD_SPEED_NOT_STACK &&
|
||||
ApplyAuraName != SPELL_AURA_MOD_INCREASE_SPEED &&
|
||||
ApplyAuraName != SPELL_AURA_MOD_DECREASE_SPEED)
|
||||
//there are many more: slow speed, -healing pct
|
||||
value *= 0.25f * exp(caster->getLevel() * (70 - _spellInfo->SpellLevel) / 1000.0f);
|
||||
//value = int32(value * (int32)getLevel() / (int32)(_spellInfo->spellLevel ? _spellInfo->spellLevel : 1));
|
||||
if (!caster->IsControlledByPlayer() &&
|
||||
_spellInfo->SpellLevel && _spellInfo->SpellLevel != caster->getLevel() &&
|
||||
!basePointsPerLevel && (_spellInfo->Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION))
|
||||
{
|
||||
bool canEffectScale = false;
|
||||
switch (Effect)
|
||||
{
|
||||
case SPELL_EFFECT_SCHOOL_DAMAGE:
|
||||
case SPELL_EFFECT_DUMMY:
|
||||
case SPELL_EFFECT_POWER_DRAIN:
|
||||
case SPELL_EFFECT_HEALTH_LEECH:
|
||||
case SPELL_EFFECT_HEAL:
|
||||
case SPELL_EFFECT_WEAPON_DAMAGE:
|
||||
case SPELL_EFFECT_POWER_BURN:
|
||||
case SPELL_EFFECT_SCRIPT_EFFECT:
|
||||
case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
|
||||
case SPELL_EFFECT_FORCE_CAST_WITH_VALUE:
|
||||
case SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE:
|
||||
case SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE:
|
||||
canEffectScale = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ApplyAuraName)
|
||||
{
|
||||
case SPELL_AURA_PERIODIC_DAMAGE:
|
||||
case SPELL_AURA_DUMMY:
|
||||
case SPELL_AURA_PERIODIC_HEAL:
|
||||
case SPELL_AURA_DAMAGE_SHIELD:
|
||||
case SPELL_AURA_PROC_TRIGGER_DAMAGE:
|
||||
case SPELL_AURA_PERIODIC_LEECH:
|
||||
case SPELL_AURA_PERIODIC_MANA_LEECH:
|
||||
case SPELL_AURA_SCHOOL_ABSORB:
|
||||
case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
|
||||
canEffectScale = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (canEffectScale)
|
||||
{
|
||||
GtNPCManaCostScalerEntry const* spellScaler = sGtNPCManaCostScalerStore.LookupEntry(_spellInfo->SpellLevel - 1);
|
||||
GtNPCManaCostScalerEntry const* casterScaler = sGtNPCManaCostScalerStore.LookupEntry(caster->getLevel() - 1);
|
||||
if (spellScaler && casterScaler)
|
||||
value *= casterScaler->ratio / spellScaler->ratio;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return int32(value);
|
||||
@@ -2124,15 +2163,39 @@ int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) c
|
||||
SpellSchools school = GetFirstSchoolInMask(schoolMask);
|
||||
// Flat mod from caster auras by spell school
|
||||
powerCost += caster->GetInt32Value(UNIT_FIELD_POWER_COST_MODIFIER + school);
|
||||
|
||||
// Shiv - costs 20 + weaponSpeed*10 energy (apply only to non-triggered spell with energy cost)
|
||||
if (AttributesEx4 & SPELL_ATTR4_SPELL_VS_EXTEND_COST)
|
||||
powerCost += caster->GetAttackTime(OFF_ATTACK) / 100;
|
||||
{
|
||||
uint32 speed = 0;
|
||||
if (SpellShapeshiftEntry const* ss = sSpellShapeshiftStore.LookupEntry(caster->GetShapeshiftForm()))
|
||||
speed = ss->attackSpeed;
|
||||
else
|
||||
{
|
||||
WeaponAttackType slot = BASE_ATTACK;
|
||||
if (AttributesEx3 & SPELL_ATTR3_REQ_OFFHAND)
|
||||
slot = OFF_ATTACK;
|
||||
|
||||
speed = caster->GetAttackTime(slot);
|
||||
}
|
||||
|
||||
powerCost += speed / 100;
|
||||
}
|
||||
|
||||
// Apply cost mod by spell
|
||||
if (Player* modOwner = caster->GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(Id, SPELLMOD_COST, powerCost);
|
||||
|
||||
if (Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION)
|
||||
powerCost = int32(powerCost / (1.117f * SpellLevel / caster->getLevel() -0.1327f));
|
||||
if (!caster->IsControlledByPlayer())
|
||||
{
|
||||
if (Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION)
|
||||
{
|
||||
GtNPCManaCostScalerEntry const* spellScaler = sGtNPCManaCostScalerStore.LookupEntry(SpellLevel - 1);
|
||||
GtNPCManaCostScalerEntry const* casterScaler = sGtNPCManaCostScalerStore.LookupEntry(caster->getLevel() - 1);
|
||||
if (spellScaler && casterScaler)
|
||||
powerCost *= casterScaler->ratio / spellScaler->ratio;
|
||||
}
|
||||
}
|
||||
|
||||
// PCT mod from user auras by school
|
||||
powerCost = int32(powerCost * (1.0f + caster->GetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER + school)));
|
||||
|
||||
Reference in New Issue
Block a user