// 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;
/* 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("Alissa! You... You are alive!"), .@gak$;
sleep2(2000);
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("Well... No... But... Yes... I mean..."), .@gak$;
sleep2(1000);
npctalk l("Stop giving excuses, I don't want to hear them!"), .@ali$;
sleep2(2000);
npctalk l("Alissa..."), .@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 Alissa..."), .@gak$;
sleep2(2000);
// Let Alissa direct to her final position
npcwalkto(98, 41, .@ali$);
if (X21TYPE() == IOT_PARTY)
npctalk l("Thanks %s. I may have now an earful to listen, but... I'm really thankful.", strcharinfo(1)), .@gak$;
else
npctalk l("Thanks %s. I may have now an earful to listen, but... I'm really thankful.", strcharinfo(0)), .@gak$;
sleep2(3000);
npctalk l("Here, you can have this %s which Easter Bunny gave me.", b(l("Carrot"))), .@gak$;
sleep2(3000);
npctalk l("He said I could trade for a rare or even level up if I gave it to GM Santa..."), .@gak$;
sleep2(3000);
npctalk l("But Alissa is worth way more than that. You can have it."), .@gak$;
sleep2(2000);
if (X21TYPE() == IOT_PARTY) {
npctalk l("%s, in the name of %s, you should take it.", strcharinfo(0), strcharinfo(1)), .@gak$;
sleep2(2000);
}
// FIXME: getitem Carrot, 1;
// We're done
'XMAS21CUTSCENE=false;
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);
end;
OnCountFunds:
setcurrency(countitem(AquaTicket));
end;
/* @price is total cost. @points is if we accept two items as currency. */
OnPayFunds:
//dispbottom "Hi: price="+@price+" and points="+@points;
if( countitem(AquaTicket) < @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 AquaTicket, @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 AquaTicket, 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 AquaTicket, X21_TICKET_SUPPORT;
getexp X21_EXP_PUZZLE, 0;
end;
OnKil:
mapannounce getmap(), "One of the guardians has been eliminated by "+strcharinfo(0), 0;
getitem AquaTicket, X21_TICKET_SUPPORT + 1;
X21INIT();
end;
}