Skip to content

Commit

Permalink
Implements feature for animations to spawn additional animations.
Browse files Browse the repository at this point in the history
  • Loading branch information
CCHyper authored and ZivDero committed Oct 27, 2024
1 parent 4794f05 commit 8b6a2d3
Show file tree
Hide file tree
Showing 5 changed files with 364 additions and 1 deletion.
125 changes: 125 additions & 0 deletions src/extensions/anim/animext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
******************************************************************************/
#include "animext.h"
#include "anim.h"
#include "animtype.h"
#include "animtypeext.h"
#include "tibsun_inline.h"
#include "wwcrc.h"
#include "extension.h"
#include "asserthandler.h"
Expand Down Expand Up @@ -164,3 +167,125 @@ void AnimClassExtension::Compute_CRC(WWCRCEngine &crc) const
{
//EXT_DEBUG_TRACE("AnimClassExtension::Compute_CRC - Name: %s (0x%08X)\n", Name(), (uintptr_t)(This()));
}


/**
* Processes any start events.
*
* @author: CCHyper
*/
bool AnimClassExtension::Start()
{
AnimTypeClassExtension *animtypeext = Extension::Fetch<AnimTypeClassExtension>(This()->Class);

/**
* #issue-752
*
* Spawns the start animations.
*/
Spawn_Animations(This()->Center_Coord(), animtypeext->StartAnims, animtypeext->StartAnimsCount, animtypeext->StartAnimsMinimum, animtypeext->StartAnimsMaximum);

return true;
}


/**
* Processes any middle events.
*
* @author: CCHyper
*/
bool AnimClassExtension::Middle()
{
AnimTypeClassExtension *animtypeext = Extension::Fetch<AnimTypeClassExtension>(This()->Class);

/**
* #issue-752
*
* Spawns the middle animations.
*/
Spawn_Animations(This()->Center_Coord(), animtypeext->MiddleAnims, animtypeext->MiddleAnimsCount, animtypeext->MiddleAnimsMinimum, animtypeext->MiddleAnimsMaximum);

return true;
}


/**
* Processes any end events.
*
* @author: CCHyper
*/
bool AnimClassExtension::End()
{
AnimTypeClassExtension *animtypeext = Extension::Fetch<AnimTypeClassExtension>(This()->Class);

/**
* #issue-752
*
* Spawns the end animations.
*/
Spawn_Animations(This()->Center_Coord(), animtypeext->EndAnims, animtypeext->EndAnimsCount, animtypeext->EndAnimsMinimum, animtypeext->EndAnimsMaximum);

return true;
}


/**
* #issue-752
*
* Spawns the requested animation from the parsed type lists.
*
* @author: CCHyper
*/
bool AnimClassExtension::Spawn_Animations(const Coordinate &coord, const TypeList<AnimTypeClass *> &animlist, const TypeList<int> &countlist, const TypeList<int> &minlist, const TypeList<int> &maxlist)
{
if (!animlist.Count()) {
return false;
}

/**
* Some checks to make sure values are within expected ranges.
*/
if (!countlist.Count()) {
ASSERT(animlist.Count() == minlist.Count());
ASSERT(animlist.Count() == maxlist.Count());
}

/**
* Iterate over all animations set and spawn them.
*/
for (int index = 0; index < animlist.Count(); ++index) {

const AnimTypeClass *animtype = animlist[index];

int count = 1;

/**
* Pick a random count based on the minimum and maximum values
* defined and spawn the animations.
*/
if (animlist.Count() == countlist.Count()) {
count = countlist[index];

} else if (minlist.Count() && maxlist.Count()) {

int min = minlist[index];
int max = maxlist[index];

if (min != max) {
count = Random_Pick(std::min(min, max), std::max(min, max));
} else {
count = std::min(min, max);
}
}

/**
* Based on the count decided above, spawn the animation type.
*/
for (int i = 0; i < count; ++i) {
AnimClass *anim = new AnimClass(animtype, (Coordinate &)coord);
ASSERT(anim != nullptr);
}
}

return true;
}
10 changes: 10 additions & 0 deletions src/extensions/anim/animext.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@

#include "objectext.h"
#include "anim.h"
#include "ttimer.h"
#include "ftimer.h"
#include "typelist.h"


