Backported metarule2_explosions modes from 4.1

Updated version number.
This commit is contained in:
NovaRain
2020-11-05 12:13:25 +08:00
parent 38a0ddb1eb
commit cdeb970d4f
9 changed files with 132 additions and 25 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
;sfall configuration settings
;v3.8.28.1
;v3.8.29
[Main]
;Change to 1 if you want to use command line args to tell sfall to use another ini file.
+4
View File
@@ -162,6 +162,10 @@
#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 get_explosion_damage(itemPid) metarule2_explosions(6, itemPid, 0)
#define set_dynamite_damage(minDmg, maxDmg) metarule2_explosions(7, minDmg, maxDmg)
#define set_plastic_damage(minDmg, maxDmg) metarule2_explosions(8, minDmg, maxDmg)
#define set_explosion_max_targets(x) metarule2_explosions(9, x, 0)
#define GAME_MSG_COMBAT (0)
+16 -2
View File
@@ -224,7 +224,7 @@ Some additional reg_anim_* functions were introduced. They all work in the same
> void reg_anim_callback(procedure proc)
- adds the given procedure to an animation sequence-list and executes it in the registered sequence.
> int metarule2_explosions(int arg1, int arg2, int arg3)
> int/array metarule2_explosions(int arg1, int arg2, int arg3)
was made as a dirty easy hack to allow dynamically change some explosion parameters (ranged attack). All changed parameters are reset to vanilla state automatically after each attack action. Following macros are available in sfall.h:
> void set_attack_explosion_pattern(x, y)
@@ -243,6 +243,20 @@ was made as a dirty easy hack to allow dynamically change some explosion paramet
- 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.
> array get_explosion_damage(itemPid)
- returns an array of the minimum and maximum damage of Dynamite or Plastic Explosives.
> void set_dynamite_damage(minDmg, maxDmg)
- sets the minimum and maximum damage for Dynamite.
- changed damage will be reset each time the player reloads the game.
> void set_plastic_damage(minDmg, maxDmg)
- sets the minimum and maximum damage for Plastic Explosives.
- changed damage will be reset each time the player reloads the game.
> void set_explosion_max_targets(x)
- sets the maximum number of additional targets for an explosion, valid range: 1..6 (default is 6)
Some utility/math functions are available:
@@ -346,7 +360,7 @@ Some utility/math functions are available:
- it will include any hidden, dead or system objects (like cursor), so make sure to check properly when iterating
> array party_member_list(int includeHidden)
- returns array of all current party members (0 - only critter-type, alive and visible will be returned, 1 - all object, including Trunk, etc.)
- returns an array of all current party members (0 - only critter-type, alive and visible will be returned, 1 - all object, including Trunk, etc.)
> array path_find_to(object objFrom, int tileTo, int blockingType)
- returns the shortest path to a given tile using given blocking function as an array of tile directions (0..5) to move on each step
+2
View File
@@ -238,7 +238,9 @@ enum ArtType : char
// Some FO2 PIDs possibly used by engine
enum ProtoId : long
{
PID_DYNAMITE = 51,
PID_MOTION_SENSOR = 59,
PID_PLASTIC_EXPLOSIVES = 85,
PID_SUPER_STIMPAK = 144,
PID_ACTIVE_GEIGER_COUNTER = 207,
PID_ACTIVE_STEALTH_BOY = 210,
+98 -12
View File
@@ -20,10 +20,13 @@
#include "FalloutEngine.h"
#include "Logging.h"
#include "Arrays.h"
#include "ScriptExtender.h"
static bool lightingEnabled = false;
static bool explosionsMetaruleReset = false;
static bool explosionsDamageReset = false;
static bool explosionMaxTargetReset = false;
// enable lighting for flying projectile, based on projectile PID data (light intensity & radius)
static void __declspec(naked) ranged_attack_lighting_fix() {
@@ -148,22 +151,70 @@ 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 const DWORD dynamite_min_dmg_addr = 0x4A2878;
static const DWORD dynamite_max_dmg_addr = 0x4A2873;
static const DWORD plastic_min_dmg_addr = 0x4A2884;
static const DWORD plastic_max_dmg_addr = 0x4A287F;
// default values
static DWORD dynamite_minDmg;
static DWORD dynamite_maxDmg;
static DWORD plastic_minDmg;
static DWORD plastic_maxDmg;
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 void SetExplosionRadius(int arg1, int arg2) {
static void __stdcall SetExplosionRadius(int arg1, int arg2) {
SafeWrite32(explosion_radius_grenade, arg1);
SafeWrite32(explosion_radius_rocket, arg2);
}
static void __stdcall SetExplosionDamage(int pid, int min, int max) {
explosionsDamageReset = true;
switch (pid) {
case PID_DYNAMITE:
SafeWrite32(dynamite_min_dmg_addr, min);
SafeWrite32(dynamite_max_dmg_addr, max);
break;
case PID_PLASTIC_EXPLOSIVES:
SafeWrite32(plastic_min_dmg_addr, min);
SafeWrite32(plastic_max_dmg_addr, max);
break;
}
}
static int __stdcall GetExplosionDamage(int pid) {
DWORD min = 0, max = 0;
switch (pid) {
case PID_DYNAMITE:
min = *(DWORD*)dynamite_min_dmg_addr;
max = *(DWORD*)dynamite_max_dmg_addr;
break;
case PID_PLASTIC_EXPLOSIVES:
min = *(DWORD*)plastic_min_dmg_addr;
max = *(DWORD*)plastic_max_dmg_addr;
break;
}
DWORD arrayId = CreateTempArray(2, 0);
arrays[arrayId].val[0] = min;
arrays[arrayId].val[1] = max;
return arrayId;
}
enum MetaruleExplosionsMode {
EXPL_FORCE_EXPLOSION_PATTERN = 1,
EXPL_FORCE_EXPLOSION_ART = 2,
EXPL_FORCE_EXPLOSION_RADIUS = 3,
EXPL_FORCE_EXPLOSION_DMGTYPE = 4,
EXPL_STATIC_EXPLOSION_RADIUS = 5,
EXPL_FORCE_EXPLOSION_PATTERN = 1,
EXPL_FORCE_EXPLOSION_ART = 2,
EXPL_FORCE_EXPLOSION_RADIUS = 3,
EXPL_FORCE_EXPLOSION_DMGTYPE = 4,
EXPL_STATIC_EXPLOSION_RADIUS = 5,
EXPL_GET_EXPLOSION_DAMAGE = 6,
EXPL_SET_DYNAMITE_EXPLOSION_DAMAGE = 7,
EXPL_SET_PLASTIC_EXPLOSION_DAMAGE = 8,
EXPL_SET_EXPLOSION_MAX_TARGET = 9,
};
int __stdcall ExplosionsMetaruleFunc(int mode, int arg1, int arg2) {
@@ -191,6 +242,22 @@ int __stdcall ExplosionsMetaruleFunc(int mode, int arg1, int arg2) {
if (arg2 > 0) set_expl_radius_rocket = arg2;
SetExplosionRadius(set_expl_radius_grenade, set_expl_radius_rocket);
break;
case EXPL_GET_EXPLOSION_DAMAGE:
return GetExplosionDamage(arg1);
case EXPL_SET_DYNAMITE_EXPLOSION_DAMAGE:
SetExplosionDamage(PID_DYNAMITE, arg1, arg2);
return 0;
case EXPL_SET_PLASTIC_EXPLOSION_DAMAGE:
SetExplosionDamage(PID_PLASTIC_EXPLOSIVES, arg1, arg2);
return 0;
case EXPL_SET_EXPLOSION_MAX_TARGET:
if (arg1 > 0 && arg1 < 7) {
SafeWrite8(0x423C93, arg1);
explosionMaxTargetReset = true;
} else {
return 0;
}
break;
default:
return -1;
}
@@ -211,6 +278,11 @@ void ResetExplosionSettings() {
SetExplosionRadius(set_expl_radius_grenade, set_expl_radius_rocket);
// explosion dmgtype
SafeWriteBatch<BYTE>(DMG_explosion, explosion_dmg_check_adr);
// explosion max target count
if (explosionMaxTargetReset) {
SafeWrite8(0x423C93, 6);
explosionMaxTargetReset = false;
}
explosionsMetaruleReset = false;
}
@@ -218,7 +290,21 @@ void ResetExplosionRadius() {
if (set_expl_radius_grenade != 2 || set_expl_radius_rocket != 3) SetExplosionRadius(2, 3);
}
void Explosion_Init() {
static void ResetExplosionDamage() {
if (!explosionsDamageReset) return;
SafeWrite32(dynamite_min_dmg_addr, dynamite_minDmg);
SafeWrite32(dynamite_max_dmg_addr, dynamite_maxDmg);
SafeWrite32(plastic_min_dmg_addr, plastic_minDmg);
SafeWrite32(plastic_max_dmg_addr, plastic_maxDmg);
explosionsDamageReset = false;
}
void Explosions_OnGameLoad() {
ResetExplosionRadius();
ResetExplosionDamage();
}
void Explosions_Init() {
MakeJump(0x411AB4, explosion_effect_hook); // required for explosions_metarule
lightingEnabled = GetConfigInt("Misc", "ExplosionsEmitLight", 0) != 0;
@@ -230,9 +316,9 @@ void Explosion_Init() {
dlogr(" Done", DL_INIT);
}
DWORD tmp;
tmp = SimplePatch<DWORD>(0x4A2873, "Misc", "Dynamite_DmgMax", 50, 0, 9999);
SimplePatch<DWORD>(0x4A2878, "Misc", "Dynamite_DmgMin", 30, 0, tmp);
tmp = SimplePatch<DWORD>(0x4A287F, "Misc", "PlasticExplosive_DmgMax", 80, 0, 9999);
SimplePatch<DWORD>(0x4A2884, "Misc", "PlasticExplosive_DmgMin", 40, 0, tmp);
// initialize explosives
dynamite_maxDmg = SimplePatch<DWORD>(dynamite_max_dmg_addr, "Misc", "Dynamite_DmgMax", 50, 0, 9999);
dynamite_minDmg = SimplePatch<DWORD>(dynamite_min_dmg_addr, "Misc", "Dynamite_DmgMin", 30, 0, dynamite_maxDmg);
plastic_maxDmg = SimplePatch<DWORD>(plastic_max_dmg_addr, "Misc", "PlasticExplosive_DmgMax", 80, 0, 9999);
plastic_minDmg = SimplePatch<DWORD>(plastic_min_dmg_addr, "Misc", "PlasticExplosive_DmgMin", 40, 0, plastic_maxDmg);
}
+4 -3
View File
@@ -18,7 +18,8 @@
#pragma once
void Explosion_Init();
int __stdcall ExplosionsMetaruleFunc(int mode, int arg1, int arg2);
void Explosions_Init();
void Explosions_OnGameLoad();
void ResetExplosionSettings();
void ResetExplosionRadius();
int __stdcall ExplosionsMetaruleFunc(int mode, int arg1, int arg2);
+1 -1
View File
@@ -103,7 +103,7 @@ static void __stdcall ResetState(DWORD onLoad) { // OnGameReset & OnBeforeGameSt
WipeSounds();
InventoryReset();
PartyControl_OnGameLoad();
ResetExplosionRadius();
Explosions_OnGameLoad();
ClearScriptAddedExtraGameMsg();
BarBoxes_OnGameLoad();
MetaruleExtenderReset();
+2 -2
View File
@@ -251,8 +251,8 @@ static void DllMain2() {
dlogr("Running Books_Init().", DL_INIT);
Books_Init();
dlogr("Running Explosion_Init().", DL_INIT);
Explosion_Init();
dlogr("Running Explosions_Init().", DL_INIT);
Explosions_Init();
dlogr("Running Message_Init().", DL_INIT);
Message_Init();
+4 -4
View File
@@ -24,11 +24,11 @@
#define VERSION_MAJOR 3
#define VERSION_MINOR 8
#define VERSION_BUILD 28
#define VERSION_REV 1
#define VERSION_BUILD 29
#define VERSION_REV 0
#ifdef WIN2K
#define VERSION_STRING "3.8.28.1 win2k"
#define VERSION_STRING "3.8.29 win2k"
#else
#define VERSION_STRING "3.8.28.1"
#define VERSION_STRING "3.8.29"
#endif