Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fast Train & Object Spawner #171

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ file(GLOB_RECURSE SRC_FILES
)
set(DEPS_DIR "${PROJECT_SOURCE_DIR}/deps")

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")

add_library(${PROJECT_NAME} MODULE ${SRC_FILES})
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 23)

Expand Down
2 changes: 1 addition & 1 deletion cmake/imgui.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ if(NOT imgui_POPULATED)
"${imgui_SOURCE_DIR}/misc/cpp/imgui_stdlib.*"
)

add_library(imgui STATIC ${SRC_IMGUI})
add_library(imgui STATIC ${SRC_IMGUI})
source_group(TREE ${imgui_SOURCE_DIR} PREFIX "imgui" FILES ${SRC_IMGUI})
target_include_directories(imgui PRIVATE
"${imgui_SOURCE_DIR}"
Expand Down
4 changes: 2 additions & 2 deletions src/game/features/players/toxic/CagePlayerLarge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ namespace YimMenu::Features
{
auto coords = player.GetPed().GetPosition();
coords.z -= 1.0f;
SpawnObject(0x99C0CFCF, coords);
SpawnObject(0x99C0CFCF, coords, 0, 0, 0, true, true, false, false, true);
}
};

static CagePlayerLarge _CagePlayerLarge{"cageplayerlarge", "Cage Player(Large)", "Cages the player using a larger cage"};
}
}
2 changes: 1 addition & 1 deletion src/game/features/players/toxic/CagePlayerSmall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace YimMenu::Features
{
auto coords = player.GetPed().GetPosition();
coords.z -= 1.0f;
SpawnObject(0xF3D580D3, coords);
SpawnObject(0xF3D580D3, coords, 0, 0, 0, true, true, false, false, true);
}
};

Expand Down
48 changes: 48 additions & 0 deletions src/game/features/vehicle/FastTrain.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include "core/commands/LoopedCommand.hpp"
#include "core/frontend/Notifications.hpp"
#include "game/features/Features.hpp"
#include "game/rdr/Enums.hpp"
#include "game/rdr/Natives.hpp"
#include "game/backend/Self.hpp"

namespace YimMenu::Features
{
class FastTrain : public LoopedCommand
{
using LoopedCommand::LoopedCommand;

virtual void OnTick() override
{
auto vehicle = Self::GetVehicle();
if (vehicle)
{
Hash vehicleModelHash = ENTITY::GET_ENTITY_MODEL(vehicle.GetHandle());

if (VEHICLE::IS_THIS_MODEL_A_TRAIN(vehicleModelHash))
{
VEHICLE::SET_TRAIN_SPEED(vehicle.GetHandle(), 1000.0);
VEHICLE::SET_TRAIN_CRUISE_SPEED(vehicle.GetHandle(), 1000.0);
VEHICLE::_SET_TRAIN_MAX_SPEED(vehicle.GetHandle(), 1000.0);
}
}
}

virtual void OnDisable() override
{
auto vehicle = Self::GetVehicle();
if (vehicle)
{
Hash vehicleModelHash = ENTITY::GET_ENTITY_MODEL(vehicle.GetHandle());

if (VEHICLE::IS_THIS_MODEL_A_TRAIN(vehicleModelHash))
{
VEHICLE::SET_TRAIN_SPEED(vehicle.GetHandle(), 0.0);
VEHICLE::SET_TRAIN_CRUISE_SPEED(vehicle.GetHandle(), 0.0);
VEHICLE::_SET_TRAIN_MAX_SPEED(vehicle.GetHandle(), 0.0);
}
}
}
};

static FastTrain _FastTrain{"fasttrain", "Fast Train", "Makes the train much faster than normal. Instantly stops it when disabled."};
}
7 changes: 6 additions & 1 deletion src/game/frontend/submenus/Self.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,8 @@ namespace YimMenu::Submenus

auto vehicle = std::make_shared<Category>("Vehicle");
auto vehicleGlobalsGroup = std::make_shared<Group>("Globals");
auto vehicleFunGroup = std::make_shared<Group>("Fun");
auto vehicleFunGroup = std::make_shared<Group>("Fun");
auto trainGroup = std::make_shared<Group>("Train");

vehicleGlobalsGroup->AddItem(std::make_shared<BoolCommandItem>("vehiclegodmode"_J));
vehicleGlobalsGroup->AddItem(std::make_shared<CommandItem>("repairvehicle"_J));
Expand All @@ -213,8 +214,12 @@ namespace YimMenu::Submenus
vehicleFunGroup->AddItem(std::make_shared<ConditionalItem>("superdrive"_J, std::make_shared<BoolCommandItem>("superdrivedirectional"_J, "Directional")));
vehicleFunGroup->AddItem(std::make_shared<ConditionalItem>("superdrive"_J, std::make_shared<IntCommandItem>("superdriveforce"_J, "Force")));
vehicleFunGroup->AddItem(std::make_shared<BoolCommandItem>("superbrake"_J));

