//╒═════════════════════════════════════════════════════════════════════════════╕ //╞══════════════════╡ 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 = <> VECTOR vPickerNormal = <> 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