Refactored code, added more hotkeys #46 #47

This commit is contained in:
Grinch_ 2021-01-18 15:53:24 +06:00
parent 3a909e8aba
commit 2b13546efa
17 changed files with 351 additions and 363 deletions

View File

@ -8,7 +8,9 @@
"${PLUGIN_SDK_DIR}/plugin_sa",
"${PLUGIN_SDK_DIR}/plugin_sa/game_sa",
"${PLUGIN_SDK_DIR}/shared",
"${PLUGIN_SDK_DIR}/shared/game"
"${PLUGIN_SDK_DIR}/shared/game",
"E:/plugin-sdk-master/plugin_sa/game_sa",
"E:/plugin-sdk-master/shared"
],
"defines": [
"GTASA",

View File

@ -37,8 +37,8 @@ set(src_files
"src/Menu.cpp"
"src/Menu.h"
"src/MenuInfo.h"
"src/NeonAPI.cpp"
"src/NeonAPI.h"
"src/Neon.cpp"
"src/Neon.h"
"src/Paint.cpp"
"src/Paint.h"
"src/pch.cpp"

View File

@ -18,12 +18,16 @@ int Menu::overlay::selected_pos = 4;
float Menu::overlay::posX = NULL;
float Menu::overlay::posY = NULL;
HotKeyData Menu::hotkeys::command_window{};
HotKeyData Menu::hotkeys::menu_open{};
HotKeyData Menu::hotkeys::aim_skin_changer{};
HotKeyData Menu::hotkeys::airbreak{};
HotKeyData Menu::hotkeys::command_window{};
HotKeyData Menu::hotkeys::flip_veh{};
HotKeyData Menu::hotkeys::fix_veh{};
HotKeyData Menu::hotkeys::god_mode{};
HotKeyData Menu::hotkeys::menu_open{};
HotKeyData Menu::hotkeys::quick_ss{};
HotKeyData Menu::hotkeys::quick_tp{};
HotKeyData Menu::hotkeys::airbreak{};
bool Menu::commands::show_menu = false;
char Menu::commands::input_buffer[INPUT_BUFFER_SIZE] = "";
@ -62,6 +66,15 @@ Menu::Menu()
hotkeys::command_window.key1 = config.GetValue("hotkey.command_window.key1", VK_LMENU);
hotkeys::command_window.key2 = config.GetValue("hotkey.command_window.key2", VK_KEY_C);
hotkeys::flip_veh.key1 = config.GetValue("hotkey.flip_veh.key1", VK_NONE);
hotkeys::flip_veh.key2 = config.GetValue("hotkey.flip_veh.key2", VK_NONE);
hotkeys::fix_veh.key1 = config.GetValue("hotkey.fix_veh.key1", VK_NONE);
hotkeys::fix_veh.key2 = config.GetValue("hotkey.fix_veh.key2", VK_NONE);
hotkeys::god_mode.key1 = config.GetValue("hotkey.god_mode.key1", VK_NONE);
hotkeys::god_mode.key2 = config.GetValue("hotkey.god_mode.key2", VK_NONE);
};
}
@ -316,7 +329,8 @@ void Menu::Main()
}
if (ImGui::BeginTabItem("Hotkeys"))
{
ImGui::Spacing();
ImGui::TextWrapped("Right clicking will set hotkey to none. Some are set to none by default. Choose keys for them if you want to use them.");
ImGui::Spacing();
ImGui::BeginChild("Hotkeys");
if (Ui::HotKey("Open/ close cheat menu", hotkeys::menu_open))
@ -353,6 +367,26 @@ void Menu::Main()
config.SetValue("hotkey.quick_tp.key2", hotkeys::quick_tp.key2);
}
ImGui::Dummy(ImVec2(0,10));
if (Ui::HotKey("Fix current vehicle", hotkeys::fix_veh))
{
config.SetValue("hotkey.fix_veh.key1", hotkeys::fix_veh.key1);
config.SetValue("hotkey.fix_veh.key2", hotkeys::fix_veh.key2);
}
if (Ui::HotKey("Flip current vehicle", hotkeys::flip_veh))
{
config.SetValue("hotkey.flip_veh.key1", hotkeys::flip_veh.key1);
config.SetValue("hotkey.flip_veh.key2", hotkeys::flip_veh.key2);
}
if (Ui::HotKey("Toggle god mode", hotkeys::god_mode))
{
config.SetValue("hotkey.god_mode.key1", hotkeys::god_mode.key1);
config.SetValue("hotkey.god_mode.key2", hotkeys::god_mode.key2);
}
ImGui::Dummy(ImVec2(0, 10));
ImGui::EndChild();

