Decompile 7 functions in Source/Contents/Actors/RenderObject.cpp, Source/Contents/Actors/Player.cpp, ...

Batch #2092 by ragnarok-clanker: 0 byte-identical, 7 confirmed by peer review.

- fn_21037 CGameActor::Slot37: logic confirmed by peer review
- fn_21074 CGameActor::Slot38: logic confirmed by peer review
- fn_21199 CGameActor::Slot39: logic confirmed by peer review
- fn_22619 CGrannyPc::Slot39: logic confirmed by peer review
- fn_22620 CPc::Slot39: logic confirmed by peer review
- fn_22354 CCorpse::CCorpse: logic confirmed by peer review
- fn_21301 CGameMode::SpawnCorpse: logic confirmed by peer review

Reviewed-by: ragnarok-clanker
This commit is contained in:
ragnarok-clanker 2026-10-29 10:04:49 +00:00
commit 3a6bebae77
9 changed files with 132 additions and 2 deletions

View file

@ -9,6 +9,7 @@
#include <string>
class CView;
class CCorpse;
struct ActorNameAllPacket;
struct WorldScene;
@ -33,6 +34,7 @@ public:
void PlayerCell(int* column, int* row) const;
void ReceiveActorNameAll(const ActorNameAllPacket* packet);
void NotifyItemBounds();
CCorpse* SpawnCorpse(float x, float y, float z, const char* action, const char* sprite, int animation, int motion, float angle);
};
#if defined(_WIN32) && !defined(_WIN64)

View file

@ -16,6 +16,7 @@ public:
class CCorpse : public CRenderObject {
public:
CCorpse();
~CCorpse() override;
void SendObjectMessage(
CGameObject* sender, int message, int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m

View file

@ -84,6 +84,9 @@ public:
virtual void Slot34(int value) = 0;
virtual void Slot35() = 0;
virtual void Slot36() = 0;
virtual int Slot37();
virtual void Slot38();
virtual void Slot39(int value);
void SetUnknown0305(unsigned char value, int extra);
void SetUnknown0318(const float* value, int index);
@ -98,6 +101,8 @@ public:
bool FindRoute(int startX, int startY, int fractionX, int fractionY, int destX, int destY, int speed);
};
extern const int g_maxMoveSpeed;
#if defined(_WIN32) && !defined(_WIN64)
static_assert(sizeof(CGameActor) == 0x410);
static_assert(offsetof(CGameActor, route) == 0x220);

View file

@ -19,6 +19,7 @@ public:
) override;
void Slot34(int value) override;
void Slot39(int value) override;
float* GetExtent(float* extent) const;
@ -28,7 +29,8 @@ public:
/* 0434 */ int unknown_0434;
/* 0438 */ unsigned char unknown_0438[0x0C];
/* 0444 */ int unknown_0444;
/* 0448 */ unsigned char unknown_0448[0x10];
/* 0448 */ int weapon;
/* 044C */ unsigned char unknown_044C[0x0C];
/* 0458 */ int unknown_0458;
/* 045C */ int unknown_045C;
/* 0460 */ unsigned char unknown_0460[0x84];
@ -97,6 +99,7 @@ public:
void Slot25(int value) override;
void Slot26(int value) override;
void Slot27(int value) override;
void Slot39(int value) override;
void PlayMotion(int repeat);

View file

@ -1,8 +1,12 @@
#include "Contents/Actors/Pc.h"
#include "Client/Session.h"
#include "Contents/Jobs/JobInheritance.h"
#include "Resource/Models/GrannyModelResource.h"
// GLOBAL: gl_24753
extern const int g_maxMoveSpeed = 432;
// OFFSET: 0x00DAFE50
// FUNCTION: fn_22606
void CGrannyPc::SetAnimation(unsigned animation, int, int repeat) {
@ -146,3 +150,29 @@ bool CPlayer::IsSpecialState(int state) const {
return false;
}
}
// OFFSET: 0x00DB06C0
// FUNCTION: fn_22619
void CGrannyPc::Slot39(int value) {
if (this->unknown_0440 != 11 || this->unknown_0444 != 0) {
value = std::min(value, g_maxMoveSpeed);
}
this->render.unknown_0054 = static_cast<float>(value) / 432.0f;
}
// OFFSET: 0x00DB0710
// FUNCTION: fn_22620
void CPc::Slot39(int value) {
const int weapon = this->weapon;
if (weapon > 105) {
GetWeaponViewValue(weapon);
}
if (weapon != 11) {
value = std::min(value, g_maxMoveSpeed);
}
this->render.unknown_0054 = static_cast<float>(value) / 432.0f;
}

View file

