// TMW Script.
// Author:
// Jesusalva
// Notes:
// Christmas 2021 - Mysterious Glade (Final fights, cutscene & final shops)
// CANON:
// From now and hence forth, by the power vested to me due to mapmakers being
// lazy and all that, I declare that it is canon that:
// - Gak and Alissa used to live on this glade
// - Back in 2010, Gak went to Asphodel. First event.
// - Between 2011 and 2015, Gak found out someone built a house here
// - aka. The Pink Boots mage. Gak also got mad at how they got
// Zealite and were using it for petty reasons.
// - Gak took the mask as an offense to Alissa, and the manor as well.
// - As I forgot who is the Pink Boots mage... I can't say any further.
// - Oh, and in 2016, Gak went to visit Asphodel again.
080-1,98,41,0 script Alissa#ED2 NPC_ALISSA,{
if ('XMAS21ENDING) {
npctalkonce l("Thanks for bringing Gorrik back to me.");
}
end;
OnInstanceInit:
disablenpc instance_npcname(.name$);
end;
OnInit:
.distance=4;
.speed=125;
npcsit;
/* I thought in making a shop here */
/* Valentine Dress, Love Potions, Pinkie Crystal... */
/* Would be confusing and bad, so removed. */
end;
}
080-1,97,41,0 script Gak#X21 NPC_GAK,{
if (!'XMAS21FINAL)
end;
if (!X21ED1_CLEAR())
end;
if ('XMAS21CUTSCENE)
end;
if ('XMAS21ENDING) {
openshop;
closedialog;
end;
}
.@gak$=instance_npcname("Gak#X21");
.@ali$=instance_npcname("Alissa#ED2");
.@m$=getmap();
// We're now running a cutscene, lock NPCs
'XMAS21CUTSCENE=true;
// Position the NPCs based on Gak's maximum distance and visible window
unitwarp(getnpcid(.@ali$), .@m$, 97, 60);
sleep2(100);
npcwalkto(97, 42, .@ali$);
// Look at direction 4: Automatic?
sleep2(150*11); // Presumed at 150ms/tile, let she get in player window
npctalk l("GAK!"), .@ali$;
sleep2(300);
npctalk l("Alissssa! You... You arrre alive!"), .@gak$;
sleep2(2000);
setnpcdir(.@ali$, 4); // Fail-safe
npctalk l("Of course I am alive, after you did that... That stupid thing! "), .@ali$;
sleep2(2000);
npctalk l("Did you forgot I can defend myself?!"), .@ali$;
sleep2(2000);
npctalk l("Wellll... Nooo... Buttt... Yesss... I meannn..."), .@gak$;
sleep2(1000);
npctalk l("Stop giving excuses, I don't want to hear them!"), .@ali$;
sleep2(2000);
npctalk l("Alissssa..."), .@gak$;
sleep2(1000);
npctalk l("You idiot, did you really think I would be happy with you giving your life recklessy like that for me??"), .@ali$;
sleep2(2000);
npctalk l("..."), .@gak$;
sleep2(1000);
npctalk l("Also, where did you even got that ugly blinking mask."), .@ali$;
sleep2(2000);
npctalk l("You and me, we have a lot to talk."), .@ali$;
sleep2(2000);
npctalk l("Yes Alissssa..."), .@gak$;
sleep2(2000);
// Let Alissa direct to her final position
npcwalkto(98, 41, .@ali$);
if (X21TYPE() == IOT_PARTY)
npctalk l("Thanksss %s. I may have now annn earful to listennn, buttt... I'm realllly thankfulll.", strcharinfo(1)), .@gak$;
else
npctalk l("Thanksss %s. I may have now annn earful to listennn, buttt... I'm realllly thankfulll.", strcharinfo(0)), .@gak$;
sleep2(3000);
npctalk l("Herrre, you cannn have ttthis %s which Eassster Bunny gave me.", b(l("Carrot"))), .@gak$;
sleep2(3000);
setnpcdir(.@ali$, 0); // Fail-safe
npctalk l("He sssaid I could tttrade forrr a rare orrr evennn level up if I gave ittt to GM Santa..."), .@gak$;
sleep2(3000);
setnpcdir(.@ali$, 0); // Fail-safe
npcsit(.@ali$);
npctalk l("But Alissssa isss worth wayyy morrre thannn thattt. You cannn have ittt."), .@gak$;
sleep2(2000);
if (X21TYPE() == IOT_PARTY) {
npctalk l("%s, in ttthe name of %s, you ssshould tttake ittt.", strcharinfo(0), strcharinfo(1)), .@gak$;
sleep2(2000);
}
// We're done
'XMAS21CUTSCENE=false;
'XMAS21ENDING=true;
X21ED2_DOCLEAR();
// FIXME: getitem Carrot, 1;
end;
OnInit:
.distance=4;
setarray .prizes, BlinkingEvil, BlinkingEvilRed, BlinkingEvilBlue,
BlinkingEvilPink, BlinkingEvilYellow, GuyFawkesMask,
OperaMask, JesterMask, GoblinMask, WitchHat;
setarray .prices, 1500, 1650, 1600,
1650, 1600, 250,
900, 700, 250, 450;
tradertype(NST_CUSTOM);
freeloop(true);
for (.@i = 0; .@i < getarraysize(.prizes); .@i++) {
sellitem(.prizes[.@i], .prices[.@i]);
}
freeloop(false);
npcsit;
end;
OnInstanceInit:
npcsit;
end;
OnCountFunds:
setcurrency(countitem(XmasTicket));
end;
OnPayFunds:
if (!X21ED2_CLEAR()) end;
if( countitem(XmasTicket) < @price )
end;
/* Verify if you're not purchasing a dupe */
/* This requires servercode@712c09c2c6d848243c3426aeb3dbdf730c1e0b08 to work */
for (.@i=0;.@i < getarraysize(@bought_nameid); .@i++) {
if (debug || $@XMAS21_OVERRIDE)
debugmes("%dx %s", @bought_quantity[.@i], getitemname(@bought_nameid[.@i]));
.@arr = array_find(.prizes, @bought_nameid[.@i]);
if (.@arr < 0) { dispbottom "REPORT ME: Array Error (Gak)"; end;}
.@bit = (2 ** .@arr);
if (#X21PRIZES_GAK & .@bit) {
dispbottom l("You already purchased a(n) %s during the event.", getitemlink(@bought_nameid[.@i]));
dispbottom l("Therefore, the operation was cancelled.");
end;
}
}
delitem XmasTicket, @price;
/* Record the items on the bitmask (far more important) */
/* This requires servercode@712c09c2c6d848243c3426aeb3dbdf730c1e0b08 to work */
for (.@i=0;.@i < getarraysize(@bought_nameid); .@i++) {
.@arr = array_find(.prizes, @bought_nameid[.@i]);
if (.@arr < 0) { dispbottom "REPORT ME: Fatal Array Error (Gak)"; end;}
.@bit = (2 ** .@arr);
#X21PRIZES_GAK = #X21PRIZES_GAK | .@bit;
}
purchaseok();
end;
}
// But then, Gak *did* "kidnap" a zealite specialist, right?
080-1,83,136,0 script #X21BarrierF NPC_HIDDEN,3,0,{
if ('XMAS21FINAL)
end;
if (mobcount(getmap(), "#X21BarrierF::OnKil")) {
dispbottom strcharinfo(0) + " : " + l("This clearly is not a real gate; Most likely an illusion to prevent access. I should be able to dispel it by killing the guardians.");
end;
}
delcells("X21LF@"+X21ID());
specialeffect(FX_MAGIC_WICKED_SPAWN, AREA, getcharid(3));
getitem XmasTicket, X21_TICKET_BOSS;
'XMAS21FINAL = true;
maptimer2(getmap(), 10, "#X21BarrierF::OnSesame");
end;
OnInit:
.distance=1;
end;
OnSesame:
dispbottom l("Without the guardians, the illusion is just that: An illusion. The path is clear.");
getitem XmasTicket, X21_TICKET_SUPPORT;
getexp X21_EXP_PUZZLE, 0;
end;
OnKil:
mapannounce getmap(), "One of the guardians has been eliminated by "+strcharinfo(0), 0;
getitem XmasTicket, X21_TICKET_SUPPORT + 1;
X21INIT();
end;
}
027-1,105,63,0 script #GakGate NPC400,{
if (!isChristmas21()) end;
if (!X21GAK_GATE()) end;
mes l("There are several names in fine print below this gargoyle:");
// Sorry for missing names (e.g. Platyna) and spurious names (e.g. Crush)
// Wanted to list only TMW sysadmins but too much trouble
mes "Bjorn ~ Crush ~ ElvenProgrammer ~ Freeyorp ~ Frost ~ Jak1 ~ Jaxad ~ Jesusalva ~ MadCamel ~ Reid ~ Rotonen ~ Tux9th ~ Wombat ~ Wushin";
next;
mes l("Whose name do you press?");
select
l("None!"),
l("Bjorn"),
l("Crush"),
l("ElvenProgrammer"),
l("Freeyorp"),
l("Frost"),
l("Jak1"),
l("Jaxad"),
l("Jesusalva"),
l("MadCamel"),
l("Reid"),
l("Rotonen"),
l("Tux9th"),
l("Wombat"),
l("Wushin");
mes "";
.@id = @menu - 2;
if (.@id != XMAS21_KEYWORD) {
percentheal -10, -100;
} else {
X21INIT();
.@mapa$="0801@"+X21ID2();
warp .@mapa$, 84, 145;
}
closeclientdialog;
close;
OnInit:
.distance=2;
end;
}
080-1,97,140,0 script #0801Exit NPC424,0,0,{
end;
OnTouch:
mes l("Warp back?");
next;
if (askyesno() == ASK_YES)
warp "027-2", 50, 29;
closeclientdialog;
end;
}
016-2,29,23,0 script Kytty#X21 NPC430,{
if (!isChristmas21() || !X21_START() || !X21GAK_GOTO()) {
npctalkonce l("Hey there, %s.", strcharinfo(0));
end;
}
mesn;
mesq l("I'm busy looking for %s. Damn, where are TMW Sysadmins when you need them...", .adm$[XMAS21_KEYWORD]);
close;
OnInit:
.distance = 5;
setarray .adm$, "Bjorn", "Crush", "ElvenProgrammer", "Freeyorp", "Frost", "Jak1", "Jaxad", "Jesusalva", "MadCamel", "Reid", "Rotonen", "Tux9th", "Wombat", "Wushin";
if (!isChristmas21()) goto L_Off;
goto L_On;
OnClock0000:
if (!isChristmas21()) goto L_Off;
goto L_On;
L_On:
enablenpc .name$;
end;
L_Off:
disablenpc .name$;
end;
}
016-1,84,53,0 script #X21GwenA NPC_HIDDEN,0,0,{
end;
OnTouch:
if (isChristmas21()) warp "016-2", 28, 31;
end;
}
016-1,84,50,0 script #X21GwenB NPC_HIDDEN,0,0,{
end;
OnTouch:
if (isChristmas21()) warp "016-2", 26, 23;
end;
}