View File

@ -19,12 +19,15 @@ private:
public:
struct hotkeys
{
static HotKeyData command_window;
static HotKeyData menu_open;
static HotKeyData aim_skin_changer;
static HotKeyData airbreak;
static HotKeyData command_window;
static HotKeyData fix_veh;
static HotKeyData flip_veh;
static HotKeyData god_mode;
static HotKeyData menu_open;
static HotKeyData quick_ss;
static HotKeyData quick_tp;
static HotKeyData airbreak;
};
struct commands
{

View File

@ -1,11 +1,11 @@
#include "pch.h"
#include "NeonAPI.h"
#include "Neon.h"
#include "Util.h"
VehicleExtendedData<NeonAPI::NeonData> NeonAPI::VehNeon;
RwTexture* NeonAPI::neon_texture = nullptr;
VehicleExtendedData<Neon::NeonData> Neon::VehNeon;
RwTexture* Neon::neon_texture = nullptr;
NeonAPI::NeonAPI()
Neon::Neon()
{
Events::initGameEvent += [this]
{
@ -48,27 +48,27 @@ NeonAPI::NeonAPI()
};
}
NeonAPI::~NeonAPI()
Neon::~Neon()
{
delete neon_texture;
}
bool NeonAPI::IsNeonInstalled(CVehicle *pVeh)
bool Neon::IsNeonInstalled(CVehicle *pVeh)
{
return VehNeon.Get(pVeh).neon_installed;
}
bool NeonAPI::IsPulsingEnabled(CVehicle *pVeh)
bool Neon::IsPulsingEnabled(CVehicle *pVeh)
{
return VehNeon.Get(pVeh).pulsing;
}
void NeonAPI::SetPulsing(CVehicle *pVeh, bool state)
void Neon::SetPulsing(CVehicle *pVeh, bool state)
{
VehNeon.Get(pVeh).pulsing = state;
}
void NeonAPI::InstallNeon(CVehicle *pVeh, int red, int green, int blue)
void Neon::InstallNeon(CVehicle *pVeh, int red, int green, int blue)
{
CRGBA &color = VehNeon.Get(pVeh).color;
@ -80,7 +80,7 @@ void NeonAPI::InstallNeon(CVehicle *pVeh, int red, int green, int blue)
VehNeon.Get(pVeh).neon_installed = true;
}
void NeonAPI::RemoveNeon(CVehicle *pVeh)
void Neon::RemoveNeon(CVehicle *pVeh)
{
VehNeon.Get(pVeh).neon_installed = false;
}

View File

@ -1,6 +1,6 @@
#pragma once
class NeonAPI
class Neon
{
private:
static RwTexture* neon_texture;
@ -26,8 +26,8 @@ private:
static VehicleExtendedData<NeonData> VehNeon;
public:
NeonAPI();
~NeonAPI();
Neon();
~Neon();
static void InstallNeon(CVehicle *veh, int red, int green, int blue);
static bool IsNeonInstalled(CVehicle *veh);
static bool IsPulsingEnabled(CVehicle *veh);

View File

@ -1,3 +1,28 @@
// Portion of this source is taken from MoonAdditions https://github.com/THE-FYP/MoonAdditions
// To keep the licensing simple this file would go under MIT License, GPLv3 won't apply
// Copyright (c) 2012 DK22Pac
// Copyright (c) 2017 FYP
// Copyright (c) 2021 Grinch_
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include "pch.h"
#include "Paint.h"
#include "NodeName.h"
@ -5,6 +30,7 @@
std::vector<std::string> Paint::veh_nodes::names_vec{ "Default" };
std::string Paint::veh_nodes::selected = "Default";
VehicleExtendedData<Paint::VehData> Paint::vehdata;
std::map<std::string, std::shared_ptr<RwTexture>> Paint::textures;
@ -22,14 +48,59 @@ Paint::Paint()
}
};
Events::vehicleRenderEvent.before += [](CVehicle* veh) {
if (veh)
VehicleRenderer::get()->processRender(veh);
Events::vehicleRenderEvent.before += [](CVehicle* veh)
{
VehData& data = vehdata.Get(veh);
// reset custom color if color id changed
if (veh->m_nPrimaryColor != data.primary_color
|| veh->m_nSecondaryColor != data.secondary_color)
{
for (auto& it : data.materialProperties)
data.resetMaterialColor(it.first);
data.primary_color = veh->m_nPrimaryColor;
data.secondary_color = veh->m_nSecondaryColor;
}
for (auto& it : data.materialProperties)
{
if (it.second._recolor)
{
it.second._originalColor = it.first->color;
it.first->color = it.second._color;
it.second._originalGeometryFlags = it.second._geometry->flags;
it.second._geometry->flags |= rpGEOMETRYMODULATEMATERIALCOLOR;
}
if (it.second._retexture)
{
auto tex = it.second._texture.lock();
if (tex)
{
it.second._originalTexture = it.first->texture;
it.first->texture = tex.get();
}
else
{
it.second._retexture = false;
}
}
}
};
Events::vehicleResetAfterRender += [](CVehicle* veh) {
if (veh)
VehicleRenderer::get()->postRender(veh);
for (auto& it : vehdata.Get(veh).materialProperties)
{
if (it.second._recolor)
{
it.first->color = it.second._originalColor;
it.second._geometry->flags = it.second._originalGeometryFlags;
}
if (it.second._retexture)
{
it.first->texture = it.second._originalTexture;
}
}
};
}
@ -37,6 +108,48 @@ Paint::~Paint()
{
}
void Paint::VehData::setMaterialColor(RpMaterial* material, RpGeometry* geometry, RwRGBA color, bool filter_mat)
{
auto& matProps = materialProperties[material];
if ( !filter_mat
|| (material->color.red == 0x3C && material->color.green == 0xFF && material->color.blue == 0x00)
|| (material->color.red == 0xFF && material->color.green == 0x00 && material->color.blue == 0xAF))
{
matProps._recolor = true;
matProps._color = color;
matProps._geometry = geometry;
}
}
void Paint::VehData::setMaterialTexture(RpMaterial* material, std::shared_ptr<RwTexture> texture, bool filter_mat)
{
auto& matProps = materialProperties[material];
if (!filter_mat
|| (material->color.red == 0x3C && material->color.green == 0xFF && material->color.blue == 0x00)
|| (material->color.red == 0xFF && material->color.green == 0x00 && material->color.blue == 0xAF))
{
matProps._retexture = true;
matProps._texture = texture;
}
}
void Paint::VehData::resetMaterialColor(RpMaterial* material)
{
auto& matProps = materialProperties[material];
matProps._recolor = false;
matProps._color = {0, 0, 0, 0};
}
void Paint::VehData::resetMaterialTexture(RpMaterial* material)
{
auto& matProps = materialProperties[material];
matProps._retexture = false;
matProps._texture.reset();
}
void Paint::NodeWrapperRecursive(RwFrame *frame, CVehicle* pVeh, std::function<void(RwFrame*)> func)
{
if (frame)
@ -92,8 +205,10 @@ void Paint::SetNodeColor(CVehicle* pVeh, std::string node_name, CRGBA color, boo
CRGBA* color = &st->_color;
bool filter_mat = st->_filter;
VehData& data = vehdata.Get(FindPlayerPed()->m_pVehicle);
for (int i = 0; i < atomic->geometry->matList.numMaterials; ++i)
VehicleRenderer::get()->setMaterialColor(FindPlayerPed()->m_pVehicle, atomic->geometry->matList.materials[i], atomic->geometry, { color->r,color->g,color->b, 255 }, filter_mat);
data.setMaterialColor(atomic->geometry->matList.materials[i], atomic->geometry, { color->r,color->g,color->b, 255 }, filter_mat);
}
return object;
}, &st);
@ -129,8 +244,10 @@ void Paint::SetNodeTexture(CVehicle* pVeh, std::string node_name, std::string te
RpAtomic *atomic = reinterpret_cast<RpAtomic*>(object);
ST* st = reinterpret_cast<ST*>(data);
VehData& data = vehdata.Get(FindPlayerPed()->m_pVehicle);
for (int i = 0; i < atomic->geometry->matList.numMaterials; ++i)
VehicleRenderer::get()->setMaterialTexture(FindPlayerPed()->m_pVehicle, atomic->geometry->matList.materials[i], st->_textures[st->_texturename], st->_filter);
data.setMaterialTexture(atomic->geometry->matList.materials[i], st->_textures[st->_texturename], st->_filter);
}
return object;
}, &st);
@ -152,9 +269,10 @@ void Paint::ResetNodeColor(CVehicle *pVeh, std::string node_name)
if (object->type == rpATOMIC)
{
RpAtomic *atomic = reinterpret_cast<RpAtomic*>(object);
VehData& data = vehdata.Get(FindPlayerPed()->m_pVehicle);
for (int i = 0; i < atomic->geometry->matList.numMaterials; ++i)
VehicleRenderer::get()->resetMaterialColor(FindPlayerPed()->m_pVehicle, atomic->geometry->matList.materials[i]);
data.resetMaterialColor(atomic->geometry->matList.materials[i]);
}
return object;
}, nullptr);
@ -178,8 +296,10 @@ void Paint::ResetNodeTexture(CVehicle *pVeh, std::string node_name)
{
RpAtomic *atomic = reinterpret_cast<RpAtomic*>(object);
VehData& data = vehdata.Get(FindPlayerPed()->m_pVehicle);
for (int i = 0; i < atomic->geometry->matList.numMaterials; ++i)
VehicleRenderer::get()->resetMaterialTexture(FindPlayerPed()->m_pVehicle, atomic->geometry->matList.materials[i]);
data.resetMaterialTexture(atomic->geometry->matList.materials[i]);
}
return object;
}, nullptr);

