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

584 lines
19 KiB
Scheme
Executable File

//////////////////////////////////////////////////////////////////////////////////////////
// //
// SCRIPT NAME : common_packages.sc //
// AUTHOR : Joanna Wright //
// DESCRIPTION : common functionality for spaceship and letter scraps //
// //
// //
//////////////////////////////////////////////////////////////////////////////////////////
USING "RC_Helper_Functions.sch"
// Pickup spawn and cleanup distances
CONST_FLOAT CREATE_PICKUP_DISTANCE 50.0
CONST_FLOAT CREATE_SALE_SIGN_DISTANCE 100.0
CONST_FLOAT CLEANUP_PICKUP_DISTANCE 60.00
CONST_FLOAT CLEANUP_OBJECT_DISTANCE 110.0
// Rumble effect
CONST_INT PICKUP_RUMBLE_DURATION 200
CONST_INT PICKUP_RUMBLE_FREQ 250
// Packed stats
CONST_INT PACKSTAT_LETTER_START PACKED_HIDDEN_PACKAGE_START
CONST_INT PACKSTAT_UFO_START PACKSTAT_LETTER_START+50
CONST_INT PACKSTAT_TRACT_START PACKSTAT_LETTER_START+100
CONST_INT PACKSTAT_SONAR_START PACKSTAT_LETTER_START+110
CONST_INT PACKSTAT_DIVING_START PACKSTAT_LETTER_START+140
// Pickup constants (spaceship and letter scraps are globally stored)
CONST_INT MAX_TRACT_PICKUPS 10
CONST_INT NUMBER_OF_SONAR_PICKUPS 30
CONST_INT NUMBER_OF_FOR_SALE_SIGNS 15
CONST_INT NUMBER_OF_DIVING_SCRAPS 30
// Mission enum
ENUM SCRAP_MISSION
SCRAP_SHIP,
SCRAP_LETTER,
SCRAP_SALE_SIGNS,
SCRAP_SUB,
SCRAP_TRACT,
SCRAP_DIVING,
SCRAP_PEYOTE,
SCRAP_WILDLIFE,
SCRAP_MONKEY
ENDENUM
// Ambient script stage
ENUM MISSION_STAGE
STAGE_INITIALISE = 0,
STAGE_PROCESS,
STAGE_CLEANUP
ENDENUM
// Debug
#IF IS_DEBUG_BUILD
BOOL bDebug_PrintToTTYStuff = FALSE // This seems to be off for the For Sale signs
INT iDebugScrapCreatedNum = 0 // End up with negative numbers
#ENDIF
// Hidden package instance
STRUCT SCRAP_PICKUP_DATA
OBJECT_INDEX obj
PICKUP_INDEX pickup
BLIP_INDEX blip
VECTOR vCoords
VECTOR vRot
FLOAT fHeading
BOOL bActive
ENDSTRUCT
//Returns the correct bit flag slot depending on what object part we are looking for. only to be used if scrap has over 1 flag
FUNC INT RETURN_BIT_FLAG_SLOT(INT iScrapParts, INT objectPartNum)
IF objectPartNum < 32
RETURN objectPartNum
ELSE
RETURN (iScrapParts - objectPartNum)
ENDIF
ENDFUNC
/// PURPOSE:
// Loads any interior around the scrap specified
/// PARAMS:
/// VECTOR coords = the coord of the pickup or scrap
/// RETURNS:
/// N/A
PROC LOAD_INTERIOR_AROUND_COORDS(VECTOR coords)
INTERIOR_INSTANCE_INDEX intIndex = GET_INTERIOR_AT_COORDS(coords)
IF IS_VALID_INTERIOR(intIndex)
PIN_INTERIOR_IN_MEMORY(intIndex)
WHILE NOT IS_INTERIOR_READY(intIndex)
WAIT(0)
ENDWHILE
WAIT(0)
UNPIN_INTERIOR(intIndex)
ENDIF
ENDPROC
/// PURPOSE:
// When the player is close to the pickup location, create the scrap pickup
PROC CREATE_SCRAP_WHEN_IN_RANGE(SCRAP_PICKUP_DATA& theScrap, MODEL_NAMES objModel, PICKUP_TYPE pickupType = PICKUP_CUSTOM_SCRIPT, BOOL bIsInInterior = FALSE, BOOL bUseRotate=FALSE, EULER_ROT_ORDER rotOrder=EULER_YXZ)
INT iPlacementFlags
IF NOT theScrap.bActive
// If the player is close to the scrap location
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
//Don't allow creation of pickups while playing as a none story character.
IF NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_ANIMAL)
AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR)
IF NOT DOES_PICKUP_EXIST(theScrap.pickup)
IF (VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), theScrap.vCoords) <= (CREATE_PICKUP_DISTANCE*CREATE_PICKUP_DISTANCE))
// Request pickup model
REQUEST_MODEL(objModel)
WHILE NOT HAS_MODEL_LOADED(objModel)
REQUEST_MODEL(objModel)
WAIT(0)
ENDWHILE
// Load interior around pickup if required
IF bIsInInterior
LOAD_INTERIOR_AROUND_COORDS(theScrap.vCoords)
ENDIF
// Clear area
CLEAR_AREA(theScrap.vCoords, 2.5, FALSE)
// Set placement flags and create pickup
IF bUseRotate
SET_BIT(iPlacementFlags, ENUM_TO_INT(PLACEMENT_FLAG_FIXED))
theScrap.pickup = CREATE_PICKUP_ROTATE(PICKUP_CUSTOM_SCRIPT, theScrap.vCoords, theScrap.vRot, iPlacementFlags, -1, rotOrder, TRUE, objModel)
ELSE
SET_BIT(iPlacementFlags, ENUM_TO_INT(PLACEMENT_FLAG_SNAP_TO_GROUND))
SET_BIT(iPlacementFlags, ENUM_TO_INT(PLACEMENT_FLAG_ORIENT_TO_GROUND))
SET_BIT(iPlacementFlags, ENUM_TO_INT(PLACEMENT_FLAG_UPRIGHT))
SET_BIT(iPlacementFlags, ENUM_TO_INT(PLACEMENT_FLAG_FIXED))
theScrap.pickup = CREATE_PICKUP(pickupType, theScrap.vCoords, iPlacementFlags, -1, TRUE, objModel)
ENDIF
// Release model
SET_MODEL_AS_NO_LONGER_NEEDED(objModel)
ENDIF
ENDIF
ENDIF
// Pickup has successfully been created
IF DOES_PICKUP_EXIST(theScrap.pickup)
// Mark as active
theScrap.bActive = TRUE
#IF IS_DEBUG_BUILD
IF bDebug_PrintToTTYStuff
iDebugScrapCreatedNum++
CPRINTLN(DEBUG_AMBIENT, "[Hidden Packages] Scrap created, so far there are: ", iDebugScrapCreatedNum)
ENDIF
#ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
// When the player is close to the pickup location, create the scrap object
PROC CREATE_OBJECT_WHEN_IN_RANGE(SCRAP_PICKUP_DATA& theScrap, MODEL_NAMES objModel, BOOL bIsInInterior = FALSE, FLOAT spawnDistance = CREATE_PICKUP_DISTANCE)
// If the player is close to the scrap location
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
IF IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), theScrap.vCoords, spawnDistance)
AND NOT DOES_ENTITY_EXIST(theScrap.obj)
REQUEST_MODEL(objModel)
WHILE NOT HAS_MODEL_LOADED(objModel)
REQUEST_MODEL(objModel)
WAIT(0)
ENDWHILE
IF bIsInInterior
LOAD_INTERIOR_AROUND_COORDS(theScrap.vCoords)
ENDIF
CLEAR_AREA(theScrap.vCoords, 2.5, FALSE)
theScrap.obj = CREATE_OBJECT(objModel, theScrap.vCoords)
theScrap.bActive = TRUE
SET_MODEL_AS_NO_LONGER_NEEDED(objModel)
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Returns the correct pack stat based on the mission
/// PARAMS:
/// SCRAP_MISSION theScrapMission = the type of scrap mission this is
/// RETURNS:
/// The pack stat
FUNC INT GET_PACK_STAT(SCRAP_MISSION theScrapMission)
IF theScrapMission = SCRAP_SUB
RETURN PACKSTAT_SONAR_START
ELIF theScrapMission = SCRAP_DIVING
RETURN PACKSTAT_DIVING_START
ELIF theScrapMission = SCRAP_LETTER
RETURN PACKSTAT_LETTER_START
ELIF theScrapMission = SCRAP_SHIP
RETURN PACKSTAT_UFO_START
ELSE
RETURN PACKSTAT_TRACT_START
ENDIF
ENDFUNC
/// PURPOSE:
/// Returns the correct number of maximum pickups based on the mission
/// PARAMS:
/// SCRAP_MISSION theScrapMission = the type of scrap mission this is
/// RETURNS:
/// The max number of pickups in the chosen mission
FUNC INT GET_NUM_PARTS(SCRAP_MISSION theScrapMission)
IF theScrapMission = SCRAP_SUB
RETURN NUMBER_OF_SONAR_PICKUPS
ELIF theScrapMission = SCRAP_LETTER
RETURN NUMBER_OF_LETTER_SCRAPS
ELIF theScrapMission = SCRAP_SHIP
RETURN NUMBER_OF_SPACESHIP_PARTS
ELIF theScrapMission = SCRAP_TRACT
RETURN MAX_TRACT_PICKUPS
ELIF theScrapMission = SCRAP_DIVING
RETURN NUMBER_OF_DIVING_SCRAPS
ELSE
RETURN NUMBER_OF_FOR_SALE_SIGNS
ENDIF
ENDFUNC
/// PURPOSE:
/// Returns the correct number of incremented pickups (for stats) based on the mission
/// PARAMS:
/// SCRAP_MISSION theScrapMission = the type of scrap mission this is
/// RETURNS:
/// The number of incremented pickups (for stats) of the chosen mission
FUNC STATSENUM GET_HIDDEN_PACKAGES_NUM(SCRAP_MISSION theScrapMission)
IF theScrapMission = SCRAP_SUB
RETURN NUM_HIDDEN_PACKAGES_3
ELIF theScrapMission = SCRAP_LETTER
RETURN NUM_HIDDEN_PACKAGES_0
ELIF theScrapMission = SCRAP_SHIP
RETURN NUM_HIDDEN_PACKAGES_1
ELIF theScrapMission = SCRAP_DIVING
RETURN NUM_HIDDEN_PACKAGES_4
ELSE
RETURN NUM_HIDDEN_PACKAGES_2
ENDIF
ENDFUNC
/// PURPOSE:
/// Find out how many scraps have been destroyed/collected and return the number
/// PARAMS:
/// INT iNumScraps = how many scraps there are to collect/destroy in this mission
/// SCRAP_MISSION theScrapMission = the type of scrap mission this is
/// RETURNS:
/// The number of scraps destroyed/collected
FUNC INT GET_NUM_SCRAPS_SORTED(SCRAP_MISSION theScrapMission)
INT iSortedScraps = 0
INT iScrap = 0
INT ipackNum
IF theScrapMission = SCRAP_SALE_SIGNS
REPEAT GET_NUM_PARTS(theScrapMission) iScrap
IF IS_BIT_SET(g_savedGlobals.sAmbient.iForSaleSignDestroyedFlags, RETURN_BIT_FLAG_SLOT(ENUM_TO_INT(GET_NUM_PARTS(theScrapMission)), iScrap))
iSortedScraps++
ENDIF
ENDREPEAT
ELIF theScrapMission = SCRAP_PEYOTE
//Animal controller sets the counter enum directly.
STAT_GET_INT(NUM_HIDDEN_PACKAGES_5, iSortedScraps)
ELIF theScrapMission = SCRAP_WILDLIFE
//phototgraphyWildlife sets the counter enum directly.
STAT_GET_INT(NUM_HIDDEN_PACKAGES_7, iSortedScraps)
ELIF theScrapMission = SCRAP_MONKEY
//Animal controller sets the counter enum directly.
STAT_GET_INT(NUM_HIDDEN_PACKAGES_6, iSortedScraps)
ELSE
REPEAT (GET_NUM_PARTS(theScrapMission)) iScrap
ipackNum = (GET_PACK_STAT(theScrapMission)) + iScrap
IF GET_PACKED_STAT_BOOL(INT_TO_ENUM(STATS_PACKED, ipackNum))
iSortedScraps++
ENDIF
ENDREPEAT
ENDIF
RETURN iSortedScraps
ENDFUNC
/// PURPOSE:
/// Reset the packed stats for the mentioned mission to false
/// PARAMS:
/// SCRAP_MISSION theScrapMission = the type of scrap mission this is
/// RETURNS:
/// N/A
PROC RESET_ALL_PACKAGE_FLAGS_TO_ZERO(SCRAP_MISSION scrpMis)
INT i = 0
REPEAT (GET_NUM_PARTS(scrpMis)) i
SET_PACKED_STAT_BOOL(INT_TO_ENUM(STATS_PACKED, GET_PACK_STAT(scrpMis)), FALSE)
ENDREPEAT
STAT_DECREMENT(GET_HIDDEN_PACKAGES_NUM(scrpMis), TO_FLOAT(GET_NUM_SCRAPS_SORTED(scrpMis)))
ENDPROC
/// PURPOSE:
/// Returns whether all the scraps have been flagged as collected.
/// PARAMS:
/// INT iNumOfScraps = the number of scraps to check
/// SCRAP_MISSION theScrapMission = the type of scrap mission this is
/// RETURNS:
/// TRUE if all the scraps have been flagged as collected, else FALSE
FUNC BOOL HAVE_ALL_SCRAPS_BEEN_COMPLETED(SCRAP_MISSION scrMis)
INT iScrap
IF NOT (scrMis = SCRAP_SALE_SIGNS)
IF (GET_NUM_SCRAPS_SORTED(scrMis) < GET_NUM_PARTS(scrMis))
RETURN FALSE
ENDIF
ELSE
REPEAT GET_NUM_PARTS(scrMis) iScrap
IF NOT IS_BIT_SET(g_savedGlobals.sAmbient.iForSaleSignDestroyedFlags, RETURN_BIT_FLAG_SLOT(GET_NUM_PARTS(scrMis), iScrap))
RETURN FALSE
ENDIF
ENDREPEAT
ENDIF
RETURN TRUE
ENDFUNC
/// PURPOSE:
/// Clears any display messages to do with the scraps
/// PARAMS:
/// BOOL bMessageDisplayed = if a scrap display message is on screen
/// STRING scrapSorted = The string for "so-many scraps sorted" message
/// STRING allScrapsSorted = The string for "all scraps sorted" message
/// INT iNumScraps = how many scraps there are to collect/destroy in this mission
/// SCRAP_MISSION theScrapMission = the type of scrap mission this is
/// INT theMessageTimer = the time the message has been on screen
/// RETURNS:
/// N/A
PROC CLEAR_DISPLAY_MESSAGE(BOOL & bMessageDisplayed, STRING scrapSorted, STRING allScrapsSorted, SCRAP_MISSION theScrapMission, INT theMessageTimer)
IF bMessageDisplayed
IF (GET_GAME_TIMER() - theMessageTimer) > 8000
INT NumberOfScrapsSorted = GET_NUM_SCRAPS_SORTED(theScrapMission)
IF (NumberOfScrapsSorted = GET_NUM_PARTS(theScrapMission))
IF IS_THIS_PRINT_BEING_DISPLAYED(allScrapsSorted)
CLEAR_PRINTS()
ENDIF
bMessageDisplayed = FALSE
ELSE
BEGIN_TEXT_COMMAND_IS_MESSAGE_DISPLAYED(scrapSorted)
ADD_TEXT_COMPONENT_INTEGER(NumberOfScrapsSorted)
IF END_TEXT_COMMAND_IS_MESSAGE_DISPLAYED()
CLEAR_PRINTS()
ENDIF
bMessageDisplayed = FALSE
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Prints the display messages to do with the scraps
/// PARAMS:
/// STRING scrapSorted = The string for "so-many scraps sorted" message
/// STRING allScrapsSorted = The string for "all scraps sorted" message
/// INT iNumScraps = how many scraps there are to collect/destroy in this mission
/// SCRAP_MISSION theScrapMission = the type of scrap mission this is
/// RETURNS:
/// TRUE if message printed and help is clear, otherwise returns false
FUNC BOOL PRINT_DISPLAY_MESSAGE(STRING allScrapsSorted, STRING scrapSorted, SCRAP_MISSION scrapMissionType)
INT iMessageNumber = GET_NUM_SCRAPS_SORTED(scrapMissionType)
#IF IS_DEBUG_BUILD
IF bDebug_PrintToTTYStuff
CPRINTLN(DEBUG_AMBIENT, "[Hidden Packages] NUMBER OF SCRAPS SORTED IS: ", iMessageNumber)
ENDIF
#ENDIF
// Print the new message if help is clear
IF NOT IS_MESSAGE_BEING_DISPLAYED()
OR NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF HAVE_ALL_SCRAPS_BEEN_COMPLETED(scrapMissionType)
PRINT_NOW(allScrapsSorted, DEFAULT_GOD_TEXT_TIME, 1)
ELSE
PRINT_WITH_NUMBER(scrapSorted, iMessageNumber, DEFAULT_GOD_TEXT_TIME, 1)
ENDIF
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Delete scrap if Player is far away enough not to see it
/// PARAMS:
/// OBJECT_INDEX scrapObj = the scrap pickup
/// BOOL& canPickUpInVeh = if the player's allowed to pick up the scrap in a vehicle
/// RETURNS:
/// The number of scraps destroyed/collected
PROC REMOVE_SCRAP_WHEN_OUT_OF_RANGE(PICKUP_INDEX& scrapPickup, BOOL& bIsScrapActive)
// If the player is no longer near the scrap
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_PICKUP_COORDS(scrapPickup)) >= CLEANUP_PICKUP_DISTANCE
SAFE_REMOVE_PICKUP(scrapPickup)
scrapPickup = NULL
bIsScrapActive = FALSE
#IF IS_DEBUG_BUILD
IF bDebug_PrintToTTYStuff
iDebugScrapCreatedNum--
CPRINTLN(DEBUG_AMBIENT, "[Hidden Packages] Scrap removed, so far there are: ", iDebugScrapCreatedNum)
ENDIF
#ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Delete scrap if Player is far away enough not to see it
/// PARAMS:
/// OBJECT_INDEX scrapObj = the scrap object
/// BOOL& canPickUpInVeh = if the player's allowed to pick up the scrap in a vehicle
/// RETURNS:
/// The number of scraps destroyed/collected
PROC REMOVE_OBJECT_WHEN_OUT_OF_RANGE(OBJECT_INDEX& scrapObj, BOOL& bIsScrapActive)
// If the player is no longer near the scrap
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(scrapObj)) >= CLEANUP_OBJECT_DISTANCE
AND NOT IS_ENTITY_ON_SCREEN(scrapObj)
SAFE_DELETE_OBJECT(scrapObj)
bIsScrapActive = FALSE
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Retuns whether a specified submarine scrap is collected or not
/// PARAMS:
/// the index of the submarine scrap you want
/// RETURNS:
/// TRUE if scrap picked up, else FALSE
FUNC BOOL HAS_PLAYER_PICKED_UP_SCRAP(SCRAP_MISSION scrapMissionType, INT index)
INT ipackNum
INT ipackStart
IF (scrapMissionType = SCRAP_LETTER)
ipackStart = PACKSTAT_LETTER_START
ELIF (scrapMissionType = SCRAP_SHIP)
ipackStart = PACKSTAT_UFO_START
ELIF (scrapMissionType = SCRAP_SUB)
ipackStart = PACKSTAT_SONAR_START
ELIF (scrapMissionType = SCRAP_TRACT)
ipackStart = PACKSTAT_TRACT_START
ELIF (scrapMissionType = SCRAP_DIVING)
ipackStart = PACKSTAT_DIVING_START
ENDIF
ipackNum = ipackStart + index
RETURN GET_PACKED_STAT_BOOL(INT_TO_ENUM(STATS_PACKED, ipackNum))
ENDFUNC
#IF IS_DEBUG_BUILD
USING "shared_debug.sch"
/// PURPOSE:
/// Warps ped near scrap or for sale sign if need be
/// PARAMS:
/// VECTOR vTempScrapCoord = scrap's coords
/// FLOAT fTempScrapHeading = scraps heading
/// INT iScrap = number of the scrap
/// RETURNS:
/// N/A
PROC OUTPUT_TEMP_DATA(VECTOR vTempScrapCoord,
FLOAT fTempScrapHeading,
INT iScrap)
TEXT_LABEL_63 tlTemp
OPEN_DEBUG_FILE()
SAVE_NEWLINE_TO_DEBUG_FILE()
tlTemp = "vScrapCoords["
tlTemp += iScrap
tlTemp += "] = "
SAVE_STRING_TO_DEBUG_FILE(tlTemp)
SAVE_VECTOR_TO_DEBUG_FILE(vTempScrapCoord)
SAVE_STRING_TO_DEBUG_FILE(" ")
tlTemp = "fScrapHeading["
tlTemp += iScrap
tlTemp += "] = "
SAVE_STRING_TO_DEBUG_FILE(tlTemp)
SAVE_FLOAT_TO_DEBUG_FILE(fTempScrapHeading)
SAVE_NEWLINE_TO_DEBUG_FILE()
CLOSE_DEBUG_FILE()
ENDPROC
/// PURPOSE:
/// Warps player near scrap or for sale sign if need be
/// PARAMS:
/// BOOL& bWarp = If warping is needed
/// VECTOR vScrapCoords = scrap's coords
PROC CHECK_WARP_TO_PACKAGE(BOOL& bWarp, VECTOR vScrapCoords)
IF bWarp
LOAD_SCENE(vScrapCoords)
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), vScrapCoords+<<0.0, -1.5, 0.0>>, 0.0)
IF IS_PED_SWIMMING_UNDER_WATER(PLAYER_PED_ID()) //so player doesn't automatically collect it
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), vScrapCoords+<<0.0, -2.5, 0.0>>, 0.0)
FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_DIVING_IDLE)
ENDIF
bWarp = FALSE
ENDIF
ENDPROC
/// PURPOSE:
/// Prints the number in the parameter
/// PARAMS:
/// INT iScrapNum = the scrap number
PROC PRINT_SCRAP_NUMBER(INT iScrapNum)
CPRINTLN(DEBUG_AMBIENT,"[Hidden Packages] Collected scrap: ", iScrapNum)
iDebugScrapCreatedNum--
CPRINTLN(DEBUG_AMBIENT,"[Hidden Packages] So far there are: ", iDebugScrapCreatedNum)
ENDPROC
/// PURPOSE:
/// Blips scrap or for sale sign if need be
/// PARAMS:
/// BOOL bMapScraps = if the scraps need mapping (TRUE if they do else FALSE)
/// BLIP_INDEX scrapBlip = the scrap blip
/// INT iScrap = the scrap number
/// INT iNumScrapParts = number of scrap parts
/// SCRAP_MISSION scrapMissionType = the scrap mission type
/// VECTOR vScrapCoord = coord of the scrap
/// RETURNS:
/// N/A
PROC MAP_SCRAP_CHECK(BOOL bMapScraps, BLIP_INDEX& scrapBlip, INT iScrap, INT iNumScrapParts, SCRAP_MISSION scrapMissionType, VECTOR vScrapCoord)
BOOL bCollected = TRUE
IF (scrapMissionType = SCRAP_SALE_SIGNS)
bCollected = IS_BIT_SET(g_savedGlobals.sAmbient.iForSaleSignDestroyedFlags, RETURN_BIT_FLAG_SLOT(iNumScrapParts, iScrap))
ELSE
bCollected = HAS_PLAYER_PICKED_UP_SCRAP( scrapMissionType, iScrap)
ENDIF
IF bMapScraps
IF NOT DOES_BLIP_EXIST(scrapBlip)
AND NOT bCollected
scrapBlip = ADD_BLIP_FOR_COORD(vScrapCoord)
SET_BLIP_SCALE(scrapBlip, 1)
SET_BLIP_COLOUR(scrapBlip, BLIP_COLOUR_GREEN)
ELSE
IF bCollected
SAFE_REMOVE_BLIP(scrapBlip)
ENDIF
ENDIF
ELSE
SAFE_REMOVE_BLIP(scrapBlip)
ENDIF
ENDPROC
#ENDIF