// TMW2 Script // Notes: The Monster King will retake the town every // OnTue0000 // (Tuesday, midnight) // Only the world hero may begin a siege. // Only one siege per day is allowed // Writes to MK Temp Var. This variable will unlock the castle gates // Then the inner gates, and finally, will be a co-requisite to the floors // Variables: // $FORTRESS_STATE = int // 0 - Locked // 1 - Unlocked // $@FORTRESS_STATUE = bitmask // 1,2,4,8,16 - broken statues // 1024 - Fortress Gate // 2048 - Siege started // $@FORT_BLACKLIST = int array // Char ID which already raided this week // TODO: Use bg() - maybe with dummysd? What will increase allies count? // TODO: Gate control during siege (not $FORTRESS_STATE). Gate monster. // TODO: Spawn the monster general for each statue. Count their deaths. // TODO: Spawn Monster Governor (and add it) once statue is broken. ::OnConquest // TODO: Record nÂș of victories. Strengthen the governor. // TODO: Provide a way to resume failed attempts. Move Phoenix inside. // TODO: Testing. // Use setwall() instead of builtin collision? (Deprecates out NPC) // TODO: NPCs from inside: Bank. Barber. Aeros Shop. Etc. // TODO: Spawn inside and outside when siege begins. // TODO: Heartbeat - (Re)Spawn monsters inside every X seconds // MAPFLAGS 025-1 mapflag zone SuperMMO 025-3 mapflag zone SuperMMO 026-0 mapflag zone SuperMMO 026-1 mapflag zone SuperMMO ///////////////////////////////////////// // FUNCTIONS // FTCleanup(status) function script FTCleanup { $FORTRESS_STATE=getarg(0); // TODO: Magic Statues (FTStatue) $@FORTRESS_STATUE=0; //enablenpc "Magic Statue#F_1"; //enablenpc "Magic Statue#F_2"; //enablenpc "Magic Statue#F_4"; //enablenpc "Magic Statue#F_8"; //enablenpc "Magic Statue#F_16"; // TODO: Gate // TODO: ::OnConquest // TODO: Kill stray monsters //killmonsterall // Main gate if ($FORTRESS_STATE) { disablenpc "Fortress"; donpcevent "#025-1_99_112::OnDisable"; } else { enablenpc "Fortress"; donpcevent "#025-1_99_112::OnEnable"; mapwarp("025-1", "025-2", 100, 27); } deletearray $@FORT_BLACKLIST; enablenpc "#025-1_100_123"; return; } // FTStatue(id) function script FTStatue { .@id=getarg(0); mesn l("Magic Statue"); mes l("There is a reading: The Mana Source. The Moubootaur. The Monster King."); mes l("The war. The blood. The inspiration. The mana. The world. The defiance."); mes l("The guard. The heir. The originals. The races. The later. The seal."); mes l("The fragments. The war. The Terranite. AEGIS MAGNA PROTECTIVE SCUTUM."); next; mesc l("It seems to be a defensive spell."); if ($FORTRESS_STATE) return; // Break the statues? mesc l("Break the Statue?"), 1; next; if (askyesno() == ASK_YES) { if ($@FORTRESS_STATUE & .@id) return; sc_start SC_STUN, 10000, 1; //getmapxy(); //areamonster(); //mapannounce(); //maybe spawn monster governor $@FORTRESS_STATUE=$@FORTRESS_STATUE|.@id; } return; } ///////////////////////////////////////// // NPC SCRIPTS // Main gate - Also where the World Hero can begin the siege 025-1,99,112,0 script Fortress NPC_NO_SPRITE,{ function spawnMob; function spawnCore; // Main Story block - WHAT if ($GAME_STORYLINE < 3) die(); // Still open if ($FORTRESS_STATE) end; // Only World Hero may interact if (strcharinfo(0) != $MOST_HEROIC$) { dispbottom l("I will not assault the Fortress Island. I'll wait for %s.", $MOST_HEROIC$); end; } // Hey, you can assault the town! mesc ".:: "+l("THE FORTRESS ISLAND TOWN") + " ::.", 1; mes l("Behind this gate, lies the Fortress Island Town."); next; mesc ".:: "+l("THE FORTRESS ISLAND TOWN") + " ::.", 1; mes l("Assault?"); mesc l("Lorem ipsum dolor sit amet"), 1; next; if (askyesno() == ASK_NO) close; // FIRE THE EVENT disablenpc .name$; disablenpc "#025-1_100_123"; initnpctimer; // Reset variables $@FORTRESS_STATUE=2048; // Spawn the gate monster("025-1", 99, 113, "Fortress Gate", FortressGate, 1, .name$+"::OnOpenGate"); // Initial defending waves spawnCore(true); spawnCore(false); // TODO: Enable the statues // Player blacklist (unable to use 025-2 warp) maptimer2("025-1", 10, "Fortress::OnMPBlacklist"); kamibroadcast($MOST_HEROIC$+"'s team has begun a siege on Fortress Town. Will they prevail?"); close; ///////////////////////////////////////////////////////// OnOpenGate: // FIXME Broken $@FORTRESS_STATUE = $@FORTRESS_STATUE|1024; donpcevent "#025-1_99_112::OnDisable"; kamibroadcast("The Fortress Town Gate has been breached!"); close; // Heartbeat (B1) OnTimer15000: .@breach=($@FORTRESS_STATUE & 1024); spawnCore(.@breach); end; // Heartbeat (B2) OnTimer30000: .@breach=($@FORTRESS_STATUE & 1024); .@ppl=getmapusers("025-1"); // Fail condition if (.@ppl <= 0) { kamibroadcast("Players failed to conquest the Fortress Island!"); FTCleanup($FORTRESS_STATE); end; } // Spawn mobs spawnCore(.@breach); // Summon reinforcements maptimer2("025-1", 10, "Fortress::OnMPReinforce"); // Restart timer initnpctimer; end; ///////////////////////////////////////////////////////// OnMPBlacklist: array_push($@FORT_BLACKLIST, getcharid(0)); goto OnMPReinforce; OnMPReinforce: // Dispose dead bodies if (ispcdead()) { warp "025-2", 96, 25; end; } // Summon allies // Last a whole minute summon("Allied Guard", any(FallenGuard1, FallenGuard2, FallenGuard3)); end; ///////////////////////////////////////////////////////// // spawnMob(Mob, X1, Y1, X2, Y2) function spawnMob { .@mob=areamonster("025-1", getarg(1), getarg(2), getarg(3), getarg(4), strmobinfo(1, getarg(0)), getarg(0), 1); .@opt=getunitdata(.@mob, UDT_MODE); // Make aggressive .@opt=.@opt|MD_AGGRESSIVE; // All forces can suffer knockback if (.@opt & MD_NOKNOCKBACK) .@opt=.@opt^MD_NOKNOCKBACK; // Save new options setunitdata(.@ob, UDT_MODE, .@opt); // Increase health in 1%+1% per siege .@bhp=getunitdata(.@mob, UDT_MAXHP); .@bhp=.@bhp*(101+$MK_TEMPVAR)/100; setunitdata(.@mob, UDT_MAXHP, .@bhp); setunitdata(.@mob, UDT_HP, .@bhp); // Increase accuracy in 10%+1% per siege .@acc=getunitdata(.@mob, UDT_HIT); .@acc=.@acc*(110+$MK_TEMPVAR)/100; setunitdata(.@mob, UDT_HIT, .@acc); // TODO: adjust ViewRange return; } // spawnCore(breach) function spawnCore { // Now, the thing is, I don't care with how powerful your invading forces are. // I only care with how many success you have. if (getarg(0)) { .@x1=24; .@y1=21; .@x2=175; .@y2=105; .@am=2+$MK_TEMPVAR; } else { .@x1=25; .@y1=110; .@x2=180; .@y2=120; .@am=1+($MK_TEMPVAR/3); } freeloop(true); // Level 40~60 Section for (.@i = 0; .@i < .@am*3; ++.@i) { spawnMob(any(Tipiou, Pollet, Wolvern, FireSkull, DarkLizard, BlackScorpion, EarthFairy, FireFairy, WaterFairy, WindFairy, NatureFairy, DustGatling, DustRifle, DustRevolver, MountainSnake, HoodedNinja, ForestMushroom, GoldenScorpion, Yeti), .@x1, .@y1, .@x2, .@y2); } // Level 60~80 Section for (.@i = 0; .@i < .@am*2; ++.@i) { spawnMob(any(Yeti, WickedMushroom, Archant, Scar, Crafty, AzulSkullSlime, YellowSkullSlime, Forain, GreenDragon, Michel, EliteDuck, Troll, Moonshroom, Terranite), .@x1, .@y1, .@x2, .@y2); } // Level 80~100 section for (.@i = 0; .@i < .@am; ++.@i) { spawnMob(any(RedSkullSlime, Terranite, JackO, BlackMamba, GreenSkullSlime, Centaur, GoboBear, TerraniteProtector), .@x1, .@y1, .@x2, .@y2); } // Summoners Section for (.@i = 0; .@i < .@am; ++.@i) { spawnMob(any(GreenSlimeMother, BlueSlimeMother, YellowSlimeMother, RedSlimeMother, WhiteSlimeMother, AzulSlimeMother, LavaSlimeMother, BlackSlimeMother), .@x1, .@y1, .@x2, .@y2); } if (getarg(0)) { // DemiBoss section (Internal only, increases every ~2 weeks) for (.@i = 0; .@i < (.@am/2); ++.@i) { spawnMob(any(VanityPixie, HolyPixie, ShadowPixie, NulityPixie, Reaper, BlackSkullSlime, NightmareDragon, WhirlyBird, PinkieSuseran), .@x1, .@y1, .@x2, .@y2); } } freeloop(false); return; } ///////////////////////////////////////////////////////// OnInit: FTCleanup($FORTRESS_STATE); end; OnTue0000: FTCleanup(false); kamibroadcast("The Monster Army has retaken Fortress Town!"); end; OnConquest: $MK_TEMPVAR+=1; FTCleanup(true); kamibroadcast("Fortress Town has been captured by the Allied Forces!"); end; } ///////////////////////////////////////////////////////// // This exit must work even if gate is closed (bugfix) 025-1,99,111,0 script #FortressTownOut NPC_HIDDEN,1,0,{ end; OnTouch: if (!$FORTRESS_STATE) slide 100, 114; end; } // TODO: 100,20 - The Impregnable Fortress Gate // And don't forget the curse timer ///////////////////////////////////////////////////////// // Real access to 025-1 map 025-2,96,24,0 script Fortress Town Access NPC_HIDDEN,8,0,{ end; OnTouch: // Disabled if ($GAME_STORYLINE < 3 || !is_admin() || $@FORTRESS_STATUE) end; // Blacklisted if (array_find($@FORT_BLACKLIST, getcharid(0)) != -1) end; // Not blacklisted warp "025-1", 99, 122; end; }