View File

@ -1,19 +1,91 @@
// Portion of this source is taken from MoonAdditions https://github.com/THE-FYP/MoonAdditions
// To keep the licensing simple this file would go under MIT License, GPLv3 won't apply
// Copyright (c) 2012 DK22Pac
// Copyright (c) 2017 FYP
// Copyright (c) 2021 Grinch_
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#pragma once
#include "vendor/moon/vehicle_renderer.h"
class Paint : VehicleRenderer
class Paint
{
public:
Paint();
~Paint();
private:
// store vehicle specific data
struct VehData
{
struct MaterialProperties
{
MaterialProperties() :
_color{0, 0, 0, 0},
_recolor(false),
_retexture(false),
_originalColor{0, 0, 0, 0},
_originalTexture(nullptr),
_originalGeometryFlags(0),
_geometry(nullptr)
{
}
RwRGBA _color;
std::weak_ptr<RwTexture> _texture;
bool _recolor;
bool _retexture;
RpGeometry* _geometry;
RwRGBA _originalColor;
RwTexture* _originalTexture;
RwInt32 _originalGeometryFlags;
};
// carcols color id
uchar primary_color = 0;
uchar secondary_color = 0;
std::unordered_map<RpMaterial*, MaterialProperties> materialProperties;
VehData(CVehicle* veh)
{
primary_color = veh->m_nPrimaryColor;
secondary_color = veh->m_nSecondaryColor;
}
void setMaterialColor(RpMaterial* material, RpGeometry* geometry, RwRGBA color, bool filter_mat = false);
void setMaterialTexture(RpMaterial* material, std::shared_ptr<RwTexture> texture9, bool filter_mat = false);
void resetMaterialColor(RpMaterial* material);
void resetMaterialTexture(RpMaterial* material);
};
static VehicleExtendedData<VehData> vehdata;
protected:
static std::map<std::string, std::shared_ptr<RwTexture>> textures;
struct veh_nodes
{
static std::vector<std::string> names_vec;
static std::string selected;
};
static std::map<std::string, std::shared_ptr<RwTexture>> textures;
Paint();
~Paint();
static void UpdateNodeListRecursive(CVehicle* pVeh);
static void NodeWrapperRecursive(RwFrame * frame, CVehicle* pVeh, std::function<void(RwFrame*)> func);
static void SetNodeColor(CVehicle* pVeh, std::string node_name, CRGBA color, bool filter_mat = false);

View File

@ -107,6 +107,27 @@ Player::Player()
Util::ClearCharTasksVehCheck(player);
}
}
if (Ui::HotKeyPressed(Menu::hotkeys::god_mode))
{
if (god_mode)
{
CHud::SetHelpMessage("God mode disabled",false,false,false);
patch::Set<bool>(0x96916D, god_mode, false);
player->m_nPhysicalFlags.bBulletProof = false;
player->m_nPhysicalFlags.bCollisionProof = false;
player->m_nPhysicalFlags.bExplosionProof = false;
player->m_nPhysicalFlags.bFireProof = false;
player->m_nPhysicalFlags.bMeeleProof = false;
god_mode = false;
}
else
{
CHud::SetHelpMessage("God mode enabled",false,false,false);
god_mode = true;
}
}
};
}

