Circular rooms?

Harvelon
16 Jan 2020, 08:06

I am using the map in my adventure and I want to make a circular room but there doesn’t seem to be a option for that. Any help?


DarkLizerd
17 Jan 2020, 07:18

Do you want the map function to draw circular rooms???


DarkLizerd
17 Jan 2020, 07:27

To the masters that want to check this out...
Quest/Core/CoreEditorScriptsDrawing.alsx
Line # 331

  <editor>
    <appliesto>(function)Grid_DrawSquare</appliesto>
    <display>Draw custom layer grid square</display>
    <category>[EditorScriptsDrawingDrawing]</category>
    <create>Grid_DrawSquare ("", 0, 0, 1, 1, "", "White")</create>
    <add>[EditorScriptsDrawingDrawcustom]</add>
    <advanced/>
    <onlydisplayif>game.gridmap</onlydisplayif>

If this draws the room box, could this be copied and edited to draw other shapes?


DarkLizerd
17 Jan 2020, 07:29

Or could this be done easer by drawing the room map, manually, using SVG???


mrangel
17 Jan 2020, 10:30

OK, you'd need a bit of extra javascript.
I'm writing this after skimming over grid.js; I'm not sure if these functions can be added later, or if grid.js is loaded within a specific frame.

First, an actual circle-drawing function. Heavily based on drawBox

gridApi.drawCircle = function(x, y, z, r, border, borderWidth, fill) {
  activateLayer(z);
  // if this is the first room drawn, centre it.
  if (firstBox) {
    var offsetX = paper.view.center.x - x;
    var offsetY = paper.view.center.y - y;
    updateOffset(new Point(offsetX, offsetY));
    firstBox = false;
  }

  var path = new Path.Circle(gridPoint(x, y), r);
  path.closed = true;
  if (borderWidth > 0) {
    path.strokeColor = border;
    path.strokeWidth = borderWidth;
  }
  path.fillColor = fill;
  allPaths.push(path);
};

Then to act as a buffer between Quest and Paper:

function Grid_DrawCircle(x, y, z, r, border, borderWidth, fill) {
  if (!_canvasSupported) return;
  gridApi.drawCircle(parseFloat(x), parseFloat(y), parseInt(z), parseFloat(r), border, parseInt(borderWidth), fill);
}

