Merge branch 'master' into branch-feat-glue-implement-Script_AcceptedScanning

This commit is contained in:
fallenoak 2026-02-25 20:37:19 -06:00 committed by GitHub
commit 701cc8137b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
240 changed files with 13313 additions and 1073 deletions

@ -1 +1 @@
Subproject commit 48a78025ef77faac80faa30c116f3ced4bbd9251 Subproject commit 39cf7976a899b4f9a1290d0afdbd5011e4af9ac1

@ -1 +1 @@
Subproject commit 1c9e7831c874068e7c939a7dea8790eef6513d78 Subproject commit 1e5366bbc6935e3363abf5921f0be12f902e790a

View File

@ -18,6 +18,7 @@
#include "sound/Interface.hpp" #include "sound/Interface.hpp"
#include "ui/FrameScript.hpp" #include "ui/FrameScript.hpp"
#include "ui/FrameXML.hpp" #include "ui/FrameXML.hpp"
#include "ui/Game.hpp"
#include "util/Random.hpp" #include "util/Random.hpp"
#include "world/World.hpp" #include "world/World.hpp"
#include <bc/Debug.hpp> #include <bc/Debug.hpp>
@ -29,6 +30,8 @@ CVar* Client::g_accountNameVar;
CVar* Client::g_accountListVar; CVar* Client::g_accountListVar;
HEVENTCONTEXT Client::g_clientEventContext; HEVENTCONTEXT Client::g_clientEventContext;
CGameTime g_clientGameTime;
static CVar* s_desktopGammaCvar; static CVar* s_desktopGammaCvar;
static CVar* s_gammaCvar; static CVar* s_gammaCvar;
static CVar* s_textureCacheSizeCvar; static CVar* s_textureCacheSizeCvar;
@ -69,10 +72,28 @@ void BaseInitializeGlobal() {
PropInitialize(); PropInitialize();
} }
int32_t ClientGameTimeTickHandler(const void* data, void* param) {
STORM_ASSERT(data);
g_clientGameTime.GameTimeUpdate(static_cast<const EVENT_DATA_IDLE*>(data)->elapsedSec);
return 1;
}
void ClientInitializeGameTime() {
ClientServices::SetMessageHandler(SMSG_GAME_SPEED_SET, &ReceiveNewGameSpeed, nullptr);
ClientServices::SetMessageHandler(SMSG_LOGIN_SET_TIME_SPEED, &ReceiveNewTimeSpeed, nullptr);
ClientServices::SetMessageHandler(SMSG_GAME_TIME_UPDATE, &ReceiveGameTimeUpdate, nullptr);
ClientServices::SetMessageHandler(SMSG_SERVERTIME, &ReceiveServerTime, nullptr);
ClientServices::SetMessageHandler(SMSG_GAME_TIME_SET, &ReceiveNewGameTime, nullptr);
// TODO initialize s_forcedChangeCallbacks
}
int32_t ClientIdle(const void* data, void* param) { int32_t ClientIdle(const void* data, void* param) {
// TODO ClientGameTimeTickHandler(data, nullptr);
// ClientGameTimeTickHandler(data, param);
// Player_C_ZoneUpdateHandler(data, param); // TODO Player_C_ZoneUpdateHandler(data, nullptr);
return 1; return 1;
} }
@ -85,7 +106,12 @@ void ClientInitializeGame(uint32_t mapId, C3Vector position) {
// TODO // TODO
CGGameUI::InitializeGame();
// TODO
EventRegister(EVENT_ID_IDLE, ClientIdle); EventRegister(EVENT_ID_IDLE, ClientIdle);
ClientInitializeGameTime();
// TODO // TODO
@ -520,8 +546,9 @@ void WowClientDestroy() {
} }
void WowClientInit() { void WowClientInit() {
EventRegister(EVENT_ID_TICK, reinterpret_cast<EVENTHANDLERFUNC>(&CWorld::OnTick));
// TODO // TODO
// EventRegister(EVENT_ID_5, (int)sub_4020E0);
// _cfltcvt_init_0(); // _cfltcvt_init_0();
ClientRegisterConsoleCommands(); ClientRegisterConsoleCommands();

View File

@ -2,6 +2,7 @@
#define CLIENT_CLIENT_HPP #define CLIENT_CLIENT_HPP
#include "event/Event.hpp" #include "event/Event.hpp"
#include "util/Time.hpp"
#include <tempest/Vector.hpp> #include <tempest/Vector.hpp>
class CVar; class CVar;
@ -12,6 +13,8 @@ namespace Client {
extern HEVENTCONTEXT g_clientEventContext; extern HEVENTCONTEXT g_clientEventContext;
} }
extern CGameTime g_clientGameTime;
void ClientInitializeGame(uint32_t mapId, C3Vector position); void ClientInitializeGame(uint32_t mapId, C3Vector position);
void ClientPostClose(int32_t a1); void ClientPostClose(int32_t a1);

View File

@ -1,11 +1,14 @@
#include "client/ClientHandlers.hpp" #include "client/ClientHandlers.hpp"
#include "Client.hpp"
#include "console/Console.hpp" #include "console/Console.hpp"
#include "db/Db.hpp" #include "db/Db.hpp"
#include "object/Client.hpp" #include "object/Client.hpp"
#include "util/Time.hpp"
#include "util/Unimplemented.hpp"
#include "world/World.hpp" #include "world/World.hpp"
#include <common/DataStore.hpp> #include <common/DataStore.hpp>
#include <tempest/Vector.hpp>
#include <cstdint> #include <cstdint>
#include <tempest/Vector.hpp>
static float s_newFacing; static float s_newFacing;
static C3Vector s_newPosition; static C3Vector s_newPosition;
@ -77,6 +80,56 @@ int32_t PlayedTimeHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataSto
return 0; return 0;
} }
int32_t ReceiveGameTimeUpdate(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) {
WHOA_UNIMPLEMENTED(0);
}
int32_t ReceiveNewGameSpeed(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) {
WHOA_UNIMPLEMENTED(0);
}
int32_t ReceiveNewGameTime(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) {
WHOA_UNIMPLEMENTED(0);
}
int32_t ReceiveNewTimeSpeed(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) {
uint32_t encodedTime;
msg->Get(encodedTime);
float newSpeed;
msg->Get(newSpeed);
uint32_t holidayOffset;
msg->Get(holidayOffset);
if (!msg->IsRead()) {
STORM_ASSERT(msg->IsFinal());
// TODO ConsoleWriteA("Malformed message received: Id = %d, Len = %d, Read = %d\n", DEFAULT_COLOR, msgId, msg->Size(), msg->Tell());
return 0;
}
WowTime newTime;
WowTime::WowDecodeTime(encodedTime, &newTime);
newTime.m_holidayOffset = holidayOffset;
g_clientGameTime.GameTimeSetTime(newTime, true);
// TODO UpdateTime();
auto oldSpeed = g_clientGameTime.GameTimeSetMinutesPerSecond(newSpeed);
char logStr[256];
SStrPrintf(logStr, sizeof(logStr), "Gamespeed set from %.03f to %.03f", oldSpeed, newSpeed);
ConsoleWrite(logStr, DEFAULT_COLOR);
return 1;
}
int32_t ReceiveServerTime(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) {
WHOA_UNIMPLEMENTED(0);
}
int32_t TransferAbortedHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) { int32_t TransferAbortedHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) {
// TODO // TODO

View File

@ -14,6 +14,16 @@ int32_t NotifyHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore*
int32_t PlayedTimeHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg); int32_t PlayedTimeHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg);
int32_t ReceiveGameTimeUpdate(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg);
int32_t ReceiveNewGameSpeed(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg);
int32_t ReceiveNewGameTime(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg);
int32_t ReceiveNewTimeSpeed(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg);
int32_t ReceiveServerTime(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg);
int32_t TransferAbortedHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg); int32_t TransferAbortedHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg);
int32_t TransferPendingHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg); int32_t TransferPendingHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg);

View File

