// TMW2 scripts.
// Author:
// Jesusalva
// Description:
// The Impregnable Fortress Control Files - Boss Chamber - Final Showdown
026-7,39,34,0 script Impregnable#B7F NPC_HIDDEN,{
function _moveNpc;
end;
OnInit:
.MK=0;
.maxhp = 1000000; // 1,000,000 HP
.mana = 0; // More mana = more likely to cast skills
.immortal = true; // Set to FALSE when all four guardians are defeated
.memohp = 999; // Memorand HP, controls spawns
.mou = 0; // Temporary for Cutscene
.start_time = gettimetick(2); // Controls Death Touch
end;
// Maybe not OnTouch, but OnSit?
OnTouch:
if (strcharinfo(2) == "Monster King") end;
slide 39, 35;
percentheal -15,0;
dispbottom l("The throne is cursed, only the Monster King may sit on it.");
end;
function _moveNpc {
// Try to warp randomly, up to 30 attempts
.@e=0;
.@mx=getmapinfo(MAPINFO_SIZE_X, getarg(0))-20;
.@my=getmapinfo(MAPINFO_SIZE_Y, getarg(0))-20;
do {
if (.@e >= 30)
break;
.npc_x = rand2(20, .@mx);
.npc_y = rand2(20, .@my);
.@e+=1;
} while (!checknpccell(getarg(0), .npc_x, .npc_y, cell_chkpass));
return;
} // _moveNpc
// Controls the Event
// TODO: Intro Cutscene
OnBegin:
// Monster King is somewhere else, so nothing happens
if ($@MK_SCENE != MK_NONE)
end;
// Lock the MK in the showdown
$@MK_SCENE=MK_SHOWDOWN;
// Initial assortment of monsters
//siege_cast("026-7", .name$, 15, TP_TULIM|TP_HURNS|TP_NIVAL);
// Spawn the boss himself
.MK=monster("026-7", 39, 34, "The Monster King", MonsterKing, 1);
immortal(.MK); // Immortal until conditions are met
.immortal = true;
// Mana is mostly carried over between attempts, but no negatives
.mana = max(.mana, 0);
.memohp = 999; // Reset Memorand HP
// Reconfigure the AI
.@opt=getunitdata(.MK, UDT_MODE);
// 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(.MK, UDT_MODE, .@opt);
setunitdata(.MK, UDT_RACE, RC_Legendary);
// The Four Generals which command his immortality
.GUARD1=monster("026-7", 35, 30, "Air General", MonsterGeneral, 1);
.GUARD4=monster("026-7", 44, 45, "Fire General", MonsterGeneral, 1);
.GUARD3=monster("026-7", 35, 45, "Earth General", MonsterGeneral, 1);
.GUARD2=monster("026-7", 44, 30, "Darkness General", MonsterGeneral, 1);
// Boost these four generals or they'll become cheese too fast
// Also, fix their elementals, but they have no elemental skills to speak of.
setunitdata(.GUARD1, UDT_HP, 60000);
setunitdata(.GUARD1, UDT_MAXHP, 60000);
setunitdata(.GUARD2, UDT_HP, 60000);
setunitdata(.GUARD2, UDT_MAXHP, 60000);
setunitdata(.GUARD3, UDT_HP, 60000);
setunitdata(.GUARD3, UDT_MAXHP, 60000);
setunitdata(.GUARD4, UDT_HP, 60000);
setunitdata(.GUARD4, UDT_MAXHP, 60000);
setunitdata(.GUARD1, UDT_ELETYPE, Ele_Wind);
setunitdata(.GUARD2, UDT_ELETYPE, Ele_Dark);
setunitdata(.GUARD4, UDT_ELETYPE, Ele_Fire);
setunitdata(.GUARD3, UDT_ELETYPE, Ele_Earth);
setunitdata(.GUARD1, UDT_RACE, RC_Legendary);
setunitdata(.GUARD2, UDT_RACE, RC_Legendary);
setunitdata(.GUARD3, UDT_RACE, RC_Legendary);
setunitdata(.GUARD4, UDT_RACE, RC_Legendary);
// The remainder of MK army (Centered at the generals / 20 total)
.@x = 35; .@y = 30; areamonster("026-7", .@x-3, .@y-3, .@x+3, .@y+3, "Air Officer", Reaper, 5); // Air Troops
.@x = 44; .@y = 45; areamonster("026-7", .@x-3, .@y-3, .@x+3, .@y+3, "Fire Officer", LavaSkullSlime, 6); // Fire Troops
.@x = 35; .@y = 45; areamonster("026-7", .@x-3, .@y-3, .@x+3, .@y+3, "Earth Officer", Snail, 5); // Earth Troops
.@x = 44; .@y = 30; areamonster("026-7", .@x-3, .@y-3, .@x+3, .@y+3, "Darkness Officer", NightmareDragon, 5); // Darkness Troops
// Monster King Personal Bodyguard is special (4 total)
for (.@i = 0; .@i < 4; ++.@i) {
areamonster("026-7", 37, 32, 41, 36, "Imperial Officer", any(VanityPixie, HolyPixie, ShadowPixie, NulityPixie, BlackSkullSlime, PinkieSuseran), 1);
}
// General ranged troops / Artillery (20 total)
areamonster("026-7", 30, 30, 45, 45, "Ranged Support", RobinBandit, 12);
areamonster("026-7", 30, 30, 45, 45, "Ranged Support", DustRevolver, 5);
areamonster("026-7", 30, 30, 45, 45, "Ranged Support", DustRifle, 3);
initnpctimer;
end;
OnMFDispose:
if (ispcdead() || getq(General_Fortress) < 6) warp("025-2", 100, 27);
// Summons, for a whole minute, an allied solider (0.1% per siege won)
if (rand2(1000) < $MK_TEMPVAR)
summon("Allied Guard", any(FallenGuard1, FallenGuard2, FallenGuard3));
end;
// Fail-safe Mechanism (will never happen)
OnTimer60000:
consolebug("Warning! final fail-safe mechanism triggered to Monster King.");
initnpctimer;
end;
// Run every 10 seconds
OnTimer25000:
OnTimer15000:
consolewarn("Warning, fail-safe mechanism triggered to Monster King.");
OnTimer10000:
maptimer2("026-7", 10, "Impregnable#B7F::OnMFDispose");
.mana += (.immortal ? 1 : 2); // Recover mana
/* Regeneration & Defeat Loop */
.@end = false;
if (.immortal)
setunitdata(.MK, UDT_HP, INT_MAX);
if (!getmapusers("026-7")) {
if (.immortal) {
.@end = true;
} else {
.@hp = getunitdata(.MK, UDT_HP);
.@mh = .maxhp;
.@hp = max(.@mh, .@hp + (.@mh / 500)); // Regenerates 0.2% HP
// Regeneration
setunitdata(.MK, UDT_HP, .@hp);
// Fully healed, players lost
if (.@hp >= .@mh)
.@end = true;
}
}
/* Maybe the fight is over */
if (!mobcount("026-7", "all") || getunittype(.MK) < 0) {
$@MK_SCENE = MK_NONE;
$@MK_CHALLENGE=false;
killmonsterall("026-7");
enablenpc .name$;
if (!.@end) {
// This is not due to full health! We actually won!
kamibroadcast("The MONSTER KING has been DEFEATED!", "WORLD HEART");
if ($GAME_STORYLINE != 5)
goto L_NextAct;
// Will not be cast if L_NextAct is summoned
maptimer2("026-7", 10, "Impregnable#B7F::OnVictory");
} else {
// We actually lost?!
kamibroadcast("The MONSTER KING has WON the showdown!", "WORLD HEART");
}
stopnpctimer;
//end;
goto OnPrepBlight;
}
/* Prepare some combat data */
getmapxy(.@m$, .@x, .@y, UNITTYPE_MOB, .MK);
.@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);
}
}
/* Everyone is dead, get rid of their corpses and loop over */
if (!.@mvp || !.@rnd) {
mapwarp("026-7", "025-2", 100, 27);
initnpctimer;
end;
}
/* Maybe he lost his immortality */
if (.immortal) {
if (getunittype(.GUARD1) < 0 &&
getunittype(.GUARD2) < 0 &&
getunittype(.GUARD3) < 0 &&
getunittype(.GUARD4) < 0) {
.immortal = false;
kamibroadcast("The Monster King has lost his immortality.", "Monster King");
setunitdata(.MK, UDT_HP, .maxhp);
setunitdata(.MK, UDT_MAXHP, .maxhp);
.mana += 25;
.start_time = gettimetick(2);
}
}
/* Spawn every 20% HP lost, using siege logic 'cause lazy */
if (!.immortal) {
.@hp = getunitdata(.MK, UDT_HP) * 5 / .maxhp;
if (.@hp < .memohp) {
.memohp = .@hp;
.mana += 25;
siege_cast("026-7", .name$, 35, TP_TULIM|TP_HURNS|TP_NIVAL);
}
// If Monster King is taking too much damage and too fast, throttle players
// Aegis Shield, however, provides immunity to this
if (.@hp <= 2 && .start_time < gettimetick(2) + 180) {
unittalk(.MK, "Death touch!");
maptimer2("026-7", 10, "Impregnable#B7F::OnDeathTouch");
.start_time = gettimetick(2) + 180; // This only happens once
}
}
/* Decide whenever the Monster King will use a skill. */
// Each Mana point is worth 1% chance. He gains 6 points per minute. (12 later)
// (While immortal, each mana point is worth 0.5% chance)
if (rand2(.immortal ? 200 : 100) <= .mana) {
.mana -= 5; // Mana cost for skill use. It can go negative
// Give players 500ms to prepare
specialeffect(FX_SPECIAL, AREA, .MK);
sleep(500);
// Initialization
.@skill = rand2(25); .@mob = .MK; .@msg$ = ""; .@lv = 120; .@t = rand2(15);
// Skills taken from Blanc, Terogan and Moubootaur (Sealed)
switch (.@skill) {
case 1:
.@msg$ = sprintf("Witness my sublime rain of death. Regeneration!");
.@hp=getunitdata(.@mob, UDT_HP);
.@mp=getunitdata(.@mob, UDT_MAXHP);
.@hp = max(.@mp, .@hp + (.@mp / 250)); // Regenerates 0.4% HP
setunitdata(.@mob, UDT_HP, min(.@hp, .@mp));
.@mobid=(rand2(.@lv) > 50 ? DeathCat : GreenSlime);
monster(.@m$, .@x, .@y, strmobinfo(1, .@mobid), .@mobid, 1);
break;
case 2:
.@msg$ = sprintf("Chaos shall be my founding stone! Falling star!");
attachrid(.@rnd);
percentheal -5, -10;
detachrid();
.@mobid=(rand2(.@lv) > 50 ? BlackScorpion : RedSlime);
monster(.@m$, .@x, .@y, strmobinfo(1, .@mobid), .@mobid, 1);
break;
case 3:
.@msg$ = sprintf("I demand this world! Tyranny!");
attachrid(.@rnd);
percentheal -1, -1;
SC_Bonus(.@t, any(SC_BLIND, SC_POISON), 1);
detachrid();
.@mobid=(rand2(.@lv) > 50 ? DarkLizard : Assassin);
monster(.@m$, .@x, .@y, strmobinfo(1, .@mobid), .@mobid, 1);
break;
case 4:
.@msg$ = sprintf("Stop on your tracks, unfair being! Freeze!");
attachrid(.@rnd);
SC_Bonus((.@t / 2), any(SC_FREEZE, SC_SLEEP, SC_SLEEP, SC_SLEEP), 1);
detachrid();
.@mobid=(rand2(.@lv) > 50 ? BlueSlime : WhiteSlime);
monster(.@m$, .@x, .@y, strmobinfo(1, .@mobid), .@mobid, 1);
break;
case 5:
.@msg$ = sprintf("There is no free speech. Censorship!");
attachrid(.@rnd);
SC_Bonus(.@t, SC_SILENCE, 1);
detachrid();
.@mobid=(rand2(.@lv) > 50 ? Thug : RedMushroom);
monster(.@m$, .@x, .@y, strmobinfo(1, .@mobid), .@mobid, 1);
break;
case 6:
.@msg$ = sprintf("And then... There was a quake. And all life died. Bleed!");
attachrid(.@rnd);
SC_Bonus(.@t, SC_BLOODING, 1);
detachrid();
.@mobid=(rand2(.@lv) > 50 ? BlackSlime : OldSnake);
monster(.@m$, .@x, .@y, strmobinfo(1, .@mobid), .@mobid, 1);
break;
case 7:
.@msg$ = sprintf("Puny mortal, do your best to entertain me! Curse!");
attachrid(.@rnd);
SC_Bonus(.@t, SC_CURSE, 1);
detachrid();
.@mobid=(rand2(.@lv) > 50 ? FireSkull : Skeleton);
monster(.@m$, .@x, .@y, strmobinfo(1, .@mobid), .@mobid, 1);
break;
case 8:
.@msg$ = sprintf("The problem with typos is - unpredictable side effects.");
attachrid(.@rnd);
SC_Bonus(.@t, any(SC_SILENCE, SC_CURSE, SC_FREEZE, SC_BLOODING, SC_BLIND, SC_POISON, SC_DPOISON, SC_POISON, SC_BURNING, SC_SLEEP), 1);
detachrid();
.@mobid=(rand2(.@lv) > 50 ? Swashbuckler : Bluepar);
monster(.@m$, .@x, .@y, strmobinfo(1, .@mobid), .@mobid, 1);
break;
case 9:
mapannounce("026-7", "Monster King : ##BAncient Magic: Lag", 0);
areasc2("026-7", 39, 38, 20, 15000, SC_CONFUSION, BL_PC, 1);
break;
case 10:
mapannounce("026-7", "Monster King : ##BAncient Magic: Sleep", 0);
areasc2("026-7", 39, 38, 20, 15000, SC_SLEEP, BL_PC, 1);
break;
case 11:
mapannounce("026-7", "Monster King : ##BAncient Magic: Burning", 0);
areasc2("026-7", 39, 38, 20, 15000, SC_BURNING, BL_PC, 1);
break;
case 12:
mapannounce("026-7", "Monster King : ##BAncient Magic: Fear", 0);
areasc2("026-7", 39, 38, 20, 15000, SC_FEAR, BL_PC, 1);
break;
case 13:
.@msg$ = sprintf("##BAncient Magic: Obliterate");
rectharm(.MK, 7, 7, rand2(700, 900), HARM_MISC, Ele_Dark, "filter_always", BL_PC | BL_MER | BL_HOM);
break;
case 14:
.@msg$ = sprintf("##BAncient Magic: Terminate Homunculi");
rectharm(.MK, 14, 14, rand2(1500, 2500), HARM_MISC, Ele_Dark, "filter_always", BL_MER | BL_HOM);
break;
case 15:
mapannounce("026-7", "Monster King : ##BAncient Magic: Wizcat", 0);
for (.@i=0;.@i <= 2+rand2(7);.@i++) {
.@m=monster("026-7", rand2(30,50), rand2(30,45),
"Reinforcement", BlackCat, 1);
setunitdata(.@m, UDT_RACE, RC_Legendary);
}
break;
case 16:
mapannounce("026-7", "Monster King : ##BAncient Magic: Silencing Nuke", 0);
rectharm(.MK, 14, 14, rand2(450, 750), HARM_MISC, Ele_Dark, "filter_always", BL_PC | BL_MER | BL_HOM);
areasc2("026-7", 40, 35, 20, 15000, SC_SILENCE, BL_PC, 1);
break;
case 17:
// Second Attack Pattern: Holy Light (vs Tank)
.@msg$ = sprintf("%s, I'll show you no mercy! ##BThunder Bolt##b!", strcharinfo(0, "cursed player", .@mvp));
.@PW=125; .@SPW=25; .@RG=1;
.@mtk = calcdmg(.@mob, .@mvp, HARM_MAGI);
.@dmg = .@mtk * .@PW / 100;
.@dsb = .@mtk * .@SPW / 100;
sleep(1000);
specialeffect(FX_LIGHTNING, AREA, .@mvp);
areaharm(.@mvp, .@RG, .@dsb, HARM_MAGI, Ele_Wind, "filter_always", BL_PC|BL_MER|BL_HOM);
harm(.@mvp, .@dmg, HARM_MAGI, Ele_Holy);
break;
case 18:
.@msg$ = sprintf("Come forth, my minions! Wreak chaos and havoc!");
specialeffect(FX_MGWARP, AREA, .MK); // Maybe 65 would also work
sleep(1000);
// Default amount: Half players + 3
.@max = (getmapusers("026-7")/2) + 3;
// Keep boundaries: Never less than 1, never more than 10
.@max = limit(1, .@max, 10);
for (.@i=0; .@i < .@max; .@i++) {
.@mid = any(GoboBear, Centaur, BloodyMouboo, GreenSkullSlime, BlackMamba, JackO, Brainic, TerraniteProtector, Yeti, Reaper);
.@x = monster(.@m$, .@x, .@y, strmobinfo(1, .@mid), .@mid, 1);
set_aggro(.@x);
}
break;
case 19:
.@msg$ = sprintf("I shall ##Bdisable##b you, %s!", strcharinfo(0, "cursed player", .@mvp));
specialeffect(FX_SMOKE, AREA, .MK);
attachrid(.@mvp);
SC_Bonus(.@t, SC_SILENCE, 1);
SC_Bonus(.@t, SC_BLIND, 1);
SC_Bonus(.@t/3, SC_CURSE, 1);
detachrid();
break;
case 20:
// First Attack Pattern: Napalm Beat (vs MVP)
.@msg$ = sprintf("This battle is over, %s! ##BThunder Neddle##b!", strcharinfo(0, "cursed player", .@mvp));
.@PW=35; .@SPW=5; .@RG=2;
.@mtk = calcdmg(.@mob, .@mvp, HARM_MAGI);
.@dmg = .@mtk * .@PW / 100;
.@dsb = .@mtk * .@SPW / 100;
sleep(1000);
specialeffect(FX_LIGHTNING, AREA, .@mvp);
areaharm(.@mvp, .@RG, .@dsb, HARM_MAGI, Ele_Wind, "filter_always", BL_PC|BL_MER|BL_HOM);
harm(.@mvp, .@dmg, HARM_MAGI, Ele_Holy);
break;
case 21:
.@msg$ = sprintf("##BMagic: Armageddon");
rectharm(.MK, 6, 6, rand2(300, 500), HARM_MAGI, Ele_Fire, "filter_always", BL_PC | BL_MER | BL_HOM);
break;
case 22:
.mana += 1;
.@msg$ = sprintf("##BMagic: Tempest");
rectharm(.MK, 3, 3, rand2(200, 300), HARM_MAGI, Ele_Wind, "filter_always", BL_PC | BL_MER | BL_HOM);
break;
case 23:
.@msg$ = sprintf("##BMagic: Gaia Break");
sc_start SC_INCDEFRATE, 15000, 10, .MK;
rectharm(.MK, 2, 5, rand2(250, 350), HARM_MAGI, Ele_Earth, "filter_always", BL_PC | BL_MER | BL_HOM);
break;
case 24:
.@msg$ = sprintf("##BMagic: Ground Strike");
.@EF=any(SC_STUN, SC_BLIND, SC_BLOODING, SC_BLIND, SC_BLOODING);
areasc2("026-7", .@x, .@y, 3, 12000, .@EF, BL_PC, 1);
rectharm(.MK, 3, 3, rand2(250, 350), HARM_PHYS, Ele_Neutral, "filter_always", BL_PC | BL_MER | BL_HOM);
break;
// TODO: Skills which manipulate the map or weather
default:
.@mx=55; .@my=55; .@x=22; .@y=22;
.@x1=rand2(.@mx, .@x); .@x2=rand2(.@mx, .@x); .@x3=rand2(.@mx, .@x);
.@y1=rand2(.@my, .@y); .@y2=rand2(.@my, .@y); .@y3=rand2(.@my, .@y);
.@x4=rand2(.@mx, .@x); .@x5=rand2(.@mx, .@x);
.@y4=rand2(.@my, .@y); .@y5=rand2(.@my, .@y);
// TODO: Maybe replace Dummy/EnergyBall with an invisible monster/FX?
.@t1=monster("026-7", .@x1, .@y1, "", Dummy, 1);
.@t2=monster("026-7", .@x2, .@y2, "", Dummy, 1);
.@t3=monster("026-7", .@x3, .@y3, "", Dummy, 1);
.@t4=monster("026-7", .@x4, .@y4, "", Dummy, 1);
.@t5=monster("026-7", .@x5, .@y5, "", Dummy, 1);
specialeffect(67, AREA, .@t1);
specialeffect(67, AREA, .@t2);
specialeffect(67, AREA, .@t3);
specialeffect(67, AREA, .@t4);
specialeffect(67, AREA, .@t5);
immortal(.@t1); immortal(.@t2); immortal(.@t3);
immortal(.@t4); immortal(.@t5);
sleep(1500); // Saw a pillar? RUN!
specialeffect(FX_LIGHTNING, AREA, .@t1);
specialeffect(FX_LIGHTNING, AREA, .@t2);
specialeffect(FX_LIGHTNING, AREA, .@t3);
specialeffect(FX_LIGHTNING, AREA, .@t4);
specialeffect(FX_LIGHTNING, AREA, .@t5);
sleep(500);
specialeffect(FX_CRITICAL, AREA, .@t1);
specialeffect(FX_CRITICAL, AREA, .@t2);
specialeffect(FX_CRITICAL, AREA, .@t3);
specialeffect(FX_CRITICAL, AREA, .@t4);
specialeffect(FX_CRITICAL, AREA, .@t5);
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);
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);
sleep(1000);
// FIXME: M+ fails to remove them, need @refresh (maybe @refreshall?)
// NOTE: The effect Nº 67 (halo circle) is also not cleaned by M+
unitkill(.@t1); unitkill(.@t2);
unitkill(.@t4); unitkill(.@t5);
break;
}
if (.@msg$ != "")
unittalk(.@mob, .@msg$);
}
// Restart the endless loop
initnpctimer;
end;
OnDeathTouch:
if (strcharinfo(0) == $AEGIS_HOLDER$) end;
SC_Bonus(30, SC_BLIND, 1);
SC_Bonus(20, SC_SILENCE, 1);
SC_Bonus(10, SC_CURSE, 1);
// Consume some mana
if (islegendary())
percentheal 0, -10;
else
percentheal 0, -25;
end;
// Monster King was defeated - game won
L_NextAct:
$@MK_SCENE=MK_CUTSCENE;
$GAME_STORYLINE=5;
$MANA_BLVL-=10; // Set base level to 5~15
$MANA_BLVL=max(0, $MANA_BLVL);
// Thanksgiving event no longer happens after Monster King dies
if ($EVENT$ == "Thanksgiving") {
kamibroadcast("Thanksgiving ended!");
sClear();
$EVENT$="";
}
donpcevent "sThankAeros::OnTimer90000";
// XXX Cutscene
sleep(3000);
.mou = monster("026-7", 39, 37, "Moubootaur", MobMoubootaur, 1);
immortal(.mou);
sc_start(SC_STUN, 90000, 1, 10000, SCFLAG_NOAVOID|SCFLAG_FIXEDTICK, .mou);
maptimer2("026-7", 30, "Book#FoS::OnMFShake");
sleep(3000);
unittalk(.mou, "##1I'm free... At least!");
sleep(6500);
unittalk(.mou, "##1The blood in the Heart, as the prophecy foretold!");
sleep(4500);
maptimer2("026-7", 30, "Book#FoS::OnMFShake");
sleep(30);
unittalk(.mou, "##1All monsters, heed my command! ##BHostile Takeover!##b");
sleep(1500);
freeloop(true);
for (.@i=0; .@i < 25; .@i++) {
.@m = areamonster("026-7", 20, 20, 55, 55, "Subjugated Monster", any(PinkieEmperor, PanthomLord, TerraniteKing, YetiKing, PsiConscience, DemureSecondForm, Luvia, Birb, MonsterGeneral, MonsterColonel, LavaSlimeMother, BlackSlimeMother, WanderingShadow, BanditLord, HoodedAssassin, SpiderQueen, NightScorpion, SaxsoGhost, GiantMutatedBat), 1);
immortal(.@m); // Broken?
sc_start(SC_STUN, 90000, 1, 10000, SCFLAG_NOAVOID|SCFLAG_FIXEDTICK, .@m);
sleep(200); // 5 s
}
freeloop(false);
sleep(3000);
unittalk(.mou, "##1My children, ##BArise!##b");
sleep(1500);
freeloop(true);
for (.@i=0; .@i < 25; .@i++) {
.@m = areamonster("026-7", 20, 20, 55, 55, "Subjugated Monster", any(Moubi, Moubi, Moubi, MoubooSlime, GreatMoubooSlime, Mouboo, Mouboo, EasterMouboo, AlphaMouboo, Shrewboo, BloodyMouboo), 1);
immortal(.@m);
sc_start(SC_STUN, 90000, 1, 10000, SCFLAG_NOAVOID|SCFLAG_FIXEDTICK, .@m);
sleep(160); // 4 s
}
freeloop(false);
sleep(3000);
unittalk(.mou, "##1I have taken over the World Heart... Your chances are forfeit.");
sleep(6000);
unittalk(.mou, "##1But first, I'll make a Monster King puppet.");
sleep(2000);
.@m = monster("026-7", 39, 34, "Monster King (puppet)", MonsterKing, 1);
immortal(.@m);
sc_start(SC_STUN, 90000, 1, 10000, SCFLAG_NOAVOID|SCFLAG_FIXEDTICK, .@m);
sleep(3000);
unittalk(.mou, "##1Now, it would be inconvenient if you were to disturb me while I work...");
sleep(6000);
unittalk(.mou, "##1It'll take several days or even months to corrupt the Heart. Can't be bothered.");
sleep(8000);
unittalk(.mou, "##1Enjoy your final days while you can. The day on which everything will be a Mouboo is upon us!");
sleep(5000);
maptimer2("026-7", 10, "Impregnable#B7F::OnVictory");
// Cleanup
sleep(10000);
$@MK_SCENE=MK_NONE;
killmonsterall("026-7");
.mou = 0;
// This disables all mosnters :<
//setbattleflag("monster_ai", 0x209);
//setbattleflag("monster_active_enable", false);
//setbattleflag("mob_count_rate", 25);
//charcommand("@reloadbattleconf"); // Careful!
//donpcevent("@exprate::OnReload");
//donpcevent("@droprate::OnReload");
//end;
goto OnPrepBlight;
OnVictory:
// Not killed by a player? It doesn't counts, then
if (!playerattached())
end;
// Prizes
Mobpt += 165;
getitem StrangeCoin, 50;
if (!MK_WINNER) {
MK_WINNER=gettimetick(2); // TODO
getitem StrangeCoin, 1950; // Total: 2,000 Strange Coins on first win
getitembound MysteriousFruit, 3, 4; // You get 3 char bound fruits
getexp 0, 250000; // 250k job exp on first victory
}
// Effects
specialeffect(FX_FANFARE, SELF, getcharid(3));
// Bailout
sleep2(5000);
warp "025-1", 99, 22;
close;
OnPrepBlight:
if ($SHADY_HOLDER$ != "") end;
.@c=getunits(BL_PC, .@pcs, MAX_CYCLE_PC, "026-7");
.@mvp=0;.@def=-1;
for (.@i = 0; .@i < .@c; .@i++) {
.@atk = readbattleparam(.@pcs[.@i], UDT_ATKMAX);
if (.@atk > .@def) {
// Lets check if they qualify
attachrid(.@pcs[.@i]);
if (islegendary()) .@atk=false; // Already legendary, so nope
if (ispcdead()) .@atk=false; // Dead, so nope
if (!checkweight(Blightbringer, 1)) .@atk=false; // Overweight, so nope
detachrid();
// They qualify: Remember this, and look for someone worthier
if (.@atk) {
.@mvp=.@pcs[.@i];
.@def=.@atk;
}
} // if qualified
} // for Loop
if (.@mvp) {
attachrid(.@mvp);
addtimer(10, "Impregnable#B7F::OnBlightbringer");
}
end;
OnBlightbringer:
// Repeat all checks
if ($SHADY_HOLDER$ != "") end;
if (islegendary()) end;
if (ispcdead()) end;
inventoryplace Blightbringer, 1;
$SHADY_HOLDER$ = strcharinfo(0);
getitembound Blightbringer, 1, 1; // Account bound or char bound? (1 or 4)
dispbottom l("For defeating the Monster King, you've got the Legendary @@.", getitemlink(Blightbringer));
dispbottom l("This item cannot be traded normally and is a Legendary Item.");
dispbottom l("You can transfer it with \"@grantpower\" command. Please contact a GM for more info.");
dispbottom l("Protip: If you plan in selling it, it's adviseable to ask for GM mediation.");
end;
}
// Room Traps, only against players
026-7,0,0,0 script #MKBossTrap01 NPC_TRAP_ONLINE,0,0,{
end;
OnTouch:
OnTouchNPC:
WorldHeartTrap();
sleep(500); // Wait 500ms for animation
setnpcdisplay .name$, NPC_TRAP_ONLINE;
// Move the trap away after it disarms (up to 30 attempts)
OnInit:
.@e=0;
do {
if (.@e >= 30)
break;
.@x = rand2(21, 60);
.@y = rand2(21, 60);
.@e+=1;
} while (!checknpccell("026-7", .@x, .@y, cell_chkpass));
movenpc .name$, .@x, .@y;
end;
}
// Create more traps
026-7,0,0,0 duplicate(#MKBossTrap01) #MKBossTrap02 NPC_TRAP_ONLINE,0,0
026-7,0,0,0 duplicate(#MKBossTrap01) #MKBossTrap03 NPC_TRAP_ONLINE,0,0
026-7,0,0,0 duplicate(#MKBossTrap01) #MKBossTrap04 NPC_TRAP_ONLINE,0,0
026-7,0,0,0 duplicate(#MKBossTrap01) #MKBossTrap05 NPC_TRAP_ONLINE,0,0
026-7,0,0,0 duplicate(#MKBossTrap01) #MKBossTrap06 NPC_TRAP_ONLINE,0,0
026-7,0,0,0 duplicate(#MKBossTrap01) #MKBossTrap07 NPC_TRAP_ONLINE,0,0
026-7,0,0,0 duplicate(#MKBossTrap01) #MKBossTrap08 NPC_TRAP_ONLINE,0,0
026-7,0,0,0 duplicate(#MKBossTrap01) #MKBossTrap09 NPC_TRAP_ONLINE,0,0
026-7,0,0,0 duplicate(#MKBossTrap01) #MKBossTrap10 NPC_TRAP_ONLINE,0,0