Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 36477abc63 | |||
| 5d53fc74cb | |||
| ecc8d998cf | |||
| e3c0fb2178 | |||
| 090bd806ce |
@@ -2,6 +2,7 @@
|
|||||||
#define ComponentInfo_h__
|
#define ComponentInfo_h__
|
||||||
|
|
||||||
#include "../Common.h"
|
#include "../Common.h"
|
||||||
|
#include "Entity.h"
|
||||||
#include <boost/shared_array.hpp>
|
#include <boost/shared_array.hpp>
|
||||||
|
|
||||||
struct ComponentInfo
|
struct ComponentInfo
|
||||||
@@ -21,6 +22,7 @@ struct ComponentInfo
|
|||||||
{
|
{
|
||||||
std::string Name;
|
std::string Name;
|
||||||
std::string Type;
|
std::string Type;
|
||||||
|
unsigned char Index;
|
||||||
unsigned int Offset;
|
unsigned int Offset;
|
||||||
unsigned int Stride;
|
unsigned int Stride;
|
||||||
};
|
};
|
||||||
@@ -32,6 +34,16 @@ struct ComponentInfo
|
|||||||
unsigned int Stride = 0;
|
unsigned int Stride = 0;
|
||||||
boost::shared_array<char> Defaults = nullptr;
|
boost::shared_array<char> Defaults = nullptr;
|
||||||
std::shared_ptr<Meta_t> Meta = nullptr;
|
std::shared_ptr<Meta_t> Meta = nullptr;
|
||||||
|
|
||||||
|
std::size_t GetHeaderSize() const
|
||||||
|
{
|
||||||
|
std::size_t size = 0;
|
||||||
|
|
||||||
|
// A component block starts with an entity ID
|
||||||
|
size += sizeof(EntityID);
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|||||||
@@ -5,16 +5,15 @@
|
|||||||
#include "MemoryPool.h"
|
#include "MemoryPool.h"
|
||||||
#include "ComponentInfo.h"
|
#include "ComponentInfo.h"
|
||||||
#include "ComponentWrapper.h"
|
#include "ComponentWrapper.h"
|
||||||
|
#include "DirtySet.h"
|
||||||
|
|
||||||
|
|
||||||
|
class ComponentPool;
|
||||||
class ComponentPoolForwardIterator
|
class ComponentPoolForwardIterator
|
||||||
: public std::iterator<std::forward_iterator_tag, ComponentWrapper>
|
: public std::iterator<std::forward_iterator_tag, ComponentWrapper>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ComponentPoolForwardIterator(const ComponentInfo& componentInfo, const MemoryPool<char>::iterator begin, const MemoryPool<char>::iterator end)
|
ComponentPoolForwardIterator(ComponentPool* pool);
|
||||||
: m_ComponentInfo(componentInfo)
|
|
||||||
, m_MemoryPoolIterator(begin)
|
|
||||||
, m_MemoryPoolEnd(end)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
ComponentPoolForwardIterator(const ComponentPoolForwardIterator& other) = default;
|
ComponentPoolForwardIterator(const ComponentPoolForwardIterator& other) = default;
|
||||||
ComponentPoolForwardIterator(ComponentPoolForwardIterator&& other) = default;
|
ComponentPoolForwardIterator(ComponentPoolForwardIterator&& other) = default;
|
||||||
@@ -27,6 +26,7 @@ public:
|
|||||||
ComponentWrapper operator*() const;
|
ComponentWrapper operator*() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ComponentPool* m_ComponentPool;
|
||||||
const ComponentInfo& m_ComponentInfo;
|
const ComponentInfo& m_ComponentInfo;
|
||||||
MemoryPool<char>::iterator m_MemoryPoolIterator;
|
MemoryPool<char>::iterator m_MemoryPoolIterator;
|
||||||
const MemoryPool<char>::iterator m_MemoryPoolEnd;
|
const MemoryPool<char>::iterator m_MemoryPoolEnd;
|
||||||
@@ -34,6 +34,7 @@ private:
|
|||||||
|
|
||||||
class ComponentPool
|
class ComponentPool
|
||||||
{
|
{
|
||||||
|
friend class ComponentPoolForwardIterator;
|
||||||
public:
|
public:
|
||||||
typedef ComponentPoolForwardIterator iterator;
|
typedef ComponentPoolForwardIterator iterator;
|
||||||
typedef ptrdiff_t difference_type;
|
typedef ptrdiff_t difference_type;
|
||||||
@@ -41,10 +42,11 @@ public:
|
|||||||
typedef ComponentWrapper value_type;
|
typedef ComponentWrapper value_type;
|
||||||
typedef ComponentWrapper* pointer;
|
typedef ComponentWrapper* pointer;
|
||||||
typedef ComponentWrapper& reference;
|
typedef ComponentWrapper& reference;
|
||||||
|
typedef std::unordered_map<EntityID, std::set<decltype(ComponentInfo::Field_t::Index)>> DirtySet_t;
|
||||||
|
|
||||||
ComponentPool(const ::ComponentInfo& ci)
|
ComponentPool(const ::ComponentInfo& ci)
|
||||||
: m_ComponentInfo(ci)
|
: m_ComponentInfo(ci)
|
||||||
, m_Pool(ci.Meta->Allocation, sizeof(EntityID) + ci.Stride)
|
, m_Pool(ci.Meta->Allocation, ci.GetHeaderSize() + ci.Stride)
|
||||||
{ }
|
{ }
|
||||||
~ComponentPool();
|
~ComponentPool();
|
||||||
ComponentPool(const ComponentPool& other);
|
ComponentPool(const ComponentPool& other);
|
||||||
@@ -61,8 +63,8 @@ public:
|
|||||||
// Delete a component and free its memory
|
// Delete a component and free its memory
|
||||||
void Delete(ComponentWrapper& wrapper);
|
void Delete(ComponentWrapper& wrapper);
|
||||||
|
|
||||||
iterator begin() const;
|
iterator begin();
|
||||||
iterator end() const;
|
iterator end();
|
||||||
size_t size() const;
|
size_t size() const;
|
||||||
|
|
||||||
//Dumps information about what the pool memory looks like right now
|
//Dumps information about what the pool memory looks like right now
|
||||||
@@ -80,6 +82,7 @@ private:
|
|||||||
::ComponentInfo m_ComponentInfo;
|
::ComponentInfo m_ComponentInfo;
|
||||||
MemoryPool<char> m_Pool;
|
MemoryPool<char> m_Pool;
|
||||||
std::unordered_map<EntityID, char*> m_EntityToComponent;
|
std::unordered_map<EntityID, char*> m_EntityToComponent;
|
||||||
|
DirtySet m_DirtySet;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -6,44 +6,54 @@
|
|||||||
#include "../Common.h"
|
#include "../Common.h"
|
||||||
#include "Entity.h"
|
#include "Entity.h"
|
||||||
#include "ComponentInfo.h"
|
#include "ComponentInfo.h"
|
||||||
|
#include "DirtySet.h"
|
||||||
#include "Util/Any.h"
|
#include "Util/Any.h"
|
||||||
|
|
||||||
template <typename T, typename Enable = void>
|
|
||||||
struct ComponentField { };
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct ComponentField<T, typename std::enable_if<std::is_trivially_copyable<T>::value>::type>
|
|
||||||
{
|
|
||||||
static T& Get(const ComponentInfo::Field_t& info, char* data) { return *reinterpret_cast<T*>(data); }
|
|
||||||
static void Set(const ComponentInfo::Field_t& info, char* data, const T& value) { Get(data) = value; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct ComponentField<std::string, void>
|
|
||||||
{
|
|
||||||
static std::string& Get(const ComponentInfo::Field_t& info, char* data) { return **reinterpret_cast<std::string**>(data); }
|
|
||||||
static void Set(const ComponentInfo::Field_t& info, char* data, const std::string& value) { Get(info, data) = value; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ComponentWrapper
|
struct ComponentWrapper
|
||||||
{
|
{
|
||||||
ComponentWrapper(const ComponentInfo& componentInfo, char* data)
|
ComponentWrapper(const ComponentInfo& componentInfo, char* data, ::DirtyBitField* dirtyBitField)
|
||||||
: Info(componentInfo)
|
: Info(componentInfo)
|
||||||
, EntityID(*reinterpret_cast<::EntityID*>(data))
|
, EntityID(*reinterpret_cast<::EntityID*>(data))
|
||||||
, Data(data + sizeof(::EntityID))
|
, Data(data + componentInfo.GetHeaderSize())
|
||||||
|
, DirtyBitField(dirtyBitField)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
const ComponentInfo& Info;
|
const ComponentInfo& Info;
|
||||||
const ::EntityID EntityID;
|
const ::EntityID EntityID;
|
||||||
char* Data;
|
char* Data;
|
||||||
|
::DirtyBitField* DirtyBitField = nullptr;
|
||||||
|
|
||||||
ComponentInfo::EnumType Enum(const char* fieldName, const char* enumKey)
|
ComponentInfo::EnumType Enum(const char* fieldName, const char* enumKey)
|
||||||
{
|
{
|
||||||
return Info.Meta->FieldEnumDefinitions.at(fieldName).at(enumKey);
|
return Info.Meta->FieldEnumDefinitions.at(fieldName).at(enumKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Dirty(DirtySetType type, const std::string& fieldName)
|
||||||
|
{
|
||||||
|
if (DirtyBitField == nullptr) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
auto& field = Info.Fields.at(fieldName);
|
||||||
|
return DirtyBitField->operator[](type).count(field.Index) == 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetDirty(DirtySetType type, const std::string& fieldName, bool dirty = true)
|
||||||
|
{
|
||||||
|
if (DirtyBitField == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& field = Info.Fields.at(fieldName);
|
||||||
|
if (dirty) {
|
||||||
|
DirtyBitField->operator[](type).insert(field.Index);
|
||||||
|
} else {
|
||||||
|
DirtyBitField->operator[](type).erase(field.Index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T& Field(std::string name)
|
T& Field(const std::string& name)
|
||||||
{
|
{
|
||||||
const ComponentInfo::Field_t& field = Info.Fields.at(name);
|
const ComponentInfo::Field_t& field = Info.Fields.at(name);
|
||||||
if (sizeof(T) > field.Stride) {
|
if (sizeof(T) > field.Stride) {
|
||||||
@@ -55,13 +65,13 @@ struct ComponentWrapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void SetField(std::string name, const T value) { Field<T>(name) = value; }
|
void SetField(const std::string& name, const T value) { Field<T>(name) = value; }
|
||||||
//template <typename T>
|
//template <typename T>
|
||||||
//void SetField(std::string name, T& value) { Field<T>(name) = value; }
|
//void SetField(std::string name, T& value) { Field<T>(name) = value; }
|
||||||
|
|
||||||
// Specialization for string literals
|
// Specialization for string literals
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
void SetField(std::string name, const char(&value)[N]) { Field<std::string>(name) = std::string(value); }
|
void SetField(const std::string& name, const char(&value)[N]) { Field<std::string>(name) = std::string(value); }
|
||||||
|
|
||||||
void Copy(ComponentWrapper& destination)
|
void Copy(ComponentWrapper& destination)
|
||||||
{
|
{
|
||||||
@@ -96,39 +106,41 @@ struct ComponentWrapper
|
|||||||
{
|
{
|
||||||
friend struct ComponentWrapper;
|
friend struct ComponentWrapper;
|
||||||
private:
|
private:
|
||||||
SubscriptProxy(ComponentWrapper* component, std::string propertyName)
|
SubscriptProxy(ComponentWrapper* component, std::string fieldName)
|
||||||
: m_Component(component)
|
: m_Component(component)
|
||||||
, m_PropertyName(propertyName)
|
, m_FieldName(fieldName)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
ComponentWrapper* m_Component;
|
ComponentWrapper* m_Component;
|
||||||
std::string m_PropertyName;
|
std::string m_FieldName;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Return the integer value of an enum type key for this field
|
// Return the integer value of an enum type key for this field
|
||||||
ComponentInfo::EnumType Enum(const char* enumKey) { return m_Component->Enum(m_PropertyName.c_str(), enumKey); }
|
ComponentInfo::EnumType Enum(const char* enumKey) { return m_Component->Enum(m_FieldName.c_str(), enumKey); }
|
||||||
|
bool Dirty(DirtySetType type) { return m_Component->Dirty(type, m_FieldName); }
|
||||||
|
void SetDirty(DirtySetType type, bool dirty = true) { m_Component->SetDirty(type, m_FieldName, dirty); }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
operator T&() { return m_Component->Field<T>(m_PropertyName); }
|
operator T&() { return m_Component->Field<T>(m_FieldName); }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void operator=(const T val) { m_Component->SetField<T>(m_PropertyName, val); }
|
void operator=(const T val) { m_Component->SetField<T>(m_FieldName, val); }
|
||||||
// TODO: Pass by reference and rvalue (universal reference?)
|
// TODO: Pass by reference and rvalue (universal reference?)
|
||||||
//template <typename T>
|
//template <typename T>
|
||||||
//void operator=(T& val) { m_Component->SetField<T>(m_PropertyName, val); }
|
//void operator=(T& val) { m_Component->SetField<T>(m_PropertyName, val); }
|
||||||
|
|
||||||
// Specialization for string literals
|
// Specialization for string literals
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
void operator=(const char(&val)[N]) { m_Component->SetField<N>(m_PropertyName, val); }
|
void operator=(const char(&val)[N]) { m_Component->SetField<N>(m_FieldName, val); }
|
||||||
};
|
};
|
||||||
SubscriptProxy operator[](std::string propertyName) { return SubscriptProxy(this, propertyName); }
|
SubscriptProxy operator[](const std::string& propertyName) { return SubscriptProxy(this, propertyName); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// A component wrapper that "owns" its data through a shared pointer
|
// A component wrapper that "owns" its data through a shared pointer
|
||||||
struct SharedComponentWrapper : ComponentWrapper
|
struct SharedComponentWrapper : ComponentWrapper
|
||||||
{
|
{
|
||||||
SharedComponentWrapper(const ComponentInfo& componentInfo, boost::shared_array<char> data)
|
SharedComponentWrapper(const ComponentInfo& componentInfo, boost::shared_array<char> data)
|
||||||
: ComponentWrapper(componentInfo, data.get())
|
: ComponentWrapper(componentInfo, data.get(), nullptr)
|
||||||
, m_DataReference(data)
|
, m_DataReference(data)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef DirtySet_h__
|
||||||
|
#define DirtySet_h__
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include "ComponentInfo.h"
|
||||||
|
|
||||||
|
enum class DirtySetType
|
||||||
|
{
|
||||||
|
Transform,
|
||||||
|
Network
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::unordered_map<DirtySetType, std::set<decltype(ComponentInfo::Field_t::Index)>> DirtyBitField;
|
||||||
|
typedef std::unordered_map<EntityID, DirtyBitField> DirtySet;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -81,7 +81,7 @@ public:
|
|||||||
for (auto& pair : group.PureSystems) {
|
for (auto& pair : group.PureSystems) {
|
||||||
const std::string& componentName = pair.first;
|
const std::string& componentName = pair.first;
|
||||||
auto& systems = pair.second;
|
auto& systems = pair.second;
|
||||||
const ComponentPool* pool = m_World->GetComponents(componentName);
|
ComponentPool* pool = m_World->GetComponents(componentName);
|
||||||
if (pool == nullptr) {
|
if (pool == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public:
|
|||||||
// Delete a component off an entity
|
// Delete a component off an entity
|
||||||
void DeleteComponent(EntityID entity, const std::string& componentType);
|
void DeleteComponent(EntityID entity, const std::string& componentType);
|
||||||
// Get all components of the specified type
|
// Get all components of the specified type
|
||||||
const ComponentPool* GetComponents(const std::string& componentType);
|
ComponentPool* GetComponents(const std::string& componentType);
|
||||||
// Get entity parent
|
// Get entity parent
|
||||||
EntityID GetParent(EntityID entity);
|
EntityID GetParent(EntityID entity);
|
||||||
// Change the parent of an entity
|
// Change the parent of an entity
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void renderText(std::string text, Font* font, TextJob::AlignmentEnum alignment, glm::vec4 color, glm::mat4 modelMatrix, glm::mat4 projectionMatrix, glm::mat4 viewMatrix);
|
void renderText(std::string text, Font* font, TextJob::AlignmentEnum alignment, glm::vec4 color, glm::mat4 modelMatrix, glm::mat4 projectionMatrix, glm::mat4 viewMatrix);
|
||||||
std::string parseColors(std::string text, std::map<int, glm::vec4>& colorChanges, glm::vec4 originalColor);
|
|
||||||
|
|
||||||
Font* font;
|
Font* font;
|
||||||
GLuint VAO, VBO;
|
GLuint VAO, VBO;
|
||||||
|
|||||||
@@ -40,17 +40,5 @@ private:
|
|||||||
};
|
};
|
||||||
std::vector<EntityAtMaxValuePickupStruct> m_PickupAtMaximum;
|
std::vector<EntityAtMaxValuePickupStruct> m_PickupAtMaximum;
|
||||||
void DoPickup(EntityWrapper &player, EntityWrapper &trigger);
|
void DoPickup(EntityWrapper &player, EntityWrapper &trigger);
|
||||||
//class
|
|
||||||
enum class PlayerClass {
|
|
||||||
Assault,
|
|
||||||
Defender,
|
|
||||||
Sniper,
|
|
||||||
None
|
|
||||||
};
|
|
||||||
//helper methods
|
|
||||||
bool DoesPlayerHaveMaxAmmo(EntityWrapper &player);
|
|
||||||
PlayerClass DetermineClass(EntityWrapper &player);
|
|
||||||
void SetPlayerAmmo(EntityWrapper &player, int ammoGain);
|
|
||||||
int GetPlayerMaxAmmo(EntityWrapper &player);
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
#include "Core/ComponentPool.h"
|
#include "Core/ComponentPool.h"
|
||||||
|
|
||||||
|
ComponentPoolForwardIterator::ComponentPoolForwardIterator(ComponentPool* pool)
|
||||||
|
: m_ComponentPool(pool)
|
||||||
|
, m_ComponentInfo(pool->m_ComponentInfo)
|
||||||
|
, m_MemoryPoolIterator(pool->m_Pool.begin())
|
||||||
|
, m_MemoryPoolEnd(pool->m_Pool.end())
|
||||||
|
{ }
|
||||||
|
|
||||||
ComponentWrapper ComponentPoolForwardIterator::operator*() const
|
ComponentWrapper ComponentPoolForwardIterator::operator*() const
|
||||||
{
|
{
|
||||||
char* data = &(*m_MemoryPoolIterator);
|
char* data = &(*m_MemoryPoolIterator);
|
||||||
ComponentWrapper wrapper(m_ComponentInfo, data);
|
EntityID entity = *reinterpret_cast<EntityID*>(data);
|
||||||
|
ComponentWrapper wrapper(m_ComponentInfo, data, &m_ComponentPool->m_DirtySet[entity]);
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +79,7 @@ ComponentWrapper ComponentPool::Allocate(EntityID entity)
|
|||||||
memcpy(data, &entity, sizeof(EntityID));
|
memcpy(data, &entity, sizeof(EntityID));
|
||||||
|
|
||||||
m_EntityToComponent[entity] = data;
|
m_EntityToComponent[entity] = data;
|
||||||
ComponentWrapper component(m_ComponentInfo, data);
|
ComponentWrapper component(m_ComponentInfo, data, &m_DirtySet[entity]);
|
||||||
|
|
||||||
// Copy defaults
|
// Copy defaults
|
||||||
memcpy(component.Data, m_ComponentInfo.Defaults.get(), m_ComponentInfo.Stride);
|
memcpy(component.Data, m_ComponentInfo.Defaults.get(), m_ComponentInfo.Stride);
|
||||||
@@ -82,7 +90,9 @@ ComponentWrapper ComponentPool::Allocate(EntityID entity)
|
|||||||
|
|
||||||
ComponentWrapper ComponentPool::GetByEntity(EntityID ent)
|
ComponentWrapper ComponentPool::GetByEntity(EntityID ent)
|
||||||
{
|
{
|
||||||
return ComponentWrapper(m_ComponentInfo, m_EntityToComponent.at(ent));
|
auto data = m_EntityToComponent.at(ent);
|
||||||
|
auto bitField = &m_DirtySet[ent];
|
||||||
|
return ComponentWrapper(m_ComponentInfo, data, bitField);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ComponentPool::KnowsEntity(EntityID ent)
|
bool ComponentPool::KnowsEntity(EntityID ent)
|
||||||
@@ -95,16 +105,17 @@ void ComponentPool::Delete(ComponentWrapper& wrapper)
|
|||||||
ComponentWrapper::Destroy(wrapper.Info, wrapper.Data);
|
ComponentWrapper::Destroy(wrapper.Info, wrapper.Data);
|
||||||
m_EntityToComponent.erase(wrapper.EntityID);
|
m_EntityToComponent.erase(wrapper.EntityID);
|
||||||
m_Pool.Free(wrapper.Data - sizeof(EntityID));
|
m_Pool.Free(wrapper.Data - sizeof(EntityID));
|
||||||
|
m_DirtySet.erase(wrapper.EntityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
ComponentPool::iterator ComponentPool::begin() const
|
ComponentPool::iterator ComponentPool::begin()
|
||||||
{
|
{
|
||||||
return iterator(m_ComponentInfo, m_Pool.begin(), m_Pool.end());
|
return iterator(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
ComponentPool::iterator ComponentPool::end() const
|
ComponentPool::iterator ComponentPool::end()
|
||||||
{
|
{
|
||||||
return iterator(m_ComponentInfo, m_Pool.end(), m_Pool.end());
|
return iterator(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ComponentPool::size() const
|
size_t ComponentPool::size() const
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ void EntityXMLFilePreprocessor::parseComponentInfo()
|
|||||||
auto modelGroup = modelGroupParticle->getModelGroupTerm();
|
auto modelGroup = modelGroupParticle->getModelGroupTerm();
|
||||||
|
|
||||||
// <xs:element...
|
// <xs:element...
|
||||||
|
unsigned char fieldIndex = 0;
|
||||||
unsigned int fieldOffset = 0;
|
unsigned int fieldOffset = 0;
|
||||||
auto particles = modelGroup->getParticles();
|
auto particles = modelGroup->getParticles();
|
||||||
for (unsigned int i = 0; i < particles->size(); ++i) {
|
for (unsigned int i = 0; i < particles->size(); ++i) {
|
||||||
@@ -182,12 +183,14 @@ void EntityXMLFilePreprocessor::parseComponentInfo()
|
|||||||
auto& field = compInfo.Fields[name];
|
auto& field = compInfo.Fields[name];
|
||||||
field.Name = name;
|
field.Name = name;
|
||||||
field.Type = effectiveType;
|
field.Type = effectiveType;
|
||||||
|
field.Index = fieldIndex;
|
||||||
field.Offset = fieldOffset;
|
field.Offset = fieldOffset;
|
||||||
field.Stride = stride;
|
field.Stride = stride;
|
||||||
compInfo.FieldsInOrder.push_back(name);
|
compInfo.FieldsInOrder.push_back(name);
|
||||||
if (field.Type == "string") {
|
if (field.Type == "string") {
|
||||||
compInfo.StringFields.push_back(name);
|
compInfo.StringFields.push_back(name);
|
||||||
}
|
}
|
||||||
|
fieldIndex += 1;
|
||||||
fieldOffset += stride;
|
fieldOffset += stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ void World::DeleteComponent(EntityID entity, const std::string& componentType)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ComponentPool* World::GetComponents(const std::string& componentType)
|
ComponentPool* World::GetComponents(const std::string& componentType)
|
||||||
{
|
{
|
||||||
auto it = m_ComponentPools.find(componentType);
|
auto it = m_ComponentPools.find(componentType);
|
||||||
return (it != m_ComponentPools.end()) ? it->second : nullptr;
|
return (it != m_ComponentPools.end()) ? it->second : nullptr;
|
||||||
|
|||||||
@@ -7,23 +7,23 @@ TextPass::TextPass()
|
|||||||
|
|
||||||
void TextPass::Initialize()
|
void TextPass::Initialize()
|
||||||
{
|
{
|
||||||
glGenVertexArrays(1, &VAO);
|
glGenVertexArrays(1, &VAO);
|
||||||
glGenBuffers(1, &VBO);
|
glGenBuffers(1, &VBO);
|
||||||
glBindVertexArray(VAO);
|
glBindVertexArray(VAO);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
|
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
m_TextProgram = ResourceManager::Load<ShaderProgram>("#TextProgram");
|
m_TextProgram = ResourceManager::Load<ShaderProgram>("#TextProgram");
|
||||||
m_TextProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/Text.vert.glsl")));
|
m_TextProgram->AddShader(std::shared_ptr<Shader>(new VertexShader("Shaders/Text.vert.glsl")));
|
||||||
m_TextProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/Text.frag.glsl")));
|
m_TextProgram->AddShader(std::shared_ptr<Shader>(new FragmentShader("Shaders/Text.frag.glsl")));
|
||||||
m_TextProgram->Compile();
|
m_TextProgram->Compile();
|
||||||
m_TextProgram->BindFragDataLocation(0, "sceneColor");
|
m_TextProgram->BindFragDataLocation(0, "sceneColor");
|
||||||
m_TextProgram->BindFragDataLocation(1, "bloomColor");
|
m_TextProgram->BindFragDataLocation(1, "bloomColor");
|
||||||
m_TextProgram->Link();
|
m_TextProgram->Link();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextPass::Update()
|
void TextPass::Update()
|
||||||
@@ -33,180 +33,81 @@ void TextPass::Update()
|
|||||||
|
|
||||||
void TextPass::Draw(RenderScene& scene, FrameBuffer& frameBuffer)
|
void TextPass::Draw(RenderScene& scene, FrameBuffer& frameBuffer)
|
||||||
{
|
{
|
||||||
GLERROR("Derp1");
|
GLERROR("Derp1");
|
||||||
TextPassState* state = new TextPassState(frameBuffer.GetHandle());
|
TextPassState* state = new TextPassState(frameBuffer.GetHandle());
|
||||||
for (auto &job : scene.Jobs.Text) {
|
for (auto &job : scene.Jobs.Text) {
|
||||||
auto textJob = std::dynamic_pointer_cast<TextJob>(job);
|
auto textJob = std::dynamic_pointer_cast<TextJob>(job);
|
||||||
if (textJob) {
|
if (textJob) {
|
||||||
|
|
||||||
renderText(textJob->Content, textJob->Resource, textJob->Alignment, textJob->Color, textJob->Matrix, scene.Camera->ProjectionMatrix(), scene.Camera->ViewMatrix());
|
renderText(textJob->Content, textJob->Resource, textJob->Alignment, textJob->Color, textJob->Matrix, scene.Camera->ProjectionMatrix(), scene.Camera->ViewMatrix());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GLERROR("Derp2");
|
GLERROR("Derp2");
|
||||||
delete state;
|
delete state;
|
||||||
}
|
|
||||||
|
|
||||||
std::string TextPass::parseColors(std::string text, std::map<int, glm::vec4>& colorChanges, glm::vec4 originalColor)
|
|
||||||
{
|
|
||||||
std::string parsedString = text;
|
|
||||||
glm::vec4 newColor = originalColor;
|
|
||||||
bool colorChange = false;
|
|
||||||
|
|
||||||
for (std::string::const_iterator c = parsedString.begin(); c != parsedString.end(); c++) {
|
|
||||||
if (*c == char(92)) { // Backlash
|
|
||||||
if ((c + 1) != parsedString.end()) {
|
|
||||||
if (*(c + 1) == char('C')) { // C for Color
|
|
||||||
if ((c + 7) != parsedString.end()) {
|
|
||||||
bool hasCorrectFormat = true;
|
|
||||||
|
|
||||||
for (std::string::const_iterator colorC = c + 2; colorC != c + 8; colorC++) {
|
|
||||||
if (*colorC < '0' || *colorC > 'F') {
|
|
||||||
hasCorrectFormat = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasCorrectFormat == true) {
|
|
||||||
colorChange = true;
|
|
||||||
|
|
||||||
std::array<int, 3> hexToInt = {
|
|
||||||
std::stoi(std::string(c + 2, c + 4), 0, 16),
|
|
||||||
std::stoi(std::string(c + 4, c + 6), 0, 16),
|
|
||||||
std::stoi(std::string(c + 6, c + 8), 0, 16)
|
|
||||||
};
|
|
||||||
|
|
||||||
newColor = glm::vec4(
|
|
||||||
float(hexToInt[0]) / 255.f,
|
|
||||||
float(hexToInt[1]) / 255.f,
|
|
||||||
float(hexToInt[2]) / 255.f,
|
|
||||||
newColor.a);
|
|
||||||
|
|
||||||
parsedString.erase(c, (c + 8));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*(c + 1) == char('A')) { // A for Alpha
|
|
||||||
if ((c + 3) != parsedString.end()) {
|
|
||||||
bool hasCorrectFormat = true;
|
|
||||||
|
|
||||||
for (std::string::const_iterator colorC = c + 2; colorC != c + 4; colorC++) {
|
|
||||||
if (*colorC < '0' || *colorC > 'F') {
|
|
||||||
hasCorrectFormat = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasCorrectFormat == true) {
|
|
||||||
colorChange = true;
|
|
||||||
|
|
||||||
int hexToInt = std::stoi(std::string(c + 2, c + 4), 0, 16);
|
|
||||||
|
|
||||||
newColor = glm::vec4(
|
|
||||||
newColor.r,
|
|
||||||
newColor.g,
|
|
||||||
newColor.b,
|
|
||||||
float(hexToInt) / 255.f);
|
|
||||||
|
|
||||||
parsedString.erase(c, (c + 4));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*(c + 1) >= '1' && *(c + 1) <= '9') || *(c + 1) == 'B' || *(c + 1) == 'E' || *(c + 1) == 'F') { // Icons
|
|
||||||
if (*(c + 1) >= '1' && *(c + 1) <= '9') {
|
|
||||||
parsedString.replace(c, (c + 2), 1, (*(c + 1) - 48));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
parsedString.replace(c, (c + 2), 1, (*(c + 1) - 55));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (colorChange) {
|
|
||||||
colorChanges[c - parsedString.begin()] = newColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return parsedString;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextPass::renderText(std::string text, Font* font, TextJob::AlignmentEnum alignment, glm::vec4 color, glm::mat4 modelMatrix, glm::mat4 projectionMatrix, glm::mat4 viewMatrix)
|
void TextPass::renderText(std::string text, Font* font, TextJob::AlignmentEnum alignment, glm::vec4 color, glm::mat4 modelMatrix, glm::mat4 projectionMatrix, glm::mat4 viewMatrix)
|
||||||
{
|
{
|
||||||
GLfloat penX = 0;
|
GLfloat penX = 0;
|
||||||
GLfloat penY = 0;
|
GLfloat penY = 0;
|
||||||
GLfloat scale = 1.0 / font->FontSize;
|
GLfloat scale = 1.0/font->FontSize;
|
||||||
|
|
||||||
GLfloat stringWidth = 0.f;
|
GLfloat stringWidth = 0.f;
|
||||||
|
|
||||||
std::map<int, glm::vec4> colorChanges;
|
for (std::string::const_iterator c = text.begin(); c != text.end(); c++) {
|
||||||
std::string parsedText = parseColors(text, colorChanges, color);
|
Font::Character ch = font->m_Characters[*c];
|
||||||
|
stringWidth += (ch.Advance >> 6) * scale;
|
||||||
|
}
|
||||||
|
|
||||||
for (std::string::const_iterator c = parsedText.begin(); c != parsedText.end(); c++) {
|
if(alignment == TextJob::AlignmentEnum::Center) {
|
||||||
Font::Character ch = font->m_Characters[*c];
|
penX = -stringWidth/2.f;
|
||||||
stringWidth += (ch.Advance >> 6) * scale;
|
} else if (alignment == TextJob::AlignmentEnum::Right) {
|
||||||
}
|
penX = -stringWidth;
|
||||||
|
} else {
|
||||||
|
penX = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (alignment == TextJob::AlignmentEnum::Center) {
|
m_TextProgram->Bind();
|
||||||
penX = -stringWidth / 2.f;
|
glUniform4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "textColor"), 1, glm::value_ptr(color));
|
||||||
}
|
glUniformMatrix4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "M"), 1, GL_FALSE, glm::value_ptr(modelMatrix));
|
||||||
else if (alignment == TextJob::AlignmentEnum::Right) {
|
glUniformMatrix4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "V"), 1, GL_FALSE, glm::value_ptr(viewMatrix));
|
||||||
penX = -stringWidth;
|
glUniformMatrix4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "P"), 1, GL_FALSE, glm::value_ptr(projectionMatrix));
|
||||||
}
|
glActiveTexture(GL_TEXTURE0);
|
||||||
else {
|
glBindVertexArray(VAO);
|
||||||
penX = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
for (std::string::const_iterator c = text.begin(); c != text.end(); c++) {
|
||||||
|
Font::Character ch = font->m_Characters[*c];
|
||||||
|
|
||||||
m_TextProgram->Bind();
|
GLfloat xpos = penX + ch.Bearing.x * scale;
|
||||||
glUniform4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "textColor"), 1, glm::value_ptr(color));
|
GLfloat ypos = penY - (ch.Size.y - ch.Bearing.y) * scale;
|
||||||
glUniformMatrix4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "M"), 1, GL_FALSE, glm::value_ptr(modelMatrix));
|
|
||||||
glUniformMatrix4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "V"), 1, GL_FALSE, glm::value_ptr(viewMatrix));
|
|
||||||
glUniformMatrix4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "P"), 1, GL_FALSE, glm::value_ptr(projectionMatrix));
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindVertexArray(VAO);
|
|
||||||
|
|
||||||
|
GLfloat w = ch.Size.x * scale;
|
||||||
|
GLfloat h = ch.Size.y * scale;
|
||||||
|
|
||||||
for (std::string::const_iterator c = parsedText.begin(); c != parsedText.end(); c++) {
|
GLfloat vertices[6][4] = {
|
||||||
|
{ xpos, ypos + h, 0.0, 0.0 },
|
||||||
|
{ xpos, ypos, 0.0, 1.0 },
|
||||||
|
{ xpos + w, ypos, 1.0, 1.0 },
|
||||||
|
|
||||||
auto it = colorChanges.find(c - parsedText.begin());
|
{ xpos, ypos + h, 0.0, 0.0 },
|
||||||
if (it != colorChanges.end()) {
|
{ xpos + w, ypos, 1.0, 1.0 },
|
||||||
glUniform4fv(glGetUniformLocation(m_TextProgram->GetHandle(), "textColor"), 1, glm::value_ptr(it->second));
|
{ xpos + w, ypos + h, 1.0, 0.0 }
|
||||||
}
|
};
|
||||||
|
|
||||||
Font::Character ch = font->m_Characters[*c];
|
glBindTexture(GL_TEXTURE_2D, ch.TextureID);
|
||||||
|
|
||||||
GLfloat xpos = penX + ch.Bearing.x * scale;
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
GLfloat ypos = penY - (ch.Size.y - ch.Bearing.y) * scale;
|
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||||
|
penX += (ch.Advance >> 6) * scale; // Bitshift by 6 to get value in pixels (2^6 = 64)
|
||||||
|
}
|
||||||
|
glBindVertexArray(0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
GLfloat w = ch.Size.x * scale;
|
GLERROR("Text rendering Error");
|
||||||
GLfloat h = ch.Size.y * scale;
|
|
||||||
|
|
||||||
GLfloat vertices[6][4] = {
|
|
||||||
{ xpos, ypos + h, 0.0, 0.0 },
|
|
||||||
{ xpos, ypos, 0.0, 1.0 },
|
|
||||||
{ xpos + w, ypos, 1.0, 1.0 },
|
|
||||||
|
|
||||||
{ xpos, ypos + h, 0.0, 0.0 },
|
|
||||||
{ xpos + w, ypos, 1.0, 1.0 },
|
|
||||||
{ xpos + w, ypos + h, 1.0, 0.0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, ch.TextureID);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
|
||||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
||||||
penX += (ch.Advance >> 6) * scale; // Bitshift by 6 to get value in pixels (2^6 = 64)
|
|
||||||
}
|
|
||||||
glBindVertexArray(0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
|
|
||||||
GLERROR("Text rendering Error");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ void AmmoPickupSystem::Update(double dt)
|
|||||||
|
|
||||||
//erase the current element (somePickup)
|
//erase the current element (somePickup)
|
||||||
it = m_ETriggerTouchVector.erase(it);
|
it = m_ETriggerTouchVector.erase(it);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,7 +48,7 @@ void AmmoPickupSystem::Update(double dt)
|
|||||||
m_PickupAtMaximum.erase(it);
|
m_PickupAtMaximum.erase(it);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!DoesPlayerHaveMaxAmmo(it->player)) {
|
if ((int)it->player["AssaultWeapon"]["Ammo"] < (int)it->player["AssaultWeapon"]["MaxAmmo"]) {
|
||||||
DoPickup(it->player, it->trigger);
|
DoPickup(it->player, it->trigger);
|
||||||
m_PickupAtMaximum.erase(it);
|
m_PickupAtMaximum.erase(it);
|
||||||
break;
|
break;
|
||||||
@@ -55,58 +56,6 @@ void AmmoPickupSystem::Update(double dt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool AmmoPickupSystem::DoesPlayerHaveMaxAmmo(EntityWrapper &player) {
|
|
||||||
PlayerClass playerClass = DetermineClass(player);
|
|
||||||
if (playerClass == PlayerClass::Defender) {
|
|
||||||
return !((int)player["DefenderWeapon"]["Ammo"] < (int)player["DefenderWeapon"]["MaxAmmo"]);
|
|
||||||
} else if (playerClass == PlayerClass::Sniper) {
|
|
||||||
return !((int)player["SniperWeapon"]["Ammo"] < (int)player["SniperWeapon"]["MaxAmmo"]);
|
|
||||||
} else if (playerClass == PlayerClass::Assault) {
|
|
||||||
return !((int)player["AssaultWeapon"]["Ammo"] < (int)player["AssaultWeapon"]["MaxAmmo"]);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void AmmoPickupSystem::SetPlayerAmmo(EntityWrapper &player, int ammoGain) {
|
|
||||||
int maxWeaponAmmo = GetPlayerMaxAmmo(player);
|
|
||||||
|
|
||||||
PlayerClass playerClass = DetermineClass(player);
|
|
||||||
if (playerClass == PlayerClass::Defender) {
|
|
||||||
(int&)player["DefenderWeapon"]["Ammo"] = std::min((int)player["DefenderWeapon"]["Ammo"] + ammoGain, maxWeaponAmmo);
|
|
||||||
} else if (playerClass == PlayerClass::Sniper) {
|
|
||||||
(int&)player["SniperWeapon"]["Ammo"] = std::min((int)player["SniperWeapon"]["Ammo"] + ammoGain, maxWeaponAmmo);
|
|
||||||
} else if (playerClass == PlayerClass::Assault) {
|
|
||||||
(int&)player["AssaultWeapon"]["Ammo"] = std::min((int)player["AssaultWeapon"]["Ammo"] + ammoGain, maxWeaponAmmo);
|
|
||||||
} else {
|
|
||||||
//unknown class - ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int AmmoPickupSystem::GetPlayerMaxAmmo(EntityWrapper &player) {
|
|
||||||
PlayerClass playerClass = DetermineClass(player);
|
|
||||||
if (playerClass == PlayerClass::Defender) {
|
|
||||||
return (int)player["DefenderWeapon"]["MaxAmmo"];
|
|
||||||
} else if (playerClass == PlayerClass::Sniper) {
|
|
||||||
return (int)player["SniperWeapon"]["MaxAmmo"];
|
|
||||||
} else if (playerClass == PlayerClass::Assault) {
|
|
||||||
return (int)player["AssaultWeapon"]["MaxAmmo"];
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AmmoPickupSystem::PlayerClass AmmoPickupSystem::DetermineClass(EntityWrapper &player)
|
|
||||||
{
|
|
||||||
//determine the class based on what component the inflictor-player has
|
|
||||||
if (m_World->HasComponent(player.ID, "DashAbility")) {
|
|
||||||
return PlayerClass::Assault;
|
|
||||||
}
|
|
||||||
if (m_World->HasComponent(player.ID, "ShieldAbility")) {
|
|
||||||
return PlayerClass::Defender;
|
|
||||||
}
|
|
||||||
if (m_World->HasComponent(player.ID, "SprintAbility")) {
|
|
||||||
return PlayerClass::Sniper;
|
|
||||||
}
|
|
||||||
return PlayerClass::None;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AmmoPickupSystem::OnTriggerTouch(Events::TriggerTouch& e)
|
bool AmmoPickupSystem::OnTriggerTouch(Events::TriggerTouch& e)
|
||||||
{
|
{
|
||||||
@@ -114,7 +63,7 @@ bool AmmoPickupSystem::OnTriggerTouch(Events::TriggerTouch& e)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//TODO: add other weapontypes
|
//TODO: add other weapontypes
|
||||||
if (DetermineClass(e.Entity) == PlayerClass::None) {
|
if (!e.Entity.HasComponent("AssaultWeapon")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!e.Trigger.HasComponent("AmmoPickup")) {
|
if (!e.Trigger.HasComponent("AmmoPickup")) {
|
||||||
@@ -122,7 +71,7 @@ bool AmmoPickupSystem::OnTriggerTouch(Events::TriggerTouch& e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//if at maxammo, save the trigger-touch to a vector since standing inside it will not re-trigger the trigger
|
//if at maxammo, save the trigger-touch to a vector since standing inside it will not re-trigger the trigger
|
||||||
if (DoesPlayerHaveMaxAmmo(e.Entity)) {
|
if ((int)e.Entity["AssaultWeapon"]["Ammo"] >= (int)e.Entity["AssaultWeapon"]["MaxAmmo"]) {
|
||||||
m_PickupAtMaximum.push_back({ e.Entity, e.Trigger });
|
m_PickupAtMaximum.push_back({ e.Entity, e.Trigger });
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -136,16 +85,19 @@ bool AmmoPickupSystem::OnAmmoPickup(Events::AmmoPickup & e)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//TODO: add other weapontypes
|
//TODO: add other weapontypes
|
||||||
if (DetermineClass(e.Player) == PlayerClass::None) {
|
if (!e.Player.HasComponent("AssaultWeapon")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
int maxWeaponAmmo = (int)e.Player["AssaultWeapon"]["MaxAmmo"];
|
||||||
|
int& currentAmmo = (int)e.Player["AssaultWeapon"]["Ammo"];
|
||||||
//cant pick up ammopacks if you are already at MaxAmmo
|
//cant pick up ammopacks if you are already at MaxAmmo
|
||||||
if (DoesPlayerHaveMaxAmmo(e.Player)) {
|
if (currentAmmo >= maxWeaponAmmo) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
SetPlayerAmmo(e.Player, e.AmmoGain);
|
|
||||||
|
|
||||||
return true;
|
currentAmmo = std::min(currentAmmo + e.AmmoGain, maxWeaponAmmo);
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AmmoPickupSystem::OnTriggerLeave(Events::TriggerLeave& e) {
|
bool AmmoPickupSystem::OnTriggerLeave(Events::TriggerLeave& e) {
|
||||||
@@ -167,7 +119,7 @@ void AmmoPickupSystem::DoPickup(EntityWrapper &player, EntityWrapper &trigger) {
|
|||||||
if (!trigger.Valid()) {
|
if (!trigger.Valid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int maxWeaponAmmo = GetPlayerMaxAmmo(player);
|
int maxWeaponAmmo = (int)player["AssaultWeapon"]["MaxAmmo"];
|
||||||
int ammoGiven = 0.01*(double)trigger["AmmoPickup"]["AmmoGain"] * maxWeaponAmmo;
|
int ammoGiven = 0.01*(double)trigger["AmmoPickup"]["AmmoGain"] * maxWeaponAmmo;
|
||||||
|
|
||||||
Events::AmmoPickup ePlayerAmmoPickup;
|
Events::AmmoPickup ePlayerAmmoPickup;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ void PlayerMovementSystem::Update(double dt)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_SprintEffectTimer = 0.f;
|
m_SprintEffectTimer = 0.f;
|
||||||
const ComponentPool* pool = m_World->GetComponents("SprintAbility");
|
auto pool = m_World->GetComponents("SprintAbility");
|
||||||
if (pool == nullptr) {
|
if (pool == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ bool SpawnerSystem::spawnedEntityIsColliding(EntityWrapper spawnedEntity, Entity
|
|||||||
transformEntityToSpawnPoint(spawnedEntity, spawnPoint);
|
transformEntityToSpawnPoint(spawnedEntity, spawnPoint);
|
||||||
//Check if the spawned entity collides with anything, and if so, continue to the next spawnpoint.
|
//Check if the spawned entity collides with anything, and if so, continue to the next spawnpoint.
|
||||||
EntityAABB spawnedBox = *Collision::EntityAbsoluteAABB(spawnedEntity);
|
EntityAABB spawnedBox = *Collision::EntityAbsoluteAABB(spawnedEntity);
|
||||||
const ComponentPool* otherSpawnedEntities = spawnPoint.World->GetComponents(dontCollideComponent);
|
auto otherSpawnedEntities = spawnPoint.World->GetComponents(dontCollideComponent);
|
||||||
for (const auto& obj : *otherSpawnedEntities) {
|
for (const auto& obj : *otherSpawnedEntities) {
|
||||||
if (spawnedEntity.ID == obj.EntityID) {
|
if (spawnedEntity.ID == obj.EntityID) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user