From b11931085920d2afc41dd67ededa0e290a7a97cd Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Sat, 8 Feb 2025 20:25:30 -0500 Subject: [PATCH] Even further fielder logic extraction. Also remove some redundant ball-position mutation. --- src/field.lua | 29 +++++++++++++++++++---------- src/main.lua | 14 ++------------ 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/field.lua b/src/field.lua index d727b75..0c43df9 100644 --- a/src/field.lua +++ b/src/field.lua @@ -57,30 +57,39 @@ end ---@param fielder Fielder ---@param ballPos XYPair ----@return boolean isHoldingBall -local function updateFielder(deltaSeconds, fielder, ballPos) +---@return boolean isTouchingBall +local function updateFielderPosition(deltaSeconds, fielder, ballPos) if fielder.target ~= nil then if not utils.moveAtSpeed(fielder, fielder.speed * deltaSeconds, fielder.target) then fielder.target = nil end end - local isTouchingBall = utils.distanceBetweenPoints(fielder, ballPos) < C.BallCatchHitbox + return utils.distanceBetweenPoints(fielder, ballPos) < C.BallCatchHitbox +end - if not isTouchingBall then - return false +--- Selects the nearest fielder to move toward the given coordinates. +--- Other fielders should attempt to cover their bases +function Field.haveSomeoneChase(self, ballDestX, ballDestY) + local chasingFielder = utils.getNearestOf(self.fielders, ballDestX, ballDestY) + chasingFielder.target = { x = ballDestX, y = ballDestY } + + for _, base in ipairs(C.Bases) do + local nearest = utils.getNearestOf(self.fielders, base.x, base.y, function(fielder) + -- For now, skipping the pitcher because they're considered closer to 2B than second or shortstop + return fielder ~= chasingFielder and fielder ~= self.fielders.pitcher + end) + nearest.target = base end - - return true end ---@param ball XYPair ---@return Fielder | nil fielderTouchingBall nil if no fielder is currently touching the ball -function Field.updateFielders(self, ball, deltaSeconds) +function Field.updateFielderPositions(self, ball, deltaSeconds) local fielderTouchingBall for _, fielder in pairs(self.fielders) do - local isHoldingBall = updateFielder(deltaSeconds, fielder, ball) - if isHoldingBall then + local isTouchingBall = updateFielderPosition(deltaSeconds, fielder, ball) + if isTouchingBall then fielderTouchingBall = fielder end end diff --git a/src/main.lua b/src/main.lua index 2534147..bd3a0b5 100644 --- a/src/main.lua +++ b/src/main.lua @@ -418,7 +418,6 @@ end local function walk() announcer:say("Walk!") - Field.fielders.first.target = C.Bases[C.First] batter.nextBase = C.Bases[C.First] batter.prevBase = C.Bases[C.Home] offenseMode = C.Offense.walking @@ -436,11 +435,6 @@ end ---@param batDeg number local function updateBatting(batDeg, batSpeed) - if ball.y < C.BallOffscreen then - ball.y = ballAnimatorY:currentValue() + ballFloatAnimator:currentValue() - ball.size = C.SmallestBallRadius -- ballFloatAnimator:currentValue() - end - local batAngle = math.rad(batDeg) -- TODO: animate bat-flip or something batBase.x = batter and (batter.x + BatterHandPos.x) or 0 @@ -470,15 +464,13 @@ local function updateBatting(batDeg, batSpeed) local hitBallScaler = gfx.animator.new(2000, 9 + (mult * mult * 0.5), C.SmallestBallRadius, utils.easingHill) throwBall(ballDestX, ballDestY, playdate.easingFunctions.outQuint, 2000, nil, hitBallScaler) - Field.fielders.first.target = C.Bases[C.First] batter.nextBase = C.Bases[C.First] batter.prevBase = C.Bases[C.Home] updateForcedRunners() batter.forcedTo = C.Bases[C.First] batter = nil -- Demote batter to a mere runner - local chasingFielder = utils.getNearestOf(Field.fielders, ballDestX, ballDestY) - chasingFielder.target = { x = ballDestX, y = ballDestY } + Field:haveSomeoneChase(ballDestX, ballDestY) end end @@ -487,8 +479,6 @@ end ---@param appliedSpeed number ---@return boolean local function updateRunning(appliedSpeed, forcedOnly) - ball.size = ballSizeAnimator:currentValue() - local runnerMoved = false -- TODO: Filter for the runner closest to the currently-held direction button @@ -622,7 +612,7 @@ local function updateGameState() end end - local fielderHoldingBall = Field:updateFielders(ball, deltaSeconds) + local fielderHoldingBall = Field:updateFielderPositions(ball, deltaSeconds) if fielderHoldingBall then local outedSomeRunner = outEligibleRunners(fielderHoldingBall)