mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-17 11:11:10 +02:00
Bugs and stuff (#146)
* main menu scrollable when over 8 items * buggies * more buggies * Lorelei, Bruno, and Agatha now push their AfterBattle text right after a win * more and more bugs
This commit is contained in:
@@ -2431,6 +2431,27 @@ function OverworldState:runVictoryHook()
|
||||
if hooks and hooks.onVictory then hooks.onVictory(Game, self) end
|
||||
end
|
||||
|
||||
-- pokered player sprite is fixed at screen ($40, $3c). TrainerEngage reads
|
||||
-- the NPC's 8-bit SPRITESTATEDATA1 X/Y pixels and CalcDifference; engage
|
||||
-- distance is stored as range<<4 (pixels). There is no tile LOS check for
|
||||
-- interposed NPCs / walls -- but unsigned 8-bit Y makes a sprite exactly 4
|
||||
-- tiles north of the player sit at Y=$fc, so |$3c-$fc|=$c0 and a range-4
|
||||
-- DOWN trainer does not engage that tile (Route 9 Bug Catcher / issue #76).
|
||||
local PLAYER_SCREEN_X, PLAYER_SCREEN_Y = 0x40, 0x3c
|
||||
local function u8(n) return n % 256 end
|
||||
local function calcDiff(a, b)
|
||||
a, b = u8(a), u8(b)
|
||||
return a >= b and a - b or b - a
|
||||
end
|
||||
local function trainerSightPixelDist(npc, player, horizontal)
|
||||
if horizontal then
|
||||
return calcDiff(PLAYER_SCREEN_X,
|
||||
u8(PLAYER_SCREEN_X + (npc.cellX - player.cellX) * 16))
|
||||
end
|
||||
return calcDiff(PLAYER_SCREEN_Y,
|
||||
u8(PLAYER_SCREEN_Y + (npc.cellY - player.cellY) * 16))
|
||||
end
|
||||
|
||||
-- STAY trainers with a facing spot the player crossing their line of
|
||||
-- sight (range from the extracted trainer headers), walk up and battle.
|
||||
function OverworldState:checkTrainerSight()
|
||||
@@ -2448,22 +2469,23 @@ function OverworldState:checkTrainerSight()
|
||||
local range = header and header.range or 0
|
||||
local vec = DIRVEC[npc.facing]
|
||||
if range > 0 and vec then
|
||||
local dist
|
||||
local dist, horizontal
|
||||
if vec[1] ~= 0 and npc.cellY == p.cellY then
|
||||
dist = (p.cellX - npc.cellX) * vec[1]
|
||||
horizontal = true
|
||||
elseif vec[2] ~= 0 and npc.cellX == p.cellX then
|
||||
dist = (p.cellY - npc.cellY) * vec[2]
|
||||
horizontal = false
|
||||
end
|
||||
-- pokered's TrainerEngage / CheckSpriteCanSeePlayer compares screen
|
||||
-- coordinates only (home/trainers.asm, engine/overworld/
|
||||
-- trainer_sight.asm) -- there is no line-of-sight obstruction check.
|
||||
-- An aligned trainer within range engages through interposed NPCs and
|
||||
-- unwalkable tiles, and the scripted walk-up below (scriptMove) also
|
||||
-- ignores collision, so the trainer simply walks/overlaps through
|
||||
-- anything on the line -- exactly as OAM sprites overlap on hardware.
|
||||
if dist and dist >= 1 and dist <= range then
|
||||
self:startTrainerApproach(npc, dist)
|
||||
return
|
||||
-- Screen-pixel range (CheckSpriteCanSeePlayer), not cell count:
|
||||
-- same facing-line rule as before, but the $fc Y quirk excludes the
|
||||
-- 4-tiles-north tile that cell math would still count as in range.
|
||||
if dist and dist >= 1 then
|
||||
local pixelDist = trainerSightPixelDist(npc, p, horizontal)
|
||||
if pixelDist > 0 and pixelDist <= range * 16 then
|
||||
self:startTrainerApproach(npc, dist)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -3492,7 +3514,9 @@ function OverworldState:billboard(fx, fy, vw, vh, colors, keyed, drawFn)
|
||||
end
|
||||
|
||||
function OverworldState:drawWorld()
|
||||
-- advance the water/flower tile animation (runs under dialogs too)
|
||||
-- advance the water/flower tile animation (runs under dialogs too).
|
||||
-- TileRenderer.tick uses wall-clock 60Hz steps so display refresh rate
|
||||
-- does not speed or slow the cycle (issue #4).
|
||||
require("src.render.TileRenderer").tick()
|
||||
-- let the renderer know whether a spinner puzzle is currently sliding
|
||||
-- the player, so it can flicker the arrow tiles between the blur and
|
||||
|
||||
+20
-4
@@ -81,6 +81,14 @@ end
|
||||
|
||||
-- Advance one fixed step; returns true when a step just completed.
|
||||
function Player:update()
|
||||
-- land-frame walk pose lasts only through the draw after completion;
|
||||
-- the next update (idle or a chained step) clears it
|
||||
self.stepLanded = false
|
||||
-- Ledge-hop arc is cosmetic but must track the fixed 60Hz logic step,
|
||||
-- not love.draw's display refresh (issue #4: >59fps ended early).
|
||||
if self.hopFrames and self.hopFrames > 0 then
|
||||
self.hopFrames = self.hopFrames - 1
|
||||
end
|
||||
if self.turnTimer > 0 then
|
||||
self.turnTimer = self.turnTimer - 1
|
||||
end
|
||||
@@ -109,6 +117,11 @@ function Player:update()
|
||||
self.px, self.py = self.cellX * 16, self.cellY * 16
|
||||
self.moving = false
|
||||
self.stepFlip = not self.stepFlip
|
||||
-- keep animClock's pose on this frame (issue #82): bike steps land
|
||||
-- mid-cycle (animClock % 16 == 8), and walkPhase used to snap to
|
||||
-- stand whenever moving cleared — a stand flash every tile on the
|
||||
-- bike, and sometimes after dismount when the clock is desynced
|
||||
self.stepLanded = true
|
||||
return true
|
||||
end
|
||||
return false
|
||||
@@ -119,7 +132,7 @@ function Player:facingCell()
|
||||
end
|
||||
|
||||
function Player:walkPhase()
|
||||
if not self.moving then return 0 end
|
||||
if not self.moving and not self.stepLanded then return 0 end
|
||||
-- walk frame during the middle of each 16-frame animation cycle
|
||||
local p = (self.animClock or self.progress) % 16
|
||||
return (p >= 4 and p < 12) and 1 or 0
|
||||
@@ -129,10 +142,13 @@ local SPIN_ORDER = { "down", "left", "up", "right" }
|
||||
|
||||
function Player:draw(camX, camY)
|
||||
local py = self.py
|
||||
-- ledge hops arc (set for 2 cells by the ledge handler); surfing bobs
|
||||
-- ledge hops arc (set for 2 cells by the ledge handler); surfing bobs.
|
||||
-- hopFrames counts down in Player:update (fixed step), never here.
|
||||
if self.hopFrames and self.hopFrames > 0 then
|
||||
self.hopFrames = self.hopFrames - 1
|
||||
local t = 1 - self.hopFrames / (self.hopTotal or 32)
|
||||
local total = self.hopTotal or 32
|
||||
-- update runs before draw, so remaining N means N steps already
|
||||
-- consumed this hop → t matches the old draw-side post-decrement phase
|
||||
local t = 1 - self.hopFrames / total
|
||||
py = py - math.floor(10 * math.sin(t * math.pi) + 0.5)
|
||||
-- the shadow stays on the ground under the jumper: one 8x8 tile
|
||||
-- mirrored into a 2x2 block (normal/XFLIP/YFLIP/both) whose top-left
|
||||
|
||||
Reference in New Issue
Block a user