From e90edf8f426edc4991ed36b9d578c4ab825d796b Mon Sep 17 00:00:00 2001 From: phobos2077 Date: Sat, 8 Jun 2024 13:26:09 +0200 Subject: [PATCH] anim_stop: if called from combat_begin, skip ending sequences where current animation is forever --- sfall/FalloutEngine/Enums.h | 28 +++++++++++++++++++++++++++ sfall/FalloutEngine/Functions_def.h | 2 ++ sfall/FalloutEngine/VariableOffsets.h | 2 ++ sfall/FalloutEngine/Variables_def.h | 2 ++ sfall/Modules/Animations.cpp | 24 +++++++++++++++++++++++ 5 files changed, 58 insertions(+) diff --git a/sfall/FalloutEngine/Enums.h b/sfall/FalloutEngine/Enums.h index 2f7872ba..4bcca86d 100644 --- a/sfall/FalloutEngine/Enums.h +++ b/sfall/FalloutEngine/Enums.h @@ -101,6 +101,34 @@ enum AnimCommand : long RB_END_ANIM = 0x200 }; +enum AnimationType : long { + ANIM_TYPE_MOVE_TO_OBJECT = 0, + ANIM_TYPE_MOVE_TO_TILE = 1, + ANIM_TYPE_MOVE_TO_TILE_STRAIGHT = 2, + ANIM_TYPE_MOVE_TO_TILE_STRAIGHT_AND_WAIT_FOR_COMPLETE = 3, + ANIM_TYPE_ANIMATE = 4, + ANIM_TYPE_ANIMATE_REVERSED = 5, + ANIM_TYPE_ANIMATE_AND_HIDE = 6, + ANIM_TYPE_ROTATE_TO_TILE = 7, + ANIM_TYPE_ROTATE_CLOCKWISE = 8, + ANIM_TYPE_ROTATE_COUNTER_CLOCKWISE = 9, + ANIM_TYPE_HIDE = 10, + ANIM_TYPE_CALLBACK = 11, + ANIM_TYPE_CALLBACK3 = 12, + ANIM_TYPE_SET_FLAG = 14, + ANIM_TYPE_UNSET_FLAG = 15, + ANIM_TYPE_TOGGLE_FLAT = 16, + ANIM_TYPE_SET_FID = 17, + ANIM_TYPE_TAKE_OUT_WEAPON = 18, + ANIM_TYPE_SET_LIGHT_DISTANCE = 19, + ANIM_TYPE_MOVE_ON_STAIRS = 20, + ANIM_TYPE_CHECK_FALLING = 23, + ANIM_TYPE_TOGGLE_OUTLINE = 24, + ANIM_TYPE_ANIMATE_FOREVER = 25, + ANIM_TYPE_PING = 26, + ANIM_TYPE_CONTINUE = 28 +}; + enum BodyPart : long { Head = 0, ArmLeft = 1, diff --git a/sfall/FalloutEngine/Functions_def.h b/sfall/FalloutEngine/Functions_def.h index 9d25d90f..9fd50f6f 100644 --- a/sfall/FalloutEngine/Functions_def.h +++ b/sfall/FalloutEngine/Functions_def.h @@ -84,6 +84,7 @@ WRAP_WATCOM_FUNC2(fo::GameObject*, ai_retrieve_object, fo::GameObject*, critter, WRAP_WATCOM_FUNC2(fo::GameObject*, ai_search_environ, fo::GameObject*, critter, long, itemType) WRAP_WATCOM_FUNC1(fo::Program*, allocateProgram, const char*, filePath) WRAP_WATCOM_FUNC2(long, anim_can_use_door, fo::GameObject*, source, fo::GameObject*, object) +WRAP_WATCOM_FUNC1(long, anim_set_end, long, animSetIndex) WRAP_WATCOM_FUNC1(bool, art_exists, long, artFid) WRAP_WATCOM_FUNC0(void, art_flush) WRAP_WATCOM_FUNC1(const char*, art_get_name, long, artFID) @@ -207,6 +208,7 @@ WRAP_WATCOM_FUNC1(bool, obj_is_openable, fo::GameObject*, object) WRAP_WATCOM_FUNC2(long, obj_pid_new, fo::GameObject*, object, long, pid) WRAP_WATCOM_FUNC1(long, obj_lock_is_jammed, fo::GameObject*, object) // Checks/unjams jammed locks WRAP_WATCOM_FUNC1(void, obj_unjam_lock, fo::GameObject*, object) +WRAP_WATCOM_FUNC0(void, object_anim_compact) WRAP_WATCOM_FUNC1(long, partyMemberGetCurLevel, fo::GameObject*, obj) WRAP_WATCOM_FUNC1(void, pc_flag_on, long, flag) WRAP_WATCOM_FUNC2(void, perk_add_effect, fo::GameObject*, critter, long, perkId) diff --git a/sfall/FalloutEngine/VariableOffsets.h b/sfall/FalloutEngine/VariableOffsets.h index 0e46f20a..a71ffad7 100644 --- a/sfall/FalloutEngine/VariableOffsets.h +++ b/sfall/FalloutEngine/VariableOffsets.h @@ -9,6 +9,7 @@ #define FO_VAR_aiInfoList 0x510948 #define FO_VAR_ambient_light 0x51923C #define FO_VAR_anim_set 0x54CC14 +#define FO_VAR_anim_in_anim_stop 0x510724 #define FO_VAR_anon_alias 0x56CAEC #define FO_VAR_art 0x510738 #define FO_VAR_art_name 0x56C9E4 @@ -61,6 +62,7 @@ #define FO_VAR_curr_anim_counter 0x56C7DC #define FO_VAR_curr_font_num 0x51E3B0 #define FO_VAR_curr_pc_stat 0x6681AC +#define FO_VAR_curr_sad 0x510718 #define FO_VAR_curr_stack 0x59E96C #define FO_VAR_current_palette 0x6639D0 #define FO_VAR_currentProgram 0x59E78C diff --git a/sfall/FalloutEngine/Variables_def.h b/sfall/FalloutEngine/Variables_def.h index be3bbc60..30e4f4ce 100644 --- a/sfall/FalloutEngine/Variables_def.h +++ b/sfall/FalloutEngine/Variables_def.h @@ -6,6 +6,7 @@ VAR_(aiInfoList, DWORD) VAR_(ambient_light, DWORD) VARA(anim_set, fo::AnimationSet, 32) +VAR_(anim_in_anim_stop, DWORD) VARA(art, fo::Art, 11) VAR_(art_name, DWORD) VAR_(art_vault_guy_num, DWORD) @@ -41,6 +42,7 @@ VAR_(curr_anim_set, DWORD) VAR_(curr_anim_counter, DWORD) VAR_(curr_font_num, DWORD) VARA(curr_pc_stat, long, fo::PCSTAT_max_pc_stat) +VAR_(curr_sad, DWORD) VAR_(curr_stack, DWORD) VARA(current_palette, fo::PALETTE, 256) // current palette without gamma VAR_(currentProgram, fo::Program*) diff --git a/sfall/Modules/Animations.cpp b/sfall/Modules/Animations.cpp index 01152d6c..b7de99a3 100644 --- a/sfall/Modules/Animations.cpp +++ b/sfall/Modules/Animations.cpp @@ -511,6 +511,28 @@ notDude: } } + +static void __fastcall StopAnimationAtCombatStart() { + fo::var::anim_in_anim_stop = true; + fo::var::curr_anim_set = -1; + + for (int i = 0; i < animationLimit; i++) { + const fo::AnimationSet& set = animSet[i]; + if (set.currentAnim >= 1 && set.animations[set.currentAnim - 1].animType == fo::ANIM_TYPE_ANIMATE_FOREVER) continue; + fo::func::anim_set_end(i); + } + + fo::var::anim_in_anim_stop = false; + fo::func::object_anim_compact(); +} + +static __declspec(naked) void combat_begin_anim_stop_hook() { + __asm { + call StopAnimationAtCombatStart; + retn; + } +} + static void ApplyAnimationsAtOncePatches(signed char aniMax) { //allocate memory to store larger animation struct arrays sf_anim_set.resize(aniMax + 1); // include a dummy @@ -620,6 +642,8 @@ void Animations::init() { HookCall(0x49CFAC, obj_use_container_hook); SafeWrite16(0x4122D9, 0x9090); // action_get_an_object_ } + + HookCall(0x421A48, combat_begin_anim_stop_hook); } //void Animations::exit() {