// TMW Script. // Author: // Jesusalva // Notes: // Christmas 2021 - Configuration Files function script X21ID { return (getcharid(1) > 0 ? getcharid(1) : getcharid(3)); } function script X21ID2 { return (getcharid(1) > 0 ? getcharid(1) : getcharid(0)); } function script X21TYPE { return (getcharid(1) > 0 ? IOT_PARTY : IOT_CHAR); } function script X21_START { return (XMAS2021 & X21_ACCEPTED); } function script X21_DOSTART { XMAS2021 = (XMAS2021 | X21_ACCEPTED); // Actually - reset the quest. XMAS2021 = X21_ACCEPTED; /* Prepare the answer to Gak's Crypt */ if (strcharinfo(0) == "kytty") XMAS21_KEYWORD = 7; else XMAS21_KEYWORD = rand2(15); return; } function script X21_DISPATCH { return (XMAS2021 & X21_ALLOWED); } function script X21_DODISPATCH { XMAS2021 = (XMAS2021 | X21_ALLOWED); return; } function script X21BC1_CLEAR { return (XMAS2021 & X21_BOSSDEFEAT); } function script X21BC1_DOCLEAR { XMAS2021 = (XMAS2021 | X21_BOSSDEFEAT); return; } function script X21ED1_CLEAR { return (XMAS2021 & X21_ALYSSARESCUE); } function script X21ED1_DOCLEAR { if (X21BC1_CLEAR()) XMAS2021 = (XMAS2021 | X21_ALYSSARESCUE); return; } function script X21GAK_GOTO { return (XMAS2021 & X21_GOTOGAK); } function script X21GAK_DOGOTO { XMAS2021 = (XMAS2021 | X21_GOTOGAK); return; } function script X21GAK_GATE { return (XMAS2021 & X21_GATEGAK); } function script X21GAK_DOGATE { XMAS2021 = (XMAS2021 | X21_GATEGAK); return; } function script X21ED2_CLEAR { return (XMAS2021 & X21_COMPLETE); } function script X21ED2_DOCLEAR { XMAS2021 = (XMAS2021 | X21_COMPLETE); return; } function script X21SRLZ { .@n=getarg(0); switch (.@n) { case 1: return l("first"); case 2: return l("second"); case 3: return l("third"); case 4: return l("fourth"); case 5: return l("fifth"); //case 6: return l("sixth"); //case 7: return l("seventh"); } return str(.@n); } function script XMAS21_NPC { if (!isChristmas21()) return; if (!X21GAK_GOTO()) return; if (X21GAK_GATE()) return; .@npc$=getarg(0, strnpcinfo(1)); if (.@npc$ == "Forwin") { mesn; mesq l("Gak lived around here way before Golbenez moved in. He went north, but haven't seen him since."); next; } else if (.@npc$ == "Thurstan") { mesn; mesq l("I can't believe Gak refused to lend me Duck Tape! Then he went into the graveyard... Haven't seen him since."); next; } else if (.@npc$ == "Hamond") { mesn; mesq l("If you're looking for Kytty, she went east, looking for Gwendolyn. You're welcome."); next; } else if (.@npc$ == "Styx the Traveler") { mesn; mesq l("Gak and Kytty never need my services. So I didn't pay attention to either of them."); next; } else if (.@npc$ == "Blackwin") { mesn; mesq l("Kytty came visit, but she already left. You would be wise to do so as well."); next; } else if (.@npc$ == "Gwendolyn") { mesn; mesq l("Kytty is in my house waiting for someone. If you need her, feel free to enter."); next; } else { npctalk l("BUG, REPORT ME! Invalid Christmas 2021 NPC!"); debugmes "Invalid NPC: %s", .@npc$; } return; } function script X21INIT { // If it is not Christmas, there is no meaning to this. // Halt script execution if (!isChristmas21()) { warp "000-1", 22, 22; end; } // All instances require Santa authorization. // Halt script execution if (!X21_START() || !X21_DISPATCH()) { warp "020-1", 80, 87; end; } .@inst = instance_create("Northern Lights", X21ID(), X21TYPE()); // Instance must be created if (.@inst >= 0) { // We... Could use base name, actually, but whatever .@mapa$ = "0812@"+X21ID2(); // Northern Lights .@mapb$ = "0813@"+X21ID2(); // Existential Frontier .@mapc$ = "0803@"+X21ID2(); // Forgotten/Mystic/Peaceful Glade .@mapd$ = "0801@"+X21ID2(); // Peaceful Glade (Present) instance_attachmap("081-2", .@inst, false, .@mapa$); instance_attachmap("081-3", .@inst, false, .@mapb$); instance_attachmap("080-3", .@inst, false, .@mapc$); instance_attachmap("080-1", .@inst, false, .@mapd$); instance_set_timeout(getarg(0, 1800), getarg(0, 1800), .@inst); instance_init(.@inst); /* Ensure the instance is up and running without fail */ sleep2(50); .@me = getcharid(3); .@te = X21TYPE(); detachrid(); /* Spawn Special Monsters */ "#XMAS21Core"::spawn(Grinchboo, 5, .@mapa$); "#XMAS21Core"::spawn(Grinchboo, 3, .@mapc$); "#XMAS21Core"::spawn(Moonshroom, 10, .@mapa$); "#XMAS21Core"::spawn(Moonshroom, 14, .@mapc$); "#XMAS21Core"::spawn2(BlueSpark, 47, 191, 65, 212, 2, .@mapa$); "#XMAS21Core"::spawn2(RedSpark, 47, 191, 65, 212, 2, .@mapa$); if (.@te == IOT_PARTY) "#XMAS21Core"::spawn2(Koyntety, 70, 250, 99, 265, 1, .@mapa$, true); else "#XMAS21Core"::spawn2(ManaGuard, 70, 250, 99, 265, 1, .@mapa$, true); /* Northern Lights Dungeon */ "#XMAS21Core"::spawn(WhiteSlime, 37, .@mapa$); "#XMAS21Core"::spawn(Archant, 7, .@mapa$); //"#XMAS21Core"::spawn(BlueSpark, 1, .@mapa$); //? //"#XMAS21Core"::spawn(RedSpark, 1, .@mapa$); //? "#XMAS21Core"::spawn(AzulSlime, 21, .@mapa$); "#XMAS21Core"::spawn(SantaSlime, 18, .@mapa$); "#XMAS21Core"::spawn(Moggun, 27, .@mapa$); "#XMAS21Core"::spawn(Yeti, 4, .@mapa$); "#XMAS21Core"::spawn(Wisp, 5, .@mapa$); "#XMAS21Core"::spawn(Poltergeist, 12, .@mapa$); "#XMAS21Core"::spawn(Spectre, 5, .@mapa$); "#XMAS21Core"::spawn(ManaGhost, 14, .@mapa$); "#XMAS21Core"::spawn(IceElement, 2, .@mapa$); "#XMAS21Core"::spawn(IceSkull, 2, .@mapa$); "#XMAS21Core"::spawn(Nutcracker, 6, .@mapa$); "#XMAS21Core"::spawn(Fluffy, 16, .@mapa$); /* Peaceful/Mystic/Forgotten Glade (Past) */ "#XMAS21Core"::spawn(CrotcherScorpion, 10, .@mapc$); "#XMAS21Core"::spawn(Snail, 18, .@mapc$); "#XMAS21Core"::spawn(Bee, 9, .@mapc$); "#XMAS21Core"::spawn(Butterfly, 24, .@mapc$); "#XMAS21Core"::spawn(PinkFlower, 42, .@mapc$); "#XMAS21Core"::spawn(Pinkie, 32, .@mapc$); "#XMAS21Core"::spawn(Hyvern, 6, .@mapc$); "#XMAS21Core"::spawn(WitchGuard, 8, .@mapc$); /* Peaceful/Mystic/Forgotten Glade (Present) */ "#XMAS21Core"::spawn(Fluffy, 9, .@mapd$); "#XMAS21Core"::spawn(Snail, 11, .@mapd$); "#XMAS21Core"::spawn(Bee, 5, .@mapd$); "#XMAS21Core"::spawn(Butterfly, 15, .@mapd$); "#XMAS21Core"::spawn(PinkFlower, 24, .@mapd$); "#XMAS21Core"::spawn(Pinkie, 18, .@mapd$); "#XMAS21Core"::spawn(Hyvern, 3, .@mapd$); attachrid(.@me); /* The Three Guardians */ .@bon = 0; if (X21TYPE() == IOT_PARTY) .@bon = 20000; .@mg = monster(.@mapd$, 43, 47, "Der Schneemann (Alpha)", SnowmanBoss, 1, "#X21BarrierF::OnKil"); .@hp = .@bon + rand2(35000, 47000); setunitdata(.@mg, UDT_MAXHP, .@hp); setunitdata(.@mg, UDT_HP, .@hp); setunitdata(.@mg, UDT_ATKRANGE, 2); setunitdata(.@mg, UDT_ATKMIN, 40); setunitdata(.@mg, UDT_ATKMAX, 50); .@mg = monster(.@mapd$, 144, 154, "Der Schneemann (Beta)", SnowmanBoss, 1, "#X21BarrierF::OnKil"); .@hp = .@bon + rand2(35000, 47000); setunitdata(.@mg, UDT_MAXHP, .@hp); setunitdata(.@mg, UDT_HP, .@hp); setunitdata(.@mg, UDT_ATKRANGE, 2); setunitdata(.@mg, UDT_ATKMIN, 40); setunitdata(.@mg, UDT_ATKMAX, 50); .@mg = monster(.@mapd$, 42, 147, "Der Schneemann (Gamma)", SnowmanBoss, 1, "#X21BarrierF::OnKil"); .@hp = .@bon + rand2(35000, 47000); setunitdata(.@mg, UDT_MAXHP, .@hp); setunitdata(.@mg, UDT_HP, .@hp); setunitdata(.@mg, UDT_ATKRANGE, 2); setunitdata(.@mg, UDT_ATKMIN, 40); setunitdata(.@mg, UDT_ATKMAX, 50); /* The Three Guardians Friends */ if (X21TYPE() == IOT_PARTY) { .@g = 12; } else { .@g = 7; } freeloop(true); for (.@i=0; .@i < .@g; .@i++) { .@mg = areamonster(.@mapd$, 30, 38, 50, 51, "Snowman (Alpha)", Snowman, 1); .@hp = rand2(3500, 5700); .@ak = rand2(80, 120); setunitdata(.@mg, UDT_MAXHP, .@hp); setunitdata(.@mg, UDT_HP, .@hp); setunitdata(.@mg, UDT_ATKRANGE, 1); setunitdata(.@mg, UDT_ATKMIN, .@ak); setunitdata(.@mg, UDT_ATKMAX, .@ak+20); } for (.@i=0; .@i < .@g; .@i++) { .@mg = areamonster(.@mapd$, 140, 149, 149, 160, "Snowman (Beta)", Snowman, 1); .@hp = rand2(3500, 5700); .@ak = rand2(80, 120); setunitdata(.@mg, UDT_MAXHP, .@hp); setunitdata(.@mg, UDT_HP, .@hp); setunitdata(.@mg, UDT_ATKRANGE, 1); setunitdata(.@mg, UDT_ATKMIN, .@ak); setunitdata(.@mg, UDT_ATKMAX, .@ak+20); } for (.@i=0; .@i < .@g; .@i++) { .@mg = areamonster(.@mapd$, 37, 142, 47, 152, "Snowman (Gamma)", Snowman, 1); .@hp = rand2(3500, 5700); .@ak = rand2(80, 120); setunitdata(.@mg, UDT_MAXHP, .@hp); setunitdata(.@mg, UDT_HP, .@hp); setunitdata(.@mg, UDT_ATKRANGE, 1); setunitdata(.@mg, UDT_ATKMIN, .@ak); setunitdata(.@mg, UDT_ATKMAX, .@ak+20); } freeloop(false); // We had some problems with the locks, so give it a tiny while of time sleep2(50); /* Create locks */ setcells .@mapa$, 103, 211, 107, 212, 1, "X21L1@"+X21ID(); setcells .@mapa$, 124, 127, 131, 128, 1, "X21L2@"+X21ID(); setcells .@mapa$, 47, 71, 51, 72, 1, "X21L3@"+X21ID(); setcells .@mapd$, 81, 131, 86, 135, 1, "X21LF@"+X21ID(); } if (instance_id() >= 0) instance_set_timeout(getarg(0, 1800), getarg(0, 1800)); return; } function script X21CANDLE_CHECK { if ('XMAS21CANDLE) return false; // NOTE: We could check here if player already finished this // And skip the challenge after litting one candle? if ('X21_CANDLE[0] != 'COLORCODE[0]) return false; if ('X21_CANDLE[1] != 'COLORCODE[1]) return false; if ('X21_CANDLE[2] != 'COLORCODE[2]) return false; if ('X21_CANDLE[3] != 'COLORCODE[3]) return false; if ('X21_CANDLE[4] != 'COLORCODE[4]) return false; if ('X21_CANDLE[5] != 'COLORCODE[5]) return false; // This instance challenge is over 'XMAS21CANDLE = true; // Record on player as well, just to be safe. if (XMAS2021 & X21_CANDLES) return true; XMAS2021 = (XMAS2021 | X21_CANDLES); return true; } function script X21SEED_CHECK { /* Protip: You don't have to fill all spots * * If you plant a "L" it also works * This is because "L" is the first letter of "Lazy" * And I was particularly lazy to make a proper script */ if ('XMAS21TREE) return false; // NOTE: We could check here if player already finished this // And skip the challenge after planting one tree? if (!'XMAS21TREE_X[116]) return false; if (!'XMAS21TREE_X[117]) return false; if (!'XMAS21TREE_X[118]) return false; if (!'XMAS21TREE_X[119]) return false; if (!'XMAS21TREE_X[120]) return false; if (!'XMAS21TREE_Y[168]) return false; if (!'XMAS21TREE_Y[169]) return false; if (!'XMAS21TREE_Y[170]) return false; // This instance challenge is over 'XMAS21TREE = true; // Record on player as well, just to be safe. if (XMAS2021 & X21_PLANTPUZZLE) return true; XMAS2021 = (XMAS2021 | X21_PLANTPUZZLE); return true; } function script X21_SEEDS { getmapxy(.@m$, .@x, .@y, 0); // If planted in the wrong region, vanish without effect if (.@m$ != "0812@"+X21ID2()) return; if (.@x < 107 || .@x > 126) return; if (.@y < 159 || .@y > 177) return; // Instance bugfix if (@inst <= 0) { getitem XmasSeeds, 1; return; } addtimer 10, instance_npcname("#X21SeedFlag", @inst-1)+"::OnPlant"; return; } /* You cannot fiddle with party in this region */ 080-1 mapflag partylock 080-3 mapflag partylock //081-1 mapflag partylock 081-2 mapflag partylock 081-3 mapflag partylock 081-2 mapflag bexp 125 080-3 mapflag bexp 125 080-1 mapflag bexp 125 /* Secure regions */ 081-3 mapflag zone MMO 081-3 mapflag nosave 081-1,68,31 /* Script Core */ 080-1,0,0,0 script #XMAS21Core NPC_HIDDEN,{ end; // "#XMAS21Core"::spawn(MonsterID, {Amount=1, {Map=this, Normal=true}}) public function spawn { if (playerattached()) .@m$=getarg(2, getmap()); else .@m$=getarg(2); .@n$="#XMAS21Core::On"+getarg(0); if (mobcount(.@m$, .@n$) < 60 && getarg(3, true)) { /* Spawn normally */ areamonster .@m$, 20, 20, getmapinfo(MAPINFO_SIZE_X, .@m$)-20, getmapinfo(MAPINFO_SIZE_Y, .@m$)-20, strmobinfo(1, getarg(0)), getarg(0), getarg(1, 1), .@n$; } else if (!getarg(3, true)) { /* Spawn as passive */ freeloop(true); for (.@i=0; .@i < getarg(1, 1); .@i++) { .@m = areamonster(.@m$, 20, 20, getmapinfo(MAPINFO_SIZE_X, .@m$)-20, getmapinfo(MAPINFO_SIZE_Y, .@m$)-20, strmobinfo(1, getarg(0)), getarg(0), 1, .@n$+"B"); unset_aggro(.@m); } freeloop(false); } /* Aqua Ticket Drops */ if (playerattached()) { if (!compare(.@m$, str(X21ID2()))) return; // No drops outside instanced maps fix_mobkill(getarg(0)); } return; } // "#XMAS21Core"::spawn2(MonsterID, X1, Y1, X2, Y2, {Amount=1, {Map=this}}) // Function Changes from On to OnX public function spawn2 { if (playerattached()) .@m$=getarg(6, getmap()); else .@m$=getarg(6); .@n$="#XMAS21Core::OnX"+getarg(0); .@x1=max(getarg(1), 20); .@y1=max(getarg(2), 20); .@x2=min(getarg(3), getmapinfo(MAPINFO_SIZE_X, .@m$)-20); .@y2=min(getarg(4), getmapinfo(MAPINFO_SIZE_Y, .@m$)-20); .@noob=getarg(7, false); /* // Radius-based, was scrapped in favor of rectangles .@x1=max(getarg(1)-getarg(3), 20); .@y1=max(getarg(2)-getarg(3), 20); .@x2=min(getarg(1)+getarg(3), getmapinfo(MAPINFO_SIZE_X, .@m$)-20); .@y2=min(getarg(2)+getarg(3), getmapinfo(MAPINFO_SIZE_Y, .@m$)-20); */ if (mobcount(.@m$, .@n$) < 120) { .@mg=areamonster(.@m$, .@x1, .@y1, .@x2, .@y2, strmobinfo(1, getarg(0)), getarg(0), getarg(5, 1), .@n$); if (.@noob && .@mg) { .@hp = getunitdata(.@mg, UDT_MAXHP) * 3 / 5; // Reduce to 60% HP .@ak = getunitdata(.@mg, UDT_ATKMIN) * 4 / 5; // Reduce to 80% ATK .@ax = getunitdata(.@mg, UDT_ATKMAX) * 4 / 5; // Reduce to 80% ATK setunitdata(.@mg, UDT_MAXHP, .@hp); setunitdata(.@mg, UDT_HP, .@hp); setunitdata(.@mg, UDT_ATKMIN, .@ak); setunitdata(.@mg, UDT_ATKMAX, .@ax); } else if (.@noob) { debugmes "WARN: Faulty %dx %d at map %s", getarg(5,1), getarg(0), .@m$; } } return; } /* Special */ // Sparkles Chamber, drops seeds OnX1080: OnX1081: spawn2(any(BlueSpark, RedSpark), 47, 191, 65, 212); /* Give player enough seeds */ getmapxy(.@m$, .@x, .@y, 0); .@x1=.@x-1; .@y1=.@y-1; .@x2=.@x+1; .@y2=.@y+1; .@x=cap_value(rand2(.@x1, .@x2), 47, 65); .@y=cap_value(rand2(.@y1, .@y2), 191, 212); makeitem(XmasSeeds, rand2(1, 3), .@m$, .@x, .@y); end; // Mini-Boss Chamberlain, drops candle OnX1146: OnX1147: spawn2(any(Flashmob, Koyntety), 70, 250, 99, 265, 1, getmap(), true); /* Give player enough fuel potions */ getmapxy(.@m$, .@x, .@y, 0); .@x1=.@x-1; .@y1=.@y-1; .@x2=.@x+1; .@y2=.@y+1; .@x=cap_value(rand2(.@x1, .@x2), 70, 99); .@y=cap_value(rand2(.@y1, .@y2), 250, 265); makeitem(ThermalNapalm, rand2(3, 5), .@m$, .@x, .@y); end; // Mini-Boss Chamberlain, drops candle (easy mode) OnX1140: OnX1143: OnX1138: spawn2(any(Tengu, ManaSlayer, ManaGuard, ManaGuard), 70, 250, 99, 265, 1, getmap(), true); /* Give player enough fuel potions */ getmapxy(.@m$, .@x, .@y, 0); .@x1=.@x-1; .@y1=.@y-1; .@x2=.@x+1; .@y2=.@y+1; .@x=cap_value(rand2(.@x1, .@x2), 70, 99); .@y=cap_value(rand2(.@y1, .@y2), 250, 265); makeitem(ThermalNapalm, rand2(3, 5), .@m$, .@x, .@y); end; // Christmas Tree, spawns a (few?) gift boxes OnX1164: getmapxy(.@m$, .@x, .@y, 0); .@x1=.@x-2; .@y1=.@y-2; .@x2=.@x+2; .@y2=.@y+2; .@x=cap_value(rand2(.@x1, .@x2), 47, 65); .@y=cap_value(rand2(.@y1, .@y2), 191, 212); spawn2(ChristmasGift, .@x1, .@y1, .@x2, .@y2, rand2(1, 3)); end; // Christmas Gift Box, gives you Tickets OnX1165: getmapxy(.@m$, .@x, .@y, 0); .@x1=.@x-2; .@y1=.@y-2; .@x2=.@x+2; .@y2=.@y+2; .@x=cap_value(rand2(.@x1, .@x2), 107, 126); .@y=cap_value(rand2(.@y1, .@y2), 159, 177); makeitem(XmasTicket, 1, .@m$, .@x, .@y); end; /* Experimental */ On1162: spawn(Grinchboo, 2); end; On1130: spawn(Moonshroom); end; On1130B: spawn(Moonshroom, 1, getmap(), false); end; /* Ice Caves */ On1093: spawn(WhiteSlime); end; On1060: spawn(Archant); end; On1080: spawn(BlueSpark); end; On1081: spawn(RedSpark); end; On1100: spawn(AzulSlime); end; On1015: spawn(SantaSlime); end; On1061: spawn(Moggun); end; On1072: spawn(Yeti); end; On1040: spawn(Wisp); end; On1047: spawn(Poltergeist); end; On1042: spawn(Spectre); end; On1125: spawn(ManaGhost); end; On1071: spawn(IceElement); end; On1085: spawn(IceSkull); end; On1114: spawn(Nutcracker); end; On1020: spawn(Fluffy); end; /* Woodlands */ On1084: spawn(CrotcherScorpion); end; On1041: spawn(Snail); end; On1049: spawn(Bee); end; On1055: spawn(Butterfly); end; On1014: spawn(PinkFlower); end; On1018: spawn(Pinkie); end; On1088: spawn(Hyvern); end; On1103: spawn(WitchGuard); end; /* Ambush */ On1140: spawn(Tengu); end; On1138: spawn(ManaGuard); end; On1143: spawn(ManaSlayer); end; On1150: spawn(ManaTyrant); end; On1147: spawn(Koyntety); end; On1146: spawn(Flashmob); end; /* Other Christmas settings */ OnInstanceInit: /* Prepare the color code */ 'COLORCODE[0] = rand2(0, 2); 'COLORCODE[1] = rand2(0, 2); 'COLORCODE[2] = rand2(0, 2); 'COLORCODE[3] = rand2(0, 2); 'COLORCODE[4] = rand2(0, 2); 'COLORCODE[5] = rand2(0, 2); 'OBSCURECOLOR = any(0, 1); /* Prepare the Ambush Chamber */ 'AMBUSHTRI[0] = rand2(1, 17); do { 'AMBUSHTRI[1] = rand2(1, 17); } while ('AMBUSHTRI[1] == 'AMBUSHTRI[0]); do { 'AMBUSHTRI[2] = rand2(1, 17); } while ('AMBUSHTRI[2] == 'AMBUSHTRI[0] || 'AMBUSHTRI[2] == 'AMBUSHTRI[1]); 'AMBUSH_BMASK = 0; /* Prepare the Enigma */ 'TRUES=0; 'TRUTHSTAT[0]=any(false, true); if ('TRUTHSTAT[0]) 'TRUES+=1; 'TRUTHSTAT[1]=any(false, true); if ('TRUTHSTAT[1]) 'TRUES+=1; 'TRUTHSTAT[2]=any(false, ('TRUES >= 2 ? false : true)); 'TRUES=0; end; OnInit: /* Aethyra - Frontier Town */ "#XMAS21Core"::spawn(Fluffy, 16, "081-1"); "#XMAS21Core"::spawn(Poltergeist, 7, "081-1"); "#XMAS21Core"::spawn(Wisp, 7, "081-1"); "#XMAS21Core"::spawn(Spectre, 7, "081-1"); "#XMAS21Core"::spawn(WhiteSlime, 12, "081-1"); "#XMAS21Core"::spawn(SantaSlime, 4, "081-1"); "#XMAS21Core"::spawn(Moggun, 10, "081-1"); "#XMAS21Core"::spawn(Moonshroom, 7, "081-1", false); end; }