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