diff --git a/artifacts/scripting/headers/sfall.h b/artifacts/scripting/headers/sfall.h index d04fbff1..38ce940d 100644 --- a/artifacts/scripting/headers/sfall.h +++ b/artifacts/scripting/headers/sfall.h @@ -132,6 +132,7 @@ #define set_attack_explosion_radius(x) metarule2_explosions(3, x, 0) #define set_attack_is_explosion(x) metarule2_explosions(4, x, 0) #define set_attack_is_explosion_fire set_attack_is_explosion(DMG_fire) +#define set_explosion_radius(grenade, rocket) metarule2_explosions(5, grenade, rocket) #define GAME_MSG_COMBAT (0) diff --git a/artifacts/scripting/sfall function notes.txt b/artifacts/scripting/sfall function notes.txt index ee85ab2a..87383796 100644 --- a/artifacts/scripting/sfall function notes.txt +++ b/artifacts/scripting/sfall function notes.txt @@ -231,6 +231,10 @@ was made as a dirty easy hack to allow dynamically change some explosion paramet > void set_attack_is_explosion_fire - if you call this right before using a weapon with fire damage type, it will produce explosion effects (and radius damage) just like "explosion" type, but all targets will still receive fire damage. +> void set_explosion_radius(grenade, rocket) +- sets a permanent radius of the explosion for grenades and/or rockets. Passing 0 means not changing the corresponding radius. +- changed radius will be reset each time the player reloads the game. + Some utility/math functions are available: diff --git a/sfall/Define.h b/sfall/Define.h index 1c22112a..1c87a61b 100644 --- a/sfall/Define.h +++ b/sfall/Define.h @@ -1,16 +1,15 @@ #pragma once // PIDS of some items +#define PID_MOTION_SENSOR 59 +#define PID_SUPER_STIMPAK 144 #define PID_ACTIVE_GEIGER_COUNTER 207 #define PID_ACTIVE_STEALTH_BOY 210 -#define PID_CAR_TRUNK 455 - -#define PID_DRIVABLE_CAR 33555441 #define PID_JET 259 +#define PID_CAR_TRUNK 455 #define PID_JESSE_CONTAINER 467 -#define PID_MOTION_SENSOR 59 #define PID_Player 16777216 -#define PID_SUPER_STIMPAK 144 +#define PID_DRIVABLE_CAR 33555441 //XXXXXXXXXXXXXXXXXXXXX //XX Critter defines XX diff --git a/sfall/Explosions.cpp b/sfall/Explosions.cpp index 6d336e71..90fc4c92 100644 --- a/sfall/Explosions.cpp +++ b/sfall/Explosions.cpp @@ -23,6 +23,7 @@ #include "ScriptExtender.h" static bool lightingEnabled = false; +static bool explosionsMetaruleReset = false; static const DWORD ranged_attack_lighting_fix_back = 0x4118F8; @@ -96,7 +97,6 @@ static void __declspec(naked) explosion_lighting_fix2() { } } - DWORD _stdcall LogThis(DWORD value1, DWORD value2, DWORD value3) { dlog_f("anim_set_check__light_fix: object 0x%X, something 0x%X, radius 0x%X", DL_MAIN, value1, value2, value3); return value1; @@ -147,13 +147,15 @@ static void __declspec(naked) fire_dance_lighting_fix1() { } - -static const DWORD explosion_dmg_check_adr[] = {0x411709, 0x4119FC, 0x411C08, 0x4517C1, 0x423BC8}; +static const DWORD explosion_dmg_check_adr[] = {0x411709, 0x4119FC, 0x411C08, 0x4517C1, 0x423BC8, 0x42381A}; static const DWORD explosion_art_adr[] = {0x411A19, 0x411A29, 0x411A35, 0x411A3C}; static const DWORD explosion_art_defaults[] = {10, 2, 31, 29}; static const DWORD explosion_radius_grenade = 0x479183; static const DWORD explosion_radius_rocket = 0x47918B; +static DWORD set_expl_radius_grenade = 2; +static DWORD set_expl_radius_rocket = 3; + static const size_t numArtChecks = sizeof(explosion_art_adr) / sizeof(explosion_art_adr[0]); static const size_t numDmgChecks = sizeof(explosion_dmg_check_adr) / sizeof(explosion_dmg_check_adr[0]); @@ -161,8 +163,14 @@ static const size_t numDmgChecks = sizeof(explosion_dmg_check_adr) / sizeof(expl #define EXPL_FORCE_EXPLOSION_ART (2) #define EXPL_FORCE_EXPLOSION_RADIUS (3) #define EXPL_FORCE_EXPLOSION_DMGTYPE (4) +#define EXPL_STATIC_EXPLOSION_RADIUS (5) -DWORD _stdcall ExplosionsMetaruleFunc(DWORD mode, DWORD arg1, DWORD arg2) { +static void SetExplosionRadius(int arg1, int arg2) { + SafeWrite32(explosion_radius_grenade, arg1); + SafeWrite32(explosion_radius_rocket, arg2); +} + +int _stdcall ExplosionsMetaruleFunc(int mode, int arg1, int arg2) { switch (mode) { case EXPL_FORCE_EXPLOSION_PATTERN: if (arg1) { @@ -179,19 +187,27 @@ DWORD _stdcall ExplosionsMetaruleFunc(DWORD mode, DWORD arg1, DWORD arg2) { } break; case EXPL_FORCE_EXPLOSION_RADIUS: - SafeWrite32(explosion_radius_grenade, arg1); - SafeWrite32(explosion_radius_rocket, arg1); + SetExplosionRadius(arg1, arg1); break; case EXPL_FORCE_EXPLOSION_DMGTYPE: for (int i = 0; i < numDmgChecks; i++) { SafeWrite8(explosion_dmg_check_adr[i], (BYTE)arg1); } break; + case EXPL_STATIC_EXPLOSION_RADIUS: + if (arg1 > 0) set_expl_radius_grenade = arg1; + if (arg2 > 0) set_expl_radius_rocket = arg2; + SetExplosionRadius(set_expl_radius_grenade, set_expl_radius_rocket); + break; + default: + return -1; } + if (mode != EXPL_STATIC_EXPLOSION_RADIUS) explosionsMetaruleReset = true; return 0; } void ResetExplosionSettings() { + if (!explosionsMetaruleReset) return; // explosion pattern explosion_effect_starting_dir = 0; SafeWrite8(0x411B54, 6); // last direction @@ -200,15 +216,20 @@ void ResetExplosionSettings() { SafeWrite32(explosion_art_adr[i], explosion_art_defaults[i]); } // explosion radiuses - SafeWrite32(explosion_radius_grenade, 2); - SafeWrite32(explosion_radius_rocket, 3); + SetExplosionRadius(set_expl_radius_grenade, set_expl_radius_rocket); // explosion dmgtype for (int i = 0; i < numDmgChecks; i++) { SafeWrite8(explosion_dmg_check_adr[i], 6); } + explosionsMetaruleReset = false; } -void ExplosionLightingInit() { +void ResetExplosionRadius() { + if (set_expl_radius_grenade != 2 || set_expl_radius_rocket != 3) + SetExplosionRadius(2, 3); +} + +void ExplosionInit() { MakeJump(0x411AB4, explosion_effect_hook); // required for explosions_metarule lightingEnabled = GetPrivateProfileIntA("Misc", "ExplosionsEmitLight", 0, ini) != 0; @@ -220,4 +241,10 @@ void ExplosionLightingInit() { dlogr(" Done", DL_INIT); } + + DWORD tmp; + tmp = SimplePatch(0x4A2873, "Misc", "Dynamite_DmgMax", 50, 0, 9999); + SimplePatch(0x4A2878, "Misc", "Dynamite_DmgMin", 30, 0, tmp); + tmp = SimplePatch(0x4A287F, "Misc", "PlasticExplosive_DmgMax", 80, 0, 9999); + SimplePatch(0x4A2884, "Misc", "PlasticExplosive_DmgMin", 40, 0, tmp); } \ No newline at end of file diff --git a/sfall/Explosions.h b/sfall/Explosions.h index 2dfbe8b6..e8533c1a 100644 --- a/sfall/Explosions.h +++ b/sfall/Explosions.h @@ -18,6 +18,7 @@ #pragma once -void ExplosionLightingInit(); -DWORD _stdcall ExplosionsMetaruleFunc(DWORD mode, DWORD arg1, DWORD arg2); -void ResetExplosionSettings(); \ No newline at end of file +void ExplosionInit(); +int _stdcall ExplosionsMetaruleFunc(int mode, int arg1, int arg2); +void ResetExplosionSettings(); +void ResetExplosionRadius(); diff --git a/sfall/LoadGameHook.cpp b/sfall/LoadGameHook.cpp index fd344446..df33ada3 100644 --- a/sfall/LoadGameHook.cpp +++ b/sfall/LoadGameHook.cpp @@ -23,6 +23,7 @@ #include "Bugs.h" #include "Console.h" #include "Criticals.h" +#include "Explosions.h" #include "FalloutEngine.h" #include "FileSystem.h" #include "Graphics.h" @@ -78,6 +79,7 @@ static void _stdcall ResetState(DWORD onLoad) { InventoryReset(); RegAnimCombatCheck(1); AfterAttackCleanup(); + ResetExplosionRadius(); PartyControlReset(); } diff --git a/sfall/main.cpp b/sfall/main.cpp index 06dd8190..4245ba7f 100644 --- a/sfall/main.cpp +++ b/sfall/main.cpp @@ -1443,11 +1443,7 @@ static void DllMain2() { // phobos2077: ComputeSprayModInit(); - ExplosionLightingInit(); - tmp = SimplePatch(0x4A2873, "Misc", "Dynamite_DmgMax", 50, 0, 9999); - SimplePatch(0x4A2878, "Misc", "Dynamite_DmgMin", 30, 0, tmp); - tmp = SimplePatch(0x4A287F, "Misc", "PlasticExplosive_DmgMax", 80, 0, 9999); - SimplePatch(0x4A2884, "Misc", "PlasticExplosive_DmgMin", 40, 0, tmp); + ExplosionInit(); BooksInit(); DWORD addrs[2] = {0x45F9DE, 0x45FB33}; SimplePatch(addrs, 2, "Misc", "CombatPanelAnimDelay", 1000, 0, 65535);