int CHL2MP_Player::OnTakeDamage( const CTakeDamageInfo &inputInfo ) { #ifndef GE_DLL //return here if the player is in the respawn grace period vs. slams. if ( gpGlobals->curtime < m_flSlamProtectTime && (inputInfo.GetDamageType() == DMG_BLAST ) ) return 0; m_vecTotalBulletForce += inputInfo.GetDamageForce(); gamestats->Event_PlayerDamage( this, inputInfo ); #else CBaseEntity *attacker = inputInfo.GetAttacker(); Vector force = inputInfo.GetDamageForce(); if ( force == vec3_origin && attacker ) { Vector vecDir = vec3_origin; if ( inputInfo.GetInflictor() && GetMoveType() == MOVETYPE_WALK && !attacker->IsSolidFlagSet(FSOLID_TRIGGER) ) { vecDir = inputInfo.GetInflictor()->WorldSpaceCenter() - Vector ( 0, 0, 10 ) - WorldSpaceCenter(); VectorNormalize( vecDir ); force = vecDir * -DamageForce( WorldAlignSize(), inputInfo.GetBaseDamage() ); } } m_vecTotalBulletForce += force; #endif return BaseClass::OnTakeDamage( inputInfo ); }
int CZombie :: 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(); return CBaseMonster::TakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType ); }
// DeadTakeDamage - takedamage function called when a monster's corpse is damaged. int CBaseMonster::DeadTakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType) { // grab the vector of the incoming attack. ( pretend that the inflictor is a little lower than it really is, so the body will tend to fly upward a bit). Vector vecDir(0, 0, 0); if (!FNullEnt(pevInflictor)) { CBaseEntity *pInflictor = CBaseEntity::Instance(pevInflictor); if (pInflictor) { vecDir = (pInflictor->Center() - Vector(0, 0, 10) - Center()).Normalize(); vecDir = g_vecAttackDir = vecDir.Normalize(); } } // turn this back on when the bounding box issues are resolved. #if 0 pev->flags &= ~FL_ONGROUND; pev->origin.z += 1; // let the damage scoot the corpse around a bit. if (!FNullEnt(pevInflictor) && (pevAttacker->solid != SOLID_TRIGGER)) { pev->velocity = pev->velocity + vecDir * -DamageForce(flDamage); } #endif // kill the corpse if enough damage was done to destroy the corpse and the damage is of a type that is allowed to destroy the corpse. if (bitsDamageType & DMG_GIB_CORPSE) { if (pev->health <= flDamage) { pev->health = -50; Killed(pevAttacker, GIB_ALWAYS); return 0; } // Accumulate corpse gibbing damage, so you can gib with multiple hits pev->health -= flDamage * 0.1; } return 1; }
void CZombie::OnTakeDamage( const CTakeDamageInfo& info ) { CTakeDamageInfo newInfo = info; // Take 30% damage from bullets if ( newInfo.GetDamageTypes() == DMG_BULLET ) { Vector vecDir = GetAbsOrigin() - ( newInfo.GetInflictor()->pev->absmin + newInfo.GetInflictor()->pev->absmax) * 0.5; vecDir = vecDir.Normalize(); float flForce = DamageForce( newInfo.GetDamage() ); pev->velocity = pev->velocity + vecDir * flForce; newInfo.GetMutableDamage() *= 0.3; } // HACK HACK -- until we fix this. if ( IsAlive() ) PainSound(); CBaseMonster::OnTakeDamage( newInfo ); }
/* ============ TakeDamage The damage is coming from inflictor, but get mad at attacker This should be the only function that ever reduces health. bitsDamageType indicates the type of damage sustained, ie: DMG_SHOCK Time-based damage: only occurs while the monster is within the trigger_hurt. When a monster is poisoned via an arrow etc it takes all the poison damage at once. GLOBALS ASSUMED SET: g_iSkillLevel ============ */ int CBaseMonster :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) { float flTake; Vector vecDir; if (!pev->takedamage) return 0; if ( !IsAlive() ) { return DeadTakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType ); } if ( pev->deadflag == DEAD_NO ) { // no pain sound during death animation. PainSound();// "Ouch!" } //!!!LATER - make armor consideration here! flTake = flDamage; // set damage type sustained m_bitsDamageType |= bitsDamageType; // grab the vector of the incoming attack. ( pretend that the inflictor is a little lower than it really is, so the body will tend to fly upward a bit). vecDir = Vector( 0, 0, 0 ); if (!FNullEnt( pevInflictor )) { CBaseEntity *pInflictor = CBaseEntity :: Instance( pevInflictor ); if (pInflictor) { vecDir = ( pInflictor->Center() - Vector ( 0, 0, 10 ) - Center() ).Normalize(); vecDir = g_vecAttackDir = vecDir.Normalize(); } } // add to the damage total for clients, which will be sent as a single // message at the end of the frame // todo: remove after combining shotgun blasts? if ( IsPlayer() ) { if ( pevInflictor ) pev->dmg_inflictor = ENT(pevInflictor); pev->dmg_take += flTake; // check for godmode or invincibility if ( pev->flags & FL_GODMODE ) { return 0; } } // if this is a player, move him around! if ( ( !FNullEnt( pevInflictor ) ) && (pev->movetype == MOVETYPE_WALK) && (!pevAttacker || pevAttacker->solid != SOLID_TRIGGER) ) { pev->velocity = pev->velocity + vecDir * -DamageForce( flDamage ); } // do the damage pev->health -= flTake; // HACKHACK Don't kill monsters in a script. Let them break their scripts first if ( m_MonsterState == MONSTERSTATE_SCRIPT ) { SetConditions( bits_COND_LIGHT_DAMAGE ); return 0; } if ( pev->health <= 0 ) { g_pevLastInflictor = pevInflictor; if ( bitsDamageType & DMG_ALWAYSGIB ) { Killed( pevAttacker, GIB_ALWAYS ); } else if ( bitsDamageType & DMG_NEVERGIB ) { Killed( pevAttacker, GIB_NEVER ); } else { Killed( pevAttacker, GIB_NORMAL ); } g_pevLastInflictor = NULL; return 0; } // react to the damage (get mad) if ( (pev->flags & FL_MONSTER) && !FNullEnt(pevAttacker) ) { if ( pevAttacker->flags & (FL_MONSTER | FL_CLIENT) ) {// only if the attack was a monster or client! // enemy's last known position is somewhere down the vector that the attack came from. if (pevInflictor) { if (m_hEnemy == NULL || pevInflictor == m_hEnemy->pev || !HasConditions(bits_COND_SEE_ENEMY)) { m_vecEnemyLKP = pevInflictor->origin; } } else { m_vecEnemyLKP = pev->origin + ( g_vecAttackDir * 64 ); } MakeIdealYaw( m_vecEnemyLKP ); // add pain to the conditions // !!!HACKHACK - fudged for now. Do we want to have a virtual function to determine what is light and // heavy damage per monster class? if ( flDamage > 0 ) { SetConditions(bits_COND_LIGHT_DAMAGE); } if ( flDamage >= 20 ) { SetConditions(bits_COND_HEAVY_DAMAGE); } } } return 1; }