Merge remote-tracking branch 'origin/master' into Sound

# Conflicts:
#	src/Game/Systems/PlayerSpawnSystem.cpp
#	src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp
This commit is contained in:
stiffly
2016-02-12 08:19:29 +01:00
74 changed files with 4338 additions and 527 deletions
+7 -2
View File
@@ -18,12 +18,15 @@
#include "Game/Systems/DamageIndicatorSystem.h"
#include "Game/Systems/Weapon/WeaponSystem.h"
#include "Rendering/AnimationSystem.h"
#include "Game/Systems/PlayerHUDSystem.h"
#include "Game/Systems/HealthHUDSystem.h"
#include "Rendering/BoneAttachmentSystem.h"
#include "Game/Systems/LifetimeSystem.h"
#include "../Engine/Core/UniformScaleSystem.h"
#include "Rendering/AnimationSystem.h"
#include "Network/MultiplayerSnapshotFilter.h"
#include "Game/Systems/AmmunitionHUDSystem.h"
#include "Game/Systems/KillFeedSystem.h"
Game::Game(int argc, char* argv[])
{
@@ -127,6 +130,8 @@ Game::Game(int argc, char* argv[])
m_SystemPipeline->AddSystem<PickupSpawnSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<AmmoPickupSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<DamageIndicatorSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<AmmunitionHUDSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<KillFeedSystem>(updateOrderLevel);
// Populate Octree with collidables
++updateOrderLevel;
m_SystemPipeline->AddSystem<FillOctreeSystem>(updateOrderLevel, m_OctreeCollision, "Collidable");
@@ -134,8 +139,8 @@ Game::Game(int argc, char* argv[])
m_SystemPipeline->AddSystem<FillFrustumOctreeSystem>(updateOrderLevel, m_OctreeFrustrumCulling);
m_SystemPipeline->AddSystem<AnimationSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<UniformScaleSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<HealthHUDSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<PlayerDeathSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<PlayerHUDSystem>(updateOrderLevel);
// Collision and TriggerSystem should update after player.
++updateOrderLevel;
m_SystemPipeline->AddSystem<BoneAttachmentSystem>(updateOrderLevel);
+110
View File
@@ -0,0 +1,110 @@
/*
Author: Vladimir Sedach.
Purpose: demo of Call Stack creation by our own means,
and with MiniDumpWriteDump() function of DbgHelp.dll.
*/
#include <iostream>
#include <ctime>
#include <windows.h>
#include <tlhelp32.h>
//#include "dbghelp.h"
//#define DEBUG_DPRINTF 1 //allow d()
//#include "wfun.h"
#pragma optimize("y", off) //generate stack frame pointers for all functions - same as /Oy- in the project
#pragma warning(disable: 4200) //nonstandard extension used : zero-sized array in struct/union
#pragma warning(disable: 4100) //unreferenced formal parameter
// In case you don't have dbghelp.h.
#ifndef _DBGHELP_
typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
DWORD ThreadId;
PEXCEPTION_POINTERS ExceptionPointers;
BOOL ClientPointers;
} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;
typedef enum _MINIDUMP_TYPE {
MiniDumpNormal = 0x00000000,
MiniDumpWithDataSegs = 0x00000001,
} MINIDUMP_TYPE;
typedef BOOL (WINAPI * MINIDUMP_WRITE_DUMP)(
IN HANDLE hProcess,
IN DWORD ProcessId,
IN HANDLE hFile,
IN MINIDUMP_TYPE DumpType,
IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
IN PVOID UserStreamParam, OPTIONAL
IN PVOID CallbackParam OPTIONAL
);
#else
typedef BOOL (WINAPI * MINIDUMP_WRITE_DUMP)(
IN HANDLE hProcess,
IN DWORD ProcessId,
IN HANDLE hFile,
IN MINIDUMP_TYPE DumpType,
IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
IN PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
IN PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
);
#endif //#ifndef _DBGHELP_
HMODULE hDbgHelp;
MINIDUMP_WRITE_DUMP MiniDumpWriteDump_;
// Tool Help functions.
typedef HANDLE (WINAPI * CREATE_TOOL_HELP32_SNAPSHOT)(DWORD dwFlags, DWORD th32ProcessID);
//*************************************************************************************
void WINAPI Create_Dump(PEXCEPTION_POINTERS pException, BOOL File_Flag, BOOL Show_Flag)
//*************************************************************************************
// Create dump.
// pException can be either GetExceptionInformation() or NULL.
// If File_Flag = TRUE - write dump files (.dmz and .dmp) with the name of the current process.
// If Show_Flag = TRUE - show message with Get_Exception_Info() dump.
{
// Try to get MiniDumpWriteDump() address.
hDbgHelp = LoadLibrary("DBGHELP.DLL");
MiniDumpWriteDump_ = (MINIDUMP_WRITE_DUMP)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
// If MiniDumpWriteDump() of DbgHelp.dll available.
if (MiniDumpWriteDump_)
{
HANDLE hDump_File;
CHAR Dump_Path[MAX_PATH];
GetModuleFileName(NULL, Dump_Path, sizeof(Dump_Path)); //path of current process
std::time_t t = std::time(NULL);
char tStr[16];
std::strftime(tStr, 32, " %a %H-%M-%S", std::localtime(&t));
std::string time(tStr);
std::string path(Dump_Path);
path = path.substr(0, path.length() - 4);
path += time + ".dmp";
MINIDUMP_EXCEPTION_INFORMATION M;
M.ThreadId = GetCurrentThreadId();
M.ExceptionPointers = pException;
M.ClientPointers = 0;
hDump_File = CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
MiniDumpWriteDump_(GetCurrentProcess(), GetCurrentProcessId(), hDump_File,
MiniDumpNormal, (pException) ? &M : NULL, NULL, NULL);
CloseHandle(hDump_File);
std::cout << "Memory dumped to: \"" << path.c_str() << "\"";
MessageBox(NULL, ("Application crashed, memory dumped to: " + path).c_str(), "MiniDump", MB_ICONHAND | MB_OK);
} else {
MessageBox(NULL, "Application crashed, memory dump failed.", "MiniDump", MB_ICONHAND | MB_OK);
}
}
@@ -9,7 +9,15 @@ MultiplayerSnapshotFilter::MultiplayerSnapshotFilter(EventBroker* eventBroker)
bool MultiplayerSnapshotFilter::FilterComponent(EntityWrapper entity, SharedComponentWrapper& component)
{
if (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) {
return false;
if (
component.Info.Name == "Transform"
|| component.Info.Name == "Physics"
|| component.Info.Name == "AssaultWeapon"
|| component.Info.Name == "Animation"
|| component.Info.Name == "AnimationOffset"
) {
return false;
}
}
if (component.Info.Name == "Physics") {
+36
View File
@@ -0,0 +1,36 @@
#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"]);
}
}
}
}
@@ -20,6 +20,10 @@ void CapturePointHUDSystem::Update(double dt)
return;
}
if(!CapturePointHUDElements) {
return;
}
for (auto& cCapturePointHUD : *CapturePointHUDElements) {
int HUD_ID = cCapturePointHUD["CapturePointNumber"];
EntityWrapper entityHUD = EntityWrapper(m_World, cCapturePointHUD.EntityID);
+9 -3
View File
@@ -6,15 +6,21 @@ CapturePointSystem::CapturePointSystem(SystemParams params)
, PureSystem("CapturePoint")
{
//subscribe/listenTo playerdamage,healthpickup events (using the eventBroker)
EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &CapturePointSystem::OnTriggerTouch);
EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &CapturePointSystem::OnTriggerLeave);
EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &CapturePointSystem::OnCaptured);
if (IsClient) {
EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &CapturePointSystem::OnTriggerTouch);
EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &CapturePointSystem::OnTriggerLeave);
EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &CapturePointSystem::OnCaptured);
}
}
//here all capturepoints will update their component
//NOTE: needs to run each frame, since we're possibly modifying the captureTimer for the capturePoints by dt
void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, ComponentWrapper& cCapturePoint, double dt)
{
if (!IsClient) {
return;
}
if (m_WinnerWasFound) {
return;
}
+5 -2
View File
@@ -18,12 +18,15 @@ bool DamageIndicatorSystem::OnPlayerDamage(Events::PlayerDamage& e)
return false;
}
if (e.Victim != LocalPlayer) {
//if (e.Victim != LocalPlayer) {
// return false;
//}
if (e.Victim != LocalPlayer && !e.Victim.IsChildOf(LocalPlayer)) {
return false;
}
if (!e.Inflictor.Valid() || !e.Victim.Valid()) {
return false;
return false;
}
//grab players direction
@@ -1,6 +1,6 @@
#include "Game/Systems/PlayerHUDSystem.h"
#include "Game/Systems/HealthHUDSystem.h"
void PlayerHUDSystem::Update(double dt)
void HealthHUDSystem::Update(double dt)
{
auto healthHUDs = m_World->GetComponents("HealthHUD");
if (healthHUDs == nullptr) {
@@ -27,13 +27,13 @@ void PlayerHUDSystem::Update(double dt)
s = s + "/";
s = s + std::to_string((int)(double)entityIDParent["Health"]["MaxHealth"]);
float healthPercentage = (double)entityIDParent["Health"]["Health"]/(double)entityIDParent["Health"]["MaxHealth"];
(glm::vec4&)entity["Text"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, 1.f);
//(glm::vec4&)entity["Text"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, glm::vec4(entity["Text"]["Color"]).a);
entity["Text"]["Content"] = s;
}
if(entity.HasComponent("Fill")) {
float healthPercentage = (double)entityIDParent["Health"]["Health"]/(double)entityIDParent["Health"]["MaxHealth"];
(glm::vec4&)entity["Fill"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, 0.f);
(glm::vec4&)entity["Fill"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, glm::vec4(entity["Fill"]["Color"]).a);
(double&)entity["Fill"]["Percentage"] = healthPercentage;
}
+13 -8
View File
@@ -8,25 +8,30 @@ HealthSystem::HealthSystem(SystemParams params)
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &HealthSystem::OnPlayerDamaged);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerHealthPickup, &HealthSystem::OnPlayerHealthPickup);
EVENT_SUBSCRIBE_MEMBER(m_InputCommand, &HealthSystem::OnInputCommand);
m_NetworkEnabled = ResourceManager::Load<ConfigFile>("Config.ini")->Get("Networking.StartNetwork", false);
}
void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt)
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)
{
if (!IsServer && m_NetworkEnabled) {
return false;
}
ComponentWrapper cHealth = e.Victim["Health"];
double& health = cHealth["Health"];
health -= e.Damage;
if (health <= 0.0) {
Events::PlayerDeath ePlayerDeath;
ePlayerDeath.Player = e.Victim;
m_EventBroker->Publish(ePlayerDeath);
//Note: we will delete the entity in PlayerDeathSystem
}
return true;
}
+80
View File
@@ -0,0 +1,80 @@
#include "Game/Systems/KillFeedSystem.h"
void KillFeedSystem::Update(double dt)
{
auto killFeeds = m_World->GetComponents("KillFeed");
if (killFeeds == nullptr) {
return;
}
for (auto& killFeedComponent : *killFeeds) {
EntityWrapper entity = EntityWrapper(m_World, killFeedComponent.EntityID);
for (int i = 1; i <= 3; i++) {
EntityWrapper child = entity.FirstChildByName("KillFeed" + std::to_string(i));
if (child.HasComponent("Text")) {
(std::string&)child["Text"]["Content"] = "";
}
}
int feedIndex = 1;
for (auto it = m_DeathQueue.begin(); it != m_DeathQueue.end(); ) {
bool remove = false;
EntityWrapper child = entity.FirstChildByName("KillFeed" + std::to_string(feedIndex));
if (child.HasComponent("Text")) {
(std::string&)child["Text"]["Content"] = (*it).Content;
(glm::vec4&)child["Text"]["Color"] = (*it).Color;
(*it).TimeToLive -= dt;
if ((*it).TimeToLive <= 0.f) {
(std::string&)child["Text"]["Content"] = "";
(glm::vec4&)child["Text"]["Color"] = (*it).Color;
remove = true;
}
}
feedIndex++;
if(feedIndex > 3) {
break;
}
if(remove) {
it = m_DeathQueue.erase(it);
} else {
it++;
}
}
}
}
bool KillFeedSystem::OnPlayerDeath(Events::PlayerDeath& e)
{
KillFeedInfo kfInfo;
if (e.Player.HasComponent("Team")) {
int red = e.Player["Team"].Enum("Team", "Red");
int blue = e.Player["Team"].Enum("Team", "Blue");
if ((int)e.Player["Team"]["Team"] == red) {
kfInfo.Content = "Blue Player killed Red Player";
kfInfo.Color = glm::vec4(0.f, 0.2f, 1.f, 0.8f);
m_DeathQueue.push_back(kfInfo);
} else if ((int)e.Player["Team"]["Team"] == blue) {
kfInfo.Content = "Red Player killed blue Player";
kfInfo.Color = glm::vec4(1.f, 0.f, 0.f, 0.8f);
m_DeathQueue.push_back(kfInfo);
}
}
if(m_DeathQueue.size() > 3) {
m_DeathQueue.pop_front();
}
return true;
}
+13 -10
View File
@@ -40,7 +40,8 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
EntityWrapper playerModel = player.FirstChildByName("PlayerModel");
if (playerModel.Valid()) {
ComponentWrapper cAnimationOffset = playerModel["AnimationOffset"];
double time = (cameraOrientation.x + glm::half_pi<float>()) / glm::pi<float>();
float pitch = cameraOrientation.x + 0.2;
double time = (pitch + glm::half_pi<float>()) / glm::pi<float>();
cAnimationOffset["Time"] = time;
}
}
@@ -113,15 +114,17 @@ void PlayerMovementSystem::updateMovementControllers(double dt)
if (isOnGround) {
controller->SetDoubleJumping(false);
} else {
//put a hexagon at the players feet
auto hexagonEffect = ResourceManager::Load<EntityFile>("Schema/Entities/DoubleJumpHexagon.xml");
EntityFileParser parser(hexagonEffect);
EntityID hexagonEffectID = parser.MergeEntities(m_World);
EntityWrapper hexagonEW = EntityWrapper(m_World, hexagonEffectID);
hexagonEW["Transform"]["Position"] = (glm::vec3)player["Transform"]["Position"];
controller->SetDoubleJumping(true);
Events::DoubleJump e;
m_EventBroker->Publish(e);
if (IsClient) {
//put a hexagon at the players feet
auto hexagonEffect = ResourceManager::Load<EntityFile>("Schema/Entities/DoubleJumpHexagon.xml");
EntityFileParser parser(hexagonEffect);
EntityID hexagonEffectID = parser.MergeEntities(m_World);
EntityWrapper hexagonEW = EntityWrapper(m_World, hexagonEffectID);
hexagonEW["Transform"]["Position"] = (glm::vec3)player["Transform"]["Position"];
controller->SetDoubleJumping(true);
Events::DoubleJump e;
m_EventBroker->Publish(e);
}
}
velocity.y = 4.f;
}
+11 -6
View File
@@ -126,11 +126,12 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
m_PlayerIDs[e.Player.ID] = e.PlayerID;
// When a player is actually spawned (since the actual spawning is handled on the server)
// Hack should be moved.
if (!IsClient) {
return false;
}
// Set the camera to the correct entity
EntityWrapper cameraEntity = e.Player.FirstChildByName("Camera");
bool outOfBodyExperience = ResourceManager::Load<ConfigFile>("Config.ini")->Get<bool>("Debug.OutOfBodyExperience", false);
@@ -175,11 +176,15 @@ bool PlayerSpawnSystem::OnPlayerDeath(Events::PlayerDeath& e)
if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Spectator")) {
return false;
}
if (m_PlayerIDs.find(e.Player.ID) == m_PlayerIDs.end()) {
if (m_PlayerIDs.count(e.Player.ID) == 0) {
return false;
}
SpawnRequest req;
req.PlayerID = m_PlayerIDs.at(e.Player.ID);
req.Team = cTeam["Team"];
m_SpawnRequests.push_back(req);
SpawnRequest req;
req.PlayerID = m_PlayerIDs.at(e.Player.ID);
req.Team = cTeam["Team"];
m_SpawnRequests.push_back(req);
return true;
}
+13 -7
View File
@@ -6,13 +6,15 @@ SoundSystem::SoundSystem(SystemParams params)
{
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
m_Announcer = ResourceManager::Load<ConfigFile>("Config.ini")->Get<std::string>("Sound.Announcer", "female");
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundSystem::OnPlayerSpawned);
EVENT_SUBSCRIBE_MEMBER(m_InputCommand, &SoundSystem::OnInputCommand);
EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &SoundSystem::OnDoubleJump);
EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &SoundSystem::OnDashAbility);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &SoundSystem::OnPlayerDamage);
EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundSystem::OnCaptured);
EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &SoundSystem::OnTriggerTouch);
if (IsClient) {
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundSystem::OnPlayerSpawned);
EVENT_SUBSCRIBE_MEMBER(m_InputCommand, &SoundSystem::OnInputCommand);
EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &SoundSystem::OnDoubleJump);
EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &SoundSystem::OnDashAbility);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &SoundSystem::OnPlayerDamage);
EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundSystem::OnCaptured);
EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &SoundSystem::OnTriggerTouch);
}
}
void SoundSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt)
@@ -20,6 +22,10 @@ void SoundSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComp
void SoundSystem::Update(double dt)
{
if (!IsClient) {
return;
}
// Temp for play test.
if (m_DrumsIsPlaying) {
m_DrumsIsPlaying = !drumTimer(dt);
@@ -4,6 +4,7 @@ AssaultWeaponBehaviour::AssaultWeaponBehaviour(SystemParams systemParams, IRende
: WeaponBehaviour(systemParams, renderer, collisionOctree, player)
{
m_FirstPersonModel = m_Player.FirstChildByName("Hands");
m_ThirdPersonModel = m_Player.FirstChildByName("PlayerModel");
EVENT_SUBSCRIBE_MEMBER(m_EAnimationComplete, &AssaultWeaponBehaviour::OnAnimationComplete);
}
@@ -56,9 +57,14 @@ void AssaultWeaponBehaviour::Update(double dt)
if (m_Reloading) {
m_ReloadTimer -= dt;
// Re-enable glow on reload impersonator half-way through the animation
if (m_ReloadTimer <= (double)m_Player["AssaultWeapon"]["ReloadTime"] / 2.0) {
if (m_ReloadImpersonator.Valid()) {
m_ReloadImpersonator["Model"]["GlowMap"] = true;
if (IsClient) {
if (m_ReloadTimer <= (double)m_Player["AssaultWeapon"]["ReloadTime"] / 2.0) {
if (m_FirstPersonReloadImpersonator.Valid()) {
m_FirstPersonReloadImpersonator["Model"]["GlowMap"] = true;
}
if (m_ThirdPersonReloadImpersonator.Valid()) {
m_ThirdPersonReloadImpersonator["Model"]["GlowMap"] = true;
}
}
}
if (m_ReloadTimer <= 0) {
@@ -75,14 +81,18 @@ void AssaultWeaponBehaviour::Update(double dt)
}
if (!m_Firing && !m_Reloading) {
playIdleAnimation();
if (IsClient) {
playIdleAnimation();
}
}
// Disable glow map on weapon if it's out of ammo
// Make real first person weapon model visible again
EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel");
if (firstPersonWeaponModel.Valid()) {
firstPersonWeaponModel["Model"]["GlowMap"] = hasAmmo();
if (IsClient) {
EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel");
if (firstPersonWeaponModel.Valid()) {
firstPersonWeaponModel["Model"]["GlowMap"] = hasAmmo();
}
}
}
@@ -127,16 +137,19 @@ void AssaultWeaponBehaviour::fireRound()
// Fire
magAmmo -= 1;
spawnTracer();
playFireSound();
viewPunch();
playShootAnimation();
bool hit = shoot(cAssaultWeapon["BaseDamage"]);
if (hit) {
showHitMarker();
}
m_TimeSinceLastFire = 0.0;
// Effects
if (IsClient) {
spawnTracer();
playFireSound();
viewPunch();
playShootAnimation();
bool hit = shoot(cAssaultWeapon["BaseDamage"]);
if (hit) {
showHitMarker();
}
}
}
void AssaultWeaponBehaviour::spawnTracer()
@@ -146,7 +159,8 @@ void AssaultWeaponBehaviour::spawnTracer()
}
EntityWrapper spawner;
if (m_Player == LocalPlayer) {
bool outOfBodyExperience = ResourceManager::Load<ConfigFile>("Config.ini")->Get<bool>("Debug.OutOfBodyExperience", false);
if (m_Player == LocalPlayer && !outOfBodyExperience) {
spawner = m_Player.FirstChildByName("WeaponMuzzle");
} else {
spawner = m_Player.FirstChildByName("ThirdPersonWeaponMuzzle");
@@ -225,7 +239,13 @@ void AssaultWeaponBehaviour::finishReload()
// Make real first person weapon model visible again
EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel");
firstPersonWeaponModel["Model"]["Visible"] = true;
if (firstPersonWeaponModel.Valid()) {
firstPersonWeaponModel["Model"]["Visible"] = true;
}
EntityWrapper thirdPersonWeaponModel = m_Player.FirstChildByName("ThirdPersonWeaponModel");
if (thirdPersonWeaponModel.Valid()) {
thirdPersonWeaponModel["Model"]["Visible"] = true;
}
m_Reloading = false;
}
@@ -278,19 +298,45 @@ void AssaultWeaponBehaviour::playIdleAnimation()
void AssaultWeaponBehaviour::playReloadAnimation()
{
// Play animation
ComponentWrapper cAnimation = m_FirstPersonModel["Animation"];
cAnimation["AnimationName1"] = "ReloadSwitch";
cAnimation["Weight1"] = 1.0;
cAnimation["Time1"] = 0.0;
cAnimation["Speed1"] = 0.5;
cAnimation["Loop1"] = true;
// First person
if (IsClient)
{
ComponentWrapper cAnimation = m_FirstPersonModel["Animation"];
cAnimation["AnimationName1"] = "ReloadSwitch";
cAnimation["Weight1"] = 1.0;
cAnimation["Time1"] = 0.0;
cAnimation["Speed1"] = 0.5;
cAnimation["Loop1"] = true;
}
// TODO: Third person
//{
// ComponentWrapper cAnimation = m_ThirdPersonModel["Animation"];
// cAnimation["AnimationName1"] = "ReloadSwitch";
// cAnimation["Weight1"] = 1.0;
// cAnimation["Time1"] = 0.0;
// cAnimation["Speed1"] = 0.5;
// cAnimation["Loop1"] = true;
//}
// Hide weapon model and spawn the exploding version
EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel");
EntityWrapper reloadSpawner = m_Player.FirstChildByName("FirstPersonReloadSpawner");
m_ReloadImpersonator = SpawnerSystem::Spawn(reloadSpawner, reloadSpawner);
firstPersonWeaponModel["Model"].Copy(m_ReloadImpersonator["Model"]);
firstPersonWeaponModel["Model"]["Visible"] = false;
{
EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel");
EntityWrapper reloadSpawner = m_Player.FirstChildByName("FirstPersonReloadSpawner");
if (IsClient) {
m_FirstPersonReloadImpersonator = SpawnerSystem::Spawn(reloadSpawner, reloadSpawner);
firstPersonWeaponModel["Model"].Copy(m_FirstPersonReloadImpersonator["Model"]);
}
firstPersonWeaponModel["Model"]["Visible"] = false;
}
{
EntityWrapper thirdPersonWeaponModel = m_Player.FirstChildByName("ThirdPersonWeaponModel");
EntityWrapper reloadSpawner = m_Player.FirstChildByName("ThirdPersonReloadSpawner");
if (IsClient) {
m_ThirdPersonReloadImpersonator = SpawnerSystem::Spawn(reloadSpawner, reloadSpawner);
thirdPersonWeaponModel["Model"].Copy(m_ThirdPersonReloadImpersonator["Model"]);
}
thirdPersonWeaponModel["Model"]["Visible"] = false;
}
}
bool AssaultWeaponBehaviour::shoot(double damage)
@@ -321,6 +367,9 @@ bool AssaultWeaponBehaviour::shoot(double damage)
}
EntityWrapper victim(m_World, pickData.Entity);
if (!victim.Valid()) {
return false;
}
// Don't let us shoot ourselves in the foot
if (victim == LocalPlayer) {
+18 -4
View File
@@ -1,11 +1,25 @@
#include "Game.h"
#include "MiniDump.h"
LONG WINAPI CrashHandler(EXCEPTION_POINTERS* pException);
int main(int argc, char* argv[])
{
Game game(argc, argv);
while (game.Running()) {
game.Tick();
}
::SetUnhandledExceptionFilter(CrashHandler);
Game game(argc, argv);
while (game.Running()) {
game.Tick();
}
return 0;
}
LONG WINAPI CrashHandler(EXCEPTION_POINTERS* pException)
{
//Take minidump. path should be bin/TacticalZ.dmp
//Then show MessageBox, and exit application.
Create_Dump(pException, 1, 1);
return EXCEPTION_EXECUTE_HANDLER;// EXCEPTION_CONTINUE_SEARCH
}