1152 lines
48 KiB
Scheme
Executable File
1152 lines
48 KiB
Scheme
Executable File
USING "globals.sch"
|
|
USING "rage_builtins.sch"
|
|
USING "net_include.sch"
|
|
USING "ambient_globals.sch"
|
|
USING "commands_player.sch"
|
|
USING "commands_audio.sch"
|
|
USING "script_clock.sch"
|
|
USING "candidate_public.sch"
|
|
USING "beast_secret_shared.sch"
|
|
|
|
#IF FEATURE_SP_DLC_BEAST_SECRET
|
|
|
|
//╒═════════════════════════════════════════════════════════════════════════════╕
|
|
//╞═══════════════════════════ The Beast Finale ════════════════════════╡
|
|
//╘═════════════════════════════════════════════════════════════════════════════╛
|
|
|
|
CONST_INT BF_BIT_REQUESTED_ASSETS 0
|
|
CONST_INT BF_BIT_CREATED_BEAST 1
|
|
CONST_INT BF_BIT_BEAST_WAITING 2
|
|
CONST_INT BF_BIT_BEAST_LEAVING 3
|
|
CONST_INT BF_BIT_BEAST_WINDOW_PASSED 4
|
|
CONST_INT BF_BIT_BEAST_INJURED 5
|
|
CONST_INT BF_BIT_BEAST_FIGHT_ACTIVE 6
|
|
CONST_INT BF_BIT_BEAST_DEAD 7
|
|
CONST_INT BF_BIT_SOUND_PLAYING 8
|
|
CONST_INT BF_BIT_KNOCKED_DOWN 9
|
|
CONST_INT BF_BIT_ALLOWED_TO_RUN_LAST_FRAME 10
|
|
|
|
CONST_FLOAT BF_STREAM_IN_RANGE_SQR 5625.0 //75^2
|
|
CONST_FLOAT BF_STREAM_OUT_RANGE_SQR 6400.0 //80^2
|
|
CONST_FLOAT BF_LEAVE_TIMER_RANGE_SQR 3600.0 //60^2
|
|
CONST_INT BF_VISIBLE_TIME 9000
|
|
CONST_INT BF_BUSH_SLIDE_TIME 400
|
|
CONST_INT BF_STUCK_UNDER_CAR_TIME 500
|
|
|
|
CONST_INT BF_MAX_DEAD_FRAMES 10 //Frames to wait until cancelling fight
|
|
|
|
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
FUNC STRING Get_Beast_Fight_State_String(BeastFightState eBFS)
|
|
SWITCH eBFS
|
|
CASE BFS_Intro RETURN "Intro" BREAK
|
|
CASE BFS_Approach_Player RETURN "Approach player" BREAK
|
|
CASE BFS_Attack_Player RETURN "Attack player" BREAK
|
|
CASE BFS_Let_Player_Get_Up RETURN "Let player get up" BREAK
|
|
CASE BFS_Call_Backup RETURN "Call backup" BREAK
|
|
CASE BFS_Let_Dogs_Attack RETURN "Let dogs attack" BREAK
|
|
CASE BFS_Run_Away RETURN "Running away" BREAK
|
|
CASE BFS_Death RETURN "Death" BREAK
|
|
ENDSWITCH
|
|
RETURN "Unknown"
|
|
ENDFUNC
|
|
|
|
#ENDIF
|
|
|
|
PROC Set_Beast_State(BeastFightState eBFS, INT iStageTimerValue = 0)
|
|
CPRINTLN(debug_hunting, "->Beast switching from state ",Get_Beast_Fight_State_String(sBeastFinaleVars.eBeastFightingState)," to: ",Get_Beast_Fight_State_String(eBFS))
|
|
sBeastFinaleVars.eBeastFightingState = eBFS
|
|
sBeastFinaleVars.iProg = 0
|
|
sBeastFinaleVars.iTimerStage = GET_GAME_TIMER() + iStageTimerValue
|
|
ENDPROC
|
|
|
|
PROC Reset_Beast_Finale_Variables()
|
|
//Unset "ready" flag
|
|
CLEAR_BITMASK(g_iBeastSetupInt, BH_Bit_Fight_Init)
|
|
|
|
sBeastFinaleVars.iState = 0
|
|
sBeastFinaleVars.iSoundID = -1
|
|
sBeastFinaleVars.iTimer = -1
|
|
|
|
//Beast peyote Z set-up
|
|
Set_Beast_Peyote_Vectors_Z()
|
|
|
|
//Beast Hunt X Set-up
|
|
Set_Beast_Hunt_Vectors_X()
|
|
|
|
//Beast fight y set-up
|
|
Set_Beast_Fight_Vectors_y()
|
|
|
|
sBeastFinaleVars.relGroupHashBeast = INT_TO_ENUM(REL_GROUP_HASH, HASH("DLC_SFX1/BEAST"))
|
|
|
|
sBeastFinaleVars.sFightMusic = Build_Beast_String_31("OWE","HALL","SIC","EN_START_MU") //"HALLOWEEN_START_MUSIC"
|
|
sBeastFinaleVars.sFightMusicStop = Build_Beast_String_31("WEEN_F","HALLO","P_MUSIC","AST_STO") //"HALLOWEEN_FAST_STOP_MUSIC"
|
|
|
|
//Taunts for when the player is down.
|
|
sBeastFinaleVars.sTauntAnimDicts[0] = Build_Long_Beast_String_63( "NUCKL", "M@MP_PLA", "NMALE@K",
|
|
"E_CRUNCH", "ANI", "TCELE",
|
|
"BRATIO", "YER_IN") //"ANIM@MP_PLAYER_INTCELEBRATIONMALE@KNUCKLE_CRUNCH"
|
|
sBeastFinaleVars.sTauntAnims[0] = Build_Beast_String_23("UCK", "KN", "UNCH", "LE_CR") //"KNUCKLE_CRUNCH"
|
|
|
|
sBeastFinaleVars.sTauntAnimDicts[1] = Build_Long_Beast_String_63( "ALE@FAC", "IM@MP", "ATIONM",
|
|
"E_PALM", "AN", "ER_INTC",
|
|
"ELEBR", "_PLAY") //"ANIM@MP_PLAYER_INTCELEBRATIONMALE@FACE_PALM"
|
|
sBeastFinaleVars.sTauntAnims[1] = Build_Beast_String_23("CE", "FA", "LM", "_PA") //"FACE_PALM"
|
|
|
|
sBeastFinaleVars.sTauntAnimDicts[2] = Build_Long_Beast_String_63( "B_ON_E", "M@MP_PLA", "E@THUM",
|
|
"ARS", "ANI", "LEBRATI",
|
|
"ONMAL", "YER_INTCE") //"ANIM@MP_PLAYER_INTCELEBRATIONMALE@THUMB_ON_EARS"
|
|
sBeastFinaleVars.sTauntAnims[2] = Build_Beast_String_23("MB_", "THU", "ARS", "ON_E") //"THUMB_ON_EARS"
|
|
|
|
sBeastFinaleVars.sTauntAnimDicts[3] = Build_Beast_String_63("E_STRA", "MOV", "OLL", "FE@R") //"MOVE_STRAFE@ROLL"
|
|
sBeastFinaleVars.sTauntAnims[3] = Build_Beast_String_23("ATRO","COMB","D_P1_180","LL_BW") //"COMBATROLL_BWD_P1_180"
|
|
|
|
sBeastFinaleVars.sTransformAnimDict = Build_Beast_String_31("M@MP_F","ANI","T@INTRO","M_EVEN") //"ANIM@MP_FM_EVENT@INTRO"
|
|
sBeastFinaleVars.sTransformAnim = Build_Beast_String_31("ST_T","BEA","FORM","RANS") //"BEAST_TRANSFORM"
|
|
|
|
sBeastFinaleVars.sBeastSfx = Build_Beast_String_31("C_SF", "DL", "AST", "X1/BE") //"DLC_SFX1/BEAST"
|
|
sBeastFinaleVars.sKneelingAnim = Build_Beast_String_31("DIC@ST","AMB@ME","EEL@IDLE_A","ANDING@KN") //"AMB@MEDIC@STANDING@KNEEL@IDLE_A"
|
|
sBeastFinaleVars.sRelGroup = Build_Beast_String_31("L_GR","RE","AST","OUP_BE")
|
|
|
|
sBeastFinaleVars.sBeastCalls = Build_Beast_String_31("ST_C","BEA","LS","AL") //"BEAST_CALLS"
|
|
sBeastFinaleVars.sFMEvents = Build_Beast_String_31("NTS_S","FM_EVE","TCH_SOUNDS","ASQUA") //"FM_EVENTS_SASQUATCH_SOUNDS")
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC Request_Beast_Finale_Assets()
|
|
INT i
|
|
CPRINTLN(DEBUG_HUNTING, "Requesting beast finale assets.")
|
|
REQUEST_SCRIPT_AUDIO_BANK(sBeastFinaleVars.sBeastSfx) //"DLC_SFX1/BEAST"
|
|
|
|
MODEL_NAMES eBeastModel = Get_Beast_Model()
|
|
MODEL_NAMES eLionModel = Get_Beast_Hint_Model_A(BHT_LION)
|
|
MODEL_NAMES eRottweilerModel = Get_Rottweiler_Model()
|
|
|
|
REQUEST_MODEL(eBeastModel)
|
|
REQUEST_MODEL(eLionModel)
|
|
REQUEST_MODEL(eRottweilerModel)
|
|
|
|
REQUEST_ANIM_DICT(sBeastFinaleVars.sKneelingAnim) //"AMB@MEDIC@STANDING@KNEEL@IDLE_A")
|
|
REQUEST_ANIM_DICT(sBeastFinaleVars.sTransformAnimDict)
|
|
REPEAT BF_NUM_TAUNT_ANIMS i
|
|
REQUEST_ANIM_DICT(sBeastFinaleVars.sTauntAnimDicts[i])
|
|
ENDREPEAT
|
|
|
|
ADD_RELATIONSHIP_GROUP(sBeastFinaleVars.sRelGroup, sBeastFinaleVars.relGroupHashBeast)
|
|
SET_BIT(sBeastFinaleVars.iState, BF_BIT_REQUESTED_ASSETS)
|
|
ENDPROC
|
|
|
|
|
|
FUNC BOOL Have_Beast_Finale_Assets_Loaded()
|
|
INT i
|
|
REPEAT BF_NUM_TAUNT_ANIMS i
|
|
IF NOT HAS_ANIM_DICT_LOADED(sBeastFinaleVars.sTauntAnimDicts[i])
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
MODEL_NAMES eBeastModel = Get_Beast_Model()
|
|
MODEL_NAMES eLionModel = Get_Beast_Hint_Model_A(BHT_LION)
|
|
MODEL_NAMES eRottweilerModel = Get_Rottweiler_Model()
|
|
|
|
IF REQUEST_SCRIPT_AUDIO_BANK(sBeastFinaleVars.sBeastSfx) //"DLC_SFX1/BEAST"
|
|
AND HAS_MODEL_LOADED(eBeastModel)
|
|
AND HAS_MODEL_LOADED(eLionModel)
|
|
AND HAS_MODEL_LOADED(eRottweilerModel)
|
|
AND HAS_ANIM_DICT_LOADED(sBeastFinaleVars.sKneelingAnim) //"AMB@MEDIC@STANDING@KNEEL@IDLE_A")
|
|
AND HAS_ANIM_DICT_LOADED(sBeastFinaleVars.sTransformAnimDict)
|
|
AND DOES_RELATIONSHIP_GROUP_EXIST(sBeastFinaleVars.relGroupHashBeast)
|
|
RETURN TRUE
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
PROC Release_Beast_Finale_Assets()
|
|
INT i
|
|
CPRINTLN(DEBUG_HUNTING, "Releasing beast finale assets.")
|
|
RELEASE_SCRIPT_AUDIO_BANK()
|
|
|
|
MODEL_NAMES eBeastModel = Get_Beast_Model()
|
|
MODEL_NAMES eLionModel = Get_Beast_Hint_Model_A(BHT_LION)
|
|
MODEL_NAMES eRottweilerModel = Get_Rottweiler_Model()
|
|
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(eBeastModel)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(eLionModel)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(eRottweilerModel)
|
|
|
|
REMOVE_ANIM_DICT(sBeastFinaleVars.sKneelingAnim) //"AMB@MEDIC@STANDING@KNEEL@IDLE_A")
|
|
REMOVE_ANIM_DICT(sBeastFinaleVars.sTransformAnimDict)
|
|
REPEAT BF_NUM_TAUNT_ANIMS i
|
|
REMOVE_ANIM_DICT(sBeastFinaleVars.sTauntAnimDicts[i])
|
|
ENDREPEAT
|
|
|
|
REMOVE_RELATIONSHIP_GROUP(sBeastFinaleVars.relGroupHashBeast)
|
|
CLEAR_BIT(sBeastFinaleVars.iState, BF_BIT_REQUESTED_ASSETS)
|
|
ENDPROC
|
|
|
|
|
|
PROC Cleanup_Beast_Fight(BOOL bDeleteBeast = FALSE)
|
|
CPRINTLN(DEBUG_HUNTING, "Cleaning up beast fight.")
|
|
|
|
IF DOES_ENTITY_EXIST(sBeastFinaleVars.pedBeast)
|
|
SET_PED_AS_NO_LONGER_NEEDED(sBeastFinaleVars.pedBeast)
|
|
IF bDeleteBeast
|
|
DELETE_PED(sBeastFinaleVars.pedBeast)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
INT iAnimalIndex
|
|
REPEAT BF_MAX_ANIMALS_TO_SPAWN iAnimalIndex
|
|
IF DOES_ENTITY_EXIST(sBeastFinaleVars.pedAnimals[iAnimalIndex])
|
|
SET_PED_AS_NO_LONGER_NEEDED(sBeastFinaleVars.pedAnimals[iAnimalIndex])
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
//Free up weather.
|
|
TEXT_LABEL_23 tlWeather = Build_Beast_String_23("TR", "EX", "NY", "ASUN") //"EXTRASUNNY"
|
|
SET_WEATHER_TYPE_OVERTIME_PERSIST(tlWeather, 5.0)
|
|
|
|
//Free up clock.
|
|
PAUSE_CLOCK(FALSE)
|
|
|
|
//Stop event music
|
|
CANCEL_MUSIC_EVENT(sBeastFinaleVars.sFightMusic)
|
|
IF IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_BEAST_FIGHT_ACTIVE)
|
|
CPRINTLN(debug_hunting,"Triggering music stop")
|
|
TRIGGER_MUSIC_EVENT(sBeastFinaleVars.sFightMusicStop) // "HALLOWEEN_FAST_STOP_MUSIC")
|
|
ENDIF
|
|
|
|
//Default wanted levels
|
|
SET_MAX_WANTED_LEVEL(sBeastFinaleVars.iStartWantedLevel)
|
|
|
|
Release_Beast_Finale_Assets()
|
|
sBeastFinaleVars.iState = 0
|
|
ENDPROC
|
|
|
|
PROC Fail_Beast_Fight()
|
|
CPRINTLN(debug_hunting, "Beast fight failed, cleaning up")
|
|
Cleanup_Beast_Fight(TRUE)
|
|
|
|
//Set the bits for the failed fight
|
|
CLEAR_BIT(sBeastFinaleVars.iState, BF_BIT_BEAST_FIGHT_ACTIVE)
|
|
CLEAR_BIT(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_HUNT_COMPLETED)
|
|
SET_BIT(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_FIGHT_FAILED)
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC Create_Beast(VECTOR vPosition, FLOAT fHeading, BOOL bForCombat)
|
|
CPRINTLN(DEBUG_HUNTING, "Creating beast.")
|
|
|
|
sBeastFinaleVars.pedBeast = CREATE_PED(PEDTYPE_MISSION, MP_M_FREEMODE_01, vPosition, fHeading, FALSE, FALSE)
|
|
|
|
IF IS_ENTITY_DEAD(sBeastFinaleVars.pedBeast)
|
|
CERRORLN(debug_hunting, "WARNING! Beast ped not alive this frame!")
|
|
EXIT
|
|
ENDIF
|
|
|
|
Set_Male_Beast_Outfit_On_Ped(sBeastFinaleVars.pedBeast )
|
|
|
|
SET_PED_SUFFERS_CRITICAL_HITS(sBeastFinaleVars.pedBeast, FALSE)
|
|
SET_PED_MAX_HEALTH(sBeastFinaleVars.pedBeast, 100000)
|
|
SET_ENTITY_HEALTH(sBeastFinaleVars.pedBeast, 100000)
|
|
SET_PED_MONEY(sBeastFinaleVars.pedBeast, 0)
|
|
DISABLE_PED_PAIN_AUDIO(sBeastFinaleVars.pedBeast, TRUE)
|
|
|
|
IF bForCombat
|
|
SET_PED_RELATIONSHIP_GROUP_HASH(sBeastFinaleVars.pedBeast, sBeastFinaleVars.relGroupHashBeast)
|
|
|
|
//Remove all weapons but the melee
|
|
REMOVE_ALL_PED_WEAPONS(sBeastFinaleVars.pedBeast, FALSE)
|
|
SET_CURRENT_PED_WEAPON(sBeastFinaleVars.pedBeast, WEAPONTYPE_UNARMED, TRUE)
|
|
|
|
//Beast hates the player.
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, RELGROUPHASH_PLAYER, sBeastFinaleVars.relGroupHashBeast)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, sBeastFinaleVars.relGroupHashBeast, RELGROUPHASH_PLAYER)
|
|
|
|
//Ignores the Hillbillies.
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_IGNORE, RELGROUPHASH_AMBIENT_GANG_HILLBILLY, sBeastFinaleVars.relGroupHashBeast)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_IGNORE, sBeastFinaleVars.relGroupHashBeast, RELGROUPHASH_AMBIENT_GANG_HILLBILLY)
|
|
|
|
//Likes the guards dogs.
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, INT_TO_ENUM(REL_GROUP_HASH, HASH("GUARD_DOG")), sBeastFinaleVars.relGroupHashBeast)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, sBeastFinaleVars.relGroupHashBeast, INT_TO_ENUM(REL_GROUP_HASH, HASH("GUARD_DOG")))
|
|
|
|
//Likes cougars.
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, INT_TO_ENUM(REL_GROUP_HASH, HASH("COUGAR")), sBeastFinaleVars.relGroupHashBeast)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, sBeastFinaleVars.relGroupHashBeast, INT_TO_ENUM(REL_GROUP_HASH, HASH("COUGAR")))
|
|
|
|
//Likes wild animals.
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, INT_TO_ENUM(REL_GROUP_HASH, HASH("WILD_ANIMAL")), sBeastFinaleVars.relGroupHashBeast)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, sBeastFinaleVars.relGroupHashBeast, INT_TO_ENUM(REL_GROUP_HASH, HASH("WILD_ANIMAL")))
|
|
|
|
SET_PLAYER_MELEE_WEAPON_DAMAGE_MODIFIER(PLAYER_ID(), 150.0) //Player melee damage against the beast
|
|
|
|
SET_DISABLE_HIGH_FALL_DEATH(sBeastFinaleVars.pedBeast, TRUE)
|
|
SET_COMBAT_FLOAT(sBeastFinaleVars.pedBeast, CCF_FIGHT_PROFICIENCY, 1.0)
|
|
SET_PED_COMBAT_ABILITY(sBeastFinaleVars.pedBeast, CAL_PROFESSIONAL)
|
|
SET_PED_COMBAT_ATTRIBUTES(sBeastFinaleVars.pedBeast, CA_AGGRESSIVE, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(sBeastFinaleVars.pedBeast, CA_ALWAYS_FIGHT, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(sBeastFinaleVars.pedBeast, CA_PERFECT_ACCURACY, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(sBeastFinaleVars.pedBeast, CA_MAINTAIN_MIN_DISTANCE_TO_TARGET, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(sBeastFinaleVars.pedBeast, CA_CAN_FIGHT_ARMED_PEDS_WHEN_NOT_ARMED, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(sBeastFinaleVars.pedBeast, CA_CAN_CHARGE, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(sBeastFinaleVars.pedBeast, CA_CAN_SEE_UNDERWATER_PEDS, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(sBeastFinaleVars.pedBeast, CA_DISABLE_FLEE_FROM_COMBAT, TRUE)
|
|
SET_PED_CONFIG_FLAG(sBeastFinaleVars.pedBeast, PCF_DontActivateRagdollFromFire, TRUE)
|
|
SET_PED_CONFIG_FLAG(sBeastFinaleVars.pedBeast, PCF_DontActivateRagdollFromBulletImpact, TRUE)
|
|
SET_PED_CONFIG_FLAG(sBeastFinaleVars.pedBeast, PCF_DontActivateRagdollFromExplosions, TRUE)
|
|
SET_PED_CONFIG_FLAG(sBeastFinaleVars.pedBeast, PCF_ShouldChargeNow, TRUE)
|
|
SET_PED_CONFIG_FLAG(sBeastFinaleVars.pedBeast, PCF_ShoutToGroupOnPlayerMelee, TRUE)
|
|
SET_PED_CONFIG_FLAG(sBeastFinaleVars.pedBeast, PCF_IgnoreMeleeFistWeaponDamageMult, TRUE)
|
|
SET_PED_CONFIG_FLAG(sBeastFinaleVars.pedBeast, PCF_AllowMeleeReactionIfMeleeProofIsOn, FALSE)
|
|
SET_PED_CONFIG_FLAG(sBeastFinaleVars.pedBeast, PCF_DisableExplosionReactions, TRUE)
|
|
SET_PED_CONFIG_FLAG(sBeastFinaleVars.pedBeast, PCF_RunFromFiresAndExplosions, FALSE)
|
|
SET_ENTITY_PROOFS(sBeastFinaleVars.pedBeast, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sBeastFinaleVars.pedBeast, TRUE)
|
|
ELSE
|
|
SET_ENTITY_PROOFS(sBeastFinaleVars.pedBeast, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE)
|
|
SET_PED_CAN_BE_TARGETTED(sBeastFinaleVars.pedBeast, FALSE)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sBeastFinaleVars.pedBeast, TRUE)
|
|
SET_PED_CAN_RAGDOLL(sBeastFinaleVars.pedBeast, FALSE)
|
|
SET_PED_CONFIG_FLAG(sBeastFinaleVars.pedBeast, PCF_DisableExplosionReactions,TRUE)
|
|
sBeastFinaleVars.iSyncScene = CREATE_SYNCHRONIZED_SCENE(vPosition, << 0.000, 0.000, fHeading >>)
|
|
SET_SYNCHRONIZED_SCENE_LOOPED(sBeastFinaleVars.iSyncScene, TRUE)
|
|
|
|
TEXT_LABEL_23 tlAnim = Build_Beast_String_23("DL", "I", "A", "E_") //"IDLE_A"
|
|
TASK_SYNCHRONIZED_SCENE (sBeastFinaleVars.pedBeast, sBeastFinaleVars.iSyncScene, sBeastFinaleVars.sKneelingAnim, tlAnim, INSTANT_BLEND_IN, INSTANT_BLEND_OUT )
|
|
ENDIF
|
|
|
|
SET_BIT(sBeastFinaleVars.iState, BF_BIT_CREATED_BEAST)
|
|
ENDPROC
|
|
|
|
PROC Play_Beast_Sound_From_Position(VECTOR vPosition)
|
|
CPRINTLN(DEBUG_HUNTING, "Playing beast sound at position ", vPosition, ".")
|
|
sBeastFinaleVars.iSoundID = GET_SOUND_ID()
|
|
PLAY_SOUND_FROM_COORD(sBeastFinaleVars.iSoundId, sBeastFinaleVars.sBeastCalls, vPosition, sBeastFinaleVars.sFMEvents)
|
|
|
|
ENDPROC
|
|
|
|
PROC Destroy_Player_Vehicle()
|
|
VEHICLE_INDEX vehLast = GET_LAST_DRIVEN_VEHICLE()
|
|
sBeastFinaleVars.iState = sBeastFinaleVars.iState //Unreferenced variable fix
|
|
IF DOES_ENTITY_EXIST(vehLast)
|
|
IF NOT IS_ENTITY_DEAD(vehLast)
|
|
MODEL_NAMES mVehicle = GET_ENTITY_MODEL(vehLast)
|
|
CPRINTLN(debug_hunting, "Found last vehicle: ",GET_MODEL_NAME_FOR_DEBUG(mVehicle))
|
|
IF NOT (IS_THIS_MODEL_A_BICYCLE(mVehicle))
|
|
IF IS_ENTITY_AT_COORD(vehLast, g_vBeastFinaleArenaPos, g_vBeastFinaleArenaSize)
|
|
CPRINTLN(debug_hunting, "Last vehicle in range")
|
|
//Destroy vehicle
|
|
SET_ENTITY_HEALTH(vehLast, 0)
|
|
ADD_EXPLOSION(GET_ENTITY_COORDS(vehLast, false),EXP_TAG_STICKYBOMB)
|
|
// SET_VEHICLE_TIMED_EXPLOSION(vehLast, PLAYER_PED_ID(),0)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
//===============Beast fighting section
|
|
CONST_INT HIT_TIME 2500
|
|
CONST_INT MAX_HITS 5
|
|
|
|
PROC Maintain_Player_Hit_Combo(PED_INDEX beast, INT &iTimer, INT &iHitCount, BOOL bCheat = FALSE)
|
|
|
|
//Check if a new hit took place
|
|
IF DOES_ENTITY_EXIST(beast) AND NOT IS_ENTITY_DEAD(beast) AND NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(beast, PLAYER_PED_ID())
|
|
AND HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON(beast, WEAPONTYPE_INVALID, GENERALWEAPON_TYPE_ANYMELEE)
|
|
iHitCount = IMIN(MAX_HITS, iHitCount+1)
|
|
iTimer = GET_GAME_TIMER() + HIT_TIME
|
|
CLEAR_ENTITY_LAST_DAMAGE_ENTITY(beast)
|
|
CLEAR_ENTITY_LAST_WEAPON_DAMAGE(beast)
|
|
|
|
IF bCheat
|
|
SET_ENTITY_HEALTH(beast, 100000) //Reset the beast health if cheating
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
//Check if we need to reduce the hit counter
|
|
IF GET_GAME_TIMER() > iTimer AND iHitCount > 0
|
|
iHitCount--
|
|
iTimer = GET_GAME_TIMER() + HIT_TIME
|
|
ENDIF
|
|
|
|
//Draw combo counter
|
|
#IF IS_DEBUG_BUILD
|
|
IF iHitCount > 0
|
|
TEXT_LABEL_23 msg = "Hits:"
|
|
msg += iHitCount
|
|
msg += " Time:"
|
|
msg += (iTimer - GET_GAME_TIMER())
|
|
Beast_Display_Onscreen_Text(0.5,0.9,msg, 0.3)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC Knock_Player_Weapon()
|
|
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
WEAPON_TYPE currentWeapon
|
|
GET_CURRENT_PED_WEAPON(PLAYER_PED_ID(),currentWeapon,FALSE)
|
|
IF currentWeapon != WEAPONTYPE_UNARMED
|
|
//Remove the weapon
|
|
OBJECT_INDEX weaponObj = GET_WEAPON_OBJECT_FROM_PED(PLAYER_PED_ID(),FALSE)
|
|
weaponObj = weaponObj
|
|
REMOVE_WEAPON_FROM_PED(PLAYER_PED_ID(),currentWeapon)
|
|
SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED,TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
PROC Stun_Player_On_Shout(FLOAT fMaxRange = 3.0, BOOL bCheating = FALSE)
|
|
VECTOR vUpForce = <<0,0,0.5>>
|
|
IF bCheating //Increase stun range if cheating
|
|
fMaxRange = 10
|
|
vUpForce = <<0,0,8>>
|
|
ENDIF
|
|
|
|
IF NOT IS_ENTITY_DEAD(sBeastFinaleVars.pedBeast) AND NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
AND GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sBeastFinaleVars.pedBeast),FALSE) < fMaxRange //Check the max range
|
|
IF NOT IS_PED_RAGDOLL(PLAYER_PED_ID())
|
|
//Set the player to ragdoll
|
|
SET_PED_TO_RAGDOLL(PLAYER_PED_ID(), 2000, 6000, TASK_NM_BALANCE, FALSE)
|
|
Knock_Player_Weapon()
|
|
ENDIF
|
|
|
|
VECTOR vForce = NORMALISE_VECTOR(GET_ENTITY_COORDS(PLAYER_PED_ID()) - GET_ENTITY_COORDS(sBeastFinaleVars.pedBeast)) * (sBeastFinaleVars.fPushForce / 5) //Local multiplier
|
|
CPRINTLN(debug_hunting,"Applying force of power ",vForce)
|
|
APPLY_FORCE_TO_ENTITY(PLAYER_PED_ID(), APPLY_TYPE_IMPULSE, vForce + vUpForce, <<0,0,0.5>>, 0, FALSE, TRUE, TRUE)
|
|
IF (bCheating) //Also drop health if cheating
|
|
SET_ENTITY_HEALTH(PLAYER_PED_ID(), IMAX(GET_ENTITY_HEALTH(PLAYER_PED_ID())/2 - 300, 0))
|
|
ENDIF
|
|
// Beast_Display_Onscreen_Text(0.5, 0.6, "Applying force")
|
|
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
FUNC BOOL Should_Beast_Counter_Hit()
|
|
IF sBeastFinaleVars.iHitCount = MAX_HITS //If we're at max hits
|
|
OR (NOT IS_PED_DEAD_OR_DYING(PLAYER_PED_ID())
|
|
AND IS_PED_ARMED(PLAYER_PED_ID(), WF_INCLUDE_MELEE)) //If we're using a melee weapon
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
PROC Update_Beast()
|
|
//Local vars
|
|
VECTOR vBeastStartLoc = g_vBeastFinaleStartPoint
|
|
VECTOR vJumpOffPlanePoint = g_vBeastFinaleJumpOffPoint
|
|
SCRIPTTASKSTATUS status
|
|
BOOL bCheating = FALSE
|
|
INT i, iNumCars
|
|
VEHICLE_INDEX vehNearCars[10]
|
|
FLOAT fHeading
|
|
SEQUENCE_INDEX si
|
|
#IF IS_DEBUG_BUILD TEXT_LABEL_23 tl #ENDIF
|
|
|
|
IF IS_ENTITY_DEAD(sBeastFinaleVars.pedBeast)
|
|
CERRORLN(debug_hunting, "Can't update beast, entity dead")
|
|
EXIT
|
|
ENDIF
|
|
|
|
// DISPLAY_RADAR(TRUE)
|
|
|
|
//Constant updates
|
|
SET_PED_RESET_FLAG(sBeastFinaleVars.pedBeast, PRF_InfiniteStamina, TRUE)
|
|
SET_PED_RESET_FLAG(sBeastFinaleVars.pedBeast, PRF_PreventAllMeleeTakedowns, TRUE)
|
|
SET_PED_RESET_FLAG(sBeastFinaleVars.pedBeast, PRF_IgnoreCombatManager, TRUE)
|
|
|
|
SET_PED_MOVE_RATE_OVERRIDE(sBeastFinaleVars.pedBeast, 1.75)
|
|
|
|
//Fail check
|
|
IF sBeastFinaleVars.eBeastFightingState != BFS_Run_Away
|
|
AND NOT (IS_ENTITY_DEAD(PLAYER_PED_ID()) OR IS_ENTITY_AT_COORD(PLAYER_PED_ID(), g_vBeastFinaleArenaPos,g_vBeastFinaleArenaSize))
|
|
VECTOR vPos = GET_ENTITY_COORDS(PLAYER_PED_ID(), false)
|
|
CPRINTLN(debug_hunting, "Player at ",vpos," not at ",g_vBeastFinaleArenaPos," / ",g_vBeastFinaleArenaSize)
|
|
Set_Beast_State(BFS_Run_Away)
|
|
ENDIF
|
|
|
|
//Check if player is cheating/modding
|
|
bCheating = Maintain_Beast_Cheating_Check()
|
|
|
|
//Check if beast has just punched the player
|
|
Maintain_Apply_Beast_Punches_To_Ped(PLAYER_PED_ID(), sBeastFinaleVars.pedBeast,DEFAULT,sBeastFinaleVars.fPushForce,
|
|
500+300*sBeastFinaleVars.iHitCount) //Scaling damage with hit count
|
|
Maintain_Player_Hit_Combo(sBeastFinaleVars.pedBeast, sBeastFinaleVars.iTimerHit, sBeastFinaleVars.iHitCount)
|
|
|
|
//Apply constant countering
|
|
IF Should_Beast_Counter_Hit()
|
|
OR bCheating
|
|
//Uncomment this to get the counter working
|
|
SET_PED_RESET_FLAG(sBeastFinaleVars.pedBeast, PRF_ForceMeleeCounter, TRUE)
|
|
CPRINTLN(debug_hunting, "Either max hit combo or player armed with melee, countering")
|
|
ENDIF
|
|
|
|
|
|
//Pinned under car check
|
|
BOOL bUnderCar = FALSE
|
|
IF IS_PED_RAGDOLL(sBeastFinaleVars.pedBeast)
|
|
iNumCars = GET_PED_NEARBY_VEHICLES(sBeastFinaleVars.pedBeast, vehNearCars)
|
|
FOR i = 0 to iNumCars - 1
|
|
IF NOT IS_ENTITY_DEAD(vehNearCars[i])
|
|
IF IS_ENTITY_TOUCHING_ENTITY(sBeastFinaleVars.pedBeast, vehNearCars[i])
|
|
//AND GET_ENTITY_HEIGHT_ABOVE_GROUND(sBeastFinaleVars.pedBeast) < GET_ENTITY_HEIGHT_ABOVE_GROUND(vehNearCars[i])
|
|
//Beast_Display_Onscreen_Text(0.8,0.8, "Under Car", 0.3)
|
|
bUnderCar = TRUE
|
|
IF sBeastFinaleVars.iUnderCarTime + BF_STUCK_UNDER_CAR_TIME < GET_GAME_TIMER()
|
|
//Apply force to car
|
|
VECTOR vForce = NORMALISE_VECTOR(GET_ENTITY_COORDS(vehNearCars[i]) - GET_ENTITY_COORDS(sBeastFinaleVars.pedBeast))
|
|
vForce = vForce * sBeastFinaleVars.fPushForce
|
|
APPLY_FORCE_TO_ENTITY(vehNearCars[i], APPLY_TYPE_IMPULSE, vForce, <<0,0,0>>, 0, FALSE, TRUE, TRUE)
|
|
CPRINTLN(debug_hunting,"Applied force on car!")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
ENDIF
|
|
IF NOT bUnderCar sBeastFinaleVars.iUnderCarTime = GET_GAME_TIMER() ENDIF
|
|
|
|
SWITCH sBeastFinaleVars.eBeastFightingState
|
|
CASE BFS_Intro
|
|
//Check if player looking at beast, trigger anim
|
|
IF sBeastFinaleVars.iProg = 0
|
|
AND IS_SPHERE_VISIBLE(vBeastStartLoc, 1.0)
|
|
AND NOT IS_ENTITY_DEAD(sBeastFinaleVars.pedBeast)
|
|
//Draw attention, activate fight
|
|
SET_GAMEPLAY_ENTITY_HINT(sBeastFinaleVars.pedBeast,<<0,0,0>>,DEFAULT, 1000,1000)
|
|
TASK_PLAY_ANIM(sBeastFinaleVars.pedBeast, sBeastFinaleVars.sTransformAnimDict //"ANIM@MP_FM_EVENT@INTRO"
|
|
,sBeastFinaleVars.sTransformAnim, INSTANT_BLEND_IN, NORMAL_BLEND_OUT,DEFAULT,DEFAULT,0.2) //"BEAST_TRANSFORM"
|
|
IF NOT IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_SOUND_PLAYING)
|
|
Play_Beast_Sound_From_Position(GET_ENTITY_COORDS(sBeastFinaleVars.pedBeast))
|
|
SET_BIT(sBeastFinaleVars.iState, BF_BIT_SOUND_PLAYING)
|
|
ENDIF
|
|
Destroy_Player_Vehicle()
|
|
sBeastFinaleVars.iProg++
|
|
ELIF sBeastFinaleVars.iProg = 1
|
|
//Jump off plane
|
|
IF NOT IS_ENTITY_PLAYING_ANIM(sBeastFinaleVars.pedBeast, sBeastFinaleVars.sTransformAnimDict, sBeastFinaleVars.sTransformAnim)
|
|
OPEN_SEQUENCE_TASK(si)
|
|
TASK_ACHIEVE_HEADING(NULL, GET_HEADING_BETWEEN_VECTORS_2D(g_vBeastFinaleStartPoint, vJumpOffPlanePoint) -20)
|
|
TASK_JUMP(NULL, TRUE, TRUE)
|
|
CLOSE_SEQUENCE_TASK(si)
|
|
TASK_PERFORM_SEQUENCE(sBeastFinaleVars.pedBeast, si)
|
|
CLEAR_SEQUENCE_TASK(si)
|
|
|
|
Set_Beast_State(BFS_Approach_Player)
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE BFS_Approach_Player
|
|
IF GET_SCRIPT_TASK_STATUS(sBeastFinaleVars.pedBeast,SCRIPT_TASK_PERFORM_SEQUENCE) > PERFORMING_TASK
|
|
OR VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sBeastFinaleVars.pedBeast)) < 4 //2x2
|
|
Set_Beast_State(BFS_Attack_Player, GET_RANDOM_INT_IN_RANGE(8,15)*1000)
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE BFS_Attack_Player
|
|
//Check if beast lost the combat ped task
|
|
status = GET_SCRIPT_TASK_STATUS(sBeastFinaleVars.pedBeast, SCRIPT_TASK_COMBAT)
|
|
IF status != PERFORMING_TASK AND status != WAITING_TO_START_TASK
|
|
AND GET_GAME_TIMER() > sBeastFinaleVars.iTimer2 + 500 //Don't constantly re-task
|
|
CPRINTLN(debug_hunting,"Tasking beast to combat player, was ",status)
|
|
CLEAR_PED_TASKS(sBeastFinaleVars.pedBeast)
|
|
TASK_COMBAT_PED(sBeastFinaleVars.pedBeast, PLAYER_PED_ID())
|
|
sBeastFinaleVars.iTimer2 = GET_GAME_TIMER()
|
|
ENDIF
|
|
|
|
//Check if beast should wait for the player to get up
|
|
IF IS_PED_RAGDOLL(PLAYER_PED_ID())
|
|
Knock_Player_Weapon()
|
|
Set_Beast_State(BFS_Let_Player_Get_Up)
|
|
ENDIF
|
|
|
|
//Check if we should call for backup
|
|
IF GET_GAME_TIMER() > sBeastFinaleVars.iTimerStage
|
|
Set_Beast_State(BFS_Call_Backup)
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE BFS_Let_Player_Get_Up
|
|
#IF IS_DEBUG_BUILD
|
|
IF sBeastFinaleVars.bDebugDrawTriggers
|
|
tl = "Get up timer: "
|
|
tl += GET_GAME_TIMER() - sBeastFinaleVars.iTimer2
|
|
Beast_Display_Onscreen_Text(0.4,0.5,tl, 0.3)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
IF sBeastFinaleVars.iProg = 0
|
|
CLEAR_PED_TASKS(sBeastFinaleVars.pedBeast)
|
|
i = GET_RANDOM_INT_IN_RANGE(0,BF_NUM_TAUNT_ANIMS)
|
|
|
|
fHeading = GET_HEADING_BETWEEN_VECTORS_2D(GET_ENTITY_COORDS(sBeastFinaleVars.pedBeast, false), GET_ENTITY_COORDS(PLAYER_PED_ID(), false))
|
|
OPEN_SEQUENCE_TASK(si)
|
|
TASK_ACHIEVE_HEADING(null,fHeading)
|
|
TASK_PLAY_ANIM(null,sBeastFinaleVars.sTauntAnimDicts[i],sBeastFinaleVars.sTauntAnims[i])
|
|
CLOSE_SEQUENCE_TASK(si)
|
|
TASK_PERFORM_SEQUENCE(sBeastFinaleVars.pedBeast, si)
|
|
CLEAR_SEQUENCE_TASK(si)
|
|
|
|
sBeastFinaleVars.iTimer2 = GET_GAME_TIMER() + 4000
|
|
sBeastFinaleVars.iProg++
|
|
ELIF sBeastFinaleVars.iProg = 1
|
|
status = GET_SCRIPT_TASK_STATUS(sBeastFinaleVars.pedBeast, SCRIPT_TASK_PLAY_ANIM)
|
|
IF NOT IS_PED_RAGDOLL(PLAYER_PED_ID())
|
|
AND NOT IS_PED_GETTING_UP(PLAYER_PED_ID())
|
|
CLEAR_PED_TASKS(sBeastFinaleVars.pedBeast)
|
|
Set_Beast_State(BFS_Attack_Player, GET_RANDOM_INT_IN_RANGE(7,15)*1000)
|
|
ELIF GET_GAME_TIMER() > sBeastFinaleVars.iTimer2
|
|
sBeastFinaleVars.iProg = 0
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE BFS_Call_Backup
|
|
IF sBeastFinaleVars.iProg = 0
|
|
//Start the anim, set ped melee-proof
|
|
SET_ENTITY_PROOFS(sBeastFinaleVars.pedBeast, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE)
|
|
TASK_PLAY_ANIM(sBeastFinaleVars.pedBeast, sBeastFinaleVars.sTransformAnimDict, sBeastFinaleVars.sTransformAnim , NORMAL_BLEND_IN, NORMAL_BLEND_OUT,
|
|
DEFAULT,DEFAULT,0.3)
|
|
sBeastFinaleVars.iProg++
|
|
ELIF sBeastFinaleVars.iProg = 1
|
|
SET_PED_RESET_FLAG(sBeastFinaleVars.pedBeast, PRF_DisableMeleeHitReactions, TRUE)
|
|
IF GET_SCRIPT_TASK_STATUS(sBeastFinaleVars.pedBeast,SCRIPT_TASK_PLAY_ANIM) = PERFORMING_TASK
|
|
//Play beast sound when he's actually animating
|
|
IF NOT IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_SOUND_PLAYING)
|
|
Play_Beast_Sound_From_Position(GET_ENTITY_COORDS(sBeastFinaleVars.pedBeast))
|
|
Stun_Player_On_Shout(3, bCheating) //Push player away
|
|
|
|
SET_BIT(sBeastFinaleVars.iState, BF_BIT_SOUND_PLAYING)
|
|
sBeastFinaleVars.iProg++
|
|
ENDIF
|
|
ENDIF
|
|
ELIF sBeastFinaleVars.iProg = 2
|
|
IF GET_SCRIPT_TASK_STATUS(sBeastFinaleVars.pedBeast,SCRIPT_TASK_PLAY_ANIM) > PERFORMING_TASK
|
|
//Reset beast proofs
|
|
SET_ENTITY_PROOFS(sBeastFinaleVars.pedBeast, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE)
|
|
sBeastFinaleVars.iTimer = 0
|
|
Set_Beast_State(BFS_Attack_Player, GET_RANDOM_INT_IN_RANGE(7,15)*1000)
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE BFS_Run_Away
|
|
IF sBeastFinaleVars.iProg = 0
|
|
//Set the beast to run away from the player
|
|
CPRINTLN(debug_hunting,"Player outside of combat arena, running away")
|
|
IF DOES_ENTITY_EXIST(sBeastFinaleVars.pedBeast)
|
|
TASK_SMART_FLEE_PED(sBeastFinaleVars.pedBeast, PLAYER_PED_ID(), 200, -1)
|
|
ENDIF
|
|
sBeastFinaleVars.iProg++
|
|
ELIF sBeastFinaleVars.iProg = 1
|
|
IF IS_ENTITY_OCCLUDED(sBeastFinaleVars.pedBeast)
|
|
CPRINTLN(debug_hunting,"Fleeing beast not visible, deleting ped")
|
|
Fail_Beast_Fight()
|
|
sBeastFinaleVars.iProg++
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
|
|
PROC Update_Beast_Animal_Friends()
|
|
INT iAnimalIndex
|
|
REPEAT BF_MAX_ANIMALS_TO_SPAWN iAnimalIndex
|
|
IF DOES_ENTITY_EXIST(sBeastFinaleVars.pedAnimals[iAnimalIndex])
|
|
IF NOT IS_ENTITY_DEAD(sBeastFinaleVars.pedAnimals[iAnimalIndex])
|
|
SET_PED_RESET_FLAG(sBeastFinaleVars.pedAnimals[iAnimalIndex], PRF_IgnoreCombatManager, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
|
|
PROC Spawn_Beast_Animal_Friend()
|
|
|
|
//Pick model.
|
|
MODEL_NAMES eAnimalModel
|
|
IF GET_RANDOM_INT_IN_RANGE(0,100) < 10 //10% chance of mountain lion
|
|
eAnimalModel = Get_Beast_Hint_Model_A(BHT_LION)
|
|
ELSE
|
|
eAnimalModel = Get_Rottweiler_Model()
|
|
ENDIF
|
|
|
|
//Pick spawn point.
|
|
INT iSpawnPoint = GET_RANDOM_INT_IN_RANGE(0, BF_ANIMAL_SPAWN_POINT_COUNT)
|
|
WHILE NOT WOULD_ENTITY_BE_OCCLUDED(eAnimalModel, g_vBeastFinaleAnimalSpawnVec[iSpawnPoint])
|
|
iSpawnPoint = GET_RANDOM_INT_IN_RANGE(0, BF_ANIMAL_SPAWN_POINT_COUNT)
|
|
ENDWHILE
|
|
|
|
CPRINTLN(DEBUG_HUNTING, "Spawning Beast animal friend. Spawn:", iSpawnPoint, " Model:", PICK_STRING(eAnimalModel = A_C_MTLION, "MTLION", "ROTTWEILER"), ".")
|
|
|
|
INT iAnimalIndex
|
|
REPEAT BF_MAX_ANIMALS_TO_SPAWN iAnimalIndex
|
|
IF NOT DOES_ENTITY_EXIST(sBeastFinaleVars.pedAnimals[iAnimalIndex])
|
|
sBeastFinaleVars.pedAnimals[iAnimalIndex] = CREATE_PED( PEDTYPE_SPECIAL,
|
|
eAnimalModel,
|
|
g_vBeastFinaleAnimalSpawnVec[iSpawnPoint],
|
|
g_vBeastFinaleAnimalSpawnHead[iSpawnPoint],
|
|
FALSE, FALSE)
|
|
SET_PED_RELATIONSHIP_GROUP_HASH(sBeastFinaleVars.pedAnimals[iAnimalIndex], sBeastFinaleVars.relGroupHashBeast)
|
|
SET_COMBAT_FLOAT(sBeastFinaleVars.pedAnimals[iAnimalIndex], CCF_FIGHT_PROFICIENCY, 1.0)
|
|
SET_PED_COMBAT_ABILITY(sBeastFinaleVars.pedAnimals[iAnimalIndex], CAL_PROFESSIONAL)
|
|
SET_PED_COMBAT_ATTRIBUTES(sBeastFinaleVars.pedAnimals[iAnimalIndex], CA_DISABLE_PIN_DOWN_OTHERS, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(sBeastFinaleVars.pedAnimals[iAnimalIndex], CA_AGGRESSIVE, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(sBeastFinaleVars.pedAnimals[iAnimalIndex], CA_ALWAYS_FIGHT, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(sBeastFinaleVars.pedAnimals[iAnimalIndex], CA_PERFECT_ACCURACY, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(sBeastFinaleVars.pedAnimals[iAnimalIndex], CA_MAINTAIN_MIN_DISTANCE_TO_TARGET, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(sBeastFinaleVars.pedAnimals[iAnimalIndex], CA_CAN_FIGHT_ARMED_PEDS_WHEN_NOT_ARMED, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(sBeastFinaleVars.pedAnimals[iAnimalIndex], CA_CAN_CHARGE, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(sBeastFinaleVars.pedAnimals[iAnimalIndex], CA_CAN_SEE_UNDERWATER_PEDS, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(sBeastFinaleVars.pedAnimals[iAnimalIndex], CA_DISABLE_FLEE_FROM_COMBAT, TRUE)
|
|
SET_PED_COMBAT_ATTRIBUTES(sBeastFinaleVars.pedAnimals[iAnimalIndex], CA_DISABLE_SEEK_DUE_TO_LINE_OF_SIGHT, FALSE)
|
|
|
|
OPEN_SEQUENCE_TASK(sBeastFinaleVars.seqAnimalAttack[iAnimalIndex])
|
|
TASK_GO_TO_ENTITY(NULL, PLAYER_PED_ID(), -1, 4.0)
|
|
TASK_COMBAT_PED(NULL, PLAYER_PED_ID())
|
|
CLOSE_SEQUENCE_TASK(sBeastFinaleVars.seqAnimalAttack[iAnimalIndex])
|
|
TASK_PERFORM_SEQUENCE(sBeastFinaleVars.pedAnimals[iAnimalIndex], sBeastFinaleVars.seqAnimalAttack[iAnimalIndex])
|
|
CLEAR_SEQUENCE_TASK(sBeastFinaleVars.seqAnimalAttack[iAnimalIndex])
|
|
EXIT
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC Destroy_Beast()
|
|
CPRINTLN(DEBUG_HUNTING, "Destroying beast.")
|
|
IF DOES_ENTITY_EXIST(sBeastFinaleVars.pedBeast)
|
|
sBeastFinaleVars.iSyncScene = -1
|
|
IF NOT IS_ENTITY_DEAD(sBeastFinaleVars.pedBeast)
|
|
CLEAR_PED_TASKS(sBeastFinaleVars.pedBeast)
|
|
ENDIF
|
|
DELETE_PED(sBeastFinaleVars.pedBeast)
|
|
ENDIF
|
|
CLEAR_BIT(sBeastFinaleVars.iState, BF_BIT_CREATED_BEAST)
|
|
ENDPROC
|
|
|
|
|
|
FUNC BOOL Is_Beast_Fight_Allowed_To_Run()
|
|
RETURN IS_BIT_SET(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_HUNT_COMPLETED)
|
|
AND NOT IS_BIT_SET(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_FIGHT_FAILED)
|
|
AND NOT IS_BIT_SET(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_KILLED_AND_UNLOCKED)
|
|
AND GET_PLAYER_MODEL() = Get_Sasquatch_Model()
|
|
AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) //No Director Mode fight
|
|
|
|
ENDFUNC
|
|
|
|
|
|
PROC Maintain_Beast_Hidden_Trigger()
|
|
|
|
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
//Player inside streaming range.
|
|
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), g_vBeastFinaleRootPosition) < BF_STREAM_IN_RANGE_SQR
|
|
|
|
IF NOT IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_REQUESTED_ASSETS)
|
|
Request_Beast_Finale_Assets()
|
|
ELIF NOT IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_CREATED_BEAST)
|
|
IF Have_Beast_Finale_Assets_Loaded()
|
|
Create_Beast(g_vBeastFinaleRootPosition - <<0.1, -0.1, -1>>, -20.400, FALSE)
|
|
|
|
//Preload fight music.
|
|
PREPARE_MUSIC_EVENT(sBeastFinaleVars.sFightMusic)
|
|
ENDIF
|
|
|
|
//Beast created in world.
|
|
ELSE
|
|
//Apply beast per-frame flags
|
|
IF DOES_ENTITY_EXIST(sBeastFinaleVars.pedBeast)
|
|
IF NOT IS_ENTITY_DEAD(sBeastFinaleVars.pedBeast)
|
|
SET_PED_RESET_FLAG(sBeastFinaleVars.pedBeast, PRF_DisablePotentialBlastReactions, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
//Make the beast leave if the player gets too close.
|
|
IF NOT IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_BEAST_WAITING)
|
|
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), g_vBeastFinaleRootPosition) < BF_LEAVE_TIMER_RANGE_SQR
|
|
CPRINTLN(DEBUG_HUNTING, "Player triggered wait timer.")
|
|
sBeastFinaleVars.iTimer = GET_GAME_TIMER() + BF_VISIBLE_TIME
|
|
SET_BIT(sBeastFinaleVars.iState, BF_BIT_BEAST_WAITING)
|
|
ENDIF
|
|
ELSE
|
|
IF NOT IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_BEAST_LEAVING)
|
|
IF GET_GAME_TIMER() > sBeastFinaleVars.iTimer
|
|
OR IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_BEAST_INJURED)
|
|
CPRINTLN(DEBUG_HUNTING, "Beast started leaving.")
|
|
|
|
IF IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_BEAST_INJURED)
|
|
Play_Beast_Sound_From_Position( GET_ENTITY_COORDS(sBeastFinaleVars.pedBeast, FALSE))
|
|
SET_BIT(sBeastFinaleVars.iState, BF_BIT_SOUND_PLAYING)
|
|
ENDIF
|
|
|
|
sBeastFinaleVars.iTimer = GET_GAME_TIMER() + BF_BUSH_SLIDE_TIME
|
|
SET_BIT(sBeastFinaleVars.iState, BF_BIT_BEAST_LEAVING)
|
|
ENDIF
|
|
ELSE
|
|
IF sBeastFinaleVars.iSyncScene != -1
|
|
TASK_PLAY_ANIM(sBeastFinaleVars.pedBeast, sBeastFinaleVars.sTauntAnimDicts[3], sBeastFinaleVars.sTauntAnims[3],
|
|
INSTANT_BLEND_IN,INSTANT_BLEND_OUT,-1, AF_DEFAULT,0.2)
|
|
|
|
sBeastFinaleVars.iSyncScene = -1
|
|
ENDIF
|
|
|
|
IF GET_GAME_TIMER() > sBeastFinaleVars.iTimer
|
|
CPRINTLN(DEBUG_HUNTING, "Beast sliding into the bush.")
|
|
Destroy_Beast()
|
|
//Release_Beast_Finale_Assets(iState)
|
|
SET_BIT(sBeastFinaleVars.iState, BF_BIT_BEAST_WINDOW_PASSED)
|
|
IF IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_BEAST_INJURED)
|
|
CPRINTLN(DEBUG_HUNTING, "The player injured the beast. Waiting for player to investigate...")
|
|
|
|
//Set up some ambience: Weather, time-of-day, music.
|
|
TEXT_LABEL_23 tlWeather = Build_Beast_String_23("HUN", "T", "R", "DE") //"THUNDER"
|
|
SET_WEATHER_TYPE_OVERTIME_PERSIST(tlWeather, 15.0)
|
|
PAUSE_CLOCK(TRUE)
|
|
TRIGGER_MUSIC_EVENT(sBeastFinaleVars.sFightMusic)
|
|
|
|
SET_BIT(sBeastFinaleVars.iState, BF_BIT_BEAST_FIGHT_ACTIVE)
|
|
|
|
//Disable wanted levels and active police
|
|
CLEAR_PLAYER_WANTED_LEVEL(PLAYER_ID())
|
|
sBeastFinaleVars.iStartWantedLevel = GET_MAX_WANTED_LEVEL()
|
|
SET_MAX_WANTED_LEVEL(0)
|
|
ELSE
|
|
CPRINTLN(DEBUG_HUNTING, "The player missed the beast. Event over.")
|
|
Fail_Beast_Fight()
|
|
ENDIF
|
|
EXIT
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
//Pass the event if the player injures the beast.
|
|
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
AND NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(sBeastFinaleVars.pedBeast, PLAYER_PED_ID())
|
|
OR IS_EXPLOSION_IN_SPHERE(EXP_TAG_DONTCARE,g_vBeastFinaleRootPosition, 5)
|
|
OR VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), g_vBeastFinaleRootPosition) < 25 //5*5
|
|
CPRINTLN(DEBUG_HUNTING, "Beast damage/proximity detected.")
|
|
SET_BIT(sBeastFinaleVars.iState, BF_BIT_BEAST_INJURED)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
//Player outside streaming range.
|
|
ELIF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), g_vBeastFinaleRootPosition) > BF_STREAM_OUT_RANGE_SQR
|
|
IF IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_CREATED_BEAST)
|
|
Destroy_Beast()
|
|
ENDIF
|
|
IF IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_REQUESTED_ASSETS)
|
|
Release_Beast_Finale_Assets()
|
|
ENDIF
|
|
CLEAR_BIT(sBeastFinaleVars.iState, BF_BIT_BEAST_LEAVING)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC Update_Beast_Fight_Time()
|
|
IF GET_TIMEOFDAY_HOUR(g_todCurrent) != 4 //Force fight to take place around 4:45am
|
|
OR GET_TIMEOFDAY_MINUTE(g_todCurrent) < 40
|
|
OR GET_TIMEOFDAY_MINUTE(g_todCurrent) > 50
|
|
TIMEOFDAY todFight = g_todCurrent
|
|
ADD_TIME_TO_TIMEOFDAY(todFight, 0, 2) //Fast forward time by 1 min per frame.
|
|
SET_CLOCK_TIME(GET_TIMEOFDAY_HOUR(todFight), GET_TIMEOFDAY_MINUTE(todFight), GET_TIMEOFDAY_SECOND(todFight))
|
|
SET_CLOCK_DATE(GET_TIMEOFDAY_DAY(todFight), GET_TIMEOFDAY_MONTH(todFight), GET_TIMEOFDAY_YEAR(todFight))
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
PROC Maintain_Beast_Fight()
|
|
|
|
Update_Beast_Fight_Time()
|
|
|
|
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
sBeastFinaleVars.iDeadFrames = 0
|
|
//Wait for player to go and check The Beast's coords.
|
|
IF NOT IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_CREATED_BEAST)
|
|
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), g_vBeastFinaleCheckPos,<<3.00000,3.00000,2.000000>>)
|
|
AND IS_SPHERE_VISIBLE(g_vBeastFinaleRootPosition - <<0.3, 1, -1>>,0.5)
|
|
CPRINTLN(DEBUG_HUNTING, "Player went to investigate. Spwaning beast fight.")
|
|
Create_Beast(g_vBeastFinaleStartPoint, -155, TRUE)
|
|
Set_Beast_State(BFS_Intro)
|
|
SET_BIT(sBeastFinaleVars.iState, BF_BIT_SOUND_PLAYING)
|
|
sBeastFinaleVars.iTimer = -1//GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(4000, 20000) //No longer spawns companion by default
|
|
SET_BIT(sBeastFinaleVars.iState, BF_BIT_CREATED_BEAST)
|
|
ENDIF
|
|
|
|
//Check if player buggered off after damagint the beast
|
|
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), g_vBeastFinaleRootPosition) > BF_STREAM_OUT_RANGE_SQR
|
|
CPRINTLN(debug_hunting,"Player left area after hurting beast, cancelling")
|
|
Cleanup_Beast_Fight()
|
|
ENDIF
|
|
//Fight running.
|
|
ELIF NOT IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_BEAST_DEAD)
|
|
Update_Beast()
|
|
Update_Beast_Animal_Friends()
|
|
|
|
IF GET_GAME_TIMER() > sBeastFinaleVars.iTimer
|
|
AND sBeastFinaleVars.iTimer > -1
|
|
Spawn_Beast_Animal_Friend()
|
|
sBeastFinaleVars.iTimer = -1 // GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(8000, 15000)
|
|
ENDIF
|
|
|
|
IF DOES_ENTITY_EXIST(sBeastFinaleVars.pedBeast)
|
|
IF IS_ENTITY_DEAD(sBeastFinaleVars.pedBeast)
|
|
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
CPRINTLN(DEBUG_HUNTING, "The beast was killed. Starting transition out.")
|
|
sBeastFinaleVars.iTimer = GET_GAME_TIMER() + 2000
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
|
|
TASK_PLAY_ANIM(PLAYER_PED_ID(), sBeastFinaleVars.sTransformAnimDict //"ANIM@MP_FM_EVENT@INTRO"
|
|
,sBeastFinaleVars.sTransformAnim, NORMAL_BLEND_IN, NORMAL_BLEND_OUT)
|
|
SET_BIT(sBeastFinaleVars.iState, BF_BIT_BEAST_DEAD)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF GET_GAME_TIMER() > sBeastFinaleVars.iTimer
|
|
SET_BIT(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_KILLED_AND_UNLOCKED)
|
|
|
|
//Display an unlock message that hints the player towards the Director Mode "WildBeast" character.
|
|
CPRINTLN(DEBUG_HUNTING, "Event complete! Display beast unlocked feed message.")
|
|
TEXT_LABEL_23 tlFeedImage = Build_Beast_String_23("R_A", "CHA", "G_UP", "CTIN") //"CHAR_ACTING_UP"
|
|
TEXT_LABEL_23 tlFeedCharName = Build_Beast_String_23("_FEE", "DI", "AR", "D_CH") //"DI_FEED_CHAR"
|
|
TEXT_LABEL_23 tlFeedSubtitle = Build_Beast_String_23("AIR_G", "H", "0", "ROUP_E") //"HAIR_GROUP_E0"
|
|
BEGIN_TEXT_COMMAND_THEFEED_POST("")
|
|
END_TEXT_COMMAND_THEFEED_POST_MESSAGETEXT_SUBTITLE_LABEL(tlFeedImage, tlFeedImage, FALSE, TEXT_ICON_BLANK, tlFeedCharName, tlFeedSubtitle)
|
|
|
|
//Hack, tell scripts that the player has died to force the peyote trip to end.
|
|
g_bAnimalControllerFakeDeath = TRUE
|
|
|
|
Cleanup_Beast_Fight()
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
//Dead time buffer: Make sure player dead for a few frames before cancelling the fight
|
|
sBeastFinaleVars.iDeadFrames += 1
|
|
IF sBeastFinaleVars.iDeadFrames > BF_MAX_DEAD_FRAMES
|
|
CPRINTLN(debug_hunting, "Player killed, beast fight failed!")
|
|
Fail_Beast_Fight()
|
|
EXIT
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
PROC Maintain_Beast_Sound()
|
|
IF IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_SOUND_PLAYING)
|
|
IF HAS_SOUND_FINISHED(sBeastFinaleVars.iSoundID)
|
|
STOP_SOUND(sBeastFinaleVars.iSoundID)
|
|
RELEASE_SOUND_ID(sBeastFinaleVars.iSoundID)
|
|
sBeastFinaleVars.iSoundID = -1
|
|
CLEAR_BIT(sBeastFinaleVars.iState, BF_BIT_SOUND_PLAYING)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
PROC Maintain_Beast_Finale()
|
|
IF Has_Beast_Secret_Data_Setup_Finished()
|
|
IF NOT IS_BITMASK_SET(g_iBeastSetupInt,BH_Bit_Fight_Init)
|
|
CPRINTLN(debug_hunting,"Fight data init now set-up, running the Beast Fight scripts")
|
|
SET_BITMASK(g_iBeastSetupInt,BH_Bit_Fight_Init)
|
|
ENDIF
|
|
ELSE
|
|
EXIT //Don't do anything until data setup finishes
|
|
ENDIF
|
|
|
|
IF Is_Beast_Fight_Allowed_To_Run()
|
|
IF NOT IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_ALLOWED_TO_RUN_LAST_FRAME)
|
|
CPRINTLN(debug_hunting, "Beast Fight finale now allowed to run")
|
|
SET_BIT(sBeastFinaleVars.iState, BF_BIT_ALLOWED_TO_RUN_LAST_FRAME)
|
|
ENDIF
|
|
|
|
IF NOT IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_BEAST_WINDOW_PASSED)
|
|
Maintain_Beast_Hidden_Trigger()
|
|
ELIF IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_BEAST_FIGHT_ACTIVE)
|
|
Maintain_Beast_Fight()
|
|
ENDIF
|
|
|
|
//Manage ending the sound if it is playing.
|
|
Maintain_Beast_Sound()
|
|
|
|
//Don't let the player record any of this.
|
|
REPLAY_PREVENT_RECORDING_AND_UI_THIS_FRAME()
|
|
|
|
ELSE
|
|
IF IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_ALLOWED_TO_RUN_LAST_FRAME)
|
|
|
|
CPRINTLN(debug_hunting, "Fight not allowed now, bits: HUNT_COMPLETED:",
|
|
IS_BIT_SET(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_HUNT_COMPLETED),
|
|
" FIGHT_FAILED: ",IS_BIT_SET(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_FIGHT_FAILED),
|
|
" KILLED_AND_UNLOCKED:", IS_BIT_SET(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_KILLED_AND_UNLOCKED))
|
|
|
|
//Fail the fight if the beast not defeated
|
|
IF NOT IS_BIT_SET(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_KILLED_AND_UNLOCKED)
|
|
Fail_Beast_Fight()
|
|
ENDIF
|
|
|
|
CLEAR_BIT(sBeastFinaleVars.iState, BF_BIT_ALLOWED_TO_RUN_LAST_FRAME)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
PROC Create_Beast_Finale_Widgets(WIDGET_GROUP_ID widgetID)
|
|
CPRINTLN(DEBUG_HUNTING, "Creating beast finale widgets from ",GET_THIS_SCRIPT_NAME())
|
|
|
|
IF widgetID != NULL
|
|
SET_CURRENT_WIDGET_GROUP(widgetID)
|
|
ENDIF
|
|
|
|
START_WIDGET_GROUP("Beast Finale")
|
|
ADD_WIDGET_BOOL("Warp to location", sBeastFinaleVars.bDebugWarpToLocation)
|
|
ADD_WIDGET_BOOL("Set fight ready to trigger", sBeastFinaleVars.bDebugCompleteHunt)
|
|
ADD_WIDGET_BOOL("Set Beast low health", sBeastFinaleVars.bDebugSetBeastLowHealth)
|
|
ADD_WIDGET_BOOL("Terminate thread", sBeastFinaleVars.bDebugTerminateThread)
|
|
ADD_WIDGET_BOOL("Draw triggers", sBeastFinaleVars.bDebugDrawTriggers)
|
|
ADD_WIDGET_BOOL("Start fight", sBeastFinaleVars.bDebugBeastDamaged)
|
|
ADD_WIDGET_BOOL("Draw animal spawns", sBeastFinaleVars.bDebugDrawAnimalSpawns)
|
|
ADD_WIDGET_BOOL("Toggle beast killed", sBeastFinaleVars.bDebugToggleBeastKilled)
|
|
ADD_WIDGET_BOOL("Beast killed and unlocked", sBeastFinaleVars.bDebugBeastKilledAndUnlocked)
|
|
ADD_WIDGET_FLOAT_SLIDER("Push force", sBeastFinaleVars.fPushForce,1,200,0.5)
|
|
STOP_WIDGET_GROUP()
|
|
|
|
IF widgetID != NULL
|
|
CLEAR_CURRENT_WIDGET_GROUP(widgetID)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
PROC Update_Beast_Finale_Widgets(BOOL bAllowTerminate = TRUE)
|
|
|
|
IF sBeastFinaleVars.bDebugTerminateThread
|
|
OR IS_DEBUG_KEY_JUST_PRESSED(KEY_F, KEYBOARD_MODIFIER_CTRL_SHIFT, "Terminate thread") //Also use F to kill
|
|
CPRINTLN(DEBUG_HUNTING, "Beast finale thread terminating from widget.")
|
|
IF IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_CREATED_BEAST)
|
|
Destroy_Beast()
|
|
Cleanup_Beast_Fight()
|
|
ENDIF
|
|
IF IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_REQUESTED_ASSETS)
|
|
Release_Beast_Finale_Assets()
|
|
ENDIF
|
|
CLEAR_BIT(sBeastFinaleVars.iState, BF_BIT_BEAST_LEAVING)
|
|
IF bAllowTerminate
|
|
TERMINATE_THIS_THREAD()
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF sBeastFinaleVars.bDebugWarpToLocation
|
|
IF IS_PLAYER_PLAYING(PLAYER_ID())
|
|
AND NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
CPRINTLN(DEBUG_HUNTING, "Starting warp to beast finale location from widget...")
|
|
SET_ENTITY_COORDS(PLAYER_PED_ID(), g_vBeastFinaleCheckPos - <<1, -82, 0>>, FALSE)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(),176.0174)
|
|
// WHILE IS_PLAYER_TELEPORT_ACTIVE()
|
|
// WAIT(0)
|
|
// ENDWHILE
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
CPRINTLN(DEBUG_HUNTING, "Warp finished.")
|
|
ENDIF
|
|
sBeastFinaleVars.bDebugWarpToLocation = FALSE
|
|
ENDIF
|
|
|
|
IF sBeastFinaleVars.bDebugSetBeastLowHealth
|
|
IF DOES_ENTITY_EXIST(sBeastFinaleVars.pedBeast)
|
|
AND NOT IS_ENTITY_DEAD(sBeastFinaleVars.pedBeast)
|
|
SET_ENTITY_HEALTH(sBeastFinaleVars.pedBeast, 200)
|
|
ENDIF
|
|
sBeastFinaleVars.bDebugSetBeastLowHealth = FALSE
|
|
ENDIF
|
|
|
|
IF sBeastFinaleVars.bDebugCompleteHunt
|
|
sBeastFinaleVars.bDebugCompleteHunt = FALSE
|
|
SET_BIT(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_HUNT_COMPLETED)
|
|
CLEAR_BIT(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_FIGHT_FAILED)
|
|
CLEAR_BIT(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_KILLED_AND_UNLOCKED)
|
|
ENDIF
|
|
|
|
IF sBeastFinaleVars.bDebugBeastDamaged
|
|
sBeastFinaleVars.bDebugBeastDamaged = FALSE
|
|
SET_BIT(sBeastFinaleVars.iState, BF_BIT_BEAST_WINDOW_PASSED)
|
|
SET_BIT(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_HUNT_COMPLETED)
|
|
SET_BIT(sBeastFinaleVars.iState, BF_BIT_BEAST_INJURED)
|
|
SET_BIT(sBeastFinaleVars.iState, BF_BIT_BEAST_FIGHT_ACTIVE)
|
|
CLEAR_BIT(sBeastFinaleVars.iState, BF_BIT_CREATED_BEAST)
|
|
SET_ENTITY_COORDS(PLAYER_PED_ID(),g_vBeastFinaleCheckPos, FALSE)
|
|
ENDIF
|
|
|
|
IF sBeastFinaleVars.bDebugDrawTriggers
|
|
OR sBeastFinaleVars.bDebugDrawAnimalSpawns
|
|
IF NOT sBeastFinaleVars.bDebugDrawingEnabled
|
|
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
|
|
sBeastFinaleVars.bDebugDrawingEnabled = TRUE
|
|
ENDIF
|
|
ELSE
|
|
IF sBeastFinaleVars.bDebugDrawingEnabled
|
|
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(FALSE)
|
|
sBeastFinaleVars.bDebugDrawingEnabled = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF sBeastFinaleVars.bDebugDrawTriggers
|
|
IF IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_CREATED_BEAST)
|
|
DRAW_DEBUG_SPHERE(g_vBeastFinaleRootPosition, SQRT(BF_LEAVE_TIMER_RANGE_SQR), 0, 0, 255, 60)
|
|
ENDIF
|
|
|
|
IF IS_BIT_SET(sBeastFinaleVars.iState, BF_BIT_REQUESTED_ASSETS)
|
|
DRAW_DEBUG_SPHERE(g_vBeastFinaleRootPosition, SQRT(BF_STREAM_OUT_RANGE_SQR), 255, 0, 0, 60)
|
|
ELSE
|
|
DRAW_DEBUG_SPHERE(g_vBeastFinaleRootPosition, SQRT(BF_STREAM_IN_RANGE_SQR), 0, 255, 0, 60)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF sBeastFinaleVars.bDebugDrawAnimalSpawns
|
|
INT iSpawnIndex
|
|
TEXT_LABEL tlSpawnName
|
|
REPEAT BF_ANIMAL_SPAWN_POINT_COUNT iSpawnIndex
|
|
tlSpawnName = "Spawn "
|
|
tlSpawnName += iSpawnIndex
|
|
DRAW_DEBUG_TEXT(tlSpawnName, g_vBeastFinaleAnimalSpawnVec[iSpawnIndex], 0, 0, 255)
|
|
DRAW_DEBUG_SPHERE(g_vBeastFinaleAnimalSpawnVec[iSpawnIndex], 1.0, 0, 255, 0, 60)
|
|
ENDREPEAT
|
|
ENDIF
|
|
|
|
IF sBeastFinaleVars.bDebugToggleBeastKilled
|
|
IF IS_BIT_SET(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_KILLED_AND_UNLOCKED)
|
|
CPRINTLN(DEBUG_HUNTING, "Clearing beast as killed through widget.")
|
|
CLEAR_BIT(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_KILLED_AND_UNLOCKED)
|
|
ELSE
|
|
CPRINTLN(DEBUG_HUNTING, "Setting beast as killed through widget.")
|
|
SET_BIT(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_KILLED_AND_UNLOCKED)
|
|
ENDIF
|
|
sBeastFinaleVars.bDebugToggleBeastKilled = FALSE
|
|
ENDIF
|
|
|
|
sBeastFinaleVars.bDebugBeastKilledAndUnlocked = IS_BIT_SET(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_BEAST_KILLED_AND_UNLOCKED)
|
|
ENDPROC
|
|
|
|
#ENDIF //DEBUG
|
|
#ENDIF //FEATURE_SP_DLC_BEAST_SECRET
|