Work in progress weapon system
This commit is contained in:
@@ -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
|
||||
@@ -14,6 +14,8 @@ R=Reload
|
||||
Space=Jump
|
||||
LeftControl=Crouch
|
||||
LeftShift=Sprint
|
||||
1=SelectWeapon,1
|
||||
2=SelectWeapon,2
|
||||
F1=ToggleEditor
|
||||
C=ConnectToServer
|
||||
N=SwitchToServer
|
||||
|
||||
@@ -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
@@ -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:Fill" minOccurs="0"/>
|
||||
<xs:element ref="c:Animation" minOccurs="0"/>
|
||||
<xs:element ref="c:AssaultWeapon" minOccurs="0"/>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user