void CGameAchievements::OnEntityKilled(const HitInfo &hitInfo) { // target must be an AI IActor* pTarget = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(hitInfo.targetId); if(!pTarget || pTarget->IsPlayer()) return; // shooter might be null, if this is a collision, but will be checked otherwise IActor* pShooter = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(hitInfo.shooterId); switch(CategoriseHit(hitInfo.type)) { case eCHT_Bullet: { // ignore AI shots if(!pShooter || !pShooter->IsPlayer()) break; CProjectile* pProjectile = g_pGame->GetWeaponSystem()->GetProjectile(hitInfo.projectileId); assert(pProjectile); const CTimeValue& spawnTime = pProjectile ? pProjectile->GetSpawnTime() : 0.0f; if(spawnTime == 0.0f) break; if(hitInfo.projectileId == m_lastPlayerKillBulletId && spawnTime == m_lastPlayerKillBulletSpawnTime) { // same projectile as previously, trigger the 'two kills one bullet' objective GiveAchievement(eA_SPFeature_OneBulletTwoKills); } else { // save for later m_lastPlayerKillBulletId = hitInfo.projectileId; m_lastPlayerKillBulletSpawnTime = spawnTime; } } break; case eCHT_Grenade: { if(!pShooter || !pShooter->IsPlayer()) break; CProjectile* pGrenade = g_pGame->GetWeaponSystem()->GetProjectile(hitInfo.projectileId); const CTimeValue& spawnTime = pGrenade ? pGrenade->GetSpawnTime() : 0.0f; if(spawnTime == 0.0f) break; if(hitInfo.projectileId == m_lastPlayerKillGrenadeId && spawnTime == m_lastPlayerKillGrenadeSpawnTime) { if(++m_killsWithOneGrenade == 3) { GiveAchievement(eA_SPFeature_OneGrenadeThreeKills); } } else { // save for later m_lastPlayerKillGrenadeId = hitInfo.projectileId; m_lastPlayerKillGrenadeSpawnTime = spawnTime; m_killsWithOneGrenade = 1; } } break; case eCHT_Collision: { CTimeValue now = gEnv->pTimer->GetFrameStartTime(); if(hitInfo.weaponId != 0 && hitInfo.weaponId == m_lastPlayerThrownObject && (now-m_lastPlayerThrownTime) < THROW_TIME_THRESHOLD) { // AI was killed by an object the player threw in the last x seconds... g_pGame->GetPersistantStats()->IncrementClientStats(EIPS_ThrownObjectKill, 1); } } break; default: break; } }