Compare commits

..

18 Commits

Author SHA1 Message Date
Jace 36f6ade87a Fixed editor keyboard shortcuts getting mixed up with GUI input actions 2016-03-01 13:38:51 +01:00
Jace 0c60b637c3 Who's merging without compiling? 2016-02-26 12:52:10 +01:00
William Moberg d411de894f Merge pull request #140 from teamfisk/FixNetworkBugs
Death explosion should always get triggered now.
2016-02-26 12:01:19 +01:00
Jocke 18450ff4f3 Death explosion should always get triggered now. (I hope) 2016-02-26 11:08:05 +01:00
William Moberg 22b473a0b6 Merge pull request #139 from teamfisk/EditorCopyPaste
Editor copy paste
2016-02-26 11:01:18 +01:00
Jace f161fce719 Merge pull request #138 from teamfisk/PlayerAtOriginFix
Teleporting to origin on spawn fixed.
2016-02-25 17:55:03 +01:00
Jace 0343683678 Fixed cubemaps being generated over and over again each frame. 2016-02-25 17:51:40 +01:00
Jace 9e6c67596d Basic editor copy and paste. Doesn't actually copy the entity until you paste it. 2016-02-25 17:51:28 +01:00
William Moberg 89d0d5753f Fix for player teleporting to (0,0,0). Saves player previous position in CollisionSystem instead of Physics component so it won't be saved when editing Players. 2016-02-25 16:16:24 +01:00
Adam Byléhn 748a178801 Merge pull request #136 from teamfisk/FixNetworkBugs
Fix network bugs
2016-02-25 16:09:08 +01:00
Jocke eac9a9daf6 Pull request #136 Merge remote-tracking branch 'origin/master' into FixNetworkBugs
# Conflicts:
#	src/Engine/Network/Client.cpp
2016-02-25 16:07:06 +01:00
Jocke 059fe5c6c0 Fixed typo m_EPDoubleJump to m_EDoubleJump. 2016-02-25 16:04:27 +01:00
Joachim Pettersson fb465ede81 Merge pull request #134 from teamfisk/HUDDesync
Good job! 👍
2016-02-25 15:53:07 +01:00
Jocke f66fa7a183 Merge remote-tracking branch 'origin/master' into FixNetworkBugs
# Conflicts:
#	include/Engine/Network/Client.h
#	include/Engine/Network/MessageType.h
#	include/Engine/Network/Server.h
#	include/Engine/Network/TCPServer.h
#	src/Engine/Network/Client.cpp
#	src/Engine/Network/TCPServer.cpp
2016-02-25 15:13:11 +01:00
Jocke 508d8a6f00 Fixed memory leak in TCPServer::AcceptNewConnections caused by acceptor->async_accept().
Fixed some formating and comments.
2016-02-25 14:24:38 +01:00
stiffly 8ce6308649 In snapshot: now sends player information and also CP information. Now it is no longer true that they will arrive in pre order. Appropriate actions were therefor implemented. 2016-02-25 11:56:40 +01:00
stiffly f10958c268 Capturepoint logic is now purely done on the serverside. 2016-02-25 11:50:29 +01:00
Jocke fa13c1d065 Double jump is now working. 2016-02-23 18:24:46 +01:00
41 changed files with 345 additions and 4806 deletions
@@ -24,6 +24,7 @@ public:
private: private:
Octree<EntityAABB>* m_Octree; Octree<EntityAABB>* m_Octree;
std::vector<EntityAABB> m_OctreeResult; std::vector<EntityAABB> m_OctreeResult;
std::unordered_map<EntityWrapper, glm::vec3> m_PrevPositions;
}; };
#endif #endif
+2
View File
@@ -29,6 +29,7 @@ struct EntityWrapper
EntityWrapper Parent(); EntityWrapper Parent();
EntityWrapper FirstChildByName(const std::string& name); EntityWrapper FirstChildByName(const std::string& name);
EntityWrapper FirstParentWithComponent(const std::string& componentType); EntityWrapper FirstParentWithComponent(const std::string& componentType);
EntityWrapper Clone(EntityWrapper parent = EntityWrapper::Invalid);
bool IsChildOf(EntityWrapper potentialParent); bool IsChildOf(EntityWrapper potentialParent);
bool Valid() const; bool Valid() const;
@@ -39,6 +40,7 @@ struct EntityWrapper
private: private:
EntityWrapper firstChildByNameRecursive(const std::string& name, EntityID parent); EntityWrapper firstChildByNameRecursive(const std::string& name, EntityID parent);
EntityWrapper cloneRecursive(EntityWrapper entity, EntityWrapper parent);
}; };
namespace std namespace std
+1 -1
View File
@@ -119,7 +119,7 @@ public:
m_ExtraMemory.push_back((char*)malloc(m_Stride)); m_ExtraMemory.push_back((char*)malloc(m_Stride));
//We should preferably not enter here to avoid performance issues. Set more numMaxElements in constructor instead. //We should preferably not enter here to avoid performance issues. Set more numMaxElements in constructor instead.
if (!DisableMemoryPool::Value) { 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()); LOG_DEBUG("Allocated slots exceed Pool size, extra memory allocated dynamically. Pool size: %u, dynamic size: %u.", m_NumSlots, m_ExtraMemory.size());
} }
return m_ExtraMemory.back(); return m_ExtraMemory.back();
} }
+1 -1
View File
@@ -40,7 +40,7 @@ public:
// Change the parent of an entity // Change the parent of an entity
void SetParent(EntityID entity, EntityID parent); void SetParent(EntityID entity, EntityID parent);
// Get children of an entity // Get children of an entity
const std::pair<std::unordered_multimap<EntityID, EntityID>::const_iterator, std::unordered_multimap<EntityID, EntityID>::const_iterator> GetChildren(EntityID entity); const std::pair<std::unordered_multimap<EntityID, EntityID>::const_iterator, std::unordered_multimap<EntityID, EntityID>::const_iterator> GetDirectChildren(EntityID entity);
// Get all component pools // Get all component pools
const std::unordered_map<std::string, ComponentPool*>& GetComponentPools() const { return m_ComponentPools; } const std::unordered_map<std::string, ComponentPool*>& GetComponentPools() const { return m_ComponentPools; }
// Get the entity children map // Get the entity children map
+8
View File
@@ -73,6 +73,12 @@ public:
// Called when the user means to rename an entity. // Called when the user means to rename an entity.
typedef std::function<void(EntityWrapper, const std::string&)> OnEntityChangeName_t; typedef std::function<void(EntityWrapper, const std::string&)> OnEntityChangeName_t;
void SetEntityChangeNameCallback(OnEntityChangeName_t f) { m_OnEntityChangeName = f; } void SetEntityChangeNameCallback(OnEntityChangeName_t f) { m_OnEntityChangeName = f; }
// Called when the user pastes an entity previously "copied"
// @param EntityWrapper The entity to copy
// @param EntityWrapper The entity to parent the new copy to
// @return The new copy of the entity
typedef std::function<EntityWrapper(EntityWrapper, EntityWrapper)> OnEntityPaste_t;
void SetEntityPasteCallback(OnEntityPaste_t f) { m_OnEntityPaste = f; }
// Called when the user means to attach a new component to an entity. // Called when the user means to attach a new component to an entity.
typedef std::function<void(EntityWrapper, const std::string&)> OnComponentAttach_t; typedef std::function<void(EntityWrapper, const std::string&)> OnComponentAttach_t;
void SetComponentAttachCallback(OnComponentAttach_t f) { m_OnComponentAttach = f; } void SetComponentAttachCallback(OnComponentAttach_t f) { m_OnComponentAttach = f; }
@@ -111,6 +117,7 @@ private:
std::string m_DroppedFile = ""; std::string m_DroppedFile = "";
bool m_Paused = false; bool m_Paused = false;
bool m_MouseLocked = false; bool m_MouseLocked = false;
EntityWrapper m_CopyTarget = EntityWrapper::Invalid;
// Callbacks // Callbacks
OnEntitySelectedCallback_t m_OnEntitySelected = nullptr; OnEntitySelectedCallback_t m_OnEntitySelected = nullptr;
@@ -124,6 +131,7 @@ private:
OnComponentDelete_t m_OnComponentDelete = nullptr; OnComponentDelete_t m_OnComponentDelete = nullptr;
OnWidgetMode_t m_OnWidgetMode = nullptr; OnWidgetMode_t m_OnWidgetMode = nullptr;
OnWidgetSpace_t m_OnWidgetSpace = nullptr; OnWidgetSpace_t m_OnWidgetSpace = nullptr;
OnEntityPaste_t m_OnEntityPaste = nullptr;
// Events // Events
EventRelay<EditorGUI, Events::KeyDown> m_EKeyDown; EventRelay<EditorGUI, Events::KeyDown> m_EKeyDown;
+1
View File
@@ -56,6 +56,7 @@ private:
void OnEntityDelete(EntityWrapper entity); void OnEntityDelete(EntityWrapper entity);
void OnEntityChangeParent(EntityWrapper entity, EntityWrapper parent); void OnEntityChangeParent(EntityWrapper entity, EntityWrapper parent);
void OnEntityChangeName(EntityWrapper entity, const std::string& name); void OnEntityChangeName(EntityWrapper entity, const std::string& name);
EntityWrapper OnEntityPaste(EntityWrapper entityToCopy, EntityWrapper parent);
void OnComponentAttach(EntityWrapper entity, const std::string& componentType); void OnComponentAttach(EntityWrapper entity, const std::string& componentType);
void OnComponentDelete(EntityWrapper entity, const std::string& componentType); void OnComponentDelete(EntityWrapper entity, const std::string& componentType);
void OnWidgetSpace(EditorGUI::WidgetSpace widgetSpace); void OnWidgetSpace(EditorGUI::WidgetSpace widgetSpace);
@@ -192,8 +192,6 @@ bool FirstPersonInputController<EventContext>::OnLockMouse(const Events::LockMou
template <typename EventContext> template <typename EventContext>
void FirstPersonInputController<EventContext>::AssaultDashCheck(double dt, bool isJumping, double assaultDashCoolDownMaxTimer) { void FirstPersonInputController<EventContext>::AssaultDashCheck(double dt, bool isJumping, double assaultDashCoolDownMaxTimer) {
ImGui::Text(std::to_string(m_AssaultDashCoolDownTimer).c_str());
m_AssaultDashDoubleTapDeltaTime += dt; m_AssaultDashDoubleTapDeltaTime += dt;
m_AssaultDashCoolDownTimer -= dt; m_AssaultDashCoolDownTimer -= dt;
//cooldown = assaultDashCoolDownMaxTimer sec, pretend the dash lasts 0.25 sec (for friction to do its work) //cooldown = assaultDashCoolDownMaxTimer sec, pretend the dash lasts 0.25 sec (for friction to do its work)
+8 -5
View File
@@ -19,8 +19,10 @@
#include "Core/World.h" #include "Core/World.h"
#include "Core/EventBroker.h" #include "Core/EventBroker.h"
#include "Core/ConfigFile.h" #include "Core/ConfigFile.h"
#include "Core/EPlayerDeath.h"
#include "Input/EInputCommand.h" #include "Input/EInputCommand.h"
#include "Core/EPlayerDamage.h" #include "Core/EPlayerDamage.h"
#include "../Game/Events/EDoubleJump.h"
#include "Network/EInterpolate.h" #include "Network/EInterpolate.h"
#include "Network/SnapshotFilter.h" #include "Network/SnapshotFilter.h"
#include "Core/EPlayerSpawned.h" #include "Core/EPlayerSpawned.h"
@@ -47,7 +49,9 @@ public:
void Connect(std::string address, int port); void Connect(std::string address, int port);
void Update() override; void Update() override;
private:
UDPClient m_Unreliable;
TCPClient m_Reliable;
std::vector<Events::PlayerSpawned> m_PlayerSpawnEvents; std::vector<Events::PlayerSpawned> m_PlayerSpawnEvents;
void parseSpawnEvents(); void parseSpawnEvents();
// Save for children // Save for children
@@ -101,9 +105,9 @@ public:
void parseEntityDeletion(Packet& packet); void parseEntityDeletion(Packet& packet);
void parsePlayerDamage(Packet& packet); void parsePlayerDamage(Packet& packet);
void parseComponentDeletion(Packet& packet); void parseComponentDeletion(Packet& packet);
void parseDoubleJump(Packet& packet);
void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType); void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType);
void parseSnapshot(Packet& packet); void parseSnapshot(Packet& packet);
void UpdateLocalCapturePointHUD(EntityWrapper capturePointHUD);
void identifyPacketLoss(); void identifyPacketLoss();
void hasServerTimedOut(); void hasServerTimedOut();
EntityID createPlayer(); EntityID createPlayer();
@@ -127,11 +131,10 @@ public:
EventRelay<Client, Events::PlayerSpawned> m_EPlayerSpawned; EventRelay<Client, Events::PlayerSpawned> m_EPlayerSpawned;
bool OnPlayerSpawned(const Events::PlayerSpawned& e); bool OnPlayerSpawned(const Events::PlayerSpawned& e);
EventRelay< Client, Events::SearchForServers> m_ESearchForServers; EventRelay< Client, Events::SearchForServers> m_ESearchForServers;
EventRelay<Client, Events::DoubleJump> m_EDoubleJump;
bool OnDoubleJump(Events::DoubleJump & e);
bool OnSearchForServers(const Events::SearchForServers& e); bool OnSearchForServers(const Events::SearchForServers& e);
private:
UDPClient m_Unreliable;
UDPClient m_ServerlistRequest; UDPClient m_ServerlistRequest;
TCPClient m_Reliable;
std::vector<ServerInfo> m_Serverlist; std::vector<ServerInfo> m_Serverlist;
bool m_SearchingForServers = false; bool m_SearchingForServers = false;
std::clock_t m_StartSearchTime; std::clock_t m_StartSearchTime;
+1
View File
@@ -19,6 +19,7 @@ enum class MessageType
EntityDeleted, EntityDeleted,
ComponentDeleted, ComponentDeleted,
PlayerTransform, PlayerTransform,
OnDoubleJump,
ServerlistRequest, ServerlistRequest,
Invalid Invalid
}; };
+2 -2
View File
@@ -24,7 +24,7 @@ public:
{ {
// Check if we are trying to add more than the package can fit. // Check if we are trying to add more than the package can fit.
if (m_MaxPacketSize < m_Offset + sizeof(T)) { 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); LOG_WARNING("Packet AddPrimitive(): You are trying to add more than we have allocated for! New size is %i bytes\n", m_MaxPacketSize*2);
resizeData(); resizeData();
} }
memcpy(m_Data + m_Offset, &val, sizeof(T)); memcpy(m_Data + m_Offset, &val, sizeof(T));
@@ -35,7 +35,7 @@ public:
T ReadPrimitive() T ReadPrimitive()
{ {
if (m_Offset < m_ReturnDataOffset + sizeof(T)) { if (m_Offset < m_ReturnDataOffset + sizeof(T)) {
//LOG_WARNING("Packet PopFrontPrimitive(): You are trying to remove more than what exists in this packet!"); LOG_WARNING("Packet PopFrontPrimitive(): You are trying to remove more than what exists in this packet!");
return -1; return -1;
} }
T returnValue; T returnValue;
+4 -3
View File
@@ -8,7 +8,6 @@
#include "Network/TCPServer.h" #include "Network/TCPServer.h"
#include "Network/UDPServer.h" #include "Network/UDPServer.h"
#include "Network/UDPClient.h" //LOL
#include "Network/MessageType.h" #include "Network/MessageType.h"
#include "Network/PlayerDefinition.h" #include "Network/PlayerDefinition.h"
#include "Core/World.h" #include "Core/World.h"
@@ -18,6 +17,7 @@
#include "Core/EPlayerDamage.h" #include "Core/EPlayerDamage.h"
#include "Network/EPlayerDisconnected.h" #include "Network/EPlayerDisconnected.h"
#include "Core/EPlayerSpawned.h" #include "Core/EPlayerSpawned.h"
#include "../Game/Events/EDoubleJump.h"
#include "Core/EEntityDeleted.h" #include "Core/EEntityDeleted.h"
#include "Core/EComponentDeleted.h" #include "Core/EComponentDeleted.h"
@@ -81,8 +81,9 @@ private:
void parseOnInputCommand(Packet& packet); void parseOnInputCommand(Packet& packet);
void parseClientPing(); void parseClientPing();
void parsePing(); void parsePing();
void parseUDPConnect(Packet & packet); bool parseDoubleJump(Packet& packet);
void parseTCPConnect(Packet & packet); void parseUDPConnect(Packet& packet);
void parseTCPConnect(Packet& packet);
void parseDisconnect(); void parseDisconnect();
void parseServerlistRequest(boost::asio::ip::udp::endpoint endpoint); void parseServerlistRequest(boost::asio::ip::udp::endpoint endpoint);
bool shouldSendToClient(EntityWrapper childEntity); bool shouldSendToClient(EntityWrapper childEntity);
+2 -3
View File
@@ -25,10 +25,9 @@ private:
std::unique_ptr<boost::asio::ip::tcp::acceptor> acceptor; std::unique_ptr<boost::asio::ip::tcp::acceptor> acceptor;
boost::shared_ptr<boost::asio::ip::tcp::socket> lastReceivedSocket; boost::shared_ptr<boost::asio::ip::tcp::socket> lastReceivedSocket;
void handle_accept(boost::shared_ptr<boost::asio::ip::tcp::socket> socket,
int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers,
const boost::system::error_code& error);
int readBuffer(PlayerDefinition& playerDefinition); int readBuffer(PlayerDefinition& playerDefinition);
PlayerID getPlayerIDFromEndpoint(const std::map<PlayerID, PlayerDefinition>& connectedPlayers,
boost::asio::ip::address address, unsigned short port);
int GetPort(); int GetPort();
std::string GetAddress(); std::string GetAddress();
int m_Port = 0; int m_Port = 0;
+1 -1
View File
@@ -8,7 +8,7 @@ namespace Events
struct DoubleJump : public Event struct DoubleJump : public Event
{ {
EntityID entityID;
}; };
} }
+2 -12
View File
@@ -20,24 +20,14 @@ public:
private: private:
EventRelay<AmmoPickupSystem, Events::TriggerTouch> m_ETriggerTouch; EventRelay<AmmoPickupSystem, Events::TriggerTouch> m_ETriggerTouch;
bool OnTriggerTouch(Events::TriggerTouch& e); bool OnTriggerTouch(Events::TriggerTouch& e);
EventRelay<AmmoPickupSystem, Events::TriggerLeave> m_ETriggerLeave;
bool OnTriggerLeave(Events::TriggerLeave& e);
struct NewPickup { struct NewAmmoPickup {
glm::vec3 Pos; glm::vec3 Pos;
double AmmoGain; double AmmoGain;
double RespawnTimer; double RespawnTimer;
double DecreaseThisRespawnTimer; double DecreaseThisRespawnTimer;
EntityID parentID; EntityID parentID;
bool isAmmoPickup;
}; };
struct EntityAtMaxValuePickupStruct { std::vector<NewAmmoPickup> m_ETriggerTouchVector;
EntityWrapper player;
EntityWrapper pickup;
};
std::vector<NewPickup> m_ETriggerTouchVector;
std::vector<EntityAtMaxValuePickupStruct> m_PickupAtMaximum;
void DoPickup(EntityWrapper &player, EntityWrapper &trigger);
}; };
#endif #endif
+1 -11
View File
@@ -27,7 +27,7 @@ public:
private: private:
bool m_NetworkEnabled; bool m_NetworkEnabled;
// methods which will take care of specific events // methods which will take care of specific events
EventRelay<HealthSystem, Events::PlayerDamage> m_EPlayerDamage; EventRelay<HealthSystem, Events::PlayerDamage> m_EPlayerDamage;
bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e); bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e);
EventRelay<HealthSystem, Events::PlayerHealthPickup> m_EPlayerHealthPickup; EventRelay<HealthSystem, Events::PlayerHealthPickup> m_EPlayerHealthPickup;
@@ -37,16 +37,6 @@ private:
//vector which will keep track of health changes //vector which will keep track of health changes
std::vector<std::tuple<EntityID, double>> m_DeltaHealthVector; std::vector<std::tuple<EntityID, double>> m_DeltaHealthVector;
struct DeadPlayers {
EntityWrapper playerEntity;
double timeSinceDeath;
DeadPlayers(EntityWrapper entity) : playerEntity(entity) {
timeSinceDeath = 0.0;
}
};
std::vector<DeadPlayers> m_DeadPlayers;
}; };
#endif #endif
@@ -34,9 +34,13 @@ private:
glm::vec3 m_LastPosition = glm::vec3(); glm::vec3 m_LastPosition = glm::vec3();
// The logic for making the sound play when player is moving // The logic for making the sound play when player is moving
void playerStep(double dt); void playerStep(double dt);
// Spawn a hexagon at origin of an Entity
void spawnHexagon(EntityWrapper target);
EventRelay<PlayerMovementSystem, Events::PlayerSpawned> m_EPlayerSpawned; EventRelay<PlayerMovementSystem, Events::PlayerSpawned> m_EPlayerSpawned;
bool OnPlayerSpawned(Events::PlayerSpawned& e); bool OnPlayerSpawned(Events::PlayerSpawned& e);
EventRelay<PlayerMovementSystem, Events::DoubleJump> m_EDoubleJump;
bool PlayerMovementSystem::OnDoubleJump(Events::DoubleJump & e);
void updateMovementControllers(double dt); void updateMovementControllers(double dt);
void updateVelocity(EntityWrapper player, double dt); void updateVelocity(EntityWrapper player, double dt);
-4
View File
@@ -21,7 +21,6 @@ private:
{ {
int PlayerID; int PlayerID;
ComponentInfo::EnumType Team; ComponentInfo::EnumType Team;
double timeSinceDeath;
}; };
bool m_NetworkEnabled = false; bool m_NetworkEnabled = false;
@@ -41,7 +40,4 @@ private:
bool OnPlayerSpawned(Events::PlayerSpawned& e); bool OnPlayerSpawned(Events::PlayerSpawned& e);
EventRelay<PlayerSpawnSystem, Events::PlayerDeath> m_OnPlayerDeath; EventRelay<PlayerSpawnSystem, Events::PlayerDeath> m_OnPlayerDeath;
bool OnPlayerDeath(Events::PlayerDeath& e); bool OnPlayerDeath(Events::PlayerDeath& e);
std::vector<SpawnRequest> m_LatePlayersVector;
void CheckForLatePlayers(double dt);
}; };
-1
View File
@@ -2,7 +2,6 @@
<Physics xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Physics.xsd"> <Physics xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Physics.xsd">
<Velocity X="0" Y="0" Z="0"/> <Velocity X="0" Y="0" Z="0"/>
<Gravity>true</Gravity> <Gravity>true</Gravity>
<PrevOrigin X="-9876.5" Y="-9876.5" Z="-9876.5"/>
<IsOnGround>false</IsOnGround> <IsOnGround>false</IsOnGround>
<VerticalStepHeight>0.33</VerticalStepHeight> <VerticalStepHeight>0.33</VerticalStepHeight>
</Physics> </Physics>
-1
View File
@@ -13,7 +13,6 @@
<xs:annotation><xs:documentation>m/s^2</xs:documentation></xs:annotation> <xs:annotation><xs:documentation>m/s^2</xs:documentation></xs:annotation>
</xs:element> </xs:element>
<xs:element name="Gravity" type="t:bool" minOccurs="0"/> <xs:element name="Gravity" type="t:bool" minOccurs="0"/>
<xs:element name="PrevOrigin" type="t:Vector" minOccurs="0"/>
<xs:element name="IsOnGround" type="t:bool" minOccurs="0"/> <xs:element name="IsOnGround" type="t:bool" minOccurs="0"/>
<xs:element name="VerticalStepHeight" type="t:double" minOccurs="0"> <xs:element name="VerticalStepHeight" type="t:double" minOccurs="0">
<xs:annotation><xs:documentation>The largest height of a "stair-step" that can be walked over</xs:documentation></xs:annotation> <xs:annotation><xs:documentation>The largest height of a "stair-step" that can be walked over</xs:documentation></xs:annotation>
File diff suppressed because it is too large Load Diff
-1
View File
@@ -13,7 +13,6 @@
<c:DashAbility/> <c:DashAbility/>
<c:Health/> <c:Health/>
<c:Physics> <c:Physics>
<PrevOrigin X="0" Y="0.772000015" Z="0"/>
<Velocity X="2.30999646e-23" Y="0" Z="1.05272533e-23"/> <Velocity X="2.30999646e-23" Y="0" Z="1.05272533e-23"/>
</c:Physics> </c:Physics>
<c:Player> <c:Player>
-1
View File
@@ -13,7 +13,6 @@
<c:DashAbility/> <c:DashAbility/>
<c:Health/> <c:Health/>
<c:Physics> <c:Physics>
<PrevOrigin X="0" Y="0.772000015" Z="0"/>
<Velocity X="2.30999646e-23" Y="0" Z="1.05272533e-23"/> <Velocity X="2.30999646e-23" Y="0" Z="1.05272533e-23"/>
</c:Physics> </c:Physics>
<c:Player> <c:Player>
+2 -23
View File
@@ -215,8 +215,7 @@
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>Models\Core\UnitCube.mesh</Resource> <Resource>Models\Core\UnitCube.mesh</Resource>
<Color A="0.300000012" B="1" G="0" R="0"/> <Color A="1" B="1" G="0.200000003" R="0"/>
<Transparent>true</Transparent>
</c:Model> </c:Model>
<c:Team> <c:Team>
<Team> <Team>
@@ -242,8 +241,7 @@
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>Models\Core\UnitCube.mesh</Resource> <Resource>Models\Core\UnitCube.mesh</Resource>
<Color A="0.300000012" B="0" G="0" R="1"/> <Color A="1" B="1" G="1" R="0"/>
<Transparent>true</Transparent>
</c:Model> </c:Model>
<c:Team> <c:Team>
<Team> <Team>
@@ -258,25 +256,6 @@
</Components> </Components>
<Children/> <Children/>
</Entity> </Entity>
<Entity>
<Components>
<c:AmmoPickup/>
<c:Model>
<Resource>Models/Props/PickUps/AmmoPickUp.mesh</Resource>
</c:Model>
<c:RaptorCopter>
<Speed>8</Speed>
<Axis X="0" Y="0.100000001" Z="0"/>
</c:RaptorCopter>
<c:Transform>
<Position X="0" Y="1.86800003" Z="0"/>
<Scale X="0.600000024" Y="0.600000024" Z="0.600000024"/>
<Orientation X="0" Y="18741" Z="0"/>
</c:Transform>
<c:Trigger/>
</Components>
<Children/>
</Entity>
</Children> </Children>
</Entity> </Entity>
+45 -43
View File
@@ -16,51 +16,51 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
EntityAABB& boxA = *boundingBox; EntityAABB& boxA = *boundingBox;
bool everHitTheGround = false; bool everHitTheGround = false;
glm::vec3 size = boxA.Size(); auto prevPosIt = m_PrevPositions.find(entity);
float diameter = std::min(size.x, size.z); if (prevPosIt != m_PrevPositions.end()) {
glm::vec3 prevOrigin = (glm::vec3)cPhysics["PrevOrigin"]; glm::vec3 size = boxA.Size();
glm::vec3 toCurrentPos = boxA.Origin() - prevOrigin; float diameter = std::min(size.x, size.z);
float rayLength = glm::length(toCurrentPos) + 0.5f*diameter; glm::vec3 prevOrigin = prevPosIt->second;
//If the entity has moved farther than the size of its box, we need to handle it specially. glm::vec3 toCurrentPos = boxA.Origin() - prevOrigin;
bool traceCollision = rayLength > diameter; float rayLength = glm::length(toCurrentPos) + 0.5f*diameter;
//hack solution: If prevOrigin is less than -9000 in all dimensions, //If the entity has moved farther than the size of its box, we need to handle it specially.
//then it means it is not set, i.e. this is the first collision check for the entity. if (rayLength > diameter) {
if (traceCollision && glm::any(glm::greaterThan((glm::vec3)cPhysics["PrevOrigin"], glm::vec3(-9000.f)))) { Ray ray(prevOrigin, toCurrentPos);
Ray ray(prevOrigin, toCurrentPos); m_OctreeResult.clear();
m_OctreeResult.clear(); m_Octree->ObjectsPossiblyHitByRay(ray, m_OctreeResult);
m_Octree->ObjectsPossiblyHitByRay(ray, m_OctreeResult); for (auto& boxB : m_OctreeResult) {
for (auto& boxB : m_OctreeResult) { if (boxA.Entity == boxB.Entity) {
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&) {
continue; continue;
} }
float u, v; bool hit;
hit = Collision::RayVsModel(ray, model->Vertices(), model->m_Indices, Transform::ModelMatrix(boxB.Entity), dist, u, v); float dist;
} else { if (boxB.Entity.HasComponent("Model")) {
hit = Collision::RayVsAABB(ray, boxB, dist); RawModel* model;
} std::string res = (std::string)boxB.Entity["Model"]["Resource"];
if (hit && dist < rayLength) { try {
//Set the entity to where it was colliding, minus the maximum box size. model = ResourceManager::Load<RawModel, true>(res);
//TODO: Perhaps this should be done slightly more properly. } catch (const std::exception&) {
glm::vec3 newOriginPos = ray.Origin() + (dist - 0.707107f*diameter) * ray.Direction(); continue;
glm::vec3 resolve = newOriginPos - boxA.Origin(); }
(glm::vec3&)cTransform["Position"] += resolve; float u, v;
boxA = *Collision::EntityAbsoluteAABB(entity); hit = Collision::RayVsModel(ray, model->Vertices(), model->m_Indices, Transform::ModelMatrix(boxB.Entity), dist, u, v);
if (resolve.y > 0) { } else {
everHitTheGround = true; hit = Collision::RayVsAABB(ray, boxB, dist);
(bool)cPhysics["IsOnGround"] = true; }
((glm::vec3&)cPhysics["Velocity"]).y = 0.f; 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;
} }
} }
} }
@@ -90,6 +90,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
float verticalStepHeight = (float)(double)cPhysics["VerticalStepHeight"]; float verticalStepHeight = (float)(double)cPhysics["VerticalStepHeight"];
if (Collision::AABBvsTriangles(boxA, model->Vertices(), model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) { if (Collision::AABBvsTriangles(boxA, model->Vertices(), model->m_Indices, modelMatrix, inOutVelocity, verticalStepHeight, isOnGround, resolutionVector)) {
(glm::vec3&)cTransform["Position"] += resolutionVector; (glm::vec3&)cTransform["Position"] += resolutionVector;
boxA = *Collision::EntityAbsoluteAABB(entity);
cPhysics["Velocity"] = inOutVelocity; cPhysics["Velocity"] = inOutVelocity;
if (isOnGround) { if (isOnGround) {
everHitTheGround = true; everHitTheGround = true;
@@ -99,6 +100,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
} else if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) { } else if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) {
//Enter here if boxB has no Model. //Enter here if boxB has no Model.
(glm::vec3&)cTransform["Position"] += resolutionVector; (glm::vec3&)cTransform["Position"] += resolutionVector;
boxA = *Collision::EntityAbsoluteAABB(entity);
if (resolutionVector.y > 0) { if (resolutionVector.y > 0) {
everHitTheGround = true; everHitTheGround = true;
(bool)cPhysics["IsOnGround"] = true; (bool)cPhysics["IsOnGround"] = true;
@@ -112,5 +114,5 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
(bool)cPhysics["IsOnGround"] = false; (bool)cPhysics["IsOnGround"] = false;
} }
(glm::vec3&)cPhysics["PrevOrigin"] = boxA.Origin(); m_PrevPositions[entity] = boxA.Origin();
} }
+36 -1
View File
@@ -51,6 +51,17 @@ EntityWrapper EntityWrapper::FirstParentWithComponent(const std::string& compone
return EntityWrapper::Invalid; return EntityWrapper::Invalid;
} }
EntityWrapper EntityWrapper::Clone(EntityWrapper parent /*= Invalid*/)
{
if (!Valid()) {
return EntityWrapper::Invalid;
}
EntityWrapper clone = cloneRecursive(*this, EntityWrapper::Invalid);
this->World->SetParent(clone.ID, parent.ID);
return clone;
}
bool EntityWrapper::IsChildOf(EntityWrapper potentialParent) bool EntityWrapper::IsChildOf(EntityWrapper potentialParent)
{ {
EntityWrapper entity = *this; EntityWrapper entity = *this;
@@ -111,7 +122,7 @@ EntityWrapper EntityWrapper::firstChildByNameRecursive(const std::string& name,
return EntityWrapper::Invalid; return EntityWrapper::Invalid;
} }
auto itPair = this->World->GetChildren(parent); auto itPair = this->World->GetDirectChildren(parent);
if (itPair.first == itPair.second) { if (itPair.first == itPair.second) {
return EntityWrapper::Invalid; return EntityWrapper::Invalid;
} }
@@ -131,3 +142,27 @@ EntityWrapper EntityWrapper::firstChildByNameRecursive(const std::string& name,
return EntityWrapper::Invalid; return EntityWrapper::Invalid;
} }
EntityWrapper EntityWrapper::cloneRecursive(EntityWrapper entity, EntityWrapper parent)
{
EntityWrapper clone = EntityWrapper(entity.World, entity.World->CreateEntity(parent.ID));
entity.World->SetName(clone.ID, entity.Name());
// Clone components
for (auto& kv : entity.World->GetComponentPools()) {
if (kv.second->KnowsEntity(entity.ID)) {
ComponentWrapper c1 = kv.second->GetByEntity(entity.ID);
ComponentWrapper c2 = entity.World->AttachComponent(clone.ID, kv.first);
c1.Copy(c2);
}
}
// Clone children
auto children = entity.World->GetDirectChildren(entity.ID);
for (auto it = children.first; it != children.second; ++it) {
EntityWrapper child(entity.World, it->second);
cloneRecursive(child, clone);
}
return clone;
}
+1 -1
View File
@@ -127,7 +127,7 @@ void World::SetParent(EntityID entity, EntityID parent)
m_EntityChildren.insert(std::make_pair(parent, entity)); m_EntityChildren.insert(std::make_pair(parent, entity));
} }
const std::pair<std::unordered_multimap<EntityID, EntityID>::const_iterator, std::unordered_multimap<EntityID, EntityID>::const_iterator> World::GetChildren(EntityID entity) const std::pair<std::unordered_multimap<EntityID, EntityID>::const_iterator, std::unordered_multimap<EntityID, EntityID>::const_iterator> World::GetDirectChildren(EntityID entity)
{ {
return m_EntityChildren.equal_range(entity); return m_EntityChildren.equal_range(entity);
} }
+18
View File
@@ -580,6 +580,11 @@ void EditorGUI::createWidgetToolButton(WidgetMode mode)
bool EditorGUI::OnKeyDown(const Events::KeyDown& e) bool EditorGUI::OnKeyDown(const Events::KeyDown& e)
{ {
ImGuiIO& io = ImGui::GetIO();
if (io.WantCaptureKeyboard) {
return false;
}
if (e.ModCtrl && e.KeyCode == GLFW_KEY_S) { if (e.ModCtrl && e.KeyCode == GLFW_KEY_S) {
if (m_CurrentSelection.Valid()) { if (m_CurrentSelection.Valid()) {
EntityWrapper baseParent = m_CurrentSelection; EntityWrapper baseParent = m_CurrentSelection;
@@ -598,6 +603,19 @@ bool EditorGUI::OnKeyDown(const Events::KeyDown& e)
entityImport(m_World); entityImport(m_World);
} }
if (e.ModCtrl && e.KeyCode == GLFW_KEY_C) {
m_CopyTarget = m_CurrentSelection;
}
if (e.ModCtrl && e.KeyCode == GLFW_KEY_V) {
if (m_OnEntityPaste != nullptr) {
EntityWrapper copy = m_OnEntityPaste(m_CopyTarget, m_CurrentSelection);
if (copy != EntityWrapper::Invalid) {
SelectEntity(copy);
}
}
}
if (e.KeyCode == GLFW_KEY_DELETE) { if (e.KeyCode == GLFW_KEY_DELETE) {
if (m_CurrentSelection.Valid()) { if (m_CurrentSelection.Valid()) {
entityDelete(m_CurrentSelection); entityDelete(m_CurrentSelection);
+6
View File
@@ -28,6 +28,7 @@ EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame
m_EditorGUI->SetEntityDeleteCallback(std::bind(&EditorSystem::OnEntityDelete, this, std::placeholders::_1)); m_EditorGUI->SetEntityDeleteCallback(std::bind(&EditorSystem::OnEntityDelete, this, std::placeholders::_1));
m_EditorGUI->SetEntityChangeParentCallback(std::bind(&EditorSystem::OnEntityChangeParent, this, std::placeholders::_1, std::placeholders::_2)); m_EditorGUI->SetEntityChangeParentCallback(std::bind(&EditorSystem::OnEntityChangeParent, this, std::placeholders::_1, std::placeholders::_2));
m_EditorGUI->SetEntityChangeNameCallback(std::bind(&EditorSystem::OnEntityChangeName, this, std::placeholders::_1, std::placeholders::_2)); m_EditorGUI->SetEntityChangeNameCallback(std::bind(&EditorSystem::OnEntityChangeName, this, std::placeholders::_1, std::placeholders::_2));
m_EditorGUI->SetEntityPasteCallback(std::bind(&EditorSystem::OnEntityPaste, this, std::placeholders::_1, std::placeholders::_2));
m_EditorGUI->SetComponentAttachCallback(std::bind(&EditorSystem::OnComponentAttach, this, std::placeholders::_1, std::placeholders::_2)); m_EditorGUI->SetComponentAttachCallback(std::bind(&EditorSystem::OnComponentAttach, this, std::placeholders::_1, std::placeholders::_2));
m_EditorGUI->SetComponentDeleteCallback(std::bind(&EditorSystem::OnComponentDelete, this, std::placeholders::_1, std::placeholders::_2)); m_EditorGUI->SetComponentDeleteCallback(std::bind(&EditorSystem::OnComponentDelete, this, std::placeholders::_1, std::placeholders::_2));
m_EditorGUI->SetWidgetModeCallback(std::bind(&EditorSystem::setWidgetMode, this, std::placeholders::_1)); m_EditorGUI->SetWidgetModeCallback(std::bind(&EditorSystem::setWidgetMode, this, std::placeholders::_1));
@@ -160,6 +161,11 @@ void EditorSystem::OnEntityChangeName(EntityWrapper entity, const std::string& n
} }
} }
EntityWrapper EditorSystem::OnEntityPaste(EntityWrapper entityToCopy, EntityWrapper parent)
{
return entityToCopy.Clone(parent);
}
void EditorSystem::OnComponentAttach(EntityWrapper entity, const std::string& componentType) void EditorSystem::OnComponentAttach(EntityWrapper entity, const std::string& componentType)
{ {
if (entity.Valid()) { if (entity.Valid()) {
+55 -22
View File
@@ -32,6 +32,7 @@ void Client::Connect(std::string address, int port)
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Client::OnPlayerDamage); EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Client::OnPlayerDamage);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Client::OnPlayerSpawned); EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Client::OnPlayerSpawned);
EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &Client::OnDoubleJump);
EVENT_SUBSCRIBE_MEMBER(m_ESearchForServers, &Client::OnSearchForServers); EVENT_SUBSCRIBE_MEMBER(m_ESearchForServers, &Client::OnSearchForServers);
auto config = ResourceManager::Load<ConfigFile>("Config.ini"); auto config = ResourceManager::Load<ConfigFile>("Config.ini");
m_Address = address; m_Address = address;
@@ -140,6 +141,9 @@ void Client::parseMessageType(Packet& packet)
case MessageType::OnPlayerDamage: case MessageType::OnPlayerDamage:
parsePlayerDamage(packet); parsePlayerDamage(packet);
break; break;
case MessageType::OnDoubleJump:
parseDoubleJump(packet);
break;
default: default:
break; break;
} }
@@ -183,7 +187,7 @@ void Client::parsePing()
m_IsConnected = true; m_IsConnected = true;
// Time since last ping was received // Time since last ping was received
m_DurationOfPingTime = 1000 * (std::clock() - m_StartPingTime) / static_cast<double>(CLOCKS_PER_SEC); m_DurationOfPingTime = 1000 * (std::clock() - m_StartPingTime) / static_cast<double>(CLOCKS_PER_SEC);
//LOG_INFO("%i: response time with ctime(ms): %f", m_PacketID, m_DurationOfPingTime); LOG_INFO("%i: response time with ctime(ms): %f", m_PacketID, m_DurationOfPingTime);
m_StartPingTime = std::clock(); m_StartPingTime = std::clock();
Packet packet(MessageType::Ping, m_SendPacketID); Packet packet(MessageType::Ping, m_SendPacketID);
@@ -257,8 +261,14 @@ void Client::parseEntityDeletion(Packet & packet)
if (m_ServerIDToClientID.find(entityToDelete) != m_ServerIDToClientID.end()) { if (m_ServerIDToClientID.find(entityToDelete) != m_ServerIDToClientID.end()) {
EntityID localEntity = m_ServerIDToClientID.at(entityToDelete); EntityID localEntity = m_ServerIDToClientID.at(entityToDelete);
if (m_World->ValidEntity(localEntity)) { if (m_World->ValidEntity(localEntity)) {
m_World->DeleteEntity(localEntity); if (m_World->HasComponent(localEntity,"Player")) {
deleteFromServerClientMaps(entityToDelete, localEntity); Events::PlayerDeath e;
e.Player = EntityWrapper(m_World, localEntity);
m_EventBroker->Publish(e);
} else {
m_World->DeleteEntity(localEntity);
deleteFromServerClientMaps(entityToDelete, localEntity);
}
} }
} }
} }
@@ -272,6 +282,20 @@ void Client::parseComponentDeletion(Packet & packet)
} }
} }
void Client::parseDoubleJump(Packet & packet)
{
EntityID serverID = packet.ReadPrimitive<EntityID>();
if (!serverClientMapsHasEntity(serverID)) {
return;
}
Events::DoubleJump e;
e.entityID = m_ServerIDToClientID.at(serverID);
// If player is local player do not publish to prevent infinite feedback loop
if (e.entityID != m_LocalPlayer.ID) {
m_EventBroker->Publish(e);
}
}
void Client::updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID) void Client::updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID)
{ {
for (auto field : componentInfo.FieldsInOrder) { for (auto field : componentInfo.FieldsInOrder) {
@@ -348,9 +372,7 @@ void Client::parseSnapshot(Packet& packet)
EntityWrapper localEntity(m_World, localEntityID); EntityWrapper localEntity(m_World, localEntityID);
// Update entity // Update entity
if (m_World->HasComponent(localEntityID, componentType)) { if (m_World->HasComponent(localEntityID, componentType)) {
if (localEntity.Name() == "CapturePointHUD") { // TODO Fix memory leak here
UpdateLocalCapturePointHUD(localEntity);
}
SharedComponentWrapper newComponent = createSharedComponent(packet, localEntityID, componentInfo); SharedComponentWrapper newComponent = createSharedComponent(packet, localEntityID, componentInfo);
bool shouldApply = true; bool shouldApply = true;
// Apply potential filter function // Apply potential filter function
@@ -361,6 +383,7 @@ void Client::parseSnapshot(Packet& packet)
ComponentWrapper currentComponent = m_World->GetComponent(localEntityID, componentType); ComponentWrapper currentComponent = m_World->GetComponent(localEntityID, componentType);
memcpy(currentComponent.Data, newComponent.Data, componentInfo.Stride); memcpy(currentComponent.Data, newComponent.Data, componentInfo.Stride);
} }
//if (localEntity != m_LocalPlayer && !localEntity.IsChildOf(m_LocalPlayer)) { //if (localEntity != m_LocalPlayer && !localEntity.IsChildOf(m_LocalPlayer)) {
// updateFields(packet, componentInfo, localEntityID); // updateFields(packet, componentInfo, localEntityID);
//} else { //} else {
@@ -377,7 +400,11 @@ void Client::parseSnapshot(Packet& packet)
if (serverParentID == EntityID_Invalid) { if (serverParentID == EntityID_Invalid) {
newLocalEntityID = m_World->CreateEntity(EntityID_Invalid); newLocalEntityID = m_World->CreateEntity(EntityID_Invalid);
} else { } else {
newLocalEntityID = m_World->CreateEntity(m_ServerIDToClientID.at(serverParentID)); if (serverClientMapsHasEntity(serverParentID)) {
newLocalEntityID = m_World->CreateEntity(m_ServerIDToClientID.at(serverParentID));
} else {
newLocalEntityID = m_World->CreateEntity(EntityID_Invalid);
}
} }
m_World->SetName(newLocalEntityID, serverEntityName); m_World->SetName(newLocalEntityID, serverEntityName);
insertIntoServerClientMaps(serverEntityID, newLocalEntityID); insertIntoServerClientMaps(serverEntityID, newLocalEntityID);
@@ -387,26 +414,16 @@ void Client::parseSnapshot(Packet& packet)
} }
// Parent logic // Parent logic
// This should be enough beacause we know that the entities arives in pre-order (there will always be a parent) // This should be enough beacause we know that the entities arives in pre-order (there will always be a parent)
if (serverParentID != EntityID_Invalid) { if (serverParentID != EntityID_Invalid && serverClientMapsHasEntity(serverParentID)) {
EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID); EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID);
m_World->SetParent(localEntityID, m_ServerIDToClientID.at(serverParentID)); if (m_World->GetParent(localEntityID) != m_ServerIDToClientID.at(serverParentID)) {
m_World->SetParent(localEntityID, m_ServerIDToClientID.at(serverParentID));
}
} }
} }
parseSpawnEvents(); parseSpawnEvents();
} }
void Client::UpdateLocalCapturePointHUD(EntityWrapper capturePointHUD)
{
//auto children = m_World->GetChildren(capturePointHUD.ID);
//for (auto it = children.first; it != children.second; it++) {
// it->first
//}
//
//EntityWrapper& localHUD = m_LocalPlayer.FirstChildByName("HUD").FirstChildByName("CapturePointHUD");
//m_World->GetComponentPools()
}
void Client::disconnect() void Client::disconnect()
{ {
m_IsConnected = false; m_IsConnected = false;
@@ -469,6 +486,11 @@ bool Client::OnPlayerDamage(const Events::PlayerDamage & e)
if (e.Inflictor != m_LocalPlayer) { if (e.Inflictor != m_LocalPlayer) {
return false; return false;
} }
// Could this happen?
//if (!clientServerMapsHasEntity(e.Inflictor.ID)
// || !clientServerMapsHasEntity(e.Victim.ID)) {
// return;
//}
Packet packet(MessageType::OnPlayerDamage, m_SendPacketID); Packet packet(MessageType::OnPlayerDamage, m_SendPacketID);
packet.WritePrimitive(m_ClientIDToServerID.at(e.Inflictor.ID)); packet.WritePrimitive(m_ClientIDToServerID.at(e.Inflictor.ID));
@@ -503,7 +525,7 @@ void Client::parsePlayerDamage(Packet& packet)
Events::PlayerDamage e; Events::PlayerDamage e;
PlayerID victimID = packet.ReadPrimitive<EntityID>(); PlayerID victimID = packet.ReadPrimitive<EntityID>();
PlayerID inflictorID = packet.ReadPrimitive<EntityID>(); PlayerID inflictorID = packet.ReadPrimitive<EntityID>();
if(!serverClientMapsHasEntity(victimID) || !serverClientMapsHasEntity(inflictorID)){ if (!serverClientMapsHasEntity(victimID) || !serverClientMapsHasEntity(inflictorID)) {
return; return;
} }
e.Inflictor = EntityWrapper(m_World, m_ServerIDToClientID.at(victimID)); e.Inflictor = EntityWrapper(m_World, m_ServerIDToClientID.at(victimID));
@@ -515,6 +537,17 @@ void Client::parsePlayerDamage(Packet& packet)
} }
} }
bool Client::OnDoubleJump(Events::DoubleJump & e)
{
if (!clientServerMapsHasEntity(e.entityID) || e.entityID != m_LocalPlayer.ID) {
return false;
}
Packet packet(MessageType::OnDoubleJump);
packet.WritePrimitive(m_ClientIDToServerID.at(e.entityID));
m_Reliable.Send(packet);
return true;
}
void Client::sendLocalPlayerTransform() void Client::sendLocalPlayerTransform()
{ {
if (!m_LocalPlayer.Valid()) { if (!m_LocalPlayer.Valid()) {
+56 -43
View File
@@ -29,9 +29,8 @@ Server::~Server()
void Server::Update() void Server::Update()
{ {
PlayerDefinition pd;
m_Reliable.AcceptNewConnections(m_NextPlayerID, m_ConnectedPlayers); m_Reliable.AcceptNewConnections(m_NextPlayerID, m_ConnectedPlayers);
for (auto& kv : m_ConnectedPlayers) { for (auto& kv : m_ConnectedPlayers) {
while (kv.second.TCPSocket->available()) { while (kv.second.TCPSocket->available()) {
// Packet will get real data in receive // Packet will get real data in receive
@@ -47,6 +46,7 @@ void Server::Update()
} }
} }
PlayerDefinition pd;
while (m_Unreliable.IsSocketAvailable()) { while (m_Unreliable.IsSocketAvailable()) {
// Packet will get real data in receive // Packet will get real data in receive
Packet packet(MessageType::Invalid); Packet packet(MessageType::Invalid);
@@ -65,7 +65,7 @@ void Server::Update()
PlayerDefinition localArea; PlayerDefinition localArea;
localArea.Endpoint = boost::asio::ip::udp::endpoint(); localArea.Endpoint = boost::asio::ip::udp::endpoint();
m_ServerlistRequest.Receive(packet, localArea); m_ServerlistRequest.Receive(packet, localArea);
if(packet.GetMessageType() == MessageType::ServerlistRequest) { if (packet.GetMessageType() == MessageType::ServerlistRequest) {
packet.ReadPrimitive<int>(); // Pop size packet.ReadPrimitive<int>(); // Pop size
packet.ReadPrimitive<int>(); // Pop MsgType packet.ReadPrimitive<int>(); // Pop MsgType
packet.ReadPrimitive<int>(); // Pop packet ID packet.ReadPrimitive<int>(); // Pop packet ID
@@ -76,7 +76,7 @@ void Server::Update()
} }
// Check if players have disconnected // Check if players have disconnected
for (int i = 0; i < m_PlayersToDisconnect.size(); i++) { for (int i = 0; i < m_PlayersToDisconnect.size(); i++) {
disconnect(m_PlayersToDisconnect.at(i)); disconnect(m_PlayersToDisconnect.at(i));
} }
m_PlayersToDisconnect.clear(); m_PlayersToDisconnect.clear();
@@ -136,7 +136,10 @@ void Server::parseMessageType(Packet& packet)
parseOnPlayerDamage(packet); parseOnPlayerDamage(packet);
break; break;
case MessageType::PlayerTransform: case MessageType::PlayerTransform:
parsePlayerTransform(packet); parsePlayerTransform(packet);
break;
case MessageType::OnDoubleJump:
parseDoubleJump(packet);
break; break;
default: default:
break; break;
@@ -183,7 +186,7 @@ void Server::addInputCommandsToPacket(Packet& packet)
void Server::addPlayersToPacket(Packet & packet, EntityID entityID) void Server::addPlayersToPacket(Packet & packet, EntityID entityID)
{ {
auto itPair = m_World->GetChildren(entityID); auto itPair = m_World->GetDirectChildren(entityID);
std::unordered_map<std::string, ComponentPool*> worldComponentPools = m_World->GetComponentPools(); std::unordered_map<std::string, ComponentPool*> worldComponentPools = m_World->GetComponentPools();
// Loop through every child // Loop through every child
for (auto it = itPair.first; it != itPair.second; it++) { for (auto it = itPair.first; it != itPair.second; it++) {
@@ -191,49 +194,47 @@ void Server::addPlayersToPacket(Packet & packet, EntityID entityID)
// HACK: Only sync players for now, since the map turned out to be TOO LARGE to send in one snapshot and Simon's computer shits itself // HACK: Only sync players for now, since the map turned out to be TOO LARGE to send in one snapshot and Simon's computer shits itself
// HACK: Also checked CapturePointHUD for now. (this would get out of sync); // HACK: Also checked CapturePointHUD for now. (this would get out of sync);
EntityWrapper childEntity(m_World, childEntityID); EntityWrapper childEntity(m_World, childEntityID);
if (!shouldSendToClient(childEntity)) { if (shouldSendToClient(childEntity)) {
continue; // Write EntityID and parentsID and Entity name
} packet.WritePrimitive(childEntityID);
packet.WritePrimitive(entityID);
// Write EntityID and parentsID and Entity name packet.WriteString(m_World->GetName(childEntityID));
packet.WritePrimitive(childEntityID); // Write components to child
packet.WritePrimitive(entityID); int numberOfComponents = 0;
packet.WriteString(m_World->GetName(childEntityID)); for (auto& i : worldComponentPools) {
// Write components to child if (i.second->KnowsEntity(childEntityID)) {
int numberOfComponents = 0; numberOfComponents++;
for (auto& i : worldComponentPools) { }
if (i.second->KnowsEntity(childEntityID)) {
numberOfComponents++;
} }
} // Write how many components should be read
// Write how many components should be read packet.WritePrimitive(numberOfComponents);
packet.WritePrimitive(numberOfComponents); for (auto& i : worldComponentPools) {
for (auto& i : worldComponentPools) { // If the entity exist in the pool
// If the entity exist in the pool if (i.second->KnowsEntity(childEntityID)) {
if (i.second->KnowsEntity(childEntityID)) { ComponentWrapper componentWrapper = i.second->GetByEntity(childEntityID);
ComponentWrapper componentWrapper = i.second->GetByEntity(childEntityID); // ComponentType
// ComponentType packet.WriteString(componentWrapper.Info.Name);
packet.WriteString(componentWrapper.Info.Name); // Loop through fields
// Loop through fields for (auto& componentField : componentWrapper.Info.FieldsInOrder) {
for (auto& componentField : componentWrapper.Info.FieldsInOrder) { ComponentInfo::Field_t fieldInfo = componentWrapper.Info.Fields.at(componentField);
ComponentInfo::Field_t fieldInfo = componentWrapper.Info.Fields.at(componentField); if (fieldInfo.Type == "string") {
if (fieldInfo.Type == "string") { std::string& value = componentWrapper[componentField];
std::string& value = componentWrapper[componentField]; packet.WriteString(value);
packet.WriteString(value); } else {
} else { packet.WriteData(componentWrapper.Data + fieldInfo.Offset, fieldInfo.Stride);
packet.WriteData(componentWrapper.Data + fieldInfo.Offset, fieldInfo.Stride); }
} }
} }
} }
} }
// Go to to your children // Go to to your children
addChildrenToPacket(packet, childEntityID); addPlayersToPacket(packet, childEntityID);
} }
} }
void Server::addChildrenToPacket(Packet & packet, EntityID entityID) void Server::addChildrenToPacket(Packet & packet, EntityID entityID)
{ {
auto itPair = m_World->GetChildren(entityID); auto itPair = m_World->GetDirectChildren(entityID);
std::unordered_map<std::string, ComponentPool*> worldComponentPools = m_World->GetComponentPools(); std::unordered_map<std::string, ComponentPool*> worldComponentPools = m_World->GetComponentPools();
// Loop through every child // Loop through every child
for (auto it = itPair.first; it != itPair.second; it++) { for (auto it = itPair.first; it != itPair.second; it++) {
@@ -343,7 +344,7 @@ void Server::parseTCPConnect(Packet & packet)
// Read packet ID // Read packet ID
m_PreviousPacketID = m_PacketID; // Set previous packet id m_PreviousPacketID = m_PacketID; // Set previous packet id
m_PacketID = packet.ReadPrimitive<int>(); //Read new packet id m_PacketID = packet.ReadPrimitive<int>(); //Read new packet id
LOG_INFO("Parsing connections"); LOG_INFO("Parsing connections");
// Check if player is already connected // Check if player is already connected
// Ska vara till lagd i TCPServer receive // Ska vara till lagd i TCPServer receive
@@ -455,8 +456,7 @@ bool Server::OnInputCommand(const Events::InputCommand & e)
} }
isReadingData = !isReadingData; isReadingData = !isReadingData;
m_SaveDataTimer = std::clock(); m_SaveDataTimer = std::clock();
} } else if (e.Command == "KickPlayer" && e.Value > 0) {
else if (e.Command == "KickPlayer" && e.Value > 0) {
kick(0); kick(0);
} }
@@ -507,7 +507,7 @@ bool Server::OnPlayerDamage(const Events::PlayerDamage& e)
packet.WritePrimitive(e.Damage); packet.WritePrimitive(e.Damage);
reliableBroadcast(packet); reliableBroadcast(packet);
return false; return true;
} }
void Server::parseClientPing() void Server::parseClientPing()
@@ -536,6 +536,12 @@ void Server::parsePing()
} }
} }
bool Server::parseDoubleJump(Packet & packet)
{
reliableBroadcast(packet);
return true;
}
void Server::parseOnInputCommand(Packet& packet) void Server::parseOnInputCommand(Packet& packet)
{ {
PlayerID player = -1; PlayerID player = -1;
@@ -595,8 +601,15 @@ void Server::parsePlayerTransform(Packet& packet)
bool Server::shouldSendToClient(EntityWrapper childEntity) bool Server::shouldSendToClient(EntityWrapper childEntity)
{ {
auto children = m_World->GetDirectChildren(childEntity.ID);
for (auto it = children.first; it != children.second; it++) {
EntityWrapper child(m_World, it->second);
if(child.HasComponent("CapturePoint")) {
return true;
}
}
return childEntity.HasComponent("Player") || childEntity.FirstParentWithComponent("Player").Valid() return childEntity.HasComponent("Player") || childEntity.FirstParentWithComponent("Player").Valid()
|| childEntity.HasComponent("CapturePoint") || childEntity.FirstParentWithComponent("CapturePoint").Valid(); || childEntity.HasComponent("CapturePoint");
} }
PlayerID Server::GetPlayerIDFromEndpoint() PlayerID Server::GetPlayerIDFromEndpoint()
+17 -23
View File
@@ -4,6 +4,8 @@ using namespace boost::asio::ip;
TCPServer::TCPServer() TCPServer::TCPServer()
{ {
acceptor = std::unique_ptr<tcp::acceptor>(new tcp::acceptor(m_IOService, tcp::endpoint(tcp::v4(), 27666))); acceptor = std::unique_ptr<tcp::acceptor>(new tcp::acceptor(m_IOService, tcp::endpoint(tcp::v4(), 27666)));
// Make the acceptor non-blocking so we wont get stuck in AcceptNewConnections().
acceptor->non_blocking(true);
m_Port = GetPort(); m_Port = GetPort();
m_Address = GetAddress(); m_Address = GetAddress();
} }
@@ -13,14 +15,24 @@ TCPServer::~TCPServer()
void TCPServer::AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers) void TCPServer::AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers)
{ {
boost::system::error_code error;
boost::shared_ptr<tcp::socket> newSocket = boost::shared_ptr<tcp::socket>(new tcp::socket(m_IOService)); boost::shared_ptr<tcp::socket> newSocket = boost::shared_ptr<tcp::socket>(new tcp::socket(m_IOService));
m_IOService.poll(); acceptor->accept(*newSocket, error);
acceptor->async_accept(*newSocket, // If no error occured add new tcp connection
boost::bind(&TCPServer::handle_accept, this, newSocket, boost::ref(nextPlayerID), boost::ref(connectedPlayers), if (!error) {
boost::asio::placeholders::error)); // Add tcp socket to connections
boost::asio::ip::tcp::no_delay option(true);
newSocket->set_option(option);
PlayerDefinition pd;
pd.StopTime = std::clock();
pd.TCPSocket = newSocket;
pd.TCPAddress = newSocket.get()->remote_endpoint().address();
pd.TCPPort = newSocket.get()->remote_endpoint().port();
connectedPlayers[nextPlayerID++] = pd;
}
} }
PlayerID GetPlayerIDFromEndpoint(const std::map<PlayerID, PlayerDefinition>& connectedPlayers, PlayerID TCPServer::getPlayerIDFromEndpoint(const std::map<PlayerID, PlayerDefinition>& connectedPlayers,
boost::asio::ip::address address, unsigned short port) boost::asio::ip::address address, unsigned short port)
{ {
for (auto& kv : connectedPlayers) { for (auto& kv : connectedPlayers) {
@@ -32,24 +44,6 @@ PlayerID GetPlayerIDFromEndpoint(const std::map<PlayerID, PlayerDefinition>& con
return -1; return -1;
} }
void TCPServer::handle_accept(boost::shared_ptr<tcp::socket> socket,
int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers,
const boost::system::error_code& error)
{
if (!error && GetPlayerIDFromEndpoint(connectedPlayers, socket->remote_endpoint().address(),
socket->remote_endpoint().port()) == -1) {
// Add tcp socket to connections
boost::asio::ip::tcp::no_delay option(true);
socket->set_option(option);
PlayerDefinition pd;
pd.StopTime = std::clock();
pd.TCPSocket = socket;
pd.TCPAddress = socket.get()->remote_endpoint().address();
pd.TCPPort = socket.get()->remote_endpoint().port();
connectedPlayers[nextPlayerID++] = pd;
}
}
void TCPServer::Send(Packet & packet, PlayerDefinition & playerDefinition) void TCPServer::Send(Packet & packet, PlayerDefinition & playerDefinition)
{ {
packet.UpdateSize(); packet.UpdateSize();
+1
View File
@@ -17,6 +17,7 @@ void CubeMapPass::LoadTextures(std::string input)
m_CubeMapTextures.push_back(img); m_CubeMapTextures.push_back(img);
} }
GenerateCubeMapTexture(); GenerateCubeMapTexture();
m_PreviusCubeMapTexture = input;
} }
} }
+25 -67
View File
@@ -4,20 +4,18 @@ AmmoPickupSystem::AmmoPickupSystem(SystemParams params)
: System(params) : System(params)
{ {
EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &AmmoPickupSystem::OnTriggerTouch); EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &AmmoPickupSystem::OnTriggerTouch);
EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &AmmoPickupSystem::OnTriggerLeave);
} }
void AmmoPickupSystem::Update(double dt) void AmmoPickupSystem::Update(double dt)
{ {
for (auto it = m_ETriggerTouchVector.begin(); it != m_ETriggerTouchVector.end(); ++it) for (auto it = m_ETriggerTouchVector.begin(); it != m_ETriggerTouchVector.end(); ++it)
{ {
auto& somePickup = *it; auto& ammoPickupPosition = *it;
//set the double timer value (value 3) //set the double timer value (value 3)
somePickup.DecreaseThisRespawnTimer -= dt; ammoPickupPosition.DecreaseThisRespawnTimer -= dt;
if (somePickup.DecreaseThisRespawnTimer < 0.0) { if (ammoPickupPosition.DecreaseThisRespawnTimer < 0.0) {
//spawn and delete the vector item //spawn and delete the vector item
auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/" + somePickup.isAmmoPickup ? "AmmoPickup.xml" : "HealthPickup.xml"); auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/AmmoPickup.xml");
EntityFileParser parser(entityFile); EntityFileParser parser(entityFile);
EntityID ammoPickupID = parser.MergeEntities(m_World); EntityID ammoPickupID = parser.MergeEntities(m_World);
@@ -27,34 +25,17 @@ void AmmoPickupSystem::Update(double dt)
m_EventBroker->Publish(ePickupSpawned); m_EventBroker->Publish(ePickupSpawned);
//set values from the old entity to the new entity //set values from the old entity to the new entity
auto& newPickupEntity = EntityWrapper(m_World, ammoPickupID); auto& newAmmoPickupEntity = EntityWrapper(m_World, ammoPickupID);
newPickupEntity["Transform"]["Position"] = somePickup.Pos; newAmmoPickupEntity["Transform"]["Position"] = ammoPickupPosition.Pos;
if (somePickup.isAmmoPickup) { newAmmoPickupEntity["AmmoPickup"]["AmmoGain"] = ammoPickupPosition.AmmoGain;
newPickupEntity["AmmoPickup"]["AmmoGain"] = somePickup.AmmoGain; newAmmoPickupEntity["AmmoPickup"]["RespawnTimer"] = ammoPickupPosition.RespawnTimer;
newPickupEntity["AmmoPickup"]["RespawnTimer"] = somePickup.RespawnTimer; m_World->SetParent(newAmmoPickupEntity.ID, ammoPickupPosition.parentID);
} else {
newPickupEntity["HealthPickup"]["HealthGain"] = somePickup.AmmoGain;
newPickupEntity["HealthPickup"]["RespawnTimer"] = somePickup.RespawnTimer;
}
m_World->SetParent(newPickupEntity.ID, somePickup.parentID);
//erase the current element (somePickup) //erase the current element (AmmoPickupPosition)
m_ETriggerTouchVector.erase(it); m_ETriggerTouchVector.erase(it);
break; break;
} }
} }
//still touching AmmoPickupAtMaxHealthAmmo?
for (auto& it = m_PickupAtMaximum.begin(); it != m_PickupAtMaximum.end(); ++it) {
if (!it->player.Valid() || !it->pickup.Valid()) {
m_PickupAtMaximum.erase(it);
break;
}
if ((int)it->player["AssaultWeapon"]["Ammo"] < (int)it->player["AssaultWeapon"]["MaxAmmo"]) {
DoPickup(it->player, it->pickup);
m_PickupAtMaximum.erase(it);
break;
}
}
} }
@@ -63,59 +44,36 @@ bool AmmoPickupSystem::OnTriggerTouch(Events::TriggerTouch& e)
if (e.Entity != LocalPlayer) { if (e.Entity != LocalPlayer) {
return false; return false;
} }
if (!e.Trigger.HasComponent("AmmoPickup") && !e.Trigger.HasComponent("HealthPickup")) {
return false;
}
//TODO: add other weapontypes //TODO: add other weapontypes
if (!e.Entity.HasComponent("AssaultWeapon")) { if (!e.Entity.HasComponent("AssaultWeapon")) {
return false; return false;
} }
int maxWeaponAmmo = (int)e.Entity["AssaultWeapon"]["MaxAmmo"]; if (!e.Trigger.HasComponent("AmmoPickup")) {
int& currentAmmo = (int)e.Entity["AssaultWeapon"]["Ammo"];
//cant pick up ammopacks if you are already at MaxAmmo
if (currentAmmo >= maxWeaponAmmo) {
m_PickupAtMaximum.push_back({ e.Entity, e.Trigger });
return false; return false;
} }
DoPickup(e.Entity, e.Trigger); int maxWeaponAmmo = (int)e.Entity["AssaultWeapon"]["MaxAmmo"];
return true; int& currentAmmo = (int)e.Entity["AssaultWeapon"]["Ammo"];
}
bool AmmoPickupSystem::OnTriggerLeave(Events::TriggerLeave& e) { int ammoGiven = 0.01*(double)e.Trigger["AmmoPickup"]["AmmoGain"] * maxWeaponAmmo;
//triggerleave erases possible AmmoPickupAtMaxHealthAmmo //cant pick up ammopacks if you are already at MaxAmmo
for (auto& it = m_PickupAtMaximum.begin(); it != m_PickupAtMaximum.end(); ++it) { if (currentAmmo >= maxWeaponAmmo) {
if (it->pickup.ID == e.Trigger.ID && it->player.ID == e.Entity.ID) { return false;
m_PickupAtMaximum.erase(it);
break;
}
}
return true;
}
void AmmoPickupSystem::DoPickup(EntityWrapper &player, EntityWrapper &trigger) {
auto& weaponEntity = player["AssaultWeapon"];
auto& pickup = trigger["AmmoPickup"];
auto& gain = pickup["AmmoGain"];
int maxValue = (int)weaponEntity["MaxAmmo"];
int& currentValue = (int)weaponEntity["Ammo"];
//cant pick up if you are already at max
if (currentValue >= maxValue) {
return;
} }
int increaseGiven = 0.01*(double)gain * maxValue; //personEntered = e.Entity, thingEntered = e.Trigger
Events::AmmoPickup ePlayerAmmoPickup; Events::AmmoPickup ePlayerAmmoPickup;
ePlayerAmmoPickup.AmmoGain = increaseGiven; ePlayerAmmoPickup.AmmoGain = ammoGiven;
ePlayerAmmoPickup.Player = player; ePlayerAmmoPickup.Player = e.Entity;
m_EventBroker->Publish(ePlayerAmmoPickup); m_EventBroker->Publish(ePlayerAmmoPickup);
//immediately give the player the ammo //immediately give the player the ammo
currentValue = std::min(currentValue + increaseGiven, maxValue); currentAmmo = std::min(currentAmmo + ammoGiven, maxWeaponAmmo);
//copy position, ammogain, respawntimer (twice since one of the values will be counted down to 0, the other will be set in the new object) //copy position, ammogain, respawntimer (twice since one of the values will be counted down to 0, the other will be set in the new object)
//we need to copy all values since each value can be different for each ammoPickup //we need to copy all values since each value can be different for each ammoPickup
m_ETriggerTouchVector.push_back({ trigger["Transform"]["Position"], gain, m_ETriggerTouchVector.push_back({ e.Trigger["Transform"]["Position"], e.Trigger["AmmoPickup"]["AmmoGain"],
pickup["RespawnTimer"], pickup["RespawnTimer"], m_World->GetParent(trigger.ID) , true }); e.Trigger["AmmoPickup"]["RespawnTimer"], e.Trigger["AmmoPickup"]["RespawnTimer"], m_World->GetParent(e.Trigger.ID) });
//delete the ammopickup //delete the ammopickup
m_World->DeleteEntity(trigger.ID); m_World->DeleteEntity(e.Trigger.ID);
return true;
} }
+10 -5
View File
@@ -6,9 +6,11 @@ CapturePointSystem::CapturePointSystem(SystemParams params)
, PureSystem("CapturePoint") , PureSystem("CapturePoint")
{ {
//subscribe/listenTo playerdamage,healthpickup events (using the eventBroker) //subscribe/listenTo playerdamage,healthpickup events (using the eventBroker)
EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &CapturePointSystem::OnTriggerTouch); if (!IsClient) {
EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &CapturePointSystem::OnTriggerLeave); EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &CapturePointSystem::OnTriggerTouch);
EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &CapturePointSystem::OnCaptured); EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &CapturePointSystem::OnTriggerLeave);
EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &CapturePointSystem::OnCaptured);
}
} }
@@ -16,6 +18,9 @@ CapturePointSystem::CapturePointSystem(SystemParams params)
//NOTE: needs to run each frame, since we're possibly modifying the captureTimer for the capturePoints by dt //NOTE: needs to run each frame, since we're possibly modifying the captureTimer for the capturePoints by dt
void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, ComponentWrapper& cCapturePoint, double dt) void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, ComponentWrapper& cCapturePoint, double dt)
{ {
if (IsClient) {
return;
}
if (m_WinnerWasFound) { if (m_WinnerWasFound) {
return; return;
} }
@@ -151,12 +156,12 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp
int currentTeam = 0; int currentTeam = 0;
bool canCapture = false; bool canCapture = false;
if (redTeamPlayersStandingInside > 0 && blueTeamPlayersStandingInside == 0) { if (redTeamPlayersStandingInside > 0 && blueTeamPlayersStandingInside == 0) {
timerDeltaChange = 3*redTeamPlayersStandingInside*dt; timerDeltaChange = redTeamPlayersStandingInside*dt;
currentTeam = redTeam; currentTeam = redTeam;
canCapture = nextPossibleCapturePoint["Red"] == capturePointNumber; canCapture = nextPossibleCapturePoint["Red"] == capturePointNumber;
} }
if (redTeamPlayersStandingInside == 0 && blueTeamPlayersStandingInside > 0) { if (redTeamPlayersStandingInside == 0 && blueTeamPlayersStandingInside > 0) {
timerDeltaChange = -3*blueTeamPlayersStandingInside*dt; timerDeltaChange = -blueTeamPlayersStandingInside*dt;
currentTeam = blueTeam; currentTeam = blueTeam;
canCapture = nextPossibleCapturePoint["Blue"] == capturePointNumber; canCapture = nextPossibleCapturePoint["Blue"] == capturePointNumber;
} }
+1 -21
View File
@@ -14,35 +14,16 @@ HealthSystem::HealthSystem(SystemParams params)
void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cHealth, double dt) void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cHealth, double dt)
{ {
double& health = cHealth["Health"]; double& health = cHealth["Health"];
int healthInt = (int)health; if (health <= 0.0) {
//update struct
for (auto& iter = m_DeadPlayers.begin(); iter < m_DeadPlayers.end(); iter++)
{
iter->timeSinceDeath += dt;
if (iter->timeSinceDeath > 2.0f || !iter->playerEntity.Valid()) {
m_DeadPlayers.erase(iter);
break;
}
}
if (healthInt <= 0) {
for (auto deadPlayer : m_DeadPlayers)
{
if (deadPlayer.playerEntity.ID == entity.ID) {
return;
}
}
LOG_INFO("-> health <= 0");
Events::PlayerDeath ePlayerDeath; Events::PlayerDeath ePlayerDeath;
ePlayerDeath.Player = entity; ePlayerDeath.Player = entity;
m_EventBroker->Publish(ePlayerDeath); m_EventBroker->Publish(ePlayerDeath);
m_DeadPlayers.emplace_back(entity);
//Note: we will delete the entity in PlayerDeathSystem //Note: we will delete the entity in PlayerDeathSystem
} }
} }
bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e) bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e)
{ {
LOG_INFO("<- on player damage");
if (!IsServer && m_NetworkEnabled || !e.Victim.Valid()) { if (!IsServer && m_NetworkEnabled || !e.Victim.Valid()) {
return false; return false;
} }
@@ -50,7 +31,6 @@ bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e)
ComponentWrapper cHealth = e.Victim["Health"]; ComponentWrapper cHealth = e.Victim["Health"];
double& health = cHealth["Health"]; double& health = cHealth["Health"];
health -= e.Damage; health -= e.Damage;
LOG_INFO("-> health onplayerdam");
return true; return true;
} }
-5
View File
@@ -54,13 +54,9 @@ void KillFeedSystem::Update(double dt)
bool KillFeedSystem::OnPlayerDeath(Events::PlayerDeath& e) bool KillFeedSystem::OnPlayerDeath(Events::PlayerDeath& e)
{ {
LOG_INFO("<- killfeed death");
KillFeedInfo kfInfo; KillFeedInfo kfInfo;
if (e.Player.HasComponent("Team")) { if (e.Player.HasComponent("Team")) {
LOG_INFO("- killfeed death");
int red = e.Player["Team"].Enum("Team", "Red"); int red = e.Player["Team"].Enum("Team", "Red");
int blue = e.Player["Team"].Enum("Team", "Blue"); int blue = e.Player["Team"].Enum("Team", "Blue");
@@ -74,7 +70,6 @@ bool KillFeedSystem::OnPlayerDeath(Events::PlayerDeath& e)
m_DeathQueue.push_back(kfInfo); m_DeathQueue.push_back(kfInfo);
} }
} }
LOG_INFO("-> killfeed death");
if(m_DeathQueue.size() > 3) { if(m_DeathQueue.size() > 3) {
+2 -18
View File
@@ -8,27 +8,18 @@ PlayerDeathSystem::PlayerDeathSystem(SystemParams params)
void PlayerDeathSystem::Update(double dt) void PlayerDeathSystem::Update(double dt)
{ {
} }
bool PlayerDeathSystem::OnPlayerDeath(Events::PlayerDeath& e) bool PlayerDeathSystem::OnPlayerDeath(Events::PlayerDeath& e)
{ {
LOG_INFO("<- deathsystem: valid player");
if (!e.Player.Valid()) { if (!e.Player.Valid()) {
return false; return false;
} }
LOG_INFO("-> deathsystem: valid player");
LOG_INFO("<- create effect");
createDeathEffect(e.Player); createDeathEffect(e.Player);
LOG_INFO("-> create effect"); // Delete player
m_World->DeleteEntity(e.Player.ID);
if (!IsClient || !ResourceManager::Load<ConfigFile>("Config.ini")->Get("Networking.StartNetwork", false)) {
m_World->DeleteEntity(e.Player.ID);
}
return true; return true;
} }
@@ -41,8 +32,6 @@ void PlayerDeathSystem::createDeathEffect(EntityWrapper player)
EntityID deathEffectID = parser.MergeEntities(m_World); EntityID deathEffectID = parser.MergeEntities(m_World);
EntityWrapper deathEffectEW = EntityWrapper(m_World, deathEffectID); EntityWrapper deathEffectEW = EntityWrapper(m_World, deathEffectID);
LOG_INFO("<- effect camera");
//components that we need from player //components that we need from player
auto playerModel = player.FirstChildByName("PlayerModel"); auto playerModel = player.FirstChildByName("PlayerModel");
if (!playerModel.Valid()) { if (!playerModel.Valid()) {
@@ -53,7 +42,6 @@ void PlayerDeathSystem::createDeathEffect(EntityWrapper player)
} }
auto playerEntityModel = playerModel["Model"]; auto playerEntityModel = playerModel["Model"];
auto playerEntityAnimation = playerModel["Animation"]; auto playerEntityAnimation = playerModel["Animation"];
LOG_INFO("-> effect camera");
//copy the data from player to explosioneffectmodel //copy the data from player to explosioneffectmodel
playerEntityModel.Copy(deathEffectEW["Model"]); playerEntityModel.Copy(deathEffectEW["Model"]);
@@ -69,15 +57,11 @@ void PlayerDeathSystem::createDeathEffect(EntityWrapper player)
//effect,camera is relative to playersPosition //effect,camera is relative to playersPosition
//deathEffectEW["ExplosionEffect"]["ExplosionOrigin"] = glm::vec3(0, 0, 0); //deathEffectEW["ExplosionEffect"]["ExplosionOrigin"] = glm::vec3(0, 0, 0);
LOG_INFO("<- localplayer");
//camera (with lifetime) behind the player //camera (with lifetime) behind the player
if (player == LocalPlayer) { if (player == LocalPlayer) {
auto cam = deathEffectEW.FirstChildByName("Camera"); auto cam = deathEffectEW.FirstChildByName("Camera");
Events::SetCamera eSetCamera; Events::SetCamera eSetCamera;
eSetCamera.CameraEntity = cam; eSetCamera.CameraEntity = cam;
m_EventBroker->Publish(eSetCamera); m_EventBroker->Publish(eSetCamera);
LOG_INFO("in localplayer");
} }
LOG_INFO("-> localplayer");
} }
+28 -6
View File
@@ -4,6 +4,7 @@ PlayerMovementSystem::PlayerMovementSystem(SystemParams params)
: System(params) : System(params)
{ {
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &PlayerMovementSystem::OnPlayerSpawned); EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &PlayerMovementSystem::OnPlayerSpawned);
EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &PlayerMovementSystem::OnDoubleJump);
} }
PlayerMovementSystem::~PlayerMovementSystem() PlayerMovementSystem::~PlayerMovementSystem()
@@ -36,7 +37,6 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
if (!player.Valid()) { if (!player.Valid()) {
continue; continue;
} }
// Aim pitch // Aim pitch
EntityWrapper cameraEntity = player.FirstChildByName("Camera"); EntityWrapper cameraEntity = player.FirstChildByName("Camera");
if (cameraEntity.Valid()) { if (cameraEntity.Valid()) {
@@ -122,15 +122,14 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
if (isOnGround) { if (isOnGround) {
controller->SetDoubleJumping(false); controller->SetDoubleJumping(false);
} else { } else {
// If IsServer and network is off this will not work
if (IsClient) { if (IsClient) {
//put a hexagon at the players feet //put a hexagon at the players feet
auto hexagonEffect = ResourceManager::Load<EntityFile>("Schema/Entities/DoubleJumpHexagon.xml"); spawnHexagon(player);
EntityFileParser parser(hexagonEffect);
EntityID hexagonEffectID = parser.MergeEntities(m_World);
EntityWrapper hexagonEW = EntityWrapper(m_World, hexagonEffectID);
hexagonEW["Transform"]["Position"] = (glm::vec3)player["Transform"]["Position"];
controller->SetDoubleJumping(true); controller->SetDoubleJumping(true);
// Publish event for client to listen to
Events::DoubleJump e; Events::DoubleJump e;
e.entityID = player.ID;
m_EventBroker->Publish(e); m_EventBroker->Publish(e);
} }
} }
@@ -295,3 +294,26 @@ bool PlayerMovementSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
} }
return true; return true;
} }
bool PlayerMovementSystem::OnDoubleJump(Events::DoubleJump & e)
{
// If entity does not exist, exit
if (!EntityWrapper(m_World, e.entityID).Valid()) {
return false;
}
// If entity IsLocalPlayer, exit
if (e.entityID == m_LocalPlayer.ID) {
return false;
}
spawnHexagon(EntityWrapper(m_World, e.entityID));
}
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);
hexagonEW["Transform"]["Position"] = (glm::vec3)target["Transform"]["Position"];
}
+1 -61
View File
@@ -15,11 +15,6 @@ PlayerSpawnSystem::PlayerSpawnSystem(SystemParams params)
void PlayerSpawnSystem::Update(double dt) void PlayerSpawnSystem::Update(double dt)
{ {
CheckForLatePlayers(dt);
for (auto& spawnReqs : m_SpawnRequests)
{
spawnReqs.timeSinceDeath += dt;
}
//Increase timer. //Increase timer.
m_Timer += dt; m_Timer += dt;
if (m_Timer < m_RespawnTime) { if (m_Timer < m_RespawnTime) {
@@ -40,10 +35,6 @@ void PlayerSpawnSystem::Update(double dt)
int numSpawnedPlayers = 0; int numSpawnedPlayers = 0;
for (auto& req : m_SpawnRequests) { for (auto& req : m_SpawnRequests) {
if (req.timeSinceDeath < 2.5f) {
m_LatePlayersVector.push_back(req);
continue;
}
for (auto& cPlayerSpawn : *playerSpawns) { for (auto& cPlayerSpawn : *playerSpawns) {
EntityWrapper spawner(m_World, cPlayerSpawn.EntityID); EntityWrapper spawner(m_World, cPlayerSpawn.EntityID);
if (!spawner.HasComponent("Spawner")) { if (!spawner.HasComponent("Spawner")) {
@@ -120,8 +111,6 @@ bool PlayerSpawnSystem::OnInputCommand(Events::InputCommand& e)
SpawnRequest req; SpawnRequest req;
req.PlayerID = e.PlayerID; req.PlayerID = e.PlayerID;
req.Team = (ComponentInfo::EnumType)e.Value; req.Team = (ComponentInfo::EnumType)e.Value;
//set timeSinceDeath > 2.5f since we are force-spawning
req.timeSinceDeath = 3.0f;
m_SpawnRequests.push_back(req); m_SpawnRequests.push_back(req);
} else { } else {
return false; return false;
@@ -145,7 +134,7 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
playerName["Text"]["Content"] = e.PlayerName; playerName["Text"]["Content"] = e.PlayerName;
} }
if (m_NetworkEnabled && !IsClient) { if (!IsClient) {
return false; return false;
} }
@@ -175,8 +164,6 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
bool PlayerSpawnSystem::OnPlayerDeath(Events::PlayerDeath& e) bool PlayerSpawnSystem::OnPlayerDeath(Events::PlayerDeath& e)
{ {
LOG_INFO("<- spawnsystem death");
//Only spawn request if network is disabled or we are server. //Only spawn request if network is disabled or we are server.
if (!IsServer && m_NetworkEnabled) { if (!IsServer && m_NetworkEnabled) {
return false; return false;
@@ -190,8 +177,6 @@ bool PlayerSpawnSystem::OnPlayerDeath(Events::PlayerDeath& e)
return false; return false;
} }
LOG_INFO("- spawnsystem death");
if (m_PlayerIDs.count(e.Player.ID) == 0) { if (m_PlayerIDs.count(e.Player.ID) == 0) {
return false; return false;
} }
@@ -199,52 +184,7 @@ bool PlayerSpawnSystem::OnPlayerDeath(Events::PlayerDeath& e)
SpawnRequest req; SpawnRequest req;
req.PlayerID = m_PlayerIDs.at(e.Player.ID); req.PlayerID = m_PlayerIDs.at(e.Player.ID);
req.Team = cTeam["Team"]; req.Team = cTeam["Team"];
req.timeSinceDeath = 0.0f;
m_SpawnRequests.push_back(req); m_SpawnRequests.push_back(req);
LOG_INFO("-> spawnsystem death");
return true; return true;
} }
void PlayerSpawnSystem::CheckForLatePlayers(double dt) {
for (size_t i = 0; i < m_LatePlayersVector.size(); i++)
{
auto& req = m_LatePlayersVector[i];
req.timeSinceDeath += dt;
if (req.timeSinceDeath > 2.5f) {
//good but, this will only spawn them in the next cycle - i.e. not immediately
//m_SpawnRequests.push_back(spawnReq);
//insta spawn
auto playerSpawns = m_World->GetComponents("PlayerSpawn");
for (auto& cPlayerSpawn : *playerSpawns) {
EntityWrapper spawner(m_World, cPlayerSpawn.EntityID);
if (!spawner.HasComponent("Spawner")) {
continue;
}
// If the spawner has a team affiliation, check it
if (spawner.HasComponent("Team")) {
if ((int)spawner["Team"]["Team"] != req.Team) {
continue;
}
}
// Spawn the player!
EntityWrapper player = SpawnerSystem::Spawn(spawner, EntityWrapper::Invalid, "Player");
// Set the player team affiliation
player["Team"]["Team"] = req.Team;
// Publish a PlayerSpawned event
Events::PlayerSpawned e;
e.PlayerID = req.PlayerID;
e.Player = player;
e.Spawner = spawner;
m_EventBroker->Publish(e);
break;
}
//end insta spawn
m_LatePlayersVector.erase(m_LatePlayersVector.begin() + i);
break;
}
}
}
+1 -1
View File
@@ -36,7 +36,7 @@ EntityWrapper SpawnerSystem::Spawn(EntityWrapper spawner, EntityWrapper parent /
} }
// Find any SpawnPoints existing as children of spawner // Find any SpawnPoints existing as children of spawner
auto children = spawner.World->GetChildren(spawner.ID); auto children = spawner.World->GetDirectChildren(spawner.ID);
std::vector<EntityWrapper> spawnPoints; std::vector<EntityWrapper> spawnPoints;
for (auto kv = children.first; kv != children.second; ++kv) { for (auto kv = children.first; kv != children.second; ++kv) {
const EntityID& child = kv->second; const EntityID& child = kv->second;
@@ -386,7 +386,7 @@ bool AssaultWeaponBehaviour::shoot(double damage)
// Check for friendly fire // Check for friendly fire
if ((ComponentInfo::EnumType)victim["Team"]["Team"] == (ComponentInfo::EnumType)m_Player["Team"]["Team"]) { if ((ComponentInfo::EnumType)victim["Team"]["Team"] == (ComponentInfo::EnumType)m_Player["Team"]["Team"]) {
damage = 1; return false;
} }
// Deal damage! // Deal damage!