Merge commit '0e8b97dbbade6bb39c6f2b8af6c1cfc43ce67cde' into ScoreBoard
# Conflicts: # resources/Schema/Entities/Player.xml # src/Game/Game.cpp
This commit is contained in:
@@ -1,36 +0,0 @@
|
||||
#include "Game/Systems/AmmunitionHUDSystem.h"
|
||||
|
||||
void AmmunitionHUDSystem::Update(double dt)
|
||||
{
|
||||
//Hud element for tracking ammunition from parent with AssaultWeapon component.Child with the name "MagazineAmmo" tracks clip ammunition.Child with the name "Ammo" tracks ammo.</xs:documentation>
|
||||
|
||||
auto ammunitionHUDs = m_World->GetComponents("AmmunitionHUD");
|
||||
if (ammunitionHUDs == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& ammunitionHUDComponent : *ammunitionHUDs) {
|
||||
EntityWrapper entity = EntityWrapper(m_World, ammunitionHUDComponent.EntityID);
|
||||
|
||||
EntityWrapper playerEntity = entity.FirstParentWithComponent("AssaultWeapon");
|
||||
|
||||
if (!playerEntity.Valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
EntityWrapper magazineAmmo = entity.FirstChildByName("MagazineAmmo");
|
||||
if(magazineAmmo.Valid()) {
|
||||
if(magazineAmmo.HasComponent("Text")) {
|
||||
(std::string&)magazineAmmo["Text"]["Content"] = std::to_string((int)playerEntity["AssaultWeapon"]["MagazineAmmo"]);
|
||||
}
|
||||
}
|
||||
|
||||
EntityWrapper ammo = entity.FirstChildByName("Ammo");
|
||||
if (ammo.Valid()) {
|
||||
if (ammo.HasComponent("Text")) {
|
||||
(std::string&)ammo["Text"]["Content"] = std::to_string((int)playerEntity["AssaultWeapon"]["Ammo"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
#include "Game/Systems/TextFieldReader.h"
|
||||
|
||||
void TextFieldReader::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cAmmunitionHUD, double dt)
|
||||
{
|
||||
if (!entity.HasComponent("Text")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the entity to read from
|
||||
const std::string& parentEntityName = cAmmunitionHUD["ParentEntityName"];
|
||||
EntityWrapper readEntity = entity;
|
||||
if (!parentEntityName.empty()) {
|
||||
readEntity = entity.FirstParentByName(parentEntityName);
|
||||
if (!readEntity.Valid()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Find the component to read from
|
||||
const std::string& componentType = cAmmunitionHUD["ComponentType"];
|
||||
if (componentType.empty() || !readEntity.HasComponent(componentType)) {
|
||||
return;
|
||||
}
|
||||
ComponentWrapper component = readEntity[componentType];
|
||||
|
||||
// Find the field to read from
|
||||
const std::string& fieldName = cAmmunitionHUD["Field"];
|
||||
if (fieldName.empty() || component.Info.Fields.count(fieldName) == 0) {
|
||||
return;
|
||||
}
|
||||
const ComponentInfo::Field_t& field = component.Info.Fields.at(fieldName);
|
||||
|
||||
std::string& text = entity["Text"]["Content"];
|
||||
|
||||
if (field.Type == "int") {
|
||||
text = boost::lexical_cast<std::string>((const int&)component[fieldName]);
|
||||
} else if (field.Type == "float") {
|
||||
text = boost::lexical_cast<std::string>((const float&)component[fieldName]);
|
||||
} else if (field.Type == "double") {
|
||||
text = boost::lexical_cast<std::string>((const double&)component[fieldName]);
|
||||
} else if (field.Type == "bool") {
|
||||
text = boost::lexical_cast<std::string>((const bool&)component[fieldName]);
|
||||
} else if (field.Type == "string") {
|
||||
text = (const std::string&)component[fieldName];
|
||||
}
|
||||
}
|
||||
@@ -2,40 +2,76 @@
|
||||
|
||||
void DefenderWeaponBehaviour::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cWeapon, double dt)
|
||||
{
|
||||
(double&)cWeapon["TimeSinceLastFire"] += dt;
|
||||
double& fireCooldown = cWeapon["FireCooldown"];
|
||||
fireCooldown = glm::max(0.0, fireCooldown - dt);
|
||||
|
||||
WeaponBehaviour::UpdateComponent(entity, cWeapon, dt);
|
||||
}
|
||||
|
||||
void DefenderWeaponBehaviour::UpdateWeapon(WeaponInfo& wi, double dt)
|
||||
void DefenderWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt)
|
||||
{
|
||||
ComponentWrapper cWeapon = wi.GetComponent();
|
||||
double& reloadTimer = cWeapon["ReloadTimer"];
|
||||
reloadTimer = glm::max(0.0, reloadTimer - dt);
|
||||
|
||||
bool isFiring = cWeapon["IsFiring"];
|
||||
bool cooldownPassed = (double)cWeapon["TimeSinceLastFire"] >= (60.0 / (double)cWeapon["RPM"]);
|
||||
bool isNotShielding = wi.Player.ChildrenWithComponent("Shield").size() == 0;
|
||||
if (isFiring && cooldownPassed && isNotShielding) {
|
||||
fireShell(wi);
|
||||
double reloadTime = cWeapon["ReloadTime"];
|
||||
bool& isReloading = cWeapon["IsReloading"];
|
||||
if (isReloading && reloadTimer <= 0.0) {
|
||||
int& magAmmo = cWeapon["MagazineAmmo"];
|
||||
int& magSize = cWeapon["MagazineSize"];
|
||||
int& ammo = cWeapon["Ammo"];
|
||||
if (magAmmo < magSize && ammo > 0) {
|
||||
ammo -= 1;
|
||||
magAmmo += 1;
|
||||
reloadTimer = reloadTime;
|
||||
} else {
|
||||
isReloading = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (canFire(cWeapon, wi)) {
|
||||
fireShell(cWeapon, wi);
|
||||
}
|
||||
}
|
||||
|
||||
void DefenderWeaponBehaviour::OnPrimaryFire(WeaponInfo& wi)
|
||||
void DefenderWeaponBehaviour::OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi)
|
||||
{
|
||||
ComponentWrapper cWeapon = wi.GetComponent();
|
||||
cWeapon["IsFiring"] = true;
|
||||
bool cooldownPassed = (double)cWeapon["TimeSinceLastFire"] >= (60.0 / (double)cWeapon["RPM"]);
|
||||
bool isNotShielding = wi.Player.ChildrenWithComponent("Shield").size() == 0;
|
||||
if (cooldownPassed && isNotShielding) {
|
||||
fireShell(wi);
|
||||
cWeapon["TriggerHeld"] = true;
|
||||
if (canFire(cWeapon, wi)) {
|
||||
fireShell(cWeapon, wi);
|
||||
}
|
||||
}
|
||||
|
||||
void DefenderWeaponBehaviour::OnCeasePrimaryFire(WeaponInfo& wi)
|
||||
void DefenderWeaponBehaviour::OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi)
|
||||
{
|
||||
ComponentWrapper cWeapon = wi.GetComponent();
|
||||
cWeapon["IsFiring"] = false;
|
||||
cWeapon["TriggerHeld"] = false;
|
||||
}
|
||||
|
||||
bool DefenderWeaponBehaviour::OnInputCommand(WeaponInfo& wi, const Events::InputCommand& e)
|
||||
void DefenderWeaponBehaviour::OnReload(ComponentWrapper cWeapon, WeaponInfo& wi)
|
||||
{
|
||||
bool& isReloading = cWeapon["IsReloading"];
|
||||
if (isReloading) {
|
||||
return;
|
||||
}
|
||||
|
||||
int& magAmmo = cWeapon["MagazineAmmo"];
|
||||
int& magSize = cWeapon["MagazineSize"];
|
||||
if (magAmmo >= magSize) {
|
||||
return;
|
||||
}
|
||||
int& ammo = cWeapon["Ammo"];
|
||||
if (ammo <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
double reloadTime = cWeapon["ReloadTime"];
|
||||
double& reloadTimer = cWeapon["ReloadTimer"];
|
||||
|
||||
// Start reload
|
||||
isReloading = true;
|
||||
reloadTimer = reloadTime;
|
||||
}
|
||||
|
||||
bool DefenderWeaponBehaviour::OnInputCommand(ComponentWrapper cWeapon, WeaponInfo& wi, const Events::InputCommand& e)
|
||||
{
|
||||
if (e.Command == "SpecialAbility" && IsServer) {
|
||||
EntityWrapper attachment = wi.Player.FirstChildByName("ShieldAttachment");
|
||||
@@ -51,17 +87,23 @@ bool DefenderWeaponBehaviour::OnInputCommand(WeaponInfo& wi, const Events::Input
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DefenderWeaponBehaviour::OnSetCamera(const Events::SetCamera& e)
|
||||
void DefenderWeaponBehaviour::fireShell(ComponentWrapper cWeapon, WeaponInfo& wi)
|
||||
{
|
||||
m_CurrentCamera = e.CameraEntity;
|
||||
return true;
|
||||
}
|
||||
cWeapon["FireCooldown"] = 60.0 / (double)cWeapon["RPM"];
|
||||
|
||||
void DefenderWeaponBehaviour::fireShell(WeaponInfo& wi)
|
||||
{
|
||||
ComponentWrapper cWeapon = wi.GetComponent();
|
||||
// Stop reloading
|
||||
bool& isReloading = cWeapon["IsReloading"];
|
||||
isReloading = false;
|
||||
|
||||
// Ammo
|
||||
int& magAmmo = cWeapon["MagazineAmmo"];
|
||||
if (magAmmo <= 0) {
|
||||
OnReload(cWeapon, wi);
|
||||
return;
|
||||
} else {
|
||||
magAmmo -= 1;
|
||||
}
|
||||
|
||||
cWeapon["TimeSinceLastFire"] = 0.0;
|
||||
int numPellets = cWeapon["NumPellets"];
|
||||
float spreadAngle = cWeapon["SpreadAngle"];
|
||||
std::uniform_real_distribution<float> randomSpreadAngle(-spreadAngle, spreadAngle);
|
||||
@@ -95,13 +137,12 @@ void DefenderWeaponBehaviour::fireShell(WeaponInfo& wi)
|
||||
orientation.x += angles.x;
|
||||
orientation.y += angles.y;
|
||||
glm::vec3 trajectory = direction * distance;
|
||||
dealDamage(wi, direction, pelletDamage);
|
||||
dealDamage(cWeapon, wi, direction, pelletDamage);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DefenderWeaponBehaviour::dealDamage(WeaponInfo& wi, glm::vec3 direction, double damage)
|
||||
void DefenderWeaponBehaviour::dealDamage(ComponentWrapper cWeapon, WeaponInfo& wi, glm::vec3 direction, double damage)
|
||||
{
|
||||
// Only deal damage client side
|
||||
if (!IsClient) {
|
||||
@@ -160,16 +201,13 @@ void DefenderWeaponBehaviour::dealDamage(WeaponInfo& wi, glm::vec3 direction, do
|
||||
LOG_DEBUG("Damage: %f", damage);
|
||||
}
|
||||
|
||||
float DefenderWeaponBehaviour::traceRayDistance(glm::vec3 origin, glm::vec3 direction)
|
||||
bool DefenderWeaponBehaviour::canFire(ComponentWrapper cWeapon, WeaponInfo& wi)
|
||||
{
|
||||
float distance;
|
||||
glm::vec3 pos;
|
||||
auto entity = Collision::EntityFirstHitByRay(Ray(origin, direction), m_CollisionOctree, distance, pos);
|
||||
if (entity) {
|
||||
return distance;
|
||||
} else {
|
||||
return 100.f;
|
||||
}
|
||||
bool triggerHeld = cWeapon["TriggerHeld"];
|
||||
bool cooldownPassed = (double)cWeapon["FireCooldown"] <= 0.0;
|
||||
bool isNotShielding = wi.Player.ChildrenWithComponent("Shield").size() == 0;
|
||||
// TODO: Ammo checks
|
||||
return triggerHeld && cooldownPassed && isNotShielding;
|
||||
}
|
||||
|
||||
Camera DefenderWeaponBehaviour::cameraFromEntity(EntityWrapper camera)
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
#include "Systems/Weapon/SidearmWeaponBehaviour.h"
|
||||
|
||||
void SidearmWeaponBehaviour::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cWeapon, double dt)
|
||||
{
|
||||
double& cooldown = cWeapon["FireCooldown"];
|
||||
if (cooldown > 0) {
|
||||
cooldown -= dt;
|
||||
if (cooldown < 0) {
|
||||
cooldown = 0;
|
||||
}
|
||||
}
|
||||
WeaponBehaviour::UpdateComponent(entity, cWeapon, dt);
|
||||
}
|
||||
|
||||
void SidearmWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt)
|
||||
{
|
||||
if ((bool)cWeapon["Automatic"] && canFire(cWeapon)) {
|
||||
fireBullet(cWeapon, wi);
|
||||
}
|
||||
}
|
||||
|
||||
void SidearmWeaponBehaviour::OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi)
|
||||
{
|
||||
cWeapon["TriggerHeld"] = true;
|
||||
if (canFire(cWeapon)) {
|
||||
fireBullet(cWeapon, wi);
|
||||
}
|
||||
}
|
||||
|
||||
void SidearmWeaponBehaviour::OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi)
|
||||
{
|
||||
cWeapon["TriggerHeld"] = false;
|
||||
}
|
||||
|
||||
void SidearmWeaponBehaviour::OnEquip(ComponentWrapper cWeapon, WeaponInfo& wi)
|
||||
{
|
||||
cWeapon["FireCooldown"] = (double)cWeapon["EquipTime"];
|
||||
}
|
||||
|
||||
void SidearmWeaponBehaviour::OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi)
|
||||
{
|
||||
// Make sure the trigger is released if weapon is holstered while firing
|
||||
cWeapon["TriggerHeld"] = false;
|
||||
|
||||
// Cancel any reload
|
||||
cWeapon["IsReloading"] = false;
|
||||
cWeapon["ReloadTimer"] = 0.0;
|
||||
|
||||
LOG_DEBUG("HOLSTER");
|
||||
}
|
||||
|
||||
void SidearmWeaponBehaviour::fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi)
|
||||
{
|
||||
cWeapon["FireCooldown"] = 60.0 / (double)cWeapon["RPM"];
|
||||
|
||||
// Get weapon model based on current person
|
||||
EntityWrapper weaponModelEntity = getRelevantWeaponModelEntity(wi);
|
||||
if (!weaponModelEntity.Valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Tracer
|
||||
EntityWrapper tracerSpawner = weaponModelEntity.FirstChildByName("WeaponMuzzle");
|
||||
if (tracerSpawner.Valid()) {
|
||||
glm::vec3 origin = Transform::AbsolutePosition(tracerSpawner);
|
||||
glm::vec3 direction = Transform::AbsoluteOrientation(tracerSpawner) * glm::vec3(0, 0, -1);
|
||||
float distance = traceRayDistance(origin, direction);
|
||||
EntityWrapper ray = SpawnerSystem::Spawn(tracerSpawner);
|
||||
((glm::vec3&)ray["Transform"]["Scale"]).z = (distance / 100.f);
|
||||
}
|
||||
}
|
||||
|
||||
bool SidearmWeaponBehaviour::canFire(ComponentWrapper cWeapon)
|
||||
{
|
||||
bool triggerHeld = cWeapon["TriggerHeld"];
|
||||
double& cooldown = cWeapon["FireCooldown"];
|
||||
// TODO: Ammo checks
|
||||
return triggerHeld && cooldown <= 0.0;
|
||||
}
|
||||
Reference in New Issue
Block a user