trainGroup->AddItem(std::make_shared<BoolCommandItem>("fasttrain"_J));

vehicle->AddItem(vehicleGlobalsGroup);
vehicle->AddItem(vehicleFunGroup);
vehicle->AddItem(trainGroup);
AddCategory(std::move(vehicle));

auto animations = std::make_shared<Category>("Animations");
Expand Down
18 changes: 15 additions & 3 deletions src/game/frontend/submenus/World.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "World.hpp"

#include "World/PedSpawner.hpp"
#include "World/ObjectSpawner.hpp"
#include "World/Shows.hpp"
#include "World/Train.hpp"
#include "World/VehicleSpawner.hpp"
Expand All @@ -12,6 +13,12 @@
#include "game/backend/ScriptMgr.hpp"
#include "game/backend/Self.hpp"
#include "game/frontend/items/Items.hpp"
#include "game/rdr/Ped.hpp"
#include "game/rdr/data/PedModels.hpp"
#include "game/rdr/data/ObjModels.hpp"

#include "util/VehicleSpawner.hpp"

#include <game/rdr/Natives.hpp>


Expand Down Expand Up @@ -75,15 +82,19 @@ namespace YimMenu::Submenus
}
}));


auto spawners = std::make_shared<Category>("Spawners");
auto pedSpawnerGroup = std::make_shared<Group>("Ped Spawner");
auto spawners = std::make_shared<Category>("Spawners");
auto pedSpawnerGroup = std::make_shared<Group>("Ped Spawner");
auto objSpawnerGroup = std::make_shared<Group>("Object Spawner");
auto vehicleSpawnerGroup = std::make_shared<Group>("Vehicle Spawner");
auto trainSpawnerGroup = std::make_shared<Group>("Train Spawner");

pedSpawnerGroup->AddItem(std::make_shared<ImGuiItem>([] {
RenderPedSpawnerMenu();
}));

objSpawnerGroup->AddItem(std::make_shared<ImGuiItem>([] {
RenderObjectSpawnerMenu();
}));

vehicleSpawnerGroup->AddItem(std::make_shared<ImGuiItem>([] {
RenderVehicleSpawnerMenu();
Expand All @@ -94,6 +105,7 @@ namespace YimMenu::Submenus
}));

spawners->AddItem(pedSpawnerGroup);
spawners->AddItem(objSpawnerGroup);
spawners->AddItem(vehicleSpawnerGroup);
spawners->AddItem(trainSpawnerGroup);

Expand Down
172 changes: 172 additions & 0 deletions src/game/frontend/submenus/World/ObjectSpawner.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
#include "core/commands/Command.hpp"
#include "game/backend/FiberPool.hpp"
#include "game/backend/NativeHooks.hpp"
#include "game/backend/ScriptMgr.hpp"
#include "game/backend/Self.hpp"
#include "game/frontend/items/Items.hpp"
#include "game/rdr/Natives.hpp"
#include "game/rdr/data/ObjModels.hpp"
#include "ObjectSpawner.hpp"
#include "util/SpawnObject.hpp"

