Replace most collections with Arbutils collections for more safety.
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#define CREATURELIB_BASELIBRARY_HPP
|
||||
|
||||
#include <Arbutils/Assert.hpp>
|
||||
#include <Arbutils/Collections/Dictionary.hpp>
|
||||
#include <Arbutils/ConstString.hpp>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
@@ -9,7 +10,7 @@
|
||||
|
||||
namespace CreatureLib::Library {
|
||||
template <class T> class BaseLibrary {
|
||||
std::unordered_map<uint32_t, const T*> _values;
|
||||
Arbutils::Collections::Dictionary<uint32_t, const T*> _values;
|
||||
|
||||
public:
|
||||
BaseLibrary(size_t initialCapacity = 32) : _values(initialCapacity) {}
|
||||
@@ -18,46 +19,40 @@ namespace CreatureLib::Library {
|
||||
for (const auto& v : _values) {
|
||||
delete v.second;
|
||||
}
|
||||
_values.clear();
|
||||
_values.Clear();
|
||||
}
|
||||
|
||||
inline void Insert(const Arbutils::CaseInsensitiveConstString& key, const T* value) {
|
||||
AssertNotNull(value)
|
||||
_values.insert({key.GetHash(), value});
|
||||
_values.Insert(key.GetHash(), value);
|
||||
}
|
||||
inline void Insert(uint32_t hashedKey, const T* value) {
|
||||
AssertNotNull(value)
|
||||
_values.insert({hashedKey, value});
|
||||
_values.Insert(hashedKey, value);
|
||||
}
|
||||
|
||||
inline void Delete(const Arbutils::CaseInsensitiveConstString& key) { _values.erase(key.GetHash()); }
|
||||
inline void Delete(uint32_t hashedKey) { _values.erase({hashedKey}); }
|
||||
inline void Delete(uint32_t hashedKey) { _values.Remove(hashedKey); }
|
||||
|
||||
bool TryGet(const Arbutils::CaseInsensitiveConstString& name, const T*& out) const {
|
||||
return TryGet(name.GetHash(), out);
|
||||
}
|
||||
bool TryGet(uint32_t hashedKey, const T*& out) const {
|
||||
auto find = this->_values.find(hashedKey);
|
||||
if (find == this->_values.end()) {
|
||||
out = nullptr;
|
||||
return false;
|
||||
}
|
||||
out = find->second;
|
||||
return true;
|
||||
}
|
||||
bool TryGet(uint32_t hashedKey, const T*& out) const { return _values.TryGet(hashedKey, out); }
|
||||
|
||||
[[nodiscard]] inline const T* Get(const Arbutils::CaseInsensitiveConstString& name) const {
|
||||
return _values.at(name.GetHash());
|
||||
return _values.Get(name.GetHash());
|
||||
}
|
||||
[[nodiscard]] inline const T* Get(uint32_t hashedKey) const { return _values.at(hashedKey); }
|
||||
[[nodiscard]] inline const T* Get(uint32_t hashedKey) const { return _values.Get(hashedKey); }
|
||||
|
||||
[[nodiscard]] inline const T* operator[](const Arbutils::CaseInsensitiveConstString& name) const {
|
||||
return Get(name);
|
||||
}
|
||||
[[nodiscard]] inline const T* operator[](uint32_t hashedKey) const { return Get(hashedKey); }
|
||||
[[nodiscard]] inline const std::unordered_map<uint32_t, const T*>& GetIterator() const { return _values; }
|
||||
[[nodiscard]] inline const Arbutils::Collections::Dictionary<uint32_t, const T*>& GetIterator() const {
|
||||
return _values;
|
||||
}
|
||||
|
||||
[[nodiscard]] size_t GetCount() const { return _values.size(); }
|
||||
[[nodiscard]] size_t GetCount() const { return _values.Count(); }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -10,30 +10,21 @@ CreatureSpecies::CreatureSpecies(uint16_t id, const ConstString& name, const Spe
|
||||
AssertNotNull(defaultVariant)
|
||||
}
|
||||
|
||||
bool CreatureSpecies::HasVariant(const ConstString& name) const { return _variants.find(name) != _variants.end(); }
|
||||
bool CreatureSpecies::HasVariant(const ConstString& name) const { return _variants.Has(name); }
|
||||
|
||||
bool CreatureSpecies::TryGetVariant(const ConstString& name, const SpeciesVariant*& out) const {
|
||||
return TryGetVariant(name.GetHash(), out);
|
||||
}
|
||||
bool CreatureSpecies::TryGetVariant(uint32_t hash, const SpeciesVariant*& out) const {
|
||||
auto find = _variants.find(hash);
|
||||
if (find != _variants.end()) {
|
||||
out = find->second;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return _variants.TryGet(hash, out);
|
||||
}
|
||||
|
||||
const SpeciesVariant* CreatureSpecies::GetVariant(const ConstString& name) const { return _variants.at(name); }
|
||||
const SpeciesVariant* CreatureSpecies::GetVariant(uint32_t key) const { return _variants.at(key); }
|
||||
bool CreatureSpecies::HasVariant(uint32_t hash) const { return _variants.at(hash); }
|
||||
const SpeciesVariant* CreatureSpecies::GetVariant(const ConstString& name) const { return _variants.Get(name); }
|
||||
const SpeciesVariant* CreatureSpecies::GetVariant(uint32_t key) const { return _variants.Get(key); }
|
||||
bool CreatureSpecies::HasVariant(uint32_t hash) const { return _variants.Has(hash); }
|
||||
|
||||
void CreatureSpecies::SetVariant(const ConstString& name, const SpeciesVariant* variant) {
|
||||
auto find = _variants.find(name);
|
||||
if (find != _variants.end()) {
|
||||
delete find->second;
|
||||
}
|
||||
_variants[name] = variant;
|
||||
_variants.Insert(name, variant);
|
||||
}
|
||||
|
||||
Gender CreatureSpecies::GetRandomGender(Arbutils::Random& rand) const {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef CREATURELIB_CREATURESPECIES_HPP
|
||||
#define CREATURELIB_CREATURESPECIES_HPP
|
||||
|
||||
#include <Arbutils/Collections/Dictionary.hpp>
|
||||
#include <Arbutils/ConstString.hpp>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
@@ -20,7 +21,7 @@ namespace CreatureLib::Library {
|
||||
float _genderRate;
|
||||
const ConstString _growthRate;
|
||||
uint8_t _captureRate;
|
||||
std::unordered_map<uint32_t, const SpeciesVariant*> _variants;
|
||||
Arbutils::Collections::Dictionary<uint32_t, const SpeciesVariant*> _variants;
|
||||
|
||||
public:
|
||||
CreatureSpecies(uint16_t id, const ConstString& name, const SpeciesVariant* defaultVariant, float genderRatio,
|
||||
@@ -29,7 +30,7 @@ namespace CreatureLib::Library {
|
||||
virtual ~CreatureSpecies() {
|
||||
for (auto v : _variants)
|
||||
delete v.second;
|
||||
_variants.clear();
|
||||
_variants.Clear();
|
||||
}
|
||||
|
||||
inline uint16_t GetId() const { return _id; }
|
||||
@@ -48,7 +49,9 @@ namespace CreatureLib::Library {
|
||||
|
||||
void SetVariant(const ConstString& name, const SpeciesVariant* variant);
|
||||
|
||||
const std::unordered_map<uint32_t, const SpeciesVariant*>& GetVariantsIterator() const { return _variants; }
|
||||
const Arbutils::Collections::Dictionary<uint32_t, const SpeciesVariant*>& GetVariantsIterator() const {
|
||||
return _variants;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,14 +3,16 @@
|
||||
using namespace CreatureLib::Library;
|
||||
|
||||
void LearnableAttacks::AddLevelMove(uint8_t level, const AttackData* attack) {
|
||||
auto find = _learnedByLevel.find(level);
|
||||
if (find != _learnedByLevel.end()) {
|
||||
find->second.push_back(attack);
|
||||
|
||||
List<const AttackData*> levelData;
|
||||
if (_learnedByLevel.TryGet(level, levelData)) {
|
||||
levelData.Append(attack);
|
||||
} else {
|
||||
_learnedByLevel.insert({level, {attack}});
|
||||
levelData = {attack};
|
||||
_learnedByLevel.Insert(level, levelData);
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<const AttackData*>& LearnableAttacks::GetAttacksForLevel(uint8_t level) const {
|
||||
return _learnedByLevel.at(level);
|
||||
const List<const AttackData*>& LearnableAttacks::GetAttacksForLevel(uint8_t level) const {
|
||||
return _learnedByLevel.Get(level);
|
||||
}
|
||||
|
||||
@@ -2,17 +2,20 @@
|
||||
#define CREATURELIB_LEARNABLEATTACKS_HPP
|
||||
|
||||
#include <Arbutils/Assert.hpp>
|
||||
#include <Arbutils/Collections/Dictionary.hpp>
|
||||
#include <Arbutils/Collections/List.hpp>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include "../Attacks/AttackData.hpp"
|
||||
|
||||
using namespace Arbutils::Collections;
|
||||
|
||||
namespace CreatureLib::Library {
|
||||
class LearnableAttacks {
|
||||
std::unordered_map<uint8_t, std::vector<const AttackData*>> _learnedByLevel;
|
||||
Dictionary<uint8_t, List<const AttackData*>> _learnedByLevel;
|
||||
|
||||
public:
|
||||
LearnableAttacks(size_t levelAttackCapacity)
|
||||
: _learnedByLevel(std::unordered_map<uint8_t, std::vector<const AttackData*>>(levelAttackCapacity)) {
|
||||
: _learnedByLevel(Dictionary<uint8_t, List<const AttackData*>>(levelAttackCapacity)) {
|
||||
for (auto kv : _learnedByLevel) {
|
||||
for (auto attack : kv.second)
|
||||
AssertNotNull(attack)
|
||||
@@ -21,7 +24,7 @@ namespace CreatureLib::Library {
|
||||
|
||||
void AddLevelMove(uint8_t level, const AttackData* attack);
|
||||
|
||||
const std::vector<const AttackData*>& GetAttacksForLevel(uint8_t level) const;
|
||||
const List<const AttackData*>& GetAttacksForLevel(uint8_t level) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
const std::vector<uint8_t>& CreatureLib::Library::SpeciesVariant::GetTypes() const { return _types; }
|
||||
const List<uint8_t>& CreatureLib::Library::SpeciesVariant::GetTypes() const { return _types; }
|
||||
|
||||
size_t CreatureLib::Library::SpeciesVariant::GetTypeCount() const { return _types.size(); }
|
||||
size_t CreatureLib::Library::SpeciesVariant::GetTypeCount() const { return _types.Count(); }
|
||||
|
||||
uint8_t CreatureLib::Library::SpeciesVariant::GetType(size_t index) const { return _types[index]; }
|
||||
|
||||
@@ -14,13 +14,13 @@ uint32_t CreatureLib::Library::SpeciesVariant::GetStatistic(CreatureLib::Library
|
||||
|
||||
const CreatureLib::Library::TalentIndex
|
||||
CreatureLib::Library::SpeciesVariant::GetTalentIndex(const ConstString& talent) const {
|
||||
for (size_t i = 0; i < _talents.size(); i++) {
|
||||
if (_talents.at(i) == talent) {
|
||||
for (size_t i = 0; i < _talents.Count(); i++) {
|
||||
if (_talents.At(i) == talent) {
|
||||
return TalentIndex(false, i);
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < _secretTalents.size(); i++) {
|
||||
if (_secretTalents.at(i) == talent) {
|
||||
for (size_t i = 0; i < _secretTalents.Count(); i++) {
|
||||
if (_secretTalents.At(i) == talent) {
|
||||
return TalentIndex(true, i);
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ CreatureLib::Library::SpeciesVariant::GetTalentIndex(const ConstString& talent)
|
||||
}
|
||||
|
||||
CreatureLib::Library::TalentIndex CreatureLib::Library::SpeciesVariant::GetRandomTalent(Arbutils::Random* rand) const {
|
||||
return TalentIndex(false, rand->Get(_talents.size()));
|
||||
return TalentIndex(false, rand->Get(_talents.Count()));
|
||||
}
|
||||
|
||||
const CreatureLib::Library::LearnableAttacks* CreatureLib::Library::SpeciesVariant::GetLearnableAttacks() const {
|
||||
@@ -36,10 +36,9 @@ const CreatureLib::Library::LearnableAttacks* CreatureLib::Library::SpeciesVaria
|
||||
}
|
||||
|
||||
CreatureLib::Library::SpeciesVariant::SpeciesVariant(ConstString name, float height, float weight,
|
||||
uint32_t baseExperience, std::vector<uint8_t> types,
|
||||
uint32_t baseExperience, List<uint8_t> types,
|
||||
CreatureLib::Library::StatisticSet<uint16_t> baseStats,
|
||||
std::vector<ConstString> talents,
|
||||
std::vector<ConstString> secretTalents,
|
||||
List<ConstString> talents, List<ConstString> secretTalents,
|
||||
const LearnableAttacks* attacks)
|
||||
: _name(std::move(name)), _height(height), _weight(weight), _baseExperience(baseExperience),
|
||||
_types(std::move(types)), _baseStatistics(baseStats), _talents(std::move(talents)),
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
#ifndef CREATURELIB_SPECIESVARIANT_HPP
|
||||
#define CREATURELIB_SPECIESVARIANT_HPP
|
||||
|
||||
#include <Arbutils/Collections/List.hpp>
|
||||
#include <Arbutils/Random.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "../StatisticSet.hpp"
|
||||
#include "CreatureMoves.hpp"
|
||||
#include "LearnableAttacks.hpp"
|
||||
#include "TalentIndex.hpp"
|
||||
using ConstString = Arbutils::CaseInsensitiveConstString;
|
||||
using namespace Arbutils::Collections;
|
||||
|
||||
namespace CreatureLib::Library {
|
||||
/*!
|
||||
@@ -22,17 +23,16 @@ namespace CreatureLib::Library {
|
||||
uint32_t _baseExperience;
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> _types;
|
||||
List<uint8_t> _types;
|
||||
Library::StatisticSet<uint16_t> _baseStatistics;
|
||||
std::vector<ConstString> _talents;
|
||||
std::vector<ConstString> _secretTalents;
|
||||
List<ConstString> _talents;
|
||||
List<ConstString> _secretTalents;
|
||||
const LearnableAttacks* _attacks;
|
||||
|
||||
public:
|
||||
SpeciesVariant(ConstString name, float height, float weight, uint32_t baseExperience,
|
||||
std::vector<uint8_t> types, Library::StatisticSet<uint16_t> baseStats,
|
||||
std::vector<ConstString> talents, std::vector<ConstString> secretTalents,
|
||||
const LearnableAttacks* attacks);
|
||||
SpeciesVariant(ConstString name, float height, float weight, uint32_t baseExperience, List<uint8_t> types,
|
||||
Library::StatisticSet<uint16_t> baseStats, List<ConstString> talents,
|
||||
List<ConstString> secretTalents, const LearnableAttacks* attacks);
|
||||
|
||||
virtual ~SpeciesVariant();
|
||||
|
||||
@@ -43,21 +43,21 @@ namespace CreatureLib::Library {
|
||||
|
||||
[[nodiscard]] size_t GetTypeCount() const;
|
||||
[[nodiscard]] uint8_t GetType(size_t index) const;
|
||||
[[nodiscard]] const std::vector<uint8_t>& GetTypes() const;
|
||||
[[nodiscard]] const List<uint8_t>& GetTypes() const;
|
||||
[[nodiscard]] uint32_t GetStatistic(Library::Statistic stat) const;
|
||||
[[nodiscard]] const size_t GetTalentCount() const { return _talents.size(); }
|
||||
[[nodiscard]] const size_t GetSecretTalentCount() const { return _secretTalents.size(); }
|
||||
[[nodiscard]] const size_t GetTalentCount() const { return _talents.Count(); }
|
||||
[[nodiscard]] const size_t GetSecretTalentCount() const { return _secretTalents.Count(); }
|
||||
[[nodiscard]] const ConstString& GetTalent(const TalentIndex& index) const {
|
||||
if (index.IsSecret())
|
||||
return _secretTalents.at(index.GetIndex());
|
||||
return _talents.at(index.GetIndex());
|
||||
return _secretTalents.At(index.GetIndex());
|
||||
return _talents.At(index.GetIndex());
|
||||
}
|
||||
[[nodiscard]] const TalentIndex GetTalentIndex(const ConstString& talent) const;
|
||||
|
||||
[[nodiscard]] const LearnableAttacks* GetLearnableAttacks() const;
|
||||
[[nodiscard]] TalentIndex GetRandomTalent(Arbutils::Random* rand) const;
|
||||
[[nodiscard]] inline const std::vector<ConstString>& GetTalents() const { return _talents; }
|
||||
[[nodiscard]] inline const std::vector<ConstString>& GetSecretTalents() const { return _secretTalents; }
|
||||
[[nodiscard]] inline const List<ConstString>& GetTalents() const { return _talents; }
|
||||
[[nodiscard]] inline const List<ConstString>& GetSecretTalents() const { return _secretTalents; }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,29 +1,27 @@
|
||||
#ifndef CREATURELIB_LOOKUPGROWTHRATE_HPP
|
||||
#define CREATURELIB_LOOKUPGROWTHRATE_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <Arbutils/Collections/List.hpp>
|
||||
#include "GrowthRate.hpp"
|
||||
|
||||
namespace CreatureLib::Library {
|
||||
class LookupGrowthRate : public GrowthRate {
|
||||
protected:
|
||||
std::vector<uint32_t> _experience;
|
||||
Arbutils::Collections::List<uint32_t> _experience;
|
||||
|
||||
public:
|
||||
LookupGrowthRate(const std::vector<uint32_t>& experience) : _experience(experience) {}
|
||||
LookupGrowthRate(const Arbutils::Collections::List<uint32_t>& experience) : _experience(experience) {}
|
||||
|
||||
uint8_t CalculateLevel(uint32_t experience) const override {
|
||||
for (uint8_t i = 0; i < _experience.size(); i++) {
|
||||
for (uint8_t i = 0; i < _experience.Count(); i++) {
|
||||
if (_experience[i] > experience) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return _experience[_experience.size() - 1];
|
||||
return _experience[_experience.Count() - 1];
|
||||
}
|
||||
|
||||
uint32_t CalculateExperience(uint8_t level) const override {
|
||||
Assert(level <= _experience.size())
|
||||
return _experience[level - 1];
|
||||
}
|
||||
uint32_t CalculateExperience(uint8_t level) const override { return _experience[level - 1]; }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
using namespace CreatureLib::Library;
|
||||
|
||||
float TypeLibrary::GetEffectiveness(uint8_t attacking, const std::vector<uint8_t>& defensive) const {
|
||||
float TypeLibrary::GetEffectiveness(uint8_t attacking, const List<uint8_t>& defensive) const {
|
||||
auto eff = 1;
|
||||
for (auto def : defensive) {
|
||||
eff *= GetSingleEffectiveness(attacking, def);
|
||||
@@ -12,33 +12,29 @@ float TypeLibrary::GetEffectiveness(uint8_t attacking, const std::vector<uint8_t
|
||||
}
|
||||
|
||||
float TypeLibrary::GetSingleEffectiveness(uint8_t attacking, uint8_t defensive) const {
|
||||
Assert(attacking < _effectiveness.size())
|
||||
Assert(defensive < _effectiveness.size())
|
||||
return _effectiveness[attacking][defensive];
|
||||
}
|
||||
|
||||
uint8_t TypeLibrary::GetTypeId(const ConstString& key) const { return _types.at(key); }
|
||||
uint8_t TypeLibrary::GetTypeId(uint32_t s) const { return _types.at(s); }
|
||||
uint8_t TypeLibrary::GetTypeId(const ConstString& key) const { return _types.Get(key); }
|
||||
uint8_t TypeLibrary::GetTypeId(uint32_t s) const { return _types.Get(s); }
|
||||
|
||||
uint8_t TypeLibrary::RegisterType(const ConstString& key) {
|
||||
_types.insert({key, _types.size()});
|
||||
_effectiveness.resize(_types.size());
|
||||
_types.Insert(key, _types.Count());
|
||||
_effectiveness.Resize(_types.Count());
|
||||
for (auto& eff : _effectiveness) {
|
||||
eff.resize(_types.size(), 1);
|
||||
eff.Resize(_types.Count(), 1);
|
||||
}
|
||||
return _types.size() - 1;
|
||||
return _types.Count() - 1;
|
||||
}
|
||||
uint8_t TypeLibrary::RegisterType(uint32_t key) {
|
||||
_types.insert({key, _types.size()});
|
||||
_effectiveness.resize(_types.size());
|
||||
_types.Insert(key, _types.Count());
|
||||
_effectiveness.Resize(_types.Count());
|
||||
for (auto& eff : _effectiveness) {
|
||||
eff.resize(_types.size(), 1);
|
||||
eff.Resize(_types.Count(), 1);
|
||||
}
|
||||
return _types.size() - 1;
|
||||
return _types.Count() - 1;
|
||||
}
|
||||
|
||||
void TypeLibrary::SetEffectiveness(uint8_t attacking, uint8_t defensive, float effectiveness) {
|
||||
Assert(attacking < _effectiveness.size())
|
||||
Assert(defensive < _effectiveness.size())
|
||||
_effectiveness[attacking][defensive] = effectiveness;
|
||||
}
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
#ifndef CREATURELIB_TYPELIBRARY_HPP
|
||||
#define CREATURELIB_TYPELIBRARY_HPP
|
||||
|
||||
#include <Arbutils/Collections/Dictionary.hpp>
|
||||
#include <Arbutils/Collections/List.hpp>
|
||||
#include <Arbutils/ConstString.hpp>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
using ConstString = Arbutils::CaseInsensitiveConstString;
|
||||
using namespace Arbutils::Collections;
|
||||
|
||||
namespace CreatureLib::Library {
|
||||
class TypeLibrary {
|
||||
std::unordered_map<uint32_t, uint8_t> _types;
|
||||
std::vector<std::vector<float>> _effectiveness;
|
||||
Dictionary<uint32_t, uint8_t> _types;
|
||||
List<List<float>> _effectiveness;
|
||||
|
||||
public:
|
||||
TypeLibrary(size_t initialCapacity = 20) : _types(std::unordered_map<uint32_t, uint8_t>(initialCapacity)) {}
|
||||
TypeLibrary(size_t initialCapacity = 20) : _types(Dictionary<uint32_t, uint8_t>(initialCapacity)) {}
|
||||
|
||||
uint8_t GetTypeId(const ConstString& s) const;
|
||||
uint8_t GetTypeId(uint32_t s) const;
|
||||
[[nodiscard]] float GetSingleEffectiveness(uint8_t attacking, uint8_t defensive) const;
|
||||
[[nodiscard]] float GetEffectiveness(uint8_t attacking, const std::vector<uint8_t>& defensive) const;
|
||||
[[nodiscard]] float GetEffectiveness(uint8_t attacking, const List<uint8_t>& defensive) const;
|
||||
|
||||
uint8_t RegisterType(const ConstString& typeName);
|
||||
uint8_t RegisterType(uint32_t typeHash);
|
||||
|
||||
Reference in New Issue
Block a user