Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions mp/game/neo/materials/effects/fpmf/fpmf01.vmt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"UnlitGeneric"
{
"$basetexture" "effects\fpmf\fpmf01"
"$nocull" 1
"$additive" 1
"$model" 1
"$translucent" 1
}
8 changes: 8 additions & 0 deletions mp/game/neo/materials/effects/fpmf/fpmf02.vmt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"UnlitGeneric"
{
"$basetexture" "effects\fpmf\fpmf02"
"$nocull" 1
"$additive" 1
"$model" 1
"$translucent" 1
}
2 changes: 2 additions & 0 deletions mp/src/game/client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1564,6 +1564,8 @@ target_sources_grouped(
${CMAKE_SOURCE_DIR}/game/shared/neo/neo_playeranimstate.h
${CMAKE_SOURCE_DIR}/game/shared/neo/neo_predicted_viewmodel.cpp
${CMAKE_SOURCE_DIR}/game/shared/neo/neo_predicted_viewmodel.h
${CMAKE_SOURCE_DIR}/game/shared/neo/neo_predicted_viewmodel_muzzleflash.cpp
${CMAKE_SOURCE_DIR}/game/shared/neo/neo_predicted_viewmodel_muzzleflash.h
${CMAKE_SOURCE_DIR}/game/shared/neo/neo_shot_manipulator.cpp
${CMAKE_SOURCE_DIR}/game/shared/neo/neo_shot_manipulator.h
${CMAKE_SOURCE_DIR}/game/shared/neo/neo_version.cpp
Expand Down
3 changes: 3 additions & 0 deletions mp/src/game/client/c_baseplayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,9 @@ class C_BasePlayer : public C_BaseCombatCharacter, public CGameEventListener
virtual void Weapon_SetLast( C_BaseCombatWeapon *pWeapon );
virtual bool Weapon_ShouldSetLast( C_BaseCombatWeapon *pOldWeapon, C_BaseCombatWeapon *pNewWeapon ) { return true; }
virtual bool Weapon_ShouldSelectItem( C_BaseCombatWeapon *pWeapon );
#ifdef NEO
void UpdateMuzzleFlashProperties( C_BaseCombatWeapon* pWeapon );
#endif
virtual bool Weapon_Switch( C_BaseCombatWeapon *pWeapon, int viewmodelindex = 0 ); // Switch to given weapon if has ammo (false if failed)
virtual C_BaseCombatWeapon *GetLastWeapon( void ) { return m_hLastWeapon.Get(); }
void ResetAutoaim( void );
Expand Down
2 changes: 2 additions & 0 deletions mp/src/game/server/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1322,6 +1322,8 @@ target_sources_grouped(
${CMAKE_SOURCE_DIR}/game/shared/neo/neo_playeranimstate.h
${CMAKE_SOURCE_DIR}/game/shared/neo/neo_predicted_viewmodel.cpp
${CMAKE_SOURCE_DIR}/game/shared/neo/neo_predicted_viewmodel.h
${CMAKE_SOURCE_DIR}/game/shared/neo/neo_predicted_viewmodel_muzzleflash.cpp
${CMAKE_SOURCE_DIR}/game/shared/neo/neo_predicted_viewmodel_muzzleflash.h
${CMAKE_SOURCE_DIR}/game/shared/neo/neo_shot_manipulator.cpp
${CMAKE_SOURCE_DIR}/game/shared/neo/neo_shot_manipulator.h
${CMAKE_SOURCE_DIR}/game/shared/neo/neo_version.cpp
Expand Down
48 changes: 33 additions & 15 deletions mp/src/game/server/neo/neo_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "neo_playeranimstate.h"
#include "neo_predicted_viewmodel.h"
#include "neo_predicted_viewmodel_muzzleflash.h"
#include "in_buttons.h"
#include "neo_gamerules.h"
#include "team.h"
Expand Down Expand Up @@ -1468,26 +1469,43 @@ bool CNEO_Player::ClientCommand( const CCommand &args )
void CNEO_Player::CreateViewModel( int index )
{
Assert( index >= 0 && index < MAX_VIEWMODELS );
Assert(MUZZLE_FLASH_VIEW_MODEL_INDEX != index && MUZZLE_FLASH_VIEW_MODEL_INDEX < MAX_VIEWMODELS);

if ( GetViewModel( index ) )
if ( !GetViewModel( index ) )
{
return;
CNEOPredictedViewModel* vm = (CNEOPredictedViewModel*)CreateEntityByName("neo_predicted_viewmodel");
if (vm)
{
vm->SetAbsOrigin(GetAbsOrigin());
vm->SetOwner(this);
vm->SetIndex(index);
DispatchSpawn(vm);
vm->FollowEntity(this, false);
m_hViewModel.Set(index, vm);
}
}

CNEOPredictedViewModel *vm = ( CNEOPredictedViewModel * )CreateEntityByName( "neo_predicted_viewmodel" );
if ( vm )
if ( !GetViewModel(MUZZLE_FLASH_VIEW_MODEL_INDEX))
{
vm->SetAbsOrigin( GetAbsOrigin() );
vm->SetOwner( this );
vm->SetIndex( index );
DispatchSpawn( vm );
vm->FollowEntity( this, false );
m_hViewModel.Set( index, vm );
}
else
{
Warning("CNEO_Player::CreateViewModel: Failed to create neo_predicted_viewmodel\n");
return;
auto* vmm = (CNEOPredictedViewModelMuzzleFlash*)CreateEntityByName("neo_predicted_viewmodel_muzzleflash");
if (!vmm)
{
Assert(false);
return;
}

CBaseViewModel* vm = GetViewModel();
if (!vm)
{
Assert(false);
return;
}

vmm->SetAbsOrigin(vm->GetAbsOrigin());
vmm->SetOwner(this);
vmm->SetParent(vm);
DispatchSpawn(vmm);
m_hViewModel.Set(MUZZLE_FLASH_VIEW_MODEL_INDEX, vmm);
}
}

Expand Down
3 changes: 3 additions & 0 deletions mp/src/game/server/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,9 @@ class CBasePlayer : public CBaseCombatCharacter
virtual bool Weapon_CanUse( CBaseCombatWeapon *pWeapon );
virtual void Weapon_Equip( CBaseCombatWeapon *pWeapon );
virtual void Weapon_Drop( CBaseCombatWeapon *pWeapon, const Vector *pvecTarget /* = NULL */, const Vector *pVelocity /* = NULL */ );
#ifdef NEO
void UpdateMuzzleFlashProperties( CBaseCombatWeapon* pWeapon );
#endif
virtual bool Weapon_Switch( CBaseCombatWeapon *pWeapon, int viewmodelindex = 0 ); // Switch to given weapon if has ammo (false if failed)
virtual void Weapon_SetLast( CBaseCombatWeapon *pWeapon );
virtual bool Weapon_ShouldSetLast( CBaseCombatWeapon *pOldWeapon, CBaseCombatWeapon *pNewWeapon ) { return true; }
Expand Down
74 changes: 74 additions & 0 deletions mp/src/game/shared/baseplayer_shared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@

#ifdef NEO
#include "neo_gamerules.h"
#include "weapon_neobasecombatweapon.h"
#include "neo_predicted_viewmodel_muzzleflash.h"
#ifdef GAME_DLL
#include "neo_player.h"
#else
Expand Down Expand Up @@ -869,6 +871,65 @@ void CBasePlayer::Weapon_SetLast( CBaseCombatWeapon *pWeapon )
m_hLastWeapon = pWeapon;
}

#ifdef NEO
void CBasePlayer::UpdateMuzzleFlashProperties(CBaseCombatWeapon* pWeapon)
{
auto neoWep = static_cast<CNEOBaseCombatWeapon*>(pWeapon);
if (!neoWep)
return;

auto* neoViewModelMuzzleflash = static_cast<CNEOPredictedViewModelMuzzleFlash*>(m_hViewModel[MUZZLE_FLASH_VIEW_MODEL_INDEX].Get());
if (!neoViewModelMuzzleflash)
return;

const auto neoWepBits = neoWep->GetNeoWepBits();
if (neoWepBits & (NEO_WEP_THROWABLE | NEO_WEP_GHOST | NEO_WEP_KNIFE | NEO_WEP_SUPPRESSED))
{
neoViewModelMuzzleflash->m_bActive = false;
}
else if (neoWepBits & (NEO_WEP_PZ | NEO_WEP_TACHI | NEO_WEP_KYLA))
{
neoViewModelMuzzleflash->m_bActive = true;
neoViewModelMuzzleflash->m_nSkin = 1;
neoViewModelMuzzleflash->m_iAngleZ = 0;
neoViewModelMuzzleflash->m_iAngleZIncrement = -100;
neoViewModelMuzzleflash->SetModelScale(0.75);
}
else if (neoWepBits & NEO_WEP_SUPA7)
{
neoViewModelMuzzleflash->m_bActive = true;
neoViewModelMuzzleflash->m_nSkin = 1;
neoViewModelMuzzleflash->m_iAngleZ = 0;
neoViewModelMuzzleflash->m_iAngleZIncrement = -90;
neoViewModelMuzzleflash->SetModelScale(2);
}
else if (neoWepBits & (NEO_WEP_SRM | NEO_WEP_JITTE))
{
neoViewModelMuzzleflash->m_bActive = true;
neoViewModelMuzzleflash->m_nSkin = 0;
neoViewModelMuzzleflash->m_iAngleZ = 0;
neoViewModelMuzzleflash->m_iAngleZIncrement = -90;
neoViewModelMuzzleflash->SetModelScale(0.75);
}
else if (neoWepBits & (NEO_WEP_MX | NEO_WEP_AA13))
{
neoViewModelMuzzleflash->m_bActive = true;
neoViewModelMuzzleflash->m_nSkin = 0;
neoViewModelMuzzleflash->m_iAngleZ = 0;
neoViewModelMuzzleflash->m_iAngleZIncrement = -100;
neoViewModelMuzzleflash->SetModelScale(0.6);
}
else
{
neoViewModelMuzzleflash->m_bActive = true;
neoViewModelMuzzleflash->m_nSkin = 0;
neoViewModelMuzzleflash->m_iAngleZ = 0;
neoViewModelMuzzleflash->m_iAngleZIncrement = -90;
neoViewModelMuzzleflash->SetModelScale(0.75);
}
}
#endif // NEO

//-----------------------------------------------------------------------------
// Purpose: Override base class so player can reset autoaim
// Input :
Expand All @@ -890,8 +951,21 @@ bool CBasePlayer::Weapon_Switch( CBaseCombatWeapon *pWeapon, int viewmodelindex
if ( pViewModel )
pViewModel->RemoveEffects( EF_NODRAW );
ResetAutoaim( );

#ifdef NEO
UpdateMuzzleFlashProperties(pWeapon);
#endif // NEO

return true;
}

#ifdef NEO
if (IsAlive() == false)
{
// Active weapon was probably updated, update muzzle flash properties regardless
UpdateMuzzleFlashProperties(pWeapon);
}
#endif // NEO
return false;
}

