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

591 lines
22 KiB
Scheme
Executable File

USING "globals.sch"
USING "rage_builtins.sch"
USING "candidate_public.sch"
USING "net_include.sch"
USING "beast_secret_shared.sch"
#IF FEATURE_SP_DLC_BEAST_SECRET
//
// Beast Peyote Trail
//
// The player must collect the golden peyotes in the correct order. A different
// peyote spawns on each day of the week and the player must recognise that they
// are a progression that travel across the map from the forest to Grapeseed
// (Sunday to Saturday). Each time the player collects a peyote in the correct order
// we play a SFX of The Beast near them which is a hint they are making progress.
// Once they collect all 7 this section of the mystery is permanently completed
// and The Beast Hunt mystery becomes active on the map while playing as the Sasquatch.
CONST_FLOAT BP_SFX_DISTANCE_FROM_PLAYER 52.5
CONST_FLOAT BP_MIN_SFX_RANGE 25.0
CONST_FLOAT BP_MAX_SFX_RANGE 1600.0
CONST_INT BP_MIN_INITIAL_TIME_FOR_SFX 8000
CONST_INT BP_MAX_INITIAL_TIME_FOR_SFX 12000
CONST_INT BP_MIN_TIME_BETWEEN_SFX 10000
CONST_INT BP_MAX_TIME_BETWEEN_SFX 15000
CONST_INT BP_BITSHIFT_LAST_DAY 11
CONST_INT BP_BITMASK_LAST_DAY (BIT11|BIT12|BIT13) //See: SP_INIT_BEAST_LAST_PEYOTE_DAY
CONST_INT BP_BIT_PLAYING_AS_SASQUATCH 6 //Is the player currently the sasquatch?
CONST_INT BP_BIT_BEAST_HINT_PICKED 8 //Have we selected what kind of hint to use on this peyote?
CONST_INT BP_BIT_SFX_ALLOWED 12 //Is the beast SFX allowed to play?
CONST_INT BP_BIT_SFX_REQUESTED 23 //Has the sfx asset started to load?
CONST_INT BP_BIT_HINT_ASSETS_REQUESTED 25 //Has the hint assets started to load?
CONST_INT BP_BIT_BEAST_SOUND_PLAYING 30 //Is a hint sfx currently playing?
CONST_INT BP_BIT_BEAST_HINT_CREATED 31 //Is a hint sfx currently playing?
STRUCT BeastPeyoteVars
INT iState
INT iSoundID
INT iSoundStartTime
INT iHintFadeTimer
VEHICLE_INDEX vehHint
PED_INDEX pedHint
VECTOR vSfxTargetPosition
TEXT_LABEL_63 tlSfxName
#IF IS_DEBUG_BUILD
BOOL bDebugTerminateThread
BOOL bDebugDrawingEnabled
BOOL bDebugPeyotesComplete
BOOL bDebugTogglePeyotesComplete
BOOL bDebugDrawSoundLocation
INT iDebugLastCollectedDay
INT iDebugSetCurrentDay
VECTOR vDebugLastSoundLocation
//DecalPlacementData sDebugDecalPlacement
#ENDIF
ENDSTRUCT
PROC Reset_Beast_Peyote_Variables(BeastPeyoteVars &sBeastPeyoteVars)
sBeastPeyoteVars.iState = 0
sBeastPeyoteVars.iSoundID = -1
sBeastPeyoteVars.iSoundStartTime = -1
sBeastPeyoteVars.tlSfxName = Build_Beast_String_63("C_SF", "DL", "AST", "X1/BE") //"DLC_SFX1/BEAST"
//Set Beast Peyote X
Set_Beast_Peyote_Vectors_X()
//Set Beast Hunt Y variables
Set_Beast_Hunt_Vectors_Y()
//Beast Fight X set-up
Set_Beast_Fight_Vectors_x()
ENDPROC
FUNC INT Get_Last_Peyote_Day()
INT iValue = Get_Int_From_Bitset(g_savedGlobals.sFlowCustom.spInitBitset, BP_BITMASK_LAST_DAY, BP_BITSHIFT_LAST_DAY)
CDEBUG3LN(DEBUG_HUNTING, " Read last peyote day as ", iValue, ".")
RETURN iValue
ENDFUNC
PROC Set_Last_Peyote_Day(BeastPeyoteVars &sBeastPeyoteVars, INT iValue)
CDEBUG2LN(DEBUG_HUNTING, " Setting last peyote day to ", iValue, ".")
Set_Int_In_Bitset(g_savedGlobals.sFlowCustom.spInitBitset, iValue, BP_BITMASK_LAST_DAY, BP_BITSHIFT_LAST_DAY)
#IF IS_DEBUG_BUILD
sBeastPeyoteVars.iDebugLastCollectedDay = iValue
sBeastPeyoteVars.iDebugSetCurrentDay = iValue
#ENDIF
#IF IS_FINAL_BUILD
UNUSED_PARAMETER(sBeastPeyoteVars)
#ENDIF
ENDPROC
FUNC INT Get_Beast_Hint_Type_For_Day(INT iDayOfTheWeek)
SWITCH iDayOfTheWeek
CASE 1 RETURN BHT_RABBIT
CASE 2 RETURN BHT_DEER
CASE 3 RETURN BHT_CAR_WRECK
CASE 4 RETURN BHT_BOAR
CASE 5 RETURN BHT_LION
CASE 6 RETURN BHT_MOUNTAIN_BIKER
ENDSWITCH
RETURN BHT_INVALID
ENDFUNC
FUNC VECTOR Get_Beast_Sfx_Target_Position_For_Day(INT iDayOfTheWeek)
// SWITCH iDayOfTheWeek
// CASE 0 RETURN <<-1567.3816, 4464.3052, 17.4783>>
// CASE 1 RETURN <<-1436.3053, 4428.8013, 44.8536>>
// CASE 2 RETURN <<31.2408, 4328.0522, 43.9517>>
// CASE 3 RETURN <<278.1924, 4276.5039, 39.3595>>
// CASE 4 RETURN <<1116.0020, 4506.7651, 64.8542>>
// CASE 5 RETURN <<1676.1929, 5139.8701, 149.3976>>
// ENDSWITCH
IF iDayOfTheWeek >= 0 AND iDayOfTheWeek < 7
RETURN g_vPeyoteDaySfxPosition[iDayOfTheWeek]
ENDIF
RETURN <<0,0,0>>
ENDFUNC
FUNC VECTOR Get_Beast_Hint_Position_For_Day(INT iDayOfTheWeek)
SWITCH iDayOfTheWeek
CASE 1 RETURN g_vPeyoteDayHintPosition[0] //<<-1592.6420, 4592.2207, 35.9522>>
CASE 2 RETURN g_vPeyoteDayHintPosition[1] //<<-1573.5006, 4459.3745, 13.5490>>
CASE 3 RETURN g_vPeyoteDayHintPosition[2] //<<-1459.3585, 4473.0684, 18.1095>>
CASE 4 RETURN g_vPeyoteDayHintPosition[3] //<<21.1005, 4317.9458, 42.2091>>
CASE 5 RETURN g_vPeyoteDayHintPosition[4] //<<262.9409, 4285.7988, 41.0045>>
CASE 6 RETURN g_vPeyoteDayHintPosition[5] //<<1091.0703, 4500.7588, 50.1141>>
ENDSWITCH
CERRORLN(debug_hunting, "Get_Hint_Position_For_Day: No hint position set for given day of the week.")
RETURN <<0,0,0>>
ENDFUNC
FUNC FLOAT Get_Beast_Hint_Heading_For_Day(INT iDayOfTheWeek)
SWITCH iDayOfTheWeek
CASE 1 RETURN 190.1056
CASE 2 RETURN 132.9326
CASE 3 RETURN 355.7119
CASE 4 RETURN 209.0264
CASE 5 RETURN 122.6722
CASE 6 RETURN 174.8410
ENDSWITCH
CERRORLN(debug_hunting, "Get_Hint_Heading_For_Day: No hint heading set for given day of the week.")
RETURN 0.0
ENDFUNC
PROC Request_Beast_Peyote_Sfx(INT &iState, STRING sfxName)
CPRINTLN(DEBUG_HUNTING, " Requesting beast sfx asset.")
REQUEST_SCRIPT_AUDIO_BANK(sfxName)
SET_BIT(iState, BP_BIT_SFX_REQUESTED)
ENDPROC
PROC Release_Beast_Peyote_Sfx(INT &iState)
CPRINTLN(DEBUG_HUNTING, " Releasing beast sfx asset.")
RELEASE_SCRIPT_AUDIO_BANK()
CLEAR_BIT(iState, BP_BIT_SFX_REQUESTED)
ENDPROC
PROC Request_Beast_Peyote_Hint_Assets(INT &iState)
CPRINTLN(DEBUG_HUNTING, " Requesting beast hint assets.")
INT iPeyoteDay = Get_Last_Peyote_Day()
INT iHintType = Get_Beast_Hint_Type_For_Day(iPeyoteDay)
MODEL_NAMES eHintModelA = Get_Beast_Hint_Model_A(iHintType)
MODEL_NAMES eHintModelB = Get_Beast_Hint_Model_B(iHintType)
IF eHintModelA != DUMMY_MODEL_FOR_SCRIPT
CDEBUG1LN(DEBUG_HUNTING, " Requesting hint model A.")
REQUEST_MODEL(eHintModelA)
ENDIF
IF eHintModelB != DUMMY_MODEL_FOR_SCRIPT
CDEBUG1LN(DEBUG_HUNTING, " Requesting hint model B.")
REQUEST_MODEL(eHintModelB)
ENDIF
SET_BIT(iState, BP_BIT_HINT_ASSETS_REQUESTED)
ENDPROC
FUNC BOOL Have_Beast_Peyote_Hint_Assets_Loaded()
INT iPeyoteDay = Get_Last_Peyote_Day()
INT iHintType = Get_Beast_Hint_Type_For_Day(iPeyoteDay)
MODEL_NAMES eHintModelA = Get_Beast_Hint_Model_A(iHintType)
MODEL_NAMES eHintModelB = Get_Beast_Hint_Model_B(iHintType)
IF eHintModelA != DUMMY_MODEL_FOR_SCRIPT
IF NOT HAS_MODEL_LOADED(eHintModelA)
RETURN FALSE
ENDIF
ENDIF
IF eHintModelB != DUMMY_MODEL_FOR_SCRIPT
IF NOT HAS_MODEL_LOADED(eHintModelB)
RETURN FALSE
ENDIF
ENDIF
RETURN TRUE
ENDFUNC
PROC Release_Beast_Peyote_Hint_Assets(INT &iState)
CPRINTLN(DEBUG_HUNTING, " Releasing beast hint assets.")
INT iPeyoteDay = Get_Last_Peyote_Day()
INT iHintType = Get_Beast_Hint_Type_For_Day(iPeyoteDay)
MODEL_NAMES eHintModelA = Get_Beast_Hint_Model_A(iHintType)
MODEL_NAMES eHintModelB = Get_Beast_Hint_Model_B(iHintType)
IF eHintModelA != DUMMY_MODEL_FOR_SCRIPT
CDEBUG1LN(DEBUG_HUNTING, " Releasing hint model A.")
SET_MODEL_AS_NO_LONGER_NEEDED(eHintModelA)
ENDIF
IF eHintModelB != DUMMY_MODEL_FOR_SCRIPT
CDEBUG1LN(DEBUG_HUNTING, " Releasing hint model B.")
SET_MODEL_AS_NO_LONGER_NEEDED(eHintModelB)
ENDIF
CLEAR_BIT(iState, BP_BIT_HINT_ASSETS_REQUESTED)
ENDPROC
FUNC VECTOR Calculate_Beast_Sfx_Position_For_Player(BeastPeyoteVars &sBeastPeyoteVars)
VECTOR vFinalPosition
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
VECTOR vPlayerPosition = GET_ENTITY_COORDS(PLAYER_PED_ID())
VECTOR vOffsetToSound = NORMALISE_VECTOR(sBeastPeyoteVars.vSfxTargetPosition - vPlayerPosition) * BP_SFX_DISTANCE_FROM_PLAYER
vFinalPosition = vPlayerPosition + vOffsetToSound
ENDIF
#IF IS_DEBUG_BUILD
IF ARE_VECTORS_EQUAL(vFinalPosition, <<0,0,0>>)
SCRIPT_ASSERT("Calculate_Beast_Sfx_Position_For_Player: The player was dead while trying to calculate beast sound position.")
ENDIF
#ENDIF
RETURN vFinalPosition
ENDFUNC
PROC Play_Beast_Sound_From_Position(BeastPeyoteVars &sBeastPeyoteVars, VECTOR vPosition)
CPRINTLN(DEBUG_HUNTING, " Playing beast sound at position ", vPosition, ".")
TEXT_LABEL_63 tlSound = Build_Beast_String_63("EAS", "B", "ALLS", "T_C") //"BEAST_CALLS"
TEXT_LABEL_63 tlSet = Build_Beast_String_63("ENTS_SA", "FM_EV", "CH_SOUNDS", "SQUAT") //"FM_EVENTS_SASQUATCH_SOUNDS"
sBeastPeyoteVars.iSoundId = GET_SOUND_ID()
PLAY_SOUND_FROM_COORD(sBeastPeyoteVars.iSoundId, tlSound, vPosition, tlSet)
#IF IS_DEBUG_BUILD
sBeastPeyoteVars.vDebugLastSoundLocation = vPosition
#ENDIF
ENDPROC
PROC Create_Beast_Peyote_Hint(BeastPeyoteVars &sBeastPeyoteVars)
CPRINTLN(DEBUG_HUNTING, "Creating beast peyote hint.")
INT iPeyoteDay = Get_Last_Peyote_Day()
INT iHintType = Get_Beast_Hint_Type_For_Day(iPeyoteDay)
Create_Beast_Hint_Type( iHintType,
sBeastPeyoteVars.pedHint,
sBeastPeyoteVars.vehHint,
Get_Beast_Hint_Position_For_Day(iPeyoteDay),
Get_Beast_Hint_Heading_For_Day(iPeyoteDay),
TRUE)
SET_BIT(sBeastPeyoteVars.iState, BP_BIT_BEAST_HINT_CREATED)
ENDPROC
PROC Release_Beast_Peyote_Hint(BeastPeyoteVars &sBeastPeyoteVars)
CPRINTLN(DEBUG_HUNTING, " Releasing beast peyote hint.")
IF DOES_ENTITY_EXIST(sBeastPeyoteVars.vehHint)
REMOVE_DECALS_IN_RANGE(GET_ENTITY_COORDS(sBeastPeyoteVars.vehHint, FALSE), 10.0)
DELETE_VEHICLE(sBeastPeyoteVars.vehHint)
ENDIF
IF DOES_ENTITY_EXIST(sBeastPeyoteVars.pedHint)
REMOVE_DECALS_IN_RANGE(GET_ENTITY_COORDS(sBeastPeyoteVars.pedHint, FALSE), 10.0)
DELETE_PED(sBeastPeyoteVars.pedHint)
ENDIF
CLEAR_BIT(sBeastPeyoteVars.iState, BP_BIT_BEAST_HINT_CREATED)
ENDPROC
PROC Cleanup_Beast_Peyote_Trip(BeastPeyoteVars &sBeastPeyoteVars)
CPRINTLN(DEBUG_HUNTING, " Finished Sasquatch peyote trip.")
IF IS_BIT_SET(sBeastPeyoteVars.iState, BP_BIT_BEAST_HINT_CREATED)
Release_Beast_Peyote_Hint(sBeastPeyoteVars)
ENDIF
IF IS_BIT_SET(sBeastPeyoteVars.iState, BP_BIT_HINT_ASSETS_REQUESTED)
Release_Beast_Peyote_Hint_Assets(sBeastPeyoteVars.iState)
ENDIF
//Stop audio scene
TEXT_LABEL_31 tlMixer = Build_Beast_String_31("til_P_","Exec_U","xer_Scene","B_Mi") //"Exec_Util_P_B_Mixer_Scene"
IF IS_AUDIO_SCENE_ACTIVE(tlMixer)
CPRINTLN(debug_hunting,"Stopping Peyote Beast mixer scene")
STOP_AUDIO_SCENE(tlMixer)
ENDIF
CLEAR_BIT(sBeastPeyoteVars.iState, BP_BIT_PLAYING_AS_SASQUATCH)
CLEAR_BIT(sBeastPeyoteVars.iState, BP_BIT_BEAST_SOUND_PLAYING)
CLEAR_BIT(sBeastPeyoteVars.iState, BP_BIT_BEAST_HINT_PICKED)
ENDPROC
PROC Maintain_Beast_Peyote_Progression(BeastPeyoteVars &sBeastPeyoteVars)
IF NOT IS_BIT_SET(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_PEYOTES_COLLECTED)
IF NOT IS_BIT_SET(sBeastPeyoteVars.iState, BP_BIT_PLAYING_AS_SASQUATCH)
IF IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_ANIMAL)
AND Is_Sasquatch_Model(GET_PLAYER_MODEL())
CPRINTLN(DEBUG_HUNTING, " Detected player has started a Sasquatch peyote trip.")
#IF IS_DEBUG_BUILD
sBeastPeyoteVars.vDebugLastSoundLocation = <<0,0,0>>
#ENDIF
SET_BIT(sBeastPeyoteVars.iState, BP_BIT_PLAYING_AS_SASQUATCH)
INT iDayOfTheWeekLastProgressed = Get_Last_Peyote_Day()
sBeastPeyoteVars.vSfxTargetPosition = Get_Beast_Sfx_Target_Position_For_Day(iDayOfTheWeekLastProgressed)
IF g_iDayOfWeek = iDayOfTheWeekLastProgressed OR g_iDayOfWeek = 0 //Special case for Sunday.
CPRINTLN(DEBUG_HUNTING, " Secret pickup collected on consecutive day of the week.")
#IF IS_DEBUG_BUILD
IF (g_iDayOfWeek != iDayOfTheWeekLastProgressed) AND g_iDayOfWeek = 0
CPRINTLN(DEBUG_HUNTING, "Progression reset but running Sunday hint immediately.")
ENDIF
#ENDIF
Set_Beast_Call_Made(TRUE) //Play the 1st beast sound.
//Activate the audio mixer scene
TEXT_LABEL_31 tlMixer = Build_Beast_String_31("til_P_","Exec_U","xer_Scene","B_Mi") //"Exec_Util_P_B_Mixer_Scene"
START_AUDIO_SCENE(tlMixer)
iDayOfTheWeekLastProgressed = (g_iDayOfWeek + 1) % 8
Set_Last_Peyote_Day(sBeastPeyoteVars, iDayOfTheWeekLastProgressed)
sBeastPeyoteVars.iSoundStartTime = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(BP_MIN_INITIAL_TIME_FOR_SFX, BP_MAX_INITIAL_TIME_FOR_SFX)
SET_BIT(sBeastPeyoteVars.iState, BP_BIT_SFX_ALLOWED)
IF iDayOfTheWeekLastProgressed = 7
CPRINTLN(DEBUG_HUNTING, " Progression completed! Also doing white fade")
SET_BIT(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_PEYOTES_COLLECTED)
Do_White_Fade(255, 0)
ENDIF
ELSE
CPRINTLN(DEBUG_HUNTING, "Secret pickup not collected on consecutive day of the week.")
CPRINTLN(DEBUG_HUNTING, "Current day:", g_iDayOfWeek, " Exepected day:", iDayOfTheWeekLastProgressed , ".")
CPRINTLN(DEBUG_HUNTING, "Progression reset.")
Set_Last_Peyote_Day(sBeastPeyoteVars, 0)
CLEAR_BIT(g_savedGlobals.sFlowCustom.spInitBitset, BP_BIT_SFX_ALLOWED)
ENDIF
ENDIF
ELSE
Update_White_Fade()
IF NOT IS_BIT_SET(sBeastPeyoteVars.iState, BP_BIT_BEAST_HINT_CREATED)
IF NOT IS_BIT_SET(sBeastPeyoteVars.iState, BP_BIT_HINT_ASSETS_REQUESTED)
Request_Beast_Peyote_Hint_Assets(sBeastPeyoteVars.iState)
ELIF Have_Beast_Peyote_Hint_Assets_Loaded()
Create_Beast_Peyote_Hint(sBeastPeyoteVars)
sBeastPeyoteVars.iHintFadeTimer = GET_GAME_TIMER() + 2000
ENDIF
//Don't let the screen fade in while we are spawning the hint.
IF NOT Is_White_Faded_out()
CPRINTLN(DEBUG_HUNTING, "Fading screen out to protect hint spawn.")
Do_White_Fade(255, 0)
ENDIF
ELIF Is_White_Faded_Out()
IF GET_GAME_TIMER() > sBeastPeyoteVars.iHintFadeTimer
CPRINTLN(DEBUG_HUNTING, "Fading screen in after hint timer.")
Do_White_Fade(0, DEFAULT_FADE_TIME)
ENDIF
ENDIF
IF NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_ANIMAL)
OR NOT Is_Sasquatch_Model(GET_PLAYER_MODEL())
Cleanup_Beast_Peyote_Trip(sBeastPeyoteVars)
ENDIF
ENDIF
ENDIF
ENDPROC
PROC Maintain_Play_Beast_Peyote_Sound(BeastPeyoteVars &sBeastPeyoteVars)
IF NOT IS_BIT_SET(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_PEYOTES_COLLECTED)
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
AND Is_Sasquatch_Model(GET_PLAYER_MODEL())
BOOL bSoundActive = FALSE
IF IS_BIT_SET(sBeastPeyoteVars.iState, BP_BIT_PLAYING_AS_SASQUATCH)
AND IS_BIT_SET(sBeastPeyoteVars.iState, BP_BIT_SFX_ALLOWED)
FLOAT fDistanceToSfx = VDIST(GET_ENTITY_COORDS(PLAYER_PED_ID()), sBeastPeyoteVars.vSfxTargetPosition)
IF fDistanceToSfx > BP_MIN_SFX_RANGE
AND fDistanceToSfx < BP_MAX_SFX_RANGE
bSoundActive = TRUE
IF sBeastPeyoteVars.iSoundStartTime = -1
sBeastPeyoteVars.iSoundStartTime = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(BP_MIN_TIME_BETWEEN_SFX, BP_MAX_TIME_BETWEEN_SFX)
CDEBUG1LN(debug_hunting,"Next beast audio in ",sBeastPeyoteVars.iSoundStartTime - GET_GAME_TIMER())
ELSE
//Manage minimum sound time, if player just used a Beast Call
IF Has_Beast_Call_Just_Been_Made()
sBeastPeyoteVars.iSoundStartTime = IMAX(sBeastPeyoteVars.iSoundStartTime, GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(2000,4000))
CDEBUG1LN(debug_hunting,"Beast call - next audio time in ",sBeastPeyoteVars.iSoundStartTime - GET_GAME_TIMER())
ENDIF
IF NOT IS_BIT_SET(sBeastPeyoteVars.iState, BP_BIT_SFX_REQUESTED)
Request_Beast_Peyote_Sfx(sBeastPeyoteVars.iState, sBeastPeyoteVars.tlSfxName)
ELIF NOT IS_BIT_SET(sBeastPeyoteVars.iState, BP_BIT_BEAST_SOUND_PLAYING)
IF REQUEST_SCRIPT_AUDIO_BANK(sBeastPeyoteVars.tlSfxName)
IF GET_GAME_TIMER() > sBeastPeyoteVars.iSoundStartTime
IF Get_Last_Peyote_Day() != 7
AND Has_Beast_Call_Been_Made()
Play_Beast_Sound_From_Position(sBeastPeyoteVars, Calculate_Beast_Sfx_Position_For_Player(sBeastPeyoteVars))
Set_Beast_Call_Made(FALSE)
SET_BIT(sBeastPeyoteVars.iState, BP_BIT_BEAST_SOUND_PLAYING)
ENDIF
ENDIF
ENDIF
ELIF HAS_SOUND_FINISHED(sBeastPeyoteVars.iSoundID)
CLEAR_BIT(sBeastPeyoteVars.iState, BP_BIT_BEAST_SOUND_PLAYING)
RELEASE_SOUND_ID(sBeastPeyoteVars.iSoundID)
sBeastPeyoteVars.iSoundId = -1
sBeastPeyoteVars.iSoundStartTime = -1
ENDIF
ENDIF
ENDIF
ENDIF
IF NOT bSoundActive
IF IS_BIT_SET(sBeastPeyoteVars.iState, BP_BIT_SFX_REQUESTED)
Release_Beast_Peyote_Sfx(sBeastPeyoteVars.iState)
ENDIF
CLEAR_BIT(sBeastPeyoteVars.iState, BP_BIT_BEAST_SOUND_PLAYING)
sBeastPeyoteVars.iSoundStartTime = -1
ENDIF
ENDIF
ENDIF
ENDPROC
#IF IS_DEBUG_BUILD
PROC Create_Beast_Peyote_Widgets(BeastPeyoteVars &sBeastPeyoteVars, WIDGET_GROUP_ID groupID)
CPRINTLN(DEBUG_HUNTING, "Creating beast peyote widgets from ",GET_THIS_SCRIPT_NAME())
IF groupID != NULL
SET_CURRENT_WIDGET_GROUP(groupID)
//Set the global widget group to the main persistent one
g_iBeastWidget = NATIVE_TO_INT(groupID)
CPRINTLN(DEBUG_HUNTING, "Saved Main_persistent widget ID ",g_iBeastWidget)
ENDIF
//Init values.
sBeastPeyoteVars.iDebugLastCollectedDay = Get_Last_Peyote_Day()
sBeastPeyoteVars.iDebugSetCurrentDay = sBeastPeyoteVars.iDebugLastCollectedDay
//WIDGET_GROUP_ID widgetBeastPeyote = START_WIDGET_GROUP("Beast Peyote")
START_WIDGET_GROUP("Beast Peyote")
ADD_WIDGET_BOOL("Terminate thread", sBeastPeyoteVars.bDebugTerminateThread)
ADD_WIDGET_BOOL("Draw sound position", sBeastPeyoteVars.bDebugDrawSoundLocation)
ADD_WIDGET_STRING("")
ADD_WIDGET_STRING("0-Sun 1-Mon 2-Tue 3-Wed 4-Thur 5-Fri 6-Sat")
ADD_WIDGET_INT_READ_ONLY("Next day to collect?", sBeastPeyoteVars.iDebugLastCollectedDay)
ADD_WIDGET_INT_SLIDER("Set next day", sBeastPeyoteVars.iDebugSetCurrentDay, 0, 7, 1)
ADD_WIDGET_STRING("")
ADD_WIDGET_BOOL("Peyotes complete?", sBeastPeyoteVars.bDebugPeyotesComplete)
ADD_WIDGET_BOOL("Toggle peyotes complete", sBeastPeyoteVars.bDebugTogglePeyotesComplete)
STOP_WIDGET_GROUP()
//Create_Decal_Widget(sBeastPeyoteVars.sDebugDecalPlacement, widgetBeastPeyote)
IF groupID != NULL
CLEAR_CURRENT_WIDGET_GROUP(groupID)
ENDIF
ENDPROC
PROC Update_Beast_Peyote_Widgets(BeastPeyoteVars &sBeastPeyoteVars)
//Check if we need to kill the thread.
IF sBeastPeyoteVars.bDebugTerminateThread
CPRINTLN(DEBUG_HUNTING, "Beast peyote thread terminating from widget.")
TERMINATE_THIS_THREAD()
ENDIF
//Turn debug drawing on and off as necessary.
IF sBeastPeyoteVars.bDebugDrawSoundLocation
IF NOT sBeastPeyoteVars.bDebugDrawingEnabled
CPRINTLN(DEBUG_HUNTING, "Beast peyote thread enabled debug drawing.")
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
sBeastPeyoteVars.bDebugDrawingEnabled = TRUE
ENDIF
ELSE
IF sBeastPeyoteVars.bDebugDrawingEnabled
CPRINTLN(DEBUG_HUNTING, "Beast peyote thread disabled debug drawing.")
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(FALSE)
sBeastPeyoteVars.bDebugDrawingEnabled = FALSE
ENDIF
ENDIF
//Draw debug info to visualise where the sound is coming from.
IF sBeastPeyoteVars.bDebugDrawSoundLocation
IF IS_BIT_SET(sBeastPeyoteVars.iState, BP_BIT_PLAYING_AS_SASQUATCH)
IF NOT ARE_VECTORS_EQUAL(sBeastPeyoteVars.vSfxTargetPosition, <<0,0,0>>)
AND NOT ARE_VECTORS_EQUAL(sBeastPeyoteVars.vDebugLastSoundLocation, <<0,0,0>>)
DRAW_DEBUG_SPHERE(sBeastPeyoteVars.vDebugLastSoundLocation, 0.5, 0, 255, 100, 255)
DRAW_DEBUG_SPHERE(sBeastPeyoteVars.vSfxTargetPosition, 0.5, 255, 0, 0, 255)
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
DRAW_DEBUG_LINE(sBeastPeyoteVars.vDebugLastSoundLocation, GET_ENTITY_COORDS(PLAYER_PED_ID()), 0, 255, 100, 255)
DRAW_DEBUG_LINE(sBeastPeyoteVars.vDebugLastSoundLocation,sBeastPeyoteVars.vSfxTargetPosition, 255, 0, 0, 255)
ENDIF
ENDIF
ENDIF
ENDIF
//Read only bool. Set it every frame based on state saved in global bitset.
sBeastPeyoteVars.bDebugPeyotesComplete = IS_BIT_SET(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_PEYOTES_COLLECTED)
IF sBeastPeyoteVars.iDebugSetCurrentDay != Get_Last_Peyote_Day()
Set_Last_Peyote_Day(sBeastPeyoteVars, sBeastPeyoteVars.iDebugSetCurrentDay)
ENDIF
sBeastPeyoteVars.iDebugLastCollectedDay = Get_Last_Peyote_Day()
//Allow toggling of the saved bit.
IF sBeastPeyoteVars.bDebugTogglePeyotesComplete
IF IS_BIT_SET(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_PEYOTES_COLLECTED)
CLEAR_BIT(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_PEYOTES_COLLECTED)
ELSE
SET_BIT(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_PEYOTES_COLLECTED)
ENDIF
sBeastPeyoteVars.bDebugTogglePeyotesComplete = FALSE
ENDIF
//Update_Decal_Widget(sBeastPeyoteVars.sDebugDecalPlacement)
ENDPROC
#ENDIF //DEBUG
#ENDIF //FEATURE_SP_DLC_BEAST_SECRET