From b183014bd22cdbce702e5ec0cac1f7185b36f9c0 Mon Sep 17 00:00:00 2001 From: CCHyper <73803386+CCHyper@users.noreply.github.com> Date: Wed, 30 Jun 2021 18:20:47 +0100 Subject: [PATCH] Implements StopSound for VoxelAnimTypes. --- src/extensions/ext_hooks.cpp | 2 + .../voxelanim/voxelanimext_hooks.cpp | 90 +++++++++++++++++++ src/extensions/voxelanim/voxelanimext_hooks.h | 31 +++++++ .../voxelanimtype/voxelanimtypeext.cpp | 7 +- .../voxelanimtype/voxelanimtypeext.h | 5 +- 5 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 src/extensions/voxelanim/voxelanimext_hooks.cpp create mode 100644 src/extensions/voxelanim/voxelanimext_hooks.h diff --git a/src/extensions/ext_hooks.cpp b/src/extensions/ext_hooks.cpp index c3fb170d0..45b363274 100644 --- a/src/extensions/ext_hooks.cpp +++ b/src/extensions/ext_hooks.cpp @@ -90,6 +90,7 @@ #include "terrainext_hooks.h" #include "superext_hooks.h" #include "particlesysext_hooks.h" +#include "voxelanimext_hooks.h" #include "combatext_hooks.h" @@ -182,6 +183,7 @@ void Extension_Hooks() TerrainClassExtension_Hooks(); SuperClassExtension_Hooks(); ParticleSystemClassExtension_Hooks(); + VoxelAnimClassExtension_Hooks(); CombatExtension_Hooks(); diff --git a/src/extensions/voxelanim/voxelanimext_hooks.cpp b/src/extensions/voxelanim/voxelanimext_hooks.cpp new file mode 100644 index 000000000..a86aace2d --- /dev/null +++ b/src/extensions/voxelanim/voxelanimext_hooks.cpp @@ -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 . + * + ******************************************************************************/ +#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)); +} diff --git a/src/extensions/voxelanim/voxelanimext_hooks.h b/src/extensions/voxelanim/voxelanimext_hooks.h new file mode 100644 index 000000000..4b6fa5535 --- /dev/null +++ b/src/extensions/voxelanim/voxelanimext_hooks.h @@ -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 . + * + ******************************************************************************/ +#pragma once + + +void VoxelAnimClassExtension_Hooks(); diff --git a/src/extensions/voxelanimtype/voxelanimtypeext.cpp b/src/extensions/voxelanimtype/voxelanimtypeext.cpp index d892bd16f..9e831634f 100644 --- a/src/extensions/voxelanimtype/voxelanimtypeext.cpp +++ b/src/extensions/voxelanimtype/voxelanimtypeext.cpp @@ -44,7 +44,8 @@ ExtensionMap VoxelAnimTypeClass * @author: CCHyper */ VoxelAnimTypeClassExtension::VoxelAnimTypeClassExtension(VoxelAnimTypeClass *this_ptr) : - Extension(this_ptr) + Extension(this_ptr), + StopSound(VOC_NONE) { ASSERT(ThisPtr != nullptr); //DEV_DEBUG_TRACE("VoxelAnimTypeClassExtension constructor - Name: %s (0x%08X)\n", ThisPtr->Name(), (uintptr_t)(ThisPtr)); @@ -155,6 +156,8 @@ void VoxelAnimTypeClassExtension::Compute_CRC(WWCRCEngine &crc) const { ASSERT(ThisPtr != nullptr); //DEV_DEBUG_TRACE("VoxelAnimTypeClassExtension::Compute_CRC - Name: %s (0x%08X)\n", ThisPtr->Name(), (uintptr_t)(ThisPtr)); + + crc(StopSound); } @@ -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; } diff --git a/src/extensions/voxelanimtype/voxelanimtypeext.h b/src/extensions/voxelanimtype/voxelanimtypeext.h index 35c4d414a..30add92d1 100644 --- a/src/extensions/voxelanimtype/voxelanimtypeext.h +++ b/src/extensions/voxelanimtype/voxelanimtypeext.h @@ -52,7 +52,10 @@ class VoxelAnimTypeClassExtension final : public Extension bool Read_INI(CCINIClass &ini); public: - + /** + * The sound effect to play when this voxel anim has finished. + */ + VocType StopSound; };