Remove Fielder.onArrive() callback
Instead, just try to throw for an out when touching the ball. This also tentatively moves toward implementing cutoff throws. Re-org to define tryToThrowOut() before it is referenced.
This commit is contained in:
parent
1d55c27fa2
commit
44ba30ee97
158
src/main.lua
158
src/main.lua
|
@ -26,7 +26,6 @@ import 'CoreLibs/ui.lua'
|
||||||
--- }
|
--- }
|
||||||
|
|
||||||
--- @alias Fielder {
|
--- @alias Fielder {
|
||||||
--- onArrive: fun() | nil,
|
|
||||||
--- x: number | nil,
|
--- x: number | nil,
|
||||||
--- y: number | nil,
|
--- y: number | nil,
|
||||||
--- target: XYPair | nil,
|
--- target: XYPair | nil,
|
||||||
|
@ -162,23 +161,24 @@ local NextBaseMap <const> = {
|
||||||
[Bases[Third]] = Bases[Home],
|
[Bases[Third]] = Bases[Home],
|
||||||
}
|
}
|
||||||
|
|
||||||
function newFielder(speed)
|
function newFielder(name, speed)
|
||||||
return {
|
return {
|
||||||
|
name = name,
|
||||||
speed = speed,
|
speed = speed,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
---@type table<string, Fielder>
|
---@type table<string, Fielder>
|
||||||
local fielders <const> = {
|
local fielders <const> = {
|
||||||
first = newFielder(40),
|
first = newFielder("First", 40),
|
||||||
second = newFielder(40),
|
second = newFielder("Second", 40),
|
||||||
shortstop = newFielder(40),
|
shortstop = newFielder("Shortstop", 40),
|
||||||
third = newFielder(40),
|
third = newFielder("Third", 40),
|
||||||
pitcher = newFielder(30),
|
pitcher = newFielder("Pitcher", 30),
|
||||||
catcher = newFielder(20),
|
catcher = newFielder("Catcher", 20),
|
||||||
left = newFielder(40),
|
left = newFielder("Left", 40),
|
||||||
center = newFielder(40),
|
center = newFielder("Center", 40),
|
||||||
right = newFielder(40),
|
right = newFielder("Right", 40),
|
||||||
}
|
}
|
||||||
|
|
||||||
local PitcherStartPos <const> = {
|
local PitcherStartPos <const> = {
|
||||||
|
@ -380,6 +380,64 @@ function score(runnerIndex)
|
||||||
announcer:say("SCORE!")
|
announcer:say("SCORE!")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@return Base[]
|
||||||
|
function getForcedOutTargets()
|
||||||
|
local targets = {}
|
||||||
|
for _, base in ipairs(Bases) do
|
||||||
|
local runnerTargetingBase = getRunnerTargeting(base)
|
||||||
|
if runnerTargetingBase then
|
||||||
|
targets[#targets + 1] = base
|
||||||
|
else
|
||||||
|
return targets
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return targets
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns the position,distance of the basest closest to the runner furthest from a base
|
||||||
|
---@return Base | nil, number | nil
|
||||||
|
function getBaseOfStrandedRunner()
|
||||||
|
local farRunnersBase, farDistance
|
||||||
|
for _, runner in pairs(runners) do
|
||||||
|
local nearestBase, distance = getNearestOf(Bases, runner.x, runner.y, function(base)
|
||||||
|
return runner.nextBase == base
|
||||||
|
end)
|
||||||
|
if farRunnersBase == nil or farDistance < distance then
|
||||||
|
farRunnersBase = nearestBase
|
||||||
|
farDistance = distance
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return farRunnersBase, farDistance
|
||||||
|
end
|
||||||
|
--- Returns x,y of the throw target
|
||||||
|
---@return number|nil, number|nil
|
||||||
|
function getNextThrowTarget()
|
||||||
|
-- TODO: Handle missed throws, check for fielders at target, etc.
|
||||||
|
local targets = getForcedOutTargets()
|
||||||
|
if #targets ~= 0 then
|
||||||
|
return targets[#targets].x, targets[#targets].y
|
||||||
|
end
|
||||||
|
|
||||||
|
local baseCloseToStrandedRunner = getBaseOfStrandedRunner()
|
||||||
|
if baseCloseToStrandedRunner then
|
||||||
|
return baseCloseToStrandedRunner.x, baseCloseToStrandedRunner.y
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function tryToThrowOut(thrower)
|
||||||
|
local targetX, targetY = getNextThrowTarget()
|
||||||
|
if targetX ~= nil and targetY ~= nil then
|
||||||
|
local nearestFielder = getNearestOf(fielders, targetX, targetY)
|
||||||
|
nearestFielder.target = xy(targetX, targetY)
|
||||||
|
if nearestFielder == thrower then
|
||||||
|
ball.heldBy = thrower
|
||||||
|
else
|
||||||
|
throwBall(targetX, targetY, playdate.easingFunctions.linear, nil, true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function updateFielders()
|
function updateFielders()
|
||||||
local touchingBaseCache = buildCache(function(runner)
|
local touchingBaseCache = buildCache(function(runner)
|
||||||
return isTouchingBase(runner.x, runner.y)
|
return isTouchingBase(runner.x, runner.y)
|
||||||
|
@ -388,6 +446,7 @@ function updateFielders()
|
||||||
for _, fielder in pairs(fielders) do
|
for _, fielder in pairs(fielders) do
|
||||||
-- TODO: Target unforced runners (or their target bases) for tagging
|
-- TODO: Target unforced runners (or their target bases) for tagging
|
||||||
-- With new Position-based scheme, fielders are now able to set `fielder.target = runner` to track directly
|
-- With new Position-based scheme, fielders are now able to set `fielder.target = runner` to track directly
|
||||||
|
|
||||||
if fielder.target ~= nil then
|
if fielder.target ~= nil then
|
||||||
local x, y, distance = normalizeVector(fielder.x, fielder.y, fielder.target.x, fielder.target.y)
|
local x, y, distance = normalizeVector(fielder.x, fielder.y, fielder.target.x, fielder.target.y)
|
||||||
|
|
||||||
|
@ -396,9 +455,6 @@ function updateFielders()
|
||||||
fielder.y = fielder.y - (y * fielder.speed * deltaSeconds)
|
fielder.y = fielder.y - (y * fielder.speed * deltaSeconds)
|
||||||
else
|
else
|
||||||
fielder.target = nil
|
fielder.target = nil
|
||||||
if fielder.onArrive then
|
|
||||||
fielder:onArrive()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -407,22 +463,23 @@ function updateFielders()
|
||||||
local touchedBase = isTouchingBase(fielder.x, fielder.y)
|
local touchedBase = isTouchingBase(fielder.x, fielder.y)
|
||||||
for i, runner in pairs(runners) do
|
for i, runner in pairs(runners) do
|
||||||
if
|
if
|
||||||
|
( -- Force out
|
||||||
touchedBase
|
touchedBase
|
||||||
and runner.prevBase -- Make sure the runner is not standing at home
|
and runner.prevBase -- Make sure the runner is not standing at home
|
||||||
and runner.forcedTo == touchedBase
|
and runner.forcedTo == touchedBase
|
||||||
and touchedBase ~= touchingBaseCache.get(runner)
|
and touchedBase ~= touchingBaseCache.get(runner)
|
||||||
|
)
|
||||||
|
or ( -- Tag out
|
||||||
|
not touchingBaseCache.get(runner)
|
||||||
|
and distanceBetween(runner.x, runner.y, fielder.x, fielder.y) < TagDistance
|
||||||
|
)
|
||||||
then
|
then
|
||||||
outRunner(i)
|
outRunner(i)
|
||||||
playdate.timer.new(750, function()
|
playdate.timer.new(750, function()
|
||||||
tryToThrowOut(fielder)
|
tryToThrowOut(fielder)
|
||||||
end)
|
end)
|
||||||
elseif not touchingBaseCache.get(runner) then
|
else
|
||||||
if distanceBetween(runner.x, runner.y, fielder.x, fielder.y) < TagDistance then
|
|
||||||
outRunner(i)
|
|
||||||
playdate.timer.new(750, function()
|
|
||||||
tryToThrowOut(fielder)
|
tryToThrowOut(fielder)
|
||||||
end)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -485,52 +542,6 @@ function updateRunners(currentRunners)
|
||||||
return runnerMoved
|
return runnerMoved
|
||||||
end
|
end
|
||||||
|
|
||||||
---@return Base[]
|
|
||||||
function getForcedOutTargets()
|
|
||||||
local targets = {}
|
|
||||||
for _, base in ipairs(Bases) do
|
|
||||||
local runnerTargetingBase = getRunnerTargeting(base)
|
|
||||||
if runnerTargetingBase then
|
|
||||||
targets[#targets + 1] = base
|
|
||||||
else
|
|
||||||
return targets
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return targets
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Returns the position,distance of the basest closest to the runner furthest from a base
|
|
||||||
---@return Base | nil, number | nil
|
|
||||||
function getBaseOfStrandedRunner()
|
|
||||||
local farRunnersBase, farDistance
|
|
||||||
for _, runner in pairs(runners) do
|
|
||||||
local nearestBase, distance = getNearestOf(Bases, runner.x, runner.y, function(base)
|
|
||||||
return runner.nextBase == base
|
|
||||||
end)
|
|
||||||
if farRunnersBase == nil or farDistance < distance then
|
|
||||||
farRunnersBase = nearestBase
|
|
||||||
farDistance = distance
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return farRunnersBase, farDistance
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Returns x,y of the throw target
|
|
||||||
---@return number|nil, number|nil
|
|
||||||
function getNextThrowTarget()
|
|
||||||
-- TODO: Handle missed throws, check for fielders at target, etc.
|
|
||||||
local targets = getForcedOutTargets()
|
|
||||||
if #targets ~= 0 then
|
|
||||||
return targets[#targets].x, targets[#targets].y
|
|
||||||
end
|
|
||||||
|
|
||||||
local baseCloseToStrandedRunner = getBaseOfStrandedRunner()
|
|
||||||
if baseCloseToStrandedRunner then
|
|
||||||
return baseCloseToStrandedRunner.x, baseCloseToStrandedRunner.y
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local ResetFieldersAfterSeconds = 2
|
local ResetFieldersAfterSeconds = 2
|
||||||
-- TODO: Replace with a timer, repeatedly reset instead of setting to 0
|
-- TODO: Replace with a timer, repeatedly reset instead of setting to 0
|
||||||
local secondsSinceLastRunnerMove = 0
|
local secondsSinceLastRunnerMove = 0
|
||||||
|
@ -551,20 +562,6 @@ function init()
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
function tryToThrowOut(self)
|
|
||||||
self.onArrive = nil
|
|
||||||
local targetX, targetY = getNextThrowTarget()
|
|
||||||
if targetX ~= nil and targetY ~= nil then
|
|
||||||
local nearestFielder = getNearestOf(fielders, targetX, targetY)
|
|
||||||
nearestFielder.target = xy(targetX, targetY)
|
|
||||||
if nearestFielder == self then
|
|
||||||
ball.heldBy = self
|
|
||||||
else
|
|
||||||
throwBall(targetX, targetY, playdate.easingFunctions.linear, nil, true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local batAngleDeg
|
local batAngleDeg
|
||||||
|
|
||||||
function updateBatting()
|
function updateBatting()
|
||||||
|
@ -617,7 +614,6 @@ function updateBatting()
|
||||||
|
|
||||||
local chasingFielder = getNearestOf(fielders, ballDestX, ballDestY)
|
local chasingFielder = getNearestOf(fielders, ballDestX, ballDestY)
|
||||||
chasingFielder.target = { x = ballDestX, y = ballDestY }
|
chasingFielder.target = { x = ballDestX, y = ballDestY }
|
||||||
chasingFielder.onArrive = tryToThrowOut
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue