rodecomp/Source/Contents/Effects/BezierArcThrowEffect.cpp
ragnarok-clanker 526fc6d829 Decompile fn_09110 (CBezierArcThrowEffect::Slot03)
Batch #4592 by Bruwuno: 0 byte-identical, 1 confirmed by peer review.

- fn_09110 CBezierArcThrowEffect::Slot03: logic confirmed by peer review

Peer-reviewed-by: eAthena, alisonrag, Lumen
Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes).
2026-10-30 04:43:39 +00:00

133 lines
4.3 KiB
C++

#include "Contents/Effects/BezierArcThrowEffect.h"
#include "Client/Mode/CGameMode.h"
#include "Client/Mode/ModeMgr.h"
#include "Contents/Actors/RenderObject.h"
#include "Contents/Camera/Camera.h"
#include "Contents/Effects/EffectMemoryMgr.h"
#include "Contents/World/World.h"
#include "Utility/Math/AffineMatrix.h"
#include <cmath>
// INLINED
static vector3d TransformPoint(const matrix& transform, const vector3d& point) {
vector3d result;
result.x = point.y * transform.values[3] + point.x * transform.values[0] + point.z * transform.values[6] + transform.values[9];
result.y = point.y * transform.values[4] + point.x * transform.values[1] + point.z * transform.values[7] + transform.values[10];
result.z = point.y * transform.values[5] + point.x * transform.values[2] + point.z * transform.values[8] + transform.values[11];
return result;
}
// OFFSET: 0x007AAEA0
// FUNCTION: fn_09102
CThunderingOrb::CThunderingOrb(const std::string& name) : CBezierArcThrowEffect(name) {}
// OFFSET: 0x007AAF40
// FUNCTION: fn_09103
CWindBomb::CWindBomb(const std::string& name) : CBezierArcThrowEffect(name) {}
// OFFSET: 0x007AB290
// FUNCTION: fn_09107
void CBezierArcThrowEffect::Close() {
if (this->m_particle) {
FreeParticle(this->m_particle);
this->m_particle = nullptr;
}
}
// OFFSET: 0x007AB2C0
// FUNCTION: fn_09108
void CBezierArcThrowEffect::Slot01() {
this->m_particle = static_cast<CEZ2STRParticle*>(CreateEZ2STRParticle(reinterpret_cast<const vector3d*>(this->position), 5));
if (this->m_particle) {
this->m_particle->Load(this->m_name);
this->m_particle->m_loop = true;
this->m_target.x = 0.0f;
this->m_target.y = 0.0f;
this->m_target.z = 0.0f;
this->m_progress = 1.0f;
this->m_active = true;
}
}
// OFFSET: 0x007AB340
// FUNCTION: fn_09110
void CBezierArcThrowEffect::Slot03() {
if (!this->m_active) {
return;
}
CRenderObject* actor = FindRenderObject(this->actor);
if (!actor || !this->m_particle) {
this->m_active = false;
return;
}
const vector3d actorPos = actor->render.position;
CView* camera = static_cast<CGameMode*>(g_modeMgr.GetGameMode())->camera;
vector3d actorView = TransformPoint(camera->frame.view, actorPos);
float targetViewX = this->m_target.y * camera->frame.view.values[3] +
this->m_target.x * camera->frame.view.values[0] +
this->m_target.z * camera->frame.view.values[6] +
camera->frame.view.values[9];
matrix rotation;
if (targetViewX < actorView.x) {
rotation.MakeYRotation(2.094395f);
} else {
rotation.MakeYRotation(4.188789f);
}
actorView.y -= 10.0f;
vector3d ctrlPt = TransformPoint(static_cast<CGameMode*>(g_modeMgr.GetGameMode())->camera->frame.inverse, actorView);
this->m_progress -= 0.07f;
vector3d delta;
delta.y = this->m_target.y - ctrlPt.y;
delta.x = this->m_target.x - ctrlPt.x;
delta.z = this->m_target.z - ctrlPt.z;
float distSq = delta.y * delta.y + delta.x * delta.x + delta.z * delta.z;
float dist = SquareRoot(distSq);
float invDist = 1.0f / SquareRoot(distSq);
vector3d norm;
norm.x = delta.x * invDist * dist;
norm.y = delta.y * invDist * dist;
norm.z = delta.z * invDist * dist;
vector3d rotated = TransformPoint(rotation, norm);
float t = this->m_progress;
float u = 1.0f - t;
float u2 = static_cast<float>(std::pow(static_cast<double>(u), 2.0));
float t2 = static_cast<float>(std::pow(static_cast<double>(t), 2.0));
float mid = (t + t) * u;
this->m_particle->position.x = (rotated.x + this->m_target.x) * mid + ctrlPt.x * t2 + this->m_target.x * u2;
this->m_particle->position.y = (rotated.y + this->m_target.y) * mid + ctrlPt.y * t2 + this->m_target.y * u2;
this->m_particle->position.z = (rotated.z + this->m_target.z) * mid + ctrlPt.z * t2 + this->m_target.z * u2;
this->m_particle->Process(0.0f, 0.0f, 0.0f);
if (0.0f >= this->m_progress) {
FreeParticle(this->m_particle);
this->m_particle = nullptr;
}
}
// OFFSET: 0x007AB800
// FUNCTION: fn_09111
void CBezierArcThrowEffect::Slot04() {
if (this->m_particle) {
this->m_particle->DrawScreen(static_cast<CGameMode*>(g_modeMgr.GetGameMode())->camera->frame.view);
}
}
// OFFSET: 0x007AB830
// FUNCTION: fn_09112
void CBezierArcThrowEffect::SetTarget(const vector3d& target) {
this->m_target.x = target.x;
this->m_target.y = target.y;
this->m_target.z = target.z;
}