Work in progress weapon system

This commit is contained in:
2016-02-09 23:27:04 +01:00
parent d83190290f
commit 5cea3bed3a
7 changed files with 164 additions and 8 deletions
+86 -7
View File
@@ -9,29 +9,108 @@
#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 <tuple>
#include <vector>
class WeaponSystem : public ImpureSystem
class WeaponSystem : public PureSystem, ImpureSystem
{
public:
WeaponSystem(SystemParams params, IRenderer* renderer);
virtual void Update(double dt) override;
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) override;
private:
IRenderer* m_Renderer;
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 WeaponSystem::OnShoot(Events::Shoot& e);
bool OnShoot(Events::Shoot& e);
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
+2
View File
@@ -14,6 +14,8 @@ R=Reload
Space=Jump
LeftControl=Crouch
LeftShift=Sprint
1=SelectWeapon,1
2=SelectWeapon,2
F1=ToggleEditor
C=ConnectToServer
N=SwitchToServer
+1
View File
@@ -31,4 +31,5 @@
<xs:include schemaLocation="Components/Lifetime.xsd"/>
<xs:include schemaLocation="Components/HiddenForLocalPlayer.xsd"/>
<xs:include schemaLocation="Components/DashAbility.xsd"/>
<xs:include schemaLocation="Components/AssaultWeapon.xsd"/>
</xs:schema>
+8
View File
@@ -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
View File
@@ -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>
+1
View File
@@ -38,6 +38,7 @@
<xs:element ref="c:HiddenForLocalPlayer" minOccurs="0"/>
<xs:element ref="c:Fill" minOccurs="0"/>
<xs:element ref="c:Animation" minOccurs="0"/>
<xs:element ref="c:AssaultWeapon" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
+39 -1
View File
@@ -2,6 +2,7 @@
WeaponSystem::WeaponSystem(SystemParams params, IRenderer* renderer)
: System(params)
, PureSystem("Player")
, ImpureSystem()
, 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)
{
// 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!
if (!IsClient) {
return false;
@@ -39,7 +55,29 @@ bool WeaponSystem::OnInputCommand(Events::InputCommand& e)
return true;
}
bool WeaponSystem::OnShoot(Events::Shoot& eShoot)
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)
{
if (!eShoot.Player.Valid()) {
return false;