Spell Effect Updates.

Implemented fail chances for SE, Gate, Succor, FeignDeath.
Minor fixes to haste bonuses to allow for negatives.
Rule added for Succor failure rate.
This commit is contained in:
KayenEQ 2014-03-27 05:14:54 -04:00
parent 6906125725
commit 41903e8f09
6 changed files with 73 additions and 25 deletions

View File

@ -1,5 +1,12 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 03/27/2014 ==
Kayen: SE_Gate will now use have a fail chance as defined by its base value in the spell data.
Kayen: SE_Succor will now have a baseline fail chance of (2%). Rule added to adjust this as needed.
Kayen: SE_FeignDeath will now have a fail chance as defined by its base value in the spell data.
Optional SQL: utils/sql/git/optional/2014_03_27_SuccorFailRule.sql
== 03/22/2014 ==
Uleat: Moved the existing 'load_bots' and 'drop_bots' sqls into the emu git repository for the time being. Look to the
/utils/sql/git/bots/ folder to find them. The 'load_bots' sql has been updated to include the below fix, as well as

View File

@ -302,6 +302,7 @@ RULE_BOOL ( Spells, UseCHAScribeHack, false) //ScribeSpells and TrainDiscs quest
RULE_BOOL ( Spells, BuffLevelRestrictions, true) //Buffs will not land on low level toons like live
RULE_INT ( Spells, RootBreakCheckChance, 70) //Determines chance for a root break check to occur each buff tick.
RULE_INT ( Spells, FearBreakCheckChance, 70) //Determines chance for a fear break check to occur each buff tick.
RULE_INT ( Spells, SuccorFailChance, 2) //Determines chance for a succor spell not to teleport an invidual player
RULE_CATEGORY_END()
RULE_CATEGORY( Combat )

View File

