Rewrote set_xp_mod, get_sfall_args, set_sfall_arg functions in C++

Cleanup in ASM scripting handlers code.
This commit is contained in:
NovaRain
2019-10-14 15:29:03 +08:00
parent 882a601b0c
commit ab2283f0e3
18 changed files with 117 additions and 295 deletions
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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;
}
+2 -2
View File
@@ -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)
+3 -1
View File
@@ -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
+2
View File
@@ -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();
+5 -57
View File
@@ -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;
}
+2 -2
View File
@@ -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;
}
+16 -34
View File
@@ -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);
+4 -52
View File
@@ -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;
}
+34 -12
View File
@@ -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;
}
+2
View File
@@ -75,5 +75,7 @@ void __declspec() op_apply_heaveho_fix();
void __declspec() op_set_swiftlearner_mod();
void __declspec() op_set_perk_level_mod();
}
}
+18 -83
View File
@@ -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);
}
}
+1 -3
View File
@@ -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;
}
}
+3 -3
View File
@@ -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
View File
@@ -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);
};
+4 -2
View File
@@ -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;
}