Expand Down
20 changes: 20 additions & 0 deletions mp/src/game/shared/neo/neo_predicted_viewmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include "model_types.h"
#include "prediction.h"
#include "viewrender.h"
#include "r_efx.h"
#include "dlight.h"
#else
#include "neo_player.h"
#endif
Expand Down Expand Up @@ -429,6 +431,24 @@ void CNEOPredictedViewModel::CalcViewModelView(CBasePlayer *pOwner,
}

#ifdef CLIENT_DLL
void CNEOPredictedViewModel::ProcessMuzzleFlashEvent()
{
Vector vAttachment;
QAngle dummyAngles;
GetAttachment(2, vAttachment, dummyAngles);
Comment thread
AdamTadeusz marked this conversation as resolved.

// Make a dlight
dlight_t* dl = effects->CL_AllocDlight(LIGHT_INDEX_MUZZLEFLASH + index);
dl->origin = vAttachment;
dl->radius = random->RandomInt(64, 96);
dl->decay = dl->radius / 0.1f;
dl->die = gpGlobals->curtime + 0.1f;
dl->color.r = 255;
dl->color.g = 192;
dl->color.b = 64;
dl->color.exponent = 5;
}

RenderGroup_t CNEOPredictedViewModel::GetRenderGroup()
{
auto pPlayer = static_cast<C_NEO_Player*>(GetOwner());
Expand Down
1 change: 1 addition & 0 deletions mp/src/game/shared/neo/neo_predicted_viewmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class CNEOPredictedViewModel : public CPredictedViewModel
virtual void ClientThink() override;

virtual int DrawModel(int flags);
virtual void ProcessMuzzleFlashEvent() final override;

virtual RenderGroup_t GetRenderGroup();
#endif
Expand Down
83 changes: 83 additions & 0 deletions mp/src/game/shared/neo/neo_predicted_viewmodel_muzzleflash.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#include "cbase.h"
#include "model_types.h"

#ifdef GAME_DLL
#include "baseanimating.h"
#endif

#include "neo_predicted_viewmodel_muzzleflash.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

IMPLEMENT_NETWORKCLASS_ALIASED(NEOPredictedViewModelMuzzleFlash, DT_NEOPredictedViewModelMuzzleFlash)

BEGIN_NETWORK_TABLE(CNEOPredictedViewModelMuzzleFlash, DT_NEOPredictedViewModelMuzzleFlash)
#ifndef CLIENT_DLL
SendPropEHandle(SENDINFO_NAME(m_hMoveParent, moveparent)),
#else
RecvPropInt(RECVINFO_NAME(m_hNetworkMoveParent, moveparent), 0, RecvProxy_IntToMoveParent),
#endif
END_NETWORK_TABLE()

#ifdef CLIENT_DLL
BEGIN_PREDICTION_DATA(CNEOPredictedViewModelMuzzleFlash)
END_PREDICTION_DATA()
#endif

LINK_ENTITY_TO_CLASS(neo_predicted_viewmodel_muzzleflash, CNEOPredictedViewModelMuzzleFlash);

constexpr const char* MUZZLE_FLASH_ENTITY_MODEL = "models/effect/fpmf/fpmf01.mdl";

//-----------------------------------------------------------------------------
// Purpose: Precache assets used by the entity
//-----------------------------------------------------------------------------
void CNEOPredictedViewModelMuzzleFlash::Precache(void)
{
PrecacheModel(MUZZLE_FLASH_ENTITY_MODEL);

BaseClass::Precache();
}

//-----------------------------------------------------------------------------
// Purpose: Sets up the entity's initial state
//-----------------------------------------------------------------------------
void CNEOPredictedViewModelMuzzleFlash::Spawn(void)
{
Precache();
SetModel(MUZZLE_FLASH_ENTITY_MODEL);
SetSolid(SOLID_NONE);
AddEffects(EF_NOSHADOW | EF_NORECEIVESHADOW);
RemoveEffects(EF_NODRAW | EF_BONEMERGE);
}

#ifdef CLIENT_DLL
int CNEOPredictedViewModelMuzzleFlash::DrawModel(int flags)
{
if (m_flTimeSwitchOffMuzzleFlash > gpGlobals->curtime && m_bActive)
{
CBasePlayer* pOwner = ToBasePlayer(GetOwner());
if (pOwner == NULL)
return -1;
CBaseViewModel* vm = pOwner->GetViewModel(0, false);
if (vm == NULL)
return -1;

int iAttachment = vm->LookupAttachment("muzzle");
if (iAttachment < 0)
return -1;

Vector localOrigin;
QAngle localAngle;
vm->GetAttachment(iAttachment, localOrigin, localAngle);
UncorrectViewModelAttachment(localOrigin); // Need position of muzzle without fov modifications & viewmodel offset
m_iAngleZ = (m_iAngleZ + m_iAngleZIncrement) % 360; // NEOTODO (Adam) ? Speed of rotation depends on how often DrawModel() is called. Should this be tied to global time?
localAngle.z = m_iAngleZ;
SetAbsOrigin(localOrigin);
SetAbsAngles(localAngle);

return BaseClass::DrawModel(flags);
}
return -1;
}
#endif
50 changes: 50 additions & 0 deletions mp/src/game/shared/neo/neo_predicted_viewmodel_muzzleflash.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#ifndef NEO_PREDICTED_VIEWMODEL_MUZZLEFLASH_H
#define NEO_PREDICTED_VIEWMODEL_MUZZLEFLASH_H
#ifdef _WIN32
#pragma once
#endif

#include "predicted_viewmodel.h"

#ifdef CLIENT_DLL
#define CNEOPredictedViewModelMuzzleFlash C_NEOPredictedViewModelMuzzleFlash
#endif

#define MUZZLE_FLASH_VIEW_MODEL_INDEX 1

class CNEOPredictedViewModelMuzzleFlash : public CPredictedViewModel
{
DECLARE_CLASS(CNEOPredictedViewModelMuzzleFlash, CPredictedViewModel);
public:
DECLARE_NETWORKCLASS();
DECLARE_PREDICTABLE();
CNEOPredictedViewModelMuzzleFlash()
{
m_bActive = true;
m_iAngleZ = 0;
m_iAngleZIncrement = -5;
m_flTimeSwitchOffMuzzleFlash = gpGlobals->curtime;
}

#ifdef CLIENT_DLL
virtual ShadowType_t ShadowCastType() final override { return SHADOWS_NONE; };
virtual RenderGroup_t GetRenderGroup() final override { return RENDER_GROUP_VIEW_MODEL_TRANSLUCENT; };
virtual int DrawModel(int flags) final override;
virtual void ProcessMuzzleFlashEvent() final override
{
if (!m_bActive)
return;
m_flTimeSwitchOffMuzzleFlash = gpGlobals->curtime + 0.01f;
BaseClass::ProcessMuzzleFlashEvent();
}
#endif

virtual void Spawn(void) override;
virtual void Precache(void) override;
bool m_bActive;
int m_iAngleZ;
int m_iAngleZIncrement;
float m_flTimeSwitchOffMuzzleFlash; // If the server can fire a user's weapon (maybe some kind of server triggered weapon cook off or something), this will need to be networked too.
};

#endif // NEO_PREDICTED_VIEWMODEL_MUZZLEFLASH_H
Loading