Skip to content

Commit

Permalink
feat: New Hobo Manager
Browse files Browse the repository at this point in the history
  • Loading branch information
AthallahDzaki committed Aug 22, 2024
1 parent 3e8feb2 commit b238a83
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 18 deletions.
1 change: 1 addition & 0 deletions src/TrilogyChaosMod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class TrilogyChaosMod
public:
TrilogyChaosMod ()
{

UnProtectInstance ();

Config::Init ();
Expand Down
59 changes: 59 additions & 0 deletions src/gtasa/effects/custom/ped/RemoveAngryHoboEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,38 @@ class RemoveAngryHobo : public OneTimeEffect
return HoboManager::angryHobo.size () > 0;
}

CVector
FindSuitableTeleportPosition (EffectInstance *inst)
{
CVector randomPosition
= CVector (inst->Random (-3000.0f, 3000.0f),
inst->Random (-3000.0f, 3000.0f), 0.0f);

Command<eScriptCommands::COMMAND_REQUEST_COLLISION> (randomPosition.x,
randomPosition.y);
CStreaming::StreamZoneModels (&randomPosition);
CStreaming::LoadAllRequestedModels (false);
CStreaming::LoadScene (&randomPosition);

bool groundResult = false;
randomPosition.z
= CWorld::FindGroundZFor3DCoord (randomPosition.x, randomPosition.y,
randomPosition.z + 250.0f,
&groundResult, 0)
+ 3.0f;

if (!groundResult) return FindSuitableTeleportPosition (inst);

float waterLevel = 0.0f;
Command<eScriptCommands::COMMAND_GET_WATER_HEIGHT_AT_COORDS> (
randomPosition.x, randomPosition.y, false, &waterLevel);

if (randomPosition.z <= waterLevel)
return FindSuitableTeleportPosition (inst);

return randomPosition;
}

void
OnStart (EffectInstance *inst) override
{
Expand Down Expand Up @@ -61,10 +93,35 @@ class RemoveAngryHobo : public OneTimeEffect
}
if (farthest) {
HoboManager::RemoveAngryHobo (farthest);
}
}
break;
}
case 3: HoboManager::RemoveAllAngryHobo (); break;
case 4: {
CPed *player = FindPlayerPed ();
if (player) {
for(int i = 0; i < HoboManager::angryHobo.size (); i++) {
CPed *ped = std::get<CPed *> (HoboManager::angryHobo.at (i));
if (ped) {
CVector position = player->GetPosition ();
position.z += 3.0f;
ped->SetPosn (position);
}
}
}
break;
}
case 5: {
for(int i = 0; i < HoboManager::angryHobo.size (); i++) {
CPed *ped = std::get<CPed *> (HoboManager::angryHobo.at (i));
if (ped) {
CVector position = FindSuitableTeleportPosition (inst);
ped->SetPosn (position);
}
}
break;
}
}
}
};
Expand All @@ -73,3 +130,5 @@ DEFINE_EFFECT (RemoveAngryHobo, "effect_remove_random_angry_hobo", 0, 0);
DEFINE_EFFECT (RemoveAngryHobo, "effect_remove_nearest_angry_hobo", 0, 1);
DEFINE_EFFECT (RemoveAngryHobo, "effect_remove_farthest_angry_hobo", 0, 2);
DEFINE_EFFECT (RemoveAngryHobo, "effect_remove_all_angry_hobo", 0, 3);
DEFINE_EFFECT (RemoveAngryHobo, "effect_move_all_angry_hobo_to_you", 0, 4);
DEFINE_EFFECT (RemoveAngryHobo, "effect_move_all_angry_hobo_to_random", 0, 5);
4 changes: 2 additions & 2 deletions src/gtasa/util/GameHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,6 @@ class GameHandler
GlobalRenderer::Initialise ();
GameFixes::Initialise ();

HoboManager::LoadAngryHobo ();

