Files
gtav-src/script/dev_ng/singleplayer/scripts/Ambient/Misc/photographyMonkey.sc
T
2025-09-29 00:52:08 +02:00

1352 lines
54 KiB
Python
Executable File

//
// Photography Monkey
//
//
// Written by Simon Bramwell Date: 15/08/14
//
// The player must photograph a number of monkey mosaics around
// the map. Photographing all of them will unlock a random event.
//
//-------------------- INCLUDES --------------------
USING "rage_builtins.sch"
USING "globals.sch"
USING "cellphone_public.sch"
USING "commands_shapetest.sch"
USING "mission_stat_public.sch"
USING "replay_public.sch"
USING "random_events_public.sch"
//-------------------- STRUCTS --------------------
STRUCT MOSAIC_DATA
VECTOR vPos
VECTOR vNormal
FLOAT fWidth
FLOAT fHeight
#IF IS_DEBUG_BUILD
VECTOR vPlayerWarp
FLOAT fPlayerHeading
BLIP_INDEX blp
#ENDIF
ENDSTRUCT
//-------------------- CONSTS --------------------
CONST_INT NUM_MOSAICS 50
CONST_FLOAT MOSAIC_WIDTH 0.4
CONST_FLOAT MOSAIC_HEIGHT 0.3
CONST_FLOAT MOSAIC_RANGE 20.0
FLOAT MOSAIC_RANGE2 = MOSAIC_RANGE * MOSAIC_RANGE
CONST_FLOAT MIN_MOSAIC_WIDTH 0.08
CONST_FLOAT MIN_MOSAIC_HEIGHT 0.101
CONST_FLOAT VISIBILITY_POINT_RADIUS 0.01
CONST_FLOAT SCREEN_POSITION_MIN 0.05
CONST_FLOAT SCREEN_POSITION_MAX 0.95
CONST_FLOAT IGNORE_BORDER_AREA 0.35
//-------------------- MISC VARS --------------------
INT iBodyStage = 0
INT iCurrentMosaicIndex
INT iCenter = -1
INT iTopLeft = -1
INT iTopRight = -1
INT iBottomLeft = -1
INT iBottomRight = -1
MOSAIC_DATA mosaics[ NUM_MOSAICS ]
VECTOR vZero = <<0.0, 0.0, 0.0>>
INT iSplashStage = 0
SCALEFORM_INDEX sfMovie
BOOL bDrawSplash = FALSE
BOOL bIsBypassingSave
INT iTimer
//-------------------- DEBUG VARS --------------------
#IF IS_DEBUG_BUILD
// Widgets
// Main Group
WIDGET_GROUP_ID widMainGroup
BOOL bCreateDebugWidget = FALSE
BOOL bDisableScript = FALSE
BOOL bTerminateScript = FALSE
// Debug Group
WIDGET_GROUP_ID widDebugGroup
BOOL bDisplayInGameDebug
BOOL bIsDebugDrawingEnabled = FALSE
BOOL bBlipMosaics
BOOL bUnlockTrevorClothing
// Mosaic Group
WIDGET_GROUP_ID widMosaics
FLOAT fCurrentMosaicPosX
FLOAT fCurrentMosaicPosY
FLOAT fCurrentMosaicPosZ
FLOAT fCurrentMosaicNormalX
FLOAT fCurrentMosaicNormalY
FLOAT fCurrentMosaicNormalZ
FLOAT fCurrentMosaicOldNormalX
FLOAT fCurrentMosaicOldNormalY
FLOAT fCurrentMosaicOldNormalZ
FLOAT fCurrentMosaicWidth
FLOAT fCurrentMosaicHeight
FLOAT fCurrentMosaicWidthOld
FLOAT fCurrentMosaicHeightOld
FLOAT fCurrentMosaicAdjustAlongNormal
BOOL bCurrentMosaicDoAdjustAlongNormal
BOOL bSetAllMosaicsComplete
BOOL bSetAllMosaicsIncomplete
INT iMosaicSelector
INT iOldMosaicSelector = -1
BOOL bIsMosaicComplete
BOOL bSetMosaicComplete
BOOL bSetMosaicIncomplete
BOOL bSetPickerValsToCurrentMosaic
BOOL bSetPickerPosToCurrentMosaic
BOOL bSetPickerNormalToCurrentMosaic
BOOL bDumpMosaicDataToDebugFile
BOOL bInvertCurrentMosaicNormal
BOOL bAutoUpdateCurrentMosaicToClosestIncomplete
BOOL bUpdateCurrentMosaicToClosestIncomplete
BOOL bUnlockLastFortyNineMosaics
// Warp Group
WIDGET_GROUP_ID widPlayerWarp
INT iWarpPositionSelector
INT iOldWarpPositionSelector = -1
FLOAT fCurrentWarpX
FLOAT fCurrentWarpY
FLOAT fCurrentWarpZ
FLOAT fCurrentWarpHeading
BOOL bWarpPlayerToMosaic
BOOL bWarpPlayerToNextMosaic
BOOL bWarpPlayerToLastMosaic
BOOL bSaveCurrentPlayerWarpPosition
BOOL bDumpWarpDataToDebugFile
VECTOR vManualWarpPosition
BOOL bDoManualPlayerWarp
TEXT_WIDGET_ID twidManualWarpPosition
//Picker Group
WIDGET_GROUP_ID widPicker
SHAPETEST_INDEX stiPicker
FLOAT fPickerPosX
FLOAT fPickerPosY
FLOAT fPickerPosZ
FLOAT fPickerNormalX
FLOAT fPickerNormalY
FLOAT fPickerNormalZ
BOOL bRequestRunning
VECTOR vDebugTopLeft
VECTOR vDebugTopRight
VECTOR vDebugBottomLeft
VECTOR vDebugBottomRight
#ENDIF
//-------------------- MISC PROCS --------------------
PROC SET_ENTITY_COORD_AND_HEADING( ENTITY_INDEX entity, VECTOR vPos, FLOAT fHeading )
SET_ENTITY_COORDS( entity, vPos )
SET_ENTITY_HEADING( entity, fHeading )
ENDPROC
FUNC VECTOR NORMALIZE_VEC( VECTOR vec )
FLOAT fMag = VMAG( vec )
RETURN vec / fMag
ENDFUNC
FUNC BOOL IS_ENTITY_ALIVE( ENTITY_INDEX entity )
IF( DOES_ENTITY_EXIST( entity ) )
IF( NOT IS_ENTITY_DEAD( entity ) )
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
PROC CLEANUP_TRACKED_POINT( INT &iTrackedPoint )
IF( iTrackedPoint <> -1 )
DESTROY_TRACKED_POINT( iTrackedPoint )
iTrackedPoint = -1
ENDIF
ENDPROC
//-------------------- MOSAIC FLAG PROCS --------------------
#IF IS_DEBUG_BUILD
FUNC BOOL IS_VALID_MOSAIC_INDEX( INT index, STRING sCallerName )
IF( index >= 0 AND index < NUM_MOSAICS )
RETURN TRUE
ELSE
ASSERTLN( "IS_VALID_MOSAIC_INDEX ", index, " isn't a valid index! Called from ", sCallerName, "." )
RETURN FALSE
ENDIF
ENDFUNC
#ENDIF
PROC GET_FLAG_DATA_FOR_INDEX( INT index, INT &iArrayIndex, INT &iBitIndex )
iArrayIndex = index / 32
iBitIndex = index % 32
ENDPROC
FUNC BOOL IS_MOSAIC_COMPLETE( INT index )
#IF IS_DEBUG_BUILD
IF( IS_VALID_MOSAIC_INDEX( index, "IS_MOSAIC_COMPLETE" ) )
#ENDIF
INT iArrayIndex, iBitIndex
GET_FLAG_DATA_FOR_INDEX( index, iArrayIndex, iBitIndex )
RETURN IS_BIT_SET( g_SavedGlobals.sAmbient.iPhotographyMonkeyFlags[ iArrayIndex ], iBitIndex )
#IF IS_DEBUG_BUILD
ELSE
RETURN FALSE
ENDIF
#ENDIF
ENDFUNC
PROC SET_MOSAIC_COMPLETE( INT index, BOOL bComplete )
#IF IS_DEBUG_BUILD
IF( IS_VALID_MOSAIC_INDEX( index, "SET_MOSAIC_COMPLETE" ) )
#ENDIF
INT iArrayIndex, iBitIndex
GET_FLAG_DATA_FOR_INDEX( index, iArrayIndex, iBitIndex )
IF( bComplete )
SET_BIT( g_SavedGlobals.sAmbient.iPhotographyMonkeyFlags[ iArrayIndex ], iBitIndex )
ELSE
CLEAR_BIT( g_SavedGlobals.sAmbient.iPhotographyMonkeyFlags[ iArrayIndex ], iBitIndex )
ENDIF
#IF IS_DEBUG_BUILD
STRING sComplete
IF( bComplete )
sComplete = "complete"
ELSE
sComplete = "incomplete"
ENDIF
CPRINTLN( DEBUG_SIMON, " >>> photographyMonkey: Setting mosaic index ", index, " to ", sComplete )
iOldMosaicSelector = -1
ENDIF
#ENDIF
ENDPROC
#IF IS_DEBUG_BUILD
PROC DEBUG_SET_ALL_MOSAICS( BOOL bComplete )
INT i
FOR i = 0 TO NUM_MOSAICS - 1
SET_MOSAIC_COMPLETE( i, bComplete )
ENDFOR
ENDPROC
PROC DEBUG_SET_ALL_MOSAICS_INCOMPLETE()
DEBUG_SET_ALL_MOSAICS( FALSE )
ENDPROC
PROC DEBUG_SET_ALL_MOSAICS_COMPLETE()
DEBUG_SET_ALL_MOSAICS( TRUE )
ENDPROC
#ENDIF
PROC SET_ALL_MOSAICS_COMPLETE_FINAL()
g_SavedGlobals.sAmbient.iPhotographyMonkeyFlags[ 1 ] = -1
ENDPROC
FUNC BOOL ARE_ALL_MOSAICS_COMPLETE()
IF( g_SavedGlobals.sAmbient.iPhotographyMonkeyFlags[ 1 ] = -1 )
RETURN TRUE
ENDIF
INT iArrayIndex, iBitIndex
GET_FLAG_DATA_FOR_INDEX( NUM_MOSAICS - 1, iArrayIndex, iBitIndex )
IF( iArrayIndex > 0 )
INT i
FOR i = 0 TO iArrayIndex - 1
IF( g_SavedGlobals.sAmbient.iPhotographyMonkeyFlags[ i ] <> -1 )
RETURN FALSE
ENDIF
ENDFOR
ENDIF
IF( iBitIndex = 31 )
RETURN g_SavedGlobals.sAmbient.iPhotographyMonkeyFlags[ iArrayIndex ] = -1
ELSE
RETURN g_SavedGlobals.sAmbient.iPhotographyMonkeyFlags[ iArrayIndex ] = ROUND( POW( 2.0, TO_FLOAT( iBitIndex + 1 ) ) ) - 1
ENDIF
ENDFUNC
FUNC INT GET_NUM_MOSAICS_COMPLETED()
INT i
INT iNum = 0
REPEAT NUM_MOSAICS i
IF( IS_MOSAIC_COMPLETE( i ) )
iNum++
ENDIF
ENDREPEAT
RETURN iNum
ENDFUNC
//PURPOSE: Based on the position and normal of a mosaic, this proc extrapolates the four corners of the mosaic
PROC GET_MOSAIC_CORNER_COORDS( INT index, VECTOR &vTopLeft, VECTOR &vTopRight, VECTOR &vBottomLeft, VECTOR &vBottomRight )
VECTOR vPlayerPos = GET_ENTITY_COORDS( PLAYER_PED_ID(), FALSE )
VECTOR vPos
VECTOR vNormal
FLOAT fWidth
FLOAT fHeight
FLOAT fBoundsOffset = 0.01
IF( index = 29 AND vPlayerPos.z <= 35.0 )
vPos = <<-95.4020, -744.5060, 37.2165>>
vNormal = <<0.9047, 0.4261, 0.0000>>
fWidth = 0.5100
fHeight = 0.3500
ELIF( index = 29 AND vPlayerPos.z <= 36.0 )
vPos = <<-95.4013, -744.5073, 37.1846>>
vNormal = <<0.9047, 0.4261, 0.0000>>
fWidth = 0.5100
fHeight = 0.4300
ELSE
vPos = mosaics[ index ].vPos
vNormal = mosaics[ index ].vNormal
fWidth = mosaics[ index ].fWidth
fHeight = mosaics[ index ].fHeight
ENDIF
FLOAT fHalfWidth = fWidth / 2.0
FLOAT fHalfHeight = fHeight / 2.0
VECTOR vLeft = NORMALIZE_VEC( CROSS_PRODUCT( vNormal, <<0.0, 0.0, -1.0>> ) )
VECTOR vUp = NORMALIZE_VEC( CROSS_PRODUCT( vNormal, vLeft ) )
vTopLeft = vPos + fHalfWidth * vLeft + fHalfHeight * vUp + vNormal * fBoundsOffset
vTopRight = vPos + fHalfWidth * -vLeft + fHalfHeight * vUp + vNormal * fBoundsOffset
vBottomLeft = vPos + fHalfWidth * vLeft + fHalfHeight * -vUp + vNormal * fBoundsOffset
vBottomRight = vPos + fHalfWidth * -vLeft + fHalfHeight * -vUp + vNormal * fBoundsOffset
ENDPROC
//-------------------- MOSAIC DATA PROCS --------------------
PROC SET_MOSAIC_DATA( INT index, VECTOR vPos, VECTOR vNormal, FLOAT fWidth, FLOAT fHeight )
#IF IS_DEBUG_BUILD
IF( IS_VALID_MOSAIC_INDEX( index, "SET_MOSAIC_DATA" ) )
#ENDIF
mosaics[ index ].vPos = vPos
mosaics[ index ].vNormal = vNormal
mosaics[ index ].fWidth = fWidth
mosaics[ index ].fHeight = fHeight
#IF IS_DEBUG_BUILD
ENDIF
#ENDIF
ENDPROC
//PURPOSE: Iterates through the mosaic data to find the closest incomplete mosaic to the player
FUNC INT GET_CLOSEST_INCOMPLETE_MOSAIC_DATA_INDEX( FLOAT &fDist2 )
INT i
INT iCurrentClosestIndex = -1
VECTOR vPlayerPos = GET_ENTITY_COORDS( PLAYER_PED_ID(), FALSE )
REPEAT NUM_MOSAICS i
IF( NOT IS_MOSAIC_COMPLETE( i ) )
FLOAT fCurrentDist2 = VDIST2( vPlayerPos, mosaics[ i ].vPos )
IF( iCurrentClosestIndex = -1 OR fCurrentDist2 < fDist2 )
iCurrentClosestIndex = i
fDist2 = fCurrentDist2
ENDIF
ENDIF
ENDREPEAT
RETURN iCurrentClosestIndex
ENDFUNC
//PURPOSE: Iterates through the mosaic data to find the closest mosaic to the player
FUNC INT GET_CLOSEST_MOSAIC_DATA_INDEX( FLOAT &fDist2 )
INT i
INT iCurrentClosestIndex = -1
VECTOR vPlayerPos = GET_ENTITY_COORDS( PLAYER_PED_ID(), FALSE )
REPEAT NUM_MOSAICS i
FLOAT fCurrentDist2 = VDIST2( vPlayerPos, mosaics[ i ].vPos )
IF( iCurrentClosestIndex = -1 OR fCurrentDist2 < fDist2 )
iCurrentClosestIndex = i
fDist2 = fCurrentDist2
ENDIF
ENDREPEAT
RETURN iCurrentClosestIndex
ENDFUNC
//-------------------- DEBUG PROCS --------------------
#IF IS_DEBUG_BUILD
PROC DEBUG_SET_PLAYER_WARP_DATA( INT index, VECTOR vPos, FLOAT fHeading )
IF( IS_VALID_MOSAIC_INDEX( index, "DEBUG_SET_PLAYER_WARP_DATA" ) )
mosaics[ index ].vPlayerWarp = vPos
mosaics[ index ].fPlayerHeading = fHeading
ENDIF
ENDPROC
PROC DEBUG_SCRIPT_INIT()
CPRINTLN( DEBUG_SIMON, " >>> photographyMonkey: Starting" )
// Widget
IF( NOT DOES_WIDGET_GROUP_EXIST( widMainGroup ) )
widMainGroup = START_WIDGET_GROUP( "Photography Monkey" )
ADD_WIDGET_BOOL( "Disable Script", bDisableScript )
ADD_WIDGET_BOOL( "Terminate Script", bTerminateScript )
ADD_WIDGET_BOOL( "Create Debug", bCreateDebugWidget )
STOP_WIDGET_GROUP()
ENDIF
// Player Warp Init
DEBUG_SET_PLAYER_WARP_DATA( 0, <<157.6575, -1169.4952, 29.3317>>, 179.5758 )
DEBUG_SET_PLAYER_WARP_DATA( 1, <<1121.2115, -1273.9971, 20.6420>>, 323.1894 )
DEBUG_SET_PLAYER_WARP_DATA( 2, <<149.9654, -1186.3264, 31.3018>>, 15.7821 )
DEBUG_SET_PLAYER_WARP_DATA( 3, <<-145.9553, 232.8599, 94.9593>>, 154.7938 )
DEBUG_SET_PLAYER_WARP_DATA( 4, <<-1938.0144, -407.3192, 38.3179>>, 133.8270 )
DEBUG_SET_PLAYER_WARP_DATA( 5, <<2544.8982, 396.6932, 108.6168>>, 186.9946 )
DEBUG_SET_PLAYER_WARP_DATA( 6, <<-1102.6796, 2727.1716, 18.8004>>, 136.0167 )
DEBUG_SET_PLAYER_WARP_DATA( 7, <<203.7701, -2028.5157, 18.2723>>, 333.1616 )
DEBUG_SET_PLAYER_WARP_DATA( 8, <<1149.0546, -667.2332, 57.2968>>, 89.3821 )
DEBUG_SET_PLAYER_WARP_DATA( 9, <<-499.1074, -457.7401, 32.2324>>, 280.7153 )
DEBUG_SET_PLAYER_WARP_DATA( 10, <<1671.4944, 4976.0049, 42.3136>>, 228.6970 )
DEBUG_SET_PLAYER_WARP_DATA( 11, <<1513.5250, 3569.9678, 38.7365>>, 132.2058 )
DEBUG_SET_PLAYER_WARP_DATA( 12, <<87.4782, 212.2999, 118.3638>>, 68.6283 )
DEBUG_SET_PLAYER_WARP_DATA( 13, <<3416.5310, 3773.3933, 32.4373>>, 216.6341 )
DEBUG_SET_PLAYER_WARP_DATA( 14, <<-424.7196, 1090.4927, 332.5339>>, 261.2981 )
DEBUG_SET_PLAYER_WARP_DATA( 15, <<343.6494, 343.8360, 105.2013>>, 61.8742 )
DEBUG_SET_PLAYER_WARP_DATA( 16, <<-943.3699, 335.7236, 71.3724>>, 227.9662 )
DEBUG_SET_PLAYER_WARP_DATA( 17, <<-1826.4847, -1267.2061, 8.6183>>, 70.9242 )
DEBUG_SET_PLAYER_WARP_DATA( 18, <<-1171.1685, -2035.1980, 12.5394>>, 313.6541 )
DEBUG_SET_PLAYER_WARP_DATA( 19, <<-343.7831, -2277.1079, 6.6082>>, 69.0278 )
DEBUG_SET_PLAYER_WARP_DATA( 20, <<1729.7319, 4779.2144, 41.8836>>, 74.2863 )
DEBUG_SET_PLAYER_WARP_DATA( 21, <<2398.0562, 3140.8318, 48.1583>>, 64.1248 )
DEBUG_SET_PLAYER_WARP_DATA( 22, <<561.7291, -553.0900, 24.9653>>, 64.1156 )
DEBUG_SET_PLAYER_WARP_DATA( 23, <<285.2345, -475.4806, 34.1944>>, 121.8393 )
DEBUG_SET_PLAYER_WARP_DATA( 24, <<-805.2684, -2748.7278, 13.9444>>, 78.9389 )
DEBUG_SET_PLAYER_WARP_DATA( 25, <<354.4799, 3394.3228, 36.4034>>, 21.1326 )
DEBUG_SET_PLAYER_WARP_DATA( 26, <<474.9942, -1473.1755, 35.0911>>, 4.5510 )
DEBUG_SET_PLAYER_WARP_DATA( 27, <<-463.6809, -1453.6027, 20.6896>>, 34.1839 )
DEBUG_SET_PLAYER_WARP_DATA( 28, <<-1372.5725, -527.6714, 30.3637>>, 312.5001 )
DEBUG_SET_PLAYER_WARP_DATA( 29, <<-91.4214, -739.1796, 34.3956>>, 138.9684 )
DEBUG_SET_PLAYER_WARP_DATA( 30, <<-1985.3969, 4524.0142, 18.4844>>, 152.2984 )
DEBUG_SET_PLAYER_WARP_DATA( 31, <<556.1956, 2805.6797, 42.2620>>, 185.0993 )
DEBUG_SET_PLAYER_WARP_DATA( 32, <<1911.4100, 3733.7874, 32.5985>>, 314.2173 )
DEBUG_SET_PLAYER_WARP_DATA( 33, <<756.5193, -1858.1405, 49.2917>>, 128.5731 )
DEBUG_SET_PLAYER_WARP_DATA( 34, <<1573.1057, -2131.4221, 77.5809>>, 102.3110 )
DEBUG_SET_PLAYER_WARP_DATA( 35, <<893.2689, 3616.2092, 32.8242>>, 356.5662 )
DEBUG_SET_PLAYER_WARP_DATA( 36, <<-251.5453, 6233.4341, 30.4895>>, 46.2427 )
DEBUG_SET_PLAYER_WARP_DATA( 37, <<1243.8982, -3319.3240, 6.0288>>, 64.4201 )
DEBUG_SET_PLAYER_WARP_DATA( 38, <<-1380.4294, -900.7247, 12.6415>>, 162.9606 )
DEBUG_SET_PLAYER_WARP_DATA( 39, <<-1676.5216, 172.3334, 62.2120>>, 75.5843 )
DEBUG_SET_PLAYER_WARP_DATA( 40, <<251.8970, -3313.5427, 5.7901>>, 26.5106 )
DEBUG_SET_PLAYER_WARP_DATA( 41, <<164.3925, 6665.3047, 33.7604>>, 144.7494 )
DEBUG_SET_PLAYER_WARP_DATA( 42, <<-1380.1357, -359.2155, 41.6399>>, 210.5456 )
DEBUG_SET_PLAYER_WARP_DATA( 43, <<-1707.8241, -262.6126, 51.9987>>, 213.1819 )
DEBUG_SET_PLAYER_WARP_DATA( 44, <<-1281.3966, -1618.0881, 4.0922>>, 339.1241 )
DEBUG_SET_PLAYER_WARP_DATA( 45, <<-1037.7791, -157.6559, 38.1444>>, 247.0832 )
DEBUG_SET_PLAYER_WARP_DATA( 46, <<589.8178, 139.6559, 104.2482>>, 338.2063 )
DEBUG_SET_PLAYER_WARP_DATA( 47, <<-467.4771, -19.2029, 52.4705>>, 293.5864 )
DEBUG_SET_PLAYER_WARP_DATA( 48, <<-956.5139, -772.5125, 16.7941>>, 171.1109 )
DEBUG_SET_PLAYER_WARP_DATA( 49, <<-815.7625, -1258.3035, 5.5157>>, 326.9828 )
ENDPROC
PROC DEBUG_DUMP_VECTOR_TO_DEBUG_FILE( VECTOR vec )
SAVE_STRING_TO_DEBUG_FILE( "<<" )
SAVE_FLOAT_TO_DEBUG_FILE( vec.x )
SAVE_STRING_TO_DEBUG_FILE( ", " )
SAVE_FLOAT_TO_DEBUG_FILE( vec.y )
SAVE_STRING_TO_DEBUG_FILE( ", " )
SAVE_FLOAT_TO_DEBUG_FILE( vec.z )
SAVE_STRING_TO_DEBUG_FILE( ">>" )
ENDPROC
PROC DEBUG_DUMP_WARP_DATA_TO_DEBUG_FILE()
IF( OPEN_DEBUG_FILE() )
SAVE_NEWLINE_TO_DEBUG_FILE()
INT i
REPEAT NUM_MOSAICS i
SAVE_STRING_TO_DEBUG_FILE( "DEBUG_SET_PLAYER_WARP_DATA( " )
SAVE_INT_TO_DEBUG_FILE( i )
SAVE_STRING_TO_DEBUG_FILE( ", " )
DEBUG_DUMP_VECTOR_TO_DEBUG_FILE( mosaics[ i ].vPlayerWarp )
SAVE_STRING_TO_DEBUG_FILE( ", " )
SAVE_FLOAT_TO_DEBUG_FILE( mosaics[ i ].fPlayerHeading )
SAVE_STRING_TO_DEBUG_FILE( " )" )
SAVE_NEWLINE_TO_DEBUG_FILE()
ENDREPEAT
CLOSE_DEBUG_FILE()
ENDIF
ENDPROC
PROC DEBUG_DUMP_MOSAIC_DATA_TO_DEBUG_FILE()
IF( OPEN_DEBUG_FILE() )
SAVE_NEWLINE_TO_DEBUG_FILE()
INT i
REPEAT NUM_MOSAICS i
SAVE_STRING_TO_DEBUG_FILE( "SET_MOSAIC_DATA( " )
SAVE_INT_TO_DEBUG_FILE( i )
SAVE_STRING_TO_DEBUG_FILE( ", " )
DEBUG_DUMP_VECTOR_TO_DEBUG_FILE( mosaics[ i ].vPos )
SAVE_STRING_TO_DEBUG_FILE( ", " )
DEBUG_DUMP_VECTOR_TO_DEBUG_FILE( mosaics[ i ].vNormal )
SAVE_STRING_TO_DEBUG_FILE( ", " )
SAVE_FLOAT_TO_DEBUG_FILE( mosaics[ i ].fWidth )
SAVE_STRING_TO_DEBUG_FILE( ", " )
SAVE_FLOAT_TO_DEBUG_FILE( mosaics[ i ].fHeight )
SAVE_STRING_TO_DEBUG_FILE( " )" )
SAVE_NEWLINE_TO_DEBUG_FILE()
ENDREPEAT
CLOSE_DEBUG_FILE()
ENDIF
ENDPROC
//PURPOSE: Updates a picker which gives the world coords and normal of a vertex when the user left clicks the mouse
PROC DEBUG_UPDATE_PICKER()
IF( bRequestRunning )
INT iHitSomething
VECTOR vPos
VECTOR vNormal
ENTITY_INDEX entity
SHAPETEST_STATUS status
status = GET_SHAPE_TEST_RESULT( stiPicker, iHitSomething, vPos, vNormal, entity )
IF( status = SHAPETEST_STATUS_RESULTS_READY )
IF( iHitSomething = 1 )
vNormal = NORMALIZE_VEC( vNormal )
fPickerNormalX = vNormal.x
fPickerNormalY = vNormal.y
fPickerNormalZ = vNormal.z
bRequestRunning = FALSE
ENDIF
ENDIF
IF( status = SHAPETEST_STATUS_NONEXISTENT )
bRequestRunning = FALSE
ENDIF
ELSE
IF( IS_MOUSE_BUTTON_PRESSED( MB_LEFT_BTN ) )
VECTOR vPickerPos = GET_SCRIPT_MOUSE_POINTER_IN_WORLD_COORDS()
VECTOR vCamPos
IF( IS_CAM_ACTIVE( GET_DEBUG_CAM() ) )
vCamPos = GET_CAM_COORD( GET_DEBUG_CAM() )
ELSE
vCamPos = GET_GAMEPLAY_CAM_COORD()
ENDIF
VECTOR vFromPickerToCam = NORMALIZE_VEC( vCamPos - vPickerPos )
VECTOR vStartTest = vPickerPos + vFromPickerToCam * 0.2
VECTOR vEndTest = vPickerPos - vFromPickerToCam * 0.2
stiPicker = START_SHAPE_TEST_LOS_PROBE( vStartTest, vEndTest, SCRIPT_INCLUDE_ALL )
fPickerPosX = vPickerPos.x
fPickerPosY = vPickerPos.y
fPickerPosZ = vPickerPos.z
bRequestRunning = TRUE
ENDIF
ENDIF
ENDPROC
PROC DEBUG_DRAW_PICKER()
VECTOR vPickerPos = <<fPickerPosX, fPickerPosY, fPickerPosZ>>
VECTOR vPickerNormal = <<fPickerNormalX, fPickerNormalY, fPickerNormalZ>>
DRAW_DEBUG_SPHERE( vPickerPos, 0.02, 0, 0, 255, 255 )
DRAW_DEBUG_LINE( vPickerPos, vPickerPos + 1.0 * vPickerNormal, 255, 255, 255, 255 )
ENDPROC
PROC DEBUG_DRAW()
VECTOR vPos = mosaics[ iMosaicSelector ].vPos
VECTOR vNormalEnd = mosaics[ iMosaicSelector ].vPos + 0.5 * mosaics[ iMosaicSelector ].vNormal
// position of mosaic
IF( IS_MOSAIC_COMPLETE( iMosaicSelector ) )
DRAW_DEBUG_SPHERE( vPos, 0.02, 0, 255, 0, 100 )
ELSE
DRAW_DEBUG_SPHERE( vPos, 0.02, 255, 0, 0, 100 )
ENDIF
// mosaic normal
DRAW_DEBUG_LINE( vPos, vNormalEnd, 255, 0, 0, 255 )
// mosaic bounds
DRAW_DEBUG_LINE( vDebugTopLeft, vDebugTopRight, 255, 255, 255, 255 )
DRAW_DEBUG_LINE( vDebugTopRight, vDebugBottomRight, 255, 255, 255, 255 )
DRAW_DEBUG_LINE( vDebugBottomRight, vDebugBottomLeft, 255, 255, 255, 255 )
DRAW_DEBUG_LINE( vDebugBottomLeft, vDebugTopLeft, 255, 255, 255, 255 )
DRAW_DEBUG_SPHERE( vPos, VISIBILITY_POINT_RADIUS )
DRAW_DEBUG_SPHERE( vDebugTopLeft, VISIBILITY_POINT_RADIUS )
DRAW_DEBUG_SPHERE( vDebugTopRight, VISIBILITY_POINT_RADIUS )
DRAW_DEBUG_SPHERE( vDebugBottomLeft, VISIBILITY_POINT_RADIUS )
DRAW_DEBUG_SPHERE( vDebugBottomRight, VISIBILITY_POINT_RADIUS )
ENDPROC
FUNC BOOL DEBUG_CONVERT_SUB_STRING_TO_FLOAT( STRING str, INT iStart, INT iEnd, FLOAT &fResult )
IF( NOT IS_STRING_NULL_OR_EMPTY( str ) )
INT i = iEnd - 1
FLOAT fBase = 0.01
WHILE( i <> iStart - 1 )
STRING sChar = GET_STRING_FROM_STRING( str, i, i + 1 )
INT iCharAsInt = -1
BOOL bIsCharNumber = STRING_TO_INT( sChar, iCharAsInt )
IF( NOT bIsCharNumber )
BOOL bCharIsMinus = ARE_STRINGS_EQUAL( sChar, "-" )
BOOL bCharIsPoint = ARE_STRINGS_EQUAL( sChar, "." )
IF( bCharIsMinus )
fResult *= -1.0
ELIF( NOT bCharIsPoint )
RETURN FALSE
ENDIF
ELSE
fResult += TO_FLOAT( iCharAsInt ) * fBase
fBase *= 10.0
ENDIF
i--
ENDWHILE
ELSE
RETURN FALSE
ENDIF
RETURN TRUE
ENDFUNC
// expected form of string should have the following criteria
// - only consists of numerals 0-9, decimal points, minus signs and commas
// - no spaces
// - 2 numeral after the decimal point
// - three decimals separated by commas
// e.g. -0123.45,-0123.45,-0123.45
FUNC BOOL DEBUG_CONVERT_STRING_POSITION_TO_VECTOR( STRING str, VECTOR &vResult )
IF( NOT IS_STRING_NULL_OR_EMPTY( str ) )
INT iLength = GET_LENGTH_OF_LITERAL_STRING( str )
INT iStart = 0
BOOL bxSet = FALSE
BOOL bySet = FALSE
INT i
FOR i = 0 TO iLength
BOOL bCharIsComma = FALSE
BOOL bIsLastChar = ( i = iLength )
IF( NOT bIsLastChar )
STRING sChar = GET_STRING_FROM_STRING( str, i, i + 1 )
bCharIsComma = ARE_STRINGS_EQUAL( sChar, "," )
ENDIF
IF( bCharIsComma OR bIsLastChar )
FLOAT fComp = 0.0
IF( DEBUG_CONVERT_SUB_STRING_TO_FLOAT( str, iStart, i, fComp ) )
IF( NOT bxSet )
vResult.x = fComp
iStart = i + 1
bxSet = TRUE
ELIF( NOT bySet )
vResult.y = fComp
iStart = i + 1
bySet = TRUE
ELSE
vResult.z = fComp
RETURN TRUE
ENDIF
ELSE
RETURN FALSE
ENDIF
ENDIF
ENDFOR
ENDIF
RETURN FALSE
ENDFUNC
//PURPOSE: Mainly handles the widget update logic
PROC DEBUG_SCRIPT_UPDATE()
IF( bTerminateScript )
CPRINTLN( DEBUG_SIMON, " >>> photographyMonkey is being terminated by the user" )
TERMINATE_THIS_THREAD()
ENDIF
// Debug Widgets
// make sure debug is switched on when XML is selected
IF( g_bDebugJumpToMosaic )
bCreateDebugWidget = TRUE
ENDIF
IF( g_bDebugCompleteAllMosaics )
DEBUG_SET_ALL_MOSAICS_COMPLETE()
SET_RANDOM_EVENT_AVAILABLE( RE_MONKEYPHOTO, TRUE )
g_bDebugCompleteAllMosaics = FALSE
MAKE_AUTOSAVE_REQUEST()
TERMINATE_THIS_THREAD()
ENDIF
IF( bCreateDebugWidget )
IF( NOT DOES_WIDGET_GROUP_EXIST( widDebugGroup ) )
SET_CURRENT_WIDGET_GROUP( widMainGroup )
widDebugGroup = START_WIDGET_GROUP( "Debug" )
ADD_WIDGET_BOOL( "Display In Game Debug", bDisplayInGameDebug )
ADD_WIDGET_BOOL( "Toggle Blip Mosaics", bBlipMosaics )
ADD_WIDGET_BOOL( "Unlock Trevor Clothing", bUnlockTrevorClothing )
STOP_WIDGET_GROUP()
CLEAR_CURRENT_WIDGET_GROUP( widMainGroup )
SET_CURRENT_WIDGET_GROUP( widDebugGroup )
widMosaics = START_WIDGET_GROUP( "Mosaics" )
ADD_WIDGET_INT_SLIDER( "Select Mosaic", iMosaicSelector, 0, NUM_MOSAICS - 1, 1 )
ADD_WIDGET_FLOAT_SLIDER( "Selected Mosaic Pos X", fCurrentMosaicPosX, -10000.0, 10000.0, 0.5 )
ADD_WIDGET_FLOAT_SLIDER( "Selected Mosaic Pos Y", fCurrentMosaicPosY, -10000.0, 10000.0, 0.5 )
ADD_WIDGET_FLOAT_SLIDER( "Selected Mosaic Pos Z", fCurrentMosaicPosZ, -10000.0, 10000.0, 0.5 )
ADD_WIDGET_FLOAT_SLIDER( "Selected Mosaic Normal X", fCurrentMosaicNormalX, -1.0, 1.0, 0.01 )
ADD_WIDGET_FLOAT_SLIDER( "Selected Mosaic Normal Y", fCurrentMosaicNormalY, -1.0, 1.0, 0.01 )
ADD_WIDGET_FLOAT_SLIDER( "Selected Mosaic Normal Z", fCurrentMosaicNormalZ, -1.0, 1.0, 0.01 )
ADD_WIDGET_FLOAT_SLIDER( "Selected Mosaic Width", fCurrentMosaicWidth, 0.0, 3.0, 0.01 )
ADD_WIDGET_FLOAT_SLIDER( "Selected Mosaic Height", fCurrentMosaicHeight, 0.0, 3.0, 0.01 )
ADD_WIDGET_FLOAT_SLIDER( "Selected Mosaic Adjust Along Normal", fCurrentMosaicAdjustAlongNormal, -1.0, 1.0, 0.01 )
ADD_WIDGET_BOOL( "Do Selected Mosaic Adjust Along Normal", bCurrentMosaicDoAdjustAlongNormal )
ADD_WIDGET_BOOL( "Is Mosaic Complete", bIsMosaicComplete )
ADD_WIDGET_BOOL( "Set Mosaic Complete", bSetMosaicComplete )
ADD_WIDGET_BOOL( "Set Mosaic Incomplete", bSetMosaicIncomplete )
ADD_WIDGET_BOOL( "Set All Mosaics Complete", bSetAllMosaicsComplete )
ADD_WIDGET_BOOL( "Set All Mosaics Incomplete", bSetAllMosaicsIncomplete )
ADD_WIDGET_BOOL( "Set Selected Mosaic To Current Picker Values", bSetPickerValsToCurrentMosaic )
ADD_WIDGET_BOOL( "Set Selected Mosaic To Current Picker Position", bSetPickerPosToCurrentMosaic )
ADD_WIDGET_BOOL( "Set Selected Mosaic To Current Picker Normal", bSetPickerNormalToCurrentMosaic )
ADD_WIDGET_BOOL( "Dump Mosaic Data To Debug File", bDumpMosaicDataToDebugFile )
ADD_WIDGET_BOOL( "Invert Current Mosaic Normal", bInvertCurrentMosaicNormal )
ADD_WIDGET_BOOL( "Auto Update Current Mosaic To Closest Incomplete Mosaic", bAutoUpdateCurrentMosaicToClosestIncomplete )
ADD_WIDGET_BOOL( "Update Current Mosaic To Closest Incomplete Mosaic", bUpdateCurrentMosaicToClosestIncomplete )
ADD_WIDGET_BOOL( "Unlock Last Forty Nine Mosaics", bUnlockLastFortyNineMosaics )
STOP_WIDGET_GROUP()
CLEAR_CURRENT_WIDGET_GROUP( widDebugGroup )
SET_CURRENT_WIDGET_GROUP( widDebugGroup )
widPlayerWarp = START_WIDGET_GROUP( "Player Warp" )
ADD_WIDGET_INT_SLIDER( "Select Warp Position", iWarpPositionSelector, 0, NUM_MOSAICS - 1, 1 )
ADD_WIDGET_FLOAT_SLIDER( "Selected Warp X", fCurrentWarpX, -10000.0, 10000.0, 0.5 )
ADD_WIDGET_FLOAT_SLIDER( "Selected Warp Y", fCurrentWarpY, -10000.0, 10000.0, 0.5 )
ADD_WIDGET_FLOAT_SLIDER( "Selected Warp Z", fCurrentWarpZ, -10000.0, 10000.0, 0.5 )
ADD_WIDGET_FLOAT_SLIDER( "Selected Warp Heading", fCurrentWarpHeading, -360.0, 360.0, 0.5 )
ADD_WIDGET_BOOL( "Warp Player To Mosaic", bWarpPlayerToMosaic )
ADD_WIDGET_BOOL( "Warp Player To Next Mosaic", bWarpPlayerToNextMosaic )
ADD_WIDGET_BOOL( "Warp Player To Last Mosaic", bWarpPlayerToLastMosaic )
ADD_WIDGET_BOOL( "Save Current Player Position As Selected Warp Position", bSaveCurrentPlayerWarpPosition )
ADD_WIDGET_BOOL( "Dump Warp Data To Debug File", bDumpWarpDataToDebugFile )
ADD_WIDGET_VECTOR_SLIDER( "Manual Warp Position", vManualWarpPosition, -10000.0, 10000.0, 0.5 )
ADD_WIDGET_BOOL( "Warp Player To Manual Position", bDoManualPlayerWarp )
twidManualWarpPosition = ADD_TEXT_WIDGET( "Manual Warp Position String" )
STOP_WIDGET_GROUP()
SET_CONTENTS_OF_TEXT_WIDGET( twidManualWarpPosition, "Ready" )
CLEAR_CURRENT_WIDGET_GROUP( widDebugGroup )
SET_CURRENT_WIDGET_GROUP( widDebugGroup )
widPicker = START_WIDGET_GROUP( "Picker" )
ADD_WIDGET_FLOAT_SLIDER( "Picker Pos X", fPickerPosX, -10000.0, 10000.0, 0.5 )
ADD_WIDGET_FLOAT_SLIDER( "Picker Pos Y", fPickerPosY, -10000.0, 10000.0, 0.5 )
ADD_WIDGET_FLOAT_SLIDER( "Picker Pos Y", fPickerPosZ, -10000.0, 10000.0, 0.5 )
ADD_WIDGET_FLOAT_SLIDER( "Picker Normal X", fPickerNormalX, -10000.0, 10000.0, 0.5 )
ADD_WIDGET_FLOAT_SLIDER( "Picker Normal Y", fPickerNormalY, -10000.0, 10000.0, 0.5 )
ADD_WIDGET_FLOAT_SLIDER( "Picker Normal Z", fPickerNormalZ, -10000.0, 10000.0, 0.5 )
STOP_WIDGET_GROUP()
CLEAR_CURRENT_WIDGET_GROUP( widDebugGroup )
ENDIF
DEBUG_UPDATE_PICKER()
DEBUG_DRAW_PICKER()
// Debug
IF( bDisplayInGameDebug ) // for the currently selected mosaic
IF( NOT bIsDebugDrawingEnabled )
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE( TRUE )
bIsDebugDrawingEnabled = TRUE
ENDIF
GET_MOSAIC_CORNER_COORDS( iMosaicSelector, vDebugTopLeft, vDebugTopRight, vDebugBottomLeft, vDebugBottomRight )
DEBUG_DRAW()
ELSE
IF( bIsDebugDrawingEnabled )
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE( FALSE )
bIsDebugDrawingEnabled = FALSE
ENDIF
ENDIF
IF( bBlipMosaics )
INT i
REPEAT NUM_MOSAICS i
INT iColour
IF( IS_MOSAIC_COMPLETE( i ) )
iColour = BLIP_COLOUR_GREEN
ELSE
iColour = BLIP_COLOUR_RED
ENDIF
IF( NOT DOES_BLIP_EXIST( mosaics[ i ].blp ) )
mosaics[ i ].blp = CREATE_BLIP_FOR_COORD( mosaics[ i ].vPos, FALSE )
ENDIF
SET_BLIP_COLOUR( mosaics[ i ].blp, iColour )
IF( iMosaicSelector <> iOldMosaicSelector )
SET_BLIP_ROUTE( mosaics[ i ].blp, i = iMosaicSelector )
ENDIF
ENDREPEAT
ELSE
INT i
REPEAT NUM_MOSAICS i
IF( DOES_BLIP_EXIST( mosaics[ i ].blp ) )
REMOVE_BLIP( mosaics[ i ].blp )
ENDIF
ENDREPEAT
ENDIF
IF( bUnlockTrevorClothing )
UNLOCK_SPACE_MONKEY_CLOTHES_FOR_TREVOR()
bUnlockTrevorClothing = FALSE
ENDIF
// Mosaics
IF( bSetAllMosaicsComplete )
DEBUG_SET_ALL_MOSAICS_COMPLETE()
iOldMosaicSelector = -1
bSetAllMosaicsComplete = FALSE
ENDIF
IF( bSetAllMosaicsIncomplete )
DEBUG_SET_ALL_MOSAICS_INCOMPLETE()
iOldMosaicSelector = -1
bSetAllMosaicsIncomplete = FALSE
ENDIF
IF( iMosaicSelector <> iOldMosaicSelector )
iOldMosaicSelector = iMosaicSelector
bIsMosaicComplete = IS_MOSAIC_COMPLETE( iMosaicSelector )
fCurrentMosaicPosX = mosaics[ iMosaicSelector ].vPos.x
fCurrentMosaicPosY = mosaics[ iMosaicSelector ].vPos.y
fCurrentMosaicPosZ = mosaics[ iMosaicSelector ].vPos.z
fCurrentMosaicNormalX = mosaics[ iMosaicSelector ].vNormal.x
fCurrentMosaicNormalY = mosaics[ iMosaicSelector ].vNormal.y
fCurrentMosaicNormalZ = mosaics[ iMosaicSelector ].vNormal.z
fCurrentMosaicWidth = mosaics[ iMosaicSelector ].fWidth
fCurrentMosaicHeight = mosaics[ iMosaicSelector ].fHeight
ENDIF
IF( fCurrentMosaicNormalX <> fCurrentMosaicOldNormalX
OR fCurrentMosaicNormalY <> fCurrentMosaicOldNormalY
OR fCurrentMosaicNormalZ <> fCurrentMosaicOldNormalZ )
fCurrentMosaicOldNormalX = fCurrentMosaicNormalX
fCurrentMosaicOldNormalY = fCurrentMosaicNormalY
fCurrentMosaicOldNormalZ = fCurrentMosaicNormalZ
mosaics[ iMosaicSelector ].vNormal.x = fCurrentMosaicNormalX
mosaics[ iMosaicSelector ].vNormal.y = fCurrentMosaicNormalY
mosaics[ iMosaicSelector ].vNormal.z = fCurrentMosaicNormalZ
ENDIF
IF( fCurrentMosaicWidthOld <> fCurrentMosaicWidth )
fCurrentMosaicWidthOld = fCurrentMosaicWidth
mosaics[ iMosaicSelector ].fWidth = fCurrentMosaicWidth
ENDIF
IF( fCurrentMosaicHeightOld <> fCurrentMosaicHeight )
fCurrentMosaicHeightOld = fCurrentMosaicHeight
mosaics[ iMosaicSelector ].fHeight = fCurrentMosaicHeight
ENDIF
IF( bCurrentMosaicDoAdjustAlongNormal )
mosaics[ iMosaicSelector ].vPos += fCurrentMosaicAdjustAlongNormal * mosaics[ iMosaicSelector ].vNormal
iOldMosaicSelector = -1
fCurrentMosaicAdjustAlongNormal = 0.0
bCurrentMosaicDoAdjustAlongNormal = FALSE
ENDIF
IF( bSetMosaicComplete )
SET_MOSAIC_COMPLETE( iMosaicSelector, TRUE )
iOldMosaicSelector = -1
bSetMosaicComplete = FALSE
ENDIF
IF( bSetMosaicIncomplete )
SET_MOSAIC_COMPLETE( iMosaicSelector, FALSE )
iOldMosaicSelector = -1
bSetMosaicIncomplete = FALSE
ENDIF
IF( bSetPickerValsToCurrentMosaic )
mosaics[ iMosaicSelector ].vPos.x = fPickerPosX
mosaics[ iMosaicSelector ].vPos.y = fPickerPosY
mosaics[ iMosaicSelector ].vPos.z = fPickerPosZ
mosaics[ iMosaicSelector ].vNormal.x = fPickerNormalX
mosaics[ iMosaicSelector ].vNormal.y = fPickerNormalY
mosaics[ iMosaicSelector ].vNormal.z = fPickerNormalZ
iOldMosaicSelector = -1
ENDIF
IF( bSetPickerPosToCurrentMosaic )
mosaics[ iMosaicSelector ].vPos.x = fPickerPosX
mosaics[ iMosaicSelector ].vPos.y = fPickerPosY
mosaics[ iMosaicSelector ].vPos.z = fPickerPosZ
iOldMosaicSelector = -1
bSetPickerPosToCurrentMosaic = FALSE
ENDIF
IF( bSetPickerNormalToCurrentMosaic )
mosaics[ iMosaicSelector ].vNormal.x = fPickerNormalX
mosaics[ iMosaicSelector ].vNormal.y = fPickerNormalY
mosaics[ iMosaicSelector ].vNormal.z = fPickerNormalZ
iOldMosaicSelector = -1
bSetPickerNormalToCurrentMosaic = FALSE
ENDIF
IF( bDumpMosaicDataToDebugFile )
DEBUG_DUMP_MOSAIC_DATA_TO_DEBUG_FILE()
bDumpMosaicDataToDebugFile = FALSE
ENDIF
IF( bInvertCurrentMosaicNormal )
mosaics[ iMosaicSelector ].vNormal *= -1.0
bInvertCurrentMosaicNormal = FALSE
ENDIF
IF( bAutoUpdateCurrentMosaicToClosestIncomplete )
IF( IS_MOSAIC_COMPLETE( iMosaicSelector ) )
FLOAT fDist2
INT iIndex = GET_CLOSEST_INCOMPLETE_MOSAIC_DATA_INDEX( fDist2 )
IF( iIndex <> -1 )
iMosaicSelector = iIndex
ELSE
bAutoUpdateCurrentMosaicToClosestIncomplete = FALSE
ENDIF
ENDIF
ENDIF
IF( bUpdateCurrentMosaicToClosestIncomplete )
FLOAT fDist2
INT iIndex = GET_CLOSEST_INCOMPLETE_MOSAIC_DATA_INDEX( fDist2 )
IF( iIndex <> -1 )
iMosaicSelector = iIndex
ENDIF
bUpdateCurrentMosaicToClosestIncomplete = FALSE
ENDIF
IF( bUnlockLastFortyNineMosaics )
INT i
FOR i = 1 TO 49
SET_MOSAIC_COMPLETE( i, TRUE )
ENDFOR
bUnlockLastFortyNineMosaics = FALSE
ENDIF
// Warp Player
// Checks for XML warping
IF( g_bDebugJumpToMosaic )
IF( g_iDebugMosaicToJumpTo < 0 )
g_iDebugMosaicToJumpTo = 0
ELIF( g_iDebugMosaicToJumpTo >= NUM_MOSAICS )
g_iDebugMosaicToJumpTo = NUM_MOSAICS - 1
ENDIF
g_bDebugJumpToMosaic = ( g_iDebugMosaicToJumpTo <> iWarpPositionSelector )
bWarpPlayerToMosaic = TRUE
ENDIF
// Widget checks
IF( iWarpPositionSelector <> iOldWarpPositionSelector OR g_bDebugJumpToMosaic )
IF( g_bDebugJumpToMosaic )
iWarpPositionSelector = g_iDebugMosaicToJumpTo
g_bDebugJumpToMosaic = FALSE
ENDIF
iOldWarpPositionSelector = iWarpPositionSelector
g_iDebugMosaicToJumpTo = iWarpPositionSelector
fCurrentWarpX = mosaics[ iWarpPositionSelector ].vPlayerWarp.x
fCurrentWarpY = mosaics[ iWarpPositionSelector ].vPlayerWarp.y
fCurrentWarpZ = mosaics[ iWarpPositionSelector ].vPlayerWarp.z
fCurrentWarpHeading = mosaics[ iWarpPositionSelector ].fPlayerHeading
ENDIF
IF( bWarpPlayerToMosaic )
IF( IS_ENTITY_ALIVE( PLAYER_PED_ID() ) )
SET_ENTITY_COORD_AND_HEADING( PLAYER_PED_ID(), mosaics[ iWarpPositionSelector ].vPlayerWarp,
mosaics[ iWarpPositionSelector ].fPlayerHeading )
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
ENDIF
bWarpPlayerToMosaic = FALSE
ENDIF
IF( bWarpPlayerToNextMosaic )
iWarpPositionSelector = CLAMP_INT( iWarpPositionSelector + 1, 0, NUM_MOSAICS - 1 )
bWarpPlayerToMosaic = TRUE
bWarpPlayerToNextMosaic = FALSE
IF( IS_CONTROL_JUST_PRESSED( FRONTEND_CONTROL, INPUT_SCRIPT_PAD_DOWN ) )
iMosaicSelector = iWarpPositionSelector
ENDIF
ENDIF
IF( bWarpPlayerToLastMosaic )
iWarpPositionSelector = CLAMP_INT( iWarpPositionSelector - 1, 0, NUM_MOSAICS - 1 )
bWarpPlayerToMosaic = TRUE
bWarpPlayerToLastMosaic = FALSE
ENDIF
IF( bSaveCurrentPlayerWarpPosition )
IF( IS_ENTITY_ALIVE( PLAYER_PED_ID() ) )
DEBUG_SET_PLAYER_WARP_DATA( iWarpPositionSelector, GET_ENTITY_COORDS( PLAYER_PED_ID(), FALSE ),
GET_ENTITY_HEADING( PLAYER_PED_ID() ) )
ENDIF
iOldWarpPositionSelector = -1
bSaveCurrentPlayerWarpPosition = FALSE
ENDIF
IF( bDumpWarpDataToDebugFile )
DEBUG_DUMP_WARP_DATA_TO_DEBUG_FILE()
bDumpWarpDataToDebugFile = FALSE
ENDIF
IF( bDoManualPlayerWarp )
VECTOR vResult
IF( DEBUG_CONVERT_STRING_POSITION_TO_VECTOR( GET_CONTENTS_OF_TEXT_WIDGET( twidManualWarpPosition ), vResult ) )
SET_CONTENTS_OF_TEXT_WIDGET( twidManualWarpPosition, "Success!" )
vManualWarpPosition = vResult
ELSE
SET_CONTENTS_OF_TEXT_WIDGET( twidManualWarpPosition, "Failed!" )
ENDIF
IF( IS_ENTITY_ALIVE( PLAYER_PED_ID() ) )
SET_ENTITY_COORDS( PLAYER_PED_ID(), vManualWarpPosition )
ENDIF
bDoManualPlayerWarp = FALSE
ENDIF
ELSE
IF( DOES_WIDGET_GROUP_EXIST( widDebugGroup ) )
DELETE_WIDGET_GROUP( widPicker )
DELETE_WIDGET_GROUP( widPlayerWarp )
DELETE_WIDGET_GROUP( widMosaics )
DELETE_WIDGET_GROUP( widDebugGroup )
ENDIF
ENDIF
ENDPROC
#ENDIF
//-------------------- VALIDATE PHOTO PROCS --------------------
//PURPOSE: Uses the world corner positions of a mosaic to find the width and height of a mosaic as drawn to the screen
PROC GET_MOSAIC_SIZE_ON_SCREEN( VECTOR vTopLeft, VECTOR vTopRight, VECTOR vBottomLeft, FLOAT &fWidth, FLOAT &fHeight )
VECTOR vTopLeft2D
VECTOR vTopRight2D
VECTOR vBottomLeft2D
GET_SCREEN_COORD_FROM_WORLD_COORD( vTopLeft, vTopLeft2D.x, vTopLeft2D.y )
GET_SCREEN_COORD_FROM_WORLD_COORD( vTopRight, vTopRight2D.x, vTopRight2D.y )
GET_SCREEN_COORD_FROM_WORLD_COORD( vBottomLeft, vBottomLeft2D.x, vBottomLeft2D.y )
fWidth = VDIST( vTopLeft2D, vTopRight2D )
fHeight = VDIST( vTopLeft2D, vBottomLeft2D )
ENDPROC
FUNC BOOL IS_COORD_ON_SCREEN_AND_WITHIN_BOUNDS( VECTOR vCoord, FLOAT fScreenMin, FLOAT fScreenMax )
FLOAT fx
FLOAT fy
IF( GET_SCREEN_COORD_FROM_WORLD_COORD( vCoord, fx, fy ) )
IF( fx >= fScreenMin AND fx <= fScreenMax )
IF( fy >= fScreenMin AND fy <= fScreenMax )
RETURN TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
//PURPOSE: Draws the scaleform for each completed mosaic
PROC UPDATE_SPLASH()
IF( bDrawSplash )
IF( HAS_SCALEFORM_MOVIE_LOADED( sfMovie ) )
DRAW_SCALEFORM_MOVIE( sfMovie, 0.5, 0.5, 1.0, 1.0, 100, 100, 100, 255 )
ENDIF
SWITCH( iSplashStage )
CASE 0
iTimer = GET_GAME_TIMER() + 2000
iSplashStage++
BREAK
CASE 1
IF( iTimer < GET_GAME_TIMER() )
IF( NOT IS_RESULT_SCREEN_DISPLAYING() )
sfMovie = REQUEST_SCALEFORM_MOVIE( "MIDSIZED_MESSAGE" )
iTimer = GET_GAME_TIMER() + 5000
iSplashStage++
ENDIF
ENDIF
BREAK
CASE 2
IF( HAS_SCALEFORM_MOVIE_LOADED( sfMovie ) OR iTimer < GET_GAME_TIMER() )
IF( iTimer < GET_GAME_TIMER() )
ASSERTLN( "DRAW_SPLASH scaleform took more than 5s to load!" )
bDrawSplash = FALSE
iSplashStage = 0
ELSE
iSplashStage++
ENDIF
ENDIF
BREAK
CASE 3
BEGIN_SCALEFORM_MOVIE_METHOD( sfMovie, "SHOW_BRIDGES_KNIVES_PROGRESS" )
SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING( "PM_TITLE" )
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT( NUM_MOSAICS )
SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING( "PM_PASS" )
SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING( "PM_CHALLENGE" )
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT( GET_NUM_MOSAICS_COMPLETED() )
END_SCALEFORM_MOVIE_METHOD()
iTimer = GET_GAME_TIMER() + DEFAULT_GOD_TEXT_TIME
PLAY_SOUND_FRONTEND( -1, "UNDER_THE_BRIDGE", "HUD_AWARDS" )
iSplashStage++
BREAK
CASE 4
IF( iTimer < GET_GAME_TIMER()
OR IS_SCREEN_FADED_OUT()
OR NOT IS_PLAYER_PLAYING( PLAYER_ID() )
OR IS_RESULT_SCREEN_DISPLAYING()
OR NOT IS_PLAYER_CONTROL_ON( PLAYER_ID() )
OR IS_REPLAY_BEING_PROCESSED()
OR IS_MINIGAME_SPLASH_SHOWING() )
BEGIN_SCALEFORM_MOVIE_METHOD( sfMovie, "SHARD_ANIM_OUT" )
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT( ENUM_TO_INT( HUD_COLOUR_WHITE ) )
SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT( 0.33 )
END_SCALEFORM_MOVIE_METHOD()
iTimer = GET_GAME_TIMER() + 500
iSplashStage++
ENDIF
BREAK
CASE 5
IF( iTimer < GET_GAME_TIMER()
OR IS_SCREEN_FADED_OUT()
OR NOT IS_PLAYER_PLAYING( PLAYER_ID() )
OR IS_RESULT_SCREEN_DISPLAYING()
OR NOT IS_PLAYER_CONTROL_ON( PLAYER_ID() )
OR IS_REPLAY_BEING_PROCESSED()
OR IS_MINIGAME_SPLASH_SHOWING() )
iSplashStage++
ENDIF
BREAK
CASE 6
SET_SCALEFORM_MOVIE_AS_NO_LONGER_NEEDED( sfMovie )
IF( ARE_ALL_MOSAICS_COMPLETE() )
iTimer = GET_GAME_TIMER() + 1000
iSplashStage++
ELSE
bDrawSplash = FALSE
iSplashStage = 0
ENDIF
BREAK
CASE 7
IF( iTimer < GET_GAME_TIMER() )
IF( GET_MISSION_COMPLETE_STATE( SP_MISSION_TREVOR_1 )
AND NOT GET_MISSION_COMPLETE_STATE( SP_MISSION_FINALE_A ) )
PRINT_HELP( "PM_CLOTHES", DEFAULT_HELP_TEXT_TIME )
ENDIF
bDrawSplash = FALSE
ENDIF
BREAK
ENDSWITCH
ENDIF
ENDPROC
//-------------------- INIT PROCS --------------------
PROC SCRIPT_INIT()
SET_MOSAIC_DATA( 0, <<157.9448, -1171.3970, 29.1414>>, <<-0.0872, 0.9962, -0.0002>>, 0.5050, 0.4700 )
SET_MOSAIC_DATA( 1, <<1124.1533, -1270.9707, 23.3037>>, <<-0.8098, -0.5868, 0.0000>>, 0.4000, 0.4000 )
SET_MOSAIC_DATA( 2, <<149.5787, -1183.7872, 31.1711>>, <<0.4427, -0.7223, 0.5313>>, 0.4900, 0.5000 )
SET_MOSAIC_DATA( 3, <<-146.9499, 229.0641, 97.7295>>, <<0.0000, 1.0000, 0.0000>>, 0.4200, 0.4200 )
SET_MOSAIC_DATA( 4, <<-1939.4950, -408.4034, 37.6704>>, <<0.5596, 0.8288, -0.0011>>, 0.4100, 0.3800 )
SET_MOSAIC_DATA( 5, <<2547.1548, 394.4722, 111.3622>>, <<-0.9994, 0.0341, -0.0000>>, 0.5400, 0.5200 )
SET_MOSAIC_DATA( 6, <<-1104.9414, 2724.4644, 21.7053>>, <<0.7479, 0.6638, -0.0000>>, 0.4400, 0.4100 )
SET_MOSAIC_DATA( 7, <<205.5913, -2026.6046, 17.8582>>, <<-0.3632, -0.9317, -0.0015>>, 0.3900, 0.3300 )
SET_MOSAIC_DATA( 8, <<1143.9529, -667.2766, 58.1309>>, <<0.9955, 0.0953, 0.0000>>, 0.5900, 0.5100 )
SET_MOSAIC_DATA( 9, <<-495.5830, -457.0046, 32.6311>>, <<-0.9928, 0.1194, -0.0002>>, 0.6000, 0.6100 )
SET_MOSAIC_DATA( 10, <<1674.2952, 4973.9189, 45.5824>>, <<-0.7070, 0.7072, 0.0000>>, 0.3800, 0.3500 )
SET_MOSAIC_DATA( 11, <<1511.4800, 3567.6128, 38.0881>>, <<0.8660, 0.5000, -0.0004>>, 0.3900, 0.3800 )
SET_MOSAIC_DATA( 12, <<84.4525, 213.9647, 119.2064>>, <<0.9397, -0.3419, -0.0018>>, 0.6000, 0.6000 )
SET_MOSAIC_DATA( 13, <<3420.1680, 3769.6799, 35.8602>>, <<-0.4229, 0.9062, 0.0001>>, 0.7100, 0.7200 )
SET_MOSAIC_DATA( 14, <<-420.5195, 1090.3248, 332.0972>>, <<-0.9639, 0.2661, 0.0007>>, 0.4100, 0.3900 )
SET_MOSAIC_DATA( 15, <<341.5140, 345.7831, 105.1536>>, <<0.9709, -0.2397, 0.0000>>, 0.5100, 0.5000 )
SET_MOSAIC_DATA( 16, <<-940.4380, 332.8253, 72.5064>>, <<0.0000, 1.0000, 0.0000>>, 0.3300, 0.3100 )
SET_MOSAIC_DATA( 17, <<-1828.9017, -1266.7217, 7.7045>>, <<0.7660, -0.6428, 0.0000>>, 0.1890, 0.1600 )
SET_MOSAIC_DATA( 18, <<-1168.0094, -2033.2712, 14.4629>>, <<-0.6428, -0.7660, 0.0000>>, 0.4090, 0.4100 )
SET_MOSAIC_DATA( 19, <<-346.3339, -2275.3621, 7.0538>>, <<1.0000, 0.0000, 0.0000>>, 0.4190, 0.4200 )
SET_MOSAIC_DATA( 20, <<1725.7247, 4780.7778, 42.7613>>, <<1.0000, 0.0000, 0.0000>>, 0.3800, 0.3800 )
SET_MOSAIC_DATA( 21, <<2394.6416, 3142.6284, 48.0601>>, <<0.9096, -0.4155, 0.0000>>, 0.5200, 0.5200 )
SET_MOSAIC_DATA( 22, <<559.5842, -551.6270, 27.5494>>, <<0.9925, -0.1219, 0.0000>>, 0.3200, 0.3200 )
SET_MOSAIC_DATA( 23, <<282.2999, -477.4480, 33.6627>>, <<-0.2438, 0.9698, -0.0001>>, 0.3000, 0.3000 )
SET_MOSAIC_DATA( 24, <<-808.8348, -2749.2620, 13.5377>>, <<0.8660, -0.5000, 0.0000>>, 0.4200, 0.4200 )
SET_MOSAIC_DATA( 25, <<354.2460, 3397.8491, 36.0745>>, <<0.3677, -0.9300, 0.0000>>, 0.3900, 0.3600 )
SET_MOSAIC_DATA( 26, <<472.6187, -1470.4248, 34.8640>>, <<0.2627, -0.9649, 0.0000>>, 0.5900, 0.5400 )
SET_MOSAIC_DATA( 27, <<-466.3089, -1447.8661, 20.7979>>, <<0.6997, -0.7144, 0.0000>>, 0.5800, 0.5800 )
SET_MOSAIC_DATA( 28, <<-1370.4216, -524.2557, 30.5145>>, <<-0.8256, -0.5643, -0.0001>>, 0.4100, 0.3900 )
SET_MOSAIC_DATA( 29, <<-95.4015, -744.5070, 37.1422>>, <<0.9047, 0.4261, 0.0000>>, 0.4800, 0.4800 )
SET_MOSAIC_DATA( 30, <<-1985.9196, 4521.6475, 19.9029>>, <<0.6943, 0.6959, -0.1836>>, 0.6300, 0.6200 )
SET_MOSAIC_DATA( 31, <<555.9847, 2800.7842, 41.7896>>, <<-0.0712, 0.9975, 0.0000>>, 0.4400, 0.4300 )
SET_MOSAIC_DATA( 32, <<1914.3754, 3735.6611, 33.7799>>, <<-0.8666, -0.4989, 0.0002>>, 0.3400, 0.3300 )
SET_MOSAIC_DATA( 33, <<753.8581, -1861.1060, 51.9038>>, <<0.0823, 0.9966, -0.0012>>, 0.5400, 0.5300 )
SET_MOSAIC_DATA( 34, <<1570.8441, -2130.8457, 77.1156>>, <<0.9637, 0.2670, 0.0006>>, 0.4800, 0.4500 )
SET_MOSAIC_DATA( 35, <<894.0941, 3619.2463, 32.3190>>, <<0.0000, -1.0000, 0.0000>>, 0.3600, 0.3500 )
SET_MOSAIC_DATA( 36, <<-251.7530, 6235.9199, 30.9796>>, <<0.7092, -0.7050, 0.0000>>, 0.2300, 0.2300 )
SET_MOSAIC_DATA( 37, <<1240.0862, -3318.4395, 5.6199>>, <<1.0000, 0.0000, 0.0000>>, 0.4200, 0.4200 )
SET_MOSAIC_DATA( 38, <<-1382.7864, -905.4655, 15.0535>>, <<0.7934, 0.6087, 0.0000>>, 0.7000, 0.5400 )
SET_MOSAIC_DATA( 39, <<-1677.9526, 174.4390, 62.1203>>, <<0.4226, -0.9063, 0.6201>>, 0.2440, 0.2300 )
SET_MOSAIC_DATA( 40, <<249.8769, -3310.7395, 5.6313>>, <<0.0000, -0.9063, 0.0001>>, 0.6540, 0.6600 )
SET_MOSAIC_DATA( 41, <<158.6217, 6657.8584, 35.7506>>, <<0.7054, 0.7059, 0.0000>>, 0.5440, 0.4700 )
SET_MOSAIC_DATA( 42, <<-1378.4717, -362.0254, 42.8204>>, <<-0.9687, 0.2484, 0.0000>>, 1.7440, 1.6500 )
SET_MOSAIC_DATA( 43, <<-1706.7347, -265.9444, 50.8910>>, <<-0.8055, 0.5926, 0.0000>>, 0.3650, 0.3200 )
SET_MOSAIC_DATA( 44, <<-1279.3156, -1611.9532, 6.3379>>, <<-0.8219, -0.5697, 0.0001>>, 2.4390, 2.0910 )
SET_MOSAIC_DATA( 45, <<-1035.4744, -160.1076, 37.9679>>, <<-0.9366, 0.3504, 0.0000>>, 0.2730, 0.2280 )
SET_MOSAIC_DATA( 46, <<591.9451, 142.8853, 103.5083>>, <<-0.3445, -0.9388, 0.0038>>, 0.3550, 0.3600 )
SET_MOSAIC_DATA( 47, <<-463.3655, -18.1181, 51.9250>>, <<-0.9986, 0.0523, 0.0000>>, 0.8340, 0.8290 )
SET_MOSAIC_DATA( 48, <<-956.4725, -775.4922, 16.6361>>, <<0.6088, 0.7934, 0.0000>>, 0.2580, 0.2630 )
SET_MOSAIC_DATA( 49, <<-814.0197, -1255.7089, 5.4366>>, <<-0.6431, -0.7658, -0.0001>>, 0.4710, 0.4710 )
ENDPROC
PROC CREATE_TRACKED_POINT_WITH_INFO( INT &iTrackedPoint, VECTOR vPos, FLOAT fRadius )
iTrackedPoint = CREATE_TRACKED_POINT()
IF( iTrackedPoint = 0 )
ASSERTLN( "CREATE_TRACKED_POINT_WITH_INFO can't get free index from CREATE_TRACKED_POINT!" )
ELSE
SET_TRACKED_POINT_INFO( iTrackedPoint, vPos, fRadius )
ENDIF
ENDPROC
//-------------------- MAIN LOOP --------------------
SCRIPT
IF( HAS_FORCE_CLEANUP_OCCURRED( FORCE_CLEANUP_FLAG_SP_TO_MP | FORCE_CLEANUP_FLAG_REPEAT_PLAY | FORCE_CLEANUP_FLAG_DEBUG_MENU | FORCE_CLEANUP_FLAG_DIRECTOR ) )
CPRINTLN( DEBUG_SIMON, " >>> photographyMonkey: Forced to terminate!" )
// it's possible that the script will be forced to cleanup when requesting LOS checks
CLEANUP_TRACKED_POINT( iCenter )
CLEANUP_TRACKED_POINT( iTopLeft )
CLEANUP_TRACKED_POINT( iTopRight )
CLEANUP_TRACKED_POINT( iBottomLeft )
CLEANUP_TRACKED_POINT( iBottomRight )
TERMINATE_THIS_THREAD()
ENDIF
SCRIPT_INIT()
#IF IS_DEBUG_BUILD
DEBUG_SCRIPT_INIT()
#ENDIF
WHILE( HAS_CELLPHONE_CAM_JUST_TAKEN_PIC() )
WAIT( 0 )
ENDWHILE
WHILE( TRUE )
#IF IS_DEBUG_BUILD
DEBUG_SCRIPT_UPDATE()
#ENDIF
#IF IS_DEBUG_BUILD
IF( NOT bDisableScript )
#ENDIF
UPDATE_SPLASH()
IF( ARE_ALL_MOSAICS_COMPLETE() AND iBodyStage = 0 )
iBodyStage = 2
ENDIF
IF( NOT IS_REPEAT_PLAY_ACTIVE() ) AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR)
IF( iBodyStage = 0 )
IF( HAS_CELLPHONE_CAM_JUST_TAKEN_PIC() )
CPRINTLN( DEBUG_SIMON, " >>> photographyMonkey: Photograph taken" )
FLOAT fDist2 = 0.0
iCurrentMosaicIndex = GET_CLOSEST_INCOMPLETE_MOSAIC_DATA_INDEX( fDist2 )
bIsBypassingSave = IS_BIT_SET( BitSet_CellphoneDisplay_Continued, g_BSC_BYPASS_CAMERA_APP_SAVE_ROUTINE )
// if we got an answer
IF( iCurrentMosaicIndex <> -1 )
CPRINTLN( DEBUG_SIMON, " >>> photographyMonkey: Cloesest mosaic not complete" )
// is the mosaic within the minimum range of the player
IF( fDist2 < MOSAIC_RANGE2 )
CPRINTLN( DEBUG_SIMON, " >>> photographyMonkey: Closest mosaic is close enough for consideration" )
VECTOR vTopLeft = vZero
VECTOR vTopRight = vZero
VECTOR vBottomLeft = vZero
VECTOR vBottomRight = vZero
GET_MOSAIC_CORNER_COORDS( iCurrentMosaicIndex, vTopLeft, vTopRight, vBottomLeft, vBottomRight )
FLOAT fWidth = 0.0
FLOAT fHeight = 0.0
GET_MOSAIC_SIZE_ON_SCREEN( vTopLeft, vTopRight, vBottomLeft, fWidth, fHeight )
FLOAT fArea = fWidth * fHeight
IF( ( fArea >= IGNORE_BORDER_AREA
AND IS_COORD_ON_SCREEN_AND_WITHIN_BOUNDS( vTopLeft, 0.0, 1.0 )
AND IS_COORD_ON_SCREEN_AND_WITHIN_BOUNDS( vTopRight, 0.0, 1.0 )
AND IS_COORD_ON_SCREEN_AND_WITHIN_BOUNDS( vBottomLeft, 0.0, 1.0 )
AND IS_COORD_ON_SCREEN_AND_WITHIN_BOUNDS( vBottomRight, 0.0, 1.0 ) )
OR ( fArea < IGNORE_BORDER_AREA
AND IS_COORD_ON_SCREEN_AND_WITHIN_BOUNDS( vTopLeft, SCREEN_POSITION_MIN, SCREEN_POSITION_MAX )
AND IS_COORD_ON_SCREEN_AND_WITHIN_BOUNDS( vTopRight, SCREEN_POSITION_MIN, SCREEN_POSITION_MAX )
AND IS_COORD_ON_SCREEN_AND_WITHIN_BOUNDS( vBottomLeft, SCREEN_POSITION_MIN, SCREEN_POSITION_MAX )
AND IS_COORD_ON_SCREEN_AND_WITHIN_BOUNDS( vBottomRight, SCREEN_POSITION_MIN, SCREEN_POSITION_MAX ) ) )
CPRINTLN( DEBUG_SIMON, " >>> photographyMonkey: All four corners of the mosaic are on screen and within bounds" )
// is the mosaic size, as rendered to the screen, larger than the minimum acceptable size
IF( fWidth >= MIN_MOSAIC_WIDTH AND fHeight >= MIN_MOSAIC_HEIGHT )
CPRINTLN( DEBUG_SIMON, " >>> photographyMonkey: The mosaic size on screen is bigger than the minimum size required" )
CREATE_TRACKED_POINT_WITH_INFO( iCenter, mosaics[ iCurrentMosaicIndex ].vPos, VISIBILITY_POINT_RADIUS )
CREATE_TRACKED_POINT_WITH_INFO( iTopLeft, vTopLeft, VISIBILITY_POINT_RADIUS )
CREATE_TRACKED_POINT_WITH_INFO( iTopRight, vTopRight, VISIBILITY_POINT_RADIUS )
CREATE_TRACKED_POINT_WITH_INFO( iBottomLeft, vBottomLeft, VISIBILITY_POINT_RADIUS )
CREATE_TRACKED_POINT_WITH_INFO( iBottomRight, vBottomRight, VISIBILITY_POINT_RADIUS )
BOOL bAllTrackedPointsVisible = FALSE
INT iFrameCounter = 0
WHILE( iFrameCounter < 10 AND NOT bAllTrackedPointsVisible )
bAllTrackedPointsVisible = IS_TRACKED_POINT_VISIBLE( iCenter )
AND IS_TRACKED_POINT_VISIBLE( iTopLeft )
AND IS_TRACKED_POINT_VISIBLE( iTopRight )
AND IS_TRACKED_POINT_VISIBLE( iBottomLeft )
AND IS_TRACKED_POINT_VISIBLE( iBottomRight )
iFrameCounter++
WAIT( 0 )
ENDWHILE
// if all corners and center are visible
IF( bAllTrackedPointsVisible )
CPRINTLN( DEBUG_SIMON, " >>> photographyMonkey: The camera has clear LOS to all four of the mosaic's corners" )
CPRINTLN( DEBUG_SIMON, " >>> photographyMonkey: The LOS check took ", iFrameCounter, " frames" )
SET_MOSAIC_COMPLETE( iCurrentMosaicIndex, TRUE )
STAT_SET_INT( NUM_HIDDEN_PACKAGES_6, GET_NUM_MOSAICS_COMPLETED() )
bDrawSplash = TRUE
IF( ARE_ALL_MOSAICS_COMPLETE() )
CPRINTLN( DEBUG_SIMON, " >>> photographyMonkey: Unlocking clothing reward" )
UNLOCK_SPACE_MONKEY_CLOTHES_FOR_TREVOR()
ENDIF
MAKE_AUTOSAVE_REQUEST()
BYPASS_CELLPHONE_CAMERA_DEFAULT_SAVE_ROUTINE( TRUE )
#IF IS_DEBUG_BUILD
ELSE
CPRINTLN( DEBUG_SIMON, " >>> photographyMonkey: The camera doesn't have clear LOS to all the mosaic's corners" )
#ENDIF
ENDIF
CLEANUP_TRACKED_POINT( iCenter )
CLEANUP_TRACKED_POINT( iTopLeft )
CLEANUP_TRACKED_POINT( iTopRight )
CLEANUP_TRACKED_POINT( iBottomLeft )
CLEANUP_TRACKED_POINT( iBottomRight )
#IF IS_DEBUG_BUILD
ELSE
CPRINTLN( DEBUG_SIMON, " >>> photographyMonkey: The mosaic is smaller than the minimum size required" )
#ENDIF
ENDIF
#IF IS_DEBUG_BUILD
ELSE
CPRINTLN( DEBUG_SIMON, " >>> photographyMonkey: One or more of the mosaic's corners aren't on screen or within bounds" )
#ENDIF
ENDIF
#IF IS_DEBUG_BUILD
ELSE
CPRINTLN( DEBUG_SIMON, " >>> photographyMonkey: Closest mosaic isn't close enough for consideration" )
#ENDIF
ENDIF
#IF IS_DEBUG_BUILD
ELSE
CPRINTLN( DEBUG_SIMON, " >>> photographyMonkey: Mosaic already complete" )
#ENDIF
ENDIF
iBodyStage = 1
ENDIF
ELIF( iBodyStage = 1 )
IF( NOT HAS_CELLPHONE_CAM_JUST_TAKEN_PIC() )
BYPASS_CELLPHONE_CAMERA_DEFAULT_SAVE_ROUTINE( bIsBypassingSave )
iBodyStage = 0
ENDIF
ELIF( iBodyStage = 2 )
IF( NOT bDrawSplash )
IF( IS_LAST_GEN_PLAYER() )
CPRINTLN( DEBUG_SIMON, " >>> photographyMonkey: Setting RE available and terminating script for final time" )
SET_RANDOM_EVENT_AVAILABLE( RE_MONKEYPHOTO, TRUE )
SET_ALL_MOSAICS_COMPLETE_FINAL()
#IF IS_DEBUG_BUILD
UNLOCK_SPACE_MONKEY_CLOTHES_FOR_TREVOR()
#ENDIF
MAKE_AUTOSAVE_REQUEST()
TERMINATE_THIS_THREAD()
ENDIF
ENDIF
#IF IS_DEBUG_BUILD
IF( NOT ARE_ALL_MOSAICS_COMPLETE() )
iBodyStage = 0
ENDIF
#ENDIF
ENDIF
ENDIF
#IF IS_DEBUG_BUILD
ENDIF
#ENDIF
WAIT( 0 )
ENDWHILE
ENDSCRIPT