diff --git a/include/Game/Systems/Weapon/SidearmWeaponBehaviour.h b/include/Game/Systems/Weapon/SidearmWeaponBehaviour.h index 10e6105a..7aa20025 100644 --- a/include/Game/Systems/Weapon/SidearmWeaponBehaviour.h +++ b/include/Game/Systems/Weapon/SidearmWeaponBehaviour.h @@ -4,6 +4,8 @@ #include "WeaponBehaviour.h" #include "Collision/Collision.h" #include "Core/EPlayerDamage.h" +#include "Sound/EPlaySoundOnEntity.h" +#include "Rendering/EAutoAnimationBlend.h" class SidearmWeaponBehaviour : public WeaponBehaviour { @@ -18,6 +20,7 @@ public: void UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt) override; void OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) override; void OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) override; + void OnReload(ComponentWrapper cWeapon, WeaponInfo& wi) override; void OnEquip(ComponentWrapper cWeapon, WeaponInfo& wi) override; void OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi) override; @@ -32,6 +35,15 @@ private: // Utility bool canFire(ComponentWrapper cWeapon); bool playerInFirstPerson(EntityWrapper player); + + bool dealDamage(ComponentWrapper cWeapon, WeaponInfo& wi); + void giveAmmo(ComponentWrapper cWeapon, WeaponInfo& wi, EntityWrapper receiver); + + + void CheckAmmo(ComponentWrapper cWeapon, WeaponInfo& wi); + void RemoveFrindlyAmmoHUD(WeaponInfo& wi); + + //float traceRayDistance(glm::vec3 origin, glm::vec3 direction); }; diff --git a/resources/Schema/Components/SidearmWeapon.xml b/resources/Schema/Components/SidearmWeapon.xml index bc90c067..968306a6 100644 --- a/resources/Schema/Components/SidearmWeapon.xml +++ b/resources/Schema/Components/SidearmWeapon.xml @@ -11,6 +11,7 @@ 0.5 false 0 + false false 0 \ No newline at end of file diff --git a/resources/Schema/Components/SidearmWeapon.xsd b/resources/Schema/Components/SidearmWeapon.xsd index 514bf354..2c1df4a1 100644 --- a/resources/Schema/Components/SidearmWeapon.xsd +++ b/resources/Schema/Components/SidearmWeapon.xsd @@ -44,6 +44,7 @@ + diff --git a/resources/Schema/Entities/FriendlyAmmoHUD.xml b/resources/Schema/Entities/FriendlyAmmoHUD.xml new file mode 100644 index 00000000..5ab1b754 --- /dev/null +++ b/resources/Schema/Entities/FriendlyAmmoHUD.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + Models/Core/UnitQuad.mesh + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + + + + + + + + + 88 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + diff --git a/resources/Schema/Entities/PlayerAssaultBlue.xml b/resources/Schema/Entities/PlayerAssaultBlue.xml index 64141757..7a2010e6 100644 --- a/resources/Schema/Entities/PlayerAssaultBlue.xml +++ b/resources/Schema/Entities/PlayerAssaultBlue.xml @@ -14,12 +14,8 @@ - - - - - + @@ -30,7 +26,6 @@ - @@ -70,9 +65,10 @@ - Textures/Weapons/Crosshair/SmallThickHoleDot.png - false + Models/Core/UnitQuad.mesh + + Textures/Weapons/Crosshair/SmallThickHoleDot.png @@ -101,8 +97,9 @@ - Textures/Core/UnitHexagon.png + Models/Core/UnitQuad.mesh + Textures/Core/UnitHexagon.png @@ -119,8 +116,9 @@ 2 - Textures/Core/UnitHexagon_Rotated.png + Models/Core/UnitQuad.mesh + Textures/Core/UnitHexagon_Rotated.png @@ -135,8 +133,9 @@ - Textures/Core/UnitHexagon.png + Models/Core/UnitQuad.mesh + Textures/Core/UnitHexagon.png @@ -153,8 +152,9 @@ 3 - Textures/Core/UnitHexagon_Rotated.png + Models/Core/UnitQuad.mesh + Textures/Core/UnitHexagon_Rotated.png @@ -169,8 +169,9 @@ - Textures/Core/UnitHexagon.png + Models/Core/UnitQuad.mesh + Textures/Core/UnitHexagon.png @@ -188,8 +189,9 @@ 4 - Textures/Core/UnitHexagon_Rotated.png + Models/Core/UnitQuad.mesh + Textures/Core/UnitHexagon_Rotated.png @@ -204,8 +206,9 @@ - Textures/Core/UnitHexagon.png + Models/Core/UnitQuad.mesh + Textures/Core/UnitHexagon.png @@ -222,8 +225,9 @@ 1 - Textures/Core/UnitHexagon_Rotated.png + Models/Core/UnitQuad.mesh + Textures/Core/UnitHexagon_Rotated.png @@ -238,8 +242,9 @@ - Textures/Core/UnitHexagon.png + Models/Core/UnitQuad.mesh + Textures/Core/UnitHexagon.png @@ -255,8 +260,9 @@ - Textures/Core/UnitHexagon_Rotated.png + Models/Core/UnitQuad.mesh + Textures/Core/UnitHexagon_Rotated.png @@ -379,8 +385,9 @@ - Textures/HealthHUD3.png + Models/Core/UnitQuad.mesh + Textures/HealthHUD3.png @@ -403,9 +410,10 @@ - Textures/Icons/Boosts/Assault-01.png - false + Models/Core/UnitQuad.mesh + + Textures/Icons/Boosts/Assault-01.png @@ -422,9 +430,10 @@ - Textures/Icons/Boosts/Defender-01.png - false + Models/Core/UnitQuad.mesh + + Textures/Icons/Boosts/Defender-01.png @@ -441,9 +450,10 @@ - Textures/Icons/Boosts/Sniper-01.png - false + Models/Core/UnitQuad.mesh + + Textures/Icons/Boosts/Sniper-01.png @@ -463,9 +473,10 @@ - Textures\Icons\Abilities\Superman-01.png - false + Models/Core/UnitQuad.mesh + + Textures\Icons\Abilities\Superman-01.png @@ -517,11 +528,11 @@ - Schema/Entities/WeaponDefenderBlueView.xml + Schema/Entities/WeaponSidearmAssaultBlueView.xml - DefenderWeapon + SidearmWeapon @@ -570,8 +581,8 @@ Schema/Entities/WeaponAssaultBlueWorld.xml - - + + AssaultWeapon @@ -588,11 +599,11 @@ R_Arm_Weapon_Joint - Schema/Entities/SidearmWeaponWorld.xml + Schema/Entities/SidearmWeaponBlueWorld.xml - - + + SidearmWeapon @@ -659,7 +670,7 @@ CrouchStrafeLeftF - + true @@ -670,7 +681,7 @@ CrouchStrafeRightF - + true @@ -683,7 +694,7 @@ CrouchWalkF - + true @@ -696,7 +707,7 @@ CrouchF - + true @@ -739,7 +750,7 @@ WalkF - + true @@ -750,7 +761,7 @@ RunF - + 2 true @@ -774,7 +785,7 @@ StrafeLeftF - + 2 true @@ -786,7 +797,7 @@ StrafeRightF - + 2 true @@ -802,7 +813,7 @@ IdleF - + true @@ -891,10 +902,10 @@ - + - DashRightF + DashLeftF 1.7999999523162842 false @@ -903,10 +914,10 @@ - + - DashLeftF + DashRightF 1.7999999523162842 false @@ -926,15 +937,15 @@ - AssaultWeaponBlend + AssaultWeapon SidearmWeapon - 0 + 1 true - + Aim @@ -999,7 +1010,7 @@ IdleAssaultRifleU - + true true @@ -1011,7 +1022,7 @@ IdleAssaultRifleU - + true true @@ -1038,6 +1049,104 @@ + + + + Aim + WeaponBlend + + + + + + + + MovementBlend2 + ActionBlend + + + + + + + + Idle + Run + 0 + + + + + + + + IdleSecWepU + true + + + + + + + + + IdleSecWepU + true + + + + + + + + + + + Reload + Fire + 1 + + + + + + + + ReloadSwitchU + false + + + + + + + + + ShootSecWepU + false + + + + + + + + + + + + + AimSecWepA + + false + true + + + + + + + @@ -1087,9 +1196,10 @@ - Textures/Icons/Arrow.png - false + Models/Core/UnitQuad.mesh + + Textures/Icons/Arrow.png diff --git a/resources/Schema/Entities/SidearmWeaponBlendTree.xlm b/resources/Schema/Entities/SidearmWeaponBlendTree.xlm new file mode 100644 index 00000000..8a3dfb8e --- /dev/null +++ b/resources/Schema/Entities/SidearmWeaponBlendTree.xlm @@ -0,0 +1,101 @@ + + + + + + Aim + WeaponBlend + + + + + + + + + MovementBlend2 + ActionBlend + + + + + + + + Reload + Fire + + + + + + + + ReloadSwitchU + false + + + + + + + + + ShootSecWepU + false + + + + + + + + + + + Idle + Run + + + + + + + + IdleSecWepU + true + + + + + + + + + IdleSecWepU + true + + + + + + + + + + + + + AimSecWepA + + 0.10000000149011612 + false + true + + + + + + + + diff --git a/resources/Schema/Entities/WeaponSidearmAssaultBlueView.xml b/resources/Schema/Entities/WeaponSidearmAssaultBlueView.xml new file mode 100644 index 00000000..c3c06142 --- /dev/null +++ b/resources/Schema/Entities/WeaponSidearmAssaultBlueView.xml @@ -0,0 +1,202 @@ + + + + + + MovementBlend + ActionBlend + + + Models/Characters/Assault/FirstPersonAssaultBlue.mesh + + + + + + + + + Idle + Run + 1 + true + + + + + + + + IdleSecF + true + true + + + + + + + + + RunSecF + true + true + + + + + + + + + + + Fire + Reload + 0 + + + + + + + + ShootSecF + false + + + + + + + + + ReloadSwitchSecF + false + + + + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Blue/SecondaryWeaponBlue.mesh + + + + + + + + + + + Schema/Entities/Ray2Red.xml + + + + + + + + + + + Schema/Entities/WeaponSidearmReloadEffectView.xml + + + + + + + + + + + R_Ammo_Joint + + + + + + + + + + + + Models/Core/UnitQuad.mesh + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + + + + + + + 16 + Fonts/DroidSans.ttf,64 + + + + + SidearmWeapon + MagazineAmmo + + + + + + + + + + + + 8 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + + + Schema/Entities/FriendlyAmmoHUD.xml + + + + + + + + + + + + diff --git a/resources/Schema/Entities/WeaponSidearmReloadEffectView.xml b/resources/Schema/Entities/WeaponSidearmReloadEffectView.xml new file mode 100644 index 00000000..fce19d7f --- /dev/null +++ b/resources/Schema/Entities/WeaponSidearmReloadEffectView.xml @@ -0,0 +1,54 @@ + + + + + + 2 + + + + + + + + + + + 1 + 1 + -1 + 1 + + true + + + Models/Weapons/Blue/SecondaryWeaponBlue.mesh + true + + + + + + + + + 1 + + + + + 1 + + true + + + Models/Weapons/Blue/SecondaryWeaponBlue.mesh + true + + + + + + + + diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index fad64d77..e30c2e9f 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -75,18 +75,18 @@ void AnimationSystem::UpdateAnimations(double dt) try { model = ResourceManager::Load<::Model, true>(modelEntity["Model"]["Resource"]); } catch (const std::exception&) { - return; + continue; } Skeleton* skeleton = model->m_RawModel->m_Skeleton; if (skeleton == nullptr) { - return; + continue; } const Skeleton::Animation* animation = skeleton->GetAnimation(animationC["AnimationName"]); if (animation == nullptr) { - continue;; + continue; } double animationSpeed = (double)animationC["Speed"]; diff --git a/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp b/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp index 8c92b35b..cf2aa9c5 100644 --- a/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp +++ b/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp @@ -166,6 +166,14 @@ void AssaultWeaponBehaviour::OnReload(ComponentWrapper cWeapon, WeaponInfo& wi) void AssaultWeaponBehaviour::OnEquip(ComponentWrapper cWeapon, WeaponInfo& wi) { cWeapon["FireCooldown"] = (double)cWeapon["EquipTime"]; + + if (wi.ThirdPersonPlayerModel.Valid()) { + Events::AutoAnimationBlend b1; + b1.RootNode = wi.ThirdPersonPlayerModel; + b1.NodeName = "AssaultWeapon"; + b1.SingleLevelBlend = true; + m_EventBroker->Publish(b1); + } } void AssaultWeaponBehaviour::OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi) diff --git a/src/Game/Systems/Weapon/SidearmWeaponBehaviour.cpp b/src/Game/Systems/Weapon/SidearmWeaponBehaviour.cpp index db5a9ede..7ac802de 100644 --- a/src/Game/Systems/Weapon/SidearmWeaponBehaviour.cpp +++ b/src/Game/Systems/Weapon/SidearmWeaponBehaviour.cpp @@ -14,6 +14,62 @@ void SidearmWeaponBehaviour::UpdateComponent(EntityWrapper& entity, ComponentWra void SidearmWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt) { + + CheckAmmo(cWeapon, wi); + + // Start reloading automatically if at 0 mag ammo + int& magAmmo = cWeapon["MagazineAmmo"]; + if (m_ConfigAutoReload && magAmmo <= 0) { + OnReload(cWeapon, wi); + } + + // Only start reloading once we're done firing + bool& reloadQueued = cWeapon["ReloadQueued"]; + double& fireCooldown = cWeapon["FireCooldown"]; + bool& isReloading = cWeapon["IsReloading"]; + if (reloadQueued && fireCooldown <= 0) { + reloadQueued = fireCooldown; + isReloading = true; + } + + // Decrement reload timer + double& reloadTimer = cWeapon["ReloadTimer"]; + if (isReloading) { + reloadTimer = glm::max(0.0, reloadTimer - dt); + } + + // Handle reloading + if (isReloading && reloadTimer <= 0.0) { + int& magSize = cWeapon["MagazineSize"]; + + magAmmo = magSize; + isReloading = false; + if (wi.FirstPersonEntity.Valid()) { + wi.FirstPersonEntity.FirstChildByName("ViewModel")["Model"]["Visible"] = true; + } + if (wi.ThirdPersonEntity.Valid()) { + wi.ThirdPersonEntity["Model"]["Visible"] = true; + } + } + double reloadTime = cWeapon["ReloadTime"]; + if (isReloading && reloadTimer <= reloadTime / 2) { + + } + + // Update first person run animation + ComponentWrapper cPlayer = wi.Player["Player"]; + ComponentWrapper cPhysics = wi.Player["Physics"]; + const float& movementSpeed = cPlayer["MovementSpeed"]; + float speed = glm::length((const glm::vec3&)cPhysics["Velocity"]); + float animationWeight = glm::min(speed, movementSpeed) / movementSpeed; + EntityWrapper rootNode = wi.FirstPersonEntity; + if (rootNode.Valid()) { + EntityWrapper blend = rootNode.FirstChildByName("MovementBlend"); + if (blend.Valid()) { + (double&)blend["Blend"]["Weight"] = animationWeight; + } + } + if ((bool)cWeapon["Automatic"] && canFire(cWeapon)) { fireBullet(cWeapon, wi); } @@ -32,6 +88,67 @@ void SidearmWeaponBehaviour::OnCeasePrimaryFire(ComponentWrapper cWeapon, Weapon cWeapon["TriggerHeld"] = false; } + +void SidearmWeaponBehaviour::OnReload(ComponentWrapper cWeapon, WeaponInfo& wi) +{ + bool& reloadQueued = cWeapon["ReloadQueued"]; + bool& isReloading = cWeapon["IsReloading"]; + if (reloadQueued || isReloading) { + return; + } + + int& magAmmo = cWeapon["MagazineAmmo"]; + int& magSize = cWeapon["MagazineSize"]; + if (magAmmo >= magSize) { + return; + } + + double reloadTime = cWeapon["ReloadTime"]; + double& reloadTimer = cWeapon["ReloadTimer"]; + + // Start reload + reloadQueued = true; + reloadTimer = reloadTime; + + // Play animation + playAnimationAndReturn(wi.FirstPersonEntity, "ActionBlend", "Reload"); + // Third person anim + Events::AutoAnimationBlend eReloadBlend; + eReloadBlend.RootNode = wi.ThirdPersonPlayerModel; + eReloadBlend.NodeName = "Reload"; + eReloadBlend.Restart = true; + eReloadBlend.Start = true; + m_EventBroker->Publish(eReloadBlend); + + // Spawn explosion effect + if (wi.FirstPersonEntity.Valid()) { + if (IsClient) { + EntityWrapper reloadEffectSpawner = wi.FirstPersonEntity.FirstChildByName("ReloadSpawner"); + if (reloadEffectSpawner.Valid()) { + reloadEffectSpawner.DeleteChildren(); + SpawnerSystem::Spawn(reloadEffectSpawner, reloadEffectSpawner); + } + } + wi.FirstPersonEntity.FirstChildByName("ViewModel")["Model"]["Visible"] = false; + } + if (wi.ThirdPersonEntity.Valid()) { + if (IsServer) { + EntityWrapper reloadEffectSpawner = wi.ThirdPersonEntity.FirstChildByName("ReloadSpawner"); + if (reloadEffectSpawner.Valid()) { + reloadEffectSpawner.DeleteChildren(); + SpawnerSystem::Spawn(reloadEffectSpawner, reloadEffectSpawner); + } + } + wi.ThirdPersonEntity["Model"]["Visible"] = false; + } + + // Sound + Events::PlaySoundOnEntity e; + e.EmitterID = wi.Player.ID; + e.FilePath = "Audio/weapon/Assault/AssaultWeaponReload.wav"; + m_EventBroker->Publish(e); +} + void SidearmWeaponBehaviour::OnEquip(ComponentWrapper cWeapon, WeaponInfo& wi) { cWeapon["FireCooldown"] = (double)cWeapon["EquipTime"]; @@ -59,6 +176,14 @@ void SidearmWeaponBehaviour::fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi { cWeapon["FireCooldown"] = 60.0 / (double)cWeapon["RPM"]; + // Ammo + int& magAmmo = cWeapon["MagazineAmmo"]; + if (magAmmo <= 0) { + return; + } else { + magAmmo -= 1; + } + // Get weapon model based on current person EntityWrapper weaponModelEntity = getRelevantWeaponEntity(wi); if (!weaponModelEntity.Valid()) { @@ -73,7 +198,20 @@ void SidearmWeaponBehaviour::fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi float distance = traceRayDistance(origin, direction); EntityWrapper ray = SpawnerSystem::Spawn(tracerSpawner); if (ray.Valid()) { - ((glm::vec3&)ray["Transform"]["Scale"]).z = (distance / 100.f); + ((glm::vec3&)ray["Transform"]["Scale"]).z = distance; + } + } + + // Deal damage + if (dealDamage(cWeapon, wi)) { + // Show hit marker + EntityWrapper hitMarkerSpawner = wi.Player.FirstChildByName("HitMarkerSpawner"); + if (hitMarkerSpawner.Valid()) { + SpawnerSystem::Spawn(hitMarkerSpawner, hitMarkerSpawner); + Events::PlaySoundOnEntity e; + e.EmitterID = wi.Player.ID; + e.FilePath = "Audio/weapon/hitclick.wav"; + m_EventBroker->Publish(e); } } @@ -95,7 +233,184 @@ void SidearmWeaponBehaviour::fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi bool SidearmWeaponBehaviour::canFire(ComponentWrapper cWeapon) { bool triggerHeld = cWeapon["TriggerHeld"]; - double& cooldown = cWeapon["FireCooldown"]; - // TODO: Ammo checks - return triggerHeld && cooldown <= 0.0; -} \ No newline at end of file + bool cooldownPassed = (double)cWeapon["FireCooldown"] <= 0.0; + bool isNotReloading = !(bool)cWeapon["IsReloading"]; + return triggerHeld && cooldownPassed && isNotReloading; +} + +bool SidearmWeaponBehaviour::dealDamage(ComponentWrapper cWeapon, WeaponInfo& wi) +{ + // Only deal damage client side + if (!IsClient) { + return false; + } + + // Only handle damage for the local player + if (wi.Player != LocalPlayer) { + return false; + } + + // Make sure the player isn't shooting from the grave + if (!wi.Player.Valid()) { + return false; + } + + // 3D-pick middle of screen + Rectangle viewport = m_Renderer->GetViewportSize(); + glm::vec2 centerScreen(viewport.Width / 2, viewport.Height / 2); + // TODO: Some horizontal spread + PickData pickData = m_Renderer->Pick(centerScreen); + EntityWrapper victim(m_World, pickData.Entity); + if (!victim.Valid()) { + return false; + } + + // Don't let us somehow shoot ourselves in the foot + if (victim == LocalPlayer) { + return false; + } + + // Only care about players being hit + if (!victim.HasComponent("Player")) { + victim = victim.FirstParentWithComponent("Player"); + } + if (!victim.Valid()) { + return false; + } + + double damage = cWeapon["BaseDamage"]; + // If friendly fire, reduce damage to 0 (needed to make Boosts, Ammosharing work) + if ((ComponentInfo::EnumType)victim["Team"]["Team"] == (ComponentInfo::EnumType)wi.Player["Team"]["Team"]) { + damage = 0; + giveAmmo(cWeapon, wi, victim); + } + + // Deal damage! + Events::PlayerDamage ePlayerDamage; + ePlayerDamage.Inflictor = wi.Player; + ePlayerDamage.Victim = victim; + ePlayerDamage.Damage = damage; + m_EventBroker->Publish(ePlayerDamage); + + return damage > 0; +} + +void SidearmWeaponBehaviour::giveAmmo(ComponentWrapper cWeapon, WeaponInfo& wi, EntityWrapper receiver) +{ + if (receiver.HasComponent("AssaultWeapon")) { + int magazineSize = receiver["AssaultWeapon"]["MagazineSize"]; + int& magazineAmmo = receiver["AssaultWeapon"]["MagazineAmmo"]; + + int maxAmmo = receiver["AssaultWeapon"]["MaxAmmo"]; + int& ammo = receiver["AssaultWeapon"]["Ammo"]; + + if(magazineAmmo < magazineSize) { + magazineAmmo += 1; + } else if (ammo < maxAmmo) { + ammo += 1; + } + } else if (receiver.HasComponent("DefenderWeapon")) { + int magazineSize = receiver["DefenderWeapon"]["MagazineSize"]; + int& magazineAmmo = receiver["DefenderWeapon"]["MagazineAmmo"]; + + int maxAmmo = receiver["DefenderWeapon"]["MaxAmmo"]; + int& ammo = receiver["DefenderWeapon"]["Ammo"]; + + if (magazineAmmo < magazineSize) { + magazineAmmo += 1; + } else if (ammo < maxAmmo) { + ammo += 1; + } + } +} + +void SidearmWeaponBehaviour::CheckAmmo(ComponentWrapper cWeapon, WeaponInfo& wi) +{ + // Only check ammo client side + if (!IsClient) { + return; + } + + // Only handle ammo check for the local player + if (wi.Player != LocalPlayer) { + return; + } + + // Make sure the player isn't checking from the grave + if (!wi.Player.Valid()) { + return; + } + + // 3D-pick middle of screen + Rectangle viewport = m_Renderer->GetViewportSize(); + glm::vec2 centerScreen(viewport.Width / 2, viewport.Height / 2); + // TODO: Some horizontal spread + PickData pickData = m_Renderer->Pick(centerScreen); + EntityWrapper victim(m_World, pickData.Entity); + if (!victim.Valid()) { + RemoveFrindlyAmmoHUD(wi); + return; + } + + // Don't let us somehow shoot ourselves in the foot + if (victim == LocalPlayer) { + RemoveFrindlyAmmoHUD(wi); + return; + } + + // Only care about players being hit + if (!victim.HasComponent("Player")) { + victim = victim.FirstParentWithComponent("Player"); + } + if (!victim.Valid()) { + RemoveFrindlyAmmoHUD(wi); + return; + } + + + // If friendly fire, reduce damage to 0 (needed to make Boosts, Ammosharing work) + if ((ComponentInfo::EnumType)victim["Team"]["Team"] == (ComponentInfo::EnumType)wi.Player["Team"]["Team"]) { + int magazineAmmo = 0; + if (victim.HasComponent("AssaultWeapon")) { + magazineAmmo = (int)victim["AssaultWeapon"]["MagazineAmmo"]; + + } else if (victim.HasComponent("DefenderWeapon")) { + magazineAmmo = (int)victim["DefenderWeapon"]["MagazineAmmo"]; + } + + + EntityWrapper friendlyAmmoHudSpawner = wi.FirstPersonPlayerModel.FirstChildByName("FriendlyAmmoAttachment"); + if(friendlyAmmoHudSpawner.Valid()) { + + auto children = m_World->GetDirectChildren(friendlyAmmoHudSpawner.ID); + + if (children.first == children.second) { + EntityWrapper friendlyAmmoHud = SpawnerSystem::Spawn(friendlyAmmoHudSpawner, friendlyAmmoHudSpawner); + if (friendlyAmmoHud.Valid()) { + EntityWrapper textEntity = friendlyAmmoHud.FirstChildByName("MagazineAmmo"); + if (textEntity.Valid()) { + if (textEntity.HasComponent("Text")) { + (std::string&)textEntity["Text"]["Content"] = std::to_string(magazineAmmo); + } + } + } + } else { + EntityWrapper textEntity = friendlyAmmoHudSpawner.FirstChildByName("MagazineAmmo"); + if (textEntity.Valid()) { + if (textEntity.HasComponent("Text")) { + (std::string&)textEntity["Text"]["Content"] = std::to_string(magazineAmmo); + } + } + } + + } + } +} + +void SidearmWeaponBehaviour::RemoveFrindlyAmmoHUD(WeaponInfo& wi) +{ + EntityWrapper friendlyAmmoHudSpawner = wi.FirstPersonPlayerModel.FirstChildByName("FriendlyAmmoAttachment"); + if (friendlyAmmoHudSpawner.Valid()) { + friendlyAmmoHudSpawner.DeleteChildren(); + } +}