From eeceefed66e4eb1e6ebbcdcb2cfe50e59fc9fac0 Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Fri, 30 Oct 2026 01:35:50 +0000 Subject: [PATCH] Decompile 14 functions in Source/Contents/Effects/FlowerCastingEffect.cpp, Source/Contents/Effects/FlowerCastingEffect.h, ... Batch #4160 by youko: 4 byte-identical, 10 confirmed by peer review. - fn_19059 CFlowerCastingEffect::AddRing: logic confirmed by peer review - fn_19060 CFlowerCastingEffect::Close: byte-identical - fn_19061 CFlowerCastingEffect::Slot01: logic confirmed by peer review - fn_19062 CFlowerCastingEffect::Slot06: byte-identical - fn_19063 CFlowerCastingEffect::Slot03: logic confirmed by peer review - fn_19064 CFlowerCastingEffect::Slot04: logic confirmed by peer review - fn_19065 CHealEffect::CHealEffect: logic confirmed by peer review - fn_19067 CHealEffect::AddSparks: logic confirmed by peer review - fn_19068 CHealEffect::AddColumn: logic confirmed by peer review - fn_19069 CHealEffect::AddCone: logic confirmed by peer review - fn_19071 CHealEffect::Close: byte-identical - fn_19072 CHealEffect::Slot01: byte-identical - fn_19073 CHealEffect::Slot12: logic confirmed by peer review - fn_19074 CHealEffect::SpawnParticles: logic confirmed by peer review Peer-reviewed-by: Yommy, superintelligence, tayoba Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). Adds to the build: Source/Contents/Effects/FlowerCastingEffect.cpp, Source/Contents/Effects/HealEffect.cpp --- .../Contents/Effects/FlowerCastingEffect.cpp | 199 ++++++++++ Source/Contents/Effects/FlowerCastingEffect.h | 34 ++ Source/Contents/Effects/HealEffect.cpp | 362 ++++++++++++++++++ Source/Contents/Effects/HealEffect.h | 46 +++ data/compile.json | 2 + 5 files changed, 643 insertions(+) create mode 100644 Source/Contents/Effects/FlowerCastingEffect.cpp create mode 100644 Source/Contents/Effects/FlowerCastingEffect.h create mode 100644 Source/Contents/Effects/HealEffect.cpp create mode 100644 Source/Contents/Effects/HealEffect.h diff --git a/Source/Contents/Effects/FlowerCastingEffect.cpp b/Source/Contents/Effects/FlowerCastingEffect.cpp new file mode 100644 index 00000000..1988044a --- /dev/null +++ b/Source/Contents/Effects/FlowerCastingEffect.cpp @@ -0,0 +1,199 @@ +#include "Contents/Effects/FlowerCastingEffect.h" + +#include "Client/Mode/CGameMode.h" +#include "Client/Mode/ModeMgr.h" +#include "Contents/Actors/RenderObject.h" +#include "Contents/Effects/EffectMemoryMgr.h" +#include "Contents/Effects/Particle.h" +#include "Contents/Sound/SoundMgr.h" +#include "Contents/World/World.h" +#include "Utility/Math/AffineMatrix.h" + +#include + +// OFFSET: 0x00B66870 +// FUNCTION: fn_19059 +void CFlowerCastingEffect::AddRing(int kind) { + for (int ring = 0; ring < 4; ++ring) { + for (int segment = 0; segment < 21; ++segment) { + CParticle* particle = CreateParticle(reinterpret_cast(this->position), 5); + if (!particle) { + continue; + } + + particle->unknown_0004 = this->id; + particle->unknown_000C = segment; + particle->unknown_0010 = ring; + particle->unknown_0008 = 1; + particle->SetTexture("effect\\ring_blue.tga"); + particle->unknown_0050 = 315; + particle->alpha = 0; + + float& baseAngle = *reinterpret_cast(&particle->unknown_00C4); + if (kind == 0) { + if (ring == 0) { + particle->scale = 4.5f; + particle->unknown_004C = 85; + particle->unknown_00C0 = 27.0f; + baseAngle = 0.0f; + } else if (ring == 1) { + particle->scale = 5.0f; + particle->unknown_004C = 80; + particle->unknown_00C0 = 28.0f; + baseAngle = 90.0f; + } else if (ring == 2) { + particle->scale = 5.5f; + particle->unknown_004C = 70; + particle->unknown_00C0 = 29.0f; + baseAngle = 180.0f; + } else if (ring == 3) { + particle->scale = 5.0f; + particle->unknown_004C = 75; + particle->unknown_00C0 = 30.0f; + baseAngle = 270.0f; + } + } else if (kind == 1) { + if (ring == 0) { + particle->scale = 5.5f; + particle->unknown_004C = 50; + particle->unknown_00C0 = 30.0f; + baseAngle = 90.0f; + } else if (ring == 1) { + particle->scale = 6.0f; + particle->unknown_004C = 55; + particle->unknown_00C0 = 29.0f; + baseAngle = 180.0f; + } else if (ring == 2) { + particle->scale = 6.5f; + particle->unknown_004C = 65; + particle->unknown_00C0 = 28.0f; + baseAngle = 270.0f; + } else if (ring == 3) { + particle->scale = 6.0f; + particle->unknown_004C = 60; + particle->unknown_00C0 = 27.0f; + baseAngle = 0.0f; + } + } + + particle->SetColor(100, 100, 255); + particle->unknown_0054 = 0.0f; + *reinterpret_cast(particle->unknown_0058) = particle->unknown_00C0; + InitParticleQuad(particle->vertices); + this->particles.push_back(particle); + } + } +} + +// OFFSET: 0x00B66C60 +// FUNCTION: fn_19060 +void CFlowerCastingEffect::Close() { + for (auto it = this->particles.begin(); it != this->particles.end(); ++it) { + FreeParticle(*it); + } + + this->particles.clear(); +} + +// OFFSET: 0x00B66CA0 +// FUNCTION: fn_19061 +void CFlowerCastingEffect::Slot01() { + this->unknown_002C = 400; + + CWorld* world = static_cast(g_modeMgr.GetGameMode())->scene; + const vector3d& player = reinterpret_cast(world->player)->render.position; + g_soundMgr->PlayWave("effect\\T_안락한마법.wav", this->position[0] - player.x, 0.0f, this->position[2] - player.z, 250, 40, 1.0f, 0); + + this->AddRing(0); + this->AddRing(1); +} + +// OFFSET: 0x00B66D20 +// FUNCTION: fn_19062 +bool CFlowerCastingEffect::Slot06() { + return !this->IsFinished(); +} + +// OFFSET: 0x00B66D30 +// FUNCTION: fn_19063 +void CFlowerCastingEffect::Slot03() { + for (auto it = this->particles.begin(); it != this->particles.end(); ++it) { + (*it)->position.x = this->position[0]; + (*it)->position.y = this->position[1]; + (*it)->position.z = this->position[2]; + + CParticle* particle = *it; + if (particle && particle->unknown_00E8 > 0) { + float radius = g_sinTable[particle->unknown_00E8 % 90 * 4] * 2.5f + *reinterpret_cast(particle->unknown_0058); + particle->unknown_00C0 = radius; + + const int age = particle->unknown_00E8; + int alpha = particle->alpha; + if (age > 110) { + alpha = (std::max)(alpha - 1, 0); + } else if (age < 20) { + alpha = (std::min)(alpha + 5, 180); + } + particle->alpha = alpha; + + const int segment = particle->unknown_000C; + radius *= g_sinTable[segment * 9]; + if (age <= 90) { + radius *= g_sinTable[age]; + } + radius = (std::max)(radius, 0.0f); + + const float baseAngle = *reinterpret_cast(&particle->unknown_00C4); + const int angle = static_cast(static_cast(particle->unknown_0050 / 20.0f) * segment + baseAngle) % 360; + const int tilt = particle->unknown_004C; + const float spread = radius * g_cosTable[tilt]; + const float height = radius * g_sinTable[tilt]; + const float cosine = g_cosTable[angle]; + const float sine = g_sinTable[angle]; + + vector3d points[2] = {}; + points[0].x = particle->scale * cosine; + points[0].y = 0.0f; + points[0].z = particle->scale * sine; + points[1].x = points[0].x + spread * cosine; + points[1].y = 0.0f - height; + points[1].z = points[0].z + spread * sine; + + particle->vertices[3].x = points[0].x; + particle->vertices[3].y = points[0].y; + particle->vertices[3].z = points[0].z; + particle->vertices[1].x = points[1].x; + particle->vertices[1].y = points[1].y; + particle->vertices[1].z = points[1].z; + + if (segment != 0) { + particle->vertices[0].x = this->lastOuter.x; + particle->vertices[0].y = this->lastOuter.y; + particle->vertices[0].z = this->lastOuter.z; + particle->vertices[2].x = this->lastInner.x; + particle->vertices[2].y = this->lastInner.y; + particle->vertices[2].z = this->lastInner.z; + } + + this->lastInner = points[0]; + this->lastOuter = points[1]; + } + + ++(*it)->unknown_00E8; + } +} + +// OFFSET: 0x00B671E0 +// FUNCTION: fn_19064 +void CFlowerCastingEffect::Slot04() { + for (auto it = this->particles.begin(); it != this->particles.end(); ++it) { + CParticle* particle = *it; + if (!particle || particle->unknown_000C <= 0) { + continue; + } + + const int segment = particle->unknown_000C; + const ParticleQuad quad = {false, 0.0f, 1.0f, static_cast(segment - 1) / 21.0f, static_cast(segment) / 21.0f, false, true}; + particle->Render(quad); + } +} diff --git a/Source/Contents/Effects/FlowerCastingEffect.h b/Source/Contents/Effects/FlowerCastingEffect.h new file mode 100644 index 00000000..02ca0bdd --- /dev/null +++ b/Source/Contents/Effects/FlowerCastingEffect.h @@ -0,0 +1,34 @@ +#ifndef RAGNAROK_SOURCE_CONTENTS_EFFECTS_FLOWERCASTINGEFFECT_H +#define RAGNAROK_SOURCE_CONTENTS_EFFECTS_FLOWERCASTINGEFFECT_H + +#include "Contents/Effects/Effect.h" +#include "Utility/Math/Vector3d.h" + +#include +#include + +class CParticle; + +class CFlowerCastingEffect : public CEffect { +public: + void Slot01() override; + void Slot03() override; + void Slot04() override; + void Close() override; + bool Slot06() override; + + void AddRing(int kind); + + /* 00CC */ vector3d lastInner; + /* 00D8 */ vector3d lastOuter; + /* 00E4 */ std::vector particles; +}; + +#if defined(_WIN32) && !defined(_WIN64) +static_assert(sizeof(CFlowerCastingEffect) == 0xF0); +static_assert(offsetof(CFlowerCastingEffect, lastInner) == 0xCC); +static_assert(offsetof(CFlowerCastingEffect, lastOuter) == 0xD8); +static_assert(offsetof(CFlowerCastingEffect, particles) == 0xE4); +#endif + +#endif diff --git a/Source/Contents/Effects/HealEffect.cpp b/Source/Contents/Effects/HealEffect.cpp new file mode 100644 index 00000000..b7419b77 --- /dev/null +++ b/Source/Contents/Effects/HealEffect.cpp @@ -0,0 +1,362 @@ +#include "Contents/Effects/HealEffect.h" + +#include "Contents/Effects/EffectMemoryMgr.h" +#include "Contents/Effects/Particle.h" + +#include +#include + +// OFFSET: 0x00B67310 +// FUNCTION: fn_19065 +CHealEffect::CHealEffect() : CEffect(-1), columnEdge{}, coneEdge{} { + this->spawnTick = 0; +} + +// OFFSET: 0x00B67530 +// FUNCTION: fn_19067 +void CHealEffect::AddSparks(int kind) { + for (int index = 0; index < 4; ++index) { + CParticle* particle = CreateParticle(reinterpret_cast(this->position), 5); + if (!particle) { + continue; + } + + particle->unknown_0004 = this->id; + particle->unknown_000C = index; + particle->unknown_0010 = 0; + particle->unknown_0008 = 1; + particle->SetTexture("effect\\pok1.tga"); + particle->alpha = 0; + particle->unknown_00C4 = 0; + particle->unknown_0050 = 0; + + const int driftZ = (std::max)(rand() % 13, 0); + const int driftX = (std::max)(rand() % 13, 0); + particle->unknown_00D4 = 0.0f; + particle->unknown_00D0 = static_cast(driftX - 6); + particle->unknown_00D8 = static_cast(driftZ - 6); + particle->SetColor(220, 250, 220); + InitParticleQuad(particle->vertices); + this->sparkParticles.push_back(particle); + + switch (kind) { + case 0: + case 3: + case 6: + particle->scale = static_cast((std::max)(rand() % 10, 0)) * 0.1f + 2.0f; + particle->unknown_0054 = static_cast((std::max)(rand() % 40, 0)) * 0.01f + 0.4f; + break; + case 1: + particle->scale = static_cast((std::max)(rand() % 10, 0)) * 0.1f + 2.0f; + particle->unknown_0054 = static_cast((std::max)(rand() % 40, 0)) * 0.01f + 0.6f; + break; + case 2: + particle->scale = static_cast((std::max)(rand() % 40, 0)) * 0.1f + 0.4f; + particle->unknown_0054 = static_cast((std::max)(rand() % 40, 0)) * 0.01f + 0.4f; + break; + case 4: + particle->scale = static_cast((std::max)(rand() % 10, 0)) * 0.1f + 2.0f; + particle->unknown_0054 = static_cast((std::max)(rand() % 40, 0)) * 0.01f + 0.3f; + break; + case 7: + particle->scale = static_cast((std::max)(rand() % 10, 0)) * 0.1f + 2.0f; + particle->unknown_0054 = static_cast((std::max)(rand() % 40, 0)) * 0.01f + 0.4f; + particle->SetColor(0, 255, 255); + break; + case 8: + particle->scale = static_cast((std::max)(rand() % 10, 0)) * 0.1f + 2.0f; + particle->unknown_0054 = static_cast((std::max)(rand() % 40, 0)) * 0.01f + 0.4f; + particle->SetColor(255, 255, 0); + break; + } + } +} + +// OFFSET: 0x00B678F0 +// FUNCTION: fn_19068 +void CHealEffect::AddColumn(int kind) { + const float randomHeight = static_cast((std::max)(rand() % 20, 0)) + 40.0f; + for (int row = 0, angle = 0; angle < 360; ++row, angle += 180) { + const int randomAngle = (std::max)(rand() % 360, 0); + for (int segment = 0; segment < 21; ++segment) { + CParticle* particle = CreateParticle(reinterpret_cast(this->position), 5); + if (!particle) { + continue; + } + + particle->unknown_0004 = this->id; + particle->unknown_000C = segment; + particle->unknown_0010 = row; + particle->unknown_0008 = 1; + particle->unknown_0050 = 360; + particle->alpha = 0; + particle->unknown_004C = 90; + particle->unknown_0054 = 0.0f; + + float& baseAngle = *reinterpret_cast(&particle->unknown_00C4); + switch (kind) { + case 0: + particle->SetTexture("effect\\ring_white.tga"); + particle->unknown_00C0 = 60.0f; + baseAngle = static_cast(angle); + particle->scale = static_cast(row) * 0.4f + 4.6f; + particle->SetColor(140, 210, 140); + this->columnLifetime = 60; + break; + case 1: + particle->SetTexture("effect\\ring_white.tga"); + particle->unknown_00C0 = 60.0f; + baseAngle = static_cast(angle); + particle->scale = static_cast(row) * 0.4f + 4.6f; + particle->SetColor(140, 210, 140); + this->columnLifetime = 40; + break; + case 2: + particle->SetTexture("effect\\alpha_down.tga"); + particle->unknown_00C0 = 90.0f; + baseAngle = static_cast(angle); + particle->scale = static_cast(row) * 0.1f + 4.2f; + particle->SetColor(140, 210, 140); + this->columnLifetime = 40; + break; + case 3: + particle->SetTexture("effect\\alpha_down.tga"); + particle->unknown_00C0 = randomHeight; + baseAngle = static_cast(randomAngle); + particle->scale = static_cast((std::max)(rand() % 100, 0)) * 0.005f + 4.5f + static_cast(row) * 0.2f; + particle->SetColor(255, 255, 255); + this->columnLifetime = 30; + break; + case 4: + particle->SetTexture("effect\\alpha_down.tga"); + particle->unknown_00C0 = static_cast((std::max)(rand() % 20, 0) * row) + 40.0f; + baseAngle = static_cast(randomAngle); + particle->scale = static_cast(row) * 0.2f + 4.6f; + particle->SetColor(140, 210, 140); + this->columnLifetime = 60; + break; + case 5: + particle->SetTexture("effect\\ring_blue.tga"); + particle->unknown_00C0 = 60.0f; + baseAngle = static_cast(angle); + particle->scale = static_cast(row) * 0.4f + 4.6f; + particle->SetColor(100, 100, 255); + this->columnLifetime = 40; + break; + case 6: + particle->SetTexture("effect\\ring_white.tga"); + particle->unknown_00C0 = 60.0f; + baseAngle = static_cast(angle); + particle->scale = static_cast(row) * 0.4f + 4.6f; + particle->SetColor(115, 25, 115); + this->columnLifetime = 60; + break; + case 7: + particle->SetTexture("effect\\alpha_down.tga"); + particle->unknown_00C0 = static_cast((std::max)(rand() % 20, 0) * row) + 40.0f; + baseAngle = static_cast(randomAngle); + particle->scale = static_cast(row) * 0.2f + 4.6f; + particle->SetColor(0, 255, 255); + this->columnLifetime = 60; + break; + case 8: + particle->SetTexture("effect\\alpha_down.tga"); + particle->unknown_00C0 = static_cast((std::max)(rand() % 20, 0) * row) + 40.0f; + baseAngle = static_cast(randomAngle); + particle->scale = static_cast(row) * 0.2f + 4.6f; + particle->SetColor(255, 255, 0); + this->columnLifetime = 60; + break; + } + + InitParticleQuad(particle->vertices); + this->columnParticles.push_back(particle); + } + } +} + +// OFFSET: 0x00B67D10 +// FUNCTION: fn_19069 +void CHealEffect::AddCone(int kind) { + for (int row = 0, tilt = 50; tilt > 46; ++row, tilt -= 2) { + const int randomAngle = (std::max)(rand() % 360, 0); + for (int segment = 0; segment < 21; ++segment) { + CParticle* particle = CreateParticle(reinterpret_cast(this->position), 5); + if (!particle) { + continue; + } + + particle->unknown_0004 = this->id; + particle->unknown_000C = segment; + particle->unknown_0010 = row; + particle->unknown_0008 = 1; + particle->unknown_0050 = 360; + particle->alpha = 0; + particle->unknown_0054 = 0.0f; + + float& baseAngle = *reinterpret_cast(&particle->unknown_00C4); + switch (kind) { + case 0: + particle->SetTexture("effect\\ring_white.tga"); + baseAngle = static_cast(randomAngle); + particle->unknown_00C0 = 12.0f; + particle->scale = static_cast(row) * 0.2f + 5.0f; + particle->unknown_004C = tilt; + particle->SetColor(140, 210, 140); + this->coneLifetime = 60; + break; + case 1: + particle->SetTexture("effect\\ring_white.tga"); + baseAngle = static_cast(randomAngle); + particle->unknown_00C0 = 18.0f; + particle->scale = static_cast(row) * 0.2f + 5.0f; + particle->unknown_004C = tilt; + particle->SetColor(140, 210, 140); + this->coneLifetime = 40; + break; + case 2: + particle->SetTexture("effect\\alpha_down.tga"); + baseAngle = static_cast(randomAngle); + particle->unknown_00C0 = 10.0f; + particle->scale = static_cast(row) * 0.1f + 5.3f; + particle->unknown_004C = tilt - 4; + particle->SetColor(140, 210, 140); + this->coneLifetime = 30; + break; + case 5: + particle->SetTexture("effect\\ring_blue.tga"); + baseAngle = static_cast(randomAngle); + particle->unknown_00C0 = 18.0f; + particle->scale = static_cast(row) * 0.2f + 5.0f; + particle->unknown_004C = tilt; + particle->SetColor(100, 100, 255); + this->coneLifetime = 40; + break; + } + + InitParticleQuad(particle->vertices); + this->coneParticles.push_back(particle); + } + } +} + +// OFFSET: 0x00B686D0 +// FUNCTION: fn_19071 +void CHealEffect::Close() { + for (auto it = this->columnParticles.begin(); it != this->columnParticles.end(); ++it) { + FreeParticle(*it); + } + this->columnParticles.clear(); + + for (auto it = this->coneParticles.begin(); it != this->coneParticles.end(); ++it) { + FreeParticle(*it); + } + this->coneParticles.clear(); + + for (auto it = this->sparkParticles.begin(); it != this->sparkParticles.end(); ++it) { + FreeParticle(*it); + } + this->sparkParticles.clear(); +} + +// OFFSET: 0x00B68770 +// FUNCTION: fn_19072 +void CHealEffect::Slot01() { + this->unknown_002C = 100; +} + +// OFFSET: 0x00B68780 +// FUNCTION: fn_19073 +void CHealEffect::Slot12() { + switch (this->id) { + case 253: + this->AddEvent(0, "effect\\흡기.wav", 0, 0); + break; + case 312: + case 313: + case 320: + case 325: + this->AddEvent(0, "_heal_effect.wav", 0, 0); + break; + } +} + +// OFFSET: 0x00B68830 +// FUNCTION: fn_19074 +void CHealEffect::SpawnParticles() { + switch (this->id) { + case 253: + if (this->spawnTick == 0) { + this->AddColumn(5); + this->AddCone(5); + } + break; + case 312: + if (this->spawnTick == 0) { + this->AddColumn(4); + } + if (this->spawnTick <= 50 && this->spawnTick % 6 == 0) { + this->AddSparks(4); + } + break; + case 313: + if (this->spawnTick == 0) { + this->AddColumn(0); + this->AddCone(0); + } + if (this->spawnTick <= 50 && this->spawnTick % 6 == 0) { + this->AddSparks(0); + } + break; + case 320: + if (this->spawnTick == 0) { + this->AddColumn(3); + } + if (this->spawnTick <= 25 && this->spawnTick % 6 == 0) { + this->AddSparks(3); + } + break; + case 325: + if (this->spawnTick == 0) { + this->AddColumn(1); + this->AddCone(1); + } + if (this->spawnTick == 1) { + this->AddColumn(2); + this->AddCone(2); + } + if (this->spawnTick <= 50 && this->spawnTick % 6 == 0) { + this->AddSparks(1); + } + if (this->spawnTick <= 50 && this->spawnTick % 9 == 2) { + this->AddSparks(2); + } + break; + case 1113: + if (this->spawnTick == 0) { + this->AddColumn(6); + } + if (this->spawnTick <= 50 && this->spawnTick % 6 == 0) { + this->AddSparks(6); + } + break; + case 1143: + if (this->spawnTick == 0) { + this->AddColumn(7); + } + if (this->spawnTick <= 50 && this->spawnTick % 6 == 0) { + this->AddSparks(7); + } + break; + case 1144: + if (this->spawnTick == 0) { + this->AddColumn(8); + } + if (this->spawnTick <= 50 && this->spawnTick % 6 == 0) { + this->AddSparks(8); + } + break; + } + + ++this->spawnTick; +} diff --git a/Source/Contents/Effects/HealEffect.h b/Source/Contents/Effects/HealEffect.h new file mode 100644 index 00000000..a78be5df --- /dev/null +++ b/Source/Contents/Effects/HealEffect.h @@ -0,0 +1,46 @@ +#ifndef RAGNAROK_SOURCE_CONTENTS_EFFECTS_HEALEFFECT_H +#define RAGNAROK_SOURCE_CONTENTS_EFFECTS_HEALEFFECT_H + +#include "Contents/Effects/Effect.h" +#include "Utility/Math/Vector3d.h" + +#include +#include + +class CParticle; + +class CHealEffect : public CEffect { +public: + CHealEffect(); + + void Slot01() override; + void Close() override; + void Slot12() override; + + void AddSparks(int kind); + void AddColumn(int kind); + void AddCone(int kind); + void SpawnParticles(); + + /* 00CC */ vector3d columnEdge[2]; + /* 00E4 */ vector3d coneEdge[2]; + /* 00FC */ int columnLifetime; + /* 0100 */ int coneLifetime; + /* 0104 */ int spawnTick; + /* 0108 */ std::vector columnParticles; + /* 0114 */ std::vector coneParticles; + /* 0120 */ std::vector sparkParticles; +}; + +#if defined(_WIN32) && !defined(_WIN64) +static_assert(sizeof(CHealEffect) == 0x12C); +static_assert(offsetof(CHealEffect, columnEdge) == 0xCC); +static_assert(offsetof(CHealEffect, coneEdge) == 0xE4); +static_assert(offsetof(CHealEffect, columnLifetime) == 0xFC); +static_assert(offsetof(CHealEffect, spawnTick) == 0x104); +static_assert(offsetof(CHealEffect, columnParticles) == 0x108); +static_assert(offsetof(CHealEffect, coneParticles) == 0x114); +static_assert(offsetof(CHealEffect, sparkParticles) == 0x120); +#endif + +#endif diff --git a/data/compile.json b/data/compile.json index e4fdfc51..20ea3bbe 100644 --- a/data/compile.json +++ b/data/compile.json @@ -357,9 +357,11 @@ "Source/Contents/Effects/EnergyOrbEffect.cpp": 4, "Source/Contents/Effects/EvilLandEffect.cpp": 4, "Source/Contents/Effects/EvilsPawEffect.cpp": 4, + "Source/Contents/Effects/FlowerCastingEffect.cpp": 4, "Source/Contents/Effects/FortuneKissEffect.cpp": 4, "Source/Contents/Effects/FriggSongEffect.cpp": 4, "Source/Contents/Effects/FuumaShouakuEffect.cpp": 4, + "Source/Contents/Effects/HealEffect.cpp": 4, "Source/Contents/Effects/JupitelThunderStormEffect.cpp": 4, "Source/Contents/Effects/LightSphereEffect.cpp": 4, "Source/Contents/Effects/MagicFloorEffect.cpp": 4,