mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 17:51:28 +00:00
Merge pull request #160 from KayenEQ/Development
Implemented SE_AStacker, BStacker, CStacker, DStacker
This commit is contained in:
commit
a4fe14a3d3
@ -1,5 +1,22 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 06/17/2014 ==
|
||||
Kayen: Implemented SE_AStacker, SE_BStacker, SE_CStacker, SE_DStacker.
|
||||
These effects when present in buffs prevent each other from stacking,
|
||||
Any effect with B prevents A, C prevents B, D prevents C.
|
||||
Kayen: Implemented SE_DamageModifier2 (Stacks with SE_DamageModifier, mods damage by skill type)
|
||||
Kayen: Implemented SE_AddHatePct (Modifies +/- your total hate on NPC by percent)
|
||||
Kayen: Implemented SE_AddHateOverTimePct (Modifies +/- your total hate on NPC by percent over time)
|
||||
Kayen: Implemented SE_DoubleRiposte (Modifies +/- your double riposte chance) *Not used in any live effects
|
||||
Kayen: Implemented SE_Berserk (Sets client as 'Berserk' giving chance to crippling blow) *Not used in any live effects
|
||||
Kayen: Implemented SE_Vampirsm (Stackable lifetap from melee effect) *Not used in any live effects
|
||||
Kayen: Minor fixes to how lifetap from melee effects are calced. Removed arbitrary hard cap of 100%, Negative value will now dmg client.
|
||||
Kayen: Fix to issue that prevented NPC's from receiving HP Regeneration derived from spell buffs.
|
||||
Kayen: Fixes and Updates for melee and spell mitigation runes.
|
||||
Kayen: Update to SE_NegateAttack, 'max' value can now set upper limit of damage absorbed. DOT ticks will no longer be absorbed.
|
||||
Kayen: Implemented SE_Metabolism - Modifies food/drink consumption rates. [Data for AA is already in database]
|
||||
Kayen: Update to SE_BalanaceMana, SE_BalanceHP to support limit value which caps max mana/hp that can be taken per player.
|
||||
|
||||
== 06/13/2014 ==
|
||||
Kayen: For table 'npc_spell_effects_entries' setting se_max for damage shield effects (59) will now determine the DS Type (ie burning)
|
||||
Setting se_max to 1 for SkillDamageTaken effects (127) will allow for stackable mitigation/weakness same as quest function ModSkillDmgTaken.
|
||||
|
||||
@ -1009,6 +1009,19 @@ uint32 GetMorphTrigger(uint32 spell_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool IsCastonFadeDurationSpell(uint16 spell_id)
|
||||
{
|
||||
for (int i = 0; i < EFFECT_COUNT; ++i) {
|
||||
if (spells[spell_id].effectid[i] == SE_ImprovedSpellEffect
|
||||
|| spells[spell_id].effectid[i] == SE_BossSpellTrigger
|
||||
|| spells[spell_id].effectid[i] == SE_CastOnWearoff){
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 GetPartialMeleeRuneReduction(uint32 spell_id)
|
||||
{
|
||||
for (int i = 0; i < EFFECT_COUNT; ++i)
|
||||
|
||||
@ -190,9 +190,9 @@ typedef enum {
|
||||
#define SE_DivineAura 40 // implemented
|
||||
#define SE_Destroy 41 // implemented - Disintegrate, Banishment of Shadows
|
||||
#define SE_ShadowStep 42 // implemented
|
||||
//#define SE_Berserk 43 // not used
|
||||
#define SE_Lycanthropy 44 // implemented
|
||||
//#define SE_Vampirism 45 // not used
|
||||
#define SE_Berserk 43 // implemented (*not used in any known live spell) Makes client 'Berserk' giving crip blow chance.
|
||||
#define SE_Lycanthropy 44 // implemented
|
||||
#define SE_Vampirism 45 // implemented (*not used in any known live spell) Stackable lifetap from melee.
|
||||
#define SE_ResistFire 46 // implemented
|
||||
#define SE_ResistCold 47 // implemented
|
||||
#define SE_ResistPoison 48 // implemented
|
||||
@ -307,7 +307,7 @@ typedef enum {
|
||||
#define SE_SpellDamageShield 157 // implemented - Petrad's Protection
|
||||
#define SE_Reflect 158 // implemented
|
||||
#define SE_AllStats 159 // implemented
|
||||
#define SE_MakeDrunk 160 // implemented - poorly though, should check against tolerance
|
||||
//#define SE_MakeDrunk 160 // *not implemented - Effect works entirely client side (Should check against tolerance)
|
||||
#define SE_MitigateSpellDamage 161 // implemented - rune with max value
|
||||
#define SE_MitigateMeleeDamage 162 // implemented - rune with max value
|
||||
#define SE_NegateAttacks 163 // implemented
|
||||
@ -370,7 +370,7 @@ typedef enum {
|
||||
#define SE_SkillDamageAmount 220 // implemented
|
||||
#define SE_Packrat 221 // implemented as bonus
|
||||
#define SE_BlockBehind 222 // implemented - Chance to block from behind (with our without Shield)
|
||||
//#define SE_DoubleRiposte 223 // not used
|
||||
#define SE_DoubleRiposte 223 // implemented - Chance to double riposte [not used on live]
|
||||
#define SE_GiveDoubleRiposte 224 // implemented[AA]
|
||||
#define SE_GiveDoubleAttack 225 // implemented[AA] - Allow any class to double attack with set chance.
|
||||
#define SE_TwoHandBash 226 // *not implemented as bonus
|
||||
@ -380,7 +380,7 @@ typedef enum {
|
||||
//#define SE_ExtendedShielding 230 // not used as bonus - increase range of /shield ability
|
||||
#define SE_StunBashChance 231 // implemented - increase chance to stun from bash.
|
||||
#define SE_DivineSave 232 // implemented (base1 == % chance on death to insta-res) (base2 == spell cast on save)
|
||||
//#define SE_Metabolism 233 // *not implemented - (Crown of Feathers) Increase metabolism?
|
||||
#define SE_Metabolism 233 // implemented - Modifies food/drink consumption rates.
|
||||
//#define SE_ReduceApplyPoisonTime 234 // not implemented as bonus - reduces the time to apply poison
|
||||
#define SE_ChannelChanceSpells 235 // implemented[AA] - chance to channel from SPELLS *No longer used on live.
|
||||
//#define SE_FreePet 236 // not used
|
||||
@ -593,20 +593,20 @@ typedef enum {
|
||||
#define SE_TriggerOnReqCaster 443 // implemented - triggers a spell which a certain criteria are met (below X amount of hp,mana,end, number of pets on hatelist)
|
||||
#define SE_ImprovedTaunt 444 // implemented - Locks Aggro On Caster and Decrease other Players Aggro by X% on NPC targets below level Y
|
||||
//#define SE_AddMercSlot 445 // *not implemented[AA] - [Hero's Barracks] Allows you to conscript additional mercs.
|
||||
//#define SE_AStacker 446 // *not implementet - bufff stacking blocker ? (26219 | Qirik's Watch)
|
||||
//#define SE_BStacker 447 // *not implemented
|
||||
//#define SE_CStacker 448 // *not implemented
|
||||
//#define SE_DStacker 449 // *not implemented
|
||||
#define SE_AStacker 446 // implementet - bufff stacking blocker (26219 | Qirik's Watch)
|
||||
#define SE_BStacker 447 // implemented
|
||||
#define SE_CStacker 448 // implemented
|
||||
#define SE_DStacker 449 // implemented
|
||||
#define SE_MitigateDotDamage 450 // implemented DOT spell mitigation rune with max value
|
||||
#define SE_MeleeThresholdGuard 451 // implemented Partial Melee Rune that only is lowered if melee hits are over X amount of damage
|
||||
#define SE_SpellThresholdGuard 452 // implemented Partial Spell Rune that only is lowered if spell hits are over X amount of damage
|
||||
#define SE_TriggerMeleeThreshold 453 // implemented Trigger effect on X amount of melee damage taken
|
||||
#define SE_TriggerSpellThreshold 454 // implemented Trigger effect on X amount of spell damage taken
|
||||
//#define SE_AddHatePct 455 // not used
|
||||
//#define SE_AddHateOverTimePct 456 // not used
|
||||
#define SE_AddHatePct 455 // implemented Modify total hate by %
|
||||
#define SE_AddHateOverTimePct 456 // implemented Modify total hate by % over time.
|
||||
//#define SE_ResourceTap 457 // not used
|
||||
//#define SE_FactionModPct 458 // not used
|
||||
//#define SE_DamageModifier2 459 // *not implemented - Modifies melee damage by skill type
|
||||
#define SE_DamageModifier2 459 // implemented - Modifies melee damage by skill type
|
||||
|
||||
// LAST
|
||||
|
||||
@ -833,6 +833,7 @@ bool IsBuffSpell(uint16 spell_id);
|
||||
bool IsPersistDeathSpell(uint16 spell_id);
|
||||
bool IsSuspendableSpell(uint16 spell_id);
|
||||
uint32 GetMorphTrigger(uint32 spell_id);
|
||||
bool IsCastonFadeDurationSpell(uint16 spell_id);
|
||||
uint32 GetPartialMeleeRuneReduction(uint32 spell_id);
|
||||
uint32 GetPartialMagicRuneReduction(uint32 spell_id);
|
||||
uint32 GetPartialMeleeRuneAmount(uint32 spell_id);
|
||||
|
||||
@ -3176,7 +3176,11 @@ int32 Mob::ReduceDamage(int32 damage)
|
||||
if(!TryFadeEffect(slot))
|
||||
BuffFadeBySlot(slot , true);
|
||||
}
|
||||
return -6;
|
||||
|
||||
if (spellbonuses.NegateAttacks[2] && (damage > spellbonuses.NegateAttacks[2]))
|
||||
damage -= spellbonuses.NegateAttacks[2];
|
||||
else
|
||||
return -6;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3188,11 +3192,11 @@ int32 Mob::ReduceDamage(int32 damage)
|
||||
{
|
||||
DisableMeleeRune = true;
|
||||
int damage_to_reduce = damage * spellbonuses.MeleeThresholdGuard[0] / 100;
|
||||
if(damage_to_reduce > buffs[slot].melee_rune)
|
||||
if(damage_to_reduce >= buffs[slot].melee_rune)
|
||||
{
|
||||
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MeleeThresholdGuard %d damage negated, %d"
|
||||
" damage remaining, fading buff.", damage_to_reduce, buffs[slot].melee_rune);
|
||||
damage -= damage_to_reduce;
|
||||
damage -= buffs[slot].melee_rune;
|
||||
if(!TryFadeEffect(slot))
|
||||
BuffFadeBySlot(slot);
|
||||
}
|
||||
@ -3212,11 +3216,15 @@ int32 Mob::ReduceDamage(int32 damage)
|
||||
if(slot >= 0)
|
||||
{
|
||||
int damage_to_reduce = damage * spellbonuses.MitigateMeleeRune[0] / 100;
|
||||
if(damage_to_reduce > buffs[slot].melee_rune)
|
||||
|
||||
if (spellbonuses.MitigateMeleeRune[2] && (damage_to_reduce > spellbonuses.MitigateMeleeRune[2]))
|
||||
damage_to_reduce = spellbonuses.MitigateMeleeRune[2];
|
||||
|
||||
if(spellbonuses.MitigateMeleeRune[3] && (damage_to_reduce >= buffs[slot].melee_rune))
|
||||
{
|
||||
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateMeleeDamage %d damage negated, %d"
|
||||
" damage remaining, fading buff.", damage_to_reduce, buffs[slot].melee_rune);
|
||||
damage -= damage_to_reduce;
|
||||
damage -= buffs[slot].melee_rune;
|
||||
if(!TryFadeEffect(slot))
|
||||
BuffFadeBySlot(slot);
|
||||
}
|
||||
@ -3224,7 +3232,10 @@ int32 Mob::ReduceDamage(int32 damage)
|
||||
{
|
||||
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateMeleeDamage %d damage negated, %d"
|
||||
" damage remaining.", damage_to_reduce, buffs[slot].melee_rune);
|
||||
buffs[slot].melee_rune = (buffs[slot].melee_rune - damage_to_reduce);
|
||||
|
||||
if (spellbonuses.MitigateMeleeRune[3])
|
||||
buffs[slot].melee_rune = (buffs[slot].melee_rune - damage_to_reduce);
|
||||
|
||||
damage -= damage_to_reduce;
|
||||
}
|
||||
}
|
||||
@ -3265,7 +3276,7 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
|
||||
int32 slot = -1;
|
||||
|
||||
// See if we block the spell outright first
|
||||
if (spellbonuses.NegateAttacks[0]){
|
||||
if (!iBuffTic && spellbonuses.NegateAttacks[0]){
|
||||
slot = spellbonuses.NegateAttacks[1];
|
||||
if(slot >= 0) {
|
||||
if(--buffs[slot].numhits == 0) {
|
||||
@ -3273,7 +3284,11 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
|
||||
if(!TryFadeEffect(slot))
|
||||
BuffFadeBySlot(slot , true);
|
||||
}
|
||||
return 0;
|
||||
|
||||
if (spellbonuses.NegateAttacks[2] && (damage > spellbonuses.NegateAttacks[2]))
|
||||
damage -= spellbonuses.NegateAttacks[2];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3286,15 +3301,21 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
|
||||
if(slot >= 0)
|
||||
{
|
||||
int damage_to_reduce = damage * spellbonuses.MitigateDotRune[0] / 100;
|
||||
if(damage_to_reduce > buffs[slot].dot_rune)
|
||||
|
||||
if (spellbonuses.MitigateDotRune[2] && (damage_to_reduce > spellbonuses.MitigateDotRune[2]))
|
||||
damage_to_reduce = spellbonuses.MitigateDotRune[2];
|
||||
|
||||
if(spellbonuses.MitigateDotRune[3] && (damage_to_reduce >= buffs[slot].dot_rune))
|
||||
{
|
||||
damage -= damage_to_reduce;
|
||||
damage -= buffs[slot].dot_rune;
|
||||
if(!TryFadeEffect(slot))
|
||||
BuffFadeBySlot(slot);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffs[slot].dot_rune = (buffs[slot].dot_rune - damage_to_reduce);
|
||||
if (spellbonuses.MitigateDotRune[3])
|
||||
buffs[slot].dot_rune = (buffs[slot].dot_rune - damage_to_reduce);
|
||||
|
||||
damage -= damage_to_reduce;
|
||||
}
|
||||
}
|
||||
@ -3316,9 +3337,9 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
|
||||
{
|
||||
DisableSpellRune = true;
|
||||
int damage_to_reduce = damage * spellbonuses.SpellThresholdGuard[0] / 100;
|
||||
if(damage_to_reduce > buffs[slot].magic_rune)
|
||||
if(damage_to_reduce >= buffs[slot].magic_rune)
|
||||
{
|
||||
damage -= damage_to_reduce;
|
||||
damage -= buffs[slot].magic_rune;
|
||||
if(!TryFadeEffect(slot))
|
||||
BuffFadeBySlot(slot);
|
||||
}
|
||||
@ -3337,11 +3358,15 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
|
||||
if(slot >= 0)
|
||||
{
|
||||
int damage_to_reduce = damage * spellbonuses.MitigateSpellRune[0] / 100;
|
||||
if(damage_to_reduce > buffs[slot].magic_rune)
|
||||
|
||||
if (spellbonuses.MitigateSpellRune[2] && (damage_to_reduce > spellbonuses.MitigateSpellRune[2]))
|
||||
damage_to_reduce = spellbonuses.MitigateSpellRune[2];
|
||||
|
||||
if(spellbonuses.MitigateSpellRune[3] && (damage_to_reduce >= buffs[slot].magic_rune))
|
||||
{
|
||||
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateSpellDamage %d damage negated, %d"
|
||||
" damage remaining, fading buff.", damage_to_reduce, buffs[slot].magic_rune);
|
||||
damage -= damage_to_reduce;
|
||||
damage -= buffs[slot].magic_rune;
|
||||
if(!TryFadeEffect(slot))
|
||||
BuffFadeBySlot(slot);
|
||||
}
|
||||
@ -3349,7 +3374,10 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
|
||||
{
|
||||
mlog(SPELLS__EFFECT_VALUES, "Mob::ReduceDamage SE_MitigateMeleeDamage %d damage negated, %d"
|
||||
" damage remaining.", damage_to_reduce, buffs[slot].magic_rune);
|
||||
buffs[slot].magic_rune = (buffs[slot].magic_rune - damage_to_reduce);
|
||||
|
||||
if (spellbonuses.MitigateSpellRune[3])
|
||||
buffs[slot].magic_rune = (buffs[slot].magic_rune - damage_to_reduce);
|
||||
|
||||
damage -= damage_to_reduce;
|
||||
}
|
||||
}
|
||||
@ -4283,6 +4311,7 @@ void Mob::TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttack
|
||||
|
||||
|
||||
float critChance = 0.0f;
|
||||
bool IsBerskerSPA = false;
|
||||
|
||||
//1: Try Slay Undead
|
||||
if(defender && defender->GetBodyType() == BT_Undead || defender->GetBodyType() == BT_SummonedUndead || defender->GetBodyType() == BT_Vampire){
|
||||
@ -4310,12 +4339,15 @@ void Mob::TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttack
|
||||
//are defined you will have an innate chance to hit at Level 1 regardless of bonuses.
|
||||
//Warning: Do not define these rules if you want live like critical hits.
|
||||
critChance += RuleI(Combat, MeleeBaseCritChance);
|
||||
|
||||
|
||||
if (IsClient()) {
|
||||
critChance += RuleI(Combat, ClientBaseCritChance);
|
||||
critChance += RuleI(Combat, ClientBaseCritChance);
|
||||
|
||||
if ((GetClass() == WARRIOR || GetClass() == BERSERKER) && GetLevel() >= 12) {
|
||||
if (IsBerserk())
|
||||
if (spellbonuses.BerserkSPA || itembonuses.BerserkSPA || aabonuses.BerserkSPA)
|
||||
IsBerskerSPA = true;
|
||||
|
||||
if (((GetClass() == WARRIOR || GetClass() == BERSERKER) && GetLevel() >= 12) || IsBerskerSPA) {
|
||||
if (IsBerserk() || IsBerskerSPA)
|
||||
critChance += RuleI(Combat, BerserkBaseCritChance);
|
||||
else
|
||||
critChance += RuleI(Combat, WarBerBaseCritChance);
|
||||
@ -4360,15 +4392,15 @@ void Mob::TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttack
|
||||
uint16 critMod = 200;
|
||||
bool crip_success = false;
|
||||
int16 CripplingBlowChance = GetCrippBlowChance();
|
||||
|
||||
|
||||
//Crippling Blow Chance: The percent value of the effect is applied
|
||||
//to the your Chance to Critical. (ie You have 10% chance to critical and you
|
||||
//have a 200% Chance to Critical Blow effect, therefore you have a 20% Chance to Critical Blow.
|
||||
if (CripplingBlowChance || IsBerserk()) {
|
||||
if (!IsBerserk())
|
||||
if (CripplingBlowChance || (IsBerserk() || IsBerskerSPA)) {
|
||||
if (!IsBerserk() && !IsBerskerSPA)
|
||||
critChance *= float(CripplingBlowChance)/100.0f;
|
||||
|
||||
if (IsBerserk() || MakeRandomFloat(0, 1) < critChance) {
|
||||
if ((IsBerserk() || IsBerskerSPA) || MakeRandomFloat(0, 1) < critChance) {
|
||||
critMod = 400;
|
||||
crip_success = true;
|
||||
}
|
||||
@ -4449,6 +4481,10 @@ void Mob::DoRiposte(Mob* defender) {
|
||||
defender->spellbonuses.GiveDoubleRiposte[0] +
|
||||
defender->itembonuses.GiveDoubleRiposte[0];
|
||||
|
||||
DoubleRipChance = defender->aabonuses.DoubleRiposte +
|
||||
defender->spellbonuses.DoubleRiposte +
|
||||
defender->itembonuses.DoubleRiposte;
|
||||
|
||||
//Live AA - Double Riposte
|
||||
if(DoubleRipChance && (DoubleRipChance >= MakeRandomInt(0, 100))) {
|
||||
mlog(COMBAT__ATTACKS, "Preforming a double riposed (%d percent chance)", DoubleRipChance);
|
||||
|
||||
114
zone/bonuses.cpp
114
zone/bonuses.cpp
@ -1099,6 +1099,15 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_DamageModifier2:
|
||||
{
|
||||
if(base2 == -1)
|
||||
newbon->DamageModifier2[HIGHEST_SKILL+1] += base1;
|
||||
else
|
||||
newbon->DamageModifier2[base2] += base1;
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_SlayUndead:
|
||||
{
|
||||
if(newbon->SlayUndead[1] < base1)
|
||||
@ -1107,6 +1116,11 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_DoubleRiposte:
|
||||
{
|
||||
newbon->DoubleRiposte += base1;
|
||||
}
|
||||
|
||||
case SE_GiveDoubleRiposte:
|
||||
{
|
||||
//0=Regular Riposte 1=Skill Attack Riposte 2=Skill
|
||||
@ -1234,6 +1248,10 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_Vampirism:
|
||||
newbon->Vampirism += base1;
|
||||
break;
|
||||
|
||||
case SE_FrenziedDevastation:
|
||||
newbon->FrenziedDevastation += base2;
|
||||
break;
|
||||
@ -1242,6 +1260,14 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
|
||||
newbon->SpellProcChance += base1;
|
||||
break;
|
||||
|
||||
case SE_Berserk:
|
||||
newbon->BerserkSPA = true;
|
||||
break;
|
||||
|
||||
case SE_Metabolism:
|
||||
newbon->Metabolism += base1;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1813,6 +1839,10 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_Vampirism:
|
||||
newbon->Vampirism += effect_value;
|
||||
break;
|
||||
|
||||
case SE_AllInstrumentMod:
|
||||
{
|
||||
if(effect_value > newbon->singingMod)
|
||||
@ -1909,6 +1939,15 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_DamageModifier2:
|
||||
{
|
||||
if(base2 == -1)
|
||||
newbon->DamageModifier2[HIGHEST_SKILL+1] += effect_value;
|
||||
else
|
||||
newbon->DamageModifier2[base2] += effect_value;
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_MinDamageModifier:
|
||||
{
|
||||
if(base2 == -1)
|
||||
@ -2256,9 +2295,11 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
|
||||
|
||||
case SE_NegateAttacks:
|
||||
{
|
||||
if (!newbon->NegateAttacks[0]){
|
||||
if (!newbon->NegateAttacks[0] ||
|
||||
((newbon->NegateAttacks[0] && newbon->NegateAttacks[2]) && (newbon->NegateAttacks[2] < max))){
|
||||
newbon->NegateAttacks[0] = 1;
|
||||
newbon->NegateAttacks[1] = buffslot;
|
||||
newbon->NegateAttacks[2] = max;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2268,6 +2309,8 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
|
||||
if (newbon->MitigateMeleeRune[0] < effect_value){
|
||||
newbon->MitigateMeleeRune[0] = effect_value;
|
||||
newbon->MitigateMeleeRune[1] = buffslot;
|
||||
newbon->MitigateMeleeRune[2] = base2;
|
||||
newbon->MitigateMeleeRune[3] = max;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2298,6 +2341,8 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
|
||||
if (newbon->MitigateSpellRune[0] < effect_value){
|
||||
newbon->MitigateSpellRune[0] = effect_value;
|
||||
newbon->MitigateSpellRune[1] = buffslot;
|
||||
newbon->MitigateSpellRune[2] = base2;
|
||||
newbon->MitigateSpellRune[3] = max;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2307,6 +2352,8 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
|
||||
if (newbon->MitigateDotRune[0] < effect_value){
|
||||
newbon->MitigateDotRune[0] = effect_value;
|
||||
newbon->MitigateDotRune[1] = buffslot;
|
||||
newbon->MitigateDotRune[2] = base2;
|
||||
newbon->MitigateDotRune[3] = max;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2553,6 +2600,11 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_DoubleRiposte:
|
||||
{
|
||||
newbon->DoubleRiposte += effect_value;
|
||||
}
|
||||
|
||||
case SE_GiveDoubleRiposte:
|
||||
{
|
||||
//Only allow for regular double riposte chance.
|
||||
@ -2661,6 +2713,31 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
|
||||
}
|
||||
break;
|
||||
|
||||
case SE_AStacker:
|
||||
newbon->AStacker = true;
|
||||
break;
|
||||
|
||||
case SE_BStacker:
|
||||
newbon->BStacker = true;
|
||||
break;
|
||||
|
||||
case SE_CStacker:
|
||||
newbon->CStacker = true;
|
||||
break;
|
||||
|
||||
case SE_DStacker:
|
||||
newbon->DStacker = true;
|
||||
break;
|
||||
|
||||
case SE_Berserk:
|
||||
newbon->BerserkSPA = true;
|
||||
break;
|
||||
|
||||
|
||||
case SE_Metabolism:
|
||||
newbon->Metabolism += effect_value;
|
||||
break;
|
||||
|
||||
//Special custom cases for loading effects on to NPC from 'npc_spels_effects' table
|
||||
if (IsAISpellEffect) {
|
||||
|
||||
@ -3438,6 +3515,17 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_DamageModifier2:
|
||||
{
|
||||
for(int e = 0; e < HIGHEST_SKILL+1; e++)
|
||||
{
|
||||
spellbonuses.DamageModifier2[e] = effect_value;
|
||||
aabonuses.DamageModifier2[e] = effect_value;
|
||||
itembonuses.DamageModifier2[e] = effect_value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_MinDamageModifier:
|
||||
{
|
||||
for(int e = 0; e < HIGHEST_SKILL+1; e++)
|
||||
@ -3933,6 +4021,12 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
|
||||
itembonuses.MasteryofPast = effect_value;
|
||||
break;
|
||||
|
||||
case SE_DoubleRiposte:
|
||||
spellbonuses.DoubleRiposte = effect_value;
|
||||
itembonuses.DoubleRiposte = effect_value;
|
||||
aabonuses.DoubleRiposte = effect_value;
|
||||
break;
|
||||
|
||||
case SE_GiveDoubleRiposte:
|
||||
spellbonuses.GiveDoubleRiposte[0] = effect_value;
|
||||
itembonuses.GiveDoubleRiposte[0] = effect_value;
|
||||
@ -4033,6 +4127,24 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
|
||||
spellbonuses.AbsorbMagicAtt[0] = effect_value;
|
||||
spellbonuses.AbsorbMagicAtt[1] = -1;
|
||||
break;
|
||||
|
||||
case SE_Berserk:
|
||||
spellbonuses.BerserkSPA = false;
|
||||
aabonuses.BerserkSPA = false;
|
||||
itembonuses.BerserkSPA = false;
|
||||
break;
|
||||
|
||||
case SE_Vampirism:
|
||||
spellbonuses.Vampirism = effect_value;
|
||||
aabonuses.Vampirism = effect_value;
|
||||
itembonuses.Vampirism = effect_value;
|
||||
break;
|
||||
|
||||
case SE_Metabolism:
|
||||
spellbonuses.Metabolism = effect_value;
|
||||
aabonuses.Metabolism = effect_value;
|
||||
itembonuses.Metabolism = effect_value;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -8134,20 +8134,12 @@ void Client::Consume(const Item_Struct *item, uint8 type, int16 slot, bool auto_
|
||||
|
||||
uint16 cons_mod = 180;
|
||||
|
||||
switch(GetAA(aaInnateMetabolism)){
|
||||
case 1:
|
||||
cons_mod = cons_mod * 110 * RuleI(Character, ConsumptionMultiplier) / 10000;
|
||||
break;
|
||||
case 2:
|
||||
cons_mod = cons_mod * 125 * RuleI(Character, ConsumptionMultiplier) / 10000;
|
||||
break;
|
||||
case 3:
|
||||
cons_mod = cons_mod * 150 * RuleI(Character, ConsumptionMultiplier) / 10000;
|
||||
break;
|
||||
default:
|
||||
cons_mod = cons_mod * RuleI(Character, ConsumptionMultiplier) / 100;
|
||||
break;
|
||||
}
|
||||
int16 metabolism_bonus = spellbonuses.Metabolism + itembonuses.Metabolism + aabonuses.Metabolism;
|
||||
|
||||
if (metabolism_bonus)
|
||||
cons_mod = cons_mod * metabolism_bonus * RuleI(Character, ConsumptionMultiplier) / 10000;
|
||||
else
|
||||
cons_mod = cons_mod * RuleI(Character, ConsumptionMultiplier) / 100;
|
||||
|
||||
if(type == ItemTypeFood)
|
||||
{
|
||||
|
||||
@ -279,6 +279,7 @@ struct StatBonuses {
|
||||
int16 HitChance; //HitChance/15 == % increase i = Accuracy (Item: Accuracy)
|
||||
int16 HitChanceEffect[HIGHEST_SKILL+2]; //Spell effect Chance to Hit, straight percent increase
|
||||
int16 DamageModifier[HIGHEST_SKILL+2]; //i
|
||||
int16 DamageModifier2[HIGHEST_SKILL+2]; //i
|
||||
int16 MinDamageModifier[HIGHEST_SKILL+2]; //i
|
||||
int16 ProcChance; // ProcChance/10 == % increase i = CombatEffects
|
||||
int16 ProcChanceSPA; // ProcChance from spell effects
|
||||
@ -289,7 +290,8 @@ struct StatBonuses {
|
||||
int16 FlurryChance;
|
||||
int16 Accuracy[HIGHEST_SKILL+2]; //Accuracy/15 == % increase [Spell Effect: Accuracy)
|
||||
int16 HundredHands; //extra haste, stacks with all other haste i
|
||||
int8 MeleeLifetap; //i
|
||||
int16 MeleeLifetap; //i
|
||||
int16 Vampirism; //i
|
||||
int16 HealRate; // Spell effect that influences effectiveness of heals
|
||||
int32 MaxHPChange; // Spell Effect
|
||||
int16 SkillDmgTaken[HIGHEST_SKILL+2]; // All Skills + -1
|
||||
@ -326,12 +328,12 @@ struct StatBonuses {
|
||||
uint16 FocusEffects[HIGHEST_FOCUS+1]; // Stores the focus effectid for each focustype you have.
|
||||
bool NegateEffects; // Check if you contain a buff with negate effect. (only spellbonuses)
|
||||
int16 SkillDamageAmount2[HIGHEST_SKILL+2]; // Adds skill specific damage
|
||||
uint16 NegateAttacks[2]; // 0 = bool HasEffect 1 = Buff Slot
|
||||
uint16 MitigateMeleeRune[2]; // 0 = Mitigation value 1 = Buff Slot
|
||||
uint16 NegateAttacks[3]; // 0 = bool HasEffect 1 = Buff Slot 2 = Max damage absorbed per hit
|
||||
uint16 MitigateMeleeRune[4]; // 0 = Mitigation value 1 = Buff Slot 2 = Max mitigation per hit 3 = Rune Amt
|
||||
uint16 MeleeThresholdGuard[3]; // 0 = Mitigation value 1 = Buff Slot 2 = Min damage to trigger.
|
||||
uint16 SpellThresholdGuard[3]; // 0 = Mitigation value 1 = Buff Slot 2 = Min damage to trigger.
|
||||
uint16 MitigateSpellRune[2]; // 0 = Mitigation value 1 = Buff Slot
|
||||
uint16 MitigateDotRune[2]; // 0 = Mitigation value 1 = Buff Slot
|
||||
uint16 MitigateSpellRune[4]; // 0 = Mitigation value 1 = Buff Slot 2 = Max mitigation per spell 3 = Rune Amt
|
||||
uint16 MitigateDotRune[4]; // 0 = Mitigation value 1 = Buff Slot 2 = Max mitigation per tick 3 = Rune Amt
|
||||
uint32 TriggerMeleeThreshold[3]; // 0 = Spell Effect ID 1 = Buff slot 2 = Damage Amount to Trigger
|
||||
uint32 TriggerSpellThreshold[3]; // 0 = Spell Effect ID 1 = Buff slot 2 = Damage Amount to Trigger
|
||||
uint16 ManaAbsorbPercentDamage[2]; // 0 = Mitigation value 1 = Buff Slot
|
||||
@ -350,6 +352,12 @@ struct StatBonuses {
|
||||
bool NegateIfCombat; // Bool Drop buff if cast or melee
|
||||
int8 Screech; // -1 = Will be blocked if another Screech is +(1)
|
||||
int16 AlterNPCLevel; // amount of lvls +/-
|
||||
bool AStacker; // For buff stack blocking
|
||||
bool BStacker; // For buff stack blocking
|
||||
bool CStacker; // For buff stack blocking
|
||||
bool DStacker; // For buff stack blocking
|
||||
bool BerserkSPA; // berserk effect
|
||||
int16 Metabolism; // Food/drink consumption rates.
|
||||
|
||||
// AAs
|
||||
int8 Packrat; //weight reduction for items, 1 point = 10%
|
||||
@ -378,6 +386,7 @@ struct StatBonuses {
|
||||
int16 PetCriticalHit; // Allow pets to critical hit with % value.
|
||||
int16 PetAvoidance; // Pet avoidance chance.
|
||||
int16 CombatStability; // Melee damage mitigation.
|
||||
int16 DoubleRiposte; // Chance to double riposte
|
||||
int16 GiveDoubleRiposte[3]; // 0=Regular Chance, 1=Skill Attack Chance, 2=Skill
|
||||
uint16 RaiseSkillCap[2]; // Raise a specific skill cap (1 = value, 2=skill)
|
||||
int16 Ambidexterity; // Increase chance to duel wield by adding bonus 'skill'.
|
||||
|
||||
@ -1095,7 +1095,7 @@ void Group::HealGroup(uint32 heal_amt, Mob* caster, int32 range)
|
||||
}
|
||||
|
||||
|
||||
void Group::BalanceHP(int32 penalty, int32 range, Mob* caster)
|
||||
void Group::BalanceHP(int32 penalty, int32 range, Mob* caster, int32 limit)
|
||||
{
|
||||
if (!caster)
|
||||
return;
|
||||
@ -1103,7 +1103,7 @@ void Group::BalanceHP(int32 penalty, int32 range, Mob* caster)
|
||||
if (!range)
|
||||
range = 200;
|
||||
|
||||
int dmgtaken = 0, numMem = 0;
|
||||
int dmgtaken = 0, numMem = 0, dmgtaken_tmp = 0;
|
||||
|
||||
float distance;
|
||||
float range2 = range*range;
|
||||
@ -1114,7 +1114,12 @@ void Group::BalanceHP(int32 penalty, int32 range, Mob* caster)
|
||||
if(members[gi]){
|
||||
distance = caster->DistNoRoot(*members[gi]);
|
||||
if(distance <= range2){
|
||||
dmgtaken += (members[gi]->GetMaxHP() - members[gi]->GetHP());
|
||||
|
||||
dmgtaken_tmp = members[gi]->GetMaxHP() - members[gi]->GetHP();
|
||||
if (limit && (dmgtaken_tmp > limit))
|
||||
dmgtaken_tmp = limit;
|
||||
|
||||
dmgtaken += (dmgtaken_tmp);
|
||||
numMem += 1;
|
||||
}
|
||||
}
|
||||
@ -1140,7 +1145,7 @@ void Group::BalanceHP(int32 penalty, int32 range, Mob* caster)
|
||||
}
|
||||
}
|
||||
|
||||
void Group::BalanceMana(int32 penalty, int32 range, Mob* caster)
|
||||
void Group::BalanceMana(int32 penalty, int32 range, Mob* caster, int32 limit)
|
||||
{
|
||||
if (!caster)
|
||||
return;
|
||||
@ -1151,14 +1156,19 @@ void Group::BalanceMana(int32 penalty, int32 range, Mob* caster)
|
||||
float distance;
|
||||
float range2 = range*range;
|
||||
|
||||
int manataken = 0, numMem = 0;
|
||||
int manataken = 0, numMem = 0, manataken_tmp = 0;
|
||||
unsigned int gi = 0;
|
||||
for(; gi < MAX_GROUP_MEMBERS; gi++)
|
||||
{
|
||||
if(members[gi]){
|
||||
if(members[gi] && (members[gi]->GetMaxMana() > 0)){
|
||||
distance = caster->DistNoRoot(*members[gi]);
|
||||
if(distance <= range2){
|
||||
manataken += (members[gi]->GetMaxMana() - members[gi]->GetMana());
|
||||
|
||||
manataken_tmp = members[gi]->GetMaxMana() - members[gi]->GetMana();
|
||||
if (limit && (manataken_tmp > limit))
|
||||
manataken_tmp = limit;
|
||||
|
||||
manataken += (manataken_tmp);
|
||||
numMem += 1;
|
||||
}
|
||||
}
|
||||
@ -1166,6 +1176,10 @@ void Group::BalanceMana(int32 penalty, int32 range, Mob* caster)
|
||||
|
||||
manataken += manataken * penalty / 100;
|
||||
manataken /= numMem;
|
||||
|
||||
if (limit && (manataken > limit))
|
||||
manataken = limit;
|
||||
|
||||
for(gi = 0; gi < MAX_GROUP_MEMBERS; gi++)
|
||||
{
|
||||
if(members[gi]){
|
||||
|
||||
@ -86,8 +86,8 @@ public:
|
||||
uint16 GetAvgLevel();
|
||||
bool LearnMembers();
|
||||
void VerifyGroup();
|
||||
void BalanceHP(int32 penalty, int32 range = 0, Mob* caster = nullptr);
|
||||
void BalanceMana(int32 penalty, int32 range = 0, Mob* caster = nullptr);
|
||||
void BalanceHP(int32 penalty, int32 range = 0, Mob* caster = nullptr, int32 limit = 0);
|
||||
void BalanceMana(int32 penalty, int32 range = 0, Mob* caster = nullptr, int32 limit = 0);
|
||||
void HealGroup(uint32 heal_amt, Mob* caster, int32 range = 0);
|
||||
inline void SetGroupAAs(GroupLeadershipAA_Struct *From) { memcpy(&LeaderAbilities, From, sizeof(GroupLeadershipAA_Struct)); }
|
||||
inline void GetGroupAAs(GroupLeadershipAA_Struct *Into) { memcpy(Into, &LeaderAbilities, sizeof(GroupLeadershipAA_Struct)); }
|
||||
|
||||
24
zone/mob.cpp
24
zone/mob.cpp
@ -4277,6 +4277,9 @@ int16 Mob::GetMeleeDamageMod_SE(uint16 skill)
|
||||
dmg_mod += itembonuses.DamageModifier[HIGHEST_SKILL+1] + spellbonuses.DamageModifier[HIGHEST_SKILL+1] + aabonuses.DamageModifier[HIGHEST_SKILL+1] +
|
||||
itembonuses.DamageModifier[skill] + spellbonuses.DamageModifier[skill] + aabonuses.DamageModifier[skill];
|
||||
|
||||
dmg_mod += itembonuses.DamageModifier2[HIGHEST_SKILL+1] + spellbonuses.DamageModifier2[HIGHEST_SKILL+1] + aabonuses.DamageModifier2[HIGHEST_SKILL+1] +
|
||||
itembonuses.DamageModifier2[skill] + spellbonuses.DamageModifier2[skill] + aabonuses.DamageModifier2[skill];
|
||||
|
||||
if (HasShieldEquiped() && !IsOffHandAtk())
|
||||
dmg_mod += itembonuses.ShieldEquipDmgMod[0] + spellbonuses.ShieldEquipDmgMod[0] + aabonuses.ShieldEquipDmgMod[0];
|
||||
|
||||
@ -4334,22 +4337,19 @@ int16 Mob::GetSkillDmgAmt(uint16 skill)
|
||||
|
||||
void Mob::MeleeLifeTap(int32 damage) {
|
||||
|
||||
if(damage > 0 && (spellbonuses.MeleeLifetap || itembonuses.MeleeLifetap || aabonuses.MeleeLifetap ))
|
||||
{
|
||||
int lifetap_amt = spellbonuses.MeleeLifetap + itembonuses.MeleeLifetap + aabonuses.MeleeLifetap;
|
||||
|
||||
if(lifetap_amt > 100)
|
||||
lifetap_amt = 100;
|
||||
|
||||
else if (lifetap_amt < -99)
|
||||
lifetap_amt = -99;
|
||||
int16 lifetap_amt = 0;
|
||||
lifetap_amt = spellbonuses.MeleeLifetap + itembonuses.MeleeLifetap + aabonuses.MeleeLifetap
|
||||
+ spellbonuses.Vampirism + itembonuses.Vampirism + aabonuses.Vampirism;
|
||||
|
||||
if(lifetap_amt && damage > 0){
|
||||
|
||||
lifetap_amt = damage * lifetap_amt / 100;
|
||||
|
||||
mlog(COMBAT__DAMAGE, "Melee lifetap healing for %d damage.", damage);
|
||||
//heal self for damage done..
|
||||
HealDamage(lifetap_amt);
|
||||
|
||||
if (lifetap_amt > 0)
|
||||
HealDamage(lifetap_amt); //Heal self for modified damage amount.
|
||||
else
|
||||
Damage(this, -lifetap_amt,0, SkillEvocation,false); //Dmg self for modified damage amount.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -800,7 +800,7 @@ public:
|
||||
uint16 GetInstrumentMod(uint16 spell_id) const;
|
||||
int CalcSpellEffectValue(uint16 spell_id, int effect_id, int caster_level = 1, Mob *caster = nullptr, int ticsremaining = 0);
|
||||
int CalcSpellEffectValue_formula(int formula, int base, int max, int caster_level, uint16 spell_id, int ticsremaining = 0);
|
||||
virtual int CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2, int caster_level2, Mob* caster1 = nullptr, Mob* caster2 = nullptr);
|
||||
virtual int CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2, int caster_level2, Mob* caster1 = nullptr, Mob* caster2 = nullptr, int buffslot = -1);
|
||||
uint32 GetCastedSpellInvSlot() const { return casting_spell_inventory_slot; }
|
||||
|
||||
// HP Event
|
||||
|
||||
12
zone/npc.cpp
12
zone/npc.cpp
@ -599,19 +599,19 @@ bool NPC::Process()
|
||||
//Lieka Edit:Fixing NPC regen.NPCs should regen to full during a set duration, not based on their HPs.Increase NPC's HPs by % of total HPs / tick.
|
||||
if((GetHP() < GetMaxHP()) && !IsPet()) {
|
||||
if(!IsEngaged()) {//NPC out of combat
|
||||
if(hp_regen > OOCRegen)
|
||||
SetHP(GetHP() + hp_regen);
|
||||
if(GetNPCHPRegen() > OOCRegen)
|
||||
SetHP(GetHP() + GetNPCHPRegen());
|
||||
else
|
||||
SetHP(GetHP() + OOCRegen);
|
||||
} else
|
||||
SetHP(GetHP()+hp_regen);
|
||||
SetHP(GetHP()+GetNPCHPRegen());
|
||||
} else if(GetHP() < GetMaxHP() && GetOwnerID() !=0) {
|
||||
if(!IsEngaged()) //pet
|
||||
SetHP(GetHP()+hp_regen+bonus+(GetLevel()/5));
|
||||
SetHP(GetHP()+GetNPCHPRegen()+bonus+(GetLevel()/5));
|
||||
else
|
||||
SetHP(GetHP()+hp_regen+bonus);
|
||||
SetHP(GetHP()+GetNPCHPRegen()+bonus);
|
||||
} else
|
||||
SetHP(GetHP()+hp_regen);
|
||||
SetHP(GetHP()+GetNPCHPRegen());
|
||||
|
||||
if(GetMana() < GetMaxMana()) {
|
||||
SetMana(GetMana()+mana_regen+bonus);
|
||||
|
||||
@ -256,6 +256,7 @@ public:
|
||||
virtual void DoClassAttacks(Mob *target);
|
||||
void CheckSignal();
|
||||
inline bool IsTargetableWithHotkey() const { return no_target_hotkey; }
|
||||
int32 GetNPCHPRegen() const { return hp_regen + itembonuses.HPRegen + spellbonuses.HPRegen; }
|
||||
|
||||
//waypoint crap
|
||||
int GetMaxWp() const { return max_wp; }
|
||||
|
||||
@ -504,7 +504,7 @@ void Raid::HealGroup(uint32 heal_amt, Mob* caster, uint32 gid, int32 range)
|
||||
}
|
||||
|
||||
|
||||
void Raid::BalanceHP(int32 penalty, uint32 gid, int32 range, Mob* caster)
|
||||
void Raid::BalanceHP(int32 penalty, uint32 gid, int32 range, Mob* caster, int32 limit)
|
||||
{
|
||||
if (!caster)
|
||||
return;
|
||||
@ -512,7 +512,7 @@ void Raid::BalanceHP(int32 penalty, uint32 gid, int32 range, Mob* caster)
|
||||
if (!range)
|
||||
range = 200;
|
||||
|
||||
int dmgtaken = 0, numMem = 0;
|
||||
int dmgtaken = 0, numMem = 0, dmgtaken_tmp = 0;
|
||||
int gi = 0;
|
||||
|
||||
float distance;
|
||||
@ -525,7 +525,12 @@ void Raid::BalanceHP(int32 penalty, uint32 gid, int32 range, Mob* caster)
|
||||
{
|
||||
distance = caster->DistNoRoot(*members[gi].member);
|
||||
if(distance <= range2){
|
||||
dmgtaken += (members[gi].member->GetMaxHP() - members[gi].member->GetHP());
|
||||
|
||||
dmgtaken_tmp = members[gi].member->GetMaxHP() - members[gi].member->GetHP();
|
||||
if (limit && (dmgtaken_tmp > limit))
|
||||
dmgtaken_tmp = limit;
|
||||
|
||||
dmgtaken += (dmgtaken_tmp);
|
||||
numMem += 1;
|
||||
}
|
||||
}
|
||||
@ -555,7 +560,7 @@ void Raid::BalanceHP(int32 penalty, uint32 gid, int32 range, Mob* caster)
|
||||
}
|
||||
}
|
||||
|
||||
void Raid::BalanceMana(int32 penalty, uint32 gid, int32 range, Mob* caster)
|
||||
void Raid::BalanceMana(int32 penalty, uint32 gid, int32 range, Mob* caster, int32 limit)
|
||||
{
|
||||
if (!caster)
|
||||
return;
|
||||
@ -566,17 +571,24 @@ void Raid::BalanceMana(int32 penalty, uint32 gid, int32 range, Mob* caster)
|
||||
float distance;
|
||||
float range2 = range*range;
|
||||
|
||||
int manataken = 0, numMem = 0;
|
||||
int manataken = 0, numMem = 0, manataken_tmp = 0;
|
||||
int gi = 0;
|
||||
for(; gi < MAX_RAID_MEMBERS; gi++)
|
||||
{
|
||||
if(members[gi].member){
|
||||
if(members[gi].GroupNumber == gid)
|
||||
{
|
||||
distance = caster->DistNoRoot(*members[gi].member);
|
||||
if(distance <= range2){
|
||||
manataken += (members[gi].member->GetMaxMana() - members[gi].member->GetMana());
|
||||
numMem += 1;
|
||||
if (members[gi].member->GetMaxMana() > 0) {
|
||||
distance = caster->DistNoRoot(*members[gi].member);
|
||||
if(distance <= range2){
|
||||
|
||||
manataken_tmp = members[gi].member->GetMaxMana() - members[gi].member->GetMana();
|
||||
if (limit && (manataken_tmp > limit))
|
||||
manataken_tmp = limit;
|
||||
|
||||
manataken += (manataken_tmp);
|
||||
numMem += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -584,6 +596,7 @@ void Raid::BalanceMana(int32 penalty, uint32 gid, int32 range, Mob* caster)
|
||||
|
||||
manataken += manataken * penalty / 100;
|
||||
manataken /= numMem;
|
||||
|
||||
for(gi = 0; gi < MAX_RAID_MEMBERS; gi++)
|
||||
{
|
||||
if(members[gi].member){
|
||||
|
||||
@ -147,8 +147,8 @@ public:
|
||||
void CastGroupSpell(Mob* caster,uint16 spellid, uint32 gid);
|
||||
void SplitExp(uint32 exp, Mob* other);
|
||||
uint32 GetTotalRaidDamage(Mob* other);
|
||||
void BalanceHP(int32 penalty, uint32 gid, int32 range = 0, Mob* caster = nullptr);
|
||||
void BalanceMana(int32 penalty, uint32 gid, int32 range = 0, Mob* caster = nullptr);
|
||||
void BalanceHP(int32 penalty, uint32 gid, int32 range = 0, Mob* caster = nullptr, int32 limit = 0);
|
||||
void BalanceMana(int32 penalty, uint32 gid, int32 range = 0, Mob* caster = nullptr, int32 limit = 0);
|
||||
void HealGroup(uint32 heal_amt, Mob* caster, uint32 gid, int32 range = 0);
|
||||
void SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, Client *splitter = nullptr);
|
||||
void GroupBardPulse(Mob* caster, uint16 spellid, uint32 gid);
|
||||
|
||||
@ -2393,7 +2393,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
gid = r->GetGroup(caster->GetName());
|
||||
if(gid < 11)
|
||||
{
|
||||
r->BalanceHP(spell.base[i], gid, spell.range, caster);
|
||||
r->BalanceHP(spell.base[i], gid, spell.range, caster, spell.base2[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2403,7 +2403,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
if(!g)
|
||||
break;
|
||||
|
||||
g->BalanceHP(spell.base[i], spell.range, caster);
|
||||
g->BalanceHP(spell.base[i], spell.range, caster, spell.base2[i]);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2421,7 +2421,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
gid = r->GetGroup(caster->GetName());
|
||||
if(gid < 11)
|
||||
{
|
||||
r->BalanceMana(spell.base[i], gid, spell.range, caster);
|
||||
r->BalanceMana(spell.base[i], gid, spell.range, caster, spell.base2[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2431,7 +2431,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
if(!g)
|
||||
break;
|
||||
|
||||
g->BalanceMana(spell.base[i], spell.range, caster);
|
||||
g->BalanceMana(spell.base[i], spell.range, caster, spell.base2[i]);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2668,6 +2668,14 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
SlowMitigation(caster);
|
||||
break;
|
||||
|
||||
case SE_AddHatePct:
|
||||
{
|
||||
if (IsNPC())
|
||||
CastToNPC()->SetHate(caster, (CastToNPC()->GetHateAmount(caster) * (100 + spell.base[i]) / 100));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Handled Elsewhere
|
||||
case SE_ImmuneFleeing:
|
||||
case SE_NegateSpellEffect:
|
||||
@ -2886,6 +2894,14 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
case SE_LimitCastTimeMax:
|
||||
case SE_TriggerOnReqCaster:
|
||||
case SE_FrenziedDevastation:
|
||||
case SE_AStacker:
|
||||
case SE_BStacker:
|
||||
case SE_CStacker:
|
||||
case SE_DStacker:
|
||||
case SE_DoubleRiposte:
|
||||
case SE_Berserk:
|
||||
case SE_Vampirism:
|
||||
case SE_Metabolism:
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -3518,6 +3534,14 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste
|
||||
}
|
||||
}
|
||||
|
||||
case SE_AddHateOverTimePct:
|
||||
{
|
||||
if (IsNPC())
|
||||
CastToNPC()->SetHate(caster, (CastToNPC()->GetHateAmount(caster) * (100 + spell.base[i]) / 100));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
// do we need to do anyting here?
|
||||
|
||||
@ -2542,7 +2542,7 @@ int CalcBuffDuration_formula(int level, int formula, int duration)
|
||||
// -1 if they can't stack and spellid2 should be stopped
|
||||
//currently, a spell will not land if it would overwrite a better spell on any effect
|
||||
//if all effects are better or the same, we overwrite, else we do nothing
|
||||
int Mob::CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2, int caster_level2, Mob* caster1, Mob* caster2)
|
||||
int Mob::CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2, int caster_level2, Mob* caster1, Mob* caster2, int buffslot)
|
||||
{
|
||||
const SPDat_Spell_Struct &sp1 = spells[spellid1];
|
||||
const SPDat_Spell_Struct &sp2 = spells[spellid2];
|
||||
@ -2621,6 +2621,24 @@ int Mob::CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2,
|
||||
}
|
||||
}
|
||||
|
||||
/*Buff stacking prevention spell effects (446 - 449) works as follows... If B prevent A, if C prevent B, if D prevent C.
|
||||
Special check is added to make sure the buffs stack properly when applied from fade on duration effect, since the buff
|
||||
is not fully removed at the time of the trgger*/
|
||||
if (spellbonuses.BStacker) {
|
||||
if ((effect2 == SE_AStacker) && (!IsCastonFadeDurationSpell(spellid1) && buffs[buffslot].ticsremaining != 1 && IsEffectInSpell(spellid1, SE_BStacker)))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (spellbonuses.CStacker) {
|
||||
if ((effect2 == SE_BStacker) && (!IsCastonFadeDurationSpell(spellid1) && buffs[buffslot].ticsremaining != 1 && IsEffectInSpell(spellid1, SE_CStacker)))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (spellbonuses.DStacker) {
|
||||
if ((effect2 == SE_CStacker) && (!IsCastonFadeDurationSpell(spellid1) && buffs[buffslot].ticsremaining != 1 && IsEffectInSpell(spellid1, SE_DStacker)))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(effect2 == SE_StackingCommand_Overwrite)
|
||||
{
|
||||
overwrite_effect = sp2.base[i];
|
||||
@ -2901,7 +2919,7 @@ int Mob::AddBuff(Mob *caster, uint16 spell_id, int duration, int32 level_overrid
|
||||
if (curbuf.spellid != SPELL_UNKNOWN) {
|
||||
// there's a buff in this slot
|
||||
ret = CheckStackConflict(curbuf.spellid, curbuf.casterlevel, spell_id,
|
||||
caster_level, entity_list.GetMobID(curbuf.casterid), caster);
|
||||
caster_level, entity_list.GetMobID(curbuf.casterid), caster, buffslot);
|
||||
if (ret == -1) { // stop the spell
|
||||
mlog(SPELLS__BUFFS, "Adding buff %d failed: stacking prevented by spell %d in slot %d with caster level %d",
|
||||
spell_id, curbuf.spellid, buffslot, curbuf.casterlevel);
|
||||
@ -3047,7 +3065,7 @@ int Mob::CanBuffStack(uint16 spellid, uint8 caster_level, bool iFailIfOverwrite)
|
||||
return(-1); //do not recast a buff we already have on, we recast fast enough that we dont need to refresh our buffs
|
||||
|
||||
// there's a buff in this slot
|
||||
ret = CheckStackConflict(curbuf.spellid, curbuf.casterlevel, spellid, caster_level);
|
||||
ret = CheckStackConflict(curbuf.spellid, curbuf.casterlevel, spellid, caster_level, nullptr, nullptr, i);
|
||||
if(ret == 1) {
|
||||
// should overwrite current slot
|
||||
if(iFailIfOverwrite) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user