// ***************************************************************************************** // ***************************************************************************************** // // FILE NAME : scrap_common.sch // AUTHOR : Aaron Gandaa // // ***************************************************************************************** // ***************************************************************************************** //---------------------- // INCLUDES //---------------------- USING "RC_Helper_Functions.sch" USING "common_packages.sch" USING "CompletionPercentage_public.sch" //---------------------- // CONSTS //---------------------- CONST_INT SCRAPS_TO_CHECK_PER_FRAME 1 CONST_FLOAT PICKUP_HACK_DISTANCE 5.0 //so the Player can collect pickups in a submersible //---------------------- // STRUCTS //---------------------- STRUCT SCRAP_COLLECT_DATA INT iScrap0to31 = 0 // Bitfields storing whether scraps 0 to 63 have been picked up INT iScrap32to63 = 0 // Not used for spaceship and letter scraps as these are globally stored for Chop INT iPackNumBase = 0 // Index in the pack stat bools for the start of the array INT iMaxScraps = 0 // Maximum number of scraps to collect INT iScrapsCollected = 0 // Total number of scraps that have been collected ENDSTRUCT STRUCT SCRAP_MISSION_DATA SCRAP_MISSION missionType // Spaceship, letter scrap, etc. SCRAP_COLLECT_DATA scrapData // Scrap collection data STATSENUM packageStat // Hidden package stat MODEL_NAMES packageMdl // Model type for pickup STRING sScrapGetMsg // Message upon collecting a scrap INT iMessageTimer = 0 INT iCurrentCheckIndex = 0 // Current scrap being checked BOOL bDisplayMessage = FALSE BOOL bMessageOnDisplay ENDSTRUCT //---------------------- // FUNCTIONS //---------------------- BOOL bShowScrapDebugTTY = TRUE BOOL bUseQuickScrapCollectCheck = TRUE //---------------------- // FUNCTIONS //---------------------- /// PURPOSE: /// Checks to see if a pickup has been collected whilst the Player is in a vehicle like a submersible. /// Since pickup collection doesn't work with a vehicle we have to check for distance instead /// PARAMS: /// thePickup - the pickup to check /// RETURNS: /// true if scrap has been collected whilst in a water vehicle FUNC BOOL HAS_PLAYER_COLLECTED_PICKUP_IN_WATER_VEHICLE(PICKUP_INDEX thePickup) IF NOT DOES_PICKUP_EXIST(thePickup) RETURN FALSE ENDIF IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) // Get player vehicle VEHICLE_INDEX tmpVehicle MODEL_NAMES tmpModel tmpVehicle = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()) tmpModel = GET_ENTITY_MODEL(tmpVehicle) IF tmpModel = SUBMERSIBLE OR tmpModel = SUBMERSIBLE2 IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_PICKUP_COORDS(thePickup)) < (PICKUP_HACK_DISTANCE * PICKUP_HACK_DISTANCE) OR IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), GET_PICKUP_OBJECT(thePickup)) // Added because the sub2 has bits that stick out >5m from player coords RETURN TRUE ENDIF ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: // Print a message stating how many signs have been destroyed if this is needed... // Now using the Midsized message UI as per Les request /// PARAMS: // data - contains needed data // iMessageStage - the stage of the message displaying (for the case statement) // siMessage - scaleform index // sTitle - the message string to display (e.g so many scraps collected/ destroyed) PROC UPDATE_DISPLAY_MESSAGE(BOOL &bDisplayMessage, BOOL &bMessageOnDisplay, INT &iMessageTimer, SCRAP_MISSION missionType, INT &iMessageStage, SCALEFORM_INDEX &siMessage, STRING sTitle, STRING sScrapGetMsg) INT iSplashSoundID //Failsafe: set this flag false at the beginning SET_COLLECTED_SCREEN_DISPLAYING(FALSE) IF bDisplayMessage SWITCH iMessageStage CASE 0 siMessage = REQUEST_SCALEFORM_MOVIE("MIDSIZED_MESSAGE") IF HAS_SCALEFORM_MOVIE_LOADED(siMessage) iSplashSoundID = GET_SOUND_ID() IF missionType = SCRAP_PEYOTE PLAY_SOUND_FRONTEND(iSplashSoundID, "PEYOTE_COMPLETED", "HUD_AWARDS") ELSE PLAY_SOUND_FRONTEND(iSplashSoundID, "COLLECTED", "HUD_AWARDS") ENDIF iMessageStage++ ENDIF BREAK CASE 1 BEGIN_SCALEFORM_MOVIE_METHOD(siMessage, "SHOW_SHARD_MIDSIZED_MESSAGE") BEGIN_TEXT_COMMAND_SCALEFORM_STRING(sTitle) END_TEXT_COMMAND_SCALEFORM_STRING() BEGIN_TEXT_COMMAND_SCALEFORM_STRING(sScrapGetMsg) ADD_TEXT_COMPONENT_INTEGER(GET_NUM_SCRAPS_SORTED(missionType)) END_TEXT_COMMAND_SCALEFORM_STRING() END_SCALEFORM_MOVIE_METHOD() iMessageTimer = GET_GAME_TIMER() iMessageStage++ BREAK CASE 2 IF (GET_GAME_TIMER() - iMessageTimer) > DEFAULT_GOD_TEXT_TIME - 500 BEGIN_SCALEFORM_MOVIE_METHOD(siMessage, "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() iMessageStage++ ELSE IF NOT IS_RESULT_SCREEN_DISPLAYING() IF HAS_SCALEFORM_MOVIE_LOADED(siMessage) SET_COLLECTED_SCREEN_DISPLAYING(TRUE) DRAW_SCALEFORM_MOVIE_FULLSCREEN(siMessage, 100, 100, 100, 255 ) ENDIF ENDIF ENDIF BREAK CASE 3 IF (GET_GAME_TIMER() - iMessageTimer) > DEFAULT_GOD_TEXT_TIME iMessageStage++ ELSE IF NOT IS_RESULT_SCREEN_DISPLAYING() IF HAS_SCALEFORM_MOVIE_LOADED(siMessage) SET_COLLECTED_SCREEN_DISPLAYING(TRUE) DRAW_SCALEFORM_MOVIE_FULLSCREEN(siMessage, 100, 100, 100, 255 ) ENDIF ENDIF ENDIF BREAK CASE 4 IF HAS_SCALEFORM_MOVIE_LOADED(siMessage) SET_SCALEFORM_MOVIE_AS_NO_LONGER_NEEDED(siMessage) ENDIF SET_COLLECTED_SCREEN_DISPLAYING(FALSE) bMessageOnDisplay = FALSE bDisplayMessage = FALSE iMessageStage = 0 BREAK ENDSWITCH ENDIF ENDPROC PROC CALCULATE_TOTAL_HIDDEN_PACKAGES_COLLECTED_PERCENTAGE() INT iValue INT iTotalGot, iTotal INT iPercent = 0 //Get stats and update collected scap achievement STAT_GET_INT(GET_HIDDEN_PACKAGES_NUM(SCRAP_SHIP), iValue) iTotalGot += iValue // Spaceship Parts IF iValue>0 SET_ACHIEVEMENT_PROGRESS_SAFE(ENUM_TO_INT(ACH15),iValue) ENDIF STAT_GET_INT(GET_HIDDEN_PACKAGES_NUM(SCRAP_LETTER), iValue) iTotalGot += iValue // Letter Scraps IF iValue>0 SET_ACHIEVEMENT_PROGRESS_SAFE(ENUM_TO_INT(ACH16),iValue) ENDIF STAT_GET_INT(GET_HIDDEN_PACKAGES_NUM(SCRAP_SUB), iValue) iTotalGot += iValue // Submarine parts IF iValue>0 SET_ACHIEVEMENT_PROGRESS_SAFE(ENUM_TO_INT(ACH17),iValue) ENDIF iTotal = GET_NUM_PARTS(SCRAP_SHIP) + GET_NUM_PARTS(SCRAP_LETTER) + GET_NUM_PARTS(SCRAP_SUB) IF (iTotal > 0) iPercent = (iTotalGot * 100) / iTotal ENDIF STAT_SET_INT(PERCENT_HIDDEN_PACKAGES, iPercent) ENDPROC /// PURPOSE: /// Checks to see if a scrap from a list has been collected /// PARAMS: /// list - scrap list reference /// index - index to check /// RETURNS: /// true if scrap has been collected FUNC BOOL HAS_SCRAP_BEEN_COLLECTED(SCRAP_COLLECT_DATA &list, INT index) IF (index < 0) OR (index >= 64) SCRIPT_ASSERT("SCRAP INDEX IS INVALID!!") RETURN FALSE ENDIF // if scrap index is 31 or less use first int IF (index <= 31) RETURN IS_BIT_SET(list.iScrap0to31, index) ENDIF // else take 32 from index and use second int RETURN IS_BIT_SET(list.iScrap32to63, index - 32) ENDFUNC /// PURPOSE: /// Marks a scrap in the list as collected /// PARAMS: /// collectData - scrap list reference /// index - index to mark /// bCollected - set this as true to mark is collected, false to uncollect PROC SET_SCRAP_AS_COLLECTED(SCRAP_COLLECT_DATA &collectData, INT index, BOOL bCollected=TRUE) IF (index < 0) OR (index >= 64) SCRIPT_ASSERT("SET_SCRAP_AS_COLLECTED - SCRAP INDEX IS INVALID!!!") EXIT ENDIF // If scrap index is 31 or less use first int IF (index <= 31) IF (bCollected) SET_BIT(collectData.iScrap0to31, index) ELSE CLEAR_BIT(collectData.iScrap0to31, index) ENDIF EXIT ENDIF // Otherwise take 32 from index and use second int IF (bCollected) SET_BIT(collectData.iScrap32to63, index - 32) ELSE CLEAR_BIT(collectData.iScrap32to63, index - 32) ENDIF ENDPROC /// PURPOSE: /// Update global bitsets for Chop /// Current duplicate bitsets for letter scraps and spaceship parts /// Ambient script will check locals - Chop will access the globals - not ideal, but simplest for now /// To be improved.. PROC UPDATE_GLOBAL_SCRAP_DATA(SCRAP_MISSION missionType, INT index, BOOL bCollected=TRUE) IF (index < 0) OR (index >= 64) SCRIPT_ASSERT("UPDATE_GLOBAL_SCRAP_DATA - SCRAP INDEX IS INVALID!!!") EXIT ENDIF // Letter scraps IF missionType = SCRAP_LETTER IF (index <= 31) IF (bCollected) SET_BIT(g_savedGlobals.sAmbient.sLetterScrapData.iScrap0to31, index) ELSE CLEAR_BIT(g_savedGlobals.sAmbient.sLetterScrapData.iScrap0to31, index) ENDIF EXIT ENDIF IF (bCollected) SET_BIT(g_savedGlobals.sAmbient.sLetterScrapData.iScrap32to63, index - 32) ELSE CLEAR_BIT(g_savedGlobals.sAmbient.sLetterScrapData.iScrap32to63, index - 32) ENDIF // Spaceship parts ELIF missionType = SCRAP_SHIP IF (index <= 31) IF (bCollected) SET_BIT(g_savedGlobals.sAmbient.sSpaceshipPartData.iScrap0to31, index) ELSE CLEAR_BIT(g_savedGlobals.sAmbient.sSpaceshipPartData.iScrap0to31, index) ENDIF EXIT ENDIF IF (bCollected) SET_BIT(g_savedGlobals.sAmbient.sSpaceshipPartData.iScrap32to63, index - 32) ELSE CLEAR_BIT(g_savedGlobals.sAmbient.sSpaceshipPartData.iScrap32to63, index - 32) ENDIF ENDIF ENDPROC /// PURPOSE: /// This looks at the packed stats and fills the scrap list from it /// PARAMS: /// list - scrap list reference /// iStatPackIndex - first index of the stats to use - eg for letter scraps use PACKSTAT_LETTER_START /// iMaxScraps - the total number of scraps to collect, so for letter scraps this would be 50 PROC SET_SCRAP_COLLECT_DATA_FROM_PACKED_STATS(SCRAP_COLLECT_DATA &list, INT iStatPackIndex, INT iMaxScraps) INT i INT cnt = 0 // clear scrap list - we'll fill these from packed stats in a second list.iScrap0to31 = 0 list.iScrap32to63 = 0 // set max scraps and stat packed list index list.iPackNumBase = iStatPackIndex list.iMaxScraps = iMaxScraps // fill scrap array from stats IF (bShowScrapDebugTTY) CPRINTLN(DEBUG_AMBIENT, "Checking Scrap List From Stats - Stat Index Base:", list.iPackNumBase, " Max Scraps:", list.iMaxScraps) ENDIF REPEAT list.iMaxScraps i IF GET_PACKED_STAT_BOOL(INT_TO_ENUM(STATS_PACKED, list.iPackNumBase + i)) cnt ++ SET_SCRAP_AS_COLLECTED(list, i) IF (bShowScrapDebugTTY) CPRINTLN(DEBUG_AMBIENT, "Scrap Index: ", i, " has been collected.") ENDIF ENDIF ENDREPEAT list.iScrapsCollected = cnt IF (bShowScrapDebugTTY) CPRINTLN(DEBUG_AMBIENT, "Number of Scraps Collected: ", cnt) CPRINTLN(DEBUG_AMBIENT, "Number of Scraps Remaining: ", list.iMaxScraps - cnt) ENDIF ENDPROC /// PURPOSE: /// This sets packed stats from a scrap collect list /// Make sure list.iPackNumBase and list.iMaxScraps has been set before using this /// PARAMS: /// list - PROC SET_PACKED_STATS_FROM_SCRAP_COLLECT_DATA(SCRAP_COLLECT_DATA &list) INT i INT cnt = 0 IF (list.iMaxScraps <= 0) SCRIPT_ASSERT("list.iMaxScraps is invalid - set this using SET_SCRAP_COLLECT_DATA_FROM_PACKED_STATS()") ENDIF IF (list.ipackNumBase <= 0) SCRIPT_ASSERT("list.ipackNumBase is invalid - set this using SET_SCRAP_COLLECT_DATA_FROM_PACKED_STATS()") ENDIF IF (bShowScrapDebugTTY) CPRINTLN(DEBUG_AMBIENT, "Checking Scrap List From Scrap List - Stat Index Base:", list.iPackNumBase, " Max Scraps:", list.iMaxScraps) ENDIF REPEAT list.iMaxScraps i IF HAS_SCRAP_BEEN_COLLECTED(list, i) cnt ++ SET_PACKED_STAT_BOOL(INT_TO_ENUM(STATS_PACKED, list.ipackNumBase + i), TRUE) IF (bShowScrapDebugTTY) CPRINTLN(DEBUG_AMBIENT, "Scrap Index: ", i, " has been collected.") ENDIF ENDIF ENDREPEAT list.iScrapsCollected = cnt IF (bShowScrapDebugTTY) CPRINTLN(DEBUG_AMBIENT, "Number of Scraps Collected: ", cnt) CPRINTLN(DEBUG_AMBIENT, "Number of Scraps Remaining: ", list.iMaxScraps - cnt) ENDIF //Activate Dreyfus mission as soon as all are collected IF (cnt=list.iMaxScraps) AND (list.ipackNumBase = PACKSTAT_LETTER_START) Execute_Code_ID(CID_DREYFUSS1_COMPLETE_LETTER_SCRAPS, 0) ENDIF ENDPROC /// PURPOSE: /// This sets packed stats from a scrap collect list /// Make sure list.iPackNumBase and list.iMaxScraps has been set before using this /// PARAMS: /// list - PROC SET_SINGLE_PACKED_STAT_FROM_SCRAP_COLLECT_DATA(SCRAP_COLLECT_DATA &list, INT iIndex) CPRINTLN(DEBUG_AMBIENT, "SET_SINGLE_PACKED_STAT_FROM_SCRAP_COLLECT_DATA - ", iIndex) IF (list.iMaxScraps <= 0) SCRIPT_ASSERT("list.iMaxScraps is invalid - set this using SET_SCRAP_COLLECT_DATA_FROM_PACKED_STATS()") ENDIF IF (list.ipackNumBase <= 0) SCRIPT_ASSERT("list.ipackNumBase is invalid - set this using SET_SCRAP_COLLECT_DATA_FROM_PACKED_STATS()") ENDIF IF (bShowScrapDebugTTY) CPRINTLN(DEBUG_AMBIENT, "Checking Scrap List From Scrap List - Stat Index Base:", list.iPackNumBase, " Max Scraps:", list.iMaxScraps) ENDIF IF (iIndex >= list.iMaxScraps) SCRIPT_ASSERT("trying to pass in an index which is bigger than the maximum number of scraps") ENDIF IF HAS_SCRAP_BEEN_COLLECTED(list, iIndex) list.iScrapsCollected ++ SET_PACKED_STAT_BOOL(INT_TO_ENUM(STATS_PACKED, list.ipackNumBase + iIndex), TRUE) IF (bShowScrapDebugTTY) CPRINTLN(DEBUG_AMBIENT, "Scrap Index: ", iIndex, " has been collected.") ENDIF ENDIF IF (bShowScrapDebugTTY) CPRINTLN(DEBUG_AMBIENT, "Number of Scraps Collected: ", list.iScrapsCollected) CPRINTLN(DEBUG_AMBIENT, "Number of Scraps Remaining: ", list.iMaxScraps - list.iScrapsCollected) ENDIF //Activate Dreyfus mission as soon as all are collected IF (list.iScrapsCollected=list.iMaxScraps) AND (list.ipackNumBase = PACKSTAT_LETTER_START) Execute_Code_ID(CID_DREYFUSS1_COMPLETE_LETTER_SCRAPS, 0) ENDIF ENDPROC /// PURPOSE: /// Checks to see if all scrap from a list has been collected /// SET_PACKED_STATS_FROM_SCRAP_COLLECT_DATA() or SET_SCRAP_COLLECT_DATA_FROM_PACKED_STATS() /// should called at least once before using this... /// PARAMS: /// list - script reference /// RETURNS: /// true if scrap has been collected FUNC BOOL HAVE_ALL_SCRAPS_BEEN_COLLECTED(SCRAP_COLLECT_DATA &list) IF (list.iMaxScraps <= 0) SCRIPT_ASSERT("list.iMaxScraps is invalid - call this SET_SCRAP_COLLECT_DATA_FROM_PACKED_STATS() or SET_SCRAP_COLLECT_DATA_FROM_PACKED_STATS() at least once before using this") ENDIF RETURN (list.iScrapsCollected >= list.iMaxScraps) ENDFUNC /// PURPOSE: /// Collects A Scrap /// PARAMS: /// missionData - scrap mission data reference /// pickupData - reference to mission scrap array /// iIndex - index of scrap to collect PROC COLLECT_SCRAP(SCRAP_MISSION_DATA &missionData, SCRAP_PICKUP_DATA &pickupData[], INT iIndex) CPRINTLN(DEBUG_AMBIENT, "Scrap ", iIndex, " Collected") INT ipackNum = (GET_PACK_STAT(missionData.missionType)) + iIndex // Remove pickup and blip SAFE_REMOVE_PICKUP(pickupData[iIndex].pickup) SAFE_REMOVE_BLIP(pickupData[iIndex].blip) // Update pickup data pickupData[iIndex].pickup = NULL pickupData[iIndex].bActive = FALSE // Mark scrap as collected SET_SCRAP_AS_COLLECTED(missionData.scrapData, iIndex) // Update globals for Chop IF missionData.missionType = SCRAP_LETTER OR missionData.missionType = SCRAP_SHIP UPDATE_GLOBAL_SCRAP_DATA(missionData.missionType, iIndex) ENDIF // Rumble on collection SET_CONTROL_SHAKE(PLAYER_CONTROL, PICKUP_RUMBLE_DURATION, PICKUP_RUMBLE_FREQ) // Update stats STAT_INCREMENT(missionData.packageStat, 1.0) IF (bUseQuickScrapCollectCheck) SET_SINGLE_PACKED_STAT_FROM_SCRAP_COLLECT_DATA(missionData.scrapData, iIndex) ELSE SET_PACKED_STATS_FROM_SCRAP_COLLECT_DATA(missionData.scrapData) ENDIF CALCULATE_TOTAL_HIDDEN_PACKAGES_COLLECTED_PERCENTAGE() PLAYSTATS_ACQUIRED_HIDDEN_PACKAGE(ipackNum) // Request autosave SET_AUTOSAVE_IGNORES_ON_MISSION_FLAG(TRUE) MAKE_AUTOSAVE_REQUEST() // Signal that a message needs to be displayed missionData.bDisplayMessage = TRUE ENDPROC /// PURPOSE: /// Sets all the pickups in the given array to false /// PARAMS: /// pickupData - reference to mission scrap array PROC SET_PICKUPS_ACTIVE_TO_FALSE(SCRAP_PICKUP_DATA& pickupData[]) INT i REPEAT (COUNT_OF(pickupData)) i pickupData[i].bActive = FALSE ENDREPEAT ENDPROC /// PURPOSE: /// returns the closest coord to the player /// PARAMS: /// vec1 - the first coord to check /// vec2 - the second coord to check FUNC VECTOR RETURN_CLOSEST(VECTOR vec1, VECTOR vec2) IF (GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), vec1) < GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), vec2)) RETURN vec1 ELSE RETURN vec2 ENDIF ENDFUNC /// PURPOSE: /// Handles looking at a pickup /// PARAMS: /// pickupData - reference to mission scrap array /// index - the index of the pickup PROC SORT_HEADTRACKING(SCRAP_PICKUP_DATA &pickupData[], INT iIndex) // Pickup is active and has been created IF pickupData[iIndex].bActive IF (pickupData[iIndex].pickup != NULL) //sort looking at scrap if close IF IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), pickupData[iIndex].vCoords, 10.0) TASK_LOOK_AT_COORD(PLAYER_PED_ID(), pickupData[iIndex].vCoords, 300, SLF_WHILE_NOT_IN_FOV, SLF_LOOKAT_LOW) IF (bShowScrapDebugTTY) CPRINTLN(DEBUG_AMBIENT, "look at scrap") ENDIF ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// Handles collecting and removing a pickup /// PARAMS: /// missionData - mission scrap data reference /// pickupData - reference to mission scrap array /// playerPos - we just pass this in to save calling GET_ENTITY_COORDS() FUNC BOOL UPDATE_SCRAP_PICKUP(SCRAP_MISSION_DATA &missionData, SCRAP_PICKUP_DATA &pickupData[], VECTOR playerPos) // Get current index INT iIndex = missionData.iCurrentCheckIndex // Pickup is active and has been created IF pickupData[iIndex].bActive IF (pickupData[iIndex].pickup != NULL) // Has the player collected the pickup? IF HAS_PICKUP_BEEN_COLLECTED(pickupData[iIndex].pickup) OR HAS_PLAYER_COLLECTED_PICKUP_IN_WATER_VEHICLE(pickupData[iIndex].pickup) COLLECT_SCRAP(missionData, pickupData, iIndex) RETURN TRUE ENDIF ENDIF ENDIF // Handle removing the pickup - we use vdist2 it's quicker IF DOES_PICKUP_EXIST(pickupData[iIndex].pickup) IF (VDIST2(playerPos, GET_PICKUP_COORDS(pickupData[iIndex].pickup)) > (CLEANUP_PICKUP_DISTANCE * CLEANUP_PICKUP_DISTANCE)) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_ANIMAL) OR IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) //Don't allow creation of pickups while playing as a none story character. SAFE_REMOVE_PICKUP(pickupData[iIndex].pickup) pickupData[iIndex].pickup = NULL pickupData[iIndex].bActive = FALSE ENDIF ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Returns the nearest pickup index from a position /// PARAMS: /// missionData - mission scrap data reference /// pickupData - reference to mission scrap array /// pos - position we need to check /// out - Index into array or -1 if one can't be found /// RETURNS: /// TRUE / FALSE FUNC BOOL GET_NEAREST_PICKUP_INDEX(SCRAP_MISSION_DATA &missionData, SCRAP_PICKUP_DATA& pickupData[], VECTOR pos, INT &out) INT i = 0 FLOAT dist = 0 FLOAT minDist = -1.0 REPEAT COUNT_OF(pickupData) i IF NOT HAS_SCRAP_BEEN_COLLECTED(missionData.scrapData, i) dist = VDIST2(pos, pickupData[i].vCoords) IF (minDist = -1.0) OR (dist < minDist) out = i minDist = dist ENDIF ENDIF ENDREPEAT RETURN (out <> -1) ENDFUNC /// PURPOSE: /// Blips all scrap positions PROC BLIP_SCRAP_POSITIONS(SCRAP_MISSION_DATA &missionData, SCRAP_PICKUP_DATA &pickupData[], BOOL bShowBlip = TRUE) INT i REPEAT COUNT_OF(pickupData) i SAFE_REMOVE_BLIP(pickupData[i].blip) IF (bShowBlip) pickupData[i].blip = CREATE_COORD_BLIP(pickupData[i].vCoords, BLIPPRIORITY_MED, FALSE) IF DOES_BLIP_EXIST(pickupData[i].blip) IF HAS_SCRAP_BEEN_COLLECTED(missionData.scrapData, i) SET_BLIP_SCALE(pickupData[i].blip, 0.25) ELSE SET_BLIP_SCALE(pickupData[i].blip, 1) ENDIF SET_BLIP_COLOUR(pickupData[i].blip, BLIP_COLOUR_GREEN) ENDIF ENDIF ENDREPEAT ENDPROC /// PURPOSE: /// Setups Variables for a scrap mission /// PARAMS: /// data - mission data reference /// type - mission type num /// mdl - model of the package /// sGetMsg - message to be shown when one piece of scrap is got /// sAllGetMsg - message to be show when all scrap is got PROC SETUP_SCRAP_MISSION(SCRAP_MISSION_DATA &data, SCRAP_MISSION type, MODEL_NAMES mdl, STRING sGetMsg) data.missionType = type data.packageMdl = mdl data.sScrapGetMsg = sGetMsg data.iCurrentCheckIndex = 0 ENDPROC /// PURPOSE: /// Setups Variables for a scrap mission /// PARAMS: /// data - mission data reference /// stat - enum to the stat we write to - eg: for letter scraps this would be NUM_HIDDEN_PACKAGES_0 /// statpacnum - first index of the stats to use - eg: for letter scraps use PACKSTAT_LETTER_START /// maxScrap - the total number of scraps to collect - eg: for letter scraps this would be 50 PROC SETUP_SCRAP_MISSION_STATS(SCRAP_MISSION_DATA &data, STATSENUM stat, INT statpacnum, INT maxScrap) data.packageStat = stat SET_SCRAP_COLLECT_DATA_FROM_PACKED_STATS(data.scrapData, statpacnum, maxScrap) ENDPROC /// PURPOSE: /// This sets packed stats from a scrap collect list /// Make sure list.iPackNumBase and list.iMaxScraps has been set before using this /// PARAMS: /// list - PROC RESET_SCRAP_MISSION_COLLECTION(SCRAP_MISSION_DATA &data) INT i CPRINTLN(DEBUG_AMBIENT, "Resetting Scrap Collection") STAT_SET_INT(data.packageStat, 0) REPEAT data.scrapData.iMaxScraps i SET_SCRAP_AS_COLLECTED(data.scrapData, i, FALSE) ENDREPEAT SET_PACKED_STATS_FROM_SCRAP_COLLECT_DATA(data.scrapData) ENDPROC /// PURPOSE: /// Helper function for finding an available grass cull sphere. /// Check that this returns TRUE before using the passed INT! /// PARAMS: /// iSphere - Will be set to an available sphere index, or -1 /// RETURNS: /// TRUE if a valid sphere index was set. FALSE if all spheres are in use. FUNC BOOL IS_A_CULLSPHERE_AVAILABLE(INT &iSphere) iSphere = 0 REPEAT NUMBER_AVAILABLE_CULLSPHERES iSphere IF NOT PROCGRASS_IS_CULLSPHERE_ENABLED(iSphere) CPRINTLN(DEBUG_AMBIENT, "IS_A_CULLSPHERE_AVAILABLE returning index: ", iSphere, " to script: ", GET_THIS_SCRIPT_NAME()) RETURN TRUE ENDIF ENDREPEAT CERRORLN(DEBUG_AMBIENT, "IS_A_CULLSPHERE_AVAILABLE was unable to find an available index for script: ", GET_THIS_SCRIPT_NAME()) iSphere = -1 RETURN FALSE ENDFUNC