Compare commits

...

94 Commits

Author SHA1 Message Date
Tleety e1ca104fc9 Merge remote-tracking branch 'origin/master' into HUD-Timers
# Conflicts:
#	resources/Schema/Entities/Player.xml
2016-03-02 22:49:26 +01:00
Tleety 2cb4a307eb Merge branch 'master' into HUD-Timers
# Conflicts:
#	resources/Schema/Entities/QualityAssurance.xml
#	src/Game/Game.cpp
2016-03-02 22:42:12 +01:00
Jace 6507efc0db Merge pull request #162 from teamfisk/Boost-icons
Boost icons
2016-03-02 22:28:57 +01:00
Tobias Dahl 96a3e68bf4 Merge pull request #160 from teamfisk/EntityFileCaching
Entity file caching
2016-03-02 22:19:20 +01:00
Tleety 2d438060dd Player arrow change 2016-03-02 22:08:23 +01:00
Tleety a339c61f5b Merge remote-tracking branch 'origin/master' into Boost-icons
# Conflicts:
#	resources/Schema/Components.xsd
#	resources/Schema/Types/Entity.xsd
2016-03-02 21:51:52 +01:00
Tleety 8b81ba9019 Some small fixes, also added new UI elements to Player 2016-03-02 21:40:20 +01:00
Jace 9a668ed7d7 Now here's the real fix for the lag when loading entity files: CONSOLE SPAM 2016-03-02 20:16:03 +01:00
Jace 7624c6ee0a Updated all uses of EntityXMLFile to use the new EntityFile to load entities into a world. 2016-03-02 20:12:59 +01:00
Jace 3ef15dcb81 EntityFile now releases EntityXMLFile after processing. 2016-03-02 20:01:18 +01:00
Jace 5923d2d7a7 Made SpawnerSystem utilize the new EntityFile for spawning instead 2016-03-02 19:52:34 +01:00
Jace 069583e09f Created EntityFile which loads an EntityXMLFile into a temporary world to be merged with another world when you want to create a copy of the entity loaded from disk. This allows us to free EntityXMLFile once it's loaded into an EntityFile. 2016-03-02 19:52:11 +01:00
Jace 44b4a597d4 fixup! Created World::Merge which will merge a world into another one 2016-03-02 19:50:52 +01:00
Jace 618e96da90 "Fixed" this crash in debug. The attachment vector is sometimes empty! @Tleety 2016-03-02 19:49:54 +01:00
Jace fb9914d08a Fixed AMD shader compilation error 2016-03-02 19:48:20 +01:00
Jace 0c0f2d7e50 fixup! Renamed EntityFile to EntityXMLFile to be able to separate file parsing from entity creation 2016-03-02 18:56:22 +01:00
Jace 26d6546d79 Renamed EntityFile to EntityXMLFile to be able to separate file parsing from entity creation 2016-03-02 18:53:40 +01:00
Jace 62c8196ad4 Created World::Merge which will merge a world into another one 2016-03-02 18:53:39 +01:00
Tleety 7af17049e9 BoostIcons should now track correctly 2016-03-02 18:13:09 +01:00
Joachim Pettersson 76117cb3ce Merge pull request #155 from teamfisk/Respawning
Looks good man! 🇺🇸 🍔 😎
2016-03-02 17:55:32 +01:00
William Moberg e6b3bbeb54 Merge remote-tracking branch 'origin/master' into Respawning
# Conflicts:
#	resources/Schema/Types/Entity.xsd
2016-03-02 17:50:59 +01:00
Tobias Dahl 01def459a1 Merge pull request #159 from teamfisk/FloatingEffect
Added a FloatingEffectSystem to the game.
2016-03-02 17:49:25 +01:00
antc13 3094dd301b Added a default value to Position in FloatingEffect.xml 2016-03-02 17:47:22 +01:00
William Moberg 76ab746a22 Merge pull request #157 from teamfisk/DashAbiltyEffect
Dash abilty effect
2016-03-02 17:43:55 +01:00
antc13 e56f203f7c Removed unnecessary comment & added FloatingEffect to Schema/Types/Entity.xsd 2016-03-02 17:42:11 +01:00
stiffly 267c007291 Removed unnecessary comments, variables and functions. 2016-03-02 17:39:27 +01:00
Tleety 8b66d29adc Skeleton system for Boost icons 2016-03-02 17:32:45 +01:00
antc13 7d15313209 Added a FloatingEffectSystem to the game. Pickups now move up and down, if so desired. 2016-03-02 17:22:44 +01:00
Tleety a9a19193ad Component for Boost icons 2016-03-02 17:21:15 +01:00
William Moberg 53c520123a Uncommented code. 2016-03-02 17:06:53 +01:00
stiffly 92d5ec70ba Merge remote-tracking branch 'origin/master' into DashAbiltyEffect 2016-03-02 16:57:07 +01:00
stiffly 233a1d0990 The dash effect is now ignored on the local player, because it was annoying. Copies of yourself could be in your way. 2016-03-02 16:56:43 +01:00
William Moberg 4ef76f6c45 Merge branch 'master' into Respawning
# Conflicts:
#	resources/Schema/Types/Entity.xsd
2016-03-02 16:51:24 +01:00
Joachim Pettersson f8f4b4d939 Merge pull request #151 from teamfisk/CPArrow
CapturePoint indicator HUD
2016-03-02 16:48:52 +01:00
stiffly a5c086e389 Dash effect now working over network, by sending events. Similar to jump effect. 2016-03-02 16:48:38 +01:00
William Moberg 91dbbb9c11 Merge branch 'master' into Respawning 2016-03-02 16:47:55 +01:00
Tleety 78835f95d8 Removed comment 2016-03-02 16:47:30 +01:00
William Moberg dc10661e6b Respawn time now only displays numbers, centered below CPHUD. 2016-03-02 16:45:43 +01:00
Tobias Dahl 8a66b1e5c8 Merge pull request #119 from teamfisk/AssaultBoost
BoostSystem
2016-03-02 16:44:49 +01:00
verysecrethero 3c8df35be9 Merge remote-tracking branch 'origin/master' into AssaultBoost
# Conflicts:
#	src/Game/Game.cpp
2016-03-02 15:59:16 +01:00
Joachim Pettersson f761416e20 Merge pull request #152 from teamfisk/PickupBranch
Added the already-at-maxammo/health-savetrigger for the PickupSystems
2016-03-02 15:41:44 +01:00
Jocke 9161c11764 Changed m_ETriggerTouchVector for-loop so it wont break when an item triggers the condition. This is done to update all somePickup.DecreaseThisRespawnTimer's. 2016-03-02 15:31:42 +01:00
Tleety cdbc348cfa AbilityCooldownHUD should now correctly track cooldown for dash ability. 2016-03-02 14:46:37 +01:00
William Moberg 95078b6a4b Fix so client doesn't override the servers respawn time with its config file. Server or single player client can still override the component with the config RespawnTime. 2016-03-02 14:37:33 +01:00
Tleety 502a290d36 Merge branch 'master' into HUD-Timers
# Conflicts:
#	resources/Schema/Components.xsd
#	resources/Schema/Entities/PlayerRed.xml
#	resources/Schema/Types/Entity.xsd
2016-03-02 14:22:13 +01:00
stiffly 1217b25d02 DashEffect will now spawn a player model behind the player that will fade out . 2016-03-02 14:15:20 +01:00
Tleety a2b938d8f6 Merge branch 'master' into CPArrow
# Conflicts:
#	resources/Schema/Entities/Player.xml
#	resources/Schema/Entities/PlayerRed.xml
2016-03-02 13:58:44 +01:00
Tleety ab7fd89546 Should now correctly track if another player takes your last capture point 2016-03-02 13:56:35 +01:00
William Moberg 06d60f9884 Merge branch 'master' into Respawning 2016-03-02 13:47:03 +01:00
William Moberg 629ebb871f SpectatorCamera shows capturepoint HUD and respawntimer. It no longer requires CapturePointGameMode component to work. 2016-03-02 13:45:49 +01:00
Tleety 6968e71e07 Arrow should now correctly track the next point no matter when you join the game 2016-03-02 13:36:24 +01:00
Tobias Dahl 2fb3bb2a39 Merge pull request #153 from teamfisk/RenderSetingsV2
Shield and stuff
2016-03-02 13:15:52 +01:00
Tleety 6540848392 WIP 2016-03-02 11:59:56 +01:00
verysecrethero 4652cd7861 Added the already-at-maxammo/health-save-trigger for the PickupSystems 2016-03-02 11:53:04 +01:00
verysecrethero 03a35d0f5e Merge pull request #149 from teamfisk/FixNetworkBugs
Seems OK
2016-03-02 10:11:52 +01:00
Tobias Dahl e4e9af5d9c Merge pull request #148 from teamfisk/DashFixBranch
Moved the Dash CoolDown (CoolDownTimer) to the component (DashAbility…
2016-03-02 10:05:02 +01:00
Tleety 96768e66de Redplayer arrow fix 2016-03-02 09:57:41 +01:00
Tleety 799990f44d Next CP indicator should now be fully working. 2016-03-01 22:54:13 +01:00
Jace 39369aa3e5 Merge pull request #150 from teamfisk/EditorCameraSpeedFix
Fixed editor camera speed changing when scrolling on UI elements
2016-03-01 22:51:16 +01:00
Jace 6eb0b83d6b Fixed editor camera speed changing when scrolling on UI elements 2016-03-01 22:47:43 +01:00
Tleety ab40fa715b The arrow should now track CapturePoints correctly at start and when they are captured. 2016-03-01 21:57:30 +01:00
Tleety a38c18fd3a Merge remote-tracking branch 'origin/master' into CPArrow 2016-03-01 20:33:30 +01:00
Tobias Dahl 9747a201b7 Merge pull request #147 from teamfisk/CapturePointFixBranch
ECaptured: added NextCapturePoint entitywrapper. Changed CapturePoint…
2016-03-01 20:33:10 +01:00
Tleety 6281e20000 Arrow should now track the CapturePoint specified in the Component. 2016-03-01 20:31:09 +01:00
verysecrethero f147929aa9 Moved the Dash CoolDown (CoolDownTimer) to the component (DashAbility). Fixed 2 warnings 2016-03-01 17:57:18 +01:00
Jocke aadfdfdd90 AmmoPickups and HealthPickups will only spawn on the server. When a ammo pickup is taken the Server will send an Event to that
Client and it will update its ammo.
2016-03-01 17:55:00 +01:00
William Moberg 5a8261453e Eliminated some SAXParsing errors from our console output. 2016-03-01 17:40:42 +01:00
verysecrethero bba002dea9 Removed DebugCode 2016-03-01 17:37:30 +01:00
verysecrethero 15195964da ECaptured: added NextCapturePoint entitywrapper. Changed CapturePointID to CapturePointTakenID. Fixed so CapturePoints works in singleplayer again. Captured event is now sent in the next Update, since the information for NextCapturePoint is needed 2016-03-01 17:34:30 +01:00
William Moberg a9762f44ca Merge branch 'master' into Respawning 2016-03-01 17:34:23 +01:00
William Moberg 3d4427dd20 Added entity SpectatorCamera that shows respawntime, will activate when explosion effect is deleted. 2016-03-01 17:32:14 +01:00
Tleety b0a66f9e83 Components for CapturePoint arrow HUD element and a system skeleton 2016-03-01 16:19:59 +01:00
William Moberg 5c6a652316 Fixed so unregistered components are ignored instead of crashing the game. 2016-03-01 15:53:59 +01:00
Tleety 7ba5e01560 CapturePointArrow component files 2016-03-01 15:37:28 +01:00
Jocke 6d68486c05 Merge remote-tracking branch 'origin/master' into FixNetworkBugs 2016-03-01 15:07:06 +01:00
Jace c60e1ba7e4 Merge pull request #144 from teamfisk/RenderSetingsV2
Render settings
2016-03-01 13:49:38 +01:00
Tobias Dahl 63d205f56a Merge pull request #146 from teamfisk/EditorKeyboardFix
Fixed editor keyboard shortcuts getting mixed up with GUI input actions
2016-03-01 13:46:01 +01:00
Jace 36f6ade87a Fixed editor keyboard shortcuts getting mixed up with GUI input actions 2016-03-01 13:38:51 +01:00
Jocke bef79d116b Merge remote-tracking branch 'origin/master' into FixNetworkBugs 2016-02-29 10:15:16 +01:00
Tleety 144e548b7a Added AbilityCooldownHUD component and system to track the cooldown on the dashability, this needs to be extended for other abilities when they are implemented. However current dash time needs to be included into the component, since we can currently just see the max cooldown time. 2016-02-28 17:17:24 +01:00
Jocke afddd276a4 Merge remote-tracking branch 'origin/master' into FixNetworkBugs 2016-02-26 16:54:09 +01:00
Jocke a48e1b567a Removed comments 2016-02-26 16:49:25 +01:00
verysecrethero b2304a95f8 Fixed some XML documentation 2016-02-18 13:49:22 +01:00
verysecrethero 8c92b7ceb6 Small cleanup. Clarified a few comments 2016-02-18 13:40:17 +01:00
verysecrethero 7f489b3569 Added Assault,Defender,Sniper Components,Entities. Added ShieldAbility,Sprintability-Component (not implemented). Changed BoostSystem to use a childed Boost to the player. All friendly fire is 0 damage. 2016-02-18 10:40:09 +01:00
verysecrethero c3ed429377 Added BoostSystem, Added BoostAssault entity XML 2016-02-17 18:11:36 +01:00
verysecrethero 56bc1fee3d Added LifeTimeOfEffect in BoostAssault,BoostDefender components. 2016-02-17 16:43:38 +01:00
verysecrethero 1c9a1a9904 playerMovementSpeed,playerCrouchSpeed in the player component now also gets AssaultBoosted. 2016-02-17 16:04:44 +01:00
verysecrethero e8aff02c4e Merge remote-tracking branch 'origin/master' into AssaultBoost 2016-02-17 14:58:28 +01:00
verysecrethero f7303ad787 Merge remote-tracking branch 'origin/master' into AssaultBoost 2016-02-17 14:38:04 +01:00
verysecrethero 456cd35a12 Merge remote-tracking branch 'origin/master' into AssaultBoost
# Conflicts:
#	resources/Schema/Components.xsd
2016-02-17 11:52:06 +01:00
verysecrethero 2f53ed140f Merge remote-tracking branch 'origin/master' into AssaultBoost
# Conflicts:
#	resources/Schema/Components.xsd
2016-02-10 14:16:55 +01:00
verysecrethero 4bf91ba56a Merge remote-tracking branch 'origin/master' into AssaultBoost
# Conflicts:
#	resources/Schema/Components.xsd
#	src/Game/Systems/PlayerMovementSystem.cpp
2016-02-08 10:12:13 +01:00
verysecrethero 047e71a4e1 Added BoostAssault,BoostDefender components. Added their effects in HealthSystem,PlayerMovementSystem 2016-02-04 16:18:54 +01:00
103 changed files with 22545 additions and 819 deletions
+1 -1
Submodule assets updated: 10a611659d...72530423ad
+3 -1
View File
@@ -12,7 +12,9 @@ namespace Events
struct Captured : Event struct Captured : Event
{ {
int TeamNumberThatCapturedCapturePoint; int TeamNumberThatCapturedCapturePoint;
EntityID CapturePointID; EntityID CapturePointTakenID;
EntityWrapper BlueTeamNextCapturePoint;
EntityWrapper RedTeamNextCapturePoint;
}; };
} }
+9 -152
View File
@@ -1,164 +1,21 @@
#ifndef EntityFile_h__ #ifndef EntityFile_h__
#define EntityFile_h__ #define EntityFile_h__
#include <stack> #include "World.h"
#include <boost/lexical_cast.hpp> #include "EntityXMLFile.h"
#include <xercesc/util/XercesDefs.hpp> #include "EntityXMLFilePreprocessor.h"
#include <xercesc/util/PlatformUtils.hpp> #include "EntityXMLFileParser.h"
#include <xercesc/sax2/SAX2XMLReader.hpp> #include "EntityWrapper.h"
#include <xercesc/sax2/XMLReaderFactory.hpp>
#include <xercesc/sax2/DefaultHandler.hpp>
#include <xercesc/sax2/Attributes.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLChar.hpp>
#include <xercesc/sax2/DefaultHandler.hpp>
#include <xercesc/framework/XMLDocumentHandler.hpp>
#include <xercesc/framework/psvi/XSElementDeclaration.hpp>
#include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp>
#include <xercesc/framework/psvi/XSParticle.hpp>
#include <xercesc/framework/psvi/XSModelGroup.hpp>
#include <xercesc/framework/psvi/XSAnnotation.hpp>
#include <xercesc/framework/psvi/XSValue.hpp>
#include <xercesc/framework/XMLGrammarPoolImpl.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMLSInput.hpp>
#include <xercesc/dom/DOMElement.hpp>
#include "../GLM.h" class EntityFile : private World, public Resource
#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<void(EntityID, EntityID, const std::string&)> 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<void(EntityID, const std::string&)> OnStartComponentCallback;
void SetStartComponentCallback(OnStartComponentCallback c) { m_OnStartComponentCallback = c; }
// @param EntityID Entity
// @param std::string Component name
// @param std::string Field name
// @param std::map<std::string, std::string> Field attribute names and values
typedef std::function<void(EntityID, const std::string&, const std::string&, const std::map<std::string, std::string>&)> 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<void(EntityID, const std::string&, const std::string&, const char*)> 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: public:
enum class State EntityFile(std::string path);
{
Unknown,
Entity,
Component,
ComponentField
};
EntityFileSAXHandler(const EntityFileHandler* handler, xercesc::SAX2XMLReader* reader); EntityWrapper MergeInto(World* other);
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: private:
const EntityFileHandler* m_Handler; EntityID m_RootEntity = EntityID_Invalid;
xercesc::XMLGrammarPool* m_GrammarPool;
xercesc::SAX2XMLReader* m_Reader;
//State m_CurrentScope = State::Unknown;
std::stack<State> m_StateStack;
unsigned int m_NextEntityID = 0;
std::stack<EntityID> m_EntityStack;
std::string m_CurrentComponent;
std::string m_CurrentField;
std::map<std::string, std::string> 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<std::string, std::string>& 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<std::string, ::ComponentInfo> m_ComponentInfo;
//std::vector<std::string> m_EntityReferences;
static void setReaderFeatures(xercesc::SAX2XMLReader* reader);
}; };
#endif #endif
+164
View File
@@ -0,0 +1,164 @@
#ifndef EntityXMLFile_h__
#define EntityXMLFile_h__
#include <stack>
#include <boost/lexical_cast.hpp>
#include <xercesc/util/XercesDefs.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/sax2/SAX2XMLReader.hpp>
#include <xercesc/sax2/XMLReaderFactory.hpp>
#include <xercesc/sax2/DefaultHandler.hpp>
#include <xercesc/sax2/Attributes.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLChar.hpp>
#include <xercesc/sax2/DefaultHandler.hpp>
#include <xercesc/framework/XMLDocumentHandler.hpp>
#include <xercesc/framework/psvi/XSElementDeclaration.hpp>
#include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp>
#include <xercesc/framework/psvi/XSParticle.hpp>
#include <xercesc/framework/psvi/XSModelGroup.hpp>
#include <xercesc/framework/psvi/XSAnnotation.hpp>
#include <xercesc/framework/psvi/XSValue.hpp>
#include <xercesc/framework/XMLGrammarPoolImpl.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMLSInput.hpp>
#include <xercesc/dom/DOMElement.hpp>
#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<void(EntityID, EntityID, const std::string&)> 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<void(EntityID, const std::string&)> OnStartComponentCallback;
void SetStartComponentCallback(OnStartComponentCallback c) { m_OnStartComponentCallback = c; }
// @param EntityID Entity
// @param std::string Component name
// @param std::string Field name
// @param std::map<std::string, std::string> Field attribute names and values
typedef std::function<void(EntityID, const std::string&, const std::string&, const std::map<std::string, std::string>&)> 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<void(EntityID, const std::string&, const std::string&, const char*)> 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<State> m_StateStack;
unsigned int m_NextEntityID = 0;
std::stack<EntityID> m_EntityStack;
std::string m_CurrentComponent;
std::string m_CurrentField;
std::map<std::string, std::string> 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<std::string, std::string>& 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<std::string, ::ComponentInfo> m_ComponentInfo;
//std::vector<std::string> m_EntityReferences;
static void setReaderFeatures(xercesc::SAX2XMLReader* reader);
};
#endif
@@ -1,18 +1,19 @@
#ifndef EntityFileParser_h__ #ifndef EntityXMLFileParser_h__
#define EntityFileParser_h__ #define EntityXMLFileParser_h__
#include "EntityFile.h" #include "EntityXMLFile.h"
#include "World.h" #include "World.h"
class EntityFileParser class EntityXMLFileParser
{ {
friend class EntityFile;
public: public:
EntityFileParser(const EntityFile* entityFile); EntityXMLFileParser(const EntityXMLFile* entityFile);
EntityID MergeEntities(World* world, EntityID baseParent = EntityID_Invalid);
private: private:
const EntityFile* m_EntityFile; EntityID MergeEntities(World* world, EntityID baseParent = EntityID_Invalid);
const EntityXMLFile* m_EntityFile;
EntityFileHandler m_Handler; EntityFileHandler m_Handler;
World* m_World = nullptr; World* m_World = nullptr;
EntityID m_FirstEntity = EntityID_Invalid; EntityID m_FirstEntity = EntityID_Invalid;
@@ -1,5 +1,5 @@
#ifndef EntityFilePreprocessor_h__ #ifndef EntityXMLFilePreprocessor_h__
#define EntityFilePreprocessor_h__ #define EntityXMLFilePreprocessor_h__
#include <xercesc/framework/psvi/XSElementDeclaration.hpp> #include <xercesc/framework/psvi/XSElementDeclaration.hpp>
#include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp> #include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp>
@@ -17,17 +17,18 @@
#include "Util/XercesString.h" #include "Util/XercesString.h"
#include "ResourceManager.h" #include "ResourceManager.h"
#include "World.h" #include "World.h"
#include "EntityFile.h" #include "EntityXMLFile.h"
class EntityFilePreprocessor class EntityXMLFilePreprocessor
{ {
friend class EntityFile;
public: public:
EntityFilePreprocessor(const EntityFile* entityFile); EntityXMLFilePreprocessor(const EntityXMLFile* entityFile);
void RegisterComponents(World* world);
private: private:
const EntityFile* m_EntityFile; void RegisterComponents(World* world);
const EntityXMLFile* m_EntityFile;
std::map<std::string, unsigned int> m_ComponentCounts; std::map<std::string, unsigned int> m_ComponentCounts;
std::map<std::string, ComponentInfo> m_ComponentInfo; std::map<std::string, ComponentInfo> m_ComponentInfo;
@@ -1,5 +1,5 @@
#ifndef EntityFileWriter_h__ #ifndef EntityXMLFileWriter_h__
#define EntityFileWriter_h__ #define EntityXMLFileWriter_h__
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <xercesc/dom/DOM.hpp> #include <xercesc/dom/DOM.hpp>
@@ -8,13 +8,13 @@
#include <xercesc/framework/LocalFileFormatTarget.hpp> #include <xercesc/framework/LocalFileFormatTarget.hpp>
#include "Util/XercesString.h" #include "Util/XercesString.h"
#include "EntityFile.h" #include "EntityXMLFile.h"
#include "World.h" #include "World.h"
class EntityFileWriter class EntityXMLFileWriter
{ {
public: public:
EntityFileWriter(boost::filesystem::path file) EntityXMLFileWriter(boost::filesystem::path file)
: m_FilePath(file) : m_FilePath(file)
{ {
using namespace xercesc; using namespace xercesc;
-3
View File
@@ -118,9 +118,6 @@ public:
else { else {
m_ExtraMemory.push_back((char*)malloc(m_Stride)); m_ExtraMemory.push_back((char*)malloc(m_Stride));
//We should preferably not enter here to avoid performance issues. Set more numMaxElements in constructor instead. //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(); return m_ExtraMemory.back();
} }
} }
+9 -2
View File
@@ -6,6 +6,7 @@
#include "ObjectPool.h" #include "ObjectPool.h"
#include "ComponentPool.h" #include "ComponentPool.h"
#include "EventBroker.h" #include "EventBroker.h"
struct EntityWrapper;
class World class World
{ {
@@ -18,13 +19,13 @@ public:
World(const World& other); World(const World& other);
// Create empty entity // Create empty entity
EntityID CreateEntity(EntityID parent = 0); EntityID CreateEntity(EntityID parent = EntityID_Invalid);
// Delete entity and all components within // Delete entity and all components within
void DeleteEntity(EntityID entity); void DeleteEntity(EntityID entity);
// Check if an entity exists // Check if an entity exists
bool ValidEntity(EntityID entity) const; bool ValidEntity(EntityID entity) const;
// Register a component type and allocate space for it // 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 // Attach a component to an entity and fill it with default values
ComponentWrapper AttachComponent(EntityID entity, const std::string& componentType); ComponentWrapper AttachComponent(EntityID entity, const std::string& componentType);
// Check if an entity has a component // Check if an entity has a component
@@ -49,6 +50,12 @@ public:
void SetName(EntityID entity, const std::string& name); void SetName(EntityID entity, const std::string& name);
// Get the textual name of an entity // Get the textual name of an entity
std::string GetName(EntityID entity) const; 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<EntityID, EntityID> Merge(const World* other);
private: private:
EventBroker* m_EventBroker = nullptr; EventBroker* m_EventBroker = nullptr;
@@ -104,6 +104,11 @@ protected:
if (!m_Enabled) { if (!m_Enabled) {
return false; return false;
} }
ImGuiIO& io = ImGui::GetIO();
if (io.WantCaptureMouse || io.WantCaptureKeyboard) {
return false;
}
m_SpeedMultiplier += e.DeltaY * (0.1 * m_SpeedMultiplier); m_SpeedMultiplier += e.DeltaY * (0.1 * m_SpeedMultiplier);
m_Config->Set("Editor.CameraSpeed", m_SpeedMultiplier); m_Config->Set("Editor.CameraSpeed", m_SpeedMultiplier);
+2 -3
View File
@@ -5,9 +5,8 @@
#include "../Core/World.h" #include "../Core/World.h"
#include "../Core/SystemPipeline.h" #include "../Core/SystemPipeline.h"
#include "../Core/ResourceManager.h" #include "../Core/ResourceManager.h"
#include "../Core/EntityFilePreprocessor.h" #include "../Core/EntityFile.h"
#include "../Core/EntityFileParser.h" #include "../Core/EntityXMLFileWriter.h"
#include "../Core/EntityFileWriter.h"
#include "../Core/EMousePress.h" #include "../Core/EMousePress.h"
#include "../Input/EInputCommand.h" #include "../Input/EInputCommand.h"
#include "EditorGUI.h" #include "EditorGUI.h"
@@ -27,7 +27,7 @@ public:
virtual bool OnCommand(const Events::InputCommand& e) override; virtual bool OnCommand(const Events::InputCommand& e) override;
virtual void Reset(); 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 AssaultDashDoubleTapped() const { return m_AssaultDashDoubleTapped; }
virtual bool PlayerIsDashing() const { return m_PlayerIsDashing; } virtual bool PlayerIsDashing() const { return m_PlayerIsDashing; }
@@ -41,7 +41,7 @@ protected:
bool m_Crouching = false; bool m_Crouching = false;
//assault dash membervariables - needed to calculate the doubletap- and dashlogic //assault dash membervariables - needed to calculate the doubletap- and dashlogic
double m_AssaultDashDoubleTapDeltaTime = 0.0; 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), //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 //and its very unlikely that someone wants to change that value
const float m_AssaultDashDoubleTapSensitivityTimer = 0.25f; const float m_AssaultDashDoubleTapSensitivityTimer = 0.25f;
@@ -52,7 +52,7 @@ protected:
bool m_ShiftDashing = false; bool m_ShiftDashing = false;
bool m_ValidDoubleTap = false; bool m_ValidDoubleTap = false;
//specialabilitys //specialabilities
bool m_MovementKeyDown = false; bool m_MovementKeyDown = false;
bool m_SpecialAbilityKeyDown = false; bool m_SpecialAbilityKeyDown = false;
int m_NumberOfMovementKeysDown = 0; int m_NumberOfMovementKeysDown = 0;
@@ -191,23 +191,33 @@ bool FirstPersonInputController<EventContext>::OnLockMouse(const Events::LockMou
} }
template <typename EventContext> template <typename EventContext>
void FirstPersonInputController<EventContext>::AssaultDashCheck(double dt, bool isJumping, double assaultDashCoolDownMaxTimer) { void FirstPersonInputController<EventContext>::AssaultDashCheck(double dt, bool isJumping, double assaultDashCoolDownMaxTimer, double& assaultDashCoolDownTimer, EntityID playerID) {
m_AssaultDashDoubleTapDeltaTime += dt; 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) //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; m_PlayerIsDashing = true;
if (m_DashEffectResetTimer > 0.05) {
Events::DashAbility e;
e.Player = playerID;
m_EventBroker->Publish(e);
m_DashEffectResetTimer = 0.0;
}
} else { } else {
m_PlayerIsDashing = false; m_PlayerIsDashing = false;
} }
//dashing with shift //dashing with shift
if (m_ShiftDashing && m_AssaultDashCoolDownTimer <= 0.0f) { if (m_ShiftDashing && assaultDashCoolDownTimer <= 0.0f) {
//player is dashing with shift //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! //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_AssaultDashDoubleTapped = true;
m_AssaultDashDoubleTapDeltaTime = 0.f; m_AssaultDashDoubleTapDeltaTime = 0.f;
Events::DashAbility e;
e.Player = playerID;
m_EventBroker->Publish(e);
return; return;
} }
@@ -227,7 +237,7 @@ void FirstPersonInputController<EventContext>::AssaultDashCheck(double dt, bool
} }
m_ValidDoubleTap = false; 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 //if we cant dash at the moment, then just reset the tap-sensitivity-timer
m_AssaultDashDoubleTapDeltaTime = 0.f; m_AssaultDashDoubleTapDeltaTime = 0.f;
return; return;
@@ -235,9 +245,10 @@ void FirstPersonInputController<EventContext>::AssaultDashCheck(double dt, bool
//ok, we have a valid tap, lets do it //ok, we have a valid tap, lets do it
m_AssaultDashDoubleTapped = true; m_AssaultDashDoubleTapped = true;
m_AssaultDashDoubleTapDeltaTime = 0.f; m_AssaultDashDoubleTapDeltaTime = 0.f;
m_AssaultDashCoolDownTimer = assaultDashCoolDownMaxTimer; assaultDashCoolDownTimer = assaultDashCoolDownMaxTimer;
Events::DashAbility e; Events::DashAbility e;
e.Player = playerID;
m_EventBroker->Publish(e); m_EventBroker->Publish(e);
} }
+8 -1
View File
@@ -26,7 +26,9 @@
#include "Network/EInterpolate.h" #include "Network/EInterpolate.h"
#include "Network/SnapshotFilter.h" #include "Network/SnapshotFilter.h"
#include "Core/EPlayerSpawned.h" #include "Core/EPlayerSpawned.h"
#include "Core/EAmmoPickup.h"
#include "Network/ESearchForServers.h" #include "Network/ESearchForServers.h"
#include "../Game/Events/EDashAbility.h"
struct ServerInfo struct ServerInfo
{ {
@@ -106,7 +108,9 @@ private:
void parsePlayerDamage(Packet& packet); void parsePlayerDamage(Packet& packet);
void parseComponentDeletion(Packet& packet); void parseComponentDeletion(Packet& packet);
void parseDoubleJump(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 parseSnapshot(Packet& packet);
void identifyPacketLoss(); void identifyPacketLoss();
void hasServerTimedOut(); void hasServerTimedOut();
@@ -133,6 +137,9 @@ private:
EventRelay< Client, Events::SearchForServers> m_ESearchForServers; EventRelay< Client, Events::SearchForServers> m_ESearchForServers;
EventRelay<Client, Events::DoubleJump> m_EDoubleJump; EventRelay<Client, Events::DoubleJump> m_EDoubleJump;
bool OnDoubleJump(Events::DoubleJump & e); bool OnDoubleJump(Events::DoubleJump & e);
EventRelay<Client, Events::DashAbility> m_EDashAbility;
bool OnDashAbility(const Events::DashAbility& e);
bool OnSearchForServers(const Events::SearchForServers& e); bool OnSearchForServers(const Events::SearchForServers& e);
UDPClient m_ServerlistRequest; UDPClient m_ServerlistRequest;
std::vector<ServerInfo> m_Serverlist; std::vector<ServerInfo> m_Serverlist;
+2
View File
@@ -20,7 +20,9 @@ enum class MessageType
ComponentDeleted, ComponentDeleted,
PlayerTransform, PlayerTransform,
OnDoubleJump, OnDoubleJump,
OnDashEffect,
ServerlistRequest, ServerlistRequest,
AmmoPickup,
Invalid Invalid
}; };
+5 -1
View File
@@ -20,6 +20,7 @@
#include "../Game/Events/EDoubleJump.h" #include "../Game/Events/EDoubleJump.h"
#include "Core/EEntityDeleted.h" #include "Core/EEntityDeleted.h"
#include "Core/EComponentDeleted.h" #include "Core/EComponentDeleted.h"
#include "Core/EAmmoPickup.h"
class Server : public Network class Server : public Network
{ {
@@ -82,13 +83,14 @@ private:
void parseClientPing(); void parseClientPing();
void parsePing(); void parsePing();
bool parseDoubleJump(Packet& packet); bool parseDoubleJump(Packet& packet);
void parseDashEffect(Packet& packet);
void parseUDPConnect(Packet& packet); void parseUDPConnect(Packet& packet);
void parseTCPConnect(Packet& packet); void parseTCPConnect(Packet& packet);
void parseDisconnect(); void parseDisconnect();
void parseServerlistRequest(boost::asio::ip::udp::endpoint endpoint); void parseServerlistRequest(boost::asio::ip::udp::endpoint endpoint);
bool shouldSendToClient(EntityWrapper childEntity); bool shouldSendToClient(EntityWrapper childEntity);
// Debug event // Events
EventRelay<Server, Events::InputCommand> m_EInputCommand; EventRelay<Server, Events::InputCommand> m_EInputCommand;
bool OnInputCommand(const Events::InputCommand& e); bool OnInputCommand(const Events::InputCommand& e);
EventRelay<Server, Events::PlayerSpawned> m_EPlayerSpawned; EventRelay<Server, Events::PlayerSpawned> m_EPlayerSpawned;
@@ -99,6 +101,8 @@ private:
bool OnComponentDeleted(const Events::ComponentDeleted& e); bool OnComponentDeleted(const Events::ComponentDeleted& e);
EventRelay<Server, Events::PlayerDamage> m_EPlayerDamage; EventRelay<Server, Events::PlayerDamage> m_EPlayerDamage;
bool OnPlayerDamage(const Events::PlayerDamage& e); bool OnPlayerDamage(const Events::PlayerDamage& e);
EventRelay<Server, Events::AmmoPickup> m_EAmmoPickup;
bool OnAmmoPickup(const Events::AmmoPickup& e);
}; };
#endif #endif
+5 -1
View File
@@ -2,11 +2,15 @@
#define Events_DashAbility_h__ #define Events_DashAbility_h__
#include "Core/Event.h" #include "Core/Event.h"
#include "Core/EntityWrapper.h"
namespace Events namespace Events
{ {
struct DashAbility : public Event { }; struct DashAbility : public Event
{
EntityID Player;
};
} }
+3 -3
View File
@@ -13,13 +13,13 @@
#include "Input/KeyboardInputHandler.h" #include "Input/KeyboardInputHandler.h"
#include "Input/MouseInputHandler.h" #include "Input/MouseInputHandler.h"
#include "Core/EKeyDown.h" #include "Core/EKeyDown.h"
#include "Core/EntityFilePreprocessor.h" #include "Core/EntityXMLFilePreprocessor.h"
#include "Core/SystemPipeline.h" #include "Core/SystemPipeline.h"
#include "Systems/ExplosionEffectSystem.h" #include "Systems/ExplosionEffectSystem.h"
#include "Editor/EditorSystem.h" #include "Editor/EditorSystem.h"
#include "Core/EntityFile.h" #include "Core/EntityXMLFile.h"
#include "Rendering/RenderSystem.h" #include "Rendering/RenderSystem.h"
#include "Core/EntityFileParser.h" #include "Core/EntityXMLFileParser.h"
#include "Core/Octree.h" #include "Core/Octree.h"
#include "Rendering/Font.h" #include "Rendering/Font.h"
#include "Systems/InterpolationSystem.h" #include "Systems/InterpolationSystem.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
+12 -1
View File
@@ -4,7 +4,7 @@
#include "Core/System.h" #include "Core/System.h"
#include "Core/Transform.h" #include "Core/Transform.h"
#include "Core/ResourceManager.h" #include "Core/ResourceManager.h"
#include "Core/EntityFileParser.h" #include "Core/EntityFile.h"
#include "Core/EPickupSpawned.h" #include "Core/EPickupSpawned.h"
#include "Core/EAmmoPickup.h" #include "Core/EAmmoPickup.h"
#include "Engine/Collision/ETrigger.h" #include "Engine/Collision/ETrigger.h"
@@ -20,6 +20,11 @@ public:
private: private:
EventRelay<AmmoPickupSystem, Events::TriggerTouch> m_ETriggerTouch; EventRelay<AmmoPickupSystem, Events::TriggerTouch> m_ETriggerTouch;
bool OnTriggerTouch(Events::TriggerTouch& e); bool OnTriggerTouch(Events::TriggerTouch& e);
EventRelay<AmmoPickupSystem, Events::TriggerLeave> m_ETriggerLeave;
bool OnTriggerLeave(Events::TriggerLeave& e);
EventRelay<AmmoPickupSystem, Events::AmmoPickup> m_EAmmoPickup;
bool OnAmmoPickup(Events::AmmoPickup& e);
struct NewAmmoPickup { struct NewAmmoPickup {
glm::vec3 Pos; glm::vec3 Pos;
@@ -29,5 +34,11 @@ private:
EntityID parentID; EntityID parentID;
}; };
std::vector<NewAmmoPickup> m_ETriggerTouchVector; std::vector<NewAmmoPickup> m_ETriggerTouchVector;
struct EntityAtMaxValuePickupStruct {
EntityWrapper player;
EntityWrapper trigger;
};
std::vector<EntityAtMaxValuePickupStruct> m_PickupAtMaximum;
void DoPickup(EntityWrapper &player, EntityWrapper &trigger);
}; };
#endif #endif
@@ -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
+21
View File
@@ -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<BoostSystem, Events::PlayerDamage> m_EPlayerDamage;
bool OnPlayerDamage(Events::PlayerDamage& e);
std::string DetermineClass(EntityWrapper player);
};
#endif
@@ -0,0 +1,30 @@
#ifndef CapturePointArrowHUDSystem_h__
#define CapturePointArrowHUDSystem_h__
#include <GLFW/glfw3.h>
#include <glm/common.hpp>
#include <glm/gtx/vector_angle.hpp>
#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<CapturePointArrowHUDSystem, Events::Captured> m_ECapturedEvent;
bool OnCapturePointCaptured(Events::Captured& e);
bool m_InitialtargetsSet = false;
glm::vec3 m_RedTeamCurrentTarget;
glm::vec3 m_BlueTeamCurrentTarget;
};
#endif
+1 -1
View File
@@ -7,7 +7,7 @@
#include "Common.h" #include "Common.h"
#include "Core/System.h" #include "Core/System.h"
#include "Engine/Collision/ETrigger.h" #include "Collision/ETrigger.h"
class CapturePointHUDSystem : public ImpureSystem class CapturePointHUDSystem : public ImpureSystem
{ {
+2 -2
View File
@@ -42,9 +42,9 @@ private:
int m_NumberOfCapturePoints = 0; int m_NumberOfCapturePoints = 0;
std::map<int, EntityWrapper> m_CapturePointNumberToEntityMap; std::map<int, EntityWrapper> m_CapturePointNumberToEntityMap;
//std::vector<ComponentWrapper>
bool m_ResetTimers = false; bool m_ResetTimers = false;
bool m_RecentlyCapturedNeedNextCapturePointNow = false;
Events::Captured m_CapturedEvent;
//vectors which will keep track of enter/leave changes //vectors which will keep track of enter/leave changes
std::vector<std::tuple<EntityWrapper, EntityWrapper>> m_ETriggerTouchVector; std::vector<std::tuple<EntityWrapper, EntityWrapper>> m_ETriggerTouchVector;
+1 -1
View File
@@ -4,7 +4,7 @@
#include "Core/System.h" #include "Core/System.h"
#include "Core/Transform.h" #include "Core/Transform.h"
#include "Core/ResourceManager.h" #include "Core/ResourceManager.h"
#include "Core/EntityFileParser.h" #include "Core/EntityFile.h"
#include "Core/EPlayerDamage.h" #include "Core/EPlayerDamage.h"
#include "Common.h" #include "Common.h"
#include <tuple> #include <tuple>
@@ -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>() / (float)(double)component["Period"]) * (float)(double)component["Time"]) * (glm::vec3)component["Axis"];
}
};
+9 -2
View File
@@ -4,12 +4,11 @@
#include "Core/System.h" #include "Core/System.h"
#include "Core/Transform.h" #include "Core/Transform.h"
#include "Core/ResourceManager.h" #include "Core/ResourceManager.h"
#include "Core/EntityFileParser.h" #include "Core/EntityFile.h"
#include "Core/EPickupSpawned.h" #include "Core/EPickupSpawned.h"
#include "Core/EPlayerHealthPickup.h" #include "Core/EPlayerHealthPickup.h"
#include "Engine/Collision/ETrigger.h" #include "Engine/Collision/ETrigger.h"
#include "Common.h" #include "Common.h"
#include <tuple>
class PickupSpawnSystem : public ImpureSystem class PickupSpawnSystem : public ImpureSystem
{ {
@@ -21,6 +20,8 @@ public:
private: private:
EventRelay<PickupSpawnSystem, Events::TriggerTouch> m_ETriggerTouch; EventRelay<PickupSpawnSystem, Events::TriggerTouch> m_ETriggerTouch;
bool OnTriggerTouch(Events::TriggerTouch& e); bool OnTriggerTouch(Events::TriggerTouch& e);
EventRelay<PickupSpawnSystem, Events::TriggerLeave> m_ETriggerLeave;
bool OnTriggerLeave(Events::TriggerLeave& e);
struct NewHealthPickup { struct NewHealthPickup {
glm::vec3 Pos; glm::vec3 Pos;
@@ -30,5 +31,11 @@ private:
EntityID parentID; EntityID parentID;
}; };
std::vector<NewHealthPickup> m_ETriggerTouchVector; std::vector<NewHealthPickup> m_ETriggerTouchVector;
struct EntityAtMaxValuePickupStruct {
EntityWrapper player;
EntityWrapper trigger;
};
std::vector<EntityAtMaxValuePickupStruct> m_PickupAtMaximum;
void DoPickup(EntityWrapper &player, EntityWrapper &trigger);
}; };
#endif #endif
+5 -3
View File
@@ -6,11 +6,9 @@
#include "GLM.h" #include "GLM.h"
#include "Rendering/ESetCamera.h" #include "Rendering/ESetCamera.h"
#include "Core/ConfigFile.h" #include "Core/ConfigFile.h"
#include "Core/EntityFile.h" #include "Core/EntityFile.h"
#include "Core/EntityFileParser.h"
#include "Core/EPlayerDeath.h" #include "Core/EPlayerDeath.h"
#include "Core/EEntityDeleted.h"
class PlayerDeathSystem : public ImpureSystem class PlayerDeathSystem : public ImpureSystem
{ {
@@ -20,8 +18,12 @@ public:
virtual void Update(double dt) override; virtual void Update(double dt) override;
private: private:
EntityWrapper m_LocalPlayerDeathEffect;
EventRelay<PlayerDeathSystem, Events::PlayerDeath> m_OnPlayerDeath; EventRelay<PlayerDeathSystem, Events::PlayerDeath> m_OnPlayerDeath;
bool OnPlayerDeath(Events::PlayerDeath& e); bool OnPlayerDeath(Events::PlayerDeath& e);
EventRelay<PlayerDeathSystem, Events::EntityDeleted> m_EEntityDeleted;
bool OnEntityDeleted(Events::EntityDeleted& e);
void createDeathEffect(EntityWrapper player); void createDeathEffect(EntityWrapper player);
+2 -2
View File
@@ -6,9 +6,7 @@
#include <imgui/imgui.h> #include <imgui/imgui.h>
#include "Events/EDoubleJump.h" #include "Events/EDoubleJump.h"
#include "../Engine/Sound/EPlaySoundOnEntity.h" #include "../Engine/Sound/EPlaySoundOnEntity.h"
#include "Core/EntityFile.h" #include "Core/EntityFile.h"
#include "Core/EntityFileParser.h"
class PlayerMovementSystem : public ImpureSystem class PlayerMovementSystem : public ImpureSystem
{ {
@@ -41,6 +39,8 @@ private:
bool OnPlayerSpawned(Events::PlayerSpawned& e); bool OnPlayerSpawned(Events::PlayerSpawned& e);
EventRelay<PlayerMovementSystem, Events::DoubleJump> m_EDoubleJump; EventRelay<PlayerMovementSystem, Events::DoubleJump> m_EDoubleJump;
bool PlayerMovementSystem::OnDoubleJump(Events::DoubleJump & e); bool PlayerMovementSystem::OnDoubleJump(Events::DoubleJump & e);
EventRelay<PlayerMovementSystem, Events::DashAbility> m_EDashAbility;
bool PlayerMovementSystem::OnDashAbility(Events::DashAbility & e);
void updateMovementControllers(double dt); void updateMovementControllers(double dt);
void updateVelocity(EntityWrapper player, double dt); void updateVelocity(EntityWrapper player, double dt);
+1 -2
View File
@@ -7,8 +7,7 @@
#include "Core/System.h" #include "Core/System.h"
#include "Events/ESpawnerSpawn.h" #include "Events/ESpawnerSpawn.h"
#include "Core/Transform.h" #include "Core/Transform.h"
#include "Core/ResourceManager.h" #include "Core/EntityFile.h"
#include "Core/EntityFileParser.h"
class SpawnerSystem : public System class SpawnerSystem : public System
{ {
+2 -2
View File
@@ -9,8 +9,8 @@
#include "Core/EShoot.h" #include "Core/EShoot.h"
#include "Core/EPlayerSpawned.h" #include "Core/EPlayerSpawned.h"
#include "Input/EInputCommand.h" #include "Input/EInputCommand.h"
#include "Core/EntityFile.h" #include "Core/EntityXMLFile.h"
#include "Core/EntityFileParser.h" #include "Core/EntityXMLFileParser.h"
#include "Core/Octree.h" #include "Core/Octree.h"
#include "Collision/EntityAABB.h" #include "Collision/EntityAABB.h"
#include "Systems/SpawnerSystem.h" #include "Systems/SpawnerSystem.h"
+1 -1
View File
@@ -4,7 +4,7 @@ LoadMap=
; if true -> Pool allocation is not used when calling Allocate/Free, just use regular dynamic allocation. ; if true -> Pool allocation is not used when calling Allocate/Free, just use regular dynamic allocation.
; if false -> Use pool allocation. ; if false -> Use pool allocation.
DisableMemoryPool=false DisableMemoryPool=false
RespawnTime = 8.0 RespawnTime = -1.0
EditorEnabled=false EditorEnabled=false
OutOfBodyExperience=false OutOfBodyExperience=false
+9
View File
@@ -35,7 +35,12 @@
<xs:include schemaLocation="Components/AmmoPickup.xsd"/> <xs:include schemaLocation="Components/AmmoPickup.xsd"/>
<xs:include schemaLocation="Components/AnimationOffset.xsd"/> <xs:include schemaLocation="Components/AnimationOffset.xsd"/>
<xs:include schemaLocation="Components/DashAbility.xsd"/> <xs:include schemaLocation="Components/DashAbility.xsd"/>
<xs:include schemaLocation="Components/ShieldAbility.xsd"/>
<xs:include schemaLocation="Components/SprintAbility.xsd"/>
<xs:include schemaLocation="Components/AssaultWeapon.xsd"/> <xs:include schemaLocation="Components/AssaultWeapon.xsd"/>
<xs:include schemaLocation="Components/BoostAssault.xsd"/>
<xs:include schemaLocation="Components/BoostDefender.xsd"/>
<xs:include schemaLocation="Components/BoostSniper.xsd"/>
<xs:include schemaLocation="Components/Shield.xsd"/> <xs:include schemaLocation="Components/Shield.xsd"/>
<xs:include schemaLocation="Components/Sprite.xsd"/> <xs:include schemaLocation="Components/Sprite.xsd"/>
<xs:include schemaLocation="Components/Shielded.xsd"/> <xs:include schemaLocation="Components/Shielded.xsd"/>
@@ -46,8 +51,12 @@
<xs:include schemaLocation="Components/Page.xsd"/> <xs:include schemaLocation="Components/Page.xsd"/>
<xs:include schemaLocation="Components/SpriteIndicator.xsd"/> <xs:include schemaLocation="Components/SpriteIndicator.xsd"/>
<xs:include schemaLocation="Components/Button.xsd"/> <xs:include schemaLocation="Components/Button.xsd"/>
<xs:include schemaLocation="Components/AbilityCooldownHUD.xsd"/>
<xs:include schemaLocation="Components/DoubleJump.xsd"/> <xs:include schemaLocation="Components/DoubleJump.xsd"/>
<xs:include schemaLocation="Components/WeaponAttachment.xsd"/> <xs:include schemaLocation="Components/WeaponAttachment.xsd"/>
<xs:include schemaLocation="Components/DefenderWeapon.xsd"/> <xs:include schemaLocation="Components/DefenderWeapon.xsd"/>
<xs:include schemaLocation="Components/CapturePointGameMode.xsd"/> <xs:include schemaLocation="Components/CapturePointGameMode.xsd"/>
<xs:include schemaLocation="Components/CapturePointArrowHUD.xsd"/>
<xs:include schemaLocation="Components/FloatingEffect.xsd"/>
<xs:include schemaLocation="Components/BoostIconsHUD.xsd"/>
</xs:schema> </xs:schema>
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<AbilityCooldownHUD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="AbilityCooldownHUD.xsd">
</AbilityCooldownHUD>
@@ -0,0 +1,9 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="AbilityCooldownHUD">
<xs:annotation>
<xs:documentation>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"</xs:documentation>
</xs:annotation>
</xs:element>
</xs:schema>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<BoostAssault xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BoostAssault.xsd">
<StrengthOfEffect>2</StrengthOfEffect>
</BoostAssault>
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="BoostAssault">
<xs:annotation>
<xs:documentation>This is the assault's class boost component</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="StrengthOfEffect" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>This is the strength of the boost effect</xs:documentation></xs:annotation>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<BoostDefender xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BoostDefender.xsd">
<StrengthOfEffect>10</StrengthOfEffect>
</BoostDefender>
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="BoostDefender">
<xs:annotation>
<xs:documentation>This is the defender's class boost component</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="StrengthOfEffect" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>This is the strength of the boost effect</xs:documentation></xs:annotation>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<BoostIconsHUD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BoostIconsHUD.xsd"/>
@@ -0,0 +1,10 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="BoostIconsHUD">
<xs:annotation>
<xs:documentation>Origin for the 3 boost states. Create 3 children with Sprite and Fill components, name them "Sprint", "Defender", "Assault"</xs:documentation>
</xs:annotation>
</xs:element>
</xs:schema>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<BoostSniper xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BoostSniper.xsd">
<StrengthOfEffect>10</StrengthOfEffect>
</BoostSniper>
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="BoostSniper">
<xs:annotation>
<xs:documentation>This is the sniper's class boost component</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="StrengthOfEffect" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>This is the strength of the boost effect</xs:documentation></xs:annotation>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<CapturePointArrowHUD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="CapturePointArrowHUD.xsd">
<CurrentTarget>0</CurrentTarget>
</CapturePointArrowHUD>
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="CapturePointArrowHUD">
<xs:annotation>
<xs:documentation>HUD element for tracking next capturable Capture Point.</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="CurrentTarget" type="t:int" minOccurs="0">
<xs:annotation>
<xs:documentation>Corresponds to the current capturepoint the arrow points Towards</xs:documentation>
</xs:annotation>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<DashAbility xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="DashAbility.xsd"> <DashAbility xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="DashAbility.xsd">
<CoolDownMaxTimer>2.0</CoolDownMaxTimer> <CoolDownMaxTimer>2.0</CoolDownMaxTimer>
<CoolDownTimer>0.0</CoolDownTimer>
</DashAbility> </DashAbility>
+4 -1
View File
@@ -10,7 +10,10 @@
<xs:complexType> <xs:complexType>
<xs:all> <xs:all>
<xs:element name="CoolDownMaxTimer" type="t:double" minOccurs="0"> <xs:element name="CoolDownMaxTimer" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>This is the cooldown on dash</xs:documentation></xs:annotation> <xs:annotation><xs:documentation>This is the max cooldown on dash</xs:documentation></xs:annotation>
</xs:element>
<xs:element name="CoolDownTimer" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>This is the current cooldown on dash</xs:documentation></xs:annotation>
</xs:element> </xs:element>
</xs:all> </xs:all>
</xs:complexType> </xs:complexType>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<FloatingEffect xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FloatingEffect.xsd">
<Period>1</Period>
<Amplitude>1</Amplitude>
<Time>0</Time>
<Axis X="0" Y="0" Z="0"/>
<Position X="0" Y="0" Z="0"/>
</FloatingEffect>
@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="FloatingEffect">
<xs:complexType>
<xs:all>
<xs:element name="Period" type="t:double" minOccurs="0"/>
<xs:element name="Amplitude" type="t:double" minOccurs="0"/>
<xs:element name="Time" type="t:double" minOccurs="0"/>
<xs:element name="Axis" type="t:Vector" minOccurs="0"/>
<xs:element name="Position" type="t:Vector" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<ShieldAbility xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ShieldAbility.xsd">
<CoolDownMaxTimer>2.0</CoolDownMaxTimer>
</ShieldAbility>
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="ShieldAbility">
<xs:annotation>
<xs:documentation>A shield component for one of the classes</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="CoolDownMaxTimer" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>This is the cooldown on shield</xs:documentation></xs:annotation>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<SprintAbility xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="SprintAbility.xsd">
<CoolDownMaxTimer>2.0</CoolDownMaxTimer>
</SprintAbility>
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="SprintAbility">
<xs:annotation>
<xs:documentation>A sprint component for one of the classes</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="CoolDownMaxTimer" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>This is the cooldown on sprint</xs:documentation></xs:annotation>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Text xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Text.xsd"> <Text xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Text.xsd">
<Content></Content> <Content></Content>
<Resource></Resource> <Resource>Fonts/DroidSans.ttf,64</Resource>
<Color R="1" G="1" B="1" A="1"/> <Color R="1" G="1" B="1" A="1"/>
<Visible>true</Visible> <Visible>true</Visible>
<Alignment><Center/></Alignment> <Alignment><Center/></Alignment>
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:BoostAssault/>
<c:Lifetime>
<Lifetime>10</Lifetime>
</c:Lifetime>
<c:Transform/>
</Components>
<Children/>
</Entity>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:BoostDefender/>
<c:Lifetime>
<Lifetime>10</Lifetime>
</c:Lifetime>
<c:Transform/>
</Components>
<Children/>
</Entity>
+14
View File
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:BoostSniper/>
<c:Lifetime>
<Lifetime>10</Lifetime>
</c:Lifetime>
<c:Transform/>
</Components>
<Children/>
</Entity>
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity name="DashEffect" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Animation/>
<c:Lifetime>
<Lifetime>0.5</Lifetime>
</c:Lifetime>
<c:ExplosionEffect>
<Velocity X="0" Y="0" Z="0"/>
<TimeSinceDeath>0</TimeSinceDeath>
<ExplosionDuration>0.5</ExplosionDuration>
<EndColor A="0" B="0" G="0" R="0"/>
</c:ExplosionEffect>
<c:Model/>
<c:Transform/>
</Components>
</Entity>
+10 -10
View File
@@ -5019,7 +5019,7 @@
</Team> </Team>
</c:Team> </c:Team>
<c:Transform> <c:Transform>
<Position X="-60.3695679" Y="5.64500046" Z="-79.3789597"/> <Position X="-60.3695679" Y="5.14500046" Z="-79.3789597"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -5089,7 +5089,7 @@
</Team> </Team>
</c:Team> </c:Team>
<c:Transform> <c:Transform>
<Position X="60.0169258" Y="5.78000021" Z="76.2893906"/> <Position X="60.0169258" Y="6.0800004" Z="76.2893906"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -5165,7 +5165,7 @@
<c:Transform> <c:Transform>
<Position X="48.9189453" Y="7.06223536" Z="-78.9347992"/> <Position X="48.9189453" Y="7.06223536" Z="-78.9347992"/>
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/> <Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
<Orientation X="0" Y="75.6124268" Z="0"/> <Orientation X="0" Y="74.6042328" Z="0"/>
</c:Transform> </c:Transform>
<c:Trigger/> <c:Trigger/>
</Components> </Components>
@@ -5184,7 +5184,7 @@
<c:Transform> <c:Transform>
<Position X="-59.3499641" Y="7.46932745" Z="-20.6276321"/> <Position X="-59.3499641" Y="7.46932745" Z="-20.6276321"/>
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/> <Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
<Orientation X="0" Y="72.2667694" Z="0"/> <Orientation X="0" Y="71.2585754" Z="0"/>
</c:Transform> </c:Transform>
<c:Trigger/> <c:Trigger/>
</Components> </Components>
@@ -5203,7 +5203,7 @@
<c:Transform> <c:Transform>
<Position X="-1.13644195" Y="1.38919806" Z="38.9768829"/> <Position X="-1.13644195" Y="1.38919806" Z="38.9768829"/>
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/> <Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
<Orientation X="0" Y="69.8748016" Z="0"/> <Orientation X="0" Y="68.8666077" Z="0"/>
</c:Transform> </c:Transform>
<c:Trigger/> <c:Trigger/>
</Components> </Components>
@@ -5222,7 +5222,7 @@
<c:Transform> <c:Transform>
<Position X="54.7225227" Y="6.51863909" Z="29.0052128"/> <Position X="54.7225227" Y="6.51863909" Z="29.0052128"/>
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/> <Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
<Orientation X="0" Y="70.1887283" Z="0"/> <Orientation X="0" Y="69.180542" Z="0"/>
</c:Transform> </c:Transform>
<c:Trigger/> <c:Trigger/>
</Components> </Components>
@@ -5241,7 +5241,7 @@
<c:Transform> <c:Transform>
<Position X="-51.6792374" Y="8.44526482" Z="32.5153465"/> <Position X="-51.6792374" Y="8.44526482" Z="32.5153465"/>
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/> <Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
<Orientation X="0" Y="69.6374512" Z="0"/> <Orientation X="0" Y="68.6292572" Z="0"/>
</c:Transform> </c:Transform>
<c:Trigger/> <c:Trigger/>
</Components> </Components>
@@ -5260,7 +5260,7 @@
<c:Transform> <c:Transform>
<Position X="-42.3974304" Y="7.28327894" Z="81.9305344"/> <Position X="-42.3974304" Y="7.28327894" Z="81.9305344"/>
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/> <Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
<Orientation X="0" Y="67.7666702" Z="0"/> <Orientation X="0" Y="66.7584839" Z="0"/>
</c:Transform> </c:Transform>
<c:Trigger/> <c:Trigger/>
</Components> </Components>
@@ -5279,7 +5279,7 @@
<c:Transform> <c:Transform>
<Position X="-9.85184956" Y="8.25567532" Z="39.6119232"/> <Position X="-9.85184956" Y="8.25567532" Z="39.6119232"/>
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/> <Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
<Orientation X="0" Y="66.8154602" Z="0"/> <Orientation X="0" Y="65.8073425" Z="0"/>
</c:Transform> </c:Transform>
<c:Trigger/> <c:Trigger/>
</Components> </Components>
@@ -5298,7 +5298,7 @@
<c:Transform> <c:Transform>
<Position X="49.2257118" Y="7.39368248" Z="-31.1810112"/> <Position X="49.2257118" Y="7.39368248" Z="-31.1810112"/>
<Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/> <Scale X="0.300000012" Y="0.300000012" Z="0.300000012"/>
<Orientation X="0" Y="64.0265808" Z="0"/> <Orientation X="0" Y="63.0184822" Z="0"/>
</c:Transform> </c:Transform>
<c:Trigger/> <c:Trigger/>
</Components> </Components>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+89 -6
View File
@@ -100,12 +100,12 @@
<Percentage>1</Percentage> <Percentage>1</Percentage>
<Color A="1" B="1" G="0" R="0"/> <Color A="1" B="1" G="0" R="0"/>
</c:Fill> </c:Fill>
<c:HealthHUD/>
<c:Text> <c:Text>
<Content>100/100</Content> <Content>100/100</Content>
<Resource>Fonts/DroidSans.ttf,64</Resource> <Resource>Fonts/DroidSans.ttf,64</Resource>
<Color A="0.505882382" B="3.92156863" G="1.17647064" R="0"/> <Color A="0.505882382" B="3.92156863" G="1.17647064" R="0"/>
</c:Text> </c:Text>
<c:HealthHUD/>
<c:Transform> <c:Transform>
<Position X="-0.355000019" Y="-0.203000009" Z="0.0410000011"/> <Position X="-0.355000019" Y="-0.203000009" Z="0.0410000011"/>
<Scale X="0.0350000001" Y="0.0350000001" Z="0.0350000001"/> <Scale X="0.0350000001" Y="0.0350000001" Z="0.0350000001"/>
@@ -132,7 +132,70 @@
<Orientation X="5.87300014" Y="0" Z="4.71200037"/> <Orientation X="5.87300014" Y="0" Z="4.71200037"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children/> <Children>
<Entity name="BoostIcons">
<Components>
<c:BoostIconsHUD/>
<c:Transform/>
</Components>
<Children>
<Entity name="Assault">
<Components>
<c:Fill>
<Color A="1" B="0.533333361" G="1" R="0.329411775"/>
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/Core/White.png</DiffuseTexture>
<DepthSort>false</DepthSort>
<GlowMap></GlowMap>
<Color A="0.588235319" B="0.0392156877" G="0.184313729" R="0"/>
</c:Sprite>
<c:Transform>
<Position X="0.225000009" Y="0.168000013" Z="0"/>
<Scale X="0.27700001" Y="0.100000001" Z="0.200000003"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="Defender">
<Components>
<c:Fill>
<Color A="1" B="1" G="0.58431375" R="0.105882354"/>
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/Core/White.png</DiffuseTexture>
<DepthSort>false</DepthSort>
<GlowMap></GlowMap>
<Color A="0.588235319" B="0.34117648" G="0.192156866" R="0"/>
</c:Sprite>
<c:Transform>
<Position X="0.224999994" Y="0.27700001" Z="0"/>
<Scale X="0.27700001" Y="0.100000001" Z="0.200000003"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="Sniper">
<Components>
<c:Fill>
<Color A="1" B="0.345098048" G="0" R="1"/>
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/Core/White.png</DiffuseTexture>
<DepthSort>false</DepthSort>
<GlowMap></GlowMap>
<Color A="0.588235319" B="0.121568628" G="0" R="0.443137258"/>
</c:Sprite>
<c:Transform>
<Position X="0.225000009" Y="0.38500002" Z="0"/>
<Scale X="0.27700001" Y="0.100000001" Z="0.200000003"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
</Children>
</Entity> </Entity>
</Children> </Children>
</Entity> </Entity>
@@ -196,7 +259,6 @@
<CapturePointNumber>3</CapturePointNumber> <CapturePointNumber>3</CapturePointNumber>
</c:CapturePointHUD> </c:CapturePointHUD>
<c:Fill> <c:Fill>
<Percentage>0.80222018197612788</Percentage>
<Color A="0.699999988" B="1" G="0.200000003" R="0"/> <Color A="0.699999988" B="1" G="0.200000003" R="0"/>
</c:Fill> </c:Fill>
<c:Sprite> <c:Sprite>
@@ -231,6 +293,7 @@
<CapturePointNumber>4</CapturePointNumber> <CapturePointNumber>4</CapturePointNumber>
</c:CapturePointHUD> </c:CapturePointHUD>
<c:Fill> <c:Fill>
<Percentage>1</Percentage>
<Color A="0.699999988" B="1" G="0.200000003" R="0"/> <Color A="0.699999988" B="1" G="0.200000003" R="0"/>
</c:Fill> </c:Fill>
<c:Sprite> <c:Sprite>
@@ -286,7 +349,7 @@
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture> <DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap> <GlowMap></GlowMap>
<Color A="0.699999988" B="0" G="0.200000003" R="1"/> <Color A="0.699999988" B="0" G="0" R="1"/>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
<Position X="-1.58304751" Y="0.919596612" Z="0"/> <Position X="-1.58304751" Y="0.919596612" Z="0"/>
@@ -297,7 +360,8 @@
<Components> <Components>
<c:CapturePointHUD/> <c:CapturePointHUD/>
<c:Fill> <c:Fill>
<Color A="0.699999988" B="1" G="0.200000003" R="0"/> <Percentage>1</Percentage>
<Color A="0.699999988" B="0" G="0" R="1"/>
</c:Fill> </c:Fill>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture> <DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
@@ -306,7 +370,7 @@
<c:Transform> <c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/> <Position X="0" Y="0" Z="0.00999999978"/>
<Scale X="0.800000012" Y="0.800000012" Z="0.800000012"/> <Scale X="0.800000012" Y="0.800000012" Z="0.800000012"/>
<Orientation X="0" Y="0" Z="1.57079637"/> <Orientation X="0" Y="0" Z="4.71238899"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children/> <Children/>
@@ -369,6 +433,25 @@
</Entity> </Entity>
</Children> </Children>
</Entity> </Entity>
<Entity name="CapturePointArrow">
<Components>
<c:CapturePointArrowHUD/>
<c:Model>
<Resource>Models/Widgets/Arrows/Arrow5.mesh</Resource>
</c:Model>
<c:Team>
<Team>
<Blue/>
</Team>
</c:Team>
<c:Transform>
<Position X="0" Y="0.714000046" Z="-1.30000007"/>
<Scale X="0.200000003" Y="0.200000003" Z="0.200000003"/>
<Orientation X="0.405680239" Y="0.369605929" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children> </Children>
</Entity> </Entity>
<Entity name="Hands"> <Entity name="Hands">
+116 -38
View File
@@ -2,6 +2,9 @@
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd"> <Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components> <Components>
<c:CapturePointGameMode>
<RespawnTime>4.7473226580121377</RespawnTime>
</c:CapturePointGameMode>
<c:Transform> <c:Transform>
<Position X="0" Y="-1" Z="0"/> <Position X="0" Y="-1" Z="0"/>
</c:Transform> </c:Transform>
@@ -40,7 +43,7 @@
<Axis X="0" Y="1" Z="0"/> <Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter> </c:RaptorCopter>
<c:Transform> <c:Transform>
<Orientation X="0" Y="8433.37305" Z="0"/> <Orientation X="0" Y="9038.11328" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -81,19 +84,19 @@
</Entity> </Entity>
<Entity name="DirectionalLight"> <Entity name="DirectionalLight">
<Components> <Components>
<c:RaptorCopter>
<Speed>1</Speed>
<Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter>
<c:DirectionalLight> <c:DirectionalLight>
<Intensity>0.80000001192092896</Intensity> <Intensity>0.80000001192092896</Intensity>
</c:DirectionalLight> </c:DirectionalLight>
<c:Model> <c:Model>
<Resource>Models/Widgets/Lights/DirectionalLightWidget.mesh</Resource> <Resource>Models/Widgets/Lights/DirectionalLightWidget.mesh</Resource>
</c:Model> </c:Model>
<c:RaptorCopter>
<Speed>1</Speed>
<Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter>
<c:Transform> <c:Transform>
<Position X="2.1529963" Y="6.59221172" Z="0.169116676"/> <Position X="2.1529963" Y="6.59221172" Z="0.169116676"/>
<Orientation X="4.16300011" Y="18271.9141" Z="0"/> <Orientation X="4.16300011" Y="18876.6172" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children/> <Children/>
@@ -108,7 +111,11 @@
<Children> <Children>
<Entity name="RunAnim"> <Entity name="RunAnim">
<Components> <Components>
<c:Animation/> <c:Animation>
<AnimationName1></AnimationName1>
<AnimationName2></AnimationName2>
<AnimationName3></AnimationName3>
</c:Animation>
<c:Model> <c:Model>
<Resource>Models/Characters/Assault/AssaultAnimated.mesh</Resource> <Resource>Models/Characters/Assault/AssaultAnimated.mesh</Resource>
</c:Model> </c:Model>
@@ -120,7 +127,11 @@
</Entity> </Entity>
<Entity name="Walkanim"> <Entity name="Walkanim">
<Components> <Components>
<c:Animation/> <c:Animation>
<AnimationName1></AnimationName1>
<AnimationName2></AnimationName2>
<AnimationName3></AnimationName3>
</c:Animation>
<c:Model> <c:Model>
<Resource>Models/Characters/Assault/AssaultAnimated.mesh</Resource> <Resource>Models/Characters/Assault/AssaultAnimated.mesh</Resource>
</c:Model> </c:Model>
@@ -168,13 +179,17 @@
<Axis X="0" Y="1" Z="0"/> <Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter> </c:RaptorCopter>
<c:Transform> <c:Transform>
<Orientation X="0" Y="2553.63574" Z="0"/> <Orientation X="0" Y="2856.05518" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
<Entity name="Asset"> <Entity name="Asset">
<Components> <Components>
<c:Animation/> <c:Animation>
<AnimationName1></AnimationName1>
<AnimationName2></AnimationName2>
<AnimationName3></AnimationName3>
</c:Animation>
<c:Model> <c:Model>
<Resource>Models/Characters/Assault/AssaultAnimated.mesh</Resource> <Resource>Models/Characters/Assault/AssaultAnimated.mesh</Resource>
</c:Model> </c:Model>
@@ -213,7 +228,7 @@
<Axis X="1" Y="1" Z="1"/> <Axis X="1" Y="1" Z="1"/>
</c:RaptorCopter> </c:RaptorCopter>
<c:Transform> <c:Transform>
<Orientation X="16862.3945" Y="16862.3945" Z="16862.3945"/> <Orientation X="17467.0977" Y="17467.0977" Z="17467.0977"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -277,7 +292,7 @@
<Axis X="0" Y="1" Z="0"/> <Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter> </c:RaptorCopter>
<c:Transform> <c:Transform>
<Orientation X="0" Y="16658.3906" Z="0"/> <Orientation X="0" Y="17263.0938" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -309,7 +324,7 @@
<Axis X="0.699999988" Y="1" Z="0.300000012"/> <Axis X="0.699999988" Y="1" Z="0.300000012"/>
</c:RaptorCopter> </c:RaptorCopter>
<c:Transform> <c:Transform>
<Orientation X="12206.665" Y="17385.8008" Z="5202.3335"/> <Orientation X="12630.0664" Y="17990.5039" Z="5383.80176"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -659,7 +674,7 @@
<Axis X="0" Y="1" Z="0"/> <Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter> </c:RaptorCopter>
<c:Transform> <c:Transform>
<Orientation X="0" Y="851.386902" Z="0"/> <Orientation X="0" Y="1153.80225" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -706,7 +721,7 @@
<Axis X="0" Y="1" Z="0"/> <Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter> </c:RaptorCopter>
<c:Transform> <c:Transform>
<Orientation X="0" Y="851.386902" Z="0"/> <Orientation X="0" Y="1153.80225" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -766,7 +781,7 @@
<Axis X="0" Y="1" Z="0"/> <Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter> </c:RaptorCopter>
<c:Transform> <c:Transform>
<Orientation X="0" Y="851.386902" Z="0"/> <Orientation X="0" Y="1153.80225" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -813,7 +828,7 @@
<Axis X="0" Y="1" Z="0"/> <Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter> </c:RaptorCopter>
<c:Transform> <c:Transform>
<Orientation X="0" Y="851.386902" Z="0"/> <Orientation X="0" Y="1153.80225" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -859,7 +874,7 @@
<Axis X="0" Y="1" Z="0"/> <Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter> </c:RaptorCopter>
<c:Transform> <c:Transform>
<Orientation X="0" Y="851.386902" Z="0"/> <Orientation X="0" Y="1153.80225" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -906,7 +921,7 @@
<Axis X="0" Y="1" Z="0"/> <Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter> </c:RaptorCopter>
<c:Transform> <c:Transform>
<Orientation X="0" Y="851.386902" Z="0"/> <Orientation X="0" Y="1153.80225" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -953,7 +968,7 @@
<Axis X="0" Y="1" Z="0"/> <Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter> </c:RaptorCopter>
<c:Transform> <c:Transform>
<Orientation X="0" Y="851.386902" Z="0"/> <Orientation X="0" Y="1153.80225" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -1013,6 +1028,7 @@
</HomePointForTeam> </HomePointForTeam>
<CaptureTimer>15</CaptureTimer> <CaptureTimer>15</CaptureTimer>
</c:CapturePoint> </c:CapturePoint>
<c:Trigger/>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="0.300000012" B="0" G="0" R="1"/> <Color A="0.300000012" B="0" G="0" R="1"/>
@@ -1027,7 +1043,6 @@
<Position X="0" Y="2" Z="0"/> <Position X="0" Y="2" Z="0"/>
<Scale X="8" Y="4" Z="8"/> <Scale X="8" Y="4" Z="8"/>
</c:Transform> </c:Transform>
<c:Trigger/>
</Components> </Components>
<Children/> <Children/>
</Entity> </Entity>
@@ -1063,6 +1078,7 @@
<c:CapturePoint> <c:CapturePoint>
<CapturePointNumber>1</CapturePointNumber> <CapturePointNumber>1</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Trigger/>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="0.300000012" B="1" G="1" R="1"/> <Color A="0.300000012" B="1" G="1" R="1"/>
@@ -1073,7 +1089,6 @@
<Position X="0" Y="2" Z="0"/> <Position X="0" Y="2" Z="0"/>
<Scale X="8" Y="4" Z="8"/> <Scale X="8" Y="4" Z="8"/>
</c:Transform> </c:Transform>
<c:Trigger/>
</Components> </Components>
<Children/> <Children/>
</Entity> </Entity>
@@ -1107,6 +1122,7 @@
<c:CapturePoint> <c:CapturePoint>
<CapturePointNumber>2</CapturePointNumber> <CapturePointNumber>2</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Trigger/>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="0.300000012" B="1" G="1" R="1"/> <Color A="0.300000012" B="1" G="1" R="1"/>
@@ -1117,7 +1133,6 @@
<Position X="0" Y="2" Z="0"/> <Position X="0" Y="2" Z="0"/>
<Scale X="8" Y="4" Z="8"/> <Scale X="8" Y="4" Z="8"/>
</c:Transform> </c:Transform>
<c:Trigger/>
</Components> </Components>
<Children/> <Children/>
</Entity> </Entity>
@@ -1153,6 +1168,7 @@
<c:CapturePoint> <c:CapturePoint>
<CapturePointNumber>3</CapturePointNumber> <CapturePointNumber>3</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Trigger/>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="0.300000012" B="1" G="1" R="1"/> <Color A="0.300000012" B="1" G="1" R="1"/>
@@ -1163,7 +1179,6 @@
<Position X="0" Y="2" Z="0"/> <Position X="0" Y="2" Z="0"/>
<Scale X="8" Y="4" Z="8"/> <Scale X="8" Y="4" Z="8"/>
</c:Transform> </c:Transform>
<c:Trigger/>
</Components> </Components>
<Children/> <Children/>
</Entity> </Entity>
@@ -1203,6 +1218,7 @@
<CaptureTimer>-15</CaptureTimer> <CaptureTimer>-15</CaptureTimer>
<CapturePointNumber>4</CapturePointNumber> <CapturePointNumber>4</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Trigger/>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="0.300000012" B="1" G="0" R="0"/> <Color A="0.300000012" B="1" G="0" R="0"/>
@@ -1217,7 +1233,6 @@
<Position X="0" Y="2" Z="0"/> <Position X="0" Y="2" Z="0"/>
<Scale X="8" Y="4" Z="8"/> <Scale X="8" Y="4" Z="8"/>
</c:Transform> </c:Transform>
<c:Trigger/>
</Components> </Components>
<Children/> <Children/>
</Entity> </Entity>
@@ -1367,7 +1382,7 @@
<Axis X="0" Y="1" Z="0"/> <Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter> </c:RaptorCopter>
<c:Transform> <c:Transform>
<Orientation X="0" Y="1385.11243" Z="0"/> <Orientation X="0" Y="1687.52917" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -1376,7 +1391,7 @@
<c:ExplosionEffect> <c:ExplosionEffect>
<ColorByDistance>true</ColorByDistance> <ColorByDistance>true</ColorByDistance>
<Velocity X="0.800000012" Y="0.0379999988" Z="0"/> <Velocity X="0.800000012" Y="0.0379999988" Z="0"/>
<TimeSinceDeath>0.8256214817261025</TimeSinceDeath> <TimeSinceDeath>2.5396116058983438</TimeSinceDeath>
<ExplosionDuration>3.7999999523162842</ExplosionDuration> <ExplosionDuration>3.7999999523162842</ExplosionDuration>
<EndColor A="0" B="23.5294113" G="11.7647057" R="0"/> <EndColor A="0" B="23.5294113" G="11.7647057" R="0"/>
<Randomness>true</Randomness> <Randomness>true</Randomness>
@@ -1423,7 +1438,7 @@
<Axis X="0" Y="1" Z="0"/> <Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter> </c:RaptorCopter>
<c:Transform> <c:Transform>
<Orientation X="0" Y="1385.11243" Z="0"/> <Orientation X="0" Y="1687.52917" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -1432,7 +1447,7 @@
<c:ExplosionEffect> <c:ExplosionEffect>
<Velocity X="0.5" Y="1" Z="0"/> <Velocity X="0.5" Y="1" Z="0"/>
<ExplosionOrigin X="0" Y="0.900000036" Z="0"/> <ExplosionOrigin X="0" Y="0.900000036" Z="0"/>
<TimeSinceDeath>1.8641349174045843</TimeSinceDeath> <TimeSinceDeath>1.5396208215609732</TimeSinceDeath>
</c:ExplosionEffect> </c:ExplosionEffect>
<c:Model> <c:Model>
<Resource>Models/Characters/Assault/AssaultTPose.mesh</Resource> <Resource>Models/Characters/Assault/AssaultTPose.mesh</Resource>
@@ -1475,18 +1490,22 @@
<Axis X="0" Y="1" Z="0"/> <Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter> </c:RaptorCopter>
<c:Transform> <c:Transform>
<Orientation X="0" Y="1385.11243" Z="0"/> <Orientation X="0" Y="1687.52917" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
<Entity name="Asset"> <Entity name="Asset">
<Components> <Components>
<c:Animation/> <c:Animation>
<AnimationName1></AnimationName1>
<AnimationName2></AnimationName2>
<AnimationName3></AnimationName3>
</c:Animation>
<c:ExplosionEffect> <c:ExplosionEffect>
<ColorByDistance>true</ColorByDistance> <ColorByDistance>true</ColorByDistance>
<Velocity X="0.300000012" Y="2" Z="0"/> <Velocity X="0.300000012" Y="2" Z="0"/>
<ExplosionOrigin X="0" Y="1.30000007" Z="-0.200000003"/> <ExplosionOrigin X="0" Y="1.30000007" Z="-0.200000003"/>
<TimeSinceDeath>1.8641349174045843</TimeSinceDeath> <TimeSinceDeath>1.5396208215609732</TimeSinceDeath>
<EndColor A="0" B="0.333333343" G="0.933333337" R="3.92156863"/> <EndColor A="0" B="0.333333343" G="0.933333337" R="3.92156863"/>
<Randomness>true</Randomness> <Randomness>true</Randomness>
</c:ExplosionEffect> </c:ExplosionEffect>
@@ -1531,7 +1550,7 @@
<Axis X="0" Y="1" Z="0"/> <Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter> </c:RaptorCopter>
<c:Transform> <c:Transform>
<Orientation X="0" Y="1392.89258" Z="0"/> <Orientation X="0" Y="1695.30933" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -1541,7 +1560,7 @@
<ColorByDistance>true</ColorByDistance> <ColorByDistance>true</ColorByDistance>
<Velocity X="0" Y="0.699999988" Z="0"/> <Velocity X="0" Y="0.699999988" Z="0"/>
<ExplosionOrigin X="0" Y="-1.10000002" Z="0"/> <ExplosionOrigin X="0" Y="-1.10000002" Z="0"/>
<TimeSinceDeath>1.2301962937648341</TimeSinceDeath> <TimeSinceDeath>4.4522528839264339</TimeSinceDeath>
<ExplosionDuration>10</ExplosionDuration> <ExplosionDuration>10</ExplosionDuration>
<EndColor A="1" B="0" G="0" R="1"/> <EndColor A="1" B="0" G="0" R="1"/>
<RandomnessScalar>3</RandomnessScalar> <RandomnessScalar>3</RandomnessScalar>
@@ -1589,7 +1608,7 @@
<Axis X="0" Y="1" Z="0"/> <Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter> </c:RaptorCopter>
<c:Transform> <c:Transform>
<Orientation X="0" Y="991.007263" Z="0"/> <Orientation X="0" Y="1293.42383" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -1599,7 +1618,7 @@
<ColorByDistance>true</ColorByDistance> <ColorByDistance>true</ColorByDistance>
<Velocity X="6" Y="0.100000001" Z="0"/> <Velocity X="6" Y="0.100000001" Z="0"/>
<ExplosionOrigin X="0" Y="-10" Z="0"/> <ExplosionOrigin X="0" Y="-10" Z="0"/>
<TimeSinceDeath>3.4214855659573402</TimeSinceDeath> <TimeSinceDeath>3.2362842141074992</TimeSinceDeath>
<ExponentialAccelaration>true</ExponentialAccelaration> <ExponentialAccelaration>true</ExponentialAccelaration>
<ExplosionDuration>5</ExplosionDuration> <ExplosionDuration>5</ExplosionDuration>
<Randomness>true</Randomness> <Randomness>true</Randomness>
@@ -1690,6 +1709,7 @@
</c:Physics> </c:Physics>
<c:Player> <c:Player>
<MovementSpeed>5</MovementSpeed> <MovementSpeed>5</MovementSpeed>
<CurrentWeapon></CurrentWeapon>
</c:Player> </c:Player>
<c:Team> <c:Team>
<Team> <Team>
@@ -1712,6 +1732,7 @@
<Entity name="PlayerName"> <Entity name="PlayerName">
<Components> <Components>
<c:Text> <c:Text>
<Content></Content>
<Resource>Fonts/DroidSans.ttf,100</Resource> <Resource>Fonts/DroidSans.ttf,100</Resource>
<Color A="1" B="0" G="1" R="0"/> <Color A="1" B="0" G="1" R="0"/>
</c:Text> </c:Text>
@@ -1780,7 +1801,7 @@
<c:ExplosionEffect> <c:ExplosionEffect>
<ColorByDistance>true</ColorByDistance> <ColorByDistance>true</ColorByDistance>
<Velocity X="0.800000012" Y="0.0379999988" Z="0"/> <Velocity X="0.800000012" Y="0.0379999988" Z="0"/>
<TimeSinceDeath>0.8256214817261025</TimeSinceDeath> <TimeSinceDeath>2.5396116058983438</TimeSinceDeath>
<ExplosionDuration>3.7999999523162842</ExplosionDuration> <ExplosionDuration>3.7999999523162842</ExplosionDuration>
<EndColor A="0" B="23.5294113" G="11.7647057" R="0"/> <EndColor A="0" B="23.5294113" G="11.7647057" R="0"/>
<Randomness>true</Randomness> <Randomness>true</Randomness>
@@ -1823,7 +1844,11 @@
</Entity> </Entity>
<Entity name="PlayerModel"> <Entity name="PlayerModel">
<Components> <Components>
<c:Animation/> <c:Animation>
<AnimationName1></AnimationName1>
<AnimationName2></AnimationName2>
<AnimationName3></AnimationName3>
</c:Animation>
<c:Shielded/> <c:Shielded/>
<c:HiddenForLocalPlayer/> <c:HiddenForLocalPlayer/>
<c:Model> <c:Model>
@@ -1925,6 +1950,7 @@
<Components> <Components>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Props/FoliageDiff.png</DiffuseTexture> <DiffuseTexture>Textures/Props/FoliageDiff.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite> </c:Sprite>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -1934,6 +1960,7 @@
<Components> <Components>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Props/FoliageDiff.png</DiffuseTexture> <DiffuseTexture>Textures/Props/FoliageDiff.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
<Position X="-0.177861199" Y="0" Z="-1.04673338"/> <Position X="-0.177861199" Y="0" Z="-1.04673338"/>
@@ -1954,6 +1981,7 @@
<Components> <Components>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture> <DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.300000012" B="1" G="1" R="1"/> <Color A="0.300000012" B="1" G="1" R="1"/>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
@@ -1971,6 +1999,7 @@
</c:Fill> </c:Fill>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture> <DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/> <Position X="0" Y="0" Z="0.00999999978"/>
@@ -1986,6 +2015,7 @@
<Components> <Components>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture> <DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.300000012" B="1" G="1" R="1"/> <Color A="0.300000012" B="1" G="1" R="1"/>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
@@ -2003,6 +2033,7 @@
</c:Fill> </c:Fill>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture> <DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/> <Position X="0" Y="0" Z="0.00999999978"/>
@@ -2018,6 +2049,7 @@
<Components> <Components>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture> <DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.699999988" B="1" G="0.200000003" R="0"/> <Color A="0.699999988" B="1" G="0.200000003" R="0"/>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
@@ -2036,6 +2068,7 @@
</c:Fill> </c:Fill>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture> <DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/> <Position X="0" Y="0" Z="0.00999999978"/>
@@ -2051,6 +2084,7 @@
<Components> <Components>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture> <DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.300000012" B="1" G="1" R="1"/> <Color A="0.300000012" B="1" G="1" R="1"/>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
@@ -2068,6 +2102,7 @@
</c:Fill> </c:Fill>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture> <DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/> <Position X="0" Y="0" Z="0.00999999978"/>
@@ -2083,6 +2118,7 @@
<Components> <Components>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture> <DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.699999988" B="0" G="0" R="1"/> <Color A="0.699999988" B="0" G="0" R="1"/>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
@@ -2099,6 +2135,7 @@
</c:Fill> </c:Fill>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture> <DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/> <Position X="0" Y="0" Z="0.00999999978"/>
@@ -2167,6 +2204,7 @@
<Components> <Components>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/ErrorTexture.png</DiffuseTexture> <DiffuseTexture>Textures/Core/ErrorTexture.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
<Position X="0" Y="0" Z="-1"/> <Position X="0" Y="0" Z="-1"/>
@@ -2178,6 +2216,7 @@
<c:Button/> <c:Button/>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/White.png</DiffuseTexture> <DiffuseTexture>Textures/Core/White.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
<Position X="0" Y="0.388422519" Z="0.0627754927"/> <Position X="0" Y="0.388422519" Z="0.0627754927"/>
@@ -2206,6 +2245,7 @@
<c:Button/> <c:Button/>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/White.png</DiffuseTexture> <DiffuseTexture>Textures/Core/White.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
<Position X="0" Y="0.214031488" Z="0.0627754927"/> <Position X="0" Y="0.214031488" Z="0.0627754927"/>
@@ -2234,6 +2274,7 @@
<c:Button/> <c:Button/>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/White.png</DiffuseTexture> <DiffuseTexture>Textures/Core/White.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
<Position X="0" Y="0.0367300175" Z="0.0627754927"/> <Position X="0" Y="0.0367300175" Z="0.0627754927"/>
@@ -2262,6 +2303,7 @@
<c:Button/> <c:Button/>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/White.png</DiffuseTexture> <DiffuseTexture>Textures/Core/White.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
<Position X="0" Y="-0.148274168" Z="0.0627754927"/> <Position X="0" Y="-0.148274168" Z="0.0627754927"/>
@@ -2290,6 +2332,7 @@
<c:Button/> <c:Button/>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/White.png</DiffuseTexture> <DiffuseTexture>Textures/Core/White.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
<Position X="0" Y="-0.335298717" Z="0.0627754927"/> <Position X="0" Y="-0.335298717" Z="0.0627754927"/>
@@ -2331,6 +2374,7 @@
<Components> <Components>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/ErrorTexture.png</DiffuseTexture> <DiffuseTexture>Textures/Core/ErrorTexture.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
<Position X="0" Y="0" Z="-1"/> <Position X="0" Y="0" Z="-1"/>
@@ -2342,6 +2386,7 @@
<c:Button/> <c:Button/>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/White.png</DiffuseTexture> <DiffuseTexture>Textures/Core/White.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
<Position X="0" Y="0.375197947" Z="0.0627754927"/> <Position X="0" Y="0.375197947" Z="0.0627754927"/>
@@ -2370,6 +2415,7 @@
<c:Button/> <c:Button/>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/White.png</DiffuseTexture> <DiffuseTexture>Textures/Core/White.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
<Position X="0" Y="0.199327558" Z="0.0627754927"/> <Position X="0" Y="0.199327558" Z="0.0627754927"/>
@@ -2398,6 +2444,7 @@
<c:Button/> <c:Button/>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/White.png</DiffuseTexture> <DiffuseTexture>Textures/Core/White.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
<Position X="0" Y="0.0159880854" Z="0.0627754927"/> <Position X="0" Y="0.0159880854" Z="0.0627754927"/>
@@ -2426,6 +2473,7 @@
<c:Button/> <c:Button/>
<c:Sprite> <c:Sprite>
<DiffuseTexture>Textures/Core/White.png</DiffuseTexture> <DiffuseTexture>Textures/Core/White.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite> </c:Sprite>
<c:Transform> <c:Transform>
<Position X="0" Y="-0.164955258" Z="0.0627754927"/> <Position X="0" Y="-0.164955258" Z="0.0627754927"/>
@@ -2482,6 +2530,36 @@
</Components> </Components>
<Children/> <Children/>
</Entity> </Entity>
<Entity>
<Components>
<c:Team/>
<c:Transform>
<Position X="9.42733288" Y="8.22214794" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity name="CapturePointArrow">
<Components>
<c:CapturePointArrowHUD>
<CurrentTarget>2</CurrentTarget>
</c:CapturePointArrowHUD>
<c:Model>
<Resource>Models/Weapons/Blue/AssaultWeaponBlue.mesh</Resource>
</c:Model>
<c:Team>
<Team>
<Red/>
</Team>
</c:Team>
<c:Transform>
<Scale X="10.7000008" Y="1.4000001" Z="5.30000019"/>
<Orientation X="-0.648448348" Y="-0.417814791" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
</Children> </Children>
</Entity> </Entity>
@@ -0,0 +1,219 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity name="SpectatorCamera" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Camera/>
<c:Transform>
<Position X="0" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity name="SpectatorHUD">
<Components>
<c:Transform>
<Position X="0" Y="0" Z="-0.5"/>
</c:Transform>
</Components>
<Children>
<Entity name="RespawnTimer">
<Components>
<c:Text>
<Content>Time to respawn: 0</Content>
<Resource>Fonts/DroidSans.ttf,64</Resource>
<Color A="1" B="0" G="1" R="0.784313738"/>
<Alignment>
<Left/>
</Alignment>
</c:Text>
<c:Transform>
<Position X="-0.115000000" Y="0.15304254" Z="0"/>
<Scale X="0.0250000004" Y="0.0250000004" Z="1"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="CapturePointHUD">
<Components>
<c:Transform>
<Position X="0" Y="0.190541431" Z="0"/>
<Scale X="0.0599999987" Y="0.0599999987" Z="0.0599999987"/>
</c:Transform>
</Components>
<Children>
<Entity name="BackgroundHexagon">
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.300000012" B="1" G="1" R="1"/>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0.919596612" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity name="ProgressionHexagon">
<Components>
<c:CapturePointHUD>
<CapturePointNumber>2</CapturePointNumber>
</c:CapturePointHUD>
<c:Fill>
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/>
<Scale X="0.800000012" Y="0.800000012" Z="0.800000012"/>
<Orientation X="0" Y="0" Z="1.57079637"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
<Entity name="BackgroundHexagon">
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.300000012" B="1" G="1" R="1"/>
</c:Sprite>
<c:Transform>
<Position X="0.811270177" Y="0.440691769" Z="-0.100000001"/>
</c:Transform>
</Components>
<Children>
<Entity name="ProgressionHexagon">
<Components>
<c:CapturePointHUD>
<CapturePointNumber>3</CapturePointNumber>
</c:CapturePointHUD>
<c:Fill>
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/>
<Scale X="0.800000012" Y="0.800000012" Z="0.800000012"/>
<Orientation X="0" Y="0" Z="1.57079637"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
<Entity name="BackgroundHexagon">
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
</c:Sprite>
<c:Transform>
<Position X="1.62788737" Y="0.919596612" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity name="ProgressionHexagon">
<Components>
<c:CapturePointHUD>
<CapturePointNumber>4</CapturePointNumber>
</c:CapturePointHUD>
<c:Fill>
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/>
<Scale X="0.800000012" Y="0.800000012" Z="0.800000012"/>
<Orientation X="0" Y="0" Z="1.57079637"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
<Entity name="BackgroundHexagon">
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.300000012" B="1" G="1" R="1"/>
</c:Sprite>
<c:Transform>
<Position X="-0.820431828" Y="0.441878349" Z="-0.100000001"/>
</c:Transform>
</Components>
<Children>
<Entity name="ProgressionHexagon">
<Components>
<c:CapturePointHUD>
<CapturePointNumber>1</CapturePointNumber>
</c:CapturePointHUD>
<c:Fill>
<Percentage>0.59265931447347009</Percentage>
<Color A="0.699999988" B="0" G="0" R="1"/>
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/>
<Scale X="0.800000012" Y="0.800000012" Z="0.800000012"/>
<Orientation X="0" Y="0" Z="4.71238899"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
<Entity name="BackgroundHexagon">
<Components>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<GlowMap></GlowMap>
<Color A="0.699999988" B="0" G="0" R="1"/>
</c:Sprite>
<c:Transform>
<Position X="-1.58304751" Y="0.919596612" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity name="ProgressionHexagon">
<Components>
<c:CapturePointHUD/>
<c:Fill>
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
</c:Fill>
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
<GlowMap></GlowMap>
</c:Sprite>
<c:Transform>
<Position X="0" Y="0" Z="0.00999999978"/>
<Scale X="0.800000012" Y="0.800000012" Z="0.800000012"/>
<Orientation X="0" Y="0" Z="1.57079637"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
</Children>
</Entity>
</Children>
</Entity>
</Children>
</Entity>
+10
View File
@@ -51,7 +51,17 @@
<xs:element ref="c:Page" minOccurs="0"/> <xs:element ref="c:Page" minOccurs="0"/>
<xs:element ref="c:Button" minOccurs="0"/> <xs:element ref="c:Button" minOccurs="0"/>
<xs:element ref="c:WeaponAttachment" minOccurs="0"/> <xs:element ref="c:WeaponAttachment" minOccurs="0"/>
<xs:element ref="c:AbilityCooldownHUD" minOccurs="0"/>
<xs:element ref="c:DefenderWeapon" minOccurs="0"/> <xs:element ref="c:DefenderWeapon" minOccurs="0"/>
<xs:element ref="c:CapturePointArrowHUD" minOccurs="0"/>
<xs:element ref="c:BoostIconsHUD" minOccurs="0"/>
<xs:element ref="c:FloatingEffect" minOccurs="0"/>
<xs:element ref="c:AmmoPickup" minOccurs="0"/>
<xs:element ref="c:HealthPickup" minOccurs="0"/>
<xs:element ref="c:CapturePointGameMode" minOccurs="0"/>
<xs:element ref="c:DoubleJump" minOccurs="0"/>
<xs:element ref="c:HealthHUD" minOccurs="0"/>
<xs:element ref="c:SpriteIndicator" minOccurs="0"/>
</xs:all> </xs:all>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
@@ -40,7 +40,6 @@ layout (binding = 10) uniform sampler2D SpecularMapTexture3;
layout (binding = 11) uniform sampler2D GlowMapTexture1; layout (binding = 11) uniform sampler2D GlowMapTexture1;
layout (binding = 12) uniform sampler2D GlowMapTexture2; layout (binding = 12) uniform sampler2D GlowMapTexture2;
layout (binding = 13) uniform sampler2D GlowMapTexture3; layout (binding = 13) uniform sampler2D GlowMapTexture3;
layout (binding = 13) uniform sampler2D GlowMapTexture3;
layout (binding = 31) uniform samplerCube ShieldBuffer; layout (binding = 31) uniform samplerCube ShieldBuffer;
#define TILE_SIZE 16 #define TILE_SIZE 16
+14 -280
View File
@@ -1,291 +1,25 @@
#include "Core/EntityFile.h" #include "Core/EntityFile.h"
EntityFile::EntityFile(boost::filesystem::path path) EntityFile::EntityFile(std::string path)
: m_FilePath(path)
{ {
using namespace xercesc; EntityXMLFile* xml = ResourceManager::Load<EntityXMLFile>(path);
XMLPlatformUtils::Initialize();
m_GrammarPool = new XMLGrammarPoolImpl();
m_SAX2XMLReader = XMLReaderFactory::createXMLReader(XMLPlatformUtils::fgMemoryManager, m_GrammarPool);
}
EntityFile::~EntityFile() EntityXMLFilePreprocessor preprocessor(xml);
{ preprocessor.RegisterComponents(this);
delete m_SAX2XMLReader;
delete m_GrammarPool;
xercesc::XMLPlatformUtils::Terminate();
}
void EntityFile::Parse(const EntityFileHandler* handler) const EntityXMLFileParser parser(xml);
{ m_RootEntity = parser.MergeEntities(this);
using namespace xercesc;
EntityFileSAXHandler saxHandler(handler, m_SAX2XMLReader); if (m_RootEntity == EntityID_Invalid) {
setReaderFeatures(m_SAX2XMLReader); ResourceManager::Release("EntityXMLFile", path);
m_SAX2XMLReader->setContentHandler(&saxHandler); throw Resource::FailedLoadingException("Failed to merge entities; root entity is invalid");
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<std::string, unsigned int> 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<std::string, std::string>& attributes)
{
if (field.Type == "Vector") {
glm::vec3 vec;
vec.x = boost::lexical_cast<float>(attributes.at("X"));
vec.y = boost::lexical_cast<float>(attributes.at("Y"));
vec.z = boost::lexical_cast<float>(attributes.at("Z"));
memcpy(outData, reinterpret_cast<char*>(&vec), field.Stride);
} else if (field.Type == "Color") {
glm::vec4 vec;
vec.r = boost::lexical_cast<float>(attributes.at("R"));
vec.g = boost::lexical_cast<float>(attributes.at("G"));
vec.b = boost::lexical_cast<float>(attributes.at("B"));
vec.a = boost::lexical_cast<float>(attributes.at("A"));
memcpy(outData, reinterpret_cast<char*>(&vec), field.Stride);
} else if (field.Type == "Quaternion") {
glm::quat q;
q.x = boost::lexical_cast<float>(attributes.at("X"));
q.y = boost::lexical_cast<float>(attributes.at("Y"));
q.z = boost::lexical_cast<float>(attributes.at("Z"));
q.w = boost::lexical_cast<float>(attributes.at("W"));
memcpy(outData, reinterpret_cast<char*>(&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<int>(valueData);
memcpy(outData, reinterpret_cast<char*>(&value), field.Stride);
} else if (field.Type == "enum") {
ComponentInfo::EnumType value = boost::lexical_cast<ComponentInfo::EnumType>(valueData);
memcpy(outData, reinterpret_cast<char*>(&value), field.Stride);
} else if (field.Type == "float") {
float value = boost::lexical_cast<float>(valueData);
memcpy(outData, reinterpret_cast<char*>(&value), field.Stride);
} else if (field.Type == "double") {
double value = boost::lexical_cast<double>(valueData);
memcpy(outData, reinterpret_cast<char*>(&value), field.Stride);
} else if (field.Type == "bool") {
bool value = (valueData[0] == 't'); // Lazy bool evaluation
memcpy(outData, reinterpret_cast<char*>(&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); ResourceManager::Release("EntityXMLFile", path);
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) EntityWrapper EntityFile::MergeInto(World* other)
{ {
std::string name = XS::ToString(_localName); auto mapping = other->Merge(this);
if (m_StateStack.top() == State::Entity) { return EntityWrapper(other, mapping.at(m_RootEntity));
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);
}
-74
View File
@@ -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<std::string, std::string>& 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);
}
+291
View File
@@ -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<std::string, unsigned int> 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<std::string, std::string>& attributes)
{
if (field.Type == "Vector") {
glm::vec3 vec;
vec.x = boost::lexical_cast<float>(attributes.at("X"));
vec.y = boost::lexical_cast<float>(attributes.at("Y"));
vec.z = boost::lexical_cast<float>(attributes.at("Z"));
memcpy(outData, reinterpret_cast<char*>(&vec), field.Stride);
} else if (field.Type == "Color") {
glm::vec4 vec;
vec.r = boost::lexical_cast<float>(attributes.at("R"));
vec.g = boost::lexical_cast<float>(attributes.at("G"));
vec.b = boost::lexical_cast<float>(attributes.at("B"));
vec.a = boost::lexical_cast<float>(attributes.at("A"));
memcpy(outData, reinterpret_cast<char*>(&vec), field.Stride);
} else if (field.Type == "Quaternion") {
glm::quat q;
q.x = boost::lexical_cast<float>(attributes.at("X"));
q.y = boost::lexical_cast<float>(attributes.at("Y"));
q.z = boost::lexical_cast<float>(attributes.at("Z"));
q.w = boost::lexical_cast<float>(attributes.at("W"));
memcpy(outData, reinterpret_cast<char*>(&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<int>(valueData);
memcpy(outData, reinterpret_cast<char*>(&value), field.Stride);
} else if (field.Type == "enum") {
ComponentInfo::EnumType value = boost::lexical_cast<ComponentInfo::EnumType>(valueData);
memcpy(outData, reinterpret_cast<char*>(&value), field.Stride);
} else if (field.Type == "float") {
float value = boost::lexical_cast<float>(valueData);
memcpy(outData, reinterpret_cast<char*>(&value), field.Stride);
} else if (field.Type == "double") {
double value = boost::lexical_cast<double>(valueData);
memcpy(outData, reinterpret_cast<char*>(&value), field.Stride);
} else if (field.Type == "bool") {
bool value = (valueData[0] == 't'); // Lazy bool evaluation
memcpy(outData, reinterpret_cast<char*>(&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);
}
+84
View File
@@ -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<std::string, std::string>& 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);
}
@@ -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) : m_EntityFile(entityFile)
{ {
EntityFileHandler handler; 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); m_EntityFile->Parse(&handler);
//LOG_DEBUG("___ COMPONENT DEFINITIONS ___"); //LOG_DEBUG("___ COMPONENT DEFINITIONS ___");
@@ -28,20 +28,20 @@ EntityFilePreprocessor::EntityFilePreprocessor(const EntityFile* entityFile)
parseDefaults(); parseDefaults();
} }
void EntityFilePreprocessor::RegisterComponents(World* world) void EntityXMLFilePreprocessor::RegisterComponents(World* world)
{ {
for (auto& kv : m_ComponentInfo) { for (auto& kv : m_ComponentInfo) {
world->RegisterComponent(kv.second); 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()); //LOG_DEBUG("Component: %s", type.c_str());
m_ComponentCounts[type]++; m_ComponentCounts[type]++;
} }
void EntityFilePreprocessor::parseComponentInfo() void EntityXMLFilePreprocessor::parseComponentInfo()
{ {
using namespace xercesc; using namespace xercesc;
EntityFileXMLErrorHandler errorHandler; EntityFileXMLErrorHandler errorHandler;
@@ -141,9 +141,9 @@ void EntityFilePreprocessor::parseComponentInfo()
std::string baseType = XS::ToString(elementDeclaration->getTypeDefinition()->getBaseType()->getName()); std::string baseType = XS::ToString(elementDeclaration->getTypeDefinition()->getBaseType()->getName());
std::string effectiveType = type; std::string effectiveType = type;
unsigned int stride = EntityFile::GetTypeStride(type); unsigned int stride = EntityXMLFile::GetTypeStride(type);
if (stride == 0) { if (stride == 0) {
stride = EntityFile::GetTypeStride(baseType); stride = EntityXMLFile::GetTypeStride(baseType);
if (stride == 0) { 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()); 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; continue;
@@ -196,7 +196,7 @@ void EntityFilePreprocessor::parseComponentInfo()
} }
} }
void EntityFilePreprocessor::parseDefaults() void EntityXMLFilePreprocessor::parseDefaults()
{ {
using namespace xercesc; using namespace xercesc;
@@ -261,7 +261,7 @@ void EntityFilePreprocessor::parseDefaults()
auto attribItem = attributeMap->item(i); auto attribItem = attributeMap->item(i);
attributes[XS::ToString(attribItem->getNodeName())] = XS::ToString(attribItem->getNodeValue()); attributes[XS::ToString(attribItem->getNodeName())] = XS::ToString(attribItem->getNodeValue());
} }
EntityFile::WriteAttributeData(data, field, attributes); EntityXMLFile::WriteAttributeData(data, field, attributes);
} }
auto childNode = fieldElement->getFirstChild(); auto childNode = fieldElement->getFirstChild();
@@ -278,14 +278,14 @@ void EntityFilePreprocessor::parseDefaults()
// Handle potential field values // Handle potential field values
if (childNode->getNodeType() == DOMNode::TEXT_NODE) { if (childNode->getNodeType() == DOMNode::TEXT_NODE) {
char* cstrValue = XMLString::transcode(childNode->getNodeValue()); char* cstrValue = XMLString::transcode(childNode->getNodeValue());
EntityFile::WriteValueData(data, field, cstrValue); EntityXMLFile::WriteValueData(data, field, cstrValue);
XMLString::release(&cstrValue); XMLString::release(&cstrValue);
} }
} }
} }
} }
std::string EntityFilePreprocessor::parseAnnotationXML(const XMLCh* xml) std::string EntityXMLFilePreprocessor::parseAnnotationXML(const XMLCh* xml)
{ {
using namespace xercesc; using namespace xercesc;
@@ -1,13 +1,13 @@
#include "Core/EntityFileWriter.h" #include "Core/EntityXMLFileWriter.h"
#define X(str) XS::ToXMLCh(str) #define X(str) XS::ToXMLCh(str)
void EntityFileWriter::WriteWorld(World* world) void EntityXMLFileWriter::WriteWorld(World* world)
{ {
WriteEntity(world, 0); WriteEntity(world, 0);
} }
void EntityFileWriter::WriteEntity(World* world, EntityID entity) void EntityXMLFileWriter::WriteEntity(World* world, EntityID entity)
{ {
using namespace xercesc; using namespace xercesc;
DOMDocument* doc = m_DOMImplementation->createDocument(nullptr, X("Entity"), nullptr); DOMDocument* doc = m_DOMImplementation->createDocument(nullptr, X("Entity"), nullptr);
@@ -41,7 +41,7 @@ void EntityFileWriter::WriteEntity(World* world, EntityID entity)
doc->release(); 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; using namespace xercesc;
DOMDocument* doc = parentElement->getOwnerDocument(); 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; using namespace xercesc;
DOMDocument* doc = parentElement->getOwnerDocument(); DOMDocument* doc = parentElement->getOwnerDocument();
+2 -2
View File
@@ -33,8 +33,8 @@ void _LOG(_LOG_LEVEL logLevel, const char* file, const char* func, unsigned int
va_end(args); va_end(args);
if (logLevel == LOG_LEVEL_ERROR) { if (logLevel == LOG_LEVEL_ERROR) {
//std::cerr << file << ":" << line << " " << func << std::endl; std::cerr << file << ":" << line << " " << func << std::endl;
//std::cerr << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl; std::cerr << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl;
} else { } else {
std::cout << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl; std::cout << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl;
} }
+58 -1
View File
@@ -1,6 +1,7 @@
#include "Core/World.h" #include "Core/World.h"
#include "Core/EEntityDeleted.h" #include "Core/EEntityDeleted.h"
#include "Core/EComponentDeleted.h" #include "Core/EComponentDeleted.h"
#include "Core/EntityWrapper.h"
World::~World() World::~World()
{ {
@@ -44,7 +45,7 @@ bool World::ValidEntity(EntityID entity) const
return m_EntityParents.find(entity) != m_EntityParents.end(); 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()) { if (m_ComponentPools.find(ci.Name) == m_ComponentPools.end()) {
m_ComponentPools[ci.Name] = new ComponentPool(ci); 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<EntityID, EntityID> World::Merge(const World* other)
{
std::unordered_map<EntityID, EntityID> 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() EntityID World::generateEntityID()
{ {
// TODO: Make EntityID generation smarter // TODO: Make EntityID generation smarter
+5
View File
@@ -580,6 +580,11 @@ void EditorGUI::createWidgetToolButton(WidgetMode mode)
bool EditorGUI::OnKeyDown(const Events::KeyDown& e) 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 (e.ModCtrl && e.KeyCode == GLFW_KEY_S) {
if (m_CurrentSelection.Valid()) { if (m_CurrentSelection.Valid()) {
EntityWrapper baseParent = m_CurrentSelection; EntityWrapper baseParent = m_CurrentSelection;
+7 -7
View File
@@ -2,6 +2,7 @@
#include "Core/UniformScaleSystem.h" #include "Core/UniformScaleSystem.h"
#include "Editor/EditorRenderSystem.h" #include "Editor/EditorRenderSystem.h"
#include "Editor/EditorWidgetSystem.h" #include "Editor/EditorWidgetSystem.h"
#include "Core/EntityFile.h"
EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame* renderFrame) EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame* renderFrame)
: System(params) : System(params)
@@ -129,7 +130,7 @@ void EditorSystem::OnEntitySelected(EntityWrapper entity)
void EditorSystem::OnEntitySave(EntityWrapper entity, boost::filesystem::path filePath) void EditorSystem::OnEntitySave(EntityWrapper entity, boost::filesystem::path filePath)
{ {
EntityFileWriter writer(filePath); EntityXMLFileWriter writer(filePath);
writer.WriteEntity(entity.World, entity.ID); writer.WriteEntity(entity.World, entity.ID);
} }
@@ -260,12 +261,11 @@ EntityWrapper EditorSystem::importEntity(EntityWrapper parent, boost::filesystem
try { try {
auto entityFile = ResourceManager::Load<EntityFile>(filePath.string()); auto entityFile = ResourceManager::Load<EntityFile>(filePath.string());
EntityFilePreprocessor fpp(entityFile); EntityWrapper newEntity = entityFile->MergeInto(parent.World);
fpp.RegisterComponents(parent.World); parent.World->SetParent(newEntity.ID, parent.ID);
EntityFileParser fp(entityFile); return newEntity;
EntityID newEntity = fp.MergeEntities(parent.World, parent.ID); } catch (const std::exception& e) {
return EntityWrapper(parent.World, newEntity); LOG_ERROR("Failed to import entity \"%s\": \"%s\"", filePath.string().c_str(), e.what());
} catch (const std::exception&) {
return EntityWrapper::Invalid; return EntityWrapper::Invalid;
} }
} }
+44 -5
View File
@@ -33,6 +33,7 @@ void Client::Connect(std::string address, int port)
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Client::OnPlayerDamage); EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Client::OnPlayerDamage);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Client::OnPlayerSpawned); EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Client::OnPlayerSpawned);
EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &Client::OnDoubleJump); EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &Client::OnDoubleJump);
EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &Client::OnDashAbility);
EVENT_SUBSCRIBE_MEMBER(m_ESearchForServers, &Client::OnSearchForServers); EVENT_SUBSCRIBE_MEMBER(m_ESearchForServers, &Client::OnSearchForServers);
auto config = ResourceManager::Load<ConfigFile>("Config.ini"); auto config = ResourceManager::Load<ConfigFile>("Config.ini");
m_Address = address; m_Address = address;
@@ -101,8 +102,7 @@ void Client::Update()
void Client::parseMessageType(Packet& packet) void Client::parseMessageType(Packet& packet)
{ {
// Pop packetSize which is used by TCP Client to // Pop packetSize
// create a packet of the correct size
packet.ReadPrimitive<int>(); packet.ReadPrimitive<int>();
int messageType = packet.ReadPrimitive<int>(); int messageType = packet.ReadPrimitive<int>();
if (messageType == -1) if (messageType == -1)
@@ -144,6 +144,12 @@ void Client::parseMessageType(Packet& packet)
case MessageType::OnDoubleJump: case MessageType::OnDoubleJump:
parseDoubleJump(packet); parseDoubleJump(packet);
break; break;
case MessageType::OnDashEffect:
parseDashEffect(packet);
break;
case MessageType::AmmoPickup:
parseAmmoPickup(packet);
break;
default: default:
break; break;
} }
@@ -233,7 +239,6 @@ void Client::parseSpawnEvents()
m_EventBroker->Publish(e); m_EventBroker->Publish(e);
} }
m_PlayerSpawnEvents = tempSpawn; m_PlayerSpawnEvents = tempSpawn;
// m_PlayerSpawnEvents.clear();
} }
void Client::parsePlayersSpawned(Packet& packet) void Client::parsePlayersSpawned(Packet& packet)
@@ -261,7 +266,7 @@ void Client::parseEntityDeletion(Packet & packet)
if (m_ServerIDToClientID.find(entityToDelete) != m_ServerIDToClientID.end()) { if (m_ServerIDToClientID.find(entityToDelete) != m_ServerIDToClientID.end()) {
EntityID localEntity = m_ServerIDToClientID.at(entityToDelete); EntityID localEntity = m_ServerIDToClientID.at(entityToDelete);
if (m_World->ValidEntity(localEntity)) { if (m_World->ValidEntity(localEntity)) {
if (m_World->HasComponent(localEntity,"Player")) { if (m_World->HasComponent(localEntity, "Player")) {
Events::PlayerDeath e; Events::PlayerDeath e;
e.Player = EntityWrapper(m_World, localEntity); e.Player = EntityWrapper(m_World, localEntity);
m_EventBroker->Publish(e); m_EventBroker->Publish(e);
@@ -296,6 +301,28 @@ void Client::parseDoubleJump(Packet & packet)
} }
} }
void Client::parseDashEffect(Packet& packet)
{
EntityID serverID = packet.ReadPrimitive<EntityID>();
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<int>();
e.Player = m_LocalPlayer;
m_EventBroker->Publish(e);
}
void Client::updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID) void Client::updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID)
{ {
for (auto field : componentInfo.FieldsInOrder) { for (auto field : componentInfo.FieldsInOrder) {
@@ -379,7 +406,7 @@ void Client::parseSnapshot(Packet& packet)
if (m_SnapshotFilter != nullptr) { if (m_SnapshotFilter != nullptr) {
shouldApply = m_SnapshotFilter->FilterComponent(localEntity, newComponent); shouldApply = m_SnapshotFilter->FilterComponent(localEntity, newComponent);
} }
if (shouldApply) { if (shouldApply) {
ComponentWrapper currentComponent = m_World->GetComponent(localEntityID, componentType); ComponentWrapper currentComponent = m_World->GetComponent(localEntityID, componentType);
memcpy(currentComponent.Data, newComponent.Data, componentInfo.Stride); memcpy(currentComponent.Data, newComponent.Data, componentInfo.Stride);
} }
@@ -509,6 +536,18 @@ bool Client::OnPlayerSpawned(const Events::PlayerSpawned& e)
return true; 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) bool Client::OnSearchForServers(const Events::SearchForServers& e)
{ {
m_SearchingForServers = true; m_SearchingForServers = true;
+26 -3
View File
@@ -13,7 +13,7 @@ Server::Server(World* world, EventBroker* eventBroker, int port)
EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &Server::OnEntityDeleted); EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &Server::OnEntityDeleted);
EVENT_SUBSCRIBE_MEMBER(m_EComponentDeleted, &Server::OnComponentDeleted); EVENT_SUBSCRIBE_MEMBER(m_EComponentDeleted, &Server::OnComponentDeleted);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Server::OnPlayerDamage); EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Server::OnPlayerDamage);
EVENT_SUBSCRIBE_MEMBER(m_EAmmoPickup, &Server::OnAmmoPickup);
// BindWW // BindWW
if (port == 0) { if (port == 0) {
port = config->Get<float>("Networking.Port", 27666); port = config->Get<float>("Networking.Port", 27666);
@@ -141,6 +141,9 @@ void Server::parseMessageType(Packet& packet)
case MessageType::OnDoubleJump: case MessageType::OnDoubleJump:
parseDoubleJump(packet); parseDoubleJump(packet);
break; break;
case MessageType::OnDashEffect:
parseDashEffect(packet);
break;
default: default:
break; break;
} }
@@ -510,6 +513,19 @@ bool Server::OnPlayerDamage(const Events::PlayerDamage& e)
return true; 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() void Server::parseClientPing()
{ {
LOG_INFO("%i: Parsing ping", m_PacketID); LOG_INFO("%i: Parsing ping", m_PacketID);
@@ -542,6 +558,11 @@ bool Server::parseDoubleJump(Packet & packet)
return true; return true;
} }
void Server::parseDashEffect(Packet& packet)
{
reliableBroadcast(packet);
}
void Server::parseOnInputCommand(Packet& packet) void Server::parseOnInputCommand(Packet& packet)
{ {
PlayerID player = -1; PlayerID player = -1;
@@ -604,12 +625,14 @@ bool Server::shouldSendToClient(EntityWrapper childEntity)
auto children = m_World->GetDirectChildren(childEntity.ID); auto children = m_World->GetDirectChildren(childEntity.ID);
for (auto it = children.first; it != children.second; it++) { for (auto it = children.first; it != children.second; it++) {
EntityWrapper child(m_World, it->second); EntityWrapper child(m_World, it->second);
if(child.HasComponent("CapturePoint")) { if (child.HasComponent("CapturePoint") || child.HasComponent("HealthPickup")
|| child.HasComponent("AmmoPickup")) {
return true; return true;
} }
} }
return childEntity.HasComponent("Player") || childEntity.FirstParentWithComponent("Player").Valid() return childEntity.HasComponent("Player") || childEntity.FirstParentWithComponent("Player").Valid()
|| childEntity.HasComponent("CapturePoint"); || childEntity.HasComponent("CapturePoint") || childEntity.HasComponent("HealthPickup")
|| childEntity.HasComponent("AmmoPickup");
} }
PlayerID Server::GetPlayerIDFromEndpoint() PlayerID Server::GetPlayerIDFromEndpoint()
+1 -1
View File
@@ -70,7 +70,7 @@ void FrameBuffer::Generate()
} }
GLERROR("3"); GLERROR("3");
GLenum* bufferTextures = &attachments[0]; GLenum* bufferTextures = attachments.data();
glDrawBuffers(attachments.size(), bufferTextures); glDrawBuffers(attachments.size(), bufferTextures);
if (GLERROR("GLBufferAttachement error")) { if (GLERROR("GLBufferAttachement error")) {
printf(": AttachmentSize %i", attachments.size()); printf(": AttachmentSize %i", attachments.size());
+22 -5
View File
@@ -10,7 +10,9 @@
#include "Systems/SpawnerSystem.h" #include "Systems/SpawnerSystem.h"
#include "Systems/PlayerSpawnSystem.h" #include "Systems/PlayerSpawnSystem.h"
#include "Systems/PlayerDeathSystem.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/CapturePointSystem.h"
#include "Game/Systems/CapturePointHUDSystem.h" #include "Game/Systems/CapturePointHUDSystem.h"
#include "Game/Systems/PickupSpawnSystem.h" #include "Game/Systems/PickupSpawnSystem.h"
@@ -25,7 +27,11 @@
#include "Rendering/AnimationSystem.h" #include "Rendering/AnimationSystem.h"
#include "Network/MultiplayerSnapshotFilter.h" #include "Network/MultiplayerSnapshotFilter.h"
#include "Game/Systems/AmmunitionHUDSystem.h" #include "Game/Systems/AmmunitionHUDSystem.h"
#include "Game/Systems/AbilityCooldownHUDSystem.h"
#include "Game/Systems/CapturePointArrowHUDSystem.h"
#include "Game/Systems/KillFeedSystem.h" #include "Game/Systems/KillFeedSystem.h"
#include "Game/Systems/BoostSystem.h"
#include "Game/Systems/BoostIconsHUDSystem.h"
#include "GUI/ButtonSystem.h" #include "GUI/ButtonSystem.h"
#include "GUI/MainMenuSystem.h" #include "GUI/MainMenuSystem.h"
@@ -42,6 +48,7 @@ Game::Game(int argc, char* argv[])
ResourceManager::RegisterType<PNG>("Png"); ResourceManager::RegisterType<PNG>("Png");
ResourceManager::RegisterType<ShaderProgram>("ShaderProgram"); ResourceManager::RegisterType<ShaderProgram>("ShaderProgram");
ResourceManager::RegisterType<EntityFile>("EntityFile"); ResourceManager::RegisterType<EntityFile>("EntityFile");
ResourceManager::RegisterType<EntityXMLFile>("EntityXMLFile");
ResourceManager::RegisterType<Font>("FontFile"); ResourceManager::RegisterType<Font>("FontFile");
m_Config = ResourceManager::Load<ConfigFile>("Config.ini"); m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
@@ -78,10 +85,7 @@ Game::Game(int argc, char* argv[])
std::string mapToLoad = m_Config->Get<std::string>("Debug.LoadMap", ""); std::string mapToLoad = m_Config->Get<std::string>("Debug.LoadMap", "");
if (!mapToLoad.empty()) { if (!mapToLoad.empty()) {
auto file = ResourceManager::Load<EntityFile>(mapToLoad); auto file = ResourceManager::Load<EntityFile>(mapToLoad);
EntityFilePreprocessor fpp(file); file->MergeInto(m_World);
fpp.RegisterComponents(m_World);
EntityFileParser fp(file);
fp.MergeEntities(m_World);
} }
// Create the sound manager // Create the sound manager
@@ -118,6 +122,7 @@ Game::Game(int argc, char* argv[])
++updateOrderLevel; ++updateOrderLevel;
m_SystemPipeline->AddSystem<SoundSystem>(updateOrderLevel); m_SystemPipeline->AddSystem<SoundSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<RaptorCopterSystem>(updateOrderLevel); m_SystemPipeline->AddSystem<RaptorCopterSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<FloatingEffectSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<ExplosionEffectSystem>(updateOrderLevel); m_SystemPipeline->AddSystem<ExplosionEffectSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<HealthSystem>(updateOrderLevel); m_SystemPipeline->AddSystem<HealthSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<PlayerMovementSystem>(updateOrderLevel); m_SystemPipeline->AddSystem<PlayerMovementSystem>(updateOrderLevel);
@@ -131,9 +136,21 @@ Game::Game(int argc, char* argv[])
m_SystemPipeline->AddSystem<AmmoPickupSystem>(updateOrderLevel); m_SystemPipeline->AddSystem<AmmoPickupSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<DamageIndicatorSystem>(updateOrderLevel); m_SystemPipeline->AddSystem<DamageIndicatorSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<AmmunitionHUDSystem>(updateOrderLevel); m_SystemPipeline->AddSystem<AmmunitionHUDSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<AbilityCooldownHUDSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<CapturePointArrowHUDSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<KillFeedSystem>(updateOrderLevel); m_SystemPipeline->AddSystem<KillFeedSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<LifetimeSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<CapturePointSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<CapturePointHUDSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<PickupSpawnSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<AmmoPickupSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<DamageIndicatorSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<AmmunitionHUDSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<KillFeedSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<BoostSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<ButtonSystem>(updateOrderLevel, m_Renderer); m_SystemPipeline->AddSystem<ButtonSystem>(updateOrderLevel, m_Renderer);
m_SystemPipeline->AddSystem<MainMenuSystem>(updateOrderLevel, m_Renderer); m_SystemPipeline->AddSystem<MainMenuSystem>(updateOrderLevel, m_Renderer);
m_SystemPipeline->AddSystem<BoostIconsHUDSystem>(updateOrderLevel);
// Populate Octree with collidables // Populate Octree with collidables
++updateOrderLevel; ++updateOrderLevel;
m_SystemPipeline->AddSystem<FillOctreeSystem>(updateOrderLevel, m_OctreeCollision, "Collidable"); m_SystemPipeline->AddSystem<FillOctreeSystem>(updateOrderLevel, m_OctreeCollision, "Collidable");
@@ -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.
}
}
}
}
}
+93 -36
View File
@@ -3,45 +3,63 @@
AmmoPickupSystem::AmmoPickupSystem(SystemParams params) AmmoPickupSystem::AmmoPickupSystem(SystemParams params)
: System(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) void AmmoPickupSystem::Update(double dt)
{ {
for (auto it = m_ETriggerTouchVector.begin(); it != m_ETriggerTouchVector.end(); ++it) if (IsServer) {
{ auto it = m_ETriggerTouchVector.begin();
auto& ammoPickupPosition = *it; while (it != m_ETriggerTouchVector.end()) {
//set the double timer value (value 3) auto& somePickup = *it;
ammoPickupPosition.DecreaseThisRespawnTimer -= dt; somePickup.DecreaseThisRespawnTimer -= dt;
if (ammoPickupPosition.DecreaseThisRespawnTimer < 0.0) { if (somePickup.DecreaseThisRespawnTimer < 0.0) {
//spawn and delete the vector item auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/AmmoPickup.xml");
auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/AmmoPickup.xml"); EntityWrapper ammoPickup = entityFile->MergeInto(m_World);
EntityFileParser parser(entityFile);
EntityID ammoPickupID = parser.MergeEntities(m_World);
//let the world know a pickup has spawned (graphics effects, etc) //let the world know a pickup has spawned
Events::PickupSpawned ePickupSpawned; Events::PickupSpawned ePickupSpawned;
ePickupSpawned.Pickup = EntityWrapper(m_World, ammoPickupID); ePickupSpawned.Pickup = ammoPickup;
m_EventBroker->Publish(ePickupSpawned); m_EventBroker->Publish(ePickupSpawned);
//set values from the old entity to the new entity //copy values from the old entity to the new entity
auto& newAmmoPickupEntity = EntityWrapper(m_World, ammoPickupID); auto& newAmmoPickupEntity = ammoPickup;
newAmmoPickupEntity["Transform"]["Position"] = ammoPickupPosition.Pos; newAmmoPickupEntity["Transform"]["Position"] = somePickup.Pos;
newAmmoPickupEntity["AmmoPickup"]["AmmoGain"] = ammoPickupPosition.AmmoGain; newAmmoPickupEntity["AmmoPickup"]["AmmoGain"] = somePickup.AmmoGain;
newAmmoPickupEntity["AmmoPickup"]["RespawnTimer"] = ammoPickupPosition.RespawnTimer; newAmmoPickupEntity["AmmoPickup"]["RespawnTimer"] = somePickup.RespawnTimer;
m_World->SetParent(newAmmoPickupEntity.ID, ammoPickupPosition.parentID); m_World->SetParent(newAmmoPickupEntity.ID, somePickup.parentID);
//erase the current element (AmmoPickupPosition) //erase the current element (somePickup)
m_ETriggerTouchVector.erase(it); it = m_ETriggerTouchVector.erase(it);
break; }
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) bool AmmoPickupSystem::OnTriggerTouch(Events::TriggerTouch& e)
{ {
if (e.Entity != LocalPlayer) { if (!e.Entity.Valid()) {
return false; return false;
} }
//TODO: add other weapontypes //TODO: add other weapontypes
@@ -51,29 +69,68 @@ bool AmmoPickupSystem::OnTriggerTouch(Events::TriggerTouch& e)
if (!e.Trigger.HasComponent("AmmoPickup")) { if (!e.Trigger.HasComponent("AmmoPickup")) {
return false; 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 //cant pick up ammopacks if you are already at MaxAmmo
if (currentAmmo >= maxWeaponAmmo) { if (currentAmmo >= maxWeaponAmmo) {
return false; 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; Events::AmmoPickup ePlayerAmmoPickup;
ePlayerAmmoPickup.AmmoGain = ammoGiven; ePlayerAmmoPickup.AmmoGain = ammoGiven;
ePlayerAmmoPickup.Player = e.Entity; ePlayerAmmoPickup.Player = player;
m_EventBroker->Publish(ePlayerAmmoPickup); m_EventBroker->Publish(ePlayerAmmoPickup);
//immediately give the player the ammo
//immediately give the player the ammo (on server)
currentAmmo = std::min(currentAmmo + ammoGiven, maxWeaponAmmo); 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) //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 //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"], m_ETriggerTouchVector.push_back({ (glm::vec3)trigger["Transform"]["Position"], trigger["AmmoPickup"]["AmmoGain"],
e.Trigger["AmmoPickup"]["RespawnTimer"], e.Trigger["AmmoPickup"]["RespawnTimer"], m_World->GetParent(e.Trigger.ID) }); trigger["AmmoPickup"]["RespawnTimer"], trigger["AmmoPickup"]["RespawnTimer"], m_World->GetParent(trigger.ID) });
//delete the ammopickup //delete the ammopickup
m_World->DeleteEntity(e.Trigger.ID); m_World->DeleteEntity(trigger.ID);
return true;
} }
+42
View File
@@ -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;
}
}
}
}
+62
View File
@@ -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<EntityFile>(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 "";
}
@@ -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<int, glm::vec3> 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<int, glm::vec3>(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<int, glm::vec3>(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<int, glm::vec3>::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;
}
+11 -6
View File
@@ -6,7 +6,7 @@ CapturePointSystem::CapturePointSystem(SystemParams params)
, PureSystem("CapturePoint") , PureSystem("CapturePoint")
{ {
//subscribe/listenTo playerdamage,healthpickup events (using the eventBroker) //subscribe/listenTo playerdamage,healthpickup events (using the eventBroker)
if (!IsClient) { if (IsServer) {
EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &CapturePointSystem::OnTriggerTouch); EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &CapturePointSystem::OnTriggerTouch);
EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &CapturePointSystem::OnTriggerLeave); EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &CapturePointSystem::OnTriggerLeave);
EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &CapturePointSystem::OnCaptured); 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 //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) void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, ComponentWrapper& cCapturePoint, double dt)
{ {
if (IsClient) { if (!IsServer) {
return; return;
} }
if (m_WinnerWasFound) { if (m_WinnerWasFound) {
@@ -102,6 +102,12 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp
nextPossibleCapturePoint["Blue"] = i - 1; 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 //reset timers and reset the bool that triggers this
if (m_ResetTimers) { if (m_ResetTimers) {
@@ -188,10 +194,9 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp
teamComponent["Team"] = currentTeam; teamComponent["Team"] = currentTeam;
cCapturePoint["CaptureTimer"] = glm::sign((double)cCapturePoint["CaptureTimer"])*captureTimeToTakeOver; cCapturePoint["CaptureTimer"] = glm::sign((double)cCapturePoint["CaptureTimer"])*captureTimeToTakeOver;
//publish Captured event //publish Captured event
Events::Captured e; m_RecentlyCapturedNeedNextCapturePointNow = true;
e.CapturePointID = cCapturePoint.EntityID; m_CapturedEvent.CapturePointTakenID = cCapturePoint.EntityID;
e.TeamNumberThatCapturedCapturePoint = currentTeam; m_CapturedEvent.TeamNumberThatCapturedCapturePoint = currentTeam;
m_EventBroker->Publish(e);
//NextPossibleCapturePoint will be calculated in the next update... //NextPossibleCapturePoint will be calculated in the next update...
} }
} }
+7 -9
View File
@@ -9,7 +9,7 @@ DamageIndicatorSystem::DamageIndicatorSystem(SystemParams params)
//load texture to cache //load texture to cache
auto texture = CommonFunctions::LoadTexture("Textures/DamageIndicator.png", false); auto texture = CommonFunctions::LoadTexture("Textures/DamageIndicator.png", false);
auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/DamageIndicator.xml"); auto entityFile = ResourceManager::Load<EntityXMLFile>("Schema/Entities/DamageIndicator.xml");
} }
void DamageIndicatorSystem::Update(double dt) { void DamageIndicatorSystem::Update(double dt) {
@@ -50,15 +50,13 @@ bool DamageIndicatorSystem::OnPlayerDamage(Events::PlayerDamage& e)
//load & set the "2d" sprite //load & set the "2d" sprite
auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/DamageIndicator.xml"); auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/DamageIndicator.xml");
EntityFileParser parser(entityFile); EntityWrapper sprite = entityFile->MergeInto(m_World);
EntityID spriteID = parser.MergeEntities(m_World); m_World->SetParent(sprite.ID, m_CurrentCamera);
m_World->SetParent(spriteID, m_CurrentCamera);
auto spriteWrapper = EntityWrapper(m_World, spriteID);
//simply set the rotation z-wise to the angleBetweenVectors //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) { if (!IsServer) {
updateDamageIndicatorVector.emplace_back(spriteWrapper, inflictorPos); updateDamageIndicatorVector.emplace_back(sprite, inflictorPos);
} }
return true; 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); auto inflictorPos = glm::vec3(currentPos.x + testVar*6.0f, currentPos.y, currentPos.z + testVar2*6.0f);
//load the explosioneffect XML //load the explosioneffect XML
auto deathEffect = ResourceManager::Load<EntityFile>("Schema/Entities/PlayerDeathExplosionWithCamera.xml"); auto deathEffect = ResourceManager::Load<EntityXMLFile>("Schema/Entities/PlayerDeathExplosionWithCamera.xml");
EntityFileParser parser(deathEffect); EntityXMLFileParser parser(deathEffect);
EntityID deathEffectID = parser.MergeEntities(m_World); EntityID deathEffectID = parser.MergeEntities(m_World);
EntityWrapper deathEffectEW = EntityWrapper(m_World, deathEffectID); EntityWrapper deathEffectEW = EntityWrapper(m_World, deathEffectID);
+5
View File
@@ -30,6 +30,11 @@ bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e)
ComponentWrapper cHealth = e.Victim["Health"]; ComponentWrapper cHealth = e.Victim["Health"];
double& health = cHealth["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; health -= e.Damage;
return true; return true;
+68 -34
View File
@@ -3,65 +3,99 @@
PickupSpawnSystem::PickupSpawnSystem(SystemParams params) PickupSpawnSystem::PickupSpawnSystem(SystemParams params)
: System(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) void PickupSpawnSystem::Update(double dt)
{ {
for (auto it = m_ETriggerTouchVector.begin(); it != m_ETriggerTouchVector.end(); ++it) if (IsServer) {
{ auto it = m_ETriggerTouchVector.begin();
auto& healthPickupPosition = *it; while (it != m_ETriggerTouchVector.end()) {
//set the double timer value (value 3) auto& somePickup = *it;
healthPickupPosition.DecreaseThisRespawnTimer -= dt; somePickup.DecreaseThisRespawnTimer -= dt;
if (healthPickupPosition.DecreaseThisRespawnTimer < 0) { if (somePickup.DecreaseThisRespawnTimer < 0.0) {
//spawn and delete the vector item //spawn the new healthPickup
auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/HealthPickup.xml"); auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/HealthPickup.xml");
EntityFileParser parser(entityFile); EntityWrapper healthPickup = entityFile->MergeInto(m_World);
EntityID healthPickupID = parser.MergeEntities(m_World);
//let the world know a pickup has spawned (graphics effects, etc) //let the world know a pickup has spawned (graphics effects, etc)
Events::PickupSpawned ePickupSpawned; Events::PickupSpawned ePickupSpawned;
ePickupSpawned.Pickup = EntityWrapper(m_World, healthPickupID); ePickupSpawned.Pickup = healthPickup;
m_EventBroker->Publish(ePickupSpawned); m_EventBroker->Publish(ePickupSpawned);
//set values from the old entity to the new entity //copy values from the old entity to the new entity
auto& newHealthPickupEntity = EntityWrapper(m_World, healthPickupID); auto& newHealthPickupEntity = healthPickup;
newHealthPickupEntity["Transform"]["Position"] = healthPickupPosition.Pos; newHealthPickupEntity["Transform"]["Position"] = somePickup.Pos;
newHealthPickupEntity["HealthPickup"]["HealthGain"] = healthPickupPosition.HealthGain; newHealthPickupEntity["HealthPickup"]["HealthGain"] = somePickup.HealthGain;
newHealthPickupEntity["HealthPickup"]["RespawnTimer"] = healthPickupPosition.RespawnTimer; newHealthPickupEntity["HealthPickup"]["RespawnTimer"] = somePickup.RespawnTimer;
m_World->SetParent(newHealthPickupEntity.ID, healthPickupPosition.parentID); m_World->SetParent(newHealthPickupEntity.ID, somePickup.parentID);
//erase the current element (healthPickupPosition) //erase the current element (somePickup)
m_ETriggerTouchVector.erase(it); it = m_ETriggerTouchVector.erase(it);
break; } 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) bool PickupSpawnSystem::OnTriggerTouch(Events::TriggerTouch& e)
{ {
if (!e.Trigger.HasComponent("HealthPickup")) { if (!e.Trigger.HasComponent("HealthPickup")) {
return false; return false;
} }
double healthGiven = 0.01*(double)e.Trigger["HealthPickup"]["HealthGain"] * (double)e.Entity["Health"]["MaxHealth"]; //if at maxhealth, save the trigger-touch to a vector since standing inside it will not re-trigger the trigger
//cant pick up healthpacks if you are already at MaxHealth
if ((double)e.Entity["Health"]["Health"] >= (double)e.Entity["Health"]["MaxHealth"]) { if ((double)e.Entity["Health"]["Health"] >= (double)e.Entity["Health"]["MaxHealth"]) {
m_PickupAtMaximum.push_back({ e.Entity, e.Trigger });
return false; 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; Events::PlayerHealthPickup ePlayerHealthPickup;
ePlayerHealthPickup.HealthAmount = healthGiven; ePlayerHealthPickup.HealthAmount = healthGiven;
ePlayerHealthPickup.Player = e.Entity; ePlayerHealthPickup.Player = player;
m_EventBroker->Publish(ePlayerHealthPickup); 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) //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 //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"], m_ETriggerTouchVector.push_back({ (glm::vec3)trigger["Transform"]["Position"], trigger["HealthPickup"]["HealthGain"],
e.Trigger["HealthPickup"]["RespawnTimer"],e.Trigger["HealthPickup"]["RespawnTimer"], m_World->GetParent(e.Trigger.ID) }); trigger["HealthPickup"]["RespawnTimer"], trigger["HealthPickup"]["RespawnTimer"], m_World->GetParent(trigger.ID) });
//delete the healthpickup //delete the healthpickup
m_World->DeleteEntity(e.Trigger.ID); m_World->DeleteEntity(trigger.ID);
return true;
} }
+22 -4
View File
@@ -4,6 +4,7 @@ PlayerDeathSystem::PlayerDeathSystem(SystemParams params)
: System(params) : System(params)
{ {
EVENT_SUBSCRIBE_MEMBER(m_OnPlayerDeath, &PlayerDeathSystem::OnPlayerDeath); EVENT_SUBSCRIBE_MEMBER(m_OnPlayerDeath, &PlayerDeathSystem::OnPlayerDeath);
EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &PlayerDeathSystem::OnEntityDeleted);
} }
void PlayerDeathSystem::Update(double dt) void PlayerDeathSystem::Update(double dt)
@@ -27,10 +28,8 @@ bool PlayerDeathSystem::OnPlayerDeath(Events::PlayerDeath& e)
void PlayerDeathSystem::createDeathEffect(EntityWrapper player) void PlayerDeathSystem::createDeathEffect(EntityWrapper player)
{ {
//load the explosioneffect XML //load the explosioneffect XML
auto deathEffect = ResourceManager::Load<EntityFile>("Schema/Entities/PlayerDeathExplosionWithCamera.xml"); auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/PlayerDeathExplosionWithCamera.xml");
EntityFileParser parser(deathEffect); EntityWrapper deathEffectEW = entityFile->MergeInto(m_World);
EntityID deathEffectID = parser.MergeEntities(m_World);
EntityWrapper deathEffectEW = EntityWrapper(m_World, deathEffectID);
//components that we need from player //components that we need from player
auto playerModel = player.FirstChildByName("PlayerModel"); auto playerModel = player.FirstChildByName("PlayerModel");
@@ -59,9 +58,28 @@ void PlayerDeathSystem::createDeathEffect(EntityWrapper player)
//camera (with lifetime) behind the player //camera (with lifetime) behind the player
if (player == LocalPlayer) { if (player == LocalPlayer) {
m_LocalPlayerDeathEffect = deathEffectEW;
auto cam = deathEffectEW.FirstChildByName("Camera"); auto cam = deathEffectEW.FirstChildByName("Camera");
Events::SetCamera eSetCamera; Events::SetCamera eSetCamera;
eSetCamera.CameraEntity = cam; eSetCamera.CameraEntity = cam;
m_EventBroker->Publish(eSetCamera); 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;
}
+44 -10
View File
@@ -5,6 +5,7 @@ PlayerMovementSystem::PlayerMovementSystem(SystemParams params)
{ {
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &PlayerMovementSystem::OnPlayerSpawned); EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &PlayerMovementSystem::OnPlayerSpawned);
EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &PlayerMovementSystem::OnDoubleJump); EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &PlayerMovementSystem::OnDoubleJump);
EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &PlayerMovementSystem::OnDashAbility);
} }
PlayerMovementSystem::~PlayerMovementSystem() PlayerMovementSystem::~PlayerMovementSystem()
@@ -48,7 +49,7 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
EntityWrapper playerModel = player.FirstChildByName("PlayerModel"); EntityWrapper playerModel = player.FirstChildByName("PlayerModel");
if (playerModel.Valid()) { if (playerModel.Valid()) {
ComponentWrapper cAnimationOffset = playerModel["AnimationOffset"]; ComponentWrapper cAnimationOffset = playerModel["AnimationOffset"];
float pitch = cameraOrientation.x + 0.2; float pitch = cameraOrientation.x + 0.2f;
double time = (pitch + glm::half_pi<float>()) / glm::pi<float>(); double time = (pitch + glm::half_pi<float>()) / glm::pi<float>();
cAnimationOffset["Time"] = time; cAnimationOffset["Time"] = time;
} }
@@ -61,12 +62,18 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
float playerMovementSpeed = player["Player"]["MovementSpeed"]; float playerMovementSpeed = player["Player"]["MovementSpeed"];
float playerCrouchSpeed = player["Player"]["CrouchSpeed"]; float playerCrouchSpeed = player["Player"]["CrouchSpeed"];
glm::vec3& wishDirection = player["Player"]["CurrentWishDirection"]; 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")) { if (player.HasComponent("Physics")) {
ComponentWrapper cPhysics = player["Physics"]; ComponentWrapper cPhysics = player["Physics"];
//Assault Dash Check //Assault Dash Check
if (player.HasComponent("DashAbility")) { 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)); wishDirection = controller->Movement() * glm::inverse(glm::quat(ori));
//this makes sure you can only dash in the 4 directions: forw,backw,left,right //this makes sure you can only dash in the 4 directions: forw,backw,left,right
@@ -112,6 +119,10 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
//if doubleTapped do Assault Dash - but only boost maximum 50.0f //if doubleTapped do Assault Dash - but only boost maximum 50.0f
float doubleTapDashBoost = controller->AssaultDashDoubleTapped() ? 40.0f : 1.0f; float doubleTapDashBoost = controller->AssaultDashDoubleTapped() ? 40.0f : 1.0f;
accelerationSpeed = glm::min(doubleTapDashBoost*glm::min(accelerationSpeed, addSpeed), 50.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; velocity += accelerationSpeed * wishDirection;
ImGui::Text("velocity: (%f, %f, %f) |%f|", velocity.x, velocity.y, velocity.z, glm::length(velocity)); ImGui::Text("velocity: (%f, %f, %f) |%f|", velocity.x, velocity.y, velocity.z, glm::length(velocity));
} }
@@ -303,22 +314,45 @@ bool PlayerMovementSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
bool PlayerMovementSystem::OnDoubleJump(Events::DoubleJump & e) bool PlayerMovementSystem::OnDoubleJump(Events::DoubleJump & e)
{ {
// If entity does not exist, exit // If entity does not exist, exit
if (!EntityWrapper(m_World, e.entityID).Valid()) { if (!EntityWrapper(m_World, e.entityID).Valid()) {
return false; return false;
} }
// If entity IsLocalPlayer, exit // If entity IsLocalPlayer, exit
if (e.entityID == m_LocalPlayer.ID) { if (e.entityID == m_LocalPlayer.ID) {
return false; return false;
} }
spawnHexagon(EntityWrapper(m_World, e.entityID)); spawnHexagon(EntityWrapper(m_World, e.entityID));
return true;
} }
void PlayerMovementSystem::spawnHexagon(EntityWrapper target) void PlayerMovementSystem::spawnHexagon(EntityWrapper target)
{ {
//put a hexagon at the entitys... feet? //put a hexagon at the entitys... feet?
auto hexagonEffect = ResourceManager::Load<EntityFile>("Schema/Entities/DoubleJumpHexagon.xml"); auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/DoubleJumpHexagon.xml");
EntityFileParser parser(hexagonEffect); EntityWrapper hexagonEW = entityFile->MergeInto(m_World);
EntityID hexagonEffectID = parser.MergeEntities(m_World);
EntityWrapper hexagonEW = EntityWrapper(m_World, hexagonEffectID);
hexagonEW["Transform"]["Position"] = (glm::vec3)target["Transform"]["Position"]; hexagonEW["Transform"]["Position"] = (glm::vec3)target["Transform"]["Position"];
} }
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<EntityFile>("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;
}
+46 -20
View File
@@ -10,7 +10,7 @@ PlayerSpawnSystem::PlayerSpawnSystem(SystemParams params)
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini"); ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
m_NetworkEnabled = config->Get("Networking.StartNetwork", false); m_NetworkEnabled = config->Get("Networking.StartNetwork", false);
m_ForcedRespawnTime = config->Get("Debug.RespawnTime", -1.0f); m_ForcedRespawnTime = config->Get("Debug.RespawnTime", -1.0f);
m_DbgConfigForceRespawn = m_ForcedRespawnTime > 0; m_DbgConfigForceRespawn = m_ForcedRespawnTime > 0 && IsServer;
} }
void PlayerSpawnSystem::Update(double dt) void PlayerSpawnSystem::Update(double dt)
@@ -26,7 +26,21 @@ void PlayerSpawnSystem::Update(double dt)
// Increase timer. // Increase timer.
double& timer = (double&)modeComponent["RespawnTime"]; double& timer = (double&)modeComponent["RespawnTime"];
timer += dt; timer += dt;
double maxRespawnTime = m_DbgConfigForceRespawn ? m_ForcedRespawnTime : (double)modeComponent["MaxRespawnTime"]; 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) { if (timer < maxRespawnTime) {
return; return;
} }
@@ -54,7 +68,14 @@ void PlayerSpawnSystem::Update(double dt)
// If the spawner has a team affiliation, check it // If the spawner has a team affiliation, check it
if (spawner.HasComponent("Team")) { 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; continue;
} }
} }
@@ -75,9 +96,9 @@ void PlayerSpawnSystem::Update(double dt)
} }
} }
if (numSpawnedPlayers != (int)m_SpawnRequests.size()) { 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 { } else {
LOG_DEBUG("%i players were spawned.", numSpawnedPlayers); LOG_DEBUG("%i players were spawned or set as spectator.", numSpawnedPlayers);
} }
m_SpawnRequests.clear(); m_SpawnRequests.clear();
} }
@@ -88,24 +109,29 @@ bool PlayerSpawnSystem::OnInputCommand(Events::InputCommand& e)
return false; 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! // Team picks should be processed ONLY server-side!
// Don't make a spawn request if we're the client. // Don't make a spawn request if we're the client.
if (!IsServer && m_NetworkEnabled) { if (!IsServer && m_NetworkEnabled) {
return false; return false;
} }
if (e.Value == 0) { // Check if the player already requested spawn.
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.
auto iter = m_SpawnRequests.begin(); auto iter = m_SpawnRequests.begin();
for (; iter != m_SpawnRequests.end(); ++iter) { for (; iter != m_SpawnRequests.end(); ++iter) {
if (iter->PlayerID == e.PlayerID) { if (iter->PlayerID == e.PlayerID) {
@@ -114,11 +140,11 @@ bool PlayerSpawnSystem::OnInputCommand(Events::InputCommand& e)
} }
if (iter != m_SpawnRequests.end()) { 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; iter->Team = (ComponentInfo::EnumType)e.Value;
} else if (m_PlayerEntities.count(e.PlayerID) == 0 || !m_PlayerEntities[e.PlayerID].Valid()) { } 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, // If player is not in queue to spawn, then create a spawn request,
//but only if they are spectating and/or just connected. // but only if they are spectating and/or just connected.
SpawnRequest req; SpawnRequest req;
req.PlayerID = e.PlayerID; req.PlayerID = e.PlayerID;
req.Team = (ComponentInfo::EnumType)e.Value; req.Team = (ComponentInfo::EnumType)e.Value;
+1 -1
View File
@@ -94,7 +94,7 @@ bool SoundSystem::OnCaptured(const Events::Captured & e)
if (!LocalPlayer.Valid()) { if (!LocalPlayer.Valid()) {
return false; 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"]; int team = (int)m_World->GetComponent(LocalPlayer.ID, "Team")["Team"];
Events::PlaySoundOnEntity ev; Events::PlaySoundOnEntity ev;
if (team == homeTeam) { if (team == homeTeam) {
+8 -6
View File
@@ -17,15 +17,17 @@ EntityWrapper SpawnerSystem::Spawn(EntityWrapper spawner, EntityWrapper parent /
// Load the entity file and parse it // Load the entity file and parse it
const std::string& entityFilePath = spawner["Spawner"]["EntityFile"]; const std::string& entityFilePath = spawner["Spawner"]["EntityFile"];
auto entityFile = ResourceManager::Load<EntityFile>(entityFilePath); EntityWrapper spawnedEntity;
if (entityFile == nullptr) { try {
auto entityFile = ResourceManager::Load<EntityFile>(entityFilePath);
spawnedEntity = entityFile->MergeInto(world);
world->SetParent(spawnedEntity.ID, parent.ID);
} catch (const Resource::FailedLoadingException& e) {
return EntityWrapper::Invalid; 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 // If the spawned entity is collidable, then we must not spawn it where it collides with something that
//has a dontCollideComponent attached. // has a dontCollideComponent attached.
bool spawnOnCollidable = dontCollideComponent.empty() || !spawnedEntity.HasComponent("Collidable"); bool spawnOnCollidable = dontCollideComponent.empty() || !spawnedEntity.HasComponent("Collidable");
if (!spawnOnCollidable) { if (!spawnOnCollidable) {
boost::optional<EntityAABB> optBox = Collision::EntityAbsoluteAABB(spawnedEntity); boost::optional<EntityAABB> optBox = Collision::EntityAbsoluteAABB(spawnedEntity);
@@ -366,9 +366,10 @@ bool AssaultWeaponBehaviour::shoot(double damage)
return false; 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"]) { if ((ComponentInfo::EnumType)victim["Team"]["Team"] == (ComponentInfo::EnumType)m_Player["Team"]["Team"]) {
return false; damage = 0;
} }
// Deal damage! // Deal damage!
+5 -5
View File
@@ -7,7 +7,7 @@ using boost::unit_test_framework::test_case;
#include "Collision/TriggerSystem.h" #include "Collision/TriggerSystem.h"
#include "Collision/CollisionSystem.h" #include "Collision/CollisionSystem.h"
#include "Core/EntityFileWriter.h" #include "Core/EntityXMLFileWriter.h"
#include "Game/Systems/CapturePointSystem.h" #include "Game/Systems/CapturePointSystem.h"
BOOST_AUTO_TEST_SUITE(CapturePointTestSuite) BOOST_AUTO_TEST_SUITE(CapturePointTestSuite)
@@ -82,7 +82,7 @@ bool CapturePointTest::CapturePoint_Game_Loop_OneHundredTimes() {
CapturePointTest::CapturePointTest(int runTestNumber) CapturePointTest::CapturePointTest(int runTestNumber)
{ {
ResourceManager::RegisterType<ConfigFile>("ConfigFile"); ResourceManager::RegisterType<ConfigFile>("ConfigFile");
ResourceManager::RegisterType<EntityFile>("EntityFile"); ResourceManager::RegisterType<EntityXMLFile>("EntityFile");
m_Config = ResourceManager::Load<ConfigFile>("Config.ini"); m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1)); LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1));
@@ -99,10 +99,10 @@ CapturePointTest::CapturePointTest(int runTestNumber)
m_SystemPipeline->AddSystem<CapturePointSystem>(1); m_SystemPipeline->AddSystem<CapturePointSystem>(1);
//must register components (Components.xsd), else you cant create entities. Easiest done by loading a test xsd file //must register components (Components.xsd), else you cant create entities. Easiest done by loading a test xsd file
auto file = ResourceManager::Load<EntityFile>("Schema/Entities/TeamTest.xml"); auto file = ResourceManager::Load<EntityXMLFile>("Schema/Entities/TeamTest.xml");
EntityFilePreprocessor fpp(file); EntityXMLFilePreprocessor fpp(file);
fpp.RegisterComponents(m_World); fpp.RegisterComponents(m_World);
EntityFileParser fp(file); EntityXMLFileParser fp(file);
fp.MergeEntities(m_World); fp.MergeEntities(m_World);
EntityID playerID = m_World->CreateEntity(); EntityID playerID = m_World->CreateEntity();
+4 -4
View File
@@ -9,12 +9,12 @@
#include "Input/KeyboardInputHandler.h" #include "Input/KeyboardInputHandler.h"
#include "Input/MouseInputHandler.h" #include "Input/MouseInputHandler.h"
#include "Core/EKeyDown.h" #include "Core/EKeyDown.h"
#include "Core/EntityFile.h" #include "Core/EntityXMLFile.h"
#include "Core/SystemPipeline.h" #include "Core/SystemPipeline.h"
#include "Core/EntityFilePreprocessor.h" #include "Core/EntityXMLFilePreprocessor.h"
#include "Core/EntityFileParser.h" #include "Core/EntityXMLFileParser.h"
#include "Core/EntityFileWriter.h" #include "Core/EntityXMLFileWriter.h"
#include "Engine/Collision/ETrigger.h" #include "Engine/Collision/ETrigger.h"
+4 -4
View File
@@ -30,7 +30,7 @@ BOOST_AUTO_TEST_SUITE_END()
GameHealthSystemTest::GameHealthSystemTest() GameHealthSystemTest::GameHealthSystemTest()
{ {
ResourceManager::RegisterType<ConfigFile>("ConfigFile"); ResourceManager::RegisterType<ConfigFile>("ConfigFile");
ResourceManager::RegisterType<EntityFile>("EntityFile"); ResourceManager::RegisterType<EntityXMLFile>("EntityFile");
m_Config = ResourceManager::Load<ConfigFile>("Config.ini"); m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1)); LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1));
@@ -41,10 +41,10 @@ GameHealthSystemTest::GameHealthSystemTest()
// Create a world // Create a world
m_World = new World(); m_World = new World();
auto file = ResourceManager::Load<EntityFile>("Schema/Entities/TeamTest.xml"); auto file = ResourceManager::Load<EntityXMLFile>("Schema/Entities/TeamTest.xml");
EntityFilePreprocessor fpp(file); EntityXMLFilePreprocessor fpp(file);
fpp.RegisterComponents(m_World); fpp.RegisterComponents(m_World);
EntityFileParser fp(file); EntityXMLFileParser fp(file);
fp.MergeEntities(m_World); fp.MergeEntities(m_World);
// Create system pipeline // Create system pipeline

Some files were not shown because too many files have changed in this diff Show More