v12
This commit is contained in:
parent
1d38da55e4
commit
e165a8b786
|
@ -4793,8 +4793,8 @@
|
|||
0 : "No"
|
||||
1 : "Yes"
|
||||
]
|
||||
MinSkillLevel(integer) : "Min Skill Level" : 0 : "The minimum skill level for this spawner to function. Skill levels are: 1=easy 2=normal 3=hard 4=insane"
|
||||
MaxSkillLevel(integer) : "Max Skill Level" : 0 : "The maximum skill level for this spawner to function. Skill levels are: 1=easy 2=normal 3=hard 4=insane"
|
||||
MinSkillLevel(integer) : "Min Skill Level" : 0 : "The minimum skill level for this spawner to function. Skill levels are: 1=easy 2=normal 3=hard 4=insane 5=imba"
|
||||
MaxSkillLevel(integer) : "Max Skill Level" : 0 : "The maximum skill level for this spawner to function. Skill levels are: 1=easy 2=normal 3=hard 4=insane 5=imba"
|
||||
|
||||
output OnSpawned(string) : "Fires when an alien is spawned. The activator is the alien, and the string is the name of the alien."
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <vgui/ILocalize.h>
|
||||
#include "asw_shareddefs.h"
|
||||
#include "c_asw_marine_resource.h"
|
||||
#include "c_asw_campaign_save.h"
|
||||
|
||||
CASW_Steamstats g_ASW_Steamstats;
|
||||
|
||||
|
@ -39,15 +40,56 @@ namespace
|
|||
const char* szShotsTotal = ".shotsfired.total";
|
||||
const char* szShotsHit = ".shotshit.total";
|
||||
const char* szHealingTotal = ".healing.total";
|
||||
const char* szTimeTotal = ".time.total";
|
||||
const char* szKillsAvg = ".kills.avg";
|
||||
const char* szDamageAvg = ".damage.avg";
|
||||
const char* szFFAvg = ".ff.avg";
|
||||
const char* szTimeAvg = ".time.avg";
|
||||
const char* szBestDifficulty = ".difficulty.best";
|
||||
const char* szBestTime = ".time.best";
|
||||
const char* szBestSpeedrunDifficulty = ".time.best.difficulty";
|
||||
|
||||
// difficulty names used when fetching steam stats
|
||||
const char* g_szDifficulties[] =
|
||||
{
|
||||
"Easy",
|
||||
"Normal",
|
||||
"Hard",
|
||||
"Insane"
|
||||
"Insane",
|
||||
"imba"
|
||||
};
|
||||
|
||||
const char *g_OfficialMaps[] =
|
||||
{
|
||||
"asi-jac1-landingbay_01",
|
||||
"asi-jac1-landingbay_02",
|
||||
"asi-jac2-deima",
|
||||
"asi-jac3-rydberg",
|
||||
"asi-jac4-residential",
|
||||
"asi-jac6-sewerjunction",
|
||||
"asi-jac7-timorstation"
|
||||
};
|
||||
}
|
||||
|
||||
bool IsOfficialCampaign()
|
||||
{
|
||||
if( !ASWGameRules()->IsCampaignGame() )
|
||||
return false;
|
||||
|
||||
CASW_Campaign_Save *pCampaign = ASWGameRules()->GetCampaignSave();
|
||||
|
||||
const char *szMapName = engine->GetLevelNameShort();
|
||||
const char *szCampaignName = pCampaign->GetCampaignName();
|
||||
if( FStrEq( szCampaignName, "jacob" ) )
|
||||
{
|
||||
for( int i=0; i < ARRAYSIZE( g_OfficialMaps ); ++i )
|
||||
{
|
||||
if( FStrEq( szMapName, g_OfficialMaps[i] ) )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsDamagingWeapon( const char* szWeaponName, bool bIsExtraEquip )
|
||||
|
@ -149,6 +191,10 @@ bool CASW_Steamstats::FetchStats( CSteamID playerSteamID, CASW_Player *pPlayer )
|
|||
m_DifficultyCounts.Purge();
|
||||
m_WeaponStats.Purge();
|
||||
|
||||
// Returns true so we don't re-fetch stats
|
||||
if( !IsOfficialCampaign() )
|
||||
return true;
|
||||
|
||||
// Fetch the player's overall stats
|
||||
FETCH_STEAM_STATS( "iTotalKills", m_iTotalKills );
|
||||
FETCH_STEAM_STATS( "fAccuracy", m_fAccuracy );
|
||||
|
@ -253,7 +299,7 @@ bool CASW_Steamstats::FetchStats( CSteamID playerSteamID, CASW_Player *pPlayer )
|
|||
}
|
||||
|
||||
// Get difficulty counts
|
||||
for( int i=0; i < 4; ++i )
|
||||
for( int i=0; i < 5; ++i )
|
||||
{
|
||||
int32 iTempCount;
|
||||
FETCH_STEAM_STATS( CFmtStr( "%s.games.total", g_szDifficulties[ i ] ), iTempCount );
|
||||
|
@ -275,7 +321,13 @@ void CASW_Steamstats::PrepStatsForSend( CASW_Player *pPlayer )
|
|||
return;
|
||||
|
||||
// Update stats from the briefing screen
|
||||
if( !GetDebriefStats() || !ASWGameResource() )
|
||||
if( !GetDebriefStats()
|
||||
|| !ASWGameResource()
|
||||
|| !IsOfficialCampaign()
|
||||
#ifndef DEBUG
|
||||
|| ASWGameRules()->m_bCheated
|
||||
#endif
|
||||
)
|
||||
return;
|
||||
|
||||
if( m_MarineSelectionCounts.Count() == 0 ||
|
||||
|
@ -386,7 +438,10 @@ void CASW_Steamstats::PrepStatsForSend( CASW_Player *pPlayer )
|
|||
SEND_STEAM_STATS( CFmtStr( "marines.%i.total", iMarineProfileIndex ), m_MarineSelectionCounts[iMarineProfileIndex] );
|
||||
int iLevel = pPlayer->GetLevel();
|
||||
SEND_STEAM_STATS( "level", iLevel );
|
||||
SEND_STEAM_STATS( "level.xprequired", ( iLevel == NELEMS( g_iLevelExperience ) ) ? 0 : g_iLevelExperience[ iLevel ] );
|
||||
int iPromotion = pPlayer->GetPromotion();
|
||||
float flXPRequired = ( iLevel == NELEMS( g_iLevelExperience ) ) ? 0 : g_iLevelExperience[ iLevel ];
|
||||
flXPRequired *= g_flPromotionXPScale[ iPromotion ];
|
||||
SEND_STEAM_STATS( "level.xprequired", (int) flXPRequired );
|
||||
|
||||
// Send favorite equip info
|
||||
SEND_STEAM_STATS( "equips.primary.fav", GetFavoriteEquip(0) );
|
||||
|
@ -560,6 +615,8 @@ bool DifficultyStats_t::FetchDifficultyStats( CSteamAPIContext * pSteamContext,
|
|||
break;
|
||||
case 4: szDifficulty = "insane";
|
||||
break;
|
||||
case 5: szDifficulty = "imba";
|
||||
break;
|
||||
}
|
||||
if( szDifficulty )
|
||||
{
|
||||
|
@ -618,6 +675,8 @@ void DifficultyStats_t::PrepStatsForSend( CASW_Player *pPlayer )
|
|||
break;
|
||||
case 4: szDifficulty = "insane";
|
||||
break;
|
||||
case 5: szDifficulty = "imba";
|
||||
break;
|
||||
}
|
||||
if( szDifficulty )
|
||||
{
|
||||
|
@ -652,6 +711,12 @@ bool MissionStats_t::FetchMissionStats( CSteamAPIContext * pSteamContext, CSteam
|
|||
FETCH_STEAM_STATS( CFmtStr( "%s%s", szLevelName, szKillsTotal ), m_iKillsTotal );
|
||||
FETCH_STEAM_STATS( CFmtStr( "%s%s", szLevelName, szDamageTotal ), m_iDamageTotal );
|
||||
FETCH_STEAM_STATS( CFmtStr( "%s%s", szLevelName, szFFTotal ), m_iFFTotal );
|
||||
FETCH_STEAM_STATS( CFmtStr( "%s%s", szLevelName, szTimeTotal ), m_iTimeTotal );
|
||||
FETCH_STEAM_STATS( CFmtStr( "%s%s", szLevelName, szBestDifficulty ), m_iHighestDifficulty );
|
||||
for( int i=0; i<5; ++i )
|
||||
{
|
||||
FETCH_STEAM_STATS( CFmtStr( "%s%s.%s", szLevelName, szBestTime, g_szDifficulties[i] ), m_iBestSpeedrunTimes[i] );
|
||||
}
|
||||
|
||||
return bOK;
|
||||
}
|
||||
|
@ -663,6 +728,7 @@ void MissionStats_t::PrepStatsForSend( CASW_Player *pPlayer )
|
|||
return;
|
||||
|
||||
CASW_Marine_Resource *pMR = ASWGameResource()->GetFirstMarineResourceForPlayer( pPlayer );
|
||||
int iDifficulty = ASWGameRules()->GetSkillLevel();
|
||||
if ( pMR )
|
||||
{
|
||||
int iMarineIndex = ASWGameResource()->GetMarineResourceIndex( pMR );
|
||||
|
@ -674,6 +740,24 @@ void MissionStats_t::PrepStatsForSend( CASW_Player *pPlayer )
|
|||
m_iGamesTotal++;
|
||||
m_iGamesSuccess += ASWGameRules()->GetMissionSuccess() ? 1 : 0;
|
||||
m_fGamesSuccessPercent = m_iGamesSuccess / (float)m_iGamesTotal * 100.0f;
|
||||
m_iTimeTotal += GetDebriefStats()->m_fTimeTaken;
|
||||
if( ASWGameRules()->GetMissionSuccess() )
|
||||
{
|
||||
if( iDifficulty > m_iHighestDifficulty )
|
||||
m_iHighestDifficulty = iDifficulty;
|
||||
|
||||
if( (unsigned int)m_iBestSpeedrunTimes[ iDifficulty - 1 ] > GetDebriefStats()->m_fTimeTaken )
|
||||
{
|
||||
m_iBestSpeedrunTimes[ iDifficulty - 1 ] = GetDebriefStats()->m_fTimeTaken;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Safely compute averages
|
||||
m_fKillsAvg = m_iKillsTotal / (float)m_iGamesTotal;
|
||||
m_fFFAvg = m_iFFTotal / (float)m_iGamesTotal;
|
||||
m_fDamageAvg = m_iDamageTotal / (float)m_iGamesTotal;
|
||||
m_iTimeAvg = m_iTimeTotal / (float)m_iGamesTotal;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -692,7 +776,13 @@ void MissionStats_t::PrepStatsForSend( CASW_Player *pPlayer )
|
|||
SEND_STEAM_STATS( CFmtStr( "%s%s", szLevelName, szKillsTotal ), m_iKillsTotal );
|
||||
SEND_STEAM_STATS( CFmtStr( "%s%s", szLevelName, szDamageTotal ), m_iDamageTotal );
|
||||
SEND_STEAM_STATS( CFmtStr( "%s%s", szLevelName, szFFTotal ), m_iFFTotal );
|
||||
|
||||
SEND_STEAM_STATS( CFmtStr( "%s%s", szLevelName, szTimeTotal ), m_iTimeTotal );
|
||||
SEND_STEAM_STATS( CFmtStr( "%s%s", szLevelName, szKillsAvg ), m_fKillsAvg );
|
||||
SEND_STEAM_STATS( CFmtStr( "%s%s", szLevelName, szDamageAvg ), m_fDamageAvg );
|
||||
SEND_STEAM_STATS( CFmtStr( "%s%s", szLevelName, szFFAvg ), m_fFFAvg );
|
||||
SEND_STEAM_STATS( CFmtStr( "%s%s", szLevelName, szTimeAvg ), m_iTimeAvg );
|
||||
SEND_STEAM_STATS( CFmtStr( "%s%s", szLevelName, szBestDifficulty ), m_iHighestDifficulty );
|
||||
SEND_STEAM_STATS( CFmtStr( "%s%s.%s", szLevelName, szBestTime, g_szDifficulties[ iDifficulty - 1 ] ), m_iBestSpeedrunTimes[ iDifficulty - 1 ] );
|
||||
}
|
||||
|
||||
bool WeaponStats_t::FetchWeaponStats( CSteamAPIContext * pSteamContext, CSteamID playerSteamID, const char *szClassName )
|
||||
|
|
|
@ -34,9 +34,13 @@ struct MissionStats_t
|
|||
int32 m_iKillsTotal;
|
||||
int32 m_iDamageTotal;
|
||||
int32 m_iFFTotal;
|
||||
int32 m_iKillsAvg;
|
||||
int32 m_iDamageAvg;
|
||||
int32 m_iFFAvg;
|
||||
float32 m_fKillsAvg;
|
||||
float32 m_fDamageAvg;
|
||||
float32 m_fFFAvg;
|
||||
int32 m_iTimeTotal;
|
||||
int32 m_iTimeAvg;
|
||||
int32 m_iHighestDifficulty;
|
||||
int32 m_iBestSpeedrunTimes[5];
|
||||
};
|
||||
|
||||
struct WeaponStats_t
|
||||
|
@ -105,7 +109,7 @@ private:
|
|||
StatList_Int_t m_MarineSelectionCounts;
|
||||
StatList_Int_t m_DifficultyCounts;
|
||||
|
||||
DifficultyStats_t m_DifficultyStats[4];
|
||||
DifficultyStats_t m_DifficultyStats[5];
|
||||
MissionStats_t m_MissionStats;
|
||||
WeaponStatList_t m_WeaponStats;
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ public:
|
|||
FooterFormat_t GetFormat();
|
||||
bool GetHelpTextEnabled();
|
||||
void SetHelpText( const char *text );
|
||||
const char * GetHelpText() { return m_HelpText; }
|
||||
void FadeHelpText( void );
|
||||
void GetPosition( int &x, int &y );
|
||||
bool HasContent( void );
|
||||
|
|
|
@ -966,7 +966,7 @@ FoundGames::FoundGames( Panel *parent, const char *panelName ):
|
|||
m_pHeaderFooter->SetHeaderEnabled( false );
|
||||
m_pHeaderFooter->SetFooterEnabled( true );
|
||||
m_pHeaderFooter->SetGradientBarEnabled( true );
|
||||
m_pHeaderFooter->SetGradientBarPos( 80, 300 );
|
||||
m_pHeaderFooter->SetGradientBarPos( 80, 315 );
|
||||
|
||||
m_pTitle = new vgui::Label( this, "Title", "" );
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ using namespace BaseModUI;
|
|||
|
||||
//=============================================================================
|
||||
static ConVar ui_public_lobby_filter_difficulty2( "ui_public_lobby_filter_difficulty2", "", FCVAR_ARCHIVE, "Filter type for difficulty on the public lobby display" );
|
||||
static ConVar ui_public_lobby_filter_onslaught( "ui_public_lobby_filter_onslaught", "", FCVAR_ARCHIVE, "Filter type for Onslaught mode on the public lobby display");
|
||||
ConVar ui_public_lobby_filter_campaign( "ui_public_lobby_filter_campaign", "", FCVAR_ARCHIVE, "Filter type for campaigns on the public lobby display" );
|
||||
ConVar ui_public_lobby_filter_status( "ui_public_lobby_filter_status", "", FCVAR_ARCHIVE, "Filter type for game status on the public lobby display" );
|
||||
|
||||
|
@ -38,6 +39,7 @@ FoundPublicGames::FoundPublicGames( Panel *parent, const char *panelName ) :
|
|||
m_pSearchManager( NULL )
|
||||
{
|
||||
m_drpDifficulty = NULL;
|
||||
m_drpOnslaught = NULL;
|
||||
m_drpGameStatus = NULL;
|
||||
m_drpCampaign = NULL;
|
||||
|
||||
|
@ -92,6 +94,7 @@ void FoundPublicGames::ApplySchemeSettings( IScheme *pScheme )
|
|||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
m_drpDifficulty = dynamic_cast< DropDownMenu* >( FindChildByName( "DrpFilterDifficulty" ) );
|
||||
m_drpOnslaught = dynamic_cast< DropDownMenu* >( FindChildByName( "DrpFilterOnslaught" ) );
|
||||
m_drpGameStatus = dynamic_cast< DropDownMenu* >( FindChildByName( "DrpFilterGameStatus" ) );
|
||||
m_drpCampaign = dynamic_cast< DropDownMenu* >( FindChildByName( "DrpFilterCampaign" ) );
|
||||
m_btnFilters = dynamic_cast< BaseModUI::BaseModHybridButton* >( FindChildByName( "BtnFilters" ) );
|
||||
|
@ -168,6 +171,10 @@ void FoundPublicGames::StartSearching( void )
|
|||
if ( szDifficulty && *szDifficulty && GameModeHasDifficulty( szGameMode ) )
|
||||
pKeyValuesSearch->SetString( "game/difficulty", szDifficulty );
|
||||
|
||||
char const *szOnslaught = ui_public_lobby_filter_onslaught.GetString();
|
||||
if ( szOnslaught && *szOnslaught )
|
||||
pKeyValuesSearch->SetInt( "game/onslaught", 1 );
|
||||
|
||||
char const *szStatus = ui_public_lobby_filter_status.GetString();
|
||||
if ( szStatus && *szStatus )
|
||||
pKeyValuesSearch->SetString( "game/state", szStatus );
|
||||
|
@ -501,6 +508,11 @@ void FoundPublicGames::OnCommand( const char *command )
|
|||
ui_public_lobby_filter_difficulty2.SetValue( filterDifficulty );
|
||||
StartSearching();
|
||||
}
|
||||
else if ( char const *filterOnslaught = StringAfterPrefix( command, "filter_onslaught_" ) )
|
||||
{
|
||||
ui_public_lobby_filter_onslaught.SetValue( filterOnslaught );
|
||||
StartSearching();
|
||||
}
|
||||
else if ( char const *filterCampaign = StringAfterPrefix( command, "filter_campaign_" ) )
|
||||
{
|
||||
ui_public_lobby_filter_campaign.SetValue( filterCampaign );
|
||||
|
@ -544,6 +556,11 @@ void FoundPublicGames::Activate()
|
|||
m_drpDifficulty->SetCurrentSelection( CFmtStr( "filter_difficulty_%s", ui_public_lobby_filter_difficulty2.GetString() ) );
|
||||
}
|
||||
|
||||
if ( m_drpOnslaught )
|
||||
{
|
||||
m_drpOnslaught->SetCurrentSelection( CFmtStr( "filter_onslaught_%s", ui_public_lobby_filter_onslaught.GetString() ) );
|
||||
}
|
||||
|
||||
if ( m_drpGameStatus )
|
||||
{
|
||||
m_drpGameStatus->SetCurrentSelection( CFmtStr( "filter_status_%s", ui_public_lobby_filter_status.GetString() ) );
|
||||
|
|
|
@ -55,6 +55,7 @@ namespace BaseModUI {
|
|||
#endif
|
||||
|
||||
DropDownMenu* m_drpDifficulty;
|
||||
DropDownMenu* m_drpOnslaught;
|
||||
DropDownMenu* m_drpGameStatus;
|
||||
DropDownMenu* m_drpCampaign;
|
||||
BaseModUI::BaseModHybridButton *m_btnFilters;
|
||||
|
|
|
@ -55,13 +55,15 @@ GameSettings::GameSettings( vgui::Panel *parent, const char *panelName ):
|
|||
m_drpStartingMission( NULL ),
|
||||
m_bEditingSession( false ),
|
||||
m_bAllowChangeToCustomCampaign( true ),
|
||||
m_bPreventSessionModifications( false )
|
||||
m_bPreventSessionModifications( false ),
|
||||
m_drpFriendlyFire( NULL ),
|
||||
m_drpOnslaught( NULL )
|
||||
{
|
||||
m_pHeaderFooter = new CNB_Header_Footer( this, "HeaderFooter" );
|
||||
m_pHeaderFooter->SetTitle( "" );
|
||||
m_pHeaderFooter->SetHeaderEnabled( false );
|
||||
m_pHeaderFooter->SetGradientBarEnabled( true );
|
||||
m_pHeaderFooter->SetGradientBarPos( 150, 170 );
|
||||
m_pHeaderFooter->SetGradientBarPos( 140, 190 );
|
||||
m_pTitle = new vgui::Label( this, "Title", "" );
|
||||
SetDeleteSelfOnClose(true);
|
||||
SetProportional( true );
|
||||
|
@ -206,6 +208,36 @@ void GameSettings::Activate()
|
|||
flyout->CloseMenu( NULL );
|
||||
}
|
||||
|
||||
if ( m_drpFriendlyFire )
|
||||
{
|
||||
if ( m_pSettings->GetInt( "game/hardcoreFF", 0 ) == 1 )
|
||||
{
|
||||
m_drpFriendlyFire->SetCurrentSelection( "#L4D360UI_HardcoreFF" );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_drpFriendlyFire->SetCurrentSelection( "#L4D360UI_RegularFF" );
|
||||
}
|
||||
|
||||
if ( FlyoutMenu* flyout = m_drpFriendlyFire->GetCurrentFlyout() )
|
||||
flyout->CloseMenu( NULL );
|
||||
}
|
||||
|
||||
if ( m_drpOnslaught )
|
||||
{
|
||||
if ( m_pSettings->GetInt( "game/onslaught", 0 ) == 1 )
|
||||
{
|
||||
m_drpOnslaught->SetCurrentSelection( "#L4D360UI_OnslaughtEnabled" );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_drpOnslaught->SetCurrentSelection( "#L4D360UI_OnslaughtDisabled" );
|
||||
}
|
||||
|
||||
if ( FlyoutMenu* flyout = m_drpOnslaught->GetCurrentFlyout() )
|
||||
flyout->CloseMenu( NULL );
|
||||
}
|
||||
|
||||
// If we have an active control, navigate from it since we'll be setting a new one
|
||||
if ( m_ActiveControl )
|
||||
{
|
||||
|
@ -581,6 +613,94 @@ void GameSettings::OnCommand(const char *command)
|
|||
pFlyout->SetListener( this );
|
||||
}
|
||||
}
|
||||
else if ( !Q_strcmp( command, "#L4D360UI_RegularFF" ) )
|
||||
{
|
||||
KeyValues *pSettings = KeyValues::FromString(
|
||||
"update",
|
||||
" update { "
|
||||
" game { "
|
||||
" hardcoreFF = "
|
||||
" } "
|
||||
" } "
|
||||
);
|
||||
KeyValues::AutoDelete autodelete( pSettings );
|
||||
|
||||
pSettings->SetInt( "update/game/hardcoreFF", 0 );
|
||||
|
||||
UpdateSessionSettings( pSettings );
|
||||
|
||||
if( m_drpFriendlyFire )
|
||||
{
|
||||
if ( FlyoutMenu* pFlyout = m_drpFriendlyFire->GetCurrentFlyout() )
|
||||
pFlyout->SetListener( this );
|
||||
}
|
||||
}
|
||||
else if ( !Q_strcmp( command, "#L4D360UI_HardcoreFF" ) )
|
||||
{
|
||||
KeyValues *pSettings = KeyValues::FromString(
|
||||
"update",
|
||||
" update { "
|
||||
" game { "
|
||||
" hardcoreFF = "
|
||||
" } "
|
||||
" } "
|
||||
);
|
||||
KeyValues::AutoDelete autodelete( pSettings );
|
||||
|
||||
pSettings->SetInt( "update/game/hardcoreFF", 1 );
|
||||
|
||||
UpdateSessionSettings( pSettings );
|
||||
|
||||
if( m_drpFriendlyFire )
|
||||
{
|
||||
if ( FlyoutMenu* pFlyout = m_drpFriendlyFire->GetCurrentFlyout() )
|
||||
pFlyout->SetListener( this );
|
||||
}
|
||||
}
|
||||
else if ( !Q_strcmp( command, "#L4D360UI_OnslaughtDisabled" ) )
|
||||
{
|
||||
KeyValues *pSettings = KeyValues::FromString(
|
||||
"update",
|
||||
" update { "
|
||||
" game { "
|
||||
" onslaught = "
|
||||
" } "
|
||||
" } "
|
||||
);
|
||||
KeyValues::AutoDelete autodelete( pSettings );
|
||||
|
||||
pSettings->SetInt( "update/game/onslaught", 0 );
|
||||
|
||||
UpdateSessionSettings( pSettings );
|
||||
|
||||
if( m_drpOnslaught )
|
||||
{
|
||||
if ( FlyoutMenu* pFlyout = m_drpOnslaught->GetCurrentFlyout() )
|
||||
pFlyout->SetListener( this );
|
||||
}
|
||||
}
|
||||
else if ( !Q_strcmp( command, "#L4D360UI_OnslaughtEnabled" ) )
|
||||
{
|
||||
KeyValues *pSettings = KeyValues::FromString(
|
||||
"update",
|
||||
" update { "
|
||||
" game { "
|
||||
" onslaught = "
|
||||
" } "
|
||||
" } "
|
||||
);
|
||||
KeyValues::AutoDelete autodelete( pSettings );
|
||||
|
||||
pSettings->SetInt( "update/game/onslaught", 1 );
|
||||
|
||||
UpdateSessionSettings( pSettings );
|
||||
|
||||
if( m_drpOnslaught )
|
||||
{
|
||||
if ( FlyoutMenu* pFlyout = m_drpOnslaught->GetCurrentFlyout() )
|
||||
pFlyout->SetListener( this );
|
||||
}
|
||||
}
|
||||
else if ( const char *szRoundLimitValue = StringAfterPrefix( command, "#L4D360UI_RoundLimit_" ) )
|
||||
{
|
||||
KeyValues *pSettings = new KeyValues( "update" );
|
||||
|
@ -654,6 +774,8 @@ void GameSettings::ApplySchemeSettings( vgui::IScheme *pScheme )
|
|||
|
||||
m_drpDifficulty = dynamic_cast< DropDownMenu* >( FindChildByName( "DrpDifficulty" ) );
|
||||
m_drpGameType = dynamic_cast< DropDownMenu* >( FindChildByName( "DrpGameType" ) );
|
||||
m_drpFriendlyFire = dynamic_cast< DropDownMenu* >( FindChildByName( "DrpFriendlyFire" ) );
|
||||
m_drpOnslaught = dynamic_cast< DropDownMenu* >( FindChildByName( "DrpOnslaught" ) );
|
||||
|
||||
m_drpGameAccess = dynamic_cast< DropDownMenu* >( FindChildByName( "DrpGameAccess" ) );
|
||||
if ( m_drpGameAccess )
|
||||
|
@ -710,6 +832,12 @@ void GameSettings::OnClose()
|
|||
if( m_drpGameType )
|
||||
m_drpGameType->CloseDropDown();
|
||||
|
||||
if( m_drpFriendlyFire )
|
||||
m_drpFriendlyFire->CloseDropDown();
|
||||
|
||||
if( m_drpOnslaught )
|
||||
m_drpOnslaught->CloseDropDown();
|
||||
|
||||
m_pSettings = NULL; // NULL out settings in case we get some calls
|
||||
// after we are closed
|
||||
if ( m_bCloseSessionOnClose )
|
||||
|
|
|
@ -73,6 +73,8 @@ private:
|
|||
DropDownMenu* m_drpGameAccess;
|
||||
DropDownMenu* m_drpServerType;
|
||||
DropDownMenu* m_drpStartingMission;
|
||||
DropDownMenu* m_drpFriendlyFire;
|
||||
DropDownMenu* m_drpOnslaught;
|
||||
CNB_Header_Footer *m_pHeaderFooter;
|
||||
vgui::Label *m_pTitle;
|
||||
|
||||
|
|
|
@ -92,7 +92,8 @@ void InGameDifficultySelect::OnCommand(const char *command)
|
|||
if ( !Q_strcmp( command, "Easy" ) ||
|
||||
!Q_strcmp( command, "Normal" ) ||
|
||||
!Q_strcmp( command, "Hard" ) ||
|
||||
!Q_strcmp( command, "Insane" ) )
|
||||
!Q_strcmp( command, "Insane" ) ||
|
||||
!Q_strcmp( command, "Imba" ) )
|
||||
{
|
||||
CGameUIConVarRef z_difficulty("z_difficulty");
|
||||
|
||||
|
|
|
@ -140,6 +140,7 @@ CASW_Difficulty_Entry::CASW_Difficulty_Entry( vgui::Panel *pParent, const char *
|
|||
case 2: m_pDifficultyLabel->SetText("#asw_difficulty_chooser_normal"); break;
|
||||
case 3: m_pDifficultyLabel->SetText("#asw_difficulty_chooser_hard"); break;
|
||||
case 4: m_pDifficultyLabel->SetText("#asw_difficulty_chooser_insane"); break;
|
||||
case 5: m_pDifficultyLabel->SetText("#asw_difficulty_chooser_imba"); break;
|
||||
default: m_pDifficultyLabel->SetText("???"); break;
|
||||
}
|
||||
|
||||
|
@ -149,6 +150,7 @@ CASW_Difficulty_Entry::CASW_Difficulty_Entry( vgui::Panel *pParent, const char *
|
|||
case 2: m_pDifficultyDescriptionLabel->SetText("#asw_difficulty_chooser_normald"); break;
|
||||
case 3: m_pDifficultyDescriptionLabel->SetText("#asw_difficulty_chooser_hardd"); break;
|
||||
case 4: m_pDifficultyDescriptionLabel->SetText("#asw_difficulty_chooser_insaned"); break;
|
||||
case 5: m_pDifficultyDescriptionLabel->SetText("#asw_difficulty_chooser_imbad"); break;
|
||||
default: m_pDifficultyDescriptionLabel->SetText("???"); break;
|
||||
}
|
||||
|
||||
|
@ -158,6 +160,7 @@ CASW_Difficulty_Entry::CASW_Difficulty_Entry( vgui::Panel *pParent, const char *
|
|||
case 2: m_pImagePanel->SetImage("swarm/MissionPics/DifficultyPicNormal"); break;
|
||||
case 3: m_pImagePanel->SetImage("swarm/MissionPics/DifficultyPicHard"); break;
|
||||
case 4: m_pImagePanel->SetImage("swarm/MissionPics/DifficultyPicInsane"); break;
|
||||
case 5: m_pImagePanel->SetImage("swarm/MissionPics/DifficultyPicInsane"); break;
|
||||
default: m_pImagePanel->SetImage("swarm/MissionPics/UnknownMissionPic"); break;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,17 +40,28 @@ ExperienceBar::ExperienceBar(vgui::Panel *parent, const char *name) :
|
|||
m_pExperienceBar->SetShowMaxOnCounter( true );
|
||||
m_pExperienceBar->SetColors( Color( 255, 255, 255, 0 ), Color( 93,148,192,255 ), Color( 255, 255, 255, 255 ), Color( 17,37,57,255 ), Color( 35, 77, 111, 255 ) );
|
||||
//m_pExperienceBar->m_bShowCumulativeTotal = true;
|
||||
m_pExperienceBar->AddMinMax( 0, g_iLevelExperience[ 0 ] );
|
||||
for ( int i = 0; i < ASW_NUM_EXPERIENCE_LEVELS - 1; i++ )
|
||||
{
|
||||
m_pExperienceBar->AddMinMax( g_iLevelExperience[ i ], g_iLevelExperience[ i + 1 ] );
|
||||
}
|
||||
m_nLastPromotion = -1;
|
||||
UpdateMinMaxes( 0 );
|
||||
|
||||
m_pExperienceBar->m_flBorder = 1.5f;
|
||||
|
||||
vgui::ivgui()->AddTickSignal( GetVPanel() );
|
||||
}
|
||||
|
||||
void ExperienceBar::UpdateMinMaxes( int nPromotion )
|
||||
{
|
||||
if ( m_nLastPromotion == nPromotion )
|
||||
return;
|
||||
|
||||
m_nLastPromotion = nPromotion;
|
||||
m_pExperienceBar->ClearMinMax();
|
||||
m_pExperienceBar->AddMinMax( 0, g_iLevelExperience[ 0 ] * g_flPromotionXPScale[ m_nLastPromotion ] );
|
||||
for ( int i = 0; i < ASW_NUM_EXPERIENCE_LEVELS - 1; i++ )
|
||||
{
|
||||
m_pExperienceBar->AddMinMax( g_iLevelExperience[ i ] * g_flPromotionXPScale[ m_nLastPromotion ] , g_iLevelExperience[ i + 1 ] * g_flPromotionXPScale[ m_nLastPromotion ] );
|
||||
}
|
||||
}
|
||||
|
||||
void ExperienceBar::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
@ -97,9 +108,9 @@ void ExperienceBar::OnTick()
|
|||
}
|
||||
}
|
||||
|
||||
if ( ASWGameRules()->GetGameState() <= ASW_GS_BRIEFING )
|
||||
if ( m_hPlayer.Get() )
|
||||
{
|
||||
if ( m_hPlayer.Get() )
|
||||
if ( ASWGameRules()->GetGameState() <= ASW_GS_BRIEFING )
|
||||
{
|
||||
int nXP = m_hPlayer->GetExperience();
|
||||
if ( nXP != m_nOldPlayerXP )
|
||||
|
@ -114,32 +125,32 @@ void ExperienceBar::OnTick()
|
|||
|
||||
m_pPlayerNameLabel->SetText( m_hPlayer->GetPlayerName() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float flBarMin = m_pExperienceBar->GetBarMin();
|
||||
bool bCapped = ( (int) m_pExperienceBar->m_fCurrent ) == ASW_XP_CAP;
|
||||
|
||||
if ( m_flOldBarMin == -1 )
|
||||
else
|
||||
{
|
||||
float flBarMin = m_pExperienceBar->GetBarMin();
|
||||
bool bCapped = ( (int) m_pExperienceBar->m_fCurrent ) >= ASW_XP_CAP * g_flPromotionXPScale[ m_hPlayer->GetPromotion() ];
|
||||
|
||||
if ( m_flOldBarMin == -1 )
|
||||
{
|
||||
m_bOldCapped = bCapped;
|
||||
}
|
||||
|
||||
if ( m_flOldBarMin != -1 && ( m_flOldBarMin != flBarMin || m_bOldCapped != bCapped ) ) // bar min has changed - player has levelled up!
|
||||
{
|
||||
m_iPlayerLevel = LevelFromXP( m_pExperienceBar->m_fCurrent, m_hPlayer->GetPromotion() );
|
||||
UpdateLevelLabel();
|
||||
|
||||
m_pLevelUpLabel->SetVisible( true );
|
||||
SkillAnimPanel *pSkillAnim = dynamic_cast<SkillAnimPanel*>(GetClientMode()->GetViewport()->FindChildByName("SkillAnimPanel", true));
|
||||
if ( pSkillAnim )
|
||||
{
|
||||
pSkillAnim->AddParticlesAroundPanel( m_pPlayerLevelLabel );
|
||||
}
|
||||
}
|
||||
|
||||
m_flOldBarMin = flBarMin;
|
||||
m_bOldCapped = bCapped;
|
||||
}
|
||||
|
||||
if ( m_flOldBarMin != -1 && ( m_flOldBarMin != flBarMin || m_bOldCapped != bCapped ) ) // bar min has changed - player has levelled up!
|
||||
{
|
||||
m_iPlayerLevel = LevelFromXP( m_pExperienceBar->m_fCurrent );
|
||||
UpdateLevelLabel();
|
||||
|
||||
m_pLevelUpLabel->SetVisible( true );
|
||||
SkillAnimPanel *pSkillAnim = dynamic_cast<SkillAnimPanel*>(GetClientMode()->GetViewport()->FindChildByName("SkillAnimPanel", true));
|
||||
if ( pSkillAnim )
|
||||
{
|
||||
pSkillAnim->AddParticlesAroundPanel( m_pPlayerLevelLabel );
|
||||
}
|
||||
}
|
||||
|
||||
m_flOldBarMin = flBarMin;
|
||||
m_bOldCapped = bCapped;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,11 +168,6 @@ void ExperienceBar::InitFor( C_ASW_Player *pPlayer )
|
|||
m_pPlayerNameLabel->SetText( "Player" );
|
||||
m_pPlayerLevelLabel->SetText( "Level 5" );
|
||||
m_pExperienceBar->Init( 1200, 1500, 1500.0f / 4.0f, true, false );
|
||||
m_pExperienceBar->AddMinMax( 0, g_iLevelExperience[ 0 ] );
|
||||
for ( int i = 0; i < ASW_NUM_EXPERIENCE_LEVELS - 1; i++ )
|
||||
{
|
||||
m_pExperienceBar->AddMinMax( g_iLevelExperience[ i ], g_iLevelExperience[ i + 1 ] );
|
||||
}
|
||||
m_pExperienceBar->SetStartCountingTime( gpGlobals->curtime + 15.0f );
|
||||
}
|
||||
return;
|
||||
|
@ -188,6 +194,7 @@ void ExperienceBar::InitFor( C_ASW_Player *pPlayer )
|
|||
}
|
||||
#endif
|
||||
|
||||
UpdateMinMaxes( pPlayer->GetPromotion() );
|
||||
if ( ASWGameRules()->GetGameState() <= ASW_GS_BRIEFING )
|
||||
{
|
||||
m_iPlayerLevel = pPlayer->GetLevel();
|
||||
|
@ -204,7 +211,7 @@ void ExperienceBar::InitFor( C_ASW_Player *pPlayer )
|
|||
|
||||
int iEarnedXP = pPlayer->GetEarnedXP( ASW_XP_TOTAL );
|
||||
int nGoalXP = pPlayer->GetExperienceBeforeDebrief() + iEarnedXP;
|
||||
nGoalXP = MIN( nGoalXP, ASW_XP_CAP );
|
||||
nGoalXP = MIN( nGoalXP, ASW_XP_CAP * g_flPromotionXPScale[ pPlayer->GetPromotion() ] );
|
||||
float flRate = (float) iEarnedXP / 3.0f; // take 4 seconds to increase XP.
|
||||
if ( iEarnedXP < 150 ) // if XP is really low, count it up in 1 second
|
||||
{
|
||||
|
|
|
@ -32,6 +32,7 @@ public:
|
|||
|
||||
void InitFor( C_ASW_Player *pPlayer );
|
||||
void UpdateLevelLabel();
|
||||
void UpdateMinMaxes( int nPromotion );
|
||||
|
||||
bool IsDoneAnimating();
|
||||
|
||||
|
@ -51,6 +52,7 @@ public:
|
|||
int m_iPlayerLevel;
|
||||
int m_nOldPlayerXP;
|
||||
CSteamID m_lastSteamID;
|
||||
int m_nLastPromotion;
|
||||
};
|
||||
|
||||
class ExperienceBarSmall : public ExperienceBar
|
||||
|
|
|
@ -161,7 +161,7 @@ void CExperienceReport::PerformLayout()
|
|||
if ( pPlayer )
|
||||
{
|
||||
int nPlayerLevel = pPlayer->GetLevel();
|
||||
m_pWeaponUnlockPanel->SetVisible( nPlayerLevel < ASW_LEVEL_CAP );
|
||||
m_pWeaponUnlockPanel->SetVisible( nPlayerLevel < ASW_NUM_EXPERIENCE_LEVELS );
|
||||
|
||||
if ( ASWGameRules() && ASWGameRules()->m_iSkillLevel == 2 && !ASWGameRules()->IsOfflineGame() &&
|
||||
!( ASWGameRules()->IsCampaignGame() && ASWGameRules()->CampaignMissionsLeft() <= 1 ) )
|
||||
|
@ -194,26 +194,28 @@ void CExperienceReport::OnThink()
|
|||
|
||||
// monitor local player's experience bar to see when it loops
|
||||
float flBarMin = m_pExperienceBar[ 0 ]->m_pExperienceBar->GetBarMin();
|
||||
bool bCapped = ( (int) m_pExperienceBar[ 0 ]->m_pExperienceBar->m_fCurrent ) == ASW_XP_CAP;
|
||||
|
||||
if ( m_flOldBarMin == -1 )
|
||||
bool bCapped = false;
|
||||
|
||||
C_ASW_Player *pPlayer = C_ASW_Player::GetLocalASWPlayer();
|
||||
if ( pPlayer )
|
||||
{
|
||||
m_bOldCapped = bCapped;
|
||||
}
|
||||
|
||||
if ( m_flOldBarMin != -1 && ( m_flOldBarMin != flBarMin || m_bOldCapped != bCapped ) ) // bar min has changed - player has levelled up!
|
||||
{
|
||||
m_bPendingUnlockSequence = true;
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "level_up" );
|
||||
int nNewLevel = LevelFromXP( (int) m_pExperienceBar[ 0 ]->m_pExperienceBar->m_fCurrent );
|
||||
if ( event )
|
||||
bCapped = ( (int) m_pExperienceBar[ 0 ]->m_pExperienceBar->m_fCurrent ) >= ASW_XP_CAP * g_flPromotionXPScale[ pPlayer->GetPromotion() ];
|
||||
if ( m_flOldBarMin == -1 )
|
||||
{
|
||||
event->SetInt( "level", nNewLevel );
|
||||
gameeventmanager->FireEventClientSide( event );
|
||||
m_bOldCapped = bCapped;
|
||||
}
|
||||
C_ASW_Player *pPlayer = C_ASW_Player::GetLocalASWPlayer();
|
||||
if ( pPlayer )
|
||||
|
||||
if ( m_flOldBarMin != -1 && ( m_flOldBarMin != flBarMin || m_bOldCapped != bCapped ) ) // bar min has changed - player has levelled up!
|
||||
{
|
||||
m_bPendingUnlockSequence = true;
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "level_up" );
|
||||
int nNewLevel = LevelFromXP( (int) m_pExperienceBar[ 0 ]->m_pExperienceBar->m_fCurrent, pPlayer->GetPromotion() );
|
||||
if ( event )
|
||||
{
|
||||
event->SetInt( "level", nNewLevel );
|
||||
gameeventmanager->FireEventClientSide( event );
|
||||
}
|
||||
|
||||
const char *szWeaponClassUnlocked = pPlayer->GetWeaponUnlockedAtLevel( nNewLevel );
|
||||
if ( szWeaponClassUnlocked )
|
||||
{
|
||||
|
@ -227,9 +229,10 @@ void CExperienceReport::OnThink()
|
|||
pComplete->OnWeaponUnlocked( szWeaponClassUnlocked );
|
||||
}
|
||||
}
|
||||
|
||||
CLocalPlayerFilter filter;
|
||||
C_BaseEntity::EmitSound( filter, -1 /*SOUND_FROM_LOCAL_PLAYER*/, "ASW_XP.LevelUp" );
|
||||
}
|
||||
CLocalPlayerFilter filter;
|
||||
C_BaseEntity::EmitSound( filter, -1 /*SOUND_FROM_LOCAL_PLAYER*/, "ASW_XP.LevelUp" );
|
||||
}
|
||||
|
||||
m_flOldBarMin = flBarMin;
|
||||
|
@ -256,6 +259,7 @@ void CExperienceReport::OnThink()
|
|||
case 2: m_pXPDifficultyScaleNumber->SetText( "" ); flTotalXP *= g_flXPDifficultyScale[1]; break;
|
||||
case 3: m_pXPDifficultyScaleNumber->SetText( "+20%" ); flTotalXP *= g_flXPDifficultyScale[2]; break;
|
||||
case 4: m_pXPDifficultyScaleNumber->SetText( "+40%" ); flTotalXP *= g_flXPDifficultyScale[3]; break;
|
||||
case 5: m_pXPDifficultyScaleNumber->SetText( "+50%" ); flTotalXP *= g_flXPDifficultyScale[4]; break;
|
||||
}
|
||||
bool bShowDifficultyBonus = ( ASWGameRules()->GetSkillLevel() != 2 );
|
||||
m_pXPDifficultyScaleNumber->SetVisible( bShowDifficultyBonus );
|
||||
|
|
|
@ -115,29 +115,25 @@ void MissionStatsPanel::SetMissionLabels(vgui::Label *pMissionLabel, vgui::Label
|
|||
pszToken = "#asw_difficulty_easy";
|
||||
else if (iDiff == 3)
|
||||
pszToken = "#asw_difficulty_hard";
|
||||
else if (iDiff >= 4)
|
||||
else if (iDiff == 4)
|
||||
pszToken = "#asw_difficulty_insane";
|
||||
else if (iDiff >= 5)
|
||||
pszToken = "#asw_difficulty_imba";
|
||||
const wchar_t *pDiff = g_pVGuiLocalize->Find( pszToken );
|
||||
|
||||
// find campaign/single mission
|
||||
if (bCampaign)
|
||||
pszToken = "#asw_difficulty_campaign";
|
||||
else
|
||||
pszToken = "#asw_difficulty_mission";
|
||||
const wchar_t *pCampaign = g_pVGuiLocalize->Find( pszToken );
|
||||
bool bOnslaught = CAlienSwarm::IsOnslaught();
|
||||
|
||||
// find style
|
||||
if (bUber)
|
||||
pszToken = "#asw_difficulty_uber";
|
||||
else if (bCarnage)
|
||||
pszToken = "#asw_difficulty_carnage";
|
||||
else if (bHardcore)
|
||||
pszToken = "#asw_difficulty_hardcore";
|
||||
|
||||
const wchar_t *pStyle = L"";
|
||||
if (bUber || bCarnage || bHardcore)
|
||||
const wchar_t *pOnslaught = L"";
|
||||
if ( bOnslaught )
|
||||
{
|
||||
pStyle = g_pVGuiLocalize->Find( pszToken );
|
||||
pOnslaught = g_pVGuiLocalize->Find( "#nb_onslaught_title" );
|
||||
}
|
||||
|
||||
bool bHardcoreFriendlyFire = CAlienSwarm::IsHardcoreFF();
|
||||
const wchar_t *pHardcoreFF = L"";
|
||||
if ( bHardcoreFriendlyFire )
|
||||
{
|
||||
pHardcoreFF = g_pVGuiLocalize->Find( "#asw_hardcore_ff" );
|
||||
}
|
||||
|
||||
const wchar_t *pCheated = L"";
|
||||
|
@ -149,7 +145,7 @@ void MissionStatsPanel::SetMissionLabels(vgui::Label *pMissionLabel, vgui::Label
|
|||
wchar_t mission_difficulty[96];
|
||||
g_pVGuiLocalize->ConstructString( mission_difficulty, sizeof(mission_difficulty),
|
||||
g_pVGuiLocalize->Find("#asw_mission_difficulty"), 4,
|
||||
pCampaign, pDiff, pStyle, pCheated);
|
||||
pDiff, pOnslaught, pHardcoreFF, pCheated);
|
||||
pDifficultyLabel->SetText(mission_difficulty);
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ void CNB_Commander_List_Entry::OnThink()
|
|||
m_pCommanderName->SetText( pPlayer->GetPlayerName() );
|
||||
|
||||
int nXP = pPlayer->GetExperienceBeforeDebrief() + pPlayer->GetEarnedXP( ASW_XP_TOTAL );
|
||||
int nLevel = LevelFromXP( nXP );
|
||||
int nLevel = LevelFromXP( nXP, pPlayer->GetPromotion() );
|
||||
|
||||
wchar_t szLevelNum[16]=L"";
|
||||
_snwprintf( szLevelNum, ARRAYSIZE( szLevelNum ), L"%i", nLevel + 1 ); // levels start at 0 in code, but show from 1 in the UI
|
||||
|
|
|
@ -77,10 +77,11 @@ CNB_Lobby_Row::CNB_Lobby_Row( vgui::Panel *parent, const char *name ) : BaseClas
|
|||
m_pXPBar->SetShowMaxOnCounter( true );
|
||||
m_pXPBar->SetColors( Color( 255, 255, 255, 0 ), Color( 93,148,192,255 ), Color( 255, 255, 255, 255 ), Color( 17,37,57,255 ), Color( 35, 77, 111, 255 ) );
|
||||
//m_pXPBar->m_bShowCumulativeTotal = true;
|
||||
m_pXPBar->AddMinMax( 0, g_iLevelExperience[ 0 ] );
|
||||
m_nLastPromotion = 0;
|
||||
m_pXPBar->AddMinMax( 0, g_iLevelExperience[ 0 ] * g_flPromotionXPScale[ m_nLastPromotion ] );
|
||||
for ( int i = 0; i < ASW_NUM_EXPERIENCE_LEVELS - 1; i++ )
|
||||
{
|
||||
m_pXPBar->AddMinMax( g_iLevelExperience[ i ], g_iLevelExperience[ i + 1 ] );
|
||||
m_pXPBar->AddMinMax( g_iLevelExperience[ i ] * g_flPromotionXPScale[ m_nLastPromotion ], g_iLevelExperience[ i + 1 ] * g_flPromotionXPScale[ m_nLastPromotion ] );
|
||||
}
|
||||
|
||||
m_pXPBar->m_flBorder = 1.5f;
|
||||
|
|
|
@ -68,6 +68,7 @@ public:
|
|||
char m_szLastWeaponImage[ ASW_NUM_INVENTORY_SLOTS ][ 255 ];
|
||||
char m_szLastPortraitImage[ 255 ];
|
||||
CSteamID m_lastSteamID;
|
||||
int m_nLastPromotion;
|
||||
|
||||
int m_nLobbySlot;
|
||||
};
|
||||
|
|
|
@ -170,6 +170,9 @@ void CNB_Lobby_Tooltip::OnTick()
|
|||
case 1: m_pPromotionLabel->SetText( "#nb_first_promotion" ); m_pTitle->SetText( "#nb_promotion_medal_1"); break;
|
||||
case 2: m_pPromotionLabel->SetText( "#nb_second_promotion" ); m_pTitle->SetText( "#nb_promotion_medal_2"); break;
|
||||
case 3: m_pPromotionLabel->SetText( "#nb_third_promotion" ); m_pTitle->SetText( "#nb_promotion_medal_3"); break;
|
||||
case 4: m_pPromotionLabel->SetText( "#nb_fourth_promotion" ); m_pTitle->SetText( "#nb_promotion_medal_4"); break;
|
||||
case 5: m_pPromotionLabel->SetText( "#nb_fifth_promotion" ); m_pTitle->SetText( "#nb_promotion_medal_5"); break;
|
||||
case 6: m_pPromotionLabel->SetText( "#nb_sixth_promotion" ); m_pTitle->SetText( "#nb_promotion_medal_6"); break;
|
||||
}
|
||||
m_pPromotionIcon->SetImage( VarArgs( "briefing/promotion_%d_LG", nPromotion ) );
|
||||
}
|
||||
|
|
|
@ -158,7 +158,7 @@ void CNB_Main_Panel::OnThink()
|
|||
m_pChatButton->SetVisible( gpGlobals->maxClients > 1 );
|
||||
m_pVoteButton->SetVisible( gpGlobals->maxClients > 1 );
|
||||
C_ASW_Player *pPlayer = C_ASW_Player::GetLocalASWPlayer();
|
||||
m_pPromotionButton->SetVisible( pPlayer && pPlayer->GetExperience() >= ASW_XP_CAP && pPlayer->GetPromotion() < ASW_PROMOTION_CAP );
|
||||
m_pPromotionButton->SetVisible( pPlayer && pPlayer->GetExperience() >= ( ASW_XP_CAP * g_flPromotionXPScale[ pPlayer->GetPromotion() ] ) && pPlayer->GetPromotion() < ASW_PROMOTION_CAP );
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -70,6 +70,8 @@ void CNB_Mission_Options::OnThink()
|
|||
m_pSkillLevelLabel->SetText("#asw_difficulty_hard");
|
||||
else if (m_iLastSkillLevel == 1)
|
||||
m_pSkillLevelLabel->SetText("#asw_difficulty_easy");
|
||||
else if (m_iLastSkillLevel == 5)
|
||||
m_pSkillLevelLabel->SetText("#asw_difficulty_imba");
|
||||
else
|
||||
m_pSkillLevelLabel->SetText("#asw_difficulty_normal");
|
||||
|
||||
|
@ -80,6 +82,7 @@ void CNB_Mission_Options::OnThink()
|
|||
case 2: m_pSkillDescriptionLabel->SetText("#asw_difficulty_chooser_normald"); break;
|
||||
case 3: m_pSkillDescriptionLabel->SetText("#asw_difficulty_chooser_hardd"); break;
|
||||
case 4: m_pSkillDescriptionLabel->SetText("#asw_difficulty_chooser_insaned"); break;
|
||||
case 5: m_pSkillDescriptionLabel->SetText("#asw_difficulty_chooser_imbad"); break;
|
||||
default: m_pSkillDescriptionLabel->SetText("???"); break;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include "c_asw_game_resource.h"
|
||||
#include "asw_input.h"
|
||||
#include "nb_island.h"
|
||||
#include "gameui/swarm/basemodpanel.h"
|
||||
#include "gameui/swarm/VFooterPanel.h"
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
@ -45,6 +47,8 @@ CNB_Mission_Panel::CNB_Mission_Panel( vgui::Panel *parent, const char *name ) :
|
|||
// == MANAGED_MEMBER_CREATION_END ==
|
||||
m_pBackButton = new CNB_Button( this, "BackButton", "", this, "BackButton" );
|
||||
m_drpDifficulty = new BaseModUI::DropDownMenu( this, "DrpDifficulty" );
|
||||
m_drpFriendlyFire = new BaseModUI::DropDownMenu( this, "DrpFriendlyFire" );
|
||||
m_drpOnslaught = new BaseModUI::DropDownMenu( this, "DrpOnslaught" );
|
||||
m_drpFixedSkillPoints = new BaseModUI::DropDownMenu( this, "DrpFixedSkillPoints" );
|
||||
|
||||
m_pHeaderFooter->SetTitle( "#nb_mission_details" );
|
||||
|
@ -61,6 +65,8 @@ CNB_Mission_Panel::CNB_Mission_Panel( vgui::Panel *parent, const char *name ) :
|
|||
|
||||
m_iLastSkillLevel = -1;
|
||||
m_iLastFixedSkillPoints = -1;
|
||||
m_iLastHardcoreFF = -1;
|
||||
m_iLastOnslaught = -1;
|
||||
}
|
||||
|
||||
CNB_Mission_Panel::~CNB_Mission_Panel()
|
||||
|
@ -165,6 +171,8 @@ void CNB_Mission_Panel::OnThink()
|
|||
bool bLeader = ( pPlayer && (pPlayer->entindex() == iLeaderIndex ) );
|
||||
|
||||
m_drpDifficulty->SetEnabled( ASWGameRules()->GetGameState() == ASW_GS_BRIEFING && bLeader );
|
||||
m_drpFriendlyFire->SetEnabled( ASWGameRules()->GetGameState() == ASW_GS_BRIEFING && bLeader );
|
||||
m_drpOnslaught->SetEnabled( ASWGameRules()->GetGameState() == ASW_GS_BRIEFING && bLeader );
|
||||
m_drpFixedSkillPoints->SetEnabled( false ); //ASWGameRules()->GetGameState() == ASW_GS_BRIEFING && bLeader );
|
||||
|
||||
if (m_iLastSkillLevel != ASWGameRules()->GetSkillLevel())
|
||||
|
@ -173,27 +181,69 @@ void CNB_Mission_Panel::OnThink()
|
|||
if (m_iLastSkillLevel == 4)
|
||||
{
|
||||
m_drpDifficulty->SetCurrentSelection("#L4D360UI_Difficulty_insane");
|
||||
m_pDifficultyDescription->SetText( "#asw_difficulty_chooser_insaned" );
|
||||
//m_pDifficultyDescription->SetText( "#asw_difficulty_chooser_insaned" );
|
||||
}
|
||||
else if (m_iLastSkillLevel == 3)
|
||||
{
|
||||
m_drpDifficulty->SetCurrentSelection("#L4D360UI_Difficulty_hard");
|
||||
m_pDifficultyDescription->SetText( "#asw_difficulty_chooser_hardd" );
|
||||
//m_pDifficultyDescription->SetText( "#asw_difficulty_chooser_hardd" );
|
||||
}
|
||||
else if (m_iLastSkillLevel == 1)
|
||||
{
|
||||
m_drpDifficulty->SetCurrentSelection("#L4D360UI_Difficulty_easy");
|
||||
m_pDifficultyDescription->SetText( "#asw_difficulty_chooser_easyd" );
|
||||
//m_pDifficultyDescription->SetText( "#asw_difficulty_chooser_easyd" );
|
||||
}
|
||||
else if (m_iLastSkillLevel == 5)
|
||||
{
|
||||
m_drpDifficulty->SetCurrentSelection("#L4D360UI_Difficulty_imba");
|
||||
//m_pDifficultyDescription->SetText( "#asw_difficulty_chooser_imbad" );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_drpDifficulty->SetCurrentSelection("#L4D360UI_Difficulty_normal");
|
||||
m_pDifficultyDescription->SetText( "#asw_difficulty_chooser_normald" );
|
||||
//m_pDifficultyDescription->SetText( "#asw_difficulty_chooser_normald" );
|
||||
}
|
||||
}
|
||||
extern ConVar asw_sentry_friendly_fire_scale;
|
||||
extern ConVar asw_marine_ff_absorption;
|
||||
int nHardcoreFF = ( asw_sentry_friendly_fire_scale.GetFloat() != 0.0f || asw_marine_ff_absorption.GetInt() != 1 ) ? 1 : 0;
|
||||
if ( m_iLastHardcoreFF != nHardcoreFF )
|
||||
{
|
||||
m_iLastHardcoreFF = nHardcoreFF;
|
||||
if ( nHardcoreFF == 1 )
|
||||
{
|
||||
m_drpFriendlyFire->SetCurrentSelection( "#L4D360UI_HardcoreFF" );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_drpFriendlyFire->SetCurrentSelection( "#L4D360UI_RegularFF" );
|
||||
}
|
||||
}
|
||||
extern ConVar asw_horde_override;
|
||||
extern ConVar asw_wanderer_override;
|
||||
int nOnslaught = ( asw_horde_override.GetBool() || asw_wanderer_override.GetBool() ) ? 1 : 0;
|
||||
if ( m_iLastOnslaught != nOnslaught )
|
||||
{
|
||||
m_iLastOnslaught = nOnslaught;
|
||||
if ( nOnslaught == 1 )
|
||||
{
|
||||
m_drpOnslaught->SetCurrentSelection( "#L4D360UI_OnslaughtEnabled" );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_drpOnslaught->SetCurrentSelection( "#L4D360UI_OnslaughtDisabled" );
|
||||
}
|
||||
}
|
||||
|
||||
BaseModUI::CBaseModFooterPanel *footer = BaseModUI::CBaseModPanel::GetSingleton().GetFooterPanel();
|
||||
if ( footer )
|
||||
{
|
||||
m_pDifficultyDescription->SetText( footer->GetHelpText() );
|
||||
}
|
||||
|
||||
// only show insane in multiplayer
|
||||
m_drpDifficulty->SetFlyoutItemEnabled( "BtnImpossible", gpGlobals->maxClients > 1 );
|
||||
m_drpDifficulty->SetFlyoutItemEnabled( "BtnImba", gpGlobals->maxClients > 1 );
|
||||
|
||||
if ( ASWGameRules()->IsCampaignGame() && ASWGameRules()->GetCampaignSave() && ASWGameRules()->GetGameState() != ASW_GS_INGAME )
|
||||
{
|
||||
|
@ -265,6 +315,31 @@ void CNB_Mission_Panel::OnCommand( const char *command )
|
|||
engine->ClientCmd( "cl_skill 4" );
|
||||
return;
|
||||
}
|
||||
else if ( !Q_stricmp( command, "#L4D360UI_Difficulty_imba" ) )
|
||||
{
|
||||
engine->ClientCmd( "cl_skill 5" );
|
||||
return;
|
||||
}
|
||||
else if ( !Q_stricmp( command, "#L4D360UI_RegularFF" ) )
|
||||
{
|
||||
engine->ClientCmd( "cl_hardcore_ff 0" );
|
||||
return;
|
||||
}
|
||||
else if ( !Q_stricmp( command, "#L4D360UI_HardcoreFF" ) )
|
||||
{
|
||||
engine->ClientCmd( "cl_hardcore_ff 1" );
|
||||
return;
|
||||
}
|
||||
else if ( !Q_stricmp( command, "#L4D360UI_OnslaughtDisabled" ) )
|
||||
{
|
||||
engine->ClientCmd( "cl_onslaught 0" );
|
||||
return;
|
||||
}
|
||||
else if ( !Q_stricmp( command, "#L4D360UI_OnslaughtEnabled" ) )
|
||||
{
|
||||
engine->ClientCmd( "cl_onslaught 1" );
|
||||
return;
|
||||
}
|
||||
BaseClass::OnCommand( command );
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@ public:
|
|||
CNB_Button *m_pBackButton;
|
||||
BaseModUI::DropDownMenu* m_drpDifficulty;
|
||||
BaseModUI::DropDownMenu* m_drpFixedSkillPoints;
|
||||
BaseModUI::DropDownMenu* m_drpFriendlyFire;
|
||||
BaseModUI::DropDownMenu* m_drpOnslaught;
|
||||
|
||||
ObjectiveListBox* m_pObjectiveList;
|
||||
ObjectiveDetailsPanel* m_pObjectiveDetails;
|
||||
|
@ -59,6 +61,8 @@ public:
|
|||
|
||||
int m_iLastSkillLevel;
|
||||
int m_iLastFixedSkillPoints;
|
||||
int m_iLastHardcoreFF;
|
||||
int m_iLastOnslaught;
|
||||
};
|
||||
|
||||
class InGameMissionPanelFrame : public vgui::Frame
|
||||
|
|
|
@ -105,14 +105,31 @@ void CNB_Mission_Summary::OnThink()
|
|||
return;
|
||||
|
||||
int nSkillLevel = ASWGameRules()->GetSkillLevel();
|
||||
if (nSkillLevel == 4)
|
||||
m_pDifficultyLabel->SetText("#asw_difficulty_insane");
|
||||
else if (nSkillLevel == 3)
|
||||
m_pDifficultyLabel->SetText("#asw_difficulty_hard");
|
||||
else if (nSkillLevel == 1)
|
||||
m_pDifficultyLabel->SetText("#asw_difficulty_easy");
|
||||
else
|
||||
m_pDifficultyLabel->SetText("#asw_difficulty_normal");
|
||||
const wchar_t *pDifficulty = NULL;
|
||||
switch( nSkillLevel )
|
||||
{
|
||||
case 1: pDifficulty = g_pVGuiLocalize->Find( "#asw_difficulty_easy" ); break;
|
||||
default:
|
||||
case 2: pDifficulty = g_pVGuiLocalize->Find( "#asw_difficulty_normal" ); break;
|
||||
case 3: pDifficulty = g_pVGuiLocalize->Find( "#asw_difficulty_hard" ); break;
|
||||
case 4: pDifficulty = g_pVGuiLocalize->Find( "#asw_difficulty_insane" ); break;
|
||||
case 5: pDifficulty = g_pVGuiLocalize->Find( "#asw_difficulty_imba" ); break;
|
||||
}
|
||||
if ( !pDifficulty )
|
||||
{
|
||||
pDifficulty = L"";
|
||||
}
|
||||
|
||||
if ( CAlienSwarm::IsOnslaught() )
|
||||
{
|
||||
wchar_t wszText[ 128 ];
|
||||
_snwprintf( wszText, sizeof( wszText ), L"%s %s", pDifficulty, g_pVGuiLocalize->FindSafe( "#nb_onslaught_title" ) );
|
||||
m_pDifficultyLabel->SetText( wszText );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pDifficultyLabel->SetText( pDifficulty );
|
||||
}
|
||||
|
||||
CASWHudMinimap *pMap = GET_HUDELEMENT( CASWHudMinimap );
|
||||
if ( pMap )
|
||||
|
|
|
@ -642,8 +642,8 @@ void CAI_BaseNPC::CleanupOnDeath( CBaseEntity *pCulprit, bool bFireDeathOutput )
|
|||
|
||||
RemoveActorFromScriptedScenes( this, false /*all scenes*/ );
|
||||
}
|
||||
else
|
||||
DevMsg( "Unexpected double-death-cleanup\n" );
|
||||
//else
|
||||
//DevMsg( "Unexpected double-death-cleanup\n" );
|
||||
}
|
||||
|
||||
void CAI_BaseNPC::SelectDeathPose( const CTakeDamageInfo &info )
|
||||
|
|
|
@ -1900,13 +1900,15 @@ void CServerGameDLL::GetMatchmakingTags( char *buf, size_t bufSize )
|
|||
#ifdef INFESTED_DLL
|
||||
extern ConVar asw_marine_ff_absorption;
|
||||
extern ConVar asw_sentry_friendly_fire_scale;
|
||||
extern ConVar asw_horde_override;
|
||||
extern ConVar asw_wanderer_override;
|
||||
extern ConVar asw_skill;
|
||||
|
||||
char * const bufBase = buf;
|
||||
int len = 0;
|
||||
|
||||
// hardcore friendly fire
|
||||
if ( asw_marine_ff_absorption.GetInt() != 1 || asw_sentry_friendly_fire_scale.GetFloat() != 0.0f )
|
||||
if ( CAlienSwarm::IsHardcoreFF() )
|
||||
{
|
||||
Q_strncpy( buf, "HardcoreFF,", bufSize );
|
||||
len = strlen( buf );
|
||||
|
@ -1914,6 +1916,15 @@ void CServerGameDLL::GetMatchmakingTags( char *buf, size_t bufSize )
|
|||
bufSize -= len;
|
||||
}
|
||||
|
||||
// onslaught
|
||||
if ( CAlienSwarm::IsOnslaught() )
|
||||
{
|
||||
Q_strncpy( buf, "Onslaught,", bufSize );
|
||||
len = strlen( buf );
|
||||
buf += len;
|
||||
bufSize -= len;
|
||||
}
|
||||
|
||||
// difficulty level
|
||||
const char *szSkill = "Normal,";
|
||||
switch( asw_skill.GetInt() )
|
||||
|
@ -1921,6 +1932,7 @@ void CServerGameDLL::GetMatchmakingTags( char *buf, size_t bufSize )
|
|||
case 1: szSkill = "Easy,"; break;
|
||||
case 3: szSkill = "Hard,"; break;
|
||||
case 4: szSkill = "Insane,"; break;
|
||||
case 5: szSkill = "Imba,"; break;
|
||||
}
|
||||
Q_strncpy( buf, szSkill, bufSize );
|
||||
len = strlen( buf );
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "datacache/imdlcache.h"
|
||||
#include "asw_tesla_trap.h"
|
||||
#include "sendprop_priorities.h"
|
||||
#include "asw_spawn_manager.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
@ -151,6 +152,7 @@ IMPLEMENT_AUTO_LIST( IAlienAutoList );
|
|||
CASW_Alien::CASW_Alien( void ) :
|
||||
m_BehaviorParms( DefLessFunc( const CUtlSymbol ) )
|
||||
{
|
||||
m_bRegisteredAsAwake = false;
|
||||
m_pszAlienModelName = NULL;
|
||||
m_bRunAtChasingPathEnds = true;
|
||||
m_bPerformingZigZag = false;
|
||||
|
@ -493,6 +495,32 @@ void CASW_Alien::UpdateSleepState(bool bInPVS)
|
|||
}
|
||||
}
|
||||
}
|
||||
if ( GetSleepState() == AISS_AWAKE )
|
||||
{
|
||||
if ( !m_bRegisteredAsAwake )
|
||||
{
|
||||
ASWSpawnManager()->OnAlienWokeUp( this );
|
||||
m_bRegisteredAsAwake = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_bRegisteredAsAwake )
|
||||
{
|
||||
ASWSpawnManager()->OnAlienSleeping( this );
|
||||
m_bRegisteredAsAwake = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CASW_Alien::UpdateOnRemove()
|
||||
{
|
||||
if ( m_bRegisteredAsAwake )
|
||||
{
|
||||
m_bRegisteredAsAwake = false;
|
||||
ASWSpawnManager()->OnAlienSleeping( this );
|
||||
}
|
||||
BaseClass::UpdateOnRemove();
|
||||
}
|
||||
|
||||
void CASW_Alien::SetDistSwarmSense( float flDistSense )
|
||||
|
|
|
@ -93,6 +93,8 @@ public:
|
|||
// make the aliens wake up when a marine gets within a certain distance
|
||||
void UpdateSleepState( bool bInPVS );
|
||||
void UpdateEfficiency( bool bInPVS );
|
||||
virtual void UpdateOnRemove();
|
||||
bool m_bRegisteredAsAwake;
|
||||
float m_fLastSleepCheckTime;
|
||||
bool m_bVisibleWhenAsleep;
|
||||
|
||||
|
|
|
@ -316,10 +316,13 @@ CBaseEntity* CASW_Base_Spawner::GetAlienOrderTarget()
|
|||
|
||||
bool CASW_Base_Spawner::IsValidOnThisSkillLevel()
|
||||
{
|
||||
if (m_iMinSkillLevel > 0 && ASWGameRules()->GetSkillLevel() < m_iMinSkillLevel)
|
||||
// treat difficulty 5 and 4 as the same
|
||||
int nSkillLevel = ASWGameRules()->GetSkillLevel();
|
||||
nSkillLevel = clamp<int>( nSkillLevel, 1, 4 );
|
||||
if (m_iMinSkillLevel > 0 && nSkillLevel < m_iMinSkillLevel)
|
||||
return false;
|
||||
if (m_iMaxSkillLevel > 0 && m_iMaxSkillLevel < 10
|
||||
&& ASWGameRules()->GetSkillLevel() > m_iMaxSkillLevel)
|
||||
&& nSkillLevel > m_iMaxSkillLevel)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -2745,7 +2745,9 @@ float CASW_Buzzer::GetMaxEnginePower()
|
|||
|
||||
if (ASWGameRules())
|
||||
{
|
||||
return ASWGameRules()->GetSkillLevel() + 0.1f;
|
||||
int nSkillLevel = ASWGameRules()->GetSkillLevel();
|
||||
nSkillLevel = clamp<int>( nSkillLevel, 1, 4 );
|
||||
return nSkillLevel + 0.1f;
|
||||
}
|
||||
return 2.0f;
|
||||
}
|
||||
|
|
|
@ -22,12 +22,12 @@ ConVar asw_director_debug("asw_director_debug", "0", FCVAR_CHEAT, "Displays dire
|
|||
extern ConVar asw_intensity_far_range;
|
||||
extern ConVar asw_spawning_enabled;
|
||||
|
||||
ConVar asw_horde_override( "asw_horde_override", "0", FCVAR_NONE, "Forces hordes to spawn" );
|
||||
ConVar asw_wanderer_override( "asw_wanderer_override", "0", FCVAR_NONE, "Forces wanderers to spawn" );
|
||||
ConVar asw_horde_interval_min("asw_horde_interval_min", "40", FCVAR_CHEAT, "Min time between hordes" );
|
||||
ConVar asw_horde_interval_max("asw_horde_interval_max", "60", FCVAR_CHEAT, "Min time between hordes" );
|
||||
extern ConVar asw_horde_override;
|
||||
extern ConVar asw_wanderer_override;
|
||||
ConVar asw_horde_interval_min("asw_horde_interval_min", "45", FCVAR_CHEAT, "Min time between hordes" );
|
||||
ConVar asw_horde_interval_max("asw_horde_interval_max", "65", FCVAR_CHEAT, "Min time between hordes" );
|
||||
ConVar asw_horde_size_min("asw_horde_size_min", "9", FCVAR_CHEAT, "Min horde size" );
|
||||
ConVar asw_horde_size_max("asw_horde_size_max", "12", FCVAR_CHEAT, "Max horde size" );
|
||||
ConVar asw_horde_size_max("asw_horde_size_max", "14", FCVAR_CHEAT, "Max horde size" );
|
||||
|
||||
ConVar asw_director_relaxed_min_time("asw_director_relaxed_min_time", "25", FCVAR_CHEAT, "Min time that director stops spawning aliens");
|
||||
ConVar asw_director_relaxed_max_time("asw_director_relaxed_max_time", "40", FCVAR_CHEAT, "Max time that director stops spawning aliens");
|
||||
|
@ -102,6 +102,11 @@ void CASW_Director::LevelInitPreEntity()
|
|||
void CASW_Director::LevelInitPostEntity()
|
||||
{
|
||||
Init();
|
||||
|
||||
if ( ASWSpawnManager() )
|
||||
{
|
||||
ASWSpawnManager()->LevelInitPostEntity();
|
||||
}
|
||||
}
|
||||
|
||||
void CASW_Director::FrameUpdatePreEntityThink()
|
||||
|
@ -250,60 +255,76 @@ void CASW_Director::MarineTookDamage( CASW_Marine *pMarine, const CTakeDamageInf
|
|||
|
||||
void CASW_Director::UpdateHorde()
|
||||
{
|
||||
bool bHordesEnabled = m_bHordesEnabled || asw_horde_override.GetBool();
|
||||
if ( !bHordesEnabled || !ASWSpawnManager() )
|
||||
return;
|
||||
|
||||
if ( asw_director_debug.GetInt() > 0 )
|
||||
{
|
||||
if ( m_bHordeInProgress )
|
||||
{
|
||||
engine->Con_NPrintf( 11, "Horde in progress. Left to spawn = %d", ASWSpawnManager()->GetHordeToSpawn() );
|
||||
}
|
||||
else
|
||||
{
|
||||
engine->Con_NPrintf( 11, "Next Horde due: %f", m_HordeTimer.GetRemainingTime() );
|
||||
}
|
||||
engine->Con_NPrintf( 12, "Next Horde due: %f", m_HordeTimer.GetRemainingTime() );
|
||||
|
||||
engine->Con_NPrintf( 15, "Awake aliens: %d\n", ASWSpawnManager()->GetAwakeAliens() );
|
||||
engine->Con_NPrintf( 16, "Awake drones: %d\n", ASWSpawnManager()->GetAwakeDrones() );
|
||||
}
|
||||
|
||||
if ( !m_bHordeInProgress )
|
||||
bool bHordesEnabled = m_bHordesEnabled || asw_horde_override.GetBool();
|
||||
if ( !bHordesEnabled || !ASWSpawnManager() )
|
||||
return;
|
||||
|
||||
if ( !m_HordeTimer.HasStarted() )
|
||||
{
|
||||
if ( !m_HordeTimer.HasStarted() )
|
||||
float flDuration = RandomFloat( asw_horde_interval_min.GetFloat(), asw_horde_interval_max.GetFloat() );
|
||||
if ( m_bFinale )
|
||||
{
|
||||
float flDuration = RandomFloat( asw_horde_interval_min.GetFloat(), asw_horde_interval_max.GetFloat() );
|
||||
if ( m_bFinale )
|
||||
{
|
||||
flDuration = RandomFloat( 5.0f, 10.0f );
|
||||
}
|
||||
Msg( "Will be spawning a horde in %f seconds\n", flDuration );
|
||||
m_HordeTimer.Start( flDuration );
|
||||
flDuration = RandomFloat( 5.0f, 10.0f );
|
||||
}
|
||||
else if ( m_HordeTimer.IsElapsed() )
|
||||
if ( asw_director_debug.GetBool() )
|
||||
{
|
||||
Msg( "Will be spawning a horde in %f seconds\n", flDuration );
|
||||
}
|
||||
m_HordeTimer.Start( flDuration );
|
||||
}
|
||||
else if ( m_HordeTimer.IsElapsed() )
|
||||
{
|
||||
if ( ASWSpawnManager()->GetAwakeDrones() < 25 )
|
||||
{
|
||||
int iNumAliens = RandomInt( asw_horde_size_min.GetInt(), asw_horde_size_max.GetInt() );
|
||||
|
||||
if ( ASWSpawnManager()->AddHorde( iNumAliens ) )
|
||||
{
|
||||
Msg("Created horde of size %d\n", iNumAliens);
|
||||
if ( asw_director_debug.GetBool() )
|
||||
{
|
||||
Msg("Created horde of size %d\n", iNumAliens);
|
||||
}
|
||||
m_bHordeInProgress = true;
|
||||
|
||||
if ( ASWGameRules() )
|
||||
{
|
||||
ASWGameRules()->BroadcastSound( "Spawner.Horde" );
|
||||
}
|
||||
m_HordeTimer.Invalidate();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_HordeTimer.Invalidate();
|
||||
// if we failed to find a horde position, try again shortly.
|
||||
m_HordeTimer.Start( RandomFloat( 10.0f, 16.0f ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if there are currently too many awake aliens, then wait 10 seconds before trying again
|
||||
m_HordeTimer.Start( 10.0f );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CASW_Director::OnHordeFinishedSpawning()
|
||||
{
|
||||
Msg("Horde finishes spawning\n");
|
||||
if ( asw_director_debug.GetBool() )
|
||||
{
|
||||
Msg("Horde finishes spawning\n");
|
||||
}
|
||||
m_bHordeInProgress = false;
|
||||
m_HordeTimer.Invalidate();
|
||||
}
|
||||
|
||||
void CASW_Director::UpdateSpawningState()
|
||||
|
@ -418,7 +439,10 @@ void CASW_Director::UpdateWanderers()
|
|||
|
||||
if ( ASWSpawnManager() )
|
||||
{
|
||||
ASWSpawnManager()->AddAlien();
|
||||
if ( ASWSpawnManager()->GetAwakeDrones() < 20 )
|
||||
{
|
||||
ASWSpawnManager()->AddAlien();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -496,4 +520,36 @@ void CASW_Director::UpdateMarineInsideEscapeRoom( CASW_Marine *pMarine )
|
|||
}
|
||||
|
||||
m_bFiredEscapeRoom = true;
|
||||
}
|
||||
|
||||
void CASW_Director::OnMissionStarted()
|
||||
{
|
||||
// if we have wanders turned on, spawn a couple of encounters
|
||||
if ( asw_wanderer_override.GetBool() && ASWGameRules() )
|
||||
{
|
||||
ASWSpawnManager()->SpawnRandomShieldbug();
|
||||
|
||||
int nParasites = 1;
|
||||
switch( ASWGameRules()->GetSkillLevel() )
|
||||
{
|
||||
case 1: nParasites = RandomInt( 4, 6 ); break;
|
||||
default:
|
||||
case 2: nParasites = RandomInt( 4, 6 ); break;
|
||||
case 3: nParasites = RandomInt( 5, 7 ); break;
|
||||
case 4: nParasites = RandomInt( 5, 9 ); break;
|
||||
case 5: nParasites = RandomInt( 5, 10 ); break;
|
||||
}
|
||||
while ( nParasites > 0 )
|
||||
{
|
||||
int nParasitesInThisPack = RandomInt( 3, 6 );
|
||||
if ( ASWSpawnManager()->SpawnRandomParasitePack( nParasitesInThisPack ) )
|
||||
{
|
||||
nParasites -= nParasitesInThisPack;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -68,6 +68,8 @@ public:
|
|||
void OnMarineStartedHack( CASW_Marine *pMarine, CBaseEntity *pComputer );
|
||||
void UpdateMarineInsideEscapeRoom( CASW_Marine *pMarine );
|
||||
|
||||
void OnMissionStarted();
|
||||
|
||||
// Spawning hordes of aliens
|
||||
void OnHordeFinishedSpawning();
|
||||
|
||||
|
|
|
@ -306,6 +306,7 @@ float CASW_Drone_Advanced::GetIdealSpeed() const
|
|||
|
||||
switch (ASWGameRules()->GetSkillLevel())
|
||||
{
|
||||
case 5: boost *= asw_alien_speed_scale_insane.GetFloat(); break;
|
||||
case 4: boost *= asw_alien_speed_scale_insane.GetFloat(); break;
|
||||
case 3: boost *= asw_alien_speed_scale_hard.GetFloat(); break;
|
||||
case 2: boost *= asw_alien_speed_scale_normal.GetFloat(); break;
|
||||
|
|
|
@ -297,7 +297,7 @@ void CASW_Egg::AnimThink( void )
|
|||
}
|
||||
else
|
||||
{
|
||||
if (ASWGameRules() && ASWGameRules()->GetSkillLevel() == 4 )
|
||||
if (ASWGameRules() && ASWGameRules()->GetSkillLevel() >= 4 )
|
||||
{
|
||||
m_fNextMarineCheckTime = gpGlobals->curtime + 1.5f;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,9 @@ void CServerGameClients::GetPlayerLimits( int& minplayers, int& maxplayers, int
|
|||
|
||||
void CServerGameDLL::LevelInit_ParseAllEntities( const char *pMapEntities )
|
||||
{
|
||||
// precache even if not in the level, for onslaught mode
|
||||
UTIL_PrecacheOther( "asw_shieldbug" );
|
||||
UTIL_PrecacheOther( "asw_parasite" );
|
||||
}
|
||||
|
||||
bool g_bOfflineGame = false;
|
||||
|
@ -122,6 +125,38 @@ void CServerGameDLL::ApplyGameSettings( KeyValues *pKV )
|
|||
{
|
||||
asw_skill.SetValue( 4 );
|
||||
}
|
||||
else if ( !Q_stricmp( szDifficulty, "imba" ) )
|
||||
{
|
||||
asw_skill.SetValue( 5 );
|
||||
}
|
||||
|
||||
extern ConVar asw_sentry_friendly_fire_scale;
|
||||
extern ConVar asw_marine_ff_absorption;
|
||||
int nHardcoreFF = pKV->GetInt( "game/hardcoreFF", 0 );
|
||||
if ( nHardcoreFF == 1 )
|
||||
{
|
||||
asw_sentry_friendly_fire_scale.SetValue( 1.0f );
|
||||
asw_marine_ff_absorption.SetValue( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
asw_sentry_friendly_fire_scale.SetValue( 0.0f );
|
||||
asw_marine_ff_absorption.SetValue( 1 );
|
||||
}
|
||||
|
||||
extern ConVar asw_horde_override;
|
||||
extern ConVar asw_wanderer_override;
|
||||
int nOnslaught = pKV->GetInt( "game/onslaught", 0 );
|
||||
if ( nOnslaught == 1 )
|
||||
{
|
||||
asw_horde_override.SetValue( 1 );
|
||||
asw_wanderer_override.SetValue( 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
asw_horde_override.SetValue( 0 );
|
||||
asw_wanderer_override.SetValue( 0 );
|
||||
}
|
||||
|
||||
char const *szMapCommand = pKV->GetString( "map/mapcommand", "map" );
|
||||
|
||||
|
|
|
@ -177,7 +177,7 @@ void CASW_Hack_Computer::SelectHackOption(int i)
|
|||
diff_factor = 1.55f;
|
||||
else if (iSkill == 3)
|
||||
diff_factor = 1.50f;
|
||||
else if (iSkill == 4)
|
||||
else if (iSkill >= 4)
|
||||
diff_factor = 1.45f;
|
||||
// estimate the time for a fast hack
|
||||
// try, time taken for each column to rotate through twice
|
||||
|
|
|
@ -144,6 +144,7 @@ const char* CASW_Map_Scores::GetBestKillsKeyName(int iSkill)
|
|||
case 1: return "BestKillsEasy"; break;
|
||||
case 3: return "BestKillsHard"; break;
|
||||
case 4: return "BestKillsInsane"; break;
|
||||
case 5: return "BestKillsImba"; break;
|
||||
default: break;
|
||||
}
|
||||
return "BestKillsNormal";
|
||||
|
@ -156,6 +157,7 @@ const char* CASW_Map_Scores::GetBestTimeKeyName(int iSkill)
|
|||
case 1: return "BestTimeEasy"; break;
|
||||
case 3: return "BestTimeHard"; break;
|
||||
case 4: return "BestTimeInsane"; break;
|
||||
case 5: return "BestTimeImba"; break;
|
||||
default: break;
|
||||
}
|
||||
return "BestTimeNormal";
|
||||
|
|
|
@ -345,13 +345,6 @@ BEGIN_DATADESC( CASW_Marine )
|
|||
DEFINE_FIELD( m_bPowerupExpires, FIELD_BOOLEAN ),
|
||||
END_DATADESC()
|
||||
|
||||
void UpdateMatchmakingTags();
|
||||
|
||||
static void FriendlyFireCallback( IConVar *pConVar, const char *pOldValue, float flOldValue )
|
||||
{
|
||||
UpdateMatchmakingTags();
|
||||
}
|
||||
|
||||
extern ConVar weapon_showproficiency;
|
||||
extern ConVar asw_leadership_radius;
|
||||
extern ConVar asw_buzzer_poison_duration;
|
||||
|
@ -381,7 +374,6 @@ ConVar asw_marine_ff("asw_marine_ff", "1", FCVAR_CHEAT, "Marine friendly fire se
|
|||
ConVar asw_marine_ff_guard_time("asw_marine_ff_guard_time", "5.0", FCVAR_CHEAT, "Amount of time firing is disabled for when activating friendly fire guard");
|
||||
ConVar asw_marine_ff_dmg_base("asw_marine_ff_dmg_base", "1.0", FCVAR_CHEAT, "Amount of friendly fire damage on mission difficulty 5");
|
||||
ConVar asw_marine_ff_dmg_step("asw_marine_ff_dmg_step", "0.2", FCVAR_CHEAT, "Amount friendly fire damage is modified per mission difficuly level away from 5");
|
||||
ConVar asw_marine_ff_absorption("asw_marine_ff_absorption", "1", FCVAR_NONE, "Friendly fire absorption style (0=none 1=ramp up 2=ramp down)", FriendlyFireCallback );
|
||||
ConVar asw_marine_ff_absorption_decay_rate("asw_marine_ff_absorption_decay_rate", "0.33f", FCVAR_CHEAT, "Rate of FF absorption decay");
|
||||
ConVar asw_marine_ff_absorption_build_rate("asw_marine_ff_absorption_build_rate", "0.25f", FCVAR_CHEAT, "Rate of FF absorption decay build up when being shot by friendlies");
|
||||
ConVar asw_marine_burn_time_easy("asw_marine_burn_time_easy", "6", FCVAR_CHEAT, "Amount of time marine burns for when ignited on easy difficulty");
|
||||
|
@ -395,7 +387,8 @@ ConVar asw_marine_special_idle_chatter_chance("asw_marine_special_idle_chatter_c
|
|||
ConVar asw_force_ai_fire("asw_force_ai_fire", "0", FCVAR_CHEAT, "Forces all AI marines to fire constantly");
|
||||
ConVar asw_realistic_death_chatter("asw_realistic_death_chatter", "0", FCVAR_NONE, "If true, only 1 nearby marine will shout about marine deaths");
|
||||
ConVar asw_god( "asw_god", "0", FCVAR_CHEAT, "Set to 1 to make marines invulnerable" );
|
||||
ConVar asw_sentry_friendly_fire_scale( "asw_sentry_friendly_fire_scale", "0", FCVAR_NONE, "Damage scale for sentry gun friendly fire", FriendlyFireCallback );
|
||||
extern ConVar asw_sentry_friendly_fire_scale;
|
||||
extern ConVar asw_marine_ff_absorption;
|
||||
ConVar asw_movement_direction_tolerance( "asw_movement_direction_tolerance", "30.0", FCVAR_CHEAT );
|
||||
ConVar asw_movement_direction_interval( "asw_movement_direction_interval", "0.5", FCVAR_CHEAT );
|
||||
|
||||
|
@ -4058,7 +4051,7 @@ void CASW_Marine::ASW_Ignite( float flFlameLifetime, float flSize, CBaseEntity *
|
|||
flFlameLifetime *= asw_marine_burn_time_normal.GetFloat();
|
||||
else if (iDiff == 3)
|
||||
flFlameLifetime *= asw_marine_burn_time_hard.GetFloat();
|
||||
else if (iDiff == 4)
|
||||
else if (iDiff == 4 || iDiff == 5)
|
||||
flFlameLifetime *= asw_marine_burn_time_insane.GetFloat();
|
||||
|
||||
if ( m_flFirstBurnTime == 0 )
|
||||
|
@ -4127,7 +4120,8 @@ bool CASW_Marine::AllowedToIgnite( void )
|
|||
if ( m_iJumpJetting.Get() != 0 )
|
||||
return false;
|
||||
|
||||
if ( m_flFirstBurnTime > 0 && (gpGlobals->curtime - m_flFirstBurnTime) >= asw_marine_time_until_ignite.GetFloat() )
|
||||
float flBurnTime = ( asw_marine_ff_absorption.GetInt() > 0 ) ? asw_marine_time_until_ignite.GetFloat() : 0.2f;
|
||||
if ( m_flFirstBurnTime > 0 && (gpGlobals->curtime - m_flFirstBurnTime) >= flBurnTime )
|
||||
return true;
|
||||
|
||||
// don't ignite, but play a flesh burn sound if we aren't on fire already
|
||||
|
|
|
@ -169,6 +169,7 @@ float CASW_Marine::GetCloseCombatSightRange()
|
|||
case 2: return ASW_CLOSE_COMBAT_SIGHT_RANGE_NORMAL; break;
|
||||
case 3: return ASW_CLOSE_COMBAT_SIGHT_RANGE_HARD; break;
|
||||
case 4:
|
||||
case 5:
|
||||
default: return ASW_CLOSE_COMBAT_SIGHT_RANGE_INSANE; break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1089,6 +1089,7 @@ void CASW_Parasite::UpdatePlaybackRate()
|
|||
float boost = asw_parasite_speedboost.GetFloat();
|
||||
switch (ASWGameRules()->GetSkillLevel())
|
||||
{
|
||||
case 5: boost *= asw_alien_speed_scale_insane.GetFloat(); break;
|
||||
case 4: boost *= asw_alien_speed_scale_insane.GetFloat(); break;
|
||||
case 3: boost *= asw_alien_speed_scale_hard.GetFloat(); break;
|
||||
case 2: boost *= asw_alien_speed_scale_normal.GetFloat(); break;
|
||||
|
|
|
@ -299,7 +299,7 @@ void ASW_DrawAwakeAI()
|
|||
int iVEfficient = 0;
|
||||
int iSEfficient = 0;
|
||||
int iNormal = 0;
|
||||
int nprintIndex = 0;
|
||||
int nprintIndex = 18;
|
||||
engine->Con_NPrintf( nprintIndex, "AI (awake/asleep) (normal/efficient/very efficient/super efficient/dormant)");
|
||||
nprintIndex++;
|
||||
engine->Con_NPrintf( nprintIndex, "================================");
|
||||
|
@ -789,6 +789,76 @@ bool CASW_Player::ClientCommand( const CCommand &args )
|
|||
ASWGameRules()->RequestSkillDown(this);
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( pcmd, "cl_hardcore_ff") )
|
||||
{
|
||||
if ( args.ArgC() < 2 )
|
||||
{
|
||||
Warning("Player sent a bad cl_hardcore_ff command\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ASWGameResource() && ASWGameResource()->GetLeader() == this )
|
||||
{
|
||||
bool bOldHardcoreMode = CAlienSwarm::IsHardcoreFF();
|
||||
int nHardcore = atoi( args[1] );
|
||||
nHardcore = clamp<int>( nHardcore, 0, 1 );
|
||||
|
||||
extern ConVar asw_sentry_friendly_fire_scale;
|
||||
extern ConVar asw_marine_ff_absorption;
|
||||
asw_sentry_friendly_fire_scale.SetValue( nHardcore );
|
||||
asw_marine_ff_absorption.SetValue( 1 - nHardcore );
|
||||
|
||||
if ( CAlienSwarm::IsHardcoreFF() != bOldHardcoreMode )
|
||||
{
|
||||
CReliableBroadcastRecipientFilter filter;
|
||||
filter.RemoveRecipient( this ); // notify everyone except the player changing the setting
|
||||
if ( nHardcore > 0 )
|
||||
{
|
||||
UTIL_ClientPrintFilter( filter, ASW_HUD_PRINTTALKANDCONSOLE, "#asw_enabled_hardcoreff", GetPlayerName() );
|
||||
}
|
||||
else
|
||||
{
|
||||
UTIL_ClientPrintFilter( filter, ASW_HUD_PRINTTALKANDCONSOLE, "#asw_disabled_hardcoreff", GetPlayerName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( pcmd, "cl_onslaught") )
|
||||
{
|
||||
if ( args.ArgC() < 2 )
|
||||
{
|
||||
Warning("Player sent a bad cl_onslaught command\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ASWGameResource() && ASWGameResource()->GetLeader() == this )
|
||||
{
|
||||
bool bOldOnslaughtMode = CAlienSwarm::IsOnslaught();
|
||||
int nOnslaught = atoi( args[1] );
|
||||
nOnslaught = clamp<int>( nOnslaught, 0, 1 );
|
||||
|
||||
extern ConVar asw_horde_override;
|
||||
extern ConVar asw_wanderer_override;
|
||||
asw_horde_override.SetValue( nOnslaught );
|
||||
asw_wanderer_override.SetValue( nOnslaught );
|
||||
|
||||
if ( CAlienSwarm::IsOnslaught() != bOldOnslaughtMode )
|
||||
{
|
||||
CReliableBroadcastRecipientFilter filter;
|
||||
filter.RemoveRecipient( this ); // notify everyone except the player changing the setting
|
||||
if ( nOnslaught > 0 )
|
||||
{
|
||||
UTIL_ClientPrintFilter( filter, ASW_HUD_PRINTTALKANDCONSOLE, "#asw_enabled_onslaught", GetPlayerName() );
|
||||
}
|
||||
else
|
||||
{
|
||||
UTIL_ClientPrintFilter( filter, ASW_HUD_PRINTTALKANDCONSOLE, "#asw_disabled_onslaught", GetPlayerName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if ( FStrEq( pcmd, "cl_fixedskills") )
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -1418,6 +1418,7 @@ void CASW_Queen::SetHealthByDifficultyLevel()
|
|||
case 2: health = asw_queen_health_normal.GetInt(); break;
|
||||
case 3: health = asw_queen_health_hard.GetInt(); break;
|
||||
case 4: health = asw_queen_health_insane.GetInt(); break;
|
||||
case 5: health = asw_queen_health_insane.GetInt(); break;
|
||||
default: 5000;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include "asw_objective_escape.h"
|
||||
#include "triggers.h"
|
||||
#include "datacache/imdlcache.h"
|
||||
#include "ai_link.h"
|
||||
#include "asw_alien.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
@ -33,12 +35,10 @@ ConVar asw_batch_interval("asw_batch_interval", "5", FCVAR_CHEAT, "Time between
|
|||
ConVar asw_candidate_interval("asw_candidate_interval", "1.0", FCVAR_CHEAT, "Interval between updating candidate spawning nodes");
|
||||
ConVar asw_horde_class( "asw_horde_class", "asw_drone", FCVAR_CHEAT, "Alien class used when spawning hordes" );
|
||||
|
||||
// TODO: Notify the director when a horde is all killed?
|
||||
// - currently you could try to spawn a 2nd horde while the first is still sitting out in the world
|
||||
|
||||
CASW_Spawn_Manager::CASW_Spawn_Manager()
|
||||
{
|
||||
|
||||
m_nAwakeAliens = 0;
|
||||
m_nAwakeDrones = 0;
|
||||
}
|
||||
|
||||
CASW_Spawn_Manager::~CASW_Spawn_Manager()
|
||||
|
@ -87,6 +87,8 @@ ASW_Alien_Class_Entry* CASW_Spawn_Manager::GetAlienClass( int i )
|
|||
|
||||
void CASW_Spawn_Manager::LevelInitPreEntity()
|
||||
{
|
||||
m_nAwakeAliens = 0;
|
||||
m_nAwakeDrones = 0;
|
||||
// init alien classes
|
||||
for ( int i = 0; i < GetNumAlienClasses(); i++ )
|
||||
{
|
||||
|
@ -109,6 +111,24 @@ void CASW_Spawn_Manager::LevelInitPostEntity()
|
|||
FindEscapeTriggers();
|
||||
}
|
||||
|
||||
void CASW_Spawn_Manager::OnAlienWokeUp( CASW_Alien *pAlien )
|
||||
{
|
||||
m_nAwakeAliens++;
|
||||
if ( pAlien && pAlien->Classify() == CLASS_ASW_DRONE )
|
||||
{
|
||||
m_nAwakeDrones++;
|
||||
}
|
||||
}
|
||||
|
||||
void CASW_Spawn_Manager::OnAlienSleeping( CASW_Alien *pAlien )
|
||||
{
|
||||
m_nAwakeAliens--;
|
||||
if ( pAlien && pAlien->Classify() == CLASS_ASW_DRONE )
|
||||
{
|
||||
m_nAwakeDrones--;
|
||||
}
|
||||
}
|
||||
|
||||
// finds all trigger_multiples linked to asw_objective_escape entities
|
||||
void CASW_Spawn_Manager::FindEscapeTriggers()
|
||||
{
|
||||
|
@ -180,7 +200,7 @@ void CASW_Spawn_Manager::Update()
|
|||
if ( m_vecHordePosition != vec3_origin && ( !m_batchInterval.HasStarted() || m_batchInterval.IsElapsed() ) )
|
||||
{
|
||||
int iToSpawn = MIN( m_iHordeToSpawn, asw_max_alien_batch.GetInt() );
|
||||
int iSpawned = SpawnAlienBatch( asw_horde_class.GetString(), iToSpawn, m_vecHordePosition, m_angHordeAngle, MARINE_NEAR_DISTANCE );
|
||||
int iSpawned = SpawnAlienBatch( asw_horde_class.GetString(), iToSpawn, m_vecHordePosition, m_angHordeAngle, 0 );
|
||||
m_iHordeToSpawn -= iSpawned;
|
||||
if ( m_iHordeToSpawn <= 0 )
|
||||
{
|
||||
|
@ -189,6 +209,10 @@ void CASW_Spawn_Manager::Update()
|
|||
}
|
||||
else if ( iSpawned == 0 ) // if we failed to spawn any aliens, then try to find a new horde location
|
||||
{
|
||||
if ( asw_director_debug.GetBool() )
|
||||
{
|
||||
Msg( "Horde failed to spawn any aliens, trying new horde position.\n" );
|
||||
}
|
||||
if ( !FindHordePosition() ) // if we failed to find a new location, just abort this horde
|
||||
{
|
||||
m_iHordeToSpawn = 0;
|
||||
|
@ -198,6 +222,17 @@ void CASW_Spawn_Manager::Update()
|
|||
}
|
||||
m_batchInterval.Start( asw_batch_interval.GetFloat() );
|
||||
}
|
||||
else if ( m_vecHordePosition == vec3_origin )
|
||||
{
|
||||
Msg( "Warning: Had horde to spawn but no position, clearing.\n" );
|
||||
m_iHordeToSpawn = 0;
|
||||
ASWDirector()->OnHordeFinishedSpawning();
|
||||
}
|
||||
}
|
||||
|
||||
if ( asw_director_debug.GetBool() )
|
||||
{
|
||||
engine->Con_NPrintf( 14, "SM: Batch interval: %f pos = %f %f %f\n", m_batchInterval.HasStarted() ? m_batchInterval.GetRemainingTime() : -1, VectorExpand( m_vecHordePosition ) );
|
||||
}
|
||||
|
||||
if ( m_iAliensToSpawn > 0 )
|
||||
|
@ -209,6 +244,10 @@ void CASW_Spawn_Manager::Update()
|
|||
|
||||
void CASW_Spawn_Manager::AddAlien()
|
||||
{
|
||||
// don't stock up more than 10 wanderers at once
|
||||
if ( m_iAliensToSpawn > 10 )
|
||||
return;
|
||||
|
||||
m_iAliensToSpawn++;
|
||||
}
|
||||
|
||||
|
@ -236,7 +275,7 @@ bool CASW_Spawn_Manager::SpawnAlientAtRandomNode()
|
|||
Vector vecMins, vecMaxs;
|
||||
GetAlienBounds( szAlienClass, vecMins, vecMaxs );
|
||||
|
||||
int iMaxTries = 10;
|
||||
int iMaxTries = 1;
|
||||
for ( int i=0 ; i<iMaxTries ; i++ )
|
||||
{
|
||||
int iChosen = RandomInt( 0, candidateNodes.Count() - 1);
|
||||
|
@ -252,7 +291,13 @@ bool CASW_Spawn_Manager::SpawnAlientAtRandomNode()
|
|||
// check if there's a route from this node to the marine(s)
|
||||
AI_Waypoint_t *pRoute = ASWPathUtils()->BuildRoute( pNode->GetPosition( CANDIDATE_ALIEN_HULL ), pMarine->GetAbsOrigin(), NULL, 100 );
|
||||
if ( !pRoute )
|
||||
{
|
||||
if ( asw_director_debug.GetBool() )
|
||||
{
|
||||
NDebugOverlay::Cross3D( pNode->GetOrigin(), 10.0f, 255, 128, 0, true, 20.0f );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( bNorth && UTIL_ASW_DoorBlockingRoute( pRoute, true ) )
|
||||
{
|
||||
|
@ -265,9 +310,27 @@ bool CASW_Spawn_Manager::SpawnAlientAtRandomNode()
|
|||
{
|
||||
if ( SpawnAlienAt( szAlienClass, vecSpawnPos, vec3_angle ) )
|
||||
{
|
||||
if ( asw_director_debug.GetBool() )
|
||||
{
|
||||
NDebugOverlay::Cross3D( vecSpawnPos, 25.0f, 255, 255, 255, true, 20.0f );
|
||||
float flDist;
|
||||
CASW_Marine *pMarine = UTIL_ASW_NearestMarine( vecSpawnPos, flDist );
|
||||
if ( pMarine )
|
||||
{
|
||||
NDebugOverlay::Line( pMarine->GetAbsOrigin(), vecSpawnPos, 64, 64, 64, true, 60.0f );
|
||||
}
|
||||
}
|
||||
DeleteRoute( pRoute );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( asw_director_debug.GetBool() )
|
||||
{
|
||||
NDebugOverlay::Cross3D( vecSpawnPos, 25.0f, 255, 0, 0, true, 20.0f );
|
||||
}
|
||||
}
|
||||
DeleteRoute( pRoute );
|
||||
}
|
||||
return false;
|
||||
|
@ -288,7 +351,13 @@ bool CASW_Spawn_Manager::AddHorde( int iHordeSize )
|
|||
{
|
||||
if ( asw_director_debug.GetBool() )
|
||||
{
|
||||
NDebugOverlay::Cross3D( m_vecHordePosition, 50.0f, 255, 128, 0, true, 40.0f );
|
||||
NDebugOverlay::Cross3D( m_vecHordePosition, 50.0f, 255, 128, 0, true, 60.0f );
|
||||
float flDist;
|
||||
CASW_Marine *pMarine = UTIL_ASW_NearestMarine( m_vecHordePosition, flDist );
|
||||
if ( pMarine )
|
||||
{
|
||||
NDebugOverlay::Line( pMarine->GetAbsOrigin(), m_vecHordePosition, 255, 128, 0, true, 60.0f );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -378,11 +447,19 @@ void CASW_Spawn_Manager::UpdateCandidateNodes()
|
|||
|
||||
if ( vecPos.y >= vecSouthMarine.y )
|
||||
{
|
||||
if ( asw_director_debug.GetInt() == 3 )
|
||||
{
|
||||
NDebugOverlay::Box( vecPos, -Vector( 5, 5, 5 ), Vector( 5, 5, 5 ), 32, 32, 128, 10, 60.0f );
|
||||
}
|
||||
m_northCandidateNodes.AddToTail( i );
|
||||
}
|
||||
if ( vecPos.y <= vecNorthMarine.y )
|
||||
{
|
||||
m_southCandidateNodes.AddToTail( i );
|
||||
if ( asw_director_debug.GetInt() == 3 )
|
||||
{
|
||||
NDebugOverlay::Box( vecPos, -Vector( 5, 5, 5 ), Vector( 5, 5, 5 ), 128, 32, 32, 10, 60.0f );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -410,9 +487,15 @@ bool CASW_Spawn_Manager::FindHordePosition()
|
|||
CUtlVector<int> &candidateNodes = bNorth ? m_northCandidateNodes : m_southCandidateNodes;
|
||||
|
||||
if ( candidateNodes.Count() <= 0 )
|
||||
{
|
||||
if ( asw_director_debug.GetBool() )
|
||||
{
|
||||
Msg( " Failed to find horde pos as there are no candidate nodes\n" );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int iMaxTries = 10;
|
||||
int iMaxTries = 3;
|
||||
for ( int i=0 ; i<iMaxTries ; i++ )
|
||||
{
|
||||
int iChosen = RandomInt( 0, candidateNodes.Count() - 1);
|
||||
|
@ -423,24 +506,56 @@ bool CASW_Spawn_Manager::FindHordePosition()
|
|||
float flDistance = 0;
|
||||
CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>(UTIL_ASW_NearestMarine( pNode->GetPosition( CANDIDATE_ALIEN_HULL ), flDistance ));
|
||||
if ( !pMarine )
|
||||
{
|
||||
if ( asw_director_debug.GetBool() )
|
||||
{
|
||||
Msg( " Failed to find horde pos as there is no nearest marine\n" );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if there's a route from this node to the marine(s)
|
||||
AI_Waypoint_t *pRoute = ASWPathUtils()->BuildRoute( pNode->GetPosition( CANDIDATE_ALIEN_HULL ), pMarine->GetAbsOrigin(), NULL, 100 );
|
||||
if ( !pRoute )
|
||||
{
|
||||
if ( asw_director_debug.GetInt() >= 2 )
|
||||
{
|
||||
Msg( " Discarding horde node %d as there's no route.\n", iChosen );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( bNorth && UTIL_ASW_DoorBlockingRoute( pRoute, true ) )
|
||||
{
|
||||
if ( asw_director_debug.GetInt() >= 2 )
|
||||
{
|
||||
Msg( " Discarding horde node %d as there's a door in the way.\n", iChosen );
|
||||
}
|
||||
DeleteRoute( pRoute );
|
||||
continue;
|
||||
}
|
||||
|
||||
m_vecHordePosition = pNode->GetPosition( CANDIDATE_ALIEN_HULL ) + Vector( 0, 0, 32 );
|
||||
|
||||
// spawn facing the nearest marine
|
||||
Vector vecDir = pMarine->GetAbsOrigin() - m_vecHordePosition;
|
||||
vecDir.z = 0;
|
||||
vecDir.NormalizeInPlace();
|
||||
VectorAngles( vecDir, m_angHordeAngle );
|
||||
|
||||
if ( asw_director_debug.GetInt() >= 2 )
|
||||
{
|
||||
Msg( " Accepting horde node %d.\n", iChosen );
|
||||
}
|
||||
DeleteRoute( pRoute );
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( asw_director_debug.GetBool() )
|
||||
{
|
||||
Msg( " Failed to find horde pos as we tried 3 times to build routes to possible locations, but failed\n" );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -485,8 +600,9 @@ bool CASW_Spawn_Manager::GetAlienBounds( string_t iszAlienClass, Vector &vecMins
|
|||
}
|
||||
|
||||
// spawn a group of aliens at the target point
|
||||
int CASW_Spawn_Manager::SpawnAlienBatch( const char* szAlienClass, int iNumAliens, const Vector &vecPosition, const QAngle &angle, float flMarinesBeyondDist )
|
||||
int CASW_Spawn_Manager::SpawnAlienBatch( const char* szAlienClass, int iNumAliens, const Vector &vecPosition, const QAngle &angFacing, float flMarinesBeyondDist )
|
||||
{
|
||||
|
||||
int iSpawned = 0;
|
||||
bool bCheckGround = true;
|
||||
Vector vecMins = NAI_Hull::Mins(HULL_MEDIUMBIG);
|
||||
|
@ -499,7 +615,7 @@ int CASW_Spawn_Manager::SpawnAlienBatch( const char* szAlienClass, int iNumAlien
|
|||
// spawn one in the middle
|
||||
if ( ValidSpawnPoint( vecPosition, vecMins, vecMaxs, bCheckGround, flMarinesBeyondDist ) )
|
||||
{
|
||||
if ( SpawnAlienAt( szAlienClass, vecPosition, angle ) )
|
||||
if ( SpawnAlienAt( szAlienClass, vecPosition, angFacing ) )
|
||||
iSpawned++;
|
||||
}
|
||||
|
||||
|
@ -507,6 +623,8 @@ int CASW_Spawn_Manager::SpawnAlienBatch( const char* szAlienClass, int iNumAlien
|
|||
Vector vecNewPos = vecPosition;
|
||||
for ( int i=1; i<=5 && iSpawned < iNumAliens; i++ )
|
||||
{
|
||||
QAngle angle = angFacing;
|
||||
angle[YAW] += RandomFloat( -20, 20 );
|
||||
// spawn aliens along top of box
|
||||
for ( int x=-i; x<=i && iSpawned < iNumAliens; x++ )
|
||||
{
|
||||
|
@ -591,6 +709,14 @@ CBaseEntity* CASW_Spawn_Manager::SpawnAlienAt(const char* szAlienClass, const Ve
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// have drones unburrow by default, so we don't worry so much about them spawning onscreen
|
||||
if ( !Q_strcmp( szAlienClass, "asw_drone" ) )
|
||||
{
|
||||
pSpawnable->StartBurrowed();
|
||||
pSpawnable->SetUnburrowIdleActivity( NULL_STRING );
|
||||
pSpawnable->SetUnburrowActivity( NULL_STRING );
|
||||
}
|
||||
|
||||
DispatchSpawn( pEntity );
|
||||
pEntity->Activate();
|
||||
|
||||
|
@ -663,6 +789,308 @@ void CASW_Spawn_Manager::DeleteRoute( AI_Waypoint_t *pWaypointList )
|
|||
}
|
||||
}
|
||||
|
||||
bool CASW_Spawn_Manager::SpawnRandomShieldbug()
|
||||
{
|
||||
int iNumNodes = g_pBigAINet->NumNodes();
|
||||
if ( iNumNodes < 6 )
|
||||
return false;
|
||||
|
||||
int nHull = HULL_WIDE_SHORT;
|
||||
CUtlVector<CASW_Open_Area*> aAreas;
|
||||
for ( int i = 0; i < 6; i++ )
|
||||
{
|
||||
CAI_Node *pNode = NULL;
|
||||
int nTries = 0;
|
||||
while ( nTries < 5 && ( !pNode || pNode->GetType() != NODE_GROUND ) )
|
||||
{
|
||||
pNode = g_pBigAINet->GetNode( RandomInt( 0, iNumNodes ) );
|
||||
nTries++;
|
||||
}
|
||||
|
||||
if ( pNode )
|
||||
{
|
||||
CASW_Open_Area *pArea = FindNearbyOpenArea( pNode->GetOrigin(), HULL_MEDIUMBIG );
|
||||
if ( pArea && pArea->m_nTotalLinks > 30 )
|
||||
{
|
||||
// test if there's room to spawn a shieldbug at that spot
|
||||
if ( ValidSpawnPoint( pArea->m_pNode->GetPosition( nHull ), NAI_Hull::Mins( nHull ), NAI_Hull::Maxs( nHull ), true, false ) )
|
||||
{
|
||||
aAreas.AddToTail( pArea );
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pArea;
|
||||
}
|
||||
}
|
||||
}
|
||||
// stop searching once we have 3 acceptable candidates
|
||||
if ( aAreas.Count() >= 3 )
|
||||
break;
|
||||
}
|
||||
|
||||
// find area with the highest connectivity
|
||||
CASW_Open_Area *pBestArea = NULL;
|
||||
for ( int i = 0; i < aAreas.Count(); i++ )
|
||||
{
|
||||
CASW_Open_Area *pArea = aAreas[i];
|
||||
if ( !pBestArea || pArea->m_nTotalLinks > pBestArea->m_nTotalLinks )
|
||||
{
|
||||
pBestArea = pArea;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pBestArea )
|
||||
{
|
||||
CBaseEntity *pAlien = SpawnAlienAt( "asw_shieldbug", pBestArea->m_pNode->GetPosition( nHull ), RandomAngle( 0, 360 ) );
|
||||
IASW_Spawnable_NPC *pSpawnable = dynamic_cast<IASW_Spawnable_NPC*>( pAlien );
|
||||
if ( pSpawnable )
|
||||
{
|
||||
pSpawnable->SetAlienOrders(AOT_SpreadThenHibernate, vec3_origin, NULL);
|
||||
}
|
||||
aAreas.PurgeAndDeleteElements();
|
||||
return true;
|
||||
}
|
||||
|
||||
aAreas.PurgeAndDeleteElements();
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector TraceToGround( const Vector &vecPos )
|
||||
{
|
||||
trace_t tr;
|
||||
UTIL_TraceLine( vecPos + Vector( 0, 0, 100 ), vecPos, MASK_NPCSOLID, NULL, ASW_COLLISION_GROUP_PARASITE, &tr );
|
||||
return tr.endpos;
|
||||
}
|
||||
|
||||
bool CASW_Spawn_Manager::SpawnRandomParasitePack( int nParasites )
|
||||
{
|
||||
int iNumNodes = g_pBigAINet->NumNodes();
|
||||
if ( iNumNodes < 6 )
|
||||
return false;
|
||||
|
||||
int nHull = HULL_TINY;
|
||||
CUtlVector<CASW_Open_Area*> aAreas;
|
||||
for ( int i = 0; i < 6; i++ )
|
||||
{
|
||||
CAI_Node *pNode = NULL;
|
||||
int nTries = 0;
|
||||
while ( nTries < 5 && ( !pNode || pNode->GetType() != NODE_GROUND ) )
|
||||
{
|
||||
pNode = g_pBigAINet->GetNode( RandomInt( 0, iNumNodes ) );
|
||||
nTries++;
|
||||
}
|
||||
|
||||
if ( pNode )
|
||||
{
|
||||
CASW_Open_Area *pArea = FindNearbyOpenArea( pNode->GetOrigin(), HULL_MEDIUMBIG );
|
||||
if ( pArea && pArea->m_nTotalLinks > 30 )
|
||||
{
|
||||
// test if there's room to spawn a shieldbug at that spot
|
||||
if ( ValidSpawnPoint( pArea->m_pNode->GetPosition( nHull ), NAI_Hull::Mins( nHull ), NAI_Hull::Maxs( nHull ), true, false ) )
|
||||
{
|
||||
aAreas.AddToTail( pArea );
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pArea;
|
||||
}
|
||||
}
|
||||
}
|
||||
// stop searching once we have 3 acceptable candidates
|
||||
if ( aAreas.Count() >= 3 )
|
||||
break;
|
||||
}
|
||||
|
||||
// find area with the highest connectivity
|
||||
CASW_Open_Area *pBestArea = NULL;
|
||||
for ( int i = 0; i < aAreas.Count(); i++ )
|
||||
{
|
||||
CASW_Open_Area *pArea = aAreas[i];
|
||||
if ( !pBestArea || pArea->m_nTotalLinks > pBestArea->m_nTotalLinks )
|
||||
{
|
||||
pBestArea = pArea;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pBestArea )
|
||||
{
|
||||
for ( int i = 0; i < nParasites; i++ )
|
||||
{
|
||||
CBaseEntity *pAlien = SpawnAlienAt( "asw_parasite", TraceToGround( pBestArea->m_pNode->GetPosition( nHull ) ), RandomAngle( 0, 360 ) );
|
||||
IASW_Spawnable_NPC *pSpawnable = dynamic_cast<IASW_Spawnable_NPC*>( pAlien );
|
||||
if ( pSpawnable )
|
||||
{
|
||||
pSpawnable->SetAlienOrders(AOT_SpreadThenHibernate, vec3_origin, NULL);
|
||||
}
|
||||
if ( asw_director_debug.GetBool() && pAlien )
|
||||
{
|
||||
Msg( "Spawned parasite at %f %f %f\n", pAlien->GetAbsOrigin() );
|
||||
NDebugOverlay::Cross3D( pAlien->GetAbsOrigin(), 8.0f, 255, 0, 0, true, 20.0f );
|
||||
}
|
||||
}
|
||||
aAreas.PurgeAndDeleteElements();
|
||||
return true;
|
||||
}
|
||||
|
||||
aAreas.PurgeAndDeleteElements();
|
||||
return false;
|
||||
}
|
||||
|
||||
// heuristic to find reasonably open space - searches for areas with high node connectivity
|
||||
CASW_Open_Area* CASW_Spawn_Manager::FindNearbyOpenArea( const Vector &vecSearchOrigin, int nSearchHull )
|
||||
{
|
||||
CBaseEntity *pStartEntity = gEntList.FindEntityByClassname( NULL, "info_player_start" );
|
||||
int iNumNodes = g_pBigAINet->NumNodes();
|
||||
CAI_Node *pHighestConnectivity = NULL;
|
||||
int nHighestLinks = 0;
|
||||
for ( int i=0 ; i<iNumNodes; i++ )
|
||||
{
|
||||
CAI_Node *pNode = g_pBigAINet->GetNode( i );
|
||||
if ( !pNode || pNode->GetType() != NODE_GROUND )
|
||||
continue;
|
||||
|
||||
Vector vecPos = pNode->GetOrigin();
|
||||
float flDist = vecPos.DistTo( vecSearchOrigin );
|
||||
if ( flDist > 400.0f )
|
||||
continue;
|
||||
|
||||
// discard if node is too near start location
|
||||
if ( pStartEntity && vecPos.DistTo( pStartEntity->GetAbsOrigin() ) < 1400.0f ) // NOTE: assumes all start points are clustered near one another
|
||||
continue;
|
||||
|
||||
// discard if node is inside an escape area
|
||||
bool bInsideEscapeArea = false;
|
||||
for ( int d=0; d<m_EscapeTriggers.Count(); d++ )
|
||||
{
|
||||
if ( m_EscapeTriggers[d]->CollisionProp()->IsPointInBounds( vecPos ) )
|
||||
{
|
||||
bInsideEscapeArea = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( bInsideEscapeArea )
|
||||
continue;
|
||||
|
||||
// count links that drones could follow
|
||||
int nLinks = pNode->NumLinks();
|
||||
int nValidLinks = 0;
|
||||
for ( int k = 0; k < nLinks; k++ )
|
||||
{
|
||||
CAI_Link *pLink = pNode->GetLinkByIndex( k );
|
||||
if ( !pLink )
|
||||
continue;
|
||||
|
||||
if ( !( pLink->m_iAcceptedMoveTypes[nSearchHull] & bits_CAP_MOVE_GROUND ) )
|
||||
continue;
|
||||
|
||||
nValidLinks++;
|
||||
}
|
||||
if ( nValidLinks > nHighestLinks )
|
||||
{
|
||||
nHighestLinks = nValidLinks;
|
||||
pHighestConnectivity = pNode;
|
||||
}
|
||||
if ( asw_director_debug.GetBool() )
|
||||
{
|
||||
NDebugOverlay::Text( vecPos, UTIL_VarArgs( "%d", nValidLinks ), false, 10.0f );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !pHighestConnectivity )
|
||||
return NULL;
|
||||
|
||||
// now, starting at the new node, find all nearby nodes with a minimum connectivity
|
||||
CASW_Open_Area *pArea = new CASW_Open_Area();
|
||||
pArea->m_vecOrigin = pHighestConnectivity->GetOrigin();
|
||||
pArea->m_pNode = pHighestConnectivity;
|
||||
int nMinLinks = nHighestLinks * 0.3f;
|
||||
nMinLinks = MAX( nMinLinks, 4 );
|
||||
|
||||
pArea->m_aAreaNodes.AddToTail( pHighestConnectivity );
|
||||
if ( asw_director_debug.GetBool() )
|
||||
{
|
||||
Msg( "minLinks = %d\n", nMinLinks );
|
||||
}
|
||||
pArea->m_nTotalLinks = 0;
|
||||
for ( int i=0 ; i<iNumNodes; i++ )
|
||||
{
|
||||
CAI_Node *pNode = g_pBigAINet->GetNode( i );
|
||||
if ( !pNode || pNode->GetType() != NODE_GROUND )
|
||||
continue;
|
||||
|
||||
Vector vecPos = pNode->GetOrigin();
|
||||
float flDist = vecPos.DistTo( pArea->m_vecOrigin );
|
||||
if ( flDist > 400.0f )
|
||||
continue;
|
||||
|
||||
// discard if node is inside an escape area
|
||||
bool bInsideEscapeArea = false;
|
||||
for ( int d=0; d<m_EscapeTriggers.Count(); d++ )
|
||||
{
|
||||
if ( m_EscapeTriggers[d]->CollisionProp()->IsPointInBounds( vecPos ) )
|
||||
{
|
||||
bInsideEscapeArea = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( bInsideEscapeArea )
|
||||
continue;
|
||||
|
||||
// count links that drones could follow
|
||||
int nLinks = pNode->NumLinks();
|
||||
int nValidLinks = 0;
|
||||
for ( int k = 0; k < nLinks; k++ )
|
||||
{
|
||||
CAI_Link *pLink = pNode->GetLinkByIndex( k );
|
||||
if ( !pLink )
|
||||
continue;
|
||||
|
||||
if ( !( pLink->m_iAcceptedMoveTypes[nSearchHull] & bits_CAP_MOVE_GROUND ) )
|
||||
continue;
|
||||
|
||||
nValidLinks++;
|
||||
}
|
||||
if ( nValidLinks >= nMinLinks )
|
||||
{
|
||||
pArea->m_aAreaNodes.AddToTail( pNode );
|
||||
pArea->m_nTotalLinks += nValidLinks;
|
||||
}
|
||||
}
|
||||
// highlight and measure bounds
|
||||
Vector vecAreaMins = Vector( FLT_MAX, FLT_MAX, FLT_MAX );
|
||||
Vector vecAreaMaxs = Vector( -FLT_MAX, -FLT_MAX, -FLT_MAX );
|
||||
|
||||
for ( int i = 0; i < pArea->m_aAreaNodes.Count(); i++ )
|
||||
{
|
||||
vecAreaMins = VectorMin( vecAreaMins, pArea->m_aAreaNodes[i]->GetOrigin() );
|
||||
vecAreaMaxs = VectorMax( vecAreaMaxs, pArea->m_aAreaNodes[i]->GetOrigin() );
|
||||
|
||||
if ( asw_director_debug.GetBool() )
|
||||
{
|
||||
if ( i == 0 )
|
||||
{
|
||||
NDebugOverlay::Cross3D( pArea->m_aAreaNodes[i]->GetOrigin(), 20.0f, 255, 255, 64, true, 10.0f );
|
||||
}
|
||||
else
|
||||
{
|
||||
NDebugOverlay::Cross3D( pArea->m_aAreaNodes[i]->GetOrigin(), 10.0f, 255, 128, 0, true, 10.0f );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector vecArea = ( vecAreaMaxs - vecAreaMins );
|
||||
float flArea = vecArea.x * vecArea.y;
|
||||
|
||||
if ( asw_director_debug.GetBool() )
|
||||
{
|
||||
Msg( "area mins = %f %f %f\n", VectorExpand( vecAreaMins ) );
|
||||
Msg( "area maxs = %f %f %f\n", VectorExpand( vecAreaMaxs ) );
|
||||
NDebugOverlay::Box( vec3_origin, vecAreaMins, vecAreaMaxs, 255, 128, 128, 10, 10.0f );
|
||||
Msg( "Total links = %d Area = %f\n", pArea->m_nTotalLinks, flArea );
|
||||
}
|
||||
|
||||
return pArea;
|
||||
}
|
||||
|
||||
// creates a batch of aliens at the mouse cursor
|
||||
void asw_alien_batch_f( const CCommand& args )
|
||||
|
@ -715,4 +1143,15 @@ void asw_alien_horde_f( const CCommand& args )
|
|||
Msg("Failed to add horde\n");
|
||||
}
|
||||
}
|
||||
static ConCommand asw_alien_horde("asw_alien_horde", asw_alien_horde_f, "Creates a horde of aliens somewhere nearby", FCVAR_GAMEDLL | FCVAR_CHEAT);
|
||||
static ConCommand asw_alien_horde("asw_alien_horde", asw_alien_horde_f, "Creates a horde of aliens somewhere nearby", FCVAR_GAMEDLL | FCVAR_CHEAT);
|
||||
|
||||
|
||||
CON_COMMAND_F( asw_spawn_shieldbug, "Spawns a shieldbug somewhere randomly in the map", FCVAR_CHEAT )
|
||||
{
|
||||
ASWSpawnManager()->SpawnRandomShieldbug();
|
||||
}
|
||||
|
||||
CON_COMMAND_F( asw_spawn_parasite_pack, "Spawns a group of parasites somewhere randomly in the map", FCVAR_CHEAT )
|
||||
{
|
||||
ASWSpawnManager()->SpawnRandomParasitePack( RandomInt( 3, 5 ) );
|
||||
}
|
|
@ -7,6 +7,8 @@
|
|||
class CAI_Network;
|
||||
class CTriggerMultiple;
|
||||
struct AI_Waypoint_t;
|
||||
class CAI_Node;
|
||||
class CASW_Alien;
|
||||
|
||||
// The spawn manager can spawn aliens and groups of aliens
|
||||
|
||||
|
@ -20,6 +22,23 @@ public:
|
|||
int m_nHullType;
|
||||
};
|
||||
|
||||
class CASW_Open_Area
|
||||
{
|
||||
public:
|
||||
CASW_Open_Area()
|
||||
{
|
||||
m_flArea = 0.0f;
|
||||
m_nTotalLinks = 0;
|
||||
m_vecOrigin = vec3_origin;
|
||||
m_pNode = NULL;
|
||||
}
|
||||
float m_flArea;
|
||||
int m_nTotalLinks;
|
||||
Vector m_vecOrigin;
|
||||
CAI_Node *m_pNode;
|
||||
CUtlVector<CAI_Node*> m_aAreaNodes;
|
||||
};
|
||||
|
||||
class CASW_Spawn_Manager
|
||||
{
|
||||
public:
|
||||
|
@ -41,11 +60,20 @@ public:
|
|||
bool GetAlienBounds( const char *szAlienClass, Vector &vecMins, Vector &vecMaxs );
|
||||
bool GetAlienBounds( string_t iszAlienClass, Vector &vecMins, Vector &vecMaxs );
|
||||
|
||||
int GetHordeToSpawn() { return m_iHordeToSpawn; }
|
||||
int GetHordeToSpawn() { return m_iHordeToSpawn; }
|
||||
|
||||
void OnAlienWokeUp( CASW_Alien *pAlien );
|
||||
void OnAlienSleeping( CASW_Alien *pAlien );
|
||||
int GetAwakeAliens() { return m_nAwakeAliens; }
|
||||
int GetAwakeDrones() { return m_nAwakeDrones; }
|
||||
|
||||
int GetNumAlienClasses();
|
||||
ASW_Alien_Class_Entry* GetAlienClass( int i );
|
||||
|
||||
// spawns a shieldbug somewhere randomly in the map
|
||||
bool SpawnRandomShieldbug();
|
||||
bool SpawnRandomParasitePack( int nParasites );
|
||||
|
||||
private:
|
||||
void UpdateCandidateNodes();
|
||||
bool FindHordePosition();
|
||||
|
@ -54,12 +82,18 @@ private:
|
|||
void FindEscapeTriggers();
|
||||
void DeleteRoute( AI_Waypoint_t *pWaypointList );
|
||||
|
||||
// finds an area with good node connectivity. Caller should take ownership of the CASW_Open_Area instance.
|
||||
CASW_Open_Area* FindNearbyOpenArea( const Vector &vecSearchOrigin, int nSearchHull );
|
||||
|
||||
CountdownTimer m_batchInterval;
|
||||
Vector m_vecHordePosition;
|
||||
QAngle m_angHordeAngle;
|
||||
int m_iHordeToSpawn;
|
||||
int m_iAliensToSpawn;
|
||||
|
||||
int m_nAwakeAliens;
|
||||
int m_nAwakeDrones;
|
||||
|
||||
// maintaining a list of possible nodes to spawn aliens from
|
||||
CUtlVector<int> m_northCandidateNodes;
|
||||
CUtlVector<int> m_southCandidateNodes;
|
||||
|
|
|
@ -153,6 +153,9 @@ void CASW_Spawner::AlienKilled( CBaseEntity *pVictim )
|
|||
|
||||
m_nCurrentLiveAliens--;
|
||||
|
||||
if (asw_debug_spawners.GetBool())
|
||||
Msg("%d AlienKilled NumLive = %d\n", entindex(), m_nCurrentLiveAliens );
|
||||
|
||||
// If we're here, we're getting erroneous death messages from children we haven't created
|
||||
AssertMsg( m_nCurrentLiveAliens >= 0, "asw_spawner receiving child death notice but thinks has no children\n" );
|
||||
|
||||
|
@ -293,6 +296,22 @@ bool CASW_Spawner::ApplyCarnageMode( float fScaler, float fInvScaler )
|
|||
return false;
|
||||
}
|
||||
|
||||
int CASW_Spawner::DrawDebugTextOverlays()
|
||||
{
|
||||
int text_offset = BaseClass::DrawDebugTextOverlays();
|
||||
|
||||
if (m_debugOverlays & OVERLAY_TEXT_BIT)
|
||||
{
|
||||
NDebugOverlay::EntityText( entindex(),text_offset,CFmtStr( "Num Live Aliens: %d", m_nCurrentLiveAliens ),0 );
|
||||
text_offset++;
|
||||
NDebugOverlay::EntityText( entindex(),text_offset,CFmtStr( "Max Live Aliens: %d", m_nMaxLiveAliens ),0 );
|
||||
text_offset++;
|
||||
NDebugOverlay::EntityText( entindex(),text_offset,CFmtStr( "Alien supply: %d", m_bInfiniteAliens ? -1 : m_nNumAliens ),0 );
|
||||
text_offset++;
|
||||
}
|
||||
return text_offset;
|
||||
}
|
||||
|
||||
void ASW_ApplyCarnage_f(float fScaler)
|
||||
{
|
||||
if ( fScaler <= 0 )
|
||||
|
|
|
@ -21,6 +21,7 @@ public:
|
|||
virtual void Spawn();
|
||||
virtual void Precache();
|
||||
virtual void InitAlienClassName();
|
||||
virtual int DrawDebugTextOverlays();
|
||||
|
||||
Class_T Classify() { return (Class_T) CLASS_ASW_SPAWNER; }
|
||||
|
||||
|
|
|
@ -1208,6 +1208,9 @@ void SoundSystemPreloadSounds( void )
|
|||
|
||||
CON_COMMAND( sv_soundemitter_flush, "Flushes the sounds.txt system (server only)" )
|
||||
{
|
||||
if ( !UTIL_IsCommandIssuedByServerAdmin() )
|
||||
return;
|
||||
|
||||
// save the current soundscape
|
||||
// kill the system
|
||||
g_SoundEmitterSystem.Flush();
|
||||
|
@ -1222,12 +1225,18 @@ CON_COMMAND( sv_soundemitter_flush, "Flushes the sounds.txt system (server only)
|
|||
|
||||
CON_COMMAND( sv_soundemitter_filecheck, "Report missing wave files for sounds and game_sounds files." )
|
||||
{
|
||||
if ( !UTIL_IsCommandIssuedByServerAdmin() )
|
||||
return;
|
||||
|
||||
int missing = soundemitterbase->CheckForMissingWavFiles( true );
|
||||
DevMsg( "---------------------------\nTotal missing files %i\n", missing );
|
||||
}
|
||||
|
||||
CON_COMMAND( sv_findsoundname, "Find sound names which reference the specified wave files." )
|
||||
{
|
||||
{
|
||||
if ( !UTIL_IsCommandIssuedByServerAdmin() )
|
||||
return;
|
||||
|
||||
if ( args.ArgC() != 2 )
|
||||
return;
|
||||
|
||||
|
|
|
@ -639,6 +639,11 @@ IResponseSystem *g_pResponseSystem = &defaultresponsesytem;
|
|||
|
||||
CON_COMMAND( rr_reloadresponsesystems, "Reload all response system scripts." )
|
||||
{
|
||||
#ifdef GAME_DLL
|
||||
if ( !UTIL_IsCommandIssuedByServerAdmin() )
|
||||
return;
|
||||
#endif
|
||||
|
||||
defaultresponsesytem.ReloadAllResponseSystems();
|
||||
}
|
||||
|
||||
|
|
|
@ -762,7 +762,7 @@ class CAchievement_Unlock_All_Weapons : public CASW_Achievement
|
|||
{
|
||||
if ( !Q_stricmp( event->GetName(), "level_up" ) )
|
||||
{
|
||||
if ( event->GetInt( "level" ) >= ASW_LEVEL_CAP )
|
||||
if ( event->GetInt( "level" ) >= ASW_NUM_EXPERIENCE_LEVELS )
|
||||
{
|
||||
IncrementCount();
|
||||
}
|
||||
|
@ -1077,5 +1077,73 @@ class CAchievement_Para_Hat : public CASW_Achievement
|
|||
};
|
||||
DECLARE_ACHIEVEMENT_ORDER( CAchievement_Para_Hat, ACHIEVEMENT_ASW_PARA_HAT, "ASW_PARA_HAT", 5, 149 );
|
||||
|
||||
class CAchievement_Imba_Campaign : public CASW_Achievement
|
||||
{
|
||||
void Init()
|
||||
{
|
||||
SetFlags( ACH_SAVE_GLOBAL | ACH_HAS_COMPONENTS );
|
||||
SetStoreProgressInSteam( true );
|
||||
SetGoal( NELEMS( g_szAchievementMapNames ) );
|
||||
}
|
||||
|
||||
virtual void ListenForEvents( void )
|
||||
{
|
||||
ListenForGameEvent( "mission_success" );
|
||||
}
|
||||
|
||||
void FireGameEvent_Internal( IGameEvent *event )
|
||||
{
|
||||
if ( !Q_stricmp( event->GetName(), "mission_success" ) && ASWGameRules() && ASWGameRules()->GetSkillLevel() >= 5 )
|
||||
{
|
||||
if ( LocalPlayerWasSpectating() )
|
||||
return;
|
||||
|
||||
const char *szMapName = event->GetString( "strMapName" );
|
||||
for ( int i = 0; i < NELEMS( g_szAchievementMapNames ); i++ )
|
||||
{
|
||||
if ( !Q_stricmp( szMapName, g_szAchievementMapNames[i] ) )
|
||||
{
|
||||
EnsureComponentBitSetAndEvaluate( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
DECLARE_ACHIEVEMENT_ORDER( CAchievement_Imba_Campaign, ACHIEVEMENT_ASW_IMBA_CAMPAIGN, "ASW_IMBA_CAMPAIGN", 5, 182 );
|
||||
|
||||
class CAchievement_Hardcore : public CASW_Achievement
|
||||
{
|
||||
void Init()
|
||||
{
|
||||
SetFlags( ACH_SAVE_GLOBAL );
|
||||
SetGoal( 1 );
|
||||
}
|
||||
|
||||
virtual void ListenForEvents( void )
|
||||
{
|
||||
ListenForGameEvent( "mission_success" );
|
||||
}
|
||||
|
||||
void FireGameEvent_Internal( IGameEvent *event )
|
||||
{
|
||||
if ( !Q_stricmp( event->GetName(), "mission_success" ) && ASWGameRules() && ASWGameRules()->GetSkillLevel() >= 5
|
||||
&& CAlienSwarm::IsHardcoreFF() && CAlienSwarm::IsOnslaught() )
|
||||
{
|
||||
if ( LocalPlayerWasSpectating() )
|
||||
return;
|
||||
|
||||
const char *szMapName = event->GetString( "strMapName" );
|
||||
for ( int i = 0; i < NELEMS( g_szAchievementMapNames ); i++ )
|
||||
{
|
||||
if ( !Q_stricmp( szMapName, g_szAchievementMapNames[i] ) )
|
||||
{
|
||||
IncrementCount();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
DECLARE_ACHIEVEMENT_ORDER( CAchievement_Hardcore, ACHIEVEMENT_ASW_HARDCORE, "ASW_HARDCORE", 5, 184 );
|
||||
#endif
|
|
@ -68,7 +68,9 @@ enum
|
|||
ACHIEVEMENT_ASW_SPEEDRUN_TIMOR,
|
||||
ACHIEVEMENT_ASW_CAMPAIGN_NO_DEATHS,
|
||||
ACHIEVEMENT_ASW_MISSION_NO_DEATHS,
|
||||
ACHIEVEMENT_ASW_PARA_HAT
|
||||
ACHIEVEMENT_ASW_PARA_HAT,
|
||||
ACHIEVEMENT_ASW_IMBA_CAMPAIGN,
|
||||
ACHIEVEMENT_ASW_HARDCORE,
|
||||
};
|
||||
|
||||
#define ACH_LISTEN_ALIEN_DEATH_EVENTS 0x1000
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
#include "EntityFlame.h"
|
||||
#include "asw_buffgrenade_projectile.h"
|
||||
#include "asw_achievements.h"
|
||||
#include "asw_director.h"
|
||||
#endif
|
||||
#include "game_timescale_shared.h"
|
||||
#include "asw_gamerules.h"
|
||||
|
@ -135,6 +136,19 @@ extern ConVar old_radius_damage;
|
|||
ConVar sv_vote_kick_ban_duration("sv_vote_kick_ban_duration", "5", 0, "How long should a kick vote ban someone from the server? (in minutes)");
|
||||
ConVar sv_timeout_when_fully_connected( "sv_timeout_when_fully_connected", "30", FCVAR_NONE, "Once fully connected, player will be kicked if he doesn't send a network message within this interval." );
|
||||
ConVar mm_swarm_state( "mm_swarm_state", "ingame", FCVAR_DEVELOPMENTONLY );
|
||||
|
||||
static void UpdateMatchmakingTagsCallback( IConVar *pConVar, const char *pOldValue, float flOldValue )
|
||||
{
|
||||
// update sv_tags to force an update of the matchmaking tags
|
||||
static ConVarRef sv_tags( "sv_tags" );
|
||||
|
||||
if ( sv_tags.IsValid() )
|
||||
{
|
||||
char buffer[ 1024 ];
|
||||
Q_snprintf( buffer, sizeof( buffer ), "%s", sv_tags.GetString() );
|
||||
sv_tags.SetValue( buffer );
|
||||
}
|
||||
}
|
||||
#else
|
||||
extern ConVar asw_controls;
|
||||
#endif
|
||||
|
@ -153,6 +167,30 @@ ConVar asw_stim_time_scale("asw_stim_time_scale", "0.35", FCVAR_REPLICATED | FCV
|
|||
ConVar asw_time_scale_delay("asw_time_scale_delay", "0.15", FCVAR_REPLICATED | FCVAR_CHEAT, "Delay before timescale changes to give a chance for the client to comply and predict.");
|
||||
ConVar asw_ignore_need_two_player_requirement("asw_ignore_need_two_player_requirement", "0", FCVAR_REPLICATED, "If set to 1, ignores the mission setting that states two players are needed to start the mission.");
|
||||
ConVar mp_gamemode( "mp_gamemode", "campaign", FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY, "Current game mode, acceptable values are campaign and single_mission.", false, 0.0f, false, 0.0f );
|
||||
ConVar asw_sentry_friendly_fire_scale( "asw_sentry_friendly_fire_scale", "0", FCVAR_REPLICATED, "Damage scale for sentry gun friendly fire"
|
||||
#ifdef GAME_DLL
|
||||
,UpdateMatchmakingTagsCallback );
|
||||
#else
|
||||
);
|
||||
#endif
|
||||
ConVar asw_marine_ff_absorption("asw_marine_ff_absorption", "1", FCVAR_REPLICATED, "Friendly fire absorption style (0=none 1=ramp up 2=ramp down)"
|
||||
#ifdef GAME_DLL
|
||||
,UpdateMatchmakingTagsCallback );
|
||||
#else
|
||||
);
|
||||
#endif
|
||||
ConVar asw_horde_override( "asw_horde_override", "0", FCVAR_REPLICATED, "Forces hordes to spawn"
|
||||
#ifdef GAME_DLL
|
||||
,UpdateMatchmakingTagsCallback );
|
||||
#else
|
||||
);
|
||||
#endif
|
||||
ConVar asw_wanderer_override( "asw_wanderer_override", "0", FCVAR_REPLICATED, "Forces wanderers to spawn"
|
||||
#ifdef GAME_DLL
|
||||
,UpdateMatchmakingTagsCallback );
|
||||
#else
|
||||
);
|
||||
#endif
|
||||
|
||||
// ASW Weapons
|
||||
// Rifle
|
||||
|
@ -251,7 +289,7 @@ ConVar asw_vote_kick_fraction("asw_vote_kick_fraction", "0.6", FCVAR_REPLICATED
|
|||
ConVar asw_vote_leader_fraction("asw_vote_leader_fraction", "0.6", FCVAR_REPLICATED | FCVAR_ARCHIVE, "Fraction of players needed to activate a leader vote");
|
||||
ConVar asw_vote_map_fraction("asw_vote_map_fraction", "0.6", FCVAR_REPLICATED | FCVAR_ARCHIVE, "Fraction of players needed to activate a map vote");
|
||||
ConVar asw_marine_collision("asw_marine_collision", "0", FCVAR_REPLICATED, "Whether marines collide with each other or not, in a multiplayer game");
|
||||
ConVar asw_skill( "asw_skill","2", FCVAR_REPLICATED | FCVAR_ARCHIVE | FCVAR_ARCHIVE_XBOX, "Game skill level (1-4).", true, 1, true, 4 );
|
||||
ConVar asw_skill( "asw_skill","2", FCVAR_REPLICATED | FCVAR_ARCHIVE | FCVAR_ARCHIVE_XBOX, "Game skill level (1-5).", true, 1, true, 5 );
|
||||
ConVar asw_money( "asw_money", "0", FCVAR_REPLICATED, "Can players collect money?" );
|
||||
ConVar asw_client_build_maps("asw_client_build_maps", "0", FCVAR_REPLICATED, "Whether clients compile random maps rather than getting sent them");
|
||||
|
||||
|
@ -456,7 +494,7 @@ CAmmoDef *GetAmmoDef()
|
|||
def.AddAmmoType("ASW_P", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_asw_p", "sk_npc_dmg_asw_p", "sk_max_asw_p", BULLET_IMPULSE(200, 1225), 0 );
|
||||
// mining laser
|
||||
def.AddAmmoType("ASW_ML", DMG_ENERGYBEAM, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_asw_ml", "sk_npc_dmg_asw_ml", "sk_max_asw_ml", BULLET_IMPULSE(200, 1225), 0 );
|
||||
// mining laser
|
||||
// tesla gun - happy LJ?
|
||||
def.AddAmmoType("ASW_TG", DMG_ENERGYBEAM, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_asw_tg", "sk_npc_dmg_asw_tg", "sk_max_asw_tg", BULLET_IMPULSE(200, 1225), 0 );
|
||||
// railgun
|
||||
def.AddAmmoType("ASW_RG", DMG_SONIC, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_asw_rg", "sk_npc_dmg_asw_rg", "sk_max_asw_rg", BULLET_IMPULSE(200, 1225), 0 );
|
||||
|
@ -627,19 +665,6 @@ const char * GenerateNewSaveGameName()
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void UpdateMatchmakingTags()
|
||||
{
|
||||
// update sv_tags to force an update of the matchmaking tags
|
||||
static ConVarRef sv_tags( "sv_tags" );
|
||||
|
||||
if ( sv_tags.IsValid() )
|
||||
{
|
||||
char buffer[ 1024 ];
|
||||
Q_snprintf( buffer, sizeof( buffer ), "%s", sv_tags.GetString() );
|
||||
sv_tags.SetValue( buffer );
|
||||
}
|
||||
}
|
||||
|
||||
CAlienSwarm::CAlienSwarm()
|
||||
{
|
||||
Msg("CAlienSwarm created\n");
|
||||
|
@ -1610,6 +1635,11 @@ void CAlienSwarm::StartMission()
|
|||
|
||||
m_Medals.OnStartMission();
|
||||
|
||||
if ( ASWDirector() )
|
||||
{
|
||||
ASWDirector()->OnMissionStarted();
|
||||
}
|
||||
|
||||
Msg("==STARTMISSION==\n");
|
||||
|
||||
SetGameState(ASW_GS_LAUNCHING);
|
||||
|
@ -3319,7 +3349,7 @@ void CAlienSwarm::MissionComplete( bool bSuccess )
|
|||
if (!MapScores()->IsModeUnlocked(mapName, GetSkillLevel(), ASW_SM_CARNAGE))
|
||||
{
|
||||
// check for unlocking carnage (if we completed the mission on Insane)
|
||||
bJustUnlockedCarnage = (GetSkillLevel() == 4);
|
||||
bJustUnlockedCarnage = (GetSkillLevel() >= 4);
|
||||
//Msg("Checked just carnage unlock = %d\n", bJustUnlockedCarnage);
|
||||
}
|
||||
if (!MapScores()->IsModeUnlocked(mapName, GetSkillLevel(), ASW_SM_UBER))
|
||||
|
@ -5144,6 +5174,11 @@ void CAlienSwarm::OnSkillLevelChanged( int iNewLevel )
|
|||
m_iMissionDifficulty = 10;
|
||||
szDifficulty = "insane";
|
||||
}
|
||||
else if (iNewLevel == 5) // imba
|
||||
{
|
||||
m_iMissionDifficulty = 13;
|
||||
szDifficulty = "imba";
|
||||
}
|
||||
else // normal
|
||||
{
|
||||
m_iMissionDifficulty = 5;
|
||||
|
@ -5200,7 +5235,7 @@ void CAlienSwarm::OnSkillLevelChanged( int iNewLevel )
|
|||
}
|
||||
}
|
||||
|
||||
UpdateMatchmakingTags();
|
||||
UpdateMatchmakingTagsCallback( NULL, "0", 0.0f );
|
||||
|
||||
m_iSkillLevel = iNewLevel;
|
||||
}
|
||||
|
@ -5226,12 +5261,28 @@ void CAlienSwarm::RequestSkill( CASW_Player *pPlayer, int nSkill )
|
|||
if ( !( m_iGameState == ASW_GS_BRIEFING || m_iGameState == ASW_GS_DEBRIEF ) ) // don't allow skill change outside of briefing
|
||||
return;
|
||||
|
||||
if ( nSkill >= 1 && nSkill <= 4 && ASWGameResource() && ASWGameResource()->GetLeader() == pPlayer )
|
||||
if ( nSkill >= 1 && nSkill <= 5 && ASWGameResource() && ASWGameResource()->GetLeader() == pPlayer )
|
||||
{
|
||||
ConVar *var = (ConVar *)cvar->FindVar( "asw_skill" );
|
||||
if (var)
|
||||
{
|
||||
int iOldSkill = var->GetInt();
|
||||
|
||||
var->SetValue( nSkill );
|
||||
|
||||
if ( iOldSkill != var->GetInt() )
|
||||
{
|
||||
CReliableBroadcastRecipientFilter filter;
|
||||
filter.RemoveRecipient( pPlayer ); // notify everyone except the player changing the difficulty level
|
||||
switch(var->GetInt())
|
||||
{
|
||||
case 1: UTIL_ClientPrintFilter( filter, ASW_HUD_PRINTTALKANDCONSOLE, "#asw_set_difficulty_easy", pPlayer->GetPlayerName() ); break;
|
||||
case 2: UTIL_ClientPrintFilter( filter, ASW_HUD_PRINTTALKANDCONSOLE, "#asw_set_difficulty_normal", pPlayer->GetPlayerName() ); break;
|
||||
case 3: UTIL_ClientPrintFilter( filter, ASW_HUD_PRINTTALKANDCONSOLE, "#asw_set_difficulty_hard", pPlayer->GetPlayerName() ); break;
|
||||
case 4: UTIL_ClientPrintFilter( filter, ASW_HUD_PRINTTALKANDCONSOLE, "#asw_set_difficulty_insane", pPlayer->GetPlayerName() ); break;
|
||||
case 5: UTIL_ClientPrintFilter( filter, ASW_HUD_PRINTTALKANDCONSOLE, "#asw_set_difficulty_imba", pPlayer->GetPlayerName() ); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5241,7 +5292,7 @@ void CAlienSwarm::RequestSkillUp(CASW_Player *pPlayer)
|
|||
if (m_iGameState != ASW_GS_BRIEFING) // don't allow skill change outside of briefing
|
||||
return;
|
||||
|
||||
if (m_iSkillLevel < 4 && ASWGameResource() && ASWGameResource()->GetLeader() == pPlayer)
|
||||
if (m_iSkillLevel < 5 && ASWGameResource() && ASWGameResource()->GetLeader() == pPlayer)
|
||||
{
|
||||
ConVar *var = (ConVar *)cvar->FindVar( "asw_skill" );
|
||||
if (var)
|
||||
|
@ -6598,6 +6649,8 @@ int CAlienSwarm::TotalInfestDamage()
|
|||
return 270;
|
||||
case 4:
|
||||
return 280; // BARELY survivable with Bastille and heal beacon
|
||||
case 5:
|
||||
return 280;
|
||||
}
|
||||
|
||||
// ASv1 Total infest damage = 90 + difficulty * 20;
|
||||
|
@ -6749,3 +6802,13 @@ const QAngle& CAlienSwarm::GetTopDownMovementAxis()
|
|||
static QAngle axis = ASW_MOVEMENT_AXIS;
|
||||
return axis;
|
||||
}
|
||||
|
||||
bool CAlienSwarm::IsHardcoreFF()
|
||||
{
|
||||
return ( asw_marine_ff_absorption.GetInt() != 1 || asw_sentry_friendly_fire_scale.GetFloat() != 0.0f );
|
||||
}
|
||||
|
||||
bool CAlienSwarm::IsOnslaught()
|
||||
{
|
||||
return ( asw_horde_override.GetBool() || asw_wanderer_override.GetBool() );
|
||||
}
|
|
@ -234,9 +234,9 @@ public:
|
|||
{
|
||||
iLevel = 1;
|
||||
}
|
||||
else if ( iLevel > 4 )
|
||||
else if ( iLevel > 5 )
|
||||
{
|
||||
iLevel = 4;
|
||||
iLevel = 5;
|
||||
}
|
||||
|
||||
m_iSkillLevel = iLevel;
|
||||
|
@ -386,8 +386,8 @@ public:
|
|||
virtual void RefreshSkillData ( bool forceUpdate );
|
||||
|
||||
// difficulty
|
||||
virtual int GetSkillLevel() { return m_iSkillLevel; } // skill level (expanded HL2 style: 1 = easy, 2 = normal, 3 = hard, 4 = insane )
|
||||
CNetworkVar(int, m_iSkillLevel); // 1 = easy, 2 = normal, 3 = hard, 4 = insane
|
||||
virtual int GetSkillLevel() { return m_iSkillLevel; } // skill level (expanded HL2 style: 1 = easy, 2 = normal, 3 = hard, 4 = insane, 5 = imba )
|
||||
CNetworkVar(int, m_iSkillLevel); // 1 = easy, 2 = normal, 3 = hard, 4 = insane, 5 = imba
|
||||
int GetMissionDifficulty() { return m_iMissionDifficulty; } // overall difficulty of the mission from 2-10, based on skill level and campaign modifier
|
||||
CNetworkVar(int, m_iMissionDifficulty);
|
||||
CNetworkVar(bool, m_bCheated);
|
||||
|
@ -475,6 +475,8 @@ public:
|
|||
bool IsIntroMap() { return m_bIsIntro; }
|
||||
bool IsOutroMap() { return m_bIsOutro; }
|
||||
bool IsLobbyMap() { return m_bIsLobby; }
|
||||
static bool IsHardcoreFF();
|
||||
static bool IsOnslaught();
|
||||
|
||||
bool m_bIsTutorial;
|
||||
bool m_bIsIntro;
|
||||
|
|
|
@ -296,6 +296,7 @@ float CASW_Marine::MaxSpeed()
|
|||
// adjust the speed by difficulty level
|
||||
switch (ASWGameRules()->GetSkillLevel())
|
||||
{
|
||||
case 5: speedscale *= asw_marine_speed_scale_insane.GetFloat(); break;
|
||||
case 4: speedscale *= asw_marine_speed_scale_insane.GetFloat(); break;
|
||||
case 3: speedscale *= asw_marine_speed_scale_hard.GetFloat(); break;
|
||||
case 2: speedscale *= asw_marine_speed_scale_normal.GetFloat(); break;
|
||||
|
|
|
@ -100,15 +100,28 @@ int g_iXPAward[ ASW_NUM_XP_TYPES ]=
|
|||
50, // ASW_XP_HACKING
|
||||
};
|
||||
|
||||
// scalar applied to XP required to level, based on your current promotion
|
||||
float g_flPromotionXPScale[ ASW_PROMOTION_CAP + 1 ]=
|
||||
{
|
||||
1.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
1.0f,
|
||||
2.0f,
|
||||
4.0f,
|
||||
6.0f,
|
||||
};
|
||||
|
||||
#define ASW_MISSION_XP_AWARD_ON_FAILURE 750 // XP award divided up between objectives
|
||||
|
||||
// NOTE: If you change this, update the labels in CExperienceReport::OnThink too
|
||||
float g_flXPDifficultyScale[4]=
|
||||
float g_flXPDifficultyScale[5]=
|
||||
{
|
||||
0.5f, // easy
|
||||
1.0f, // normal
|
||||
1.2f, // hard
|
||||
1.4f, // insane
|
||||
1.5f, // imba
|
||||
};
|
||||
|
||||
// Weapon unlocks
|
||||
|
@ -153,17 +166,18 @@ ASW_Weapon_Unlock g_WeaponUnlocks[]=
|
|||
ASW_Weapon_Unlock( "asw_weapon_night_vision", 23 ),//
|
||||
ASW_Weapon_Unlock( "asw_weapon_sentry_cannon", 24 ),
|
||||
ASW_Weapon_Unlock( "asw_weapon_smart_bomb", 25 ),//
|
||||
ASW_Weapon_Unlock( "asw_weapon_grenade_launcher", 26 ), // ASW_LEVEL_CAP
|
||||
ASW_Weapon_Unlock( "asw_weapon_grenade_launcher", 26 ), // ASW_NUM_EXPERIENCE_LEVELS
|
||||
};
|
||||
|
||||
// given an Experience total, this tells you the player's level
|
||||
int LevelFromXP( int iExperience )
|
||||
int LevelFromXP( int iExperience, int iPromotion )
|
||||
{
|
||||
iExperience = MIN( iExperience, ASW_XP_CAP );
|
||||
iExperience = MIN( iExperience, ASW_XP_CAP * g_flPromotionXPScale[ iPromotion ] );
|
||||
|
||||
for ( int i = 0; i < NELEMS( g_iLevelExperience ); i++ )
|
||||
{
|
||||
if ( iExperience < g_iLevelExperience[ i ] )
|
||||
int iRequiredXP = (int) ( g_flPromotionXPScale[ iPromotion ] * g_iLevelExperience[ i ] );
|
||||
if ( iExperience < iRequiredXP )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
@ -368,13 +382,13 @@ void CASW_Player::CalculateEarnedXP()
|
|||
|
||||
int CASW_Player::GetLevel()
|
||||
{
|
||||
return LevelFromXP( GetExperience() );
|
||||
return LevelFromXP( GetExperience(), GetPromotion() );
|
||||
}
|
||||
|
||||
|
||||
int CASW_Player::GetLevelBeforeDebrief()
|
||||
{
|
||||
return LevelFromXP( GetExperienceBeforeDebrief() );
|
||||
return LevelFromXP( GetExperienceBeforeDebrief(), GetPromotion() );
|
||||
}
|
||||
|
||||
void CASW_Player::RequestExperience()
|
||||
|
@ -460,7 +474,7 @@ void CASW_Player::AwardExperience()
|
|||
Msg( "%s: AwardExperience: Pre XP is %d\n", IsServerDll() ? "S" : "C", m_iExperience );
|
||||
|
||||
m_iExperience += m_iEarnedXP[ ASW_XP_TOTAL ];
|
||||
m_iExperience = MIN( m_iExperience, ASW_XP_CAP );
|
||||
m_iExperience = MIN( m_iExperience, ASW_XP_CAP * g_flPromotionXPScale[ GetPromotion() ] );
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
if ( IsLocalPlayer() )
|
||||
|
@ -646,7 +660,7 @@ void CASW_Player::Steam_OnUserStatsReceived( UserStatsReceived_t *pUserStatsRece
|
|||
if( GetLocalASWPlayer() == this )
|
||||
g_ASW_Steamstats.FetchStats( steamID, this );
|
||||
|
||||
if ( IsLocalPlayer() && GetLevel() >= ASW_LEVEL_CAP )
|
||||
if ( IsLocalPlayer() && GetLevel() >= ASW_NUM_EXPERIENCE_LEVELS )
|
||||
{
|
||||
CAchievementMgr *pAchievementMgr = dynamic_cast<CAchievementMgr *>( engine->GetAchievementMgr() );
|
||||
if ( !pAchievementMgr )
|
||||
|
@ -694,7 +708,7 @@ ConCommand asw_debug_xp( "asw_debug_xp", asw_debug_xp_f, "Lists XP details for l
|
|||
|
||||
void CASW_Player::AcceptPromotion()
|
||||
{
|
||||
if ( GetExperience() < ASW_XP_CAP )
|
||||
if ( GetExperience() < ASW_XP_CAP * g_flPromotionXPScale[ GetPromotion() ] )
|
||||
return;
|
||||
|
||||
if ( GetPromotion() >= ASW_PROMOTION_CAP )
|
||||
|
|
|
@ -26,11 +26,13 @@ enum
|
|||
ASW_USE_HOLD_RELEASE_FULL,
|
||||
};
|
||||
|
||||
#define ASW_PROMOTION_CAP 6
|
||||
#define ASW_NUM_EXPERIENCE_LEVELS 26
|
||||
|
||||
extern int g_iLevelExperience[ ASW_NUM_EXPERIENCE_LEVELS ];
|
||||
extern float g_flPromotionXPScale[ ASW_PROMOTION_CAP + 1 ];
|
||||
|
||||
int LevelFromXP( int iExperience );
|
||||
int LevelFromXP( int iExperience, int iPromotion );
|
||||
|
||||
enum CASW_Earned_XP_t
|
||||
{
|
||||
|
|
|
@ -583,8 +583,6 @@ enum
|
|||
};
|
||||
|
||||
#define ASW_XP_CAP 42250
|
||||
#define ASW_LEVEL_CAP 26
|
||||
#define ASW_PROMOTION_CAP 3
|
||||
|
||||
extern ConVar asw_visrange_generic;
|
||||
|
||||
|
@ -602,4 +600,13 @@ public:
|
|||
|
||||
#endif
|
||||
|
||||
enum CASW_Flock_Leader_State
|
||||
{
|
||||
ASW_FL_CHASING = 0,
|
||||
ASW_FL_CHARGING,
|
||||
ASW_FL_FLEEING,
|
||||
|
||||
NUM_FLOCK_LEADER_STATES,
|
||||
};
|
||||
|
||||
#endif // ASW_SHAREDDEFS_H
|
||||
|
|
|
@ -954,7 +954,7 @@ float UTIL_ASW_CalcFastDoorHackTime(int iNumRows, int iNumColumns, int iNumWires
|
|||
ideal_time *= 1.05f; // 5% slower on easy mode
|
||||
else if (iSkill == 3)
|
||||
ideal_time *= 0.95f; // 5% faster on hard mode
|
||||
else if (iSkill == 4)
|
||||
else if (iSkill == 4 || iSkill == 5)
|
||||
ideal_time *= 0.90f; // 10% faster on insane mode
|
||||
|
||||
return ideal_time;
|
||||
|
|
|
@ -885,6 +885,7 @@ bool CASW_Weapon::ASWReload( int iClipSize1, int iClipSize2, int iActivity )
|
|||
case 2: flFastReloadWidth = random->RandomFloat( 0.10f, 0.1f ); break; // easy/normal
|
||||
case 3: flFastReloadWidth = random->RandomFloat( 0.08f, 0.12f ); break; // hard
|
||||
case 4: flFastReloadWidth = random->RandomFloat( 0.06f, 0.10f ); break; // insane
|
||||
case 5: flFastReloadWidth = random->RandomFloat( 0.055f, 0.09f ); break; // imba
|
||||
}
|
||||
// scale by marine skills
|
||||
flFastReloadWidth *= MarineSkills()->GetSkillBasedValueByMarine( pMarine, ASW_MARINE_SKILL_RELOADING, ASW_MARINE_SUBSKILL_RELOADING_FAST_WIDTH_SCALE );
|
||||
|
|
Loading…
Reference in New Issue