From 9eb1aa3740622d2fac76231738439d1d35acaa58 Mon Sep 17 00:00:00 2001 From: Belonit Date: Tue, 10 Nov 2020 21:51:55 +0300 Subject: [PATCH] Customizable laser disc radius new tag [WeaponType]->DiskLaser.Radius= (double) --- Phobos.vcxproj | 4 ++ README.md | 2 +- src/Ext/WeaponType/Body.cpp | 98 ++++++++++++++++++++++++++ src/Ext/WeaponType/Body.h | 45 ++++++++++++ src/Ext/WeaponType/DiskLaserRadius.cpp | 47 ++++++++++++ src/Ext/WeaponType/Serialize.hpp | 2 + 6 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 src/Ext/WeaponType/Body.cpp create mode 100644 src/Ext/WeaponType/Body.h create mode 100644 src/Ext/WeaponType/DiskLaserRadius.cpp create mode 100644 src/Ext/WeaponType/Serialize.hpp diff --git a/Phobos.vcxproj b/Phobos.vcxproj index f045ffef36..a17cccb2e6 100644 --- a/Phobos.vcxproj +++ b/Phobos.vcxproj @@ -13,6 +13,8 @@ + + @@ -31,6 +33,8 @@ + + diff --git a/README.md b/README.md index 6eff86a5ba..2d71a4984d 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ - `Deployed.RememberTarget= (boolean)` - makes vehicle-to-building deployer not lose the target on deploy. Defaults to `no` - Fixed the bug when the mind control link was broken on vehicle-to-building deployment and it permanently changed owner - Ability to hide the unstable warning by specifying the build number after `-b=` as a command line arg. (for example, `-b=1` would hide the warning for build 1). **Please, test the features (especially online and edge cases) before disabling it, we can't test everything :)** - +- Customizable laser disk radius via `[WeaponType]->DiskLaser.Radius= (double)` (in voxels). Defaults to `38.2`, which is roughly the default radius used for vanilla saucer. Building diff --git a/src/Ext/WeaponType/Body.cpp b/src/Ext/WeaponType/Body.cpp new file mode 100644 index 0000000000..13e549574c --- /dev/null +++ b/src/Ext/WeaponType/Body.cpp @@ -0,0 +1,98 @@ +#include "Body.h" + +template<> const DWORD Extension::Canary = 0x22222222; +WeaponTypeExt::ExtContainer WeaponTypeExt::ExtMap; + +// ============================= +// load / save + +void WeaponTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) { + auto pThis = this->OwnerObject(); + const char* pSection = pThis->ID; + + if (!pINI->GetSection(pSection)) { + return; + } + + this->DiskLaser_Radius = pINI->ReadDouble(pSection, "DiskLaser.Radius", this->DiskLaser_Radius); + this->DiskLaser_Circumference = (int)(this->DiskLaser_Radius * Math::Pi * 2); +} + +void WeaponTypeExt::ExtData::LoadFromStream(IStream* Stm) { +#define STM_Process(A) Stm->Read(&A, sizeof(A), 0); +#include "Serialize.hpp" +#undef STM_Process +} + +void WeaponTypeExt::ExtData::SaveToStream(IStream* Stm) { +#define STM_Process(A) Stm->Write(&A, sizeof(A), 0); +#include "Serialize.hpp" +#undef STM_Process +} + +// ============================= +// container + +WeaponTypeExt::ExtContainer::ExtContainer() : Container("WeaponTypeClass") { +} + +WeaponTypeExt::ExtContainer::~ExtContainer() = default; + +// ============================= +// container hooks + +DEFINE_HOOK(771EE9, WeaponTypeClass_CTOR, 5) +{ + GET(WeaponTypeClass*, pItem, ESI); + + WeaponTypeExt::ExtMap.FindOrAllocate(pItem); + return 0; +} + +DEFINE_HOOK(77311D, WeaponTypeClass_SDDTOR, 6) +{ + GET(WeaponTypeClass*, pItem, ESI); + + WeaponTypeExt::ExtMap.Remove(pItem); + return 0; +} + +DEFINE_HOOK_AGAIN(772EB0, WeaponTypeClass_SaveLoad_Prefix, 5) +DEFINE_HOOK(772CD0, WeaponTypeClass_SaveLoad_Prefix, 7) +{ + GET_STACK(WeaponTypeClass*, pItem, 0x4); + GET_STACK(IStream*, pStm, 0x8); + + WeaponTypeExt::ExtMap.PrepareStream(pItem, pStm); + + return 0; +} + +DEFINE_HOOK(772EA6, WeaponTypeClass_Load_Suffix, 6) +{ + auto pItem = WeaponTypeExt::ExtMap.Find(WeaponTypeExt::ExtMap.SavingObject); + IStream* pStm = WeaponTypeExt::ExtMap.SavingStream; + + pItem->LoadFromStream(pStm); + return 0; +} + +DEFINE_HOOK(772F8C, WeaponTypeClass_Save, 5) +{ + auto pItem = WeaponTypeExt::ExtMap.Find(WeaponTypeExt::ExtMap.SavingObject); + IStream* pStm = WeaponTypeExt::ExtMap.SavingStream; + + pItem->SaveToStream(pStm); + return 0; +} + +DEFINE_HOOK_AGAIN(7729C7, WeaponTypeClass_LoadFromINI, 5) +DEFINE_HOOK_AGAIN(7729D6, WeaponTypeClass_LoadFromINI, 5) +DEFINE_HOOK(7729B0, WeaponTypeClass_LoadFromINI, 5) +{ + GET(WeaponTypeClass*, pItem, ESI); + GET_STACK(CCINIClass*, pINI, 0xE4); + + WeaponTypeExt::ExtMap.LoadFromINI(pItem, pINI); + return 0; +} diff --git a/src/Ext/WeaponType/Body.h b/src/Ext/WeaponType/Body.h new file mode 100644 index 0000000000..3220af99a3 --- /dev/null +++ b/src/Ext/WeaponType/Body.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include + +#include "../_Container.hpp" +#include "../../Phobos.h" + +#include "../../Utilities/Debug.h" + +class WeaponTypeExt +{ +public: + using base_type = WeaponTypeClass; + + class ExtData final : public Extension + { + public: + + double DiskLaser_Radius; + int DiskLaser_Circumference; + + ExtData(WeaponTypeClass* OwnerObject) : Extension(OwnerObject), + DiskLaser_Radius(38.2), + DiskLaser_Circumference(240) + { } + + virtual void LoadFromINIFile(CCINIClass* pINI) override; + virtual ~ExtData() = default; + + virtual void InvalidatePointer(void* ptr, bool bRemoved) override {} + + virtual void LoadFromStream(IStream* Stm); + + virtual void SaveToStream(IStream* Stm); + }; + + class ExtContainer final : public Container { + public: + ExtContainer(); + ~ExtContainer(); + }; + + static ExtContainer ExtMap; +}; diff --git a/src/Ext/WeaponType/DiskLaserRadius.cpp b/src/Ext/WeaponType/DiskLaserRadius.cpp new file mode 100644 index 0000000000..3d616d4fe3 --- /dev/null +++ b/src/Ext/WeaponType/DiskLaserRadius.cpp @@ -0,0 +1,47 @@ +#include "Body.h" + +int old_Circumference = 240; +DEFINE_HOOK(4A757B, DiskLaser_Circle, 6) +{ + GET(WeaponTypeClass*, pWeapon, EDX); + int new_Circumference = WeaponTypeExt::ExtMap.Find(pWeapon)->DiskLaser_Circumference; + + if (old_Circumference != new_Circumference) { + old_Circumference = new_Circumference; + + Point2D* DiscLaserCoords = reinterpret_cast(0x8A0180); + DiscLaserCoords[0].X = 0; + DiscLaserCoords[0].Y = -1 * new_Circumference; + DiscLaserCoords[1].X = (int)(0.3746065934159128 * new_Circumference); + DiscLaserCoords[1].Y = (int)(-0.9271838545667871 * new_Circumference); + DiscLaserCoords[2].X = (int)(0.707106781186548 * new_Circumference); + DiscLaserCoords[2].Y = -1 * DiscLaserCoords[2].X; + DiscLaserCoords[3].X = (int)(0.9205048534524406 * new_Circumference); + DiscLaserCoords[3].Y = (int)(-0.39073112848927305 * new_Circumference); + DiscLaserCoords[4].X = new_Circumference; + DiscLaserCoords[4].Y = 0; + DiscLaserCoords[5].X = -1 * DiscLaserCoords[1].Y; + DiscLaserCoords[5].Y = DiscLaserCoords[1].X; + DiscLaserCoords[6].X = DiscLaserCoords[2].X; + DiscLaserCoords[6].Y = DiscLaserCoords[2].X; + DiscLaserCoords[7].X = -1 * DiscLaserCoords[3].Y; + DiscLaserCoords[7].Y = DiscLaserCoords[3].X; + DiscLaserCoords[8].X = 0; + DiscLaserCoords[8].Y = DiscLaserCoords[4].X; + DiscLaserCoords[9].X = -1 * DiscLaserCoords[1].X; + DiscLaserCoords[9].Y = DiscLaserCoords[5].X; + DiscLaserCoords[10].X = DiscLaserCoords[2].Y; + DiscLaserCoords[10].Y = DiscLaserCoords[6].Y; + DiscLaserCoords[11].X = -1 * DiscLaserCoords[3].X; + DiscLaserCoords[11].Y = DiscLaserCoords[7].X; + DiscLaserCoords[12].X = DiscLaserCoords[0].Y; + DiscLaserCoords[12].Y = 0; + DiscLaserCoords[13].X = DiscLaserCoords[1].Y; + DiscLaserCoords[13].Y = DiscLaserCoords[9].X; + DiscLaserCoords[14].X = (int)(-0.5735764363510456 * new_Circumference); + DiscLaserCoords[14].Y = (int)(-0.8191520442889921 * new_Circumference); + DiscLaserCoords[15].Y = (int)(-0.9743700647852354 * new_Circumference); + DiscLaserCoords[15].X = (int)(-0.2249510543438644 * new_Circumference); + } + return 0; +} diff --git a/src/Ext/WeaponType/Serialize.hpp b/src/Ext/WeaponType/Serialize.hpp new file mode 100644 index 0000000000..0e14fe4ddd --- /dev/null +++ b/src/Ext/WeaponType/Serialize.hpp @@ -0,0 +1,2 @@ +STM_Process(this->DiskLaser_Radius) +STM_Process(this->DiskLaser_Circumference)