mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Core/Spells: Refactor CastSpellExtraArgs
* Allow C++20 designated initializers * Allow precise float values for SPELLVALUE_RADIUS_MOD, SPELLVALUE_CRIT_CHANCE and SPELLVALUE_DURATION_PCT
This commit is contained in:
@@ -2949,8 +2949,13 @@ SpellCastResult WorldObject::CastSpell(CastSpellTargetArg const& targets, uint32
|
||||
}
|
||||
|
||||
Spell* spell = new Spell(this, info, args.TriggerFlags, args.OriginalCaster, args.OriginalCastId);
|
||||
for (auto const& pair : args.SpellValueOverrides)
|
||||
spell->SetSpellValue(pair.first, pair.second);
|
||||
for (auto const& [Type, Value] : args.SpellValueOverrides)
|
||||
{
|
||||
if (Type < SPELLVALUE_INT_END)
|
||||
spell->SetSpellValue(SpellValueMod(Type), Value.I);
|
||||
else
|
||||
spell->SetSpellValue(SpellValueModFloat(Type), Value.F);
|
||||
}
|
||||
|
||||
spell->m_CastItem = args.CastItem;
|
||||
if (args.OriginalCastItemLevel)
|
||||
|
||||
@@ -8793,21 +8793,12 @@ void Spell::SetSpellValue(SpellValueMod mod, int32 value)
|
||||
|
||||
switch (mod)
|
||||
{
|
||||
case SPELLVALUE_RADIUS_MOD:
|
||||
m_spellValue->RadiusMod = (float)value / 10000;
|
||||
break;
|
||||
case SPELLVALUE_MAX_TARGETS:
|
||||
m_spellValue->MaxAffectedTargets = (uint32)value;
|
||||
break;
|
||||
case SPELLVALUE_AURA_STACK:
|
||||
m_spellValue->AuraStackAmount = uint8(value);
|
||||
break;
|
||||
case SPELLVALUE_CRIT_CHANCE:
|
||||
m_spellValue->CriticalChance = value / 100.0f; // @todo ugly /100 remove when basepoints are double
|
||||
break;
|
||||
case SPELLVALUE_DURATION_PCT:
|
||||
m_spellValue->DurationMul = float(value) / 100.0f;
|
||||
break;
|
||||
case SPELLVALUE_DURATION:
|
||||
m_spellValue->Duration = value;
|
||||
break;
|
||||
@@ -8822,6 +8813,24 @@ void Spell::SetSpellValue(SpellValueMod mod, int32 value)
|
||||
}
|
||||
}
|
||||
|
||||
void Spell::SetSpellValue(SpellValueModFloat mod, float value)
|
||||
{
|
||||
switch (mod)
|
||||
{
|
||||
case SPELLVALUE_RADIUS_MOD:
|
||||
m_spellValue->RadiusMod = value;
|
||||
break;
|
||||
case SPELLVALUE_CRIT_CHANCE:
|
||||
m_spellValue->CriticalChance = value;
|
||||
break;
|
||||
case SPELLVALUE_DURATION_PCT:
|
||||
m_spellValue->DurationMul = value / 100.0f;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Spell::PrepareTargetProcessing()
|
||||
{
|
||||
}
|
||||
@@ -9662,8 +9671,10 @@ CastSpellExtraArgs& CastSpellExtraArgs::SetTriggeringSpell(Spell const* triggeri
|
||||
TriggeringSpell = triggeringSpell;
|
||||
if (triggeringSpell)
|
||||
{
|
||||
OriginalCastItemLevel = triggeringSpell->m_castItemLevel;
|
||||
OriginalCastId = triggeringSpell->m_castId;
|
||||
if (!OriginalCastItemLevel)
|
||||
OriginalCastItemLevel = triggeringSpell->m_castItemLevel;
|
||||
if (!OriginalCastItemLevel)
|
||||
OriginalCastId = triggeringSpell->m_castId;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,8 @@ enum ProcFlagsHit : uint32;
|
||||
enum ProcFlagsSpellType : uint32;
|
||||
enum SpellTargetCheckTypes : uint8;
|
||||
enum SpellTargetObjectTypes : uint8;
|
||||
enum SpellValueMod : uint8;
|
||||
enum SpellValueMod : int32;
|
||||
enum SpellValueModFloat : int32;
|
||||
enum TriggerCastFlags : uint32;
|
||||
enum WeaponAttackType : uint8;
|
||||
|
||||
@@ -673,6 +674,7 @@ class TC_GAME_API Spell
|
||||
void CleanupTargetList();
|
||||
|
||||
void SetSpellValue(SpellValueMod mod, int32 value);
|
||||
void SetSpellValue(SpellValueModFloat mod, float value);
|
||||
|
||||
Spell** m_selfContainer; // pointer to our spell container (if applicable)
|
||||
|
||||
|
||||
@@ -194,7 +194,7 @@ enum class SpellModOp : uint8
|
||||
|
||||
#define MAX_SPELLMOD 40
|
||||
|
||||
enum SpellValueMod : uint8
|
||||
enum SpellValueMod : int32
|
||||
{
|
||||
SPELLVALUE_BASE_POINT0,
|
||||
SPELLVALUE_BASE_POINT1,
|
||||
@@ -228,15 +228,23 @@ enum SpellValueMod : uint8
|
||||
SPELLVALUE_BASE_POINT29,
|
||||
SPELLVALUE_BASE_POINT30,
|
||||
SPELLVALUE_BASE_POINT31,
|
||||
|
||||
SPELLVALUE_BASE_POINT_END,
|
||||
SPELLVALUE_RADIUS_MOD,
|
||||
SPELLVALUE_MAX_TARGETS,
|
||||
|
||||
SPELLVALUE_MAX_TARGETS = SPELLVALUE_BASE_POINT_END,
|
||||
SPELLVALUE_AURA_STACK,
|
||||
SPELLVALUE_CRIT_CHANCE,
|
||||
SPELLVALUE_DURATION_PCT,
|
||||
SPELLVALUE_DURATION,
|
||||
SPELLVALUE_PARENT_SPELL_TARGET_COUNT,
|
||||
SPELLVALUE_PARENT_SPELL_TARGET_INDEX
|
||||
SPELLVALUE_PARENT_SPELL_TARGET_INDEX,
|
||||
|
||||
SPELLVALUE_INT_END
|
||||
};
|
||||
|
||||
enum SpellValueModFloat : int32
|
||||
{
|
||||
SPELLVALUE_RADIUS_MOD = uint8(SPELLVALUE_INT_END),
|
||||
SPELLVALUE_CRIT_CHANCE,
|
||||
SPELLVALUE_DURATION_PCT,
|
||||
};
|
||||
|
||||
enum SpellFacingFlags
|
||||
@@ -448,16 +456,46 @@ struct TC_GAME_API CastSpellTargetArg
|
||||
Optional<SpellCastTargets> Targets; // empty optional used to signal error state
|
||||
};
|
||||
|
||||
struct TC_GAME_API CastSpellExtraArgs
|
||||
struct CastSpellExtraArgsInit
|
||||
{
|
||||
TriggerCastFlags TriggerFlags = TRIGGERED_NONE;
|
||||
Item* CastItem = nullptr;
|
||||
Spell const* TriggeringSpell = nullptr;
|
||||
AuraEffect const* TriggeringAura = nullptr;
|
||||
ObjectGuid OriginalCaster = ObjectGuid::Empty;
|
||||
Difficulty CastDifficulty = Difficulty(0);
|
||||
ObjectGuid OriginalCastId = ObjectGuid::Empty;
|
||||
Optional<int32> OriginalCastItemLevel;
|
||||
struct SpellValueOverride
|
||||
{
|
||||
SpellValueOverride(SpellValueMod mod, int32 val) : Type(mod) { Value.I = val; }
|
||||
SpellValueOverride(SpellValueModFloat mod, float val) : Type(mod) { Value.F = val; }
|
||||
|
||||
int32 Type;
|
||||
union
|
||||
{
|
||||
float F;
|
||||
int32 I;
|
||||
} Value;
|
||||
};
|
||||
std::vector<SpellValueOverride> SpellValueOverrides;
|
||||
std::any CustomArg;
|
||||
Optional<Scripting::v2::ActionResultSetter<SpellCastResult>> ScriptResult;
|
||||
bool ScriptWaitsForSpellHit = false;
|
||||
};
|
||||
|
||||
struct TC_GAME_API CastSpellExtraArgs : public CastSpellExtraArgsInit
|
||||
{
|
||||
CastSpellExtraArgs();
|
||||
CastSpellExtraArgs(bool triggered) : TriggerFlags(triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE) {}
|
||||
CastSpellExtraArgs(TriggerCastFlags trigger) : TriggerFlags(trigger) {}
|
||||
CastSpellExtraArgs(Item* item) : TriggerFlags(TRIGGERED_FULL_MASK), CastItem(item) {}
|
||||
CastSpellExtraArgs(Spell const* triggeringSpell) : TriggerFlags(TRIGGERED_FULL_MASK) { SetTriggeringSpell(triggeringSpell); }
|
||||
CastSpellExtraArgs(AuraEffect const* eff) : TriggerFlags(TRIGGERED_FULL_MASK) { SetTriggeringAura(eff); }
|
||||
CastSpellExtraArgs(Difficulty castDifficulty) : CastDifficulty(castDifficulty) {}
|
||||
CastSpellExtraArgs(SpellValueMod mod, int32 val) { SpellValueOverrides.AddMod(mod, val); }
|
||||
CastSpellExtraArgs(bool triggered) { TriggerFlags = triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE; }
|
||||
CastSpellExtraArgs(TriggerCastFlags trigger) { TriggerFlags = trigger; }
|
||||
CastSpellExtraArgs(Item* item) { TriggerFlags = TRIGGERED_FULL_MASK; CastItem = item; }
|
||||
CastSpellExtraArgs(Spell const* triggeringSpell) { TriggerFlags = TRIGGERED_FULL_MASK; SetTriggeringSpell(triggeringSpell); }
|
||||
CastSpellExtraArgs(AuraEffect const* eff) { TriggerFlags = TRIGGERED_FULL_MASK; SetTriggeringAura(eff); }
|
||||
CastSpellExtraArgs(Difficulty castDifficulty) { CastDifficulty = castDifficulty; }
|
||||
CastSpellExtraArgs(SpellValueMod mod, int32 val) { SpellValueOverrides.emplace_back(mod, val); }
|
||||
CastSpellExtraArgs(SpellValueModFloat mod, float val) { SpellValueOverrides.emplace_back(mod, val); }
|
||||
CastSpellExtraArgs(CastSpellExtraArgsInit&& init) : CastSpellExtraArgsInit(std::move(init)) { SetTriggeringSpell(TriggeringSpell); }
|
||||
|
||||
CastSpellExtraArgs(CastSpellExtraArgs const& other);
|
||||
CastSpellExtraArgs(CastSpellExtraArgs&& other) noexcept;
|
||||
@@ -474,37 +512,12 @@ struct TC_GAME_API CastSpellExtraArgs
|
||||
CastSpellExtraArgs& SetOriginalCaster(ObjectGuid const& guid) { OriginalCaster = guid; return *this; }
|
||||
CastSpellExtraArgs& SetCastDifficulty(Difficulty castDifficulty) { CastDifficulty = castDifficulty; return *this; }
|
||||
CastSpellExtraArgs& SetOriginalCastId(ObjectGuid const& castId) { OriginalCastId = castId; return *this; }
|
||||
CastSpellExtraArgs& AddSpellMod(SpellValueMod mod, int32 val) { SpellValueOverrides.AddMod(mod, val); return *this; }
|
||||
CastSpellExtraArgs& AddSpellMod(SpellValueMod mod, int32 val) { SpellValueOverrides.emplace_back(mod, val); return *this; }
|
||||
CastSpellExtraArgs& AddSpellMod(SpellValueModFloat mod, float val) { SpellValueOverrides.emplace_back(mod, val); return *this; }
|
||||
CastSpellExtraArgs& AddSpellBP0(int32 val) { return AddSpellMod(SPELLVALUE_BASE_POINT0, val); } // because i don't want to type SPELLVALUE_BASE_POINT0 300 times
|
||||
CastSpellExtraArgs& SetCustomArg(std::any customArg) { CustomArg = std::move(customArg); return *this; }
|
||||
CastSpellExtraArgs& SetScriptResult(Scripting::v2::ActionResultSetter<SpellCastResult> scriptResult) { ScriptResult.emplace(std::move(scriptResult)); return *this; }
|
||||
CastSpellExtraArgs& SetScriptWaitsForSpellHit(bool scriptWaitsForSpellHit) { ScriptWaitsForSpellHit = scriptWaitsForSpellHit; return *this; }
|
||||
|
||||
TriggerCastFlags TriggerFlags = TRIGGERED_NONE;
|
||||
Item* CastItem = nullptr;
|
||||
Spell const* TriggeringSpell = nullptr;
|
||||
AuraEffect const* TriggeringAura = nullptr;
|
||||
ObjectGuid OriginalCaster = ObjectGuid::Empty;
|
||||
Difficulty CastDifficulty = Difficulty(0);
|
||||
ObjectGuid OriginalCastId = ObjectGuid::Empty;
|
||||
Optional<int32> OriginalCastItemLevel;
|
||||
struct
|
||||
{
|
||||
friend struct CastSpellExtraArgs;
|
||||
friend class WorldObject;
|
||||
|
||||
private:
|
||||
void AddMod(SpellValueMod mod, int32 val) { data.push_back({ mod, val }); }
|
||||
|
||||
auto begin() const { return data.cbegin(); }
|
||||
auto end() const { return data.cend(); }
|
||||
|
||||
std::vector<std::pair<SpellValueMod, int32>> data;
|
||||
} SpellValueOverrides;
|
||||
std::any CustomArg;
|
||||
|
||||
Optional<Scripting::v2::ActionResultSetter<SpellCastResult>> ScriptResult;
|
||||
bool ScriptWaitsForSpellHit = false;
|
||||
};
|
||||
|
||||
struct SpellCastVisual
|
||||
|
||||
@@ -555,7 +555,7 @@ public:
|
||||
{
|
||||
void SetRadiusMod()
|
||||
{
|
||||
GetSpell()->SetSpellValue(SPELLVALUE_RADIUS_MOD, int32(GetCaster()->GetObjectScale() * 10000 * 2 / 3));
|
||||
GetSpell()->SetSpellValue(SPELLVALUE_RADIUS_MOD, GetCaster()->GetObjectScale() * 2 / 3);
|
||||
}
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& unitList)
|
||||
@@ -626,7 +626,7 @@ public:
|
||||
{
|
||||
void SetRadiusMod()
|
||||
{
|
||||
GetSpell()->SetSpellValue(SPELLVALUE_RADIUS_MOD, int32(GetCaster()->GetObjectScale() * 10000 * 2 / 3));
|
||||
GetSpell()->SetSpellValue(SPELLVALUE_RADIUS_MOD, GetCaster()->GetObjectScale() * 2 / 3);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
|
||||
@@ -1506,7 +1506,7 @@ class spell_halion_combustion_consumption_periodic : public SpellScriptLoader
|
||||
return;
|
||||
|
||||
uint32 triggerSpell = aurEff->GetSpellEffectInfo().TriggerSpell;
|
||||
int32 radius = caster->GetObjectScale() * M_PI * 10000 / 3;
|
||||
float radius = caster->GetObjectScale() * M_PI / 3;
|
||||
|
||||
CastSpellExtraArgs args(aurEff);
|
||||
args.OriginalCaster = caster->GetGUID();
|
||||
|
||||
@@ -1208,7 +1208,7 @@ class spell_jormungars_slime_pool : public AuraScript
|
||||
{
|
||||
PreventDefaultAction();
|
||||
|
||||
int32 const radius = static_cast<int32>(((aurEff->GetTickNumber() / 60.f) * 0.9f + 0.1f) * 10000.f * 2.f / 3.f);
|
||||
float const radius = ((aurEff->GetTickNumber() / 60.f) * 0.9f + 0.1f) * 2.f / 3.f;
|
||||
CastSpellExtraArgs args(aurEff);
|
||||
args.AddSpellMod(SPELLVALUE_RADIUS_MOD, radius);
|
||||
GetTarget()->CastSpell(nullptr, aurEff->GetSpellEffectInfo().TriggerSpell, args);
|
||||
|
||||
@@ -226,7 +226,7 @@ class spell_grobbulus_poison_cloud : public AuraScript
|
||||
return;
|
||||
|
||||
uint32 triggerSpell = aurEff->GetSpellEffectInfo().TriggerSpell;
|
||||
int32 mod = int32(((float(aurEff->GetTickNumber()) / aurEff->GetTotalTicks()) * 0.9f + 0.1f) * 10000 * 2 / 3);
|
||||
float mod = ((float(aurEff->GetTickNumber()) / aurEff->GetTotalTicks()) * 0.9f + 0.1f) * 2 / 3;
|
||||
|
||||
CastSpellExtraArgs args(aurEff);
|
||||
args.AddSpellMod(SPELLVALUE_RADIUS_MOD, mod);
|
||||
|
||||
@@ -292,7 +292,7 @@ class spell_broggok_poison_cloud : public SpellScriptLoader
|
||||
return;
|
||||
|
||||
uint32 triggerSpell = aurEff->GetSpellEffectInfo().TriggerSpell;
|
||||
int32 mod = int32(((float(aurEff->GetTickNumber()) / aurEff->GetTotalTicks()) * 0.9f + 0.1f) * 10000 * 2 / 3);
|
||||
float mod = ((float(aurEff->GetTickNumber()) / aurEff->GetTotalTicks()) * 0.9f + 0.1f) * 10000 * 2 / 3;
|
||||
GetTarget()->CastSpell(nullptr, triggerSpell, CastSpellExtraArgs(aurEff).AddSpellMod(SPELLVALUE_RADIUS_MOD, mod));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user