Core/Spells: fixed combo points damage calculation
* added GameTable class to simplify access to game table values
This commit is contained in:
1 parent
4524c29f2c
commit
96975fcd6b
6 files changed
+117
-45
No files matched your search
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GameTable.h"
|
||||
#include "DBCStores.h"
|
||||
#include "DBCStructure.h"
|
||||
|
||||
/*static*/ float GameTable::GetSpellScalingValue(uint8 level, UnitClass unitClass)
|
||||
{
|
||||
if (level > GT_MAX_LEVEL)
|
||||
return 0.0f;
|
||||
|
||||
GtSpellScalingEntry const* gt = sGtSpellScalingStore.LookupEntry((unitClass - 1) * 100 + level -1);
|
||||
if (!gt)
|
||||
return 0.0f;
|
||||
|
||||
return gt->value;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GAMETABLE_H
|
||||
#define __GAMETABLE_H
|
||||
|
||||
#include "Define.h"
|
||||
|
||||
enum UnitClass : uint8;
|
||||
|
||||
class GameTable
|
||||
{
|
||||
public:
|
||||
static float GetSpellScalingValue(uint8 level, UnitClass unitClass);
|
||||
};
|
||||
|
||||
#endif // __GAMETABLE_H
|
||||
@@ -139,7 +139,7 @@ enum Classes
|
||||
(1<<(CLASS_DEATH_KNIGHT-1)))
|
||||
|
||||
// valid classes for creature_template.unit_class
|
||||
enum UnitClass
|
||||
enum UnitClass : uint8
|
||||
{
|
||||
UNIT_CLASS_WARRIOR = 1,
|
||||
UNIT_CLASS_PALADIN = 2,
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "Creature.h"
|
||||
#include "DBCStores.h"
|
||||
#include "GameClient.h"
|
||||
#include "GameTable.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "Item.h"
|
||||
#include "ItemTemplate.h"
|
||||
@@ -441,13 +442,18 @@ int32 SpellEffectInfo::CalcValue(WorldObject const* caster /*= nullptr*/, int32
|
||||
// TODO: this needs to be a float, not rounded
|
||||
int basePoints = CalcBaseValue(caster, target);
|
||||
double value = bp ? *bp : basePoints;
|
||||
double comboDamage = PointsPerComboPoint;
|
||||
|
||||
Unit const* casterUnit = nullptr;
|
||||
if (caster)
|
||||
casterUnit = caster->ToUnit();
|
||||
|
||||
if (DieSides)
|
||||
if (Scaling.Variance != 0.0f)
|
||||
{
|
||||
float delta = fabs(Scaling.Variance * 0.5f);
|
||||
double valueVariance = frand(-delta, delta);
|
||||
value += double(basePoints) * valueVariance;
|
||||
}
|
||||
else if (DieSides)
|
||||
{
|
||||
// roll in a range <1;EffectDieSides> as of patch 3.3.3
|
||||
if (DieSides == 1)
|
||||
@@ -455,20 +461,9 @@ int32 SpellEffectInfo::CalcValue(WorldObject const* caster /*= nullptr*/, int32
|
||||
else
|
||||
value += (DieSides >= 1) ? irand(1, DieSides) : irand(DieSides, 1);
|
||||
}
|
||||
else if (Scaling.Variance != 0.0f)
|
||||
{
|
||||
float delta = fabs(Scaling.Variance * 0.5f);
|
||||
double valueVariance = frand(-delta, delta);
|
||||
value += double(basePoints) * valueVariance;
|
||||
}
|
||||
|
||||
// base amount modification based on spell lvl vs caster lvl
|
||||
if (Scaling.Coefficient != 0.0f)
|
||||
{
|
||||
if (Scaling.ComboPointsCoefficient != 0.0f)
|
||||
comboDamage = Scaling.ComboPointsCoefficient * value;
|
||||
}
|
||||
else
|
||||
if (Scaling.Coefficient == 0.0f)
|
||||
{
|
||||
if (casterUnit && basePointsPerLevel != 0.0)
|
||||
{
|
||||
@@ -484,12 +479,12 @@ int32 SpellEffectInfo::CalcValue(WorldObject const* caster /*= nullptr*/, int32
|
||||
}
|
||||
}
|
||||
|
||||
// random damage
|
||||
if (casterUnit)
|
||||
// bonus amount from combo points
|
||||
if (casterUnit && _spellInfo->HasAttribute(SPELL_ATTR1_FINISHING_MOVE_DAMAGE))
|
||||
{
|
||||
// bonus amount from combo points
|
||||
if (comboDamage)
|
||||
if (int32 comboPoints = casterUnit->GetGameClientMovingMe()->GetBasePlayer()->GetComboPoints())
|
||||
double comboDamage = CalcPointsPerResource(casterUnit);
|
||||
if (comboDamage != 0.0)
|
||||
if (uint8 comboPoints = casterUnit->GetGameClientMovingMe()->GetBasePlayer()->GetComboPoints())
|
||||
value += comboDamage * comboPoints;
|
||||
}
|
||||
|
||||
@@ -523,9 +518,7 @@ int32 SpellEffectInfo::CalcBaseValue(WorldObject const* caster, Unit const* targ
|
||||
if (!_spellInfo->Scaling.Class)
|
||||
return 0;
|
||||
|
||||
if (GtSpellScalingEntry const* gtScaling = sGtSpellScalingStore.LookupEntry(((_spellInfo->Scaling.Class > 0 ? _spellInfo->Scaling.Class : ((MAX_CLASSES - 1 /*last class*/) - _spellInfo->Scaling.Class)) - 1) * 100 + level - 1))
|
||||
value = gtScaling->value;
|
||||
|
||||
value = GameTable::GetSpellScalingValue(level, static_cast<UnitClass>(_spellInfo->Scaling.Class > 0 ? _spellInfo->Scaling.Class: (MAX_CLASSES - 1 /*last class*/) - _spellInfo->Scaling.Class));
|
||||
value *= _spellInfo->GetSpellScalingMultiplier(level, false);
|
||||
}
|
||||
|
||||
@@ -542,6 +535,33 @@ int32 SpellEffectInfo::CalcBaseValue(WorldObject const* caster, Unit const* targ
|
||||
}
|
||||
}
|
||||
|
||||
// Based on client function QuestTextParser::Spell_C_GetPointsPerResource (build 15595)
|
||||
double SpellEffectInfo::CalcPointsPerResource(WorldObject const* caster) const
|
||||
{
|
||||
double value = 0.0;
|
||||
if (caster && caster->IsUnit())
|
||||
{
|
||||
if (Scaling.Coefficient != 0.0f)
|
||||
{
|
||||
if (!_spellInfo->Scaling.Class)
|
||||
return 0.0;
|
||||
|
||||
int32 scalingClass = _spellInfo->Scaling.Class;
|
||||
if (scalingClass < 0)
|
||||
scalingClass = (MAX_CLASSES - 1 /*last class*/) - scalingClass;
|
||||
|
||||
float scaledAmount = GameTable::GetSpellScalingValue(caster->ToUnit()->getLevel(), static_cast<UnitClass>(scalingClass));
|
||||
scaledAmount *= _spellInfo->GetSpellScalingMultiplier(caster->ToUnit()->getLevel(), false) * Scaling.ComboPointsCoefficient;
|
||||
value = scaledAmount;
|
||||
}
|
||||
}
|
||||
|
||||
if (std::fabs(value) < 0.00000023841858 && PointsPerComboPoint != 0.0f)
|
||||
return PointsPerComboPoint;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
float SpellEffectInfo::CalcValueMultiplier(WorldObject* caster, Spell* spell) const
|
||||
{
|
||||
float multiplier = Amplitude;
|
||||
|
||||
@@ -295,6 +295,7 @@ public:
|
||||
|
||||
int32 CalcValue(WorldObject const* caster = nullptr, int32 const* basePoints = nullptr, Unit const* target = nullptr) const;
|
||||
int32 CalcBaseValue(WorldObject const* caster, Unit const* target) const;
|
||||
double CalcPointsPerResource(WorldObject const* caster) const;
|
||||
float CalcValueMultiplier(WorldObject* caster, Spell* spell = nullptr) const;
|
||||
float CalcDamageMultiplier(WorldObject* caster, Spell* spell = nullptr) const;
|
||||
|
||||
|
||||
@@ -875,30 +875,18 @@ class spell_rog_eviscerate : public SpellScript
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChangeDamage(SpellEffIndex /*effIndex*/)
|
||||
void CalculateDamage(Unit* victim, int32& /*damage*/, int32& flatMod, float& pctMod)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
Unit* target = GetHitUnit();
|
||||
if (!caster || !target)
|
||||
return;
|
||||
Player const* playerCaster = GetCaster()->ToPlayer();
|
||||
uint8 comboPoints = playerCaster->GetComboPoints();
|
||||
flatMod += static_cast<int32>(comboPoints * playerCaster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.091f);
|
||||
|
||||
if (Player* player = caster->ToPlayer())
|
||||
{
|
||||
int32 damage = GetEffectValue();
|
||||
damage += int32(player->GetComboPoints() * (player->GetTotalAttackPowerValue(BASE_ATTACK) * 0.091f));
|
||||
// Eviscerate and Envenom Bonus Damage (item set effect)
|
||||
if (AuraEffect* aurEff = playerCaster->GetAuraEffect(SPELL_ROGUE_EVISCERATE_AND_ENVENOM_BONUS_DAMAGE, EFFECT_0))
|
||||
flatMod += comboPoints * aurEff->GetAmount();
|
||||
|
||||
// Eviscerate and Envenom Bonus Damage (item set effect)
|
||||
if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_ROGUE_EVISCERATE_AND_ENVENOM_BONUS_DAMAGE, EFFECT_0))
|
||||
damage += player->GetComboPoints() * aurEff->GetAmount();
|
||||
|
||||
if (AuraEffect* const revealingStrike = target->GetAuraEffect(SPELL_ROGUE_REVEALING_STRIKE, EFFECT_2, caster->GetGUID()))
|
||||
{
|
||||
damage += CalculatePct(damage, revealingStrike->GetAmount());
|
||||
revealingStrike->GetBase()->Remove();
|
||||
}
|
||||
|
||||
SetEffectValue(damage);
|
||||
}
|
||||
if (AuraEffect* const revealingStrike = victim->GetAuraEffect(SPELL_ROGUE_REVEALING_STRIKE, EFFECT_2, playerCaster->GetGUID()))
|
||||
AddPct(pctMod, revealingStrike->GetAmount());
|
||||
}
|
||||
|
||||
void HandleSerratedBlades(SpellEffIndex /*effIndex*/)
|
||||
@@ -916,7 +904,7 @@ class spell_rog_eviscerate : public SpellScript
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectLaunchTarget.Register(&spell_rog_eviscerate::ChangeDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
|
||||
CalcDamage.Register(&spell_rog_eviscerate::CalculateDamage);
|
||||
OnEffectHitTarget.Register(&spell_rog_eviscerate::HandleSerratedBlades, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user