// 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 // 4096 - Governor was spawned // $@FORT_BLACKLIST = int array // Char ID which already raided this week // MAPFLAGS 025-1 mapflag zone SuperMMO 025-3 mapflag zone SuperMMO 026-0 mapflag zone SuperMMO 026-1 mapflag zone SuperMMO 026-2 mapflag zone SuperMMO ///////////////////////////////////////// // FUNCTIONS // FTCleanup(status) function script FTCleanup { // Kills whatever called this function if time is wrong if ($GAME_STORYLINE < 3) end; // Reset variables $FORTRESS_STATE=getarg(0); $@FORTRESS_STATUE=0; // Enable the Magic Statues enablenpc "Magic Statue#1"; enablenpc "Magic Statue#2"; enablenpc "Magic Statue#4"; enablenpc "Magic Statue#8"; enablenpc "Magic Statue#16"; // Kill stray monsters (including town gate) killmonsterall("025-1"); // Main gate if ($FORTRESS_STATE) { hideonnpc "Gate#F"; enablenpc "Yuko"; enablenpc "Ihclot"; enablenpc "Salohnic"; enablenpc "Xovilam"; enablenpc "Drahcir"; enablenpc "Selim"; enablenpc "Rum Barrel"; enablenpc "Commander Povo"; enablenpc "Commander Cadis"; enablenpc "Phoenix Rebirth"; enablenpc "Anin The Traveler"; enablenpc "The Impregnable Fortress"; enablenpc "#025-3_100_179"; donpcevent "#025-1_99_112::OnDisable"; deletearray $@FORT_BLACKLIST; } else { hideoffnpc "Gate#F"; disablenpc "Yuko"; disablenpc "Ihclot"; disablenpc "Salohnic"; disablenpc "Xovilam"; disablenpc "Drahcir"; disablenpc "Selim"; disablenpc "Rum Barrel"; disablenpc "Commander Povo"; disablenpc "Commander Cadis"; disablenpc "Phoenix Rebirth"; disablenpc "Anin The Traveler"; disablenpc "The Impregnable Fortress"; disablenpc "#025-3_100_179"; donpcevent "#025-1_99_112::OnEnable"; mapwarp("025-1", "025-2", 100, 27); } enablenpc "#025-1_100_123"; return; } // FTStatue(id) function script FTStatue { .@id=getarg(0); mesn l("Magic Statue"); mes l("There is an inscription: 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 false; // Break the statues? mesc l("Break the Statue?"), 1; if (!islegendary()) mesc l("* Will stun you for 10 seconds!"); next; if (askyesno() == ASK_YES) { if ($@FORTRESS_STATUE & .@id) return false; if (!islegendary()) sc_start SC_STUN, 10000, 1; doevent("Gate#F::OnStatueBreach"); mapannounce("025-1", strcharinfo(0)+" has broken a statue!", bc_map); $@FORTRESS_STATUE=$@FORTRESS_STATUE|.@id; return true; } return false; } ///////////////////////////////////////// // NPC SCRIPTS // Main gate - Also where the World Hero can begin the siege 025-1,99,112,0 script Gate#F NPC_NO_SPRITE,{ function spawnMob; function spawnCore; // Main Story block - WHAT if ($GAME_STORYLINE < 3) die(); // Still open if ($FORTRESS_STATE) end; // Siege ongoing if ($@FORTRESS_STATUE) end; // Only World Hero may interact if (strcharinfo(0) != $MOST_HEROIC$ && !is_master()) { dispbottom l("I will not assault the Fortress Island by myself. Instead, 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; mesc l("Assault?"), 1; mes l("* Ensure you and your team is ready and at their positions."); next; select l("Not now."), l("Information"), l("Bring it on, we're ready!"); mes ""; if (@menu == 1) { close; } else if (@menu == 2) { mesc l("* The siege resets at Tuesday 00:00"); mesc l("* Sieges increase in difficulty as they are won"); mesc l("* Unlike monster sieges, the difficulty does not fluctuates based on nÂș of players or their level!"); dnext; mesc l("* The warp to this map will be suspended until the siege is finished."); mesc l("* The town is liberated once the Monster Governor is slain."); mesc l("* Monster Governor will only show up when the town magic shield is broken."); mesc l("* Monster Governor gives 500,000 exp and 100,000 jexp to whoever deals most damage to it"); dnext; mesc l("* All monsters in the town and Impregnable Fortress give +25%% EXP"); mesc l("* You cannot teleport in the town."); mesc l("* This is a Cursed Lands map, watch out for MP during the fights as well"); mesc l("* The siege is lost if all players die."); mesc l("* Only one attempt can be made per day."); close; } // FIRE THE EVENT hideonnpc "Gate#F"; disablenpc "#025-1_100_123"; initnpctimer; // Reset variables $@FORTRESS_STATUE=2048; // Spawn the gate .@g=monster("025-1", 99, 113, strmobinfo(1, FortressGate), FortressGate, 1, "Gate#F::OnSesame"); .@bhp=getunitdata(.@g, UDT_MAXHP); .@bhp=.@bhp*(25+$MK_TEMPVAR)/25; // +4% per success or 8,000 HP setunitdata(.@g, UDT_MAXHP, .@bhp); setunitdata(.@g, UDT_HP, .@bhp); // Initial defending waves spawnCore(true); spawnCore(false); // Front Gate Guardians (Lv 70~80) getmapxy(.@m$, .@x, .@y, 0); .@x1=.@x-5; .@x2=.@x+5; .@y1=.@y-5; .@y2=.@y+5; for (.@i = 0; .@i < 4; ++.@i) { spawnMob(any(AzulSkullSlime, YellowSkullSlime, Forain, GreenDragon, Michel, EliteDuck, Troll, Moonshroom, Terranite), .@x1, .@y1, .@x2, .@y2); } // Player blacklist (unable to use 025-2 warp) maptimer2("025-1", 10, "Gate#F::OnMPBlacklist"); kamibroadcast($MOST_HEROIC$+"'s team has begun a siege on Fortress Town. Will they prevail?"); close; ///////////////////////////////////////////////////////// OnSesame: debugmes("[INFO] FORTRESS TOWN WAS BREACHED"); $@FORTRESS_STATUE = $@FORTRESS_STATUE|1024; donpcevent "#025-1_99_112::OnDisable"; kamibroadcast("The Fortress Town Gate has been breached!"); spawnCore(true); close; // Heartbeat (B1) OnTimer35000: if ($FORTRESS_STATE) end; .@breach=($@FORTRESS_STATUE & 1024); if (mobcount("025-1", "all") < (.@breach ? 180 : 90)) spawnCore(.@breach); end; // Heartbeat (B2) OnTimer70000: if ($FORTRESS_STATE) end; // Initial variables .@breach=($@FORTRESS_STATUE & 1024); .@ppl=getmapusers("025-1"); // Fail condition if (.@ppl <= 0) { kamibroadcast("Players failed to conquer the Fortress Island!"); FTCleanup($FORTRESS_STATE); end; } // Spawn mobs spawnCore(.@breach); // Summon reinforcements maptimer2("025-1", 10, "Gate#F::OnMPReinforce"); // Restart timer initnpctimer; end; ///////////////////////////////////////////////////////// OnMPBlacklist: array_push($@FORT_BLACKLIST, getcharid(0)); goto OnMPReinforce; OnMPReinforce: // Dispose dead bodies if (ispcdead() || getmap() != "025-1") { warp "025-2", 96, 25; end; } // Summon allies // Last a whole minute summon("Allied Guard", any(FallenGuard1, FallenGuard2, FallenGuard3)); end; ///////////////////////////////////////////////////////// OnStatueBreach: spawnCore(true); getmapxy(.@m$, .@x, .@y, 0); .@x1=.@x-5; .@x2=.@x+5; .@y1=.@y-5; .@y2=.@y+5; // Statue Guardians (Lv 70~90) for (.@i = 0; .@i < 5; ++.@i) { spawnMob(any(AzulSkullSlime, YellowSkullSlime, Forain, GreenDragon, Michel, EliteDuck, Troll, Moonshroom, Terranite, JackO, BlackMamba, Centaur, GoboBear, TerraniteProtector), .@x1, .@y1, .@x2, .@y2); } // Maybe spawn monster governor if ( ($@FORTRESS_STATUE & 1) && ($@FORTRESS_STATUE & 2) && ($@FORTRESS_STATUE & 4) && ($@FORTRESS_STATUE & 8) && ($@FORTRESS_STATUE & 16)) { // The monster Governor shall now make their appearance! spawnCore(true); .@x1=97; .@y1=21; .@x2=102; .@y2=25; // Governor's Personal Bodyguard (Lv 90~110) for (.@i = 0; .@i < 4; ++.@i) { spawnMob(any(TerraniteProtector, LavaSkullSlime, VanityPixie, HolyPixie, ShadowPixie, NulityPixie, BlackSkullSlime, Reaper, NightmareDragon, WhirlyBird, PinkieSuseran), .@x1, .@y1, .@x2, .@y2); } .@mob=monster("025-1", any(99, 100), any(22, 23, 24), "Monster Governor", MonsterGeneral, 1, "Gate#F::OnConquest"); // Stat and Strengthen the governor // Set governor metadata setunitdata(.@mob, UDT_LEVEL, 100+$MK_TEMPVAR); // Update monster modes .@opt=getunitdata(.@mob, UDT_MODE); .@opt=.@opt|MD_AGGRESSIVE; .@opt=.@opt|MD_BOSS; .@opt=.@opt|MD_NOKNOCKBACK; setunitdata(.@mob, UDT_MODE, .@opt); setunitdata(.@mob, UDT_RACE, RC_Legendary); // Increase health in 2% per siege .@bhp=75000; .@bhp=.@bhp*(50+$MK_TEMPVAR)/50; setunitdata(.@mob, UDT_MAXHP, .@bhp); setunitdata(.@mob, UDT_HP, .@bhp); // Accuracy is very very high, immune to crits, always crit setunitdata(.@mob, UDT_HIT, 9999); setunitdata(.@mob, UDT_LUK, 65535); // Increase damage in 1% per siege (remember crit) .@atk=320; .@atk=.@atk*(100+$MK_TEMPVAR)/100; setunitdata(.@mob, UDT_ATKMIN, .@atk); setunitdata(.@mob, UDT_ATKMAX, .@atk); // Ranged monster setunitdata(.@mob, UDT_ATKRANGE, 8); // Increase defenses in 0.5% per siege .@def=getunitdata(.@mob, UDT_DEF); .@def=.@def*(200+$MK_TEMPVAR)/200; setunitdata(.@mob, UDT_DEF, .@def); .@def=getunitdata(.@mob, UDT_MDEF); .@def=.@def*(200+$MK_TEMPVAR)/200; setunitdata(.@mob, UDT_MDEF, .@def); .@def=getunitdata(.@mob, UDT_FLEE); .@def=.@def*(200+$MK_TEMPVAR)/200; setunitdata(.@mob, UDT_FLEE, .@def); .@def=getunitdata(.@mob, UDT_PDODGE); .@def=.@def*(200+$MK_TEMPVAR)/200; setunitdata(.@mob, UDT_PDODGE, .@def); // "Normalize" criticals setunitdata(.@mob, UDT_CRIT, rand2(900, 2700)); // Announce that the Fortress Town can now be conquered kamibroadcast("##1"+"Aegis Scutum has been nullified, the Monster Governor has appeared at Fortress Town!"); mapannounce "025-1", "Defeat the Monster Governor to capture the fortress town.", bc_map; } end; ///////////////////////////////////////////////////////// // spawnMob(Mob, X1, Y1, X2, Y2) function spawnMob { //.@mob=monster("025-1", rand2(getarg(1), getarg(3)), rand2(getarg(2), getarg(4)), strmobinfo(1, getarg(0)), getarg(0), 1); .@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(.@mob, 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*2; ++.@i) { spawnMob(any(Tipiou, Pollet, Wolvern, FireSkull, DarkLizard, BlackScorpion, EarthFairy, FireFairy, WaterFairy, WindFairy, PoisonFairy, DustGatling, DustRifle, DustRevolver, MountainSnake, HoodedNinja, ForestMushroom, GoldenScorpion, Yeti), .@x1, .@y1, .@x2, .@y2); } // Level 60~80 Section for (.@i = 0; .@i < .@am*3/2+1; ++.@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: sleep(200); // Ensure the NPCs will exist when this run FTCleanup($FORTRESS_STATE); end; OnTue0000: .@cl=$FORTRESS_STATE; FTCleanup(false); if (.@cl) kamibroadcast("The Monster Army has retaken Fortress Town!"); end; OnConquest: // Failsafe if ($GAME_STORYLINE < 3) end; // Advance the victory count $MK_TEMPVAR+=1; // Handle rewards in low priority freeloop(true); for (.@i=0; .@i < getarraysize($@FORT_BLACKLIST); .@i++) { .@cid=$@FORT_BLACKLIST[.@i]; rodex_sendmail(.@cid, "Commander Povo", "Fortress Town Reward", "For your bravure in Fortress Town conquest! Cheers!", 0, StrangeCoin, 1+$MK_TEMPVAR); } freeloop(false); // Clean up the remainders of the fight FTCleanup(true); kamibroadcast("Fortress Town has been captured by the Allied Forces!"); // Experience injection to the brave (500k EXP, 100k JEXP) if (playerattached()) { getexp 500000, 100000; getitem StrangeCoin, rand2(40,50); specialeffect(FX_FANFARE, AREA, getcharid(3)); } // Experience injection to the survivors maptimer("025-1", 10, "Gate#F::OnConBonus"); stopnpctimer; // Begin Fires of Steam if needed if (!$FIRESOFSTEAM && $MK_TEMPVAR >= MK_FIRESOFSTEAM_START) { kamibroadcast("Andrei Sakar : It has been about three months since we begun battling for control overthe Fortress Town."); sleep(5000); kamibroadcast("Andrei Sakar : Since this begun, however, we've heard nothing of Artis Town."); sleep(5000); kamibroadcast("Andrei Sakar : Therefore, I invite all of you, brave adventurers, to go on an expedition with me to Artis."); sleep(5000); kamibroadcast("Andrei Sakar : "+b("Hopefully nothing terrible happened... Nard shall provide us transport.")); sleep(5000); kamibroadcast("Andrei Sakar : I only want people strong enough to battle on the Fortress because the risks are high. Onwards! To victory! I'll be waiting"); $FIRESOFSTEAM = 1; } end; OnConBonus: message strcharinfo(0), l("Commander Povo : Good job %s. You did well.", lg("girl", "man")); // TRANSLATORS: Preserve whitespace. .@it=any(ApanaCake, SacredLifePotion, SacredManaPotion, SacredImmortalityPotion, DeathPotion, PurificationPotion, ApanaCake); if (.@it == ApanaCake || .@it == PurificationPotion) .@qn = rand2(2, 5); else .@qn = 1; getitem .@it, .@qn; getexp 25000, 10000; end; } ///////////////////////////////////////////////////////// // Statue NPCs 025-1,32,55,0 script Magic Statue#1 NPC_STATUE_WIZARD,{ .@b=FTStatue(strnpcinfo(2, "0")); if (.@b) disablenpc .name$; close; OnInit: .distance=2; end; } 025-1,160,25,0 duplicate(Magic Statue#1) Magic Statue#2 NPC_STATUE_BACCHUS 025-1,156,97,0 duplicate(Magic Statue#1) Magic Statue#4 NPC_STATUE_FAFA 025-1,134,70,0 duplicate(Magic Statue#1) Magic Statue#8 NPC_STATUE_EVILMAN 025-1,80,37,0 duplicate(Magic Statue#1) Magic Statue#16 NPC_STATUE_GUARD ///////////////////////////////////////////////////////// // The Impregnable Fortress Gate 025-1,99,20,0 script The Impregnable Fortress NPC_NO_SPRITE,3,1,{ // Operation not permitted if (!$FORTRESS_STATE || $@FORTRESS_STATUE) end; // Not unlocked if ($GAME_STORYLINE >= 3 && $MK_TEMPVAR < MKIF_LV_0F) { mesc l("The gate is sealed shut."), 1; mesc l("The monster army is still strong on this floor!"), 1; mesc l("Minimum wins: %d/%d", $MK_TEMPVAR, MKIF_LV_0F), 1; close; } mesc l("Visit the Impregnable Fortress, 0F?"); mesc l("Minimum wins: %d/%d", $MK_TEMPVAR, MKIF_LV_0F); if (askyesno() == ASK_YES) warp "025-3", 100, 178; closeclientdialog; close; OnTouch: // Operation not permitted if (!$FORTRESS_STATE || $@FORTRESS_STATUE) end; // Not unlocked if ($GAME_STORYLINE >= 3 && $MK_TEMPVAR < MKIF_LV_0F) end; warp "025-3", 100, 178; end; OnInit: .distance=4; end; } ///////////////////////////////////////////////////////// // 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 || $@FORTRESS_STATUE) end; // Open if ($FORTRESS_STATE) cwarp "025-1", 99, 122; // Blacklisted if (array_find($@FORT_BLACKLIST, getcharid(0)) != -1) end; // Not blacklisted warp "025-1", 99, 122; end; }