diff --git a/artifacts/example_mods/AutoCloseBox/gl_auto_closebox.int b/artifacts/example_mods/AutoCloseBox/gl_auto_closebox.int index 9a7fb151..64aa7da2 100644 Binary files a/artifacts/example_mods/AutoCloseBox/gl_auto_closebox.int and b/artifacts/example_mods/AutoCloseBox/gl_auto_closebox.int differ diff --git a/artifacts/example_mods/AutoCloseBox/gl_auto_closebox.ssl b/artifacts/example_mods/AutoCloseBox/gl_auto_closebox.ssl index 42e5f308..b69213d6 100644 --- a/artifacts/example_mods/AutoCloseBox/gl_auto_closebox.ssl +++ b/artifacts/example_mods/AutoCloseBox/gl_auto_closebox.ssl @@ -13,8 +13,10 @@ Requires sfall 4.2.2/3.8.29 or higher #include "..\headers\sfall\define_extra.h" procedure start; +procedure close; variable lootObject; +variable closeObject; procedure start begin if (game_loaded) then begin @@ -26,8 +28,13 @@ procedure start begin lootObject := loot_obj; if (obj_type(lootObject) != OBJ_TYPE_ITEM) then lootObject = 0; end else if (lootObject andAlso get_sfall_arg_at(1) == INTFACELOOT) then begin - if (get_object_data(lootObject, OBJ_DATA_CUR_FRM) > 1) then obj_close(lootObject); + if (get_object_data(lootObject, OBJ_DATA_CUR_FRM) > 1) then call close in 1; + closeObject = lootObject; lootObject = 0; end end end + +procedure close begin + obj_close(closeObject); +end diff --git a/artifacts/example_mods/ItemHighlight_Lite/gl_highlighting_lite.int b/artifacts/example_mods/ItemHighlight_Lite/gl_highlighting_lite.int index e947b4bb..6b479e88 100644 Binary files a/artifacts/example_mods/ItemHighlight_Lite/gl_highlighting_lite.int and b/artifacts/example_mods/ItemHighlight_Lite/gl_highlighting_lite.int differ diff --git a/artifacts/example_mods/ItemHighlight_Lite/main.h b/artifacts/example_mods/ItemHighlight_Lite/main.h index 28c719f3..5f545e45 100644 --- a/artifacts/example_mods/ItemHighlight_Lite/main.h +++ b/artifacts/example_mods/ItemHighlight_Lite/main.h @@ -25,7 +25,7 @@ end // Gets the string value from the specified ini procedure GetIniConfigStr(variable section, variable key, variable def, variable inifile) begin variable val := get_ini_string(inifile + "|" + section + "|" + key); - if val == -1 or val == "" then val := def; + if val == -1 orElse val == "" then val := def; return val; end @@ -39,14 +39,14 @@ end // Gets the string value from sfall-mods.ini procedure GetConfigStr(variable section, variable key, variable def) begin variable val := get_ini_string(ini + "|" + section + "|" + key); - if val == -1 or val == "" then val := def; + if val == -1 orElse val == "" then val := def; return val; end // Gets the value from sfall-mods.ini as a temp array of strings procedure GetConfigList(variable section, variable key) begin variable val := get_ini_string(ini + "|" + section + "|" + key); - if val == -1 or val == "" then return []; + if val == -1 orElse val == "" then return []; return string_split(val, ","); end @@ -65,7 +65,7 @@ end // Translates given string using Translations.ini procedure Translate(variable id, variable def) begin variable str := get_ini_string(translationIni + "|Sfall|" + id); - if not str or (strlen(str) == 0) then begin + if (str == 0 orElse (strlen(str) == 0)) then begin str := def; end return str; diff --git a/sfall/Animations.cpp b/sfall/Animations.cpp index b131a24d..bd6c4b47 100644 --- a/sfall/Animations.cpp +++ b/sfall/Animations.cpp @@ -17,22 +17,17 @@ */ #include "main.h" - -#include "Animations.h" #include "FalloutEngine.h" #include "LoadGameHook.h" -static const int animRecordSize = sizeof(AnimationSet); -static const int sadSize = 3240; - -static int animationLimit = 32; +//static int animationLimit = 32; //pointers to new animation struct arrays -static std::vector new_anim_set; -static std::vector new_sad; +static std::vector sf_anim_set; +static std::vector sf_sad; -static DWORD animSetAddr = FO_VAR_anim_set; -static DWORD sadAddr = FO_VAR_sad; +static AnimationSet* animSet = (AnimationSet*)FO_VAR_anim_set; +static AnimationSad* animSad = (AnimationSad*)FO_VAR_sad; static const DWORD animPCMove[] = { 0x416E11, 0x416F64, 0x417143, 0x41725C, 0x4179CC, @@ -46,11 +41,7 @@ static const DWORD animMaxSizeCheck[] = { 0x413AA9, 0x413CB7, 0x413DC2, 0x417F3A, }; -static const DWORD fake_anim_set_C[] = { - 0x413AA4, 0x413DBC, -}; - -static const DWORD anim_set_0[] = { +static const DWORD anim_set_0[] = { // curr_anim 0x413B96, 0x413C5A, 0x413CF0, 0x413DE1, 0x413E66, 0x413EF3, 0x413FA2, 0x414161, 0x4142D3, 0x41449A, 0x41460B, 0x4146FF, 0x414826, 0x41491A, 0x4149F8, 0x414AD0, 0x414BA4, 0x414C8C, 0x414CF0, 0x414D60, 0x414DD0, @@ -60,32 +51,36 @@ static const DWORD anim_set_0[] = { 0x415BB6, 0x415C7C, 0x415CA3, /*0x415DE4, - conflct with 0x415DE2*/ }; -static const DWORD anim_set_4[] = { +static const DWORD anim_set_4[] = { // counter 0x413D07, 0x415700, 0x415B6B, 0x415B78, 0x415C2D, 0x415D38, 0x415D56, 0x415D63, 0x415DCF, }; -static const DWORD anim_set_8[] = { +static const DWORD anim_set_8[] = { // anim_counter 0x413C6A, 0x413CA3, 0x413CF6, 0x413E76, 0x413EA4, 0x413F03, 0x413F20, 0x413F3A, 0x4156EC, 0x415B72, 0x415C18, 0x415C58, 0x415C6D, 0x415DBE, }; -static const DWORD anim_set_C[] = { +static const DWORD anim_set_C[] = { // flags 0x413B2A, 0x413B33, 0x413B43, 0x413B54, 0x413B66, 0x413BA2, 0x413BAB, 0x413BC0, 0x413BCD, 0x413C3C, 0x413C87, 0x413D01, 0x413D10, 0x413D36, 0x413D53, 0x413DAD, 0x413E93, 0x4155DF, 0x415AE2, 0x415D9A, 0x415DDE, 0x415E06, 0x415E12, 0x417F25, 0x417F30, }; -static const DWORD anim_set_10[] = { +static const DWORD anim_set_C_shift[] = { // flags + 0x413AA4, 0x413DBC, +}; + +static const DWORD anim_set_10[] = { // anim_0 0x413C7E, 0x413E8A, 0x413F17, 0x415C24, 0x415D16, 0x415D44, }; -static const DWORD anim_set_14[] = { +static const DWORD anim_set_14[] = { // anim_0.source 0x413C76, 0x413E82, 0x413F0F, 0x415C3E, 0x415D0E, 0x415D4D, }; -static const DWORD anim_set_28[] = { +static const DWORD anim_set_28[] = { // anim_0.delay 0x413D1C, 0x41570D, 0x415720, }; @@ -150,42 +145,26 @@ static const DWORD sad_28[] = { 0x4173CE, 0x4174C1, 0x4175F1, 0x417730, }; -static DWORD __fastcall AnimCombatFix(TGameObj* src, BYTE combatFlag) { - DWORD animAddr = animSetAddr; - - if (animationLimit > 32) { - animAddr += animRecordSize; // include a dummy - } - - if (combatFlag & 2) { // combat flag is set - __asm call combat_anim_finished_; - } - return animAddr; -} - static void __declspec(naked) anim_set_end_hack() { __asm { - push ecx; - call AnimCombatFix; - mov [eax][esi], ebx; - pop ecx; - xor dl, dl; // for goto 0x415DF2; + test dl, 2; // is combat flag set? + jz skip; + call combat_anim_finished_; +skip: + mov eax, animSet; + mov [eax][esi], ebx; // anim_set.curr_anim = -1000 retn; } } -static DWORD __fastcall CheckSetSad(BYTE openFlag, DWORD valueMul) { - bool result = false; - int offset = (sadSize * valueMul) + 32; - - if (*(DWORD*)(sadAddr + offset) == -1000) { - result = true; +static bool __fastcall CheckSetSad(BYTE openFlag, DWORD slot) { + if (animSad[slot].currentAnim == -1000) { + return true; } else if (!InCombat() && !(openFlag & 1)) { - *(DWORD*)(sadAddr + offset) = -1000; - result = true; + animSad[slot].currentAnim = -1000; + return true; } - - return result; + return false; } static void __declspec(naked) object_move_hack() { @@ -193,9 +172,9 @@ static void __declspec(naked) object_move_hack() { static const DWORD object_move_back1 = 0x417616; __asm { mov ecx, ds:[ecx + 0x3C]; // openFlag - mov edx, [esp + 0x4C - 0x20]; // valueMul + mov edx, [esp + 0x4C - 0x20]; // slot (valueMul) call CheckSetSad; - test eax, eax; + test al, al; jz end; jmp object_move_back0; // fixed jump end: @@ -241,105 +220,61 @@ void ApplyAnimationsAtOncePatches(signed char aniMax) { if (aniMax <= 32) return; //allocate memory to store larger animation struct arrays - new_anim_set.resize(aniMax + 1); - new_sad.resize(sadSize * (aniMax + 1)); + sf_anim_set.resize(aniMax + 1); // include a dummy + sf_sad.resize(aniMax + 1); // -8? - animSetAddr = reinterpret_cast(new_anim_set.data()); - sadAddr = reinterpret_cast(new_sad.data()); + //replace addresses for arrays + animSet = &sf_anim_set[1]; // the zero slot for the game remains unused + animSad = sf_sad.data(); - //set general animation limit check (old 20) aniMax-12 -- +12 reserved for PC movement(4) + other critical animations(8)? + //set general animation limit check (old 20) aniMax-12 (4 reserved for PC movement + 8 other critical animations?) SafeWrite8(0x413C07, aniMax - 12); - //PC movement animation limit checks (old 24) aniMax-8 -- +8 reserved for other critical animations?. + //PC movement animation limit checks (old 24) aniMax-8 (8 reserved for other critical animations?) SafeWriteBatch(aniMax - 8, animPCMove); //Max animation limit checks (old 32) aniMax SafeWriteBatch(aniMax, animMaxCheck); //Max animations checks - animation struct size * max num of animations (old 2656*32=84992) - SafeWriteBatch(animRecordSize * aniMax, animMaxSizeCheck); + SafeWriteBatch(sizeof(AnimationSet) * aniMax, animMaxSizeCheck); //divert old animation structure list pointers to newly allocated memory - //struct array 1/////////////////// + AnimationSet* animSetAddr = &sf_anim_set[0]; //old addr 0x54C1B4 - SafeWrite32(0x413A9E, animSetAddr); - + SafeWrite32(0x413A9E, (DWORD)&animSetAddr->currentAnim); // anim_reset_ //old addr 0x54C1C0 - SafeWriteBatch(12 + animSetAddr, fake_anim_set_C); + SafeWriteBatch((DWORD)&animSetAddr->flags, anim_set_C_shift); - //old addr 0x54CC14 - SafeWriteBatch(animRecordSize + animSetAddr, anim_set_0); + SafeWriteBatch((DWORD)&animSet->currentAnim, anim_set_0); + SafeWriteBatch((DWORD)&animSet->counter, anim_set_4); + SafeWriteBatch((DWORD)&animSet->totalAnimCount, anim_set_8); + SafeWriteBatch((DWORD)&animSet->flags, anim_set_C); + SafeWriteBatch((DWORD)&animSet->animations[0].number, anim_set_10); + SafeWriteBatch((DWORD)&animSet->animations[0].source, anim_set_14); + SafeWrite32(0x413F29, (DWORD)&animSet->animations[0].animCode); + SafeWriteBatch((DWORD)&animSet->animations[0].delay, anim_set_28); + SafeWrite32(0x415C35, (DWORD)&animSet->animations[0].flags); - //old addr 0x54CC18 - SafeWriteBatch(animRecordSize + 4 + animSetAddr, anim_set_4); - - //old addr 0x54CC1C - SafeWriteBatch(animRecordSize + 8 + animSetAddr, anim_set_8); - - //old addr 0x54CC20 - SafeWriteBatch(animRecordSize + 12 + animSetAddr, anim_set_C); - - //old addr 0x54CC24 - SafeWriteBatch(animRecordSize + 16 + animSetAddr, anim_set_10); - - //old addr 0x54CC28 - SafeWriteBatch(animRecordSize + 20 + animSetAddr, anim_set_14); - - //old addr 0x54CC38 - SafeWrite32(0x413F29, animRecordSize + 36 + animSetAddr); - - //old addr 0x54CC3C - SafeWriteBatch(animRecordSize + 40 + animSetAddr, anim_set_28); - - //old addr 0x54CC48 - SafeWrite32(0x415C35, animRecordSize + 52 + animSetAddr); - - //struct array 2/////////////////// - - //old addr 0x530014 - SafeWriteBatch(sadAddr, sad_0); - - //old addr 0x530018 - SafeWriteBatch(4 + sadAddr, sad_4); - - //old addr 0x53001C - SafeWriteBatch(8 + sadAddr, sad_8); - - //old addr 0x530020 - SafeWriteBatch(12 + sadAddr, sad_C); - - //old addr 0x530024 - SafeWriteBatch(16 + sadAddr, sad_10); - - //old addr 0x530028 - SafeWriteBatch(20 + sadAddr, sad_14); - - //old addr 0x53002C - SafeWriteBatch(24 + sadAddr, sad_18); - - //old addr 0x530030 - SafeWriteBatch(28 + sadAddr, sad_1C); - - //old addr 0x530034 - SafeWriteBatch(32 + sadAddr, sad_20); - - //old addr 0x530038 - SafeWriteBatch(36 + sadAddr, sad_24); - - //old addr 0x53003A - SafeWrite32(0x416903, 38 + sadAddr); - - //old addr 0x53003B - SafeWriteBatch(39 + sadAddr, sad_27); - - //old addr 0x53003C - SafeWriteBatch(40 + sadAddr, sad_28); + SafeWriteBatch((DWORD)&animSad->flags, sad_0); + SafeWriteBatch((DWORD)&animSad->source, sad_4); + SafeWriteBatch((DWORD)&animSad->fid, sad_8); + SafeWriteBatch((DWORD)&animSad->animCode, sad_C); + SafeWriteBatch((DWORD)&animSad->ticks, sad_10); + SafeWriteBatch((DWORD)&animSad->tpf, sad_14); + SafeWriteBatch((DWORD)&animSad->currAnimSet, sad_18); + SafeWriteBatch((DWORD)&animSad->pathCount, sad_1C); + SafeWriteBatch((DWORD)&animSad->currentAnim, sad_20); + SafeWriteBatch((DWORD)&animSad->dstTile, sad_24); + SafeWrite32(0x416903, (DWORD)&animSad->rotation1); + SafeWriteBatch((DWORD)&animSad->rotation2, sad_27); + SafeWriteBatch((DWORD)&animSad->pathData[0].tile, sad_28); } void Animations_Init() { - animationLimit = GetConfigInt("Misc", "AnimationsAtOnceLimit", 32); + int animationLimit = GetConfigInt("Misc", "AnimationsAtOnceLimit", 32); if (animationLimit > 32) { if (animationLimit > 127) { animationLimit = 127; @@ -348,8 +283,10 @@ void Animations_Init() { ApplyAnimationsAtOncePatches(animationLimit); dlogr(" Done", DL_INIT); } + // Fix for calling anim() functions in combat MakeCall(0x415DE2, anim_set_end_hack, 1); + SafeWrite8(0x415DEB, CODETYPE_JumpShort); // jz > jmp // Fix crash when the critter goes through a door with animation trigger MakeJump(0x41755E, object_move_hack); diff --git a/sfall/FalloutStructs.h b/sfall/FalloutStructs.h index 8e9661a9..fbfa4765 100644 --- a/sfall/FalloutStructs.h +++ b/sfall/FalloutStructs.h @@ -51,8 +51,9 @@ struct sArt { struct AnimationSet { long currentAnim; long counter; - long animCounter; + long totalAnimCount; long flags; + struct Animation { long number; long source; @@ -71,6 +72,30 @@ struct AnimationSet { static_assert(sizeof(AnimationSet) == 2656, "Incorrect AnimationSet definition."); +struct AnimationSad { + long flags; + long source; + long fid; + long animCode; + long ticks; + long tpf; // fps + long currAnimSet; + long pathCount; // len + long currentAnim; + short dstTile; + char rotation1; + char rotation2; + + struct BuildPathData { + long tile; + long elevation; + long sX; + long sY; + } pathData[200]; +}; + +static_assert(sizeof(AnimationSad) == 3240, "Incorrect AnimationSad definition."); + // Bounding rectangle, used by tile_refresh_rect and related functions. struct BoundRect { long x;