Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements StopSound for AnimTypes and VoxelAnimTypes. #546

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 62 additions & 11 deletions src/extensions/anim/animext_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "cell.h"
#include "rules.h"
#include "scenario.h"
#include "voc.h"
#include "fatal.h"
#include "debughandler.h"
#include "asserthandler.h"
Expand All @@ -48,6 +49,55 @@
#include "hooker_macros.h"


/**
* #issue-475
*
* Implements StopSound for AnimTypes.
*
* @author: CCHyper
*/
static void Sound_Effect_At_Object(VocType sound, ObjectClass *object)
{
Sound_Effect(sound, object->Center_Coord());
}

DECLARE_PATCH(_AnimClass_Remove_This_StopSound_Patch)
{
GET_REGISTER_STATIC(AnimClass *, this_ptr, esi);
static AnimTypeClass *animtype;
static AnimTypeClassExtension *animtypeext;

animtype = this_ptr->Class;

animtypeext = AnimTypeClassExtensions.find(animtype);
if (animtypeext) {

/**
* Has the animation finished playing? StopSound should only
* be played if the animation was able to complete.
*/
if (!this_ptr->IsPlaying) {

/**
* Play the StopSound if one has been defined.
*/
if (animtypeext->StopSound != VOC_NONE) {
Sound_Effect_At_Object(animtypeext->StopSound, this_ptr);
}

}

}

/**
* Stolen bytes/code.
*/
this_ptr->ObjectClass::entry_E4();

JMP_REG(ecx, 0x004167D1);
}


/**
* A fake class for implementing new member functions which allow
* access to the "this" pointer of the intended class.
Expand Down Expand Up @@ -366,21 +416,21 @@ DECLARE_PATCH(_AnimClass_Constructor_Init_Class_Values_Patch)
*/
DECLARE_PATCH(_AnimClass_AI_RandomLoop_Randomiser_BugFix_Patch)
{
GET_REGISTER_STATIC(AnimClass *, this_ptr, esi);
static AnimTypeClass *animtype;
GET_REGISTER_STATIC(AnimClass *, this_ptr, esi);
static AnimTypeClass *animtype;

animtype = reinterpret_cast<AnimTypeClass *>(this_ptr->Class_Of());
animtype = reinterpret_cast<AnimTypeClass *>(this_ptr->Class_Of());

/**
* Generate a random delay using the network synchronized RNG.
*/
this_ptr->Delay = Random_Pick(animtype->RandomLoopDelayMin, animtype->RandomLoopDelayMax);
/**
* Generate a random delay using the network synchronized RNG.
*/
this_ptr->Delay = Random_Pick(animtype->RandomLoopDelayMin, animtype->RandomLoopDelayMax);

/**
* Return from the function.
*/
/**
* Return from the function.
*/
function_return:
JMP(0x00415AF2);
JMP(0x00415AF2);
}


Expand All @@ -401,4 +451,5 @@ void AnimClassExtension_Hooks()
Patch_Jump(0x0041606C, &_AnimClass_Middle_SpawnParticle_Patch);
Patch_Jump(0x00415D30, &AnimClassFake::_In_Which_Layer);
Patch_Jump(0x00413D3E, &_AnimClass_Constructor_Layer_Set_Z_Height_Patch);
Patch_Jump(0x004167CA, &_AnimClass_Remove_This_StopSound_Patch);
}
5 changes: 4 additions & 1 deletion src/extensions/animtype/animtypeext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ AnimTypeClassExtension::AnimTypeClassExtension(AnimTypeClass *this_ptr) :
ZAdjust(0),
AttachLayer(LAYER_NONE),
ParticleToSpawn(PARTICLE_NONE),
NumberOfParticles(0)
NumberOfParticles(0),
StopSound(VOC_NONE)
{
ASSERT(ThisPtr != nullptr);
//EXT_DEBUG_TRACE("AnimTypeClassExtension constructor - Name: %s (0x%08X)\n", ThisPtr->Name(), (uintptr_t)(ThisPtr));
Expand Down Expand Up @@ -165,6 +166,7 @@ void AnimTypeClassExtension::Compute_CRC(WWCRCEngine &crc) const

crc(AttachLayer);
crc(NumberOfParticles);
crc(StopSound);
}


Expand Down Expand Up @@ -224,6 +226,7 @@ bool AnimTypeClassExtension::Read_INI(CCINIClass &ini)
AttachLayer = ini.Get_LayerType(ini_name, "Layer", AttachLayer);
ParticleToSpawn = ini.Get_ParticleType(ini_name, "SpawnsParticle", ParticleToSpawn);
NumberOfParticles = ini.Get_Int(ini_name, "NumParticles", NumberOfParticles);
StopSound = ini.Get_VocType(ini_name, "StopSound", StopSound);

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

#include "extension.h"
#include "container.h"
#include "tibsun_defines.h"


class AnimTypeClass;
Expand Down Expand Up @@ -85,6 +86,11 @@ class AnimTypeClassExtension final : public Extension<AnimTypeClass>
* The number of the particle to spawn.
*/
unsigned NumberOfParticles;

/**
* The sound effect to play when this anim has finished.
*/
VocType StopSound;
};


