Added new HOOK_SETLIGHTING (from Mr.Stalin) (#215)

This commit is contained in:
NovaRain
2018-12-30 08:01:13 +08:00
parent 267d8694c9
commit b89663174f
8 changed files with 92 additions and 2 deletions
+1
View File
@@ -59,6 +59,7 @@
#define HOOK_USESKILLON (35)
#define HOOK_ONEXPLOSION (36)
#define HOOK_SUBCOMBATDAMAGE (37)
#define HOOK_SETLIGHTING (38)
//Valid arguments to list_begin
#define LIST_CRITTERS (0)
+13
View File
@@ -603,3 +603,16 @@ int arg11 - The calculated amount of damage (usually 0, required when using
mixed arg12 - Computed attack results (see C_ATTACK_* for offsets and use get/set_object_data functions to get/set the data)
int ret1 - The returned amount of damage
-------------------------------------------
HOOK_SETLIGHTING (hs_setlighting.int)
Runs before setting the light level for an object or a map. You can override the result.
Obj arg1 - the object being set, or -1 when setting the light level for a map
int arg2 - the light intensity
int arg3 - the light radius, or -1 when setting the light level for a map
int ret1 - overrides the light intensity. Intensity range is from 0 to 65536
int ret2 - overrides the light radius. Radius range is from 0 to 8 (works only for the object)
+2 -2
View File
@@ -141,7 +141,7 @@ array - array ID to be used with array-related functions (actually an integer)
- In this case use force_encounter_with_flags with the ENCOUNTER_FLAG_NO_CAR flag set.
> int get_light_level()
- ambient light level in range 0..65535
- ambient light level in range 0..65536
- The value returned by get_light_level may not exactly match that set by set_light_level, as set_light_level applies modifiers from the night vision perk.
> void set_map_time_multi(float multi)
@@ -325,7 +325,7 @@ Some utility/math functions are available:
- this calls an internal engine function which is used to determine the perception range of critters (which you can override using HOOK_WITHINPERCEPTION)
> int tile_light(int elevation, int tileNum)
- returns light intensity at the given tile in range from 0 to 65535
- returns light intensity at the given tile in range from 0 to 65536
> object obj_blocking_line(object objFrom, int tileTo, int blockingType)
- returns first object which blocks direct linear path from objFrom to tileTo using selected blocking function (see BLOCKING_TYPE_* constants in sfall.h)
+1
View File
@@ -82,6 +82,7 @@ static HooksInjectInfo injectHooks[] = {
{HOOK_USESKILLON, Inject_UseSkillOnHook, false},
{HOOK_ONEXPLOSION, Inject_OnExplosionHook, false},
{HOOK_SUBCOMBATDAMAGE, Inject_SubCombatDamageHook, false}, // replace the code logic
{HOOK_SETLIGHTING, Inject_SetLightingHook, false},
};
bool HookScripts::injectAllHooks;
+1
View File
@@ -64,6 +64,7 @@ enum HookType
HOOK_USESKILLON = 35,
HOOK_ONEXPLOSION = 36,
HOOK_SUBCOMBATDAMAGE = 37,
HOOK_SETLIGHTING = 38,
HOOK_COUNT
};
+1
View File
@@ -65,6 +65,7 @@ static bool CheckRecursiveHooks(DWORD hook) {
if (hook == currentRunHook) {
switch (hook) {
case HOOK_SETGLOBALVAR:
case HOOK_SETLIGHTING:
return true;
}
}
+72
View File
@@ -171,6 +171,72 @@ skip:
}
}
static bool __fastcall SetLightingHook_Script(DWORD* intensity, DWORD* radius, DWORD object) {
BeginHook();
argCount = 3;
args[0] = object;
args[1] = *intensity;
args[2] = *radius;
RunHookScript(HOOK_SETLIGHTING);
bool result = false;
if (cRet > 0) {
int light = rets[0];
if (light < 0) light = 0;
*intensity = light;
if (cRet > 1 && object != -1) {
int dist = rets[1];
if (dist < 0) dist = 0;
*radius = dist;
}
result = true;
}
EndHook();
return result;
}
static void __declspec(naked) SetObjectLightHook() {
__asm {
pushadc;
push ebp;
mov edx, esp; // &radius
push ebx;
mov ecx, esp; // &intensity
push esi; // object
call SetLightingHook_Script;
test al, al;
jz skip;
pop ebx; // return intensity value
pop ebp; // return radius value
jmp end;
skip:
add esp, 8;
end:
popadc;
jmp fo::funcoffs::obj_turn_off_light_;
}
}
static void __declspec(naked) SetMapLightHook() {
__asm {
push ecx;
push ebx;
mov ecx, esp; // &intensity
push -1; // no object (it's a map)
mov edx, esp; // no radius
call SetLightingHook_Script;
add esp, 4;
test al, al;
jz skip;
mov ebx, [esp - 4]; // return intensity value
skip:
pop ecx;
cmp ebx, dword ptr ds:[0x47A93D]; // get miminal ambient light intensity (16384)
retn;
}
}
void Inject_UseObjOnHook() {
HookCalls(UseObjOnHook, { 0x49C606, 0x473619 });
@@ -195,12 +261,18 @@ void Inject_DescriptionObjHook() {
HookCall(0x48C925, DescriptionObjHook);
}
void Inject_SetLightingHook() {
HookCall(0x48ACA0, SetObjectLightHook);
MakeCall(0x47A934, SetMapLightHook, 1);
}
void InitObjectHookScripts() {
LoadHookScript("hs_useobjon", HOOK_USEOBJON);
LoadHookScript("hs_useobj", HOOK_USEOBJ);
LoadHookScript("hs_useanimobj", HOOK_USEANIMOBJ);
LoadHookScript("hs_descriptionobj", HOOK_DESCRIPTIONOBJ);
LoadHookScript("hs_setlighting", HOOK_SETLIGHTING);
}
}
+1
View File
@@ -8,4 +8,5 @@ namespace sfall
void Inject_UseObjHook();
void Inject_UseAnimateObjHook();
void Inject_DescriptionObjHook();
void Inject_SetLightingHook();
}