View File

@ -791,7 +791,7 @@ bool Ui::HotKey(const char* label, HotKeyData& key_data)
{
ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyle().Colors[ImGuiCol_ButtonActive]);
for (int key = 2; key != 90; ++key)
for (int key = 3; key != 90; ++key)
{
if (KeyPressed(key))
{
@ -800,7 +800,7 @@ bool Ui::HotKey(const char* label, HotKeyData& key_data)
}
}
for (int key = 90; key != 2; --key)
for (int key = 90; key != 3; --key)
{
if (KeyPressed(key))
{
@ -810,7 +810,13 @@ bool Ui::HotKey(const char* label, HotKeyData& key_data)
}
}
std::string text = key_names[key_data.key1-1];
std::string text;
if (key_data.key1 != VK_NONE)
text = key_names[key_data.key1-1];
else
text = "None";
if (key_data.key1 != key_data.key2)
text += (" + " + key_names[key_data.key2-1]);
@ -825,6 +831,13 @@ bool Ui::HotKey(const char* label, HotKeyData& key_data)
else
current_hotkey = label;;
}
if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(1)) // right click
{
key_data.key1 = VK_NONE;
key_data.key2 = VK_NONE;
}
ImGui::SameLine();
ImGui::Text(label);
@ -850,7 +863,12 @@ bool Ui::HotKeyPressed(HotKeyData& hotkey)
std::string Ui::GetHotKeyNameString(HotKeyData& hotkey)
{
std::string text = key_names[hotkey.key1 - 1];
std::string text;
if (hotkey.key1 != VK_NONE)
text = key_names[hotkey.key1-1];
else
text = "None";
if (hotkey.key1 != hotkey.key2)
text += (" + " + key_names[hotkey.key2 - 1]);

View File

@ -1,5 +1,6 @@
#pragma once
#define VK_NONE -1
#define VK_KEY_0 0x30
#define VK_KEY_1 0x31
#define VK_KEY_2 0x32

View File

@ -1,5 +1,6 @@
#include "pch.h"
#include "Vehicle.h"
#include "Menu.h"
#include "Ui.h"
#include "Util.h"
@ -90,6 +91,22 @@ Vehicle::Vehicle()
{
int hveh = CPools::GetVehicleRef(veh);
if (Ui::HotKeyPressed(Menu::hotkeys::flip_veh))
{
float roll;
Command<Commands::GET_CAR_ROLL>(hveh, &roll);
roll += 180;
Command<Commands::SET_CAR_ROLL>(hveh, roll);
Command<Commands::SET_CAR_ROLL>(hveh, roll); // z rot fix
}
if (Ui::HotKeyPressed(Menu::hotkeys::fix_veh))
{
player->m_pVehicle->Fix();
player->m_pVehicle->m_fHealth = 1000.0f;
CHud::SetHelpMessage("Vehicle fixed",false,false,false);
}
if (veh_nodmg)
{
veh->m_nPhysicalFlags.bBulletProof = true;
@ -135,7 +152,7 @@ Vehicle::Vehicle()
int red, green, blue;
Util::RainbowValues(red, green, blue, 0.25);
NeonAPI::InstallNeon(veh, red, green, blue);
InstallNeon(veh, red, green, blue);
neon::rainbow_timer = timer;
}
}
@ -156,8 +173,8 @@ Vehicle::Vehicle()
if (veh->m_nVehicleClass == CLASS_EXECUTIVE) // Executive
chance = rand() % 3 + 1;
if (chance == 1 && !NeonAPI::IsNeonInstalled(veh) && veh->m_pDriver != player)
NeonAPI::InstallNeon(veh, rand() % 255, rand() % 255, rand() % 255);
if (chance == 1 && !IsNeonInstalled(veh) && veh->m_pDriver != player)
InstallNeon(veh, rand() % 255, rand() % 255, rand() % 255);
}
neon::traffic_timer = timer;
}
@ -716,12 +733,12 @@ void Vehicle::Main()
if (Ui::CheckboxWithHint("Explosion proof", &state, nullptr, veh_nodmg))
pVeh->m_nPhysicalFlags.bExplosionProof = state;
ImGui::NextColumn();
state = pVeh->m_nPhysicalFlags.bFireProof;
if (Ui::CheckboxWithHint("Fire proof", &state, nullptr, veh_nodmg))
pVeh->m_nPhysicalFlags.bFireProof = state;
ImGui::NextColumn();
state = pVeh->m_nVehicleFlags.bVehicleCanBeTargettedByHS;
if (Ui::CheckboxWithHint("HS targetable", &state, "Heat Seaker missile can target this"))
pVeh->m_nVehicleFlags.bVehicleCanBeTargettedByHS = state;
@ -747,6 +764,14 @@ void Vehicle::Main()
if (Ui::CheckboxWithHint("Melee proof", &state, nullptr, veh_nodmg))
pVeh->m_nPhysicalFlags.bMeeleProof = state;
state = pVeh->m_nVehicleFlags.bPetrolTankIsWeakPoint;
if (Ui::CheckboxWithHint("Petrol tank blow", &state, "Vehicle will blow up if petrol tank is shot"))
pVeh->m_nVehicleFlags.bPetrolTankIsWeakPoint = state;
state = pVeh->m_nVehicleFlags.bSirenOrAlarm;
if (Ui::CheckboxWithHint("Siren", &state))
pVeh->m_nVehicleFlags.bSirenOrAlarm = state;
state = pVeh->m_nVehicleFlags.bTakeLessDamage;
if (Ui::CheckboxWithHint("Take less dmg", &state, nullptr))
pVeh->m_nVehicleFlags.bTakeLessDamage = state;
@ -1036,16 +1061,16 @@ void Vehicle::Main()
ImGui::Spacing();
if (ImGui::Button("Remove neon", ImVec2(Ui::GetSize())))
{
NeonAPI::RemoveNeon(veh);
RemoveNeon(veh);
CHud::SetHelpMessage("Neon removed", false, false, false);
}
ImGui::Spacing();
ImGui::Columns(2, NULL, false);
bool pulsing = NeonAPI::IsPulsingEnabled(veh);
bool pulsing = IsPulsingEnabled(veh);
if (Ui::CheckboxWithHint("Pulsing neons", &pulsing))
NeonAPI::SetPulsing(veh,pulsing);
SetPulsing(veh,pulsing);
Ui::CheckboxWithHint("Rainbow neons", &neon::rainbow, "Rainbow effect to neon lights");
ImGui::NextColumn();
@ -1056,7 +1081,7 @@ Only some vehicles will have them.");
ImGui::Spacing();
if (ImGui::ColorEdit3("Color picker", neon::color_picker))
NeonAPI::InstallNeon(veh, neon::color_picker[0] * 255, neon::color_picker[1] * 255, neon::color_picker[2] * 255);
InstallNeon(veh, neon::color_picker[0] * 255, neon::color_picker[1] * 255, neon::color_picker[2] * 255);
ImGui::Spacing();
ImGui::Text("Select neon preset:");
@ -1073,7 +1098,7 @@ Only some vehicles will have them.");
if (Ui::ColorButton(color_id, carcols_color_values[color_id], ImVec2(btn_size, btn_size)))
{
std::vector<float> &color = carcols_color_values[color_id];
NeonAPI::InstallNeon(veh, color[0]*255, color[1]*255, color[2]*255);
InstallNeon(veh, color[0]*255, color[1]*255, color[2]*255);
}
if ((color_id + 1) % btns_in_row != 0)

