Added "interface_art_draw" script function

Added an argument to "intface_redraw" function to redraw all interfaces.
This commit is contained in:
NovaRain
2020-09-26 16:15:32 +08:00
parent 88d9126b18
commit e696db4b7b
12 changed files with 131 additions and 25 deletions
+7 -2
View File
@@ -89,6 +89,7 @@
#define WINTYPE_CHARACTER (5)
#define WINTYPE_SKILLDEX (6)
#define WINTYPE_ESCMENU (7) // escape menu
#define WINTYPE_AUTOMAP (8)
//Valid flags for force_encounter_with_flags
#define ENCOUNTER_FLAG_NO_CAR (0x1)
@@ -299,8 +300,8 @@
#define dialog_message(text) sfall_func1("dialog_message", 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)
#define draw_image_scaled(pathFile, frame, x, y, w, h) sfall_func6("draw_image_scaled", pathFile, frame, x, y, w, h)
#define draw_image(artFile, frame, x, y, noTrans) sfall_func5("draw_image", artFile, frame, x, y, noTrans)
#define draw_image_scaled(artFile, frame, x, y, w, h) sfall_func6("draw_image_scaled", artFile, frame, x, y, w, h)
#define exec_map_update_scripts sfall_func0("exec_map_update_scripts")
#define floor2(value) sfall_func1("floor2", value)
#define get_can_rest_on_map(map, elev) sfall_func2("get_can_rest_on_map", map, elev)
@@ -327,6 +328,10 @@
#define has_fake_perk_npc(npc, perk) sfall_func2("has_fake_perk_npc", npc, perk)
#define has_fake_trait_npc(npc, trait) sfall_func2("has_fake_trait_npc", npc, trait)
#define hide_window(winName) sfall_func1("hide_window", winName)
#define interface_art_draw(winID, artFile, x, y) sfall_func4("interface_art_draw", winID, artFile, x, y)
#define interface_art_draw_frame(wID, art, x, y, frame) sfall_func5("interface_art_draw", wID, art, x, y, frame)
#define interface_art_draw_ex(wID, art, x, y, frm, prm) sfall_func6("interface_art_draw", wID, art, x, y, frm, prm)
#define interface_redraw_all sfall_func1("intface_redraw", 1)
#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)
+24 -9
View File
@@ -356,7 +356,7 @@ Some utility/math functions are available:
- returns first object blocking given tile using given blocking function or 0 if tile is clear
> array tile_get_objs(int tileNum, int elevation)
- returns array of all objects at given tile
- returns an array of all objects at given tile
- it will include any hidden, dead or system objects (like cursor), so make sure to check properly when iterating
> array party_member_list(int includeHidden)
@@ -402,8 +402,9 @@ Some utility/math functions are available:
- works just like vanilla critter_inven_obj, but correctly reports item in player's inactive hand slot
> void sfall_func0("intface_redraw")
- redraws main game interface
- useful after direct changes to current player weapons or stats to reflect changes
> void sfall_func1("intface_redraw", bool eachWin)
- redraws main game interface, useful to reflect changes after directly changing current player weapons or stats
- eachWin: pass True to redraw all interface windows
> void sfall_func0("intface_hide")
- hides main interface
@@ -612,15 +613,15 @@ Some utility/math functions are available:
- there is also a unique ID number range for the player and party members from 18000 to 83535
- to assign a new ID number generated by the engine to the object (i.e. unassign a unique ID), call the function with two arguments and pass -1 for the flag argument
> void sfall_func5("draw_image", string/int pathFile/artId, int frame, int x, int y, bool noTransparent)
> void sfall_func6("draw_image_scaled", string/int pathFile/artId, int frame, int x, int y, int width, int height)
> void sfall_func5("draw_image", string/int artFile/artId, int frame, int x, int y, bool noTransparent)
> void sfall_func6("draw_image_scaled", string/int artFile/artId, int frame, int x, int y, int width, int height)
- displays the specified PCX or FRM image in the active window created by vanilla CreateWin or sfall's create_win script function
- pathFile/artId: path to the PCX/FRM file (e.g. "art\\inven\\5mmap.frm"), or its FRM ID number (e.g. 0x7000026, see specification of the FID format)
- artFile/artId: path to the PCX/FRM file (e.g. "art\\inven\\5mmap.frm"), or its FRM ID number (e.g. 0x7000026, see specification of the FID format)
optional arguments:
- frame: frame number, the first frame starts from zero
- x/y: offset relative to the top-left corner of the window
- width/height: image size, used to scale the image when displaying it. Pass -1 to either width or height to keep the aspect ratio when scaling
- noTransparent: pass true to display an image without transparent background
- width/height: the new width/height to scale the image to. Pass -1 to either width or height to keep the aspect ratio when scaling
- noTransparent: pass True to display an image without transparent background
- NOTE: to omit optional arguments starting from the right, call the functions with different sfall_funcX (e.g. sfall_func4("draw_image", pathFile, frame, x, y))
- if draw_image_scaled is called without x/y/width/height arguments, the image will be scaled to fit the window without transparent background
@@ -731,7 +732,7 @@ optional argument:
- message: the text in the dialog box. Use the \n control character to move text to a new line (example: "Hello\nWorld!")
optional arguments:
- flags: mode flags (see MSGBOX_* constants in define_extra.h). Pass -1 to skip setting the flags (default flags are NORMAL and YESNO)
- color1/2: the color index in Fallout palette. color1 sets the text color for the first line, and color2 for all subsequent lines of text (default color is 145)
- color1/color2: the color index in Fallout palette. color1 sets the text color for the first line, and color2 for all subsequent lines of text (default color is 145)
> int sfall_func1("get_stat_min", stat)
> int sfall_func1("get_stat_max", stat)
@@ -740,6 +741,20 @@ optional arguments:
- returns the maximum or minimum set value of the specified stat (see set_stat_max/min functions)
- who: 0 (false) or omitting the argument - returns the value of the player, 1 (true) - returns the value set for other critters
> int sfall_func4("interface_art_draw", int winType, string/int artFile/artId, int x, int y)
> int sfall_func5("interface_art_draw", int winType, string/int artFile/artId, int x, int y, int frame)
> int sfall_func6("interface_art_draw", int winType, string/int artFile/artId, int x, int y, int frame, array param)
- draws the specified PCX or FRM image in the game interface window, returns -1 in case of any error
- winType: the type number of the interface window (see WINTYPE_* constants in sfall.h)
this also takes the value of the flag (0x10000) to prevent immediate redrawing of the interface window
- artFile/artId: path to the PCX/FRM file (e.g. "art\\inven\\5mmap.frm"), or its FRM ID number (e.g. 0x7000026, see specification of the FID format)
- x/y: offset relative to the top-left corner of the window
optional arguments:
- frame: frame number, the first frame starts from zero
- param: an array which specifies additional parameters:
index 0 - the direction of multi-directional FRM
index 1/index 2 - the new width/height to scale the image to. Pass -1 to width or height to use the original image size
------------------------
------ MORE INFO -------
------------------------
+2 -2
View File
@@ -481,9 +481,9 @@ void RedrawObject(GameObject* obj) {
}
// Redraws all interface windows
void RefreshGNW() {
void RefreshGNW(size_t from) {
*(DWORD*)FO_VAR_doing_refresh_all = 1;
for (size_t i = 0; i < fo::var::num_windows; i++) {
for (size_t i = from; i < fo::var::num_windows; i++) {
func::GNW_win_refresh(fo::var::window[i], &fo::var::scr_size, 0);
}
*(DWORD*)FO_VAR_doing_refresh_all = 0;
+1 -1
View File
@@ -133,7 +133,7 @@ DWORD GetMaxCharWidth();
void RedrawObject(GameObject* obj);
// Redraws all interface windows
void RefreshGNW();
void RefreshGNW(size_t from);
UnlistedFrm *LoadUnlistedFrm(char *frmName, unsigned int folderRef);
+2 -1
View File
@@ -196,6 +196,7 @@ static void WindowInit() {
ScriptShaders::LoadGlobalShader();
}
// pixel size for the current game resolution
const float* Graphics::rcpresGet() {
return rcpres;
}
@@ -770,7 +771,7 @@ public:
if (d3d9Device->TestCooperativeLevel() == D3DERR_DEVICENOTRESET) {
ResetDevice(false);
DeviceLost = false;
fo::RefreshGNW();
fo::RefreshGNW(0);
}
return !DeviceLost;
}
+1 -4
View File
@@ -46,11 +46,8 @@ enum WinNameType {
EscMenu = 7, // escape menu
Automap = 8,
// TODO
IntfaceUse,
IntfaceLoot,
DialogView,
DialogPanel,
BarterPanel,
MemberPanel,
};
@@ -58,7 +55,7 @@ fo::Window* Interface::GetWindow(long winType) {
long winID = 0;
switch (winType) {
case WinNameType::Inventory:
if (GetLoopFlags() & INVENTORY) winID = fo::var::i_wid;
if (GetLoopFlags() & (INVENTORY | INTFACEUSE | INTFACELOOT | BARTER)) winID = fo::var::i_wid;
break;
case WinNameType::Dialog:
if (GetLoopFlags() & DIALOG) winID = fo::var::dialogueBackWindow;
+1 -1
View File
@@ -216,7 +216,7 @@ static void StopMovie() {
aviPlayState = AviState::Stop;
Graphics::SetMovieTexture(false);
movieInterface.pControl->Stop();
if (*(DWORD*)FO_VAR_subtitles == 0) fo::RefreshGNW(); // Note: it is only necessary when in the game
if (*(DWORD*)FO_VAR_subtitles == 0) fo::RefreshGNW(0); // Note: it is only necessary when in the game
}
DWORD FreeMovie(sDSTexture* movie) {
+11 -2
View File
@@ -539,8 +539,12 @@ void SetArray(DWORD id, const ScriptValue& key, const ScriptValue& val, bool all
}
int LenArray(DWORD id) {
if (arrays.find(id) == arrays.end()) return -1;
return arrays[id].size();
array_itr it = arrays.find(id);
return (it != arrays.end()) ? it->second.size() : -1;
}
bool ArrayExist(DWORD id) {
return (arrays.find(id) != arrays.end());
}
template <class T>
@@ -746,5 +750,10 @@ long StackArray(const ScriptValue& key, const ScriptValue& val) {
return 0;
}
sArrayVar* GetRawArray(DWORD id) {
array_itr it = arrays.find(id);
return (it != arrays.end()) ? &it->second : nullptr;
}
}
}
+4
View File
@@ -185,6 +185,8 @@ void SetArray(DWORD id, const ScriptValue& key, const ScriptValue& val, bool all
// number of elements in list or pairs in map
int LenArray(DWORD id);
bool ArrayExist(DWORD id);
// change array size (only works with list)
long ResizeArray(DWORD id, int newlen);
@@ -203,5 +205,7 @@ void SaveArray(const ScriptValue& key, DWORD id);
// special function that powers array expressions
long StackArray(const ScriptValue& key, const ScriptValue& val);
sArrayVar* GetRawArray(DWORD id);
}
}
+74 -2
View File
@@ -24,6 +24,7 @@
#include "..\..\LoadGameHook.h"
#include "..\..\ScriptExtender.h"
#include "..\..\Interface.h"
#include "..\Arrays.h"
#include "..\OpcodeContext.h"
#include "..\..\HookScripts\InventoryHs.h"
@@ -265,7 +266,11 @@ void op_is_iface_tag_active(OpcodeContext &ctx) {
}
void mf_intface_redraw(OpcodeContext& ctx) {
fo::func::intface_redraw();
if (ctx.arg(0).rawValue() == 0) {
fo::func::intface_redraw();
} else {
fo::func::RefreshGNW(1); // redraw all interfaces
}
}
void mf_intface_show(OpcodeContext& ctx) {
@@ -458,7 +463,7 @@ static long GetArtFIDFile(long fid, const char* &file) {
file = fo::func::art_get_name(_fid); // .frm
if (_fid >> 24 == fo::OBJ_TYPE_CRITTER) {
direction = (fid >> 28);
if (direction && !fo::func::db_access(file)) {
if (direction > 0 && !fo::func::db_access(file)) {
file = fo::func::art_get_name(fid); // .fr#
}
}
@@ -557,6 +562,73 @@ void mf_draw_image_scaled(OpcodeContext& ctx) {
ctx.setReturn(DrawImage(ctx, true));
}
static long InterfaceDrawImage(OpcodeContext& ctx, fo::Window* interfaceWin) {
const char* file = nullptr;
bool useShift = false;
long direction = -1, w = -1, h = -1;
if (ctx.arg(1).isInt()) { // art id
long fid = ctx.arg(1).rawValue();
if (fid == -1) return -1;
useShift = (((fid & 0xF000000) >> 24) == fo::OBJ_TYPE_CRITTER);
direction = GetArtFIDFile(fid, file);
} else {
file = ctx.arg(1).strValue(); // path to frm/pcx file
}
if (ctx.numArgs() > 5) { // array params
sArrayVar* sArray = GetRawArray(ctx.arg(5).rawValue());
if (sArray) {
if (direction < 0) direction = sArray->val[0].intVal;
int size = sArray->size();
if (size > 1) w = sArray->val[1].intVal;
if (size > 2) h = sArray->val[2].intVal;
}
}
long frame = ctx.arg(4).rawValue();
fo::FrmFrameData* framePtr;
fo::FrmFile* frmPtr = LoadArtFile(file, frame, direction, framePtr);
if (frmPtr == nullptr) {
ctx.printOpcodeError("%s() - cannot open the file: %s", ctx.getMetaruleName(), file);
return -1;
}
int x = ctx.arg(2).rawValue();
int y = ctx.arg(3).rawValue();
if (useShift && direction >= 0) {
x += frmPtr->xshift[direction];
y += frmPtr->yshift[direction];
}
if (x < 0) x = 0;
if (y < 0) y = 0;
int width = (w >= 0) ? w : framePtr->width;
int height = (h >= 0) ? h : framePtr->height;
fo::func::trans_cscale(framePtr->data, framePtr->width, framePtr->height, framePtr->width,
interfaceWin->surface + (y * interfaceWin->width) + x, width, height, interfaceWin->width
);
if (!(ctx.arg(0).rawValue() & 0x10000)) {
fo::func::GNW_win_refresh(interfaceWin, &interfaceWin->rect, 0);
}
fo::func::mem_free(frmPtr);
return 1;
}
void mf_interface_art_draw(OpcodeContext& ctx) {
long result = -1;
fo::Window* win = Interface::GetWindow(ctx.arg(0).rawValue() & 0xFF);
if (win && (int)win != -1) {
result = InterfaceDrawImage(ctx, win);
} else {
ctx.printOpcodeError("%s() - the game interface window is not created or invalid value for the interface.", ctx.getMetaruleName());
}
ctx.setReturn(result);
}
void mf_unwield_slot(OpcodeContext& ctx) {
fo::InvenType slot = static_cast<fo::InvenType>(ctx.arg(1).rawValue());
if (slot < fo::INVEN_TYPE_WORN || slot > fo::INVEN_TYPE_LEFT_HAND) {
@@ -111,6 +111,8 @@ void mf_draw_image(OpcodeContext&);
void mf_draw_image_scaled(OpcodeContext&);
void mf_interface_art_draw(OpcodeContext&);
void mf_unwield_slot(OpcodeContext&);
void mf_get_window_attribute(OpcodeContext&);
@@ -100,9 +100,10 @@ static const SfallMetarule metarules[] = {
{"has_fake_perk_npc", mf_has_fake_perk_npc, 2, 2, 0, {ARG_OBJECT, ARG_STRING}},
{"has_fake_trait_npc", mf_has_fake_trait_npc, 2, 2, 0, {ARG_OBJECT, ARG_STRING}},
{"hide_window", mf_hide_window, 0, 1, -1, {ARG_STRING}},
{"interface_art_draw", mf_interface_art_draw, 4, 6, -1, {ARG_INT, ARG_INTSTR, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
{"intface_hide", mf_intface_hide, 0, 0},
{"intface_is_hidden", mf_intface_is_hidden, 0, 0},
{"intface_redraw", mf_intface_redraw, 0, 0},
{"intface_redraw", mf_intface_redraw, 0, 1},
{"intface_show", mf_intface_show, 0, 0},
{"inventory_redraw", mf_inventory_redraw, 0, 1, -1, {ARG_INT}},
{"item_make_explosive", mf_item_make_explosive, 3, 4, -1, {ARG_INT, ARG_INT, ARG_INT, ARG_INT}},