2019-07-01 21:10:00 +03:00
//
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
// Copyright (c) YaPB Development Team.
//
// This software is licensed under the BSD-style license.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://yapb.ru/license
//
# include <yapb.h>
2019-08-24 12:43:42 +03:00
ConVar yb_display_menu_text ( " yb_display_menu_text " , " 1 " , " Enables or disables display menu text, when players asks for menu. Useful only for Android. " ) ;
ConVar yb_password ( " yb_password " , " " , " The value (password) for the setinfo key , if user set ' s correct password , he ' s gains access to bot commands and menus . " , false, 0.0f, 0.0f, Var::Password) ;
ConVar yb_password_key ( " yb_password_key " , " _ybpw " , " The name of setinfo key used to store password to bot commands and menus " , false ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
int BotControl : : cmdAddBot ( ) {
2019-07-01 21:10:00 +03:00
enum args { alias = 1 , difficulty , personality , team , model , name , max } ;
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
2019-07-27 17:36:24 +03:00
// this is duplicate error as in main bot creation code, but not to be silent
if ( ! graph . length ( ) | | graph . hasChanged ( ) ) {
2019-07-28 15:47:46 +03:00
ctrl . msg ( " There is no graph found or graph is changed. Cannot create bot. " ) ;
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
}
2019-07-01 21:10:00 +03:00
// if team is specified, modify args to set team
2019-08-18 21:00:00 +03:00
if ( m_args [ alias ] . find ( " _ct " , 0 ) ! = String : : InvalidIndex ) {
2019-07-01 21:10:00 +03:00
m_args . set ( team , " 2 " ) ;
}
2019-08-18 21:00:00 +03:00
else if ( m_args [ alias ] . find ( " _t " , 0 ) ! = String : : InvalidIndex ) {
2019-07-01 21:10:00 +03:00
m_args . set ( team , " 1 " ) ;
}
// if highskilled bot is requsted set personality to rusher and maxout difficulty
2019-08-18 21:00:00 +03:00
if ( m_args [ alias ] . find ( " hs " , 0 ) ! = String : : InvalidIndex ) {
2019-07-01 21:10:00 +03:00
m_args . set ( difficulty , " 4 " ) ;
m_args . set ( personality , " 1 " ) ;
}
bots . addbot ( m_args [ name ] , m_args [ difficulty ] , m_args [ personality ] , m_args [ team ] , m_args [ model ] , true ) ;
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdKickBot ( ) {
2019-07-01 21:10:00 +03:00
enum args { alias = 1 , team , max } ;
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
// if team is specified, kick from specified tram
2019-08-18 21:00:00 +03:00
if ( m_args [ alias ] . find ( " _ct " , 0 ) ! = String : : InvalidIndex | | getInt ( team ) = = 2 | | getStr ( team ) = = " ct " ) {
2019-07-27 17:36:24 +03:00
bots . kickFromTeam ( Team : : CT ) ;
2019-07-01 21:10:00 +03:00
}
2019-08-18 21:00:00 +03:00
else if ( m_args [ alias ] . find ( " _t " , 0 ) ! = String : : InvalidIndex | | getInt ( team ) = = 1 | | getStr ( team ) = = " t " ) {
2019-07-27 17:36:24 +03:00
bots . kickFromTeam ( Team : : Terrorist ) ;
2019-07-01 21:10:00 +03:00
}
else {
bots . kickRandom ( ) ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdKickBots ( ) {
2019-07-01 21:10:00 +03:00
enum args { alias = 1 , instant , max } ;
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
// check if we're need to remove bots instantly
auto kickInstant = getStr ( instant ) = = " instant " ;
// kick the bots
bots . kickEveryone ( kickInstant ) ;
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdKillBots ( ) {
2019-07-01 21:10:00 +03:00
enum args { alias = 1 , team , max } ;
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
// if team is specified, kick from specified tram
2019-08-18 21:00:00 +03:00
if ( m_args [ alias ] . find ( " _ct " , 0 ) ! = String : : InvalidIndex | | getInt ( team ) = = 2 | | getStr ( team ) = = " ct " ) {
2019-07-27 17:36:24 +03:00
bots . killAllBots ( Team : : CT ) ;
2019-07-01 21:10:00 +03:00
}
2019-08-18 21:00:00 +03:00
else if ( m_args [ alias ] . find ( " _t " , 0 ) ! = String : : InvalidIndex | | getInt ( team ) = = 1 | | getStr ( team ) = = " t " ) {
2019-07-27 17:36:24 +03:00
bots . killAllBots ( Team : : Terrorist ) ;
2019-07-01 21:10:00 +03:00
}
else {
bots . killAllBots ( ) ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdFill ( ) {
2019-07-01 21:10:00 +03:00
enum args { alias = 1 , team , count , difficulty , personality , max } ;
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
if ( ! hasArg ( team ) ) {
2019-07-27 17:36:24 +03:00
return BotCommandResult : : BadFormat ;
2019-07-01 21:10:00 +03:00
}
bots . serverFill ( getInt ( team ) , hasArg ( personality ) ? getInt ( personality ) : - 1 , hasArg ( difficulty ) ? getInt ( difficulty ) : - 1 , hasArg ( count ) ? getInt ( count ) : - 1 ) ;
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdVote ( ) {
2019-07-01 21:10:00 +03:00
enum args { alias = 1 , mapid , max } ;
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
if ( ! hasArg ( mapid ) ) {
2019-07-27 17:36:24 +03:00
return BotCommandResult : : BadFormat ;
2019-07-01 21:10:00 +03:00
}
int mapID = getInt ( mapid ) ;
// loop through all players
2019-07-27 17:36:24 +03:00
for ( const auto & bot : bots ) {
bot - > m_voteMap = mapID ;
2019-07-01 21:10:00 +03:00
}
msg ( " All dead bots will vote for map #%d " , mapID ) ;
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdWeaponMode ( ) {
2019-07-01 21:10:00 +03:00
enum args { alias = 1 , type , max } ;
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
if ( ! hasArg ( type ) ) {
2019-07-27 17:36:24 +03:00
return BotCommandResult : : BadFormat ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
Dictionary < String , int > modes ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
modes . push ( " kinfe " , 1 ) ;
modes . push ( " pistol " , 2 ) ;
modes . push ( " shotgun " , 3 ) ;
modes . push ( " smg " , 4 ) ;
modes . push ( " rifle " , 5 ) ;
modes . push ( " sniper " , 6 ) ;
2019-08-07 15:25:14 +03:00
modes . push ( " standard " , 7 ) ;
2019-07-01 21:10:00 +03:00
auto mode = getStr ( type ) ;
// check if selected mode exists
if ( ! modes . exists ( mode ) ) {
2019-07-27 17:36:24 +03:00
return BotCommandResult : : BadFormat ;
2019-07-01 21:10:00 +03:00
}
bots . setWeaponMode ( modes [ mode ] ) ;
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdVersion ( ) {
2019-08-24 12:43:42 +03:00
auto hash = String ( PRODUCT_GIT_HASH ) . substr ( 0 , 8 ) ;
auto author = String ( PRODUCT_GIT_COMMIT_AUTHOR ) ;
// if no hash specified, set local one
if ( hash . startsWith ( " unspe " ) ) {
hash = " local " ;
}
// if no commit author, set local one
if ( author . startsWith ( " unspe " ) ) {
author = PRODUCT_EMAIL ;
}
2019-07-01 21:10:00 +03:00
msg ( " %s v%s (build %u) " , PRODUCT_NAME , PRODUCT_VERSION , util . buildNumber ( ) ) ;
2019-08-24 12:43:42 +03:00
msg ( " compiled: %s %s by %s " , __DATE__ , __TIME__ , author . chars ( ) ) ;
if ( ! hash . startsWith ( " local " ) ) {
msg ( " commit: %scommit/%s " , PRODUCT_COMMENTS , hash . chars ( ) ) ;
}
2019-07-01 21:10:00 +03:00
msg ( " url: %s " , PRODUCT_URL ) ;
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodeMenu ( ) {
2019-07-01 21:10:00 +03:00
enum args { alias = 1 , max } ;
2019-07-27 17:36:24 +03:00
// graph editor is available only with editor
if ( ! graph . hasEditor ( ) ) {
msg ( " Unable to open graph editor without setting the editor player. " ) ;
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : NodeMainPage1 ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdMenu ( ) {
2019-07-01 21:10:00 +03:00
enum args { alias = 1 , cmd , max } ;
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
// reset the current menu
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ;
2019-07-01 21:10:00 +03:00
if ( getStr ( cmd ) = = " cmd " & & util . isAlive ( m_ent ) ) {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : Commands ) ;
2019-07-01 21:10:00 +03:00
}
else {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : Main ) ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdList ( ) {
2019-07-01 21:10:00 +03:00
enum args { alias = 1 , max } ;
bots . listBots ( ) ;
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-08-24 12:43:42 +03:00
int BotControl : : cmdCvars ( ) {
enum args { alias = 1 , pattern , max } ;
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
const auto & match = getStr ( pattern ) ;
const bool isSave = match = = " save " ;
File cfg ;
// if save requested, dump cvars to yapb.cfg
if ( isSave ) {
cfg . open ( strings . format ( " %s/addons/yapb/conf/yapb.cfg " , game . getModName ( ) ) , " wt " ) ;
cfg . puts ( " // Configuration file for %s \n \n " , PRODUCT_SHORT_NAME ) ;
}
for ( const auto & cvar : game . getCvars ( ) ) {
if ( cvar . info . empty ( ) ) {
continue ;
}
if ( ! isSave & & match ! = " empty " & & ! strstr ( cvar . reg . name , match . chars ( ) ) ) {
continue ;
}
// float value ?
bool isFloat = ! strings . isEmpty ( cvar . self - > str ( ) ) & & strstr ( cvar . self - > str ( ) , " . " ) ;
if ( isSave ) {
cfg . puts ( " // \n " ) ;
cfg . puts ( " // %s \n " , String : : join ( cvar . info . split ( " \n " ) , " \n // " ) . chars ( ) ) ;
cfg . puts ( " // --- \n " ) ;
if ( cvar . bounded ) {
if ( isFloat ) {
cfg . puts ( " // Default: \" %.1f \" , Min: \" %.1f \" , Max: \" %.1f \" \n " , cvar . initial , cvar . min , cvar . max ) ;
}
else {
cfg . puts ( " // Default: \" %i \" , Min: \" %i \" , Max: \" %i \" \n " , static_cast < int > ( cvar . initial ) , static_cast < int > ( cvar . min ) , static_cast < int > ( cvar . max ) ) ;
}
}
else {
cfg . puts ( " // Default: \" %s \" \n " , cvar . self - > str ( ) ) ;
}
cfg . puts ( " // \n " ) ;
if ( cvar . bounded ) {
if ( isFloat ) {
cfg . puts ( " %s \" %.1f \" \n " , cvar . reg . name , cvar . self - > float_ ( ) ) ;
}
else {
cfg . puts ( " %s \" %i \" \n " , cvar . reg . name , cvar . self - > int_ ( ) ) ;
}
}
else {
cfg . puts ( " %s \" %s \" \n " , cvar . reg . name , cvar . self - > str ( ) ) ;
}
cfg . puts ( " \n " ) ;
}
else {
game . print ( " cvar: %s " , cvar . reg . name ) ;
game . print ( " info: %s " , cvar . info . chars ( ) ) ;
game . print ( " " ) ;
}
}
if ( isSave ) {
ctrl . msg ( " Bots cvars has been written to file. " ) ;
cfg . close ( ) ;
}
return BotCommandResult : : Handled ;
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNode ( ) {
2019-07-01 21:10:00 +03:00
enum args { root , alias , cmd , cmd2 , max } ;
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
2019-07-27 17:36:24 +03:00
// graph editor supported only with editor
if ( game . isDedicated ( ) & & ! graph . hasEditor ( ) & & getStr ( cmd ) ! = " acquire_editor " ) {
msg ( " Unable to use graph edit commands without setting graph editor player. Please use \" graph acquire_editor \" to acquire rights for graph editing. " ) ;
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
// should be moved to class?
2019-07-27 17:36:24 +03:00
static Dictionary < String , BotCmd > commands ;
static StringArray descriptions ;
2019-07-01 21:10:00 +03:00
// fill only once
if ( descriptions . empty ( ) ) {
// separate function
2019-07-27 17:36:24 +03:00
auto pushGraphCmd = [ & ] ( String cmd , String format , String help , Handler handler ) - > void {
BotCmd botCmd ( cr : : move ( cmd ) , cr : : move ( format ) , cr : : move ( help ) , cr : : move ( handler ) ) ;
commands . push ( cmd , cr : : move ( botCmd ) ) ;
2019-07-01 21:10:00 +03:00
descriptions . push ( cmd ) ;
} ;
2019-07-27 17:36:24 +03:00
// add graph commands
pushGraphCmd ( " on " , " on [display|auto|noclip|models] " , " Enables displaying of graph, nodes, noclip cheat " , & BotControl : : cmdNodeOn ) ;
pushGraphCmd ( " off " , " off [display|auto|noclip|models] " , " Disables displaying of graph, auto adding nodes, noclip cheat " , & BotControl : : cmdNodeOff ) ;
pushGraphCmd ( " menu " , " menu [noarguments] " , " Opens and displays bots graph edtior. " , & BotControl : : cmdNodeMenu ) ;
pushGraphCmd ( " add " , " add [noarguments] " , " Opens and displays graph node add menu. " , & BotControl : : cmdNodeAdd ) ;
pushGraphCmd ( " addbasic " , " menu [noarguments] " , " Adds basic nodes such as player spawn points, goals and ladders. " , & BotControl : : cmdNodeAddBasic ) ;
pushGraphCmd ( " save " , " save [noarguments] " , " Save graph file to disk. " , & BotControl : : cmdNodeSave ) ;
pushGraphCmd ( " load " , " load [noarguments] " , " Load graph file from disk. " , & BotControl : : cmdNodeLoad ) ;
pushGraphCmd ( " erase " , " erase [iamsure] " , " Erases the graph file from disk. " , & BotControl : : cmdNodeErase ) ;
pushGraphCmd ( " delete " , " delete [nearest|index] " , " Deletes single graph node from map. " , & BotControl : : cmdNodeDelete ) ;
pushGraphCmd ( " check " , " check [noarguments] " , " Check if graph working correctly. " , & BotControl : : cmdNodeCheck ) ;
pushGraphCmd ( " cache " , " cache [nearest|index] " , " Caching node for future use. " , & BotControl : : cmdNodeCache ) ;
pushGraphCmd ( " clean " , " clean [all|nearest|index] " , " Clean useless path connections from all or single node. " , & BotControl : : cmdNodeClean ) ;
pushGraphCmd ( " setradius " , " setradius [radius] [nearest|index] " , " Sets the radius for node. " , & BotControl : : cmdNodeSetRadius ) ;
pushGraphCmd ( " flags " , " flags [noarguments] " , " Open and displays menu for modifying flags for nearest point. " , & BotControl : : cmdNodeSetFlags ) ;
pushGraphCmd ( " teleport " , " teleport [index] " , " Teleports player to specified node index. " , & BotControl : : cmdNodeTeleport ) ;
pushGraphCmd ( " upload " , " upload [id] " , " Uploads created graph to graph database. " , & BotControl : : cmdNodeUpload ) ;
2019-07-01 21:10:00 +03:00
// add path commands
2019-07-27 17:36:24 +03:00
pushGraphCmd ( " path_create " , " path_create [noarguments] " , " Opens and displays path creation menu. " , & BotControl : : cmdNodePathCreate ) ;
pushGraphCmd ( " path_create_in " , " path_create_in [noarguments] " , " Opens and displays path creation menu. " , & BotControl : : cmdNodePathCreate ) ;
pushGraphCmd ( " path_create_out " , " path_create_out [noarguments] " , " Opens and displays path creation menu. " , & BotControl : : cmdNodePathCreate ) ;
pushGraphCmd ( " path_create_both " , " path_create_both [noarguments] " , " Opens and displays path creation menu. " , & BotControl : : cmdNodePathCreate ) ;
pushGraphCmd ( " path_delete " , " path_create_both [noarguments] " , " Opens and displays path creation menu. " , & BotControl : : cmdNodePathDelete ) ;
pushGraphCmd ( " path_set_autopath " , " path_set_autoath [max_distance] " , " Opens and displays path creation menu. " , & BotControl : : cmdNodePathSetAutoDistance ) ;
2019-08-30 10:52:31 +03:00
// camp points iterator
pushGraphCmd ( " iterate_camp " , " iterate_camp [begin|end|next] " , " Allows to go through all camp points on map. " , & BotControl : : cmdNodeIterateCamp ) ;
2019-07-27 17:36:24 +03:00
// remote graph editing stuff
2019-07-01 21:10:00 +03:00
if ( game . isDedicated ( ) ) {
2019-07-27 17:36:24 +03:00
pushGraphCmd ( " acquire_editor " , " acquire_editor [max_distance] " , " Acquires rights to edit graph on dedicated server. " , & BotControl : : cmdNodeAcquireEditor ) ;
pushGraphCmd ( " release_editor " , " acquire_editor [max_distance] " , " Releases graph editing rights. " , & BotControl : : cmdNodeAcquireEditor ) ;
2019-07-01 21:10:00 +03:00
}
}
if ( commands . exists ( getStr ( cmd ) ) ) {
2019-07-27 17:36:24 +03:00
auto item = commands [ getStr ( cmd ) ] ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
// graph have only bad format return status
2019-07-01 21:10:00 +03:00
int status = ( this - > * item . handler ) ( ) ;
2019-07-27 17:36:24 +03:00
if ( status = = BotCommandResult : : BadFormat ) {
2019-07-01 21:10:00 +03:00
msg ( " Incorrect usage of \" %s %s %s \" command. Correct usage is: \n \n \t %s \n \n Please use correct format. " , m_args [ root ] . chars ( ) , m_args [ alias ] . chars ( ) , item . name . chars ( ) , item . format . chars ( ) ) ;
}
}
else {
if ( getStr ( cmd ) = = " help " & & hasArg ( cmd2 ) & & commands . exists ( getStr ( cmd2 ) ) ) {
auto & item = commands [ getStr ( cmd2 ) ] ;
msg ( " Command: \" %s %s %s \" \n Format: %s \n Help: %s " , m_args [ root ] . chars ( ) , m_args [ alias ] . chars ( ) , item . name . chars ( ) , item . format . chars ( ) , item . help . chars ( ) ) ;
}
else {
for ( auto & desc : descriptions ) {
auto & item = commands [ desc ] ;
msg ( " %s - %s " , item . name . chars ( ) , item . help . chars ( ) ) ;
}
2019-07-27 17:36:24 +03:00
msg ( " Currently Graph Status %s " , graph . hasEditFlag ( GraphEdit : : On ) ? " Enabled " : " Disabled " ) ;
2019-07-01 21:10:00 +03:00
}
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodeOn ( ) {
2019-07-01 21:10:00 +03:00
enum args { alias = 1 , cmd , option , max } ;
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
// enable various features of editor
if ( getStr ( option ) = = " empty " | | getStr ( option ) = = " display " | | getStr ( option ) = = " models " ) {
2019-07-27 17:36:24 +03:00
graph . setEditFlag ( GraphEdit : : On ) ;
2019-07-01 21:10:00 +03:00
enableDrawModels ( true ) ;
2019-07-27 17:36:24 +03:00
msg ( " Graph editor has been enabled. " ) ;
2019-07-01 21:10:00 +03:00
}
else if ( getStr ( option ) = = " noclip " ) {
m_ent - > v . movetype = MOVETYPE_NOCLIP ;
2019-07-27 17:36:24 +03:00
graph . setEditFlag ( GraphEdit : : On | GraphEdit : : Noclip ) ;
2019-07-01 21:10:00 +03:00
enableDrawModels ( true ) ;
2019-07-27 17:36:24 +03:00
msg ( " Graph editor has been enabled with noclip mode. " ) ;
2019-07-01 21:10:00 +03:00
}
else if ( getStr ( option ) = = " auto " ) {
2019-07-27 17:36:24 +03:00
graph . setEditFlag ( GraphEdit : : On | GraphEdit : : Auto ) ;
2019-07-01 21:10:00 +03:00
enableDrawModels ( true ) ;
2019-07-27 17:36:24 +03:00
msg ( " Graph editor has been enabled with auto add node mode. " ) ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
if ( graph . hasEditFlag ( GraphEdit : : On ) ) {
2019-07-01 21:10:00 +03:00
extern ConVar mp_roundtime , mp_freezetime , mp_timelimit ;
mp_roundtime . set ( 9 ) ;
mp_freezetime . set ( 0 ) ;
mp_timelimit . set ( 0 ) ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodeOff ( ) {
enum args { graph_cmd = 1 , cmd , option , max } ;
2019-07-01 21:10:00 +03:00
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
// enable various features of editor
if ( getStr ( option ) = = " empty " | | getStr ( option ) = = " display " ) {
2019-07-27 17:36:24 +03:00
graph . clearEditFlag ( GraphEdit : : On | GraphEdit : : Auto | GraphEdit : : Noclip ) ;
2019-07-01 21:10:00 +03:00
enableDrawModels ( false ) ;
2019-07-27 17:36:24 +03:00
msg ( " Graph editor has been disabled. " ) ;
2019-07-01 21:10:00 +03:00
}
else if ( getStr ( option ) = = " models " ) {
enableDrawModels ( false ) ;
2019-07-27 17:36:24 +03:00
msg ( " Graph editor has disabled spawn points highlighting. " ) ;
2019-07-01 21:10:00 +03:00
}
else if ( getStr ( option ) = = " noclip " ) {
m_ent - > v . movetype = MOVETYPE_WALK ;
2019-07-27 17:36:24 +03:00
graph . clearEditFlag ( GraphEdit : : Noclip ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
msg ( " Graph editor has disabled noclip mode. " ) ;
2019-07-01 21:10:00 +03:00
}
else if ( getStr ( option ) = = " auto " ) {
2019-07-27 17:36:24 +03:00
graph . clearEditFlag ( GraphEdit : : Auto ) ;
msg ( " Graph editor has disabled auto add node mode. " ) ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodeAdd ( ) {
enum args { graph_cmd = 1 , cmd , max } ;
2019-07-01 21:10:00 +03:00
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
2019-07-27 17:36:24 +03:00
// turn graph on
graph . setEditFlag ( GraphEdit : : On ) ;
2019-07-01 21:10:00 +03:00
// show the menu
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : NodeType ) ;
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodeAddBasic ( ) {
enum args { graph_cmd = 1 , cmd , max } ;
2019-07-01 21:10:00 +03:00
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
2019-07-27 17:36:24 +03:00
// turn graph on
graph . setEditFlag ( GraphEdit : : On ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
graph . addBasic ( ) ;
msg ( " Basic graph nodes was added. " ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodeSave ( ) {
enum args { graph_cmd = 1 , cmd , option , max } ;
2019-07-01 21:10:00 +03:00
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
// if no check is set save anyway
2019-07-27 17:36:24 +03:00
if ( getStr ( option ) = = " nocheck " ) {
graph . saveGraphData ( ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
msg ( " All nodes has been saved and written to disk (IGNORING QUALITY CONTROL). " ) ;
}
else if ( getStr ( option ) = = " old " ) {
graph . saveOldFormat ( ) ;
msg ( " All nodes has been saved and written to disk (POD-Bot Format (.pwf)). " ) ;
2019-07-01 21:10:00 +03:00
}
else {
2019-07-27 17:36:24 +03:00
if ( graph . checkNodes ( false ) ) {
graph . saveGraphData ( ) ;
msg ( " All nodes has been saved and written to disk. " ) ;
2019-07-01 21:10:00 +03:00
}
else {
2019-07-27 17:36:24 +03:00
msg ( " Could not save save nodes to disk. Graph check has failed. " ) ;
2019-07-01 21:10:00 +03:00
}
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodeLoad ( ) {
enum args { graph_cmd = 1 , cmd , max } ;
2019-07-01 21:10:00 +03:00
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
2019-07-27 17:36:24 +03:00
// just save graph on request
if ( graph . loadGraphData ( ) ) {
msg ( " Graph successfully loaded. " ) ;
2019-07-01 21:10:00 +03:00
}
else {
2019-07-27 17:36:24 +03:00
msg ( " Could not load Graph. See console... " ) ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodeErase ( ) {
enum args { graph_cmd = 1 , cmd , iamsure , max } ;
2019-07-01 21:10:00 +03:00
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
2019-07-27 17:36:24 +03:00
// prevent accidents when graph are deleted unintentionally
2019-07-01 21:10:00 +03:00
if ( getStr ( iamsure ) = = " iamsure " ) {
2019-07-27 17:36:24 +03:00
graph . eraseFromDisk ( ) ;
2019-07-01 21:10:00 +03:00
}
else {
2019-07-27 17:36:24 +03:00
msg ( " Please, append \" iamsure \" as parameter to get graph erased from the disk. " ) ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodeDelete ( ) {
enum args { graph_cmd = 1 , cmd , nearest , max } ;
2019-07-01 21:10:00 +03:00
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
2019-07-27 17:36:24 +03:00
// turn graph on
graph . setEditFlag ( GraphEdit : : On ) ;
2019-07-01 21:10:00 +03:00
// if "neareset" or nothing passed delete neareset, else delete by index
if ( getStr ( nearest ) = = " empty " | | getStr ( nearest ) = = " nearest " ) {
2019-07-27 17:36:24 +03:00
graph . erase ( kInvalidNodeIndex ) ;
2019-07-01 21:10:00 +03:00
}
else {
int index = getInt ( nearest ) ;
// check for existence
2019-07-27 17:36:24 +03:00
if ( graph . exists ( index ) ) {
graph . erase ( index ) ;
msg ( " Node #%d has beed deleted. " , index ) ;
2019-07-01 21:10:00 +03:00
}
else {
2019-07-27 17:36:24 +03:00
msg ( " Could not delete node #%d. " , index ) ;
2019-07-01 21:10:00 +03:00
}
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodeCheck ( ) {
enum args { graph_cmd = 1 , cmd , max } ;
2019-07-01 21:10:00 +03:00
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
// check if nodes are ok
2019-07-27 17:36:24 +03:00
if ( graph . checkNodes ( true ) ) {
msg ( " Graph seems to be OK. " ) ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodeCache ( ) {
enum args { graph_cmd = 1 , cmd , nearest , max } ;
2019-07-01 21:10:00 +03:00
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
2019-07-27 17:36:24 +03:00
// turn graph on
graph . setEditFlag ( GraphEdit : : On ) ;
2019-07-01 21:10:00 +03:00
// if "neareset" or nothing passed delete neareset, else delete by index
if ( getStr ( nearest ) = = " empty " | | getStr ( nearest ) = = " nearest " ) {
2019-07-27 17:36:24 +03:00
graph . cachePoint ( kInvalidNodeIndex ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
msg ( " Nearest node has been put into the memory. " ) ;
2019-07-01 21:10:00 +03:00
}
else {
int index = getInt ( nearest ) ;
// check for existence
2019-07-27 17:36:24 +03:00
if ( graph . exists ( index ) ) {
graph . cachePoint ( index ) ;
msg ( " Node #%d has been put into the memory. " , index ) ;
2019-07-01 21:10:00 +03:00
}
else {
2019-07-27 17:36:24 +03:00
msg ( " Could not put node #%d into the memory. " , index ) ;
2019-07-01 21:10:00 +03:00
}
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodeClean ( ) {
enum args { graph_cmd = 1 , cmd , option , max } ;
2019-07-01 21:10:00 +03:00
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
2019-07-27 17:36:24 +03:00
// turn graph on
graph . setEditFlag ( GraphEdit : : On ) ;
2019-07-01 21:10:00 +03:00
// if "all" passed clean up all the paths
if ( getStr ( option ) = = " all " ) {
int removed = 0 ;
2019-07-27 17:36:24 +03:00
for ( int i = 0 ; i < graph . length ( ) ; + + i ) {
removed + = graph . clearConnections ( i ) ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
msg ( " Done. Processed %d nodes. %d useless paths was cleared. " , graph . length ( ) , removed ) ;
2019-07-01 21:10:00 +03:00
}
else if ( getStr ( option ) = = " empty " | | getStr ( option ) = = " nearest " ) {
2019-07-27 17:36:24 +03:00
int removed = graph . clearConnections ( graph . getEditorNeareset ( ) ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
msg ( " Done. Processed node #%d. %d useless paths was cleared. " , graph . getEditorNeareset ( ) , removed ) ;
2019-07-01 21:10:00 +03:00
}
else {
int index = getInt ( option ) ;
// check for existence
2019-07-27 17:36:24 +03:00
if ( graph . exists ( index ) ) {
int removed = graph . clearConnections ( index ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
msg ( " Done. Processed node #%d. %d useless paths was cleared. " , index , removed ) ;
2019-07-01 21:10:00 +03:00
}
else {
2019-07-27 17:36:24 +03:00
msg ( " Could not process node #%d clearance. " , index ) ;
2019-07-01 21:10:00 +03:00
}
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodeSetRadius ( ) {
enum args { graph_cmd = 1 , cmd , radius , index , max } ;
2019-07-01 21:10:00 +03:00
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
// radius is a must
if ( ! hasArg ( radius ) ) {
2019-07-27 17:36:24 +03:00
return BotCommandResult : : BadFormat ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int radiusIndex = kInvalidNodeIndex ;
2019-07-01 21:10:00 +03:00
if ( getStr ( index ) = = " empty " | | getStr ( index ) = = " nearest " ) {
2019-07-27 17:36:24 +03:00
radiusIndex = graph . getEditorNeareset ( ) ;
2019-07-01 21:10:00 +03:00
}
else {
radiusIndex = getInt ( index ) ;
}
2019-07-27 17:36:24 +03:00
float value = getStr ( radius ) . float_ ( ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
graph . setRadius ( radiusIndex , value ) ;
msg ( " Node #%d has been set to radius %.2f. " , radiusIndex , value ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodeSetFlags ( ) {
enum args { graph_cmd = 1 , cmd , max } ;
2019-07-01 21:10:00 +03:00
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
2019-07-27 17:36:24 +03:00
// turn graph on
graph . setEditFlag ( GraphEdit : : On ) ;
2019-07-01 21:10:00 +03:00
//show the flag menu
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : NodeFlag ) ;
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodeTeleport ( ) {
enum args { graph_cmd = 1 , cmd , teleport_index , max } ;
2019-07-01 21:10:00 +03:00
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
if ( ! hasArg ( teleport_index ) ) {
2019-07-27 17:36:24 +03:00
return BotCommandResult : : BadFormat ;
2019-07-01 21:10:00 +03:00
}
int index = getInt ( teleport_index ) ;
// check for existence
2019-07-27 17:36:24 +03:00
if ( graph . exists ( index ) ) {
engfuncs . pfnSetOrigin ( graph . getEditor ( ) , graph [ index ] . origin ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
msg ( " You have been teleported to node #%d. " , index ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
// turn graph on
graph . setEditFlag ( GraphEdit : : On | GraphEdit : : Noclip ) ;
2019-07-01 21:10:00 +03:00
}
else {
2019-07-27 17:36:24 +03:00
msg ( " Could not teleport to node #%d. " , index ) ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodePathCreate ( ) {
enum args { graph_cmd = 1 , cmd , max } ;
2019-07-01 21:10:00 +03:00
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
2019-07-27 17:36:24 +03:00
// turn graph on
graph . setEditFlag ( GraphEdit : : On ) ;
2019-07-01 21:10:00 +03:00
// choose the direction for path creation
2019-08-18 21:00:00 +03:00
if ( m_args [ cmd ] . find ( " _both " , 0 ) ! = String : : InvalidIndex ) {
2019-07-27 17:36:24 +03:00
graph . pathCreate ( PathConnection : : Bidirectional ) ;
2019-07-01 21:10:00 +03:00
}
2019-08-18 21:00:00 +03:00
else if ( m_args [ cmd ] . find ( " _in " , 0 ) ! = String : : InvalidIndex ) {
2019-07-27 17:36:24 +03:00
graph . pathCreate ( PathConnection : : Incoming ) ;
2019-07-01 21:10:00 +03:00
}
2019-08-18 21:00:00 +03:00
else if ( m_args [ cmd ] . find ( " _out " , 0 ) ! = String : : InvalidIndex ) {
2019-07-27 17:36:24 +03:00
graph . pathCreate ( PathConnection : : Outgoing ) ;
2019-07-01 21:10:00 +03:00
}
else {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : NodePath ) ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodePathDelete ( ) {
enum args { graph_cmd = 1 , cmd , max } ;
2019-07-01 21:10:00 +03:00
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
2019-07-27 17:36:24 +03:00
// turn graph on
graph . setEditFlag ( GraphEdit : : On ) ;
2019-07-01 21:10:00 +03:00
// delete the patch
2019-07-27 17:36:24 +03:00
graph . erasePath ( ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodePathSetAutoDistance ( ) {
enum args { graph_cmd = 1 , cmd , max } ;
2019-07-01 21:10:00 +03:00
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
2019-07-27 17:36:24 +03:00
// turn graph on
graph . setEditFlag ( GraphEdit : : On ) ;
showMenu ( Menu : : NodeAutoPath ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodeAcquireEditor ( ) {
enum args { graph_cmd = 1 , max } ;
2019-07-01 21:10:00 +03:00
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
if ( game . isNullEntity ( m_ent ) ) {
msg ( " This command should not be executed from HLDS console. " ) ;
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
if ( graph . hasEditor ( ) ) {
msg ( " Sorry, players \" %s \" already acquired rights to edit graph on this server. " , STRING ( graph . getEditor ( ) - > v . netname ) ) ;
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
graph . setEditor ( m_ent ) ;
msg ( " You're acquired rights to edit graph on this server. You're now able to use graph commands. " ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : cmdNodeReleaseEditor ( ) {
enum args { graph_cmd = 1 , max } ;
2019-07-01 21:10:00 +03:00
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
2019-07-27 17:36:24 +03:00
if ( ! graph . hasEditor ( ) ) {
2019-07-01 21:10:00 +03:00
msg ( " No one is currently has rights to edit. Nothing to release. " ) ;
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
graph . setEditor ( nullptr ) ;
msg ( " Graph editor rights freed. You're now not able to use graph commands. " ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
}
int BotControl : : cmdNodeUpload ( ) {
enum args { graph_cmd = 1 , cmd , id , max } ;
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
if ( ! hasArg ( id ) ) {
return BotCommandResult : : BadFormat ;
}
// do not allow to upload bad graph
if ( ! graph . checkNodes ( false ) ) {
msg ( " Sorry, unable to upload graph file that contains errors. Please type \" wp check \" to verify graph consistency. " ) ;
return BotCommandResult : : BadFormat ;
}
msg ( " \n " ) ;
msg ( " WARNING! " ) ;
msg ( " Graph uploaded to graph database in synchronous mode. That means if graph is big enough " ) ;
msg ( " you may notice the game freezes a bit during upload and issue request creation. Please, be patient. " ) ;
msg ( " \n " ) ;
// six seconds is enough?
http . setTimeout ( 6 ) ;
extern ConVar yb_graph_url ;
// try to upload the file
if ( http . uploadFile ( strings . format ( " %s/ " , yb_graph_url . str ( ) ) , strings . format ( " %sgraph/%s.graph " , graph . getDataDirectory ( false ) , game . getMapName ( ) ) ) ) {
msg ( " Graph file was uploaded and Issue Request has been created for review. " ) ;
msg ( " As soon as database administrator review your upload request, your graph will " ) ;
msg ( " be available to download for all YaPB users. You can check your issue request at: " ) ;
msg ( " URL: https://github.com/jeefo/yapb-graph/issues " ) ;
msg ( " \n " ) ;
msg ( " Thank you. " ) ;
msg ( " \n " ) ;
}
else {
String status ;
auto code = http . getLastStatusCode ( ) ;
if ( code = = HttpClientResult : : Forbidden ) {
status = " AlreadyExists " ;
}
else if ( code = = HttpClientResult : : NotFound ) {
status = " AccessDenied " ;
}
else {
status . assignf ( " %d " , code ) ;
}
msg ( " Something went wrong with uploading. Come back later. (%s) " , status . chars ( ) ) ;
msg ( " \n " ) ;
if ( code = = HttpClientResult : : Forbidden ) {
msg ( " You should create issue-request manually for this graph " ) ;
msg ( " as it's already exists in database, can't overwrite. Sorry... " ) ;
}
else {
msg ( " There is an internal error, or somethingis totally wrong with " ) ;
msg ( " your files, and they are not passed sanity checks. Sorry... " ) ;
}
msg ( " \n " ) ;
}
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-08-30 10:52:31 +03:00
int BotControl : : cmdNodeIterateCamp ( ) {
enum args { graph_cmd = 1 , cmd , option , max } ;
// adding more args to args array, if not enough passed
fixMissingArgs ( max ) ;
// turn graph on
graph . setEditFlag ( GraphEdit : : On ) ;
// get the option descriping operation
auto op = getStr ( option ) ;
if ( op ! = " begin " & & op ! = " end " & & op ! = " next " ) {
return BotCommandResult : : BadFormat ;
}
2019-08-30 11:10:22 +03:00
if ( ( op = = " next " | | op = = " end " ) & & m_campIterator . empty ( ) ) {
2019-08-30 10:52:31 +03:00
msg ( " Before calling for 'next' / 'end' camp point, you should hit 'begin'. " ) ;
return BotCommandResult : : Handled ;
}
2019-08-30 11:10:22 +03:00
else if ( op = = " begin " & & ! m_campIterator . empty ( ) ) {
2019-08-30 10:52:31 +03:00
msg ( " Before calling for 'begin' camp point, you should hit 'end'. " ) ;
return BotCommandResult : : Handled ;
}
if ( op = = " end " ) {
2019-08-30 11:10:22 +03:00
m_campIterator . clear ( ) ;
2019-08-30 10:52:31 +03:00
}
else if ( op = = " next " ) {
2019-08-30 11:10:22 +03:00
if ( ! m_campIterator . empty ( ) ) {
Vector origin = graph [ m_campIterator . first ( ) ] . origin ;
2019-08-30 10:52:31 +03:00
2019-08-30 11:10:22 +03:00
if ( graph [ m_campIterator . first ( ) ] . flags & NodeFlag : : Crouch ) {
2019-08-30 10:52:31 +03:00
origin . z + = 23.0f ;
}
engfuncs . pfnSetOrigin ( m_ent , origin ) ;
2019-08-30 11:10:22 +03:00
// go to next
m_campIterator . shift ( ) ;
2019-08-30 10:52:31 +03:00
}
else {
2019-08-30 11:10:22 +03:00
m_campIterator . clear ( ) ;
2019-08-30 10:52:31 +03:00
msg ( " Finished iterating camp spots. " ) ;
}
}
else if ( op = = " begin " ) {
for ( int i = 0 ; i < graph . length ( ) ; + + i ) {
if ( graph [ i ] . flags & NodeFlag : : Camp ) {
2019-08-30 11:10:22 +03:00
m_campIterator . push ( i ) ;
2019-08-30 10:52:31 +03:00
}
}
2019-08-30 11:10:22 +03:00
msg ( " Ready for iteration. Type 'next' to go to first camp node. " ) ;
2019-08-30 10:52:31 +03:00
}
return BotCommandResult : : Handled ;
}
2019-07-01 21:10:00 +03:00
int BotControl : : menuMain ( int item ) {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 :
m_isMenuFillCommand = false ;
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : Control ) ;
2019-07-01 21:10:00 +03:00
break ;
case 2 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : Features ) ;
2019-07-01 21:10:00 +03:00
break ;
case 3 :
m_isMenuFillCommand = true ;
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : TeamSelect ) ;
2019-07-01 21:10:00 +03:00
break ;
case 4 :
bots . killAllBots ( ) ;
break ;
case 10 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ;
2019-07-01 21:10:00 +03:00
break ;
default :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : Main ) ;
2019-07-01 21:10:00 +03:00
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
int BotControl : : menuFeatures ( int item ) {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : WeaponMode ) ;
2019-07-01 21:10:00 +03:00
break ;
case 2 :
2019-07-27 17:36:24 +03:00
showMenu ( graph . hasEditor ( ) ? Menu : : NodeMainPage1 : Menu : : Features ) ;
2019-07-01 21:10:00 +03:00
break ;
case 3 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : Personality ) ;
2019-07-01 21:10:00 +03:00
break ;
case 4 :
extern ConVar yb_debug ;
2019-07-27 17:36:24 +03:00
yb_debug . set ( yb_debug . int_ ( ) ^ 1 ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : Features ) ;
2019-07-01 21:10:00 +03:00
break ;
case 5 :
if ( util . isAlive ( m_ent ) ) {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : Commands ) ;
2019-07-01 21:10:00 +03:00
}
else {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
msg ( " You're dead, and have no access to this menu " ) ;
}
break ;
case 10 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ;
2019-07-01 21:10:00 +03:00
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
int BotControl : : menuControl ( int item ) {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 :
bots . createRandom ( true ) ;
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : Control ) ;
2019-07-01 21:10:00 +03:00
break ;
case 2 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : Difficulty ) ;
2019-07-01 21:10:00 +03:00
break ;
case 3 :
bots . kickRandom ( ) ;
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : Control ) ;
2019-07-01 21:10:00 +03:00
break ;
case 4 :
bots . kickEveryone ( ) ;
break ;
case 5 :
kickBotByMenu ( 1 ) ;
break ;
case 10 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ;
2019-07-01 21:10:00 +03:00
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
int BotControl : : menuWeaponMode ( int item ) {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 :
case 2 :
case 3 :
case 4 :
case 5 :
case 6 :
case 7 :
bots . setWeaponMode ( item ) ;
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : WeaponMode ) ;
2019-07-01 21:10:00 +03:00
break ;
case 10 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ;
2019-07-01 21:10:00 +03:00
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
int BotControl : : menuPersonality ( int item ) {
if ( m_isMenuFillCommand ) {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 :
case 2 :
case 3 :
case 4 :
bots . serverFill ( m_menuServerFillTeam , item - 2 , m_interMenuData [ 0 ] ) ;
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ;
2019-07-01 21:10:00 +03:00
break ;
case 10 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ;
2019-07-01 21:10:00 +03:00
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 :
case 2 :
case 3 :
case 4 :
m_interMenuData [ 3 ] = item - 2 ;
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : TeamSelect ) ;
2019-07-01 21:10:00 +03:00
break ;
case 10 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ;
2019-07-01 21:10:00 +03:00
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
int BotControl : : menuDifficulty ( int item ) {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 :
m_interMenuData [ 0 ] = 0 ;
break ;
case 2 :
m_interMenuData [ 0 ] = 1 ;
break ;
case 3 :
m_interMenuData [ 0 ] = 2 ;
break ;
case 4 :
m_interMenuData [ 0 ] = 3 ;
break ;
case 5 :
m_interMenuData [ 0 ] = 4 ;
break ;
case 10 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ;
2019-07-01 21:10:00 +03:00
break ;
}
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : Personality ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
int BotControl : : menuTeamSelect ( int item ) {
if ( m_isMenuFillCommand ) {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
if ( item < 3 ) {
extern ConVar mp_limitteams , mp_autoteambalance ;
// turn off cvars if specified team
mp_limitteams . set ( 0 ) ;
mp_autoteambalance . set ( 0 ) ;
}
switch ( item ) {
case 1 :
case 2 :
case 5 :
m_menuServerFillTeam = item ;
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : Difficulty ) ;
2019-07-01 21:10:00 +03:00
break ;
case 10 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ;
2019-07-01 21:10:00 +03:00
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 :
case 2 :
case 5 :
m_interMenuData [ 1 ] = item ;
if ( item = = 5 ) {
m_interMenuData [ 2 ] = item ;
bots . addbot ( " " , m_interMenuData [ 0 ] , m_interMenuData [ 3 ] , m_interMenuData [ 1 ] , m_interMenuData [ 2 ] , true ) ;
}
else {
2019-07-27 17:36:24 +03:00
showMenu ( item = = 1 ? Menu : : TerroristSelect : Menu : : CTSelect ) ;
2019-07-01 21:10:00 +03:00
}
break ;
case 10 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ;
2019-07-01 21:10:00 +03:00
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
int BotControl : : menuClassSelect ( int item ) {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 :
case 2 :
case 3 :
case 4 :
case 5 :
m_interMenuData [ 2 ] = item ;
bots . addbot ( " " , m_interMenuData [ 0 ] , m_interMenuData [ 3 ] , m_interMenuData [ 1 ] , m_interMenuData [ 2 ] , true ) ;
break ;
case 10 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ;
2019-07-01 21:10:00 +03:00
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
int BotControl : : menuCommands ( int item ) {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ; // reset menu display
2019-08-18 21:00:00 +03:00
Bot * nearest = nullptr ;
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 :
case 2 :
2019-08-18 21:00:00 +03:00
if ( util . findNearestPlayer ( reinterpret_cast < void * * > ( & m_djump ) , m_ent , 600.0f , true , true , true , true , false ) & & ! m_djump - > m_hasC4 & & ! m_djump - > hasHostage ( ) ) {
2019-07-01 21:10:00 +03:00
if ( item = = 1 ) {
2019-08-18 21:00:00 +03:00
m_djump - > startDoubleJump ( m_ent ) ;
2019-07-01 21:10:00 +03:00
}
else {
2019-08-18 21:00:00 +03:00
if ( m_djump ) {
m_djump - > resetDoubleJump ( ) ;
m_djump = nullptr ;
}
2019-07-01 21:10:00 +03:00
}
}
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : Commands ) ;
2019-07-01 21:10:00 +03:00
break ;
case 3 :
case 4 :
2019-08-18 21:00:00 +03:00
if ( util . findNearestPlayer ( reinterpret_cast < void * * > ( & nearest ) , m_ent , 600.0f , true , true , true , true , item = = 4 ? false : true ) ) {
nearest - > dropWeaponForUser ( m_ent , item = = 4 ? false : true ) ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : Commands ) ;
2019-07-01 21:10:00 +03:00
break ;
case 10 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ;
2019-07-01 21:10:00 +03:00
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : menuGraphPage1 ( int item ) {
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 :
2019-07-27 17:36:24 +03:00
if ( graph . hasEditFlag ( GraphEdit : : On ) ) {
graph . clearEditFlag ( GraphEdit : : On ) ;
2019-07-01 21:10:00 +03:00
enableDrawModels ( false ) ;
2019-07-27 17:36:24 +03:00
msg ( " Graph editor has been disabled. " ) ;
2019-07-01 21:10:00 +03:00
}
else {
2019-07-27 17:36:24 +03:00
graph . setEditFlag ( GraphEdit : : On ) ;
2019-07-01 21:10:00 +03:00
enableDrawModels ( true ) ;
2019-07-27 17:36:24 +03:00
msg ( " Graph editor has been enabled. " ) ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : NodeMainPage1 ) ;
2019-07-01 21:10:00 +03:00
break ;
case 2 :
2019-07-27 17:36:24 +03:00
graph . setEditFlag ( GraphEdit : : On ) ;
graph . cachePoint ( kInvalidNodeIndex ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : NodeMainPage1 ) ;
2019-07-01 21:10:00 +03:00
break ;
case 3 :
2019-07-27 17:36:24 +03:00
graph . setEditFlag ( GraphEdit : : On ) ;
showMenu ( Menu : : NodePath ) ;
2019-07-01 21:10:00 +03:00
break ;
case 4 :
2019-07-27 17:36:24 +03:00
graph . setEditFlag ( GraphEdit : : On ) ;
graph . erasePath ( ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : NodeMainPage1 ) ;
2019-07-01 21:10:00 +03:00
break ;
case 5 :
2019-07-27 17:36:24 +03:00
graph . setEditFlag ( GraphEdit : : On ) ;
showMenu ( Menu : : NodeType ) ;
2019-07-01 21:10:00 +03:00
break ;
case 6 :
2019-07-27 17:36:24 +03:00
graph . setEditFlag ( GraphEdit : : On ) ;
graph . erase ( kInvalidNodeIndex ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : NodeMainPage1 ) ;
2019-07-01 21:10:00 +03:00
break ;
case 7 :
2019-07-27 17:36:24 +03:00
graph . setEditFlag ( GraphEdit : : On ) ;
showMenu ( Menu : : NodeAutoPath ) ;
2019-07-01 21:10:00 +03:00
break ;
case 8 :
2019-07-27 17:36:24 +03:00
graph . setEditFlag ( GraphEdit : : On ) ;
showMenu ( Menu : : NodeRadius ) ;
2019-07-01 21:10:00 +03:00
break ;
case 9 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : NodeMainPage2 ) ;
2019-07-01 21:10:00 +03:00
break ;
case 10 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ;
2019-07-01 21:10:00 +03:00
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : menuGraphPage2 ( int item ) {
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 : {
int terrPoints = 0 ;
int ctPoints = 0 ;
int goalPoints = 0 ;
int rescuePoints = 0 ;
int campPoints = 0 ;
int sniperPoints = 0 ;
int noHostagePoints = 0 ;
2019-07-27 17:36:24 +03:00
for ( int i = 0 ; i < graph . length ( ) ; + + i ) {
2019-08-12 22:51:26 +03:00
const Path & path = graph [ i ] ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
if ( path . flags & NodeFlag : : TerroristOnly ) {
2019-08-04 18:22:01 +03:00
+ + terrPoints ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
if ( path . flags & NodeFlag : : CTOnly ) {
2019-08-04 18:22:01 +03:00
+ + ctPoints ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
if ( path . flags & NodeFlag : : Goal ) {
2019-08-04 18:22:01 +03:00
+ + goalPoints ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
if ( path . flags & NodeFlag : : Rescue ) {
2019-08-04 18:22:01 +03:00
+ + rescuePoints ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
if ( path . flags & NodeFlag : : Camp ) {
2019-08-04 18:22:01 +03:00
+ + campPoints ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
if ( path . flags & NodeFlag : : Sniper ) {
2019-08-04 18:22:01 +03:00
+ + sniperPoints ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
if ( path . flags & NodeFlag : : NoHostage ) {
2019-08-04 18:22:01 +03:00
+ + noHostagePoints ;
2019-07-01 21:10:00 +03:00
}
}
2019-07-27 17:36:24 +03:00
msg ( " Nodes: %d - T Points: %d \n "
2019-07-01 21:10:00 +03:00
" CT Points: %d - Goal Points: %d \n "
" Rescue Points: %d - Camp Points: %d \n "
" Block Hostage Points: %d - Sniper Points: %d \n " ,
2019-07-27 17:36:24 +03:00
graph . length ( ) , terrPoints , ctPoints , goalPoints , rescuePoints , campPoints , noHostagePoints , sniperPoints ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : NodeMainPage2 ) ;
2019-07-01 21:10:00 +03:00
} break ;
case 2 :
2019-07-27 17:36:24 +03:00
graph . setEditFlag ( GraphEdit : : On ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
if ( graph . hasEditFlag ( GraphEdit : : Auto ) ) {
graph . clearEditFlag ( GraphEdit : : Auto ) ;
2019-07-01 21:10:00 +03:00
}
else {
2019-07-27 17:36:24 +03:00
graph . setEditFlag ( GraphEdit : : Auto ) ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
msg ( " Auto-Add-Nodes %s " , graph . hasEditFlag ( GraphEdit : : Auto ) ? " Enabled " : " Disabled " ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : NodeMainPage2 ) ;
2019-07-01 21:10:00 +03:00
break ;
case 3 :
2019-07-27 17:36:24 +03:00
graph . setEditFlag ( GraphEdit : : On ) ;
showMenu ( Menu : : NodeFlag ) ;
2019-07-01 21:10:00 +03:00
break ;
case 4 :
2019-07-27 17:36:24 +03:00
if ( graph . checkNodes ( true ) ) {
graph . saveGraphData ( ) ;
2019-07-01 21:10:00 +03:00
}
else {
2019-07-27 17:36:24 +03:00
msg ( " Graph not saved \n There are errors. See console... " ) ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : NodeMainPage2 ) ;
2019-07-01 21:10:00 +03:00
break ;
case 5 :
2019-07-27 17:36:24 +03:00
graph . saveGraphData ( ) ;
showMenu ( Menu : : NodeMainPage2 ) ;
2019-07-01 21:10:00 +03:00
break ;
case 6 :
2019-07-27 17:36:24 +03:00
graph . loadGraphData ( ) ;
showMenu ( Menu : : NodeMainPage2 ) ;
2019-07-01 21:10:00 +03:00
break ;
case 7 :
2019-07-27 17:36:24 +03:00
if ( graph . checkNodes ( true ) ) {
2019-07-01 21:10:00 +03:00
msg ( " Nodes works fine " ) ;
}
else {
msg ( " There are errors, see console " ) ;
}
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : NodeMainPage2 ) ;
2019-07-01 21:10:00 +03:00
break ;
case 8 :
2019-07-27 17:36:24 +03:00
graph . setEditFlag ( GraphEdit : : On | GraphEdit : : Noclip ) ;
showMenu ( Menu : : NodeMainPage2 ) ;
2019-07-01 21:10:00 +03:00
break ;
case 9 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : NodeMainPage1 ) ;
2019-07-01 21:10:00 +03:00
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : menuGraphRadius ( int item ) {
showMenu ( Menu : : None ) ; // reset menu display
graph . setEditFlag ( GraphEdit : : On ) ; // turn graph on in case
2019-07-01 21:10:00 +03:00
constexpr float radius [ ] = { 0.0f , 8.0f , 16.0f , 32.0f , 48.0f , 64.0f , 80.0f , 96.0f , 128.0f } ;
if ( item > = 1 & & item < = 9 ) {
2019-07-27 17:36:24 +03:00
graph . setRadius ( kInvalidNodeIndex , radius [ item - 1 ] ) ;
showMenu ( Menu : : NodeRadius ) ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : menuGraphType ( int item ) {
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 :
case 2 :
case 3 :
case 4 :
case 5 :
case 6 :
case 7 :
2019-07-27 17:36:24 +03:00
graph . add ( item - 1 ) ;
showMenu ( Menu : : NodeType ) ;
2019-07-01 21:10:00 +03:00
break ;
case 8 :
2019-07-27 17:36:24 +03:00
graph . add ( 100 ) ;
showMenu ( Menu : : NodeType ) ;
2019-07-01 21:10:00 +03:00
break ;
case 9 :
2019-07-27 17:36:24 +03:00
graph . startLearnJump ( ) ;
showMenu ( Menu : : NodeType ) ;
2019-07-01 21:10:00 +03:00
break ;
case 10 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ;
2019-07-01 21:10:00 +03:00
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : menuGraphFlag ( int item ) {
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 :
2019-07-27 17:36:24 +03:00
graph . toggleFlags ( NodeFlag : : NoHostage ) ;
showMenu ( Menu : : NodeFlag ) ;
2019-07-01 21:10:00 +03:00
break ;
case 2 :
2019-07-27 17:36:24 +03:00
graph . toggleFlags ( NodeFlag : : TerroristOnly ) ;
showMenu ( Menu : : NodeFlag ) ;
2019-07-01 21:10:00 +03:00
break ;
case 3 :
2019-07-27 17:36:24 +03:00
graph . toggleFlags ( NodeFlag : : CTOnly ) ;
showMenu ( Menu : : NodeFlag ) ;
2019-07-01 21:10:00 +03:00
break ;
case 4 :
2019-07-27 17:36:24 +03:00
graph . toggleFlags ( NodeFlag : : Lift ) ;
showMenu ( Menu : : NodeFlag ) ;
2019-07-01 21:10:00 +03:00
break ;
case 5 :
2019-07-27 17:36:24 +03:00
graph . toggleFlags ( NodeFlag : : Sniper ) ;
showMenu ( Menu : : NodeFlag ) ;
2019-07-01 21:10:00 +03:00
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
int BotControl : : menuAutoPathDistance ( int item ) {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
constexpr float distances [ ] = { 0.0f , 100.0f , 130.0f , 160.0f , 190.0f , 220.0f , 250.0f } ;
float result = 0.0f ;
if ( item > = 1 & & item < = 7 ) {
result = distances [ item - 1 ] ;
2019-07-27 17:36:24 +03:00
graph . setAutoPathDistance ( result ) ;
2019-07-01 21:10:00 +03:00
}
if ( cr : : fzero ( result ) ) {
msg ( " Autopathing is now disabled. " ) ;
}
else {
msg ( " Autopath distance is set to %.2f. " , result ) ;
}
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : NodeAutoPath ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
int BotControl : : menuKickPage1 ( int item ) {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 :
case 2 :
case 3 :
case 4 :
case 5 :
case 6 :
case 7 :
case 8 :
bots . kickBot ( item - 1 ) ;
kickBotByMenu ( 1 ) ;
break ;
case 9 :
kickBotByMenu ( 2 ) ;
break ;
case 10 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : Control ) ;
2019-07-01 21:10:00 +03:00
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
int BotControl : : menuKickPage2 ( int item ) {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 :
case 2 :
case 3 :
case 4 :
case 5 :
case 6 :
case 7 :
case 8 :
bots . kickBot ( item + 8 - 1 ) ;
kickBotByMenu ( 2 ) ;
break ;
case 9 :
kickBotByMenu ( 3 ) ;
break ;
case 10 :
kickBotByMenu ( 1 ) ;
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
int BotControl : : menuKickPage3 ( int item ) {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 :
case 2 :
case 3 :
case 4 :
case 5 :
case 6 :
case 7 :
case 8 :
bots . kickBot ( item + 16 - 1 ) ;
kickBotByMenu ( 3 ) ;
break ;
case 9 :
kickBotByMenu ( 4 ) ;
break ;
case 10 :
kickBotByMenu ( 2 ) ;
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
int BotControl : : menuKickPage4 ( int item ) {
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 :
case 2 :
case 3 :
case 4 :
case 5 :
case 6 :
case 7 :
case 8 :
bots . kickBot ( item + 24 - 1 ) ;
kickBotByMenu ( 4 ) ;
break ;
case 10 :
kickBotByMenu ( 3 ) ;
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
int BotControl : : menuGraphPath ( int item ) {
showMenu ( Menu : : None ) ; // reset menu display
2019-07-01 21:10:00 +03:00
switch ( item ) {
case 1 :
2019-07-27 17:36:24 +03:00
graph . pathCreate ( PathConnection : : Outgoing ) ;
showMenu ( Menu : : NodePath ) ;
2019-07-01 21:10:00 +03:00
break ;
case 2 :
2019-07-27 17:36:24 +03:00
graph . pathCreate ( PathConnection : : Incoming ) ;
showMenu ( Menu : : NodePath ) ;
2019-07-01 21:10:00 +03:00
break ;
case 3 :
2019-07-27 17:36:24 +03:00
graph . pathCreate ( PathConnection : : Bidirectional ) ;
showMenu ( Menu : : NodePath ) ;
2019-07-01 21:10:00 +03:00
break ;
case 10 :
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ;
2019-07-01 21:10:00 +03:00
break ;
}
2019-07-27 17:36:24 +03:00
return BotCommandResult : : Handled ;
2019-07-01 21:10:00 +03:00
}
2019-07-27 17:36:24 +03:00
bool BotControl : : executeCommands ( ) {
2019-07-01 21:10:00 +03:00
if ( m_args . empty ( ) ) {
return false ;
}
// handle only "yb" and "yapb" commands
if ( m_args [ 0 ] ! = " yb " & & m_args [ 0 ] ! = " yapb " ) {
return false ;
}
2019-07-27 17:36:24 +03:00
Client & client = util . getClient ( game . indexOfPlayer ( m_ent ) ) ;
2019-07-01 21:10:00 +03:00
// do not allow to execute stuff for non admins
2019-07-27 17:36:24 +03:00
if ( m_ent ! = game . getLocalEntity ( ) & & ! ( client . flags & ClientFlags : : Admin ) ) {
msg ( " Access to %s commands is restricted. " , PRODUCT_SHORT_NAME ) ;
2019-07-01 21:10:00 +03:00
return true ;
}
auto aliasMatch = [ ] ( String & test , const String & cmd , String & aliasName ) - > bool {
2019-07-27 17:36:24 +03:00
for ( auto & alias : test . split ( " / " ) ) {
2019-07-01 21:10:00 +03:00
if ( alias = = cmd ) {
aliasName = alias ;
return true ;
}
}
return false ;
} ;
String cmd ;
// give some help
2019-07-27 17:36:24 +03:00
if ( m_args . length ( ) > 0 & & m_args [ 1 ] = = " help " ) {
2019-07-01 21:10:00 +03:00
for ( auto & item : m_cmds ) {
if ( aliasMatch ( item . name , m_args [ 2 ] , cmd ) ) {
msg ( " Command: \" %s %s \" \n Format: %s \n Help: %s " , m_args [ 0 ] . chars ( ) , cmd . chars ( ) , item . format . chars ( ) , item . help . chars ( ) ) ;
String aliases ;
2019-07-27 17:36:24 +03:00
for ( auto & alias : item . name . split ( " / " ) ) {
aliases . appendf ( " %s, " , alias . chars ( ) ) ;
2019-07-01 21:10:00 +03:00
}
aliases . rtrim ( " , " ) ;
msg ( " Aliases: %s " , aliases . chars ( ) ) ;
return true ;
}
}
if ( m_args [ 2 ] . empty ( ) ) {
return true ;
}
else {
msg ( " No help found for \" %s \" " , m_args [ 2 ] . chars ( ) ) ;
}
return true ;
}
cmd . clear ( ) ;
// if no args passed just print all the commands
if ( m_args . length ( ) = = 1 ) {
msg ( " usage %s <command> [arguments] " , m_args [ 0 ] . chars ( ) ) ;
msg ( " valid commands are: " ) ;
for ( auto & item : m_cmds ) {
2019-07-27 17:36:24 +03:00
msg ( " %s - %s " , item . name . split ( " / " ) [ 0 ] . chars ( ) , item . help . chars ( ) ) ;
2019-07-01 21:10:00 +03:00
}
return true ;
}
// first search for a actual cmd
for ( auto & item : m_cmds ) {
auto root = m_args [ 0 ] . chars ( ) ;
if ( aliasMatch ( item . name , m_args [ 1 ] , cmd ) ) {
auto alias = cmd . chars ( ) ;
switch ( ( this - > * item . handler ) ( ) ) {
2019-07-27 17:36:24 +03:00
case BotCommandResult : : Handled :
2019-07-01 21:10:00 +03:00
default :
break ;
2019-07-27 17:36:24 +03:00
case BotCommandResult : : ListenServer :
2019-07-01 21:10:00 +03:00
msg ( " Command \" %s %s \" is only available from the listenserver console. " , root , alias ) ;
break ;
2019-07-27 17:36:24 +03:00
case BotCommandResult : : BadFormat :
2019-07-01 21:10:00 +03:00
msg ( " Incorrect usage of \" %s %s \" command. Correct usage is: \n \n \t %s \n \n Please type \" %s help %s \" to get more information. " , root , alias , item . format . chars ( ) , root , alias ) ;
break ;
}
m_isFromConsole = false ;
return true ;
}
}
msg ( " Unrecognized command: %s " , m_args [ 1 ] . chars ( ) ) ;
return true ;
}
2019-07-27 17:36:24 +03:00
bool BotControl : : executeMenus ( ) {
2019-07-01 21:10:00 +03:00
if ( ! util . isPlayer ( m_ent ) | | game . isBotCmd ( ) ) {
return false ;
}
2019-07-27 17:36:24 +03:00
auto & issuer = util . getClient ( game . indexOfPlayer ( m_ent ) ) ;
2019-07-01 21:10:00 +03:00
// check if it's menu select, and some key pressed
2019-07-27 17:36:24 +03:00
if ( getStr ( 0 ) ! = " menuselect " | | getStr ( 1 ) . empty ( ) | | issuer . menu = = Menu : : None ) {
2019-07-01 21:10:00 +03:00
return false ;
}
// let's get handle
for ( auto & menu : m_menus ) {
if ( menu . ident = = issuer . menu ) {
2019-07-27 17:36:24 +03:00
return ( this - > * menu . handler ) ( getStr ( 1 ) . int_ ( ) ) ;
2019-07-01 21:10:00 +03:00
}
}
return false ;
}
void BotControl : : showMenu ( int id ) {
static bool s_menusParsed = false ;
// make menus looks like we need only once
if ( ! s_menusParsed ) {
for ( auto & parsed : m_menus ) {
2019-08-04 18:22:01 +03:00
const String & translated = conf . translate ( parsed . text . chars ( ) ) ;
2019-07-01 21:10:00 +03:00
// translate all the things
parsed . text = translated ;
2019-07-27 17:36:24 +03:00
// make menu looks best
if ( ! ( game . is ( GameFlags : : Legacy ) ) ) {
for ( int j = 0 ; j < 10 ; + + j ) {
parsed . text . replace ( strings . format ( " %d. " , j ) , strings . format ( " \\ r%d. \\ w " , j ) ) ;
2019-07-01 21:10:00 +03:00
}
}
}
s_menusParsed = true ;
}
if ( ! util . isPlayer ( m_ent ) ) {
return ;
}
2019-07-27 17:36:24 +03:00
Client & client = util . getClient ( game . indexOfPlayer ( m_ent ) ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
if ( id = = Menu : : None ) {
2019-08-18 21:00:00 +03:00
MessageWriter ( MSG_ONE_UNRELIABLE , msgs . id ( NetMsg : : ShowMenu ) , nullptr , m_ent )
2019-07-01 21:10:00 +03:00
. writeShort ( 0 )
. writeChar ( 0 )
. writeByte ( 0 )
. writeString ( " " ) ;
client . menu = id ;
return ;
}
for ( auto & display : m_menus ) {
if ( display . ident = = id ) {
2019-07-28 23:21:24 +03:00
auto text = ( game . is ( GameFlags : : Xash3D | GameFlags : : Mobility ) & & ! yb_display_menu_text . bool_ ( ) ) ? " " : display . text . chars ( ) ;
2019-07-01 21:10:00 +03:00
MessageWriter msg ;
while ( strlen ( text ) > = 64 ) {
2019-08-18 21:00:00 +03:00
msg . start ( MSG_ONE_UNRELIABLE , msgs . id ( NetMsg : : ShowMenu ) , nullptr , m_ent )
2019-07-01 21:10:00 +03:00
. writeShort ( display . slots )
. writeChar ( - 1 )
. writeByte ( 1 ) ;
2019-07-27 17:36:24 +03:00
for ( int i = 0 ; i < 64 ; + + i ) {
2019-07-01 21:10:00 +03:00
msg . writeChar ( text [ i ] ) ;
}
msg . end ( ) ;
text + = 64 ;
}
2019-08-18 21:00:00 +03:00
MessageWriter ( MSG_ONE_UNRELIABLE , msgs . id ( NetMsg : : ShowMenu ) , nullptr , m_ent )
2019-07-01 21:10:00 +03:00
. writeShort ( display . slots )
. writeChar ( - 1 )
. writeByte ( 0 )
. writeString ( text ) ;
client . menu = id ;
engfuncs . pfnClientCommand ( m_ent , " speak \" player/geiger1 \" \n " ) ; // Stops others from hearing menu sounds..
}
}
}
void BotControl : : kickBotByMenu ( int page ) {
if ( page > 4 | | page < 1 ) {
return ;
}
String menus ;
2019-07-27 17:36:24 +03:00
menus . assignf ( " \\ yBots Remove Menu (%d/4): \\ w \n \n " , page ) ;
2019-07-01 21:10:00 +03:00
int menuKeys = ( page = = 4 ) ? cr : : bit ( 9 ) : ( cr : : bit ( 8 ) | cr : : bit ( 9 ) ) ;
int menuKey = ( page - 1 ) * 8 ;
2019-07-27 17:36:24 +03:00
for ( int i = menuKey ; i < page * 8 ; + + i ) {
auto bot = bots [ i ] ;
2019-07-01 21:10:00 +03:00
2019-08-24 12:43:42 +03:00
// check for fakeclient bit, since we're clear it upon kick, but actual bot struct destroyed after client disconnected
if ( bot ! = nullptr & & ( bot - > pev - > flags & FL_FAKECLIENT ) ) {
2019-07-01 21:10:00 +03:00
menuKeys | = cr : : bit ( cr : : abs ( i - menuKey ) ) ;
2019-07-27 17:36:24 +03:00
menus . appendf ( " %1.1d. %s%s \n " , i - menuKey + 1 , STRING ( bot - > pev - > netname ) , bot - > m_team = = Team : : CT ? " \\ y(CT) \\ w " : " \\ r(T) \\ w " ) ;
2019-07-01 21:10:00 +03:00
}
else {
2019-07-27 17:36:24 +03:00
menus . appendf ( " \\ d %1.1d. Not a Bot \\ w \n " , i - menuKey + 1 ) ;
2019-07-01 21:10:00 +03:00
}
}
2019-07-27 17:36:24 +03:00
menus . appendf ( " \n %s 0. Back " , ( page = = 4 ) ? " " : " 9. More... \n " ) ;
2019-07-01 21:10:00 +03:00
// force to clear current menu
2019-07-27 17:36:24 +03:00
showMenu ( Menu : : None ) ;
2019-07-01 21:10:00 +03:00
2019-07-27 17:36:24 +03:00
auto id = Menu : : KickPage1 - 1 + page ;
2019-07-01 21:10:00 +03:00
for ( auto & menu : m_menus ) {
if ( menu . ident = = id ) {
2019-07-27 17:36:24 +03:00
menu . slots = menuKeys & static_cast < uint32 > ( - 1 ) ;
2019-07-01 21:10:00 +03:00
menu . text = menus ;
break ;
}
}
showMenu ( id ) ;
}
void BotControl : : assignAdminRights ( edict_t * ent , char * infobuffer ) {
if ( ! game . isDedicated ( ) | | util . isFakeClient ( ent ) ) {
return ;
}
const String & key = yb_password_key . str ( ) ;
const String & password = yb_password . str ( ) ;
if ( ! key . empty ( ) & & ! password . empty ( ) ) {
2019-07-27 17:36:24 +03:00
auto & client = util . getClient ( game . indexOfPlayer ( ent ) ) ;
2019-07-01 21:10:00 +03:00
if ( password = = engfuncs . pfnInfoKeyValue ( infobuffer , key . chars ( ) ) ) {
2019-07-27 17:36:24 +03:00
client . flags | = ClientFlags : : Admin ;
2019-07-01 21:10:00 +03:00
}
else {
2019-07-27 17:36:24 +03:00
client . flags & = ~ ClientFlags : : Admin ;
2019-07-01 21:10:00 +03:00
}
}
}
2019-07-27 17:36:24 +03:00
void BotControl : : maintainAdminRights ( ) {
2019-07-01 21:10:00 +03:00
if ( ! game . isDedicated ( ) ) {
return ;
}
2019-07-27 17:36:24 +03:00
for ( int i = 0 ; i < game . maxClients ( ) ; + + i ) {
edict_t * player = game . playerOfIndex ( i ) ;
2019-07-01 21:10:00 +03:00
// code below is executed only on dedicated server
if ( util . isPlayer ( player ) & & ! util . isFakeClient ( player ) ) {
Client & client = util . getClient ( i ) ;
2019-07-27 17:36:24 +03:00
if ( client . flags & ClientFlags : : Admin ) {
2019-08-12 14:16:28 +03:00
if ( strings . isEmpty ( yb_password_key . str ( ) ) & & strings . isEmpty ( yb_password . str ( ) ) ) {
2019-07-27 17:36:24 +03:00
client . flags & = ~ ClientFlags : : Admin ;
2019-07-01 21:10:00 +03:00
}
else if ( ! ! strcmp ( yb_password . str ( ) , engfuncs . pfnInfoKeyValue ( engfuncs . pfnGetInfoKeyBuffer ( client . ent ) , const_cast < char * > ( yb_password_key . str ( ) ) ) ) ) {
2019-07-27 17:36:24 +03:00
client . flags & = ~ ClientFlags : : Admin ;
2019-07-01 21:10:00 +03:00
game . print ( " Player %s had lost remote access to %s. " , STRING ( player - > v . netname ) , PRODUCT_SHORT_NAME ) ;
}
}
2019-08-12 14:16:28 +03:00
else if ( ! ( client . flags & ClientFlags : : Admin ) & & ! strings . isEmpty ( yb_password_key . str ( ) ) & & ! strings . isEmpty ( yb_password . str ( ) ) ) {
2019-07-01 21:10:00 +03:00
if ( strcmp ( yb_password . str ( ) , engfuncs . pfnInfoKeyValue ( engfuncs . pfnGetInfoKeyBuffer ( client . ent ) , const_cast < char * > ( yb_password_key . str ( ) ) ) ) = = 0 ) {
2019-07-27 17:36:24 +03:00
client . flags | = ClientFlags : : Admin ;
2019-07-01 21:10:00 +03:00
game . print ( " Player %s had gained full remote access to %s. " , STRING ( player - > v . netname ) , PRODUCT_SHORT_NAME ) ;
}
}
}
}
}
2019-07-27 17:36:24 +03:00
BotControl : : BotControl ( ) {
2019-07-01 21:10:00 +03:00
m_ent = nullptr ;
2019-08-18 21:00:00 +03:00
m_djump = nullptr ;
2019-07-01 21:10:00 +03:00
m_isFromConsole = false ;
m_isMenuFillCommand = false ;
2019-07-27 17:36:24 +03:00
m_rapidOutput = false ;
2019-07-01 21:10:00 +03:00
m_menuServerFillTeam = 5 ;
2019-07-27 17:36:24 +03:00
m_cmds . emplace ( " add/addbot/add_ct/addbot_ct/add_t/addbot_t/addhs/addhs_t/addhs_ct " , " add [difficulty[personality[team[model[name]]]]] " , " Adding specific bot into the game. " , & BotControl : : cmdAddBot ) ;
m_cmds . emplace ( " kick/kickone/kick_ct/kick_t/kickbot_ct/kickbot_t " , " kick [team] " , " Kicks off the random bot from the game. " , & BotControl : : cmdKickBot ) ;
m_cmds . emplace ( " removebots/kickbots/kickall " , " removebots [instant] " , " Kicks all the bots from the game. " , & BotControl : : cmdKickBots ) ;
m_cmds . emplace ( " kill/killbots/killall/kill_ct/kill_t " , " kill [team] " , " Kills the specified team / all the bots. " , & BotControl : : cmdKillBots ) ;
m_cmds . emplace ( " fill/fillserver " , " fill [team[count[difficulty[pesonality]]]] " , " Fill the server (add bots) with specified parameters. " , & BotControl : : cmdFill ) ;
m_cmds . emplace ( " vote/votemap " , " vote [map_id] " , " Forces all the bot to vote to specified map. " , & BotControl : : cmdVote ) ;
m_cmds . emplace ( " weapons/weaponmode " , " weapons [knife|pistol|shotgun|smg|rifle|sniper|standard] " , " Sets the bots weapon mode to use " , & BotControl : : cmdWeaponMode ) ;
m_cmds . emplace ( " menu/botmenu " , " menu [cmd] " , " Opens the main bot menu, or command menu if specified. " , & BotControl : : cmdMenu ) ;
m_cmds . emplace ( " version/ver/about " , " version [no arguments] " , " Displays version information about bot build. " , & BotControl : : cmdVersion ) ;
m_cmds . emplace ( " graphmenu/wpmenu/wptmenu " , " graphmenu [noarguments] " , " Opens and displays bots graph edtior. " , & BotControl : : cmdNodeMenu ) ;
m_cmds . emplace ( " list/listbots " , " list [noarguments] " , " Lists the bots currently playing on server. " , & BotControl : : cmdList ) ;
2019-08-18 21:00:00 +03:00
m_cmds . emplace ( " graph/g/wp/wpt/waypoint " , " graph [help] " , " Handles graph operations. " , & BotControl : : cmdNode ) ;
2019-08-24 12:43:42 +03:00
m_cmds . emplace ( " cvars " , " cvars [save|cvar] " , " Display all the cvars with their descriptions. " , & BotControl : : cmdCvars ) ;
2019-07-01 21:10:00 +03:00
// declare the menus
createMenus ( ) ;
}
2019-07-27 17:36:24 +03:00
void BotControl : : handleEngineCommands ( ) {
2019-08-18 21:00:00 +03:00
collectArgs ( ) ;
setIssuer ( game . getLocalEntity ( ) ) ;
2019-07-01 21:10:00 +03:00
2019-08-18 21:00:00 +03:00
setFromConsole ( true ) ;
executeCommands ( ) ;
2019-07-01 21:10:00 +03:00
}
bool BotControl : : handleClientCommands ( edict_t * ent ) {
2019-08-18 21:00:00 +03:00
collectArgs ( ) ;
2019-07-01 21:10:00 +03:00
setIssuer ( ent ) ;
setFromConsole ( true ) ;
return executeCommands ( ) ;
}
bool BotControl : : handleMenuCommands ( edict_t * ent ) {
2019-08-18 21:00:00 +03:00
collectArgs ( ) ;
2019-07-01 21:10:00 +03:00
setIssuer ( ent ) ;
setFromConsole ( false ) ;
return ctrl . executeMenus ( ) ;
}
void BotControl : : enableDrawModels ( bool enable ) {
StringArray entities ;
entities . push ( " info_player_start " ) ;
entities . push ( " info_player_deathmatch " ) ;
entities . push ( " info_vip_start " ) ;
for ( auto & entity : entities ) {
2019-08-18 21:00:00 +03:00
game . searchEntities ( " classname " , entity , [ & enable ] ( edict_t * ent ) {
2019-07-01 21:10:00 +03:00
if ( enable ) {
ent - > v . effects & = ~ EF_NODRAW ;
}
else {
ent - > v . effects | = EF_NODRAW ;
}
2019-08-18 21:00:00 +03:00
return EntitySearchResult : : Continue ;
} ) ;
2019-07-01 21:10:00 +03:00
}
}
2019-07-27 17:36:24 +03:00
void BotControl : : createMenus ( ) {
2019-07-01 21:10:00 +03:00
auto keys = [ ] ( int numKeys ) - > int {
int result = 0 ;
2019-07-27 17:36:24 +03:00
for ( int i = 0 ; i < numKeys ; + + i ) {
2019-07-01 21:10:00 +03:00
result | = cr : : bit ( i ) ;
}
result | = cr : : bit ( 9 ) ;
return result ;
} ;
// bots main menu
2019-07-27 17:36:24 +03:00
m_menus . emplace (
Menu : : Main , keys ( 4 ) ,
2019-07-01 21:10:00 +03:00
" \\ yMain Menu \\ w \n \n "
" 1. Control Bots \n "
" 2. Features \n \n "
" 3. Fill Server \n "
" 4. End Round \n \n "
" 0. Exit " ,
2019-07-27 17:36:24 +03:00
& BotControl : : menuMain ) ;
2019-07-01 21:10:00 +03:00
// bots features menu
2019-07-27 17:36:24 +03:00
m_menus . emplace (
Menu : : Features , keys ( 5 ) ,
2019-07-01 21:10:00 +03:00
" \\ yBots Features \\ w \n \n "
" 1. Weapon Mode Menu \n "
" 2. Waypoint Menu \n "
" 3. Select Personality \n \n "
" 4. Toggle Debug Mode \n "
" 5. Command Menu \n \n "
" 0. Exit " ,
2019-07-27 17:36:24 +03:00
& BotControl : : menuFeatures ) ;
2019-07-01 21:10:00 +03:00
// bot control menu
2019-07-27 17:36:24 +03:00
m_menus . emplace (
Menu : : Control , keys ( 5 ) ,
2019-07-01 21:10:00 +03:00
" \\ yBots Control Menu \\ w \n \n "
" 1. Add a Bot, Quick \n "
" 2. Add a Bot, Specified \n \n "
" 3. Remove Random Bot \n "
" 4. Remove All Bots \n \n "
" 5. Remove Bot Menu \n \n "
" 0. Exit " ,
2019-07-27 17:36:24 +03:00
& BotControl : : menuControl ) ;
2019-07-01 21:10:00 +03:00
// weapon mode select menu
2019-07-27 17:36:24 +03:00
m_menus . emplace (
Menu : : WeaponMode , keys ( 7 ) ,
2019-07-01 21:10:00 +03:00
" \\ yBots Weapon Mode \\ w \n \n "
" 1. Knives only \n "
" 2. Pistols only \n "
" 3. Shotguns only \n "
" 4. Machine Guns only \n "
" 5. Rifles only \n "
" 6. Sniper Weapons only \n "
" 7. All Weapons \n \n "
" 0. Exit " ,
2019-07-27 17:36:24 +03:00
& BotControl : : menuWeaponMode ) ;
2019-07-01 21:10:00 +03:00
// personality select menu
2019-07-27 17:36:24 +03:00
m_menus . emplace (
Menu : : Personality , keys ( 4 ) ,
2019-07-01 21:10:00 +03:00
" \\ yBots Personality \\ w \n \n "
" 1. Random \n "
" 2. Normal \n "
" 3. Aggressive \n "
" 4. Careful \n \n "
" 0. Exit " ,
2019-07-27 17:36:24 +03:00
& BotControl : : menuPersonality ) ;
2019-07-01 21:10:00 +03:00
// difficulty select menu
2019-07-27 17:36:24 +03:00
m_menus . emplace (
Menu : : Difficulty , keys ( 5 ) ,
2019-07-01 21:10:00 +03:00
" \\ yBots Difficulty Level \\ w \n \n "
" 1. Newbie \n "
" 2. Average \n "
" 3. Normal \n "
" 4. Professional \n "
" 5. Godlike \n \n "
" 0. Exit " ,
2019-07-27 17:36:24 +03:00
& BotControl : : menuDifficulty ) ;
2019-07-01 21:10:00 +03:00
// team select menu
2019-07-27 17:36:24 +03:00
m_menus . emplace (
Menu : : TeamSelect , keys ( 5 ) ,
2019-07-01 21:10:00 +03:00
" \\ ySelect a team \\ w \n \n "
" 1. Terrorist Force \n "
" 2. Counter-Terrorist Force \n \n "
" 5. Auto-select \n \n "
" 0. Exit " ,
2019-07-27 17:36:24 +03:00
& BotControl : : menuTeamSelect ) ;
2019-07-01 21:10:00 +03:00
// terrorist model select menu
2019-07-27 17:36:24 +03:00
m_menus . emplace (
Menu : : TerroristSelect , keys ( 5 ) ,
2019-07-01 21:10:00 +03:00
" \\ ySelect an appearance \\ w \n \n "
" 1. Phoenix Connexion \n "
" 2. L337 Krew \n "
" 3. Arctic Avengers \n "
" 4. Guerilla Warfare \n \n "
" 5. Auto-select \n \n "
" 0. Exit " ,
2019-07-27 17:36:24 +03:00
& BotControl : : menuClassSelect ) ;
2019-07-01 21:10:00 +03:00
// counter-terrorist model select menu
2019-07-27 17:36:24 +03:00
m_menus . emplace (
Menu : : CTSelect , keys ( 5 ) ,
2019-07-01 21:10:00 +03:00
" \\ ySelect an appearance \\ w \n \n "
" 1. Seal Team 6 (DEVGRU) \n "
" 2. German GSG-9 \n "
" 3. UK SAS \n "
" 4. French GIGN \n \n "
" 5. Auto-select \n \n "
" 0. Exit " ,
2019-07-27 17:36:24 +03:00
& BotControl : : menuClassSelect ) ;
2019-07-01 21:10:00 +03:00
// command menu
2019-07-27 17:36:24 +03:00
m_menus . emplace (
Menu : : Commands , keys ( 4 ) ,
2019-07-01 21:10:00 +03:00
" \\ yBot Command Menu \\ w \n \n "
" 1. Make Double Jump \n "
" 2. Finish Double Jump \n \n "
" 3. Drop the C4 Bomb \n "
" 4. Drop the Weapon \n \n "
" 0. Exit " ,
2019-07-27 17:36:24 +03:00
& BotControl : : menuCommands ) ;
2019-07-01 21:10:00 +03:00
// main waypoint menu
2019-07-27 17:36:24 +03:00
m_menus . emplace (
Menu : : NodeMainPage1 , keys ( 9 ) ,
2019-07-01 21:10:00 +03:00
" \\ yWaypoint Operations (Page 1) \\ w \n \n "
" 1. Show/Hide waypoints \n "
" 2. Cache waypoint \n "
" 3. Create path \n "
" 4. Delete path \n "
" 5. Add waypoint \n "
" 6. Delete waypoint \n "
" 7. Set Autopath Distance \n "
" 8. Set Radius \n \n "
" 9. Next... \n \n "
" 0. Exit " ,
2019-07-27 17:36:24 +03:00
& BotControl : : menuGraphPage1 ) ;
2019-07-01 21:10:00 +03:00
// main waypoint menu (page 2)
2019-07-27 17:36:24 +03:00
m_menus . emplace (
Menu : : NodeMainPage2 , keys ( 9 ) ,
2019-07-01 21:10:00 +03:00
" \\ yWaypoint Operations (Page 2) \\ w \n \n "
" 1. Waypoint stats \n "
" 2. Autowaypoint on/off \n "
" 3. Set flags \n "
" 4. Save waypoints \n "
" 5. Save without checking \n "
" 6. Load waypoints \n "
" 7. Check waypoints \n "
" 8. Noclip cheat on/off \n \n "
" 9. Previous... \n \n "
" 0. Exit " ,
2019-07-27 17:36:24 +03:00
& BotControl : : menuGraphPage2 ) ;
2019-07-01 21:10:00 +03:00
// select waypoint radius menu
2019-07-27 17:36:24 +03:00
m_menus . emplace (
Menu : : NodeRadius , keys ( 9 ) ,
2019-07-01 21:10:00 +03:00
" \\ yWaypoint Radius \\ w \n \n "
" 1. SetRadius 0 \n "
" 2. SetRadius 8 \n "
" 3. SetRadius 16 \n "
" 4. SetRadius 32 \n "
" 5. SetRadius 48 \n "
" 6. SetRadius 64 \n "
" 7. SetRadius 80 \n "
" 8. SetRadius 96 \n "
" 9. SetRadius 128 \n \n "
" 0. Exit " ,
2019-07-27 17:36:24 +03:00
& BotControl : : menuGraphRadius ) ;
2019-07-01 21:10:00 +03:00
// waypoint add menu
2019-07-27 17:36:24 +03:00
m_menus . emplace (
Menu : : NodeType , keys ( 9 ) ,
2019-07-01 21:10:00 +03:00
" \\ yWaypoint Type \\ w \n \n "
" 1. Normal \n "
" \\ r2. Terrorist Important \n "
" 3. Counter-Terrorist Important \n "
" \\ w4. Block with hostage / Ladder \n "
" \\ y5. Rescue Zone \n "
" \\ w6. Camping \n "
" 7. Camp End \n "
" \\ r8. Map Goal \n "
" \\ w9. Jump \n \n "
" 0. Exit " ,
2019-07-27 17:36:24 +03:00
& BotControl : : menuGraphType ) ;
2019-07-01 21:10:00 +03:00
// set waypoint flag menu
2019-07-27 17:36:24 +03:00
m_menus . emplace (
Menu : : NodeFlag , keys ( 5 ) ,
2019-07-01 21:10:00 +03:00
" \\ yToggle Waypoint Flags \\ w \n \n "
" 1. Block with Hostage \n "
" 2. Terrorists Specific \n "
" 3. CTs Specific \n "
" 4. Use Elevator \n "
" 5. Sniper Point ( \\ yFor Camp Points Only! \\ w) \n \n "
" 0. Exit " ,
2019-07-27 17:36:24 +03:00
& BotControl : : menuGraphFlag ) ;
2019-07-01 21:10:00 +03:00
// auto-path max distance
2019-07-27 17:36:24 +03:00
m_menus . emplace (
Menu : : NodeAutoPath , keys ( 7 ) ,
2019-07-01 21:10:00 +03:00
" \\ yAutoPath Distance \\ w \n \n "
" 1. Distance 0 \n "
" 2. Distance 100 \n "
" 3. Distance 130 \n "
" 4. Distance 160 \n "
" 5. Distance 190 \n "
" 6. Distance 220 \n "
" 7. Distance 250 (Default) \n \n "
" 0. Exit " ,
2019-07-27 17:36:24 +03:00
& BotControl : : menuAutoPathDistance ) ;
2019-07-01 21:10:00 +03:00
// path connections
2019-07-27 17:36:24 +03:00
m_menus . emplace (
Menu : : NodePath , keys ( 3 ) ,
2019-07-01 21:10:00 +03:00
" \\ yCreate Path (Choose Direction) \\ w \n \n "
" 1. Outgoing Path \n "
" 2. Incoming Path \n "
" 3. Bidirectional (Both Ways) \n \n "
" 0. Exit " ,
2019-07-27 17:36:24 +03:00
& BotControl : : menuGraphPath ) ;
2019-07-01 21:10:00 +03:00
// kick menus
2019-07-27 17:36:24 +03:00
m_menus . emplace ( Menu : : KickPage1 , 0x0 , " " , & BotControl : : menuKickPage1 ) ;
m_menus . emplace ( Menu : : KickPage2 , 0x0 , " " , & BotControl : : menuKickPage2 ) ;
m_menus . emplace ( Menu : : KickPage3 , 0x0 , " " , & BotControl : : menuKickPage3 ) ;
m_menus . emplace ( Menu : : KickPage4 , 0x0 , " " , & BotControl : : menuKickPage4 ) ;
2019-07-01 21:10:00 +03:00
}