USING "commands_network.sch" USING "tennis_mp.sch" USING "tennis_debug.sch" USING "fmmc_restart_header.sch" STRUCT TENNIS_PARTICIPANT_INFO INT iPlayers[TENNIS_PLAYERS] INT iSCTV[TENNIS_MAX_SCTV] INT iPlayerCount INT iSCTVCount ENDSTRUCT // The server broadcast data // Everyone can read this data, only the server can update it STRUCT TENNIS_SERVER_BD TENNIS_MP_STATE eMPState //Server Data TENNIS_PLAYER_ID eWhoIsServing TENNIS_PLAYER_ID eHitLast TENNIS_PLAYER_ID eScoredLast SERVING_SIDE_ENUM eServingSide = SERVING_FROM_RIGHT TENNIS_GAME_STATE_ENUM eGameState TENNIS_GAME_STATE_ENUM ePrevGameState TENNIS_SCORES playerScores[TENNIS_PLAYERS] TENNIS_MATCH_RULESET eRuleset FLOAT fDesyncTimer BOOL bOnTieBreak INT iNumSets = 1 INT iServeCount INT iCurrentSet INT iTMSFlags INT iCurrentOption INT iMatchHistoryID INT iMatchType INT iHashMac SERVER_EOM_VARS sServerFMMC_EOM PLAYER_CURRENT_STATUS_COUNTS sPlayerCounts SCRIPT_TIMER timeLeaderboardTimeOut SCRIPT_TIMER timeServeTimeOut ENDSTRUCT PROC SET_TENNIS_SERVER_FLAG(TENNIS_SERVER_BD &serverBD, TENNIS_MP_SERVER_FLAGS eFlag) CDEBUG2LN(DEBUG_TENNIS, "SET_TENNIS_SERVER_FLAG :: Setting ", GET_STRING_FROM_TENNIS_SERVER_FLAG(eFlag)) IF NETWORK_IS_HOST_OF_THIS_SCRIPT() SET_BITMASK_AS_ENUM(serverBD.iTMSFlags, eFlag) ENDIF ENDPROC FUNC BOOL IS_TENNIS_SERVER_FLAG_SET(TENNIS_SERVER_BD &serverBD, TENNIS_MP_SERVER_FLAGS eFlag) RETURN IS_BITMASK_AS_ENUM_SET(serverBD.iTMSFlags, eFlag) ENDFUNC PROC CLEAR_TENNIS_SERVER_FLAG(TENNIS_SERVER_BD &serverBD, TENNIS_MP_SERVER_FLAGS eFlag) CDEBUG2LN(DEBUG_TENNIS, "CLEAR_TENNIS_SERVER_FLAG :: Clearing ", GET_STRING_FROM_TENNIS_SERVER_FLAG(eFlag)) IF NETWORK_IS_HOST_OF_THIS_SCRIPT() CLEAR_BITMASK_AS_ENUM(serverBD.iTMSFlags, eFlag) ENDIF ENDPROC /// PURPOSE: /// WARNING: This will unset all other server flags! /// PARAMS: /// serverBD - /// eFlag - PROC SET_TENNIS_SERVER_FLAG_EXCLUSIVE(TENNIS_SERVER_BD &serverBD, TENNIS_MP_SERVER_FLAGS eFlag) CDEBUG2LN(DEBUG_TENNIS, "SET_TENNIS_SERVER_FLAG_EXCLUSIVE :: Setting ", GET_STRING_FROM_TENNIS_SERVER_FLAG(eFlag)) serverBD.iTMSFlags = ENUM_TO_INT(eFlag) ENDPROC PROC SET_TENNIS_MP_TIE_BREAK(TENNIS_SERVER_BD &serverBD, BOOL bOnTieBreak) IF NETWORK_IS_HOST_OF_THIS_SCRIPT() CDEBUG2LN(DEBUG_TENNIS, "START_TENNIS_MP_TIE_BREAK :: bOnTieBreak=", PICK_STRING(bOnTieBreak, "TRUE", "FALSE")) serverBD.bOnTieBreak = bOnTieBreak ENDIF ENDPROC FUNC BOOL IS_TENNIS_MP_ON_TIE_BREAK(TENNIS_SERVER_BD &serverBD) RETURN serverBD.bOnTieBreak ENDFUNC PROC SET_TENNIS_MP_RULESET(TENNIS_SERVER_BD &serverBD, TENNIS_MATCH_RULESET eNewRuleset) IF NETWORK_IS_HOST_OF_THIS_SCRIPT() serverBD.eRuleset = eNewRuleset ENDIF ENDPROC FUNC TENNIS_MATCH_RULESET GET_TENNIS_MP_RULESET(TENNIS_SERVER_BD &serverBD) RETURN serverBD.eRuleset ENDFUNC PROC SET_TENNIS_MP_NUM_SETS(TENNIS_SERVER_BD &serverBD, INT iNewSets) IF NETWORK_IS_HOST_OF_THIS_SCRIPT() serverBD.iNumSets = iNewSets ENDIF ENDPROC FUNC INT GET_TENNIS_MP_NUM_SETS(TENNIS_SERVER_BD &serverBD) RETURN serverBD.iNumSets ENDFUNC FLOAT fDesyncTimer PROC INCREASE_TENNIS_DESYNC_TIMER() fDesyncTimer += GET_FRAME_TIME() ENDPROC FUNC BOOL SHOULD_TENNIS_DESYNC_BE_HANDLED() RETURN fDesyncTimer > DESYNC_THRESHOLD ENDFUNC PROC RESET_TENNIS_DESYNC_TIMER() fDesyncTimer = 0.0 ENDPROC PROC TENNIS_MP_RESET_POINTS_WON(TENNIS_SCORES &playerScores[], INT &iUtilFlags) IF NETWORK_IS_HOST_OF_THIS_SCRIPT() playerScores[0].iPointsWon = 0 playerScores[1].iPointsWon = 0 SET_BITMASK_AS_ENUM(iUtilFlags, TD_UPDATE_SCORES) ENDIF ENDPROC /// PURPOSE: /// /// PARAMS: /// playerScores - The score struct of the player who just scored PROC TENNIS_MP_INCREASE_POINTS_WON(TENNIS_SCORES &serverScores, INT &iUtilFlags) #IF IS_DEBUG_BUILD IF NOT DO_NOT_TRACK_SCORE #ENDIF IF NETWORK_IS_HOST_OF_THIS_SCRIPT() serverScores.iPointsWon++ SET_BITMASK_AS_ENUM(iUtilFlags, TD_UPDATE_SCORES) CPRINTLN(DEBUG_TENNIS, "Increasing Points Won for the serverScores passed in") ENDIF #IF IS_DEBUG_BUILD ENDIF #ENDIF ENDPROC /// PURPOSE: /// Currently void, does nothing. PROC RECORD_TENNIS_MP_GAME_WIN() ENDPROC FUNC TENNIS_GAME_STATE_ENUM GET_TENNIS_SERVER_PREV_GAME_STATE(TENNIS_SERVER_BD &serverBD) RETURN serverBD.ePrevGameState ENDFUNC PROC SET_TENNIS_MP_WHO_IS_SERVING(TENNIS_SERVER_BD &thisBD, TENNIS_PLAYER_ID newServing) IF NETWORK_IS_HOST_OF_THIS_SCRIPT() thisBD.eWhoIsServing = newServing CPRINTLN(DEBUG_TENNIS, "Tennis Server changed to ", PICK_STRING(newServing = TENNIS_PLAYER_AWAY, "TENNIS_PLAYER_AWAY", "TENNIS_PLAYER_HOME")) ENDIF ENDPROC FUNC TENNIS_PLAYER_ID GET_TENNIS_MP_WHO_IS_SERVING(TENNIS_SERVER_BD &serverBD) RETURN serverBD.eWhoIsServing ENDFUNC PROC SET_TENNIS_MP_HIT_LAST(TENNIS_SERVER_BD &thisBD, TENNIS_PLAYER_ID newHitLast) IF NETWORK_IS_HOST_OF_THIS_SCRIPT() thisBD.eHitLast = newHitLast CPRINTLN(DEBUG_TENNIS, "Set ped to hit last as ", PICK_STRING(newHitLast = TENNIS_PLAYER_AWAY, "TENNIS_PLAYER_AWAY", "TENNIS_PLAYER_HOME")) ENDIF ENDPROC FUNC TENNIS_PLAYER_ID GET_TENNIS_MP_HIT_LAST(TENNIS_SERVER_BD &serverBD) RETURN serverBD.eHitLast ENDFUNC FUNC INT GET_TENNIS_MP_CURRENT_SET(TENNIS_SERVER_BD &serverBD) RETURN serverBD.iCurrentSet ENDFUNC PROC SET_TENNIS_SERVER_MP_STATE(TENNIS_SERVER_BD &serverBD, TENNIS_MP_STATE newMPState) IF NETWORK_IS_HOST_OF_THIS_SCRIPT() CDEBUG3LN(DEBUG_TENNIS, "SET_TENNIS_SERVER_MP_STATE :: newMPState=", GET_STRING_FROM_TENNIS_MP_STATE(newMPState)) serverBD.eMPState = newMPState ENDIF ENDPROC FUNC TENNIS_MP_STATE GET_TENNIS_SERVER_MP_STATE(TENNIS_SERVER_BD &serverBD) RETURN serverBD.eMPState ENDFUNC PROC SET_TENNIS_SERVER_GAME_STATE(TENNIS_SERVER_BD &serverBD, TENNIS_GAME_STATE_ENUM newTGSE, BOOL desynced=FALSE) IF NETWORK_IS_HOST_OF_THIS_SCRIPT() IF serverBD.eGameState <> newTGSE OR desynced serverBD.ePrevGameState = serverBD.eGameState serverBD.eGameState = newTGSE CPRINTLN(DEBUG_TENNIS, "Game Timer: ", GET_GAME_TIMER(), " Server switched to: ", PICK_STRING(newTGSE = TGSE_PREPARE_SERVE, "TGSE_PREPARE_FOR_SERVE ", PICK_STRING(newTGSE = TGSE_RALLY, "TGSE_RALLY ", PICK_STRING(newTGSE = TGSE_POINT_WON, "TGSE_POINT_WON ", PICK_STRING(newTGSE = TGSE_POINT_CHECKS, "TGSE_POINT_CHECKS ", PICK_STRING(newTGSE = TGSE_INTERSTITIAL, "TGSE_INTERSTITIAL ", PICK_STRING(newTGSE = TGSE_TEST_STATE, "TGSE_TEST_STATE ", PICK_STRING(newTGSE = TGSE_PREPARE_REMATCH, "TGSE_PREPARE_REMATCH ", PICK_STRING(newTGSE = TGSE_CHANGE_SERVERS, "TGSE_CHANGE_SERVERS ", "TENNIS_GAME_STATE_ENUM Enum: ")))))))), newTGSE) CPRINTLN(DEBUG_TENNIS, PICK_STRING(desynced, "Game experienced a desync", "Game is running smoothly")) ELSE CPRINTLN(DEBUG_TENNIS, "Trying to set to state: ", PICK_STRING(newTGSE = TGSE_PREPARE_SERVE, "TGSE_PREPARE_FOR_SERVE ", PICK_STRING(newTGSE = TGSE_RALLY, "TGSE_RALLY ", PICK_STRING(newTGSE = TGSE_POINT_WON, "TGSE_POINT_WON ", PICK_STRING(newTGSE = TGSE_POINT_CHECKS, "TGSE_POINT_CHECKS ", PICK_STRING(newTGSE = TGSE_INTERSTITIAL, "TGSE_INTERSTITIAL ", PICK_STRING(newTGSE = TGSE_PREPARE_REMATCH, "TGSE_PREPARE_REMATCH ", PICK_STRING(newTGSE = TGSE_TEST_STATE, "TGSE_TEST_STATE ", PICK_STRING(newTGSE = TGSE_CHANGE_SERVERS, "TGSE_CHANGE_SERVERS ", "TENNIS_GAME_STATE_ENUM Enum: ")))))))), newTGSE) CPRINTLN(DEBUG_TENNIS, PICK_STRING(desynced, "Game experienced a desync", "Game is running smoothly")) //SCRIPT_ASSERT("Server State is being set to itself, contact Rob Pearsall") ENDIF IF desynced AND newTGSE <> TGSE_POINT_WON CLEAR_TENNIS_SERVER_FLAG(serverBD, TMS_RECOVERING_FROM_DESYNC) CPRINTLN(DEBUG_TENNIS, "Clearing desync server flag") ENDIF ENDIF ENDPROC FUNC TENNIS_GAME_STATE_ENUM GET_TENNIS_SERVER_GAME_STATE(TENNIS_SERVER_BD &serverBD) RETURN serverBD.eGameState ENDFUNC PROC SET_TENNIS_MP_SCORED_LAST_private(TENNIS_SERVER_BD &serverBD, TENNIS_PLAYER_ID whoScored) IF NETWORK_IS_HOST_OF_THIS_SCRIPT() serverBD.eScoredLast = whoScored CPRINTLN(DEBUG_TENNIS, "Last ped to score is ", PICK_STRING(whoScored = TENNIS_PLAYER_AWAY, "TENNIS_PLAYER_AWAY", "TENNIS_PLAYER_HOME")) ENDIF ENDPROC FUNC TENNIS_PLAYER_ID GET_TENNIS_MP_SCORED_LAST(TENNIS_SERVER_BD &serverBD) RETURN serverBD.eScoredLast ENDFUNC PROC SET_TENNIS_MP_SERVING_SIDE(TENNIS_SERVER_BD &serverBD, SERVING_SIDE_ENUM newSide) IF NETWORK_IS_HOST_OF_THIS_SCRIPT() serverBD.eServingSide = newSide CPRINTLN(DEBUG_TENNIS, "Changing the serving side to ", PICK_STRING(newSide = SERVING_FROM_RIGHT, "SERVING_FROM_RIGHT", "SERVING_FROM_LEFT")) ENDIF ENDPROC FUNC SERVING_SIDE_ENUM GET_TENNIS_MP_SERVING_SIDE(TENNIS_SERVER_BD &serverBD) RETURN serverBD.eServingSide ENDFUNC PROC SET_TENNIS_MP_SERVE_COUNT(TENNIS_SERVER_BD &serverBD, INT iCount) IF NETWORK_IS_HOST_OF_THIS_SCRIPT() serverBD.iServeCount = iCount CPRINTLN(DEBUG_TENNIS, "Game Timer: ", GET_GAME_TIMER(), " Serve count set to: ", iCount) ENDIF ENDPROC FUNC INT GET_TENNIS_MP_SERVE_COUNT(TENNIS_SERVER_BD &serverBD) RETURN serverBD.iServeCount ENDFUNC PROC PRINT_ALL_TENNIS_SERVER_FLAGS(TENNIS_SERVER_BD &serverBD) CPRINTLN(DEBUG_TENNIS, "TMS_MOVE_TO_GAME ", PICK_STRING(IS_TENNIS_SERVER_FLAG_SET(serverBD, TMS_MOVE_TO_GAME), "IS", "IS NOT"), " set") CPRINTLN(DEBUG_TENNIS, "TMS_MOVE_TO_RALLY ", PICK_STRING(IS_TENNIS_SERVER_FLAG_SET(serverBD, TMS_MOVE_TO_RALLY), "IS", "IS NOT"), " set") CPRINTLN(DEBUG_TENNIS, "TMS_MOVE_TO_PREPARE_SERVE ", PICK_STRING(IS_TENNIS_SERVER_FLAG_SET(serverBD, TMS_MOVE_TO_PREPARE_SERVE), "IS", "IS NOT"), " set") CPRINTLN(DEBUG_TENNIS, "TMS_MOVE_TO_OUTRO ", PICK_STRING(IS_TENNIS_SERVER_FLAG_SET(serverBD, TMS_MOVE_TO_OUTRO), "IS", "IS NOT"), " set") CPRINTLN(DEBUG_TENNIS, "TMS_MOVE_TO_POINT_WON ", PICK_STRING(IS_TENNIS_SERVER_FLAG_SET(serverBD, TMS_MOVE_TO_POINT_WON), "IS", "IS NOT"), " set") CPRINTLN(DEBUG_TENNIS, "TMS_MOVE_TO_INTERSTITIAL ", PICK_STRING(IS_TENNIS_SERVER_FLAG_SET(serverBD, TMS_MOVE_TO_INTERSTITIAL), "IS", "IS NOT"), " set") CPRINTLN(DEBUG_TENNIS, "TMS_MOVE_TO_CHANGE_SERVERS ", PICK_STRING(IS_TENNIS_SERVER_FLAG_SET(serverBD, TMS_MOVE_TO_CHANGE_SERVERS), "IS", "IS NOT"), " set") CPRINTLN(DEBUG_TENNIS, "TMS_PREPARE_FOR_DESYNC ", PICK_STRING(IS_TENNIS_SERVER_FLAG_SET(serverBD, TMS_PREPARE_FOR_DESYNC), "IS", "IS NOT"), " set") CPRINTLN(DEBUG_TENNIS, "TMS_RECOVERING_FROM_DESYNC ", PICK_STRING(IS_TENNIS_SERVER_FLAG_SET(serverBD, TMS_RECOVERING_FROM_DESYNC), "IS", "IS NOT"), " set") CPRINTLN(DEBUG_TENNIS, "TMS_MOVE_TO_FINISH ", PICK_STRING(IS_TENNIS_SERVER_FLAG_SET(serverBD, TMS_MOVE_TO_FINISH), "IS", "IS NOT"), " set") CPRINTLN(DEBUG_TENNIS, "TMS_MOVE_TO_SIDE_CHANGE ", PICK_STRING(IS_TENNIS_SERVER_FLAG_SET(serverBD, TMS_MOVE_TO_SIDE_CHANGE), "IS", "IS NOT"), " set") CPRINTLN(DEBUG_TENNIS, "TMS_MOVE_TO_PREPARE_REMATCH ", PICK_STRING(IS_TENNIS_SERVER_FLAG_SET(serverBD, TMS_MOVE_TO_PREPARE_REMATCH), "IS", "IS NOT"), " set") CPRINTLN(DEBUG_TENNIS, "TMS_MOVE_TO_POINT_CHECKS ", PICK_STRING(IS_TENNIS_SERVER_FLAG_SET(serverBD, TMS_MOVE_TO_POINT_CHECKS), "IS", "IS NOT"), " set") CPRINTLN(DEBUG_TENNIS, "TMS_IS_REMATCH_FLAG ", PICK_STRING(IS_TENNIS_SERVER_FLAG_SET(serverBD, TMS_IS_REMATCH_FLAG), "IS", "IS NOT"), " set") ENDPROC PROC PRINT_ALL_TENNIS_SERVER_DATA(TENNIS_SERVER_BD &serverBD) CPRINTLN(DEBUG_TENNIS, "PRINT_ALL_TENNIS_SERVER_DATA :: Data below") CPRINTLN(DEBUG_TENNIS, "eMPState=", GET_STRING_FROM_TENNIS_MP_STATE(serverBD.eMPState)) CPRINTLN(DEBUG_TENNIS, "eWhoIsServing=", GET_STRING_FROM_TENNIS_PLAYER_ID(serverBD.eWhoIsServing)) CPRINTLN(DEBUG_TENNIS, "eHitLast=", GET_STRING_FROM_TENNIS_PLAYER_ID(serverBD.eHitLast)) CPRINTLN(DEBUG_TENNIS, "eScoredLast=", GET_STRING_FROM_TENNIS_PLAYER_ID(serverBD.eScoredLast)) CPRINTLN(DEBUG_TENNIS, "eServingSide=", serverBD.eServingSide) CPRINTLN(DEBUG_TENNIS, "eGameState=", GET_STRING_FROM_TENNIS_GAME_STATE(serverBD.eGameState)) CPRINTLN(DEBUG_TENNIS, "ePrevGameState=", GET_STRING_FROM_TENNIS_GAME_STATE(serverBD.ePrevGameState)) CPRINTLN(DEBUG_TENNIS, "fDesyncTimer=", serverBD.fDesyncTimer) CPRINTLN(DEBUG_TENNIS, "bOnTieBreak=", serverBD.bOnTieBreak) CPRINTLN(DEBUG_TENNIS, "iNumSets=", serverBD.iNumSets) CPRINTLN(DEBUG_TENNIS, "iServeCount=", serverBD.iServeCount) CPRINTLN(DEBUG_TENNIS, "iCurrentSet=", serverBD.iCurrentSet) CPRINTLN(DEBUG_TENNIS, "iCurrentOption=", serverBD.iCurrentOption) CPRINTLN(DEBUG_TENNIS, "iMatchHistoryID=", serverBD.iMatchHistoryID) CPRINTLN(DEBUG_TENNIS, "iMatchType=", serverBD.iMatchType) CPRINTLN(DEBUG_TENNIS, "iHashMac=", serverBD.iHashMac) PRINT_ALL_TENNIS_SERVER_FLAGS(serverBD) ENDPROC FUNC BOOL VALIDATE_TENNIS_PLAYERS_INFO(TENNIS_PARTICIPANT_INFO &info) IF info.iPlayers[0] = TENNIS_INVALID_PARTICIPANT_ID CERRORLN(DEBUG_TENNIS, "VALIDATE_TENNIS_PLAYERS_INFO :: Exiting player0=", PICK_STRING(info.iPlayers[0] = TENNIS_INVALID_PARTICIPANT_ID, "INVALID", "VALID")) DEBUG_PRINTCALLSTACK() RETURN FALSE ENDIF IF info.iPlayers[1] = TENNIS_INVALID_PARTICIPANT_ID CERRORLN(DEBUG_TENNIS, "VALIDATE_TENNIS_PLAYERS_INFO :: Exiting player1=", PICK_STRING(info.iPlayers[1] = TENNIS_INVALID_PARTICIPANT_ID, "INVALID", "VALID")) DEBUG_PRINTCALLSTACK() RETURN FALSE ENDIF RETURN TRUE ENDFUNC /// PURPOSE: /// Checks if a player is SCTV or joined as a spectator /// PARAMS: /// iPlayerID - The INT of the player you're curious about, -1 returns the local player /// RETURNS: /// TRUE if the player joined as spectator or SCTV, FALSE otherwise FUNC BOOL TENNIS_IS_PLAYER_SPECTATING( INT iPlayerID = -1 ) PLAYER_INDEX playerToCheck IF iPlayerID = -1 playerToCheck = PLAYER_ID() ELSE playerToCheck = INT_TO_PLAYERINDEX( iPlayerID ) ENDIF IF IS_PLAYER_SCTV( playerToCheck ) RETURN TRUE ENDIF IF DID_PLAYER_JOIN_MISSION_AS_SPECTATOR( playerToCheck ) RETURN TRUE ENDIF RETURN FALSE ENDFUNC