mirror of
https://github.com/EQEmu/Server.git
synced 2026-09-04 14:36:37 +00:00
Implemented broad support for fields min_dist, min_dist_mod, max_dist, max_dist_mod -
Scales spell power based on targets distance from caster. This implemented in a broad way to function with spells that would make sense to scale. Some work will still be needed on this. Be aware if making custom spells not everything will work and certain effects just should not be included (use common sense).
This commit is contained in:
+6
-1
@@ -740,6 +740,7 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
|
||||
|
||||
float dist = caster->GetAOERange(spell_id);
|
||||
float dist2 = dist * dist;
|
||||
float dist_targ = 0;
|
||||
|
||||
bool bad = IsDetrimentalSpell(spell_id);
|
||||
bool isnpc = caster->IsNPC();
|
||||
@@ -755,7 +756,9 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
|
||||
continue;
|
||||
if (curmob == caster && !affect_caster) //watch for caster too
|
||||
continue;
|
||||
if (center->DistNoRoot(*curmob) > dist2) //make sure they are in range
|
||||
|
||||
dist_targ = center->DistNoRoot(*curmob);
|
||||
if (dist_targ > dist2) //make sure they are in range
|
||||
continue;
|
||||
if (isnpc && curmob->IsNPC()) { //check npc->npc casting
|
||||
FACTION_VALUE f = curmob->GetReverseFactionCon(caster);
|
||||
@@ -786,6 +789,8 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
|
||||
continue;
|
||||
}
|
||||
|
||||
curmob->CalcSpellPowerDistanceMod(spell_id, dist_targ);
|
||||
|
||||
//if we get here... cast the spell.
|
||||
if (IsTargetableAESpell(spell_id) && bad) {
|
||||
if (iCounter < MAX_TARGETS_ALLOWED) {
|
||||
|
||||
@@ -674,6 +674,7 @@ void Group::CastGroupSpell(Mob* caster, uint16 spell_id) {
|
||||
{
|
||||
distance = caster->DistNoRoot(*members[z]);
|
||||
if(distance <= range2) {
|
||||
members[z]->CalcSpellPowerDistanceMod(spell_id, distance);
|
||||
caster->SpellOnTarget(spell_id, members[z]);
|
||||
#ifdef GROUP_BUFF_PETS
|
||||
if(members[z]->GetPet() && members[z]->HasPetAffinity() && !members[z]->GetPet()->IsCharmed())
|
||||
|
||||
+5
-1
@@ -567,20 +567,24 @@ void HateList::SpellCast(Mob *caster, uint32 spell_id, float range)
|
||||
//So keep a list of entity ids and look up after
|
||||
std::list<uint32> id_list;
|
||||
range = range * range;
|
||||
float dist_targ = 0;
|
||||
auto iterator = list.begin();
|
||||
while (iterator != list.end())
|
||||
{
|
||||
tHateEntry *h = (*iterator);
|
||||
if(range > 0)
|
||||
{
|
||||
if(caster->DistNoRoot(*h->ent) <= range)
|
||||
dist_targ = caster->DistNoRoot(*h->ent);
|
||||
if(dist_targ <= range)
|
||||
{
|
||||
id_list.push_back(h->ent->GetID());
|
||||
h->ent->CalcSpellPowerDistanceMod(spell_id, dist_targ);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
id_list.push_back(h->ent->GetID());
|
||||
h->ent->CalcSpellPowerDistanceMod(spell_id, 0, caster);
|
||||
}
|
||||
++iterator;
|
||||
}
|
||||
|
||||
@@ -182,6 +182,7 @@ Mob::Mob(const char* in_name,
|
||||
has_numhits = false;
|
||||
has_MGB = false;
|
||||
has_ProjectIllusion = false;
|
||||
SpellPowerDistanceMod = 0;
|
||||
|
||||
if(in_aa_title>0)
|
||||
aa_title = in_aa_title;
|
||||
|
||||
@@ -615,6 +615,9 @@ public:
|
||||
bool ImprovedTaunt();
|
||||
bool TryRootFadeByDamage(int buffslot, Mob* attacker);
|
||||
int16 GetSlowMitigation() const {return slow_mitigation;}
|
||||
void CalcSpellPowerDistanceMod(uint16 spell_id, float range, Mob* caster = nullptr);
|
||||
inline int16 GetSpellPowerDistanceMod() const { return SpellPowerDistanceMod; };
|
||||
inline void SetSpellPowerDistanceMod(int16 value) { SpellPowerDistanceMod = value; };
|
||||
|
||||
void ModSkillDmgTaken(SkillUseTypes skill_num, int value);
|
||||
int16 GetModSkillDmgTaken(const SkillUseTypes skill_num);
|
||||
@@ -1114,6 +1117,7 @@ protected:
|
||||
bool has_numhits;
|
||||
bool has_MGB;
|
||||
bool has_ProjectIllusion;
|
||||
int16 SpellPowerDistanceMod;
|
||||
|
||||
// Bind wound
|
||||
Timer bindwound_timer;
|
||||
|
||||
+30
-1
@@ -186,6 +186,12 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
buffs[buffslot].numhits = numhit;
|
||||
}
|
||||
|
||||
bool _IsPowerDistModSpell = false;
|
||||
if (IsPowerDistModSpell(spell_id))
|
||||
_IsPowerDistModSpell = true;
|
||||
else
|
||||
SetSpellPowerDistanceMod(0);
|
||||
|
||||
// iterate through the effects in the spell
|
||||
for (i = 0; i < EFFECT_COUNT; i++)
|
||||
{
|
||||
@@ -198,6 +204,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
if(spell_id == SPELL_LAY_ON_HANDS && caster && caster->GetAA(aaImprovedLayOnHands))
|
||||
effect_value = GetMaxHP();
|
||||
|
||||
if (_IsPowerDistModSpell)
|
||||
effect_value += (effect_value*(GetSpellPowerDistanceMod()/100)/100);
|
||||
|
||||
#ifdef SPELL_EFFECT_SPAM
|
||||
effect_desc[0] = 0;
|
||||
#endif
|
||||
@@ -6444,4 +6453,24 @@ bool Mob::CheckSpellCategory(uint16 spell_id, int category_id, int effect_id){
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Mob::CalcSpellPowerDistanceMod(uint16 spell_id, float range, Mob* caster)
|
||||
{
|
||||
if (IsPowerDistModSpell(spell_id)){
|
||||
|
||||
float distance = 0;
|
||||
|
||||
if (caster && !range)
|
||||
distance = caster->CalculateDistance(GetX(), GetY(), GetZ());
|
||||
else
|
||||
distance = sqrt(range);
|
||||
|
||||
float dm_range = spells[spell_id].max_dist - spells[spell_id].min_dist;
|
||||
float dm_mod_interval = spells[spell_id].max_dist_mod - spells[spell_id].min_dist_mod;
|
||||
float dist_from_min = distance - spells[spell_id].min_dist;
|
||||
float mod = spells[spell_id].min_dist_mod + (dist_from_min * (dm_mod_interval/dm_range));
|
||||
mod *= 100.0f;
|
||||
|
||||
SetSpellPowerDistanceMod(static_cast<int>(mod));
|
||||
}
|
||||
}
|
||||
+8
-2
@@ -1915,6 +1915,8 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
|
||||
Message_StringID(13, TARGET_OUT_OF_RANGE);
|
||||
return(false);
|
||||
}
|
||||
|
||||
spell_target->CalcSpellPowerDistanceMod(spell_id, dist2);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -2114,16 +2116,20 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
|
||||
if((heading_to_target >= angle_start && heading_to_target <= 360.0f) ||
|
||||
(heading_to_target >= 0.0f && heading_to_target <= angle_end))
|
||||
{
|
||||
if(CheckLosFN(spell_target))
|
||||
if(CheckLosFN((*iter)) || spells[spell_id].npc_no_los){
|
||||
(*iter)->CalcSpellPowerDistanceMod(spell_id, 0, this);
|
||||
SpellOnTarget(spell_id, spell_target, false, true, resist_adjust);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(heading_to_target >= angle_start && heading_to_target <= angle_end)
|
||||
{
|
||||
if(CheckLosFN((*iter)))
|
||||
if(CheckLosFN((*iter)) || spells[spell_id].npc_no_los){
|
||||
(*iter)->CalcSpellPowerDistanceMod(spell_id, 0, this);
|
||||
SpellOnTarget(spell_id, (*iter), false, true, resist_adjust);
|
||||
}
|
||||
}
|
||||
}
|
||||
++iter;
|
||||
|
||||
Reference in New Issue
Block a user