mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-13 02:38:45 +00:00
Implemented SE_HealthTransfer 509
Implemented SE_Health_Transfer 509 'life burn' Consume base2 % of Hit Points to Damage for base % of Hit Points Can be used for heal Act of Valor
This commit is contained in:
+8
-6
@@ -62,6 +62,8 @@
|
|||||||
#define SPELL_SHAPECHANGE60 1924
|
#define SPELL_SHAPECHANGE60 1924
|
||||||
#define SPELL_COMMAND_OF_DRUZZIL 3355
|
#define SPELL_COMMAND_OF_DRUZZIL 3355
|
||||||
#define SPELL_SHAPECHANGE70 6503
|
#define SPELL_SHAPECHANGE70 6503
|
||||||
|
#define SPELL_MANA_BURN 2751
|
||||||
|
#define SPELL_LIFE_BURN 2755
|
||||||
// these have known hardcoded behavior but we don't do anything yet, move them above this comment when fixed
|
// these have known hardcoded behavior but we don't do anything yet, move them above this comment when fixed
|
||||||
#define SPELL_THE_DAINS_JUSTICE 1476
|
#define SPELL_THE_DAINS_JUSTICE 1476
|
||||||
#define SPELL_MODULATION 1502
|
#define SPELL_MODULATION 1502
|
||||||
@@ -152,7 +154,7 @@
|
|||||||
#define SPELL_RESURRECTION_SICKNESS 756
|
#define SPELL_RESURRECTION_SICKNESS 756
|
||||||
#define SPELL_RESURRECTION_SICKNESS2 5249
|
#define SPELL_RESURRECTION_SICKNESS2 5249
|
||||||
#define SPELL_REVIVAL_SICKNESS 13087
|
#define SPELL_REVIVAL_SICKNESS 13087
|
||||||
#define SPELL_MANA_BURN 2751
|
|
||||||
|
|
||||||
|
|
||||||
#define EFFECT_COUNT 12
|
#define EFFECT_COUNT 12
|
||||||
@@ -849,16 +851,16 @@ typedef enum {
|
|||||||
//#define SE_Damage_Taken_Position_Amt 506 //
|
//#define SE_Damage_Taken_Position_Amt 506 //
|
||||||
//#define SE_Fc_Amplify_Mod 507 //
|
//#define SE_Fc_Amplify_Mod 507 //
|
||||||
//#define SE_Fc_Amplify_Amt 508 //
|
//#define SE_Fc_Amplify_Amt 508 //
|
||||||
//#define SE_Health_Transfer 509 //
|
#define SE_Health_Transfer 509 //
|
||||||
//#define SE_Fc_ResistIncoming 510 //
|
//#define SE_Fc_ResistIncoming 510 //
|
||||||
//#define SE_Ff_FocusTimerMin 511 //
|
//#define SE_Ff_FocusTimerMin 511 //
|
||||||
//#define SE_Proc_Timer_Modifier 512 //
|
//#define SE_Proc_Timer_Modifier 512 //
|
||||||
//#define SE_Mana_Max_Percent 513 //
|
//#define SE_Mana_Max_Percent 513 //
|
||||||
//#define SE_Endurance_Max_Percent 514 //
|
//#define SE_Endurance_Max_Percent 514 //
|
||||||
//#define SE_AC_Avoidance_Max_Percent 515 //
|
//#define SE_AC_Avoidance_Max_Percent 515 // 515 is before 172 TotalEffect(515) * static_cast<double>(avoidance_ac) * 0.0001 that value is then rounded with a +/- 0.5
|
||||||
//#define SE_AC_Mitigation_Max_Percent 516 //
|
//#define SE_AC_Mitigation_Max_Percent 516 // 516 is after AGI bonus
|
||||||
//#define SE_Attack_Offense_Max_Percent 517 //
|
//#define SE_Attack_Offense_Max_Percent 517 // Requires too much rewrite of code.
|
||||||
//#define SE_Attack_Accuracy_Max_Percent 518 //
|
#define SE_Attack_Accuracy_Max_Percent 518 //
|
||||||
//#define SE_Luck_Amount 519 //
|
//#define SE_Luck_Amount 519 //
|
||||||
//#define SE_Luck_Percent 520 //
|
//#define SE_Luck_Percent 520 //
|
||||||
#define SE_Endurance_Absorb_Pct_Damage 521 //
|
#define SE_Endurance_Absorb_Pct_Damage 521 //
|
||||||
|
|||||||
+7
-2
@@ -188,6 +188,11 @@ int Mob::GetTotalToHit(EQ::skills::SkillType skill, int chance_mod)
|
|||||||
if (skill != EQ::skills::SkillArchery && skill != EQ::skills::SkillThrowing)
|
if (skill != EQ::skills::SkillArchery && skill != EQ::skills::SkillThrowing)
|
||||||
accuracy += itembonuses.HitChance;
|
accuracy += itembonuses.HitChance;
|
||||||
|
|
||||||
|
//518 Increase ATK accuracy by percentage, stackable
|
||||||
|
auto atkhit_bonus = itembonuses.Attack_Accuracy_Max_Percent + aabonuses.Attack_Accuracy_Max_Percent + spellbonuses.Attack_Accuracy_Max_Percent;
|
||||||
|
|
||||||
|
accuracy += (accuracy * atkhit_bonus) / 10000;
|
||||||
|
|
||||||
// 216 Melee Accuracy Amt aka SE_Accuracy -- flat bonus
|
// 216 Melee Accuracy Amt aka SE_Accuracy -- flat bonus
|
||||||
accuracy += itembonuses.Accuracy[EQ::skills::HIGHEST_SKILL + 1] +
|
accuracy += itembonuses.Accuracy[EQ::skills::HIGHEST_SKILL + 1] +
|
||||||
aabonuses.Accuracy[EQ::skills::HIGHEST_SKILL + 1] +
|
aabonuses.Accuracy[EQ::skills::HIGHEST_SKILL + 1] +
|
||||||
@@ -3333,8 +3338,8 @@ int32 Mob::ReduceAllDamage(int32 damage)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (spellbonuses.EnduranceAbsorbPercentDamage[0]) {
|
if (spellbonuses.EnduranceAbsorbPercentDamage[0]) {
|
||||||
int32 damage_reduced = damage * spellbonuses.EnduranceAbsorbPercentDamage[0] / 10000;
|
int32 damage_reduced = damage * spellbonuses.EnduranceAbsorbPercentDamage[0] / 10000; //If hit for 1000, at 10% then lower damage by 100;
|
||||||
int32 endurance_drain = damage_reduced * spellbonuses.EnduranceAbsorbPercentDamage[1] / 10000;
|
int32 endurance_drain = damage_reduced * spellbonuses.EnduranceAbsorbPercentDamage[1] / 10000; //Reduce endurance by 0.05% per HP loss
|
||||||
if (endurance_drain < 1)
|
if (endurance_drain < 1)
|
||||||
endurance_drain = 1;
|
endurance_drain = 1;
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -1487,7 +1487,9 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SE_Attack_Accuracy_Max_Percent:
|
||||||
|
newbon->Attack_Accuracy_Max_Percent += base1;
|
||||||
|
break;
|
||||||
|
|
||||||
// to do
|
// to do
|
||||||
case SE_PetDiscipline:
|
case SE_PetDiscipline:
|
||||||
@@ -3261,6 +3263,9 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
|||||||
new_bonus->trap_slots = effect_value;
|
new_bonus->trap_slots = effect_value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SE_Attack_Accuracy_Max_Percent:
|
||||||
|
new_bonus->Attack_Accuracy_Max_Percent += effect_value;
|
||||||
|
break;
|
||||||
|
|
||||||
//Special custom cases for loading effects on to NPC from 'npc_spels_effects' table
|
//Special custom cases for loading effects on to NPC from 'npc_spels_effects' table
|
||||||
if (IsAISpellEffect) {
|
if (IsAISpellEffect) {
|
||||||
|
|||||||
@@ -524,6 +524,7 @@ struct StatBonuses {
|
|||||||
uint32 SkillProcSuccess[MAX_SKILL_PROCS]; // Max number of spells containing skill_procs_success.
|
uint32 SkillProcSuccess[MAX_SKILL_PROCS]; // Max number of spells containing skill_procs_success.
|
||||||
uint32 PC_Pet_Rampage[2]; // 0= % chance to rampage, 1=damage modifier
|
uint32 PC_Pet_Rampage[2]; // 0= % chance to rampage, 1=damage modifier
|
||||||
uint32 PC_Pet_Flurry; // Percent chance flurry from double attack
|
uint32 PC_Pet_Flurry; // Percent chance flurry from double attack
|
||||||
|
int32 Attack_Accuracy_Max_Percent; // Increase ATK accuracy by percent.
|
||||||
|
|
||||||
// AAs
|
// AAs
|
||||||
int8 Packrat; //weight reduction for items, 1 point = 10%
|
int8 Packrat; //weight reduction for items, 1 point = 10%
|
||||||
|
|||||||
@@ -3711,6 +3711,32 @@ void Mob::TryTwincast(Mob *caster, Mob *target, uint32 spell_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Used for effects that should occur after the completion of the spell
|
||||||
|
void Mob::TryOnSpellFinished(Mob *caster, Mob *target, uint16 spell_id)
|
||||||
|
{
|
||||||
|
if (!IsValidSpell(spell_id))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*Apply damage from Lifeburn type effects on caster at end of spell cast.
|
||||||
|
This allows for the AE spells to function without repeatedly killing caster
|
||||||
|
Damage or heal portion can be found as regular single use spell effect
|
||||||
|
*/
|
||||||
|
if (IsEffectInSpell(spell_id, SE_Health_Transfer)){
|
||||||
|
for (int i = 0; i < EFFECT_COUNT; i++) {
|
||||||
|
|
||||||
|
if (spells[spell_id].effectid[i] == SE_Health_Transfer) {
|
||||||
|
int new_hp = GetMaxHP();
|
||||||
|
new_hp -= GetMaxHP() * spells[spell_id].base[i] / 1000;
|
||||||
|
|
||||||
|
if (new_hp > 0)
|
||||||
|
SetHP(new_hp);
|
||||||
|
else
|
||||||
|
Kill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32 Mob::GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining)
|
int32 Mob::GetVulnerability(Mob* caster, uint32 spell_id, uint32 ticsremaining)
|
||||||
{
|
{
|
||||||
if (!IsValidSpell(spell_id))
|
if (!IsValidSpell(spell_id))
|
||||||
|
|||||||
@@ -353,6 +353,7 @@ public:
|
|||||||
void CalcDestFromHeading(float heading, float distance, float MaxZDiff, float StartX, float StartY, float &dX, float &dY, float &dZ);
|
void CalcDestFromHeading(float heading, float distance, float MaxZDiff, float StartX, float StartY, float &dX, float &dY, float &dZ);
|
||||||
void BeamDirectional(uint16 spell_id, int16 resist_adjust);
|
void BeamDirectional(uint16 spell_id, int16 resist_adjust);
|
||||||
void ConeDirectional(uint16 spell_id, int16 resist_adjust);
|
void ConeDirectional(uint16 spell_id, int16 resist_adjust);
|
||||||
|
void TryOnSpellFinished(Mob *caster, Mob *target, uint16 spell_id);
|
||||||
|
|
||||||
//Buff
|
//Buff
|
||||||
void BuffProcess();
|
void BuffProcess();
|
||||||
|
|||||||
+17
-2
@@ -275,11 +275,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int32 dmg = effect_value;
|
int32 dmg = effect_value;
|
||||||
if (spell_id == 2751 && caster) //Manaburn
|
if (spell_id == SPELL_MANA_BURN && caster) //Manaburn
|
||||||
{
|
{
|
||||||
dmg = caster->GetMana()*-3;
|
dmg = caster->GetMana()*-3;
|
||||||
caster->SetMana(0);
|
caster->SetMana(0);
|
||||||
} else if (spell_id == 2755 && caster) //Lifeburn
|
} else if (spell_id == SPELL_LIFE_BURN && caster) //Lifeburn
|
||||||
{
|
{
|
||||||
dmg = caster->GetHP(); // just your current HP
|
dmg = caster->GetHP(); // just your current HP
|
||||||
caster->SetHP(dmg / 4); // 2003 patch notes say ~ 1/4 HP. Should this be 1/4 your current HP or do 3/4 max HP dmg? Can it kill you?
|
caster->SetHP(dmg / 4); // 2003 patch notes say ~ 1/4 HP. Should this be 1/4 your current HP or do 3/4 max HP dmg? Can it kill you?
|
||||||
@@ -303,6 +303,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
case SE_PercentalHeal:
|
case SE_PercentalHeal:
|
||||||
{
|
{
|
||||||
#ifdef SPELL_EFFECT_SPAM
|
#ifdef SPELL_EFFECT_SPAM
|
||||||
@@ -2860,6 +2861,19 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/*Calc for base1 is found in TryOnSpellFinished() due to needing to account for AOE functionality
|
||||||
|
since effect can potentially kill caster*/
|
||||||
|
case SE_Health_Transfer: {
|
||||||
|
effect_value = spells[spell_id].base2[i];
|
||||||
|
int32 amt = abs(caster->GetMaxHP() * effect_value / 1000);
|
||||||
|
|
||||||
|
if (effect_value < 0)
|
||||||
|
Damage(caster, amt, spell_id, spell.skill, false, buffslot, false);
|
||||||
|
else
|
||||||
|
HealDamage(amt, caster);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
case SE_PersistentEffect:
|
case SE_PersistentEffect:
|
||||||
MakeAura(spell_id);
|
MakeAura(spell_id);
|
||||||
@@ -3107,6 +3121,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
case SE_Duration_HP_Pct:
|
case SE_Duration_HP_Pct:
|
||||||
case SE_Duration_Mana_Pct:
|
case SE_Duration_Mana_Pct:
|
||||||
case SE_Duration_Endurance_Pct:
|
case SE_Duration_Endurance_Pct:
|
||||||
|
case SE_Endurance_Absorb_Pct_Damage:
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1393,6 +1393,8 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo
|
|||||||
TrySympatheticProc(target, spell_id);
|
TrySympatheticProc(target, spell_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TryOnSpellFinished(this, target, spell_id);
|
||||||
|
|
||||||
TryTwincast(this, target, spell_id);
|
TryTwincast(this, target, spell_id);
|
||||||
|
|
||||||
TryTriggerOnCast(spell_id, 0);
|
TryTriggerOnCast(spell_id, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user