From ea8559f2bae5792c97f40968b78df6da45f90d85 Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Thu, 29 Oct 2026 21:01:40 +0000 Subject: [PATCH] Decompile fn_19893 (CEffectPrim::RenderOrbitIcons) Batch #2523 by ragnarok-clanker: 0 byte-identical, 1 confirmed by peer review. - fn_19893 CEffectPrim::RenderOrbitIcons: logic confirmed by peer review Peer-reviewed-by: eAthena, meitogi, youko, superintelligence Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes). --- Source/Contents/Effects/EffectPrim.h | 1 + .../Effects/EffectPrimitiveRendering.cpp | 57 +++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/Source/Contents/Effects/EffectPrim.h b/Source/Contents/Effects/EffectPrim.h index c9b6e2d2..54a87b8c 100644 --- a/Source/Contents/Effects/EffectPrim.h +++ b/Source/Contents/Effects/EffectPrim.h @@ -137,6 +137,7 @@ struct CEffectPrim : CRenderObject { void RenderPeongUp(matrix& wtm); void RenderRipple(matrix& wtm); void RenderRainbow(matrix& wtm); + void RenderOrbitIcons(matrix& wtm, float scale, unsigned char red, unsigned char green, unsigned char blue); void RenderLayeredGlow(matrix& wtm); void RenderSphereCage(matrix& wtm); void RenderGroundBubbles(matrix& wtm); diff --git a/Source/Contents/Effects/EffectPrimitiveRendering.cpp b/Source/Contents/Effects/EffectPrimitiveRendering.cpp index 90771191..60105918 100644 --- a/Source/Contents/Effects/EffectPrimitiveRendering.cpp +++ b/Source/Contents/Effects/EffectPrimitiveRendering.cpp @@ -3139,6 +3139,63 @@ void CEffectPrim::RenderLayeredGlow(matrix& wtm) { } } +// OFFSET: 0x00BD9FC0 +// FUNCTION: fn_19893 +void CEffectPrim::RenderOrbitIcons(matrix& wtm, float scale, unsigned char red, unsigned char green, unsigned char blue) { + vector3d vec1{}; + vector3d vec2{}; + vector3d vec3{}; + vector3d vec4{}; + int rpCnt = 0; + + for (int ec = 0; ec < 4; ++ec) { + EffectPrimitiveSlot& slot = this->state.slots[ec]; + + if (slot.life != 1) { + continue; + } + + if (slot.flag1[4] == 1) { + red = 255; + green = 20; + blue = 20; + } + + vector3d* const points[4] = {&slot.vecBPre, &slot.vecBNow, &slot.vecTPre, &slot.vecTNow}; + for (int item = 0; item < 4; ++item) { + const int angle = static_cast(slot.height[3 + 4 * item]); + points[item]->x = g_cosTable[angle] * 4.0f; + points[item]->z = g_sinTable[angle] * 4.0f; + } + + const float rx = scale * slot.distance; + vec1 = {rx * g_cosTable[45], 0.0f, rx * g_sinTable[45]}; + vec2 = {rx * g_cosTable[135], 0.0f, rx * g_sinTable[135]}; + vec3 = {rx * g_cosTable[225], 0.0f, rx * g_sinTable[225]}; + vec4 = {rx * g_cosTable[315], 0.0f, rx * g_sinTable[315]}; + this->Tei_TowardScreen(vec1, vec2, vec3, vec4, this->state.slots[0].alphaT, this->state.slots[1].alphaT); + const vector3d quad[4] = {vec1, vec2, vec3, vec4}; + + for (int item = 0; item < 4; ++item) { + const float mode = slot.height[2 + 4 * item]; + const int delta = static_cast(slot.height[3 + 4 * item] - static_cast(this->state.slots[0].alphaT)); + const bool back = (delta >= 70 || delta <= -80) && static_cast(delta + 270) <= 540; + const bool flipped = mode == 0.0f || mode == 2.0f ? back : !back; + const vector3d& point = *points[item]; + const int order[4] = {flipped ? 1 : 0, flipped ? 0 : 1, flipped ? 3 : 2, flipped ? 2 : 3}; + vector3d corners[4]; + for (int corner = 0; corner < 4; ++corner) { + const vector3d& local = quad[order[corner]]; + corners[corner] = {local.x + point.x, local.y + point.y - slot.height[20], local.z + point.z}; + } + this->RenderTeiRect( + &rpCnt, static_cast(static_cast(slot.height[1 + 4 * item])), corners[0], corners[1], corners[2], corners[3], wtm, 0, + static_cast(static_cast(mode)), 0, red, green, blue, 0.0f, 1.0f, 0.0f, 1.0f, 2 + ); + } + } +} + // OFFSET: 0x00BDF0A0 // FUNCTION: fn_19908 void CEffectPrim::RenderRainbow(matrix& wtm) {