302 lines
13 KiB
XML
Executable File
302 lines
13 KiB
XML
Executable File
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Name: turret_manager_sup.sch //
|
|
// Description: "Private" support methods for the turret management system. Mostly contains server-side //
|
|
// methods to deal with client lock requests. //
|
|
// See turret_manager_core.sch for more details. //
|
|
// //
|
|
// Written by: Online Technical Team: Orlando C-H //
|
|
// Date: 05/09/2018 //
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
USING "turret_manager_public.sch"
|
|
USING "turret_manager_def.sch"
|
|
USING "globals.sch"
|
|
USING "script_network.sch"
|
|
USING "net_include.sch"
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Queries server data for a free turret index given a group and instance.
|
|
/// No ordering is taken into account.
|
|
///
|
|
/// Only guarenteed to be up to date for the freemode host.
|
|
/// Request use of a turret with TURRET_MANAGER_CREATE_LOCK_REQUEST.
|
|
/// PARAMS:
|
|
/// ref_iTurretId - Set to the turret index. Only valid if the function returns true.
|
|
/// RETURNS:
|
|
///
|
|
FUNC BOOL GET_ANY_FREE_TURRET_ID(TURRET_GROUP_TYPE eGroupType, INT iInstanceId, INT& ref_iTurretId)
|
|
INT iTurretCount = TURRET_GROUP_TURRET_COUNT(eGroupType)
|
|
|
|
IF iTurretCount > ci_MAX_TURRET_GROUP_SIZE
|
|
ASSERTLN("[ARENA_TURRET] GET_FIRST_FREE_TURRET_ID - INCREASE ci_MAX_TURRET_GROUP_SIZE")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
BOOL bInUse[ci_MAX_TURRET_GROUP_SIZE]
|
|
|
|
INT i
|
|
REPEAT COUNT_OF(GlobalServerBD.turrets.players) i
|
|
IF GlobalServerBD.turrets.players[i].iInstanceId = iInstanceId
|
|
AND GlobalServerBD.turrets.players[i].groupType = eGroupType
|
|
bInUse[GlobalServerBD.turrets.players[i].iTurretId] = TRUE
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
REPEAT COUNT_OF(bInUse) i
|
|
IF NOT bInUse[i]
|
|
ref_iTurretId = i
|
|
CDEBUG1LN(DEBUG_NET_TURRET, "GET_ANY_FREE_TURRET_ID Found free turretId = ", ref_iTurretId)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Checks the serverBd to see if a turret is free.
|
|
/// Only guarenteed to be up to date for the freemode host.
|
|
/// Request use of a turret with TURRET_MANAGER_CREATE_LOCK_REQUEST.
|
|
FUNC BOOL GET_NEXT_FREE_TURRET_ID(BOOL bForwards, TURRET_GROUP_TYPE eGroupType, INT iInstanceId, INT& ref_iTurretId)
|
|
INT iTurretCount = TURRET_GROUP_TURRET_COUNT(eGroupType)
|
|
|
|
IF iTurretCount > ci_MAX_TURRET_GROUP_SIZE
|
|
ASSERTLN("[ARENA_TURRET] GET_FIRST_FREE_TURRET_ID - INCREASE ci_MAX_TURRET_GROUP_SIZE")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
BOOL bInUse[ci_MAX_TURRET_GROUP_SIZE]
|
|
|
|
INT i
|
|
REPEAT COUNT_OF(GlobalServerBD.turrets.players) i
|
|
IF GlobalServerBD.turrets.players[i].iInstanceId = iInstanceId
|
|
AND GlobalServerBD.turrets.players[i].groupType = eGroupType
|
|
bInUse[GlobalServerBD.turrets.players[i].iTurretId] = TRUE
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
INT iClosestId = ref_iTurretId
|
|
INT iClosestDist = ci_MAX_TURRET_GROUP_SIZE
|
|
|
|
IF bForwards
|
|
REPEAT COUNT_OF(bInUse) i
|
|
IF NOT bInUse[i]
|
|
AND ref_iTurretId <> i
|
|
INT iDist = i - ref_iTurretId
|
|
// Wrap distance around 0->max
|
|
IF iDist < 0
|
|
iDist += iTurretCount
|
|
ENDIF
|
|
IF iDist < iClosestDist
|
|
iClosestId = i
|
|
iClosestDist = iDist
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
ELSE
|
|
REPEAT COUNT_OF(bInUse) i
|
|
IF NOT bInUse[i]
|
|
AND ref_iTurretId <> i
|
|
INT iDist = ref_iTurretId - i
|
|
// Wrap distance around 0->max
|
|
IF iDist < 0
|
|
iDist += iTurretCount
|
|
ENDIF
|
|
|
|
IF iDist < iClosestDist
|
|
iClosestId = i
|
|
iClosestDist = iDist
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
ENDIF
|
|
|
|
IF iClosestId = ref_iTurretId
|
|
RETURN FALSE
|
|
ELSE
|
|
ref_iTurretId = iClosestId
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Checks the serverBd to see if a turret is free.
|
|
/// Only guarenteed to be up to date for the freemode host.
|
|
/// Request use of a turret with TURRET_MANAGER_CREATE_LOCK_REQUEST.
|
|
/// Returns -1 if turret is free.
|
|
FUNC PLAYER_INDEX GET_PLAYER_IN_TURRET(TURRET_GROUP_TYPE eGroupType, INT iInstanceId, INT iTurretId)
|
|
INT iPlayer
|
|
REPEAT COUNT_OF(GlobalServerBD.turrets.players) iPlayer
|
|
IF GlobalServerBD.turrets.players[iPlayer].groupType = eGroupType
|
|
AND GlobalServerBD.turrets.players[iPlayer].iInstanceId = iInstanceId
|
|
AND GlobalServerBD.turrets.players[iPlayer].iTurretId = iTurretId
|
|
RETURN INT_TO_NATIVE(PLAYER_INDEX, iPlayer)
|
|
ENDIF
|
|
ENDREPEAT
|
|
RETURN INT_TO_NATIVE(PLAYER_INDEX, -1)
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Checks the serverBd to see if a turret is free.
|
|
/// Only guarenteed to be up to date for the freemode host.
|
|
/// Request use of a turret with TURRET_MANAGER_CREATE_LOCK_REQUEST.
|
|
FUNC BOOL IS_THIS_TURRET_ID_IS_FREE(TURRET_GROUP_TYPE eGroupType, INT iInstanceId, INT iTurretId)
|
|
PLAYER_INDEX player = GET_PLAYER_IN_TURRET(eGroupType, iInstanceId, iTurretId)
|
|
RETURN NATIVE_TO_INT(player) = -1
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Returns FALSE if no turretId is free with matching eGroupType and iInstanceId.
|
|
FUNC BOOL IS_TURRET_FREE(INT& ref_iTurretId, INT iInstanceId, TURRET_GROUP_TYPE eGroupType, TURRET_LOCK_SEARCH_TYPE eSearchType)
|
|
CDEBUG1LN(DEBUG_NET_TURRET, "IS_TURRET_FREE eGroupType = ", ENUM_TO_INT(eGroupType), " iInstanceId = ",iInstanceId, " iTurretId = ", ref_iTurretId, " eSearchType = ", eSearchType)
|
|
SWITCH eSearchType
|
|
CASE TLST_THIS_TURRET_ONLY
|
|
RETURN IS_THIS_TURRET_ID_IS_FREE(eGroupType, iInstanceId, ref_iTurretId)
|
|
|
|
CASE TLST_ANY_TURRET
|
|
RETURN GET_ANY_FREE_TURRET_ID(eGroupType, iInstanceId, ref_iTurretId)
|
|
|
|
CASE TLST_ANY_TURRET_FORWARDS
|
|
RETURN GET_NEXT_FREE_TURRET_ID(TRUE, eGroupType, iInstanceId, ref_iTurretId)
|
|
|
|
CASE TLST_ANY_TURRET_BACKWARDS
|
|
RETURN GET_NEXT_FREE_TURRET_ID(FALSE, eGroupType, iInstanceId, ref_iTurretId)
|
|
|
|
DEFAULT
|
|
RETURN FALSE
|
|
ENDSWITCH
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Save the arguments into global broadcast data for the turret management system.
|
|
PROC TURRET_MANAGER_SERVER_SET_DATA(PLAYER_INDEX player, TURRET_GROUP_TYPE eGroup, INT iInstanceId, INT iTurretId)
|
|
INT iPlayerIndex = NATIVE_TO_INT(player)
|
|
IF iPlayerIndex < 0
|
|
OR iPlayerIndex >= COUNT_OF(GlobalServerBD.turrets.players)
|
|
PRINTLN("TURRET_MANAGER_SERVER_SET_DATA [VALIDATE] - invalid player index in player: ", iPlayerIndex)
|
|
SCRIPT_ASSERT("TURRET_MANAGER_SERVER_SET_DATA [VALIDATE] - invalid player index in player")
|
|
EXIT
|
|
ENDIF
|
|
|
|
INT iTurretGroupType = ENUM_TO_INT(eGroup)
|
|
IF iTurretGroupType < 0
|
|
OR iTurretGroupType > ENUM_TO_INT(TGT_ARENA_CONTESTANT)
|
|
CDEBUG1LN(DEBUG_NET_TURRET, "TURRET_MANAGER_SERVER_SET_DATA [VALIDATE] - invalid TURRET_GROUP_TYPE in eGroup, expected value between 0 and TGT_ARENA_CONTESTANT, actual value: ", iTurretGroupType)
|
|
SCRIPT_ASSERT("TURRET_MANAGER_SERVER_SET_DATA [VALIDATE] - invalid TURRET_GROUP_TYPE in eGroup")
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF iTurretId < 0
|
|
OR iTurretId >= ci_MAX_TURRET_GROUP_SIZE
|
|
CDEBUG1LN(DEBUG_NET_TURRET, "TURRET_MANAGER_SERVER_SET_DATA [VALIDATE] - invalid value in iTurretId, expected value between 0 and (ci_MAX_TURRET_GROUP_SIZE-1), actual value: ", iTurretId)
|
|
SCRIPT_ASSERT("TURRET_MANAGER_SERVER_SET_DATA [VALIDATE] - invalid value in iTurretId")
|
|
EXIT
|
|
ENDIF
|
|
|
|
GlobalServerBD.turrets.players[iPlayerIndex].groupType = eGroup
|
|
GlobalServerBD.turrets.players[iPlayerIndex].iInstanceId = iInstanceId
|
|
GlobalServerBD.turrets.players[iPlayerIndex].iTurretId = iTurretId
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// This proc takes data from a request "ref_iRequestArray" and populates "ref_iResponseArray"
|
|
/// with data to send back to the player who requested a turret change.
|
|
///
|
|
/// This should only be handled by the player owning the turret serverBd (GlobalServerBD.turrets - freemode host).
|
|
PROC PROCESS_SERVER_RESPONSE_TO_TURRET_REQUEST(PLAYER_INDEX player, INT& ref_iRequestArray[], INT& ref_iResponseArray[])
|
|
|
|
CDEBUG1LN(DEBUG_NET_TURRET, "[SERVER] PROCESS_SERVER_RESPONSE_TO_TURRET_REQUEST for ", GET_PLAYER_NAME(player), " (", NATIVE_TO_INT(player),")")
|
|
TURRET_GROUP_TYPE eGroupTypeRequest = INT_TO_ENUM(TURRET_GROUP_TYPE, ref_iRequestArray[ci_TURRET_RQST_GRP])
|
|
TURRET_LOCK_SEARCH_TYPE eSearchType = INT_TO_ENUM(TURRET_LOCK_SEARCH_TYPE, ref_iRequestArray[ci_TURRET_RQST_SEARCH])
|
|
TURRET_GROUP_TYPE eCurrentGroupType = TURRET_MANAGER_GET_GROUP(player)
|
|
|
|
SWITCH eGroupTypeRequest
|
|
CASE TGT_NONE
|
|
CDEBUG1LN(DEBUG_NET_TURRET, "[SERVER] Setting player turret to TGT_NONE.")
|
|
|
|
// To release a turret simply set the group type to tgt_none & copy other data.
|
|
ref_iResponseArray[ci_TURRET_RQST_TURRET] = ref_iRequestArray[ci_TURRET_RQST_TURRET]
|
|
ref_iResponseArray[ci_TURRET_RQST_INST] = ref_iRequestArray[ci_TURRET_RQST_INST]
|
|
ref_iResponseArray[ci_TURRET_RQST_UID] = ref_iRequestArray[ci_TURRET_RQST_UID]
|
|
ref_iResponseArray[ci_TURRET_RQST_SEARCH] = ref_iRequestArray[ci_TURRET_RQST_SEARCH]
|
|
ref_iResponseArray[ci_TURRET_RQST_BS] = ref_iRequestArray[ci_TURRET_RQST_BS]
|
|
ref_iResponseArray[ci_TURRET_RQST_GRP] = ENUM_TO_INT(TGT_NONE)
|
|
BREAK
|
|
|
|
DEFAULT
|
|
// Defualt behaviour : Return requested turret details & set group type to TGT_NONE if
|
|
// the turret isn't free.
|
|
ref_iResponseArray[ci_TURRET_RQST_GRP] = ref_iRequestArray[ci_TURRET_RQST_GRP]
|
|
ref_iResponseArray[ci_TURRET_RQST_TURRET] = ref_iRequestArray[ci_TURRET_RQST_TURRET]
|
|
ref_iResponseArray[ci_TURRET_RQST_INST] = ref_iRequestArray[ci_TURRET_RQST_INST]
|
|
ref_iResponseArray[ci_TURRET_RQST_UID] = ref_iRequestArray[ci_TURRET_RQST_UID]
|
|
ref_iResponseArray[ci_TURRET_RQST_SEARCH] = ref_iRequestArray[ci_TURRET_RQST_SEARCH]
|
|
ref_iResponseArray[ci_TURRET_RQST_BS] = ref_iRequestArray[ci_TURRET_RQST_BS]
|
|
|
|
IF NOT IS_TURRET_FREE(ref_iResponseArray[ci_TURRET_RQST_TURRET], ref_iRequestArray[ci_TURRET_RQST_INST], eGroupTypeRequest, eSearchType)
|
|
IF eCurrentGroupType <> TGT_NONE
|
|
AND IS_BIT_SET(ref_iRequestArray[ci_TURRET_RQST_BS], ci_TURRET_LOCK_BS_DO_NOT_KICK)
|
|
CDEBUG1LN(DEBUG_NET_TURRET, "[SERVER] ci_TURRET_LOCK_BS_DO_NOT_KICK - not kicking player from their current turret.")
|
|
// Don't kick player form current turret on fail.
|
|
ref_iResponseArray[ci_TURRET_RQST_TURRET] = TURRET_MANAGER_GET_TURRET_ID(player)
|
|
ref_iResponseArray[ci_TURRET_RQST_GRP] = ENUM_TO_INT(eCurrentGroupType)
|
|
ref_iResponseArray[ci_TURRET_RQST_INST] = TURRET_MANAGER_GET_INSTANCE_ID(player)
|
|
ELSE
|
|
// Respond with fail & kick from turret if they're in one.
|
|
ref_iResponseArray[ci_TURRET_RQST_TURRET] = -1
|
|
ref_iResponseArray[ci_TURRET_RQST_GRP] = ENUM_TO_INT(TGT_NONE)
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
// Assign response to serverBd
|
|
PRINT_TURRET_RQST(ref_iResponseArray)
|
|
TURRET_MANAGER_SERVER_SET_DATA(player, INT_TO_ENUM(TURRET_GROUP_TYPE, ref_iResponseArray[ci_TURRET_RQST_GRP]), ref_iResponseArray[ci_TURRET_RQST_INST], ref_iResponseArray[ci_TURRET_RQST_TURRET])
|
|
ENDPROC
|
|
|
|
FUNC TURRET_OCCUPANCY_DATA CONVERT_TURRET_REQUEST_DATA(INT& ref_iRequestArray[])
|
|
TURRET_OCCUPANCY_DATA data
|
|
IF COUNT_OF(ref_iRequestArray) < ci_TURRET_RQST_COUNT
|
|
ASSERTLN("CONVERT_TURRET_REQUEST_DATA int array too small")
|
|
RETURN data
|
|
ENDIF
|
|
|
|
data.iInstanceId = ref_iRequestArray[ci_TURRET_RQST_INST]
|
|
data.groupType = INT_TO_ENUM(TURRET_GROUP_TYPE, ref_iRequestArray[ci_TURRET_RQST_GRP])
|
|
data.iTurretId = ref_iRequestArray[ci_TURRET_RQST_TURRET]
|
|
RETURN data
|
|
ENDFUNC
|
|
|
|
PROC SAVE_TURRET_LOCK_RESPONSE(INT& ref_iResponseArray[])
|
|
IF COUNT_OF(ref_iResponseArray) < ci_TURRET_RQST_COUNT
|
|
ASSERTLN("SET_TURRET_REQUEST_RESPONSE Response int array too small")
|
|
EXIT
|
|
ENDIF
|
|
|
|
g_turretLockResponse = CONVERT_TURRET_REQUEST_DATA(ref_iResponseArray)
|
|
g_iTurretLockResponseUid = INT_TO_ENUM(TURRET_LOCK_REQUEST_ID, ref_iResponseArray[ci_TURRET_RQST_UID])
|
|
|
|
// No need to save response search settings
|
|
CDEBUG1LN(DEBUG_NET_TURRET, "SAVE_TURRET_LOCK_RESPONSE: ")
|
|
PRINT_TURRET_RQST(ref_iResponseArray)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Fill "ref_iRequestArray" with the data required for a turret request event.
|
|
///
|
|
PROC FILL_TURRET_REQUEST_DATA(TURRET_OCCUPANCY_DATA& ref_request, INT iUniqueId, TURRET_LOCK_SEARCH_TYPE eSearchType, INT iSettingsBs, INT& ref_iRequestArray[])
|
|
IF COUNT_OF(ref_iRequestArray) < ci_TURRET_RQST_COUNT
|
|
ASSERTLN("SET_TURRET_REQUEST_RESPONSE Request int array too small")
|
|
EXIT
|
|
ENDIF
|
|
|
|
ref_iRequestArray[ci_TURRET_RQST_UID] = iUniqueId
|
|
ref_iRequestArray[ci_TURRET_RQST_INST] = ref_request.iInstanceId
|
|
ref_iRequestArray[ci_TURRET_RQST_GRP] = ENUM_TO_INT(ref_request.groupType)
|
|
ref_iRequestArray[ci_TURRET_RQST_TURRET] = ref_request.iTurretId
|
|
ref_iRequestArray[ci_TURRET_RQST_SEARCH] = ENUM_TO_INT(eSearchType)
|
|
ref_iRequestArray[ci_TURRET_RQST_BS] = iSettingsBs
|
|
ENDPROC
|