View File

@ -1,8 +1,8 @@
#pragma once
#include "NeonAPI.h"
#include "Neon.h"
#include "Paint.h"
class Vehicle : Paint, NeonAPI
class Vehicle : Paint, Neon
{
private:
static bool bike_fly;

View File

@ -38,9 +38,6 @@ set(vendor_files
"kiero/minhook/trampoline.c"
"kiero/minhook/hde/hde32.c"
"kiero/minhook/trampoline.c"
"moon/pool_object_extender.h"
"moon/vehicle_renderer.h"
"moon/vehicle_renderer.cpp"
)
add_library(${PROJECT_NAME} STATIC ${vendor_files})

View File

@ -1,73 +0,0 @@
// This source is taken from MoonAdditions https://github.com/THE-FYP/MoonAdditions
// MIT License
// Copyright (c) 2012 DK22Pac
// Copyright (c) 2017 FYP
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#pragma once
#include <unordered_map>
template<typename ObjT, typename DataT>
class ExtendedObjectDataPool
{
public:
auto begin()
{
return _pool.begin();
}
auto end()
{
return _pool.end();
}
bool exists(const ObjT* obj) const
{
return _pool.find(obj) != _pool.end();
}
DataT& get(const ObjT* obj)
{
if (_pool.find(obj) != _pool.end())
return *_pool.find(obj)->second;
return *(_pool[obj] = std::make_unique<DataT>(obj));
}
void remove(const ObjT* obj)
{
_pool.erase(obj);
}
private:
std::unordered_map<const ObjT*, std::unique_ptr<DataT>> _pool;
};
template<typename T>
class VehicleDataExtended : public ExtendedObjectDataPool<CVehicle, T>
{
public:
VehicleDataExtended()
{
plugin::Events::vehicleDtorEvent.after += [this](CVehicle* veh) {
this->remove(veh);
};
}
};

View File

@ -1,145 +0,0 @@
// This source is taken from MoonAdditions https://github.com/THE-FYP/MoonAdditions
// MIT License
// Copyright (c) 2012 DK22Pac
// Copyright (c) 2017 FYP
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include "plugin.h"
#include "vehicle_renderer.h"
auto& VehicleRenderer::getVehicleData(CVehicle* veh)
{
if (!_vehicleData)
_vehicleData = std::make_unique<VehicleDataExtended<VehicleData>>();
return _vehicleData->get(veh);
}
auto& VehicleRenderer::getVehicleMaterialProperties(CVehicle* veh)
{
return getVehicleData(veh)._materialProperties;
}
void VehicleRenderer::setMaterialColor(CVehicle* veh, RpMaterial* material, RpGeometry* geometry, RwRGBA color, bool filter_mat)
{
auto& matProps = getVehicleMaterialProperties(veh)[material];
if ( !filter_mat
|| (material->color.red == 0x3C && material->color.green == 0xFF && material->color.blue == 0x00)
|| (material->color.red == 0xFF && material->color.green == 0x00 && material->color.blue == 0xAF))
{
matProps._recolor = true;
matProps._color = color;
matProps._geometry = geometry;
}
}
void VehicleRenderer::setMaterialTexture(CVehicle* veh, RpMaterial* material, std::shared_ptr<RwTexture> texture, bool filter_mat)
{
auto& matProps = getVehicleMaterialProperties(veh)[material];
if (!filter_mat
|| (material->color.red == 0x3C && material->color.green == 0xFF && material->color.blue == 0x00)
|| (material->color.red == 0xFF && material->color.green == 0x00 && material->color.blue == 0xAF))
{
matProps._retexture = true;
matProps._texture = texture;
}
}
void VehicleRenderer::resetMaterialColor(CVehicle* veh, RpMaterial* material)
{
if (isInitialized() && _vehicleData->exists(veh))
{
auto& matProps = getVehicleMaterialProperties(veh)[material];
matProps._recolor = false;
matProps._color = {0, 0, 0, 0};
}
}
void VehicleRenderer::resetMaterialTexture(CVehicle* veh, RpMaterial* material)
{
if (isInitialized() && _vehicleData->exists(veh))
{
auto& matProps = getVehicleMaterialProperties(veh)[material];
matProps._retexture = false;
matProps._texture.reset();
}
}
void VehicleRenderer::processRender(CVehicle* veh)
{
if (isInitialized() && _vehicleData->exists(veh))
{
// reset custom color if color id changed
if (veh->m_nPrimaryColor != getVehicleData(veh).primary_color
|| veh->m_nSecondaryColor != getVehicleData(veh).secondary_color)
{
for (auto& it : _vehicleData->get(veh)._materialProperties)
resetMaterialColor(veh, it.first);
getVehicleData(veh).primary_color = veh->m_nPrimaryColor;
getVehicleData(veh).secondary_color = veh->m_nSecondaryColor;
}
for (auto& it : _vehicleData->get(veh)._materialProperties)
{
if (it.second._recolor)
{
it.second._originalColor = it.first->color;
it.first->color = it.second._color;
it.second._originalGeometryFlags = it.second._geometry->flags;
it.second._geometry->flags |= rpGEOMETRYMODULATEMATERIALCOLOR;
}
if (it.second._retexture)
{
auto tex = it.second._texture.lock();
if (tex)
{
it.second._originalTexture = it.first->texture;
it.first->texture = tex.get();
}
else
{
it.second._retexture = false;
}
}
}
}
}
void VehicleRenderer::postRender(CVehicle* veh)
{
if (isInitialized() && _vehicleData->exists(veh))
{
for (auto& it : _vehicleData->get(veh)._materialProperties)
{
if (it.second._recolor)
{
it.first->color = it.second._originalColor;
it.second._geometry->flags = it.second._originalGeometryFlags;
}
if (it.second._retexture)
{
it.first->texture = it.second._originalTexture;
}
}
}
}

View File

@ -1,87 +0,0 @@
// This source is taken from MoonAdditions https://github.com/THE-FYP/MoonAdditions
// MIT License
// Copyright (c) 2012 DK22Pac
// Copyright (c) 2017 FYP
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#pragma once
#include "pool_object_extender.h"
class VehicleRenderer
{
struct MaterialProperties
{
MaterialProperties() :
_color{0, 0, 0, 0},
_recolor(false),
_retexture(false),
_originalColor{0, 0, 0, 0},
_originalTexture(nullptr),
_originalGeometryFlags(0),
_geometry(nullptr)
{
}
RwRGBA _color;
std::weak_ptr<RwTexture> _texture;
bool _recolor;
bool _retexture;
RpGeometry* _geometry;
RwRGBA _originalColor;
RwTexture* _originalTexture;
RwInt32 _originalGeometryFlags;
};
struct VehicleData
{
VehicleData(const CVehicle* veh)
{
primary_color = veh->m_nPrimaryColor;
secondary_color = veh->m_nSecondaryColor;
}
// carcols color id
uchar primary_color;
uchar secondary_color;
std::unordered_map<RpMaterial*, MaterialProperties> _materialProperties;
};
public:
void setMaterialColor(CVehicle* veh, RpMaterial* material, RpGeometry* geometry, RwRGBA color, bool filter_mat = false);
void setMaterialTexture(CVehicle* veh, RpMaterial* material, std::shared_ptr<RwTexture> texture9, bool filter_mat = false);
void resetMaterialColor(CVehicle* veh, RpMaterial* material);
void resetMaterialTexture(CVehicle* veh, RpMaterial* material);
void processRender(CVehicle* veh);
void postRender(CVehicle* veh);
bool isInitialized() const { return _vehicleData != nullptr; }
static VehicleRenderer* get()
{
static std::unique_ptr<VehicleRenderer> instance = std::make_unique<VehicleRenderer>();
return instance.get();
}
private:
auto& getVehicleMaterialProperties(CVehicle* veh);
auto& getVehicleData(CVehicle* veh);
std::unique_ptr<VehicleDataExtended<VehicleData>> _vehicleData;
};