// Custom save-file hook for "Slot 9"
HOOK_ARGS (GlobalHooksInstance::Get (), Hooked_OpenFile,
FILE * (const char *, const char *), 0x5D0D66);
Expand Down Expand Up @@ -119,6 +117,8 @@ class GameHandler
static void
ProcessGame ()
{
HoboManager::LoadAngryHobo (); // Call One Time, IDK where place suitable

HandleAutoSave ();
HandleQuickSave ();

Expand Down
75 changes: 59 additions & 16 deletions src/gtasa/util/HoboManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
#include <filesystem>
#include <variant>

#include "util/GlobalHooksInstance.h"
#include "util/CPedDamageResponseCalculator.h"

#include <CCivilianPed.h>
#include <CPed.h>
#include <CPickups.h>
Expand All @@ -21,6 +24,8 @@ class HoboManager
static inline std::vector<std::tuple<CPed *, int, eWeaponType>> angryHobo
= {};

static inline bool angryHoboLoaded = false;

static std::filesystem::path
GetHoboManagerPath ()
{
Expand All @@ -37,6 +42,12 @@ class HoboManager
static void
LoadAngryHobo ()
{
if (angryHoboLoaded) return;

byte gameState
= injector::ReadMemory<byte> (0xC8D4C0, true); // GameState

if (gameState != 9) return;
// Load Hobo
const std::filesystem::path managerPath = GetHoboManagerPath ();

Expand All @@ -51,37 +62,38 @@ class HoboManager
// now we can read the file
file.read (ini);

int Type, Alive, Weapon;
float Health, X, Y, Z;
int Type = 0, Alive = 0, Weapon = 0;
float Health = 0.0, X = 0.0, Y = 0.0, Z = 0.0;
for (auto &section : ini)
{
for (auto &item : section.second)
{
if (item.first == "Type")
std::cout << item.first << " = " << item.second << std::endl;
if (item.first == "type")
{
Type = std::stoi (item.second);
}
else if (item.first == "Alive")
else if (item.first == "alive")
{
Alive = std::stoi (item.second);
}
else if (item.first == "Weapon")
else if (item.first == "weapon")
{
Weapon = std::stoi (item.second);
}
else if (item.first == "Health")
else if (item.first == "health")
{
Health = std::stof (item.second);
}
else if (item.first == "X")
else if (item.first == "x")
{
X = std::stof (item.second);
}
else if (item.first == "Y")
else if (item.first == "y")
{
Y = std::stof (item.second);
}
else if (item.first == "Z")
else if (item.first == "z")
{
Z = std::stof (item.second);
}
Expand All @@ -94,6 +106,35 @@ class HoboManager
std::make_tuple (ped, Type, (eWeaponType) Weapon));
}
}

HOOK_METHOD_ARGS (GlobalHooksInstance::Get (), Hooked_ComputeWillKillPed,
void (CPedDamageResponseCalculator *, CPed *, void *,
char),
0x4B5B27);

angryHoboLoaded = true;
}

static void
Hooked_ComputeWillKillPed (auto &&cb,
CPedDamageResponseCalculator *thisCalc,
CPed *ped, void *a3, char a4)
{
cb ();

if (!ped) return;

if(ped->m_fHealth > 0.0f) return; // Skip the hook if the ped is still alive

auto index = std::find_if (
angryHobo.begin (), angryHobo.end (),
[ped] (std::tuple<CPed *, int, eWeaponType> &t)
{ return std::get<CPed *> (t) == ped; });

if (index != angryHobo.end ())
{
_RemoveAngryHobo (ped);
}
}

static void
Expand All @@ -112,14 +153,16 @@ class HoboManager
eWeaponType weaponType = std::get<eWeaponType> (angryHobo.at (i));
CVector position = ped->GetPosition ();

ini["Hobo" + std::to_string (i)]["Type"] = Type;
ini["Hobo" + std::to_string (i)]["Type"] = std::to_string (Type);
ini["Hobo" + std::to_string (i)]["Alive"]
= ped->m_nPedState != PEDSTATE_DIE;
ini["Hobo" + std::to_string (i)]["Weapon"] = weaponType;
ini["Hobo" + std::to_string (i)]["Health"] = ped->m_fHealth;
ini["Hobo" + std::to_string (i)]["X"] = position.x;
ini["Hobo" + std::to_string (i)]["Y"] = position.y;
ini["Hobo" + std::to_string (i)]["Z"] = position.z;
= std::to_string (ped->m_nPedState != PEDSTATE_DIE);
ini["Hobo" + std::to_string (i)]["Weapon"]
= std::to_string (weaponType);
ini["Hobo" + std::to_string (i)]["Health"]
= std::to_string (ped->m_fHealth);
ini["Hobo" + std::to_string (i)]["X"] = std::to_string (position.x);
ini["Hobo" + std::to_string (i)]["Y"] = std::to_string (position.y);
ini["Hobo" + std::to_string (i)]["Z"] = std::to_string (position.z);
}

file.generate (ini);
Expand Down

0 comments on commit b238a83

Please sign in to comment.