Work in progress weapon system
This commit is contained in:
@@ -9,29 +9,108 @@
|
|||||||
#include "Core/System.h"
|
#include "Core/System.h"
|
||||||
#include "Core/EPlayerDamage.h"
|
#include "Core/EPlayerDamage.h"
|
||||||
#include "Core/EShoot.h"
|
#include "Core/EShoot.h"
|
||||||
|
#include "Core/EPlayerSpawned.h"
|
||||||
#include "Input/EInputCommand.h"
|
#include "Input/EInputCommand.h"
|
||||||
#include "Core/EntityFile.h"
|
#include "Core/EntityFile.h"
|
||||||
#include "Core/EntityFileParser.h"
|
#include "Core/EntityFileParser.h"
|
||||||
|
|
||||||
#include <tuple>
|
class WeaponSystem : public PureSystem, ImpureSystem
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
|
||||||
class WeaponSystem : public ImpureSystem
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WeaponSystem(SystemParams params, IRenderer* renderer);
|
WeaponSystem(SystemParams params, IRenderer* renderer);
|
||||||
|
|
||||||
virtual void Update(double dt) override;
|
virtual void Update(double dt) override;
|
||||||
|
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IRenderer* m_Renderer;
|
IRenderer* m_Renderer;
|
||||||
|
|
||||||
|
std::unordered_map<EntityWrapper, std::shared_ptr<WeaponBehaviour>> m_ActiveWeapons;
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
|
EventRelay<WeaponSystem, Events::PlayerSpawned> m_EPlayerSpawned;
|
||||||
|
bool OnPlayerSpawned(Events::PlayerSpawned& e);
|
||||||
EventRelay<WeaponSystem, Events::Shoot> m_EShoot;
|
EventRelay<WeaponSystem, Events::Shoot> m_EShoot;
|
||||||
bool WeaponSystem::OnShoot(Events::Shoot& e);
|
bool OnShoot(Events::Shoot& e);
|
||||||
EventRelay<WeaponSystem, Events::InputCommand> m_EInputCommand;
|
EventRelay<WeaponSystem, Events::InputCommand> m_EInputCommand;
|
||||||
bool WeaponSystem::OnInputCommand(Events::InputCommand& e);
|
bool OnInputCommand(Events::InputCommand& e);
|
||||||
|
|
||||||
|
void selectWeapon(EntityWrapper player, ComponentInfo::EnumType slot);
|
||||||
|
};
|
||||||
|
|
||||||
|
class WeaponBehaviour
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WeaponBehaviour(EntityWrapper weaponEntity)
|
||||||
|
: m_Entity(weaponEntity)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void Fire() = 0;
|
||||||
|
virtual void CeaseFire() { }
|
||||||
|
virtual void Reload() { }
|
||||||
|
virtual void Update(double dt) { }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
EntityWrapper m_Entity;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AssaultWeaponBehaviour : public WeaponBehaviour
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AssaultWeaponBehaviour(EntityWrapper weaponEntity)
|
||||||
|
: WeaponBehaviour(weaponEntity)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void Fire() override
|
||||||
|
{
|
||||||
|
m_TimeSinceLastFire = 0.0;
|
||||||
|
m_Firing = true;
|
||||||
|
fireRound();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void CeaseFire() override
|
||||||
|
{
|
||||||
|
m_Firing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Update(double dt) override
|
||||||
|
{
|
||||||
|
if (!m_Firing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_TimeSinceLastFire += dt;
|
||||||
|
|
||||||
|
ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"];
|
||||||
|
if (m_TimeSinceLastFire > (double)cAssaultWeapon["RPM"] / 60.0) {
|
||||||
|
fireRound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_Firing = false;
|
||||||
|
double m_TimeSinceLastFire = 0.0;
|
||||||
|
ComponentWrapper m_Component;
|
||||||
|
|
||||||
|
void fireRound()
|
||||||
|
{
|
||||||
|
ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"];
|
||||||
|
|
||||||
|
int& magAmmo = cAssaultWeapon["MagazineAmmo"];
|
||||||
|
int ammo = cAssaultWeapon["Ammo"];
|
||||||
|
|
||||||
|
// Reload if our magazine is empty and we have ammo to fill it with
|
||||||
|
if (magAmmo <= 0 && ammo > 0) {
|
||||||
|
CeaseFire();
|
||||||
|
Reload();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fire
|
||||||
|
magAmmo -= 1;
|
||||||
|
|
||||||
|
m_TimeSinceLastFire = 0.0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -14,6 +14,8 @@ R=Reload
|
|||||||
Space=Jump
|
Space=Jump
|
||||||
LeftControl=Crouch
|
LeftControl=Crouch
|
||||||
LeftShift=Sprint
|
LeftShift=Sprint
|
||||||
|
1=SelectWeapon,1
|
||||||
|
2=SelectWeapon,2
|
||||||
F1=ToggleEditor
|
F1=ToggleEditor
|
||||||
C=ConnectToServer
|
C=ConnectToServer
|
||||||
N=SwitchToServer
|
N=SwitchToServer
|
||||||
|
|||||||
@@ -31,4 +31,5 @@
|
|||||||
<xs:include schemaLocation="Components/Lifetime.xsd"/>
|
<xs:include schemaLocation="Components/Lifetime.xsd"/>
|
||||||
<xs:include schemaLocation="Components/HiddenForLocalPlayer.xsd"/>
|
<xs:include schemaLocation="Components/HiddenForLocalPlayer.xsd"/>
|
||||||
<xs:include schemaLocation="Components/DashAbility.xsd"/>
|
<xs:include schemaLocation="Components/DashAbility.xsd"/>
|
||||||
|
<xs:include schemaLocation="Components/AssaultWeapon.xsd"/>
|
||||||
</xs:schema>
|
</xs:schema>
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<AssaultWeapon xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="AssaultWeapon.xsd">
|
||||||
|
<MagazineAmmo>32</MagazineAmmo>
|
||||||
|
<MagazineSize>32</MagazineSize>
|
||||||
|
<Ammo>360</Ammo>
|
||||||
|
<MaxAmmo>360</MaxAmmo>
|
||||||
|
<RPM>40</RPM>
|
||||||
|
</AssaultWeapon>
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||||
|
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||||
|
|
||||||
|
<xs:element name="AssaultWeapon">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="MagazineAmmo" type="t:int" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Ammo currently loaded into the magazine</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="MagazineSize" type="t:int" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Max number of rounds in a magazine</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="Ammo" type="t:int" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Current ammo carried</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="MaxAmmo" type="t:int" minOccurs="0">
|
||||||
|
<xs:annotation><xs:documentation>Maximum ammo able to be carried</xs:documentation></xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<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:element>
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
||||||
@@ -38,6 +38,7 @@
|
|||||||
<xs:element ref="c:HiddenForLocalPlayer" minOccurs="0"/>
|
<xs:element ref="c:HiddenForLocalPlayer" minOccurs="0"/>
|
||||||
<xs:element ref="c:Fill" minOccurs="0"/>
|
<xs:element ref="c:Fill" minOccurs="0"/>
|
||||||
<xs:element ref="c:Animation" minOccurs="0"/>
|
<xs:element ref="c:Animation" minOccurs="0"/>
|
||||||
|
<xs:element ref="c:AssaultWeapon" minOccurs="0"/>
|
||||||
</xs:all>
|
</xs:all>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
WeaponSystem::WeaponSystem(SystemParams params, IRenderer* renderer)
|
WeaponSystem::WeaponSystem(SystemParams params, IRenderer* renderer)
|
||||||
: System(params)
|
: System(params)
|
||||||
|
, PureSystem("Player")
|
||||||
, ImpureSystem()
|
, ImpureSystem()
|
||||||
, m_Renderer(renderer)
|
, m_Renderer(renderer)
|
||||||
{
|
{
|
||||||
@@ -14,8 +15,23 @@ void WeaponSystem::Update(double dt)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WeaponSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
bool WeaponSystem::OnInputCommand(Events::InputCommand& e)
|
bool WeaponSystem::OnInputCommand(Events::InputCommand& e)
|
||||||
{
|
{
|
||||||
|
// Make sure player is alive
|
||||||
|
if (!e.Player.Valid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Weapon selection
|
||||||
|
if (e.Command == "SelectWeapon") {
|
||||||
|
selectWeapon(e.Player, static_cast<ComponentInfo::EnumType>(e.Value));
|
||||||
|
}
|
||||||
|
|
||||||
// Only shoot client-side!
|
// Only shoot client-side!
|
||||||
if (!IsClient) {
|
if (!IsClient) {
|
||||||
return false;
|
return false;
|
||||||
@@ -39,6 +55,28 @@ bool WeaponSystem::OnInputCommand(Events::InputCommand& e)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WeaponSystem::selectWeapon(EntityWrapper player, ComponentInfo::EnumType slot)
|
||||||
|
{
|
||||||
|
// Primary
|
||||||
|
if (slot == 1) {
|
||||||
|
// TODO: if class...
|
||||||
|
m_ActiveWeapons[player] = std::make_shared<AssaultWeaponBehaviour>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Secondary
|
||||||
|
if (slot == 2) {
|
||||||
|
//m_ActiveWeapons[player] = std::make_shared<PistolWeaponBehaviour>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WeaponSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
|
||||||
|
{
|
||||||
|
// Select primary weapon on player spawn
|
||||||
|
// TODO: Select the active one specified by player component
|
||||||
|
selectWeapon(e.Player, 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool WeaponSystem::OnShoot(Events::Shoot& eShoot)
|
bool WeaponSystem::OnShoot(Events::Shoot& eShoot)
|
||||||
{
|
{
|
||||||
if (!eShoot.Player.Valid()) {
|
if (!eShoot.Player.Valid()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user