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
|
GENERATED_FILES := src/assets.lua
|
||||||
|
|
||||||
all:
|
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),
|
center = newFielder("C.Center", 40),
|
||||||
right = newFielder("Right", 40),
|
right = newFielder("Right", 40),
|
||||||
},
|
},
|
||||||
|
---@type Fielder | nil
|
||||||
|
fielderTouchingBall = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Actually only benches the infield, because outfielders are far away!
|
--- Actually only benches the infield, because outfielders are far away!
|
||||||
|
@ -86,12 +88,34 @@ 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.updateFielderPositions(self, ball, deltaSeconds)
|
function Field.updateFielderPositions(self, ball, deltaSeconds)
|
||||||
local fielderTouchingBall
|
local fielderTouchingBallLocal = nil
|
||||||
for _, fielder in pairs(self.fielders) do
|
for _, fielder in pairs(self.fielders) do
|
||||||
local isTouchingBall = updateFielderPosition(deltaSeconds, fielder, ball)
|
local isTouchingBall = updateFielderPosition(deltaSeconds, fielder, ball)
|
||||||
if isTouchingBall then
|
if isTouchingBall then
|
||||||
fielderTouchingBall = fielder
|
fielderTouchingBallLocal = fielder
|
||||||
end
|
end
|
||||||
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
|
end
|
28
src/main.lua
28
src/main.lua
|
@ -28,6 +28,7 @@ import 'utils.lua'
|
||||||
import 'constants.lua'
|
import 'constants.lua'
|
||||||
import 'assets.lua'
|
import 'assets.lua'
|
||||||
|
|
||||||
|
import 'action-queue.lua'
|
||||||
import 'announcer.lua'
|
import 'announcer.lua'
|
||||||
import 'dbg.lua'
|
import 'dbg.lua'
|
||||||
import 'field.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 battingTeam = teams.away
|
||||||
local outs = 0
|
local outs = 0
|
||||||
local inning = 1
|
local inning = 1
|
||||||
|
@ -286,10 +287,9 @@ local function readThrow()
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param thrower Fielder
|
|
||||||
---@param throwFlyMs number
|
---@param throwFlyMs number
|
||||||
---@return boolean didThrow
|
---@return boolean didThrow
|
||||||
local function buttonControlledThrow(thrower, throwFlyMs, forbidThrowHome)
|
local function buttonControlledThrow(throwFlyMs, forbidThrowHome)
|
||||||
local targetBase
|
local targetBase
|
||||||
if playdate.buttonIsPressed(playdate.kButtonLeft) then
|
if playdate.buttonIsPressed(playdate.kButtonLeft) then
|
||||||
targetBase = C.Bases[C.Third]
|
targetBase = C.Bases[C.Third]
|
||||||
|
@ -303,12 +303,10 @@ local function buttonControlledThrow(thrower, throwFlyMs, forbidThrowHome)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
local closestFielder = utils.getNearestOf(Field.fielders, targetBase.x, targetBase.y, function(fielder)
|
-- Power for this throw has already been determined
|
||||||
return fielder ~= thrower
|
throwMeter = 0
|
||||||
end)
|
|
||||||
|
|
||||||
throwBall(targetBase.x, targetBase.y, playdate.easingFunctions.linear, throwFlyMs)
|
Field:playerThrowTo(targetBase, throwBall, throwFlyMs)
|
||||||
closestFielder.target = targetBase
|
|
||||||
secondsSinceLastRunnerMove = 0
|
secondsSinceLastRunnerMove = 0
|
||||||
offenseMode = C.Offense.running
|
offenseMode = C.Offense.running
|
||||||
|
|
||||||
|
@ -583,7 +581,7 @@ local function updateGameState()
|
||||||
if secondsSincePitchAllowed > C.PitchAfterSeconds then
|
if secondsSincePitchAllowed > C.PitchAfterSeconds then
|
||||||
if playerOnDefense then
|
if playerOnDefense then
|
||||||
local throwFly = readThrow()
|
local throwFly = readThrow()
|
||||||
if throwFly and not buttonControlledThrow(pitcher, throwFly, true) then
|
if throwFly and not buttonControlledThrow(throwFly, true) then
|
||||||
playerPitch(throwFly)
|
playerPitch(throwFly)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
@ -614,19 +612,21 @@ local function updateGameState()
|
||||||
|
|
||||||
local fielderHoldingBall = Field:updateFielderPositions(ball, deltaSeconds)
|
local fielderHoldingBall = Field:updateFielderPositions(ball, deltaSeconds)
|
||||||
|
|
||||||
if fielderHoldingBall then
|
|
||||||
local outedSomeRunner = outEligibleRunners(fielderHoldingBall)
|
|
||||||
if playerOnDefense then
|
if playerOnDefense then
|
||||||
local throwFly = readThrow()
|
local throwFly = readThrow()
|
||||||
if throwFly then
|
if throwFly then
|
||||||
buttonControlledThrow(Field.fielders.pitcher, throwFly)
|
buttonControlledThrow(throwFly)
|
||||||
end
|
end
|
||||||
else
|
end
|
||||||
npcFielderAction(fielder, outedSomeRunner)
|
if fielderHoldingBall then
|
||||||
|
local outedSomeRunner = outEligibleRunners(fielderHoldingBall)
|
||||||
|
if playerOnOffense then
|
||||||
|
npcFielderAction(fielderHoldingBall, outedSomeRunner)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
walkAwayOutRunners()
|
walkAwayOutRunners()
|
||||||
|
actionQueue:runWaiting(deltaSeconds)
|
||||||
end
|
end
|
||||||
|
|
||||||
function playdate.update()
|
function playdate.update()
|
||||||
|
|
|
@ -44,18 +44,18 @@ local function getForcedOutTargets(runners)
|
||||||
return targets
|
return targets
|
||||||
end
|
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
|
---@return Base | nil, number | nil
|
||||||
local function getBaseOfStrandedRunner(runners)
|
local function getBaseOfStrandedRunner(runners)
|
||||||
local farRunnersBase, farDistance
|
local farRunnersBase, farDistance
|
||||||
for _, runner in pairs(runners) do
|
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)
|
local nearestBase, distance = utils.getNearestOf(C.Bases, runner.x, runner.y)
|
||||||
if farRunnersBase == nil or farDistance < distance then
|
if farRunnersBase == nil or farDistance < distance then
|
||||||
farRunnersBase = nearestBase
|
farRunnersBase = nearestBase
|
||||||
farDistance = distance
|
farDistance = distance
|
||||||
end
|
end
|
||||||
end
|
--end
|
||||||
end
|
end
|
||||||
|
|
||||||
return farRunnersBase, farDistance
|
return farRunnersBase, farDistance
|
||||||
|
|
Loading…
Reference in New Issue