Merge remote-tracking branch 'origin/Weapons' into Movement
# Conflicts: # resources/Schema/Entities/PlayerDefenderBlue.xml
This commit is contained in:
+3
-2
@@ -34,6 +34,7 @@
|
||||
#include "Game/Systems/KillFeedSystem.h"
|
||||
#include "Game/Systems/BoostSystem.h"
|
||||
#include "Game/Systems/BoostIconsHUDSystem.h"
|
||||
#include "Game/Systems/ScoreScreenSystem.h"
|
||||
#include "GUI/ButtonSystem.h"
|
||||
#include "GUI/MainMenuSystem.h"
|
||||
|
||||
@@ -143,7 +144,6 @@ Game::Game(int argc, char* argv[])
|
||||
m_SystemPipeline->AddSystem<AbilityCooldownHUDSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<CapturePointArrowHUDSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<KillFeedSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<LifetimeSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<CapturePointSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<CapturePointHUDSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<PickupSpawnSystem>(updateOrderLevel);
|
||||
@@ -155,6 +155,7 @@ Game::Game(int argc, char* argv[])
|
||||
m_SystemPipeline->AddSystem<ButtonSystem>(updateOrderLevel, m_Renderer);
|
||||
m_SystemPipeline->AddSystem<MainMenuSystem>(updateOrderLevel, m_Renderer);
|
||||
m_SystemPipeline->AddSystem<BoostIconsHUDSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<ScoreScreenSystem>(updateOrderLevel);
|
||||
// Populate Octree with collidables
|
||||
++updateOrderLevel;
|
||||
m_SystemPipeline->AddSystem<FillOctreeSystem>(updateOrderLevel, m_OctreeCollision, "Collidable");
|
||||
@@ -217,7 +218,7 @@ void Game::Tick()
|
||||
PerformanceTimer::StartTimerAndStopPrevious("InputProxy");
|
||||
m_InputProxy->Update(dt);
|
||||
m_EventBroker->Swap();
|
||||
m_InputProxy->Process();
|
||||
m_InputProxy->Process(ImGui::GetIO().WantCaptureKeyboard || ImGui::GetIO().WantCaptureMouse);
|
||||
m_EventBroker->Swap();
|
||||
|
||||
PerformanceTimer::StartTimerAndStopPrevious("SoundManager");
|
||||
|
||||
@@ -15,7 +15,9 @@ bool MultiplayerSnapshotFilter::FilterComponent(EntityWrapper entity, SharedComp
|
||||
|| component.Info.Name == "AssaultWeapon"
|
||||
|| component.Info.Name == "DefenderWeapon"
|
||||
|| component.Info.Name == "Animation"
|
||||
|| component.Info.Name == "AnimationOffset"
|
||||
|| component.Info.Name == "Blend"
|
||||
|| component.Info.Name == "BlendAdditive"
|
||||
|| component.Info.Name == "BlendOverride"
|
||||
|| entity.Name() == "PlayerName"
|
||||
) {
|
||||
return false;
|
||||
|
||||
@@ -14,17 +14,20 @@ void AbilityCooldownHUDSystem::Update(double dt)
|
||||
if (!abilityEntity.Valid())
|
||||
return;
|
||||
EntityWrapper cooldownTextEntity = entity.FirstChildByName("Cooldown");
|
||||
|
||||
double maxAbilityCD = (double)abilityEntity["DashAbility"]["CoolDownMaxTimer"];
|
||||
double currentAbilityCD = (double)abilityEntity["DashAbility"]["CoolDownTimer"];
|
||||
|
||||
currentAbilityCD = currentAbilityCD >= 0.0 ? currentAbilityCD : 0.0;
|
||||
|
||||
if(cooldownTextEntity.Valid()) {
|
||||
if(cooldownTextEntity.HasComponent("Text"))
|
||||
{
|
||||
double maxAbilityCD = (double)abilityEntity["DashAbility"]["CoolDownMaxTimer"];
|
||||
double currentAbilityCD = (double)abilityEntity["DashAbility"]["CoolDownTimer"];
|
||||
currentAbilityCD = currentAbilityCD >= 0.0 ? currentAbilityCD : 0.0;
|
||||
std::string t = (std::string&)cooldownTextEntity["Text"]["Content"] = std::to_string(currentAbilityCD).substr(0, 3);
|
||||
if(entity.HasComponent("Fill")) {
|
||||
entity["Fill"]["Percentage"] = currentAbilityCD/maxAbilityCD; //TODO: current time needs to be in the component.
|
||||
}
|
||||
}
|
||||
}
|
||||
if (entity.HasComponent("Fill")) {
|
||||
entity["Fill"]["Percentage"] = currentAbilityCD/maxAbilityCD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,16 @@ bool BoostSystem::OnPlayerDamage(Events::PlayerDamage& e)
|
||||
if (e.Victim.ID == e.Inflictor.ID) {
|
||||
return false;
|
||||
}
|
||||
if (!e.Victim.Valid() && e.Victim != LocalPlayer && !e.Victim.IsChildOf(LocalPlayer)) {
|
||||
|
||||
if (!e.Victim.Valid() || !LocalPlayer.Valid()) {
|
||||
return false;
|
||||
}
|
||||
if (!e.Inflictor.Valid() || !e.Victim.Valid()) {
|
||||
|
||||
if (e.Victim != LocalPlayer && !e.Victim.IsChildOf(LocalPlayer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!e.Inflictor.Valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ CapturePointHUDSystem::CapturePointHUDSystem(SystemParams params)
|
||||
|
||||
void CapturePointHUDSystem::Update(double dt)
|
||||
{
|
||||
bool LoadCheck = true;
|
||||
bool loadCheck = true;
|
||||
int redTeam;
|
||||
int blueTeam;
|
||||
int spectatorTeam;
|
||||
@@ -35,11 +35,11 @@ void CapturePointHUDSystem::Update(double dt)
|
||||
//Check if the HUD corresponds to the Capture Point Number
|
||||
if (HUD_ID == (int)entityCP["CapturePoint"]["CapturePointNumber"]) {
|
||||
ComponentWrapper& teamComponent = entityCP["Team"];
|
||||
if (LoadCheck) {
|
||||
if (loadCheck) {
|
||||
redTeam = (int)teamComponent["Team"].Enum("Red");
|
||||
blueTeam = (int)teamComponent["Team"].Enum("Blue");
|
||||
spectatorTeam = (int)teamComponent["Team"].Enum("Spectator");
|
||||
LoadCheck = false;
|
||||
loadCheck = false;
|
||||
}
|
||||
//Color hud with team color
|
||||
auto capturePointTeam = (int)teamComponent["Team"];
|
||||
|
||||
@@ -2,13 +2,17 @@
|
||||
|
||||
void ExplosionEffectSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt)
|
||||
{
|
||||
if ((double)component["TimeSinceDeath"] > (double)component["ExplosionDuration"]) {
|
||||
(double)component["TimeSinceDeath"] = 0.f;
|
||||
double& delay = (double)component["Delay"];
|
||||
if (delay > 0) {
|
||||
delay = std::max(0.0, delay - dt);
|
||||
}
|
||||
(double&)component["TimeSinceDeath"] += dt;
|
||||
|
||||
//if ((bool)Component["Gravity"] == true) {
|
||||
// (bool)Component["ExponentialAccelaration"] = false;
|
||||
//}
|
||||
if (delay <= 0) {
|
||||
double& timeSinceDeath = component["TimeSinceDeath"];
|
||||
timeSinceDeath += (double)component["Speed"] * dt;
|
||||
if (timeSinceDeath < 0 || timeSinceDeath > (double)component["ExplosionDuration"]) {
|
||||
timeSinceDeath = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,15 +12,7 @@ HealthSystem::HealthSystem(SystemParams params)
|
||||
}
|
||||
|
||||
void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cHealth, double dt)
|
||||
{
|
||||
double& health = cHealth["Health"];
|
||||
if (health <= 0.0) {
|
||||
Events::PlayerDeath ePlayerDeath;
|
||||
ePlayerDeath.Player = entity;
|
||||
m_EventBroker->Publish(ePlayerDeath);
|
||||
//Note: we will delete the entity in PlayerDeathSystem
|
||||
}
|
||||
}
|
||||
{ }
|
||||
|
||||
bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e)
|
||||
{
|
||||
@@ -35,7 +27,16 @@ bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e)
|
||||
if (playerBoostDefenderEntity.Valid()) {
|
||||
e.Damage -= (double)playerBoostDefenderEntity["BoostDefender"]["StrengthOfEffect"];
|
||||
}
|
||||
health -= e.Damage;
|
||||
if (health > 0) {
|
||||
health -= e.Damage;
|
||||
if (health <= 0.0) {
|
||||
Events::PlayerDeath ePlayerDeath;
|
||||
ePlayerDeath.Player = e.Victim;
|
||||
ePlayerDeath.Killer = e.Inflictor;
|
||||
m_EventBroker->Publish(ePlayerDeath);
|
||||
//Note: we will delete the entity in PlayerDeathSystem
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
PlayerMovementSystem::PlayerMovementSystem(SystemParams params)
|
||||
: System(params)
|
||||
, m_SprintEffectTimer(0.f)
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &PlayerMovementSystem::OnPlayerSpawned);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &PlayerMovementSystem::OnDoubleJump);
|
||||
@@ -19,8 +20,48 @@ void PlayerMovementSystem::Update(double dt)
|
||||
{
|
||||
updateMovementControllers(dt);
|
||||
// Only do physics calculations on client and only for themselves.
|
||||
if (IsClient && LocalPlayer.Valid()) {
|
||||
updateVelocity(LocalPlayer, dt);
|
||||
if (IsClient) {
|
||||
if (LocalPlayer.Valid()){
|
||||
updateVelocity(LocalPlayer, dt);
|
||||
}
|
||||
m_SprintEffectTimer += dt;
|
||||
if (m_SprintEffectTimer < 0.016f) {
|
||||
return;
|
||||
}
|
||||
m_SprintEffectTimer = 0.f;
|
||||
const ComponentPool* pool = m_World->GetComponents("SprintAbility");
|
||||
if (pool == nullptr) {
|
||||
return;
|
||||
}
|
||||
for (auto cSprint : *pool) {
|
||||
if (cSprint.EntityID != LocalPlayer.ID && (bool)cSprint["Active"]) {
|
||||
// Spawn one afterimage for each player that sprints.
|
||||
EntityWrapper player(m_World, cSprint.EntityID);
|
||||
auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/SprintEffect.xml");
|
||||
EntityWrapper sprintEffect = entityFile->MergeInto(m_World);
|
||||
auto playerModel = player.FirstChildByName("PlayerModel");
|
||||
if (!playerModel.Valid()) {
|
||||
continue;
|
||||
}
|
||||
if (!playerModel.HasComponent("Model")) {
|
||||
continue;
|
||||
}
|
||||
if (!playerModel.HasComponent("Animation")) {
|
||||
continue;
|
||||
}
|
||||
auto playerEntityModel = playerModel["Model"];
|
||||
auto playerEntityAnimation = playerModel["Animation"];
|
||||
playerEntityModel.Copy(sprintEffect["Model"]);
|
||||
playerEntityAnimation.Copy(sprintEffect["Animation"]);
|
||||
sprintEffect["ExplosionEffect"]["EndColor"] = (glm::vec4)playerEntityModel["Color"];
|
||||
((glm::vec4&)sprintEffect["ExplosionEffect"]["EndColor"]).w = 0.f;
|
||||
sprintEffect["Animation"]["Speed1"] = 0.0;
|
||||
sprintEffect["Animation"]["Speed2"] = 0.0;
|
||||
sprintEffect["Animation"]["Speed3"] = 0.0;
|
||||
sprintEffect["Transform"]["Position"] = (glm::vec3)player["Transform"]["Position"];
|
||||
sprintEffect["Transform"]["Orientation"] = (glm::vec3)player["Transform"]["Orientation"];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +119,7 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
|
||||
}
|
||||
bool sniperSprinting = false;
|
||||
if (player.HasComponent("SprintAbility")) {
|
||||
(bool)player["SprintAbility"]["Active"] = controller->SpecialAbilityKeyDown();
|
||||
if (controller->SpecialAbilityKeyDown()) {
|
||||
playerMovementSpeed *= (double)player["SprintAbility"]["StrengthOfEffect"];
|
||||
playerCrouchSpeed *= (double)player["SprintAbility"]["StrengthOfEffect"];
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
#include "Game/Systems/ScoreScreenSystem.h"
|
||||
|
||||
|
||||
ScoreScreenSystem::ScoreScreenSystem(SystemParams params)
|
||||
: System(params)
|
||||
, PureSystem("ScoreScreen")
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDeath, &ScoreScreenSystem::OnPlayerDeath);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &ScoreScreenSystem::OnPlayerSpawn);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerConnected, &ScoreScreenSystem::OnPlayerConnected);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDisconnected, &ScoreScreenSystem::OnPlayerDisconnected);
|
||||
}
|
||||
|
||||
void ScoreScreenSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& scoreScreen, double dt)
|
||||
{
|
||||
if (!IsServer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!entity.HasComponent("ScoreScreen")){
|
||||
return;
|
||||
}
|
||||
|
||||
int currentTeam = 0;
|
||||
|
||||
if(entity.HasComponent("Team")) {
|
||||
currentTeam = (int)entity["Team"]["Team"];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
auto children = entity.ChildrenWithComponent("ScoreIdentity");
|
||||
|
||||
float position = 0.f;
|
||||
|
||||
for (auto it = m_PlayerIdentities.begin(); it != m_PlayerIdentities.end(); ++it) {
|
||||
bool found = false;
|
||||
for (auto& child : children) {
|
||||
int ID = (int)child["ScoreIdentity"]["ID"];
|
||||
if (it->first == ID) {
|
||||
if (it->second.Team != currentTeam) {
|
||||
m_World->DeleteEntity(child.ID);
|
||||
(int&)entity["ScoreScreen"]["TotalIdentities"] -= 1;
|
||||
break;
|
||||
}
|
||||
for (auto it2 = m_DisconnectedIdentities.begin(); it2 != m_DisconnectedIdentities.end(); ++it2) {
|
||||
if (ID == *it2) {
|
||||
m_World->DeleteEntity(child.ID);
|
||||
(int&)entity["ScoreScreen"]["TotalIdentities"] -= 1;
|
||||
it2 = m_DisconnectedIdentities.erase(it2);
|
||||
it = m_PlayerIdentities.erase(it);
|
||||
|
||||
//Remove from m_playerIdentities
|
||||
break;
|
||||
}
|
||||
}
|
||||
found = true;
|
||||
if(!child.Valid()) {
|
||||
break;
|
||||
}
|
||||
//Update Deaths for child
|
||||
(int&)child["ScoreIdentity"]["Kills"] = it->second.Kills;
|
||||
//Update Kills for child
|
||||
(int&)child["ScoreIdentity"]["Deaths"] = it->second.Deaths;
|
||||
//KD is not updated at the moment.
|
||||
if (it->second.Deaths != 0) {
|
||||
(double&)child["ScoreIdentity"]["KD"] = it->second.Kills/it->second.Deaths;
|
||||
}
|
||||
|
||||
//Update position for child
|
||||
glm::vec3 offset = (glm::vec3)entity["ScoreScreen"]["Offset"];
|
||||
(glm::vec3&) child["Transform"]["Position"] = offset * position;
|
||||
position += 1.f;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (it == m_PlayerIdentities.end()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(found == false) {
|
||||
if(it->second.Team != currentTeam) {
|
||||
//This player is not the same team as this scoreboard should show.
|
||||
continue;
|
||||
}
|
||||
//There is no entry for this player, create one.
|
||||
auto entityFile = ResourceManager::Load<EntityFile>("Schema/Entities/ScoreIdentity.xml");
|
||||
EntityWrapper scoreIdentity = entityFile->MergeInto(m_World);
|
||||
glm::vec3 offset = (glm::vec3)entity["ScoreScreen"]["Offset"];
|
||||
int newPosition = (int)entity["ScoreScreen"]["TotalIdentities"];
|
||||
(glm::vec3&) scoreIdentity["Transform"]["Position"] = offset * (float)newPosition;
|
||||
auto cScoreIdentity = scoreIdentity["ScoreIdentity"];
|
||||
auto data = it->second;
|
||||
|
||||
(std::string&)cScoreIdentity["Name"] = data.Name;
|
||||
(int&)cScoreIdentity["ID"] = data.ID;
|
||||
|
||||
m_World->SetParent(scoreIdentity.ID, entity.ID);
|
||||
|
||||
(int&)entity["ScoreScreen"]["TotalIdentities"] += 1;
|
||||
|
||||
}
|
||||
}
|
||||
//Local player should have an icon, compare with LocalPlayer somthing
|
||||
}
|
||||
|
||||
bool ScoreScreenSystem::OnPlayerDeath(const Events::KillDeath& e)
|
||||
{
|
||||
//When player die, add it to his score, and when possible the player who killed him.
|
||||
std::unordered_map<int, PlayerData>::iterator got;
|
||||
got = m_PlayerIdentities.find(e.Casualty);
|
||||
if(got != m_PlayerIdentities.end()) {
|
||||
got->second.Deaths++;
|
||||
}
|
||||
got = m_PlayerIdentities.find(e.Killer);
|
||||
if (got != m_PlayerIdentities.end()) {
|
||||
got->second.Kills++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ScoreScreenSystem::OnPlayerSpawn(const Events::PlayerSpawned& e)
|
||||
{
|
||||
//When a player spawn, add data to the list entry with the same ID.
|
||||
|
||||
std::unordered_map<int, PlayerData>::iterator got;
|
||||
|
||||
got = m_PlayerIdentities.find(e.PlayerID);
|
||||
if(got == m_PlayerIdentities.end()) {
|
||||
LOG_ERROR("Player spawned without having an entry on score screen");
|
||||
return 0;
|
||||
}
|
||||
auto& data = got->second;
|
||||
data.Player = e.Player;
|
||||
data.Team = (int)data.Player["Team"]["Team"];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ScoreScreenSystem::OnPlayerConnected(const Events::PlayerConnected& e)
|
||||
{
|
||||
//player has connected, add his data to the list of ScoreIdentities
|
||||
PlayerData data;
|
||||
data.ID = e.PlayerID;
|
||||
data.Name = e.PlayerName;
|
||||
m_PlayerIdentities.insert( {data.ID, data} );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ScoreScreenSystem::OnPlayerDisconnected(const Events::PlayerDisconnected& e)
|
||||
{
|
||||
//player has disconnected, remove him from list of ScoreIdentities
|
||||
m_DisconnectedIdentities.push_back(e.PlayerID);
|
||||
return 0;
|
||||
}
|
||||
@@ -7,17 +7,21 @@ void TextFieldReader::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
|
||||
}
|
||||
|
||||
// Find the entity to read from
|
||||
const std::string& parentEntityName = cAmmunitionHUD["ParentEntityName"];
|
||||
const std::string& entityName = cAmmunitionHUD["ParentEntityName"];
|
||||
const std::string& componentType = cAmmunitionHUD["ComponentType"];
|
||||
EntityWrapper readEntity = entity;
|
||||
if (!parentEntityName.empty()) {
|
||||
readEntity = entity.FirstParentByName(parentEntityName);
|
||||
if (!readEntity.Valid()) {
|
||||
return;
|
||||
if (entityName.empty()) {
|
||||
if (!readEntity.HasComponent(componentType)) {
|
||||
readEntity = readEntity.FirstParentWithComponent(componentType);
|
||||
}
|
||||
} else {
|
||||
readEntity = entity.FirstParentByName(entityName);
|
||||
}
|
||||
if (!readEntity.Valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the component to read from
|
||||
const std::string& componentType = cAmmunitionHUD["ComponentType"];
|
||||
if (componentType.empty() || !readEntity.HasComponent(componentType)) {
|
||||
return;
|
||||
}
|
||||
@@ -35,9 +39,17 @@ void TextFieldReader::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
|
||||
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]);
|
||||
std::ostringstream ss;
|
||||
float f = (float)component[fieldName];
|
||||
ss << std::fixed << std::setprecision(2);
|
||||
ss << f;
|
||||
text = ss.str();
|
||||
} else if (field.Type == "double") {
|
||||
text = boost::lexical_cast<std::string>((const double&)component[fieldName]);
|
||||
std::ostringstream ss;
|
||||
double d = (double)component[fieldName];
|
||||
ss << std::fixed << std::setprecision(1);
|
||||
ss << d;
|
||||
text = ss.str();
|
||||
} else if (field.Type == "bool") {
|
||||
text = boost::lexical_cast<std::string>((const bool&)component[fieldName]);
|
||||
} else if (field.Type == "string") {
|
||||
|
||||
@@ -39,7 +39,17 @@ void AssaultWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo&
|
||||
ammo = glm::max(0, ammo - (magSize - magAmmo));
|
||||
magAmmo = glm::min(magSize, ammo);
|
||||
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) {
|
||||
|
||||
}
|
||||
|
||||
// Restore view angle
|
||||
if (IsClient) {
|
||||
@@ -56,6 +66,20 @@ void AssaultWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo&
|
||||
}
|
||||
}
|
||||
|
||||
// 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.FirstParentWithComponent("Model");
|
||||
if (rootNode.Valid()) {
|
||||
EntityWrapper blend = rootNode.FirstChildByName("MovementBlend");
|
||||
if (blend.Valid()) {
|
||||
(double&)blend["Blend"]["Weight"] = animationWeight;
|
||||
}
|
||||
}
|
||||
|
||||
// Fire if we're able to fire
|
||||
if (canFire(cWeapon, wi)) {
|
||||
fireBullet(cWeapon, wi);
|
||||
@@ -101,26 +125,34 @@ void AssaultWeaponBehaviour::OnReload(ComponentWrapper cWeapon, WeaponInfo& wi)
|
||||
reloadTimer = reloadTime;
|
||||
|
||||
// Play animation
|
||||
EntityWrapper modelEntity = wi.FirstPersonEntity.Parent().Parent();
|
||||
if (modelEntity.Valid()) {
|
||||
EntityWrapper blendTree = modelEntity.FirstChildByName("BlendTreeAssaultWeapon");
|
||||
EntityWrapper reloadBlend = blendTree.FirstChildByName("Reload");
|
||||
|
||||
Events::AutoAnimationBlend eFireBlend;
|
||||
eFireBlend.RootNode = modelEntity;
|
||||
eFireBlend.NodeName = "Reload";
|
||||
eFireBlend.Restart = true;
|
||||
eFireBlend.Start = true;
|
||||
m_EventBroker->Publish(eFireBlend);
|
||||
|
||||
Events::AutoAnimationBlend eIdleBlend;
|
||||
eIdleBlend.RootNode = modelEntity;
|
||||
eIdleBlend.NodeName = "Idle";
|
||||
eIdleBlend.AnimationEntity = reloadBlend;
|
||||
eIdleBlend.Delay = -0.2;
|
||||
eIdleBlend.Duration = 0.2;
|
||||
m_EventBroker->Publish(eIdleBlend);
|
||||
playAnimationAndReturn(wi.FirstPersonEntity, "BlendTreeAssaultWeapon", "Reload");
|
||||
// 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 AssaultWeaponBehaviour::OnEquip(ComponentWrapper cWeapon, WeaponInfo& wi)
|
||||
@@ -170,7 +202,7 @@ void AssaultWeaponBehaviour::fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi
|
||||
}
|
||||
|
||||
// Get weapon model based on current person
|
||||
EntityWrapper weaponModelEntity = getRelevantWeaponModelEntity(wi);
|
||||
EntityWrapper weaponModelEntity = getRelevantWeaponEntity(wi);
|
||||
if (!weaponModelEntity.Valid()) {
|
||||
return;
|
||||
}
|
||||
@@ -201,26 +233,13 @@ void AssaultWeaponBehaviour::fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi
|
||||
}
|
||||
|
||||
// Play animation
|
||||
EntityWrapper modelEntity = wi.FirstPersonEntity.Parent().Parent();
|
||||
if (modelEntity.Valid()) {
|
||||
EntityWrapper blendTree = modelEntity.FirstChildByName("BlendTreeAssaultWeapon");
|
||||
EntityWrapper fireBlend = blendTree.FirstChildByName("Fire");
|
||||
playAnimationAndReturn(wi.FirstPersonEntity, "BlendTreeAssaultWeapon", "Fire");
|
||||
|
||||
Events::AutoAnimationBlend eFireBlend;
|
||||
eFireBlend.RootNode = modelEntity;
|
||||
eFireBlend.NodeName = "Fire";
|
||||
eFireBlend.Restart = true;
|
||||
eFireBlend.Start = true;
|
||||
m_EventBroker->Publish(eFireBlend);
|
||||
|
||||
Events::AutoAnimationBlend eIdleBlend;
|
||||
eIdleBlend.RootNode = modelEntity;
|
||||
eIdleBlend.NodeName = "Idle";
|
||||
eIdleBlend.AnimationEntity = fireBlend;
|
||||
eIdleBlend.Delay = -0.2;
|
||||
eIdleBlend.Duration = 0.2;
|
||||
m_EventBroker->Publish(eIdleBlend);
|
||||
}
|
||||
// Sound
|
||||
Events::PlaySoundOnEntity e;
|
||||
e.EmitterID = wi.Player.ID;
|
||||
e.FilePath = "Audio/weapon/Assault/AssaultWeaponFire.wav";
|
||||
m_EventBroker->Publish(e);
|
||||
}
|
||||
|
||||
bool AssaultWeaponBehaviour::canFire(ComponentWrapper cWeapon, WeaponInfo& wi)
|
||||
|
||||
@@ -36,6 +36,7 @@ void DefenderWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo&
|
||||
m_EventBroker->Publish(e);
|
||||
} else {
|
||||
isReloading = false;
|
||||
playAnimationAndReturn(wi.FirstPersonEntity, "FinalBlend", "ReloadEnd");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +97,23 @@ void DefenderWeaponBehaviour::OnReload(ComponentWrapper cWeapon, WeaponInfo& wi)
|
||||
// Start reload
|
||||
isReloading = true;
|
||||
reloadTimer = reloadTime;
|
||||
|
||||
// Play animation
|
||||
if (wi.FirstPersonEntity.Valid()) {
|
||||
Events::AutoAnimationBlend eBlendStart;
|
||||
eBlendStart.RootNode = wi.FirstPersonEntity;
|
||||
eBlendStart.NodeName = "ReloadStart";
|
||||
eBlendStart.Restart = true;
|
||||
eBlendStart.Start = true;
|
||||
m_EventBroker->Publish(eBlendStart);
|
||||
Events::AutoAnimationBlend eBlendLoop;
|
||||
eBlendLoop.RootNode = wi.FirstPersonEntity;
|
||||
eBlendLoop.NodeName = "ReloadLoop";
|
||||
eBlendLoop.Restart = true;
|
||||
eBlendLoop.Start = true;
|
||||
eBlendLoop.AnimationEntity = wi.FirstPersonEntity.FirstChildByName("ReloadStart");
|
||||
m_EventBroker->Publish(eBlendLoop);
|
||||
}
|
||||
}
|
||||
|
||||
void DefenderWeaponBehaviour::OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi)
|
||||
@@ -110,13 +128,51 @@ void DefenderWeaponBehaviour::OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi
|
||||
|
||||
bool DefenderWeaponBehaviour::OnInputCommand(ComponentWrapper cWeapon, WeaponInfo& wi, const Events::InputCommand& e)
|
||||
{
|
||||
if (e.Command == "SpecialAbility" && IsServer) {
|
||||
if (e.Command == "SpecialAbility") {
|
||||
EntityWrapper attachment = wi.Player.FirstChildByName("ShieldAttachment");
|
||||
if (attachment.Valid()) {
|
||||
if (e.Value > 0) {
|
||||
SpawnerSystem::Spawn(attachment, attachment);
|
||||
if (IsServer) {
|
||||
SpawnerSystem::Spawn(attachment, attachment);
|
||||
}
|
||||
|
||||
if (IsClient) {
|
||||
EntityWrapper root = wi.FirstPersonEntity;
|
||||
if (root.Valid()) {
|
||||
EntityWrapper subTree = root.FirstChildByName("FinalBlend");
|
||||
if (subTree.Valid()) {
|
||||
EntityWrapper animationNode = subTree.FirstChildByName("Shield");
|
||||
if (animationNode.Valid()) {
|
||||
Events::AutoAnimationBlend eFireBlend;
|
||||
eFireBlend.RootNode = root;
|
||||
eFireBlend.NodeName = "Shield";
|
||||
eFireBlend.Restart = true;
|
||||
eFireBlend.Start = true;
|
||||
m_EventBroker->Publish(eFireBlend);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
attachment.DeleteChildren();
|
||||
|
||||
if (IsClient) {
|
||||
EntityWrapper root = wi.FirstPersonEntity;
|
||||
if (root.Valid()) {
|
||||
EntityWrapper subTree = root.FirstChildByName("FinalBlend");
|
||||
if (subTree.Valid()) {
|
||||
EntityWrapper animationNode = subTree.FirstChildByName("ActionBlend");
|
||||
if (animationNode.Valid()) {
|
||||
Events::AutoAnimationBlend eFireBlend;
|
||||
eFireBlend.RootNode = root;
|
||||
eFireBlend.NodeName = "ActionBlend";
|
||||
eFireBlend.Restart = true;
|
||||
eFireBlend.Start = true;
|
||||
m_EventBroker->Publish(eFireBlend);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,6 +251,9 @@ void DefenderWeaponBehaviour::fireShell(ComponentWrapper cWeapon, WeaponInfo& wi
|
||||
}
|
||||
}
|
||||
|
||||
// Play animation
|
||||
playAnimationAndReturn(wi.FirstPersonEntity, "FinalBlend", "Fire");
|
||||
|
||||
// Sound
|
||||
Events::PlaySoundOnEntity e;
|
||||
e.EmitterID = wi.Player.ID;
|
||||
|
||||
@@ -52,7 +52,7 @@ 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);
|
||||
EntityWrapper weaponModelEntity = getRelevantWeaponEntity(wi);
|
||||
if (!weaponModelEntity.Valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user