Expand Down
2 changes: 2 additions & 0 deletions src/extensions/ext_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
#include "terrainext_hooks.h"
#include "superext_hooks.h"
#include "particlesysext_hooks.h"
#include "voxelanimext_hooks.h"

#include "combatext_hooks.h"

Expand Down Expand Up @@ -206,6 +207,7 @@ void Extension_Hooks()
TerrainClassExtension_Hooks();
SuperClassExtension_Hooks();
ParticleSystemClassExtension_Hooks();
VoxelAnimClassExtension_Hooks();

EMPulseClassExtension_Hooks();
WaveClassExtension_Hooks();
Expand Down
90 changes: 90 additions & 0 deletions src/extensions/voxelanim/voxelanimext_hooks.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*******************************************************************************
/* O P E N S O U R C E -- V I N I F E R A **
/*******************************************************************************
*
* @project Vinifera
*
* @file VOXELANIMEXT_HOOKS.CPP
*
* @author CCHyper
*
* @brief Contains the hooks for the extended VoxelAnimClass.
*
* @license Vinifera is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version
* 3 of the License, or (at your option) any later version.
*
* Vinifera is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#include "voxelanimext_hooks.h"
#include "voxelanim.h"
#include "voxelanimtype.h"
#include "voxelanimtypeext.h"
#include "voc.h"
#include "fatal.h"
#include "debughandler.h"
#include "asserthandler.h"

#include "hooker.h"
#include "hooker_macros.h"


/**
* A fake class for implementing new member functions which allow
* access to the "this" pointer of the intended class.
*
* @note: This must not contain a constructor or deconstructor!
* @note: All functions must be prefixed with "_" to prevent accidental virtualization.
*/
class VoxelAnimClassFake final : public VoxelAnimClass
{
public:
void _entry_E4();
};


/**
* Implementation of entry_E4() for VoxelAnimClass.
*/
void VoxelAnimClassFake::_entry_E4()
{
VoxelAnimTypeClassExtension *voxelanimtypeext = nullptr;

/**
* #issue-474
*
* Implements StopSound for VoxelAnimTypes.
*
* @author: CCHyper
*/
voxelanimtypeext = VoxelAnimTypeClassExtensions.find(Class);
if (voxelanimtypeext) {

/**
* Play the StopSound if one has been defined.
*/
if (voxelanimtypeext->StopSound != VOC_NONE) {
Sound_Effect(voxelanimtypeext->StopSound, Center_Coord());
}
}

ObjectClass::entry_E4();
}


/**
* Main function for patching the hooks.
*/
void VoxelAnimClassExtension_Hooks()
{
Change_Virtual_Address(0x006D9134, Get_Func_Address(&VoxelAnimClassFake::_entry_E4));
}
31 changes: 31 additions & 0 deletions src/extensions/voxelanim/voxelanimext_hooks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*******************************************************************************
/* O P E N S O U R C E -- V I N I F E R A **
/*******************************************************************************
*
* @project Vinifera
*
* @file VOXELANIMEXT_HOOKS.H
*
* @author CCHyper
*
* @brief Contains the hooks for the extended VoxelAnimClass.
*
* @license Vinifera is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version
* 3 of the License, or (at your option) any later version.
*
* Vinifera is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#pragma once


void VoxelAnimClassExtension_Hooks();
7 changes: 6 additions & 1 deletion src/extensions/voxelanimtype/voxelanimtypeext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ ExtensionMap<VoxelAnimTypeClass, VoxelAnimTypeClassExtension> VoxelAnimTypeClass
* @author: CCHyper
*/
VoxelAnimTypeClassExtension::VoxelAnimTypeClassExtension(VoxelAnimTypeClass *this_ptr) :
Extension(this_ptr)
Extension(this_ptr),
StopSound(VOC_NONE)
{
ASSERT(ThisPtr != nullptr);
//EXT_DEBUG_TRACE("VoxelAnimTypeClassExtension constructor - Name: %s (0x%08X)\n", ThisPtr->Name(), (uintptr_t)(ThisPtr));
Expand Down Expand Up @@ -155,6 +156,8 @@ void VoxelAnimTypeClassExtension::Compute_CRC(WWCRCEngine &crc) const
{
ASSERT(ThisPtr != nullptr);
//EXT_DEBUG_TRACE("VoxelAnimTypeClassExtension::Compute_CRC - Name: %s (0x%08X)\n", ThisPtr->Name(), (uintptr_t)(ThisPtr));

crc(StopSound);
}


Expand All @@ -174,6 +177,8 @@ bool VoxelAnimTypeClassExtension::Read_INI(CCINIClass &ini)
if (!ini.Is_Present(ini_name)) {
return false;
}

StopSound = ini.Get_VocType(ini_name, "StopSound", StopSound);

return true;
}
5 changes: 4 additions & 1 deletion src/extensions/voxelanimtype/voxelanimtypeext.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ class VoxelAnimTypeClassExtension final : public Extension<VoxelAnimTypeClass>
bool Read_INI(CCINIClass &ini);

public:

/**
* The sound effect to play when this voxel anim has finished.
*/
VocType StopSound;
};


Expand Down