DramaticShapeVoxelMod archival mirror · read-only
data/battle_arenas.lua

battle_arenas.lua

data/battle_arenas.lua12.8 KB10064433f7164646
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
-- Where each map's battles happen.
--
-- One authored spot per area, rather than whichever clearing happens to be
-- nearest the step the fight started on. A battle on Route 1 should look the
-- same every time it happens on Route 1 -- and, more importantly, "open
-- ground" is not the same question as "you can see the two of them": the
-- battle camera sits low and a long way back, so a hedge, a ledge lip or the
-- corner of a house anywhere along that sightline hides a Pokemon completely
-- while every cell it is standing on is perfectly walkable.
--
-- Each entry is the arena's north-west corner in map CELLS, and which of
-- BattleArena.SHAPES it is. Picked by tools/arena_pick (BattleArena.search
-- with the clearance test on, from the middle of the map) and then looked at,
-- one screenshot per map -- these are eyeballed answers, not just passing
-- ones. Grass and flowers around a mon's feet are fine and wanted; anything
-- that cuts into a body is not.
--
-- A map with no entry here falls back to the nearest-clear search at battle
-- time, so a mod that adds maps, or an entry that goes stale against an
-- edited map, degrades to the old behaviour rather than to no battle.
--
-- The entries below are generated; regenerate with
--
--   SHOT_DIR=.scratchpad/arenas \
--   POKEPORT_DRIVER=mods/DramaticShapeVoxelMod/tests/arena_pick.lua love .
--
-- To change ONE map's spot, or to go over these by eye, run the editor
-- instead -- it is the same choice made in front of the map rather than in a
-- batch. It slides the arena around on a plan of the map with the fit, the
-- clearance and the camera's own sightlines answering live, stages a real
-- battle on the spot when asked, and writes this file back a map at a time,
-- replacing only the lines that changed and leaving every comment here alone:
--
--   POKEPORT_DRIVER=mods/DramaticShapeVoxelMod/tests/arena_editor.lua lovec .
--
-- Its export lands in .scratchpad/arena_editor/ to be diffed and copied over;
-- ARENA_WRITE=1 points it at this file directly. A comment above an entry it
-- moved describes where that spot USED to be, and it says so by name at
-- export time -- those are the lines to re-word by hand.

-- `cam = "wide"` on an entry swaps the long default lens for the 44-degree
-- one (BattleCam.RIGS). Both frame the same composition -- the two mons land
-- on the same screen anchors either way -- so it is purely a choice about how
-- much of the place is in shot, at the cost of a smaller pair. Rooms the long
-- lens cannot stand back from NEED it; anywhere that simply reads better with
-- more of itself visible may ask for it.
--
-- Tall grass is never part of an arena (BattleArena.openCell rejects it), so
-- a route's spot is always its bare path rather than the field beside it --
-- grass is knee-high geometry to a Pokemon and this camera is nearly level
-- with the floor, so tufts on the mon's own tile stand between it and the
-- lens. Flowers are left alone: they are ankle height and read as ground.

