mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added new HOOK_ONEXPLOSION and a new mode "set_explosion_max_targets" to metarule2_explosions (from Mr.Stalin) (#35)
This commit is contained in:
@@ -57,6 +57,7 @@
|
||||
#define HOOK_EXPLOSIVETIMER (33)
|
||||
#define HOOK_DESCRIPTIONOBJ (34)
|
||||
#define HOOK_USESKILLON (35)
|
||||
#define HOOK_ONEXPLOSION (36)
|
||||
|
||||
//Valid arguments to list_begin
|
||||
#define LIST_CRITTERS (0)
|
||||
@@ -148,6 +149,7 @@
|
||||
#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)
|
||||
|
||||
@@ -561,3 +561,20 @@ int arg3 - skill being used
|
||||
|
||||
int ret1 - a new critter to override the user critter. Pass -1 to cancel the skill use, pass 0 to skip this return value
|
||||
int ret2 - pass 1 to allow the skill being used in combat (only for dude_obj or critter being controlled by the player)
|
||||
|
||||
-------------------------------------------
|
||||
|
||||
HOOK_ONEXPLOSION (hs_onexplosion.int)
|
||||
|
||||
Runs when an explosion occurs and Fallout is checking all the tiles within the explosion radius for targets.
|
||||
The tile checking will be interrupted when 6 additional targets (critters) are received.
|
||||
|
||||
int arg1 - event type: 1 - when the explosion is from an explosive item, 0 - otherwise
|
||||
Critter arg2 - The attacker
|
||||
int arg3 - The tile on which the explosion occurs
|
||||
int arg4 - checked tile within the explosion radius
|
||||
Obj arg5 - first found object on the checked tile as an additional target
|
||||
Critter arg6 - The target critter, may be 0 or equal to the attacker
|
||||
int arg7 - 1 when using throwing weapons (e.g. grenades), 0 otherwise
|
||||
|
||||
int ret1 - overrides the found object on the checked tile, pass 0 to skip the object
|
||||
|
||||
@@ -246,6 +246,9 @@ was made as a dirty easy hack to allow dynamically change some explosion paramet
|
||||
- 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:
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ static bool onlyOnce = false;
|
||||
static bool lightingEnabled = false;
|
||||
static bool explosionsMetaruleReset = false;
|
||||
static bool explosionsDamageReset = false;
|
||||
static bool explosionMaxTargetReset = false;
|
||||
|
||||
static const DWORD ranged_attack_lighting_fix_back = 0x4118F8;
|
||||
|
||||
@@ -363,7 +364,8 @@ enum MetaruleExplosionsMode {
|
||||
EXPL_STATIC_EXPLOSION_RADIUS = 5,
|
||||
EXPL_GET_EXPLOSION_DAMAGE = 6,
|
||||
EXPL_SET_DYNAMITE_EXPLOSION_DAMAGE = 7,
|
||||
EXPL_SET_PLASTIC_EXPLOSION_DAMAGE = 8
|
||||
EXPL_SET_PLASTIC_EXPLOSION_DAMAGE = 8,
|
||||
EXPL_SET_EXPLOSION_MAX_TARGET = 9,
|
||||
};
|
||||
|
||||
static void SetExplosionRadius(int arg1, int arg2) {
|
||||
@@ -444,6 +446,14 @@ int _stdcall ExplosionsMetaruleFunc(int mode, int arg1, int arg2) {
|
||||
case EXPL_SET_PLASTIC_EXPLOSION_DAMAGE:
|
||||
SetExplosionDamage(fo::ProtoId::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;
|
||||
}
|
||||
@@ -466,6 +476,11 @@ void ResetExplosionSettings() {
|
||||
for (int i = 0; i < numDmgChecks; i++) {
|
||||
SafeWrite8(explosion_dmg_check_adr[i], fo::DamageType::DMG_explosion);
|
||||
}
|
||||
// explosion max target count
|
||||
if (explosionMaxTargetReset) {
|
||||
SafeWrite8(0x423C93, 6);
|
||||
explosionMaxTargetReset = false;
|
||||
}
|
||||
explosionsMetaruleReset = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ static HooksInjectInfo injectHooks[] = {
|
||||
{HOOK_EXPLOSIVETIMER, Inject_ExplosiveTimerHook, false},
|
||||
{HOOK_DESCRIPTIONOBJ, Inject_DescriptionObjHook, false},
|
||||
{HOOK_USESKILLON, Inject_UseSkillOnHook, false},
|
||||
{HOOK_ONEXPLOSION, Inject_OnExplosionHook, false},
|
||||
};
|
||||
|
||||
bool HookScripts::injectAllHooks;
|
||||
|
||||
@@ -62,6 +62,7 @@ enum HookType
|
||||
HOOK_EXPLOSIVETIMER = 33,
|
||||
HOOK_DESCRIPTIONOBJ = 34,
|
||||
HOOK_USESKILLON = 35,
|
||||
HOOK_ONEXPLOSION = 36,
|
||||
HOOK_COUNT
|
||||
};
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ static void __declspec(naked) ToHitHook() {
|
||||
}
|
||||
|
||||
static void __fastcall AfterHitRollHook_Script(fo::ComputeAttackResult &ctd, DWORD hitChance, DWORD hit) {
|
||||
|
||||
BeginHook();
|
||||
argCount = 5;
|
||||
|
||||
@@ -125,7 +124,6 @@ static void __declspec(naked) CalcApCostHook2() {
|
||||
}
|
||||
|
||||
static void __fastcall ComputeDamageHook_Script(fo::ComputeAttackResult &ctd, DWORD rounds, DWORD multiply) {
|
||||
|
||||
BeginHook();
|
||||
argCount = 12;
|
||||
|
||||
@@ -176,7 +174,6 @@ static void __declspec(naked) ComputeDamageHook() {
|
||||
}
|
||||
|
||||
static void __fastcall FindTargetHook_Script(DWORD* target, DWORD attacker) {
|
||||
|
||||
BeginHook();
|
||||
argCount = 5;
|
||||
|
||||
@@ -344,6 +341,51 @@ normalTurn:
|
||||
}
|
||||
}
|
||||
|
||||
fo::GameObject* __fastcall ComputeExplosionOnExtrasHook_Script(fo::GameObject* object, DWORD checkTile, fo::ComputeAttackResult* ctdSource, DWORD isCheck, DWORD isThrowing, fo::GameObject* who) {
|
||||
fo::GameObject* result = object;
|
||||
|
||||
BeginHook();
|
||||
argCount = 7;
|
||||
|
||||
args[0] = isCheck;
|
||||
args[1] = (DWORD)ctdSource->attacker;
|
||||
args[2] = ctdSource->targetTile;
|
||||
args[3] = checkTile;
|
||||
args[4] = (DWORD)object;
|
||||
args[5] = (DWORD)who;
|
||||
args[6] = isThrowing;
|
||||
|
||||
RunHookScript(HOOK_ONEXPLOSION);
|
||||
|
||||
if (cRet > 0) result = (fo::GameObject*)rets[0]; // override object
|
||||
|
||||
EndHook();
|
||||
return result;
|
||||
}
|
||||
|
||||
static void _declspec(naked) ComputeExplosionOnExtrasHook() {
|
||||
__asm {
|
||||
cmp dword ptr [esp + 0x34 + 4], 0x429533; // skip hook when AI assesses the situation in choosing the best weapon
|
||||
jz end;
|
||||
cmp dword ptr [esp + 0x34 + 4], 0x4296BC;
|
||||
jnz hook;
|
||||
end:
|
||||
jmp fo::funcoffs::obj_blocking_at_;
|
||||
hook:
|
||||
push ecx;
|
||||
push eax; // who (target/source)
|
||||
call fo::funcoffs::obj_blocking_at_;
|
||||
push [esp + 0x34 - 0x24 + 12]; // isThrowing
|
||||
push [esp + 0x34 - 0x34 + 16]; // isCheck (bypass damage)
|
||||
push esi; // source ctd
|
||||
mov ecx, eax; // object
|
||||
mov edx, edi; // check tile
|
||||
call ComputeExplosionOnExtrasHook_Script;
|
||||
pop ecx;
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
void Inject_ToHitHook() {
|
||||
HookCalls(ToHitHook, {
|
||||
0x421686, // combat_safety_invalidate_weapon_func_
|
||||
@@ -407,8 +449,11 @@ void Inject_CombatTurnHook() {
|
||||
HookCalls(CombatTurnHook, { 0x422D87, 0x422E20 });
|
||||
}
|
||||
|
||||
void InitCombatHookScripts() {
|
||||
void Inject_OnExplosionHook() {
|
||||
HookCall(0x423D70, ComputeExplosionOnExtrasHook);
|
||||
}
|
||||
|
||||
void InitCombatHookScripts() {
|
||||
LoadHookScript("hs_tohit", HOOK_TOHIT);
|
||||
LoadHookScript("hs_afterhitroll", HOOK_AFTERHITROLL);
|
||||
LoadHookScript("hs_calcapcost", HOOK_CALCAPCOST);
|
||||
@@ -417,7 +462,7 @@ void InitCombatHookScripts() {
|
||||
LoadHookScript("hs_itemdamage", HOOK_ITEMDAMAGE);
|
||||
LoadHookScript("hs_ammocost", HOOK_AMMOCOST);
|
||||
LoadHookScript("hs_combatturn", HOOK_COMBATTURN);
|
||||
|
||||
LoadHookScript("hs_onexplosion", HOOK_ONEXPLOSION);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,5 +15,6 @@ void Inject_FindTargetHook();
|
||||
void Inject_ItemDamageHook();
|
||||
void Inject_AmmoCostHook();
|
||||
void Inject_CombatTurnHook();
|
||||
void Inject_OnExplosionHook();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user