Buffer player-controlled fielder throws.
Use new actionQueue to do so. Move thrower and receiver selection into fielder.lua Correct SOURCE_FILES listing in Makefile
This commit is contained in:
parent
b119310859
commit
82d1dac5de
2
Makefile
2
Makefile
|
@ -1,4 +1,4 @@
|
|||
SOURCE_FILES := $(shell grep "import '" src/main.lua | grep -v CoreLibs | sed "s/.*'\(.*\)'.*/\1/") main.lua
|
||||
SOURCE_FILES := $(shell grep "import '" src/main.lua | grep -v CoreLibs | sed "s/.*'\(.*\)'.*/src\/\1/") src/main.lua
|
||||
GENERATED_FILES := src/assets.lua
|
||||
|
||||
all:
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
---@alias ActionResult {}
|
||||
|
||||
---@type table<string, ActionResult>
|
||||
-- selene: allow(unscoped_variables)
|
||||
ActionResult = {
|
||||
Succeeded = {},
|
||||
Failed = {},
|
||||
NeedsMoreTime = {},
|
||||
}
|
||||
|
||||
-- selene: allow(unscoped_variables)
|
||||
actionQueue = {
|
||||
---@type ({ action: Action, expireTimeMs: number })[]
|
||||
queue = {},
|
||||
}
|
||||
|
||||
---@alias Action fun(deltaSeconds: number): ActionResult
|
||||
|
||||
--- Added actions will be called on every runWaiting() update.
|
||||
--- They will continue to be executed until they return Succeeded or Failed instead of NeedsMoreTime.
|
||||
--- Replaces any existing action with the given name.
|
||||
--- If the first call of action() doesn't return NeedsMoreTime, will skip adding to the queue.
|
||||
---@param name string
|
||||
---@param maxTimeMs number
|
||||
---@param action Action
|
||||
function actionQueue.upsert(self, name, maxTimeMs, action)
|
||||
if action(0) ~= ActionResult.NeedsMoreTime then
|
||||
return
|
||||
end
|
||||
|
||||
self.queue[name] = {
|
||||
action = action,
|
||||
expireTimeMs = maxTimeMs + playdate.getCurrentTimeMilliseconds(),
|
||||
}
|
||||
end
|
||||
|
||||
--- Must call on every playdate.update() to check for (and run) any waiting tasks.
|
||||
--- Actions that return NeedsMoreTime will not be removed from the queue unless they have expired.
|
||||
function actionQueue.runWaiting(self, deltaSeconds)
|
||||
local currentTimeMs = playdate.getCurrentTimeMilliseconds()
|
||||
for name, actionObject in pairs(self.queue) do
|
||||
local result = actionObject.action(deltaSeconds)
|
||||
if
|
||||
result ~= ActionResult.NeedsMoreTime
|
||||
or currentTimeMs > actionObject.expireTimeMs
|
||||
then
|
||||
self.queue[name] = nil
|
||||
end
|
||||
end
|
||||
end
|
|
@ -21,6 +21,8 @@ Field = {
|
|||
center = newFielder("C.Center", 40),
|
||||
right = newFielder("Right", 40),
|
||||
},
|
||||
---@type Fielder | nil
|
||||
fielderTouchingBall = nil,
|
||||
}
|
||||
|
||||
--- Actually only benches the infield, because outfielders are far away!
|
||||
|
@ -86,12 +88,34 @@ end
|
|||
---@param ball XYPair
|
||||
---@return Fielder | nil fielderTouchingBall nil if no fielder is currently touching the ball
|
||||
function Field.updateFielderPositions(self, ball, deltaSeconds)
|
||||
local fielderTouchingBall
|
||||
local fielderTouchingBallLocal = nil
|
||||
for _, fielder in pairs(self.fielders) do
|
||||
local isTouchingBall = updateFielderPosition(deltaSeconds, fielder, ball)
|
||||
if isTouchingBall then
|
||||
fielderTouchingBall = fielder
|
||||
fielderTouchingBallLocal = fielder
|
||||
end
|
||||
end
|
||||
return fielderTouchingBall
|
||||
self.fielderTouchingBall = fielderTouchingBallLocal
|
||||
return fielderTouchingBallLocal
|
||||
end
|
||||
|
||||
-- TODO? Start moving target fielders close sooner?
|
||||
local function playerThrowToImpl(field, targetBase, throwBall, throwFlyMs)
|
||||
if field.fielderTouchingBall == nil then
|
||||
return ActionResult.NeedsMoreTime
|
||||
end
|
||||
local closestFielder = utils.getNearestOf(field.fielders, targetBase.x, targetBase.y, function(fielder)
|
||||
return fielder ~= field.fielderTouchingBall -- presumably, this is who will be doing the throwing
|
||||
end)
|
||||
|
||||
closestFielder.target = targetBase
|
||||
throwBall(targetBase.x, targetBase.y, playdate.easingFunctions.linear, throwFlyMs)
|
||||
end
|
||||
|
||||
--- Buffer in a fielder throw action.
|
||||
function Field.playerThrowTo(self, targetBase, throwBall, throwFlyMs)
|
||||
local maxTryTimeMs = 5000
|
||||
actionQueue:upsert('playerThrowTo', maxTryTimeMs, function()
|
||||
return playerThrowToImpl(self, targetBase, throwBall, throwFlyMs)
|
||||
end)
|
||||
end
|
28
src/main.lua
28
src/main.lua
|
@ -28,6 +28,7 @@ import 'utils.lua'
|
|||
import 'constants.lua'
|
||||
import 'assets.lua'
|
||||
|
||||
import 'action-queue.lua'
|
||||
import 'announcer.lua'
|
||||
import 'dbg.lua'
|
||||
import 'field.lua'
|
||||
|
@ -85,7 +86,7 @@ local teams <const> = {
|
|||
},
|
||||
}
|
||||
|
||||
local PlayerTeam <const> = teams.away
|
||||
local PlayerTeam <const> = teams.home
|
||||
local battingTeam = teams.away
|
||||
local outs = 0
|
||||
local inning = 1
|
||||
|
@ -286,10 +287,9 @@ local function readThrow()
|
|||
return nil
|
||||
end
|
||||
|
||||
---@param thrower Fielder
|
||||
---@param throwFlyMs number
|
||||
---@return boolean didThrow
|
||||
local function buttonControlledThrow(thrower, throwFlyMs, forbidThrowHome)
|
||||
local function buttonControlledThrow(throwFlyMs, forbidThrowHome)
|
||||
local targetBase
|
||||
if playdate.buttonIsPressed(playdate.kButtonLeft) then
|
||||
targetBase = C.Bases[C.Third]
|
||||
|
@ -303,12 +303,10 @@ local function buttonControlledThrow(thrower, throwFlyMs, forbidThrowHome)
|
|||
return false
|
||||
end
|
||||
|
||||
local closestFielder = utils.getNearestOf(Field.fielders, targetBase.x, targetBase.y, function(fielder)
|
||||
return fielder ~= thrower
|
||||
end)
|
||||
-- Power for this throw has already been determined
|
||||
throwMeter = 0
|
||||
|
||||
throwBall(targetBase.x, targetBase.y, playdate.easingFunctions.linear, throwFlyMs)
|
||||
closestFielder.target = targetBase
|
||||
Field:playerThrowTo(targetBase, throwBall, throwFlyMs)
|
||||
secondsSinceLastRunnerMove = 0
|
||||
offenseMode = C.Offense.running
|
||||
|
||||
|
@ -583,7 +581,7 @@ local function updateGameState()
|
|||
if secondsSincePitchAllowed > C.PitchAfterSeconds then
|
||||
if playerOnDefense then
|
||||
local throwFly = readThrow()
|
||||
if throwFly and not buttonControlledThrow(pitcher, throwFly, true) then
|
||||
if throwFly and not buttonControlledThrow(throwFly, true) then
|
||||
playerPitch(throwFly)
|
||||
end
|
||||
else
|
||||
|
@ -614,19 +612,21 @@ local function updateGameState()
|
|||
|
||||
local fielderHoldingBall = Field:updateFielderPositions(ball, deltaSeconds)
|
||||
|
||||
if fielderHoldingBall then
|
||||
local outedSomeRunner = outEligibleRunners(fielderHoldingBall)
|
||||
if playerOnDefense then
|
||||
local throwFly = readThrow()
|
||||
if throwFly then
|
||||
buttonControlledThrow(Field.fielders.pitcher, throwFly)
|
||||
buttonControlledThrow(throwFly)
|
||||
end
|
||||
else
|
||||
npcFielderAction(fielder, outedSomeRunner)
|
||||
end
|
||||
if fielderHoldingBall then
|
||||
local outedSomeRunner = outEligibleRunners(fielderHoldingBall)
|
||||
if playerOnOffense then
|
||||
npcFielderAction(fielderHoldingBall, outedSomeRunner)
|
||||
end
|
||||
end
|
||||
|
||||
walkAwayOutRunners()
|
||||
actionQueue:runWaiting(deltaSeconds)
|
||||
end
|
||||
|
||||
function playdate.update()
|
||||
|
|
|
@ -44,18 +44,18 @@ local function getForcedOutTargets(runners)
|
|||
return targets
|
||||
end
|
||||
|
||||
--- Returns the position,distance of the basest closest to the runner furthest from a base
|
||||
--- Returns the position,distance of the base closest to the runner who is *furthest* from a base
|
||||
---@return Base | nil, number | nil
|
||||
local function getBaseOfStrandedRunner(runners)
|
||||
local farRunnersBase, farDistance
|
||||
for _, runner in pairs(runners) do
|
||||
if runner ~= batter then
|
||||
--if runner ~= batter then
|
||||
local nearestBase, distance = utils.getNearestOf(C.Bases, runner.x, runner.y)
|
||||
if farRunnersBase == nil or farDistance < distance then
|
||||
farRunnersBase = nearestBase
|
||||
farDistance = distance
|
||||
end
|
||||
end
|
||||
--end
|
||||
end
|
||||
|
||||
return farRunnersBase, farDistance
|
||||
|
|
Loading…
Reference in New Issue