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

2245 lines
83 KiB
Scheme
Executable File

// *****************************************************************************************
// *****************************************************************************************
//
// SCRIPT NAME : achievement_public.sch
// AUTHOR : Aaron Gandaa
//
// *****************************************************************************************
// *****************************************************************************************
//----------------------
// INCLUDES
//----------------------
USING "rage_builtins.sch"
USING "globals.sch"
USING "commands_stats.sch"
USING "achievements_enum.sch"
USING "net_stat_system.sch"
USING "transition_saving.sch"
USING "net_system_activity_feed.sch"
USING "candidate_public.sch"
USING "script_conversion.sch"
USING "flyunderbridges.sch"
//----------------------
// CONSTS
//----------------------
CONST_INT ACH10_GOLDS_NEEDED 70
CONST_INT ACH13_AIR_TOTAL 5
CONST_INT ACH13_GND_TOTAL 5
CONST_INT ACH19_STUNTJUMPS 50
CONST_INT ACH24_CASH_NEEDED 200000000
CONST_INT ACH31_RANK_NEEDED 25
CONST_INT ACH32_RANK_NEEDED 50
CONST_INT ACH33_RANK_NEEDED 100
CONST_INT ACH35_CUSTOM_RACES_WON 5
CONST_INT ACH36_WAVESSURVIVED 10
//CONST_INT ACH37_CLEARSNEEDED 20
CONST_INT ACH40_KILLSNEEDED 10
CONST_INT ACH41_AWARDS_NEEDED 30
CONST_INT ACH43_HOLDUPSNEEDED 20
// First Person Achievement
CONST_INT ACH_FIRST_PERSON_MODE_HOURS 15 // achievement unlock time in first person mode threshold in hours
//CONST_INT ACH44_BOUNTIESKILLED 10
CONST_FLOAT ACH21_SURVIVE_TIME 180.0
//----------------------
// ENUM
//----------------------
ENUM eACH45BitFlags
ACH45_GOLF,
ACH45_TENNIS,
ACH45_ARMWRESTLING,
ACH45_DARTS,
ACH45_SHOOTING,
ACH45_LAPDANCE,
ACH45_CLOTHES,
ACH45_TATTOO,
ACH45_HAIRCUT,
MAX_ACH45_FLAGS
ENDENUM
ENUM eHeistACHCheckID
HEISTACH_INVALID = -1,
HEISTACH_H1_DONE = 0,
HEISTACH_H2_DONE,
HEISTACH_H3_DONE,
HEISTACH_H4_DONE,
HEISTACH_H5_DONE,
HEISTACH_H6_DONE,
HEISTACH_H7_DONE,
HEISTACH_H8_DONE,
HEISTACH_H9_DONE,
HEISTACH_H10_DONE,
HEISTACH_HUMANELAB_DONE,
HEISTACH_SERIESA_DONE,
HEISTACH_FLECCAJOB_DONE,
HEISTACH_PACIFIC_DONE,
HEISTACH_PRISON_DONE,
HEISTACH_CREW_CUT,
HEISTACH_CREW_CUT_SANCHECK,
MAX_HEISTACHCHK_ID
ENDENUM
ENUM eGangOpsAchCheck
GOPS_ACH_INVALID = -1,
GOPS_ACH_1_DONE = 0,
GOPS_ACH_2_DONE,
GOPS_ACH_3_DONE,
GOPS_ACH_4_DONE,
GOPS_ACH_5_DONE,
GOPS_ACH_6_DONE,
GOPS_ACH_7_DONE,
GOPS_ACH_8_DONE,
MAX_GOPS_ACH
ENDENUM
//----------------------
// FUNCTIONS
//----------------------
FUNC INT COUNT_ACHIEVEMENTS()
INT i
INT cnt
REPEAT ENUM_TO_INT(ACHIEVEMENT_COUNT) i
IF (i > 0)
IF HAS_ACHIEVEMENT_BEEN_PASSED(i)
cnt ++
ENDIF
ENDIF
ENDREPEAT
/*
IF (cnt = (ENUM_TO_INT(ACHIEVEMENT_COUNT) - 1))
IF IS_PS3_VERSION()
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: We should be awarding a platinum here - but I haven't worked out how to do that yet")
IF NOT HAS_ACHIEVEMENT_BEEN_PASSED(PLATINUM)
GIVE_ACHIEVEMENT_TO_PLAYER(PLATINUM)
ENDIF
ELSE
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: No platinum for Xbox")
ENDIF
ENDIF
*/
RETURN cnt
ENDFUNC
FUNC STRING DEBUG_GET_ACHIEVEMENT_TITLE(ACHIEVEMENT_ENUM achEnum)
SWITCH (achEnum)
CASE ACH00 RETURN "WELCOME TO LOS SANTOS"
CASE ACH01 RETURN "A FRIENDSHIP RESURRECTED"
CASE ACH02 RETURN "A FAIR DAY'S PAY"
CASE ACH03 RETURN "THE MOMENT OF TRUTH"
CASE ACH04 RETURN "TO LIVE OR DIE IN LOS SANTOS"
CASE ACH05 RETURN "DIAMOND HARD"
CASE ACH06 RETURN "SUBVERSIVE"
CASE ACH42 RETURN "BLITZED"
CASE ACH07 RETURN "BIG TOWN SMALL JOB"
CASE ACH08 RETURN "THE GOVERNMENT GIMPS"
CASE ACH09 RETURN "THE BIG ONE"
CASE ACH10 RETURN "SOLID GOLD BABY"
CASE ACH11 RETURN "CAREER CRIMINAL"
CASE ACH50 RETURN "SAN ANDREAS SIGHTSEER"
CASE ACH12 RETURN "ALL'S FAIR IN LOVE AND WAR"
CASE ACH13 RETURN "TP INDUSTRIES ARMS RACE"
CASE ACH14 RETURN "MULTI-DISCIPLINED"
CASE ACH15 RETURN "FROM BEYOND THE STARS"
CASE ACH16 RETURN "A MYSTERY, SOLVED"
CASE ACH17 RETURN "WASTE MANAGEMENT"
CASE ACH18 RETURN "RED MIST"
CASE ACH19 RETURN "SHOW OFF"
CASE ACH20 RETURN "KIFFLOM"
CASE ACH21 RETURN "THREE MAN ARMY"
CASE ACH22 RETURN "OUT OF YOUR DEPTH"
CASE ACH23 RETURN "ALTRUIST ACOLYTE"
CASE ACH24 RETURN "A LOT OF CHEDDAR"
CASE ACH25 RETURN "TRADING PURE ALPHA"
CASE ACH26 RETURN "PIMP MY SIDEARM"
CASE ACH27 RETURN "WANTED ALIVE OR ALIVE"
CASE ACH28 RETURN "LOS SANTOS CUSTOMS"
CASE ACH29 RETURN "CLOSE SHAVE"
// MP ACHIEVEMENTS
CASE ACH30 RETURN "OFF THE PLANE"
CASE ACH31 RETURN "THREE BIT GANGSTER"
CASE ACH32 RETURN "MAKING MOVES"
CASE ACH33 RETURN "ABOVE THE LAW"
CASE ACH34 RETURN "NUMERO UNO"
CASE ACH35 RETURN "THE MIDNIGHT CLUB"
CASE ACH36 RETURN "UNNATURAL SELECTION"
CASE ACH38 RETURN "BACKSEAT DRIVER"
CASE ACH39 RETURN "RUN LIKE THE WIND"
CASE ACH40 RETURN "CLEAN SWEEP"
CASE ACH41 RETURN "DECORATED"
CASE ACH43 RETURN "STICK UP KID"
CASE ACH45 RETURN "ENJOY YOUR STAY"
CASE ACH46 RETURN "CREW CUT"
CASE ACH47 RETURN "FULL REFUND"
CASE ACH48 RETURN "DIALLING DIGITS"
CASE ACH49 RETURN "AMERICAN DREAM"
// First Person Achievement
// new NG only achievement - first person mode
CASE ACH51 RETURN "A NEW PERSPECTIVE"
// MP HEIST ACHIEVEMENTS
CASE ACHH1 RETURN "BE PREPARED"
CASE ACHH2 RETURN "IN THE NAME OF SCIENCE"
CASE ACHH3 RETURN "DEAD PRESIDENTS"
CASE ACHH4 RETURN "PAROLE DAY"
CASE ACHH5 RETURN "SHOT CALLER"
CASE ACHH6 RETURN "FOUR WAY"
CASE ACHH7 RETURN "LIVE A LITTLE"
CASE ACHH8 RETURN "CAN'T TOUCH THIS"
//CASE ACHH9 RETURN "VALUABLE ASSET"
CASE ACHH10 RETURN "MASTER MIND"
// ROCKSTAR EDITOR ACHIEVEMENTS
CASE ACHH11 RETURN "VINEWOOD VISIONARY" // this is ACHH11 as it was mistakedly called that in the PC version - so we're stuck with it
CASE ACHR2 RETURN "MAJESTIC"
CASE ACHR3 RETURN "HUMANS OF LOS SANTOS"
CASE ACHR4 RETURN "FIRST TIME DIRECTOR"
CASE ACHR5 RETURN "ANIMAL LOVER"
CASE ACHR6 RETURN "ENSEMBLE PIECE"
CASE ACHR7 RETURN "CULT MOVIE"
CASE ACHR8 RETURN "LOCATION SCOUT"
CASE ACHR9 RETURN "METHOD ACTOR"
CASE ACHR10 RETURN "CRYPTOZOOLOGIST"
//NEW HEISTS ACHIEVEMENTS
CASE ACHGO1 RETURN "Getting Started"
CASE ACHGO2 RETURN "The IAA Job"
CASE ACHGO3 RETURN "The Submarine Job"
CASE ACHGO4 RETURN "The Missile Silo Job"
CASE ACHGO5 RETURN "A World Worth Saving"
CASE ACHGO6 RETURN "Orbital Obliteration"
CASE ACHGO7 RETURN "Elitist"
CASE ACHGO8 RETURN "Masterminds"
ENDSWITCH
RETURN "INVALID OR UNKNOWN ACHIEVEMENT"
ENDFUNC
FUNC STRING DEBUG_GET_ACHIEVEMENT_TITLE_FROM_INT(INT achEnum)
RETURN DEBUG_GET_ACHIEVEMENT_TITLE(INT_TO_ENUM(ACHIEVEMENT_ENUM, achEnum))
ENDFUNC
FUNC BOOL IS_THIS_A_DIRECTOR_MODE_ACHIEVEMENT(ACHIEVEMENT_ENUM achEnum)
SWITCH (achEnum)
CASE ACHH11 // VINEWOOD VISIONARY
CASE ACHR2 // MAJESTIC
CASE ACHR3 // HUMANS OF LOS SANTOS
CASE ACHR4 // FIRST TIME DIRECTOR
CASE ACHR5 // ANIMAL LOVER
CASE ACHR6 // ENSEMBLE PIECE
CASE ACHR7 // CULT MOVIE
CASE ACHR8 // LOCATION SCOUT
CASE ACHR9 // METHOD ACTOR
CASE ACHR10 // CRYTPOZOOLOGIST [SECRET]
RETURN TRUE
ENDSWITCH
RETURN FALSE
ENDFUNC
FUNC BOOL HAS_ACHIEVEMENT_BEEN_AWARDED(ACHIEVEMENT_ENUM achEnum)
RETURN HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(achEnum))
ENDFUNC
//----------------------
// QUEUE FUNCTIONS
//----------------------
FUNC BOOL IS_ACHIEVEMENT_QUEUE_RUNNING(ACHIEVEMENT_QUEUE &aQ)
RETURN aQ.bIsRunning = TRUE
ENDFUNC
FUNC FLOAT GET_ACHIEVEMENT_QUEUE_TIMER(ACHIEVEMENT_QUEUE &aQ)
RETURN aQ.fQueueTimer
ENDFUNC
PROC RESET_ACHIEVEMENT_QUEUE_TIMER(ACHIEVEMENT_QUEUE &aQ, FLOAT shift = 0.0)
IF (shift = 0.0)
aQ.fQueueTimer = 0.0
ELSE
aQ.fQueueTimer = shift
ENDIF
ENDPROC
PROC SET_ACHIEVEMENT_QUEUE_RUNNING(ACHIEVEMENT_QUEUE &aQ, BOOL bTrue = TRUE)
aQ.bIsRunning = bTrue
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: Achievement Queue - Running Status:", aQ.bIsRunning)
IF (aQ.bIsRunning)
RESET_ACHIEVEMENT_QUEUE_TIMER(aQ)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: Achievement Queue - Timer has been started you have ", ACHIEVEMENT_QUEUE_RUNTIME / 60.0, " minutes to reach minimum safe distance")
ENDIF
ENDPROC
FUNC BOOL IS_ACHIEVEMENT_QUEUE_ENTRY_EMPTY(ACHIEVEMENT_QUEUE &aQ, INT i)
RETURN aQ.mQueue[i] = ACHIEVEMENT_COUNT
ENDFUNC
PROC RESET_ACHEIVEMENT_QUEUE_ENTRY(ACHIEVEMENT_QUEUE &aQ, INT i)
aQ.mQueue[i] = ACHIEVEMENT_COUNT
ENDPROC
PROC RESET_ACHIEVEMENT_QUEUE(ACHIEVEMENT_QUEUE &aQ)
INT i
// fill array with nonsense
REPEAT COUNT_OF(aQ.mQueue) i
RESET_ACHEIVEMENT_QUEUE_ENTRY(aQ, i)
ENDREPEAT
RESET_ACHIEVEMENT_QUEUE_TIMER(aQ, ACHIEVEMENT_QUEUE_TIME - 0.5)
ENDPROC
FUNC INT GET_ACHIEVEMENT_POSITION_IN_QUEUE(ACHIEVEMENT_QUEUE &aQ, ACHIEVEMENT_ENUM achEnum)
INT i
// fill array with nonsense
REPEAT COUNT_OF(aQ.mQueue) i
IF (aQ.mQueue[i] = achEnum)
RETURN i
ENDIF
ENDREPEAT
RETURN -1
ENDFUNC
FUNC BOOL IS_ACHIEVEMENT_IN_QUEUE(ACHIEVEMENT_QUEUE &aQ, ACHIEVEMENT_ENUM achEnum)
RETURN (GET_ACHIEVEMENT_POSITION_IN_QUEUE(aQ, achEnum) <> -1)
ENDFUNC
PROC SHIFT_ACHIEVEMENT_QUEUE_FORWARD(ACHIEVEMENT_QUEUE &aQ)
INT i = 1
IF IS_ACHIEVEMENT_QUEUE_ENTRY_EMPTY(aq, 0)
EXIT
ENDIF
// fill array with nonsense
WHILE (i < COUNT_OF(aQ.mQueue))
aQ.mQueue[i - 1] = aQ.mQueue[i]
i ++
ENDWHILE
ENDPROC
FUNC BOOL ADD_ACHIEVEMENT_TO_QUEUE(ACHIEVEMENT_QUEUE &aQ, ACHIEVEMENT_ENUM achEnum)
INT i
IF HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(achEnum))
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Queued Achievement #", ENUM_TO_INT(achEnum), " ", DEBUG_GET_ACHIEVEMENT_TITLE(achEnum), " ADD_ACHIEVEMENT_TO_QUEUE - FAILED - ACHIEVEMENT IS PASSED ALREADY")
RETURN FALSE
ENDIF
IF IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) AND NOT IS_THIS_A_DIRECTOR_MODE_ACHIEVEMENT(achEnum)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Queued Achievement #", ENUM_TO_INT(achEnum), " ", DEBUG_GET_ACHIEVEMENT_TITLE(achEnum), " ADD_ACHIEVEMENT_TO_QUEUE - FAILED - WE ARE IN DIRECTOR MODE - THIS IS NOT A DIRECTOR MODE ACHIEVEMENT")
RETURN FALSE
ENDIF
IF IS_ACHIEVEMENT_IN_QUEUE(aQ, achEnum)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Queued Achievement #", ENUM_TO_INT(achEnum), " ", DEBUG_GET_ACHIEVEMENT_TITLE(achEnum), " ADD_ACHIEVEMENT_TO_QUEUE - FAILED - ACHIEVEMENT IS IN QUEUE")
RETURN FALSE
ENDIF
IF (GET_ACHIEVEMENT_QUEUE_TIMER(aQ) < 0.0)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Queued Achievement #", ENUM_TO_INT(achEnum), " ", DEBUG_GET_ACHIEVEMENT_TITLE(achEnum), " ADD_ACHIEVEMENT_TO_QUEUE - TIMER HAS GONE MANKY RESTARTING")
RESET_ACHIEVEMENT_QUEUE_TIMER(aQ)
ENDIF
// actually add achievement to queue
REPEAT COUNT_OF(aQ.mQueue) i
IF IS_ACHIEVEMENT_QUEUE_ENTRY_EMPTY(aQ, i)
aQ.mQueue[i] = achEnum
RETURN TRUE
ENDIF
ENDREPEAT
RETURN FALSE
ENDFUNC
FUNC BOOL ADD_ACHIEVEMENT_TO_FRONT_OF_QUEUE(ACHIEVEMENT_QUEUE &aQ, ACHIEVEMENT_ENUM achEnum)
INT i
ACHIEVEMENT_QUEUE tmpQueue
IF HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(achEnum))
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Queued Achievement #", ENUM_TO_INT(achEnum), " ", DEBUG_GET_ACHIEVEMENT_TITLE(achEnum), " ADD_ACHIEVEMENT_TO_FRONT_OF_QUEUE - FAILED - ACHIEVEMENT IS PASSED ALREADY")
RETURN FALSE
ENDIF
IF IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) AND NOT IS_THIS_A_DIRECTOR_MODE_ACHIEVEMENT(achEnum)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Queued Achievement #", ENUM_TO_INT(achEnum), " ", DEBUG_GET_ACHIEVEMENT_TITLE(achEnum), " ADD_ACHIEVEMENT_TO_FRONT_OF_QUEUE - FAILED - WE ARE IN DIRECTOR MODE - THIS IS NOT A DIRECTOR MODE ACHIEVEMENT")
RETURN FALSE
ENDIF
IF IS_ACHIEVEMENT_IN_QUEUE(aQ, achEnum)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Queued Achievement #", ENUM_TO_INT(achEnum), " ", DEBUG_GET_ACHIEVEMENT_TITLE(achEnum), " ADD_ACHIEVEMENT_TO_FRONT_OF_QUEUE - FAILED - ACHIEVEMENT IS IN QUEUE")
RETURN FALSE
ENDIF
IF (GET_ACHIEVEMENT_QUEUE_TIMER(aQ) < 0.0)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Queued Achievement #", ENUM_TO_INT(achEnum), " ", DEBUG_GET_ACHIEVEMENT_TITLE(achEnum), " ADD_ACHIEVEMENT_TO_FRONT_OF_QUEUE - TIMER HAS GONE MANKY RESTARTING")
RESET_ACHIEVEMENT_QUEUE_TIMER(aQ)
ENDIF
RESET_ACHIEVEMENT_QUEUE(tmpQueue)
// copy queue to temp queue - with one shift
i = 0
REPEAT COUNT_OF(aQ.mQueue) - 1 i
tmpQueue.mQueue[i + 1] = aQ.mQueue[i]
ENDREPEAT
ADD_ACHIEVEMENT_TO_QUEUE(tmpQueue, achEnum)
// copy temp queue to real queue
i = 0
REPEAT COUNT_OF(aQ.mQueue) i
aQ.mQueue[i] = tmpQueue.mQueue[i]
ENDREPEAT
RETURN TRUE
ENDFUNC
PROC DUMP_ACHIEVEMENT_QUEUE_TO_TTY(ACHIEVEMENT_QUEUE &aQ)
INT i = 0
CPRINTLN(DEBUG_ACHIEVEMENT, "---- DUMPING ACHIEVEMENT QUEUE ----")
WHILE (i < COUNT_OF(aQ.mQueue))
IF IS_ACHIEVEMENT_QUEUE_ENTRY_EMPTY(aQ, i)
i = COUNT_OF(aQ.mQueue) + 100
ELSE
CPRINTLN(DEBUG_ACHIEVEMENT, " #", i, " ACH # ", aQ.mQueue[i], " ", DEBUG_GET_ACHIEVEMENT_TITLE(aQ.mQueue[i]))
ENDIF
i ++
ENDWHILE
CPRINTLN(DEBUG_ACHIEVEMENT, " TIMER:", GET_ACHIEVEMENT_QUEUE_TIMER(aQ))
CPRINTLN(DEBUG_ACHIEVEMENT, "---- END OF QUEUE ---------")
ENDPROC
FUNC BOOL GIVE_QUEUED_ACHIEVEMENT_TO_PLAYER(INT achID)
// this is the proper code
IF HAS_ACHIEVEMENT_BEEN_PASSED(achID)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Queued Achievement #", achID, " ", DEBUG_GET_ACHIEVEMENT_TITLE_FROM_INT(achID), " has already been given")
RETURN FALSE
ENDIF
IF IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) AND NOT IS_THIS_A_DIRECTOR_MODE_ACHIEVEMENT(INT_TO_ENUM(ACHIEVEMENT_ENUM, achID))
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Queued Achievement #", achID, " ", DEBUG_GET_ACHIEVEMENT_TITLE_FROM_INT(achID), " FAILED - WE ARE IN DIRECTOR MODE - THIS IS NOT A DIRECTOR MODE ACHIEVEMENT")
RETURN FALSE
ENDIF
IF NOT GIVE_ACHIEVEMENT_TO_PLAYER(achID)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Queued Achievement #", achID, " ", DEBUG_GET_ACHIEVEMENT_TITLE_FROM_INT(achID), " couldn't be awarded - GIVE_ACHIEVEMENT_TO_PLAYER - FAILED")
RETURN FALSE
ENDIF
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Queued Achievement #", achID, " ", DEBUG_GET_ACHIEVEMENT_TITLE_FROM_INT(achID), " has been given to player")
IF HAS_ACHIEVEMENT_BEEN_PASSED(achID)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Queued Achievement #", achID, " ", DEBUG_GET_ACHIEVEMENT_TITLE_FROM_INT(achID), " player actually has recieved achievement")
RETURN TRUE
ENDIF
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Queued Achievement #", achID, " ", DEBUG_GET_ACHIEVEMENT_TITLE_FROM_INT(achID), " we gave the achievement to the player but they don't have it - FAILURE")
RETURN FALSE
ENDFUNC
PROC UPDATE_ACHIEVEMENT_QUEUE(ACHIEVEMENT_QUEUE &aQ)
FLOAT aqTime = ACHIEVEMENT_QUEUE_TIME
aQ.fQueueTimer += GET_FRAME_TIME()
IF NOT IS_ACHIEVEMENT_QUEUE_RUNNING(aQ)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Achievement Queue is not running?")
EXIT
ENDIF
IF (GET_ACHIEVEMENT_QUEUE_TIMER(aQ) < 0.0)
SCRIPT_ASSERT("Achievement Queue Timer is somehow negative - This is bad, really bad... - Resetting Timer")
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Achievement Queue Timer is negative - This is bad, really bad...")
RESET_ACHIEVEMENT_QUEUE_TIMER(aQ)
EXIT
ENDIF
IF IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR)
aqTime = 10.0 // delay between achievement in director mode should be 10 seconds
ENDIF
IF GET_ACHIEVEMENT_QUEUE_TIMER(aQ) < aqTime
EXIT
ENDIF
IF IS_ACHIEVEMENT_QUEUE_ENTRY_EMPTY(aQ, 0)
EXIT
ENDIF
IF GIVE_QUEUED_ACHIEVEMENT_TO_PLAYER(ENUM_TO_INT(aQ.mQueue[0]))
SHIFT_ACHIEVEMENT_QUEUE_FORWARD(aQ)
DUMP_ACHIEVEMENT_QUEUE_TO_TTY(aQ)
RESET_ACHIEVEMENT_QUEUE_TIMER(aQ)
ENDIF
ENDPROC
//----------------------
// ACH FUNCTIONS
//----------------------
FUNC BOOL AWARD_ACHIEVEMENT_BY_INT(INT achnum, BOOL bIgnoreCheck = TRUE)
/* NEED TO REMOVE ACHIEVEMENTS FOR ONLINE BETA
#IF USE_TU_CHANGES
IF NETWORK_IS_GAME_IN_PROGRESS() OR g_bInMultiplayer
RETURN FALSE
ENDIF
#ENDIF
*/
IF IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) AND NOT IS_THIS_A_DIRECTOR_MODE_ACHIEVEMENT(INT_TO_ENUM(ACHIEVEMENT_ENUM, achnum))
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: Achievement #", achnum, " ", DEBUG_GET_ACHIEVEMENT_TITLE_FROM_INT(achnum), " can't be awarded while in Director Mode")
RETURN FALSE
ENDIF
// check if we have the achievement
IF HAS_ACHIEVEMENT_BEEN_PASSED(achnum) AND (bIgnoreCheck = TRUE)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: Achievement #", achnum, " ", DEBUG_GET_ACHIEVEMENT_TITLE_FROM_INT(achnum), " has already been awarded - Total Achievements:", COUNT_ACHIEVEMENTS())
RETURN FALSE
ENDIF
IF (g_iBitsetCheatsUsedThisSession <> 0) AND (NOT g_bInMultiplayer)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: Achievement #", achnum, " ", DEBUG_GET_ACHIEVEMENT_TITLE_FROM_INT(achnum), " has NOT been awarded - Due to Cheating")
//PRINT_HELP("CHEAT_ACHIEVE")
RETURN FALSE
ENDIF
// award achievement
IF (IS_ACHIEVEMENT_QUEUE_RUNNING(q_mAchievementQueue))
IF IS_ACHIEVEMENT_IN_QUEUE(q_mAchievementQueue, INT_TO_ENUM(ACHIEVEMENT_ENUM, achnum))
CDEBUG3LN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: Achievement #", achnum, " ", DEBUG_GET_ACHIEVEMENT_TITLE_FROM_INT(achnum), " is already in the queue.")
RETURN FALSE
ENDIF
IF ADD_ACHIEVEMENT_TO_FRONT_OF_QUEUE(q_mAchievementQueue, INT_TO_ENUM(ACHIEVEMENT_ENUM, achnum))
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: Achievement #", achnum, " ", DEBUG_GET_ACHIEVEMENT_TITLE_FROM_INT(achnum), " has been added to queue")
RETURN TRUE
ENDIF
ELSE
IF NOT GIVE_ACHIEVEMENT_TO_PLAYER(achnum)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Achievement #", achnum, " ", DEBUG_GET_ACHIEVEMENT_TITLE_FROM_INT(achnum), " couldn't be awarded - GIVE_ACHIEVEMENT_TO_PLAYER - FAILED")
RETURN FALSE
ENDIF
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Achievement #", achnum, " ", DEBUG_GET_ACHIEVEMENT_TITLE_FROM_INT(achnum), " has been given to player")
IF HAS_ACHIEVEMENT_BEEN_PASSED(achnum)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Achievement #", achnum, " ", DEBUG_GET_ACHIEVEMENT_TITLE_FROM_INT(achnum), " player actually has the achievement")
RETURN TRUE
ENDIF
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - Achievement #", achnum, " ", DEBUG_GET_ACHIEVEMENT_TITLE_FROM_INT(achnum), " we gave the achievement to the player but they don't have it - FAILURE")
RETURN FALSE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL AWARD_ACHIEVEMENT(ACHIEVEMENT_ENUM achenum, BOOL bIgnoreCheck = TRUE)
// convert the string to an enum and check it isn't wrong
#IF USE_TU_CHANGES
IF (achenum >= ACHIEVEMENT_COUNT)
#ENDIF
#IF NOT USE_TU_CHANGES
IF (achenum >= ACHIEVEMENT_COUNT_WHEN_GTA5_WAS_RELEASED)
#ENDIF
SCRIPT_ASSERT("CHECK THE STRING YOU'VE SUPPLIED IT SHOULD BE BETWEEN ACH00 AND ACH49")
RETURN FALSE
#IF USE_TU_CHANGES
ENDIF
#ENDIF
#IF NOT USE_TU_CHANGES
ENDIF
#ENDIF
// check if we have the achievement
RETURN AWARD_ACHIEVEMENT_BY_INT(ENUM_TO_INT(achenum), bIgnoreCheck)
ENDFUNC
FUNC BOOL AWARD_ACHIEVEMENT_FOR_MISSION(ACHIEVEMENT_ENUM achenum, BOOL bIgnoreCheck = FALSE)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: Achievement #", ENUM_TO_INT(achenum), " ", DEBUG_GET_ACHIEVEMENT_TITLE(achenum), " Trying to award mission based achievment - ", GET_THIS_SCRIPT_NAME())
IF IS_BIT_SET(g_replay.iReplayBits, ENUM_TO_INT(RB_DID_WE_EVER_SHITSKIP))
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: Achievement #", ENUM_TO_INT(achenum), " ", DEBUG_GET_ACHIEVEMENT_TITLE(achenum), " won't be awarded because you shit skipped earlier this mission - ", GET_THIS_SCRIPT_NAME())
RETURN FALSE
ENDIF
RETURN AWARD_ACHIEVEMENT(achenum, bIgnoreCheck)
ENDFUNC
/// PURPOSE:
/// This Awards the achievement
/// PARAMS:
/// achname - achievement name in the form "ACHXX" where xx is a number from 0 to 49.
/// RETURNS:
/// True if awarded
FUNC BOOL AWARD_ACHIEVEMENT_BY_STRING(STRING achname, BOOL bIgnoreCheck = TRUE)
INT achnum
ACHIEVEMENT_ENUM achenum = GET_ACHIEVEMENT_ENUM_BY_NAME_STRING(achname)
// convert the string to an enum and check it isn't wrong
IF (achenum >= ACHIEVEMENT_COUNT)
SCRIPT_ASSERT("CHECK THE STRING YOU'VE SUPPLIED IT SHOULD BE BETWEEN ACH00 AND ACHH11")
RETURN FALSE
ENDIF
// check if we have the achievement
achnum = ENUM_TO_INT(achenum)
RETURN AWARD_ACHIEVEMENT_BY_INT(achnum, bIgnoreCheck)
ENDFUNC
FUNC BOOL _CHECK_STREET_RACES_FOR_MULTI_DISCIPLINED_ACHIEVEMENT()
INT i = 0
REPEAT ENUM_TO_INT(NUM_STREET_RACES) i
IF IS_BIT_SET(g_savedGlobals.sStreetRaceData.iRaceWon, i)
RETURN TRUE
ENDIF
ENDREPEAT
RETURN FALSE
ENDFUNC
FUNC BOOL _CHECK_SEA_RACES_FOR_MULTI_DISCIPLINED_ACHIEVEMENT()
INT i = 0
REPEAT ENUM_TO_INT(NUM_SEA_RACES) i
IF IS_BIT_SET(g_savedGlobals.sSeaRaceData.iRaceWon, i)
RETURN TRUE
ENDIF
ENDREPEAT
RETURN FALSE
ENDFUNC
FUNC BOOL _CHECK_SHOOTING_RANGE_FOR_MULTI_DISCIPLINED_ACHIEVEMENT()
// check shooting range
INT i = 0
REPEAT ENUM_TO_INT(RT_MAX_ROUND_TYPES) i
IF (g_savedGlobals.sRangeData[0].sRounds[INT_TO_ENUM(RANGE_ROUND_TYPE, i)].eTopMedal = RRM_GOLD)
RETURN TRUE
ELIF (g_savedGlobals.sRangeData[1].sRounds[INT_TO_ENUM(RANGE_ROUND_TYPE, i)].eTopMedal = RRM_GOLD)
RETURN TRUE
ELIF (g_savedGlobals.sRangeData[2].sRounds[INT_TO_ENUM(RANGE_ROUND_TYPE, i)].eTopMedal = RRM_GOLD)
RETURN TRUE
ENDIF
ENDREPEAT
RETURN FALSE
ENDFUNC
FUNC BOOL _CHECK_FLIGHTSCHOOL_FOR_MULTI_DISCIPLINED_ACHIEVEMENT()
// check shooting range
INT i = 0
REPEAT ENUM_TO_INT(NUMBER_OF_PILOT_SCHOOL_CLASSES) i
IF (g_savedGlobals.sFlightSchoolData[0].PlayerData[INT_TO_ENUM(PILOT_SCHOOL_CLASSES_ENUM, i)].eMedal = PS_GOLD)
RETURN TRUE
ELIF (g_savedGlobals.sFlightSchoolData[1].PlayerData[INT_TO_ENUM(PILOT_SCHOOL_CLASSES_ENUM, i)].eMedal = PS_GOLD)
RETURN TRUE
ELIF (g_savedGlobals.sFlightSchoolData[2].PlayerData[INT_TO_ENUM(PILOT_SCHOOL_CLASSES_ENUM, i)].eMedal = PS_GOLD)
RETURN TRUE
ENDIF
ENDREPEAT
RETURN FALSE
ENDFUNC
FUNC BOOL _CHECK_OFFROAD_FOR_MULTI_DISCIPLINED_ACHIEVEMENT()
// check off road races
INT i = 0
REPEAT ENUM_TO_INT(NUM_OFFROAD_RACES) i
IF g_savedGlobals.sOffroadData.iRaceBestPlaces[INT_TO_ENUM(OFFROAD_RACE_INDEX, i)] = 1
RETURN TRUE
ENDIF
ENDREPEAT
RETURN FALSE
ENDFUNC
FUNC BOOL _CHECK_TRIATHLON_FOR_MULTI_DISCIPLINED_ACHIEVEMENT()
// check triathlon
INT i = 0
REPEAT ENUM_TO_INT(NUM_TRIATHLON_RACES) i
IF (g_savedGlobals.sTriathlonData.iBestRank[INT_TO_ENUM(TRIATHLON_RACE_INDEX, i)] = 1)
RETURN TRUE
ENDIF
ENDREPEAT
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Only returns true the 1st time the achievement is awarded
/// RETURNS:
///
FUNC BOOL CHECK_MULTI_DISCIPLINED_ACHIEVEMENT(BOOL tty = FALSE)
IF HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACH14))
RETURN FALSE
ENDIF
BOOL bGold[6]
bGold[0]=_CHECK_TRIATHLON_FOR_MULTI_DISCIPLINED_ACHIEVEMENT()
bGold[1]=_CHECK_OFFROAD_FOR_MULTI_DISCIPLINED_ACHIEVEMENT()
bGold[2]=_CHECK_STREET_RACES_FOR_MULTI_DISCIPLINED_ACHIEVEMENT()
bGold[3]=_CHECK_SEA_RACES_FOR_MULTI_DISCIPLINED_ACHIEVEMENT()
bGold[4]=_CHECK_SHOOTING_RANGE_FOR_MULTI_DISCIPLINED_ACHIEVEMENT()
bGold[5]=_CHECK_FLIGHTSCHOOL_FOR_MULTI_DISCIPLINED_ACHIEVEMENT()
//Check number of gold discipline medals
INT iGold = 0, i, iCurrent
REPEAT 6 i
IF bGold[i]
iGold++
ENDIF
ENDREPEAT
//Set the discipline gold int, update achievement progress
STAT_GET_INT(NUM_DISCIPLINE_GOLD_EARNED,iCurrent)
IF iGOld > iCurrent AND iGold > 0
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH14 - changing the achievement progress from ",iCurrent," to ",iGold)
STAT_SET_INT(NUM_DISCIPLINE_GOLD_EARNED,iGold)
SET_ACHIEVEMENT_PROGRESS_SAFE(ENUM_TO_INT(ACH14),iGold)
ENDIF
IF (tty)
CPRINTLN(DEBUG_ACHIEVEMENT, " ")
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH14 - Multi Disciplined Check - Triathalon:",bGold[0] )
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH14 - Multi Disciplined Check - OffRoad:", bGold[1])
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH14 - Multi Disciplined Check - Street Race:", bGold[2])
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH14 - Multi Disciplined Check - Sea Race:", bGold[3])
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH14 - Multi Disciplined Check - Shooting:", bGold[4])
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH14 - Multi Disciplined Check - Flight:", bGold[5])
CPRINTLN(DEBUG_ACHIEVEMENT, " ")
ENDIF
//CPRINTLN(DEBUG_ACHIEVEMENT, "\n[ACHIEVEMENT]: ACH14 - Multi Disciplined Check Start")
IF NOT bGold[0]
IF (tty)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH14 - Multi Disciplined Check Failed - Haven't won a Triathalon Gold")
ENDIF
RETURN FALSE
ENDIF
IF NOT bGold[1]
IF (tty)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH14 - Multi Disciplined Check Failed - Haven't won a Off Road Gold")
ENDIF
RETURN FALSE
ENDIF
IF NOT bGold[2]
IF (tty)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH14 - Multi Disciplined Check Failed - Haven't won a Street Race Gold")
ENDIF
RETURN FALSE
ENDIF
IF NOT bGold[3]
IF (tty)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH14 - Multi Disciplined Check Failed - Haven't won a Sea Race Gold")
ENDIF
RETURN FALSE
ENDIF
IF NOT bGold[4]
IF (tty)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH14 - Multi Disciplined Check Failed - Haven't won a Shooting Gold")
ENDIF
RETURN FALSE
ENDIF
IF NOT bGold[5]
IF (tty)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH14 - Multi Disciplined Check Failed - Haven't won a Flying Gold")
ENDIF
RETURN FALSE
ENDIF
AWARD_ACHIEVEMENT(ACH14) // Multi-Disciplined
RETURN TRUE
ENDFUNC
FUNC BOOL IS_BIT_SET_FOR_FRANKIE_SAYS_ACHIEVEMENT(INT iBitField, eACH45BitFlags bit, BOOL tty = TRUE)
BOOL bOk = IS_BIT_SET(iBitField, ENUM_TO_INT(bit))
IF NOT (tty)
RETURN bOk
ENDIF
// tty
SWITCH bit
CASE ACH45_GOLF
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH45 - Golf Played:", bOK)
RETURN bOk
CASE ACH45_TENNIS
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH45 - Tennis Played:", bOK)
RETURN bOk
CASE ACH45_ARMWRESTLING
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH45 - Wrestling Played:", bOK)
RETURN bOk
CASE ACH45_DARTS
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH45 - Darts Played:", bOK)
RETURN bOk
CASE ACH45_SHOOTING
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH45 - Shooting Played:", bOK)
RETURN bOk
CASE ACH45_LAPDANCE
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH45 - Lap Dance Played:", bOK)
RETURN bOk
CASE ACH45_CLOTHES
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH45 - Clothes Bought:", bOK)
RETURN bOk
CASE ACH45_TATTOO
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH45 - Tattoo Bought:", bOK)
RETURN bOk
CASE ACH45_HAIRCUT
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH45 - Haircut Bought:", bOK)
RETURN bOk
ENDSWITCH
RETURN FALSE
ENDFUNC
FUNC BOOL SET_BIT_FOR_FRANKIE_SAYS_ACHIEVEMENT(eACH45BitFlags bit)
INT i
INT cnt
INT bitfield
IF NOT g_bInMultiplayer
RETURN FALSE
ENDIF
IF HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACH45))
RETURN FALSE
ENDIF
IF NOT HAS_IMPORTANT_STATS_LOADED()
RETURN FALSE
ENDIF
// set the bits
bitfield = GET_MP_INT_CHARACTER_STAT(MP_STAT_CHAR_ACH45_TRACKER)
SET_BIT(bitfield, ENUM_TO_INT(bit))
SET_MP_INT_CHARACTER_STAT(MP_STAT_CHAR_ACH45_TRACKER, bitfield)
// check
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH45 - Checking Bits")
REPEAT ENUM_TO_INT(MAX_ACH45_FLAGS) i
IF IS_BIT_SET_FOR_FRANKIE_SAYS_ACHIEVEMENT(bitfield, INT_TO_ENUM(eACH45BitFlags, i))
cnt ++
ENDIF
ENDREPEAT
// award achievment if all flags are set
IF (cnt = ENUM_TO_INT(MAX_ACH45_FLAGS))
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH45 - Frankie Says - Unlocked")
AWARD_ACHIEVEMENT(ACH45) // Frankie Says
ENDIF
RETURN TRUE
ENDFUNC
FUNC BOOL CHECK_FRANKIE_SAYS_ACHIEVEMENT(BOOL tty = TRUE)
IF NOT HAS_IMPORTANT_STATS_LOADED()
RETURN FALSE
ENDIF
IF HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACH45))
RETURN FALSE
ENDIF
IF NOT g_bInMultiplayer
RETURN FALSE
ENDIF
INT i, cnt
INT bitfield = GET_MP_INT_CHARACTER_STAT(MP_STAT_CHAR_ACH45_TRACKER)
// check
//CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH45 - Checking Bits")
REPEAT ENUM_TO_INT(MAX_ACH45_FLAGS) i
IF IS_BIT_SET_FOR_FRANKIE_SAYS_ACHIEVEMENT(bitfield, INT_TO_ENUM(eACH45BitFlags, i), tty)
cnt ++
ENDIF
ENDREPEAT
// award achievment if all flags are set
IF (cnt = ENUM_TO_INT(MAX_ACH45_FLAGS))
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH45 - Frankie Says - Unlocked")
AWARD_ACHIEVEMENT(ACH45) // Frankie Says
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL CHECK_AMERICAN_DREAM_ACHIEVEMENT(BOOL tty = FALSE)
IF NOT HAS_IMPORTANT_STATS_LOADED()
RETURN FALSE
ENDIF
IF NOT g_bInMultiplayer
RETURN FALSE
ENDIF
IF HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACH49))
RETURN FALSE
ENDIF
IF (tty = TRUE)
CPRINTLN(DEBUG_ACHIEVEMENT, " ")
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH49 - American Dream Check Start - PROP:", GET_OWNED_PROPERTY(0),
" APT:", GET_MP_BOOL_CHARACTER_STAT(MP_STAT_CL_BUY_APPARTMENT),
" GRG:", GET_MP_BOOL_CHARACTER_STAT(MP_STAT_CL_BUY_GARAGE), " INS:", GET_MP_BOOL_CHARACTER_STAT(MP_STAT_CL_BUY_INSURANCE))
ENDIF
IF NOT GET_MP_BOOL_CHARACTER_STAT(MP_STAT_CL_BUY_APPARTMENT)
IF (tty = TRUE)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH49 - American Dream Check Failed - No Appartment Owned")
ENDIF
RETURN FALSE
ENDIF
IF NOT GET_MP_BOOL_CHARACTER_STAT(MP_STAT_CL_BUY_GARAGE)
IF (tty = TRUE)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH49 - American Dream Check Failed - No Garage Owned")
ENDIF
RETURN FALSE
ENDIF
IF NOT GET_MP_BOOL_CHARACTER_STAT(MP_STAT_CL_BUY_INSURANCE)
IF (tty = TRUE)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH49 - American Dream Check Failed - No Car Insurance Owned")
ENDIF
RETURN FALSE
ENDIF
AWARD_ACHIEVEMENT(ACH49) // American Dream
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH49 - American Dream - Unlocked")
RETURN TRUE
ENDFUNC
FUNC BOOL CHECK_TRADING_PURE_ALPHA_ACHIEVEMENT(BOOL forcePass = FALSE)
IF (g_savedGlobals.sFinanceData.iProfitLoss <= 0)
AND !forcePass
RETURN FALSE
ENDIF
IF HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACH25))
PRINTLN("CHECK_TRADING_PURE_ALPHA_ACHIEVEMENT: Achievement already passed. ")
RETURN FALSE
ENDIF
PRINTLN("CHECK_TRADING_PURE_ALPHA_ACHIEVEMENT: awarding ")
AWARD_ACHIEVEMENT(ACH25) // Trading Pure Alpha
RETURN TRUE
ENDFUNC
FUNC BOOL CHECK_THATS_A_LOT_OF_CHEDDAR_ACHIEVEMENT(BOOL dbg = FALSE)
INT iValue
INT iTotalMoneySpent = 0
IF HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACH24))
RETURN FALSE
ENDIF
IF STAT_GET_INT(SP0_MONEY_TOTAL_SPENT, iValue)
iTotalMoneySpent += iValue
ENDIF
IF STAT_GET_INT(SP1_MONEY_TOTAL_SPENT, iValue)
iTotalMoneySpent += iValue
ENDIF
IF STAT_GET_INT(SP2_MONEY_TOTAL_SPENT, iValue)
iTotalMoneySpent += iValue
ENDIF
IF (dbg)
CPRINTLN(DEBUG_ACHIEVEMENT, " ")
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACH24 - That's a lot of Chedder - Cash", iTotalMoneySpent, " of ", ACH24_CASH_NEEDED)
ENDIF
//Set the achievement progress for A Lot Of Cheddar
INT iOldVal = 0
STAT_GET_INT(NUM_CASH_SPENT,iOldVal)
IF iTotalMoneySpent>0 AND (iOldVal/2000000) <> (iTotalMoneySpent/2000000)
//CPRINTLN(debug_achievement, "Updating cheddar achievement")
STAT_SET_INT(NUM_CASH_SPENT,iTotalMoneySpent)
SET_ACHIEVEMENT_PROGRESS_SAFE(ENUM_TO_INT(ACH24),iTotalMoneySpent)
ENDIF
IF (iTotalMoneySpent < ACH24_CASH_NEEDED)
RETURN FALSE
ENDIF
AWARD_ACHIEVEMENT(ACH24) // a lot of chedder
RETURN TRUE
ENDFUNC
FUNC BOOL CHECK_NUMERO_UNO_ACHIEVEMENT(BOOL tty = FALSE)
IF HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACH34))
RETURN FALSE
ENDIF
IF NOT HAS_IMPORTANT_STATS_LOADED()
RETURN FALSE
ENDIF
IF NOT g_bInMultiplayer
RETURN FALSE
ENDIF
IF (tty)
INT land_races
land_races = GET_MP_INT_CHARACTER_AWARD(MP_AWARD_RACES_WON)
land_races -= GET_MP_INT_CHARACTER_AWARD(MP_AWARD_FMWINAIRRACE)
land_races -= GET_MP_INT_CHARACTER_AWARD(MP_AWARD_FMWINSEARACE)
CPRINTLN(DEBUG_ACHIEVEMENT, " ")
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACH34 - Arm Wrestling:", GET_MP_INT_CHARACTER_AWARD(MP_AWARD_NO_ARMWRESTLING_WINS) > 0)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACH34 - Darts:", GET_MP_INT_CHARACTER_AWARD(MP_AWARD_WIN_AT_DARTS) > 0)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACH34 - Tennis:", GET_MP_INT_CHARACTER_AWARD(MP_AWARD_FM_TENNIS_WON) > 0)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACH34 - DM:", GET_MP_INT_CHARACTER_AWARD(MP_AWARD_FM_DM_WINS) > 0)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACH34 - TDM:", GET_MP_INT_CHARACTER_AWARD(MP_AWARD_FM_TDM_WINS) > 0)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACH34 - SEA RACE:", GET_MP_INT_CHARACTER_AWARD(MP_AWARD_FMWINSEARACE) > 0)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACH34 - GOLF:", GET_MP_INT_CHARACTER_AWARD(MP_AWARD_FM_GOLF_WON) > 0)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACH34 - AIR RACE:", GET_MP_INT_CHARACTER_AWARD(MP_AWARD_FMWINAIRRACE) > 0)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACH34 - BJ:", GET_MP_INT_CHARACTER_STAT(MP_STAT_BJWINS) > 0)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACH34 - HORDE:", GET_MP_INT_CHARACTER_STAT(MP_STAT_HORDEWINS) > 0)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACH34 - MC:", GET_MP_INT_CHARACTER_STAT(MP_STAT_MCMWINS) > 0)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACH34 - GANG:", GET_MP_INT_CHARACTER_STAT(MP_STAT_GANGHIDWINS) > 0)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACH34 - LAND RACE:", land_races > 0)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACH34 - GTA RACE :", GET_MP_INT_CHARACTER_AWARD(MP_AWARD_FM_GTA_RACES_WON) > 0)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACH34 - RALLY:", (GET_MP_INT_CHARACTER_AWARD(MP_AWARD_FMRALLYWONDRIVE) > 0) OR (GET_MP_INT_CHARACTER_AWARD(MP_AWARD_FMRALLYWONNAV) > 0))
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACH34 - SHOOTING:", (GET_MP_INT_CHARACTER_AWARD(MP_AWARD_FM_SHOOTRANG_TG_WON) > 0) OR (GET_MP_INT_CHARACTER_AWARD(MP_AWARD_FM_SHOOTRANG_RT_WON) > 0) OR (GET_MP_INT_CHARACTER_AWARD(MP_AWARD_FM_SHOOTRANG_CT_WON) > 0) OR (GET_MP_BOOL_CHARACTER_AWARD(MP_AWARD_FM_SHOOTRANG_GRAN_WON) = TRUE))
CPRINTLN(DEBUG_ACHIEVEMENT, " ")
ENDIF
IF GET_MP_BOOL_CHARACTER_AWARD(MP_AWARD_FMWINEVERYGAMEMODE)
AWARD_ACHIEVEMENT(ACH34) // NUMERO UNO
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL CHECK_SHOW_OFF_ACHIEVEMENT()
IF HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACH19))
RETURN FALSE
ENDIF
//Update achievement progress
INT iNumStuntJumps = GET_NUM_SUCCESSFUL_STUNT_JUMPS()
IF iNumStuntJumps > 0
IF g_iPreviousNumberOfStuntJumps < iNumStuntJumps
//Don't resend the stat on boot/load
IF g_iPreviousNumberOfStuntJumps >= 0
SET_ACHIEVEMENT_PROGRESS_SAFE(ENUM_TO_INT(ACH19),iNumStuntJumps)
CPRINTLN(DEBUG_ACHIEVEMENT,"[ACHIEVEMENT] - ACH19: Changed Show Off achievement progress from ", g_iPreviousNumberOfStuntJumps," to ",iNumStuntJumps)
ELSE
CPRINTLN(DEBUG_ACHIEVEMENT,"[ACHIEVEMENT] - ACH19: Just booted, setting global to current number of jumps")
ENDIF
g_iPreviousNumberOfStuntJumps = iNumStuntJumps
ENDIF
ENDIF
IF (GET_NUM_SUCCESSFUL_STUNT_JUMPS() >= ACH19_STUNTJUMPS)
AWARD_ACHIEVEMENT(ACH19) // Show Off - Get All 50 Stunt Jumps
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC FLOAT DEBUG_GET_HOURS_FOR_A_NEW_PERSPECTIVE_ACHIEVEMENT()
FLOAT fStatValueSP = 0
FLOAT fStatValueMP = 0
// SP time
fStatValueSP += (TO_FLOAT(STAT_GET_NUMBER_OF_DAYS(FIRST_PERSON_CAM_TIME)) * 24.0)
fStatValueSP += (TO_FLOAT(STAT_GET_NUMBER_OF_HOURS(FIRST_PERSON_CAM_TIME)))
fStatValueSP += (TO_FLOAT(STAT_GET_NUMBER_OF_MINUTES(FIRST_PERSON_CAM_TIME)) / 60.0)
fStatValueSP += (TO_FLOAT(STAT_GET_NUMBER_OF_SECONDS(FIRST_PERSON_CAM_TIME)) / (60.0 * 60.0))
// MP time
fStatValueMP += (TO_FLOAT(STAT_GET_NUMBER_OF_DAYS(MP_FIRST_PERSON_CAM_TIME)) * 24.0)
fStatValueMP += (TO_FLOAT(STAT_GET_NUMBER_OF_HOURS(MP_FIRST_PERSON_CAM_TIME)))
fStatValueMP += (TO_FLOAT(STAT_GET_NUMBER_OF_MINUTES(MP_FIRST_PERSON_CAM_TIME)) / 60.0)
fStatValueMP += (TO_FLOAT(STAT_GET_NUMBER_OF_SECONDS(MP_FIRST_PERSON_CAM_TIME)) / (60.0 * 60.0))
RETURN fStatValueSP + fStatValueMP
ENDFUNC
// First Person Achievement
/// PURPOSE:
/// Monitiors player reached "A New Perspective" SP & MP Achievement
/// see url:bugstar:2004307
/// RETURNS:
/// TRUE - only returns TRUE the frame the achievements are awarded
FUNC BOOL CHECK_A_NEW_PERSPECTIVE_ACHIEVEMENT()
// don't re-award achievement
IF HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACH51))
RETURN FALSE
ENDIF
// work out if we have reached the time threshold in hours to award the achievement
INT iStatValueSP = 0
INT iStatValueMP = 0
// SP time
iStatValueSP += (STAT_GET_NUMBER_OF_DAYS(FIRST_PERSON_CAM_TIME) * 24)
iStatValueSP += (STAT_GET_NUMBER_OF_HOURS(FIRST_PERSON_CAM_TIME))
// MP time
iStatValueMP += (STAT_GET_NUMBER_OF_DAYS(MP_FIRST_PERSON_CAM_TIME) * 24)
iStatValueMP += (STAT_GET_NUMBER_OF_HOURS(MP_FIRST_PERSON_CAM_TIME))
// combined times for the threshold check
IF (iStatValueSP + iStatValueMP) >= ACH_FIRST_PERSON_MODE_HOURS
AWARD_ACHIEVEMENT(ACH51)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: CHECK_A_NEW_PERSPECTIVE_ACHIEVEMENT() return TRUE for ACH51 - Unlocked")
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL CHECK_SAN_ANDREAS_SIGHTSEER_ACHIEVEMENT()
IF NETWORK_IS_GAME_IN_PROGRESS() OR (g_bInMultiplayer)
RETURN FALSE
ENDIF
IF IS_PLAYER_PLAYING(PLAYER_ID())
IF IS_PLAYER_CONTROL_ON(PLAYER_ID())
FLOAT fFow = GET_MINIMAP_FOW_DISCOVERY_RATIO()
IF fFow > 0.01 AND IS_PC_VERSION()
SET_ACHIEVEMENT_PROGRESS_SAFE(ENUM_TO_INT(ACH50),FLOOR(fFow*100))
ENDIF
IF (fFow >= 0.975)
AWARD_ACHIEVEMENT(ACH50) // San Andreas Sightseer
RETURN TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
FUNC ACHIEVEMENT_ENUM GET_GANGOPS_ACHIEVEMENT_FROM_CHECKER_ENUM(eGangOpsAchCheck iAch)
SWITCH (iAch)
CASE GOPS_ACH_1_DONE RETURN ACHGO1
CASE GOPS_ACH_2_DONE RETURN ACHGO2
CASE GOPS_ACH_3_DONE RETURN ACHGO3
CASE GOPS_ACH_4_DONE RETURN ACHGO4
CASE GOPS_ACH_5_DONE RETURN ACHGO5
CASE GOPS_ACH_6_DONE RETURN ACHGO6
CASE GOPS_ACH_7_DONE RETURN ACHGO7
CASE GOPS_ACH_8_DONE RETURN ACHGO8
DEFAULT
CASSERTLN(DEBUG_ACHIEVEMENT, "[GOPS ACHIEVEMENT] Invalid GOps tracker enum value ",ENUM_TO_INT(iAch))
RETURN ACHGO1 //Default return value, should never get here
ENDSWITCH
ENDFUNC
PROC SET_GANGOPS_ACHIEVEMENT_BIT(eGangOpsAchCheck iAch)
SET_BIT(g_iGangOpsAchTracker, ENUM_TO_INT(iAch))
CPRINTLN(DEBUG_ACHIEVEMENT, "[GOPS ACHIEVEMENT] - Setting achievement tracker bit for #",ENUM_TO_INT(iAch))
ENDPROC
PROC CLEAR_GANGOPS_ACHIEVEMENT_BIT(eGangOpsAchCheck iAch)
CLEAR_BIT(g_iGangOpsAchTracker, ENUM_TO_INT(iAch))
CPRINTLN(DEBUG_ACHIEVEMENT, "[GOPS ACHIEVEMENT] - CLEARING achievement tracker bit for #",ENUM_TO_INT(iAch))
ENDPROC
FUNC BOOL IS_GANGOPS_ACHIEVEMENT_BIT_SET(eGangOpsAchCheck iAch)
RETURN IS_BIT_SET(g_iGangOpsAchTracker, ENUM_TO_INT(iAch))
ENDFUNC
PROC SET_GANGOPS_ACHIEVEMENT_DONE(eGangOpsAchCheck iAch, BOOL bDone = true)
ACHIEVEMENT_ENUM ach = GET_GANGOPS_ACHIEVEMENT_FROM_CHECKER_ENUM(iAch)
IF bDone
IF NOT HAS_ACHIEVEMENT_BEEN_AWARDED(ach)
SET_GANGOPS_ACHIEVEMENT_BIT(iAch)
EXIT
ENDIF
//Else print that the achievement's already been awarded
CPRINTLN(DEBUG_ACHIEVEMENT, "[GOPS ACHIEVEMENT] - Achievement ALREADY AWARDED for #",DEBUG_GET_ACHIEVEMENT_TITLE(ach))
ELSE
CLEAR_GANGOPS_ACHIEVEMENT_BIT(iAch)
ENDIF
ENDPROC
FUNC STRING GET_STRING_FROM_HEIST_ACHIEVEMENT_ID(eHeistACHCheckID iHeist)
SWITCH (iHeist)
CASE HEISTACH_INVALID RETURN "HEISTACH_INVALID"
CASE HEISTACH_H1_DONE RETURN "HEISTACH_H1_DONE - BE PREPARED"
CASE HEISTACH_H2_DONE RETURN "HEISTACH_H2_DONE - IN THE NAME OF SCIENCE"
CASE HEISTACH_H3_DONE RETURN "HEISTACH_H3_DONE - DEAD PRESIDENTS"
CASE HEISTACH_H4_DONE RETURN "HEISTACH_H4_DONE - PAROLE DAY"
CASE HEISTACH_H5_DONE RETURN "HEISTACH_H5_DONE - SHOT CALLER"
CASE HEISTACH_H6_DONE RETURN "HEISTACH_H6_DONE - FOUR WAY"
CASE HEISTACH_H7_DONE RETURN "HEISTACH_H7_DONE - LIVE A LITTLE"
CASE HEISTACH_H8_DONE RETURN "HEISTACH_H8_DONE - CAN'T TOUCH THIS "
CASE HEISTACH_H9_DONE RETURN "HEISTACH_H9_DONE - VALUABLE ASSET [REMOVED]"
CASE HEISTACH_H10_DONE RETURN "HEISTACH_H10_DONE - MASTER MIND"
CASE HEISTACH_HUMANELAB_DONE RETURN "HEISTACH_HUMANELAB_DONE - NEEDED FOR IN THE NAME OF SCIENCE"
CASE HEISTACH_SERIESA_DONE RETURN "HEISTACH_SERIESA_DONE - NEEDED FOR IN THE NAME OF SCIENCE"
CASE HEISTACH_FLECCAJOB_DONE RETURN "HEISTACH_FLECCAJOB_DONE - NEEDED FOR DEAD PRESIDENTS"
CASE HEISTACH_PACIFIC_DONE RETURN "HEISTACH_PACIFIC_DONE - NEEDED FOR DEAD PRESIDENTS"
CASE HEISTACH_PRISON_DONE RETURN "HEISTACH_PRISON_DONE - NEEDED FOR PRISON BREAK"
CASE HEISTACH_CREW_CUT RETURN "HEISTACH_CREW_CUT"
CASE HEISTACH_CREW_CUT_SANCHECK RETURN "HEISTACH_CREW_CUT_SANITY_CHECK"
CASE MAX_HEISTACHCHK_ID RETURN "MAX_HEISTACHCHK_ID"
ENDSWITCH
RETURN "UNKNOWN HEIST ACHIEVEMENT ID"
ENDFUNC
PROC SET_HEIST_ACHIEVEMENT_ID_BIT(eHeistACHCheckID iHeist)
INT value = GET_MP_INT_PLAYER_STAT(MPPLY_HEIST_ACH_TRACKER)
SET_BIT(value, ENUM_TO_INT(iHeist))
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - HEIST ACHIEVEMENT TRACKER BIT SET:", GET_STRING_FROM_HEIST_ACHIEVEMENT_ID(iHeist), " ID:", ENUM_TO_INT(iHeist), " TO TRUE - VALUE:", value)
SET_MP_INT_PLAYER_STAT(MPPLY_HEIST_ACH_TRACKER, value)
ENDPROC
PROC CLEAR_HEIST_ACHIEVEMENT_ID_BIT(eHeistACHCheckID iHeist)
INT value = GET_MP_INT_PLAYER_STAT(MPPLY_HEIST_ACH_TRACKER)
CLEAR_BIT(value, ENUM_TO_INT(iHeist))
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - HEIST ACHIEVEMENT TRACKER BIT CLEARED:", GET_STRING_FROM_HEIST_ACHIEVEMENT_ID(iHeist), " ID:", ENUM_TO_INT(iHeist), " TO FALSE - VALUE:", value)
SET_MP_INT_PLAYER_STAT(MPPLY_HEIST_ACH_TRACKER, value)
ENDPROC
PROC SET_HEIST_ACHIEVEMENT_ID(eHeistACHCheckID iHeist, BOOL ok = TRUE)
CPRINTLN(DEBUG_ACHIEVEMENT, " ")
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - START SET ACHIEVEMENT TRACKER BIT:", GET_STRING_FROM_HEIST_ACHIEVEMENT_ID(iHeist))
IF (ok)
SWITCH (iHeist)
CASE HEISTACH_H1_DONE
IF NOT HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACHH1))
SET_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ELSE
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACHIEVEMENT:", DEBUG_GET_ACHIEVEMENT_TITLE(ACHH1) ," HAS BEEN PASSED - NOT SETTING BIT FOR:", GET_STRING_FROM_HEIST_ACHIEVEMENT_ID(iHeist))
CLEAR_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ENDIF
BREAK
CASE HEISTACH_H2_DONE
CASE HEISTACH_HUMANELAB_DONE
CASE HEISTACH_SERIESA_DONE
IF NOT HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACHH2))
SET_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ELSE
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACHIEVEMENT:", DEBUG_GET_ACHIEVEMENT_TITLE(ACHH2) ," HAS BEEN PASSED - NOT SETTING BIT FOR:", GET_STRING_FROM_HEIST_ACHIEVEMENT_ID(iHeist))
CLEAR_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ENDIF
BREAK
CASE HEISTACH_H3_DONE
CASE HEISTACH_FLECCAJOB_DONE
CASE HEISTACH_PACIFIC_DONE
IF NOT HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACHH3))
SET_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ELSE
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACHIEVEMENT:", DEBUG_GET_ACHIEVEMENT_TITLE(ACHH3) ," HAS BEEN PASSED - NOT SETTING BIT FOR:", GET_STRING_FROM_HEIST_ACHIEVEMENT_ID(iHeist))
CLEAR_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ENDIF
BREAK
CASE HEISTACH_H4_DONE
CASE HEISTACH_PRISON_DONE
IF NOT HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACHH4))
SET_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ELSE
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACHIEVEMENT:", DEBUG_GET_ACHIEVEMENT_TITLE(ACHH4) ," HAS BEEN PASSED - NOT SETTING BIT FOR:", GET_STRING_FROM_HEIST_ACHIEVEMENT_ID(iHeist))
CLEAR_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ENDIF
BREAK
CASE HEISTACH_H5_DONE
IF NOT HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACHH5))
SET_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ELSE
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACHIEVEMENT:", DEBUG_GET_ACHIEVEMENT_TITLE(ACHH5) ," HAS BEEN PASSED - NOT SETTING BIT FOR:", GET_STRING_FROM_HEIST_ACHIEVEMENT_ID(iHeist))
CLEAR_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ENDIF
BREAK
CASE HEISTACH_H6_DONE
IF NOT HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACHH6))
SET_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ELSE
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACHIEVEMENT:", DEBUG_GET_ACHIEVEMENT_TITLE(ACHH6) ," HAS BEEN PASSED - NOT SETTING BIT FOR:", GET_STRING_FROM_HEIST_ACHIEVEMENT_ID(iHeist))
CLEAR_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ENDIF
BREAK
CASE HEISTACH_H7_DONE
IF NOT HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACHH7))
SET_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ELSE
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACHIEVEMENT:", DEBUG_GET_ACHIEVEMENT_TITLE(ACHH7) ," HAS BEEN PASSED - NOT SETTING BIT FOR:", GET_STRING_FROM_HEIST_ACHIEVEMENT_ID(iHeist))
CLEAR_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ENDIF
BREAK
CASE HEISTACH_H8_DONE
IF NOT HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACHH8))
SET_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ELSE
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACHIEVEMENT:", DEBUG_GET_ACHIEVEMENT_TITLE(ACHH8) ," HAS BEEN PASSED - NOT SETTING BIT FOR:", GET_STRING_FROM_HEIST_ACHIEVEMENT_ID(iHeist))
CLEAR_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ENDIF
BREAK
CASE HEISTACH_H9_DONE
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - VALUABLE ASSET HAS BEEN REMOVED - CLEARING BIT")
CLEAR_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
BREAK
CASE HEISTACH_H10_DONE
IF NOT HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACHH10))
SET_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ELSE
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACHIEVEMENT:", DEBUG_GET_ACHIEVEMENT_TITLE(ACHH10) ," HAS BEEN PASSED - NOT SETTING BIT FOR:", GET_STRING_FROM_HEIST_ACHIEVEMENT_ID(iHeist))
CLEAR_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ENDIF
BREAK
CASE HEISTACH_CREW_CUT
IF NOT HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACH46))
SET_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ELSE
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACHIEVEMENT:", DEBUG_GET_ACHIEVEMENT_TITLE(ACH46) ," HAS BEEN PASSED - NOT SETTING BIT FOR:", GET_STRING_FROM_HEIST_ACHIEVEMENT_ID(iHeist))
CLEAR_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ENDIF
BREAK
CASE HEISTACH_CREW_CUT_SANCHECK
IF NOT HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACH46))
SET_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ELSE
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACHIEVEMENT:", DEBUG_GET_ACHIEVEMENT_TITLE(ACH46) ," HAS BEEN PASSED - NOT SETTING BIT FOR:", GET_STRING_FROM_HEIST_ACHIEVEMENT_ID(iHeist))
CLEAR_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ENDIF
BREAK
ENDSWITCH
ELSE
CLEAR_HEIST_ACHIEVEMENT_ID_BIT(iHeist)
ENDIF
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - END SET ACHIEVEMENT TRACKER BIT:", GET_STRING_FROM_HEIST_ACHIEVEMENT_ID(iHeist))
ENDPROC
FUNC BOOL IS_HEIST_ACHIEVEMENT_ID_SET(eHeistACHCheckID iHeist)
INT value = GET_MP_INT_PLAYER_STAT(MPPLY_HEIST_ACH_TRACKER)
RETURN IS_BIT_SET(value, ENUM_TO_INT(iHeist))
ENDFUNC
FUNC BOOL IS_THIS_VEHICLE_MODEL_IN_THE_HEIST_PACK(MODEL_NAMES carModel)
SWITCH (carModel)
// new vehicles for sale
CASE BOXVILLE4
CASE CASCO
CASE DINGHY3
CASE ENDURO
CASE GBURRITO2
CASE GUARDIAN
CASE HYDRA
CASE INSURGENT
CASE INSURGENT2
CASE KURUMA
CASE KURUMA2
CASE LECTRO
CASE MULE3
CASE SAVAGE
CASE TECHNICAL
CASE VALKYRIE
CASE VELUM2
// existing vehicles for sale
CASE GRESLEY
CASE JACKAL
CASE LANDSTALKER
CASE MESA3
CASE NEMESIS
CASE PBUS
CASE RUMPO
CASE SCHAFTER2
CASE SEMINOLE
CASE SURGE
RETURN TRUE
ENDSWITCH
RETURN FALSE
ENDFUNC
FUNC BOOL CHECK_LIVE_A_LITTLE_ACHIEVEMENT(MODEL_NAMES carModel, INT price)
IF (price = 0)
RETURN FALSE
ENDIF
IF NOT IS_THIS_VEHICLE_MODEL_IN_THE_HEIST_PACK(carModel)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - LIVE A LITTLE - WE HAVE BOUGHT A CAR:", GET_MODEL_NAME_FOR_DEBUG(carModel), " BUT IS IT NOT IN THE HEIST PACK")
RETURN FALSE
ENDIF
INT iTotal
INCREMENT_BY_MP_INT_PLAYER_STAT(MPPLY_MONEY_SPENT_ON_HEISTVEH, price)
iTotal = GET_MP_INT_PLAYER_STAT(MPPLY_MONEY_SPENT_ON_HEISTVEH)
IF (iTotal >= 8000000)
SET_HEIST_ACHIEVEMENT_ID(HEISTACH_H7_DONE)
IF HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACHH7))
AWARD_ACHIEVEMENT(ACHH7)
ENDIF
RETURN TRUE
ENDIF
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT] - ACH58 - LIVE A LITTLE - WE HAVE BOUGHT A CAR:", GET_MODEL_NAME_FOR_DEBUG(carModel), " TOTAL INCREASED BY:", price, " CURRENT TOTAL:", iTotal)
RETURN FALSE
ENDFUNC
PROC CHECK_ACHIEVEMENT_AWARD_JUNKIE(BOOL tty = FALSE)
IF NOT HAS_IMPORTANT_STATS_LOADED()
EXIT
ENDIF
IF NOT g_bInMultiplayer
EXIT
ENDIF
IF (tty)
CPRINTLN(DEBUG_ACHIEVEMENT, " ")
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH41 - Award Junkie - Active Char Award Counter:", GET_MP_INT_CHARACTER_STAT(MP_STAT_CHAR_FM_PLAT_AWARD_COUNT), " of ", ACH41_AWARDS_NEEDED)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH41 - Award Junkie - P1 Award Counter:", GET_MP_INT_CHARACTER_STAT(MP_STAT_CHAR_FM_PLAT_AWARD_COUNT, 0), " of ", ACH41_AWARDS_NEEDED)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH41 - Award Junkie - P2 Award Counter:", GET_MP_INT_CHARACTER_STAT(MP_STAT_CHAR_FM_PLAT_AWARD_COUNT, 1), " of ", ACH41_AWARDS_NEEDED)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH41 - Award Junkie - P3 Award Counter:", GET_MP_INT_CHARACTER_STAT(MP_STAT_CHAR_FM_PLAT_AWARD_COUNT, 2), " of ", ACH41_AWARDS_NEEDED)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH41 - Award Junkie - P4 Award Counter:", GET_MP_INT_CHARACTER_STAT(MP_STAT_CHAR_FM_PLAT_AWARD_COUNT, 3), " of ", ACH41_AWARDS_NEEDED)
CPRINTLN(DEBUG_ACHIEVEMENT, "[ACHIEVEMENT]: ACH41 - Award Junkie - P5 Award Counter:", GET_MP_INT_CHARACTER_STAT(MP_STAT_CHAR_FM_PLAT_AWARD_COUNT, 4), " of ", ACH41_AWARDS_NEEDED)
CPRINTLN(DEBUG_ACHIEVEMENT, " ")
ENDIF
IF GET_MP_INT_CHARACTER_STAT(MP_STAT_CHAR_FM_PLAT_AWARD_COUNT) >= ACH41_AWARDS_NEEDED
AWARD_ACHIEVEMENT(ACH41) // Award Junkie
ELSE
SET_ACHIEVEMENT_PROGRESS_SAFE(ENUM_TO_INT(ACH41),GET_MP_INT_CHARACTER_STAT(MP_STAT_CHAR_FM_PLAT_AWARD_COUNT))
ENDIF
ENDPROC
///// PURPOSE: Informs the acheivement system that a DLC assassination target has been killed.
///// This command will query what weapon type was used to kill the target and flag this
///// against the Tools of the Trade acheveiment progress.
/////
//PROC REGISTER_ASSASSIN_TARGET_KILLED(PED_INDEX pedDeadTarget)
// IF IS_ENTITY_DEAD(pedDeadTarget)
//
// //Check for standard weapon type kills.
// WEAPON_TYPE eWeaponType = GET_PED_CAUSE_OF_DEATH(pedDeadTarget)
// IF eWeaponType != WEAPONTYPE_INVALID
//
// WEAPON_GROUP eWeaponGroup = GET_WEAPONTYPE_GROUP(eWeaponType)
// INT iGroupBitToSet = -1
// #IF IS_DEBUG_BUILD
// STRING strGroupName
// #ENDIF
//
// SWITCH eWeaponGroup
// CASE WEAPONGROUP_PISTOL #IF IS_DEBUG_BUILD strGroupName = "PISTOL" #ENDIF iGroupBitToSet = 0 BREAK
// CASE WEAPONGROUP_MG #IF IS_DEBUG_BUILD strGroupName = "SMG/MG" #ENDIF iGroupBitToSet = 1 BREAK
// CASE WEAPONGROUP_SMG #IF IS_DEBUG_BUILD strGroupName = "SMG/MG" #ENDIF iGroupBitToSet = 1 BREAK
// CASE WEAPONGROUP_RIFLE #IF IS_DEBUG_BUILD strGroupName = "RIFLE" #ENDIF iGroupBitToSet = 2 BREAK
// CASE WEAPONGROUP_SNIPER #IF IS_DEBUG_BUILD strGroupName = "SNIPER" #ENDIF iGroupBitToSet = 3 BREAK
// CASE WEAPONGROUP_MELEE #IF IS_DEBUG_BUILD strGroupName = "MELEE" #ENDIF iGroupBitToSet = 4 BREAK
// CASE WEAPONGROUP_SHOTGUN #IF IS_DEBUG_BUILD strGroupName = "SHOTGUN" #ENDIF iGroupBitToSet = 5 BREAK
// CASE WEAPONGROUP_HEAVY #IF IS_DEBUG_BUILD strGroupName = "HEAVY" #ENDIF iGroupBitToSet = 6 BREAK
// CASE WEAPONGROUP_THROWN #IF IS_DEBUG_BUILD strGroupName = "THROWN" #ENDIF iGroupBitToSet = 7 BREAK
// ENDSWITCH
//
// //Flag the group as acheived in a saved bitset.
// IF iGroupBitToSet != -1
// IF NOT IS_BIT_SET(g_savedGlobalsDLC.iAssassinWeaponGroupsUsedBitset, iGroupBitToSet)
//#IF IS_DEBUG_BUILD
// CPRINTLN(DEBUG_ACHIEVEMENT, "Registering weapon group ", strGroupName, " as used for an Assassination.")
//#ENDIF
// SET_BIT(g_savedGlobalsDLC.iAssassinWeaponGroupsUsedBitset, iGroupBitToSet)
//#IF IS_DEBUG_BUILD
// ELSE
// CPRINTLN(DEBUG_ACHIEVEMENT, "Checked registration of weapon group ", strGroupName, " for Assassination, but it was already registered.")
//#ENDIF
// ENDIF
// ENDIF
// ENDIF
//
// ELSE
// SCRIPT_ASSERT("REGISTER_ASSASSIN_TARGET_KILLED: Passed ped index has not been killed yet.")
// ENDIF
//ENDPROC
//
//
//FUNC BOOL CHECK_TOOLS_OF_THE_TRADE_ACHIEVEMENT()
// IF HAS_ACHIEVEMENT_BEEN_PASSED(ENUM_TO_INT(ACH51)) this will need updating as ACH51 is now first person mode ach on NG
// RETURN FALSE
// ENDIF
//
// IF g_savedGlobalsDLC.iAssassinWeaponGroupsUsedBitset = 255
// AWARD_ACHIEVEMENT(ACH51)
// RETURN TRUE
// ENDIF
//
// RETURN FALSE
//ENDFUNC
//----------------------
// PS4 ACTIVITY FEED CHECKS
//----------------------
CONST_INT NO_SCHEDULED_ACTIVITY_FEED_CHECKS 10
CONST_INT BIT_ACTFEED_5STAR_WANTED_LAST_FRAME 0
CONST_INT BIT_ACTFEED_SENT_FINISHED_ALL_RES 0
CONST_INT BIT_ACTFEED_SENT_FIRED_HALF_MIL_BULLETS 6
CONST_INT BIT_ACTFEED_SENT_DRIVEN_ALL_VEHICLES 7
CONST_INT BIT_ACTFEED_SENT_ALL_STUNT_JUMPS 8
CONST_INT BIT_ACTFEED_SENT_WHOLE_MAP_EXPLORED 9
CONST_INT BIT_ACTFEED_SENT_ALL_BRIDGES_FLOWN 10
STRUCT ActivityFeedLocalVars
INT iFiveStarWantedCooldown
INT iAtHighestPointCooldown
INT iAtLowestPointCooldown
INT iRECheckIndex
INT iSixtyFrameCheckIndex
INT iNextMapPercentageTarget
INT iNextWastedCountTarget
INT iNextBustedCountTarget
FLOAT fNextDistanceRunTarget
FLOAT fNextDistanceDrivenTarget
FLOAT fNextDistanceFlownTarget
FLOAT fNextUnderBridgeTarget
FLOAT fNextStuntJumpTarget
INT iStateBitset
BOOL bMapPercentageInitialised
ENDSTRUCT
PROC ACTIVITY_FEED_EVADED_5STAR_WANTED_CHECK(ActivityFeedLocalVars &sLocalVars)
//Player doesn't have a 5 star wanted rating. Wait for them to get one.
IF NOT IS_BIT_SET(sLocalVars.iStateBitset, BIT_ACTFEED_5STAR_WANTED_LAST_FRAME)
IF GET_GAME_TIMER() > sLocalVars.iFiveStarWantedCooldown
IF IS_PLAYER_PLAYING(PLAYER_ID())
IF NOT IS_CURRENTLY_ON_MISSION_OF_ANY_TYPE()
IF g_sPlayerPedRequest.eState != PR_STATE_PROCESSING AND NOT IS_PLAYER_SWITCH_IN_PROGRESS()
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) = 5
CPRINTLN(DEBUG_ACTIVITY_FEED, "<5STAR_WANTED> Player has a 5 star wanted level. Starting tracking for activity feed.")
SET_BIT(sLocalVars.iStateBitset, BIT_ACTFEED_5STAR_WANTED_LAST_FRAME)
#IF IS_DEBUG_BUILD
ELIF (GET_FRAME_COUNT() % 60) = 0
CDEBUG2LN(DEBUG_ACTIVITY_FEED, "<5STAR_WANTED> Waiting for player to attain 5 stars.")
#ENDIF
ENDIF
#IF IS_DEBUG_BUILD
ELIF (GET_FRAME_COUNT() % 60) = 0
CDEBUG2LN(DEBUG_ACTIVITY_FEED, "<5STAR_WANTED> Waiting for player to finish switching character.")
#ENDIF
ENDIF
#IF IS_DEBUG_BUILD
ELIF (GET_FRAME_COUNT() % 60) = 0
CDEBUG2LN(DEBUG_ACTIVITY_FEED, "<5STAR_WANTED> Waiting for player to be off mission.")
#ENDIF
ENDIF
#IF IS_DEBUG_BUILD
ELIF (GET_FRAME_COUNT() % 60) = 0
CDEBUG2LN(DEBUG_ACTIVITY_FEED, "<5STAR_WANTED> Waiting for player to be playing.")
#ENDIF
ENDIF
#IF IS_DEBUG_BUILD
ELIF (GET_FRAME_COUNT() % 60) = 0
CDEBUG2LN(DEBUG_ACTIVITY_FEED, "<5STAR_WANTED> Waiting for cooldown timer.")
#ENDIF
ENDIF
//Player has a 5 star wanting level. Check if they have lost it.
ELSE
IF NOT IS_PLAYER_PLAYING(PLAYER_ID())
CPRINTLN(DEBUG_ACTIVITY_FEED, "<5STAR_WANTED> Player has died or been arrested. Clearing tracking for activity feed.")
CLEAR_BIT(sLocalVars.iStateBitset, BIT_ACTFEED_5STAR_WANTED_LAST_FRAME)
ELSE
IF g_sPlayerPedRequest.eState = PR_STATE_PROCESSING OR IS_PLAYER_SWITCH_IN_PROGRESS()
CPRINTLN(DEBUG_ACTIVITY_FEED, "<5STAR_WANTED> The player switched character. Clearing tracking for activity feed.")
CLEAR_BIT(sLocalVars.iStateBitset, BIT_ACTFEED_5STAR_WANTED_LAST_FRAME)
ELSE
IF IS_CURRENTLY_ON_MISSION_OF_ANY_TYPE()
CPRINTLN(DEBUG_ACTIVITY_FEED, "<5STAR_WANTED> The player went on mission. Clearing tracking for activity feed.")
CLEAR_BIT(sLocalVars.iStateBitset, BIT_ACTFEED_5STAR_WANTED_LAST_FRAME)
ELSE
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) = 0
CPRINTLN(DEBUG_ACTIVITY_FEED, "<5STAR_WANTED> Player lost their 5 star wanted level. Pushing message to activity feed.")
REQUEST_SYSTEM_ACTIVITY_TYPE_EVADED_5STAR_WANTED()
CLEAR_BIT(sLocalVars.iStateBitset, BIT_ACTFEED_5STAR_WANTED_LAST_FRAME)
//Don't allow this message to trigger again for 30 minutes real time.
sLocalVars.iFiveStarWantedCooldown = GET_GAME_TIMER() + 1800000
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC ACTIVITY_FEED_ALL_RES_CHECK(ActivityFeedLocalVars &sLocalVars)
IF NOT IS_BIT_SET(g_savedGlobals.sSocialData.iActivityFeedPostsMadeBitset, BIT_ACTFEED_SENT_FINISHED_ALL_RES)
IF g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[sLocalVars.iRECheckIndex].CP_Grouping = CP_GROUP_RANDOMEVENTS
IF g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[sLocalVars.iRECheckIndex].CP_Marked_As_Complete
sLocalVars.iRECheckIndex++
ELSE
CDEBUG3LN(DEBUG_ACTIVITY_FEED, "<ALL_RES> RE ", GET_STRING_FROM_TEXT_FILE(g_SavedGlobals.sCompletionPercentageData.g_CompletionPercentageList[sLocalVars.iRECheckIndex].CP_Label), " has not passed. Activity feed won't send yet.")
sLocalVars.iRECheckIndex = ENUM_TO_INT(CP_RE_ABCAR1)
ENDIF
ELSE
sLocalVars.iRECheckIndex++
ENDIF
IF sLocalVars.iRECheckIndex = ENUM_TO_INT(CP_RE_STAG1)
CPRINTLN(DEBUG_ACTIVITY_FEED, "<ALL_RES> All original RE missions have been completed. Pushing message to activity feed.")
REQUEST_SYSTEM_ACTIVITY_TYPE_COMPLETED_ALL_RANDOM()
SET_BIT(g_savedGlobals.sSocialData.iActivityFeedPostsMadeBitset, BIT_ACTFEED_SENT_FINISHED_ALL_RES)
ENDIF
ENDIF
ENDPROC
PROC ACTIVITY_FEED_AT_HIGHEST_POINT_CHECK(ActivityFeedLocalVars &sLocalVars)
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
IF GET_GAME_TIMER() > sLocalVars.iAtHighestPointCooldown
//On top of the radar tower on top of Mount Chilliad.
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), <<450.495056,5566.205078,806.223572>>, <<1.000000,1.000000,1.500000>>)
CPRINTLN(DEBUG_ACTIVITY_FEED, "<HIGHEST_POINT> The player is at the highest point on the map. Pushing message to activity feed.")
REQUEST_SYSTEM_ACTIVITY_TYPE_FOUND_HIGHEST_POINT()
//Don't allow this message to trigger again for 30 minutes real time.
sLocalVars.iAtHighestPointCooldown = GET_GAME_TIMER() + 1800000
ENDIF
ENDIF
ENDIF
ENDPROC
PROC ACTIVITY_FEED_AT_LOWEST_POINT_CHECK(ActivityFeedLocalVars &sLocalVars)
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
IF GET_GAME_TIMER() > sLocalVars.iAtLowestPointCooldown
//Some interiors are under the map. Don't allow this to trigger if they player is in one of these.
//Double check this by also checking the player is underwater.
IF GET_INTERIOR_FROM_ENTITY(PLAYER_PED_ID()) = NULL
//Crush depth is -150. If you push past it you can hit -175 and still get out alive... just.
VECTOR vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID())
IF vPlayerPos.z <= -175.0
CPRINTLN(DEBUG_ACTIVITY_FEED, "<LOWEST_POINT> The player is at the lowest depth possible on the map. Pushing message to activity feed.")
REQUEST_SYSTEM_ACTIVITY_TYPE_FOUND_LOWEST_POINT()
//Don't allow this message to trigger again for 30 minutes real time.
sLocalVars.iAtLowestPointCooldown = GET_GAME_TIMER() + 1800000
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
FUNC FLOAT GET_DISTANCE_ALL_CHARACTERS_HAVE_RUN()
FLOAT fDistanceRunning
FLOAT fCharacterDist
STAT_GET_FLOAT(SP0_DIST_WALKING, fCharacterDist)
fDistanceRunning += fCharacterDist
STAT_GET_FLOAT(SP1_DIST_WALKING, fCharacterDist)
fDistanceRunning += fCharacterDist
STAT_GET_FLOAT(SP2_DIST_WALKING, fCharacterDist)
fDistanceRunning += fCharacterDist
STAT_GET_FLOAT(SP0_DIST_RUNNING, fCharacterDist)
fDistanceRunning += fCharacterDist
STAT_GET_FLOAT(SP1_DIST_RUNNING, fCharacterDist)
fDistanceRunning += fCharacterDist
STAT_GET_FLOAT(SP2_DIST_RUNNING, fCharacterDist)
fDistanceRunning += fCharacterDist
IF DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM()
fDistanceRunning /= 1000
ELSE
fDistanceRunning = CONVERT_METERS_TO_MILES(fDistanceRunning)
ENDIF
RETURN fDistanceRunning
ENDFUNC
FUNC FLOAT GET_NEXT_DISTANCE_RUN_TARGET()
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<DIST_RUN> Generating new target for distance run...")
FLOAT fCurrentDistRun = GET_DISTANCE_ALL_CHARACTERS_HAVE_RUN()
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<DIST_RUN> Current distance run ", fCurrentDistRun, PICK_STRING(DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM(), " km.", " miles."))
FLOAT fRunInterval =50.0 // miles
IF DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM()
fRunInterval = 100.0 // kilometers
ENDIF
FLOAT fNewDistance = fCurrentDistRun - (fCurrentDistRun % fRunInterval)
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<DIST_RUN> Rounded down to nearest ", fRunInterval, PICK_STRING(DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM(), " km = ", " miles = "), fNewDistance, PICK_STRING(DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM(), " km.", " miles."))
fNewDistance += fRunInterval
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<DIST_RUN> Stepped up to next interval = ", fNewDistance, PICK_STRING(DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM(), " km.", " miles."))
RETURN fNewDistance
ENDFUNC
PROC ACTIVITY_FEED_RAN_X_DISTANCE_CHECK(ActivityFeedLocalVars &sLocalVars)
FLOAT fDistanceRunning = GET_DISTANCE_ALL_CHARACTERS_HAVE_RUN()
CDEBUG2LN(DEBUG_ACTIVITY_FEED, "<DIST_RUN> The player has run ", fDistanceRunning, PICK_STRING(DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM(), " km.", " miles."))
IF fDistanceRunning >= sLocalVars.fNextDistanceRunTarget
CPRINTLN(DEBUG_ACTIVITY_FEED, "<DIST_RUN> The player has run ", fDistanceRunning, PICK_STRING(DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM(), " km.", " miles."), " Pushing message to activity feed.")
IF DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM()
REQUEST_SYSTEM_ACTIVITY_TYPE_RAN_KILOMETERS(ROUND(sLocalVars.fNextDistanceRunTarget))
ELSE
REQUEST_SYSTEM_ACTIVITY_TYPE_RAN_MILES(ROUND(sLocalVars.fNextDistanceRunTarget))
ENDIF
sLocalVars.fNextDistanceRunTarget = GET_NEXT_DISTANCE_RUN_TARGET()
ENDIF
ENDPROC
FUNC FLOAT GET_DISTANCE_ALL_CHARACTERS_HAVE_DRIVEN()
FLOAT fDistanceDriven
FLOAT fCharacterDist
STAT_GET_FLOAT(SP0_DIST_CAR, fCharacterDist)
fDistanceDriven += fCharacterDist
STAT_GET_FLOAT(SP1_DIST_CAR, fCharacterDist)
fDistanceDriven += fCharacterDist
STAT_GET_FLOAT(SP2_DIST_CAR, fCharacterDist)
fDistanceDriven += fCharacterDist
STAT_GET_FLOAT(SP0_DIST_BIKE, fCharacterDist)
fDistanceDriven += fCharacterDist
STAT_GET_FLOAT(SP1_DIST_BIKE, fCharacterDist)
fDistanceDriven += fCharacterDist
STAT_GET_FLOAT(SP2_DIST_BIKE, fCharacterDist)
fDistanceDriven += fCharacterDist
STAT_GET_FLOAT(SP0_DIST_BICYCLE, fCharacterDist)
fDistanceDriven += fCharacterDist
STAT_GET_FLOAT(SP1_DIST_BICYCLE, fCharacterDist)
fDistanceDriven += fCharacterDist
STAT_GET_FLOAT(SP2_DIST_BICYCLE, fCharacterDist)
fDistanceDriven += fCharacterDist
IF DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM()
fDistanceDriven /= 1000
ELSE
fDistanceDriven = CONVERT_METERS_TO_MILES(fDistanceDriven)
ENDIF
RETURN fDistanceDriven
ENDFUNC
FUNC FLOAT GET_NEXT_DISTANCE_DRIVEN_TARGET()
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<DIST_DRI> Generating new target for distance driven...")
FLOAT fCurrentDistDriven = GET_DISTANCE_ALL_CHARACTERS_HAVE_DRIVEN()
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<DIST_DRI> Current distance driven ", fCurrentDistDriven, PICK_STRING(DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM(), " km.", " miles."))
FLOAT fDriveInterval = 500.0 // miles
IF DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM()
fDriveInterval = 1000.0 // kilometers
ENDIF
FLOAT fNewDistance = fCurrentDistDriven - (fCurrentDistDriven % fDriveInterval)
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<DIST_DRI> Rounded down to nearest ", fDriveInterval, PICK_STRING(DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM(), " km = ", " miles = "), fNewDistance, PICK_STRING(DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM(), " km.", " miles."))
fNewDistance += fDriveInterval
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<DIST_DRI> Stepped up to next interval = ", fNewDistance, PICK_STRING(DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM(), " km.", " miles."))
RETURN fNewDistance
ENDFUNC
PROC ACTIVITY_FEED_DRIVEN_X_DISTANCE_CHECK(ActivityFeedLocalVars &sLocalVars)
FLOAT fDistanceDriven = GET_DISTANCE_ALL_CHARACTERS_HAVE_DRIVEN()
CDEBUG2LN(DEBUG_ACTIVITY_FEED, "<DIST_DRI> The player has driven ", fDistanceDriven, PICK_STRING(DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM(), " km.", " miles."))
IF fDistanceDriven >= sLocalVars.fNextDistanceDrivenTarget
CPRINTLN(DEBUG_ACTIVITY_FEED, "<DIST_DRI> The player has driven ", fDistanceDriven, PICK_STRING(DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM(), " km.", " miles."), " Pushing message to activity feed.")
IF DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM()
REQUEST_SYSTEM_ACTIVITY_TYPE_DRIVEN_KILOMETERS(ROUND(sLocalVars.fNextDistanceDrivenTarget))
ELSE
REQUEST_SYSTEM_ACTIVITY_TYPE_DRIVEN_MILES(ROUND(sLocalVars.fNextDistanceDrivenTarget))
ENDIF
sLocalVars.fNextDistanceDrivenTarget = GET_NEXT_DISTANCE_DRIVEN_TARGET()
ENDIF
ENDPROC
FUNC FLOAT GET_DISTANCE_ALL_CHARACTERS_HAVE_FLOWN()
FLOAT fDistanceFlown
FLOAT fCharacterDist
STAT_GET_FLOAT(SP0_DIST_HELI, fCharacterDist)
fDistanceFlown += fCharacterDist
STAT_GET_FLOAT(SP1_DIST_HELI, fCharacterDist)
fDistanceFlown += fCharacterDist
STAT_GET_FLOAT(SP2_DIST_HELI, fCharacterDist)
fDistanceFlown += fCharacterDist
STAT_GET_FLOAT(SP0_DIST_PLANE, fCharacterDist)
fDistanceFlown += fCharacterDist
STAT_GET_FLOAT(SP1_DIST_PLANE, fCharacterDist)
fDistanceFlown += fCharacterDist
STAT_GET_FLOAT(SP2_DIST_PLANE, fCharacterDist)
fDistanceFlown += fCharacterDist
IF DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM()
fDistanceFlown /= 1000
ELSE
fDistanceFlown = CONVERT_METERS_TO_MILES(fDistanceFlown)
ENDIF
RETURN fDistanceFlown
ENDFUNC
FUNC FLOAT GET_NEXT_DISTANCE_FLOWN_TARGET()
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<DIST_FLY> Generating new target for distance flown...")
FLOAT fCurrentDistFlown = GET_DISTANCE_ALL_CHARACTERS_HAVE_FLOWN()
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<DIST_FLY> Current distance flown ", fCurrentDistFlown, PICK_STRING(DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM(), " km.", " miles."))
FLOAT fFlyInterval = 500.0 // miles
IF DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM()
fFlyInterval = 1000.0 // kilometers
ENDIF
FLOAT fNewDistance = fCurrentDistFlown - (fCurrentDistFlown % fFlyInterval)
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<DIST_FLY> Rounded down to nearest ", fFlyInterval, PICK_STRING(DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM(), " km = ", " miles = "), fNewDistance, PICK_STRING(DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM(), " km.", " miles."))
fNewDistance += fFlyInterval
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<DIST_FLY> Stepped up to next interval = ", fNewDistance, PICK_STRING(DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM(), " km.", " miles."))
RETURN fNewDistance
ENDFUNC
PROC ACTIVITY_FEED_FLOWN_X_DISTANCE_CHECK(ActivityFeedLocalVars &sLocalVars)
FLOAT fDistanceFlown = GET_DISTANCE_ALL_CHARACTERS_HAVE_FLOWN()
CDEBUG2LN(DEBUG_ACTIVITY_FEED, "<DIST_FLY> The player has flown ", fDistanceFlown, PICK_STRING(DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM(), " km.", " miles."))
IF fDistanceFlown >= sLocalVars.fNextDistanceFlownTarget
CPRINTLN(DEBUG_ACTIVITY_FEED, "<DIST_FLY> The player has flown ", fDistanceFlown, PICK_STRING(DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM(), " km.", " miles."), " Pushing message to activity feed.")
IF DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM()
REQUEST_SYSTEM_ACTIVITY_TYPE_FLOWN_KILOMETERS(ROUND(sLocalVars.fNextDistanceFlownTarget))
ELSE
REQUEST_SYSTEM_ACTIVITY_TYPE_FLOWN_MILES(ROUND(sLocalVars.fNextDistanceFlownTarget))
ENDIF
sLocalVars.fNextDistanceFlownTarget = GET_NEXT_DISTANCE_FLOWN_TARGET()
ENDIF
ENDPROC
FUNC INT GET_NUMBER_OF_TIMES_PLAYER_WASTED()
INT iTimesWasted = 0
INT iWastedCount
STAT_GET_INT(SP0_DEATHS, iWastedCount)
iTimesWasted += iWastedCount
STAT_GET_INT(SP1_DEATHS, iWastedCount)
iTimesWasted += iWastedCount
STAT_GET_INT(SP2_DEATHS, iWastedCount)
iTimesWasted += iWastedCount
RETURN iTimesWasted
ENDFUNC
FUNC INT GET_NEXT_WASTED_COUNT_TARGET()
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<WASTED_X> Generating new target wasted count...")
INT iCurrentTimesWasted = GET_NUMBER_OF_TIMES_PLAYER_WASTED()
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<WASTED_X> Current wasted count ", iCurrentTimesWasted, ".")
INT iWastedInterval = 25
INT iNewWastedTarget = iCurrentTimesWasted - (iCurrentTimesWasted % iWastedInterval)
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<WASTED_X> Rounded down to nearest ", iWastedInterval, " times = ", iNewWastedTarget, ".")
iNewWastedTarget += iWastedInterval
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<WASTED_X> Stepped up to next interval = ", iNewWastedTarget, ".")
RETURN iNewWastedTarget
ENDFUNC
PROC ACTIVITY_FEED_WASTED_X_TIMES_CHECK(ActivityFeedLocalVars &sLocalVars)
INT iCurrentWastedCount = GET_NUMBER_OF_TIMES_PLAYER_WASTED()
CDEBUG2LN(DEBUG_ACTIVITY_FEED, "<WASTED_X> The player has been wasted ", iCurrentWastedCount, " times.")
IF iCurrentWastedCount >= sLocalVars.iNextWastedCountTarget
CPRINTLN(DEBUG_ACTIVITY_FEED, "<WASTED_X> The player has been wasted ", iCurrentWastedCount, " times which is higher than target ", sLocalVars.iNextWastedCountTarget, ".")
CPRINTLN(DEBUG_ACTIVITY_FEED, "<WASTED_X> Pushing message to activity feed.")
REQUEST_SYSTEM_ACTIVITY_TYPE_WASTED_10_TIMES(sLocalVars.iNextWastedCountTarget)
sLocalVars.iNextWastedCountTarget = GET_NEXT_WASTED_COUNT_TARGET()
ENDIF
ENDPROC
FUNC INT GET_NUMBER_OF_TIMES_PLAYER_BUSTED()
INT iTimesBusted = 0
INT iBustedCount
STAT_GET_INT(SP0_BUSTED, iBustedCount)
iTimesBusted += iBustedCount
STAT_GET_INT(SP1_BUSTED, iBustedCount)
iTimesBusted += iBustedCount
STAT_GET_INT(SP2_BUSTED, iBustedCount)
iTimesBusted += iBustedCount
RETURN iTimesBusted
ENDFUNC
FUNC INT GET_NEXT_BUSTED_COUNT_TARGET()
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<BUSTED_X> Generating new target busted count...")
INT iCurrentTimesBusted = GET_NUMBER_OF_TIMES_PLAYER_BUSTED()
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<BUSTED_X> Current busted count ", iCurrentTimesBusted, ".")
INT iBustedInterval = 25
INT iNewBustedTarget = iCurrentTimesBusted - (iCurrentTimesBusted % iBustedInterval)
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<BUSTED_X> Rounded down to nearest ", iBustedInterval, " times = ", iNewBustedTarget, ".")
iNewBustedTarget += iBustedInterval
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<BUSTED_X> Stepped up to next interval = ", iNewBustedTarget, ".")
RETURN iNewBustedTarget
ENDFUNC
PROC ACTIVITY_FEED_BUSTED_X_TIMES_CHECK(ActivityFeedLocalVars &sLocalVars)
INT iCurrentBustedCount = GET_NUMBER_OF_TIMES_PLAYER_BUSTED()
CDEBUG2LN(DEBUG_ACTIVITY_FEED, "<BUSTED_X> The player has been busted ", iCurrentBustedCount, " times.")
IF iCurrentBustedCount >= sLocalVars.iNextBustedCountTarget
CPRINTLN(DEBUG_ACTIVITY_FEED, "<BUSTED_X> The player has been busted ", iCurrentBustedCount, " times which is higher than target ", sLocalVars.iNextBustedCountTarget, ".")
CPRINTLN(DEBUG_ACTIVITY_FEED, "<BUSTED_X> Pushing message to activity feed.")
REQUEST_SYSTEM_ACTIVITY_TYPE_BUSTED_10_TIMES(sLocalVars.iNextBustedCountTarget)
sLocalVars.iNextBustedCountTarget = GET_NEXT_BUSTED_COUNT_TARGET()
ENDIF
ENDPROC
FUNC FLOAT GET_PERCENTAGE_OF_UNDER_BRIDGES_COMPLETED()
RETURN (TO_FLOAT(GET_NUMBER_OF_COMPLETED_UNDER_BRIDGES()) / TO_FLOAT(SP_NUMBER_OF_BRIDGES)) * 100.0
ENDFUNC
FUNC FLOAT GET_NEXT_UNDER_BRIDGE_PERCENTAGE_TARGET()
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<UNDER_BRI> Generating new target under bridge percentage...")
FLOAT fCurrentPercentage = GET_PERCENTAGE_OF_UNDER_BRIDGES_COMPLETED()
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<UNDER_BRI> Current under bridge percentage = ", fCurrentPercentage, "%.")
FLOAT fUnderBridgeInterval = 4.0
FLOAT fNewUnderBridgeTarget = fCurrentPercentage - (fCurrentPercentage % fUnderBridgeInterval)
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<UNDER_BRI> Rounded down to nearest ", fUnderBridgeInterval, "% = ", fNewUnderBridgeTarget, "%.")
fNewUnderBridgeTarget += fUnderBridgeInterval
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<UNDER_BRI> Stepped up to next interval = ", fNewUnderBridgeTarget, "%.")
RETURN fNewUnderBridgeTarget
ENDFUNC
PROC ACTIVITY_FEED_FLY_UNDER_BRIDGES_CHECK(ActivityFeedLocalVars &sLocalVars)
IF NOT IS_BIT_SET(g_savedGlobals.sSocialData.iActivityFeedPostsMadeBitset, BIT_ACTFEED_SENT_ALL_BRIDGES_FLOWN)
FLOAT fCurrentPercentage = GET_PERCENTAGE_OF_UNDER_BRIDGES_COMPLETED()
CDEBUG2LN(DEBUG_ACTIVITY_FEED, "<UNDER_BRI> The player has completed ", fCurrentPercentage, "% of under bridge flights.")
IF fCurrentPercentage >= sLocalVars.fNextUnderBridgeTarget
CPRINTLN(DEBUG_ACTIVITY_FEED, "<UNDER_BRI> The player has completed ", fCurrentPercentage, "% of under bridge flights.")
CPRINTLN(DEBUG_ACTIVITY_FEED, "<UNDER_BRI> This is higher than target of ", sLocalVars.fNextUnderBridgeTarget, "%. Pushing message to activity feed.")
REQUEST_SYSTEM_ACTIVITY_TYPE_SP_UNDER_BRIDGE(ROUND(sLocalVars.fNextUnderBridgeTarget))
sLocalVars.fNextUnderBridgeTarget = GET_NEXT_UNDER_BRIDGE_PERCENTAGE_TARGET()
IF fCurrentPercentage >= 100.0
CPRINTLN(DEBUG_ACTIVITY_FEED, "<UNDER_BRI> All bridges flown. Flagging not to run the check again.")
SET_BIT(g_savedGlobals.sSocialData.iActivityFeedPostsMadeBitset, BIT_ACTFEED_SENT_ALL_BRIDGES_FLOWN)
ENDIF
ENDIF
ENDIF
ENDPROC
FUNC FLOAT GET_PERCENTAGE_OF_STUNT_JUMPS_COMPLETED()
RETURN TO_FLOAT(GET_NUM_SUCCESSFUL_STUNT_JUMPS())/50.0*100.0
ENDFUNC
FUNC FLOAT GET_NEXT_STUNT_JUMP_PERCENTAGE_TARGET()
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<STUNT_J> Generating new target stunt jump percentage...")
FLOAT fCurrentPercentage = GET_PERCENTAGE_OF_STUNT_JUMPS_COMPLETED()
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<STUNT_J> Current stunt jump percentage = ", fCurrentPercentage, "%.")
FLOAT fStuntJumpInterval = 4.0
FLOAT fNewStuntJumpTarget = fCurrentPercentage - (fCurrentPercentage % fStuntJumpInterval)
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<STUNT_J> Rounded down to nearest ", fStuntJumpInterval, "% = ", fNewStuntJumpTarget, "%.")
fNewStuntJumpTarget += fStuntJumpInterval
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<STUNT_J> Stepped up to next interval = ", fNewStuntJumpTarget, "%.")
RETURN fNewStuntJumpTarget
ENDFUNC
PROC ACTIVITY_FEED_STUNT_JUMP_CHECK(ActivityFeedLocalVars &sLocalVars)
IF NOT IS_BIT_SET(g_savedGlobals.sSocialData.iActivityFeedPostsMadeBitset, BIT_ACTFEED_SENT_ALL_STUNT_JUMPS)
FLOAT fCurrentPercentage = GET_PERCENTAGE_OF_STUNT_JUMPS_COMPLETED()
CDEBUG2LN(DEBUG_ACTIVITY_FEED, "<STUNT_J> The player has completed ", fCurrentPercentage, "% of stunt jumps.")
IF fCurrentPercentage >= sLocalVars.fNextStuntJumpTarget
CPRINTLN(DEBUG_ACTIVITY_FEED, "<STUNT_J> The player has completed ", fCurrentPercentage, "% of stunt jumps.")
CPRINTLN(DEBUG_ACTIVITY_FEED, "<STUNT_J> This is higher than target of ", sLocalVars.fNextStuntJumpTarget, "%. Pushing message to activity feed.")
REQUEST_SYSTEM_ACTIVITY_TYPE_SP_STUNT_JUMPS(ROUND(sLocalVars.fNextStuntJumpTarget))
sLocalVars.fNextStuntJumpTarget = GET_NEXT_STUNT_JUMP_PERCENTAGE_TARGET()
IF fCurrentPercentage >= 100.0
CPRINTLN(DEBUG_ACTIVITY_FEED, "<STUNT_J> All stunt jumps complete. Flagging not to run the check again.")
SET_BIT(g_savedGlobals.sSocialData.iActivityFeedPostsMadeBitset, BIT_ACTFEED_SENT_ALL_STUNT_JUMPS)
ENDIF
ENDIF
ENDIF
ENDPROC
PROC ACTIVITY_FEED_FIRED_HALF_MIL_BULLETS_CHECK()
IF NOT IS_BIT_SET(g_savedGlobals.sSocialData.iActivityFeedPostsMadeBitset, BIT_ACTFEED_SENT_FIRED_HALF_MIL_BULLETS)
INT iTimesShot = 0
INT iShotCount
STAT_GET_INT(SP0_SHOTS, iShotCount)
iTimesShot += iShotCount
STAT_GET_INT(SP1_SHOTS, iShotCount)
iTimesShot += iShotCount
STAT_GET_INT(SP2_SHOTS, iShotCount)
iTimesShot += iShotCount
CDEBUG2LN(DEBUG_ACTIVITY_FEED, "<HALF_MIL_BULLETS> The player has fired ", iTimesShot, " rounds.")
IF iTimesShot >= 500000
CPRINTLN(DEBUG_ACTIVITY_FEED, "<HALF_MIL_BULLETS> The player has fired ", iTimesShot, " rounds. Pushing message to activity feed.")
REQUEST_SYSTEM_ACTIVITY_TYPE_FIRED_HALFMIL_BULLETS()
SET_BIT(g_savedGlobals.sSocialData.iActivityFeedPostsMadeBitset, BIT_ACTFEED_SENT_FIRED_HALF_MIL_BULLETS)
ENDIF
ENDIF
ENDPROC
PROC ACTIVITY_FEED_DRIVEN_ALL_VEHICLES()
IF NOT IS_BIT_SET(g_savedGlobals.sSocialData.iActivityFeedPostsMadeBitset, BIT_ACTFEED_SENT_DRIVEN_ALL_VEHICLES)
IF GET_PLAYER_HAS_DRIVEN_ALL_VEHICLES()
CPRINTLN(DEBUG_ACTIVITY_FEED, "<DRIVEN_ALL> The player has driven all vehicles on this playthrough. Pushing message to activity feed.")
REQUEST_SYSTEM_ACTIVITY_TYPE_DRIVEN_ALL_VEHICLES()
SET_BIT(g_savedGlobals.sSocialData.iActivityFeedPostsMadeBitset, BIT_ACTFEED_SENT_DRIVEN_ALL_VEHICLES)
ENDIF
ENDIF
ENDPROC
FUNC FLOAT GET_LENIENT_MAP_REVEALED_PERCENTAGE()
RETURN (GET_MINIMAP_FOW_DISCOVERY_RATIO()*100) + 0.5 //Add an extra 0.5% to all values to make it possible to hit the elusive 100%.
ENDFUNC
FUNC INT GET_NEXT_MAP_PERCENTAGE_TARGET()
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<MAP_EXP> Generating new target map explore percentage...")
//Get current percentage.
FLOAT fCurrentPercentage = GET_LENIENT_MAP_REVEALED_PERCENTAGE()
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<MAP_EXP> Currently explored ", fCurrentPercentage, "%.")
FLOAT fNewPercentage = fCurrentPercentage - (fCurrentPercentage%5)
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<MAP_EXP> Rounded down to nearest 5% = ", fNewPercentage, "%.")
fNewPercentage += 5.0
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<MAP_EXP> Stepping up to next 5% = ", fNewPercentage, "%.")
IF fNewPercentage > 100.0
fNewPercentage = 100.0
ENDIF
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<MAP_EXP> Final capped value = ", fNewPercentage, "%.")
RETURN ROUND(fNewPercentage)
ENDFUNC
PROC ACTIVITY_FEED_INITIALISE_MAP_PERCENTAGE_VALUE(ActivityFeedLocalVars &sLocalVars)
IF IS_SCREEN_FADED_IN()
sLocalVars.iNextMapPercentageTarget = GET_NEXT_MAP_PERCENTAGE_TARGET()
sLocalVars.bMapPercentageInitialised = TRUE
ENDIF
ENDPROC
PROC ACTIVITY_FEED_MAP_EXPLORED_CHECK(ActivityFeedLocalVars &sLocalVars)
IF sLocalVars.bMapPercentageInitialised
IF NOT IS_BIT_SET(g_savedGlobals.sSocialData.iActivityFeedPostsMadeBitset, BIT_ACTFEED_SENT_WHOLE_MAP_EXPLORED)
CDEBUG2LN(DEBUG_ACTIVITY_FEED, "<MAP_EXP> Player has explored ", GET_LENIENT_MAP_REVEALED_PERCENTAGE(), "%. Target is ", sLocalVars.iNextMapPercentageTarget, "%.")
IF GET_LENIENT_MAP_REVEALED_PERCENTAGE() >= TO_FLOAT(sLocalVars.iNextMapPercentageTarget)
CPRINTLN(DEBUG_ACTIVITY_FEED, "<MAP_EXP> The player has explored over the current target percentage of ", sLocalVars.iNextMapPercentageTarget, "%.")
CPRINTLN(DEBUG_ACTIVITY_FEED, "<MAP_EXP> Pushing message to activity feed.")
REQUEST_SYSTEM_ACTIVITY_TYPE_EXPLORATION(sLocalVars.iNextMapPercentageTarget)
IF sLocalVars.iNextMapPercentageTarget < 100
sLocalVars.iNextMapPercentageTarget = GET_NEXT_MAP_PERCENTAGE_TARGET()
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<MAP_EXP> New target percentage is ", sLocalVars.iNextMapPercentageTarget, "%.")
ELSE
SET_BIT(g_savedGlobals.sSocialData.iActivityFeedPostsMadeBitset, BIT_ACTFEED_SENT_WHOLE_MAP_EXPLORED)
CDEBUG1LN(DEBUG_ACTIVITY_FEED, "<MAP_EXP> Whole map explored. Flagging check to no longer run.")
ENDIF
ENDIF
ENDIF
ELSE
ACTIVITY_FEED_INITIALISE_MAP_PERCENTAGE_VALUE(sLocalVars)
ENDIF
ENDPROC
PROC ACTIVITY_FEED_INITIALISE_TARGET_VALUES(ActivityFeedLocalVars &sLocalVars)
CPRINTLN(DEBUG_ACTIVITY_FEED, "Setting up intial target values for PS4 activity feed.")
ACTIVITY_FEED_INITIALISE_MAP_PERCENTAGE_VALUE(sLocalVars)
sLocalVars.iNextWastedCountTarget = GET_NEXT_WASTED_COUNT_TARGET()
sLocalVars.iNextBustedCountTarget = GET_NEXT_BUSTED_COUNT_TARGET()
sLocalVars.fNextDistanceRunTarget = GET_NEXT_DISTANCE_RUN_TARGET()
sLocalVars.fNextDistanceDrivenTarget = GET_NEXT_DISTANCE_DRIVEN_TARGET()
sLocalVars.fNextDistanceFlownTarget = GET_NEXT_DISTANCE_FLOWN_TARGET()
sLocalVars.fNextUnderBridgeTarget = GET_NEXT_UNDER_BRIDGE_PERCENTAGE_TARGET()
sLocalVars.fNextStuntJumpTarget = GET_NEXT_STUNT_JUMP_PERCENTAGE_TARGET()
sLocalVars.iRECheckIndex = ENUM_TO_INT(CP_RE_ABCAR1)
ENDPROC
PROC MAINTAIN_ACTIVITY_FEED_CHECKS(ActivityFeedLocalVars &sLocalVars)
//Per frame checks.
ACTIVITY_FEED_EVADED_5STAR_WANTED_CHECK(sLocalVars)
ACTIVITY_FEED_ALL_RES_CHECK(sLocalVars)
ACTIVITY_FEED_AT_HIGHEST_POINT_CHECK(sLocalVars)
ACTIVITY_FEED_AT_LOWEST_POINT_CHECK(sLocalVars)
//Run one non critical check every 60 frames.
IF (GET_FRAME_COUNT() % 60) = 0
SWITCH sLocalVars.iSixtyFrameCheckIndex
CASE 0 ACTIVITY_FEED_RAN_X_DISTANCE_CHECK(sLocalVars) BREAK
CASE 1 ACTIVITY_FEED_DRIVEN_X_DISTANCE_CHECK(sLocalVars) BREAK
CASE 2 ACTIVITY_FEED_FLOWN_X_DISTANCE_CHECK(sLocalVars) BREAK
CASE 3 ACTIVITY_FEED_WASTED_X_TIMES_CHECK(sLocalVars) BREAK
CASE 4 ACTIVITY_FEED_BUSTED_X_TIMES_CHECK(sLocalVars) BREAK
CASE 5 ACTIVITY_FEED_FLY_UNDER_BRIDGES_CHECK(sLocalVars) BREAK
CASE 6 ACTIVITY_FEED_STUNT_JUMP_CHECK(sLocalVars) BREAK
CASE 7 ACTIVITY_FEED_FIRED_HALF_MIL_BULLETS_CHECK() BREAK
CASE 8 ACTIVITY_FEED_DRIVEN_ALL_VEHICLES() BREAK
CASE 9 ACTIVITY_FEED_MAP_EXPLORED_CHECK(sLocalVars) BREAK
ENDSWITCH
sLocalVars.iSixtyFrameCheckIndex++
IF sLocalVars.iSixtyFrameCheckIndex >= NO_SCHEDULED_ACTIVITY_FEED_CHECKS
sLocalVars.iSixtyFrameCheckIndex = 0
ENDIF
ENDIF
ENDPROC