diff --git a/Source/Contents/Effects/SpriteParticle.cpp b/Source/Contents/Effects/SpriteParticle.cpp new file mode 100644 index 00000000..995511e7 --- /dev/null +++ b/Source/Contents/Effects/SpriteParticle.cpp @@ -0,0 +1,62 @@ +#include "Contents/Effects/SpriteParticle.h" +#include "Resource/ResourceMgr.h" +#include "Resource/Sprites/ActionResource.h" +#include "Resource/Sprites/SpriteResource.h" + +// OFFSET: 0x00B40E30 +// FUNCTION: fn_18864 +void CSpriteParticle::UpdateFrame() { + if (!this->action || this->loopMode == 3) { + return; + } + + const long long frameCount = static_cast(this->action->FrameCount(this->animation)); + const long long delay = static_cast(this->frameDelay); + if (delay == 0 || (this->unknown_00E8 >= delay && this->unknown_00E8 % delay == 0)) { + ++this->frame; + } + + switch (this->loopMode) { + case 0: + if (this->frame >= frameCount) { + this->frame = 0; + } + break; + case 1: + if (this->frame >= frameCount) { + this->life = -1.0f; + } + break; + case 2: + if (this->frame >= frameCount) { + this->frame = static_cast(frameCount) - 1; + } + break; + } +} + +// OFFSET: 0x00B41D60 +// FUNCTION: fn_18866 +void CSpriteParticle::SetAction(const char* name) { + if (this->action) { + this->action->Unlock(); + } + + this->action = static_cast(ResourceMgr::Instance().Load(name)); + if (this->action) { + this->action->Lock(); + } +} + +// OFFSET: 0x00B41DA0 +// FUNCTION: fn_18867 +void CSpriteParticle::SetSprite(const char* name) { + if (this->sprite) { + this->sprite->Unlock(); + } + + this->sprite = static_cast(ResourceMgr::Instance().Load(name)); + if (this->sprite) { + this->sprite->Lock(); + } +} diff --git a/Source/Contents/Effects/SpriteParticle.h b/Source/Contents/Effects/SpriteParticle.h new file mode 100644 index 00000000..9d0ca69e --- /dev/null +++ b/Source/Contents/Effects/SpriteParticle.h @@ -0,0 +1,38 @@ +#ifndef RAGNAROK_SOURCE_CONTENTS_EFFECTS_SPRITEPARTICLE_H +#define RAGNAROK_SOURCE_CONTENTS_EFFECTS_SPRITEPARTICLE_H + +#include "Contents/Effects/Particle.h" + +#include + +class CActRes; +class CSprRes; + +class CSpriteParticle : public CParticle { +public: + void UpdateFrame(); + void SetAction(const char* name); + void SetSprite(const char* name); + + /* 02BC */ short unknown_02BC; + /* 02BE */ unsigned char unknown_02BE[2]; + /* 02C0 */ int unknown_02C0; + /* 02C4 */ int unknown_02C4; + /* 02C8 */ vector3d velocity; + /* 02D4 */ int unknown_02D4; + /* 02D8 */ float frameDelay; + /* 02DC */ unsigned char unknown_02DC[4]; + /* 02E0 */ CSprRes* sprite; + /* 02E4 */ CActRes* action; + /* 02E8 */ int animation; + /* 02EC */ int frame; + /* 02F0 */ int loopMode; +}; + +#if defined(_WIN32) && !defined(_WIN64) +static_assert(offsetof(CSpriteParticle, velocity) == 0x2C8); +static_assert(offsetof(CSpriteParticle, frameDelay) == 0x2D8); +static_assert(offsetof(CSpriteParticle, loopMode) == 0x2F0); +#endif + +#endif diff --git a/Source/Contents/Effects/ThrowEffects.cpp b/Source/Contents/Effects/ThrowEffects.cpp new file mode 100644 index 00000000..aad8cd7a --- /dev/null +++ b/Source/Contents/Effects/ThrowEffects.cpp @@ -0,0 +1,33 @@ +#include "Contents/Effects/ThrowEffects.h" +#include "Contents/Effects/Particle.h" + +// OFFSET: 0x00B7D8B0 +// FUNCTION: fn_19234 +void CThrowItemEffect::Slot12() { + switch (this->id) { + case 613: + case 614: + case 615: + case 616: + this->AddEvent(0, "effect\\닌자_던지기.wav", 0, 0); + break; + case 298: + this->AddEvent(0, "_heal_effect.wav", 0, 0); + break; + case 914: + this->AddEvent(0, "effect\\G스포어익스플로젼.wav", 0, 0); + break; + } +} + +// OFFSET: 0x00B7F190 +// FUNCTION: fn_19243 +bool CVolcanoEffect::Slot06() { + for (auto particle = this->particles.begin(); particle != this->particles.end(); ++particle) { + if ((*particle)->alpha > 0) { + return true; + } + } + + return false; +} diff --git a/Source/Contents/Effects/ThrowEffects.h b/Source/Contents/Effects/ThrowEffects.h new file mode 100644 index 00000000..389cbbc8 --- /dev/null +++ b/Source/Contents/Effects/ThrowEffects.h @@ -0,0 +1,28 @@ +#ifndef RAGNAROK_SOURCE_CONTENTS_EFFECTS_THROWEFFECTS_H +#define RAGNAROK_SOURCE_CONTENTS_EFFECTS_THROWEFFECTS_H + +#include "Contents/Effects/Effect.h" + +#include +#include + +class CParticle; + +class CThrowItemEffect : public CEffect { +public: + void Slot12() override; +}; + +class CVolcanoEffect : public CEffect { +public: + bool Slot06() override; + + /* 00CC */ unsigned char unknown_00CC[0x18]; + /* 00E4 */ std::vector particles; +}; + +#if defined(_WIN32) && !defined(_WIN64) +static_assert(offsetof(CVolcanoEffect, particles) == 0xE4); +#endif + +#endif diff --git a/data/compile.json b/data/compile.json index f696f2a3..48802308 100644 --- a/data/compile.json +++ b/data/compile.json @@ -344,6 +344,8 @@ "Source/Contents/Effects/RagEffect.cpp": 4, "Source/Contents/Effects/RagEffectInitialization.cpp": 4, "Source/Contents/Effects/RectUpEffect.cpp": 4, + "Source/Contents/Effects/SpriteParticle.cpp": 4, + "Source/Contents/Effects/ThrowEffects.cpp": 4, "Source/Contents/EmblemCacheRaw.cpp": 4, "Source/Contents/Emblems/EmblemCache.cpp": 2, "Source/Contents/Emblems/EmblemDataDownloadAsyncWork.cpp": 4,