From 85a01272c30b65d3ad23b253c59043952ca374c5 Mon Sep 17 00:00:00 2001 From: nlgxzef <1937572+nlgxzef@users.noreply.github.com> Date: Fri, 14 Jul 2023 14:26:23 +0300 Subject: [PATCH] v4.0.0.805 + Added options to define custom stock parts in the config files. * Fixed dummy skin duplication in Binary step of the installer for the TPKs called TOOLKIT. * Fixed custom heat level multipliers (FECooling) variables in the config files. (Now they are called Attachment0-9 instead of 1-10 like everything else.) + Added options to change the name and icons of the Custom Rims and Vinyl categories. * Presitter now deletes the old preset data before saving new ones. It should fix the issue where the cars get parts from another one. * Allowed randomization of Custom Gauges and their colors. * Fixed an issue where the game crashes while loading the Customize Main screen when TestCareerCustomization is enabled. --- CarCustomizeManager.h | 20 +- CustomizePaint.h | 3 +- CustomizeParts.h | 22 +- CustomizeSub.h | 58 ++++-- NFSMWUnlimiter.vcxproj | 1 + Presitter.h | 47 +++++ RealmcIface_MemcardInterfaceImpl.h | 11 + RideInfo.h | 312 ++++++++++++++++++++++++++++- UnlimiterData/_General.ini | 137 +++++++++++-- UnlimiterStuff.h | 6 +- 10 files changed, 557 insertions(+), 60 deletions(-) create mode 100644 RealmcIface_MemcardInterfaceImpl.h diff --git a/CarCustomizeManager.h b/CarCustomizeManager.h index dbc6d4f..a601401 100644 --- a/CarCustomizeManager.h +++ b/CarCustomizeManager.h @@ -341,43 +341,43 @@ void __fastcall CarCustomizeManager_UpdateHeatOnVehicle(DWORD* CarCustomizeManag if (CustomFECoolingValue != 0.0f) FECareerRecord[3] = FECareerRecord[3] * CustomFECoolingValue * HeatAdjustMultiplier; break; case 52: // ATTACHMENT0 - CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment1", 0.0f); + CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment0", 0.0f); if (CustomFECoolingValue != 0.0f) FECareerRecord[3] = FECareerRecord[3] * CustomFECoolingValue * HeatAdjustMultiplier; break; case 53: // ATTACHMENT1 - CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment2", 0.0f); + CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment1", 0.0f); if (CustomFECoolingValue != 0.0f) FECareerRecord[3] = FECareerRecord[3] * CustomFECoolingValue * HeatAdjustMultiplier; break; case 54: // ATTACHMENT2 - CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment3", 0.0f); + CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment2", 0.0f); if (CustomFECoolingValue != 0.0f) FECareerRecord[3] = FECareerRecord[3] * CustomFECoolingValue * HeatAdjustMultiplier; break; case 55: // ATTACHMENT3 - CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment4", 0.0f); + CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment3", 0.0f); if (CustomFECoolingValue != 0.0f) FECareerRecord[3] = FECareerRecord[3] * CustomFECoolingValue * HeatAdjustMultiplier; break; case 56: // ATTACHMENT4 - CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment5", 0.0f); + CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment4", 0.0f); if (CustomFECoolingValue != 0.0f) FECareerRecord[3] = FECareerRecord[3] * CustomFECoolingValue * HeatAdjustMultiplier; break; case 57: // ATTACHMENT5 - CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment6", 0.0f); + CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment5", 0.0f); if (CustomFECoolingValue != 0.0f) FECareerRecord[3] = FECareerRecord[3] * CustomFECoolingValue * HeatAdjustMultiplier; break; case 58: // ATTACHMENT6 - CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment7", 0.0f); + CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment6", 0.0f); if (CustomFECoolingValue != 0.0f) FECareerRecord[3] = FECareerRecord[3] * CustomFECoolingValue * HeatAdjustMultiplier; break; case 59: // ATTACHMENT7 - CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment8", 0.0f); + CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment7", 0.0f); if (CustomFECoolingValue != 0.0f) FECareerRecord[3] = FECareerRecord[3] * CustomFECoolingValue * HeatAdjustMultiplier; break; case 60: // ATTACHMENT8 - CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment9", 0.0f); + CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment8", 0.0f); if (CustomFECoolingValue != 0.0f) FECareerRecord[3] = FECareerRecord[3] * CustomFECoolingValue * HeatAdjustMultiplier; break; case 61: // ATTACHMENT9 - CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment10", 0.0f); + CustomFECoolingValue = GetCarFloatOption(CarINI, GeneralINI, "FECooling", "Attachment9", 0.0f); if (CustomFECoolingValue != 0.0f) FECareerRecord[3] = FECareerRecord[3] * CustomFECoolingValue * HeatAdjustMultiplier; break; case 43: // DRIVER diff --git a/CustomizePaint.h b/CustomizePaint.h index 99745d6..9f31824 100644 --- a/CustomizePaint.h +++ b/CustomizePaint.h @@ -170,4 +170,5 @@ void __fastcall CustomizePaint_RefreshHeader(DWORD* CustomizePaint, void* EDX_Un } } } -} \ No newline at end of file +} + diff --git a/CustomizeParts.h b/CustomizeParts.h index 9cfbe02..1ea411e 100644 --- a/CustomizeParts.h +++ b/CustomizeParts.h @@ -310,10 +310,24 @@ void __fastcall CustomizeParts_Setup(DWORD* _CustomizeParts, void* EDX_Unused) CarSlotID = 77; CIniReader VinylGroupsINI("UnlimiterData\\_VinylGroups.ini"); - sprintf(VinylBrandID, "Group%d", MenuID - 0x402); - sprintf(VinylBrandIcon, VinylGroupsINI.ReadString(VinylBrandID, "Texture", GetDefaultVinylGroupTexture(MenuID - 0x402))); - sprintf(VinylBrandString, VinylGroupsINI.ReadString(VinylBrandID, "String", GetDefaultVinylGroupString(MenuID - 0x402))); - PartCategory = VinylGroupsINI.ReadInteger(VinylBrandID, "Index", GetDefaultVinylGroupIndex(MenuID - 0x402)); + int i = MenuID - 0x402; + + if (i == 0) + { + sprintf(VinylBrandID, "Group%d", 0); + sprintf(VinylBrandIcon, GetCarTextOption(CarINI, GeneralINI, "Icons", "VisualVinylsCustom", "")); + sprintf(VinylBrandString, GetCarTextOption(CarINI, GeneralINI, "Names", "VisualVinylsCustom", "")); + + if (bStringHash(VinylBrandIcon) == -1) sprintf(VinylBrandIcon, VinylGroupsINI.ReadString(VinylBrandID, "Texture", GetDefaultVinylGroupTexture(0))); + if (bStringHash(VinylBrandString) == -1) sprintf(VinylBrandString, VinylGroupsINI.ReadString(VinylBrandID, "String", GetDefaultVinylGroupString(0))); + } + else + { + sprintf(VinylBrandID, "Group%d", i); + sprintf(VinylBrandIcon, VinylGroupsINI.ReadString(VinylBrandID, "Texture", GetDefaultVinylGroupTexture(i))); + sprintf(VinylBrandString, VinylGroupsINI.ReadString(VinylBrandID, "String", GetDefaultVinylGroupString(i))); + } + PartCategory = VinylGroupsINI.ReadInteger(VinylBrandID, "Index", GetDefaultVinylGroupIndex(i)); PartIconNormal = bStringHash(VinylBrandIcon); _CustomizeParts[87] = bStringHash(VinylBrandString); diff --git a/CustomizeSub.h b/CustomizeSub.h index 97274ef..2313b12 100644 --- a/CustomizeSub.h +++ b/CustomizeSub.h @@ -344,16 +344,25 @@ int __fastcall CustomizeSub_SetupRimBrands(DWORD* _CustomizeSub, void* EDX_Unuse // Add the brands from ini for (int i = 0; i <= RimBrandsCount; i++) { - if (i == 0 && HasNoCustomRims) continue; - sprintf(RimBrandID, "Brand%d", i); - sprintf(RimBrandIcon, RimBrandsINI.ReadString(RimBrandID, "Texture", GetDefaultRimBrandTexture(i))); - sprintf(RimBrandString, RimBrandsINI.ReadString(RimBrandID, "String", GetDefaultRimBrandString(i))); - CustomizeCategoryScreen_AddCustomOption( - _CustomizeSub, - *(char**)g_pCustomizeRimsPkg, - bStringHash(RimBrandIcon), - bStringHash(RimBrandString), - 0x702 + i); + if (i == 0) + { + if (HasNoCustomRims) continue; + + sprintf(RimBrandID, "Brand%d", i); + sprintf(RimBrandIcon, GetCarTextOption(CarINI, GeneralINI, "Icons", "PartsRimsCustom", "")); + sprintf(RimBrandString, GetCarTextOption(CarINI, GeneralINI, "Names", "PartsRimsCustom", "")); + + if (bStringHash(RimBrandIcon) == -1) sprintf(RimBrandIcon, RimBrandsINI.ReadString(RimBrandID, "Texture", GetDefaultRimBrandTexture(i))); + if (bStringHash(RimBrandString) == -1) sprintf(RimBrandString, RimBrandsINI.ReadString(RimBrandID, "String", GetDefaultRimBrandString(i))); + } + else + { + sprintf(RimBrandID, "Brand%d", i); + sprintf(RimBrandIcon, RimBrandsINI.ReadString(RimBrandID, "Texture", GetDefaultRimBrandTexture(i))); + sprintf(RimBrandString, RimBrandsINI.ReadString(RimBrandID, "String", GetDefaultRimBrandString(i))); + } + + CustomizeCategoryScreen_AddCustomOption(_CustomizeSub, *(char**)g_pCustomizeRimsPkg, bStringHash(RimBrandIcon), bStringHash(RimBrandString), 0x702 + i); } ARimPart[0] = SelectablePart_vtable; @@ -1127,16 +1136,25 @@ int __fastcall CustomizeSub_SetupVinylGroups(DWORD* _CustomizeSub, void* EDX_Unu // Add the brands from ini for (int i = 0; i <= VinylGroupsCount; i++) { - if (i == 0 && HasNoCustomVinyls) continue; - sprintf(VinylBrandID, "Group%d", i); - sprintf(VinylBrandIcon, VinylGroupsINI.ReadString(VinylBrandID, "Texture", GetDefaultVinylGroupTexture(i))); - sprintf(VinylBrandString, VinylGroupsINI.ReadString(VinylBrandID, "String", GetDefaultVinylGroupString(i))); - CustomizeCategoryScreen_AddCustomOption( - _CustomizeSub, - *(char**)g_pCustomizePartsPkg, - bStringHash(VinylBrandIcon), - bStringHash(VinylBrandString), - 0x402 + i); + if (i == 0) + { + if (HasNoCustomVinyls) continue; + + sprintf(VinylBrandID, "Group%d", i); + sprintf(VinylBrandIcon, GetCarTextOption(CarINI, GeneralINI, "Icons", "VisualVinylsCustom", "")); + sprintf(VinylBrandString, GetCarTextOption(CarINI, GeneralINI, "Names", "VisualVinylsCustom", "")); + + if (bStringHash(VinylBrandIcon) == -1) sprintf(VinylBrandIcon, VinylGroupsINI.ReadString(VinylBrandID, "Texture", GetDefaultVinylGroupTexture(i))); + if (bStringHash(VinylBrandString) == -1) sprintf(VinylBrandString, VinylGroupsINI.ReadString(VinylBrandID, "String", GetDefaultVinylGroupString(i))); + } + else + { + sprintf(VinylBrandID, "Group%d", i); + sprintf(VinylBrandIcon, VinylGroupsINI.ReadString(VinylBrandID, "Texture", GetDefaultVinylGroupTexture(i))); + sprintf(VinylBrandString, VinylGroupsINI.ReadString(VinylBrandID, "String", GetDefaultVinylGroupString(i))); + } + + CustomizeCategoryScreen_AddCustomOption(_CustomizeSub, *(char**)g_pCustomizePartsPkg, bStringHash(VinylBrandIcon), bStringHash(VinylBrandString), 0x402 + i); } AVinylPart[0] = SelectablePart_vtable; diff --git a/NFSMWUnlimiter.vcxproj b/NFSMWUnlimiter.vcxproj index 077a8ce..1e1c91e 100644 --- a/NFSMWUnlimiter.vcxproj +++ b/NFSMWUnlimiter.vcxproj @@ -122,6 +122,7 @@ copy "$(TargetDir)*.pdb" "G:\Oyunlar\Need for Speed Most Wanted Dirty\scripts" + diff --git a/Presitter.h b/Presitter.h index 9011b41..7c2ea55 100644 --- a/Presitter.h +++ b/Presitter.h @@ -12,6 +12,39 @@ static injector::hook_back hb_SHGetFolderPathA; +void Presitter_Delete(char const* ProfileName) +{ + // Presitter: Delete preset data + char SaveProfilePath[MAX_PATH]; + char PresetPath[MAX_PATH]; + char CarTypeName[CarNameLength]; + char PresetName[PresetNameLength]; + int zero = 0; + + hb_SHGetFolderPathA.fun(0, 0x8005, 0, 0, SaveProfilePath); // Get save profile folder + strcat(SaveProfilePath, "\\NFS Most Wanted"); + strcat(SaveProfilePath, "\\"); + strcat(SaveProfilePath, ProfileName); + strcat(SaveProfilePath, "\\Presets"); + + // Empty the directory + for (int i = 0; i < NumFECustomizationRecords; i++) + { + // Create file handle + sprintf(PresetPath, "%s\\%02d.bin", SaveProfilePath, i); + FILE* PresetFile = fopen(PresetPath, "rb"); + + if (PresetFile) + { + fclose(PresetFile); // Close the file + remove(PresetPath); // Delete the file we just opened + } + } + + // Delete the directory + RemoveDirectoryA(SaveProfilePath); +} + void Presitter_Save(char const* ProfileName) { // Presittter: Dump preset data from customization records next to the game profile @@ -34,6 +67,20 @@ void Presitter_Save(char const* ProfileName) { DWORD* FEDatabase = *(DWORD**)_FEDatabase; + // Delete all files first + for (int i = 0; i < NumFECustomizationRecords; i++) + { + // Create file handle + sprintf(PresetPath, "%s\\%02d.bin", SaveProfilePath, i); + FILE* PresetFile = fopen(PresetPath, "rb"); + + if (PresetFile) + { + fclose(PresetFile); // Close the file + remove(PresetPath); // Delete the file we just opened + } + } + for (int i = 0; i < NumFECarRecords; i++) { // Get car record diff --git a/RealmcIface_MemcardInterfaceImpl.h b/RealmcIface_MemcardInterfaceImpl.h new file mode 100644 index 0000000..b193d91 --- /dev/null +++ b/RealmcIface_MemcardInterfaceImpl.h @@ -0,0 +1,11 @@ +#pragma once + +#include "stdio.h" +#include "InGameFunctions.h" + +static injector::hook_back hb_RealmcIface_MemcardInterfaceImpl_ProcessDelete; +unsigned int __fastcall RealmcIface_MemcardInterfaceImpl_ProcessDelete(DWORD* RealmcIface_MemcardInterfaceImpl, void* EDX_Unused, DWORD* Message) +{ + //Presitter_Delete((char const*)RealmcIface_MemcardInterfaceImpl + 180); + return hb_RealmcIface_MemcardInterfaceImpl_ProcessDelete.fun(RealmcIface_MemcardInterfaceImpl, EDX_Unused, Message); +} \ No newline at end of file diff --git a/RideInfo.h b/RideInfo.h index 4e1de50..5c3c6b4 100644 --- a/RideInfo.h +++ b/RideInfo.h @@ -402,6 +402,285 @@ unsigned int __fastcall RideInfo_SetRandomDecal(DWORD* RideInfo, void* EDX_Unuse return 0; } +DWORD __fastcall RideInfo_GetStockPartNameHash(DWORD* RideInfo, void* EDX_Unused, int CarSlotID) +{ + DWORD result = -1; + + // Check UnlimiterData\\CARNAME.ini for custom stock parts + // Get CarType Info + sprintf(CarTypeName, GetCarTypeName(RideInfo[0])); + sprintf(CarININame, "UnlimiterData\\%s.ini", CarTypeName); + CIniReader CarINI(CarININame); + CIniReader GeneralINI("UnlimiterData\\_General.ini"); + + switch (CarSlotID) + { + case 23: // BODY + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "BodyKits", ""); + break; + case 44: // SPOILER + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Spoilers", ""); + break; + case 66: // FRONT_WHEEL + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "RimsFront", ""); + break; + case 67: // REAR_WHEEL + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "RimsRear", ""); + break; + case 63: // HOOD + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Hoods", ""); + break; + case 62: // ROOF + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "RoofScoops", ""); + break; + case 28: // INTERIOR + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Interior", ""); + break; + case 0: // BASE + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Roof", ""); + break; + case 24: // FRONT_BRAKE + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Brakes", ""); + break; + case 31: // LEFT_HEADLIGHT + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Headlights", ""); + break; + case 29: // LEFT_BRAKELIGHT + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Taillights", ""); + break; + case 33: // LEFT_SIDE_MIRROR + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Mirrors", ""); + break; + case 52: // ATTACHMENT0 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Attachment0", ""); + break; + case 53: // ATTACHMENT1 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Attachment1", ""); + break; + case 54: // ATTACHMENT2 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Attachment2", ""); + break; + case 55: // ATTACHMENT3 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Attachment3", ""); + break; + case 56: // ATTACHMENT4 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Attachment4", ""); + break; + case 57: // ATTACHMENT5 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Attachment5", ""); + break; + case 58: // ATTACHMENT6 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Attachment6", ""); + break; + case 59: // ATTACHMENT7 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Attachment7", ""); + break; + case 60: // ATTACHMENT8 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Attachment8", ""); + break; + case 61: // ATTACHMENT9 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Attachment9", ""); + break; + case 76: // BASE_PAINT + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Paint", ""); + break; + case 77: // VINYL_LAYER0 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Vinyls", ""); + break; + case 78: // PAINT_RIM + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "RimPaint", ""); + break; + case 79: // VINYL_COLOUR0_0 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "VinylColor1", ""); + break; + case 80: // VINYL_COLOUR0_1 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "VinylColor2", ""); + break; + case 81: // VINYL_COLOUR0_2 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "VinylColor3", ""); + break; + case 82: // VINYL_COLOUR0_3 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "VinylColor4", ""); + break; + case 83: // DECAL_FRONT_WINDOW_TEX0 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsWindshield1", ""); + break; + case 84: // DECAL_FRONT_WINDOW_TEX1 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsWindshield2", ""); + break; + case 85: // DECAL_FRONT_WINDOW_TEX2 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsWindshield3", ""); + break; + case 86: // DECAL_FRONT_WINDOW_TEX3 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsWindshield4", ""); + break; + case 87: // DECAL_FRONT_WINDOW_TEX4 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsWindshield5", ""); + break; + case 88: // DECAL_FRONT_WINDOW_TEX5 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsWindshield6", ""); + break; + case 89: // DECAL_FRONT_WINDOW_TEX6 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsWindshield7", ""); + break; + case 90: // DECAL_FRONT_WINDOW_TEX7 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsWindshield8", ""); + break; + case 91: // DECAL_REAR_WINDOW_TEX0 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRearWindow1", ""); + break; + case 92: // DECAL_REAR_WINDOW_TEX1 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRearWindow2", ""); + break; + case 93: // DECAL_REAR_WINDOW_TEX2 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRearWindow3", ""); + break; + case 94: // DECAL_REAR_WINDOW_TEX3 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRearWindow4", ""); + break; + case 95: // DECAL_REAR_WINDOW_TEX4 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRearWindow5", ""); + break; + case 96: // DECAL_REAR_WINDOW_TEX5 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRearWindow6", ""); + break; + case 97: // DECAL_REAR_WINDOW_TEX6 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRearWindow7", ""); + break; + case 98: // DECAL_REAR_WINDOW_TEX7 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRearWindow8", ""); + break; + case 99: // DECAL_LEFT_DOOR_TEX0 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsLeftDoor1", ""); + break; + case 100: // DECAL_LEFT_DOOR_TEX1 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsLeftDoor2", ""); + break; + case 101: // DECAL_LEFT_DOOR_TEX2 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsLeftDoor3", ""); + break; + case 102: // DECAL_LEFT_DOOR_TEX3 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsLeftDoor4", ""); + break; + case 103: // DECAL_LEFT_DOOR_TEX4 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsLeftDoor5", ""); + break; + case 104: // DECAL_LEFT_DOOR_TEX5 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsLeftDoor6", ""); + break; + case 105: // DECAL_LEFT_DOOR_TEX6 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsLeftDoor7", ""); + break; + case 106: // DECAL_LEFT_DOOR_TEX7 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsLeftDoor8", ""); + break; + case 107: // DECAL_RIGHT_DOOR_TEX0 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRightDoor1", ""); + break; + case 108: // DECAL_RIGHT_DOOR_TEX1 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRightDoor2", ""); + break; + case 109: // DECAL_RIGHT_DOOR_TEX2 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRightDoor3", ""); + break; + case 110: // DECAL_RIGHT_DOOR_TEX3 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRightDoor4", ""); + break; + case 111: // DECAL_RIGHT_DOOR_TEX4 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRightDoor5", ""); + break; + case 112: // DECAL_RIGHT_DOOR_TEX5 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRightDoor6", ""); + break; + case 113: // DECAL_RIGHT_DOOR_TEX6 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRightDoor7", ""); + break; + case 114: // DECAL_RIGHT_DOOR_TEX7 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRightDoor8", ""); + break; + case 115: // DECAL_LEFT_QUARTER_TEX0 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsLeftQuarter1", ""); + break; + case 116: // DECAL_LEFT_QUARTER_TEX1 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsLeftQuarter2", ""); + break; + case 117: // DECAL_LEFT_QUARTER_TEX2 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsLeftQuarter3", ""); + break; + case 118: // DECAL_LEFT_QUARTER_TEX3 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsLeftQuarter4", ""); + break; + case 119: // DECAL_LEFT_QUARTER_TEX4 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsLeftQuarter5", ""); + break; + case 120: // DECAL_LEFT_QUARTER_TEX5 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsLeftQuarter6", ""); + break; + case 121: // DECAL_LEFT_QUARTER_TEX6 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsLeftQuarter7", ""); + break; + case 122: // DECAL_LEFT_QUARTER_TEX7 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsLeftQuarter8", ""); + break; + case 123: // DECAL_RIGHT_QUARTER_TEX0 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRightQuarter1", ""); + break; + case 124: // DECAL_RIGHT_QUARTER_TEX1 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRightQuarter2", ""); + break; + case 125: // DECAL_RIGHT_QUARTER_TEX2 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRightQuarter3", ""); + break; + case 126: // DECAL_RIGHT_QUARTER_TEX3 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRightQuarter4", ""); + break; + case 127: // DECAL_RIGHT_QUARTER_TEX4 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRightQuarter5", ""); + break; + case 128: // DECAL_RIGHT_QUARTER_TEX5 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRightQuarter6", ""); + break; + case 129: // DECAL_RIGHT_QUARTER_TEX6 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRightQuarter7", ""); + break; + case 130: // DECAL_RIGHT_QUARTER_TEX7 + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "DecalsRightQuarter8", ""); + break; + case 131: // WINDOW_TINT + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "WindowTint", ""); + break; + case 132: // CUSTOM_HUD + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "CustomGauges", ""); + break; + case 133: // HUD_BACKING_COLOUR + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "CustomGaugesBackingColor", ""); + break; + case 134: // HUD_NEEDLE_COLOUR + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "CustomGaugesNeedleColor", ""); + break; + case 135: // HUD_CHARACTER_COLOUR + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "CustomGaugesCharacterColor", ""); + break; + case 43: // DRIVER + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Driver", ""); + break; + case 69: // LICENSE_PLATE + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "LicensePlate", ""); + break; + case 64: // HEADLIGHT (Tires) + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Tires", ""); + break; + case 65: // BRAKELIGHT (Neon) + result = GetCarTextOptionHash(CarINI, GeneralINI, "StockParts", "Neon", ""); + break; + default: + result = -1; + break; + } + + return result; +} + void __fastcall RideInfo_SetStockParts(DWORD* TheRideInfo, void* EDX_Unused) { DWORD PartNameHash; // eax MAPDST @@ -441,11 +720,11 @@ void __fastcall RideInfo_SetStockParts(DWORD* TheRideInfo, void* EDX_Unused) PartNameHash = bStringHash("ROOF_STYLE00"); goto ApplyPart; break; - + /* case 64: // HEADLIGHT (Tires) PartNameHash = bStringHash("TIRE_STYLE01"); goto ApplyPart; - break; + break;*/ case 65: // BRAKELIGHT (Neon) PartNameHash = bStringHash("NEON_NONE"); @@ -473,6 +752,15 @@ void __fastcall RideInfo_SetStockParts(DWORD* TheRideInfo, void* EDX_Unused) } } // else: No need to assign, RideInfo inits them with 0 + + // Check if ini has a custom stock part + PartNameHash = RideInfo_GetStockPartNameHash(TheRideInfo, EDX_Unused, CarSlotID); + if (PartNameHash != -1) // apply the part + { + TheCarPart = CarPartDatabase_NewGetCarPart((DWORD*)_CarPartDB, CarType, CarSlotID, PartNameHash, 0, -1); + if (TheCarPart) RideInfo_SetPart(TheRideInfo, EDX_Unused, CarSlotID, TheCarPart, 1); + else RideInfo_SetUpgradePart(TheRideInfo, CarSlotID, 0); + } } VinylColorSlotID = 79; // VINYL_COLOUR0_0 @@ -480,8 +768,12 @@ void __fastcall RideInfo_SetStockParts(DWORD* TheRideInfo, void* EDX_Unused) NumVinylLayers = 4; do { - TheCarPart = CarPartDatabase_NewGetCarPart((DWORD*)_CarPartDB, CarType, VinylColorSlotID, *VinylColorRef, 0, -1); - RideInfo_SetPart(TheRideInfo, EDX_Unused, VinylColorSlotID, TheCarPart, 1); + PartNameHash = RideInfo_GetStockPartNameHash(TheRideInfo, EDX_Unused, VinylColorSlotID); + if (PartNameHash == -1) + { + TheCarPart = CarPartDatabase_NewGetCarPart((DWORD*)_CarPartDB, CarType, VinylColorSlotID, *VinylColorRef, 0, -1); + RideInfo_SetPart(TheRideInfo, EDX_Unused, VinylColorSlotID, TheCarPart, 1); + } ++VinylColorRef; ++VinylColorSlotID; --NumVinylLayers; @@ -603,6 +895,10 @@ void __fastcall RideInfo_SetRandomParts(DWORD* RideInfo, void* EDX_Unused) if (GetCarIntOption(CarINI, GeneralINI, "RandomParts", "DecalsRightQuarter6", 0) != 0) RideInfo_SetRandomDecal(RideInfo, EDX_Unused, 128, -1); // DECAL_RIGHT_QUARTER_TEX5 if (GetCarIntOption(CarINI, GeneralINI, "RandomParts", "DecalsRightQuarter7", 0) != 0) RideInfo_SetRandomDecal(RideInfo, EDX_Unused, 129, -1); // DECAL_RIGHT_QUARTER_TEX6 if (GetCarIntOption(CarINI, GeneralINI, "RandomParts", "DecalsRightQuarter8", 0) != 0) RideInfo_SetRandomDecal(RideInfo, EDX_Unused, 130, -1); // DECAL_RIGHT_QUARTER_TEX7 + if (GetCarIntOption(CarINI, GeneralINI, "RandomParts", "CustomGauges", 0) != 0) RideInfo_SetRandomPart(RideInfo, 132, -1); // CUSTOM_HUD + if (GetCarIntOption(CarINI, GeneralINI, "RandomParts", "CustomGaugesBackingColor", 0) != 0) RideInfo_SetRandomPart(RideInfo, 133, -1); // HUD_BACKING_COLOUR + if (GetCarIntOption(CarINI, GeneralINI, "RandomParts", "CustomGaugesNeedleColor", 0) != 0) RideInfo_SetRandomPart(RideInfo, 134, -1); // HUD_NEEDLE_COLOUR + if (GetCarIntOption(CarINI, GeneralINI, "RandomParts", "CustomGaugesCharacterColor", 0) != 0) RideInfo_SetRandomPart(RideInfo, 135, -1); // HUD_CHARACTER_COLOUR if (GetCarIntOption(CarINI, GeneralINI, "RandomParts", "Driver", 0) != 0) RideInfo_SetRandomPart(RideInfo, 43, -1); // DRIVER if (GetCarIntOption(CarINI, GeneralINI, "RandomParts", "LicensePlate", 0) != 0) RideInfo_SetRandomPart(RideInfo, 69, -1); // LICENSE_PLATE if (GetCarIntOption(CarINI, GeneralINI, "RandomParts", "Tires", 0) != 0) RideInfo_SetRandomPart(RideInfo, 64, -1); // HEADLIGHT @@ -678,6 +974,14 @@ void __fastcall RideInfo_SetRandomParts(DWORD* RideInfo, void* EDX_Unused) RideInfo_SetRandomDecal(RideInfo, EDX_Unused, 128, -1); // DECAL_RIGHT_QUARTER_TEX5 RideInfo_SetRandomDecal(RideInfo, EDX_Unused, 129, -1); // DECAL_RIGHT_QUARTER_TEX6 RideInfo_SetRandomDecal(RideInfo, EDX_Unused, 130, -1); // DECAL_RIGHT_QUARTER_TEX7 + // Gauges + if (GetCarIntOption(CarINI, GeneralINI, "Visual", "CustomGauges", 1) != 0) + { + RideInfo_SetRandomPart(RideInfo, 132, -1); // CUSTOM_HUD + RideInfo_SetRandomPart(RideInfo, 133, -1); // HUD_BACKING_COLOUR + RideInfo_SetRandomPart(RideInfo, 134, -1); // HUD_NEEDLE_COLOUR + RideInfo_SetRandomPart(RideInfo, 135, -1); // HUD_CHARACTER_COLOUR + } case 3: // Unlimiter parts diff --git a/UnlimiterData/_General.ini b/UnlimiterData/_General.ini index 271b8cd..e7c7fb5 100644 --- a/UnlimiterData/_General.ini +++ b/UnlimiterData/_General.ini @@ -66,6 +66,7 @@ Parts = BROWSER_PARTS PartsBodyKits = VISUAL_PART_BODY PartsSpoilers = VISUAL_PART_SPOILER PartsRims = VISUAL_PART_RIMS +PartsRimsCustom = PartsHoods = VISUAL_PART_HOOD PartsHoodsCF = VISUAL_PART_HOOD_CARBON PartsRoofScoops = VISUAL_PART_ROOF_SCOOP @@ -99,6 +100,7 @@ PerformanceSupercharger = PERFORMANCE_SUPERCHARGER Visual = BROWSER_VISUAL VisualPaint = PAINT_MOD_BASE VisualVinyls = VISUAL_PART_VINYL +VisualVinylsCustom = VisualRimPaint = PAINT_MOD_PART_RIMS VisualWindowTint = VISUAL_PART_WINDOW_TINTING VisualDecals = VISUAL_PART_DECALS @@ -336,6 +338,7 @@ PartsBodyKits = CO_BODY_KITS PartsSpoilers = CO_SPOILERS PartsRims = CO_RIMS PartsRimsBrand = CO_RIM_BRAND +PartsRimsCustom = PartsHoods = CO_HOODS PartsRoofScoops = CO_ROOF_SCOOPS PartsInterior = CO_INTERIOR @@ -367,6 +370,7 @@ PerformanceSupercharger = CO_SUPERCHARGER Visual = CO_VISUAL VisualPaint = CO_PAINT VisualVinyls = CO_VINYLS +VisualVinylsCustom = VisualVinylsGroup = CO_VINYL_STYLE VisualRimPaint = CO_RIM_PAINT VisualWindowTint = CO_WINDOW_TINT @@ -582,6 +586,94 @@ PerformanceSuperchargerLevel2Item1 = PD_SUPERCHARGER_2_1 // Stage 2 S PerformanceSuperchargerLevel3Item1 = PD_SUPERCHARGER_3_1 // Stage 3 Supercharger PerformanceSuperchargerJunkmanItem = PD_SUPERCHARGER_JUNKMAN // Custom Supercharger +[StockParts] // Specify a part name (for example: CARNAME_BODY_KIT03) if you want to use it instead of the stock one +BodyKits = +Spoilers = +RimsFront = +RimsRear = +Hoods = +RoofScoops = +Interior = +Roof = +Brakes = +Headlights = +Taillights = +Mirrors = +Attachment0 = +Attachment1 = +Attachment2 = +Attachment3 = +Attachment4 = +Attachment5 = +Attachment6 = +Attachment7 = +Attachment8 = +Attachment9 = +Paint = +Vinyls = +VinylColor1 = +VinylColor2 = +VinylColor3 = +VinylColor4 = +RimPaint = +WindowTint = +DecalsWindshield1 = +DecalsWindshield2 = +DecalsWindshield3 = +DecalsWindshield4 = +DecalsWindshield5 = +DecalsWindshield6 = +DecalsWindshield7 = +DecalsWindshield8 = +DecalsRearWindow1 = +DecalsRearWindow2 = +DecalsRearWindow3 = +DecalsRearWindow4 = +DecalsRearWindow5 = +DecalsRearWindow6 = +DecalsRearWindow7 = +DecalsRearWindow8 = +DecalsLeftDoor1 = +DecalsLeftDoor2 = +DecalsLeftDoor3 = +DecalsLeftDoor4 = +DecalsLeftDoor5 = +DecalsLeftDoor6 = +DecalsLeftDoor7 = +DecalsLeftDoor8 = +DecalsRightDoor1 = +DecalsRightDoor2 = +DecalsRightDoor3 = +DecalsRightDoor4 = +DecalsRightDoor5 = +DecalsRightDoor6 = +DecalsRightDoor7 = +DecalsRightDoor8 = +DecalsLeftQuarter1 = +DecalsLeftQuarter2 = +DecalsLeftQuarter3 = +DecalsLeftQuarter4 = +DecalsLeftQuarter5 = +DecalsLeftQuarter6 = +DecalsLeftQuarter7 = +DecalsLeftQuarter8 = +DecalsRightQuarter1 = +DecalsRightQuarter2 = +DecalsRightQuarter3 = +DecalsRightQuarter4 = +DecalsRightQuarter5 = +DecalsRightQuarter6 = +DecalsRightQuarter7 = +DecalsRightQuarter8 = +CustomGauges = +CustomGaugesBackingColor = +CustomGaugesNeedleColor = +CustomGaugesCharacterColor = +Driver = +LicensePlate = +Tires = +Neon = + [RandomParts] ForceCustomizationLevel = -2 // Forces a customization level for part randomization. (-2 (Default), -1, 0-4) // -2 = Random customization level (0-4) @@ -665,6 +757,10 @@ DecalsRightQuarter5 = 0 // {DECAL} + {CARNAME} CARNAME_(KITxx_)DECAL_RIG DecalsRightQuarter6 = 0 // {DECAL} + {CARNAME} CARNAME_(KITxx_)DECAL_RIGHT_QUARTER DecalsRightQuarter7 = 0 // {DECAL} + {CARNAME} CARNAME_(KITxx_)DECAL_RIGHT_QUARTER DecalsRightQuarter8 = 0 // {DECAL} + {CARNAME} CARNAME_(KITxx_)DECAL_RIGHT_QUARTER +CustomGauges = 0 // {CUSTOM_HUDS} (Textures: Global\HUDS_Global_[00-10].bin, HUDTextures.tpk / GLOBAL\GlobalB.lzc, GlobalTextures.tpk) +CustomGaugesBackingColor = 0 // {CUSTOM_HUD_PAINT} +CustomGaugesNeedleColor = 0 // {CUSTOM_HUD_PAINT} +CustomGaugesCharacterColor = 0 // {CUSTOM_HUD_PAINT} Driver = 0 // {CARNAME} CARNAME_(STYLExx_)STYLExx_DRIVER LicensePlate = 0 // {PLATES} (Attribute: TEXTURE_NAME) (Textures: GLOBAL\GlobalB.lzc, GlobalTextures.tpk) Tires = 0 // {EXTRA} (Attribute: TEXTURE_NAME) (Textures: GLOBAL\GlobalB.lzc, GlobalTextures.tpk) @@ -676,28 +772,29 @@ Spoilers = 0.0 // (Default = 0.9) Rims = 0.0 // (Default = 0.95) Hoods = 0.0 // (Default = 0.9) RoofScoops = 0.0 // (Default = 0.97) -Interior = 0.98 // -Roof = 0.75 // -Brakes = 0.98 // -Headlights = 0.9 // -Taillights = 0.9 // -Mirrors = 0.9 // -Attachment1 = 0.95 // -Attachment2 = 0.95 // -Attachment3 = 0.95 // -Attachment4 = 0.95 // -Attachment5 = 0.95 // -Attachment6 = 0.95 // -Attachment7 = 0.95 // -Attachment8 = 0.95 // -Attachment9 = 0.95 // -Attachment10 = 0.95 // +Interior = 0.98 +Roof = 0.75 +Brakes = 0.98 +Headlights = 0.9 +Taillights = 0.9 +Mirrors = 0.9 +Attachment0 = 0.95 +Attachment1 = 0.95 +Attachment2 = 0.95 +Attachment3 = 0.95 +Attachment4 = 0.95 +Attachment5 = 0.95 +Attachment6 = 0.95 +Attachment7 = 0.95 +Attachment8 = 0.95 +Attachment9 = 0.95 Paint = 0.0 // (Default = 0.7) Vinyls = 0.0 // (Default = 0.75) RimPaint = 0.0 // (Default = 0.97) WindowTint = 0.0 // (Default = 0.99) Decals = 0.0 // (Default = 0.98) (Also valid for numbers) -Driver = 0.9 // -LicensePlate = 0.75 // -Tires = 0.99 // -Neon = 0.95 // +Driver = 0.9 +LicensePlate = 0.75 +Tires = 0.99 +Neon = 0.95 + diff --git a/UnlimiterStuff.h b/UnlimiterStuff.h index d2757a5..e59e200 100644 --- a/UnlimiterStuff.h +++ b/UnlimiterStuff.h @@ -41,6 +41,7 @@ bool ManuHook, ExtraCustomization, DisappearingWheelsFix, SecondaryLogoFix, Expa #include "Presitter.h" #include "UserProfile.h" #include "MemcardCallbacks.h" +#include "RealmcIface_MemcardInterfaceImpl.h" #include "Game.h" #include "Helpers.h" #include "CodeCaves.h" @@ -448,7 +449,7 @@ int Init() { injector::WriteMemory(g_bTestCareerCustomization, 1, true); injector::MakeJMP(0x7BABDD, 0x7BAC6D, true); // CarCustomizeManager::Checkout (Don't deduct user's cash) - injector::MakeJMP(0x7BB594, 0x7BB5C8, true); // CustomizeCategoryScreen::AddCustomOption (Ignore backroom parts without markers) + injector::WriteMemory(0x7BB594, 0xEB, true); // CustomizeCategoryScreen::AddCustomOption (Ignore backroom parts without markers) injector::WriteMemory(0x7B0185, 0xEB, true); // CustomizeShoppingCart::CanCheckout (Allow checkout when there isn't enough cash) } @@ -466,6 +467,9 @@ int Init() injector::MakeCALL(0x5ACDEB, UserProfile_LoadFromBuffer, true); // cFrontendDatabase::LoadUserProfileFromBuffer injector::MakeCALL(0x5ACE01, UserProfile_LoadFromBuffer, true); // cFrontendDatabase::LoadUserProfileFromBuffer hb_UserProfile_LoadFromBuffer.fun = injector::MakeCALL(0x5ACE74, UserProfile_LoadFromBuffer, true).get(); // cFrontendDatabase::RestoreFromBackupDB + + // Deleting (todo: make it delete after asking) + //hb_RealmcIface_MemcardInterfaceImpl_ProcessDelete.fun = injector::MakeCALL(0x7F5BB1, RealmcIface_MemcardInterfaceImpl_ProcessDelete, true).get(); // RealmcIface::MemcardInterfaceImpl::Update } // Car Skin Fix (Requires CarSkinCount (20) x dummy skin and wheel textures in CARS\TEXTURES.BIN)