Files
monstermod-redo-repo-copy/src/dlls/weapons.cpp
Giegue 0622ccc638 Stop allied monsters from attacking the player.
Part B of making MonsterMod aware of normal HL entities.
2023-02-19 15:57:07 -03:00

235 lines
5.8 KiB
C++

/***
*
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
/*
===== weapons.cpp ========================================================
functions governing the selection/use of weapons for players
*/
#include "extdll.h"
#include "util.h"
#include "cmbase.h"
#include "cmbasemonster.h"
#include "monsters.h"
#include "weapons.h"
#include "nodes.h"
#include "decals.h"
extern CGraph WorldGraph;
MULTIDAMAGE gMultiDamage;
#define TRACER_FREQ 4 // Tracers fire every fourth bullet
/*
==============================================================================
MULTI-DAMAGE
Collects multiple small damages into a single damage
==============================================================================
*/
//
// ClearMultiDamage - resets the global multi damage accumulator
//
void ClearMultiDamage(void)
{
gMultiDamage.pEntity = NULL;
gMultiDamage.amount = 0;
gMultiDamage.type = 0;
}
//
// ApplyMultiDamage - inflicts contents of global multi damage register on gMultiDamage.pEntity
//
// GLOBALS USED:
// gMultiDamage
void ApplyMultiDamage(entvars_t *pevInflictor, entvars_t *pevAttacker )
{
Vector vecSpot1;//where blood comes from
Vector vecDir;//direction blood should go
TraceResult tr;
if ( !gMultiDamage.pEntity )
return;
if (UTIL_IsPlayer(gMultiDamage.pEntity))
UTIL_TakeDamage(gMultiDamage.pEntity, pevInflictor, pevAttacker, gMultiDamage.amount, gMultiDamage.type );
else if (gMultiDamage.pEntity->v.euser4 != NULL)
{
CMBaseMonster *pMonster = GetClassPtr((CMBaseMonster *)VARS(gMultiDamage.pEntity));
pMonster->TakeDamage(pevInflictor, pevAttacker, gMultiDamage.amount, gMultiDamage.type );
}
else
UTIL_TakeDamageExternal(gMultiDamage.pEntity, pevInflictor, pevAttacker, gMultiDamage.amount, gMultiDamage.type );
}
// GLOBALS USED:
// gMultiDamage
void AddMultiDamage( entvars_t *pevInflictor, edict_t *pEntity, float flDamage, int bitsDamageType)
{
if ( !pEntity )
return;
gMultiDamage.type |= bitsDamageType;
if ( pEntity != gMultiDamage.pEntity )
{
ApplyMultiDamage(pevInflictor,pevInflictor); // UNDONE: wrong attacker!
gMultiDamage.pEntity = pEntity;
gMultiDamage.amount = 0;
}
gMultiDamage.amount += flDamage;
}
/*
================
SpawnBlood
================
*/
void SpawnBlood(Vector vecSpot, int bloodColor, float flDamage)
{
UTIL_BloodDrips( vecSpot, g_vecAttackDir, bloodColor, (int)flDamage );
}
int DamageDecal( CMBaseEntity *pEntity, int bitsDamageType )
{
if ( !pEntity )
return (DECAL_GUNSHOT1 + RANDOM_LONG(0,4));
return pEntity->DamageDecal( bitsDamageType );
}
void DecalGunshot( TraceResult *pTrace, int iBulletType )
{
// Is the entity valid
if ( !UTIL_IsValidEntity( pTrace->pHit ) )
return;
if ( VARS(pTrace->pHit)->solid == SOLID_BSP || VARS(pTrace->pHit)->movetype == MOVETYPE_PUSHSTEP )
{
CMBaseEntity *pEntity = NULL;
// Decal the wall with a gunshot
if ( !FNullEnt(pTrace->pHit) )
pEntity = CMBaseEntity::Instance(pTrace->pHit);
switch( iBulletType )
{
case BULLET_PLAYER_CROWBAR:
{
// wall decal
UTIL_DecalTrace( pTrace, DamageDecal( pEntity, DMG_CLUB ) );
break;
}
default:
{
// smoke and decal
UTIL_GunshotDecalTrace( pTrace, DamageDecal( pEntity, DMG_BULLET ) );
break;
}
/* why the duplicate case?
case BULLET_PLAYER_9MM:
case BULLET_MONSTER_9MM:
case BULLET_PLAYER_MP5:
case BULLET_MONSTER_MP5:
case BULLET_PLAYER_BUCKSHOT:
case BULLET_PLAYER_357:
default:
// smoke and decal
UTIL_GunshotDecalTrace( pTrace, DamageDecal( pEntity, DMG_BULLET ) );
break;
case BULLET_MONSTER_12MM:
// smoke and decal
UTIL_GunshotDecalTrace( pTrace, DamageDecal( pEntity, DMG_BULLET ) );
break;
case BULLET_PLAYER_CROWBAR:
// wall decal
UTIL_DecalTrace( pTrace, DamageDecal( pEntity, DMG_CLUB ) );
break;
*/
}
}
}
//
// EjectBrass - tosses a brass shell from passed origin at passed velocity
//
void EjectBrass ( const Vector &vecOrigin, const Vector &vecVelocity, float rotation, int model, int soundtype )
{
// FIX: when the player shoots, their gun isn't in the same position as it is on the model other players see.
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecOrigin );
WRITE_BYTE( TE_MODEL);
WRITE_COORD( vecOrigin.x);
WRITE_COORD( vecOrigin.y);
WRITE_COORD( vecOrigin.z);
WRITE_COORD( vecVelocity.x);
WRITE_COORD( vecVelocity.y);
WRITE_COORD( vecVelocity.z);
WRITE_ANGLE( rotation );
WRITE_SHORT( model );
WRITE_BYTE ( soundtype);
WRITE_BYTE ( 25 );// 2.5 seconds
MESSAGE_END();
}
#if 0
// UNDONE: This is no longer used?
void ExplodeModel( const Vector &vecOrigin, float speed, int model, int count )
{
MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecOrigin );
WRITE_BYTE ( TE_EXPLODEMODEL );
WRITE_COORD( vecOrigin.x );
WRITE_COORD( vecOrigin.y );
WRITE_COORD( vecOrigin.z );
WRITE_COORD( speed );
WRITE_SHORT( model );
WRITE_SHORT( count );
WRITE_BYTE ( 15 );// 1.5 seconds
MESSAGE_END();
}
#endif
BOOL CanAttack( float attack_time, float curtime, BOOL isPredicted )
{
#if defined( CLIENT_WEAPONS )
if ( !isPredicted )
#else
if ( 1 )
#endif
{
return ( attack_time <= curtime ) ? TRUE : FALSE;
}
else
{
return ( attack_time <= 0.0 ) ? TRUE : FALSE;
}
}