Fix bitness of velocity. Added target scan function. Currently broken.
This commit is contained in:
parent
7fcb93c83c
commit
eb53739618
5 changed files with 135 additions and 61 deletions
|
@ -41,7 +41,7 @@ _M.StartPowerup = 0
|
|||
|
||||
_M.NeatConfig = {
|
||||
DisableSound = true,
|
||||
Threads = 1,
|
||||
Threads = 7,
|
||||
--Filename = "DP1.state",
|
||||
SaveFile = _M.Filename .. ".pool",
|
||||
|
||||
|
|
74
game.lua
74
game.lua
|
@ -196,6 +196,66 @@ function _M.findPreferredExit()
|
|||
end)
|
||||
end
|
||||
|
||||
--- Starting from a specified point in the area, weave back and forth until we reach
|
||||
--- fall to the bottom. Return all points where we hit the floor on the way down.
|
||||
---@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)
|
||||
local areaWidth = _M.getAreaWidth()
|
||||
local areaHeight = _M.getAreaHeight()
|
||||
local increment = mem.size.tile
|
||||
local direction = increment
|
||||
local terminus = areaWidth
|
||||
-- If we're on the right half, move left
|
||||
-- If we're on the left half, move right
|
||||
if startX > areaWidth / 2 then
|
||||
direction = -direction
|
||||
terminus = 0
|
||||
end
|
||||
|
||||
local collisions = {}
|
||||
local currentY = startY
|
||||
local currentX = startX
|
||||
while currentY < areaHeight - increment do
|
||||
-- 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,
|
||||
})
|
||||
-- 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
|
||||
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.
|
||||
if _M.getAbsoluteTile(currentX, currentY + increment) == 1 then
|
||||
currentY = currentY + increment
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
print(util.table_to_string(collisions))
|
||||
return collisions
|
||||
end
|
||||
|
||||
function _M.getGoalHit()
|
||||
local sprites = _M.getSprites()
|
||||
for i=1,#sprites,1 do
|
||||
|
@ -345,9 +405,9 @@ function _M.tileIsSolid(x, y, tileVal, tileOffset)
|
|||
return true
|
||||
end
|
||||
|
||||
function _M.getTile(dx, dy)
|
||||
local tileX = math.floor((_M.partyX + dx * mem.size.tile) / mem.size.tile) * mem.size.tile
|
||||
local tileY = math.floor((_M.partyY + dy * mem.size.tile) / mem.size.tile) * mem.size.tile
|
||||
function _M.getAbsoluteTile(x, y)
|
||||
local tileX = math.floor(x / mem.size.tile) * mem.size.tile
|
||||
local tileY = math.floor(y / mem.size.tile) * mem.size.tile
|
||||
|
||||
local offset = _M.tileOffsetCalculation(tileX, tileY, _M.vertical)
|
||||
|
||||
|
@ -360,6 +420,10 @@ function _M.getTile(dx, dy)
|
|||
return 1
|
||||
end
|
||||
|
||||
function _M.getTile(dx, dy)
|
||||
return _M.getAbsoluteTile(_M.partyX + dx * mem.size.tile, _M.partyY + dy * mem.size.tile)
|
||||
end
|
||||
|
||||
function _M.getCurrentArea()
|
||||
return memory.readword(mem.addr.currentAreaNumber)
|
||||
end
|
||||
|
@ -403,8 +467,8 @@ function _M.getSprite(idx)
|
|||
-- 0x4000 0: Right facing 1: Flipped
|
||||
-- 0x1000 0: Alive 1: Dying
|
||||
style = util.regionToWord(spriteData, offsets.style),
|
||||
velocityX = util.regionToWord(spriteData, offsets.velocityX),
|
||||
velocityY = util.regionToWord(spriteData, offsets.velocityY),
|
||||
velocityX = util.regionToSWord(spriteData, offsets.velocityX),
|
||||
velocityY = util.regionToSWord(spriteData, offsets.velocityY),
|
||||
motion = util.regionToWord(spriteData, offsets.motion),
|
||||
x = x,
|
||||
y = y,
|
||||
|
|
|
@ -10,3 +10,6 @@ set_timer_timeout(1)
|
|||
local game = dofile(base.."/game.lua")(Promise)
|
||||
local util = dofile(base.."/util.lua")(Promise)
|
||||
local serpent = dofile(base.."/serpent.lua")
|
||||
|
||||
game.registerHandlers()
|
||||
game.getPositions()
|
||||
|
|
|
@ -132,44 +132,43 @@ function on_input (subframe)
|
|||
end
|
||||
end
|
||||
|
||||
local function get_sprite(base_addr)
|
||||
local function get_sprite(baseAddr)
|
||||
local spriteData = memory.readregion(baseAddr, mem.size.sprite)
|
||||
local offsets = mem.offset.sprite
|
||||
local cameraX = memory.readword(mem.addr.cameraX) - 256
|
||||
local cameraY = memory.readword(mem.addr.cameraY) - 256
|
||||
local x = memory.readword(base_addr + offsets.x)
|
||||
local y = memory.readword(base_addr + offsets.y)
|
||||
local x = util.regionToWord(spriteData, offsets.x)
|
||||
local y = util.regionToWord(spriteData, offsets.y)
|
||||
return {
|
||||
base_addr = string.format("%04x", base_addr),
|
||||
screenX = x - 256 - cameraX,
|
||||
screenY = y - 256 - cameraY - mem.size.tile / 3,
|
||||
control = memory.readword(base_addr + offsets.control),
|
||||
draworder = memory.readword(base_addr + 0x02),
|
||||
base_addr = string.format("%04x", baseAddr),
|
||||
screenX = x - game.cameraX,
|
||||
screenY = y - game.cameraY - mem.size.tile / 3,
|
||||
control = util.regionToWord(spriteData, offsets.control),
|
||||
draworder = util.regionToWord(spriteData, 0x02),
|
||||
x = x,
|
||||
y = y,
|
||||
jumpHeight = memory.readword(base_addr + offsets.jumpHeight),
|
||||
style = memory.readword(base_addr + offsets.style),
|
||||
currentframe = memory.readword(base_addr + 0x18),
|
||||
nextframe = memory.readword(base_addr + 0x1a),
|
||||
state = memory.readword(base_addr + 0x1e),
|
||||
velocityX = memory.readsword(base_addr + offsets.velocityX),
|
||||
velocityY = memory.readsword(base_addr + offsets.velocityY),
|
||||
velomaxx = memory.readsword(base_addr + 0x26),
|
||||
velomaxy = memory.readsword(base_addr + 0x2a),
|
||||
motion = memory.readword(base_addr + offsets.motion),
|
||||
attr = memory.readword(base_addr + 0x30),
|
||||
animnum = memory.readword(base_addr + 0x36),
|
||||
remainingframe = memory.readword(base_addr + 0x38),
|
||||
animcontrol = memory.readword(base_addr + 0x3a),
|
||||
animreadpos = memory.readword(base_addr + 0x3c),
|
||||
animcontrol2 = memory.readword(base_addr + 0x3e),
|
||||
animformat = memory.readword(base_addr + 0x40),
|
||||
damage1 = memory.readword(base_addr + 0x44),
|
||||
damage2 = memory.readword(base_addr + 0x46),
|
||||
damage3 = memory.readword(base_addr + 0x48),
|
||||
damage4 = memory.readword(base_addr + 0x4a),
|
||||
damage5 = memory.readword(base_addr + 0x4c),
|
||||
damage6 = memory.readword(base_addr + 0x4e),
|
||||
spriteparam = memory.readword(base_addr + 0x58),
|
||||
jumpHeight = util.regionToWord(spriteData, offsets.jumpHeight),
|
||||
style = util.regionToWord(spriteData, offsets.style),
|
||||
currentframe = util.regionToWord(spriteData, 0x18),
|
||||
nextframe = util.regionToWord(spriteData, 0x1a),
|
||||
state = util.regionToWord(spriteData, 0x1e),
|
||||
velocityX = util.regionToSWord(spriteData, offsets.velocityX),
|
||||
velocityY = util.regionToSWord(spriteData, offsets.velocityY),
|
||||
velomaxx = util.regionToSWord(spriteData, 0x26),
|
||||
velomaxy = util.regionToSWord(spriteData, 0x2a),
|
||||
motion = util.regionToWord(spriteData, offsets.motion),
|
||||
attr = util.regionToWord(spriteData, 0x30),
|
||||
animnum = util.regionToWord(spriteData, 0x36),
|
||||
remainingframe = util.regionToWord(spriteData, 0x38),
|
||||
animcontrol = util.regionToWord(spriteData, 0x3a),
|
||||
animreadpos = util.regionToWord(spriteData, 0x3c),
|
||||
animcontrol2 = util.regionToWord(spriteData, 0x3e),
|
||||
animformat = util.regionToWord(spriteData, 0x40),
|
||||
damage1 = util.regionToWord(spriteData, 0x44),
|
||||
damage2 = util.regionToWord(spriteData, 0x46),
|
||||
damage3 = util.regionToWord(spriteData, 0x48),
|
||||
damage4 = util.regionToWord(spriteData, 0x4a),
|
||||
damage5 = util.regionToWord(spriteData, 0x4c),
|
||||
damage6 = util.regionToWord(spriteData, 0x4e),
|
||||
spriteparam = util.regionToWord(spriteData, 0x58),
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -233,6 +232,8 @@ Sprite Details:
|
|||
return
|
||||
end
|
||||
|
||||
game.getPositions()
|
||||
|
||||
local toggles = ""
|
||||
|
||||
if pokemon then
|
||||
|
@ -256,17 +257,11 @@ Sprite Details:
|
|||
"Up"
|
||||
}
|
||||
|
||||
local cameraX = memory.readword(mem.addr.cameraX) - 256
|
||||
local cameraY = memory.readword(mem.addr.cameraY) - 256
|
||||
local cameraDir = memory.readbyte(CAMERA_MODE)
|
||||
|
||||
local direction = directions[cameraDir+1]
|
||||
|
||||
local vertical = memory.readword(mem.addr.tileCollisionMathPointer) == mem.addr.verticalPointer
|
||||
|
||||
local partyX = memory.readword(mem.addr.partyX)
|
||||
local partyY = memory.readword(mem.addr.partyY)
|
||||
local partyTileOffset = game.tileOffsetCalculation(partyX, partyY, vertical)
|
||||
local partyTileOffset = game.tileOffsetCalculation(game.partyX, game.partyY, game.vertical)
|
||||
|
||||
local stats = string.format([[
|
||||
%s camera %d,%d
|
||||
|
@ -275,11 +270,11 @@ Tile offset: %04x
|
|||
Main area: %04x
|
||||
Current area: %04x
|
||||
%s
|
||||
]], direction, cameraX, cameraY, vertical, partyTileOffset, memory.readword(mem.addr.mainAreaNumber), memory.readword(mem.addr.currentAreaNumber), util.table_to_string(game.getInputs()):gsub("[\\{\\},\n\"]", ""):gsub("-1", "X"):gsub("0", "."):gsub("1", "O"):gsub("(.............)", "%1\n"))
|
||||
]], direction, game.cameraX, game.cameraY, game.vertical, partyTileOffset, memory.readword(mem.addr.mainAreaNumber), memory.readword(mem.addr.currentAreaNumber), util.table_to_string(game.getInputs()):gsub("[\\{\\},\n\"]", ""):gsub("-1", "X"):gsub("0", "."):gsub("1", "O"):gsub("(.............)", "%1\n"))
|
||||
|
||||
text(guiWidth - 125, guiHeight - 200, stats)
|
||||
|
||||
text((partyX - 256 - cameraX) * 2, (partyY - 256 - cameraY) * 2 + 20, "Party")
|
||||
text((game.partyX - game.cameraX) * 2, (game.partyY - game.cameraY) * 2 + 20, "Party")
|
||||
|
||||
local sprites = {}
|
||||
for idx = 0,22,1 do
|
||||
|
@ -312,20 +307,20 @@ Current area: %04x
|
|||
::continue::
|
||||
end
|
||||
|
||||
if rulers and cameraX >= 0 then
|
||||
if rulers and game.cameraX >= 0 then
|
||||
local halfWidth = math.floor(guiWidth / 2)
|
||||
local halfHeight = math.floor(guiHeight / 2)
|
||||
|
||||
local cameraTileX = math.floor(cameraX / mem.size.tile)
|
||||
local cameraTileX = math.floor(game.cameraX / mem.size.tile)
|
||||
gui.line(0, halfHeight, guiWidth, halfHeight, BG_COLOR)
|
||||
for i = cameraTileX, cameraTileX + guiWidth / mem.size.tile / 2,1 do
|
||||
text((i * mem.size.tile - cameraX) * 2, halfHeight, tostring(i), FG_COLOR, BG_COLOR)
|
||||
text((i * mem.size.tile - game.cameraX) * 2, halfHeight, tostring(i), FG_COLOR, BG_COLOR)
|
||||
end
|
||||
|
||||
local cameraTileY = math.floor(cameraY / mem.size.tile)
|
||||
local cameraTileY = math.floor(game.cameraY / mem.size.tile)
|
||||
gui.line(halfWidth, 0, halfWidth, guiHeight, BG_COLOR)
|
||||
for i = cameraTileY, cameraTileY + guiHeight / mem.size.tile / 2,1 do
|
||||
text(halfWidth, (i * mem.size.tile - cameraY) * 2, tostring(i), FG_COLOR, BG_COLOR)
|
||||
text(halfWidth, (i * mem.size.tile - game.cameraY) * 2, tostring(i), FG_COLOR, BG_COLOR)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -333,10 +328,10 @@ Current area: %04x
|
|||
|
||||
for x = -TILE_RADIUS, TILE_RADIUS, 1 do
|
||||
for y = -TILE_RADIUS, TILE_RADIUS, 1 do
|
||||
local tileX = math.floor((partyX + x * mem.size.tile) / mem.size.tile) * mem.size.tile
|
||||
local tileY = math.floor((partyY + y * mem.size.tile) / mem.size.tile) * mem.size.tile
|
||||
local tileX = math.floor((game.partyX + x * mem.size.tile) / mem.size.tile) * mem.size.tile
|
||||
local tileY = math.floor((game.partyY + y * mem.size.tile) / mem.size.tile) * mem.size.tile
|
||||
|
||||
local offset = game.tileOffsetCalculation(tileX, tileY, vertical)
|
||||
local offset = game.tileOffsetCalculation(tileX, tileY, game.vertical)
|
||||
|
||||
local tile = memory.readword(tilePtr + offset)
|
||||
|
||||
|
@ -344,8 +339,8 @@ Current area: %04x
|
|||
goto continue
|
||||
end
|
||||
|
||||
local screenX = (tileX - 256 - cameraX) * 2
|
||||
local screenY = (tileY - 256 - cameraY) * 2
|
||||
local screenX = (tileX - 256 - game.cameraX) * 2
|
||||
local screenY = (tileY - 256 - game.cameraY) * 2
|
||||
if screenX < 0 or screenX > guiWidth or
|
||||
screenY < 0 or screenY > guiHeight then
|
||||
--goto continue
|
||||
|
@ -357,7 +352,7 @@ Current area: %04x
|
|||
end
|
||||
end
|
||||
|
||||
if cameraX >= 0 then
|
||||
if game.cameraX >= 0 then
|
||||
local oam = memory2.OAM:readregion(0x00, 0x220)
|
||||
|
||||
for idx=0,0x200/4-1,1 do
|
||||
|
|
12
util.lua
12
util.lua
|
@ -275,6 +275,18 @@ function _M.regionToWord(region, offset)
|
|||
return bit.compose(region[offset], region[offset + 1])
|
||||
end
|
||||
|
||||
function _M.regionToSWord(region, offset)
|
||||
local unsigned = _M.regionToWord(region, offset)
|
||||
local base = bit.band(unsigned, 0x7fff)
|
||||
local sign = bit.lrshift(unsigned, 15)
|
||||
-- There is a more mathematical way to do this but whatever
|
||||
if sign == 1 then
|
||||
return base-0x8000
|
||||
else
|
||||
return base
|
||||
end
|
||||
end
|
||||
|
||||
return function(promise)
|
||||
Promise = promise
|
||||
return _M
|
||||
|
|
Loading…
Add table
Reference in a new issue