mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added settings about Educated, Healer, and Lifegiver to perks.ini
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user