USING "minigames_helpers.sch" USING "minigame_UIInputs.sch" USING "tennis_debug.sch" /// PURPOSE: ENUM TENNIS_AI_STATE_ENUM ASE_AI_IDLE = 0, ASE_AI_MOVING_TO_BALL, ASE_AI_CHOOSING_SHOT, ASE_AI_CHARGING_TOPSPIN, ASE_AI_CHARGING_LOB, ASE_AI_MOVING_TO_IDLE, ASE_AI_REACTING ENDENUM /// PURPOSE: ENUM AI_DIFFICULTY AD_EASY, AD_NORMAL, AD_HARD, AD_TUTORIAL // Moved Tutorial to the back, it was messing with the ENUM_TO_INT() call for setting difficulty ENDENUM /// PURPOSE: STRUCT TENNIS_AI_PLAYER VECTOR vAIBallPredictionPoint VECTOR vCurrentDestinationPoint VECTOR vHomePos[MAX_HOME_POS] TENNIS_AI_STATE_ENUM eTennisAIState AI_DIFFICULTY eDifficulty FLOAT fRightBucket = 0.0 FLOAT fBackBucket = 0.0 FLOAT fServeBucket = 0.0 FLOAT fReactionTime INT iAIFlags INT iActionTakenStamp #IF IS_DEBUG_BUILD TEXT_LABEL_7 texName #ENDIF ENDSTRUCT ENUM TENNIS_AI_FLAGS TAF_PREVENT_DBL_SWING = BIT0, // Used to prevent AI from swinging after missing the ball TAF_AI_HAS_SWUNG = BIT1, // Used to prevent AI from swinging more than once after the ball is launched TAF_JUST_TASKED = BIT2, // Used for AI indicates that the AI was just tasked to move to a coord TAF_DONT_CHASE = BIT3, // Used when the AI knows the ball is out of bounds so we don't chase it. TAF_TASKED_ANIM = BIT4, TAF_CHECK_FOR_OOB = BIT5, // Used to tell the AI to start looking for OOB balls TAF_CHECK_REACTS = BIT6, TAF_PLYR_RUN_LR_HELD = BIT7, TAF_TASKED_NEW_RALLY = BIT8, // Intended to gate setting the player to get ready for the next rally. TAF_PREVENT_MP_TENNIS_MODE_UPDATE = BIT9, TAF_TASKED_ANIM_2_IDLE = BIT10 ENDENUM FUNC STRING GET_STRING_FROM_TENNIS_AI_FLAG(TENNIS_AI_FLAGS eFlag) SWITCH eFlag CASE TAF_PREVENT_DBL_SWING RETURN "TAF_PREVENT_DBL_SWING" CASE TAF_AI_HAS_SWUNG RETURN "TAF_AI_HAS_SWUNG" CASE TAF_JUST_TASKED RETURN "TAF_JUST_TASKED" CASE TAF_DONT_CHASE RETURN "TAF_DONT_CHASE" CASE TAF_TASKED_ANIM RETURN "TAF_TASKED_ANIM" CASE TAF_CHECK_FOR_OOB RETURN "TAF_CHECK_FOR_OOB" CASE TAF_CHECK_REACTS RETURN "TAF_CHECK_REACTS" CASE TAF_PLYR_RUN_LR_HELD RETURN "TAF_PLYR_RUN_LR_HELD" CASE TAF_TASKED_NEW_RALLY RETURN "TAF_TASKED_NEW_RALLY" CASE TAF_PREVENT_MP_TENNIS_MODE_UPDATE RETURN "TAF_PREVENT_MP_TENNIS_MODE_UPDATE" CASE TAF_TASKED_ANIM_2_IDLE RETURN "TAF_TASKED_ANIM_2_IDLE" ENDSWITCH RETURN "Unknown TENNIS_AI_FLAGS" ENDFUNC PROC SET_TENNIS_AI_ACTION_TAKEN_STAMP(TENNIS_AI_PLAYER &thisAI, INT iNewStamp) thisAI.iActionTakenStamp = iNewStamp ENDPROC FUNC INT GET_TENNIS_AI_ACTION_TAKEN_STAMP(TENNIS_AI_PLAYER &thisAI) RETURN thisAI.iActionTakenStamp ENDFUNC PROC CLEAR_TENNIS_AI_FLAGS_ALL(TENNIS_AI_PLAYER &thisAI) CPRINTLN(DEBUG_TENNIS, "CLEAR_TENNIS_AI_FLAGS_ALL called on ", thisAI.texName) thisAI.iAIFlags = 0 ENDPROC PROC SET_TENNIS_AI_FLAG(TENNIS_AI_PLAYER &thisAI, TENNIS_AI_FLAGS eFlag) CDEBUG2LN(DEBUG_TENNIS, "SET_TENNIS_AI_FLAG :: ", thisAI.texName, ", ", GET_STRING_FROM_TENNIS_AI_FLAG(eFlag)) SET_BITMASK_AS_ENUM(thisAI.iAIFlags, eFlag) ENDPROC FUNC BOOL IS_TENNIS_AI_FLAG_SET(TENNIS_AI_PLAYER &thisAI, TENNIS_AI_FLAGS eFlag) RETURN IS_BITMASK_AS_ENUM_SET(thisAI.iAIFlags, eFlag) ENDFUNC PROC CLEAR_TENNIS_AI_FLAG(TENNIS_AI_PLAYER &thisAI, TENNIS_AI_FLAGS eFlag) CDEBUG2LN(DEBUG_TENNIS, "CLEAR_TENNIS_AI_FLAG :: ", thisAI.texName, ", ", GET_STRING_FROM_TENNIS_AI_FLAG(eFlag)) CLEAR_BITMASK_AS_ENUM(thisAI.iAIFlags, eFlag) ENDPROC PROC SET_AI_PREDICTION_POINT(TENNIS_AI_PLAYER &thisAI, VECTOR newPredictionPoint) CDEBUG2LN(DEBUG_TENNIS, "SET_AI_PREDICTION_POINT: ", newPredictionPoint) thisAI.vAIBallPredictionPoint = newPredictionPoint ENDPROC FUNC VECTOR GET_AI_PREDICTION_POINT(TENNIS_AI_PLAYER &thisAI) RETURN thisAI.vAIBallPredictionPoint ENDFUNC FUNC BOOL SHOULD_RETASK_MOTION(TENNIS_AI_PLAYER &thisAI) FLOAT fDist = VDIST(thisAI.vAIBallPredictionPoint, thisAI.vCurrentDestinationPoint) IF fDist > 0.1 CDEBUG2LN(DEBUG_TENNIS, "SHOULD_RETASK_MOTION :: fDist=", fDist) RETURN TRUE ELSE RETURN FALSE ENDIF ENDFUNC FUNC VECTOR GET_AI_DESTINATION_POINT(TENNIS_AI_PLAYER &thisAI) RETURN thisAI.vCurrentDestinationPoint ENDFUNC PROC SET_AI_DESTINATION_POINT(TENNIS_AI_PLAYER &thisAI, VECTOR vPos) thisAI.vCurrentDestinationPoint = vPos ENDPROC PROC SET_AI_DIFFICULTY(TENNIS_AI_PLAYER &thisAI, AI_DIFFICULTY thisDiff) CPRINTLN(DEBUG_TENNIS, "SET_AI_DIFFICULTY: ", thisAI.texName, " newDifficulty is ", PICK_STRING(thisDiff = AD_TUTORIAL, "AD_TUTORIAL", PICK_STRING(thisDiff = AD_EASY, "AD_EASY", PICK_STRING(thisDiff = AD_NORMAL, "AD_NORMAL", PICK_STRING(thisDiff = AD_HARD, "AD_HARD", "Unknown Difficulty"))))) thisAI.eDifficulty = thisDiff ENDPROC FUNC AI_DIFFICULTY GET_AI_DIFFICULTY(TENNIS_AI_PLAYER &thisAI) RETURN thisAI.eDifficulty ENDFUNC #IF IS_DEBUG_BUILD FUNC STRING GET_AI_STATE_STRING(TENNIS_AI_STATE_ENUM newASE) SWITCH newASE CASE ASE_AI_IDLE RETURN "ASE_AI_IDLE" CASE ASE_AI_MOVING_TO_BALL RETURN "ASE_AI_MOVING_TO_BALL" CASE ASE_AI_CHOOSING_SHOT RETURN "ASE_AI_CHOOSING_SHOT" CASE ASE_AI_CHARGING_TOPSPIN RETURN "ASE_AI_CHARGING_TOPSPIN" CASE ASE_AI_CHARGING_LOB RETURN "ASE_AI_CHARGING_LOB" CASE ASE_AI_MOVING_TO_IDLE RETURN "ASE_AI_MOVING_TO_IDLE" CASE ASE_AI_REACTING RETURN "ASE_AI_REACTING" ENDSWITCH RETURN "Unknown ASE" ENDFUNC #ENDIF PROC SET_TENNIS_AI_STATE(TENNIS_AI_PLAYER &thisAI, TENNIS_AI_STATE_ENUM newASE) #IF IS_DEBUG_BUILD #IF TENNIS_DEBUG_RECORDING DEBUG_RECORD_STRING("SET_TENNIS_AI_STATE", GET_AI_STATE_STRING(newASE)) #ENDIF CDEBUG2LN(DEBUG_TENNIS, "SET_TENNIS_AI_STATE :: ", thisAI.texName, ", oldState: ", GET_AI_STATE_STRING(thisAI.eTennisAIState), " newState: ", GET_AI_STATE_STRING(newASE)) #ENDIF thisAI.eTennisAIState = newASE ENDPROC FUNC TENNIS_AI_STATE_ENUM GET_TENNIS_AI_STATE(TENNIS_AI_PLAYER &thisAI) RETURN thisAI.eTennisAIState ENDFUNC