Compare commits

...

103 Commits

Author SHA1 Message Date
William Moberg bc3c8299e8 Moved minidump code to MiniDump.cpp from main. 2016-03-04 03:05:09 +01:00
verysecrethero dc88074f7f Merge remote-tracking branch 'origin/master' into MiniDump 2016-03-03 17:03:06 +01:00
verysecrethero db09d93111 Minidump stage 2 fix 2016-03-03 16:41:47 +01:00
verysecrethero cc34f53b16 Memorydump stage 1 fix 2016-03-03 16:07:35 +01:00
Tobias Dahl fe36e8b423 Merge pull request #164 from teamfisk/FixNetworkBugs
Fixed invisible players and connect crash.
2016-03-03 15:57:02 +01:00
stiffly a7bff92899 The readBuffer now checks if the whole packet has arrived before attempting to parse it. 2016-03-03 15:16:42 +01:00
Tobias Dahl bfcf7b240e Merge pull request #163 from teamfisk/revert-145-Shadows
Revert "Shadows"
2016-03-03 14:25:10 +01:00
Tobias Dahl 73b8bff1f3 Revert "Shadows" 2016-03-03 14:24:43 +01:00
Tobias Dahl 1deb506fb2 Merge pull request #145 from teamfisk/Shadows
Shadows
2016-03-03 14:06:48 +01:00
Jocke ae3cab6cd1 Merge remote-tracking branch 'origin/master' into FixNetworkBugs 2016-03-03 13:31:43 +01:00
Jocke a9b19d9af1 Packet write now only warns when a a packet is huge 2016-03-03 13:29:45 +01:00
Jocke cb7beae28c Only do physics and collision calculations on the clients side, and only for their own entity. 2016-03-03 11:39:00 +01:00
FakeShemp 7ea26d10ee Rewritten. Works as a charm now. 2016-03-03 03:28:21 +01:00
FakeShemp 28e9ba1208 Merge branch 'master' into Shadows
# Conflicts:
#	include/Engine/Rendering/DrawFinalPass.h
#	src/Engine/Rendering/DrawFinalPass.cpp
#	src/Engine/Rendering/FrameBuffer.cpp
#	src/Engine/Rendering/Renderer.cpp
2016-03-03 03:00:05 +01:00
Tobias Dahl f0c2fdead1 Merge pull request #156 from teamfisk/HUD-Timers
Hud timers for dash ability
2016-03-02 22:53:25 +01:00
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
Jocke 85ba5552e9 Merge remote-tracking branch 'origin/master' into FixNetworkBugs 2016-03-02 17:59:20 +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
Jocke 0a6653d079 Merge remote-tracking branch 'origin/master' into FixNetworkBugs 2016-03-02 17:06:24 +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
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
William Moberg dc10661e6b Respawn time now only displays numbers, centered below CPHUD. 2016-03-02 16:45:43 +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
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
Jocke cfba8efd24 WritePrimitive would spam a warning when snapshots got bigger than 512 and it got resized. 2016-03-02 10:59:03 +01:00
FakeShemp 5a6374f013 Fix the remainder of errors. Might have borked splatmap in the process. 2016-03-02 10:57:22 +01:00
FakeShemp 1ae2f3f5f3 Begin clean-up 2016-03-01 19:10:13 +01:00
William Moberg 5a8261453e Eliminated some SAXParsing errors from our console output. 2016-03-01 17:40:42 +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
William Moberg 5c6a652316 Fixed so unregistered components are ignored instead of crashing the game. 2016-03-01 15:53:59 +01:00
FakeShemp 1961c16fe2 add weight slider 2016-03-01 13:27:52 +01:00
FakeShemp d32a483bb4 remove farclip override 2016-03-01 13:17:17 +01:00
FakeShemp e23ea78aeb Merge remote-tracking branch 'origin/master' into Shadows
# Conflicts:
#	resources/Shaders/ForwardPlus.frag.glsl
2016-03-01 13:04:11 +01:00
FakeShemp 4153a31e3a Fix goof. 2016-02-29 19:47:24 +01:00
FakeShemp 0908be1e02 Shadows are pretty much done. 2016-02-29 19:45:56 +01:00
FakeShemp 2ed5fad699 The shadows are working 2016-02-29 19:17:16 +01:00
FakeShemp 70374fa10e It compiles, but no shadows 2016-02-29 18:20:32 +01:00
FakeShemp 20468cba1b Merge branch 'master' into Shadows
# Conflicts:
#	assets
#	include/Engine/Rendering/DrawFinalPass.h
#	include/Engine/Rendering/Renderer.h
#	resources/Shaders/ForwardPlus.frag.glsl
#	resources/Shaders/ForwardPlus.vert.glsl
#	src/Engine/Rendering/DrawFinalPass.cpp
#	src/Engine/Rendering/FrameBuffer.cpp
#	src/Engine/Rendering/Renderer.cpp
2016-02-29 18:03:00 +01:00
FakeShemp 7749fc5474 Small fixing up 2016-02-28 19:46:50 +01:00
FakeShemp 6dd7f1a657 Buggy transparent shadows.
Transparent textures might glow.
2016-02-28 18:00:23 +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
FakeShemp 14b0a64720 begin fixing transparent object's shadows 2016-02-27 18:42:51 +01:00
FakeShemp 8647267cad Make code less dumb, save 7 fps 2016-02-27 18:04:33 +01:00
FakeShemp ecab5de056 Various shadow calculation methods implemented and ready for use. 2016-02-27 16:35:15 +01:00
FakeShemp 38d8cdded2 Texture Array is now working. Enjoy your single Bind(). 2016-02-27 15:53:28 +01:00
FakeShemp 22c391df54 Initial work on texture arrays 2016-02-26 17:40:35 +01:00
FakeShemp f220d8088c Begin clean-up 2016-02-26 10:53:16 +01:00
FakeShemp df2e4abb52 WE HAVE WORKING CASCADE SHADOWS 2016-02-25 21:21:38 +01:00
FakeShemp 8867e7ac3c Working shadows, no cascade blend yet 2016-02-25 20:29:41 +01:00
William Moberg 05bbecc452 WIP, minidump is done in another program, started from our app.
The other program is not in git yet.
2016-02-24 17:23:47 +01:00
William Moberg a36deb2cf9 WIP, trying to figure out why minidumps doesn't work. 2016-02-23 18:19:48 +01:00
FakeShemp 73a4336206 Try some stuff 2016-02-18 23:33:10 +01:00
FakeShemp f2ab02d860 More WIP
Switching between levels seem to work, but I borked all matrices
2016-02-18 22:38:50 +01:00
FakeShemp bf376f54b6 WIP
I think this is now finding the different segments of the cascade
2016-02-18 20:48:39 +01:00
FakeShemp 178402e964 cascade shadow wip 2016-02-18 10:08:29 +01:00
FakeShemp 36043010af wip for shadows
they work, but will be shit until we get cascaded.
2016-02-10 20:51:33 +01:00
FakeShemp cb77c1ff97 Working pcf, not optimized 2016-02-10 16:16:41 +01:00
FakeShemp 69db32337d Shado wip 2016-02-10 15:16:58 +01:00
Ayumiwii 6af167675d Shadow WIP stage 2
- fix cel-shading
2016-02-10 11:48:44 +01:00
Ayumiwii ecd823cb9f Shadow WIP stage 2
-  Soft shadow
2016-02-09 16:15:11 +01:00
FakeShemp 847c539373 Fix viewport 2016-02-09 14:44:12 +01:00
Ayumiwii cb7f06573f Shadows stage 2 WIP 2016-02-09 14:08:57 +01:00
Ayumiwii 6542d1b444 Shadow WIP
- DepthTexture working
2016-02-05 17:29:53 +01:00
Ayumiwii bbf6058c17 Shadow WIP
- fixed file placing of ShadowPass.cpp
2016-02-05 16:13:46 +01:00
Ayumiwii 0e51ae7dc9 shadow wip 2016-02-05 15:31:20 +01:00
Ayumiwii c912cd7a42 Shadows wip 2016-02-05 15:12:17 +01:00
Ayumiwii 7f1016476b Shadows WIP
- create 2D texture (depthmap)
2016-02-05 15:08:56 +01:00
81 changed files with 7328 additions and 960 deletions
+9 -152
View File
@@ -1,164 +1,21 @@
#ifndef EntityFile_h__
#define EntityFile_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 "World.h"
#include "EntityXMLFile.h"
#include "EntityXMLFilePreprocessor.h"
#include "EntityXMLFileParser.h"
#include "EntityWrapper.h"
#include "../GLM.h"
#include "Util/XercesString.h"
#include "ResourceManager.h"
#include "Entity.h"
#include "ComponentInfo.h"
class EntityFileHandler
{
friend class EntityFileSAXHandler;
public:
// @param EntityID The entity found
// @param EntityID The parent of the entity
typedef std::function<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
class EntityFile : private World, public Resource
{
public:
enum class State
{
Unknown,
Entity,
Component,
ComponentField
};
EntityFile(std::string path);
EntityFileSAXHandler(const EntityFileHandler* handler, xercesc::SAX2XMLReader* reader);
void startElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname, const xercesc::Attributes& attrs) override;
void characters(const XMLCh* const chars, const XMLSize_t length) override;
void endElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname) override;
void warning(const xercesc::SAXParseException& e);
void error(const xercesc::SAXParseException& e);
void fatalError(const xercesc::SAXParseException& e);
EntityWrapper MergeInto(World* other);
private:
const EntityFileHandler* m_Handler;
xercesc::XMLGrammarPool* m_GrammarPool;
xercesc::SAX2XMLReader* m_Reader;
//State m_CurrentScope = State::Unknown;
std::stack<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);
EntityID m_RootEntity = EntityID_Invalid;
};
#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__
#define EntityFileParser_h__
#ifndef EntityXMLFileParser_h__
#define EntityXMLFileParser_h__
#include "EntityFile.h"
#include "EntityXMLFile.h"
#include "World.h"
class EntityFileParser
class EntityXMLFileParser
{
friend class EntityFile;
public:
EntityFileParser(const EntityFile* entityFile);
EntityID MergeEntities(World* world, EntityID baseParent = EntityID_Invalid);
EntityXMLFileParser(const EntityXMLFile* entityFile);
private:
const EntityFile* m_EntityFile;
EntityID MergeEntities(World* world, EntityID baseParent = EntityID_Invalid);
const EntityXMLFile* m_EntityFile;
EntityFileHandler m_Handler;
World* m_World = nullptr;
EntityID m_FirstEntity = EntityID_Invalid;
@@ -1,5 +1,5 @@
#ifndef EntityFilePreprocessor_h__
#define EntityFilePreprocessor_h__
#ifndef EntityXMLFilePreprocessor_h__
#define EntityXMLFilePreprocessor_h__
#include <xercesc/framework/psvi/XSElementDeclaration.hpp>
#include <xercesc/framework/psvi/XSComplexTypeDefinition.hpp>
@@ -17,17 +17,18 @@
#include "Util/XercesString.h"
#include "ResourceManager.h"
#include "World.h"
#include "EntityFile.h"
#include "EntityXMLFile.h"
class EntityFilePreprocessor
class EntityXMLFilePreprocessor
{
friend class EntityFile;
public:
EntityFilePreprocessor(const EntityFile* entityFile);
void RegisterComponents(World* world);
EntityXMLFilePreprocessor(const EntityXMLFile* entityFile);
private:
const EntityFile* m_EntityFile;
void RegisterComponents(World* world);
const EntityXMLFile* m_EntityFile;
std::map<std::string, unsigned int> m_ComponentCounts;
std::map<std::string, ComponentInfo> m_ComponentInfo;
@@ -1,5 +1,5 @@
#ifndef EntityFileWriter_h__
#define EntityFileWriter_h__
#ifndef EntityXMLFileWriter_h__
#define EntityXMLFileWriter_h__
#include <boost/filesystem.hpp>
#include <xercesc/dom/DOM.hpp>
@@ -8,13 +8,13 @@
#include <xercesc/framework/LocalFileFormatTarget.hpp>
#include "Util/XercesString.h"
#include "EntityFile.h"
#include "EntityXMLFile.h"
#include "World.h"
class EntityFileWriter
class EntityXMLFileWriter
{
public:
EntityFileWriter(boost::filesystem::path file)
EntityXMLFileWriter(boost::filesystem::path file)
: m_FilePath(file)
{
using namespace xercesc;
-3
View File
@@ -118,9 +118,6 @@ public:
else {
m_ExtraMemory.push_back((char*)malloc(m_Stride));
//We should preferably not enter here to avoid performance issues. Set more numMaxElements in constructor instead.
if (!DisableMemoryPool::Value) {
LOG_DEBUG("Allocated slots exceed Pool size, extra memory allocated dynamically. Pool size: %u, dynamic size: %u.", m_NumSlots, m_ExtraMemory.size());
}
return m_ExtraMemory.back();
}
}
+9 -2
View File
@@ -6,6 +6,7 @@
#include "ObjectPool.h"
#include "ComponentPool.h"
#include "EventBroker.h"
struct EntityWrapper;
class World
{
@@ -18,13 +19,13 @@ public:
World(const World& other);
// Create empty entity
EntityID CreateEntity(EntityID parent = 0);
EntityID CreateEntity(EntityID parent = EntityID_Invalid);
// Delete entity and all components within
void DeleteEntity(EntityID entity);
// Check if an entity exists
bool ValidEntity(EntityID entity) const;
// Register a component type and allocate space for it
void RegisterComponent(ComponentInfo& ci);
void RegisterComponent(const ComponentInfo& ci);
// Attach a component to an entity and fill it with default values
ComponentWrapper AttachComponent(EntityID entity, const std::string& componentType);
// Check if an entity has a component
@@ -49,6 +50,12 @@ public:
void SetName(EntityID entity, const std::string& name);
// Get the textual name of an entity
std::string GetName(EntityID entity) const;
// Get the first entity in the world with the name.
EntityWrapper GetFirstEntityByName(const std::string& name);
// Merge another world into this one
// Returns a map that maps entities from the other world to their copies in this one
std::unordered_map<EntityID, EntityID> Merge(const World* other);
private:
EventBroker* m_EventBroker = nullptr;
+2 -3
View File
@@ -5,9 +5,8 @@
#include "../Core/World.h"
#include "../Core/SystemPipeline.h"
#include "../Core/ResourceManager.h"
#include "../Core/EntityFilePreprocessor.h"
#include "../Core/EntityFileParser.h"
#include "../Core/EntityFileWriter.h"
#include "../Core/EntityFile.h"
#include "../Core/EntityXMLFileWriter.h"
#include "../Core/EMousePress.h"
#include "../Input/EInputCommand.h"
#include "EditorGUI.h"
@@ -27,7 +27,7 @@ public:
virtual bool OnCommand(const Events::InputCommand& e) override;
virtual void Reset();
void AssaultDashCheck(double dt, bool isJumping, double assaultDashCoolDownMaxTimer, double& assaultDashCoolDownTimer);
void AssaultDashCheck(double dt, bool isJumping, double assaultDashCoolDownMaxTimer, double& assaultDashCoolDownTimer, EntityID playerID);
virtual bool AssaultDashDoubleTapped() const { return m_AssaultDashDoubleTapped; }
virtual bool PlayerIsDashing() const { return m_PlayerIsDashing; }
@@ -41,6 +41,7 @@ protected:
bool m_Crouching = false;
//assault dash membervariables - needed to calculate the doubletap- and dashlogic
double m_AssaultDashDoubleTapDeltaTime = 0.0;
double m_DashEffectResetTimer = 0.0;
//i will let m_AssaultDashDoubleTapSensitivityTimer stay hardcoded, its not really a gamevariable (more an inputvariable),
//and its very unlikely that someone wants to change that value
const float m_AssaultDashDoubleTapSensitivityTimer = 0.25f;
@@ -51,7 +52,7 @@ protected:
bool m_ShiftDashing = false;
bool m_ValidDoubleTap = false;
//specialabilitys
//specialabilities
bool m_MovementKeyDown = false;
bool m_SpecialAbilityKeyDown = false;
int m_NumberOfMovementKeysDown = 0;
@@ -190,12 +191,19 @@ bool FirstPersonInputController<EventContext>::OnLockMouse(const Events::LockMou
}
template <typename EventContext>
void FirstPersonInputController<EventContext>::AssaultDashCheck(double dt, bool isJumping, double assaultDashCoolDownMaxTimer, double& assaultDashCoolDownTimer) {
void FirstPersonInputController<EventContext>::AssaultDashCheck(double dt, bool isJumping, double assaultDashCoolDownMaxTimer, double& assaultDashCoolDownTimer, EntityID playerID) {
m_AssaultDashDoubleTapDeltaTime += dt;
m_DashEffectResetTimer += dt;
assaultDashCoolDownTimer -= dt;
//cooldown = assaultDashCoolDownMaxTimer sec, pretend the dash lasts 0.25 sec (for friction to do its work)
if (assaultDashCoolDownTimer > (assaultDashCoolDownMaxTimer - 0.25f)) {
m_PlayerIsDashing = true;
if (m_DashEffectResetTimer > 0.05) {
Events::DashAbility e;
e.Player = playerID;
m_EventBroker->Publish(e);
m_DashEffectResetTimer = 0.0;
}
} else {
m_PlayerIsDashing = false;
}
@@ -207,6 +215,9 @@ void FirstPersonInputController<EventContext>::AssaultDashCheck(double dt, bool
assaultDashCoolDownTimer = assaultDashCoolDownMaxTimer;
m_AssaultDashDoubleTapped = true;
m_AssaultDashDoubleTapDeltaTime = 0.f;
Events::DashAbility e;
e.Player = playerID;
m_EventBroker->Publish(e);
return;
}
@@ -237,6 +248,7 @@ void FirstPersonInputController<EventContext>::AssaultDashCheck(double dt, bool
assaultDashCoolDownTimer = assaultDashCoolDownMaxTimer;
Events::DashAbility e;
e.Player = playerID;
m_EventBroker->Publish(e);
}
+5
View File
@@ -28,6 +28,7 @@
#include "Core/EPlayerSpawned.h"
#include "Core/EAmmoPickup.h"
#include "Network/ESearchForServers.h"
#include "../Game/Events/EDashAbility.h"
struct ServerInfo
{
@@ -107,6 +108,7 @@ private:
void parsePlayerDamage(Packet& packet);
void parseComponentDeletion(Packet& packet);
void parseDoubleJump(Packet& packet);
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);
@@ -135,6 +137,9 @@ private:
EventRelay< Client, Events::SearchForServers> m_ESearchForServers;
EventRelay<Client, Events::DoubleJump> m_EDoubleJump;
bool OnDoubleJump(Events::DoubleJump & e);
EventRelay<Client, Events::DashAbility> m_EDashAbility;
bool OnDashAbility(const Events::DashAbility& e);
bool OnSearchForServers(const Events::SearchForServers& e);
UDPClient m_ServerlistRequest;
std::vector<ServerInfo> m_Serverlist;
+1
View File
@@ -20,6 +20,7 @@ enum class MessageType
ComponentDeleted,
PlayerTransform,
OnDoubleJump,
OnDashEffect,
ServerlistRequest,
AmmoPickup,
Invalid
+3 -1
View File
@@ -24,7 +24,9 @@ public:
{
// Check if we are trying to add more than the package can fit.
if (m_MaxPacketSize < m_Offset + sizeof(T)) {
LOG_WARNING("Packet AddPrimitive(): You are trying to add more than we have allocated for! New size is %i bytes\n", m_MaxPacketSize*2);
if (m_MaxPacketSize >= 32000) {
LOG_WARNING("Package::WritePrimitive(): New size is huge %i bytes\n", m_MaxPacketSize*2);
}
resizeData();
}
memcpy(m_Data + m_Offset, &val, sizeof(T));
+1
View File
@@ -83,6 +83,7 @@ private:
void parseClientPing();
void parsePing();
bool parseDoubleJump(Packet& packet);
void parseDashEffect(Packet& packet);
void parseUDPConnect(Packet& packet);
void parseTCPConnect(Packet& packet);
void parseDisconnect();
+5 -1
View File
@@ -2,11 +2,15 @@
#define Events_DashAbility_h__
#include "Core/Event.h"
#include "Core/EntityWrapper.h"
namespace Events
{
struct DashAbility : public Event { };
struct DashAbility : public Event
{
EntityID Player;
};
}
+3 -3
View File
@@ -13,13 +13,13 @@
#include "Input/KeyboardInputHandler.h"
#include "Input/MouseInputHandler.h"
#include "Core/EKeyDown.h"
#include "Core/EntityFilePreprocessor.h"
#include "Core/EntityXMLFilePreprocessor.h"
#include "Core/SystemPipeline.h"
#include "Systems/ExplosionEffectSystem.h"
#include "Editor/EditorSystem.h"
#include "Core/EntityFile.h"
#include "Core/EntityXMLFile.h"
#include "Rendering/RenderSystem.h"
#include "Core/EntityFileParser.h"
#include "Core/EntityXMLFileParser.h"
#include "Core/Octree.h"
#include "Rendering/Font.h"
#include "Systems/InterpolationSystem.h"
+2 -1
View File
@@ -2,7 +2,8 @@
#define MiniDump_h__
#include <Windows.h>
#include <DbgHelp.h>
void WINAPI Create_Dump(PEXCEPTION_POINTERS pException, BOOL File_Flag, BOOL Show_Flag);
long WINAPI Create_Dump_Immediate(LPEXCEPTION_POINTERS pException);
#endif
@@ -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
+1 -1
View File
@@ -4,7 +4,7 @@
#include "Core/System.h"
#include "Core/Transform.h"
#include "Core/ResourceManager.h"
#include "Core/EntityFileParser.h"
#include "Core/EntityFile.h"
#include "Core/EPickupSpawned.h"
#include "Core/EAmmoPickup.h"
#include "Engine/Collision/ETrigger.h"
@@ -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
+1 -1
View File
@@ -3,7 +3,7 @@
#include "Core/System.h"
#include "Core/ResourceManager.h"
#include "Core/EntityFileParser.h"
#include "Core/EntityFile.h"
#include "Core/EPlayerDamage.h"
#include "Common.h"
+1 -1
View File
@@ -4,7 +4,7 @@
#include "Core/System.h"
#include "Core/Transform.h"
#include "Core/ResourceManager.h"
#include "Core/EntityFileParser.h"
#include "Core/EntityFile.h"
#include "Core/EPlayerDamage.h"
#include "Common.h"
#include <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"];
}
};
+1 -1
View File
@@ -4,7 +4,7 @@
#include "Core/System.h"
#include "Core/Transform.h"
#include "Core/ResourceManager.h"
#include "Core/EntityFileParser.h"
#include "Core/EntityFile.h"
#include "Core/EPickupSpawned.h"
#include "Core/EPlayerHealthPickup.h"
#include "Engine/Collision/ETrigger.h"
+5 -3
View File
@@ -6,11 +6,9 @@
#include "GLM.h"
#include "Rendering/ESetCamera.h"
#include "Core/ConfigFile.h"
#include "Core/EntityFile.h"
#include "Core/EntityFileParser.h"
#include "Core/EPlayerDeath.h"
#include "Core/EEntityDeleted.h"
class PlayerDeathSystem : public ImpureSystem
{
@@ -20,8 +18,12 @@ public:
virtual void Update(double dt) override;
private:
EntityWrapper m_LocalPlayerDeathEffect;
EventRelay<PlayerDeathSystem, Events::PlayerDeath> m_OnPlayerDeath;
bool OnPlayerDeath(Events::PlayerDeath& e);
EventRelay<PlayerDeathSystem, Events::EntityDeleted> m_EEntityDeleted;
bool OnEntityDeleted(Events::EntityDeleted& e);
void createDeathEffect(EntityWrapper player);
+2 -2
View File
@@ -6,9 +6,7 @@
#include <imgui/imgui.h>
#include "Events/EDoubleJump.h"
#include "../Engine/Sound/EPlaySoundOnEntity.h"
#include "Core/EntityFile.h"
#include "Core/EntityFileParser.h"
class PlayerMovementSystem : public ImpureSystem
{
@@ -41,6 +39,8 @@ private:
bool OnPlayerSpawned(Events::PlayerSpawned& e);
EventRelay<PlayerMovementSystem, Events::DoubleJump> m_EDoubleJump;
bool PlayerMovementSystem::OnDoubleJump(Events::DoubleJump & e);
EventRelay<PlayerMovementSystem, Events::DashAbility> m_EDashAbility;
bool PlayerMovementSystem::OnDashAbility(Events::DashAbility & e);
void updateMovementControllers(double dt);
void updateVelocity(EntityWrapper player, double dt);
+1 -2
View File
@@ -7,8 +7,7 @@
#include "Core/System.h"
#include "Events/ESpawnerSpawn.h"
#include "Core/Transform.h"
#include "Core/ResourceManager.h"
#include "Core/EntityFileParser.h"
#include "Core/EntityFile.h"
class SpawnerSystem : public System
{
+2 -2
View File
@@ -9,8 +9,8 @@
#include "Core/EShoot.h"
#include "Core/EPlayerSpawned.h"
#include "Input/EInputCommand.h"
#include "Core/EntityFile.h"
#include "Core/EntityFileParser.h"
#include "Core/EntityXMLFile.h"
#include "Core/EntityXMLFileParser.h"
#include "Core/Octree.h"
#include "Collision/EntityAABB.h"
#include "Systems/SpawnerSystem.h"
+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 false -> Use pool allocation.
DisableMemoryPool=false
RespawnTime = 8.0
RespawnTime = -1.0
EditorEnabled=false
OutOfBodyExperience=false
+3
View File
@@ -51,9 +51,12 @@
<xs:include schemaLocation="Components/Page.xsd"/>
<xs:include schemaLocation="Components/SpriteIndicator.xsd"/>
<xs:include schemaLocation="Components/Button.xsd"/>
<xs:include schemaLocation="Components/AbilityCooldownHUD.xsd"/>
<xs:include schemaLocation="Components/DoubleJump.xsd"/>
<xs:include schemaLocation="Components/WeaponAttachment.xsd"/>
<xs:include schemaLocation="Components/DefenderWeapon.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>
@@ -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,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,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>
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Text xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Text.xsd">
<Content></Content>
<Resource></Resource>
<Resource>Fonts/DroidSans.ttf,64</Resource>
<Color R="1" G="1" B="1" A="1"/>
<Visible>true</Visible>
<Alignment><Center/></Alignment>
+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>
+49 -49
View File
@@ -804,11 +804,11 @@
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>3002.0048499272534</Time>
<Time>3297.0538973857279</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="0" Y="0.00320033543" Z="0"/>
<Position X="-0" Y="-0.0338360146" Z="-0"/>
</c:Transform>
</Components>
<Children>
@@ -825,7 +825,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="23665.3672" Z="0"/>
<Orientation X="0" Y="23901.0449" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
@@ -851,11 +851,11 @@
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>2981.7884295114754</Time>
<Time>3276.8374769699499</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="-0" Y="-0.123386621" Z="-0"/>
<Position X="0" Y="0.0977828354" Z="0"/>
</c:Transform>
</Components>
<Children>
@@ -872,7 +872,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="23644.3164" Z="0"/>
<Orientation X="0" Y="23879.9941" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
@@ -898,11 +898,11 @@
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>2965.4934667508096</Time>
<Time>3260.542514209284</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="-0" Y="-0.199960142" Z="-0"/>
<Position X="0" Y="0.19820635" Z="0"/>
</c:Transform>
</Components>
<Children>
@@ -919,7 +919,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="23585.6074" Z="0"/>
<Orientation X="0" Y="23821.2852" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
@@ -945,11 +945,11 @@
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>2922.0307477781698</Time>
<Time>3217.0797952366443</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="0" Y="0.0194334686" Z="0"/>
<Position X="-0" Y="-0.0497358106" Z="-0"/>
</c:Transform>
</Components>
<Children>
@@ -966,7 +966,7 @@
<c:Transform>
<Position X="0" Y="2.36800003" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="5331.15967" Z="0"/>
<Orientation X="0" Y="5567.29199" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
@@ -992,11 +992,11 @@
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>2871.33224525081</Time>
<Time>3166.3812927092845</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="-0" Y="-0.172897741" Z="-0"/>
<Position X="0" Y="0.186271787" Z="0"/>
</c:Transform>
</Components>
<Children>
@@ -1013,7 +1013,7 @@
<c:Transform>
<Position X="0" Y="2.36800003" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="5241.63037" Z="0"/>
<Orientation X="0" Y="5477.7627" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
@@ -1039,11 +1039,11 @@
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>2854.2794756870871</Time>
<Time>3149.3285231455616</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="0" Y="0.154012829" Z="0"/>
<Position X="-0" Y="-0.171761468" Z="-0"/>
</c:Transform>
</Components>
<Children>
@@ -1060,7 +1060,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="14694.2959" Z="0"/>
<Orientation X="0" Y="14930.6826" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
@@ -1086,11 +1086,11 @@
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>2839.2647225755118</Time>
<Time>3134.3137700339862</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="-0" Y="-0.147846922" Z="-0"/>
<Position X="0" Y="0.166757002" Z="0"/>
</c:Transform>
</Components>
<Children>
@@ -1107,7 +1107,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="12585.2275" Z="0"/>
<Orientation X="0" Y="12821.6143" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
@@ -2242,7 +2242,7 @@
<Resource>Models/Props/Stones/AssaultHolder.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="-3.47628784" Y="0.507368565" Z="0.99732101"/>
<Position X="-3.30188537" Y="0.507368565" Z="1.6052227"/>
</c:Transform>
</Components>
<Children/>
@@ -2355,11 +2355,11 @@
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>2746.6837512442808</Time>
<Time>3041.7327987027552</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="0" Y="0.16754517" Z="0"/>
<Position X="-0" Y="-0.148809776" Z="-0"/>
</c:Transform>
</Components>
<Children>
@@ -2376,7 +2376,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="16210.457" Z="0"/>
<Orientation X="0" Y="16446.9434" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
@@ -2402,11 +2402,11 @@
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>2732.8386366079758</Time>
<Time>3027.8876840664502</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="0" Y="0.0970942229" Z="0"/>
<Position X="-0" Y="-0.0691253543" Z="-0"/>
</c:Transform>
</Components>
<Children>
@@ -2423,7 +2423,7 @@
<c:Transform>
<Position X="0" Y="2.36800003" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="5167.40771" Z="0"/>
<Orientation X="0" Y="5403.54004" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
@@ -2904,11 +2904,11 @@
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>2969.073541383088</Time>
<Time>3264.1225888415624</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="-0" Y="-0.0458931364" Z="-0"/>
<Position X="0" Y="0.0752089471" Z="0"/>
</c:Transform>
</Components>
<Children>
@@ -2925,7 +2925,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="23639.0527" Z="0"/>
<Orientation X="0" Y="23874.7305" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
@@ -2951,11 +2951,11 @@
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>2948.85712096731</Time>
<Time>3243.9061684257845</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="0" Y="0.0866934955" Z="0"/>
<Position X="-0" Y="-0.0580219813" Z="-0"/>
</c:Transform>
</Components>
<Children>
@@ -2972,7 +2972,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="23618.002" Z="0"/>
<Orientation X="0" Y="23853.6797" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
@@ -2998,11 +2998,11 @@
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>2932.5621582066442</Time>
<Time>3227.6112056651186</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="0" Y="0.196187839" Z="0"/>
<Position X="-0" Y="-0.187905088" Z="-0"/>
</c:Transform>
</Components>
<Children>
@@ -3019,7 +3019,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="23559.293" Z="0"/>
<Orientation X="0" Y="23794.9707" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
@@ -3045,11 +3045,11 @@
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>2889.0994392340044</Time>
<Time>3184.1484866924789</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="-0" Y="-0.0615537763" Z="-0"/>
<Position X="0" Y="0.0900137872" Z="0"/>
</c:Transform>
</Components>
<Children>
@@ -3066,7 +3066,7 @@
<c:Transform>
<Position X="0" Y="2.36800003" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="5304.81885" Z="0"/>
<Orientation X="0" Y="5540.95117" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
@@ -3092,11 +3092,11 @@
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>2838.4009367066446</Time>
<Time>3133.4499841651191</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="0" Y="0.190397173" Z="0"/>
<Position X="-0" Y="-0.197535709" Z="-0"/>
</c:Transform>
</Components>
<Children>
@@ -3113,7 +3113,7 @@
<c:Transform>
<Position X="0" Y="2.36800003" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="5215.28955" Z="0"/>
<Orientation X="0" Y="5451.42188" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
@@ -3139,11 +3139,11 @@
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>2821.3481671429217</Time>
<Time>3116.3972146013962</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="-0" Y="-0.177647248" Z="-0"/>
<Position X="0" Y="0.189699799" Z="0"/>
</c:Transform>
</Components>
<Children>
@@ -3160,7 +3160,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="14667.9326" Z="0"/>
<Orientation X="0" Y="14904.3193" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
@@ -3186,11 +3186,11 @@
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>2806.3334140313464</Time>
<Time>3101.3824614898208</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="0" Y="0.173328787" Z="0"/>
<Position X="-0" Y="-0.186583459" Z="-0"/>
</c:Transform>
</Components>
<Children>
@@ -3207,7 +3207,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="12558.8643" Z="0"/>
<Orientation X="0" Y="12795.251" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
+114 -34
View File
@@ -802,8 +802,13 @@
<Children>
<Entity>
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>309.46063484238653</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="0" Y="0.181836113" Z="0"/>
<Position X="-0" Y="-0.198473096" Z="-0"/>
</c:Transform>
</Components>
<Children>
@@ -821,7 +826,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="24080.8184" Z="0"/>
<Orientation X="0" Y="24396.9355" Z="0"/>
</c:Transform>
</Components>
<Children/>
@@ -844,8 +849,13 @@
<Children>
<Entity>
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>277.77588852554459</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="-0" Y="-0.185762629" Z="-0"/>
<Position X="-0" Y="-0.129464492" Z="-0"/>
</c:Transform>
</Components>
<Children>
@@ -863,7 +873,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="24059.7676" Z="0"/>
<Orientation X="0" Y="24375.8848" Z="0"/>
</c:Transform>
</Components>
<Children/>
@@ -886,8 +896,13 @@
<Children>
<Entity>
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>265.69306053010564</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="0" Y="0.167244121" Z="0"/>
<Position X="-0" Y="-0.164330602" Z="-0"/>
</c:Transform>
</Components>
<Children>
@@ -905,7 +920,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="24001.0586" Z="0"/>
<Orientation X="0" Y="24317.1758" Z="0"/>
</c:Transform>
</Components>
<Children/>
@@ -928,8 +943,13 @@
<Children>
<Entity>
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>254.01948784300018</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="0" Y="0.0644967183" Z="0"/>
<Position X="0" Y="0.0122369174" Z="0"/>
</c:Transform>
</Components>
<Children>
@@ -947,7 +967,7 @@
<c:Transform>
<Position X="0" Y="2.36800003" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="5746.52246" Z="0"/>
<Orientation X="0" Y="6061.90527" Z="0"/>
</c:Transform>
</Components>
<Children/>
@@ -970,8 +990,13 @@
<Children>
<Entity>
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>244.21618709850597</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="-0" Y="-0.0994067639" Z="-0"/>
<Position X="0" Y="0.125630379" Z="0"/>
</c:Transform>
</Components>
<Children>
@@ -989,7 +1014,7 @@
<c:Transform>
<Position X="0" Y="2.36800003" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="5656.99316" Z="0"/>
<Orientation X="0" Y="5972.37598" Z="0"/>
</c:Transform>
</Components>
<Children/>
@@ -1012,8 +1037,13 @@
<Children>
<Entity>
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>231.37430087102678</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="-0" Y="-0.19803375" Z="-0"/>
<Position X="-0" Y="-0.184606224" Z="-0"/>
</c:Transform>
</Components>
<Children>
@@ -1031,7 +1061,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="15110.7119" Z="0"/>
<Orientation X="0" Y="15425.6113" Z="0"/>
</c:Transform>
</Components>
<Children/>
@@ -1054,8 +1084,13 @@
<Children>
<Entity>
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>219.21100328618962</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="-0" Y="-0.11493478" Z="-0"/>
<Position X="-0" Y="-0.12308117" Z="-0"/>
</c:Transform>
</Components>
<Children>
@@ -1073,7 +1108,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="13001.6436" Z="0"/>
<Orientation X="0" Y="13316.543" Z="0"/>
</c:Transform>
</Components>
<Children/>
@@ -2318,8 +2353,13 @@
<Children>
<Entity>
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>192.42971043059836</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="0" Y="0.143913418" Z="0"/>
<Position X="0" Y="0.195146352" Z="0"/>
</c:Transform>
</Components>
<Children>
@@ -2337,7 +2377,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="16626.7168" Z="0"/>
<Orientation X="0" Y="16942.834" Z="0"/>
</c:Transform>
</Components>
<Children/>
@@ -2360,8 +2400,13 @@
<Children>
<Entity>
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>180.12130596231671</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="0" Y="0.151800558" Z="0"/>
<Position X="0" Y="0.0743921027" Z="0"/>
</c:Transform>
</Components>
<Children>
@@ -2379,7 +2424,7 @@
<c:Transform>
<Position X="0" Y="2.36800003" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="5582.77051" Z="0"/>
<Orientation X="0" Y="5898.15332" Z="0"/>
</c:Transform>
</Components>
<Children/>
@@ -2857,8 +2902,13 @@
<Children>
<Entity>
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>154.99927956894089</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="-0" Y="-0.199556321" Z="-0"/>
<Position X="0" Y="0.000450141786" Z="0"/>
</c:Transform>
</Components>
<Children>
@@ -2876,7 +2926,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="24054.5039" Z="0"/>
<Orientation X="0" Y="24370.6191" Z="0"/>
</c:Transform>
</Components>
<Children/>
@@ -2899,8 +2949,13 @@
<Children>
<Entity>
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>144.56072209865593</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="-0" Y="-0.0983726978" Z="-0"/>
<Position X="0" Y="0.196372822" Z="0"/>
</c:Transform>
</Components>
<Children>
@@ -2918,7 +2973,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="24033.4531" Z="0"/>
<Orientation X="0" Y="24349.5703" Z="0"/>
</c:Transform>
</Components>
<Children/>
@@ -2941,8 +2996,13 @@
<Children>
<Entity>
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>113.54515932497441</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="0" Y="0.199529812" Z="0"/>
<Position X="-0" Y="-0.197990373" Z="-0"/>
</c:Transform>
</Components>
<Children>
@@ -2960,7 +3020,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="23974.7441" Z="0"/>
<Orientation X="0" Y="24290.8613" Z="0"/>
</c:Transform>
</Components>
<Children/>
@@ -2983,8 +3043,13 @@
<Children>
<Entity>
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>101.62883282122999</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="-0" Y="-0.129332498" Z="-0"/>
<Position X="-0" Y="-0.183840692" Z="-0"/>
</c:Transform>
</Components>
<Children>
@@ -3002,7 +3067,7 @@
<c:Transform>
<Position X="0" Y="2.36800003" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="5720.18164" Z="0"/>
<Orientation X="0" Y="6035.56445" Z="0"/>
</c:Transform>
</Components>
<Children/>
@@ -3025,8 +3090,13 @@
<Children>
<Entity>
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>90.764091375525993</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="-0" Y="-0.199750423" Z="-0"/>
<Position X="0" Y="0.135024786" Z="0"/>
</c:Transform>
</Components>
<Children>
@@ -3044,7 +3114,7 @@
<c:Transform>
<Position X="0" Y="2.36800003" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="5630.65234" Z="0"/>
<Orientation X="0" Y="5946.03516" Z="0"/>
</c:Transform>
</Components>
<Children/>
@@ -3067,8 +3137,13 @@
<Children>
<Entity>
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>70.667870676407972</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="-0" Y="-0.164693162" Z="-0"/>
<Position X="0" Y="0.172826052" Z="0"/>
</c:Transform>
</Components>
<Children>
@@ -3086,7 +3161,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="15084.3486" Z="0"/>
<Orientation X="0" Y="15399.248" Z="0"/>
</c:Transform>
</Components>
<Children/>
@@ -3109,8 +3184,13 @@
<Children>
<Entity>
<Components>
<c:FloatingEffect>
<Axis X="0" Y="0.200000003" Z="0"/>
<Time>54.385750605052408</Time>
<Period>2</Period>
</c:FloatingEffect>
<c:Transform>
<Position X="-0" Y="-0.0709934905" Z="-0"/>
<Position X="0" Y="0.187255353" Z="0"/>
</c:Transform>
</Components>
<Children>
@@ -3128,7 +3208,7 @@
<c:Transform>
<Position X="0" Y="2.36784196" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="12975.2803" Z="0"/>
<Orientation X="0" Y="13290.1797" Z="0"/>
</c:Transform>
</Components>
<Children/>
@@ -4222,7 +4302,7 @@
<HomePointForTeam>
<Blue/>
</HomePointForTeam>
<CapturePointMaxTimer>-15</CapturePointMaxTimer>
<CaptureTimer>-15</CaptureTimer>
<CapturePointNumber>4</CapturePointNumber>
</c:CapturePoint>
<c:Trigger/>
@@ -4444,7 +4524,7 @@
<Entity name="Directional">
<Components>
<c:DirectionalLight>
<Intensity>1</Intensity>
<Intensity>0.40000000596046448</Intensity>
</c:DirectionalLight>
<c:Transform>
<Orientation X="0" Y="1.16600001" Z="2.08000016"/>
File diff suppressed because it is too large Load Diff
+89 -6
View File
@@ -100,12 +100,12 @@
<Percentage>1</Percentage>
<Color A="1" B="1" G="0" R="0"/>
</c:Fill>
<c:HealthHUD/>
<c:Text>
<Content>100/100</Content>
<Resource>Fonts/DroidSans.ttf,64</Resource>
<Color A="0.505882382" B="3.92156863" G="1.17647064" R="0"/>
</c:Text>
<c:HealthHUD/>
<c:Transform>
<Position X="-0.355000019" Y="-0.203000009" Z="0.0410000011"/>
<Scale X="0.0350000001" Y="0.0350000001" Z="0.0350000001"/>
@@ -132,7 +132,70 @@
<Orientation X="5.87300014" Y="0" Z="4.71200037"/>
</c:Transform>
</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>
</Children>
</Entity>
@@ -196,7 +259,6 @@
<CapturePointNumber>3</CapturePointNumber>
</c:CapturePointHUD>
<c:Fill>
<Percentage>0.80222018197612788</Percentage>
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
</c:Fill>
<c:Sprite>
@@ -231,6 +293,7 @@
<CapturePointNumber>4</CapturePointNumber>
</c:CapturePointHUD>
<c:Fill>
<Percentage>1</Percentage>
<Color A="0.699999988" B="1" G="0.200000003" R="0"/>
</c:Fill>
<c:Sprite>
@@ -286,7 +349,7 @@
<c:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon.png</DiffuseTexture>
<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:Transform>
<Position X="-1.58304751" Y="0.919596612" Z="0"/>
@@ -297,7 +360,8 @@
<Components>
<c:CapturePointHUD/>
<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:Sprite>
<DiffuseTexture>Textures/Core/UnitHexagon_Rotated.png</DiffuseTexture>
@@ -306,7 +370,7 @@
<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"/>
<Orientation X="0" Y="0" Z="4.71238899"/>
</c:Transform>
</Components>
<Children/>
@@ -369,6 +433,25 @@
</Entity>
</Children>
</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>
</Entity>
<Entity name="Hands">
@@ -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>
+9
View File
@@ -51,8 +51,17 @@
<xs:element ref="c:Page" minOccurs="0"/>
<xs:element ref="c:Button" 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: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:complexType>
</xs:element>
@@ -40,7 +40,6 @@ layout (binding = 10) uniform sampler2D SpecularMapTexture3;
layout (binding = 11) uniform sampler2D GlowMapTexture1;
layout (binding = 12) uniform sampler2D GlowMapTexture2;
layout (binding = 13) uniform sampler2D GlowMapTexture3;
layout (binding = 13) uniform sampler2D GlowMapTexture3;
layout (binding = 31) uniform samplerCube ShieldBuffer;
#define TILE_SIZE 16
+84 -82
View File
@@ -17,105 +17,107 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
EntityAABB& boxA = *boundingBox;
bool everHitTheGround = false;
auto prevPosIt = m_PrevPositions.find(entity);
if (prevPosIt != m_PrevPositions.end()) {
glm::vec3 size = boxA.Size();
float diameter = std::min(size.x, size.z);
glm::vec3 prevOrigin = prevPosIt->second;
glm::vec3 toCurrentPos = boxA.Origin() - prevOrigin;
float rayLength = glm::length(toCurrentPos) + 0.5f*diameter;
//If the entity has moved farther than the size of its box, we need to handle it specially.
if (rayLength > diameter) {
Ray ray(prevOrigin, toCurrentPos);
m_OctreeResult.clear();
m_Octree->ObjectsPossiblyHitByRay(ray, m_OctreeResult);
for (auto& boxB : m_OctreeResult) {
if (boxA.Entity == boxB.Entity) {
continue;
}
bool hit;
float dist;
if (boxB.Entity.HasComponent("Model")) {
RawModel* model;
std::string res = (std::string)boxB.Entity["Model"]["Resource"];
try {
model = ResourceManager::Load<RawModel, true>(res);
} catch (const std::exception&) {
if (entity == LocalPlayer) {
auto prevPosIt = m_PrevPositions.find(entity);
if (prevPosIt != m_PrevPositions.end()) {
glm::vec3 size = boxA.Size();
float diameter = std::min(size.x, size.z);
glm::vec3 prevOrigin = prevPosIt->second;
glm::vec3 toCurrentPos = boxA.Origin() - prevOrigin;
float rayLength = glm::length(toCurrentPos) + 0.5f*diameter;
//If the entity has moved farther than the size of its box, we need to handle it specially.
if (rayLength > diameter) {
Ray ray(prevOrigin, toCurrentPos);
m_OctreeResult.clear();
m_Octree->ObjectsPossiblyHitByRay(ray, m_OctreeResult);
for (auto& boxB : m_OctreeResult) {
if (boxA.Entity == boxB.Entity) {
continue;
}
float u, v;
hit = Collision::RayVsModel(ray, model->Vertices(), model->m_Indices, Transform::ModelMatrix(boxB.Entity), dist, u, v);
} else {
hit = Collision::RayVsAABB(ray, boxB, dist);
}
if (hit && dist < rayLength) {
//Set the entity to where it was colliding, minus the maximum box size.
//TODO: Perhaps this should be done slightly more properly.
glm::vec3 newOriginPos = ray.Origin() + (dist - 0.707107f*diameter) * ray.Direction();
glm::vec3 resolve = newOriginPos - boxA.Origin();
(glm::vec3&)cTransform["Position"] += resolve;
boxA = *Collision::EntityAbsoluteAABB(entity);
if (resolve.y > 0) {
everHitTheGround = true;
(bool)cPhysics["IsOnGround"] = true;
((glm::vec3&)cPhysics["Velocity"]).y = 0.f;
bool hit;
float dist;
if (boxB.Entity.HasComponent("Model")) {
RawModel* model;
std::string res = (std::string)boxB.Entity["Model"]["Resource"];
try {
model = ResourceManager::Load<RawModel, true>(res);
} catch (const std::exception&) {
continue;
}
float u, v;
hit = Collision::RayVsModel(ray, model->Vertices(), model->m_Indices, Transform::ModelMatrix(boxB.Entity), dist, u, v);
} else {
hit = Collision::RayVsAABB(ray, boxB, dist);
}
if (hit && dist < rayLength) {
//Set the entity to where it was colliding, minus the maximum box size.
//TODO: Perhaps this should be done slightly more properly.
glm::vec3 newOriginPos = ray.Origin() + (dist - 0.707107f*diameter) * ray.Direction();
glm::vec3 resolve = newOriginPos - boxA.Origin();
(glm::vec3&)cTransform["Position"] += resolve;
boxA = *Collision::EntityAbsoluteAABB(entity);
if (resolve.y > 0) {
everHitTheGround = true;
(bool)cPhysics["IsOnGround"] = true;
((glm::vec3&)cPhysics["Velocity"]).y = 0.f;
}
break;
}
break;
}
}
}
}
// Collide against octree items
m_OctreeResult.clear();
m_Octree->ObjectsInSameRegion(*boundingBox, m_OctreeResult);
for (auto& boxB : m_OctreeResult) {
glm::vec3 resolutionVector;
if (boxA.Entity == boxB.Entity) {
continue;
}
if (boxB.Entity.HasComponent("Model") && Collision::AABBVsAABB(boxA, boxB)) {
//Here we know boxB is a entity with Collideable, AABB, and Model.
RawModel* model;
try {
model = ResourceManager::Load<RawModel, true>(boxB.Entity["Model"]["Resource"]);
} catch (const std::exception&) {
// Collide against octree items
m_OctreeResult.clear();
m_Octree->ObjectsInSameRegion(*boundingBox, m_OctreeResult);
for (auto& boxB : m_OctreeResult) {
glm::vec3 resolutionVector;
if (boxA.Entity == boxB.Entity) {
continue;
}
glm::mat4 modelMatrix = Transform::ModelMatrix(boxB.Entity);
if (boxB.Entity.HasComponent("Model") && Collision::AABBVsAABB(boxA, boxB)) {
//Here we know boxB is a entity with Collideable, AABB, and Model.
RawModel* model;
try {
model = ResourceManager::Load<RawModel, true>(boxB.Entity["Model"]["Resource"]);
} catch (const std::exception&) {
continue;
}
glm::vec3 inOutVelocity = (glm::vec3)cPhysics["Velocity"];
bool notMovingxz = glm::all(glm::lessThan(glm::abs(glm::vec2(inOutVelocity.x, inOutVelocity.z)), glm::vec2(0.01f))) && prevPosIt != m_PrevPositions.end();
bool isOnGround = (bool)cPhysics["IsOnGround"];
float verticalStepHeight = (float)(double)cPhysics["VerticalStepHeight"];
if (Collision::AABBvsTriangles(boxA, model->Vertices(), model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) {
//Move the position to previous position if it is not moving in the xz-plane, else resolve with the resolution vector.
(glm::vec3&)cTransform["Position"] += notMovingxz ? prevPosIt->second - boxA.Origin() : resolutionVector;
glm::mat4 modelMatrix = Transform::ModelMatrix(boxB.Entity);
glm::vec3 inOutVelocity = (glm::vec3)cPhysics["Velocity"];
bool notMovingxz = glm::all(glm::lessThan(glm::abs(glm::vec2(inOutVelocity.x, inOutVelocity.z)), glm::vec2(0.01f))) && prevPosIt != m_PrevPositions.end();
bool isOnGround = (bool)cPhysics["IsOnGround"];
float verticalStepHeight = (float)(double)cPhysics["VerticalStepHeight"];
if (Collision::AABBvsTriangles(boxA, model->Vertices(), model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) {
//Move the position to previous position if it is not moving in the xz-plane, else resolve with the resolution vector.
(glm::vec3&)cTransform["Position"] += notMovingxz ? prevPosIt->second - boxA.Origin() : resolutionVector;
boxA = *Collision::EntityAbsoluteAABB(entity);
cPhysics["Velocity"] = inOutVelocity;
if (isOnGround) {
everHitTheGround = true;
(bool)cPhysics["IsOnGround"] = true;
}
}
} else if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) {
//Enter here if boxB has no Model.
(glm::vec3&)cTransform["Position"] += resolutionVector;
boxA = *Collision::EntityAbsoluteAABB(entity);
cPhysics["Velocity"] = inOutVelocity;
if (isOnGround) {
if (resolutionVector.y > 0) {
everHitTheGround = true;
(bool)cPhysics["IsOnGround"] = true;
((glm::vec3&)cPhysics["Velocity"]).y = 0.f;
}
}
} else if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) {
//Enter here if boxB has no Model.
(glm::vec3&)cTransform["Position"] += resolutionVector;
boxA = *Collision::EntityAbsoluteAABB(entity);
if (resolutionVector.y > 0) {
everHitTheGround = true;
(bool)cPhysics["IsOnGround"] = true;
((glm::vec3&)cPhysics["Velocity"]).y = 0.f;
}
}
}
//This should apply air friction and such, iff zero models were hit.
if (!everHitTheGround) {
(bool)cPhysics["IsOnGround"] = false;
}
//This should apply air friction and such, iff zero models were hit.
if (!everHitTheGround) {
(bool)cPhysics["IsOnGround"] = false;
}
m_PrevPositions[entity] = boxA.Origin();
m_PrevPositions[entity] = boxA.Origin();
}
}
+14 -280
View File
@@ -1,291 +1,25 @@
#include "Core/EntityFile.h"
EntityFile::EntityFile(boost::filesystem::path path)
: m_FilePath(path)
EntityFile::EntityFile(std::string path)
{
using namespace xercesc;
XMLPlatformUtils::Initialize();
m_GrammarPool = new XMLGrammarPoolImpl();
m_SAX2XMLReader = XMLReaderFactory::createXMLReader(XMLPlatformUtils::fgMemoryManager, m_GrammarPool);
}
EntityXMLFile* xml = ResourceManager::Load<EntityXMLFile>(path);
EntityFile::~EntityFile()
{
delete m_SAX2XMLReader;
delete m_GrammarPool;
xercesc::XMLPlatformUtils::Terminate();
}
EntityXMLFilePreprocessor preprocessor(xml);
preprocessor.RegisterComponents(this);
void EntityFile::Parse(const EntityFileHandler* handler) const
{
using namespace xercesc;
EntityXMLFileParser parser(xml);
m_RootEntity = parser.MergeEntities(this);
EntityFileSAXHandler saxHandler(handler, m_SAX2XMLReader);
setReaderFeatures(m_SAX2XMLReader);
m_SAX2XMLReader->setContentHandler(&saxHandler);
m_SAX2XMLReader->setErrorHandler(&saxHandler);
m_SAX2XMLReader->setDeclarationHandler(&saxHandler);
m_SAX2XMLReader->parse(m_FilePath.string().c_str());
}
void EntityFile::setReaderFeatures(xercesc::SAX2XMLReader* reader)
{
using namespace xercesc;
reader->setFeature(XMLUni::fgXercesCacheGrammarFromParse, true);
reader->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true);
reader->setFeature(XMLUni::fgSAX2CoreValidation, true);
reader->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
reader->setFeature(XMLUni::fgXercesSchema, true);
reader->setFeature(XMLUni::fgXercesSchemaFullChecking, true);
reader->setFeature(XMLUni::fgXercesCalculateSrcOfs, true);
reader->setFeature(XMLUni::fgXercesIdentityConstraintChecking, true);
}
unsigned int EntityFile::GetTypeStride(std::string typeName)
{
std::map<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;
}
if (m_RootEntity == EntityID_Invalid) {
ResourceManager::Release("EntityXMLFile", path);
throw Resource::FailedLoadingException("Failed to merge entities; root entity is invalid");
}
std::string uri = XS::ToString(_uri);
if (m_StateStack.top() == State::Entity) {
if (uri == "components") {
m_StateStack.push(State::Component);
onStartComponent(name);
return;
}
}
if (m_StateStack.top() == State::Component) {
m_StateStack.push(State::ComponentField);
onStartComponentField(name, attrs);
return;
}
ResourceManager::Release("EntityXMLFile", path);
}
void EntityFileSAXHandler::endElement(const XMLCh* const _uri, const XMLCh* const _localName, const XMLCh* const _qname)
EntityWrapper EntityFile::MergeInto(World* other)
{
std::string name = XS::ToString(_localName);
if (m_StateStack.top() == State::Entity) {
if (name == "Entity") {
m_StateStack.pop();
onEndEntity();
return;
}
}
std::string uri = XS::ToString(_uri);
if (m_StateStack.top() == State::Component) {
//if (uri == "components") {
m_StateStack.pop();
onEndComponent(name);
return;
//}
}
if (m_StateStack.top() == State::ComponentField && name == m_CurrentField) {
m_StateStack.pop();
onEndComponentField(name);
return;
}
}
void EntityFileSAXHandler::characters(const XMLCh* const chars, const XMLSize_t length)
{
if (m_StateStack.top() == State::ComponentField) {
char* transcoded = xercesc::XMLString::transcode(chars);
onFieldData(transcoded);
}
}
void EntityFileSAXHandler::fatalError(const xercesc::SAXParseException& e)
{
std::string message = XS::ToString(e.getMessage());
std::string systemId = XS::ToString(e.getSystemId());
XMLFileLoc line = e.getLineNumber();
XMLFileLoc column = e.getColumnNumber();
LOG_ERROR("SAXParseException\n\tLocation: %s:%i:%i\n\tFatal Error: %s", systemId.c_str(), line, column, message.c_str());
}
void EntityFileSAXHandler::error(const xercesc::SAXParseException& e)
{
std::string message = XS::ToString(e.getMessage());
std::string systemId = XS::ToString(e.getSystemId());
XMLFileLoc line = e.getLineNumber();
XMLFileLoc column = e.getColumnNumber();
LOG_ERROR("SAXParseException\n\tLocation: %s:%i:%i\n\tError: %s", systemId.c_str(), line, column, message.c_str());
}
void EntityFileSAXHandler::warning(const xercesc::SAXParseException& e)
{
std::string message = XS::ToString(e.getMessage());
std::string systemId = XS::ToString(e.getSystemId());
XMLFileLoc line = e.getLineNumber();
XMLFileLoc column = e.getColumnNumber();
LOG_ERROR("SAXParseException\n\tLocation: %s:%i:%i\n\tWarning: %s", systemId.c_str(), line, column, message.c_str());
}
void EntityFileSAXHandler::onStartEntity(const xercesc::Attributes& attrs)
{
EntityID parent = m_EntityStack.top();
if (m_Handler->m_OnStartEntityCallback) {
std::string name;
auto xName = attrs.getValue(XS::ToXMLCh("name"));
if (xName != nullptr) {
name = XS::ToString(xName);
}
m_Handler->m_OnStartEntityCallback(m_NextEntityID, parent, name);
}
m_EntityStack.push(m_NextEntityID);
m_NextEntityID++;
}
void EntityFileSAXHandler::onEndEntity()
{
m_EntityStack.pop();
}
void EntityFileSAXHandler::onStartEntityRef(const xercesc::Attributes& attrs)
{
std::string path = XS::ToString(attrs.getValue(XS::ToXMLCh("file")));
xercesc::SAX2XMLReader* reader = xercesc::XMLReaderFactory::createXMLReader();
EntityFile::setReaderFeatures(reader);
reader->setContentHandler(this);
reader->setErrorHandler(this);
reader->parse(path.c_str());
delete reader;
}
void EntityFileSAXHandler::onStartComponentField(const std::string& field, const xercesc::Attributes& attrs)
{
//LOG_DEBUG(" Field: %s", field.c_str());
m_CurrentField = field;
m_CurrentAttributes.clear();
for (int i = 0; i < attrs.getLength(); i++) {
auto name = attrs.getQName(i);
auto value = attrs.getValue(name);
//LOG_DEBUG(" %s = %s", (char*)XS::ToString(name), (char*)XS::ToString(value));
m_CurrentAttributes[XS::ToString(name).operator std::string()] = XS::ToString(value).operator std::string();
}
if (m_Handler->m_OnStartFieldCallback) {
m_Handler->m_OnStartFieldCallback(m_EntityStack.top(), m_CurrentComponent, field, m_CurrentAttributes);
}
}
void EntityFileSAXHandler::onEndComponent(const std::string& name) { }
void EntityFileSAXHandler::onStartComponent(const std::string& name)
{
//LOG_DEBUG(" Component: %s", name.c_str());
m_CurrentComponent = name;
if (m_Handler->m_OnStartComponentCallback) {
m_Handler->m_OnStartComponentCallback(m_EntityStack.top(), name);
}
}
void EntityFileSAXHandler::onEndComponentField(const std::string& field) { }
void EntityFileSAXHandler::onFieldData(char* data)
{
//LOG_DEBUG(" Data: %s", data);
if (m_Handler->m_OnStartFieldDataCallback) {
m_Handler->m_OnStartFieldDataCallback(m_EntityStack.top(), m_CurrentComponent, m_CurrentField, data);
}
xercesc::XMLString::release(&data);
}
auto mapping = other->Merge(this);
return EntityWrapper(other, mapping.at(m_RootEntity));
}
-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)
{
EntityFileHandler handler;
handler.SetStartComponentCallback(std::bind(&EntityFilePreprocessor::onStartComponent, this, std::placeholders::_1, std::placeholders::_2));
handler.SetStartComponentCallback(std::bind(&EntityXMLFilePreprocessor::onStartComponent, this, std::placeholders::_1, std::placeholders::_2));
m_EntityFile->Parse(&handler);
//LOG_DEBUG("___ COMPONENT DEFINITIONS ___");
@@ -28,20 +28,20 @@ EntityFilePreprocessor::EntityFilePreprocessor(const EntityFile* entityFile)
parseDefaults();
}
void EntityFilePreprocessor::RegisterComponents(World* world)
void EntityXMLFilePreprocessor::RegisterComponents(World* world)
{
for (auto& kv : m_ComponentInfo) {
world->RegisterComponent(kv.second);
}
}
void EntityFilePreprocessor::onStartComponent(EntityID entity, std::string type)
void EntityXMLFilePreprocessor::onStartComponent(EntityID entity, std::string type)
{
//LOG_DEBUG("Component: %s", type.c_str());
m_ComponentCounts[type]++;
}
void EntityFilePreprocessor::parseComponentInfo()
void EntityXMLFilePreprocessor::parseComponentInfo()
{
using namespace xercesc;
EntityFileXMLErrorHandler errorHandler;
@@ -141,9 +141,9 @@ void EntityFilePreprocessor::parseComponentInfo()
std::string baseType = XS::ToString(elementDeclaration->getTypeDefinition()->getBaseType()->getName());
std::string effectiveType = type;
unsigned int stride = EntityFile::GetTypeStride(type);
unsigned int stride = EntityXMLFile::GetTypeStride(type);
if (stride == 0) {
stride = EntityFile::GetTypeStride(baseType);
stride = EntityXMLFile::GetTypeStride(baseType);
if (stride == 0) {
LOG_WARNING("Field \"%s\" in component \"%s\" uses unexpected field type \"%s\" with base type \"%s\". Skipping.", name.c_str(), compInfo.Name.c_str(), type.c_str(), baseType.c_str());
continue;
@@ -196,7 +196,7 @@ void EntityFilePreprocessor::parseComponentInfo()
}
}
void EntityFilePreprocessor::parseDefaults()
void EntityXMLFilePreprocessor::parseDefaults()
{
using namespace xercesc;
@@ -261,7 +261,7 @@ void EntityFilePreprocessor::parseDefaults()
auto attribItem = attributeMap->item(i);
attributes[XS::ToString(attribItem->getNodeName())] = XS::ToString(attribItem->getNodeValue());
}
EntityFile::WriteAttributeData(data, field, attributes);
EntityXMLFile::WriteAttributeData(data, field, attributes);
}
auto childNode = fieldElement->getFirstChild();
@@ -278,14 +278,14 @@ void EntityFilePreprocessor::parseDefaults()
// Handle potential field values
if (childNode->getNodeType() == DOMNode::TEXT_NODE) {
char* cstrValue = XMLString::transcode(childNode->getNodeValue());
EntityFile::WriteValueData(data, field, cstrValue);
EntityXMLFile::WriteValueData(data, field, cstrValue);
XMLString::release(&cstrValue);
}
}
}
}
std::string EntityFilePreprocessor::parseAnnotationXML(const XMLCh* xml)
std::string EntityXMLFilePreprocessor::parseAnnotationXML(const XMLCh* xml)
{
using namespace xercesc;
@@ -1,13 +1,13 @@
#include "Core/EntityFileWriter.h"
#include "Core/EntityXMLFileWriter.h"
#define X(str) XS::ToXMLCh(str)
void EntityFileWriter::WriteWorld(World* world)
void EntityXMLFileWriter::WriteWorld(World* world)
{
WriteEntity(world, 0);
}
void EntityFileWriter::WriteEntity(World* world, EntityID entity)
void EntityXMLFileWriter::WriteEntity(World* world, EntityID entity)
{
using namespace xercesc;
DOMDocument* doc = m_DOMImplementation->createDocument(nullptr, X("Entity"), nullptr);
@@ -41,7 +41,7 @@ void EntityFileWriter::WriteEntity(World* world, EntityID entity)
doc->release();
}
void EntityFileWriter::appendEntityChildren(xercesc::DOMElement* parentElement, const World* world, EntityID entity)
void EntityXMLFileWriter::appendEntityChildren(xercesc::DOMElement* parentElement, const World* world, EntityID entity)
{
using namespace xercesc;
DOMDocument* doc = parentElement->getOwnerDocument();
@@ -67,7 +67,7 @@ void EntityFileWriter::appendEntityChildren(xercesc::DOMElement* parentElement,
}
}
void EntityFileWriter::appentEntityComponents(xercesc::DOMElement* parentElement, const World* world, EntityID entity)
void EntityXMLFileWriter::appentEntityComponents(xercesc::DOMElement* parentElement, const World* world, EntityID entity)
{
using namespace xercesc;
DOMDocument* doc = parentElement->getOwnerDocument();
+2 -2
View File
@@ -33,8 +33,8 @@ void _LOG(_LOG_LEVEL logLevel, const char* file, const char* func, unsigned int
va_end(args);
if (logLevel == LOG_LEVEL_ERROR) {
//std::cerr << file << ":" << line << " " << func << std::endl;
//std::cerr << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl;
std::cerr << file << ":" << line << " " << func << std::endl;
std::cerr << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl;
} else {
std::cout << _LOG_LEVEL_PREFIX[logLevel] << message << std::endl;
}
+58 -1
View File
@@ -1,6 +1,7 @@
#include "Core/World.h"
#include "Core/EEntityDeleted.h"
#include "Core/EComponentDeleted.h"
#include "Core/EntityWrapper.h"
World::~World()
{
@@ -44,7 +45,7 @@ bool World::ValidEntity(EntityID entity) const
return m_EntityParents.find(entity) != m_EntityParents.end();
}
void World::RegisterComponent(ComponentInfo& ci)
void World::RegisterComponent(const ComponentInfo& ci)
{
if (m_ComponentPools.find(ci.Name) == m_ComponentPools.end()) {
m_ComponentPools[ci.Name] = new ComponentPool(ci);
@@ -151,6 +152,62 @@ std::string World::GetName(EntityID entity) const
}
}
EntityWrapper World::GetFirstEntityByName(const std::string& name)
{
auto itPair = GetDirectChildren(EntityID_Invalid);
for (auto it = itPair.first; it != itPair.second; it++) {
EntityID childEntityID = it->second;
EntityWrapper childEntity(this, childEntityID);
if (!childEntity.Valid()) {
continue;
}
EntityWrapper entityWithName = childEntity.Name() == name ? childEntity : childEntity.FirstChildByName(name);
if (entityWithName.Valid()) {
return entityWithName;
}
}
return EntityWrapper::Invalid;
}
std::unordered_map<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()
{
// TODO: Make EntityID generation smarter
+7 -7
View File
@@ -2,6 +2,7 @@
#include "Core/UniformScaleSystem.h"
#include "Editor/EditorRenderSystem.h"
#include "Editor/EditorWidgetSystem.h"
#include "Core/EntityFile.h"
EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame* renderFrame)
: System(params)
@@ -129,7 +130,7 @@ void EditorSystem::OnEntitySelected(EntityWrapper entity)
void EditorSystem::OnEntitySave(EntityWrapper entity, boost::filesystem::path filePath)
{
EntityFileWriter writer(filePath);
EntityXMLFileWriter writer(filePath);
writer.WriteEntity(entity.World, entity.ID);
}
@@ -260,12 +261,11 @@ EntityWrapper EditorSystem::importEntity(EntityWrapper parent, boost::filesystem
try {
auto entityFile = ResourceManager::Load<EntityFile>(filePath.string());
EntityFilePreprocessor fpp(entityFile);
fpp.RegisterComponents(parent.World);
EntityFileParser fp(entityFile);
EntityID newEntity = fp.MergeEntities(parent.World, parent.ID);
return EntityWrapper(parent.World, newEntity);
} catch (const std::exception&) {
EntityWrapper newEntity = entityFile->MergeInto(parent.World);
parent.World->SetParent(newEntity.ID, parent.ID);
return newEntity;
} catch (const std::exception& e) {
LOG_ERROR("Failed to import entity \"%s\": \"%s\"", filePath.string().c_str(), e.what());
return EntityWrapper::Invalid;
}
}
+33 -3
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_EPlayerSpawned, &Client::OnPlayerSpawned);
EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &Client::OnDoubleJump);
EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &Client::OnDashAbility);
EVENT_SUBSCRIBE_MEMBER(m_ESearchForServers, &Client::OnSearchForServers);
auto config = ResourceManager::Load<ConfigFile>("Config.ini");
m_Address = address;
@@ -143,6 +144,9 @@ void Client::parseMessageType(Packet& packet)
case MessageType::OnDoubleJump:
parseDoubleJump(packet);
break;
case MessageType::OnDashEffect:
parseDashEffect(packet);
break;
case MessageType::AmmoPickup:
parseAmmoPickup(packet);
break;
@@ -262,7 +266,7 @@ void Client::parseEntityDeletion(Packet & packet)
if (m_ServerIDToClientID.find(entityToDelete) != m_ServerIDToClientID.end()) {
EntityID localEntity = m_ServerIDToClientID.at(entityToDelete);
if (m_World->ValidEntity(localEntity)) {
if (m_World->HasComponent(localEntity,"Player")) {
if (m_World->HasComponent(localEntity, "Player")) {
Events::PlayerDeath e;
e.Player = EntityWrapper(m_World, localEntity);
m_EventBroker->Publish(e);
@@ -297,8 +301,22 @@ 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;
@@ -388,7 +406,7 @@ void Client::parseSnapshot(Packet& packet)
if (m_SnapshotFilter != nullptr) {
shouldApply = m_SnapshotFilter->FilterComponent(localEntity, newComponent);
}
if (shouldApply) {
if (shouldApply) {
ComponentWrapper currentComponent = m_World->GetComponent(localEntityID, componentType);
memcpy(currentComponent.Data, newComponent.Data, componentInfo.Stride);
}
@@ -518,6 +536,18 @@ bool Client::OnPlayerSpawned(const Events::PlayerSpawned& e)
return true;
}
bool Client::OnDashAbility(const Events::DashAbility& e)
{
if (!clientServerMapsHasEntity(e.Player) || e.Player != m_LocalPlayer.ID) {
return false;
}
Packet packet(MessageType::OnDashEffect);
packet.WritePrimitive(m_ClientIDToServerID.at(e.Player));
m_Reliable.Send(packet);
return true;
}
bool Client::OnSearchForServers(const Events::SearchForServers& e)
{
m_SearchingForServers = true;
+10 -4
View File
@@ -49,18 +49,24 @@ void Packet::WriteString(const std::string& str)
// Message, add one extra byte for null terminator
size_t sizeOfString = str.size() + 1;
if (m_Offset + sizeOfString > m_MaxPacketSize) {
//LOG_WARNING("Package::WriteString(): Data size in packet exceeded maximum package size. New size is %i bytes\n", m_MaxPacketSize*2);
if (m_MaxPacketSize >= 32000) {
LOG_WARNING("Package::WriteString(): New size is huge %i bytes\n", m_MaxPacketSize*2);
}
resizeData();
}
memcpy(m_Data + m_Offset, str.data(), sizeOfString * sizeof(char));
m_Offset += sizeOfString * sizeof(char);
memcpy(m_Data + m_Offset, str.data(), str.size() * sizeof(char));
m_Offset += str.size() * sizeof(char);
m_Data[m_Offset] = '\0';
m_Offset += 1;
}
void Packet::WriteData(char * data, int sizeOfData)
{
if (m_Offset + sizeOfData > m_MaxPacketSize) {
//LOG_WARNING("Packet::WriteData(): Data size in packet exceeded maximum packet size. New size is %i bytes\n", m_MaxPacketSize*2);
if (m_MaxPacketSize >= 32000) {
LOG_WARNING("Package::WriteData(): New size is huge %i bytes\n", m_MaxPacketSize*2);
}
while (m_Offset + sizeOfData > m_MaxPacketSize) {
resizeData();
}
+8
View File
@@ -141,6 +141,9 @@ void Server::parseMessageType(Packet& packet)
case MessageType::OnDoubleJump:
parseDoubleJump(packet);
break;
case MessageType::OnDashEffect:
parseDashEffect(packet);
break;
default:
break;
}
@@ -555,6 +558,11 @@ bool Server::parseDoubleJump(Packet & packet)
return true;
}
void Server::parseDashEffect(Packet& packet)
{
reliableBroadcast(packet);
}
void Server::parseOnInputCommand(Packet& packet)
{
PlayerID player = -1;
+4 -1
View File
@@ -74,7 +74,10 @@ size_t TCPClient::readBuffer()
boost::asio::ip::tcp::socket::message_peek, error);
unsigned int sizeOfPacket = 0;
memcpy(&sizeOfPacket, m_ReadBuffer, sizeof(int));
if (sizeOfPacket > m_Socket->available()) {
LOG_WARNING("TCPClient::readBuffer(): We haven't got the whole packet yet.");
return 0;
}
// if the buffer is to small increase the size of it
// TODO if message is huge 1 time the buffer will not decrease.
if (sizeOfPacket > m_BufferSize) {
+4 -1
View File
@@ -106,7 +106,10 @@ int TCPServer::readBuffer(PlayerDefinition & playerDefinition)
boost::asio::ip::tcp::socket::message_peek, error);
unsigned int sizeOfPacket = 0;
memcpy(&sizeOfPacket, m_ReadBuffer, sizeof(int));
if (sizeOfPacket > playerDefinition.TCPSocket->available()) {
LOG_WARNING("TCPServer::readBuffer(): We haven't got the whole packet yet.");
return 0;
}
// if the buffer is to small increase the size of it
if (sizeOfPacket > m_BufferSize) {
delete[] m_ReadBuffer;
+4 -1
View File
@@ -45,7 +45,10 @@ int UDPClient::readBuffer()
boost::asio::ip::udp::socket::message_peek, error);
int sizeOfPacket = 0;
memcpy(&sizeOfPacket, m_ReadBuffer, sizeof(int));
if (sizeOfPacket > m_Socket->available()) {
LOG_WARNING("UDPClient::readBuffer(): We haven't got the whole packet yet.");
return 0;
}
// if the buffer is to small increase the size of it
if (sizeOfPacket > m_BufferSize) {
delete[] m_ReadBuffer;
+5
View File
@@ -92,6 +92,11 @@ int UDPServer::readBuffer()
unsigned int sizeOfPacket = 0;
memcpy(&sizeOfPacket, m_ReadBuffer, sizeof(int));
if (sizeOfPacket > m_Socket->available()) {
LOG_WARNING("UDPServer::readBuffer(): We haven't got the whole packet yet.");
return 0;
}
// if the buffer is to small increase the size of it
if (sizeOfPacket > m_BufferSize) {
delete[] m_ReadBuffer;
+1 -1
View File
@@ -70,7 +70,7 @@ void FrameBuffer::Generate()
}
GLERROR("3");
GLenum* bufferTextures = &attachments[0];
GLenum* bufferTextures = attachments.data();
glDrawBuffers(attachments.size(), bufferTextures);
if (GLERROR("GLBufferAttachement error")) {
printf(": AttachmentSize %i", attachments.size());
+10 -5
View File
@@ -10,7 +10,9 @@
#include "Systems/SpawnerSystem.h"
#include "Systems/PlayerSpawnSystem.h"
#include "Systems/PlayerDeathSystem.h"
#include "Core/EntityFileWriter.h"
#include "Systems/FloatingEffectSystem.h"
#include "Core/EntityFile.h"
#include "Core/EntityXMLFileWriter.h"
#include "Game/Systems/CapturePointSystem.h"
#include "Game/Systems/CapturePointHUDSystem.h"
#include "Game/Systems/PickupSpawnSystem.h"
@@ -25,9 +27,11 @@
#include "Rendering/AnimationSystem.h"
#include "Network/MultiplayerSnapshotFilter.h"
#include "Game/Systems/AmmunitionHUDSystem.h"
#include "Game/Systems/AbilityCooldownHUDSystem.h"
#include "Game/Systems/CapturePointArrowHUDSystem.h"
#include "Game/Systems/KillFeedSystem.h"
#include "Game/Systems/BoostSystem.h"
#include "Game/Systems/BoostIconsHUDSystem.h"
#include "GUI/ButtonSystem.h"
#include "GUI/MainMenuSystem.h"
@@ -44,6 +48,7 @@ Game::Game(int argc, char* argv[])
ResourceManager::RegisterType<PNG>("Png");
ResourceManager::RegisterType<ShaderProgram>("ShaderProgram");
ResourceManager::RegisterType<EntityFile>("EntityFile");
ResourceManager::RegisterType<EntityXMLFile>("EntityXMLFile");
ResourceManager::RegisterType<Font>("FontFile");
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
@@ -80,10 +85,7 @@ Game::Game(int argc, char* argv[])
std::string mapToLoad = m_Config->Get<std::string>("Debug.LoadMap", "");
if (!mapToLoad.empty()) {
auto file = ResourceManager::Load<EntityFile>(mapToLoad);
EntityFilePreprocessor fpp(file);
fpp.RegisterComponents(m_World);
EntityFileParser fp(file);
fp.MergeEntities(m_World);
file->MergeInto(m_World);
}
// Create the sound manager
@@ -120,6 +122,7 @@ Game::Game(int argc, char* argv[])
++updateOrderLevel;
m_SystemPipeline->AddSystem<SoundSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<RaptorCopterSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<FloatingEffectSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<ExplosionEffectSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<HealthSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<PlayerMovementSystem>(updateOrderLevel);
@@ -133,6 +136,7 @@ Game::Game(int argc, char* argv[])
m_SystemPipeline->AddSystem<AmmoPickupSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<DamageIndicatorSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<AmmunitionHUDSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<AbilityCooldownHUDSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<CapturePointArrowHUDSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<KillFeedSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<LifetimeSystem>(updateOrderLevel);
@@ -146,6 +150,7 @@ Game::Game(int argc, char* argv[])
m_SystemPipeline->AddSystem<BoostSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<ButtonSystem>(updateOrderLevel, m_Renderer);
m_SystemPipeline->AddSystem<MainMenuSystem>(updateOrderLevel, m_Renderer);
m_SystemPipeline->AddSystem<BoostIconsHUDSystem>(updateOrderLevel);
// Populate Octree with collidables
++updateOrderLevel;
m_SystemPipeline->AddSystem<FillOctreeSystem>(updateOrderLevel, m_OctreeCollision, "Collidable");
+71 -80
View File
@@ -1,110 +1,101 @@
/*
Author: Vladimir Sedach.
Inspired by Original Author: Vladimir Sedach.
Purpose: demo of Call Stack creation by our own means,
and with MiniDumpWriteDump() function of DbgHelp.dll.
Purpose: demo of Call Stack creation by our own means,
and with MiniDumpWriteDump() function of DbgHelp.dll.
*/
#include "MiniDump.h"
#include <string>
#include <iostream>
#include <ctime>
#include <comdef.h>
#include <windows.h>
#include <tlhelp32.h>
//#include "dbghelp.h"
#pragma optimize("y", off) //generate stack frame pointers for all functions - same as /Oy- in the project
#pragma warning(disable: 4200) //nonstandard extension used : zero-sized array in struct/union
#pragma warning(disable: 4100) //unreferenced formal parameter
//#define DEBUG_DPRINTF 1 //allow d()
//#include "wfun.h"
#pragma optimize("y", off) //generate stack frame pointers for all functions - same as /Oy- in the project
#pragma warning(disable: 4200) //nonstandard extension used : zero-sized array in struct/union
#pragma warning(disable: 4100) //unreferenced formal parameter
// In case you don't have dbghelp.h.
#ifndef _DBGHELP_
typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
DWORD ThreadId;
PEXCEPTION_POINTERS ExceptionPointers;
BOOL ClientPointers;
} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;
typedef enum _MINIDUMP_TYPE {
MiniDumpNormal = 0x00000000,
MiniDumpWithDataSegs = 0x00000001,
} MINIDUMP_TYPE;
typedef BOOL (WINAPI * MINIDUMP_WRITE_DUMP)(
IN HANDLE hProcess,
IN DWORD ProcessId,
IN HANDLE hFile,
IN MINIDUMP_TYPE DumpType,
IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
IN PVOID UserStreamParam, OPTIONAL
IN PVOID CallbackParam OPTIONAL
);
#else
typedef BOOL (WINAPI * MINIDUMP_WRITE_DUMP)(
IN HANDLE hProcess,
IN DWORD ProcessId,
IN HANDLE hFile,
IN MINIDUMP_TYPE DumpType,
IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
IN PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
IN PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
);
#endif //#ifndef _DBGHELP_
HMODULE hDbgHelp;
MINIDUMP_WRITE_DUMP MiniDumpWriteDump_;
// Tool Help functions.
typedef HANDLE (WINAPI * CREATE_TOOL_HELP32_SNAPSHOT)(DWORD dwFlags, DWORD th32ProcessID);
typedef BOOL(WINAPI * MINIDUMP_WRITE_DUMP)(
IN HANDLE hProcess,
IN DWORD ProcessId,
IN HANDLE hFile,
IN MINIDUMP_TYPE DumpType,
IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
IN PVOID UserStreamParam, OPTIONAL
IN PVOID CallbackParam OPTIONAL
);
//*************************************************************************************
void WINAPI Create_Dump(PEXCEPTION_POINTERS pException, BOOL File_Flag, BOOL Show_Flag)
long WINAPI Create_Dump_Immediate(LPEXCEPTION_POINTERS pException)
//*************************************************************************************
// Create dump.
// pException can be either GetExceptionInformation() or NULL.
// If File_Flag = TRUE - write dump files (.dmz and .dmp) with the name of the current process.
// If Show_Flag = TRUE - show message with Get_Exception_Info() dump.
{
// Try to get MiniDumpWriteDump() address.
hDbgHelp = LoadLibrary("DBGHELP.DLL");
MiniDumpWriteDump_ = (MINIDUMP_WRITE_DUMP)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
HMODULE hDbgHelp = LoadLibrary("DBGHELP.DLL");
MINIDUMP_WRITE_DUMP MiniDumpWriteDump_ = (MINIDUMP_WRITE_DUMP)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
// If MiniDumpWriteDump() of DbgHelp.dll available.
if (MiniDumpWriteDump_)
{
HANDLE hDump_File;
CHAR Dump_Path[MAX_PATH];
// If MiniDumpWriteDump() of DbgHelp.dll available.
if (MiniDumpWriteDump_) {
// Get absolute path of current process: C:/ ... /name.exe
CHAR Dump_Path[MAX_PATH];
GetModuleFileName(NULL, Dump_Path, sizeof(Dump_Path));
std::string path(Dump_Path);
GetModuleFileName(NULL, Dump_Path, sizeof(Dump_Path)); //path of current process
// Get current time in a string.
std::time_t t = std::time(NULL);
char tStr[16];
std::strftime(tStr, 32, " %a %H-%M-%S", std::localtime(&t));
std::strftime(tStr, ARRAYSIZE(tStr), " %a %H-%M-%S", std::localtime(&t));
std::string time(tStr);
std::string path(Dump_Path);
// Remove the .exe from path
path = path.substr(0, path.length() - 4);
path += time + ".dmp";
// Add the current time and .dmp
path += "dump" + time + ".dmp";
MINIDUMP_EXCEPTION_INFORMATION M;
M.ThreadId = GetCurrentThreadId();
M.ExceptionPointers = pException;
M.ClientPointers = 0;
DWORD procId = GetCurrentProcessId();
DWORD threadId = GetCurrentThreadId();
hDump_File = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
MINIDUMP_EXCEPTION_INFORMATION M;
M.ThreadId = threadId;
M.ExceptionPointers = pException;
M.ClientPointers = TRUE;
MiniDumpWriteDump_(GetCurrentProcess(), GetCurrentProcessId(), hDump_File,
MiniDumpNormal, (pException) ? &M : NULL, NULL, NULL);
HANDLE hDump_File = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE process = GetCurrentProcess();
CloseHandle(hDump_File);
BOOL result = MiniDumpWriteDump_(process, procId, hDump_File
, (MINIDUMP_TYPE)(MiniDumpWithDataSegs |
MiniDumpWithHandleData |
MiniDumpScanMemory |
MiniDumpWithUnloadedModules |
MiniDumpWithIndirectlyReferencedMemory |
MiniDumpWithPrivateReadWriteMemory |
MiniDumpWithFullMemoryInfo |
MiniDumpWithThreadInfo |
MiniDumpIgnoreInaccessibleMemory)
, &M, NULL, NULL);
HRESULT error = (HRESULT)GetLastError();
std::cout << "Memory dumped to: \"" << path.c_str() << "\"";
MessageBox(NULL, ("Application crashed, memory dumped to: " + path).c_str(), "MiniDump", MB_ICONHAND | MB_OK);
CloseHandle(hDump_File);
if (!result) {
_com_error cErr(error);
HRESULT actualErrorCode = error & 0xFFFF;
char hexErrBuf[16];
std::sprintf(hexErrBuf, "0x%x", actualErrorCode);
std::cout << "Bad memory dump at: \"" << path.c_str() << "\"" << std::endl
<< "because MiniDumpWriteDump failed with error #" << actualErrorCode << " (" << hexErrBuf << "): \"" << cErr.ErrorMessage() << "\"" << std::endl;
MessageBox(NULL, "Application crashed, memory dump failed, but file was created.", "MiniDump", MB_ICONHAND | MB_OK);
} else {
std::cout << "Memory dumped to: \"" << path.c_str() << "\"" << std::endl;
MessageBox(NULL, ("Application crashed, memory dumped to: " + path).c_str(), "MiniDump", MB_ICONHAND | MB_OK);
}
} else {
MessageBox(NULL, "Application crashed, memory dump failed.", "MiniDump", MB_ICONHAND | MB_OK);
std::cout << "Memory dump failed because MiniDumpWriteDump is not available." << std::endl;
MessageBox(NULL, "Application crashed, could not create a memory dump.", "MiniDump", MB_ICONHAND | MB_OK);
}
// Basically, terminate the application.
return EXCEPTION_EXECUTE_HANDLER;
}
@@ -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.
}
}
}
}
}
+3 -4
View File
@@ -21,16 +21,15 @@ void AmmoPickupSystem::Update(double dt)
somePickup.DecreaseThisRespawnTimer -= dt;
if (somePickup.DecreaseThisRespawnTimer < 0.0) {
auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/AmmoPickup.xml");
EntityFileParser parser(entityFile);
EntityID ammoPickupID = parser.MergeEntities(m_World);
EntityWrapper ammoPickup = entityFile->MergeInto(m_World);
//let the world know a pickup has spawned
Events::PickupSpawned ePickupSpawned;
ePickupSpawned.Pickup = EntityWrapper(m_World, ammoPickupID);
ePickupSpawned.Pickup = ammoPickup;
m_EventBroker->Publish(ePickupSpawned);
//copy values from the old entity to the new entity
auto& newAmmoPickupEntity = EntityWrapper(m_World, ammoPickupID);
auto& newAmmoPickupEntity = ammoPickup;
newAmmoPickupEntity["Transform"]["Position"] = somePickup.Pos;
newAmmoPickupEntity["AmmoPickup"]["AmmoGain"] = somePickup.AmmoGain;
newAmmoPickupEntity["AmmoPickup"]["RespawnTimer"] = somePickup.RespawnTimer;
+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;
}
}
}
}
+3 -4
View File
@@ -39,10 +39,9 @@ bool BoostSystem::OnPlayerDamage(Events::PlayerDamage& e)
}
//load boost XML file, set it entity parented with the victim player
auto entityFile = ResourceManager::Load<EntityFile>(classXML);
EntityFileParser parser(entityFile);
EntityID boostAssaultEntity = parser.MergeEntities(m_World);
m_World->SetName(boostAssaultEntity, className);
m_World->SetParent(boostAssaultEntity, e.Victim.ID);
EntityWrapper boostAssaultEntity = entityFile->MergeInto(m_World);
m_World->SetName(boostAssaultEntity.ID, className);
m_World->SetParent(boostAssaultEntity.ID, e.Victim.ID);
return true;
}
+7 -9
View File
@@ -9,7 +9,7 @@ DamageIndicatorSystem::DamageIndicatorSystem(SystemParams params)
//load texture to cache
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) {
@@ -50,15 +50,13 @@ bool DamageIndicatorSystem::OnPlayerDamage(Events::PlayerDamage& e)
//load & set the "2d" sprite
auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/DamageIndicator.xml");
EntityFileParser parser(entityFile);
EntityID spriteID = parser.MergeEntities(m_World);
m_World->SetParent(spriteID, m_CurrentCamera);
auto spriteWrapper = EntityWrapper(m_World, spriteID);
EntityWrapper sprite = entityFile->MergeInto(m_World);
m_World->SetParent(sprite.ID, m_CurrentCamera);
//simply set the rotation z-wise to the angleBetweenVectors
spriteWrapper["Transform"]["Orientation"] = glm::vec3(0, 0, angleBetweenVectors);
sprite["Transform"]["Orientation"] = glm::vec3(0, 0, angleBetweenVectors);
if (!IsServer) {
updateDamageIndicatorVector.emplace_back(spriteWrapper, inflictorPos);
updateDamageIndicatorVector.emplace_back(sprite, inflictorPos);
}
return true;
@@ -127,8 +125,8 @@ glm::vec3 DamageIndicatorSystem::DamageIndicatorTest(EntityWrapper player) {
auto inflictorPos = glm::vec3(currentPos.x + testVar*6.0f, currentPos.y, currentPos.z + testVar2*6.0f);
//load the explosioneffect XML
auto deathEffect = ResourceManager::Load<EntityFile>("Schema/Entities/PlayerDeathExplosionWithCamera.xml");
EntityFileParser parser(deathEffect);
auto deathEffect = ResourceManager::Load<EntityXMLFile>("Schema/Entities/PlayerDeathExplosionWithCamera.xml");
EntityXMLFileParser parser(deathEffect);
EntityID deathEffectID = parser.MergeEntities(m_World);
EntityWrapper deathEffectEW = EntityWrapper(m_World, deathEffectID);
+3 -4
View File
@@ -19,16 +19,15 @@ void PickupSpawnSystem::Update(double dt)
if (somePickup.DecreaseThisRespawnTimer < 0.0) {
//spawn the new healthPickup
auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/HealthPickup.xml");
EntityFileParser parser(entityFile);
EntityID healthPickupID = parser.MergeEntities(m_World);
EntityWrapper healthPickup = entityFile->MergeInto(m_World);
//let the world know a pickup has spawned (graphics effects, etc)
Events::PickupSpawned ePickupSpawned;
ePickupSpawned.Pickup = EntityWrapper(m_World, healthPickupID);
ePickupSpawned.Pickup = healthPickup;
m_EventBroker->Publish(ePickupSpawned);
//copy values from the old entity to the new entity
auto& newHealthPickupEntity = EntityWrapper(m_World, healthPickupID);
auto& newHealthPickupEntity = healthPickup;
newHealthPickupEntity["Transform"]["Position"] = somePickup.Pos;
newHealthPickupEntity["HealthPickup"]["HealthGain"] = somePickup.HealthGain;
newHealthPickupEntity["HealthPickup"]["RespawnTimer"] = somePickup.RespawnTimer;
+22 -4
View File
@@ -4,6 +4,7 @@ PlayerDeathSystem::PlayerDeathSystem(SystemParams params)
: System(params)
{
EVENT_SUBSCRIBE_MEMBER(m_OnPlayerDeath, &PlayerDeathSystem::OnPlayerDeath);
EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &PlayerDeathSystem::OnEntityDeleted);
}
void PlayerDeathSystem::Update(double dt)
@@ -27,10 +28,8 @@ bool PlayerDeathSystem::OnPlayerDeath(Events::PlayerDeath& e)
void PlayerDeathSystem::createDeathEffect(EntityWrapper player)
{
//load the explosioneffect XML
auto deathEffect = ResourceManager::Load<EntityFile>("Schema/Entities/PlayerDeathExplosionWithCamera.xml");
EntityFileParser parser(deathEffect);
EntityID deathEffectID = parser.MergeEntities(m_World);
EntityWrapper deathEffectEW = EntityWrapper(m_World, deathEffectID);
auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/PlayerDeathExplosionWithCamera.xml");
EntityWrapper deathEffectEW = entityFile->MergeInto(m_World);
//components that we need from player
auto playerModel = player.FirstChildByName("PlayerModel");
@@ -59,9 +58,28 @@ void PlayerDeathSystem::createDeathEffect(EntityWrapper player)
//camera (with lifetime) behind the player
if (player == LocalPlayer) {
m_LocalPlayerDeathEffect = deathEffectEW;
auto cam = deathEffectEW.FirstChildByName("Camera");
Events::SetCamera eSetCamera;
eSetCamera.CameraEntity = cam;
m_EventBroker->Publish(eSetCamera);
}
}
bool PlayerDeathSystem::OnEntityDeleted(Events::EntityDeleted& e)
{
// We only care about when the local players death effect is removed.
if (m_LocalPlayerDeathEffect.ID != e.DeletedEntity) {
return false;
}
// Look for the spectator camera entity in the level.
EntityWrapper spectatorCam = m_World->GetFirstEntityByName("SpectatorCamera");
if (!spectatorCam.Valid() || !spectatorCam.HasComponent("Camera") || LocalPlayer.Valid()) {
return false;
}
Events::SetCamera eSetCamera;
eSetCamera.CameraEntity = spectatorCam;
m_EventBroker->Publish(eSetCamera);
return true;
}
+35 -17
View File
@@ -5,6 +5,7 @@ PlayerMovementSystem::PlayerMovementSystem(SystemParams params)
{
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &PlayerMovementSystem::OnPlayerSpawned);
EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &PlayerMovementSystem::OnDoubleJump);
EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &PlayerMovementSystem::OnDashAbility);
}
PlayerMovementSystem::~PlayerMovementSystem()
@@ -17,14 +18,9 @@ PlayerMovementSystem::~PlayerMovementSystem()
void PlayerMovementSystem::Update(double dt)
{
updateMovementControllers(dt);
if (IsServer) {
for (auto& kv : m_PlayerInputControllers) {
updateVelocity(kv.first, dt);
}
} else {
if (LocalPlayer.Valid()) {
updateVelocity(LocalPlayer, dt);
}
// Only do physics calculations on client and only for themselves.
if (IsClient && LocalPlayer.Valid()) {
updateVelocity(LocalPlayer, dt);
}
}
@@ -72,7 +68,7 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
ComponentWrapper cPhysics = player["Physics"];
//Assault Dash Check
if (player.HasComponent("DashAbility")) {
controller->AssaultDashCheck(dt, ((glm::vec3)cPhysics["Velocity"]).y != 0.0f, player["DashAbility"]["CoolDownMaxTimer"], player["DashAbility"]["CoolDownTimer"]);
controller->AssaultDashCheck(dt, ((glm::vec3)cPhysics["Velocity"]).y != 0.0f, player["DashAbility"]["CoolDownMaxTimer"], player["DashAbility"]["CoolDownTimer"], player.ID);
}
wishDirection = controller->Movement() * glm::inverse(glm::quat(ori));
//this makes sure you can only dash in the 4 directions: forw,backw,left,right
@@ -313,11 +309,11 @@ bool PlayerMovementSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
bool PlayerMovementSystem::OnDoubleJump(Events::DoubleJump & e)
{
// If entity does not exist, exit
if (!EntityWrapper(m_World, e.entityID).Valid()) {
if (!EntityWrapper(m_World, e.entityID).Valid()) {
return false;
}
// If entity IsLocalPlayer, exit
if (e.entityID == m_LocalPlayer.ID) {
if (e.entityID == m_LocalPlayer.ID) {
return false;
}
spawnHexagon(EntityWrapper(m_World, e.entityID));
@@ -325,11 +321,33 @@ bool PlayerMovementSystem::OnDoubleJump(Events::DoubleJump & e)
}
void PlayerMovementSystem::spawnHexagon(EntityWrapper target)
{
{
//put a hexagon at the entitys... feet?
auto hexagonEffect = ResourceManager::Load<EntityFile>("Schema/Entities/DoubleJumpHexagon.xml");
EntityFileParser parser(hexagonEffect);
EntityID hexagonEffectID = parser.MergeEntities(m_World);
EntityWrapper hexagonEW = EntityWrapper(m_World, hexagonEffectID);
auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/DoubleJumpHexagon.xml");
EntityWrapper hexagonEW = entityFile->MergeInto(m_World);
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");
m_NetworkEnabled = config->Get("Networking.StartNetwork", false);
m_ForcedRespawnTime = config->Get("Debug.RespawnTime", -1.0f);
m_DbgConfigForceRespawn = m_ForcedRespawnTime > 0;
m_DbgConfigForceRespawn = m_ForcedRespawnTime > 0 && IsServer;
}
void PlayerSpawnSystem::Update(double dt)
@@ -26,7 +26,21 @@ void PlayerSpawnSystem::Update(double dt)
// Increase timer.
double& timer = (double&)modeComponent["RespawnTime"];
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) {
return;
}
@@ -54,7 +68,14 @@ void PlayerSpawnSystem::Update(double dt)
// If the spawner has a team affiliation, check it
if (spawner.HasComponent("Team")) {
if ((int)spawner["Team"]["Team"] != req.Team) {
auto cSpawnerTeam = spawner["Team"];
if ((int)cSpawnerTeam["Team"] != req.Team) {
// Increase num spawned players if someone picks spectator, since it is valid to pick spectator
// but don't spawn anything, goto next spawnrequest.
if (req.Team == (int)cSpawnerTeam["Team"].Enum("Spectator")) {
++numSpawnedPlayers;
break;
}
continue;
}
}
@@ -75,9 +96,9 @@ void PlayerSpawnSystem::Update(double dt)
}
}
if (numSpawnedPlayers != (int)m_SpawnRequests.size()) {
LOG_DEBUG("%i players were supposed to be spawned, but %i was spawned.", (int)m_SpawnRequests.size(), numSpawnedPlayers);
LOG_DEBUG("%i players were supposed to be spawned or set as spectator, but only %i was handled.", (int)m_SpawnRequests.size(), numSpawnedPlayers);
} else {
LOG_DEBUG("%i players were spawned.", numSpawnedPlayers);
LOG_DEBUG("%i players were spawned or set as spectator.", numSpawnedPlayers);
}
m_SpawnRequests.clear();
}
@@ -88,24 +109,29 @@ bool PlayerSpawnSystem::OnInputCommand(Events::InputCommand& e)
return false;
}
if (e.Value == 0) {
return false;
}
// A dead client should be able to swap to the spectator camera.
if (IsClient && !LocalPlayer.Valid()) {
// Set the spectator camera as active, if it exists.
// Find the camera.
EntityWrapper spectatorCam = m_World->GetFirstEntityByName("SpectatorCamera");
if (spectatorCam.Valid() && spectatorCam.HasComponent("Camera")) {
Events::SetCamera eSetCamera;
eSetCamera.CameraEntity = spectatorCam;
m_EventBroker->Publish(eSetCamera);
}
}
// Team picks should be processed ONLY server-side!
// Don't make a spawn request if we're the client.
if (!IsServer && m_NetworkEnabled) {
return false;
}
if (e.Value == 0) {
return false;
}
//TODO: Spectating?
//Right now, return if someone picks spectator.
//1 signifies spectator here, could not get Playerteam component since it may be invalid or without team comp.
if ((ComponentInfo::EnumType)e.Value == 1) {
return false;
}
//Check if the player already requested spawn.
// Check if the player already requested spawn.
auto iter = m_SpawnRequests.begin();
for (; iter != m_SpawnRequests.end(); ++iter) {
if (iter->PlayerID == e.PlayerID) {
@@ -114,11 +140,11 @@ bool PlayerSpawnSystem::OnInputCommand(Events::InputCommand& e)
}
if (iter != m_SpawnRequests.end()) {
//If player is in queue to spawn, then change their team affiliation in the request.
// If player is in queue to spawn, then change their team affiliation in the request.
iter->Team = (ComponentInfo::EnumType)e.Value;
} else if (m_PlayerEntities.count(e.PlayerID) == 0 || !m_PlayerEntities[e.PlayerID].Valid()) {
//If player is not in queue to spawn, then create a spawn request,
//but only if they are spectating and/or just connected.
// If player is not in queue to spawn, then create a spawn request,
// but only if they are spectating and/or just connected.
SpawnRequest req;
req.PlayerID = e.PlayerID;
req.Team = (ComponentInfo::EnumType)e.Value;
+8 -6
View File
@@ -17,15 +17,17 @@ EntityWrapper SpawnerSystem::Spawn(EntityWrapper spawner, EntityWrapper parent /
// Load the entity file and parse it
const std::string& entityFilePath = spawner["Spawner"]["EntityFile"];
auto entityFile = ResourceManager::Load<EntityFile>(entityFilePath);
if (entityFile == nullptr) {
EntityWrapper spawnedEntity;
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;
}
EntityFileParser parser(entityFile);
EntityWrapper spawnedEntity(world, parser.MergeEntities(world, parent.ID));
//If the spawned entity is collideable, then we must not spawn it where it collides with something that
//has a dontCollideComponent attached.
// If the spawned entity is collidable, then we must not spawn it where it collides with something that
// has a dontCollideComponent attached.
bool spawnOnCollidable = dontCollideComponent.empty() || !spawnedEntity.HasComponent("Collidable");
if (!spawnOnCollidable) {
boost::optional<EntityAABB> optBox = Collision::EntityAbsoluteAABB(spawnedEntity);
+4 -15
View File
@@ -1,27 +1,16 @@
#include "Game.h"
#include "MiniDump.h"
LONG WINAPI CrashHandler(EXCEPTION_POINTERS* pException);
int main(int argc, char* argv[])
{
::SetUnhandledExceptionFilter(CrashHandler);
SetUnhandledExceptionFilter(Create_Dump_Immediate);
Game game(argc, argv);
while (game.Running()) {
PerformanceTimer::StartTimer("Game-Tick");
PerformanceTimer::StartTimer("Game-Tick");
game.Tick();
PerformanceTimer::StopTimer("Game-Tick");
PerformanceTimer::StopTimer("Game-Tick");
}
return 0;
return 0;
}
LONG WINAPI CrashHandler(EXCEPTION_POINTERS* pException)
{
//Take minidump. path should be bin/TacticalZ.dmp
//Then show MessageBox, and exit application.
Create_Dump(pException, 1, 1);
return EXCEPTION_EXECUTE_HANDLER;// EXCEPTION_CONTINUE_SEARCH
}
+5 -5
View File
@@ -7,7 +7,7 @@ using boost::unit_test_framework::test_case;
#include "Collision/TriggerSystem.h"
#include "Collision/CollisionSystem.h"
#include "Core/EntityFileWriter.h"
#include "Core/EntityXMLFileWriter.h"
#include "Game/Systems/CapturePointSystem.h"
BOOST_AUTO_TEST_SUITE(CapturePointTestSuite)
@@ -82,7 +82,7 @@ bool CapturePointTest::CapturePoint_Game_Loop_OneHundredTimes() {
CapturePointTest::CapturePointTest(int runTestNumber)
{
ResourceManager::RegisterType<ConfigFile>("ConfigFile");
ResourceManager::RegisterType<EntityFile>("EntityFile");
ResourceManager::RegisterType<EntityXMLFile>("EntityFile");
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
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);
//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");
EntityFilePreprocessor fpp(file);
auto file = ResourceManager::Load<EntityXMLFile>("Schema/Entities/TeamTest.xml");
EntityXMLFilePreprocessor fpp(file);
fpp.RegisterComponents(m_World);
EntityFileParser fp(file);
EntityXMLFileParser fp(file);
fp.MergeEntities(m_World);
EntityID playerID = m_World->CreateEntity();
+4 -4
View File
@@ -9,12 +9,12 @@
#include "Input/KeyboardInputHandler.h"
#include "Input/MouseInputHandler.h"
#include "Core/EKeyDown.h"
#include "Core/EntityFile.h"
#include "Core/EntityXMLFile.h"
#include "Core/SystemPipeline.h"
#include "Core/EntityFilePreprocessor.h"
#include "Core/EntityFileParser.h"
#include "Core/EntityFileWriter.h"
#include "Core/EntityXMLFilePreprocessor.h"
#include "Core/EntityXMLFileParser.h"
#include "Core/EntityXMLFileWriter.h"
#include "Engine/Collision/ETrigger.h"
+4 -4
View File
@@ -30,7 +30,7 @@ BOOST_AUTO_TEST_SUITE_END()
GameHealthSystemTest::GameHealthSystemTest()
{
ResourceManager::RegisterType<ConfigFile>("ConfigFile");
ResourceManager::RegisterType<EntityFile>("EntityFile");
ResourceManager::RegisterType<EntityXMLFile>("EntityFile");
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1));
@@ -41,10 +41,10 @@ GameHealthSystemTest::GameHealthSystemTest()
// Create a world
m_World = new World();
auto file = ResourceManager::Load<EntityFile>("Schema/Entities/TeamTest.xml");
EntityFilePreprocessor fpp(file);
auto file = ResourceManager::Load<EntityXMLFile>("Schema/Entities/TeamTest.xml");
EntityXMLFilePreprocessor fpp(file);
fpp.RegisterComponents(m_World);
EntityFileParser fp(file);
EntityXMLFileParser fp(file);
fp.MergeEntities(m_World);
// Create system pipeline
+1 -1
View File
@@ -11,7 +11,7 @@
#include "Input/KeyboardInputHandler.h"
#include "Input/MouseInputHandler.h"
#include "Core/EKeyDown.h"
#include "Core/EntityFile.h"
#include "Core/EntityXMLFile.h"
#include "Core/SystemPipeline.h"
#include "Editor/EditorSystem.h"
+4 -4
View File
@@ -30,7 +30,7 @@ BOOST_AUTO_TEST_SUITE_END()
PickupSpawnTest::PickupSpawnTest(int runTestNumber)
{
ResourceManager::RegisterType<ConfigFile>("ConfigFile");
ResourceManager::RegisterType<EntityFile>("EntityFile");
ResourceManager::RegisterType<EntityXMLFile>("EntityFile");
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1));
@@ -44,10 +44,10 @@ PickupSpawnTest::PickupSpawnTest(int runTestNumber)
m_SystemPipeline->AddSystem<PickupSpawnSystem>(1);
//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/HealthPickup.xml");
EntityFilePreprocessor fpp(file);
auto file = ResourceManager::Load<EntityXMLFile>("Schema/Entities/HealthPickup.xml");
EntityXMLFilePreprocessor fpp(file);
fpp.RegisterComponents(m_World);
EntityFileParser fp(file);
EntityXMLFileParser fp(file);
//connect the healthpickup to the world
m_HealthPickupID = fp.MergeEntities(m_World);
+5 -5
View File
@@ -9,12 +9,12 @@
#include "Input/KeyboardInputHandler.h"
#include "Input/MouseInputHandler.h"
#include "Core/EKeyDown.h"
#include "Core/EntityFile.h"
#include "Core/EntityXMLFile.h"
#include "Core/SystemPipeline.h"
#include "Core/EntityFilePreprocessor.h"
#include "Core/EntityFileParser.h"
#include "Core/EntityFileWriter.h"
#include "Core/EntityXMLFilePreprocessor.h"
#include "Core/EntityXMLFileParser.h"
#include "Core/EntityXMLFileWriter.h"
#include "Engine/Collision/ETrigger.h"
@@ -29,7 +29,7 @@
//#include <tuple>
#include "Collision/TriggerSystem.h"
#include "Collision/CollisionSystem.h"
#include "Core/EntityFileWriter.h"
#include "Core/EntityXMLFileWriter.h"
#include "Game/Systems/HealthSystem.h"
#include "Game/Systems/PickupSpawnSystem.h"