// TMW2 scripts.
// Authors:
// Jesusalva
// Description:
// Gemini Sisters Quest - Part C: Showdown
034-4,98,22,0 script #GeminiPartD NPC_HIDDEN,0,0,{
end;
OnTouch:
if (instance_id() < 0 || getcharid(1) < 1) end;
GeminiCheck(13);
.@p=getcharid(1);
if ($@VALIA_STATUS[.@p] < 14 || mobcount(getmap(), "#GeminiShowdown::OnABC")) {
dispbottom l("Luvia is too dangerous to be left alone.");
end;
}
if (mobcount(getmap(), "all") > 0) {
dispbottom l("I cannot leave until Luvia and her allies are dead.");
end;
}
if (mobcount(getmap(), "all") <= 0 && $@VALIA_STATUS[.@p] == 14) {
$@VALIA_STATUS[.@p]=15;
}
if ($@VALIA_STATUS[.@p] >= 15) {
if (!@v_fanfare)
specialeffect(FX_FANFARE, SELF, getcharid(3));
slide 143, 96;
}
end;
}
// 98 36 with radius 12?
034-4,98,28,0 script #GeminiShowdown NPC_HIDDEN,2,1,{
end;
OnTouch:
if (instance_id() < 0 || getcharid(1) < 1) end;
GeminiCheck(13);
.@p=getcharid(1);
if (strcharinfo(0) != getpartyleader(.@p)) end;
if (!.state) {
.mp$ = getmap();
.beats = 0;
.pid = getcharid(1);
.state = true;
initnpctimer;
killmonsterall(.mp$); // Cancel everything done thus far, incl. showdown
}
end;
OnABC:
// Extra drop chance (20% chance)
getmapxy(.@m$, .@x, .@y, 0);
if (!rand2(5))
makeitem BronzeBossGift, 1, .@m$, .@x, .@y;
end;
OnTimer1000:
.luvia = monster(.mp$, 98, 32, "Luvia Gemini", Luvia, 1);
immortal(.luvia);
setunitdata(.luvia, UDT_MODE, MD_BOSS|MD_PLANT|MD_NOKNOCKBACK);
end;
OnTimer2500:
unittalk(.luvia, "Ara! Look at who is trying to sneak past me!");
end;
OnTimer6000:
unittalk(.luvia, "How silly. I prepared this party for ya, you know.");
end;
OnTimer9500:
unittalk(.luvia, "Isbamuth wants all of you dead ─ And I'll carry out his orders.");
end;
OnTimer13000:
unittalk(.luvia, "Long live Isbamuth... And death to traitors! Now begone!!");
end;
OnTimer15000:
// Create a new Luvia Gemini
unitwarp(.luvia, "034-4", 98, 32);
unitkill(.luvia);
.luvia = monster(.mp$, 98, 38, "Luvia Gemini", Luvia, 1, "#GeminiShowdown::OnABC");
// Grant her more HP if more players came to attack her
.@hp = getunitdata(.luvia, UDT_MAXHP) + (getmapusers(.mp$) * 12000);
setunitdata(.luvia, UDT_MAXHP, .@hp);
setunitdata(.luvia, UDT_HP, .@hp);
// Reconfigure the AI
.@opt=getunitdata(.luvia, UDT_MODE);
// Add knockback immunity
.@opt=.@opt|MD_NOKNOCKBACK;
// 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(.luvia, UDT_MODE, .@opt);
// Prepare the party, lalala!
.@pi = getmapusers(.mp$) * 2 + 1;
monster(.mp$, 117, 51, strmobinfo(1, Scar), Scar, .@pi);
monster(.mp$, 83, 58, strmobinfo(1, Scar), Scar, .@pi);
monster(.mp$, 83, 51, strmobinfo(1, Scar), Scar, .@pi);
monster(.mp$, 114, 29, strmobinfo(1, Scar), Scar, .@pi);
monster(.mp$, 98, 22, strmobinfo(1, Scar), Scar, .@pi);
$@VALIA_STATUS[.pid] = 14;
end;
// The fight loops from 20k (the restart point)
// So this cycle happens every 10 seconds
OnTimer60000:
OnTimer45000:
consolewarn("Warning, fail-safe mechanism triggered to Luvia.");
OnTimer30000:
if (mobcount(.mp$, "#GeminiShowdown::OnABC") < 1) {
stopnpctimer;
end;
}
.beats+=1;
/* Prepare some data */
.@hp = getunitdata(.luvia, UDT_HP) * 10 / getunitdata(.luvia, UDT_MAXHP);
.@pi = getmapusers(.mp$);
getmapxy(.@m$, .@x, .@y, UNITTYPE_MOB, .luvia);
.@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);
}
}*/
// Luvia's spell casting
// She casts every ~30 seconds
switch (.beats % 18) {
case 0:
case 6:
case 12:
unittalk(.luvia, "Hahahah, die, die!");
specialeffect(64, AREA, .luvia);
sleep(1000);
monster(.mp$, .@x, .@y, strmobinfo(1, Scar), Scar, .@pi + max(1, (11 - .@hp) / 10));
monster(.mp$, .@x, .@y, strmobinfo(1, MagicGoblin), MagicGoblin, .@pi + max(1, (11 - .@hp) / 10));
// Doors reinforcements
// As time passes, they get stronger
// But after 7 minutes, it resets
switch ((.beats / 6) % 14) {
case 0:
.@mob = Skeleton; break; // Shouldn't trigger
case 1:
.@mob = LavaSlime; break;
case 2:
.@mob = ArmoredSkeleton; break;
case 3:
.@mob = DustRifle; break;
case 4:
.@mob = DarkLizard; break;
case 5:
.@mob = HoodedNinja; break;
case 6:
.@mob = Archant; break;
case 7:
.@mob = Scar; break;
case 8:
.@mob = Terranite; break;
case 9:
.@mob = EliteDuck; break;
case 10:
.@mob = Troll; break;
case 11:
.@mob = YellowSkullSlime; break;
case 12:
.@mob = Michel; break;
case 13:
.@mob = JackO; break;
}
monster(.mp$, 114, 29, strmobinfo(1, .@mob), .@mob, 1);
// If you can't deal enough damage, less support comes
if (.@hp <= 7) // Up to 79% HP
monster(.mp$, 117, 51, strmobinfo(1, .@mob), .@mob, 1);
if (.@hp <= 6) // Up to 69% HP
monster(.mp$, 98, 22, strmobinfo(1, .@mob), .@mob, 1);
if (.@hp <= 4) // Up to 39% HP
monster(.mp$, 83, 58, strmobinfo(1, .@mob), .@mob, 1);
if (.@hp <= 3) // Up to 29% HP
monster(.mp$, 83, 51, strmobinfo(1, .@mob), .@mob, 1);
break;
case 3:
case 9:
case 15:
specialeffect(60, AREA, .luvia);
sleep(500);
.@r = (10-.@hp) / 5 + rand2(4); // From 0 to 5
// Blind has extra chance until her HP falls below 60%
// Curse won't happen if her HP is equal or above 60%
// Once her HP falls below 10%, she no longer silences
// And her poison is strengthened.
switch (.@r) {
case 1:
unittalk(.luvia, "The dead are ##Bsilent##b, just like you!");
.@sc = SC_SILENCE;
break;
case 2:
unittalk(.luvia, "I am your doom, and ##Bpoison##b is my tool!");
.@sc = (.@hp < 1 ? SC_DPOISON : SC_POISON);
break;
case 3:
unittalk(.luvia, "You shall ##Bbleed##b, and cease!");
.@sc = SC_BLOODING;
break;
case 4:
unittalk(.luvia, "You dare to underestimate me?! ##BCurse##b you!");
.@sc = SC_CURSE;
break;
default:
unittalk(.luvia, "You won't see what killed you when ##Bblind##b!");
.@sc = SC_BLIND;
break;
}
areasc(9, 45000, .@sc, BL_PC|BL_HOM|BL_MER, 1, "filter_always", .luvia, 95000);
.@dmg=100 + (max(1, (11 - .@hp) / 10) * 40);
areaharm(.luvia, 9, .@dmg, HARM_MAGI, any(Ele_Water,Ele_Fire,Ele_Wind,Ele_Earth), "filter_always", BL_PC|BL_MER|BL_HOM);
break;
default:
specialeffect(60, AREA, .luvia);
unittalk(.luvia, any("I am getting tired of you!",
"That's all you can muster?",
"Long live Isbamuth!",
"Hahahahah!",
"Incompetent! Simply incompetent!",
"You shall not resist!",
"I'm not afraid of you!"));
sleep(500);
.@dmg=40 + (max(1, (11 - .@hp) / 10) * 20);
areaharm(.luvia, 9, .@dmg, HARM_MAGI, any(Ele_Water,Ele_Fire,Ele_Wind,Ele_Earth), "filter_always", BL_PC|BL_MER|BL_HOM);
break;
}
// And we're done! Wait 10 seconds before next casting
setnpctimer 20000;
end;
OnInit:
OnInstanceInit:
.state = false;
.mp$ = "";
.pid = 0;
.luvia = 0;
.beats = 0;
end;
}