Kayen: Implemented SE_ArcheryDoubleAttack (Chance to do an extra archery attack)

Kayen: Implemented SE_ShieldEquipDmgMod (Increase damage in primary hand if shield equiped)
Kayen: Implemented SE_ShieldEquipHateMod (Increase hate generated if shield equiped)
Kayen: Implemented SE_TriggerOnAmountValue (Trigger spell if HP/Mana/End bellow X value or num pet on target)
This commit is contained in:
KayenEQ 2013-12-17 21:51:13 -05:00
parent 8007097aae
commit bfb17a2fb5
13 changed files with 216 additions and 21 deletions

View File

@ -1,5 +1,11 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 12/16/2013 ==
Kayen: Implemented SE_ArcheryDoubleAttack (Chance to do an extra archery attack)
Kayen: Implemented SE_ShieldEquipDmgMod (Increase damage in primary hand if shield equiped)
Kayen: Implemented SE_ShieldEquipHateMod (Increase hate generated if shield equiped)
Kayen: Implemented SE_TriggerOnAmountValue (Trigger spell if HP/Mana/End bellow X value or num pet on target)
== 12/16/2013 ==
Kayen: Fix to SE_BlockNextSpellFocus to make it functional again.

View File

@ -448,7 +448,7 @@ typedef enum {
#define SE_ArcheryDamageModifier 301 // implemented[AA] - increase archery damage by percent
#define SE_ImprovedDamage2 302 // implemented - spell damage focus
#define SE_FF_Damage_Amount 303 // implemented - adds direct spell damage
#define SE_OffhandRiposteFail 304 // not implemented as bonus - enemy cannot riposte offhand attacks
#define SE_OffhandRiposteFail 304 // implemented as bonus - enemy cannot riposte offhand attacks
#define SE_MitigateDamageShield 305 // implemented - off hand attacks only (Shielding Resistance)
#define SE_ArmyOfTheDead 306 // *not implemented NecroAA - This ability calls up to five shades of nearby corpses back to life to serve the necromancer. The soulless abominations will mindlessly fight the target until called back to the afterlife some time later. The first rank summons up to three shades that serve for 60 seconds, and each additional rank adds one more possible shade and increases their duration by 15 seconds
#define SE_Appraisal 307 // *not implemented Rogue AA - This ability allows you to estimate the selling price of an item you are holding on your cursor.
@ -491,9 +491,9 @@ typedef enum {
#define SE_ChannelChanceItems 344 // implemented[AA] - chance to not have ITEM effects interrupted when you take damage.
#define SE_AssassinationLevel 345 // not implemented as bonus - AA Assisination max level to kill
#define SE_HeadShotLevel 346 // not implemented as bonus - AA HeadShot max level to kill
#define SE_ExtraArcheryAttack 347 // not implemented - chance at an additional archery attack (consumes arrow)
#define SE_ArcheryDoubleAttack 347 // implemented - chance at an additional archery attack (consumes arrow)
#define SE_LimitManaCost 348 // implemented
#define SE_ShieldEquipHateMod 349 // *not implemented[AA] ie. used to increase melee hate when wearing a shield w/ Shield Specialist AA.
#define SE_ShieldEquipHateMod 349 // implemented[AA] Increase melee hate when wearing a shield.
#define SE_ManaBurn 350 // implemented - Drains mana for damage/heal at a defined ratio up to a defined maximum amount of mana.
#define SE_PersistentEffect 351 // *not implemented. creates a trap/totem that casts a spell (spell id + base1?) when anything comes near it. can probably make a beacon for this
#define SE_Unknown352 352 // *not implemented - looks to be some type of invulnerability? Test ITC (8755)
@ -510,7 +510,7 @@ typedef enum {
#define SE_BandolierSlots 363 // *not implemented[AA] 'Battle Ready' expands the bandolier by one additional save slot per rank.
#define SE_TripleAttackChance 364 // implemented
#define SE_SpellOnKill2 365 // implemented - chance to trigger a spell on kill when the kill is caused by a specific spell with this effect in it (10470 Venin)
#define SE_ShieldEquipDmgMod 366 // *not implemented - [AA Shield Specialist] - damage bonus to weapon if shield equiped.
#define SE_ShieldEquipDmgMod 366 // implemented[AA] Damage modifier to melee if shield equiped. (base1 = dmg mod , base2 = ?) ie Shield Specialist AA
#define SE_SetBodyType 367 // implemented - set body type of base1 so it can be affected by spells that are limited to that type (Plant, Animal, Undead, etc)
#define SE_FactionMod 368 // *not implemented - increases faction with base1 (faction id, live won't match up w/ ours) by base2
#define SE_CorruptionCounter 369 // implemented
@ -586,7 +586,7 @@ typedef enum {
#define SE_IncreaseAssassinationLvl 439 // *not implemented[AA] - increases the maximum level of humanoid that can be affected by assassination
#define SE_FinishingBlowLvl 440 // implemented[AA] - Sets the level Finishing blow can be triggered on an NPC
#define SE_CancleIfMoved 441 // *not implemented - Buff is removed from target when target moves X amount of distance away from where initially hit.
#define SE_TriggerOnHPAmount 442 // *not implemented - triggers a spell which a certain hp level is reached
#define SE_TriggerOnValueAmount 442 // implemented - triggers a spell which a certain criteria are met (below X amount of hp,mana,end, number of pets on hatelist)
#define SE_TriggerIfMovement 443 // *not implemented - Trigger a spell if you move (37846 | Chopping Block)
#define SE_AggroLock 444 // *not implemented - Locks Aggro On Caster and Decrease other Players Aggro by X% up to level Z
#define SE_AdditionalMercenary 445 // *not implemented[AA] - [Hero's Barracks] Allows you to conscript additional mercs.

View File

@ -444,19 +444,20 @@ bool Mob::AvoidDamage(Mob* other, int32 &damage, bool CanRiposte)
RollTable[1] = RollTable[0];
}
if(damage > 0 && (aabonuses.ShieldBlock || spellbonuses.ShieldBlock || itembonuses.ShieldBlock)
if(damage > 0 && HasShieldEquiped() && (aabonuses.ShieldBlock || spellbonuses.ShieldBlock || itembonuses.ShieldBlock)
&& (!other->BehindMob(this, other->GetX(), other->GetY()) || bShieldBlockFromRear)) {
/*
bool equiped = CastToClient()->m_inv.GetItem(14);
if(equiped) {
uint8 shield = CastToClient()->m_inv.GetItem(14)->GetItem()->ItemType;
float bonusShieldBlock = 0.0f;
if(shield == ItemTypeShield) {
//Live AA - Shield Block
bonusShieldBlock = aabonuses.ShieldBlock + spellbonuses.ShieldBlock + itembonuses.ShieldBlock;
RollTable[1] += bonusShieldBlock;
}
}
*/
float bonusShieldBlock = 0.0f;
bonusShieldBlock = aabonuses.ShieldBlock + spellbonuses.ShieldBlock + itembonuses.ShieldBlock;
RollTable[1] += bonusShieldBlock;
}
if(damage > 0 && (aabonuses.TwoHandBluntBlock || spellbonuses.TwoHandBluntBlock || itembonuses.TwoHandBluntBlock)
@ -1141,7 +1142,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
}
else{
weapon = GetInv().GetItem(SLOT_PRIMARY);
OffHandAtk(false);
OffHandAtk(false);
}
if(weapon != nullptr) {
@ -2432,6 +2433,12 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp,
if(other){
AddRampage(other);
int hatemod = 100 + other->spellbonuses.hatemod + other->itembonuses.hatemod + other->aabonuses.hatemod;
int16 shieldhatemod = other->spellbonuses.ShieldEquipHateMod + other->itembonuses.ShieldEquipHateMod + other->aabonuses.ShieldEquipHateMod;
if (shieldhatemod && other->HasShieldEquiped())
hatemod += shieldhatemod;
if(hatemod < 1)
hatemod = 1;
hate = ((hate * (hatemod))/100);
@ -2446,6 +2453,9 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp,
return;
}
if (other->IsNPC() && (other->IsPet() || other->CastToNPC()->GetSwarmOwner() > 0))
TryTriggerOnValueAmount(false, false, false, true);
if(IsClient() && !IsAIControlled())
return;
@ -3223,6 +3233,7 @@ int32 Mob::ReduceDamage(int32 damage)
if(GetMana() > damage * spellbonuses.ManaAbsorbPercentDamage[0] / 100) {
damage -= (damage * spellbonuses.ManaAbsorbPercentDamage[0] / 100);
SetMana(GetMana() - damage);
TryTriggerOnValueAmount(false, true);
CheckHitsRemaining(slot);
}
}
@ -3298,6 +3309,7 @@ int32 Mob::AffectMagicalDamage(int32 damage, uint16 spell_id, const bool iBuffTi
if(GetMana() > damage * spellbonuses.ManaAbsorbPercentDamage[0] / 100) {
damage -= (damage * spellbonuses.ManaAbsorbPercentDamage[0] / 100);
SetMana(GetMana() - damage);
TryTriggerOnValueAmount(false, true);
CheckHitsRemaining(slot);
}
}
@ -3374,6 +3386,16 @@ bool Client::CheckDoubleAttack(bool tripleAttack) {
return false;
}
bool Client::CheckArcheryDoubleAttack() {
int16 chance = spellbonuses.ArcheryDoubleAttack + itembonuses.ArcheryDoubleAttack + aabonuses.ArcheryDoubleAttack;
if(chance && (MakeRandomInt(0, 100) < chance))
return true;
return false;
}
void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, const SkillUseTypes skill_used, bool &avoidable, const int8 buffslot, const bool iBuffTic) {
// This method is called with skill_used=ABJURE for Damage Shield damage.
bool FromDamageShield = (skill_used == SkillAbjuration);
@ -3481,7 +3503,7 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
ReduceAllDamage(damage);
SetHP(GetHP() - damage);
if(HasDied()) {
bool IsSaved = false;
@ -3501,6 +3523,8 @@ void Mob::CommonDamage(Mob* attacker, int32 &damage, const uint16 spell_id, cons
TryDeathSave();
}
TryTriggerOnValueAmount(true);
//fade mez if we are mezzed
if (IsMezzed()) {
mlog(COMBAT__HITS, "Breaking mez due to attack.");

View File

@ -135,6 +135,7 @@ void Client::CalcItemBonuses(StatBonuses* newbon) {
// Clear item faction mods
ClearItemFactionBonuses();
ShieldEquiped(false);
unsigned int i;
//should not include 21 (SLOT_AMMO)
@ -143,6 +144,10 @@ void Client::CalcItemBonuses(StatBonuses* newbon) {
if(inst == 0)
continue;
AddItemBonuses(inst, newbon);
//Check if item is secondary slot is a 'shield'. Required for multiple spelll effects.
if (i == 14 && (m_inv.GetItem(14)->GetItem()->ItemType == ItemTypeShield))
ShieldEquiped(true);
}
//Power Source Slot
@ -846,6 +851,9 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
case SE_ArcheryDamageModifier:
newbon->ArcheryDamageModifier += base1;
break;
case SE_ArcheryDoubleAttack:
newbon->ArcheryDoubleAttack += base1;
break;
case SE_DamageShield:
newbon->DamageShield += base1;
break;
@ -905,6 +913,13 @@ void Client::ApplyAABonuses(uint32 aaid, uint32 slots, StatBonuses* newbon)
case SE_ShieldBlock:
newbon->ShieldBlock += base1;
break;
case SE_ShieldEquipHateMod:
newbon->ShieldEquipHateMod += base1;
break;
case SE_ShieldEquipDmgMod:
newbon->ShieldEquipDmgMod[0] += base1;
newbon->ShieldEquipDmgMod[1] += base2;
break;
case SE_SecondaryDmgInc:
newbon->SecondaryDmgInc = true;
break;
@ -2196,6 +2211,15 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_ShieldBlock:
newbon->ShieldBlock += effect_value;
break;
case SE_ShieldEquipHateMod:
newbon->ShieldEquipHateMod += effect_value;
break;
case SE_ShieldEquipDmgMod:
newbon->ShieldEquipDmgMod[0] += effect_value;
newbon->ShieldEquipDmgMod[1] += spells[spell_id].base2[i];
break;
case SE_BlockBehind:
newbon->BlockBehind += effect_value;
@ -2258,6 +2282,10 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
newbon->ArcheryDamageModifier += effect_value;
break;
case SE_ArcheryDoubleAttack:
newbon->ArcheryDoubleAttack += effect_value;
break;
case SE_SecondaryDmgInc:
newbon->SecondaryDmgInc = true;
break;
@ -2391,6 +2419,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
break;
}
case SE_TriggerOnValueAmount:
newbon->TriggerOnValueAmount = true;
break;
}
}
@ -3659,7 +3690,27 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
aabonuses.SlayUndead[0] = effect_value;
aabonuses.SlayUndead[1] = effect_value;
break;
case SE_ArcheryDoubleAttack:
spellbonuses.ArcheryDoubleAttack = effect_value;
aabonuses.ArcheryDoubleAttack = effect_value;
itembonuses.ArcheryDoubleAttack = effect_value;
break;
case SE_ShieldEquipHateMod:
spellbonuses.ShieldEquipHateMod = effect_value;
aabonuses.ShieldEquipHateMod = effect_value;
itembonuses.ShieldEquipHateMod = effect_value;
break;
case SE_ShieldEquipDmgMod:
spellbonuses.ShieldEquipDmgMod[0] = effect_value;
spellbonuses.ShieldEquipDmgMod[1] = effect_value;
aabonuses.ShieldEquipDmgMod[0] = effect_value;
aabonuses.ShieldEquipDmgMod[1] = effect_value;
itembonuses.ShieldEquipDmgMod[0] = effect_value;
itembonuses.ShieldEquipDmgMod[1] = effect_value;
break;
}
}
}

View File

@ -819,6 +819,7 @@ public:
void LinkDead();
void Insight(uint32 t_id);
bool CheckDoubleAttack(bool tripleAttack = false);
bool CheckArcheryDoubleAttack();
//remove charges/multiple objects from inventory:
//bool DecreaseByType(uint32 type, uint8 amt);
@ -828,7 +829,7 @@ public:
void RemoveNoRent(bool client_update = true);
void RemoveDuplicateLore(bool client_update = true);
void MoveSlotNotAllowed(bool client_update = true);
virtual void RangedAttack(Mob* other);
virtual void RangedAttack(Mob* other, bool CanDoubleAttack = false);
virtual void ThrowingAttack(Mob* other);
void DoClassAttacks(Mob *ca_target, uint16 skill = -1, bool IsRiposte=false);

View File

@ -303,6 +303,8 @@ bool Client::Process() {
if(CheckLosFN(GetTarget())){
//client has built in los check, but auto fire does not.. done last.
RangedAttack(GetTarget());
if (CheckArcheryDoubleAttack())
RangedAttack(GetTarget(), true);
}
else
ranged_timer.Start();
@ -1931,8 +1933,10 @@ void Client::DoEnduranceUpkeep() {
}
}
if(upkeep_sum != 0)
if(upkeep_sum != 0){
SetEndurance(GetEndurance() - upkeep_sum);
TryTriggerOnValueAmount(false, false, true);
}
}
void Client::CalcRestState() {

View File

@ -250,6 +250,7 @@ struct StatBonuses {
int16 DualWieldChance; //i
int16 DoubleAttackChance; //i
int16 TripleAttackChance; //i
int16 ArcheryDoubleAttack; //i
int16 ResistSpellChance; //i
int16 ResistFearChance; //i
bool Fearless; //i
@ -359,6 +360,9 @@ struct StatBonuses {
int16 ItemATKCap; // Raise item attack cap
int32 FinishingBlow[2]; // Chance to do a finishing blow for specified damage amount.
uint16 FinishingBlowLvl[2]; // Sets max level an NPC can be affected by FB. (base1 = lv, base2= ???)
int16 ShieldEquipHateMod; // Hate mod when shield equiped.
int16 ShieldEquipDmgMod[2]; // Damage mod when shield equiped. 0 = damage modifier 1 = Unknown
bool TriggerOnValueAmount; // Triggers off various different conditions, bool to check if client has effect.
};
typedef struct

View File

@ -612,6 +612,7 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
if(GetEndurance() > spell.EndurCost) {
SetEndurance(GetEndurance() - spell.EndurCost);
TryTriggerOnValueAmount(false, false, true);
} else {
Message(11, "You are too fatigued to use this skill right now.");
return(false);

View File

@ -177,6 +177,7 @@ Mob::Mob(const char* in_name,
slow_mitigation= 0;
findable = false;
trackable = true;
has_shieldequiped = false;
if(in_aa_title>0)
aa_title = in_aa_title;
@ -3223,6 +3224,80 @@ void Mob::TryApplyEffect(Mob *target, uint32 spell_id)
}
}
}
void Mob::TryTriggerOnValueAmount(bool IsHP, bool IsMana, bool IsEndur, bool IsPet)
{
/*
Base2 Range: 500-520 = Below (base2 - 500)*5 HP
Base2 Range: 521 = Below (?) Mana UKNOWN - Will assume its 20% unless proven otherwise
Base2 Range: 522 = Below (40%) Endurance
Base2 Range: 523 = Below (40%) Mana
Base2 Range: 220-? = Number of pets on hatelist to trigger (base2 - 220) (Set at 30 pets max for now)
*/
if (!spellbonuses.TriggerOnValueAmount)
return;
if (spellbonuses.TriggerOnValueAmount){
int buff_count = GetMaxTotalSlots();
for(int e = 0; e < buff_count; e++){
uint32 spell_id = buffs[e].spellid;
if (IsValidSpell(spell_id)){
for(int i = 0; i < EFFECT_COUNT; i++){
if (spells[spell_id].effectid[i] == SE_TriggerOnValueAmount){
int base2 = spells[spell_id].base2[i];
bool use_spell = false;
if (IsHP){
if ((base2 >= 500 && base2 <= 520) && GetHPRatio() < (base2 - 500)*5){
use_spell = true;
}
}
else if (IsMana){
if ( (base2 = 521 && GetManaRatio() < 20) || (base2 = 523 && GetManaRatio() < 40)) {
use_spell = true;
}
}
else if (IsEndur){
if (base2 = 522 && GetEndurancePercent() < 40){
use_spell = true;
}
}
else if (IsPet){
int count = hate_list.SummonedPetCount(this);
if ((base2 >= 220 && base2 <= 250) && count >= (base2 - 220)){
use_spell = true;
}
}
if (use_spell){
SpellFinished(spells[spell_id].base[i], this, 10, 0, -1, spells[spell_id].ResistDiff);
/*Note, spell data shows numhits values of 0 or 1, however many descriptions of these spells indicate they should
be fading when consumed even with numhits of 0 (It makes sense they should fade...).
Unless proven otherwise, they should fade when triggered. */
if(!TryFadeEffect(e))
BuffFadeBySlot(e);
}
}
}
}
}
}
}
//Twincast Focus effects should stack across different types (Spell, AA - when implemented ect)
void Mob::TryTwincast(Mob *caster, Mob *target, uint32 spell_id)
{
@ -4200,6 +4275,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];
if (HasShieldEquiped() && !IsOffHandAtk())
dmg_mod += itembonuses.ShieldEquipDmgMod[0] + spellbonuses.ShieldEquipDmgMod[0] + aabonuses.ShieldEquipDmgMod[0];
if(dmg_mod < -100)
dmg_mod = -100;

View File

@ -259,6 +259,8 @@ public:
void TempName(const char *newname = nullptr);
void SetTargetable(bool on);
bool IsTargetable() const { return m_targetable; }
bool HasShieldEquiped() const { return has_shieldequiped; }
inline void ShieldEquiped(bool val) { has_shieldequiped = val; }
virtual uint16 GetSkill(SkillUseTypes skill_num) const { return 0; }
virtual uint32 GetEquipment(uint8 material_slot) const { return(0); }
virtual int32 GetEquipmentMaterial(uint8 material_slot) const;
@ -531,6 +533,7 @@ public:
void TriggerOnCast(uint32 focus_spell, uint32 spell_id, bool aa_trigger);
void TrySpellTrigger(Mob *target, uint32 spell_id);
void TryApplyEffect(Mob *target, uint32 spell_id);
void TryTriggerOnValueAmount(bool IsHP = false, bool IsMana = false, bool IsEndur = false, bool IsPet = false);
void TryTwincast(Mob *caster, Mob *target, uint32 spell_id);
void TrySympatheticProc(Mob *target, uint32 spell_id);
bool TryFadeEffect(int slot);
@ -1044,6 +1047,7 @@ protected:
uint16 viral_spells[MAX_SPELL_TRIGGER*2]; // Stores the spell ids of the viruses on target and caster ids
int16 rooted_mod; //Modifier to root break chance, defined when root is cast on a target.
bool offhand;
bool has_shieldequiped;
// Bind wound
Timer bindwound_timer;

View File

@ -203,6 +203,9 @@ void Client::OPCombatAbility(const EQApplicationPacket *app) {
if (ca_atk->m_skill == SkillArchery) {
SetAttackTimer();
RangedAttack(GetTarget());
bool test = CheckArcheryDoubleAttack();
if (CheckArcheryDoubleAttack())
RangedAttack(GetTarget(), true);
return;
}
//could we return here? Im not sure is m_atk 11 is used for real specials
@ -682,12 +685,12 @@ void Mob::RogueAssassinate(Mob* other)
DoAnim(animPiercing); //piercing animation
}
void Client::RangedAttack(Mob* other) {
void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
//conditions to use an attack checked before we are called
//make sure the attack and ranged timers are up
//if the ranged timer is disabled, then they have no ranged weapon and shouldent be attacking anyhow
if((attack_timer.Enabled() && !attack_timer.Check(false)) || (ranged_timer.Enabled() && !ranged_timer.Check())) {
if(!CanDoubleAttack && ((attack_timer.Enabled() && !attack_timer.Check(false)) || (ranged_timer.Enabled() && !ranged_timer.Check()))) {
mlog(COMBAT__RANGED, "Throwing attack canceled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime());
// The server and client timers are not exact matches currently, so this would spam too often if enabled
//Message(0, "Error: Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime());

View File

@ -180,6 +180,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
if (caster && caster->IsClient())
numhit += caster->CastToClient()->GetFocusEffect(focusIncreaseNumHits, spell_id);
buffs[buffslot].numhits = numhit;
}
@ -467,6 +468,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
#endif
SetMana(GetMana() + effect_value);
caster->SetMana(caster->GetMana() + abs(effect_value));
if (effect_value < 0)
TryTriggerOnValueAmount(false, true);
#ifdef SPELL_EFFECT_SPAM
caster->Message(0, "You have gained %+i mana!", effect_value);
#endif
@ -480,6 +484,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
break;
SetMana(GetMana() + effect_value);
if (effect_value < 0)
TryTriggerOnValueAmount(false, true);
}
break;
@ -2366,6 +2372,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
#endif
if(IsClient()) {
CastToClient()->SetEndurance(CastToClient()->GetEndurance() + effect_value);
if (effect_value < 0)
TryTriggerOnValueAmount(false, false, true);
}
break;
}
@ -2378,6 +2386,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
if(IsClient()) {
CastToClient()->SetEndurance(CastToClient()->GetEndurance() + effect_value);
if (effect_value < 0)
TryTriggerOnValueAmount(false, false, true);
}
break;
}
@ -2549,7 +2559,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
int mana_damage = 0;
int32 mana_to_use = GetMana() - spell.base[i];
if(mana_to_use > -1) {
SetMana(GetMana() - spell.base[i]);
SetMana(GetMana() - spell.base[i]);
TryTriggerOnValueAmount(false, true);
// we take full dmg(-10 to make the damage the right sign)
mana_damage = spell.base[i] / -10 * spell.base2[i];
Damage(caster, mana_damage, spell_id, spell.skill, false, i, true);
@ -2569,6 +2580,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
int32 end_to_use = CastToClient()->GetEndurance() - spell.base[i];
if(end_to_use > -1) {
CastToClient()->SetEndurance(CastToClient()->GetEndurance() - spell.base[i]);
TryTriggerOnValueAmount(false, false, true);
// we take full dmg(-10 to make the damage the right sign)
end_damage = spell.base[i] / -10 * spell.base2[i];
Damage(caster, end_damage, spell_id, spell.skill, false, i, true);
@ -2650,6 +2662,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
else {
dmg = ratio*max_mana/10;
caster->SetMana(caster->GetMana() - max_mana);
TryTriggerOnValueAmount(false, true);
}
if(IsDetrimentalSpell(spell_id)) {
@ -2896,6 +2909,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
case SE_CastonFocusEffect:
case SE_ReduceHeal:
case SE_IncreaseHitDmgTaken:
case SE_ArcheryDoubleAttack:
case SE_ShieldEquipHateMod:
case SE_ShieldEquipDmgMod:
case SE_TriggerOnValueAmount:
{
break;
}
@ -3772,7 +3789,7 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
SetBodyType(GetOrigBodyType(), false);
break;
}
case SE_MovementSpeed:
{
if(IsClient())
@ -5206,7 +5223,7 @@ bool Mob::CheckHitsRemaining(uint32 buff_slot, bool when_spell_done, bool negate
}
return false;
}
// For spell buffs that are limited by the number of times it can successfully trigger a spell.
// Effects: SE_TriggerOnCast, SE_SympatheticProc,SE_DefensiveProc, SE_SkillProc, SE_RangedProc
if(spell_id){

View File

@ -235,6 +235,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
// fizzle 1/4 the mana away
SetMana(GetMana() - use_mana);
TryTriggerOnValueAmount(false, true);
return(false);
}
@ -2069,6 +2070,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
mlog(SPELLS__CASTING, "Spell %d: consuming %d mana", spell_id, mana_used);
if (!DoHPToManaCovert(mana_used))
SetMana(GetMana() - mana_used);
TryTriggerOnValueAmount(false, true);
}
//set our reuse timer on long ass reuse_time spells...