@ -159,8 +159,8 @@ typedef enum {
#define SE_WIS 9 // implemented
#define SE_CHA 10 // implemented - used as a spacer
#define SE_AttackSpeed 11 // implemented
#define SE_Invisibility 12 // implemented
#define SE_SeeInvis 13 // implemented
#define SE_Invisibility 12 // implemented - TO DO: Implemented Invisiblity Levels
#define SE_SeeInvis 13 // implemented - TO DO: Implemented See Invisiblity Levels
#define SE_WaterBreathing 14 // implemented
#define SE_CurrentMana 15 // implemented
//#define SE_NPCFrenzy 16 // not used
@ -172,7 +172,7 @@ typedef enum {
#define SE_Charm 22 // implemented
#define SE_Fear 23 // implemented
#define SE_Stamina 24 // implemented - Invigor and such
#define SE_BindAffinity 25 // implemented
#define SE_BindAffinity 25 // implemented - TO DO: Implement 2nd and 3rd Recall (value 2,3 ect). Sets additional bind points.
#define SE_Gate 26 // implemented - Gate to bind point
#define SE_CancelMagic 27 // implemented
#define SE_InvisVsUndead 28 // implemented
@ -211,7 +211,7 @@ typedef enum {
#define SE_Identify 61 // implemented
//#define SE_ItemID 62 // not used
#define SE_WipeHateList 63 // implemented
#define SE_SpinTarget 64 // implemented
#define SE_SpinTarget 64 // implemented - TO DO: Not sure stun portion is working correctly
#define SE_InfraVision 65 // implemented
#define SE_UltraVision 66 // implemented
#define SE_EyeOfZomm 67 // implemented
@ -456,7 +456,7 @@ typedef enum {
//#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.
#define SE_SuspendMinion 308 // not implemented as bonus
#define SE_YetAnotherGate 309 // implemented
#define SE_GateCastersBindpoint 309 // implemented - Gate to casters bind point
#define SE_ReduceReuseTimer 310 // implemented
#define SE_LimitCombatSkills 311 // implemented - Excludes focus from procs (except if proc is a memorizable spell)
//#define SE_Sanctuary 312 // *not implemented

View File

@ -0,0 +1 @@
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:SuccorFailChance', '2', 'Determines chance for a succor spell not to teleport an invidual player.');

View File

@ -1358,16 +1358,27 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_AttackSpeed2:
{
if ((effect_value - 100) > 0) { // Haste V2 - Stacks with V1 but does not Overcap
if (newbon->hastetype2 < 0) break; //Slowed - Don't apply haste2
if ((effect_value - 100) > newbon->hastetype2) {
newbon->hastetype2 = effect_value - 100;
}
}
else if ((effect_value - 100) < 0) { // Slow
int real_slow_value = (100 - effect_value) * -1;
if (real_slow_value < newbon->hastetype2)
newbon->hastetype2 = real_slow_value;
}
break;
}
case SE_AttackSpeed3:
{
if (effect_value > 0) { // Haste V3 - Stacks and Overcaps
if (effect_value < 0){ //Slow
if (effect_value < newbon->hastetype3)
newbon->hastetype3 = effect_value;
}
else if (effect_value > 0) { // Haste V3 - Stacks and Overcaps
if (effect_value > newbon->hastetype3) {
newbon->hastetype3 = effect_value;
}
@ -1377,18 +1388,24 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses* ne
case SE_AttackSpeed4:
{
if (effect_value > 0) {
if (effect_value < 0) //A few spells use negative values(Descriptions all indicate it should be a slow)
effect_value = effect_value * -1;
if (effect_value > 0 && effect_value > newbon->inhibitmelee) {
if (slow_mitigation){
int new_effect_value = SlowMitigation(false,caster,effect_value);
if (new_effect_value > newbon->inhibitmelee) {
newbon->inhibitmelee = new_effect_value;
SlowMitigation(true,caster);
newbon->inhibitmelee = new_effect_value;
SlowMitigation(true,caster);
}
}
else if (effect_value > newbon->inhibitmelee) {
newbon->inhibitmelee = effect_value;
newbon->inhibitmelee = effect_value;
}
}
break;
}

View File

@ -396,10 +396,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
}
case SE_Succor:
{
{
float x, y, z, heading;
const char *target_zone;
x = spell.base[1];
y = spell.base[0];
z = spell.base[2];
@ -426,6 +427,14 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
if(IsClient())
{
if(MakeRandomInt(0, 99) < RuleI(Spells, SuccorFailChance)) { //2% Fail chance by default
if(IsClient()) {
CastToClient()->Message(MT_SpellFailure,"Your portal collapses before you can make your escape!");
}
break;
}
// Below are the spellid's for known evac/succor spells that send player
// to the current zone's safe points.
@ -441,10 +450,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
#ifdef SPELL_EFFECT_SPAM
LogFile->write(EQEMuLog::Debug, "Succor/Evacuation Spell In Same Zone.");
#endif
if(IsClient())
CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), x, y, z, heading, 0, EvacToSafeCoords);
else
GMMove(x, y, z, heading);
if(IsClient())
CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), x, y, z, heading, 0, EvacToSafeCoords);
else
GMMove(x, y, z, heading);
}
else {
#ifdef SPELL_EFFECT_SPAM
@ -457,7 +466,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
break;
}
case SE_YetAnotherGate: //Shin: Used on Teleport Bind.
case SE_GateCastersBindpoint: //Shin: Used on Teleport Bind.
case SE_Teleport: // gates, rings, circles, etc
case SE_Teleport2:
{
@ -489,7 +498,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
}
}
if (effect == SE_YetAnotherGate && caster->IsClient())
if (effect == SE_GateCastersBindpoint && caster->IsClient())
{ //Shin: Teleport Bind uses caster's bind point
x = caster->CastToClient()->GetBindX();
y = caster->CastToClient()->GetBindY();
@ -857,7 +866,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
break;
}
case SE_BindAffinity:
case SE_BindAffinity: //TO DO: Add support for secondary and tertiary gate abilities
{
#ifdef SPELL_EFFECT_SPAM
snprintf(effect_desc, _EDLEN, "Bind Affinity");
@ -989,13 +998,18 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
break;
}
case SE_Gate:
case SE_Gate: //TO DO: Add support for secondary and tertiary gate abilities (base2)
{
#ifdef SPELL_EFFECT_SPAM
snprintf(effect_desc, _EDLEN, "Gate");
#endif
if(!spellbonuses.AntiGate)
Gate();
if(!spellbonuses.AntiGate){
if(MakeRandomInt(0, 99) < effect_value)
Gate();
else
caster->Message(MT_SpellFailure,"Your portal has collapsed.");
}
break;
}
@ -1378,7 +1392,8 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
(
spell.base[i],
Mob::GetDefaultGender(spell.base[i], GetGender()),
spell.base2[i]
spell.base2[i],
spell.max[i]
);
if(spell.base[i] == OGRE){
SendAppearancePacket(AT_Size, 9);
@ -1554,8 +1569,15 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
if(spell_id == 2488) //Dook- Lifeburn fix
break;
if(IsClient())
CastToClient()->SetFeigned(true);
if(IsClient()) {
if (MakeRandomInt(0, 99) > spells[spell_id].base[i]) {
CastToClient()->SetFeigned(false);
entity_list.MessageClose_StringID(this, false, 200, 10, STRING_FEIGNFAILED, GetName());
}
else
CastToClient()->SetFeigned(true);
}
break;
}