return {
  -- ------- routes
  -- narrow, deliberately: the route's interior is a 3-cell-wide lane and the
  -- wide shape only fits in the western connection border, which staged every
  -- fight at the edge of the world instead of on the road.
  --
  -- Of the seventeen spots the route has outside that border, fourteen are
  -- this one mid-route clearing and the other three bury the near mon behind
  -- a hedge -- which the clearance test passes, since it measures terrain
  -- height along the sightline and a hedge in the apron row is not terrain.
  -- So the choice is where in the clearing, and this is its west end: tree
  -- line square behind the pair, nothing crossing either of them.
  ["ROUTE_1"] = { x = 10, y = 16, shape = "narrow", turn = 90 },
  ["ROUTE_2"] = { x = 1, y = 49, shape = "wide" },
  ["ROUTE_3"] = { x = 52, y = 10, shape = "wide", turn = 90 },
  ["ROUTE_4"] = { x = 46, y = 4, shape = "wide" },
  ["ROUTE_5"] = { x = 7, y = 0, shape = "wide", turn = 270 },
  ["ROUTE_6"] = { x = 4, y = 15, shape = "narrow" },
  ["ROUTE_7"] = { x = 4, y = 3, shape = "narrow", cam = "wide" },
  ["ROUTE_8"] = { x = 24, y = 5, shape = "wide", turn = 90 },
  -- the whole route admits six bare wide arenas, all in the west cliff
  -- corridor; this is the best of them. A flower cluster crosses the far
  -- mon's hind legs, which the brief allows -- every alternative put a
  -- terrace through the near mon's waist, which it does not.
  ["ROUTE_9"] = { x = 1, y = 11, shape = "wide", cam = "wide" },
  ["ROUTE_10"] = { x = 7, y = 40, shape = "wide" },
  ["ROUTE_11"] = { x = 9, y = 6, shape = "wide" },
  ["ROUTE_12"] = { x = 10, y = 71, shape = "wide", turn = 90 },
  ["ROUTE_13"] = { x = 51, y = 5, shape = "narrow" },
  ["ROUTE_14"] = { x = 11, y = 24, shape = "wide" },
  ["ROUTE_15"] = { x = 30, y = 10, shape = "wide", turn = 90 },
  ["ROUTE_16"] = { x = 8, y = 10, shape = "wide", turn = 90 },
  ["ROUTE_17"] = { x = 14, y = 70, shape = "wide" },
  ["ROUTE_18"] = { x = 11, y = 3, shape = "wide" },

  -- ------- buildings and caves
  --
  -- Indoors the narrow shape earns its keep: a room with furniture, machinery
  -- or gravestones in it rarely holds a 3x6 clearing whose whole width is
  -- also SEEN, and giving up the apron is usually the difference between a
  -- fight in the open and one behind a console.
  ["POKEMON_MANSION_1F"] = { x = 4, y = 12, shape = "wide", cam = "wide" },
  ["POKEMON_MANSION_2F"] = { x = 10, y = 1, shape = "wide", cam = "wide" },
  ["POKEMON_MANSION_3F"] = { x = 24, y = 3, shape = "narrow", cam = "wide" },
  ["POKEMON_MANSION_B1F"] = { x = 6, y = 19, shape = "wide", turn = 90 },
  ["POKEMON_TOWER_2F"] = { x = 4, y = 7, shape = "narrow" },
  ["POKEMON_TOWER_3F"] = { x = 4, y = 6, shape = "wide" },
  -- every one of 4F's thirty candidate spots puts a gravestone through a
  -- mon; the floor below is the same tower and has the room, so the fight
  -- is shot there
  ["POKEMON_TOWER_4F"] = { map = "POKEMON_TOWER_3F", x = 4, y = 6,
                           shape = "wide" },
  ["POKEMON_TOWER_5F"] = { x = 8, y = 9, shape = "narrow", cam = "wide" },
  ["POKEMON_TOWER_6F"] = { x = 14, y = 6, shape = "narrow", cam = "wide" },
  ["POKEMON_TOWER_7F"] = { x = 9, y = 5, shape = "wide" },
  ["POWER_PLANT"] = { x = 18, y = 5, shape = "narrow" },
  ["ROCK_TUNNEL_1F"] = { x = 14, y = 15, shape = "wide" },
  ["ROCK_TUNNEL_B1F"] = { x = 20, y = 17, shape = "wide" },
  ["ROCKET_HIDEOUT_B1F"] = { x = 20, y = 18, shape = "narrow" },
  ["ROCKET_HIDEOUT_B2F"] = { x = 20, y = 10, shape = "narrow", cam = "wide" },
  ["ROCKET_HIDEOUT_B3F"] = { x = 24, y = 15,
                             shape = "narrow", turn = 90, cam = "wide" },
  ["ROCKET_HIDEOUT_B4F"] = { x = 19, y = 17, shape = "wide", cam = "wide" },
  ["SAFARI_ZONE_CENTER"] = { x = 1, y = 8, shape = "wide" },
  ["SAFARI_ZONE_EAST"] = { x = 16, y = 8,
                           shape = "wide", turn = 90, cam = "wide" },
  ["SAFARI_ZONE_NORTH"] = { x = 22, y = 12, shape = "wide", turn = 90 },
  ["SAFARI_ZONE_WEST"] = { x = 20, y = 2, shape = "wide" },
  ["SEAFOAM_ISLANDS_1F"] = { x = 14, y = 7, shape = "wide" },
  ["SEAFOAM_ISLANDS_B1F"] = { x = 9, y = 8,
                              shape = "wide", turn = 90, cam = "wide" },
  ["SEAFOAM_ISLANDS_B2F"] = { x = 15, y = 9, shape = "wide", turn = 90 },
  ["SEAFOAM_ISLANDS_B3F"] = { x = 26, y = 7, shape = "wide", turn = 180 },
  ["SEAFOAM_ISLANDS_B4F"] = { x = 9, y = 7, shape = "narrow" },
  -- Silph Co is office floors partitioned into small rooms, so the long lens
  -- often lands outside the walls it is meant to be looking between; the
  -- floors that could not be framed any other way ask for the wide one.
  ["SILPH_CO_2F"] = { x = 4, y = 9, shape = "narrow", turn = 270 },
  ["SILPH_CO_4F"] = { x = 14, y = 14, shape = "narrow", turn = 90 },
  ["SILPH_CO_5F"] = { x = 16, y = 7, shape = "wide" },
  ["SILPH_CO_6F"] = { x = 19, y = 2,
                      shape = "narrow", turn = 90, cam = "wide" },
  ["SILPH_CO_7F"] = { x = 1, y = 2, shape = "wide", cam = "wide" },
  ["SILPH_CO_8F"] = { x = 8, y = 6, shape = "narrow" },
  ["SILPH_CO_9F"] = { x = 20, y = 11, shape = "wide", cam = "wide" },
  ["SS_ANNE_1F_ROOMS"] = { x = 11, y = 1, shape = "narrow", cam = "wide" },
  -- the ship is all two-cell corridors, so the wide arena shape fits nowhere
  -- aboard and the long lens always lands outside the hull
  ["SS_ANNE_2F"] = { x = 36, y = 8, shape = "narrow", cam = "wide" },
  -- these two decks are byte-identical geometry, so they take the same spot
  ["SS_ANNE_2F_ROOMS"] = { x = 11, y = 12, shape = "narrow", cam = "wide" },
  ["SS_ANNE_B1F_ROOMS"] = { x = 11, y = 12, shape = "narrow", cam = "wide" },
  ["SS_ANNE_BOW"] = { x = 8, y = 3, shape = "wide" },
  ["VICTORY_ROAD_2F"] = { x = 16, y = 6, shape = "wide", cam = "wide" },
  ["VICTORY_ROAD_3F"] = { x = 20, y = 1, shape = "wide", cam = "wide" },

  -- ------- towns and the last interiors
  ["CERULEAN_CITY"] = { x = 15, y = 16, shape = "wide" },
  ["GAME_CORNER"] = { x = 8, y = 5, shape = "wide" },
  -- the lab is ten cells by twelve, so the long lens is always off-map, and
  -- on it a desk clipped one mon and a pillar the other
  ["OAKS_LAB"] = { x = 1, y = 3, shape = "narrow", turn = 90, cam = "wide" },
  -- Saffron's gym is a grid of small walled cells: no wide shape exists
  -- anywhere in it, and the long lens sits inside a divider
  ["SAFFRON_GYM"] = { x = 9, y = 7, shape = "narrow", cam = "wide" },
  ["SILPH_CO_3F"] = { x = 18, y = 11, shape = "wide", cam = "wide" },
  ["SILPH_CO_10F"] = { x = 1, y = 1, shape = "wide", cam = "wide" },
  ["SILPH_CO_11F"] = { x = 10, y = 6,
                       shape = "wide", turn = 180, cam = "wide" },
  -- the upper corridor (cols 4-5, rows 1-4) is sealed at runtime by the
  -- gym's barrier, so arenas there silently fail the fit test
  ["VERMILION_GYM"] = { x = 3, y = 2,
                        shape = "narrow", turn = 90, cam = "wide" },
  ["VICTORY_ROAD_1F"] = { x = 11, y = 5, shape = "narrow", cam = "wide" },
  ["VIRIDIAN_FOREST"] = { x = 16, y = 34, shape = "narrow" },

  -- ------- the remaining routes
  ["ROUTE_19"] = { x = 8, y = 31, shape = "narrow" },
  -- the two surf routes fight AFLOAT, in the middle of their own sea rather
  -- than on the rim of beach the land search would otherwise find
  ["ROUTE_20"] = { x = 23, y = 7, shape = "wide" },
  ["ROUTE_21"] = { x = 8, y = 46, shape = "wide" },
  ["ROUTE_22"] = { x = 35, y = 7, shape = "wide", cam = "wide" },
  ["ROUTE_23"] = { x = 2, y = 34, shape = "wide", cam = "wide" },
  ["ROUTE_24"] = { x = 6, y = 9, shape = "wide", turn = 270, cam = "wide" },
  ["ROUTE_25"] = { x = 32, y = 2, shape = "wide", cam = "wide" },

  -- ------- caves, gyms and the Elite Four
  --
  -- None of these tilesets has a grass tile at all, so the no-grass rule
  -- constrained nothing here; what constrains them is furniture, rock
  -- pillars and how small the rooms are.
  ["AGATHAS_ROOM"] = { x = 4, y = 2, shape = "narrow", cam = "wide" },
  ["BRUNOS_ROOM"] = { x = 2, y = 1, shape = "wide", turn = 90 },
  ["CELADON_GYM"] = { x = 3, y = 4,
                      shape = "narrow", turn = 90, cam = "wide" },
  ["CERULEAN_CAVE_1F"] = { x = 12, y = 8, shape = "narrow", cam = "wide" },
  -- 2F is a maze of one-cell rock corridors; all 24 of its candidate spots
  -- hide a mon, so it borrows the floor below -- the same cave
  ["CERULEAN_CAVE_2F"] = { map = "CERULEAN_CAVE_B1F", x = 2, y = 0,
                           shape = "wide" },
  ["CERULEAN_CAVE_B1F"] = { x = 2, y = 0, shape = "wide", cam = "wide" },
  ["CERULEAN_GYM"] = { x = 4, y = 2, shape = "wide" },
  ["CHAMPIONS_ROOM"] = { x = 2, y = 2, shape = "narrow", cam = "wide" },
  ["CINNABAR_GYM"] = { x = 9, y = 16,
                       shape = "narrow", turn = 90, cam = "wide" },
  ["DIGLETTS_CAVE"] = { x = 14, y = 26,
                        shape = "wide", turn = 90, cam = "wide" },
  ["FIGHTING_DOJO"] = { x = 3, y = 5,
                        shape = "narrow", turn = 90, cam = "wide" },
  ["LANCES_ROOM"] = { x = 4, y = 2, shape = "wide", cam = "wide" },
  ["LORELEIS_ROOM"] = { x = 4, y = 2, shape = "narrow" },
  ["MT_MOON_1F"] = { x = 25, y = 16, shape = "wide" },
  ["MT_MOON_B1F"] = { x = 4, y = 11, shape = "wide" },
  ["MT_MOON_B2F"] = { x = 8, y = 20, shape = "wide" },

  -- The three gyms the default rig cannot stand back from. Five blocks is
  -- further than these rooms are wide, so the eye landed outside the map and
  -- the border ring -- extruded into a cliff by this mode -- crossed the near
  -- mon wherever it stood. `cam = "wide"` swaps in the 44-degree lens (see
  -- BattleCam), which fits inside the room; the mons come out smaller and all
  -- three became stageable. It is asked for HERE, per map, so every area that
  -- does not ask keeps the long lens it was framed for.
  ["FUCHSIA_GYM"] = { x = 8, y = 6, shape = "narrow", cam = "wide" },
  ["PEWTER_GYM"] = { x = 4, y = 1, shape = "narrow", turn = 90, cam = "wide" },
  ["VIRIDIAN_GYM"] = { x = 10, y = 8, shape = "narrow", cam = "wide" },
}