// TMW2 scripts. // Authors: // Jesusalva // TMW Org. // Description: // HUB functions (Magic) // HUB_SkillInvoke ( ) function script HUB_SkillInvoke { // Something is... wrong if (!@skillId) { Exception("ILLEGAL SKILL PASSED TO HUB. It has been compromised, Jim.", RB_DEBUGMES|RB_IRCBROADCAST); debugmes "Legal Caster: %s", strcharinfo(0); debugmes "Effective Caster: %d", @skillCaster; return; } /* *********************************************************************** */ // TODO: Detect what was script-cast and what was player-case. Then, readd RB_IRCBROADCAST // If you can't do this: You can't do this if (getskilllv(@skillId) < @skillLv && @skillId != BS_GREED) Exception("System ERROR, HSI."+@skillId+" INVALID CAST (got "+@skillLv+" expected "+getskilllv(@skillId)+", sub-LC."+(getcharid(3)-2000000)+")", RB_DEBUGMES|RB_ISFATAL); // You are AFK for over 3 minutes, that's crazy, disregard if (checkidle() > 180) return; // Record to database skillInvoke[@skillId] = skillInvoke[@skillId] + 1; // Script-based skills /* *********************************************************************** */ switch (@skillId) { case TMW2_FAKESKILL: charcommand("@refresh"); // Possibly broken on too up-to-date Herc break; case SKILL_ABIZIT: SK_Abizit(); break; case EVOL_AREA_PROVOKE: SK_Itenplz(); break; case SKILL_FLAR: SK_Flar(); break; //////////////////////////////// /* / XXX: Healing Class case TMW2_FIRSTAID: .@PW=90+(10*@skillLv); // First aid only works on you, so .@heal=max(AdjustSpellpower(.@PW), AdjustAttackpower(.@PW)); heal .@heal, 0; GetManaExp(TMW2_HEALING, 1); break; case TMW2_HEALING: .@PW=130+(20*@skillLv); harm(@skillTarget, -AdjustSpellpower(.@PW), HARM_MISC); GetManaExp(TMW2_HEALING, 2); break; case TMW2_MAGNUSHEAL: // Area healing .@PW=200+(20*@skillLv); .@RG=4+(@skillLv/5); areaharm(@skillTarget, .@RG, -AdjustSpellpower(.@PW), HARM_MISC, "filter_friendly"); GetManaExp(TMW2_HEALING, 3); break; //////////////////////////////// // XXX: Fire Class // (May burn targets for damage over time) case TMW2_FIREARROW: .@PW=140+(10*@skillLv); // 4% chance, 2.5s harm(@skillTarget, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Fire); sc_start SC_BLOODING, 4500, 1, 400, SCFLAG_NONE, @skillTarget; GetManaExp(TMW2_FIREBALL, 1); break; case TMW2_FIREBALL: .@PW=140+(10*@skillLv); .@RG=2+(@skillLv/5); // 22% chance, 2.5s areaharm(@skillTarget, .@RG, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Fire); sc_start SC_BLOODING, 2500, 1, 4200, SCFLAG_NONE, @skillTarget; GetManaExp(TMW2_FIREBALL, 2); break; case TMW2_ARMAGEDDON: .@PW=140+(10*@skillLv); .@RG=5+(@skillLv/5); // 18% chance, 3s, 3x3 radius areaharm(@skillTarget, .@RG, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Fire); areasc(.@RG, 6000, SC_BLOODING, BL_MOB|BL_PC|BL_HOM|BL_MER, 1, "filter_hostile", @skillTarget, 1800); GetManaExp(TMW2_FIREBALL, 3); break; //////////////////////////////// // XXX: Holy Class // (Single DPS + AOE) case TMW2_NAPALMBEAT: .@PW=35+(5*@skillLv); .@dmg=AdjustSpellpower(.@PW); .@RG=2+(@skillLv/3); harm(@skillTarget, .@dmg/10, HARM_MAGI, Ele_Holy); areaharm(@skillTarget, .@RG, .@dmg, HARM_MAGI, Ele_Holy); GetManaExp(TMW2_HOLYLIGHT, 1); break; case TMW2_HOLYLIGHT: .@PW=125+(25*@skillLv); .@dmg=AdjustSpellpower(.@PW); harm(@skillTarget, .@dmg, HARM_MAGI, Ele_Holy); areaharm(@skillTarget, 1, .@dmg/5, HARM_MAGI, Ele_Holy); GetManaExp(TMW2_HOLYLIGHT, 2); break; case TMW2_JUDGMENT: .@PW=250+(50*@skillLv); .@SPW=60+(15*@skillLv); .@dmg=AdjustSpellpower(.@PW); .@dsub=AdjustSpellpower(.@SPW); .@RG=3+(@skillLv/5); harm(@skillTarget, .@dmg, HARM_MAGI, Ele_Holy); areaharm(@skillTarget, .@RG, .@dsub, HARM_MAGI, Ele_Holy); GetManaExp(TMW2_HOLYLIGHT, 3); break; //////////////////////////////// // XXX: Wind Class // (Smaller cooldown than others) case TMW2_MAGICSTRIKE: .@PW=125+(25*@skillLv); .@dmg=AdjustSpellpower(.@PW); harm(@skillTarget, .@dmg, HARM_MAGI, Ele_Wind); GetManaExp(TMW2_LIGHTNINGBOLT, 1); break; case TMW2_LIGHTNINGBOLT: .@PW=150+(50*@skillLv); .@dmg=AdjustSpellpower(.@PW); harm(@skillTarget, .@dmg, HARM_MAGI, Ele_Wind); GetManaExp(TMW2_LIGHTNINGBOLT, 2); break; case TMW2_TEMPEST: .@PW=125+(25*@skillLv); .@dmg=AdjustSpellpower(.@PW); .@RG=2+(@skillLv/5); areaharm(@skillTarget, .@RG, .@dmg, HARM_MAGI, Ele_Wind); GetManaExp(TMW2_LIGHTNINGBOLT, 3); break; //////////////////////////////// // XXX: Ice Class // (May freeze the targets) case TMW2_FROSTDIVER: .@PW=80+(10*@skillLv); // 22% chance, 2.5s harm(@skillTarget, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Water); sc_start SC_FREEZE, 2500, 1, 2200, SCFLAG_NONE, @skillTarget; GetManaExp(TMW2_NILFHEIM, 1); break; case TMW2_FROSTNOVA: .@PW=80+(10*@skillLv); .@RG=2+(@skillLv/5); // 18% chance, 3s, 3x3 radius areaharm(@skillTarget, .@RG, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Water); areasc(.@RG, 3000, SC_FREEZE, BL_MOB|BL_PC|BL_HOM|BL_MER, 1, "filter_hostile", @skillTarget, 1800); GetManaExp(TMW2_NILFHEIM, 2); break; case TMW2_NILFHEIM: // Nilfheim cast on self? .@PW=80+(10*@skillLv); .@RG=4+(@skillLv/5); areaharm(getcharid(3), .@RG*3/2, AdjustSpellpower(.@PW), HARM_MAGI, Ele_Water); areasc(.@RG, 15000, SC_FREEZE, BL_PC | BL_MOB | BL_MER | BL_HOM, 1, "filter_hostile"); // Maybe filter_notme() would work better, indeed GetManaExp(TMW2_NILFHEIM, 3); break; //////////////////////////////// // XXX: Earth Class // DEF Effects at Gaia Break, more expensive case TMW2_METEORSTRIKE: .@PW=130+(20*@skillLv); .@dmg=AdjustSpellpower(.@PW); .@TM=1200+(@skillLv*300); harm(@skillTarget, .@dmg, HARM_MAGI, Ele_Earth); sc_start SC_STUN, .@TM, 1, 800, SCFLAG_NONE, @skillTarget; GetManaExp(TMW2_METEORSTRIKE, 1); break; case TMW2_METEORSHOWER: .@PW=130+(15*@skillLv); .@dmg=AdjustSpellpower(.@PW); .@RG=3+(@skillLv/5); .@TM=800+(@skillLv*200); areaharm(@skillTarget, .@RG, .@dmg, HARM_MAGI, Ele_Earth); areasc(.@RG, .@TM, SC_STUN, BL_MOB | BL_PC | BL_HOM | BL_MER, 1, "filter_hostile", @skillTarget, 800); GetManaExp(TMW2_METEORSTRIKE, 2); break; case TMW2_GAIABREAK: .@PWA=170+(30*@skillLv); .@PWB=110+(10*@skillLv); .@dmg=AdjustSpellpower(.@PWA); .@dsub=AdjustSpellpower(.@PWB); harm(@skillTarget, .@dmg, HARM_MAGI, Ele_Earth); rectharm(@skillTarget, 2, 5, .@dsub, HARM_MAGI, Ele_Earth); areasc(2, 5000, SC_INCDEFRATE, BL_PC, 10, "filter_friendly"); GetManaExp(TMW2_METEORSTRIKE, 3); break; //////////////////////////////// // XXX: Physical Class (Regular) case TMW2_FALKONSTRIKE: .@PW=100+(25*@skillLv); .@ST=0+(10*@skillLv); .@TM=100+(90*@skillLv); harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral); sc_start SC_STUN, .@TM, 1, .@ST, SCFLAG_NONE, @skillTarget; GetManaExp(@skillId, 1); break; case TMW2_GROUNDSTRIKE: .@PW=50+(40*@skillLv); .@dmg=AdjustAttackpower(.@PW); .@RG=2+(@skillLv/5); .@TM=100+(@skillLv*200); .@ST=500+(100*@skillLv); .@EF=any(SC_STUN, SC_BLIND, SC_BLOODING, SC_BLIND, SC_BLOODING); areaharm(@skillTarget, .@RG, .@dmg, HARM_PHYS, Ele_Neutral); areasc(.@RG, .@TM, .@EF, BL_MOB | BL_PC | BL_HOM | BL_MER, 1, "filter_hostile", @skillTarget, .@ST); GetManaExp(@skillId, 1); break; case TMW2_SUPREMEATTACK: .@PW=100+(50*@skillLv); harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral); GetManaExp(@skillId, 1); break; //////////////////////////////// // XXX: Physical Class (Archery) case TMW2_CHARGEDARROW: .@PW=100+(50*@skillLv); harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral); GetManaExp(@skillId, 1); break; case TMW2_ARROWSHOWER: .@PW=150+(10*@skillLv); .@dmg=AdjustAttackpower(.@PW); .@RG=1+(@skillLv/3); areaharm(@skillTarget, .@RG, .@dmg, HARM_PHYS, Ele_Neutral); GetManaExp(@skillId, 1); break; //////////////////////////////// // XXX: Brawling Class case TMW2_BRAWLING: // 75x3 = 225 .@PW=70+(5*@skillLv); // Using a shield, so power is halved if (getequipid(EQI_HAND_L) > 0) .@PW=.@PW/2; harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral); sleep2(10); harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral); sleep2(10); harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral); break; case TMW2_BEARSTRIKE: // 60x5 = 300 .@PW=55+(5*@skillLv); // Using a shield, so power is halved if (getequipid(EQI_HAND_L) > 0) .@PW=.@PW/2; harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral); sleep2(10); harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral); sleep2(10); harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral); sleep2(10); harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral); sleep2(10); harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral); break; case TMW2_ALLINONE: // 45x8 = 360 .@PW=40+(5*@skillLv); // Using a shield, so power is halved if (getequipid(EQI_HAND_L) > 0) .@PW=.@PW/2; //harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral); harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Fire); sleep2(10); harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Water); sleep2(10); harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Earth); sleep2(10); harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Wind); sleep2(10); harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Holy); sleep2(10); harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Shadow); sleep2(10); harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Ghost); sleep2(10); // The main elemental-less blast hits all in same square, // and also hits behind (and on your square) rectharm(@skillTarget, 0, 1, AdjustAttackpower(.@PW/2), HARM_PHYS, Ele_Neutral); break; //////////////////////////////// // CLASS_OTHER case TMW2_PARUM: SK_parum(); break; case TMW2_DEMURE: SK_Demure(); break; case TMW2_DRAGOKIN: SK_Dragokin(); break; // Summons which never fail case TMW2_ZARKOR: alignment_cansummon(); SummonMagic(@skillId, CaveMaggot, 2, @skillLv); GetManaExp(@skillId, 1); break; // Summons which may fail case TMW2_KALWULF: SK_summon(Wolvern, 4, any(3,4)); break; case TMW2_KALBOO: SK_summon(Mouboo, 4, any(2,3)); break; case TMW2_KALSPIKE: SK_summon(PoisonSpikyMushroom, 4, any(2,3)); break; case TMW2_CUTEHEART: SK_summon(Fluffy, 4, any(2,3)); break; // Slightly more complex summons case TMW2_LIMERIZER: SK_summon(any(GreenSlime,AzulSlime,RedSlime,AngryYellowSlime), 2, any(3,4)); break; case TMW2_FAIRYKINGDOM: SK_summon(any(FireFairy, EarthFairy, WaterFairy, WindFairy, PoisonFairy), 4, any(3,4)); break; case TMW2_FAIRYEMPIRE: SK_summon(any(VanityPixie, HolyPixie, ShadowPixie, NulityPixie), 5, any(4,5)); break; // More complex summons case TMW2_KALMURK: .@mobId=Maggot; SK_summon(.@mobId, (.@mobId == Maggot ? 2 : 4), any(1,2)); break; case TMW2_HALHISS: .@mobId=Snake; SK_summon(.@mobId, 4, any(3,4)); break; case TMW2_FROZENHEART: .@mobId=Moggun; if (rand2(6,12) < abizit()+1) { .@mobId=Yeti; } SK_summon(.@mobId, 4, any(3,4)); break; case TMW2_STONEHEART: .@mobId=Terranite; if (rand2(9,12) < abizit()+1 && BaseLevel > 80) { .@mobId=TerraniteProtector; } SK_summon(.@mobId, 4, any(4,5)); break; case TMW2_DUCKY: .@mobId=Duck; SummonMagic(@skillId, .@mobId, 2); GetManaExp(@skillId, 1); break; */ // Experience only default: GetManaExp(@skillId, 1); break; } // Debug if ($@GM_OVERRIDE) debugmes "Cast skill %d on level %d - Target %d", @skillId, @skillLv, @skillTarget; // Cleanup (double-safe) @skillTarget = 0; return; } // HUB_PCBonus () function script HUB_PCBonus { /* Passive Skills */ if (FOCUSING & FSKILL_ASTRAL_SOUL) { bonus bMatk, 9*getskilllv(SKILL_ASTRAL_SOUL); } if (FOCUSING & FSKILL_RAGING) { bonus bCritical, 2*getskilllv(SKILL_RAGING); } if (FOCUSING & FSKILL_SPEED) { bonus bSpeedAddRate, 1*getskilllv(SKILL_SPEED); bonus bAspd, 2*getskilllv(SKILL_SPEED); } if (FOCUSING & FSKILL_RESIST_POISON) { .@l=5*getskilllv(SKILL_RESIST_POISON); bonus2(bResEff, Eff_Silence, .@l); bonus2(bResEff, Eff_Poison, .@l); bonus2(bResEff, Eff_Curse, .@l); bonus2(bResEff, Eff_Blind, .@l); } if (FOCUSING & FSKILL_BRAWLING) { if (getequipid(EQI_HAND_R) < 1) { bonus bAtk, 10*getskilllv(SKILL_BRAWLING); } else if (getiteminfo( getequipid(EQI_HAND_R), ITEMINFO_SUBTYPE) == W_FIST) { bonus bAtk, 10*getskilllv(SKILL_BRAWLING); } } if (FOCUSING & FSKILL_MALLARDS_EYE) { bonus bAtkRange, (1+getskilllv(SKILL_MALLARDS_EYE))/2; bonus bHit, 5*getskilllv(SKILL_MALLARDS_EYE); } return; }