mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Backported the advanced BarBoxes features from 4.x:
* Added BoxBarCount option. * Added "set_iface_tag_text" and "add_iface_tag" script functions. * Now number of simultaneously displayed boxes depends on game res. * Updated documents.
This commit is contained in:
+5
-2
@@ -460,8 +460,11 @@ ScienceOnCritters=0
|
||||
;Default is 166
|
||||
SpeedInventoryPCRotation=166
|
||||
|
||||
;Uncomment to set the text colour of the extra 5 interface boxes
|
||||
;The line must contain 5 digits, each either a 0 for green or 1 for red
|
||||
;Modify the number of the extra interface boxes available to modders. (Default is 5, and the maximum is 95)
|
||||
BoxBarCount=5
|
||||
|
||||
;Uncomment to set the text colour of the extra interface boxes
|
||||
;The line must contain the same number of digits as the value of BoxBarCount, each either a 0 for green or 1 for red
|
||||
;BoxBarColours=00000
|
||||
|
||||
;Set to 1 to fix the bug that caused bonus HtH damage to not be applied correctly.
|
||||
|
||||
@@ -224,6 +224,7 @@
|
||||
#define ADD_PERK_MODE_REMOVE (4) // remove from the list of selectable perks
|
||||
|
||||
// sfall_funcX macros
|
||||
#define add_iface_tag sfall_func0("add_iface_tag")
|
||||
#define add_trait(traitId) sfall_func1("add_trait", traitId)
|
||||
#define art_cache_clear sfall_func0("art_cache_clear")
|
||||
#define attack_is_aimed sfall_func0("attack_is_aimed")
|
||||
@@ -256,6 +257,7 @@
|
||||
#define real_dude_obj sfall_func0("real_dude_obj")
|
||||
#define set_cursor_mode(mode) sfall_func1("set_cursor_mode", mode)
|
||||
#define set_flags(obj, flags) sfall_func2("set_flags", obj, flags)
|
||||
#define set_iface_tag_text(tag, text, color) sfall_func3("set_iface_tag_text", tag, text, color)
|
||||
#define set_ini_setting(setting, value) sfall_func2("set_ini_setting", setting, value)
|
||||
#define set_map_enter_position(tile, elev, rot) sfall_func3("set_map_enter_position", tile, elev, rot)
|
||||
#define set_object_data(obj, offset, value) sfall_func3("set_object_data", obj, offset, value)
|
||||
|
||||
@@ -50,7 +50,7 @@ has_fake_trait and has_fake_perk return the number of levels the player has of t
|
||||
|
||||
perk_add_mode, set_selectable_perk, set_perkbox_title, hide_real_perks, show_real_perks and clear_selectable_perks control the behaviour of the select a perk box. set_selectable_perk can be used to add additional items by setting the 'active' parameter to 1, and to remove them again by setting it to 0. set_perkbox_title can be used to change the title of the box, or by using "" it will be set back to the default. hide and show_real_perks can be used to prevent the dialog from displaying any of the original 119 perks. perk_add_mode modifies what happens when a fake perk is selected from the perks dialog. It is treated as a set of flags - if bit 1 is set then it is added to the player's traits, if bit 2 is set it is added to the player's perks, and if bit 3 is set it is removed from the list of selectable perks. The default is 0x2. clear_selectable_perks restores the dialog to its default state.
|
||||
|
||||
show_iface_tag, hide_iface_tag and is_iface_tag_active relate to the boxes that appear above the interface such as SNEAK and LEVEL. You can use 3 for LEVEL and 4 for ADDICT, or the range from 5 to 9 for custom boxes. Remember to add your messages to intrface.msg and set up the font colours in ddraw.ini if you're going to use custom boxes. Starting from sfall 3.8.12, is_iface_tag_active can also be used to check 0 for SNEAK, 1 for POISONED, and 2 for RADIATED.
|
||||
show_iface_tag, hide_iface_tag and is_iface_tag_active relate to the boxes that appear above the interface such as SNEAK and LEVEL. You can use 3 for LEVEL and 4 for ADDICT, or the range from 5 to (4 + the value of BoxBarCount in ddraw.ini) for custom boxes. Remember to add your messages to intrface.msg and set up the font colours in ddraw.ini if you're going to use custom boxes. Starting from sfall 3.8.12, is_iface_tag_active can also be used to check 0 for SNEAK, 1 for POISONED, and 2 for RADIATED.
|
||||
|
||||
get/set_bodypart_hit_modifier alter the hit percentage modifiers for aiming at specific bodyparts. Valid bodypart id's are from 0 to 8. Changes are not saved, and will reset to the defaults (or to the values specified in ddraw.ini if they exist) at each reload.
|
||||
|
||||
@@ -462,6 +462,16 @@ Some utility/math functions are available:
|
||||
> int sfall_func0("attack_is_aimed")
|
||||
- returns 1 if the aimed attack mode is selected, 0 otherwise
|
||||
|
||||
> void sfall_func3("set_iface_tag_text", int tag, string text, int color)
|
||||
- sets the text messages and colors for custom notification boxes to the interface without the need to add messages to intrface.msg and set up the font colors in ddraw.ini
|
||||
- tag value is the same as used in show_iface_tag, hide_iface_tag, and is_iface_tag_active. The valid range is from 5 to (4 + the value of BoxBarCount in ddraw.ini) or the number of the last custom box added using the add_ifaca_tag function
|
||||
- The text is limited to 19 characters
|
||||
- available colors: 0 - green, 1 - red, 2 - white, 3 - yellow, 4 - dark yellow, 5 - blue, 6 - purple, 7 - dull pink
|
||||
|
||||
> int sfall_func0("add_iface_tag")
|
||||
- adds one custom box to the current boxes, and returns the number of the added tag (-1 if the tags limit is exceeded)
|
||||
- The maximum number of boxes is limited to 126 tags
|
||||
|
||||
> void sfall_func1("inventory_redraw", int invSide)
|
||||
- redraws inventory list in the inventory/use inventory item on/loot/barter screens
|
||||
- invSide specifies which side needs to be redrawn: 0 - the player, 1 - target (container/NPC in loot/barter screens)
|
||||
|
||||
+308
-46
@@ -17,88 +17,350 @@
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
|
||||
#include "BarBoxes.h"
|
||||
#include "FalloutEngine.h"
|
||||
#include "Graphics.h"
|
||||
|
||||
struct sBox {
|
||||
static int boxCount; // current box count
|
||||
static int totalBoxCount, actualBoxCount; // total boxes and w/o vanilla
|
||||
static int initCount = 5; // init config counter (5 - vanilla box)
|
||||
static int sizeBox, setBoxIndex = 5;
|
||||
|
||||
static long newBoxSlot[16];
|
||||
static long maxSlots = 6; // maximum number of slots for the current game window resolution
|
||||
static long ifaceWidth;
|
||||
|
||||
#define sSize (12)
|
||||
static struct sBox {
|
||||
DWORD msg;
|
||||
DWORD colour;
|
||||
void* mem;
|
||||
};
|
||||
} *boxes;
|
||||
|
||||
static sBox boxes[10] = {0};
|
||||
static DWORD boxesEnabled[5] = {0};
|
||||
#define tSize (24)
|
||||
static struct tBox {
|
||||
bool hasText;
|
||||
char color;
|
||||
char cfgColor;
|
||||
bool isActive;
|
||||
char text[tSize - 4];
|
||||
} *boxText;
|
||||
|
||||
static bool setCustomBoxText;
|
||||
|
||||
static const DWORD bboxMemAddr[] = {
|
||||
0x461266, 0x4612AC, 0x461374, 0x4613E8, 0x461479, 0x46148C, 0x4616BB,
|
||||
};
|
||||
|
||||
static const DWORD bboxSlotAddr[] = {
|
||||
0x4616F7, 0x46170F, 0x461736, 0x4616B1, 0x46151D, 0x4615B3
|
||||
};
|
||||
|
||||
static const DWORD DisplayBoxesRet1 = 0x4615A8;
|
||||
static const DWORD DisplayBoxesRet2 = 0x4615BE;
|
||||
static void __declspec(naked) DisplayBoxesHook() {
|
||||
static void __declspec(naked) DisplayBoxesHack() {
|
||||
__asm {
|
||||
mov ebx, 0;
|
||||
mov edx, [boxText];
|
||||
xor ebx, ebx;
|
||||
start:
|
||||
mov eax, boxesEnabled[ebx * 4];
|
||||
test eax, eax;
|
||||
jz next;
|
||||
lea eax, [ebx + 5];
|
||||
imul eax, ebx, tSize;
|
||||
mov al, byte ptr [edx][eax + 3]; // .isActive
|
||||
test al, al;
|
||||
jz next;
|
||||
lea eax, [ebx + 5]; // index box
|
||||
call add_bar_box_;
|
||||
add esi, eax;
|
||||
add esi, eax;
|
||||
next:
|
||||
inc ebx;
|
||||
cmp ebx, 5;
|
||||
jne start;
|
||||
cmp esi, 1;
|
||||
jle fail;
|
||||
jmp DisplayBoxesRet1;
|
||||
inc ebx;
|
||||
cmp ebx, actualBoxCount;
|
||||
jne start;
|
||||
// engine code
|
||||
cmp esi, 1;
|
||||
jle fail;
|
||||
jmp DisplayBoxesRet1;
|
||||
fail:
|
||||
jmp DisplayBoxesRet2;
|
||||
jmp DisplayBoxesRet2;
|
||||
}
|
||||
}
|
||||
|
||||
static void __declspec(naked) BarBoxesTextHack() {
|
||||
__asm {
|
||||
push ecx; // ecx = BoxIndex
|
||||
sub ecx, 5; // subtract vanilla boxes
|
||||
imul ecx, tSize;
|
||||
mov esi, [boxText]; // boxText addr
|
||||
cmp byte ptr [esi][ecx], 1; // .hasText
|
||||
je customText;
|
||||
add esp, 4;
|
||||
jmp getmsg_;
|
||||
customText:
|
||||
// get color
|
||||
movzx ebx, byte ptr [esi][ecx + 1]; // .color
|
||||
// set text
|
||||
lea eax, [esi + ecx + 4]; // .text
|
||||
// set color
|
||||
pop ecx; // restore BoxIndex
|
||||
imul ecx, sSize;
|
||||
mov esi, [boxes]; // boxes addr
|
||||
cmp dword ptr [esi][ecx + 4], 2; // .colour
|
||||
jb skip;
|
||||
mov [esp + 0x440 - 0x20], ebx; // set to Color
|
||||
skip:
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
static const DWORD SetIndexBoxRet = 0x4612E8;
|
||||
static void __declspec(naked) BarBoxesIndexHack() {
|
||||
__asm {
|
||||
mov eax, ds:[0x4612E2]; // fontnum
|
||||
mov ecx, setBoxIndex; // start index
|
||||
mov edx, ecx;
|
||||
jmp SetIndexBoxRet;
|
||||
}
|
||||
}
|
||||
|
||||
static const DWORD SizeLoopBoxRet = 0x461477;
|
||||
static const DWORD ExitLoopBoxRet = 0x461498;
|
||||
static void __declspec(naked) BarBoxesSizeHack() {
|
||||
__asm {
|
||||
cmp edx, sizeBox;
|
||||
jz exitLoop;
|
||||
jmp SizeLoopBoxRet;
|
||||
exitLoop:
|
||||
jmp ExitLoopBoxRet;
|
||||
}
|
||||
}
|
||||
|
||||
static void ReconstructBarBoxes(int count) {
|
||||
SafeWrite8(0x46140B, count);
|
||||
__asm {
|
||||
//call refresh_box_bar_win_;
|
||||
call reset_box_bar_win_;
|
||||
call construct_box_bar_win_;
|
||||
}
|
||||
}
|
||||
|
||||
//static BYTE restoreData[] = {0x31, 0xD2, 0x89, 0x94, 0x24}; // xor edx, edx; mov...
|
||||
void ResetBoxes() {
|
||||
for (int i = 0; i < actualBoxCount; i++) {
|
||||
boxText[i].isActive = false;
|
||||
boxText[i].hasText = false;
|
||||
boxes[i + 5].colour = boxText[i].cfgColor;
|
||||
}
|
||||
if (setBoxIndex == 5) return;
|
||||
|
||||
// Restore boxes
|
||||
setBoxIndex = 5; // set start
|
||||
//SafeWrite32(0x461343, 0x00023D05); // call getmsg_
|
||||
ReconstructBarBoxes(totalBoxCount);
|
||||
//SafeWriteBytes(0x461243, restoreData, 5);
|
||||
}
|
||||
|
||||
void ResetBoxCount() {
|
||||
if (initCount != totalBoxCount) {
|
||||
boxCount = initCount;
|
||||
actualBoxCount = initCount - 5;
|
||||
}
|
||||
}
|
||||
|
||||
int __stdcall BarBoxes_MaxBox() {
|
||||
return boxCount - 1;
|
||||
}
|
||||
|
||||
void __stdcall BarBoxes_SetText(int box, const char* text, DWORD color) {
|
||||
setBoxIndex = box;
|
||||
boxes[box].colour = color;
|
||||
box -= 5;
|
||||
boxText[box].hasText = true;
|
||||
strncpy_s(boxText[box].text, text, _TRUNCATE);
|
||||
|
||||
char clr;
|
||||
switch (color) {
|
||||
case 2:
|
||||
clr = *ptr_WhiteColor;
|
||||
break;
|
||||
case 3:
|
||||
clr = *ptr_YellowColor;
|
||||
break;
|
||||
case 4:
|
||||
clr = *ptr_PeanutButter;
|
||||
break;
|
||||
case 5:
|
||||
clr = *ptr_BlueColor;
|
||||
break;
|
||||
case 6:
|
||||
clr = *ptr_GoodColor;
|
||||
break;
|
||||
case 7:
|
||||
clr = *(BYTE*)_DullPinkColor;
|
||||
break;
|
||||
default:
|
||||
clr = *ptr_GreenColor;
|
||||
}
|
||||
boxText[box].color = clr;
|
||||
|
||||
if (!setCustomBoxText) {
|
||||
setCustomBoxText = true;
|
||||
MakeCall(0x461342, BarBoxesTextHack); // construct_box_bar_win_
|
||||
MakeJump(0x461243, BarBoxesIndexHack); // construct_box_bar_win_
|
||||
}
|
||||
ReconstructBarBoxes(setBoxIndex + 1);
|
||||
}
|
||||
|
||||
static void SetEngine(int count) {
|
||||
for (int i = 0; i < sizeof(bboxMemAddr) / 4; i++) {
|
||||
SafeWrite32(bboxMemAddr[i], (DWORD)boxes + 8); //.mem
|
||||
}
|
||||
SafeWrite32(0x4612FE, (DWORD)boxes + 4); //.colour
|
||||
SafeWrite32(0x46133C, (DWORD)boxes); //.msg
|
||||
|
||||
sizeBox = sizeof(sBox) * count;
|
||||
|
||||
static bool onlyOnce = false;
|
||||
if (onlyOnce) return;
|
||||
|
||||
if (count > 10) {
|
||||
MakeJump(0x461493, BarBoxesSizeHack); // deconstruct_box_bar_win_
|
||||
onlyOnce = true;
|
||||
} else {
|
||||
SafeWrite8(0x461495, sizeBox);
|
||||
}
|
||||
}
|
||||
|
||||
long SetBoxMaxSlots() {
|
||||
long scrWidth = Gfx_GetGameWidthRes();
|
||||
|
||||
int slots = scrWidth / 127;
|
||||
if (++slots > 16) {
|
||||
slots = 16;
|
||||
} else if (slots < 6) {
|
||||
slots = 6;
|
||||
}
|
||||
if (slots != maxSlots) {
|
||||
maxSlots = slots;
|
||||
SafeWrite8(0x461513, slots); // 6
|
||||
SafeWrite8(0x461718, --slots); // 5
|
||||
SafeWrite8(0x46170A, slots * 4);
|
||||
}
|
||||
return scrWidth;
|
||||
}
|
||||
|
||||
static long __fastcall GetOffsetX(int width) {
|
||||
int x_offset = 0;
|
||||
if (SetBoxMaxSlots() > 640 && width > ifaceWidth) {
|
||||
x_offset -= (width - ifaceWidth) / 2;
|
||||
}
|
||||
return x_offset;
|
||||
}
|
||||
|
||||
static void __declspec(naked) refresh_box_bar_win_hack() {
|
||||
__asm {
|
||||
push ecx;
|
||||
mov ecx, ebx; // _barWindow width
|
||||
call GetOffsetX; // x position
|
||||
pop ecx;
|
||||
mov edx, 358; // y position
|
||||
retn;
|
||||
}
|
||||
}
|
||||
|
||||
void BarBoxesInit() {
|
||||
memcpy(boxes, (void*)0x518FE8, 12 * 5);
|
||||
for (int i = 5; i < 10; i++) {
|
||||
initCount += GetConfigInt("Misc", "BoxBarCount", 5);
|
||||
if (initCount < 5) initCount = 5; // exclude the influence of negative values from the config
|
||||
if (initCount > 100) initCount = 100;
|
||||
|
||||
actualBoxCount = initCount - 5;
|
||||
|
||||
boxes = new sBox[initCount]();
|
||||
boxText = new tBox[actualBoxCount]();
|
||||
|
||||
memcpy(boxes, (void*)0x518FE8, sSize * 5);
|
||||
for (int i = 5; i < initCount; i++) {
|
||||
boxes[i].msg = 100 + i;
|
||||
}
|
||||
|
||||
std::string boxBarColors = GetConfigString("Misc", "BoxBarColours", "", 6);
|
||||
if (boxBarColors.size() == 5) {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (boxBarColors[i] == '1') {
|
||||
boxes[i + 5].colour = 1; // red color
|
||||
}
|
||||
std::string boxBarColors = GetConfigString("Misc", "BoxBarColours", "", actualBoxCount + 1);
|
||||
for (size_t i = 0; i < boxBarColors.size(); i++) {
|
||||
if (boxBarColors[i] == '1') {
|
||||
boxes[i + 5].colour = 1; // red color
|
||||
boxText[i].cfgColor = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeof(bboxMemAddr) / 4; i++) {
|
||||
SafeWrite32(bboxMemAddr[i], (DWORD)boxes + 8); //.mem
|
||||
SetEngine(initCount);
|
||||
SafeWrite8(0x46127C, initCount); // for only init
|
||||
SafeWrite8(0x46140B, initCount);
|
||||
|
||||
MakeJump(0x4615A3, DisplayBoxesHack);
|
||||
|
||||
totalBoxCount = boxCount = initCount;
|
||||
|
||||
MakeCall(0x4615FA, refresh_box_bar_win_hack);
|
||||
for (int i = 0; i < sizeof(bboxSlotAddr) / 4; i++) {
|
||||
SafeWrite32(bboxSlotAddr[i], (DWORD)newBoxSlot); // _bboxslot
|
||||
}
|
||||
SafeWrite32(0x4612FE, (DWORD)boxes + 4); //.colour
|
||||
SafeWrite32(0x46133C, (DWORD)boxes + 0); //.msg
|
||||
|
||||
SafeWrite8(0x46127C, 10);
|
||||
SafeWrite8(0x46140B, 10);
|
||||
SafeWrite8(0x461495, 0x78);
|
||||
|
||||
MakeJump(0x4615A3, DisplayBoxesHook);
|
||||
ifaceWidth = iniGetInt("IFACE", "IFACE_BAR_WIDTH", 640, ".\\f2_res.ini");
|
||||
if (ifaceWidth < 640) ifaceWidth = 640;
|
||||
}
|
||||
|
||||
bool GetBox(int i) {
|
||||
if (i < 5 || i > 9) return false;
|
||||
return (boxesEnabled[i - 5] != 0);
|
||||
long __stdcall AddExtraBox() {
|
||||
if (boxCount < totalBoxCount) {
|
||||
actualBoxCount++;
|
||||
boxCount++;
|
||||
return BarBoxes_MaxBox(); // just return the number of the previously added box
|
||||
}
|
||||
if (totalBoxCount > 126) return -1; // limit is exceeded
|
||||
|
||||
void* data;
|
||||
__asm {
|
||||
mov eax, 2730;
|
||||
call mem_malloc_;
|
||||
mov data, eax;
|
||||
}
|
||||
if (data == nullptr) return -1; // error on memory allocation
|
||||
memcpy(data, boxes[1].mem, 2730); // copy image box to a new allocated memory
|
||||
|
||||
sBox* boxes_new = new sBox[totalBoxCount + 1];
|
||||
memcpy(boxes_new, boxes, sizeof(sBox) * totalBoxCount);
|
||||
delete[] boxes;
|
||||
boxes = boxes_new;
|
||||
|
||||
boxes[totalBoxCount].mem = data;
|
||||
boxes[totalBoxCount].msg = 100; // set default text for added box
|
||||
boxes[totalBoxCount].colour = 0;
|
||||
boxCount = ++totalBoxCount;
|
||||
|
||||
tBox* boxText_new = new tBox[actualBoxCount + 1];
|
||||
memcpy(boxText_new, boxText, sizeof(tBox) * actualBoxCount);
|
||||
delete[] boxText;
|
||||
boxText = boxText_new;
|
||||
|
||||
memset((void*)&boxText[actualBoxCount], 0, sizeof(tBox));
|
||||
actualBoxCount++;
|
||||
|
||||
SetEngine(totalBoxCount);
|
||||
return BarBoxes_MaxBox(); // current number of added box
|
||||
}
|
||||
|
||||
void AddBox(int i) {
|
||||
if (i < 5 || i > 9) return;
|
||||
boxesEnabled[i - 5] = 1;
|
||||
bool __stdcall GetBox(int i) {
|
||||
if (i < 5 || i > BarBoxes_MaxBox()) return false;
|
||||
return boxText[i - 5].isActive;
|
||||
}
|
||||
|
||||
void __stdcall AddBox(int i) {
|
||||
if (i < 5 || i > BarBoxes_MaxBox()) return;
|
||||
boxText[i - 5].isActive = true;
|
||||
__asm call refresh_box_bar_win_;
|
||||
}
|
||||
|
||||
void RemoveBox(int i) {
|
||||
if (i < 5 || i > 9) return;
|
||||
boxesEnabled[i - 5] = 0;
|
||||
void __stdcall RemoveBox(int i) {
|
||||
if (i < 5 || i > BarBoxes_MaxBox()) return;
|
||||
boxText[i - 5].isActive = false;
|
||||
__asm call refresh_box_bar_win_;
|
||||
}
|
||||
|
||||
void BarBoxesExit() {
|
||||
delete[] boxes;
|
||||
delete[] boxText;
|
||||
}
|
||||
|
||||
+14
-3
@@ -1,4 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
void BarBoxesInit();
|
||||
bool GetBox(int i);
|
||||
void AddBox(int i);
|
||||
void RemoveBox(int i);
|
||||
void BarBoxesExit();
|
||||
void ResetBoxes();
|
||||
void ResetBoxCount();
|
||||
long SetBoxMaxSlots();
|
||||
|
||||
int __stdcall BarBoxes_MaxBox();
|
||||
void __stdcall BarBoxes_SetText(int box, const char* text, DWORD color);
|
||||
|
||||
bool __stdcall GetBox(int i);
|
||||
void __stdcall AddBox(int i);
|
||||
void __stdcall RemoveBox(int i);
|
||||
long __stdcall AddExtraBox();
|
||||
|
||||
@@ -33,6 +33,7 @@ DWORD* ptr_art_vault_guy_num = reinterpret_cast<DWORD*>(_art_vault_guy_
|
||||
DWORD* ptr_art_vault_person_nums = reinterpret_cast<DWORD*>(_art_vault_person_nums);
|
||||
DWORD* ptr_bckgnd = reinterpret_cast<DWORD*>(_bckgnd);
|
||||
DWORD* ptr_black_palette = reinterpret_cast<DWORD*>(_black_palette);
|
||||
BYTE* ptr_BlueColor = reinterpret_cast<BYTE*>(_BlueColor);
|
||||
DWORD* ptr_bottom_line = reinterpret_cast<DWORD*>(_bottom_line);
|
||||
DWORD* ptr_btable = reinterpret_cast<DWORD*>(_btable);
|
||||
DWORD* ptr_btncnt = reinterpret_cast<DWORD*>(_btncnt);
|
||||
@@ -77,6 +78,7 @@ DWORD* ptr_gIsSteal = reinterpret_cast<DWORD*>(_gIsSteal);
|
||||
DWORD* ptr_glblmode = reinterpret_cast<DWORD*>(_glblmode);
|
||||
long* ptr_gmouse_current_cursor = reinterpret_cast<long*>(_gmouse_current_cursor);
|
||||
DWORD* ptr_gmovie_played_list = reinterpret_cast<DWORD*>(_gmovie_played_list);
|
||||
BYTE* ptr_GoodColor = reinterpret_cast<BYTE*>(_GoodColor);
|
||||
BYTE* ptr_GreenColor = reinterpret_cast<BYTE*>(_GreenColor);
|
||||
DWORD* ptr_gsound_initialized = reinterpret_cast<DWORD*>(_gsound_initialized);
|
||||
long* ptr_hit_location_penalty = reinterpret_cast<long*>(_hit_location_penalty);
|
||||
@@ -208,6 +210,7 @@ DWORD* ptr_title_font = reinterpret_cast<DWORD*>(_title_font);
|
||||
DWORD* ptr_trait_data = reinterpret_cast<DWORD*>(_trait_data);
|
||||
DWORD* ptr_view_page = reinterpret_cast<DWORD*>(_view_page);
|
||||
DWORD* ptr_wd_obj = reinterpret_cast<DWORD*>(_wd_obj);
|
||||
BYTE* ptr_WhiteColor = reinterpret_cast<BYTE*>(_WhiteColor);
|
||||
DWORD* ptr_wmAreaInfoList = reinterpret_cast<DWORD*>(_wmAreaInfoList);
|
||||
DWORD* ptr_wmLastRndTime = reinterpret_cast<DWORD*>(_wmLastRndTime);
|
||||
DWORD* ptr_wmWorldOffsetX = reinterpret_cast<DWORD*>(_wmWorldOffsetX);
|
||||
@@ -282,6 +285,7 @@ const DWORD combat_turn_run_ = 0x4227DC;
|
||||
const DWORD compute_damage_ = 0x4247B8;
|
||||
const DWORD config_get_string_ = 0x42BF48;
|
||||
const DWORD config_set_value_ = 0x42C160;
|
||||
const DWORD construct_box_bar_win_ = 0x461134;
|
||||
const DWORD container_exit_ = 0x476394;
|
||||
const DWORD correctFidForRemovedItem_ = 0x45409C;
|
||||
const DWORD createWindow_ = 0x4B7F3C;
|
||||
@@ -600,6 +604,7 @@ const DWORD register_object_must_erase_ = 0x414E20;
|
||||
const DWORD register_object_take_out_ = 0x415238;
|
||||
const DWORD register_object_turn_towards_ = 0x414C50;
|
||||
const DWORD report_explosion_ = 0x413144;
|
||||
const DWORD reset_box_bar_win_ = 0x4614A0;
|
||||
const DWORD RestorePlayer_ = 0x43A8BC;
|
||||
const DWORD roll_random_ = 0x4A30C0;
|
||||
const DWORD runProgram_ = 0x46E154;
|
||||
|
||||
@@ -257,6 +257,7 @@
|
||||
// colors
|
||||
#define _BlueColor 0x6A38EF
|
||||
#define _DarkGreenColor 0x6A3A90
|
||||
#define _DullPinkColor 0x6AB718
|
||||
#define _GoodColor 0x6AB4EF
|
||||
#define _GreenColor 0x6A3CB0
|
||||
#define _PeanutButter 0x6A82F3
|
||||
@@ -277,6 +278,7 @@ extern DWORD* ptr_art_vault_guy_num;
|
||||
extern DWORD* ptr_art_vault_person_nums;
|
||||
extern DWORD* ptr_bckgnd;
|
||||
extern DWORD* ptr_black_palette;
|
||||
extern BYTE* ptr_BlueColor;
|
||||
extern DWORD* ptr_bottom_line;
|
||||
extern DWORD* ptr_btable;
|
||||
extern DWORD* ptr_btncnt;
|
||||
@@ -321,6 +323,7 @@ extern DWORD* ptr_gIsSteal;
|
||||
extern DWORD* ptr_glblmode;
|
||||
extern long* ptr_gmouse_current_cursor;
|
||||
extern DWORD* ptr_gmovie_played_list;
|
||||
extern BYTE* ptr_GoodColor;
|
||||
extern BYTE* ptr_GreenColor;
|
||||
extern DWORD* ptr_gsound_initialized;
|
||||
extern long* ptr_hit_location_penalty;
|
||||
@@ -453,6 +456,7 @@ extern DWORD* ptr_title_font;
|
||||
extern DWORD* ptr_trait_data;
|
||||
extern DWORD* ptr_view_page;
|
||||
extern DWORD* ptr_wd_obj;
|
||||
extern BYTE* ptr_WhiteColor;
|
||||
extern DWORD* ptr_wmAreaInfoList;
|
||||
extern DWORD* ptr_wmLastRndTime;
|
||||
extern DWORD* ptr_wmWorldOffsetX;
|
||||
@@ -509,6 +513,7 @@ extern const DWORD combat_turn_run_;
|
||||
extern const DWORD compute_damage_;
|
||||
extern const DWORD config_get_string_;
|
||||
extern const DWORD config_set_value_;
|
||||
extern const DWORD construct_box_bar_win_;
|
||||
extern const DWORD container_exit_;
|
||||
extern const DWORD correctFidForRemovedItem_; // (int critter@<eax>, int oldArmor@<edx>, int removeSlotsFlags@<ebx>)
|
||||
extern const DWORD createWindow_;
|
||||
@@ -835,6 +840,7 @@ extern const DWORD register_object_must_erase_; // int aObj<eax>
|
||||
extern const DWORD register_object_take_out_; // int aObj<eax>, int aHoldFrame<edx> - hold frame ID (1 - spear, 2 - club, etc.)
|
||||
extern const DWORD register_object_turn_towards_; // int aObj<eax>, int aTile<edx>
|
||||
extern const DWORD report_explosion_;
|
||||
extern const DWORD reset_box_bar_win_;
|
||||
extern const DWORD RestorePlayer_;
|
||||
extern const DWORD roll_random_;
|
||||
extern const DWORD runProgram_; // eax - programPtr, called once for each program after first loaded - hooks program to game and UI events
|
||||
|
||||
+1
-1
@@ -1116,7 +1116,7 @@ void GraphicsInit() {
|
||||
}
|
||||
|
||||
void GraphicsExit() {
|
||||
if (GraphicsMode != 0) {
|
||||
if (GraphicsMode) {
|
||||
if (titlesBuffer) delete[] titlesBuffer;
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "AI.h"
|
||||
#include "Arrays.h"
|
||||
#include "BugFixes.h"
|
||||
#include "BarBoxes.h"
|
||||
#include "Combat.h"
|
||||
#include "Console.h"
|
||||
#include "Criticals.h"
|
||||
@@ -98,12 +99,14 @@ static void _stdcall ResetState(DWORD onLoad) {
|
||||
InventoryReset();
|
||||
ClearSavPrototypes();
|
||||
RegAnimCombatCheck(1);
|
||||
ForceEncounterRestore(); // restore if the encounter did not happen
|
||||
AfterAttackCleanup();
|
||||
ResetExplosionRadius();
|
||||
RestoreObjUnjamAllLocks();
|
||||
ForceEncounterRestore(); // restore if the encounter did not happen
|
||||
PartyControlReset();
|
||||
NpcEngineLevelUpReset();
|
||||
ResetBoxes();
|
||||
ResetBoxCount();
|
||||
}
|
||||
|
||||
void GetSavePath(char* buf, char* ftype) {
|
||||
@@ -284,8 +287,9 @@ static void __stdcall game_init_hook() { // OnGameInit
|
||||
}
|
||||
|
||||
static void __stdcall GameInitialized() { // OnAfterGameInit
|
||||
rcpresInit();
|
||||
if (GraphicsMode) rcpresInit();
|
||||
RemoveSavFiles();
|
||||
SetBoxMaxSlots();
|
||||
if (Use32BitTalkingHeads) TalkingHeadsSetup();
|
||||
}
|
||||
|
||||
|
||||
@@ -404,6 +404,7 @@ static const SfallOpcodeMetadata opcodeMetaArray[] = {
|
||||
{sf_get_obj_under_cursor, "obj_under_cursor", {DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
||||
{sf_set_cursor_mode, "set_cursor_mode", {DATATYPE_MASK_INT}},
|
||||
{sf_set_flags, "set_flags", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT}},
|
||||
{sf_set_iface_tag_text, "set_iface_tag_text", {DATATYPE_MASK_INT, DATATYPE_MASK_STR, DATATYPE_MASK_INT}},
|
||||
{sf_set_ini_setting, "set_ini_setting", {DATATYPE_MASK_STR, DATATYPE_MASK_INT | DATATYPE_MASK_STR}},
|
||||
{sf_set_map_enter_position, "set_map_enter_position", {DATATYPE_MASK_INT, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
||||
{sf_set_object_data, "set_object_data", {DATATYPE_MASK_VALID_OBJ, DATATYPE_MASK_INT, DATATYPE_MASK_INT}},
|
||||
|
||||
@@ -241,6 +241,12 @@ end:
|
||||
}
|
||||
}
|
||||
|
||||
static void sf_add_iface_tag() {
|
||||
int result = AddExtraBox();
|
||||
if (result == -1) opHandler.printOpcodeError("add_iface_tag() - cannot add new tag as the maximum limit of 126 tags has been reached.");
|
||||
opHandler.setReturn(result);
|
||||
}
|
||||
|
||||
static void _stdcall ShowIfaceTag2() {
|
||||
const ScriptValue &tagArg = opHandler.arg(0);
|
||||
if (tagArg.isInt()) {
|
||||
@@ -306,7 +312,7 @@ static void IsIfaceTagActive2() {
|
||||
}
|
||||
opHandler.setReturn(result);
|
||||
} else {
|
||||
opHandler.printOpcodeError("is_iface_tag_active() - argument is not an integer.");
|
||||
OpcodeInvalidArgs("is_iface_tag_active");
|
||||
opHandler.setReturn(-1);
|
||||
}
|
||||
}
|
||||
@@ -364,6 +370,17 @@ static void sf_display_stats() {
|
||||
}
|
||||
}
|
||||
|
||||
static void sf_set_iface_tag_text() {
|
||||
int boxTag = opHandler.arg(0).asInt();
|
||||
int maxBox = BarBoxes_MaxBox();
|
||||
|
||||
if (boxTag > 4 && boxTag <= maxBox) {
|
||||
BarBoxes_SetText(boxTag, opHandler.arg(1).strValue(), opHandler.arg(2).asInt());
|
||||
} else {
|
||||
opHandler.printOpcodeError("set_iface_tag_text() - tag value must be in the range of 5 to %d.", maxBox);
|
||||
}
|
||||
}
|
||||
|
||||
static void sf_inventory_redraw() {
|
||||
int mode;
|
||||
DWORD loopFlag = GetLoopFlags() & (INVENTORY | INTFACEUSE | INTFACELOOT | BARTER);
|
||||
|
||||
@@ -118,6 +118,7 @@ static void sf_metarule_exist() {
|
||||
- minArgs/maxArgs - minimum and maximum number of arguments allowed for this function (max 6)
|
||||
*/
|
||||
static const SfallMetarule metaruleArray[] = {
|
||||
{"add_iface_tag", sf_add_iface_tag, 0, 0},
|
||||
{"add_trait", sf_add_trait, 1, 1},
|
||||
{"art_cache_clear", sf_art_cache_flush, 0, 0},
|
||||
{"attack_is_aimed", sf_attack_is_aimed, 0, 0},
|
||||
@@ -149,6 +150,7 @@ static const SfallMetarule metaruleArray[] = {
|
||||
{"real_dude_obj", sf_real_dude_obj, 0, 0},
|
||||
{"set_cursor_mode", sf_set_cursor_mode, 1, 1},
|
||||
{"set_flags", sf_set_flags, 2, 2},
|
||||
{"set_iface_tag_text", sf_set_iface_tag_text, 3, 3},
|
||||
{"set_ini_setting", sf_set_ini_setting, 2, 2},
|
||||
{"set_map_enter_position", sf_set_map_enter_position, 3, 3},
|
||||
{"set_object_data", sf_set_object_data, 3, 3},
|
||||
|
||||
@@ -766,6 +766,7 @@ static void _stdcall OnExit() {
|
||||
BooksExit();
|
||||
//gExtraGameMsgLists.clear();
|
||||
AnimationsExit();
|
||||
BarBoxesExit();
|
||||
HeroAppearanceModExit();
|
||||
TalkingHeadsExit();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user