mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-07-27 10:48:28 +03:00
Compare commits
3 Commits
971b781368
...
e08b41a133
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e08b41a133 | ||
![]() |
58954a9655 | ||
![]() |
f2a253f5ad |
@ -12,6 +12,7 @@
|
||||
#include "db/Db.hpp"
|
||||
#include "db/Startup_Strings.hpp"
|
||||
#include "glue/CGlueMgr.hpp"
|
||||
#include "glue/CCharacterComponent.hpp"
|
||||
#include "gameui/CGGameUI.hpp"
|
||||
#include "gx/Screen.hpp"
|
||||
#include "gx/Texture.hpp"
|
||||
@ -736,8 +737,8 @@ void WowClientInit() {
|
||||
|
||||
// TODO
|
||||
// sub_6F75E0();
|
||||
// sub_401FF0();
|
||||
|
||||
CCharacterComponent::Initialize();
|
||||
ClientServices::Initialize();
|
||||
// TODO ClientServices::SetMessageHandler(SMSG_TUTORIAL_FLAGS, (int)sub_530920, 0);
|
||||
|
||||
|
@ -1 +1,137 @@
|
||||
#include "glue/CCharacterComponent.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <common/ObjectAlloc.hpp>
|
||||
#include <common/Processor.hpp>
|
||||
#include "console/Types.hpp"
|
||||
#include "console/CVar.hpp"
|
||||
|
||||
CVar* CCharacterComponent::g_componentTextureLevelVar = nullptr;
|
||||
CVar* CCharacterComponent::g_componentThreadVar = nullptr;
|
||||
CVar* CCharacterComponent::g_componentCompressVar = nullptr;
|
||||
|
||||
uint32_t* CCharacterComponent::s_heap = nullptr;
|
||||
|
||||
|
||||
static bool ComponentVarHandler(CVar*, const char*, const char*, void*) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ComponentData::ComponentData() {
|
||||
this->m_unkFlag &= 0xFFFFFFFC;
|
||||
memset(&this->m_info, 0, sizeof(this->m_info));
|
||||
this->m_model = nullptr;
|
||||
}
|
||||
|
||||
void CCharacterComponent::Initialize() {
|
||||
CCharacterComponent::g_componentTextureLevelVar = CVar::Register(
|
||||
"componentTextureLevel",
|
||||
"Number of mip levels used for character component textures",
|
||||
0x1,
|
||||
"8",
|
||||
&ComponentVarHandler,
|
||||
CATEGORY::DEBUG,
|
||||
0,
|
||||
nullptr,
|
||||
false);
|
||||
|
||||
CCharacterComponent::g_componentThreadVar = CVar::Register(
|
||||
"componentThread",
|
||||
"Multi thread character component processing",
|
||||
0x1,
|
||||
"1",
|
||||
&ComponentVarHandler,
|
||||
CATEGORY::DEBUG,
|
||||
0,
|
||||
nullptr,
|
||||
false);
|
||||
|
||||
CCharacterComponent::g_componentCompressVar = CVar::Register(
|
||||
"componentCompress",
|
||||
"Character component texture compression",
|
||||
0x1,
|
||||
"1",
|
||||
&ComponentVarHandler,
|
||||
CATEGORY::DEBUG,
|
||||
0,
|
||||
nullptr,
|
||||
false);
|
||||
|
||||
uint32_t mipLevels = CCharacterComponent::g_componentTextureLevelVar->GetInt();
|
||||
int32_t useThreads = CCharacterComponent::g_componentThreadVar->GetInt();
|
||||
int32_t useCompression = CCharacterComponent::g_componentCompressVar->GetInt();
|
||||
|
||||
if (!useThreads || OsGetProcessorCount() < 2) {
|
||||
useThreads = 0;
|
||||
|
||||
if (mipLevels > 8) {
|
||||
mipLevels = 8;
|
||||
}
|
||||
|
||||
useCompression = 0;
|
||||
}
|
||||
|
||||
if (mipLevels > 9) {
|
||||
mipLevels = 9;
|
||||
}
|
||||
|
||||
if (mipLevels < 7) {
|
||||
mipLevels = 7;
|
||||
}
|
||||
|
||||
CCharacterComponent::Initialize(GxTex_Rgb565, mipLevels, useThreads, useCompression);
|
||||
}
|
||||
|
||||
void CCharacterComponent::Initialize(EGxTexFormat format, uint32_t mipLevels, int32_t useThreads, int32_t useCompression) {
|
||||
CCharacterComponent::s_heap = static_cast<uint32_t*>(ALLOC(sizeof(uint32_t)));
|
||||
if (CCharacterComponent::s_heap) {
|
||||
*CCharacterComponent::s_heap = ObjectAllocAddHeap(sizeof(CCharacterComponent), 32, "CCharacterComponent", true);
|
||||
}
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
CCharacterComponent* CCharacterComponent::AllocComponent() {
|
||||
|
||||
uint32_t handle;
|
||||
void* memory;
|
||||
|
||||
if (ObjectAlloc(*CCharacterComponent::s_heap, &handle, &memory, false) && memory) {
|
||||
auto component = new (memory) CCharacterComponent();
|
||||
component->m_handle = handle;
|
||||
return component;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CCharacterComponent::FreeComponent(CCharacterComponent* component) {
|
||||
component->~CCharacterComponent();
|
||||
// TODO: ObjectFree()
|
||||
}
|
||||
|
||||
CCharacterComponent::CCharacterComponent() {
|
||||
}
|
||||
|
||||
CCharacterComponent::~CCharacterComponent() {
|
||||
}
|
||||
|
||||
void CCharacterComponent::SetRandomSkin(COMPONENT_CONTEXT context) {
|
||||
}
|
||||
|
||||
void CCharacterComponent::SetRandomHairColor(COMPONENT_CONTEXT context) {
|
||||
}
|
||||
|
||||
void CCharacterComponent::SetRandomHairStyle(COMPONENT_CONTEXT context) {
|
||||
}
|
||||
|
||||
void CCharacterComponent::SetRandomFace(COMPONENT_CONTEXT context) {
|
||||
}
|
||||
|
||||
void CCharacterComponent::SetRandomFacialFeature(COMPONENT_CONTEXT context) {
|
||||
}
|
||||
|
||||
bool CCharacterComponent::Init(ComponentData* data, const char* a3) {
|
||||
this->m_data = *data;
|
||||
return false;
|
||||
}
|
||||
|
@ -2,16 +2,61 @@
|
||||
#define GLUE_C_CHARACTER_COMPONENT_HPP
|
||||
|
||||
#include "net/Types.hpp"
|
||||
#include "gx/Types.hpp"
|
||||
#include <storm/Array.hpp>
|
||||
|
||||
class CSimpleModelFFX;
|
||||
class CM2Model;
|
||||
class CVar;
|
||||
|
||||
class ComponentData {
|
||||
public:
|
||||
ComponentData();
|
||||
|
||||
public:
|
||||
CHARACTER_CREATE_INFO m_info;
|
||||
CM2Model* m_model;
|
||||
uint32_t m_unkFlag;
|
||||
};
|
||||
|
||||
class CCharacterComponent {
|
||||
public:
|
||||
enum COMPONENT_CONTEXT
|
||||
{
|
||||
DEFAULT_CONTEXT = 0,
|
||||
CONTEXT_1,
|
||||
CONTEXT_2,
|
||||
CONTEXT_3
|
||||
};
|
||||
|
||||
public:
|
||||
// Static variables
|
||||
static CVar* g_componentTextureLevelVar;
|
||||
static CVar* g_componentThreadVar;
|
||||
static CVar* g_componentCompressVar;
|
||||
|
||||
static uint32_t* s_heap;
|
||||
|
||||
// Static functions
|
||||
static void Initialize();
|
||||
static void Initialize(EGxTexFormat format, uint32_t mipLevels, int32_t useThreads, int32_t useCompression);
|
||||
static CCharacterComponent* AllocComponent();
|
||||
static void FreeComponent(CCharacterComponent* component);
|
||||
|
||||
CCharacterComponent();
|
||||
~CCharacterComponent();
|
||||
|
||||
void SetRandomSkin(COMPONENT_CONTEXT context = DEFAULT_CONTEXT);
|
||||
void SetRandomHairColor(COMPONENT_CONTEXT context = DEFAULT_CONTEXT);
|
||||
void SetRandomHairStyle(COMPONENT_CONTEXT context = DEFAULT_CONTEXT);
|
||||
void SetRandomFace(COMPONENT_CONTEXT context = DEFAULT_CONTEXT);
|
||||
void SetRandomFacialFeature(COMPONENT_CONTEXT context = DEFAULT_CONTEXT);
|
||||
|
||||
bool Init(ComponentData* data, const char* a3);
|
||||
|
||||
public:
|
||||
uint32_t m_handle;
|
||||
ComponentData m_data;
|
||||
};
|
||||
|
||||
#endif // GLUE_C_CHARACTER_COMPONENT_HPP
|
||||
|
@ -1,8 +1,178 @@
|
||||
#include "glue/CCharacterCreation.hpp"
|
||||
#include "glue/CCharacterComponent.hpp"
|
||||
#include "ui/CSimpleModelFFX.hpp"
|
||||
#include "model/CM2Model.hpp"
|
||||
#include "clientobject/Player_C.hpp"
|
||||
#include "db/Db.hpp"
|
||||
|
||||
float CCharacterCreation::m_charFacing = 0.0;
|
||||
CharacterCreationDisplay CCharacterCreation::m_character = {};
|
||||
int32_t CCharacterCreation::m_existingCharacterIndex;
|
||||
int32_t CCharacterCreation::m_raceIndex;
|
||||
CSimpleModel* CCharacterCreation::m_charCustomizeFrame;
|
||||
float CCharacterCreation::m_charFacing;
|
||||
uint32_t CCharacterCreation::m_prevSkinIndex;
|
||||
uint32_t CCharacterCreation::m_prevFaceIndex;
|
||||
uint32_t CCharacterCreation::m_prevHairColorIndex;
|
||||
uint32_t CCharacterCreation::m_prevHairStyleIndex;
|
||||
uint32_t CCharacterCreation::m_prevFacialFeatureIndex;
|
||||
CCharacterComponent* CCharacterCreation::m_character = nullptr;
|
||||
TSGrowableArray<ChrClassesRec*> CCharacterCreation::m_classes;
|
||||
TSGrowableArray<int32_t> CCharacterCreation::m_races;
|
||||
|
||||
void CCharacterCreation::Initialize() {
|
||||
CCharacterCreation::m_charFacing = 0.0;
|
||||
int32_t factionSwitch = 0;
|
||||
CCharacterCreation::m_charCustomizeFrame = nullptr;
|
||||
CCharacterCreation::m_existingCharacterIndex = -1;
|
||||
// TODO: memset
|
||||
int32_t factionSwitch2 = 0;
|
||||
|
||||
bool weirdCondition = false;
|
||||
|
||||
do {
|
||||
for (int32_t raceIndex = 0; raceIndex < g_chrRacesDB.GetNumRecords(); ++raceIndex) {
|
||||
auto raceRecord = g_chrRacesDB.GetRecordByIndex(raceIndex);
|
||||
if (!raceRecord || (raceRecord->m_flags & 1) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto factionTemplateRecord = g_factionTemplateDB.GetRecord(raceRecord->m_factionID);
|
||||
if (!factionTemplateRecord) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int32_t factionGroupIndex = 0; factionGroupIndex < g_factionGroupDB.GetNumRecords(); ++factionGroupIndex) {
|
||||
auto factionGroupRecord = g_factionGroupDB.GetRecordByIndex(factionGroupIndex);
|
||||
if (!factionGroupRecord || factionGroupRecord->m_maskID == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((1 << factionGroupRecord->m_maskID) & factionTemplateRecord->m_factionGroup) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (SStrCmpI(factionGroupRecord->m_internalName, factionSwitch == 1 ? "Horde" : "Alliance", STORM_MAX_STR)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CCharacterCreation::m_races.Add(1, &raceRecord->m_ID);
|
||||
|
||||
factionSwitch = factionSwitch2;
|
||||
}
|
||||
}
|
||||
|
||||
weirdCondition = factionSwitch++ == -1;
|
||||
factionSwitch2 = factionSwitch;
|
||||
} while (weirdCondition || factionSwitch == 1);
|
||||
}
|
||||
|
||||
void CCharacterCreation::SetCharCustomizeFrame(CSimpleModel* frame) {
|
||||
CCharacterCreation::m_charCustomizeFrame = frame;
|
||||
}
|
||||
|
||||
void CCharacterCreation::SetCharCustomizeModel(char const* filename) {
|
||||
if (!CCharacterCreation::m_charCustomizeFrame || !filename || !*filename) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO
|
||||
CCharacterCreation::m_charCustomizeFrame->SetModel(filename);
|
||||
}
|
||||
|
||||
void CCharacterCreation::ResetCharCustomizeInfo() {
|
||||
if (!CCharacterCreation::m_charCustomizeFrame) {
|
||||
return;
|
||||
}
|
||||
|
||||
CCharacterCreation::m_existingCharacterIndex = -1;
|
||||
|
||||
// TODO: CM2Model__DetachAllChildrenById
|
||||
|
||||
ComponentData data;
|
||||
CCharacterCreation::GetRandomRaceAndSex(&data);
|
||||
CCharacterCreation::CalcClasses(data.m_info.raceID);
|
||||
CCharacterCreation::InitCharacterComponent(&data, 1);
|
||||
|
||||
// TODO
|
||||
|
||||
CCharacterCreation::m_raceIndex = -1;
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCharacterCreation::GetRandomRaceAndSex(ComponentData* data) {
|
||||
// TODO
|
||||
// WORKAROUND
|
||||
data->m_info.raceID = 1;
|
||||
}
|
||||
|
||||
void CCharacterCreation::CalcClasses(uint32_t raceID) {
|
||||
uint32_t count = 0;
|
||||
|
||||
for (int32_t i = 0; i < g_charBaseInfoDB.GetNumRecords(); ++i) {
|
||||
auto record = g_charBaseInfoDB.GetRecordByIndex(i);
|
||||
if (record && record->m_raceID == raceID) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
CCharacterCreation::m_classes.SetCount(count);
|
||||
|
||||
uint32_t index = 0;
|
||||
|
||||
for (int32_t i = 0; i < g_charBaseInfoDB.GetNumRecords(); ++i) {
|
||||
auto record = g_charBaseInfoDB.GetRecordByIndex(i);
|
||||
if (!record || record->m_raceID != raceID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CCharacterCreation::m_classes[index] = g_chrClassesDB.GetRecord(record->m_classID);
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
void CCharacterCreation::InitCharacterComponent(ComponentData* data, int32_t randomize) {
|
||||
auto record = Player_C_GetModelName(data->m_info.raceID, data->m_info.sexID);
|
||||
if (!record || !record->m_modelName[0]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (CCharacterCreation::m_character) {
|
||||
auto model = CCharacterCreation::m_character->m_data.m_model;
|
||||
if (model->m_attachParent) {
|
||||
// TODO: model->DetachFromParent();
|
||||
}
|
||||
CCharacterComponent::FreeComponent(CCharacterCreation::m_character);
|
||||
}
|
||||
|
||||
CCharacterCreation::m_character = CCharacterComponent::AllocComponent();
|
||||
|
||||
auto scene = CCharacterCreation::m_charCustomizeFrame->GetScene();
|
||||
data->m_model = scene->CreateModel(record->m_modelName, 0);
|
||||
if (!data->m_model) {
|
||||
return;
|
||||
}
|
||||
|
||||
data->m_unkFlag |= 2u;
|
||||
CCharacterCreation::m_character->Init(data, nullptr);
|
||||
|
||||
if (randomize) {
|
||||
CCharacterCreation::RandomizeCharFeatures();
|
||||
}
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
void CCharacterCreation::RandomizeCharFeatures() {
|
||||
CCharacterCreation::m_character->SetRandomSkin();
|
||||
CCharacterCreation::m_character->SetRandomHairColor();
|
||||
CCharacterCreation::m_character->SetRandomHairStyle();
|
||||
CCharacterCreation::m_character->SetRandomFace();
|
||||
CCharacterCreation::m_character->SetRandomFacialFeature();
|
||||
|
||||
const auto& info = CCharacterCreation::m_character->m_data.m_info;
|
||||
CCharacterCreation::m_prevSkinIndex = info.skinID;
|
||||
CCharacterCreation::m_prevFaceIndex = info.faceID;
|
||||
CCharacterCreation::m_prevHairColorIndex = info.hairColorID;
|
||||
CCharacterCreation::m_prevHairStyleIndex = info.hairStyleID;
|
||||
CCharacterCreation::m_prevFacialFeatureIndex = info.facialFeatureID;
|
||||
}
|
||||
|
@ -4,22 +4,39 @@
|
||||
#include "net/Types.hpp"
|
||||
#include <storm/Array.hpp>
|
||||
|
||||
class CSimpleModel;
|
||||
class CSimpleModelFFX;
|
||||
class CM2Model;
|
||||
class ComponentData;
|
||||
class CCharacterComponent;
|
||||
class ChrClassesRec;
|
||||
|
||||
struct CharacterCreationDisplay {
|
||||
CHARACTER_CREATE_INFO m_characterInfo;
|
||||
CM2Model* m_characterModel;
|
||||
};
|
||||
|
||||
class CCharacterCreation {
|
||||
public:
|
||||
// Static variables
|
||||
static int32_t m_existingCharacterIndex;
|
||||
static int32_t m_raceIndex;
|
||||
static CSimpleModel* m_charCustomizeFrame;
|
||||
static float m_charFacing;
|
||||
static CharacterCreationDisplay m_character;
|
||||
static uint32_t m_prevSkinIndex;
|
||||
static uint32_t m_prevFaceIndex;
|
||||
static uint32_t m_prevHairColorIndex;
|
||||
static uint32_t m_prevHairStyleIndex;
|
||||
static uint32_t m_prevFacialFeatureIndex;
|
||||
static CCharacterComponent* m_character;
|
||||
static TSGrowableArray<ChrClassesRec*> m_classes;
|
||||
static TSGrowableArray<int32_t> m_races;
|
||||
|
||||
// Static functions
|
||||
static void Initialize();
|
||||
static void SetCharCustomizeFrame(CSimpleModel* frame);
|
||||
static void SetCharCustomizeModel(char const* filename);
|
||||
static void ResetCharCustomizeInfo();
|
||||
static void GetRandomRaceAndSex(ComponentData* data);
|
||||
static void CalcClasses(uint32_t raceID);
|
||||
static void InitCharacterComponent(ComponentData* data, int32_t randomize);
|
||||
static void RandomizeCharFeatures();
|
||||
};
|
||||
|
||||
#endif // GLUE_C_CHARACTER_CREATION_HPP
|
||||
|
@ -813,15 +813,12 @@ void CGlueMgr::InitCursor() {
|
||||
}
|
||||
|
||||
void CGlueMgr::Resume() {
|
||||
// TODO
|
||||
// CGlueMgr::m_disconnectPending = 0;
|
||||
// CGlueMgr::m_reconnect = 0;
|
||||
|
||||
CGlueMgr::m_disconnectPending = 0;
|
||||
CGlueMgr::m_reconnect = 0;
|
||||
CGlueMgr::m_idleState = IDLE_NONE;
|
||||
CGlueMgr::m_showedDisconnect = 0;
|
||||
|
||||
// TODO
|
||||
// CGlueMgr::m_showedDisconnect = 0;
|
||||
// CGlueMgr::m_characterInfo = 0;
|
||||
CGlueMgr::m_characterInfo = nullptr;
|
||||
|
||||
CGlueMgr::m_suspended = 0;
|
||||
CGlueMgr::m_reload = 0;
|
||||
|
@ -1287,9 +1287,14 @@ struct CHARACTER_INFO {
|
||||
};
|
||||
|
||||
struct CHARACTER_CREATE_INFO {
|
||||
uint8_t unk[24];
|
||||
uint32_t raceID;
|
||||
uint32_t sexID;
|
||||
uint32_t unk;
|
||||
uint32_t hairColorID;
|
||||
uint32_t skinID;
|
||||
uint32_t faceID;
|
||||
uint32_t facialFeatureID;
|
||||
uint32_t hairStyleID;
|
||||
};
|
||||
|
||||
struct CLIENT_NETSTATS {
|
||||
|
@ -1,27 +1,49 @@
|
||||
#include "ui/ScriptFunctions.hpp"
|
||||
#include "ui/CSimpleModelFFX.hpp"
|
||||
#include "ui/Types.hpp"
|
||||
#include "util/Lua.hpp"
|
||||
#include "util/Unimplemented.hpp"
|
||||
#include "db/Db.hpp"
|
||||
#include "clientobject/Unit_C.hpp"
|
||||
#include "glue/CCharacterCreation.hpp"
|
||||
#include "glue/CCharacterComponent.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
int32_t Script_SetCharCustomizeFrame(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED(0);
|
||||
if (!lua_isstring(L, 1)) {
|
||||
return luaL_error(L, "Usage: SetCharCustomizeFrame(\"frameName\")");
|
||||
}
|
||||
|
||||
auto type = CSimpleModel::GetObjectType();
|
||||
auto name = lua_tolstring(L, 1, nullptr);
|
||||
auto frame = CScriptObject::GetScriptObjectByName(name, type);
|
||||
|
||||
if (frame) {
|
||||
CCharacterCreation::SetCharCustomizeFrame(static_cast<CSimpleModel*>(frame));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_SetCharCustomizeBackground(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED(0);
|
||||
if (!lua_isstring(L, 1)) {
|
||||
return luaL_error(L, "Usage: SetCharCustomizeBackground(\"filename\")");
|
||||
}
|
||||
|
||||
int32_t Script_ResetCharCustomize(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED(0);
|
||||
auto filename = lua_tolstring(L, 1, nullptr);
|
||||
CCharacterCreation::SetCharCustomizeModel(filename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_ResetCharCustomize(lua_State*) {
|
||||
CCharacterCreation::ResetCharCustomizeInfo();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t Script_GetNameForRace(lua_State* L) {
|
||||
auto raceID = CCharacterCreation::m_character.m_characterInfo.raceID;
|
||||
auto sexID = CCharacterCreation::m_character.m_characterInfo.sexID;
|
||||
auto raceID = CCharacterCreation::m_character->m_data.m_info.raceID;
|
||||
auto sexID = CCharacterCreation::m_character->m_data.m_info.sexID;
|
||||
auto record = g_chrRacesDB.GetRecord(raceID);
|
||||
auto raceName = CGUnit_C::GetDisplayRaceNameFromRecord(record, sexID);
|
||||
if (record && raceName) {
|
||||
@ -36,19 +58,93 @@ int32_t Script_GetNameForRace(lua_State* L) {
|
||||
}
|
||||
|
||||
int32_t Script_GetFactionForRace(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED(0);
|
||||
if (!lua_isnumber(L, 1)) {
|
||||
return luaL_error(L, "Usage: GetFactionForRace(index)");
|
||||
}
|
||||
|
||||
uint32_t index = static_cast<uint32_t>(lua_tonumber(L, 1)) - 1;
|
||||
int32_t raceID = 0;
|
||||
if (index < CCharacterCreation::m_races.Count()) {
|
||||
raceID = CCharacterCreation::m_races[index];
|
||||
}
|
||||
|
||||
auto raceRecord = g_chrRacesDB.GetRecord(raceID);
|
||||
if (raceRecord) {
|
||||
auto factionTemplateRecord = g_factionTemplateDB.GetRecord(raceRecord->m_factionID);
|
||||
if (factionTemplateRecord) {
|
||||
for (int32_t i = 0; i < g_factionGroupDB.GetNumRecords(); ++i) {
|
||||
auto factionGroupRecord = g_factionGroupDB.GetRecordByIndex(i);
|
||||
if (!factionGroupRecord || factionGroupRecord->m_maskID == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((1 << factionGroupRecord->m_maskID) & factionTemplateRecord->m_factionGroup) != 0) {
|
||||
lua_pushstring(L, factionGroupRecord->m_name);
|
||||
lua_pushstring(L, factionGroupRecord->m_internalName);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lua_pushnil(L);
|
||||
lua_pushnil(L);
|
||||
return 2;
|
||||
}
|
||||
|
||||
int32_t Script_GetAvailableRaces(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED(0);
|
||||
for (uint32_t i = 0; i < CCharacterCreation::m_races.Count(); ++i) {
|
||||
auto raceRecord = g_chrRacesDB.GetRecord(CCharacterCreation::m_races[i]);
|
||||
auto raceName = CGUnit_C::GetDisplayRaceNameFromRecord(
|
||||
raceRecord,
|
||||
CCharacterCreation::m_character->m_data.m_info.sexID);
|
||||
|
||||
lua_pushstring(L, raceName);
|
||||
lua_pushstring(L, raceRecord ? raceRecord->m_clientFileString : nullptr);
|
||||
// TODO: Expansion Check
|
||||
lua_pushnumber(L, 1.0);
|
||||
}
|
||||
return CCharacterCreation::m_races.Count() * 3;
|
||||
}
|
||||
|
||||
int32_t Script_GetAvailableClasses(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED(0);
|
||||
for (int32_t i = 0; i < g_chrClassesDB.GetNumRecords(); ++i) {
|
||||
auto record = g_chrClassesDB.GetRecordByIndex(i);
|
||||
auto className = CGUnit_C::GetDisplayClassNameFromRecord(
|
||||
record,
|
||||
CCharacterCreation::m_character->m_data.m_info.sexID);
|
||||
if (className) {
|
||||
lua_pushstring(L, className);
|
||||
lua_pushstring(L, record->m_filename);
|
||||
// TODO: Expansion Check
|
||||
lua_pushnumber(L, 1.0);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
lua_pushnil(L);
|
||||
lua_pushnil(L);
|
||||
}
|
||||
}
|
||||
return g_chrClassesDB.GetNumRecords() * 3;
|
||||
}
|
||||
|
||||
int32_t Script_GetClassesForRace(lua_State* L) {
|
||||
WHOA_UNIMPLEMENTED(0);
|
||||
for (uint32_t i = 0; i < CCharacterCreation::m_classes.Count(); ++i) {
|
||||
auto record = CCharacterCreation::m_classes[i];
|
||||
auto className = CGUnit_C::GetDisplayClassNameFromRecord(
|
||||
record,
|
||||
CCharacterCreation::m_character->m_data.m_info.sexID);
|
||||
if (className) {
|
||||
lua_pushstring(L, className);
|
||||
lua_pushstring(L, record->m_filename);
|
||||
// TODO: Expansion Check
|
||||
lua_pushnumber(L, 1.0);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
lua_pushnil(L);
|
||||
lua_pushnil(L);
|
||||
}
|
||||
}
|
||||
return CCharacterCreation::m_classes.Count() * 3;
|
||||
}
|
||||
|
||||
int32_t Script_GetHairCustomization(lua_State* L) {
|
||||
|
Loading…
Reference in New Issue
Block a user