DramaticShapeVoxelMod archival mirror · read-only
tests/shiny_obs.lua

shiny_obs.lua

tests/shiny_obs.lua4.3 KB1006448c29e73239
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
-- Driver: five shiny encounters, five outdoor places, paced for a capture.
--
--   POKEPORT_DRIVER=mods/DramaticShapeVoxelMod/tests/shiny_obs.lua \
--   "/c/Program Files/LOVE/lovec.exe" .
--
-- Run from the PROJECT ROOT. Nothing here is a screenshot test -- it is a
-- performance, timed for somebody recording the window.
--
-- Each beat: teleport, let the ground mesh, open a wild battle, let the
-- Pokemon ARRIVE (the wipe, the send-out, the shiny sparkle), then hold
-- three full seconds on it before closing the battle and moving on. The hold
-- is deliberately silent -- no button taps during it -- so the recording is
-- of the Pokemon standing there and not of a text box being clicked through.
--
-- Every encounter is shiny, because the odds are pinned to 1 for the run and
-- the roll still happens where it always does, inside Pokemon.new.
return function(game)
  local U = dofile("tests/drivers/util.lua")
  local BattleState = require("src.battle.BattleState")
  local Pokemon = require("src.pokemon.Pokemon")

  local exports = game.mods and game.mods.exports
  local lib = exports and exports.DRAMATIC_SHAPE and exports.DRAMATIC_SHAPE.lib
  if not lib then
    U.log("DRAMATIC_SHAPE is not loaded -- nothing to show")
    return
  end
  local Shiny = lib.require("Shiny")
  local OverworldBattle = lib.require("OverworldBattle")
  local StadiumInstall = lib.require("StadiumInstall")

  -- ------- timing, in frames at 60fps
  local SETTLE   = 110   -- after a teleport, for the neighbourhood to mesh
  local ARRIVE   = 70    -- the wipe, then the Pokemon landing on its tile
  local HOLD     = 180   -- THE THREE SECONDS
  local BETWEEN  = 45    -- back on the map before the next one opens

  -- ------- the models
  if not StadiumInstall.ready() then
    U.log("building stadium models first...")
    StadiumInstall.begin()
    local guard = 0
    while not StadiumInstall.ready() and guard < 2000 do
      for _ = 1, 6 do StadiumInstall.step() end
      U.wait(1)
      guard = guard + 1
    end
  end
  U.log("stadium ready: " .. tostring(StadiumInstall.ready()))

  OverworldBattle.setting:setValue("stadium", game)

  -- party FIRST, at ordinary odds: Pokemon.new is where shininess is
  -- decided, so pinning the odds before this made the player's own Pikachu
  -- shiny -- and that tints the player's side, which during the intro is the
  -- trainer sprite. The foe is what these runs are about.
  game.save.player.name = "RED"
  game.save.party = { Pokemon.new(game.data, "PIKACHU", 50) }

  Shiny.setOdds(1)                       -- from here on: every encounter

  -- Five outdoor places, deliberately unalike -- a coast, an open route, a
  -- water city, a rocky pass and a wooded shore -- so the recording is five
  -- different-looking fights and not the same meadow five times. Each mon is
  -- put somewhere its colour has something to sit against.
  local RUNS = {
    { "CHARIZARD",  50, "ROUTE_4",       10, 5 },
    { "ELECTRODE",  40, "VIRIDIAN_CITY", 20, 20 },
    { "VAPOREON",   42, "ROUTE_25",      12, 5 },
    { "DRATINI",    30, "ROUTE_3",       10, 5 },
  }

  -- a beat before the first one, so a recorder that started with the window
  -- is not already mid-encounter by the time it is rolling
  U.log("starting in 3...")
  U.wait(60)
  U.log("2...")
  U.wait(60)
  U.log("1...")
  U.wait(60)

  for i, r in ipairs(RUNS) do
    local species, level, map, cx, cy = r[1], r[2], r[3], r[4], r[5]
    if not game.data.pokemon[species] then
      U.log(("skip %s -- not in this dataset"):format(species))
    elseif not game.data.maps[map] then
      U.log(("skip %s -- no map %s"):format(species, map))
    else
      U.teleport(game, map, cx, cy, "down")
      U.wait(SETTLE)

      local battle = BattleState.newWild(game, species, level)
      battle.onFinish = function() end
      game.overworld:pushBattle(battle)

      local mon = battle.enemy and battle.enemy.mon
      U.log(("%d/4  %-10s  %-14s  shiny=%s")
            :format(i, species, map, tostring(Shiny.isShiny(mon))))

      -- the arrival, then three seconds of nothing but the Pokemon
      U.wait(ARRIVE)
      U.wait(HOLD)

      -- close the battle and go back to the map
      while game.stack:top() and game.stack:top() ~= game.overworld do
        game.stack:pop()
      end
      U.wait(BETWEEN)
    end
  end

  Shiny.setOdds(8192)
  U.log("done -- five encounters")
end