mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added 3 new modes to metarule2_explosions and "item_make_explosive" script function (#169)
Simplified byte writing in some options (from Crafty) Minor edits to Criticals.cpp. Updated version number.
This commit is contained in:
+2
-2
@@ -1,5 +1,5 @@
|
||||
;sfall configuration settings
|
||||
;v4.1.1
|
||||
;v4.1.2
|
||||
|
||||
[Main]
|
||||
;Change to 1 if you want to use command line args to tell sfall to use another ini file.
|
||||
@@ -524,7 +524,7 @@ ObjCanSeeObj_ShootThru_Fix=0
|
||||
;Set to 1 to fix the broken obj_can_hear_obj script function
|
||||
ObjCanHearObjFix=0
|
||||
|
||||
;Set to 1 to fix the mood argument of start_gdialog script function to be available for talking heads
|
||||
;Set to 1 to enable the mood argument of start_gdialog script function to be available for talking heads
|
||||
;If the argument value is -1, the mood will be determined by the local variable 0 of the script (vanilla behavior)
|
||||
StartGDialogFix=0
|
||||
|
||||
|
||||
@@ -143,6 +143,9 @@
|
||||
#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 GAME_MSG_COMBAT (0)
|
||||
@@ -245,6 +248,7 @@
|
||||
#define intface_redraw sfall_func0("intface_redraw")
|
||||
#define intface_show sfall_func0("intface_show")
|
||||
#define inventory_redraw(invSide) sfall_func1("inventory_redraw", invSide)
|
||||
#define item_make_explosive(pid, aPid, min, max) sfall_func4("item_make_explosive", pid, aPid, min, max)
|
||||
#define item_weight(obj) sfall_func1("item_weight", obj)
|
||||
#define lock_is_jammed(obj) sfall_func1("lock_is_jammed", obj)
|
||||
#define outlined_object sfall_func0("outlined_object")
|
||||
|
||||
@@ -216,7 +216,7 @@ Some additional reg_anim_* functions were introduced. They all work in the same
|
||||
> void reg_anim_turn_towards(object, tile/target, delay)
|
||||
- makes object change its direction to face given tile num or target object.
|
||||
|
||||
> 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)
|
||||
@@ -235,6 +235,17 @@ 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 array of the minimum and maximum damage of the explosive item.
|
||||
|
||||
> 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.
|
||||
|
||||
|
||||
Some utility/math functions are available:
|
||||
|
||||
@@ -491,6 +502,15 @@ Some utility/math functions are available:
|
||||
- redraws inventory list in the inventory/use inventory item on/loot/barter screens
|
||||
- invSide specifies which side needs to be redrawn: 0 - the player, 1 - target (container/NPC in loot/barter screens)
|
||||
|
||||
> void sfall_func3("item_make_explosive", int pid, int activePid, int damage)
|
||||
> void sfall_func4("item_make_explosive", int pid, int activePid, int min, int max)
|
||||
- makes the specified item (pid) an explosive item like Dynamite or Plastic Explosives
|
||||
- activePid is for an item with an active timer, can be the same as the pid argument
|
||||
- the item proto must be "Misc Item" type and have "Use" action flag
|
||||
- min/max are the minimum and maximum explosion damage
|
||||
- using the function on an item that is already set as an explosive will override its previous settings
|
||||
- NOTE: this function does not work for pid's of Dynamite and Plastic Explosives
|
||||
|
||||
> int sfall_func1("get_string_pointer", string text)
|
||||
- returns a pointer to a string variable or to a text
|
||||
|
||||
@@ -502,7 +522,7 @@ Some utility/math functions are available:
|
||||
|
||||
> void sfall_func5("create_win", string winName, int x, int y, int width, int height)
|
||||
> void sfall_func6("create_win", string winName, int x, int y, int width, int height, int flags)
|
||||
- works just like vanilla CreateWin function, but creates a window with MoveOnTop flag if flags argument is not specified, and allows to set additional flags for the created window
|
||||
- works just like vanilla CreateWin function, but creates a window with MoveOnTop flag if the flags argument is not specified, and allows to set additional flags for the created window
|
||||
- MoveOnTop flag allows the created window to be placed on top of the game interface
|
||||
|
||||
> void sfall_func3("set_can_rest_on_map", int mapNum, int elev, bool value)
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
static const char* critTableFile = ".\\CriticalOverrides.ini";
|
||||
const DWORD Criticals::critTableCount = 2 * 19 + 1; // Number of species in new critical table
|
||||
|
||||
static DWORD mode;
|
||||
@@ -86,7 +87,7 @@ void CritLoad() {
|
||||
fo::CritInfo& newEffect = baseCritTable[newCritter][part][crit];
|
||||
fo::CritInfo& defaultEffect = fo::var::crit_succ_eff[critter][part][crit];
|
||||
for (int i = 0; i < 7; i++) {
|
||||
newEffect.values[i] = GetPrivateProfileIntA(section, critNames[i], defaultEffect.values[i], ".\\CriticalOverrides.ini");
|
||||
newEffect.values[i] = GetPrivateProfileIntA(section, critNames[i], defaultEffect.values[i], critTableFile);
|
||||
if (isDebug) {
|
||||
char logmsg[256];
|
||||
if (newEffect.values[i] != defaultEffect.values[i]) {
|
||||
@@ -109,11 +110,11 @@ void CritLoad() {
|
||||
for (int critter = 0; critter < Criticals::critTableCount; critter++) {
|
||||
sprintf_s(buf, "c_%02d", critter);
|
||||
int all;
|
||||
if (!(all = GetPrivateProfileIntA(buf, "Enabled", 0, ".\\CriticalOverrides.ini"))) continue;
|
||||
if (!(all = GetPrivateProfileIntA(buf, "Enabled", 0, critTableFile))) continue;
|
||||
for (int part = 0; part < 9; part++) {
|
||||
if (all < 2) {
|
||||
sprintf_s(buf2, "Part_%d", part);
|
||||
if (!GetPrivateProfileIntA(buf, buf2, 0, ".\\CriticalOverrides.ini")) continue;
|
||||
if (!GetPrivateProfileIntA(buf, buf2, 0, critTableFile)) continue;
|
||||
}
|
||||
|
||||
sprintf_s(buf2, "c_%02d_%d", critter, part);
|
||||
@@ -121,7 +122,7 @@ void CritLoad() {
|
||||
fo::CritInfo& effect = baseCritTable[critter][part][crit];
|
||||
for (int i = 0; i < 7; i++) {
|
||||
sprintf_s(buf3, "e%d_%s", crit, critNames[i]);
|
||||
effect.values[i] = GetPrivateProfileIntA(buf2, buf3, effect.values[i], ".\\CriticalOverrides.ini");
|
||||
effect.values[i] = GetPrivateProfileIntA(buf2, buf3, effect.values[i], critTableFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,10 +245,9 @@ void CriticalTableOverride() {
|
||||
void RemoveCriticalTimeLimitsPatch() {
|
||||
if (GetConfigInt("Misc", "RemoveCriticalTimelimits", 0)) {
|
||||
dlog("Removing critical time limits.", DL_INIT);
|
||||
SafeWrite8(0x42412B, 0x90);
|
||||
BlockCall(0x42412C);
|
||||
SafeWrite16(0x4A3052, 0x9090);
|
||||
SafeWrite16(0x4A3093, 0x9090);
|
||||
SafeWrite8(0x424118, 0xEB); // jmps 0x424131
|
||||
SafeWrite8(0x4A3053, 0x0);
|
||||
SafeWrite8(0x4A3094, 0x0);
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
}
|
||||
|
||||
+258
-10
@@ -16,6 +16,8 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "..\main.h"
|
||||
|
||||
#include "..\FalloutEngine\Fallout2.h"
|
||||
@@ -24,14 +26,28 @@
|
||||
#include "LoadGameHook.h"
|
||||
#include "MainLoopHook.h"
|
||||
#include "ScriptExtender.h"
|
||||
#include "Scripting\Arrays.h"
|
||||
|
||||
#include "Explosions.h"
|
||||
|
||||
namespace sfall
|
||||
{
|
||||
|
||||
using namespace fo::Fields;
|
||||
|
||||
struct explosiveInfo {
|
||||
DWORD pid;
|
||||
DWORD pidActive;
|
||||
DWORD minDamage;
|
||||
DWORD maxDamage;
|
||||
};
|
||||
|
||||
std::vector<explosiveInfo> explosives;
|
||||
|
||||
static bool onlyOnce = false;
|
||||
static bool lightingEnabled = false;
|
||||
static bool explosionsMetaruleReset = false;
|
||||
static bool explosionsDamageReset = true;
|
||||
|
||||
static const DWORD ranged_attack_lighting_fix_back = 0x4118F8;
|
||||
|
||||
@@ -40,7 +56,7 @@ static void __declspec(naked) ranged_attack_lighting_fix() {
|
||||
__asm {
|
||||
mov eax, [esp+40]; // projectile ptr - 1st arg
|
||||
mov ecx, [eax+0x70]; // check existing light intensity
|
||||
cmp ecx, 0; // if non-zero, skip obj_set_light call
|
||||
cmp ecx, 0; // if non-zero, skip obj_set_light call
|
||||
jnz skip;
|
||||
mov ecx, [esp+0x1C]; // protoPtr of projectile
|
||||
mov edx, [ecx+0x0C]; // light radius - 2nd arg
|
||||
@@ -53,7 +69,7 @@ skip:
|
||||
}
|
||||
|
||||
// misc functions from the engine..
|
||||
static const DWORD register_object_play_sfx = 0x41541C;
|
||||
//static const DWORD register_object_play_sfx = 0x41541C;
|
||||
|
||||
static const DWORD explosion_effect_hook_back = 0x411AB9;
|
||||
static DWORD explosion_effect_starting_dir = 0;
|
||||
@@ -154,6 +170,168 @@ static void __declspec(naked) fire_dance_lighting_fix1() {
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
static DWORD __fastcall CheckExplosives(DWORD register pid) {
|
||||
for (const auto &item: explosives) {
|
||||
if (item.pid == pid) return item.pidActive;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DWORD __fastcall CheckActiveExplosives(DWORD register pid) {
|
||||
for (const auto &item: explosives) {
|
||||
if (item.pidActive == pid) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static DWORD __fastcall GetDamage(DWORD register pid, DWORD &min, DWORD &max) {
|
||||
DWORD result = 0;
|
||||
for (const auto &item: explosives) {
|
||||
if (item.pidActive == pid) {
|
||||
min = item.minDamage;
|
||||
max = item.maxDamage;
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static DWORD __fastcall SetQueueExplosionDamage(DWORD register pid) {
|
||||
DWORD min, max;
|
||||
DWORD result = GetDamage(pid, min, max);
|
||||
|
||||
if (result) {
|
||||
_asm mov edx, min;
|
||||
_asm mov ecx, max;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void __declspec(naked) obj_use_explosive_hack() {
|
||||
using namespace fo;
|
||||
__asm {
|
||||
cmp edx, PID_PLASTIC_EXPLOSIVES;
|
||||
jz end;
|
||||
// end engine code
|
||||
pushad;
|
||||
mov ecx, edx;
|
||||
call CheckExplosives;
|
||||
test eax, eax;
|
||||
popad;
|
||||
jnz end;
|
||||
retn;
|
||||
end:
|
||||
mov dword ptr [esp], 0x49BCE0;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) obj_use_explosive_active_hack() {
|
||||
using namespace fo;
|
||||
__asm {
|
||||
cmp eax, PID_PLASTIC_EXPLOSIVES;
|
||||
jz end;
|
||||
// end engine code
|
||||
push ebx;
|
||||
push ecx;
|
||||
push edx;
|
||||
mov ecx, eax;
|
||||
call CheckExplosives;
|
||||
pop edx;
|
||||
pop ecx;
|
||||
pop ebx;
|
||||
test eax, eax;
|
||||
jz skipSet;
|
||||
mov dword ptr [esi + protoId], eax; // change item pid to active;
|
||||
skipSet:
|
||||
mov dword ptr [esp], 0x49BD62;
|
||||
end:
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) queue_do_explosion_hack() {
|
||||
using namespace fo;
|
||||
__asm {
|
||||
cmp edx, PID_ACTIVE_DYNAMITE;
|
||||
jz dynamite;
|
||||
cmp edx, PID_ACTIVE_PLASTIC_EXPLOSIVE;
|
||||
jz end;
|
||||
push edx;
|
||||
mov ecx, edx;
|
||||
call SetQueueExplosionDamage;
|
||||
test eax, eax;
|
||||
mov ebx, edx;
|
||||
pop edx;
|
||||
jz end;
|
||||
mov dword ptr [esp], 0x4A2888;
|
||||
end:
|
||||
retn;
|
||||
dynamite:
|
||||
mov dword ptr [esp], 0x4A2872;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) inven_action_cursor_drop_hack() {
|
||||
using namespace fo;
|
||||
__asm {
|
||||
cmp ebx, PID_ACTIVE_PLASTIC_EXPLOSIVE;
|
||||
jz end;
|
||||
// end engine code
|
||||
push eax;
|
||||
push ecx;
|
||||
mov ecx, ebx;
|
||||
call CheckActiveExplosives;
|
||||
test eax, eax; // check in engine
|
||||
pop ecx;
|
||||
pop eax;
|
||||
end:
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) protinstTestDroppedExplosive_hack() {
|
||||
__asm {
|
||||
jz end;
|
||||
mov ecx, edx;
|
||||
call CheckActiveExplosives;
|
||||
test eax, eax;
|
||||
jz end;
|
||||
mov dword ptr [esp], 0x49C112; // exit, no active item explosive
|
||||
end:
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static void apply_expl_hack() {
|
||||
onlyOnce = true;
|
||||
MakeCall(0x49BCC7, obj_use_explosive_hack); // check explosives
|
||||
MakeCall(0x49BD56, obj_use_explosive_active_hack); // set active explosive
|
||||
MakeCall(0x4A2865, queue_do_explosion_hack); // set damage explosive
|
||||
MakeCall(0x4737F2, inven_action_cursor_drop_hack); // check drop explosives
|
||||
SafeWrite8(0x4737F7, 0x90);
|
||||
MakeCall(0x49C005, protinstTestDroppedExplosive_hack); // check drop explosives
|
||||
SafeWrite8(0x49C00A, 0x90);
|
||||
}
|
||||
|
||||
void Explosions::AddToExplosives(DWORD pid, DWORD activePid, DWORD minDmg, DWORD maxDmg) {
|
||||
for (unsigned int i = 0; i < explosives.size(); i++) {
|
||||
if (explosives[i].pid == pid) {
|
||||
explosives.erase(explosives.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
explosives.push_back({ pid, activePid, minDmg, maxDmg });
|
||||
|
||||
if (!onlyOnce) apply_expl_hack();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
static const DWORD explosion_dmg_check_adr[] = {0x411709, 0x4119FC, 0x411C08, 0x4517C1, 0x423BC8, 0x42381A};
|
||||
static const DWORD explosion_art_adr[] = {0x411A19, 0x411A29, 0x411A35, 0x411A3C};
|
||||
@@ -161,6 +339,15 @@ 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 = 0x4A2878;
|
||||
static const DWORD dynamite_max_dmg = 0x4A2873;
|
||||
static const DWORD plastic_min_dmg = 0x4A2884;
|
||||
static const DWORD plastic_max_dmg = 0x4A287F;
|
||||
static DWORD dynamite_min_setting;
|
||||
static DWORD dynamite_max_setting;
|
||||
static DWORD plastic_min_setting;
|
||||
static DWORD plastic_max_setting;
|
||||
|
||||
static DWORD set_expl_radius_grenade = 2;
|
||||
static DWORD set_expl_radius_rocket = 3;
|
||||
|
||||
@@ -172,7 +359,10 @@ enum MetaruleExplosionsMode {
|
||||
EXPL_FORCE_EXPLOSION_ART = 2,
|
||||
EXPL_FORCE_EXPLOSION_RADIUS = 3,
|
||||
EXPL_FORCE_EXPLOSION_DMGTYPE = 4,
|
||||
EXPL_STATIC_EXPLOSION_RADIUS = 5
|
||||
EXPL_STATIC_EXPLOSION_RADIUS = 5,
|
||||
EXPL_GET_EXPLOSION_DAMAGE = 6,
|
||||
EXPL_SET_DYNAMITE_EXPLOSION_DAMAGE = 7,
|
||||
EXPL_SET_PLASTIC_EXPLOSION_DAMAGE = 8
|
||||
};
|
||||
|
||||
static void SetExplosionRadius(int arg1, int arg2) {
|
||||
@@ -180,6 +370,42 @@ static void SetExplosionRadius(int arg1, int arg2) {
|
||||
SafeWrite32(explosion_radius_rocket, arg2);
|
||||
}
|
||||
|
||||
static void SetExplosionDamage(int pid, int min, int max) {
|
||||
explosionsDamageReset = true;
|
||||
switch (pid) {
|
||||
case fo::ProtoId::PID_DYNAMITE:
|
||||
SafeWrite32(dynamite_min_dmg, min);
|
||||
SafeWrite32(dynamite_max_dmg, max);
|
||||
break;
|
||||
case fo::ProtoId::PID_PLASTIC_EXPLOSIVES:
|
||||
SafeWrite32(plastic_min_dmg, min);
|
||||
SafeWrite32(plastic_max_dmg, max);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int GetExplosionDamage(int pid) {
|
||||
DWORD min = 0, max = 0;
|
||||
switch (pid) {
|
||||
case fo::ProtoId::PID_DYNAMITE:
|
||||
min = *(DWORD*)dynamite_min_dmg;
|
||||
max = *(DWORD*)dynamite_max_dmg;
|
||||
break;
|
||||
case fo::ProtoId::PID_PLASTIC_EXPLOSIVES:
|
||||
min = *(DWORD*)plastic_min_dmg;
|
||||
max = *(DWORD*)plastic_max_dmg;
|
||||
break;
|
||||
default:
|
||||
GetDamage(pid, min, max);
|
||||
}
|
||||
|
||||
DWORD arrayId = script::TempArray(2, 0);
|
||||
script::arrays[arrayId].val[0] = min;
|
||||
script::arrays[arrayId].val[1] = max;
|
||||
|
||||
return arrayId;
|
||||
}
|
||||
|
||||
int _stdcall ExplosionsMetaruleFunc(int mode, int arg1, int arg2) {
|
||||
switch (mode) {
|
||||
case EXPL_FORCE_EXPLOSION_PATTERN:
|
||||
@@ -209,6 +435,14 @@ 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(fo::ProtoId::PID_DYNAMITE, arg1, arg2);
|
||||
return 0;
|
||||
case EXPL_SET_PLASTIC_EXPLOSION_DAMAGE:
|
||||
SetExplosionDamage(fo::ProtoId::PID_PLASTIC_EXPLOSIVES, arg1, arg2);
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@@ -239,6 +473,17 @@ void ResetExplosionRadius() {
|
||||
SetExplosionRadius(2, 3);
|
||||
}
|
||||
|
||||
static void ResetExplosionDamage() {
|
||||
if (!explosives.empty()) explosives.clear();
|
||||
|
||||
if (!explosionsDamageReset) return;
|
||||
SafeWrite32(dynamite_max_dmg, dynamite_max_setting);
|
||||
SafeWrite32(dynamite_min_dmg, dynamite_min_setting);
|
||||
SafeWrite32(plastic_max_dmg, plastic_max_setting);
|
||||
SafeWrite32(plastic_min_dmg, plastic_min_setting);
|
||||
explosionsDamageReset = false;
|
||||
}
|
||||
|
||||
void Explosions::init() {
|
||||
MakeJump(0x411AB4, explosion_effect_hook); // required for explosions_metarule
|
||||
|
||||
@@ -248,20 +493,23 @@ void Explosions::init() {
|
||||
MakeJump(0x4118E1, ranged_attack_lighting_fix);
|
||||
MakeJump(0x410A4A, fire_dance_lighting_fix1);
|
||||
MakeJump(0x415A3F, anim_set_check__light_fix); // this allows to change light intensity
|
||||
|
||||
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_max_setting = SimplePatch<DWORD>(dynamite_max_dmg, "Misc", "Dynamite_DmgMax", 50, 0, 9999);
|
||||
dynamite_min_setting = SimplePatch<DWORD>(dynamite_min_dmg, "Misc", "Dynamite_DmgMin", 30, 0, dynamite_max_setting);
|
||||
plastic_max_setting = SimplePatch<DWORD>(plastic_max_dmg, "Misc", "PlasticExplosive_DmgMax", 80, 0, 9999);
|
||||
plastic_min_setting = SimplePatch<DWORD>(plastic_min_dmg, "Misc", "PlasticExplosive_DmgMin", 40, 0, plastic_max_setting);
|
||||
if (!explosives.empty()) explosives.clear();
|
||||
|
||||
// after each combat attack, reset metarule_explosions settings
|
||||
MainLoopHook::OnAfterCombatAttack() += ResetExplosionSettings;
|
||||
|
||||
LoadGameHook::OnGameReset() += ResetExplosionRadius;
|
||||
LoadGameHook::OnGameReset() += []() {
|
||||
ResetExplosionRadius();
|
||||
ResetExplosionDamage();
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ class Explosions : public Module {
|
||||
public:
|
||||
const char* name() { return "Explosions"; }
|
||||
void init();
|
||||
|
||||
static void AddToExplosives(DWORD pid, DWORD activePid, DWORD minDmg, DWORD maxDmg);
|
||||
};
|
||||
|
||||
int _stdcall ExplosionsMetaruleFunc(int mode, int arg1, int arg2);
|
||||
|
||||
@@ -495,7 +495,7 @@ void NpcAutoLevelPatch() {
|
||||
|
||||
if (GetConfigInt("Misc", "OverrideArtCacheSize", 0)) {
|
||||
dlog("Applying override art cache size patch.", DL_INIT);
|
||||
SafeWrite32(0x418867, 0x90909090);
|
||||
SafeWrite8(0x41886A, 0x0);
|
||||
SafeWrite32(0x418872, 256);
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
@@ -581,7 +581,7 @@ void FashShotTraitFix() {
|
||||
break;
|
||||
case 2:
|
||||
dlog("Applying Fast Shot Trait Fix. (Fallout 1 version)", DL_INIT);
|
||||
SafeWrite16(0x478C9F, 0x9090);
|
||||
SafeWrite8(0x478CA0, 0x0);
|
||||
for (int i = 0; i < sizeof(FastShotFixF1) / 4; i++) {
|
||||
HookCall(FastShotFixF1[i], (void*)0x478C7D);
|
||||
}
|
||||
@@ -705,7 +705,7 @@ void MotionScannerFlagsPatch() {
|
||||
if (flags & 1) MakeJump(0x41BBE9, ScannerAutomapHook);
|
||||
if (flags & 2) {
|
||||
// automap_
|
||||
SafeWrite16(0x41BC24, 0x9090);
|
||||
SafeWrite8(0x41BC25, 0x0);
|
||||
BlockCall(0x41BC3C);
|
||||
// item_m_use_charged_item_
|
||||
SafeWrite8(0x4794B3, 0x5E); // jbe short 0x479512
|
||||
|
||||
@@ -101,6 +101,7 @@ static const SfallMetarule metarules[] = {
|
||||
{"intface_redraw", sf_intface_redraw, 0, 0},
|
||||
{"intface_show", sf_intface_show, 0, 0},
|
||||
{"inventory_redraw", sf_inventory_redraw, 1, 1, {ARG_INT}},
|
||||
{"item_make_explosive", sf_item_make_explosive, 3, 4, {ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
{"item_weight", sf_item_weight, 1, 1, {ARG_OBJECT}},
|
||||
{"lock_is_jammed", sf_lock_is_jammed, 1, 1, {ARG_OBJECT}},
|
||||
{"outlined_object", sf_outlined_object, 0, 0},
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "..\..\..\FalloutEngine\Fallout2.h"
|
||||
#include "..\..\Explosions.h"
|
||||
#include "..\..\Knockback.h"
|
||||
#include "..\..\Inventory.h"
|
||||
#include "..\..\LoadGameHook.h"
|
||||
@@ -429,6 +430,24 @@ void sf_set_unjam_locks_time(OpcodeContext& ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
void sf_item_make_explosive(OpcodeContext& ctx) {
|
||||
DWORD pid = ctx.arg(0).rawValue();
|
||||
DWORD pidActive = ctx.arg(1).rawValue();
|
||||
DWORD min = ctx.arg(2).rawValue();
|
||||
DWORD max = (ctx.numArgs() == 4) ? ctx.arg(3).rawValue() : min;
|
||||
|
||||
if (min > max) {
|
||||
max = min;
|
||||
ctx.printOpcodeError("item_make_explosive() - Warning: value of max argument is less than the min argument.");
|
||||
}
|
||||
|
||||
if (pid > 0 && pidActive > 0) {
|
||||
Explosions::AddToExplosives(pid, pidActive, min, max);
|
||||
} else {
|
||||
ctx.printOpcodeError("item_make_explosive() - PID arguments must be greater than 0.");
|
||||
}
|
||||
}
|
||||
|
||||
void sf_get_current_inven_size(OpcodeContext& ctx) {
|
||||
ctx.setReturn(sf_item_total_size(ctx.arg(0).asObject()));
|
||||
}
|
||||
|
||||
@@ -91,6 +91,8 @@ void sf_unjam_lock(OpcodeContext&);
|
||||
|
||||
void sf_set_unjam_locks_time(OpcodeContext&);
|
||||
|
||||
void sf_item_make_explosive(OpcodeContext&);
|
||||
|
||||
void sf_get_current_inven_size(OpcodeContext&);
|
||||
|
||||
void sf_get_dialog_object(OpcodeContext&);
|
||||
|
||||
+2
-2
@@ -24,10 +24,10 @@
|
||||
|
||||
#define VERSION_MAJOR 4
|
||||
#define VERSION_MINOR 1
|
||||
#define VERSION_BUILD 1
|
||||
#define VERSION_BUILD 2
|
||||
#define VERSION_REV 0
|
||||
|
||||
#define VERSION_STRING "4.1.1"
|
||||
#define VERSION_STRING "4.1.2"
|
||||
|
||||
#define CHECK_VAL (4)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user