//----------------------------------------------------------------------------- // Purpose: This is a generic function (to be implemented by sub-classes) to // handle specific interactions between different types of characters // (For example the barnacle grabbing an NPC) // Input : Constant for the type of interaction // Output : true - if sub-class has a response for the interaction // false - if sub-class has no response //----------------------------------------------------------------------------- bool CHL1_Player::HandleInteraction(int interactionType, void *data, CBaseCombatCharacter* sourceEnt) { if ( interactionType == g_interactionBarnacleVictimDangle ) { TakeDamage ( CTakeDamageInfo( sourceEnt, sourceEnt, m_iHealth + ArmorValue(), DMG_SLASH | DMG_ALWAYSGIB ) ); return true; } if (interactionType == g_interactionBarnacleVictimReleased) { m_afPhysicsFlags &= ~PFLAG_ONBARNACLE; SetMoveType( MOVETYPE_WALK ); return true; } else if (interactionType == g_interactionBarnacleVictimGrab) { m_afPhysicsFlags |= PFLAG_ONBARNACLE; ClearUseEntity(); return true; } return false; }
int CSDKPlayer::OnTakeDamage_Alive( const CTakeDamageInfo &info ) { // set damage type sustained m_bitsDamageType |= info.GetDamageType(); if ( !CBaseCombatCharacter::OnTakeDamage_Alive( info ) ) return 0; // fire global game event IGameEvent * event = gameeventmanager->CreateEvent( "player_hurt" ); if ( event ) { event->SetInt("userid", GetUserID() ); event->SetInt("health", max(0, m_iHealth) ); event->SetInt("armor", max(0, ArmorValue()) ); if ( info.GetDamageType() & DMG_BLAST ) { event->SetInt( "hitgroup", HITGROUP_GENERIC ); } else { event->SetInt( "hitgroup", LastHitGroup() ); } CBaseEntity * attacker = info.GetAttacker(); const char *weaponName = ""; if ( attacker->IsPlayer() ) { CBasePlayer *player = ToBasePlayer( attacker ); event->SetInt("attacker", player->GetUserID() ); // hurt by other player CBaseEntity *pInflictor = info.GetInflictor(); if ( pInflictor ) { if ( pInflictor == player ) { // If the inflictor is the killer, then it must be their current weapon doing the damage if ( player->GetActiveWeapon() ) { weaponName = player->GetActiveWeapon()->GetClassname(); } } else { weaponName = STRING( pInflictor->m_iClassname ); // it's just that easy } } } else { event->SetInt("attacker", 0 ); // hurt by "world" } if ( strncmp( weaponName, "weapon_", 7 ) == 0 ) { weaponName += 7; } else if( strncmp( weaponName, "grenade", 9 ) == 0 ) //"grenade_projectile" { weaponName = "grenade"; } event->SetString( "weapon", weaponName ); event->SetInt( "priority", 5 ); gameeventmanager->FireEvent( event ); } return 1; }
int CSDKPlayer::OnTakeDamage( const CTakeDamageInfo &inputInfo ) { CTakeDamageInfo info = inputInfo; CBaseEntity *pInflictor = info.GetInflictor(); if ( !pInflictor ) return 0; if ( GetMoveType() == MOVETYPE_NOCLIP || GetMoveType() == MOVETYPE_OBSERVER ) return 0; float flArmorBonus = 0.5f; float flArmorRatio = 0.5f; float flDamage = info.GetDamage(); bool bCheckFriendlyFire = false; bool bFriendlyFire = friendlyfire.GetBool(); //Tony; only check teams in teamplay if ( gpGlobals->teamplay ) bCheckFriendlyFire = true; if ( bFriendlyFire || ( bCheckFriendlyFire && pInflictor->GetTeamNumber() != GetTeamNumber() ) || pInflictor == this || info.GetAttacker() == this ) { if ( bFriendlyFire && (info.GetDamageType() & DMG_BLAST) == 0 ) { if ( pInflictor->GetTeamNumber() == GetTeamNumber() && bCheckFriendlyFire) { flDamage *= 0.35; // bullets hurt teammates less } } // keep track of amount of damage last sustained m_lastDamageAmount = flDamage; // Deal with Armour if ( ArmorValue() && !( info.GetDamageType() & (DMG_FALL | DMG_DROWN)) ) { float flNew = flDamage * flArmorRatio; float flArmor = (flDamage - flNew) * flArmorBonus; // Does this use more armor than we have? if (flArmor > ArmorValue() ) { //armorHit = (int)(flArmor); flArmor = ArmorValue(); flArmor *= (1/flArmorBonus); flNew = flDamage - flArmor; SetArmorValue( 0 ); } else { int oldValue = (int)(ArmorValue()); if ( flArmor < 0 ) flArmor = 1; SetArmorValue( oldValue - flArmor ); //armorHit = oldValue - (int)(pev->armorvalue); } flDamage = flNew; info.SetDamage( flDamage ); } // round damage to integer info.SetDamage( (int)flDamage ); if ( info.GetDamage() <= 0 ) return 0; CSingleUserRecipientFilter user( this ); user.MakeReliable(); UserMessageBegin( user, "Damage" ); WRITE_BYTE( (int)info.GetDamage() ); WRITE_VEC3COORD( info.GetInflictor()->WorldSpaceCenter() ); MessageEnd(); // Do special explosion damage effect if ( info.GetDamageType() & DMG_BLAST ) { OnDamagedByExplosion( info ); } gamestats->Event_PlayerDamage( this, info ); return CBaseCombatCharacter::OnTakeDamage( info ); } else { return 0; } }