Fixed the negative skill points of a skill not being taken into account when calculating the skill level (from Mr.Stalin, #202)

Fixed the return value of has_skill function for incorrect skill numbers.
This commit is contained in:
NovaRain
2019-02-21 10:53:55 +08:00
parent 36e3a2bd5f
commit 1687e50729
3 changed files with 58 additions and 37 deletions
+2 -2
View File
@@ -92,7 +92,7 @@ FadeMultiplier=100
;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[Input] [Input]
;Set to 1 to enable the mouse scroll wheel to scroll through inventory, barter, and loot screens ;Set to 1 to enable the mouse scroll wheel to scroll through the inventory, barter, and loot screens
UseScrollWheel=1 UseScrollWheel=1
;The mouse Z position is divided by this modifier to calculate the number of inventory ;The mouse Z position is divided by this modifier to calculate the number of inventory
@@ -645,7 +645,7 @@ WorldMapFontPatch=0
;Set to 1 to keep the selected attack mode when moving the weapon between active item slots ;Set to 1 to keep the selected attack mode when moving the weapon between active item slots
KeepWeaponSelectMode=1 KeepWeaponSelectMode=1
;Set to 1 to display full item description for weapon/ammo in barter screen ;Set to 1 to display full item description for weapon/ammo in the barter screen
FullItemDescInBarter=0 FullItemDescInBarter=0
;Set to 1 to display experience points with the bonus from Swift Learner perk when gained from non-scripted situations ;Set to 1 to display experience points with the bonus from Swift Learner perk when gained from non-scripted situations
+35 -32
View File
@@ -293,7 +293,7 @@ static void __declspec(naked) queue_clear_type_mem_free_hook() {
} }
} }
static void __declspec(naked) partyMemberCopyLevelInfo_stat_level_hook() { static void __declspec(naked) partyMemberCopyLevelInfo_hook_stat_level() {
__asm { __asm {
nextArmor: nextArmor:
mov eax, esi mov eax, esi
@@ -308,7 +308,7 @@ noArmor:
} }
} }
static void __declspec(naked) correctFidForRemovedItem_adjust_ac_hook() { static void __declspec(naked) correctFidForRemovedItem_hook_adjust_ac() {
__asm { __asm {
call fo::funcoffs::adjust_ac_ call fo::funcoffs::adjust_ac_
nextArmor: nextArmor:
@@ -323,40 +323,40 @@ end:
} }
} }
static void __declspec(naked) partyMemberCopyLevelInfo_hook() { static void __declspec(naked) partyMemberIncLevels_hook() {
__asm { __asm {
push eax mov ebx, eax; // party member pointer
call fo::funcoffs::partyMemberCopyLevelInfo_ call fo::funcoffs::partyMemberCopyLevelInfo_;
pop ebx cmp eax, -1;
cmp eax, -1 je end;
je end xor edx, edx; // queue type (0)
pushad mov eax, ebx; // source
mov dword ptr ds:[FO_VAR_critterClearObj], ebx call fo::funcoffs::queue_remove_this_;
mov edx, fo::funcoffs::critterClearObjDrugs_ push ecx;
call fo::funcoffs::queue_clear_type_ push edi;
mov ecx, 8 mov ecx, 8;
mov edi, FO_VAR_drugInfoList mov edi, FO_VAR_drugInfoList;
mov esi, ebx
loopAddict: loopAddict:
mov eax, dword ptr [edi] // eax = drug pid mov eax, dword ptr [edi]; // eax = drug pid
call fo::funcoffs::item_d_check_addict_ call fo::funcoffs::item_d_check_addict_;
test eax, eax // Has addiction? test eax, eax; // Has addiction?
jz noAddict // No jz noAddict; // No
cmp dword ptr [eax], 0 // queue_addict.init cmp dword ptr [eax], 0; // queue_addict.init
jne noAddict // Addiction is not active yet jne noAddict; // Addiction is not active yet
mov edx, dword ptr [eax+0x8] // queue_addict.perk mov edx, dword ptr [eax + 0x8]; // queue_addict.perk
mov eax, ebx mov eax, ebx;
call fo::funcoffs::perk_add_effect_ call fo::funcoffs::perk_add_effect_;
noAddict: noAddict:
add edi, 12 lea edi, [edi + 12];
loop loopAddict dec ecx;
popad jnz loopAddict;
pop edi;
pop ecx;
end: end:
retn retn;
} }
} }
static void __declspec(naked) gdProcessUpdate_hack() { static void __declspec(naked) gdProcessUpdate_hack() {
__asm { __asm {
add eax, esi add eax, esi
@@ -1894,14 +1894,14 @@ void BugFixes::init()
// The same happens if you just order NPC to remove the armor through dialogue. // The same happens if you just order NPC to remove the armor through dialogue.
//if (GetConfigInt("Misc", "ArmorCorruptsNPCStatsFix", 1)) { //if (GetConfigInt("Misc", "ArmorCorruptsNPCStatsFix", 1)) {
dlog("Applying fix for armor reducing NPC original stats when removed.", DL_INIT); dlog("Applying fix for armor reducing NPC original stats when removed.", DL_INIT);
HookCall(0x495F3B, partyMemberCopyLevelInfo_stat_level_hook); HookCall(0x495F3B, partyMemberCopyLevelInfo_hook_stat_level);
HookCall(0x45419B, correctFidForRemovedItem_adjust_ac_hook); HookCall(0x45419B, correctFidForRemovedItem_hook_adjust_ac);
dlogr(" Done", DL_INIT); dlogr(" Done", DL_INIT);
//} //}
// Fix of invalid stats when party member gains a level while being on drugs // Fix of invalid stats when party member gains a level while being on drugs
dlog("Applying fix for addicted party member level up bug.", DL_INIT); dlog("Applying fix for addicted party member level up bug.", DL_INIT);
HookCall(0x495D5C, partyMemberCopyLevelInfo_hook); HookCall(0x495D5C, partyMemberIncLevels_hook);
dlogr(" Done", DL_INIT); dlogr(" Done", DL_INIT);
// Allow 9 options (lines of text) to be displayed correctly in a dialog window // Allow 9 options (lines of text) to be displayed correctly in a dialog window
@@ -2320,6 +2320,9 @@ void BugFixes::init()
// Fix for the reserved item FRM being displayed in the top-left corner when in the loot/barter screens // Fix for the reserved item FRM being displayed in the top-left corner when in the loot/barter screens
HookCalls(JesseContainerFid, {0x473AC9, 0x475895}); HookCalls(JesseContainerFid, {0x473AC9, 0x475895});
// Fix the return value of has_skill function for incorrect skill numbers
SafeWrite32(0x4AA56B, 0);
} }
} }
+21 -3
View File
@@ -39,8 +39,8 @@ struct SkillModifier {
SkillModifier() : id(0), maximum(300)/*, mod(0)*/ {} SkillModifier() : id(0), maximum(300)/*, mod(0)*/ {}
SkillModifier(long _id, int max) { SkillModifier(long id, int max) {
id = _id; this->id = id;
maximum = max; maximum = max;
//mod = _mod; //mod = _mod;
} }
@@ -61,6 +61,8 @@ static double* multipliers = nullptr;
static std::vector<ChanceModifier> pickpocketMods; static std::vector<ChanceModifier> pickpocketMods;
static ChanceModifier basePickpocket; static ChanceModifier basePickpocket;
static int skillNegPoints;
static int __fastcall PickpocketMod(int base, fo::GameObject* critter) { static int __fastcall PickpocketMod(int base, fo::GameObject* critter) {
for (DWORD i = 0; i < pickpocketMods.size(); i++) { for (DWORD i = 0; i < pickpocketMods.size(); i++) {
if (critter->id == pickpocketMods[i].id) { if (critter->id == pickpocketMods[i].id) {
@@ -84,6 +86,8 @@ static void __declspec(naked) skill_check_stealing_hack() {
} }
static int __fastcall CheckSkillMax(fo::GameObject* critter, int base) { static int __fastcall CheckSkillMax(fo::GameObject* critter, int base) {
base += skillNegPoints; // add the negative skill points after calculating the skill level
for (DWORD i = 0; i < skillMaxMods.size(); i++) { for (DWORD i = 0; i < skillMaxMods.size(); i++) {
if (critter->id == skillMaxMods[i].id) { if (critter->id == skillMaxMods[i].id) {
return min(base, skillMaxMods[i].maximum); return min(base, skillMaxMods[i].maximum);
@@ -101,6 +105,19 @@ static void __declspec(naked) skill_level_hack() {
} }
} }
static void __declspec(naked) skill_level_hook() {
__asm {
mov skillNegPoints, 0; // reset value
call fo::funcoffs::skill_points_;
test eax, eax;
jge skip; // skip if eax >= 0
mov skillNegPoints, eax; // save the negative skill points
xor eax, eax;
skip:
retn;
}
}
static void __declspec(naked) skill_inc_point_force_hack() { static void __declspec(naked) skill_inc_point_force_hack() {
__asm { __asm {
push ecx; push ecx;
@@ -236,7 +253,7 @@ void _stdcall SetPickpocketMax(fo::GameObject* critter, DWORD maximum, DWORD mod
pickpocketMods.push_back(ChanceModifier(id, maximum, mod)); pickpocketMods.push_back(ChanceModifier(id, maximum, mod));
} }
void Skills_OnGameLoad() { static void Skills_OnGameLoad() {
pickpocketMods.clear(); pickpocketMods.clear();
basePickpocket.SetDefault(); basePickpocket.SetDefault();
@@ -245,6 +262,7 @@ void Skills_OnGameLoad() {
} }
void Skills::init() { void Skills::init() {
HookCall(0x4AA574, skill_level_hook); // fix for negative skill points
MakeJump(0x4AA63C, skill_level_hack, 1); MakeJump(0x4AA63C, skill_level_hack, 1);
MakeCall(0x4AA847, skill_inc_point_force_hack); MakeCall(0x4AA847, skill_inc_point_force_hack);
MakeCall(0x4AA725, skill_inc_point_hack); MakeCall(0x4AA725, skill_inc_point_hack);