diff --git a/src/dlls/cmbasemonster.h b/src/dlls/cmbasemonster.h index 26439b1..270c13e 100644 --- a/src/dlls/cmbasemonster.h +++ b/src/dlls/cmbasemonster.h @@ -1333,6 +1333,11 @@ public: void DeathSound(void); void PainSound(void); void IdleSound(void); + + void SetActivity(Activity NewActivity); + Schedule_t *GetScheduleOfType( int Type ); + + CUSTOM_SCHEDULES; }; //========================================================= diff --git a/src/dlls/combat.cpp b/src/dlls/combat.cpp index 0c6080e..ecb3e57 100644 --- a/src/dlls/combat.cpp +++ b/src/dlls/combat.cpp @@ -831,7 +831,7 @@ int CMBaseMonster :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker { float flTake; Vector vecDir; - + if (!pev->takedamage) return 0; diff --git a/src/dlls/dllapi.cpp b/src/dlls/dllapi.cpp index 9c3d251..fbf0fea 100644 --- a/src/dlls/dllapi.cpp +++ b/src/dlls/dllapi.cpp @@ -306,7 +306,7 @@ void check_monster_hurt(edict_t *pAttacker) pent->v.health = pent->v.fuser4; 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) ); } diff --git a/src/dlls/gonome.cpp b/src/dlls/gonome.cpp index 87a306c..2a4b2be 100644 --- a/src/dlls/gonome.cpp +++ b/src/dlls/gonome.cpp @@ -351,16 +351,6 @@ int CMGonome::Classify(void) //========================================================= 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. if( IsAlive() ) PainSound(); diff --git a/src/dlls/massn.cpp b/src/dlls/massn.cpp index 1cc2b81..14e6d1d 100644 --- a/src/dlls/massn.cpp +++ b/src/dlls/massn.cpp @@ -61,6 +61,8 @@ //========================================================= #define MASSN_AE_KICK ( 3 ) #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_DROP_GUN ( 11 ) // grunt (probably dead) is dropping his mp5. @@ -176,6 +178,11 @@ void CMMassn::HandleAnimEvent(MonsterEvent_t *pEvent) } break; + case MASSN_AE_BURST2: + case MASSN_AE_BURST3: + Shoot(); + break; + case MASSN_AE_KICK: { edict_t *pHurt = Kick(); @@ -193,6 +200,8 @@ void CMMassn::HandleAnimEvent(MonsterEvent_t *pEvent) CMBaseMonster *pMonster = GetClassPtr((CMBaseMonster *)VARS(pHurt)); pMonster->TakeDamage( pev, pev, gSkillData.massnDmgKick, DMG_CLUB ); } + else + UTIL_TakeDamageExternal( pHurt, pev, pev, gSkillData.massnDmgKick, DMG_CLUB ); } } break; @@ -307,3 +316,116 @@ void CMMassn::Precache() 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 ); + } + } +} diff --git a/src/dlls/monster_config.cpp b/src/dlls/monster_config.cpp index 2e520e1..c4e77b1 100644 --- a/src/dlls/monster_config.cpp +++ b/src/dlls/monster_config.cpp @@ -411,7 +411,7 @@ void scan_monster_bsp(void) pKVD data[MAX_KEYVALUES]; int kvd_index; - int duplicate_ent; + bool use_monstermod_explicit; bool use_monstermod; int classname_kvdI, mIndex; @@ -424,7 +424,7 @@ void scan_monster_bsp(void) kv_pair = entities[ent].epairs; kvd_index = 0; - duplicate_ent = 0; + use_monstermod_explicit = false; use_monstermod = true; 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); use_monstermod = false; + use_monstermod_explicit = false; break; } @@ -450,32 +451,21 @@ void scan_monster_bsp(void) edict_t *existsGAME = CREATE_NAMED_ENTITY( MAKE_STRING( kv_pair->value ) ); 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! // 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 // due to "ED_Alloc: no free edicts" error. 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) { - // EXPLICITY requested to use the monstermod entity - use_monstermod = true; + // EXPLICITY requested to use monstermod for this entity + use_monstermod_explicit = true; } } @@ -487,7 +477,7 @@ void scan_monster_bsp(void) } // spawn a monstermod entity? - if (use_monstermod) + if (use_monstermod_explicit || use_monstermod) { // find classname keyvalue for (int i = 0; i < kvd_index; i++) diff --git a/src/dlls/monsters.cpp b/src/dlls/monsters.cpp index e10ad0e..18a181e 100644 --- a/src/dlls/monsters.cpp +++ b/src/dlls/monsters.cpp @@ -1554,7 +1554,7 @@ void CMBaseMonster :: Move ( float flInterval ) } else { -//jlb TaskFail(); + TaskFail(); 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 ); } diff --git a/src/dlls/zombie.cpp b/src/dlls/zombie.cpp index 29c5910..6c1ca64 100644 --- a/src/dlls/zombie.cpp +++ b/src/dlls/zombie.cpp @@ -111,16 +111,6 @@ void CMZombie :: SetYawSpeed ( void ) 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. if ( IsAlive() ) PainSound(); diff --git a/src/metamod/comp_dep.h b/src/metamod/comp_dep.h index 3d49de0..8f4cbd5 100644 --- a/src/metamod/comp_dep.h +++ b/src/metamod/comp_dep.h @@ -74,14 +74,17 @@ #endif //defined WIN32 #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. #define va_copy(dst,src) ((dst)=(src)) #else - // Some systems that do not supply va_copy have __va_copy instead, since - // that was the name used in the draft proposal. - #if !defined(__GNUC__) || __GNUC__ < 3 - #define va_copy __va_copy + #if (linux) + // Some systems that do not supply va_copy have __va_copy instead, since + // that was the name used in the draft proposal. + #if !defined(__GNUC__) || __GNUC__ < 3 + #define va_copy __va_copy + #endif #endif #endif