Modified source engine (2017) developed by valve and leaked in 2020. Not for commercial purporses
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

208 lines
5.8 KiB

//========= Copyright Valve Corporation, All rights reserved. ============//
// boss_alpha_nuke_attack.cpp
// Michael Booth, November 2010
#include "cbase.h"
#ifdef TF_RAID_MODE
#include "tf_player.h"
#include "tf_team.h"
#include "player_vs_environment/monster_resource.h"
#include "player_vs_environment/boss_alpha/boss_alpha.h"
#include "player_vs_environment/boss_alpha/behavior/boss_alpha_nuke_attack.h"
#include "player_vs_environment/boss_alpha/behavior/boss_alpha_stunned.h"
ConVar tf_boss_alpha_nuke_charge_time( "tf_boss_alpha_nuke_charge_time", "5" );
ConVar tf_boss_alpha_nuke_interval( "tf_boss_alpha_nuke_interval", "20" );
ConVar tf_boss_alpha_nuke_lethal_time( "tf_boss_alpha_nuke_lethal_time", "999999999" ); // 300
ConVar tf_boss_alpha_nuke_damage( "tf_boss_alpha_nuke_damage", "75"/*, FCVAR_CHEAT*/ );
ConVar tf_boss_alpha_nuke_max_remaining_health( "tf_boss_alpha_nuke_max_remaining_health", "60"/*, FCVAR_CHEAT*/ );
ConVar tf_boss_alpha_nuke_afterburn_time( "tf_boss_alpha_nuke_afterburn_time", "5"/*, FCVAR_CHEAT*/ );
extern ConVar tf_boss_alpha_stunned_duration;
//---------------------------------------------------------------------------------------------
ActionResult< CBossAlpha > CBossAlphaNukeAttack::OnStart( CBossAlpha *me, Action< CBossAlpha > *priorAction )
{
me->GetBodyInterface()->StartActivity( ACT_MP_JUMP_FLOAT_LOSERSTATE );
me->StartNukeEffect();
me->EmitSound( "RobotBoss.ChargeUpNukeAttack" );
// me->AddCondition( CBossAlpha::VULNERABLE_TO_STUN );
m_chargeUpTimer.Start( tf_boss_alpha_nuke_charge_time.GetFloat() );
m_shakeTimer.Start( 0.25f );
return Continue();
}
//---------------------------------------------------------------------------------------------
ActionResult< CBossAlpha > CBossAlphaNukeAttack::Update( CBossAlpha *me, float interval )
{
float stunRatio = me->GetStunDamage() / me->GetBecomeStunnedDamage();
if ( me->HasAbility( CBossAlpha::CAN_BE_STUNNED ) && stunRatio >= 1.0f )
{
return ChangeTo( new CBossAlphaStunned( tf_boss_alpha_stunned_duration.GetFloat() ), "They got me" );
}
// update the client's HUD
if ( g_pMonsterResource )
{
g_pMonsterResource->SetBossStunPercentage( 1.0f - stunRatio );
}
if ( m_shakeTimer.IsElapsed() )
{
m_shakeTimer.Reset();
UTIL_ScreenShake( me->GetAbsOrigin(), 15.0f, 5.0f, 1.0f, 3000.0f, SHAKE_START );
}
if ( m_chargeUpTimer.IsElapsed() )
{
// BLAST!
CUtlVector< CTFPlayer * > playerVector;
CollectPlayers( &playerVector, TF_TEAM_RED, COLLECT_ONLY_LIVING_PLAYERS );
CollectPlayers( &playerVector, TF_TEAM_BLUE, COLLECT_ONLY_LIVING_PLAYERS, APPEND_PLAYERS );
me->EmitSound( "RobotBoss.NukeAttack" );
CUtlVector< CBaseCombatCharacter * > victimVector;
int i;
// players
for ( i=0; i<playerVector.Count(); ++i )
{
CBasePlayer *player = playerVector[i];
if ( player && player->IsAlive() && player->GetTeamNumber() == TF_TEAM_BLUE )
{
victimVector.AddToTail( player );
}
}
// objects
CTFTeam *team = GetGlobalTFTeam( TF_TEAM_BLUE );
if ( team )
{
for ( i=0; i<team->GetNumObjects(); ++i )
{
CBaseObject *object = team->GetObject( i );
if ( object )
{
victimVector.AddToTail( object );
}
}
}
#ifdef SKIPME
team = GetGlobalTFTeam( TF_TEAM_RED );
if ( team )
{
for ( i=0; i<team->GetNumObjects(); ++i )
{
CBaseObject *object = team->GetObject( i );
if ( object )
{
victimVector.AddToTail( object );
}
}
}
// non-player bots
CUtlVector< INextBot * > botVector;
TheNextBots().CollectAllBots( &botVector );
for( i=0; i<botVector.Count(); ++i )
{
CBaseCombatCharacter *bot = botVector[i]->GetEntity();
if ( !bot->IsPlayer() && bot->IsAlive() )
{
victimVector.AddToTail( bot );
}
}
#endif // SKIPME
for( int i=0; i<victimVector.Count(); ++i )
{
CBaseCombatCharacter *victim = victimVector[i];
if ( me->IsSelf( victim ) )
continue;
if ( me->IsLineOfSightClear( victim ) )
{
Vector toVictim = victim->WorldSpaceCenter() - me->WorldSpaceCenter();
toVictim.NormalizeInPlace();
float damage = tf_boss_alpha_nuke_damage.GetFloat();
if ( me->GetAge() > tf_boss_alpha_nuke_lethal_time.GetFloat() )
{
// nuke is now lethal
damage = 999.9f;
}
else if ( tf_boss_alpha_nuke_max_remaining_health.GetFloat() >= 0.0f )
{
// nuke slams everyone's health to this
if ( victim->GetHealth() > tf_boss_alpha_nuke_max_remaining_health.GetFloat() )
{
damage = victim->GetHealth() - tf_boss_alpha_nuke_max_remaining_health.GetFloat();
}
}
CTakeDamageInfo info( me, me, damage, DMG_ENERGYBEAM, TF_DMG_CUSTOM_NONE );
CalculateMeleeDamageForce( &info, toVictim, me->WorldSpaceCenter(), 1.0f );
victim->TakeDamage( info );
if ( victim->IsPlayer() )
{
CTFPlayer *playerVictim = ToTFPlayer( victim );
// catch them on fire (unless they are a Pyro)
if ( !playerVictim->IsPlayerClass( TF_CLASS_PYRO ) )
{
playerVictim->m_Shared.Burn( me, tf_boss_alpha_nuke_afterburn_time.GetFloat() );
}
color32 colorHit = { 255, 255, 255, 255 };
UTIL_ScreenFade( victim, colorHit, 1.0f, 0.1f, FFADE_IN );
}
}
}
return Done();
}
return Continue();
}
//---------------------------------------------------------------------------------------------
void CBossAlphaNukeAttack::OnEnd( CBossAlpha *me, Action< CBossAlpha > *nextAction )
{
me->RemoveCondition( CBossAlpha::VULNERABLE_TO_STUN );
me->StopNukeEffect();
me->ClearStunDamage();
me->GetNukeTimer()->Start( tf_boss_alpha_nuke_interval.GetFloat() );
if ( g_pMonsterResource )
{
g_pMonsterResource->HideBossStunMeter();
}
}
//---------------------------------------------------------------------------------------------
EventDesiredResult< CBossAlpha > CBossAlphaNukeAttack::OnInjured( CBossAlpha *me, const CTakeDamageInfo &info )
{
return TryToSustain( RESULT_CRITICAL );
}
#endif // TF_RAID_MODE