Even further fielder logic extraction.

Also remove some redundant ball-position mutation.
This commit is contained in:
Sage Vaillancourt 2025-02-08 20:25:30 -05:00
parent 30f2eada72
commit b119310859
2 changed files with 21 additions and 22 deletions

View File

@ -57,30 +57,39 @@ end
---@param fielder Fielder ---@param fielder Fielder
---@param ballPos XYPair ---@param ballPos XYPair
---@return boolean isHoldingBall ---@return boolean isTouchingBall
local function updateFielder(deltaSeconds, fielder, ballPos) local function updateFielderPosition(deltaSeconds, fielder, ballPos)
if fielder.target ~= nil then if fielder.target ~= nil then
if not utils.moveAtSpeed(fielder, fielder.speed * deltaSeconds, fielder.target) then if not utils.moveAtSpeed(fielder, fielder.speed * deltaSeconds, fielder.target) then
fielder.target = nil fielder.target = nil
end end
end end
local isTouchingBall = utils.distanceBetweenPoints(fielder, ballPos) < C.BallCatchHitbox return utils.distanceBetweenPoints(fielder, ballPos) < C.BallCatchHitbox
end
if not isTouchingBall then --- Selects the nearest fielder to move toward the given coordinates.
return false --- 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 end
return true
end end
---@param ball XYPair ---@param ball XYPair
---@return Fielder | nil fielderTouchingBall nil if no fielder is currently touching the ball ---@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 local fielderTouchingBall
for _, fielder in pairs(self.fielders) do for _, fielder in pairs(self.fielders) do
local isHoldingBall = updateFielder(deltaSeconds, fielder, ball) local isTouchingBall = updateFielderPosition(deltaSeconds, fielder, ball)
if isHoldingBall then if isTouchingBall then
fielderTouchingBall = fielder fielderTouchingBall = fielder
end end
end end

View File

@ -418,7 +418,6 @@ end
local function walk() local function walk()
announcer:say("Walk!") announcer:say("Walk!")
Field.fielders.first.target = C.Bases[C.First]
batter.nextBase = C.Bases[C.First] batter.nextBase = C.Bases[C.First]
batter.prevBase = C.Bases[C.Home] batter.prevBase = C.Bases[C.Home]
offenseMode = C.Offense.walking offenseMode = C.Offense.walking
@ -436,11 +435,6 @@ end
---@param batDeg number ---@param batDeg number
local function updateBatting(batDeg, batSpeed) 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) local batAngle = math.rad(batDeg)
-- TODO: animate bat-flip or something -- TODO: animate bat-flip or something
batBase.x = batter and (batter.x + BatterHandPos.x) or 0 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) local hitBallScaler = gfx.animator.new(2000, 9 + (mult * mult * 0.5), C.SmallestBallRadius, utils.easingHill)
throwBall(ballDestX, ballDestY, playdate.easingFunctions.outQuint, 2000, nil, hitBallScaler) throwBall(ballDestX, ballDestY, playdate.easingFunctions.outQuint, 2000, nil, hitBallScaler)
Field.fielders.first.target = C.Bases[C.First]
batter.nextBase = C.Bases[C.First] batter.nextBase = C.Bases[C.First]
batter.prevBase = C.Bases[C.Home] batter.prevBase = C.Bases[C.Home]
updateForcedRunners() updateForcedRunners()
batter.forcedTo = C.Bases[C.First] batter.forcedTo = C.Bases[C.First]
batter = nil -- Demote batter to a mere runner batter = nil -- Demote batter to a mere runner
local chasingFielder = utils.getNearestOf(Field.fielders, ballDestX, ballDestY) Field:haveSomeoneChase(ballDestX, ballDestY)
chasingFielder.target = { x = ballDestX, y = ballDestY }
end end
end end
@ -487,8 +479,6 @@ end
---@param appliedSpeed number ---@param appliedSpeed number
---@return boolean ---@return boolean
local function updateRunning(appliedSpeed, forcedOnly) local function updateRunning(appliedSpeed, forcedOnly)
ball.size = ballSizeAnimator:currentValue()
local runnerMoved = false local runnerMoved = false
-- TODO: Filter for the runner closest to the currently-held direction button -- TODO: Filter for the runner closest to the currently-held direction button
@ -622,7 +612,7 @@ local function updateGameState()
end end
end end
local fielderHoldingBall = Field:updateFielders(ball, deltaSeconds) local fielderHoldingBall = Field:updateFielderPositions(ball, deltaSeconds)
if fielderHoldingBall then if fielderHoldingBall then
local outedSomeRunner = outEligibleRunners(fielderHoldingBall) local outedSomeRunner = outEligibleRunners(fielderHoldingBall)