mirror of
https://github.com/whoahq/whoa.git
synced 2026-02-02 08:42:45 +03:00
Compare commits
63 Commits
2886416545
...
826f20ef04
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
826f20ef04 | ||
|
|
553a59c808 | ||
|
|
2efef87898 | ||
|
|
c92f1b8de8 | ||
|
|
c9aaa245c9 | ||
|
|
43dcfae6b0 | ||
|
|
0b0b7927aa | ||
|
|
de2bea7129 | ||
|
|
ccca191048 | ||
|
|
cd3585ca42 | ||
|
|
13ec1d7eef | ||
|
|
f4ca99ac15 | ||
|
|
ca3888f38e | ||
|
|
a1541725f2 | ||
|
|
ba0baf1688 | ||
|
|
a43ab56644 | ||
|
|
e2bfef907a | ||
|
|
361d327f30 | ||
|
|
8a062e5631 | ||
|
|
2bb8da6971 | ||
|
|
7e994ff195 | ||
|
|
3332062f86 | ||
|
|
56f645fe3b | ||
|
|
72d5247563 | ||
|
|
ae911d94ad | ||
|
|
d18a479bfb | ||
|
|
8615757d54 | ||
|
|
b7c3735e7f | ||
|
|
f44ba4bf63 | ||
|
|
082bc06c69 | ||
|
|
1e13e33f2a | ||
|
|
31fca17064 | ||
|
|
97d386f745 | ||
|
|
b26db42994 | ||
|
|
e29b584da3 | ||
|
|
f722040986 | ||
|
|
4f9cceda79 | ||
|
|
a90933f635 | ||
|
|
4dd9921a4f | ||
|
|
2fc113d5b0 | ||
|
|
43ad9fc8a6 | ||
|
|
be264e22bf | ||
|
|
775320a7fc | ||
|
|
8333530d65 | ||
|
|
4114f1ee16 | ||
|
|
1cc8c3ce40 | ||
|
|
c59d0de8b5 | ||
|
|
364fba9f34 | ||
|
|
5e4ca1980d | ||
|
|
6d8510b4a7 | ||
|
|
9162978b4f | ||
|
|
8066b4c053 | ||
|
|
abdb5c364c | ||
|
|
47e0dbb028 | ||
|
|
d1b764903c | ||
|
|
8ab88329bb | ||
|
|
860d6978fd | ||
|
|
bd0d7c63d2 | ||
|
|
68ab5ccced | ||
|
|
2695b584fd | ||
|
|
e9cb989eb7 | ||
|
|
92adcefef8 | ||
|
|
0c3bbc4336 |
@ -1 +1 @@
|
||||
Subproject commit 48a78025ef77faac80faa30c116f3ced4bbd9251
|
||||
Subproject commit 39cf7976a899b4f9a1290d0afdbd5011e4af9ac1
|
||||
@ -520,8 +520,9 @@ void WowClientDestroy() {
|
||||
}
|
||||
|
||||
void WowClientInit() {
|
||||
EventRegister(EVENT_ID_TICK, reinterpret_cast<EVENTHANDLERFUNC>(&CWorld::OnTick));
|
||||
|
||||
// TODO
|
||||
// EventRegister(EVENT_ID_5, (int)sub_4020E0);
|
||||
// _cfltcvt_init_0();
|
||||
|
||||
ClientRegisterConsoleCommands();
|
||||
|
||||
@ -286,12 +286,10 @@ int32_t SchedulerThreadProcProcess(uint32_t a1) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t v9 = (currTime - context->m_schedLastIdle);
|
||||
float elapsedSec = (currTime - context->m_schedLastIdle) * 0.001;
|
||||
context->m_schedLastIdle = currTime;
|
||||
double elapsedSec = v9 * 0.001;
|
||||
|
||||
// TODO
|
||||
// FrameTime::Update(currTime, elapsedSec);
|
||||
SynthesizeTick(context, currTime, elapsedSec);
|
||||
|
||||
IEvtTimerDispatch(context);
|
||||
|
||||
|
||||
@ -91,3 +91,17 @@ void SynthesizePoll(EvtContext* context) {
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_POLL, nullptr);
|
||||
}
|
||||
|
||||
void SynthesizeTick(EvtContext* context, uint32_t currTime, float elapsedSec) {
|
||||
context->m_critsect.Enter();
|
||||
bool closed = context->m_schedState == EvtContext::SCHEDSTATE_CLOSED;
|
||||
context->m_critsect.Leave();
|
||||
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
EVENT_DATA_TICK data = { elapsedSec, currTime };
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_TICK, &data);
|
||||
}
|
||||
|
||||
@ -15,4 +15,6 @@ void SynthesizePaint(EvtContext* context);
|
||||
|
||||
void SynthesizePoll(EvtContext* context);
|
||||
|
||||
void SynthesizeTick(EvtContext* context, uint32_t currTime, float elapsedSec);
|
||||
|
||||
#endif
|
||||
|
||||
@ -12,7 +12,7 @@ enum EVENTID {
|
||||
EVENT_ID_FOCUS = 2,
|
||||
EVENT_ID_CLOSE = 3,
|
||||
EVENT_ID_DESTROY = 4,
|
||||
EVENT_ID_5 = 5,
|
||||
EVENT_ID_TICK = 5,
|
||||
EVENT_ID_IDLE = 6,
|
||||
EVENT_ID_POLL = 7,
|
||||
EVENT_ID_INITIALIZE = 8,
|
||||
@ -259,4 +259,9 @@ struct EVENT_DATA_SIZE {
|
||||
int32_t h;
|
||||
};
|
||||
|
||||
struct EVENT_DATA_TICK {
|
||||
float tickTimeSec;
|
||||
uint32_t curTimeMs;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -410,6 +410,11 @@ int32_t CGlueMgr::Idle(const void* a1, void* a2) {
|
||||
break;
|
||||
}
|
||||
|
||||
case IDLE_DELETE_CHARACTER: {
|
||||
CGlueMgr::PollDeleteCharacter(msg, complete, result);
|
||||
break;
|
||||
}
|
||||
|
||||
case IDLE_ENTER_WORLD: {
|
||||
CGlueMgr::PollEnterWorld();
|
||||
break;
|
||||
@ -775,6 +780,34 @@ void CGlueMgr::PollCharacterList(const char* msg, int32_t complete, int32_t resu
|
||||
}
|
||||
}
|
||||
|
||||
void CGlueMgr::PollDeleteCharacter(const char* msg, int32_t complete, int32_t result) {
|
||||
FrameScript_SignalEvent(UPDATE_STATUS_DIALOG, "%s", msg);
|
||||
|
||||
if (CGlueMgr::HandleBattlenetDisconnect()) {
|
||||
CGlueMgr::SetIdleState(IDLE_NONE);
|
||||
}
|
||||
|
||||
if (!complete) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Error
|
||||
|
||||
if (result == 0) {
|
||||
FrameScript_SignalEvent(OPEN_STATUS_DIALOG, "%s%s", "OKAY", msg);
|
||||
|
||||
CGlueMgr::SetIdleState(IDLE_NONE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Success
|
||||
|
||||
FrameScript_SignalEvent(SELECT_FIRST_CHARACTER, nullptr);
|
||||
|
||||
CGlueMgr::GetCharacterList();
|
||||
}
|
||||
|
||||
void CGlueMgr::PollEnterWorld() {
|
||||
if (!LoadingScreenDrawing()) {
|
||||
return;
|
||||
@ -1112,7 +1145,7 @@ void CGlueMgr::StatusDialogClick() {
|
||||
|
||||
case IDLE_REALM_LIST:
|
||||
case IDLE_5:
|
||||
case IDLE_6:
|
||||
case IDLE_DELETE_CHARACTER:
|
||||
case IDLE_ENTER_WORLD: {
|
||||
ClientServices::Connection()->Cancel(2);
|
||||
CGlueMgr::SetIdleState(IDLE_NONE);
|
||||
|
||||
@ -21,7 +21,7 @@ class CGlueMgr {
|
||||
IDLE_CHARACTER_LIST = 3,
|
||||
IDLE_REALM_LIST = 4,
|
||||
IDLE_5 = 5,
|
||||
IDLE_6 = 6,
|
||||
IDLE_DELETE_CHARACTER = 6,
|
||||
IDLE_7 = 7,
|
||||
IDLE_8 = 8,
|
||||
IDLE_9 = 9,
|
||||
@ -80,6 +80,7 @@ class CGlueMgr {
|
||||
static int32_t OnKickReasonMsg(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg);
|
||||
static void PollAccountLogin(int32_t errorCode, const char* msg, int32_t complete, int32_t result, WOWCS_OPS op);
|
||||
static void PollCharacterList(const char* msg, int32_t complete, int32_t result, int32_t errorCode);
|
||||
static void PollDeleteCharacter(const char* msg, int32_t complete, int32_t result);
|
||||
static void PollEnterWorld();
|
||||
static void PollLoginServerLogin();
|
||||
static void PollRealmList(const char* msg, int32_t complete, int32_t result, WOWCS_OPS op);
|
||||
|
||||
@ -104,6 +104,10 @@ void ClientConnection::GetRealmList() {
|
||||
}
|
||||
}
|
||||
|
||||
void ClientConnection::HandleCharacterDelete(uint8_t result) {
|
||||
this->Complete(result == 71, result);
|
||||
}
|
||||
|
||||
int32_t ClientConnection::HandleConnect() {
|
||||
this->Complete(1, 5);
|
||||
|
||||
|
||||
@ -22,6 +22,7 @@ class ClientConnection : public RealmConnection {
|
||||
|
||||
// Virtual member functions
|
||||
virtual int32_t HandleConnect();
|
||||
virtual void HandleCharacterDelete(uint8_t result);
|
||||
|
||||
// Member functions
|
||||
ClientConnection(RealmResponse* realmResponse)
|
||||
|
||||
@ -30,7 +30,7 @@ int32_t RealmConnection::MessageHandler(void* param, NETMESSAGE msgId, uint32_t
|
||||
}
|
||||
|
||||
case SMSG_DELETE_CHAR: {
|
||||
// TODO
|
||||
result = connection->DeleteCharHandler(msgId, time, msg);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -294,6 +294,15 @@ int32_t RealmConnection::HandleCharEnum(uint32_t msgId, uint32_t time, CDataStor
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t RealmConnection::DeleteCharHandler(uint32_t msgId, uint32_t time, CDataStore* msg) {
|
||||
uint8_t result;
|
||||
msg->Get(result);
|
||||
|
||||
this->HandleCharacterDelete(result);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void RealmConnection::RequestCharacterEnum() {
|
||||
CDataStore msg;
|
||||
|
||||
|
||||
@ -46,11 +46,13 @@ class RealmConnection : public NetClient {
|
||||
|
||||
// Virtual member functions
|
||||
virtual int32_t HandleAuthChallenge(AuthenticationChallenge* challenge);
|
||||
virtual void HandleCharacterDelete(uint8_t result) = 0;
|
||||
|
||||
// Member functions
|
||||
RealmConnection(RealmResponse* realmResponse);
|
||||
int32_t HandleAuthResponse(uint32_t msgId, uint32_t time, CDataStore* msg);
|
||||
int32_t HandleCharEnum(uint32_t msgId, uint32_t time, CDataStore* msg);
|
||||
int32_t DeleteCharHandler(uint32_t msgId, uint32_t time, CDataStore* msg);
|
||||
void RequestCharacterEnum();
|
||||
void RequestCharacterLogin(uint64_t guid, int32_t a2);
|
||||
void SetSelectedRealm(uint32_t a2, uint32_t a3, uint32_t a4);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
file(GLOB PRIVATE_SOURCES
|
||||
"*.cpp"
|
||||
"client/*.cpp"
|
||||
"movement/*.cpp"
|
||||
)
|
||||
|
||||
add_library(object STATIC
|
||||
|
||||
@ -72,6 +72,12 @@ enum OBJECT_TYPE_ID {
|
||||
// TODO
|
||||
};
|
||||
|
||||
enum OUT_OF_RANGE_TYPE {
|
||||
OUT_OF_RANGE_0 = 0,
|
||||
OUT_OF_RANGE_1 = 1,
|
||||
OUT_OF_RANGE_2 = 2,
|
||||
};
|
||||
|
||||
enum SHEATHE_TYPE {
|
||||
SHEATHE_0 = 0,
|
||||
SHEATHE_1 = 1,
|
||||
|
||||
32
src/object/client/CClientMoveUpdate.cpp
Normal file
32
src/object/client/CClientMoveUpdate.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
#include "object/client/CClientMoveUpdate.hpp"
|
||||
|
||||
void CClientMoveUpdate::Skip(CDataStore* msg) {
|
||||
uint32_t moveFlags = CMovementStatus::Skip(msg);
|
||||
|
||||
void* data;
|
||||
msg->GetDataInSitu(data, 9 * sizeof(float));
|
||||
|
||||
if (moveFlags & 0x8000000) {
|
||||
CMoveSpline::Skip(msg);
|
||||
}
|
||||
}
|
||||
|
||||
CDataStore& operator>>(CDataStore& msg, CClientMoveUpdate& move) {
|
||||
msg >> move.status;
|
||||
|
||||
msg.Get(move.float60);
|
||||
msg.Get(move.float64);
|
||||
msg.Get(move.float68);
|
||||
msg.Get(move.float6C);
|
||||
msg.Get(move.float70);
|
||||
msg.Get(move.float74);
|
||||
msg.Get(move.float78);
|
||||
msg.Get(move.float7C);
|
||||
msg.Get(move.float80);
|
||||
|
||||
if (move.status.moveFlags & 0x8000000) {
|
||||
msg >> move.spline;
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
27
src/object/client/CClientMoveUpdate.hpp
Normal file
27
src/object/client/CClientMoveUpdate.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef OBJECT_CLIENT_C_CLIENT_MOVE_UPDATE_HPP
|
||||
#define OBJECT_CLIENT_C_CLIENT_MOVE_UPDATE_HPP
|
||||
|
||||
#include "object/movement/CMovementStatus.hpp"
|
||||
#include "object/movement/CMoveSpline.hpp"
|
||||
#include <common/datastore/CDataStore.hpp>
|
||||
|
||||
struct CClientMoveUpdate {
|
||||
CMovementStatus status;
|
||||
float float60;
|
||||
float float64;
|
||||
float float68;
|
||||
float float6C;
|
||||
float float70;
|
||||
float float74;
|
||||
float float78;
|
||||
float float7C;
|
||||
float float80;
|
||||
// TODO
|
||||
CMoveSpline spline;
|
||||
|
||||
static void Skip(CDataStore* msg);
|
||||
};
|
||||
|
||||
CDataStore& operator>>(CDataStore& msg, CClientMoveUpdate& move);
|
||||
|
||||
#endif
|
||||
133
src/object/client/CClientObjCreate.cpp
Normal file
133
src/object/client/CClientObjCreate.cpp
Normal file
@ -0,0 +1,133 @@
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "util/DataStore.hpp"
|
||||
#include "util/GUID.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include <common/DataStore.hpp>
|
||||
|
||||
void CClientObjCreate::Skip(CDataStore* msg) {
|
||||
uint16_t flags;
|
||||
msg->Get(flags);
|
||||
|
||||
if (flags & 0x20) {
|
||||
CClientMoveUpdate::Skip(msg);
|
||||
} else if (flags & 0x100) {
|
||||
SmartGUID guid;
|
||||
*msg >> guid;
|
||||
|
||||
C3Vector position28;
|
||||
*msg >> position28;
|
||||
|
||||
C3Vector position18;
|
||||
*msg >> position18;
|
||||
|
||||
float facing34;
|
||||
msg->Get(facing34);
|
||||
|
||||
float facing24;
|
||||
msg->Get(facing24);
|
||||
} else if (flags & 0x40) {
|
||||
C3Vector position28;
|
||||
*msg >> position28;
|
||||
|
||||
float facing34;
|
||||
msg->Get(facing34);
|
||||
}
|
||||
|
||||
if (flags & 0x8) {
|
||||
uint32_t uint2AC;
|
||||
msg->Get(uint2AC);
|
||||
}
|
||||
|
||||
if (flags & 0x10) {
|
||||
uint32_t uint2B0;
|
||||
msg->Get(uint2B0);
|
||||
}
|
||||
|
||||
if (flags & 0x4) {
|
||||
SmartGUID guid2B8;
|
||||
*msg >> guid2B8;
|
||||
}
|
||||
|
||||
if (flags & 0x2) {
|
||||
uint32_t uint2C0;
|
||||
msg->Get(uint2C0);
|
||||
}
|
||||
|
||||
if (flags & 0x80) {
|
||||
uint32_t uint2C4;
|
||||
msg->Get(uint2C4);
|
||||
|
||||
float float2C8;
|
||||
msg->Get(float2C8);
|
||||
}
|
||||
|
||||
if (flags & 0x200) {
|
||||
uint64_t uint2D4;
|
||||
msg->Get(uint2D4);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t CClientObjCreate::Get(CDataStore* msg) {
|
||||
uint16_t flags;
|
||||
msg->Get(flags);
|
||||
|
||||
this->flags = flags;
|
||||
|
||||
if (this->flags & 0x20) {
|
||||
*msg >> this->move;
|
||||
} else if (this->flags & 0x100) {
|
||||
SmartGUID guid;
|
||||
*msg >> guid;
|
||||
this->move.status.transport = guid;
|
||||
|
||||
*msg >> this->move.status.position28;
|
||||
*msg >> this->move.status.position18;
|
||||
|
||||
msg->Get(this->move.status.facing34);
|
||||
msg->Get(this->move.status.facing24);
|
||||
} else if (this->flags & 0x40) {
|
||||
this->move.status.transport = 0;
|
||||
|
||||
*msg >> this->move.status.position28;
|
||||
this->move.status.position18 = this->move.status.position28;
|
||||
|
||||
msg->Get(this->move.status.facing34);
|
||||
}
|
||||
|
||||
if (this->flags & 0x8) {
|
||||
msg->Get(this->uint2AC);
|
||||
} else {
|
||||
this->uint2AC = 0;
|
||||
}
|
||||
|
||||
if (this->flags & 0x10) {
|
||||
msg->Get(this->uint2B0);
|
||||
} else {
|
||||
this->uint2B0 = 0;
|
||||
}
|
||||
|
||||
if (this->flags & 0x4) {
|
||||
SmartGUID guid;
|
||||
*msg >> guid;
|
||||
this->guid2B8 = guid;
|
||||
} else {
|
||||
this->guid2B8 = 0;
|
||||
}
|
||||
|
||||
if (this->flags & 0x2) {
|
||||
msg->Get(this->uint2C0);
|
||||
}
|
||||
|
||||
if (this->flags & 0x80) {
|
||||
msg->Get(this->uint2C4);
|
||||
msg->Get(this->float2C8);
|
||||
}
|
||||
|
||||
if (this->flags & 0x200) {
|
||||
msg->Get(this->uint2D4);
|
||||
} else {
|
||||
this->uint2D4 = 0;
|
||||
}
|
||||
|
||||
return msg->Size() >= msg->Tell();
|
||||
}
|
||||
27
src/object/client/CClientObjCreate.hpp
Normal file
27
src/object/client/CClientObjCreate.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef OBJECT_CLIENT_C_CLIENT_OBJ_CREATE_HPP
|
||||
#define OBJECT_CLIENT_C_CLIENT_OBJ_CREATE_HPP
|
||||
|
||||
#include "object/client/CClientMoveUpdate.hpp"
|
||||
#include "util/GUID.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
class CDataStore;
|
||||
|
||||
struct CClientObjCreate {
|
||||
CClientMoveUpdate move;
|
||||
uint32_t flags = 0x0;
|
||||
uint32_t uint2AC;
|
||||
uint32_t uint2B0;
|
||||
// TODO
|
||||
WOWGUID guid2B8 = 0;
|
||||
uint32_t uint2C0;
|
||||
uint32_t uint2C4;
|
||||
float float2C8;
|
||||
// TODO
|
||||
uint64_t uint2D4 = 0; // TODO guid?
|
||||
|
||||
static void Skip(CDataStore* msg);
|
||||
int32_t Get(CDataStore* msg);
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,10 +1,26 @@
|
||||
#include "object/client/CGContainer.hpp"
|
||||
#include "object/client/CGItem.hpp"
|
||||
|
||||
uint32_t CGContainer::GetBaseOffset() {
|
||||
return CGItem::TotalFields();
|
||||
}
|
||||
|
||||
uint32_t CGContainer::GetBaseOffsetSaved() {
|
||||
return CGItem::TotalFieldsSaved();
|
||||
}
|
||||
|
||||
uint32_t CGContainer::GetDataSize() {
|
||||
return CGContainer::TotalFields() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t CGContainer::GetDataSizeSaved() {
|
||||
return CGContainer::TotalFieldsSaved() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t CGContainer::TotalFields() {
|
||||
return CGItem::TotalFields() + 74;
|
||||
return CGContainer::GetBaseOffset() + 74;
|
||||
}
|
||||
|
||||
uint32_t CGContainer::TotalFieldsSaved() {
|
||||
return CGItem::TotalFieldsSaved() + 72;
|
||||
return CGContainer::GetBaseOffsetSaved() + 72;
|
||||
}
|
||||
|
||||
@ -1,17 +1,28 @@
|
||||
#ifndef OBJECT_CLIENT_CG_CONTAINER_HPP
|
||||
#define OBJECT_CLIENT_CG_CONTAINER_HPP
|
||||
|
||||
#include "util/GUID.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
struct CGContainerData {
|
||||
// TODO
|
||||
uint32_t numSlots;
|
||||
uint32_t pad;
|
||||
WOWGUID slots[36];
|
||||
};
|
||||
|
||||
class CGContainer {
|
||||
public:
|
||||
// Public static functions
|
||||
static uint32_t GetBaseOffset();
|
||||
static uint32_t GetBaseOffsetSaved();
|
||||
static uint32_t GetDataSize();
|
||||
static uint32_t GetDataSizeSaved();
|
||||
static uint32_t TotalFields();
|
||||
static uint32_t TotalFieldsSaved();
|
||||
|
||||
// Public member variables
|
||||
CGContainerData* m_cont;
|
||||
uint32_t* m_contSaved;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
12
src/object/client/CGContainer_C.cpp
Normal file
12
src/object/client/CGContainer_C.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "object/client/CGContainer_C.hpp"
|
||||
|
||||
CGContainer_C::CGContainer_C(uint32_t time, CClientObjCreate& objCreate) : CGItem_C(time, objCreate) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CGContainer_C::SetStorage(uint32_t* storage, uint32_t* saved) {
|
||||
this->CGItem_C::SetStorage(storage, saved);
|
||||
|
||||
this->m_cont = reinterpret_cast<CGContainerData*>(&storage[CGContainer::GetBaseOffset()]);
|
||||
this->m_contSaved = &saved[CGContainer::GetBaseOffsetSaved()];
|
||||
}
|
||||
@ -1,12 +1,15 @@
|
||||
#ifndef OBJECT_CLIENT_CG_CONTAINER_C_HPP
|
||||
#define OBJECT_CLIENT_CG_CONTAINER_C_HPP
|
||||
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGContainer.hpp"
|
||||
#include "object/client/CGItem_C.hpp"
|
||||
|
||||
class CGContainer_C : public CGItem_C, public CGContainer {
|
||||
public:
|
||||
// TODO
|
||||
// Public member functions
|
||||
CGContainer_C(uint32_t time, CClientObjCreate& objCreate);
|
||||
void SetStorage(uint32_t* storage, uint32_t* saved);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,10 +1,26 @@
|
||||
#include "object/client/CGCorpse.hpp"
|
||||
#include "object/client/CGObject.hpp"
|
||||
|
||||
uint32_t CGCorpse::GetBaseOffset() {
|
||||
return CGObject::TotalFields();
|
||||
}
|
||||
|
||||
uint32_t CGCorpse::GetBaseOffsetSaved() {
|
||||
return CGObject::TotalFieldsSaved();
|
||||
}
|
||||
|
||||
uint32_t CGCorpse::GetDataSize() {
|
||||
return CGCorpse::TotalFields() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t CGCorpse::GetDataSizeSaved() {
|
||||
return CGCorpse::TotalFieldsSaved() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t CGCorpse::TotalFields() {
|
||||
return CGObject::TotalFields() + 30;
|
||||
return CGCorpse::GetBaseOffset() + 30;
|
||||
}
|
||||
|
||||
uint32_t CGCorpse::TotalFieldsSaved() {
|
||||
return CGObject::TotalFieldsSaved() + 3;
|
||||
return CGCorpse::GetBaseOffsetSaved() + 3;
|
||||
}
|
||||
|
||||
@ -10,8 +10,16 @@ struct CGCorpseData {
|
||||
class CGCorpse {
|
||||
public:
|
||||
// Public static functions
|
||||
static uint32_t GetBaseOffset();
|
||||
static uint32_t GetBaseOffsetSaved();
|
||||
static uint32_t GetDataSize();
|
||||
static uint32_t GetDataSizeSaved();
|
||||
static uint32_t TotalFields();
|
||||
static uint32_t TotalFieldsSaved();
|
||||
|
||||
// Public member variables
|
||||
CGCorpseData* m_corpse;
|
||||
uint32_t* m_corpseSaved;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
12
src/object/client/CGCorpse_C.cpp
Normal file
12
src/object/client/CGCorpse_C.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "object/client/CGCorpse_C.hpp"
|
||||
|
||||
CGCorpse_C::CGCorpse_C(uint32_t time, CClientObjCreate& objCreate) : CGObject_C(time, objCreate) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CGCorpse_C::SetStorage(uint32_t* storage, uint32_t* saved) {
|
||||
this->CGObject_C::SetStorage(storage, saved);
|
||||
|
||||
this->m_corpse = reinterpret_cast<CGCorpseData*>(&storage[CGCorpse::GetBaseOffset()]);
|
||||
this->m_corpseSaved = &saved[CGCorpse::GetBaseOffsetSaved()];
|
||||
}
|
||||
@ -1,12 +1,15 @@
|
||||
#ifndef OBJECT_CLIENT_CG_CORPSE_C_HPP
|
||||
#define OBJECT_CLIENT_CG_CORPSE_C_HPP
|
||||
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGCorpse.hpp"
|
||||
#include "object/client/CGObject_C.hpp"
|
||||
|
||||
class CGCorpse_C : public CGObject_C, public CGCorpse {
|
||||
public:
|
||||
// TODO
|
||||
// Public member functions
|
||||
CGCorpse_C(uint32_t time, CClientObjCreate& objCreate);
|
||||
void SetStorage(uint32_t* storage, uint32_t* saved);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,10 +1,26 @@
|
||||
#include "object/client/CGDynamicObject.hpp"
|
||||
#include "object/client/CGObject.hpp"
|
||||
|
||||
uint32_t CGDynamicObject::GetBaseOffset() {
|
||||
return CGObject::TotalFields();
|
||||
}
|
||||
|
||||
uint32_t CGDynamicObject::GetBaseOffsetSaved() {
|
||||
return CGObject::TotalFieldsSaved();
|
||||
}
|
||||
|
||||
uint32_t CGDynamicObject::GetDataSize() {
|
||||
return CGDynamicObject::TotalFields() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t CGDynamicObject::GetDataSizeSaved() {
|
||||
return CGDynamicObject::TotalFieldsSaved() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t CGDynamicObject::TotalFields() {
|
||||
return CGObject::TotalFields() + 6;
|
||||
return CGDynamicObject::GetBaseOffset() + 6;
|
||||
}
|
||||
|
||||
uint32_t CGDynamicObject::TotalFieldsSaved() {
|
||||
return CGObject::TotalFieldsSaved();
|
||||
return CGDynamicObject::GetBaseOffsetSaved() + 0;
|
||||
}
|
||||
|
||||
@ -10,8 +10,16 @@ struct CGDynamicObjectData {
|
||||
class CGDynamicObject {
|
||||
public:
|
||||
// Public static functions
|
||||
static uint32_t GetBaseOffset();
|
||||
static uint32_t GetBaseOffsetSaved();
|
||||
static uint32_t GetDataSize();
|
||||
static uint32_t GetDataSizeSaved();
|
||||
static uint32_t TotalFields();
|
||||
static uint32_t TotalFieldsSaved();
|
||||
|
||||
// Public member variables
|
||||
CGDynamicObjectData* m_dynamicObj;
|
||||
uint32_t* m_dynamicObjSaved;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
12
src/object/client/CGDynamicObject_C.cpp
Normal file
12
src/object/client/CGDynamicObject_C.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "object/client/CGDynamicObject_C.hpp"
|
||||
|
||||
CGDynamicObject_C::CGDynamicObject_C(uint32_t time, CClientObjCreate& objCreate) : CGObject_C(time, objCreate) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CGDynamicObject_C::SetStorage(uint32_t* storage, uint32_t* saved) {
|
||||
this->CGObject_C::SetStorage(storage, saved);
|
||||
|
||||
this->m_dynamicObj = reinterpret_cast<CGDynamicObjectData*>(&storage[CGDynamicObject::GetBaseOffset()]);
|
||||
this->m_dynamicObjSaved = &saved[CGDynamicObject::GetBaseOffsetSaved()];
|
||||
}
|
||||
@ -1,12 +1,15 @@
|
||||
#ifndef OBJECT_CLIENT_CG_DYNAMIC_OBJECT_C_HPP
|
||||
#define OBJECT_CLIENT_CG_DYNAMIC_OBJECT_C_HPP
|
||||
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGDynamicObject.hpp"
|
||||
#include "object/client/CGObject_C.hpp"
|
||||
|
||||
class CGDynamicObject_C : public CGObject_C, public CGDynamicObject {
|
||||
public:
|
||||
// TODO
|
||||
// Public member functions
|
||||
CGDynamicObject_C(uint32_t time, CClientObjCreate& objCreate);
|
||||
void SetStorage(uint32_t* storage, uint32_t* saved);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,10 +1,26 @@
|
||||
#include "object/client/CGGameObject.hpp"
|
||||
#include "object/client/CGObject.hpp"
|
||||
|
||||
uint32_t CGGameObject::GetBaseOffset() {
|
||||
return CGObject::TotalFields();
|
||||
}
|
||||
|
||||
uint32_t CGGameObject::GetBaseOffsetSaved() {
|
||||
return CGObject::TotalFieldsSaved();
|
||||
}
|
||||
|
||||
uint32_t CGGameObject::GetDataSize() {
|
||||
return CGGameObject::TotalFields() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t CGGameObject::GetDataSizeSaved() {
|
||||
return CGGameObject::TotalFieldsSaved() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t CGGameObject::TotalFields() {
|
||||
return CGObject::TotalFields() + 12;
|
||||
return CGGameObject::GetBaseOffset() + 12;
|
||||
}
|
||||
|
||||
uint32_t CGGameObject::TotalFieldsSaved() {
|
||||
return CGObject::TotalFieldsSaved() + 4;
|
||||
return CGGameObject::GetBaseOffsetSaved() + 4;
|
||||
}
|
||||
|
||||
@ -10,8 +10,16 @@ struct CGGameObjectData {
|
||||
class CGGameObject {
|
||||
public:
|
||||
// Public static functions
|
||||
static uint32_t GetBaseOffset();
|
||||
static uint32_t GetBaseOffsetSaved();
|
||||
static uint32_t GetDataSize();
|
||||
static uint32_t GetDataSizeSaved();
|
||||
static uint32_t TotalFields();
|
||||
static uint32_t TotalFieldsSaved();
|
||||
|
||||
// Public member variables
|
||||
CGGameObjectData* m_gameObj;
|
||||
uint32_t* m_gameObjSaved;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
12
src/object/client/CGGameObject_C.cpp
Normal file
12
src/object/client/CGGameObject_C.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "object/client/CGGameObject_C.hpp"
|
||||
|
||||
CGGameObject_C::CGGameObject_C(uint32_t time, CClientObjCreate& objCreate) : CGObject_C(time, objCreate) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CGGameObject_C::SetStorage(uint32_t* storage, uint32_t* saved) {
|
||||
this->CGObject_C::SetStorage(storage, saved);
|
||||
|
||||
this->m_gameObj = reinterpret_cast<CGGameObjectData*>(&storage[CGGameObject::GetBaseOffset()]);
|
||||
this->m_gameObjSaved = &saved[CGGameObject::GetBaseOffsetSaved()];
|
||||
}
|
||||
@ -1,12 +1,15 @@
|
||||
#ifndef OBJECT_CLIENT_CG_GAME_OBJECT_C_HPP
|
||||
#define OBJECT_CLIENT_CG_GAME_OBJECT_C_HPP
|
||||
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGGameObject.hpp"
|
||||
#include "object/client/CGObject_C.hpp"
|
||||
|
||||
class CGGameObject_C : public CGObject_C, public CGGameObject {
|
||||
public:
|
||||
// TODO
|
||||
// Public member functions
|
||||
CGGameObject_C(uint32_t time, CClientObjCreate& objCreate);
|
||||
void SetStorage(uint32_t* storage, uint32_t* saved);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,10 +1,26 @@
|
||||
#include "object/client/CGItem.hpp"
|
||||
#include "object/client/CGObject.hpp"
|
||||
|
||||
uint32_t CGItem::GetBaseOffset() {
|
||||
return CGObject::TotalFields();
|
||||
}
|
||||
|
||||
uint32_t CGItem::GetBaseOffsetSaved() {
|
||||
return CGObject::TotalFieldsSaved();
|
||||
}
|
||||
|
||||
uint32_t CGItem::GetDataSize() {
|
||||
return CGItem::TotalFields() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t CGItem::GetDataSizeSaved() {
|
||||
return CGItem::TotalFieldsSaved() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t CGItem::TotalFields() {
|
||||
return CGObject::TotalFields() + 58;
|
||||
return CGItem::GetBaseOffset() + 58;
|
||||
}
|
||||
|
||||
uint32_t CGItem::TotalFieldsSaved() {
|
||||
return CGObject::TotalFieldsSaved() + 47;
|
||||
return CGItem::GetBaseOffsetSaved() + 47;
|
||||
}
|
||||
|
||||
@ -1,17 +1,46 @@
|
||||
#ifndef OBJECT_CLIENT_CG_ITEM_HPP
|
||||
#define OBJECT_CLIENT_CG_ITEM_HPP
|
||||
|
||||
#include "util/GUID.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
struct ItemEnchantment {
|
||||
int32_t id;
|
||||
int32_t expiration;
|
||||
int32_t chargesRemaining;
|
||||
};
|
||||
|
||||
struct CGItemData {
|
||||
// TODO
|
||||
WOWGUID owner;
|
||||
WOWGUID containedIn;
|
||||
WOWGUID creator;
|
||||
WOWGUID giftCreator;
|
||||
uint32_t stackCount;
|
||||
int32_t expiration;
|
||||
int32_t spellCharges[5];
|
||||
uint32_t flags;
|
||||
ItemEnchantment enchantments[12];
|
||||
int32_t propertySeed;
|
||||
int32_t randomPropertiesID;
|
||||
int32_t durability;
|
||||
int32_t maxDurability;
|
||||
int32_t createPlayedTime;
|
||||
int32_t pad;
|
||||
};
|
||||
|
||||
class CGItem {
|
||||
public:
|
||||
// Public static functions
|
||||
static uint32_t GetBaseOffset();
|
||||
static uint32_t GetBaseOffsetSaved();
|
||||
static uint32_t GetDataSize();
|
||||
static uint32_t GetDataSizeSaved();
|
||||
static uint32_t TotalFields();
|
||||
static uint32_t TotalFieldsSaved();
|
||||
|
||||
// Public member variables
|
||||
CGItemData* m_item;
|
||||
uint32_t* m_itemSaved;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
12
src/object/client/CGItem_C.cpp
Normal file
12
src/object/client/CGItem_C.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "object/client/CGItem_C.hpp"
|
||||
|
||||
CGItem_C::CGItem_C(uint32_t time, CClientObjCreate& objCreate) : CGObject_C(time, objCreate) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CGItem_C::SetStorage(uint32_t* storage, uint32_t* saved) {
|
||||
this->CGObject_C::SetStorage(storage, saved);
|
||||
|
||||
this->m_item = reinterpret_cast<CGItemData*>(&storage[CGItem::GetBaseOffset()]);
|
||||
this->m_itemSaved = &saved[CGItem::GetBaseOffsetSaved()];
|
||||
}
|
||||
@ -1,12 +1,15 @@
|
||||
#ifndef OBJECT_CLIENT_CG_ITEM_C_HPP
|
||||
#define OBJECT_CLIENT_CG_ITEM_C_HPP
|
||||
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGObject_C.hpp"
|
||||
#include "object/client/CGItem.hpp"
|
||||
|
||||
class CGItem_C : public CGObject_C, public CGItem {
|
||||
public:
|
||||
// TODO
|
||||
// Public member functions
|
||||
CGItem_C(uint32_t time, CClientObjCreate& objCreate);
|
||||
void SetStorage(uint32_t* storage, uint32_t* saved);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,9 +1,25 @@
|
||||
#include "object/client/CGObject.hpp"
|
||||
|
||||
uint32_t CGObject::GetBaseOffset() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t CGObject::GetBaseOffsetSaved() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t CGObject::GetDataSize() {
|
||||
return CGObject::TotalFields() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t CGObject::GetDataSizeSaved() {
|
||||
return CGObject::TotalFieldsSaved() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t CGObject::TotalFields() {
|
||||
return 6;
|
||||
return CGObject::GetBaseOffset() + 6;
|
||||
}
|
||||
|
||||
uint32_t CGObject::TotalFieldsSaved() {
|
||||
return 3;
|
||||
return CGObject::GetBaseOffsetSaved() + 3;
|
||||
}
|
||||
|
||||
@ -2,10 +2,11 @@
|
||||
#define OBJECT_CLIENT_CG_OBJECT_HPP
|
||||
|
||||
#include "object/Types.hpp"
|
||||
#include "util/GUID.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
struct CGObjectData {
|
||||
uint64_t m_guid;
|
||||
WOWGUID m_guid;
|
||||
OBJECT_TYPE m_type;
|
||||
int32_t m_entryID;
|
||||
float m_scale;
|
||||
@ -15,6 +16,10 @@ struct CGObjectData {
|
||||
class CGObject {
|
||||
public:
|
||||
// Public static functions
|
||||
static uint32_t GetBaseOffset();
|
||||
static uint32_t GetBaseOffsetSaved();
|
||||
static uint32_t GetDataSize();
|
||||
static uint32_t GetDataSizeSaved();
|
||||
static uint32_t TotalFields();
|
||||
static uint32_t TotalFieldsSaved();
|
||||
|
||||
|
||||
@ -1,4 +1,81 @@
|
||||
#include "object/client/CGObject_C.hpp"
|
||||
#include "object/client/ObjMgr.hpp"
|
||||
#include "world/World.hpp"
|
||||
|
||||
CGObject_C::CGObject_C(uint32_t time, CClientObjCreate& objCreate) {
|
||||
// TODO
|
||||
|
||||
this->m_lockCount = 0;
|
||||
this->m_disabled = false;
|
||||
this->m_inReenable = false;
|
||||
this->m_postInited = false;
|
||||
this->m_flag19 = false;
|
||||
this->m_disablePending = false;
|
||||
|
||||
// TODO
|
||||
|
||||
ClntObjMgrLinkInNewObject(this);
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CGObject_C::AddWorldObject() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CGObject_C::Disable() {
|
||||
// TODO
|
||||
|
||||
this->m_disabled = true;
|
||||
// TODO other flag manipulation
|
||||
|
||||
this->m_disableTimeMs = CWorld::GetCurTimeMs();
|
||||
}
|
||||
|
||||
int32_t CGObject_C::IsInReenable() {
|
||||
return this->m_inReenable;
|
||||
}
|
||||
|
||||
int32_t CGObject_C::IsObjectLocked() {
|
||||
return this->m_lockCount != 0;
|
||||
}
|
||||
|
||||
void CGObject_C::Reenable() {
|
||||
this->m_disabled = false;
|
||||
this->m_inReenable = true;
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CGObject_C::SetBlock(uint32_t block, uint32_t value) {
|
||||
auto storage = reinterpret_cast<uint32_t*>(this->m_obj);
|
||||
storage[block] = value;
|
||||
}
|
||||
|
||||
void CGObject_C::SetDisablePending(int32_t pending) {
|
||||
if (pending) {
|
||||
this->m_disablePending = true;
|
||||
} else {
|
||||
this->m_disablePending = false;
|
||||
}
|
||||
}
|
||||
|
||||
void CGObject_C::SetObjectLocked(int32_t locked) {
|
||||
if (locked) {
|
||||
if (this->m_lockCount != 0xFFFF) {
|
||||
this->m_lockCount++;
|
||||
}
|
||||
} else {
|
||||
if (this->m_lockCount != 0) {
|
||||
this->m_lockCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGObject_C::SetStorage(uint32_t* storage, uint32_t* saved) {
|
||||
this->m_obj = reinterpret_cast<CGObjectData*>(&storage[CGObject::GetBaseOffset()]);
|
||||
this->m_objSaved = &saved[CGObject::GetBaseOffsetSaved()];
|
||||
}
|
||||
|
||||
void CGObject_C::SetTypeID(OBJECT_TYPE_ID typeID) {
|
||||
this->m_typeID = typeID;
|
||||
|
||||
@ -1,14 +1,45 @@
|
||||
#ifndef OBJECT_CLIENT_CG_OBJECT_C_HPP
|
||||
#define OBJECT_CLIENT_CG_OBJECT_C_HPP
|
||||
|
||||
#include "object/client/CGObject.hpp"
|
||||
#include "object/Types.hpp"
|
||||
#include "util/CHashKeyGUID.hpp"
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGObject.hpp"
|
||||
#include "util/GUID.hpp"
|
||||
#include <storm/Hash.hpp>
|
||||
#include <storm/List.hpp>
|
||||
|
||||
class CGObject_C : public CGObject, public TSHashObject<CGObject_C, CHashKeyGUID> {
|
||||
public:
|
||||
// Public member variables
|
||||
TSLink<CGObject_C> m_link;
|
||||
uint32_t m_disableTimeMs;
|
||||
// TODO
|
||||
uint32_t m_lockCount : 16;
|
||||
uint32_t m_disabled : 1;
|
||||
uint32_t m_inReenable : 1;
|
||||
uint32_t m_postInited : 1;
|
||||
uint32_t m_flag19 : 1;
|
||||
uint32_t m_disablePending : 1;
|
||||
// TODO
|
||||
|
||||
// Virtual public member functions
|
||||
// TODO
|
||||
virtual void Disable();
|
||||
// TODO
|
||||
virtual void HandleOutOfRange(OUT_OF_RANGE_TYPE type) {};
|
||||
// TODO
|
||||
|
||||
// Public member functions
|
||||
CGObject_C() = default;
|
||||
CGObject_C(uint32_t time, CClientObjCreate& objCreate);
|
||||
void AddWorldObject();
|
||||
int32_t IsInReenable();
|
||||
int32_t IsObjectLocked();
|
||||
void Reenable();
|
||||
void SetBlock(uint32_t block, uint32_t value);
|
||||
void SetDisablePending(int32_t pending);
|
||||
void SetObjectLocked(int32_t locked);
|
||||
void SetStorage(uint32_t* storage, uint32_t* saved);
|
||||
void SetTypeID(OBJECT_TYPE_ID typeID);
|
||||
};
|
||||
|
||||
|
||||
@ -1,18 +1,42 @@
|
||||
#include "object/client/CGPlayer.hpp"
|
||||
#include "object/client/CGUnit.hpp"
|
||||
|
||||
uint32_t CGPlayer::GetBaseOffset() {
|
||||
return CGUnit::TotalFields();
|
||||
}
|
||||
|
||||
uint32_t CGPlayer::GetBaseOffsetSaved() {
|
||||
return CGUnit::TotalFieldsSaved();
|
||||
}
|
||||
|
||||
uint32_t CGPlayer::GetDataSize() {
|
||||
return CGPlayer::TotalFields() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t CGPlayer::GetDataSizeSaved() {
|
||||
return CGPlayer::TotalFieldsSaved() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t CGPlayer::GetRemoteDataSize() {
|
||||
return CGPlayer::TotalRemoteFields() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t CGPlayer::GetRemoteDataSizeSaved() {
|
||||
return CGPlayer::TotalRemoteFieldsSaved() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t CGPlayer::TotalFields() {
|
||||
return CGUnit::TotalFields() + 1178;
|
||||
return CGPlayer::GetBaseOffset() + 1178;
|
||||
}
|
||||
|
||||
uint32_t CGPlayer::TotalRemoteFields() {
|
||||
return CGUnit::TotalFields() + 176;
|
||||
return CGPlayer::GetBaseOffset() + 176;
|
||||
}
|
||||
|
||||
uint32_t CGPlayer::TotalFieldsSaved() {
|
||||
return CGUnit::TotalFieldsSaved() + 1043;
|
||||
return CGPlayer::GetBaseOffsetSaved() + 1043;
|
||||
}
|
||||
|
||||
uint32_t CGPlayer::TotalRemoteFieldsSaved() {
|
||||
return CGUnit::TotalFieldsSaved() + 173;
|
||||
return CGPlayer::GetBaseOffsetSaved() + 173;
|
||||
}
|
||||
|
||||
@ -1,19 +1,156 @@
|
||||
#ifndef OBJECT_CLIENT_CG_PLAYER_HPP
|
||||
#define OBJECT_CLIENT_CG_PLAYER_HPP
|
||||
|
||||
#include "object/Types.hpp"
|
||||
#include "util/GUID.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
struct CQuestLogData {
|
||||
int32_t questID;
|
||||
uint32_t field2;
|
||||
uint32_t field3;
|
||||
uint32_t field4;
|
||||
uint32_t field5;
|
||||
};
|
||||
|
||||
// TODO is this VisibleItem_C?
|
||||
struct CVisibleItemData {
|
||||
int32_t entryID;
|
||||
uint32_t enchantment;
|
||||
};
|
||||
|
||||
struct CSkillInfo {
|
||||
uint16_t skillLineID;
|
||||
uint16_t skillStep;
|
||||
uint16_t skillRank;
|
||||
uint16_t skillMaxRank;
|
||||
int16_t skillTempModifier;
|
||||
int16_t skillPermModifier;
|
||||
};
|
||||
|
||||
struct CArenaTeamInfo {
|
||||
uint32_t field1;
|
||||
uint32_t field2;
|
||||
uint32_t field3;
|
||||
uint32_t field4;
|
||||
uint32_t field5;
|
||||
uint32_t field6;
|
||||
uint32_t field7;
|
||||
};
|
||||
|
||||
struct CGPlayerData {
|
||||
// TODO
|
||||
WOWGUID duelArbiter;
|
||||
uint32_t flags;
|
||||
uint32_t guildID;
|
||||
uint32_t guildRank;
|
||||
uint8_t skinID;
|
||||
uint8_t faceID;
|
||||
uint8_t hairStyleID;
|
||||
uint8_t hairColorID;
|
||||
uint8_t facialHairStyleID;
|
||||
uint8_t bytes_2_2; // TODO
|
||||
uint8_t bytes_2_3; // TODO
|
||||
uint8_t restState;
|
||||
uint8_t bytes_3_1; // TODO
|
||||
uint8_t bytes_3_2; // TODO
|
||||
uint8_t bytes_3_3; // TODO
|
||||
uint8_t bytes_3_4; // TODO
|
||||
uint32_t duelTeam;
|
||||
int32_t guildTimestamp;
|
||||
CQuestLogData questLog[25];
|
||||
CVisibleItemData visibleItems[19];
|
||||
int32_t chosenTitle;
|
||||
int32_t fakeInebriation;
|
||||
int32_t pad1;
|
||||
WOWGUID invSlots[NUM_INVENTORY_SLOTS];
|
||||
WOWGUID packSlots[16];
|
||||
WOWGUID bankSlots[28];
|
||||
WOWGUID bankBagSlots[7];
|
||||
WOWGUID vendorBuybackSlots[12];
|
||||
WOWGUID keyringSlots[32];
|
||||
WOWGUID currencyTokenSlots[32];
|
||||
WOWGUID farsightObject;
|
||||
WOWGUID knownTitles;
|
||||
WOWGUID knownTitles2;
|
||||
WOWGUID knownTitles3;
|
||||
WOWGUID knownCurrencies;
|
||||
uint32_t xp;
|
||||
uint32_t nextLevelXP;
|
||||
CSkillInfo skillInfo[128];
|
||||
int32_t characterPoints[2];
|
||||
uint32_t trackCreatureMask;
|
||||
uint32_t trackResourceMask;
|
||||
float blockPercentage;
|
||||
float dodgePercentage;
|
||||
float parryPercentage;
|
||||
int32_t expertise;
|
||||
int32_t offhandExpertise;
|
||||
float critPercentage;
|
||||
float rangedCritPercentage;
|
||||
float offhandCritPercentage;
|
||||
float spellCritPercentage[7];
|
||||
int32_t shieldBlock;
|
||||
float shieldBlockCritPercentage;
|
||||
uint8_t exploredZones[512];
|
||||
uint32_t restStateXP;
|
||||
uint32_t coinage;
|
||||
int32_t modDamageDonePos[7];
|
||||
int32_t modDamageDoneNeg[7];
|
||||
float modDamageDonePct[7];
|
||||
uint32_t modHealingDonePos;
|
||||
float modHealingPct;
|
||||
float modHealingDonePct;
|
||||
int32_t modTargetResistance;
|
||||
int32_t modTargetPhysicalResistance;
|
||||
uint8_t field_bytes_1; // TODO
|
||||
uint8_t field_bytes_2; // TODO
|
||||
uint8_t field_bytes_3; // TODO
|
||||
uint8_t field_bytes_4; // TODO
|
||||
int32_t ammoID;
|
||||
int32_t selfResSpell;
|
||||
uint32_t pvpMedals;
|
||||
uint32_t buybackPrice[12];
|
||||
uint32_t buybackTimestamp[12];
|
||||
uint16_t kills[2];
|
||||
uint32_t todayContribution;
|
||||
uint32_t yesterdayContribution;
|
||||
uint32_t lifetimeHonorableKills;
|
||||
uint8_t field_bytes_2_1; // TODO
|
||||
uint8_t field_bytes_2_2; // TODO
|
||||
uint8_t field_bytes_2_3; // TODO
|
||||
uint8_t field_bytes_2_4; // TODO
|
||||
int32_t watchedFactionIndex;
|
||||
uint32_t combatRating[25];
|
||||
CArenaTeamInfo arenaTeamInfo[3];
|
||||
uint32_t honorCurrency;
|
||||
uint32_t arenaCurrency;
|
||||
uint32_t maxLevel;
|
||||
uint32_t dailyQuests[25];
|
||||
float runeRegen[4];
|
||||
uint32_t noReagentCost[3];
|
||||
uint32_t glyphSlots[6];
|
||||
uint32_t glyphs[6];
|
||||
int32_t glyphsEnabled;
|
||||
uint32_t petSpellPower;
|
||||
};
|
||||
|
||||
class CGPlayer {
|
||||
public:
|
||||
// Public static functions
|
||||
static uint32_t GetBaseOffset();
|
||||
static uint32_t GetBaseOffsetSaved();
|
||||
static uint32_t GetDataSize();
|
||||
static uint32_t GetDataSizeSaved();
|
||||
static uint32_t GetRemoteDataSize();
|
||||
static uint32_t GetRemoteDataSizeSaved();
|
||||
static uint32_t TotalFields();
|
||||
static uint32_t TotalRemoteFields();
|
||||
static uint32_t TotalFieldsSaved();
|
||||
static uint32_t TotalRemoteFieldsSaved();
|
||||
|
||||
// Public member variables
|
||||
CGPlayerData* m_player;
|
||||
uint32_t* m_playerSaved;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -3,6 +3,17 @@
|
||||
#include "object/Types.hpp"
|
||||
#include <storm/Error.hpp>
|
||||
|
||||
CGPlayer_C::CGPlayer_C(uint32_t time, CClientObjCreate& objCreate) : CGUnit_C(time, objCreate) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CGPlayer_C::SetStorage(uint32_t* storage, uint32_t* saved) {
|
||||
this->CGUnit_C::SetStorage(storage, saved);
|
||||
|
||||
this->m_player = reinterpret_cast<CGPlayerData*>(&storage[CGPlayer::GetBaseOffset()]);
|
||||
this->m_playerSaved = &saved[CGPlayer::GetBaseOffsetSaved()];
|
||||
}
|
||||
|
||||
uint32_t Player_C_GetDisplayId(uint32_t race, uint32_t sex) {
|
||||
STORM_ASSERT(sex < UNITSEX_LAST);
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#ifndef OBJECT_CLIENT_CG_PLAYER_C_HPP
|
||||
#define OBJECT_CLIENT_CG_PLAYER_C_HPP
|
||||
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGPlayer.hpp"
|
||||
#include "object/client/CGUnit_C.hpp"
|
||||
#include <cstdint>
|
||||
@ -9,7 +10,9 @@ class CreatureModelDataRec;
|
||||
|
||||
class CGPlayer_C : public CGUnit_C, public CGPlayer {
|
||||
public:
|
||||
// TODO
|
||||
// Public member functions
|
||||
CGPlayer_C(uint32_t time, CClientObjCreate& objCreate);
|
||||
void SetStorage(uint32_t* storage, uint32_t* saved);
|
||||
};
|
||||
|
||||
uint32_t Player_C_GetDisplayId(uint32_t race, uint32_t sex);
|
||||
|
||||
@ -1,10 +1,26 @@
|
||||
#include "object/client/CGUnit.hpp"
|
||||
#include "object/client/CGObject.hpp"
|
||||
|
||||
uint32_t CGUnit::GetBaseOffset() {
|
||||
return CGObject::TotalFields();
|
||||
}
|
||||
|
||||
uint32_t CGUnit::GetBaseOffsetSaved() {
|
||||
return CGObject::TotalFieldsSaved();
|
||||
}
|
||||
|
||||
uint32_t CGUnit::GetDataSize() {
|
||||
return CGUnit::TotalFields() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t CGUnit::GetDataSizeSaved() {
|
||||
return CGUnit::TotalFieldsSaved() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t CGUnit::TotalFields() {
|
||||
return CGObject::TotalFields() + 142;
|
||||
return CGUnit::GetBaseOffset() + 142;
|
||||
}
|
||||
|
||||
uint32_t CGUnit::TotalFieldsSaved() {
|
||||
return CGObject::TotalFieldsSaved() + 123;
|
||||
return CGUnit::GetBaseOffsetSaved() + 123;
|
||||
}
|
||||
|
||||
@ -1,17 +1,90 @@
|
||||
#ifndef OBJECT_CLIENT_CG_UNIT_HPP
|
||||
#define OBJECT_CLIENT_CG_UNIT_HPP
|
||||
|
||||
#include "util/GUID.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
struct CGUnitData {
|
||||
// TODO
|
||||
WOWGUID charm;
|
||||
WOWGUID summon;
|
||||
WOWGUID critter;
|
||||
WOWGUID charmedBy;
|
||||
WOWGUID summonedBy;
|
||||
WOWGUID createdBy;
|
||||
WOWGUID target;
|
||||
WOWGUID channelObject;
|
||||
int32_t channelSpell;
|
||||
int32_t pad1;
|
||||
int32_t health;
|
||||
int32_t power[7];
|
||||
int32_t maxHealth;
|
||||
int32_t maxPower[7];
|
||||
float powerRegenFlatModifier[7];
|
||||
int32_t powerRegenInterruptedFlatModifier[7];
|
||||
int32_t level;
|
||||
int32_t factionTemplate;
|
||||
int32_t virtualItemSlotID[3];
|
||||
uint32_t flags;
|
||||
uint32_t flags2;
|
||||
uint32_t auraState;
|
||||
uint32_t attackRoundBaseTime[2];
|
||||
uint32_t rangedAttackTime;
|
||||
float boundingRadius;
|
||||
float combatReach;
|
||||
int32_t displayID;
|
||||
int32_t nativeDisplayID;
|
||||
int32_t mountDisplayID;
|
||||
float minDamage;
|
||||
float maxDamage;
|
||||
uint32_t minOffhandDamage;
|
||||
uint32_t maxOffhandDamage;
|
||||
int32_t pad2;
|
||||
uint32_t petNumber;
|
||||
uint32_t petNameTimestamp;
|
||||
uint32_t petExperience;
|
||||
uint32_t petNextLevelExperience;
|
||||
uint32_t dynamicFlags;
|
||||
float modCastingSpeed;
|
||||
int32_t createdBySpell;
|
||||
uint32_t npcFlags;
|
||||
uint32_t emoteState;
|
||||
int32_t stats[5];
|
||||
int32_t posStats[5];
|
||||
int32_t negStats[5];
|
||||
int32_t resistance[7];
|
||||
int32_t resistanceBuffModsPositive[7];
|
||||
int32_t resistanceBuffModsNegative[7];
|
||||
int32_t baseMana;
|
||||
int32_t baseHealth;
|
||||
int32_t pad3;
|
||||
int32_t attackPower;
|
||||
int32_t attackPowerMods;
|
||||
int32_t attackPowerMultiplier;
|
||||
int32_t rangedAttackPower;
|
||||
int32_t rangedAttackPowerMods;
|
||||
int32_t rangedAttackPowerMultiplier;
|
||||
float minRangedDamage;
|
||||
float maxRangedDamage;
|
||||
int32_t powerCostModifier[7];
|
||||
int32_t powerCostMultiplier[7];
|
||||
int32_t maxHealthModifier;
|
||||
float hoverHeight;
|
||||
int32_t pad4;
|
||||
};
|
||||
|
||||
class CGUnit {
|
||||
public:
|
||||
// Public static functions
|
||||
static uint32_t GetBaseOffset();
|
||||
static uint32_t GetBaseOffsetSaved();
|
||||
static uint32_t GetDataSize();
|
||||
static uint32_t GetDataSizeSaved();
|
||||
static uint32_t TotalFields();
|
||||
static uint32_t TotalFieldsSaved();
|
||||
|
||||
// Public member variables
|
||||
CGUnitData* m_unit;
|
||||
uint32_t* m_unitSaved;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -88,3 +88,14 @@ const char* CGUnit_C::GetDisplayRaceNameFromRecord(const ChrRacesRec* raceRec, U
|
||||
|
||||
return raceRec->m_name;
|
||||
}
|
||||
|
||||
CGUnit_C::CGUnit_C(uint32_t time, CClientObjCreate& objCreate) : CGObject_C(time, objCreate) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CGUnit_C::SetStorage(uint32_t* storage, uint32_t* saved) {
|
||||
this->CGObject_C::SetStorage(storage, saved);
|
||||
|
||||
this->m_unit = reinterpret_cast<CGUnitData*>(&storage[CGUnit::GetBaseOffset()]);
|
||||
this->m_unitSaved = &saved[CGUnit::GetBaseOffsetSaved()];
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#ifndef OBJECT_CLIENT_CG_UNIT_C_HPP
|
||||
#define OBJECT_CLIENT_CG_UNIT_C_HPP
|
||||
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGObject_C.hpp"
|
||||
#include "object/client/CGUnit.hpp"
|
||||
#include "object/Types.hpp"
|
||||
@ -13,6 +14,10 @@ class CGUnit_C : public CGObject_C, public CGUnit {
|
||||
// Public static functions
|
||||
static const char* GetDisplayClassNameFromRecord(const ChrClassesRec* classRec, UNIT_SEX sex, UNIT_SEX* displaySex);
|
||||
static const char* GetDisplayRaceNameFromRecord(const ChrRacesRec* raceRec, UNIT_SEX sex, UNIT_SEX* displaySex);
|
||||
|
||||
// Public member functions
|
||||
CGUnit_C(uint32_t time, CClientObjCreate& objCreate);
|
||||
void SetStorage(uint32_t* storage, uint32_t* saved);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
#ifndef OBJECT_CLIENT_CLNT_OBJ_MGR_HPP
|
||||
#define OBJECT_CLIENT_CLNT_OBJ_MGR_HPP
|
||||
|
||||
#include "object/client/CGObject_C.hpp"
|
||||
#include <storm/Hash.hpp>
|
||||
#include <storm/List.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
class ClientConnection;
|
||||
@ -8,7 +11,13 @@ class ClientConnection;
|
||||
class ClntObjMgr {
|
||||
public:
|
||||
// Member variables
|
||||
uint64_t m_activePlayer = 0;
|
||||
TSHashTable<CGObject_C, CHashKeyGUID> m_objects;
|
||||
TSHashTable<CGObject_C, CHashKeyGUID> m_lazyCleanupObjects;
|
||||
STORM_EXPLICIT_LIST(CGObject_C, m_link) m_lazyCleanupFifo[NUM_CLIENT_OBJECT_TYPES - 1];
|
||||
STORM_EXPLICIT_LIST(CGObject_C, m_link) m_visibleObjects;
|
||||
STORM_EXPLICIT_LIST(CGObject_C, m_link) m_reenabledObjects;
|
||||
// TODO
|
||||
WOWGUID m_activePlayer = 0;
|
||||
uint32_t m_mapID = 0;
|
||||
ClientConnection* m_net = nullptr;
|
||||
};
|
||||
|
||||
@ -1,9 +1,330 @@
|
||||
#include "object/client/MessageHandlers.hpp"
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGContainer_C.hpp"
|
||||
#include "object/client/CGCorpse_C.hpp"
|
||||
#include "object/client/CGDynamicObject_C.hpp"
|
||||
#include "object/client/CGGameObject_C.hpp"
|
||||
#include "object/client/CGItem_C.hpp"
|
||||
#include "object/client/CGObject_C.hpp"
|
||||
#include "object/client/CGPlayer_C.hpp"
|
||||
#include "object/client/CGUnit_C.hpp"
|
||||
#include "object/client/Mirror.hpp"
|
||||
#include "object/client/ObjMgr.hpp"
|
||||
#include "object/client/Util.hpp"
|
||||
#include "util/GUID.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include "util/Zlib.hpp"
|
||||
#include <common/DataStore.hpp>
|
||||
#include <storm/Error.hpp>
|
||||
#include <storm/Memory.hpp>
|
||||
#include <new>
|
||||
|
||||
enum UPDATE_TYPE {
|
||||
UPDATE_PARTIAL = 0,
|
||||
UPDATE_MOVEMENT = 1,
|
||||
UPDATE_FULL = 2,
|
||||
UPDATE_3 = 3,
|
||||
UPDATE_OUT_OF_RANGE = 4,
|
||||
UPDATE_IN_RANGE = 5,
|
||||
};
|
||||
|
||||
int32_t SkipPartialObjectUpdate(CDataStore* msg) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UpdateOutOfRangeObjects(CDataStore* msg) {
|
||||
uint32_t count;
|
||||
msg->Get(count);
|
||||
|
||||
// TODO CVehiclePassenger_C::StartAddingPendingRescueTransitions();
|
||||
|
||||
auto startPos = msg->Tell();
|
||||
|
||||
// Pass 1
|
||||
|
||||
for (int32_t i = 0; i < count; i++) {
|
||||
SmartGUID guid;
|
||||
*msg >> guid;
|
||||
|
||||
if (guid == ClntObjMgrGetActivePlayer()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto object = FindActiveObject(guid);
|
||||
|
||||
if (object) {
|
||||
HandleObjectOutOfRangePass1(object, OUT_OF_RANGE_0);
|
||||
}
|
||||
}
|
||||
|
||||
msg->Seek(startPos);
|
||||
|
||||
// Pass 2
|
||||
|
||||
for (int32_t i = 0; i < count; i++) {
|
||||
SmartGUID guid;
|
||||
*msg >> guid;
|
||||
|
||||
if (guid == ClntObjMgrGetActivePlayer()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto object = FindActiveObject(guid);
|
||||
|
||||
if (object && !object->IsObjectLocked()) {
|
||||
HandleObjectOutOfRangePass2(object);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO CVehiclePassenger_C::ExecutePendingRescueTransitions();
|
||||
}
|
||||
|
||||
int32_t UpdateObject(CDataStore* msg) {
|
||||
SmartGUID guid;
|
||||
*msg >> guid;
|
||||
|
||||
int32_t reenable;
|
||||
auto object = GetUpdateObject(guid, &reenable);
|
||||
|
||||
if (object) {
|
||||
if (!FillInPartialObjectData(object, object->m_obj->m_guid, msg, false, false)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (reenable) {
|
||||
object->Reenable();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return SkipPartialObjectUpdate(msg);
|
||||
}
|
||||
|
||||
void UpdateObjectMovement(CDataStore* msg) {
|
||||
WHOA_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void SetupObjectStorage(OBJECT_TYPE_ID typeID, CGObject_C* object, WOWGUID guid) {
|
||||
auto ptr = reinterpret_cast<char*>(object);
|
||||
|
||||
switch (typeID) {
|
||||
case ID_OBJECT: {
|
||||
auto storage = reinterpret_cast<uint32_t*>(ptr + sizeof(CGObject_C));
|
||||
auto saved = storage + CGObject::TotalFields();
|
||||
|
||||
object->SetStorage(storage, saved);
|
||||
memset(storage, 0, CGObject::GetDataSize());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_ITEM: {
|
||||
auto storage = reinterpret_cast<uint32_t*>(ptr + sizeof(CGItem_C));
|
||||
auto saved = storage + CGItem::TotalFields();
|
||||
|
||||
static_cast<CGItem_C*>(object)->SetStorage(storage, saved);
|
||||
memset(storage, 0, CGItem::GetDataSize());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_CONTAINER: {
|
||||
auto storage = reinterpret_cast<uint32_t*>(ptr + sizeof(CGContainer_C));
|
||||
auto saved = storage + CGContainer::TotalFields();
|
||||
|
||||
static_cast<CGContainer_C*>(object)->SetStorage(storage, saved);
|
||||
memset(storage, 0, CGContainer::GetDataSize());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_UNIT: {
|
||||
auto storage = reinterpret_cast<uint32_t*>(ptr + sizeof(CGUnit_C));
|
||||
auto saved = storage + CGUnit::TotalFields();
|
||||
|
||||
static_cast<CGUnit_C*>(object)->SetStorage(storage, saved);
|
||||
memset(storage, 0, CGUnit::GetDataSize());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_PLAYER: {
|
||||
// TODO something at ptr + 0x614 (within CGPlayer_C)
|
||||
|
||||
if (guid == ClntObjMgrGetActivePlayer()) {
|
||||
auto storage = reinterpret_cast<uint32_t*>(ptr + sizeof(CGPlayer_C));
|
||||
auto saved = storage + CGPlayer::TotalFields();
|
||||
|
||||
static_cast<CGPlayer_C*>(object)->SetStorage(storage, saved);
|
||||
memset(storage, 0, CGPlayer::GetDataSize());
|
||||
} else {
|
||||
auto storage = reinterpret_cast<uint32_t*>(ptr + sizeof(CGPlayer_C));
|
||||
auto saved = storage + CGPlayer::TotalRemoteFields();
|
||||
|
||||
static_cast<CGPlayer_C*>(object)->SetStorage(storage, saved);
|
||||
memset(storage, 0, CGPlayer::GetRemoteDataSize());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_GAMEOBJECT: {
|
||||
auto storage = reinterpret_cast<uint32_t*>(ptr + sizeof(CGGameObject_C));
|
||||
auto saved = storage + CGGameObject::TotalFields();
|
||||
|
||||
static_cast<CGGameObject_C*>(object)->SetStorage(storage, saved);
|
||||
memset(storage, 0, CGGameObject::GetDataSize());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_DYNAMICOBJECT: {
|
||||
auto storage = reinterpret_cast<uint32_t*>(ptr + sizeof(CGDynamicObject_C));
|
||||
auto saved = storage + CGDynamicObject::TotalFields();
|
||||
|
||||
static_cast<CGDynamicObject_C*>(object)->SetStorage(storage, saved);
|
||||
memset(storage, 0, CGDynamicObject::GetDataSize());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_CORPSE: {
|
||||
auto storage = reinterpret_cast<uint32_t*>(ptr + sizeof(CGCorpse_C));
|
||||
auto saved = storage + CGCorpse::TotalFields();
|
||||
|
||||
static_cast<CGCorpse_C*>(object)->SetStorage(storage, saved);
|
||||
memset(storage, 0, CGCorpse::GetDataSize());
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t CreateObject(CDataStore* msg, uint32_t time) {
|
||||
SmartGUID guid;
|
||||
*msg >> guid;
|
||||
|
||||
uint8_t _typeID;
|
||||
msg->Get(_typeID);
|
||||
auto typeID = static_cast<OBJECT_TYPE_ID>(_typeID);
|
||||
|
||||
int32_t reenable;
|
||||
auto existingObject = GetUpdateObject(guid, &reenable);
|
||||
|
||||
if (existingObject) {
|
||||
CClientObjCreate::Skip(msg);
|
||||
|
||||
if (!FillInPartialObjectData(existingObject, existingObject->m_obj->m_guid, msg, false, true)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (reenable) {
|
||||
existingObject->Reenable();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
CClientObjCreate objCreate;
|
||||
if (!objCreate.Get(msg)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (objCreate.flags & 0x1) {
|
||||
ClntObjMgrSetActivePlayer(guid);
|
||||
}
|
||||
|
||||
auto newObject = ClntObjMgrAllocObject(typeID, guid);
|
||||
|
||||
SetupObjectStorage(typeID, newObject, guid);
|
||||
|
||||
newObject->SetTypeID(typeID);
|
||||
|
||||
if (!FillInPartialObjectData(newObject, guid, msg, true, false)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
InitObject(newObject, time, objCreate);
|
||||
|
||||
ClntObjMgrGetCurrent()->m_visibleObjects.LinkToTail(newObject);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void UpdateInRangeObjects(CDataStore* msg) {
|
||||
uint32_t count;
|
||||
msg->Get(count);
|
||||
|
||||
for (int32_t i = 0; i < count; i++) {
|
||||
SmartGUID guid;
|
||||
*msg >> guid;
|
||||
|
||||
if (guid != ClntObjMgrGetActivePlayer()) {
|
||||
int32_t reenable;
|
||||
auto object = GetUpdateObject(guid, &reenable);
|
||||
|
||||
if (object && reenable) {
|
||||
object->Reenable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ObjectUpdateFirstPass(CDataStore* msg, uint32_t time, uint32_t updateIdx, uint32_t updateCount) {
|
||||
for (uint32_t i = updateIdx; i < updateCount; i++) {
|
||||
uint8_t updateType;
|
||||
msg->Get(updateType);
|
||||
|
||||
switch (updateType) {
|
||||
case UPDATE_PARTIAL: {
|
||||
if (!UpdateObject(msg)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case UPDATE_MOVEMENT: {
|
||||
// Skipped in first pass
|
||||
|
||||
SmartGUID guid;
|
||||
*msg >> guid;
|
||||
|
||||
CClientMoveUpdate::Skip(msg);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case UPDATE_FULL:
|
||||
case UPDATE_3: {
|
||||
if (!CreateObject(msg, time)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case UPDATE_IN_RANGE: {
|
||||
UpdateInRangeObjects(msg);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
STORM_APP_FATAL("Unknown client update packet type (%d)!", updateType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t ObjectUpdateSecondPass(CDataStore* msg, uint32_t time, uint32_t updateCount) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ObjectCompressedUpdateHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) {
|
||||
uint32_t origSize;
|
||||
@ -60,9 +381,51 @@ int32_t ObjectCompressedUpdateHandler(void* param, NETMESSAGE msgId, uint32_t ti
|
||||
}
|
||||
|
||||
int32_t ObjectUpdateHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) {
|
||||
WHOA_UNIMPLEMENTED(0);
|
||||
uint32_t updateCount;
|
||||
msg->Get(updateCount);
|
||||
|
||||
auto startPos = msg->Tell();
|
||||
|
||||
uint8_t firstUpdateType;
|
||||
msg->Get(firstUpdateType);
|
||||
|
||||
uint32_t updateIdx = 0;
|
||||
|
||||
if (firstUpdateType == UPDATE_OUT_OF_RANGE) {
|
||||
UpdateOutOfRangeObjects(msg);
|
||||
updateIdx = 1;
|
||||
} else {
|
||||
msg->Seek(startPos);
|
||||
}
|
||||
|
||||
int32_t result = 0;
|
||||
|
||||
if (ObjectUpdateFirstPass(msg, time, updateIdx, updateCount)) {
|
||||
msg->Seek(startPos);
|
||||
result = ObjectUpdateSecondPass(msg, time, updateCount);
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t OnObjectDestroy(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) {
|
||||
WHOA_UNIMPLEMENTED(0);
|
||||
WOWGUID guid;
|
||||
msg->Get(guid);
|
||||
|
||||
uint8_t dead;
|
||||
msg->Get(dead);
|
||||
|
||||
auto object = FindActiveObject(guid);
|
||||
|
||||
if (object) {
|
||||
// TODO handle unit death
|
||||
|
||||
if (HandleObjectOutOfRangePass1(object, OUT_OF_RANGE_1)) {
|
||||
HandleObjectOutOfRangePass2(object);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
187
src/object/client/Mirror.cpp
Normal file
187
src/object/client/Mirror.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
#include "object/client/Mirror.hpp"
|
||||
#include "object/client/CGContainer.hpp"
|
||||
#include "object/client/CGCorpse.hpp"
|
||||
#include "object/client/CGDynamicObject.hpp"
|
||||
#include "object/client/CGGameObject.hpp"
|
||||
#include "object/client/CGItem.hpp"
|
||||
#include "object/client/CGObject_C.hpp"
|
||||
#include "object/client/CGPlayer.hpp"
|
||||
#include "object/client/CGUnit.hpp"
|
||||
#include "object/client/ObjMgr.hpp"
|
||||
#include "object/Types.hpp"
|
||||
#include <common/DataStore.hpp>
|
||||
|
||||
#define MAX_CHANGE_MASKS 42
|
||||
|
||||
static uint32_t s_objMirrorBlocks[] = {
|
||||
CGObject::TotalFields(),
|
||||
CGItem::TotalFields(),
|
||||
CGContainer::TotalFields(),
|
||||
CGUnit::TotalFields(),
|
||||
CGPlayer::TotalFields(),
|
||||
CGGameObject::TotalFields(),
|
||||
CGDynamicObject::TotalFields(),
|
||||
CGCorpse::TotalFields(),
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a message data store, extract the dirty change masks contained inside. Any masks not
|
||||
* present are zeroed out. This function assumes the provided masks pointer has enough space for
|
||||
* MAX_CHANGE_MASKS.
|
||||
*/
|
||||
int32_t ExtractDirtyMasks(CDataStore* msg, uint8_t* maskCount, uint32_t* masks) {
|
||||
uint8_t count;
|
||||
msg->Get(count);
|
||||
|
||||
*maskCount = count;
|
||||
|
||||
if (count > MAX_CHANGE_MASKS) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < count; i++) {
|
||||
msg->Get(masks[i]);
|
||||
}
|
||||
|
||||
// Zero out masks that aren't present
|
||||
memset(&masks[count], 0, (MAX_CHANGE_MASKS - count) * sizeof(uint32_t));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an object type hierarchy and GUID, return the number of DWORD blocks backing the object's
|
||||
* data storage.
|
||||
*/
|
||||
uint32_t GetNumDwordBlocks(OBJECT_TYPE type, WOWGUID guid) {
|
||||
switch (type) {
|
||||
case HIER_TYPE_OBJECT:
|
||||
return CGObject::TotalFields();
|
||||
|
||||
case HIER_TYPE_ITEM:
|
||||
return CGItem::TotalFields();
|
||||
|
||||
case HIER_TYPE_CONTAINER:
|
||||
return CGContainer::TotalFields();
|
||||
|
||||
case HIER_TYPE_UNIT:
|
||||
return CGUnit::TotalFields();
|
||||
|
||||
case HIER_TYPE_PLAYER:
|
||||
return guid == ClntObjMgrGetActivePlayer() ? CGPlayer::TotalFields() : CGPlayer::TotalRemoteFields();
|
||||
|
||||
case HIER_TYPE_GAMEOBJECT:
|
||||
return CGGameObject::TotalFields();
|
||||
|
||||
case HIER_TYPE_DYNAMICOBJECT:
|
||||
return CGDynamicObject::TotalFields();
|
||||
|
||||
case HIER_TYPE_CORPSE:
|
||||
return CGCorpse::TotalFields();
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accounting for the full hierarchy of the given object, return the next inherited type ID after
|
||||
* the given current type ID. If there is no next inherited type, return NUM_CLIENT_OBJECT_TYPES
|
||||
* to indicate the end of the hierarchy.
|
||||
*/
|
||||
OBJECT_TYPE_ID IncTypeID(CGObject_C* object, OBJECT_TYPE_ID curTypeID) {
|
||||
switch (object->m_obj->m_type) {
|
||||
// ID_OBJECT -> ID_ITEM -> ID_CONTAINER
|
||||
case HIER_TYPE_ITEM:
|
||||
case HIER_TYPE_CONTAINER:
|
||||
if (curTypeID == ID_OBJECT) {
|
||||
return ID_ITEM;
|
||||
}
|
||||
|
||||
if (curTypeID == ID_ITEM) {
|
||||
return ID_CONTAINER;
|
||||
}
|
||||
|
||||
return NUM_CLIENT_OBJECT_TYPES;
|
||||
|
||||
// ID_OBJECT -> ID_UNIT -> ID_PLAYER
|
||||
case HIER_TYPE_UNIT:
|
||||
case HIER_TYPE_PLAYER:
|
||||
if (curTypeID == ID_OBJECT) {
|
||||
return ID_UNIT;
|
||||
}
|
||||
|
||||
if (curTypeID == ID_UNIT) {
|
||||
return ID_PLAYER;
|
||||
}
|
||||
|
||||
return NUM_CLIENT_OBJECT_TYPES;
|
||||
|
||||
// ID_OBJECT -> ID_GAMEOBJECT
|
||||
case HIER_TYPE_GAMEOBJECT:
|
||||
if (curTypeID == ID_OBJECT) {
|
||||
return ID_GAMEOBJECT;
|
||||
}
|
||||
|
||||
return NUM_CLIENT_OBJECT_TYPES;
|
||||
|
||||
// ID_OBJECT -> ID_DYNAMICOBJECT
|
||||
case HIER_TYPE_DYNAMICOBJECT:
|
||||
if (curTypeID == ID_OBJECT) {
|
||||
return ID_DYNAMICOBJECT;
|
||||
}
|
||||
|
||||
return NUM_CLIENT_OBJECT_TYPES;
|
||||
|
||||
// ID_OBJECT -> ID_CORPSE
|
||||
case HIER_TYPE_CORPSE:
|
||||
if (curTypeID == ID_OBJECT) {
|
||||
return ID_CORPSE;
|
||||
}
|
||||
|
||||
return NUM_CLIENT_OBJECT_TYPES;
|
||||
|
||||
default:
|
||||
return NUM_CLIENT_OBJECT_TYPES;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t IsMaskBitSet(uint32_t* masks, uint32_t block) {
|
||||
return masks[block / 32] & (1 << (block % 32));
|
||||
}
|
||||
|
||||
int32_t FillInPartialObjectData(CGObject_C* object, WOWGUID guid, CDataStore* msg, bool forFullUpdate, bool zeroZeroBits) {
|
||||
uint8_t changeMaskCount;
|
||||
uint32_t changeMasks[MAX_CHANGE_MASKS];
|
||||
if (!ExtractDirtyMasks(msg, &changeMaskCount, changeMasks)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
OBJECT_TYPE_ID typeID = ID_OBJECT;
|
||||
uint32_t blockOffset = 0;
|
||||
uint32_t numBlocks = GetNumDwordBlocks(object->m_obj->m_type, guid);
|
||||
|
||||
for (int32_t block = 0; block < numBlocks; block++) {
|
||||
if (block >= s_objMirrorBlocks[typeID]) {
|
||||
blockOffset = s_objMirrorBlocks[typeID];
|
||||
typeID = IncTypeID(object, typeID);
|
||||
}
|
||||
|
||||
if (!forFullUpdate) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
if (IsMaskBitSet(changeMasks, block)) {
|
||||
uint32_t blockValue;
|
||||
msg->GetArray(reinterpret_cast<uint8_t*>(&blockValue), sizeof(blockValue));
|
||||
|
||||
object->SetBlock(block, blockValue);
|
||||
} else if (zeroZeroBits) {
|
||||
object->SetBlock(block, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
return 1;
|
||||
}
|
||||
12
src/object/client/Mirror.hpp
Normal file
12
src/object/client/Mirror.hpp
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef OBJECT_CLIENT_MIRROR_HPP
|
||||
#define OBJECT_CLIENT_MIRROR_HPP
|
||||
|
||||
#include "util/GUID.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
class CDataStore;
|
||||
class CGObject_C;
|
||||
|
||||
int32_t FillInPartialObjectData(CGObject_C* object, WOWGUID guid, CDataStore* msg, bool forFullUpdate, bool zeroZeroBits);
|
||||
|
||||
#endif
|
||||
@ -11,6 +11,7 @@
|
||||
#include "object/client/CGPlayer_C.hpp"
|
||||
#include "object/client/CGUnit_C.hpp"
|
||||
#include "object/client/MessageHandlers.hpp"
|
||||
#include "object/client/Util.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include <common/ObjectAlloc.hpp>
|
||||
#include <storm/Memory.hpp>
|
||||
@ -26,14 +27,14 @@ static ClntObjMgr* s_curMgr;
|
||||
#endif
|
||||
|
||||
static uint32_t s_objTotalSize[] = {
|
||||
static_cast<uint32_t>(sizeof(CGObject_C) + sizeof(CGObjectData) + (sizeof(uint32_t) * CGObject::TotalFieldsSaved())),
|
||||
static_cast<uint32_t>(sizeof(CGItem_C) + sizeof(CGItemData) + (sizeof(uint32_t) * CGItem::TotalFieldsSaved())),
|
||||
static_cast<uint32_t>(sizeof(CGContainer_C) + sizeof(CGContainerData) + (sizeof(uint32_t) * CGContainer::TotalFieldsSaved())),
|
||||
static_cast<uint32_t>(sizeof(CGUnit_C) + sizeof(CGUnitData) + (sizeof(uint32_t) * CGUnit::TotalFieldsSaved())),
|
||||
static_cast<uint32_t>(sizeof(CGPlayer_C) + sizeof(CGPlayerData) + (sizeof(uint32_t) * CGPlayer::TotalRemoteFieldsSaved())),
|
||||
static_cast<uint32_t>(sizeof(CGGameObject_C) + sizeof(CGGameObjectData) + (sizeof(uint32_t) * CGGameObject::TotalFieldsSaved())),
|
||||
static_cast<uint32_t>(sizeof(CGDynamicObject_C) + sizeof(CGDynamicObjectData) + (sizeof(uint32_t) * CGDynamicObject::TotalFieldsSaved())),
|
||||
static_cast<uint32_t>(sizeof(CGCorpse_C) + sizeof(CGCorpseData) + (sizeof(uint32_t) * CGCorpse::TotalFieldsSaved())),
|
||||
static_cast<uint32_t>(sizeof(CGObject_C) + CGObject::GetDataSize() + CGObject::GetDataSizeSaved()),
|
||||
static_cast<uint32_t>(sizeof(CGItem_C) + CGItem::GetDataSize() + CGItem::GetDataSizeSaved()),
|
||||
static_cast<uint32_t>(sizeof(CGContainer_C) + CGContainer::GetDataSize() + CGContainer::GetDataSizeSaved()),
|
||||
static_cast<uint32_t>(sizeof(CGUnit_C) + CGUnit::GetDataSize() + CGUnit::GetDataSizeSaved()),
|
||||
static_cast<uint32_t>(sizeof(CGPlayer_C) + CGPlayer::GetRemoteDataSize() + CGPlayer::GetRemoteDataSizeSaved()),
|
||||
static_cast<uint32_t>(sizeof(CGGameObject_C) + CGGameObject::GetDataSize() + CGGameObject::GetDataSizeSaved()),
|
||||
static_cast<uint32_t>(sizeof(CGDynamicObject_C) + CGDynamicObject::GetDataSize() + CGDynamicObject::GetDataSizeSaved()),
|
||||
static_cast<uint32_t>(sizeof(CGCorpse_C) + CGCorpse::GetDataSize() + CGCorpse::GetDataSizeSaved()),
|
||||
};
|
||||
|
||||
static const char* s_objNames[] = {
|
||||
@ -66,12 +67,12 @@ void MirrorInitialize() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void* ClntObjMgrAllocObject(OBJECT_TYPE_ID typeID, uint64_t guid) {
|
||||
CGObject_C* ClntObjMgrAllocObject(OBJECT_TYPE_ID typeID, WOWGUID guid) {
|
||||
auto playerGUID = ClntObjMgrGetActivePlayer();
|
||||
|
||||
// Heap allocate player object for current player
|
||||
if (guid == playerGUID) {
|
||||
return STORM_ALLOC(sizeof(CGPlayer_C) + sizeof(CGPlayerData) + (sizeof(uint32_t) * CGPlayer::TotalFieldsSaved()));
|
||||
return static_cast<CGObject_C*>(STORM_ALLOC(sizeof(CGPlayer_C) + CGPlayer::GetDataSize() + CGPlayer::GetDataSizeSaved()));
|
||||
}
|
||||
|
||||
// TODO GarbageCollect(typeID, 10000);
|
||||
@ -84,12 +85,13 @@ void* ClntObjMgrAllocObject(OBJECT_TYPE_ID typeID, uint64_t guid) {
|
||||
}
|
||||
|
||||
// TODO pointer should be fetched via ObjectPtr
|
||||
static_cast<CGObject_C*>(mem)->m_memHandle = memHandle;
|
||||
auto object = static_cast<CGObject_C*>(mem);
|
||||
object->m_memHandle = memHandle;
|
||||
|
||||
return mem;
|
||||
return object;
|
||||
}
|
||||
|
||||
uint64_t ClntObjMgrGetActivePlayer() {
|
||||
WOWGUID ClntObjMgrGetActivePlayer() {
|
||||
if (!s_curMgr) {
|
||||
return 0;
|
||||
}
|
||||
@ -138,6 +140,29 @@ void ClntObjMgrInitializeStd(uint32_t mapID) {
|
||||
mgr->m_mapID = mapID;
|
||||
}
|
||||
|
||||
void ClntObjMgrLinkInNewObject(CGObject_C* object) {
|
||||
CHashKeyGUID key(object->m_obj->m_guid);
|
||||
s_curMgr->m_objects.Insert(object, object->m_obj->m_guid, key);
|
||||
}
|
||||
|
||||
CGObject_C* ClntObjMgrObjectPtr(WOWGUID guid, OBJECT_TYPE type, const char* fileName, int32_t lineNumber) {
|
||||
if (!s_curMgr || !guid) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto object = FindActiveObject(guid);
|
||||
|
||||
if (!object) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!(object->m_obj->m_type & type)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
void ClntObjMgrPop() {
|
||||
if (!s_savMgr) {
|
||||
return;
|
||||
@ -156,7 +181,7 @@ void ClntObjMgrPush(ClntObjMgr* mgr) {
|
||||
s_curMgr = mgr;
|
||||
}
|
||||
|
||||
void ClntObjMgrSetActivePlayer(uint64_t guid) {
|
||||
void ClntObjMgrSetActivePlayer(WOWGUID guid) {
|
||||
s_curMgr->m_activePlayer = guid;
|
||||
}
|
||||
|
||||
|
||||
@ -6,9 +6,9 @@
|
||||
#include "object/Types.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
void* ClntObjMgrAllocObject(OBJECT_TYPE_ID typeID, uint64_t guid);
|
||||
CGObject_C* ClntObjMgrAllocObject(OBJECT_TYPE_ID typeID, WOWGUID guid);
|
||||
|
||||
uint64_t ClntObjMgrGetActivePlayer();
|
||||
WOWGUID ClntObjMgrGetActivePlayer();
|
||||
|
||||
ClntObjMgr* ClntObjMgrGetCurrent();
|
||||
|
||||
@ -18,11 +18,15 @@ void ClntObjMgrInitializeShared();
|
||||
|
||||
void ClntObjMgrInitializeStd(uint32_t mapID);
|
||||
|
||||
void ClntObjMgrLinkInNewObject(CGObject_C* object);
|
||||
|
||||
CGObject_C* ClntObjMgrObjectPtr(WOWGUID guid, OBJECT_TYPE type, const char* fileName, int32_t lineNumber);
|
||||
|
||||
void ClntObjMgrPop();
|
||||
|
||||
void ClntObjMgrPush(ClntObjMgr* mgr);
|
||||
|
||||
void ClntObjMgrSetActivePlayer(uint64_t guid);
|
||||
void ClntObjMgrSetActivePlayer(WOWGUID guid);
|
||||
|
||||
void ClntObjMgrSetHandlers();
|
||||
|
||||
|
||||
142
src/object/client/Util.cpp
Normal file
142
src/object/client/Util.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
#include "object/client/Util.hpp"
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGContainer_C.hpp"
|
||||
#include "object/client/CGCorpse_C.hpp"
|
||||
#include "object/client/CGDynamicObject_C.hpp"
|
||||
#include "object/client/CGGameObject_C.hpp"
|
||||
#include "object/client/CGItem_C.hpp"
|
||||
#include "object/client/CGObject_C.hpp"
|
||||
#include "object/client/CGPlayer_C.hpp"
|
||||
#include "object/client/CGUnit_C.hpp"
|
||||
#include "object/client/ObjMgr.hpp"
|
||||
|
||||
CGObject_C* FindActiveObject(WOWGUID guid) {
|
||||
return ClntObjMgrGetCurrent()->m_objects.Ptr(guid, CHashKeyGUID(guid));
|
||||
}
|
||||
|
||||
CGObject_C* GetUpdateObject(WOWGUID guid, int32_t* reenable) {
|
||||
*reenable = false;
|
||||
|
||||
// Active object
|
||||
|
||||
auto activeObject = FindActiveObject(guid);
|
||||
|
||||
if (activeObject) {
|
||||
activeObject->SetDisablePending(false);
|
||||
|
||||
return activeObject;
|
||||
}
|
||||
|
||||
// Disabled object
|
||||
|
||||
auto disabledObject = ClntObjMgrGetCurrent()->m_lazyCleanupObjects.Ptr(guid, CHashKeyGUID(guid));
|
||||
|
||||
if (disabledObject) {
|
||||
ClntObjMgrGetCurrent()->m_lazyCleanupObjects.Unlink(disabledObject);
|
||||
disabledObject->m_link.Unlink();
|
||||
|
||||
ClntObjMgrGetCurrent()->m_objects.Insert(disabledObject, guid, CHashKeyGUID(guid));
|
||||
|
||||
// These link checks are guaranteed to pass because of the unlink above (both lists share
|
||||
// the same link). This check is either from an inlined function or is cruft left behind
|
||||
// after a refactor.
|
||||
if (
|
||||
!ClntObjMgrGetCurrent()->m_visibleObjects.IsLinked(disabledObject)
|
||||
&& !ClntObjMgrGetCurrent()->m_reenabledObjects.IsLinked(disabledObject)
|
||||
) {
|
||||
*reenable = true;
|
||||
ClntObjMgrGetCurrent()->m_reenabledObjects.LinkToTail(disabledObject);
|
||||
}
|
||||
|
||||
return disabledObject;
|
||||
}
|
||||
|
||||
// Object not found
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t HandleObjectOutOfRangePass1(CGObject_C* object, OUT_OF_RANGE_TYPE type) {
|
||||
// TODO arena unit out of range handling
|
||||
|
||||
object->HandleOutOfRange(type);
|
||||
|
||||
if (object->IsObjectLocked()) {
|
||||
object->SetDisablePending(true);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
object->SetDisablePending(false);
|
||||
object->Disable();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleObjectOutOfRangePass2(CGObject_C* object) {
|
||||
// TODO ClearObjectMirrorHandlers(object);
|
||||
|
||||
ClntObjMgrGetCurrent()->m_objects.Unlink(object);
|
||||
|
||||
if (ClntObjMgrGetCurrent()->m_visibleObjects.IsLinked(object)) {
|
||||
ClntObjMgrGetCurrent()->m_visibleObjects.UnlinkNode(object);
|
||||
}
|
||||
|
||||
ClntObjMgrGetCurrent()->m_lazyCleanupObjects.Insert(object, object->m_hashval, CHashKeyGUID(object->m_key));
|
||||
ClntObjMgrGetCurrent()->m_lazyCleanupFifo[object->m_typeID - 1].LinkToTail(object);
|
||||
}
|
||||
|
||||
void InitObject(CGObject_C* object, uint32_t time, CClientObjCreate& objCreate) {
|
||||
switch (object->m_typeID) {
|
||||
case ID_ITEM: {
|
||||
new (object) CGItem_C(time, objCreate);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_CONTAINER: {
|
||||
new (object) CGContainer_C(time, objCreate);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_UNIT: {
|
||||
new (object) CGUnit_C(time, objCreate);
|
||||
object->AddWorldObject();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_PLAYER: {
|
||||
new (object) CGPlayer_C(time, objCreate);
|
||||
object->AddWorldObject();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_GAMEOBJECT: {
|
||||
new (object) CGGameObject_C(time, objCreate);
|
||||
object->AddWorldObject();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_DYNAMICOBJECT: {
|
||||
new (object) CGDynamicObject_C(time, objCreate);
|
||||
object->AddWorldObject();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_CORPSE: {
|
||||
new (object) CGCorpse_C(time, objCreate);
|
||||
object->AddWorldObject();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
21
src/object/client/Util.hpp
Normal file
21
src/object/client/Util.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef OBJECT_CLIENT_UTIL_HPP
|
||||
#define OBJECT_CLIENT_UTIL_HPP
|
||||
|
||||
#include "object/Types.hpp"
|
||||
#include "util/GUID.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
class CClientObjCreate;
|
||||
class CGObject_C;
|
||||
|
||||
CGObject_C* FindActiveObject(WOWGUID guid);
|
||||
|
||||
CGObject_C* GetUpdateObject(WOWGUID guid, int32_t* reenable);
|
||||
|
||||
int32_t HandleObjectOutOfRangePass1(CGObject_C* object, OUT_OF_RANGE_TYPE type);
|
||||
|
||||
void HandleObjectOutOfRangePass2(CGObject_C* object);
|
||||
|
||||
void InitObject(CGObject_C* object, uint32_t time, CClientObjCreate& objCreate);
|
||||
|
||||
#endif
|
||||
55
src/object/movement/CMoveSpline.cpp
Normal file
55
src/object/movement/CMoveSpline.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include "object/movement/CMoveSpline.hpp"
|
||||
#include "util/DataStore.hpp"
|
||||
#include <common/Time.hpp>
|
||||
|
||||
void CMoveSpline::Skip(CDataStore* msg) {
|
||||
uint32_t flags;
|
||||
msg->Get(flags);
|
||||
|
||||
uint32_t faceBytes = 0;
|
||||
|
||||
if (flags & 0x20000) {
|
||||
faceBytes = 4;
|
||||
} else if (flags & 0x10000) {
|
||||
faceBytes = 8;
|
||||
} else if (flags & 0x8000) {
|
||||
faceBytes = 12;
|
||||
}
|
||||
|
||||
void* data;
|
||||
msg->GetDataInSitu(data, faceBytes + 28);
|
||||
|
||||
uint32_t splinePoints = 0;
|
||||
msg->Get(splinePoints);
|
||||
|
||||
msg->GetDataInSitu(data, (splinePoints * sizeof(C3Vector)) + 13);
|
||||
}
|
||||
|
||||
CDataStore& operator>>(CDataStore& msg, CMoveSpline& spline) {
|
||||
msg.Get(spline.flags);
|
||||
|
||||
if (spline.flags & 0x20000) {
|
||||
msg.Get(spline.face.facing);
|
||||
} else if (spline.flags & 0x10000) {
|
||||
msg.Get(spline.face.guid);
|
||||
} else if (spline.flags & 0x8000) {
|
||||
msg >> spline.face.spot;
|
||||
}
|
||||
|
||||
uint32_t val;
|
||||
msg.Get(val);
|
||||
spline.start = OsGetAsyncTimeMsPrecise() - val;
|
||||
|
||||
msg.Get(spline.uint2C);
|
||||
msg.Get(spline.uint30);
|
||||
msg.Get(spline.float204);
|
||||
msg.Get(spline.float208);
|
||||
msg.Get(spline.float20C);
|
||||
msg.Get(spline.uint210);
|
||||
|
||||
msg >> spline.spline;
|
||||
|
||||
msg >> spline.vector1F8;
|
||||
|
||||
return msg;
|
||||
}
|
||||
34
src/object/movement/CMoveSpline.hpp
Normal file
34
src/object/movement/CMoveSpline.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef OBJECT_MOVEMENT_C_MOVE_SPLINE_HPP
|
||||
#define OBJECT_MOVEMENT_C_MOVE_SPLINE_HPP
|
||||
|
||||
#include "util/C3Spline.hpp"
|
||||
#include "util/GUID.hpp"
|
||||
#include <common/DataStore.hpp>
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
struct CMoveSpline {
|
||||
// TODO
|
||||
union {
|
||||
C3Vector spot = {};
|
||||
WOWGUID guid;
|
||||
float facing;
|
||||
} face;
|
||||
uint32_t flags;
|
||||
uint32_t start;
|
||||
// TODO
|
||||
uint32_t uint2C;
|
||||
uint32_t uint30;
|
||||
C3Spline_CatmullRom spline;
|
||||
C3Vector vector1F8;
|
||||
float float204;
|
||||
float float208;
|
||||
float float20C;
|
||||
uint32_t uint210;
|
||||
// TODO
|
||||
|
||||
static void Skip(CDataStore* msg);
|
||||
};
|
||||
|
||||
CDataStore& operator>>(CDataStore& msg, CMoveSpline& spline);
|
||||
|
||||
#endif
|
||||
81
src/object/movement/CMovementStatus.cpp
Normal file
81
src/object/movement/CMovementStatus.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
#include "object/movement/CMovementStatus.hpp"
|
||||
#include "util/DataStore.hpp"
|
||||
|
||||
uint32_t CMovementStatus::Skip(CDataStore* msg) {
|
||||
uint32_t moveFlags = 0;
|
||||
msg->Get(moveFlags);
|
||||
|
||||
uint16_t uint14;
|
||||
msg->Get(uint14);
|
||||
|
||||
void* data;
|
||||
msg->GetDataInSitu(data, 20);
|
||||
|
||||
uint32_t skipBytes = 0;
|
||||
|
||||
if (moveFlags & 0x200) {
|
||||
SmartGUID guid;
|
||||
*msg >> guid;
|
||||
|
||||
skipBytes += 21;
|
||||
|
||||
if (uint14 & 0x400) {
|
||||
skipBytes += 4;
|
||||
}
|
||||
}
|
||||
|
||||
if ((moveFlags & (0x200000 | 0x2000000)) || (uint14 & 0x20)) {
|
||||
skipBytes += 4;
|
||||
}
|
||||
|
||||
skipBytes += 4;
|
||||
|
||||
if (moveFlags & 0x1000) {
|
||||
skipBytes += 16;
|
||||
}
|
||||
|
||||
if (moveFlags & 0x4000000) {
|
||||
skipBytes += 4;
|
||||
}
|
||||
|
||||
msg->GetDataInSitu(data, skipBytes);
|
||||
|
||||
return moveFlags;
|
||||
}
|
||||
|
||||
CDataStore& operator>>(CDataStore& msg, CMovementStatus& move) {
|
||||
msg.Get(move.moveFlags);
|
||||
msg.Get(move.uint14);
|
||||
msg.Get(move.uint0);
|
||||
|
||||
msg >> move.position18;
|
||||
msg.Get(move.facing34);
|
||||
|
||||
if (move.moveFlags & 0x200) {
|
||||
// TODO
|
||||
} else {
|
||||
move.transport = 0;
|
||||
// TODO
|
||||
}
|
||||
|
||||
if ((move.moveFlags & (0x200000 | 0x2000000)) || (move.uint14 & 0x20)) {
|
||||
msg.Get(move.float38);
|
||||
} else {
|
||||
move.float38 = 0.0f;
|
||||
}
|
||||
|
||||
msg.Get(move.uint3C);
|
||||
|
||||
if (move.moveFlags & 0x1000) {
|
||||
msg.Get(move.float40);
|
||||
msg.Get(move.float44);
|
||||
msg.Get(move.float48);
|
||||
msg.Get(move.float4C);
|
||||
}
|
||||
|
||||
if (move.moveFlags & 0x4000000) {
|
||||
msg.Get(move.float50);
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
34
src/object/movement/CMovementStatus.hpp
Normal file
34
src/object/movement/CMovementStatus.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef OBJECT_MOVEMENT_C_MOVEMENT_STATUS_HPP
|
||||
#define OBJECT_MOVEMENT_C_MOVEMENT_STATUS_HPP
|
||||
|
||||
#include "util/GUID.hpp"
|
||||
#include <common/DataStore.hpp>
|
||||
#include <tempest/Vector.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
struct CMovementStatus {
|
||||
uint32_t uint0 = 0;
|
||||
// TODO
|
||||
WOWGUID transport = 0;
|
||||
uint32_t moveFlags = 0x0;
|
||||
uint16_t uint14 = 0;
|
||||
// TODO
|
||||
C3Vector position18;
|
||||
float facing24 = 0.0f;
|
||||
C3Vector position28;
|
||||
float facing34 = 0.0f;
|
||||
float float38 = 0.0f;
|
||||
uint32_t uint3C = 0;
|
||||
float float40 = 0.0f;
|
||||
float float44 = 0.0f;
|
||||
float float48 = 0.0f;
|
||||
float float4C = 0.0f;
|
||||
float float50 = 0.0f;
|
||||
// TODO
|
||||
|
||||
static uint32_t Skip(CDataStore* msg);
|
||||
};
|
||||
|
||||
CDataStore& operator>>(CDataStore& msg, CMovementStatus& move);
|
||||
|
||||
#endif
|
||||
20
src/util/C3Spline.cpp
Normal file
20
src/util/C3Spline.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include "util/C3Spline.hpp"
|
||||
#include <tempest/vector/C3Vector.hpp>
|
||||
|
||||
CDataStore& operator>>(CDataStore& msg, C3Spline_CatmullRom& spline) {
|
||||
uint32_t pointCount = 0;
|
||||
msg.Get(pointCount);
|
||||
|
||||
void* points;
|
||||
msg.GetDataInSitu(points, sizeof(C3Vector) * pointCount);
|
||||
|
||||
uint8_t splineMode;
|
||||
msg.Get(splineMode);
|
||||
// TODO spline.splineMode = splineMode;
|
||||
|
||||
if (pointCount && msg.IsValid()) {
|
||||
// TODO spline.SetPoints()
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
20
src/util/C3Spline.hpp
Normal file
20
src/util/C3Spline.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef UTIL_C3_SPLINE_HPP
|
||||
#define UTIL_C3_SPLINE_HPP
|
||||
|
||||
#include <common/DataStore.hpp>
|
||||
|
||||
// TODO move these classes to typhoon
|
||||
class C3Spline {
|
||||
public:
|
||||
// TODO
|
||||
};
|
||||
|
||||
class C3Spline_CatmullRom : public C3Spline {
|
||||
public:
|
||||
// TODO
|
||||
};
|
||||
|
||||
// TODO move this operator>> to util/DataStore.hpp
|
||||
CDataStore& operator>>(CDataStore& msg, C3Spline_CatmullRom& spline);
|
||||
|
||||
#endif
|
||||
@ -1,9 +0,0 @@
|
||||
#include "util/CHashKeyGUID.hpp"
|
||||
|
||||
CHashKeyGUID::CHashKeyGUID() {
|
||||
this->m_guid = 0;
|
||||
}
|
||||
|
||||
CHashKeyGUID::CHashKeyGUID(uint64_t guid) {
|
||||
this->m_guid = guid;
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
#ifndef UTIL_C_HASH_KEY_GUID_HPP
|
||||
#define UTIL_C_HASH_KEY_GUID_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class CHashKeyGUID {
|
||||
public:
|
||||
// Public member functions
|
||||
CHashKeyGUID();
|
||||
CHashKeyGUID(uint64_t guid);
|
||||
|
||||
private:
|
||||
// Private member variables
|
||||
uint64_t m_guid;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -1,5 +1,6 @@
|
||||
file(GLOB PRIVATE_SOURCES
|
||||
"*.cpp"
|
||||
"guid/*.cpp"
|
||||
)
|
||||
|
||||
if(WHOA_SYSTEM_MAC)
|
||||
|
||||
8
src/util/GUID.hpp
Normal file
8
src/util/GUID.hpp
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef UTIL_GUID_HPP
|
||||
#define UTIL_GUID_HPP
|
||||
|
||||
#include "util/guid/CHashKeyGUID.hpp"
|
||||
#include "util/guid/SmartGUID.hpp"
|
||||
#include "util/guid/Types.hpp"
|
||||
|
||||
#endif
|
||||
17
src/util/guid/CHashKeyGUID.cpp
Normal file
17
src/util/guid/CHashKeyGUID.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
#include "util/guid/CHashKeyGUID.hpp"
|
||||
|
||||
CHashKeyGUID::CHashKeyGUID() {
|
||||
this->m_guid = 0;
|
||||
}
|
||||
|
||||
CHashKeyGUID::CHashKeyGUID(WOWGUID guid) {
|
||||
this->m_guid = guid;
|
||||
}
|
||||
|
||||
bool CHashKeyGUID::operator==(WOWGUID guid) const {
|
||||
return this->m_guid == guid;
|
||||
}
|
||||
|
||||
bool CHashKeyGUID::operator==(const CHashKeyGUID& key) const {
|
||||
return this->m_guid == key.m_guid;
|
||||
}
|
||||
20
src/util/guid/CHashKeyGUID.hpp
Normal file
20
src/util/guid/CHashKeyGUID.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef UTIL_GUID_C_HASH_KEY_GUID_HPP
|
||||
#define UTIL_GUID_C_HASH_KEY_GUID_HPP
|
||||
|
||||
#include "util/guid/Types.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
class CHashKeyGUID {
|
||||
public:
|
||||
// Public member functions
|
||||
CHashKeyGUID();
|
||||
CHashKeyGUID(WOWGUID guid);
|
||||
bool operator==(WOWGUID guid) const;
|
||||
bool operator==(const CHashKeyGUID& key) const;
|
||||
|
||||
private:
|
||||
// Private member variables
|
||||
WOWGUID m_guid;
|
||||
};
|
||||
|
||||
#endif
|
||||
29
src/util/guid/SmartGUID.cpp
Normal file
29
src/util/guid/SmartGUID.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
#include "util/guid/SmartGUID.hpp"
|
||||
#include <common/DataStore.hpp>
|
||||
|
||||
SmartGUID::operator WOWGUID() const {
|
||||
return this->guid;
|
||||
}
|
||||
|
||||
SmartGUID& SmartGUID::operator=(WOWGUID guid) {
|
||||
this->guid = guid;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CDataStore& operator>>(CDataStore& msg, SmartGUID& guid) {
|
||||
guid = 0;
|
||||
|
||||
uint8_t mask;
|
||||
msg.Get(mask);
|
||||
|
||||
for (int32_t i = 0; i < 8; i++) {
|
||||
if (mask & (1 << i)) {
|
||||
uint8_t byte;
|
||||
msg.Get(byte);
|
||||
|
||||
guid.guid |= static_cast<uint64_t>(byte) << (i * 8);
|
||||
}
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
18
src/util/guid/SmartGUID.hpp
Normal file
18
src/util/guid/SmartGUID.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef UTIL_GUID_SMART_GUID_HPP
|
||||
#define UTIL_GUID_SMART_GUID_HPP
|
||||
|
||||
#include "util/guid/Types.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
class CDataStore;
|
||||
|
||||
struct SmartGUID {
|
||||
WOWGUID guid;
|
||||
|
||||
operator WOWGUID() const;
|
||||
SmartGUID& operator=(WOWGUID value);
|
||||
};
|
||||
|
||||
CDataStore& operator>>(CDataStore& msg, SmartGUID& guid);
|
||||
|
||||
#endif
|
||||
8
src/util/guid/Types.hpp
Normal file
8
src/util/guid/Types.hpp
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef UTIL_GUID_TYPES_HPP
|
||||
#define UTIL_GUID_TYPES_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
typedef uint64_t WOWGUID;
|
||||
|
||||
#endif
|
||||
@ -6,10 +6,49 @@
|
||||
#include "world/Weather.hpp"
|
||||
#include <storm/Memory.hpp>
|
||||
|
||||
uint32_t CWorld::s_curTimeMs;
|
||||
float CWorld::s_curTimeSec;
|
||||
uint32_t CWorld::s_enables;
|
||||
uint32_t CWorld::s_enables2;
|
||||
uint32_t CWorld::s_gameTimeFixed;
|
||||
float CWorld::s_gameTimeSec;
|
||||
uint32_t CWorld::s_tickTimeFixed;
|
||||
uint32_t CWorld::s_tickTimeMs;
|
||||
float CWorld::s_tickTimeSec;
|
||||
Weather* CWorld::s_weather;
|
||||
|
||||
uint32_t CWorld::GetCurTimeMs() {
|
||||
return CWorld::s_curTimeMs;
|
||||
}
|
||||
|
||||
float CWorld::GetCurTimeSec() {
|
||||
return CWorld::s_curTimeSec;
|
||||
}
|
||||
|
||||
uint32_t CWorld::GetFixedPrecisionTime(float timeSec) {
|
||||
return static_cast<uint32_t>(timeSec * 1024.0f);
|
||||
}
|
||||
|
||||
uint32_t CWorld::GetGameTimeFixed() {
|
||||
return CWorld::s_gameTimeFixed;
|
||||
}
|
||||
|
||||
float CWorld::GetGameTimeSec() {
|
||||
return CWorld::s_gameTimeSec;
|
||||
}
|
||||
|
||||
uint32_t CWorld::GetTickTimeFixed() {
|
||||
return CWorld::s_tickTimeFixed;
|
||||
}
|
||||
|
||||
uint32_t CWorld::GetTickTimeMs() {
|
||||
return CWorld::s_tickTimeMs;
|
||||
}
|
||||
|
||||
float CWorld::GetTickTimeSec() {
|
||||
return CWorld::s_tickTimeSec;
|
||||
}
|
||||
|
||||
void CWorld::Initialize() {
|
||||
CWorld::s_enables |=
|
||||
Enables::Enable_1
|
||||
@ -26,6 +65,9 @@ void CWorld::Initialize() {
|
||||
| Enables::Enable_Particulates
|
||||
| Enables::Enable_LowDetail;
|
||||
|
||||
CWorld::s_gameTimeFixed = 0;
|
||||
CWorld::s_gameTimeSec = 0.0f;
|
||||
|
||||
// TODO
|
||||
|
||||
if (GxCaps().m_shaderTargets[GxSh_Pixel] > GxShPS_none) {
|
||||
@ -58,3 +100,23 @@ void CWorld::LoadMap(const char* mapName, const C3Vector& position, int32_t zone
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
int32_t CWorld::OnTick(const EVENT_DATA_TICK* data, void* param) {
|
||||
CWorld::SetUpdateTime(data->tickTimeSec, data->curTimeMs);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CWorld::SetUpdateTime(float tickTimeSec, uint32_t curTimeMs) {
|
||||
auto tickTimeFixed = CWorld::GetFixedPrecisionTime(tickTimeSec);
|
||||
|
||||
CWorld::s_curTimeMs = curTimeMs;
|
||||
CWorld::s_curTimeSec = static_cast<float>(curTimeMs) * 0.001f;
|
||||
|
||||
CWorld::s_gameTimeFixed += tickTimeFixed;
|
||||
CWorld::s_gameTimeSec += tickTimeSec;
|
||||
|
||||
CWorld::s_tickTimeFixed = tickTimeFixed;
|
||||
CWorld::s_tickTimeMs = static_cast<uint32_t>(tickTimeSec * 1000.0f);
|
||||
CWorld::s_tickTimeSec = tickTimeSec;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#ifndef WORLD_C_WORLD_HPP
|
||||
#define WORLD_C_WORLD_HPP
|
||||
|
||||
#include "event/Event.hpp"
|
||||
#include <tempest/Vector.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
@ -44,14 +45,36 @@ class CWorld {
|
||||
Enable_HwPcf = 0x2
|
||||
};
|
||||
|
||||
// Static variables
|
||||
// Public static variables
|
||||
static uint32_t s_enables;
|
||||
static uint32_t s_enables2;
|
||||
static Weather* s_weather;
|
||||
|
||||
// Static functions
|
||||
static void Initialize(void);
|
||||
// Public static functions
|
||||
static uint32_t GetCurTimeMs();
|
||||
static float GetCurTimeSec();
|
||||
static uint32_t GetGameTimeFixed();
|
||||
static float GetGameTimeSec();
|
||||
static uint32_t GetTickTimeFixed();
|
||||
static uint32_t GetTickTimeMs();
|
||||
static float GetTickTimeSec();
|
||||
static void Initialize();
|
||||
static void LoadMap(const char* mapName, const C3Vector& position, int32_t zoneID);
|
||||
static int32_t OnTick(const EVENT_DATA_TICK* data, void* param);
|
||||
static void SetUpdateTime(float tickTimeSec, uint32_t curTimeMs);
|
||||
|
||||
private:
|
||||
// Private static variables
|
||||
static uint32_t s_curTimeMs;
|
||||
static float s_curTimeSec;
|
||||
static uint32_t s_gameTimeFixed;
|
||||
static float s_gameTimeSec;
|
||||
static uint32_t s_tickTimeFixed;
|
||||
static uint32_t s_tickTimeMs;
|
||||
static float s_tickTimeSec;
|
||||
|
||||
// Private static functions
|
||||
static uint32_t GetFixedPrecisionTime(float timeSec);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue
Block a user