// 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;
// Level 0
case SKILL_CONFRINGO:
SK_Confringo(); break;
// Level 1
case SKILL_ABIZIT:
SK_Abizit(); break;
case SKILL_MONSTERINFO:
SK_Miteyo(); break;
case EVOL_AREA_PROVOKE:
SK_Itenplz(); break;
case SKILL_FLAR:
SK_Flar(); break;
case SKILL_MODRIPHOO:
case SKILL_MODRISUMP:
case SKILL_MODRIYIKAM:
case SKILL_MODRILAX:
SK_GrowPlants(); break; // FIXME: Unreleased/cannot be learned
case SKILL_LUM:
SK_Lum(); break;
// Level 2
case SKILL_INMA:
SK_Inma(); break;
// Level 3
// Level 4
// Level 5
////////////////////////////////
/* 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;
}