Move more logic into field.lua
This commit is contained in:
parent
d85db79e52
commit
80c15161e3
|
@ -94,9 +94,9 @@ C.ThrowMeterDrainPerSec = 150
|
||||||
|
|
||||||
--- Controls how hard the ball can be hit, and
|
--- Controls how hard the ball can be hit, and
|
||||||
--- how fast the ball can be thrown.
|
--- how fast the ball can be thrown.
|
||||||
C.CrankPower = 10
|
C.CrankPower = 3
|
||||||
|
|
||||||
--- How fast baserunners move after a walk
|
--- How fast baserunners move after a walk
|
||||||
C.WalkedRunnerSpeed = 10
|
C.WalkedRunnerSpeed = 10
|
||||||
|
|
||||||
C.ResetFieldersAfterSeconds = 3
|
C.ResetFieldersAfterSeconds = 7
|
||||||
|
|
|
@ -54,3 +54,35 @@ function Field.resetFielderPositions(self, fromOffTheField)
|
||||||
self.fielders.center.target = utils.xy(C.Center.x, C.Screen.H * -0.4)
|
self.fielders.center.target = utils.xy(C.Center.x, C.Screen.H * -0.4)
|
||||||
self.fielders.right.target = utils.xy(C.Screen.W * 2, self.fielders.left.target.y)
|
self.fielders.right.target = utils.xy(C.Screen.W * 2, self.fielders.left.target.y)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param fielder Fielder
|
||||||
|
---@param ballPos XYPair
|
||||||
|
---@return boolean isHoldingBall
|
||||||
|
local function updateFielder(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
|
||||||
|
|
||||||
|
if not isTouchingBall then
|
||||||
|
return false
|
||||||
|
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)
|
||||||
|
local fielderTouchingBall
|
||||||
|
for _, fielder in pairs(self.fielders) do
|
||||||
|
local isHoldingBall = updateFielder(deltaSeconds, fielder, ball)
|
||||||
|
if isHoldingBall then
|
||||||
|
fielderTouchingBall = fielder
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return fielderTouchingBall
|
||||||
|
end
|
79
src/main.lua
79
src/main.lua
|
@ -85,7 +85,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
|
||||||
|
@ -206,25 +206,6 @@ local function pitch(pitchFlyTimeMs, pitchTypeIndex)
|
||||||
secondsSincePitchAllowed = 0
|
secondsSincePitchAllowed = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns the base being touched by the player at (x,y), or nil, if no base is being touched
|
|
||||||
---@param x number
|
|
||||||
---@param y number
|
|
||||||
---@return Base | nil
|
|
||||||
local function isTouchingBase(x, y)
|
|
||||||
return utils.first(C.Bases, function(base)
|
|
||||||
return utils.distanceBetween(x, y, base.x, base.y) < C.BaseHitbox
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Returns true only if the given point is touching the ball at its current position
|
|
||||||
---@param x number
|
|
||||||
---@param y number
|
|
||||||
---@return boolean, number
|
|
||||||
local function isTouchingBall(x, y)
|
|
||||||
local ballDistance = utils.distanceBetween(x, y, ball.x, ball.y)
|
|
||||||
return ballDistance < C.BallCatchHitbox, ballDistance
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param base Base
|
---@param base Base
|
||||||
---@return Runner | nil
|
---@return Runner | nil
|
||||||
local function getRunnerWithNextBase(base)
|
local function getRunnerWithNextBase(base)
|
||||||
|
@ -307,7 +288,7 @@ local function score(runnerIndex)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@return Base[]
|
---@return Base[]
|
||||||
local function getForcedOutTargets()
|
local function npcGetForcedOutTargets()
|
||||||
local targets = {}
|
local targets = {}
|
||||||
for _, base in ipairs(C.Bases) do
|
for _, base in ipairs(C.Bases) do
|
||||||
local runnerTargetingBase = getRunnerWithNextBase(base)
|
local runnerTargetingBase = getRunnerWithNextBase(base)
|
||||||
|
@ -339,9 +320,9 @@ end
|
||||||
|
|
||||||
--- Returns x,y of the out target
|
--- Returns x,y of the out target
|
||||||
---@return number|nil, number|nil
|
---@return number|nil, number|nil
|
||||||
local function getNextOutTarget()
|
local function npcGetNextOutTarget()
|
||||||
-- TODO: Handle missed throws, check for fielders at target, etc.
|
-- TODO: Handle missed throws, check for fielders at target, etc.
|
||||||
local targets = getForcedOutTargets()
|
local targets = npcGetForcedOutTargets()
|
||||||
if #targets ~= 0 then
|
if #targets ~= 0 then
|
||||||
return targets[#targets].x, targets[#targets].y
|
return targets[#targets].x, targets[#targets].y
|
||||||
end
|
end
|
||||||
|
@ -353,8 +334,8 @@ local function getNextOutTarget()
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param fielder Fielder
|
---@param fielder Fielder
|
||||||
local function tryToMakeAnOut(fielder)
|
local function npcTryToMakeAnOut(fielder)
|
||||||
local targetX, targetY = getNextOutTarget()
|
local targetX, targetY = npcGetNextOutTarget()
|
||||||
if targetX ~= nil and targetY ~= nil then
|
if targetX ~= nil and targetY ~= nil then
|
||||||
local nearestFielder = utils.getNearestOf(Field.fielders, targetX, targetY)
|
local nearestFielder = utils.getNearestOf(Field.fielders, targetX, targetY)
|
||||||
nearestFielder.target = utils.xy(targetX, targetY)
|
nearestFielder.target = utils.xy(targetX, targetY)
|
||||||
|
@ -403,10 +384,10 @@ local function buttonControlledThrow(thrower, throwFlyMs, forbidThrowHome)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function outEligibleRunners(fielder)
|
local function outEligibleRunners(fielder)
|
||||||
local touchedBase = isTouchingBase(fielder.x, fielder.y)
|
local touchedBase = utils.isTouchingBase(fielder.x, fielder.y)
|
||||||
local didOutRunner = false
|
local didOutRunner = false
|
||||||
for i, runner in pairs(runners) do
|
for i, runner in pairs(runners) do
|
||||||
local runnerOnBase = isTouchingBase(runner.x, runner.y)
|
local runnerOnBase = utils.isTouchingBase(runner.x, runner.y)
|
||||||
if -- Force out
|
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
|
||||||
|
@ -429,34 +410,10 @@ local function updateNpcFielder(fielder, outedSomeRunner)
|
||||||
end
|
end
|
||||||
if outedSomeRunner then
|
if outedSomeRunner then
|
||||||
playdate.timer.new(750, function()
|
playdate.timer.new(750, function()
|
||||||
tryToMakeAnOut(fielder)
|
npcTryToMakeAnOut(fielder)
|
||||||
end)
|
end)
|
||||||
else
|
else
|
||||||
tryToMakeAnOut(fielder)
|
npcTryToMakeAnOut(fielder)
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param fielder Fielder
|
|
||||||
local function updateFielder(fielder)
|
|
||||||
if fielder.target ~= nil then
|
|
||||||
if not utils.moveAtSpeed(fielder, fielder.speed * deltaSeconds, fielder.target) then
|
|
||||||
fielder.target = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not isTouchingBall(fielder.x, fielder.y) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local outedSomeRunner = outEligibleRunners(fielder)
|
|
||||||
|
|
||||||
if playerIsOn(C.Sides.defense) then
|
|
||||||
local throwFly = readThrow()
|
|
||||||
if throwFly then
|
|
||||||
buttonControlledThrow(Field.fielders.pitcher, throwFly)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
updateNpcFielder(fielder, outedSomeRunner)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -508,6 +465,7 @@ local function updateRunner(runner, runnerIndex, appliedSpeed)
|
||||||
local autoRun = (nearestBaseDistance > 40 or runner.forcedTo) and mult * autoRunSpeed
|
local autoRun = (nearestBaseDistance > 40 or runner.forcedTo) and mult * autoRunSpeed
|
||||||
or nearestBaseDistance < 5 and 0
|
or nearestBaseDistance < 5 and 0
|
||||||
or (nearestBase == runner.nextBase and autoRunSpeed or -1 * autoRunSpeed)
|
or (nearestBase == runner.nextBase and autoRunSpeed or -1 * autoRunSpeed)
|
||||||
|
|
||||||
mult = autoRun + (appliedSpeed / 20)
|
mult = autoRun + (appliedSpeed / 20)
|
||||||
runner.x = runner.x - (x * mult)
|
runner.x = runner.x - (x * mult)
|
||||||
runner.y = runner.y - (y * mult)
|
runner.y = runner.y - (y * mult)
|
||||||
|
@ -731,9 +689,20 @@ local function updateGameState()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, fielder in pairs(Field.fielders) do
|
local fielderHoldingBall = Field:updateFielders(ball, deltaSeconds)
|
||||||
updateFielder(fielder)
|
|
||||||
|
if fielderHoldingBall then
|
||||||
|
local outedSomeRunner = outEligibleRunners(fielderHoldingBall)
|
||||||
|
if playerOnDefense then
|
||||||
|
local throwFly = readThrow()
|
||||||
|
if throwFly then
|
||||||
|
buttonControlledThrow(Field.fielders.pitcher, throwFly)
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
updateNpcFielder(fielder, outedSomeRunner)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
walkAwayOutRunners()
|
walkAwayOutRunners()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ function npc.runningSpeed(runners)
|
||||||
if #runners == 0 then
|
if #runners == 0 then
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
local touchedBase = isTouchingBase(runners[1].x, runners[1].y)
|
local touchedBase = utils.isTouchingBase(runners[1].x, runners[1].y)
|
||||||
if not touchedBase or touchedBase == C.Bases[C.Home] then
|
if not touchedBase or touchedBase == C.Bases[C.Home] then
|
||||||
return 10
|
return 10
|
||||||
end
|
end
|
||||||
|
|
|
@ -102,6 +102,15 @@ function utils.distanceBetween(x1, y1, x2, y2)
|
||||||
return sqrt((x * x) + (y * y)), x, y
|
return sqrt((x * x) + (y * y)), x, y
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param point1 XYPair
|
||||||
|
---@param point2 XYPair
|
||||||
|
---@return number distance, number x, number y
|
||||||
|
function utils.distanceBetweenPoints(point1, point2)
|
||||||
|
local x = point1.x - point2.x
|
||||||
|
local y = point1.y - point2.y
|
||||||
|
return sqrt((x * x) + (y * y)), x, y
|
||||||
|
end
|
||||||
|
|
||||||
---@return number distance, number x, number y, number z
|
---@return number distance, number x, number y, number z
|
||||||
function utils.distanceBetweenZ(x1, y1, z1, x2, y2, z2)
|
function utils.distanceBetweenZ(x1, y1, z1, x2, y2, z2)
|
||||||
local x = x1 - x2
|
local x = x1 - x2
|
||||||
|
@ -123,6 +132,16 @@ function utils.newRunner(runners)
|
||||||
return new
|
return new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Returns the base being touched by the player at (x,y), or nil, if no base is being touched
|
||||||
|
---@param x number
|
||||||
|
---@param y number
|
||||||
|
---@return Base | nil
|
||||||
|
function utils.isTouchingBase(x, y)
|
||||||
|
return utils.first(C.Bases, function(base)
|
||||||
|
return utils.distanceBetween(x, y, base.x, base.y) < C.BaseHitbox
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
--- Returns true only if the point is below the given line, within the x bounds of said line, and above the bottomBound
|
--- Returns true only if the point is below the given line, within the x bounds of said line, and above the bottomBound
|
||||||
--- @return boolean
|
--- @return boolean
|
||||||
function utils.pointDirectlyUnderLine(pointX, pointY, lineX1, lineY1, lineX2, lineY2, bottomBound)
|
function utils.pointDirectlyUnderLine(pointX, pointY, lineX1, lineY1, lineX2, lineY2, bottomBound)
|
||||||
|
|
Loading…
Reference in New Issue