mirror of
https://github.com/whoahq/whoa.git
synced 2026-03-18 21:51:06 +03:00
Merge branch 'master' into branch-feat-glue-implement-Script_ContestAccepted
This commit is contained in:
commit
0d8525e317
@ -1 +1 @@
|
||||
Subproject commit 48a78025ef77faac80faa30c116f3ced4bbd9251
|
||||
Subproject commit 39cf7976a899b4f9a1290d0afdbd5011e4af9ac1
|
||||
@ -1 +1 @@
|
||||
Subproject commit 1c9e7831c874068e7c939a7dea8790eef6513d78
|
||||
Subproject commit 1e5366bbc6935e3363abf5921f0be12f902e790a
|
||||
@ -18,6 +18,7 @@
|
||||
#include "sound/Interface.hpp"
|
||||
#include "ui/FrameScript.hpp"
|
||||
#include "ui/FrameXML.hpp"
|
||||
#include "ui/Game.hpp"
|
||||
#include "util/Random.hpp"
|
||||
#include "world/World.hpp"
|
||||
#include <bc/Debug.hpp>
|
||||
@ -29,6 +30,8 @@ CVar* Client::g_accountNameVar;
|
||||
CVar* Client::g_accountListVar;
|
||||
HEVENTCONTEXT Client::g_clientEventContext;
|
||||
|
||||
CGameTime g_clientGameTime;
|
||||
|
||||
static CVar* s_desktopGammaCvar;
|
||||
static CVar* s_gammaCvar;
|
||||
static CVar* s_textureCacheSizeCvar;
|
||||
@ -69,10 +72,28 @@ void BaseInitializeGlobal() {
|
||||
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) {
|
||||
// TODO
|
||||
// ClientGameTimeTickHandler(data, param);
|
||||
// Player_C_ZoneUpdateHandler(data, param);
|
||||
ClientGameTimeTickHandler(data, nullptr);
|
||||
|
||||
// TODO Player_C_ZoneUpdateHandler(data, nullptr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -85,7 +106,12 @@ void ClientInitializeGame(uint32_t mapId, C3Vector position) {
|
||||
|
||||
// TODO
|
||||
|
||||
CGGameUI::InitializeGame();
|
||||
|
||||
// TODO
|
||||
|
||||
EventRegister(EVENT_ID_IDLE, ClientIdle);
|
||||
ClientInitializeGameTime();
|
||||
|
||||
// TODO
|
||||
|
||||
@ -520,8 +546,9 @@ void WowClientDestroy() {
|
||||
}
|
||||
|
||||
void WowClientInit() {
|
||||
EventRegister(EVENT_ID_TICK, reinterpret_cast<EVENTHANDLERFUNC>(&CWorld::OnTick));
|
||||
|
||||
// TODO
|
||||
// EventRegister(EVENT_ID_5, (int)sub_4020E0);
|
||||
// _cfltcvt_init_0();
|
||||
|
||||
ClientRegisterConsoleCommands();
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define CLIENT_CLIENT_HPP
|
||||
|
||||
#include "event/Event.hpp"
|
||||
#include "util/Time.hpp"
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
class CVar;
|
||||
@ -12,6 +13,8 @@ namespace Client {
|
||||
extern HEVENTCONTEXT g_clientEventContext;
|
||||
}
|
||||
|
||||
extern CGameTime g_clientGameTime;
|
||||
|
||||
void ClientInitializeGame(uint32_t mapId, C3Vector position);
|
||||
|
||||
void ClientPostClose(int32_t a1);
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
#include "client/ClientHandlers.hpp"
|
||||
#include "Client.hpp"
|
||||
#include "console/Console.hpp"
|
||||
#include "db/Db.hpp"
|
||||
#include "object/Client.hpp"
|
||||
#include "util/Time.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include "world/World.hpp"
|
||||
#include <common/DataStore.hpp>
|
||||
#include <tempest/Vector.hpp>
|
||||
#include <cstdint>
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
static float s_newFacing;
|
||||
static C3Vector s_newPosition;
|
||||
@ -77,6 +80,56 @@ int32_t PlayedTimeHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataSto
|
||||
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) {
|
||||
// TODO
|
||||
|
||||
|
||||
@ -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 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 TransferPendingHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg);
|
||||
|
||||
@ -121,6 +121,10 @@ bool ComponentCompressCallback(CVar* var, const char* oldValue, const char* valu
|
||||
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) {
|
||||
if (!model || !displayRec || invSlot > INVSLOT_TABARD) {
|
||||
return -1;
|
||||
@ -247,6 +251,26 @@ CCharacterComponent* CCharacterComponent::AllocComponent() {
|
||||
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) {
|
||||
uint32_t firstBone;
|
||||
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) {
|
||||
auto component = static_cast<CCharacterComponent*>(userArg);
|
||||
|
||||
|
||||
@ -10,6 +10,8 @@
|
||||
class CACHEENTRY;
|
||||
class CCharacterComponent;
|
||||
class CharSectionsRec;
|
||||
class CreatureDisplayInfoRec;
|
||||
class CreatureModelDataRec;
|
||||
class ItemDisplayInfoRec;
|
||||
|
||||
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 void AddLink(CM2Model* parent, GEOCOMPONENTLINKS link, char const* modelPath, char const* texturePath, int32_t visualID, const ItemDisplayInfoRec* displayRec);
|
||||
static CCharacterComponent* AllocComponent();
|
||||
static void ApplyMonsterGeosets(CM2Model* model, const CreatureDisplayInfoRec* displayInfoRec);
|
||||
static void ComponentCloseFingers(CM2Model* model, COMP_HAND_SLOT handSlot);
|
||||
static void ComponentOpenFingers(CM2Model* model, COMP_HAND_SLOT handSlot);
|
||||
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 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 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);
|
||||
|
||||
// Member variables
|
||||
|
||||
@ -12,14 +12,18 @@ WowClientDB<CharacterFacialHairStylesRec> g_characterFacialHairStylesDB;
|
||||
WowClientDB<ChrClassesRec> g_chrClassesDB;
|
||||
WowClientDB<ChrRacesRec> g_chrRacesDB;
|
||||
WowClientDB<CreatureDisplayInfoRec> g_creatureDisplayInfoDB;
|
||||
WowClientDB<CreatureDisplayInfoExtraRec> g_creatureDisplayInfoExtraDB;
|
||||
WowClientDB<CreatureModelDataRec> g_creatureModelDataDB;
|
||||
WowClientDB<CreatureSoundDataRec> g_creatureSoundDataDB;
|
||||
WowClientDB<FactionGroupRec> g_factionGroupDB;
|
||||
WowClientDB<FactionTemplateRec> g_factionTemplateDB;
|
||||
WowClientDB<ItemDisplayInfoRec> g_itemDisplayInfoDB;
|
||||
WowClientDB<ItemVisualsRec> g_itemVisualsDB;
|
||||
WowClientDB<MapRec> g_mapDB;
|
||||
WowClientDB<PaperDollItemFrameRec> g_paperDollItemFrameDB;
|
||||
WowClientDB<SoundEntriesRec> g_soundEntriesDB;
|
||||
WowClientDB<SoundEntriesAdvancedRec> g_soundEntriesAdvancedDB;
|
||||
WowClientDB<UnitBloodLevelsRec> g_unitBloodLevelsDB;
|
||||
|
||||
void LoadDB(WowClientDB_Base* db, const char* filename, int32_t 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_chrRacesDB, __FILE__, __LINE__);
|
||||
loadFn(&g_creatureDisplayInfoDB, __FILE__, __LINE__);
|
||||
loadFn(&g_creatureDisplayInfoExtraDB, __FILE__, __LINE__);
|
||||
loadFn(&g_creatureModelDataDB, __FILE__, __LINE__);
|
||||
loadFn(&g_creatureSoundDataDB, __FILE__, __LINE__);
|
||||
loadFn(&g_factionGroupDB, __FILE__, __LINE__);
|
||||
loadFn(&g_factionTemplateDB, __FILE__, __LINE__);
|
||||
loadFn(&g_itemDisplayInfoDB, __FILE__, __LINE__);
|
||||
loadFn(&g_itemVisualsDB, __FILE__, __LINE__);
|
||||
loadFn(&g_mapDB, __FILE__, __LINE__);
|
||||
loadFn(&g_paperDollItemFrameDB, __FILE__, __LINE__);
|
||||
loadFn(&g_soundEntriesDB, __FILE__, __LINE__);
|
||||
loadFn(&g_soundEntriesAdvancedDB, __FILE__, __LINE__);
|
||||
loadFn(&g_unitBloodLevelsDB, __FILE__, __LINE__);
|
||||
};
|
||||
|
||||
void ClientDBInitialize() {
|
||||
|
||||
@ -13,14 +13,18 @@
|
||||
#include "db/rec/ChrClassesRec.hpp"
|
||||
#include "db/rec/ChrRacesRec.hpp"
|
||||
#include "db/rec/CreatureDisplayInfoRec.hpp"
|
||||
#include "db/rec/CreatureDisplayInfoExtraRec.hpp"
|
||||
#include "db/rec/CreatureModelDataRec.hpp"
|
||||
#include "db/rec/CreatureSoundDataRec.hpp"
|
||||
#include "db/rec/FactionGroupRec.hpp"
|
||||
#include "db/rec/FactionTemplateRec.hpp"
|
||||
#include "db/rec/ItemDisplayInfoRec.hpp"
|
||||
#include "db/rec/ItemVisualsRec.hpp"
|
||||
#include "db/rec/MapRec.hpp"
|
||||
#include "db/rec/PaperDollItemFrameRec.hpp"
|
||||
#include "db/rec/SoundEntriesRec.hpp"
|
||||
#include "db/rec/SoundEntriesAdvancedRec.hpp"
|
||||
#include "db/rec/UnitBloodLevelsRec.hpp"
|
||||
|
||||
extern WowClientDB<AchievementRec> g_achievementDB;
|
||||
extern WowClientDB<AreaTableRec> g_areaTableDB;
|
||||
@ -33,14 +37,18 @@ extern WowClientDB<CharacterFacialHairStylesRec> g_characterFacialHairStylesDB;
|
||||
extern WowClientDB<ChrClassesRec> g_chrClassesDB;
|
||||
extern WowClientDB<ChrRacesRec> g_chrRacesDB;
|
||||
extern WowClientDB<CreatureDisplayInfoRec> g_creatureDisplayInfoDB;
|
||||
extern WowClientDB<CreatureDisplayInfoExtraRec> g_creatureDisplayInfoExtraDB;
|
||||
extern WowClientDB<CreatureModelDataRec> g_creatureModelDataDB;
|
||||
extern WowClientDB<CreatureSoundDataRec> g_creatureSoundDataDB;
|
||||
extern WowClientDB<FactionGroupRec> g_factionGroupDB;
|
||||
extern WowClientDB<FactionTemplateRec> g_factionTemplateDB;
|
||||
extern WowClientDB<ItemDisplayInfoRec> g_itemDisplayInfoDB;
|
||||
extern WowClientDB<ItemVisualsRec> g_itemVisualsDB;
|
||||
extern WowClientDB<MapRec> g_mapDB;
|
||||
extern WowClientDB<PaperDollItemFrameRec> g_paperDollItemFrameDB;
|
||||
extern WowClientDB<SoundEntriesRec> g_soundEntriesDB;
|
||||
extern WowClientDB<SoundEntriesAdvancedRec> g_soundEntriesAdvancedDB;
|
||||
extern WowClientDB<UnitBloodLevelsRec> g_unitBloodLevelsDB;
|
||||
|
||||
void ClientDBInitialize();
|
||||
|
||||
|
||||
66
src/db/rec/CreatureDisplayInfoExtraRec.cpp
Normal file
66
src/db/rec/CreatureDisplayInfoExtraRec.cpp
Normal 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;
|
||||
}
|
||||
32
src/db/rec/CreatureDisplayInfoExtraRec.hpp
Normal file
32
src/db/rec/CreatureDisplayInfoExtraRec.hpp
Normal 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
|
||||
75
src/db/rec/CreatureSoundDataRec.cpp
Normal file
75
src/db/rec/CreatureSoundDataRec.cpp
Normal 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;
|
||||
}
|
||||
52
src/db/rec/CreatureSoundDataRec.hpp
Normal file
52
src/db/rec/CreatureSoundDataRec.hpp
Normal 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
|
||||
51
src/db/rec/PaperDollItemFrameRec.cpp
Normal file
51
src/db/rec/PaperDollItemFrameRec.cpp
Normal 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;
|
||||
}
|
||||
25
src/db/rec/PaperDollItemFrameRec.hpp
Normal file
25
src/db/rec/PaperDollItemFrameRec.hpp
Normal 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
|
||||
41
src/db/rec/UnitBloodLevelsRec.cpp
Normal file
41
src/db/rec/UnitBloodLevelsRec.cpp
Normal 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;
|
||||
}
|
||||
23
src/db/rec/UnitBloodLevelsRec.hpp
Normal file
23
src/db/rec/UnitBloodLevelsRec.hpp
Normal 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
|
||||
@ -286,12 +286,10 @@ int32_t SchedulerThreadProcProcess(uint32_t a1) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t v9 = (currTime - context->m_schedLastIdle);
|
||||
float elapsedSec = (currTime - context->m_schedLastIdle) * 0.001;
|
||||
context->m_schedLastIdle = currTime;
|
||||
double elapsedSec = v9 * 0.001;
|
||||
|
||||
// TODO
|
||||
// FrameTime::Update(currTime, elapsedSec);
|
||||
SynthesizeTick(context, currTime, elapsedSec);
|
||||
|
||||
IEvtTimerDispatch(context);
|
||||
|
||||
|
||||
@ -91,3 +91,17 @@ void SynthesizePoll(EvtContext* context) {
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_POLL, nullptr);
|
||||
}
|
||||
|
||||
void SynthesizeTick(EvtContext* context, uint32_t currTime, float elapsedSec) {
|
||||
context->m_critsect.Enter();
|
||||
bool closed = context->m_schedState == EvtContext::SCHEDSTATE_CLOSED;
|
||||
context->m_critsect.Leave();
|
||||
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
EVENT_DATA_TICK data = { elapsedSec, currTime };
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_TICK, &data);
|
||||
}
|
||||
|
||||
@ -15,4 +15,6 @@ void SynthesizePaint(EvtContext* context);
|
||||
|
||||
void SynthesizePoll(EvtContext* context);
|
||||
|
||||
void SynthesizeTick(EvtContext* context, uint32_t currTime, float elapsedSec);
|
||||
|
||||
#endif
|
||||
|
||||
@ -12,7 +12,7 @@ enum EVENTID {
|
||||
EVENT_ID_FOCUS = 2,
|
||||
EVENT_ID_CLOSE = 3,
|
||||
EVENT_ID_DESTROY = 4,
|
||||
EVENT_ID_5 = 5,
|
||||
EVENT_ID_TICK = 5,
|
||||
EVENT_ID_IDLE = 6,
|
||||
EVENT_ID_POLL = 7,
|
||||
EVENT_ID_INITIALIZE = 8,
|
||||
@ -259,4 +259,9 @@ struct EVENT_DATA_SIZE {
|
||||
int32_t h;
|
||||
};
|
||||
|
||||
struct EVENT_DATA_TICK {
|
||||
float tickTimeSec;
|
||||
uint32_t curTimeMs;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -25,10 +25,12 @@
|
||||
#include "ui/FrameScript.hpp"
|
||||
#include "ui/FrameXML.hpp"
|
||||
#include "ui/Interface.hpp"
|
||||
#include "ui/ScriptFunctions.hpp"
|
||||
#include "ui/Key.hpp"
|
||||
#include "ui/ScriptFunctionsSystem.hpp"
|
||||
#include "ui/game/CGVideoOptions.hpp"
|
||||
#include "ui/simple/CSimpleModelFFX.hpp"
|
||||
#include "ui/simple/CSimpleTop.hpp"
|
||||
#include "ui/simple/ScriptMethods.hpp"
|
||||
#include "util/Filesystem.hpp"
|
||||
#include "util/Locale.hpp"
|
||||
#include "util/Log.hpp"
|
||||
@ -411,6 +413,11 @@ int32_t CGlueMgr::Idle(const void* a1, void* a2) {
|
||||
break;
|
||||
}
|
||||
|
||||
case IDLE_CREATE_CHARACTER: {
|
||||
CGlueMgr::PollCreateCharacter(msg, complete, result);
|
||||
break;
|
||||
}
|
||||
|
||||
case IDLE_DELETE_CHARACTER: {
|
||||
CGlueMgr::PollDeleteCharacter(msg, complete, result);
|
||||
break;
|
||||
@ -781,6 +788,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) {
|
||||
FrameScript_SignalEvent(UPDATE_STATUS_DIALOG, "%s", msg);
|
||||
|
||||
@ -1006,51 +1044,53 @@ void CGlueMgr::Resume() {
|
||||
|
||||
DeleteInterfaceFiles();
|
||||
|
||||
MD5_CTX md5;
|
||||
unsigned char digest1[16];
|
||||
unsigned char digest2[16];
|
||||
uint8_t digest1[16];
|
||||
|
||||
int32_t v8;
|
||||
unsigned char* v9;
|
||||
unsigned char* v10;
|
||||
|
||||
MD5Init(&md5);
|
||||
|
||||
switch (FrameXML_CheckSignature("Interface\\GlueXML\\GlueXML.toc", 0, InterfaceKey, digest1)) {
|
||||
case 0:
|
||||
switch (FrameXML_CheckSignature("Interface\\GlueXML\\GlueXML.toc", nullptr, InterfaceKey, digest1)) {
|
||||
case 0: {
|
||||
status.Add(STATUS_WARNING, "GlueXML missing signature");
|
||||
ClientPostClose(9);
|
||||
return;
|
||||
|
||||
case 1:
|
||||
return;
|
||||
}
|
||||
|
||||
case 1: {
|
||||
status.Add(STATUS_WARNING, "GlueXML has corrupt signature");
|
||||
ClientPostClose(9);
|
||||
return;
|
||||
|
||||
case 2:
|
||||
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;
|
||||
|
||||
case 3: {
|
||||
// Success
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
default: {
|
||||
ClientPostClose(9);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
// - some kind of digest validation?
|
||||
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);
|
||||
|
||||
@ -1145,7 +1185,7 @@ void CGlueMgr::StatusDialogClick() {
|
||||
}
|
||||
|
||||
case IDLE_REALM_LIST:
|
||||
case IDLE_5:
|
||||
case IDLE_CREATE_CHARACTER:
|
||||
case IDLE_DELETE_CHARACTER:
|
||||
case IDLE_ENTER_WORLD: {
|
||||
ClientServices::Connection()->Cancel(2);
|
||||
@ -1203,6 +1243,10 @@ void CGlueMgr::Suspend() {
|
||||
|
||||
// TODO
|
||||
|
||||
SystemUnregisterFunctions();
|
||||
|
||||
// TODO
|
||||
|
||||
FrameXML_FreeHashNodes();
|
||||
|
||||
// TODO
|
||||
|
||||
@ -20,7 +20,7 @@ class CGlueMgr {
|
||||
IDLE_ACCOUNT_LOGIN = 2,
|
||||
IDLE_CHARACTER_LIST = 3,
|
||||
IDLE_REALM_LIST = 4,
|
||||
IDLE_5 = 5,
|
||||
IDLE_CREATE_CHARACTER = 5,
|
||||
IDLE_DELETE_CHARACTER = 6,
|
||||
IDLE_7 = 7,
|
||||
IDLE_8 = 8,
|
||||
@ -81,6 +81,7 @@ class CGlueMgr {
|
||||
static int32_t OnKickReasonMsg(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg);
|
||||
static void PollAccountLogin(int32_t errorCode, const char* msg, int32_t complete, int32_t result, WOWCS_OPS op);
|
||||
static void PollCharacterList(const char* msg, int32_t complete, int32_t result, int32_t errorCode);
|
||||
static void PollCreateCharacter(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 PollLoginServerLogin();
|
||||
|
||||
@ -17,7 +17,13 @@
|
||||
#include <cstdint>
|
||||
|
||||
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) {
|
||||
@ -198,7 +204,13 @@ int32_t Script_ShowTerminationWithoutNoticeNotice(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) {
|
||||
@ -528,36 +540,6 @@ int32_t Script_IsScanDLLFinished(lua_State* L) {
|
||||
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) {
|
||||
WHOA_UNIMPLEMENTED(0);
|
||||
}
|
||||
|
||||
@ -924,6 +924,10 @@ CGxPool* CGxDevice::PoolCreate(EGxPoolTarget target, EGxPoolUsage usage, uint32_
|
||||
return pool;
|
||||
}
|
||||
|
||||
void CGxDevice::RenderTargetGet(EGxBuffer buffer, CGxTex*& gxTex) {
|
||||
gxTex = this->m_textureTarget[buffer].m_texture;
|
||||
}
|
||||
|
||||
void CGxDevice::RsGet(EGxRenderState which, int32_t& value) {
|
||||
value = static_cast<int32_t>(this->m_appRenderStates[which].m_value);
|
||||
}
|
||||
|
||||
@ -38,6 +38,13 @@ struct ShaderConstants {
|
||||
|
||||
class CGxDevice {
|
||||
public:
|
||||
// Structs
|
||||
struct TextureTarget {
|
||||
CGxTex* m_texture;
|
||||
uint32_t m_plane;
|
||||
void* m_apiSpecific;
|
||||
};
|
||||
|
||||
// Static variables
|
||||
static uint32_t s_alphaRef[];
|
||||
static C3Vector s_pointScaleIdentity;
|
||||
@ -101,12 +108,12 @@ class CGxDevice {
|
||||
uint32_t m_appMasterEnables = 0;
|
||||
uint32_t m_hwMasterEnables = 0;
|
||||
TSList<CGxPool, TSGetLink<CGxPool>> m_poolList;
|
||||
CGxBuf* m_bufLocked[GxPoolTargets_Last];
|
||||
CGxBuf* m_bufLocked[GxPoolTargets_Last] = {};
|
||||
CGxPool* m_vertexPool = nullptr;
|
||||
CGxPool* m_indexPool = nullptr;
|
||||
CGxBuf* m_streamBufs[GxPoolTargets_Last];
|
||||
CGxBuf* m_streamBufs[GxPoolTargets_Last] = {};
|
||||
CGxVertexAttrib m_primVertexFormatAttrib[GxVertexBufferFormats_Last];
|
||||
CGxBuf* m_primVertexFormatBuf[GxVertexBufferFormats_Last];
|
||||
CGxBuf* m_primVertexFormatBuf[GxVertexBufferFormats_Last] = {};
|
||||
uint32_t m_primVertexMask = 0;
|
||||
uint32_t m_primVertexDirty = 0;
|
||||
EGxVertexBufferFormat m_primVertexFormat = GxVertexBufferFormats_Last;
|
||||
@ -116,6 +123,9 @@ class CGxDevice {
|
||||
int32_t m_primIndexDirty = 0;
|
||||
TSFixedArray<CGxAppRenderState> m_appRenderStates;
|
||||
TSFixedArray<CGxStateBom> m_hwRenderStates;
|
||||
// TODO
|
||||
TextureTarget m_textureTarget[GxBuffers_Last] = {};
|
||||
// TODO
|
||||
uint32_t m_baseMipLevel = 0; // TODO placeholder
|
||||
|
||||
// Virtual member functions
|
||||
@ -173,6 +183,7 @@ class CGxDevice {
|
||||
void PrimVertexFormat(CGxBuf*, CGxVertexAttrib*, uint32_t);
|
||||
void PrimVertexMask(uint32_t);
|
||||
void PrimVertexPtr(CGxBuf*, EGxVertexBufferFormat);
|
||||
void RenderTargetGet(EGxBuffer buffer, CGxTex*& gxTex);
|
||||
void RsGet(EGxRenderState, int32_t&);
|
||||
void RsSet(EGxRenderState, int32_t);
|
||||
void RsSet(EGxRenderState, void*);
|
||||
|
||||
6
src/gx/RenderTarget.cpp
Normal file
6
src/gx/RenderTarget.cpp
Normal 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
10
src/gx/RenderTarget.hpp
Normal 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
|
||||
@ -54,6 +54,12 @@ enum EGxBlend {
|
||||
GxBlends_Last = 12
|
||||
};
|
||||
|
||||
enum EGxBuffer {
|
||||
GxBuffers_Color = 0,
|
||||
GxBuffers_Depth = 1,
|
||||
GxBuffers_Last,
|
||||
};
|
||||
|
||||
enum EGxColorFormat {
|
||||
GxCF_argb = 0,
|
||||
GxCF_rgba = 1,
|
||||
|
||||
@ -1604,6 +1604,10 @@ void CM2Model::LinkToCallbackListTail() {
|
||||
this->m_shared->m_callbackListTail = &this->m_callbackNext;
|
||||
}
|
||||
|
||||
void CM2Model::OptimizeVisibleGeometry() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
int32_t CM2Model::ProcessCallbacks() {
|
||||
// TODO
|
||||
return 1;
|
||||
|
||||
@ -178,6 +178,7 @@ class CM2Model {
|
||||
int32_t IsDrawable(int32_t a2, int32_t a3);
|
||||
int32_t IsLoaded(int32_t a2, int32_t attachments);
|
||||
void LinkToCallbackListTail();
|
||||
void OptimizeVisibleGeometry();
|
||||
int32_t ProcessCallbacks();
|
||||
void ProcessCallbacksRecursive();
|
||||
uint32_t Release();
|
||||
|
||||
@ -60,11 +60,11 @@ enum NETMESSAGE {
|
||||
CMSG_AUTH_SRP6_BEGIN = 0x0033,
|
||||
CMSG_AUTH_SRP6_PROOF = 0x0034,
|
||||
CMSG_AUTH_SRP6_RECODE = 0x0035,
|
||||
CMSG_CREATE_CHARACTER = 0x0036,
|
||||
CMSG_CHAR_CREATE = 0x0036,
|
||||
CMSG_ENUM_CHARACTERS = 0x0037,
|
||||
CMSG_CHAR_DELETE = 0x0038,
|
||||
SMSG_AUTH_SRP6_RESPONSE = 0x0039,
|
||||
SMSG_CREATE_CHAR = 0x003A,
|
||||
SMSG_CHAR_CREATE = 0x003A,
|
||||
SMSG_ENUM_CHARACTERS_RESULT = 0x003B,
|
||||
SMSG_DELETE_CHAR = 0x003C,
|
||||
CMSG_PLAYER_LOGIN = 0x003D,
|
||||
|
||||
@ -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() {
|
||||
this->Complete(1, 5);
|
||||
|
||||
|
||||
@ -22,6 +22,8 @@ class ClientConnection : public RealmConnection {
|
||||
|
||||
// Virtual member functions
|
||||
virtual int32_t HandleConnect();
|
||||
virtual void HandleCharacterCreate(uint8_t result);
|
||||
virtual void HandleCharacterDelete(uint8_t result);
|
||||
|
||||
// Member functions
|
||||
ClientConnection(RealmResponse* realmResponse)
|
||||
|
||||
@ -19,8 +19,8 @@ int32_t RealmConnection::MessageHandler(void* param, NETMESSAGE msgId, uint32_t
|
||||
break;
|
||||
}
|
||||
|
||||
case SMSG_CREATE_CHAR: {
|
||||
// TODO
|
||||
case SMSG_CHAR_CREATE: {
|
||||
result = connection->CreateCharHandler(msgId, time, msg);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ int32_t RealmConnection::MessageHandler(void* param, NETMESSAGE msgId, uint32_t
|
||||
}
|
||||
|
||||
case SMSG_DELETE_CHAR: {
|
||||
// TODO
|
||||
result = connection->DeleteCharHandler(msgId, time, msg);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ RealmConnection::RealmConnection(RealmResponse* realmResponse) {
|
||||
this->SetMessageHandler(SMSG_AUTH_RESPONSE, &RealmConnection::MessageHandler, this);
|
||||
this->SetMessageHandler(SMSG_ADDON_INFO, &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_LOGOUT_COMPLETE, &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;
|
||||
}
|
||||
|
||||
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() {
|
||||
CDataStore msg;
|
||||
|
||||
|
||||
@ -46,11 +46,15 @@ class RealmConnection : public NetClient {
|
||||
|
||||
// Virtual member functions
|
||||
virtual int32_t HandleAuthChallenge(AuthenticationChallenge* challenge);
|
||||
virtual void HandleCharacterCreate(uint8_t result) = 0;
|
||||
virtual void HandleCharacterDelete(uint8_t result) = 0;
|
||||
|
||||
// Member functions
|
||||
RealmConnection(RealmResponse* realmResponse);
|
||||
int32_t HandleAuthResponse(uint32_t msgId, uint32_t time, CDataStore* msg);
|
||||
int32_t HandleCharEnum(uint32_t msgId, uint32_t time, CDataStore* msg);
|
||||
int32_t CreateCharHandler(uint32_t msgId, uint32_t time, CDataStore* msg);
|
||||
int32_t DeleteCharHandler(uint32_t msgId, uint32_t time, CDataStore* msg);
|
||||
void RequestCharacterEnum();
|
||||
void RequestCharacterLogin(uint64_t guid, int32_t a2);
|
||||
void SetSelectedRealm(uint32_t a2, uint32_t a3, uint32_t a4);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
file(GLOB PRIVATE_SOURCES
|
||||
"*.cpp"
|
||||
"client/*.cpp"
|
||||
"movement/*.cpp"
|
||||
)
|
||||
|
||||
add_library(object STATIC
|
||||
@ -15,4 +16,5 @@ target_include_directories(object
|
||||
target_link_libraries(object
|
||||
PRIVATE
|
||||
db
|
||||
ui
|
||||
)
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#ifndef OBJECT_CLIENT_HPP
|
||||
#define OBJECT_CLIENT_HPP
|
||||
|
||||
#include "client/CGPlayer_C.hpp"
|
||||
#include "client/ObjMgr.hpp"
|
||||
#include "object/Types.hpp"
|
||||
|
||||
|
||||
@ -72,6 +72,17 @@ enum OBJECT_TYPE_ID {
|
||||
// TODO
|
||||
};
|
||||
|
||||
enum OUT_OF_RANGE_TYPE {
|
||||
OUT_OF_RANGE_0 = 0,
|
||||
OUT_OF_RANGE_1 = 1,
|
||||
OUT_OF_RANGE_2 = 2,
|
||||
};
|
||||
|
||||
enum PLAYER_TYPE {
|
||||
PLAYER_NORMAL = 0,
|
||||
PLAYER_BOT = 1,
|
||||
};
|
||||
|
||||
enum SHEATHE_TYPE {
|
||||
SHEATHE_0 = 0,
|
||||
SHEATHE_1 = 1,
|
||||
|
||||
32
src/object/client/CClientMoveUpdate.cpp
Normal file
32
src/object/client/CClientMoveUpdate.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
#include "object/client/CClientMoveUpdate.hpp"
|
||||
|
||||
void CClientMoveUpdate::Skip(CDataStore* msg) {
|
||||
uint32_t moveFlags = CMovementStatus::Skip(msg);
|
||||
|
||||
void* data;
|
||||
msg->GetDataInSitu(data, 9 * sizeof(float));
|
||||
|
||||
if (moveFlags & 0x8000000) {
|
||||
CMoveSpline::Skip(msg);
|
||||
}
|
||||
}
|
||||
|
||||
CDataStore& operator>>(CDataStore& msg, CClientMoveUpdate& move) {
|
||||
msg >> move.status;
|
||||
|
||||
msg.Get(move.float60);
|
||||
msg.Get(move.float64);
|
||||
msg.Get(move.float68);
|
||||
msg.Get(move.float6C);
|
||||
msg.Get(move.float70);
|
||||
msg.Get(move.float74);
|
||||
msg.Get(move.float78);
|
||||
msg.Get(move.float7C);
|
||||
msg.Get(move.float80);
|
||||
|
||||
if (move.status.moveFlags & 0x8000000) {
|
||||
msg >> move.spline;
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
27
src/object/client/CClientMoveUpdate.hpp
Normal file
27
src/object/client/CClientMoveUpdate.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef OBJECT_CLIENT_C_CLIENT_MOVE_UPDATE_HPP
|
||||
#define OBJECT_CLIENT_C_CLIENT_MOVE_UPDATE_HPP
|
||||
|
||||
#include "object/movement/CMovementStatus.hpp"
|
||||
#include "object/movement/CMoveSpline.hpp"
|
||||
#include <common/datastore/CDataStore.hpp>
|
||||
|
||||
struct CClientMoveUpdate {
|
||||
CMovementStatus status;
|
||||
float float60;
|
||||
float float64;
|
||||
float float68;
|
||||
float float6C;
|
||||
float float70;
|
||||
float float74;
|
||||
float float78;
|
||||
float float7C;
|
||||
float float80;
|
||||
// TODO
|
||||
CMoveSpline spline;
|
||||
|
||||
static void Skip(CDataStore* msg);
|
||||
};
|
||||
|
||||
CDataStore& operator>>(CDataStore& msg, CClientMoveUpdate& move);
|
||||
|
||||
#endif
|
||||
133
src/object/client/CClientObjCreate.cpp
Normal file
133
src/object/client/CClientObjCreate.cpp
Normal file
@ -0,0 +1,133 @@
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "util/DataStore.hpp"
|
||||
#include "util/GUID.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include <common/DataStore.hpp>
|
||||
|
||||
void CClientObjCreate::Skip(CDataStore* msg) {
|
||||
uint16_t flags;
|
||||
msg->Get(flags);
|
||||
|
||||
if (flags & 0x20) {
|
||||
CClientMoveUpdate::Skip(msg);
|
||||
} else if (flags & 0x100) {
|
||||
SmartGUID guid;
|
||||
*msg >> guid;
|
||||
|
||||
C3Vector position28;
|
||||
*msg >> position28;
|
||||
|
||||
C3Vector position18;
|
||||
*msg >> position18;
|
||||
|
||||
float facing34;
|
||||
msg->Get(facing34);
|
||||
|
||||
float facing24;
|
||||
msg->Get(facing24);
|
||||
} else if (flags & 0x40) {
|
||||
C3Vector position28;
|
||||
*msg >> position28;
|
||||
|
||||
float facing34;
|
||||
msg->Get(facing34);
|
||||
}
|
||||
|
||||
if (flags & 0x8) {
|
||||
uint32_t uint2AC;
|
||||
msg->Get(uint2AC);
|
||||
}
|
||||
|
||||
if (flags & 0x10) {
|
||||
uint32_t uint2B0;
|
||||
msg->Get(uint2B0);
|
||||
}
|
||||
|
||||
if (flags & 0x4) {
|
||||
SmartGUID guid2B8;
|
||||
*msg >> guid2B8;
|
||||
}
|
||||
|
||||
if (flags & 0x2) {
|
||||
uint32_t uint2C0;
|
||||
msg->Get(uint2C0);
|
||||
}
|
||||
|
||||
if (flags & 0x80) {
|
||||
uint32_t uint2C4;
|
||||
msg->Get(uint2C4);
|
||||
|
||||
float float2C8;
|
||||
msg->Get(float2C8);
|
||||
}
|
||||
|
||||
if (flags & 0x200) {
|
||||
uint64_t uint2D4;
|
||||
msg->Get(uint2D4);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t CClientObjCreate::Get(CDataStore* msg) {
|
||||
uint16_t flags;
|
||||
msg->Get(flags);
|
||||
|
||||
this->flags = flags;
|
||||
|
||||
if (this->flags & 0x20) {
|
||||
*msg >> this->move;
|
||||
} else if (this->flags & 0x100) {
|
||||
SmartGUID guid;
|
||||
*msg >> guid;
|
||||
this->move.status.transport = guid;
|
||||
|
||||
*msg >> this->move.status.position28;
|
||||
*msg >> this->move.status.position18;
|
||||
|
||||
msg->Get(this->move.status.facing34);
|
||||
msg->Get(this->move.status.facing24);
|
||||
} else if (this->flags & 0x40) {
|
||||
this->move.status.transport = 0;
|
||||
|
||||
*msg >> this->move.status.position28;
|
||||
this->move.status.position18 = this->move.status.position28;
|
||||
|
||||
msg->Get(this->move.status.facing34);
|
||||
}
|
||||
|
||||
if (this->flags & 0x8) {
|
||||
msg->Get(this->uint2AC);
|
||||
} else {
|
||||
this->uint2AC = 0;
|
||||
}
|
||||
|
||||
if (this->flags & 0x10) {
|
||||
msg->Get(this->uint2B0);
|
||||
} else {
|
||||
this->uint2B0 = 0;
|
||||
}
|
||||
|
||||
if (this->flags & 0x4) {
|
||||
SmartGUID guid;
|
||||
*msg >> guid;
|
||||
this->guid2B8 = guid;
|
||||
} else {
|
||||
this->guid2B8 = 0;
|
||||
}
|
||||
|
||||
if (this->flags & 0x2) {
|
||||
msg->Get(this->uint2C0);
|
||||
}
|
||||
|
||||
if (this->flags & 0x80) {
|
||||
msg->Get(this->uint2C4);
|
||||
msg->Get(this->float2C8);
|
||||
}
|
||||
|
||||
if (this->flags & 0x200) {
|
||||
msg->Get(this->uint2D4);
|
||||
} else {
|
||||
this->uint2D4 = 0;
|
||||
}
|
||||
|
||||
return msg->Size() >= msg->Tell();
|
||||
}
|
||||
27
src/object/client/CClientObjCreate.hpp
Normal file
27
src/object/client/CClientObjCreate.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef OBJECT_CLIENT_C_CLIENT_OBJ_CREATE_HPP
|
||||
#define OBJECT_CLIENT_C_CLIENT_OBJ_CREATE_HPP
|
||||
|
||||
#include "object/client/CClientMoveUpdate.hpp"
|
||||
#include "util/GUID.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
class CDataStore;
|
||||
|
||||
struct CClientObjCreate {
|
||||
CClientMoveUpdate move;
|
||||
uint32_t flags = 0x0;
|
||||
uint32_t uint2AC;
|
||||
uint32_t uint2B0;
|
||||
// TODO
|
||||
WOWGUID guid2B8 = 0;
|
||||
uint32_t uint2C0;
|
||||
uint32_t uint2C4;
|
||||
float float2C8;
|
||||
// TODO
|
||||
uint64_t uint2D4 = 0; // TODO guid?
|
||||
|
||||
static void Skip(CDataStore* msg);
|
||||
int32_t Get(CDataStore* msg);
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -24,3 +24,7 @@ uint32_t CGContainer::TotalFields() {
|
||||
uint32_t CGContainer::TotalFieldsSaved() {
|
||||
return CGContainer::GetBaseOffsetSaved() + 72;
|
||||
}
|
||||
|
||||
CGContainerData* CGContainer::Container() const {
|
||||
return this->m_cont;
|
||||
}
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
#ifndef OBJECT_CLIENT_CG_CONTAINER_HPP
|
||||
#define OBJECT_CLIENT_CG_CONTAINER_HPP
|
||||
|
||||
#include "util/GUID.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
struct CGContainerData {
|
||||
uint32_t numSlots;
|
||||
uint32_t pad;
|
||||
uint64_t slots[36];
|
||||
WOWGUID slots[36];
|
||||
};
|
||||
|
||||
class CGContainer {
|
||||
@ -19,9 +20,13 @@ class CGContainer {
|
||||
static uint32_t TotalFields();
|
||||
static uint32_t TotalFieldsSaved();
|
||||
|
||||
// Public member variables
|
||||
protected:
|
||||
// Protected member variables
|
||||
CGContainerData* m_cont;
|
||||
uint32_t* m_contSaved;
|
||||
|
||||
// Protected member functions
|
||||
CGContainerData* Container() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,5 +1,13 @@
|
||||
#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) {
|
||||
this->CGItem_C::SetStorage(storage, saved);
|
||||
|
||||
|
||||
@ -1,12 +1,17 @@
|
||||
#ifndef OBJECT_CLIENT_CG_CONTAINER_C_HPP
|
||||
#define OBJECT_CLIENT_CG_CONTAINER_C_HPP
|
||||
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGContainer.hpp"
|
||||
#include "object/client/CGItem_C.hpp"
|
||||
|
||||
class CGContainer_C : public CGItem_C, public CGContainer {
|
||||
public:
|
||||
// Virtual public member functions
|
||||
virtual ~CGContainer_C();
|
||||
|
||||
// Public member functions
|
||||
CGContainer_C(uint32_t time, CClientObjCreate& objCreate);
|
||||
void SetStorage(uint32_t* storage, uint32_t* saved);
|
||||
};
|
||||
|
||||
|
||||
@ -24,3 +24,7 @@ uint32_t CGCorpse::TotalFields() {
|
||||
uint32_t CGCorpse::TotalFieldsSaved() {
|
||||
return CGCorpse::GetBaseOffsetSaved() + 3;
|
||||
}
|
||||
|
||||
CGCorpseData* CGCorpse::Corpse() const {
|
||||
return this->m_corpse;
|
||||
}
|
||||
|
||||
@ -17,9 +17,13 @@ class CGCorpse {
|
||||
static uint32_t TotalFields();
|
||||
static uint32_t TotalFieldsSaved();
|
||||
|
||||
// Public member variables
|
||||
protected:
|
||||
// Protected member variables
|
||||
CGCorpseData* m_corpse;
|
||||
uint32_t* m_corpseSaved;
|
||||
|
||||
// Protected member functions
|
||||
CGCorpseData* Corpse() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,5 +1,21 @@
|
||||
#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) {
|
||||
this->CGObject_C::SetStorage(storage, saved);
|
||||
|
||||
|
||||
@ -1,12 +1,18 @@
|
||||
#ifndef OBJECT_CLIENT_CG_CORPSE_C_HPP
|
||||
#define OBJECT_CLIENT_CG_CORPSE_C_HPP
|
||||
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGCorpse.hpp"
|
||||
#include "object/client/CGObject_C.hpp"
|
||||
|
||||
class CGCorpse_C : public CGObject_C, public CGCorpse {
|
||||
public:
|
||||
// Virtual public member functions
|
||||
virtual ~CGCorpse_C();
|
||||
|
||||
// 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);
|
||||
};
|
||||
|
||||
|
||||
@ -24,3 +24,7 @@ uint32_t CGDynamicObject::TotalFields() {
|
||||
uint32_t CGDynamicObject::TotalFieldsSaved() {
|
||||
return CGDynamicObject::GetBaseOffsetSaved() + 0;
|
||||
}
|
||||
|
||||
CGDynamicObjectData* CGDynamicObject::DynamicObject() const {
|
||||
return this->m_dynamicObj;
|
||||
}
|
||||
|
||||
@ -17,9 +17,13 @@ class CGDynamicObject {
|
||||
static uint32_t TotalFields();
|
||||
static uint32_t TotalFieldsSaved();
|
||||
|
||||
// Public member variables
|
||||
protected:
|
||||
// Protected member variables
|
||||
CGDynamicObjectData* m_dynamicObj;
|
||||
uint32_t* m_dynamicObjSaved;
|
||||
|
||||
// Protected member functions
|
||||
CGDynamicObjectData* DynamicObject() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,5 +1,21 @@
|
||||
#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) {
|
||||
this->CGObject_C::SetStorage(storage, saved);
|
||||
|
||||
|
||||
@ -1,12 +1,18 @@
|
||||
#ifndef OBJECT_CLIENT_CG_DYNAMIC_OBJECT_C_HPP
|
||||
#define OBJECT_CLIENT_CG_DYNAMIC_OBJECT_C_HPP
|
||||
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGDynamicObject.hpp"
|
||||
#include "object/client/CGObject_C.hpp"
|
||||
|
||||
class CGDynamicObject_C : public CGObject_C, public CGDynamicObject {
|
||||
public:
|
||||
// Virtual public member functions
|
||||
virtual ~CGDynamicObject_C();
|
||||
|
||||
// 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);
|
||||
};
|
||||
|
||||
|
||||
@ -24,3 +24,7 @@ uint32_t CGGameObject::TotalFields() {
|
||||
uint32_t CGGameObject::TotalFieldsSaved() {
|
||||
return CGGameObject::GetBaseOffsetSaved() + 4;
|
||||
}
|
||||
|
||||
CGGameObjectData* CGGameObject::GameObject() const {
|
||||
return this->m_gameObj;
|
||||
}
|
||||
|
||||
@ -17,9 +17,13 @@ class CGGameObject {
|
||||
static uint32_t TotalFields();
|
||||
static uint32_t TotalFieldsSaved();
|
||||
|
||||
// Public member variables
|
||||
protected:
|
||||
// Protected member variables
|
||||
CGGameObjectData* m_gameObj;
|
||||
uint32_t* m_gameObjSaved;
|
||||
|
||||
// Protected member functions
|
||||
CGGameObjectData* GameObject() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,5 +1,21 @@
|
||||
#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) {
|
||||
this->CGObject_C::SetStorage(storage, saved);
|
||||
|
||||
|
||||
@ -1,12 +1,18 @@
|
||||
#ifndef OBJECT_CLIENT_CG_GAME_OBJECT_C_HPP
|
||||
#define OBJECT_CLIENT_CG_GAME_OBJECT_C_HPP
|
||||
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGGameObject.hpp"
|
||||
#include "object/client/CGObject_C.hpp"
|
||||
|
||||
class CGGameObject_C : public CGObject_C, public CGGameObject {
|
||||
public:
|
||||
// Virtual public member functions
|
||||
virtual ~CGGameObject_C();
|
||||
|
||||
// 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);
|
||||
};
|
||||
|
||||
|
||||
@ -24,3 +24,7 @@ uint32_t CGItem::TotalFields() {
|
||||
uint32_t CGItem::TotalFieldsSaved() {
|
||||
return CGItem::GetBaseOffsetSaved() + 47;
|
||||
}
|
||||
|
||||
CGItemData* CGItem::Item() const {
|
||||
return this->m_item;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#ifndef OBJECT_CLIENT_CG_ITEM_HPP
|
||||
#define OBJECT_CLIENT_CG_ITEM_HPP
|
||||
|
||||
#include "util/GUID.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
struct ItemEnchantment {
|
||||
@ -10,10 +11,10 @@ struct ItemEnchantment {
|
||||
};
|
||||
|
||||
struct CGItemData {
|
||||
uint64_t owner;
|
||||
uint64_t containedIn;
|
||||
uint64_t creator;
|
||||
uint64_t giftCreator;
|
||||
WOWGUID owner;
|
||||
WOWGUID containedIn;
|
||||
WOWGUID creator;
|
||||
WOWGUID giftCreator;
|
||||
uint32_t stackCount;
|
||||
int32_t expiration;
|
||||
int32_t spellCharges[5];
|
||||
@ -37,9 +38,13 @@ class CGItem {
|
||||
static uint32_t TotalFields();
|
||||
static uint32_t TotalFieldsSaved();
|
||||
|
||||
// Public member variables
|
||||
protected:
|
||||
// Protected member variables
|
||||
CGItemData* m_item;
|
||||
uint32_t* m_itemSaved;
|
||||
|
||||
// Protected member functions
|
||||
CGItemData* Item() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,5 +1,19 @@
|
||||
#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) {
|
||||
this->CGObject_C::SetStorage(storage, saved);
|
||||
|
||||
|
||||
@ -1,12 +1,18 @@
|
||||
#ifndef OBJECT_CLIENT_CG_ITEM_C_HPP
|
||||
#define OBJECT_CLIENT_CG_ITEM_C_HPP
|
||||
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGObject_C.hpp"
|
||||
#include "object/client/CGItem.hpp"
|
||||
|
||||
class CGItem_C : public CGObject_C, public CGItem {
|
||||
public:
|
||||
// Virtual public member functions
|
||||
virtual ~CGItem_C();
|
||||
|
||||
// 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);
|
||||
};
|
||||
|
||||
|
||||
@ -23,3 +23,27 @@ uint32_t CGObject::TotalFields() {
|
||||
uint32_t CGObject::TotalFieldsSaved() {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -2,10 +2,11 @@
|
||||
#define OBJECT_CLIENT_CG_OBJECT_HPP
|
||||
|
||||
#include "object/Types.hpp"
|
||||
#include "util/GUID.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
struct CGObjectData {
|
||||
uint64_t m_guid;
|
||||
WOWGUID m_guid;
|
||||
OBJECT_TYPE m_type;
|
||||
int32_t m_entryID;
|
||||
float m_scale;
|
||||
@ -24,10 +25,23 @@ class CGObject {
|
||||
|
||||
// Public member variables
|
||||
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;
|
||||
uint32_t* m_objSaved;
|
||||
uint32_t m_memHandle;
|
||||
OBJECT_TYPE_ID m_typeID;
|
||||
|
||||
// Protected member functions
|
||||
CGObjectData* Obj() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,4 +1,188 @@
|
||||
#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) {
|
||||
this->m_obj = reinterpret_cast<CGObjectData*>(&storage[CGObject::GetBaseOffset()]);
|
||||
@ -45,3 +229,7 @@ void CGObject_C::SetTypeID(OBJECT_TYPE_ID typeID) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CGObject_C::UpdateWorldObject(int32_t a2) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@ -1,14 +1,64 @@
|
||||
#ifndef OBJECT_CLIENT_CG_OBJECT_C_HPP
|
||||
#define OBJECT_CLIENT_CG_OBJECT_C_HPP
|
||||
|
||||
#include "object/client/CGObject.hpp"
|
||||
#include "object/Types.hpp"
|
||||
#include "util/CHashKeyGUID.hpp"
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGObject.hpp"
|
||||
#include "util/GUID.hpp"
|
||||
#include "world/Types.hpp"
|
||||
#include <storm/Hash.hpp>
|
||||
#include <storm/List.hpp>
|
||||
|
||||
class CM2Model;
|
||||
|
||||
class CGObject_C : public CGObject, public TSHashObject<CGObject_C, CHashKeyGUID> {
|
||||
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
|
||||
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 SetTypeID(OBJECT_TYPE_ID typeID);
|
||||
};
|
||||
|
||||
@ -40,3 +40,19 @@ uint32_t CGPlayer::TotalFieldsSaved() {
|
||||
uint32_t CGPlayer::TotalRemoteFieldsSaved() {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define OBJECT_CLIENT_CG_PLAYER_HPP
|
||||
|
||||
#include "object/Types.hpp"
|
||||
#include "util/GUID.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
struct CQuestLogData {
|
||||
@ -18,36 +19,119 @@ struct CVisibleItemData {
|
||||
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 {
|
||||
uint64_t duelArbiter;
|
||||
WOWGUID duelArbiter;
|
||||
uint32_t flags;
|
||||
uint32_t guildID;
|
||||
uint32_t guildRank;
|
||||
int32_t pad1;
|
||||
int32_t pad2;
|
||||
int32_t pad3;
|
||||
uint8_t skinID;
|
||||
uint8_t faceID;
|
||||
uint8_t hairStyleID;
|
||||
uint8_t hairColorID;
|
||||
uint8_t facialHairStyleID;
|
||||
uint8_t bytes_2_2; // TODO
|
||||
uint8_t bytes_2_3; // TODO
|
||||
uint8_t restState;
|
||||
uint8_t bytes_3_1; // TODO
|
||||
uint8_t bytes_3_2; // TODO
|
||||
uint8_t bytes_3_3; // TODO
|
||||
uint8_t bytes_3_4; // TODO
|
||||
uint32_t duelTeam;
|
||||
int32_t guildTimestamp;
|
||||
CQuestLogData questLog[25];
|
||||
CVisibleItemData visibleItems[19];
|
||||
int32_t chosenTitle;
|
||||
int32_t fakeInebriation;
|
||||
int32_t pad4;
|
||||
uint64_t invSlots[NUM_INVENTORY_SLOTS];
|
||||
uint64_t packSlots[16];
|
||||
uint64_t bankSlots[28];
|
||||
uint64_t bankBagSlots[7];
|
||||
uint64_t vendorBuybackSlots[12];
|
||||
uint64_t keyringSlots[32];
|
||||
uint64_t currencyTokenSlots[32];
|
||||
uint64_t farsightObject;
|
||||
uint64_t knownTitles;
|
||||
uint64_t knownTitles2;
|
||||
uint64_t knownTitles3;
|
||||
uint64_t knownCurrencies;
|
||||
int32_t pad1;
|
||||
WOWGUID invSlots[NUM_INVENTORY_SLOTS];
|
||||
WOWGUID packSlots[16];
|
||||
WOWGUID bankSlots[28];
|
||||
WOWGUID bankBagSlots[7];
|
||||
WOWGUID vendorBuybackSlots[12];
|
||||
WOWGUID keyringSlots[32];
|
||||
WOWGUID currencyTokenSlots[32];
|
||||
WOWGUID farsightObject;
|
||||
WOWGUID knownTitles;
|
||||
WOWGUID knownTitles2;
|
||||
WOWGUID knownTitles3;
|
||||
WOWGUID knownCurrencies;
|
||||
uint32_t xp;
|
||||
uint32_t nextLevelXP;
|
||||
// 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 {
|
||||
@ -64,9 +148,18 @@ class CGPlayer {
|
||||
static uint32_t TotalFieldsSaved();
|
||||
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;
|
||||
uint32_t* m_playerSaved;
|
||||
|
||||
// Protected member functions
|
||||
CGPlayerData* Player() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,8 +1,85 @@
|
||||
#include "object/client/CGPlayer_C.hpp"
|
||||
#include "db/Db.hpp"
|
||||
#include "object/Types.hpp"
|
||||
#include "object/client/ObjMgr.hpp"
|
||||
#include "ui/FrameScript.hpp"
|
||||
#include "ui/Game.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) {
|
||||
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()];
|
||||
}
|
||||
|
||||
void CGPlayer_C::UpdatePartyMemberState() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
uint32_t Player_C_GetDisplayId(uint32_t race, uint32_t sex) {
|
||||
STORM_ASSERT(sex < UNITSEX_LAST);
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#ifndef OBJECT_CLIENT_CG_PLAYER_C_HPP
|
||||
#define OBJECT_CLIENT_CG_PLAYER_C_HPP
|
||||
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGPlayer.hpp"
|
||||
#include "object/client/CGUnit_C.hpp"
|
||||
#include <cstdint>
|
||||
@ -9,8 +10,21 @@ class CreatureModelDataRec;
|
||||
|
||||
class CGPlayer_C : public CGUnit_C, public CGPlayer {
|
||||
public:
|
||||
// Public static functions
|
||||
static CGPlayer_C* GetActivePtr();
|
||||
|
||||
// Virtual public member functions
|
||||
virtual ~CGPlayer_C();
|
||||
|
||||
// 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 UpdatePartyMemberState();
|
||||
};
|
||||
|
||||
uint32_t Player_C_GetDisplayId(uint32_t race, uint32_t sex);
|
||||
|
||||
@ -24,3 +24,15 @@ uint32_t CGUnit::TotalFields() {
|
||||
uint32_t CGUnit::TotalFieldsSaved() {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1,24 +1,25 @@
|
||||
#ifndef OBJECT_CLIENT_CG_UNIT_HPP
|
||||
#define OBJECT_CLIENT_CG_UNIT_HPP
|
||||
|
||||
#include "util/GUID.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
struct CGUnitData {
|
||||
uint64_t charm;
|
||||
uint64_t summon;
|
||||
uint64_t critter;
|
||||
uint64_t charmedBy;
|
||||
uint64_t summonedBy;
|
||||
uint64_t createdBy;
|
||||
uint64_t target;
|
||||
uint64_t channelObject;
|
||||
WOWGUID charm;
|
||||
WOWGUID summon;
|
||||
WOWGUID critter;
|
||||
WOWGUID charmedBy;
|
||||
WOWGUID summonedBy;
|
||||
WOWGUID createdBy;
|
||||
WOWGUID target;
|
||||
WOWGUID channelObject;
|
||||
int32_t channelSpell;
|
||||
int32_t pad1;
|
||||
int32_t health;
|
||||
int32_t power[7];
|
||||
int32_t maxHealth;
|
||||
int32_t maxPower[7];
|
||||
int32_t powerRegenFlatModifier[7];
|
||||
float powerRegenFlatModifier[7];
|
||||
int32_t powerRegenInterruptedFlatModifier[7];
|
||||
int32_t level;
|
||||
int32_t factionTemplate;
|
||||
@ -33,8 +34,8 @@ struct CGUnitData {
|
||||
int32_t displayID;
|
||||
int32_t nativeDisplayID;
|
||||
int32_t mountDisplayID;
|
||||
uint32_t minDamage;
|
||||
uint32_t maxDamage;
|
||||
float minDamage;
|
||||
float maxDamage;
|
||||
uint32_t minOffhandDamage;
|
||||
uint32_t maxOffhandDamage;
|
||||
int32_t pad2;
|
||||
@ -43,7 +44,7 @@ struct CGUnitData {
|
||||
uint32_t petExperience;
|
||||
uint32_t petNextLevelExperience;
|
||||
uint32_t dynamicFlags;
|
||||
int32_t modCastingSpeed;
|
||||
float modCastingSpeed;
|
||||
int32_t createdBySpell;
|
||||
uint32_t npcFlags;
|
||||
uint32_t emoteState;
|
||||
@ -62,12 +63,12 @@ struct CGUnitData {
|
||||
int32_t rangedAttackPower;
|
||||
int32_t rangedAttackPowerMods;
|
||||
int32_t rangedAttackPowerMultiplier;
|
||||
int32_t minRangedDamage;
|
||||
int32_t maxRangedDamage;
|
||||
float minRangedDamage;
|
||||
float maxRangedDamage;
|
||||
int32_t powerCostModifier[7];
|
||||
int32_t powerCostMultiplier[7];
|
||||
int32_t maxHealthModifier;
|
||||
int32_t hoverHeight;
|
||||
float hoverHeight;
|
||||
int32_t pad4;
|
||||
};
|
||||
|
||||
@ -81,9 +82,17 @@ class CGUnit {
|
||||
static uint32_t TotalFields();
|
||||
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;
|
||||
uint32_t* m_unitSaved;
|
||||
|
||||
// Protected member functions
|
||||
CGUnitData* Unit() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,5 +1,12 @@
|
||||
#include "object/client/CGUnit_C.hpp"
|
||||
#include "component/CCharacterComponent.hpp"
|
||||
#include "model/Model2.hpp"
|
||||
#include "object/client/ObjMgr.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) {
|
||||
if (displaySex) {
|
||||
@ -89,6 +96,161 @@ const char* CGUnit_C::GetDisplayRaceNameFromRecord(const ChrRacesRec* raceRec, U
|
||||
return raceRec->m_name;
|
||||
}
|
||||
|
||||
CGUnit_C::CGUnit_C(uint32_t time, CClientObjCreate& objCreate) : CGObject_C(time, objCreate) {
|
||||
// TODO
|
||||
|
||||
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) {
|
||||
this->CGObject_C::SetStorage(storage, saved);
|
||||
|
||||
|
||||
@ -1,21 +1,63 @@
|
||||
#ifndef OBJECT_CLIENT_CG_UNIT_C_HPP
|
||||
#define OBJECT_CLIENT_CG_UNIT_C_HPP
|
||||
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGObject_C.hpp"
|
||||
#include "object/client/CGUnit.hpp"
|
||||
#include "object/Types.hpp"
|
||||
#include "util/GUID.hpp"
|
||||
|
||||
class ChrClassesRec;
|
||||
class ChrRacesRec;
|
||||
class CreatureDisplayInfoRec;
|
||||
class CreatureDisplayInfoExtraRec;
|
||||
class CreatureModelDataRec;
|
||||
class CreatureSoundDataRec;
|
||||
class UnitBloodLevelsRec;
|
||||
|
||||
class CGUnit_C : public CGObject_C, public CGUnit {
|
||||
public:
|
||||
// Public static variables
|
||||
static WOWGUID s_activeMover;
|
||||
|
||||
// Public static functions
|
||||
static const char* GetDisplayClassNameFromRecord(const ChrClassesRec* classRec, UNIT_SEX sex, UNIT_SEX* displaySex);
|
||||
static const char* GetDisplayRaceNameFromRecord(const ChrRacesRec* raceRec, UNIT_SEX sex, UNIT_SEX* displaySex);
|
||||
|
||||
// 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
|
||||
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);
|
||||
|
||||
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
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
#ifndef OBJECT_CLIENT_CLNT_OBJ_MGR_HPP
|
||||
#define OBJECT_CLIENT_CLNT_OBJ_MGR_HPP
|
||||
|
||||
#include "object/client/CGObject_C.hpp"
|
||||
#include <storm/Hash.hpp>
|
||||
#include <storm/List.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
class ClientConnection;
|
||||
@ -8,9 +11,19 @@ class ClientConnection;
|
||||
class ClntObjMgr {
|
||||
public:
|
||||
// Member variables
|
||||
uint64_t m_activePlayer = 0;
|
||||
TSHashTable<CGObject_C, CHashKeyGUID> m_objects;
|
||||
TSHashTable<CGObject_C, CHashKeyGUID> m_lazyCleanupObjects;
|
||||
STORM_EXPLICIT_LIST(CGObject_C, m_link) m_lazyCleanupFifo[NUM_CLIENT_OBJECT_TYPES - 1];
|
||||
STORM_EXPLICIT_LIST(CGObject_C, m_link) m_visibleObjects;
|
||||
STORM_EXPLICIT_LIST(CGObject_C, m_link) m_reenabledObjects;
|
||||
// TODO
|
||||
WOWGUID m_activePlayer = 0;
|
||||
PLAYER_TYPE m_type;
|
||||
uint32_t m_mapID = 0;
|
||||
ClientConnection* m_net = nullptr;
|
||||
|
||||
// Member functions
|
||||
ClntObjMgr(PLAYER_TYPE type) : m_type(type) {};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,9 +1,492 @@
|
||||
#include "object/client/MessageHandlers.hpp"
|
||||
#include "object/client/CClientObjCreate.hpp"
|
||||
#include "object/client/CGContainer_C.hpp"
|
||||
#include "object/client/CGCorpse_C.hpp"
|
||||
#include "object/client/CGDynamicObject_C.hpp"
|
||||
#include "object/client/CGGameObject_C.hpp"
|
||||
#include "object/client/CGItem_C.hpp"
|
||||
#include "object/client/CGObject_C.hpp"
|
||||
#include "object/client/CGPlayer_C.hpp"
|
||||
#include "object/client/CGUnit_C.hpp"
|
||||
#include "object/client/Mirror.hpp"
|
||||
#include "object/client/ObjMgr.hpp"
|
||||
#include "object/client/Util.hpp"
|
||||
#include "util/GUID.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include "util/Zlib.hpp"
|
||||
#include <common/DataStore.hpp>
|
||||
#include <storm/Error.hpp>
|
||||
#include <storm/Memory.hpp>
|
||||
#include <new>
|
||||
|
||||
enum UPDATE_TYPE {
|
||||
UPDATE_PARTIAL = 0,
|
||||
UPDATE_MOVEMENT = 1,
|
||||
UPDATE_FULL = 2,
|
||||
UPDATE_3 = 3,
|
||||
UPDATE_OUT_OF_RANGE = 4,
|
||||
UPDATE_IN_RANGE = 5,
|
||||
};
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
248
src/object/client/Mirror.cpp
Normal file
248
src/object/client/Mirror.cpp
Normal 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;
|
||||
}
|
||||
16
src/object/client/Mirror.hpp
Normal file
16
src/object/client/Mirror.hpp
Normal 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
|
||||
@ -11,6 +11,7 @@
|
||||
#include "object/client/CGPlayer_C.hpp"
|
||||
#include "object/client/CGUnit_C.hpp"
|
||||
#include "object/client/MessageHandlers.hpp"
|
||||
#include "object/client/Util.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include <common/ObjectAlloc.hpp>
|
||||
#include <storm/Memory.hpp>
|
||||
@ -66,15 +67,15 @@ void MirrorInitialize() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void* ClntObjMgrAllocObject(OBJECT_TYPE_ID typeID, uint64_t guid) {
|
||||
CGObject_C* ClntObjMgrAllocObject(OBJECT_TYPE_ID typeID, WOWGUID guid) {
|
||||
auto playerGUID = ClntObjMgrGetActivePlayer();
|
||||
|
||||
// Heap allocate player object for current player
|
||||
if (guid == playerGUID) {
|
||||
return STORM_ALLOC(sizeof(CGPlayer_C) + 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;
|
||||
void* mem;
|
||||
@ -84,12 +85,43 @@ void* ClntObjMgrAllocObject(OBJECT_TYPE_ID typeID, uint64_t guid) {
|
||||
}
|
||||
|
||||
// TODO pointer should be fetched via ObjectPtr
|
||||
static_cast<CGObject_C*>(mem)->m_memHandle = memHandle;
|
||||
auto object = static_cast<CGObject_C*>(mem);
|
||||
object->m_memHandle = memHandle;
|
||||
|
||||
return mem;
|
||||
return object;
|
||||
}
|
||||
|
||||
uint64_t ClntObjMgrGetActivePlayer() {
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
@ -109,6 +141,10 @@ uint32_t ClntObjMgrGetMapID() {
|
||||
return s_curMgr->m_mapID;
|
||||
}
|
||||
|
||||
PLAYER_TYPE ClntObjMgrGetPlayerType() {
|
||||
return s_curMgr->m_type;
|
||||
}
|
||||
|
||||
void ClntObjMgrInitializeShared() {
|
||||
if (!s_heapsAllocated) {
|
||||
for (int32_t i = ID_ITEM; i < NUM_CLIENT_OBJECT_TYPES; i++) {
|
||||
@ -126,7 +162,7 @@ void ClntObjMgrInitializeShared() {
|
||||
void ClntObjMgrInitializeStd(uint32_t mapID) {
|
||||
// TODO last instance time
|
||||
|
||||
auto mgr = STORM_NEW(ClntObjMgr);
|
||||
auto mgr = STORM_NEW(ClntObjMgr)(PLAYER_NORMAL);
|
||||
|
||||
g_clientConnection->SetObjMgr(mgr);
|
||||
mgr->m_net = g_clientConnection;
|
||||
@ -138,6 +174,29 @@ void ClntObjMgrInitializeStd(uint32_t 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() {
|
||||
if (!s_savMgr) {
|
||||
return;
|
||||
@ -156,7 +215,7 @@ void ClntObjMgrPush(ClntObjMgr* mgr) {
|
||||
s_curMgr = mgr;
|
||||
}
|
||||
|
||||
void ClntObjMgrSetActivePlayer(uint64_t guid) {
|
||||
void ClntObjMgrSetActivePlayer(WOWGUID guid) {
|
||||
s_curMgr->m_activePlayer = guid;
|
||||
}
|
||||
|
||||
|
||||
@ -6,23 +6,31 @@
|
||||
#include "object/Types.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
void* ClntObjMgrAllocObject(OBJECT_TYPE_ID typeID, uint64_t guid);
|
||||
CGObject_C* ClntObjMgrAllocObject(OBJECT_TYPE_ID typeID, WOWGUID guid);
|
||||
|
||||
uint64_t ClntObjMgrGetActivePlayer();
|
||||
WOWGUID ClntObjMgrGetActivePlayer();
|
||||
|
||||
void ClntObjMgrFreeObject(CGObject_C* object);
|
||||
|
||||
ClntObjMgr* ClntObjMgrGetCurrent();
|
||||
|
||||
uint32_t ClntObjMgrGetMapID();
|
||||
|
||||
PLAYER_TYPE ClntObjMgrGetPlayerType();
|
||||
|
||||
void ClntObjMgrInitializeShared();
|
||||
|
||||
void ClntObjMgrInitializeStd(uint32_t mapID);
|
||||
|
||||
void ClntObjMgrLinkInNewObject(CGObject_C* object);
|
||||
|
||||
CGObject_C* ClntObjMgrObjectPtr(WOWGUID guid, OBJECT_TYPE type, const char* fileName, int32_t lineNumber);
|
||||
|
||||
void ClntObjMgrPop();
|
||||
|
||||
void ClntObjMgrPush(ClntObjMgr* mgr);
|
||||
|
||||
void ClntObjMgrSetActivePlayer(uint64_t guid);
|
||||
void ClntObjMgrSetActivePlayer(WOWGUID guid);
|
||||
|
||||
void ClntObjMgrSetHandlers();
|
||||
|
||||
|
||||
166
src/object/client/Util.cpp
Normal file
166
src/object/client/Util.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
23
src/object/client/Util.hpp
Normal file
23
src/object/client/Util.hpp
Normal 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
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
55
src/object/movement/CMoveSpline.cpp
Normal file
55
src/object/movement/CMoveSpline.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include "object/movement/CMoveSpline.hpp"
|
||||
#include "util/DataStore.hpp"
|
||||
#include <common/Time.hpp>
|
||||
|
||||
void CMoveSpline::Skip(CDataStore* msg) {
|
||||
uint32_t flags;
|
||||
msg->Get(flags);
|
||||
|
||||
uint32_t faceBytes = 0;
|
||||
|
||||
if (flags & 0x20000) {
|
||||
faceBytes = 4;
|
||||
} else if (flags & 0x10000) {
|
||||
faceBytes = 8;
|
||||
} else if (flags & 0x8000) {
|
||||
faceBytes = 12;
|
||||
}
|
||||
|
||||
void* data;
|
||||
msg->GetDataInSitu(data, faceBytes + 28);
|
||||
|
||||
uint32_t splinePoints = 0;
|
||||
msg->Get(splinePoints);
|
||||
|
||||
msg->GetDataInSitu(data, (splinePoints * sizeof(C3Vector)) + 13);
|
||||
}
|
||||
|
||||
CDataStore& operator>>(CDataStore& msg, CMoveSpline& spline) {
|
||||
msg.Get(spline.flags);
|
||||
|
||||
if (spline.flags & 0x20000) {
|
||||
msg.Get(spline.face.facing);
|
||||
} else if (spline.flags & 0x10000) {
|
||||
msg.Get(spline.face.guid);
|
||||
} else if (spline.flags & 0x8000) {
|
||||
msg >> spline.face.spot;
|
||||
}
|
||||
|
||||
uint32_t val;
|
||||
msg.Get(val);
|
||||
spline.start = OsGetAsyncTimeMsPrecise() - val;
|
||||
|
||||
msg.Get(spline.uint2C);
|
||||
msg.Get(spline.uint30);
|
||||
msg.Get(spline.float204);
|
||||
msg.Get(spline.float208);
|
||||
msg.Get(spline.float20C);
|
||||
msg.Get(spline.uint210);
|
||||
|
||||
msg >> spline.spline;
|
||||
|
||||
msg >> spline.vector1F8;
|
||||
|
||||
return msg;
|
||||
}
|
||||
34
src/object/movement/CMoveSpline.hpp
Normal file
34
src/object/movement/CMoveSpline.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef OBJECT_MOVEMENT_C_MOVE_SPLINE_HPP
|
||||
#define OBJECT_MOVEMENT_C_MOVE_SPLINE_HPP
|
||||
|
||||
#include "util/C3Spline.hpp"
|
||||
#include "util/GUID.hpp"
|
||||
#include <common/DataStore.hpp>
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
struct CMoveSpline {
|
||||
// TODO
|
||||
union {
|
||||
C3Vector spot = {};
|
||||
WOWGUID guid;
|
||||
float facing;
|
||||
} face;
|
||||
uint32_t flags;
|
||||
uint32_t start;
|
||||
// TODO
|
||||
uint32_t uint2C;
|
||||
uint32_t uint30;
|
||||
C3Spline_CatmullRom spline;
|
||||
C3Vector vector1F8;
|
||||
float float204;
|
||||
float float208;
|
||||
float float20C;
|
||||
uint32_t uint210;
|
||||
// TODO
|
||||
|
||||
static void Skip(CDataStore* msg);
|
||||
};
|
||||
|
||||
CDataStore& operator>>(CDataStore& msg, CMoveSpline& spline);
|
||||
|
||||
#endif
|
||||
81
src/object/movement/CMovementStatus.cpp
Normal file
81
src/object/movement/CMovementStatus.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
#include "object/movement/CMovementStatus.hpp"
|
||||
#include "util/DataStore.hpp"
|
||||
|
||||
uint32_t CMovementStatus::Skip(CDataStore* msg) {
|
||||
uint32_t moveFlags = 0;
|
||||
msg->Get(moveFlags);
|
||||
|
||||
uint16_t uint14;
|
||||
msg->Get(uint14);
|
||||
|
||||
void* data;
|
||||
msg->GetDataInSitu(data, 20);
|
||||
|
||||
uint32_t skipBytes = 0;
|
||||
|
||||
if (moveFlags & 0x200) {
|
||||
SmartGUID guid;
|
||||
*msg >> guid;
|
||||
|
||||
skipBytes += 21;
|
||||
|
||||
if (uint14 & 0x400) {
|
||||
skipBytes += 4;
|
||||
}
|
||||
}
|
||||
|
||||
if ((moveFlags & (0x200000 | 0x2000000)) || (uint14 & 0x20)) {
|
||||
skipBytes += 4;
|
||||
}
|
||||
|
||||
skipBytes += 4;
|
||||
|
||||
if (moveFlags & 0x1000) {
|
||||
skipBytes += 16;
|
||||
}
|
||||
|
||||
if (moveFlags & 0x4000000) {
|
||||
skipBytes += 4;
|
||||
}
|
||||
|
||||
msg->GetDataInSitu(data, skipBytes);
|
||||
|
||||
return moveFlags;
|
||||
}
|
||||
|
||||
CDataStore& operator>>(CDataStore& msg, CMovementStatus& move) {
|
||||
msg.Get(move.moveFlags);
|
||||
msg.Get(move.uint14);
|
||||
msg.Get(move.uint0);
|
||||
|
||||
msg >> move.position18;
|
||||
msg.Get(move.facing34);
|
||||
|
||||
if (move.moveFlags & 0x200) {
|
||||
// TODO
|
||||
} else {
|
||||
move.transport = 0;
|
||||
// TODO
|
||||
}
|
||||
|
||||
if ((move.moveFlags & (0x200000 | 0x2000000)) || (move.uint14 & 0x20)) {
|
||||
msg.Get(move.float38);
|
||||
} else {
|
||||
move.float38 = 0.0f;
|
||||
}
|
||||
|
||||
msg.Get(move.uint3C);
|
||||
|
||||
if (move.moveFlags & 0x1000) {
|
||||
msg.Get(move.float40);
|
||||
msg.Get(move.float44);
|
||||
msg.Get(move.float48);
|
||||
msg.Get(move.float4C);
|
||||
}
|
||||
|
||||
if (move.moveFlags & 0x4000000) {
|
||||
msg.Get(move.float50);
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
34
src/object/movement/CMovementStatus.hpp
Normal file
34
src/object/movement/CMovementStatus.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef OBJECT_MOVEMENT_C_MOVEMENT_STATUS_HPP
|
||||
#define OBJECT_MOVEMENT_C_MOVEMENT_STATUS_HPP
|
||||
|
||||
#include "util/GUID.hpp"
|
||||
#include <common/DataStore.hpp>
|
||||
#include <tempest/Vector.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
struct CMovementStatus {
|
||||
uint32_t uint0 = 0;
|
||||
// TODO
|
||||
WOWGUID transport = 0;
|
||||
uint32_t moveFlags = 0x0;
|
||||
uint16_t uint14 = 0;
|
||||
// TODO
|
||||
C3Vector position18;
|
||||
float facing24 = 0.0f;
|
||||
C3Vector position28;
|
||||
float facing34 = 0.0f;
|
||||
float float38 = 0.0f;
|
||||
uint32_t uint3C = 0;
|
||||
float float40 = 0.0f;
|
||||
float float44 = 0.0f;
|
||||
float float48 = 0.0f;
|
||||
float float4C = 0.0f;
|
||||
float float50 = 0.0f;
|
||||
// TODO
|
||||
|
||||
static uint32_t Skip(CDataStore* msg);
|
||||
};
|
||||
|
||||
CDataStore& operator>>(CDataStore& msg, CMovementStatus& move);
|
||||
|
||||
#endif
|
||||
@ -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) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -353,8 +357,20 @@ int32_t CLayoutFrame::GetRect(CRect* rect) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
float CLayoutFrame::GetHeight() {
|
||||
return this->m_height;
|
||||
void CLayoutFrame::GetSize(float& width, float& height, int32_t a4) {
|
||||
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() {
|
||||
@ -846,6 +862,13 @@ void CLayoutFrame::SetProtectFlag(uint32_t flag) {
|
||||
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) {
|
||||
this->m_flags &= ~0x8;
|
||||
this->m_width = width;
|
||||
|
||||
@ -49,8 +49,10 @@ class CLayoutFrame {
|
||||
virtual bool SetLayoutScale(float scale, bool force);
|
||||
virtual void SetWidth(float width);
|
||||
virtual void SetHeight(float height);
|
||||
virtual void SetSize(float width, float height);
|
||||
virtual float GetWidth();
|
||||
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 int32_t IsAttachmentOrigin();
|
||||
virtual CLayoutFrame* GetLayoutFrameByName(const char* name);
|
||||
|
||||
@ -219,7 +219,28 @@ int32_t CScriptRegion_SetHeight(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) {
|
||||
|
||||
@ -11,8 +11,6 @@
|
||||
#include <storm/String.hpp>
|
||||
#include <tempest/Vector.hpp>
|
||||
|
||||
const char* g_scriptEvents[722];
|
||||
|
||||
int32_t g_glueFrameScriptGenders[] = {
|
||||
2, // UNIT_SEX_MALE
|
||||
3, // UNIT_SEX_FEMALE
|
||||
@ -154,8 +152,10 @@ void FrameScript_CreateEvents(const char* names[], uint32_t count) {
|
||||
FrameScript::s_scriptEvents.SetCount(count);
|
||||
|
||||
for (int32_t i = 0; i < count; i++) {
|
||||
auto event = FrameScript::s_scriptEventsHash.New(names[i], 0, 0);
|
||||
FrameScript::s_scriptEvents[i] = event;
|
||||
if (names[i]) {
|
||||
auto event = FrameScript::s_scriptEventsHash.New(names[i], 0, 0);
|
||||
FrameScript::s_scriptEvents[i] = event;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1047,6 +1047,15 @@ const char* FrameScript_Sprintf(lua_State* L, int32_t idx, char buffer[], uint32
|
||||
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) {
|
||||
if (event->pendingSignalCount) {
|
||||
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";
|
||||
}
|
||||
|
||||
@ -40,7 +40,6 @@ class FrameScript_EventObject : public TSHashObject<FrameScript_EventObject, HAS
|
||||
};
|
||||
|
||||
extern int32_t g_glueFrameScriptGenders[UNITSEX_LAST];
|
||||
extern const char* g_scriptEvents[722];
|
||||
|
||||
namespace FrameScript {
|
||||
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);
|
||||
|
||||
void FrameScript_UnregisterFunction(const char* name);
|
||||
|
||||
void FrameScript_UnregisterScriptEvent(FrameScript_Object* object, FrameScript_EventObject* event);
|
||||
|
||||
void ScriptEventsInitialize();
|
||||
|
||||
#endif
|
||||
|
||||
@ -5,6 +5,12 @@
|
||||
|
||||
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)) {
|
||||
lua_createtable(L, 0, 0);
|
||||
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* name = this->GetName();
|
||||
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) {
|
||||
if (!SStrCmpI(name, "OnEvent", STORM_MAX_STR)) {
|
||||
data.wrapper = "return function(self,event,...) %s end";
|
||||
@ -166,6 +193,25 @@ int32_t FrameScript_Object::SetScript(lua_State* L) {
|
||||
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) {
|
||||
auto L = FrameScript_GetContext();
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ class FrameScript_Object {
|
||||
struct ScriptIx {
|
||||
int32_t luaRef = 0;
|
||||
const char* unk = nullptr;
|
||||
~ScriptIx();
|
||||
};
|
||||
|
||||
class ScriptFunction {
|
||||
@ -34,7 +35,7 @@ class FrameScript_Object {
|
||||
ScriptIx m_onEvent;
|
||||
|
||||
// Virtual member functions
|
||||
virtual ~FrameScript_Object();
|
||||
virtual ~FrameScript_Object() = default;
|
||||
virtual char* GetName() = 0;
|
||||
virtual int32_t GetScriptMetaTable() = 0;
|
||||
virtual ScriptIx* GetScriptByName(const char* name, ScriptData& data);
|
||||
@ -42,10 +43,12 @@ class FrameScript_Object {
|
||||
|
||||
// Member functions
|
||||
const char* GetDisplayName();
|
||||
int32_t GetScript(lua_State* L);
|
||||
int32_t RegisterScriptEvent(const char* name);
|
||||
void RegisterScriptObject(const char* name);
|
||||
void RunScript(ScriptIx const& script, int32_t argCount, const char* a4);
|
||||
int32_t SetScript(lua_State* L);
|
||||
void UnregisterScriptEvent(const char* name);
|
||||
void UnregisterScriptObject(const char* name);
|
||||
};
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include "ui/simple/CSimpleModel.hpp"
|
||||
#include "ui/simple/CSimpleScrollFrame.hpp"
|
||||
#include "ui/simple/CSimpleSlider.hpp"
|
||||
#include "ui/simple/CSimpleStatusBar.hpp"
|
||||
#include "util/CStatus.hpp"
|
||||
#include "util/SFile.hpp"
|
||||
#include <common/XML.hpp>
|
||||
@ -96,9 +97,9 @@ CSimpleFrame* Create_SimpleHTML(CSimpleFrame* parent) {
|
||||
}
|
||||
|
||||
CSimpleFrame* Create_SimpleStatusBar(CSimpleFrame* parent) {
|
||||
// TODO
|
||||
// TODO CDataAllocator
|
||||
|
||||
return nullptr;
|
||||
return STORM_NEW(CSimpleStatusBar(parent));
|
||||
}
|
||||
|
||||
CSimpleFrame* Create_SimpleColorSelect(CSimpleFrame* parent) {
|
||||
@ -541,19 +542,19 @@ int32_t FrameXML_RegisterFactory(const char* type, CSimpleFrame* (*factory)(CSim
|
||||
}
|
||||
|
||||
void FrameXML_RegisterDefault() {
|
||||
FrameXML_RegisterFactory("Button", &Create_SimpleButton, 0);
|
||||
FrameXML_RegisterFactory("CheckButton", &Create_SimpleCheckButton, 0);
|
||||
FrameXML_RegisterFactory("EditBox", &Create_SimpleEditBox, 0);
|
||||
FrameXML_RegisterFactory("Frame", &Create_SimpleFrame, 0);
|
||||
FrameXML_RegisterFactory("MessageFrame", &Create_SimpleMessageFrame, 0);
|
||||
FrameXML_RegisterFactory("Model", &Create_SimpleModel, 0);
|
||||
FrameXML_RegisterFactory("ScrollFrame", &Create_SimpleScrollFrame, 0);
|
||||
FrameXML_RegisterFactory("ScrollingMessageFrame", &Create_SimpleScrollingMessageFrame, 0);
|
||||
FrameXML_RegisterFactory("Slider", &Create_SimpleSlider, 0);
|
||||
FrameXML_RegisterFactory("SimpleHTML", &Create_SimpleHTML, 0);
|
||||
FrameXML_RegisterFactory("StatusBar", &Create_SimpleStatusBar, 0);
|
||||
FrameXML_RegisterFactory("ColorSelect", &Create_SimpleColorSelect, 0);
|
||||
FrameXML_RegisterFactory("MovieFrame", &Create_SimpleMovieFrame, 0);
|
||||
FrameXML_RegisterFactory("Button", &Create_SimpleButton, false);
|
||||
FrameXML_RegisterFactory("CheckButton", &Create_SimpleCheckButton, false);
|
||||
FrameXML_RegisterFactory("EditBox", &Create_SimpleEditBox, false);
|
||||
FrameXML_RegisterFactory("Frame", &Create_SimpleFrame, false);
|
||||
FrameXML_RegisterFactory("MessageFrame", &Create_SimpleMessageFrame, false);
|
||||
FrameXML_RegisterFactory("Model", &Create_SimpleModel, false);
|
||||
FrameXML_RegisterFactory("ScrollFrame", &Create_SimpleScrollFrame, false);
|
||||
FrameXML_RegisterFactory("ScrollingMessageFrame", &Create_SimpleScrollingMessageFrame, false);
|
||||
FrameXML_RegisterFactory("Slider", &Create_SimpleSlider, false);
|
||||
FrameXML_RegisterFactory("SimpleHTML", &Create_SimpleHTML, false);
|
||||
FrameXML_RegisterFactory("StatusBar", &Create_SimpleStatusBar, false);
|
||||
FrameXML_RegisterFactory("ColorSelect", &Create_SimpleColorSelect, false);
|
||||
FrameXML_RegisterFactory("MovieFrame", &Create_SimpleMovieFrame, false);
|
||||
}
|
||||
|
||||
void FrameXML_ReleaseHashNode(const char* name) {
|
||||
|
||||
9
src/ui/Game.hpp
Normal file
9
src/ui/Game.hpp
Normal 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
20
src/ui/Key.cpp
Normal 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
Loading…
Reference in New Issue
Block a user