diff --git a/artifacts/scripting/headers/lib.math.h b/artifacts/scripting/headers/lib.math.h index 9f3191d4..1ef8a7d4 100644 --- a/artifacts/scripting/headers/lib.math.h +++ b/artifacts/scripting/headers/lib.math.h @@ -11,7 +11,7 @@ #define below_equal(a, b) (unsigned_comp(a, b) <= 0) procedure unsigned_comp(variable a, variable b) begin - if (a bwxor b) then return 0; + if ((a bwxor b) == 0) then return 0; // a == b if (b == 0) then return 1; return 1 if (a / b) else -1; end diff --git a/artifacts/scripting/headers/sfall.h b/artifacts/scripting/headers/sfall.h index 3578e617..584e27ed 100644 --- a/artifacts/scripting/headers/sfall.h +++ b/artifacts/scripting/headers/sfall.h @@ -80,6 +80,7 @@ //Valid flags for force_encounter_with_flags #define ENCOUNTER_FLAG_NO_CAR (1) #define ENCOUNTER_FLAG_LOCK (2) // block new forced encounter by the next function call until the current specified encounter occurs +#define ENCOUNTER_FLAG_SPECIAL (4) // special blinking icon //The attack types returned by get_attack_type #define ATKTYPE_LWEP1 (0) diff --git a/artifacts/scripting/hookscripts.txt b/artifacts/scripting/hookscripts.txt index 9e49bc4f..af9aa2ce 100644 --- a/artifacts/scripting/hookscripts.txt +++ b/artifacts/scripting/hookscripts.txt @@ -681,5 +681,5 @@ int arg1 - event type: 0 - when a random encounter occurs, 1 - when the play int arg2 - the map ID that the encounter will load (see MAPS.h or Maps.txt) int arg3 - 1 when the encounter occurs is a special encounter, 0 otherwise -int ret1 - overrides the map ID, or pass -1 to cancel the encounter and continue traveling (only for event type 0) +int ret1 - overrides the map ID, or pass -1 for event type 0 to cancel the encounter and continue traveling int ret2 - pass 1 to cancel the encounter and load the specified map from the ret1 (only for event type 0) diff --git a/artifacts/scripting/sfall function notes.txt b/artifacts/scripting/sfall function notes.txt index 618e2b25..88a914d3 100644 --- a/artifacts/scripting/sfall function notes.txt +++ b/artifacts/scripting/sfall function notes.txt @@ -137,7 +137,7 @@ array - array ID to be used with array-related functions (actually an integer) - The player will not get an outdoorsman skill check. > void force_encounter_with_flags(int map, int flags) -- does the same thing as force_encounter, but allows the specification of some extra options. +- does the same thing as force_encounter, but allows the specification of some extra options (see sfall.h for available flags). - Forcing a random encounter on a map that is not normally used for random encounters may cause the player to lose the car, if they have it. - In this case use force_encounter_with_flags with the ENCOUNTER_FLAG_NO_CAR flag set. @@ -703,7 +703,7 @@ optional argument: - NOTE: this function works only for English letters of A-Z/a-z > void sfall_func3("set_terrain_name", int x, int y, string name) -- overrides the terrain type name for the sub-tile by the specified coordinates on the world map +- overrides the terrain type name for the sub-tile on the world map by the specified coordinates ------------------------ ------ MORE INFO ------- diff --git a/sfall/FalloutEngine/Functions_def.h b/sfall/FalloutEngine/Functions_def.h index cc6e8d04..3d8ef877 100644 --- a/sfall/FalloutEngine/Functions_def.h +++ b/sfall/FalloutEngine/Functions_def.h @@ -50,6 +50,7 @@ WRAP_WATCOM_FUNC4(BYTE*, art_ptr_lock_data, long, frmId, long, frameNum, long, r WRAP_WATCOM_FUNC4(BYTE*, art_lock, long, frmId, DWORD*, lockPtr, long*, widthOut, long*, heightOut) WRAP_WATCOM_FUNC1(long, art_ptr_unlock, DWORD, lockId) WRAP_WATCOM_FUNC2(long, barter_compute_value, GameObject*, source, GameObject*, target) +WRAP_WATCOM_FUNC1(long, block_for_tocks, long, ticks) WRAP_WATCOM_FUNC1(void*, dbase_open, const char*, fileName) WRAP_WATCOM_FUNC1(void, dbase_close, void*, dbPtr) WRAP_WATCOM_FUNC3(long, db_freadShortCount, DbFile*, file, WORD*, dest, long, count) diff --git a/sfall/FalloutEngine/VariableOffsets.h b/sfall/FalloutEngine/VariableOffsets.h index 0f1eb2c3..1e483a67 100644 --- a/sfall/FalloutEngine/VariableOffsets.h +++ b/sfall/FalloutEngine/VariableOffsets.h @@ -245,11 +245,13 @@ #define FO_VAR_wmAreaInfoList 0x51DDF8 #define FO_VAR_wmBkWin 0x51DE14 #define FO_VAR_wmBkWinBuf 0x51DE24 +#define FO_VAR_wmEncounterIconShow 0x672E48 #define FO_VAR_wmLastRndTime 0x51DEA0 #define FO_VAR_wmMaxMapNum 0x51DE10 #define FO_VAR_wmMaxTileNum 0x51DDF0 #define FO_VAR_wmMsgFile 0x672FB0 #define FO_VAR_wmNumHorizontalTiles 0x51DDF4 +#define FO_VAR_wmRndCursorFid 0x672E58 #define FO_VAR_wmViewportRightScrlLimit 0x672EFC #define FO_VAR_wmViewportBottomtScrlLimit 0x672F00 #define FO_VAR_wmWorldOffsetX 0x51DE2C diff --git a/sfall/Modules/HookScripts/MiscHs.cpp b/sfall/Modules/HookScripts/MiscHs.cpp index 15e5b862..ddbcc52f 100644 --- a/sfall/Modules/HookScripts/MiscHs.cpp +++ b/sfall/Modules/HookScripts/MiscHs.cpp @@ -525,14 +525,14 @@ end: } } -// hook does not work for scripted encounters and meeting Horrigan +// Hook does not work for scripted encounters and meeting Horrigan static long __fastcall EncounterHook_Script(long encounterMapID, long eventType, long encType) { BeginHook(); argCount = 3; args[0] = eventType; // 1 - enter local map from the world map args[1] = encounterMapID; - args[2] = (encType == 3); // 1 - special random encounter (not verified) + args[2] = (encType == 3); // 1 - special random encounter RunHookScript(HOOK_ENCOUNTER); @@ -595,22 +595,22 @@ clearEnc: ///////////////////////////////// dec edx; blinkIcon: cmp edx, 6; // counter of blinking - je break; + jge break; jmp fo::funcoffs::wmInterfaceRefresh_; break: mov eax, hkEncounterMapID; - cmp ds:[FO_VAR_Move_on_Car], 1; - jne noCar; + cmp ds:[FO_VAR_Move_on_Car], 0; + je noCar; mov edx, FO_VAR_carCurrentArea; call fo::funcoffs::wmMatchAreaContainingMapIdx_; mov eax, hkEncounterMapID; noCar: call fo::funcoffs::map_load_idx_; xor eax, eax; - //mov ds:[0x672E48], eax; // _wmUnkVar00 mov hkEncounterMapID, -1; cancelEnc: inc eax; // 0 - continue movement, 1 - interrupt + mov ds:[FO_VAR_wmEncounterIconShow], 0; add esp, 4; mov ebx, 0x4C0BC7; jmp ebx; diff --git a/sfall/Modules/Scripting/Handlers/Worldmap.cpp b/sfall/Modules/Scripting/Handlers/Worldmap.cpp index c33c32fd..5f30233f 100644 --- a/sfall/Modules/Scripting/Handlers/Worldmap.cpp +++ b/sfall/Modules/Scripting/Handlers/Worldmap.cpp @@ -43,6 +43,20 @@ DWORD ForceEncounterRestore() { return mapID; } +// implements a blinking encounter icon +static void ForceEncounterIcon() { + long iconType = (ForceEncounterFlags & 4) ? 3 : 1; // icon type flag (special: 0-3, normal: 0-1) + *(DWORD*)FO_VAR_wmEncounterIconShow = 1; + *(DWORD*)FO_VAR_wmRndCursorFid = 0; + for (size_t n = 0; n < 7; ++n) { + long iconFidIndex = iconType - *(DWORD*)FO_VAR_wmRndCursorFid; + *(DWORD*)FO_VAR_wmRndCursorFid = iconFidIndex; + __asm call fo::funcoffs::wmInterfaceRefresh_; + fo::func::block_for_tocks(200); + } + *(DWORD*)FO_VAR_wmEncounterIconShow = 0; +} + static void __declspec(naked) wmRndEncounterOccurred_hack() { __asm { test ForceEncounterFlags, 0x1; // _NoCar flag @@ -53,10 +67,8 @@ static void __declspec(naked) wmRndEncounterOccurred_hack() { mov eax, ForceEncounterMapID; call fo::funcoffs::wmMatchAreaContainingMapIdx_; noCar: - //push ecx; - // TODO: implement a blinking red icon + call ForceEncounterIcon; call ForceEncounterRestore; - //pop ecx; push 0x4C0721; // return addr jmp fo::funcoffs::map_load_idx_; // eax - mapID }