From 32778cf9fd4738e554189a3d4ecb6959196b6e38 Mon Sep 17 00:00:00 2001 From: empathicqubit Date: Fri, 7 May 2021 21:54:25 -0400 Subject: [PATCH] Added a bunch of code to add waypoints to the goal. Not sure at what point this becomes cheating. --- game.lua | 40 ++++++++++++++++++-------- runner.lua | 61 +++++++++++++++++++++++++--------------- state-test.lua | 4 +++ tools/status-overlay.lua | 49 ++++++++++++++++++++++++++------ 4 files changed, 112 insertions(+), 42 deletions(-) diff --git a/game.lua b/game.lua index a80b86f..f99e85a 100644 --- a/game.lua +++ b/game.lua @@ -201,7 +201,7 @@ end ---@param startX integer x coordinate of the starting point ---@param startY integer y coordinate of the starting point ---@return table table A list of all the points that we collided with a platform -function _M.rollFromTarget(startX, startY) +function _M.getWaypoints(startX, startY) local areaWidth = _M.getAreaWidth() local areaHeight = _M.getAreaHeight() local increment = mem.size.tile @@ -211,35 +211,45 @@ function _M.rollFromTarget(startX, startY) -- If we're on the left half, move right if startX > areaWidth / 2 then direction = -direction - terminus = 0 + terminus = 0x100 end local collisions = {} local currentY = startY local currentX = startX + local switches = 0 while currentY < areaHeight - increment do + switches = 0 -- Drop down until we collide with the floor while currentY < areaHeight - increment and _M.getAbsoluteTile(currentX, currentY) ~= 1 do currentY = currentY + increment - print(string.format("currentx: %d, currenty: %d, areaheight: %d, direction: %d, ", currentX, currentY, areaHeight, direction)) - end - - -- Break if we've hit the bottom - if currentY > areaHeight - increment then - break end -- Track the collision table.insert(collisions, { x = currentX, y = currentY, }) + -- Break if we've hit the bottom + if currentY > areaHeight - increment then + break + end -- Move in the direction until we reach a gap or the edge of the area while currentY < areaHeight - increment do currentX = currentX + direction - print(string.format("currentx: %d, currenty: %d, areaheight: %d, direction: %d, ", currentX, currentY, areaHeight, direction)) -- Switch directions if we're out of bounds if direction < 0 and currentX < terminus + increment or direction > 0 and currentX > terminus - increment then - direction = -direction + switches = switches + 1 + if switches > 2 then + currentY = currentY + increment + break + end + if terminus == 0x100 then + terminus = areaWidth + direction = increment + else + terminus = 0x100 + direction = -increment + end elseif _M.getAbsoluteTile(currentX, currentY) ~= 1 then -- Check to make sure there isn't a floor immediately underneath. -- If there is we're probably on an incline. @@ -252,7 +262,6 @@ function _M.rollFromTarget(startX, startY) end end - print(util.table_to_string(collisions)) return collisions end @@ -436,6 +445,15 @@ function _M.getJumpHeight() return sprite.jumpHeight end +function _M.diedFromHit() + local sprite = _M.getSprite(_M.leader) + if sprite == nil then + return 0 + end + + return sprite.motion == 0x05 +end + function _M.fell() local sprite = _M.getSprite(_M.leader) if sprite == nil then diff --git a/runner.lua b/runner.lua index 6387ade..6df5d27 100644 --- a/runner.lua +++ b/runner.lua @@ -254,6 +254,17 @@ local function displayButtons(_M) gui.renderctx.setnull() end +local function getDistanceTraversed(areaInfos) + local distanceTraversed = 0 + for _,areaInfo in pairs(areaInfos) do + for i=1,#areaInfo.waypoints,1 do + local waypoint = areaInfo.waypoints[i] + distanceTraversed = distanceTraversed + (waypoint.startDistance - waypoint.shortest) + end + end + return distanceTraversed +end + local formCtx = nil local form = nil local function displayForm(_M) @@ -274,12 +285,11 @@ local function displayForm(_M) gui.rectangle(0, 0, 500, guiHeight, 1, 0x00ffffff, 0xbb000000) --gui.circle(game.screenX-84, game.screenY-84, 192 / 2, 1, 0x50000000) - local areaInfo = _M.areaInfo[_M.currentArea] - local distanceTraversed = 0 + local distanceTraversed = getDistanceTraversed(_M.areaInfo) local goalX = 0 local goalY = 0 + local areaInfo = _M.areaInfo[_M.currentArea] if areaInfo ~= nil then - distanceTraversed = areaInfo.startDistance - areaInfo.shortest goalX = areaInfo.preferredExit.x goalY = areaInfo.preferredExit.y end @@ -499,7 +509,10 @@ local function initializeRun(_M) _M.lastArea = _M.currentArea for _,areaInfo in pairs(_M.areaInfo) do - areaInfo.shortest = areaInfo.startDistance + for i=1,#areaInfo.waypoints,1 do + local waypoint = areaInfo.waypoints[i] + waypoint.shortest = waypoint.startDistance + end end local genome = _M.currentSpecies.genomes[_M.currentGenomeIndex] @@ -510,14 +523,6 @@ local function initializeRun(_M) end) end -local function getDistanceTraversed(areaInfo) - local distanceTraversed = 0 - for _,areaInfo in pairs(areaInfo) do - distanceTraversed = areaInfo.startDistance - areaInfo.shortest - end - return distanceTraversed -end - local function mainLoop(_M, genome) return game.advanceFrame():next(function() local nextArea = game.getCurrentArea() @@ -532,12 +537,21 @@ local function mainLoop(_M, genome) elseif _M.currentArea == _M.lastArea and _M.areaInfo[_M.currentArea] == nil then message(_M, 'Searching for the main exit in this area') return game.findPreferredExit():next(function(preferredExit) - local startDistance = math.floor(math.sqrt((preferredExit.y - game.partyY) ^ 2 + (preferredExit.x - game.partyX) ^ 2)) - _M.areaInfo[_M.currentArea] = { - startDistance = startDistance, + local areaInfo = { preferredExit = preferredExit, - shortest = startDistance, + waypoints = game.getWaypoints(preferredExit.x, preferredExit.y), } + -- XXX Insert means add a new one, not overwrite? + table.insert(areaInfo.waypoints, 1, preferredExit) + + for i=1,#areaInfo.waypoints,1 do + local waypoint = areaInfo.waypoints[i] + local startDistance = math.floor(math.sqrt((waypoint.y - game.partyY) ^ 2 + (waypoint.x - game.partyX) ^ 2)) + waypoint.startDistance = startDistance + waypoint.shortest = startDistance + end + + _M.areaInfo[_M.currentArea] = areaInfo end) end end):next(function() @@ -565,7 +579,7 @@ local function mainLoop(_M, genome) end local fell = game.fell() - if fell and _M.timeout > 0 then + if (fell or game.diedFromHit()) and _M.timeout > 0 then _M.timeout = 0 end @@ -580,11 +594,14 @@ local function mainLoop(_M, genome) local areaInfo = _M.areaInfo[_M.currentArea] if areaInfo ~= nil and game.partyY ~= 0 and game.partyX ~= 0 then - local exitDist = math.floor(math.sqrt((areaInfo.preferredExit.y - game.partyY) ^ 2 + (areaInfo.preferredExit.x - game.partyX) ^ 2)) - if exitDist < areaInfo.shortest then - areaInfo.shortest = exitDist - if _M.timeout < timeoutConst then - _M.timeout = timeoutConst + for i=1,#areaInfo.waypoints,1 do + local waypoint = areaInfo.waypoints[i] + local dist = math.floor(math.sqrt((waypoint.y - game.partyY) ^ 2 + (waypoint.x - game.partyX) ^ 2)) + if dist < waypoint.shortest then + waypoint.shortest = dist + if _M.timeout < timeoutConst then + _M.timeout = timeoutConst + end end end end diff --git a/state-test.lua b/state-test.lua index a5240e5..a162760 100644 --- a/state-test.lua +++ b/state-test.lua @@ -13,3 +13,7 @@ local serpent = dofile(base.."/serpent.lua") game.registerHandlers() game.getPositions() + +game.findPreferredExit():next(function(preferredExit) + game.getWaypoints(preferredExit.x, preferredExit.y) +end) \ No newline at end of file diff --git a/tools/status-overlay.lua b/tools/status-overlay.lua index 98ab950..f3c08ed 100644 --- a/tools/status-overlay.lua +++ b/tools/status-overlay.lua @@ -1,16 +1,21 @@ local base = string.gsub(@@LUA_SCRIPT_FILENAME@@, "(.*[/\\])(.*)", "%1").."/.." -local set_timer_timeout, memory, memory2, gui, input, bit = set_timer_timeout, memory, memory2, gui, input, bit +local set_timer_timeout, memory, memory2, gui, input, bit, callback = set_timer_timeout, memory, memory2, gui, input, bit, callback local warn = '========== The ROM must be running before running this script' io.stderr:write(warn) print(warn) -local util = dofile(base.."/util.lua")() +local Promise = dofile(base.."/promise.lua") +callback.register('timer', function() + Promise.update() + set_timer_timeout(1) +end) +set_timer_timeout(1) +local util = dofile(base.."/util.lua")(Promise) local mem = dofile(base.."/mem.lua") local spritelist = dofile(base.."/spritelist.lua") -local game = dofile(base.."/game.lua")() -local config = dofile(base.."/config.lua") +local game = dofile(base.."/game.lua")(Promise) spritelist.InitSpriteList() spritelist.InitExtSpriteList() @@ -203,6 +208,7 @@ local function sprite_details(idx) text(0, 0, "Sprite "..idx..(locked and " (Locked)" or "")..":\n\n"..util.table_to_string(sprite)) end +local waypoints = {} local overlayCtx = nil local overlay = nil local function renderOverlay(guiWidth, guiHeight) @@ -307,6 +313,31 @@ Current area: %04x ::continue:: end + for i=1,#waypoints,1 do + local screenX = (waypoints[i].x - game.cameraX) * 2 + local screenY = (waypoints[i].y - game.cameraY) * 2 + + if screenX > guiWidth - mem.size.tile * 2 then + screenX = guiWidth - mem.size.tile * 2 + end + + if screenY > guiHeight then + screenY = guiHeight - 20 + end + + if screenX < 0 then + screenX = 0 + end + + if screenY < 0 then + screenY = 0 + end + + text(screenX, screenY, "WAYPOINT "..i) + end + + text(guiWidth / 2, guiHeight - 20, "WAYPOINTS: "..#waypoints) + if rulers and game.cameraX >= 0 then local halfWidth = math.floor(guiWidth / 2) local halfHeight = math.floor(guiHeight / 2) @@ -417,10 +448,6 @@ function on_paint (not_synth) end end -function on_timer() - set_timer_timeout(100 * 1000) -end - input.keyhook("1", true) input.keyhook("2", true) input.keyhook("3", true) @@ -432,7 +459,11 @@ input.keyhook("8", true) input.keyhook("9", true) input.keyhook("0", true) -set_timer_timeout(100 * 1000) +game.findPreferredExit():next(function(preferredExit) + return game.getWaypoints(preferredExit.x, preferredExit.y) +end):next(function(w) + waypoints = w +end) -- fe0a58 crate: near bunch and klomp on barrels -- fe0a58: Crate X position