diff --git a/Source/Contents/Actors/GameActor.h b/Source/Contents/Actors/GameActor.h index 1c3aae2..7149ce2 100644 --- a/Source/Contents/Actors/GameActor.h +++ b/Source/Contents/Actors/GameActor.h @@ -7,7 +7,9 @@ class CGameActor : public CRenderObject { public: - /* 0138 */ unsigned char unknown_0138[0x128]; + /* 0138 */ unsigned char unknown_0138[0x100]; + /* 0238 */ unsigned char unknown_0238; + /* 0239 */ unsigned char unknown_0239[0x27]; /* 0260 */ int unknown_0260; /* 0264 */ unsigned char unknown_0264[0x64]; /* 02C8 */ int unknown_02C8; @@ -17,9 +19,15 @@ public: /* 0305 */ unsigned char unknown_0305; /* 0306 */ unsigned char unknown_0306[2]; /* 0308 */ int unknown_0308; - /* 030C */ unsigned char unknown_030C[0xBC]; + /* 030C */ unsigned char unknown_030C[8]; + /* 0314 */ unsigned char unknown_0314; + /* 0315 */ unsigned char unknown_0315[0x63]; + /* 0378 */ float unknown_0378; + /* 037C */ unsigned char unknown_037C[0x4C]; /* 03C8 */ int unknown_03C8; + void SetAnimation(unsigned animation, int motion, int repeat) override; + void SetUnknown0305(unsigned char value, int extra); void RaiseUnknown03C8(int value); void SetUnknown02E4(int value); @@ -28,11 +36,14 @@ public: }; #if defined(_WIN32) && !defined(_WIN64) +static_assert(offsetof(CGameActor, unknown_0238) == 0x238); static_assert(offsetof(CGameActor, unknown_0260) == 0x260); static_assert(offsetof(CGameActor, unknown_02C8) == 0x2C8); static_assert(offsetof(CGameActor, unknown_02E4) == 0x2E4); static_assert(offsetof(CGameActor, unknown_0305) == 0x305); static_assert(offsetof(CGameActor, unknown_0308) == 0x308); +static_assert(offsetof(CGameActor, unknown_0314) == 0x314); +static_assert(offsetof(CGameActor, unknown_0378) == 0x378); static_assert(offsetof(CGameActor, unknown_03C8) == 0x3C8); #endif diff --git a/Source/Contents/Actors/RenderObject.cpp b/Source/Contents/Actors/RenderObject.cpp index 459d8cc..07a2702 100644 --- a/Source/Contents/Actors/RenderObject.cpp +++ b/Source/Contents/Actors/RenderObject.cpp @@ -1,12 +1,18 @@ #include "Contents/Actors/RenderObject.h" +#include "Client/Mode/ActiveGameMode.h" +#include "Client/Mode/CGameMode.h" #include "Client/Replay.h" +#include "Contents/Camera/Camera.h" #include "Contents/Actors/GameActor.h" #include "Resource/ResourceMgr.h" #include "Resource/Sprites/ActionResource.h" #include "Resource/Sprites/SpriteResource.h" +#include "Utility/Math/AffineMatrix.h" #include "Utility/Math/ScalarConversion.h" +#include + #include #include @@ -235,3 +241,101 @@ void CRenderObject::SetAnimationSpeed(float speed) { void CGameActor::SetUnknown02C8(int value) { this->unknown_02C8 = value; } + +// OFFSET: 0x00CBF970 +// FUNCTION: fn_21117 +void CGameActor::SetAnimation(unsigned animation, int motion, int repeat) { + if (this->unknown_0314 == 7) { + if (!this->render.action || static_cast(this->render.action->animations.size()) <= static_cast(animation)) { + return; + } + } + + CRenderObject::SetAnimation(animation, motion, repeat); + this->unknown_0238 = 0; + this->unknown_0378 = -1.0f; +} + +// OFFSET: 0x00CC15F0 +// FUNCTION: fn_21121 +int CRenderObject::HoverHeight() { + this->render.unknown_00F8 += 2; + if (this->render.unknown_00F8 >= 360) { + this->render.unknown_00F8 -= 360; + } + + const short angle = this->render.unknown_00F8; + const int state = this->render.unknown_0070; + if (state == 0 || state == 1 || (this->render.flags & 0x40000) != 0) { + if (this->render.unknown_00FA < 20) { + if (angle % 30 == 0) { + ++this->render.unknown_00FA; + } + } else if (this->render.unknown_00FA > 20 && angle % 30 == 0) { + --this->render.unknown_00FA; + } + } else if (state == 6) { + if (this->render.unknown_00FA < 100) { + if (angle % 30 == 0) { + ++this->render.unknown_00FA; + } + } else if (this->render.unknown_00FA > 100 && angle % 30 == 0) { + --this->render.unknown_00FA; + } + } else if (this->render.unknown_00FA != 0) { + --this->render.unknown_00FA; + } + + const short height = static_cast(ClientSine(angle) * 4.0f + this->render.unknown_00FA); + CGameMode* mode = static_cast(g_world.ActiveGameMode()); + const short scaled = static_cast(400.0f / mode->camera->camera.desiredDistance * height); + return scaled < 0 ? 0 : scaled; +} + +// OFFSET: 0x00CC1810 +// FUNCTION: fn_21123 +void CRenderObject::ScaleByPulse(float& scale) const { + if ((this->render.flags & 0x10) != 0) { + const unsigned index = std::max(this->render.pulsePhases[0] * 4u + 90u, 90u); + if (index < 270) { + scale = ((ClientSine(index) + 1.0f) * 0.25f + 0.5f) * scale; + } else { + scale = scale * 0.5f; + } + } + + if ((this->render.flags & 0x400) != 0) { + const unsigned index = std::max(this->render.pulsePhases[1] * 4u + 90u, 90u); + if (index < 270) { + scale = (1.5f - (ClientSine(index) + 1.0f) * 0.25f) * scale; + } else { + scale = scale * 1.5f; + } + } +} + +// OFFSET: 0x00CC18F0 +// FUNCTION: fn_21124 +void CRenderObject::ApplySwing(int mode, int& x, int& y, int& outX, int& outY) const { + if ((this->render.flags & 0x40) == 0) { + return; + } + + const int swing = static_cast(180.0f - ClientSine(this->render.unknown_00F4 * 5 + 90) * 180.0f); + const int angle = swing >= 360 ? swing - 360 : swing; + if (mode == 1) { + x = static_cast(ClientSine(angle) * 40.0f + x); + y = static_cast(y - (ClientCosine(angle) * 40.0f - 40.0f)); + outX = x; + outY = y; + } else if (mode >= 2) { + x = static_cast(ClientSine(angle) * 10.0f + x); + y = static_cast(y - (ClientCosine(angle) * 10.0f - 10.0f)); + } +} + +// OFFSET: 0x00CC2240 +// FUNCTION: fn_21138 +void CRenderObject::SetInstantValue(int key, std::int64_t value) { + this->render.instant.Set(key, value); +} diff --git a/Source/Contents/Actors/RenderObject.h b/Source/Contents/Actors/RenderObject.h index b8434c8..e1b0c36 100644 --- a/Source/Contents/Actors/RenderObject.h +++ b/Source/Contents/Actors/RenderObject.h @@ -32,6 +32,10 @@ public: unsigned char animation2, unsigned char frame2, unsigned char animation3, unsigned char frame3, unsigned char animation4, unsigned char frame4, int timed, std::uint32_t duration, int loop ); + int HoverHeight(); + void ScaleByPulse(float& scale) const; + void ApplySwing(int mode, int& x, int& y, int& outX, int& outY) const; + void SetInstantValue(int key, std::int64_t value); void SetFrameSequence( unsigned char animation, unsigned char firstFrame, unsigned char lastFrame, unsigned char finishAnimation, unsigned char finishFrame, int timed, std::uint32_t duration, int loop diff --git a/Source/Contents/Actors/RenderObjectState.h b/Source/Contents/Actors/RenderObjectState.h index 5a15614..b8ea9d3 100644 --- a/Source/Contents/Actors/RenderObjectState.h +++ b/Source/Contents/Actors/RenderObjectState.h @@ -78,13 +78,16 @@ struct RenderObjectState { /* 00E4 */ std::uint32_t sequenceDeadline; /* 00E8 */ std::uint32_t flags; /* 00EC */ std::uint32_t unknown_00EC; - /* 00F0 */ std::uint16_t unknown_00F0; + union { + /* 00F0 */ std::uint16_t unknown_00F0; + /* 00F0 */ unsigned char pulsePhases[2]; + }; /* 00F2 */ unsigned char unknown_00F2; /* 00F3 */ unsigned char unknown_00F3; - /* 00F4 */ std::uint16_t unknown_00F4; + /* 00F4 */ short unknown_00F4; /* 00F6 */ unsigned char unknown_00F6; /* 00F7 */ unsigned char unknown_00F7; - /* 00F8 */ std::uint16_t unknown_00F8; + /* 00F8 */ short unknown_00F8; /* 00FA */ unsigned char unknown_00FA; /* 00FB */ unsigned char unknown_00FB; /* 00FC */ std::uint32_t unknown_00FC;