---@class BatRenderState ---@field batBase XyPair ---@field batTip XyPair ---@field batAngleDeg number ---@field batSpeed number ---@class Batting ---@field private Baserunning ---@field state BatRenderState Is updated by checkForHit() Batting = {} local SwingBackDeg = 30 local SwingForwardDeg = 170 local OffscreenPos = utils.xy(-999, -999) ---@param baserunning Baserunning function Batting.new(baserunning) return setmetatable({ baserunning = baserunning, state = { batAngleDeg = 0, batSpeed = 0, batTip = OffscreenPos, batBase = OffscreenPos, }, }, { __index = Batting }) end -- TODO? Make the bat angle work more like the throw meter. -- Would instead constantly drift toward a default value, giving us a little more control, -- and letting the user find a crank position and direction that works for them --- Assumes the bat is being held by self.baserunning.batter --- Mutates self.state for later rendering. ---@param batDeg number ---@param batSpeed number ---@param ball Point3d ---@return XyPair | nil, boolean, number | nil Ball destination or nil if no hit, true only if batter swung, power mult function Batting:checkForHit(batDeg, batSpeed, ball) local batter = self.baserunning.batter local isSwinging = batDeg > SwingBackDeg and batDeg < SwingForwardDeg local batRadians = math.rad(batDeg) local base = batter and utils.xy(batter.x + C.BatterHandPos.x, batter.y + C.BatterHandPos.y) or OffscreenPos local tip = utils.xy(base.x + (C.BatLength * math.sin(batRadians)), base.y + (C.BatLength * math.cos(batRadians))) self.state.batSpeed = batSpeed self.state.batAngleDeg = batDeg self.state.batTip = tip self.state.batBase = base local ballWasHit = batSpeed > 0 and ball.y < 232 and utils.pointOnOrUnderLine(ball, base, tip, C.Screen.H) if not ballWasHit then return nil, isSwinging end local ballAngle = batRadians + math.rad(90) local mult = math.abs(batSpeed / 15) local ballVelX = mult * C.BattingPower * 10 * math.sin(ballAngle) local ballVelY = mult * C.BattingPower * 5 * math.cos(ballAngle) if ballVelY > 0 then ballVelX = ballVelX * -1 ballVelY = ballVelY * -1 end return utils.xy(ball.x + ballVelX, ball.y + ballVelY), isSwinging, mult end