mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 10:31:29 +00:00
Merge branch 'master' of github.com:EQEmu/Server
This commit is contained in:
commit
754d70d513
@ -1,5 +1,10 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 02/18/2014 ==
|
||||
Kayen: Implemented SE_TriggerOnReqCaster - triggers a spell which a certain criteria are met (below X amount of hp,mana,end, number of pets on hatelist)
|
||||
Kayen: Implemented SE_ImprovedTaunt - Locks Aggro On Caster and Decrease other Players Aggro by X% on NPC targets below level Y
|
||||
Kayen: Fixed an error where SE_ChangeAggro was adding its bonus x 2 for spell generated aggro. (this applies also to spell casting subtlety AA reduction)
|
||||
|
||||
== 02/14/2014 ==
|
||||
Kayen: Fixes for buffs not fading under certain conditions in revised numhits system, and other fixes.
|
||||
Kayen: Implemented support for spell_new field CastRestrictions (limits what type of targets spells can effect).
|
||||
|
||||
@ -949,7 +949,7 @@ bool IsDebuffSpell(uint16 spell_id)
|
||||
if (IsBeneficialSpell(spell_id) || IsEffectHitpointsSpell(spell_id) || IsStunSpell(spell_id) ||
|
||||
IsMezSpell(spell_id) || IsCharmSpell(spell_id) || IsSlowSpell(spell_id) ||
|
||||
IsEffectInSpell(spell_id, SE_Root) || IsEffectInSpell(spell_id, SE_CancelMagic) ||
|
||||
IsEffectInSpell(spell_id, SE_MovementSpeed) || IsFearSpell(spell_id) || IsEffectInSpell(spell_id, SE_Calm))
|
||||
IsEffectInSpell(spell_id, SE_MovementSpeed) || IsFearSpell(spell_id) || IsEffectInSpell(spell_id, SE_InstantHate))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
|
||||
@ -148,7 +148,7 @@ typedef enum {
|
||||
// full listing: https://forums.station.sony.com/eq/index.php?threads/enumerated-spa-list.206288/
|
||||
// mirror: http://pastebin.com/MYeQqGwe
|
||||
#define SE_CurrentHP 0 // implemented - Heals and nukes, repeates every tic if in a buff
|
||||
#define SE_ArmorClass 1 // implemented
|
||||
#define SE_ArmorClass 1 // implemented
|
||||
#define SE_ATK 2 // implemented
|
||||
#define SE_MovementSpeed 3 // implemented - SoW, SoC, etc
|
||||
#define SE_STR 4 // implemented
|
||||
@ -239,7 +239,7 @@ typedef enum {
|
||||
#define SE_ModelSize 89 // implemented - Shrink, Growth
|
||||
#define SE_Cloak 90 // *not implemented - Used in only 2 spells
|
||||
#define SE_SummonCorpse 91 // implemented
|
||||
#define SE_Calm 92 // implemented - Hate modifier stuff(poorly named)
|
||||
#define SE_InstantHate 92 // implemented - add hate
|
||||
#define SE_StopRain 93 // implemented - Wake of Karana
|
||||
#define SE_NegateIfCombat 94 // *not implemented? - Works client side but there is comment todo in spell effects...Component of Spirit of Scale
|
||||
#define SE_Sacrifice 95 // implemented
|
||||
@ -572,7 +572,7 @@ typedef enum {
|
||||
#define SE_LimitUseMin 422 // implemented - limit a focus to require a min amount of numhits value (used with above)
|
||||
#define SE_LimitUseType 423 // implemented - limit a focus to require a certain numhits type
|
||||
#define SE_GravityEffect 424 // implemented - Pulls/pushes you toward/away the mob at a set pace
|
||||
#define SE_Display 425 // *not implemented - Illusion: Flying Dragon(21626)
|
||||
//#define SE_Display 425 // *not implemented - Illusion: Flying Dragon(21626)
|
||||
#define SE_IncreaseExtTargetWindow 426 // *not implmented[AA] - increases the capacity of your extended target window
|
||||
#define SE_SkillProc 427 // implemented - chance to proc when using a skill(ie taunt)
|
||||
#define SE_LimitToSkill 428 // implemented - limits what skills will effect a skill proc
|
||||
@ -589,9 +589,9 @@ 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_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_ImprovedTaunt 444 // *not implemented - Locks Aggro On Caster and Decrease other Players Aggro by X% up to level Z
|
||||
#define SE_TriggerOnReqTarget 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_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
|
||||
|
||||
@ -1054,7 +1054,8 @@ void Mob::AI_Process() {
|
||||
SetTarget(hate_list.GetTop(this));
|
||||
}
|
||||
} else {
|
||||
SetTarget(hate_list.GetTop(this));
|
||||
if (!ImprovedTaunt())
|
||||
SetTarget(hate_list.GetTop(this));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1257,7 +1257,7 @@ int32 Mob::CheckAggroAmount(uint16 spell_id, bool isproc)
|
||||
break;
|
||||
}
|
||||
case SE_ReduceHate:
|
||||
case SE_Calm: {
|
||||
case SE_InstantHate: {
|
||||
nonModifiedAggro = CalcSpellEffectValue_formula(spells[spell_id].formula[o], spells[spell_id].base[o], spells[spell_id].max[o], slevel, spell_id);
|
||||
break;
|
||||
}
|
||||
@ -1282,9 +1282,6 @@ int32 Mob::CheckAggroAmount(uint16 spell_id, bool isproc)
|
||||
if (IsClient())
|
||||
HateMod += CastToClient()->GetFocusEffect(focusSpellHateMod, spell_id);
|
||||
|
||||
//Live AA - Spell casting subtlety
|
||||
HateMod += aabonuses.hatemod + spellbonuses.hatemod + itembonuses.hatemod;
|
||||
|
||||
AggroAmount = (AggroAmount * HateMod) / 100;
|
||||
|
||||
//made up number probably scales a bit differently on live but it seems like it will be close enough
|
||||
@ -1405,7 +1402,7 @@ bool Mob::PassCharismaCheck(Mob* caster, Mob* spellTarget, uint16 spell_id) {
|
||||
return true;
|
||||
|
||||
//1: The mob has a default 25% chance of being allowed a resistance check against the charm.
|
||||
if (MakeRandomInt(0, 100) > RuleI(Spells, CharmBreakCheckChance))
|
||||
if (MakeRandomInt(0, 99) > RuleI(Spells, CharmBreakCheckChance))
|
||||
return true;
|
||||
|
||||
//2: The mob makes a resistance check against the charm
|
||||
@ -1419,7 +1416,7 @@ bool Mob::PassCharismaCheck(Mob* caster, Mob* spellTarget, uint16 spell_id) {
|
||||
//3: At maxed ability, Total Domination has a 50% chance of preventing the charm break that otherwise would have occurred.
|
||||
uint16 TotalDominationBonus = caster->aabonuses.CharmBreakChance + caster->spellbonuses.CharmBreakChance + caster->itembonuses.CharmBreakChance;
|
||||
|
||||
if (MakeRandomInt(0, 100) < TotalDominationBonus)
|
||||
if (MakeRandomInt(0, 99) < TotalDominationBonus)
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@ -1336,6 +1336,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
|
||||
|
||||
// Hate Generation is on a per swing basis, regardless of a hit, miss, or block, its always the same.
|
||||
// If we are this far, this means we are atleast making a swing.
|
||||
|
||||
if (!bRiposte) // Ripostes never generate any aggro.
|
||||
other->AddToHateList(this, hate);
|
||||
|
||||
@ -1901,6 +1902,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
mlog(COMBAT__HITS, "Generating hate %d towards %s", hate, GetName());
|
||||
// now add done damage to the hate list
|
||||
other->AddToHateList(this, hate);
|
||||
|
||||
} else {
|
||||
if(opts) {
|
||||
damage *= opts->damage_percent;
|
||||
@ -2435,7 +2437,9 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
||||
}
|
||||
|
||||
void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp, bool bFrenzy, bool iBuffTic) {
|
||||
|
||||
assert(other != nullptr);
|
||||
|
||||
if (other == this)
|
||||
return;
|
||||
|
||||
@ -2516,6 +2520,10 @@ void Mob::AddToHateList(Mob* other, int32 hate, int32 damage, bool iYellForHelp,
|
||||
if(damage > GetHP())
|
||||
damage = GetHP();
|
||||
|
||||
if (spellbonuses.ImprovedTaunt[1] && (GetLevel() < spellbonuses.ImprovedTaunt[0])
|
||||
&& other && (buffs[spellbonuses.ImprovedTaunt[2]].casterid != other->GetID()))
|
||||
hate = (hate*spellbonuses.ImprovedTaunt[1])/100;
|
||||
|
||||
hate_list.Add(other, hate, damage, bFrenzy, !iBuffTic);
|
||||
|
||||
if(other->IsClient())
|
||||
|
||||
@ -2496,7 +2496,8 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
|
||||
break;
|
||||
}
|
||||
|
||||
case SE_TriggerOnValueAmount:
|
||||
case SE_TriggerOnReqTarget:
|
||||
case SE_TriggerOnReqCaster:
|
||||
newbon->TriggerOnValueAmount = true;
|
||||
break;
|
||||
|
||||
@ -2504,6 +2505,14 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
|
||||
newbon->DivineAura = true;
|
||||
break;
|
||||
|
||||
case SE_ImprovedTaunt:
|
||||
if (newbon->ImprovedTaunt[0] < effect_value) {
|
||||
newbon->ImprovedTaunt[0] = effect_value;
|
||||
newbon->ImprovedTaunt[1] = spells[spell_id].base2[i];
|
||||
newbon->ImprovedTaunt[2] = buffslot;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12973,7 +12973,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
|
||||
pacer->Say("Trying to pacify %s \n", target->GetCleanName());
|
||||
|
||||
if(pacer->Bot_Command_CalmTarget(target)) {
|
||||
if(target->FindType(SE_Lull) || target->FindType(SE_Harmony) || target->FindType(SE_Calm))
|
||||
if(target->FindType(SE_Lull) || target->FindType(SE_Harmony) || target->FindType(SE_InstantHate))
|
||||
//if(pacer->IsPacified(target))
|
||||
c->Message(0, "I have successfully pacified %s.", target->GetCleanName());
|
||||
return;
|
||||
@ -12989,7 +12989,7 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
|
||||
pacer->Say("Trying to pacify %s \n", target->GetCleanName());
|
||||
|
||||
if(pacer->Bot_Command_CalmTarget(target)) {
|
||||
if(target->FindType(SE_Lull) || target->FindType(SE_Harmony) || target->FindType(SE_Calm))
|
||||
if(target->FindType(SE_Lull) || target->FindType(SE_Harmony) || target->FindType(SE_InstantHate))
|
||||
//if(pacer->IsPacified(target))
|
||||
c->Message(0, "I have successfully pacified %s.", target->GetCleanName());
|
||||
return;
|
||||
|
||||
@ -328,6 +328,7 @@ struct StatBonuses {
|
||||
bool CriticalHealDecay; // increase critical heal chance, decays based on spell level cast
|
||||
bool CriticalDotDecay; // increase critical dot chance, decays based on spell level cast
|
||||
bool DivineAura; // invulnerability
|
||||
int16 ImprovedTaunt[3]; // 0 = Max Level 1 = Aggro modifier 2 = buffid
|
||||
//bool AbsorbMagicAtt; // Magic Rune *Need to be implemented for NegateEffect
|
||||
//bool MeleeRune; // Melee Rune *Need to be implemented for NegateEffect
|
||||
|
||||
|
||||
@ -3670,7 +3670,7 @@ MercSpell Merc::GetBestMercSpellForHate(Merc* caster) {
|
||||
result.time_cancast = 0;
|
||||
|
||||
if(caster) {
|
||||
std::list<MercSpell> mercSpellList = GetMercSpellsForSpellEffect(caster, SE_Calm);
|
||||
std::list<MercSpell> mercSpellList = GetMercSpellsForSpellEffect(caster, SE_InstantHate);
|
||||
|
||||
for(std::list<MercSpell>::iterator mercSpellListItr = mercSpellList.begin(); mercSpellListItr != mercSpellList.end(); ++mercSpellListItr) {
|
||||
// Assuming all the spells have been loaded into this list by level and in descending order
|
||||
|
||||
27
zone/mob.cpp
27
zone/mob.cpp
@ -3228,11 +3228,20 @@ void Mob::TryApplyEffect(Mob *target, uint32 spell_id)
|
||||
void Mob::TryTriggerOnValueAmount(bool IsHP, bool IsMana, bool IsEndur, bool IsPet)
|
||||
{
|
||||
/*
|
||||
At present time there is no obvious difference between ReqTarget and ReqCaster
|
||||
ReqTarget is typically used in spells cast on a target where the trigger occurs on that target.
|
||||
ReqCaster is typically self only spells where the triggers on self.
|
||||
Regardless both trigger on the owner of the buff.
|
||||
*/
|
||||
|
||||
/*
|
||||
Base2 Range: 1004 = Below < 80% HP
|
||||
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)
|
||||
38311 = < 10% mana;
|
||||
*/
|
||||
|
||||
if (!spellbonuses.TriggerOnValueAmount)
|
||||
@ -3250,21 +3259,25 @@ void Mob::TryTriggerOnValueAmount(bool IsHP, bool IsMana, bool IsEndur, bool IsP
|
||||
|
||||
for(int i = 0; i < EFFECT_COUNT; i++){
|
||||
|
||||
if (spells[spell_id].effectid[i] == SE_TriggerOnValueAmount){
|
||||
if ((spells[spell_id].effectid[i] == SE_TriggerOnReqTarget) || (spells[spell_id].effectid[i] == SE_TriggerOnReqCaster)) {
|
||||
|
||||
int base2 = spells[spell_id].base2[i];
|
||||
bool use_spell = false;
|
||||
|
||||
if (IsHP){
|
||||
if ((base2 >= 500 && base2 <= 520) && GetHPRatio() < (base2 - 500)*5){
|
||||
if ((base2 >= 500 && base2 <= 520) && GetHPRatio() < (base2 - 500)*5)
|
||||
use_spell = true;
|
||||
|
||||
else if (base2 = 1004 && GetHPRatio() < 80)
|
||||
use_spell = true;
|
||||
}
|
||||
}
|
||||
|
||||
else if (IsMana){
|
||||
if ( (base2 = 521 && GetManaRatio() < 20) || (base2 = 523 && GetManaRatio() < 40)) {
|
||||
if ( (base2 = 521 && GetManaRatio() < 20) || (base2 = 523 && GetManaRatio() < 40))
|
||||
use_spell = true;
|
||||
|
||||
else if (base2 = 38311 && GetManaRatio() < 10)
|
||||
use_spell = true;
|
||||
}
|
||||
}
|
||||
|
||||
else if (IsEndur){
|
||||
@ -3283,10 +3296,6 @@ void Mob::TryTriggerOnValueAmount(bool IsHP, bool IsMana, bool IsEndur, bool IsP
|
||||
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);
|
||||
}
|
||||
|
||||
@ -592,6 +592,7 @@ public:
|
||||
int32 GetExtraSpellAmt(uint16 spell_id, int32 extra_spell_amt, int32 base_spell_dmg);
|
||||
void MeleeLifeTap(int32 damage);
|
||||
bool PassCastRestriction(bool UseCastRestriction = true, int16 value = 0, bool IsDamage = true);
|
||||
bool ImprovedTaunt();
|
||||
|
||||
void ModSkillDmgTaken(SkillUseTypes skill_num, int value);
|
||||
int16 GetModSkillDmgTaken(const SkillUseTypes skill_num);
|
||||
|
||||
@ -2667,7 +2667,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
case SE_ChangeAggro:
|
||||
case SE_Hate2:
|
||||
case SE_Identify:
|
||||
case SE_Calm:
|
||||
case SE_InstantHate:
|
||||
case SE_ReduceHate:
|
||||
case SE_SpellDamageShield:
|
||||
case SE_ReverseDS:
|
||||
@ -2806,7 +2806,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
||||
case SE_DoubleRangedAttack:
|
||||
case SE_ShieldEquipHateMod:
|
||||
case SE_ShieldEquipDmgMod:
|
||||
case SE_TriggerOnValueAmount:
|
||||
case SE_TriggerOnReqTarget:
|
||||
case SE_LimitRace:
|
||||
case SE_FcLimitUse:
|
||||
case SE_FcMute:
|
||||
@ -5577,6 +5577,28 @@ bool Mob::TryDispel(uint8 caster_level, uint8 buff_level, int level_modifier){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Mob::ImprovedTaunt(){
|
||||
|
||||
if (spellbonuses.ImprovedTaunt[2]){
|
||||
|
||||
if (GetLevel() > spellbonuses.ImprovedTaunt[0])
|
||||
return false;
|
||||
|
||||
target = entity_list.GetMob(buffs[spellbonuses.ImprovedTaunt[2]].casterid);
|
||||
|
||||
if (target){
|
||||
SetTarget(target);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
BuffFadeBySlot(spellbonuses.ImprovedTaunt[2]); //If caster killed removed effect.
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDamage)
|
||||
{
|
||||
/*If return TRUE spell met all restrictions and can continue (this = target).
|
||||
@ -5633,7 +5655,7 @@ bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDama
|
||||
Range 839 : Unknown *not implemented
|
||||
Range 842 - 844 : Humaniod lv MAX ((842 - 800) * 2)
|
||||
Range 845 - 847 : UNKNOWN
|
||||
Range 10000+ : Limit to Race [base2 - 10000 = Race] (*Not on live: Too useful a function to not implement)
|
||||
Range 10000 - 11000 : Limit to Race [base2 - 10000 = Race] (*Not on live: Too useful a function to not implement)
|
||||
THIS IS A WORK IN PROGRESS
|
||||
*/
|
||||
|
||||
@ -5650,7 +5672,7 @@ bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDama
|
||||
break;
|
||||
|
||||
case 101:
|
||||
if (GetBodyType() == BT_Dragon)
|
||||
if (GetBodyType() == BT_Dragon || GetBodyType() == BT_VeliousDragon || GetBodyType() == BT_Dragon3)
|
||||
return true;
|
||||
break;
|
||||
|
||||
@ -5786,6 +5808,11 @@ bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDama
|
||||
return true;
|
||||
break;
|
||||
|
||||
case 701:
|
||||
if (!IsPet())
|
||||
return true;
|
||||
break;
|
||||
|
||||
case 818:
|
||||
if (GetBodyType() == BT_Undead)
|
||||
return true;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user