From fc306bbc1d64ee796fdc2038f9fc02aa03159b14 Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Tue, 16 Dec 2014 18:53:15 -0500 Subject: [PATCH 1/4] Fix for special attack NPC_CHASE_DISTANCE to now work correctly Perl export: NPC GetAttackDelay Perl export: NPC GetAvoidanceRating Perl export: NPC AddMeleeProc Special Attacks will no longer be able to hit immune to melee / bane only flagged NPCs. --- zone/mob.cpp | 166 ++++++++++++++++++++------------------- zone/npc.cpp | 1 + zone/npc.h | 1 + zone/perl_npc.cpp | 80 +++++++++++++++++++ zone/special_attacks.cpp | 3 + 5 files changed, 169 insertions(+), 82 deletions(-) diff --git a/zone/mob.cpp b/zone/mob.cpp index e497ed05e..03f845184 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -542,6 +542,8 @@ float Mob::_GetMovementSpeed(int mod) const // http://everquest.allakhazam.com/db/item.html?item=1721;page=1;howmany=50#m10822246245352 if (IsRooted()) return 0.0f; + else if (IsPseudoRooted()) + return 0.000001f; float speed_mod = runspeed; @@ -5307,98 +5309,98 @@ int32 Mob::GetSpellStat(uint32 spell_id, const char *identifier, uint8 slot) } if (slot < 16){ - if (id == "classes") {stat = spells[spell_id].classes[slot]; } - else if (id == "dieties") {stat = spells[spell_id].deities[slot];} + if (id == "classes") {return spells[spell_id].classes[slot]; } + else if (id == "dieties") {return spells[spell_id].deities[slot];} } if (slot < 12){ - if (id == "base") {stat = spells[spell_id].base[slot];} - else if (id == "base2") {stat = spells[spell_id].base2[slot];} - else if (id == "max") {stat = spells[spell_id].max[slot];} - else if (id == "formula") {spells[spell_id].formula[slot];} - else if (id == "effectid") {spells[spell_id].effectid[slot];} + if (id == "base") {return spells[spell_id].base[slot];} + else if (id == "base2") {return spells[spell_id].base2[slot];} + else if (id == "max") {return spells[spell_id].max[slot];} + else if (id == "formula") {return spells[spell_id].formula[slot];} + else if (id == "effectid") {return spells[spell_id].effectid[slot];} } if (slot < 4){ - if (id == "components") { spells[spell_id].components[slot];} - else if (id == "component_counts") {spells[spell_id].component_counts[slot];} - else if (id == "NoexpendReagent") {spells[spell_id].NoexpendReagent[slot];} + if (id == "components") { return spells[spell_id].components[slot];} + else if (id == "component_counts") { return spells[spell_id].component_counts[slot];} + else if (id == "NoexpendReagent") {return spells[spell_id].NoexpendReagent[slot];} } - if (id == "range") {stat = static_cast(spells[spell_id].range); } - else if (id == "aoerange") {stat = static_cast(spells[spell_id].aoerange);} - else if (id == "pushback") {stat = static_cast(spells[spell_id].pushback);} - else if (id == "pushup") {stat = static_cast(spells[spell_id].pushup);} - else if (id == "cast_time") {stat = spells[spell_id].cast_time;} - else if (id == "recovery_time") {stat = spells[spell_id].recovery_time;} - else if (id == "recast_time") {stat = spells[spell_id].recast_time;} - else if (id == "buffdurationformula") {stat = spells[spell_id].buffdurationformula;} - else if (id == "buffduration") {stat = spells[spell_id].buffduration;} - else if (id == "AEDuration") {stat = spells[spell_id].AEDuration;} - else if (id == "mana") {stat = spells[spell_id].mana;} + if (id == "range") {return static_cast(spells[spell_id].range); } + else if (id == "aoerange") {return static_cast(spells[spell_id].aoerange);} + else if (id == "pushback") {return static_cast(spells[spell_id].pushback);} + else if (id == "pushup") {return static_cast(spells[spell_id].pushup);} + else if (id == "cast_time") {return spells[spell_id].cast_time;} + else if (id == "recovery_time") {return spells[spell_id].recovery_time;} + else if (id == "recast_time") {return spells[spell_id].recast_time;} + else if (id == "buffdurationformula") {return spells[spell_id].buffdurationformula;} + else if (id == "buffduration") {return spells[spell_id].buffduration;} + else if (id == "AEDuration") {return spells[spell_id].AEDuration;} + else if (id == "mana") {return spells[spell_id].mana;} //else if (id == "LightType") {stat = spells[spell_id].LightType;} - Not implemented - else if (id == "goodEffect") {stat = spells[spell_id].goodEffect;} - else if (id == "Activated") {stat = spells[spell_id].Activated;} - else if (id == "resisttype") {stat = spells[spell_id].resisttype;} - else if (id == "targettype") {stat = spells[spell_id].targettype;} - else if (id == "basedeiff") {stat = spells[spell_id].basediff;} - else if (id == "skill") {stat = spells[spell_id].skill;} - else if (id == "zonetype") {stat = spells[spell_id].zonetype;} - else if (id == "EnvironmentType") {stat = spells[spell_id].EnvironmentType;} - else if (id == "TimeOfDay") {stat = spells[spell_id].TimeOfDay;} - else if (id == "CastingAnim") {stat = spells[spell_id].CastingAnim;} - else if (id == "SpellAffectIndex") {stat = spells[spell_id].SpellAffectIndex; } - else if (id == "disallow_sit") {stat = spells[spell_id].disallow_sit; } + else if (id == "goodEffect") {return spells[spell_id].goodEffect;} + else if (id == "Activated") {return spells[spell_id].Activated;} + else if (id == "resisttype") {return spells[spell_id].resisttype;} + else if (id == "targettype") {return spells[spell_id].targettype;} + else if (id == "basedeiff") {return spells[spell_id].basediff;} + else if (id == "skill") {return spells[spell_id].skill;} + else if (id == "zonetype") {return spells[spell_id].zonetype;} + else if (id == "EnvironmentType") {return spells[spell_id].EnvironmentType;} + else if (id == "TimeOfDay") {return spells[spell_id].TimeOfDay;} + else if (id == "CastingAnim") {return spells[spell_id].CastingAnim;} + else if (id == "SpellAffectIndex") {return spells[spell_id].SpellAffectIndex; } + else if (id == "disallow_sit") {return spells[spell_id].disallow_sit; } //else if (id == "spellanim") {stat = spells[spell_id].spellanim; } - Not implemented - else if (id == "uninterruptable") {stat = spells[spell_id].uninterruptable; } - else if (id == "ResistDiff") {stat = spells[spell_id].ResistDiff; } - else if (id == "dot_stacking_exemp") {stat = spells[spell_id].dot_stacking_exempt; } - else if (id == "RecourseLink") {stat = spells[spell_id].RecourseLink; } - else if (id == "no_partial_resist") {stat = spells[spell_id].no_partial_resist; } - else if (id == "short_buff_box") {stat = spells[spell_id].short_buff_box; } - else if (id == "descnum") {stat = spells[spell_id].descnum; } - else if (id == "effectdescnum") {stat = spells[spell_id].effectdescnum; } - else if (id == "npc_no_los") {stat = spells[spell_id].npc_no_los; } - else if (id == "reflectable") {stat = spells[spell_id].reflectable; } - else if (id == "bonushate") {stat = spells[spell_id].bonushate; } - else if (id == "EndurCost") {stat = spells[spell_id].EndurCost; } - else if (id == "EndurTimerIndex") {stat = spells[spell_id].EndurTimerIndex; } - else if (id == "IsDisciplineBuf") {stat = spells[spell_id].IsDisciplineBuff; } - else if (id == "HateAdded") {stat = spells[spell_id].HateAdded; } - else if (id == "EndurUpkeep") {stat = spells[spell_id].EndurUpkeep; } - else if (id == "numhitstype") {stat = spells[spell_id].numhitstype; } - else if (id == "numhits") {stat = spells[spell_id].numhits; } - else if (id == "pvpresistbase") {stat = spells[spell_id].pvpresistbase; } - else if (id == "pvpresistcalc") {stat = spells[spell_id].pvpresistcalc; } - else if (id == "pvpresistcap") {stat = spells[spell_id].pvpresistcap; } - else if (id == "spell_category") {stat = spells[spell_id].spell_category; } - else if (id == "can_mgb") {stat = spells[spell_id].can_mgb; } - else if (id == "dispel_flag") {stat = spells[spell_id].dispel_flag; } - else if (id == "MinResist") {stat = spells[spell_id].MinResist; } - else if (id == "MaxResist") {stat = spells[spell_id].MaxResist; } - else if (id == "viral_targets") {stat = spells[spell_id].viral_targets; } - else if (id == "viral_timer") {stat = spells[spell_id].viral_timer; } - else if (id == "NimbusEffect") {stat = spells[spell_id].NimbusEffect; } - else if (id == "directional_start") {stat = static_cast(spells[spell_id].directional_start); } - else if (id == "directional_end") {stat = static_cast(spells[spell_id].directional_end); } - else if (id == "not_extendable") {stat = spells[spell_id].not_extendable; } - else if (id == "suspendable") {stat = spells[spell_id].suspendable; } - else if (id == "viral_range") {stat = spells[spell_id].viral_range; } - else if (id == "spellgroup") {stat = spells[spell_id].spellgroup; } - else if (id == "rank") {stat = spells[spell_id].rank; } - else if (id == "powerful_flag") {stat = spells[spell_id].powerful_flag; } - else if (id == "CastRestriction") {stat = spells[spell_id].CastRestriction; } - else if (id == "AllowRest") {stat = spells[spell_id].AllowRest; } - else if (id == "InCombat") {stat = spells[spell_id].InCombat; } - else if (id == "OutofCombat") {stat = spells[spell_id].OutofCombat; } - else if (id == "aemaxtargets") {stat = spells[spell_id].aemaxtargets; } - else if (id == "maxtargets") {stat = spells[spell_id].maxtargets; } - else if (id == "persistdeath") {stat = spells[spell_id].persistdeath; } - else if (id == "min_dist") {stat = static_cast(spells[spell_id].min_dist); } - else if (id == "min_dist_mod") {stat = static_cast(spells[spell_id].min_dist_mod); } - else if (id == "max_dist") {stat = static_cast(spells[spell_id].max_dist); } - else if (id == "min_range") {stat = static_cast(spells[spell_id].min_range); } - else if (id == "DamageShieldType") {stat = spells[spell_id].DamageShieldType; } + else if (id == "uninterruptable") {return spells[spell_id].uninterruptable; } + else if (id == "ResistDiff") {return spells[spell_id].ResistDiff; } + else if (id == "dot_stacking_exemp") {return spells[spell_id].dot_stacking_exempt; } + else if (id == "RecourseLink") {return spells[spell_id].RecourseLink; } + else if (id == "no_partial_resist") {return spells[spell_id].no_partial_resist; } + else if (id == "short_buff_box") {return spells[spell_id].short_buff_box; } + else if (id == "descnum") {return spells[spell_id].descnum; } + else if (id == "effectdescnum") {return spells[spell_id].effectdescnum; } + else if (id == "npc_no_los") {return spells[spell_id].npc_no_los; } + else if (id == "reflectable") {return spells[spell_id].reflectable; } + else if (id == "bonushate") {return spells[spell_id].bonushate; } + else if (id == "EndurCost") {return spells[spell_id].EndurCost; } + else if (id == "EndurTimerIndex") {return spells[spell_id].EndurTimerIndex; } + else if (id == "IsDisciplineBuf") {return spells[spell_id].IsDisciplineBuff; } + else if (id == "HateAdded") {return spells[spell_id].HateAdded; } + else if (id == "EndurUpkeep") {return spells[spell_id].EndurUpkeep; } + else if (id == "numhitstype") {return spells[spell_id].numhitstype; } + else if (id == "numhits") {return spells[spell_id].numhits; } + else if (id == "pvpresistbase") {return spells[spell_id].pvpresistbase; } + else if (id == "pvpresistcalc") {return spells[spell_id].pvpresistcalc; } + else if (id == "pvpresistcap") {return spells[spell_id].pvpresistcap; } + else if (id == "spell_category") {return spells[spell_id].spell_category; } + else if (id == "can_mgb") {return spells[spell_id].can_mgb; } + else if (id == "dispel_flag") {return spells[spell_id].dispel_flag; } + else if (id == "MinResist") {return spells[spell_id].MinResist; } + else if (id == "MaxResist") {return spells[spell_id].MaxResist; } + else if (id == "viral_targets") {return spells[spell_id].viral_targets; } + else if (id == "viral_timer") {return spells[spell_id].viral_timer; } + else if (id == "NimbusEffect") {return spells[spell_id].NimbusEffect; } + else if (id == "directional_start") {return static_cast(spells[spell_id].directional_start); } + else if (id == "directional_end") {return static_cast(spells[spell_id].directional_end); } + else if (id == "not_extendable") {return spells[spell_id].not_extendable; } + else if (id == "suspendable") {return spells[spell_id].suspendable; } + else if (id == "viral_range") {return spells[spell_id].viral_range; } + else if (id == "spellgroup") {return spells[spell_id].spellgroup; } + else if (id == "rank") {return spells[spell_id].rank; } + else if (id == "powerful_flag") {return spells[spell_id].powerful_flag; } + else if (id == "CastRestriction") {return spells[spell_id].CastRestriction; } + else if (id == "AllowRest") {return spells[spell_id].AllowRest; } + else if (id == "InCombat") {return spells[spell_id].InCombat; } + else if (id == "OutofCombat") {return spells[spell_id].OutofCombat; } + else if (id == "aemaxtargets") {return spells[spell_id].aemaxtargets; } + else if (id == "maxtargets") {return spells[spell_id].maxtargets; } + else if (id == "persistdeath") {return spells[spell_id].persistdeath; } + else if (id == "min_dist") {return static_cast(spells[spell_id].min_dist); } + else if (id == "min_dist_mod") {return static_cast(spells[spell_id].min_dist_mod); } + else if (id == "max_dist") {return static_cast(spells[spell_id].max_dist); } + else if (id == "min_range") {return static_cast(spells[spell_id].min_range); } + else if (id == "DamageShieldType") {return spells[spell_id].DamageShieldType; } return stat; } diff --git a/zone/npc.cpp b/zone/npc.cpp index 6fdab645c..d9833d856 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -1942,6 +1942,7 @@ void NPC::ModifyNPCStat(const char *identifier, const char *newValue) else if(id == "special_attacks") { NPCSpecialAttacks(val.c_str(), 0, 1); return; } else if(id == "special_abilities") { ProcessSpecialAbilities(val.c_str()); return; } else if(id == "attack_speed") { attack_speed = (float)atof(val.c_str()); CalcBonuses(); return; } + else if(id == "attack_delay") { attack_delay = atoi(val.c_str()); CalcBonuses(); return; } else if(id == "atk") { ATK = atoi(val.c_str()); return; } else if(id == "accuracy") { accuracy_rating = atoi(val.c_str()); return; } else if(id == "avoidance") { avoidance_rating = atoi(val.c_str()); return; } diff --git a/zone/npc.h b/zone/npc.h index 081fca514..1e378d2ad 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -259,6 +259,7 @@ public: uint32 GetMinDMG() const {return min_dmg;} int16 GetSlowMitigation() const {return slow_mitigation;} float GetAttackSpeed() const {return attack_speed;} + uint8 GetAttackDelay() const {return attack_delay;} bool IsAnimal() const { return(bodytype == BT_Animal); } uint16 GetPetSpellID() const {return pet_spell_id;} void SetPetSpellID(uint16 amt) {pet_spell_id = amt;} diff --git a/zone/perl_npc.cpp b/zone/perl_npc.cpp index c1f8d8828..736db9565 100644 --- a/zone/perl_npc.cpp +++ b/zone/perl_npc.cpp @@ -2119,6 +2119,32 @@ XS(XS_NPC_GetAttackSpeed) XSRETURN(1); } +XS(XS_NPC_GetAttackDelay); /* prototype to pass -Wmissing-prototypes */ +XS(XS_NPC_GetAttackDelay) +{ + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: NPC::GetAttackDelay(THIS)"); + { + NPC * THIS; + float RETVAL; + dXSTARG; + + if (sv_derived_from(ST(0), "NPC")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(NPC *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type NPC"); + if(THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + RETVAL = THIS->GetAttackDelay(); + XSprePUSH; PUSHn((double)RETVAL); + } + XSRETURN(1); +} + XS(XS_NPC_GetAccuracyRating); /* prototype to pass -Wmissing-prototypes */ XS(XS_NPC_GetAccuracyRating) { @@ -2145,6 +2171,32 @@ XS(XS_NPC_GetAccuracyRating) XSRETURN(1); } +XS(XS_NPC_GetAvoidanceRating); /* prototype to pass -Wmissing-prototypes */ +XS(XS_NPC_GetAvoidanceRating) +{ + dXSARGS; + if (items != 1) + Perl_croak(aTHX_ "Usage: NPC::GetAvoidanceyRating(THIS)"); + { + NPC * THIS; + int32 RETVAL; + dXSTARG; + + if (sv_derived_from(ST(0), "NPC")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(NPC *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type NPC"); + if(THIS == nullptr) + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + + RETVAL = THIS->GetAvoidanceRating(); + XSprePUSH; PUSHu((UV)RETVAL); + } + XSRETURN(1); +} + XS(XS_NPC_GetSpawnKillCount); /* prototype to pass -Wmissing-prototypes */ XS(XS_NPC_GetSpawnKillCount) { @@ -2245,6 +2297,31 @@ XS(XS_NPC_GetMerchantProbability) { XSRETURN(1); } +XS(XS_NPC_AddMeleeProc); +XS(XS_NPC_AddMeleeProc) { + dXSARGS; + if (items != 3) + Perl_croak(aTHX_ "Usage: NPC::AddMeleePro(THIS,spellid,chance)"); + { + NPC * THIS; + int spell_id = (int)SvIV(ST(1)); + int chance = (int)SvIV(ST(2)); + dXSTARG; + + if (sv_derived_from(ST(0), "NPC")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(NPC *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type NPC"); + if(THIS == NULL) + Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); + + THIS->AddProcToWeapon(spell_id, true, chance); + } + XSRETURN_EMPTY; +} + #ifdef __cplusplus extern "C" #endif @@ -2342,11 +2419,14 @@ XS(boot_NPC) newXSproto(strcpy(buf, "GetSpellFocusHeal"), XS_NPC_GetSpellFocusHeal, file, "$"); newXSproto(strcpy(buf, "GetSlowMitigation"), XS_NPC_GetSlowMitigation, file, "$"); newXSproto(strcpy(buf, "GetAttackSpeed"), XS_NPC_GetAttackSpeed, file, "$"); + newXSproto(strcpy(buf, "GetAttackDelay"), XS_NPC_GetAttackDelay, file, "$"); newXSproto(strcpy(buf, "GetAccuracyRating"), XS_NPC_GetAccuracyRating, file, "$"); + newXSproto(strcpy(buf, "GetAvoidanceRating"), XS_NPC_GetAvoidanceRating, file, "$"); newXSproto(strcpy(buf, "GetSpawnKillCount"), XS_NPC_GetSpawnKillCount, file, "$"); newXSproto(strcpy(buf, "GetScore"), XS_NPC_GetScore, file, "$"); newXSproto(strcpy(buf, "SetMerchantProbability"), XS_NPC_SetMerchantProbability, file, "$$"); newXSproto(strcpy(buf, "GetMerchantProbability"), XS_NPC_GetMerchantProbability, file, "$"); + newXSproto(strcpy(buf, "AddMeleeProc"), XS_NPC_AddMeleeProc, file, "$$$"); XSRETURN_YES; } diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index 282eeb11e..0f57a7147 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -103,6 +103,9 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage, if (!who) return; + if(who->GetInvul() || who->GetSpecialAbility(IMMUNE_MELEE) || who->GetSpecialAbility(IMMUNE_MELEE_EXCEPT_BANE)) + return; //-5? + int32 hate = max_damage; if(hate_override > -1) hate = hate_override; From ab5d0ad43f7b68ddbec02ab4a92869cc2a11967c Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Tue, 16 Dec 2014 20:20:22 -0500 Subject: [PATCH 2/4] Fix for NPC ranged procs --- zone/mob_ai.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index dbd6d4e2d..e289f41d2 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -2731,7 +2731,7 @@ DBnpcspells_Struct* ZoneDatabase::GetNPCSpells(uint32 iDBSpellsID) { npc_spells_cache[iDBSpellsID]->attack_proc = tmpattack_proc; npc_spells_cache[iDBSpellsID]->proc_chance = tmpproc_chance; npc_spells_cache[iDBSpellsID]->range_proc = tmprange_proc; - npc_spells_cache[iDBSpellsID]->rproc_chance = tmpdproc_chance; + npc_spells_cache[iDBSpellsID]->rproc_chance = tmprproc_chance; npc_spells_cache[iDBSpellsID]->defensive_proc = tmpdefensive_proc; npc_spells_cache[iDBSpellsID]->dproc_chance = tmpdproc_chance; npc_spells_cache[iDBSpellsID]->fail_recast = tmppfail_recast; From d69552d4df58507c86ae7b814cc818028b094056 Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Wed, 17 Dec 2014 05:57:16 -0500 Subject: [PATCH 3/4] Perl: NPC AddRangedProc(spellid, chance) Perl: NPC AddDefensiveProc(spellid, chance) --- zone/perl_npc.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/zone/perl_npc.cpp b/zone/perl_npc.cpp index 736db9565..279b64330 100644 --- a/zone/perl_npc.cpp +++ b/zone/perl_npc.cpp @@ -2301,7 +2301,57 @@ XS(XS_NPC_AddMeleeProc); XS(XS_NPC_AddMeleeProc) { dXSARGS; if (items != 3) - Perl_croak(aTHX_ "Usage: NPC::AddMeleePro(THIS,spellid,chance)"); + Perl_croak(aTHX_ "Usage: NPC::AddMeleeProc(THIS,spellid,chance)"); + { + NPC * THIS; + int spell_id = (int)SvIV(ST(1)); + int chance = (int)SvIV(ST(2)); + dXSTARG; + + if (sv_derived_from(ST(0), "NPC")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(NPC *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type NPC"); + if(THIS == NULL) + Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); + + THIS->AddProcToWeapon(spell_id, true, chance); + } + XSRETURN_EMPTY; +} + +XS(XS_NPC_AddRangedProc); +XS(XS_NPC_AddRangedProc) { + dXSARGS; + if (items != 3) + Perl_croak(aTHX_ "Usage: NPC::AddRangedProc(THIS,spellid,chance)"); + { + NPC * THIS; + int spell_id = (int)SvIV(ST(1)); + int chance = (int)SvIV(ST(2)); + dXSTARG; + + if (sv_derived_from(ST(0), "NPC")) { + IV tmp = SvIV((SV*)SvRV(ST(0))); + THIS = INT2PTR(NPC *,tmp); + } + else + Perl_croak(aTHX_ "THIS is not of type NPC"); + if(THIS == NULL) + Perl_croak(aTHX_ "THIS is NULL, avoiding crash."); + + THIS->AddDefensiveProc(spell_id,chance); + } + XSRETURN_EMPTY; +} + +XS(XS_NPC_AddDefensiveProc); +XS(XS_NPC_AddDefensiveProc) { + dXSARGS; + if (items != 3) + Perl_croak(aTHX_ "Usage: NPC::AddDefensiveProc(THIS,spellid,chance)"); { NPC * THIS; int spell_id = (int)SvIV(ST(1)); @@ -2427,6 +2477,8 @@ XS(boot_NPC) newXSproto(strcpy(buf, "SetMerchantProbability"), XS_NPC_SetMerchantProbability, file, "$$"); newXSproto(strcpy(buf, "GetMerchantProbability"), XS_NPC_GetMerchantProbability, file, "$"); newXSproto(strcpy(buf, "AddMeleeProc"), XS_NPC_AddMeleeProc, file, "$$$"); + newXSproto(strcpy(buf, "AddRangedProc"), XS_NPC_AddRangedProc, file, "$$$"); + newXSproto(strcpy(buf, "AddDefensiveProc"), XS_NPC_AddDefensiveProc, file, "$$$"); XSRETURN_YES; } From 29ef1527e7b3ad15a5bdffe002ce97ad0f636859 Mon Sep 17 00:00:00 2001 From: KayenEQ Date: Wed, 17 Dec 2014 06:09:04 -0500 Subject: [PATCH 4/4] update --- zone/mob.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/mob.cpp b/zone/mob.cpp index 03f845184..af7c5a8c7 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -543,7 +543,7 @@ float Mob::_GetMovementSpeed(int mod) const if (IsRooted()) return 0.0f; else if (IsPseudoRooted()) - return 0.000001f; + return 0.00001f; float speed_mod = runspeed;