First person shoot animations
This commit is contained in:
@@ -0,0 +1,34 @@
|
|||||||
|
#include "Sound/EPlaySoundOnEntity.h"
|
||||||
|
#include "Rendering/AnimationSystem.h"
|
||||||
|
#include "WeaponBehaviour.h"
|
||||||
|
#include "../SpawnerSystem.h"
|
||||||
|
|
||||||
|
class AssaultWeaponBehaviour : public WeaponBehaviour
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AssaultWeaponBehaviour(SystemParams systemParams, Octree<EntityAABB>* collisionOctree, EntityWrapper weaponEntity);
|
||||||
|
|
||||||
|
virtual void Fire() override;
|
||||||
|
virtual void CeaseFire() override;
|
||||||
|
virtual void Reload() override;
|
||||||
|
|
||||||
|
virtual void Update(double dt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
EntityWrapper m_FirstPersonModel;
|
||||||
|
// State
|
||||||
|
bool m_Firing = false;
|
||||||
|
bool m_Reloading = false;
|
||||||
|
double m_TimeSinceLastFire = 0.0;
|
||||||
|
|
||||||
|
EventRelay<WeaponBehaviour, Events::AnimationComplete> m_EAnimationComplete;
|
||||||
|
bool OnAnimationComplete(Events::AnimationComplete& e);
|
||||||
|
|
||||||
|
void fireRound();
|
||||||
|
void spawnTracer();
|
||||||
|
float traceRayDistance(glm::vec3 origin, glm::vec3 direction);
|
||||||
|
void playSound();
|
||||||
|
void viewPunch();
|
||||||
|
void playShootAnimation();
|
||||||
|
void playIdleAnimation();
|
||||||
|
};
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef WeaponBehaviour_h__
|
||||||
|
#define WeaponBehaviour_h__
|
||||||
|
|
||||||
|
#include "Core/System.h"
|
||||||
|
#include "Core/Octree.h"
|
||||||
|
#include "Collision/EntityAABB.h"
|
||||||
|
|
||||||
|
class WeaponBehaviour : public System
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WeaponBehaviour(SystemParams systemParams, Octree<EntityAABB>* collisionOctree, EntityWrapper weaponEntity)
|
||||||
|
: System(systemParams)
|
||||||
|
, m_CollisionOctree(collisionOctree)
|
||||||
|
, m_Entity(weaponEntity)
|
||||||
|
{ }
|
||||||
|
virtual ~WeaponBehaviour() = default;
|
||||||
|
|
||||||
|
WeaponBehaviour(const WeaponBehaviour&) = delete;
|
||||||
|
WeaponBehaviour& operator=(const WeaponBehaviour &) = delete;
|
||||||
|
|
||||||
|
virtual void Fire() = 0;
|
||||||
|
virtual void CeaseFire() { }
|
||||||
|
virtual void Reload() { }
|
||||||
|
virtual void Update(double dt) { }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Octree<EntityAABB>* m_CollisionOctree;
|
||||||
|
EntityWrapper m_Entity;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#ifndef WeaponSystem_h__
|
||||||
|
#define WeaponSystem_h__
|
||||||
|
|
||||||
|
#include "Rendering/IRenderer.h"
|
||||||
|
|
||||||
|
#include "Common.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
#include "Core/EPlayerDamage.h"
|
||||||
|
#include "Core/EShoot.h"
|
||||||
|
#include "Core/EPlayerSpawned.h"
|
||||||
|
#include "Input/EInputCommand.h"
|
||||||
|
#include "Core/EntityFile.h"
|
||||||
|
#include "Core/EntityFileParser.h"
|
||||||
|
#include "Core/Octree.h"
|
||||||
|
#include "Collision/EntityAABB.h"
|
||||||
|
#include "Systems/SpawnerSystem.h"
|
||||||
|
#include "Sound/EPlaySoundOnEntity.h"
|
||||||
|
#include "AssaultWeaponBehaviour.h"
|
||||||
|
|
||||||
|
class WeaponSystem : public PureSystem, ImpureSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WeaponSystem(SystemParams params, IRenderer* renderer, Octree<EntityAABB>* collisionOctree);
|
||||||
|
|
||||||
|
virtual void Update(double dt) override;
|
||||||
|
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cPlayer, double dt) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SystemParams m_SystemParams;
|
||||||
|
IRenderer* m_Renderer;
|
||||||
|
Octree<EntityAABB>* m_CollisionOctree;
|
||||||
|
|
||||||
|
std::unordered_map<EntityWrapper, std::shared_ptr<WeaponBehaviour>> m_ActiveWeapons;
|
||||||
|
|
||||||
|
// Events
|
||||||
|
EventRelay<WeaponSystem, Events::PlayerSpawned> m_EPlayerSpawned;
|
||||||
|
bool OnPlayerSpawned(Events::PlayerSpawned& e);
|
||||||
|
EventRelay<WeaponSystem, Events::Shoot> m_EShoot;
|
||||||
|
bool OnShoot(Events::Shoot& e);
|
||||||
|
EventRelay<WeaponSystem, Events::InputCommand> m_EInputCommand;
|
||||||
|
bool OnInputCommand(Events::InputCommand& e);
|
||||||
|
|
||||||
|
void selectWeapon(EntityWrapper player, ComponentInfo::EnumType slot);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,192 +0,0 @@
|
|||||||
#ifndef WeaponSystem_h__
|
|
||||||
#define WeaponSystem_h__
|
|
||||||
|
|
||||||
//#include <GLFW/glfw3.h>
|
|
||||||
//#include <glm/common.hpp>
|
|
||||||
#include "Rendering/IRenderer.h"
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
#include "Core/System.h"
|
|
||||||
#include "Core/EPlayerDamage.h"
|
|
||||||
#include "Core/EShoot.h"
|
|
||||||
#include "Core/EPlayerSpawned.h"
|
|
||||||
#include "Input/EInputCommand.h"
|
|
||||||
#include "Core/EntityFile.h"
|
|
||||||
#include "Core/EntityFileParser.h"
|
|
||||||
#include "Core/Octree.h"
|
|
||||||
#include "Collision/EntityAABB.h"
|
|
||||||
#include "Systems/SpawnerSystem.h"
|
|
||||||
#include "Sound/EPlaySoundOnEntity.h"
|
|
||||||
|
|
||||||
class WeaponBehaviour;
|
|
||||||
|
|
||||||
class WeaponSystem : public PureSystem, ImpureSystem
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WeaponSystem(SystemParams params, IRenderer* renderer, Octree<EntityAABB>* collisionOctree);
|
|
||||||
|
|
||||||
virtual void Update(double dt) override;
|
|
||||||
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cPlayer, double dt) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
SystemParams m_SystemParams;
|
|
||||||
IRenderer* m_Renderer;
|
|
||||||
Octree<EntityAABB>* m_CollisionOctree;
|
|
||||||
|
|
||||||
std::unordered_map<EntityWrapper, std::shared_ptr<WeaponBehaviour>> m_ActiveWeapons;
|
|
||||||
|
|
||||||
// Events
|
|
||||||
EventRelay<WeaponSystem, Events::PlayerSpawned> m_EPlayerSpawned;
|
|
||||||
bool OnPlayerSpawned(Events::PlayerSpawned& e);
|
|
||||||
EventRelay<WeaponSystem, Events::Shoot> m_EShoot;
|
|
||||||
bool OnShoot(Events::Shoot& e);
|
|
||||||
EventRelay<WeaponSystem, Events::InputCommand> m_EInputCommand;
|
|
||||||
bool OnInputCommand(Events::InputCommand& e);
|
|
||||||
|
|
||||||
void selectWeapon(EntityWrapper player, ComponentInfo::EnumType slot);
|
|
||||||
};
|
|
||||||
|
|
||||||
class WeaponBehaviour : public System
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WeaponBehaviour(SystemParams systemParams, Octree<EntityAABB>* collisionOctree, EntityWrapper weaponEntity)
|
|
||||||
: System(systemParams)
|
|
||||||
, m_CollisionOctree(collisionOctree)
|
|
||||||
, m_Entity(weaponEntity)
|
|
||||||
{ }
|
|
||||||
virtual ~WeaponBehaviour() = default;
|
|
||||||
|
|
||||||
WeaponBehaviour(const WeaponBehaviour&) = delete;
|
|
||||||
WeaponBehaviour& operator=(const WeaponBehaviour &) = delete;
|
|
||||||
|
|
||||||
virtual void Fire() = 0;
|
|
||||||
virtual void CeaseFire() { }
|
|
||||||
virtual void Reload() { }
|
|
||||||
virtual void Update(double dt) { }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Octree<EntityAABB>* m_CollisionOctree;
|
|
||||||
EntityWrapper m_Entity;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AssaultWeaponBehaviour : public WeaponBehaviour
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AssaultWeaponBehaviour(SystemParams systemParams, Octree<EntityAABB>* collisionOctree, EntityWrapper weaponEntity)
|
|
||||||
: WeaponBehaviour(systemParams, collisionOctree, weaponEntity)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual void Fire() override
|
|
||||||
{
|
|
||||||
m_TimeSinceLastFire = 0.0;
|
|
||||||
m_Firing = true;
|
|
||||||
fireRound();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void CeaseFire() override
|
|
||||||
{
|
|
||||||
m_Firing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Reload() override
|
|
||||||
{
|
|
||||||
ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"];
|
|
||||||
|
|
||||||
int& magAmmo = cAssaultWeapon["MagazineAmmo"];
|
|
||||||
int magSize = cAssaultWeapon["MagazineSize"];
|
|
||||||
int& ammo = cAssaultWeapon["Ammo"];
|
|
||||||
|
|
||||||
// Don't reload if we're already fully loaded
|
|
||||||
if (magAmmo == magSize) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Throw away rounds in magazine to incentivise ammo sharing
|
|
||||||
int toLoad = glm::min(magSize, ammo);
|
|
||||||
magAmmo = toLoad;
|
|
||||||
ammo -= toLoad;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Update(double dt) override
|
|
||||||
{
|
|
||||||
if (!m_Firing) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_TimeSinceLastFire += dt;
|
|
||||||
|
|
||||||
ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"];
|
|
||||||
if (m_TimeSinceLastFire >= 1.0 / ((double)cAssaultWeapon["RPM"] / 60.0)) {
|
|
||||||
fireRound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_Firing = false;
|
|
||||||
double m_TimeSinceLastFire = 0.0;
|
|
||||||
EntityFile* m_RayRed = nullptr;
|
|
||||||
EntityFile* m_RayBlue = nullptr;
|
|
||||||
|
|
||||||
void fireRound()
|
|
||||||
{
|
|
||||||
ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"];
|
|
||||||
|
|
||||||
int& magAmmo = cAssaultWeapon["MagazineAmmo"];
|
|
||||||
int ammo = cAssaultWeapon["Ammo"];
|
|
||||||
|
|
||||||
// Reload if our magazine is empty
|
|
||||||
if (magAmmo <= 0) {
|
|
||||||
Reload();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fire
|
|
||||||
magAmmo -= 1;
|
|
||||||
spawnTracer();
|
|
||||||
playSound();
|
|
||||||
|
|
||||||
m_TimeSinceLastFire = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void spawnTracer()
|
|
||||||
{
|
|
||||||
if (!IsClient) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityWrapper spawner;
|
|
||||||
if (m_Entity == LocalPlayer) {
|
|
||||||
spawner = m_Entity.FirstChildByName("WeaponMuzzle");
|
|
||||||
} else {
|
|
||||||
spawner = m_Entity.FirstChildByName("ThirdPersonWeaponMuzzle");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!spawner.Valid()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Events::SpawnerSpawn e;
|
|
||||||
e.Spawner = spawner;
|
|
||||||
m_EventBroker->Publish(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
float traceRayDistance(glm::vec3 origin, glm::vec3 direction)
|
|
||||||
{
|
|
||||||
// TODO: Cast a ray and size tracer appropriately
|
|
||||||
return 100.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void playSound()
|
|
||||||
{
|
|
||||||
if (!IsClient) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Events::PlaySoundOnEntity e;
|
|
||||||
e.EmitterID = m_Entity.ID;
|
|
||||||
e.FilePath = "Audio/laser/laser1.wav";
|
|
||||||
m_EventBroker->Publish(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -6,4 +6,5 @@
|
|||||||
<MaxAmmo>360</MaxAmmo>
|
<MaxAmmo>360</MaxAmmo>
|
||||||
<BaseDamage>5</BaseDamage>
|
<BaseDamage>5</BaseDamage>
|
||||||
<RPM>120</RPM>
|
<RPM>120</RPM>
|
||||||
|
<ViewPunch>0.01</ViewPunch>
|
||||||
</AssaultWeapon>
|
</AssaultWeapon>
|
||||||
@@ -22,6 +22,9 @@
|
|||||||
<xs:element name="RPM" type="t:double" minOccurs="0">
|
<xs:element name="RPM" type="t:double" minOccurs="0">
|
||||||
<xs:annotation><xs:documentation>Rate of fire in rounds per minute</xs:documentation></xs:annotation>
|
<xs:annotation><xs:documentation>Rate of fire in rounds per minute</xs:documentation></xs:annotation>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
<xs:element name="ViewPunch" type="t:float" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>View punch in radians for each bullet fired</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
</xs:all>
|
</xs:all>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
|||||||
@@ -2,4 +2,5 @@
|
|||||||
<Player xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Player.xsd">
|
<Player xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Player.xsd">
|
||||||
<MovementSpeed>3</MovementSpeed>
|
<MovementSpeed>3</MovementSpeed>
|
||||||
<CrouchSpeed>1.5</CrouchSpeed>
|
<CrouchSpeed>1.5</CrouchSpeed>
|
||||||
|
<CurrentWishDirection X="0" Y="0" Z="0"/>
|
||||||
</Player>
|
</Player>
|
||||||
@@ -5,12 +5,13 @@
|
|||||||
|
|
||||||
<xs:element name="Player">
|
<xs:element name="Player">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>The player charachter</xs:documentation>
|
<xs:documentation>The player entity</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:all>
|
<xs:all>
|
||||||
<xs:element name="MovementSpeed" type="t:float" minOccurs="0"/>
|
<xs:element name="MovementSpeed" type="t:float" minOccurs="0"/>
|
||||||
<xs:element name="CrouchSpeed" type="t:float" minOccurs="0"/>
|
<xs:element name="CrouchSpeed" type="t:float" minOccurs="0"/>
|
||||||
|
<xs:element name="CurrentWishDirection" type="t:Vector" minOccurs="0"/>
|
||||||
</xs:all>
|
</xs:all>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
|||||||
@@ -34,19 +34,32 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a
|
|||||||
if (!(bool)animationComponent["Loop" + std::to_string(i)]) {
|
if (!(bool)animationComponent["Loop" + std::to_string(i)]) {
|
||||||
if (nextTime > animation->Duration) {
|
if (nextTime > animation->Duration) {
|
||||||
nextTime = animation->Duration;
|
nextTime = animation->Duration;
|
||||||
} else if (nextTime < 0) {
|
|
||||||
nextTime = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
(double&)animationComponent["Speed" + std::to_string(i)] = 0.0;
|
|
||||||
Events::AnimationComplete e;
|
Events::AnimationComplete e;
|
||||||
e.Entity = entity;
|
e.Entity = entity;
|
||||||
e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)];
|
e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)];
|
||||||
m_EventBroker->Publish(e);
|
m_EventBroker->Publish(e);
|
||||||
|
} else if (nextTime < 0) {
|
||||||
|
Events::AnimationComplete e;
|
||||||
|
e.Entity = entity;
|
||||||
|
e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)];
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
nextTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
(double&)animationComponent["Speed" + std::to_string(i)] = 0.0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (nextTime > animation->Duration) {
|
if (nextTime > animation->Duration) {
|
||||||
|
Events::AnimationComplete e;
|
||||||
|
e.Entity = entity;
|
||||||
|
e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)];
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
nextTime -= animation->Duration;
|
nextTime -= animation->Duration;
|
||||||
} else if (nextTime < 0) {
|
} else if (nextTime < 0) {
|
||||||
|
Events::AnimationComplete e;
|
||||||
|
e.Entity = entity;
|
||||||
|
e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)];
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
nextTime += animation->Duration;
|
nextTime += animation->Duration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,12 @@ file(GLOB SOURCE_FILES_Systems
|
|||||||
)
|
)
|
||||||
source_group(Systems FILES ${SOURCE_FILES_Systems})
|
source_group(Systems FILES ${SOURCE_FILES_Systems})
|
||||||
|
|
||||||
|
file(GLOB SOURCE_FILES_Systems_Weapon
|
||||||
|
"${INCLUDE_PATH}/Systems/Weapon/*.h"
|
||||||
|
"Systems/Weapon/*.cpp"
|
||||||
|
)
|
||||||
|
source_group(Systems\\Weapon FILES ${SOURCE_FILES_Systems_Weapon})
|
||||||
|
|
||||||
file(GLOB SOURCE_FILES_Events
|
file(GLOB SOURCE_FILES_Events
|
||||||
"${INCLUDE_PATH}/Events/*.h"
|
"${INCLUDE_PATH}/Events/*.h"
|
||||||
"Events/*.cpp"
|
"Events/*.cpp"
|
||||||
@@ -31,6 +37,7 @@ set(SOURCE_FILES
|
|||||||
${SOURCE_FILES}
|
${SOURCE_FILES}
|
||||||
"Game.cpp"
|
"Game.cpp"
|
||||||
${SOURCE_FILES_Systems}
|
${SOURCE_FILES_Systems}
|
||||||
|
${SOURCE_FILES_Systems_Weapon}
|
||||||
${SOURCE_FILES_Events}
|
${SOURCE_FILES_Events}
|
||||||
${SOURCE_FILES_Network}
|
${SOURCE_FILES_Network}
|
||||||
)
|
)
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@
|
|||||||
#include "Core/EntityFileWriter.h"
|
#include "Core/EntityFileWriter.h"
|
||||||
#include "Game/Systems/CapturePointSystem.h"
|
#include "Game/Systems/CapturePointSystem.h"
|
||||||
#include "Game/Systems/PickupSpawnSystem.h"
|
#include "Game/Systems/PickupSpawnSystem.h"
|
||||||
#include "Game/Systems/WeaponSystem.h"
|
#include "Game/Systems/Weapon/WeaponSystem.h"
|
||||||
#include "Rendering/AnimationSystem.h"
|
#include "Rendering/AnimationSystem.h"
|
||||||
#include "Game/Systems/PlayerHUDSystem.h"
|
#include "Game/Systems/PlayerHUDSystem.h"
|
||||||
#include "Rendering/BoneAttachmentSystem.h"
|
#include "Rendering/BoneAttachmentSystem.h"
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
|
|||||||
|
|
||||||
float playerMovementSpeed = player["Player"]["MovementSpeed"];
|
float playerMovementSpeed = player["Player"]["MovementSpeed"];
|
||||||
float playerCrouchSpeed = player["Player"]["CrouchSpeed"];
|
float playerCrouchSpeed = player["Player"]["CrouchSpeed"];
|
||||||
|
glm::vec3& wishDirection = player["Player"]["CurrentWishDirection"];
|
||||||
|
|
||||||
if (player.HasComponent("Physics")) {
|
if (player.HasComponent("Physics")) {
|
||||||
ComponentWrapper cPhysics = player["Physics"];
|
ComponentWrapper cPhysics = player["Physics"];
|
||||||
@@ -58,7 +59,7 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
|
|||||||
if (player.HasComponent("DashAbility")) {
|
if (player.HasComponent("DashAbility")) {
|
||||||
controller->AssaultDashCheck(dt, ((glm::vec3)cPhysics["Velocity"]).y != 0.0f, player["DashAbility"]["CoolDownMaxTimer"]);
|
controller->AssaultDashCheck(dt, ((glm::vec3)cPhysics["Velocity"]).y != 0.0f, player["DashAbility"]["CoolDownMaxTimer"]);
|
||||||
}
|
}
|
||||||
glm::vec3 wishDirection = controller->Movement() * glm::inverse(glm::quat(ori));
|
wishDirection = controller->Movement() * glm::inverse(glm::quat(ori));
|
||||||
//this makes sure you can only dash in the 4 directions: forw,backw,left,right
|
//this makes sure you can only dash in the 4 directions: forw,backw,left,right
|
||||||
if (controller->AssaultDashDoubleTapped() && controller->Movement().z != 0 && controller->Movement().x != 0) {
|
if (controller->AssaultDashDoubleTapped() && controller->Movement().z != 0 && controller->Movement().x != 0) {
|
||||||
wishDirection = glm::vec3(controller->Movement().x, 0, 0)* glm::inverse(glm::quat(ori));
|
wishDirection = glm::vec3(controller->Movement().x, 0, 0)* glm::inverse(glm::quat(ori));
|
||||||
|
|||||||
@@ -0,0 +1,190 @@
|
|||||||
|
#include "Systems/Weapon/AssaultWeaponBehaviour.h"
|
||||||
|
|
||||||
|
AssaultWeaponBehaviour::AssaultWeaponBehaviour(SystemParams systemParams, Octree<EntityAABB>* collisionOctree, EntityWrapper weaponEntity)
|
||||||
|
: WeaponBehaviour(systemParams, collisionOctree, weaponEntity)
|
||||||
|
{
|
||||||
|
m_FirstPersonModel = m_Entity.FirstChildByName("Hands");
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EAnimationComplete, &AssaultWeaponBehaviour::OnAnimationComplete);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssaultWeaponBehaviour::Fire()
|
||||||
|
{
|
||||||
|
m_TimeSinceLastFire = 0.0;
|
||||||
|
m_Firing = true;
|
||||||
|
fireRound();
|
||||||
|
playShootAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssaultWeaponBehaviour::CeaseFire()
|
||||||
|
{
|
||||||
|
m_Firing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssaultWeaponBehaviour::Reload()
|
||||||
|
{
|
||||||
|
ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"];
|
||||||
|
|
||||||
|
int& magAmmo = cAssaultWeapon["MagazineAmmo"];
|
||||||
|
int magSize = cAssaultWeapon["MagazineSize"];
|
||||||
|
int& ammo = cAssaultWeapon["Ammo"];
|
||||||
|
|
||||||
|
// Don't reload if we're already fully loaded
|
||||||
|
if (magAmmo == magSize) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Throw away rounds in magazine to incentivise ammo sharing
|
||||||
|
int toLoad = glm::min(magSize, ammo);
|
||||||
|
magAmmo = toLoad;
|
||||||
|
ammo -= toLoad;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssaultWeaponBehaviour::Update(double dt)
|
||||||
|
{
|
||||||
|
if (m_Firing) {
|
||||||
|
m_TimeSinceLastFire += dt;
|
||||||
|
|
||||||
|
ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"];
|
||||||
|
if (m_TimeSinceLastFire >= 1.0 / ((double)cAssaultWeapon["RPM"] / 60.0)) {
|
||||||
|
fireRound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_Firing && !m_Reloading) {
|
||||||
|
playIdleAnimation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AssaultWeaponBehaviour::OnAnimationComplete(Events::AnimationComplete& e)
|
||||||
|
{
|
||||||
|
if (e.Entity != m_FirstPersonModel) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (e.Name == "ShootRifle") {
|
||||||
|
// if (!m_Firing) {
|
||||||
|
// playIdleAnimation();
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssaultWeaponBehaviour::fireRound()
|
||||||
|
{
|
||||||
|
ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"];
|
||||||
|
|
||||||
|
int& magAmmo = cAssaultWeapon["MagazineAmmo"];
|
||||||
|
int ammo = cAssaultWeapon["Ammo"];
|
||||||
|
|
||||||
|
// Reload if our magazine is empty
|
||||||
|
if (magAmmo <= 0) {
|
||||||
|
Reload();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fire
|
||||||
|
magAmmo -= 1;
|
||||||
|
spawnTracer();
|
||||||
|
playSound();
|
||||||
|
viewPunch();
|
||||||
|
|
||||||
|
m_TimeSinceLastFire = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssaultWeaponBehaviour::spawnTracer()
|
||||||
|
{
|
||||||
|
if (!IsClient) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityWrapper spawner;
|
||||||
|
if (m_Entity == LocalPlayer) {
|
||||||
|
spawner = m_Entity.FirstChildByName("WeaponMuzzle");
|
||||||
|
} else {
|
||||||
|
spawner = m_Entity.FirstChildByName("ThirdPersonWeaponMuzzle");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!spawner.Valid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Events::SpawnerSpawn e;
|
||||||
|
e.Spawner = spawner;
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
float AssaultWeaponBehaviour::traceRayDistance(glm::vec3 origin, glm::vec3 direction)
|
||||||
|
{
|
||||||
|
// TODO: Cast a ray and size tracer appropriately
|
||||||
|
return 100.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssaultWeaponBehaviour::playSound()
|
||||||
|
{
|
||||||
|
if (!IsClient) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Events::PlaySoundOnEntity e;
|
||||||
|
e.EmitterID = m_Entity.ID;
|
||||||
|
e.FilePath = "Audio/laser/laser1.wav";
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssaultWeaponBehaviour::viewPunch()
|
||||||
|
{
|
||||||
|
EntityWrapper playerCamera = m_Entity.FirstChildByName("Camera");
|
||||||
|
if (!playerCamera.Valid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
float viewPunch = m_Entity["AssaultWeapon"]["ViewPunch"];
|
||||||
|
ComponentWrapper cTransform = playerCamera["Transform"];
|
||||||
|
glm::vec3& orientation = cTransform["Orientation"];
|
||||||
|
orientation.x += viewPunch;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssaultWeaponBehaviour::playShootAnimation()
|
||||||
|
{
|
||||||
|
EntityWrapper firstPersonWeapon = m_Entity.FirstChildByName("Hands");
|
||||||
|
ComponentWrapper cAnimation = firstPersonWeapon["Animation"];
|
||||||
|
cAnimation["AnimationName1"] = "ShootRifle";
|
||||||
|
cAnimation["Weight1"] = 1.0;
|
||||||
|
cAnimation["Time1"] = 0.0;
|
||||||
|
cAnimation["Speed1"] = 1.0;
|
||||||
|
cAnimation["Loop1"] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssaultWeaponBehaviour::playIdleAnimation()
|
||||||
|
{
|
||||||
|
if (!m_FirstPersonModel.Valid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComponentWrapper cAnimation = m_FirstPersonModel["Animation"];
|
||||||
|
std::string& animationName1 = cAnimation["AnimationName1"];
|
||||||
|
double& animationSpeed1 = cAnimation["Speed1"];
|
||||||
|
|
||||||
|
std::string animationToPlay = "Idle";
|
||||||
|
double speedToSet = 1.0;
|
||||||
|
|
||||||
|
ComponentWrapper cPlayer = m_Entity["Player"];
|
||||||
|
glm::vec3 movementDirection = cPlayer["CurrentWishDirection"];
|
||||||
|
if (glm::length2(movementDirection) > 0) {
|
||||||
|
animationToPlay = "Run";
|
||||||
|
ComponentWrapper cPhysics = m_Entity["Physics"];
|
||||||
|
speedToSet = glm::length((glm::vec3)cPhysics["Velocity"]) / (float)cPlayer["MovementSpeed"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (animationName1 != animationToPlay) {
|
||||||
|
cAnimation["AnimationName1"] = animationToPlay;
|
||||||
|
cAnimation["Weight1"] = 1.0;
|
||||||
|
cAnimation["Time1"] = 0.0;
|
||||||
|
cAnimation["Loop1"] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (animationSpeed1 != speedToSet) {
|
||||||
|
cAnimation["Speed1"] = speedToSet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "Systems/WeaponSystem.h"
|
#include "Systems/Weapon/WeaponSystem.h"
|
||||||
|
|
||||||
WeaponSystem::WeaponSystem(SystemParams params, IRenderer* renderer, Octree<EntityAABB>* collisionOctree)
|
WeaponSystem::WeaponSystem(SystemParams params, IRenderer* renderer, Octree<EntityAABB>* collisionOctree)
|
||||||
: System(params)
|
: System(params)
|
||||||
@@ -25,6 +25,7 @@ void WeaponSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cPla
|
|||||||
selectWeapon(entity, 1);
|
selectWeapon(entity, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_EventBroker->Process<WeaponBehaviour>();
|
||||||
m_ActiveWeapons.at(entity)->Update(dt);
|
m_ActiveWeapons.at(entity)->Update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user