mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-11 11:19:09 +00:00
1
This commit is contained in:
@@ -0,0 +1,306 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
// tf_nav_mesh_edit.cpp
|
||||
// TF specific nav mesh editing
|
||||
// Michael Booth, May 2009
|
||||
|
||||
#include "cbase.h"
|
||||
#include "tf_nav_mesh.h"
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
class CTFAttributeClearer
|
||||
{
|
||||
public:
|
||||
CTFAttributeClearer( TFNavAttributeType attribute )
|
||||
{
|
||||
m_attribute = attribute;
|
||||
}
|
||||
|
||||
bool operator() ( CNavArea *baseArea )
|
||||
{
|
||||
CTFNavArea *area = (CTFNavArea *)baseArea;
|
||||
|
||||
area->ClearAttributeTF( m_attribute );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TFNavAttributeType m_attribute;
|
||||
};
|
||||
|
||||
void TF_EditClearAllAttributes( void )
|
||||
{
|
||||
CTFAttributeClearer clear( (TFNavAttributeType)0xFFFFFFFF );
|
||||
TheNavMesh->ForAllSelectedAreas( clear );
|
||||
TheNavMesh->ClearSelectedSet();
|
||||
}
|
||||
static ConCommand ClearAllAttributes( "tf_wipe_attributes", TF_EditClearAllAttributes, "Clear all TF-specific attributes of selected area.", FCVAR_CHEAT );
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
struct AttributeLookup
|
||||
{
|
||||
const char *name;
|
||||
TFNavAttributeType attribute;
|
||||
};
|
||||
|
||||
static AttributeLookup s_TFAttributeTable[] =
|
||||
{
|
||||
{ "BLUE_SETUP_GATE", TF_NAV_BLUE_SETUP_GATE },
|
||||
{ "RED_SETUP_GATE", TF_NAV_RED_SETUP_GATE },
|
||||
{ "BLOCKED_AFTER_POINT_CAPTURE", TF_NAV_BLOCKED_AFTER_POINT_CAPTURE },
|
||||
{ "BLOCKED_UNTIL_POINT_CAPTURE", TF_NAV_BLOCKED_UNTIL_POINT_CAPTURE },
|
||||
{ "BLUE_ONE_WAY_DOOR", TF_NAV_BLUE_ONE_WAY_DOOR },
|
||||
{ "RED_ONE_WAY_DOOR", TF_NAV_RED_ONE_WAY_DOOR },
|
||||
|
||||
{ "SNIPER_SPOT", TF_NAV_SNIPER_SPOT },
|
||||
{ "SENTRY_SPOT", TF_NAV_SENTRY_SPOT },
|
||||
{ "NO_SPAWNING", TF_NAV_NO_SPAWNING },
|
||||
{ "RESCUE_CLOSET", TF_NAV_RESCUE_CLOSET },
|
||||
|
||||
{ "DOOR_ALWAYS_BLOCKS", TF_NAV_DOOR_ALWAYS_BLOCKS },
|
||||
{ "DOOR_NEVER_BLOCKS", TF_NAV_DOOR_NEVER_BLOCKS },
|
||||
{ "UNBLOCKABLE", TF_NAV_UNBLOCKABLE },
|
||||
|
||||
{ "WITH_SECOND_POINT", TF_NAV_WITH_SECOND_POINT },
|
||||
{ "WITH_THIRD_POINT", TF_NAV_WITH_THIRD_POINT },
|
||||
{ "WITH_FOURTH_POINT", TF_NAV_WITH_FOURTH_POINT },
|
||||
{ "WITH_FIFTH_POINT", TF_NAV_WITH_FIFTH_POINT },
|
||||
|
||||
{ NULL, TF_NAV_INVALID }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Can be used with any command that takes an attribute as its 2nd argument
|
||||
*/
|
||||
static int AttributeAutocomplete( const char *input, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] )
|
||||
{
|
||||
if ( Q_strlen( input ) >= COMMAND_COMPLETION_ITEM_LENGTH )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
char command[ COMMAND_COMPLETION_ITEM_LENGTH+1 ];
|
||||
Q_strncpy( command, input, sizeof( command ) );
|
||||
|
||||
// skip to start of argument
|
||||
char *partialArg = Q_strrchr( command, ' ' );
|
||||
if ( partialArg == NULL )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// chop command from partial argument
|
||||
*partialArg = '\000';
|
||||
++partialArg;
|
||||
|
||||
int partialArgLength = Q_strlen( partialArg );
|
||||
|
||||
int count = 0;
|
||||
for( unsigned int i=0; s_TFAttributeTable[i].name && count < COMMAND_COMPLETION_MAXITEMS; ++i )
|
||||
{
|
||||
if ( !Q_strnicmp( s_TFAttributeTable[i].name, partialArg, partialArgLength ) )
|
||||
{
|
||||
// Add to the autocomplete array
|
||||
Q_snprintf( commands[ count++ ], COMMAND_COMPLETION_ITEM_LENGTH, "%s %s", command, s_TFAttributeTable[i].name );
|
||||
}
|
||||
}
|
||||
|
||||
/* all of these are deprecated
|
||||
for( unsigned int i=0; TheNavAttributeTable[i].name && count < COMMAND_COMPLETION_MAXITEMS; ++i )
|
||||
{
|
||||
if ( !Q_strnicmp( TheNavAttributeTable[i].name, partialArg, partialArgLength ) )
|
||||
{
|
||||
// Add to the autocomplete array
|
||||
Q_snprintf( commands[ count++ ], COMMAND_COMPLETION_ITEM_LENGTH, "%s %s", command, TheNavAttributeTable[i].name );
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
TFNavAttributeType NameToTFAttribute( const char *name )
|
||||
{
|
||||
for( unsigned int i=0; s_TFAttributeTable[i].name; ++i )
|
||||
{
|
||||
if ( !Q_stricmp( s_TFAttributeTable[i].name, name ) )
|
||||
{
|
||||
return s_TFAttributeTable[i].attribute;
|
||||
}
|
||||
}
|
||||
|
||||
return TF_NAV_INVALID;
|
||||
}
|
||||
|
||||
|
||||
const char *TFAttributeToName( TFNavAttributeType attribute )
|
||||
{
|
||||
for( unsigned int i=0; s_TFAttributeTable[i].name; ++i )
|
||||
{
|
||||
if ( s_TFAttributeTable[i].attribute == attribute )
|
||||
{
|
||||
return s_TFAttributeTable[i].name;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void TF_EditClearAttribute( const CCommand &args )
|
||||
{
|
||||
if ( args.ArgC() < 2 )
|
||||
{
|
||||
Msg( "Usage: %s <attribute1> [attribute2...]\n", args[0] );
|
||||
return;
|
||||
}
|
||||
|
||||
for ( int i = 1; i < args.ArgC(); ++i )
|
||||
{
|
||||
TFNavAttributeType spawnAttribute = NameToTFAttribute( args[i] );
|
||||
NavAttributeType navAttribute = NameToNavAttribute( args[i] );
|
||||
|
||||
if ( spawnAttribute != TF_NAV_INVALID )
|
||||
{
|
||||
CTFAttributeClearer clear( spawnAttribute );
|
||||
TheNavMesh->ForAllSelectedAreas( clear );
|
||||
}
|
||||
else if ( navAttribute != NAV_MESH_INVALID )
|
||||
{
|
||||
NavAttributeClearer clear( navAttribute );
|
||||
TheNavMesh->ForAllSelectedAreas( clear );
|
||||
}
|
||||
else
|
||||
{
|
||||
Msg( "Unknown attribute '%s'", args[i] );
|
||||
}
|
||||
}
|
||||
|
||||
TheNavMesh->ClearSelectedSet();
|
||||
}
|
||||
static ConCommand ClearAttributeTF( "tf_clear_attribute", TF_EditClearAttribute, "Remove given attribute from all areas in the selected set.", FCVAR_CHEAT, AttributeAutocomplete );
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
class CTFAttributeToggler
|
||||
{
|
||||
public:
|
||||
CTFAttributeToggler( TFNavAttributeType attribute )
|
||||
{
|
||||
m_attribute = attribute;
|
||||
}
|
||||
|
||||
bool operator() ( CNavArea *baseArea )
|
||||
{
|
||||
CTFNavArea *area = (CTFNavArea *)baseArea;
|
||||
|
||||
// only toggle if dealing with a single selected area
|
||||
if ( TheNavMesh->IsSelectedSetEmpty() && area->HasAttributeTF( m_attribute ) )
|
||||
{
|
||||
area->ClearAttributeTF( m_attribute );
|
||||
}
|
||||
else
|
||||
{
|
||||
area->SetAttributeTF( m_attribute );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TFNavAttributeType m_attribute;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void TF_EditMarkAttribute( const CCommand &args )
|
||||
{
|
||||
if ( args.ArgC() < 2 )
|
||||
{
|
||||
Msg( "Usage: %s <attribute> [attribute2...]\n", args[0] );
|
||||
return;
|
||||
}
|
||||
|
||||
for ( int i = 1; i < args.ArgC(); ++i )
|
||||
{
|
||||
TFNavAttributeType spawnAttribute = NameToTFAttribute( args[i] );
|
||||
NavAttributeType navAttribute = NameToNavAttribute( args[i] );
|
||||
|
||||
if ( spawnAttribute != TF_NAV_INVALID )
|
||||
{
|
||||
CTFAttributeToggler toggle( spawnAttribute );
|
||||
TheNavMesh->ForAllSelectedAreas( toggle );
|
||||
}
|
||||
else if ( navAttribute != NAV_MESH_INVALID )
|
||||
{
|
||||
NavAttributeToggler clear( navAttribute );
|
||||
TheNavMesh->ForAllSelectedAreas( clear );
|
||||
}
|
||||
else
|
||||
{
|
||||
Msg( "Unknown attribute '%s'", args[i] );
|
||||
}
|
||||
}
|
||||
|
||||
TheNavMesh->ClearSelectedSet();
|
||||
}
|
||||
static ConCommand MarkAttribute( "tf_mark", TF_EditMarkAttribute, "Set attribute of selected area.", FCVAR_CHEAT, AttributeAutocomplete );
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
void TF_EditSelectWithAttribute( const CCommand &args )
|
||||
{
|
||||
TheNavMesh->ClearSelectedSet();
|
||||
|
||||
if ( args.ArgC() != 2 )
|
||||
{
|
||||
Msg( "Usage: %s <attribute>\n", args[0] );
|
||||
return;
|
||||
}
|
||||
|
||||
TFNavAttributeType spawnAttribute = NameToTFAttribute( args[1] );
|
||||
|
||||
int count = 0;
|
||||
|
||||
if ( spawnAttribute != TF_NAV_INVALID )
|
||||
{
|
||||
FOR_EACH_VEC( TheNavAreas, it )
|
||||
{
|
||||
CTFNavArea *area = (CTFNavArea *)TheNavAreas[ it ];
|
||||
|
||||
if ( area->HasAttributeTF( spawnAttribute ) )
|
||||
{
|
||||
TheNavMesh->AddToSelectedSet( area );
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NavAttributeType navAttribute = NameToNavAttribute( args[1] );
|
||||
if ( navAttribute != NAV_MESH_INVALID )
|
||||
{
|
||||
FOR_EACH_VEC( TheNavAreas, it )
|
||||
{
|
||||
CNavArea *area = TheNavAreas[ it ];
|
||||
|
||||
if ( area->GetAttributes() & navAttribute )
|
||||
{
|
||||
TheNavMesh->AddToSelectedSet( area );
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Msg( "Unknown attribute '%s'", args[1] );
|
||||
}
|
||||
}
|
||||
|
||||
Msg( "%d areas added to selection\n", count );
|
||||
}
|
||||
static ConCommand SelectWithAttribute( "tf_select_with_attribute", TF_EditSelectWithAttribute, "Selects areas with the given attribute.", FCVAR_CHEAT, AttributeAutocomplete );
|
||||
|
||||
Reference in New Issue
Block a user