From 80c15161e3cae5f70496d253aafee089d794041d Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Sat, 8 Feb 2025 18:28:17 -0500 Subject: [PATCH] Move more logic into field.lua --- src/constants.lua | 4 +-- src/field.lua | 32 +++++++++++++++++++ src/main.lua | 79 ++++++++++++++--------------------------------- src/npc.lua | 2 +- src/utils.lua | 19 ++++++++++++ 5 files changed, 78 insertions(+), 58 deletions(-) diff --git a/src/constants.lua b/src/constants.lua index 3d1af86..7b257af 100644 --- a/src/constants.lua +++ b/src/constants.lua @@ -94,9 +94,9 @@ C.ThrowMeterDrainPerSec = 150 --- Controls how hard the ball can be hit, and --- how fast the ball can be thrown. -C.CrankPower = 10 +C.CrankPower = 3 --- How fast baserunners move after a walk C.WalkedRunnerSpeed = 10 -C.ResetFieldersAfterSeconds = 3 +C.ResetFieldersAfterSeconds = 7 diff --git a/src/field.lua b/src/field.lua index 0dae341..d727b75 100644 --- a/src/field.lua +++ b/src/field.lua @@ -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.right.target = utils.xy(C.Screen.W * 2, self.fielders.left.target.y) 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 \ No newline at end of file diff --git a/src/main.lua b/src/main.lua index d54c2bf..c43a73e 100644 --- a/src/main.lua +++ b/src/main.lua @@ -85,7 +85,7 @@ local teams = { }, } -local PlayerTeam = teams.away +local PlayerTeam = teams.home local battingTeam = teams.away local outs = 0 local inning = 1 @@ -206,25 +206,6 @@ local function pitch(pitchFlyTimeMs, pitchTypeIndex) secondsSincePitchAllowed = 0 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 ---@return Runner | nil local function getRunnerWithNextBase(base) @@ -307,7 +288,7 @@ local function score(runnerIndex) end ---@return Base[] -local function getForcedOutTargets() +local function npcGetForcedOutTargets() local targets = {} for _, base in ipairs(C.Bases) do local runnerTargetingBase = getRunnerWithNextBase(base) @@ -339,9 +320,9 @@ end --- Returns x,y of the out target ---@return number|nil, number|nil -local function getNextOutTarget() +local function npcGetNextOutTarget() -- TODO: Handle missed throws, check for fielders at target, etc. - local targets = getForcedOutTargets() + local targets = npcGetForcedOutTargets() if #targets ~= 0 then return targets[#targets].x, targets[#targets].y end @@ -353,8 +334,8 @@ local function getNextOutTarget() end ---@param fielder Fielder -local function tryToMakeAnOut(fielder) - local targetX, targetY = getNextOutTarget() +local function npcTryToMakeAnOut(fielder) + local targetX, targetY = npcGetNextOutTarget() if targetX ~= nil and targetY ~= nil then local nearestFielder = utils.getNearestOf(Field.fielders, targetX, targetY) nearestFielder.target = utils.xy(targetX, targetY) @@ -403,10 +384,10 @@ local function buttonControlledThrow(thrower, throwFlyMs, forbidThrowHome) end local function outEligibleRunners(fielder) - local touchedBase = isTouchingBase(fielder.x, fielder.y) + local touchedBase = utils.isTouchingBase(fielder.x, fielder.y) local didOutRunner = false 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 touchedBase and runner.prevBase -- Make sure the runner is not standing at home @@ -429,34 +410,10 @@ local function updateNpcFielder(fielder, outedSomeRunner) end if outedSomeRunner then playdate.timer.new(750, function() - tryToMakeAnOut(fielder) + npcTryToMakeAnOut(fielder) end) else - tryToMakeAnOut(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) + npcTryToMakeAnOut(fielder) end end @@ -508,6 +465,7 @@ local function updateRunner(runner, runnerIndex, appliedSpeed) local autoRun = (nearestBaseDistance > 40 or runner.forcedTo) and mult * autoRunSpeed or nearestBaseDistance < 5 and 0 or (nearestBase == runner.nextBase and autoRunSpeed or -1 * autoRunSpeed) + mult = autoRun + (appliedSpeed / 20) runner.x = runner.x - (x * mult) runner.y = runner.y - (y * mult) @@ -731,9 +689,20 @@ local function updateGameState() end end - for _, fielder in pairs(Field.fielders) do - updateFielder(fielder) + local fielderHoldingBall = Field:updateFielders(ball, deltaSeconds) + + if fielderHoldingBall then + local outedSomeRunner = outEligibleRunners(fielderHoldingBall) + if playerOnDefense then + local throwFly = readThrow() + if throwFly then + buttonControlledThrow(Field.fielders.pitcher, throwFly) + end + else + updateNpcFielder(fielder, outedSomeRunner) + end end + walkAwayOutRunners() end diff --git a/src/npc.lua b/src/npc.lua index de71bee..2f596e3 100644 --- a/src/npc.lua +++ b/src/npc.lua @@ -23,7 +23,7 @@ function npc.runningSpeed(runners) if #runners == 0 then return 0 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 return 10 end diff --git a/src/utils.lua b/src/utils.lua index 0a3304e..a438e00 100644 --- a/src/utils.lua +++ b/src/utils.lua @@ -102,6 +102,15 @@ function utils.distanceBetween(x1, y1, x2, y2) return sqrt((x * x) + (y * y)), x, y 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 function utils.distanceBetweenZ(x1, y1, z1, x2, y2, z2) local x = x1 - x2 @@ -123,6 +132,16 @@ function utils.newRunner(runners) return new 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 --- @return boolean function utils.pointDirectlyUnderLine(pointX, pointY, lineX1, lineY1, lineX2, lineY2, bottomBound)