Fix male assassin unable to use weapons properly.
Remove zombie/gonome bullet resistance. Make it slighly harder to gib monsters. Small navigation fix. Fix compilation on Visual Studio 2015 and 2017. Fix "use_monstermod" keyvalue not working.
This commit is contained in:
@@ -1333,6 +1333,11 @@ public:
|
|||||||
void DeathSound(void);
|
void DeathSound(void);
|
||||||
void PainSound(void);
|
void PainSound(void);
|
||||||
void IdleSound(void);
|
void IdleSound(void);
|
||||||
|
|
||||||
|
void SetActivity(Activity NewActivity);
|
||||||
|
Schedule_t *GetScheduleOfType( int Type );
|
||||||
|
|
||||||
|
CUSTOM_SCHEDULES;
|
||||||
};
|
};
|
||||||
|
|
||||||
//=========================================================
|
//=========================================================
|
||||||
|
|||||||
@@ -831,7 +831,7 @@ int CMBaseMonster :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker
|
|||||||
{
|
{
|
||||||
float flTake;
|
float flTake;
|
||||||
Vector vecDir;
|
Vector vecDir;
|
||||||
|
|
||||||
if (!pev->takedamage)
|
if (!pev->takedamage)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ void check_monster_hurt(edict_t *pAttacker)
|
|||||||
pent->v.health = pent->v.fuser4;
|
pent->v.health = pent->v.fuser4;
|
||||||
|
|
||||||
ClearMultiDamage( );
|
ClearMultiDamage( );
|
||||||
monsters[index].pMonster->TraceAttack( VARS(pAttacker), damage, (tr.vecEndPos - vecSrc).Normalize( ), &tr, DMG_BULLET );
|
monsters[index].pMonster->TraceAttack( VARS(pAttacker), damage, (tr.vecEndPos - vecSrc).Normalize( ), &tr, DMG_BULLET|DMG_NEVERGIB );
|
||||||
ApplyMultiDamage( VARS(pAttacker), VARS(pAttacker) );
|
ApplyMultiDamage( VARS(pAttacker), VARS(pAttacker) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -351,16 +351,6 @@ int CMGonome::Classify(void)
|
|||||||
//=========================================================
|
//=========================================================
|
||||||
int CMGonome::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType)
|
int CMGonome::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType)
|
||||||
{
|
{
|
||||||
// Take 15% damage from bullets
|
|
||||||
if( bitsDamageType == DMG_BULLET )
|
|
||||||
{
|
|
||||||
Vector vecDir = pev->origin - (pevInflictor->absmin + pevInflictor->absmax) * 0.5;
|
|
||||||
vecDir = vecDir.Normalize();
|
|
||||||
float flForce = DamageForce( flDamage );
|
|
||||||
pev->velocity = pev->velocity + vecDir * flForce;
|
|
||||||
flDamage *= 0.15;
|
|
||||||
}
|
|
||||||
|
|
||||||
// HACK HACK -- until we fix this.
|
// HACK HACK -- until we fix this.
|
||||||
if( IsAlive() )
|
if( IsAlive() )
|
||||||
PainSound();
|
PainSound();
|
||||||
|
|||||||
@@ -61,6 +61,8 @@
|
|||||||
//=========================================================
|
//=========================================================
|
||||||
#define MASSN_AE_KICK ( 3 )
|
#define MASSN_AE_KICK ( 3 )
|
||||||
#define MASSN_AE_BURST1 ( 4 )
|
#define MASSN_AE_BURST1 ( 4 )
|
||||||
|
#define MASSN_AE_BURST2 ( 5 )
|
||||||
|
#define MASSN_AE_BURST3 ( 6 )
|
||||||
#define MASSN_AE_CAUGHT_ENEMY ( 10 ) // grunt established sight with an enemy (player only) that had previously eluded the squad.
|
#define MASSN_AE_CAUGHT_ENEMY ( 10 ) // grunt established sight with an enemy (player only) that had previously eluded the squad.
|
||||||
#define MASSN_AE_DROP_GUN ( 11 ) // grunt (probably dead) is dropping his mp5.
|
#define MASSN_AE_DROP_GUN ( 11 ) // grunt (probably dead) is dropping his mp5.
|
||||||
|
|
||||||
@@ -176,6 +178,11 @@ void CMMassn::HandleAnimEvent(MonsterEvent_t *pEvent)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MASSN_AE_BURST2:
|
||||||
|
case MASSN_AE_BURST3:
|
||||||
|
Shoot();
|
||||||
|
break;
|
||||||
|
|
||||||
case MASSN_AE_KICK:
|
case MASSN_AE_KICK:
|
||||||
{
|
{
|
||||||
edict_t *pHurt = Kick();
|
edict_t *pHurt = Kick();
|
||||||
@@ -193,6 +200,8 @@ void CMMassn::HandleAnimEvent(MonsterEvent_t *pEvent)
|
|||||||
CMBaseMonster *pMonster = GetClassPtr((CMBaseMonster *)VARS(pHurt));
|
CMBaseMonster *pMonster = GetClassPtr((CMBaseMonster *)VARS(pHurt));
|
||||||
pMonster->TakeDamage( pev, pev, gSkillData.massnDmgKick, DMG_CLUB );
|
pMonster->TakeDamage( pev, pev, gSkillData.massnDmgKick, DMG_CLUB );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
UTIL_TakeDamageExternal( pHurt, pev, pev, gSkillData.massnDmgKick, DMG_CLUB );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -307,3 +316,116 @@ void CMMassn::Precache()
|
|||||||
|
|
||||||
m_iBrassShell = PRECACHE_MODEL("models/shell.mdl");// brass shell
|
m_iBrassShell = PRECACHE_MODEL("models/shell.mdl");// brass shell
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
// Chase enemy failure schedule
|
||||||
|
//=========================================================
|
||||||
|
Task_t tlMassnSniperAttack[] =
|
||||||
|
{
|
||||||
|
{ TASK_STOP_MOVING, (float)0 },
|
||||||
|
{ TASK_SET_ACTIVITY, (float)ACT_IDLE_ANGRY },
|
||||||
|
{ TASK_WAIT_FACE_ENEMY , (float)1 },
|
||||||
|
{ TASK_SET_ACTIVITY, (float)ACT_RANGE_ATTACK1 },
|
||||||
|
{ TASK_WAIT_FACE_ENEMY, (float)1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
Schedule_t slMassnSniperAttack[] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
tlMassnSniperAttack,
|
||||||
|
ARRAYSIZE ( tlMassnSniperAttack ),
|
||||||
|
bits_COND_HEAR_SOUND,
|
||||||
|
0,
|
||||||
|
"MassnSniperAttack"
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_CUSTOM_SCHEDULES( CMMassn )
|
||||||
|
{
|
||||||
|
slMassnSniperAttack,
|
||||||
|
};
|
||||||
|
|
||||||
|
IMPLEMENT_CUSTOM_SCHEDULES( CMMassn, CMBaseMonster );
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
// SetActivity
|
||||||
|
//=========================================================
|
||||||
|
void CMMassn :: SetActivity ( Activity NewActivity )
|
||||||
|
{
|
||||||
|
int iSequence = ACTIVITY_NOT_AVAILABLE;
|
||||||
|
void *pmodel = GET_MODEL_PTR( ENT(pev) );
|
||||||
|
|
||||||
|
switch ( NewActivity )
|
||||||
|
{
|
||||||
|
case ACT_RANGE_ATTACK1:
|
||||||
|
// shooting standing or shooting crouched
|
||||||
|
if (FBitSet( pev->weapons, MASSN_SNIPERRIFLE))
|
||||||
|
{
|
||||||
|
// Always standing
|
||||||
|
iSequence = LookupSequence( "standing_m40a1" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( m_fStanding )
|
||||||
|
{
|
||||||
|
// get aimable sequence
|
||||||
|
iSequence = LookupSequence( "standing_mp5" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// get crouching shoot
|
||||||
|
iSequence = LookupSequence( "crouching_mp5" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CMHGrunt::SetActivity(NewActivity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Activity = NewActivity; // Go ahead and set this so it doesn't keep trying when the anim is not present
|
||||||
|
|
||||||
|
// Set to the desired anim, or default anim if the desired is not present
|
||||||
|
if ( iSequence > ACTIVITY_NOT_AVAILABLE )
|
||||||
|
{
|
||||||
|
if ( pev->sequence != iSequence || !m_fSequenceLoops )
|
||||||
|
{
|
||||||
|
pev->frame = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pev->sequence = iSequence; // Set to the reset anim (if it's there)
|
||||||
|
ResetSequenceInfo( );
|
||||||
|
SetYawSpeed();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Not available try to get default anim
|
||||||
|
ALERT ( at_console, "%s has no sequence for act:%d\n", STRING(pev->classname), NewActivity );
|
||||||
|
pev->sequence = 0; // Set to the reset anim (if it's there)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
// GetScheduleOfType - Override schedule for sniper attack
|
||||||
|
//=========================================================
|
||||||
|
Schedule_t* CMMassn :: GetScheduleOfType ( int Type )
|
||||||
|
{
|
||||||
|
switch ( Type )
|
||||||
|
{
|
||||||
|
case SCHED_RANGE_ATTACK1:
|
||||||
|
{
|
||||||
|
if (FBitSet(pev->weapons, MASSN_SNIPERRIFLE))
|
||||||
|
{
|
||||||
|
// sniper attack is always standing
|
||||||
|
m_fStanding = TRUE;
|
||||||
|
return &slMassnSniperAttack[ 0 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return CMHGrunt :: GetScheduleOfType ( Type );
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return CMHGrunt :: GetScheduleOfType ( Type );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -411,7 +411,7 @@ void scan_monster_bsp(void)
|
|||||||
pKVD data[MAX_KEYVALUES];
|
pKVD data[MAX_KEYVALUES];
|
||||||
|
|
||||||
int kvd_index;
|
int kvd_index;
|
||||||
int duplicate_ent;
|
bool use_monstermod_explicit;
|
||||||
bool use_monstermod;
|
bool use_monstermod;
|
||||||
|
|
||||||
int classname_kvdI, mIndex;
|
int classname_kvdI, mIndex;
|
||||||
@@ -424,7 +424,7 @@ void scan_monster_bsp(void)
|
|||||||
kv_pair = entities[ent].epairs;
|
kv_pair = entities[ent].epairs;
|
||||||
|
|
||||||
kvd_index = 0;
|
kvd_index = 0;
|
||||||
duplicate_ent = 0;
|
use_monstermod_explicit = false;
|
||||||
use_monstermod = true;
|
use_monstermod = true;
|
||||||
|
|
||||||
classname_kvdI = 0;
|
classname_kvdI = 0;
|
||||||
@@ -438,6 +438,7 @@ void scan_monster_bsp(void)
|
|||||||
{
|
{
|
||||||
LOG_MESSAGE(PLID, "WARNING: can't process entity #%i - too many keyvalues", ent);
|
LOG_MESSAGE(PLID, "WARNING: can't process entity #%i - too many keyvalues", ent);
|
||||||
use_monstermod = false;
|
use_monstermod = false;
|
||||||
|
use_monstermod_explicit = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,32 +451,21 @@ void scan_monster_bsp(void)
|
|||||||
edict_t *existsGAME = CREATE_NAMED_ENTITY( MAKE_STRING( kv_pair->value ) );
|
edict_t *existsGAME = CREATE_NAMED_ENTITY( MAKE_STRING( kv_pair->value ) );
|
||||||
if ( !FNullEnt( existsGAME ) )
|
if ( !FNullEnt( existsGAME ) )
|
||||||
{
|
{
|
||||||
for (mIndex = 0; monster_types[mIndex].name[0]; mIndex++)
|
|
||||||
{
|
|
||||||
if (strcmp(kv_pair->value, monster_types[mIndex].name) == 0)
|
|
||||||
{
|
|
||||||
// the entity exists BOTH in the game and monstermod!
|
|
||||||
// keep track of it
|
|
||||||
duplicate_ent = ent;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// use REMOVE_ENTITY instead of UTIL_Remove!
|
// use REMOVE_ENTITY instead of UTIL_Remove!
|
||||||
// UTIL_Remove sets FL_KILLME to remove the entity on the next frame, that won't do.
|
// UTIL_Remove sets FL_KILLME to remove the entity on the next frame, that won't do.
|
||||||
// REMOVE_ENTITY instead removes it instantly, which is needed to prevent server crashes
|
// REMOVE_ENTITY instead removes it instantly, which is needed to prevent server crashes
|
||||||
// due to "ED_Alloc: no free edicts" error.
|
// due to "ED_Alloc: no free edicts" error.
|
||||||
|
|
||||||
REMOVE_ENTITY( existsGAME ); // get rid of the temporary entity
|
REMOVE_ENTITY( existsGAME ); // get rid of the temporary entity
|
||||||
use_monstermod = false; // use game entity
|
use_monstermod = false; // stick with game entity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (duplicate_ent && strcmp(kv_pair->key, "use_monstermod") == 0)
|
else if (strcmp(kv_pair->key, "use_monstermod") == 0)
|
||||||
{
|
{
|
||||||
if (atoi(kv_pair->value) == 1)
|
if (atoi(kv_pair->value) == 1)
|
||||||
{
|
{
|
||||||
// EXPLICITY requested to use the monstermod entity
|
// EXPLICITY requested to use monstermod for this entity
|
||||||
use_monstermod = true;
|
use_monstermod_explicit = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -487,7 +477,7 @@ void scan_monster_bsp(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// spawn a monstermod entity?
|
// spawn a monstermod entity?
|
||||||
if (use_monstermod)
|
if (use_monstermod_explicit || use_monstermod)
|
||||||
{
|
{
|
||||||
// find classname keyvalue
|
// find classname keyvalue
|
||||||
for (int i = 0; i < kvd_index; i++)
|
for (int i = 0; i < kvd_index; i++)
|
||||||
|
|||||||
@@ -1554,7 +1554,7 @@ void CMBaseMonster :: Move ( float flInterval )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//jlb TaskFail();
|
TaskFail();
|
||||||
ALERT( at_aiconsole, "%s Failed to move (%d)!\n", STRING(pev->classname), HasMemory( bits_MEMORY_MOVE_FAILED ) );
|
ALERT( at_aiconsole, "%s Failed to move (%d)!\n", STRING(pev->classname), HasMemory( bits_MEMORY_MOVE_FAILED ) );
|
||||||
//ALERT( at_aiconsole, "%f, %f, %f\n", pev->origin.z, (pev->origin + (vecDir * flCheckDist)).z, m_Route[m_iRouteIndex].vecLocation.z );
|
//ALERT( at_aiconsole, "%f, %f, %f\n", pev->origin.z, (pev->origin + (vecDir * flCheckDist)).z, m_Route[m_iRouteIndex].vecLocation.z );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,16 +111,6 @@ void CMZombie :: SetYawSpeed ( void )
|
|||||||
|
|
||||||
int CMZombie :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType )
|
int CMZombie :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType )
|
||||||
{
|
{
|
||||||
// Take 30% damage from bullets
|
|
||||||
if ( bitsDamageType == DMG_BULLET )
|
|
||||||
{
|
|
||||||
Vector vecDir = pev->origin - (pevInflictor->absmin + pevInflictor->absmax) * 0.5;
|
|
||||||
vecDir = vecDir.Normalize();
|
|
||||||
float flForce = DamageForce( flDamage );
|
|
||||||
pev->velocity = pev->velocity + vecDir * flForce;
|
|
||||||
flDamage *= 0.3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// HACK HACK -- until we fix this.
|
// HACK HACK -- until we fix this.
|
||||||
if ( IsAlive() )
|
if ( IsAlive() )
|
||||||
PainSound();
|
PainSound();
|
||||||
|
|||||||
@@ -74,14 +74,17 @@
|
|||||||
#endif //defined WIN32
|
#endif //defined WIN32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (_WIN32) && defined (_MSC_VER)
|
// VS2015 and newer already has va_copy defined
|
||||||
|
#if defined (_WIN32) && defined (_MSC_VER) && _MSC_VER < 1900
|
||||||
// On x86 va_list is just a pointer.
|
// On x86 va_list is just a pointer.
|
||||||
#define va_copy(dst,src) ((dst)=(src))
|
#define va_copy(dst,src) ((dst)=(src))
|
||||||
#else
|
#else
|
||||||
// Some systems that do not supply va_copy have __va_copy instead, since
|
#if (linux)
|
||||||
// that was the name used in the draft proposal.
|
// Some systems that do not supply va_copy have __va_copy instead, since
|
||||||
#if !defined(__GNUC__) || __GNUC__ < 3
|
// that was the name used in the draft proposal.
|
||||||
#define va_copy __va_copy
|
#if !defined(__GNUC__) || __GNUC__ < 3
|
||||||
|
#define va_copy __va_copy
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user