add invisible water, no water, disable hydrant improvements
This commit is contained in:
parent
bd75524368
commit
c0869efcae
225
src/FileHandler.cpp
Normal file
225
src/FileHandler.cpp
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "FileHandler.h"
|
||||||
|
#include "Visual.h"
|
||||||
|
|
||||||
|
// TODO: Clean up this mess, use structures instead?
|
||||||
|
void FileHandler::GenerateHandlingFile(int pHandling, std::map<int, std::string>& storeMap)
|
||||||
|
{
|
||||||
|
FILE* fp = fopen("handling.txt", "w");
|
||||||
|
|
||||||
|
std::string handlingId = storeMap[FindPlayerPed()->m_pVehicle->m_nModelIndex];
|
||||||
|
float fMass = patch::Get<float>(pHandling + 0x4);
|
||||||
|
float fTurnMass = patch::Get<float>(pHandling + 0xC);
|
||||||
|
float fDragMult = patch::Get<float>(pHandling + 0x10);
|
||||||
|
float CentreOfMassX = patch::Get<float>(pHandling + 0x14);
|
||||||
|
float CentreOfMassY = patch::Get<float>(pHandling + 0x18);
|
||||||
|
float CentreOfMassZ = patch::Get<float>(pHandling + 0x1C);
|
||||||
|
int nPercentSubmerged = patch::Get<int>(pHandling + 0x20);
|
||||||
|
float fTractionMultiplier = patch::Get<float>(pHandling + 0x28);
|
||||||
|
float fTractionLoss = patch::Get<float>(pHandling + 0xA4);
|
||||||
|
float TractionBias = patch::Get<float>(pHandling + 0xA8);
|
||||||
|
float fEngineAcceleration = patch::Get<float>(pHandling + 0x7C) * 12500;
|
||||||
|
float fEngineInertia = patch::Get<float>(pHandling + 0x80);
|
||||||
|
int nDriveType = patch::Get<BYTE>(pHandling + 0x74);
|
||||||
|
int nEngineType = patch::Get<BYTE>(pHandling + 0x75);
|
||||||
|
float BrakeDeceleration = patch::Get<float>(pHandling + 0x94) * 2500;
|
||||||
|
float BrakeBias = patch::Get<float>(pHandling + 0x98);
|
||||||
|
int ABS = patch::Get<BYTE>(pHandling + 0x9C);
|
||||||
|
float SteeringLock = patch::Get<float>(pHandling + 0xA0);
|
||||||
|
float SuspensionForceLevel = patch::Get<float>(pHandling + 0xAC);
|
||||||
|
float SuspensionDampingLevel = patch::Get<float>(pHandling + 0xB0);
|
||||||
|
float SuspensionHighSpdComDamp = patch::Get<float>(pHandling + 0xB4);
|
||||||
|
float Suspension_upper_limit = patch::Get<float>(pHandling + 0xB8);
|
||||||
|
float Suspension_lower_limit = patch::Get<float>(pHandling + 0xBC);
|
||||||
|
float Suspension_bias = patch::Get<float>(pHandling + 0xC0);
|
||||||
|
float Suspension_anti_dive_multiplier = patch::Get<float>(pHandling + 0xC4);
|
||||||
|
float fCollisionDamageMultiplier = patch::Get<float>(pHandling + 0xC8) * 0.338;
|
||||||
|
int nMonetaryValue = patch::Get<int>(pHandling + 0xD8);
|
||||||
|
int MaxVelocity = patch::Get<float>(pHandling + 0x84);
|
||||||
|
MaxVelocity = MaxVelocity * 206 + (MaxVelocity - 0.918668) * 1501;
|
||||||
|
int modelFlags = patch::Get<int>(pHandling + 0xCC);
|
||||||
|
int handlingFlags = patch::Get<int>(pHandling + 0xD0);
|
||||||
|
int front_lights = patch::Get<BYTE>(pHandling + 0xDC);
|
||||||
|
int rear_lights = patch::Get<BYTE>(pHandling + 0xDD);
|
||||||
|
int vehicle_anim_group = patch::Get<BYTE>(pHandling + 0xDE);
|
||||||
|
int nNumberOfGears = patch::Get<BYTE>(pHandling + 0x76);
|
||||||
|
float fSeatOffsetDistance = patch::Get<float>(pHandling + 0xD4);
|
||||||
|
|
||||||
|
// TODO: make this more readable
|
||||||
|
fprintf(
|
||||||
|
fp,
|
||||||
|
"\n%s\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%d\t%.5g\t%.5g\t%.5g\t%d\t%d\t%.5g\t%.5g\t%c\t%c\t%.5g\t%.5g\t%d\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%d\t%d\t%d\t%d\t%d\t%d",
|
||||||
|
handlingId.c_str(), fMass, fTurnMass, fDragMult, CentreOfMassX, CentreOfMassY, CentreOfMassZ, nPercentSubmerged,
|
||||||
|
fTractionMultiplier, fTractionLoss, TractionBias, nNumberOfGears,
|
||||||
|
MaxVelocity, fEngineAcceleration, fEngineInertia, nDriveType, nEngineType, BrakeDeceleration, BrakeBias, ABS,
|
||||||
|
SteeringLock, SuspensionForceLevel, SuspensionDampingLevel,
|
||||||
|
SuspensionHighSpdComDamp, Suspension_upper_limit, Suspension_lower_limit, Suspension_bias,
|
||||||
|
Suspension_anti_dive_multiplier, fSeatOffsetDistance,
|
||||||
|
fCollisionDamageMultiplier, nMonetaryValue, modelFlags, handlingFlags, front_lights, rear_lights,
|
||||||
|
vehicle_anim_group);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileHandler::FetchColorData(std::vector<std::vector<float>>& storeVec,
|
||||||
|
std::map<std::string, std::vector<int>>& storeMap)
|
||||||
|
{
|
||||||
|
std::string m_FilePath = GAME_PATH((char*)"/data/carcols.dat");
|
||||||
|
|
||||||
|
if (std::filesystem::exists(m_FilePath))
|
||||||
|
{
|
||||||
|
std::ifstream file(m_FilePath);
|
||||||
|
std::string line;
|
||||||
|
bool bIsCar = false;
|
||||||
|
bool bIsCol = false;
|
||||||
|
int nLineCount = 0;
|
||||||
|
|
||||||
|
while (getline(file, line))
|
||||||
|
{
|
||||||
|
// skip commented & emety lines
|
||||||
|
if (line[0] == '#' || line == "")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// section blocks
|
||||||
|
if (line[0] == 'c' && line[1] == 'a' && line[2] == 'r')
|
||||||
|
{
|
||||||
|
bIsCar = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line[0] == 'c' && line[1] == 'o' && line[2] == 'l')
|
||||||
|
{
|
||||||
|
bIsCol = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line[0] == 'e' && line[1] == 'n' && line[2] == 'd')
|
||||||
|
{
|
||||||
|
bIsCar = false;
|
||||||
|
bIsCol = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bIsCol)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::string temp;
|
||||||
|
std::stringstream ss(line);
|
||||||
|
|
||||||
|
// fix one instance where . is used instead of ,
|
||||||
|
std::replace(temp.begin(), temp.end(), '.', ',');
|
||||||
|
|
||||||
|
// Format: red, green, blue
|
||||||
|
int r,g,b;
|
||||||
|
getline(ss, temp, ',');
|
||||||
|
r = std::stoi(temp);
|
||||||
|
getline(ss, temp, ',');
|
||||||
|
g = std::stoi(temp);
|
||||||
|
getline(ss, temp, ',');
|
||||||
|
b = std::stoi(temp);
|
||||||
|
|
||||||
|
storeVec.push_back({r / 255.0f, g / 255.0f, b / 255.0f});
|
||||||
|
++nLineCount;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
flog << "Error parsing carcols.dat, " << line << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bIsCar)
|
||||||
|
{
|
||||||
|
std::string temp;
|
||||||
|
std::stringstream ss(line);
|
||||||
|
|
||||||
|
// Format: modelname, colorindex1, colorindex2,...
|
||||||
|
getline(ss, temp, ',');
|
||||||
|
std::string name = temp;
|
||||||
|
while (getline(ss, temp, ','))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::for_each(name.begin(), name.end(), [](char& c)
|
||||||
|
{
|
||||||
|
c = ::toupper(c);
|
||||||
|
});
|
||||||
|
|
||||||
|
int val = std::stoi(temp);
|
||||||
|
if (!(std::find(storeMap[name].begin(), storeMap[name].end(), val) !=
|
||||||
|
storeMap[name].end()))
|
||||||
|
{
|
||||||
|
storeMap[name].push_back(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
flog << "Error parsing carcols.dat, " << line << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flog << "Carcols.dat not found";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileHandler::FetchHandlingID(std::map<int, std::string>& storeMap)
|
||||||
|
{
|
||||||
|
std::string m_FilePath = GAME_PATH((char*)"/data/vehicles.ide");
|
||||||
|
|
||||||
|
if (std::filesystem::exists(m_FilePath))
|
||||||
|
{
|
||||||
|
std::ifstream file(m_FilePath);
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
while (getline(file, line))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Format: model, modelname, txdname, type, handlingId, ...
|
||||||
|
Skip if first thing isn't model id
|
||||||
|
*/
|
||||||
|
if (line[0] <= '0' || line[0] >= '9')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// running inside try block to handle user errors, mostly commas
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::string temp;
|
||||||
|
std::stringstream ss(line);
|
||||||
|
|
||||||
|
// get model
|
||||||
|
getline(ss, temp, ',');
|
||||||
|
int model = std::stoi(temp);
|
||||||
|
|
||||||
|
// get modelname, txd, type, handlingId
|
||||||
|
getline(ss, temp, ',');
|
||||||
|
getline(ss, temp, ',');
|
||||||
|
getline(ss, temp, ',');
|
||||||
|
getline(ss, temp, ',');
|
||||||
|
|
||||||
|
temp.erase(std::remove_if(temp.begin(), temp.end(), ::isspace), temp.end());
|
||||||
|
|
||||||
|
storeMap[model] = temp;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
flog << "Error parsing vehicles.ide, " << line << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flog << "Vehicle.ide not found";
|
||||||
|
}
|
||||||
|
}
|
25
src/FileHandler.h
Normal file
25
src/FileHandler.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class FileHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FileHandler() = delete;
|
||||||
|
FileHandler(FileHandler&) = delete;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parses data/carcols.dat file and stores color data per vehicle
|
||||||
|
TODO: Implement something that also parses modloader data
|
||||||
|
*/
|
||||||
|
static void FetchColorData(std::vector<std::vector<float>>& storeVec,
|
||||||
|
std::map<std::string, std::vector<int>>& storeMap);
|
||||||
|
/*
|
||||||
|
Parses data/vehicles.ide file and stores handingId in a map
|
||||||
|
TODO: Implement something that also parses modloader data
|
||||||
|
*/
|
||||||
|
static void FetchHandlingID(std::map<int, std::string>& storeMap);
|
||||||
|
static void GenerateHandlingFile(int pHandling, std::map<int, std::string>& storeMap);
|
||||||
|
};
|
||||||
|
|
@ -249,27 +249,30 @@ void Player::ChangePlayerCloth(std::string& name)
|
|||||||
std::string model = temp.c_str();
|
std::string model = temp.c_str();
|
||||||
|
|
||||||
getline(ss, temp, '$');
|
getline(ss, temp, '$');
|
||||||
std::string texture9 = temp.c_str();
|
std::string texName = temp.c_str();
|
||||||
|
|
||||||
CPlayerPed* player = FindPlayerPed();
|
CPlayerPed* player = FindPlayerPed();
|
||||||
|
|
||||||
if (texture9 == "cutoffchinosblue")
|
if (texName == "cutoffchinosblue")
|
||||||
{
|
{
|
||||||
player->m_pPlayerData->m_pPedClothesDesc->SetTextureAndModel(-697413025, 744365350, body_part);
|
player->m_pPlayerData->m_pPedClothesDesc->SetTextureAndModel(-697413025, 744365350, body_part);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (texture9 == "sneakerbincblue")
|
if (texName == "sneakerbincblue")
|
||||||
{
|
{
|
||||||
player->m_pPlayerData->m_pPedClothesDesc->SetTextureAndModel(-915574819, 2099005073, body_part);
|
player->m_pPlayerData->m_pPedClothesDesc->SetTextureAndModel(-915574819, 2099005073, body_part);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (texture9 == "12myfac")
|
if (texName == "12myfac")
|
||||||
|
{
|
||||||
player->m_pPlayerData->m_pPedClothesDesc->SetTextureAndModel(-1750049245, 1393983095, body_part);
|
player->m_pPlayerData->m_pPedClothesDesc->SetTextureAndModel(-1750049245, 1393983095, body_part);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
player->m_pPlayerData->m_pPedClothesDesc->
|
{
|
||||||
SetTextureAndModel(texture9.c_str(), model.c_str(), body_part);
|
player->m_pPlayerData->m_pPedClothesDesc->SetTextureAndModel(texName.c_str(), model.c_str(), body_part);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CClothes::RebuildPlayer(player, false);
|
CClothes::RebuildPlayer(player, false);
|
||||||
|
@ -59,7 +59,7 @@ void ResourceStore::LoadTextureResource(std::string&& name)
|
|||||||
pEndDic = (RwTexDictionary*)pRLL->link.next;
|
pEndDic = (RwTexDictionary*)pRLL->link.next;
|
||||||
RwTexture *pTex = (RwTexture*)&pRLL[-1];
|
RwTexture *pTex = (RwTexture*)&pRLL[-1];
|
||||||
|
|
||||||
m_ImagesList.push_back(std::make_unique<STextureResource>());
|
m_ImagesList.push_back(std::make_unique<TextureResource>());
|
||||||
m_ImagesList.back().get()->m_pRwTexture = pTex;
|
m_ImagesList.back().get()->m_pRwTexture = pTex;
|
||||||
|
|
||||||
// Fetch IDirec9Texture9* from RwTexture*
|
// Fetch IDirec9Texture9* from RwTexture*
|
||||||
|
@ -28,7 +28,7 @@ struct RwRasterEx : public RwRaster
|
|||||||
RwD3D9Raster *m_pRenderResource;
|
RwD3D9Raster *m_pRenderResource;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct STextureResource
|
struct TextureResource
|
||||||
{
|
{
|
||||||
std::string m_FileName;
|
std::string m_FileName;
|
||||||
std::string m_CategoryName;
|
std::string m_CategoryName;
|
||||||
@ -43,7 +43,7 @@ enum eResourceType
|
|||||||
TYPE_BOTH,
|
TYPE_BOTH,
|
||||||
};
|
};
|
||||||
|
|
||||||
using TextureResourceList = std::vector<std::unique_ptr<STextureResource>>;
|
using TextureResourceList = std::vector<std::unique_ptr<TextureResource>>;
|
||||||
class ResourceStore
|
class ResourceStore
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
252
src/Vehicle.cpp
252
src/Vehicle.cpp
@ -3,6 +3,7 @@
|
|||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
#include "Ui.h"
|
#include "Ui.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
#include "FileHandler.h"
|
||||||
#include <CPopulation.h>
|
#include <CPopulation.h>
|
||||||
#include <CDamageManager.h>
|
#include <CDamageManager.h>
|
||||||
|
|
||||||
@ -31,15 +32,15 @@ void Vehicle::FixVehicle(CVehicle *pVeh)
|
|||||||
Vehicle::Vehicle()
|
Vehicle::Vehicle()
|
||||||
{
|
{
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
ParseVehiclesIDE();
|
FileHandler::FetchHandlingID(m_VehicleIDE);
|
||||||
#endif
|
#endif
|
||||||
ParseCarcolsDAT();
|
FileHandler::FetchColorData(m_CarcolsColorData, m_CarcolsCarData);
|
||||||
|
|
||||||
Events::processScriptsEvent += [this]
|
Events::processScriptsEvent += [this]
|
||||||
{
|
{
|
||||||
uint timer = CTimer::m_snTimeInMilliseconds;
|
uint timer = CTimer::m_snTimeInMilliseconds;
|
||||||
CPlayerPed* pPlayer = FindPlayerPed();
|
CPlayerPed* pPlayer = FindPlayerPed();
|
||||||
CVehicle* pVeh = pPlayer->m_pVehicle;
|
CVehicle* pVeh = FindPlayerVehicle(-1, false);
|
||||||
|
|
||||||
if (pPlayer && pVeh)
|
if (pPlayer && pVeh)
|
||||||
{
|
{
|
||||||
@ -159,13 +160,19 @@ Vehicle::Vehicle()
|
|||||||
int chance = 0;
|
int chance = 0;
|
||||||
|
|
||||||
if (veh->m_nVehicleClass == CLASS_NORMAL) // Normal
|
if (veh->m_nVehicleClass == CLASS_NORMAL) // Normal
|
||||||
|
{
|
||||||
chance = Random(1, 20);
|
chance = Random(1, 20);
|
||||||
|
}
|
||||||
|
|
||||||
if (veh->m_nVehicleClass == CLASS_RICHFAMILY) // Rich family
|
if (veh->m_nVehicleClass == CLASS_RICHFAMILY) // Rich family
|
||||||
|
{
|
||||||
chance = Random(1, 4);
|
chance = Random(1, 4);
|
||||||
|
}
|
||||||
|
|
||||||
if (veh->m_nVehicleClass == CLASS_EXECUTIVE) // Executive
|
if (veh->m_nVehicleClass == CLASS_EXECUTIVE) // Executive
|
||||||
|
{
|
||||||
chance = Random(1, 3);
|
chance = Random(1, 3);
|
||||||
|
}
|
||||||
|
|
||||||
if (chance == 1 && !IsNeonInstalled(veh) && veh->m_pDriver != pPlayer)
|
if (chance == 1 && !IsNeonInstalled(veh) && veh->m_pDriver != pPlayer)
|
||||||
{
|
{
|
||||||
@ -228,7 +235,9 @@ void Vehicle::RemoveComponent(const std::string& component, const bool display_m
|
|||||||
player->m_pVehicle->RemoveVehicleUpgrade(icomp);
|
player->m_pVehicle->RemoveVehicleUpgrade(icomp);
|
||||||
|
|
||||||
if (display_message)
|
if (display_message)
|
||||||
|
{
|
||||||
SetHelpMessage("Component removed", false, false, false);
|
SetHelpMessage("Component removed", false, false, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
@ -267,220 +276,8 @@ int Vehicle::GetRandomTrainIdForModel(int model)
|
|||||||
int id = Random(_start, _end);
|
int id = Random(_start, _end);
|
||||||
return train_ids[id];
|
return train_ids[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get vehicle HandlingId
|
|
||||||
void Vehicle::ParseVehiclesIDE()
|
|
||||||
{
|
|
||||||
std::string m_FilePath = std::string(paths::GetGameDirPathA()) + "/data/vehicles.ide";
|
|
||||||
|
|
||||||
if (fs::exists(m_FilePath))
|
|
||||||
{
|
|
||||||
std::ifstream file(m_FilePath);
|
|
||||||
std::string line;
|
|
||||||
|
|
||||||
while (getline(file, line))
|
|
||||||
{
|
|
||||||
if (line[0] <= '0' || line[0] >= '9')
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::string temp;
|
|
||||||
std::stringstream ss(line);
|
|
||||||
|
|
||||||
// model
|
|
||||||
getline(ss, temp, ',');
|
|
||||||
|
|
||||||
int model = std::stoi(temp);
|
|
||||||
|
|
||||||
// modelname, txd, type, handlingId
|
|
||||||
getline(ss, temp, ',');
|
|
||||||
getline(ss, temp, ',');
|
|
||||||
getline(ss, temp, ',');
|
|
||||||
getline(ss, temp, ',');
|
|
||||||
|
|
||||||
temp.erase(std::remove_if(temp.begin(), temp.end(), ::isspace), temp.end());
|
|
||||||
|
|
||||||
m_VehicleIDE[model] = temp;
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
flog << "Error while parsing line, " << line << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
else flog << "Vehicle.ide file not found";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Vehicle::GenerateHandlingDataFile(int phandling)
|
|
||||||
{
|
|
||||||
FILE* fp = fopen("handling.txt", "w");
|
|
||||||
|
|
||||||
std::string handlingId = m_VehicleIDE[FindPlayerPed()->m_pVehicle->m_nModelIndex];
|
|
||||||
float fMass = patch::Get<float>(phandling + 0x4);
|
|
||||||
float fTurnMass = patch::Get<float>(phandling + 0xC);
|
|
||||||
float fDragMult = patch::Get<float>(phandling + 0x10);
|
|
||||||
float CentreOfMassX = patch::Get<float>(phandling + 0x14);
|
|
||||||
float CentreOfMassY = patch::Get<float>(phandling + 0x18);
|
|
||||||
float CentreOfMassZ = patch::Get<float>(phandling + 0x1C);
|
|
||||||
int nPercentSubmerged = patch::Get<int>(phandling + 0x20);
|
|
||||||
float fTractionMultiplier = patch::Get<float>(phandling + 0x28);
|
|
||||||
float fTractionLoss = patch::Get<float>(phandling + 0xA4);
|
|
||||||
float TractionBias = patch::Get<float>(phandling + 0xA8);
|
|
||||||
float fEngineAcceleration = patch::Get<float>(phandling + 0x7C) * 12500;
|
|
||||||
float fEngineInertia = patch::Get<float>(phandling + 0x80);
|
|
||||||
int nDriveType = patch::Get<BYTE>(phandling + 0x74);
|
|
||||||
int nEngineType = patch::Get<BYTE>(phandling + 0x75);
|
|
||||||
float BrakeDeceleration = patch::Get<float>(phandling + 0x94) * 2500;
|
|
||||||
float BrakeBias = patch::Get<float>(phandling + 0x98);
|
|
||||||
int ABS = patch::Get<BYTE>(phandling + 0x9C);
|
|
||||||
float SteeringLock = patch::Get<float>(phandling + 0xA0);
|
|
||||||
float SuspensionForceLevel = patch::Get<float>(phandling + 0xAC);
|
|
||||||
float SuspensionDampingLevel = patch::Get<float>(phandling + 0xB0);
|
|
||||||
float SuspensionHighSpdComDamp = patch::Get<float>(phandling + 0xB4);
|
|
||||||
float Suspension_upper_limit = patch::Get<float>(phandling + 0xB8);
|
|
||||||
float Suspension_lower_limit = patch::Get<float>(phandling + 0xBC);
|
|
||||||
float Suspension_bias = patch::Get<float>(phandling + 0xC0);
|
|
||||||
float Suspension_anti_dive_multiplier = patch::Get<float>(phandling + 0xC4);
|
|
||||||
float fCollisionDamageMultiplier = patch::Get<float>(phandling + 0xC8) * 0.338;
|
|
||||||
int nMonetaryValue = patch::Get<int>(phandling + 0xD8);
|
|
||||||
|
|
||||||
int MaxVelocity = patch::Get<float>(phandling + 0x84);
|
|
||||||
MaxVelocity = MaxVelocity * 206 + (MaxVelocity - 0.918668) * 1501;
|
|
||||||
|
|
||||||
int modelFlags = patch::Get<int>(phandling + 0xCC);
|
|
||||||
int handlingFlags = patch::Get<int>(phandling + 0xD0);
|
|
||||||
|
|
||||||
int front_lights = patch::Get<BYTE>(phandling + 0xDC);
|
|
||||||
int rear_lights = patch::Get<BYTE>(phandling + 0xDD);
|
|
||||||
int vehicle_anim_group = patch::Get<BYTE>(phandling + 0xDE);
|
|
||||||
int nNumberOfGears = patch::Get<BYTE>(phandling + 0x76);
|
|
||||||
float fSeatOffsetDistance = patch::Get<float>(phandling + 0xD4);
|
|
||||||
|
|
||||||
fprintf(
|
|
||||||
fp,
|
|
||||||
"\n%s\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%d\t%.5g\t%.5g\t%.5g\t%d\t%d\t%.5g\t%.5g\t%c\t%c\t%.5g\t%.5g\t%d\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t%d\t%d\t%d\t%d\t%d\t%d",
|
|
||||||
handlingId.c_str(), fMass, fTurnMass, fDragMult, CentreOfMassX, CentreOfMassY, CentreOfMassZ, nPercentSubmerged,
|
|
||||||
fTractionMultiplier, fTractionLoss, TractionBias, nNumberOfGears,
|
|
||||||
MaxVelocity, fEngineAcceleration, fEngineInertia, nDriveType, nEngineType, BrakeDeceleration, BrakeBias, ABS,
|
|
||||||
SteeringLock, SuspensionForceLevel, SuspensionDampingLevel,
|
|
||||||
SuspensionHighSpdComDamp, Suspension_upper_limit, Suspension_lower_limit, Suspension_bias,
|
|
||||||
Suspension_anti_dive_multiplier, fSeatOffsetDistance,
|
|
||||||
fCollisionDamageMultiplier, nMonetaryValue, modelFlags, handlingFlags, front_lights, rear_lights,
|
|
||||||
vehicle_anim_group);
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Vehicle::ParseCarcolsDAT()
|
|
||||||
{
|
|
||||||
std::string m_FilePath = GAME_PATH((char*)"/data/carcols.dat");
|
|
||||||
|
|
||||||
if (fs::exists(m_FilePath))
|
|
||||||
{
|
|
||||||
std::ifstream file(m_FilePath);
|
|
||||||
std::string line;
|
|
||||||
|
|
||||||
bool car_section = false;
|
|
||||||
bool col_section = false;
|
|
||||||
int count = 0;
|
|
||||||
while (getline(file, line))
|
|
||||||
{
|
|
||||||
if (line[0] == '#' || line == "")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (line[0] == 'c' && line[1] == 'a' && line[2] == 'r')
|
|
||||||
{
|
|
||||||
car_section = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line[0] == 'c' && line[1] == 'o' && line[2] == 'l')
|
|
||||||
{
|
|
||||||
col_section = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line[0] == 'e' && line[1] == 'n' && line[2] == 'd')
|
|
||||||
{
|
|
||||||
car_section = false;
|
|
||||||
col_section = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (col_section)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::string temp;
|
|
||||||
std::stringstream ss(line);
|
|
||||||
|
|
||||||
std::replace(temp.begin(), temp.end(), '.', ','); // fix one instance where . is used instead of ,
|
|
||||||
|
|
||||||
// red, green, blue
|
|
||||||
getline(ss, temp, ',');
|
|
||||||
int red = std::stoi(temp);
|
|
||||||
|
|
||||||
getline(ss, temp, ',');
|
|
||||||
int green = std::stoi(temp);
|
|
||||||
|
|
||||||
getline(ss, temp, ',');
|
|
||||||
int blue = std::stoi(temp);
|
|
||||||
|
|
||||||
std::vector<float> color = { red / 255.0f, green / 255.0f, blue / 255.0f };
|
|
||||||
m_CarcolsColorData.push_back(color);
|
|
||||||
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
flog << "Error while parsing car line, " << line << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (car_section)
|
|
||||||
{
|
|
||||||
std::string temp;
|
|
||||||
std::stringstream ss(line);
|
|
||||||
|
|
||||||
getline(ss, temp, ',');
|
|
||||||
std::string name = temp;
|
|
||||||
while (getline(ss, temp, ','))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::for_each(name.begin(), name.end(), [](char& c)
|
|
||||||
{
|
|
||||||
c = ::toupper(c);
|
|
||||||
});
|
|
||||||
|
|
||||||
int val = std::stoi(temp);
|
|
||||||
if (!(std::find(m_CarcolsCarData[name].begin(), m_CarcolsCarData[name].end(), val) !=
|
|
||||||
m_CarcolsCarData[name].end()))
|
|
||||||
m_CarcolsCarData[name].push_back(val);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
flog << "Error while parsing car line, " << line << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
flog << "Error locating Vehicle.ide";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
void Vehicle::SpawnVehicle(std::string& smodel)
|
void Vehicle::SpawnVehicle(std::string& smodel)
|
||||||
#elif GTAVC
|
#elif GTAVC
|
||||||
@ -752,6 +549,29 @@ void Vehicle::Draw()
|
|||||||
}
|
}
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
Ui::CheckboxAddress("Decreased traffic", 0x96917A);
|
Ui::CheckboxAddress("Decreased traffic", 0x96917A);
|
||||||
|
// if (Ui::CheckboxWithHint("Disable collisions", &m_bDisableColDetection))
|
||||||
|
// {
|
||||||
|
// if (m_bDisableColDetection)
|
||||||
|
// {
|
||||||
|
// patch::SetUChar(0x56717B, 0x7D);
|
||||||
|
// patch::SetUChar(0x56725D, 0x7D);
|
||||||
|
// }
|
||||||
|
// // update flags for exising vehicles
|
||||||
|
// for (auto veh : CPools::ms_pVehiclePool)
|
||||||
|
// {
|
||||||
|
// if (veh == FindPlayerVehicle(-1, false))
|
||||||
|
// {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// if (m_bDisableColDetection)
|
||||||
|
// {
|
||||||
|
// CCollisionData* pColData = veh->GetColModel()->m_pColData;
|
||||||
|
// // pColData->m_nNumSpheres = 0;
|
||||||
|
// pColData->m_nNumBoxes = 0;
|
||||||
|
// pColData->m_nNumTriangles = 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
#endif
|
#endif
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
@ -1372,7 +1192,7 @@ void Vehicle::Draw()
|
|||||||
|
|
||||||
if (ImGui::Button("Save to file", ImVec2(Ui::GetSize(3))))
|
if (ImGui::Button("Save to file", ImVec2(Ui::GetSize(3))))
|
||||||
{
|
{
|
||||||
GenerateHandlingDataFile(pHandling);
|
FileHandler::GenerateHandlingFile(pHandling, m_VehicleIDE);
|
||||||
SetHelpMessage("Handling saved", false, false, false);
|
SetHelpMessage("Handling saved", false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
#include "Neon.h"
|
#include "Neon.h"
|
||||||
#include "Paint.h"
|
#include "Paint.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GTASA
|
||||||
class Vehicle : public Paint, public Neon
|
class Vehicle : public Paint, public Neon
|
||||||
#elif GTAVC
|
#elif GTAVC
|
||||||
class Vehicle
|
class Vehicle
|
||||||
@ -32,6 +34,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
|
inline static bool m_bDisableColDetection;
|
||||||
inline static std::map<int, std::string> m_VehicleIDE;
|
inline static std::map<int, std::string> m_VehicleIDE;
|
||||||
struct m_Neon
|
struct m_Neon
|
||||||
{
|
{
|
||||||
@ -92,10 +95,8 @@ private:
|
|||||||
static void AddComponent(const std::string& component, bool display_message = true);
|
static void AddComponent(const std::string& component, bool display_message = true);
|
||||||
static void RemoveComponent(const std::string& component, bool display_message = true);
|
static void RemoveComponent(const std::string& component, bool display_message = true);
|
||||||
static int GetRandomTrainIdForModel(int model);
|
static int GetRandomTrainIdForModel(int model);
|
||||||
static void ParseVehiclesIDE();
|
|
||||||
static void GenerateHandlingDataFile(int phandling);
|
static void GenerateHandlingDataFile(int phandling);
|
||||||
#endif
|
#endif
|
||||||
static void ParseCarcolsDAT();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#ifdef GTASA
|
#ifdef GTASA
|
||||||
|
234
src/Visual.cpp
234
src/Visual.cpp
@ -29,94 +29,6 @@ Visual::Visual()
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
int Visual::CalcArrayIndex()
|
|
||||||
{
|
|
||||||
int hour = CClock::ms_nGameClockHours;
|
|
||||||
|
|
||||||
#ifdef GTASA
|
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
if (m_nTimecycHour == 24)
|
|
||||||
{
|
|
||||||
result = hour;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (hour < 5) result = 0;
|
|
||||||
if (hour == 5) result = 1;
|
|
||||||
if (hour == 6) result = 2;
|
|
||||||
if (7 <= hour && hour < 12) result = 3;
|
|
||||||
if (12 <= hour && hour < 19) result = 4;
|
|
||||||
if (hour == 19) result = 5;
|
|
||||||
if (hour == 20 || hour == 21) result = 6;
|
|
||||||
if (hour == 22 || hour == 23) result = 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 23 * result + CWeather::OldWeatherType;
|
|
||||||
#elif GTAVC
|
|
||||||
return 7 * hour + CWeather::OldWeatherType;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Visual::TimeCycColorEdit3(const char* label, uchar* r, uchar* g, uchar* b, ImGuiColorEditFlags flags)
|
|
||||||
{
|
|
||||||
bool rtn = false;
|
|
||||||
int val = CalcArrayIndex();
|
|
||||||
|
|
||||||
#ifdef GTASA
|
|
||||||
auto red = static_cast<uchar*>(patch::GetPointer(int(r)));
|
|
||||||
auto green = static_cast<uchar*>(patch::GetPointer(int(g)));
|
|
||||||
auto blue = static_cast<uchar*>(patch::GetPointer(int(b)));
|
|
||||||
#elif GTAVC
|
|
||||||
auto red = static_cast<uchar*>(r);
|
|
||||||
auto green = static_cast<uchar*>(g);
|
|
||||||
auto blue = static_cast<uchar*>(b);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
float col[3]{ red[val] / 255.0f, green[val] / 255.0f, blue[val] / 255.0f };
|
|
||||||
|
|
||||||
if (ImGui::ColorEdit3(label, col, flags))
|
|
||||||
{
|
|
||||||
red[val] = col[0] * 255;
|
|
||||||
green[val] = col[1] * 255;
|
|
||||||
blue[val] = col[2] * 255;
|
|
||||||
rtn = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rtn;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Visual::TimeCycColorEdit4(const char* label, uchar* r, uchar* g, uchar* b, uchar* a, ImGuiColorEditFlags flags)
|
|
||||||
{
|
|
||||||
bool rtn = false;
|
|
||||||
int val = CalcArrayIndex();
|
|
||||||
|
|
||||||
#ifdef GTASA
|
|
||||||
auto red = static_cast<uchar*>(patch::GetPointer(int(r)));
|
|
||||||
auto green = static_cast<uchar*>(patch::GetPointer(int(g)));
|
|
||||||
auto blue = static_cast<uchar*>(patch::GetPointer(int(b)));
|
|
||||||
auto alpha = static_cast<uchar*>(patch::GetPointer(int(a)));
|
|
||||||
#elif GTAVC
|
|
||||||
auto red = static_cast<uchar*>(r);
|
|
||||||
auto green = static_cast<uchar*>(g);
|
|
||||||
auto blue = static_cast<uchar*>(b);
|
|
||||||
auto alpha = static_cast<uchar*>(a);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
float col[4]{ red[val] / 255.0f, green[val] / 255.0f, blue[val] / 255.0f, alpha[val] / 255.0f };
|
|
||||||
|
|
||||||
if (ImGui::ColorEdit4(label, col, flags))
|
|
||||||
{
|
|
||||||
red[val] = col[0] * 255;
|
|
||||||
green[val] = col[1] * 255;
|
|
||||||
blue[val] = col[2] * 255;
|
|
||||||
alpha[val] = col[3] * 255;
|
|
||||||
rtn = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rtn;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
int GetTCVal(T* addr, int index)
|
int GetTCVal(T* addr, int index)
|
||||||
{
|
{
|
||||||
@ -259,6 +171,99 @@ void Visual::GenerateTimecycFile()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Visual::CalcArrayIndex()
|
||||||
|
{
|
||||||
|
int hour = CClock::ms_nGameClockHours;
|
||||||
|
|
||||||
|
#ifdef GTASA
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
if (m_nTimecycHour == 24)
|
||||||
|
{
|
||||||
|
result = hour;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (hour < 5) result = 0;
|
||||||
|
if (hour == 5) result = 1;
|
||||||
|
if (hour == 6) result = 2;
|
||||||
|
if (7 <= hour && hour < 12) result = 3;
|
||||||
|
if (12 <= hour && hour < 19) result = 4;
|
||||||
|
if (hour == 19) result = 5;
|
||||||
|
if (hour == 20 || hour == 21) result = 6;
|
||||||
|
if (hour == 22 || hour == 23) result = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 23 * result + CWeather::OldWeatherType;
|
||||||
|
#elif GTAVC
|
||||||
|
return 7 * hour + CWeather::OldWeatherType;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Visual::TimeCycColorEdit3(const char* label, uchar* r, uchar* g, uchar* b, ImGuiColorEditFlags flags)
|
||||||
|
{
|
||||||
|
bool rtn = false;
|
||||||
|
int val = CalcArrayIndex();
|
||||||
|
|
||||||
|
#ifdef GTASA
|
||||||
|
auto red = static_cast<uchar*>(patch::GetPointer(int(r)));
|
||||||
|
auto green = static_cast<uchar*>(patch::GetPointer(int(g)));
|
||||||
|
auto blue = static_cast<uchar*>(patch::GetPointer(int(b)));
|
||||||
|
#elif GTAVC
|
||||||
|
auto red = static_cast<uchar*>(r);
|
||||||
|
auto green = static_cast<uchar*>(g);
|
||||||
|
auto blue = static_cast<uchar*>(b);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float col[3]{ red[val] / 255.0f, green[val] / 255.0f, blue[val] / 255.0f };
|
||||||
|
|
||||||
|
if (ImGui::ColorEdit3(label, col, flags))
|
||||||
|
{
|
||||||
|
red[val] = col[0] * 255;
|
||||||
|
green[val] = col[1] * 255;
|
||||||
|
blue[val] = col[2] * 255;
|
||||||
|
rtn = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
char __cdecl GetWaterLevelNoWaves(float x, float y, float z, int a4, __int64 a5)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Visual::TimeCycColorEdit4(const char* label, uchar* r, uchar* g, uchar* b, uchar* a, ImGuiColorEditFlags flags)
|
||||||
|
{
|
||||||
|
bool rtn = false;
|
||||||
|
int val = CalcArrayIndex();
|
||||||
|
|
||||||
|
#ifdef GTASA
|
||||||
|
auto red = static_cast<uchar*>(patch::GetPointer(int(r)));
|
||||||
|
auto green = static_cast<uchar*>(patch::GetPointer(int(g)));
|
||||||
|
auto blue = static_cast<uchar*>(patch::GetPointer(int(b)));
|
||||||
|
auto alpha = static_cast<uchar*>(patch::GetPointer(int(a)));
|
||||||
|
#elif GTAVC
|
||||||
|
auto red = static_cast<uchar*>(r);
|
||||||
|
auto green = static_cast<uchar*>(g);
|
||||||
|
auto blue = static_cast<uchar*>(b);
|
||||||
|
auto alpha = static_cast<uchar*>(a);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float col[4]{ red[val] / 255.0f, green[val] / 255.0f, blue[val] / 255.0f, alpha[val] / 255.0f };
|
||||||
|
|
||||||
|
if (ImGui::ColorEdit4(label, col, flags))
|
||||||
|
{
|
||||||
|
red[val] = col[0] * 255;
|
||||||
|
green[val] = col[1] * 255;
|
||||||
|
blue[val] = col[2] * 255;
|
||||||
|
alpha[val] = col[3] * 255;
|
||||||
|
rtn = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
|
|
||||||
void Visual::Draw()
|
void Visual::Draw()
|
||||||
{
|
{
|
||||||
if (ImGui::BeginTabBar("Visual", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll))
|
if (ImGui::BeginTabBar("Visual", ImGuiTabBarFlags_NoTooltip + ImGuiTabBarFlags_FittingPolicyScroll))
|
||||||
@ -273,6 +278,18 @@ void Visual::Draw()
|
|||||||
Ui::CheckboxAddress("Armour percentage", 0x589125);
|
Ui::CheckboxAddress("Armour percentage", 0x589125);
|
||||||
Ui::CheckboxAddress("Breath border", 0x589207);
|
Ui::CheckboxAddress("Breath border", 0x589207);
|
||||||
Ui::CheckboxAddress("Breath percentage", 0x589209);
|
Ui::CheckboxAddress("Breath percentage", 0x589209);
|
||||||
|
if (Ui::CheckboxWithHint("Disable hydrant splash", &m_bDisableHydrant))
|
||||||
|
{
|
||||||
|
if (m_bDisableHydrant)
|
||||||
|
{
|
||||||
|
// don't call Fx_c::TriggerWaterHydrant
|
||||||
|
plugin::patch::Nop(0x4A0D70, 5);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
plugin::patch::SetRaw(0x4A0D70, (char*)"\xE9\x94\x3F\xF6\xFF", 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
Ui::CheckboxAddress("Gray radar", 0xA444A4);
|
Ui::CheckboxAddress("Gray radar", 0xA444A4);
|
||||||
Ui::CheckboxAddress("Health border", 0x589353);
|
Ui::CheckboxAddress("Health border", 0x589353);
|
||||||
Ui::CheckboxAddress("Health percentage", 0x589355);
|
Ui::CheckboxAddress("Health percentage", 0x589355);
|
||||||
@ -290,11 +307,52 @@ void Visual::Draw()
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ui::CheckboxAddressEx("Hide wanted level", 0x58DD1B, 0x90, 1);
|
Ui::CheckboxAddressEx("Hide wanted level", 0x58DD1B, 0x90, 1);
|
||||||
|
|
||||||
|
if (Ui::CheckboxWithHint("Invisible water", &m_bInvisibleWater))
|
||||||
|
{
|
||||||
|
if (!m_bNoWater)
|
||||||
|
{
|
||||||
|
if (m_bInvisibleWater)
|
||||||
|
{
|
||||||
|
// don't call CWaterLevel::RenderWater()
|
||||||
|
plugin::patch::Nop(0x53E004, 5);
|
||||||
|
plugin::patch::Nop(0x53E142, 5);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// restore call CWaterLevel::RenderWater()
|
||||||
|
plugin::patch::SetRaw(0x53E004, (char*)"\xE8\x47\x16\x1B\x00", 5);
|
||||||
|
plugin::patch::SetRaw(0x53E142, (char*)"\xE8\x09\x15\x1B\x00", 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (Ui::CheckboxWithHint("Lock weather", &m_bLockWeather))
|
if (Ui::CheckboxWithHint("Lock weather", &m_bLockWeather))
|
||||||
{
|
{
|
||||||
m_nBacWeatherType = CWeather::OldWeatherType;
|
m_nBacWeatherType = CWeather::OldWeatherType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Ui::CheckboxWithHint("No water", &m_bNoWater))
|
||||||
|
{
|
||||||
|
if (m_bNoWater)
|
||||||
|
{
|
||||||
|
// don't call CWaterLevel::RenderWater()
|
||||||
|
plugin::patch::Nop(0x53E004, 5);
|
||||||
|
plugin::patch::Nop(0x53E142, 5);
|
||||||
|
|
||||||
|
// rtn CWaterLevel::GetWaterLevelNoWaves
|
||||||
|
plugin::patch::SetRaw(0x6E8580, (char*)"\x32\xC0\xC3", 3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// restore call CWaterLevel::RenderWater()
|
||||||
|
plugin::patch::SetRaw(0x53E004, (char*)"\xE8\x47\x16\x1B\x00", 5);
|
||||||
|
plugin::patch::SetRaw(0x53E142, (char*)"\xE8\x09\x15\x1B\x00", 5);
|
||||||
|
|
||||||
|
// restore CWaterLevel::GetWaterLevelNoWaves
|
||||||
|
plugin::patch::SetRaw(0x6E8580, (char*)"\x51\xD9\x44", 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool radar_state = (patch::Get<BYTE>(0xBA676C) != 2);
|
bool radar_state = (patch::Get<BYTE>(0xBA676C) != 2);
|
||||||
if (Ui::CheckboxWithHint("Show radar", &radar_state))
|
if (Ui::CheckboxWithHint("Show radar", &radar_state))
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,11 @@ private:
|
|||||||
inline static bool m_bLockWeather;
|
inline static bool m_bLockWeather;
|
||||||
inline static int m_nBacWeatherType;
|
inline static int m_nBacWeatherType;
|
||||||
|
|
||||||
|
#ifdef GTASA
|
||||||
|
inline static bool m_bInvisibleWater;
|
||||||
|
inline static bool m_bNoWater;
|
||||||
|
inline static bool m_bDisableHydrant;
|
||||||
|
#endif
|
||||||
// Timecyc
|
// Timecyc
|
||||||
inline static int m_nTimecycHour = 8;
|
inline static int m_nTimecycHour = 8;
|
||||||
inline static std::vector<std::string> m_WeatherNames
|
inline static std::vector<std::string> m_WeatherNames
|
||||||
|
Loading…
Reference in New Issue
Block a user