Added a new hook: HOOK_ROLLCHECK

This commit is contained in:
NovaRain
2021-01-13 23:26:19 +08:00
parent bde6b94855
commit ef0bdf1e3b
7 changed files with 85 additions and 2 deletions
+1
View File
@@ -71,6 +71,7 @@
#define HOOK_ENCOUNTER (43)
#define HOOK_ADJUSTPOISON (44)
#define HOOK_ADJUSTRADS (45)
#define HOOK_ROLLCHECK (46)
//Valid arguments to list_begin
#define LIST_CRITTERS (0)
+23
View File
@@ -718,3 +718,26 @@ Critter arg0 - the critter (usually dude_obj)
int arg1 - the amount of radiation being added/removed
int ret0 - the new amount of radiation being added/removed
-------------------------------------------
HOOK_ROLLCHECK (hs_rollcheck.int)
Runs when a game event performs a random roll to check the chance of success or failure.
int arg0 - event type:
1 - checks the chance of an attack hitting the target
2 - checks the chance of a bullet from a burst hitting the target (for burst attacks)
3 - checks the chance when using skills (not listed below)
4 - check the chance of using Repair skill
5 - check the chance of using Doctor skill
6 - check the chance of using Steal skill for the thief
7 - the second Steal skill chance check for the target to catch the thief, in which the target's failure is the thief's success result
int arg1 - the value of roll result (see ROLL_* constants), which is calculated as:
for ROLL_CRITICAL_SUCCESS: random(1, 100) <= (random_chance / 10) + bonus
for ROLL_CRITICAL_FAILURE: random(1, 100) <= -random_chance / 10
int arg2 - the chance value
int arg3 - the bonus value, used when checking critical success
int arg4 - random chance (calculated as: chance - random(1, 100)), where a negative value is a failure check (ROLL_FAILURE)
int ret0 - overrides the roll result
+1 -1
View File
@@ -116,7 +116,7 @@ static void __declspec(naked) critter_check_rads_hack() {
}
void CritterPoison::init() {
// Allow changing the poison level for critters
// Allow changing the poison level for NPCs
MakeCall(0x42D226, critter_adjust_poison_hack);
SafeWrite8(0x42D22C, 0xDA); // jmp 0x42D30A
+2 -1
View File
@@ -107,10 +107,11 @@ static HooksInjectInfo injectHooks[] = {
{HOOK_ENCOUNTER, Inject_EncounterHook, 0},
{HOOK_ADJUSTPOISON, Inject_AdjustPoisonHook, 0},
{HOOK_ADJUSTRADS, Inject_AdjustRadsHook, 1}, // always embedded for party control fix
{HOOK_ROLLCHECK, Inject_RollCheckHook, 0},
};
void HookScripts::InjectingHook(int hookId) {
if (!IsInjectHook(hookId) && injectHooks[hookId].id == hookId) {
if (IsInjectHook(hookId) == false && injectHooks[hookId].id == hookId) {
injectHooks[hookId].injectState = 2;
injectHooks[hookId].inject();
devlog_f("Inject hook ID: %d\n", DL_INIT, hookId);
+1
View File
@@ -72,6 +72,7 @@ enum HookType
HOOK_ENCOUNTER = 43,
HOOK_ADJUSTPOISON = 44,
HOOK_ADJUSTRADS = 45,
HOOK_ROLLCHECK = 46,
HOOK_COUNT
};
+56
View File
@@ -631,6 +631,57 @@ cancelEnc:
}
}
static long __stdcall RollCheckHook_Script(long roll, long chance, long bonus, long randomChance, long calledFrom) {
long hookType;
switch (calledFrom - 5) {
case 0x42388E: // compute_attack_
// compute_spray_
case 0x4234D1: hookType = 1; break; // single and burst attack hit event
// compute_spray_
case 0x42356C: hookType = 2; break; // burst attack bullet hit event
// skill_result_
case 0x4AAB29: hookType = 3; break; // common skill check event
// skill_use_
case 0x4AB3B6: hookType = 4; break; // SKILL_REPAIR
case 0x4AB8B5: hookType = 5; break; // SKILL_DOCTOR
// skill_check_stealing_ // SKILL_STEAL
case 0x4ABC9F: hookType = 6; break; // source stealing check event
case 0x4ABCE6: hookType = 7; break; // target stealing check event (fail for success stealing)
default:
return roll; // unsupported hook
}
BeginHook();
argCount = 5;
args[0] = hookType;
args[1] = roll;
args[2] = chance;
args[3] = bonus;
args[4] = randomChance;
RunHookScript(HOOK_ROLLCHECK);
if (cRet) roll = rets[0];
EndHook();
return roll;
}
static void __declspec(naked) roll_check_hook() {
__asm {
push ecx;
push [esp + 0xC + 8]; // calledFrom
push ebx; // random chance value
push esi; // bonus
push edi; // chance value
call fo::funcoffs::roll_check_critical_;
push eax; // roll result
call RollCheckHook_Script;
pop ecx;
retn;
}
}
void Inject_BarterPriceHook() {
HookCalls(BarterPriceHook, {
0x474D4C, // barter_attempt_transaction_ (offers button)
@@ -698,6 +749,10 @@ void Inject_EncounterHook() {
HookCall(0x4C095C, wmRndEncounterOccurred_hook);
}
void Inject_RollCheckHook() {
HookCall(0x4A3020, roll_check_hook);
}
void InitMiscHookScripts() {
HookScripts::LoadHookScript("hs_barterprice", HOOK_BARTERPRICE);
HookScripts::LoadHookScript("hs_useskillon", HOOK_USESKILLON);
@@ -710,6 +765,7 @@ void InitMiscHookScripts() {
HookScripts::LoadHookScript("hs_resttimer", HOOK_RESTTIMER);
HookScripts::LoadHookScript("hs_explosivetimer", HOOK_EXPLOSIVETIMER);
HookScripts::LoadHookScript("hs_encounter", HOOK_ENCOUNTER);
HookScripts::LoadHookScript("hs_rollcheck", HOOK_ROLLCHECK);
}
}
+1
View File
@@ -16,6 +16,7 @@ namespace sfall
void Inject_RestTimerHook();
void Inject_ExplosiveTimerHook();
void Inject_EncounterHook();
void Inject_RollCheckHook();
// Implementation of is_within_perception_ engine function with the hook
long __fastcall sf_is_within_perception(fo::GameObject* watcher, fo::GameObject* target);