Files
gtav-src/script/dev_ng/singleplayer/include/public/distributed_los.sch
T
2025-09-29 00:52:08 +02:00

216 lines
6.4 KiB
XML
Executable File

USING "commands_misc.sch"
USING "commands_debug.sch"
USING "buildtype.sch"
#IF IS_DEBUG_BUILD
USING "commands_pad.sch"
USING "script_debug_display.sch"
#ENDIF
ENUM SCRIPT_ENTITY_LOS_FLAGS
SCRIPTLOSFLAG_DEFAULT = 0,
SCRIPTLOSFLAG_IN_FRONT_ONLY = BIT1
ENDENUM
STRUCT SCRIPT_ENTITY_LOS_STRUCT
ENTITY_INDEX entity
ENTITY_INDEX target
SCRIPT_ENTITY_LOS_FLAGS eFlags
INT iLOSFlags
BOOL bHitThisFrame // used for cleaning up out of date queued calls
BOOL bResult // result of the test, this only changes when the distributed call is made, e.g. if last frame it got changed to true, it will remain true until the next code LOS is called
ENDSTRUCT
FUNC BOOL HAS_ENTITY_CLEAR_LOS_TO_ENTITY_DISTRIBUTED( SCRIPT_ENTITY_LOS_STRUCT &sData[], ENTITY_INDEX entity, ENTITY_INDEX target, SCRIPT_ENTITY_LOS_FLAGS eFlags = SCRIPTLOSFLAG_DEFAULT, INT iLOSFlags = LOS_FLAGS_LOS_TO_ENTITY )
INT i
INT iFreeSlot = -1
REPEAT COUNT_OF( sData ) i
// Ped pair found...
IF sData[i].entity = entity AND sData[i].target = target
sData[i].bHitThisFrame = TRUE
// ...return the currently stored result
RETURN sData[i].bResult
// ...not a matching pair, check if valid...
ELIF sData[i].entity = NULL
// ...not valid so store as free slot
IF iFreeSlot = -1
iFreeSlot = i
ENDIF
ENDIF
ENDREPEAT
// No ped pair found, find a spare slot and generate a new 1
IF iFreeSlot != -1
sData[iFreeSlot].entity = entity
sData[iFreeSlot].target = target
sData[iFreeSlot].eFlags = eFlags
sData[iFreeSlot].iLOSFlags = iLOSFlags
sData[iFreeSlot].bHitThisFrame = TRUE
sData[iFreeSlot].bResult = FALSE
// unable to find a free slot for the new test
ELSE
SCRIPT_ASSERT( "HAS_ENTITY_CLEAR_LOS_ENTITY_DISTRIBUTED() - Could not queue new LOS check, number of unique pairs exceedes sData array size, please increase your array size locally" )
ENDIF
RETURN FALSE
ENDFUNC
PROC UPDATE_SCRIPT_ENTITY_LOS_DISTRIBUTED_CHECKS( SCRIPT_ENTITY_LOS_STRUCT &sData[], INT &iCurrentIndex )
INT iLoopCount
// Check this is a valid queued check
IF sData[iCurrentIndex].entity != NULL AND DOES_ENTITY_EXIST( sData[iCurrentIndex].entity )
AND sData[iCurrentIndex].target != NULL AND DOES_ENTITY_EXIST( sData[iCurrentIndex].target )
AND sData[iCurrentIndex].bHitThisFrame
IF IS_BITMASK_ENUM_AS_ENUM_SET( sData[iCurrentIndex].eFlags, SCRIPTLOSFLAG_IN_FRONT_ONLY )
sData[iCurrentIndex].bResult = HAS_ENTITY_CLEAR_LOS_TO_ENTITY_IN_FRONT( sData[iCurrentIndex].entity, sData[iCurrentIndex].target )
ELSE
sData[iCurrentIndex].bResult = HAS_ENTITY_CLEAR_LOS_TO_ENTITY( sData[iCurrentIndex].entity, sData[iCurrentIndex].target, sData[iCurrentIndex].iLOSFlags )
ENDIF
ENDIF
// Find a new check to make
iLoopCount++
iCurrentIndex++
// Reset the index, we've overran the array
IF iCurrentIndex >= COUNT_OF( sData )
iCurrentIndex = 0
ENDIF
WHILE ( ( sData[iCurrentIndex].entity = NULL OR NOT DOES_ENTITY_EXIST( sData[iCurrentIndex].entity ) )
OR ( sData[iCurrentIndex].target = NULL OR NOT DOES_ENTITY_EXIST( sData[iCurrentIndex].target ) ) )
AND iLoopCount < COUNT_OF( sData ) // don't keep looking if everything in the array has been checked
iLoopCount++
iCurrentIndex++
// Reset the index, we've overran the array
IF iCurrentIndex >= COUNT_OF( sData )
iCurrentIndex = 0
ENDIF
ENDWHILE
// General queue cleanup
INT i
REPEAT COUNT_OF( sData ) i
// Not hit this frame so clean it up
IF NOT sData[i].bHitThisFrame
sData[i].entity = NULL
sData[i].target = NULL
sData[i].eFlags = SCRIPTLOSFLAG_DEFAULT
sData[i].iLOSFlags = 0
sData[i].bResult = FALSE
ENDIF
// Reset hit this frame check
sData[i].bHitThisFrame = FALSE
ENDREPEAT
ENDPROC
#IF IS_DEBUG_BUILD
TEXT_LABEL_23 TL_DEBUG_PAGE_DISTRIBUTED_LOS = "Distributed LOS"
PROC DEBUG_DISPLAY_DISTRIBUTED_LOS_INFO( DEBUG_DISPLAY &sDebug, SCRIPT_ENTITY_LOS_STRUCT &sData[], INT &iCurrentIndex )
DEBUG_DISPLAY_INT_THIS_FRAME( sDebug, "iCurrentIndex", iCurrentIndex, TL_DEBUG_PAGE_DISTRIBUTED_LOS )
DEBUG_DISPLAY_SPACE_THIS_FRAME( sDebug, TL_DEBUG_PAGE_DISTRIBUTED_LOS )
CONST_INT I_LOS_DEBUG_TABS_AFTER_ID 3
CONST_INT I_LOS_DEBUG_TABS_AFTER_ENTITY 3
CONST_INT I_LOS_DEBUG_TABS_AFTER_TARGET 3
CONST_INT I_LOS_DEBUG_TABS_AFTER_RESULT 5
INT i
TEXT_LABEL_63 str_debug_info
str_debug_info = "ID"
REPEAT I_LOS_DEBUG_TABS_AFTER_ID i
str_debug_info += " "
ENDREPEAT
str_debug_info += "Entity"
REPEAT I_LOS_DEBUG_TABS_AFTER_ENTITY i
str_debug_info += " "
ENDREPEAT
str_debug_info += "Target"
REPEAT I_LOS_DEBUG_TABS_AFTER_TARGET i
str_debug_info += " "
ENDREPEAT
str_debug_info += "Result"
REPEAT I_LOS_DEBUG_TABS_AFTER_RESULT i
str_debug_info += " "
ENDREPEAT
DEBUG_DISPLAY_STRING_THIS_FRAME( sDebug, str_debug_info, TL_DEBUG_PAGE_DISTRIBUTED_LOS )
DEBUG_DISPLAY_SPACE_THIS_FRAME( sDebug, TL_DEBUG_PAGE_DISTRIBUTED_LOS )
REPEAT COUNT_OF( sData ) i
INT j, iStringLength
IF DOES_ENTITY_EXIST( sData[i].entity )
TEXT_LABEL_63 str_temp
// ID
str_debug_info = ""
str_temp = i
str_debug_info += str_temp
iStringLength = GET_LENGTH_OF_LITERAL_STRING( str_temp )
REPEAT ( ( I_LOS_DEBUG_TABS_AFTER_ID + 2 ) - iStringLength ) j
str_debug_info += " "
ENDREPEAT
// Entity
str_temp = NATIVE_TO_INT( sData[i].entity )
str_debug_info += str_temp
iStringLength = GET_LENGTH_OF_LITERAL_STRING( str_temp )
REPEAT ( ( I_LOS_DEBUG_TABS_AFTER_ENTITY + 6 ) - iStringLength ) j
str_debug_info += " "
ENDREPEAT
// Target
str_temp = NATIVE_TO_INT( sData[i].target )
str_debug_info += str_temp
iStringLength = GET_LENGTH_OF_LITERAL_STRING( str_temp )
REPEAT ( ( I_LOS_DEBUG_TABS_AFTER_TARGET + 6 ) - iStringLength ) j
str_debug_info += " "
ENDREPEAT
// Result
IF sData[i].bResult
str_temp = "TRUE"
ELSE
str_temp = "FALSE"
ENDIF
str_debug_info += str_temp
iStringLength = GET_LENGTH_OF_LITERAL_STRING( str_temp )
REPEAT ( ( I_LOS_DEBUG_TABS_AFTER_RESULT + 6 ) -iStringLength ) j
str_debug_info += " "
ENDREPEAT
DEBUG_DISPLAY_STRING_THIS_FRAME( sDebug, str_debug_info, TL_DEBUG_PAGE_DISTRIBUTED_LOS )
ENDIF
ENDREPEAT
ENDPROC
#ENDIF