summaryrefslogtreecommitdiff
path: root/npc/006-7
diff options
context:
space:
mode:
authorJesusaves <cpntb1@ymail.com>2022-10-23 21:44:22 -0300
committerJesusaves <cpntb1@ymail.com>2022-10-23 21:44:22 -0300
commita7c45a192268da2601cef47a4cdba987ae2327ca (patch)
treec5fb5b97db109fe7106496dd96498c475881046b /npc/006-7
downloadserverdata-a7c45a192268da2601cef47a4cdba987ae2327ca.tar.gz
serverdata-a7c45a192268da2601cef47a4cdba987ae2327ca.tar.bz2
serverdata-a7c45a192268da2601cef47a4cdba987ae2327ca.tar.xz
serverdata-a7c45a192268da2601cef47a4cdba987ae2327ca.zip
Initial commit (Moubootaur Legends fork)
Diffstat (limited to 'npc/006-7')
-rw-r--r--npc/006-7/_import.txt3
-rw-r--r--npc/006-7/ctrl.txt354
2 files changed, 357 insertions, 0 deletions
diff --git a/npc/006-7/_import.txt b/npc/006-7/_import.txt
new file mode 100644
index 0000000..87e9595
--- /dev/null
+++ b/npc/006-7/_import.txt
@@ -0,0 +1,3 @@
+// Map 006-7: Aethyr Chamber
+// This file is generated automatically. All manually added changes will be removed when running the Converter.
+"npc/006-7/ctrl.txt",
diff --git a/npc/006-7/ctrl.txt b/npc/006-7/ctrl.txt
new file mode 100644
index 0000000..17243b5
--- /dev/null
+++ b/npc/006-7/ctrl.txt
@@ -0,0 +1,354 @@
+// TMW2 Script
+// Author:
+// Jesusalva
+
+006-7 mapflag zone MMO
+
+006-7,44,50,0 script #OutOf0067 NPC_HIDDEN,0,0,{
+ end;
+
+OnTouch:
+ if (!$@ICICLE_CHALLENGE)
+ warp "006-6", 40, 36;
+ end;
+
+OnRw:
+ getexp 1000000, 0;
+ Mobpt += 10000;
+ dispbottom l("Der Schneemann has been defeated: %s Monster Points gained.", fnum(10000));
+ RegEasterEgg(EE_SNOWMAN, 25);
+ specialeffect(FX_FANFARE, SELF, getcharid(3));
+ end;
+}
+
+006-7,44,35,0 script Ice Lord NPC_YETIFLY,{
+ if ($@ICICLE_CHALLENGE) end;
+ if (.ticks > gettimetick(2)) {
+ mesn;
+ mesq l("This challenge will be available in %s. Please wait until then.", FuzzyTime(.ticks));
+ close;
+ }
+ mesn;
+ mesq l("With Magic and Blades, The Icicle shall break. Do you undertake the challenge?");
+ mesc l("Advised: 6+ players"), 1;
+ mesc l("Advised: 1+ mage, 1+ tanker, 2+ healers"), 1;
+ mesc l("Time Limit: 90 minutes"), 1;
+ mesc l("Enter/Leave after start: %s", b(l("NO"))), 1;
+ next;
+ select
+ l("Not yet."),
+ l("Bring it on!"),
+ rif(REBIRTH, l("Bring me, my worst nightmare."));
+ mes "";
+ if (@menu == 1) {
+ closeclientdialog;
+ close;
+ }
+ if (@menu == 2)
+ .hard = false;
+ else
+ .hard = true;
+
+ // Der Schneemann
+ .ticks = gettimetick(2) + 5400; // 90 minutes
+ .BOSS = monster("006-7", 44, 36, "The Icicle", SnowmanBoss, 1);
+ .@mlt = (.hard ? 15 : 10);
+
+ // Basic attributes
+ setunitdata(.BOSS, UDT_MAXHP, 750000 * .@mlt / 10); // 750k ~ 1250k
+ setunitdata(.BOSS, UDT_HP, 750000 * .@mlt / 10);
+ setunitdata(.BOSS, UDT_ATKRANGE, (.hard ? 7 : 6));
+
+ // Reconfigure the AI
+ .@opt=getunitdata(.BOSS, UDT_MODE);
+ // Disable looting
+ if (.@opt & MD_LOOTER)
+ .@opt=.@opt^MD_LOOTER;
+ // Add knockback immunity
+ .@opt=.@opt|MD_NOKNOCKBACK;
+ // Mark as boss
+ .@opt=.@opt|MD_BOSS;
+ // Mark as aggressive
+ .@opt=.@opt|MD_AGGRESSIVE;
+ .@opt=.@opt|MD_ANGRY;
+ // Make it more op
+ .@opt=.@opt|MD_DETECTOR;
+ .@opt=.@opt|MD_CASTSENSOR_CHASE;
+ .@opt=.@opt|MD_CASTSENSOR_IDLE;
+ .@opt=.@opt|MD_CHANGECHASE;
+ .@opt=.@opt|MD_CHANGETARGET_MELEE;
+ .@opt=.@opt|MD_CHANGETARGET_CHASE;
+ setunitdata(.BOSS, UDT_MODE, .@opt);
+
+ // Nerf the damage, but never miss a hit
+ setunitdata(.BOSS, UDT_ATKMIN, 60 * .@mlt / 10); // 60~90 dmg
+ setunitdata(.BOSS, UDT_ATKMAX, 60 * .@mlt / 10);
+ setunitdata(.BOSS, UDT_ADELAY, 2220 / .@mlt * 10); // 2220 or 1480ms
+ setunitdata(.BOSS, UDT_HIT, 2400);
+
+ // Boosting the defense is not necessary
+ // It nerfs weapons to 40% (bows to 20%)
+ // Then it resists 50% of Neutral element.
+ // Note it is strong against Water (25% dmg)
+ // And weak against Fire (snow) and Wind (100% dmg)
+ // Otherwise, behave as Ghost element
+
+ $@ICICLE_CHALLENGE = true;
+ disablenpc .name$;
+ initnpctimer;
+ closeclientdialog;
+ close;
+
+// Fail-safe Mechanism (will never happen)
+OnTimer60000:
+ consolebug("Warning! final fail-safe mechanism triggered to Icicle.");
+ initnpctimer;
+ end;
+OnTimer25000:
+OnTimer15000:
+ consolewarn("Warning, fail-safe mechanism triggered to Icicle.");
+// This is the boss' core
+OnTimer5000:
+ /* Maybe the fight is over */
+ if (!mobcount("006-7", "all"))
+ maptimer2("006-7", 10, "#OutOf0067::OnRw");
+ if (.ticks < gettimetick(2) || !mobcount("006-7", "all") || !getmapusers("006-7")) {
+ killmonsterall("006-7");
+ enablenpc .name$;
+ npctalk "The battle is over!";
+ .ticks = min(.ticks, gettimetick(2) + 1800); // Min. Cooldown: 30 min
+ .beats = 0;
+ .warn = 0;
+ $@ICICLE_CHALLENGE = false;
+ stopnpctimer;
+ end;
+ }
+
+ /* Warn players when time is about to end */
+ if (.ticks - 1800 < gettimetick(2) && .warn < 1) {
+ mapannounce("006-7", "Warning : ##1##BTime left: 30 minutes##b", 0);
+ .warn = 1;
+ }
+ else if (.ticks - 900 < gettimetick(2) && .warn < 2) {
+ mapannounce("006-7", "Warning : ##1##BTime left: 15 minutes##b", 0);
+ .warn = 2;
+ }
+ else if (.ticks - 600 < gettimetick(2) && .warn < 3) {
+ mapannounce("006-7", "Warning : ##1##BTime left: 10 minutes##b", 0);
+ .warn = 3;
+ }
+ else if (.ticks - 300 < gettimetick(2) && .warn < 4) {
+ mapannounce("006-7", "Warning : ##1##BTime left: 5 minutes##b", 0);
+ .warn = 4;
+ }
+
+ /* Prepare some data */
+ .@hp = getunitdata(.BOSS, UDT_HP) * 10 / getunitdata(.BOSS, UDT_MAXHP);
+ getmapxy(.@m$, .@x, .@y, UNITTYPE_MOB, .BOSS);
+ .@c=getunits(BL_PC, .@pcs, MAX_CYCLE_PC, .@m$);
+ .@mvp=0;.@rnd=0;.@def=-1;
+ for (.@i = 0; .@i < .@c; .@i++) {
+ if (!.@rnd || !rand2(.@c))
+ .@rnd=.@pcs[.@i];
+ if (readbattleparam(.@pcs[.@i], UDT_DEF) > .@def) {
+ if (readparam(Hp, .@pcs[.@i]) < 1) continue;
+ .@mvp=.@pcs[.@i];
+ .@def=readbattleparam(.@pcs[.@i], UDT_DEF);
+ }
+ }
+ .beats += 1;
+
+ /* Everyone is dead, get rid of them */
+ if (!.@mvp || !.@rnd) {
+ mapwarp("006-7", "006-6", 40, 36);
+ initnpctimer;
+ end;
+ }
+
+ //debugmes "----------- Skill Loop, beat is %d", .beats % 18;
+ /* Decide the skill to use based on ~5s beats over 3 minutes */
+ switch (.beats % 18) {
+ // (1/6) Summon Reinforcements (every 60s)
+ case 0:
+ case 6:
+ case 12:
+ unittalk(.BOSS, "Come forth, ##Bsnow army##b, for the Icicle shall live forever!");
+ specialeffect(65, AREA, .BOSS); // Actually 64, but won't do well here
+ sleep(1000);
+ monster("006-7", 44, 22, strmobinfo(1, Snowman), Snowman, max(1, (11 - .@hp) / 10));
+ break;
+ // (2/6) Tanker (~30s)
+ case 1:
+ case 4:
+ case 7:
+ case 10:
+ case 13:
+ case 16:
+ specialeffect(702, AREA, .BOSS);
+ sleep(1000);
+ if (.@hp < 3) {
+ // Third Attack Pattern: Judgment
+ unittalk(.BOSS, sprintf("%s cannot stop me! ##BJudgment##b!", strcharinfo(0, "cursed player", .@mvp)));
+ .@PW=240; .@SPW=60; .@RG=3;
+ } else if (.@hp < 7) {
+ // Second Attack Pattern: Holy Light
+ unittalk(.BOSS, sprintf("%s, I'll show you no mercy! ##BHoly Light##b!", strcharinfo(0, "cursed player", .@mvp)));
+ .@PW=125; .@SPW=25; .@RG=1;
+ } else {
+ // First Attack Pattern: Napalm Beat
+ unittalk(.BOSS, sprintf("This battle is over, %s! ##BNapalm Beat##b!", strcharinfo(0, "cursed player", .@mvp)));
+ .@PW=35; .@SPW=5; .@RG=2;
+ }
+ .@mtk = calcdmg(.BOSS, .@mvp, HARM_MAGI);
+ .@dmg = .@mtk * .@PW / 100;
+ .@dsb = .@mtk * .@SPW / 100;
+ sleep(1000);
+ areaharm(.@mvp, .@RG, .@dsb, HARM_MAGI, Ele_Holy, "filter_always", BL_PC|BL_MER|BL_HOM);
+ harm(.@mvp, .@dmg, HARM_MAGI, Ele_Holy);
+ break;
+ // (3/6) Random Target (~60s)
+ case 2:
+ case 8:
+ case 14:
+ specialeffect(50, AREA, .BOSS);
+ sleep(1000);
+ .@time=rand2(18000, 36000) + 10000 - (.@hp * 1000);
+ // Switch between curse and disable
+ if (any(true,false)) {
+ unittalk(.BOSS, sprintf("I hereby ##Bcurse##b you, %s!", strcharinfo(0, "cursed player", .@rnd)));
+ sc_start(SC_CURSE, .@time, 1, 10000, SCFLAG_FIXEDRATE, .@rnd);
+ } else {
+ unittalk(.BOSS, sprintf("I shall ##Bdisable##b you, %s!", strcharinfo(0, "cursed player", .@rnd)));
+ sc_start(SC_BLIND, .@time / 2, 1, 10000, SCFLAG_FIXEDRATE, .@rnd);
+ sc_start(SC_SILENCE, .@time / 2, 1, 10000, SCFLAG_FIXEDRATE, .@rnd);
+ }
+ // Second pattern: Bleeding ON
+ if (.@hp < 7) {
+ sc_start(SC_BLOODING, 10000, 1, 9000-(.@hp*1000), SCFLAG_FIXEDRATE, .@rnd);
+ }
+ break;
+ // (4/6) Traps (~60s)
+ case 3:
+ case 9:
+ case 15:
+ .@x1=rand2(31, 58); .@x2=rand2(31, 58); .@x3=rand2(31, 58);
+ .@y1=rand2(23, 49); .@y2=rand2(23, 49); .@y3=rand2(23, 49);
+ .@t1=monster("006-7", .@x1, .@y1, "", Dummy, 1);
+ .@t2=monster("006-7", .@x2, .@y2, "", Dummy, 1);
+ .@t3=monster("006-7", .@x3, .@y3, "", Dummy, 1);
+ specialeffect(67, AREA, .@t1);
+ specialeffect(67, AREA, .@t2);
+ specialeffect(67, AREA, .@t3);
+ immortal(.@t1); immortal(.@t2); immortal(.@t3);
+ if (.@hp < 5 || .hard) {
+ .@x4=rand2(31, 58); .@x5=rand2(31, 58); .@x6=rand2(31, 58);
+ .@y4=rand2(23, 49); .@y5=rand2(23, 49); .@y6=rand2(23, 49);
+ .@t4=monster("006-7", .@x1, .@y1, "", Dummy, 1);
+ .@t5=monster("006-7", .@x2, .@y2, "", Dummy, 1);
+ .@t6=monster("006-7", .@x3, .@y3, "", Dummy, 1);
+ specialeffect(67, AREA, .@t4);
+ specialeffect(67, AREA, .@t5);
+ specialeffect(67, AREA, .@t6);
+ immortal(.@t4); immortal(.@t5); immortal(.@t6);
+ }
+ sleep(2000);
+ specialeffect(11, AREA, .@t1);
+ specialeffect(11, AREA, .@t2);
+ specialeffect(11, AREA, .@t3);
+ if (.@hp < 5 || .hard) {
+ specialeffect(11, AREA, .@t4);
+ specialeffect(11, AREA, .@t5);
+ specialeffect(11, AREA, .@t6);
+ }
+ areaharm(.@t1, 2, 450, HARM_MISC, Ele_Neutral, "filter_always", BL_PC|BL_MER|BL_HOM);
+ areaharm(.@t2, 2, 450, HARM_MISC, Ele_Neutral, "filter_always", BL_PC|BL_MER|BL_HOM);
+ areaharm(.@t3, 2, 450, HARM_MISC, Ele_Neutral, "filter_always", BL_PC|BL_MER|BL_HOM);
+ if (.@hp < 5 || .hard) {
+ areaharm(.@t4, 2, 450, HARM_MISC, Ele_Neutral, "filter_always", BL_PC|BL_MER|BL_HOM);
+ areaharm(.@t5, 2, 450, HARM_MISC, Ele_Neutral, "filter_always", BL_PC|BL_MER|BL_HOM);
+ areaharm(.@t6, 2, 450, HARM_MISC, Ele_Neutral, "filter_always", BL_PC|BL_MER|BL_HOM);
+ }
+ sleep(1000);
+ // FIXME: M+ fails to remove them, need @refresh
+ unitkill(.@t1); unitkill(.@t2); unitkill(.@t3);
+ if (.@hp < 5 || .hard) {
+ unitkill(.@t4); unitkill(.@t5); unitkill(.@t6);
+ }
+ break;
+ // (5/6) Weak AOE (~60s)
+ case 5:
+ case 11:
+ case 17:
+ specialeffect(60, AREA, .BOSS);
+ sleep(500);
+ switch (rand2(3)) {
+ case 1:
+ unittalk(.BOSS, "I shall ##Bpoison##b you all!");
+ .@sc = (.@hp < 1 ? SC_DPOISON : SC_POISON);
+ break;
+ case 2:
+ unittalk(.BOSS, "I shall ##Bhurt##b you all!");
+ .@sc = SC_BLOODING;
+ break;
+ case 3:
+ unittalk(.BOSS, "I shall ##Bsilence##b you all!");
+ .@sc = SC_SILENCE;
+ break;
+ default:
+ unittalk(.BOSS, "I shall ##Bcripple##b you all!");
+ .@sc = SC_BLIND;
+ break;
+ }
+ areasc((.hard ? 7 : 6), 45000, .@sc, BL_PC|BL_HOM|BL_MER, 1, "filter_always", .BOSS, 95000);
+ areaharm(.BOSS, (.hard ? 7 : 6), 100, HARM_MAGI, Ele_Water, "filter_always", BL_PC|BL_MER|BL_HOM);
+ break;
+ }
+ // Strong AOE: Every 3 minutes (case = 0)
+ // Stalls all other skills for a while
+ if (.beats % 18 == 0) {
+ specialeffect(66, AREA, .BOSS);
+ unittalk(.BOSS, "I am the Icicle, the immortal.");
+ sleep((.hard ? 1000 : 1500));
+ specialeffect(700, AREA, .BOSS);
+ unittalk(.BOSS, "You're no match for me, so...");
+ sleep((.hard ? 1000 : 1500));
+ specialeffect(700, AREA, .BOSS);
+ if (.@hp < 3) {
+ unittalk(.BOSS, "Perish! ##BSnowstorm##b!");
+ .@dmg=rand2(900, 1100);
+ areasc(3, 5000, SC_FREEZE, BL_PC|BL_HOM|BL_MER, 1, "filter_always", .BOSS, 2000);
+ areasc(6, 10000, SC_BLIND, BL_PC|BL_HOM|BL_MER, 1, "filter_always", .BOSS, 2000);
+ } else if (.@hp < 7) {
+ unittalk(.BOSS, "Perish! ##BBlizzard##b!");
+ .@dmg=rand2(650, 900);
+ areasc(3, 5000, SC_FREEZE, BL_PC|BL_HOM|BL_MER, 1, "filter_always", .BOSS, 1500);
+ } else {
+ unittalk(.BOSS, "Perish! ##BShattering Winds##b!");
+ .@dmg=rand2(400, 650);
+ }
+ /* Three blocks */
+ specialeffect(66, AREA, .BOSS);
+ areaharm(.BOSS, (.hard ? 7 : 6), .@dmg, HARM_MAGI, Ele_Neutral, "filter_always", BL_PC|BL_MER|BL_HOM);
+ sleep(500);
+ specialeffect(66, AREA, .BOSS);
+ areaharm(.BOSS, (.hard ? 18 : 12), .@dmg, HARM_MAGI, Ele_Water, "filter_always", BL_PC|BL_MER|BL_HOM);
+ sleep(500);
+ specialeffect(66, AREA, .BOSS);
+ specialeffect(312, AREA, .BOSS);
+ areaharm(.BOSS, (.hard ? 24 : 18), .@dmg, HARM_MAGI, Ele_Holy, "filter_always", BL_PC|BL_MER|BL_HOM);
+ areasc((.hard ? 24 : 18), .@dmg*rand2(50, 100), SC_FROSTMISTY, BL_PC|BL_HOM|BL_MER, 1, "filter_always", .BOSS, 10001 - (.@hp * 1000)); // FIXME
+ // SC_COLD freezes you, so trying SC_FROSTMISTY
+ }
+
+ initnpctimer;
+ end;
+
+OnInit:
+ .distance = 4;
+ .ticks = gettimetick(2);
+ .beats = 0;
+ .hard = 0;
+ .warn = 0;
+ end;
+}
+