mirror of
https://github.com/YGGverse/hlsdk-portable.git
synced 2025-01-24 05:34:18 +00:00
Merge pull request #315 from FreeSlave/opfor_allies_check_ff
[opforfixed] Allies check for player to avoid friendly fire
This commit is contained in:
commit
1c5381c07d
100
dlls/barney.cpp
100
dlls/barney.cpp
@ -28,6 +28,7 @@
|
|||||||
#include "weapons.h"
|
#include "weapons.h"
|
||||||
#include "soundent.h"
|
#include "soundent.h"
|
||||||
#include "barney.h"
|
#include "barney.h"
|
||||||
|
#include "plane.h"
|
||||||
|
|
||||||
//=========================================================
|
//=========================================================
|
||||||
// Monster's Anim Events Go Here
|
// Monster's Anim Events Go Here
|
||||||
@ -41,6 +42,13 @@
|
|||||||
#define BARNEY_BODY_GUNDRAWN 1
|
#define BARNEY_BODY_GUNDRAWN 1
|
||||||
#define BARNEY_BODY_GUNGONE 2
|
#define BARNEY_BODY_GUNGONE 2
|
||||||
|
|
||||||
|
#define bits_COND_BARNEY_NOFIRE ( bits_COND_SPECIAL1 )
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TASK_BARNEY_CHECK_FIRE = LAST_COMMON_TASK + 1,
|
||||||
|
};
|
||||||
|
|
||||||
LINK_ENTITY_TO_CLASS( monster_barney, CBarney )
|
LINK_ENTITY_TO_CLASS( monster_barney, CBarney )
|
||||||
|
|
||||||
TYPEDESCRIPTION CBarney::m_SaveData[] =
|
TYPEDESCRIPTION CBarney::m_SaveData[] =
|
||||||
@ -154,19 +162,57 @@ Schedule_t slIdleBaStand[] =
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// primary range attack
|
||||||
|
Task_t tlBaRangeAttack1[] =
|
||||||
|
{
|
||||||
|
{ TASK_STOP_MOVING, 0 },
|
||||||
|
{ TASK_FACE_ENEMY, (float)0 },
|
||||||
|
{ TASK_BARNEY_CHECK_FIRE, (float)0 },
|
||||||
|
{ TASK_RANGE_ATTACK1, (float)0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
Schedule_t slBaRangeAttack1[] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
tlBaRangeAttack1,
|
||||||
|
ARRAYSIZE( tlBaRangeAttack1 ),
|
||||||
|
bits_COND_NEW_ENEMY |
|
||||||
|
bits_COND_ENEMY_DEAD |
|
||||||
|
bits_COND_LIGHT_DAMAGE |
|
||||||
|
bits_COND_HEAVY_DAMAGE |
|
||||||
|
bits_COND_ENEMY_OCCLUDED |
|
||||||
|
bits_COND_NO_AMMO_LOADED |
|
||||||
|
bits_COND_BARNEY_NOFIRE |
|
||||||
|
bits_COND_HEAR_SOUND,
|
||||||
|
bits_SOUND_DANGER,
|
||||||
|
"Range Attack1"
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
DEFINE_CUSTOM_SCHEDULES( CBarney )
|
DEFINE_CUSTOM_SCHEDULES( CBarney )
|
||||||
{
|
{
|
||||||
slBaFollow,
|
slBaFollow,
|
||||||
slBarneyEnemyDraw,
|
slBarneyEnemyDraw,
|
||||||
slBaFaceTarget,
|
slBaFaceTarget,
|
||||||
slIdleBaStand,
|
slIdleBaStand,
|
||||||
|
slBaRangeAttack1,
|
||||||
};
|
};
|
||||||
|
|
||||||
IMPLEMENT_CUSTOM_SCHEDULES( CBarney, CTalkMonster )
|
IMPLEMENT_CUSTOM_SCHEDULES( CBarney, CTalkMonster )
|
||||||
|
|
||||||
void CBarney::StartTask( Task_t *pTask )
|
void CBarney::StartTask( Task_t *pTask )
|
||||||
{
|
{
|
||||||
CTalkMonster::StartTask( pTask );
|
switch ( pTask->iTask ) {
|
||||||
|
case TASK_BARNEY_CHECK_FIRE:
|
||||||
|
if( !NoFriendlyFire() )
|
||||||
|
{
|
||||||
|
SetConditions( bits_COND_BARNEY_NOFIRE );
|
||||||
|
}
|
||||||
|
TaskComplete();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CTalkMonster::StartTask( pTask );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBarney::RunTask( Task_t *pTask )
|
void CBarney::RunTask( Task_t *pTask )
|
||||||
@ -617,6 +663,8 @@ Schedule_t *CBarney::GetScheduleOfType( int Type )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
return psched;
|
return psched;
|
||||||
|
case SCHED_RANGE_ATTACK1:
|
||||||
|
return slBaRangeAttack1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CTalkMonster::GetScheduleOfType( Type );
|
return CTalkMonster::GetScheduleOfType( Type );
|
||||||
@ -718,6 +766,56 @@ void CBarney::DeclineFollowing( void )
|
|||||||
PlaySentence( "BA_POK", 2, VOL_NORM, ATTN_NORM );
|
PlaySentence( "BA_POK", 2, VOL_NORM, ATTN_NORM );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL CBarney::NoFriendlyFire()
|
||||||
|
{
|
||||||
|
if( m_hEnemy != 0 )
|
||||||
|
{
|
||||||
|
UTIL_MakeVectors( UTIL_VecToAngles( m_hEnemy->Center() - pev->origin ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if there's no enemy, pretend there's a friendly in the way, so the grunt won't shoot.
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CPlane backPlane;
|
||||||
|
CPlane leftPlane;
|
||||||
|
CPlane rightPlane;
|
||||||
|
|
||||||
|
Vector vecLeftSide;
|
||||||
|
Vector vecRightSide;
|
||||||
|
Vector v_left;
|
||||||
|
Vector v_dir;
|
||||||
|
|
||||||
|
v_dir = gpGlobals->v_right * ( pev->size.x * 1.5f );
|
||||||
|
vecLeftSide = pev->origin - v_dir;
|
||||||
|
vecRightSide = pev->origin + v_dir;
|
||||||
|
|
||||||
|
v_left = gpGlobals->v_right * -1.0f;
|
||||||
|
|
||||||
|
leftPlane.InitializePlane( gpGlobals->v_right, vecLeftSide );
|
||||||
|
rightPlane.InitializePlane( v_left, vecRightSide );
|
||||||
|
backPlane.InitializePlane( gpGlobals->v_forward, pev->origin );
|
||||||
|
|
||||||
|
for( int k = 1; k <= gpGlobals->maxClients; k++ )
|
||||||
|
{
|
||||||
|
CBaseEntity* pPlayer = UTIL_PlayerByIndex(k);
|
||||||
|
if (pPlayer && pPlayer->IsPlayer() && IRelationship(pPlayer) == R_AL && pPlayer->IsAlive())
|
||||||
|
{
|
||||||
|
if( backPlane.PointInFront( pPlayer->pev->origin ) &&
|
||||||
|
leftPlane.PointInFront( pPlayer->pev->origin ) &&
|
||||||
|
rightPlane.PointInFront( pPlayer->pev->origin ) )
|
||||||
|
{
|
||||||
|
//ALERT(at_aiconsole, "%s: Ally player at fire plane!\n", STRING(pev->classname));
|
||||||
|
// player is in the check volume! Don't shoot!
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
//=========================================================
|
//=========================================================
|
||||||
// DEAD BARNEY PROP
|
// DEAD BARNEY PROP
|
||||||
//
|
//
|
||||||
|
@ -55,6 +55,8 @@ public:
|
|||||||
virtual void TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType);
|
virtual void TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType);
|
||||||
virtual void Killed(entvars_t *pevAttacker, int iGib);
|
virtual void Killed(entvars_t *pevAttacker, int iGib);
|
||||||
|
|
||||||
|
BOOL NoFriendlyFire();
|
||||||
|
|
||||||
virtual int Save(CSave &save);
|
virtual int Save(CSave &save);
|
||||||
virtual int Restore(CRestore &restore);
|
virtual int Restore(CRestore &restore);
|
||||||
static TYPEDESCRIPTION m_SaveData[];
|
static TYPEDESCRIPTION m_SaveData[];
|
||||||
@ -73,4 +75,4 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // BARNEY_H
|
#endif // BARNEY_H
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "customentity.h"
|
#include "customentity.h"
|
||||||
#include "decals.h"
|
#include "decals.h"
|
||||||
#include "hgrunt.h"
|
#include "hgrunt.h"
|
||||||
|
#include "plane.h"
|
||||||
|
|
||||||
//=========================================================
|
//=========================================================
|
||||||
//
|
//
|
||||||
@ -185,6 +186,8 @@ public:
|
|||||||
int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType );
|
int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType );
|
||||||
int IRelationship ( CBaseEntity *pTarget );
|
int IRelationship ( CBaseEntity *pTarget );
|
||||||
|
|
||||||
|
BOOL NoFriendlyFire( void );
|
||||||
|
|
||||||
virtual int Save( CSave &save );
|
virtual int Save( CSave &save );
|
||||||
virtual int Restore( CRestore &restore );
|
virtual int Restore( CRestore &restore );
|
||||||
static TYPEDESCRIPTION m_SaveData[];
|
static TYPEDESCRIPTION m_SaveData[];
|
||||||
@ -2909,6 +2912,81 @@ MONSTERSTATE CHFGrunt :: GetIdealState ( void )
|
|||||||
return CTalkMonster::GetIdealState();
|
return CTalkMonster::GetIdealState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL CHFGrunt::NoFriendlyFire( void )
|
||||||
|
{
|
||||||
|
CPlane backPlane;
|
||||||
|
CPlane leftPlane;
|
||||||
|
CPlane rightPlane;
|
||||||
|
|
||||||
|
Vector vecLeftSide;
|
||||||
|
Vector vecRightSide;
|
||||||
|
Vector v_left;
|
||||||
|
Vector v_dir;
|
||||||
|
|
||||||
|
//!!!BUGBUG - to fix this, the planes must be aligned to where the monster will be firing its gun, not the direction it is facing!!!
|
||||||
|
if( m_hEnemy != 0 )
|
||||||
|
{
|
||||||
|
UTIL_MakeVectors( UTIL_VecToAngles( m_hEnemy->Center() - pev->origin ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if there's no enemy, pretend there's a friendly in the way, so the grunt won't shoot.
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
v_dir = gpGlobals->v_right * ( pev->size.x * 1.5f );
|
||||||
|
vecLeftSide = pev->origin - v_dir;
|
||||||
|
vecRightSide = pev->origin + v_dir;
|
||||||
|
|
||||||
|
v_left = gpGlobals->v_right * -1.0f;
|
||||||
|
|
||||||
|
leftPlane.InitializePlane( gpGlobals->v_right, vecLeftSide );
|
||||||
|
rightPlane.InitializePlane( v_left, vecRightSide );
|
||||||
|
backPlane.InitializePlane( gpGlobals->v_forward, pev->origin );
|
||||||
|
/*
|
||||||
|
ALERT( at_console, "LeftPlane: %f %f %f : %f\n", leftPlane.m_vecNormal.x, leftPlane.m_vecNormal.y, leftPlane.m_vecNormal.z, leftPlane.m_flDist );
|
||||||
|
ALERT( at_console, "RightPlane: %f %f %f : %f\n", rightPlane.m_vecNormal.x, rightPlane.m_vecNormal.y, rightPlane.m_vecNormal.z, rightPlane.m_flDist );
|
||||||
|
ALERT( at_console, "BackPlane: %f %f %f : %f\n", backPlane.m_vecNormal.x, backPlane.m_vecNormal.y, backPlane.m_vecNormal.z, backPlane.m_flDist );
|
||||||
|
*/
|
||||||
|
for( int k = 1; k <= gpGlobals->maxClients; k++ )
|
||||||
|
{
|
||||||
|
CBaseEntity* pPlayer = UTIL_PlayerByIndex(k);
|
||||||
|
if (pPlayer && pPlayer->IsPlayer() && IRelationship(pPlayer) == R_AL && pPlayer->IsAlive())
|
||||||
|
{
|
||||||
|
if( backPlane.PointInFront( pPlayer->pev->origin ) &&
|
||||||
|
leftPlane.PointInFront( pPlayer->pev->origin ) &&
|
||||||
|
rightPlane.PointInFront( pPlayer->pev->origin ) )
|
||||||
|
{
|
||||||
|
ALERT(at_aiconsole, "%s: Ally player at fire plane!\n", STRING(pev->classname));
|
||||||
|
// player is in the check volume! Don't shoot!
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !InSquad() )
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
CSquadMonster *pSquadLeader = MySquadLeader();
|
||||||
|
for( int i = 0; i < MAX_SQUAD_MEMBERS; i++ )
|
||||||
|
{
|
||||||
|
CSquadMonster *pMember = pSquadLeader->MySquadMember( i );
|
||||||
|
if( pMember && pMember != this )
|
||||||
|
{
|
||||||
|
if( backPlane.PointInFront( pMember->pev->origin ) &&
|
||||||
|
leftPlane.PointInFront( pMember->pev->origin ) &&
|
||||||
|
rightPlane.PointInFront( pMember->pev->origin ) )
|
||||||
|
{
|
||||||
|
// this guy is in the check volume! Don't shoot!
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void CHFGrunt::DeclineFollowing( void )
|
void CHFGrunt::DeclineFollowing( void )
|
||||||
{
|
{
|
||||||
PlaySentence( "FG_POK", 2, VOL_NORM, ATTN_NORM );
|
PlaySentence( "FG_POK", 2, VOL_NORM, ATTN_NORM );
|
||||||
|
Loading…
x
Reference in New Issue
Block a user