mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Fixed broken Print() script function
Fixed the background image of the character portrait on inv/char screens. Renamed "print_text" to "interface_print".
This commit is contained in:
@@ -329,8 +329,10 @@
|
||||
#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_art_draw_frame(winID, artID, x, y, frame) sfall_func5("interface_art_draw", winID, artID, x, y, frame)
|
||||
#define interface_art_draw_ex(winID, artID, x, y, frame, param) sfall_func6("interface_art_draw", winID, artID, x, y, frame, param)
|
||||
#define interface_print(text, winType, x, y, color) sfall_func5("interface_print", text, winType, x, y, color)
|
||||
#define interface_print_width(text, winType, x, y, color, w) sfall_func6("interface_print", text, winType, x, y, color, w)
|
||||
#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")
|
||||
@@ -348,8 +350,6 @@
|
||||
#define obj_under_cursor(onlyCritter, includeDude) sfall_func2("obj_under_cursor", onlyCritter, includeDude)
|
||||
#define objects_in_radius(tile, radius, elev, type) sfall_func4("objects_in_radius", tile, radius, elev, type)
|
||||
#define outlined_object sfall_func0("outlined_object")
|
||||
#define print_text(text, winType, x, y, color) sfall_func5("print_text", text, winType, x, y, color)
|
||||
#define print_text_width(text, winType, x, y, color, w) sfall_func6("print_text", text, winType, x, y, color, w)
|
||||
#define real_dude_obj sfall_func0("real_dude_obj")
|
||||
#define remove_all_timer_events sfall_func0("remove_timer_event")
|
||||
#define remove_timer_event(fixedParam) sfall_func1("remove_timer_event", fixedParam)
|
||||
|
||||
@@ -729,7 +729,7 @@ optional argument:
|
||||
> int sfall_func4("message_box", string message, int flags, int color1, int color2)
|
||||
- creates a dialog box with text and returns the result of pressing the button: 0 - No (Escape), 1 - Yes/Done (Enter)
|
||||
- returns -1 if for some reason the dialog box cannot be created
|
||||
- message: the text in the dialog box. Use the \n control character to move text to a new line (example: "Hello\nWorld!")
|
||||
- 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/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)
|
||||
@@ -744,9 +744,9 @@ optional arguments:
|
||||
> int sfall_func4("interface_art_draw", int winType, string artFile/int artID, int x, int y)
|
||||
> int sfall_func5("interface_art_draw", int winType, string artFile/int artID, int x, int y, int frame)
|
||||
> int sfall_func6("interface_art_draw", int winType, string artFile/int 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
|
||||
- draws the specified PCX or FRM image in the game interface window, returns -1 on 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
|
||||
this also takes the value of the flag (0x1000000) 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:
|
||||
@@ -755,17 +755,19 @@ optional arguments:
|
||||
index 0 - sprite direction for multi-directional FRM
|
||||
index 1/index 2 - the new width/height to scale the image to. Pass -1 to use the original width/height
|
||||
|
||||
> int sfall_func5("print_text", string text, int winType, int x, int y, int color)
|
||||
> int sfall_func6("print_text", string text, int winType, int x, int y, int color, int width)
|
||||
> int sfall_func5("interface_print", string text, int winType, int x, int y, int color)
|
||||
> int sfall_func6("interface_print", string text, int winType, int x, int y, int color, int width)
|
||||
- displays the text in the specified interface window with the current font. Use vanilla SetFont function to set the font
|
||||
- text: the text to be printed. Use the \n control character to move text to a new line (example: "Hello\nWorld!")
|
||||
- returns the count of lines printed, or -1 on any error
|
||||
- text: the text to be printed. Use the '\n' control character to move text to a new line (example: "Hello\nWorld!")
|
||||
- winType: the type number of the interface window (see WINTYPE_* constants in sfall.h)
|
||||
- x/y: offset relative to the top-left corner of the window
|
||||
- color: the color index in Fallout palette. Pass 0 if the text color was previously set by vanilla SetTextColor function
|
||||
it can also take additional flags (via bwor) for displaying text:
|
||||
0x0010000 - adds a shadow to the text, the 'textshadow' compiler constant
|
||||
0x1000000 - prevents immediate redrawing of the interface window, the 'textdirect' compiler constant (works the other way around)
|
||||
0x2000000 - fills the background of the text with black color, the 'textnofill' compiler constant (works the other way around)
|
||||
- width: the maximum width of the text. The text will be wrapped to fit within the specified width
|
||||
- width (optional): the maximum width of the text. The text will be wrapped to fit within the specified width
|
||||
|
||||
------------------------
|
||||
------ MORE INFO -------
|
||||
|
||||
@@ -416,6 +416,10 @@ void AI::init() {
|
||||
dlogr(" Done", DL_INIT);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (iniGetInt("Debugging", "AIBugFixes", 1, ::sfall::ddrawIni) == 0) return;
|
||||
#endif
|
||||
|
||||
// Fix for NPCs not fully reloading a weapon if it has more ammo capacity than a box of ammo
|
||||
HookCalls(item_w_reload_hook, {
|
||||
0x42AF15, // cai_attempt_w_reload_
|
||||
@@ -436,10 +440,6 @@ void AI::init() {
|
||||
MakeCall(0x428EB5, ai_find_attackers_hack_target3);
|
||||
MakeCall(0x428EE5, ai_find_attackers_hack_target4, 1);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (iniGetInt("Debugging", "AIBugFixes", 1, ::sfall::ddrawIni) == 0) return;
|
||||
#endif
|
||||
|
||||
// Tweak for finding new targets for party members
|
||||
// Save the current target in the "target1" variable and find other potential targets
|
||||
MakeCall(0x429074, ai_danger_source_hack_pm_newfind);
|
||||
|
||||
@@ -3243,7 +3243,7 @@ void BugFixes::init()
|
||||
MakeCall(0x456B63, op_obj_can_see_obj_hack);
|
||||
SafeWrite16(0x456B76, 0x23EB); // jmp loc_456B9B (skip unused engine code)
|
||||
|
||||
// Fix broken op_obj_can_hear_obj_ function
|
||||
// Fix broken obj_can_hear_obj function
|
||||
if (GetConfigInt("Misc", "ObjCanHearObjFix", 0)) {
|
||||
dlog("Applying obj_can_hear_obj fix.", DL_INIT);
|
||||
SafeWrite8(0x4583D8, 0x3B); // jz loc_458414
|
||||
@@ -3570,6 +3570,9 @@ void BugFixes::init()
|
||||
// when calculating the hit chance penalty of ranged attacks in determine_to_hit_func_ engine function
|
||||
SafeWriteBatch<BYTE>(0x41, {0x426D46, 0x426D4E}); // edi > ecx (replace target with object critter)
|
||||
SafeWrite8(0x426D48, fo::DAM_DEAD | fo::DAM_KNOCKED_DOWN | fo::DAM_KNOCKED_OUT);
|
||||
|
||||
// Fix broken Print() script function
|
||||
HookCall(0x461AD4, (void*)fo::funcoffs::windowOutput_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -938,6 +938,26 @@ static void __declspec(naked) main_death_scene_hook() {
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) display_body_hook() {
|
||||
static const DWORD display_body_hook_Ret = 0x47098D;
|
||||
__asm {
|
||||
mov ebx, [esp + 0x60 - 0x28 + 8];
|
||||
cmp ebx, 1; // check mode 0 or 1
|
||||
jbe fix;
|
||||
add esp, 8;
|
||||
mov dword ptr [esp + 0x60 - 0x40], 0; // frm_ptr
|
||||
jmp display_body_hook_Ret;
|
||||
fix:
|
||||
dec edx; // USE.FRM
|
||||
mov ecx, 48; // INVBOX.FRM
|
||||
test ebx, ebx;
|
||||
cmovz edx, ecx;
|
||||
xor ebx, ebx;
|
||||
xor ecx, ecx;
|
||||
jmp fo::funcoffs::art_id_;
|
||||
}
|
||||
}
|
||||
|
||||
void Interface::init() {
|
||||
if (GetConfigInt("Interface", "ActionPointsBar", 0)) {
|
||||
ActionPointsBarPatch();
|
||||
@@ -966,6 +986,16 @@ void Interface::init() {
|
||||
if (hrpIsEnabled == false) SafeWrite32(0x48134D, 38 - (640 * 3)); // main_death_scene_ (shift y-offset 2px up, w/o HRP)
|
||||
if (hrpIsEnabled == false || hrpVersionValid) SafeWrite8(0x481345, 4); // main_death_scene_
|
||||
if (hrpVersionValid) SafeWrite8(HRPAddress(0x10011738), 10);
|
||||
|
||||
// Cosmetic fix for the background image of the character portrait on the inventory and character screens
|
||||
HookCall(0x47093C, display_body_hook);
|
||||
BYTE code[11] = {
|
||||
0x8B, 0xD3, // mov edx, ebx
|
||||
0x66, 0x8B, 0x58, 0xF4, // mov bx, [eax - 12] [sizeof(frame)]
|
||||
0x0F, 0xAF, 0xD3, // imul edx, ebx (y * frame width)
|
||||
0x53, 0x90 // push ebx (frame width)
|
||||
};
|
||||
SafeWriteBytes(0x470971, code, 11);
|
||||
}
|
||||
|
||||
void Interface::exit() {
|
||||
|
||||
@@ -599,7 +599,7 @@ static long InterfaceDrawImage(OpcodeContext& ctx, fo::Window* interfaceWin) {
|
||||
interfaceWin->surface + (y * interfaceWin->width) + x, width, height, interfaceWin->width
|
||||
);
|
||||
|
||||
if (!(ctx.arg(0).rawValue() & 0x10000)) {
|
||||
if (!(ctx.arg(0).rawValue() & 0x1000000)) {
|
||||
fo::func::GNW_win_refresh(interfaceWin, &interfaceWin->rect, 0);
|
||||
}
|
||||
fo::func::mem_free(frmPtr);
|
||||
@@ -708,7 +708,7 @@ void mf_get_window_attribute(OpcodeContext& ctx) {
|
||||
ctx.setReturn(result);
|
||||
}
|
||||
|
||||
void mf_print_text(OpcodeContext& ctx) { // same as vanilla PrintRect
|
||||
void mf_interface_print(OpcodeContext& ctx) { // same as vanilla PrintRect
|
||||
fo::Window* win = Interface::GetWindow(ctx.arg(1).rawValue());
|
||||
if (win == nullptr || (int)win == -1) {
|
||||
ctx.printOpcodeError("%s() - the game interface window is not created or invalid value for the interface.", ctx.getMetaruleName());
|
||||
@@ -716,8 +716,12 @@ void mf_print_text(OpcodeContext& ctx) { // same as vanilla PrintRect
|
||||
return;
|
||||
}
|
||||
const char* text = ctx.arg(0).strValue();
|
||||
|
||||
long x = ctx.arg(2).rawValue();
|
||||
if (x < 0) x = 0;
|
||||
long y = ctx.arg(3).rawValue();
|
||||
if (y < 0) y = 0;
|
||||
|
||||
long color = ctx.arg(4).rawValue();
|
||||
long width = ctx.arg(5).rawValue();
|
||||
|
||||
@@ -729,17 +733,19 @@ void mf_print_text(OpcodeContext& ctx) { // same as vanilla PrintRect
|
||||
width = maxWidth;
|
||||
}
|
||||
|
||||
color ^= 0x2000000; // fills background with black color if the flag is set
|
||||
color ^= 0x2000000; // fills background with black color if the flag is set (textnofill)
|
||||
if ((color & 0xFF) == 0) {
|
||||
__asm call fo::funcoffs::windowGetTextColor_; // set from SetTextColor
|
||||
__asm mov byte ptr color, al;
|
||||
}
|
||||
if (color & 0x10000) { // shadow
|
||||
if (color & 0x10000) { // shadow (textshadow)
|
||||
fo::func::windowWrapLineWithSpacing(win->wID, text, width, maxHeight, x, y, 0x201000F, 0, 0);
|
||||
color ^= 0x10000;
|
||||
}
|
||||
ctx.setReturn(fo::func::windowWrapLineWithSpacing(win->wID, text, width, maxHeight, x, y, color, 0, 0));
|
||||
fo::func::GNW_win_refresh(win, &win->rect, 0);
|
||||
ctx.setReturn(fo::func::windowWrapLineWithSpacing(win->wID, text, width, maxHeight, x, y, color, 0, 0)); // returns count of lines printed
|
||||
|
||||
// no redraw (textdirect)
|
||||
if (!(color & 0x1000000)) fo::func::GNW_win_refresh(win, &win->rect, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ void mf_unwield_slot(OpcodeContext&);
|
||||
|
||||
void mf_get_window_attribute(OpcodeContext&);
|
||||
|
||||
void mf_print_text(OpcodeContext& ctx);
|
||||
void mf_interface_print(OpcodeContext&);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,6 +101,7 @@ static const SfallMetarule metarules[] = {
|
||||
{"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}},
|
||||
{"interface_print", mf_interface_print, 5, 6, -1, {ARG_STRING, ARG_INT, 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, 1},
|
||||
@@ -116,7 +117,6 @@ static const SfallMetarule metarules[] = {
|
||||
{"obj_under_cursor", mf_obj_under_cursor, 2, 2, 0, {ARG_INT, ARG_INT}},
|
||||
{"objects_in_radius", mf_objects_in_radius, 3, 4, 0, {ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
{"outlined_object", mf_outlined_object, 0, 0},
|
||||
{"print_text", mf_print_text, 5, 6, -1, {ARG_STRING, ARG_INT, ARG_INT, ARG_INT, ARG_INT, ARG_INT}},
|
||||
{"real_dude_obj", mf_real_dude_obj, 0, 0},
|
||||
{"remove_timer_event", mf_remove_timer_event, 0, 1, -1, {ARG_INT}},
|
||||
{"set_can_rest_on_map", mf_set_rest_on_map, 3, 3, -1, {ARG_INT, ARG_INT, ARG_INT}},
|
||||
|
||||
Reference in New Issue
Block a user