diff --git a/Source/Contents/Effects/EvilLandEffect.cpp b/Source/Contents/Effects/EvilLandEffect.cpp index b0b69e94..35ba6e2e 100644 --- a/Source/Contents/Effects/EvilLandEffect.cpp +++ b/Source/Contents/Effects/EvilLandEffect.cpp @@ -4,6 +4,8 @@ #include "Client/Mode/ModeMgr.h" #include "Contents/Effects/EffectMemoryMgr.h" #include "Contents/Effects/NyanggrassEffect.h" +#include "Render/Textures/Texture.h" +#include "Render/Textures/TextureCache.h" // OFFSET: 0x006FE300 // FUNCTION: fn_06944 @@ -20,6 +22,55 @@ void CEvilLandEffect::Close() { this->particles.clear(); } +// OFFSET: 0x006FE530 +// FUNCTION: fn_06948 +void CEvilLandEffect::Slot01() { + CTexture* texture = g_texMgr.Load("effect\\EVILLAND\\demonground.tga", 0, false, true, false); + const float textureStepU = static_cast(texture->ImageWidth()) / static_cast(texture->TextureWidth()) / static_cast(this->unknown_00B0); + const float textureStepV = static_cast(texture->ImageHeight()) / static_cast(texture->TextureHeight()) / static_cast(this->unknown_00B0); + + CTexture* alpha = g_texMgr.Load("effect\\EVILLAND\\demonground_alpha_translucent.tga", 0, false, true, false); + const float alphaStepU = static_cast(alpha->ImageWidth()) / static_cast(alpha->TextureWidth()) / static_cast(this->unknown_00B0); + const float alphaStepV = static_cast(alpha->ImageHeight()) / static_cast(alpha->TextureHeight()) / static_cast(this->unknown_00B0); + + for (int row = 0; row < this->unknown_00B0; ++row) { + for (int column = 0; column < this->unknown_00B0; ++column) { + CMultiTexParticle* particle = static_cast(CreateMultiTexParticle(reinterpret_cast(this->position), -1)); + if (!particle) { + continue; + } + + particle->unknown_0004 = this->id; + particle->unknown_0010 = row; + particle->unknown_000C = column; + particle->unknown_0008 = 1; + particle->texture1 = texture; + particle->texture2 = alpha; + + particle->uv1[0][0] = static_cast(column) * textureStepU; + particle->uv1[0][1] = static_cast(row) * textureStepV; + particle->uv1[1][0] = static_cast(column + 1) * textureStepU; + particle->uv1[1][1] = static_cast(row) * textureStepV; + particle->uv1[2][0] = static_cast(column) * textureStepU; + particle->uv1[2][1] = static_cast(row + 1) * textureStepV; + particle->uv1[3][0] = static_cast(column + 1) * textureStepU; + particle->uv1[3][1] = static_cast(row + 1) * textureStepV; + + particle->uv2[0][0] = static_cast(column) * alphaStepU; + particle->uv2[0][1] = static_cast(row) * alphaStepV; + particle->uv2[1][0] = static_cast(column + 1) * alphaStepU; + particle->uv2[1][1] = static_cast(row) * alphaStepV; + particle->uv2[2][0] = static_cast(column) * alphaStepU; + particle->uv2[2][1] = static_cast(row + 1) * alphaStepV; + particle->uv2[3][0] = static_cast(column + 1) * alphaStepU; + particle->uv2[3][1] = static_cast(row + 1) * alphaStepV; + + particle->AllocateVertices(4); + this->particles.push_back(particle); + } + } +} + // OFFSET: 0x006FE830 // FUNCTION: fn_06949 bool CEvilLandEffect::Slot06() { diff --git a/Source/Contents/Effects/EvilLandEffect.h b/Source/Contents/Effects/EvilLandEffect.h index 0ad28521..2260d0fa 100644 --- a/Source/Contents/Effects/EvilLandEffect.h +++ b/Source/Contents/Effects/EvilLandEffect.h @@ -11,6 +11,7 @@ class CParticle; class CEvilLandEffect : public CEffect { public: CEvilLandEffect(); + void Slot01() override; void Slot03() override; void Slot04() override; void Close() override; diff --git a/Source/Contents/Effects/JupitelThunderStormEffect.cpp b/Source/Contents/Effects/JupitelThunderStormEffect.cpp index 767966d5..f3c397c4 100644 --- a/Source/Contents/Effects/JupitelThunderStormEffect.cpp +++ b/Source/Contents/Effects/JupitelThunderStormEffect.cpp @@ -2,8 +2,16 @@ #include "Client/Mode/CGameMode.h" #include "Client/Mode/ModeMgr.h" #include "Contents/Camera/Camera.h" +#include "Contents/Effects/EZ2STREffectEx.h" #include "Contents/Effects/EffectMemoryMgr.h" #include "Contents/Effects/Particle.h" +#include "Contents/MapSkyMgr.h" +#include "Utility/Math/AffineMatrix.h" +#include "Utility/Text/FormatString.h" + +#include +#include +#include // INLINED static bool ParticleAlive(const CParticle* particle) { @@ -31,6 +39,65 @@ void CJupitelThunderStormEffect::Close() { this->particles.clear(); } +// OFFSET: 0x00706180 +// FUNCTION: fn_07043 +void CJupitelThunderStormEffect::Slot01() { + const float dy = this->sourcePosition[1] - this->position[1]; + const float dx = this->sourcePosition[0] - this->position[0]; + const float dz = this->sourcePosition[2] - this->position[2]; + const float speed = SquareRoot(dy * dy + dx * dx + dz * dz) / static_cast(this->duration); + + this->step.x = this->sourcePosition[0] - this->position[0]; + this->step.y = this->sourcePosition[1] - this->position[1]; + this->step.z = this->sourcePosition[2] - this->position[2]; + const float scale = 1.0f / SquareRoot(this->step.x * this->step.x + this->step.y * this->step.y + this->step.z * this->step.z); + this->step.x = scale * this->step.x * speed; + this->step.y = scale * this->step.y * speed; + this->step.z = scale * this->step.z * speed; + + const float angle = ScreenAngle(this->position, this->sourcePosition, static_cast(g_modeMgr.GetGameMode())->camera->frame.view.values); + CEZ2STRParticle* ball = static_cast(CreateEZ2STRParticle(reinterpret_cast(this->position), 5)); + this->particle = ball; + if (ball) { + ball->Load(std::string("HYPER_NOVICE\\HN_JUPITEL_THUNDER_STORM\\jupitel_thunder_storm_ball\\jupitel_thunder_storm_ball.str")); + static_cast(this->particle)->m_angle = angle; + } + + int corners[4][2] = {{-1, 1}, {1, 1}, {-1, -1}, {1, -1}}; + int index = 0; + const int rings = (this->unknown_00B0 - 1) / 4; + const int lastDelay = ((this->unknown_00B0 - 1) / 2 + 6) * 150; + for (int delay = 80; delay <= lastDelay; delay += 80, ++index) { + CEZ2STRParticle* bolt = static_cast(CreateEZ2STRParticle(reinterpret_cast(this->position), 5)); + if (!bolt) { + continue; + } + + const int range = (rings * 10 + 25) / 2; + const int corner = index % 4; + int offsetX = 0; + float offsetZ; + if (range == 0) { + offsetZ = static_cast(corners[corner][1]) * g_depthAverageHalf; + } else { + const int randomZ = rand() % range; + offsetX = std::max(rand() % range, 0); + offsetZ = (static_cast(std::max(randomZ, 0)) + g_depthAverageHalf) * static_cast(corners[corner][1]); + } + + bolt->Load(FormatOwnedString("HYPER_NOVICE\\HN_JUPITEL_THUNDER_STORM\\jupitel_thunder_storm\\jupitel_thunder_storm_%02d.str", std::max(rand() % 3, 0))); + bolt->position.z = offsetZ + this->sourcePosition[2]; + bolt->position.y = this->sourcePosition[1] - 15.0f; + bolt->position.x = static_cast(corners[corner][0]) * (static_cast(offsetX) + g_depthAverageHalf) + this->sourcePosition[0]; + bolt->m_delay = delay; + this->particles.push_back(bolt); + + if (corner == 0) { + this->AddEvent(0, "effect\\HYPER_NOVICE\\hu_jupitel_thunder_storm.wav", delay / 16 + 1, 0); + } + } +} + // OFFSET: 0x007065F0 // FUNCTION: fn_07044 bool CJupitelThunderStormEffect::Slot06() { diff --git a/Source/Contents/Effects/JupitelThunderStormEffect.h b/Source/Contents/Effects/JupitelThunderStormEffect.h index 14e78c5f..c51ea12f 100644 --- a/Source/Contents/Effects/JupitelThunderStormEffect.h +++ b/Source/Contents/Effects/JupitelThunderStormEffect.h @@ -13,6 +13,7 @@ class CJupitelThunderStormEffect : public CEffect { public: CJupitelThunderStormEffect(); + void Slot01() override; void Slot03() override; void Slot04() override; void Close() override; diff --git a/Source/Contents/Effects/NyanggrassEffect.cpp b/Source/Contents/Effects/NyanggrassEffect.cpp index 0dd3cadf..f77da38c 100644 --- a/Source/Contents/Effects/NyanggrassEffect.cpp +++ b/Source/Contents/Effects/NyanggrassEffect.cpp @@ -44,6 +44,33 @@ void CMultiTexParticle::Reset() { this->offsetV = 0.0f; } +struct MultiTexVertex : LightmappedVertex { + MultiTexVertex() { + this->x = 0.0f; + this->y = 0.0f; + this->z = 0.0f; + this->rhw = 0.0f; + this->diffuse = 0xFFFFFFFFu; + this->specular = 0xFFFFFFFFu; + this->u = 0.0f; + this->v = 0.0f; + this->lightU = 0.0f; + this->lightV = 0.0f; + } +}; + +// OFFSET: 0x00707FB0 +// FUNCTION: fn_07068 +void CMultiTexParticle::AllocateVertices(int count) { + delete[] this->command.indices; + this->command.indices = nullptr; + delete[] this->command.vertices; + this->command.vertices = nullptr; + this->command.indexCount = 0; + this->command.vertexCount = count; + this->command.vertices = new MultiTexVertex[count]; +} + // OFFSET: 0x007080F0 // FUNCTION: fn_07069 void CMultiTexParticle::Render(int column, int row) { diff --git a/Source/Contents/Effects/NyanggrassEffect.h b/Source/Contents/Effects/NyanggrassEffect.h index a0d1a0a5..f367cb46 100644 --- a/Source/Contents/Effects/NyanggrassEffect.h +++ b/Source/Contents/Effects/NyanggrassEffect.h @@ -15,6 +15,7 @@ public: void Slot01() override; void Reset(); + void AllocateVertices(int count); void Render(int column, int row); /* 02BC */ LightmappedCommand command;