// 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);
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;
}