Backported 3 script functions from 4.1:

* dialog_obj, loot_obj, and npc_engine_level_up.
This commit is contained in:
NovaRain
2019-05-08 21:04:18 +08:00
parent ec3bc8c21c
commit 2059a3da8c
9 changed files with 65 additions and 10 deletions
+3
View File
@@ -219,6 +219,7 @@
#define create_win(winName, x, y, w, h) sfall_func5("create_win", winName, x, y, w, h)
#define create_win_flag(winName, x, y, w, h, flag) sfall_func6("create_win", winName, x, y, w, h, flag)
#define critter_inven_obj2(obj, type) sfall_func2("critter_inven_obj2", obj, type)
#define dialog_obj sfall_func0("dialog_obj")
#define display_stats sfall_func0("display_stats")
#define exec_map_update_scripts sfall_func0("exec_map_update_scripts")
#define floor2(value) sfall_func1("floor2", value)
@@ -235,6 +236,8 @@
#define inventory_redraw(invSide) sfall_func1("inventory_redraw", invSide)
#define item_weight(obj) sfall_func1("item_weight", obj)
#define lock_is_jammed(obj) sfall_func1("lock_is_jammed", obj)
#define loot_obj sfall_func0("loot_obj")
#define npc_engine_level_up(toggle) sfall_func1("npc_engine_level_up", toggle)
#define obj_under_cursor(crSwitch, inclDude) sfall_func2("obj_under_cursor", crSwitch, inclDude)
#define outlined_object sfall_func0("outlined_object")
#define set_cursor_mode(mode) sfall_func1("set_cursor_mode", mode)
@@ -458,11 +458,17 @@ Some utility/math functions are available:
- 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
> object sfall_func0("dialog_obj")
- returns a pointer to the object (critter) the player is having a conversation or bartering with
> object sfall_func2("obj_under_cursor", bool crSwitch, bool inclDude)
- returns the object under the cursor on the main game screen
- crSwitch: True - only checks critters and ignores their cover (roof tiles, walls, scenery, etc.), False - checks all objects (can't check critters under objects)
- passing False to the inclDude argument will ignore dude_obj
> object sfall_func0("loot_obj")
- returns a pointer to the target object (container or critter) of the loot screen
> int sfall_func2("get_object_data", object, int offset)
- returns the data at the specified offset of an object (see OBJ_DATA_* constants in define_extra.h for offsets)
@@ -472,6 +478,10 @@ Some utility/math functions are available:
> void sfall_func0("art_cache_clear")
- clears the cache of FRM image files loaded into memory
> void sfall_func1("npc_engine_level_up", bool toggle)
- enables/disables the engine function that increases the level of party members in the player leveling process
- if the engine function is disabled, the process of leveling up party members should be performed by script functions
> int sfall_func1("set_unique_id", object)
> int sfall_func2("set_unique_id", object, int flag)
- assigns a unique ID number to the object and returns it. If a unique ID number has already been assigned to an object, then ID number is returned without reassignment
+8
View File
@@ -48,6 +48,8 @@
#define MAX_GLOBAL_SIZE (MaxGlobalVars * 12 + 4)
DWORD LoadGameHook_LootTarget = 0;
static DWORD InLoop = 0;
static DWORD SaveInCombatFix;
static bool mapLoaded = false;
@@ -64,6 +66,10 @@ DWORD InCombat() {
return (InLoop & COMBAT) ? 1 : 0;
}
DWORD InDialog() {
return (InLoop & DIALOG) ? 1 : 0;
}
DWORD GetCurrentLoops() {
return InLoop;
}
@@ -85,6 +91,7 @@ static void _stdcall ResetState(DWORD onLoad) {
ClearSavPrototypes();
ResetExplosionRadius();
PartyControlReset();
NpcEngineLevelUpReset();
}
void GetSavePath(char* buf, char* ftype) {
@@ -489,6 +496,7 @@ static void __declspec(naked) UseInventoryOnHook() {
static void __declspec(naked) LootContainerHook() {
__asm {
mov LoadGameHook_LootTarget, edx;
or InLoop, INTFACELOOT;
call loot_container_;
and InLoop, (-1 ^ INTFACELOOT);
+3
View File
@@ -18,11 +18,14 @@
#pragma once
extern DWORD LoadGameHook_LootTarget;
void LoadGameHookInit();
bool IsMapLoaded();
DWORD InWorldMap();
DWORD InCombat();
DWORD InDialog();
#define WORLDMAP (1<<0) // 0x1
#define LOCALMAP (1<<1) // 0x2 No point hooking this: would always be 1 at any point at which scripts are running
+18 -10
View File
@@ -32,6 +32,7 @@
#include "PartyControl.h"
bool npcAutoLevelEnabled;
bool npcEngineLevelUp = true;
static DWORD Mode;
static int IsControllingNPC = 0;
@@ -356,6 +357,16 @@ end:
}
}
void __stdcall PartyControlReset() {
if (real_dude != nullptr && IsControllingNPC > 0) {
RestoreRealDudeState();
}
}
bool IsNpcControlled() {
return IsControllingNPC != 0;
}
static char levelMsg[12], armorClassMsg[12], addictMsg[16];
static void __fastcall PartyMemberPrintStat(BYTE* surface, DWORD toWidth) {
const char* fmt = "%s %d";
@@ -404,6 +415,13 @@ static void NpcAutoLevelPatch() {
}
}
void NpcEngineLevelUpReset() {
if (!npcEngineLevelUp) {
npcEngineLevelUp = true;
SafeWrite16(0x4AFC1C, 0x840F);
}
}
void PartyControlInit() {
Mode = GetPrivateProfileIntA("Misc", "ControlCombat", 0, ini);
if (Mode > 2)
@@ -454,13 +472,3 @@ void PartyControlInit() {
dlogr(" Done", DL_INIT);
}
}
void __stdcall PartyControlReset() {
if (real_dude != nullptr && IsControllingNPC > 0) {
RestoreRealDudeState();
}
}
bool IsNpcControlled() {
return IsControllingNPC != 0;
}
+2
View File
@@ -19,8 +19,10 @@
#pragma once
extern bool npcAutoLevelEnabled;
extern bool npcEngineLevelUp;
void PartyControlInit();
void __stdcall PartyControlReset();
int __stdcall PartyControl_SwitchHandHook(TGameObj* item);
bool IsNpcControlled();
void NpcEngineLevelUpReset();
+3
View File
@@ -108,6 +108,7 @@ static const SfallMetarule metaruleArray[] = {
{"attack_is_aimed", sf_attack_is_aimed, 0, 0},
{"critter_inven_obj2", sf_critter_inven_obj2, 2, 2},
{"create_win", sf_create_win, 5, 6},
{"dialog_obj", sf_get_dialog_object, 0, 0},
{"display_stats", sf_display_stats, 0, 0},
{"exec_map_update_scripts", sf_exec_map_update_scripts, 0, 0},
{"floor2", sf_floor2, 1, 1},
@@ -125,6 +126,8 @@ static const SfallMetarule metaruleArray[] = {
{"inventory_redraw", sf_inventory_redraw, 1, 1},
{"item_weight", sf_item_weight, 1, 1},
{"lock_is_jammed", sf_lock_is_jammed, 1, 1},
{"loot_obj", sf_get_loot_object, 0, 0},
{"npc_engine_level_up", sf_npc_engine_level_up, 1, 1},
{"obj_under_cursor", sf_get_obj_under_cursor, 2, 2},
{"outlined_object", sf_outlined_object, 0, 0},
{"set_cursor_mode", sf_set_cursor_mode, 1, 1},
+10
View File
@@ -1488,3 +1488,13 @@ static void sf_set_ini_setting() {
break;
}
}
static void sf_npc_engine_level_up() {
if (opHandler.arg(0).asBool()) {
if (!npcEngineLevelUp) SafeWrite16(0x4AFC1C, 0x840F); // enable
npcEngineLevelUp = true;
} else {
if (npcEngineLevelUp) SafeWrite16(0x4AFC1C, 0xE990);
npcEngineLevelUp = false;
}
}
+8
View File
@@ -619,6 +619,10 @@ static void sf_get_current_inven_size() {
opHandler.setReturn(sf_item_total_size(opHandler.arg(0).asObject()), DATATYPE_INT);
}
static void sf_get_dialog_object() {
opHandler.setReturn(InDialog() ? *ptr_dialog_target : 0, DATATYPE_INT);
}
static void sf_get_obj_under_cursor() {
int crSwitch = opHandler.arg(0).asBool() ? 1 : -1,
inclDude = opHandler.arg(1).rawValue(),
@@ -634,6 +638,10 @@ static void sf_get_obj_under_cursor() {
opHandler.setReturn(obj);
}
static void sf_get_loot_object() {
opHandler.setReturn((GetCurrentLoops() & INTFACELOOT) ? LoadGameHook_LootTarget : 0, DATATYPE_INT);
}
static void sf_get_object_data() {
BYTE* object_ptr = (BYTE*)opHandler.arg(0).asObject();
opHandler.setReturn(*(long*)(object_ptr + opHandler.arg(1).asInt()), DATATYPE_INT);