Added settings about Educated, Healer, and Lifegiver to perks.ini

This commit is contained in:
NovaRain
2025-01-27 21:02:35 +08:00
parent d07d27fcec
commit 1cbca9c133
2 changed files with 108 additions and 45 deletions
+18 -3
View File
@@ -2,10 +2,12 @@
;When adding extra perks to a mod, it's advisable to use the fake perk scripting functions rather than make
; modifications in this file, as some perks have hardcoded effects which may catch you out
;Set the bonus value to 0 in the 'PerksTweak' section for perks to get around this problem
;Since traits need to be picked before any scripts run, they have an additional NoHardcode option in this file which can
; be used to remove their hardcoded effects, and add new stat/skill effects
;Since traits need to be picked before any scripts run, they have an additional 'NoHardcode' option in this file
; which can be used to remove their hardcoded effects, and add new stat/skill effects
;##############################################################################
[PerksTweak]
;Changes the light level bonus for 'Night Vision' perk (ID 9)
;valid range: 0..100, 20 - default bonus
@@ -19,6 +21,20 @@ SurvivalistBonus=25
;25 - default bonus
MasterTraderBonus=25
;Changes the skill point bonus for 'Educated' perk (ID 18)
;125 - maximum bonus, 2 - default bonus
EducatedBonus=2
;Changes the hit point bonuses for 'Healer' perk (ID 19)
;999 - maximum bonus, 4 - default bonus
HealerMinBonus=4
;999 - maximum bonus, 10 - default bonus
HealerMaxBonus=10
;Changes the hit point bonus for 'Lifegiver' perk (ID 28)
;125 - maximum bonus, 4 - default bonus
LifegiverBonus=4
;Changes the Science and Repair skill bonus for 'Mr.Fixit' perk (ID 31)
;125 - maximum bonus, 10 - default bonus
MrFixitBonus=10
@@ -163,7 +179,6 @@ Enable=0
;Skill3-Skill5: The skill to be modified (or -1 for none)
;Skill3Mod-Skill5Mod: The increased/decreased value to the modified skill
;##############################################################################
;This is a modification to vanilla perk 0
[0]
Name=Example
+90 -42
View File
@@ -31,6 +31,10 @@ static long SalesmanBonus = 20;
static long DemolitionExpertBonus = 10;
static long NightVisionBonus = 13107; // 20% of max light
static long ComprehensionBonus = 150; // +50% of earned skill points
static long EducatedBonus = 2;
static long HealerMinBonus = 4;
static long HealerMaxBonus = 10;
static long LifegiverBonus = 4;
static bool TryGetModifiedInt(const char* key, int defaultValue, int& outValue, const char* perksFile) {
outValue = IniReader::GetInt("PerksTweak", key, defaultValue, perksFile);
@@ -78,21 +82,46 @@ static __declspec(naked) void queue_explode_exit_hack_demolition_expert() {
}
static __declspec(naked) void light_set_ambient_hack_night_vision() {
static const DWORD light_set_ambient_night_vision_Ret = 0x47A932;
__asm {
imul eax, [NightVisionBonus];
pop edx;
add edx, 16; // skip code (to 0x47A932)
jmp edx;
jmp light_set_ambient_night_vision_Ret;
}
}
static __declspec(naked) void obj_use_book_hack_comprehension() {
static const DWORD obj_use_book_comprehension_Ret = 0x49BADD;
__asm {
imul esi, [ComprehensionBonus];
mov edx, esi;
pop ebx;
add ebx, 11; // skip code (to 0x49BADD)
jmp ebx;
jmp obj_use_book_comprehension_Ret;
}
}
static __declspec(naked) void UpdateLevel_hack_educated() {
__asm {
call fo::funcoffs::perk_level_;
imul eax, [EducatedBonus];
retn;
}
}
static __declspec(naked) void skill_use_hack_healer() {
static const DWORD skill_use_healer_Ret = 0x4AADDC;
__asm {
mov edx, eax;
imul edx, [HealerMinBonus];
mov [esp + 0xC8 - 0x34], edx; // minimumHpToHeal
imul eax, [HealerMaxBonus];
jmp skill_use_healer_Ret;
}
}
static __declspec(naked) void statPcExperience_hack_lifegiver() {
__asm {
call fo::funcoffs::perk_level_;
imul eax, [LifegiverBonus];
retn;
}
}
@@ -101,8 +130,12 @@ void EnginePerkBonusInit() {
MakeCall(0x496F5E, perk_adjust_skill_hack_salesman);
MakeCall(0x4A289C, queue_explode_exit_hack_demolition_expert, 1);
// Allow configurable bonuses
MakeCall(0x47A91D, light_set_ambient_hack_night_vision);
MakeCall(0x49BACD, obj_use_book_hack_comprehension);
MakeJump(0x47A91D, light_set_ambient_hack_night_vision);
MakeJump(0x49BACD, obj_use_book_hack_comprehension);
MakeCall(0x43C287, UpdateLevel_hack_educated, 2);
MakeJump(0x4AADC5, skill_use_hack_healer, 2);
MakeCall(0x4AFBCC, statPcExperience_hack_lifegiver, 3); // statPCAddExperienceCheckPMs_
MakeCall(0x4AFCBB, statPcExperience_hack_lifegiver, 3); // statPcResetExperience_
}
void ReadPerksBonuses(const char* perksFile) {
@@ -111,32 +144,49 @@ void ReadPerksBonuses(const char* perksFile) {
TryPatchValue32("WeaponScopeRangeBonus", 5, 2, 100, 0x424489, perksFile);
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));
TryPatchSkillBonus8("SurvivalistBonus", 25, 0x496FAB, perksFile);
TryPatchSkillBonus8("MrFixitBonus", 10, 0x496E00, perksFile);
TryPatchSkillBonus32("MedicFirstAidBonus", 10, 0x496E19, perksFile);
TryPatchSkillBonus32("MedicDoctorBonus", 10, 0x496E4E, perksFile);
TryPatchSkillBonus8("MasterThiefBonus", 15, 0x496EE0, perksFile);
TryPatchSkillBonus32("SpeakerBonus", 20, 0x496F1B, perksFile);
TryPatchSkillBonus32("GhostBonus", 20, 0x496EA9, perksFile);
TryPatchSkillBonus32("RangerOutdoorsmanBonus", 15, 0x496F95, perksFile);
TryPatchValue8("CautiousNatureBonus", 3, -12, 20, 0x4C1756, perksFile); // -12 - force distance to 0
TryPatchSkillBonus32("GamblerBonus", 20, 0x496F79, perksFile);
TryPatchSkillBonus8("HarmlessBonus", 20, 0x496F02, perksFile);
TryPatchSkillBonus8("LivingAnatomyBonus", 5, 0x424A91, perksFile);
TryPatchSkillBonus8("LivingAnatomyDoctorBonus", 10, 0x496E66, perksFile);
TryPatchSkillBonus8("NegotiatorBonus", 10, 0x496F48, perksFile);
TryPatchSkillBonus8("PyromaniacBonus", 5, 0x424AB6, perksFile);
TryPatchValue8("StonewallPercent", 50, 0, 100, 0x424B50, perksFile);
TryPatchSkillBonus8("ThiefBonus", 10, 0x496EC1, perksFile);
TryPatchSkillBonus8("VaultCityTrainingFirstAidBonus", 5, 0x496E35, perksFile);
TryPatchSkillBonus8("VaultCityTrainingDoctorBonus", 5, 0x496E7F, perksFile);
TryPatchSkillBonus8("ExpertExcrementExpeditorBonus", 5, 0x496F33, perksFile);
if (TryGetModifiedInt("NightVisionBonus", 20, value, perksFile) && value >= 0) {
if (value > 100) value = 100;
NightVisionBonus = (65536 * value) / 100;
}
if (TryGetModifiedInt("MasterTraderBonus", 25, value, perksFile) && value >= 0) {
float floatValue = static_cast<float>(value);
SafeWrite32(0x474BB3, *(DWORD*)&floatValue); // write float data
}
if (TryGetModifiedInt("NightVisionBonus", 20, value, perksFile) && value >= 0) {
if (value > 100) value = 100;
NightVisionBonus = (65536 * value) / 100;
if (TryGetModifiedInt("EducatedBonus", EducatedBonus, value, perksFile) && value >= 0) {
EducatedBonus = min(value, 125);
SafeWrite8(0x43CA6D, static_cast<signed char>(EducatedBonus));
}
if (TryGetModifiedInt("SalesmanBonus", SalesmanBonus, value, perksFile) && value >= 0) {
SalesmanBonus = min(value, 999);
if (TryGetModifiedInt("HealerMinBonus", HealerMinBonus, value, perksFile) && value >= 0) {
HealerMinBonus = min(value, 999);
}
TryPatchSkillBonus8("LivingAnatomyBonus", 5, 0x424A91, perksFile);
TryPatchSkillBonus8("LivingAnatomyDoctorBonus", 10, 0x496E66, perksFile);
TryPatchSkillBonus8("PyromaniacBonus", 5, 0x424AB6, perksFile);
TryPatchValue8("StonewallPercent", 50, 0, 100, 0x424B50, perksFile);
TryPatchValue8("CautiousNatureBonus", 3, -12, 20, 0x4C1756, perksFile); // -12 - force distance to 0
if (TryGetModifiedInt("ComprehensionBonus", 50, value, perksFile) && value >= 0) {
ComprehensionBonus = value + 100;
if (TryGetModifiedInt("HealerMaxBonus", HealerMaxBonus, value, perksFile) && value >= 0) {
HealerMaxBonus = min(value, 999);
}
if (TryGetModifiedInt("DemolitionExpertBonus", DemolitionExpertBonus, value, perksFile) && value >= 0) {
DemolitionExpertBonus = min(value, 999);
if (TryGetModifiedInt("LifegiverBonus", LifegiverBonus, value, perksFile) && value >= 0) {
LifegiverBonus = min(value, 125);
SafeWriteBatch<BYTE>(static_cast<signed char>(LifegiverBonus), {0x43CA2C, 0x43CA3D});
}
if (TryGetModifiedInt("VaultCityInoculationsPoisonBonus", 10, value, perksFile)) {
SafeWrite8(0x4AF26A, static_cast<signed char>(clamp<long>(value, -100, 100)));
@@ -144,22 +194,20 @@ void ReadPerksBonuses(const char* perksFile) {
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);
TryPatchSkillBonus32("GhostBonus", 20, 0x496EA9, perksFile);
TryPatchSkillBonus8("ThiefBonus", 10, 0x496EC1, perksFile);
TryPatchSkillBonus8("MasterThiefBonus", 15, 0x496EE0, perksFile);
TryPatchSkillBonus8("HarmlessBonus", 20, 0x496F02, perksFile);
TryPatchSkillBonus32("SpeakerBonus", 20, 0x496F1B, perksFile);
TryPatchSkillBonus8("ExpertExcrementExpeditorBonus", 5, 0x496F33, perksFile);
TryPatchSkillBonus8("NegotiatorBonus", 10, 0x496F48, perksFile);
TryPatchSkillBonus32("GamblerBonus", 20, 0x496F79, perksFile);
TryPatchSkillBonus32("RangerOutdoorsmanBonus", 15, 0x496F95, perksFile);
TryPatchSkillBonus8("SurvivalistBonus", 25, 0x496FAB, perksFile);
TryPatchSkillBonus8("MrFixitBonus", 10, 0x496E00, perksFile);
if (TryGetModifiedInt("ComprehensionBonus", 50, value, perksFile) && value >= 0) {
ComprehensionBonus = value + 100;
}
if (TryGetModifiedInt("DemolitionExpertBonus", DemolitionExpertBonus, value, perksFile) && value >= 0) {
DemolitionExpertBonus = min(value, 999);
}
if (TryGetModifiedInt("SalesmanBonus", SalesmanBonus, value, perksFile) && value >= 0) {
SalesmanBonus = min(value, 999);
}
if (TryGetModifiedInt("WeaponHandlingBonus", 3, value, perksFile) && value >= 0) {
if (value > 10) value = 10;
SafeWrite8(0x424636, static_cast<signed char>(value));
SafeWrite8(0x4251CE, static_cast<signed char>(-value));
}
}
}