summaryrefslogtreecommitdiff
path: root/npc/00000SAVE/maze.txt
diff options
context:
space:
mode:
Diffstat (limited to 'npc/00000SAVE/maze.txt')
-rw-r--r--npc/00000SAVE/maze.txt776
1 files changed, 776 insertions, 0 deletions
diff --git a/npc/00000SAVE/maze.txt b/npc/00000SAVE/maze.txt
new file mode 100644
index 000000000..601e333f4
--- /dev/null
+++ b/npc/00000SAVE/maze.txt
@@ -0,0 +1,776 @@
+// TMW2 Scripts
+// Author:
+// Jesusalva
+// Description:
+// Maze generation script (Protip: (30,30) is ALWAYS reachable - for @warp)
+// Based on https://wiki.themanaworld.org/index.php/Archive:Afterlife#maze_generation
+// Begin script, instance is required. Maze is Saved to player data.
+// Scopes: MAZE_ {ID, MX, MY} or {X_Y$} or {X_Y_ALLOWEDTYPES} or {X_Y_ID}
+
+/////////////////////////////////////////////////////////////////////////////////
+// MazeVar(x,y,param)
+function script MazeVar {
+ return "MAZE_"+getarg(0)+"_"+getarg(1)+getarg(2, "");
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+// SetMazeCon(Maze, north, west, east, south)
+function script SetMazeCon {
+ setd(getarg(0)+"$["+MAZENORTH+"]", getarg(1));
+ setd(getarg(0)+"$["+MAZE_WEST+"]", getarg(2));
+ setd(getarg(0)+"$["+MAZE_EAST+"]", getarg(3));
+ setd(getarg(0)+"$["+MAZESOUTH+"]", getarg(4));
+ return;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+// UpdateMazeCon(Maze, x, y)
+function script UpdateMazeCon {
+ if (getd(getarg(0)+"$["+MAZENORTH+"]") != "WALL")
+ setd(getarg(0)+"$["+MAZENORTH+"]", str(getarg(1))+"_"+str(getarg(2)-1));
+
+ if (getd(getarg(0)+"$["+MAZE_WEST+"]") != "WALL")
+ setd(getarg(0)+"$["+MAZE_WEST+"]", str(getarg(1)-1)+"_"+str(getarg(2)));
+
+ if (getd(getarg(0)+"$["+MAZE_EAST+"]") != "WALL")
+ setd(getarg(0)+"$["+MAZE_EAST+"]", str(getarg(1)+1)+"_"+str(getarg(2)));
+
+ if (getd(getarg(0)+"$["+MAZESOUTH+"]") != "WALL")
+ setd(getarg(0)+"$["+MAZESOUTH+"]", str(getarg(1))+"_"+str(getarg(2)+1));
+ return;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+// FindMazeTypeByCon(Maze)
+function script FindMazeTypeByCon {
+ .@n=false;.@s=false;.@w=false;.@e=false;
+ if (getd(getarg(0)+"$["+MAZENORTH+"]") != "WALL")
+ .@n=true;
+
+ if (getd(getarg(0)+"$["+MAZE_WEST+"]") != "WALL")
+ .@w=true;
+
+ if (getd(getarg(0)+"$["+MAZE_EAST+"]") != "WALL")
+ .@e=true;
+
+ if (getd(getarg(0)+"$["+MAZESOUTH+"]") != "WALL")
+ .@s=true;
+
+ if (.@n && .@w && .@e && .@s)
+ return MAZEMAPTYPE_CROSS;
+ else if (.@n && .@w && .@s)
+ return MAZEMAPTYPE_TNWS;
+ else if (.@n && .@e && .@s)
+ return MAZEMAPTYPE_TNES;
+ else if (.@w && .@e && .@n)
+ return MAZEMAPTYPE_TEWN;
+ else if (.@w && .@e && .@s)
+ return MAZEMAPTYPE_TWES;
+ else if (.@n && .@w)
+ return MAZEMAPTYPE_CURVENW;
+ else if (.@n && .@e)
+ return MAZEMAPTYPE_CURVENE;
+ else if (.@s && .@w)
+ return MAZEMAPTYPE_CURVESW;
+ else if (.@s && .@w)
+ return MAZEMAPTYPE_CURVESE;
+ else if (.@n && .@s)
+ return MAZEMAPTYPE_LINENS;
+ else if (.@w && .@e)
+ return MAZEMAPTYPE_LINEWE;
+ else if (.@s)
+ return MAZEMAPTYPE_DEADS;
+ else if (.@w)
+ return MAZEMAPTYPE_DEADW;
+ else if (.@n)
+ return MAZEMAPTYPE_DEADN;
+ else if (.@e)
+ return MAZEMAPTYPE_DEADE;
+ else
+ return MAZEMAPTYPE_NULL;
+
+ return -1;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+// ParseMaze(mapType, x, y)
+function script ParseMaze {
+ .@t=getarg(0);
+ .@x=getarg(1);
+ .@y=getarg(2);
+
+ /*
+ // Prepare .@sim, the simulator array
+ copyarray(.@sim,
+ getd(MazeVar(.@x, .@y, "_ALLOWEDTYPES")),
+ getarraysize(getd(MazeVar(.@x, .@y, "_ALLOWEDTYPES"))));
+ */
+
+ // Setup the maze connectors
+ .@v$=MazeVar(.@x, .@y);
+ switch (.@t) {
+ case MAZEMAPTYPE_NULL:
+ SetMazeCon(.@v$, "WALL", "WALL", "WALL", "WALL");
+ // It's a fallback
+ Exception("ERROR IN PARSER, FALLBACK", RB_DEBUGMES|RB_IRCBROADCAST);
+ return true;
+ break;
+
+ // N W E S
+ case MAZEMAPTYPE_DEADS:
+ SetMazeCon(.@v$, "WALL", "WALL", "WALL", "");
+ break;
+ case MAZEMAPTYPE_DEADW:
+ SetMazeCon(.@v$, "WALL", "", "WALL", "WALL");
+ break;
+ case MAZEMAPTYPE_DEADN:
+ SetMazeCon(.@v$, "", "WALL", "WALL", "WALL");
+ break;
+ case MAZEMAPTYPE_DEADE:
+ SetMazeCon(.@v$, "WALL", "WALL", "", "WALL");
+ break;
+
+ // N W E S
+ case MAZEMAPTYPE_CURVENW:
+ SetMazeCon(.@v$, "", "", "WALL", "WALL");
+ break;
+ case MAZEMAPTYPE_CURVENE:
+ SetMazeCon(.@v$, "", "WALL", "", "WALL");
+ break;
+ case MAZEMAPTYPE_CURVESW:
+ SetMazeCon(.@v$, "WALL", "", "WALL", "");
+ break;
+ case MAZEMAPTYPE_CURVESE:
+ SetMazeCon(.@v$, "WALL", "WALL", "", "");
+ break;
+
+ // N W E S
+ case MAZEMAPTYPE_TNWS:
+ SetMazeCon(.@v$, "", "", "WALL", "");
+ break;
+ case MAZEMAPTYPE_TNES:
+ SetMazeCon(.@v$, "", "WALL", "", "");
+ break;
+ case MAZEMAPTYPE_TWEN:
+ SetMazeCon(.@v$, "", "", "", "WALL");
+ break;
+ case MAZEMAPTYPE_TWES:
+ SetMazeCon(.@v$, "WALL", "", "", "");
+ break;
+
+ // N W E S
+ case MAZEMAPTYPE_LINENS:
+ SetMazeCon(.@v$, "", "WALL", "WALL", "");
+ break;
+ case MAZEMAPTYPE_LINEWE:
+ SetMazeCon(.@v$, "WALL", "", "", "WALL");
+ break;
+
+ // N W E S
+ case MAZEMAPTYPE_CROSS:
+ SetMazeCon(.@v$, "", "", "", "");
+ break;
+ }
+
+ // Now that connectors are set, we do simulations
+ /*
+ debugmes "(%d, %d) found %s (ID %d)", .@x, .@y, getd(MazeVar(.@x, .@y, "$["+MAZENORTH+"]")), getd(MazeVar(.@x, .@y, "_ID"));
+
+ debugmes "(%d, %d) is with north %s (ID %d)", .@x, .@y, getd(MazeVar(.@x, .@y, "$["+MAZENORTH+"]")), getd(MazeVar(.@x, .@y, "_ID"));
+ debugmes ".@v$ is %s", .@v$;
+ debugmes ".@v$[NORTH] is %s", getd(.@v$+"$["+MAZENORTH+"]");
+ */
+
+ //////////////////////////
+ // Way north
+ if (getd(.@v$+"$["+MAZENORTH+"]") != "WALL") {
+ // Does north map accept this?
+ //debugmes "(%d, %d) is worth proccessing in NORTH", .@x, .@y;
+
+ // Case 1: We're in the edge
+ if (.@y == 0)
+ return false;
+
+ // Case 2: South direction thinks it is a wall
+ if (getd(MazeVar(.@x, .@y-1, "$["+MAZESOUTH+"]")) == "WALL")
+ return false;
+
+ //debugmes "(%d, %d) found %s (ID %d)", .@x, .@y, getd(MazeVar(.@x, .@y-1, "$["+MAZESOUTH+"]")), getd(MazeVar(.@x, .@y-1, "_ID"));
+ // Okay, this is a valid movement, we continue
+ } else {
+ // Case 1: We're in the edge
+ if (.@y != 0) {
+ // Case 2: South direction thinks it is a wall
+ if (getd(MazeVar(.@x, .@y-1, "$["+MAZESOUTH+"]")) != "WALL")
+ return false;
+ }
+ }
+
+ //////////////////////////
+ // Way west
+ if (getd(.@v$+"$["+MAZE_WEST+"]") != "WALL") {
+ // Does west map accept this?
+
+ // Case 1: We're in the edge
+ if (.@x == 0)
+ return false;
+
+ // Case 2: West direction thinks it is a wall
+ if (getd(MazeVar(.@x-1, .@y, "$["+MAZE_EAST+"]")) == "WALL")
+ return false;
+
+ // Okay, this is a valid movement, we continue
+ } else {
+ // Case 1: We're in the edge
+ if (.@x != 0) {
+ // Case 2: West direction thinks it is a wall
+ if (getd(MazeVar(.@x-1, .@y, "$["+MAZE_EAST+"]")) != "WALL")
+ return false;
+ }
+ }
+
+ //////////////////////////
+ // Way down
+ if (getd(.@v$+"$["+MAZESOUTH+"]") != "WALL") {
+ // Can we do this?
+
+ // Case 1: We're in the edge
+ if (.@y == MAZE_MY-1)
+ return false;
+
+ // Case 2: Down direction is invalid?
+ // TODO
+
+ // Okay, this is a valid movement, we continue
+ }
+
+ //////////////////////////
+ // Way east
+ if (getd(.@v$+"$["+MAZE_EAST+"]") != "WALL") {
+ // Can we do this?
+
+ // Case 1: We're in the edge
+ if (.@x == MAZE_MX-1)
+ return false;
+
+ // Case 2: Right direction is invalid?
+ // TODO
+
+ // Okay, this is a valid movement, we continue
+ }
+
+ // All checks passed!
+ UpdateMazeCon(.@v$, .@x, .@y);
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+// MazeFix() → Breaks islands at cost of randomness
+// runs after ParseMaze. By now, maze structure is set and working
+function script MazeFix {
+ // FIXME: BROKEN
+ if (!$@GM_OVERRIDE)
+ return;
+
+ .@x=0; .@y=0;
+ debugmes "(%d, %d)", MAZE_MX, MAZE_MY;
+ while (.@x < MAZE_MX) {
+ // For every cell:
+ while (.@y < MAZE_MY) {
+ .@v$=MazeVar(.@x, .@y); // Our ID
+ .@skip=false;
+
+ // It need to have either a way east, or a way south
+ if (getd(.@v$+"$["+MAZE_EAST+"]") != "WALL")
+ .@skip=true;
+ if (getd(.@v$+"$["+MAZESOUTH+"]") != "WALL")
+ .@skip=true;
+
+ // Finally skip
+ if (.@skip) {
+ .@y++;
+ continue;
+ }
+
+ .@dirns=any(true, false);
+
+ // If it doesn't, but is an edge, so we cannot enforce both rules
+ // Do note (x,y) only goes to (MX-1, MY-1) because index
+ if (.@x >= MAZE_MX-1 || .@y >= MAZE_MY-1)
+ .@skip=true;
+
+ // Finally skip
+ if (.@skip) {
+ // End of X axis (row)
+ if (.@x >= MAZE_MX-1) {
+ .@x1=0; .@al=true;
+ while (.@x1 < .@x) {
+ .@vi=MazeVar(.@x1, .@y);
+ // There's a wall somewhere
+ if (getd(.@v$+"$["+MAZE_EAST+"]") == "WALL") {
+ .@al=false;
+ break;
+ }
+ .@x1++;
+ }
+ // There's no walls, so we need safeties
+ if (.@al) {
+ // Could pick a random place, but...
+ .@skip=false; .@dirns=true;
+ }
+ // End of Y axis (column)
+ } else {
+ .@y1=0; .@al=true;
+ while (.@y1 < .@y) {
+ .@vi=MazeVar(.@x, .@y1);
+ // There's a wall somewhere
+ if (getd(.@v$+"$["+MAZESOUTH+"]") == "WALL") {
+ .@al=false;
+ break;
+ }
+ .@y1++;
+ }
+ // There's no walls, so we need safeties
+ if (.@al) {
+ // Could pick a random place, but...
+ .@skip=false; .@dirns=false;
+ }
+ }
+ }
+
+ // All fine, continue to next row
+ if (.@skip) {
+ .@y++;
+ continue;
+ }
+
+ debugmes "(%d, %d) editing from %d", .@x, .@y, getd(.@v$+"_ID");
+
+ // At least one of those paths must be open
+ if (.@dirns) {
+ // Force the opening to south
+ .@v2$=MazeVar(.@x, .@y+1);
+ setd(.@v$+"$["+MAZESOUTH+"]", str(.@x)+"_"+str(.@y+1));
+ setd(.@v2$+"$["+MAZENORTH+"]", str(.@x)+"_"+str(.@y));
+ debugmes "Edited NS axis: %s -> %s", .@v$, .@v2$;
+ } else {
+ // Force the opening to east
+ .@v2$=MazeVar(.@x+1, .@y);
+ setd(.@v$+"$["+MAZE_EAST+"]", str(.@x+1)+"_"+str(.@y));
+ setd(.@v2$+"$["+MAZE_WEST+"]", str(.@x)+"_"+str(.@y));
+ debugmes "Edited WE axis: %s -> %s", .@v$, .@v2$;
+ }
+ // Fix type
+ setd(.@v$+"_ID", FindMazeTypeByCon(.@v$));
+ setd(.@v2$+"_ID", FindMazeTypeByCon(.@v2$));
+
+ // End the fix loop
+ .@y++;
+ debugmes "(%d, %d)", .@x, .@y;
+ }
+ .@x++;
+ .@y=0;
+ debugmes "(%d, %d)", .@x, .@y;
+ }
+ debugmes "(%d, %d)", .@x, .@y;
+ return;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////
+// GenerateMaze(width, height) → Returns instance ID
+function script GenerateMaze {
+ // Save maze configuration
+ MAZE_MX=getarg(0);
+ MAZE_MY=getarg(1);
+ freeloop(true);
+
+ // Delete previous maze data as relevant
+ debugmes "[STATUS] Clean up";
+ for (.@y=0; .@y < MAZE_MY; .@y++) {
+ for (.@x=0; .@x < MAZE_MX; .@x++) {
+ setd(MazeVar(.@x, .@y, "_ID"), 0);
+ deletearray(getd(MazeVar(.@x, .@y, "_ALLOWEDTYPES")));
+ deletearray(getd(MazeVar(.@x, .@y, "$")));
+ }
+ }
+
+ ////////////////////
+ // SETUP
+ .@x=0; .@y=0;
+ debugmes "[STATUS] Setup";
+
+ // For every column:
+ while (.@x < MAZE_MX) {
+ // For every cell:
+ while (.@y < MAZE_MY) {
+
+ // Case 1: Left column
+ if (.@y == 0) {
+
+ // NW edge
+ if (.@x == 0)
+ setarray getd(MazeVar(.@x, .@y, "_ALLOWEDTYPES")),
+ MAZEMAPTYPE_DEADS, MAZEMAPTYPE_DEADE,
+ MAZEMAPTYPE_CURVESE;
+ // NE edge
+ else if (.@x == MAZE_MX-1)
+ setarray getd(MazeVar(.@x, .@y, "_ALLOWEDTYPES")),
+ MAZEMAPTYPE_DEADS, MAZEMAPTYPE_DEADW,
+ MAZEMAPTYPE_CURVESW;
+ // North wall
+ else
+ setarray getd(MazeVar(.@x, .@y, "_ALLOWEDTYPES")),
+ MAZEMAPTYPE_DEADS, MAZEMAPTYPE_DEADW, MAZEMAPTYPE_DEADE,
+ MAZEMAPTYPE_TWES, MAZEMAPTYPE_LINEWE,
+ MAZEMAPTYPE_CURVESE, MAZEMAPTYPE_CURVESW;
+
+
+ // Case 2: Right column
+ } else if (.@y == MAZE_MY-1) {
+
+ // SW edge
+ if (.@x == 0)
+ setarray getd(MazeVar(.@x, .@y, "_ALLOWEDTYPES")),
+ MAZEMAPTYPE_DEADN, MAZEMAPTYPE_DEADE,
+ MAZEMAPTYPE_CURVENE;
+ // SE edge
+ else if (.@x == MAZE_MX-1)
+ setarray getd(MazeVar(.@x, .@y, "_ALLOWEDTYPES")),
+ MAZEMAPTYPE_DEADN, MAZEMAPTYPE_DEADW,
+ MAZEMAPTYPE_CURVENW;
+ // South wall
+ else
+ setarray getd(MazeVar(.@x, .@y, "_ALLOWEDTYPES")),
+ MAZEMAPTYPE_DEADN, MAZEMAPTYPE_DEADW, MAZEMAPTYPE_DEADE,
+ MAZEMAPTYPE_TWEN, MAZEMAPTYPE_LINEWE,
+ MAZEMAPTYPE_CURVENE, MAZEMAPTYPE_CURVENW;
+
+
+ // Case 3: Nothing in special
+ } else {
+ setarray getd(MazeVar(.@x, .@y, "_ALLOWEDTYPES")),
+ MAZEMAPTYPE_DEADN, MAZEMAPTYPE_DEADW, MAZEMAPTYPE_DEADE, MAZEMAPTYPE_DEADS,
+ MAZEMAPTYPE_CURVENW, MAZEMAPTYPE_CURVENE, MAZEMAPTYPE_CURVESW, MAZEMAPTYPE_CURVESE,
+ MAZEMAPTYPE_TNWS, MAZEMAPTYPE_TNES, MAZEMAPTYPE_TWEN, MAZEMAPTYPE_TWES,
+ MAZEMAPTYPE_LINEWE, MAZEMAPTYPE_LINENS, MAZEMAPTYPE_CROSS;
+ }
+
+
+ // End the setup loop
+ .@y++;
+ }
+ .@x++;
+ .@y=0;
+ }
+
+
+ ////////////////////
+ // BUILDING
+ .@x=0; .@y=0;
+ debugmes "[STATUS] Build";
+
+ // For every line:
+ while (.@y < MAZE_MY) {
+ // For every cell:
+ while (.@x < MAZE_MX) {
+
+ //debugmes "[STATUS] [BUILD %d %d] Running...", .@x, .@y;
+ // While connections weren't parsed
+ do {
+ // We start at (0,0) and go to (MAZE_MX,0)
+ // Then we go to (0,MAZE_MY) until (MAZE_MX,MAZE_MY)
+ // Shuffle the array
+ array_shuffle(getd(MazeVar(.@x, .@y, "_ALLOWEDTYPES")));
+ freeloop(true);
+
+ if (getarraysize(getd(MazeVar(.@x, .@y, "_ALLOWEDTYPES"))))
+ .@mztype=array_pop(getd(MazeVar(.@x, .@y, "_ALLOWEDTYPES")));
+ else
+ .@mztype=-1;
+
+ // XXX: MAZEMAPTYPE_NULL is also a bug
+ if (.@mztype <= 0) {
+ Exception("ERROR IN MAZE BUILDER ("+.@x+","+.@y+") MTYPEXY", RB_DEBUGMES|RB_IRCBROADCAST);
+ .@mztype=MAZEMAPTYPE_NULL;
+ }
+ setd(MazeVar(.@x, .@y, "_ID"), .@mztype);
+
+ // Attempt to parse connections
+ } while (!ParseMaze(.@mztype, .@x, .@y));
+
+ // End the build loop
+ .@x++;
+ }
+ .@y++;
+ .@x=0;
+ }
+
+ // Lose some randomness to try to ensure every place is accessible
+ debugmes "[STATUS] Island Fix";
+ MazeFix();
+
+ // Debug the statuses
+ .@x=0; .@y=0;
+ setarray .@debug$, ".",
+ "↑", "→", "↓", "←",
+ "⮠", "⮡", "⮢", "⮣",
+ "ㅓ", "ㅏ", "ㅗ", "T",
+ "|", "—", "𐘁\ ";
+ debugmes "[STATUS] Finishing...";
+ for (.@y=0; .@y < MAZE_MY; .@y++) {
+ .@l$="";
+ .@lb$="";
+ freeloop(true);
+ for (.@x=0; .@x < MAZE_MX; .@x++) {
+ .@symbol$=getd(".@debug$["+getd(MazeVar(.@x, .@y, "_ID"))+"]");
+ //debugmes "[rpts] %d %d = %d", .@x, .@y, getd(MazeVar(.@x, .@y, "_ID"));
+ .@l$=.@l$+","+getd(MazeVar(.@x, .@y, "_ID"));
+ .@lb$=.@lb$+" "+.@symbol$;
+ }
+ // Debug human readable format + a easy to grep-replace RNG
+ // Pseudo-rng example: $@MAZES_12_4 = Random Maze 12, Row 4
+ // On the example, replace VAR_X with "MAZES_12"
+ debugmes "[REPORT-SA] setarray $@VAR_X_%d%s;", .@y, .@l$; // SetArray
+ debugmes "[REPORT-HR] %s", .@lb$; // HumanReadable
+ }
+
+
+ freeloop(false);
+ debugmes "[STATUS] Finished";
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+// WarpToMaze(dir)
+function script WarpToMaze {
+ // Look up the destination map
+ switch (getarg(0)) {
+ case DIR_NORTH:
+ .@dst$=getd(MazeVar(MAZE_X, MAZE_Y, "$["+MAZENORTH+"]"));
+ .@x=29; .@y=38;
+ break;
+ case DIR_SOUTH:
+ .@dst$=getd(MazeVar(MAZE_X, MAZE_Y, "$["+MAZESOUTH+"]"));
+ .@x=29; .@y=21;
+ break;
+ case DIR_WEST:
+ .@dst$=getd(MazeVar(MAZE_X, MAZE_Y, "$["+MAZE_WEST+"]"));
+ .@x=38; .@y=31;
+ break;
+ case DIR_EAST:
+ .@dst$=getd(MazeVar(MAZE_X, MAZE_Y, "$["+MAZE_EAST+"]"));
+ .@x=21; .@y=31;
+ break;
+ default:
+ return Exception("INVALID DIRECTION", RB_DEFAULT|RB_ISFATAL);
+ }
+
+ // Get MAPID
+ .@id=getd("MAZE_"+.@dst$+"_ID");
+ explode(.@crd$, .@dst$, "_");
+ debugmes "%s = (%d,%d)", .@dst$, .@crd$[0], .@crd$[1];
+ // Warp you based on MAPID and update your coordinates
+ MAZE_X=atoi(.@crd$[0]);
+ MAZE_Y=atoi(.@crd$[1]);
+
+ switch (.@id) {
+ // If a special map have different warp rules, specify here
+ case MAZEMAPTYPE_NULL:
+ .@x=30; .@y=30; break;
+ }
+
+ // We don't need MAZE_ID do we?
+ warp "mz"+.@id+"@"+getcharid(0), .@x, .@y;
+ return;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+// CreateMaze()
+function script CreateMaze {
+ // Create the Maze instance or die trying
+ .@inst = instance_create("Maze "+getcharid(0), getcharid(3), IOT_CHAR);
+ if (.@inst < 0) end;
+ MAZE_ID=.@inst;
+ // Attach instance maps
+ instance_attachmap("maze0", .@inst, false, "mz0@"+getcharid(0));
+ instance_attachmap("maze1", .@inst, false, "mz1@"+getcharid(0));
+ instance_attachmap("maze2", .@inst, false, "mz2@"+getcharid(0));
+ instance_attachmap("maze3", .@inst, false, "mz3@"+getcharid(0));
+ instance_attachmap("maze4", .@inst, false, "mz4@"+getcharid(0));
+ instance_attachmap("maze5", .@inst, false, "mz5@"+getcharid(0));
+ instance_attachmap("maze6", .@inst, false, "mz6@"+getcharid(0));
+ instance_attachmap("maze7", .@inst, false, "mz7@"+getcharid(0));
+ instance_attachmap("maze8", .@inst, false, "mz8@"+getcharid(0));
+ instance_attachmap("maze9", .@inst, false, "mz9@"+getcharid(0));
+ instance_attachmap("maze10", .@inst, false, "mz10@"+getcharid(0));
+ instance_attachmap("maze11", .@inst, false, "mz11@"+getcharid(0));
+ instance_attachmap("maze12", .@inst, false, "mz12@"+getcharid(0));
+ instance_attachmap("maze13", .@inst, false, "mz13@"+getcharid(0));
+ instance_attachmap("maze14", .@inst, false, "mz14@"+getcharid(0));
+ instance_attachmap("maze15", .@inst, false, "mz15@"+getcharid(0));
+ // Instance lasts one hour
+ instance_set_timeout(3600, 3600, .@inst);
+ instance_init(.@inst);
+
+ debugmes "Maze instance created: %s", MAZE_ID;
+ return .@inst;
+}
+
+// InitMaze(maze_x, maze_y, {renew=True})
+function script InitMaze {
+ // Should we renew the instance?
+ if (getarg(2, true))
+ instance_set_timeout(3600, 3600, MAZE_ID);
+
+ MAZE_X=getarg(0);
+ MAZE_Y=getarg(1);
+ .@id=getd(MazeVar(MAZE_X, MAZE_Y, "_ID"));
+ warp "mz"+.@id+"@"+getcharid(0), 30, 30;
+ dispbottom l("Good luck!");
+ return;
+}
+
+// Warp NPCs
+maze1,29,39,0 script #MZSOUTH NPC_SUMMONING_CIRC,0,0,{
+ end;
+OnTouch:
+ WarpToMaze(DIR_SOUTH);
+ end;
+}
+
+maze2,20,31,0 script #MZWEST NPC_SUMMONING_CIRC,0,0,{
+ end;
+OnTouch:
+ WarpToMaze(DIR_WEST);
+ end;
+}
+
+maze3,29,20,0 script #MZNORTH NPC_SUMMONING_CIRC,0,0,{
+ end;
+OnTouch:
+ WarpToMaze(DIR_NORTH);
+ end;
+}
+
+maze4,39,31,0 script #MZEAST NPC_SUMMONING_CIRC,0,0,{
+ end;
+OnTouch:
+ WarpToMaze(DIR_EAST);
+ end;
+}
+
+maze5,29,20,0 duplicate(#MZNORTH) #MZ5N NPC_SUMMONING_CIRC,0,0
+maze5,20,31,0 duplicate(#MZWEST) #MZ5W NPC_SUMMONING_CIRC,0,0
+
+maze6,29,20,0 duplicate(#MZNORTH) #MZ6N NPC_SUMMONING_CIRC,0,0
+maze6,39,31,0 duplicate(#MZEAST) #MZ6E NPC_SUMMONING_CIRC,0,0
+
+maze7,29,39,0 duplicate(#MZSOUTH) #MZ7S NPC_SUMMONING_CIRC,0,0
+maze7,20,31,0 duplicate(#MZWEST) #MZ7W NPC_SUMMONING_CIRC,0,0
+
+maze8,29,39,0 duplicate(#MZSOUTH) #MZ8S NPC_SUMMONING_CIRC,0,0
+maze8,39,31,0 duplicate(#MZEAST) #MZ8E NPC_SUMMONING_CIRC,0,0
+
+maze9,29,20,0 duplicate(#MZNORTH) #MZ9N NPC_SUMMONING_CIRC,0,0
+maze9,20,31,0 duplicate(#MZWEST) #MZ9W NPC_SUMMONING_CIRC,0,0
+maze9,29,39,0 duplicate(#MZSOUTH) #MZ9S NPC_SUMMONING_CIRC,0,0
+
+maze10,29,20,0 duplicate(#MZNORTH) #MZ10N NPC_SUMMONING_CIRC,0,0
+maze10,39,31,0 duplicate(#MZEAST) #MZ10E NPC_SUMMONING_CIRC,0,0
+maze10,29,39,0 duplicate(#MZSOUTH) #MZ10S NPC_SUMMONING_CIRC,0,0
+
+maze11,20,31,0 duplicate(#MZWEST) #MZ11W NPC_SUMMONING_CIRC,0,0
+maze11,39,31,0 duplicate(#MZEAST) #MZ11E NPC_SUMMONING_CIRC,0,0
+maze11,29,20,0 duplicate(#MZNORTH) #MZ11N NPC_SUMMONING_CIRC,0,0
+
+maze12,20,31,0 duplicate(#MZWEST) #MZ12W NPC_SUMMONING_CIRC,0,0
+maze12,39,31,0 duplicate(#MZEAST) #MZ12E NPC_SUMMONING_CIRC,0,0
+maze12,29,39,0 duplicate(#MZSOUTH) #MZ12S NPC_SUMMONING_CIRC,0,0
+
+maze13,29,20,0 duplicate(#MZNORTH) #MZ13N NPC_SUMMONING_CIRC,0,0
+maze13,29,39,0 duplicate(#MZSOUTH) #MZ13S NPC_SUMMONING_CIRC,0,0
+
+maze14,20,31,0 duplicate(#MZWEST) #MZ14W NPC_SUMMONING_CIRC,0,0
+maze14,39,31,0 duplicate(#MZEAST) #MZ14E NPC_SUMMONING_CIRC,0,0
+
+maze15,29,20,0 duplicate(#MZNORTH) #MZ15N NPC_SUMMONING_CIRC,0,0
+maze15,20,31,0 duplicate(#MZWEST) #MZ15W NPC_SUMMONING_CIRC,0,0
+maze15,29,39,0 duplicate(#MZSOUTH) #MZ15S NPC_SUMMONING_CIRC,0,0
+maze15,39,31,0 duplicate(#MZEAST) #MZ15E NPC_SUMMONING_CIRC,0,0
+
+// Testing framework
+maze0,30,30,0 script #MazeMaster NPC_MONA,{
+ /*
+ function mazeGen;
+ function parseConnections;
+ */
+ //GenerateMaze(7, 7, 0);
+ select
+ l("Playtesting"),
+ l("RMG"),
+ l("RMG+Playtest");
+ mes "";
+ .@x=5;.@y=5;
+ if (@menu >= 2) {
+ // Width
+ mesf "Width (%d-25): ", max(1, @xvar);
+ input .@x, max(1, @xvar), 25;
+
+ // Height
+ mesf "Height (%d-25): ", max(1, @yvar);
+ input .@y, max(1, @yvar), 25;
+
+ // Amount of copies
+ mesf "N. Copies: ";
+ input .@loop, 1, 100;
+
+ // Prevent bugs
+ @xvar=.@x; @yvar=.@y;
+ }
+
+ if (@menu == 2) {
+ freeloop(true);
+ for (.@i=0; .@i < .@loop; .@i++) {
+ GenerateMaze(.@x, .@y);
+ debugmes "";
+ debugmes "";
+ // Throw some entropy
+ .@noname=rand2(.@loop*(1+.@i));
+ freeloop(true);
+ }
+ freeloop(false);
+ close;
+ }
+
+ GenerateMaze(.@x, .@y);
+ CreateMaze();
+ InitMaze(0, 0);
+ end;
+}
+
+// Mapflags
+/*
+maze0 mapflag nowarpto
+maze1 mapflag nowarpto
+maze2 mapflag nowarpto
+maze3 mapflag nowarpto
+maze4 mapflag nowarpto
+maze5 mapflag nowarpto
+maze6 mapflag nowarpto
+maze7 mapflag nowarpto
+maze8 mapflag nowarpto
+maze9 mapflag nowarpto
+maze10 mapflag nowarpto
+maze11 mapflag nowarpto
+maze12 mapflag nowarpto
+maze13 mapflag nowarpto
+maze14 mapflag nowarpto
+maze15 mapflag nowarpto
+*/
+