2020-12-02 16:19:16 -05:00
|
|
|
#include "pch.h"
|
|
|
|
#include "Util.h"
|
2021-04-07 16:35:21 -04:00
|
|
|
#include "../Depend/imgui/stb_image.h"
|
2020-12-02 16:19:16 -05:00
|
|
|
|
|
|
|
void Util::ClearCharTasksVehCheck(CPed* ped)
|
|
|
|
{
|
|
|
|
uint hped = CPools::GetPedRef(ped);
|
|
|
|
uint hveh = NULL;
|
2020-12-09 08:15:50 -05:00
|
|
|
bool veh_engine = true;
|
2020-12-02 16:19:16 -05:00
|
|
|
|
2021-02-15 18:58:02 -05:00
|
|
|
if (ped->m_nPedFlags.bInVehicle)
|
2020-12-09 08:15:50 -05:00
|
|
|
{
|
2020-12-02 16:19:16 -05:00
|
|
|
hveh = CPools::GetVehicleRef(ped->m_pVehicle);
|
2020-12-09 08:15:50 -05:00
|
|
|
veh_engine = ped->m_pVehicle->m_nVehicleFlags.bEngineOn;
|
|
|
|
}
|
2020-12-02 16:19:16 -05:00
|
|
|
|
|
|
|
Command<Commands::CLEAR_CHAR_TASKS_IMMEDIATELY>(hped);
|
|
|
|
|
|
|
|
if (hveh)
|
2020-12-09 08:15:50 -05:00
|
|
|
{
|
2020-12-02 16:19:16 -05:00
|
|
|
Command<Commands::TASK_WARP_CHAR_INTO_CAR_AS_DRIVER>(hped, hveh);
|
2020-12-09 08:15:50 -05:00
|
|
|
ped->m_pVehicle->m_nVehicleFlags.bEngineOn = veh_engine;
|
|
|
|
}
|
2020-12-02 16:19:16 -05:00
|
|
|
}
|
|
|
|
|
2021-03-16 03:12:59 -04:00
|
|
|
void Util::ReleaseTextures(std::vector<std::unique_ptr<TextureStructure>> &store_vec)
|
|
|
|
{
|
|
|
|
// for (auto &it : store_vec)
|
|
|
|
// {
|
|
|
|
// if (Globals::renderer == Render_DirectX9)
|
|
|
|
// {
|
|
|
|
// reinterpret_cast<IDirect3DTexture9*>(it->texture)->Release();
|
|
|
|
// it->texture = nullptr;
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// reinterpret_cast<ID3D11ShaderResourceView*>(it->texture)->Release();
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
2021-02-24 16:54:45 -05:00
|
|
|
void Util::LoadTexturesInDirRecursive(const char* path, const char* file_ext, std::vector<std::string>& category_vec, std::vector<std::unique_ptr<TextureStructure>>& store_vec)
|
2020-12-02 16:19:16 -05:00
|
|
|
{
|
|
|
|
std::string folder = "";
|
2021-02-24 16:54:45 -05:00
|
|
|
for (auto& p : fs::recursive_directory_iterator(path))
|
2020-12-02 16:19:16 -05:00
|
|
|
{
|
|
|
|
if (p.path().extension() == file_ext)
|
|
|
|
{
|
|
|
|
store_vec.push_back(std::make_unique<TextureStructure>());
|
|
|
|
HRESULT hr = -1;
|
2021-03-16 03:12:59 -04:00
|
|
|
|
2020-12-02 16:19:16 -05:00
|
|
|
if (Globals::renderer == Render_DirectX9)
|
2021-01-07 16:07:45 -05:00
|
|
|
hr = D3DXCreateTextureFromFileA(GetD3DDevice(), p.path().string().c_str(), reinterpret_cast<PDIRECT3DTEXTURE9*>(&store_vec.back().get()->texture));
|
2021-03-16 03:12:59 -04:00
|
|
|
else
|
2020-12-02 16:19:16 -05:00
|
|
|
{
|
2021-01-07 16:07:45 -05:00
|
|
|
if (LoadTextureFromFileDx11(p.path().string().c_str(), reinterpret_cast<ID3D11ShaderResourceView**>(&store_vec.back().get()->texture)))
|
2020-12-02 16:19:16 -05:00
|
|
|
hr = S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hr == S_OK)
|
|
|
|
{
|
|
|
|
store_vec.back().get()->file_name = p.path().stem().string();
|
|
|
|
store_vec.back().get()->category_name = folder;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-02-25 17:45:41 -05:00
|
|
|
flog << "Failed to load " << p.path().stem().string() << std::endl;
|
2020-12-02 16:19:16 -05:00
|
|
|
store_vec.pop_back();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
folder = p.path().stem().string();
|
|
|
|
category_vec.push_back(folder);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Util::LoadTextureFromFileDx11(const char* filename, ID3D11ShaderResourceView** out_srv)
|
|
|
|
{
|
|
|
|
// Load from disk into a raw RGBA buffer
|
|
|
|
int image_width = 0;
|
|
|
|
int image_height = 0;
|
|
|
|
unsigned char* image_data = stbi_load(filename, &image_width, &image_height, NULL, 4);
|
|
|
|
if (image_data == NULL)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Create texture
|
|
|
|
D3D11_TEXTURE2D_DESC desc;
|
|
|
|
ZeroMemory(&desc, sizeof(desc));
|
|
|
|
desc.Width = image_width;
|
|
|
|
desc.Height = image_height;
|
|
|
|
desc.MipLevels = 1;
|
|
|
|
desc.ArraySize = 1;
|
|
|
|
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
|
|
desc.SampleDesc.Count = 1;
|
|
|
|
desc.Usage = D3D11_USAGE_DEFAULT;
|
|
|
|
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
|
|
|
desc.CPUAccessFlags = 0;
|
|
|
|
|
2021-02-24 16:54:45 -05:00
|
|
|
ID3D11Texture2D* pTexture = NULL;
|
2020-12-02 16:19:16 -05:00
|
|
|
D3D11_SUBRESOURCE_DATA subResource;
|
|
|
|
subResource.pSysMem = image_data;
|
|
|
|
subResource.SysMemPitch = desc.Width * 4;
|
|
|
|
subResource.SysMemSlicePitch = 0;
|
|
|
|
|
2021-01-07 16:07:45 -05:00
|
|
|
reinterpret_cast<ID3D11Device*>(Globals::device)->CreateTexture2D(&desc, &subResource, &pTexture);
|
2020-12-02 16:19:16 -05:00
|
|
|
|
|
|
|
// Create texture view
|
|
|
|
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
|
|
|
ZeroMemory(&srvDesc, sizeof(srvDesc));
|
|
|
|
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
|
|
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
|
|
|
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
|
|
|
srvDesc.Texture2D.MostDetailedMip = 0;
|
2021-01-07 16:07:45 -05:00
|
|
|
reinterpret_cast<ID3D11Device*>(Globals::device)->CreateShaderResourceView(pTexture, &srvDesc, out_srv);
|
2020-12-02 16:19:16 -05:00
|
|
|
pTexture->Release();
|
|
|
|
|
|
|
|
stbi_image_free(image_data);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Util::IsOnMission()
|
|
|
|
{
|
|
|
|
return FindPlayerPed()->CanPlayerStartMission() && !*(patch::Get<char*>(0x5D5380, false) + CTheScripts::OnAMissionFlag);
|
|
|
|
}
|
|
|
|
|
2021-02-24 16:54:45 -05:00
|
|
|
std::string Util::GetLocationName(CVector* pos)
|
2020-12-02 16:19:16 -05:00
|
|
|
{
|
|
|
|
int hplayer = CPools::GetPedRef(FindPlayerPed());
|
|
|
|
int interior = 0;
|
|
|
|
Command<Commands::GET_AREA_VISIBLE>(&interior);
|
|
|
|
|
|
|
|
std::string town = "San Andreas";
|
|
|
|
int city;
|
|
|
|
Command<Commands::GET_CITY_PLAYER_IS_IN>(&hplayer, &city);
|
|
|
|
|
|
|
|
switch (city)
|
|
|
|
{
|
2021-02-24 16:54:45 -05:00
|
|
|
case 0:
|
|
|
|
town = "CS";
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
town = "LS";
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
town = "SF";
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
town = "LV";
|
|
|
|
break;
|
2020-12-02 16:19:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (interior == 0)
|
|
|
|
return CTheZones::FindSmallestZoneForPosition(*pos, true)->GetTranslatedName() + std::string(", ") + town;
|
|
|
|
else
|
|
|
|
return std::string("Interior ") + std::to_string(interior) + ", " + town;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int Util::GetLargestGangInZone()
|
|
|
|
{
|
|
|
|
int gang_id = 0, max_density = 0;
|
|
|
|
|
|
|
|
for (int i = 0; i != 10; ++i)
|
|
|
|
{
|
|
|
|
CVector pos = FindPlayerPed()->GetPosition();
|
2021-02-24 16:54:45 -05:00
|
|
|
CZone* zone = new CZone();
|
|
|
|
|
|
|
|
CZoneExtraInfo* zone_info = CTheZones::GetZoneInfo(&pos, &zone);
|
2020-12-02 16:19:16 -05:00
|
|
|
int density = zone_info->m_nGangDensity[i];
|
|
|
|
|
|
|
|
if (density > max_density)
|
|
|
|
{
|
|
|
|
max_density = density;
|
|
|
|
gang_id = i;
|
|
|
|
}
|
2021-01-05 01:29:26 -05:00
|
|
|
delete zone;
|
2020-12-02 16:19:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return gang_id;
|
|
|
|
}
|
|
|
|
|
2021-01-03 06:48:07 -05:00
|
|
|
// implemention of opcode 0AB5 (STORE_CLOSEST_ENTITIES)
|
2020-12-02 16:19:16 -05:00
|
|
|
// https://github.com/cleolibrary/CLEO4/blob/916d400f4a731ba1dd0ff16e52bdb056f42b7038/source/CCustomOpcodeSystem.cpp#L1671
|
2021-01-03 06:48:07 -05:00
|
|
|
CVehicle* Util::GetClosestVehicle()
|
2020-12-02 16:19:16 -05:00
|
|
|
{
|
2021-02-24 16:54:45 -05:00
|
|
|
CPlayerPed* player = FindPlayerPed();
|
|
|
|
CPedIntelligence* pedintel;
|
2020-12-02 16:19:16 -05:00
|
|
|
if (player && (pedintel = player->m_pIntelligence))
|
|
|
|
{
|
2021-02-24 16:54:45 -05:00
|
|
|
CVehicle* veh = nullptr;
|
2020-12-02 16:19:16 -05:00
|
|
|
for (int i = 0; i < 16; i++)
|
|
|
|
{
|
|
|
|
veh = (CVehicle*)pedintel->m_vehicleScanner.m_apEntities[i];
|
|
|
|
if (veh && !veh->m_nVehicleFlags.bFadeOut)
|
|
|
|
break;
|
|
|
|
veh = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return veh;
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2021-01-03 06:48:07 -05:00
|
|
|
CPed* Util::GetClosestPed()
|
|
|
|
{
|
2021-02-24 16:54:45 -05:00
|
|
|
CPlayerPed* player = FindPlayerPed();
|
|
|
|
CPedIntelligence* pedintel;
|
2021-01-03 06:48:07 -05:00
|
|
|
if (player && (pedintel = player->m_pIntelligence))
|
|
|
|
{
|
2021-02-24 16:54:45 -05:00
|
|
|
CPed* ped = nullptr;
|
2021-01-03 06:48:07 -05:00
|
|
|
|
|
|
|
for (int i = 0; i < 16; i++)
|
|
|
|
{
|
|
|
|
ped = (CPed*)pedintel->m_pedScanner.m_apEntities[i];
|
|
|
|
if (ped && ped != player && (ped->m_nCreatedBy & 0xFF) == 1 && !ped->m_nPedFlags.bFadeOut)
|
|
|
|
break;
|
|
|
|
ped = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ped;
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2021-02-24 16:54:45 -05:00
|
|
|
void Util::RainbowValues(int& r, int& g, int& b, float speed)
|
2020-12-02 16:19:16 -05:00
|
|
|
{
|
2021-02-24 16:54:45 -05:00
|
|
|
int timer = CTimer::m_snTimeInMilliseconds / 150;
|
2020-12-02 16:19:16 -05:00
|
|
|
r = sin(timer * speed) * 127 + 128;
|
|
|
|
g = sin(timer * speed + 2) * 127 + 128;
|
|
|
|
b = sin(timer * speed + 4) * 127 + 128;
|
2020-12-25 16:22:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
RwTexture* CreateRwTextureFromRwImage(RwImage* image)
|
|
|
|
{
|
|
|
|
RwInt32 width, height, depth, flags;
|
|
|
|
RwImageFindRasterFormat(image, 4, &width, &height, &depth, &flags);
|
|
|
|
RwRaster* raster = RwRasterCreate(width, height, depth, flags);
|
|
|
|
RwRasterSetFromImage(raster, image);
|
|
|
|
RwImageDestroy(image);
|
|
|
|
RwTexture* texture = RwTextureCreate(raster);
|
|
|
|
return texture;
|
|
|
|
}
|
|
|
|
|
|
|
|
RwTexture* Util::LoadTextureFromPngFile(fs::path path)
|
|
|
|
{
|
|
|
|
RwImage* image = RtPNGImageRead(path.string().c_str());
|
|
|
|
if (!image)
|
|
|
|
return nullptr;
|
|
|
|
RwTexture* texture = CreateRwTextureFromRwImage(image);
|
|
|
|
path.stem().string().copy(texture->name, sizeof(texture->name) - 1);
|
|
|
|
return texture;
|
2020-12-02 16:19:16 -05:00
|
|
|
}
|