@ -5,6 +5,9 @@
#include "Client/Replay.h"
#include "Contents/Camera/Camera.h"
#include "Contents/Actors/GameActor.h"
#include "Contents/Actors/EffectActors.h"
#include "Contents/Effects/Effect.h"
#include "Contents/Effects/EffectLists.h"
#include "Render/SpriteQuad.h"
#include "Resource/ResourceMgr.h"
#include "Resource/Sprites/ActionResource.h"
@ -485,3 +488,52 @@ void CGameActor::ProcessBodyState() {
int CGameActor::GetShield() {
return -1;
}
// OFFSET: 0x00CABD40
// FUNCTION: fn_21037
int CGameActor::Slot37() {
const CActRes* action = this->render.action;
const int count = static_cast<int>(action->FrameCount(this->render.previousAnimation));
for (int frame = 0; frame < count; ++frame) {
const int sound = action->Frame(this->render.previousAnimation, frame).sound;
if (sound != -1 && std::strcmp(action->Sound(sound), "atk") == 0) {
return frame;
}
}
return count - (count != 1 ? 2 : 1);
}
// OFFSET: 0x00CAE500
// FUNCTION: fn_21074
void CGameActor::Slot38() {
CGameMode* mode = static_cast<CGameMode*>(g_world.ActiveGameMode());
const float angle = this->render.angle;
const int motion = this->render.curMotion;
const int animation = this->render.animation;
const char* sprite = this->render.sprite ? this->render.sprite->name.text : nullptr;
const char* action = this->render.action ? this->render.action->name.text : nullptr;
CCorpse* corpse = mode->SpawnCorpse(
this->render.position.x, this->render.position.y, this->render.position.z, action, sprite, animation, motion, angle
);
if (corpse) {
if (this->render.unknown_010C > 0) {
corpse->render.unknown_010C = this->render.unknown_010C;
}
if (CEffect* effect = g_effectMgr->Find(static_cast<int>(this->render.accountId), 2374)) {
corpse->spriteOffset = *reinterpret_cast<const float*>(&effect->unknown_0048);
}
}
}
// OFFSET: 0x00CCCAF0
// FUNCTION: fn_21199
void CGameActor::Slot39(int value) {
const float speed = static_cast<float>(std::min(value, g_maxMoveSpeed)) / 432.0f;
this->render.unknown_0054 = speed;
this->render.speed = speed;
}

View file

@ -68,7 +68,9 @@ public:
/* 0034 */ unsigned char outsideRange;
/* 0035 */ unsigned char unknown_0035[3];
/* 0038 */ int range;
/* 003C */ unsigned char unknown_003C[116];
/* 003C */ unsigned char unknown_003C[12];
/* 0048 */ int unknown_0048;
/* 004C */ unsigned char unknown_004C[100];
/* 00B0 */ int unknown_00B0;
/* 00B4 */ std::vector<EffectEvent> events;
/* 00C0 */ unsigned char retained;

View file

@ -17,6 +17,15 @@
#include <windows.h>
#include <timeapi.h>
// OFFSET: 0x00DA1190
// FUNCTION: fn_22354
CCorpse::CCorpse() {
this->render.visible = 1;
this->render.isLieOnGround = true;
this->spriteOffset = 0.0f;
this->render.unknown_008C = timeGetTime();
}
// OFFSET: 0x00DA1E30
// FUNCTION: fn_22363
CSoundMaker::CSoundMaker() {

View file

@ -1,9 +1,14 @@
#include "Client/Mode/CGameMode.h"
#include "Client/Session.h"
#include "Contents/Actors/EffectActors.h"
#include "Resource/ResourceMgr.h"
#include "Contents/Actors/RenderObject.h"
#include "Contents/World/WorldObjects.h"
#include "Contents/World/WorldScene.h"
#include "Contents/Effects/EffectLists.h"
#include <new>
// OFFSET: 0x00AC8220
// FUNCTION: fn_17667
CRenderObject* WorldScene::GetGameActorByAidIncludeMe(std::uint32_t aid) const {
@ -73,3 +78,24 @@ void WorldObjects::SendObjectMessage(CGameObject* sender, std::uint64_t identity
}
}
}
// OFFSET: 0x00CD8740
// FUNCTION: fn_21301
CCorpse* CGameMode::SpawnCorpse(float x, float y, float z, const char* action, const char* sprite, int animation, int motion, float angle) {
auto* corpse = new (std::nothrow) CCorpse;
if (corpse) {
this->scene->objects.push_back(corpse);
corpse->render.position.x = x;
corpse->render.position.y = y;
corpse->render.position.z = z;
corpse->SetActionName(ResourceMgr::Instance(), action);
corpse->SetSpriteName(ResourceMgr::Instance(), sprite);
corpse->render.previousAnimation = animation;
corpse->render.animation = animation;
corpse->render.curMotion = motion;
corpse->render.angle = angle;
}
return corpse;
}