From c3fe24e02062da8fe02f27c2d925fe0ef3b91572 Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Wed, 28 Oct 2026 19:42:58 +0000 Subject: [PATCH] Decompile 2 functions in Source/Contents/ActorMovementRoute.cpp, Source/Contents/Actors/GameActor.h, ... Batch #1601 by eAthena: 0 byte-identical, 2 confirmed by peer review. - fn_19317 Replay::DelayScale: logic confirmed by peer review - fn_21028 CGameActor::FindRoute: logic confirmed by peer review Reviewed-by: ragnarok-clanker Adds to the build: Source/Contents/ActorMovementRoute.cpp --- Source/Client/Replay.h | 1 + Source/Contents/ActorMovementRoute.cpp | 64 ++++++++++++++++++++++++++ Source/Contents/Actors/GameActor.h | 11 ++++- Source/Contents/TerrainPathSearch.h | 2 + data/compile.json | 1 + 5 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 Source/Contents/ActorMovementRoute.cpp diff --git a/Source/Client/Replay.h b/Source/Client/Replay.h index d1841ed..7b6fe60 100644 --- a/Source/Client/Replay.h +++ b/Source/Client/Replay.h @@ -113,6 +113,7 @@ public: int WriteHeader(int event); std::vector BuildMetadata(); float AnimationScale() const; + float DelayScale() const; bool SetState(int state); bool SetBaseFrame(std::uint32_t baseFrame); void UpdateDuration(); diff --git a/Source/Contents/ActorMovementRoute.cpp b/Source/Contents/ActorMovementRoute.cpp new file mode 100644 index 0000000..f6b223b --- /dev/null +++ b/Source/Contents/ActorMovementRoute.cpp @@ -0,0 +1,64 @@ +#include "Client/Replay.h" +#include "Client/Session.h" +#include "Contents/Actors/GameActor.h" +#include "Contents/TerrainPathSearch.h" + +// GLOBAL: gl_24733 +CPathFinder g_pathFinder; + +// OFFSET: 0x00B84570 +// FUNCTION: fn_19317 +float Replay::DelayScale() const { + if (this->speed == 0.25f) { + return 4.0f; + } + if (this->speed == 0.5f) { + return 2.0f; + } + if (this->speed == 1.0f) { + return 1.0f; + } + if (this->speed == 2.0f) { + return 0.5f; + } + if (this->speed == 4.0f) { + return 0.25f; + } + if (this->speed == 8.0f) { + return 0.125f; + } + if (this->speed == 16.0f) { + return 0.0625f; + } + return 1.0f; +} + +// OFFSET: 0x00CAB610 +// FUNCTION: fn_21028 +bool CGameActor::FindRoute(int startX, int startY, int fractionX, int fractionY, int destX, int destY, int speed) { + float scaledSpeed = 0.0f; + int stepSpeed; + if (g_replayAnimationScaling != 0) { + scaledSpeed = Replay::Instance().DelayScale() * static_cast(speed); + stepSpeed = static_cast(scaledSpeed); + } else { + stepSpeed = speed; + } + + const bool found = + g_pathFinder.FindPath(this->routeStartTick, startX, startY, fractionX, fractionY, destX, destY, stepSpeed, this->route, this->unknown_0314); + if (!found) { + return found; + } + + std::uint32_t endTick; + this->route.EndTick(&endTick); + const std::uint32_t now = g_session.GetServerTime(); + if (endTick > now) { + return found; + } + + const int baseSpeed = g_replayAnimationScaling != 0 ? static_cast(scaledSpeed) : speed; + this->routeStartTick = now; + return g_pathFinder.FindPath(now, startX, startY, fractionX, fractionY, destX, destY, baseSpeed * 10 / 13, this->route, this->unknown_0314); +} diff --git a/Source/Contents/Actors/GameActor.h b/Source/Contents/Actors/GameActor.h index 88baeb3..79b255e 100644 --- a/Source/Contents/Actors/GameActor.h +++ b/Source/Contents/Actors/GameActor.h @@ -2,6 +2,7 @@ #define RAGNAROK_SOURCE_CONTENTS_ACTORS_GAMEACTOR_H #include "Contents/Actors/RenderObject.h" +#include "Contents/MovementRouteInterpolation.h" #include @@ -9,9 +10,12 @@ class CGameActor : public CRenderObject { public: ~CGameActor() override; - /* 0138 */ unsigned char unknown_0138[0x100]; + /* 0138 */ unsigned char unknown_0138[0xE8]; + /* 0220 */ MovementRouteInterpolation route; /* 0238 */ unsigned char unknown_0238; - /* 0239 */ unsigned char unknown_0239[0x27]; + /* 0239 */ unsigned char unknown_0239[0x1B]; + /* 0254 */ std::uint32_t routeStartTick; + /* 0258 */ unsigned char unknown_0258[0x08]; /* 0260 */ int unknown_0260; /* 0264 */ unsigned char unknown_0264[0x64]; /* 02C8 */ int unknown_02C8; @@ -49,11 +53,14 @@ public: void SetUnknown02E4(int value); void SetUnknown02C8(int value); void SetUnknown0260(int value); + bool FindRoute(int startX, int startY, int fractionX, int fractionY, int destX, int destY, int speed); }; #if defined(_WIN32) && !defined(_WIN64) static_assert(sizeof(CGameActor) == 0x410); +static_assert(offsetof(CGameActor, route) == 0x220); static_assert(offsetof(CGameActor, unknown_0238) == 0x238); +static_assert(offsetof(CGameActor, routeStartTick) == 0x254); static_assert(offsetof(CGameActor, unknown_0260) == 0x260); static_assert(offsetof(CGameActor, unknown_02C8) == 0x2C8); static_assert(offsetof(CGameActor, unknown_02E4) == 0x2E4); diff --git a/Source/Contents/TerrainPathSearch.h b/Source/Contents/TerrainPathSearch.h index ac758c3..1e78d06 100644 --- a/Source/Contents/TerrainPathSearch.h +++ b/Source/Contents/TerrainPathSearch.h @@ -54,6 +54,8 @@ public: int Width() const; }; +extern CPathFinder g_pathFinder; + #if defined(_WIN32) && !defined(_WIN64) static_assert(offsetof(CPathFinder, attrCache) == 0x1078); static_assert(offsetof(CPathFinder, nodePool) == 0x1084); diff --git a/data/compile.json b/data/compile.json index ede9fe2..9cf717d 100644 --- a/data/compile.json +++ b/data/compile.json @@ -266,6 +266,7 @@ "Source/Client/ReplayPacketRecorder.cpp": 2, "Source/Client/Session.cpp": 0, "Source/Contents/ActorGeometry.cpp": 4, + "Source/Contents/ActorMovementRoute.cpp": 4, "Source/Contents/ActorNameCard.cpp": 4, "Source/Contents/ActorNameDirectory.cpp": 4, "Source/Contents/Actors/AttackMotion.cpp": 4,