class AnimClass;
Expand Down Expand Up @@ -63,5 +66,12 @@ AnimClassExtension final : public ObjectClassExtension
virtual const AnimClass *This_Const() const override { return reinterpret_cast<const AnimClass *>(ObjectClassExtension::This_Const()); }
virtual RTTIType What_Am_I() const override { return RTTI_ANIM; }

bool Start();
bool Middle();
bool End();

private:
bool Spawn_Animations(const Coordinate &coord, const TypeList<AnimTypeClass *> &animlist, const TypeList<int> &countlist, const TypeList<int> &minlist, const TypeList<int> &maxlist);

public:
};
99 changes: 99 additions & 0 deletions src/extensions/anim/animext_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "tibsun_globals.h"
#include "tibsun_inline.h"
#include "anim.h"
#include "animext.h"
#include "animext_init.h"
#include "animtype.h"
#include "animtypeext.h"
Expand Down Expand Up @@ -136,6 +137,82 @@ static void Anim_Spawn_Particles(AnimClass *this_ptr)
}


/**
* Calls the AnimClass extension middle event processor.
*
* @author: CCHyper
*/
DECLARE_PATCH(_AnimClass_Start_Ext_Patch)
{
GET_REGISTER_STATIC(AnimClass *, this_ptr, esi);
static AnimClassExtension *animext;

animext = Extension::Fetch<AnimClassExtension>(this_ptr);

animext->Start();

original_code:
_asm { pop esi }
_asm { pop ebx }
_asm { add esp, 0x24 }
_asm { retn }
}


/**
* Calls the AnimClass extension middle event processor.
*
* @author: CCHyper
*/
DECLARE_PATCH(_AnimClass_Middle_Ext_Patch)
{
GET_REGISTER_STATIC(AnimClass *, this_ptr, esi);
static AnimClassExtension *animext;

animext = Extension::Fetch<AnimClassExtension>(this_ptr);

animext->Middle();

original_code:
_asm { pop edi }
_asm { pop esi }
_asm { pop ebp }
_asm { add esp, 0x38 }
_asm { retn }
}


/**
* Calls the AnimClass extension middle event processor.
*
* @author: CCHyper
*/
DECLARE_PATCH(_AnimClass_AI_End_Ext_Patch)
{
GET_REGISTER_STATIC(AnimClass *, this_ptr, esi);
static AnimClassExtension *animext;

animext = Extension::Fetch<AnimClassExtension>(this_ptr);

animext->End();

original_code:
/**
* Restore expected register states.
*/
_asm { mov esi, this_ptr }
_asm { xor ebp, ebp}

/**
* Stolen bytes/code.
*/
_asm { mov edx, [esi+0x64] } // this->Class
_asm { mov ecx, [edx+0x154] } // Class->ChainTo

JMP_REG(edx, 0x00415B03);
}


/**
* #issue-568
*
Expand Down Expand Up @@ -384,6 +461,28 @@ void AnimClassExtension_Hooks()
*/
AnimClassExtension_Init();

Patch_Jump(0x00415F38, &_AnimClass_Start_Ext_Patch);

/**
* This patch removes duplicate return in AnimClass::Middle, so we only
* need to hook one place.
*/
Patch_Jump(0x004162BD, 0x0041637C);

/**
* Unfortunately, this manual patch is required because the code is optimised
* and reuses "this" (ESI), which we need for the ext patch.
*/
Patch_Byte(0x0041636D, 0x8B); // mov esi, [esi+0x68] -> mov ebp, [esi+0x68]
Patch_Byte(0x0041636D+1, 0x6E); // ^
Patch_Byte(0x0041636D+2, 0x68); // ^
Patch_Byte(0x00416370, 0x85); // test esi, esi -> test ebp, ebp
Patch_Byte(0x00416370+1, 0xED); // ^
Patch_Byte(0x00416374, 0x55); // push esi -> push ebp

Patch_Jump(0x0041637C, &_AnimClass_Middle_Ext_Patch);

Patch_Jump(0x00415AFA, &_AnimClass_AI_End_Ext_Patch);
Patch_Jump(0x00415ADA, &_AnimClass_AI_RandomLoop_Randomiser_BugFix_Patch);
//Patch_Jump(0x00413C79, &_AnimClass_Constructor_Init_Class_Values_Patch); // Moved to AnimClassExtension due to patching conflict.
Patch_Jump(0x00414E8F, &_AnimClass_AI_Beginning_Patch);
Expand Down
Loading

0 comments on commit 8b6a2d3

Please sign in to comment.