Files
2025-09-29 00:52:08 +02:00

225 lines
8.0 KiB
Scheme
Executable File

USING "minigames_helpers.sch"
USING "minigame_UIInputs.sch"
USING "tennis_debug.sch"
ENUM TENNIS_BALL_SPIN
TBS_NO_SPIN = 0,
TBS_TOPSPIN,
TBS_SLICE
ENDENUM
ENUM TENNIS_NET_BOUNCE_ENUM
TNB_NO_BOUNCE = 0,
TNB_GROUND_BOUNCE, // bounce against the ground
TNB_NORMAL_BOUNCE, // bounce against net, nothing special
TNB_RICOCHET // crazy bounce off net, ricochets
ENDENUM
ENUM TENNIS_BALL_FLAGS_ENUM
TBF_UPDATE_PTFX = BIT0,
TBF_PAUSE_UPDATE = BIT1,
TBF_HIT_PLAYER = BIT2,
TBF_SOUND_ON_FOR_TUT = BIT3,
TBF_BOUNCED_IN_TIME_SLICE = BIT4, // used for more than just time slicing, speed increase causes collisions to miss occassionally
TBF_INCREASE_SIM_SPEED = BIT5,
TBF_SERVE_WAS_POWERFUL = BIT6,
TBF_NO_BOUNCE_TIMEOUT_OCCURED = BIT7,
TBF_RICOCHETED = BIT8
ENDENUM
FUNC STRING GET_STRING_FROM_TENNIS_BALL_FLAG(TENNIS_BALL_FLAGS_ENUM eFlag)
SWITCH eFlag
CASE TBF_UPDATE_PTFX RETURN "TBF_UPDATE_PTFX"
CASE TBF_PAUSE_UPDATE RETURN "TBF_PAUSE_UPDATE"
CASE TBF_HIT_PLAYER RETURN "TBF_HIT_PLAYER"
CASE TBF_SOUND_ON_FOR_TUT RETURN "TBF_SOUND_ON_FOR_TUT"
CASE TBF_BOUNCED_IN_TIME_SLICE RETURN "TBF_BOUNCED_IN_TIME_SLICE"
CASE TBF_INCREASE_SIM_SPEED RETURN "TBF_INCREASE_SIM_SPEED"
CASE TBF_SERVE_WAS_POWERFUL RETURN "TBF_SERVE_WAS_POWERFUL"
CASE TBF_NO_BOUNCE_TIMEOUT_OCCURED RETURN "TBF_NO_BOUNCE_TIMEOUT_OCCURED"
CASE TBF_RICOCHETED RETURN "TBF_RICOCHETED"
ENDSWITCH
RETURN "Unknown Ball Flag"
ENDFUNC
STRUCT TENNIS_BALL
OBJECT_INDEX oBall
INT iBounceCount // To track first bounce in / out / second bounce missed swing
INT iBallBounceFrameStamp = 0
INT iBallIntoPlayerFrameStamp
FLOAT fFlightTimer, fSpinTimer, fNoBounceTimeOut
VECTOR vBallPosHidden, vBallVel, vCollPos, vBallLaunchPos, vBallServeSafety
TENNIS_BALL_SPIN eBallSpin
PTFX_ID ptfxBallTrail
INT iBallFlags
// Time Slice Variables
FLOAT fTargetTime, fSimTime
VECTOR vNaught, vNext
FLOAT fPredTimeRemainder
ENDSTRUCT
FUNC STRING GET_STRING_FROM_TENNIS_BALL_SPIN(TENNIS_BALL_SPIN eSpin)
SWITCH eSpin
CASE TBS_NO_SPIN RETURN "TBS_NO_SPIN"
CASE TBS_TOPSPIN RETURN "TBS_TOPSPIN"
CASE TBS_SLICE RETURN "TBS_SLICE"
ENDSWITCH
RETURN "Unknown TENNIS_BALL_SPIN enum"
ENDFUNC
/// PURPOSE:
/// Accessor. Used to set a failsafe position to launch the ball from when receiving a serve event.
PROC SET_TENNIS_BALL_SERVE_SAFETY_POS(TENNIS_BALL & thisBall, VECTOR vSafetyPos)
CDEBUG2LN(DEBUG_TENNIS, "SET_TENNIS_BALL_SERVE_SAFETY_POS setting to ", vSafetyPos)
thisBall.vBallServeSafety = vSafetyPos
ENDPROC
/// PURPOSE:
/// Accessor. Gets the ball position stored from the serve event. Used only when a failsafe is encountered.
FUNC VECTOR GET_TENNIS_BALL_SERVE_SAFETY_POS(TENNIS_BALL & thisBall)
RETURN thisBall.vBallServeSafety
ENDFUNC
PROC SET_TENNIS_BALL_INTO_PLAYER_FRAME_STAMP(TENNIS_BALL &thisBall, INT iNewStamp)
CDEBUG2LN(DEBUG_TENNIS, "SET_TENNIS_BALL_INTO_PLAYER_FRAME_STAMP :: iNewStamp=", iNewStamp)
thisBall.iBallIntoPlayerFrameStamp = iNewStamp
ENDPROC
FUNC INT GET_TENNIS_BALL_INTO_PLAYER_FRAME_STAMP(TENNIS_BALL &thisBall)
RETURN thisBall.iBallIntoPlayerFrameStamp
ENDFUNC
PROC SET_TENNIS_BALL_BOUNCE_FRAME_STAMP(TENNIS_BALL &thisBall, INT iNewStamp)
CDEBUG2LN(DEBUG_TENNIS, "SET_TENNIS_BALL_BOUNCE_FRAME_STAMP :: iNewStamp=", iNewStamp)
thisBall.iBallBounceFrameStamp = iNewStamp
ENDPROC
PROC INCREASE_TENNIS_BALL_BOUNCE_TIMEOUT(TENNIS_BALL &thisBall)
thisBall.fNoBounceTimeOut += GET_FRAME_TIME()
ENDPROC
FUNC FLOAT GET_TENNIS_BALL_BOUNCE_TIMEOUT(TENNIS_BALL &thisBall)
RETURN thisBall.fNoBounceTimeOut
ENDFUNC
PROC RESET_TENNIS_BALL_BOUNCE_TIMEOUT(TENNIS_BALL &thisBall)
thisBall.fNoBounceTimeOut = 0
ENDPROC
FUNC VECTOR GET_TENNIS_BALL_POS(TENNIS_BALL &thisBall)
RETURN thisBall.vBallPosHidden
ENDFUNC
PROC SET_TENNIS_BALL_POS(TENNIS_BALL &thisBall, VECTOR vPos)
thisBall.vBallPosHidden = vPos
#IF TENNIS_DEBUG_RECORDING
#IF IS_DEBUG_BUILD
DEBUG_RECORD_ENTITY_VECTOR( GET_PLAYER_PED(GET_PLAYER_INDEX()), "SET_TENNIS_BALL_POS", vPos, TRUE)
#ENDIF
#ENDIF
ENDPROC
PROC SET_TENNIS_BALL_FLAG(TENNIS_BALL &thisBall, TENNIS_BALL_FLAGS_ENUM eFlag)
CPRINTLN(DEBUG_TENNIS, "SET_TENNIS_BALL_FLAG :: ", GET_STRING_FROM_TENNIS_BALL_FLAG(eFlag))
SET_BITMASK_AS_ENUM(thisBall.iBallFlags, eFlag)
ENDPROC
FUNC BOOL IS_TENNIS_BALL_FLAG_SET(TENNIS_BALL &thisBall, TENNIS_BALL_FLAGS_ENUM eFlag)
RETURN IS_BITMASK_AS_ENUM_SET(thisBall.iBallFlags, eFlag)
ENDFUNC
PROC CLEAR_TENNIS_BALL_FLAG(TENNIS_BALL &thisBall, TENNIS_BALL_FLAGS_ENUM eFlag)
CPRINTLN(DEBUG_TENNIS, "CLEAR_TENNIS_BALL_FLAG :: ", GET_STRING_FROM_TENNIS_BALL_FLAG(eFlag))
CLEAR_BITMASK_AS_ENUM(thisBall.iBallFlags, eFlag)
ENDPROC
PROC CLEAR_ALL_TENNIS_BALL_FLAGS(TENNIS_BALL &thisBall)
CDEBUG3LN(DEBUG_TENNIS, "CLEAR_ALL_TENNIS_BALL_FLAGS called")
thisBall.iBallFlags = 0
ENDPROC
FUNC BOOL DOES_TENNIS_BALL_TRAIL_EXIST(TENNIS_BALL &thisBall)
RETURN DOES_PARTICLE_FX_LOOPED_EXIST(thisBall.ptfxBallTrail)
ENDFUNC
PROC START_TENNIS_BALL_TRAIL(TENNIS_BALL &thisBall)
CPRINTLN(DEBUG_TENNIS, "START_TENNIS_BALL_TRAIL called")
SET_TENNIS_BALL_FLAG(thisBall, TBF_UPDATE_PTFX)
ENDPROC
PROC STOP_TENNIS_BALL_TRAIL(TENNIS_BALL &thisBall)
// CPRINTLN(DEBUG_TENNIS, "STOP_TENNIS_BALL_TRAIL called")
IF DOES_TENNIS_BALL_TRAIL_EXIST(thisBall)
STOP_PARTICLE_FX_LOOPED(thisBall.ptfxBallTrail, TRUE)
CPRINTLN(DEBUG_TENNIS, "STOP_PARTICLE_FX_LOOPED(thisBall.ptfxBallTrail) called on thisBall.PTFX=", NATIVE_TO_INT(thisBall.ptfxBallTrail))
CLEAR_TENNIS_BALL_FLAG(thisBall, TBF_UPDATE_PTFX)
ENDIF
ENDPROC
PROC UPDATE_TENNIS_BALL_TRAIL(TENNIS_BALL &thisBall, VECTOR vLoopedOffsets)
IF IS_TENNIS_BALL_FLAG_SET(thisBall, TBF_UPDATE_PTFX)
IF NOT DOES_TENNIS_BALL_TRAIL_EXIST(thisBall)
thisBall.ptfxBallTrail = START_PARTICLE_FX_LOOPED_AT_COORD("scr_tennis_ball_trail", vLoopedOffsets, (<<0,0,0>>), DEFAULT, DEFAULT, DEFAULT, DEFAULT, TRUE)
INT r, g, b, a
GET_HUD_COLOUR(HUD_COLOUR_YELLOW, r, g, b, a)
SET_PARTICLE_FX_LOOPED_COLOUR(thisBall.ptfxBallTrail, TO_FLOAT(r)/255.0, TO_FLOAT(g)/255.0, TO_FLOAT(b)/255.0)
a=a
CPRINTLN(DEBUG_TENNIS, "START_PARTICLE_FX_LOOPED_AT_COORD(scr_tennis_ball_trail) called at vPos:", vLoopedOffsets, ", thisBall.PTFX=", NATIVE_TO_INT(thisBall.ptfxBallTrail), ", r=", r, ", g=", g, ", b=", b)
ENDIF
SET_PARTICLE_FX_LOOPED_OFFSETS(thisBall.ptfxBallTrail, vLoopedOffsets, (<<0,0,0>>))
ENDIF
ENDPROC
PROC RESET_TENNIS_BALL_TIMERS(TENNIS_BALL &thisBall)
thisBall.fFlightTimer = 0
thisBall.fSpinTimer = 0
RESET_TENNIS_BALL_BOUNCE_TIMEOUT(thisBall)
ENDPROC
FUNC FLOAT GET_TENNIS_BALL_FLIGHT_TIMER(TENNIS_BALL &thisBall)
RETURN thisBall.fFlightTimer
ENDFUNC
FUNC FLOAT GET_TENNIS_BALL_SPIN_TIMER(TENNIS_BALL &thisBall)
RETURN thisBall.fSpinTimer
ENDFUNC
PROC RESET_TENNIS_BALL_SPIN(TENNIS_BALL &thisBall)
thisball.eBallSpin = TBS_NO_SPIN
ENDPROC
PROC RESET_TENNIS_BALL_BOUNCE_COUNT(TENNIS_BALL &thisBall)
thisBall.iBounceCount = 0
ENDPROC
PROC INCREASE_TENNIS_BALL_BOUNCE_COUNT(TENNIS_BALL &thisBall)
thisBall.iBounceCount++
CPRINTLN(DEBUG_TENNIS, "INCREASE_TENNIS_BALL_BOUNCE_COUNT to ", thisBall.iBounceCount)
ENDPROC
FUNC INT GET_TENNIS_BALL_BOUNCE_COUNT(TENNIS_BALL &thisBall)
RETURN thisBall.iBounceCount
ENDFUNC
PROC SET_TENNIS_BALL_SPIN(TENNIS_BALL &thisBall, TENNIS_BALL_SPIN newSpin)
thisBall.eBallSpin = newSpin
CPRINTLN(DEBUG_TENNIS, "SET_TENNIS_BALL_SPIN :: Applying ", GET_STRING_FROM_TENNIS_BALL_SPIN(newSpin))
ENDPROC
FUNC TENNIS_BALL_SPIN GET_TENNIS_BALL_SPIN(TENNIS_BALL &thisBall)
RETURN thisBall.eBallSpin
ENDFUNC
PROC SET_TENNIS_BALL_VISIBILITY(OBJECT_INDEX oBall, BOOL bVisible)
IF DOES_ENTITY_EXIST(oBall)
IF (IS_ENTITY_VISIBLE(oBall) AND NOT bVisible)
OR (NOT IS_ENTITY_VISIBLE(oBall) AND bVisible)
SET_ENTITY_VISIBLE(oBall, bVisible)
SET_ENTITY_FLAG_RENDER_SMALL_SHADOW(oBall, bVisible)
CPRINTLN(DEBUG_TENNIS, "SET_TENNIS_BALL_VISIBILITY with: ", bVisible)
ENDIF
ELSE
CPRINTLN(DEBUG_TENNIS, "SET_TENNIS_BALL_VISIBILITY Ball doesn't exist")
ENDIF
ENDPROC