diff --git a/Source/Client/Mode/CGameMode.h b/Source/Client/Mode/CGameMode.h index c3bfca4c..30b24473 100644 --- a/Source/Client/Mode/CGameMode.h +++ b/Source/Client/Mode/CGameMode.h @@ -9,6 +9,7 @@ #include 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) diff --git a/Source/Contents/Actors/EffectActors.h b/Source/Contents/Actors/EffectActors.h index 9e07945d..40a7990e 100644 --- a/Source/Contents/Actors/EffectActors.h +++ b/Source/Contents/Actors/EffectActors.h @@ -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 diff --git a/Source/Contents/Actors/GameActor.h b/Source/Contents/Actors/GameActor.h index f15ac4f4..55b37a43 100644 --- a/Source/Contents/Actors/GameActor.h +++ b/Source/Contents/Actors/GameActor.h @@ -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); diff --git a/Source/Contents/Actors/Pc.h b/Source/Contents/Actors/Pc.h index dd26befa..2018a29a 100644 --- a/Source/Contents/Actors/Pc.h +++ b/Source/Contents/Actors/Pc.h @@ -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); diff --git a/Source/Contents/Actors/Player.cpp b/Source/Contents/Actors/Player.cpp index 7ccdb088..4ef98f95 100644 --- a/Source/Contents/Actors/Player.cpp +++ b/Source/Contents/Actors/Player.cpp @@ -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(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(value) / 432.0f; +} diff --git a/Source/Contents/Actors/RenderObject.cpp b/Source/Contents/Actors/RenderObject.cpp index 6cef02b1..11d9ea16 100644 --- a/Source/Contents/Actors/RenderObject.cpp +++ b/Source/Contents/Actors/RenderObject.cpp @@ -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(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(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(this->render.accountId), 2374)) { + corpse->spriteOffset = *reinterpret_cast(&effect->unknown_0048); + } + } +} + +// OFFSET: 0x00CCCAF0 +// FUNCTION: fn_21199 +void CGameActor::Slot39(int value) { + const float speed = static_cast(std::min(value, g_maxMoveSpeed)) / 432.0f; + this->render.unknown_0054 = speed; + this->render.speed = speed; +} diff --git a/Source/Contents/Effects/Effect.h b/Source/Contents/Effects/Effect.h index fe4a714d..50a48cf9 100644 --- a/Source/Contents/Effects/Effect.h +++ b/Source/Contents/Effects/Effect.h @@ -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 events; /* 00C0 */ unsigned char retained; diff --git a/Source/Contents/Sound/SoundMaker.cpp b/Source/Contents/Sound/SoundMaker.cpp index 5b423f02..b0300821 100644 --- a/Source/Contents/Sound/SoundMaker.cpp +++ b/Source/Contents/Sound/SoundMaker.cpp @@ -17,6 +17,15 @@ #include #include +// 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() { diff --git a/Source/Contents/World/WorldObjects.cpp b/Source/Contents/World/WorldObjects.cpp index 552a4470..da51bc49 100644 --- a/Source/Contents/World/WorldObjects.cpp +++ b/Source/Contents/World/WorldObjects.cpp @@ -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 + // 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; +}