@ -121,6 +121,10 @@ bool ComponentCompressCallback(CVar* var, const char* oldValue, const char* valu
return true; return true;
} }
void ReplaceParticleColor(CM2Model* model, int32_t particleColorID) {
// TODO
}
int32_t CCharacterComponent::AddHandItem(CM2Model* model, const ItemDisplayInfoRec* displayRec, INVENTORY_SLOTS invSlot, SHEATHE_TYPE sheatheType, bool sheathed, bool shield, bool a7, int32_t visualID) { int32_t CCharacterComponent::AddHandItem(CM2Model* model, const ItemDisplayInfoRec* displayRec, INVENTORY_SLOTS invSlot, SHEATHE_TYPE sheatheType, bool sheathed, bool shield, bool a7, int32_t visualID) {
if (!model || !displayRec || invSlot > INVSLOT_TABARD) { if (!model || !displayRec || invSlot > INVSLOT_TABARD) {
return -1; return -1;
@ -247,6 +251,26 @@ CCharacterComponent* CCharacterComponent::AllocComponent() {
return component; return component;
} }
void CCharacterComponent::ApplyMonsterGeosets(CM2Model* model, const CreatureDisplayInfoRec* displayInfoRec) {
if (!model || !displayInfoRec || !displayInfoRec->m_creatureGeosetData) {
return;
}
for (int32_t group = 100, dataOfs = 0; group < 900; group += 100, dataOfs += 4) {
auto section = (displayInfoRec->m_creatureGeosetData >> dataOfs) & 0xF;
if (section) {
// Hide all sections in group
model->SetGeometryVisible(group, group + 99, false);
// Show matching section
model->SetGeometryVisible(group + section, group + section, true);
}
}
model->OptimizeVisibleGeometry();
}
void CCharacterComponent::ComponentCloseFingers(CM2Model* model, COMP_HAND_SLOT handSlot) { void CCharacterComponent::ComponentCloseFingers(CM2Model* model, COMP_HAND_SLOT handSlot) {
uint32_t firstBone; uint32_t firstBone;
uint32_t lastBone; uint32_t lastBone;
@ -789,6 +813,54 @@ void CCharacterComponent::RemoveLinkpt(CM2Model* model, GEOCOMPONENTLINKS link)
} }
} }
void CCharacterComponent::ReplaceMonsterSkin(CM2Model* model, const CreatureDisplayInfoRec* displayInfoRec, const CreatureModelDataRec* modelDataRec) {
if (!model || !displayInfoRec || !modelDataRec) {
return;
}
CStatus status;
char texturePath[STORM_MAX_PATH];
// Copy model path to use as base path for texture
auto src = modelDataRec->m_modelName;
auto dst = texturePath;
while (*src) {
*dst++ = *src++;
}
*dst = '\0';
// Locate start of model file name
auto lastSlash = strrchr(texturePath, '\\');
auto modelFileName = lastSlash ? lastSlash + 1 : texturePath;
auto textureFlags = CGxTexFlags(GxTex_LinearMipLinear, 1, 1, 0, 0, 0, 1);
for (uint32_t i = 0; i < 3; i++) {
auto textureName = displayInfoRec->m_textureVariation[i];
if (textureName[0] == '\0') {
continue;
}
// Replace model file name with texture name
src = textureName;
dst = modelFileName;
while (*src) {
*dst++ = *src++;
}
*dst = '\0';
auto texture = TextureCreate(texturePath, textureFlags, &status, 0);
if (texture) {
model->ReplaceTexture(11 + i, texture);
HandleClose(texture);
}
}
ReplaceParticleColor(model, displayInfoRec->m_particleColorID);
}
void CCharacterComponent::UpdateBaseTexture(EGxTexCommand cmd, uint32_t width, uint32_t height, uint32_t depth, uint32_t mipLevel, void* userArg, uint32_t& texelStrideInBytes, const void*& texels) { void CCharacterComponent::UpdateBaseTexture(EGxTexCommand cmd, uint32_t width, uint32_t height, uint32_t depth, uint32_t mipLevel, void* userArg, uint32_t& texelStrideInBytes, const void*& texels) {
auto component = static_cast<CCharacterComponent*>(userArg); auto component = static_cast<CCharacterComponent*>(userArg);

View File

@ -10,6 +10,8 @@
class CACHEENTRY; class CACHEENTRY;
class CCharacterComponent; class CCharacterComponent;
class CharSectionsRec; class CharSectionsRec;
class CreatureDisplayInfoRec;
class CreatureModelDataRec;
class ItemDisplayInfoRec; class ItemDisplayInfoRec;
struct BlpPalPixel; struct BlpPalPixel;
@ -51,6 +53,7 @@ class CCharacterComponent {
static int32_t AddHandItem(CM2Model* model, const ItemDisplayInfoRec* displayRec, INVENTORY_SLOTS invSlot, SHEATHE_TYPE sheatheType, bool sheathed, bool shield, bool a7, int32_t a8); static int32_t AddHandItem(CM2Model* model, const ItemDisplayInfoRec* displayRec, INVENTORY_SLOTS invSlot, SHEATHE_TYPE sheatheType, bool sheathed, bool shield, bool a7, int32_t a8);
static void AddLink(CM2Model* parent, GEOCOMPONENTLINKS link, char const* modelPath, char const* texturePath, int32_t visualID, const ItemDisplayInfoRec* displayRec); static void AddLink(CM2Model* parent, GEOCOMPONENTLINKS link, char const* modelPath, char const* texturePath, int32_t visualID, const ItemDisplayInfoRec* displayRec);
static CCharacterComponent* AllocComponent(); static CCharacterComponent* AllocComponent();
static void ApplyMonsterGeosets(CM2Model* model, const CreatureDisplayInfoRec* displayInfoRec);
static void ComponentCloseFingers(CM2Model* model, COMP_HAND_SLOT handSlot); static void ComponentCloseFingers(CM2Model* model, COMP_HAND_SLOT handSlot);
static void ComponentOpenFingers(CM2Model* model, COMP_HAND_SLOT handSlot); static void ComponentOpenFingers(CM2Model* model, COMP_HAND_SLOT handSlot);
static HTEXTURE CreateTexture(const char* fileName, CStatus* status); static HTEXTURE CreateTexture(const char* fileName, CStatus* status);
@ -68,6 +71,7 @@ class CCharacterComponent {
static void PasteTransparent4Bit(void* srcTexture, const BlpPalPixel* srcPal, MipBits* dstMips, const C2iVector& dstPos, uint32_t dstWidth, const C2iVector& srcPos, const C2iVector& srcSize, TCTEXTUREINFO& srcInfo, int32_t srcMipLevel, int32_t dstMipLevelOfs); static void PasteTransparent4Bit(void* srcTexture, const BlpPalPixel* srcPal, MipBits* dstMips, const C2iVector& dstPos, uint32_t dstWidth, const C2iVector& srcPos, const C2iVector& srcSize, TCTEXTUREINFO& srcInfo, int32_t srcMipLevel, int32_t dstMipLevelOfs);
static void PasteTransparent8Bit(void* srcTexture, const BlpPalPixel* srcPal, MipBits* dstMips, const C2iVector& dstPos, uint32_t dstWidth, const C2iVector& srcPos, const C2iVector& srcSize, TCTEXTUREINFO& srcInfo, int32_t srcMipLevel, int32_t dstMipLevelOfs); static void PasteTransparent8Bit(void* srcTexture, const BlpPalPixel* srcPal, MipBits* dstMips, const C2iVector& dstPos, uint32_t dstWidth, const C2iVector& srcPos, const C2iVector& srcSize, TCTEXTUREINFO& srcInfo, int32_t srcMipLevel, int32_t dstMipLevelOfs);
static void RemoveLinkpt(CM2Model* model, GEOCOMPONENTLINKS link); static void RemoveLinkpt(CM2Model* model, GEOCOMPONENTLINKS link);
static void ReplaceMonsterSkin(CM2Model* model, const CreatureDisplayInfoRec* displayInfoRec, const CreatureModelDataRec* modelDataRec);
static void UpdateBaseTexture(EGxTexCommand cmd, uint32_t width, uint32_t height, uint32_t depth, uint32_t mipLevel, void* userArg, uint32_t& texelStrideInBytes, const void*& texels); static void UpdateBaseTexture(EGxTexCommand cmd, uint32_t width, uint32_t height, uint32_t depth, uint32_t mipLevel, void* userArg, uint32_t& texelStrideInBytes, const void*& texels);
// Member variables // Member variables

View File

@ -12,14 +12,18 @@ WowClientDB<CharacterFacialHairStylesRec> g_characterFacialHairStylesDB;
WowClientDB<ChrClassesRec> g_chrClassesDB; WowClientDB<ChrClassesRec> g_chrClassesDB;
WowClientDB<ChrRacesRec> g_chrRacesDB; WowClientDB<ChrRacesRec> g_chrRacesDB;
WowClientDB<CreatureDisplayInfoRec> g_creatureDisplayInfoDB; WowClientDB<CreatureDisplayInfoRec> g_creatureDisplayInfoDB;
WowClientDB<CreatureDisplayInfoExtraRec> g_creatureDisplayInfoExtraDB;
WowClientDB<CreatureModelDataRec> g_creatureModelDataDB; WowClientDB<CreatureModelDataRec> g_creatureModelDataDB;
WowClientDB<CreatureSoundDataRec> g_creatureSoundDataDB;
WowClientDB<FactionGroupRec> g_factionGroupDB; WowClientDB<FactionGroupRec> g_factionGroupDB;
WowClientDB<FactionTemplateRec> g_factionTemplateDB; WowClientDB<FactionTemplateRec> g_factionTemplateDB;
WowClientDB<ItemDisplayInfoRec> g_itemDisplayInfoDB; WowClientDB<ItemDisplayInfoRec> g_itemDisplayInfoDB;
WowClientDB<ItemVisualsRec> g_itemVisualsDB; WowClientDB<ItemVisualsRec> g_itemVisualsDB;
WowClientDB<MapRec> g_mapDB; WowClientDB<MapRec> g_mapDB;
WowClientDB<PaperDollItemFrameRec> g_paperDollItemFrameDB;
WowClientDB<SoundEntriesRec> g_soundEntriesDB; WowClientDB<SoundEntriesRec> g_soundEntriesDB;
WowClientDB<SoundEntriesAdvancedRec> g_soundEntriesAdvancedDB; WowClientDB<SoundEntriesAdvancedRec> g_soundEntriesAdvancedDB;
WowClientDB<UnitBloodLevelsRec> g_unitBloodLevelsDB;
void LoadDB(WowClientDB_Base* db, const char* filename, int32_t linenumber) { void LoadDB(WowClientDB_Base* db, const char* filename, int32_t linenumber) {
db->Load(filename, linenumber); db->Load(filename, linenumber);
@ -37,14 +41,18 @@ void StaticDBLoadAll(void (*loadFn)(WowClientDB_Base*, const char*, int32_t)) {
loadFn(&g_chrClassesDB, __FILE__, __LINE__); loadFn(&g_chrClassesDB, __FILE__, __LINE__);
loadFn(&g_chrRacesDB, __FILE__, __LINE__); loadFn(&g_chrRacesDB, __FILE__, __LINE__);
loadFn(&g_creatureDisplayInfoDB, __FILE__, __LINE__); loadFn(&g_creatureDisplayInfoDB, __FILE__, __LINE__);
loadFn(&g_creatureDisplayInfoExtraDB, __FILE__, __LINE__);
loadFn(&g_creatureModelDataDB, __FILE__, __LINE__); loadFn(&g_creatureModelDataDB, __FILE__, __LINE__);
loadFn(&g_creatureSoundDataDB, __FILE__, __LINE__);
loadFn(&g_factionGroupDB, __FILE__, __LINE__); loadFn(&g_factionGroupDB, __FILE__, __LINE__);
loadFn(&g_factionTemplateDB, __FILE__, __LINE__); loadFn(&g_factionTemplateDB, __FILE__, __LINE__);
loadFn(&g_itemDisplayInfoDB, __FILE__, __LINE__); loadFn(&g_itemDisplayInfoDB, __FILE__, __LINE__);
loadFn(&g_itemVisualsDB, __FILE__, __LINE__); loadFn(&g_itemVisualsDB, __FILE__, __LINE__);
loadFn(&g_mapDB, __FILE__, __LINE__); loadFn(&g_mapDB, __FILE__, __LINE__);
loadFn(&g_paperDollItemFrameDB, __FILE__, __LINE__);
loadFn(&g_soundEntriesDB, __FILE__, __LINE__); loadFn(&g_soundEntriesDB, __FILE__, __LINE__);
loadFn(&g_soundEntriesAdvancedDB, __FILE__, __LINE__); loadFn(&g_soundEntriesAdvancedDB, __FILE__, __LINE__);
loadFn(&g_unitBloodLevelsDB, __FILE__, __LINE__);
}; };
void ClientDBInitialize() { void ClientDBInitialize() {

View File

@ -13,14 +13,18 @@
#include "db/rec/ChrClassesRec.hpp" #include "db/rec/ChrClassesRec.hpp"
#include "db/rec/ChrRacesRec.hpp" #include "db/rec/ChrRacesRec.hpp"
#include "db/rec/CreatureDisplayInfoRec.hpp" #include "db/rec/CreatureDisplayInfoRec.hpp"
#include "db/rec/CreatureDisplayInfoExtraRec.hpp"
#include "db/rec/CreatureModelDataRec.hpp" #include "db/rec/CreatureModelDataRec.hpp"
#include "db/rec/CreatureSoundDataRec.hpp"
#include "db/rec/FactionGroupRec.hpp" #include "db/rec/FactionGroupRec.hpp"
#include "db/rec/FactionTemplateRec.hpp" #include "db/rec/FactionTemplateRec.hpp"
#include "db/rec/ItemDisplayInfoRec.hpp" #include "db/rec/ItemDisplayInfoRec.hpp"
#include "db/rec/ItemVisualsRec.hpp" #include "db/rec/ItemVisualsRec.hpp"
#include "db/rec/MapRec.hpp" #include "db/rec/MapRec.hpp"
#include "db/rec/PaperDollItemFrameRec.hpp"
#include "db/rec/SoundEntriesRec.hpp" #include "db/rec/SoundEntriesRec.hpp"
#include "db/rec/SoundEntriesAdvancedRec.hpp" #include "db/rec/SoundEntriesAdvancedRec.hpp"
#include "db/rec/UnitBloodLevelsRec.hpp"
extern WowClientDB<AchievementRec> g_achievementDB; extern WowClientDB<AchievementRec> g_achievementDB;
extern WowClientDB<AreaTableRec> g_areaTableDB; extern WowClientDB<AreaTableRec> g_areaTableDB;
@ -33,14 +37,18 @@ extern WowClientDB<CharacterFacialHairStylesRec> g_characterFacialHairStylesDB;
extern WowClientDB<ChrClassesRec> g_chrClassesDB; extern WowClientDB<ChrClassesRec> g_chrClassesDB;
extern WowClientDB<ChrRacesRec> g_chrRacesDB; extern WowClientDB<ChrRacesRec> g_chrRacesDB;
extern WowClientDB<CreatureDisplayInfoRec> g_creatureDisplayInfoDB; extern WowClientDB<CreatureDisplayInfoRec> g_creatureDisplayInfoDB;
extern WowClientDB<CreatureDisplayInfoExtraRec> g_creatureDisplayInfoExtraDB;
extern WowClientDB<CreatureModelDataRec> g_creatureModelDataDB; extern WowClientDB<CreatureModelDataRec> g_creatureModelDataDB;
extern WowClientDB<CreatureSoundDataRec> g_creatureSoundDataDB;
extern WowClientDB<FactionGroupRec> g_factionGroupDB; extern WowClientDB<FactionGroupRec> g_factionGroupDB;
extern WowClientDB<FactionTemplateRec> g_factionTemplateDB; extern WowClientDB<FactionTemplateRec> g_factionTemplateDB;
extern WowClientDB<ItemDisplayInfoRec> g_itemDisplayInfoDB; extern WowClientDB<ItemDisplayInfoRec> g_itemDisplayInfoDB;
extern WowClientDB<ItemVisualsRec> g_itemVisualsDB; extern WowClientDB<ItemVisualsRec> g_itemVisualsDB;
extern WowClientDB<MapRec> g_mapDB; extern WowClientDB<MapRec> g_mapDB;
extern WowClientDB<PaperDollItemFrameRec> g_paperDollItemFrameDB;
extern WowClientDB<SoundEntriesRec> g_soundEntriesDB; extern WowClientDB<SoundEntriesRec> g_soundEntriesDB;
extern WowClientDB<SoundEntriesAdvancedRec> g_soundEntriesAdvancedDB; extern WowClientDB<SoundEntriesAdvancedRec> g_soundEntriesAdvancedDB;
extern WowClientDB<UnitBloodLevelsRec> g_unitBloodLevelsDB;
void ClientDBInitialize(); void ClientDBInitialize();

View File

@ -0,0 +1,66 @@
// DO NOT EDIT: generated by whoa-autocode
#include "db/rec/CreatureDisplayInfoExtraRec.hpp"
#include "util/Locale.hpp"
#include "util/SFile.hpp"
const char* CreatureDisplayInfoExtraRec::GetFilename() {
return "DBFilesClient\\CreatureDisplayInfoExtra.dbc";
}
uint32_t CreatureDisplayInfoExtraRec::GetNumColumns() {
return 21;
}
uint32_t CreatureDisplayInfoExtraRec::GetRowSize() {
return 84;
}
bool CreatureDisplayInfoExtraRec::NeedIDAssigned() {
return false;
}
int32_t CreatureDisplayInfoExtraRec::GetID() {
return this->m_ID;
}
void CreatureDisplayInfoExtraRec::SetID(int32_t id) {
this->m_ID = id;
}
bool CreatureDisplayInfoExtraRec::Read(SFile* f, const char* stringBuffer) {
uint32_t bakeNameOfs;
if (
!SFile::Read(f, &this->m_ID, sizeof(this->m_ID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_displayRaceID, sizeof(this->m_displayRaceID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_displaySexID, sizeof(this->m_displaySexID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_skinID, sizeof(this->m_skinID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_faceID, sizeof(this->m_faceID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_hairStyleID, sizeof(this->m_hairStyleID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_hairColorID, sizeof(this->m_hairColorID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_facialHairID, sizeof(this->m_facialHairID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_npcitemDisplay[0], sizeof(m_npcitemDisplay[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_npcitemDisplay[1], sizeof(m_npcitemDisplay[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_npcitemDisplay[2], sizeof(m_npcitemDisplay[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_npcitemDisplay[3], sizeof(m_npcitemDisplay[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_npcitemDisplay[4], sizeof(m_npcitemDisplay[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_npcitemDisplay[5], sizeof(m_npcitemDisplay[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_npcitemDisplay[6], sizeof(m_npcitemDisplay[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_npcitemDisplay[7], sizeof(m_npcitemDisplay[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_npcitemDisplay[8], sizeof(m_npcitemDisplay[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_npcitemDisplay[9], sizeof(m_npcitemDisplay[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_npcitemDisplay[10], sizeof(m_npcitemDisplay[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_flags, sizeof(this->m_flags), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &bakeNameOfs, sizeof(uint32_t), nullptr, nullptr, nullptr)
) {
return false;
}
if (stringBuffer) {
this->m_bakeName = &stringBuffer[bakeNameOfs];
} else {
this->m_bakeName = "";
}
return true;
}

View File

@ -0,0 +1,32 @@
// DO NOT EDIT: generated by whoa-autocode
#ifndef DB_REC_CREATURE_DISPLAY_INFO_EXTRA_REC_HPP
#define DB_REC_CREATURE_DISPLAY_INFO_EXTRA_REC_HPP
#include <cstdint>
class SFile;
class CreatureDisplayInfoExtraRec {
public:
int32_t m_ID;
int32_t m_displayRaceID;
int32_t m_displaySexID;
int32_t m_skinID;
int32_t m_faceID;
int32_t m_hairStyleID;
int32_t m_hairColorID;
int32_t m_facialHairID;
int32_t m_npcitemDisplay[11];
int32_t m_flags;
const char* m_bakeName;
static const char* GetFilename();
static uint32_t GetNumColumns();
static uint32_t GetRowSize();
static bool NeedIDAssigned();
int32_t GetID();
void SetID(int32_t id);
bool Read(SFile* f, const char* stringBuffer);
};
#endif

View File

@ -0,0 +1,75 @@
// DO NOT EDIT: generated by whoa-autocode
#include "db/rec/CreatureSoundDataRec.hpp"
#include "util/Locale.hpp"
#include "util/SFile.hpp"
const char* CreatureSoundDataRec::GetFilename() {
return "DBFilesClient\\CreatureSoundData.dbc";
}
uint32_t CreatureSoundDataRec::GetNumColumns() {
return 38;
}
uint32_t CreatureSoundDataRec::GetRowSize() {
return 152;
}
bool CreatureSoundDataRec::NeedIDAssigned() {
return false;
}
int32_t CreatureSoundDataRec::GetID() {
return this->m_ID;
}
void CreatureSoundDataRec::SetID(int32_t id) {
this->m_ID = id;
}
bool CreatureSoundDataRec::Read(SFile* f, const char* stringBuffer) {
if (
!SFile::Read(f, &this->m_ID, sizeof(this->m_ID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundExertionID, sizeof(this->m_soundExertionID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundExertionCriticalID, sizeof(this->m_soundExertionCriticalID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundInjuryID, sizeof(this->m_soundInjuryID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundInjuryCriticalID, sizeof(this->m_soundInjuryCriticalID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundInjuryCrushingBlowID, sizeof(this->m_soundInjuryCrushingBlowID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundDeathID, sizeof(this->m_soundDeathID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundStunID, sizeof(this->m_soundStunID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundStandID, sizeof(this->m_soundStandID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundFootstepID, sizeof(this->m_soundFootstepID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundAggroID, sizeof(this->m_soundAggroID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundWingFlapID, sizeof(this->m_soundWingFlapID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundWingGlideID, sizeof(this->m_soundWingGlideID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundAlertID, sizeof(this->m_soundAlertID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundFidget[0], sizeof(m_soundFidget[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundFidget[1], sizeof(m_soundFidget[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundFidget[2], sizeof(m_soundFidget[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundFidget[3], sizeof(m_soundFidget[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundFidget[4], sizeof(m_soundFidget[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_customAttack[0], sizeof(m_customAttack[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_customAttack[1], sizeof(m_customAttack[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_customAttack[2], sizeof(m_customAttack[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_customAttack[3], sizeof(m_customAttack[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_npcsoundID, sizeof(this->m_npcsoundID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_loopSoundID, sizeof(this->m_loopSoundID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_creatureImpactType, sizeof(this->m_creatureImpactType), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundJumpStartID, sizeof(this->m_soundJumpStartID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundJumpEndID, sizeof(this->m_soundJumpEndID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundPetAttackID, sizeof(this->m_soundPetAttackID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundPetOrderID, sizeof(this->m_soundPetOrderID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_soundPetDismissID, sizeof(this->m_soundPetDismissID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_fidgetDelaySecondsMin, sizeof(this->m_fidgetDelaySecondsMin), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_fidgetDelaySecondsMax, sizeof(this->m_fidgetDelaySecondsMax), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_birthSoundID, sizeof(this->m_birthSoundID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_spellCastDirectedSoundID, sizeof(this->m_spellCastDirectedSoundID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_submergeSoundID, sizeof(this->m_submergeSoundID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_submergedSoundID, sizeof(this->m_submergedSoundID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_creatureSoundDataIdpet, sizeof(this->m_creatureSoundDataIdpet), nullptr, nullptr, nullptr)
) {
return false;
}
return true;
}

View File

@ -0,0 +1,52 @@
// DO NOT EDIT: generated by whoa-autocode
#ifndef DB_REC_CREATURE_SOUND_DATA_REC_HPP
#define DB_REC_CREATURE_SOUND_DATA_REC_HPP
#include <cstdint>
class SFile;
class CreatureSoundDataRec {
public:
int32_t m_ID;
int32_t m_soundExertionID;
int32_t m_soundExertionCriticalID;
int32_t m_soundInjuryID;
int32_t m_soundInjuryCriticalID;
int32_t m_soundInjuryCrushingBlowID;
int32_t m_soundDeathID;
int32_t m_soundStunID;
int32_t m_soundStandID;
int32_t m_soundFootstepID;
int32_t m_soundAggroID;
int32_t m_soundWingFlapID;
int32_t m_soundWingGlideID;
int32_t m_soundAlertID;
int32_t m_soundFidget[5];
int32_t m_customAttack[4];
int32_t m_npcsoundID;
int32_t m_loopSoundID;
int32_t m_creatureImpactType;
int32_t m_soundJumpStartID;
int32_t m_soundJumpEndID;
int32_t m_soundPetAttackID;
int32_t m_soundPetOrderID;
int32_t m_soundPetDismissID;
float m_fidgetDelaySecondsMin;
float m_fidgetDelaySecondsMax;
int32_t m_birthSoundID;
int32_t m_spellCastDirectedSoundID;
int32_t m_submergeSoundID;
int32_t m_submergedSoundID;
int32_t m_creatureSoundDataIdpet;
static const char* GetFilename();
static uint32_t GetNumColumns();
static uint32_t GetRowSize();
static bool NeedIDAssigned();
int32_t GetID();
void SetID(int32_t id);
bool Read(SFile* f, const char* stringBuffer);
};
#endif

View File

@ -0,0 +1,51 @@
// DO NOT EDIT: generated by whoa-autocode
#include "db/rec/PaperDollItemFrameRec.hpp"
#include "util/Locale.hpp"
#include "util/SFile.hpp"
const char* PaperDollItemFrameRec::GetFilename() {
return "DBFilesClient\\PaperDollItemFrame.dbc";
}
uint32_t PaperDollItemFrameRec::GetNumColumns() {
return 3;
}
uint32_t PaperDollItemFrameRec::GetRowSize() {
return 12;
}
bool PaperDollItemFrameRec::NeedIDAssigned() {
return true;
}
int32_t PaperDollItemFrameRec::GetID() {
return this->m_generatedID;
}
void PaperDollItemFrameRec::SetID(int32_t id) {
this->m_generatedID = id;
}
bool PaperDollItemFrameRec::Read(SFile* f, const char* stringBuffer) {
uint32_t itemButtonNameOfs;
uint32_t slotIconOfs;
if (
!SFile::Read(f, &itemButtonNameOfs, sizeof(uint32_t), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &slotIconOfs, sizeof(uint32_t), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_slotNumber, sizeof(this->m_slotNumber), nullptr, nullptr, nullptr)
) {
return false;
}
if (stringBuffer) {
this->m_itemButtonName = &stringBuffer[itemButtonNameOfs];
this->m_slotIcon = &stringBuffer[slotIconOfs];
} else {
this->m_itemButtonName = "";
this->m_slotIcon = "";
}
return true;
}

View File

@ -0,0 +1,25 @@
// DO NOT EDIT: generated by whoa-autocode
#ifndef DB_REC_PAPER_DOLL_ITEM_FRAME_REC_HPP
#define DB_REC_PAPER_DOLL_ITEM_FRAME_REC_HPP
#include <cstdint>
class SFile;
class PaperDollItemFrameRec {
public:
const char* m_itemButtonName;
const char* m_slotIcon;
int32_t m_slotNumber;
int32_t m_generatedID;
static const char* GetFilename();
static uint32_t GetNumColumns();
static uint32_t GetRowSize();
static bool NeedIDAssigned();
int32_t GetID();
void SetID(int32_t id);
bool Read(SFile* f, const char* stringBuffer);
};
#endif

View File

@ -0,0 +1,41 @@
// DO NOT EDIT: generated by whoa-autocode
#include "db/rec/UnitBloodLevelsRec.hpp"
#include "util/Locale.hpp"
#include "util/SFile.hpp"
const char* UnitBloodLevelsRec::GetFilename() {
return "DBFilesClient\\UnitBloodLevels.dbc";
}
uint32_t UnitBloodLevelsRec::GetNumColumns() {
return 4;
}
uint32_t UnitBloodLevelsRec::GetRowSize() {
return 16;
}
bool UnitBloodLevelsRec::NeedIDAssigned() {
return false;
}
int32_t UnitBloodLevelsRec::GetID() {
return this->m_ID;
}
void UnitBloodLevelsRec::SetID(int32_t id) {
this->m_ID = id;
}
bool UnitBloodLevelsRec::Read(SFile* f, const char* stringBuffer) {
if (
!SFile::Read(f, &this->m_ID, sizeof(this->m_ID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_violencelevel[0], sizeof(m_violencelevel[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_violencelevel[1], sizeof(m_violencelevel[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_violencelevel[2], sizeof(m_violencelevel[0]), nullptr, nullptr, nullptr)
) {
return false;
}
return true;
}

View File

@ -0,0 +1,23 @@
// DO NOT EDIT: generated by whoa-autocode
#ifndef DB_REC_UNIT_BLOOD_LEVELS_REC_HPP
#define DB_REC_UNIT_BLOOD_LEVELS_REC_HPP
#include <cstdint>
class SFile;
class UnitBloodLevelsRec {
public:
int32_t m_ID;
int32_t m_violencelevel[3];
static const char* GetFilename();
static uint32_t GetNumColumns();
static uint32_t GetRowSize();
static bool NeedIDAssigned();
int32_t GetID();
void SetID(int32_t id);
bool Read(SFile* f, const char* stringBuffer);
};
#endif

View File

@ -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; context->m_schedLastIdle = currTime;
double elapsedSec = v9 * 0.001;
// TODO SynthesizeTick(context, currTime, elapsedSec);
// FrameTime::Update(currTime, elapsedSec);
IEvtTimerDispatch(context); IEvtTimerDispatch(context);

View File

@ -91,3 +91,17 @@ void SynthesizePoll(EvtContext* context) {
IEvtQueueDispatch(context, EVENT_ID_POLL, nullptr); 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);
}

View File

@ -15,4 +15,6 @@ void SynthesizePaint(EvtContext* context);
void SynthesizePoll(EvtContext* context); void SynthesizePoll(EvtContext* context);
void SynthesizeTick(EvtContext* context, uint32_t currTime, float elapsedSec);
#endif #endif

View File

@ -12,7 +12,7 @@ enum EVENTID {
EVENT_ID_FOCUS = 2, EVENT_ID_FOCUS = 2,
EVENT_ID_CLOSE = 3, EVENT_ID_CLOSE = 3,
EVENT_ID_DESTROY = 4, EVENT_ID_DESTROY = 4,
EVENT_ID_5 = 5, EVENT_ID_TICK = 5,
EVENT_ID_IDLE = 6, EVENT_ID_IDLE = 6,
EVENT_ID_POLL = 7, EVENT_ID_POLL = 7,
EVENT_ID_INITIALIZE = 8, EVENT_ID_INITIALIZE = 8,
@ -259,4 +259,9 @@ struct EVENT_DATA_SIZE {
int32_t h; int32_t h;
}; };
struct EVENT_DATA_TICK {
float tickTimeSec;
uint32_t curTimeMs;
};
#endif #endif

View File

@ -25,10 +25,12 @@
#include "ui/FrameScript.hpp" #include "ui/FrameScript.hpp"
#include "ui/FrameXML.hpp" #include "ui/FrameXML.hpp"
#include "ui/Interface.hpp" #include "ui/Interface.hpp"
#include "ui/ScriptFunctions.hpp" #include "ui/Key.hpp"
#include "ui/ScriptFunctionsSystem.hpp"
#include "ui/game/CGVideoOptions.hpp" #include "ui/game/CGVideoOptions.hpp"
#include "ui/simple/CSimpleModelFFX.hpp" #include "ui/simple/CSimpleModelFFX.hpp"
#include "ui/simple/CSimpleTop.hpp" #include "ui/simple/CSimpleTop.hpp"
#include "ui/simple/ScriptMethods.hpp"
#include "util/Filesystem.hpp" #include "util/Filesystem.hpp"
#include "util/Locale.hpp" #include "util/Locale.hpp"
#include "util/Log.hpp" #include "util/Log.hpp"
@ -36,25 +38,7 @@
#include <common/MD5.hpp> #include <common/MD5.hpp>
#include <cstdio> #include <cstdio>
unsigned char InterfaceKey[256] = { int32_t CGlueMgr::m_acceptedContest = 1; // TODO
0xC3, 0x5B, 0x50, 0x84, 0xB9, 0x3E, 0x32, 0x42, 0x8C, 0xD0, 0xC7, 0x48, 0xFA, 0x0E, 0x5D, 0x54,
0x5A, 0xA3, 0x0E, 0x14, 0xBA, 0x9E, 0x0D, 0xB9, 0x5D, 0x8B, 0xEE, 0xB6, 0x84, 0x93, 0x45, 0x75,
0xFF, 0x31, 0xFE, 0x2F, 0x64, 0x3F, 0x3D, 0x6D, 0x07, 0xD9, 0x44, 0x9B, 0x40, 0x85, 0x59, 0x34,
0x4E, 0x10, 0xE1, 0xE7, 0x43, 0x69, 0xEF, 0x7C, 0x16, 0xFC, 0xB4, 0xED, 0x1B, 0x95, 0x28, 0xA8,
0x23, 0x76, 0x51, 0x31, 0x57, 0x30, 0x2B, 0x79, 0x08, 0x50, 0x10, 0x1C, 0x4A, 0x1A, 0x2C, 0xC8,
0x8B, 0x8F, 0x05, 0x2D, 0x22, 0x3D, 0xDB, 0x5A, 0x24, 0x7A, 0x0F, 0x13, 0x50, 0x37, 0x8F, 0x5A,
0xCC, 0x9E, 0x04, 0x44, 0x0E, 0x87, 0x01, 0xD4, 0xA3, 0x15, 0x94, 0x16, 0x34, 0xC6, 0xC2, 0xC3,
0xFB, 0x49, 0xFE, 0xE1, 0xF9, 0xDA, 0x8C, 0x50, 0x3C, 0xBE, 0x2C, 0xBB, 0x57, 0xED, 0x46, 0xB9,
0xAD, 0x8B, 0xC6, 0xDF, 0x0E, 0xD6, 0x0F, 0xBE, 0x80, 0xB3, 0x8B, 0x1E, 0x77, 0xCF, 0xAD, 0x22,
0xCF, 0xB7, 0x4B, 0xCF, 0xFB, 0xF0, 0x6B, 0x11, 0x45, 0x2D, 0x7A, 0x81, 0x18, 0xF2, 0x92, 0x7E,
0x98, 0x56, 0x5D, 0x5E, 0x69, 0x72, 0x0A, 0x0D, 0x03, 0x0A, 0x85, 0xA2, 0x85, 0x9C, 0xCB, 0xFB,
0x56, 0x6E, 0x8F, 0x44, 0xBB, 0x8F, 0x02, 0x22, 0x68, 0x63, 0x97, 0xBC, 0x85, 0xBA, 0xA8, 0xF7,
0xB5, 0x40, 0x68, 0x3C, 0x77, 0x86, 0x6F, 0x4B, 0xD7, 0x88, 0xCA, 0x8A, 0xD7, 0xCE, 0x36, 0xF0,
0x45, 0x6E, 0xD5, 0x64, 0x79, 0x0F, 0x17, 0xFC, 0x64, 0xDD, 0x10, 0x6F, 0xF3, 0xF5, 0xE0, 0xA6,
0xC3, 0xFB, 0x1B, 0x8C, 0x29, 0xEF, 0x8E, 0xE5, 0x34, 0xCB, 0xD1, 0x2A, 0xCE, 0x79, 0xC3, 0x9A,
0x0D, 0x36, 0xEA, 0x01, 0xE0, 0xAA, 0x91, 0x20, 0x54, 0xF0, 0x72, 0xD8, 0x1E, 0xC7, 0x89, 0xD2
};
int32_t CGlueMgr::m_acceptedEULA = 1; // TODO int32_t CGlueMgr::m_acceptedEULA = 1; // TODO
int32_t CGlueMgr::m_acceptedScanning = 1; // TODO int32_t CGlueMgr::m_acceptedScanning = 1; // TODO
int32_t CGlueMgr::m_acceptedTerminationWithoutNotice; int32_t CGlueMgr::m_acceptedTerminationWithoutNotice;
@ -411,6 +395,11 @@ int32_t CGlueMgr::Idle(const void* a1, void* a2) {
break; break;
} }
case IDLE_CREATE_CHARACTER: {
CGlueMgr::PollCreateCharacter(msg, complete, result);
break;
}
case IDLE_DELETE_CHARACTER: { case IDLE_DELETE_CHARACTER: {
CGlueMgr::PollDeleteCharacter(msg, complete, result); CGlueMgr::PollDeleteCharacter(msg, complete, result);
break; break;
@ -781,6 +770,37 @@ void CGlueMgr::PollCharacterList(const char* msg, int32_t complete, int32_t resu
} }
} }
void CGlueMgr::PollCreateCharacter(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
CGlueMgr::SetIdleState(IDLE_NONE);
FrameScript_SignalEvent(CLOSE_STATUS_DIALOG, nullptr);
FrameScript_SignalEvent(SELECT_LAST_CHARACTER, nullptr);
CGlueMgr::SetScreen("charselect");
}
void CGlueMgr::PollDeleteCharacter(const char* msg, int32_t complete, int32_t result) { void CGlueMgr::PollDeleteCharacter(const char* msg, int32_t complete, int32_t result) {
FrameScript_SignalEvent(UPDATE_STATUS_DIALOG, "%s", msg); FrameScript_SignalEvent(UPDATE_STATUS_DIALOG, "%s", msg);
@ -1006,51 +1026,53 @@ void CGlueMgr::Resume() {
DeleteInterfaceFiles(); DeleteInterfaceFiles();
MD5_CTX md5; uint8_t digest1[16];
unsigned char digest1[16];
unsigned char digest2[16];
int32_t v8; switch (FrameXML_CheckSignature("Interface\\GlueXML\\GlueXML.toc", nullptr, InterfaceKey, digest1)) {
unsigned char* v9; case 0: {
unsigned char* v10;
MD5Init(&md5);
switch (FrameXML_CheckSignature("Interface\\GlueXML\\GlueXML.toc", 0, InterfaceKey, digest1)) {
case 0:
status.Add(STATUS_WARNING, "GlueXML missing signature"); status.Add(STATUS_WARNING, "GlueXML missing signature");
ClientPostClose(9); ClientPostClose(9);
return;
case 1:
status.Add(STATUS_WARNING, "GlueXML has corrupt signature");
ClientPostClose(9);
return;
case 2:
status.Add(STATUS_WARNING, "GlueXML is modified or corrupt");
ClientPostClose(9);
return;
case 3:
FrameXML_FreeHashNodes();
FrameXML_CreateFrames("Interface\\GlueXML\\GlueXML.toc", 0, &md5, &status);
MD5Final(digest2, &md5);
v8 = 16;
v9 = digest2;
v10 = digest1;
break;
default:
ClientPostClose(9);
return; return;
} }
// TODO case 1: {
// - some kind of digest validation? status.Add(STATUS_WARNING, "GlueXML has corrupt signature");
ClientPostClose(9);
return;
}
case 2: {
status.Add(STATUS_WARNING, "GlueXML is modified or corrupt");
ClientPostClose(9);
return;
}
case 3: {
// Success
break;
}
default: {
ClientPostClose(9);
return;
}
}
MD5_CTX md5;
MD5Init(&md5);
FrameXML_FreeHashNodes();
FrameXML_CreateFrames("Interface\\GlueXML\\GlueXML.toc", nullptr, &md5, &status);
uint8_t digest2[16];
MD5Final(digest2, &md5);
// TODO digest validation
FrameScript_SignalEvent(22, nullptr); FrameScript_SignalEvent(22, nullptr);
@ -1145,7 +1167,7 @@ void CGlueMgr::StatusDialogClick() {
} }
case IDLE_REALM_LIST: case IDLE_REALM_LIST:
case IDLE_5: case IDLE_CREATE_CHARACTER:
case IDLE_DELETE_CHARACTER: case IDLE_DELETE_CHARACTER:
case IDLE_ENTER_WORLD: { case IDLE_ENTER_WORLD: {
ClientServices::Connection()->Cancel(2); ClientServices::Connection()->Cancel(2);
@ -1203,6 +1225,10 @@ void CGlueMgr::Suspend() {
// TODO // TODO
SystemUnregisterFunctions();
// TODO
FrameXML_FreeHashNodes(); FrameXML_FreeHashNodes();
// TODO // TODO

View File

@ -20,7 +20,7 @@ class CGlueMgr {
IDLE_ACCOUNT_LOGIN = 2, IDLE_ACCOUNT_LOGIN = 2,
IDLE_CHARACTER_LIST = 3, IDLE_CHARACTER_LIST = 3,
IDLE_REALM_LIST = 4, IDLE_REALM_LIST = 4,
IDLE_5 = 5, IDLE_CREATE_CHARACTER = 5,
IDLE_DELETE_CHARACTER = 6, IDLE_DELETE_CHARACTER = 6,
IDLE_7 = 7, IDLE_7 = 7,
IDLE_8 = 8, IDLE_8 = 8,
@ -32,6 +32,7 @@ class CGlueMgr {
}; };
// Static variables // Static variables
static int32_t m_acceptedContest;
static int32_t m_acceptedEULA; static int32_t m_acceptedEULA;
static int32_t m_acceptedScanning; static int32_t m_acceptedScanning;
static int32_t m_acceptedTerminationWithoutNotice; static int32_t m_acceptedTerminationWithoutNotice;
@ -81,6 +82,7 @@ class CGlueMgr {
static int32_t OnKickReasonMsg(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg); 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 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 PollCharacterList(const char* msg, int32_t complete, int32_t result, int32_t errorCode);
static void PollCreateCharacter(const char* msg, int32_t complete, int32_t result);
static void PollDeleteCharacter(const char* msg, int32_t complete, int32_t result); static void PollDeleteCharacter(const char* msg, int32_t complete, int32_t result);
static void PollEnterWorld(); static void PollEnterWorld();
static void PollLoginServerLogin(); static void PollLoginServerLogin();

View File

@ -17,7 +17,13 @@
#include <cstdint> #include <cstdint>
int32_t Script_IsShiftKeyDown(lua_State* L) { int32_t Script_IsShiftKeyDown(lua_State* L) {
WHOA_UNIMPLEMENTED(0); if (EventIsKeyDown(KEY_LSHIFT) || EventIsKeyDown(KEY_RSHIFT)) {
lua_pushnumber(L, 1.0);
} else {
lua_pushnil(L);
}
return 1;
} }
int32_t Script_GetBuildInfo(lua_State* L) { int32_t Script_GetBuildInfo(lua_State* L) {
@ -198,7 +204,13 @@ int32_t Script_ShowTerminationWithoutNoticeNotice(lua_State* L) {
} }
int32_t Script_TerminationWithoutNoticeAccepted(lua_State* L) { int32_t Script_TerminationWithoutNoticeAccepted(lua_State* L) {
WHOA_UNIMPLEMENTED(0); if (CGlueMgr::m_acceptedTerminationWithoutNotice) {
lua_pushnumber(L, 1.0);
} else {
lua_pushnil(L);
}
return 1;
} }
int32_t Script_AcceptTerminationWithoutNotice(lua_State* L) { int32_t Script_AcceptTerminationWithoutNotice(lua_State* L) {
@ -229,7 +241,13 @@ int32_t Script_ShowContestNotice(lua_State* L) {
} }
int32_t Script_ContestAccepted(lua_State* L) { int32_t Script_ContestAccepted(lua_State* L) {
WHOA_UNIMPLEMENTED(0); if (CGlueMgr::m_acceptedContest) {
lua_pushnumber(L, 1.0);
} else {
lua_pushnil(L);
}
return 1;
} }
int32_t Script_AcceptContest(lua_State* L) { int32_t Script_AcceptContest(lua_State* L) {
@ -529,36 +547,6 @@ int32_t Script_IsScanDLLFinished(lua_State* L) {
return 1; return 1;
} }
int32_t Script_IsWindowsClient(lua_State* L) {
#if defined(WHOA_SYSTEM_WIN)
lua_pushnumber(L, 1.0);
#else
lua_pushnil(L);
#endif
return 1;
}
int32_t Script_IsMacClient(lua_State* L) {
#if defined(WHOA_SYSTEM_MAC)
lua_pushnumber(L, 1.0);
#else
lua_pushnil(L);
#endif
return 1;
}
int32_t Script_IsLinuxClient(lua_State* L) {
#if defined(WHOA_SYSTEM_LINUX)
lua_pushnumber(L, 1.0);
#else
lua_pushnil(L);
#endif
return 1;
}
int32_t Script_SetRealmSplitState(lua_State* L) { int32_t Script_SetRealmSplitState(lua_State* L) {
WHOA_UNIMPLEMENTED(0); WHOA_UNIMPLEMENTED(0);
} }

View File

@ -924,6 +924,10 @@ CGxPool* CGxDevice::PoolCreate(EGxPoolTarget target, EGxPoolUsage usage, uint32_
return pool; return pool;
} }
void CGxDevice::RenderTargetGet(EGxBuffer buffer, CGxTex*& gxTex) {
gxTex = this->m_textureTarget[buffer].m_texture;
}
void CGxDevice::RsGet(EGxRenderState which, int32_t& value) { void CGxDevice::RsGet(EGxRenderState which, int32_t& value) {
value = static_cast<int32_t>(this->m_appRenderStates[which].m_value); value = static_cast<int32_t>(this->m_appRenderStates[which].m_value);
} }

View File

@ -38,6 +38,13 @@ struct ShaderConstants {
class CGxDevice { class CGxDevice {
public: public:
// Structs
struct TextureTarget {
CGxTex* m_texture;
uint32_t m_plane;
void* m_apiSpecific;
};
// Static variables // Static variables
static uint32_t s_alphaRef[]; static uint32_t s_alphaRef[];
static C3Vector s_pointScaleIdentity; static C3Vector s_pointScaleIdentity;
@ -101,12 +108,12 @@ class CGxDevice {
uint32_t m_appMasterEnables = 0; uint32_t m_appMasterEnables = 0;
uint32_t m_hwMasterEnables = 0; uint32_t m_hwMasterEnables = 0;
TSList<CGxPool, TSGetLink<CGxPool>> m_poolList; TSList<CGxPool, TSGetLink<CGxPool>> m_poolList;
CGxBuf* m_bufLocked[GxPoolTargets_Last]; CGxBuf* m_bufLocked[GxPoolTargets_Last] = {};
CGxPool* m_vertexPool = nullptr; CGxPool* m_vertexPool = nullptr;
CGxPool* m_indexPool = nullptr; CGxPool* m_indexPool = nullptr;
CGxBuf* m_streamBufs[GxPoolTargets_Last]; CGxBuf* m_streamBufs[GxPoolTargets_Last] = {};
CGxVertexAttrib m_primVertexFormatAttrib[GxVertexBufferFormats_Last]; CGxVertexAttrib m_primVertexFormatAttrib[GxVertexBufferFormats_Last];
CGxBuf* m_primVertexFormatBuf[GxVertexBufferFormats_Last]; CGxBuf* m_primVertexFormatBuf[GxVertexBufferFormats_Last] = {};
uint32_t m_primVertexMask = 0; uint32_t m_primVertexMask = 0;
uint32_t m_primVertexDirty = 0; uint32_t m_primVertexDirty = 0;
EGxVertexBufferFormat m_primVertexFormat = GxVertexBufferFormats_Last; EGxVertexBufferFormat m_primVertexFormat = GxVertexBufferFormats_Last;
@ -116,6 +123,9 @@ class CGxDevice {
int32_t m_primIndexDirty = 0; int32_t m_primIndexDirty = 0;
TSFixedArray<CGxAppRenderState> m_appRenderStates; TSFixedArray<CGxAppRenderState> m_appRenderStates;
TSFixedArray<CGxStateBom> m_hwRenderStates; TSFixedArray<CGxStateBom> m_hwRenderStates;
// TODO
TextureTarget m_textureTarget[GxBuffers_Last] = {};
// TODO
uint32_t m_baseMipLevel = 0; // TODO placeholder uint32_t m_baseMipLevel = 0; // TODO placeholder
// Virtual member functions // Virtual member functions
@ -173,6 +183,7 @@ class CGxDevice {
void PrimVertexFormat(CGxBuf*, CGxVertexAttrib*, uint32_t); void PrimVertexFormat(CGxBuf*, CGxVertexAttrib*, uint32_t);
void PrimVertexMask(uint32_t); void PrimVertexMask(uint32_t);
void PrimVertexPtr(CGxBuf*, EGxVertexBufferFormat); void PrimVertexPtr(CGxBuf*, EGxVertexBufferFormat);
void RenderTargetGet(EGxBuffer buffer, CGxTex*& gxTex);
void RsGet(EGxRenderState, int32_t&); void RsGet(EGxRenderState, int32_t&);
void RsSet(EGxRenderState, int32_t); void RsSet(EGxRenderState, int32_t);
void RsSet(EGxRenderState, void*); void RsSet(EGxRenderState, void*);

6
src/gx/RenderTarget.cpp Normal file
View File

@ -0,0 +1,6 @@
#include "gx/RenderTarget.hpp"
#include "gx/Device.hpp"
void GxRenderTargetGet(EGxBuffer buffer, CGxTex*& gxTex) {
g_theGxDevicePtr->RenderTargetGet(buffer, gxTex);
}

10
src/gx/RenderTarget.hpp Normal file
View File

@ -0,0 +1,10 @@
#ifndef GX_RENDER_TARGET_HPP
#define GX_RENDER_TARGET_HPP
#include "gx/Types.hpp"
class CGxTex;
void GxRenderTargetGet(EGxBuffer buffer, CGxTex*& gxTex);
#endif

View File

@ -54,6 +54,12 @@ enum EGxBlend {
GxBlends_Last = 12 GxBlends_Last = 12
}; };
enum EGxBuffer {
GxBuffers_Color = 0,
GxBuffers_Depth = 1,
GxBuffers_Last,
};
enum EGxColorFormat { enum EGxColorFormat {
GxCF_argb = 0, GxCF_argb = 0,
GxCF_rgba = 1, GxCF_rgba = 1,

View File

@ -1604,6 +1604,10 @@ void CM2Model::LinkToCallbackListTail() {
this->m_shared->m_callbackListTail = &this->m_callbackNext; this->m_shared->m_callbackListTail = &this->m_callbackNext;
} }
void CM2Model::OptimizeVisibleGeometry() {
// TODO
}
int32_t CM2Model::ProcessCallbacks() { int32_t CM2Model::ProcessCallbacks() {
// TODO // TODO
return 1; return 1;

View File

@ -178,6 +178,7 @@ class CM2Model {
int32_t IsDrawable(int32_t a2, int32_t a3); int32_t IsDrawable(int32_t a2, int32_t a3);
int32_t IsLoaded(int32_t a2, int32_t attachments); int32_t IsLoaded(int32_t a2, int32_t attachments);
void LinkToCallbackListTail(); void LinkToCallbackListTail();
void OptimizeVisibleGeometry();
int32_t ProcessCallbacks(); int32_t ProcessCallbacks();
void ProcessCallbacksRecursive(); void ProcessCallbacksRecursive();
uint32_t Release(); uint32_t Release();

View File

@ -60,11 +60,11 @@ enum NETMESSAGE {
CMSG_AUTH_SRP6_BEGIN = 0x0033, CMSG_AUTH_SRP6_BEGIN = 0x0033,
CMSG_AUTH_SRP6_PROOF = 0x0034, CMSG_AUTH_SRP6_PROOF = 0x0034,
CMSG_AUTH_SRP6_RECODE = 0x0035, CMSG_AUTH_SRP6_RECODE = 0x0035,
CMSG_CREATE_CHARACTER = 0x0036, CMSG_CHAR_CREATE = 0x0036,
CMSG_ENUM_CHARACTERS = 0x0037, CMSG_ENUM_CHARACTERS = 0x0037,
CMSG_CHAR_DELETE = 0x0038, CMSG_CHAR_DELETE = 0x0038,
SMSG_AUTH_SRP6_RESPONSE = 0x0039, SMSG_AUTH_SRP6_RESPONSE = 0x0039,
SMSG_CREATE_CHAR = 0x003A, SMSG_CHAR_CREATE = 0x003A,
SMSG_ENUM_CHARACTERS_RESULT = 0x003B, SMSG_ENUM_CHARACTERS_RESULT = 0x003B,
SMSG_DELETE_CHAR = 0x003C, SMSG_DELETE_CHAR = 0x003C,
CMSG_PLAYER_LOGIN = 0x003D, CMSG_PLAYER_LOGIN = 0x003D,

View File

@ -104,6 +104,14 @@ void ClientConnection::GetRealmList() {
} }
} }
void ClientConnection::HandleCharacterCreate(uint8_t result) {
this->Complete(result == 47, result);
}
void ClientConnection::HandleCharacterDelete(uint8_t result) {
this->Complete(result == 71, result);
}
int32_t ClientConnection::HandleConnect() { int32_t ClientConnection::HandleConnect() {
this->Complete(1, 5); this->Complete(1, 5);

View File

@ -22,6 +22,8 @@ class ClientConnection : public RealmConnection {
// Virtual member functions // Virtual member functions
virtual int32_t HandleConnect(); virtual int32_t HandleConnect();
virtual void HandleCharacterCreate(uint8_t result);
virtual void HandleCharacterDelete(uint8_t result);
// Member functions // Member functions
ClientConnection(RealmResponse* realmResponse) ClientConnection(RealmResponse* realmResponse)

View File

@ -19,8 +19,8 @@ int32_t RealmConnection::MessageHandler(void* param, NETMESSAGE msgId, uint32_t
break; break;
} }
case SMSG_CREATE_CHAR: { case SMSG_CHAR_CREATE: {
// TODO result = connection->CreateCharHandler(msgId, time, msg);
break; break;
} }
@ -30,7 +30,7 @@ int32_t RealmConnection::MessageHandler(void* param, NETMESSAGE msgId, uint32_t
} }
case SMSG_DELETE_CHAR: { case SMSG_DELETE_CHAR: {
// TODO result = connection->DeleteCharHandler(msgId, time, msg);
break; break;
} }
@ -91,7 +91,7 @@ RealmConnection::RealmConnection(RealmResponse* realmResponse) {
this->SetMessageHandler(SMSG_AUTH_RESPONSE, &RealmConnection::MessageHandler, this); this->SetMessageHandler(SMSG_AUTH_RESPONSE, &RealmConnection::MessageHandler, this);
this->SetMessageHandler(SMSG_ADDON_INFO, &RealmConnection::MessageHandler, this); this->SetMessageHandler(SMSG_ADDON_INFO, &RealmConnection::MessageHandler, this);
this->SetMessageHandler(SMSG_ENUM_CHARACTERS_RESULT, &RealmConnection::MessageHandler, this); this->SetMessageHandler(SMSG_ENUM_CHARACTERS_RESULT, &RealmConnection::MessageHandler, this);
this->SetMessageHandler(SMSG_CREATE_CHAR, &RealmConnection::MessageHandler, this); this->SetMessageHandler(SMSG_CHAR_CREATE, &RealmConnection::MessageHandler, this);
this->SetMessageHandler(SMSG_CHARACTER_LOGIN_FAILED, &RealmConnection::MessageHandler, this); this->SetMessageHandler(SMSG_CHARACTER_LOGIN_FAILED, &RealmConnection::MessageHandler, this);
this->SetMessageHandler(SMSG_LOGOUT_COMPLETE, &RealmConnection::MessageHandler, this); this->SetMessageHandler(SMSG_LOGOUT_COMPLETE, &RealmConnection::MessageHandler, this);
this->SetMessageHandler(SMSG_LOGOUT_CANCEL_ACK, &RealmConnection::MessageHandler, this); this->SetMessageHandler(SMSG_LOGOUT_CANCEL_ACK, &RealmConnection::MessageHandler, this);
@ -294,6 +294,24 @@ int32_t RealmConnection::HandleCharEnum(uint32_t msgId, uint32_t time, CDataStor
return 1; return 1;
} }
int32_t RealmConnection::CreateCharHandler(uint32_t msgId, uint32_t time, CDataStore* msg) {
uint8_t result;
msg->Get(result);
this->HandleCharacterCreate(result);
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() { void RealmConnection::RequestCharacterEnum() {
CDataStore msg; CDataStore msg;

View File

@ -46,11 +46,15 @@ class RealmConnection : public NetClient {
// Virtual member functions // Virtual member functions
virtual int32_t HandleAuthChallenge(AuthenticationChallenge* challenge); virtual int32_t HandleAuthChallenge(AuthenticationChallenge* challenge);
virtual void HandleCharacterCreate(uint8_t result) = 0;
virtual void HandleCharacterDelete(uint8_t result) = 0;
// Member functions // Member functions
RealmConnection(RealmResponse* realmResponse); RealmConnection(RealmResponse* realmResponse);
int32_t HandleAuthResponse(uint32_t msgId, uint32_t time, CDataStore* msg); int32_t HandleAuthResponse(uint32_t msgId, uint32_t time, CDataStore* msg);
int32_t HandleCharEnum(uint32_t msgId, uint32_t time, CDataStore* msg); int32_t HandleCharEnum(uint32_t msgId, uint32_t time, CDataStore* msg);
int32_t CreateCharHandler(uint32_t msgId, uint32_t time, CDataStore* msg);
int32_t DeleteCharHandler(uint32_t msgId, uint32_t time, CDataStore* msg);
void RequestCharacterEnum(); void RequestCharacterEnum();
void RequestCharacterLogin(uint64_t guid, int32_t a2); void RequestCharacterLogin(uint64_t guid, int32_t a2);
void SetSelectedRealm(uint32_t a2, uint32_t a3, uint32_t a4); void SetSelectedRealm(uint32_t a2, uint32_t a3, uint32_t a4);

View File

@ -1,6 +1,7 @@
file(GLOB PRIVATE_SOURCES file(GLOB PRIVATE_SOURCES
"*.cpp" "*.cpp"
"client/*.cpp" "client/*.cpp"
"movement/*.cpp"
) )
add_library(object STATIC add_library(object STATIC
@ -15,4 +16,5 @@ target_include_directories(object
target_link_libraries(object target_link_libraries(object
PRIVATE PRIVATE
db db
ui
) )

View File

@ -1,6 +1,7 @@
#ifndef OBJECT_CLIENT_HPP #ifndef OBJECT_CLIENT_HPP
#define OBJECT_CLIENT_HPP #define OBJECT_CLIENT_HPP
#include "client/CGPlayer_C.hpp"
#include "client/ObjMgr.hpp" #include "client/ObjMgr.hpp"
#include "object/Types.hpp" #include "object/Types.hpp"

View File

@ -72,6 +72,17 @@ enum OBJECT_TYPE_ID {
// TODO // TODO
}; };
enum OUT_OF_RANGE_TYPE {
OUT_OF_RANGE_0 = 0,
OUT_OF_RANGE_1 = 1,
OUT_OF_RANGE_2 = 2,
};
enum PLAYER_TYPE {
PLAYER_NORMAL = 0,
PLAYER_BOT = 1,
};
enum SHEATHE_TYPE { enum SHEATHE_TYPE {
SHEATHE_0 = 0, SHEATHE_0 = 0,
SHEATHE_1 = 1, SHEATHE_1 = 1,

View 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;
}

View 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

View 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();
}

View 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

View File

@ -24,3 +24,7 @@ uint32_t CGContainer::TotalFields() {
uint32_t CGContainer::TotalFieldsSaved() { uint32_t CGContainer::TotalFieldsSaved() {
return CGContainer::GetBaseOffsetSaved() + 72; return CGContainer::GetBaseOffsetSaved() + 72;
} }
CGContainerData* CGContainer::Container() const {
return this->m_cont;
}

View File

@ -1,12 +1,13 @@
#ifndef OBJECT_CLIENT_CG_CONTAINER_HPP #ifndef OBJECT_CLIENT_CG_CONTAINER_HPP
#define OBJECT_CLIENT_CG_CONTAINER_HPP #define OBJECT_CLIENT_CG_CONTAINER_HPP
#include "util/GUID.hpp"
#include <cstdint> #include <cstdint>
struct CGContainerData { struct CGContainerData {
uint32_t numSlots; uint32_t numSlots;
uint32_t pad; uint32_t pad;
uint64_t slots[36]; WOWGUID slots[36];
}; };
class CGContainer { class CGContainer {
@ -19,9 +20,13 @@ class CGContainer {
static uint32_t TotalFields(); static uint32_t TotalFields();
static uint32_t TotalFieldsSaved(); static uint32_t TotalFieldsSaved();
// Public member variables protected:
// Protected member variables
CGContainerData* m_cont; CGContainerData* m_cont;
uint32_t* m_contSaved; uint32_t* m_contSaved;
// Protected member functions
CGContainerData* Container() const;
}; };
#endif #endif

View File

@ -1,5 +1,13 @@
#include "object/client/CGContainer_C.hpp" #include "object/client/CGContainer_C.hpp"
CGContainer_C::CGContainer_C(uint32_t time, CClientObjCreate& objCreate) : CGItem_C(time, objCreate) {
// TODO
}
CGContainer_C::~CGContainer_C() {
// TODO
}
void CGContainer_C::SetStorage(uint32_t* storage, uint32_t* saved) { void CGContainer_C::SetStorage(uint32_t* storage, uint32_t* saved) {
this->CGItem_C::SetStorage(storage, saved); this->CGItem_C::SetStorage(storage, saved);

View File

@ -1,12 +1,17 @@
#ifndef OBJECT_CLIENT_CG_CONTAINER_C_HPP #ifndef OBJECT_CLIENT_CG_CONTAINER_C_HPP
#define 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/CGContainer.hpp"
#include "object/client/CGItem_C.hpp" #include "object/client/CGItem_C.hpp"
class CGContainer_C : public CGItem_C, public CGContainer { class CGContainer_C : public CGItem_C, public CGContainer {
public: public:
// Virtual public member functions
virtual ~CGContainer_C();
// Public member functions // Public member functions
CGContainer_C(uint32_t time, CClientObjCreate& objCreate);
void SetStorage(uint32_t* storage, uint32_t* saved); void SetStorage(uint32_t* storage, uint32_t* saved);
}; };

View File

@ -24,3 +24,7 @@ uint32_t CGCorpse::TotalFields() {
uint32_t CGCorpse::TotalFieldsSaved() { uint32_t CGCorpse::TotalFieldsSaved() {
return CGCorpse::GetBaseOffsetSaved() + 3; return CGCorpse::GetBaseOffsetSaved() + 3;
} }
CGCorpseData* CGCorpse::Corpse() const {
return this->m_corpse;
}

View File

@ -17,9 +17,13 @@ class CGCorpse {
static uint32_t TotalFields(); static uint32_t TotalFields();
static uint32_t TotalFieldsSaved(); static uint32_t TotalFieldsSaved();
// Public member variables protected:
// Protected member variables
CGCorpseData* m_corpse; CGCorpseData* m_corpse;
uint32_t* m_corpseSaved; uint32_t* m_corpseSaved;
// Protected member functions
CGCorpseData* Corpse() const;
}; };
#endif #endif

View File

@ -1,5 +1,21 @@
#include "object/client/CGCorpse_C.hpp" #include "object/client/CGCorpse_C.hpp"
CGCorpse_C::CGCorpse_C(uint32_t time, CClientObjCreate& objCreate) : CGObject_C(time, objCreate) {
// TODO
}
CGCorpse_C::~CGCorpse_C() {
// TODO
}
void CGCorpse_C::PostInit(uint32_t time, const CClientObjCreate& init, bool a4) {
// TODO
this->CGObject_C::PostInit(time, init, a4);
// TODO
}
void CGCorpse_C::SetStorage(uint32_t* storage, uint32_t* saved) { void CGCorpse_C::SetStorage(uint32_t* storage, uint32_t* saved) {
this->CGObject_C::SetStorage(storage, saved); this->CGObject_C::SetStorage(storage, saved);

View File

@ -1,12 +1,18 @@
#ifndef OBJECT_CLIENT_CG_CORPSE_C_HPP #ifndef OBJECT_CLIENT_CG_CORPSE_C_HPP
#define 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/CGCorpse.hpp"
#include "object/client/CGObject_C.hpp" #include "object/client/CGObject_C.hpp"
class CGCorpse_C : public CGObject_C, public CGCorpse { class CGCorpse_C : public CGObject_C, public CGCorpse {
public: public:
// Virtual public member functions
virtual ~CGCorpse_C();
// Public member functions // Public member functions
CGCorpse_C(uint32_t time, CClientObjCreate& objCreate);
void PostInit(uint32_t time, const CClientObjCreate& init, bool a4);
void SetStorage(uint32_t* storage, uint32_t* saved); void SetStorage(uint32_t* storage, uint32_t* saved);
}; };

View File

@ -24,3 +24,7 @@ uint32_t CGDynamicObject::TotalFields() {
uint32_t CGDynamicObject::TotalFieldsSaved() { uint32_t CGDynamicObject::TotalFieldsSaved() {
return CGDynamicObject::GetBaseOffsetSaved() + 0; return CGDynamicObject::GetBaseOffsetSaved() + 0;
} }
CGDynamicObjectData* CGDynamicObject::DynamicObject() const {
return this->m_dynamicObj;
}

View File

@ -17,9 +17,13 @@ class CGDynamicObject {
static uint32_t TotalFields(); static uint32_t TotalFields();
static uint32_t TotalFieldsSaved(); static uint32_t TotalFieldsSaved();
// Public member variables protected:
// Protected member variables
CGDynamicObjectData* m_dynamicObj; CGDynamicObjectData* m_dynamicObj;
uint32_t* m_dynamicObjSaved; uint32_t* m_dynamicObjSaved;
// Protected member functions
CGDynamicObjectData* DynamicObject() const;
}; };
#endif #endif

View File

@ -1,5 +1,21 @@
#include "object/client/CGDynamicObject_C.hpp" #include "object/client/CGDynamicObject_C.hpp"
CGDynamicObject_C::CGDynamicObject_C(uint32_t time, CClientObjCreate& objCreate) : CGObject_C(time, objCreate) {
// TODO
}
CGDynamicObject_C::~CGDynamicObject_C() {
// TODO
}
void CGDynamicObject_C::PostInit(uint32_t time, const CClientObjCreate& init, bool a4) {
// TODO
this->CGObject_C::PostInit(time, init, a4);
// TODO
}
void CGDynamicObject_C::SetStorage(uint32_t* storage, uint32_t* saved) { void CGDynamicObject_C::SetStorage(uint32_t* storage, uint32_t* saved) {
this->CGObject_C::SetStorage(storage, saved); this->CGObject_C::SetStorage(storage, saved);

View File

@ -1,12 +1,18 @@
#ifndef OBJECT_CLIENT_CG_DYNAMIC_OBJECT_C_HPP #ifndef OBJECT_CLIENT_CG_DYNAMIC_OBJECT_C_HPP
#define 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/CGDynamicObject.hpp"
#include "object/client/CGObject_C.hpp" #include "object/client/CGObject_C.hpp"
class CGDynamicObject_C : public CGObject_C, public CGDynamicObject { class CGDynamicObject_C : public CGObject_C, public CGDynamicObject {
public: public:
// Virtual public member functions
virtual ~CGDynamicObject_C();
// Public member functions // Public member functions
CGDynamicObject_C(uint32_t time, CClientObjCreate& objCreate);
void PostInit(uint32_t time, const CClientObjCreate& init, bool a4);
void SetStorage(uint32_t* storage, uint32_t* saved); void SetStorage(uint32_t* storage, uint32_t* saved);
}; };

View File

@ -24,3 +24,7 @@ uint32_t CGGameObject::TotalFields() {
uint32_t CGGameObject::TotalFieldsSaved() { uint32_t CGGameObject::TotalFieldsSaved() {
return CGGameObject::GetBaseOffsetSaved() + 4; return CGGameObject::GetBaseOffsetSaved() + 4;
} }
CGGameObjectData* CGGameObject::GameObject() const {
return this->m_gameObj;
}

View File

@ -17,9 +17,13 @@ class CGGameObject {
static uint32_t TotalFields(); static uint32_t TotalFields();
static uint32_t TotalFieldsSaved(); static uint32_t TotalFieldsSaved();
// Public member variables protected:
// Protected member variables
CGGameObjectData* m_gameObj; CGGameObjectData* m_gameObj;
uint32_t* m_gameObjSaved; uint32_t* m_gameObjSaved;
// Protected member functions
CGGameObjectData* GameObject() const;
}; };
#endif #endif

View File

@ -1,5 +1,21 @@
#include "object/client/CGGameObject_C.hpp" #include "object/client/CGGameObject_C.hpp"
CGGameObject_C::CGGameObject_C(uint32_t time, CClientObjCreate& objCreate) : CGObject_C(time, objCreate) {
// TODO
}
CGGameObject_C::~CGGameObject_C() {
// TODO
}
void CGGameObject_C::PostInit(uint32_t time, const CClientObjCreate& init, bool a4) {
// TODO
this->CGObject_C::PostInit(time, init, a4);
// TODO
}
void CGGameObject_C::SetStorage(uint32_t* storage, uint32_t* saved) { void CGGameObject_C::SetStorage(uint32_t* storage, uint32_t* saved) {
this->CGObject_C::SetStorage(storage, saved); this->CGObject_C::SetStorage(storage, saved);

View File

@ -1,12 +1,18 @@
#ifndef OBJECT_CLIENT_CG_GAME_OBJECT_C_HPP #ifndef OBJECT_CLIENT_CG_GAME_OBJECT_C_HPP
#define 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/CGGameObject.hpp"
#include "object/client/CGObject_C.hpp" #include "object/client/CGObject_C.hpp"
class CGGameObject_C : public CGObject_C, public CGGameObject { class CGGameObject_C : public CGObject_C, public CGGameObject {
public: public:
// Virtual public member functions
virtual ~CGGameObject_C();
// Public member functions // Public member functions
CGGameObject_C(uint32_t time, CClientObjCreate& objCreate);
void PostInit(uint32_t time, const CClientObjCreate& init, bool a4);
void SetStorage(uint32_t* storage, uint32_t* saved); void SetStorage(uint32_t* storage, uint32_t* saved);
}; };

View File

@ -24,3 +24,7 @@ uint32_t CGItem::TotalFields() {
uint32_t CGItem::TotalFieldsSaved() { uint32_t CGItem::TotalFieldsSaved() {
return CGItem::GetBaseOffsetSaved() + 47; return CGItem::GetBaseOffsetSaved() + 47;
} }
CGItemData* CGItem::Item() const {
return this->m_item;
}

View File

@ -1,6 +1,7 @@
#ifndef OBJECT_CLIENT_CG_ITEM_HPP #ifndef OBJECT_CLIENT_CG_ITEM_HPP
#define OBJECT_CLIENT_CG_ITEM_HPP #define OBJECT_CLIENT_CG_ITEM_HPP
#include "util/GUID.hpp"
#include <cstdint> #include <cstdint>
struct ItemEnchantment { struct ItemEnchantment {
@ -10,10 +11,10 @@ struct ItemEnchantment {
}; };
struct CGItemData { struct CGItemData {
uint64_t owner; WOWGUID owner;
uint64_t containedIn; WOWGUID containedIn;
uint64_t creator; WOWGUID creator;
uint64_t giftCreator; WOWGUID giftCreator;
uint32_t stackCount; uint32_t stackCount;
int32_t expiration; int32_t expiration;
int32_t spellCharges[5]; int32_t spellCharges[5];
@ -37,9 +38,13 @@ class CGItem {
static uint32_t TotalFields(); static uint32_t TotalFields();
static uint32_t TotalFieldsSaved(); static uint32_t TotalFieldsSaved();
// Public member variables protected:
// Protected member variables
CGItemData* m_item; CGItemData* m_item;
uint32_t* m_itemSaved; uint32_t* m_itemSaved;
// Protected member functions
CGItemData* Item() const;
}; };
#endif #endif

View File

@ -1,5 +1,19 @@
#include "object/client/CGItem_C.hpp" #include "object/client/CGItem_C.hpp"
CGItem_C::CGItem_C(uint32_t time, CClientObjCreate& objCreate) : CGObject_C(time, objCreate) {
// TODO
}
CGItem_C::~CGItem_C() {
// TODO
}
void CGItem_C::PostInit(uint32_t time, const CClientObjCreate& init, bool a4) {
this->CGObject_C::PostInit(time, init, a4);
// TODO
}
void CGItem_C::SetStorage(uint32_t* storage, uint32_t* saved) { void CGItem_C::SetStorage(uint32_t* storage, uint32_t* saved) {
this->CGObject_C::SetStorage(storage, saved); this->CGObject_C::SetStorage(storage, saved);

View File

@ -1,12 +1,18 @@
#ifndef OBJECT_CLIENT_CG_ITEM_C_HPP #ifndef OBJECT_CLIENT_CG_ITEM_C_HPP
#define 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/CGObject_C.hpp"
#include "object/client/CGItem.hpp" #include "object/client/CGItem.hpp"
class CGItem_C : public CGObject_C, public CGItem { class CGItem_C : public CGObject_C, public CGItem {
public: public:
// Virtual public member functions
virtual ~CGItem_C();
// Public member functions // Public member functions
CGItem_C(uint32_t time, CClientObjCreate& objCreate);
void PostInit(uint32_t time, const CClientObjCreate& init, bool a4);
void SetStorage(uint32_t* storage, uint32_t* saved); void SetStorage(uint32_t* storage, uint32_t* saved);
}; };

View File

@ -23,3 +23,27 @@ uint32_t CGObject::TotalFields() {
uint32_t CGObject::TotalFieldsSaved() { uint32_t CGObject::TotalFieldsSaved() {
return CGObject::GetBaseOffsetSaved() + 3; return CGObject::GetBaseOffsetSaved() + 3;
} }
WOWGUID CGObject::GetGUID() const {
return this->m_obj->m_guid;
}
OBJECT_TYPE CGObject::GetType() const {
return this->m_obj->m_type;
}
OBJECT_TYPE_ID CGObject::GetTypeID() const {
return this->m_typeID;
}
int32_t CGObject::IsA(OBJECT_TYPE type) const {
return (this->GetType() & type) != 0;
}
int32_t CGObject::IsExactlyA(OBJECT_TYPE_ID typeID) const {
return this->m_typeID == typeID;
}
CGObjectData* CGObject::Obj() const {
return this->m_obj;
}

View File

@ -2,10 +2,11 @@
#define OBJECT_CLIENT_CG_OBJECT_HPP #define OBJECT_CLIENT_CG_OBJECT_HPP
#include "object/Types.hpp" #include "object/Types.hpp"
#include "util/GUID.hpp"
#include <cstdint> #include <cstdint>
struct CGObjectData { struct CGObjectData {
uint64_t m_guid; WOWGUID m_guid;
OBJECT_TYPE m_type; OBJECT_TYPE m_type;
int32_t m_entryID; int32_t m_entryID;
float m_scale; float m_scale;
@ -24,10 +25,23 @@ class CGObject {
// Public member variables // Public member variables
uint32_t uint0; // TODO what is this? uint32_t uint0; // TODO what is this?
uint32_t m_memHandle;
// Public member functions
WOWGUID GetGUID() const;
OBJECT_TYPE GetType() const;
OBJECT_TYPE_ID GetTypeID() const;
int32_t IsA(OBJECT_TYPE type) const;
int32_t IsExactlyA(OBJECT_TYPE_ID typeID) const;
protected:
// Protected member variables
CGObjectData* m_obj; CGObjectData* m_obj;
uint32_t* m_objSaved; uint32_t* m_objSaved;
uint32_t m_memHandle;
OBJECT_TYPE_ID m_typeID; OBJECT_TYPE_ID m_typeID;
// Protected member functions
CGObjectData* Obj() const;
}; };
#endif #endif

View File

@ -1,4 +1,188 @@
#include "object/client/CGObject_C.hpp" #include "object/client/CGObject_C.hpp"
#include "model/Model2.hpp"
#include "object/client/ObjMgr.hpp"
#include "world/World.hpp"
CGObject_C::CGObject_C(uint32_t time, CClientObjCreate& objCreate) {
// TODO
this->m_model = nullptr;
this->m_worldObject = 0;
// 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
}
CGObject_C::~CGObject_C() {
// TODO
}
void CGObject_C::AddWorldObject() {
if (!this->m_model) {
const char* fileName;
if (this->GetModelFileName(fileName)) {
auto model = CWorld::GetM2Scene()->CreateModel(fileName, 0);
this->SetModel(model);
model->Release();
}
}
if (!this->m_model) {
return;
}
if (ClntObjMgrGetPlayerType() != PLAYER_NORMAL) {
return;
}
if (this->m_worldObject) {
// TODO SysMsgPrintf(1, 2, "OBJECTALREADYACTIVE|0x%016I64X", this->GetGUID());
return;
}
uint32_t objFlags = 0x0;
if (this->IsA(TYPE_GAMEOBJECT)) {
objFlags |= 0x8 | 0x2 | 0x1;
} else if (this->IsA(TYPE_DYNAMICOBJECT)) {
objFlags |= 0x8 | 0x2;
} else if (this->IsA(TYPE_CORPSE)) {
// TODO
} else if (this->IsA(TYPE_UNIT)) {
// TODO
objFlags |= 0x10;
if (this->IsA(TYPE_PLAYER)) {
objFlags |= 0x20;
}
}
this->m_worldObject = CWorld::AddObject(this->GetObjectModel(), nullptr, nullptr, this->GetGUID(), 0, objFlags);
if (!this->m_inReenable && this->m_postInited) {
this->UpdateWorldObject(false);
}
}
int32_t CGObject_C::CanBeTargetted() {
return false;
}
int32_t CGObject_C::CanHighlight() {
return false;
}
void CGObject_C::Disable() {
// TODO
this->m_disabled = true;
// TODO other flag manipulation
this->m_disableTimeMs = CWorld::GetCurTimeMs();
}
float CGObject_C::GetFacing() const {
return 0.0f;
}
int32_t CGObject_C::GetModelFileName(const char*& name) const {
return false;
}
CM2Model* CGObject_C::GetObjectModel() {
return this->m_model;
}
C3Vector CGObject_C::GetPosition() const {
return { 0.0f, 0.0f, 0.0f };
}
int32_t CGObject_C::IsInReenable() {
return this->m_inReenable;
}
int32_t CGObject_C::IsObjectLocked() {
return this->m_lockCount != 0;
}
void CGObject_C::PostReenable() {
// TODO
this->m_inReenable = false;
// TODO
}
void CGObject_C::Reenable() {
this->m_disabled = false;
this->m_inReenable = true;
// TODO
}
void CGObject_C::PostInit(uint32_t time, const CClientObjCreate& init, bool a4) {
this->m_postInited = 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::SetModel(CM2Model* model) {
// No change
if (this->m_model == model) {
return;
}
if (model) {
model->AddRef();
}
this->m_model = model;
this->SetModelFinish(model);
}
void CGObject_C::SetModelFinish(CM2Model* model) {
// TODO
}
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) { void CGObject_C::SetStorage(uint32_t* storage, uint32_t* saved) {
this->m_obj = reinterpret_cast<CGObjectData*>(&storage[CGObject::GetBaseOffset()]); this->m_obj = reinterpret_cast<CGObjectData*>(&storage[CGObject::GetBaseOffset()]);
@ -45,3 +229,7 @@ void CGObject_C::SetTypeID(OBJECT_TYPE_ID typeID) {
break; break;
} }
} }
void CGObject_C::UpdateWorldObject(int32_t a2) {
// TODO
}

View File

@ -1,14 +1,64 @@
#ifndef OBJECT_CLIENT_CG_OBJECT_C_HPP #ifndef OBJECT_CLIENT_CG_OBJECT_C_HPP
#define OBJECT_CLIENT_CG_OBJECT_C_HPP #define OBJECT_CLIENT_CG_OBJECT_C_HPP
#include "object/client/CGObject.hpp"
#include "object/Types.hpp" #include "object/Types.hpp"
#include "util/CHashKeyGUID.hpp" #include "object/client/CClientObjCreate.hpp"
#include "object/client/CGObject.hpp"
#include "util/GUID.hpp"
#include "world/Types.hpp"
#include <storm/Hash.hpp> #include <storm/Hash.hpp>
#include <storm/List.hpp>
class CM2Model;
class CGObject_C : public CGObject, public TSHashObject<CGObject_C, CHashKeyGUID> { class CGObject_C : public CGObject, public TSHashObject<CGObject_C, CHashKeyGUID> {
public: public:
// Public member variables
TSLink<CGObject_C> m_link;
uint32_t m_disableTimeMs;
// TODO
CM2Model* m_model;
// TODO
HWORLDOBJECT m_worldObject;
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
virtual ~CGObject_C();
virtual void Disable();
void Reenable();
void PostReenable();
virtual void HandleOutOfRange(OUT_OF_RANGE_TYPE type) {};
virtual void UpdateWorldObject(int32_t a2);
// TODO
virtual C3Vector GetPosition() const;
// TODO
virtual float GetFacing() const;
// TODO
virtual int32_t GetModelFileName(const char*& name) const;
// TODO
virtual int32_t CanHighlight();
virtual int32_t CanBeTargetted();
// TODO
virtual CM2Model* GetObjectModel();
// Public member functions // Public member functions
CGObject_C() = default;
CGObject_C(uint32_t time, CClientObjCreate& objCreate);
void AddWorldObject();
int32_t IsInReenable();
int32_t IsObjectLocked();
void PostInit(uint32_t time, const CClientObjCreate& init, bool a4);
void SetBlock(uint32_t block, uint32_t value);
void SetDisablePending(int32_t pending);
void SetModel(CM2Model* model);
void SetModelFinish(CM2Model* model);
void SetObjectLocked(int32_t locked);
void SetStorage(uint32_t* storage, uint32_t* saved); void SetStorage(uint32_t* storage, uint32_t* saved);
void SetTypeID(OBJECT_TYPE_ID typeID); void SetTypeID(OBJECT_TYPE_ID typeID);
}; };

View File

@ -40,3 +40,19 @@ uint32_t CGPlayer::TotalFieldsSaved() {
uint32_t CGPlayer::TotalRemoteFieldsSaved() { uint32_t CGPlayer::TotalRemoteFieldsSaved() {
return CGPlayer::GetBaseOffsetSaved() + 173; return CGPlayer::GetBaseOffsetSaved() + 173;
} }
uint32_t CGPlayer::GetMoney() const {
return this->Player()->coinage;
}
uint32_t CGPlayer::GetNextLevelXP() const {
return this->Player()->nextLevelXP;
}
uint32_t CGPlayer::GetXP() const {
return this->Player()->xp;
}
CGPlayerData* CGPlayer::Player() const {
return this->m_player;
}

View File

@ -2,6 +2,7 @@
#define OBJECT_CLIENT_CG_PLAYER_HPP #define OBJECT_CLIENT_CG_PLAYER_HPP
#include "object/Types.hpp" #include "object/Types.hpp"
#include "util/GUID.hpp"
#include <cstdint> #include <cstdint>
struct CQuestLogData { struct CQuestLogData {
@ -18,36 +19,119 @@ struct CVisibleItemData {
uint32_t enchantment; 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 { struct CGPlayerData {
uint64_t duelArbiter; WOWGUID duelArbiter;
uint32_t flags; uint32_t flags;
uint32_t guildID; uint32_t guildID;
uint32_t guildRank; uint32_t guildRank;
int32_t pad1; uint8_t skinID;
int32_t pad2; uint8_t faceID;
int32_t pad3; 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; uint32_t duelTeam;
int32_t guildTimestamp; int32_t guildTimestamp;
CQuestLogData questLog[25]; CQuestLogData questLog[25];
CVisibleItemData visibleItems[19]; CVisibleItemData visibleItems[19];
int32_t chosenTitle; int32_t chosenTitle;
int32_t fakeInebriation; int32_t fakeInebriation;
int32_t pad4; int32_t pad1;
uint64_t invSlots[NUM_INVENTORY_SLOTS]; WOWGUID invSlots[NUM_INVENTORY_SLOTS];
uint64_t packSlots[16]; WOWGUID packSlots[16];
uint64_t bankSlots[28]; WOWGUID bankSlots[28];
uint64_t bankBagSlots[7]; WOWGUID bankBagSlots[7];
uint64_t vendorBuybackSlots[12]; WOWGUID vendorBuybackSlots[12];
uint64_t keyringSlots[32]; WOWGUID keyringSlots[32];
uint64_t currencyTokenSlots[32]; WOWGUID currencyTokenSlots[32];
uint64_t farsightObject; WOWGUID farsightObject;
uint64_t knownTitles; WOWGUID knownTitles;
uint64_t knownTitles2; WOWGUID knownTitles2;
uint64_t knownTitles3; WOWGUID knownTitles3;
uint64_t knownCurrencies; WOWGUID knownCurrencies;
uint32_t xp; uint32_t xp;
uint32_t nextLevelXP; uint32_t nextLevelXP;
// TODO 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 { class CGPlayer {
@ -64,9 +148,18 @@ class CGPlayer {
static uint32_t TotalFieldsSaved(); static uint32_t TotalFieldsSaved();
static uint32_t TotalRemoteFieldsSaved(); static uint32_t TotalRemoteFieldsSaved();
// Public member variables // Public member functions
uint32_t GetMoney() const;
uint32_t GetNextLevelXP() const;
uint32_t GetXP() const;
protected:
// Protected member variables
CGPlayerData* m_player; CGPlayerData* m_player;
uint32_t* m_playerSaved; uint32_t* m_playerSaved;
// Protected member functions
CGPlayerData* Player() const;
}; };
#endif #endif

View File

@ -1,8 +1,85 @@
#include "object/client/CGPlayer_C.hpp" #include "object/client/CGPlayer_C.hpp"
#include "db/Db.hpp" #include "db/Db.hpp"
#include "object/Types.hpp" #include "object/Types.hpp"
#include "object/client/ObjMgr.hpp"
#include "ui/FrameScript.hpp"
#include "ui/Game.hpp"
#include <storm/Error.hpp> #include <storm/Error.hpp>
CGPlayer_C* CGPlayer_C::GetActivePtr() {
return static_cast<CGPlayer_C*>(
ClntObjMgrObjectPtr(ClntObjMgrGetActivePlayer(), TYPE_PLAYER, __FILE__, __LINE__)
);
}
CGPlayer_C::CGPlayer_C(uint32_t time, CClientObjCreate& objCreate) : CGUnit_C(time, objCreate) {
// TODO
}
CGPlayer_C::~CGPlayer_C() {
// TODO
}
uint32_t CGPlayer_C::GetMoney() const {
if (this->GetGUID() != ClntObjMgrGetActivePlayer()) {
return 0;
}
return this->CGPlayer::GetMoney();
}
uint32_t CGPlayer_C::GetNextLevelXP() const {
if (this->GetGUID() != ClntObjMgrGetActivePlayer()) {
return 0;
}
return this->CGPlayer::GetNextLevelXP();
}
uint32_t CGPlayer_C::GetXP() const {
if (this->GetGUID() != ClntObjMgrGetActivePlayer()) {
return 0;
}
return this->CGPlayer::GetXP();
}
void CGPlayer_C::PostInit(uint32_t time, const CClientObjCreate& init, bool a4) {
// TODO
this->CGUnit_C::PostInit(time, init, a4);
// TODO
if (this->GetGUID() == ClntObjMgrGetActivePlayer()) {
this->PostInitActivePlayer();
} else {
this->UpdatePartyMemberState();
}
// TODO
}
void CGPlayer_C::PostInitActivePlayer() {
// TODO
if (ClntObjMgrGetPlayerType() == PLAYER_NORMAL) {
// TODO
FrameScript_SignalEvent(SCRIPT_ACTIONBAR_SLOT_CHANGED, "%d", 0);
}
// TODO
if (ClntObjMgrGetPlayerType() == PLAYER_NORMAL) {
// TODO
CGGameUI::EnterWorld();
}
// TODO
}
void CGPlayer_C::SetStorage(uint32_t* storage, uint32_t* saved) { void CGPlayer_C::SetStorage(uint32_t* storage, uint32_t* saved) {
this->CGUnit_C::SetStorage(storage, saved); this->CGUnit_C::SetStorage(storage, saved);
@ -10,6 +87,10 @@ void CGPlayer_C::SetStorage(uint32_t* storage, uint32_t* saved) {
this->m_playerSaved = &saved[CGPlayer::GetBaseOffsetSaved()]; this->m_playerSaved = &saved[CGPlayer::GetBaseOffsetSaved()];
} }
void CGPlayer_C::UpdatePartyMemberState() {
// TODO
}
uint32_t Player_C_GetDisplayId(uint32_t race, uint32_t sex) { uint32_t Player_C_GetDisplayId(uint32_t race, uint32_t sex) {
STORM_ASSERT(sex < UNITSEX_LAST); STORM_ASSERT(sex < UNITSEX_LAST);

View File

@ -1,6 +1,7 @@
#ifndef OBJECT_CLIENT_CG_PLAYER_C_HPP #ifndef OBJECT_CLIENT_CG_PLAYER_C_HPP
#define 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/CGPlayer.hpp"
#include "object/client/CGUnit_C.hpp" #include "object/client/CGUnit_C.hpp"
#include <cstdint> #include <cstdint>
@ -9,8 +10,21 @@ class CreatureModelDataRec;
class CGPlayer_C : public CGUnit_C, public CGPlayer { class CGPlayer_C : public CGUnit_C, public CGPlayer {
public: public:
// Public static functions
static CGPlayer_C* GetActivePtr();
// Virtual public member functions
virtual ~CGPlayer_C();
// Public member functions // Public member functions
CGPlayer_C(uint32_t time, CClientObjCreate& objCreate);
uint32_t GetMoney() const;
uint32_t GetNextLevelXP() const;
uint32_t GetXP() const;
void PostInit(uint32_t time, const CClientObjCreate& init, bool a4);
void PostInitActivePlayer();
void SetStorage(uint32_t* storage, uint32_t* saved); void SetStorage(uint32_t* storage, uint32_t* saved);
void UpdatePartyMemberState();
}; };
uint32_t Player_C_GetDisplayId(uint32_t race, uint32_t sex); uint32_t Player_C_GetDisplayId(uint32_t race, uint32_t sex);

View File

@ -24,3 +24,15 @@ uint32_t CGUnit::TotalFields() {
uint32_t CGUnit::TotalFieldsSaved() { uint32_t CGUnit::TotalFieldsSaved() {
return CGUnit::GetBaseOffsetSaved() + 123; return CGUnit::GetBaseOffsetSaved() + 123;
} }
int32_t CGUnit::GetDisplayID() const {
return this->Unit()->displayID;
}
int32_t CGUnit::GetNativeDisplayID() const {
return this->Unit()->nativeDisplayID;
}
CGUnitData* CGUnit::Unit() const {
return this->m_unit;
}

View File

@ -1,24 +1,25 @@
#ifndef OBJECT_CLIENT_CG_UNIT_HPP #ifndef OBJECT_CLIENT_CG_UNIT_HPP
#define OBJECT_CLIENT_CG_UNIT_HPP #define OBJECT_CLIENT_CG_UNIT_HPP
#include "util/GUID.hpp"
#include <cstdint> #include <cstdint>
struct CGUnitData { struct CGUnitData {
uint64_t charm; WOWGUID charm;
uint64_t summon; WOWGUID summon;
uint64_t critter; WOWGUID critter;
uint64_t charmedBy; WOWGUID charmedBy;
uint64_t summonedBy; WOWGUID summonedBy;
uint64_t createdBy; WOWGUID createdBy;
uint64_t target; WOWGUID target;
uint64_t channelObject; WOWGUID channelObject;
int32_t channelSpell; int32_t channelSpell;
int32_t pad1; int32_t pad1;
int32_t health; int32_t health;
int32_t power[7]; int32_t power[7];
int32_t maxHealth; int32_t maxHealth;
int32_t maxPower[7]; int32_t maxPower[7];
int32_t powerRegenFlatModifier[7]; float powerRegenFlatModifier[7];
int32_t powerRegenInterruptedFlatModifier[7]; int32_t powerRegenInterruptedFlatModifier[7];
int32_t level; int32_t level;
int32_t factionTemplate; int32_t factionTemplate;
@ -33,8 +34,8 @@ struct CGUnitData {
int32_t displayID; int32_t displayID;
int32_t nativeDisplayID; int32_t nativeDisplayID;
int32_t mountDisplayID; int32_t mountDisplayID;
uint32_t minDamage; float minDamage;
uint32_t maxDamage; float maxDamage;
uint32_t minOffhandDamage; uint32_t minOffhandDamage;
uint32_t maxOffhandDamage; uint32_t maxOffhandDamage;
int32_t pad2; int32_t pad2;
@ -43,7 +44,7 @@ struct CGUnitData {
uint32_t petExperience; uint32_t petExperience;
uint32_t petNextLevelExperience; uint32_t petNextLevelExperience;
uint32_t dynamicFlags; uint32_t dynamicFlags;
int32_t modCastingSpeed; float modCastingSpeed;
int32_t createdBySpell; int32_t createdBySpell;
uint32_t npcFlags; uint32_t npcFlags;
uint32_t emoteState; uint32_t emoteState;
@ -62,12 +63,12 @@ struct CGUnitData {
int32_t rangedAttackPower; int32_t rangedAttackPower;
int32_t rangedAttackPowerMods; int32_t rangedAttackPowerMods;
int32_t rangedAttackPowerMultiplier; int32_t rangedAttackPowerMultiplier;
int32_t minRangedDamage; float minRangedDamage;
int32_t maxRangedDamage; float maxRangedDamage;
int32_t powerCostModifier[7]; int32_t powerCostModifier[7];
int32_t powerCostMultiplier[7]; int32_t powerCostMultiplier[7];
int32_t maxHealthModifier; int32_t maxHealthModifier;
int32_t hoverHeight; float hoverHeight;
int32_t pad4; int32_t pad4;
}; };
@ -81,9 +82,17 @@ class CGUnit {
static uint32_t TotalFields(); static uint32_t TotalFields();
static uint32_t TotalFieldsSaved(); static uint32_t TotalFieldsSaved();
// Public member variables // Public member functions
int32_t GetDisplayID() const;
int32_t GetNativeDisplayID() const;
protected:
// Protected member variables
CGUnitData* m_unit; CGUnitData* m_unit;
uint32_t* m_unitSaved; uint32_t* m_unitSaved;
// Protected member functions
CGUnitData* Unit() const;
}; };
#endif #endif

View File

@ -1,5 +1,12 @@
#include "object/client/CGUnit_C.hpp" #include "object/client/CGUnit_C.hpp"
#include "component/CCharacterComponent.hpp"
#include "model/Model2.hpp"
#include "object/client/ObjMgr.hpp"
#include "db/Db.hpp" #include "db/Db.hpp"
#include "ui/Game.hpp"
#include <storm/Error.hpp>
WOWGUID CGUnit_C::s_activeMover;
const char* CGUnit_C::GetDisplayClassNameFromRecord(const ChrClassesRec* classRec, UNIT_SEX sex, UNIT_SEX* displaySex) { const char* CGUnit_C::GetDisplayClassNameFromRecord(const ChrClassesRec* classRec, UNIT_SEX sex, UNIT_SEX* displaySex) {
if (displaySex) { if (displaySex) {
@ -89,6 +96,161 @@ const char* CGUnit_C::GetDisplayRaceNameFromRecord(const ChrRacesRec* raceRec, U
return raceRec->m_name; return raceRec->m_name;
} }
CGUnit_C::CGUnit_C(uint32_t time, CClientObjCreate& objCreate) : CGObject_C(time, objCreate) {
// TODO
this->RefreshDataPointers();
// TODO
}
CGUnit_C::~CGUnit_C() {
// TODO
}
int32_t CGUnit_C::CanHighlight() {
if (this->m_unit->flags & 0x2000000) {
if (this->m_unit->createdBy != ClntObjMgrGetActivePlayer() || this->GetGUID() != CGPetInfo::GetPet(0)) {
return false;
}
}
return true;
}
int32_t CGUnit_C::CanBeTargetted() {
return this->CanHighlight();
}
int32_t CGUnit_C::GetDisplayID() const {
// Prefer local display ID if set and unit's display ID hasn't been overridden from unit's
// native display ID.
if (this->GetLocalDisplayID() && this->GetDisplayID() == this->GetNativeDisplayID()) {
return this->GetLocalDisplayID();
}
return this->CGUnit::GetDisplayID();
}
int32_t CGUnit_C::GetLocalDisplayID() const {
return this->m_localDisplayID;
}
CreatureModelDataRec* CGUnit_C::GetModelData() const {
auto displayID = this->GetDisplayID();
auto creatureDisplayInfoRec = g_creatureDisplayInfoDB.GetRecord(displayID);
if (!creatureDisplayInfoRec) {
// TODO SysMsgPrintf(1, 2, "NOCREATUREDISPLAYIDFOUND|%d", displayID);
return nullptr;
}
auto creatureModelDataRec = g_creatureModelDataDB.GetRecord(creatureDisplayInfoRec->m_modelID);
if (!creatureModelDataRec) {
// TODO SysMsgPrintf(1, 16, "INVALIDDISPLAYMODELRECORD|%d|%d", creatureDisplayInfoRec->m_modelID, creatureDisplayInfoRec->m_ID);
return nullptr;
}
return creatureModelDataRec;
}
int32_t CGUnit_C::GetModelFileName(const char*& name) const {
auto modelDataRec = this->GetModelData();
// Model data not found
if (!modelDataRec) {
name = "Spells\\ErrorCube.mdx";
return true;
}
name = modelDataRec->m_modelName;
return modelDataRec->m_modelName ? true : false;
}
void CGUnit_C::PostInit(uint32_t time, const CClientObjCreate& init, bool a4) {
// TODO
this->CGObject_C::PostInit(time, init, a4);
// TODO
if (this->m_displayInfo) {
CCharacterComponent::ApplyMonsterGeosets(this->m_model, this->m_displayInfo);
CCharacterComponent::ReplaceMonsterSkin(this->m_model, this->m_displayInfo, this->m_modelData);
if (this->m_modelData) {
this->m_model->m_flag4 = (this->m_modelData->m_flags & 0x200) ? true : false;
}
}
// TODO
}
void CGUnit_C::PostMovementUpdate(const CClientMoveUpdate& move, int32_t activeMover) {
// TODO
}
void CGUnit_C::RefreshDataPointers() {
auto displayID = this->GetDisplayID();
// Display info
this->m_displayInfo = g_creatureDisplayInfoDB.GetRecord(displayID);
if (!this->m_displayInfo) {
// TODO auto name = this->GetUnitName(0, 1);
// TODO SysMsgPrintf(2, 2, "NOUNITDISPLAYID|%d|%s", displayID, name);
this->m_displayInfo = g_creatureDisplayInfoDB.GetRecordByIndex(0);
if (!this->m_displayInfo) {
STORM_APP_FATAL("Error, NO creature display records found");
}
}
// Display info extra
this->m_displayInfoExtra = g_creatureDisplayInfoExtraDB.GetRecord(this->m_displayInfo->m_extendedDisplayInfoID);
// Model data
this->m_modelData = g_creatureModelDataDB.GetRecord(this->m_displayInfo->m_modelID);
// Sound data
this->m_soundData = g_creatureSoundDataDB.GetRecord(this->m_displayInfo->m_soundID);
if (!this->m_soundData) {
this->m_soundData = g_creatureSoundDataDB.GetRecord(this->m_modelData->m_soundID);
}
// Blood levels
this->m_bloodRec = g_unitBloodLevelsDB.GetRecord(this->m_displayInfo->m_bloodID);
if (!this->m_bloodRec) {
this->m_bloodRec = g_unitBloodLevelsDB.GetRecord(this->m_modelData->m_bloodID);
if (!this->m_bloodRec) {
this->m_bloodRec = g_unitBloodLevelsDB.GetRecordByIndex(0);
}
}
// Creature stats
if (this->GetType() == HIER_TYPE_UNIT) {
// TODO load creature stats
}
// Flags
// TODO set flags
}
void CGUnit_C::SetStorage(uint32_t* storage, uint32_t* saved) { void CGUnit_C::SetStorage(uint32_t* storage, uint32_t* saved) {
this->CGObject_C::SetStorage(storage, saved); this->CGObject_C::SetStorage(storage, saved);

View File

@ -1,21 +1,63 @@
#ifndef OBJECT_CLIENT_CG_UNIT_C_HPP #ifndef OBJECT_CLIENT_CG_UNIT_C_HPP
#define 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/CGObject_C.hpp"
#include "object/client/CGUnit.hpp" #include "object/client/CGUnit.hpp"
#include "object/Types.hpp" #include "object/Types.hpp"
#include "util/GUID.hpp"
class ChrClassesRec; class ChrClassesRec;
class ChrRacesRec; class ChrRacesRec;
class CreatureDisplayInfoRec;
class CreatureDisplayInfoExtraRec;
class CreatureModelDataRec;
class CreatureSoundDataRec;
class UnitBloodLevelsRec;
class CGUnit_C : public CGObject_C, public CGUnit { class CGUnit_C : public CGObject_C, public CGUnit {
public: public:
// Public static variables
static WOWGUID s_activeMover;
// Public static functions // Public static functions
static const char* GetDisplayClassNameFromRecord(const ChrClassesRec* classRec, UNIT_SEX sex, UNIT_SEX* displaySex); 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); static const char* GetDisplayRaceNameFromRecord(const ChrRacesRec* raceRec, UNIT_SEX sex, UNIT_SEX* displaySex);
// Virtual public member functions
virtual ~CGUnit_C();
// TODO
virtual int32_t GetModelFileName(const char*& name) const;
// TODO
virtual int32_t CanHighlight();
virtual int32_t CanBeTargetted();
// TODO
// Public member functions // Public member functions
CGUnit_C(uint32_t time, CClientObjCreate& objCreate);
int32_t GetDisplayID() const;
CreatureModelDataRec* GetModelData() const;
void PostInit(uint32_t time, const CClientObjCreate& init, bool a4);
void PostMovementUpdate(const CClientMoveUpdate& move, int32_t activeMover);
void SetStorage(uint32_t* storage, uint32_t* saved); void SetStorage(uint32_t* storage, uint32_t* saved);
protected:
// Protected member functions
int32_t GetLocalDisplayID() const;
void RefreshDataPointers();
private:
// Private member variables
// TODO
CreatureDisplayInfoRec* m_displayInfo;
CreatureDisplayInfoExtraRec* m_displayInfoExtra;
CreatureModelDataRec* m_modelData;
CreatureSoundDataRec* m_soundData;
// TODO
UnitBloodLevelsRec* m_bloodRec;
// TODO
int32_t m_localDisplayID = 0;
// TODO
}; };
#endif #endif

View File

@ -1,6 +1,9 @@
#ifndef OBJECT_CLIENT_CLNT_OBJ_MGR_HPP #ifndef OBJECT_CLIENT_CLNT_OBJ_MGR_HPP
#define 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> #include <cstdint>
class ClientConnection; class ClientConnection;
@ -8,9 +11,19 @@ class ClientConnection;
class ClntObjMgr { class ClntObjMgr {
public: public:
// Member variables // 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;
PLAYER_TYPE m_type;
uint32_t m_mapID = 0; uint32_t m_mapID = 0;
ClientConnection* m_net = nullptr; ClientConnection* m_net = nullptr;
// Member functions
ClntObjMgr(PLAYER_TYPE type) : m_type(type) {};
}; };
#endif #endif

View File

@ -1,9 +1,492 @@
#include "object/client/MessageHandlers.hpp" #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/Unimplemented.hpp"
#include "util/Zlib.hpp" #include "util/Zlib.hpp"
#include <common/DataStore.hpp> #include <common/DataStore.hpp>
#include <storm/Error.hpp> #include <storm/Error.hpp>
#include <storm/Memory.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,
};
void SkipSetOfObjects(CDataStore* msg) {
uint32_t count;
msg->Get(count);
for (int32_t i = 0; i < count; i++) {
SmartGUID guid;
*msg >> guid;
}
}
int32_t PostInitObject(CDataStore* msg, uint32_t time, bool a3) {
SmartGUID guid;
*msg >> guid;
uint8_t _typeID;
msg->Get(_typeID);
auto typeID = static_cast<OBJECT_TYPE_ID>(_typeID);
if (guid == 0) {
return 0;
}
auto object = FindActiveObject(guid);
if (!object) {
return 0;
}
CClientObjCreate init;
if (!init.Get(msg)) {
return 0;
}
if (object->m_inReenable && object->GetType() & TYPE_UNIT) {
// TODO
}
if (object->m_postInited) {
return CallMirrorHandlers(msg, true, guid);
}
switch (typeID) {
case ID_OBJECT: {
object->PostInit(time, init, a3);
break;
}
case ID_ITEM:
case ID_CONTAINER: {
static_cast<CGItem_C*>(object)->PostInit(time, init, a3);
break;
}
case ID_UNIT: {
static_cast<CGUnit_C*>(object)->PostInit(time, init, a3);
break;
}
case ID_PLAYER: {
static_cast<CGPlayer_C*>(object)->PostInit(time, init, a3);
break;
}
case ID_GAMEOBJECT: {
static_cast<CGGameObject_C*>(object)->PostInit(time, init, a3);
break;
}
case ID_DYNAMICOBJECT: {
static_cast<CGDynamicObject_C*>(object)->PostInit(time, init, a3);
break;
}
case ID_CORPSE: {
static_cast<CGCorpse_C*>(object)->PostInit(time, init, a3);
break;
}
default: {
STORM_APP_FATAL("PostInitObject: unknown object type %d", typeID);
}
}
return SkipPartialObjectUpdate(msg);
}
void PostMovementUpdate(CDataStore* msg) {
SmartGUID guid;
*msg >> guid;
CClientMoveUpdate move;
*msg >> move;
if (guid == CGUnit_C::s_activeMover) {
return;
}
int32_t reenable;
auto unit = static_cast<CGUnit_C*>(GetUpdateObject(guid, &reenable));
if (!unit) {
return;
}
unit->PostMovementUpdate(move, unit->GetGUID() == CGUnit_C::s_activeMover);
if (reenable) {
unit->Reenable();
}
}
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->GetGUID(), 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->GetGUID(), 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) {
// Handle post updates
for (int32_t i = 0; i < updateCount; i++) {
uint8_t updateType;
msg->Get(updateType);
switch (updateType) {
case UPDATE_PARTIAL: {
if (!CallMirrorHandlers(msg, false, 0)) {
return 0;
}
break;
}
case UPDATE_MOVEMENT: {
PostMovementUpdate(msg);
break;
}
case UPDATE_FULL:
case UPDATE_3: {
if (!PostInitObject(msg, time, updateType == UPDATE_3)) {
return 0;
}
break;
}
case UPDATE_IN_RANGE:
case UPDATE_OUT_OF_RANGE: {
SkipSetOfObjects(msg);
break;
}
default: {
break;
}
}
}
// Finish reenabling objects
while (auto reenabledObject = ClntObjMgrGetCurrent()->m_reenabledObjects.Head()) {
ClntObjMgrGetCurrent()->m_visibleObjects.LinkToTail(reenabledObject);
reenabledObject->PostReenable();
}
return 1;
}
int32_t ObjectCompressedUpdateHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) { int32_t ObjectCompressedUpdateHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) {
uint32_t origSize; uint32_t origSize;
@ -60,9 +543,59 @@ int32_t ObjectCompressedUpdateHandler(void* param, NETMESSAGE msgId, uint32_t ti
} }
int32_t ObjectUpdateHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) { int32_t ObjectUpdateHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) {
WHOA_UNIMPLEMENTED(0); uint32_t updateCount;
msg->Get(updateCount);
// If first update type is out of range, handle it before continuing with normal processing
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);
}
// Process all updates in two passes (creates, updates and disables objects as appropriate)
int32_t result = 0;
if (ObjectUpdateFirstPass(msg, time, updateIdx, updateCount)) {
msg->Seek(startPos);
result = ObjectUpdateSecondPass(msg, time, updateCount);
}
// Garbage collect objects disabled more than 2 minutes ago (catch all)
for (int32_t typeID = ID_OBJECT; typeID < NUM_CLIENT_OBJECT_TYPES; typeID++) {
GarbageCollect(static_cast<OBJECT_TYPE_ID>(typeID), 120000);
}
return result;
} }
int32_t OnObjectDestroy(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) { 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;
} }

View File

@ -0,0 +1,248 @@
#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/client/Util.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->GetType()) {
// 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 CallMirrorHandlers(CDataStore* msg, bool a2, WOWGUID guid) {
if (!a2) {
SmartGUID _guid;
*msg >> _guid;
guid = _guid;
}
auto object = FindActiveObject(guid);
if (!object) {
return SkipPartialObjectUpdate(msg);
}
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->GetType(), guid);
for (int32_t block = 0; block < numBlocks; block++) {
if (block >= s_objMirrorBlocks[typeID]) {
blockOffset = s_objMirrorBlocks[typeID];
typeID = IncTypeID(object, typeID);
}
// TODO
if (IsMaskBitSet(changeMasks, block)) {
uint32_t blockValue = 0;
msg->Get(blockValue);
}
// TODO
}
return 1;
}
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->GetType(), 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;
}
int32_t SkipPartialObjectUpdate(CDataStore* msg) {
uint8_t changeMaskCount;
uint32_t changeMasks[MAX_CHANGE_MASKS];
if (!ExtractDirtyMasks(msg, &changeMaskCount, changeMasks)) {
return 0;
}
for (int32_t block = 0; block < changeMaskCount * 32; block++) {
if (IsMaskBitSet(changeMasks, block)) {
uint32_t blockValue;
msg->Get(blockValue);
}
}
return 1;
}

View File

@ -0,0 +1,16 @@
#ifndef OBJECT_CLIENT_MIRROR_HPP
#define OBJECT_CLIENT_MIRROR_HPP
#include "util/GUID.hpp"
#include <cstdint>
class CDataStore;
class CGObject_C;
int32_t CallMirrorHandlers(CDataStore* msg, bool a2, WOWGUID guid);
int32_t FillInPartialObjectData(CGObject_C* object, WOWGUID guid, CDataStore* msg, bool forFullUpdate, bool zeroZeroBits);
int32_t SkipPartialObjectUpdate(CDataStore* msg);
#endif

View File

@ -11,6 +11,7 @@
#include "object/client/CGPlayer_C.hpp" #include "object/client/CGPlayer_C.hpp"
#include "object/client/CGUnit_C.hpp" #include "object/client/CGUnit_C.hpp"
#include "object/client/MessageHandlers.hpp" #include "object/client/MessageHandlers.hpp"
#include "object/client/Util.hpp"
#include "util/Unimplemented.hpp" #include "util/Unimplemented.hpp"
#include <common/ObjectAlloc.hpp> #include <common/ObjectAlloc.hpp>
#include <storm/Memory.hpp> #include <storm/Memory.hpp>
@ -66,15 +67,15 @@ void MirrorInitialize() {
// TODO // TODO
} }
void* ClntObjMgrAllocObject(OBJECT_TYPE_ID typeID, uint64_t guid) { CGObject_C* ClntObjMgrAllocObject(OBJECT_TYPE_ID typeID, WOWGUID guid) {
auto playerGUID = ClntObjMgrGetActivePlayer(); auto playerGUID = ClntObjMgrGetActivePlayer();
// Heap allocate player object for current player // Heap allocate player object for current player
if (guid == playerGUID) { if (guid == playerGUID) {
return STORM_ALLOC(sizeof(CGPlayer_C) + CGPlayer::GetDataSize() + CGPlayer::GetDataSizeSaved()); return static_cast<CGObject_C*>(STORM_ALLOC(sizeof(CGPlayer_C) + CGPlayer::GetDataSize() + CGPlayer::GetDataSizeSaved()));
} }
// TODO GarbageCollect(typeID, 10000); GarbageCollect(typeID, 10000);
uint32_t memHandle; uint32_t memHandle;
void* mem; void* mem;
@ -84,12 +85,43 @@ void* ClntObjMgrAllocObject(OBJECT_TYPE_ID typeID, uint64_t guid) {
} }
// TODO pointer should be fetched via ObjectPtr // 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() { void ClntObjMgrFreeObject(CGObject_C* object) {
auto playerGUID = ClntObjMgrGetActivePlayer();
auto isActivePlayer = object->GetGUID() == playerGUID;
switch (object->GetType()) {
case TYPE_OBJECT:
case HIER_TYPE_ITEM:
case HIER_TYPE_CONTAINER:
case HIER_TYPE_UNIT:
case HIER_TYPE_PLAYER:
case HIER_TYPE_GAMEOBJECT:
case HIER_TYPE_DYNAMICOBJECT:
case HIER_TYPE_CORPSE: {
object->~CGObject_C();
break;
}
default: {
break;
}
}
if (isActivePlayer) {
STORM_FREE(object);
} else {
ObjectFree(s_objHeapId[object->GetTypeID()], object->m_memHandle);
}
}
WOWGUID ClntObjMgrGetActivePlayer() {
if (!s_curMgr) { if (!s_curMgr) {
return 0; return 0;
} }
@ -109,6 +141,10 @@ uint32_t ClntObjMgrGetMapID() {
return s_curMgr->m_mapID; return s_curMgr->m_mapID;
} }
PLAYER_TYPE ClntObjMgrGetPlayerType() {
return s_curMgr->m_type;
}
void ClntObjMgrInitializeShared() { void ClntObjMgrInitializeShared() {
if (!s_heapsAllocated) { if (!s_heapsAllocated) {
for (int32_t i = ID_ITEM; i < NUM_CLIENT_OBJECT_TYPES; i++) { for (int32_t i = ID_ITEM; i < NUM_CLIENT_OBJECT_TYPES; i++) {
@ -126,7 +162,7 @@ void ClntObjMgrInitializeShared() {
void ClntObjMgrInitializeStd(uint32_t mapID) { void ClntObjMgrInitializeStd(uint32_t mapID) {
// TODO last instance time // TODO last instance time
auto mgr = STORM_NEW(ClntObjMgr); auto mgr = STORM_NEW(ClntObjMgr)(PLAYER_NORMAL);
g_clientConnection->SetObjMgr(mgr); g_clientConnection->SetObjMgr(mgr);
mgr->m_net = g_clientConnection; mgr->m_net = g_clientConnection;
@ -138,6 +174,29 @@ void ClntObjMgrInitializeStd(uint32_t mapID) {
mgr->m_mapID = mapID; mgr->m_mapID = mapID;
} }
void ClntObjMgrLinkInNewObject(CGObject_C* object) {
CHashKeyGUID key(object->GetGUID());
s_curMgr->m_objects.Insert(object, object->GetGUID(), 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->GetType() & type)) {
return nullptr;
}
return object;
}
void ClntObjMgrPop() { void ClntObjMgrPop() {
if (!s_savMgr) { if (!s_savMgr) {
return; return;
@ -156,7 +215,7 @@ void ClntObjMgrPush(ClntObjMgr* mgr) {
s_curMgr = mgr; s_curMgr = mgr;
} }
void ClntObjMgrSetActivePlayer(uint64_t guid) { void ClntObjMgrSetActivePlayer(WOWGUID guid) {
s_curMgr->m_activePlayer = guid; s_curMgr->m_activePlayer = guid;
} }

View File

@ -6,23 +6,31 @@
#include "object/Types.hpp" #include "object/Types.hpp"
#include <cstdint> #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();
void ClntObjMgrFreeObject(CGObject_C* object);
ClntObjMgr* ClntObjMgrGetCurrent(); ClntObjMgr* ClntObjMgrGetCurrent();
uint32_t ClntObjMgrGetMapID(); uint32_t ClntObjMgrGetMapID();
PLAYER_TYPE ClntObjMgrGetPlayerType();
void ClntObjMgrInitializeShared(); void ClntObjMgrInitializeShared();
void ClntObjMgrInitializeStd(uint32_t mapID); 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 ClntObjMgrPop();
void ClntObjMgrPush(ClntObjMgr* mgr); void ClntObjMgrPush(ClntObjMgr* mgr);
void ClntObjMgrSetActivePlayer(uint64_t guid); void ClntObjMgrSetActivePlayer(WOWGUID guid);
void ClntObjMgrSetHandlers(); void ClntObjMgrSetHandlers();

166
src/object/client/Util.cpp Normal file
View File

@ -0,0 +1,166 @@
#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"
#include <common/Time.hpp>
CGObject_C* FindActiveObject(WOWGUID guid) {
return ClntObjMgrGetCurrent()->m_objects.Ptr(guid, CHashKeyGUID(guid));
}
/**
* Given an object type and collection age, free the object at the head of that type's FIFO queue
* if it was disabled longer ago than the collection age. Only frees at most one object per call.
*/
void GarbageCollect(OBJECT_TYPE_ID typeID, uint32_t collectAgeMs) {
auto object = ClntObjMgrGetCurrent()->m_lazyCleanupFifo[typeID - 1].Head();
if (!object) {
return;
}
uint32_t disableAgeMs = OsGetAsyncTimeMsPrecise() - object->m_disableTimeMs;
if (disableAgeMs < collectAgeMs) {
return;
}
ClntObjMgrGetCurrent()->m_lazyCleanupObjects.Unlink(object);
object->m_link.Unlink();
ClntObjMgrFreeObject(object);
}
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->GetTypeID() - 1].LinkToTail(object);
}
void InitObject(CGObject_C* object, uint32_t time, CClientObjCreate& objCreate) {
switch (object->GetTypeID()) {
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;
}
}
}

View File

@ -0,0 +1,23 @@
#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);
void GarbageCollect(OBJECT_TYPE_ID typeID, uint32_t collectAgeMs);
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

View File

@ -1,63 +0,0 @@
#include "object/client/Utils.hpp"
/**
* 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;
}
}

View File

@ -1,9 +0,0 @@
#ifndef OBJECT_CLIENT_UTILS_HPP
#define OBJECT_CLIENT_UTILS_HPP
#include "object/client/CGObject_C.hpp"
#include "object/Types.hpp"
OBJECT_TYPE_ID IncTypeID(CGObject_C* object, OBJECT_TYPE_ID curTypeID);
#endif

View 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;
}

View 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

View 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;
}

View 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

View File

@ -332,6 +332,10 @@ void CLayoutFrame::GetFirstPointY(const FRAMEPOINT* const pointarray, int32_t el
} }
} }
float CLayoutFrame::GetHeight() {
return this->m_height;
}
CLayoutFrame* CLayoutFrame::GetLayoutFrameByName(const char* name) { CLayoutFrame* CLayoutFrame::GetLayoutFrameByName(const char* name) {
return nullptr; return nullptr;
} }
@ -353,8 +357,20 @@ int32_t CLayoutFrame::GetRect(CRect* rect) {
return 1; return 1;
} }
float CLayoutFrame::GetHeight() { void CLayoutFrame::GetSize(float& width, float& height, int32_t a4) {
return this->m_height; width = this->GetWidth();
height = this->GetHeight();
if (!a4 && (width == 0.0f || height == 0.0f)) {
if (this->m_flags & FLAG_RESIZE_PENDING) {
this->Resize(1);
}
if (this->m_flags & 0x1) {
width = (this->m_rect.maxX - this->m_rect.minX) / this->m_layoutScale;
height = (this->m_rect.maxY - this->m_rect.minY) / this->m_layoutScale;
}
}
} }
float CLayoutFrame::GetWidth() { float CLayoutFrame::GetWidth() {
@ -846,6 +862,13 @@ void CLayoutFrame::SetProtectFlag(uint32_t flag) {
this->m_flags &= ~0x800; this->m_flags &= ~0x800;
} }
void CLayoutFrame::SetSize(float width, float height) {
this->m_flags &= ~0x8;
this->m_width = width;
this->m_height = height;
this->Resize(0);
}
void CLayoutFrame::SetWidth(float width) { void CLayoutFrame::SetWidth(float width) {
this->m_flags &= ~0x8; this->m_flags &= ~0x8;
this->m_width = width; this->m_width = width;

View File

@ -49,8 +49,10 @@ class CLayoutFrame {
virtual bool SetLayoutScale(float scale, bool force); virtual bool SetLayoutScale(float scale, bool force);
virtual void SetWidth(float width); virtual void SetWidth(float width);
virtual void SetHeight(float height); virtual void SetHeight(float height);
virtual void SetSize(float width, float height);
virtual float GetWidth(); virtual float GetWidth();
virtual float GetHeight(); virtual float GetHeight();
virtual void GetSize(float& width, float& height, int32_t a4);
virtual void GetClampRectInsets(float& a1, float& a2, float& a3, float& a4); virtual void GetClampRectInsets(float& a1, float& a2, float& a3, float& a4);
virtual int32_t IsAttachmentOrigin(); virtual int32_t IsAttachmentOrigin();
virtual CLayoutFrame* GetLayoutFrameByName(const char* name); virtual CLayoutFrame* GetLayoutFrameByName(const char* name);

View File

@ -219,7 +219,28 @@ int32_t CScriptRegion_SetHeight(lua_State* L) {
} }
int32_t CScriptRegion_SetSize(lua_State* L) { int32_t CScriptRegion_SetSize(lua_State* L) {
WHOA_UNIMPLEMENTED(0); auto type = CScriptRegion::GetObjectType();
auto region = static_cast<CScriptRegion*>(FrameScript_GetObjectThis(L, type));
if (!region->ProtectedFunctionsAllowed()) {
// TODO disallowed logic
return 0;
}
if (!lua_isnumber(L, 2) || !lua_isnumber(L, 3)) {
luaL_error(L, "Usage: %s:SetSize(width, height)", region->GetDisplayName());
return 0;
}
auto ndcWidth = static_cast<float>(lua_tonumber(L, 2)) / (CoordinateGetAspectCompensation() * 1024.0f);
auto ddcWidth = NDCToDDCWidth(ndcWidth);
auto ndcHeight = static_cast<float>(lua_tonumber(L, 3)) / (CoordinateGetAspectCompensation() * 1024.0f);
auto ddcHeight = NDCToDDCWidth(ndcHeight);
region->SetSize(ddcWidth, ddcHeight);
return 0;
} }
int32_t CScriptRegion_GetSize(lua_State* L) { int32_t CScriptRegion_GetSize(lua_State* L) {

View File

@ -11,8 +11,6 @@
#include <storm/String.hpp> #include <storm/String.hpp>
#include <tempest/Vector.hpp> #include <tempest/Vector.hpp>
const char* g_scriptEvents[722];
int32_t g_glueFrameScriptGenders[] = { int32_t g_glueFrameScriptGenders[] = {
2, // UNIT_SEX_MALE 2, // UNIT_SEX_MALE
3, // UNIT_SEX_FEMALE 3, // UNIT_SEX_FEMALE
@ -154,9 +152,11 @@ void FrameScript_CreateEvents(const char* names[], uint32_t count) {
FrameScript::s_scriptEvents.SetCount(count); FrameScript::s_scriptEvents.SetCount(count);
for (int32_t i = 0; i < count; i++) { for (int32_t i = 0; i < count; i++) {
if (names[i]) {
auto event = FrameScript::s_scriptEventsHash.New(names[i], 0, 0); auto event = FrameScript::s_scriptEventsHash.New(names[i], 0, 0);
FrameScript::s_scriptEvents[i] = event; FrameScript::s_scriptEvents[i] = event;
} }
}
} }
void FrameScript_Destroy() { void FrameScript_Destroy() {
@ -1047,6 +1047,15 @@ const char* FrameScript_Sprintf(lua_State* L, int32_t idx, char buffer[], uint32
return buffer; return buffer;
} }
void FrameScript_UnregisterFunction(const char* name) {
auto L = FrameScript::s_context;
lua_pushnil(L);
lua_pushstring(L, name);
lua_insert(L, -2);
lua_rawset(L, LUA_GLOBALSINDEX);
}
void FrameScript_UnregisterScriptEvent(FrameScript_Object* object, FrameScript_EventObject* event) { void FrameScript_UnregisterScriptEvent(FrameScript_Object* object, FrameScript_EventObject* event) {
if (event->pendingSignalCount) { if (event->pendingSignalCount) {
auto node = event->unregisterListeners.Head(); auto node = event->unregisterListeners.Head();
@ -1074,656 +1083,3 @@ void FrameScript_UnregisterScriptEvent(FrameScript_Object* object, FrameScript_E
} }
} }
} }
void ScriptEventsInitialize() {
g_scriptEvents[0] = "UNIT_PET";
g_scriptEvents[2] = "UNIT_PET";
g_scriptEvents[12] = "UNIT_TARGET";
g_scriptEvents[17] = "UNIT_DISPLAYPOWER";
g_scriptEvents[18] = "UNIT_HEALTH";
g_scriptEvents[19] = "UNIT_MANA";
g_scriptEvents[20] = "UNIT_RAGE";
g_scriptEvents[21] = "UNIT_FOCUS";
g_scriptEvents[22] = "UNIT_ENERGY";
g_scriptEvents[23] = "UNIT_HAPPINESS";
g_scriptEvents[25] = "UNIT_RUNIC_POWER";
g_scriptEvents[26] = "UNIT_MAXHEALTH";
g_scriptEvents[27] = "UNIT_MAXMANA";
g_scriptEvents[28] = "UNIT_MAXRAGE";
g_scriptEvents[29] = "UNIT_MAXFOCUS";
g_scriptEvents[30] = "UNIT_MAXENERGY";
g_scriptEvents[31] = "UNIT_MAXHAPPINESS";
g_scriptEvents[33] = "UNIT_MAXRUNIC_POWER";
g_scriptEvents[48] = "UNIT_LEVEL";
g_scriptEvents[49] = "UNIT_FACTION";
g_scriptEvents[53] = "UNIT_FLAGS";
g_scriptEvents[54] = "UNIT_FLAGS";
g_scriptEvents[56] = "UNIT_ATTACK_SPEED";
g_scriptEvents[57] = "UNIT_ATTACK_SPEED";
g_scriptEvents[58] = "UNIT_RANGEDDAMAGE";
g_scriptEvents[64] = "UNIT_DAMAGE";
g_scriptEvents[65] = "UNIT_DAMAGE";
g_scriptEvents[66] = "UNIT_DAMAGE";
g_scriptEvents[67] = "UNIT_DAMAGE";
g_scriptEvents[71] = "UNIT_PET_EXPERIENCE";
g_scriptEvents[72] = "UNIT_PET_EXPERIENCE";
g_scriptEvents[73] = "UNIT_DYNAMIC_FLAGS";
g_scriptEvents[78] = "UNIT_STATS";
g_scriptEvents[79] = "UNIT_STATS";
g_scriptEvents[80] = "UNIT_STATS";
g_scriptEvents[81] = "UNIT_STATS";
g_scriptEvents[82] = "UNIT_STATS";
g_scriptEvents[93] = "UNIT_RESISTANCES";
g_scriptEvents[94] = "UNIT_RESISTANCES";
g_scriptEvents[95] = "UNIT_RESISTANCES";
g_scriptEvents[96] = "UNIT_RESISTANCES";
g_scriptEvents[97] = "UNIT_RESISTANCES";
g_scriptEvents[98] = "UNIT_RESISTANCES";
g_scriptEvents[99] = "UNIT_RESISTANCES";
g_scriptEvents[100] = "UNIT_RESISTANCES";
g_scriptEvents[101] = "UNIT_RESISTANCES";
g_scriptEvents[102] = "UNIT_RESISTANCES";
g_scriptEvents[103] = "UNIT_RESISTANCES";
g_scriptEvents[104] = "UNIT_RESISTANCES";
g_scriptEvents[105] = "UNIT_RESISTANCES";
g_scriptEvents[106] = "UNIT_RESISTANCES";
g_scriptEvents[107] = "UNIT_RESISTANCES";
g_scriptEvents[108] = "UNIT_RESISTANCES";
g_scriptEvents[109] = "UNIT_RESISTANCES";
g_scriptEvents[110] = "UNIT_RESISTANCES";
g_scriptEvents[111] = "UNIT_RESISTANCES";
g_scriptEvents[112] = "UNIT_RESISTANCES";
g_scriptEvents[113] = "UNIT_RESISTANCES";
g_scriptEvents[117] = "UNIT_ATTACK_POWER";
g_scriptEvents[118] = "UNIT_ATTACK_POWER";
g_scriptEvents[119] = "UNIT_ATTACK_POWER";
g_scriptEvents[120] = "UNIT_RANGED_ATTACK_POWER";
g_scriptEvents[121] = "UNIT_RANGED_ATTACK_POWER";
g_scriptEvents[122] = "UNIT_RANGED_ATTACK_POWER";
g_scriptEvents[123] = "UNIT_RANGEDDAMAGE";
g_scriptEvents[124] = "UNIT_RANGEDDAMAGE";
g_scriptEvents[125] = "UNIT_MANA";
g_scriptEvents[132] = "UNIT_MANA";
g_scriptEvents[139] = "UNIT_STATS";
g_scriptEvents[142] = "UNIT_AURA";
g_scriptEvents[143] = "UNIT_COMBAT";
g_scriptEvents[144] = "UNIT_NAME_UPDATE";
g_scriptEvents[145] = "UNIT_PORTRAIT_UPDATE";
g_scriptEvents[146] = "UNIT_MODEL_CHANGED";
g_scriptEvents[147] = "UNIT_INVENTORY_CHANGED";
g_scriptEvents[148] = "UNIT_CLASSIFICATION_CHANGED";
g_scriptEvents[149] = "UNIT_COMBO_POINTS";
g_scriptEvents[150] = "ITEM_LOCK_CHANGED";
g_scriptEvents[151] = "PLAYER_XP_UPDATE";
g_scriptEvents[152] = "PLAYER_REGEN_DISABLED";
g_scriptEvents[153] = "PLAYER_REGEN_ENABLED";
g_scriptEvents[154] = "PLAYER_AURAS_CHANGED";
g_scriptEvents[155] = "PLAYER_ENTER_COMBAT";
g_scriptEvents[156] = "PLAYER_LEAVE_COMBAT";
g_scriptEvents[157] = "PLAYER_TARGET_CHANGED";
g_scriptEvents[158] = "PLAYER_FOCUS_CHANGED";
g_scriptEvents[159] = "PLAYER_CONTROL_LOST";
g_scriptEvents[160] = "PLAYER_CONTROL_GAINED";
g_scriptEvents[161] = "PLAYER_FARSIGHT_FOCUS_CHANGED";
g_scriptEvents[162] = "PLAYER_LEVEL_UP";
g_scriptEvents[163] = "PLAYER_MONEY";
g_scriptEvents[164] = "PLAYER_DAMAGE_DONE_MODS";
g_scriptEvents[165] = "PLAYER_TOTEM_UPDATE";
g_scriptEvents[166] = "ZONE_CHANGED";
g_scriptEvents[167] = "ZONE_CHANGED_INDOORS";
g_scriptEvents[168] = "ZONE_CHANGED_NEW_AREA";
g_scriptEvents[169] = "MINIMAP_UPDATE_ZOOM";
g_scriptEvents[170] = "MINIMAP_UPDATE_TRACKING";
g_scriptEvents[171] = "SCREENSHOT_SUCCEEDED";
g_scriptEvents[172] = "SCREENSHOT_FAILED";
g_scriptEvents[173] = "ACTIONBAR_SHOWGRID";
g_scriptEvents[174] = "ACTIONBAR_HIDEGRID";
g_scriptEvents[175] = "ACTIONBAR_PAGE_CHANGED";
g_scriptEvents[176] = "ACTIONBAR_SLOT_CHANGED";
g_scriptEvents[177] = "ACTIONBAR_UPDATE_STATE";
g_scriptEvents[178] = "ACTIONBAR_UPDATE_USABLE";
g_scriptEvents[179] = "ACTIONBAR_UPDATE_COOLDOWN";
g_scriptEvents[180] = "UPDATE_BONUS_ACTIONBAR";
g_scriptEvents[181] = "PARTY_MEMBERS_CHANGED";
g_scriptEvents[182] = "PARTY_LEADER_CHANGED";
g_scriptEvents[183] = "PARTY_MEMBER_ENABLE";
g_scriptEvents[184] = "PARTY_MEMBER_DISABLE";
g_scriptEvents[185] = "PARTY_LOOT_METHOD_CHANGED";
g_scriptEvents[186] = "SYSMSG";
g_scriptEvents[187] = "UI_ERROR_MESSAGE";
g_scriptEvents[188] = "UI_INFO_MESSAGE";
g_scriptEvents[189] = "UPDATE_CHAT_COLOR";
g_scriptEvents[190] = "CHAT_MSG_ADDON";
g_scriptEvents[191] = "CHAT_MSG_SYSTEM";
g_scriptEvents[192] = "CHAT_MSG_SAY";
g_scriptEvents[193] = "CHAT_MSG_PARTY";
g_scriptEvents[194] = "CHAT_MSG_RAID";
g_scriptEvents[195] = "CHAT_MSG_GUILD";
g_scriptEvents[196] = "CHAT_MSG_OFFICER";
g_scriptEvents[197] = "CHAT_MSG_YELL";
g_scriptEvents[198] = "CHAT_MSG_WHISPER";
g_scriptEvents[199] = "CHAT_MSG_WHISPER_INFORM";
g_scriptEvents[200] = "CHAT_MSG_EMOTE";
g_scriptEvents[201] = "CHAT_MSG_TEXT_EMOTE";
g_scriptEvents[202] = "CHAT_MSG_MONSTER_SAY";
g_scriptEvents[203] = "CHAT_MSG_MONSTER_PARTY";
g_scriptEvents[204] = "CHAT_MSG_MONSTER_YELL";
g_scriptEvents[205] = "CHAT_MSG_MONSTER_WHISPER";
g_scriptEvents[206] = "CHAT_MSG_MONSTER_EMOTE";
g_scriptEvents[207] = "CHAT_MSG_CHANNEL";
g_scriptEvents[208] = "CHAT_MSG_CHANNEL_JOIN";
g_scriptEvents[209] = "CHAT_MSG_CHANNEL_LEAVE";
g_scriptEvents[210] = "CHAT_MSG_CHANNEL_LIST";
g_scriptEvents[211] = "CHAT_MSG_CHANNEL_NOTICE";
g_scriptEvents[212] = "CHAT_MSG_CHANNEL_NOTICE_USER";
g_scriptEvents[213] = "CHAT_MSG_AFK";
g_scriptEvents[214] = "CHAT_MSG_DND";
g_scriptEvents[215] = "CHAT_MSG_IGNORED";
g_scriptEvents[216] = "CHAT_MSG_SKILL";
g_scriptEvents[217] = "CHAT_MSG_LOOT";
g_scriptEvents[218] = "CHAT_MSG_MONEY";
g_scriptEvents[219] = "CHAT_MSG_OPENING";
g_scriptEvents[220] = "CHAT_MSG_TRADESKILLS";
g_scriptEvents[221] = "CHAT_MSG_PET_INFO";
g_scriptEvents[222] = "CHAT_MSG_COMBAT_MISC_INFO";
g_scriptEvents[223] = "CHAT_MSG_COMBAT_XP_GAIN";
g_scriptEvents[224] = "CHAT_MSG_COMBAT_HONOR_GAIN";
g_scriptEvents[225] = "CHAT_MSG_COMBAT_FACTION_CHANGE";
g_scriptEvents[226] = "CHAT_MSG_BG_SYSTEM_NEUTRAL";
g_scriptEvents[227] = "CHAT_MSG_BG_SYSTEM_ALLIANCE";
g_scriptEvents[228] = "CHAT_MSG_BG_SYSTEM_HORDE";
g_scriptEvents[229] = "CHAT_MSG_RAID_LEADER";
g_scriptEvents[230] = "CHAT_MSG_RAID_WARNING";
g_scriptEvents[231] = "CHAT_MSG_RAID_BOSS_WHISPER";
g_scriptEvents[232] = "CHAT_MSG_RAID_BOSS_EMOTE";
g_scriptEvents[233] = "CHAT_MSG_FILTERED";
g_scriptEvents[234] = "CHAT_MSG_BATTLEGROUND";
g_scriptEvents[235] = "CHAT_MSG_BATTLEGROUND_LEADER";
g_scriptEvents[236] = "CHAT_MSG_RESTRICTED";
// TODO
// g_scriptEvents[237] = &byte_9E14FF;
g_scriptEvents[238] = "CHAT_MSG_ACHIEVEMENT";
g_scriptEvents[239] = "CHAT_MSG_GUILD_ACHIEVEMENT";
g_scriptEvents[240] = "LANGUAGE_LIST_CHANGED";
g_scriptEvents[241] = "TIME_PLAYED_MSG";
g_scriptEvents[242] = "SPELLS_CHANGED";
g_scriptEvents[243] = "CURRENT_SPELL_CAST_CHANGED";
g_scriptEvents[244] = "SPELL_UPDATE_COOLDOWN";
g_scriptEvents[245] = "SPELL_UPDATE_USABLE";
g_scriptEvents[246] = "CHARACTER_POINTS_CHANGED";
g_scriptEvents[247] = "SKILL_LINES_CHANGED";
g_scriptEvents[248] = "ITEM_PUSH";
g_scriptEvents[249] = "LOOT_OPENED";
g_scriptEvents[250] = "LOOT_SLOT_CLEARED";
g_scriptEvents[251] = "LOOT_SLOT_CHANGED";
g_scriptEvents[252] = "LOOT_CLOSED";
g_scriptEvents[253] = "PLAYER_LOGIN";
g_scriptEvents[254] = "PLAYER_LOGOUT";
g_scriptEvents[255] = "PLAYER_ENTERING_WORLD";
g_scriptEvents[256] = "PLAYER_LEAVING_WORLD";
g_scriptEvents[257] = "PLAYER_ALIVE";
g_scriptEvents[258] = "PLAYER_DEAD";
g_scriptEvents[259] = "PLAYER_CAMPING";
g_scriptEvents[260] = "PLAYER_QUITING";
g_scriptEvents[261] = "LOGOUT_CANCEL";
g_scriptEvents[262] = "RESURRECT_REQUEST";
g_scriptEvents[263] = "PARTY_INVITE_REQUEST";
g_scriptEvents[264] = "PARTY_INVITE_CANCEL";
g_scriptEvents[265] = "GUILD_INVITE_REQUEST";
g_scriptEvents[266] = "GUILD_INVITE_CANCEL";
g_scriptEvents[267] = "GUILD_MOTD";
g_scriptEvents[268] = "TRADE_REQUEST";
g_scriptEvents[269] = "TRADE_REQUEST_CANCEL";
g_scriptEvents[270] = "LOOT_BIND_CONFIRM";
g_scriptEvents[271] = "EQUIP_BIND_CONFIRM";
g_scriptEvents[272] = "AUTOEQUIP_BIND_CONFIRM";
g_scriptEvents[273] = "USE_BIND_CONFIRM";
g_scriptEvents[274] = "DELETE_ITEM_CONFIRM";
g_scriptEvents[275] = "CURSOR_UPDATE";
g_scriptEvents[276] = "ITEM_TEXT_BEGIN";
g_scriptEvents[277] = "ITEM_TEXT_TRANSLATION";
g_scriptEvents[278] = "ITEM_TEXT_READY";
g_scriptEvents[279] = "ITEM_TEXT_CLOSED";
g_scriptEvents[280] = "GOSSIP_SHOW";
g_scriptEvents[281] = "GOSSIP_CONFIRM";
g_scriptEvents[282] = "GOSSIP_CONFIRM_CANCEL";
g_scriptEvents[283] = "GOSSIP_ENTER_CODE";
g_scriptEvents[284] = "GOSSIP_CLOSED";
g_scriptEvents[285] = "QUEST_GREETING";
g_scriptEvents[286] = "QUEST_DETAIL";
g_scriptEvents[287] = "QUEST_PROGRESS";
g_scriptEvents[288] = "QUEST_COMPLETE";
g_scriptEvents[289] = "QUEST_FINISHED";
g_scriptEvents[290] = "QUEST_ITEM_UPDATE";
g_scriptEvents[291] = "TAXIMAP_OPENED";
g_scriptEvents[292] = "TAXIMAP_CLOSED";
g_scriptEvents[293] = "QUEST_LOG_UPDATE";
g_scriptEvents[294] = "TRAINER_SHOW";
g_scriptEvents[295] = "TRAINER_UPDATE";
g_scriptEvents[296] = "TRAINER_DESCRIPTION_UPDATE";
g_scriptEvents[297] = "TRAINER_CLOSED";
g_scriptEvents[298] = "CVAR_UPDATE";
g_scriptEvents[299] = "TRADE_SKILL_SHOW";
g_scriptEvents[300] = "TRADE_SKILL_UPDATE";
g_scriptEvents[301] = "TRADE_SKILL_CLOSE";
g_scriptEvents[302] = "MERCHANT_SHOW";
g_scriptEvents[303] = "MERCHANT_UPDATE";
g_scriptEvents[304] = "MERCHANT_CLOSED";
g_scriptEvents[305] = "TRADE_SHOW";
g_scriptEvents[306] = "TRADE_CLOSED";
g_scriptEvents[307] = "TRADE_UPDATE";
g_scriptEvents[308] = "TRADE_ACCEPT_UPDATE";
g_scriptEvents[309] = "TRADE_TARGET_ITEM_CHANGED";
g_scriptEvents[310] = "TRADE_PLAYER_ITEM_CHANGED";
g_scriptEvents[311] = "TRADE_MONEY_CHANGED";
g_scriptEvents[312] = "PLAYER_TRADE_MONEY";
g_scriptEvents[313] = "BAG_OPEN";
g_scriptEvents[314] = "BAG_UPDATE";
g_scriptEvents[315] = "BAG_CLOSED";
g_scriptEvents[316] = "BAG_UPDATE_COOLDOWN";
g_scriptEvents[317] = "LOCALPLAYER_PET_RENAMED";
g_scriptEvents[318] = "UNIT_ATTACK";
g_scriptEvents[319] = "UNIT_DEFENSE";
g_scriptEvents[320] = "PET_ATTACK_START";
g_scriptEvents[321] = "PET_ATTACK_STOP";
g_scriptEvents[322] = "UPDATE_MOUSEOVER_UNIT";
g_scriptEvents[323] = "UNIT_SPELLCAST_SENT";
g_scriptEvents[324] = "UNIT_SPELLCAST_START";
g_scriptEvents[325] = "UNIT_SPELLCAST_STOP";
g_scriptEvents[326] = "UNIT_SPELLCAST_FAILED";
g_scriptEvents[327] = "UNIT_SPELLCAST_FAILED_QUIET";
g_scriptEvents[328] = "UNIT_SPELLCAST_INTERRUPTED";
g_scriptEvents[329] = "UNIT_SPELLCAST_DELAYED";
g_scriptEvents[330] = "UNIT_SPELLCAST_SUCCEEDED";
g_scriptEvents[331] = "UNIT_SPELLCAST_CHANNEL_START";
g_scriptEvents[332] = "UNIT_SPELLCAST_CHANNEL_UPDATE";
g_scriptEvents[333] = "UNIT_SPELLCAST_CHANNEL_STOP";
g_scriptEvents[334] = "UNIT_SPELLCAST_INTERRUPTIBLE";
g_scriptEvents[335] = "UNIT_SPELLCAST_NOT_INTERRUPTIBLE";
g_scriptEvents[336] = "PLAYER_GUILD_UPDATE";
g_scriptEvents[337] = "QUEST_ACCEPT_CONFIRM";
g_scriptEvents[338] = "PLAYERBANKSLOTS_CHANGED";
g_scriptEvents[339] = "BANKFRAME_OPENED";
g_scriptEvents[340] = "BANKFRAME_CLOSED";
g_scriptEvents[341] = "PLAYERBANKBAGSLOTS_CHANGED";
g_scriptEvents[342] = "FRIENDLIST_UPDATE";
g_scriptEvents[343] = "IGNORELIST_UPDATE";
g_scriptEvents[344] = "MUTELIST_UPDATE";
g_scriptEvents[345] = "PET_BAR_UPDATE";
g_scriptEvents[346] = "PET_BAR_UPDATE_COOLDOWN";
g_scriptEvents[347] = "PET_BAR_SHOWGRID";
g_scriptEvents[348] = "PET_BAR_HIDEGRID";
g_scriptEvents[349] = "PET_BAR_HIDE";
g_scriptEvents[350] = "PET_BAR_UPDATE_USABLE";
g_scriptEvents[351] = "MINIMAP_PING";
g_scriptEvents[352] = "MIRROR_TIMER_START";
g_scriptEvents[353] = "MIRROR_TIMER_PAUSE";
g_scriptEvents[354] = "MIRROR_TIMER_STOP";
g_scriptEvents[355] = "WORLD_MAP_UPDATE";
g_scriptEvents[356] = "WORLD_MAP_NAME_UPDATE";
g_scriptEvents[357] = "AUTOFOLLOW_BEGIN";
g_scriptEvents[358] = "AUTOFOLLOW_END";
g_scriptEvents[360] = "CINEMATIC_START";
g_scriptEvents[361] = "CINEMATIC_STOP";
g_scriptEvents[362] = "UPDATE_FACTION";
g_scriptEvents[363] = "CLOSE_WORLD_MAP";
g_scriptEvents[364] = "OPEN_TABARD_FRAME";
g_scriptEvents[365] = "CLOSE_TABARD_FRAME";
g_scriptEvents[366] = "TABARD_CANSAVE_CHANGED";
g_scriptEvents[367] = "GUILD_REGISTRAR_SHOW";
g_scriptEvents[368] = "GUILD_REGISTRAR_CLOSED";
g_scriptEvents[369] = "DUEL_REQUESTED";
g_scriptEvents[370] = "DUEL_OUTOFBOUNDS";
g_scriptEvents[371] = "DUEL_INBOUNDS";
g_scriptEvents[372] = "DUEL_FINISHED";
g_scriptEvents[373] = "TUTORIAL_TRIGGER";
g_scriptEvents[374] = "PET_DISMISS_START";
g_scriptEvents[375] = "UPDATE_BINDINGS";
g_scriptEvents[376] = "UPDATE_SHAPESHIFT_FORMS";
g_scriptEvents[377] = "UPDATE_SHAPESHIFT_FORM";
g_scriptEvents[378] = "UPDATE_SHAPESHIFT_USABLE";
g_scriptEvents[379] = "UPDATE_SHAPESHIFT_COOLDOWN";
g_scriptEvents[380] = "WHO_LIST_UPDATE";
g_scriptEvents[381] = "PETITION_SHOW";
g_scriptEvents[382] = "PETITION_CLOSED";
g_scriptEvents[383] = "EXECUTE_CHAT_LINE";
g_scriptEvents[384] = "UPDATE_MACROS";
g_scriptEvents[385] = "UPDATE_TICKET";
g_scriptEvents[386] = "UPDATE_CHAT_WINDOWS";
g_scriptEvents[387] = "CONFIRM_XP_LOSS";
g_scriptEvents[388] = "CORPSE_IN_RANGE";
g_scriptEvents[389] = "CORPSE_IN_INSTANCE";
g_scriptEvents[390] = "CORPSE_OUT_OF_RANGE";
g_scriptEvents[391] = "UPDATE_GM_STATUS";
g_scriptEvents[392] = "PLAYER_UNGHOST";
g_scriptEvents[393] = "BIND_ENCHANT";
g_scriptEvents[394] = "REPLACE_ENCHANT";
g_scriptEvents[395] = "TRADE_REPLACE_ENCHANT";
g_scriptEvents[396] = "TRADE_POTENTIAL_BIND_ENCHANT";
g_scriptEvents[397] = "PLAYER_UPDATE_RESTING";
g_scriptEvents[398] = "UPDATE_EXHAUSTION";
g_scriptEvents[399] = "PLAYER_FLAGS_CHANGED";
g_scriptEvents[400] = "GUILD_ROSTER_UPDATE";
g_scriptEvents[401] = "GM_PLAYER_INFO";
g_scriptEvents[402] = "MAIL_SHOW";
g_scriptEvents[403] = "MAIL_CLOSED";
g_scriptEvents[404] = "SEND_MAIL_MONEY_CHANGED";
g_scriptEvents[405] = "SEND_MAIL_COD_CHANGED";
g_scriptEvents[406] = "MAIL_SEND_INFO_UPDATE";
g_scriptEvents[407] = "MAIL_SEND_SUCCESS";
g_scriptEvents[408] = "MAIL_INBOX_UPDATE";
g_scriptEvents[409] = "MAIL_LOCK_SEND_ITEMS";
g_scriptEvents[410] = "MAIL_UNLOCK_SEND_ITEMS";
g_scriptEvents[411] = "BATTLEFIELDS_SHOW";
g_scriptEvents[412] = "BATTLEFIELDS_CLOSED";
g_scriptEvents[413] = "UPDATE_BATTLEFIELD_STATUS";
g_scriptEvents[414] = "UPDATE_BATTLEFIELD_SCORE";
g_scriptEvents[415] = "AUCTION_HOUSE_SHOW";
g_scriptEvents[416] = "AUCTION_HOUSE_CLOSED";
g_scriptEvents[417] = "NEW_AUCTION_UPDATE";
g_scriptEvents[418] = "AUCTION_ITEM_LIST_UPDATE";
g_scriptEvents[419] = "AUCTION_OWNED_LIST_UPDATE";
g_scriptEvents[420] = "AUCTION_BIDDER_LIST_UPDATE";
g_scriptEvents[421] = "PET_UI_UPDATE";
g_scriptEvents[422] = "PET_UI_CLOSE";
g_scriptEvents[423] = "ADDON_LOADED";
g_scriptEvents[424] = "VARIABLES_LOADED";
g_scriptEvents[425] = "MACRO_ACTION_FORBIDDEN";
g_scriptEvents[426] = "ADDON_ACTION_FORBIDDEN";
g_scriptEvents[427] = "MACRO_ACTION_BLOCKED";
g_scriptEvents[428] = "ADDON_ACTION_BLOCKED";
g_scriptEvents[429] = "START_AUTOREPEAT_SPELL";
g_scriptEvents[430] = "STOP_AUTOREPEAT_SPELL";
g_scriptEvents[431] = "PET_STABLE_SHOW";
g_scriptEvents[432] = "PET_STABLE_UPDATE";
g_scriptEvents[433] = "PET_STABLE_UPDATE_PAPERDOLL";
g_scriptEvents[434] = "PET_STABLE_CLOSED";
g_scriptEvents[435] = "RAID_ROSTER_UPDATE";
g_scriptEvents[436] = "UPDATE_PENDING_MAIL";
g_scriptEvents[437] = "UPDATE_INVENTORY_ALERTS";
g_scriptEvents[438] = "UPDATE_INVENTORY_DURABILITY";
g_scriptEvents[439] = "UPDATE_TRADESKILL_RECAST";
g_scriptEvents[440] = "OPEN_MASTER_LOOT_LIST";
g_scriptEvents[441] = "UPDATE_MASTER_LOOT_LIST";
g_scriptEvents[442] = "START_LOOT_ROLL";
g_scriptEvents[443] = "CANCEL_LOOT_ROLL";
g_scriptEvents[444] = "CONFIRM_LOOT_ROLL";
g_scriptEvents[445] = "CONFIRM_DISENCHANT_ROLL";
g_scriptEvents[446] = "INSTANCE_BOOT_START";
g_scriptEvents[447] = "INSTANCE_BOOT_STOP";
g_scriptEvents[448] = "LEARNED_SPELL_IN_TAB";
g_scriptEvents[449] = "DISPLAY_SIZE_CHANGED";
g_scriptEvents[450] = "CONFIRM_TALENT_WIPE";
g_scriptEvents[451] = "CONFIRM_BINDER";
g_scriptEvents[452] = "MAIL_FAILED";
g_scriptEvents[453] = "CLOSE_INBOX_ITEM";
g_scriptEvents[454] = "CONFIRM_SUMMON";
g_scriptEvents[455] = "CANCEL_SUMMON";
g_scriptEvents[456] = "BILLING_NAG_DIALOG";
g_scriptEvents[457] = "IGR_BILLING_NAG_DIALOG";
g_scriptEvents[458] = "PLAYER_SKINNED";
g_scriptEvents[459] = "TABARD_SAVE_PENDING";
g_scriptEvents[460] = "UNIT_QUEST_LOG_CHANGED";
g_scriptEvents[461] = "PLAYER_PVP_KILLS_CHANGED";
g_scriptEvents[462] = "PLAYER_PVP_RANK_CHANGED";
g_scriptEvents[463] = "INSPECT_HONOR_UPDATE";
g_scriptEvents[464] = "UPDATE_WORLD_STATES";
g_scriptEvents[465] = "AREA_SPIRIT_HEALER_IN_RANGE";
g_scriptEvents[466] = "AREA_SPIRIT_HEALER_OUT_OF_RANGE";
g_scriptEvents[467] = "PLAYTIME_CHANGED";
g_scriptEvents[468] = "UPDATE_LFG_TYPES";
g_scriptEvents[469] = "UPDATE_LFG_LIST";
g_scriptEvents[470] = "UPDATE_LFG_LIST_INCREMENTAL";
g_scriptEvents[471] = "START_MINIGAME";
g_scriptEvents[472] = "MINIGAME_UPDATE";
g_scriptEvents[473] = "READY_CHECK";
g_scriptEvents[474] = "READY_CHECK_CONFIRM";
g_scriptEvents[475] = "READY_CHECK_FINISHED";
g_scriptEvents[476] = "RAID_TARGET_UPDATE";
g_scriptEvents[477] = "GMSURVEY_DISPLAY";
g_scriptEvents[478] = "UPDATE_INSTANCE_INFO";
g_scriptEvents[479] = "SOCKET_INFO_UPDATE";
g_scriptEvents[480] = "SOCKET_INFO_CLOSE";
g_scriptEvents[481] = "PETITION_VENDOR_SHOW";
g_scriptEvents[482] = "PETITION_VENDOR_CLOSED";
g_scriptEvents[483] = "PETITION_VENDOR_UPDATE";
g_scriptEvents[484] = "COMBAT_TEXT_UPDATE";
g_scriptEvents[485] = "QUEST_WATCH_UPDATE";
g_scriptEvents[486] = "KNOWLEDGE_BASE_SETUP_LOAD_SUCCESS";
g_scriptEvents[487] = "KNOWLEDGE_BASE_SETUP_LOAD_FAILURE";
g_scriptEvents[488] = "KNOWLEDGE_BASE_QUERY_LOAD_SUCCESS";
g_scriptEvents[489] = "KNOWLEDGE_BASE_QUERY_LOAD_FAILURE";
g_scriptEvents[490] = "KNOWLEDGE_BASE_ARTICLE_LOAD_SUCCESS";
g_scriptEvents[491] = "KNOWLEDGE_BASE_ARTICLE_LOAD_FAILURE";
g_scriptEvents[492] = "KNOWLEDGE_BASE_SYSTEM_MOTD_UPDATED";
g_scriptEvents[493] = "KNOWLEDGE_BASE_SERVER_MESSAGE";
g_scriptEvents[494] = "ARENA_TEAM_UPDATE";
g_scriptEvents[495] = "ARENA_TEAM_ROSTER_UPDATE";
g_scriptEvents[496] = "ARENA_TEAM_INVITE_REQUEST";
g_scriptEvents[497] = "HONOR_CURRENCY_UPDATE";
g_scriptEvents[498] = "KNOWN_TITLES_UPDATE";
g_scriptEvents[499] = "NEW_TITLE_EARNED";
g_scriptEvents[500] = "OLD_TITLE_LOST";
g_scriptEvents[501] = "LFG_UPDATE";
g_scriptEvents[502] = "LFG_PROPOSAL_UPDATE";
g_scriptEvents[503] = "LFG_PROPOSAL_SHOW";
g_scriptEvents[504] = "LFG_PROPOSAL_FAILED";
g_scriptEvents[505] = "LFG_PROPOSAL_SUCCEEDED";
g_scriptEvents[506] = "LFG_ROLE_UPDATE";
g_scriptEvents[507] = "LFG_ROLE_CHECK_UPDATE";
g_scriptEvents[508] = "LFG_ROLE_CHECK_SHOW";
g_scriptEvents[509] = "LFG_ROLE_CHECK_HIDE";
g_scriptEvents[510] = "LFG_ROLE_CHECK_ROLE_CHOSEN";
g_scriptEvents[511] = "LFG_QUEUE_STATUS_UPDATE";
g_scriptEvents[512] = "LFG_BOOT_PROPOSAL_UPDATE";
g_scriptEvents[513] = "LFG_LOCK_INFO_RECEIVED";
g_scriptEvents[514] = "LFG_UPDATE_RANDOM_INFO";
g_scriptEvents[515] = "LFG_OFFER_CONTINUE";
g_scriptEvents[516] = "LFG_OPEN_FROM_GOSSIP";
g_scriptEvents[517] = "LFG_COMPLETION_REWARD";
g_scriptEvents[518] = "PARTY_LFG_RESTRICTED";
g_scriptEvents[519] = "PLAYER_ROLES_ASSIGNED";
g_scriptEvents[520] = "COMBAT_RATING_UPDATE";
g_scriptEvents[521] = "MODIFIER_STATE_CHANGED";
g_scriptEvents[522] = "UPDATE_STEALTH";
g_scriptEvents[523] = "ENABLE_TAXI_BENCHMARK";
g_scriptEvents[524] = "DISABLE_TAXI_BENCHMARK";
g_scriptEvents[525] = "VOICE_START";
g_scriptEvents[526] = "VOICE_STOP";
g_scriptEvents[527] = "VOICE_STATUS_UPDATE";
g_scriptEvents[528] = "VOICE_CHANNEL_STATUS_UPDATE";
g_scriptEvents[529] = "UPDATE_FLOATING_CHAT_WINDOWS";
g_scriptEvents[530] = "RAID_INSTANCE_WELCOME";
g_scriptEvents[531] = "MOVIE_RECORDING_PROGRESS";
g_scriptEvents[532] = "MOVIE_COMPRESSING_PROGRESS";
g_scriptEvents[533] = "MOVIE_UNCOMPRESSED_MOVIE";
g_scriptEvents[534] = "VOICE_PUSH_TO_TALK_START";
g_scriptEvents[535] = "VOICE_PUSH_TO_TALK_STOP";
g_scriptEvents[536] = "GUILDBANKFRAME_OPENED";
g_scriptEvents[537] = "GUILDBANKFRAME_CLOSED";
g_scriptEvents[538] = "GUILDBANKBAGSLOTS_CHANGED";
g_scriptEvents[539] = "GUILDBANK_ITEM_LOCK_CHANGED";
g_scriptEvents[540] = "GUILDBANK_UPDATE_TABS";
g_scriptEvents[541] = "GUILDBANK_UPDATE_MONEY";
g_scriptEvents[542] = "GUILDBANKLOG_UPDATE";
g_scriptEvents[543] = "GUILDBANK_UPDATE_WITHDRAWMONEY";
g_scriptEvents[544] = "GUILDBANK_UPDATE_TEXT";
g_scriptEvents[545] = "GUILDBANK_TEXT_CHANGED";
g_scriptEvents[546] = "CHANNEL_UI_UPDATE";
g_scriptEvents[547] = "CHANNEL_COUNT_UPDATE";
g_scriptEvents[548] = "CHANNEL_ROSTER_UPDATE";
g_scriptEvents[549] = "CHANNEL_VOICE_UPDATE";
g_scriptEvents[550] = "CHANNEL_INVITE_REQUEST";
g_scriptEvents[551] = "CHANNEL_PASSWORD_REQUEST";
g_scriptEvents[552] = "CHANNEL_FLAGS_UPDATED";
g_scriptEvents[553] = "VOICE_SESSIONS_UPDATE";
g_scriptEvents[554] = "VOICE_CHAT_ENABLED_UPDATE";
g_scriptEvents[555] = "VOICE_LEFT_SESSION";
g_scriptEvents[556] = "INSPECT_TALENT_READY";
g_scriptEvents[557] = "VOICE_SELF_MUTE";
g_scriptEvents[558] = "VOICE_PLATE_START";
g_scriptEvents[559] = "VOICE_PLATE_STOP";
g_scriptEvents[560] = "ARENA_SEASON_WORLD_STATE";
g_scriptEvents[561] = "GUILD_EVENT_LOG_UPDATE";
g_scriptEvents[562] = "GUILDTABARD_UPDATE";
g_scriptEvents[563] = "SOUND_DEVICE_UPDATE";
g_scriptEvents[564] = "COMMENTATOR_MAP_UPDATE";
g_scriptEvents[565] = "COMMENTATOR_ENTER_WORLD";
g_scriptEvents[566] = "COMBAT_LOG_EVENT";
g_scriptEvents[567] = "COMBAT_LOG_EVENT_UNFILTERED";
g_scriptEvents[568] = "COMMENTATOR_PLAYER_UPDATE";
g_scriptEvents[569] = "PLAYER_ENTERING_BATTLEGROUND";
g_scriptEvents[570] = "BARBER_SHOP_OPEN";
g_scriptEvents[571] = "BARBER_SHOP_CLOSE";
g_scriptEvents[572] = "BARBER_SHOP_SUCCESS";
g_scriptEvents[573] = "BARBER_SHOP_APPEARANCE_APPLIED";
g_scriptEvents[574] = "CALENDAR_UPDATE_INVITE_LIST";
g_scriptEvents[575] = "CALENDAR_UPDATE_EVENT_LIST";
g_scriptEvents[576] = "CALENDAR_NEW_EVENT";
g_scriptEvents[577] = "CALENDAR_OPEN_EVENT";
g_scriptEvents[578] = "CALENDAR_CLOSE_EVENT";
g_scriptEvents[579] = "CALENDAR_UPDATE_EVENT";
g_scriptEvents[580] = "CALENDAR_UPDATE_PENDING_INVITES";
g_scriptEvents[581] = "CALENDAR_EVENT_ALARM";
g_scriptEvents[582] = "CALENDAR_UPDATE_ERROR";
g_scriptEvents[583] = "CALENDAR_ACTION_PENDING";
g_scriptEvents[584] = "VEHICLE_ANGLE_SHOW";
g_scriptEvents[585] = "VEHICLE_ANGLE_UPDATE";
g_scriptEvents[586] = "VEHICLE_POWER_SHOW";
g_scriptEvents[587] = "UNIT_ENTERING_VEHICLE";
g_scriptEvents[588] = "UNIT_ENTERED_VEHICLE";
g_scriptEvents[589] = "UNIT_EXITING_VEHICLE";
g_scriptEvents[590] = "UNIT_EXITED_VEHICLE";
g_scriptEvents[591] = "VEHICLE_PASSENGERS_CHANGED";
g_scriptEvents[592] = "PLAYER_GAINS_VEHICLE_DATA";
g_scriptEvents[593] = "PLAYER_LOSES_VEHICLE_DATA";
g_scriptEvents[594] = "PET_FORCE_NAME_DECLENSION";
g_scriptEvents[595] = "LEVEL_GRANT_PROPOSED";
g_scriptEvents[596] = "SYNCHRONIZE_SETTINGS";
g_scriptEvents[597] = "PLAY_MOVIE";
g_scriptEvents[598] = "RUNE_POWER_UPDATE";
g_scriptEvents[599] = "RUNE_TYPE_UPDATE";
g_scriptEvents[600] = "ACHIEVEMENT_EARNED";
g_scriptEvents[601] = "CRITERIA_UPDATE";
g_scriptEvents[602] = "RECEIVED_ACHIEVEMENT_LIST";
g_scriptEvents[603] = "PET_RENAMEABLE";
g_scriptEvents[604] = "KNOWN_CURRENCY_TYPES_UPDATE";
g_scriptEvents[605] = "CURRENCY_DISPLAY_UPDATE";
g_scriptEvents[606] = "COMPANION_LEARNED";
g_scriptEvents[607] = "COMPANION_UNLEARNED";
g_scriptEvents[608] = "COMPANION_UPDATE";
g_scriptEvents[609] = "UNIT_THREAT_LIST_UPDATE";
g_scriptEvents[610] = "UNIT_THREAT_SITUATION_UPDATE";
g_scriptEvents[611] = "GLYPH_ADDED";
g_scriptEvents[612] = "GLYPH_REMOVED";
g_scriptEvents[613] = "GLYPH_UPDATED";
g_scriptEvents[614] = "GLYPH_ENABLED";
g_scriptEvents[615] = "GLYPH_DISABLED";
g_scriptEvents[616] = "USE_GLYPH";
g_scriptEvents[617] = "TRACKED_ACHIEVEMENT_UPDATE";
g_scriptEvents[618] = "ARENA_OPPONENT_UPDATE";
g_scriptEvents[619] = "INSPECT_ACHIEVEMENT_READY";
g_scriptEvents[620] = "RAISED_AS_GHOUL";
g_scriptEvents[621] = "PARTY_CONVERTED_TO_RAID";
g_scriptEvents[622] = "PVPQUEUE_ANYWHERE_SHOW";
g_scriptEvents[623] = "PVPQUEUE_ANYWHERE_UPDATE_AVAILABLE";
g_scriptEvents[624] = "QUEST_ACCEPTED";
g_scriptEvents[625] = "PLAYER_TALENT_UPDATE";
g_scriptEvents[626] = "ACTIVE_TALENT_GROUP_CHANGED";
g_scriptEvents[627] = "PET_TALENT_UPDATE";
g_scriptEvents[628] = "PREVIEW_TALENT_POINTS_CHANGED";
g_scriptEvents[629] = "PREVIEW_PET_TALENT_POINTS_CHANGED";
g_scriptEvents[630] = "WEAR_EQUIPMENT_SET";
g_scriptEvents[631] = "EQUIPMENT_SETS_CHANGED";
g_scriptEvents[632] = "INSTANCE_LOCK_START";
g_scriptEvents[633] = "INSTANCE_LOCK_STOP";
g_scriptEvents[634] = "PLAYER_EQUIPMENT_CHANGED";
g_scriptEvents[635] = "ITEM_LOCKED";
g_scriptEvents[636] = "ITEM_UNLOCKED";
g_scriptEvents[637] = "TRADE_SKILL_FILTER_UPDATE";
g_scriptEvents[638] = "EQUIPMENT_SWAP_PENDING";
g_scriptEvents[639] = "EQUIPMENT_SWAP_FINISHED";
g_scriptEvents[640] = "NPC_PVPQUEUE_ANYWHERE";
g_scriptEvents[641] = "UPDATE_MULTI_CAST_ACTIONBAR";
g_scriptEvents[642] = "ENABLE_XP_GAIN";
g_scriptEvents[643] = "DISABLE_XP_GAIN";
g_scriptEvents[644] = "BATTLEFIELD_MGR_ENTRY_INVITE";
g_scriptEvents[645] = "BATTLEFIELD_MGR_ENTERED";
g_scriptEvents[646] = "BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE";
g_scriptEvents[647] = "BATTLEFIELD_MGR_EJECT_PENDING";
g_scriptEvents[648] = "BATTLEFIELD_MGR_EJECTED";
g_scriptEvents[649] = "BATTLEFIELD_MGR_QUEUE_INVITE";
g_scriptEvents[650] = "BATTLEFIELD_MGR_STATE_CHANGE";
g_scriptEvents[651] = "WORLD_STATE_UI_TIMER_UPDATE";
g_scriptEvents[652] = "END_REFUND";
g_scriptEvents[653] = "END_BOUND_TRADEABLE";
g_scriptEvents[654] = "UPDATE_CHAT_COLOR_NAME_BY_CLASS";
g_scriptEvents[655] = "GMRESPONSE_RECEIVED";
g_scriptEvents[656] = "VEHICLE_UPDATE";
g_scriptEvents[657] = "WOW_MOUSE_NOT_FOUND";
g_scriptEvents[659] = "MAIL_SUCCESS";
g_scriptEvents[660] = "TALENTS_INVOLUNTARILY_RESET";
g_scriptEvents[661] = "INSTANCE_ENCOUNTER_ENGAGE_UNIT";
g_scriptEvents[662] = "QUEST_QUERY_COMPLETE";
g_scriptEvents[663] = "QUEST_POI_UPDATE";
g_scriptEvents[664] = "PLAYER_DIFFICULTY_CHANGED";
g_scriptEvents[665] = "CHAT_MSG_PARTY_LEADER";
g_scriptEvents[666] = "VOTE_KICK_REASON_NEEDED";
g_scriptEvents[667] = "ENABLE_LOW_LEVEL_RAID";
g_scriptEvents[668] = "DISABLE_LOW_LEVEL_RAID";
g_scriptEvents[669] = "CHAT_MSG_TARGETICONS";
g_scriptEvents[670] = "AUCTION_HOUSE_DISABLED";
g_scriptEvents[671] = "AUCTION_MULTISELL_START";
g_scriptEvents[672] = "AUCTION_MULTISELL_UPDATE";
g_scriptEvents[673] = "AUCTION_MULTISELL_FAILURE";
g_scriptEvents[674] = "PET_SPELL_POWER_UPDATE";
g_scriptEvents[675] = "BN_CONNECTED";
g_scriptEvents[676] = "BN_DISCONNECTED";
g_scriptEvents[677] = "BN_SELF_ONLINE";
g_scriptEvents[678] = "BN_SELF_OFFLINE";
g_scriptEvents[679] = "BN_FRIEND_LIST_SIZE_CHANGED";
g_scriptEvents[680] = "BN_FRIEND_INVITE_LIST_INITIALIZED";
g_scriptEvents[681] = "BN_FRIEND_INVITE_SEND_RESULT";
g_scriptEvents[682] = "BN_FRIEND_INVITE_ADDED";
g_scriptEvents[683] = "BN_FRIEND_INVITE_REMOVED";
g_scriptEvents[684] = "BN_FRIEND_INFO_CHANGED";
g_scriptEvents[685] = "BN_CUSTOM_MESSAGE_CHANGED";
g_scriptEvents[686] = "BN_CUSTOM_MESSAGE_LOADED";
g_scriptEvents[687] = "CHAT_MSG_BN_WHISPER";
g_scriptEvents[688] = "CHAT_MSG_BN_WHISPER_INFORM";
g_scriptEvents[689] = "BN_CHAT_WHISPER_UNDELIVERABLE";
g_scriptEvents[690] = "BN_CHAT_CHANNEL_JOINED";
g_scriptEvents[691] = "BN_CHAT_CHANNEL_LEFT";
g_scriptEvents[692] = "BN_CHAT_CHANNEL_CLOSED";
g_scriptEvents[693] = "CHAT_MSG_BN_CONVERSATION";
g_scriptEvents[694] = "CHAT_MSG_BN_CONVERSATION_NOTICE";
g_scriptEvents[695] = "CHAT_MSG_BN_CONVERSATION_LIST";
g_scriptEvents[696] = "BN_CHAT_CHANNEL_MESSAGE_UNDELIVERABLE";
g_scriptEvents[697] = "BN_CHAT_CHANNEL_MESSAGE_BLOCKED";
g_scriptEvents[698] = "BN_CHAT_CHANNEL_MEMBER_JOINED";
g_scriptEvents[699] = "BN_CHAT_CHANNEL_MEMBER_LEFT";
g_scriptEvents[700] = "BN_CHAT_CHANNEL_MEMBER_UPDATED";
g_scriptEvents[701] = "BN_CHAT_CHANNEL_CREATE_SUCCEEDED";
g_scriptEvents[702] = "BN_CHAT_CHANNEL_CREATE_FAILED";
g_scriptEvents[703] = "BN_CHAT_CHANNEL_INVITE_SUCCEEDED";
g_scriptEvents[704] = "BN_CHAT_CHANNEL_INVITE_FAILED";
g_scriptEvents[705] = "BN_BLOCK_LIST_UPDATED";
g_scriptEvents[706] = "BN_SYSTEM_MESSAGE";
g_scriptEvents[707] = "BN_REQUEST_FOF_SUCCEEDED";
g_scriptEvents[708] = "BN_REQUEST_FOF_FAILED";
g_scriptEvents[709] = "BN_NEW_PRESENCE";
g_scriptEvents[710] = "BN_TOON_NAME_UPDATED";
g_scriptEvents[711] = "BN_FRIEND_ACCOUNT_ONLINE";
g_scriptEvents[712] = "BN_FRIEND_ACCOUNT_OFFLINE";
g_scriptEvents[713] = "BN_FRIEND_TOON_ONLINE";
g_scriptEvents[714] = "BN_FRIEND_TOON_OFFLINE";
g_scriptEvents[715] = "BN_MATURE_LANGUAGE_FILTER";
g_scriptEvents[716] = "COMMENTATOR_SKIRMISH_QUEUE_REQUEST";
g_scriptEvents[717] = "COMMENTATOR_SKIRMISH_MODE_REQUEST";
g_scriptEvents[718] = "CHAT_MSG_BN_INLINE_TOAST_ALERT";
g_scriptEvents[719] = "CHAT_MSG_BN_INLINE_TOAST_BROADCAST";
g_scriptEvents[720] = "CHAT_MSG_BN_INLINE_TOAST_BROADCAST_INFORM";
g_scriptEvents[721] = "CHAT_MSG_BN_INLINE_TOAST_CONVERSATION";
}

View File

@ -40,7 +40,6 @@ class FrameScript_EventObject : public TSHashObject<FrameScript_EventObject, HAS
}; };
extern int32_t g_glueFrameScriptGenders[UNITSEX_LAST]; extern int32_t g_glueFrameScriptGenders[UNITSEX_LAST];
extern const char* g_scriptEvents[722];
namespace FrameScript { namespace FrameScript {
extern void* s_mempool; extern void* s_mempool;
@ -99,8 +98,8 @@ void FrameScript_SignalEvent(uint32_t index, const char* format, ...);
const char* FrameScript_Sprintf(lua_State* L, int32_t idx, char buffer[], uint32_t bufferLen); const char* FrameScript_Sprintf(lua_State* L, int32_t idx, char buffer[], uint32_t bufferLen);
void FrameScript_UnregisterFunction(const char* name);
void FrameScript_UnregisterScriptEvent(FrameScript_Object* object, FrameScript_EventObject* event); void FrameScript_UnregisterScriptEvent(FrameScript_Object* object, FrameScript_EventObject* event);
void ScriptEventsInitialize();
#endif #endif

View File

@ -5,6 +5,12 @@
int32_t FrameScript_Object::s_objectTypes = 0; int32_t FrameScript_Object::s_objectTypes = 0;
FrameScript_Object::ScriptIx::~ScriptIx() {
if (this->luaRef) {
luaL_unref(FrameScript_GetContext(), LUA_REGISTRYINDEX, this->luaRef);
}
}
int32_t FrameScript_Object::CreateScriptMetaTable(lua_State* L, void (*a2)(lua_State* L)) { int32_t FrameScript_Object::CreateScriptMetaTable(lua_State* L, void (*a2)(lua_State* L)) {
lua_createtable(L, 0, 0); lua_createtable(L, 0, 0);
lua_pushstring(L, "__index"); lua_pushstring(L, "__index");
@ -24,17 +30,38 @@ void FrameScript_Object::FillScriptMethodTable(lua_State *L, FrameScript_Method
} }
} }
FrameScript_Object::~FrameScript_Object() {
if (this->m_onEvent.luaRef) {
luaL_unref(FrameScript_GetContext(), LUA_REGISTRYINDEX, this->m_onEvent.luaRef);
}
}
const char* FrameScript_Object::GetDisplayName() { const char* FrameScript_Object::GetDisplayName() {
const char* name = this->GetName(); const char* name = this->GetName();
return name ? name : "<unnamed>"; return name ? name : "<unnamed>";
} }
int32_t FrameScript_Object::GetScript(lua_State* L) {
if (!lua_isstring(L, 2)) {
luaL_error(L, "Usage: %s:GetScript(\"type\")", this->GetDisplayName());
return 0;
}
auto name = lua_tostring(L, 2);
ScriptData data;
auto script = this->GetScriptByName(name, data);
if (!script) {
luaL_error(L, "%s doesn't have a \"%s\" script", this->GetDisplayName(), lua_tostring(L, 2));
return 0;
}
// TODO taint management
if (script->luaRef > 0) {
lua_rawgeti(L, LUA_REGISTRYINDEX, script->luaRef);
} else {
lua_pushnil(L);
}
return 1;
}
FrameScript_Object::ScriptIx* FrameScript_Object::GetScriptByName(const char* name, FrameScript_Object::ScriptData& data) { FrameScript_Object::ScriptIx* FrameScript_Object::GetScriptByName(const char* name, FrameScript_Object::ScriptData& data) {
if (!SStrCmpI(name, "OnEvent", STORM_MAX_STR)) { if (!SStrCmpI(name, "OnEvent", STORM_MAX_STR)) {
data.wrapper = "return function(self,event,...) %s end"; data.wrapper = "return function(self,event,...) %s end";
@ -166,6 +193,25 @@ int32_t FrameScript_Object::SetScript(lua_State* L) {
return 0; return 0;
} }
void FrameScript_Object::UnregisterScriptEvent(const char* name) {
auto event = FrameScript::s_scriptEventsHash.Ptr(name);
if (!event) {
return;
}
if (event->pendingSignalCount) {
for (auto node = event->registerListeners.Head(); node; node = event->registerListeners.Next(node)) {
if (node->listener == this) {
event->registerListeners.DeleteNode(node);
break;
}
}
}
FrameScript_UnregisterScriptEvent(this, event);
}
void FrameScript_Object::UnregisterScriptObject(const char* name) { void FrameScript_Object::UnregisterScriptObject(const char* name) {
auto L = FrameScript_GetContext(); auto L = FrameScript_GetContext();

View File

@ -14,6 +14,7 @@ class FrameScript_Object {
struct ScriptIx { struct ScriptIx {
int32_t luaRef = 0; int32_t luaRef = 0;
const char* unk = nullptr; const char* unk = nullptr;
~ScriptIx();
}; };
class ScriptFunction { class ScriptFunction {
@ -34,7 +35,7 @@ class FrameScript_Object {
ScriptIx m_onEvent; ScriptIx m_onEvent;
// Virtual member functions // Virtual member functions
virtual ~FrameScript_Object(); virtual ~FrameScript_Object() = default;
virtual char* GetName() = 0; virtual char* GetName() = 0;
virtual int32_t GetScriptMetaTable() = 0; virtual int32_t GetScriptMetaTable() = 0;
virtual ScriptIx* GetScriptByName(const char* name, ScriptData& data); virtual ScriptIx* GetScriptByName(const char* name, ScriptData& data);
@ -42,10 +43,12 @@ class FrameScript_Object {
// Member functions // Member functions
const char* GetDisplayName(); const char* GetDisplayName();
int32_t GetScript(lua_State* L);
int32_t RegisterScriptEvent(const char* name); int32_t RegisterScriptEvent(const char* name);
void RegisterScriptObject(const char* name); void RegisterScriptObject(const char* name);
void RunScript(ScriptIx const& script, int32_t argCount, const char* a4); void RunScript(ScriptIx const& script, int32_t argCount, const char* a4);
int32_t SetScript(lua_State* L); int32_t SetScript(lua_State* L);
void UnregisterScriptEvent(const char* name);
void UnregisterScriptObject(const char* name); void UnregisterScriptObject(const char* name);
}; };

View File

@ -8,6 +8,7 @@
#include "ui/simple/CSimpleModel.hpp" #include "ui/simple/CSimpleModel.hpp"
#include "ui/simple/CSimpleScrollFrame.hpp" #include "ui/simple/CSimpleScrollFrame.hpp"
#include "ui/simple/CSimpleSlider.hpp" #include "ui/simple/CSimpleSlider.hpp"
#include "ui/simple/CSimpleStatusBar.hpp"
#include "util/CStatus.hpp" #include "util/CStatus.hpp"
#include "util/SFile.hpp" #include "util/SFile.hpp"
#include <common/XML.hpp> #include <common/XML.hpp>
@ -96,9 +97,9 @@ CSimpleFrame* Create_SimpleHTML(CSimpleFrame* parent) {
} }
CSimpleFrame* Create_SimpleStatusBar(CSimpleFrame* parent) { CSimpleFrame* Create_SimpleStatusBar(CSimpleFrame* parent) {
// TODO // TODO CDataAllocator
return nullptr; return STORM_NEW(CSimpleStatusBar(parent));
} }
CSimpleFrame* Create_SimpleColorSelect(CSimpleFrame* parent) { CSimpleFrame* Create_SimpleColorSelect(CSimpleFrame* parent) {
@ -541,19 +542,19 @@ int32_t FrameXML_RegisterFactory(const char* type, CSimpleFrame* (*factory)(CSim
} }
void FrameXML_RegisterDefault() { void FrameXML_RegisterDefault() {
FrameXML_RegisterFactory("Button", &Create_SimpleButton, 0); FrameXML_RegisterFactory("Button", &Create_SimpleButton, false);
FrameXML_RegisterFactory("CheckButton", &Create_SimpleCheckButton, 0); FrameXML_RegisterFactory("CheckButton", &Create_SimpleCheckButton, false);
FrameXML_RegisterFactory("EditBox", &Create_SimpleEditBox, 0); FrameXML_RegisterFactory("EditBox", &Create_SimpleEditBox, false);
FrameXML_RegisterFactory("Frame", &Create_SimpleFrame, 0); FrameXML_RegisterFactory("Frame", &Create_SimpleFrame, false);
FrameXML_RegisterFactory("MessageFrame", &Create_SimpleMessageFrame, 0); FrameXML_RegisterFactory("MessageFrame", &Create_SimpleMessageFrame, false);
FrameXML_RegisterFactory("Model", &Create_SimpleModel, 0); FrameXML_RegisterFactory("Model", &Create_SimpleModel, false);
FrameXML_RegisterFactory("ScrollFrame", &Create_SimpleScrollFrame, 0); FrameXML_RegisterFactory("ScrollFrame", &Create_SimpleScrollFrame, false);
FrameXML_RegisterFactory("ScrollingMessageFrame", &Create_SimpleScrollingMessageFrame, 0); FrameXML_RegisterFactory("ScrollingMessageFrame", &Create_SimpleScrollingMessageFrame, false);
FrameXML_RegisterFactory("Slider", &Create_SimpleSlider, 0); FrameXML_RegisterFactory("Slider", &Create_SimpleSlider, false);
FrameXML_RegisterFactory("SimpleHTML", &Create_SimpleHTML, 0); FrameXML_RegisterFactory("SimpleHTML", &Create_SimpleHTML, false);
FrameXML_RegisterFactory("StatusBar", &Create_SimpleStatusBar, 0); FrameXML_RegisterFactory("StatusBar", &Create_SimpleStatusBar, false);
FrameXML_RegisterFactory("ColorSelect", &Create_SimpleColorSelect, 0); FrameXML_RegisterFactory("ColorSelect", &Create_SimpleColorSelect, false);
FrameXML_RegisterFactory("MovieFrame", &Create_SimpleMovieFrame, 0); FrameXML_RegisterFactory("MovieFrame", &Create_SimpleMovieFrame, false);
} }
void FrameXML_ReleaseHashNode(const char* name) { void FrameXML_ReleaseHashNode(const char* name) {

9
src/ui/Game.hpp Normal file
View File

@ -0,0 +1,9 @@
#ifndef UI_GAME_HPP
#define UI_GAME_HPP
#include "ui/game/CGGameUI.hpp"
#include "ui/game/CGPetInfo.hpp"
#include "ui/game/ScriptEvents.hpp"
#include "ui/game/Types.hpp"
#endif

20
src/ui/Key.cpp Normal file
View File

@ -0,0 +1,20 @@
#include "ui/Key.hpp"
uint8_t InterfaceKey[256] = {
0xC3, 0x5B, 0x50, 0x84, 0xB9, 0x3E, 0x32, 0x42, 0x8C, 0xD0, 0xC7, 0x48, 0xFA, 0x0E, 0x5D, 0x54,
0x5A, 0xA3, 0x0E, 0x14, 0xBA, 0x9E, 0x0D, 0xB9, 0x5D, 0x8B, 0xEE, 0xB6, 0x84, 0x93, 0x45, 0x75,
0xFF, 0x31, 0xFE, 0x2F, 0x64, 0x3F, 0x3D, 0x6D, 0x07, 0xD9, 0x44, 0x9B, 0x40, 0x85, 0x59, 0x34,
0x4E, 0x10, 0xE1, 0xE7, 0x43, 0x69, 0xEF, 0x7C, 0x16, 0xFC, 0xB4, 0xED, 0x1B, 0x95, 0x28, 0xA8,
0x23, 0x76, 0x51, 0x31, 0x57, 0x30, 0x2B, 0x79, 0x08, 0x50, 0x10, 0x1C, 0x4A, 0x1A, 0x2C, 0xC8,
0x8B, 0x8F, 0x05, 0x2D, 0x22, 0x3D, 0xDB, 0x5A, 0x24, 0x7A, 0x0F, 0x13, 0x50, 0x37, 0x8F, 0x5A,
0xCC, 0x9E, 0x04, 0x44, 0x0E, 0x87, 0x01, 0xD4, 0xA3, 0x15, 0x94, 0x16, 0x34, 0xC6, 0xC2, 0xC3,
0xFB, 0x49, 0xFE, 0xE1, 0xF9, 0xDA, 0x8C, 0x50, 0x3C, 0xBE, 0x2C, 0xBB, 0x57, 0xED, 0x46, 0xB9,
0xAD, 0x8B, 0xC6, 0xDF, 0x0E, 0xD6, 0x0F, 0xBE, 0x80, 0xB3, 0x8B, 0x1E, 0x77, 0xCF, 0xAD, 0x22,
0xCF, 0xB7, 0x4B, 0xCF, 0xFB, 0xF0, 0x6B, 0x11, 0x45, 0x2D, 0x7A, 0x81, 0x18, 0xF2, 0x92, 0x7E,
0x98, 0x56, 0x5D, 0x5E, 0x69, 0x72, 0x0A, 0x0D, 0x03, 0x0A, 0x85, 0xA2, 0x85, 0x9C, 0xCB, 0xFB,
0x56, 0x6E, 0x8F, 0x44, 0xBB, 0x8F, 0x02, 0x22, 0x68, 0x63, 0x97, 0xBC, 0x85, 0xBA, 0xA8, 0xF7,
0xB5, 0x40, 0x68, 0x3C, 0x77, 0x86, 0x6F, 0x4B, 0xD7, 0x88, 0xCA, 0x8A, 0xD7, 0xCE, 0x36, 0xF0,
0x45, 0x6E, 0xD5, 0x64, 0x79, 0x0F, 0x17, 0xFC, 0x64, 0xDD, 0x10, 0x6F, 0xF3, 0xF5, 0xE0, 0xA6,
0xC3, 0xFB, 0x1B, 0x8C, 0x29, 0xEF, 0x8E, 0xE5, 0x34, 0xCB, 0xD1, 0x2A, 0xCE, 0x79, 0xC3, 0x9A,
0x0D, 0x36, 0xEA, 0x01, 0xE0, 0xAA, 0x91, 0x20, 0x54, 0xF0, 0x72, 0xD8, 0x1E, 0xC7, 0x89, 0xD2
};

Some files were not shown because too many files have changed in this diff Show More