Added "dialog_box" script function

Added a new attrType value to "get_window_attribute" function.

Tweaked the arg type check for "force_encounter_with_flags" function.
This commit is contained in:
NovaRain
2020-01-27 20:52:01 +08:00
parent 6b1fffded1
commit 893847cc6a
10 changed files with 143 additions and 67 deletions
+5 -3
View File
@@ -59,7 +59,7 @@
#define LIST_ALL (9)
//Valid window types for get_window_attribute
#define WINTYPE_INVENTORY (0) // any inventory window
#define WINTYPE_INVENTORY (0) // any inventory window (player/loot/use/barter)
#define WINTYPE_DIALOG (1)
#define WINTYPE_PIPBOY (2)
#define WINTYPE_WORLDMAP (3)
@@ -244,6 +244,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_box(text) sfall_func1("dialog_box", text)
#define dialog_obj sfall_func0("dialog_obj")
#define display_stats sfall_func0("display_stats")
#define draw_image(pathFile, frame, x, y, noTrans) sfall_func5("draw_image", pathFile, frame, x, y, noTrans)
@@ -253,8 +254,8 @@
#define get_current_inven_size(obj) sfall_func1("get_current_inven_size", obj)
#define get_cursor_mode sfall_func0("get_cursor_mode")
#define get_flags(obj) sfall_func1("get_flags", obj)
#define get_interface_x(winType) sfall_func2("get_window_attribute", winType, 0)
#define get_interface_y(winType) sfall_func2("get_window_attribute", winType, 1)
#define get_interface_x(winType) sfall_func2("get_window_attribute", winType, 1)
#define get_interface_y(winType) sfall_func2("get_window_attribute", winType, 2)
#define get_inven_ap_cost sfall_func0("get_inven_ap_cost")
#define get_map_enter_position sfall_func0("get_map_enter_position")
#define get_metarule_table sfall_func0("get_metarule_table")
@@ -265,6 +266,7 @@
#define hide_window(winName) sfall_func1("hide_window", winName)
#define intface_hide sfall_func0("intface_hide")
#define intface_is_hidden sfall_func0("intface_is_hidden")
#define intface_is_shown(winType) sfall_func1("get_window_attribute", winType)
#define intface_redraw sfall_func0("intface_redraw")
#define intface_show sfall_func0("intface_show")
#define inventory_redraw(invSide) sfall_func1("inventory_redraw", invSide)
+12 -2
View File
@@ -611,15 +611,25 @@ optional arguments:
> void sfall_func3("set_terrain_name", int x, int y, string name)
- overrides the terrain type name for the sub-tile on the world map by the specified coordinates
int sfall_func2("get_window_attribute", int winType, int attrType)
> int sfall_func1("get_window_attribute", int winType)
> int sfall_func2("get_window_attribute", int winType, int attrType)
- returns the attribute of the specified interface window by the attrType argument
- winType: the type number of the interface window (see WINTYPE_* constants in sfall.h)
- attrType: 0 - X position, 1 - Y position (relative to the top-left corner of the game screen)
- attrType: 0 - returns a value of 1 if the specified interface window is created by the game (same as without the argument)
1 - X position, 2 - Y position (relative to the top-left corner of the game screen)
- returns -1 if the specified attribute cannot be obtained
> void sfall_func2("set_town_title", int areaID, string title)
- sets a floating text for a town on the world map when hovering the cursor over the player's marker
- areaID: the ID number of the town from city.txt
> int sfall_func1("dialog_box", string text1)
> int sfall_func2("dialog_box", string text1, string text2)
> int sfall_func3("dialog_box", string text1, string text2, string text3)
- creates a dialog box with text and returns the result of pressing the button: 0 - No, 1 - Yes
- text1/text2/text3: corresponding text in the dialog box for the first, second, and third lines
- returns -1 if for some reason the dialog box cannot be created
------------------------
------ MORE INFO -------
------------------------
+10
View File
@@ -444,3 +444,13 @@ enum QueueType : long
map_update_event = 12,
gsound_sfx_event = 13 // no object
};
enum DialogOutFlags : long
{
DIALOGOUT_NORMAL = 0x01, // uses regular graphic
DIALOGOUT_SMALL = 0x02, // uses smaller graphic
DIALOGOUT_ALIGN_LEFT = 0x04, // text aligned to left
DIALOGOUT_ALIGN_TOP = 0x08, // text aligned to top
DIALOGOUT_YESNO = 0x10, // DONE button replaced by YES/NO buttons - WIP: currently useless in scripts
DIALOGOUT_CLEAN = 0x20 // no buttons
};
+33 -6
View File
@@ -989,8 +989,12 @@ long __fastcall ScrSetLocalVar(long sid, long varId, long value) {
WRAP_WATCOM_FCALL3(scr_set_local_var_, sid, varId, value)
}
long __stdcall IntfaceIsHidden() {
WRAP_WATCOM_CALL0(intface_is_hidden_)
}
// redraws the main game interface windows (useful after changing some data like active hand, etc.)
void __stdcall InterfaceRedraw() {
void __stdcall IntfaceRedraw() {
WRAP_WATCOM_CALL0(intface_redraw_)
}
@@ -1081,21 +1085,36 @@ long __stdcall WinRegisterButton(DWORD winRef, long xPos, long yPos, long width,
void __stdcall DialogOut(const char* text) {
__asm {
push 1; // flag
push 1; // DIALOGOUT_NORMAL flag
xor eax, eax;
push eax; // ColorMsg
push eax; // DisplayMsg
push eax; // DisplayMsg (unknown)
mov al, byte ptr ds:[0x6AB718];
push eax; // ColorIndex
push 116; // y
mov ecx, 192; // x
mov eax, text; // DisplayText
xor ebx, ebx; // ?
xor edx, edx; // ?
xor ebx, ebx;
xor edx, edx;
call dialog_out_;
}
}
long __fastcall DialogOutEx(const char* text, const char** textEx, long count, long flags) {
__asm {
mov eax, 145; // Color index
push flags; // flag
push eax; // ColorMsg2
push 0; // DisplayMsg (unknown)
push eax; // ColorMsg1
mov eax, ecx; // DisplayText first line
push 116; // y
mov ecx, 192; // x
mov ebx, count; // count text lines 0-2
call dialog_out_; // edx - DisplayText second/third line
}
}
void __fastcall DrawWinLine(int winRef, DWORD startXPos, DWORD endXPos, DWORD startYPos, DWORD endYPos, BYTE colour) {
__asm {
xor eax, eax;
@@ -1160,6 +1179,14 @@ long __fastcall WordWrap(const char* text, int maxWidth, DWORD* buf, BYTE* count
WRAP_WATCOM_FCALL4(_word_wrap_, text, maxWidth, buf, count)
}
long __stdcall Gmouse3dGetMode() {
WRAP_WATCOM_CALL0(gmouse_3d_get_mode_)
}
void __stdcall Gmouse3dSetMode(long mode) {
WRAP_WATCOM_CALL1(gmouse_3d_set_mode_, mode)
}
long __stdcall GsoundBackgroundVolumeGetSet(long setVolume) {
WRAP_WATCOM_CALL1(gsound_background_volume_get_set_, setVolume)
}
@@ -1480,7 +1507,7 @@ long __fastcall GetTopWindowID(long xPos, long yPos) {
}
enum WinNameType {
WINTYPE_Inventory = 0, // any inventory window
WINTYPE_Inventory = 0, // any inventory window (player/loot/use/barter)
WINTYPE_Dialog = 1,
WINTYPE_PipBoy = 2,
WINTYPE_WorldMap = 3,
+9 -1
View File
@@ -1139,8 +1139,10 @@ void __fastcall RegisterObjectCall(long* target, long* source, void* func, long
long __fastcall ScrGetLocalVar(long sid, long varId, long* value);
long __fastcall ScrSetLocalVar(long sid, long varId, long value);
long __stdcall IntfaceIsHidden();
// redraws the main game interface windows (useful after changing some data like active hand, etc.)
void __stdcall InterfaceRedraw();
void __stdcall IntfaceRedraw();
void __stdcall ProcessBk();
@@ -1186,6 +1188,8 @@ long __stdcall WinRegisterButton(DWORD winRef, long xPos, long yPos, long width,
void __stdcall DialogOut(const char* text);
long __fastcall DialogOutEx(const char* text, const char** textEx, long count, long flags);
void __fastcall WindowDisplayBuf(long x, long width, long y, long height, void* data, long noTrans);
void __fastcall DisplayInWindow(long w_here, long width, long height, void* data);
@@ -1196,6 +1200,10 @@ long __fastcall GetGameConfigString(const char* outValue, const char* section, c
long __fastcall WordWrap(const char* text, int maxWidth, DWORD* buf, BYTE* count);
long __stdcall Gmouse3dGetMode();
void __stdcall Gmouse3dSetMode(long mode);
long __stdcall GsoundBackgroundVolumeGetSet(long setVolume);
WINinfo* __stdcall GNWFind(long winRef);
+2 -2
View File
@@ -160,7 +160,7 @@ static void TakeControlOfNPC(TGameObj* npc) {
delayedExperience = 0;
SetInventoryCheck(true);
InterfaceRedraw();
IntfaceRedraw();
}
// restores the real dude state
@@ -195,7 +195,7 @@ static void RestoreRealDudeState(bool redraw = true) {
SafeWrite8(0x422BDE, 1);
}
if (redraw) InterfaceRedraw();
if (redraw) IntfaceRedraw();
SetInventoryCheck(false);
isControllingNPC = false;
+1
View File
@@ -417,6 +417,7 @@ static const SfallOpcodeMetadata opcodeMetaArray[] = {
{sf_add_g_timer_event, "add_g_timer_event", {DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
{sf_add_trait, "add_trait", {DATATYPE_MASK_INT}},
{sf_create_win, "create_win", {DATATYPE_MASK_STR, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
{sf_dialog_box, "dialog_box", {DATATYPE_MASK_STR, DATATYPE_MASK_STR, DATATYPE_MASK_STR}},
{sf_draw_image, "draw_image", {DATATYPE_MASK_INT | DATATYPE_MASK_STR, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
{sf_draw_image_scaled, "draw_image_scaled", {DATATYPE_MASK_INT | DATATYPE_MASK_STR, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
{sf_hide_window, "hide_window", {DATATYPE_MASK_STR}},
+55 -36
View File
@@ -168,13 +168,15 @@ static void __declspec(naked) resume_game() {
}
}
static bool dialogShow = false;
static void _stdcall create_message_window2() {
const ScriptValue &strArg = opHandler.arg(0);
if (strArg.isString()) {
static bool dialogShow = false;
if (dialogShow) return;
const char* str = strArg.strValue();
if (!str || str[0] == 0) return;
dialogShow = true;
DialogOut(str);
dialogShow = false;
@@ -187,6 +189,26 @@ static void __declspec(naked) create_message_window() {
_WRAP_OPCODE(create_message_window2, 1, 0)
}
static void sf_dialog_box() {
const char* str = opHandler.arg(0).strValue();
if (!str || str[0] == 0) return;
const char* str2[2];
long lines = 0;
if (opHandler.numArgs() > 1) {
++lines;
str2[0] = opHandler.arg(1).strValue();
}
if (opHandler.numArgs() > 2) {
++lines;
str2[1] = opHandler.arg(2).strValue();
}
*(DWORD*)_script_engine_running = 0;
long result = DialogOutEx(str, str2, lines, DIALOGOUT_NORMAL | DIALOGOUT_YESNO);
*(DWORD*)_script_engine_running = 1;
opHandler.setReturn(result);
}
static void __declspec(naked) GetViewportX() {
__asm {
mov edx, ds:[_wmWorldOffsetX];
@@ -302,7 +324,7 @@ static void __declspec(naked) IsIfaceTagActive() {
}
static void sf_intface_redraw() {
InterfaceRedraw();
IntfaceRedraw();
}
static void sf_intface_show() {
@@ -314,12 +336,7 @@ static void sf_intface_hide() {
}
static void sf_intface_is_hidden() {
int isHidden;
__asm {
call intface_is_hidden_;
mov isHidden, eax;
}
opHandler.setReturn(isHidden);
opHandler.setReturn(IntfaceIsHidden());
}
static void sf_tile_refresh_display() {
@@ -327,20 +344,11 @@ static void sf_tile_refresh_display() {
}
static void sf_get_cursor_mode() {
int cursorMode;
__asm {
call gmouse_3d_get_mode_;
mov cursorMode, eax;
}
opHandler.setReturn(cursorMode);
opHandler.setReturn(Gmouse3dGetMode());
}
static void sf_set_cursor_mode() {
int cursorMode = opHandler.arg(0).rawValue();
__asm {
mov eax, cursorMode;
call gmouse_3d_set_mode_;
}
Gmouse3dSetMode(opHandler.arg(0).rawValue());
}
static void sf_display_stats() {
@@ -590,8 +598,7 @@ static void sf_draw_image_scaled() {
}
// initialize other args
int frameno = 0, x = 0, y = 0, wsize = 0;
const int argNums = opHandler.numArgs();
switch (argNums) {
switch (opHandler.numArgs()) {
case 6:
case 5:
wsize = opHandler.arg(4).rawValue();
@@ -611,17 +618,17 @@ static void sf_draw_image_scaled() {
framePtr = (FrmFrameData*)offsFrame;
}
}
if (argNums < 3) {
if (opHandler.numArgs() < 3) {
DisplayInWindow(framePtr->width, framePtr->width, framePtr->height, framePtr->data); // scaled to window size (w/o transparent)
} else {
// draw to scale
long s_width, s_height;
if (argNums < 5) {
if (opHandler.numArgs() < 5) {
s_width = framePtr->width;
s_height = framePtr->height;
} else {
s_width = wsize;
s_height = (argNums > 5) ? opHandler.arg(5).rawValue() : -1;
s_height = (opHandler.numArgs() > 5) ? opHandler.arg(5).rawValue() : -1;
}
// scale with aspect ratio if w or h is set to -1
if (s_width <= -1 && s_height > 0) {
@@ -708,30 +715,42 @@ static void sf_unwield_slot() {
}
void sf_get_window_attribute() {
const ScriptValue &winArg = opHandler.arg(0),
&attrArg = opHandler.arg(1);
if (winArg.isInt() && attrArg.isInt()) {
const ScriptValue &winArg = opHandler.arg(0);
if (winArg.isInt()) {
long attr = 0;
if (opHandler.numArgs() > 1) {
const ScriptValue &attrArg = opHandler.arg(1);
if (!attrArg.isInt()) goto invalidArgs;
attr = attrArg.rawValue();
}
WINinfo* win = GetUIWindow(winArg.rawValue());
if (win == nullptr) {
opHandler.printOpcodeError("get_window_attribute() - failed to get the interface window.");
if (attr != 0) {
opHandler.printOpcodeError("get_window_attribute() - failed to get the interface window.");
opHandler.setReturn(-1);
}
return;
}
if ((long)win == -1) {
opHandler.printOpcodeError("get_window_attribute() - invalid window type number.");
opHandler.setReturn(-1);
return;
}
long pos = 0;
switch (attrArg.rawValue()) {
case 0: // x
pos = win->wRect.left;
long result = 0;
switch (attr) {
case 0: // check if window exists
result = 1;
break;
case 1: // y
pos = win->wRect.top;
case 1: // x
result = win->wRect.left;
break;
case 2: // y
result = win->wRect.top;
break;
}
opHandler.setReturn(pos);
opHandler.setReturn(result);
} else {
invalidArgs:
OpcodeInvalidArgs("get_window_attribute");
opHandler.setReturn(0);
}
+2 -1
View File
@@ -126,6 +126,7 @@ static const SfallMetarule metaruleArray[] = {
{"create_win", sf_create_win, 5, 6},
{"critter_inven_obj2", sf_critter_inven_obj2, 2, 2},
{"dialog_obj", sf_get_dialog_object, 0, 0},
{"dialog_box", sf_dialog_box, 1, 3},
{"display_stats", sf_display_stats, 0, 0}, // refresh
{"draw_image", sf_draw_image, 1, 5},
{"draw_image_scaled", sf_draw_image_scaled, 1, 6},
@@ -141,7 +142,7 @@ static const SfallMetarule metaruleArray[] = {
{"get_outline", sf_get_outline, 1, 1},
{"get_sfall_arg_at", sf_get_sfall_arg_at, 1, 1},
{"get_text_width", sf_get_text_width, 1, 1},
{"get_window_attribute", sf_get_window_attribute, 2, 2},
{"get_window_attribute", sf_get_window_attribute, 1, 2},
{"hide_window", sf_hide_window, 0, 1},
{"intface_hide", sf_intface_hide, 0, 0},
{"intface_is_hidden", sf_intface_is_hidden, 0, 0},
+14 -16
View File
@@ -81,31 +81,29 @@ static void _stdcall ForceEncounter2() {
const ScriptValue &mapIDArg = opHandler.arg(0);
if (mapIDArg.isInt()) {
DWORD flags = 0;
if (opHandler.numArgs() > 1) {
const ScriptValue &flagsArg = opHandler.arg(1);
if (!flagsArg.isInt()) goto invalidArgs;
flags = flagsArg.rawValue();
if (flags & 2) { // _Lock flag
flags |= (1 << 31); // set bit 31
} else {
flags &= ~(1 << 31);
}
}
DWORD mapID = mapIDArg.rawValue();
if (mapID < 0) {
opHandler.printOpcodeError("force_encounter() - invalid map number.");
opHandler.printOpcodeError("force_encounter/force_encounter_with_flags() - invalid map number.");
return;
}
if (ForceEncounterMapID == -1) MakeJump(0x4C06D1, wmRndEncounterOccurred_hack);
ForceEncounterMapID = mapID;
DWORD flags = 0;
if (opHandler.numArgs() > 1) {
const ScriptValue &flagsArg = opHandler.arg(1);
if (flagsArg.isInt()) {
flags = opHandler.arg(1).rawValue();
if (flags & 2) { // _Lock flag
flags |= (1 << 31); // set bit 31
} else {
flags &= ~(1 << 31);
}
} else {
opHandler.printOpcodeError("force_encounter_with_flags() - invalid flags.");
}
}
ForceEncounterFlags = flags;
} else {
OpcodeInvalidArgs("force_encounter");
invalidArgs:
OpcodeInvalidArgs("force_encounter/force_encounter_with_flags");
}
}