mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-02-04 18:09:56 +00:00
Merge branch 'main' into cdclient-rework
This commit is contained in:
@@ -3,21 +3,27 @@
|
||||
|
||||
#include "BrickDatabase.h"
|
||||
#include "Game.h"
|
||||
#include "AssetManager.h"
|
||||
#include "tinyxml2.h"
|
||||
#include "Brick.h"
|
||||
|
||||
std::vector<Brick> BrickDatabase::emptyCache{};
|
||||
BrickDatabase* BrickDatabase::m_Address = nullptr;
|
||||
const BrickList& BrickDatabase::GetBricks(const LxfmlPath& lxfmlPath) {
|
||||
static std::unordered_map<LxfmlPath, BrickList> m_Cache;
|
||||
static const BrickList emptyCache;
|
||||
|
||||
BrickDatabase::BrickDatabase() = default;
|
||||
BrickDatabase::~BrickDatabase() = default;
|
||||
|
||||
std::vector<Brick>& BrickDatabase::GetBricks(const std::string& lxfmlPath) {
|
||||
const auto cached = m_Cache.find(lxfmlPath);
|
||||
|
||||
if (cached != m_Cache.end()) {
|
||||
return cached->second;
|
||||
}
|
||||
|
||||
std::ifstream file(lxfmlPath);
|
||||
AssetMemoryBuffer buffer = Game::assetManager->GetFileAsBuffer((lxfmlPath).c_str());
|
||||
|
||||
if (!buffer.m_Success) {
|
||||
return emptyCache;
|
||||
}
|
||||
|
||||
std::istream file(&buffer);
|
||||
if (!file.good()) {
|
||||
return emptyCache;
|
||||
}
|
||||
@@ -25,16 +31,19 @@ std::vector<Brick>& BrickDatabase::GetBricks(const std::string& lxfmlPath) {
|
||||
std::stringstream data;
|
||||
data << file.rdbuf();
|
||||
if (data.str().empty()) {
|
||||
buffer.close();
|
||||
return emptyCache;
|
||||
}
|
||||
|
||||
buffer.close();
|
||||
|
||||
auto* doc = new tinyxml2::XMLDocument();
|
||||
if (doc->Parse(data.str().c_str(), data.str().size()) != 0) {
|
||||
delete doc;
|
||||
return emptyCache;
|
||||
}
|
||||
|
||||
std::vector<Brick> parts;
|
||||
BrickList parts;
|
||||
|
||||
auto* lxfml = doc->FirstChildElement("LXFML");
|
||||
auto* bricks = lxfml->FirstChildElement("Bricks");
|
||||
|
||||
@@ -1,29 +1,16 @@
|
||||
#ifndef __BRICKDATABASE__H__
|
||||
#define __BRICKDATABASE__H__
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Entity.h"
|
||||
|
||||
class BrickDatabase
|
||||
{
|
||||
public:
|
||||
static BrickDatabase* Instance() {
|
||||
if (m_Address == nullptr) {
|
||||
m_Address = new BrickDatabase();
|
||||
}
|
||||
class Brick;
|
||||
using BrickList = std::vector<Brick>;
|
||||
using LxfmlPath = std::string;
|
||||
|
||||
return m_Address;
|
||||
}
|
||||
|
||||
std::vector<Brick>& GetBricks(const std::string& lxfmlPath);
|
||||
|
||||
explicit BrickDatabase();
|
||||
|
||||
~BrickDatabase();
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::vector<Brick>> m_Cache;
|
||||
|
||||
static std::vector<Brick> emptyCache;
|
||||
|
||||
static BrickDatabase* m_Address; //For singleton method
|
||||
|
||||
/* data */
|
||||
namespace BrickDatabase {
|
||||
const BrickList& GetBricks(const LxfmlPath& lxfmlPath);
|
||||
};
|
||||
|
||||
#endif //!__BRICKDATABASE__H__
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
set(DGAME_DUTILITIES_SOURCES "BrickDatabase.cpp"
|
||||
"dLocale.cpp"
|
||||
"GameConfig.cpp"
|
||||
"GUID.cpp"
|
||||
"Loot.cpp"
|
||||
"Mail.cpp"
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
#include "GameConfig.h"
|
||||
#include <sstream>
|
||||
|
||||
std::map<std::string, std::string> GameConfig::m_Config{};
|
||||
std::string GameConfig::m_EmptyString{};
|
||||
|
||||
void GameConfig::Load(const std::string& filepath) {
|
||||
m_EmptyString = "";
|
||||
std::ifstream in(filepath);
|
||||
if (!in.good()) return;
|
||||
|
||||
std::string line;
|
||||
while (std::getline(in, line)) {
|
||||
if (line.length() > 0) {
|
||||
if (line[0] != '#') ProcessLine(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& GameConfig::GetValue(const std::string& key) {
|
||||
const auto& it = m_Config.find(key);
|
||||
|
||||
if (it != m_Config.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return m_EmptyString;
|
||||
}
|
||||
|
||||
void GameConfig::SetValue(const std::string& key, const std::string& value) {
|
||||
m_Config.insert_or_assign(key, value);
|
||||
}
|
||||
|
||||
void GameConfig::ProcessLine(const std::string& line) {
|
||||
std::stringstream ss(line);
|
||||
std::string segment;
|
||||
std::vector<std::string> seglist;
|
||||
|
||||
while (std::getline(ss, segment, '=')) {
|
||||
seglist.push_back(segment);
|
||||
}
|
||||
|
||||
if (seglist.size() != 2) return;
|
||||
|
||||
//Make sure that on Linux, we remove special characters:
|
||||
if (!seglist[1].empty() && seglist[1][seglist[1].size() - 1] == '\r')
|
||||
seglist[1].erase(seglist[1].size() - 1);
|
||||
|
||||
m_Config.insert_or_assign(seglist[0], seglist[1]);
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
#pragma once
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "GeneralUtils.h"
|
||||
|
||||
class GameConfig {
|
||||
public:
|
||||
static void Load(const std::string& filepath);
|
||||
|
||||
static const std::string& GetValue(const std::string& key);
|
||||
|
||||
static void SetValue(const std::string& key, const std::string& value);
|
||||
|
||||
template <typename T>
|
||||
static T GetValue(const std::string& key) {
|
||||
T value;
|
||||
|
||||
if (GeneralUtils::TryParse(GetValue(key), value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return T();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void SetValue(const std::string& key, const T& value) {
|
||||
SetValue(key, std::to_string(value));
|
||||
}
|
||||
|
||||
private:
|
||||
static void ProcessLine(const std::string& line);
|
||||
|
||||
static std::map<std::string, std::string> m_Config;
|
||||
static std::string m_EmptyString;
|
||||
};
|
||||
@@ -7,19 +7,23 @@
|
||||
#include "CDLootMatrixTable.h"
|
||||
#include "CDLootTableTable.h"
|
||||
#include "CDRarityTableTable.h"
|
||||
#include "CDActivityRewardsTable.h"
|
||||
#include "CDCurrencyTableTable.h"
|
||||
#include "Character.h"
|
||||
#include "Entity.h"
|
||||
#include "GameMessages.h"
|
||||
#include "GeneralUtils.h"
|
||||
#include "InventoryComponent.h"
|
||||
#include "MissionComponent.h"
|
||||
#include "eMissionState.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
|
||||
LootGenerator::LootGenerator() {
|
||||
CDLootTableTable* lootTableTable = CDClientManager::Instance()->GetTable<CDLootTableTable>("LootTable");
|
||||
CDComponentsRegistryTable* componentsRegistryTable = CDClientManager::Instance()->GetTable<CDComponentsRegistryTable>("ComponentsRegistry");
|
||||
CDItemComponentTable* itemComponentTable = CDClientManager::Instance()->GetTable<CDItemComponentTable>("ItemComponent");
|
||||
CDLootMatrixTable* lootMatrixTable = CDClientManager::Instance()->GetTable<CDLootMatrixTable>("LootMatrix");
|
||||
CDRarityTableTable* rarityTableTable = CDClientManager::Instance()->GetTable<CDRarityTableTable>("RarityTable");
|
||||
CDLootTableTable* lootTableTable = CDClientManager::Instance().GetTable<CDLootTableTable>();
|
||||
CDComponentsRegistryTable* componentsRegistryTable = CDClientManager::Instance().GetTable<CDComponentsRegistryTable>();
|
||||
CDItemComponentTable* itemComponentTable = CDClientManager::Instance().GetTable<CDItemComponentTable>();
|
||||
CDLootMatrixTable* lootMatrixTable = CDClientManager::Instance().GetTable<CDLootMatrixTable>();
|
||||
CDRarityTableTable* rarityTableTable = CDClientManager::Instance().GetTable<CDRarityTableTable>();
|
||||
|
||||
// ==============================
|
||||
// Cache Item Rarities
|
||||
@@ -36,7 +40,7 @@ LootGenerator::LootGenerator() {
|
||||
uniqueItems.erase(std::unique(uniqueItems.begin(), uniqueItems.end()), uniqueItems.end());
|
||||
|
||||
for (const uint32_t itemID : uniqueItems) {
|
||||
uint32_t itemComponentID = componentsRegistryTable->GetByIDAndType(itemID, COMPONENT_TYPE_ITEM);
|
||||
uint32_t itemComponentID = componentsRegistryTable->GetByIDAndType(itemID, eReplicaComponentType::ITEM);
|
||||
const CDItemComponent& item = itemComponentTable->GetItemComponentByID(itemComponentID);
|
||||
|
||||
m_ItemRarities.insert({ itemID, item.rarity });
|
||||
@@ -186,13 +190,13 @@ std::unordered_map<LOT, int32_t> LootGenerator::RollLootMatrix(Entity* player, u
|
||||
|
||||
// convert faction token proxy
|
||||
if (drop.itemID == 13763) {
|
||||
if (missionComponent->GetMissionState(545) == MissionState::MISSION_STATE_COMPLETE)
|
||||
if (missionComponent->GetMissionState(545) == eMissionState::COMPLETE)
|
||||
drop.itemID = 8318; // "Assembly Token"
|
||||
else if (missionComponent->GetMissionState(556) == MissionState::MISSION_STATE_COMPLETE)
|
||||
else if (missionComponent->GetMissionState(556) == eMissionState::COMPLETE)
|
||||
drop.itemID = 8321; // "Venture League Token"
|
||||
else if (missionComponent->GetMissionState(567) == MissionState::MISSION_STATE_COMPLETE)
|
||||
else if (missionComponent->GetMissionState(567) == eMissionState::COMPLETE)
|
||||
drop.itemID = 8319; // "Sentinels Token"
|
||||
else if (missionComponent->GetMissionState(578) == MissionState::MISSION_STATE_COMPLETE)
|
||||
else if (missionComponent->GetMissionState(578) == eMissionState::COMPLETE)
|
||||
drop.itemID = 8320; // "Paradox Token"
|
||||
}
|
||||
|
||||
@@ -290,7 +294,7 @@ void LootGenerator::GiveLoot(Entity* player, std::unordered_map<LOT, int32_t>& r
|
||||
}
|
||||
|
||||
void LootGenerator::GiveActivityLoot(Entity* player, Entity* source, uint32_t activityID, int32_t rating) {
|
||||
CDActivityRewardsTable* activityRewardsTable = CDClientManager::Instance()->GetTable<CDActivityRewardsTable>("ActivityRewards");
|
||||
CDActivityRewardsTable* activityRewardsTable = CDClientManager::Instance().GetTable<CDActivityRewardsTable>();
|
||||
std::vector<CDActivityRewards> activityRewards = activityRewardsTable->Query([activityID](CDActivityRewards entry) { return (entry.objectTemplate == activityID); });
|
||||
|
||||
const CDActivityRewards* selectedReward = nullptr;
|
||||
@@ -306,7 +310,7 @@ void LootGenerator::GiveActivityLoot(Entity* player, Entity* source, uint32_t ac
|
||||
uint32_t minCoins = 0;
|
||||
uint32_t maxCoins = 0;
|
||||
|
||||
CDCurrencyTableTable* currencyTableTable = CDClientManager::Instance()->GetTable<CDCurrencyTableTable>("CurrencyTable");
|
||||
CDCurrencyTableTable* currencyTableTable = CDClientManager::Instance().GetTable<CDCurrencyTableTable>();
|
||||
std::vector<CDCurrencyTable> currencyTable = currencyTableTable->Query([selectedReward](CDCurrencyTable entry) { return (entry.currencyIndex == selectedReward->CurrencyIndex && entry.npcminlevel == 1); });
|
||||
|
||||
if (currencyTable.size() > 0) {
|
||||
@@ -314,13 +318,13 @@ void LootGenerator::GiveActivityLoot(Entity* player, Entity* source, uint32_t ac
|
||||
maxCoins = currencyTable[0].maxvalue;
|
||||
}
|
||||
|
||||
GiveLoot(player, selectedReward->LootMatrixIndex, eLootSourceType::LOOT_SOURCE_ACTIVITY);
|
||||
GiveLoot(player, selectedReward->LootMatrixIndex, eLootSourceType::ACTIVITY);
|
||||
|
||||
uint32_t coins = (int)(minCoins + GeneralUtils::GenerateRandomNumber<float>(0, 1) * (maxCoins - minCoins));
|
||||
|
||||
auto* character = player->GetCharacter();
|
||||
|
||||
character->SetCoins(character->GetCoins() + coins, eLootSourceType::LOOT_SOURCE_ACTIVITY);
|
||||
character->SetCoins(character->GetCoins() + coins, eLootSourceType::ACTIVITY);
|
||||
}
|
||||
|
||||
void LootGenerator::DropLoot(Entity* player, Entity* killedObject, uint32_t matrixIndex, uint32_t minCoins, uint32_t maxCoins) {
|
||||
@@ -360,7 +364,7 @@ void LootGenerator::DropLoot(Entity* player, Entity* killedObject, std::unordere
|
||||
}
|
||||
|
||||
void LootGenerator::DropActivityLoot(Entity* player, Entity* source, uint32_t activityID, int32_t rating) {
|
||||
CDActivityRewardsTable* activityRewardsTable = CDClientManager::Instance()->GetTable<CDActivityRewardsTable>("ActivityRewards");
|
||||
CDActivityRewardsTable* activityRewardsTable = CDClientManager::Instance().GetTable<CDActivityRewardsTable>();
|
||||
std::vector<CDActivityRewards> activityRewards = activityRewardsTable->Query([activityID](CDActivityRewards entry) { return (entry.objectTemplate == activityID); });
|
||||
|
||||
const CDActivityRewards* selectedReward = nullptr;
|
||||
@@ -377,7 +381,7 @@ void LootGenerator::DropActivityLoot(Entity* player, Entity* source, uint32_t ac
|
||||
uint32_t minCoins = 0;
|
||||
uint32_t maxCoins = 0;
|
||||
|
||||
CDCurrencyTableTable* currencyTableTable = CDClientManager::Instance()->GetTable<CDCurrencyTableTable>("CurrencyTable");
|
||||
CDCurrencyTableTable* currencyTableTable = CDClientManager::Instance().GetTable<CDCurrencyTableTable>();
|
||||
std::vector<CDCurrencyTable> currencyTable = currencyTableTable->Query([selectedReward](CDCurrencyTable entry) { return (entry.currencyIndex == selectedReward->CurrencyIndex && entry.npcminlevel == 1); });
|
||||
|
||||
if (currencyTable.size() > 0) {
|
||||
|
||||
@@ -47,8 +47,8 @@ public:
|
||||
|
||||
std::unordered_map<LOT, int32_t> RollLootMatrix(Entity* player, uint32_t matrixIndex);
|
||||
std::unordered_map<LOT, int32_t> RollLootMatrix(uint32_t matrixIndex);
|
||||
void GiveLoot(Entity* player, uint32_t matrixIndex, eLootSourceType lootSourceType = eLootSourceType::LOOT_SOURCE_NONE);
|
||||
void GiveLoot(Entity* player, std::unordered_map<LOT, int32_t>& result, eLootSourceType lootSourceType = eLootSourceType::LOOT_SOURCE_NONE);
|
||||
void GiveLoot(Entity* player, uint32_t matrixIndex, eLootSourceType lootSourceType = eLootSourceType::NONE);
|
||||
void GiveLoot(Entity* player, std::unordered_map<LOT, int32_t>& result, eLootSourceType lootSourceType = eLootSourceType::NONE);
|
||||
void GiveActivityLoot(Entity* player, Entity* source, uint32_t activityID, int32_t rating = 0);
|
||||
void DropLoot(Entity* player, Entity* killedObject, uint32_t matrixIndex, uint32_t minCoins, uint32_t maxCoins);
|
||||
void DropLoot(Entity* player, Entity* killedObject, std::unordered_map<LOT, int32_t>& result, uint32_t minCoins, uint32_t maxCoins);
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "Entity.h"
|
||||
#include "Character.h"
|
||||
#include "PacketUtils.h"
|
||||
#include "dMessageIdentifiers.h"
|
||||
#include "dLogger.h"
|
||||
#include "EntityManager.h"
|
||||
#include "InventoryComponent.h"
|
||||
@@ -22,6 +21,11 @@
|
||||
#include "MissionComponent.h"
|
||||
#include "ChatPackets.h"
|
||||
#include "Character.h"
|
||||
#include "dZoneManager.h"
|
||||
#include "WorldConfig.h"
|
||||
#include "eMissionTaskType.h"
|
||||
#include "eReplicaComponentType.h"
|
||||
#include "eConnectionType.h"
|
||||
|
||||
void Mail::SendMail(const Entity* recipient, const std::string& subject, const std::string& body, const LOT attachment,
|
||||
const uint16_t attachmentCount) {
|
||||
@@ -74,12 +78,12 @@ void Mail::SendMail(const LWOOBJID sender, const std::string& senderName, LWOOBJ
|
||||
auto* ins = Database::CreatePreppedStmt("INSERT INTO `mail`(`sender_id`, `sender_name`, `receiver_id`, `receiver_name`, `time_sent`, `subject`, `body`, `attachment_id`, `attachment_lot`, `attachment_subkey`, `attachment_count`, `was_read`) VALUES (?,?,?,?,?,?,?,?,?,?,?,0)");
|
||||
|
||||
ins->setUInt(1, sender);
|
||||
ins->setString(2, senderName);
|
||||
ins->setString(2, senderName.c_str());
|
||||
ins->setUInt(3, recipient);
|
||||
ins->setString(4, recipientName.c_str());
|
||||
ins->setUInt64(5, time(nullptr));
|
||||
ins->setString(6, subject);
|
||||
ins->setString(7, body);
|
||||
ins->setString(6, subject.c_str());
|
||||
ins->setString(7, body.c_str());
|
||||
ins->setUInt(8, 0);
|
||||
ins->setInt(9, attachment);
|
||||
ins->setInt(10, 0);
|
||||
@@ -126,7 +130,7 @@ void Mail::HandleMailStuff(RakNet::BitStream* packet, const SystemAddress& sysAd
|
||||
int mailStuffID = 0;
|
||||
packet->Read(mailStuffID);
|
||||
|
||||
std::async(std::launch::async, [packet, &sysAddr, entity, mailStuffID]() {
|
||||
auto returnVal = std::async(std::launch::async, [packet, &sysAddr, entity, mailStuffID]() {
|
||||
Mail::MailMessageID stuffID = MailMessageID(mailStuffID);
|
||||
switch (stuffID) {
|
||||
case MailMessageID::AttachmentCollect:
|
||||
@@ -163,7 +167,7 @@ void Mail::HandleSendMail(RakNet::BitStream* packet, const SystemAddress& sysAdd
|
||||
|
||||
if (!character) return;
|
||||
|
||||
if (character->HasPermission(PermissionMap::RestrictedMailAccess)) {
|
||||
if (character->HasPermission(ePermissionMap::RestrictedMailAccess)) {
|
||||
// Send a message to the player
|
||||
ChatPackets::SendSystemMessage(
|
||||
sysAddr,
|
||||
@@ -191,15 +195,15 @@ void Mail::HandleSendMail(RakNet::BitStream* packet, const SystemAddress& sysAdd
|
||||
uint32_t itemID = static_cast<uint32_t>(attachmentID);
|
||||
LOT itemLOT = 0;
|
||||
//Inventory::InventoryType itemType;
|
||||
int mailCost = 25;
|
||||
int mailCost = Game::zoneManager->GetWorldConfig()->mailBaseFee;
|
||||
int stackSize = 0;
|
||||
auto inv = static_cast<InventoryComponent*>(entity->GetComponent(COMPONENT_TYPE_INVENTORY));
|
||||
auto inv = static_cast<InventoryComponent*>(entity->GetComponent(eReplicaComponentType::INVENTORY));
|
||||
Item* item = nullptr;
|
||||
|
||||
if (itemID > 0 && attachmentCount > 0 && inv) {
|
||||
item = inv->FindItemById(attachmentID);
|
||||
if (item) {
|
||||
mailCost += (item->GetInfo().baseValue * 0.1f);
|
||||
mailCost += (item->GetInfo().baseValue * Game::zoneManager->GetWorldConfig()->mailPercentAttachmentFee);
|
||||
stackSize = item->GetCount();
|
||||
itemLOT = item->GetLot();
|
||||
} else {
|
||||
@@ -255,7 +259,7 @@ void Mail::HandleSendMail(RakNet::BitStream* packet, const SystemAddress& sysAdd
|
||||
}
|
||||
|
||||
Mail::SendSendResponse(sysAddr, Mail::MailSendResponse::Success);
|
||||
entity->GetCharacter()->SetCoins(entity->GetCharacter()->GetCoins() - mailCost, eLootSourceType::LOOT_SOURCE_MAIL);
|
||||
entity->GetCharacter()->SetCoins(entity->GetCharacter()->GetCoins() - mailCost, eLootSourceType::MAIL);
|
||||
|
||||
Game::logger->Log("Mail", "Seeing if we need to remove item with ID/count/LOT: %i %i %i", itemID, attachmentCount, itemLOT);
|
||||
|
||||
@@ -266,7 +270,7 @@ void Mail::HandleSendMail(RakNet::BitStream* packet, const SystemAddress& sysAdd
|
||||
auto* missionCompoent = entity->GetComponent<MissionComponent>();
|
||||
|
||||
if (missionCompoent != nullptr) {
|
||||
missionCompoent->Progress(MissionTaskType::MISSION_TASK_TYPE_ITEM_COLLECTION, itemLOT, LWOOBJID_EMPTY, "", -attachmentCount);
|
||||
missionCompoent->Progress(eMissionTaskType::GATHER, itemLOT, LWOOBJID_EMPTY, "", -attachmentCount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +283,7 @@ void Mail::HandleDataRequest(RakNet::BitStream* packet, const SystemAddress& sys
|
||||
sql::ResultSet* res = stmt->executeQuery();
|
||||
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_MAIL);
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
|
||||
bitStream.Write(int(MailMessageID::MailData));
|
||||
bitStream.Write(int(0));
|
||||
|
||||
@@ -352,10 +356,10 @@ void Mail::HandleAttachmentCollect(RakNet::BitStream* packet, const SystemAddres
|
||||
attachmentCount = res->getInt(2);
|
||||
}
|
||||
|
||||
auto inv = static_cast<InventoryComponent*>(player->GetComponent(COMPONENT_TYPE_INVENTORY));
|
||||
auto inv = static_cast<InventoryComponent*>(player->GetComponent(eReplicaComponentType::INVENTORY));
|
||||
if (!inv) return;
|
||||
|
||||
inv->AddItem(attachmentLOT, attachmentCount, eLootSourceType::LOOT_SOURCE_MAIL);
|
||||
inv->AddItem(attachmentLOT, attachmentCount, eLootSourceType::MAIL);
|
||||
|
||||
Mail::SendAttachmentRemoveConfirm(sysAddr, mailID);
|
||||
|
||||
@@ -389,7 +393,7 @@ void Mail::HandleMailRead(RakNet::BitStream* packet, const SystemAddress& sysAdd
|
||||
}
|
||||
|
||||
void Mail::HandleNotificationRequest(const SystemAddress& sysAddr, uint32_t objectID) {
|
||||
std::async(std::launch::async, [&]() {
|
||||
auto returnVal = std::async(std::launch::async, [&]() {
|
||||
sql::PreparedStatement* stmt = Database::CreatePreppedStmt("SELECT id FROM mail WHERE receiver_id=? AND was_read=0");
|
||||
stmt->setUInt(1, objectID);
|
||||
sql::ResultSet* res = stmt->executeQuery();
|
||||
@@ -402,7 +406,7 @@ void Mail::HandleNotificationRequest(const SystemAddress& sysAddr, uint32_t obje
|
||||
|
||||
void Mail::SendSendResponse(const SystemAddress& sysAddr, MailSendResponse response) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_MAIL);
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
|
||||
bitStream.Write(int(MailMessageID::SendResponse));
|
||||
bitStream.Write(int(response));
|
||||
Game::server->Send(&bitStream, sysAddr, false);
|
||||
@@ -410,7 +414,7 @@ void Mail::SendSendResponse(const SystemAddress& sysAddr, MailSendResponse respo
|
||||
|
||||
void Mail::SendNotification(const SystemAddress& sysAddr, int mailCount) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_MAIL);
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
|
||||
uint64_t messageType = 2;
|
||||
uint64_t s1 = 0;
|
||||
uint64_t s2 = 0;
|
||||
@@ -429,7 +433,7 @@ void Mail::SendNotification(const SystemAddress& sysAddr, int mailCount) {
|
||||
|
||||
void Mail::SendAttachmentRemoveConfirm(const SystemAddress& sysAddr, uint64_t mailID) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_MAIL);
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
|
||||
bitStream.Write(int(MailMessageID::AttachmentCollectConfirm));
|
||||
bitStream.Write(int(0)); //unknown
|
||||
bitStream.Write(mailID);
|
||||
@@ -438,7 +442,7 @@ void Mail::SendAttachmentRemoveConfirm(const SystemAddress& sysAddr, uint64_t ma
|
||||
|
||||
void Mail::SendDeleteConfirm(const SystemAddress& sysAddr, uint64_t mailID, LWOOBJID playerID) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_MAIL);
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
|
||||
bitStream.Write(int(MailMessageID::MailDeleteConfirm));
|
||||
bitStream.Write(int(0)); //unknown
|
||||
bitStream.Write(mailID);
|
||||
@@ -452,7 +456,7 @@ void Mail::SendDeleteConfirm(const SystemAddress& sysAddr, uint64_t mailID, LWOO
|
||||
|
||||
void Mail::SendReadConfirm(const SystemAddress& sysAddr, uint64_t mailID) {
|
||||
RakNet::BitStream bitStream;
|
||||
PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_MAIL);
|
||||
PacketUtils::WriteHeader(bitStream, eConnectionType::CLIENT, eClientMessageType::MAIL);
|
||||
bitStream.Write(int(MailMessageID::MailReadConfirm));
|
||||
bitStream.Write(int(0)); //unknown
|
||||
bitStream.Write(mailID);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "LevelProgressionComponent.h"
|
||||
#include "DestroyableComponent.h"
|
||||
#include "GameMessages.h"
|
||||
|
||||
#include "eMissionState.h"
|
||||
|
||||
std::map<uint32_t, Precondition*> Preconditions::cache = {};
|
||||
|
||||
@@ -142,19 +142,19 @@ bool Precondition::CheckValue(Entity* player, const uint32_t value, bool evaluat
|
||||
case PreconditionType::HasAchievement:
|
||||
mission = missionComponent->GetMission(value);
|
||||
|
||||
return mission == nullptr || mission->GetMissionState() >= MissionState::MISSION_STATE_COMPLETE;
|
||||
return mission == nullptr || mission->GetMissionState() >= eMissionState::COMPLETE;
|
||||
case PreconditionType::MissionAvailable:
|
||||
mission = missionComponent->GetMission(value);
|
||||
|
||||
return mission == nullptr || mission->GetMissionState() >= MissionState::MISSION_STATE_AVAILABLE;
|
||||
return mission == nullptr || mission->GetMissionState() >= eMissionState::AVAILABLE;
|
||||
case PreconditionType::OnMission:
|
||||
mission = missionComponent->GetMission(value);
|
||||
|
||||
return mission == nullptr || mission->GetMissionState() >= MissionState::MISSION_STATE_ACTIVE;
|
||||
return mission == nullptr || mission->GetMissionState() >= eMissionState::ACTIVE;
|
||||
case PreconditionType::MissionComplete:
|
||||
mission = missionComponent->GetMission(value);
|
||||
|
||||
return mission == nullptr || mission->GetMissionState() >= MissionState::MISSION_STATE_COMPLETE;
|
||||
return mission == nullptr ? false : mission->GetMissionState() >= eMissionState::COMPLETE;
|
||||
case PreconditionType::PetDeployed:
|
||||
return false; // TODO
|
||||
case PreconditionType::HasFlag:
|
||||
@@ -277,11 +277,6 @@ bool PreconditionExpression::Check(Entity* player, bool evaluateCosts) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (player->GetGMLevel() >= 9) // Developers can skip this for testing
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const auto a = Preconditions::Check(player, condition, evaluateCosts);
|
||||
|
||||
if (!a) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,8 +13,6 @@ class Entity;
|
||||
|
||||
namespace SlashCommandHandler {
|
||||
void HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr);
|
||||
bool CheckIfAccessibleZone(const unsigned int zoneID);
|
||||
|
||||
void SendAnnouncement(const std::string& title, const std::string& message);
|
||||
};
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include "tinyxml2.h"
|
||||
#include "Game.h"
|
||||
#include "dLogger.h"
|
||||
#include "BinaryPathFinder.h"
|
||||
#include "EntityInfo.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
@@ -27,7 +29,7 @@ void VanityUtilities::SpawnVanity() {
|
||||
|
||||
const uint32_t zoneID = Game::server->GetZoneID();
|
||||
|
||||
ParseXML("./vanity/NPC.xml");
|
||||
ParseXML((BinaryPathFinder::GetBinaryDir() / "vanity/NPC.xml").string());
|
||||
|
||||
// Loop through all parties
|
||||
for (const auto& party : m_Parties) {
|
||||
@@ -63,17 +65,21 @@ void VanityUtilities::SpawnVanity() {
|
||||
npcIndex = GeneralUtils::GenerateRandomNumber<uint32_t>(0, npcList.size() - 1);
|
||||
}
|
||||
|
||||
const auto& npc = npcList[npcIndex];
|
||||
auto& npc = npcList[npcIndex];
|
||||
|
||||
taken.push_back(npcIndex);
|
||||
|
||||
// Spawn the NPC
|
||||
std::vector<LDFBaseData*> data = { new LDFData<std::vector<std::u16string>>(
|
||||
u"syncLDF", { u"custom_script_client" }),
|
||||
new LDFData<std::u16string>(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua") };
|
||||
Game::logger->Log("VanityUtilities", "ldf size is %i", npc.ldf.size());
|
||||
if (npc.ldf.empty()) {
|
||||
npc.ldf = {
|
||||
new LDFData<std::vector<std::u16string>>(u"syncLDF", { u"custom_script_client" }),
|
||||
new LDFData<std::u16string>(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua")
|
||||
};
|
||||
}
|
||||
|
||||
// Spawn the NPC
|
||||
auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, data);
|
||||
auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, npc.ldf);
|
||||
|
||||
npcEntity->SetVar<std::vector<std::string>>(u"chats", m_PartyPhrases);
|
||||
|
||||
@@ -84,11 +90,11 @@ void VanityUtilities::SpawnVanity() {
|
||||
}
|
||||
|
||||
// Loop through all NPCs
|
||||
for (const auto& pair : m_NPCs) {
|
||||
if (pair.m_Locations.find(Game::server->GetZoneID()) == pair.m_Locations.end())
|
||||
for (auto& npc : m_NPCs) {
|
||||
if (npc.m_Locations.find(Game::server->GetZoneID()) == npc.m_Locations.end())
|
||||
continue;
|
||||
|
||||
const std::vector<VanityNPCLocation>& locations = pair.m_Locations.at(Game::server->GetZoneID());
|
||||
const std::vector<VanityNPCLocation>& locations = npc.m_Locations.at(Game::server->GetZoneID());
|
||||
|
||||
// Pick a random location
|
||||
const auto& location = locations[GeneralUtils::GenerateRandomNumber<int>(
|
||||
@@ -99,27 +105,30 @@ void VanityUtilities::SpawnVanity() {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<LDFBaseData*> data = { new LDFData<std::vector<std::u16string>>(
|
||||
u"syncLDF", { u"custom_script_client" }),
|
||||
new LDFData<std::u16string>(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua") };
|
||||
if (npc.ldf.empty()) {
|
||||
npc.ldf = {
|
||||
new LDFData<std::vector<std::u16string>>(u"syncLDF", { u"custom_script_client" }),
|
||||
new LDFData<std::u16string>(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua")
|
||||
};
|
||||
}
|
||||
|
||||
// Spawn the NPC
|
||||
auto* npc = SpawnNPC(pair.m_LOT, pair.m_Name, location.m_Position, location.m_Rotation, pair.m_Equipment, data);
|
||||
auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, npc.ldf);
|
||||
|
||||
npc->SetVar<std::vector<std::string>>(u"chats", pair.m_Phrases);
|
||||
npcEntity->SetVar<std::vector<std::string>>(u"chats", npc.m_Phrases);
|
||||
|
||||
auto* scriptComponent = npc->GetComponent<ScriptComponent>();
|
||||
auto* scriptComponent = npcEntity->GetComponent<ScriptComponent>();
|
||||
|
||||
if (scriptComponent != nullptr) {
|
||||
scriptComponent->SetScript(pair.m_Script);
|
||||
if (scriptComponent && !npc.m_Script.empty()) {
|
||||
scriptComponent->SetScript(npc.m_Script);
|
||||
scriptComponent->SetSerialized(false);
|
||||
|
||||
for (const auto& pair : pair.m_Flags) {
|
||||
npc->SetVar<bool>(GeneralUtils::ASCIIToUTF16(pair.first), pair.second);
|
||||
for (const auto& npc : npc.m_Flags) {
|
||||
npcEntity->SetVar<bool>(GeneralUtils::ASCIIToUTF16(npc.first), npc.second);
|
||||
}
|
||||
}
|
||||
|
||||
SetupNPCTalk(npc);
|
||||
SetupNPCTalk(npcEntity);
|
||||
}
|
||||
|
||||
if (zoneID == 1200) {
|
||||
@@ -128,14 +137,14 @@ void VanityUtilities::SpawnVanity() {
|
||||
info.lot = 8139;
|
||||
info.pos = { 259.5f, 246.4f, -705.2f };
|
||||
info.rot = { 0.0f, 0.0f, 1.0f, 0.0f };
|
||||
info.spawnerID = EntityManager::Instance()->GetZoneControlEntity()->GetObjectID();
|
||||
info.spawnerID = Game::entityManager->GetZoneControlEntity()->GetObjectID();
|
||||
|
||||
info.settings = { new LDFData<bool>(u"hasCustomText", true),
|
||||
new LDFData<std::string>(u"customText", ParseMarkdown("./vanity/TESTAMENT.md")) };
|
||||
new LDFData<std::string>(u"customText", ParseMarkdown((BinaryPathFinder::GetBinaryDir() / "vanity/TESTAMENT.md").string())) };
|
||||
|
||||
auto* entity = EntityManager::Instance()->CreateEntity(info);
|
||||
auto* entity = Game::entityManager->CreateEntity(info);
|
||||
|
||||
EntityManager::Instance()->ConstructEntity(entity);
|
||||
Game::entityManager->ConstructEntity(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,15 +155,15 @@ Entity* VanityUtilities::SpawnNPC(LOT lot, const std::string& name, const NiPoin
|
||||
info.lot = lot;
|
||||
info.pos = position;
|
||||
info.rot = rotation;
|
||||
info.spawnerID = EntityManager::Instance()->GetZoneControlEntity()->GetObjectID();
|
||||
info.spawnerID = Game::entityManager->GetZoneControlEntity()->GetObjectID();
|
||||
info.settings = ldf;
|
||||
|
||||
auto* entity = EntityManager::Instance()->CreateEntity(info);
|
||||
auto* entity = Game::entityManager->CreateEntity(info);
|
||||
entity->SetVar(u"npcName", name);
|
||||
|
||||
auto* inventoryComponent = entity->GetComponent<InventoryComponent>();
|
||||
|
||||
if (inventoryComponent != nullptr) {
|
||||
if (inventoryComponent && !inventory.empty()) {
|
||||
inventoryComponent->SetNPCItems(inventory);
|
||||
}
|
||||
|
||||
@@ -166,7 +175,7 @@ Entity* VanityUtilities::SpawnNPC(LOT lot, const std::string& name, const NiPoin
|
||||
destroyableComponent->SetHealth(0);
|
||||
}
|
||||
|
||||
EntityManager::Instance()->ConstructEntity(entity);
|
||||
Game::entityManager->ConstructEntity(entity);
|
||||
|
||||
return entity;
|
||||
}
|
||||
@@ -264,10 +273,7 @@ void VanityUtilities::ParseXML(const std::string& file) {
|
||||
// Get the NPC name
|
||||
auto* name = npc->Attribute("name");
|
||||
|
||||
if (name == nullptr) {
|
||||
Game::logger->Log("VanityUtilities", "Failed to parse NPC name");
|
||||
continue;
|
||||
}
|
||||
if (!name) name = "";
|
||||
|
||||
// Get the NPC lot
|
||||
auto* lot = npc->Attribute("lot");
|
||||
@@ -279,71 +285,76 @@ void VanityUtilities::ParseXML(const std::string& file) {
|
||||
|
||||
// Get the equipment
|
||||
auto* equipment = npc->FirstChildElement("equipment");
|
||||
|
||||
if (equipment == nullptr) {
|
||||
Game::logger->Log("VanityUtilities", "Failed to parse NPC equipment");
|
||||
continue;
|
||||
}
|
||||
|
||||
auto* text = equipment->GetText();
|
||||
|
||||
std::vector<LOT> inventory;
|
||||
|
||||
if (text != nullptr) {
|
||||
std::string equipmentString(text);
|
||||
if (equipment) {
|
||||
auto* text = equipment->GetText();
|
||||
|
||||
std::vector<std::string> splitEquipment = GeneralUtils::SplitString(equipmentString, ',');
|
||||
if (text != nullptr) {
|
||||
std::string equipmentString(text);
|
||||
|
||||
for (auto& item : splitEquipment) {
|
||||
inventory.push_back(std::stoi(item));
|
||||
std::vector<std::string> splitEquipment = GeneralUtils::SplitString(equipmentString, ',');
|
||||
|
||||
for (auto& item : splitEquipment) {
|
||||
inventory.push_back(std::stoi(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get the phrases
|
||||
auto* phrases = npc->FirstChildElement("phrases");
|
||||
|
||||
if (phrases == nullptr) {
|
||||
Game::logger->Log("VanityUtilities", "Failed to parse NPC phrases");
|
||||
continue;
|
||||
}
|
||||
std::vector<std::string> phraseList = {};
|
||||
|
||||
std::vector<std::string> phraseList;
|
||||
|
||||
for (auto* phrase = phrases->FirstChildElement("phrase"); phrase != nullptr;
|
||||
phrase = phrase->NextSiblingElement("phrase")) {
|
||||
// Get the phrase
|
||||
auto* text = phrase->GetText();
|
||||
|
||||
if (text == nullptr) {
|
||||
Game::logger->Log("VanityUtilities", "Failed to parse NPC phrase");
|
||||
continue;
|
||||
if (phrases) {
|
||||
for (auto* phrase = phrases->FirstChildElement("phrase"); phrase != nullptr;
|
||||
phrase = phrase->NextSiblingElement("phrase")) {
|
||||
// Get the phrase
|
||||
auto* text = phrase->GetText();
|
||||
if (text == nullptr) {
|
||||
Game::logger->Log("VanityUtilities", "Failed to parse NPC phrase");
|
||||
continue;
|
||||
}
|
||||
phraseList.push_back(text);
|
||||
}
|
||||
|
||||
phraseList.push_back(text);
|
||||
}
|
||||
|
||||
// Get the script
|
||||
auto* scriptElement = npc->FirstChildElement("script");
|
||||
|
||||
std::string scriptName;
|
||||
std::string scriptName = "";
|
||||
|
||||
if (scriptElement != nullptr) {
|
||||
auto* scriptNameAttribute = scriptElement->Attribute("name");
|
||||
|
||||
if (scriptNameAttribute == nullptr) {
|
||||
Game::logger->Log("VanityUtilities", "Failed to parse NPC script name");
|
||||
continue;
|
||||
}
|
||||
|
||||
scriptName = scriptNameAttribute;
|
||||
if (scriptNameAttribute) scriptName = scriptNameAttribute;
|
||||
}
|
||||
|
||||
auto* ldfElement = npc->FirstChildElement("ldf");
|
||||
std::vector<std::u16string> keys = {};
|
||||
|
||||
std::vector<LDFBaseData*> ldf = {};
|
||||
if(ldfElement) {
|
||||
for (auto* entry = ldfElement->FirstChildElement("entry"); entry != nullptr;
|
||||
entry = entry->NextSiblingElement("entry")) {
|
||||
// Get the ldf data
|
||||
auto* data = entry->Attribute("data");
|
||||
if (!data) continue;
|
||||
|
||||
LDFBaseData* ldfData = LDFBaseData::DataFromString(data);
|
||||
keys.push_back(ldfData->GetKey());
|
||||
ldf.push_back(ldfData);
|
||||
}
|
||||
}
|
||||
if (!keys.empty()) ldf.push_back(new LDFData<std::vector<std::u16string>>(u"syncLDF", keys));
|
||||
|
||||
VanityNPC npcData;
|
||||
npcData.m_Name = name;
|
||||
npcData.m_LOT = std::stoi(lot);
|
||||
npcData.m_Equipment = inventory;
|
||||
npcData.m_Phrases = phraseList;
|
||||
npcData.m_Script = scriptName;
|
||||
npcData.ldf = ldf;
|
||||
|
||||
// Get flags
|
||||
auto* flags = npc->FirstChildElement("flags");
|
||||
@@ -524,7 +535,7 @@ void VanityUtilities::NPCTalk(Entity* npc) {
|
||||
npc->GetObjectID(), u"sendToclient_bubble", 0, 0, npc->GetObjectID(), selected, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
}
|
||||
|
||||
EntityManager::Instance()->SerializeEntity(npc);
|
||||
Game::entityManager->SerializeEntity(npc);
|
||||
|
||||
const float nextTime = GeneralUtils::GenerateRandomNumber<float>(15, 60);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ struct VanityNPC
|
||||
std::string m_Script;
|
||||
std::map<std::string, bool> m_Flags;
|
||||
std::map<uint32_t, std::vector<VanityNPCLocation>> m_Locations;
|
||||
std::vector<LDFBaseData*> ldf;
|
||||
};
|
||||
|
||||
struct VanityParty
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
#include "dLocale.h"
|
||||
|
||||
#include <clocale>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "tinyxml2.h"
|
||||
#include "Game.h"
|
||||
#include "dConfig.h"
|
||||
|
||||
dLocale::dLocale() {
|
||||
if (Game::config->GetValue("locale_enabled") != "1") {
|
||||
return;
|
||||
}
|
||||
|
||||
std::ifstream file(m_LocalePath);
|
||||
|
||||
if (!file.good()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::stringstream data;
|
||||
data << file.rdbuf();
|
||||
|
||||
if (data.str().empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* doc = new tinyxml2::XMLDocument();
|
||||
|
||||
if (doc == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (doc->Parse(data.str().c_str(), data.str().size()) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::hash<std::string> hash;
|
||||
|
||||
auto* localization = doc->FirstChildElement("localization");
|
||||
auto* phrases = localization->FirstChildElement("phrases");
|
||||
|
||||
auto* phrase = phrases->FirstChildElement("phrase");
|
||||
|
||||
while (phrase != nullptr) {
|
||||
// Add the phrase hash to the vector
|
||||
m_Phrases.push_back(hash(phrase->Attribute("id")));
|
||||
phrase = phrase->NextSiblingElement("phrase");
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
delete doc;
|
||||
}
|
||||
|
||||
dLocale::~dLocale() = default;
|
||||
|
||||
std::string dLocale::GetTemplate(const std::string& phraseID) {
|
||||
return "%[" + phraseID + "]";
|
||||
}
|
||||
|
||||
bool dLocale::HasPhrase(const std::string& phraseID) {
|
||||
if (Game::config->GetValue("locale_enabled") != "1") {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Compute the hash and see if it's in the vector
|
||||
std::hash<std::string> hash;
|
||||
std::size_t hashValue = hash(phraseID);
|
||||
return std::find(m_Phrases.begin(), m_Phrases.end(), hashValue) != m_Phrases.end();
|
||||
}
|
||||
|
||||
/*std::string dLocale::GetPhrase(const std::string& phraseID) {
|
||||
if (m_Phrases.find(phraseID) == m_Phrases.end()) {
|
||||
return "";
|
||||
}
|
||||
return m_Phrases[phraseID];
|
||||
}*/
|
||||
@@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
class dLocale {
|
||||
public:
|
||||
dLocale();
|
||||
~dLocale();
|
||||
static std::string GetTemplate(const std::string& phraseID);
|
||||
bool HasPhrase(const std::string& phraseID);
|
||||
//std::string GetPhrase(const std::string& phraseID);
|
||||
|
||||
private:
|
||||
std::string m_LocalePath = "./locale/locale.xml";
|
||||
std::string m_Locale = "en_US"; // TODO: add to config
|
||||
std::vector<std::size_t> m_Phrases;
|
||||
};
|
||||
Reference in New Issue
Block a user