mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-10-26 18:11:59 +00:00
Grim LU
Wincent's attempt at making LU into something it isn't supposed to be, an ARPG.
This commit is contained in:
6
dGame/dGrim/CMakeLists.txt
Normal file
6
dGame/dGrim/CMakeLists.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
set(DGAME_DGRIM_SOURCES "StatProperty.cpp"
|
||||
"ItemModifierTemplate.cpp"
|
||||
"DamageProfile.cpp"
|
||||
"ResistanceProfile.cpp"
|
||||
"SpawnPatterns.cpp"
|
||||
"EntityProfile.cpp" PARENT_SCOPE)
|
||||
56
dGame/dGrim/DamageProfile.cpp
Normal file
56
dGame/dGrim/DamageProfile.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include "DamageProfile.h"
|
||||
|
||||
#include "tinyxml2.h"
|
||||
|
||||
std::map<int32_t, DamageProfile> DamageProfile::s_DamageProfiles;
|
||||
|
||||
void DamageProfile::LoadDamageProfiles(const std::string& filename) {
|
||||
tinyxml2::XMLDocument doc;
|
||||
doc.LoadFile(filename.c_str());
|
||||
|
||||
auto root = doc.FirstChildElement("DamageProfiles");
|
||||
|
||||
for (auto element = root->FirstChildElement("DamageProfile"); element != nullptr; element = element->NextSiblingElement("DamageProfile")) {
|
||||
auto skillID = element->IntAttribute("skillID");
|
||||
|
||||
DamageProfile damageProfile(skillID);
|
||||
|
||||
for (auto damageElement = element->FirstChildElement("Damage"); damageElement != nullptr; damageElement = damageElement->NextSiblingElement("Damage")) {
|
||||
auto statType = damageElement->IntAttribute("type");
|
||||
auto value = damageElement->FloatAttribute("value");
|
||||
|
||||
damageProfile.AddDamageProfile(static_cast<eStatTypes>(statType), value);
|
||||
}
|
||||
|
||||
s_DamageProfiles.emplace(skillID, damageProfile);
|
||||
}
|
||||
}
|
||||
|
||||
DamageProfile* DamageProfile::FindDamageProfile(int32_t skillID) {
|
||||
const auto& it = s_DamageProfiles.find(skillID);
|
||||
|
||||
if (it != s_DamageProfiles.end()) {
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
DamageProfile::DamageProfile(int32_t skillID) {
|
||||
this->m_SkillID = skillID;
|
||||
}
|
||||
|
||||
void DamageProfile::AddDamageProfile(eStatTypes statType, float value) {
|
||||
m_DamageProfile[statType] = value;
|
||||
}
|
||||
|
||||
float DamageProfile::GetDamageProfile(eStatTypes statType) const {
|
||||
const auto& it = m_DamageProfile.find(statType);
|
||||
|
||||
if (it != m_DamageProfile.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
33
dGame/dGrim/DamageProfile.h
Normal file
33
dGame/dGrim/DamageProfile.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __EDAMAGEPROFILE__H__
|
||||
#define __EDAMAGEPROFILE__H__
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "ItemModifierTemplate.h"
|
||||
|
||||
class DamageProfile {
|
||||
public:
|
||||
DamageProfile(int32_t skillID);
|
||||
|
||||
~DamageProfile() = default;
|
||||
|
||||
void AddDamageProfile(eStatTypes statType, float value);
|
||||
|
||||
float GetDamageProfile(eStatTypes statType) const;
|
||||
|
||||
static void LoadDamageProfiles(const std::string& filename);
|
||||
|
||||
static DamageProfile* FindDamageProfile(int32_t skillID);
|
||||
|
||||
private:
|
||||
int32_t m_SkillID;
|
||||
|
||||
std::map<eStatTypes, float> m_DamageProfile;
|
||||
|
||||
static std::map<int32_t, DamageProfile> s_DamageProfiles;
|
||||
};
|
||||
|
||||
#endif //!__EDAMAGEPROFILE__H__
|
||||
38
dGame/dGrim/EntityProfile.cpp
Normal file
38
dGame/dGrim/EntityProfile.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "EntityProfile.h"
|
||||
|
||||
#include "tinyxml2.h"
|
||||
|
||||
std::map<int32_t, EntityProfile> EntityProfile::s_EntityProfiles;
|
||||
|
||||
EntityProfile::EntityProfile(int32_t lot) {
|
||||
this->m_Lot = lot;
|
||||
}
|
||||
|
||||
void EntityProfile::LoadEntityProfiles(const std::string& filename) {
|
||||
tinyxml2::XMLDocument doc;
|
||||
doc.LoadFile(filename.c_str());
|
||||
|
||||
const auto root = doc.FirstChildElement("EntityProfiles");
|
||||
|
||||
for (auto elem = root->FirstChildElement("EntityProfile"); elem != nullptr; elem = elem->NextSiblingElement("EntityProfile")) {
|
||||
const auto lot = elem->IntAttribute("lot");
|
||||
|
||||
EntityProfile profile(lot);
|
||||
|
||||
profile.m_Level = elem->IntAttribute("level");
|
||||
profile.m_Health = elem->IntAttribute("health");
|
||||
profile.m_Armor = elem->IntAttribute("armor");
|
||||
|
||||
s_EntityProfiles.emplace(lot, profile);
|
||||
}
|
||||
}
|
||||
|
||||
EntityProfile* EntityProfile::FindEntityProfile(int32_t lot) {
|
||||
const auto it = s_EntityProfiles.find(lot);
|
||||
|
||||
if (it != s_EntityProfiles.end()) {
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
49
dGame/dGrim/EntityProfile.h
Normal file
49
dGame/dGrim/EntityProfile.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __EENTITYPROFILE__H__
|
||||
#define __EENTITYPROFILE__H__
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "ItemModifierTemplate.h"
|
||||
|
||||
class EntityProfile {
|
||||
public:
|
||||
EntityProfile(int32_t lot);
|
||||
|
||||
~EntityProfile() = default;
|
||||
|
||||
int32_t GetLot() const {
|
||||
return this->m_Lot;
|
||||
}
|
||||
|
||||
int32_t GetLevel() const {
|
||||
return this->m_Level;
|
||||
}
|
||||
|
||||
int32_t GetHealth() const {
|
||||
return this->m_Health;
|
||||
}
|
||||
|
||||
int32_t GetArmor() const {
|
||||
return this->m_Armor;
|
||||
}
|
||||
|
||||
static void LoadEntityProfiles(const std::string& filename);
|
||||
|
||||
static EntityProfile* FindEntityProfile(int32_t lot);
|
||||
|
||||
private:
|
||||
int32_t m_Lot;
|
||||
|
||||
int32_t m_Level;
|
||||
|
||||
int32_t m_Health;
|
||||
|
||||
int32_t m_Armor;
|
||||
|
||||
static std::map<int32_t, EntityProfile> s_EntityProfiles;
|
||||
};
|
||||
|
||||
#endif //!__EENTITYPROFILE__H__
|
||||
315
dGame/dGrim/ItemModifierTemplate.cpp
Normal file
315
dGame/dGrim/ItemModifierTemplate.cpp
Normal file
@@ -0,0 +1,315 @@
|
||||
#include "ItemModifierTemplate.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <tinyxml2.h>
|
||||
#include "Item.h"
|
||||
#include "Entity.h"
|
||||
#include "InventoryComponent.h"
|
||||
#include "LevelProgressionComponent.h"
|
||||
|
||||
std::vector<ItemModifierTemplate> ItemModifierTemplate::s_ItemModifierTemplates;
|
||||
|
||||
void ItemModifierTemplate::LoadItemModifierTemplates(const std::string& filename) {
|
||||
std::vector<ItemModifierTemplate> itemModifierTemplates;
|
||||
|
||||
tinyxml2::XMLDocument doc;
|
||||
doc.LoadFile(filename.c_str());
|
||||
|
||||
tinyxml2::XMLElement* root = doc.FirstChildElement("Templates");
|
||||
|
||||
for (tinyxml2::XMLElement* element = root->FirstChildElement("Template"); element != nullptr; element = element->NextSiblingElement("Template")) {
|
||||
std::string name = element->Attribute("name");
|
||||
eStatRarity rarity = static_cast<eStatRarity>(element->IntAttribute("rarity"));
|
||||
bool isPrefix = element->BoolAttribute("isPrefix");
|
||||
bool isSuffix = element->BoolAttribute("isSuffix");
|
||||
int32_t priority = element->IntAttribute("priority");
|
||||
|
||||
ModifierRoll roll;
|
||||
roll.chance = element->FloatAttribute("chance");
|
||||
roll.levelMultiplier = element->FloatAttribute("levelMultiplier");
|
||||
roll.minRatity = element->IntAttribute("minRarity");
|
||||
roll.standardDeviation = element->FloatAttribute("standardDeviation");
|
||||
|
||||
std::string itemTypes = element->Attribute("itemTypes");
|
||||
std::stringstream ss(itemTypes);
|
||||
std::string itemType;
|
||||
while (std::getline(ss, itemType, ',')) {
|
||||
roll.itemTypes.push_back(static_cast<eItemType>(std::stoi(itemType)));
|
||||
}
|
||||
|
||||
ItemModifierTemplate itemModifierTemplate(name, rarity, isPrefix, isSuffix, roll, priority);
|
||||
|
||||
for (tinyxml2::XMLElement* statElement = element->FirstChildElement("Stat"); statElement != nullptr; statElement = statElement->NextSiblingElement("Stat")) {
|
||||
eStatTypes type = static_cast<eStatTypes>(statElement->IntAttribute("type"));
|
||||
eStatModifier modifier = static_cast<eStatModifier>(statElement->IntAttribute("modifier"));
|
||||
float value = statElement->FloatAttribute("value");
|
||||
|
||||
StatProperty statProperty(type, modifier, value);
|
||||
|
||||
itemModifierTemplate.AddStatProperty(statProperty);
|
||||
}
|
||||
|
||||
itemModifierTemplates.push_back(itemModifierTemplate);
|
||||
}
|
||||
|
||||
s_ItemModifierTemplates = itemModifierTemplates;
|
||||
}
|
||||
|
||||
ItemModifierTemplate* ItemModifierTemplate::FindItemModifierTemplate(const std::string& name) {
|
||||
for (ItemModifierTemplate& itemModifierTemplate : s_ItemModifierTemplates) {
|
||||
if (itemModifierTemplate.m_Name == name) {
|
||||
return &itemModifierTemplate;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ItemModifierTemplate::RollItemModifierTemplates(Item* item, eLootSourceType lootSourceType) {
|
||||
if (item->GetLot() == 6086) return;
|
||||
|
||||
auto* entity = item->GetInventory()->GetComponent()->GetParent();
|
||||
|
||||
auto* levelProgressionComponent = entity->GetComponent<LevelProgressionComponent>();
|
||||
|
||||
if (levelProgressionComponent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t level = levelProgressionComponent->GetLevel();
|
||||
|
||||
std::vector<ItemModifierTemplate*> prefixes;
|
||||
std::vector<ItemModifierTemplate*> suffixes;
|
||||
std::vector<StatProperty> statProperties;
|
||||
|
||||
const auto& itemInfo = item->GetInfo();
|
||||
|
||||
int32_t rarity = itemInfo.rarity;
|
||||
int32_t value = itemInfo.baseValue;
|
||||
|
||||
for (ItemModifierTemplate& itemModifierTemplate : s_ItemModifierTemplates) {
|
||||
const auto& rollInfo = itemModifierTemplate.m_ModifierRoll;
|
||||
|
||||
if (rollInfo.minRatity > rarity) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rollInfo.itemTypes.size() > 0) {
|
||||
bool found = false;
|
||||
for (eItemType itemType : rollInfo.itemTypes) {
|
||||
if (itemType == static_cast<eItemType>(itemInfo.itemType)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
float chance = rollInfo.chance;
|
||||
|
||||
float rng = static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
|
||||
|
||||
if (rng > chance) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (itemModifierTemplate.m_IsPrefix) {
|
||||
prefixes.push_back(&itemModifierTemplate);
|
||||
}
|
||||
else if (itemModifierTemplate.m_IsSuffix) {
|
||||
suffixes.push_back(&itemModifierTemplate);
|
||||
}
|
||||
}
|
||||
|
||||
// Randomize order of prefixes and suffixes
|
||||
std::random_shuffle(prefixes.begin(), prefixes.end());
|
||||
std::random_shuffle(suffixes.begin(), suffixes.end());
|
||||
|
||||
// Add the first prefix and suffix
|
||||
if (prefixes.size() > 0) {
|
||||
ItemModifierTemplate* prefix = prefixes[0];
|
||||
|
||||
item->GetModifiers().push_back(prefix);
|
||||
}
|
||||
|
||||
if (suffixes.size() > 0) {
|
||||
ItemModifierTemplate* suffix = suffixes[0];
|
||||
|
||||
item->GetModifiers().push_back(suffix);
|
||||
}
|
||||
|
||||
// If there are more than one prefix or suffix, there is a 0.05 chance to add another one
|
||||
if (prefixes.size() > 1) {
|
||||
float rng = static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
|
||||
|
||||
if (rng < 0.05f) {
|
||||
ItemModifierTemplate* prefix = prefixes[1];
|
||||
|
||||
item->GetModifiers().push_back(prefix);
|
||||
}
|
||||
}
|
||||
|
||||
if (suffixes.size() > 1) {
|
||||
float rng = static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
|
||||
|
||||
if (rng < 0.05f) {
|
||||
ItemModifierTemplate* suffix = suffixes[1];
|
||||
|
||||
item->GetModifiers().push_back(suffix);
|
||||
}
|
||||
}
|
||||
|
||||
// Add stat properties from prefixes and suffixes
|
||||
for (ItemModifierTemplate* itemModifierTemplate : item->GetModifiers()) {
|
||||
const std::vector<StatProperty>& templateStatProperties = itemModifierTemplate->GetStatProperties();
|
||||
|
||||
auto rollInfo = itemModifierTemplate->m_ModifierRoll;
|
||||
|
||||
// Roll stat properties
|
||||
for (const StatProperty& statProperty : templateStatProperties) {
|
||||
float value = statProperty.value;
|
||||
|
||||
float rng = static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
|
||||
|
||||
float standardDeviation = rollInfo.standardDeviation;
|
||||
|
||||
// (+/-) standardDeviation
|
||||
float deviation = value * ((rng * standardDeviation * 2.0f) - standardDeviation);
|
||||
|
||||
value += deviation;
|
||||
|
||||
float levelMultiplier = rollInfo.levelMultiplier;
|
||||
|
||||
float multiplier = 1.0f + (level * levelMultiplier);
|
||||
|
||||
switch (itemInfo.rarity)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
multiplier += 0.0f;
|
||||
break;
|
||||
case 2:
|
||||
multiplier += 0.5f;
|
||||
break;
|
||||
case 3:
|
||||
multiplier += 0.75f;
|
||||
break;
|
||||
case 4:
|
||||
multiplier += 1.25f;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
value *= multiplier;
|
||||
|
||||
if (itemInfo.isTwoHanded) {
|
||||
value *= 1.75f;
|
||||
}
|
||||
|
||||
if (lootSourceType == eLootSourceType::VENDOR) {
|
||||
value *= 0.75f;
|
||||
}
|
||||
|
||||
// Round to 2 decimal places
|
||||
value = static_cast<float>(static_cast<int32_t>(value * 100.0f)) / 100.0f;
|
||||
|
||||
StatProperty newStatProperty(statProperty.type, statProperty.modifier, value);
|
||||
|
||||
statProperties.push_back(newStatProperty);
|
||||
}
|
||||
}
|
||||
|
||||
// Add stat properties
|
||||
for (const StatProperty& statProperty : statProperties) {
|
||||
item->GetStats().push_back(statProperty);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ItemModifierTemplate::ItemModifierTemplate(const std::string& name, eStatRarity rarity, bool isPrefix, bool isSuffix, const ModifierRoll& roll, int32_t priority) {
|
||||
this->m_Name = name;
|
||||
this->m_Rarity = rarity;
|
||||
this->m_IsPrefix = isPrefix;
|
||||
this->m_IsSuffix = isSuffix;
|
||||
this->m_Priority = priority;
|
||||
this->m_ModifierRoll = roll;
|
||||
this->m_StatProperties = {};
|
||||
}
|
||||
|
||||
void ItemModifierTemplate::AddStatProperty(const StatProperty& statProperty) {
|
||||
m_StatProperties.push_back(statProperty);
|
||||
}
|
||||
|
||||
const std::vector<StatProperty>& ItemModifierTemplate::GetStatProperties() const {
|
||||
return m_StatProperties;
|
||||
}
|
||||
|
||||
std::string ItemModifierTemplate::HtmlString() const {
|
||||
std::stringstream ss;
|
||||
ss << "<font color=\"#";
|
||||
|
||||
switch (m_Rarity)
|
||||
{
|
||||
case eStatRarity::Common:
|
||||
ss << "FFFFFF";
|
||||
break;
|
||||
case eStatRarity::Uncommon:
|
||||
ss << "00FF00";
|
||||
break;
|
||||
case eStatRarity::Rare:
|
||||
ss << "0077FF";
|
||||
break;
|
||||
case eStatRarity::Epic:
|
||||
ss << "FF00FF";
|
||||
break;
|
||||
case eStatRarity::Legendary:
|
||||
ss << "FF7700";
|
||||
break;
|
||||
case eStatRarity::Relic:
|
||||
ss << "FFC391";
|
||||
break;
|
||||
default:
|
||||
ss << "FFFFFF";
|
||||
break;
|
||||
}
|
||||
|
||||
ss << "\">";
|
||||
|
||||
ss << m_Name << "</font>\n";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string ItemModifierTemplate::HtmlString(const std::vector<ItemModifierTemplate*>& itemModifierTemplates) {
|
||||
/*
|
||||
Prefix-1 Prefix-2 NAME Suffix-1 Suffix-2
|
||||
*/
|
||||
std::stringstream ss;
|
||||
|
||||
for (ItemModifierTemplate* itemModifierTemplate : itemModifierTemplates) {
|
||||
if (itemModifierTemplate->m_IsPrefix) {
|
||||
ss << itemModifierTemplate->HtmlString();
|
||||
}
|
||||
}
|
||||
|
||||
ss << "<font color=\"#56B555\">NAME</font>";
|
||||
|
||||
for (ItemModifierTemplate* itemModifierTemplate : itemModifierTemplates) {
|
||||
if (itemModifierTemplate->m_IsSuffix) {
|
||||
ss << itemModifierTemplate->HtmlString();
|
||||
}
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
const std::string& ItemModifierTemplate::GetName() const {
|
||||
return m_Name;
|
||||
}
|
||||
60
dGame/dGrim/ItemModifierTemplate.h
Normal file
60
dGame/dGrim/ItemModifierTemplate.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __ITEMMODIFIERTEMPLATE__H__
|
||||
#define __ITEMMODIFIERTEMPLATE__H__
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include "StatProperty.h"
|
||||
#include "StatRarity.h"
|
||||
#include "eItemType.h"
|
||||
#include "eLootSourceType.h"
|
||||
|
||||
struct ModifierRoll {
|
||||
std::vector<eItemType> itemTypes;
|
||||
int32_t minRatity;
|
||||
float chance;
|
||||
float levelMultiplier;
|
||||
float standardDeviation;
|
||||
};
|
||||
|
||||
class ItemModifierTemplate {
|
||||
public:
|
||||
ItemModifierTemplate(const std::string& name, eStatRarity rarity, bool isPrefix, bool isSuffix, const ModifierRoll& roll, int32_t priority = 0);
|
||||
~ItemModifierTemplate() = default;
|
||||
|
||||
void AddStatProperty(const StatProperty& statProperty);
|
||||
|
||||
const std::vector<StatProperty>& GetStatProperties() const;
|
||||
|
||||
std::string HtmlString() const;
|
||||
|
||||
const std::string& GetName() const;
|
||||
|
||||
static void LoadItemModifierTemplates(const std::string& filename);
|
||||
|
||||
static ItemModifierTemplate* FindItemModifierTemplate(const std::string& name);
|
||||
|
||||
static void RollItemModifierTemplates(class Item* item, eLootSourceType lootSourceType);
|
||||
|
||||
static std::string HtmlString(const std::vector<ItemModifierTemplate*>& itemModifierTemplates);
|
||||
|
||||
private:
|
||||
std::string m_Name;
|
||||
|
||||
eStatRarity m_Rarity;
|
||||
|
||||
ModifierRoll m_ModifierRoll;
|
||||
|
||||
bool m_IsPrefix;
|
||||
bool m_IsSuffix;
|
||||
|
||||
int32_t m_Priority;
|
||||
|
||||
std::vector<StatProperty> m_StatProperties;
|
||||
|
||||
static std::vector<ItemModifierTemplate> s_ItemModifierTemplates;
|
||||
};
|
||||
|
||||
#endif //!__ITEMMODIFIERTEMPLATE__H__
|
||||
67
dGame/dGrim/ResistanceProfile.cpp
Normal file
67
dGame/dGrim/ResistanceProfile.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "ResistanceProfile.h"
|
||||
|
||||
#include "tinyxml2.h"
|
||||
|
||||
std::map<int32_t, ResistanceProfile> ResistanceProfile::s_ResistanceProfiles;
|
||||
|
||||
void ResistanceProfile::LoadResistanceProfiles(const std::string& filename) {
|
||||
tinyxml2::XMLDocument doc;
|
||||
doc.LoadFile(filename.c_str());
|
||||
|
||||
auto root = doc.FirstChildElement("ResistanceProfiles");
|
||||
|
||||
for (auto element = root->FirstChildElement("ResistanceProfile"); element != nullptr; element = element->NextSiblingElement("ResistanceProfile")) {
|
||||
// lot,lot,...
|
||||
auto lots = element->Attribute("lot");
|
||||
|
||||
if (lots == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& splits = GeneralUtils::SplitString(lots, ',');
|
||||
|
||||
for (const auto& split : splits) {
|
||||
const auto lot = std::stoi(split);
|
||||
|
||||
ResistanceProfile resistanceProfile(lot);
|
||||
|
||||
for (auto resistanceElement = element->FirstChildElement("Resistance"); resistanceElement != nullptr; resistanceElement = resistanceElement->NextSiblingElement("Resistance")) {
|
||||
auto statType = resistanceElement->IntAttribute("type");
|
||||
auto value = resistanceElement->FloatAttribute("value");
|
||||
|
||||
resistanceProfile.AddResistanceProfile(static_cast<eStatTypes>(statType), value);
|
||||
}
|
||||
|
||||
s_ResistanceProfiles.emplace(lot, resistanceProfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ResistanceProfile* ResistanceProfile::FindResistanceProfile(int32_t lot) {
|
||||
const auto& it = s_ResistanceProfiles.find(lot);
|
||||
|
||||
if (it != s_ResistanceProfiles.end()) {
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ResistanceProfile::ResistanceProfile(int32_t lot) {
|
||||
this->m_Lot = lot;
|
||||
}
|
||||
|
||||
void ResistanceProfile::AddResistanceProfile(eStatTypes statType, float value) {
|
||||
m_ResistanceProfile[statType] = value;
|
||||
}
|
||||
|
||||
float ResistanceProfile::GetResistanceProfile(eStatTypes statType) const {
|
||||
const auto& it = m_ResistanceProfile.find(statType);
|
||||
|
||||
if (it != m_ResistanceProfile.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
33
dGame/dGrim/ResistanceProfile.h
Normal file
33
dGame/dGrim/ResistanceProfile.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __ERESISTANCEPROFILE__H__
|
||||
#define __ERESISTANCEPROFILE__H__
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "ItemModifierTemplate.h"
|
||||
|
||||
class ResistanceProfile {
|
||||
public:
|
||||
ResistanceProfile(int32_t lot);
|
||||
|
||||
~ResistanceProfile() = default;
|
||||
|
||||
void AddResistanceProfile(eStatTypes statType, float value);
|
||||
|
||||
float GetResistanceProfile(eStatTypes statType) const;
|
||||
|
||||
static void LoadResistanceProfiles(const std::string& filename);
|
||||
|
||||
static ResistanceProfile* FindResistanceProfile(int32_t lot);
|
||||
|
||||
private:
|
||||
int32_t m_Lot;
|
||||
|
||||
std::map<eStatTypes, float> m_ResistanceProfile;
|
||||
|
||||
static std::map<int32_t, ResistanceProfile> s_ResistanceProfiles;
|
||||
};
|
||||
|
||||
#endif //!__ERESISTANCEPROFILE__H__
|
||||
58
dGame/dGrim/SpawnPatterns.cpp
Normal file
58
dGame/dGrim/SpawnPatterns.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#include "SpawnPatterns.h"
|
||||
|
||||
#include "tinyxml2.h"
|
||||
|
||||
std::map<int32_t, SpawnPatterns> SpawnPatterns::s_SpawnPatterns;
|
||||
|
||||
void SpawnPatterns::LoadSpawnPatterns(const std::string& filename) {
|
||||
tinyxml2::XMLDocument doc;
|
||||
doc.LoadFile(filename.c_str());
|
||||
|
||||
auto root = doc.FirstChildElement("SpawnPatterns");
|
||||
|
||||
for (auto element = root->FirstChildElement("SpawnPattern"); element != nullptr; element = element->NextSiblingElement("SpawnPattern")) {
|
||||
auto lot = element->IntAttribute("lot");
|
||||
|
||||
SpawnPatterns spawnPatterns(lot);
|
||||
|
||||
for (auto spawnElement = element->FirstChildElement("Spawn"); spawnElement != nullptr; spawnElement = spawnElement->NextSiblingElement("Spawn")) {
|
||||
auto rating = spawnElement->FloatAttribute("rating");
|
||||
auto chance = spawnElement->FloatAttribute("chance");
|
||||
|
||||
std::vector<int32_t> spawns;
|
||||
|
||||
for (auto spawn = spawnElement->FirstChildElement("SpawnLot"); spawn != nullptr; spawn = spawn->NextSiblingElement("SpawnID")) {
|
||||
auto spawnID = spawn->IntAttribute("lot");
|
||||
|
||||
spawns.push_back(spawnID);
|
||||
}
|
||||
|
||||
spawnPatterns.AddSpawnPatterns(rating, chance, spawns);
|
||||
}
|
||||
|
||||
s_SpawnPatterns.emplace(lot, spawnPatterns);
|
||||
}
|
||||
}
|
||||
|
||||
SpawnPatterns* SpawnPatterns::FindSpawnPatterns(int32_t lot) {
|
||||
const auto& it = s_SpawnPatterns.find(lot);
|
||||
|
||||
if (it != s_SpawnPatterns.end()) {
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SpawnPatterns::SpawnPatterns(int32_t lot)
|
||||
{
|
||||
this->m_Lot = lot;
|
||||
}
|
||||
|
||||
const std::map<float, std::pair<float, std::vector<int32_t>>>& SpawnPatterns::GetSpawnPatterns() const {
|
||||
return m_SpawnPatterns;
|
||||
}
|
||||
|
||||
void SpawnPatterns::AddSpawnPatterns(float rating, float change, std::vector<int32_t> spawns) {
|
||||
m_SpawnPatterns.emplace(rating, std::make_pair(change, spawns));
|
||||
}
|
||||
33
dGame/dGrim/SpawnPatterns.h
Normal file
33
dGame/dGrim/SpawnPatterns.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __ESPAWNPATTERNS__H__
|
||||
#define __ESPAWNPATTERNS__H__
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "ItemModifierTemplate.h"
|
||||
|
||||
class SpawnPatterns {
|
||||
public:
|
||||
SpawnPatterns(int32_t lot);
|
||||
|
||||
~SpawnPatterns() = default;
|
||||
|
||||
void AddSpawnPatterns(float rating, float change, std::vector<int32_t> spawns);
|
||||
|
||||
const std::map<float, std::pair<float, std::vector<int32_t>>>& GetSpawnPatterns() const;
|
||||
|
||||
static void LoadSpawnPatterns(const std::string& filename);
|
||||
|
||||
static SpawnPatterns* FindSpawnPatterns(int32_t lot);
|
||||
|
||||
private:
|
||||
int32_t m_Lot;
|
||||
|
||||
std::map<float, std::pair<float, std::vector<int32_t>>> m_SpawnPatterns;
|
||||
|
||||
static std::map<int32_t, SpawnPatterns> s_SpawnPatterns;
|
||||
};
|
||||
|
||||
#endif //!__ESPAWNPATTERNS__H__
|
||||
18
dGame/dGrim/StatModifier.h
Normal file
18
dGame/dGrim/StatModifier.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __ESTATMODIFIER__H__
|
||||
#define __ESTATMODIFIER__H__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class eStatModifier : uint32_t {
|
||||
Absolute = 0,
|
||||
Percent = 1,
|
||||
DamageAbsolute = 2,
|
||||
DamagePercent = 3,
|
||||
DamageResistance = 4,
|
||||
|
||||
MAX
|
||||
};
|
||||
|
||||
#endif //!__ESTATMODIFIER__H__
|
||||
132
dGame/dGrim/StatProperty.cpp
Normal file
132
dGame/dGrim/StatProperty.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
#include "StatProperty.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
StatProperty::StatProperty(eStatTypes type, eStatModifier modifier, float value) {
|
||||
this->type = type;
|
||||
this->modifier = modifier;
|
||||
this->value = value;
|
||||
}
|
||||
|
||||
std::string StatProperty::HtmlString() {
|
||||
// "<font color=\"#38B6FF\">Physical: +20%</font>\n..."
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "<font color=\"";
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case eStatTypes::Health:
|
||||
ss << "#FF0000";
|
||||
break;
|
||||
case eStatTypes::Armor:
|
||||
ss << "#525252";
|
||||
break;
|
||||
case eStatTypes::Imagination:
|
||||
ss << "#0077FF";
|
||||
break;
|
||||
case eStatTypes::Physical:
|
||||
ss << "#FF9500";
|
||||
break;
|
||||
case eStatTypes::Electric:
|
||||
ss << "#0059FF";
|
||||
break;
|
||||
case eStatTypes::Corruption:
|
||||
ss << "#5500FF";
|
||||
break;
|
||||
case eStatTypes::Heat:
|
||||
ss << "#FF6A00";
|
||||
break;
|
||||
case eStatTypes::Shadow:
|
||||
ss << "#0D0061";
|
||||
break;
|
||||
case eStatTypes::Pierce:
|
||||
ss << "#611200";
|
||||
break;
|
||||
case eStatTypes::Vitality:
|
||||
ss << "#2D0800";
|
||||
break;
|
||||
case eStatTypes::Domination:
|
||||
ss << "#CF00A5";
|
||||
break;
|
||||
default:
|
||||
ss << "#FFFFFF";
|
||||
break;
|
||||
}
|
||||
|
||||
ss << "\">";
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case eStatTypes::Health:
|
||||
ss << "Health";
|
||||
break;
|
||||
case eStatTypes::Armor:
|
||||
ss << "Armor";
|
||||
break;
|
||||
case eStatTypes::Imagination:
|
||||
ss << "Imagination";
|
||||
break;
|
||||
case eStatTypes::Physical:
|
||||
ss << "Physical";
|
||||
break;
|
||||
case eStatTypes::Electric:
|
||||
ss << "Electric";
|
||||
break;
|
||||
case eStatTypes::Corruption:
|
||||
ss << "Corruption";
|
||||
break;
|
||||
case eStatTypes::Heat:
|
||||
ss << "Heat";
|
||||
break;
|
||||
case eStatTypes::Shadow:
|
||||
ss << "Shadow";
|
||||
break;
|
||||
case eStatTypes::Pierce:
|
||||
ss << "Pierce";
|
||||
break;
|
||||
case eStatTypes::Vitality:
|
||||
ss << "Vitality";
|
||||
break;
|
||||
case eStatTypes::Domination:
|
||||
ss << "Domination";
|
||||
break;
|
||||
default:
|
||||
ss << "Unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
switch (modifier)
|
||||
{
|
||||
case eStatModifier::DamageResistance:
|
||||
ss << " Resistance";
|
||||
break;
|
||||
case eStatModifier::DamagePercent:
|
||||
case eStatModifier::DamageAbsolute:
|
||||
ss << " Damage";
|
||||
break;
|
||||
}
|
||||
|
||||
ss << "</font>";
|
||||
|
||||
switch (modifier)
|
||||
{
|
||||
case eStatModifier::Percent:
|
||||
case eStatModifier::DamagePercent:
|
||||
case eStatModifier::DamageResistance:
|
||||
{
|
||||
float percent = value * 100.0f;
|
||||
// Round to 2 decimal places
|
||||
percent = static_cast<float>(static_cast<int32_t>(percent * 100.0f)) / 100.0f;
|
||||
ss << ": +" << percent << "%";
|
||||
}
|
||||
break;
|
||||
case eStatModifier::Absolute:
|
||||
case eStatModifier::DamageAbsolute:
|
||||
default:
|
||||
ss << ": +" << value;
|
||||
break;
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
26
dGame/dGrim/StatProperty.h
Normal file
26
dGame/dGrim/StatProperty.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __ESTAT__H__
|
||||
#define __ESTAT__H__
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "StatModifier.h"
|
||||
#include "StatTypes.h"
|
||||
|
||||
#define BASE_MULTIPLIER 100.0f
|
||||
|
||||
struct StatProperty
|
||||
{
|
||||
eStatTypes type;
|
||||
eStatModifier modifier;
|
||||
float value;
|
||||
|
||||
StatProperty(eStatTypes type, eStatModifier modifier, float value);
|
||||
|
||||
std::string HtmlString();
|
||||
};
|
||||
|
||||
|
||||
#endif //!__ESTAT__H__
|
||||
19
dGame/dGrim/StatRarity.h
Normal file
19
dGame/dGrim/StatRarity.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __ESTATRARITY__H__
|
||||
#define __ESTATRARITY__H__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class eStatRarity : uint32_t {
|
||||
Common = 0,
|
||||
Uncommon = 1,
|
||||
Rare = 2,
|
||||
Epic = 3,
|
||||
Legendary = 4,
|
||||
Relic = 5,
|
||||
|
||||
MAX
|
||||
};
|
||||
|
||||
#endif //!__ESTATRARITY__H__
|
||||
27
dGame/dGrim/StatTypes.h
Normal file
27
dGame/dGrim/StatTypes.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __ESTATTYPES__H__
|
||||
#define __ESTATTYPES__H__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class eStatTypes : uint32_t {
|
||||
// Stats
|
||||
Health = 0,
|
||||
Armor = 1,
|
||||
Imagination = 2,
|
||||
|
||||
// Damage
|
||||
Physical = 3,
|
||||
Electric = 4,
|
||||
Corruption = 5,
|
||||
Heat = 6,
|
||||
Shadow = 7,
|
||||
Pierce = 8,
|
||||
Vitality = 9,
|
||||
Domination = 10,
|
||||
|
||||
MAX
|
||||
};
|
||||
|
||||
#endif //!__ESTATTYPES__H__
|
||||
Reference in New Issue
Block a user