namespace YimMenu::Submenus
{
static bool IsObjectModelInList(const std::string& model)
{
for (const auto& objModel : YimMenu::Data::g_ObjModels)
{
if (objModel.model == model)
return true;
}
return false;
}

static int ObjectSpawnerInputCallback(ImGuiInputTextCallbackData* data)
{
if (data->EventFlag == ImGuiInputTextFlags_CallbackCompletion)
{
std::string newText;
std::string inputLower = data->Buf;
std::transform(inputLower.begin(), inputLower.end(), inputLower.begin(), ::tolower);

for (const auto& objModel : YimMenu::Data::g_ObjModels)
{
std::string modelLower = objModel.model;
std::transform(modelLower.begin(), modelLower.end(), modelLower.begin(), ::tolower);
if (modelLower.find(inputLower) != std::string::npos)
{
newText = objModel.model;
break;
}
}

if (!newText.empty())
{
data->DeleteChars(0, data->BufTextLen);
data->InsertChars(0, newText.c_str());
}

return 1;
}
return 0;
}

void RenderObjectSpawnerMenu()
{
static std::string objectModelBuffer;
static float positionOffsetX = 5.0f;
static float positionOffsetY = 5.0f;
static float positionOffsetZ = 0.0f;
static float pitch = 0.0f;
static float yaw = 0.0f;
static float roll = 0.0f;
static float alpha = 125.0f;
static bool onGround = false;
static bool isFrozen = false;
static bool isBurning = false;
static bool isPickup = false;
static bool showPreview = false;
static bool hasCollision = false;
static int modelHash = 0;

Vector3 playerCoords = Self::GetPed().GetPosition();
Vector3 forwardVector = ENTITY::GET_ENTITY_FORWARD_VECTOR(Self::GetPed().GetHandle());

Vector3 spawnPosition;
spawnPosition.x = playerCoords.x + forwardVector.x * positionOffsetX;
spawnPosition.y = playerCoords.y + forwardVector.y * positionOffsetY;
spawnPosition.z = playerCoords.z + positionOffsetZ;

char buffer[256];
strncpy(buffer, objectModelBuffer.c_str(), sizeof(buffer));

ImGui::InputTextWithHint("##objectmodel", "Object Model", buffer, sizeof(buffer), ImGuiInputTextFlags_CallbackCompletion, ObjectSpawnerInputCallback);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use the frontend item InputTextWithHint. Make sure to call .Draw() if you choose to go this route, you probably should though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity Code Description Project File Line Suppression State Details
Error C2440 '': cannot convert from 'initializer list' to 'YimMenu::InputTextWithHint'

InputTextWithHint("##objectmodel", "Object Model", &buffer, ImGuiInputTextFlags_CallbackCompletion, nullptr, ObjectSpawnerInputCallback)
.Draw();

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Buffer has to be a string, not a char.


objectModelBuffer = buffer;

if (ImGui::IsItemHovered())
ImGui::SetTooltip("Press Tab to auto-fill");

if (!objectModelBuffer.empty() && !IsObjectModelInList(objectModelBuffer))
{
ImGui::BeginListBox("##objectmodels", ImVec2(250, 100));

std::string bufferLower = objectModelBuffer;
std::transform(bufferLower.begin(), bufferLower.end(), bufferLower.begin(), ::tolower);
for (const auto& objModel : YimMenu::Data::g_ObjModels)
{
std::string objModelLower = objModel.model;
std::transform(objModelLower.begin(), objModelLower.end(), objModelLower.begin(), ::tolower);
if (objModelLower.find(bufferLower) != std::string::npos && ImGui::Selectable(objModel.model.c_str()))
{
objectModelBuffer = objModel.model;
modelHash = Joaat(objectModelBuffer.c_str());
STREAMING::REQUEST_MODEL(modelHash, false);
while (!STREAMING::HAS_MODEL_LOADED(modelHash))
{
return;
}
}
}

ImGui::EndListBox();
}

ImGui::SliderFloat("Offset X", &positionOffsetX, -25.0f, 25.0f);
ImGui::SliderFloat("Offset Y", &positionOffsetY, -25.0f, 25.0f);
ImGui::SliderFloat("Offset Z", &positionOffsetZ, -10.0f, 10.0f);
ImGui::Separator();
ImGui::SliderFloat("Pitch", &pitch, -180.0f, 180.0f);
ImGui::SliderFloat("Yaw", &yaw, -180.0f, 180.0f);
ImGui::SliderFloat("Roll", &roll, -180.0f, 180.0f);
ImGui::Separator();
ImGui::SliderFloat("Transparency", &alpha, 0.0f, 255.0f);

ImGui::Checkbox("Place on Ground", &onGround);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Places the object properly on the ground when spawned.");
ImGui::SameLine();
ImGui::Checkbox("Freeze Position", &isFrozen);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Locks the object in place when spawned, preventing it from being moved.");
ImGui::SameLine();
ImGui::Checkbox("Set on Fire", &isBurning);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Sets things on fire near the object when spawned.");
ImGui::SameLine();
ImGui::Checkbox("Set as Pickup", &isPickup);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Sets the object as a pickup (if applicable) for spawning lootable items.");

ImGui::Checkbox("Set Collision", &hasCollision);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Sets the collision of the object making it so you cannot pass through it.");
ImGui::SameLine();
ImGui::Checkbox("Show Preview", &showPreview);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Shows a preview of the object in front of you.");

if (ImGui::Button("Spawn Object"))
{
int modelHash = Joaat(objectModelBuffer.c_str());
SpawnObject(modelHash, spawnPosition, pitch, yaw, roll, onGround, isFrozen, isBurning, isPickup, hasCollision);
}
ImGui::SameLine();
if (ImGui::Button("Reset Sliders"))
{
positionOffsetX = 5.0f;
positionOffsetY = 5.0f;
positionOffsetZ = 0.0f;
pitch = 0.0f;
yaw = 0.0f;
roll = 0.0f;
alpha = 125.0f;
}

if (showPreview)
{
int modelHash = Joaat(objectModelBuffer.c_str());
PreviewObject(modelHash, spawnPosition, pitch, yaw, roll, alpha, showPreview);
}
}
}
6 changes: 6 additions & 0 deletions src/game/frontend/submenus/World/ObjectSpawner.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

namespace YimMenu::Submenus
{
void RenderObjectSpawnerMenu();
}
Loading