mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Implemented executing timed_event_p_proc in sfall global scripts
Added "add_g_timer_event" and "remove_timer_event" script functions for timed_event_p_proc in global scripts. Fixed the check on the 'hidden' flag for previous commit.
This commit is contained in:
@@ -249,6 +249,7 @@
|
|||||||
|
|
||||||
// sfall_funcX macros
|
// sfall_funcX macros
|
||||||
#define add_extra_msg_file(name) sfall_func1("add_extra_msg_file", name)
|
#define add_extra_msg_file(name) sfall_func1("add_extra_msg_file", name)
|
||||||
|
#define add_global_timer_event(time, param) sfall_func2("add_g_timer_event", time, param)
|
||||||
#define add_iface_tag sfall_func0("add_iface_tag")
|
#define add_iface_tag sfall_func0("add_iface_tag")
|
||||||
#define add_trait(traitId) sfall_func1("add_trait", traitId)
|
#define add_trait(traitId) sfall_func1("add_trait", traitId)
|
||||||
#define art_cache_clear sfall_func0("art_cache_clear")
|
#define art_cache_clear sfall_func0("art_cache_clear")
|
||||||
@@ -293,6 +294,8 @@
|
|||||||
#define obj_under_cursor(crSwitch, inclDude) sfall_func2("obj_under_cursor", crSwitch, inclDude)
|
#define obj_under_cursor(crSwitch, inclDude) sfall_func2("obj_under_cursor", crSwitch, inclDude)
|
||||||
#define outlined_object sfall_func0("outlined_object")
|
#define outlined_object sfall_func0("outlined_object")
|
||||||
#define real_dude_obj sfall_func0("real_dude_obj")
|
#define real_dude_obj sfall_func0("real_dude_obj")
|
||||||
|
#define remove_all_timer_events sfall_func0("remove_timer_event")
|
||||||
|
#define remove_timer_event(param) sfall_func1("remove_timer_event", param)
|
||||||
#define set_can_rest_on_map(map, elev, value) sfall_func3("set_can_rest_on_map", map, elev, value)
|
#define set_can_rest_on_map(map, elev, value) sfall_func3("set_can_rest_on_map", map, elev, value)
|
||||||
#define set_car_intface_art(artIndex) sfall_func1("set_car_intface_art", artIndex)
|
#define set_car_intface_art(artIndex) sfall_func1("set_car_intface_art", artIndex)
|
||||||
#define set_cursor_mode(mode) sfall_func1("set_cursor_mode", mode)
|
#define set_cursor_mode(mode) sfall_func1("set_cursor_mode", mode)
|
||||||
|
|||||||
@@ -633,6 +633,17 @@ optional argument:
|
|||||||
> int sfall_func0("get_inven_ap_cost")
|
> int sfall_func0("get_inven_ap_cost")
|
||||||
- returns the current AP cost to access the inventory in combat
|
- returns the current AP cost to access the inventory in combat
|
||||||
|
|
||||||
|
> void sfall_func2("add_g_timer_event", int time, int param)
|
||||||
|
- adds a timer event that calls the timed_event_p_proc procedure in the current global script
|
||||||
|
- time: the number of ticks after which the event timer is triggered
|
||||||
|
- param: the value that is passed to the timed_event_p_proc procedure for the fixed_param function
|
||||||
|
|
||||||
|
> void sfall_func0("remove_timer_event")
|
||||||
|
- clears all set timer events for the current global script
|
||||||
|
|
||||||
|
> void sfall_func1("remove_timer_event", int param)
|
||||||
|
- removes all timer events with the specified 'param' value for the current global script
|
||||||
|
|
||||||
------------------------
|
------------------------
|
||||||
------ MORE INFO -------
|
------ MORE INFO -------
|
||||||
------------------------
|
------------------------
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace fo
|
|||||||
namespace func
|
namespace func
|
||||||
{
|
{
|
||||||
|
|
||||||
// prints debug message to debug.log file for develop build
|
// Prints debug message to debug.log file for develop build
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
void __declspec(naked) dev_printf(const char* fmt, ...) {
|
void __declspec(naked) dev_printf(const char* fmt, ...) {
|
||||||
__asm jmp fo::funcoffs::debug_printf_;
|
__asm jmp fo::funcoffs::debug_printf_;
|
||||||
@@ -181,7 +181,7 @@ long __stdcall db_dir_entry(const char *fileName, DWORD *sizeOut) {
|
|||||||
|
|
||||||
// prints message to debug.log file
|
// prints message to debug.log file
|
||||||
void __declspec(naked) debug_printf(const char* fmt, ...) {
|
void __declspec(naked) debug_printf(const char* fmt, ...) {
|
||||||
__asm jmp fo::funcoffs::debug_printf_
|
__asm jmp fo::funcoffs::debug_printf_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Displays message in main UI console window
|
// Displays message in main UI console window
|
||||||
|
|||||||
@@ -591,8 +591,8 @@ static void __declspec(naked) gmouse_bk_process_hook() {
|
|||||||
retn;
|
retn;
|
||||||
checkFlag:
|
checkFlag:
|
||||||
call fo::funcoffs::GNW_find_;
|
call fo::funcoffs::GNW_find_;
|
||||||
cmp [eax + 4], Hidden; // window flags
|
test [eax + 4], Hidden; // window flags
|
||||||
jnz skip;
|
jz skip;
|
||||||
mov eax, ds:[FO_VAR_display_win]; // window is hidden, so return the number of the display_win
|
mov eax, ds:[FO_VAR_display_win]; // window is hidden, so return the number of the display_win
|
||||||
skip:
|
skip:
|
||||||
retn;
|
retn;
|
||||||
@@ -609,7 +609,7 @@ void Interface::init() {
|
|||||||
|
|
||||||
// Fix for interface windows with 'Hidden' and 'ScriptWindow' flags
|
// Fix for interface windows with 'Hidden' and 'ScriptWindow' flags
|
||||||
// Hidden - will not toggle the mouse cursor when the cursor hovers over a hidden window
|
// Hidden - will not toggle the mouse cursor when the cursor hovers over a hidden window
|
||||||
// ScriptWindow - prevents player's movement when clicking on the window if the 'Transparent' flag is not set
|
// ScriptWindow - prevents the player from moving when clicking on the window if the 'Transparent' flag is not set
|
||||||
HookCall(0x44B737, gmouse_bk_process_hook);
|
HookCall(0x44B737, gmouse_bk_process_hook);
|
||||||
LoadGameHook::OnBeforeGameInit() += []() {
|
LoadGameHook::OnBeforeGameInit() += []() {
|
||||||
if (hrpVersionValid) IFACE_BAR_MODE = *(BYTE*)HRPAddress(0x1006EB0C) != 0;
|
if (hrpVersionValid) IFACE_BAR_MODE = *(BYTE*)HRPAddress(0x1006EB0C) != 0;
|
||||||
|
|||||||
@@ -16,9 +16,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
//#include <unordered_set>
|
//#include <unordered_set>
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
@@ -84,6 +82,18 @@ struct SelfOverrideObj {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TimedEvent {
|
||||||
|
ScriptProgram* script;
|
||||||
|
long time;
|
||||||
|
long fixed_param;
|
||||||
|
|
||||||
|
bool operator() (const TimedEvent &a, const TimedEvent &b) {
|
||||||
|
return a.time < b.time;
|
||||||
|
}
|
||||||
|
} *timedEvent = nullptr;
|
||||||
|
|
||||||
|
static std::list<TimedEvent> timerEventScripts;
|
||||||
|
|
||||||
static std::vector<std::string> globalScriptPathList;
|
static std::vector<std::string> globalScriptPathList;
|
||||||
static std::map<std::string, std::string> globalScriptFilesList;
|
static std::map<std::string, std::string> globalScriptFilesList;
|
||||||
|
|
||||||
@@ -132,6 +142,11 @@ static DWORD _stdcall FindSid(fo::Program* script) {
|
|||||||
}
|
}
|
||||||
// this will allow to use functions like roll_vs_skill, etc without calling set_self (they don't really need self object)
|
// this will allow to use functions like roll_vs_skill, etc without calling set_self (they don't really need self object)
|
||||||
if (sfallProgsMap.find(script) != sfallProgsMap.end()) {
|
if (sfallProgsMap.find(script) != sfallProgsMap.end()) {
|
||||||
|
if (timedEvent && timedEvent->script->ptr == script) {
|
||||||
|
overrideScriptStruct.fixedParam = timedEvent->fixed_param;
|
||||||
|
} else {
|
||||||
|
overrideScriptStruct.fixedParam = 0;
|
||||||
|
}
|
||||||
overrideScriptStruct.targetObject = overrideScriptStruct.selfObject = 0;
|
overrideScriptStruct.targetObject = overrideScriptStruct.selfObject = 0;
|
||||||
return -2; // override struct
|
return -2; // override struct
|
||||||
}
|
}
|
||||||
@@ -499,7 +514,9 @@ static void PrepareGlobalScriptsListByMask() {
|
|||||||
static void LoadGlobalScripts() {
|
static void LoadGlobalScripts() {
|
||||||
static bool listIsPrepared = false;
|
static bool listIsPrepared = false;
|
||||||
isGameLoading = false;
|
isGameLoading = false;
|
||||||
|
|
||||||
LoadHookScripts();
|
LoadHookScripts();
|
||||||
|
|
||||||
dlogr("Loading global scripts:", DL_SCRIPT|DL_INIT);
|
dlogr("Loading global scripts:", DL_SCRIPT|DL_INIT);
|
||||||
if (!listIsPrepared) { // only once
|
if (!listIsPrepared) { // only once
|
||||||
PrepareGlobalScriptsListByMask();
|
PrepareGlobalScriptsListByMask();
|
||||||
@@ -528,6 +545,7 @@ static void ClearGlobalScripts() {
|
|||||||
globalScripts.clear();
|
globalScripts.clear();
|
||||||
selfOverrideMap.clear();
|
selfOverrideMap.clear();
|
||||||
globalExportedVars.clear();
|
globalExportedVars.clear();
|
||||||
|
timerEventScripts.clear();
|
||||||
HookScriptClear();
|
HookScriptClear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -617,6 +635,54 @@ static DWORD _stdcall HandleMapUpdateForScripts(const DWORD procId) {
|
|||||||
return procId; // restore eax (don't delete)
|
return procId; // restore eax (don't delete)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long HandleTimedEventScripts() {
|
||||||
|
long currentTime = fo::var::fallout_game_time;
|
||||||
|
bool wereRunning = false;
|
||||||
|
auto timerIt = timerEventScripts.cbegin();
|
||||||
|
for (; timerIt != timerEventScripts.cend(); timerIt++) {
|
||||||
|
if (currentTime >= timerIt->time) {
|
||||||
|
timedEvent = const_cast<TimedEvent*>(&(*timerIt));
|
||||||
|
fo::func::dev_printf("\n[TimedEventScripts] run event: %d", timerIt->time);
|
||||||
|
RunScriptProc(timerIt->script, fo::ScriptProc::timed_event_p_proc);
|
||||||
|
wereRunning = true;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (wereRunning) {
|
||||||
|
for (auto _it = timerEventScripts.cbegin(); _it != timerIt; _it++) {
|
||||||
|
fo::func::dev_printf("\n[TimedEventScripts] delete events: %d", _it->time);
|
||||||
|
}
|
||||||
|
timerEventScripts.erase(timerEventScripts.cbegin(), timerIt);
|
||||||
|
}
|
||||||
|
timedEvent = nullptr;
|
||||||
|
return currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptExtender::AddTimerEventScripts(fo::Program* script, long time, long param) {
|
||||||
|
ScriptProgram* scriptProg = &(sfallProgsMap.find(script)->second);
|
||||||
|
TimedEvent timer;
|
||||||
|
timer.script = scriptProg;
|
||||||
|
timer.fixed_param = param;
|
||||||
|
timer.time = fo::var::fallout_game_time + time;
|
||||||
|
timerEventScripts.push_back(std::move(timer));
|
||||||
|
timerEventScripts.sort(TimedEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptExtender::RemoveTimerEventScripts(fo::Program* script, long param) {
|
||||||
|
ScriptProgram* scriptProg = &(sfallProgsMap.find(script)->second);
|
||||||
|
timerEventScripts.remove_if([scriptProg, param] (TimedEvent timer) {
|
||||||
|
return timer.script == scriptProg && timer.fixed_param == param;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptExtender::RemoveTimerEventScripts(fo::Program* script) {
|
||||||
|
ScriptProgram* scriptProg = &(sfallProgsMap.find(script)->second);
|
||||||
|
timerEventScripts.remove_if([scriptProg] (TimedEvent timer) {
|
||||||
|
return timer.script == scriptProg;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// run all global scripts of types 0 and 3 at specific procedure (if exist)
|
// run all global scripts of types 0 and 3 at specific procedure (if exist)
|
||||||
void RunGlobalScriptsAtProc(DWORD procId) {
|
void RunGlobalScriptsAtProc(DWORD procId) {
|
||||||
for (DWORD d = 0; d < globalScripts.size(); d++) {
|
for (DWORD d = 0; d < globalScripts.size(); d++) {
|
||||||
@@ -754,9 +820,9 @@ void ScriptExtender::init() {
|
|||||||
alwaysFindScripts = isDebug && (iniGetInt("Debugging", "AlwaysFindScripts", 0, ::sfall::ddrawIni) != 0);
|
alwaysFindScripts = isDebug && (iniGetInt("Debugging", "AlwaysFindScripts", 0, ::sfall::ddrawIni) != 0);
|
||||||
if (alwaysFindScripts) dlogr("Always searching for global scripts behavior enabled.", DL_SCRIPT);
|
if (alwaysFindScripts) dlogr("Always searching for global scripts behavior enabled.", DL_SCRIPT);
|
||||||
|
|
||||||
MakeJump(0x4A390C, FindSidHack);
|
MakeJump(0x4A390C, FindSidHack); // scr_find_sid_from_program_
|
||||||
MakeJump(0x4A5E34, ScrPtrHack);
|
MakeJump(0x4A5E34, ScrPtrHack);
|
||||||
|
HookCall(0x4A26D6, HandleTimedEventScripts); // queue_process_
|
||||||
MakeJump(0x4A67F0, ExecMapScriptsHack);
|
MakeJump(0x4A67F0, ExecMapScriptsHack);
|
||||||
|
|
||||||
// this patch makes it possible to export variables from sfall global scripts
|
// this patch makes it possible to export variables from sfall global scripts
|
||||||
|
|||||||
@@ -34,6 +34,10 @@ public:
|
|||||||
|
|
||||||
static std::string iniConfigFolder;
|
static std::string iniConfigFolder;
|
||||||
|
|
||||||
|
static void AddTimerEventScripts(fo::Program* script, long time, long param);
|
||||||
|
static void RemoveTimerEventScripts(fo::Program* script, long param);
|
||||||
|
static void RemoveTimerEventScripts(fo::Program* script);
|
||||||
|
|
||||||
// Called before map exit (before map_exit_p_proc handlers in normal scripts)
|
// Called before map exit (before map_exit_p_proc handlers in normal scripts)
|
||||||
static Delegate<>& OnMapExit();
|
static Delegate<>& OnMapExit();
|
||||||
};
|
};
|
||||||
@@ -67,6 +71,7 @@ void SetGlobals(GlobalVar* globals);
|
|||||||
|
|
||||||
long SetGlobalVar(const char* var, int val);
|
long SetGlobalVar(const char* var, int val);
|
||||||
void SetGlobalVarInt(DWORD var, int val);
|
void SetGlobalVarInt(DWORD var, int val);
|
||||||
|
|
||||||
long GetGlobalVar(const char* var);
|
long GetGlobalVar(const char* var);
|
||||||
long GetGlobalVarInt(DWORD var);
|
long GetGlobalVarInt(DWORD var);
|
||||||
long GetGlobalVarInternal(__int64 val);
|
long GetGlobalVarInternal(__int64 val);
|
||||||
|
|||||||
@@ -184,6 +184,18 @@ void sf_register_hook(OpcodeContext& ctx) {
|
|||||||
RegisterHook(ctx.program(), ctx.arg(0).rawValue(), proc, specReg);
|
RegisterHook(ctx.program(), ctx.arg(0).rawValue(), proc, specReg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sf_add_g_timer_event(OpcodeContext& ctx) {
|
||||||
|
ScriptExtender::AddTimerEventScripts(ctx.program(), ctx.arg(0).rawValue(), ctx.arg(1).rawValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
void sf_remove_timer_event(OpcodeContext& ctx) {
|
||||||
|
if (ctx.numArgs() > 0) {
|
||||||
|
ScriptExtender::RemoveTimerEventScripts(ctx.program(), ctx.arg(0).rawValue());
|
||||||
|
} else {
|
||||||
|
ScriptExtender::RemoveTimerEventScripts(ctx.program()); // remove all
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void sf_sfall_ver_major(OpcodeContext& ctx) {
|
void sf_sfall_ver_major(OpcodeContext& ctx) {
|
||||||
ctx.setReturn(VERSION_MAJOR);
|
ctx.setReturn(VERSION_MAJOR);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ void __declspec() op_set_self();
|
|||||||
// used for both register_hook and register_hook_proc
|
// used for both register_hook and register_hook_proc
|
||||||
void sf_register_hook(OpcodeContext&);
|
void sf_register_hook(OpcodeContext&);
|
||||||
|
|
||||||
|
void sf_add_g_timer_event(OpcodeContext&);
|
||||||
|
|
||||||
|
void sf_remove_timer_event(OpcodeContext&);
|
||||||
|
|
||||||
void sf_sfall_ver_major(OpcodeContext&);
|
void sf_sfall_ver_major(OpcodeContext&);
|
||||||
|
|
||||||
void sf_sfall_ver_minor(OpcodeContext&);
|
void sf_sfall_ver_minor(OpcodeContext&);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "..\Arrays.h"
|
#include "..\Arrays.h"
|
||||||
#include "..\OpcodeContext.h"
|
#include "..\OpcodeContext.h"
|
||||||
#include "Anims.h"
|
#include "Anims.h"
|
||||||
|
#include "Core.h"
|
||||||
#include "Interface.h"
|
#include "Interface.h"
|
||||||
#include "Misc.h"
|
#include "Misc.h"
|
||||||
#include "Objects.h"
|
#include "Objects.h"
|
||||||
@@ -61,6 +62,7 @@ static MetaruleTableType metaruleTable;
|
|||||||
static const SfallMetarule metarules[] = {
|
static const SfallMetarule metarules[] = {
|
||||||
{"add_extra_msg_file", sf_add_extra_msg_file, 1, 2, {ARG_STRING, ARG_INT}},
|
{"add_extra_msg_file", sf_add_extra_msg_file, 1, 2, {ARG_STRING, ARG_INT}},
|
||||||
{"add_iface_tag", sf_add_iface_tag, 0, 0},
|
{"add_iface_tag", sf_add_iface_tag, 0, 0},
|
||||||
|
{"add_g_timer_event", sf_add_g_timer_event, 2, 2, {ARG_INT, ARG_INT}},
|
||||||
{"add_trait", sf_add_trait, 1, 1, {ARG_INT}},
|
{"add_trait", sf_add_trait, 1, 1, {ARG_INT}},
|
||||||
{"art_cache_clear", sf_art_cache_flush, 0, 0},
|
{"art_cache_clear", sf_art_cache_flush, 0, 0},
|
||||||
{"attack_is_aimed", sf_attack_is_aimed, 0, 0},
|
{"attack_is_aimed", sf_attack_is_aimed, 0, 0},
|
||||||
@@ -103,6 +105,7 @@ static const SfallMetarule metarules[] = {
|
|||||||
{"obj_under_cursor", sf_get_obj_under_cursor, 2, 2, {ARG_INT, ARG_INT}},
|
{"obj_under_cursor", sf_get_obj_under_cursor, 2, 2, {ARG_INT, ARG_INT}},
|
||||||
{"outlined_object", sf_outlined_object, 0, 0},
|
{"outlined_object", sf_outlined_object, 0, 0},
|
||||||
{"real_dude_obj", sf_real_dude_obj, 0, 0},
|
{"real_dude_obj", sf_real_dude_obj, 0, 0},
|
||||||
|
{"remove_timer_event", sf_remove_timer_event, 0, 1, {ARG_INT}},
|
||||||
{"set_can_rest_on_map", sf_set_rest_on_map, 3, 3, {ARG_INT, ARG_INT, ARG_INT}},
|
{"set_can_rest_on_map", sf_set_rest_on_map, 3, 3, {ARG_INT, ARG_INT, ARG_INT}},
|
||||||
{"set_car_intface_art", sf_set_car_intface_art, 1, 1, {ARG_INT}},
|
{"set_car_intface_art", sf_set_car_intface_art, 1, 1, {ARG_INT}},
|
||||||
{"set_cursor_mode", sf_set_cursor_mode, 1, 1, {ARG_INT}},
|
{"set_cursor_mode", sf_set_cursor_mode, 1, 1, {ARG_INT}},
|
||||||
|
|||||||
Reference in New Issue
Block a user