mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added an additional mode to SpeedInterfaceCounterAnims (from Mr.Stalin)
Refactored the code of Stats.cpp. Unified stat_level_ usages in Inventory.cpp, LoadGameHook.cpp and skills.cpp.
This commit is contained in:
@@ -430,6 +430,7 @@ ExtraSaveSlots=0
|
||||
|
||||
;Set to 1 to speed up the HP/AC counter animations
|
||||
;Set to 2 to update the HP/AC counters instantly
|
||||
;Set to 3 to update the AC counter instantly when switching to other controlled critters in combat
|
||||
SpeedInterfaceCounterAnims=0
|
||||
|
||||
;These lines allow you to control the karma FRMs displayed on the character screen
|
||||
|
||||
+2
-10
@@ -381,16 +381,8 @@ static int __fastcall SuperStimFix2(TGameObj* item, TGameObj* target) {
|
||||
}
|
||||
|
||||
DWORD curr_hp, max_hp;
|
||||
__asm {
|
||||
mov eax, target;
|
||||
mov edx, STAT_current_hp
|
||||
call stat_level_
|
||||
mov curr_hp, eax;
|
||||
mov eax, target;
|
||||
mov edx, STAT_max_hit_points
|
||||
call stat_level_
|
||||
mov max_hp, eax;
|
||||
}
|
||||
curr_hp = StatLevel(target, STAT_current_hp);
|
||||
max_hp = StatLevel(target, STAT_max_hit_points);
|
||||
if (curr_hp < max_hp) return 0;
|
||||
|
||||
DisplayConsoleMessage(SuperStimMsg);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "Bugs.h"
|
||||
#include "Console.h"
|
||||
#include "Criticals.h"
|
||||
#include "Define.h"
|
||||
#include "Explosions.h"
|
||||
#include "FalloutEngine.h"
|
||||
#include "FileSystem.h"
|
||||
@@ -128,15 +129,11 @@ static DWORD _stdcall combatSaveTest() {
|
||||
DisplayConsoleMessage(SaveFailMsg);
|
||||
return 0;
|
||||
}
|
||||
DWORD ap;
|
||||
DWORD bonusmove;
|
||||
int ap = StatLevel(*ptr_obj_dude, STAT_max_move_points);
|
||||
int bonusmove;
|
||||
__asm {
|
||||
mov edx, 8;
|
||||
mov edx, PERK_bonus_move;
|
||||
mov eax, ds:[_obj_dude];
|
||||
call stat_level_;
|
||||
mov ap, eax;
|
||||
mov eax, ds:[_obj_dude];
|
||||
mov edx, 3;
|
||||
call perk_level_;
|
||||
mov bonusmove, eax;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
static DWORD Mode;
|
||||
static int IsControllingNPC = 0;
|
||||
static bool SkipCounterAnim = false;
|
||||
static std::vector<WORD> Chars;
|
||||
static int DelayedExperience;
|
||||
|
||||
@@ -103,6 +104,11 @@ static void SaveRealDudeState() {
|
||||
//real_map_elevation = *ptr_map_elevation;
|
||||
real_sneak_working = *ptr_sneak_working;
|
||||
SkillGetTags(real_tag_skill, 4);
|
||||
|
||||
if (SkipCounterAnim) {
|
||||
SafeWrite8(0x4229EC, 0); // no animate
|
||||
SafeWrite8(0x422BDE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// take control of the NPC
|
||||
@@ -187,6 +193,11 @@ static void RestoreRealDudeState() {
|
||||
StatPcAddExperience(DelayedExperience);
|
||||
}
|
||||
|
||||
|
||||
if (SkipCounterAnim) {
|
||||
SafeWrite8(0x4229EC, 1); // restore
|
||||
SafeWrite8(0x422BDE, 1);
|
||||
}
|
||||
InterfaceRedraw();
|
||||
|
||||
SetInventoryCheck(false);
|
||||
@@ -422,6 +433,8 @@ void PartyControlInit() {
|
||||
} else
|
||||
dlogr(" Disabled.", DL_INIT);
|
||||
|
||||
SkipCounterAnim = (GetPrivateProfileIntA("Misc", "SpeedInterfaceCounterAnims", 0, ini) == 3);
|
||||
|
||||
// display party member's current level & AC & addict flag
|
||||
if (GetPrivateProfileIntA("Misc", "PartyMemberExtraInfo", 0, ini)) {
|
||||
dlog("Applying display NPC extra info patch.", DL_INIT);
|
||||
|
||||
@@ -1012,19 +1012,20 @@ static void __declspec(naked) SetApAcBonus() {
|
||||
call interpretPopLong_;
|
||||
cmp dx, VAR_TYPE_INT;
|
||||
jnz end;
|
||||
mov StandardApAcBonus, ax;
|
||||
mov StandardApAcBonus, eax;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) GetApAcBonus() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
mov ecx, eax;
|
||||
movzx edx, StandardApAcBonus;
|
||||
mov edx, StandardApAcBonus;
|
||||
call interpretPushLong_;
|
||||
mov eax, ecx;
|
||||
mov edx, VAR_TYPE_INT;
|
||||
@@ -1034,6 +1035,7 @@ static void __declspec(naked) GetApAcBonus() {
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) SetApAcEBonus() {
|
||||
__asm {
|
||||
push ecx;
|
||||
@@ -1045,19 +1047,20 @@ static void __declspec(naked) SetApAcEBonus() {
|
||||
call interpretPopLong_;
|
||||
cmp dx, VAR_TYPE_INT;
|
||||
jnz end;
|
||||
mov ExtraApAcBonus, ax;
|
||||
mov ExtraApAcBonus, eax;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) GetApAcEBonus() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
mov ecx, eax;
|
||||
movzx edx, ExtraApAcBonus;
|
||||
mov edx, ExtraApAcBonus;
|
||||
call interpretPushLong_;
|
||||
mov eax, ecx;
|
||||
mov edx, VAR_TYPE_INT;
|
||||
@@ -1088,9 +1091,9 @@ next:
|
||||
//call palette_set_to_;
|
||||
mov eax, ecx;
|
||||
call interpretGetString_;
|
||||
call loadColorTable_
|
||||
mov eax, _cmap
|
||||
call palette_set_to_
|
||||
call loadColorTable_;
|
||||
mov eax, _cmap;
|
||||
call palette_set_to_;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
|
||||
+109
-118
@@ -29,79 +29,73 @@ static DWORD StatMinimumsPC[STAT_max_stat];
|
||||
static DWORD StatMaximumsNPC[STAT_max_stat];
|
||||
static DWORD StatMinimumsNPC[STAT_max_stat];
|
||||
|
||||
static DWORD cCritter;
|
||||
static TGameObj* cCritter;
|
||||
|
||||
static DWORD xpTable[99];
|
||||
static int StatFormulas[33 * 2];
|
||||
static int StatShifts[33 * 7];
|
||||
static double StatMulti[33 * 7];
|
||||
|
||||
static void __declspec(naked) GetCurrentStatHook1() {
|
||||
DWORD StandardApAcBonus = 4;
|
||||
DWORD ExtraApAcBonus = 4;
|
||||
|
||||
static const DWORD StatLevelHack_Ret = 0x4AEF52;
|
||||
static void __declspec(naked) stat_level_hack() {
|
||||
__asm {
|
||||
mov cCritter, eax;
|
||||
push ebx;
|
||||
push ecx;
|
||||
push esi;
|
||||
push edi;
|
||||
push ebp;
|
||||
push 0x4AEF4D;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
static void __declspec(naked) GetCurrentStatHook2() {
|
||||
__asm {
|
||||
shl esi, 2;
|
||||
mov eax, cCritter;
|
||||
cmp eax, dword ptr ds:[_obj_dude];
|
||||
je pc;
|
||||
cmp ecx, StatMinimumsNPC[esi];
|
||||
jg npc1;
|
||||
mov eax, StatMinimumsNPC[esi];
|
||||
jmp end;
|
||||
npc1:
|
||||
cmp ecx, StatMaximumsNPC[esi];
|
||||
jl npc2;
|
||||
mov eax, StatMaximumsNPC[esi];
|
||||
jmp end;
|
||||
npc2:
|
||||
mov eax, ecx;
|
||||
jmp end;
|
||||
pc:
|
||||
cmp ecx, StatMinimumsPC[esi];
|
||||
jge pc1;
|
||||
mov eax, StatMinimumsPC[esi];
|
||||
jmp end;
|
||||
pc1:
|
||||
cmp ecx, StatMaximumsPC[esi];
|
||||
jle pc2;
|
||||
mov eax, StatMaximumsPC[esi];
|
||||
jmp end;
|
||||
pc2:
|
||||
mov eax, ecx;
|
||||
end:
|
||||
push 0x4AF3D7;
|
||||
retn;
|
||||
sub esp, 8;
|
||||
mov ebx, eax;
|
||||
jmp StatLevelHack_Ret;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) SetCurrentStatHook() {
|
||||
static DWORD __fastcall check_stat_level(register DWORD value, DWORD stat) {
|
||||
DWORD valLimit;
|
||||
if (cCritter == *ptr_obj_dude) {
|
||||
valLimit = StatMinimumsPC[stat];
|
||||
if (value < valLimit) return valLimit;
|
||||
valLimit = StatMaximumsPC[stat];
|
||||
if (value > valLimit) return valLimit;
|
||||
} else {
|
||||
valLimit = StatMinimumsNPC[stat];
|
||||
if (value < valLimit) return valLimit;
|
||||
valLimit = StatMaximumsNPC[stat];
|
||||
if (value > valLimit) return valLimit;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static const DWORD StatLevelHackCheck_Ret = 0x4AF3D7;
|
||||
static void __declspec(naked) stat_level_hack_check() {
|
||||
__asm {
|
||||
mov edx, esi;
|
||||
call check_stat_level; // ecx - value stat
|
||||
jmp StatLevelHackCheck_Ret;
|
||||
}
|
||||
}
|
||||
|
||||
static const DWORD StatSetBaseHack_RetMin = 0x4AF57E;
|
||||
static const DWORD StatSetBaseHack_RetMax = 0x4AF591;
|
||||
static const DWORD StatSetBaseHack_Ret = 0x4AF59C;
|
||||
static void __declspec(naked) stat_set_base_hack_check() {
|
||||
__asm {
|
||||
cmp esi, dword ptr ds:[_obj_dude];
|
||||
je pc;
|
||||
cmp ebx, StatMinimumsNPC[ecx*4];
|
||||
jl fail;
|
||||
cmp ebx, StatMaximumsNPC[ecx*4];
|
||||
jg fail;
|
||||
jmp end;
|
||||
jz pc;
|
||||
cmp ebx, StatMinimumsNPC[eax];
|
||||
jl failMin;
|
||||
cmp ebx, StatMaximumsNPC[eax];
|
||||
jg failMax;
|
||||
jmp StatSetBaseHack_Ret;
|
||||
pc:
|
||||
cmp ebx, StatMinimumsPC[ecx*4];
|
||||
jl fail;
|
||||
cmp ebx, StatMaximumsPC[ecx*4];
|
||||
jg fail;
|
||||
jmp end;
|
||||
fail:
|
||||
push 0x4AF57E;
|
||||
retn;
|
||||
end:
|
||||
push 0x4AF59C;
|
||||
retn;
|
||||
cmp ebx, StatMinimumsPC[eax];
|
||||
jl failMin;
|
||||
cmp ebx, StatMaximumsPC[eax];
|
||||
jg failMax;
|
||||
jmp StatSetBaseHack_Ret;
|
||||
failMin:
|
||||
jmp StatSetBaseHack_RetMin;
|
||||
failMax:
|
||||
jmp StatSetBaseHack_RetMax;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,9 +103,10 @@ static void __declspec(naked) GetLevelXPHook() {
|
||||
__asm {
|
||||
dec eax;
|
||||
mov eax, [xpTable + eax * 4];
|
||||
ret;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) GetNextLevelXPHook() {
|
||||
__asm {
|
||||
mov eax, ds:[_Level_];
|
||||
@@ -119,46 +114,29 @@ static void __declspec(naked) GetNextLevelXPHook() {
|
||||
}
|
||||
}
|
||||
|
||||
unsigned short StandardApAcBonus=4;
|
||||
unsigned short ExtraApAcBonus=4;
|
||||
static const DWORD ApAcRetAddr = 0x4AF0A4;
|
||||
static void __declspec(naked) ApplyApAcBonus() {
|
||||
static void __declspec(naked) CalcApToAcBonus() {
|
||||
__asm {
|
||||
push edi;
|
||||
push edx;
|
||||
cmp [esp+12], 2;
|
||||
jge h2hEvade;
|
||||
xor edi, edi;
|
||||
jmp standard;
|
||||
h2hEvade:
|
||||
xor eax, eax;
|
||||
mov edi, [ebx + 0x40];
|
||||
test edi, edi;
|
||||
jz end;
|
||||
cmp [esp + 0x1C - 0x18], 2; // pc have perk h2hEvade (2 - vanilla bonus)
|
||||
jb standard;
|
||||
mov edx, PERK_hth_evade_perk;
|
||||
mov eax, dword ptr ds:[_obj_dude];
|
||||
call perk_level_;
|
||||
imul ax, ExtraApAcBonus;
|
||||
imul ax, [ebx+0x40];
|
||||
mov edi, eax;
|
||||
imul eax, ExtraApAcBonus; // bonus = perkLvl * ExtraApBonus
|
||||
imul eax, edi; // perkBonus = bonus * curAP
|
||||
standard:
|
||||
mov eax, [ebx+0x40];
|
||||
imul ax, StandardApAcBonus;
|
||||
add eax, edi;
|
||||
shr eax, 2;
|
||||
pop edx;
|
||||
pop edi;
|
||||
imul edi, StandardApAcBonus; // stdBonus = curAP * StandardApBonus
|
||||
add eax, edi; // bonus = perkBonus + stdBonus
|
||||
shr eax, 2; // acBonus = bonus / 4
|
||||
end:
|
||||
jmp ApAcRetAddr;
|
||||
}
|
||||
}
|
||||
|
||||
static int StatFormulas[33*2];
|
||||
static int StatShifts[33*7];
|
||||
static double StatMulti[33*7];
|
||||
static int __declspec(naked) _stdcall StatLevel(void* critter, int id) {
|
||||
__asm {
|
||||
mov eax, [esp+4];
|
||||
mov edx, [esp+8];
|
||||
call stat_level_;
|
||||
retn 8;
|
||||
}
|
||||
}
|
||||
static void __declspec(naked) _stdcall ProtoPtr(DWORD pid, int** proto) {
|
||||
__asm {
|
||||
mov eax, [esp + 4];
|
||||
@@ -167,17 +145,19 @@ static void __declspec(naked) _stdcall ProtoPtr(DWORD pid, int** proto) {
|
||||
retn 8;
|
||||
}
|
||||
}
|
||||
static void _stdcall StatRecalcDerived(DWORD* critter) {
|
||||
int basestats[7];
|
||||
for(int i=0;i<7;i++) basestats[i]=StatLevel(critter, i);
|
||||
int* proto;
|
||||
ProtoPtr(critter[25], &proto);
|
||||
|
||||
for(int i=7;i<=32;i++) {
|
||||
if(i>=17&&i<=30) continue;
|
||||
static void _stdcall StatRecalcDerived(TGameObj* critter) {
|
||||
int basestats[7];
|
||||
for (int i = STAT_st; i <= STAT_lu; i++) basestats[i] = StatLevel(critter, i);
|
||||
|
||||
int* proto;
|
||||
ProtoPtr(critter->pid, &proto);
|
||||
|
||||
for (int i = STAT_max_hit_points; i <= STAT_poison_resist; i++) {
|
||||
if (i >= STAT_dmg_thresh && i <= STAT_dmg_resist_explosion) continue;
|
||||
|
||||
double sum = 0;
|
||||
for(int j=0;j<7;j++) {
|
||||
for (int j = STAT_st; j <= STAT_lu; j++) {
|
||||
sum += (basestats[j] + StatShifts[i * 7 + j]) * StatMulti[i * 7 + j];
|
||||
}
|
||||
proto[i + 9] = StatFormulas[i * 2] + (int)floor(sum);
|
||||
@@ -185,7 +165,7 @@ static void _stdcall StatRecalcDerived(DWORD* critter) {
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) stat_recalc_derived() {
|
||||
static void __declspec(naked) stat_recalc_derived_hack() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
@@ -205,16 +185,14 @@ void StatsReset() {
|
||||
StandardApAcBonus = 4;
|
||||
ExtraApAcBonus = 4;
|
||||
}
|
||||
|
||||
void StatsInit() {
|
||||
StatsReset();
|
||||
SafeWrite8(0x4AEF48, 0xE9);
|
||||
HookCall(0x4AEF48, GetCurrentStatHook1);
|
||||
SafeWrite8(0x4AF3AF, 0xE9);
|
||||
HookCall(0x4AF3AF, GetCurrentStatHook2);
|
||||
SafeWrite8(0x4AF56A, 0xE9);
|
||||
HookCall(0x4AF56A, SetCurrentStatHook);
|
||||
SafeWrite8(0x4AF09C, 0xE9);
|
||||
HookCall(0x4AF09C, ApplyApAcBonus);
|
||||
|
||||
MakeJump(0x4AEF4D, stat_level_hack);
|
||||
MakeJump(0x4AF3AF, stat_level_hack_check);
|
||||
MakeJump(0x4AF571, stat_set_base_hack_check);
|
||||
MakeJump(0x4AF09C, CalcApToAcBonus); // stat_level_
|
||||
|
||||
char table[2048];
|
||||
GetPrivateProfileString("Misc", "XPTable", "", table, 2048, ini);
|
||||
@@ -242,7 +220,8 @@ void StatsInit() {
|
||||
|
||||
GetPrivateProfileStringA("Misc", "DerivedStats", "", table, 2048, ini);
|
||||
if (strlen(table)) {
|
||||
MakeJump(0x4AF6FC, stat_recalc_derived);
|
||||
MakeJump(0x4AF6FC, stat_recalc_derived_hack); // overrides function
|
||||
|
||||
memset(StatFormulas, 0, sizeof(StatFormulas));
|
||||
memset(StatShifts, 0, sizeof(StatShifts));
|
||||
memset(StatMulti, 0, sizeof(StatMulti));
|
||||
@@ -250,17 +229,22 @@ void StatsInit() {
|
||||
StatFormulas[7 * 2] = 15; // max hp
|
||||
StatMulti[7 * 7 + 0] = 1;
|
||||
StatMulti[7 * 7 + 2] = 2;
|
||||
|
||||
StatFormulas[8 * 2] = 5; // max ap
|
||||
StatMulti[8 * 7 + 5] = 0.5;
|
||||
|
||||
StatMulti[9 * 7 + 5] = 1; // ac
|
||||
StatFormulas[11 * 2 + 1] = 1; // melee damage
|
||||
StatShifts[11 * 7 + 0] = -5;
|
||||
StatMulti[11 * 7 + 0] = 1;
|
||||
|
||||
StatFormulas[12 * 2] = 25; // carry weight
|
||||
StatMulti[12 * 7 + 0] = 25;
|
||||
|
||||
StatMulti[13 * 7 + 1] = 2; // sequence
|
||||
StatFormulas[14 * 2 + 1] = 1; // heal rate
|
||||
StatMulti[14 * 7 + 2] = 1.0 / 3.0;
|
||||
|
||||
StatMulti[15 * 7 + 6] = 1; // critical chance
|
||||
StatMulti[31 * 7 + 2] = 2; // rad resist
|
||||
StatMulti[32 * 7 + 2] = 5; // poison resist
|
||||
@@ -268,13 +252,13 @@ void StatsInit() {
|
||||
char key[6], buf2[256], buf3[256];
|
||||
strcpy_s(buf3, table);
|
||||
sprintf(table, ".\\%s", buf3);
|
||||
for(int i=7;i<=32;i++) {
|
||||
if(i>=17&&i<=30) continue;
|
||||
for (int i = STAT_max_hit_points; i <= STAT_poison_resist; i++) {
|
||||
if (i >= STAT_dmg_thresh && i <= STAT_dmg_resist_explosion) continue;
|
||||
|
||||
_itoa(i, key, 10);
|
||||
StatFormulas[i * 2] = GetPrivateProfileInt(key, "base", StatFormulas[i * 2], table);
|
||||
StatFormulas[i * 2 + 1] = GetPrivateProfileInt(key, "min", StatFormulas[i * 2 + 1], table);
|
||||
for(int j=0;j<7;j++) {
|
||||
for (int j = 0; j < STAT_max_hit_points; j++) {
|
||||
sprintf(buf2, "shift%d", j);
|
||||
StatShifts[i * 7 + j] = GetPrivateProfileInt(key, buf2, StatShifts[i * 7 + 0], table);
|
||||
sprintf(buf2, "multi%d", j);
|
||||
@@ -287,18 +271,25 @@ void StatsInit() {
|
||||
}
|
||||
|
||||
void _stdcall SetPCStatMax(int stat, int i) {
|
||||
if(stat<0||stat>=STAT_max_stat) return;
|
||||
if (stat >= 0 && stat < STAT_max_stat) {
|
||||
StatMaximumsPC[stat] = i;
|
||||
}
|
||||
}
|
||||
|
||||
void _stdcall SetPCStatMin(int stat, int i) {
|
||||
if(stat<0||stat>=STAT_max_stat) return;
|
||||
if (stat >= 0 && stat < STAT_max_stat) {
|
||||
StatMinimumsPC[stat] = i;
|
||||
}
|
||||
}
|
||||
|
||||
void _stdcall SetNPCStatMax(int stat, int i) {
|
||||
if(stat<0||stat>=STAT_max_stat) return;
|
||||
if (stat >= 0 && stat < STAT_max_stat) {
|
||||
StatMaximumsNPC[stat] = i;
|
||||
}
|
||||
}
|
||||
|
||||
void _stdcall SetNPCStatMin(int stat, int i) {
|
||||
if(stat<0||stat>=STAT_max_stat) return;
|
||||
if (stat >= 0 && stat < STAT_max_stat) {
|
||||
StatMinimumsNPC[stat] = i;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -24,5 +24,5 @@ void _stdcall SetPCStatMax(int stat, int i);
|
||||
void _stdcall SetPCStatMin(int stat, int i);
|
||||
void _stdcall SetNPCStatMax(int stat, int i);
|
||||
void _stdcall SetNPCStatMin(int stat, int i);
|
||||
extern unsigned short StandardApAcBonus;
|
||||
extern unsigned short ExtraApAcBonus;
|
||||
extern DWORD StandardApAcBonus;
|
||||
extern DWORD ExtraApAcBonus;
|
||||
|
||||
+1
-1
@@ -1290,7 +1290,7 @@ static void DllMain2() {
|
||||
break;
|
||||
case 2:
|
||||
dlog("Applying SpeedInterfaceCounterAnims patch. (Instant)", DL_INIT);
|
||||
SafeWrite32(0x460BB6, 0x90DB3190);
|
||||
SafeWrite32(0x460BB6, 0x90DB3190); // xor ebx, ebx
|
||||
dlogr(" Done", DL_INIT);
|
||||
break;
|
||||
}
|
||||
|
||||
+25
-26
@@ -27,24 +27,29 @@
|
||||
#include "Knockback.h"
|
||||
|
||||
struct SkillInfo {
|
||||
DWORD a, b, c; //Not interested in these at the moment
|
||||
DWORD image;
|
||||
DWORD base;
|
||||
DWORD statMulti;
|
||||
int statA;
|
||||
int statB;
|
||||
DWORD skillPointMulti;
|
||||
DWORD e, f; //nor these
|
||||
const char* name;
|
||||
const char* description;
|
||||
long attr;
|
||||
long image;
|
||||
long base;
|
||||
long statMulti;
|
||||
long statA;
|
||||
long statB;
|
||||
long skillPointMulti;
|
||||
// Default experience for using the skill: 25 for Lockpick, Steal, Traps, and First Aid, 50 for Doctor, and 100 for Outdoorsman.
|
||||
long experience;
|
||||
// 1 for Lockpick, Steal, Traps; 0 otherwise
|
||||
long f;
|
||||
};
|
||||
|
||||
struct ChanceModifier {
|
||||
struct SkillModifier {
|
||||
DWORD id;
|
||||
int maximum;
|
||||
int mod;
|
||||
};
|
||||
|
||||
static std::vector<ChanceModifier> SkillMaxMods;
|
||||
static ChanceModifier BaseSkillMax;
|
||||
static std::vector<SkillModifier> SkillMaxMods;
|
||||
static SkillModifier BaseSkillMax;
|
||||
static BYTE skillCosts[512 * SKILL_count];
|
||||
static DWORD basedOnPoints;
|
||||
|
||||
@@ -56,6 +61,7 @@ static int _stdcall SkillMaxHook2(int base, DWORD critter) {
|
||||
}
|
||||
return min(base, BaseSkillMax.maximum);
|
||||
}
|
||||
|
||||
static void __declspec(naked) SkillHookA() {
|
||||
__asm {
|
||||
push ecx;
|
||||
@@ -65,6 +71,7 @@ static void __declspec(naked) SkillHookA() {
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) SkillHookB() {
|
||||
__asm {
|
||||
push edx;
|
||||
@@ -87,6 +94,7 @@ win:
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static const DWORD SkillHookWin = 0x4AA738;
|
||||
static const DWORD SkillHookFail = 0x4AA72C;
|
||||
static void __declspec(naked) SkillHookC() {
|
||||
@@ -117,7 +125,7 @@ void _stdcall SetSkillMax(DWORD critter, DWORD maximum) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
ChanceModifier cm;
|
||||
SkillModifier cm;
|
||||
cm.id = critter;
|
||||
cm.maximum = maximum;
|
||||
cm.mod = 0;
|
||||
@@ -125,29 +133,20 @@ void _stdcall SetSkillMax(DWORD critter, DWORD maximum) {
|
||||
}
|
||||
|
||||
double* multipliers;
|
||||
static const DWORD StatBonusHookRet=0x4AA5D6;
|
||||
|
||||
static int __declspec(naked) _stdcall stat_level(void* critter, int stat) {
|
||||
__asm {
|
||||
push edx;
|
||||
mov eax, [esp+8];
|
||||
mov edx, [esp+12];
|
||||
call stat_level_;
|
||||
pop edx;
|
||||
ret 8;
|
||||
}
|
||||
}
|
||||
static int _stdcall GetStatBonusHook2(const SkillInfo* info, int skill, int points, void* critter) {
|
||||
static int _stdcall GetStatBonusHook2(const SkillInfo* info, int skill, int points, TGameObj* critter) {
|
||||
double result = 0;
|
||||
for(int i=0;i<7;i++) {
|
||||
result+=stat_level(critter, i)*multipliers[skill*7+i];
|
||||
for (int i = STAT_st; i <= STAT_lu; i++) {
|
||||
result += StatLevel(critter, i) * multipliers[skill * 7 + i];
|
||||
}
|
||||
result += points*info->skillPointMulti;
|
||||
result += info->base;
|
||||
return (int)result;
|
||||
}
|
||||
|
||||
//On input, ebx contains the skill id, ecx contains the critter, edx contains the skill id, edi contains a SkillInfo*, ebp contains the number of skill points
|
||||
//On exit ebx, ecx, edi, ebp are preserved, esi contains skill base + stat bonus + skillpoints * multiplier
|
||||
static const DWORD StatBonusHookRet = 0x4AA5D6;
|
||||
static void __declspec(naked) GetStatBonusHook() {
|
||||
__asm {
|
||||
push edx;
|
||||
|
||||
Reference in New Issue
Block a user