diff --git a/assets b/assets index d72b3b4b..c82b5716 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit d72b3b4b47cb6a1de8d8ccc94ff9640b3d1e0d56 +Subproject commit c82b5716d98a0c9fb3914367e9b08cc2e7dbca43 diff --git a/include/Engine/Core/ECaptured.h b/include/Engine/Core/ECaptured.h index d891c7b0..047c5d7d 100644 --- a/include/Engine/Core/ECaptured.h +++ b/include/Engine/Core/ECaptured.h @@ -12,7 +12,9 @@ namespace Events struct Captured : Event { int TeamNumberThatCapturedCapturePoint; - EntityID CapturePointID; + EntityID CapturePointTakenID; + EntityWrapper BlueTeamNextCapturePoint; + EntityWrapper RedTeamNextCapturePoint; }; } diff --git a/include/Engine/Core/EntityFile.h b/include/Engine/Core/EntityFile.h index 538e9047..fae39c51 100644 --- a/include/Engine/Core/EntityFile.h +++ b/include/Engine/Core/EntityFile.h @@ -1,164 +1,21 @@ #ifndef EntityFile_h__ #define EntityFile_h__ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "World.h" +#include "EntityXMLFile.h" +#include "EntityXMLFilePreprocessor.h" +#include "EntityXMLFileParser.h" +#include "EntityWrapper.h" -#include "../GLM.h" -#include "Util/XercesString.h" -#include "ResourceManager.h" -#include "Entity.h" -#include "ComponentInfo.h" - -class EntityFileHandler -{ - friend class EntityFileSAXHandler; -public: - // @param EntityID The entity found - // @param EntityID The parent of the entity - typedef std::function OnStartEntityCallback; - void SetStartEntityCallback(OnStartEntityCallback c) { m_OnStartEntityCallback = c; } - // @param EntityID The entity the component corresponds to - // @param std::string Type name of the component - typedef std::function OnStartComponentCallback; - void SetStartComponentCallback(OnStartComponentCallback c) { m_OnStartComponentCallback = c; } - // @param EntityID Entity - // @param std::string Component name - // @param std::string Field name - // @param std::map Field attribute names and values - typedef std::function&)> OnStartFieldCallback; - void SetStartFieldCallback(OnStartFieldCallback c) { m_OnStartFieldCallback = c; } - // @param EntityID Entity - // @param std::string Component name - // @param std::string Field name - // @param char* Field data - typedef std::function OnStartFieldDataCallback; - void SetStartFieldDataCallback(OnStartFieldDataCallback c) { m_OnStartFieldDataCallback = c; } - -private: - OnStartEntityCallback m_OnStartEntityCallback = nullptr; - OnStartComponentCallback m_OnStartComponentCallback = nullptr; - OnStartFieldCallback m_OnStartFieldCallback = nullptr; - OnStartFieldDataCallback m_OnStartFieldDataCallback = nullptr; -}; - -class EntityFileSAXHandler : public xercesc::DefaultHandler +class EntityFile : private World, public Resource { public: - enum class State - { - Unknown, - Entity, - Component, - ComponentField - }; + EntityFile(std::string path); - EntityFileSAXHandler(const EntityFileHandler* handler, xercesc::SAX2XMLReader* reader); - - void startElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname, const xercesc::Attributes& attrs) override; - void characters(const XMLCh* const chars, const XMLSize_t length) override; - void endElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname) override; - - void warning(const xercesc::SAXParseException& e); - void error(const xercesc::SAXParseException& e); - void fatalError(const xercesc::SAXParseException& e); + EntityWrapper MergeInto(World* other); private: - const EntityFileHandler* m_Handler; - xercesc::XMLGrammarPool* m_GrammarPool; - xercesc::SAX2XMLReader* m_Reader; - //State m_CurrentScope = State::Unknown; - std::stack m_StateStack; - unsigned int m_NextEntityID = 0; - std::stack m_EntityStack; - std::string m_CurrentComponent; - std::string m_CurrentField; - std::map m_CurrentAttributes; - - void onStartEntity(const xercesc::Attributes& attrs); - void onEndEntity(); - void onStartEntityRef(const xercesc::Attributes& attrs); - void onStartComponent(const std::string& name); - void onEndComponent(const std::string& name); - void onStartComponentField(const std::string& field, const xercesc::Attributes& attrs); - void onEndComponentField(const std::string& field); - void onFieldData(char* data); -}; - -class EntityFileXMLErrorHandler : public xercesc::ErrorHandler -{ -public: - void warning(const xercesc::SAXParseException& e) override - { - reportParseException("Warning", e); - } - void error(const xercesc::SAXParseException& e) override - { - reportParseException("Error", e); - } - void fatalError(const xercesc::SAXParseException& e) override - { - reportParseException("FATAL ERROR", e); - } - void resetErrors() override { } - -private: - void reportParseException(std::string type, const xercesc::SAXParseException& e) - { - char* message = xercesc::XMLString::transcode(e.getMessage()); - char* systemID = xercesc::XMLString::transcode(e.getSystemId()); - std::cerr << systemID << ":" << e.getLineNumber() << ":" << e.getColumnNumber() << std::endl; - std::cerr << type << ": " << message << std::endl; - xercesc::XMLString::release(&systemID); - xercesc::XMLString::release(&message); - } -}; - -class EntityFile : public Resource -{ - friend class ResourceManager; - friend class EntityFileSAXHandler; -private: - EntityFile(boost::filesystem::path path); - ~EntityFile(); - -public: - static unsigned int GetTypeStride(std::string typeName); - static void WriteAttributeData(char* outData, const ComponentInfo::Field_t& field, const std::map& attributes); - static void WriteValueData(char* outData, const ComponentInfo::Field_t& field, const char* valueData); - - xercesc::XMLGrammarPool* GrammarPool() const { return m_GrammarPool; } - - void Parse(const EntityFileHandler* handler) const; - -private: - boost::filesystem::path m_FilePath; - xercesc::XMLGrammarPool* m_GrammarPool; - xercesc::SAX2XMLReader* m_SAX2XMLReader; - //std::map m_ComponentInfo; - //std::vector m_EntityReferences; - - static void setReaderFeatures(xercesc::SAX2XMLReader* reader); + EntityID m_RootEntity = EntityID_Invalid; }; #endif \ No newline at end of file diff --git a/include/Engine/Core/EntityXMLFile.h b/include/Engine/Core/EntityXMLFile.h new file mode 100644 index 00000000..6f24154d --- /dev/null +++ b/include/Engine/Core/EntityXMLFile.h @@ -0,0 +1,164 @@ +#ifndef EntityXMLFile_h__ +#define EntityXMLFile_h__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../GLM.h" +#include "Util/XercesString.h" +#include "ResourceManager.h" +#include "Entity.h" +#include "ComponentInfo.h" + +class EntityFileHandler +{ + friend class EntityFileSAXHandler; +public: + // @param EntityID The entity found + // @param EntityID The parent of the entity + typedef std::function OnStartEntityCallback; + void SetStartEntityCallback(OnStartEntityCallback c) { m_OnStartEntityCallback = c; } + // @param EntityID The entity the component corresponds to + // @param std::string Type name of the component + typedef std::function OnStartComponentCallback; + void SetStartComponentCallback(OnStartComponentCallback c) { m_OnStartComponentCallback = c; } + // @param EntityID Entity + // @param std::string Component name + // @param std::string Field name + // @param std::map Field attribute names and values + typedef std::function&)> OnStartFieldCallback; + void SetStartFieldCallback(OnStartFieldCallback c) { m_OnStartFieldCallback = c; } + // @param EntityID Entity + // @param std::string Component name + // @param std::string Field name + // @param char* Field data + typedef std::function OnStartFieldDataCallback; + void SetStartFieldDataCallback(OnStartFieldDataCallback c) { m_OnStartFieldDataCallback = c; } + +private: + OnStartEntityCallback m_OnStartEntityCallback = nullptr; + OnStartComponentCallback m_OnStartComponentCallback = nullptr; + OnStartFieldCallback m_OnStartFieldCallback = nullptr; + OnStartFieldDataCallback m_OnStartFieldDataCallback = nullptr; +}; + +class EntityFileSAXHandler : public xercesc::DefaultHandler +{ +public: + enum class State + { + Unknown, + Entity, + Component, + ComponentField + }; + + EntityFileSAXHandler(const EntityFileHandler* handler, xercesc::SAX2XMLReader* reader); + + void startElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname, const xercesc::Attributes& attrs) override; + void characters(const XMLCh* const chars, const XMLSize_t length) override; + void endElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname) override; + + void warning(const xercesc::SAXParseException& e); + void error(const xercesc::SAXParseException& e); + void fatalError(const xercesc::SAXParseException& e); + +private: + const EntityFileHandler* m_Handler; + xercesc::XMLGrammarPool* m_GrammarPool; + xercesc::SAX2XMLReader* m_Reader; + //State m_CurrentScope = State::Unknown; + std::stack m_StateStack; + unsigned int m_NextEntityID = 0; + std::stack m_EntityStack; + std::string m_CurrentComponent; + std::string m_CurrentField; + std::map m_CurrentAttributes; + + void onStartEntity(const xercesc::Attributes& attrs); + void onEndEntity(); + void onStartEntityRef(const xercesc::Attributes& attrs); + void onStartComponent(const std::string& name); + void onEndComponent(const std::string& name); + void onStartComponentField(const std::string& field, const xercesc::Attributes& attrs); + void onEndComponentField(const std::string& field); + void onFieldData(char* data); +}; + +class EntityFileXMLErrorHandler : public xercesc::ErrorHandler +{ +public: + void warning(const xercesc::SAXParseException& e) override + { + reportParseException("Warning", e); + } + void error(const xercesc::SAXParseException& e) override + { + reportParseException("Error", e); + } + void fatalError(const xercesc::SAXParseException& e) override + { + reportParseException("FATAL ERROR", e); + } + void resetErrors() override { } + +private: + void reportParseException(std::string type, const xercesc::SAXParseException& e) + { + char* message = xercesc::XMLString::transcode(e.getMessage()); + char* systemID = xercesc::XMLString::transcode(e.getSystemId()); + std::cerr << systemID << ":" << e.getLineNumber() << ":" << e.getColumnNumber() << std::endl; + std::cerr << type << ": " << message << std::endl; + xercesc::XMLString::release(&systemID); + xercesc::XMLString::release(&message); + } +}; + +class EntityXMLFile : public Resource +{ + friend class ResourceManager; + friend class EntityFileSAXHandler; +private: + EntityXMLFile(boost::filesystem::path path); + ~EntityXMLFile(); + +public: + static unsigned int GetTypeStride(std::string typeName); + static void WriteAttributeData(char* outData, const ComponentInfo::Field_t& field, const std::map& attributes); + static void WriteValueData(char* outData, const ComponentInfo::Field_t& field, const char* valueData); + + xercesc::XMLGrammarPool* GrammarPool() const { return m_GrammarPool; } + + void Parse(const EntityFileHandler* handler) const; + +private: + boost::filesystem::path m_FilePath; + xercesc::XMLGrammarPool* m_GrammarPool; + xercesc::SAX2XMLReader* m_SAX2XMLReader; + //std::map m_ComponentInfo; + //std::vector m_EntityReferences; + + static void setReaderFeatures(xercesc::SAX2XMLReader* reader); +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Core/EntityFileParser.h b/include/Engine/Core/EntityXMLFileParser.h similarity index 78% rename from include/Engine/Core/EntityFileParser.h rename to include/Engine/Core/EntityXMLFileParser.h index b4eee5b2..4bc2fab9 100644 --- a/include/Engine/Core/EntityFileParser.h +++ b/include/Engine/Core/EntityXMLFileParser.h @@ -1,18 +1,19 @@ -#ifndef EntityFileParser_h__ -#define EntityFileParser_h__ +#ifndef EntityXMLFileParser_h__ +#define EntityXMLFileParser_h__ -#include "EntityFile.h" +#include "EntityXMLFile.h" #include "World.h" -class EntityFileParser +class EntityXMLFileParser { + friend class EntityFile; public: - EntityFileParser(const EntityFile* entityFile); - - EntityID MergeEntities(World* world, EntityID baseParent = EntityID_Invalid); + EntityXMLFileParser(const EntityXMLFile* entityFile); private: - const EntityFile* m_EntityFile; + EntityID MergeEntities(World* world, EntityID baseParent = EntityID_Invalid); + + const EntityXMLFile* m_EntityFile; EntityFileHandler m_Handler; World* m_World = nullptr; EntityID m_FirstEntity = EntityID_Invalid; diff --git a/include/Engine/Core/EntityFilePreprocessor.h b/include/Engine/Core/EntityXMLFilePreprocessor.h similarity index 80% rename from include/Engine/Core/EntityFilePreprocessor.h rename to include/Engine/Core/EntityXMLFilePreprocessor.h index b46bd383..4f969291 100644 --- a/include/Engine/Core/EntityFilePreprocessor.h +++ b/include/Engine/Core/EntityXMLFilePreprocessor.h @@ -1,5 +1,5 @@ -#ifndef EntityFilePreprocessor_h__ -#define EntityFilePreprocessor_h__ +#ifndef EntityXMLFilePreprocessor_h__ +#define EntityXMLFilePreprocessor_h__ #include #include @@ -17,17 +17,18 @@ #include "Util/XercesString.h" #include "ResourceManager.h" #include "World.h" -#include "EntityFile.h" +#include "EntityXMLFile.h" -class EntityFilePreprocessor +class EntityXMLFilePreprocessor { + friend class EntityFile; public: - EntityFilePreprocessor(const EntityFile* entityFile); - - void RegisterComponents(World* world); + EntityXMLFilePreprocessor(const EntityXMLFile* entityFile); private: - const EntityFile* m_EntityFile; + void RegisterComponents(World* world); + + const EntityXMLFile* m_EntityFile; std::map m_ComponentCounts; std::map m_ComponentInfo; diff --git a/include/Engine/Core/EntityFileWriter.h b/include/Engine/Core/EntityXMLFileWriter.h similarity index 87% rename from include/Engine/Core/EntityFileWriter.h rename to include/Engine/Core/EntityXMLFileWriter.h index b75bc145..da073a73 100644 --- a/include/Engine/Core/EntityFileWriter.h +++ b/include/Engine/Core/EntityXMLFileWriter.h @@ -1,5 +1,5 @@ -#ifndef EntityFileWriter_h__ -#define EntityFileWriter_h__ +#ifndef EntityXMLFileWriter_h__ +#define EntityXMLFileWriter_h__ #include #include @@ -8,13 +8,13 @@ #include #include "Util/XercesString.h" -#include "EntityFile.h" +#include "EntityXMLFile.h" #include "World.h" -class EntityFileWriter +class EntityXMLFileWriter { public: - EntityFileWriter(boost::filesystem::path file) + EntityXMLFileWriter(boost::filesystem::path file) : m_FilePath(file) { using namespace xercesc; diff --git a/include/Engine/Core/MemoryPool.h b/include/Engine/Core/MemoryPool.h index 053e75aa..da4af84e 100644 --- a/include/Engine/Core/MemoryPool.h +++ b/include/Engine/Core/MemoryPool.h @@ -118,9 +118,6 @@ public: else { m_ExtraMemory.push_back((char*)malloc(m_Stride)); //We should preferably not enter here to avoid performance issues. Set more numMaxElements in constructor instead. - if (!DisableMemoryPool::Value) { - LOG_DEBUG("Allocated slots exceed Pool size, extra memory allocated dynamically. Pool size: %u, dynamic size: %u.", m_NumSlots, m_ExtraMemory.size()); - } return m_ExtraMemory.back(); } } diff --git a/include/Engine/Core/World.h b/include/Engine/Core/World.h index c9f738ce..9ae38021 100644 --- a/include/Engine/Core/World.h +++ b/include/Engine/Core/World.h @@ -6,6 +6,7 @@ #include "ObjectPool.h" #include "ComponentPool.h" #include "EventBroker.h" +struct EntityWrapper; class World { @@ -18,13 +19,13 @@ public: World(const World& other); // Create empty entity - EntityID CreateEntity(EntityID parent = 0); + EntityID CreateEntity(EntityID parent = EntityID_Invalid); // Delete entity and all components within void DeleteEntity(EntityID entity); // Check if an entity exists bool ValidEntity(EntityID entity) const; // Register a component type and allocate space for it - void RegisterComponent(ComponentInfo& ci); + void RegisterComponent(const ComponentInfo& ci); // Attach a component to an entity and fill it with default values ComponentWrapper AttachComponent(EntityID entity, const std::string& componentType); // Check if an entity has a component @@ -49,6 +50,12 @@ public: void SetName(EntityID entity, const std::string& name); // Get the textual name of an entity std::string GetName(EntityID entity) const; + // Get the first entity in the world with the name. + EntityWrapper GetFirstEntityByName(const std::string& name); + + // Merge another world into this one + // Returns a map that maps entities from the other world to their copies in this one + std::unordered_map Merge(const World* other); private: EventBroker* m_EventBroker = nullptr; diff --git a/include/Engine/Editor/EditorCameraInputController.h b/include/Engine/Editor/EditorCameraInputController.h index 4c139e01..6cb31d99 100644 --- a/include/Engine/Editor/EditorCameraInputController.h +++ b/include/Engine/Editor/EditorCameraInputController.h @@ -104,6 +104,11 @@ protected: if (!m_Enabled) { return false; } + + ImGuiIO& io = ImGui::GetIO(); + if (io.WantCaptureMouse || io.WantCaptureKeyboard) { + return false; + } m_SpeedMultiplier += e.DeltaY * (0.1 * m_SpeedMultiplier); m_Config->Set("Editor.CameraSpeed", m_SpeedMultiplier); diff --git a/include/Engine/Editor/EditorSystem.h b/include/Engine/Editor/EditorSystem.h index 06ee53b6..655ac9b9 100644 --- a/include/Engine/Editor/EditorSystem.h +++ b/include/Engine/Editor/EditorSystem.h @@ -5,9 +5,8 @@ #include "../Core/World.h" #include "../Core/SystemPipeline.h" #include "../Core/ResourceManager.h" -#include "../Core/EntityFilePreprocessor.h" -#include "../Core/EntityFileParser.h" -#include "../Core/EntityFileWriter.h" +#include "../Core/EntityFile.h" +#include "../Core/EntityXMLFileWriter.h" #include "../Core/EMousePress.h" #include "../Input/EInputCommand.h" #include "EditorGUI.h" diff --git a/include/Engine/Input/FirstPersonInputController.h b/include/Engine/Input/FirstPersonInputController.h index 7dc24a2c..7ed85c84 100644 --- a/include/Engine/Input/FirstPersonInputController.h +++ b/include/Engine/Input/FirstPersonInputController.h @@ -27,7 +27,7 @@ public: virtual bool OnCommand(const Events::InputCommand& e) override; virtual void Reset(); - void AssaultDashCheck(double dt, bool isJumping, double assaultDashCoolDownMaxTimer); + void AssaultDashCheck(double dt, bool isJumping, double assaultDashCoolDownMaxTimer, double& assaultDashCoolDownTimer, EntityID playerID); virtual bool AssaultDashDoubleTapped() const { return m_AssaultDashDoubleTapped; } virtual bool PlayerIsDashing() const { return m_PlayerIsDashing; } @@ -41,7 +41,7 @@ protected: bool m_Crouching = false; //assault dash membervariables - needed to calculate the doubletap- and dashlogic double m_AssaultDashDoubleTapDeltaTime = 0.0; - double m_AssaultDashCoolDownTimer = 0.0; + double m_DashEffectResetTimer = 0.0; //i will let m_AssaultDashDoubleTapSensitivityTimer stay hardcoded, its not really a gamevariable (more an inputvariable), //and its very unlikely that someone wants to change that value const float m_AssaultDashDoubleTapSensitivityTimer = 0.25f; @@ -52,7 +52,7 @@ protected: bool m_ShiftDashing = false; bool m_ValidDoubleTap = false; - //specialabilitys + //specialabilities bool m_MovementKeyDown = false; bool m_SpecialAbilityKeyDown = false; int m_NumberOfMovementKeysDown = 0; @@ -191,23 +191,33 @@ bool FirstPersonInputController::OnLockMouse(const Events::LockMou } template -void FirstPersonInputController::AssaultDashCheck(double dt, bool isJumping, double assaultDashCoolDownMaxTimer) { +void FirstPersonInputController::AssaultDashCheck(double dt, bool isJumping, double assaultDashCoolDownMaxTimer, double& assaultDashCoolDownTimer, EntityID playerID) { m_AssaultDashDoubleTapDeltaTime += dt; - m_AssaultDashCoolDownTimer -= dt; + m_DashEffectResetTimer += dt; + assaultDashCoolDownTimer -= dt; //cooldown = assaultDashCoolDownMaxTimer sec, pretend the dash lasts 0.25 sec (for friction to do its work) - if (m_AssaultDashCoolDownTimer > (assaultDashCoolDownMaxTimer - 0.25f)) { + if (assaultDashCoolDownTimer > (assaultDashCoolDownMaxTimer - 0.25f)) { m_PlayerIsDashing = true; + if (m_DashEffectResetTimer > 0.05) { + Events::DashAbility e; + e.Player = playerID; + m_EventBroker->Publish(e); + m_DashEffectResetTimer = 0.0; + } } else { m_PlayerIsDashing = false; } //dashing with shift - if (m_ShiftDashing && m_AssaultDashCoolDownTimer <= 0.0f) { + if (m_ShiftDashing && assaultDashCoolDownTimer <= 0.0f) { //player is dashing with shift //the wanted-direction is set in playermovement already so we dont need to check what direction we want to dash in! - m_AssaultDashCoolDownTimer = assaultDashCoolDownMaxTimer; + assaultDashCoolDownTimer = assaultDashCoolDownMaxTimer; m_AssaultDashDoubleTapped = true; m_AssaultDashDoubleTapDeltaTime = 0.f; + Events::DashAbility e; + e.Player = playerID; + m_EventBroker->Publish(e); return; } @@ -227,7 +237,7 @@ void FirstPersonInputController::AssaultDashCheck(double dt, bool } m_ValidDoubleTap = false; - if (!(m_AssaultDashCoolDownTimer <= 0.0f)) { + if (!(assaultDashCoolDownTimer <= 0.0f)) { //if we cant dash at the moment, then just reset the tap-sensitivity-timer m_AssaultDashDoubleTapDeltaTime = 0.f; return; @@ -235,9 +245,10 @@ void FirstPersonInputController::AssaultDashCheck(double dt, bool //ok, we have a valid tap, lets do it m_AssaultDashDoubleTapped = true; m_AssaultDashDoubleTapDeltaTime = 0.f; - m_AssaultDashCoolDownTimer = assaultDashCoolDownMaxTimer; + assaultDashCoolDownTimer = assaultDashCoolDownMaxTimer; Events::DashAbility e; + e.Player = playerID; m_EventBroker->Publish(e); } diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index be76e265..4ee071d2 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -26,7 +26,9 @@ #include "Network/EInterpolate.h" #include "Network/SnapshotFilter.h" #include "Core/EPlayerSpawned.h" +#include "Core/EAmmoPickup.h" #include "Network/ESearchForServers.h" +#include "../Game/Events/EDashAbility.h" struct ServerInfo { @@ -106,7 +108,9 @@ private: void parsePlayerDamage(Packet& packet); void parseComponentDeletion(Packet& packet); void parseDoubleJump(Packet& packet); - void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType); + void parseDashEffect(Packet& packet); + void parseAmmoPickup(Packet& packet); + void InterpolateFields(Packet& packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType); void parseSnapshot(Packet& packet); void identifyPacketLoss(); void hasServerTimedOut(); @@ -133,6 +137,9 @@ private: EventRelay< Client, Events::SearchForServers> m_ESearchForServers; EventRelay m_EDoubleJump; bool OnDoubleJump(Events::DoubleJump & e); + EventRelay m_EDashAbility; + bool OnDashAbility(const Events::DashAbility& e); + bool OnSearchForServers(const Events::SearchForServers& e); UDPClient m_ServerlistRequest; std::vector m_Serverlist; diff --git a/include/Engine/Network/MessageType.h b/include/Engine/Network/MessageType.h index 00a2a91f..c34f584e 100644 --- a/include/Engine/Network/MessageType.h +++ b/include/Engine/Network/MessageType.h @@ -20,7 +20,9 @@ enum class MessageType ComponentDeleted, PlayerTransform, OnDoubleJump, + OnDashEffect, ServerlistRequest, + AmmoPickup, Invalid }; diff --git a/include/Engine/Network/Packet.h b/include/Engine/Network/Packet.h index b688b8c6..e7444d9d 100644 --- a/include/Engine/Network/Packet.h +++ b/include/Engine/Network/Packet.h @@ -24,7 +24,9 @@ public: { // Check if we are trying to add more than the package can fit. if (m_MaxPacketSize < m_Offset + sizeof(T)) { - LOG_WARNING("Packet AddPrimitive(): You are trying to add more than we have allocated for! New size is %i bytes\n", m_MaxPacketSize*2); + if (m_MaxPacketSize >= 32000) { + LOG_WARNING("Package::WritePrimitive(): New size is huge %i bytes\n", m_MaxPacketSize*2); + } resizeData(); } memcpy(m_Data + m_Offset, &val, sizeof(T)); diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index aac4e4c8..7bcefc65 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -20,6 +20,7 @@ #include "../Game/Events/EDoubleJump.h" #include "Core/EEntityDeleted.h" #include "Core/EComponentDeleted.h" +#include "Core/EAmmoPickup.h" class Server : public Network { @@ -82,13 +83,14 @@ private: void parseClientPing(); void parsePing(); bool parseDoubleJump(Packet& packet); + void parseDashEffect(Packet& packet); void parseUDPConnect(Packet& packet); void parseTCPConnect(Packet& packet); void parseDisconnect(); void parseServerlistRequest(boost::asio::ip::udp::endpoint endpoint); bool shouldSendToClient(EntityWrapper childEntity); - // Debug event + // Events EventRelay m_EInputCommand; bool OnInputCommand(const Events::InputCommand& e); EventRelay m_EPlayerSpawned; @@ -99,6 +101,8 @@ private: bool OnComponentDeleted(const Events::ComponentDeleted& e); EventRelay m_EPlayerDamage; bool OnPlayerDamage(const Events::PlayerDamage& e); + EventRelay m_EAmmoPickup; + bool OnAmmoPickup(const Events::AmmoPickup& e); }; #endif diff --git a/include/Engine/Rendering/DrawBloomPass.h b/include/Engine/Rendering/DrawBloomPass.h index 07c90e23..ee3a8489 100644 --- a/include/Engine/Rendering/DrawBloomPass.h +++ b/include/Engine/Rendering/DrawBloomPass.h @@ -12,7 +12,7 @@ class DrawBloomPass { public: - DrawBloomPass(IRenderer* renderer /* ,Texture or finalpass*/ ); + DrawBloomPass(IRenderer* renderer, ConfigFile* config); ~DrawBloomPass() { } void InitializeTextures(); void InitializeFrameBuffers(); @@ -23,26 +23,33 @@ public: void FillGaussianBuffer(FrameBuffer* fb); void Draw(GLuint texture); + void ChangeQuality(int quality); void OnWindowResize(); //Getters //Return the blurred result of the texture that was sent into draw - GLuint GaussianTexture() const { return m_GaussianTexture_vert; } + GLuint GaussianTexture() const { + if (m_Quality == 0) { + return m_BlackTexture->m_Texture; + } else { + return m_GaussianTexture_vert; + } + } private: - void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const; - - Texture* m_WhiteTexture; + Texture* m_BlackTexture; Model* m_ScreenQuad; const IRenderer* m_Renderer; + ConfigFile* m_Config; //const LightCullingPass* m_LightCullingPass - GLuint m_iterations = 9; + int m_Iterations; + int m_Quality = 0; - GLuint m_GaussianTexture_horiz; - GLuint m_GaussianTexture_vert; + GLuint m_GaussianTexture_horiz = 0; + GLuint m_GaussianTexture_vert = 0; FrameBuffer m_GaussianFrameBuffer_horiz; FrameBuffer m_GaussianFrameBuffer_vert; diff --git a/include/Engine/Rendering/DrawColorCorrectionPass.h b/include/Engine/Rendering/DrawColorCorrectionPass.h index 231e2d33..fcde73d7 100644 --- a/include/Engine/Rendering/DrawColorCorrectionPass.h +++ b/include/Engine/Rendering/DrawColorCorrectionPass.h @@ -17,7 +17,7 @@ public: void InitializeFrameBuffers(); void InitializeShaderPrograms(); - void Draw(GLuint sceneTexture, GLuint bloomTexture, GLuint sceneTextureLowRes, GLuint bloomTextureLowRes, GLfloat gamma, GLfloat exposure); + void Draw(GLuint sceneTexture, GLuint bloomTexture, GLfloat gamma, GLfloat exposure); private: const IRenderer* m_Renderer; diff --git a/include/Engine/Rendering/DrawFinalPass.h b/include/Engine/Rendering/DrawFinalPass.h index 1800c90e..cfddd5c6 100644 --- a/include/Engine/Rendering/DrawFinalPass.h +++ b/include/Engine/Rendering/DrawFinalPass.h @@ -5,6 +5,7 @@ #include "DrawFinalPassState.h" #include "LightCullingPass.h" #include "CubeMapPass.h" +#include "SSAOPass.h" #include "FrameBuffer.h" #include "ShaderProgram.h" #include "Util/UnorderedMapVec2.h" @@ -14,34 +15,28 @@ class DrawFinalPass { public: - DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass, CubeMapPass* cubeMapPass); + DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass, CubeMapPass* cubeMapPass, SSAOPass* ssaoPass); ~DrawFinalPass() { } void InitializeTextures(); void InitializeFrameBuffers(); void InitializeShaderPrograms(); - void Draw(RenderScene& scene, GLuint SSAOTexture); + void Draw(RenderScene& scene); void ClearBuffer(); void OnWindowResize(); //Return the texture that is used in later stages to apply the bloom effect GLuint BloomTexture() const { return m_BloomTexture; } - GLuint BloomTextureLowRes() const { return m_BloomTextureLowRes; } //Return the texture with diffuse and lighting of the scene. GLuint SceneTexture() const { return m_SceneTexture; } - GLuint SceneTextureLowRes() const { return m_SceneTextureLowRes; } //Return the framebuffer used in the scene rendering stage. FrameBuffer* FinalPassFrameBuffer() { return &m_FinalPassFrameBuffer; } - FrameBuffer* FinalPassFrameBufferLowRes() { return &m_FinalPassFrameBufferLowRes; } private: - void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const; - void GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm::vec2 dimensions, GLint format, GLenum type, GLint numMipMaps) const; - void DrawSprites(std::list>&jobs, RenderScene& scene); - void DrawModelRenderQueues(std::list>& jobs, RenderScene& scene, GLuint SSAOTexture); - void DrawShieldToStencilBuffer(std::list>& jobs, RenderScene& scene); + void DrawModelRenderQueues(std::list>& jobs, RenderScene& scene); + void DrawModelRenderQueuesWithShieldCheck(std::list>& jobs, RenderScene& scene); void DrawShieldedModelRenderQueue(std::list>& jobs, RenderScene& scene); - void DrawToDepthBuffer(std::list>& jobs, RenderScene& scene); + void DrawToDepthStencilBuffer(std::list>& jobs, RenderScene& scene); void BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene); void BindModelUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene); @@ -56,13 +51,11 @@ private: Texture* m_ErrorTexture; FrameBuffer m_FinalPassFrameBuffer; - FrameBuffer m_FinalPassFrameBufferLowRes; + FrameBuffer m_ShieldDepthFrameBuffer; GLuint m_BloomTexture; GLuint m_SceneTexture; - GLuint m_BloomTextureLowRes; - GLuint m_SceneTextureLowRes; GLuint m_DepthBuffer; - GLuint m_DepthBufferLowRes; + GLuint m_ShieldBuffer; GLuint m_CubeMapTexture; //maqke this component based i guess? @@ -71,22 +64,34 @@ private: const IRenderer* m_Renderer; const LightCullingPass* m_LightCullingPass; const CubeMapPass* m_CubeMapPass; + const SSAOPass* m_SSAOPass; ShaderProgram* m_ForwardPlusProgram; ShaderProgram* m_ExplosionEffectProgram; ShaderProgram* m_ExplosionEffectSplatMapProgram; ShaderProgram* m_SpriteProgram; ShaderProgram* m_ForwardPlusSplatMapProgram; - ShaderProgram* m_ShieldToStencilProgram; - ShaderProgram* m_FillDepthBufferProgram; + ShaderProgram* m_FillDepthStencilBufferProgram; + + ShaderProgram* m_ForwardPlusShieldCheckProgram; + ShaderProgram* m_ExplosionEffectShieldCheckProgram; + ShaderProgram* m_ExplosionEffectSplatMapShieldCheckProgram; + ShaderProgram* m_SpriteShieldCheckProgram; + ShaderProgram* m_ForwardPlusSplatMapShieldCheckProgram; + ShaderProgram* m_ForwardPlusSkinnedProgram; ShaderProgram* m_ExplosionEffectSkinnedProgram; ShaderProgram* m_ExplosionEffectSplatMapSkinnedProgram; ShaderProgram* m_ForwardPlusSplatMapSkinnedProgram; - ShaderProgram* m_ShieldToStencilSkinnedProgram; - ShaderProgram* m_FillDepthBufferSkinnedProgram; + ShaderProgram* m_FillDepthStencilBufferSkinnedProgram; + + ShaderProgram* m_ForwardPlusSkinnedShieldCheckProgram; + ShaderProgram* m_ExplosionEffectSkinnedShieldCheckProgram; + ShaderProgram* m_ExplosionEffectSplatMapSkinnedShieldCheckProgram; + ShaderProgram* m_ForwardPlusSplatMapSkinnedShieldCheckProgram; + ShaderProgram* m_FillDepthBufferSkinnedShieldCheckProgram; }; #endif \ No newline at end of file diff --git a/include/Engine/Rendering/ExplosionEffectJob.h b/include/Engine/Rendering/ExplosionEffectJob.h index 8f339526..695a8dfe 100644 --- a/include/Engine/Rendering/ExplosionEffectJob.h +++ b/include/Engine/Rendering/ExplosionEffectJob.h @@ -15,8 +15,8 @@ struct ExplosionEffectJob : ModelJob { - ExplosionEffectJob(ComponentWrapper explosionEffectComponent, ::Model* model, Camera* camera, glm::mat4 matrix, ::RawModel::MaterialProperties matGroup, ComponentWrapper modelComponent, ::World* world, glm::vec4 fillColor, float fillPercentage) - : ModelJob(model, camera, matrix, matGroup, modelComponent, world, fillColor, fillPercentage) + ExplosionEffectJob(ComponentWrapper explosionEffectComponent, ::Model* model, Camera* camera, glm::mat4 matrix, ::RawModel::MaterialProperties matGroup, ComponentWrapper modelComponent, ::World* world, glm::vec4 fillColor, float fillPercentage, bool isShielded) + : ModelJob(model, camera, matrix, matGroup, modelComponent, world, fillColor, fillPercentage, isShielded) { ExplosionOrigin = (glm::vec3)explosionEffectComponent["ExplosionOrigin"]; TimeSinceDeath = (double)explosionEffectComponent["TimeSinceDeath"]; diff --git a/include/Engine/Rendering/IRenderer.h b/include/Engine/Rendering/IRenderer.h index 4441bb7d..2e6f3a97 100644 --- a/include/Engine/Rendering/IRenderer.h +++ b/include/Engine/Rendering/IRenderer.h @@ -5,11 +5,13 @@ #include "../OpenGL.h" #include "../GLM.h" #include "../Core/Util/Rectangle.h" +#include "../Core/ConfigFile.h" #include "Util/ScreenCoords.h" #include "Camera.h" #include "RenderQueue.h" #include "Model.h" #include "../Core/World.h" //So temp +#include "Util/CommonFunctions.h" struct PickData diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index c2a469d2..58993ea1 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -18,7 +18,7 @@ struct ModelJob : RenderJob { - ModelJob(Model* model, Camera* camera, glm::mat4 matrix, ::RawModel::MaterialProperties matProp, ComponentWrapper modelComponent, World* world, glm::vec4 fillColor, float fillPercentage) + ModelJob(Model* model, Camera* camera, glm::mat4 matrix, ::RawModel::MaterialProperties matProp, ComponentWrapper modelComponent, World* world, glm::vec4 fillColor, float fillPercentage, bool isShielded) : RenderJob() { Model = model; @@ -117,7 +117,7 @@ struct ModelJob : RenderJob FillColor = fillColor; FillPercentage = fillPercentage; - + IsShielded = isShielded; if (model->IsSkinned()) { Skeleton = Model->m_RawModel->m_Skeleton; @@ -181,7 +181,7 @@ struct ModelJob : RenderJob glm::vec4 FillColor = glm::vec4(0); float FillPercentage = 0.0; - + bool IsShielded; void CalculateHash() override { Hash = ShaderID << 20 + ModelID << 10 + TextureID; diff --git a/include/Engine/Rendering/PickingPass.h b/include/Engine/Rendering/PickingPass.h index f6434781..df99a615 100644 --- a/include/Engine/Rendering/PickingPass.h +++ b/include/Engine/Rendering/PickingPass.h @@ -28,15 +28,13 @@ public: const ShaderProgram& PickingProgram() const { return *m_PickingProgram; } //const std::unordered_map& PickingColorsToEntity() const { return m_PickingColorsToEntity; } GLuint PickingTexture() const { return m_PickingTexture; } - GLuint DepthBuffer() const { return m_DepthBuffer; } + GLuint* DepthBuffer() { return &m_DepthBuffer; } const FrameBuffer& PickingBuffer() const { return m_PickingBuffer; } PickData Pick(glm::vec2 screenCoord); private: - void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const; - EventBroker* m_EventBroker; const IRenderer* m_Renderer; diff --git a/include/Engine/Rendering/RenderQueue.h b/include/Engine/Rendering/RenderQueue.h index 647adab8..e3c46e85 100644 --- a/include/Engine/Rendering/RenderQueue.h +++ b/include/Engine/Rendering/RenderQueue.h @@ -24,7 +24,6 @@ struct RenderScene std::list> OpaqueObjects; std::list> TransparentObjects; std::list> OpaqueShieldedObjects; - std::list> TransparentShieldedObjects; std::list> ShieldObjects; std::list> SpriteJob; std::list> PointLight; @@ -41,7 +40,6 @@ struct RenderScene Jobs.OpaqueObjects.clear(); Jobs.TransparentObjects.clear(); Jobs.OpaqueShieldedObjects.clear(); - Jobs.TransparentShieldedObjects.clear(); Jobs.ShieldObjects.clear(); Jobs.SpriteJob.clear(); Jobs.DirectionalLight.clear(); diff --git a/include/Engine/Rendering/RenderState.h b/include/Engine/Rendering/RenderState.h index c1886247..24f908a9 100644 --- a/include/Engine/Rendering/RenderState.h +++ b/include/Engine/Rendering/RenderState.h @@ -24,6 +24,8 @@ public: bool StencilFunc(GLenum func, GLint ref, GLuint mask); bool StencilMask(GLuint mask); bool DepthMask(GLboolean flag); + bool DepthFunc(GLenum func); + bool AlphaFunc(GLenum func, GLclampf thresholder); private: std::vector> m_ResetFunctions; diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index f3a6bf31..a64a4aa3 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -32,8 +32,9 @@ class Renderer : public IRenderer static void glfwFrameBufferCallback(GLFWwindow* window, int width, int height); public: - Renderer(EventBroker* eventBroker) - : m_EventBroker(eventBroker) + Renderer(EventBroker* eventBroker, ConfigFile* config) + : m_EventBroker(eventBroker) + , m_Config(config) { } virtual void Initialize() override; @@ -47,6 +48,7 @@ private: //----------------------Variables----------------------// static std::unordered_map m_WindowToRenderer; + ConfigFile* m_Config; EventBroker* m_EventBroker; TextPass* m_TextPass; @@ -61,12 +63,8 @@ private: int m_DebugTextureToDraw = 0; int m_CubeMapTexture = 0; bool m_ResizeWindow = false; - float m_SSAO_Radius = 1.0f; - float m_SSAO_Bias = 0.05f; - float m_SSAO_Contrast = 1.5f; - float m_SSAO_IntensityScale = 1.0f; - int m_SSAO_NumOfSamples = 24; - int m_SSAO_NumOfTurns = 7; + int m_SSAO_Quality = 0; + int m_GLOW_Quality = 2; PickingPass* m_PickingPass; LightCullingPass* m_LightCullingPass; diff --git a/include/Engine/Rendering/SSAOPass.h b/include/Engine/Rendering/SSAOPass.h index 792d1d82..1cb28009 100644 --- a/include/Engine/Rendering/SSAOPass.h +++ b/include/Engine/Rendering/SSAOPass.h @@ -13,18 +13,32 @@ class SSAOPass { public: - SSAOPass(IRenderer* rendere); - ~SSAOPass() { - delete m_DrawBloomPass; - }; + SSAOPass(IRenderer* renderer, ConfigFile* config); + ~SSAOPass() { }; + + void ChangeQuality(int quality); void Draw(GLuint depthBuffer, Camera* camera); - void Setting(float radius, float bias, float contrast, float intensityScale, int numOfSamples, int NumOfTurns); + void Setting(float radius, float bias, float contrast, float intensityScale, int numOfSamples, int numOfTurns, int iterations, int quality); void ClearBuffer(); void OnWindowResize(); //Return the SSAO of the texture sent to Draw - GLuint SSAOTexture() const { return m_DrawBloomPass->GaussianTexture(); } + GLuint SSAOTexture() const { + if (m_Quality == 0) { + return m_WhiteTexture->m_Texture; + } else { + return m_Gaussian_vert; + } + } + + int TextureQuality() const { + if (m_Quality == 0) { + return 13; + } else { + return m_TextureQuality; + } + } private: void InitializeTexture(); @@ -32,14 +46,13 @@ private: void InitializeShaderProgram(); void InitializeBuffer(); - void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const; - //void blurHorizontal(GLuint depthBuffer); //void blurVertical(GLuint depthBuffer); Model* m_ScreenQuad; const IRenderer* m_Renderer; + ConfigFile* m_Config; float m_Radius; float m_Bias; @@ -47,17 +60,28 @@ private: float m_IntensityScale; int m_NumOfSamples; int m_NumOfTurns; + int m_Iterations; + int m_TextureQuality; + int m_Quality = 0; - GLuint m_SSAOTexture; + Texture* m_WhiteTexture; + + GLuint m_SSAOTexture = 0; FrameBuffer m_SSAOFramBuffer; - GLuint m_SSAOViewSpaceZTexture; + GLuint m_SSAOViewSpaceZTexture = 0; FrameBuffer m_SSAOViewSpaceZFramBuffer; + GLuint m_Gaussian_horiz = 0; + GLuint m_Gaussian_vert = 0; + + FrameBuffer m_GaussianFrameBuffer_horiz; + FrameBuffer m_GaussianFrameBuffer_vert; + ShaderProgram* m_SSAOProgram; ShaderProgram* m_SSAOViewSpaceZProgram; - - DrawBloomPass* m_DrawBloomPass; + ShaderProgram* m_GaussianProgram_horiz; + ShaderProgram* m_GaussianProgram_vert; }; #endif \ No newline at end of file diff --git a/include/Engine/Rendering/Util/CommonFunctions.h b/include/Engine/Rendering/Util/CommonFunctions.h index e178f52d..1ed3d82a 100644 --- a/include/Engine/Rendering/Util/CommonFunctions.h +++ b/include/Engine/Rendering/Util/CommonFunctions.h @@ -9,6 +9,10 @@ namespace CommonFunctions { Texture* LoadTexture(std::string path, bool threaded); +void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type); +void GenerateMultiSampleTexture(GLuint* texture, int numSamples, glm::vec2 dimensions, GLint internalFormat); +void GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm::vec2 dimensions, GLint format, GLenum type, GLint numMipMaps); +void DeleteTexture(GLuint* texture); }; #endif \ No newline at end of file diff --git a/include/Game/Events/EDashAbility.h b/include/Game/Events/EDashAbility.h index 62a2b935..c5078fab 100644 --- a/include/Game/Events/EDashAbility.h +++ b/include/Game/Events/EDashAbility.h @@ -2,11 +2,15 @@ #define Events_DashAbility_h__ #include "Core/Event.h" +#include "Core/EntityWrapper.h" namespace Events { -struct DashAbility : public Event { }; +struct DashAbility : public Event +{ + EntityID Player; +}; } diff --git a/include/Game/Game.h b/include/Game/Game.h index 06fd4703..4d173b48 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -13,13 +13,13 @@ #include "Input/KeyboardInputHandler.h" #include "Input/MouseInputHandler.h" #include "Core/EKeyDown.h" -#include "Core/EntityFilePreprocessor.h" +#include "Core/EntityXMLFilePreprocessor.h" #include "Core/SystemPipeline.h" #include "Systems/ExplosionEffectSystem.h" #include "Editor/EditorSystem.h" -#include "Core/EntityFile.h" +#include "Core/EntityXMLFile.h" #include "Rendering/RenderSystem.h" -#include "Core/EntityFileParser.h" +#include "Core/EntityXMLFileParser.h" #include "Core/Octree.h" #include "Rendering/Font.h" #include "Systems/InterpolationSystem.h" diff --git a/include/Game/Systems/AbilityCooldownHUDSystem.h b/include/Game/Systems/AbilityCooldownHUDSystem.h new file mode 100644 index 00000000..610b4dc2 --- /dev/null +++ b/include/Game/Systems/AbilityCooldownHUDSystem.h @@ -0,0 +1,17 @@ +#ifndef AbilityCooldownHUDSystem_h__ +#define AbilityCooldownHUDSystem_h__ + +#include "../../Engine/Core/System.h" +#include "../../Engine/GLM.h" + +class AbilityCooldownHUDSystem : public ImpureSystem +{ +public: + AbilityCooldownHUDSystem(SystemParams params) + : System(params) + { } + + virtual void Update(double dt) override; +}; + +#endif \ No newline at end of file diff --git a/include/Game/Systems/AmmoPickupSystem.h b/include/Game/Systems/AmmoPickupSystem.h index 0fbd9e08..70c5630f 100644 --- a/include/Game/Systems/AmmoPickupSystem.h +++ b/include/Game/Systems/AmmoPickupSystem.h @@ -4,7 +4,7 @@ #include "Core/System.h" #include "Core/Transform.h" #include "Core/ResourceManager.h" -#include "Core/EntityFileParser.h" +#include "Core/EntityFile.h" #include "Core/EPickupSpawned.h" #include "Core/EAmmoPickup.h" #include "Engine/Collision/ETrigger.h" @@ -20,6 +20,11 @@ public: private: EventRelay m_ETriggerTouch; bool OnTriggerTouch(Events::TriggerTouch& e); + EventRelay m_ETriggerLeave; + bool OnTriggerLeave(Events::TriggerLeave& e); + + EventRelay m_EAmmoPickup; + bool OnAmmoPickup(Events::AmmoPickup& e); struct NewAmmoPickup { glm::vec3 Pos; @@ -29,5 +34,11 @@ private: EntityID parentID; }; std::vector m_ETriggerTouchVector; + struct EntityAtMaxValuePickupStruct { + EntityWrapper player; + EntityWrapper trigger; + }; + std::vector m_PickupAtMaximum; + void DoPickup(EntityWrapper &player, EntityWrapper &trigger); }; #endif diff --git a/include/Game/Systems/BoostIconsHUDSystem.h b/include/Game/Systems/BoostIconsHUDSystem.h new file mode 100644 index 00000000..d8de777d --- /dev/null +++ b/include/Game/Systems/BoostIconsHUDSystem.h @@ -0,0 +1,19 @@ +#ifndef BoostIconsHUDSystem_h__ +#define BoostIconsHUDSystem_h__ + +#include "../../Engine/Core/System.h" +#include "../../Engine/GLM.h" + +class BoostIconsHUDSystem : public PureSystem +{ +public: + BoostIconsHUDSystem(SystemParams params) + : System(params) + , PureSystem("BoostIconsHUD") + { } + + virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& capturePoint, double dt) override; + +}; + +#endif \ No newline at end of file diff --git a/include/Game/Systems/BoostSystem.h b/include/Game/Systems/BoostSystem.h new file mode 100644 index 00000000..f02e9472 --- /dev/null +++ b/include/Game/Systems/BoostSystem.h @@ -0,0 +1,21 @@ +#ifndef BoostSystem_h__ +#define BoostSystem_h__ + +#include "Core/System.h" +#include "Core/ResourceManager.h" +#include "Core/EntityFile.h" +#include "Core/EPlayerDamage.h" +#include "Common.h" + +class BoostSystem : public System +{ +public: + BoostSystem(SystemParams params); + +private: + EventRelay m_EPlayerDamage; + bool OnPlayerDamage(Events::PlayerDamage& e); + + std::string DetermineClass(EntityWrapper player); +}; +#endif \ No newline at end of file diff --git a/include/Game/Systems/CapturePointArrowHUDSystem.h b/include/Game/Systems/CapturePointArrowHUDSystem.h new file mode 100644 index 00000000..26462879 --- /dev/null +++ b/include/Game/Systems/CapturePointArrowHUDSystem.h @@ -0,0 +1,30 @@ +#ifndef CapturePointArrowHUDSystem_h__ +#define CapturePointArrowHUDSystem_h__ + +#include +#include +#include + +#include "Common.h" +#include "Core/System.h" +#include "Core/Transform.h" +#include "Core/ECaptured.h" + + +class CapturePointArrowHUDSystem : public ImpureSystem +{ +public: + CapturePointArrowHUDSystem(SystemParams params); + + virtual void Update(double dt) override; + +private: + EventRelay m_ECapturedEvent; + bool OnCapturePointCaptured(Events::Captured& e); + + bool m_InitialtargetsSet = false; + glm::vec3 m_RedTeamCurrentTarget; + glm::vec3 m_BlueTeamCurrentTarget; +}; + +#endif \ No newline at end of file diff --git a/include/Game/Systems/CapturePointHUDSystem.h b/include/Game/Systems/CapturePointHUDSystem.h index 41db0c12..53ca9b73 100644 --- a/include/Game/Systems/CapturePointHUDSystem.h +++ b/include/Game/Systems/CapturePointHUDSystem.h @@ -7,7 +7,7 @@ #include "Common.h" #include "Core/System.h" -#include "Engine/Collision/ETrigger.h" +#include "Collision/ETrigger.h" class CapturePointHUDSystem : public ImpureSystem { diff --git a/include/Game/Systems/CapturePointSystem.h b/include/Game/Systems/CapturePointSystem.h index 34a23e14..3cf72e15 100644 --- a/include/Game/Systems/CapturePointSystem.h +++ b/include/Game/Systems/CapturePointSystem.h @@ -42,9 +42,9 @@ private: int m_NumberOfCapturePoints = 0; std::map m_CapturePointNumberToEntityMap; - //std::vector - bool m_ResetTimers = false; + bool m_RecentlyCapturedNeedNextCapturePointNow = false; + Events::Captured m_CapturedEvent; //vectors which will keep track of enter/leave changes std::vector> m_ETriggerTouchVector; diff --git a/include/Game/Systems/DamageIndicatorSystem.h b/include/Game/Systems/DamageIndicatorSystem.h index ae9ba195..9c88ba78 100644 --- a/include/Game/Systems/DamageIndicatorSystem.h +++ b/include/Game/Systems/DamageIndicatorSystem.h @@ -4,7 +4,7 @@ #include "Core/System.h" #include "Core/Transform.h" #include "Core/ResourceManager.h" -#include "Core/EntityFileParser.h" +#include "Core/EntityFile.h" #include "Core/EPlayerDamage.h" #include "Common.h" #include diff --git a/include/Game/Systems/FloatingEffectSystem.h b/include/Game/Systems/FloatingEffectSystem.h new file mode 100644 index 00000000..56931001 --- /dev/null +++ b/include/Game/Systems/FloatingEffectSystem.h @@ -0,0 +1,19 @@ +#include "Common.h" +#include "Core/System.h" + +class FloatingEffectSystem : public PureSystem +{ +public: + FloatingEffectSystem(SystemParams params) + : System(params) + , PureSystem("FloatingEffect") + { } + + virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override + { + ComponentWrapper& transform = m_World->GetComponent(component.EntityID, "Transform"); + (double&)component["Time"] += dt; + (glm::vec3&)transform["Position"] = (float)(double)component["Amplitude"] * glm::sin((glm::two_pi() / (float)(double)component["Period"]) * (float)(double)component["Time"]) * (glm::vec3)component["Axis"]; + + } +}; \ No newline at end of file diff --git a/include/Game/Systems/PickupSpawnSystem.h b/include/Game/Systems/PickupSpawnSystem.h index 66c5f630..b72b8b25 100644 --- a/include/Game/Systems/PickupSpawnSystem.h +++ b/include/Game/Systems/PickupSpawnSystem.h @@ -4,12 +4,11 @@ #include "Core/System.h" #include "Core/Transform.h" #include "Core/ResourceManager.h" -#include "Core/EntityFileParser.h" +#include "Core/EntityFile.h" #include "Core/EPickupSpawned.h" #include "Core/EPlayerHealthPickup.h" #include "Engine/Collision/ETrigger.h" #include "Common.h" -#include class PickupSpawnSystem : public ImpureSystem { @@ -21,6 +20,8 @@ public: private: EventRelay m_ETriggerTouch; bool OnTriggerTouch(Events::TriggerTouch& e); + EventRelay m_ETriggerLeave; + bool OnTriggerLeave(Events::TriggerLeave& e); struct NewHealthPickup { glm::vec3 Pos; @@ -30,5 +31,11 @@ private: EntityID parentID; }; std::vector m_ETriggerTouchVector; + struct EntityAtMaxValuePickupStruct { + EntityWrapper player; + EntityWrapper trigger; + }; + std::vector m_PickupAtMaximum; + void DoPickup(EntityWrapper &player, EntityWrapper &trigger); }; #endif diff --git a/include/Game/Systems/PlayerDeathSystem.h b/include/Game/Systems/PlayerDeathSystem.h index 112c202e..e4f96114 100644 --- a/include/Game/Systems/PlayerDeathSystem.h +++ b/include/Game/Systems/PlayerDeathSystem.h @@ -6,11 +6,9 @@ #include "GLM.h" #include "Rendering/ESetCamera.h" #include "Core/ConfigFile.h" - #include "Core/EntityFile.h" -#include "Core/EntityFileParser.h" - #include "Core/EPlayerDeath.h" +#include "Core/EEntityDeleted.h" class PlayerDeathSystem : public ImpureSystem { @@ -20,8 +18,12 @@ public: virtual void Update(double dt) override; private: + EntityWrapper m_LocalPlayerDeathEffect; + EventRelay m_OnPlayerDeath; bool OnPlayerDeath(Events::PlayerDeath& e); + EventRelay m_EEntityDeleted; + bool OnEntityDeleted(Events::EntityDeleted& e); void createDeathEffect(EntityWrapper player); diff --git a/include/Game/Systems/PlayerMovementSystem.h b/include/Game/Systems/PlayerMovementSystem.h index 92aa1915..bf7b4718 100644 --- a/include/Game/Systems/PlayerMovementSystem.h +++ b/include/Game/Systems/PlayerMovementSystem.h @@ -6,9 +6,7 @@ #include #include "Events/EDoubleJump.h" #include "../Engine/Sound/EPlaySoundOnEntity.h" - #include "Core/EntityFile.h" -#include "Core/EntityFileParser.h" class PlayerMovementSystem : public ImpureSystem { @@ -41,6 +39,8 @@ private: bool OnPlayerSpawned(Events::PlayerSpawned& e); EventRelay m_EDoubleJump; bool PlayerMovementSystem::OnDoubleJump(Events::DoubleJump & e); + EventRelay m_EDashAbility; + bool PlayerMovementSystem::OnDashAbility(Events::DashAbility & e); void updateMovementControllers(double dt); void updateVelocity(EntityWrapper player, double dt); diff --git a/include/Game/Systems/PlayerSpawnSystem.h b/include/Game/Systems/PlayerSpawnSystem.h index bf87bef8..70f94807 100644 --- a/include/Game/Systems/PlayerSpawnSystem.h +++ b/include/Game/Systems/PlayerSpawnSystem.h @@ -13,8 +13,6 @@ public: PlayerSpawnSystem(SystemParams params); virtual void Update(double dt) override; - - static void SetRespawnTime(float respawnTime) { m_RespawnTime = respawnTime; }; private: struct SpawnRequest @@ -31,8 +29,8 @@ private: //EntityWrapper ID -> Player ID. std::map m_PlayerIDs; - static float m_RespawnTime; - float m_Timer; + float m_ForcedRespawnTime; + bool m_DbgConfigForceRespawn; EventRelay m_OnInputCommand; bool OnInputCommand(Events::InputCommand& e); diff --git a/include/Game/Systems/SpawnerSystem.h b/include/Game/Systems/SpawnerSystem.h index e4a44738..f36f7259 100644 --- a/include/Game/Systems/SpawnerSystem.h +++ b/include/Game/Systems/SpawnerSystem.h @@ -7,8 +7,7 @@ #include "Core/System.h" #include "Events/ESpawnerSpawn.h" #include "Core/Transform.h" -#include "Core/ResourceManager.h" -#include "Core/EntityFileParser.h" +#include "Core/EntityFile.h" class SpawnerSystem : public System { diff --git a/include/Game/Systems/Weapon/WeaponSystem.h b/include/Game/Systems/Weapon/WeaponSystem.h index b8278bc4..f6543ffb 100644 --- a/include/Game/Systems/Weapon/WeaponSystem.h +++ b/include/Game/Systems/Weapon/WeaponSystem.h @@ -9,8 +9,8 @@ #include "Core/EShoot.h" #include "Core/EPlayerSpawned.h" #include "Input/EInputCommand.h" -#include "Core/EntityFile.h" -#include "Core/EntityFileParser.h" +#include "Core/EntityXMLFile.h" +#include "Core/EntityXMLFileParser.h" #include "Core/Octree.h" #include "Collision/EntityAABB.h" #include "Systems/SpawnerSystem.h" diff --git a/resources/DefaultConfig.ini b/resources/DefaultConfig.ini index c118070b..35b3cd0f 100644 --- a/resources/DefaultConfig.ini +++ b/resources/DefaultConfig.ini @@ -4,7 +4,7 @@ LoadMap= ; if true -> Pool allocation is not used when calling Allocate/Free, just use regular dynamic allocation. ; if false -> Use pool allocation. DisableMemoryPool=false -RespawnTime = 8.0 +RespawnTime = -1.0 EditorEnabled=false OutOfBodyExperience=false @@ -37,4 +37,49 @@ ResourceLoading=true BGMVolume=1.0 SFXVolume=1.0 AnnouncerVolume=1.0 -Announcer=female \ No newline at end of file +Announcer=female + +[SSAO] +Quality=0 + +[SSAO1] +Radius=1.0 +Bias=0.02 +Contrast=1.5 +Intensity=1.0 +NumSamples=8 +NumTurns=3 +NumIterations=5 +TextureQuality=2 + +[SSAO2] +Radius=1.0 +Bias=0.02 +Contrast=1.5 +Intensity=1.0 +NumSamples=16 +NumTurns=13 +NumIterations=9 +TextureQuality=1 + +[SSAO3] +Radius=1.0 +Bias=0.02 +Contrast=1.5 +Intensity=1.0 +NumSamples=24 +NumTurns=17 +NumIterations=9 +TextureQuality=0 + +[GLOW] +Quality=3; + +[GLOW1] +NumIterations=5 + +[GLOW2] +NumIterations=9 + +[GLOW3] +NumIterations=13 \ No newline at end of file diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index cad50c7e..004a11a7 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -35,7 +35,12 @@ + + + + + @@ -46,6 +51,12 @@ + + + + + + \ No newline at end of file diff --git a/resources/Schema/Components/AbilityCooldownHUD.xml b/resources/Schema/Components/AbilityCooldownHUD.xml new file mode 100644 index 00000000..8f91bbc3 --- /dev/null +++ b/resources/Schema/Components/AbilityCooldownHUD.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/resources/Schema/Components/AbilityCooldownHUD.xsd b/resources/Schema/Components/AbilityCooldownHUD.xsd new file mode 100644 index 00000000..5bfb01a8 --- /dev/null +++ b/resources/Schema/Components/AbilityCooldownHUD.xsd @@ -0,0 +1,9 @@ + + + + + + HUD element for tracking ability cooldown. If it has a sprite and fill component it will fill the sprite with chosen color depending on the cooldown.\n A child with text component named "Cooldown" + + + \ No newline at end of file diff --git a/resources/Schema/Components/BoostAssault.xml b/resources/Schema/Components/BoostAssault.xml new file mode 100644 index 00000000..c76fe21e --- /dev/null +++ b/resources/Schema/Components/BoostAssault.xml @@ -0,0 +1,4 @@ + + + 2 + diff --git a/resources/Schema/Components/BoostAssault.xsd b/resources/Schema/Components/BoostAssault.xsd new file mode 100644 index 00000000..f7d348b7 --- /dev/null +++ b/resources/Schema/Components/BoostAssault.xsd @@ -0,0 +1,18 @@ + + + + + + + + This is the assault's class boost component + + + + + This is the strength of the boost effect + + + + + diff --git a/resources/Schema/Components/BoostDefender.xml b/resources/Schema/Components/BoostDefender.xml new file mode 100644 index 00000000..fad0d2b7 --- /dev/null +++ b/resources/Schema/Components/BoostDefender.xml @@ -0,0 +1,4 @@ + + + 10 + diff --git a/resources/Schema/Components/BoostDefender.xsd b/resources/Schema/Components/BoostDefender.xsd new file mode 100644 index 00000000..167b41dd --- /dev/null +++ b/resources/Schema/Components/BoostDefender.xsd @@ -0,0 +1,18 @@ + + + + + + + + This is the defender's class boost component + + + + + This is the strength of the boost effect + + + + + diff --git a/resources/Schema/Components/BoostIconsHUD.xml b/resources/Schema/Components/BoostIconsHUD.xml new file mode 100644 index 00000000..e25d9611 --- /dev/null +++ b/resources/Schema/Components/BoostIconsHUD.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/resources/Schema/Components/BoostIconsHUD.xsd b/resources/Schema/Components/BoostIconsHUD.xsd new file mode 100644 index 00000000..c5fe2e5d --- /dev/null +++ b/resources/Schema/Components/BoostIconsHUD.xsd @@ -0,0 +1,10 @@ + + + + + + + Origin for the 3 boost states. Create 3 children with Sprite and Fill components, name them "Sprint", "Defender", "Assault" + + + \ No newline at end of file diff --git a/resources/Schema/Components/BoostSniper.xml b/resources/Schema/Components/BoostSniper.xml new file mode 100644 index 00000000..844b7c59 --- /dev/null +++ b/resources/Schema/Components/BoostSniper.xml @@ -0,0 +1,4 @@ + + + 10 + diff --git a/resources/Schema/Components/BoostSniper.xsd b/resources/Schema/Components/BoostSniper.xsd new file mode 100644 index 00000000..2d62a9da --- /dev/null +++ b/resources/Schema/Components/BoostSniper.xsd @@ -0,0 +1,18 @@ + + + + + + + + This is the sniper's class boost component + + + + + This is the strength of the boost effect + + + + + diff --git a/resources/Schema/Components/CapturePointArrowHUD.xml b/resources/Schema/Components/CapturePointArrowHUD.xml new file mode 100644 index 00000000..ebe8727a --- /dev/null +++ b/resources/Schema/Components/CapturePointArrowHUD.xml @@ -0,0 +1,4 @@ + + + 0 + \ No newline at end of file diff --git a/resources/Schema/Components/CapturePointArrowHUD.xsd b/resources/Schema/Components/CapturePointArrowHUD.xsd new file mode 100644 index 00000000..d1c035f6 --- /dev/null +++ b/resources/Schema/Components/CapturePointArrowHUD.xsd @@ -0,0 +1,18 @@ + + + + + + HUD element for tracking next capturable Capture Point. + + + + + + Corresponds to the current capturepoint the arrow points Towards + + + + + + \ No newline at end of file diff --git a/resources/Schema/Components/CapturePointGameMode.xml b/resources/Schema/Components/CapturePointGameMode.xml new file mode 100644 index 00000000..3104e71f --- /dev/null +++ b/resources/Schema/Components/CapturePointGameMode.xml @@ -0,0 +1,5 @@ + + + 0.0 + 8.0 + \ No newline at end of file diff --git a/resources/Schema/Components/CapturePointGameMode.xsd b/resources/Schema/Components/CapturePointGameMode.xsd new file mode 100644 index 00000000..8b81d67a --- /dev/null +++ b/resources/Schema/Components/CapturePointGameMode.xsd @@ -0,0 +1,18 @@ + + + + + + + + + + The time since the last respawn wave. Players will be spawned when this reaches MaxRespawnTime. + + + Players will be spawned when RespawnTime reaches this. + + + + + \ No newline at end of file diff --git a/resources/Schema/Components/DashAbility.xml b/resources/Schema/Components/DashAbility.xml index a313c447..a71e4e52 100644 --- a/resources/Schema/Components/DashAbility.xml +++ b/resources/Schema/Components/DashAbility.xml @@ -1,4 +1,5 @@ 2.0 + 0.0 \ No newline at end of file diff --git a/resources/Schema/Components/DashAbility.xsd b/resources/Schema/Components/DashAbility.xsd index 4273cc71..6fc59c77 100644 --- a/resources/Schema/Components/DashAbility.xsd +++ b/resources/Schema/Components/DashAbility.xsd @@ -10,7 +10,10 @@ - This is the cooldown on dash + This is the max cooldown on dash + + + This is the current cooldown on dash diff --git a/resources/Schema/Components/DoubleJump.xml b/resources/Schema/Components/DoubleJump.xml new file mode 100644 index 00000000..bb0d3bc7 --- /dev/null +++ b/resources/Schema/Components/DoubleJump.xml @@ -0,0 +1,4 @@ + + + 4.0 + \ No newline at end of file diff --git a/resources/Schema/Components/DoubleJump.xsd b/resources/Schema/Components/DoubleJump.xsd new file mode 100644 index 00000000..65ff0419 --- /dev/null +++ b/resources/Schema/Components/DoubleJump.xsd @@ -0,0 +1,16 @@ + + + + + + + Enables a Player to double jump. + + + + Vertical velocity set on double jump. + + + + + \ No newline at end of file diff --git a/resources/Schema/Components/FloatingEffect.xml b/resources/Schema/Components/FloatingEffect.xml new file mode 100644 index 00000000..f1fd237a --- /dev/null +++ b/resources/Schema/Components/FloatingEffect.xml @@ -0,0 +1,8 @@ + + + 1 + 1 + + + + \ No newline at end of file diff --git a/resources/Schema/Components/FloatingEffect.xsd b/resources/Schema/Components/FloatingEffect.xsd new file mode 100644 index 00000000..a71006f5 --- /dev/null +++ b/resources/Schema/Components/FloatingEffect.xsd @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/Schema/Components/Player.xml b/resources/Schema/Components/Player.xml index 1aaeff25..b50274ac 100644 --- a/resources/Schema/Components/Player.xml +++ b/resources/Schema/Components/Player.xml @@ -2,6 +2,7 @@ 3 1.5 + 4.0 \ No newline at end of file diff --git a/resources/Schema/Components/Player.xsd b/resources/Schema/Components/Player.xsd index ebaed462..006ae9d7 100644 --- a/resources/Schema/Components/Player.xsd +++ b/resources/Schema/Components/Player.xsd @@ -11,6 +11,9 @@ + + Vertical velocity set when jumping. + diff --git a/resources/Schema/Components/ShieldAbility.xml b/resources/Schema/Components/ShieldAbility.xml new file mode 100644 index 00000000..49fcf0c0 --- /dev/null +++ b/resources/Schema/Components/ShieldAbility.xml @@ -0,0 +1,4 @@ + + + 2.0 + \ No newline at end of file diff --git a/resources/Schema/Components/ShieldAbility.xsd b/resources/Schema/Components/ShieldAbility.xsd new file mode 100644 index 00000000..5cf2145c --- /dev/null +++ b/resources/Schema/Components/ShieldAbility.xsd @@ -0,0 +1,18 @@ + + + + + + + + A shield component for one of the classes + + + + + This is the cooldown on shield + + + + + \ No newline at end of file diff --git a/resources/Schema/Components/SprintAbility.xml b/resources/Schema/Components/SprintAbility.xml new file mode 100644 index 00000000..2aac99d6 --- /dev/null +++ b/resources/Schema/Components/SprintAbility.xml @@ -0,0 +1,4 @@ + + + 2.0 + \ No newline at end of file diff --git a/resources/Schema/Components/SprintAbility.xsd b/resources/Schema/Components/SprintAbility.xsd new file mode 100644 index 00000000..4207dee2 --- /dev/null +++ b/resources/Schema/Components/SprintAbility.xsd @@ -0,0 +1,18 @@ + + + + + + + + A sprint component for one of the classes + + + + + This is the cooldown on sprint + + + + + \ No newline at end of file diff --git a/resources/Schema/Components/Text.xml b/resources/Schema/Components/Text.xml index d38d3961..cda29b86 100644 --- a/resources/Schema/Components/Text.xml +++ b/resources/Schema/Components/Text.xml @@ -1,7 +1,7 @@ - + Fonts/DroidSans.ttf,64 true
diff --git a/resources/Schema/Entities/BoostAssault.xml b/resources/Schema/Entities/BoostAssault.xml new file mode 100644 index 00000000..9c8e54fd --- /dev/null +++ b/resources/Schema/Entities/BoostAssault.xml @@ -0,0 +1,14 @@ + + + + + + + 10 + + + + + + + diff --git a/resources/Schema/Entities/BoostAssaultTest.xml b/resources/Schema/Entities/BoostAssaultTest.xml new file mode 100644 index 00000000..89dcd0d7 --- /dev/null +++ b/resources/Schema/Entities/BoostAssaultTest.xml @@ -0,0 +1,5311 @@ + + + + + + + + + + + + + + + + + + Models/Props/Ground.mesh + + + + + + + + + Models/Props/Highground1.mesh + + + + + + + + + + Models/Props/Highground2.mesh + + + + + + + + + + Models/Props/Highground1.mesh + + + + + + + + + + + + Models/Props/Highground2.mesh + + + + + + + + + + + + Models/Props/Highground3.mesh + + + + + + + + + + Models/Props/Highground4.mesh + + + + + + + + + + Models/Props/Highground5.mesh + + + + + + + + + + + Models/Props/Highground6.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallTop.mesh + + + + + + + + + Models/Props/Walls/SciFiWallBig.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallMedium.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallSmall1.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallSmall2.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallBig.mesh + + + + + + + + + + + + Models/Props/Walls/SciFiWallMedium.mesh + + + + + + + + + + + + Models/Props/Walls/SciFiWallSmall3.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallSmall4.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar1Blue.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar1Red.mesh + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar3Blue.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar1Blue.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar1Red.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar3Red.mesh + + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall4.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall4.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall4.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + Models/Props/Walls/SpecialWall1.mesh + + + + + + + + + + + + + + Models/Props/Flora/SpecialRoot.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall4.mesh + + + + + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SpecialWall1.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + Models/Props/Walls/SpecialWall1.mesh + + + + + + + + + + + + Models/Props/Walls/SpecialWall1.mesh + + + + + + + + + + + + + Models/Props/Walls/SpecialWall1.mesh + + + + + + + + + + + + + Models/Props/Walls/SpecialWall1.mesh + + + + + + + + + + + + + Models/Props/Walls/SpecialWall1.mesh + + + + + + + + + + + + + + Models/Props/Walls/SpecialWall1.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/Bridges/WoodenBridge.mesh + + + + + + + + + + + + + + Models/Props/Bridges/WoodenBridge.mesh + + + + + + + + + + + + + + Models/Props/Bridges/WoodenBridge.mesh + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Red.mesh + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Blue.mesh + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Blue.mesh + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Blue.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Red.mesh + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Red.mesh + + + + + + + + + + + + + Models/Props/Bridges/WoodenBridge.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Models/Core/UnitPlane.mesh + + true + + + + + + + + + + + + + Models/Core/UnitPlane.mesh + + true + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + + Models/Props/Flora/TreeLog.mesh + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + Models/Props/Flora/SpecialRoot.mesh + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + Models/Props/Flora/SpecialRoot.mesh + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + Models/Props/Flora/SpecialRoot.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointBlue.mesh + + + + + + + + + + + + + 4 + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointNeutral.mesh + + + + + + + + + + 3 + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointNeutral.mesh + + + + + + + + + + 2 + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointNeutral.mesh + + + + + + + + + + 1.5498908015879351 + 1 + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointRed.mesh + + + + + + + + + + + + + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + 10 + + + + + + + + + + 10 + + + + + + + + + + + + + 10 + + + + + + + + + + + 10 + + + + + + + + + + + 10 + + + + + + + + + + + 1 + + + + + + + + + + + + + + Schema/Entities/PlayerRed.xml + + + + + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/HealthPickUp.mesh + + + 0.10000000149011612 + + + + + + + + + + + + + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + 0.10000000149011612 + + + + + + + + + + + + + + + + Models/Props/PickUps/HealthPickUp.mesh + + + 0.10000000149011612 + + + + + + + + + + + + + + + + Models/Props/PickUps/HealthPickUp.mesh + + + 0.10000000149011612 + + + + + + + + + + + + + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + 0.10000000149011612 + + + + + + + + + + + + + + + + Models/Props/PickUps/HealthPickUp.mesh + + + 0.10000000149011612 + + + + + + + + + + + + + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + 0.10000000149011612 + + + + + + + + + + + + + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + 0.10000000149011612 + + + + + + + + + + + + + + + + diff --git a/resources/Schema/Entities/BoostDefender.xml b/resources/Schema/Entities/BoostDefender.xml new file mode 100644 index 00000000..f22b404e --- /dev/null +++ b/resources/Schema/Entities/BoostDefender.xml @@ -0,0 +1,14 @@ + + + + + + + 10 + + + + + + + diff --git a/resources/Schema/Entities/BoostSniper.xml b/resources/Schema/Entities/BoostSniper.xml new file mode 100644 index 00000000..a82a7a5d --- /dev/null +++ b/resources/Schema/Entities/BoostSniper.xml @@ -0,0 +1,14 @@ + + + + + + + 10 + + + + + + + diff --git a/resources/Schema/Entities/DashEffect.xml b/resources/Schema/Entities/DashEffect.xml new file mode 100644 index 00000000..9dfdc14c --- /dev/null +++ b/resources/Schema/Entities/DashEffect.xml @@ -0,0 +1,18 @@ + + + + + + + 0.5 + + + + 0 + 0.5 + + + + + + diff --git a/resources/Schema/Entities/NewMap.xml b/resources/Schema/Entities/NewMap.xml index 00dc476f..8fb8d9f4 100644 --- a/resources/Schema/Entities/NewMap.xml +++ b/resources/Schema/Entities/NewMap.xml @@ -5019,7 +5019,7 @@ - + @@ -5089,7 +5089,7 @@ - + @@ -5165,7 +5165,7 @@ - + @@ -5184,7 +5184,7 @@ - + @@ -5203,7 +5203,7 @@ - + @@ -5222,7 +5222,7 @@ - + @@ -5241,7 +5241,7 @@ - + @@ -5260,7 +5260,7 @@ - + @@ -5279,7 +5279,7 @@ - + @@ -5298,7 +5298,7 @@ - + diff --git a/resources/Schema/Entities/NewMap2version2.xml b/resources/Schema/Entities/NewMap2version2.xml new file mode 100644 index 00000000..8089073f --- /dev/null +++ b/resources/Schema/Entities/NewMap2version2.xml @@ -0,0 +1,4690 @@ + + + + + + + + + + + + + + + + + + Models/Props/GroundTest.mesh + + + + + + + + + Models/Props/Walls/SciFiWallTop.mesh + + + + + + + + + Models/Props/Walls/SciFiWallBig.mesh + true + + + + + + + + + + Models/Props/Walls/SciFiWallMedium.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallSmall1.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallSmall2.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallBig.mesh + + + + + + + + + + + + Models/Props/Walls/SciFiWallMedium.mesh + + + + + + + + + + + + Models/Props/Walls/SciFiWallSmall3.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallSmall4.mesh + + + + + + + + + + + + Models/Props/Highground1.mesh + + + + + + + + + + Models/Props/Highground2.mesh + + + + + + + + + + + Models/Props/Highground3.mesh + + + + + + + + + + + Models/Props/Highground4.mesh + + + + + + + + + + + Models/Props/Highground5.mesh + + + + + + + + + + Models/Props/Highground6.mesh + + + + + + + + + + + Models/Props/Highground7.mesh + + + + + + + + + + + + + Models/Props/Highground8.mesh + + + + + + + + + + + + + Models/Props/Highground9.mesh + + + + + + + + + + + + + Models/Props/Highground10.mesh + + + + + + + + + + + + + Models/Props/Highground6.mesh + + + + + + + + + + + + + Models/Props/Highground1.mesh + + + + + + + + + + + + Models/Props/Highground2.mesh + + + + + + + + + + + + + Models/Props/Highground3.mesh + + + + + + + + + + + + + Models/Props/Highground4.mesh + + + + + + + + + + + + + Models/Props/Highground5.mesh + + + + + + + + + + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar1Blue.mesh + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar1Red.mesh + + + + + + + + + + + + + 4 + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar3Blue.mesh + + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar1Blue.mesh + + + + + + + + + + + + + + 4 + Models/Props/Pillars/SciFiPillar1Red.mesh + + + + + + + + + + + + + + 4 + Models/Props/Pillars/SciFiPillar3Red.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + 4 + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + 5 + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + 4 + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 3 + + + + + + + + + + + + 2 + 1 + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + Models/Props/PickUps/HealthPickUp.mesh + + + 8 + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + Models/Props/PickUps/HealthPickUp.mesh + + + 8 + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + 8 + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + 8 + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + Models/Props/PickUps/HealthPickUp.mesh + + + 8 + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + Models/Props/PickUps/HealthPickUp.mesh + + + 8 + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + 8 + + + + + + + + + + + + + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Red.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Red.mesh + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Red.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Flora/SpecialRoot.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Core/UnitPlane.mesh + + true + + + + + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar1Red.mesh + + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + Models/Props/PickUps/HealthPickUp.mesh + + + 8 + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + 8 + + + + + + + + + + + + + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + 5 + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + 4 + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 3 + + + + + + + + + + + + 2 + 1 + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + Models/Props/PickUps/HealthPickUp.mesh + + + 8 + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + Models/Props/PickUps/HealthPickUp.mesh + + + 8 + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + 8 + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + 8 + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + Models/Props/PickUps/HealthPickUp.mesh + + + 8 + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + Models/Props/PickUps/HealthPickUp.mesh + + + 8 + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + 8 + + + + + + + + + + + + + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Blue.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Blue.mesh + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Blue.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Flora/SpecialRoot.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Core/UnitPlane.mesh + + true + + + + + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar1Blue.mesh + + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointBlue.mesh + + + + + + + + + + + + + 4 + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointNeutral.mesh + + + + + + + + + + 3 + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointNeutral.mesh + + + + + + + + + + 2 + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointNeutral.mesh + + + + + + + + + + 1 + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointRed.mesh + + + + + + + + + + + + + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + 10 + + + + + + + + + + + 10 + + + + + + + + + + + 10 + + + + + + + + + + + + 10 + + + + + + + + + + + 1 + false + + + + + + + + + + + + 10 + + + + + + + + + + + + + + Schema/Entities/PlayerRed.xml + + + + + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + diff --git a/resources/Schema/Entities/NewMap2version3NEW.xml b/resources/Schema/Entities/NewMap2version3NEW.xml new file mode 100644 index 00000000..61e7b740 --- /dev/null +++ b/resources/Schema/Entities/NewMap2version3NEW.xml @@ -0,0 +1,4691 @@ + + + + + + + + + + + + + + + + + + Models/Props/GroundTest.mesh + + + + + + + + + Models/Props/Walls/SciFiWallTop.mesh + + + + + + + + + Models/Props/Walls/SciFiWallBig.mesh + true + + + + + + + + + + Models/Props/Walls/SciFiWallMedium.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallSmall1.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallSmall2.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallBig.mesh + + + + + + + + + + + + Models/Props/Walls/SciFiWallMedium.mesh + + + + + + + + + + + + Models/Props/Walls/SciFiWallSmall3.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallSmall4.mesh + + + + + + + + + + + + Models/Props/Highground1.mesh + + + + + + + + + + Models/Props/Highground2.mesh + + + + + + + + + + + Models/Props/Highground3.mesh + + + + + + + + + + + Models/Props/Highground4.mesh + + + + + + + + + + + Models/Props/Highground5.mesh + + + + + + + + + + Models/Props/Highground6.mesh + + + + + + + + + + + Models/Props/Highground7.mesh + + + + + + + + + + + + + Models/Props/Highground8.mesh + + + + + + + + + + + + + Models/Props/Highground9.mesh + + + + + + + + + + + + + Models/Props/Highground10.mesh + + + + + + + + + + + + + Models/Props/Highground6.mesh + + + + + + + + + + + + + Models/Props/Highground1.mesh + + + + + + + + + + + + Models/Props/Highground2.mesh + + + + + + + + + + + + + Models/Props/Highground3.mesh + + + + + + + + + + + + + Models/Props/Highground4.mesh + + + + + + + + + + + + + Models/Props/Highground5.mesh + + + + + + + + + + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar1Blue.mesh + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar1Red.mesh + + + + + + + + + + + + + 4 + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar3Blue.mesh + + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar1Blue.mesh + + + + + + + + + + + + + + 4 + Models/Props/Pillars/SciFiPillar1Red.mesh + + + + + + + + + + + + + + 4 + Models/Props/Pillars/SciFiPillar3Red.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + 4 + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + 5 + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + 4 + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 3 + + + + + + + + + + + + 2 + 1 + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 8 + + + + Models/Props/PickUps/HealthPickUp.mesh + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 8 + + + + Models/Props/PickUps/HealthPickUp.mesh + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 8 + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 8 + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 8 + + + + Models/Props/PickUps/HealthPickUp.mesh + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 8 + + + + Models/Props/PickUps/HealthPickUp.mesh + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 8 + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + + + + + + + + + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Red.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Red.mesh + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Red.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Flora/SpecialRoot.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Core/UnitPlane.mesh + + true + + + + + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar1Red.mesh + + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 8 + + + + Models/Props/PickUps/HealthPickUp.mesh + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 8 + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + + + + + + + + + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + 5 + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + 4 + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 3 + + + + + + + + + + + + 2 + 1 + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + 6 + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 8 + + + + Models/Props/PickUps/HealthPickUp.mesh + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 8 + + + + Models/Props/PickUps/HealthPickUp.mesh + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 8 + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 8 + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 8 + + + + Models/Props/PickUps/HealthPickUp.mesh + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 8 + + + + Models/Props/PickUps/HealthPickUp.mesh + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + 2 + + + + + + + + + + + + 8 + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + + + + + + + + + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Blue.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Blue.mesh + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Blue.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Flora/SpecialRoot.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Core/UnitPlane.mesh + + true + + + + + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + + + + + + + + + 6 + Models/Props/Pillars/SciFiPillar1Blue.mesh + + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointBlue.mesh + + + + + + + + + + + + + -15 + 4 + + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointNeutral.mesh + + + + + + + + + + 3 + + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointNeutral.mesh + + + + + + + + + + 2 + + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointNeutral.mesh + + + + + + + + + + 1 + + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointRed.mesh + + + + + + + + + + + + + 15 + + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + 10 + + + + + + + + + + + 10 + + + + + + + + + + + 10 + + + + + + + + + + + + 10 + + + + + + + + + + + 0.40000000596046448 + + + + + + + + + + + + 10 + + + + + + + + + + + + + + Schema/Entities/PlayerRed.xml + + + + + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + diff --git a/resources/Schema/Entities/NewMapWSpectatorCam.xml b/resources/Schema/Entities/NewMapWSpectatorCam.xml new file mode 100644 index 00000000..bf1b4c2b --- /dev/null +++ b/resources/Schema/Entities/NewMapWSpectatorCam.xml @@ -0,0 +1,5532 @@ + + + + + + 0.0 + 15 + + + + + + + + + + + + + + + Models/Props/Ground.mesh + + + + + + + + + Models/Props/Highground1.mesh + + + + + + + + + + Models/Props/Highground2.mesh + + + + + + + + + + Models/Props/Highground1.mesh + + + + + + + + + + + + Models/Props/Highground2.mesh + + + + + + + + + + + + Models/Props/Highground3.mesh + + + + + + + + + + Models/Props/Highground4.mesh + + + + + + + + + + Models/Props/Highground5.mesh + + + + + + + + + + + Models/Props/Highground6.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallTop.mesh + + + + + + + + + Models/Props/Walls/SciFiWallBig.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallMedium.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallSmall1.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallSmall2.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallBig.mesh + + + + + + + + + + + + Models/Props/Walls/SciFiWallMedium.mesh + + + + + + + + + + + + Models/Props/Walls/SciFiWallSmall3.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallSmall4.mesh + + + + + + + + + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar1Blue.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar1Red.mesh + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar3Blue.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar1Blue.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar1Red.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar3Red.mesh + + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Blue.mesh + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2Red.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall4.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall4.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall4.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallBlue.mesh + + + + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + Models/Props/Walls/BigWallRed.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + Models/Props/Walls/SpecialWall1.mesh + + + + + + + + + + + + + + Models/Props/Flora/SpecialRoot.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall4.mesh + + + + + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SpecialWall1.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + Models/Props/Walls/SpecialWall1.mesh + + + + + + + + + + + + Models/Props/Walls/SpecialWall1.mesh + + + + + + + + + + + + + Models/Props/Walls/SpecialWall1.mesh + + + + + + + + + + + + + Models/Props/Walls/SpecialWall1.mesh + + + + + + + + + + + + + Models/Props/Walls/SpecialWall1.mesh + + + + + + + + + + + + + + Models/Props/Walls/SpecialWall1.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/Bridges/WoodenBridge.mesh + + + + + + + + + + + + + + Models/Props/Bridges/WoodenBridge.mesh + + + + + + + + + + + + + + Models/Props/Bridges/WoodenBridge.mesh + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Red.mesh + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Blue.mesh + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Blue.mesh + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Blue.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Red.mesh + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge1Red.mesh + + + + + + + + + + + + + Models/Props/Bridges/WoodenBridge.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Models/Core/UnitPlane.mesh + + true + + + + + + + + + + + + + Models/Core/UnitPlane.mesh + + true + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + + Models/Props/Flora/TreeLog.mesh + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + Models/Props/Flora/SpecialRoot.mesh + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + Models/Props/Flora/SpecialRoot.mesh + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + Models/Props/Flora/SpecialRoot.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone1.mesh + + + + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/SmallStone2.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone2.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalBlue.mesh + + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystalRed.mesh + + + + + + + + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointBlue.mesh + + + + + + + + + + + + + 4 + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointNeutral.mesh + + + + + + + + + + 3 + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointNeutral.mesh + + + + + + + + + + 2 + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointNeutral.mesh + + + + + + + + + + 1.5498908015879351 + 1 + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + + Models/Props/CapturePoint/CapturePointRed.mesh + + + + + + + + + + + + + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + 10 + + + + + + + + + + 10 + + + + + + + + + + + + + 10 + + + + + + + + + + + 10 + + + + + + + + + + + 10 + + + + + + + + + + + 1 + + + + + + + + + + + + + + Schema/Entities/PlayerRed.xml + + + + + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + false + + + + + + + + + + + + + + + + + + + 0.10000000149011612 + + + + Models/Props/PickUps/HealthPickUp.mesh + + + + + + + + + + + + + + + 0.10000000149011612 + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + + + + + + + + + + + + + 0.10000000149011612 + + + + Models/Props/PickUps/HealthPickUp.mesh + + + + + + + + + + + + + + + 0.10000000149011612 + + + + Models/Props/PickUps/HealthPickUp.mesh + + + + + + + + + + + + + + + 0.10000000149011612 + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + + + + + + + + + + + + + 0.10000000149011612 + + + + Models/Props/PickUps/HealthPickUp.mesh + + + + + + + + + + + + + + + 0.10000000149011612 + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + + + + + + + + + + + + + 0.10000000149011612 + + + + Models/Props/PickUps/AmmoPickUp.mesh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + 2 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + 3 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + 4 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + 1 + + + 0.59265931447347009 + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 7976fe2b..34692605 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -13,8 +13,9 @@ - 1.6944730461160304 + 52.867678870419283 + @@ -36,7 +37,10 @@ - + + 0.10000000149011612 + 300 + @@ -96,12 +100,12 @@ 1 - 100/100 Fonts/DroidSans.ttf,64 + @@ -128,7 +132,70 @@ - + + + + + + + + + + + + + + Textures/Core/White.png + false + + + + + + + + + + + + + + + + + Textures/Core/White.png + false + + + + + + + + + + + + + + + + + Textures/Core/White.png + false + + + + + + + + + + + + + @@ -192,7 +259,6 @@ 3 - 0.80222018197612788 @@ -227,6 +293,7 @@ 4 + 1 @@ -282,7 +349,7 @@ Textures/Core/UnitHexagon.png - + @@ -293,7 +360,8 @@ - + 1 + Textures/Core/UnitHexagon_Rotated.png @@ -302,7 +370,7 @@ - + @@ -365,13 +433,32 @@ + + + + + Models/Widgets/Arrows/Arrow5.mesh + + + + + + + + + + + + + + Idle - 0.67172915251515519 + 1.9408570429715581 1 @@ -385,25 +472,25 @@ + + DefenderWeapon + Schema/Entities/DefenderWeaponView.xml - - DefenderWeapon - + + AssaultWeapon + Schema/Entities/AssaultWeaponView.xml - - AssaultWeapon - @@ -413,7 +500,10 @@ - + + 0.10000000149011612 + 300 + Models/Widgets/Camera.mesh false @@ -429,6 +519,7 @@ Idle + 1.5631122524686134 1 @@ -448,31 +539,31 @@ - - Schema/Entities/DefenderWeaponWorld.xml - - DefenderWeapon + + Schema/Entities/DefenderWeaponWorld.xml + + - - Schema/Entities/AssaultWeaponWorld.xml - - AssaultWeapon + + Schema/Entities/AssaultWeaponWorld.xml + + diff --git a/resources/Schema/Entities/PlayerRed.xml b/resources/Schema/Entities/PlayerRed.xml old mode 100755 new mode 100644 index 69116f21..c46b9d79 --- a/resources/Schema/Entities/PlayerRed.xml +++ b/resources/Schema/Entities/PlayerRed.xml @@ -13,8 +13,9 @@ - 1.6944730461160304 + 22.22055262342397 + @@ -36,7 +37,10 @@ - + + 0.10000000149011612 + 300 + @@ -371,7 +375,7 @@ Idle - 0.67172915251515519 + 1.1978087298230946 1 @@ -385,25 +389,25 @@ + + DefenderWeapon + Schema/Entities/DefenderWeaponViewRed.xml - - DefenderWeapon - + + AssaultWeapon + Schema/Entities/AssaultWeaponView.xml - - AssaultWeapon - @@ -413,7 +417,10 @@ - + + 0.10000000149011612 + 300 + Models/Widgets/Camera.mesh false @@ -429,6 +436,7 @@ Idle + 0.69274608502888668 1 @@ -448,31 +456,31 @@ - - Schema/Entities/DefenderWeaponWorldRed.xml - - DefenderWeapon + + Schema/Entities/DefenderWeaponWorldRed.xml + + - - Schema/Entities/AssaultWeaponWorld.xml - - AssaultWeapon + + Schema/Entities/AssaultWeaponWorld.xml + + diff --git a/resources/Schema/Entities/QualityAssurance.xml b/resources/Schema/Entities/QualityAssurance.xml index 0aa2fbe7..04cc288a 100644 --- a/resources/Schema/Entities/QualityAssurance.xml +++ b/resources/Schema/Entities/QualityAssurance.xml @@ -2,6 +2,9 @@ + + 4.7473226580121377 + @@ -40,7 +43,7 @@ - + @@ -81,19 +84,19 @@ + + 1 + + 0.80000001192092896 Models/Widgets/Lights/DirectionalLightWidget.mesh - - 1 - - - + @@ -108,7 +111,11 @@ - + + + + + Models/Characters/Assault/AssaultAnimated.mesh @@ -120,7 +127,11 @@ - + + + + + Models/Characters/Assault/AssaultAnimated.mesh @@ -168,13 +179,17 @@ - + - + + + + + Models/Characters/Assault/AssaultAnimated.mesh @@ -213,7 +228,7 @@ - + @@ -277,7 +292,7 @@ - + @@ -309,7 +324,7 @@ - + @@ -659,7 +674,7 @@ - + @@ -706,7 +721,7 @@ - + @@ -766,7 +781,7 @@ - + @@ -813,7 +828,7 @@ - + @@ -859,7 +874,7 @@ - + @@ -906,7 +921,7 @@ - + @@ -953,7 +968,7 @@ - + @@ -1013,6 +1028,7 @@ 15 + Models/Core/UnitCube.mesh @@ -1027,7 +1043,6 @@ - @@ -1063,6 +1078,7 @@ 1 + Models/Core/UnitCube.mesh @@ -1073,7 +1089,6 @@ - @@ -1107,6 +1122,7 @@ 2 + Models/Core/UnitCube.mesh @@ -1117,7 +1133,6 @@ - @@ -1153,6 +1168,7 @@ 3 + Models/Core/UnitCube.mesh @@ -1163,7 +1179,6 @@ - @@ -1203,6 +1218,7 @@ -15 4 + Models/Core/UnitCube.mesh @@ -1217,7 +1233,6 @@ - @@ -1367,7 +1382,7 @@ - + @@ -1376,7 +1391,7 @@ true - 0.8256214817261025 + 2.5396116058983438 3.7999999523162842 true @@ -1423,7 +1438,7 @@ - + @@ -1432,7 +1447,7 @@ - 1.8641349174045843 + 1.5396208215609732 Models/Characters/Assault/AssaultTPose.mesh @@ -1475,18 +1490,22 @@ - + - + + + + + true - 1.8641349174045843 + 1.5396208215609732 true @@ -1531,7 +1550,7 @@ - + @@ -1541,7 +1560,7 @@ true - 1.2301962937648341 + 4.4522528839264339 10 3 @@ -1589,7 +1608,7 @@ - + @@ -1599,7 +1618,7 @@ true - 3.4214855659573402 + 3.2362842141074992 true 5 true @@ -1690,6 +1709,7 @@ 5 + @@ -1712,6 +1732,7 @@ + Fonts/DroidSans.ttf,100 @@ -1780,7 +1801,7 @@ true - 0.8256214817261025 + 2.5396116058983438 3.7999999523162842 true @@ -1823,7 +1844,11 @@ - + + + + + @@ -1925,6 +1950,7 @@ Textures/Props/FoliageDiff.png + @@ -1934,6 +1960,7 @@ Textures/Props/FoliageDiff.png + @@ -1954,6 +1981,7 @@ Textures/Core/UnitHexagon.png + @@ -1971,6 +1999,7 @@ Textures/Core/UnitHexagon_Rotated.png + @@ -1986,6 +2015,7 @@ Textures/Core/UnitHexagon.png + @@ -2003,6 +2033,7 @@ Textures/Core/UnitHexagon_Rotated.png + @@ -2018,6 +2049,7 @@ Textures/Core/UnitHexagon.png + @@ -2036,6 +2068,7 @@ Textures/Core/UnitHexagon_Rotated.png + @@ -2051,6 +2084,7 @@ Textures/Core/UnitHexagon.png + @@ -2068,6 +2102,7 @@ Textures/Core/UnitHexagon_Rotated.png + @@ -2083,6 +2118,7 @@ Textures/Core/UnitHexagon.png + @@ -2099,6 +2135,7 @@ Textures/Core/UnitHexagon_Rotated.png + @@ -2167,6 +2204,7 @@ Textures/Core/ErrorTexture.png + @@ -2178,6 +2216,7 @@ Textures/Core/White.png + @@ -2206,6 +2245,7 @@ Textures/Core/White.png + @@ -2234,6 +2274,7 @@ Textures/Core/White.png + @@ -2262,6 +2303,7 @@ Textures/Core/White.png + @@ -2290,6 +2332,7 @@ Textures/Core/White.png + @@ -2331,6 +2374,7 @@ Textures/Core/ErrorTexture.png + @@ -2342,6 +2386,7 @@ Textures/Core/White.png + @@ -2370,6 +2415,7 @@ Textures/Core/White.png + @@ -2398,6 +2444,7 @@ Textures/Core/White.png + @@ -2426,6 +2473,7 @@ Textures/Core/White.png + @@ -2482,6 +2530,36 @@ + + + + + + + + + + + + 2 + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + + + + + + + + + + + + + + + diff --git a/resources/Schema/Entities/SpectatorCamera.xml b/resources/Schema/Entities/SpectatorCamera.xml new file mode 100644 index 00000000..5c3dc514 --- /dev/null +++ b/resources/Schema/Entities/SpectatorCamera.xml @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + Time to respawn: 0 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + 2 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + 3 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + 4 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + 1 + + + 0.59265931447347009 + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + + + + + diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index 0965ef89..1d8ea8f3 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -51,7 +51,17 @@ + + + + + + + + + + diff --git a/resources/Shaders/DrawColorCorrection.frag.glsl b/resources/Shaders/DrawColorCorrection.frag.glsl index bae50887..d8273547 100644 --- a/resources/Shaders/DrawColorCorrection.frag.glsl +++ b/resources/Shaders/DrawColorCorrection.frag.glsl @@ -2,8 +2,6 @@ layout (binding = 0) uniform sampler2D SceneTexture; layout (binding = 1) uniform sampler2D BloomTexture; -layout (binding = 2) uniform sampler2D SceneTextureLowRes; -layout (binding = 3) uniform sampler2D BloomTextureLowRes; uniform float Exposure; uniform float Gamma; @@ -17,21 +15,12 @@ void main() { vec4 hdrColor = texture(SceneTexture, Input.TextureCoordinate); vec4 bloomColor = texture(BloomTexture, Input.TextureCoordinate); - vec4 hdrColorLowRes = texture(SceneTextureLowRes, Input.TextureCoordinate); - vec4 bloomColorLowRes = texture(BloomTextureLowRes, Input.TextureCoordinate); //hdrColor = hdrColor * SSAO; hdrColor += bloomColor; - hdrColorLowRes; - float hdrColorsum = hdrColorLowRes.r + hdrColorLowRes.g + hdrColorLowRes.b; //Toon mapping thingy - vec3 result; - if(hdrColorsum > 0.0) { - result = vec3(1.0) - exp(-hdrColorLowRes.rgb * Exposure); - } else { - result = vec3(1.0) - exp(-hdrColor.rgb * Exposure); - } + vec3 result = vec3(1.0) - exp(-hdrColor.rgb * Exposure); //gamme correction result = pow(result, vec3(1.0 / Gamma)); diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index 6fbc9c27..aa45d118 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -13,6 +13,7 @@ uniform vec4 AmbientColor; uniform float FillPercentage; uniform float GlowIntensity = 10; uniform vec3 CameraPosition; +uniform int SSAOQuality; uniform vec2 DiffuseUVRepeat; uniform vec2 NormalUVRepeat; @@ -125,7 +126,7 @@ vec4 CalcNormalMappedValue(vec3 normal, vec3 tangent, vec3 bitangent, vec2 textu void main() { - float ao = texelFetch(AOTexture, ivec2(gl_FragCoord.xy), 0).r; + float ao = texelFetch(AOTexture, ivec2(gl_FragCoord.xy) >> int(SSAOQuality), 0).r; ao = (clamp(1.0 - (1.0 - ao), 0.0, 1.0) + MIN_AMBIENT_LIGHT) / (1.0 + MIN_AMBIENT_LIGHT); vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate * DiffuseUVRepeat); vec4 glowTexel = texture2D(GlowMapTexture, Input.TextureCoordinate * GlowUVRepeat); @@ -170,7 +171,8 @@ void main() vec4 color_result = mix((Color * diffuseTexel * DiffuseColor), Input.ExplosionColor, Input.ExplosionPercentageElapsed); color_result = color_result * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)); float specularResult = (specularTexel.r + specularTexel.g + specularTexel.b)/3.0; - color_result = color_result * clamp(1/specularTexel, 0, 1)*2 + reflectionColor * clamp(specularTexel, 0, 1)/2; + vec4 reflectionTotal = reflectionColor * (1-specularTexel.a) * color_result.a; + color_result = color_result * clamp(1/specularTexel.a, 0, 1) + reflectionTotal; //vec4 color_result = (DiffuseColor + Input.ExplosionColor) * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)) * diffuseTexel * Color; @@ -181,9 +183,9 @@ void main() } sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1)); //sceneColor = vec4(reflectionColor.xyz, 1); - color_result += glowTexel*GlowIntensity; + color_result.xyz += glowTexel.xyz*GlowIntensity; - bloomColor = vec4(clamp(color_result.xyz - 1.0, 0, 100), clamp(color_result.a, 0, 1)); + bloomColor = vec4(max(color_result.xyz - 1.0, 0.0), clamp(color_result.a, 0, 1)); //Tiled Debug Code /* diff --git a/resources/Shaders/ForwardPlusShieldCheck.frag.glsl b/resources/Shaders/ForwardPlusShieldCheck.frag.glsl new file mode 100644 index 00000000..35db495b --- /dev/null +++ b/resources/Shaders/ForwardPlusShieldCheck.frag.glsl @@ -0,0 +1,207 @@ +#version 430 + +#define MIN_AMBIENT_LIGHT 0.3 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; +uniform vec4 Color; +uniform vec4 DiffuseColor; +uniform vec2 ScreenDimensions; +uniform vec4 FillColor; +uniform vec4 AmbientColor; +uniform float FillPercentage; +uniform float GlowIntensity = 10; +uniform vec3 CameraPosition; +uniform int SSAOQuality; + +uniform vec2 DiffuseUVRepeat; +uniform vec2 NormalUVRepeat; +uniform vec2 SpecularUVRepeat; +uniform vec2 GlowUVRepeat; +layout (binding = 0) uniform sampler2D AOTexture; +layout (binding = 1) uniform sampler2D DiffuseTexture; +layout (binding = 2) uniform sampler2D NormalMapTexture; +layout (binding = 3) uniform sampler2D SpecularMapTexture; +layout (binding = 4) uniform sampler2D GlowMapTexture; +layout (binding = 5) uniform samplerCube CubeMap; +layout (binding = 31) uniform sampler2D ShieldBuffer; + +#define TILE_SIZE 16 + +struct LightSource { + vec4 Position; + vec4 Direction; + vec4 Color; + float Radius; + float Intensity; + float Falloff; + int Type; +}; + +layout (std430, binding = 1) buffer LightBuffer +{ + LightSource List[]; +} LightSources; + +struct LightGrid { + float Start; + float Amount; + vec2 Padding; +}; + +layout (std430, binding = 2) buffer LightGridBuffer +{ + LightGrid Data[]; +} LightGrids; + +layout (std430, binding = 4) buffer LightIndexBuffer +{ + float LightIndex[]; +}; + + +in VertexData{ + vec3 Position; + vec3 Normal; + vec3 Tangent; + vec3 BiTangent; + vec2 TextureCoordinate; + vec4 ExplosionColor; + float ExplosionPercentageElapsed; +}Input; + +out vec4 sceneColor; +out vec4 bloomColor; + +struct LightResult { + vec4 Diffuse; + vec4 Specular; +}; + +float CalcAttenuation(float radius, float dist, float falloff) { + return 1.0 - smoothstep(radius * falloff, radius, dist); +} + +vec4 CalcSpecular(vec4 lightColor, vec4 viewVec, vec4 lightVec, vec4 normal) { + vec4 R = normalize( reflect(-lightVec, normal)); + float RdotV = max( dot(R, viewVec), 0.0); + return lightColor * pow(RdotV, 90.0); +} + +vec4 CalcDiffuse(vec4 lightColor, vec4 lightVec, vec4 normal) { + float power = max( dot(normal, lightVec), 0.0); + return lightColor * power; +} + +LightResult CalcPointLightSource(vec4 lightPos, float lightRadius, vec4 lightColor, float intensity, vec4 viewVec, vec4 position, vec4 normal, float falloff) +{ + vec4 L = lightPos - position; + float dist = length(L); + L = normalize(L); + + float attenuation = CalcAttenuation(lightRadius, dist, falloff); + + LightResult result; + result.Diffuse = CalcDiffuse(lightColor, L, normal) * attenuation * intensity; + result.Specular = CalcSpecular(lightColor, viewVec, L, normal) * attenuation * intensity; + return result; +} + +LightResult CalcDirectionalLightSource(vec4 direction, vec4 color, float intensity, vec4 viewVec, vec4 vertNormal) +{ + vec4 L = normalize( -vec4(direction.xyz, 0) ); + + LightResult result; + result.Diffuse = CalcDiffuse(color, L, vertNormal) * intensity; + result.Specular = CalcSpecular(color, viewVec, L, vertNormal) * intensity; + return result; +} + +vec4 CalcNormalMappedValue(vec3 normal, vec3 tangent, vec3 bitangent, vec2 textureCoordinate, sampler2D normalMap) +{ + mat3 TBN = mat3(tangent, bitangent, normal); + vec3 NormalMap = texture(normalMap, textureCoordinate).xyz * 2.0 - vec3(1.0); + return vec4(TBN * normalize(NormalMap), 0.0); +} + +void main() +{ + float shieldDepthValue = texelFetch(ShieldBuffer, ivec2(gl_FragCoord.xy), 0).r; + + if(shieldDepthValue < gl_FragCoord.z){ + discard; + } + + float ao = texelFetch(AOTexture, ivec2(gl_FragCoord.xy) >> int(SSAOQuality), 0).r; + ao = (clamp(1.0 - (1.0 - ao), 0.0, 1.0) + MIN_AMBIENT_LIGHT) / (1.0 + MIN_AMBIENT_LIGHT); + vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate * DiffuseUVRepeat); + vec4 glowTexel = texture2D(GlowMapTexture, Input.TextureCoordinate * GlowUVRepeat); + vec4 specularTexel = texture2D(SpecularMapTexture, Input.TextureCoordinate * SpecularUVRepeat); + vec4 position = V * M * vec4(Input.Position, 1.0); + vec4 normal = V * CalcNormalMappedValue(Input.Normal, Input.Tangent, Input.BiTangent, Input.TextureCoordinate * NormalUVRepeat, NormalMapTexture); + normal = normalize(normal); + //vec4 normal = normalize(V * vec4(Input.Normal, 0.0)); + vec4 viewVec = normalize(-position); + vec3 I = normalize(vec3(M * vec4(Input.Position, 1.0)) - CameraPosition); + vec3 R = reflect(-I, Input.Normal); + //R = vec3(P * vec4(R, 1.0)); + vec4 reflectionColor = texture(CubeMap, R); + + vec2 tilePos; + tilePos.x = int(gl_FragCoord.x/TILE_SIZE); + tilePos.y = int(gl_FragCoord.y/TILE_SIZE); + + LightResult totalLighting; + totalLighting.Diffuse = vec4(AmbientColor.rgb * ao, 1.0); + int currentTile = int(floor(gl_FragCoord.x/TILE_SIZE) + (floor(gl_FragCoord.y/TILE_SIZE) * int(ScreenDimensions.x/TILE_SIZE))); + + int start = int(LightGrids.Data[currentTile].Start); + int amount = int(LightGrids.Data[currentTile].Amount); + + for(int i = start; i < start + amount; i++) { + + int l = int(LightIndex[i]); + LightSource light = LightSources.List[l]; + + LightResult light_result; + //These if statements should be removed. + if(light.Type == 1) { // point + light_result = CalcPointLightSource(V * light.Position, light.Radius, light.Color, light.Intensity, viewVec, position, normal, light.Falloff); + } else if (light.Type == 2) { //Directional + light_result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal); + } + totalLighting.Diffuse += vec4(light_result.Diffuse.rgb * ao, light_result.Diffuse.a); + totalLighting.Specular += vec4(light_result.Specular.rgb * ao, light_result.Specular.a); + } + + vec4 color_result = mix((Color * diffuseTexel * DiffuseColor), Input.ExplosionColor, Input.ExplosionPercentageElapsed); + color_result = color_result * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)); + float specularResult = (specularTexel.r + specularTexel.g + specularTexel.b)/3.0; + vec4 reflectionTotal = reflectionColor * (1-specularTexel.a) * color_result.a; + color_result = color_result * clamp(1/specularTexel.a, 0, 1) + reflectionTotal; + //vec4 color_result = (DiffuseColor + Input.ExplosionColor) * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)) * diffuseTexel * Color; + + + float pos = ((P * vec4(Input.Position, 1)).y + 1.0)/2.0; + + if(pos <= FillPercentage) { + color_result += FillColor; + } + sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1)); + //sceneColor = vec4(reflectionColor.xyz, 1); + color_result.xyz += glowTexel.xyz*GlowIntensity; + + bloomColor = vec4(max(color_result.xyz - 1.0, 0.0), clamp(color_result.a, 0, 1)); + + //Tiled Debug Code + /* + if(int(gl_FragCoord.x)%16 == 0 || int(gl_FragCoord.y)%16 == 0 ) { + sceneColor += vec4(0.5, 0, 0, 0); + } else { + sceneColor += vec4(LightGrids.Data[int(tilePos.x + tilePos.y*80)].Amount/LightSources.List.length(), 0, 0, 1); + } + */ +} + + diff --git a/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl b/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl index cf358b96..c67a9c99 100644 --- a/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl +++ b/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl @@ -11,6 +11,7 @@ uniform vec4 DiffuseColor; uniform vec4 FillColor; uniform vec4 Color; uniform vec4 AmbientColor; +uniform int SSAOQuality; //Get bineded at the same time as the textures uniform vec2 DiffuseUVRepeat1; @@ -177,7 +178,7 @@ vec4 CalcBlendedNormal(vec4 blendValue, sampler2D R, sampler2D G, sampler2D B, void main() { - float ao = texelFetch(AOTexture, ivec2(gl_FragCoord.xy), 0).r; + float ao = texelFetch(AOTexture, ivec2(gl_FragCoord.xy) >> int(SSAOQuality), 0).r; ao = (clamp(1.0 - (1.0 - ao), 0.0, 1.0) + MIN_AMBIENT_LIGHT) / (1.0 + MIN_AMBIENT_LIGHT); vec4 splatTexel = texture2D(SplatMapTexture, Input.TextureCoordinate); diff --git a/resources/Shaders/ForwardPlusSplatMapRGBShieldCheck.frag.glsl b/resources/Shaders/ForwardPlusSplatMapRGBShieldCheck.frag.glsl new file mode 100644 index 00000000..d61726fe --- /dev/null +++ b/resources/Shaders/ForwardPlusSplatMapRGBShieldCheck.frag.glsl @@ -0,0 +1,253 @@ +#version 430 + +#define MIN_AMBIENT_LIGHT 0.3 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; +uniform vec2 ScreenDimensions; +uniform float FillPercentage; +uniform vec4 DiffuseColor; +uniform vec4 FillColor; +uniform vec4 Color; +uniform vec4 AmbientColor; +uniform int SSAOQuality; + +//Get bineded at the same time as the textures +uniform vec2 DiffuseUVRepeat1; +uniform vec2 DiffuseUVRepeat2; +uniform vec2 DiffuseUVRepeat3; +uniform vec2 NormalUVRepeat1; +uniform vec2 NormalUVRepeat2; +uniform vec2 NormalUVRepeat3; +uniform vec2 SpecularUVRepeat1; +uniform vec2 SpecularUVRepeat2; +uniform vec2 SpecularUVRepeat3; +uniform vec2 GlowUVRepeat1; +uniform vec2 GlowUVRepeat2; +uniform vec2 GlowUVRepeat3; +layout (binding = 0) uniform sampler2D AOTexture; +layout (binding = 1) uniform sampler2D SplatMapTexture; +layout (binding = 2) uniform sampler2D DiffuseTexture1; +layout (binding = 3) uniform sampler2D DiffuseTexture2; +layout (binding = 4) uniform sampler2D DiffuseTexture3; +layout (binding = 5) uniform sampler2D NormalMapTexture1; +layout (binding = 6) uniform sampler2D NormalMapTexture2; +layout (binding = 7) uniform sampler2D NormalMapTexture3; +layout (binding = 8) uniform sampler2D SpecularMapTexture1; +layout (binding = 9) uniform sampler2D SpecularMapTexture2; +layout (binding = 10) uniform sampler2D SpecularMapTexture3; +layout (binding = 11) uniform sampler2D GlowMapTexture1; +layout (binding = 12) uniform sampler2D GlowMapTexture2; +layout (binding = 13) uniform sampler2D GlowMapTexture3; +layout (binding = 31) uniform samplerCube ShieldBuffer; + +#define TILE_SIZE 16 + +struct LightSource { + vec4 Position; + vec4 Direction; + vec4 Color; + float Radius; + float Intensity; + float Falloff; + int Type; +}; + +layout (std430, binding = 1) buffer LightBuffer +{ + LightSource List[]; +} LightSources; + +struct LightGrid { + float Start; + float Amount; + vec2 Padding; +}; + +layout (std430, binding = 2) buffer LightGridBuffer +{ + LightGrid Data[]; +} LightGrids; + +layout (std430, binding = 4) buffer LightIndexBuffer +{ + float LightIndex[]; +}; + + +in VertexData{ + vec3 Position; + vec3 Normal; + vec3 Tangent; + vec3 BiTangent; + vec2 TextureCoordinate; + vec4 ExplosionColor; + float ExplosionPercentageElapsed; +}Input; + +out vec4 sceneColor; +out vec4 bloomColor; + +struct LightResult { + vec4 Diffuse; + vec4 Specular; +}; + +float CalcAttenuation(float radius, float dist, float falloff) { + return 1.0 - smoothstep(radius * 0.3, radius, dist); +} + +vec4 CalcSpecular(vec4 lightColor, vec4 viewVec, vec4 lightVec, vec4 normal) { + vec4 R = normalize( reflect(-lightVec, normal)); + float RdotV = max( dot(R, viewVec), 0.0); + return lightColor * pow(RdotV, 90.0); +} + +vec4 CalcDiffuse(vec4 lightColor, vec4 lightVec, vec4 normal) { + float power = max( dot(normal, lightVec), 0.0); + return lightColor * power; +} + +LightResult CalcPointLightSource(vec4 lightPos, float lightRadius, vec4 lightColor, float intensity, vec4 viewVec, vec4 position, vec4 normal, float falloff) +{ + vec4 L = lightPos - position; + float dist = length(L); + L = normalize(L); + + float attenuation = CalcAttenuation(lightRadius, dist, falloff); + + LightResult result; + result.Diffuse = CalcDiffuse(lightColor, L, normal) * attenuation * intensity; + result.Specular = CalcSpecular(lightColor, viewVec, L, normal) * attenuation * intensity; + return result; +} + +LightResult CalcDirectionalLightSource(vec4 direction, vec4 color, float intensity, vec4 viewVec, vec4 vertNormal) +{ + vec4 L = normalize( -vec4(direction.xyz, 0) ); + + LightResult result; + result.Diffuse = CalcDiffuse(color, L, vertNormal) * intensity; + result.Specular = CalcSpecular(color, viewVec, L, vertNormal) * intensity; + return result; +} + +vec4 CalcNormalMappedValue(vec3 normal, vec3 tangent, vec3 bitangent, vec2 textureCoordinate, sampler2D normalMap) +{ + mat3 TBN = mat3(tangent, bitangent, normal); + vec3 NormalMap = texture(normalMap, textureCoordinate).xyz * 2.0 - vec3(1.0); + return vec4(TBN * normalize(NormalMap), 0.0); +} + +vec4 CalcBlendedTexel(vec4 blendValue, sampler2D R, sampler2D G, sampler2D B, + vec2 R_TileValues, vec2 G_TileValues, vec2 B_TileValues){ + vec4 R_Channel = texture2D(R, Input.TextureCoordinate * R_TileValues); + vec4 G_Channel = texture2D(G, Input.TextureCoordinate * G_TileValues); + vec4 B_Channel = texture2D(B, Input.TextureCoordinate * B_TileValues); + + float total = blendValue.r + blendValue.g + blendValue.b; + float totalDiv = 1.0f / total; + blendValue.r = blendValue.r * totalDiv; + blendValue.g = blendValue.g * totalDiv; + blendValue.b = blendValue.b * totalDiv; + + return blendValue.r * R_Channel + + blendValue.g * G_Channel + + blendValue.b * B_Channel; +} + +vec4 CalcBlendedNormal(vec4 blendValue, sampler2D R, sampler2D G, sampler2D B, + vec2 R_TileValues, vec2 G_TileValues, vec2 B_TileValues){ + mat3 TBN = mat3(Input.Tangent, Input.BiTangent, Input.Normal); + vec3 R_Channel = texture(R, Input.TextureCoordinate * R_TileValues).xyz * 2.0 - vec3(1.0); + vec3 G_Channel = texture(G, Input.TextureCoordinate * G_TileValues).xyz * 2.0 - vec3(1.0); + vec3 B_Channel = texture(B, Input.TextureCoordinate * B_TileValues).xyz * 2.0 - vec3(1.0); + + float total = blendValue.r + blendValue.g + blendValue.b + blendValue.a; + float totalDiv = 1 / total; + blendValue.r = blendValue.r * totalDiv; + blendValue.g = blendValue.g * totalDiv; + blendValue.b = blendValue.b * totalDiv; + + vec3 Normal_result = blendValue.r * R_Channel + + blendValue.g * G_Channel + + blendValue.b * B_Channel; + + return vec4(TBN * normalize(Normal_result), 0.0); +} + +void main() +{ + float ao = texelFetch(AOTexture, ivec2(gl_FragCoord.xy) >> int(SSAOQuality), 0).r; + ao = (clamp(1.0 - (1.0 - ao), 0.0, 1.0) + MIN_AMBIENT_LIGHT) / (1.0 + MIN_AMBIENT_LIGHT); + + vec4 splatTexel = texture2D(SplatMapTexture, Input.TextureCoordinate); + + vec4 diffuseTexel = CalcBlendedTexel(splatTexel, DiffuseTexture1, DiffuseTexture2, DiffuseTexture3, + DiffuseUVRepeat1, DiffuseUVRepeat2, DiffuseUVRepeat3); + vec4 glowTexel = CalcBlendedTexel(splatTexel, GlowMapTexture1, GlowMapTexture2, GlowMapTexture3, + GlowUVRepeat1, GlowUVRepeat2, GlowUVRepeat3); + vec4 specularTexel = CalcBlendedTexel(splatTexel, SpecularMapTexture1, SpecularMapTexture2, SpecularMapTexture3, + SpecularUVRepeat1, SpecularUVRepeat2, SpecularUVRepeat3); + vec4 position = V * M * vec4(Input.Position, 1.0); + //vec4 normal = V * CalcNormalMappedValue(Input.Normal, Input.Tangent, Input.BiTangent, Input.TextureCoordinate, SplatMapTexture); + vec4 normal = V * CalcBlendedNormal(splatTexel, NormalMapTexture1, NormalMapTexture2, NormalMapTexture3, + NormalUVRepeat1, NormalUVRepeat2, NormalUVRepeat3); + normal = normalize(normal); + //vec4 normal = normalize(V * vec4(Input.Normal, 0.0)); + vec4 viewVec = normalize(-position); + + vec2 tilePos; + tilePos.x = int(gl_FragCoord.x/TILE_SIZE); + tilePos.y = int(gl_FragCoord.y/TILE_SIZE); + + LightResult totalLighting; + totalLighting.Diffuse = vec4(AmbientColor.rgb * ao, 1.0); + int currentTile = int(floor(gl_FragCoord.x/TILE_SIZE) + (floor(gl_FragCoord.y/TILE_SIZE) * int(ScreenDimensions.x/TILE_SIZE))); + + int start = int(LightGrids.Data[currentTile].Start); + int amount = int(LightGrids.Data[currentTile].Amount); + + for(int i = start; i < start + amount; i++) { + + int l = int(LightIndex[i]); + LightSource light = LightSources.List[l]; + + LightResult light_result; + //These if statements should be removed. + if(light.Type == 1) { // point + light_result = CalcPointLightSource(V * light.Position, light.Radius, light.Color, light.Intensity, viewVec, position, normal, light.Falloff); + } else if (light.Type == 2) { //Directional + light_result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal); + } + totalLighting.Diffuse += vec4(light_result.Diffuse.rgb * ao, light_result.Diffuse.a); + totalLighting.Specular += vec4(light_result.Specular.rgb * ao, light_result.Specular.a); + } + + vec4 color_result = mix((Color * diffuseTexel * DiffuseColor), Input.ExplosionColor, Input.ExplosionPercentageElapsed); + color_result = color_result * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)); + //vec4 color_result = (DiffuseColor + Input.ExplosionColor) * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)) * diffuseTexel * Color; + + + float pos = ((P * vec4(Input.Position, 1)).y + 1.0)/2.0; + + if(pos <= FillPercentage) { + color_result += FillColor; + } + sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1)); + color_result += glowTexel*3; + + bloomColor = vec4(clamp(color_result.xyz - 1.0, 0, 100), 1.0); + + //Tiled Debug Code + /* + if(int(gl_FragCoord.x)%16 == 0 || int(gl_FragCoord.y)%16 == 0 ) { + sceneColor += vec4(0.5, 0, 0, 0); + } else { + sceneColor += vec4(LightGrids.Data[int(tilePos.x + tilePos.y*80)].Amount/LightSources.List.length(), 0, 0, 1); + } + */ +} + + diff --git a/resources/Shaders/SSAO.frag.glsl b/resources/Shaders/SSAO.frag.glsl index 68c830f8..749881c4 100644 --- a/resources/Shaders/SSAO.frag.glsl +++ b/resources/Shaders/SSAO.frag.glsl @@ -2,11 +2,11 @@ //Number of samples per pixel uniform int uNumOfSamples; -//#define NUM_SAMPLES (11) +//#define uNumOfSamples (11) //Number of turns around the cirle uniform int uNumOfTurns; -//#define NUM_TURNS (7) +//#define uNumOfTurns (7) layout (binding = 0) uniform sampler2D ViewSpaceZ; @@ -16,15 +16,16 @@ uniform float uProjScale; //#define ProjScale 500 uniform float uRadius; -//#define Radius 1.0f +//#define uRadius 1.0f uniform float uBias; -//#define Bias 0.012f +//#define uBias 0.05f uniform float uContrast; -//#define IntensityDivR6 1 +//#define uContrast 1.5f uniform float uIntensityScale; +//#define uIntensityScale 1.0f out float AO; @@ -88,13 +89,7 @@ void main() { vec3 origin = getVSPosition(originScreenCoord); - float radius; - if(origin.z < uRadius){ - radius = origin.z; - } else { - radius = uRadius; - } - + float radius = min(origin.z, uRadius); vec3 originNormal = getVSFaceNormal(origin); diff --git a/resources/Shaders/SSAO.vert.glsl b/resources/Shaders/SSAO.vert.glsl index a019c5ef..346bc141 100644 --- a/resources/Shaders/SSAO.vert.glsl +++ b/resources/Shaders/SSAO.vert.glsl @@ -2,7 +2,12 @@ layout (location = 0) in vec3 Position; +out VertexData{ + vec2 TextureCoordinate; +}Output; + void main() { gl_Position = vec4(Position, 1.0); + Output.TextureCoordinate = (vec2(Position) + 1) / 2; } \ No newline at end of file diff --git a/resources/Shaders/SSAOViewSpaceZ.frag.glsl b/resources/Shaders/SSAOViewSpaceZ.frag.glsl index dbcfd899..d1bf6f17 100644 --- a/resources/Shaders/SSAOViewSpaceZ.frag.glsl +++ b/resources/Shaders/SSAOViewSpaceZ.frag.glsl @@ -3,11 +3,15 @@ layout (binding = 0) uniform sampler2D DepthBuffer; uniform vec3 ClipInfo; +in VertexData{ + vec2 TextureCoordinate; +}Input; + out float depthLinear; //Just for Debug, should be depthLinear //out vec4 fragmentColor; void main() { - float depthSample = texelFetch(DepthBuffer, ivec2(gl_FragCoord.xy), 0).r; + float depthSample = texture2D(DepthBuffer, Input.TextureCoordinate).r; depthLinear = ClipInfo[0] / (ClipInfo[1] * depthSample + ClipInfo[2]); //float depthLinear = (NearClip) / ( -depthSample + 1.0f); //fragmentColor = vec4(depthLinear, depthLinear, depthLinear, 1.0f); diff --git a/resources/Shaders/SpriteShieldCheck.frag.glsl b/resources/Shaders/SpriteShieldCheck.frag.glsl new file mode 100644 index 00000000..754be6ac --- /dev/null +++ b/resources/Shaders/SpriteShieldCheck.frag.glsl @@ -0,0 +1,41 @@ +#version 430 + +uniform vec4 Color; +uniform vec4 FillColor; +uniform float FillPercentage; +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; + +layout (binding = 1) uniform sampler2D DiffuseTexture; +layout (binding = 2) uniform sampler2D GlowMapTexture; + + +in VertexData{ + vec3 Position; + vec3 Normal; + vec2 TextureCoordinate; +}Input; + + +out vec4 sceneColor; +out vec4 bloomColor; + +void main() +{ + vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate); + vec4 glowTexel = texture2D(GlowMapTexture, Input.TextureCoordinate); + + vec4 color_result = Color * diffuseTexel; + + float pos = ((P * vec4(Input.Position, 1)).y + 1.0)/2.0; + if(pos <= FillPercentage) { + color_result = FillColor*diffuseTexel.a; + } + sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1)); + + //bloomColor = vec4(clamp((glowTexel.xyz*3) - 1.0, 0, 100), 1.0); + bloomColor = vec4(1.0, 1.0, 1.0, 0.0); +} + + diff --git a/src/Engine/Collision/CollisionSystem.cpp b/src/Engine/Collision/CollisionSystem.cpp index 9689bf13..53cabfac 100644 --- a/src/Engine/Collision/CollisionSystem.cpp +++ b/src/Engine/Collision/CollisionSystem.cpp @@ -12,107 +12,112 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c if (!boundingBox) { return; } + ComponentWrapper& cTransform = entity["Transform"]; EntityAABB& boxA = *boundingBox; bool everHitTheGround = false; - auto prevPosIt = m_PrevPositions.find(entity); - if (prevPosIt != m_PrevPositions.end()) { - glm::vec3 size = boxA.Size(); - float diameter = std::min(size.x, size.z); - glm::vec3 prevOrigin = prevPosIt->second; - glm::vec3 toCurrentPos = boxA.Origin() - prevOrigin; - float rayLength = glm::length(toCurrentPos) + 0.5f*diameter; - //If the entity has moved farther than the size of its box, we need to handle it specially. - if (rayLength > diameter) { - Ray ray(prevOrigin, toCurrentPos); - m_OctreeResult.clear(); - m_Octree->ObjectsPossiblyHitByRay(ray, m_OctreeResult); - for (auto& boxB : m_OctreeResult) { - if (boxA.Entity == boxB.Entity) { - continue; - } - bool hit; - float dist; - if (boxB.Entity.HasComponent("Model")) { - RawModel* model; - std::string res = (std::string)boxB.Entity["Model"]["Resource"]; - try { - model = ResourceManager::Load(res); - } catch (const std::exception&) { + if (entity == LocalPlayer) { + auto prevPosIt = m_PrevPositions.find(entity); + if (prevPosIt != m_PrevPositions.end()) { + glm::vec3 size = boxA.Size(); + float diameter = std::min(size.x, size.z); + glm::vec3 prevOrigin = prevPosIt->second; + glm::vec3 toCurrentPos = boxA.Origin() - prevOrigin; + float rayLength = glm::length(toCurrentPos) + 0.5f*diameter; + //If the entity has moved farther than the size of its box, we need to handle it specially. + if (rayLength > diameter) { + Ray ray(prevOrigin, toCurrentPos); + m_OctreeResult.clear(); + m_Octree->ObjectsPossiblyHitByRay(ray, m_OctreeResult); + for (auto& boxB : m_OctreeResult) { + if (boxA.Entity == boxB.Entity) { continue; } - float u, v; - hit = Collision::RayVsModel(ray, model->Vertices(), model->m_Indices, Transform::ModelMatrix(boxB.Entity), dist, u, v); - } else { - hit = Collision::RayVsAABB(ray, boxB, dist); - } - if (hit && dist < rayLength) { - //Set the entity to where it was colliding, minus the maximum box size. - //TODO: Perhaps this should be done slightly more properly. - glm::vec3 newOriginPos = ray.Origin() + (dist - 0.707107f*diameter) * ray.Direction(); - glm::vec3 resolve = newOriginPos - boxA.Origin(); - (glm::vec3&)cTransform["Position"] += resolve; - boxA = *Collision::EntityAbsoluteAABB(entity); - if (resolve.y > 0) { - everHitTheGround = true; - (bool)cPhysics["IsOnGround"] = true; - ((glm::vec3&)cPhysics["Velocity"]).y = 0.f; + bool hit; + float dist; + if (boxB.Entity.HasComponent("Model")) { + RawModel* model; + std::string res = (std::string)boxB.Entity["Model"]["Resource"]; + try { + model = ResourceManager::Load(res); + } catch (const std::exception&) { + continue; + } + float u, v; + hit = Collision::RayVsModel(ray, model->Vertices(), model->m_Indices, Transform::ModelMatrix(boxB.Entity), dist, u, v); + } else { + hit = Collision::RayVsAABB(ray, boxB, dist); + } + if (hit && dist < rayLength) { + //Set the entity to where it was colliding, minus the maximum box size. + //TODO: Perhaps this should be done slightly more properly. + glm::vec3 newOriginPos = ray.Origin() + (dist - 0.707107f*diameter) * ray.Direction(); + glm::vec3 resolve = newOriginPos - boxA.Origin(); + (glm::vec3&)cTransform["Position"] += resolve; + boxA = *Collision::EntityAbsoluteAABB(entity); + if (resolve.y > 0) { + everHitTheGround = true; + (bool)cPhysics["IsOnGround"] = true; + ((glm::vec3&)cPhysics["Velocity"]).y = 0.f; + } + break; } - break; } } } - } - // Collide against octree items - m_OctreeResult.clear(); - m_Octree->ObjectsInSameRegion(*boundingBox, m_OctreeResult); - for (auto& boxB : m_OctreeResult) { - glm::vec3 resolutionVector; - if (boxA.Entity == boxB.Entity) { - continue; - } - - if (boxB.Entity.HasComponent("Model") && Collision::AABBVsAABB(boxA, boxB)) { - //Here we know boxB is a entity with Collideable, AABB, and Model. - RawModel* model; - try { - model = ResourceManager::Load(boxB.Entity["Model"]["Resource"]); - } catch (const std::exception&) { + // Collide against octree items + m_OctreeResult.clear(); + m_Octree->ObjectsInSameRegion(*boundingBox, m_OctreeResult); + for (auto& boxB : m_OctreeResult) { + glm::vec3 resolutionVector; + if (boxA.Entity == boxB.Entity) { continue; } - glm::mat4 modelMatrix = Transform::ModelMatrix(boxB.Entity); + if (boxB.Entity.HasComponent("Model") && Collision::AABBVsAABB(boxA, boxB)) { + //Here we know boxB is a entity with Collideable, AABB, and Model. + RawModel* model; + try { + model = ResourceManager::Load(boxB.Entity["Model"]["Resource"]); + } catch (const std::exception&) { + continue; + } - glm::vec3 inOutVelocity = (glm::vec3)cPhysics["Velocity"]; - bool isOnGround = (bool)cPhysics["IsOnGround"]; - float verticalStepHeight = (float)(double)cPhysics["VerticalStepHeight"]; - if (Collision::AABBvsTriangles(boxA, model->Vertices(), model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) { + glm::mat4 modelMatrix = Transform::ModelMatrix(boxB.Entity); + + glm::vec3 inOutVelocity = (glm::vec3)cPhysics["Velocity"]; + bool notMovingxz = glm::all(glm::lessThan(glm::abs(glm::vec2(inOutVelocity.x, inOutVelocity.z)), glm::vec2(0.01f))) && prevPosIt != m_PrevPositions.end(); + bool isOnGround = (bool)cPhysics["IsOnGround"]; + float verticalStepHeight = (float)(double)cPhysics["VerticalStepHeight"]; + if (Collision::AABBvsTriangles(boxA, model->Vertices(), model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) { + //Move the position to previous position if it is not moving in the xz-plane, else resolve with the resolution vector. + (glm::vec3&)cTransform["Position"] += notMovingxz ? prevPosIt->second - boxA.Origin() : resolutionVector; + boxA = *Collision::EntityAbsoluteAABB(entity); + cPhysics["Velocity"] = inOutVelocity; + if (isOnGround) { + everHitTheGround = true; + (bool)cPhysics["IsOnGround"] = true; + } + } + } else if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) { + //Enter here if boxB has no Model. (glm::vec3&)cTransform["Position"] += resolutionVector; boxA = *Collision::EntityAbsoluteAABB(entity); - cPhysics["Velocity"] = inOutVelocity; - if (isOnGround) { + if (resolutionVector.y > 0) { everHitTheGround = true; (bool)cPhysics["IsOnGround"] = true; + ((glm::vec3&)cPhysics["Velocity"]).y = 0.f; } } - } else if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) { - //Enter here if boxB has no Model. - (glm::vec3&)cTransform["Position"] += resolutionVector; - boxA = *Collision::EntityAbsoluteAABB(entity); - if (resolutionVector.y > 0) { - everHitTheGround = true; - (bool)cPhysics["IsOnGround"] = true; - ((glm::vec3&)cPhysics["Velocity"]).y = 0.f; - } } - } - //This should apply air friction and such, iff zero models were hit. - if (!everHitTheGround) { - (bool)cPhysics["IsOnGround"] = false; - } + //This should apply air friction and such, iff zero models were hit. + if (!everHitTheGround) { + (bool)cPhysics["IsOnGround"] = false; + } - m_PrevPositions[entity] = boxA.Origin(); + m_PrevPositions[entity] = boxA.Origin(); + } } diff --git a/src/Engine/Core/EntityFile.cpp b/src/Engine/Core/EntityFile.cpp index 3987b092..997b9c46 100644 --- a/src/Engine/Core/EntityFile.cpp +++ b/src/Engine/Core/EntityFile.cpp @@ -1,291 +1,25 @@ #include "Core/EntityFile.h" -EntityFile::EntityFile(boost::filesystem::path path) - : m_FilePath(path) +EntityFile::EntityFile(std::string path) { - using namespace xercesc; - XMLPlatformUtils::Initialize(); - m_GrammarPool = new XMLGrammarPoolImpl(); - m_SAX2XMLReader = XMLReaderFactory::createXMLReader(XMLPlatformUtils::fgMemoryManager, m_GrammarPool); -} + EntityXMLFile* xml = ResourceManager::Load(path); -EntityFile::~EntityFile() -{ - delete m_SAX2XMLReader; - delete m_GrammarPool; - xercesc::XMLPlatformUtils::Terminate(); -} + EntityXMLFilePreprocessor preprocessor(xml); + preprocessor.RegisterComponents(this); -void EntityFile::Parse(const EntityFileHandler* handler) const -{ - using namespace xercesc; + EntityXMLFileParser parser(xml); + m_RootEntity = parser.MergeEntities(this); - EntityFileSAXHandler saxHandler(handler, m_SAX2XMLReader); - setReaderFeatures(m_SAX2XMLReader); - m_SAX2XMLReader->setContentHandler(&saxHandler); - m_SAX2XMLReader->setErrorHandler(&saxHandler); - m_SAX2XMLReader->setDeclarationHandler(&saxHandler); - m_SAX2XMLReader->parse(m_FilePath.string().c_str()); -} - -void EntityFile::setReaderFeatures(xercesc::SAX2XMLReader* reader) -{ - using namespace xercesc; - reader->setFeature(XMLUni::fgXercesCacheGrammarFromParse, true); - reader->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true); - reader->setFeature(XMLUni::fgSAX2CoreValidation, true); - reader->setFeature(XMLUni::fgSAX2CoreNameSpaces, true); - reader->setFeature(XMLUni::fgXercesSchema, true); - reader->setFeature(XMLUni::fgXercesSchemaFullChecking, true); - reader->setFeature(XMLUni::fgXercesCalculateSrcOfs, true); - reader->setFeature(XMLUni::fgXercesIdentityConstraintChecking, true); -} - -unsigned int EntityFile::GetTypeStride(std::string typeName) -{ - std::map typeStrides{ - { "bool", sizeof(bool) }, - { "int", sizeof(int) }, - { "float", sizeof(float) }, - { "double", sizeof(double) }, - { "string", sizeof(std::string) }, - { "enum", sizeof(ComponentInfo::EnumType) }, - { "Vector", sizeof(glm::vec3) }, - { "Quaternion", sizeof(glm::quat) }, - { "Color", sizeof(glm::vec4) } - }; - - auto it = typeStrides.find(typeName); - return (it != typeStrides.end()) ? it->second : 0; -} - -void EntityFile::WriteAttributeData(char* outData, const ComponentInfo::Field_t& field, const std::map& attributes) -{ - if (field.Type == "Vector") { - glm::vec3 vec; - vec.x = boost::lexical_cast(attributes.at("X")); - vec.y = boost::lexical_cast(attributes.at("Y")); - vec.z = boost::lexical_cast(attributes.at("Z")); - memcpy(outData, reinterpret_cast(&vec), field.Stride); - } else if (field.Type == "Color") { - glm::vec4 vec; - vec.r = boost::lexical_cast(attributes.at("R")); - vec.g = boost::lexical_cast(attributes.at("G")); - vec.b = boost::lexical_cast(attributes.at("B")); - vec.a = boost::lexical_cast(attributes.at("A")); - memcpy(outData, reinterpret_cast(&vec), field.Stride); - } else if (field.Type == "Quaternion") { - glm::quat q; - q.x = boost::lexical_cast(attributes.at("X")); - q.y = boost::lexical_cast(attributes.at("Y")); - q.z = boost::lexical_cast(attributes.at("Z")); - q.w = boost::lexical_cast(attributes.at("W")); - memcpy(outData, reinterpret_cast(&q), field.Stride); - } else if (!attributes.empty()) { - LOG_WARNING("%i attributes not handled by any type conversion!", attributes.size()); - } -} - -void EntityFile::WriteValueData(char* outData, const ComponentInfo::Field_t& field, const char* valueData) -{ - // Catch and ignore casting errors so whitespace around string enums won't mess anything up - try { - if (field.Type == "int") { - int value = boost::lexical_cast(valueData); - memcpy(outData, reinterpret_cast(&value), field.Stride); - } else if (field.Type == "enum") { - ComponentInfo::EnumType value = boost::lexical_cast(valueData); - memcpy(outData, reinterpret_cast(&value), field.Stride); - } else if (field.Type == "float") { - float value = boost::lexical_cast(valueData); - memcpy(outData, reinterpret_cast(&value), field.Stride); - } else if (field.Type == "double") { - double value = boost::lexical_cast(valueData); - memcpy(outData, reinterpret_cast(&value), field.Stride); - } else if (field.Type == "bool") { - bool value = (valueData[0] == 't'); // Lazy bool evaluation - memcpy(outData, reinterpret_cast(&value), field.Stride); - } else if (field.Type == "string") { - new (outData) std::string(valueData); - } else { - LOG_WARNING("Unknown value data type: %s", field.Type.c_str()); - } - } catch (const boost::bad_lexical_cast&) { } -} - -EntityFileSAXHandler::EntityFileSAXHandler(const EntityFileHandler* handler, xercesc::SAX2XMLReader* reader) - : m_Handler(handler) - , m_Reader(reader) -{ - // 0 is imaginary base parent - m_EntityStack.push(0); - m_StateStack.push(State::Unknown); -} - -void EntityFileSAXHandler::startElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname, const xercesc::Attributes& attrs) -{ - std::string name = XS::ToString(_localName); - - if (m_StateStack.top() == State::Unknown || m_StateStack.top() == State::Entity) { - if (name == "Entity") { - m_StateStack.push(State::Entity); - onStartEntity(attrs); - return; - } - if (name == "EntityRef") { - onStartEntityRef(attrs); - return; - } + if (m_RootEntity == EntityID_Invalid) { + ResourceManager::Release("EntityXMLFile", path); + throw Resource::FailedLoadingException("Failed to merge entities; root entity is invalid"); } - std::string uri = XS::ToString(_uri); - if (m_StateStack.top() == State::Entity) { - if (uri == "components") { - m_StateStack.push(State::Component); - onStartComponent(name); - return; - } - } - - if (m_StateStack.top() == State::Component) { - m_StateStack.push(State::ComponentField); - onStartComponentField(name, attrs); - return; - } + ResourceManager::Release("EntityXMLFile", path); } -void EntityFileSAXHandler::endElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname) +EntityWrapper EntityFile::MergeInto(World* other) { - std::string name = XS::ToString(_localName); - if (m_StateStack.top() == State::Entity) { - if (name == "Entity") { - m_StateStack.pop(); - onEndEntity(); - return; - } - } - - std::string uri = XS::ToString(_uri); - if (m_StateStack.top() == State::Component) { - //if (uri == "components") { - m_StateStack.pop(); - onEndComponent(name); - return; - //} - } - - if (m_StateStack.top() == State::ComponentField && name == m_CurrentField) { - m_StateStack.pop(); - onEndComponentField(name); - return; - } -} - -void EntityFileSAXHandler::characters(const XMLCh* const chars, const XMLSize_t length) -{ - if (m_StateStack.top() == State::ComponentField) { - char* transcoded = xercesc::XMLString::transcode(chars); - onFieldData(transcoded); - } -} - -void EntityFileSAXHandler::fatalError(const xercesc::SAXParseException& e) -{ - std::string message = XS::ToString(e.getMessage()); - std::string systemId = XS::ToString(e.getSystemId()); - XMLFileLoc line = e.getLineNumber(); - XMLFileLoc column = e.getColumnNumber(); - LOG_ERROR("SAXParseException\n\tLocation: %s:%i:%i\n\tFatal Error: %s", systemId.c_str(), line, column, message.c_str()); -} - -void EntityFileSAXHandler::error(const xercesc::SAXParseException& e) -{ - std::string message = XS::ToString(e.getMessage()); - std::string systemId = XS::ToString(e.getSystemId()); - XMLFileLoc line = e.getLineNumber(); - XMLFileLoc column = e.getColumnNumber(); - LOG_ERROR("SAXParseException\n\tLocation: %s:%i:%i\n\tError: %s", systemId.c_str(), line, column, message.c_str()); -} - -void EntityFileSAXHandler::warning(const xercesc::SAXParseException& e) -{ - std::string message = XS::ToString(e.getMessage()); - std::string systemId = XS::ToString(e.getSystemId()); - XMLFileLoc line = e.getLineNumber(); - XMLFileLoc column = e.getColumnNumber(); - LOG_ERROR("SAXParseException\n\tLocation: %s:%i:%i\n\tWarning: %s", systemId.c_str(), line, column, message.c_str()); -} - -void EntityFileSAXHandler::onStartEntity(const xercesc::Attributes& attrs) -{ - EntityID parent = m_EntityStack.top(); - - if (m_Handler->m_OnStartEntityCallback) { - std::string name; - auto xName = attrs.getValue(XS::ToXMLCh("name")); - if (xName != nullptr) { - name = XS::ToString(xName); - } - m_Handler->m_OnStartEntityCallback(m_NextEntityID, parent, name); - } - - m_EntityStack.push(m_NextEntityID); - m_NextEntityID++; -} - -void EntityFileSAXHandler::onEndEntity() -{ - m_EntityStack.pop(); -} - -void EntityFileSAXHandler::onStartEntityRef(const xercesc::Attributes& attrs) -{ - std::string path = XS::ToString(attrs.getValue(XS::ToXMLCh("file"))); - - xercesc::SAX2XMLReader* reader = xercesc::XMLReaderFactory::createXMLReader(); - EntityFile::setReaderFeatures(reader); - reader->setContentHandler(this); - reader->setErrorHandler(this); - reader->parse(path.c_str()); - delete reader; -} - -void EntityFileSAXHandler::onStartComponentField(const std::string& field, const xercesc::Attributes& attrs) -{ - //LOG_DEBUG(" Field: %s", field.c_str()); - m_CurrentField = field; - m_CurrentAttributes.clear(); - for (int i = 0; i < attrs.getLength(); i++) { - auto name = attrs.getQName(i); - auto value = attrs.getValue(name); - //LOG_DEBUG(" %s = %s", (char*)XS::ToString(name), (char*)XS::ToString(value)); - m_CurrentAttributes[XS::ToString(name).operator std::string()] = XS::ToString(value).operator std::string(); - } - - if (m_Handler->m_OnStartFieldCallback) { - m_Handler->m_OnStartFieldCallback(m_EntityStack.top(), m_CurrentComponent, field, m_CurrentAttributes); - } -} - -void EntityFileSAXHandler::onEndComponent(const std::string& name) { } - -void EntityFileSAXHandler::onStartComponent(const std::string& name) -{ - //LOG_DEBUG(" Component: %s", name.c_str()); - m_CurrentComponent = name; - if (m_Handler->m_OnStartComponentCallback) { - m_Handler->m_OnStartComponentCallback(m_EntityStack.top(), name); - } -} - -void EntityFileSAXHandler::onEndComponentField(const std::string& field) { } - -void EntityFileSAXHandler::onFieldData(char* data) -{ - //LOG_DEBUG(" Data: %s", data); - if (m_Handler->m_OnStartFieldDataCallback) { - m_Handler->m_OnStartFieldDataCallback(m_EntityStack.top(), m_CurrentComponent, m_CurrentField, data); - } - - xercesc::XMLString::release(&data); -} + auto mapping = other->Merge(this); + return EntityWrapper(other, mapping.at(m_RootEntity)); +} \ No newline at end of file diff --git a/src/Engine/Core/EntityFileParser.cpp b/src/Engine/Core/EntityFileParser.cpp deleted file mode 100644 index 23c0c4c4..00000000 --- a/src/Engine/Core/EntityFileParser.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "Core/EntityFileParser.h" - -EntityFileParser::EntityFileParser(const EntityFile* entityFile) - : m_EntityFile(entityFile) -{ - m_Handler.SetStartEntityCallback(std::bind(&EntityFileParser::onStartEntity, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - m_Handler.SetStartComponentCallback(std::bind(&EntityFileParser::onStartComponent, this, std::placeholders::_1, std::placeholders::_2)); - m_Handler.SetStartFieldCallback(std::bind(&EntityFileParser::onStartComponentField, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); - m_Handler.SetStartFieldDataCallback(std::bind(&EntityFileParser::onFieldData, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); -} - -EntityID EntityFileParser::MergeEntities(World* world, EntityID baseParent /*= EntityID_Invalid */) -{ - m_World = world; - m_EntityIDMapper[0] = baseParent; - m_EntityFile->Parse(&m_Handler); - return m_FirstEntity; -} - -void EntityFileParser::onStartEntity(EntityID entity, EntityID parent, const std::string& name) -{ - EntityID realParent = m_EntityIDMapper.at(parent); - EntityID realEntity = m_World->CreateEntity(realParent); - if (m_FirstEntity == EntityID_Invalid) { - m_FirstEntity = realEntity; - } - if (!name.empty()) { - m_World->SetName(realEntity, name); - } - m_EntityIDMapper[entity] = realEntity; - //LOG_DEBUG("Created entity #%i (%i) with parent %i (%i)", entity, realEntity, parent, realParent); -} - -void EntityFileParser::onStartComponent(EntityID entity, const std::string& component) -{ - EntityID realEntity = m_EntityIDMapper.at(entity); - m_World->AttachComponent(realEntity, component); - //LOG_DEBUG("Attached component of type \"%s\" to entity #%i (%i)", component.c_str(), entity, realEntity); -} - -void EntityFileParser::onStartComponentField(EntityID entity, const std::string& componentType, const std::string& fieldName, const std::map& attributes) -{ - EntityID realEntity = m_EntityIDMapper.at(entity); - ComponentWrapper component = m_World->GetComponent(realEntity, componentType); - auto fieldIt = component.Info.Fields.find(fieldName); - if (fieldIt == component.Info.Fields.end()) { - LOG_ERROR("Tried to set unknown field \"%s\" of component type \"%s\"! Ignoring.", fieldName.c_str(), componentType.c_str()); - return; - } - auto& field = fieldIt->second; - - //LOG_DEBUG("Field \"%s\" type \"%s\"", fieldName.c_str(), field.Type.c_str()); - //LOG_DEBUG("Attributes:"); - //for (auto& kv : attributes) { - // LOG_DEBUG("\t%s = %s", kv.first.c_str(), kv.second.c_str()); - //} - - char* data = component.Data + field.Offset; - EntityFile::WriteAttributeData(data, field, attributes); -} - -void EntityFileParser::onFieldData(EntityID entity, const std::string& componentType, const std::string& fieldName, const char* fieldData) -{ - EntityID realEntity = m_EntityIDMapper.at(entity); - ComponentWrapper component = m_World->GetComponent(realEntity, componentType); - auto fieldIt = component.Info.Fields.find(fieldName); - if (fieldIt == component.Info.Fields.end()) { - return; - } - auto& field = fieldIt->second; - - char* data = component.Data + field.Offset; - EntityFile::WriteValueData(data, field, fieldData); -} diff --git a/src/Engine/Core/EntityXMLFile.cpp b/src/Engine/Core/EntityXMLFile.cpp new file mode 100644 index 00000000..b32d952d --- /dev/null +++ b/src/Engine/Core/EntityXMLFile.cpp @@ -0,0 +1,291 @@ +#include "Core/EntityXMLFile.h" + +EntityXMLFile::EntityXMLFile(boost::filesystem::path path) + : m_FilePath(path) +{ + using namespace xercesc; + XMLPlatformUtils::Initialize(); + m_GrammarPool = new XMLGrammarPoolImpl(); + m_SAX2XMLReader = XMLReaderFactory::createXMLReader(XMLPlatformUtils::fgMemoryManager, m_GrammarPool); +} + +EntityXMLFile::~EntityXMLFile() +{ + delete m_SAX2XMLReader; + delete m_GrammarPool; + xercesc::XMLPlatformUtils::Terminate(); +} + +void EntityXMLFile::Parse(const EntityFileHandler* handler) const +{ + using namespace xercesc; + + EntityFileSAXHandler saxHandler(handler, m_SAX2XMLReader); + setReaderFeatures(m_SAX2XMLReader); + m_SAX2XMLReader->setContentHandler(&saxHandler); + m_SAX2XMLReader->setErrorHandler(&saxHandler); + m_SAX2XMLReader->setDeclarationHandler(&saxHandler); + m_SAX2XMLReader->parse(m_FilePath.string().c_str()); +} + +void EntityXMLFile::setReaderFeatures(xercesc::SAX2XMLReader* reader) +{ + using namespace xercesc; + reader->setFeature(XMLUni::fgXercesCacheGrammarFromParse, true); + reader->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true); + reader->setFeature(XMLUni::fgSAX2CoreValidation, true); + reader->setFeature(XMLUni::fgSAX2CoreNameSpaces, true); + reader->setFeature(XMLUni::fgXercesSchema, true); + reader->setFeature(XMLUni::fgXercesSchemaFullChecking, true); + reader->setFeature(XMLUni::fgXercesCalculateSrcOfs, true); + reader->setFeature(XMLUni::fgXercesIdentityConstraintChecking, true); +} + +unsigned int EntityXMLFile::GetTypeStride(std::string typeName) +{ + std::map typeStrides{ + { "bool", sizeof(bool) }, + { "int", sizeof(int) }, + { "float", sizeof(float) }, + { "double", sizeof(double) }, + { "string", sizeof(std::string) }, + { "enum", sizeof(ComponentInfo::EnumType) }, + { "Vector", sizeof(glm::vec3) }, + { "Quaternion", sizeof(glm::quat) }, + { "Color", sizeof(glm::vec4) } + }; + + auto it = typeStrides.find(typeName); + return (it != typeStrides.end()) ? it->second : 0; +} + +void EntityXMLFile::WriteAttributeData(char* outData, const ComponentInfo::Field_t& field, const std::map& attributes) +{ + if (field.Type == "Vector") { + glm::vec3 vec; + vec.x = boost::lexical_cast(attributes.at("X")); + vec.y = boost::lexical_cast(attributes.at("Y")); + vec.z = boost::lexical_cast(attributes.at("Z")); + memcpy(outData, reinterpret_cast(&vec), field.Stride); + } else if (field.Type == "Color") { + glm::vec4 vec; + vec.r = boost::lexical_cast(attributes.at("R")); + vec.g = boost::lexical_cast(attributes.at("G")); + vec.b = boost::lexical_cast(attributes.at("B")); + vec.a = boost::lexical_cast(attributes.at("A")); + memcpy(outData, reinterpret_cast(&vec), field.Stride); + } else if (field.Type == "Quaternion") { + glm::quat q; + q.x = boost::lexical_cast(attributes.at("X")); + q.y = boost::lexical_cast(attributes.at("Y")); + q.z = boost::lexical_cast(attributes.at("Z")); + q.w = boost::lexical_cast(attributes.at("W")); + memcpy(outData, reinterpret_cast(&q), field.Stride); + } else if (!attributes.empty()) { + LOG_WARNING("%i attributes not handled by any type conversion!", attributes.size()); + } +} + +void EntityXMLFile::WriteValueData(char* outData, const ComponentInfo::Field_t& field, const char* valueData) +{ + // Catch and ignore casting errors so whitespace around string enums won't mess anything up + try { + if (field.Type == "int") { + int value = boost::lexical_cast(valueData); + memcpy(outData, reinterpret_cast(&value), field.Stride); + } else if (field.Type == "enum") { + ComponentInfo::EnumType value = boost::lexical_cast(valueData); + memcpy(outData, reinterpret_cast(&value), field.Stride); + } else if (field.Type == "float") { + float value = boost::lexical_cast(valueData); + memcpy(outData, reinterpret_cast(&value), field.Stride); + } else if (field.Type == "double") { + double value = boost::lexical_cast(valueData); + memcpy(outData, reinterpret_cast(&value), field.Stride); + } else if (field.Type == "bool") { + bool value = (valueData[0] == 't'); // Lazy bool evaluation + memcpy(outData, reinterpret_cast(&value), field.Stride); + } else if (field.Type == "string") { + new (outData) std::string(valueData); + } else { + LOG_WARNING("Unknown value data type: %s", field.Type.c_str()); + } + } catch (const boost::bad_lexical_cast&) { } +} + +EntityFileSAXHandler::EntityFileSAXHandler(const EntityFileHandler* handler, xercesc::SAX2XMLReader* reader) + : m_Handler(handler) + , m_Reader(reader) +{ + // 0 is imaginary base parent + m_EntityStack.push(0); + m_StateStack.push(State::Unknown); +} + +void EntityFileSAXHandler::startElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname, const xercesc::Attributes& attrs) +{ + std::string name = XS::ToString(_localName); + + if (m_StateStack.top() == State::Unknown || m_StateStack.top() == State::Entity) { + if (name == "Entity") { + m_StateStack.push(State::Entity); + onStartEntity(attrs); + return; + } + if (name == "EntityRef") { + onStartEntityRef(attrs); + return; + } + } + + std::string uri = XS::ToString(_uri); + if (m_StateStack.top() == State::Entity) { + if (uri == "components") { + m_StateStack.push(State::Component); + onStartComponent(name); + return; + } + } + + if (m_StateStack.top() == State::Component) { + m_StateStack.push(State::ComponentField); + onStartComponentField(name, attrs); + return; + } +} + +void EntityFileSAXHandler::endElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname) +{ + std::string name = XS::ToString(_localName); + if (m_StateStack.top() == State::Entity) { + if (name == "Entity") { + m_StateStack.pop(); + onEndEntity(); + return; + } + } + + std::string uri = XS::ToString(_uri); + if (m_StateStack.top() == State::Component) { + //if (uri == "components") { + m_StateStack.pop(); + onEndComponent(name); + return; + //} + } + + if (m_StateStack.top() == State::ComponentField && name == m_CurrentField) { + m_StateStack.pop(); + onEndComponentField(name); + return; + } +} + +void EntityFileSAXHandler::characters(const XMLCh* const chars, const XMLSize_t length) +{ + if (m_StateStack.top() == State::ComponentField) { + char* transcoded = xercesc::XMLString::transcode(chars); + onFieldData(transcoded); + } +} + +void EntityFileSAXHandler::fatalError(const xercesc::SAXParseException& e) +{ + std::string message = XS::ToString(e.getMessage()); + std::string systemId = XS::ToString(e.getSystemId()); + XMLFileLoc line = e.getLineNumber(); + XMLFileLoc column = e.getColumnNumber(); + LOG_ERROR("SAXParseException\n\tLocation: %s:%i:%i\n\tFatal Error: %s", systemId.c_str(), line, column, message.c_str()); +} + +void EntityFileSAXHandler::error(const xercesc::SAXParseException& e) +{ + std::string message = XS::ToString(e.getMessage()); + std::string systemId = XS::ToString(e.getSystemId()); + XMLFileLoc line = e.getLineNumber(); + XMLFileLoc column = e.getColumnNumber(); + LOG_ERROR("SAXParseException\n\tLocation: %s:%i:%i\n\tError: %s", systemId.c_str(), line, column, message.c_str()); +} + +void EntityFileSAXHandler::warning(const xercesc::SAXParseException& e) +{ + std::string message = XS::ToString(e.getMessage()); + std::string systemId = XS::ToString(e.getSystemId()); + XMLFileLoc line = e.getLineNumber(); + XMLFileLoc column = e.getColumnNumber(); + LOG_ERROR("SAXParseException\n\tLocation: %s:%i:%i\n\tWarning: %s", systemId.c_str(), line, column, message.c_str()); +} + +void EntityFileSAXHandler::onStartEntity(const xercesc::Attributes& attrs) +{ + EntityID parent = m_EntityStack.top(); + + if (m_Handler->m_OnStartEntityCallback) { + std::string name; + auto xName = attrs.getValue(XS::ToXMLCh("name")); + if (xName != nullptr) { + name = XS::ToString(xName); + } + m_Handler->m_OnStartEntityCallback(m_NextEntityID, parent, name); + } + + m_EntityStack.push(m_NextEntityID); + m_NextEntityID++; +} + +void EntityFileSAXHandler::onEndEntity() +{ + m_EntityStack.pop(); +} + +void EntityFileSAXHandler::onStartEntityRef(const xercesc::Attributes& attrs) +{ + std::string path = XS::ToString(attrs.getValue(XS::ToXMLCh("file"))); + + xercesc::SAX2XMLReader* reader = xercesc::XMLReaderFactory::createXMLReader(); + EntityXMLFile::setReaderFeatures(reader); + reader->setContentHandler(this); + reader->setErrorHandler(this); + reader->parse(path.c_str()); + delete reader; +} + +void EntityFileSAXHandler::onStartComponentField(const std::string& field, const xercesc::Attributes& attrs) +{ + //LOG_DEBUG(" Field: %s", field.c_str()); + m_CurrentField = field; + m_CurrentAttributes.clear(); + for (int i = 0; i < attrs.getLength(); i++) { + auto name = attrs.getQName(i); + auto value = attrs.getValue(name); + //LOG_DEBUG(" %s = %s", (char*)XS::ToString(name), (char*)XS::ToString(value)); + m_CurrentAttributes[XS::ToString(name).operator std::string()] = XS::ToString(value).operator std::string(); + } + + if (m_Handler->m_OnStartFieldCallback) { + m_Handler->m_OnStartFieldCallback(m_EntityStack.top(), m_CurrentComponent, field, m_CurrentAttributes); + } +} + +void EntityFileSAXHandler::onEndComponent(const std::string& name) { } + +void EntityFileSAXHandler::onStartComponent(const std::string& name) +{ + //LOG_DEBUG(" Component: %s", name.c_str()); + m_CurrentComponent = name; + if (m_Handler->m_OnStartComponentCallback) { + m_Handler->m_OnStartComponentCallback(m_EntityStack.top(), name); + } +} + +void EntityFileSAXHandler::onEndComponentField(const std::string& field) { } + +void EntityFileSAXHandler::onFieldData(char* data) +{ + //LOG_DEBUG(" Data: %s", data); + if (m_Handler->m_OnStartFieldDataCallback) { + m_Handler->m_OnStartFieldDataCallback(m_EntityStack.top(), m_CurrentComponent, m_CurrentField, data); + } + + xercesc::XMLString::release(&data); +} diff --git a/src/Engine/Core/EntityXMLFileParser.cpp b/src/Engine/Core/EntityXMLFileParser.cpp new file mode 100644 index 00000000..9c79775c --- /dev/null +++ b/src/Engine/Core/EntityXMLFileParser.cpp @@ -0,0 +1,84 @@ +#include "Core/EntityXMLFileParser.h" + +EntityXMLFileParser::EntityXMLFileParser(const EntityXMLFile* entityFile) + : m_EntityFile(entityFile) +{ + m_Handler.SetStartEntityCallback(std::bind(&EntityXMLFileParser::onStartEntity, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + m_Handler.SetStartComponentCallback(std::bind(&EntityXMLFileParser::onStartComponent, this, std::placeholders::_1, std::placeholders::_2)); + m_Handler.SetStartFieldCallback(std::bind(&EntityXMLFileParser::onStartComponentField, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); + m_Handler.SetStartFieldDataCallback(std::bind(&EntityXMLFileParser::onFieldData, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); +} + +EntityID EntityXMLFileParser::MergeEntities(World* world, EntityID baseParent /*= EntityID_Invalid */) +{ + m_World = world; + m_EntityIDMapper[0] = baseParent; + m_EntityFile->Parse(&m_Handler); + return m_FirstEntity; +} + +void EntityXMLFileParser::onStartEntity(EntityID entity, EntityID parent, const std::string& name) +{ + EntityID realParent = m_EntityIDMapper.at(parent); + EntityID realEntity = m_World->CreateEntity(realParent); + if (m_FirstEntity == EntityID_Invalid) { + m_FirstEntity = realEntity; + } + if (!name.empty()) { + m_World->SetName(realEntity, name); + } + m_EntityIDMapper[entity] = realEntity; + //LOG_DEBUG("Created entity #%i (%i) with parent %i (%i)", entity, realEntity, parent, realParent); +} + +void EntityXMLFileParser::onStartComponent(EntityID entity, const std::string& component) +{ + if (m_World->GetComponentPools().count(component) != 0) { + EntityID realEntity = m_EntityIDMapper.at(entity); + m_World->AttachComponent(realEntity, component); + } else { + LOG_ERROR("Tried to attach unregistered component \"%s\"! to entity #%i. Ignoring.", component.c_str(), entity); + } + //LOG_DEBUG("Attached component of type \"%s\" to entity #%i (%i)", component.c_str(), entity, realEntity); +} + +void EntityXMLFileParser::onStartComponentField(EntityID entity, const std::string& componentType, const std::string& fieldName, const std::map& attributes) +{ + if (m_World->GetComponentPools().count(componentType) == 0) { + return; + } + EntityID realEntity = m_EntityIDMapper.at(entity); + ComponentWrapper component = m_World->GetComponent(realEntity, componentType); + auto fieldIt = component.Info.Fields.find(fieldName); + if (fieldIt == component.Info.Fields.end()) { + LOG_ERROR("Tried to set unknown field \"%s\" of component type \"%s\"! Ignoring.", fieldName.c_str(), componentType.c_str()); + return; + } + auto& field = fieldIt->second; + + //LOG_DEBUG("Field \"%s\" type \"%s\"", fieldName.c_str(), field.Type.c_str()); + //LOG_DEBUG("Attributes:"); + //for (auto& kv : attributes) { + // LOG_DEBUG("\t%s = %s", kv.first.c_str(), kv.second.c_str()); + //} + + char* data = component.Data + field.Offset; + EntityXMLFile::WriteAttributeData(data, field, attributes); +} + +void EntityXMLFileParser::onFieldData(EntityID entity, const std::string& componentType, const std::string& fieldName, const char* fieldData) +{ + if (m_World->GetComponentPools().count(componentType) == 0) { + return; + } + EntityID realEntity = m_EntityIDMapper.at(entity); + ComponentWrapper component = m_World->GetComponent(realEntity, componentType); + auto fieldIt = component.Info.Fields.find(fieldName); + if (fieldIt == component.Info.Fields.end()) { + return; + } + auto& field = fieldIt->second; + + char* data = component.Data + field.Offset; + EntityXMLFile::WriteValueData(data, field, fieldData); +} diff --git a/src/Engine/Core/EntityFilePreprocessor.cpp b/src/Engine/Core/EntityXMLFilePreprocessor.cpp similarity index 93% rename from src/Engine/Core/EntityFilePreprocessor.cpp rename to src/Engine/Core/EntityXMLFilePreprocessor.cpp index 592daedb..9695509d 100644 --- a/src/Engine/Core/EntityFilePreprocessor.cpp +++ b/src/Engine/Core/EntityXMLFilePreprocessor.cpp @@ -1,10 +1,10 @@ -#include "Core/EntityFilePreprocessor.h" +#include "Core/EntityXMLFilePreprocessor.h" -EntityFilePreprocessor::EntityFilePreprocessor(const EntityFile* entityFile) +EntityXMLFilePreprocessor::EntityXMLFilePreprocessor(const EntityXMLFile* entityFile) : m_EntityFile(entityFile) { EntityFileHandler handler; - handler.SetStartComponentCallback(std::bind(&EntityFilePreprocessor::onStartComponent, this, std::placeholders::_1, std::placeholders::_2)); + handler.SetStartComponentCallback(std::bind(&EntityXMLFilePreprocessor::onStartComponent, this, std::placeholders::_1, std::placeholders::_2)); m_EntityFile->Parse(&handler); //LOG_DEBUG("___ COMPONENT DEFINITIONS ___"); @@ -28,20 +28,20 @@ EntityFilePreprocessor::EntityFilePreprocessor(const EntityFile* entityFile) parseDefaults(); } -void EntityFilePreprocessor::RegisterComponents(World* world) +void EntityXMLFilePreprocessor::RegisterComponents(World* world) { for (auto& kv : m_ComponentInfo) { world->RegisterComponent(kv.second); } } -void EntityFilePreprocessor::onStartComponent(EntityID entity, std::string type) +void EntityXMLFilePreprocessor::onStartComponent(EntityID entity, std::string type) { //LOG_DEBUG("Component: %s", type.c_str()); m_ComponentCounts[type]++; } -void EntityFilePreprocessor::parseComponentInfo() +void EntityXMLFilePreprocessor::parseComponentInfo() { using namespace xercesc; EntityFileXMLErrorHandler errorHandler; @@ -141,9 +141,9 @@ void EntityFilePreprocessor::parseComponentInfo() std::string baseType = XS::ToString(elementDeclaration->getTypeDefinition()->getBaseType()->getName()); std::string effectiveType = type; - unsigned int stride = EntityFile::GetTypeStride(type); + unsigned int stride = EntityXMLFile::GetTypeStride(type); if (stride == 0) { - stride = EntityFile::GetTypeStride(baseType); + stride = EntityXMLFile::GetTypeStride(baseType); if (stride == 0) { LOG_WARNING("Field \"%s\" in component \"%s\" uses unexpected field type \"%s\" with base type \"%s\". Skipping.", name.c_str(), compInfo.Name.c_str(), type.c_str(), baseType.c_str()); continue; @@ -196,7 +196,7 @@ void EntityFilePreprocessor::parseComponentInfo() } } -void EntityFilePreprocessor::parseDefaults() +void EntityXMLFilePreprocessor::parseDefaults() { using namespace xercesc; @@ -261,7 +261,7 @@ void EntityFilePreprocessor::parseDefaults() auto attribItem = attributeMap->item(i); attributes[XS::ToString(attribItem->getNodeName())] = XS::ToString(attribItem->getNodeValue()); } - EntityFile::WriteAttributeData(data, field, attributes); + EntityXMLFile::WriteAttributeData(data, field, attributes); } auto childNode = fieldElement->getFirstChild(); @@ -278,14 +278,14 @@ void EntityFilePreprocessor::parseDefaults() // Handle potential field values if (childNode->getNodeType() == DOMNode::TEXT_NODE) { char* cstrValue = XMLString::transcode(childNode->getNodeValue()); - EntityFile::WriteValueData(data, field, cstrValue); + EntityXMLFile::WriteValueData(data, field, cstrValue); XMLString::release(&cstrValue); } } } } -std::string EntityFilePreprocessor::parseAnnotationXML(const XMLCh* xml) +std::string EntityXMLFilePreprocessor::parseAnnotationXML(const XMLCh* xml) { using namespace xercesc; diff --git a/src/Engine/Core/EntityFileWriter.cpp b/src/Engine/Core/EntityXMLFileWriter.cpp similarity index 94% rename from src/Engine/Core/EntityFileWriter.cpp rename to src/Engine/Core/EntityXMLFileWriter.cpp index 06a3c4ca..a98d3fbd 100644 --- a/src/Engine/Core/EntityFileWriter.cpp +++ b/src/Engine/Core/EntityXMLFileWriter.cpp @@ -1,13 +1,13 @@ -#include "Core/EntityFileWriter.h" +#include "Core/EntityXMLFileWriter.h" #define X(str) XS::ToXMLCh(str) -void EntityFileWriter::WriteWorld(World* world) +void EntityXMLFileWriter::WriteWorld(World* world) { WriteEntity(world, 0); } -void EntityFileWriter::WriteEntity(World* world, EntityID entity) +void EntityXMLFileWriter::WriteEntity(World* world, EntityID entity) { using namespace xercesc; DOMDocument* doc = m_DOMImplementation->createDocument(nullptr, X("Entity"), nullptr); @@ -41,7 +41,7 @@ void EntityFileWriter::WriteEntity(World* world, EntityID entity) doc->release(); } -void EntityFileWriter::appendEntityChildren(xercesc::DOMElement* parentElement, const World* world, EntityID entity) +void EntityXMLFileWriter::appendEntityChildren(xercesc::DOMElement* parentElement, const World* world, EntityID entity) { using namespace xercesc; DOMDocument* doc = parentElement->getOwnerDocument(); @@ -67,7 +67,7 @@ void EntityFileWriter::appendEntityChildren(xercesc::DOMElement* parentElement, } } -void EntityFileWriter::appentEntityComponents(xercesc::DOMElement* parentElement, const World* world, EntityID entity) +void EntityXMLFileWriter::appentEntityComponents(xercesc::DOMElement* parentElement, const World* world, EntityID entity) { using namespace xercesc; DOMDocument* doc = parentElement->getOwnerDocument(); diff --git a/src/Engine/Core/Util/Logging.cpp b/src/Engine/Core/Util/Logging.cpp index c7612fd8..63a6f380 100644 --- a/src/Engine/Core/Util/Logging.cpp +++ b/src/Engine/Core/Util/Logging.cpp @@ -33,8 +33,8 @@ void _LOG(_LOG_LEVEL logLevel, const char* file, const char* func, unsigned int va_end(args); if (logLevel == LOG_LEVEL_ERROR) { - //std::cerr << file << ":" << line << " " << func << std::endl; - //std::cerr << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl; + std::cerr << file << ":" << line << " " << func << std::endl; + std::cerr << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl; } else { std::cout << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl; } diff --git a/src/Engine/Core/World.cpp b/src/Engine/Core/World.cpp index 9b323ff4..0952a53b 100644 --- a/src/Engine/Core/World.cpp +++ b/src/Engine/Core/World.cpp @@ -1,6 +1,7 @@ #include "Core/World.h" #include "Core/EEntityDeleted.h" #include "Core/EComponentDeleted.h" +#include "Core/EntityWrapper.h" World::~World() { @@ -44,7 +45,7 @@ bool World::ValidEntity(EntityID entity) const return m_EntityParents.find(entity) != m_EntityParents.end(); } -void World::RegisterComponent(ComponentInfo& ci) +void World::RegisterComponent(const ComponentInfo& ci) { if (m_ComponentPools.find(ci.Name) == m_ComponentPools.end()) { m_ComponentPools[ci.Name] = new ComponentPool(ci); @@ -151,6 +152,62 @@ std::string World::GetName(EntityID entity) const } } +EntityWrapper World::GetFirstEntityByName(const std::string& name) +{ + auto itPair = GetDirectChildren(EntityID_Invalid); + for (auto it = itPair.first; it != itPair.second; it++) { + EntityID childEntityID = it->second; + EntityWrapper childEntity(this, childEntityID); + if (!childEntity.Valid()) { + continue; + } + EntityWrapper entityWithName = childEntity.Name() == name ? childEntity : childEntity.FirstChildByName(name); + if (entityWithName.Valid()) { + return entityWithName; + } + } + return EntityWrapper::Invalid; +} + +std::unordered_map World::Merge(const World* other) +{ + std::unordered_map oldToNew; + + // Create new entities + for (auto& kv : other->m_EntityParents) { + EntityID entity = kv.first; + + EntityID newEntity = CreateEntity(); + SetName(newEntity, other->GetName(entity)); + oldToNew[entity] = newEntity; + } + // Fix relationships + for (auto& kv : other->m_EntityParents) { + EntityID entity = kv.first; + EntityID parent = kv.second; + if (parent != EntityID_Invalid) { + SetParent(oldToNew.at(entity), oldToNew.at(parent)); + } + } + + // Transfer components + for (auto& kv : other->m_ComponentPools) { + auto& componentType = kv.first; + ComponentPool* pool = kv.second; + // Register pool if it's not present in world + if (m_ComponentPools.count(componentType) == 0) { + RegisterComponent(pool->ComponentInfo()); + } + // Copy components + for (auto component : *pool) { + ComponentWrapper newComponent = AttachComponent(oldToNew.at(component.EntityID), componentType); + component.Copy(newComponent); + } + } + + return oldToNew; +} + EntityID World::generateEntityID() { // TODO: Make EntityID generation smarter diff --git a/src/Engine/Editor/EditorGUI.cpp b/src/Engine/Editor/EditorGUI.cpp index f2690f13..8ce15d0a 100644 --- a/src/Engine/Editor/EditorGUI.cpp +++ b/src/Engine/Editor/EditorGUI.cpp @@ -580,6 +580,11 @@ void EditorGUI::createWidgetToolButton(WidgetMode mode) bool EditorGUI::OnKeyDown(const Events::KeyDown& e) { + ImGuiIO& io = ImGui::GetIO(); + if (io.WantCaptureKeyboard) { + return false; + } + if (e.ModCtrl && e.KeyCode == GLFW_KEY_S) { if (m_CurrentSelection.Valid()) { EntityWrapper baseParent = m_CurrentSelection; diff --git a/src/Engine/Editor/EditorRenderSystem.cpp b/src/Engine/Editor/EditorRenderSystem.cpp index 9a385e7d..f5fcc1a1 100644 --- a/src/Engine/Editor/EditorRenderSystem.cpp +++ b/src/Engine/Editor/EditorRenderSystem.cpp @@ -54,7 +54,7 @@ void EditorRenderSystem::Update(double dt) EntityWrapper entity(m_World, cModel.EntityID); glm::mat4 modelMatrix = Transform::ModelMatrix(entity.ID, entity.World); for (auto matGroup : model->MaterialGroups()) { - std::shared_ptr modelJob = std::make_shared(model, scene.Camera, modelMatrix, matGroup, cModel, entity.World, glm::vec4(0), 0.f); + std::shared_ptr modelJob = std::make_shared(model, scene.Camera, modelMatrix, matGroup, cModel, entity.World, glm::vec4(0), 0.f, false); if (cModel["Transparent"]) { scene.Jobs.TransparentObjects.push_back(modelJob); } else { diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 4bee1427..62ddba88 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -2,6 +2,7 @@ #include "Core/UniformScaleSystem.h" #include "Editor/EditorRenderSystem.h" #include "Editor/EditorWidgetSystem.h" +#include "Core/EntityFile.h" EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame* renderFrame) : System(params) @@ -129,7 +130,7 @@ void EditorSystem::OnEntitySelected(EntityWrapper entity) void EditorSystem::OnEntitySave(EntityWrapper entity, boost::filesystem::path filePath) { - EntityFileWriter writer(filePath); + EntityXMLFileWriter writer(filePath); writer.WriteEntity(entity.World, entity.ID); } @@ -260,12 +261,11 @@ EntityWrapper EditorSystem::importEntity(EntityWrapper parent, boost::filesystem try { auto entityFile = ResourceManager::Load(filePath.string()); - EntityFilePreprocessor fpp(entityFile); - fpp.RegisterComponents(parent.World); - EntityFileParser fp(entityFile); - EntityID newEntity = fp.MergeEntities(parent.World, parent.ID); - return EntityWrapper(parent.World, newEntity); - } catch (const std::exception&) { + EntityWrapper newEntity = entityFile->MergeInto(parent.World); + parent.World->SetParent(newEntity.ID, parent.ID); + return newEntity; + } catch (const std::exception& e) { + LOG_ERROR("Failed to import entity \"%s\": \"%s\"", filePath.string().c_str(), e.what()); return EntityWrapper::Invalid; } } diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index d8da7e16..d666e550 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -33,6 +33,7 @@ void Client::Connect(std::string address, int port) EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Client::OnPlayerDamage); EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Client::OnPlayerSpawned); EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &Client::OnDoubleJump); + EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &Client::OnDashAbility); EVENT_SUBSCRIBE_MEMBER(m_ESearchForServers, &Client::OnSearchForServers); auto config = ResourceManager::Load("Config.ini"); m_Address = address; @@ -101,8 +102,7 @@ void Client::Update() void Client::parseMessageType(Packet& packet) { - // Pop packetSize which is used by TCP Client to - // create a packet of the correct size + // Pop packetSize packet.ReadPrimitive(); int messageType = packet.ReadPrimitive(); if (messageType == -1) @@ -144,6 +144,12 @@ void Client::parseMessageType(Packet& packet) case MessageType::OnDoubleJump: parseDoubleJump(packet); break; + case MessageType::OnDashEffect: + parseDashEffect(packet); + break; + case MessageType::AmmoPickup: + parseAmmoPickup(packet); + break; default: break; } @@ -233,7 +239,6 @@ void Client::parseSpawnEvents() m_EventBroker->Publish(e); } m_PlayerSpawnEvents = tempSpawn; - // m_PlayerSpawnEvents.clear(); } void Client::parsePlayersSpawned(Packet& packet) @@ -261,7 +266,7 @@ void Client::parseEntityDeletion(Packet & packet) if (m_ServerIDToClientID.find(entityToDelete) != m_ServerIDToClientID.end()) { EntityID localEntity = m_ServerIDToClientID.at(entityToDelete); if (m_World->ValidEntity(localEntity)) { - if (m_World->HasComponent(localEntity,"Player")) { + if (m_World->HasComponent(localEntity, "Player")) { Events::PlayerDeath e; e.Player = EntityWrapper(m_World, localEntity); m_EventBroker->Publish(e); @@ -296,6 +301,28 @@ void Client::parseDoubleJump(Packet & packet) } } + +void Client::parseDashEffect(Packet& packet) +{ + EntityID serverID = packet.ReadPrimitive(); + if (!serverClientMapsHasEntity(serverID)) { + return; + } + Events::DashAbility e; + e.Player = m_ServerIDToClientID.at(serverID); + if (e.Player != m_LocalPlayer.ID) { + m_EventBroker->Publish(e); + } +} + +void Client::parseAmmoPickup(Packet & packet) +{ + Events::AmmoPickup e; + e.AmmoGain = packet.ReadPrimitive(); + e.Player = m_LocalPlayer; + m_EventBroker->Publish(e); +} + void Client::updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID) { for (auto field : componentInfo.FieldsInOrder) { @@ -379,7 +406,7 @@ void Client::parseSnapshot(Packet& packet) if (m_SnapshotFilter != nullptr) { shouldApply = m_SnapshotFilter->FilterComponent(localEntity, newComponent); } - if (shouldApply) { + if (shouldApply) { ComponentWrapper currentComponent = m_World->GetComponent(localEntityID, componentType); memcpy(currentComponent.Data, newComponent.Data, componentInfo.Stride); } @@ -509,6 +536,18 @@ bool Client::OnPlayerSpawned(const Events::PlayerSpawned& e) return true; } + +bool Client::OnDashAbility(const Events::DashAbility& e) +{ + if (!clientServerMapsHasEntity(e.Player) || e.Player != m_LocalPlayer.ID) { + return false; + } + Packet packet(MessageType::OnDashEffect); + packet.WritePrimitive(m_ClientIDToServerID.at(e.Player)); + m_Reliable.Send(packet); + return true; +} + bool Client::OnSearchForServers(const Events::SearchForServers& e) { m_SearchingForServers = true; diff --git a/src/Engine/Network/Packet.cpp b/src/Engine/Network/Packet.cpp index 475ca673..6a4d0098 100644 --- a/src/Engine/Network/Packet.cpp +++ b/src/Engine/Network/Packet.cpp @@ -49,18 +49,24 @@ void Packet::WriteString(const std::string& str) // Message, add one extra byte for null terminator size_t sizeOfString = str.size() + 1; if (m_Offset + sizeOfString > m_MaxPacketSize) { - //LOG_WARNING("Package::WriteString(): Data size in packet exceeded maximum package size. New size is %i bytes\n", m_MaxPacketSize*2); + if (m_MaxPacketSize >= 32000) { + LOG_WARNING("Package::WriteString(): New size is huge %i bytes\n", m_MaxPacketSize*2); + } resizeData(); } - memcpy(m_Data + m_Offset, str.data(), sizeOfString * sizeof(char)); - m_Offset += sizeOfString * sizeof(char); + memcpy(m_Data + m_Offset, str.data(), str.size() * sizeof(char)); + m_Offset += str.size() * sizeof(char); + m_Data[m_Offset] = '\0'; + m_Offset += 1; } void Packet::WriteData(char * data, int sizeOfData) { if (m_Offset + sizeOfData > m_MaxPacketSize) { - //LOG_WARNING("Packet::WriteData(): Data size in packet exceeded maximum packet size. New size is %i bytes\n", m_MaxPacketSize*2); + if (m_MaxPacketSize >= 32000) { + LOG_WARNING("Package::WriteData(): New size is huge %i bytes\n", m_MaxPacketSize*2); + } while (m_Offset + sizeOfData > m_MaxPacketSize) { resizeData(); } diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 7c614cee..68c00fbe 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -13,7 +13,7 @@ Server::Server(World* world, EventBroker* eventBroker, int port) EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &Server::OnEntityDeleted); EVENT_SUBSCRIBE_MEMBER(m_EComponentDeleted, &Server::OnComponentDeleted); EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Server::OnPlayerDamage); - + EVENT_SUBSCRIBE_MEMBER(m_EAmmoPickup, &Server::OnAmmoPickup); // BindWW if (port == 0) { port = config->Get("Networking.Port", 27666); @@ -141,6 +141,9 @@ void Server::parseMessageType(Packet& packet) case MessageType::OnDoubleJump: parseDoubleJump(packet); break; + case MessageType::OnDashEffect: + parseDashEffect(packet); + break; default: break; } @@ -510,6 +513,19 @@ bool Server::OnPlayerDamage(const Events::PlayerDamage& e) return true; } +bool Server::OnAmmoPickup(const Events::AmmoPickup & e) +{ + for (auto& kv : m_ConnectedPlayers) { + if (e.Player.ID == kv.second.EntityID) { + Packet packet(MessageType::AmmoPickup); + // We dont send playerID as it will be set at client to local + packet.WritePrimitive(e.AmmoGain); + m_Reliable.Send(packet, kv.second); + } + } + return true; +} + void Server::parseClientPing() { LOG_INFO("%i: Parsing ping", m_PacketID); @@ -542,6 +558,11 @@ bool Server::parseDoubleJump(Packet & packet) return true; } +void Server::parseDashEffect(Packet& packet) +{ + reliableBroadcast(packet); +} + void Server::parseOnInputCommand(Packet& packet) { PlayerID player = -1; @@ -604,12 +625,14 @@ bool Server::shouldSendToClient(EntityWrapper childEntity) auto children = m_World->GetDirectChildren(childEntity.ID); for (auto it = children.first; it != children.second; it++) { EntityWrapper child(m_World, it->second); - if(child.HasComponent("CapturePoint")) { + if (child.HasComponent("CapturePoint") || child.HasComponent("HealthPickup") + || child.HasComponent("AmmoPickup")) { return true; } } return childEntity.HasComponent("Player") || childEntity.FirstParentWithComponent("Player").Valid() - || childEntity.HasComponent("CapturePoint"); + || childEntity.HasComponent("CapturePoint") || childEntity.HasComponent("HealthPickup") + || childEntity.HasComponent("AmmoPickup"); } PlayerID Server::GetPlayerIDFromEndpoint() diff --git a/src/Engine/Network/TCPClient.cpp b/src/Engine/Network/TCPClient.cpp index f3394d3d..8bfa9ded 100644 --- a/src/Engine/Network/TCPClient.cpp +++ b/src/Engine/Network/TCPClient.cpp @@ -74,7 +74,10 @@ size_t TCPClient::readBuffer() boost::asio::ip::tcp::socket::message_peek, error); unsigned int sizeOfPacket = 0; memcpy(&sizeOfPacket, m_ReadBuffer, sizeof(int)); - + if (sizeOfPacket > m_Socket->available()) { + LOG_WARNING("TCPClient::readBuffer(): We haven't got the whole packet yet."); + return 0; + } // if the buffer is to small increase the size of it // TODO if message is huge 1 time the buffer will not decrease. if (sizeOfPacket > m_BufferSize) { diff --git a/src/Engine/Network/TCPServer.cpp b/src/Engine/Network/TCPServer.cpp index acd3d6d0..ff35aa91 100644 --- a/src/Engine/Network/TCPServer.cpp +++ b/src/Engine/Network/TCPServer.cpp @@ -106,7 +106,10 @@ int TCPServer::readBuffer(PlayerDefinition & playerDefinition) boost::asio::ip::tcp::socket::message_peek, error); unsigned int sizeOfPacket = 0; memcpy(&sizeOfPacket, m_ReadBuffer, sizeof(int)); - + if (sizeOfPacket > playerDefinition.TCPSocket->available()) { + LOG_WARNING("TCPServer::readBuffer(): We haven't got the whole packet yet."); + return 0; + } // if the buffer is to small increase the size of it if (sizeOfPacket > m_BufferSize) { delete[] m_ReadBuffer; diff --git a/src/Engine/Network/UDPClient.cpp b/src/Engine/Network/UDPClient.cpp index 51c29920..a7061884 100644 --- a/src/Engine/Network/UDPClient.cpp +++ b/src/Engine/Network/UDPClient.cpp @@ -45,7 +45,10 @@ int UDPClient::readBuffer() boost::asio::ip::udp::socket::message_peek, error); int sizeOfPacket = 0; memcpy(&sizeOfPacket, m_ReadBuffer, sizeof(int)); - + if (sizeOfPacket > m_Socket->available()) { + LOG_WARNING("UDPClient::readBuffer(): We haven't got the whole packet yet."); + return 0; + } // if the buffer is to small increase the size of it if (sizeOfPacket > m_BufferSize) { delete[] m_ReadBuffer; diff --git a/src/Engine/Network/UDPServer.cpp b/src/Engine/Network/UDPServer.cpp index 635ebd4d..13dd5ccd 100644 --- a/src/Engine/Network/UDPServer.cpp +++ b/src/Engine/Network/UDPServer.cpp @@ -92,6 +92,11 @@ int UDPServer::readBuffer() unsigned int sizeOfPacket = 0; memcpy(&sizeOfPacket, m_ReadBuffer, sizeof(int)); + if (sizeOfPacket > m_Socket->available()) { + LOG_WARNING("UDPServer::readBuffer(): We haven't got the whole packet yet."); + return 0; + } + // if the buffer is to small increase the size of it if (sizeOfPacket > m_BufferSize) { delete[] m_ReadBuffer; diff --git a/src/Engine/Rendering/DrawBloomPass.cpp b/src/Engine/Rendering/DrawBloomPass.cpp index e8ad4cd5..12777941 100644 --- a/src/Engine/Rendering/DrawBloomPass.cpp +++ b/src/Engine/Rendering/DrawBloomPass.cpp @@ -1,19 +1,41 @@ #include "Rendering/DrawBloomPass.h" -DrawBloomPass::DrawBloomPass(IRenderer* renderer) +DrawBloomPass::DrawBloomPass(IRenderer* renderer, ConfigFile* config) + : m_Renderer(renderer) + , m_Config(config) { - m_Renderer = renderer; + InitializeTextures(); - m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.mesh"); - - InitializeTextures(); - InitializeBuffers(); - InitializeShaderPrograms(); + ChangeQuality(m_Config->Get("GLOW.Quality", 2)); } void DrawBloomPass::InitializeTextures() { - m_WhiteTexture = CommonFunctions::LoadTexture("Textures/Core/White.png", false); + m_BlackTexture = CommonFunctions::LoadTexture("Textures/Core/Black.png", false); +} + +void DrawBloomPass::ChangeQuality(int quality) +{ + if (m_Quality == quality) { + return; + } + m_Quality = quality; + + m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.mesh"); + + if (m_Quality == 0) { + CommonFunctions::DeleteTexture(&m_GaussianTexture_horiz); + CommonFunctions::DeleteTexture(&m_GaussianTexture_vert); + m_GaussianTexture_horiz = 0; + m_GaussianTexture_vert = 0; + return; + } + InitializeTextures(); + + InitializeBuffers(); + InitializeShaderPrograms(); + std::string qStr = std::to_string(m_Quality); + m_Iterations = m_Config->Get("GLOW" + qStr + ".NumIterations", 0); } void DrawBloomPass::InitializeShaderPrograms() @@ -35,37 +57,45 @@ void DrawBloomPass::InitializeShaderPrograms() } } - void DrawBloomPass::InitializeBuffers() { - GenerateTexture(&m_GaussianTexture_horiz, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); + CommonFunctions::GenerateTexture(&m_GaussianTexture_horiz, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); - m_GaussianFrameBuffer_horiz.AddResource(std::shared_ptr(new Texture2D(&m_GaussianTexture_horiz, GL_COLOR_ATTACHMENT0))); - m_GaussianFrameBuffer_horiz.Generate(); + if (m_GaussianFrameBuffer_horiz.GetHandle() == 0) { + m_GaussianFrameBuffer_horiz.AddResource(std::shared_ptr(new Texture2D(&m_GaussianTexture_horiz, GL_COLOR_ATTACHMENT0))); + } + m_GaussianFrameBuffer_horiz.Generate(); - GenerateTexture(&m_GaussianTexture_vert, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); - - m_GaussianFrameBuffer_vert.AddResource(std::shared_ptr(new Texture2D(&m_GaussianTexture_vert, GL_COLOR_ATTACHMENT0))); - m_GaussianFrameBuffer_vert.Generate(); + CommonFunctions::GenerateTexture(&m_GaussianTexture_vert, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); + if (m_GaussianFrameBuffer_vert.GetHandle() == 0) { + m_GaussianFrameBuffer_vert.AddResource(std::shared_ptr(new Texture2D(&m_GaussianTexture_vert, GL_COLOR_ATTACHMENT0))); + } + m_GaussianFrameBuffer_vert.Generate(); } void DrawBloomPass::ClearBuffer() { + if (m_Quality == 0) { + return; + } GLERROR("PRE"); m_GaussianFrameBuffer_horiz.Bind(); glClearColor(0.f, 0.f, 0.f, 0.f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT); m_GaussianFrameBuffer_horiz.Unbind(); m_GaussianFrameBuffer_vert.Bind(); glClearColor(0.f, 0.f, 0.f, 0.f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT); m_GaussianFrameBuffer_vert.Unbind(); GLERROR("END"); } void DrawBloomPass::Draw(GLuint texture) { + if (m_Quality == 0) { + return; + } GLERROR("DrawBloomPass::Draw: Pre"); DrawBloomPassState state; @@ -84,11 +114,12 @@ void DrawBloomPass::Draw(GLuint texture) glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1 , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); //Iterate some times to make it more gaussian. - for (int i = 1; i < m_iterations; i++) { + for (int i = 1; i < m_Iterations; i++) { //Vertical pass m_GaussianFrameBuffer_vert.Bind(); m_GaussianProgram_vert->Bind(); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_GaussianTexture_horiz); glBindVertexArray(m_ScreenQuad->VAO); @@ -96,16 +127,19 @@ void DrawBloomPass::Draw(GLuint texture) glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1 , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); //horizontal pass + m_GaussianFrameBuffer_vert.Unbind(); m_GaussianFrameBuffer_horiz.Bind(); m_GaussianProgram_horiz->Bind(); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_GaussianTexture_vert); glBindVertexArray(m_ScreenQuad->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1 , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); + m_GaussianFrameBuffer_horiz.Unbind(); } //final vertical gaussian after the iterations are done @@ -113,6 +147,7 @@ void DrawBloomPass::Draw(GLuint texture) m_GaussianFrameBuffer_vert.Bind(); m_GaussianProgram_vert->Bind(); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_GaussianTexture_horiz); glBindVertexArray(m_ScreenQuad->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); @@ -125,20 +160,11 @@ void DrawBloomPass::Draw(GLuint texture) void DrawBloomPass::OnWindowResize() { - GenerateTexture(&m_GaussianTexture_vert, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); + if (m_Quality == 0) { + return; + } + CommonFunctions::GenerateTexture(&m_GaussianTexture_vert, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); m_GaussianFrameBuffer_vert.Generate(); - GenerateTexture(&m_GaussianTexture_horiz, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); + CommonFunctions::GenerateTexture(&m_GaussianTexture_horiz, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); m_GaussianFrameBuffer_horiz.Generate(); } - -void DrawBloomPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const -{ - glGenTextures(1, texture); - glBindTexture(GL_TEXTURE_2D, *texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); - glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, dimensions.x, dimensions.y, 0, format, type, nullptr);//TODO: Renderer: Fix the precision and Resolution - GLERROR("Texture initialization failed"); -} diff --git a/src/Engine/Rendering/DrawColorCorrectionPass.cpp b/src/Engine/Rendering/DrawColorCorrectionPass.cpp index c82d614f..70d3a053 100644 --- a/src/Engine/Rendering/DrawColorCorrectionPass.cpp +++ b/src/Engine/Rendering/DrawColorCorrectionPass.cpp @@ -18,7 +18,7 @@ void DrawColorCorrectionPass::InitializeShaderPrograms() m_ColorCorrectionProgram->Link(); } -void DrawColorCorrectionPass::Draw(GLuint sceneTexture, GLuint bloomTexture, GLuint sceneTextureLowRes, GLuint bloomTextureLowRes, GLfloat gamma, GLfloat exposure) +void DrawColorCorrectionPass::Draw(GLuint sceneTexture, GLuint bloomTexture, GLfloat gamma, GLfloat exposure) { //glBindFramebuffer(GL_FRAMEBUFFER, 0); GLERROR("DrawScreenQuadPass::Draw: Pre"); @@ -33,10 +33,6 @@ void DrawColorCorrectionPass::Draw(GLuint sceneTexture, GLuint bloomTexture, GLu glBindTexture(GL_TEXTURE_2D, sceneTexture); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, bloomTexture); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, sceneTextureLowRes); - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, bloomTextureLowRes); glBindVertexArray(m_ScreenQuad->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 6cd2c1f1..6cdf42d1 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -1,9 +1,9 @@ #include "Rendering/DrawFinalPass.h" - -DrawFinalPass::DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass, CubeMapPass* cubeMapPass) - : m_Renderer(renderer) - , m_LightCullingPass(lightCullingPass) - , m_CubeMapPass(cubeMapPass) +DrawFinalPass::DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCullingPass, CubeMapPass* cubeMapPass, SSAOPass* ssaoPass) + : m_Renderer(renderer) + , m_LightCullingPass(lightCullingPass) + , m_CubeMapPass(cubeMapPass) + , m_SSAOPass(ssaoPass) { //TODO: Make sure that uniforms are not sent into shader if not needed. m_ShieldPixelRate = 8; @@ -23,42 +23,26 @@ void DrawFinalPass::InitializeTextures() void DrawFinalPass::InitializeFrameBuffers() { - glGenRenderbuffers(1, &m_DepthBuffer); - glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); - GLERROR("RenderBuffer generation"); - - - GenerateTexture(&m_SceneTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); + CommonFunctions::GenerateTexture(&m_SceneTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); //GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); - GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); + CommonFunctions::GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); //GenerateMipMapTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, glm::vec2(m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height), GL_RGB16F, GL_FLOAT, 4); //GenerateTexture(&m_StencilTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_STENCIL, GL_STENCIL_INDEX8, GL_INT); - m_FinalPassFrameBuffer.AddResource(std::shared_ptr(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_STENCIL_ATTACHMENT))); + CommonFunctions::GenerateTexture(&m_DepthBuffer, GL_CLAMP_TO_BORDER, GL_NEAREST, + glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8); + + m_FinalPassFrameBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthBuffer, GL_DEPTH_STENCIL_ATTACHMENT))); //m_FinalPassFrameBuffer.AddResource(std::shared_ptr(new Texture2D(&m_StencilTexture, GL_STENCIL_ATTACHMENT))); m_FinalPassFrameBuffer.AddResource(std::shared_ptr(new Texture2D(&m_SceneTexture, GL_COLOR_ATTACHMENT0))); m_FinalPassFrameBuffer.AddResource(std::shared_ptr(new Texture2D(&m_BloomTexture, GL_COLOR_ATTACHMENT1))); m_FinalPassFrameBuffer.Generate(); GLERROR("FBO generation"); - glGenRenderbuffers(1, &m_DepthBufferLowRes); - glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBufferLowRes); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, (int)(m_Renderer->GetViewportSize().Width/m_ShieldPixelRate), (int)(m_Renderer->GetViewportSize().Height/m_ShieldPixelRate)); - GLERROR("RenderBufferLowRes generation"); - - GenerateTexture(&m_SceneTextureLowRes, GL_CLAMP_TO_EDGE, GL_NEAREST, glm::vec2((int)(m_Renderer->GetViewportSize().Width/m_ShieldPixelRate), (int)(m_Renderer->GetViewportSize().Height/m_ShieldPixelRate)), GL_RGB16F, GL_RGB, GL_FLOAT); - //GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); - GenerateTexture(&m_BloomTextureLowRes, GL_CLAMP_TO_EDGE, GL_NEAREST, glm::vec2((int)(m_Renderer->GetViewportSize().Width/m_ShieldPixelRate), (int)(m_Renderer->GetViewportSize().Height/m_ShieldPixelRate)), GL_RGB16F, GL_RGB, GL_FLOAT); - //GenerateMipMapTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, glm::vec2(m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height), GL_RGB16F, GL_FLOAT, 4); - //GenerateTexture(&m_StencilTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_STENCIL, GL_STENCIL_INDEX8, GL_INT); - - m_FinalPassFrameBufferLowRes.AddResource(std::shared_ptr(new RenderBuffer(&m_DepthBufferLowRes, GL_DEPTH_STENCIL_ATTACHMENT))); - //m_FinalPassFrameBufferLowRes.AddResource(std::shared_ptr(new Texture2D(&m_StencilTexture, GL_STENCIL_ATTACHMENT))); - m_FinalPassFrameBufferLowRes.AddResource(std::shared_ptr(new Texture2D(&m_SceneTextureLowRes, GL_COLOR_ATTACHMENT0))); - m_FinalPassFrameBufferLowRes.AddResource(std::shared_ptr(new Texture2D(&m_BloomTextureLowRes, GL_COLOR_ATTACHMENT1))); - m_FinalPassFrameBufferLowRes.Generate(); - GLERROR("FBO2 generation"); + CommonFunctions::GenerateTexture(&m_ShieldBuffer, GL_CLAMP_TO_BORDER, GL_NEAREST, + glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT); + m_ShieldDepthFrameBuffer.AddResource(std::shared_ptr(new Texture2D(&m_ShieldBuffer, GL_DEPTH_ATTACHMENT))); + m_ShieldDepthFrameBuffer.Generate(); } void DrawFinalPass::InitializeShaderPrograms() @@ -90,6 +74,7 @@ void DrawFinalPass::InitializeShaderPrograms() m_SpriteProgram->BindFragDataLocation(1, "bloomColor"); m_SpriteProgram->Link(); GLERROR("Creating sprite program"); + m_ForwardPlusSplatMapProgram = ResourceManager::Load("#ForwardPlusSplatMapProgram"); m_ForwardPlusSplatMapProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlus.vert.glsl"))); m_ForwardPlusSplatMapProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusSplatMapRGB.frag.glsl"))); @@ -145,40 +130,120 @@ void DrawFinalPass::InitializeShaderPrograms() m_ForwardPlusSplatMapSkinnedProgram->BindFragDataLocation(1, "bloomColor"); m_ForwardPlusSplatMapSkinnedProgram->Link(); GLERROR("Creating Forward SplatMap Skinned program"); + + m_FillDepthStencilBufferProgram = ResourceManager::Load("#FillDepthBufferProgram"); + m_FillDepthStencilBufferProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/FillDepthBuffer.vert.glsl"))); + m_FillDepthStencilBufferProgram->Compile(); + m_FillDepthStencilBufferProgram->Link(); + GLERROR("Creating DepthFill program"); + + m_FillDepthStencilBufferSkinnedProgram = ResourceManager::Load("#FillDepthBufferProgramSkinned"); + m_FillDepthStencilBufferSkinnedProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/FillDepthBufferSkinned.vert.glsl"))); + m_FillDepthStencilBufferSkinnedProgram->Compile(); + m_FillDepthStencilBufferSkinnedProgram->Link(); + GLERROR("Creating DepthFill program"); + + + + + + m_ForwardPlusShieldCheckProgram = ResourceManager::Load("#ForwardPlusShieldCheckProgram"); + m_ForwardPlusShieldCheckProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlus.vert.glsl"))); + m_ForwardPlusShieldCheckProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusShieldCheck.frag.glsl"))); + m_ForwardPlusShieldCheckProgram->Compile(); + m_ForwardPlusShieldCheckProgram->BindFragDataLocation(0, "sceneColor"); + m_ForwardPlusShieldCheckProgram->BindFragDataLocation(1, "bloomColor"); + m_ForwardPlusShieldCheckProgram->Link(); + GLERROR("Creating forward+ program"); + + m_ExplosionEffectShieldCheckProgram = ResourceManager::Load("#ExplosionEffectShieldCheckProgram"); + m_ExplosionEffectShieldCheckProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlus.vert.glsl"))); + m_ExplosionEffectShieldCheckProgram->AddShader(std::shared_ptr(new GeometryShader("Shaders/ExplosionEffect.geom.glsl"))); + m_ExplosionEffectShieldCheckProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusShieldCheck.frag.glsl"))); + m_ExplosionEffectShieldCheckProgram->Compile(); + m_ExplosionEffectShieldCheckProgram->BindFragDataLocation(0, "sceneColor"); + m_ExplosionEffectShieldCheckProgram->BindFragDataLocation(1, "bloomColor"); + m_ExplosionEffectShieldCheckProgram->Link(); + GLERROR("Creating explosion program"); + + m_SpriteShieldCheckProgram = ResourceManager::Load("#SpriteShieldCheckProgram"); + m_SpriteShieldCheckProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/Sprite.vert.glsl"))); + m_SpriteShieldCheckProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/SpriteShieldCheck.frag.glsl"))); + m_SpriteShieldCheckProgram->Compile(); + m_SpriteShieldCheckProgram->BindFragDataLocation(0, "sceneColor"); + m_SpriteShieldCheckProgram->BindFragDataLocation(1, "bloomColor"); + m_SpriteShieldCheckProgram->Link(); + GLERROR("Creating sprite program"); + + m_ForwardPlusSplatMapShieldCheckProgram = ResourceManager::Load("#ForwardPlusSplatMapShieldCheckProgram"); + m_ForwardPlusSplatMapShieldCheckProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlus.vert.glsl"))); + m_ForwardPlusSplatMapShieldCheckProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusSplatMapRGBShieldCheck.frag.glsl"))); + m_ForwardPlusSplatMapShieldCheckProgram->Compile(); + m_ForwardPlusSplatMapShieldCheckProgram->BindFragDataLocation(0, "sceneColor"); + m_ForwardPlusSplatMapShieldCheckProgram->BindFragDataLocation(1, "bloomColor"); + m_ForwardPlusSplatMapShieldCheckProgram->Link(); + GLERROR("Creating Forward SplatMap program"); + + m_ExplosionEffectSplatMapShieldCheckProgram = ResourceManager::Load("#ExplosionEffectSplatMapShieldCheckProgram"); + m_ExplosionEffectSplatMapShieldCheckProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlus.vert.glsl"))); + m_ExplosionEffectSplatMapShieldCheckProgram->AddShader(std::shared_ptr(new GeometryShader("Shaders/ExplosionEffect.geom.glsl"))); + m_ExplosionEffectSplatMapShieldCheckProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusSplatMapRGBShieldCheck.frag.glsl"))); + m_ExplosionEffectSplatMapShieldCheckProgram->Compile(); + m_ExplosionEffectSplatMapShieldCheckProgram->BindFragDataLocation(0, "sceneColor"); + m_ExplosionEffectSplatMapShieldCheckProgram->BindFragDataLocation(1, "bloomColor"); + m_ExplosionEffectSplatMapShieldCheckProgram->Link(); + GLERROR("Creating explosion SplatMap program"); + + m_ForwardPlusSkinnedShieldCheckProgram = ResourceManager::Load("#ForwardPlusSkinnedShieldCheckProgram"); + m_ForwardPlusSkinnedShieldCheckProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlusSkinned.vert.glsl"))); + m_ForwardPlusSkinnedShieldCheckProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusShieldCheck.frag.glsl"))); + m_ForwardPlusSkinnedShieldCheckProgram->Compile(); + m_ForwardPlusSkinnedShieldCheckProgram->BindFragDataLocation(0, "sceneColor"); + m_ForwardPlusSkinnedShieldCheckProgram->BindFragDataLocation(1, "bloomColor"); + m_ForwardPlusSkinnedShieldCheckProgram->Link(); + GLERROR("Creating forward+ Skinned program"); + + m_ExplosionEffectSkinnedShieldCheckProgram = ResourceManager::Load("#ExplosionEffectSkinnedShieldCheckProgram"); + m_ExplosionEffectSkinnedShieldCheckProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlusSkinned.vert.glsl"))); + m_ExplosionEffectSkinnedShieldCheckProgram->AddShader(std::shared_ptr(new GeometryShader("Shaders/ExplosionEffect.geom.glsl"))); + m_ExplosionEffectSkinnedShieldCheckProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusShieldCheck.frag.glsl"))); + m_ExplosionEffectSkinnedShieldCheckProgram->Compile(); + m_ExplosionEffectSkinnedShieldCheckProgram->BindFragDataLocation(0, "sceneColor"); + m_ExplosionEffectSkinnedShieldCheckProgram->BindFragDataLocation(1, "bloomColor"); + m_ExplosionEffectSkinnedShieldCheckProgram->Link(); + GLERROR("Creating explosion Skinned program"); + + m_ExplosionEffectSplatMapSkinnedShieldCheckProgram = ResourceManager::Load("#ExplosionEffectSplatMapSkinnedShieldCheckProgram"); + m_ExplosionEffectSplatMapSkinnedShieldCheckProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlusSkinned.vert.glsl"))); + m_ExplosionEffectSplatMapSkinnedShieldCheckProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusSplatMapRGBShieldCheck.frag.glsl"))); + m_ExplosionEffectSplatMapSkinnedShieldCheckProgram->Compile(); + m_ExplosionEffectSplatMapSkinnedShieldCheckProgram->BindFragDataLocation(0, "sceneColor"); + m_ExplosionEffectSplatMapSkinnedShieldCheckProgram->BindFragDataLocation(1, "bloomColor"); + m_ExplosionEffectSplatMapSkinnedShieldCheckProgram->Link(); + GLERROR("Creating Forward SplatMap Skinned program"); + + m_ForwardPlusSplatMapSkinnedShieldCheckProgram = ResourceManager::Load("#ForwardPlusSplatMapSkinnedShieldCheckProgram"); + m_ForwardPlusSplatMapSkinnedShieldCheckProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlusSkinned.vert.glsl"))); + m_ForwardPlusSplatMapSkinnedShieldCheckProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusSplatMapRGBShieldCheck.frag.glsl"))); + m_ForwardPlusSplatMapSkinnedShieldCheckProgram->Compile(); + m_ForwardPlusSplatMapSkinnedShieldCheckProgram->BindFragDataLocation(0, "sceneColor"); + m_ForwardPlusSplatMapSkinnedShieldCheckProgram->BindFragDataLocation(1, "bloomColor"); + m_ForwardPlusSplatMapSkinnedShieldCheckProgram->Link(); + GLERROR("Creating Forward SplatMap Skinned program"); - m_ShieldToStencilProgram = ResourceManager::Load("#ShieldToStencilProgram"); - m_ShieldToStencilProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ShieldStencil.vert.glsl"))); - m_ShieldToStencilProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ShieldStencil.frag.glsl"))); - m_ShieldToStencilProgram->Compile(); - m_ShieldToStencilProgram->Link(); - GLERROR("Creating Shield program"); - - m_ShieldToStencilSkinnedProgram = ResourceManager::Load("#ShieldToStencilProgramSkinned"); - m_ShieldToStencilSkinnedProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ShieldStencilSkinned.vert.glsl"))); - m_ShieldToStencilSkinnedProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ShieldStencil.frag.glsl"))); - m_ShieldToStencilSkinnedProgram->Compile(); - m_ShieldToStencilSkinnedProgram->Link(); - GLERROR("Creating Shield Skinned program"); - - m_FillDepthBufferProgram = ResourceManager::Load("#FillDepthBufferProgram"); - m_FillDepthBufferProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/FillDepthBuffer.vert.glsl"))); - m_FillDepthBufferProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/FillDepthBuffer.frag.glsl"))); - m_FillDepthBufferProgram->Compile(); - m_FillDepthBufferProgram->Link(); - GLERROR("Creating DepthFill program"); - - m_FillDepthBufferSkinnedProgram = ResourceManager::Load("#FillDepthBufferProgramSkinned"); - m_FillDepthBufferSkinnedProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/FillDepthBufferSkinned.vert.glsl"))); - m_FillDepthBufferSkinnedProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/FillDepthBuffer.frag.glsl"))); - m_FillDepthBufferSkinnedProgram->Compile(); - m_FillDepthBufferSkinnedProgram->Link(); - GLERROR("Creating DepthFill program"); } -void DrawFinalPass::Draw(RenderScene& scene, GLuint SSAOTexture) +void DrawFinalPass::Draw(RenderScene& scene) { GLERROR("Pre"); - DrawFinalPassState* state = new DrawFinalPassState(m_FinalPassFrameBuffer.GetHandle()); + DrawFinalPassState* stateDethp = new DrawFinalPassState(m_ShieldDepthFrameBuffer.GetHandle()); + //Draw shields to stencil + DrawToDepthStencilBuffer(scene.Jobs.ShieldObjects, scene); + GLERROR("StencilPass"); + delete stateDethp; + + + DrawFinalPassState* state = new DrawFinalPassState(m_FinalPassFrameBuffer.GetHandle()); if (scene.ClearDepth) { //glClear(GL_DEPTH_BUFFER_BIT); state->Disable(GL_DEPTH_TEST); @@ -189,99 +254,53 @@ void DrawFinalPass::Draw(RenderScene& scene, GLuint SSAOTexture) glClear(GL_STENCIL_BUFFER_BIT); //Fill depth buffer - - state->StencilMask(0x00); - DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene, SSAOTexture); - GLERROR("OpaqueObjects"); - state->BlendFunc(GL_ONE, GL_ONE); - DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene, SSAOTexture); - GLERROR("TransparentObjects"); - state->BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - DrawSprites(scene.Jobs.SpriteJob, scene); - GLERROR("SpriteJobs"); - - //DrawStencilState* stencilState = new DrawStencilState(m_FinalPassFrameBuffer.GetHandle()); - //Draw shields to stencil pass - state->StencilFunc(GL_ALWAYS, 1, 0xFF); - state->StencilMask(0xFF); - DrawShieldToStencilBuffer(scene.Jobs.ShieldObjects, scene); - GLERROR("StencilPass"); + state->Enable(GL_STENCIL_TEST); + state->StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + state->StencilFunc(GL_ALWAYS, 1, 0xFF); + state->StencilMask(0xFF); + state->DepthMask(GL_FALSE); + //DrawToDepthStencilBuffer(scene.Jobs.ShieldObjects, scene); + state->DepthMask(GL_TRUE); //Draw Opaque shielded objects + state->Disable(GL_STENCIL_TEST); state->StencilFunc(GL_NOTEQUAL, 1, 0xFF); state->StencilMask(0x00); - DrawModelRenderQueues(scene.Jobs.OpaqueShieldedObjects, scene, SSAOTexture); //might need changing + DrawModelRenderQueuesWithShieldCheck(scene.Jobs.OpaqueShieldedObjects, scene); //might need changing GLERROR("Shielded Opaque object"); + //Draw Opaque objects + //state->StencilMask(0x00); + DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene); + GLERROR("OpaqueObjects"); + + //state->Disable(GL_STENCIL_TEST); //Draw Transparen Shielded objects - DrawModelRenderQueues(scene.Jobs.TransparentShieldedObjects, scene, SSAOTexture); //might need changing + state->BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + DrawModelRenderQueuesWithShieldCheck(scene.Jobs.TransparentObjects, scene); //might need changing GLERROR("Shielded Transparent objects"); + //Draw Transparen objects + //state->BlendFunc(GL_ONE, GL_ONE); + //state->StencilFunc(GL_EQUAL, 1, 0xFF); + //DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene); + GLERROR("TransparentObjects"); + //state->BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + DrawSprites(scene.Jobs.SpriteJob, scene); + GLERROR("SpriteJobs"); + + delete state; GLERROR("END"); - delete state; - - - DrawFinalPassState* stateLowRes = new DrawFinalPassState(m_FinalPassFrameBufferLowRes.GetHandle()); - //Draw the lowres texture that will be shown behind the shield. - stateLowRes->Enable(GL_SCISSOR_TEST); - stateLowRes->Enable(GL_DEPTH_TEST); - //TODO: Viewports and scissor should be in state - glViewport(0, 0, m_Renderer->GetViewportSize().Width/m_ShieldPixelRate, m_Renderer->GetViewportSize().Height/m_ShieldPixelRate); - glScissor(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); - - glClearStencil(0x00); - glClear(GL_STENCIL_BUFFER_BIT); - - //TODO: This should not be here... - stateLowRes->StencilFunc(GL_ALWAYS, 1, 0xFF); - stateLowRes->StencilMask(0x00); - DrawToDepthBuffer(scene.Jobs.OpaqueObjects, scene); - DrawToDepthBuffer(scene.Jobs.TransparentObjects, scene); - - //Draw shields to stencil pass - stateLowRes->StencilFunc(GL_ALWAYS, 1, 0xFF); - stateLowRes->StencilMask(0xFF); - stateLowRes->Enable(GL_DEPTH_TEST); - DrawShieldToStencilBuffer(scene.Jobs.ShieldObjects, scene); - GLERROR("StencilPass"); - - //glClear(GL_DEPTH_BUFFER_BIT); - - stateLowRes->Enable(GL_DEPTH_TEST); - stateLowRes->StencilFunc(GL_LEQUAL, 1, 0xFF); - stateLowRes->StencilMask(0x00); - DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene, SSAOTexture); - GLERROR("OpaqueObjects"); - DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene, SSAOTexture); - GLERROR("TransparentObjects"); - glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); - glScissor(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); - delete stateLowRes; + } void DrawFinalPass::ClearBuffer() { GLERROR("PRE"); - m_FinalPassFrameBufferLowRes.Bind(); - GLERROR("Bind LowRes"); - - glViewport(0, 0, m_Renderer->GetViewportSize().Width/m_ShieldPixelRate, m_Renderer->GetViewportSize().Height/m_ShieldPixelRate); - glScissor(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); - GLERROR("ViewPort,Scissor LowRes"); - - glClearColor(0.f, 0.f, 0.f, 0.f); - GLERROR("1"); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - GLERROR("2"); - - glDisable(GL_SCISSOR_TEST); - GLERROR("3"); - - m_FinalPassFrameBufferLowRes.Unbind(); - - GLERROR("prebind HighRes"); + m_ShieldDepthFrameBuffer.Bind(); + glClear(GL_DEPTH_BUFFER_BIT); + m_ShieldDepthFrameBuffer.Unbind(); m_FinalPassFrameBuffer.Bind(); GLERROR("Bind HighRes"); glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); @@ -297,145 +316,105 @@ void DrawFinalPass::ClearBuffer() void DrawFinalPass::OnWindowResize() { //InitializeFrameBuffers(); - glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); - - GenerateTexture(&m_SceneTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); - GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); + CommonFunctions::GenerateTexture(&m_DepthBuffer, GL_CLAMP_TO_BORDER, GL_NEAREST, + glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8); + CommonFunctions::GenerateTexture(&m_SceneTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); + CommonFunctions::GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); m_FinalPassFrameBuffer.Generate(); - - glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBufferLowRes); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, (int)(m_Renderer->GetViewportSize().Width/m_ShieldPixelRate), (int)(m_Renderer->GetViewportSize().Height/m_ShieldPixelRate)); - - GenerateTexture(&m_SceneTextureLowRes, GL_CLAMP_TO_EDGE, GL_NEAREST, glm::vec2((int)(m_Renderer->GetViewportSize().Width/m_ShieldPixelRate), (int)(m_Renderer->GetViewportSize().Height/m_ShieldPixelRate)), GL_RGB16F, GL_RGB, GL_FLOAT); - GenerateTexture(&m_BloomTextureLowRes, GL_CLAMP_TO_EDGE, GL_NEAREST, glm::vec2((int)(m_Renderer->GetViewportSize().Width/m_ShieldPixelRate), (int)(m_Renderer->GetViewportSize().Height/m_ShieldPixelRate)), GL_RGB16F, GL_RGB, GL_FLOAT); - m_FinalPassFrameBufferLowRes.Generate(); GLERROR("Error changing texture resolutions"); } -void DrawFinalPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const -{ - glGenTextures(1, texture); - glBindTexture(GL_TEXTURE_2D, *texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); - glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, dimensions.x, dimensions.y, 0, format, type, nullptr);//TODO: Renderer: Fix the precision and Resolution - GLERROR("Texture initialization failed"); -} - -void DrawFinalPass::GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm::vec2 dimensions, GLint format, GLenum type, GLint numMipMaps) const -{ - glGenTextures(1, texture); - glBindTexture(GL_TEXTURE_2D, *texture); - glTexStorage2D(GL_TEXTURE_2D, numMipMaps, GL_RGBA8, dimensions.x, dimensions.y); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, dimensions.x, dimensions.y, format, type, texture); - glGenerateMipmap(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - GLERROR("MipMap Texture initialization failed"); -} - -void DrawFinalPass::DrawModelRenderQueues(std::list>& jobs, RenderScene& scene, GLuint SSAOTexture) +void DrawFinalPass::DrawModelRenderQueues(std::list>& jobs, RenderScene& scene) { GLuint forwardHandle = m_ForwardPlusProgram->GetHandle(); - GLERROR("forwardHandle"); GLuint explosionHandle = m_ExplosionEffectProgram->GetHandle(); - GLERROR("explosionHandle"); GLuint explosionSplatMapHandle = m_ExplosionEffectSplatMapProgram->GetHandle(); - GLERROR("explosionSplatMapHandle"); - GLuint forwardSplatHandle = m_ForwardPlusSplatMapProgram->GetHandle(); - GLERROR("forwardSplatHandle"); + GLuint forwardSplatMapHandle = m_ForwardPlusSplatMapProgram->GetHandle(); GLuint forwardSkinnedHandle = m_ForwardPlusSkinnedProgram->GetHandle(); - GLERROR("forwardSkinnedHandle"); GLuint explosionSkinnedHandle = m_ExplosionEffectSkinnedProgram->GetHandle(); - GLERROR("explosionSkinnedHandle"); GLuint explosionSplatMapSkinnedHandle = m_ExplosionEffectSplatMapSkinnedProgram->GetHandle(); - GLERROR("explosionSplatMapSkinnedHandle"); GLuint forwardSplatMapSkinnedHandle = m_ForwardPlusSplatMapSkinnedProgram->GetHandle(); - GLERROR("forwardSplatSkinnedHandle"); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightCullingPass->LightSSBO()); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO()); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightCullingPass->LightIndexSSBO()); glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, SSAOTexture); + glBindTexture(GL_TEXTURE_2D, m_SSAOPass->SSAOTexture()); for (auto &job : jobs) { auto explosionEffectJob = std::dynamic_pointer_cast(job); if (explosionEffectJob) { switch (explosionEffectJob->Type) { case RawModel::MaterialType::Basic: - case RawModel::MaterialType::SingleTextures: - { - if (explosionEffectJob->Model->IsSkinned()) { + case RawModel::MaterialType::SingleTextures: + { + if (explosionEffectJob->Model->IsSkinned()) { - m_ExplosionEffectSkinnedProgram->Bind(); - GLERROR("Bind ExplosionEffectSkinned program"); - //bind uniforms - BindExplosionUniforms(explosionSkinnedHandle, explosionEffectJob, scene); - //bind textures - BindExplosionTextures(explosionSkinnedHandle, explosionEffectJob); - glActiveTexture(GL_TEXTURE5); - glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture); - glUniform3fv(glGetUniformLocation(forwardHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position())); + m_ExplosionEffectSkinnedProgram->Bind(); + GLERROR("Bind ExplosionEffectSkinned program"); + //bind uniforms + BindExplosionUniforms(explosionSkinnedHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionSkinnedHandle, explosionEffectJob); + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture); + glUniform3fv(glGetUniformLocation(explosionSkinnedHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position())); - std::vector frameBones; - if (explosionEffectJob->AnimationOffset.animation != nullptr) { - frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); - } else { - frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); - } - glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } else { - m_ExplosionEffectProgram->Bind(); - GLERROR("Bind ExplosionEffect program"); - //bind uniforms - BindExplosionUniforms(explosionHandle, explosionEffectJob, scene); - //bind textures - BindExplosionTextures(explosionHandle, explosionEffectJob); - glActiveTexture(GL_TEXTURE5); - glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture); - glUniform3fv(glGetUniformLocation(forwardHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position())); - - } - break; - } - case RawModel::MaterialType::SplatMapping: - { - if (explosionEffectJob->Model->IsSkinned()) { - m_ExplosionEffectSplatMapSkinnedProgram->Bind(); - GLERROR("Bind ExplosionEffectSplatMapSkinned program"); - //bind uniforms - BindExplosionUniforms(explosionSplatMapSkinnedHandle, explosionEffectJob, scene); - //bind textures - BindExplosionTextures(explosionSplatMapSkinnedHandle, explosionEffectJob); - GLERROR("asdasd"); - std::vector frameBones; - if (explosionEffectJob->AnimationOffset.animation != nullptr) { - frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); - } else { - frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); - } - glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - - } else { - m_ExplosionEffectSplatMapProgram->Bind(); - GLERROR("Bind ExplosionEffectSplatMap program"); - //bind uniforms - //bind uniforms - BindExplosionUniforms(explosionSplatMapHandle, explosionEffectJob, scene); - //bind textures - BindExplosionTextures(explosionSplatMapHandle, explosionEffectJob); - GLERROR("asdasd"); - } - break; - } + std::vector frameBones; + if (explosionEffectJob->AnimationOffset.animation != nullptr) { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); + } + else { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + else { + m_ExplosionEffectProgram->Bind(); + GLERROR("Bind ExplosionEffect program"); + //bind uniforms + BindExplosionUniforms(explosionHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionHandle, explosionEffectJob); + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture); + glUniform3fv(glGetUniformLocation(explosionHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position())); + } + break; + } + case RawModel::MaterialType::SplatMapping: + { + if (explosionEffectJob->Model->IsSkinned()) { + m_ExplosionEffectSplatMapSkinnedProgram->Bind(); + GLERROR("Bind ExplosionEffectSplatMapSkinned program"); + //bind uniforms + BindExplosionUniforms(explosionSplatMapSkinnedHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionSplatMapSkinnedHandle, explosionEffectJob); + GLERROR("asdasd"); + std::vector frameBones; + if (explosionEffectJob->AnimationOffset.animation != nullptr) { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); + } + else { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + else { + m_ExplosionEffectSplatMapProgram->Bind(); + GLERROR("Bind ExplosionEffectSplatMap program"); + //bind uniforms + //bind uniforms + BindExplosionUniforms(explosionSplatMapHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionSplatMapHandle, explosionEffectJob); + GLERROR("asdasd"); + } + break; + } } glDisable(GL_CULL_FACE); @@ -445,132 +424,439 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& glDrawElements(GL_TRIANGLES, explosionEffectJob->EndIndex - explosionEffectJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(explosionEffectJob->StartIndex*sizeof(unsigned int))); glEnable(GL_CULL_FACE); GLERROR("explosion effect end"); - } else { - auto modelJob = std::dynamic_pointer_cast(job); - if (modelJob) { - //bind forward program - //TODO: JOHAN/TOBIAS: Bind shader based on ModelJob->ShaderID; - switch (modelJob->Type) { - case RawModel::MaterialType::Basic: - case RawModel::MaterialType::SingleTextures: - { - if (modelJob->Model->IsSkinned()) { - m_ForwardPlusSkinnedProgram->Bind(); - GLERROR("Bind ForwardPlusSkinnedProgram"); - //bind uniforms - BindModelUniforms(forwardSkinnedHandle, modelJob, scene); - //bind textures - BindModelTextures(forwardSkinnedHandle, modelJob); - glActiveTexture(GL_TEXTURE5); - glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture); - glUniform3fv(glGetUniformLocation(forwardHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position())); + } else { + auto modelJob = std::dynamic_pointer_cast(job); + if (modelJob) { + //bind forward program + //TODO: JOHAN/TOBIAS: Bind shader based on ModelJob->ShaderID; + switch (modelJob->Type) { + case RawModel::MaterialType::Basic: + case RawModel::MaterialType::SingleTextures: + { + if (modelJob->Model->IsSkinned()) { + m_ForwardPlusSkinnedProgram->Bind(); + GLERROR("Bind ForwardPlusSkinnedProgram"); + //bind uniforms + BindModelUniforms(forwardSkinnedHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardSkinnedHandle, modelJob); + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture); + glUniform3fv(glGetUniformLocation(forwardSkinnedHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position())); - std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); - } else { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } - glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + std::vector frameBones; + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } + else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } else { - m_ForwardPlusProgram->Bind(); - GLERROR("Bind ForwardPlusProgram"); - //bind uniforms - BindModelUniforms(forwardHandle, modelJob, scene); - //bind textures - BindModelTextures(forwardHandle, modelJob); - glActiveTexture(GL_TEXTURE5); - glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture); - glUniform3fv(glGetUniformLocation(forwardHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position())); - } - break; - } - case RawModel::MaterialType::SplatMapping: - { - if (modelJob->Model->IsSkinned()) { - m_ForwardPlusSplatMapSkinnedProgram->Bind(); - GLERROR("Bind SplatMap program"); - //bind uniforms - BindModelUniforms(forwardSplatMapSkinnedHandle, modelJob, scene); - //bind textures - BindModelTextures(forwardSplatMapSkinnedHandle, modelJob); - GLERROR("asdasd"); - std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); - } else { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } - glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + else { + m_ForwardPlusProgram->Bind(); + GLERROR("Bind ForwardPlusProgram"); + //bind uniforms + BindModelUniforms(forwardHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardHandle, modelJob); + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture); + glUniform3fv(glGetUniformLocation(forwardHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position())); + } + break; + } + case RawModel::MaterialType::SplatMapping: + { + if (modelJob->Model->IsSkinned()) { + m_ForwardPlusSplatMapSkinnedProgram->Bind(); + GLERROR("Bind SplatMap program"); + //bind uniforms + BindModelUniforms(forwardSplatMapSkinnedHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardSplatMapSkinnedHandle, modelJob); + GLERROR("asdasd"); + std::vector frameBones; + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } + else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } else { - m_ForwardPlusSplatMapProgram->Bind(); - GLERROR("Bind SplatMap program"); - //bind uniforms - BindModelUniforms(forwardSplatHandle, modelJob, scene); - //bind textures - BindModelTextures(forwardSplatHandle, modelJob); - GLERROR("asdasd"); - } - break; - } - } - //draw - glBindVertexArray(modelJob->Model->VAO); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); - glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex*sizeof(unsigned int))); - if (GLERROR("models end")) { - continue; - } + } + else { + m_ForwardPlusSplatMapProgram->Bind(); + GLERROR("Bind SplatMap program"); + //bind uniforms + BindModelUniforms(forwardSplatMapHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardSplatMapHandle, modelJob); + GLERROR("asdasd"); + } + break; + } } - } - } -} - - -void DrawFinalPass::DrawShieldToStencilBuffer(std::list>& jobs, RenderScene& scene) -{ - - - for (auto &job : jobs) { - auto modelJob = std::dynamic_pointer_cast(job); - if (modelJob) { - - if(modelJob->Model->IsSkinned()) { - m_ShieldToStencilSkinnedProgram->Bind(); - GLuint shaderHandle = m_ShieldToStencilSkinnedProgram->GetHandle(); - - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); - std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); - } else { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + //draw + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex*sizeof(unsigned int))); + if (GLERROR("models end")) { + continue; } - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } else { - m_ShieldToStencilProgram->Bind(); - GLuint shaderHandle = m_ShieldToStencilProgram->GetHandle(); - - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); - glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); - - } - - glBindVertexArray(modelJob->Model->VAO); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); - glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex*sizeof(unsigned int))); - if (GLERROR("models end")) { - continue; } } } } +void DrawFinalPass::DrawModelRenderQueuesWithShieldCheck(std::list>& jobs, RenderScene& scene) +{ + GLuint forwardHandle = m_ForwardPlusProgram->GetHandle(); + GLuint explosionHandle = m_ExplosionEffectProgram->GetHandle(); + GLuint explosionSplatMapHandle = m_ExplosionEffectSplatMapProgram->GetHandle(); + GLuint forwardSplatMapHandle = m_ForwardPlusSplatMapProgram->GetHandle(); + GLuint forwardSkinnedHandle = m_ForwardPlusSkinnedProgram->GetHandle(); + GLuint explosionSkinnedHandle = m_ExplosionEffectSkinnedProgram->GetHandle(); + GLuint explosionSplatMapSkinnedHandle = m_ExplosionEffectSplatMapSkinnedProgram->GetHandle(); + GLuint forwardSplatMapSkinnedHandle = m_ForwardPlusSplatMapSkinnedProgram->GetHandle(); + + GLuint forwardShieldCheckHandle = m_ForwardPlusShieldCheckProgram->GetHandle(); + GLuint explosionShieldCheckHandle = m_ExplosionEffectShieldCheckProgram->GetHandle(); + GLuint explosionSplatMapShieldCheckHandle = m_ExplosionEffectSplatMapShieldCheckProgram->GetHandle(); + GLuint forwardSplatShieldCheckHandle = m_ForwardPlusSplatMapShieldCheckProgram->GetHandle(); + GLuint forwardSkinnedShieldCheckHandle = m_ForwardPlusSkinnedShieldCheckProgram->GetHandle(); + GLuint explosionSkinnedShieldCheckHandle = m_ExplosionEffectSkinnedShieldCheckProgram->GetHandle(); + GLuint explosionSplatMapSkinnedShieldCheckHandle = m_ExplosionEffectSplatMapSkinnedShieldCheckProgram->GetHandle(); + GLuint forwardSplatMapSkinnedShieldCheckHandle = m_ForwardPlusSplatMapSkinnedShieldCheckProgram->GetHandle(); + + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightCullingPass->LightSSBO()); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO()); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightCullingPass->LightIndexSSBO()); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_SSAOPass->SSAOTexture()); + + glActiveTexture(GL_TEXTURE31); + glBindTexture(GL_TEXTURE_2D, m_ShieldBuffer); + + for (auto &job : jobs) { + auto explosionEffectJob = std::dynamic_pointer_cast(job); + if (explosionEffectJob) { + if (explosionEffectJob->IsShielded) { + switch (explosionEffectJob->Type) { + case RawModel::MaterialType::Basic: + case RawModel::MaterialType::SingleTextures: + { + if (explosionEffectJob->Model->IsSkinned()) { + + m_ExplosionEffectSkinnedShieldCheckProgram->Bind(); + GLERROR("Bind ExplosionEffectSkinned program"); + //bind uniforms + BindExplosionUniforms(explosionSkinnedShieldCheckHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionSkinnedShieldCheckHandle, explosionEffectJob); + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture); + glUniform3fv(glGetUniformLocation(explosionSkinnedShieldCheckHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position())); + + std::vector frameBones; + if (explosionEffectJob->AnimationOffset.animation != nullptr) { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); + } + else { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedShieldCheckHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + else { + m_ExplosionEffectShieldCheckProgram->Bind(); + GLERROR("Bind ExplosionEffect program"); + //bind uniforms + BindExplosionUniforms(explosionShieldCheckHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionShieldCheckHandle, explosionEffectJob); + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture); + glUniform3fv(glGetUniformLocation(explosionShieldCheckHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position())); + + } + break; + } + case RawModel::MaterialType::SplatMapping: + { + if (explosionEffectJob->Model->IsSkinned()) { + m_ExplosionEffectSplatMapSkinnedShieldCheckProgram->Bind(); + GLERROR("Bind ExplosionEffectSplatMapSkinned program"); + //bind uniforms + BindExplosionUniforms(explosionSplatMapSkinnedShieldCheckHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionSplatMapSkinnedShieldCheckHandle, explosionEffectJob); + GLERROR("asdasd"); + std::vector frameBones; + if (explosionEffectJob->AnimationOffset.animation != nullptr) { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); + } + else { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedShieldCheckHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + + } + else { + m_ExplosionEffectSplatMapShieldCheckProgram->Bind(); + GLERROR("Bind ExplosionEffectSplatMap program"); + //bind uniforms + //bind uniforms + BindExplosionUniforms(explosionSplatMapShieldCheckHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionSplatMapShieldCheckHandle, explosionEffectJob); + GLERROR("asdasd"); + } + break; + } + } + } else { + switch (explosionEffectJob->Type) { + case RawModel::MaterialType::Basic: + case RawModel::MaterialType::SingleTextures: + { + if (explosionEffectJob->Model->IsSkinned()) { + + m_ExplosionEffectSkinnedProgram->Bind(); + GLERROR("Bind ExplosionEffectSkinned program"); + //bind uniforms + BindExplosionUniforms(explosionSkinnedHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionSkinnedHandle, explosionEffectJob); + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture); + glUniform3fv(glGetUniformLocation(explosionSkinnedHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position())); + + std::vector frameBones; + if (explosionEffectJob->AnimationOffset.animation != nullptr) { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); + } + else { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + else { + m_ExplosionEffectProgram->Bind(); + GLERROR("Bind ExplosionEffect program"); + //bind uniforms + BindExplosionUniforms(explosionHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionHandle, explosionEffectJob); + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture); + glUniform3fv(glGetUniformLocation(explosionHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position())); + } + break; + } + case RawModel::MaterialType::SplatMapping: + { + if (explosionEffectJob->Model->IsSkinned()) { + m_ExplosionEffectSplatMapSkinnedProgram->Bind(); + GLERROR("Bind ExplosionEffectSplatMapSkinned program"); + //bind uniforms + BindExplosionUniforms(explosionSplatMapSkinnedHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionSplatMapSkinnedHandle, explosionEffectJob); + GLERROR("asdasd"); + std::vector frameBones; + if (explosionEffectJob->AnimationOffset.animation != nullptr) { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); + } + else { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + else { + m_ExplosionEffectSplatMapProgram->Bind(); + GLERROR("Bind ExplosionEffectSplatMap program"); + //bind uniforms + //bind uniforms + BindExplosionUniforms(explosionSplatMapHandle, explosionEffectJob, scene); + //bind textures + BindExplosionTextures(explosionSplatMapHandle, explosionEffectJob); + GLERROR("asdasd"); + } + break; + } + } + } + glDisable(GL_CULL_FACE); + + //draw + glBindVertexArray(explosionEffectJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, explosionEffectJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, explosionEffectJob->EndIndex - explosionEffectJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(explosionEffectJob->StartIndex*sizeof(unsigned int))); + glEnable(GL_CULL_FACE); + GLERROR("explosion effect end"); + } else { + auto modelJob = std::dynamic_pointer_cast(job); + if (modelJob) { + //bind forward program + //TODO: JOHAN/TOBIAS: Bind shader based on ModelJob->ShaderID; + if (modelJob->IsShielded) { + switch (modelJob->Type) { + case RawModel::MaterialType::Basic: + case RawModel::MaterialType::SingleTextures: + { + if (modelJob->Model->IsSkinned()) { + m_ForwardPlusSkinnedShieldCheckProgram->Bind(); + GLERROR("Bind ForwardPlusSkinnedProgram"); + //bind uniforms + BindModelUniforms(forwardSkinnedShieldCheckHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardSkinnedShieldCheckHandle, modelJob); + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture); + glUniform3fv(glGetUniformLocation(forwardSkinnedShieldCheckHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position())); + + std::vector frameBones; + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } + else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedShieldCheckHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + + } + else { + m_ForwardPlusShieldCheckProgram->Bind(); + GLERROR("Bind ForwardPlusProgram"); + //bind uniforms + BindModelUniforms(forwardShieldCheckHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardShieldCheckHandle, modelJob); + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture); + glUniform3fv(glGetUniformLocation(forwardShieldCheckHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position())); + } + break; + } + case RawModel::MaterialType::SplatMapping: + { + if (modelJob->Model->IsSkinned()) { + m_ForwardPlusSplatMapSkinnedShieldCheckProgram->Bind(); + GLERROR("Bind SplatMap program"); + //bind uniforms + BindModelUniforms(forwardSplatMapSkinnedShieldCheckHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardSplatMapSkinnedShieldCheckHandle, modelJob); + GLERROR("asdasd"); + std::vector frameBones; + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } + else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedShieldCheckHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + + } + else { + m_ForwardPlusSplatMapShieldCheckProgram->Bind(); + GLERROR("Bind SplatMap program"); + //bind uniforms + BindModelUniforms(forwardSplatShieldCheckHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardSplatShieldCheckHandle, modelJob); + GLERROR("asdasd"); + } + break; + } + } + } else { + switch (modelJob->Type) { + case RawModel::MaterialType::Basic: + case RawModel::MaterialType::SingleTextures: + { + if (modelJob->Model->IsSkinned()) { + m_ForwardPlusSkinnedProgram->Bind(); + GLERROR("Bind ForwardPlusSkinnedProgram"); + //bind uniforms + BindModelUniforms(forwardSkinnedHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardSkinnedHandle, modelJob); + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture); + glUniform3fv(glGetUniformLocation(forwardSkinnedHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position())); + + std::vector frameBones; + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } + else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + + } + else { + m_ForwardPlusProgram->Bind(); + GLERROR("Bind ForwardPlusProgram"); + //bind uniforms + BindModelUniforms(forwardHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardHandle, modelJob); + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_CUBE_MAP, m_CubeMapPass->m_CubeMapTexture); + glUniform3fv(glGetUniformLocation(forwardHandle, "CameraPosition"), 1, glm::value_ptr(scene.Camera->Position())); + } + break; + } + case RawModel::MaterialType::SplatMapping: + { + if (modelJob->Model->IsSkinned()) { + m_ForwardPlusSplatMapSkinnedProgram->Bind(); + GLERROR("Bind SplatMap program"); + //bind uniforms + BindModelUniforms(forwardSplatMapSkinnedHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardSplatMapSkinnedHandle, modelJob); + GLERROR("asdasd"); + std::vector frameBones; + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } + else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } + glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + + } + else { + m_ForwardPlusSplatMapProgram->Bind(); + GLERROR("Bind SplatMap program"); + //bind uniforms + BindModelUniforms(forwardSplatMapHandle, modelJob, scene); + //bind textures + BindModelTextures(forwardSplatMapHandle, modelJob); + GLERROR("asdasd"); + } + break; + } + } + } + //draw + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex*sizeof(unsigned int))); + if (GLERROR("models end")) { + continue; + } + } + } + } +} + void DrawFinalPass::DrawShieldedModelRenderQueue(std::list>& jobs, RenderScene& scene) { GLuint forwardHandle = m_ForwardPlusProgram->GetHandle(); @@ -663,7 +949,7 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list>& jobs, RenderScene& scene) +void DrawFinalPass::DrawToDepthStencilBuffer(std::list>& jobs, RenderScene& scene) { @@ -671,8 +957,8 @@ void DrawFinalPass::DrawToDepthBuffer(std::list>& job auto modelJob = std::dynamic_pointer_cast(job); if(modelJob->Model->IsSkinned()) { - m_FillDepthBufferSkinnedProgram->Bind(); - GLuint shaderHandle = m_FillDepthBufferSkinnedProgram->GetHandle(); + m_FillDepthStencilBufferSkinnedProgram->Bind(); + GLuint shaderHandle = m_FillDepthStencilBufferSkinnedProgram->GetHandle(); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); @@ -686,8 +972,8 @@ void DrawFinalPass::DrawToDepthBuffer(std::list>& job glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { - m_FillDepthBufferProgram->Bind(); - GLuint shaderHandle = m_FillDepthBufferProgram->GetHandle(); + m_FillDepthStencilBufferProgram->Bind(); + GLuint shaderHandle = m_FillDepthStencilBufferProgram->GetHandle(); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); @@ -753,6 +1039,7 @@ void DrawFinalPass::DrawSprites(std::list>&jobs, Rend void DrawFinalPass::BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene) { + glUniform1i(glGetUniformLocation(shaderHandle, "SSAOQuality"), m_SSAOPass->TextureQuality()); GLERROR("Bind 1 uniform"); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(job->Matrix)); GLERROR("Bind 2 uniform"); @@ -801,6 +1088,7 @@ void DrawFinalPass::BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene) { + glUniform1i(glGetUniformLocation(shaderHandle, "SSAOQuality"), m_SSAOPass->TextureQuality()); GLERROR("Bind 1 uniform"); GLint Location_M = glGetUniformLocation(shaderHandle, "M"); glUniformMatrix4fv(Location_M, 1, GL_FALSE, glm::value_ptr(job->Matrix)); diff --git a/src/Engine/Rendering/DrawFinalPassState.cpp b/src/Engine/Rendering/DrawFinalPassState.cpp index 8b5ddc8b..5c238985 100644 --- a/src/Engine/Rendering/DrawFinalPassState.cpp +++ b/src/Engine/Rendering/DrawFinalPassState.cpp @@ -8,11 +8,12 @@ DrawFinalPassState::DrawFinalPassState(GLuint frameBuffer) Enable(GL_BLEND); BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); Enable(GL_DEPTH_TEST); + DepthMask(GL_TRUE); Enable(GL_CULL_FACE); - Enable(GL_STENCIL_TEST); - StencilFunc(GL_NOTEQUAL, 1, 0xFF); - StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - StencilMask(0xFF); + // Enable(GL_STENCIL_TEST); + // StencilFunc(GL_NOTEQUAL, 1, 0xFF); + // StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + // StencilMask(0xFF); ClearColor(glm::vec4(0.f, 0.f, 0.f, 0.f)); } @@ -24,11 +25,9 @@ DrawFinalPassState::~DrawFinalPassState() DrawStencilState::DrawStencilState(GLuint frameBuffer) { BindFramebuffer(frameBuffer); - Enable(GL_STENCIL_TEST); - StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - StencilFunc(GL_ALWAYS, 1, 0xFF); - StencilMask(0xFF); Enable(GL_DEPTH_TEST); + DepthMask(GL_TRUE); + Enable(GL_CULL_FACE); ClearColor(glm::vec4(0.f)); } diff --git a/src/Engine/Rendering/FrameBuffer.cpp b/src/Engine/Rendering/FrameBuffer.cpp index 794fb84e..da438e7a 100644 --- a/src/Engine/Rendering/FrameBuffer.cpp +++ b/src/Engine/Rendering/FrameBuffer.cpp @@ -42,35 +42,35 @@ void FrameBuffer::Generate() GLERROR("PRE"); std::vector attachments; - - glGenFramebuffers(1, &m_BufferHandle); + if (m_BufferHandle == 0) { + glGenFramebuffers(1, &m_BufferHandle); + } glBindFramebuffer(GL_FRAMEBUFFER, m_BufferHandle); GLERROR("1"); - for (auto it = m_Resources.begin(); it != m_Resources.end(); it++) { - switch ((*it)->m_ResourceType) { - case GL_TEXTURE_2D: - glFramebufferTexture2D(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle, 0); - GLERROR("FrameBuffer generate: glFramebufferTexture2D"); + for (auto it = m_Resources.begin(); it != m_Resources.end(); it++) { + switch ((*it)->m_ResourceType) { + case GL_TEXTURE_2D: + glFramebufferTexture2D(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle, 0); + GLERROR("FrameBuffer generate: glFramebufferTexture2D"); - break; - case GL_RENDERBUFFER: - glFramebufferRenderbuffer(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle); - GLERROR("FrameBuffer generate: glFramebufferRenderbuffer"); - break; - } - GLERROR("2"); + break; + case GL_RENDERBUFFER: + glFramebufferRenderbuffer(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle); + GLERROR("FrameBuffer generate: glFramebufferRenderbuffer"); + break; + } + GLERROR("2"); - if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT && (*it)->m_Attachment != GL_STENCIL_ATTACHMENT && (*it)->m_Attachment != GL_DEPTH_STENCIL_ATTACHMENT) { - attachments.push_back((*it)->m_Attachment); - } - GLERROR("Attachment"); + if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT && (*it)->m_Attachment != GL_STENCIL_ATTACHMENT && (*it)->m_Attachment != GL_DEPTH_STENCIL_ATTACHMENT) { + attachments.push_back((*it)->m_Attachment); + } + GLERROR("Attachment"); - } - GLERROR("3"); + } + GLERROR("3"); - - GLenum* bufferTextures = &attachments[0]; + GLenum* bufferTextures = attachments.data(); glDrawBuffers(attachments.size(), bufferTextures); if (GLERROR("GLBufferAttachement error")) { printf(": AttachmentSize %i", attachments.size()); diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index 1eab9939..7b9e2498 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -19,15 +19,16 @@ PickingPass::~PickingPass() void PickingPass::InitializeTextures() { - GenerateTexture(&m_PickingTexture, GL_CLAMP_TO_BORDER, GL_LINEAR, + CommonFunctions::GenerateTexture(&m_PickingTexture, GL_CLAMP_TO_BORDER, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RG8, GL_RG, GL_UNSIGNED_BYTE); - GenerateTexture(&m_DepthBuffer, GL_CLAMP_TO_BORDER, GL_NEAREST, - glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8); + CommonFunctions::GenerateTexture(&m_DepthBuffer, GL_CLAMP_TO_BORDER, GL_NEAREST, + glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT); } void PickingPass::InitializeFrameBuffers() { + m_PickingBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthBuffer, GL_DEPTH_ATTACHMENT))); m_PickingBuffer.AddResource(std::shared_ptr(new Texture2D(&m_PickingTexture, GL_COLOR_ATTACHMENT0))); m_PickingBuffer.Generate(); @@ -366,7 +367,7 @@ void PickingPass::ClearPicking() m_PickingBuffer.Bind(); glClearColor(0.f, 0.f, 0.f, 0.f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); m_PickingBuffer.Unbind(); GLERROR("END"); } @@ -407,16 +408,3 @@ PickData PickingPass::Pick(glm::vec2 screenCoord) pickData.World = pickInfo.World; return pickData; } - -void PickingPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const -{ - //TODO: Renderer: Make this in a sparate class - glGenTextures(1, texture); - glBindTexture(GL_TEXTURE_2D, *texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); - glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, dimensions.x, dimensions.y, 0, format, type, nullptr);//TODO: Renderer: Fix the precision and Resolution - GLERROR("Texture initialization failed"); -} diff --git a/src/Engine/Rendering/PickingPassState.cpp b/src/Engine/Rendering/PickingPassState.cpp index f2d42bff..767b9577 100644 --- a/src/Engine/Rendering/PickingPassState.cpp +++ b/src/Engine/Rendering/PickingPassState.cpp @@ -9,11 +9,11 @@ PickingPassState::PickingPassState(GLuint frameBuffer) Enable(GL_DEPTH_TEST); Enable(GL_CULL_FACE); Disable(GL_BLEND); - glm::vec4 clearColor = glm::vec4(0.f); //ClearColor(clearColor); //Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GLERROR("END"); + } PickingPassState::~PickingPassState() diff --git a/src/Engine/Rendering/RenderState.cpp b/src/Engine/Rendering/RenderState.cpp index 26ba18a1..56812f9a 100644 --- a/src/Engine/Rendering/RenderState.cpp +++ b/src/Engine/Rendering/RenderState.cpp @@ -135,6 +135,26 @@ bool RenderState::DepthMask(GLboolean flag) return !GLERROR("DepthMask"); } +bool RenderState::DepthFunc(GLenum func) +{ + GLint original; + glGetIntegerv(GL_DEPTH_FUNC, &original); + m_ResetFunctions.push_back(std::bind(glDepthFunc, original)); + glDepthFunc(func); + return !GLERROR("DepthFunc"); +} + +bool RenderState::AlphaFunc(GLenum func, GLclampf thresholder) +{ + GLint originalFunc; + glGetIntegerv(GL_ALPHA_TEST_FUNC, &originalFunc); + GLint originalRef; + glGetIntegerv(GL_ALPHA_TEST_REF, &originalRef); + m_ResetFunctions.push_back(std::bind(glAlphaFunc, originalFunc, originalRef)); + glAlphaFunc(func, thresholder); + return !GLERROR("AlphaFunc"); +} + RenderState::~RenderState() { for (auto& f : boost::adaptors::reverse(m_ResetFunctions)) { diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 7b0ea84f..a1f00c88 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -240,6 +240,8 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs) fillColor = (glm::vec4)fillComponent["Color"]; } + bool isShielded = m_World->HasComponent(cModel.EntityID, "Shielded") || m_World->HasComponent(cModel.EntityID, "Player"); + glm::mat4 modelMatrix = Transform::ModelMatrix(cModel.EntityID, m_World); //Loop through all materialgroups of a model for (auto matGroup : model->MaterialGroups()) { @@ -255,20 +257,19 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs) cModel, m_World, fillColor, - fillPercentage + fillPercentage, + isShielded )); if (m_World->HasComponent(cModel.EntityID, "Shield")){ explosionEffectJob->CalculateHash(); Jobs.ShieldObjects.push_back(explosionEffectJob); - } else if (m_World->HasComponent(cModel.EntityID, "Shielded") - || m_World->HasComponent(cModel.EntityID, "Player")) { - + } else if (isShielded) { if (explosionEffectJob->Color.a != 1.f || explosionEffectJob->EndColor.a != 1.f || explosionEffectJob->DiffuseColor.a != 1.f) { cModel["Transparent"] = true; } if (cModel["Transparent"]) { - Jobs.TransparentShieldedObjects.push_back(explosionEffectJob); + Jobs.TransparentObjects.push_back(explosionEffectJob); } else { explosionEffectJob->CalculateHash(); Jobs.OpaqueShieldedObjects.push_back(explosionEffectJob); @@ -294,20 +295,20 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs) cModel, m_World, fillColor, - fillPercentage + fillPercentage, + isShielded )); if (m_World->HasComponent(cModel.EntityID, "Shield")) { modelJob->CalculateHash(); Jobs.ShieldObjects.push_back(modelJob); - } else if (m_World->HasComponent(cModel.EntityID, "Shielded") - || m_World->HasComponent(cModel.EntityID, "Player")) { + } else if (isShielded) { if (modelJob->Color.a != 1.f || modelJob->DiffuseColor.a != 1.f) { cModel["Transparent"] = true; } if (cModel["Transparent"]) { - Jobs.TransparentShieldedObjects.push_back(modelJob); + Jobs.TransparentObjects.push_back(modelJob); } else { modelJob->CalculateHash(); Jobs.OpaqueShieldedObjects.push_back(modelJob); diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 251bba2b..3ce985b6 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -4,6 +4,8 @@ std::unordered_map Renderer::m_WindowToRenderer; void Renderer::Initialize() { + m_SSAO_Quality = m_Config->Get("SSAO.Quality", 0); + m_GLOW_Quality = m_Config->Get("GLOW.Quality", 0); InitializeWindow(); InitializeRenderPasses(); @@ -26,9 +28,9 @@ void Renderer::glfwFrameBufferCallback(GLFWwindow* window, int width, int height glViewport(0, 0, width, height); Renderer* currentRenderer = m_WindowToRenderer[window]; currentRenderer->m_ViewportSize = Rectangle(width, height); + currentRenderer->m_PickingPass->OnWindowResize(); currentRenderer->m_DrawFinalPass->OnWindowResize(); currentRenderer->m_LightCullingPass->OnWindowResize(); - currentRenderer->m_PickingPass->OnWindowResize(); currentRenderer->m_DrawBloomPass->OnWindowResize(); currentRenderer->m_SSAOPass->OnWindowResize(); } @@ -107,7 +109,8 @@ void Renderer::Update(double dt) void Renderer::Draw(RenderFrame& frame) { GLERROR("PRE"); - ImGui::Combo("Draw textures", &m_DebugTextureToDraw, "Final\0Scene\0Bloom\0SceneLowRes\0BloomLowRes\0Gaussian\0Picking\0Ambient Occlusion"); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + ImGui::Combo("Draw textures", &m_DebugTextureToDraw, "Final\0Scene\0Bloom\0Gaussian\0Picking\0Ambient Occlusion"); ImGui::Combo("CubeMap", &m_CubeMapTexture, "Nevada(512)\0Sky(1024)"); if(m_CubeMapTexture == 0) { m_CubeMapPass->LoadTextures("Nevada"); @@ -115,19 +118,16 @@ void Renderer::Draw(RenderFrame& frame) m_CubeMapPass->LoadTextures("Sky"); } - ImGui::SliderFloat("SSAO sample radius", &m_SSAO_Radius, 0.01f, 5.0f); - ImGui::SliderFloat("SSAO bias", &m_SSAO_Bias, 0.0f, 0.1f); - ImGui::SliderFloat("SSAO contrast", &m_SSAO_Contrast, 0.0f, 10.0f); - ImGui::SliderFloat("SSAO IntensityScale", &m_SSAO_IntensityScale, 0.0f, 10.0f); - ImGui::SliderInt("SSAO Number of Samples", &m_SSAO_NumOfSamples, 2, 100); - ImGui::SliderInt("SSAO Number of Turns", &m_SSAO_NumOfTurns, 0, 50); - m_SSAOPass->Setting(m_SSAO_Radius, m_SSAO_Bias, m_SSAO_Contrast, m_SSAO_IntensityScale, m_SSAO_NumOfSamples, m_SSAO_NumOfTurns); + ImGui::SliderInt("SSAO Quality", &m_SSAO_Quality, 0, 3); + ImGui::SliderInt("Glow Quality", &m_GLOW_Quality, 0, 3); + m_SSAOPass->ChangeQuality(m_SSAO_Quality); + m_DrawBloomPass->ChangeQuality(m_GLOW_Quality); GLERROR("SSAO Settings"); //clear buffer 0 glClearColor(0.f, 0.f, 0.f, 0.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - //Clear other buffers + //Clear other buffers PerformanceTimer::StartTimer("Renderer-ClearBuffers"); m_PickingPass->ClearPicking(); m_DrawFinalPass->ClearBuffer(); @@ -136,18 +136,16 @@ void Renderer::Draw(RenderFrame& frame) PerformanceTimer::StopTimer("Renderer-ClearBuffers"); GLERROR("ClearBuffers"); for (auto scene : frame.RenderScenes) { - PerformanceTimer::StartTimer("Renderer-Depth"); + PerformanceTimer::StartTimer("Renderer-PickingPass"); m_PickingPass->Draw(*scene); GLERROR("Drawing pickingpass"); - PerformanceTimer::StopTimer("Renderer-Depth"); + PerformanceTimer::StopTimer("Renderer-PickingPass"); } - PerformanceTimer::StartTimer("AO generation"); - m_SSAOPass->Draw(m_PickingPass->DepthBuffer(), frame.RenderScenes.front()->Camera); - GLuint ao = m_SSAOPass->SSAOTexture(); - PerformanceTimer::StopTimer("AO generation"); + PerformanceTimer::StartTimer("Renderer-AO generation"); + m_SSAOPass->Draw(*m_PickingPass->DepthBuffer(), frame.RenderScenes.front()->Camera); + PerformanceTimer::StopTimer("Renderer-AO generation"); for (auto scene : frame.RenderScenes){ - - PerformanceTimer::StartTimer("Renderer-Drawing PickingPass"); + PerformanceTimer::StartTimer("Renderer-Depth"); SortRenderJobsByDepth(*scene); GLERROR("SortByDepth"); PerformanceTimer::StartTimerAndStopPrevious("Renderer-Generate Frustrums"); @@ -159,8 +157,8 @@ void Renderer::Draw(RenderFrame& frame) PerformanceTimer::StartTimerAndStopPrevious("Renderer-Light Culling"); m_LightCullingPass->CullLights(*scene); GLERROR("LightCulling"); - m_DrawFinalPass->Draw(*scene, ao); - PerformanceTimer::StartTimerAndStopPrevious("Renderer-Draw Geometry+Light"); + PerformanceTimer::StartTimerAndStopPrevious("Renderer-Draw Geometry+Light"); + m_DrawFinalPass->Draw(*scene); GLERROR("Draw Geometry+Light"); //m_DrawScenePass->Draw(*scene); @@ -176,7 +174,7 @@ void Renderer::Draw(RenderFrame& frame) if (m_DebugTextureToDraw == 0) { PerformanceTimer::StartTimer("Renderer-Color Correction Pass"); - m_DrawColorCorrectionPass->Draw(m_DrawFinalPass->SceneTexture(), m_DrawBloomPass->GaussianTexture(), m_DrawFinalPass->SceneTextureLowRes(), m_DrawFinalPass->BloomTextureLowRes(), frame.Gamma, frame.Exposure); + m_DrawColorCorrectionPass->Draw(m_DrawFinalPass->SceneTexture(), m_DrawBloomPass->GaussianTexture(), frame.Gamma, frame.Exposure); PerformanceTimer::StopTimer("Renderer-Color Correction Pass"); } @@ -188,18 +186,12 @@ void Renderer::Draw(RenderFrame& frame) m_DrawScreenQuadPass->Draw(m_DrawFinalPass->BloomTexture()); } if (m_DebugTextureToDraw == 3) { - m_DrawScreenQuadPass->Draw(m_DrawFinalPass->SceneTextureLowRes()); - } - if (m_DebugTextureToDraw == 4) { - m_DrawScreenQuadPass->Draw(m_DrawFinalPass->BloomTextureLowRes()); - } - if (m_DebugTextureToDraw == 5) { m_DrawScreenQuadPass->Draw(m_DrawBloomPass->GaussianTexture()); } - if (m_DebugTextureToDraw == 6) { + if (m_DebugTextureToDraw == 4) { m_DrawScreenQuadPass->Draw(m_PickingPass->PickingTexture()); } - if (m_DebugTextureToDraw == 7) { + if (m_DebugTextureToDraw == 5) { m_DrawScreenQuadPass->Draw(m_SSAOPass->SSAOTexture()); } PerformanceTimer::StopTimer("Renderer-Misc Debug Draws"); @@ -207,8 +199,11 @@ void Renderer::Draw(RenderFrame& frame) PerformanceTimer::StartTimer("Renderer-ImGuiRenderPass"); m_ImGuiRenderPass->Draw(); GLERROR("Imgui draw"); + PerformanceTimer::StopTimer("Renderer-ImGuiRenderPass"); + + PerformanceTimer::StartTimer("Renderer-SwapBuffer"); glfwSwapBuffers(m_Window); - PerformanceTimer::StopTimer("Renderer-ImGuiRenderPass"); + PerformanceTimer::StopTimer("Renderer-SwapBuffer"); } PickData Renderer::Pick(glm::vec2 screenCoord) @@ -248,9 +243,10 @@ void Renderer::InitializeRenderPasses() m_PickingPass = new PickingPass(this, m_EventBroker); m_LightCullingPass = new LightCullingPass(this); m_CubeMapPass = new CubeMapPass(this); - m_DrawFinalPass = new DrawFinalPass(this, m_LightCullingPass, m_CubeMapPass); + m_SSAOPass = new SSAOPass(this, m_Config); + m_DrawFinalPass = new DrawFinalPass(this, m_LightCullingPass, m_CubeMapPass, m_SSAOPass); m_DrawScreenQuadPass = new DrawScreenQuadPass(this); - m_DrawBloomPass = new DrawBloomPass(this); + m_DrawBloomPass = new DrawBloomPass(this, m_Config); m_DrawColorCorrectionPass = new DrawColorCorrectionPass(this); - m_SSAOPass = new SSAOPass(this); -} + +} \ No newline at end of file diff --git a/src/Engine/Rendering/SSAOPass.cpp b/src/Engine/Rendering/SSAOPass.cpp index d4cdcb19..9992db70 100644 --- a/src/Engine/Rendering/SSAOPass.cpp +++ b/src/Engine/Rendering/SSAOPass.cpp @@ -1,84 +1,168 @@ #include "Rendering/SSAOPass.h" -SSAOPass::SSAOPass(IRenderer* renderer) +SSAOPass::SSAOPass(IRenderer* renderer, ConfigFile* config) + : m_Renderer(renderer) + , m_Config(config) { - m_Renderer = renderer; + m_WhiteTexture = CommonFunctions::LoadTexture("Textures/Core/White.png", false); + + ChangeQuality(m_Config->Get("SSAO.Quality", 0)); + +} + +void SSAOPass::ChangeQuality(int quality) +{ + if (m_Quality == quality) { + return; + } + + m_Quality = quality; + + if (m_Quality == 0) { + CommonFunctions::DeleteTexture(&m_SSAOTexture); + CommonFunctions::DeleteTexture(&m_SSAOViewSpaceZTexture); + CommonFunctions::DeleteTexture(&m_Gaussian_horiz); + CommonFunctions::DeleteTexture(&m_Gaussian_vert); + return; + } + + std::string qStr = std::to_string(m_Quality); + Setting( + m_Config->Get("SSAO" + qStr + ".Radius", 0.01), + m_Config->Get("SSAO" + qStr + ".Bias", 0.012), + m_Config->Get("SSAO" + qStr + ".Contrast", 1.0), + m_Config->Get("SSAO" + qStr + ".Intensity", 1.0), + m_Config->Get("SSAO" + qStr + ".NumSamples", 0), + m_Config->Get("SSAO" + qStr + ".NumTurns", 0), + m_Config->Get("SSAO" + qStr + ".NumIterations", 0), + m_Config->Get("SSAO" + qStr + ".TextureQuality", 4) + ); + + m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.mesh"); InitializeTexture(); InitializeBuffer(); InitializeShaderProgram(); - Setting(0.1f, 0.012f, 1.0f, 1.0f, 13, 7); - m_DrawBloomPass = new DrawBloomPass(renderer); + } void SSAOPass::InitializeShaderProgram() { m_SSAOProgram = ResourceManager::Load("##SSAOProgram"); - m_SSAOProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/SSAO.vert.glsl"))); - m_SSAOProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/SSAO.frag.glsl"))); - m_SSAOProgram->Compile(); - m_SSAOProgram->Link(); + if (m_SSAOProgram->GetHandle() == 0) { + m_SSAOProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/SSAO.vert.glsl"))); + m_SSAOProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/SSAO.frag.glsl"))); + m_SSAOProgram->Compile(); + m_SSAOProgram->Link(); + } m_SSAOViewSpaceZProgram = ResourceManager::Load("##SSAOViewSpaceZProgram"); - m_SSAOViewSpaceZProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/SSAO.vert.glsl"))); - m_SSAOViewSpaceZProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/SSAOViewSpaceZ.frag.glsl"))); - m_SSAOViewSpaceZProgram->Compile(); - m_SSAOViewSpaceZProgram->Link(); + if (m_SSAOViewSpaceZProgram->GetHandle() == 0) { + m_SSAOViewSpaceZProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/SSAO.vert.glsl"))); + m_SSAOViewSpaceZProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/SSAOViewSpaceZ.frag.glsl"))); + m_SSAOViewSpaceZProgram->Compile(); + m_SSAOViewSpaceZProgram->Link(); + } + + m_GaussianProgram_horiz = ResourceManager::Load("##GaussianProgramHoriz"); + if (m_GaussianProgram_horiz->GetHandle() == 0) { + m_GaussianProgram_horiz->AddShader(std::shared_ptr(new VertexShader("Shaders/Gaussian_horiz.vert.glsl"))); + m_GaussianProgram_horiz->AddShader(std::shared_ptr(new FragmentShader("Shaders/Gaussian_horiz.frag.glsl"))); + m_GaussianProgram_horiz->Compile(); + m_GaussianProgram_horiz->Link(); + } + + m_GaussianProgram_vert = ResourceManager::Load("##GaussianProgramVert"); + if (m_GaussianProgram_vert->GetHandle() == 0) { + m_GaussianProgram_vert->AddShader(std::shared_ptr(new VertexShader("Shaders/Gaussian_vert.vert.glsl"))); + m_GaussianProgram_vert->AddShader(std::shared_ptr(new FragmentShader("Shaders/Gaussian_vert.frag.glsl"))); + m_GaussianProgram_vert->Compile(); + m_GaussianProgram_vert->Link(); + } } void SSAOPass::InitializeTexture() { - GenerateTexture(&m_SSAOTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_R8, GL_RED, GL_FLOAT); - GenerateTexture(&m_SSAOViewSpaceZTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_R32F, GL_RED, GL_FLOAT); + CommonFunctions::GenerateTexture(&m_SSAOTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width >> m_TextureQuality, m_Renderer->GetViewportSize().Height >> m_TextureQuality), GL_R8, GL_RED, GL_FLOAT); + CommonFunctions::GenerateTexture(&m_SSAOViewSpaceZTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width >> m_TextureQuality, m_Renderer->GetViewportSize().Height >> m_TextureQuality), GL_R32F, GL_RED, GL_FLOAT); + + CommonFunctions::GenerateTexture(&m_Gaussian_horiz, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width >> m_TextureQuality, m_Renderer->GetViewportSize().Height >> m_TextureQuality), GL_R8, GL_RED, GL_FLOAT); + CommonFunctions::GenerateTexture(&m_Gaussian_vert, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width >> m_TextureQuality, m_Renderer->GetViewportSize().Height >> m_TextureQuality), GL_R8, GL_RED, GL_FLOAT); } void SSAOPass::InitializeBuffer() { - m_SSAOFramBuffer.AddResource(std::shared_ptr(new Texture2D(&m_SSAOTexture, GL_COLOR_ATTACHMENT0))); + if (m_SSAOFramBuffer.GetHandle() == 0) { + m_SSAOFramBuffer.AddResource(std::shared_ptr(new Texture2D(&m_SSAOTexture, GL_COLOR_ATTACHMENT0))); + } m_SSAOFramBuffer.Generate(); - m_SSAOViewSpaceZFramBuffer.AddResource(std::shared_ptr(new Texture2D(&m_SSAOViewSpaceZTexture, GL_COLOR_ATTACHMENT0))); + + if (m_SSAOViewSpaceZFramBuffer.GetHandle() == 0) { + m_SSAOViewSpaceZFramBuffer.AddResource(std::shared_ptr(new Texture2D(&m_SSAOViewSpaceZTexture, GL_COLOR_ATTACHMENT0))); + } m_SSAOViewSpaceZFramBuffer.Generate(); + + + + if (m_GaussianFrameBuffer_horiz.GetHandle() == 0) { + m_GaussianFrameBuffer_horiz.AddResource(std::shared_ptr(new Texture2D(&m_Gaussian_horiz, GL_COLOR_ATTACHMENT0))); + } + m_GaussianFrameBuffer_horiz.Generate(); + + + if (m_GaussianFrameBuffer_vert.GetHandle() == 0) { + m_GaussianFrameBuffer_vert.AddResource(std::shared_ptr(new Texture2D(&m_Gaussian_vert, GL_COLOR_ATTACHMENT0))); + } + m_GaussianFrameBuffer_vert.Generate(); + } void SSAOPass::ClearBuffer() { + if (m_Quality == 0) { + return; + } m_SSAOFramBuffer.Bind(); glClearColor(1.f, 1.f, 1.f, 1.f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT); m_SSAOFramBuffer.Unbind(); m_SSAOViewSpaceZFramBuffer.Bind(); glClearColor(1.f, 1.f, 1.f, 1.f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT); m_SSAOViewSpaceZFramBuffer.Unbind(); + + m_GaussianFrameBuffer_horiz.Bind(); + glClearColor(1.f, 1.f, 1.f, 1.f); + glClear(GL_COLOR_BUFFER_BIT); + m_GaussianFrameBuffer_horiz.Unbind(); + + m_GaussianFrameBuffer_vert.Bind(); + glClearColor(1.f, 1.f, 1.f, 1.f); + glClear(GL_COLOR_BUFFER_BIT); + m_GaussianFrameBuffer_vert.Unbind(); } -void SSAOPass::Setting(float radius, float bias, float contrast, float intensityScale, int numOfSamples, int NumOfTurns) { +void SSAOPass::Setting(float radius, float bias, float contrast, float intensityScale, int numOfSamples, int numOfTurns, int iterations, int quality) { m_Radius = radius; m_Bias = bias; m_Contrast = contrast; m_IntensityScale = intensityScale; m_NumOfSamples = numOfSamples; - m_NumOfTurns = NumOfTurns; -} - -void SSAOPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const -{ - glGenTextures(1, texture); - glBindTexture(GL_TEXTURE_2D, *texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); - glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, dimensions.x, dimensions.y, 0, format, type, nullptr); - GLERROR("Texture initialization failed"); + m_NumOfTurns = numOfTurns; + m_Iterations = iterations; + m_TextureQuality = quality; } void SSAOPass::Draw(GLuint depthBuffer, Camera* camera) { + if (m_Quality == 0) { + return; + } + SSAOPassState state; GLuint viewSpaceZPShaderHandle = m_SSAOViewSpaceZProgram->GetHandle(); GLuint SSAOShaderHandle = m_SSAOProgram->GetHandle(); @@ -98,6 +182,7 @@ void SSAOPass::Draw(GLuint depthBuffer, Camera* camera) (-1.0f), (+1.0f) );*/ + glViewport(0, 0, (m_Renderer->GetViewportSize().Width >> m_TextureQuality), (m_Renderer->GetViewportSize().Height >> m_TextureQuality)); //JOHAN TODO: Get this into state glUniform3fv(glGetUniformLocation(viewSpaceZPShaderHandle, "ClipInfo"), 1, glm::value_ptr(clipInfo)); glBindVertexArray(m_ScreenQuad->VAO); @@ -107,9 +192,9 @@ void SSAOPass::Draw(GLuint depthBuffer, Camera* camera) glm::vec4 projInfo = glm::vec4( ((1.0 - camera->ProjectionMatrix()[0][2]) / camera->ProjectionMatrix()[0][0]), - (-2.0 / (m_Renderer->GetViewportSize().Width * camera->ProjectionMatrix()[0][0])), + (-2.0 / ((m_Renderer->GetViewportSize().Width >> m_TextureQuality) * camera->ProjectionMatrix()[0][0])), ((1.0 + camera->ProjectionMatrix()[1][2]) / camera->ProjectionMatrix()[1][1]), - (-2.0 / (m_Renderer->GetViewportSize().Height * camera->ProjectionMatrix()[1][1])) + (-2.0 / ((m_Renderer->GetViewportSize().Height >> m_TextureQuality) * camera->ProjectionMatrix()[1][1])) ); @@ -120,26 +205,84 @@ void SSAOPass::Draw(GLuint depthBuffer, Camera* camera) glBindTexture(GL_TEXTURE_2D, m_SSAOViewSpaceZTexture); // How many pixel there are in a 1m long object 1m away from the camera - glUniform1f(glGetUniformLocation(SSAOShaderHandle, "uProjScale"), m_Renderer->GetViewportSize().Height / (-2.0f * glm::tan(camera->FOV() * 0.5f))); + glUniform1f(glGetUniformLocation(SSAOShaderHandle, "uProjScale"), (m_Renderer->GetViewportSize().Height >> m_TextureQuality) / (-2.0f * glm::tan(camera->FOV() * 0.5f))); glUniform1f(glGetUniformLocation(SSAOShaderHandle, "uRadius"), m_Radius); glUniform1f(glGetUniformLocation(SSAOShaderHandle, "uBias"), m_Bias); glUniform1f(glGetUniformLocation(SSAOShaderHandle, "uContrast"), m_Contrast); glUniform1f(glGetUniformLocation(SSAOShaderHandle, "uIntensityScale"), m_IntensityScale); glUniform1i(glGetUniformLocation(SSAOShaderHandle, "uNumOfSamples"), m_NumOfSamples); - glUniform1i(glGetUniformLocation(SSAOShaderHandle, "uNumOfTurns"), m_NumOfTurns);; + glUniform1i(glGetUniformLocation(SSAOShaderHandle, "uNumOfTurns"), m_NumOfTurns); glUniform4fv(glGetUniformLocation(SSAOShaderHandle, "uProjInfo"), 1, glm::value_ptr(projInfo)); glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex + 1 , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); - m_DrawBloomPass->ClearBuffer(); - m_DrawBloomPass->Draw(m_SSAOTexture); + DrawBloomPassState BloomState; + GLuint shaderHandle_horiz = m_GaussianProgram_horiz->GetHandle(); + GLuint shaderHandle_vert = m_GaussianProgram_vert->GetHandle(); + + m_GaussianFrameBuffer_horiz.Bind(); + m_GaussianProgram_horiz->Bind(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_SSAOTexture); + + glBindVertexArray(m_ScreenQuad->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); + glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex + 1 + , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); + //Iterate some times to make it more gaussian. + for (int i = 1; i < m_Iterations; i++) { + //Vertical pass + m_GaussianFrameBuffer_vert.Bind(); + m_GaussianProgram_vert->Bind(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_Gaussian_horiz); + + glBindVertexArray(m_ScreenQuad->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); + glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex + 1 + , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); + //horizontal pass + m_GaussianFrameBuffer_vert.Unbind(); + + m_GaussianFrameBuffer_horiz.Bind(); + m_GaussianProgram_horiz->Bind(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_Gaussian_vert); + + glBindVertexArray(m_ScreenQuad->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); + glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex + 1 + , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); + m_GaussianFrameBuffer_horiz.Unbind(); + } + + //final vertical gaussian after the iterations are done + + m_GaussianFrameBuffer_vert.Bind(); + m_GaussianProgram_vert->Bind(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_Gaussian_horiz); + glBindVertexArray(m_ScreenQuad->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); + glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex + 1 + , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); + + m_GaussianFrameBuffer_vert.Unbind(); + + glViewport(0, 0, (m_Renderer->GetViewportSize().Width), (m_Renderer->GetViewportSize().Height)); } void SSAOPass::OnWindowResize() { - m_DrawBloomPass->OnWindowResize(); + if (m_Quality == 0) { + return; + } + InitializeTexture(); - m_SSAOFramBuffer.Generate(); - m_SSAOViewSpaceZFramBuffer.Generate(); + InitializeBuffer(); } \ No newline at end of file diff --git a/src/Engine/Rendering/Util/CommonFunctions.cpp b/src/Engine/Rendering/Util/CommonFunctions.cpp index 382cb790..913e005e 100644 --- a/src/Engine/Rendering/Util/CommonFunctions.cpp +++ b/src/Engine/Rendering/Util/CommonFunctions.cpp @@ -17,3 +17,46 @@ Texture* CommonFunctions::LoadTexture(std::string path, bool threaded) return img; } + +void CommonFunctions::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) +{ + glDeleteTextures(1, texture); + glGenTextures(1, texture); + glBindTexture(GL_TEXTURE_2D, *texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, dimensions.x, dimensions.y, 0, format, type, nullptr); + GLERROR("Texture initialization failed"); +} + +void CommonFunctions::GenerateMultiSampleTexture(GLuint* texture, int numSamples, glm::vec2 dimensions, GLint internalFormat) +{ + glDeleteTextures(1, texture); + glGenTextures(1, texture); + glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, *texture); + glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, numSamples, internalFormat, dimensions.x, dimensions.y, false); + GLERROR("Texture initialization failed"); +} + + +void CommonFunctions::GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm::vec2 dimensions, GLint format, GLenum type, GLint numMipMaps) +{ + glGenTextures(1, texture); + glBindTexture(GL_TEXTURE_2D, *texture); + glTexStorage2D(GL_TEXTURE_2D, numMipMaps, GL_RGBA8, dimensions.x, dimensions.y); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, dimensions.x, dimensions.y, format, type, texture); + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + GLERROR("MipMap Texture initialization failed"); +} + +void CommonFunctions::DeleteTexture(GLuint* texture) +{ + glDeleteTextures(1, texture); + *texture = 0; +} \ No newline at end of file diff --git a/src/Engine/Rendering/Util/ScreenCoords.cpp b/src/Engine/Rendering/Util/ScreenCoords.cpp index 36f1295e..8b7768c8 100644 --- a/src/Engine/Rendering/Util/ScreenCoords.cpp +++ b/src/Engine/Rendering/Util/ScreenCoords.cpp @@ -31,22 +31,27 @@ glm::vec3 ScreenCoords::ToWorldPos(glm::vec2 screenCoord, float depth, float scr ScreenCoords::PixelData ScreenCoords::ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer) { + GLERROR("Pre"); PickDataBuffer->Bind(); unsigned char pdata[3]; glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pdata); + GLERROR("glReadPixels(pdata) Error"); PickDataBuffer->Unbind(); - glBindFramebuffer(GL_FRAMEBUFFER, DepthBuffer); + glBindFramebuffer(GL_FRAMEBUFFER, DepthBuffer); + GLERROR("glBindFramebuffer(DepthBuffer) Error"); float depthData; glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depthData); + GLERROR("glReadPixels(depthData) Error"); glBindFramebuffer(GL_FRAMEBUFFER, 0); + GLERROR("glBindFramebuffer(0) Error"); PixelData p; p.Color[0] = (int)pdata[0]; p.Color[1] = (int)pdata[1]; p.Depth = depthData; - GLERROR("ScreenCoords::ToPixelData Error"); + GLERROR("End"); return p; } diff --git a/src/Engine/Sound/SoundManager.cpp b/src/Engine/Sound/SoundManager.cpp index d271e260..57b710cf 100644 --- a/src/Engine/Sound/SoundManager.cpp +++ b/src/Engine/Sound/SoundManager.cpp @@ -363,7 +363,7 @@ bool SoundManager::OnPlayerSpawned(const Events::PlayerSpawned &e) if (m_TempPleaseDeleteMeASAP) { return true; } - m_CurrentBGMCombo = createSource("Audio/bgm/layer2.wav"); + m_CurrentBGMCombo = createSource("Audio/BGM/Layer2.wav"); m_CurrentBGMCombo->Type = SoundType::BGM; alSourcei(m_CurrentBGMCombo->ALsource, AL_LOOPING, 1); setGain(m_CurrentBGMCombo, 0); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 5388fd04..ab4b9652 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -10,7 +10,9 @@ #include "Systems/SpawnerSystem.h" #include "Systems/PlayerSpawnSystem.h" #include "Systems/PlayerDeathSystem.h" -#include "Core/EntityFileWriter.h" +#include "Systems/FloatingEffectSystem.h" +#include "Core/EntityFile.h" +#include "Core/EntityXMLFileWriter.h" #include "Game/Systems/CapturePointSystem.h" #include "Game/Systems/CapturePointHUDSystem.h" #include "Game/Systems/PickupSpawnSystem.h" @@ -25,7 +27,11 @@ #include "Rendering/AnimationSystem.h" #include "Network/MultiplayerSnapshotFilter.h" #include "Game/Systems/AmmunitionHUDSystem.h" +#include "Game/Systems/AbilityCooldownHUDSystem.h" +#include "Game/Systems/CapturePointArrowHUDSystem.h" #include "Game/Systems/KillFeedSystem.h" +#include "Game/Systems/BoostSystem.h" +#include "Game/Systems/BoostIconsHUDSystem.h" #include "GUI/ButtonSystem.h" #include "GUI/MainMenuSystem.h" @@ -42,19 +48,19 @@ Game::Game(int argc, char* argv[]) ResourceManager::RegisterType("Png"); ResourceManager::RegisterType("ShaderProgram"); ResourceManager::RegisterType("EntityFile"); + ResourceManager::RegisterType("EntityXMLFile"); ResourceManager::RegisterType("FontFile"); m_Config = ResourceManager::Load("Config.ini"); ResourceManager::UseThreading = m_Config->Get("Multithreading.ResourceLoading", true); DisableMemoryPool::Value = m_Config->Get("Debug.DisableMemoryPool", false); LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get("Debug.LogLevel", 1)); - PlayerSpawnSystem::SetRespawnTime(m_Config->Get("Debug.RespawnTime", 15.0f)); // Create the core event broker m_EventBroker = new EventBroker(); // Create the renderer - m_Renderer = new Renderer(m_EventBroker); + m_Renderer = new Renderer(m_EventBroker, m_Config); m_Renderer->SetFullscreen(m_Config->Get("Video.Fullscreen", false)); m_Renderer->SetVSYNC(m_Config->Get("Video.VSYNC", false)); m_Renderer->SetResolution(Rectangle::Rectangle( @@ -79,10 +85,7 @@ Game::Game(int argc, char* argv[]) std::string mapToLoad = m_Config->Get("Debug.LoadMap", ""); if (!mapToLoad.empty()) { auto file = ResourceManager::Load(mapToLoad); - EntityFilePreprocessor fpp(file); - fpp.RegisterComponents(m_World); - EntityFileParser fp(file); - fp.MergeEntities(m_World); + file->MergeInto(m_World); } // Create the sound manager @@ -119,6 +122,7 @@ Game::Game(int argc, char* argv[]) ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); @@ -132,14 +136,25 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer); m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer); + m_SystemPipeline->AddSystem(updateOrderLevel); // Populate Octree with collidables ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeTrigger, "Player"); - m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeFrustrumCulling); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); @@ -149,6 +164,9 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision); m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeTrigger); + // Octree for frustum culling must be updated after collisions, otherwise players frustum may be moved after tree is filled, and wrong things are culled. + ++updateOrderLevel; + m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeFrustrumCulling); ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer, m_RenderFrame, m_OctreeFrustrumCulling); ++updateOrderLevel; diff --git a/src/Game/Systems/AbilityCooldownHUDSystem.cpp b/src/Game/Systems/AbilityCooldownHUDSystem.cpp new file mode 100644 index 00000000..44180a62 --- /dev/null +++ b/src/Game/Systems/AbilityCooldownHUDSystem.cpp @@ -0,0 +1,30 @@ +#include "Game/Systems/AbilityCooldownHUDSystem.h" + +void AbilityCooldownHUDSystem::Update(double dt) +{ + //HUD element for tracking cooldown on the parent entity with Dashability TODO: Make sure it support other abilities when they are made. + + auto abilityHUDs = m_World->GetComponents("AbilityCooldownHUD"); + if (abilityHUDs == nullptr) + return; + + for (auto& abilityHUDC : *abilityHUDs) { + EntityWrapper entity = EntityWrapper(m_World, abilityHUDC.EntityID); + EntityWrapper abilityEntity = entity.FirstParentWithComponent("DashAbility"); + if (!abilityEntity.Valid()) + return; + EntityWrapper cooldownTextEntity = entity.FirstChildByName("Cooldown"); + if(cooldownTextEntity.Valid()) { + if(cooldownTextEntity.HasComponent("Text")) + { + double maxAbilityCD = (double)abilityEntity["DashAbility"]["CoolDownMaxTimer"]; + double currentAbilityCD = (double)abilityEntity["DashAbility"]["CoolDownTimer"]; + currentAbilityCD = currentAbilityCD >= 0.0 ? currentAbilityCD : 0.0; + std::string t = (std::string&)cooldownTextEntity["Text"]["Content"] = std::to_string(currentAbilityCD).substr(0, 3); + if(entity.HasComponent("Fill")) { + entity["Fill"]["Percentage"] = currentAbilityCD/maxAbilityCD; //TODO: current time needs to be in the component. + } + } + } + } +} diff --git a/src/Game/Systems/AmmoPickupSystem.cpp b/src/Game/Systems/AmmoPickupSystem.cpp index 250fa494..062efe94 100644 --- a/src/Game/Systems/AmmoPickupSystem.cpp +++ b/src/Game/Systems/AmmoPickupSystem.cpp @@ -3,45 +3,63 @@ AmmoPickupSystem::AmmoPickupSystem(SystemParams params) : System(params) { - EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &AmmoPickupSystem::OnTriggerTouch); + if (IsServer) { + EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &AmmoPickupSystem::OnTriggerTouch); + EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &AmmoPickupSystem::OnTriggerLeave); + } + if (IsClient) { + EVENT_SUBSCRIBE_MEMBER(m_EAmmoPickup, &AmmoPickupSystem::OnAmmoPickup); + } } void AmmoPickupSystem::Update(double dt) { - for (auto it = m_ETriggerTouchVector.begin(); it != m_ETriggerTouchVector.end(); ++it) - { - auto& ammoPickupPosition = *it; - //set the double timer value (value 3) - ammoPickupPosition.DecreaseThisRespawnTimer -= dt; - if (ammoPickupPosition.DecreaseThisRespawnTimer < 0.0) { - //spawn and delete the vector item - auto entityFile = ResourceManager::Load("Schema/Entities/AmmoPickup.xml"); - EntityFileParser parser(entityFile); - EntityID ammoPickupID = parser.MergeEntities(m_World); + if (IsServer) { + auto it = m_ETriggerTouchVector.begin(); + while (it != m_ETriggerTouchVector.end()) { + auto& somePickup = *it; + somePickup.DecreaseThisRespawnTimer -= dt; + if (somePickup.DecreaseThisRespawnTimer < 0.0) { + auto entityFile = ResourceManager::Load("Schema/Entities/AmmoPickup.xml"); + EntityWrapper ammoPickup = entityFile->MergeInto(m_World); - //let the world know a pickup has spawned (graphics effects, etc) - Events::PickupSpawned ePickupSpawned; - ePickupSpawned.Pickup = EntityWrapper(m_World, ammoPickupID); - m_EventBroker->Publish(ePickupSpawned); + //let the world know a pickup has spawned + Events::PickupSpawned ePickupSpawned; + ePickupSpawned.Pickup = ammoPickup; + m_EventBroker->Publish(ePickupSpawned); - //set values from the old entity to the new entity - auto& newAmmoPickupEntity = EntityWrapper(m_World, ammoPickupID); - newAmmoPickupEntity["Transform"]["Position"] = ammoPickupPosition.Pos; - newAmmoPickupEntity["AmmoPickup"]["AmmoGain"] = ammoPickupPosition.AmmoGain; - newAmmoPickupEntity["AmmoPickup"]["RespawnTimer"] = ammoPickupPosition.RespawnTimer; - m_World->SetParent(newAmmoPickupEntity.ID, ammoPickupPosition.parentID); + //copy values from the old entity to the new entity + auto& newAmmoPickupEntity = ammoPickup; + newAmmoPickupEntity["Transform"]["Position"] = somePickup.Pos; + newAmmoPickupEntity["AmmoPickup"]["AmmoGain"] = somePickup.AmmoGain; + newAmmoPickupEntity["AmmoPickup"]["RespawnTimer"] = somePickup.RespawnTimer; + m_World->SetParent(newAmmoPickupEntity.ID, somePickup.parentID); - //erase the current element (AmmoPickupPosition) - m_ETriggerTouchVector.erase(it); - break; + //erase the current element (somePickup) + it = m_ETriggerTouchVector.erase(it); + } + else { + it++; + } + } + //still touching m_PickupAtMaximum? + for (auto& it = m_PickupAtMaximum.begin(); it != m_PickupAtMaximum.end(); ++it) { + if (!it->player.Valid()) { + m_PickupAtMaximum.erase(it); + break; + } + if ((int)it->player["AssaultWeapon"]["Ammo"] < (int)it->player["AssaultWeapon"]["MaxAmmo"]) { + DoPickup(it->player, it->trigger); + m_PickupAtMaximum.erase(it); + break; + } } } } - bool AmmoPickupSystem::OnTriggerTouch(Events::TriggerTouch& e) { - if (e.Entity != LocalPlayer) { + if (!e.Entity.Valid()) { return false; } //TODO: add other weapontypes @@ -51,29 +69,68 @@ bool AmmoPickupSystem::OnTriggerTouch(Events::TriggerTouch& e) if (!e.Trigger.HasComponent("AmmoPickup")) { return false; } - int maxWeaponAmmo = (int)e.Entity["AssaultWeapon"]["MaxAmmo"]; - int& currentAmmo = (int)e.Entity["AssaultWeapon"]["Ammo"]; - int ammoGiven = 0.01*(double)e.Trigger["AmmoPickup"]["AmmoGain"] * maxWeaponAmmo; + //if at maxammo, save the trigger-touch to a vector since standing inside it will not re-trigger the trigger + if ((int)e.Entity["AssaultWeapon"]["Ammo"] >= (int)e.Entity["AssaultWeapon"]["MaxAmmo"]) { + m_PickupAtMaximum.push_back({ e.Entity, e.Trigger }); + return false; + } + DoPickup(e.Entity, e.Trigger); + return true; +} + +bool AmmoPickupSystem::OnAmmoPickup(Events::AmmoPickup & e) +{ + if (!e.Player.Valid()) { + return false; + } + //TODO: add other weapontypes + if (!e.Player.HasComponent("AssaultWeapon")) { + 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 if (currentAmmo >= maxWeaponAmmo) { return false; } - //personEntered = e.Entity, thingEntered = e.Trigger + currentAmmo = std::min(currentAmmo + e.AmmoGain, maxWeaponAmmo); + return false; +} + +bool AmmoPickupSystem::OnTriggerLeave(Events::TriggerLeave& e) { + if (!e.Trigger.HasComponent("AmmoPickup")) { + return false; + } + //triggerleave erases possible m_PickupAtMaximum + for (auto& it = m_PickupAtMaximum.begin(); it != m_PickupAtMaximum.end(); ++it) { + if (it->trigger.ID == e.Trigger.ID && it->player.ID == e.Entity.ID) { + m_PickupAtMaximum.erase(it); + break; + } + } + return true; +} + +void AmmoPickupSystem::DoPickup(EntityWrapper &player, EntityWrapper &trigger) { + int maxWeaponAmmo = (int)player["AssaultWeapon"]["MaxAmmo"]; + int& currentAmmo = (int)player["AssaultWeapon"]["Ammo"]; + int ammoGiven = 0.01*(double)trigger["AmmoPickup"]["AmmoGain"] * maxWeaponAmmo; + Events::AmmoPickup ePlayerAmmoPickup; ePlayerAmmoPickup.AmmoGain = ammoGiven; - ePlayerAmmoPickup.Player = e.Entity; + ePlayerAmmoPickup.Player = player; m_EventBroker->Publish(ePlayerAmmoPickup); - //immediately give the player the ammo + + //immediately give the player the ammo (on server) currentAmmo = std::min(currentAmmo + ammoGiven, maxWeaponAmmo); //copy position, ammogain, respawntimer (twice since one of the values will be counted down to 0, the other will be set in the new object) //we need to copy all values since each value can be different for each ammoPickup - m_ETriggerTouchVector.push_back({ e.Trigger["Transform"]["Position"], e.Trigger["AmmoPickup"]["AmmoGain"], - e.Trigger["AmmoPickup"]["RespawnTimer"], e.Trigger["AmmoPickup"]["RespawnTimer"], m_World->GetParent(e.Trigger.ID) }); + m_ETriggerTouchVector.push_back({ (glm::vec3)trigger["Transform"]["Position"], trigger["AmmoPickup"]["AmmoGain"], + trigger["AmmoPickup"]["RespawnTimer"], trigger["AmmoPickup"]["RespawnTimer"], m_World->GetParent(trigger.ID) }); //delete the ammopickup - m_World->DeleteEntity(e.Trigger.ID); - return true; + m_World->DeleteEntity(trigger.ID); } diff --git a/src/Game/Systems/BoostIconsHUDSystem.cpp b/src/Game/Systems/BoostIconsHUDSystem.cpp new file mode 100644 index 00000000..f83278ff --- /dev/null +++ b/src/Game/Systems/BoostIconsHUDSystem.cpp @@ -0,0 +1,42 @@ +#include "Game/Systems/BoostIconsHUDSystem.h" + +void BoostIconsHUDSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& capturePoint, double dt) +{ + EntityWrapper assaultEntity = entity.FirstChildByName("Assault"); + EntityWrapper defenderEntity = entity.FirstChildByName("Defender"); + EntityWrapper sniperEntity = entity.FirstChildByName("Sniper"); + + if(assaultEntity.Valid()) { + if (assaultEntity.HasComponent("Fill")) { + EntityWrapper parentWithAssaultBoost = assaultEntity.FirstParentWithComponent("BoostAssault"); + if (parentWithAssaultBoost.Valid()) { + (double&)assaultEntity["Fill"]["Percentage"] = 1.0; + } else { + (double&)assaultEntity["Fill"]["Percentage"] = 0.0; + } + } + } + + if (defenderEntity.Valid()) { + if (defenderEntity.HasComponent("Fill")) { + EntityWrapper parentWithAssaultBoost = defenderEntity.FirstParentWithComponent("BoostDefender"); + if (parentWithAssaultBoost.Valid()) { + (double&)defenderEntity["Fill"]["Percentage"] = 1.0; + } else { + (double&)defenderEntity["Fill"]["Percentage"] = 0.0; + } + } + } + + if (sniperEntity.Valid()) { + if (sniperEntity.HasComponent("Fill")) { + EntityWrapper parentWithAssaultBoost = sniperEntity.FirstParentWithComponent("BoostSniper"); + if (parentWithAssaultBoost.Valid()) { + (double&)sniperEntity["Fill"]["Percentage"] = 1.0; + } else { + (double&)sniperEntity["Fill"]["Percentage"] = 0.0; + } + } + } +} + diff --git a/src/Game/Systems/BoostSystem.cpp b/src/Game/Systems/BoostSystem.cpp new file mode 100644 index 00000000..c79576e4 --- /dev/null +++ b/src/Game/Systems/BoostSystem.cpp @@ -0,0 +1,62 @@ +#include "Systems/BoostSystem.h" + +BoostSystem::BoostSystem(SystemParams params) + : System(params) +{ + EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &BoostSystem::OnPlayerDamage); +} + +bool BoostSystem::OnPlayerDamage(Events::PlayerDamage& e) +{ + if (e.Victim.ID == e.Inflictor.ID) { + return false; + } + if (!e.Victim.Valid() && e.Victim != LocalPlayer && !e.Victim.IsChildOf(LocalPlayer)) { + return false; + } + if (!e.Inflictor.Valid() || !e.Victim.Valid()) { + return false; + } + + //if its not friendly fire, return + if ((int)m_World->GetComponent(e.Inflictor.ID, "Team")["Team"] != (int)m_World->GetComponent(e.Victim.ID, "Team")["Team"]) { + return false; + } + + //determine the inflictors class + auto className = DetermineClass(e.Inflictor); + if (className == "") { + return false; + } + + //get the XML file, example: "Schema/Entities/BoostclassName.xml" + std::string classXML = "Schema/Entities/" + className + ".xml"; + + //check if player already has a child with the component, if so delete that child + auto playerBoostAssaultEntity = e.Victim.FirstChildByName(className); + if (playerBoostAssaultEntity.Valid()) { + m_World->DeleteEntity(playerBoostAssaultEntity.ID); + } + //load boost XML file, set it entity parented with the victim player + auto entityFile = ResourceManager::Load(classXML); + EntityWrapper boostAssaultEntity = entityFile->MergeInto(m_World); + m_World->SetName(boostAssaultEntity.ID, className); + m_World->SetParent(boostAssaultEntity.ID, e.Victim.ID); + + return true; +} + +std::string BoostSystem::DetermineClass(EntityWrapper inflictorPlayer) +{ + //determine the class based on what component the inflictor-player has + if (m_World->HasComponent(inflictorPlayer.ID, "DashAbility")) { + return "BoostAssault"; + } + if (m_World->HasComponent(inflictorPlayer.ID, "ShieldAbility")) { + return "BoostDefender"; + } + if (m_World->HasComponent(inflictorPlayer.ID, "SprintAbility")) { + return "BoostSniper"; + } + return ""; +} diff --git a/src/Game/Systems/CapturePointArrowHUDSystem.cpp b/src/Game/Systems/CapturePointArrowHUDSystem.cpp new file mode 100644 index 00000000..9e327a43 --- /dev/null +++ b/src/Game/Systems/CapturePointArrowHUDSystem.cpp @@ -0,0 +1,183 @@ +#include "Systems/CapturePointArrowHUDSystem.h" + +CapturePointArrowHUDSystem::CapturePointArrowHUDSystem(SystemParams params) + : System(params) + , ImpureSystem() +{ + EVENT_SUBSCRIBE_MEMBER(m_ECapturedEvent, &CapturePointArrowHUDSystem::OnCapturePointCaptured); +} + + +void CapturePointArrowHUDSystem::Update(double dt) +{ + bool loadCheck = true; + int redTeamEnum; + int blueTeamEnum; + int spectatorTeamEnum; + + //Get list for all CapturePointArrowHUDComponents + auto arrowHUDs = m_World->GetComponents("CapturePointArrowHUD"); + auto capturePoints = m_World->GetComponents("CapturePoint"); + if(arrowHUDs == nullptr) { + return; + } + + for(auto& cArrowHUD : *arrowHUDs) { + //Get what team the current arrow corresponds to + EntityWrapper arrowEntity = EntityWrapper(m_World, cArrowHUD.EntityID); + if (!arrowEntity.Valid()) { + continue; + } + if(!arrowEntity.HasComponent("Team")) { + continue; + } + auto cTeam = arrowEntity["Team"]; + int currentTeam = (int)cTeam["Team"]; + + if (loadCheck) { + redTeamEnum = (int)cTeam["Team"].Enum("Red"); + blueTeamEnum = (int)cTeam["Team"].Enum("Blue"); + spectatorTeamEnum = (int)cTeam["Team"].Enum("Spectator"); + loadCheck = false; + + + if (!m_InitialtargetsSet) { + std::unordered_map blueTargets, redTargets; + EntityWrapper homeBlue, homeRed; + int lastCP = -INFINITY; + int firstCP = INFINITY; + + for (auto& cCP : *capturePoints) { + auto homePointTeam = (int)cCP["HomePointForTeam"]; + EntityWrapper capturePointEntity = EntityWrapper(m_World, cCP.EntityID); + int capturePointID = (int)capturePointEntity["CapturePoint"]["CapturePointNumber"]; + + if(capturePointID < firstCP) { + firstCP = capturePointID; + } + + if(capturePointID > lastCP) { + lastCP = capturePointID; + } + + if (!capturePointEntity.HasComponent("Team")) { + continue; + } + + int currentOwner = (int)capturePointEntity["Team"]["Team"]; + + if(currentOwner != redTeamEnum) { + //This capturePoint is not owned by the red team and is therefor an eligible target for red team + glm::vec3 targetPos = Transform::AbsolutePosition(capturePointEntity); + redTargets.insert(std::pair(capturePointID, targetPos)); + } + if(currentOwner != blueTeamEnum) { + //This capturePoint is not owned by the blue team and is therefor an eligible target for blue team + glm::vec3 targetPos = Transform::AbsolutePosition(capturePointEntity); + blueTargets.insert(std::pair(capturePointID, targetPos)); + } + + if(homePointTeam == blueTeamEnum) { + //CP is the home point for blue team. + homeBlue = capturePointEntity; + } else if (homePointTeam == redTeamEnum) { + //CP is the home point for red team. + homeRed = capturePointEntity; + } + } + + if(!homeRed.Valid() || !homeBlue.Valid()) { + //One or both teams have no home point, cant continue + return; + } + + std::unordered_map::const_iterator got; + //Find next target for red team. + if((int)homeRed["CapturePoint"]["CapturePointNumber"] == lastCP) { + //Red home base is the last capture point, count back from lastCP and find next target + for (int i = lastCP; i >= firstCP; i--) { + got = redTargets.find(i); + if(got == redTargets.end()) { + continue; + } else { + m_RedTeamCurrentTarget = got->second; + break; + } + } + } else if ((int)homeRed["CapturePoint"]["CapturePointNumber"] == firstCP) { + //Red home is the first capture point, count forward from firstCP and find next target. + for (int i = firstCP; i <= lastCP; i++) { + got = redTargets.find(i); + if(got == redTargets.end()) { + //Target was not found, try the next one after that. + continue; + } else { + m_RedTeamCurrentTarget = got->second; + break; + } + } + } + + //Find next target for blue team + if ((int)homeBlue["CapturePoint"]["CapturePointNumber"] == lastCP) { + //Red home base is the last capture point, count back from lastCP and find next target + for (int i = lastCP; i >= firstCP; i--) { + got = blueTargets.find(i); + if (got == blueTargets.end()) { + continue; + } else { + m_BlueTeamCurrentTarget = got->second; + break; + } + } + } else if ((int)homeBlue["CapturePoint"]["CapturePointNumber"] == firstCP) { + //Red home is the first capture point, count forward from firstCP and find next target. + for (int i = firstCP; i <= lastCP; i++) { + got = blueTargets.find(i); + if (got == blueTargets.end()) { + //Target was not found, try the next one after that. + continue; + } else { + m_BlueTeamCurrentTarget = got->second; + break; + } + } + } + } + } + //if red team, get red team next point, otherwise blue team next point. + //Untill this is awailable we will just use the hardcoded value in the component. + //This will also give us a position, so we wont need to loop through all capturePoints. + glm::vec3 pos; + if(currentTeam == redTeamEnum) { + pos = m_RedTeamCurrentTarget; + } else if (currentTeam == blueTeamEnum) { + pos = m_BlueTeamCurrentTarget; + } + + glm::vec3& arrowOri = arrowEntity["Transform"]["Orientation"]; + glm::vec3 lookVector = glm::normalize(Transform::AbsolutePosition(arrowEntity) - pos); //Maybe should be player instead + float pitch = std::asin(-lookVector.y); + float yaw = std::atan2(lookVector.x, lookVector.z); + arrowOri.x = pitch; + arrowOri.y = yaw; + arrowOri.z = 0.f; + EntityWrapper parent = arrowEntity.Parent(); + if (parent.Valid()) { + arrowOri -= Transform::AbsoluteOrientationEuler(parent); + } + } +} + +bool CapturePointArrowHUDSystem::OnCapturePointCaptured(Events::Captured& e) +{ + if(!e.BlueTeamNextCapturePoint.Valid() || !e.RedTeamNextCapturePoint.Valid()) { + return 0; + } + + m_RedTeamCurrentTarget = Transform::AbsolutePosition(e.RedTeamNextCapturePoint); + m_BlueTeamCurrentTarget = Transform::AbsolutePosition(e.BlueTeamNextCapturePoint); + + m_InitialtargetsSet = true; + return 0; +} diff --git a/src/Game/Systems/CapturePointSystem.cpp b/src/Game/Systems/CapturePointSystem.cpp index c99a36a6..0d6089c5 100644 --- a/src/Game/Systems/CapturePointSystem.cpp +++ b/src/Game/Systems/CapturePointSystem.cpp @@ -6,7 +6,7 @@ CapturePointSystem::CapturePointSystem(SystemParams params) , PureSystem("CapturePoint") { //subscribe/listenTo playerdamage,healthpickup events (using the eventBroker) - if (!IsClient) { + if (IsServer) { EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &CapturePointSystem::OnTriggerTouch); EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &CapturePointSystem::OnTriggerLeave); EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &CapturePointSystem::OnCaptured); @@ -18,7 +18,7 @@ CapturePointSystem::CapturePointSystem(SystemParams params) //NOTE: needs to run each frame, since we're possibly modifying the captureTimer for the capturePoints by dt void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, ComponentWrapper& cCapturePoint, double dt) { - if (IsClient) { + if (!IsServer) { return; } if (m_WinnerWasFound) { @@ -102,6 +102,12 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp nextPossibleCapturePoint["Blue"] = i - 1; } } + if (m_RecentlyCapturedNeedNextCapturePointNow) { + m_CapturedEvent.BlueTeamNextCapturePoint = m_CapturePointNumberToEntityMap[nextPossibleCapturePoint["Blue"]]; + m_CapturedEvent.RedTeamNextCapturePoint = m_CapturePointNumberToEntityMap[nextPossibleCapturePoint["Red"]]; + m_EventBroker->Publish(m_CapturedEvent); + m_RecentlyCapturedNeedNextCapturePointNow = false; + } //reset timers and reset the bool that triggers this if (m_ResetTimers) { @@ -188,10 +194,9 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp teamComponent["Team"] = currentTeam; cCapturePoint["CaptureTimer"] = glm::sign((double)cCapturePoint["CaptureTimer"])*captureTimeToTakeOver; //publish Captured event - Events::Captured e; - e.CapturePointID = cCapturePoint.EntityID; - e.TeamNumberThatCapturedCapturePoint = currentTeam; - m_EventBroker->Publish(e); + m_RecentlyCapturedNeedNextCapturePointNow = true; + m_CapturedEvent.CapturePointTakenID = cCapturePoint.EntityID; + m_CapturedEvent.TeamNumberThatCapturedCapturePoint = currentTeam; //NextPossibleCapturePoint will be calculated in the next update... } } diff --git a/src/Game/Systems/DamageIndicatorSystem.cpp b/src/Game/Systems/DamageIndicatorSystem.cpp index ca26052d..e68f741d 100644 --- a/src/Game/Systems/DamageIndicatorSystem.cpp +++ b/src/Game/Systems/DamageIndicatorSystem.cpp @@ -9,7 +9,7 @@ DamageIndicatorSystem::DamageIndicatorSystem(SystemParams params) //load texture to cache auto texture = CommonFunctions::LoadTexture("Textures/DamageIndicator.png", false); - auto entityFile = ResourceManager::Load("Schema/Entities/DamageIndicator.xml"); + auto entityFile = ResourceManager::Load("Schema/Entities/DamageIndicator.xml"); } void DamageIndicatorSystem::Update(double dt) { @@ -50,15 +50,13 @@ bool DamageIndicatorSystem::OnPlayerDamage(Events::PlayerDamage& e) //load & set the "2d" sprite auto entityFile = ResourceManager::Load("Schema/Entities/DamageIndicator.xml"); - EntityFileParser parser(entityFile); - EntityID spriteID = parser.MergeEntities(m_World); - m_World->SetParent(spriteID, m_CurrentCamera); - auto spriteWrapper = EntityWrapper(m_World, spriteID); + EntityWrapper sprite = entityFile->MergeInto(m_World); + m_World->SetParent(sprite.ID, m_CurrentCamera); //simply set the rotation z-wise to the angleBetweenVectors - spriteWrapper["Transform"]["Orientation"] = glm::vec3(0, 0, angleBetweenVectors); + sprite["Transform"]["Orientation"] = glm::vec3(0, 0, angleBetweenVectors); if (!IsServer) { - updateDamageIndicatorVector.emplace_back(spriteWrapper, inflictorPos); + updateDamageIndicatorVector.emplace_back(sprite, inflictorPos); } return true; @@ -127,8 +125,8 @@ glm::vec3 DamageIndicatorSystem::DamageIndicatorTest(EntityWrapper player) { auto inflictorPos = glm::vec3(currentPos.x + testVar*6.0f, currentPos.y, currentPos.z + testVar2*6.0f); //load the explosioneffect XML - auto deathEffect = ResourceManager::Load("Schema/Entities/PlayerDeathExplosionWithCamera.xml"); - EntityFileParser parser(deathEffect); + auto deathEffect = ResourceManager::Load("Schema/Entities/PlayerDeathExplosionWithCamera.xml"); + EntityXMLFileParser parser(deathEffect); EntityID deathEffectID = parser.MergeEntities(m_World); EntityWrapper deathEffectEW = EntityWrapper(m_World, deathEffectID); diff --git a/src/Game/Systems/HealthSystem.cpp b/src/Game/Systems/HealthSystem.cpp index 94f23c67..b4ace6b9 100644 --- a/src/Game/Systems/HealthSystem.cpp +++ b/src/Game/Systems/HealthSystem.cpp @@ -30,6 +30,11 @@ bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e) ComponentWrapper cHealth = e.Victim["Health"]; double& health = cHealth["Health"]; + //if player has the boost from a defender, subtract the damage taken by StrengthOfEffect amount + auto playerBoostDefenderEntity = e.Victim.FirstChildByName("BoostDefender"); + if (playerBoostDefenderEntity.Valid()) { + e.Damage -= (double)playerBoostDefenderEntity["BoostDefender"]["StrengthOfEffect"]; + } health -= e.Damage; return true; diff --git a/src/Game/Systems/PickupSpawnSystem.cpp b/src/Game/Systems/PickupSpawnSystem.cpp index abf59007..99da931f 100644 --- a/src/Game/Systems/PickupSpawnSystem.cpp +++ b/src/Game/Systems/PickupSpawnSystem.cpp @@ -3,65 +3,99 @@ PickupSpawnSystem::PickupSpawnSystem(SystemParams params) : System(params) { - EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &PickupSpawnSystem::OnTriggerTouch); + if (IsServer) { + EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &PickupSpawnSystem::OnTriggerTouch); + EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &PickupSpawnSystem::OnTriggerLeave); + } } void PickupSpawnSystem::Update(double dt) { - for (auto it = m_ETriggerTouchVector.begin(); it != m_ETriggerTouchVector.end(); ++it) - { - auto& healthPickupPosition = *it; - //set the double timer value (value 3) - healthPickupPosition.DecreaseThisRespawnTimer -= dt; - if (healthPickupPosition.DecreaseThisRespawnTimer < 0) { - //spawn and delete the vector item - auto entityFile = ResourceManager::Load("Schema/Entities/HealthPickup.xml"); - EntityFileParser parser(entityFile); - EntityID healthPickupID = parser.MergeEntities(m_World); + if (IsServer) { + auto it = m_ETriggerTouchVector.begin(); + while (it != m_ETriggerTouchVector.end()) { + auto& somePickup = *it; + somePickup.DecreaseThisRespawnTimer -= dt; + if (somePickup.DecreaseThisRespawnTimer < 0.0) { + //spawn the new healthPickup + auto entityFile = ResourceManager::Load("Schema/Entities/HealthPickup.xml"); + EntityWrapper healthPickup = entityFile->MergeInto(m_World); - //let the world know a pickup has spawned (graphics effects, etc) - Events::PickupSpawned ePickupSpawned; - ePickupSpawned.Pickup = EntityWrapper(m_World, healthPickupID); - m_EventBroker->Publish(ePickupSpawned); + //let the world know a pickup has spawned (graphics effects, etc) + Events::PickupSpawned ePickupSpawned; + ePickupSpawned.Pickup = healthPickup; + m_EventBroker->Publish(ePickupSpawned); - //set values from the old entity to the new entity - auto& newHealthPickupEntity = EntityWrapper(m_World, healthPickupID); - newHealthPickupEntity["Transform"]["Position"] = healthPickupPosition.Pos; - newHealthPickupEntity["HealthPickup"]["HealthGain"] = healthPickupPosition.HealthGain; - newHealthPickupEntity["HealthPickup"]["RespawnTimer"] = healthPickupPosition.RespawnTimer; - m_World->SetParent(newHealthPickupEntity.ID, healthPickupPosition.parentID); + //copy values from the old entity to the new entity + auto& newHealthPickupEntity = healthPickup; + newHealthPickupEntity["Transform"]["Position"] = somePickup.Pos; + newHealthPickupEntity["HealthPickup"]["HealthGain"] = somePickup.HealthGain; + newHealthPickupEntity["HealthPickup"]["RespawnTimer"] = somePickup.RespawnTimer; + m_World->SetParent(newHealthPickupEntity.ID, somePickup.parentID); - //erase the current element (healthPickupPosition) - m_ETriggerTouchVector.erase(it); - break; + //erase the current element (somePickup) + it = m_ETriggerTouchVector.erase(it); + } else { + it++; + } + } + //still touching PickupAtMaximum? + for (auto& it = m_PickupAtMaximum.begin(); it != m_PickupAtMaximum.end(); ++it) { + if (!it->player.Valid()) { + m_PickupAtMaximum.erase(it); + break; + } + if ((double)it->player["Health"]["Health"] < (double)it->player["Health"]["MaxHealth"]) { + DoPickup(it->player, it->trigger); + m_PickupAtMaximum.erase(it); + break; + } } } } - - bool PickupSpawnSystem::OnTriggerTouch(Events::TriggerTouch& e) { if (!e.Trigger.HasComponent("HealthPickup")) { return false; } - double healthGiven = 0.01*(double)e.Trigger["HealthPickup"]["HealthGain"] * (double)e.Entity["Health"]["MaxHealth"]; - //cant pick up healthpacks if you are already at MaxHealth + //if at maxhealth, save the trigger-touch to a vector since standing inside it will not re-trigger the trigger if ((double)e.Entity["Health"]["Health"] >= (double)e.Entity["Health"]["MaxHealth"]) { + m_PickupAtMaximum.push_back({ e.Entity, e.Trigger }); return false; } - //personEntered = e.Entity, thingEntered = e.Trigger + DoPickup(e.Entity, e.Trigger); + return true; +} +bool PickupSpawnSystem::OnTriggerLeave(Events::TriggerLeave& e) +{ + if (!e.Trigger.HasComponent("HealthPickup")) { + return false; + } + //triggerleave erases possible m_PickupAtMaximum + for (auto& it = m_PickupAtMaximum.begin(); it != m_PickupAtMaximum.end(); ++it) { + if (it->trigger.ID == e.Trigger.ID && it->player.ID == e.Entity.ID) { + m_PickupAtMaximum.erase(it); + break; + } + } + return true; +} +void PickupSpawnSystem::DoPickup(EntityWrapper &player, EntityWrapper &trigger) +{ + double healthGiven = 0.01*(double)trigger["HealthPickup"]["HealthGain"] * (double)player["Health"]["MaxHealth"]; + + //only the server will increase the players hp and set it in the next delta Events::PlayerHealthPickup ePlayerHealthPickup; ePlayerHealthPickup.HealthAmount = healthGiven; - ePlayerHealthPickup.Player = e.Entity; + ePlayerHealthPickup.Player = player; m_EventBroker->Publish(ePlayerHealthPickup); //copy position, healthgain, respawntimer (twice since one of the values will be counted down to 0, the other will be set in the new object) //we need to copy all values since each value can be different for each healthPickup - m_ETriggerTouchVector.push_back({ (glm::vec3)e.Trigger["Transform"]["Position"] ,e.Trigger["HealthPickup"]["HealthGain"], - e.Trigger["HealthPickup"]["RespawnTimer"],e.Trigger["HealthPickup"]["RespawnTimer"], m_World->GetParent(e.Trigger.ID) }); + m_ETriggerTouchVector.push_back({ (glm::vec3)trigger["Transform"]["Position"], trigger["HealthPickup"]["HealthGain"], + trigger["HealthPickup"]["RespawnTimer"], trigger["HealthPickup"]["RespawnTimer"], m_World->GetParent(trigger.ID) }); //delete the healthpickup - m_World->DeleteEntity(e.Trigger.ID); - return true; + m_World->DeleteEntity(trigger.ID); } diff --git a/src/Game/Systems/PlayerDeathSystem.cpp b/src/Game/Systems/PlayerDeathSystem.cpp index 844d2ed1..cbf0927f 100644 --- a/src/Game/Systems/PlayerDeathSystem.cpp +++ b/src/Game/Systems/PlayerDeathSystem.cpp @@ -4,6 +4,7 @@ PlayerDeathSystem::PlayerDeathSystem(SystemParams params) : System(params) { EVENT_SUBSCRIBE_MEMBER(m_OnPlayerDeath, &PlayerDeathSystem::OnPlayerDeath); + EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &PlayerDeathSystem::OnEntityDeleted); } void PlayerDeathSystem::Update(double dt) @@ -27,10 +28,8 @@ bool PlayerDeathSystem::OnPlayerDeath(Events::PlayerDeath& e) void PlayerDeathSystem::createDeathEffect(EntityWrapper player) { //load the explosioneffect XML - auto deathEffect = ResourceManager::Load("Schema/Entities/PlayerDeathExplosionWithCamera.xml"); - EntityFileParser parser(deathEffect); - EntityID deathEffectID = parser.MergeEntities(m_World); - EntityWrapper deathEffectEW = EntityWrapper(m_World, deathEffectID); + auto entityFile = ResourceManager::Load("Schema/Entities/PlayerDeathExplosionWithCamera.xml"); + EntityWrapper deathEffectEW = entityFile->MergeInto(m_World); //components that we need from player auto playerModel = player.FirstChildByName("PlayerModel"); @@ -59,9 +58,28 @@ void PlayerDeathSystem::createDeathEffect(EntityWrapper player) //camera (with lifetime) behind the player if (player == LocalPlayer) { + m_LocalPlayerDeathEffect = deathEffectEW; auto cam = deathEffectEW.FirstChildByName("Camera"); Events::SetCamera eSetCamera; eSetCamera.CameraEntity = cam; m_EventBroker->Publish(eSetCamera); } } + +bool PlayerDeathSystem::OnEntityDeleted(Events::EntityDeleted& e) +{ + // We only care about when the local players death effect is removed. + if (m_LocalPlayerDeathEffect.ID != e.DeletedEntity) { + return false; + } + + // Look for the spectator camera entity in the level. + EntityWrapper spectatorCam = m_World->GetFirstEntityByName("SpectatorCamera"); + if (!spectatorCam.Valid() || !spectatorCam.HasComponent("Camera") || LocalPlayer.Valid()) { + return false; + } + Events::SetCamera eSetCamera; + eSetCamera.CameraEntity = spectatorCam; + m_EventBroker->Publish(eSetCamera); + return true; +} diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 2e2502ec..72008e05 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -5,6 +5,7 @@ PlayerMovementSystem::PlayerMovementSystem(SystemParams params) { EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &PlayerMovementSystem::OnPlayerSpawned); EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &PlayerMovementSystem::OnDoubleJump); + EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &PlayerMovementSystem::OnDashAbility); } PlayerMovementSystem::~PlayerMovementSystem() @@ -17,14 +18,9 @@ PlayerMovementSystem::~PlayerMovementSystem() void PlayerMovementSystem::Update(double dt) { updateMovementControllers(dt); - if (IsServer) { - for (auto& kv : m_PlayerInputControllers) { - updateVelocity(kv.first, dt); - } - } else { - if (LocalPlayer.Valid()) { - updateVelocity(LocalPlayer, dt); - } + // Only do physics calculations on client and only for themselves. + if (IsClient && LocalPlayer.Valid()) { + updateVelocity(LocalPlayer, dt); } } @@ -48,7 +44,7 @@ void PlayerMovementSystem::updateMovementControllers(double dt) EntityWrapper playerModel = player.FirstChildByName("PlayerModel"); if (playerModel.Valid()) { ComponentWrapper cAnimationOffset = playerModel["AnimationOffset"]; - float pitch = cameraOrientation.x + 0.2; + float pitch = cameraOrientation.x + 0.2f; double time = (pitch + glm::half_pi()) / glm::pi(); cAnimationOffset["Time"] = time; } @@ -61,12 +57,18 @@ void PlayerMovementSystem::updateMovementControllers(double dt) float playerMovementSpeed = player["Player"]["MovementSpeed"]; float playerCrouchSpeed = player["Player"]["CrouchSpeed"]; glm::vec3& wishDirection = player["Player"]["CurrentWishDirection"]; + auto playerBoostAssaultEntity = player.FirstChildByName("BoostAssault"); + if (playerBoostAssaultEntity.Valid()) { + playerMovementSpeed *= (double)playerBoostAssaultEntity["BoostAssault"]["StrengthOfEffect"]; + playerCrouchSpeed *= (double)playerBoostAssaultEntity["BoostAssault"]["StrengthOfEffect"]; + } + if (player.HasComponent("Physics")) { ComponentWrapper cPhysics = player["Physics"]; //Assault Dash Check if (player.HasComponent("DashAbility")) { - controller->AssaultDashCheck(dt, ((glm::vec3)cPhysics["Velocity"]).y != 0.0f, player["DashAbility"]["CoolDownMaxTimer"]); + controller->AssaultDashCheck(dt, ((glm::vec3)cPhysics["Velocity"]).y != 0.0f, player["DashAbility"]["CoolDownMaxTimer"], player["DashAbility"]["CoolDownTimer"], player.ID); } wishDirection = controller->Movement() * glm::inverse(glm::quat(ori)); //this makes sure you can only dash in the 4 directions: forw,backw,left,right @@ -112,16 +114,26 @@ void PlayerMovementSystem::updateMovementControllers(double dt) //if doubleTapped do Assault Dash - but only boost maximum 50.0f float doubleTapDashBoost = controller->AssaultDashDoubleTapped() ? 40.0f : 1.0f; accelerationSpeed = glm::min(doubleTapDashBoost*glm::min(accelerationSpeed, addSpeed), 50.0f); + //if player has Boost from an Assault class, accelerate the player faster + if (playerBoostAssaultEntity.Valid()) { + accelerationSpeed *= (double)playerBoostAssaultEntity["BoostAssault"]["StrengthOfEffect"]; + } velocity += accelerationSpeed * wishDirection; ImGui::Text("velocity: (%f, %f, %f) |%f|", velocity.x, velocity.y, velocity.z, glm::length(velocity)); } - //you cant jump and dash at the same time - since there is no friction in the air and we would thus dash much further in the air - if (!controller->PlayerIsDashing() && controller->Jumping() && !controller->Crouching() && (isOnGround || !controller->DoubleJumping())) { - (bool)cPhysics["IsOnGround"] = false; + if (isOnGround) { + controller->SetDoubleJumping(false); + } + //If player presses Jump and is not crouching. + if (controller->Jumping() && !controller->Crouching()) { if (isOnGround) { - controller->SetDoubleJumping(false); - } else { + (bool)cPhysics["IsOnGround"] = false; + velocity.y = player["Player"]["JumpSpeed"]; + } else if (player.HasComponent("DoubleJump") && !controller->DoubleJumping()) { + //Enter here if player can double jump and is doing so. + (bool)cPhysics["IsOnGround"] = false; + velocity.y = player["DoubleJump"]["DoubleJumpSpeed"]; // If IsServer and network is off this will not work if (IsClient) { //put a hexagon at the players feet @@ -133,7 +145,6 @@ void PlayerMovementSystem::updateMovementControllers(double dt) m_EventBroker->Publish(e); } } - velocity.y = 4.f; } if (player.HasComponent("AABB")) { @@ -298,22 +309,45 @@ bool PlayerMovementSystem::OnPlayerSpawned(Events::PlayerSpawned& e) bool PlayerMovementSystem::OnDoubleJump(Events::DoubleJump & e) { // If entity does not exist, exit - if (!EntityWrapper(m_World, e.entityID).Valid()) { + if (!EntityWrapper(m_World, e.entityID).Valid()) { return false; } // If entity IsLocalPlayer, exit - if (e.entityID == m_LocalPlayer.ID) { + if (e.entityID == m_LocalPlayer.ID) { return false; } spawnHexagon(EntityWrapper(m_World, e.entityID)); + return true; } void PlayerMovementSystem::spawnHexagon(EntityWrapper target) -{ +{ //put a hexagon at the entitys... feet? - auto hexagonEffect = ResourceManager::Load("Schema/Entities/DoubleJumpHexagon.xml"); - EntityFileParser parser(hexagonEffect); - EntityID hexagonEffectID = parser.MergeEntities(m_World); - EntityWrapper hexagonEW = EntityWrapper(m_World, hexagonEffectID); + auto entityFile = ResourceManager::Load("Schema/Entities/DoubleJumpHexagon.xml"); + EntityWrapper hexagonEW = entityFile->MergeInto(m_World); hexagonEW["Transform"]["Position"] = (glm::vec3)target["Transform"]["Position"]; -} \ No newline at end of file +} + +bool PlayerMovementSystem::OnDashAbility(Events::DashAbility & e) +{ + EntityWrapper player(m_World, e.Player); + if (!player.Valid() || !IsClient || player.ID == LocalPlayer.ID) { + return false; + } + + auto entityFile = ResourceManager::Load("Schema/Entities/DashEffect.xml"); + EntityWrapper dashEffect = entityFile->MergeInto(m_World); + auto playerModel = player.FirstChildByName("PlayerModel"); + auto playerEntityModel = playerModel["Model"]; + auto playerEntityAnimation = playerModel["Animation"]; + playerEntityModel.Copy(dashEffect["Model"]); + playerEntityAnimation.Copy(dashEffect["Animation"]); + dashEffect["ExplosionEffect"]["EndColor"] = (glm::vec4)playerEntityModel["Color"]; + ((glm::vec4&)dashEffect["ExplosionEffect"]["EndColor"]).w = 0.f; + dashEffect["Animation"]["Speed1"] = 0.0; + dashEffect["Animation"]["Speed2"] = 0.0; + dashEffect["Animation"]["Speed3"] = 0.0; + dashEffect["Transform"]["Position"] = (glm::vec3)player["Transform"]["Position"]; + dashEffect["Transform"]["Orientation"] = (glm::vec3)player["Transform"]["Orientation"]; + return true; +} diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index 6254c674..fbda849d 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -1,29 +1,54 @@ #include "Systems/PlayerSpawnSystem.h" -//This should be set by the config anyway. -float PlayerSpawnSystem::m_RespawnTime = 15.0f; - PlayerSpawnSystem::PlayerSpawnSystem(SystemParams params) : System(params) - , m_Timer(0.f) + , m_DbgConfigForceRespawn(false) { EVENT_SUBSCRIBE_MEMBER(m_OnInputCommand, &PlayerSpawnSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_OnPlayerSpawnerd, &PlayerSpawnSystem::OnPlayerSpawned); EVENT_SUBSCRIBE_MEMBER(m_OnPlayerDeath, &PlayerSpawnSystem::OnPlayerDeath); - m_NetworkEnabled = ResourceManager::Load("Config.ini")->Get("Networking.StartNetwork", false); + ConfigFile* config = ResourceManager::Load("Config.ini"); + m_NetworkEnabled = config->Get("Networking.StartNetwork", false); + m_ForcedRespawnTime = config->Get("Debug.RespawnTime", -1.0f); + m_DbgConfigForceRespawn = m_ForcedRespawnTime > 0 && IsServer; } void PlayerSpawnSystem::Update(double dt) { - //Increase timer. - m_Timer += dt; - if (m_Timer < m_RespawnTime) { - return; + // If there are no CapturePointGameMode components we will just spawn immediately. + // Should be able to support older maps with this. + // TODO: In the future we might want to return instead, to avoid spawning in the menu for instance. + auto pool = m_World->GetComponents("CapturePointGameMode"); + if (pool != nullptr && pool->size() > 0) + { + // Take the first CapturePointGameMode component found. + ComponentWrapper& modeComponent = *pool->begin(); + // Increase timer. + double& timer = (double&)modeComponent["RespawnTime"]; + timer += dt; + if (m_DbgConfigForceRespawn) { + (double&)modeComponent["MaxRespawnTime"] = m_ForcedRespawnTime; + } + double maxRespawnTime = (double)modeComponent["MaxRespawnTime"]; + EntityWrapper spectatorCam = m_World->GetFirstEntityByName("SpectatorCamera"); + if (spectatorCam.Valid()) { + EntityWrapper HUD = spectatorCam.FirstChildByName("SpectatorHUD"); + if (HUD.Valid()) { + EntityWrapper respawnTimer = spectatorCam.FirstChildByName("RespawnTimer"); + if (respawnTimer.Valid()) { + //Update respawn time in the HUD element. + respawnTimer["Text"]["Content"] = std::to_string(1 + (int)(maxRespawnTime - timer)); + } + } + } + if (timer < maxRespawnTime) { + return; + } + // If respawn time has passed, we spawn all players that have requested to be spawned. + timer = 0; } - //If respawn time has passed, we spawn all players that have requested to be spawned. - m_Timer = 0.f; - //If there are no spawn requests, return immediately, if we are client the SpawnRequests should always be empty. + // If there are no spawn requests, return immediately, if we are client the SpawnRequests should always be empty. if (m_SpawnRequests.size() == 0) { return; } @@ -43,7 +68,14 @@ void PlayerSpawnSystem::Update(double dt) // If the spawner has a team affiliation, check it if (spawner.HasComponent("Team")) { - if ((int)spawner["Team"]["Team"] != req.Team) { + auto cSpawnerTeam = spawner["Team"]; + if ((int)cSpawnerTeam["Team"] != req.Team) { + // Increase num spawned players if someone picks spectator, since it is valid to pick spectator + // but don't spawn anything, goto next spawnrequest. + if (req.Team == (int)cSpawnerTeam["Team"].Enum("Spectator")) { + ++numSpawnedPlayers; + break; + } continue; } } @@ -64,9 +96,9 @@ void PlayerSpawnSystem::Update(double dt) } } if (numSpawnedPlayers != (int)m_SpawnRequests.size()) { - LOG_DEBUG("%i players were supposed to be spawned, but %i was spawned.", (int)m_SpawnRequests.size(), numSpawnedPlayers); + LOG_DEBUG("%i players were supposed to be spawned or set as spectator, but only %i was handled.", (int)m_SpawnRequests.size(), numSpawnedPlayers); } else { - LOG_DEBUG("%i players were spawned.", numSpawnedPlayers); + LOG_DEBUG("%i players were spawned or set as spectator.", numSpawnedPlayers); } m_SpawnRequests.clear(); } @@ -77,24 +109,29 @@ bool PlayerSpawnSystem::OnInputCommand(Events::InputCommand& e) return false; } + if (e.Value == 0) { + return false; + } + + // A dead client should be able to swap to the spectator camera. + if (IsClient && !LocalPlayer.Valid()) { + // Set the spectator camera as active, if it exists. + // Find the camera. + EntityWrapper spectatorCam = m_World->GetFirstEntityByName("SpectatorCamera"); + if (spectatorCam.Valid() && spectatorCam.HasComponent("Camera")) { + Events::SetCamera eSetCamera; + eSetCamera.CameraEntity = spectatorCam; + m_EventBroker->Publish(eSetCamera); + } + } + // Team picks should be processed ONLY server-side! // Don't make a spawn request if we're the client. if (!IsServer && m_NetworkEnabled) { return false; } - if (e.Value == 0) { - return false; - } - - //TODO: Spectating? - //Right now, return if someone picks spectator. - //1 signifies spectator here, could not get Playerteam component since it may be invalid or without team comp. - if ((ComponentInfo::EnumType)e.Value == 1) { - return false; - } - - //Check if the player already requested spawn. + // Check if the player already requested spawn. auto iter = m_SpawnRequests.begin(); for (; iter != m_SpawnRequests.end(); ++iter) { if (iter->PlayerID == e.PlayerID) { @@ -103,11 +140,11 @@ bool PlayerSpawnSystem::OnInputCommand(Events::InputCommand& e) } if (iter != m_SpawnRequests.end()) { - //If player is in queue to spawn, then change their team affiliation in the request. + // If player is in queue to spawn, then change their team affiliation in the request. iter->Team = (ComponentInfo::EnumType)e.Value; } else if (m_PlayerEntities.count(e.PlayerID) == 0 || !m_PlayerEntities[e.PlayerID].Valid()) { - //If player is not in queue to spawn, then create a spawn request, - //but only if they are spectating and/or just connected. + // If player is not in queue to spawn, then create a spawn request, + // but only if they are spectating and/or just connected. SpawnRequest req; req.PlayerID = e.PlayerID; req.Team = (ComponentInfo::EnumType)e.Value; diff --git a/src/Game/Systems/SoundSystem.cpp b/src/Game/Systems/SoundSystem.cpp index c446ee3c..93ab4469 100644 --- a/src/Game/Systems/SoundSystem.cpp +++ b/src/Game/Systems/SoundSystem.cpp @@ -31,12 +31,12 @@ bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned &e) if (e.PlayerID == -1) { // Local player m_World->AttachComponent(e.Player.ID, "Listener"); Events::PlayAnonuncerVoice go; - go.FilePath = "Audio/announcer/" + m_Announcer + "/go.wav"; + go.FilePath = "Audio/Announcer/" + m_Announcer + "/Go.wav"; m_EventBroker->Publish(go); // TEMP: starts bgm { Events::PlayBackgroundMusic ev; - ev.FilePath = "Audio/bgm/layer1.wav"; + ev.FilePath = "Audio/BGM/Layer1.wav"; m_EventBroker->Publish(ev); } } @@ -78,7 +78,7 @@ void SoundSystem::playerJumps() if (grounded) { Events::PlaySoundOnEntity e; e.EmitterID = LocalPlayer.ID; - e.FilePath = "Audio/jump/jump1.wav"; + e.FilePath = "Audio/Jump/Jump1.wav"; m_EventBroker->Publish(e); } } @@ -88,13 +88,13 @@ bool SoundSystem::OnCaptured(const Events::Captured & e) if (!LocalPlayer.Valid()) { return false; } - int homeTeam = (int)m_World->GetComponent(e.CapturePointID, "Team")["Team"]; + int homeTeam = (int)m_World->GetComponent(e.CapturePointTakenID, "Team")["Team"]; int team = (int)m_World->GetComponent(LocalPlayer.ID, "Team")["Team"]; Events::PlayAnonuncerVoice ev; if (team == homeTeam) { - ev.FilePath = "Audio/announcer/" + m_Announcer + "/objective_achieved.wav"; + ev.FilePath = "Audio/Announcer/" + m_Announcer + "/ObjectiveAchieved.wav"; } else { - ev.FilePath = "Audio/announcer/" + m_Announcer + "/objective_failed.wav"; // have not been tested + ev.FilePath = "Audio/Announcer/" + m_Announcer + "/ObjectiveFailed.wav"; } m_EventBroker->Publish(ev); return false; @@ -112,7 +112,7 @@ bool SoundSystem::OnPlayerDamage(const Events::PlayerDamage & e) std::uniform_int_distribution dist(1, 12); int rand = dist(generator); std::vector paths; - paths.push_back("Audio/hurt/hurt" + std::to_string(rand) + ".wav"); + paths.push_back("Audio/Hurt/Hurt" + std::to_string(rand) + ".wav"); Events::PlayQueueOnEntity ev; ev.Emitter = LocalPlayer; @@ -133,7 +133,7 @@ bool SoundSystem::OnPlayerDeath(const Events::PlayerDeath & e) // Play the sound from the listener. // TODO: We might want to hear other players die. Events::PlayBackgroundMusic ev; - ev.FilePath = "Audio/die/die2.wav"; + ev.FilePath = "Audio/Die/Die2.wav"; m_EventBroker->Publish(ev); return false; } @@ -142,7 +142,7 @@ bool SoundSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup & e) { Events::PlaySoundOnEntity ev; ev.EmitterID = LocalPlayer.ID; - ev.FilePath = "Audio/pickup/pickup2.wav"; + ev.FilePath = "Audio/Pickup/Pickup2.wav"; m_EventBroker->Publish(ev); return false; } @@ -157,7 +157,7 @@ bool SoundSystem::OnDoubleJump(const Events::DoubleJump & e) } Events::PlaySoundOnEntity ev; ev.EmitterID = e.entityID; - ev.FilePath = "Audio/jump/jump2.wav"; + ev.FilePath = "Audio/Jump/Jump2.wav"; m_EventBroker->Publish(ev); return false; } \ No newline at end of file diff --git a/src/Game/Systems/SpawnerSystem.cpp b/src/Game/Systems/SpawnerSystem.cpp index 6500460f..282c958b 100644 --- a/src/Game/Systems/SpawnerSystem.cpp +++ b/src/Game/Systems/SpawnerSystem.cpp @@ -17,15 +17,17 @@ EntityWrapper SpawnerSystem::Spawn(EntityWrapper spawner, EntityWrapper parent / // Load the entity file and parse it const std::string& entityFilePath = spawner["Spawner"]["EntityFile"]; - auto entityFile = ResourceManager::Load(entityFilePath); - if (entityFile == nullptr) { + EntityWrapper spawnedEntity; + try { + auto entityFile = ResourceManager::Load(entityFilePath); + spawnedEntity = entityFile->MergeInto(world); + world->SetParent(spawnedEntity.ID, parent.ID); + } catch (const Resource::FailedLoadingException& e) { return EntityWrapper::Invalid; } - EntityFileParser parser(entityFile); - EntityWrapper spawnedEntity(world, parser.MergeEntities(world, parent.ID)); - //If the spawned entity is collideable, then we must not spawn it where it collides with something that - //has a dontCollideComponent attached. + // If the spawned entity is collidable, then we must not spawn it where it collides with something that + // has a dontCollideComponent attached. bool spawnOnCollidable = dontCollideComponent.empty() || !spawnedEntity.HasComponent("Collidable"); if (!spawnOnCollidable) { boost::optional optBox = Collision::EntityAbsoluteAABB(spawnedEntity); diff --git a/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp_ b/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp_ index c3b3385f..547ed36a 100644 --- a/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp_ +++ b/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp_ @@ -366,9 +366,10 @@ bool AssaultWeaponBehaviour::shoot(double damage) return false; } - // Check for friendly fire + + // If friendly fire - reduce damage to 0 (needed to make Boosts, Ammosharing work) if ((ComponentInfo::EnumType)victim["Team"]["Team"] == (ComponentInfo::EnumType)m_Player["Team"]["Team"]) { - return false; + damage = 0; } // Deal damage! diff --git a/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp b/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp index fbc6e37c..f148f6de 100644 --- a/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp +++ b/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp @@ -88,7 +88,7 @@ void DefenderWeaponBehaviour::fireShell(WeaponInfo& wi) EntityWrapper spawner = weaponModelEntity.FirstChildByName("WeaponMuzzle"); Events::PlaySoundOnEntity e; e.EmitterID = weaponModelEntity.ID; - e.FilePath = "Audio/laser/laser1.wav"; + e.FilePath = "Audio/weapon/Shotgun/ShotgunFire.wav"; m_EventBroker->Publish(e); for (auto& angles : pelletAngles) { glm::vec3 direction = Transform::AbsoluteOrientation(spawner) * glm::quat(glm::vec3(angles, 0.f)) * glm::vec3(0, 0, -1); diff --git a/src/Game/main.cpp b/src/Game/main.cpp index dd2a5a84..3c9b6d38 100644 --- a/src/Game/main.cpp +++ b/src/Game/main.cpp @@ -9,7 +9,9 @@ int main(int argc, char* argv[]) Game game(argc, argv); while (game.Running()) { + PerformanceTimer::StartTimer("Game-Tick"); game.Tick(); + PerformanceTimer::StopTimer("Game-Tick"); } return 0; diff --git a/src/Tests/CapturePointTest.cpp b/src/Tests/CapturePointTest.cpp index 8a9baf40..8fb7869c 100644 --- a/src/Tests/CapturePointTest.cpp +++ b/src/Tests/CapturePointTest.cpp @@ -7,7 +7,7 @@ using boost::unit_test_framework::test_case; #include "Collision/TriggerSystem.h" #include "Collision/CollisionSystem.h" -#include "Core/EntityFileWriter.h" +#include "Core/EntityXMLFileWriter.h" #include "Game/Systems/CapturePointSystem.h" BOOST_AUTO_TEST_SUITE(CapturePointTestSuite) @@ -82,7 +82,7 @@ bool CapturePointTest::CapturePoint_Game_Loop_OneHundredTimes() { CapturePointTest::CapturePointTest(int runTestNumber) { ResourceManager::RegisterType("ConfigFile"); - ResourceManager::RegisterType("EntityFile"); + ResourceManager::RegisterType("EntityFile"); m_Config = ResourceManager::Load("Config.ini"); LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get("Debug.LogLevel", 1)); @@ -99,10 +99,10 @@ CapturePointTest::CapturePointTest(int runTestNumber) m_SystemPipeline->AddSystem(1); //must register components (Components.xsd), else you cant create entities. Easiest done by loading a test xsd file - auto file = ResourceManager::Load("Schema/Entities/TeamTest.xml"); - EntityFilePreprocessor fpp(file); + auto file = ResourceManager::Load("Schema/Entities/TeamTest.xml"); + EntityXMLFilePreprocessor fpp(file); fpp.RegisterComponents(m_World); - EntityFileParser fp(file); + EntityXMLFileParser fp(file); fp.MergeEntities(m_World); EntityID playerID = m_World->CreateEntity(); diff --git a/src/Tests/CapturePointTest.h b/src/Tests/CapturePointTest.h index 54bdc55c..1046f714 100644 --- a/src/Tests/CapturePointTest.h +++ b/src/Tests/CapturePointTest.h @@ -9,12 +9,12 @@ #include "Input/KeyboardInputHandler.h" #include "Input/MouseInputHandler.h" #include "Core/EKeyDown.h" -#include "Core/EntityFile.h" +#include "Core/EntityXMLFile.h" #include "Core/SystemPipeline.h" -#include "Core/EntityFilePreprocessor.h" -#include "Core/EntityFileParser.h" -#include "Core/EntityFileWriter.h" +#include "Core/EntityXMLFilePreprocessor.h" +#include "Core/EntityXMLFileParser.h" +#include "Core/EntityXMLFileWriter.h" #include "Engine/Collision/ETrigger.h" diff --git a/src/Tests/HealthSystemTest.cpp b/src/Tests/HealthSystemTest.cpp index bf2650a3..0a8758ae 100644 --- a/src/Tests/HealthSystemTest.cpp +++ b/src/Tests/HealthSystemTest.cpp @@ -30,7 +30,7 @@ BOOST_AUTO_TEST_SUITE_END() GameHealthSystemTest::GameHealthSystemTest() { ResourceManager::RegisterType("ConfigFile"); - ResourceManager::RegisterType("EntityFile"); + ResourceManager::RegisterType("EntityFile"); m_Config = ResourceManager::Load("Config.ini"); LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get("Debug.LogLevel", 1)); @@ -41,10 +41,10 @@ GameHealthSystemTest::GameHealthSystemTest() // Create a world m_World = new World(); - auto file = ResourceManager::Load("Schema/Entities/TeamTest.xml"); - EntityFilePreprocessor fpp(file); + auto file = ResourceManager::Load("Schema/Entities/TeamTest.xml"); + EntityXMLFilePreprocessor fpp(file); fpp.RegisterComponents(m_World); - EntityFileParser fp(file); + EntityXMLFileParser fp(file); fp.MergeEntities(m_World); // Create system pipeline diff --git a/src/Tests/HealthSystemTest.h b/src/Tests/HealthSystemTest.h index 275558d2..787a2d0e 100644 --- a/src/Tests/HealthSystemTest.h +++ b/src/Tests/HealthSystemTest.h @@ -11,7 +11,7 @@ #include "Input/KeyboardInputHandler.h" #include "Input/MouseInputHandler.h" #include "Core/EKeyDown.h" -#include "Core/EntityFile.h" +#include "Core/EntityXMLFile.h" #include "Core/SystemPipeline.h" #include "Editor/EditorSystem.h" diff --git a/src/Tests/PickupSpawnTest.cpp b/src/Tests/PickupSpawnTest.cpp index 4acd897e..0af72883 100644 --- a/src/Tests/PickupSpawnTest.cpp +++ b/src/Tests/PickupSpawnTest.cpp @@ -30,7 +30,7 @@ BOOST_AUTO_TEST_SUITE_END() PickupSpawnTest::PickupSpawnTest(int runTestNumber) { ResourceManager::RegisterType("ConfigFile"); - ResourceManager::RegisterType("EntityFile"); + ResourceManager::RegisterType("EntityFile"); m_Config = ResourceManager::Load("Config.ini"); LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get("Debug.LogLevel", 1)); @@ -44,10 +44,10 @@ PickupSpawnTest::PickupSpawnTest(int runTestNumber) m_SystemPipeline->AddSystem(1); //must register components (Components.xsd), else you cant create entities. Easiest done by loading a test xsd file - auto file = ResourceManager::Load("Schema/Entities/HealthPickup.xml"); - EntityFilePreprocessor fpp(file); + auto file = ResourceManager::Load("Schema/Entities/HealthPickup.xml"); + EntityXMLFilePreprocessor fpp(file); fpp.RegisterComponents(m_World); - EntityFileParser fp(file); + EntityXMLFileParser fp(file); //connect the healthpickup to the world m_HealthPickupID = fp.MergeEntities(m_World); diff --git a/src/Tests/PickupSpawnTest.h b/src/Tests/PickupSpawnTest.h index b9d5483a..372b07cd 100644 --- a/src/Tests/PickupSpawnTest.h +++ b/src/Tests/PickupSpawnTest.h @@ -9,12 +9,12 @@ #include "Input/KeyboardInputHandler.h" #include "Input/MouseInputHandler.h" #include "Core/EKeyDown.h" -#include "Core/EntityFile.h" +#include "Core/EntityXMLFile.h" #include "Core/SystemPipeline.h" -#include "Core/EntityFilePreprocessor.h" -#include "Core/EntityFileParser.h" -#include "Core/EntityFileWriter.h" +#include "Core/EntityXMLFilePreprocessor.h" +#include "Core/EntityXMLFileParser.h" +#include "Core/EntityXMLFileWriter.h" #include "Engine/Collision/ETrigger.h" @@ -29,7 +29,7 @@ //#include #include "Collision/TriggerSystem.h" #include "Collision/CollisionSystem.h" -#include "Core/EntityFileWriter.h" +#include "Core/EntityXMLFileWriter.h" #include "Game/Systems/HealthSystem.h" #include "Game/Systems/PickupSpawnSystem.h"