EnginePerks: rewritten and expanded

- Got rid of unused and repeated code
- Added all perk skill bonuses
This commit is contained in:
phobos2077
2023-07-30 19:58:34 +02:00
parent c95d872f77
commit cd5c803386
3 changed files with 143 additions and 146 deletions
+61 -2
View File
@@ -34,9 +34,10 @@ VaultCityInoculationsRadBonus=10
;999 - maximum bonus, 10 - default bonus ;999 - maximum bonus, 10 - default bonus
DemolitionExpertBonus=10 DemolitionExpertBonus=10
;Changes the damage bonus for 'Living Anatomy' perk (ID 97) ;Changes the damage bonus and Doctor Skill for 'Living Anatomy' perk (ID 97)
;125 - maximum bonus, 5 - default bonus ;125 - maximum bonus, 5 - default bonus, 10 - default skill bonus
LivingAnatomyBonus=5 LivingAnatomyBonus=5
LivingAnatomyDoctorBonus=10
;Changes the damage bonus for 'Pyromaniac' perk (ID 101) ;Changes the damage bonus for 'Pyromaniac' perk (ID 101)
;125 - maximum bonus, 5 - default bonus ;125 - maximum bonus, 5 - default bonus
@@ -54,6 +55,64 @@ StonewallPercent=50
;0 - no bonus, 10 - maximum bonus, 3 - default bonus ;0 - no bonus, 10 - maximum bonus, 3 - default bonus
WeaponHandlingBonus=3 WeaponHandlingBonus=3
;Changes the Skill bonuses for 'Medic' perk (ID 32)
;125 - maximum bonus, 10 - default bonus
MedicFirstAidBonus=10
MedicDoctorBonus=10
;Changes the Skill bonuses for 'Vault City Training' perk (ID 107)
;125 - maximum bonus, 5 - default bonus
VaultCityTrainingFirstAidBonus=5
VaultCityTrainingDoctorBonus=5
;Changes the Sneak skill bonus for 'Ghost' perk (ID 38)
;125 - maximum bonus, 20 - default bonus
GhostSneakBonus=20
;Changes the Lockpick, Steal and Traps skill bonus for 'Thief' perk (ID 105)
;125 - maximum bonus, 10 - default bonus
ThiefSkillsBonus=10
;Changes the Lockpick and Steal skill bonus for 'Master Thief' perk (ID 3)
;125 - maximum bonus, 15 - default bonus
MasterThiefSkillsBonus=15
;Changes the Steal skill bonus for 'Harmless' perk (ID 91)
;125 - maximum bonus, 20 - default bonus
HarmlessStealBonus=20
;Changes the Speech skill bonus for 'Speaker' perk (ID 34)
;125 - maximum bonus, 20 - default bonus
SpeakerSpeechBonus=20
;Changes the Speech skill bonus for 'Expert Excrement Expeditor' perk (ID 116)
;125 - maximum bonus, 5 - default bonus
ExpertExcrementExpeditorSpeechBonus=5
;Changes the Speech and Barter skill bonus for 'Negotiator' perk (ID 99)
;125 - maximum bonus, 10 - default bonus
NegotiatorSkillsBonus=10
;Changes the Barter skill bonus for 'Salesman' perk (ID 103)
;125 - maximum bonus, 20 - default bonus
SalesmanBarterBonus=20
;Changes the Gambling skill bonus for 'Gambler' perk (ID 83)
;125 - maximum bonus, 20 - default bonus
GamblerGamblingBonus=20
;Changes the Outdoorsman skill bonus for 'Ranger' perk (ID 47)
;125 - maximum bonus, 15 - default bonus
RangerOutdoorsmanBonus=15
;Changes the Outdoorsman skill bonus for 'Survivalist' perk (ID 16)
;125 - maximum bonus, 25 - default bonus
SurvivalistOutdoorsmanBonus=25
;Changes the Science and Repair skill bonus for 'Mr.Fixit' perk (ID 31)
;125 - maximum bonus, 10 - default bonus
MrFixitSkillsBonus=10
;############################################################################## ;##############################################################################
[Perks] [Perks]
;Set to 1 to enable the modifications for perks ;Set to 1 to enable the modifications for perks
+75 -144
View File
@@ -17,6 +17,7 @@
*/ */
#include "..\..\main.h" #include "..\..\main.h"
#include "..\..\Utils.h"
#include "..\..\FalloutEngine\Fallout2.h" #include "..\..\FalloutEngine\Fallout2.h"
#include "EnginePerks.h" #include "EnginePerks.h"
@@ -26,120 +27,39 @@ namespace sfall
namespace perk namespace perk
{ {
static class EnginePerkBonus { static long SalesmanBonus;
public: static long DemolitionExpertBonus;
long WeaponScopeRangePenalty = 8;
long WeaponScopeRangeBonus = 5;
long WeaponLongRangeBonus = 4;
long WeaponAccurateBonus = 20;
long WeaponHandlingBonus = 3;
float MasterTraderBonus = 25; static bool TryGetModifiedInt(const char* key, int defaultValue, int& outValue, const char* perksFile) {
long SalesmanBonus = 20; outValue = IniReader::GetInt("PerksTweak", key, defaultValue, perksFile);
return outValue != defaultValue;
}
long LivingAnatomyBonus = 5; static void TryPatchValue8(const char* key, int defaultValue, int minValue, int maxValue, DWORD addr, const char* perksFile) {
long PyromaniacBonus = 5; int value;
if (TryGetModifiedInt(key, defaultValue, value, perksFile) && value >= minValue) {
long StonewallPercent = 50; SafeWrite8(addr, static_cast<BYTE>(min(value, maxValue)));
long DemolitionExpertBonus = 10;
long VaultCityInoculationsPoisonBonus = 10;
long VaultCityInoculationsRadBonus = 10;
///////////////////////////////////////////
void setWeaponScopeRangePenalty(long value) {
if (value < 0) return;
WeaponScopeRangePenalty = value;
SafeWrite32(0x42448E, value);
} }
}
void setWeaponScopeRangeBonus(long value) { static void TryPatchValue32(const char* key, int defaultValue, int minValue, int maxValue, DWORD addr, const char* perksFile) {
if (value < 2) return; int value;
WeaponScopeRangeBonus = value; if (TryGetModifiedInt(key, defaultValue, value, perksFile) && value >= minValue) {
SafeWrite32(0x424489, value); SafeWrite32(addr, min(value, maxValue));
} }
}
void setWeaponLongRangeBonus(long value) { static void TryPatchSkillBonus8(const char* key, int defaultValue, DWORD addr, const char* perksFile) {
if (value < 2) return; TryPatchValue8(key, defaultValue, 0, 125, addr, perksFile);
WeaponLongRangeBonus = value; }
SafeWrite32(0x424474, value);
}
void setWeaponAccurateBonus(long value) { static void TryPatchSkillBonus32(const char* key, int defaultValue, DWORD addr, const char* perksFile) {
if (value < 0) return; TryPatchValue32(key, defaultValue, 0, 125, addr, perksFile);
WeaponAccurateBonus = value; }
if (WeaponAccurateBonus > 125) WeaponAccurateBonus = 125;
SafeWrite8(0x42465D, static_cast<BYTE>(WeaponAccurateBonus));
}
void setWeaponHandlingBonus(long value) {
if (value < 0) return;
WeaponHandlingBonus = value;
if (WeaponHandlingBonus > 10) WeaponHandlingBonus = 10;
SafeWrite8(0x424636, static_cast<char>(WeaponHandlingBonus));
SafeWrite8(0x4251CE, static_cast<signed char>(-WeaponHandlingBonus));
}
void setMasterTraderBonus(long value) {
if (value < 0) return;
MasterTraderBonus = static_cast<float>(value);
SafeWrite32(0x474BB3, *(DWORD*)&MasterTraderBonus); // write float data
}
void setSalesmanBonus(long value) {
if (value < 0) return;
SalesmanBonus = value;
if (SalesmanBonus > 999) SalesmanBonus = 999;
}
void setLivingAnatomyBonus(long value) {
if (value < 0) return;
LivingAnatomyBonus = value;
if (LivingAnatomyBonus > 125) LivingAnatomyBonus = 125;
SafeWrite8(0x424A91, static_cast<BYTE>(LivingAnatomyBonus));
}
void setPyromaniacBonus(long value) {
if (value < 0) return;
PyromaniacBonus = value;
if (PyromaniacBonus > 125) PyromaniacBonus = 125;
SafeWrite8(0x424AB6, static_cast<BYTE>(PyromaniacBonus));
}
void setStonewallPercent(long value) {
if (value < 0) return;
StonewallPercent = value;
if (StonewallPercent > 100) StonewallPercent = 100;
SafeWrite8(0x424B50, static_cast<BYTE>(StonewallPercent));
}
void setDemolitionExpertBonus(long value) {
if (value < 0) return;
DemolitionExpertBonus = value;
if (DemolitionExpertBonus > 999) DemolitionExpertBonus = 999;
}
void setVaultCityInoculationsPoisonBonus(long value) {
if (value < -100) value = -100;
if (value > 100) value = 100;
VaultCityInoculationsPoisonBonus = value;
SafeWrite8(0x4AF26A, static_cast<signed char>(VaultCityInoculationsPoisonBonus));
}
void setVaultCityInoculationsRadBonus(long value) {
if (value < -100) value = -100;
if (value > 100) value = 100;
VaultCityInoculationsRadBonus = value;
SafeWrite8(0x4AF287, static_cast<signed char>(VaultCityInoculationsRadBonus));
}
} perks;
static void __declspec(naked) perk_adjust_skill_hack_salesman() { static void __declspec(naked) perk_adjust_skill_hack_salesman() {
__asm { __asm {
imul eax, [perks.SalesmanBonus]; imul eax, [SalesmanBonus];
add ecx, eax; // barter_skill + (perkLevel * SalesmanBonus) add ecx, eax; // barter_skill + (perkLevel * SalesmanBonus)
mov eax, ecx mov eax, ecx
retn; retn;
@@ -148,7 +68,7 @@ static void __declspec(naked) perk_adjust_skill_hack_salesman() {
static void __declspec(naked) queue_explode_exit_hack_demolition_expert() { static void __declspec(naked) queue_explode_exit_hack_demolition_expert() {
__asm { __asm {
imul eax, [perks.DemolitionExpertBonus]; imul eax, [DemolitionExpertBonus];
add ecx, eax; // maxBaseDmg + (perkLevel * DemolitionExpertBonus) add ecx, eax; // maxBaseDmg + (perkLevel * DemolitionExpertBonus)
add ebx, eax // minBaseDmg + (perkLevel * DemolitionExpertBonus) add ebx, eax // minBaseDmg + (perkLevel * DemolitionExpertBonus)
retn; retn;
@@ -156,48 +76,59 @@ static void __declspec(naked) queue_explode_exit_hack_demolition_expert() {
} }
void EnginePerkBonusInit() { void EnginePerkBonusInit() {
// Allows the current perk level to affect the calculation of its bonus value
MakeCall(0x496F5E, perk_adjust_skill_hack_salesman);
MakeCall(0x4A289C, queue_explode_exit_hack_demolition_expert, 1);
} }
void ReadPerksBonuses(const char* perksFile) { void ReadPerksBonuses(const char* perksFile) {
int wScopeRangeMod = IniReader::GetInt("PerksTweak", "WeaponScopeRangePenalty", 8, perksFile); int value;
if (wScopeRangeMod != 8) perks.setWeaponScopeRangePenalty(wScopeRangeMod); TryPatchValue32("WeaponScopeRangePenalty", 8, 0, 100, 0x42448E, perksFile);
wScopeRangeMod = IniReader::GetInt("PerksTweak", "WeaponScopeRangeBonus", 5, perksFile); TryPatchValue32("WeaponScopeRangeBonus", 5, 2, 100, 0x424489, perksFile);
if (wScopeRangeMod != 5) perks.setWeaponScopeRangeBonus(wScopeRangeMod); TryPatchValue32("WeaponLongRangeBonus", 4, 2, 100, 0x424474, perksFile);
TryPatchSkillBonus8("WeaponAccurateBonus", 20, 0x42465D, perksFile);
if (TryGetModifiedInt("WeaponHandlingBonus", 3, value, perksFile) && value >= 0) {
if (value > 10) value = 10;
SafeWrite8(0x424636, static_cast<char>(value));
SafeWrite8(0x4251CE, static_cast<signed char>(-value));
}
if (TryGetModifiedInt("MasterTraderBonus", 25, value, perksFile) && value >= 0) {
float floatValue = static_cast<float>(value);
SafeWrite32(0x474BB3, *(DWORD*)&floatValue); // write float data
}
if (TryGetModifiedInt("SalesmanBonus", 20, value, perksFile) && value >= 0) {
SalesmanBonus = min(value, 999);
// Allows the current perk level to affect the calculation of its bonus value
MakeCall(0x496F5E, perk_adjust_skill_hack_salesman);
}
TryPatchSkillBonus8("LivingAnatomyBonus", 5, 0x424A91, perksFile);
TryPatchSkillBonus8("LivingAnatomyDoctorBonus", 10, 0x496E66, perksFile);
TryPatchSkillBonus8("PyromaniacBonus", 5, 0x424AB6, perksFile);
TryPatchValue8("StonewallPercent", 50, 0, 100, 0x424B50, perksFile);
if (TryGetModifiedInt("DemolitionExpertBonus", 10, value, perksFile) && value >= 0) {
DemolitionExpertBonus = min(value, 999);
MakeCall(0x4A289C, queue_explode_exit_hack_demolition_expert, 1);
}
if (TryGetModifiedInt("VaultCityInoculationsPoisonBonus", 10, value, perksFile)) {
SafeWrite8(0x4AF26A, static_cast<signed char>(clamp<long>(value, -100, 100)));
}
if (TryGetModifiedInt("VaultCityInoculationsRadBonus", 10, value, perksFile)) {
SafeWrite8(0x4AF287, static_cast<signed char>(clamp<long>(value, -100, 100)));
}
TryPatchSkillBonus8("VaultCityTrainingFirstAidBonus", 5, 0x496E35, perksFile);
TryPatchSkillBonus8("VaultCityTrainingDoctorBonus", 5, 0x496E7F, perksFile);
TryPatchSkillBonus32("MedicFirstAidBonus", 10, 0x496E19, perksFile);
TryPatchSkillBonus32("MedicDoctorBonus", 10, 0x496E4E, perksFile);
int wLongRangeBonus = IniReader::GetInt("PerksTweak", "WeaponLongRangeBonus", 4, perksFile); TryPatchSkillBonus32("GhostSneakBonus", 20, 0x496EA9, perksFile);
if (wLongRangeBonus != 4) perks.setWeaponLongRangeBonus(wLongRangeBonus); TryPatchSkillBonus8("ThiefSkillsBonus", 10, 0x496EC1, perksFile);
TryPatchSkillBonus8("MasterThiefSkillsBonus", 15, 0x496EE0, perksFile);
int wAccurateBonus = IniReader::GetInt("PerksTweak", "WeaponAccurateBonus", 20, perksFile); TryPatchSkillBonus8("HarmlessStealBonus", 20, 0x496F02, perksFile);
if (wAccurateBonus != 20) perks.setWeaponAccurateBonus(wAccurateBonus); TryPatchSkillBonus32("SpeakerSpeechBonus", 20, 0x496F1B, perksFile);
TryPatchSkillBonus8("ExpertExcrementExpeditorSpeechBonus", 5, 0x496F33, perksFile);
int wHandlingBonus = IniReader::GetInt("PerksTweak", "WeaponHandlingBonus", 3, perksFile); TryPatchSkillBonus8("NegotiatorSkillsBonus", 10, 0x496F48, perksFile);
if (wHandlingBonus != 3) perks.setWeaponHandlingBonus(wHandlingBonus); TryPatchSkillBonus8("SalesmanBarterBonus", 20, 0x496F60, perksFile);
TryPatchSkillBonus32("GamblerGamblingBonus", 20, 0x496F79, perksFile);
int masterTraderBonus = IniReader::GetInt("PerksTweak", "MasterTraderBonus", 25, perksFile); TryPatchSkillBonus32("RangerOutdoorsmanBonus", 15, 0x496F95, perksFile);
if (masterTraderBonus != 25) perks.setMasterTraderBonus(masterTraderBonus); TryPatchSkillBonus8("SurvivalistOutdoorsmanBonus", 25, 0x496FAB, perksFile);
TryPatchSkillBonus8("MrFixitSkillsBonus", 10, 0x496E00, perksFile);
int salesmanBonus = IniReader::GetInt("PerksTweak", "SalesmanBonus", 20, perksFile);
if (salesmanBonus != 20) perks.setSalesmanBonus(salesmanBonus);
int livingAnatomyBonus = IniReader::GetInt("PerksTweak", "LivingAnatomyBonus", 5, perksFile);
if (livingAnatomyBonus != 5) perks.setLivingAnatomyBonus(livingAnatomyBonus);
int pyromaniacBonus = IniReader::GetInt("PerksTweak", "PyromaniacBonus", 5, perksFile);
if (pyromaniacBonus != 5) perks.setPyromaniacBonus(pyromaniacBonus);
int stonewallPercent = IniReader::GetInt("PerksTweak", "StonewallPercent", 50, perksFile);
if (stonewallPercent != 50) perks.setStonewallPercent(stonewallPercent);
int demolitionExpertBonus = IniReader::GetInt("PerksTweak", "DemolitionExpertBonus", 10, perksFile);
if (demolitionExpertBonus != 10) perks.setDemolitionExpertBonus(demolitionExpertBonus);
int vaultCityInoculationsBonus = IniReader::GetInt("PerksTweak", "VaultCityInoculationsPoisonBonus", 10, perksFile);
if (vaultCityInoculationsBonus != 10) perks.setVaultCityInoculationsPoisonBonus(vaultCityInoculationsBonus);
vaultCityInoculationsBonus = IniReader::GetInt("PerksTweak", "VaultCityInoculationsRadBonus", 10, perksFile);
if (vaultCityInoculationsBonus != 10) perks.setVaultCityInoculationsRadBonus(vaultCityInoculationsBonus);
} }
} }
+7
View File
@@ -21,6 +21,13 @@ void split(const std::string &s, char delim, T result, size_t limit = -1) {
} }
} }
template <typename T>
T clamp(T value, T min, T max) {
if (value < min) return min;
if (value > max) return max;
return value;
}
WORD ByteSwapW(WORD w); WORD ByteSwapW(WORD w);
DWORD ByteSwapD(DWORD dw); DWORD ByteSwapD(DWORD dw);