From 4df1d4c72feb6f31654e76d6e3209d9da05e4eca Mon Sep 17 00:00:00 2001 From: OnlyRealNubs <91900600+OnlyRealNubs@users.noreply.github.com> Date: Mon, 13 Mar 2023 21:16:51 -0400 Subject: [PATCH] Added "Fake Fake Death" effect Self explanatory. --- ChaosMod/ChaosMod.vcxproj | 3 +- .../Effects/db/Player/PlayerFakeFakeDeath.cpp | 306 ++++++++++++++++++ ConfigApp/Effects.cs | 1 + 3 files changed, 309 insertions(+), 1 deletion(-) create mode 100644 ChaosMod/Effects/db/Player/PlayerFakeFakeDeath.cpp diff --git a/ChaosMod/ChaosMod.vcxproj b/ChaosMod/ChaosMod.vcxproj index 9b0548902..fc6393b78 100644 --- a/ChaosMod/ChaosMod.vcxproj +++ b/ChaosMod/ChaosMod.vcxproj @@ -153,6 +153,7 @@ + @@ -481,4 +482,4 @@ - + \ No newline at end of file diff --git a/ChaosMod/Effects/db/Player/PlayerFakeFakeDeath.cpp b/ChaosMod/Effects/db/Player/PlayerFakeFakeDeath.cpp new file mode 100644 index 000000000..2902b440d --- /dev/null +++ b/ChaosMod/Effects/db/Player/PlayerFakeFakeDeath.cpp @@ -0,0 +1,306 @@ +/* + Effect by Last0xygen, modified +*/ + +#include + +#include "Components/EffectDispatcher.h" +#include "Memory/Hooks/ScriptThreadRunHook.h" + +static const char *ms_rgTextPairs[] = { "Just kidding, keep playing", + "lol u suck", + "Did you really fall for that?", + "~g~(No you're fine)", + "Did this scare you?", + "~r~FISSION MAILED", + "ded" }; + +enum FakeDeathState +{ + start = 0, + animation, + soundStart, + overlay, + fakeCleanup, + kill +}; + +static int scaleForm = 0; +static int currentMode = FakeDeathState::start; +static int lastModeTime = 0; +static int nextModeTime = 0; +static int soundId = 0; +static bool isOnMission = false; +static const char *deathAnimationName = ""; +static const char *playerDeathName = ""; + +static void OnStart() +{ + bool cancelledDeathAnim = false; + + scaleForm = 0; + currentMode = FakeDeathState::start; + lastModeTime = 0; + nextModeTime = 0; + isOnMission = GET_MISSION_FLAG(); + soundId = GET_SOUND_ID(); + + REQUEST_SCRIPT_AUDIO_BANK("OFFMISSION_WASTED", false, -1); + + Hooks::EnableScriptThreadBlock(); + + while (currentMode < FakeDeathState::kill) + { + WAIT(0); + + if (currentMode > FakeDeathState::animation) + { + HIDE_HUD_AND_RADAR_THIS_FRAME(); + } + + if (scaleForm > 0) + { + DRAW_SCALEFORM_MOVIE_FULLSCREEN(scaleForm, 255, 255, 255, 255, 0); + } + + int current_time = GetTickCount64(); + if (current_time - lastModeTime > nextModeTime) + { + nextModeTime = 999999; + lastModeTime = current_time; + currentMode++; + } + else + { + continue; + } + + Ped playerPed = PLAYER_PED_ID(); + + if (currentMode != FakeDeathState::kill) + { + SET_PLAYER_INVINCIBLE(playerPed, true); + } + + // Eager assumption + std::string fakeEffectId = "player_suicide"; + std::string fakeDeathEffectId = "player_fakedeath"; + switch (currentMode) + { + case FakeDeathState::animation: // Play either the suicide animation or an explosion if in vehicle + if (g_Random.GetRandomInt(0, 1) % 2 == 0) + { + if (!IS_PED_IN_ANY_VEHICLE(playerPed, false)) + { + if (IS_PED_ON_FOOT(playerPed) && GET_PED_PARACHUTE_STATE(playerPed) == -1) + { + // Fake suicide + REQUEST_ANIM_DICT("mp_suicide"); + while (!HAS_ANIM_DICT_LOADED("mp_suicide")) + { + WAIT(0); + } + Hash pistolHash = "WEAPON_PISTOL"_hash; + GIVE_WEAPON_TO_PED(playerPed, pistolHash, 1, true, true); + TASK_PLAY_ANIM(playerPed, "mp_suicide", "pistol", 8.0f, -1.0f, 1150.f, 1, 0.f, false, false, + false); + nextModeTime = 750; + break; + } + } + else if (IS_PED_IN_ANY_VEHICLE(playerPed, false)) + { + // Fake veh explosion + fakeEffectId = "playerveh_explode"; + + Vehicle veh = GET_VEHICLE_PED_IS_IN(playerPed, false); + + int lastTimestamp = GET_GAME_TIMER(); + + int seats = GET_VEHICLE_MODEL_NUMBER_OF_SEATS(GET_ENTITY_MODEL(veh)); + + int detonateTimer = 5000; + int beepTimer = 5000; + while (DOES_ENTITY_EXIST(veh)) + { + WAIT(0); + + int curTimestamp = GET_GAME_TIMER(); + + if ((detonateTimer -= curTimestamp - lastTimestamp) < beepTimer) + { + beepTimer *= .8f; + + PLAY_SOUND_FROM_ENTITY(soundId, "Beep_Red", veh, "DLC_HEIST_HACKING_SNAKE_SOUNDS", true, + false); + } + + if (!IS_PED_IN_VEHICLE(PLAYER_PED_ID(), veh, false)) + { + for (int i = -1; i < seats - 1; i++) + { + Ped ped = GET_PED_IN_VEHICLE_SEAT(veh, i, false); + + if (!ped) + { + continue; + } + + TASK_LEAVE_VEHICLE(ped, veh, 4160); + } + } + + if (detonateTimer <= 0) + { + for (int i = 0; i < 6; i++) + { + SET_VEHICLE_DOOR_BROKEN(veh, i, false); + } + Vector3 vehCoords = GET_ENTITY_COORDS(veh, false); + Vector3 plrCoords = GET_ENTITY_COORDS(playerPed, false); + if (GET_DISTANCE_BETWEEN_COORDS(vehCoords.x, vehCoords.y, vehCoords.z, plrCoords.x, + plrCoords.y, plrCoords.z, true) + < 2.5f) + { + ADD_EXPLOSION(vehCoords.x, vehCoords.y, vehCoords.z, 7, 999, true, false, 1, true); + } + else + { + cancelledDeathAnim = true; + } + + break; + } + + lastTimestamp = curTimestamp; + } + } + } + + // Set the fake name accordingly + GetComponent()->OverrideEffectNameId("player_fakefakedeath", fakeEffectId); + + nextModeTime = 0; + + if (cancelledDeathAnim) + { + nextModeTime = 4000; + currentMode = FakeDeathState::overlay; + } + + break; + case FakeDeathState::soundStart: // Apply Screen Effect + lastModeTime = GetTickCount64(); + nextModeTime = 2000; + switch (GET_ENTITY_MODEL(playerPed)) + { + case 225514697: // Michael + deathAnimationName = "DeathFailMichaelIn"; + playerDeathName = "Micheal Died"; + break; + case 2602752943: // Franklin + deathAnimationName = "DeathFailFranklinIn"; + playerDeathName = "Franklin Died"; + break; + case 2608926626: // Trevor + deathAnimationName = "DeathFailTrevorIn"; + playerDeathName = "Trever Died"; + break; + default: // default + deathAnimationName = "DeathFailNeutralIn"; + playerDeathName = "You Died"; + break; + } + START_AUDIO_SCENE(isOnMission ? "MISSION_FAILED_SCENE" : "DEATH_SCENE"); + ANIMPOSTFX_PLAY(deathAnimationName, 0, false); + + PLAY_SOUND_FRONTEND(soundId, "ScreenFlash", isOnMission ? "MissionFailedSounds" : "WastedSounds", true); + PLAY_SOUND_FRONTEND(soundId, "Bed", "WastedSounds", true); + + SET_TIME_SCALE(0.1f); + SHAKE_GAMEPLAY_CAM("DEATH_FAIL_IN_EFFECT_SHAKE", 1); + break; + case FakeDeathState::overlay: // 2 Seconds later, Show Fake Wasted Screen Message + { + scaleForm = REQUEST_SCALEFORM_MOVIE("MP_BIG_MESSAGE_FREEMODE"); + while (!HAS_SCALEFORM_MOVIE_LOADED(scaleForm)) + { + HIDE_HUD_AND_RADAR_THIS_FRAME(); + WAIT(0); + } + lastModeTime = GetTickCount64(); + nextModeTime = 2000; + ANIMPOSTFX_STOP(deathAnimationName); + ANIMPOSTFX_PLAY("DeathFailOut", 0, false); + BEGIN_SCALEFORM_MOVIE_METHOD(scaleForm, "SHOW_SHARD_WASTED_MP_MESSAGE"); + + SCALEFORM_MOVIE_METHOD_ADD_PARAM_PLAYER_NAME_STRING(isOnMission ? "~r~mission failed" : "~r~wasted"); + int iChosenIndex = g_Random.GetRandomInt(0, sizeof(ms_rgTextPairs) / sizeof(ms_rgTextPairs[0]) - 1); + SCALEFORM_MOVIE_METHOD_ADD_PARAM_PLAYER_NAME_STRING(isOnMission ? playerDeathName + : ms_rgTextPairs[iChosenIndex]); + + END_SCALEFORM_MOVIE_METHOD(); + PLAY_SOUND_FRONTEND(soundId, "TextHit", "WastedSounds", true); + break; + } + case FakeDeathState::fakeCleanup: // Remove all Effects, so you dont have to see this for the rest of the + // duration + { + Vehicle veh = GET_VEHICLE_PED_IS_IN(playerPed, false); + SET_VEHICLE_FIXED(veh); + STOP_ANIM_TASK(playerPed, "mp_suicide", "pistol", 3); + ANIMPOSTFX_STOP("DeathFailOut"); + STOP_AUDIO_SCENE(isOnMission ? "MISSION_FAILED_SCENE" : "DEATH_SCENE"); + SET_TIME_SCALE(1); + STOP_GAMEPLAY_CAM_SHAKING(true); + REMOVE_ANIM_DICT("mp_suicide"); + SET_PLAYER_INVINCIBLE(playerPed, false); + scaleForm = 0; + + GetComponent()->OverrideEffectNameId("player_fakefakedeath", "player_fakedeath"); + + nextModeTime = g_Random.GetRandomInt(2000, 6500); + break; + } + case FakeDeathState::kill: + + if (IS_PED_IN_ANY_VEHICLE(playerPed, false)) + { + SET_ENTITY_HEALTH(playerPed, 0, 0); + } + else + { + if (!IS_PED_IN_ANY_VEHICLE(playerPed, false) && IS_PED_ON_FOOT(playerPed) + && GET_PED_PARACHUTE_STATE(playerPed) == -1) + { + REQUEST_ANIM_DICT("mp_suicide"); + while (!HAS_ANIM_DICT_LOADED("mp_suicide")) + { + WAIT(0); + } + Hash pistolHash = "WEAPON_PISTOL"_hash; + GIVE_WEAPON_TO_PED(playerPed, pistolHash, 9999, true, true); + TASK_PLAY_ANIM(playerPed, "mp_suicide", "pistol", 8.0f, -1.0f, 800.f, 1, 0.f, false, false, false); + WAIT(750); + SET_PED_SHOOTS_AT_COORD(playerPed, 0, 0, 0, true); + REMOVE_ANIM_DICT("mp_suicide"); + } + SET_ENTITY_HEALTH(playerPed, 0, 0); + } + + break; + } + } + + RELEASE_SOUND_ID(soundId); + RELEASE_NAMED_SCRIPT_AUDIO_BANK("OFFMISSION_WASTED"); + Hooks::DisableScriptThreadBlock(); +} + +// clang-format off +REGISTER_EFFECT(OnStart, nullptr, nullptr, EffectInfo + { + .Name = "Fake Fake Death", + .Id = "player_fakedeathx2" + } +); \ No newline at end of file diff --git a/ConfigApp/Effects.cs b/ConfigApp/Effects.cs index 24a16d084..c1c4bb416 100644 --- a/ConfigApp/Effects.cs +++ b/ConfigApp/Effects.cs @@ -399,6 +399,7 @@ public enum EffectTimedType { "peds_not_menendez", new EffectInfo("Not Menendez!", EffectCategory.Peds, true) }, { "misc_go_to_jail", new EffectInfo("Bad Boys", EffectCategory.Misc) }, { "misc_muffled_audio", new EffectInfo("Muffled Audio", EffectCategory.Misc, true) }, + { "player_fakedeathx2", new EffectInfo("Fake Fake Death", EffectCategory.Player) }, }; } }