From c9034f917b3633c77640efa71d6c6dde72efd8c1 Mon Sep 17 00:00:00 2001 From: NovaRain Date: Wed, 17 May 2023 00:14:44 +0800 Subject: [PATCH] Added "set_spray_settings" function for scriptable burst (#36) * Current implementation works similar to metarule2_explosions. documentation will come later. --- artifacts/scripting/headers/sfall.h | 1 + sfall/Modules/BurstMods.cpp | 36 ++++++++++++++++++- sfall/Modules/BurstMods.h | 2 ++ sfall/Modules/Scripting/Handlers/Combat.cpp | 20 +++++++++++ sfall/Modules/Scripting/Handlers/Combat.h | 2 ++ sfall/Modules/Scripting/Handlers/Metarule.cpp | 1 + 6 files changed, 61 insertions(+), 1 deletion(-) diff --git a/artifacts/scripting/headers/sfall.h b/artifacts/scripting/headers/sfall.h index df60b340..73efa8e5 100644 --- a/artifacts/scripting/headers/sfall.h +++ b/artifacts/scripting/headers/sfall.h @@ -373,6 +373,7 @@ #define set_rest_heal_time(time) sfall_func1("set_rest_heal_time", time) #define set_rest_mode(mode) sfall_func1("set_rest_mode", mode) #define set_scr_name(name) sfall_func1("set_scr_name", name) +#define set_spray_settings(ctrMult, ctrDiv, tgtMult, tgtDiv) sfall_func4("set_spray_settings", ctrMult, ctrDiv, tgtMult, tgtDiv) #define set_terrain_name(x, y, name) sfall_func3("set_terrain_name", x, y, name) #define set_town_title(areaID, title) sfall_func2("set_town_title", areaID, title) #define set_unique_id(obj) sfall_func1("set_unique_id", obj) diff --git a/sfall/Modules/BurstMods.cpp b/sfall/Modules/BurstMods.cpp index 0f70466d..3008e78e 100644 --- a/sfall/Modules/BurstMods.cpp +++ b/sfall/Modules/BurstMods.cpp @@ -19,6 +19,7 @@ #include "..\main.h" #include "BurstMods.h" +#include "MainLoopHook.h" namespace sfall { @@ -28,6 +29,14 @@ static long compute_spray_center_div; static long compute_spray_target_mult; static long compute_spray_target_div; +// default values +static long compute_spray_center_mult_def; +static long compute_spray_center_div_def; +static long compute_spray_target_mult_def; +static long compute_spray_target_div_def; + +static bool computeSpraySettingsReset = false; + static long __fastcall ComputeSpray(DWORD* roundsLeftOut, DWORD* roundsRightOut, DWORD totalRounds, DWORD* roundsCenterOut) { // roundsCenter = totalRounds * mult / div long result = totalRounds * compute_spray_center_mult; @@ -65,8 +74,25 @@ static void __declspec(naked) compute_spray_rounds_distribution() { } } +void BurstMods::SetComputeSpraySettings(long centerMult, long centerDiv, long targetMult, long targetDiv) { + compute_spray_center_mult = centerMult; + compute_spray_center_div = centerDiv; + compute_spray_target_mult = targetMult; + compute_spray_target_div = targetDiv; + computeSpraySettingsReset = true; +} + +void ResetComputeSpraySettings() { + if (!computeSpraySettingsReset) return; + compute_spray_center_mult = compute_spray_center_mult_def; + compute_spray_center_div = compute_spray_center_div_def; + compute_spray_target_mult = compute_spray_target_mult_def; + compute_spray_target_div = compute_spray_target_div_def; + computeSpraySettingsReset = false; +} + void BurstMods::init() { - //if (IniReader::GetConfigInt("Misc", "ComputeSprayMod", 0)) { + //if (IniReader::GetConfigInt("Misc", "ComputeSprayMod", 1)) { dlogr("Applying ComputeSpray settings to burst attacks.", DL_INIT); compute_spray_center_mult = IniReader::GetConfigInt("Misc", "ComputeSpray_CenterMult", 1); compute_spray_center_div = IniReader::GetConfigInt("Misc", "ComputeSpray_CenterDiv", 3); @@ -76,6 +102,9 @@ void BurstMods::init() { if (compute_spray_center_mult > compute_spray_center_div) { compute_spray_center_mult = compute_spray_center_div; } + compute_spray_center_mult_def = compute_spray_center_mult; + compute_spray_center_div_def = compute_spray_center_div; + compute_spray_target_mult = IniReader::GetConfigInt("Misc", "ComputeSpray_TargetMult", 1); compute_spray_target_div = IniReader::GetConfigInt("Misc", "ComputeSpray_TargetDiv", 2); if (compute_spray_target_div < 1) { @@ -84,7 +113,12 @@ void BurstMods::init() { if (compute_spray_target_mult > compute_spray_target_div) { compute_spray_target_mult = compute_spray_target_div; } + compute_spray_target_mult_def = compute_spray_target_mult; + compute_spray_target_div_def = compute_spray_target_div; + MakeJump(0x4234F1, compute_spray_rounds_distribution); + // after each combat attack, reset ComputeSpray settings + MainLoopHook::OnAfterCombatAttack() += ResetComputeSpraySettings; //} } diff --git a/sfall/Modules/BurstMods.h b/sfall/Modules/BurstMods.h index 1b2fad7d..948e3772 100644 --- a/sfall/Modules/BurstMods.h +++ b/sfall/Modules/BurstMods.h @@ -27,6 +27,8 @@ class BurstMods : public Module { public: const char* name() { return "BurstMods"; } void init(); + + static void SetComputeSpraySettings(long centerMult, long centerDiv, long targetMult, long targetDiv); }; } diff --git a/sfall/Modules/Scripting/Handlers/Combat.cpp b/sfall/Modules/Scripting/Handlers/Combat.cpp index d9e281dc..3ea04ada 100644 --- a/sfall/Modules/Scripting/Handlers/Combat.cpp +++ b/sfall/Modules/Scripting/Handlers/Combat.cpp @@ -19,6 +19,7 @@ #include "..\..\..\FalloutEngine\AsmMacros.h" #include "..\..\..\FalloutEngine\Fallout2.h" #include "..\..\AI.h" +#include "..\..\BurstMods.h" #include "..\..\Combat.h" #include "..\..\KillCounter.h" @@ -241,5 +242,24 @@ void mf_combat_data(OpcodeContext& ctx) { ctx.setReturn((DWORD)ctd, DataType::INT); } +void mf_set_spray_settings(OpcodeContext& ctx) { + long centerMult = ctx.arg(0).rawValue(), + centerDiv = ctx.arg(1).rawValue(), + targetMult = ctx.arg(2).rawValue(), + targetDiv = ctx.arg(3).rawValue(); + + if (centerDiv < 1) centerDiv = 1; + if (centerMult > centerDiv) { + centerMult = centerDiv; + ctx.printOpcodeError("%s() - Warning: centerMult value is capped at centerDiv.", ctx.getMetaruleName()); + } + if (targetDiv < 1) targetDiv = 1; + if (targetMult > targetDiv) { + targetMult = targetDiv; + ctx.printOpcodeError("%s() - Warning: targetMult value is capped at targetDiv.", ctx.getMetaruleName()); + } + BurstMods::SetComputeSpraySettings(centerMult, centerDiv, targetMult, targetDiv); +} + } } diff --git a/sfall/Modules/Scripting/Handlers/Combat.h b/sfall/Modules/Scripting/Handlers/Combat.h index e480457c..e3cbad0d 100644 --- a/sfall/Modules/Scripting/Handlers/Combat.h +++ b/sfall/Modules/Scripting/Handlers/Combat.h @@ -56,5 +56,7 @@ void mf_attack_is_aimed(OpcodeContext&); void mf_combat_data(OpcodeContext&); +void mf_set_spray_settings(OpcodeContext&); + } } diff --git a/sfall/Modules/Scripting/Handlers/Metarule.cpp b/sfall/Modules/Scripting/Handlers/Metarule.cpp index 8034c37e..0b86fb27 100644 --- a/sfall/Modules/Scripting/Handlers/Metarule.cpp +++ b/sfall/Modules/Scripting/Handlers/Metarule.cpp @@ -125,6 +125,7 @@ static const SfallMetarule metarules[] = { {"outlined_object", mf_outlined_object, 0, 0}, {"real_dude_obj", mf_real_dude_obj, 0, 0}, {"remove_timer_event", mf_remove_timer_event, 0, 1, -1, {ARG_INT}}, + {"set_spray_settings", mf_set_spray_settings, 4, 4, -1, {ARG_INT, ARG_INT, ARG_INT, ARG_INT}}, {"set_can_rest_on_map", mf_set_rest_on_map, 3, 3, -1, {ARG_INT, ARG_INT, ARG_INT}}, {"set_car_intface_art", mf_set_car_intface_art, 1, 1, -1, {ARG_INT}}, {"set_cursor_mode", mf_set_cursor_mode, 1, 1, -1, {ARG_INT}},