From 5b1d3c34c471e6a1884a1adb36d33121f1c71b68 Mon Sep 17 00:00:00 2001 From: gromchek <38837437+gromchek@users.noreply.github.com> Date: Sun, 20 Aug 2023 21:36:51 +0300 Subject: [PATCH] New effect: WASD Cheats (#244) --- .../custom/unsorted/WASDCheatsEffect.cpp | 278 ++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 src/gtasa/effects/custom/unsorted/WASDCheatsEffect.cpp diff --git a/src/gtasa/effects/custom/unsorted/WASDCheatsEffect.cpp b/src/gtasa/effects/custom/unsorted/WASDCheatsEffect.cpp new file mode 100644 index 00000000..5ec7bdc0 --- /dev/null +++ b/src/gtasa/effects/custom/unsorted/WASDCheatsEffect.cpp @@ -0,0 +1,278 @@ +#include "util/EffectBase.h" +#include "util/GenericUtil.h" +#include "util/hooks/HookMacros.h" + +#include +#include +#include +#include +#include + +using namespace plugin; + +namespace +{ +void +adjustPlayerStat (int stat, float value, float min, float max) +{ + float oldValue = CStats::GetStatValue (stat); + oldValue = std::clamp (oldValue + value, min, max); + CStats::SetStatValue (stat, oldValue); + GameUtil::RebuildPlayer (); +} +std::vector> customCheats = { + [] (EffectInstance *inst) + { + auto *player = FindPlayerPed (); + if (!player) return; + + auto *playerInfo = player->GetPlayerInfoForThisPlayerPed (); + + auto value = inst->Random (5.0f, 15.0f); + player->m_fHealth + = std::max (player->m_fHealth + value, player->m_fMaxHealth); + playerInfo->m_nMoney += inst->Random (5, 10) * 1000; + + auto *vehicle = FindPlayerVehicle (-1, false); + if (!vehicle) return; + + float setHealth = std::max (vehicle->m_fHealth + 75.0f, 1250.0f); + vehicle->m_fHealth = setHealth; + }, + [] (EffectInstance *inst) + { adjustPlayerStat (STAT_FAT, 50.0f, 250.0f, 750.0f); }, + [] (EffectInstance *inst) + { adjustPlayerStat (STAT_FAT, -50.0f, 250.0f, 750.0f); }, + [] (EffectInstance *inst) + { adjustPlayerStat (STAT_MUSCLE, 50.0f, 250.0f, 750.0f); }, + [] (EffectInstance *inst) + { adjustPlayerStat (STAT_MUSCLE, -50.0f, 250.0f, 750.0f); }, + [] (EffectInstance *inst) + { + adjustPlayerStat (STAT_FAT, -50.0f, 250.0f, 750.0f); + adjustPlayerStat (STAT_MUSCLE, -50.0f, 250.0f, 750.0f); + }, + [] (EffectInstance *inst) + { adjustPlayerStat (STAT_STAMINA, 50.0f, 250.0f, 750.0f); }, + [] (EffectInstance *inst) + { adjustPlayerStat (STAT_STAMINA, -50.0f, 250.0f, 750.0f); }, + [] (EffectInstance *inst) + { + for (CVehicle *vehicle : CPools::ms_pVehiclePool) + { + if (!vehicle) continue; + + bool cond = vehicle->m_nStatus != STATUS_WRECKED; + cond &= vehicle->m_fHealth > 0.0f; + + if (cond && inst->Random (1, 100000) % 100 == 0) + { + vehicle->m_nPhysicalFlags.bExplosionProof = false; + vehicle->BlowUpCar (nullptr, false); + continue; + } + + if (cond) + { + vehicle->m_fHealth + = std::max (250.0f, vehicle->m_fHealth - 125.0f); + } + + cond &= inst->Random (1, 100000) % 20 == 0; + cond &= vehicle->m_fHealth > 250.0f; + if (cond) + { + vehicle->m_fHealth = 249.0f; + } + } + }, + [] (EffectInstance *inst) + { + auto *player = FindPlayerPed (); + if (!player) return; + + auto *playerInfo = player->GetPlayerInfoForThisPlayerPed (); + auto dmg = inst->Random (5.0f, 15.0f); + player->m_fHealth = std::max (player->m_fHealth - dmg, 0.0f); + }, + [] (EffectInstance *inst) + { + int stats[] = {STAT_PISTOL_SKILL, + STAT_SILENCED_PISTOL_SKILL, + STAT_DESERT_EAGLE_SKILL, + STAT_SHOTGUN_SKILL, + STAT_SAWN_OFF_SHOTGUN_SKILL, + STAT_COMBAT_SHOTGUN_SKILL, + STAT_MACHINE_PISTOL_SKILL, + STAT_SMG_SKILL, + STAT_AK_47_SKILL, + STAT_M4_SKILL}; + for (const auto &stat : stats) + { + adjustPlayerStat (stat, 10.0f, 0.0f, 1000.0f); + } + }, + [] (EffectInstance *inst) + { + int stats[] = {STAT_DRIVING_SKILL, STAT_FLYING_SKILL, + STAT_CYCLING_SKILL, STAT_BIKE_SKILL}; + for (const auto &stat : stats) + { + adjustPlayerStat (stat, 10.0f, 0.0f, 1000.0f); + } + }, + [] (EffectInstance *inst) + { + auto *wanted = FindPlayerWanted (-1); + if (!wanted) return; + + int targetWanted = std::min (wanted->m_nWantedLevel + 1u, 6u); + wanted->CheatWantedLevel (targetWanted); + }, + [] (EffectInstance *inst) + { + auto *wanted = FindPlayerWanted (-1); + if (!wanted) return; + + if (wanted->m_nWantedLevel > 0) + { + wanted->CheatWantedLevel (wanted->m_nWantedLevel - 1); + } + }, + [] (EffectInstance *inst) + { + int weather = inst->Random (0, int (WEATHER_SANDSTORM_DESERT)); + CWeather::ForceWeatherNow (weather); + }, + [] (EffectInstance *inst) + { + auto *player = FindPlayerPed (); + if (!player || player->m_nAreaCode) return; + + int ids[] = {473, 462, 600, 409, 485, 574, 423, 583, 457}; + auto idx = inst->Random (0, int (std::size (ids)) - 1); + + auto position = player->TransformFromObjectSpace ({0.0f, 15.0f, 5.0f}); + GameUtil::CreateVehicle (ids[idx], position, 3.1415926f, true); + }, + [] (EffectInstance *inst) + { + auto *player = FindPlayerPed (); + if (!player) return; + + auto *vehicle = FindPlayerVehicle (-1, false); + + eWeaponType weapons[] = {WEAPON_CHAINSAW, WEAPON_KATANA, WEAPON_SPAS12}; + for (CPed *ped : CPools::ms_pPedPool) + { + if (!ped) continue; + if (ped == player) continue; + + Command ( + ped, 4, ePedType::PED_TYPE_PLAYER1); + auto weapon + = weapons[inst->Random (0, 100000) % std::size (weapons)]; + + int m = CPickups::ModelForWeapon (weapon); + CStreaming::RequestModel (m, 2); + CStreaming::LoadAllRequestedModels (false); + CStreaming::SetModelIsDeletable (m); + + Command (ped, weapon, + 1); + Command (ped, + weapon); + Command (ped, + player); + } + }, + [] (EffectInstance *inst) + { + auto *player = FindPlayerPed (); + if (!player) return; + + auto p = player->GetPosition (); + p.x += inst->Random (-15.0f, 15.0f); + p.y += inst->Random (-15.0f, 15.0f); + int explostionType = 11; + if (inst->Random (1, 100000) % 2 == 0) + { + explostionType = 0; + } + Command (p.x, p.y, p.z, + explostionType); + }}; + +std::string cheatString; +} // namespace + +class WASDCheatsEffect : public EffectBase +{ + int timer = 0; + int CHECK_TIME = 5000; + const int SUBSTR_LEN = 10; + +public: + void + OnStart (EffectInstance *inst) override + { + cheatString.reserve (32); + cheatString.clear (); + + HOOK_ARGS (inst, Hook_AddToCheatString, void (char key), 0x438480); + } + + static void + Hook_AddToCheatString (auto &&cb, char key) + { + cb (); + if (!CCutsceneMgr::ms_running) + { + cheatString.append (1, key); + } + } + + void + OnTick (EffectInstance *inst) override + { + if (!GameUtil::IsPlayerSafe ()) return; + + timer += int (GenericUtil::CalculateTick ()); + + if (timer >= CHECK_TIME) + { + if (isWASDTyped ()) + { + Command ("CHEAT1"); + int cheat = inst->Random (0, 100000) % customCheats.size (); + customCheats[cheat](inst); + } + cheatString.clear (); + timer -= CHECK_TIME; + } + } + + bool + isWASDTyped () const + { + if (cheatString.empty ()) + { + return false; + } + + std::string cheat (cheatString.substr (0, SUBSTR_LEN)); + + for (auto c : cheat) + { + c = std::tolower (c); + if (c != 'w' && c != 'a' && c != 's' && c != 'd') + { + return false; + } + } + + return true; + } +}; + +DEFINE_EFFECT (WASDCheatsEffect, "effect_wasd_cheats", 0);