diff --git a/artifacts/scripting/headers/define_extra.h b/artifacts/scripting/headers/define_extra.h index 1c752d76..1f6a0949 100644 --- a/artifacts/scripting/headers/define_extra.h +++ b/artifacts/scripting/headers/define_extra.h @@ -87,7 +87,7 @@ #define FLAG_SEEN (0x40000000) #define FLAG_SHOOTTHRU (0x80000000) -/* Critter Flags */ +/* Critter flags */ #define CFLG_BARTER 2 // 0x00000002 - Barter (can trade with) #define CFLG_NOSTEAL 32 // 0x00000020 - Steal (cannot steal from) #define CFLG_NODROP 64 // 0x00000040 - Drop (doesn't drop items) @@ -100,12 +100,20 @@ #define CFLG_RANGED 8192 // 0x00002000 - Range (melee attack is possible at a distance) #define CFLG_NOKNOCKDOWN 16384 // 0x00004000 - Knock (cannot be knocked down) -/* Window Flags */ +/* Window flags */ #define WIN_FLAG_MOVEONTOP (0x4) #define WIN_FLAG_HIDDEN (0x8) #define WIN_FLAG_EXCLUSIVE (0x10) #define WIN_FLAG_TRANSPARENT (0x20) +/* Message window flags */ +#define MSGBOX_AUTOSIZE (0x0) +#define MSGBOX_NORMAL (0x1) +#define MSGBOX_SMALL (0x2) +#define MSGBOX_ALIGN_LEFT (0x4) // text aligned to left +#define MSGBOX_ALIGN_TOP (0x8) // text aligned to top +#define MSGBOX_YESNO (0x10) // use YES/NO buttons instead of DONE +#define MSGBOX_CLEAN (0x20) // no buttons //remove inven obj defines #define RMOBJ_CONSUME_DRUG 4666772 diff --git a/artifacts/scripting/sfall function notes.txt b/artifacts/scripting/sfall function notes.txt index 51976a5c..01436b07 100644 --- a/artifacts/scripting/sfall function notes.txt +++ b/artifacts/scripting/sfall function notes.txt @@ -624,11 +624,11 @@ optional arguments: - areaID: the ID number of the town from city.txt > 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, 1 - Yes/Done +- 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!") optional arguments: -- flags: mode flags (see DIALOGOUT_* constants in define_extra.h). Pass -1 to skip setting the flags (default flags are DIALOGOUT_NORMAL|DIALOGOUT_YESNO) +- 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) ------------------------ diff --git a/sfall/Define.h b/sfall/Define.h index e41594f9..516650fb 100644 --- a/sfall/Define.h +++ b/sfall/Define.h @@ -247,6 +247,12 @@ enum Stat : long #define STAT_max_derived STAT_poison_resist #define STAT_max_stat STAT_current_hp +// Script data types +#define VAR_TYPE_INT (0xC001) +#define VAR_TYPE_FLOAT (0xA001) +#define VAR_TYPE_STR (0x9801) +#define VAR_TYPE_STR2 (0x9001) + // extra stat-like values that are treated specially enum PCStat : long { @@ -451,6 +457,6 @@ enum DialogOutFlags : long 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_YESNO = 0x10, // DONE button replaced by YES/NO buttons DIALOGOUT_CLEAN = 0x20 // no buttons }; diff --git a/sfall/FalloutEngine.cpp b/sfall/FalloutEngine.cpp index 7889156d..790e6085 100644 --- a/sfall/FalloutEngine.cpp +++ b/sfall/FalloutEngine.cpp @@ -1083,37 +1083,44 @@ long __stdcall WinRegisterButton(DWORD winRef, long xPos, long yPos, long width, } } -void __fastcall DialogOut(const char* text, const char** textEx, long lines) { +void __stdcall DialogOut(const char* text) { __asm { push 1; // DIALOGOUT_NORMAL flag - xor eax, eax; - mov al, byte ptr ds:[0x6AB718]; - push eax; // ColorMsg - push 0; // DisplayMsg (unknown) - push eax; // ColorIndex - mov eax, ecx; // DisplayText - push 116; // y + xor edx, edx; + push edx; + push edx; + mov dl, byte ptr ds:[0x6AB718]; + push edx; // ColorMsg mov ecx, 192; // x - mov ebx, lines; // count text lines 0-5 + push 116; // y + mov eax, text; // DisplayText + xor ebx, ebx; call dialog_out_; } } long __fastcall DialogOutEx(const char* text, const char** textEx, long lines, long flags, long colors) { __asm { + mov ebx, colors; // Color index xor eax, eax; - mov ebx, colors;// Color index + push flags; + test ebx, ebx; + jnz cColor; + mov al, byte ptr ds:[0x6AB718]; + mov bl, al; + jmp skip; +cColor: mov al, bh; - push flags; // flag and ebx, 0xFF +skip: push eax; // ColorMsg2 push 0; // DisplayMsg (unknown) - mov eax, ecx; // DisplayText first line + mov eax, ecx; // DisplayText (first line) push ebx; // ColorMsg1 mov ecx, 192; // x push 116; // y - mov ebx, lines; // count text lines 0-5 - call dialog_out_; // edx - DisplayText second and later lines + mov ebx, lines; // count second lines + call dialog_out_; // edx - DisplayText (seconds lines) } } diff --git a/sfall/FalloutEngine.h b/sfall/FalloutEngine.h index f813eef4..01182d3b 100644 --- a/sfall/FalloutEngine.h +++ b/sfall/FalloutEngine.h @@ -1186,9 +1186,9 @@ long __fastcall CreateWindowFunc(const char* winName, DWORD x, DWORD y, DWORD wi // creates a button long __stdcall WinRegisterButton(DWORD winRef, long xPos, long yPos, long width, long height, long hoverOn, long hoverOff, long buttonDown, long buttonUp, BYTE* pictureUp, BYTE* pictureDown, long arg12, long buttonType); -void __fastcall DialogOut(const char* text, const char** textEx, long lines); +void __stdcall DialogOut(const char* text);; -long __fastcall DialogOutEx(const char* text, const char** textEx, long lines, long flags, long colors); +long __fastcall DialogOutEx(const char* text, const char** textEx, long lines, long flags, long colors = 0); void __fastcall WindowDisplayBuf(long x, long width, long y, long height, void* data, long noTrans); diff --git a/sfall/ScriptExtender.h b/sfall/ScriptExtender.h index 12911857..23c9ece7 100644 --- a/sfall/ScriptExtender.h +++ b/sfall/ScriptExtender.h @@ -95,12 +95,6 @@ static char reg_anim_combat_check = 1; extern DWORD isGlobalScriptLoading; extern DWORD AvailableGlobalScriptTypes; -// Script data types -#define VAR_TYPE_INT (0xC001) -#define VAR_TYPE_FLOAT (0xA001) -#define VAR_TYPE_STR (0x9801) -#define VAR_TYPE_STR2 (0x9001) - // Script procedure types enum ScriptProc : long { diff --git a/sfall/ScriptOps/InterfaceOp.hpp b/sfall/ScriptOps/InterfaceOp.hpp index 56cb47ee..b46cf7a5 100644 --- a/sfall/ScriptOps/InterfaceOp.hpp +++ b/sfall/ScriptOps/InterfaceOp.hpp @@ -171,14 +171,14 @@ static void __declspec(naked) resume_game() { // copy and split static void _stdcall SplitToBuffer(const char* str, const char** str_ptr, long &lines) { size_t i = 0; - do { + while (str[i]) { if (str[i] == '\n' && lines < 4) { gTextBuffer[i] = '\0'; str_ptr[lines++] = &gTextBuffer[++i]; } else { gTextBuffer[i] = str[i++]; } - } while (str[i]); + }; gTextBuffer[i] = '\0'; } @@ -196,7 +196,7 @@ static void _stdcall create_message_window2() { SplitToBuffer(str, str_ptr, lines); dialogShow = true; - DialogOut(gTextBuffer, str_ptr, lines); + DialogOutEx(gTextBuffer, str_ptr, lines, DIALOGOUT_NORMAL); dialogShow = false; } else { OpcodeInvalidArgs("create_message_window"); diff --git a/sfall/ScriptOps/MetaruleOp.hpp b/sfall/ScriptOps/MetaruleOp.hpp index 09dc3e3e..0fa1cab0 100644 --- a/sfall/ScriptOps/MetaruleOp.hpp +++ b/sfall/ScriptOps/MetaruleOp.hpp @@ -94,14 +94,10 @@ static void sf_get_metarule_table() { static void sf_metarule_exist() { bool result = false; - const char *funcXName = opHandler.arg(0).asString(); + const char* funcXName = opHandler.arg(0).asString(); if (funcXName[0] != '\0') { - for (MetaruleTableType::iterator it = metaruleTable.begin(); it != metaruleTable.end(); it++) { - if (it->first == funcXName) { - result = true; - break; - } - } + const auto &it = metaruleTable.find(funcXName); + if (it != metaruleTable.cend()) result = true; } opHandler.setReturn(result); } diff --git a/sfall/Worldmap.cpp b/sfall/Worldmap.cpp index 3058642b..3c78da65 100644 --- a/sfall/Worldmap.cpp +++ b/sfall/Worldmap.cpp @@ -30,7 +30,7 @@ static DWORD ViewportX; static DWORD ViewportY; std::vector> wmTerrainTypeNames; // pair first: x + y * number of horizontal sub-tiles -std::vector> wmAreaHotSpotTitle; +std::tr1::unordered_map wmAreaHotSpotTitle; static DWORD worldMapDelay; static DWORD worldMapTicks; @@ -461,14 +461,13 @@ void Wmap_SetTerrainTypeName(long x, long y, const char* name) { long subTileID = x + y * (*ptr_wmNumHorizontalTiles * 7); wmTerrainTypeNames.push_back(std::make_pair(subTileID, name)); } -/* + // TODO: someone might need to know the name of a terrain type? -const char* Wmap_GetTerrainTypeName(long x, long y) { - //const char* name = GetOverrideTerrainName(x, y); - //return (name) ? name : fo::GetMessageStr(&fo::var::wmMsgFile, 1000 + fo::wmGetTerrainType(x, y)); - return nullptr; -} -*/ +/*const char* Wmap_GetTerrainTypeName(long x, long y) { + const char* name = GetOverrideTerrainName(x, y); + return (name) ? name : fo::GetMessageStr(&fo::var::wmMsgFile, 1000 + fo::wmGetTerrainType(x, y)); +}*/ + // Returns the name of the terrain type in the position of the player's marker on the world map const char* Wmap_GetCurrentTerrainName() { const char* name = GetOverrideTerrainName(*ptr_world_xpos / 50, *ptr_world_ypos / 50); @@ -480,17 +479,13 @@ bool Wmap_AreaTitlesIsEmpty() { } void Wmap_SetCustomAreaTitle(long areaID, const char* msg) { - wmAreaHotSpotTitle.push_back(std::make_pair(areaID, msg)); + wmAreaHotSpotTitle[areaID] = msg; } const char* Wmap_GetCustomAreaTitle(long areaID) { - if (wmAreaHotSpotTitle.empty()) return nullptr; - - auto it = std::find_if(wmAreaHotSpotTitle.crbegin(), wmAreaHotSpotTitle.crend(), - [=](const std::pair &el) - { return el.first == areaID; } - ); - return (it != wmAreaHotSpotTitle.crend()) ? it->second.c_str() : nullptr; + if (Wmap_AreaTitlesIsEmpty()) return nullptr; + const auto &it = wmAreaHotSpotTitle.find(areaID); + return (it != wmAreaHotSpotTitle.cend()) ? it->second.c_str() : nullptr; } void Worldmap_OnGameLoad() {