mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Rewrote set_xp_mod, get_sfall_args, set_sfall_arg functions in C++
Cleanup in ASM scripting handlers code.
This commit is contained in:
@@ -28,7 +28,7 @@ WeaponHandlingBonus=3
|
||||
|
||||
;##############################################################################
|
||||
[Perks]
|
||||
;Set to 1 to enable the modifications to perks
|
||||
;Set to 1 to enable modifications to perks
|
||||
Enable=0
|
||||
|
||||
;Name=The name of the perk (max 63 characters)
|
||||
@@ -125,7 +125,7 @@ Skill5Mod=0
|
||||
|
||||
;##############################################################################
|
||||
[Traits]
|
||||
;Set to 1 to enable the modifications to traits
|
||||
;Set to 1 to enable modifications to traits
|
||||
Enable=0
|
||||
|
||||
;This is a modification to trait 0
|
||||
|
||||
@@ -141,11 +141,11 @@ DWORD _stdcall GetHSArg() {
|
||||
return (cArg == argCount) ? 0 : args[cArg++];
|
||||
}
|
||||
|
||||
void _stdcall SetHSArg(DWORD id, DWORD value) {
|
||||
void SetHSArg(DWORD id, DWORD value) {
|
||||
if (id < argCount) args[id] = value;
|
||||
}
|
||||
|
||||
DWORD* _stdcall GetHSArgs() {
|
||||
DWORD* GetHSArgs() {
|
||||
return args;
|
||||
}
|
||||
|
||||
|
||||
@@ -88,8 +88,8 @@ public:
|
||||
|
||||
DWORD _stdcall GetHSArgCount();
|
||||
DWORD _stdcall GetHSArg();
|
||||
DWORD* _stdcall GetHSArgs();
|
||||
void _stdcall SetHSArg(DWORD id, DWORD value);
|
||||
DWORD* GetHSArgs();
|
||||
void SetHSArg(DWORD id, DWORD value);
|
||||
void _stdcall SetHSReturn(DWORD d);
|
||||
|
||||
// register hook by proc num (special values: -1 - use default (start) procedure, 0 - unregister)
|
||||
|
||||
@@ -29,6 +29,8 @@ namespace sfall
|
||||
{
|
||||
using namespace fo;
|
||||
|
||||
long Perks::PerkLevelMod = 0;
|
||||
|
||||
constexpr int maxNameLen = 64; // don't change size
|
||||
constexpr int maxDescLen = 512; // don't change size
|
||||
static const int descLen = 256; // maximum text length for interface
|
||||
@@ -1291,7 +1293,7 @@ void PerksReset() {
|
||||
|
||||
// Reset some settable game values back to the defaults
|
||||
// Perk level mod
|
||||
SafeWrite32(0x496880, 0x019078);
|
||||
Perks::PerkLevelMod = 0;
|
||||
// Pyromaniac bonus
|
||||
SafeWrite8(0x424AB6, 5);
|
||||
// Swift Learner bonus
|
||||
|
||||
@@ -39,6 +39,8 @@ public:
|
||||
static DWORD HasFakeTrait(const char* name);
|
||||
static DWORD HasFakePerkOwner(const char* name, long objId);
|
||||
static DWORD HasFakeTraitOwner(const char* name, long objId);
|
||||
|
||||
static long PerkLevelMod;
|
||||
};
|
||||
|
||||
void PerksEnterCharScreen();
|
||||
|
||||
@@ -35,13 +35,11 @@ namespace script
|
||||
void __declspec(naked) op_set_global_script_repeat() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
mov ecx, eax;
|
||||
_GET_ARG_INT(end);
|
||||
mov edx, eax; // frames
|
||||
call SetGlobalScriptRepeat; // ecx - script
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -50,13 +48,11 @@ end:
|
||||
void __declspec(naked) op_set_global_script_type() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
mov ecx, eax;
|
||||
_GET_ARG_INT(end);
|
||||
mov edx, eax; // type
|
||||
call SetGlobalScriptType; // ecx - script
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -65,10 +61,8 @@ end:
|
||||
void __declspec(naked) op_available_global_script_types() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
mov edx, availableGlobalScriptTypes;
|
||||
_RET_VAL_INT(ecx);
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -114,79 +108,37 @@ void sf_get_sfall_global_float(OpcodeContext& ctx) {
|
||||
void __declspec(naked) op_get_sfall_arg() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
push eax;
|
||||
call GetHSArg;
|
||||
mov edx, eax;
|
||||
pop eax;
|
||||
_RET_VAL_INT(ecx);
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static DWORD _stdcall GetSfallArgs() {
|
||||
void sf_get_sfall_args(OpcodeContext& ctx) {
|
||||
DWORD argCount = GetHSArgCount();
|
||||
DWORD id = TempArray(argCount, 0);
|
||||
DWORD* args = GetHSArgs();
|
||||
for (DWORD i = 0; i < argCount; i++) {
|
||||
arrays[id].val[i].set(*(long*)&args[i]);
|
||||
}
|
||||
return id;
|
||||
ctx.setReturn(id);
|
||||
}
|
||||
|
||||
void __declspec(naked) op_get_sfall_args() { // rewrite to c++
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
push eax;
|
||||
call GetSfallArgs;
|
||||
mov edx, eax;
|
||||
pop eax;
|
||||
_RET_VAL_INT(ecx);
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) op_set_sfall_arg() {
|
||||
__asm {
|
||||
pushad;
|
||||
mov ecx, eax;
|
||||
call fo::funcoffs::interpretPopShort_;
|
||||
mov edi, eax;
|
||||
mov eax, ecx;
|
||||
call fo::funcoffs::interpretPopLong_;
|
||||
mov edx, eax;
|
||||
mov eax, ecx;
|
||||
call fo::funcoffs::interpretPopShort_;
|
||||
mov esi, eax;
|
||||
mov eax, ecx;
|
||||
call fo::funcoffs::interpretPopLong_;
|
||||
cmp di, VAR_TYPE_INT;
|
||||
jnz end;
|
||||
cmp si, VAR_TYPE_INT;
|
||||
jnz end;
|
||||
push edx;
|
||||
push eax;
|
||||
call SetHSArg;
|
||||
end:
|
||||
popad;
|
||||
retn;
|
||||
}
|
||||
void sf_set_sfall_arg(OpcodeContext& ctx) {
|
||||
SetHSArg(ctx.arg(0).rawValue(), ctx.arg(1).rawValue());
|
||||
}
|
||||
|
||||
void __declspec(naked) op_set_sfall_return() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
push eax;
|
||||
call SetHSReturn;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -194,26 +146,22 @@ end:
|
||||
|
||||
void __declspec(naked) op_init_hook() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
mov edx, initingHookScripts;
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) op_set_self() { // rewrite to c++
|
||||
void __declspec(naked) op_set_self() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
mov ecx, eax;
|
||||
_GET_ARG_INT(end);
|
||||
mov edx, eax; // object
|
||||
call SetSelfObject; // ecx - script
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
|
||||
@@ -41,9 +41,9 @@ void sf_get_sfall_global_float(OpcodeContext&);
|
||||
|
||||
void __declspec() op_get_sfall_arg();
|
||||
|
||||
void __declspec() op_get_sfall_args();
|
||||
void sf_get_sfall_args(OpcodeContext&);
|
||||
|
||||
void __declspec() op_set_sfall_arg();
|
||||
void sf_set_sfall_arg(OpcodeContext&);
|
||||
|
||||
void __declspec() op_set_sfall_return();
|
||||
|
||||
|
||||
@@ -32,14 +32,12 @@ namespace script
|
||||
|
||||
void __declspec(naked) op_graphics_funcs_available() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
cmp Graphics::mode, 3;
|
||||
seta dl;
|
||||
and edx, 0xFF;
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
@@ -86,12 +84,10 @@ result:
|
||||
void __declspec(naked) op_free_shader() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
push eax;
|
||||
call FreeShader;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -100,12 +96,10 @@ end:
|
||||
void __declspec(naked) op_activate_shader() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
push eax;
|
||||
call ActivateShader;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -114,12 +108,10 @@ end:
|
||||
void __declspec(naked) op_deactivate_shader() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
push eax;
|
||||
call DeactivateShader;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -414,13 +406,11 @@ end:
|
||||
void __declspec(naked) op_get_shader_version() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
push eax;
|
||||
call GetShaderVersion;
|
||||
mov edx, eax;
|
||||
pop eax;
|
||||
_RET_VAL_INT(ecx);
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -464,12 +454,10 @@ end:
|
||||
void __declspec(naked) op_force_graphics_refresh() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
push eax;
|
||||
call ForceGraphicsRefresh;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
|
||||
@@ -35,10 +35,8 @@ namespace script
|
||||
void __declspec(naked) op_input_funcs_available() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
mov edx, 1; // They're always available from 2.9 on
|
||||
_RET_VAL_INT(ecx);
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -51,7 +49,6 @@ void sf_key_pressed(OpcodeContext& ctx) {
|
||||
void __declspec(naked) op_tap_key() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
test eax, eax;
|
||||
jl end;
|
||||
@@ -60,7 +57,6 @@ void __declspec(naked) op_tap_key() {
|
||||
push eax;
|
||||
call TapKey;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -68,26 +64,22 @@ end:
|
||||
|
||||
void __declspec(naked) op_get_mouse_x() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
mov edx, ds:[FO_VAR_mouse_x_];
|
||||
add edx, ds:[FO_VAR_mouse_hotx];
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) op_get_mouse_y() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
mov edx, ds:[FO_VAR_mouse_y_];
|
||||
add edx, ds:[FO_VAR_mouse_hoty];
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
@@ -103,40 +95,34 @@ void sf_get_mouse_buttons(OpcodeContext& ctx) {
|
||||
|
||||
void __declspec(naked) op_get_window_under_mouse() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
mov edx, ds:[FO_VAR_last_button_winID];
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) op_get_screen_width() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
mov edx, ds:[FO_VAR_scr_size + 8]; // _scr_size.offx
|
||||
sub edx, ds:[FO_VAR_scr_size]; // _scr_size.x
|
||||
inc edx;
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) op_get_screen_height() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
mov edx, ds:[FO_VAR_scr_size + 12]; // _scr_size.offy
|
||||
sub edx, ds:[FO_VAR_scr_size + 4]; // _scr_size.y
|
||||
inc edx;
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
@@ -165,24 +151,20 @@ void sf_create_message_window(OpcodeContext &ctx) {
|
||||
|
||||
void __declspec(naked) op_get_viewport_x() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
mov edx, ds:[FO_VAR_wmWorldOffsetX];
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) op_get_viewport_y() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
mov edx, ds:[FO_VAR_wmWorldOffsetY];
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
@@ -190,11 +172,9 @@ void __declspec(naked) op_get_viewport_y() {
|
||||
void __declspec(naked) op_set_viewport_x() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
mov ds:[FO_VAR_wmWorldOffsetX], eax;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -203,11 +183,9 @@ end:
|
||||
void __declspec(naked) op_set_viewport_y() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
mov ds:[FO_VAR_wmWorldOffsetY], eax;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -323,19 +301,23 @@ void sf_set_iface_tag_text(OpcodeContext& ctx) {
|
||||
|
||||
void sf_inventory_redraw(OpcodeContext& ctx) {
|
||||
int mode;
|
||||
DWORD loopFlag = GetLoopFlags();
|
||||
if (loopFlag & INVENTORY) {
|
||||
mode = 0;
|
||||
} else if (loopFlag & INTFACEUSE) {
|
||||
mode = 1;
|
||||
} else if (loopFlag & INTFACELOOT) {
|
||||
mode = 2;
|
||||
} else if (loopFlag & BARTER) {
|
||||
mode = 3;
|
||||
} else {
|
||||
return;
|
||||
DWORD loopFlag = GetLoopFlags() & (INVENTORY | INTFACEUSE | INTFACELOOT | BARTER);
|
||||
switch (loopFlag) {
|
||||
case INVENTORY:
|
||||
mode = 0;
|
||||
break;
|
||||
case INTFACEUSE:
|
||||
mode = 1;
|
||||
break;
|
||||
case INTFACELOOT:
|
||||
mode = 2;
|
||||
break;
|
||||
case BARTER:
|
||||
mode = 3;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ctx.arg(0).asBool()) {
|
||||
fo::var::stack_offset[fo::var::curr_stack] = 0;
|
||||
fo::func::display_inventory(0, -1, mode);
|
||||
|
||||
@@ -289,8 +289,6 @@ void sf_set_object_knockback(OpcodeContext& ctx) {
|
||||
case 0x197:
|
||||
mode = 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
fo::GameObject* object = ctx.arg(0).asObject();
|
||||
if (mode) {
|
||||
@@ -316,8 +314,6 @@ void sf_remove_object_knockback(OpcodeContext& ctx) {
|
||||
case 0x19a:
|
||||
mode = 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
KnockbackRemoveMod(ctx.arg(0).asObject(), mode);
|
||||
}
|
||||
@@ -390,12 +386,10 @@ end:
|
||||
|
||||
void __declspec(naked) op_active_hand() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
mov edx, dword ptr ds:[FO_VAR_itemCurrentItem];
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
@@ -409,12 +403,10 @@ void __declspec(naked) op_toggle_active_hand() {
|
||||
|
||||
void __declspec(naked) op_eax_available() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
xor edx, edx
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
@@ -589,13 +581,11 @@ void sf_get_ini_string(OpcodeContext& ctx) {
|
||||
void __declspec(naked) op_get_uptime() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
push eax;
|
||||
call GetTickCount;
|
||||
mov edx, eax;
|
||||
pop eax;
|
||||
_RET_VAL_INT(ecx);
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -604,11 +594,9 @@ void __declspec(naked) op_get_uptime() {
|
||||
void __declspec(naked) op_set_car_current_town() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
mov ds:[FO_VAR_carCurrentArea], eax;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -617,13 +605,11 @@ end:
|
||||
void __declspec(naked) op_set_hp_per_level_mod() { // rewrite to c++
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
push eax; // allowed -/+127
|
||||
push 0x4AFBC1;
|
||||
call SafeWrite8;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -736,11 +722,9 @@ void sf_reset_critical_table(OpcodeContext& ctx) {
|
||||
void __declspec(naked) op_set_unspent_ap_bonus() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
mov standardApAcBonus, eax;
|
||||
mov Stats::standardApAcBonus, eax;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -748,12 +732,10 @@ end:
|
||||
|
||||
void __declspec(naked) op_get_unspent_ap_bonus() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
mov edx, standardApAcBonus;
|
||||
mov edx, Stats::standardApAcBonus;
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
@@ -761,11 +743,9 @@ void __declspec(naked) op_get_unspent_ap_bonus() {
|
||||
void __declspec(naked) op_set_unspent_ap_perk_bonus() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
mov extraApAcBonus, eax;
|
||||
mov Stats::extraApAcBonus, eax;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -773,12 +753,10 @@ end:
|
||||
|
||||
void __declspec(naked) op_get_unspent_ap_perk_bonus() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
mov edx, extraApAcBonus;
|
||||
mov edx, Stats::extraApAcBonus;
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
@@ -835,12 +813,10 @@ void __declspec(naked) op_nb_create_char() {
|
||||
void __declspec(naked) op_hero_select_win() { // for opening the appearance selection window
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(fail);
|
||||
push eax;
|
||||
call HeroSelectWindow;
|
||||
fail:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -849,12 +825,10 @@ fail:
|
||||
void __declspec(naked) op_set_hero_style() { // for setting the hero style/appearance takes an 1 int
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(fail);
|
||||
push eax;
|
||||
call SetHeroStyle;
|
||||
fail:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -863,12 +837,10 @@ fail:
|
||||
void __declspec(naked) op_set_hero_race() { // for setting the hero race takes an 1 int
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(fail);
|
||||
push eax;
|
||||
call SetHeroRace;
|
||||
fail:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -876,12 +848,10 @@ fail:
|
||||
|
||||
void __declspec(naked) op_get_light_level() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
mov edx, ds:[FO_VAR_ambient_light];
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
@@ -889,9 +859,7 @@ void __declspec(naked) op_get_light_level() {
|
||||
void __declspec(naked) op_refresh_pc_art() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
call RefreshPCArt;
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -945,12 +913,10 @@ end:
|
||||
void __declspec(naked) op_stop_sfall_sound() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
push eax;
|
||||
call StopSfallSound;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -992,12 +958,10 @@ end:
|
||||
|
||||
void __declspec(naked) op_modified_ini() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
mov edx, modifiedIni;
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
@@ -1005,12 +969,10 @@ void __declspec(naked) op_modified_ini() {
|
||||
void __declspec(naked) op_force_aimed_shots() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
push eax;
|
||||
call ForceAimedShots;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -1019,12 +981,10 @@ end:
|
||||
void __declspec(naked) op_disable_aimed_shots() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
push eax;
|
||||
call DisableAimedShots;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -1033,7 +993,6 @@ end:
|
||||
void __declspec(naked) op_mark_movie_played() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
test eax, eax;
|
||||
jl end;
|
||||
@@ -1041,7 +1000,6 @@ void __declspec(naked) op_mark_movie_played() {
|
||||
jge end;
|
||||
mov byte ptr ds:[eax + FO_VAR_gmovie_played_list], 1;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -1104,12 +1062,10 @@ end:
|
||||
void __declspec(naked) op_block_combat() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
push eax;
|
||||
call AIBlockCombat;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -1145,12 +1101,10 @@ void __declspec(naked) op_tile_under_cursor() {
|
||||
|
||||
void __declspec(naked) op_gdialog_get_barter_mod() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
mov edx, dword ptr ds:[FO_VAR_gdBarterMod];
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
@@ -1158,12 +1112,10 @@ void __declspec(naked) op_gdialog_get_barter_mod() {
|
||||
void __declspec(naked) op_set_inven_ap_cost() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
push eax;
|
||||
call SetInvenApCost;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
|
||||
@@ -30,12 +30,10 @@ namespace script
|
||||
|
||||
void __declspec(naked) op_get_perk_owed() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
movzx edx, byte ptr ds:[FO_VAR_free_perk];
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
@@ -43,14 +41,12 @@ void __declspec(naked) op_get_perk_owed() {
|
||||
void __declspec(naked) op_set_perk_owed() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
and eax, 0xFF;
|
||||
cmp eax, 250;
|
||||
jg end;
|
||||
mov byte ptr ds:[FO_VAR_free_perk], al;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -59,12 +55,10 @@ end:
|
||||
void __declspec(naked) op_set_perk_freq() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
push eax;
|
||||
call SetPerkFreq;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -309,12 +303,10 @@ void sf_has_fake_trait_npc(OpcodeContext& ctx) {
|
||||
void __declspec(naked) op_perk_add_mode() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
push eax;
|
||||
call AddPerkMode;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -347,13 +339,11 @@ next:
|
||||
void __declspec(naked) op_set_pyromaniac_mod() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
push eax;
|
||||
push 0x424AB6;
|
||||
call SafeWrite8;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -371,13 +361,45 @@ void __declspec(naked) op_apply_heaveho_fix() {
|
||||
void __declspec(naked) op_set_swiftlearner_mod() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
push eax;
|
||||
push 0x4AFAE2;
|
||||
call SafeWrite32;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) perk_can_add_hook() {
|
||||
__asm {
|
||||
call fo::funcoffs::stat_pc_get_;
|
||||
add eax, Perks::PerkLevelMod;
|
||||
js jneg; // level < 0
|
||||
retn;
|
||||
jneg:
|
||||
xor eax, eax;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __fastcall SetPerkLevelMod(long mod) {
|
||||
static bool perkLevelModPatch = false;
|
||||
if (mod < -25 || mod > 25) return;
|
||||
Perks::PerkLevelMod = mod;
|
||||
|
||||
if (perkLevelModPatch) return;
|
||||
perkLevelModPatch = true;
|
||||
HookCall(0x49687F, perk_can_add_hook);
|
||||
}
|
||||
|
||||
void __declspec(naked) op_set_perk_level_mod() {
|
||||
__asm {
|
||||
push ecx;
|
||||
_GET_ARG_INT(end);
|
||||
mov ecx, eax;
|
||||
call SetPerkLevelMod;
|
||||
end:
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
|
||||
@@ -75,5 +75,7 @@ void __declspec() op_apply_heaveho_fix();
|
||||
|
||||
void __declspec() op_set_swiftlearner_mod();
|
||||
|
||||
void __declspec() op_set_perk_level_mod();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,13 +237,11 @@ end:
|
||||
void __declspec(naked) op_set_available_skill_points() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
mov edx, eax;
|
||||
xor eax, eax;
|
||||
call fo::funcoffs::stat_pc_set_;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -251,12 +249,10 @@ end:
|
||||
|
||||
void __declspec(naked) op_get_available_skill_points() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
mov edx, dword ptr ds:[FO_VAR_curr_pc_stat];
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
@@ -264,7 +260,6 @@ void __declspec(naked) op_get_available_skill_points() {
|
||||
void __declspec(naked) op_mod_skill_points_per_level() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
cmp eax, 100;
|
||||
jg end;
|
||||
@@ -275,7 +270,6 @@ void __declspec(naked) op_mod_skill_points_per_level() {
|
||||
push 0x43C27A;
|
||||
call SafeWrite8;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -876,88 +870,29 @@ end:
|
||||
}
|
||||
}
|
||||
|
||||
static float xpmod;
|
||||
static DWORD xptmp;
|
||||
static void __declspec(naked) SetXpMod3() {
|
||||
static DWORD xpTemp;
|
||||
static void __declspec(naked) statPCAddExperienceCheckPMs_hack() {
|
||||
__asm {
|
||||
push ebx;
|
||||
push ecx;
|
||||
push esi;
|
||||
push edi;
|
||||
push ebp;
|
||||
mov xptmp, eax;
|
||||
fild xptmp;
|
||||
fmul xpmod;
|
||||
fistp xptmp;
|
||||
mov eax, xptmp;
|
||||
push 0x4AFABD;
|
||||
retn;
|
||||
mov ebp, [esp]; // return addr
|
||||
mov xpTemp, eax; // experience
|
||||
fild xpTemp;
|
||||
fmul Stats::experienceMod;
|
||||
fistp xpTemp;
|
||||
mov eax, xpTemp;
|
||||
sub esp, 0xC; // instead of 0x10
|
||||
mov edi, eax;
|
||||
jmp ebp;
|
||||
}
|
||||
}
|
||||
|
||||
static void _stdcall SetXpMod2(DWORD percent) {
|
||||
MakeJump(0x4AFAB8, SetXpMod3);
|
||||
xpmod = (float)percent / 100.0f;
|
||||
}
|
||||
void sf_set_xp_mod(OpcodeContext& ctx) {
|
||||
static bool xpModPatch = false;
|
||||
DWORD percent = ctx.arg(0).rawValue() & 0xFFFF;
|
||||
Stats::experienceMod = (float)percent / 100.0f;
|
||||
|
||||
static int PerkLevelMod;
|
||||
static void __declspec(naked) SetPerkLevelMod3() {
|
||||
__asm {
|
||||
push ebx;
|
||||
call fo::funcoffs::stat_pc_get_;
|
||||
pop ebx;
|
||||
add eax, PerkLevelMod;
|
||||
cmp eax, 0;
|
||||
jge end;
|
||||
xor eax, eax;
|
||||
end:
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void _stdcall SetPerkLevelMod2(int mod) {
|
||||
if (mod < -25 || mod > 25) return;
|
||||
PerkLevelMod = mod;
|
||||
HookCall(0x49687F, &SetPerkLevelMod3);
|
||||
}
|
||||
|
||||
void __declspec(naked) op_set_xp_mod() {
|
||||
__asm {
|
||||
push ebx;
|
||||
push ecx;
|
||||
push edx;
|
||||
push edi;
|
||||
mov ecx, eax;
|
||||
call fo::funcoffs::interpretPopShort_;
|
||||
mov edx, eax;
|
||||
mov eax, ecx;
|
||||
call fo::funcoffs::interpretPopLong_;
|
||||
cmp dx, VAR_TYPE_INT;
|
||||
jnz end;
|
||||
and eax, 0xFFFF;
|
||||
push eax;
|
||||
call SetXpMod2;
|
||||
end:
|
||||
pop edi;
|
||||
pop edx;
|
||||
pop ecx;
|
||||
pop ebx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) op_set_perk_level_mod() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
_GET_ARG_INT(end);
|
||||
push eax;
|
||||
call SetPerkLevelMod2;
|
||||
end:
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
if (xpModPatch) return;
|
||||
xpModPatch = true;
|
||||
MakeCall(0x4AFABD, statPCAddExperienceCheckPMs_hack);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -84,9 +84,7 @@ void __declspec() op_set_npc_stat_max();
|
||||
|
||||
void __declspec() op_set_npc_stat_min();
|
||||
|
||||
void __declspec() op_set_xp_mod();
|
||||
|
||||
void __declspec() op_set_perk_level_mod();
|
||||
void sf_set_xp_mod(OpcodeContext&);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,13 +89,11 @@ void sf_force_encounter(OpcodeContext& cxt) {
|
||||
void __declspec(naked) op_in_world_map() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
push eax;
|
||||
call InWorldMap;
|
||||
mov edx, eax;
|
||||
pop eax;
|
||||
_RET_VAL_INT(ecx);
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -104,13 +102,11 @@ void __declspec(naked) op_in_world_map() {
|
||||
void __declspec(naked) op_get_game_mode() {
|
||||
__asm {
|
||||
push ecx;
|
||||
push edx;
|
||||
push eax;
|
||||
call GetLoopFlags;
|
||||
mov edx, eax;
|
||||
pop eax;
|
||||
_RET_VAL_INT(ecx);
|
||||
pop edx;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
@@ -118,24 +114,20 @@ void __declspec(naked) op_get_game_mode() {
|
||||
|
||||
void __declspec(naked) op_get_world_map_x_pos() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
mov edx, ds:[FO_VAR_world_xpos];
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) op_get_world_map_y_pos() {
|
||||
__asm {
|
||||
push edx;
|
||||
push ecx;
|
||||
mov edx, ds:[FO_VAR_world_ypos];
|
||||
_RET_VAL_INT(ecx);
|
||||
pop ecx;
|
||||
pop edx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@ static SfallOpcodeInfo opcodeInfoArray[] = {
|
||||
{0x19e, "get_sfall_global_int", sf_get_sfall_global_int, 1, true, {ARG_INTSTR}},
|
||||
{0x19f, "get_sfall_global_float", sf_get_sfall_global_float, 1, true, {ARG_INTSTR}},
|
||||
{0x1a5, "inc_npc_level", sf_inc_npc_level, 1, false, {ARG_INTSTR}},
|
||||
{0x1aa, "set_xp_mod", sf_set_xp_mod, 1, false, {ARG_INT}},
|
||||
{0x1ac, "get_ini_setting", sf_get_ini_setting, 1, true, {ARG_STRING}},
|
||||
|
||||
{0x1bb, "set_fake_perk", sf_set_fake_perk, 4, false, {ARG_STRING, ARG_INT, ARG_INT, ARG_STRING}},
|
||||
@@ -159,6 +160,8 @@ static SfallOpcodeInfo opcodeInfoArray[] = {
|
||||
{0x237, "atoi", sf_atoi, 1, true, {ARG_STRING}},
|
||||
{0x238, "atof", sf_atof, 1, true, {ARG_STRING}},
|
||||
{0x239, "scan_array", sf_scan_array, 2, true, {ARG_OBJECT, ARG_ANY}},
|
||||
{0x23c, "get_sfall_args", sf_get_sfall_args, 0, true},
|
||||
{0x23d, "set_sfall_arg", sf_set_sfall_arg, 2, false, {ARG_INT, ARG_INT}},
|
||||
{0x241, "get_npc_level", sf_get_npc_level, 1, true, {ARG_INTSTR}},
|
||||
|
||||
{0x24e, "substr", sf_substr, 3, true, {ARG_STRING, ARG_INT, ARG_INT}},
|
||||
@@ -327,7 +330,6 @@ void InitNewOpcodes() {
|
||||
opcodes[0x1a7] = op_get_viewport_y;
|
||||
opcodes[0x1a8] = op_set_viewport_x;
|
||||
opcodes[0x1a9] = op_set_viewport_y;
|
||||
opcodes[0x1aa] = op_set_xp_mod;
|
||||
opcodes[0x1ab] = op_set_perk_level_mod;
|
||||
opcodes[0x1ad] = op_get_shader_version;
|
||||
opcodes[0x1ae] = op_set_shader_mode;
|
||||
@@ -394,8 +396,6 @@ void InitNewOpcodes() {
|
||||
|
||||
opcodes[0x23a] = op_get_tile_fid;
|
||||
opcodes[0x23b] = op_modified_ini;
|
||||
opcodes[0x23c] = op_get_sfall_args;
|
||||
opcodes[0x23d] = op_set_sfall_arg;
|
||||
opcodes[0x23e] = op_force_aimed_shots;
|
||||
opcodes[0x23f] = op_disable_aimed_shots;
|
||||
opcodes[0x240] = op_mark_movie_played;
|
||||
|
||||
+17
-20
@@ -16,9 +16,6 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "..\main.h"
|
||||
#include "..\FalloutEngine\Fallout2.h"
|
||||
#include "CritterStats.h"
|
||||
@@ -36,6 +33,10 @@ static DWORD statMinimumsNPC[fo::STAT_max_stat];
|
||||
|
||||
static DWORD xpTable[99];
|
||||
|
||||
float Stats::experienceMod = 1.0f; // set_xp_mod func
|
||||
DWORD Stats::standardApAcBonus = 4;
|
||||
DWORD Stats::extraApAcBonus = 4;
|
||||
|
||||
static struct StatFormula {
|
||||
long base;
|
||||
long min;
|
||||
@@ -43,9 +44,6 @@ static struct StatFormula {
|
||||
double multi[fo::STAT_lu + 1];
|
||||
} statFormulas[fo::STAT_max_derived + 1] = {0};
|
||||
|
||||
DWORD standardApAcBonus = 4;
|
||||
DWORD extraApAcBonus = 4;
|
||||
|
||||
static fo::GameObject* cCritter;
|
||||
|
||||
static const DWORD StatLevelHack_Ret = 0x4AEF52;
|
||||
@@ -136,12 +134,12 @@ static void __declspec(naked) CalcApToAcBonus() {
|
||||
mov edx, PERK_hth_evade_perk;
|
||||
mov eax, dword ptr ds:[FO_VAR_obj_dude];
|
||||
call fo::funcoffs::perk_level_;
|
||||
imul eax, extraApAcBonus; // bonus = perkLvl * extraApBonus
|
||||
imul eax, edi; // perkBonus = bonus * curAP
|
||||
imul eax, Stats::extraApAcBonus; // bonus = perkLvl * extraApBonus
|
||||
imul eax, edi; // perkBonus = bonus * curAP
|
||||
standard:
|
||||
imul edi, standardApAcBonus; // stdBonus = curAP * standardApBonus
|
||||
add eax, edi; // bonus = perkBonus + stdBonus
|
||||
shr eax, 2; // acBonus = bonus / 4
|
||||
imul edi, Stats::standardApAcBonus; // stdBonus = curAP * standardApBonus
|
||||
add eax, edi; // bonus = perkBonus + stdBonus
|
||||
shr eax, 2; // acBonus = bonus / 4
|
||||
end:
|
||||
retn;
|
||||
}
|
||||
@@ -212,13 +210,11 @@ allow:
|
||||
}
|
||||
}
|
||||
|
||||
void StatsReset() {
|
||||
static void StatsReset() {
|
||||
for (int i = 0; i < fo::STAT_max_stat; i++) {
|
||||
statMaximumsPC[i] = statMaximumsNPC[i] = fo::var::stat_data[i].maxValue;
|
||||
statMinimumsPC[i] = statMinimumsNPC[i] = fo::var::stat_data[i].minValue;
|
||||
}
|
||||
standardApAcBonus = 4;
|
||||
extraApAcBonus = 4;
|
||||
}
|
||||
|
||||
void Stats::init() {
|
||||
@@ -228,13 +224,14 @@ void Stats::init() {
|
||||
|
||||
LoadGameHook::OnGameReset() += []() {
|
||||
StatsReset();
|
||||
//Reset some settable game values back to the defaults
|
||||
//xp mod
|
||||
SafeWrite8(0x4AFAB8, 0x53);
|
||||
SafeWrite32(0x4AFAB9, 0x55575651);
|
||||
//HP bonus
|
||||
// Reset some settable game values back to the defaults
|
||||
standardApAcBonus = 4;
|
||||
extraApAcBonus = 4;
|
||||
// XP mod set to 100%
|
||||
experienceMod = 1.0f;
|
||||
// HP bonus
|
||||
SafeWrite8(0x4AFBC1, 2);
|
||||
//skill points per level mod
|
||||
// Skill points per level mod
|
||||
SafeWrite8(0x43C27A, 5);
|
||||
};
|
||||
|
||||
|
||||
@@ -27,13 +27,15 @@ class Stats : public Module {
|
||||
public:
|
||||
const char* name() { return "Stats"; }
|
||||
void init();
|
||||
|
||||
static float experienceMod;
|
||||
static DWORD standardApAcBonus;
|
||||
static DWORD extraApAcBonus;
|
||||
};
|
||||
|
||||
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 DWORD standardApAcBonus;
|
||||
extern DWORD extraApAcBonus;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user