summaryrefslogtreecommitdiff
path: root/npc/magic/final.txt
diff options
context:
space:
mode:
authorJesusaves <cpntb1@ymail.com>2021-04-11 08:38:20 -0300
committerJesusaves <cpntb1@ymail.com>2021-04-11 08:38:20 -0300
commited39c7518c82ede371b9b74f6eca8deb66a73e31 (patch)
treee6fe9662612df7fc4ec55e9ed32fd87c97ab93dc /npc/magic/final.txt
parentedf822b99c36c7bede00aef3202b2cbe42cde37b (diff)
downloadserverdata-ed39c7518c82ede371b9b74f6eca8deb66a73e31.tar.gz
serverdata-ed39c7518c82ede371b9b74f6eca8deb66a73e31.tar.bz2
serverdata-ed39c7518c82ede371b9b74f6eca8deb66a73e31.tar.xz
serverdata-ed39c7518c82ede371b9b74f6eca8deb66a73e31.zip
Fix bugs, prepare to implement the *real* skill loop
Diffstat (limited to 'npc/magic/final.txt')
-rw-r--r--npc/magic/final.txt464
1 files changed, 464 insertions, 0 deletions
diff --git a/npc/magic/final.txt b/npc/magic/final.txt
new file mode 100644
index 00000000..c64c9c95
--- /dev/null
+++ b/npc/magic/final.txt
@@ -0,0 +1,464 @@
+// 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 EVOL_AREA_PROVOKE:
+ if (@skillTargetX && @skillTargetY)
+ massprovoke(1+@skillLv, getmap(), @skillTargetX, @skillTargetY);
+ else
+ massprovoke(1+@skillLv);
+ // SC_PROVOKE ?
+ GetManaExp(@skillId, rand2(1,3));
+ 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, rand2(1,3));
+ 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, rand2(1,3));
+ break;
+ case TMW2_SUPREMEATTACK:
+ .@PW=100+(50*@skillLv);
+ harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
+ GetManaExp(@skillId, rand2(1,3));
+ break;
+ ////////////////////////////////
+ // XXX: Physical Class (Archery)
+ case TMW2_CHARGEDARROW:
+ .@PW=100+(50*@skillLv);
+ harm(@skillTarget, AdjustAttackpower(.@PW), HARM_PHYS, Ele_Neutral);
+ GetManaExp(@skillId, rand2(1,3));
+ 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, rand2(1,3));
+ 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;
+ if (abizit() > 4 &&
+ GHMEMO[GHQ_GetQuestIDByMonsterID(Maggot)] >= 10000 &&
+ MAGIC_LVL >= 3)
+ {
+ .@mobId=any(Maggot, Maggot, Maggot, Maggot, GiantMaggot);
+ }
+ SK_summon(.@mobId, (.@mobId == Maggot ? 2 : 4), any(1,2));
+ break;
+ case TMW2_HALHISS:
+ .@mobId=Snake;
+ if (abizit() > 3 &&
+ GHMEMO[GHQ_GetQuestIDByMonsterID(MountainSnake)] >= 10000 &&
+ rand2(1,3) == 2)
+ {
+ .@mobId=MountainSnake;
+ }
+ SK_summon(.@mobId, 4, any(3,4));
+ break;
+ case TMW2_FROZENHEART:
+ .@mobId=Moggun;
+ if (rand2(6,12) < (abizit()*2)+1)
+ {
+ .@mobId=Yeti;
+ }
+ SK_summon(.@mobId, 4, any(3,4));
+ break;
+ case TMW2_STONEHEART:
+ .@mobId=Terranite;
+ if (rand2(9,12) < (abizit()*2)+1 &&
+ BaseLevel > 80)
+ {
+ .@mobId=TerraniteProtector;
+ }
+ SK_summon(.@mobId, 4, any(4,5));
+ break;
+ case TMW2_DUCKY:
+ .@mobId=Duck;
+ .@q=getq(LilitQuest_PiratesOfSARAH);
+ if (!alignment_cansummon())
+ break;
+ if (abizit() > 4 &&
+ .@q > 2 &&
+ MAGIC_LVL >= 3)
+ {
+ // GHQ Complete: 33% chances
+ // Otherwise: 8% chances
+ if (GHMEMO[GHQ_GetQuestIDByMonsterID(Duck)] >= 10000)
+ .@mobId=any(Duck, Duck, EliteDuck);
+ else
+ .@mobId=any(Duck, Duck, Duck, Duck,
+ Duck, Duck, Duck, Duck,
+ Duck, Duck, Duck, EliteDuck);
+ }
+ SummonMagic(@skillId, .@mobId, 2);
+ GetManaExp(@skillId, 1);
+ break;
+
+ // Experience only
+ case KN_AUTOCOUNTER:
+ case SN_SHARPSHOOTING:
+ case HW_MAGICPOWER:
+ case SM_PROVOKE:
+ case SN_WINDWALK:
+ case SO_FIREWALK:
+ case TF_BACKSLIDING:
+ case MG_FIREWALL:
+ case ALL_FULL_THROTTLE:
+ case GC_DARKILLUSION:
+ case NV_TRICKDEAD:
+ GetManaExp(@skillId, rand2(1,3));
+ 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, 25*getskilllv(SKILL_ASTRAL_SOUL);
+ }
+ if (FOCUSING & FSKILL_RAGING) {
+ bonus bCritical, 5*getskilllv(SKILL_RAGING);
+ }
+ if (FOCUSING & FSKILL_SPEED) {
+ bonus bAspd, 5*getskilllv(SKILL_SPEED);
+ }
+ // MALLARD EYE handled by C code
+ // SKILL_BRAWLING SKILL_RESIST_POISON
+ return;
+}
+