// TMW2 Scripts // Author: // Jesusalva // Description: // Controls map domain 030 and provide helpers. See constants; // Player Variables: // MAZE_ID → ID of the maze being used // MAZE_MAP$ → Map being used for the maze // MAZE_INST → Instance ID of the Maze ///////////////////////////////////////////////////////////////////////////////// // CreateMaze(scope=IOT_CHAR{, size=MAZE_SIZE_S}) // Creates the maze instances so they can be configured // But does not initializes anything. function script CreateMaze { .@scope = getarg(0, IOT_CHAR); .@size = getarg(1, MAZE_SIZE_S); // Small mazes (30x30 average) (24 total) if (.@size & MAZE_SIZE_S) { .@p = getarraysize(.@ids); setarray .@ids[.@p], 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24; } // Medium mazes (45x45 average) (15 total) if (.@size & MAZE_SIZE_M) { .@p = getarraysize(.@ids); setarray .@ids[.@p], 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39; } // Great mazes (60x60 average) (20 total) if (.@size & MAZE_SIZE_G) { .@p = getarraysize(.@ids); setarray .@ids[.@p], 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59; } // Xtra mazes (75x75 average) (10 total) if (.@size & MAZE_SIZE_X) { .@p = getarraysize(.@ids); setarray .@ids[.@p], 60, 61, 62, 63, 64, 65, 66, 67, 68, 69; } // Abs. mazes (90x90 average) (6 total) if (.@size & MAZE_SIZE_A) { .@p = getarraysize(.@ids); setarray .@ids[.@p], 70, 71, 72, 73, 74, 75; } // Get a random maze, but it must not be repeated do { .@r = any_of(.@ids); if (MAZE_ID == .@r) continue; MAZE_ID = .@r; .@MAZEMP$=sprintf("030-%02d", MAZE_ID); MAZE_MAP$=sprintf("mz%02d@"+getcharid(0), MAZE_ID); // Maze is not yet started if (.@scope == IOT_CHAR) { MAZE_INST = instance_create("Maze "+MAZE_ID+" "+getcharid(0), getcharid(3), IOT_CHAR); // Failed if (MAZE_INST < 0) { consolebug("Instance \"%s\" already exists! (Error %d)", "Maze "+MAZE_ID+" "+getcharid(0), MAZE_INST); continue; // Get a new maze } // Attach map instance_attachmap(.@MAZEMP$, MAZE_INST, false, MAZE_MAP$); } else { consolebug("Scope %d not yet supported by maze system", .@scope); return 0; // Exit early } } while (MAZE_INST < 0); return MAZE_ID; } ///////////////////////////////////////////////////////////////////////////////// // InitMaze(duration=2 hours, random_coords=yes, treasure=no) // Puts maze to work and send player there. // Exit must have been configured prior to the maze. function script InitMaze { .@t = getarg(0, 7200); instance_set_timeout(.@t, .@t, MAZE_INST); instance_init(MAZE_INST); // Find random, warpable coordinates .@e=0; .@x=0; .@y=0; if (getarg(1, true)) { .@mx=getmapinfo(MAPINFO_SIZE_X, MAZE_MAP$)-20; .@my=getmapinfo(MAPINFO_SIZE_Y, MAZE_MAP$)-20; } else { .@mx=40; // Wouldn't (30,30) be safer? .@my=40; } do { .@x = rand2(20, .@mx); .@y = rand2(20, .@my); .@e += 1; if (.@e > 30) { consolebug("Too many failures at Maze \"%s\"! Trying anyway!", MAZE_MAP$); break; } } while (!checknpccell(MAZE_MAP$, .@x, .@y, cell_chkpass)); // Teleport the player warp MAZE_MAP$, .@x, .@y; // Add a random treasure chest if set to do so if (getarg(2, false)) { .@n$=instance_npcname(sprintf("#T_030-%02d", MAZE_ID), MAZE_INST); .@mx=getmapinfo(MAPINFO_SIZE_X, MAZE_MAP$)-20; .@my=getmapinfo(MAPINFO_SIZE_Y, MAZE_MAP$)-20; do { .@x = rand2(20, .@mx); .@y = rand2(20, .@my); .@e += 1; if (.@e > 20) break; } while (!checknpccell(MAZE_MAP$, .@x, .@y, cell_chkpass)); movenpc(.@n$, .@x, .@y); } return true; } ///////////////////////////////////////////////////////////////////////////////// // MazeMobs(level=BaseLevel, chests=yes, density_redux=10) // Puts monsters on the maze. Less density_redux is more mobs. function script MazeMobs { .@mx=getmapinfo(MAPINFO_SIZE_X, MAZE_MAP$)-20; .@my=getmapinfo(MAPINFO_SIZE_Y, MAZE_MAP$)-20; .@tl=(20-.@mx)*(20-.@my) * 3 / 10; // Total tiles + collision guess .@tl=.@tl / getarg(2, 10) + 1; // Monster density /* *** Copied from 006-5/groata.txt & 018-2-2/main.txt! *** */ /* ********* Spawn monsters based on DTOWER_FLOOR ********* */ .@lv = getarg(0, BaseLevel); .@mb[0] = MagicGoblin; .@mb[1] = CaveMaggot; // Artillery & Chests // TODO: Mimics? if (getarg(1, true)) { if (.@lv > 10) array_push(.@mb, BronzeChest); if (.@lv > 15) array_push(.@mb, BronzeMimic); if (.@lv > 20) array_push(.@mb, SmallMagicBif); if (.@lv > 30) array_push(.@mb, Bif); if (.@lv > 45) array_push(.@mb, SilverChest); if (.@lv > 50) array_push(.@mb, SilverMimic); if (.@lv > 55) array_push(.@mb, MagicBif); if (.@lv > 75) array_push(.@mb, GoldenChest); if (.@lv > 80) array_push(.@mb, GoldenMimic); if (.@lv > 85) array_push(.@mb, BigMagicBif); if (.@lv > 105) array_push(.@mb, PrismChest); } if (.@lv > 40) array_push(.@mb, RobinBandit); if (.@lv > 50) array_push(.@mb, DustGatling); if (.@lv > 60) array_push(.@mb, DustRifle); if (.@lv > 70) array_push(.@mb, DustRevolver); if (.@lv > 80) array_push(.@mb, DustBoss); if (.@lv > 90) array_push(.@mb, GreatMoubooSlime); if (.@lv > 100) array_push(.@mb, Jhon); // Monsters if (is_between2(0, .@lv, 30)) { array_push(.@mb, Piou); array_push(.@mb, Piousse); array_push(.@mb, Squirrel); array_push(.@mb, ManaPiou); array_push(.@mb, ForestPiou); array_push(.@mb, RedButterfly); array_push(.@mb, Maggot); array_push(.@mb, CandorScorpion); array_push(.@mb, HouseMaggot); array_push(.@mb, LittleYellowSlime); array_push(.@mb, Ratto); array_push(.@mb, RudolphSlime); array_push(.@mb, MoubooSlime); array_push(.@mb, Croc); array_push(.@mb, Scorpion); array_push(.@mb, SmallFrog); } if (is_between2(10, .@lv, 40)) { array_push(.@mb, BigFrog); array_push(.@mb, Lavern); array_push(.@mb, LittleRedSlime); array_push(.@mb, ChocolateSlime); array_push(.@mb, Blub); array_push(.@mb, Duck); array_push(.@mb, Bat); array_push(.@mb, CaveMaggot); array_push(.@mb, ManaGhost); array_push(.@mb, ManaBug); array_push(.@mb, Fluffy); array_push(.@mb, FireGoblin); array_push(.@mb, ViciousSquirrel); array_push(.@mb, RedScorpion); array_push(.@mb, WhiteSlime); array_push(.@mb, AzulSlime); array_push(.@mb, DesertLogHead); } if (is_between2(20, .@lv, 50)) { array_push(.@mb, RedSlime); array_push(.@mb, PoisonSpikyMushroom); array_push(.@mb, DesertBandit); array_push(.@mb, OceanCroc); array_push(.@mb, ToppyBlub); array_push(.@mb, Sarracenus); array_push(.@mb, IceMaggot); array_push(.@mb, VampireBat); array_push(.@mb, Bandit); array_push(.@mb, Pinkie); array_push(.@mb, LivingPotato); array_push(.@mb, Assassin); array_push(.@mb, Skeleton); } if (is_between2(30, .@lv, 60)) { array_push(.@mb, CaveSnake); array_push(.@mb, GreenSlime); array_push(.@mb, CopperSlime); array_push(.@mb, YellowSlime); array_push(.@mb, SantaSlime); array_push(.@mb, LavaSlime); array_push(.@mb, Bluepar); array_push(.@mb, DeathCat); array_push(.@mb, Moggun); array_push(.@mb, SeaSlime); array_push(.@mb, RedMushroom); array_push(.@mb, Mouboo); array_push(.@mb, LogHead); array_push(.@mb, CandiedSlime); array_push(.@mb, OldSnake); array_push(.@mb, GrassSnake); } if (is_between2(40, .@lv, 70)) { array_push(.@mb, GiantMaggot); array_push(.@mb, IcedFluffy); array_push(.@mb, Snake); array_push(.@mb, BlackSlime); array_push(.@mb, Tipiou); array_push(.@mb, AlphaMouboo); array_push(.@mb, Pollet); array_push(.@mb, PiouKnight); array_push(.@mb, Shrewboo); } if (is_between2(40, .@lv, 80)) { array_push(.@mb, Wolvern); array_push(.@mb, FireSkull); array_push(.@mb, DarkLizard); } if (is_between2(50, .@lv, 90)) { array_push(.@mb, ArmoredSkeleton); array_push(.@mb, BlackScorpion); array_push(.@mb, ElectroWorm); array_push(.@mb, EarthFairy); array_push(.@mb, FireFairy); array_push(.@mb, WaterFairy); array_push(.@mb, WindFairy); array_push(.@mb, PoisonFairy); array_push(.@mb, MountainSnake); array_push(.@mb, HoodedNinja); array_push(.@mb, ForestMushroom); array_push(.@mb, GoldenScorpion); } if (is_between2(60, .@lv, 100)) { array_push(.@mb, Yeti); array_push(.@mb, FallenGuard1); array_push(.@mb, GreenSlimeMother); array_push(.@mb, SnowFlower); array_push(.@mb, BlueSlimeMother); array_push(.@mb, WickedMushroom); array_push(.@mb, CopperSlimeMother); array_push(.@mb, YellowSlimeMother); array_push(.@mb, RedSlimeMother); array_push(.@mb, ChocolateSlimeMother); array_push(.@mb, WhiteSlimeMother); array_push(.@mb, Archant); array_push(.@mb, Scar); } if (is_between2(70, .@lv, 110)) { array_push(.@mb, AzulSlimeMother); array_push(.@mb, SeaSlimeMother); array_push(.@mb, LavaSlimeMother); array_push(.@mb, BlackSlimeMother); array_push(.@mb, Crafty); array_push(.@mb, Forain); array_push(.@mb, GreenDragon); array_push(.@mb, Michel); array_push(.@mb, Troll); } if (is_between2(80, .@lv, 120)) { array_push(.@mb, EliteDuck); array_push(.@mb, AzulSkullSlime); array_push(.@mb, Moonshroom); array_push(.@mb, RedSkullSlime); array_push(.@mb, Terranite); array_push(.@mb, JackO); array_push(.@mb, BlackMamba); array_push(.@mb, GreenSkullSlime); array_push(.@mb, BloodyMouboo); array_push(.@mb, Centaur); array_push(.@mb, GoboBear); } if (is_between2(90, .@lv, 130)) { array_push(.@mb, CopperSkullSlime); array_push(.@mb, LavaSkullSlime); array_push(.@mb, BlackSkullSlime); array_push(.@mb, GiantCaveMaggot); array_push(.@mb, TerraniteProtector); array_push(.@mb, VanityPixie); array_push(.@mb, HolyPixie); } if (is_between2(100, .@lv, 140)) { array_push(.@mb, ShadowPixie); array_push(.@mb, NulityPixie); array_push(.@mb, Reaper); array_push(.@mb, NightmareDragon); array_push(.@mb, Snail); array_push(.@mb, WhirlyBird); } if (is_between2(110, .@lv, 150)) { array_push(.@mb, PinkieSuseran); array_push(.@mb, Mandragora); array_push(.@mb, PinkieMaximus); } if (.@lv > 120) { array_push(.@mb, Junglefowl); array_push(.@mb, Tengu); array_push(.@mb, Moubi); } if (.@lv > 130) { array_push(.@mb, SuperiorShroom); array_push(.@mb, Nutcracker); array_push(.@mb, Golem); } if (.@lv > 140) { array_push(.@mb, SiegeTower); array_push(.@mb, GreenhornAbomination); array_push(.@mb, ShadowTortuga); array_push(.@mb, FireElement); array_push(.@mb, WaterElement); array_push(.@mb, EarthElement); array_push(.@mb, WindElement); } if (.@lv > 150) { array_push(.@mb, SacredWisp); array_push(.@mb, EvilWisp); array_push(.@mb, PanthomWisp); array_push(.@mb, EpiphanyWisp); } if (.@lv > 175) array_push(.@mb, Tortuga); /* Spawn them and make hostile */ freeloop(true); for (.@i = 0; .@i < 1+(.@tl); .@i++) { .@mid = any_of(.@mb); .@m=areamonster(MAZE_MAP$, 20, 20, .@mx, .@my, strmobinfo(1, .@mid), .@mid, 1); set_aggro(.@m); } freeloop(false); return; } ///////////////////////////////////////////////////////////////////////////////// // RenewMaze(duration=2 hours) // Renews the map expiration time function script RenewMaze { .@t = getarg(0, 7200); instance_set_timeout(.@t, .@t, MAZE_INST); return true; } ///////////////////////////////////////////////////////////////////////////////// // Configure maze maps as MMO zones 030-01 mapflag zone MMO 030-02 mapflag zone MMO 030-03 mapflag zone MMO 030-04 mapflag zone MMO 030-05 mapflag zone MMO 030-06 mapflag zone MMO 030-07 mapflag zone MMO 030-08 mapflag zone MMO 030-09 mapflag zone MMO 030-10 mapflag zone MMO 030-11 mapflag zone MMO 030-12 mapflag zone MMO 030-13 mapflag zone MMO 030-14 mapflag zone MMO 030-15 mapflag zone MMO 030-16 mapflag zone MMO 030-17 mapflag zone MMO 030-18 mapflag zone MMO 030-19 mapflag zone MMO 030-20 mapflag zone MMO 030-21 mapflag zone MMO 030-22 mapflag zone MMO 030-23 mapflag zone MMO 030-24 mapflag zone MMO 030-25 mapflag zone MMO 030-26 mapflag zone MMO 030-27 mapflag zone MMO 030-28 mapflag zone MMO 030-29 mapflag zone MMO 030-30 mapflag zone MMO 030-31 mapflag zone MMO 030-32 mapflag zone MMO 030-33 mapflag zone MMO 030-34 mapflag zone MMO 030-35 mapflag zone MMO 030-36 mapflag zone MMO 030-37 mapflag zone MMO 030-38 mapflag zone MMO 030-39 mapflag zone MMO 030-40 mapflag zone MMO 030-41 mapflag zone MMO 030-42 mapflag zone MMO 030-43 mapflag zone MMO 030-44 mapflag zone MMO 030-45 mapflag zone MMO 030-46 mapflag zone MMO 030-47 mapflag zone MMO 030-48 mapflag zone MMO 030-49 mapflag zone MMO 030-50 mapflag zone MMO 030-51 mapflag zone MMO 030-52 mapflag zone MMO 030-53 mapflag zone MMO 030-54 mapflag zone MMO 030-55 mapflag zone MMO 030-56 mapflag zone MMO 030-57 mapflag zone MMO 030-58 mapflag zone MMO 030-59 mapflag zone MMO 030-60 mapflag zone MMO 030-61 mapflag zone MMO 030-62 mapflag zone MMO 030-63 mapflag zone MMO 030-64 mapflag zone MMO 030-65 mapflag zone MMO 030-66 mapflag zone MMO 030-67 mapflag zone MMO 030-68 mapflag zone MMO 030-69 mapflag zone MMO 030-70 mapflag zone MMO 030-71 mapflag zone MMO 030-72 mapflag zone MMO 030-73 mapflag zone MMO 030-74 mapflag zone MMO 030-75 mapflag zone MMO ///////////////////////////////////////////////////////////////////////////////// // Add Treasure chests 030-01,0,0,0 script #T_030-01 NPC_CHEST,{ if (!reachable(.x, .y, 3)) end; callfunc "TreasureBox", 150; // 1.5% extra chance specialeffect(.dir == 0 ? 24 : 25, AREA, getnpcid()); // closed ? opening : closing close; OnInit: .distance=3; end; } 030-02,0,0,0 duplicate(#T_030-01) #T_030-02 NPC_CHEST 030-03,0,0,0 duplicate(#T_030-01) #T_030-03 NPC_CHEST 030-04,0,0,0 duplicate(#T_030-01) #T_030-04 NPC_CHEST 030-05,0,0,0 duplicate(#T_030-01) #T_030-05 NPC_CHEST 030-06,0,0,0 duplicate(#T_030-01) #T_030-06 NPC_CHEST 030-07,0,0,0 duplicate(#T_030-01) #T_030-07 NPC_CHEST 030-08,0,0,0 duplicate(#T_030-01) #T_030-08 NPC_CHEST 030-09,0,0,0 duplicate(#T_030-01) #T_030-09 NPC_CHEST 030-10,0,0,0 duplicate(#T_030-01) #T_030-10 NPC_CHEST 030-11,0,0,0 duplicate(#T_030-01) #T_030-11 NPC_CHEST 030-12,0,0,0 duplicate(#T_030-01) #T_030-12 NPC_CHEST 030-13,0,0,0 duplicate(#T_030-01) #T_030-13 NPC_CHEST 030-14,0,0,0 duplicate(#T_030-01) #T_030-14 NPC_CHEST 030-15,0,0,0 duplicate(#T_030-01) #T_030-15 NPC_CHEST 030-16,0,0,0 duplicate(#T_030-01) #T_030-16 NPC_CHEST 030-17,0,0,0 duplicate(#T_030-01) #T_030-17 NPC_CHEST 030-18,0,0,0 duplicate(#T_030-01) #T_030-18 NPC_CHEST 030-19,0,0,0 duplicate(#T_030-01) #T_030-19 NPC_CHEST 030-20,0,0,0 duplicate(#T_030-01) #T_030-20 NPC_CHEST 030-21,0,0,0 duplicate(#T_030-01) #T_030-21 NPC_CHEST 030-22,0,0,0 duplicate(#T_030-01) #T_030-22 NPC_CHEST 030-23,0,0,0 duplicate(#T_030-01) #T_030-23 NPC_CHEST 030-24,0,0,0 duplicate(#T_030-01) #T_030-24 NPC_CHEST 030-25,0,0,0 duplicate(#T_030-01) #T_030-25 NPC_CHEST 030-26,0,0,0 duplicate(#T_030-01) #T_030-26 NPC_CHEST 030-27,0,0,0 duplicate(#T_030-01) #T_030-27 NPC_CHEST 030-28,0,0,0 duplicate(#T_030-01) #T_030-28 NPC_CHEST 030-29,0,0,0 duplicate(#T_030-01) #T_030-29 NPC_CHEST 030-30,0,0,0 duplicate(#T_030-01) #T_030-30 NPC_CHEST 030-31,0,0,0 duplicate(#T_030-01) #T_030-31 NPC_CHEST 030-32,0,0,0 duplicate(#T_030-01) #T_030-32 NPC_CHEST 030-33,0,0,0 duplicate(#T_030-01) #T_030-33 NPC_CHEST 030-34,0,0,0 duplicate(#T_030-01) #T_030-34 NPC_CHEST 030-35,0,0,0 duplicate(#T_030-01) #T_030-35 NPC_CHEST 030-36,0,0,0 duplicate(#T_030-01) #T_030-36 NPC_CHEST 030-37,0,0,0 duplicate(#T_030-01) #T_030-37 NPC_CHEST 030-38,0,0,0 duplicate(#T_030-01) #T_030-38 NPC_CHEST 030-39,0,0,0 duplicate(#T_030-01) #T_030-39 NPC_CHEST 030-40,0,0,0 duplicate(#T_030-01) #T_030-40 NPC_CHEST 030-41,0,0,0 duplicate(#T_030-01) #T_030-41 NPC_CHEST 030-42,0,0,0 duplicate(#T_030-01) #T_030-42 NPC_CHEST 030-43,0,0,0 duplicate(#T_030-01) #T_030-43 NPC_CHEST 030-44,0,0,0 duplicate(#T_030-01) #T_030-44 NPC_CHEST 030-45,0,0,0 duplicate(#T_030-01) #T_030-45 NPC_CHEST 030-46,0,0,0 duplicate(#T_030-01) #T_030-46 NPC_CHEST 030-47,0,0,0 duplicate(#T_030-01) #T_030-47 NPC_CHEST 030-48,0,0,0 duplicate(#T_030-01) #T_030-48 NPC_CHEST 030-49,0,0,0 duplicate(#T_030-01) #T_030-49 NPC_CHEST 030-50,0,0,0 duplicate(#T_030-01) #T_030-50 NPC_CHEST 030-51,0,0,0 duplicate(#T_030-01) #T_030-51 NPC_CHEST 030-52,0,0,0 duplicate(#T_030-01) #T_030-52 NPC_CHEST 030-53,0,0,0 duplicate(#T_030-01) #T_030-53 NPC_CHEST 030-54,0,0,0 duplicate(#T_030-01) #T_030-54 NPC_CHEST 030-55,0,0,0 duplicate(#T_030-01) #T_030-55 NPC_CHEST 030-56,0,0,0 duplicate(#T_030-01) #T_030-56 NPC_CHEST 030-57,0,0,0 duplicate(#T_030-01) #T_030-57 NPC_CHEST 030-58,0,0,0 duplicate(#T_030-01) #T_030-58 NPC_CHEST 030-59,0,0,0 duplicate(#T_030-01) #T_030-59 NPC_CHEST 030-60,0,0,0 duplicate(#T_030-01) #T_030-60 NPC_CHEST 030-61,0,0,0 duplicate(#T_030-01) #T_030-61 NPC_CHEST 030-62,0,0,0 duplicate(#T_030-01) #T_030-62 NPC_CHEST 030-63,0,0,0 duplicate(#T_030-01) #T_030-63 NPC_CHEST 030-64,0,0,0 duplicate(#T_030-01) #T_030-64 NPC_CHEST 030-65,0,0,0 duplicate(#T_030-01) #T_030-65 NPC_CHEST 030-66,0,0,0 duplicate(#T_030-01) #T_030-66 NPC_CHEST 030-67,0,0,0 duplicate(#T_030-01) #T_030-67 NPC_CHEST 030-68,0,0,0 duplicate(#T_030-01) #T_030-68 NPC_CHEST 030-69,0,0,0 duplicate(#T_030-01) #T_030-69 NPC_CHEST 030-70,0,0,0 duplicate(#T_030-01) #T_030-70 NPC_CHEST 030-71,0,0,0 duplicate(#T_030-01) #T_030-71 NPC_CHEST 030-72,0,0,0 duplicate(#T_030-01) #T_030-72 NPC_CHEST 030-73,0,0,0 duplicate(#T_030-01) #T_030-73 NPC_CHEST 030-74,0,0,0 duplicate(#T_030-01) #T_030-74 NPC_CHEST 030-75,0,0,0 duplicate(#T_030-01) #T_030-75 NPC_CHEST