Then on the Quest side, a function that will work out the coordinates of a circular room (as we've got the coords of the top left corner and a width and height; we need a centre and a radius.

For now I'll post a basic function so there's a first attempt here. If this works, then there are a few modifications that could be added later; like drawing ellipses if the width and length of the room aren't the same, and moving the endpoints of diagonal exits in by (1-1/√2) units so that they actually meet the circle.

<function name="Grid_DrawCircleRoom" parameters="x, y, z, width, length, border, borderWidth, fill">
  // half the average of the width and length; best estimate for now
  radius = (width + length)/4.0
  x = x + width/2.0
  y = y + length/2.0
  JS.Grid_DrawCircle (x, y, z, radius, border, borderWidth, fill)
</function>

Then to call this instead of just drawing a box, we'll need to add some lines to one of the core functions:

  <function name="Grid_DrawRoom" parameters="room, redraw, playerobject">
    <![CDATA[
    if (room.grid_render) {
      if (redraw or not Grid_GetRoomBooleanForPlayer(playerobject, room, "grid_isdrawn")) {

        if (not room.parent = null) {
          Grid_DrawRoom (room.parent, redraw, playerobject)
        }

        if (not HasString (room, "grid_shape")) {
          room.grid_shape = "box"
        }
        switch (room.gird_shape) {
          case ("box") {            JS.Grid_DrawBox(Grid_GetGridCoordinateForPlayer(game.pov, room, "x"), Grid_GetGridCoordinateForPlayer(game.pov, room, "y"), Grid_GetGridCoordinateForPlayer(game.pov, room, "z"), room.grid_width, room.grid_length, room.grid_border, room.grid_borderwidth, room.grid_fill, room.grid_bordersides)          }
          case ("circle") {
            Grid_DrawCircleRoom (Grid_GetGridCoordinateForPlayer(game.pov, room, "x"), Grid_GetGridCoordinateForPlayer(game.pov, room, "y"), Grid_GetGridCoordinateForPlayer(game.pov, room, "z"), room.grid_width, room.grid_length, room.grid_border, room.grid_borderwidth, room.grid_fill)
          }
          case ("label") {
            // allow rooms where only the label is drawn
          }
          default {
            error ("Unknown grid shape "+room.grid_shape+" for room "+room.name)
          }
        }
        if (LengthOf(room.grid_label) > 0) {
          label_x = Grid_GetGridCoordinateForPlayer(game.pov, room, "x") + room.grid_width/2.0
          label_y = (Grid_GetGridCoordinateForPlayer(game.pov, room, "y") + room.grid_length/2.0) - 0.5
          JS.Grid_DrawLabel(label_x, label_y, Grid_GetGridCoordinateForPlayer(game.pov, room, "z"), room.grid_label, room.grid_label_colour)
        }

        foreach (exit, AllExits()) {
          if (exit.grid_render and exit.parent = room and exit.grid_length > 0) {
            Grid_DrawLine (Grid_GetGridCoordinateForPlayer(game.pov, exit, "x"), Grid_GetGridCoordinateForPlayer(game.pov, exit, "y"), Grid_GetGridCoordinateForPlayer(game.pov, exit, "end_x"), Grid_GetGridCoordinateForPlayer(game.pov, exit, "end_y"), game.mapexitcolour, game.mapexitwidth)
          }
        }

        Grid_SetRoomBooleanForPlayer(playerobject, room, "grid_isdrawn", true)
      }
    }
    ]]>
  </function>

mrangel
17 Jan 2020, 11:19

OK… here's a quick attempt at a function to fix exit coords:

<function name="Grid_FixCircleExits" parameters="room">
  x1 = Grid_GetGridCoordinateForPlayer(game.pov, room, "x")
  x2 = x1 + room.grid_width/2.0
  y1 = Grid_GetGridCoordinateForPlayer(game.pov, room, "y")
  y2 = y1 + room.grid_height/2.0
  r = (room.grid_width + room.grid_height)/4.0
  x_offset = room.grid_width/2.0 - r/Sqrt(2)
  y_offset = room.grid_length/2.0 - r/Sqrt(2)
  ortho_offset = room.grid_width/2.0 - r

  foreach (exit, AllExits()) {
    if (exit.grid_render) {
      if (exit.parent = room) {
        exit_x = Grid_GetGridCoordinateForPlayer(game.pov, exit, "x")
        exit_y = Grid_GetGridCoordinateForPlayer(game.pov, exit, "y")
        if (DoesInherit (exit, "northeastdirection") or DoesInherit (exit, "southeastdirection")) {
          if (exit_x = x2) {
            Grid_SetGridCoordinateForPlayer(game.pov, exit, "x", exit_x - x_offset)
          }
        }
        else if (DoesInherit (exit, "northwestdirection") or DoesInherit (exit, "southwestdirection")) {
          if (exit_x = x1) {
            Grid_SetGridCoordinateForPlayer(game.pov, exit, "x", exit_x + x_offset)
          }
        }
        else if (ortho_offset <> 0) {
          if (DoesInherit (exit, "westdirection")) {
            if (exit_x = x1) {
              Grid_SetGridCoordinateForPlayer(game.pov, exit, "x", exit_x + ortho_offset)
            }
          }
          else if (DoesInherit (exit, "eastdirection")) {
            if (exit_x = x2) {
              Grid_SetGridCoordinateForPlayer(game.pov, exit, "x", exit_x - ortho_offset)
            }
          }
        }
        if (DoesInherit (exit, "southwestdirection") or DoesInherit (exit, "southeastdirection")) {
          if (exit_y = y2) {
            Grid_SetGridCoordinateForPlayer(game.pov, exit, "y", exit_y - y_offset)
          }
        }
        else if (DoesInherit (exit, "northwestdirection") or DoesInherit (exit, "northeastdirection")) {
          if (exit_y = y1) {
            Grid_SetGridCoordinateForPlayer(game.pov, exit, "y", exit_y + y_offset)
          }
        }
        else if (ortho_offset <> 0) {
          if (DoesInherit (exit, "southdirection")) {
            if (exit_y = y2) {
              Grid_SetGridCoordinateForPlayer(game.pov, exit, "y", exit_y + ortho_offset)
            }
          }
          else if (DoesInherit (exit, "northdirection")) {
            if (exit_y = y1) {
              Grid_SetGridCoordinateForPlayer(game.pov, exit, "y", exit_y - ortho_offset)
            }
          }
        }
      }
      else if (exit.to = room) {
        exit_x = Grid_GetGridCoordinateForPlayer(game.pov, exit, "end_x")
        exit_y = Grid_GetGridCoordinateForPlayer(game.pov, exit, "end_y")
        changed = false
        if (DoesInherit (exit, "southwestdirection") or DoesInherit (exit, "northwestdirection")) {
          if (exit_x = x2) {
            Grid_SetGridCoordinateForPlayer(game.pov, exit, "end_x", exit_x - x_offset)
            changed = true
          }
        }
        else if (DoesInherit (exit, "southeastdirection") or DoesInherit (exit, "northeastdirection")) {
          if (exit_x = x1) {
            Grid_SetGridCoordinateForPlayer(game.pov, exit, "end_x", exit_x + x_offset)
            changed = true
          }
        }
        else if (ortho_offset <> 0) {
          if (DoesInherit (exit, "eastdirection")) {
            if (exit_x = x1) {
              Grid_SetGridCoordinateForPlayer(game.pov, exit, "end_x", exit_x + ortho_offset)
              changed = true
            }
          }
          else if (DoesInherit (exit, "westdirection")) {
            if (exit_x = x2) {
              Grid_SetGridCoordinateForPlayer(game.pov, exit, "end_x", exit_x - ortho_offset)
              changed = true
            }
          }
        }

        if (DoesInherit (exit, "northeastdirection") or DoesInherit (exit, "northwestdirection")) {
          if (exit_y = y2) {
            Grid_SetGridCoordinateForPlayer(game.pov, exit, "end_y", exit_y - y_offset)
            changed = true
          }
        }
        else if (DoesInherit (exit, "southeastdirection") or DoesInherit (exit, "southwestdirection")) {
          if (exit_y = y1) {
            Grid_SetGridCoordinateForPlayer(game.pov, exit, "end_y", exit_y + y_offset)
            changed = true
          }
        }
        else if (ortho_offset <> 0) {
          if (DoesInherit (exit, "northdirection")) {
            if (exit_y = y2) {
              Grid_SetGridCoordinateForPlayer(game.pov, exit, "end_y", exit_y + ortho_offset)
              changed = true
            }
          }
          else if (DoesInherit (exit, "southdirection")) {
            if (exit_y = y1) {
              Grid_SetGridCoordinateForPlayer(game.pov, exit, "end_y", exit_y - ortho_offset)
              changed = true
            }
          }
        }

        // If we change the *end* of an exit, there's a chance it's already been drawn
        //   in this case, we setup a flag to redraw the map at the end of the turn, so we're not redrawing repeatedly
        //   on games which pre-draw the map, or when loading a saved game
        if (changed and Grid_GetRoomBooleanForPlayer(playerobject, exit.parent, "grid_isdrawn") {
          Grid_RedrawAtEndOfTurn()
        }
      }
    }
  }
</function>

<function name="Grid_RedrawAtEndOfTurn">
  if (GetObject ("gridredraw_turnscript") = null) {
    create turnscript ("gridredraw_turnscript")
    gridredraw_turnscript.script => {
      JS.Grid_ClearAllLayers()
      Grid_Redraw()
      destroy (this.name)
    }
  }
  gridredraw_turnscript.enabled = true
</function>