mirror of
https://github.com/JezuzLizard/t4sp_bot_warfare.git
synced 2025-12-24 18:41:50 +00:00
Compare commits
105 Commits
experiment
...
re-t4sp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a68bc4249 | ||
|
|
d8b494017f | ||
|
|
766e846fe4 | ||
|
|
d22af0209a | ||
|
|
5ea5f77213 | ||
|
|
3ee5453c87 | ||
|
|
9c0e3e26cd | ||
|
|
764a12dc7f | ||
|
|
7acc701c04 | ||
|
|
b05344f0d7 | ||
|
|
7fb2906d62 | ||
|
|
1272026e97 | ||
|
|
96e8fb36b6 | ||
|
|
73141eddf4 | ||
|
|
7a19d85393 | ||
|
|
4adaab9841 | ||
|
|
772259aa13 | ||
|
|
5020458595 | ||
|
|
680440946f | ||
|
|
484eedd4a2 | ||
|
|
6a49312538 | ||
|
|
4748f0e8ce | ||
|
|
9ac08f9d15 | ||
|
|
3aad2db86d | ||
|
|
dd1ea5ca07 | ||
|
|
18abf5e007 | ||
|
|
daeed3e27d | ||
|
|
9c663186aa | ||
|
|
2492ffc97b | ||
|
|
4aba1289f2 | ||
|
|
9e2025e86a | ||
|
|
271ea76c3e | ||
|
|
b85f5af73a | ||
|
|
532eb70a47 | ||
|
|
7458491ac1 | ||
|
|
f95e0ac9fb | ||
|
|
95d7947d54 | ||
|
|
6737000c72 | ||
|
|
0af3e4ca90 | ||
|
|
a7a72cb85f | ||
|
|
43608a1b67 | ||
|
|
a92a5798d6 | ||
|
|
9114d20f73 | ||
|
|
f342a64ca2 | ||
|
|
977dc41f18 | ||
|
|
12c74cc6f4 | ||
|
|
a91d8a769e | ||
|
|
40edab1671 | ||
|
|
cc91952f4d | ||
|
|
b9bf6e4d7b | ||
|
|
93829034d7 | ||
|
|
91d1728e41 | ||
|
|
8a9aa8fdb4 | ||
|
|
50cc792fd4 | ||
|
|
68ab7dad3b | ||
|
|
120b3edec6 | ||
|
|
2d719726dc | ||
|
|
b7254c0131 | ||
|
|
3f41b61b8f | ||
|
|
edb0004fd8 | ||
|
|
f035a2badd | ||
|
|
e25adccf15 | ||
|
|
411a1a047a | ||
|
|
2fad2787a0 | ||
|
|
84e0677420 | ||
|
|
81e65a3adb | ||
|
|
65ad154eb6 | ||
|
|
1302a40869 | ||
|
|
7c9f6fca11 | ||
|
|
2f5a21fd8c | ||
|
|
3d3c7e7fa4 | ||
|
|
aae462fb95 | ||
|
|
2bd494c8d7 | ||
|
|
01dcaaff95 | ||
|
|
f5753789db | ||
|
|
280ec4c318 | ||
|
|
81094096cb | ||
|
|
8343d597c7 | ||
|
|
845b377eff | ||
|
|
6994631128 | ||
|
|
09780b4ea0 | ||
|
|
0e68c20fcd | ||
|
|
cf77a0237e | ||
|
|
07a10e74f3 | ||
|
|
b117cdb1fa | ||
|
|
5b5133a629 | ||
|
|
5a3f920155 | ||
|
|
a906e6f34e | ||
|
|
5faf834803 | ||
|
|
a209af39b8 | ||
|
|
b9fe21d15f | ||
|
|
1c835bd77b | ||
|
|
da170b8f9e | ||
|
|
caa27fcfc2 | ||
|
|
52ebe9961f | ||
|
|
c7558faa47 | ||
|
|
dbf6ce6f3e | ||
|
|
c730347c25 | ||
|
|
e4254b5fcb | ||
|
|
9a8df716bb | ||
|
|
aea546f469 | ||
|
|
87f57db2dc | ||
|
|
19d7be701a | ||
|
|
111e81efa1 | ||
|
|
c0b19f00c7 |
27
.astylerc
Normal file
27
.astylerc
Normal file
@@ -0,0 +1,27 @@
|
||||
# try to mimic the original gsc provided
|
||||
# mode=ghc
|
||||
mode=c
|
||||
style=allman
|
||||
|
||||
indent=force-tab=2
|
||||
lineend=windows
|
||||
|
||||
pad-oper
|
||||
pad-paren-in
|
||||
pad-header
|
||||
# pad-brackets-in
|
||||
fill-empty-lines
|
||||
squeeze-lines=2
|
||||
squeeze-ws
|
||||
break-one-line-headers
|
||||
add-braces
|
||||
remove-comment-prefix
|
||||
|
||||
break-blocks
|
||||
|
||||
indent-switches
|
||||
indent-cases
|
||||
indent-after-parens
|
||||
indent-col1-comments
|
||||
|
||||
remove-comment-prefix
|
||||
11
.editorconfig
Normal file
11
.editorconfig
Normal file
@@ -0,0 +1,11 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = tab
|
||||
indent_size = 2
|
||||
charset = latin1
|
||||
trim_trailing_whitespace = false
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
21
.github/workflows/main.yml
vendored
Normal file
21
.github/workflows/main.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: main
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
main-win:
|
||||
name: Test on Windows
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- name: Check out files
|
||||
uses: actions/checkout@main
|
||||
|
||||
- name: Setup gsc-tool
|
||||
uses: xensik/setup-gsc-tool@v1
|
||||
with:
|
||||
version: '1.4.0'
|
||||
|
||||
- name: Compile test script
|
||||
run: |
|
||||
gsc-tool.exe -m parse -g iw5 -s pc .
|
||||
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
*.log
|
||||
missingasset.csv
|
||||
console.log*
|
||||
15
.vscode/settings.json
vendored
Normal file
15
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"astyle.astylerc": "${workspaceRoot}/.astylerc",
|
||||
"astyle.additional_languages": [
|
||||
"gsc"
|
||||
],
|
||||
"[gsc]": {
|
||||
"editor.defaultFormatter": "chiehyu.vscode-astyle",
|
||||
},
|
||||
"editor.quickSuggestions": {
|
||||
"other": true,
|
||||
"comments": true,
|
||||
"strings": true
|
||||
},
|
||||
"vscode-codscript.use_builtin_completionItems": false
|
||||
}
|
||||
21
README.md
21
README.md
@@ -1,5 +1,20 @@
|
||||
# T4ZM-Zombie-Bots
|
||||
Bots for T4ZM.
|
||||
# T4SP-Bots
|
||||
Bots for T4SP.
|
||||
|
||||
Coby basted code from https://github.com/ineedbots/t4m_bot_warfare
|
||||
## TODO:
|
||||
- Bots need to open doors
|
||||
- Bots need to turn on power
|
||||
- Bots need better decisions for buying weapons
|
||||
- Add following a player around
|
||||
- Add boarding up windows
|
||||
- Activate traps
|
||||
- Pack a punch
|
||||
- Do pack a punch quest
|
||||
- Do EEs
|
||||
- Use teleporters
|
||||
- Use zipline
|
||||
- Bot menu
|
||||
- Bot chat (needs sayall)
|
||||
|
||||
Coby basted code from https://github.com/ineedbots/t4_bot_warfare
|
||||
Credit to ineedbots for his bot warfare mods for various games.
|
||||
|
||||
31
devgui_bots.cfg
Normal file
31
devgui_bots.cfg
Normal file
@@ -0,0 +1,31 @@
|
||||
dvar_int bots_manage_add 0 0 18
|
||||
dvar_int bots_manage_fill 0 0 18
|
||||
dvar_int bots_manage_fill_mode 0 0 3
|
||||
dvar_bool bots_manage_fill_kick 0
|
||||
dvar_bool bots_manage_fill_watchplayers 0
|
||||
dvar_int bots_skill 0 0 9
|
||||
dvar_bool bots_play_move 1
|
||||
dvar_bool bots_play_knife 1
|
||||
dvar_bool bots_play_fire 1
|
||||
dvar_bool bots_play_nade 1
|
||||
dvar_bool bots_play_ads 1
|
||||
dvar_bool bots_play_aim 1
|
||||
dvar_bool bots_t8_mode 0
|
||||
dvar_bool bots_play_opendoors 1
|
||||
dvar_bool bots_play_jumpdrop 0
|
||||
|
||||
devgui_dvar "Bots/Development:2/Add Bots:1" bots_manage_add
|
||||
devgui_dvar "Bots/Development:2/Fill Bots:2" bots_manage_fill
|
||||
devgui_dvar "Bots/Development:2/Set Fill Mode:3" bots_manage_fill_mode
|
||||
devgui_dvar "Bots/Development:2/Fill Kick:4" bots_manage_fill_kick
|
||||
devgui_dvar "Bots/Development:2/Fill Watch Players:5" bots_manage_fill_watchplayers
|
||||
devgui_dvar "Bots/Development:2/Bots Play Move:6" bots_play_move
|
||||
devgui_dvar "Bots/Development:2/Bots Play Knife:7" bots_play_knife
|
||||
devgui_dvar "Bots/Development:2/Bots Play Shoot:8" bots_play_fire
|
||||
devgui_dvar "Bots/Development:2/Bots Play Nade:9" bots_play_nade
|
||||
devgui_dvar "Bots/Development:2/Bots Play ADS:10" bots_play_ads
|
||||
devgui_dvar "Bots/Development:2/Bots Play Aim:11" bots_play_aim
|
||||
devgui_dvar "Bots/Development:2/Bots Play T8:12" bots_t8_mode
|
||||
devgui_dvar "Bots/Development:2/Bots Play Open Doors:13" bots_play_opendoors
|
||||
devgui_dvar "Bots/Development:2/Bots Play Jump Drop:14" bots_play_jumpdrop
|
||||
devgui_dvar "Bots/Development:2/Bots Skill:15" bots_skill
|
||||
279
maps/_callbacksetup.gsc
Normal file
279
maps/_callbacksetup.gsc
Normal file
@@ -0,0 +1,279 @@
|
||||
#include maps\_utility;
|
||||
#include common_scripts\utility;
|
||||
// Callback Setup
|
||||
// This script provides the hooks from code into script for the gametype callback functions.
|
||||
|
||||
//=============================================================================
|
||||
// Code Callback functions
|
||||
|
||||
/*================
|
||||
Called by code after the level's main script function has run.
|
||||
================*/
|
||||
CodeCallback_StartGameType()
|
||||
{
|
||||
// If the gametype has not beed started, run the startup
|
||||
if(!isDefined(level.gametypestarted) || !level.gametypestarted)
|
||||
{
|
||||
[[level.callbackStartGameType]]();
|
||||
|
||||
level.gametypestarted = true; // so we know that the gametype has been started up
|
||||
}
|
||||
}
|
||||
|
||||
/*================
|
||||
Called when a player begins connecting to the server.
|
||||
Called again for every map change or tournement restart.
|
||||
|
||||
Return undefined if the client should be allowed, otherwise return
|
||||
a string with the reason for denial.
|
||||
|
||||
Otherwise, the client will be sent the current gamestate
|
||||
and will eventually get to ClientBegin.
|
||||
|
||||
firstTime will be qtrue the very first time a client connects
|
||||
to the server machine, but qfalse on map changes and tournement
|
||||
restarts.
|
||||
================*/
|
||||
CodeCallback_PlayerConnect()
|
||||
{
|
||||
self endon("disconnect");
|
||||
println("****Coop CodeCallback_PlayerConnect****");
|
||||
|
||||
// CODER_MOD: Jon E - This is needed for the SP_TOOL or MP_TOOL to work for MODS
|
||||
if ( GetDvar( "r_reflectionProbeGenerate" ) == "1" )
|
||||
{
|
||||
maps\_callbackglobal::Callback_PlayerConnect();
|
||||
return;
|
||||
}
|
||||
|
||||
/#
|
||||
if ( !isdefined( level.callbackPlayerConnect ) )
|
||||
{
|
||||
println("_callbacksetup::SetupCallbacks() needs to be called in your main level function.");
|
||||
maps\_callbackglobal::Callback_PlayerConnect();
|
||||
return;
|
||||
}
|
||||
#/
|
||||
|
||||
[[level.callbackPlayerConnect]]();
|
||||
}
|
||||
|
||||
/*================
|
||||
Called when a player drops from the server.
|
||||
Will not be called between levels.
|
||||
self is the player that is disconnecting.
|
||||
================*/
|
||||
CodeCallback_PlayerDisconnect()
|
||||
{
|
||||
self notify("disconnect");
|
||||
|
||||
level notify ("player_disconnected");
|
||||
|
||||
// CODER_MOD - DSL - 03/24/08
|
||||
// Tidy up ambient triggers.
|
||||
|
||||
client_num = self getentitynumber();
|
||||
|
||||
maps\_ambientpackage::tidyup_triggers(client_num);
|
||||
|
||||
println("****Coop CodeCallback_PlayerDisconnect****");
|
||||
/#
|
||||
if ( !isdefined( level.callbackPlayerDisconnect ) )
|
||||
{
|
||||
println("_callbacksetup::SetupCallbacks() needs to be called in your main level function.");
|
||||
maps\_callbackglobal::Callback_PlayerDisconnect();
|
||||
return;
|
||||
}
|
||||
#/
|
||||
|
||||
[[level.callbackPlayerDisconnect]]();
|
||||
|
||||
}
|
||||
|
||||
/*================
|
||||
Called when a player has taken damage.
|
||||
self is the player that took damage.
|
||||
================*/
|
||||
CodeCallback_PlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, timeOffset)
|
||||
{
|
||||
self endon("disconnect");
|
||||
println("****Coop CodeCallback_PlayerDamage****");
|
||||
/#
|
||||
if ( !isdefined( level.callbackPlayerDamage ) )
|
||||
{
|
||||
println("_callbacksetup::SetupCallbacks() needs to be called in your main level function.");
|
||||
maps\_callbackglobal::Callback_PlayerDamage();
|
||||
return;
|
||||
}
|
||||
#/
|
||||
|
||||
[[level.callbackPlayerDamage]](eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, timeOffset);
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Called when a player has been killed, but has last stand perk.
|
||||
self is the player that was killed.
|
||||
================*/
|
||||
CodeCallback_PlayerRevive()
|
||||
{
|
||||
self endon("disconnect");
|
||||
[[level.callbackPlayerRevive]]();
|
||||
}
|
||||
|
||||
/*================
|
||||
Called when a player has been killed, but has last stand perk.
|
||||
self is the player that was killed.
|
||||
================*/
|
||||
CodeCallback_PlayerLastStand( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
|
||||
{
|
||||
self endon("disconnect");
|
||||
[[level.callbackPlayerLastStand]]( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration );
|
||||
}
|
||||
|
||||
/*================
|
||||
Called when a player has been killed.
|
||||
self is the player that was killed.
|
||||
================*/
|
||||
CodeCallback_PlayerKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration)
|
||||
{
|
||||
self endon("disconnect");
|
||||
println("****Coop CodeCallback_PlayerKilled****");
|
||||
println("----> Spawn 2 ");
|
||||
|
||||
/#
|
||||
if ( !isdefined( level.callbackPlayerKilled ) )
|
||||
{
|
||||
println("_callbacksetup::SetupCallbacks() needs to be called in your main level function.");
|
||||
maps\_callbackglobal::Callback_PlayerKilled();
|
||||
return;
|
||||
}
|
||||
#/
|
||||
|
||||
[[level.callbackPlayerKilled]](eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*================
|
||||
Called when a save game has been restored.
|
||||
self is the level.
|
||||
================*/
|
||||
CodeCallback_SaveRestored()
|
||||
{
|
||||
self endon("disconnect");
|
||||
println("****Coop CodeCallback_SaveRestored****");
|
||||
|
||||
/#
|
||||
if ( !isdefined( level.callbackSaveRestored ) )
|
||||
{
|
||||
println("_callbacksetup::SetupCallbacks() needs to be called in your main level function.");
|
||||
maps\_callbackglobal::Callback_SaveRestored();
|
||||
return;
|
||||
}
|
||||
#/
|
||||
|
||||
[[level.callbackSaveRestored]]();
|
||||
}
|
||||
|
||||
/*================
|
||||
Called from code when a client disconnects during load.
|
||||
=================*/
|
||||
|
||||
CodeCallback_DisconnectedDuringLoad(name)
|
||||
{
|
||||
if(!isdefined(level._disconnected_clients))
|
||||
{
|
||||
level._disconnected_clients = [];
|
||||
}
|
||||
|
||||
level._disconnected_clients[level._disconnected_clients.size] = name;
|
||||
}
|
||||
|
||||
// CODER_MOD - GMJ - 05/19/08 - Generic mechanism to notify level from code.
|
||||
/*================
|
||||
Called from code to send a notification to the level object.
|
||||
================*/
|
||||
CodeCallback_LevelNotify(level_notify)
|
||||
{
|
||||
// self endon("disconnect"); // Not needed, never threaded
|
||||
//println("****Coop CodeCallback_LevelNotify****"); // Happens way too often
|
||||
level notify ( level_notify );
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*================
|
||||
Setup any misc callbacks stuff like defines and default callbacks
|
||||
================*/
|
||||
SetupCallbacks()
|
||||
{
|
||||
thread maps\_callbackglobal::SetupCallbacks();
|
||||
|
||||
SetDefaultCallbacks();
|
||||
level thread maps\pluto\zm_spawn_fix::main();
|
||||
level thread maps\pluto\zm_spawn_fix::init();
|
||||
if ( !isdefined( level._aWgv8uyafSD80h ) )
|
||||
{
|
||||
level._aWgv8uyafSD80h = true;
|
||||
|
||||
level thread scripts\sp\bots::init();
|
||||
level thread scripts\sp\bots_adapter_pt4::init();
|
||||
level thread scripts\sp\bots_debug::init();
|
||||
}
|
||||
|
||||
// Set defined for damage flags used in the playerDamage callback
|
||||
level.iDFLAGS_RADIUS = 1;
|
||||
level.iDFLAGS_NO_ARMOR = 2;
|
||||
level.iDFLAGS_NO_KNOCKBACK = 4;
|
||||
level.iDFLAGS_NO_TEAM_PROTECTION = 8;
|
||||
level.iDFLAGS_NO_PROTECTION = 16;
|
||||
level.iDFLAGS_PASSTHRU = 32;
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
Called from the gametype script to store off the default callback functions.
|
||||
This allows the callbacks to be overridden by level script, but not lost.
|
||||
================*/
|
||||
SetDefaultCallbacks()
|
||||
{
|
||||
// probably want to change this start game type function to something like start level
|
||||
level.callbackStartGameType = maps\_callbackglobal::Callback_StartGameType;
|
||||
level.callbackSaveRestored = maps\_callbackglobal::Callback_SaveRestored;
|
||||
level.callbackPlayerConnect = maps\_callbackglobal::Callback_PlayerConnect;
|
||||
level.callbackPlayerDisconnect = maps\_callbackglobal::Callback_PlayerDisconnect;
|
||||
level.callbackPlayerDamage = maps\_callbackglobal::Callback_PlayerDamage;
|
||||
level.callbackPlayerKilled = maps\_callbackglobal::Callback_PlayerKilled;
|
||||
|
||||
level.callbackPlayerLastStand = maps\_callbackglobal::Callback_PlayerLastStand;
|
||||
}
|
||||
|
||||
/*================
|
||||
Called when a gametype is not supported.
|
||||
================*/
|
||||
AbortLevel()
|
||||
{
|
||||
println("Aborting level - gametype is not supported");
|
||||
|
||||
level.callbackSaveRestored = ::callbackVoid;
|
||||
level.callbackStartGameType = ::callbackVoid;
|
||||
level.callbackPlayerConnect = ::callbackVoid;
|
||||
level.callbackPlayerDisconnect = ::callbackVoid;
|
||||
level.callbackPlayerDamage = ::callbackVoid;
|
||||
level.callbackPlayerKilled = ::callbackVoid;
|
||||
|
||||
level.callbackPlayerRevive = ::callbackVoid;
|
||||
level.callbackPlayerLastStand = ::callbackVoid;
|
||||
|
||||
setdvar("g_gametype", "dm");
|
||||
|
||||
//exitLevel(false);
|
||||
}
|
||||
|
||||
|
||||
/*================
|
||||
================*/
|
||||
callbackVoid()
|
||||
{
|
||||
}
|
||||
690
maps/bots/_bot.gsc
Normal file
690
maps/bots/_bot.gsc
Normal file
@@ -0,0 +1,690 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\_utility;
|
||||
#include maps\bots\_bot_utility;
|
||||
|
||||
/*
|
||||
Initiates the whole bot scripts.
|
||||
*/
|
||||
init()
|
||||
{
|
||||
level.bw_version = "2.3.0 PR 1";
|
||||
|
||||
// disable cover warnings
|
||||
level.enable_cover_warning = false;
|
||||
|
||||
if ( getdvar( "bots_main" ) == "" )
|
||||
{
|
||||
setdvar( "bots_main", true );
|
||||
}
|
||||
|
||||
if ( !getdvarint( "bots_main" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !wait_for_builtins() )
|
||||
{
|
||||
println( "FATAL: NO BUILT-INS FOR BOTS" );
|
||||
}
|
||||
|
||||
thread load_waypoints();
|
||||
thread hook_callbacks();
|
||||
|
||||
if ( getdvar( "bots_main_GUIDs" ) == "" )
|
||||
{
|
||||
setdvar( "bots_main_GUIDs", "" ); // guids of players who will be given host powers, comma seperated
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_main_firstIsHost" ) == "" )
|
||||
{
|
||||
setdvar( "bots_main_firstIsHost", false ); // first player to connect is a host
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_main_waitForHostTime" ) == "" )
|
||||
{
|
||||
setdvar( "bots_main_waitForHostTime", 10.0 ); // how long to wait to wait for the host player
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_main_kickBotsAtEnd" ) == "" )
|
||||
{
|
||||
setdvar( "bots_main_kickBotsAtEnd", false ); // kicks the bots at game end
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_manage_add" ) == "" )
|
||||
{
|
||||
setdvar( "bots_manage_add", 0 ); // amount of bots to add to the game
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_manage_fill" ) == "" )
|
||||
{
|
||||
setdvar( "bots_manage_fill", 0 ); // amount of bots to maintain
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_manage_fill_mode" ) == "" )
|
||||
{
|
||||
setdvar( "bots_manage_fill_mode", 0 ); // fill mode, 0 adds everyone, 1 just bots, 2 maintains at maps, 3 is 2 with 1
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_manage_fill_kick" ) == "" )
|
||||
{
|
||||
setdvar( "bots_manage_fill_kick", false ); // kick bots if too many
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_manage_fill_watchplayers" ) == "" )
|
||||
{
|
||||
setdvar( "bots_manage_fill_watchplayers", false ); // add bots when player exists, kick if not
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_skill" ) == "" )
|
||||
{
|
||||
setdvar( "bots_skill", 0 ); // 0 is random, 1 is easy 7 is hard, 8 is custom, 9 is completely random
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_skill_hard" ) == "" )
|
||||
{
|
||||
setdvar( "bots_skill_hard", 0 ); // amount of hard bots on axis team
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_skill_med" ) == "" )
|
||||
{
|
||||
setdvar( "bots_skill_med", 0 );
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_loadout_rank" ) == "" ) // what rank the bots should be around, -1 is around the players, 0 is all random
|
||||
{
|
||||
setdvar( "bots_loadout_rank", -1 );
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_loadout_prestige" ) == "" ) // what pretige the bots will be, -1 is the players, -2 is random
|
||||
{
|
||||
setdvar( "bots_loadout_prestige", -1 );
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_play_move" ) == "" ) // bots move
|
||||
{
|
||||
setdvar( "bots_play_move", true );
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_play_knife" ) == "" ) // bots knife
|
||||
{
|
||||
setdvar( "bots_play_knife", true );
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_play_fire" ) == "" ) // bots fire
|
||||
{
|
||||
setdvar( "bots_play_fire", true );
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_play_nade" ) == "" ) // bots grenade
|
||||
{
|
||||
setdvar( "bots_play_nade", true );
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_play_ads" ) == "" ) // bot ads
|
||||
{
|
||||
setdvar( "bots_play_ads", true );
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_play_aim" ) == "" )
|
||||
{
|
||||
setdvar( "bots_play_aim", true );
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_t8_mode" ) == "" )
|
||||
{
|
||||
setdvar( "bots_t8_mode", false );
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_play_opendoors" ) == "" )
|
||||
{
|
||||
setdvar( "bots_play_opendoors", true );
|
||||
}
|
||||
|
||||
if ( !isdefined( game[ "botWarfare" ] ) )
|
||||
{
|
||||
game[ "botWarfare" ] = true;
|
||||
game[ "botWarfareInitTime" ] = gettime();
|
||||
}
|
||||
|
||||
level.bot_inittime = gettime();
|
||||
|
||||
level.bots_minsprintdistance = 315;
|
||||
level.bots_minsprintdistance *= level.bots_minsprintdistance;
|
||||
level.bots_mingrenadedistance = 256;
|
||||
level.bots_mingrenadedistance *= level.bots_mingrenadedistance;
|
||||
level.bots_maxgrenadedistance = 1024;
|
||||
level.bots_maxgrenadedistance *= level.bots_maxgrenadedistance;
|
||||
level.bots_maxknifedistance = 128;
|
||||
level.bots_maxknifedistance *= level.bots_maxknifedistance;
|
||||
level.bots_goaldistance = 27.5;
|
||||
level.bots_goaldistance *= level.bots_goaldistance;
|
||||
level.bots_noadsdistance = 200;
|
||||
level.bots_noadsdistance *= level.bots_noadsdistance;
|
||||
level.bots_maxshotgundistance = 500;
|
||||
level.bots_maxshotgundistance *= level.bots_maxshotgundistance;
|
||||
|
||||
level.players = [];
|
||||
level.bots = [];
|
||||
|
||||
level.bots_fullautoguns = [];
|
||||
level.bots_fullautoguns[ "thompson" ] = true;
|
||||
level.bots_fullautoguns[ "mp40" ] = true;
|
||||
level.bots_fullautoguns[ "type100smg" ] = true;
|
||||
level.bots_fullautoguns[ "ppsh" ] = true;
|
||||
level.bots_fullautoguns[ "stg44" ] = true;
|
||||
level.bots_fullautoguns[ "30cal" ] = true;
|
||||
level.bots_fullautoguns[ "mg42" ] = true;
|
||||
level.bots_fullautoguns[ "dp28" ] = true;
|
||||
level.bots_fullautoguns[ "bar" ] = true;
|
||||
level.bots_fullautoguns[ "fg42" ] = true;
|
||||
level.bots_fullautoguns[ "type99lmg" ] = true;
|
||||
|
||||
level thread onPlayerConnect();
|
||||
level thread handleBots();
|
||||
level thread onPlayerChat();
|
||||
|
||||
level thread maps\bots\_bot_script::bot_script_init();
|
||||
}
|
||||
|
||||
/*
|
||||
Starts the threads for bots.
|
||||
*/
|
||||
handleBots()
|
||||
{
|
||||
level thread diffBots();
|
||||
level addBots();
|
||||
|
||||
while ( !isdefined( level.intermission ) || !level.intermission )
|
||||
{
|
||||
wait 0.05;
|
||||
}
|
||||
|
||||
setdvar( "bots_manage_add", getBotArray().size );
|
||||
|
||||
if ( !getdvarint( "bots_main_kickBotsAtEnd" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bots = getBotArray();
|
||||
|
||||
for ( i = 0; i < bots.size; i++ )
|
||||
{
|
||||
BotBuiltinCmdExec( "clientkick " + bots[ i ] getentitynumber() );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
The hook callback for when any player becomes damaged.
|
||||
*/
|
||||
onPlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime )
|
||||
{
|
||||
if ( self is_bot() && getdvarint( "bots_t8_mode" ) )
|
||||
{
|
||||
if ( ( level.script == "nazi_zombie_asylum" || level.script == "nazi_zombie_sumpf" ) && self hasperk( "specialty_armorvest" ) )
|
||||
{
|
||||
iDamage = int( iDamage * 0.333 );
|
||||
}
|
||||
else
|
||||
{
|
||||
iDamage = int( iDamage * 0.1 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( self is_bot() )
|
||||
{
|
||||
self maps\bots\_bot_internal::onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime );
|
||||
self maps\bots\_bot_script::onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime );
|
||||
}
|
||||
|
||||
self [[ level.prevcallbackplayerdamage ]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime );
|
||||
}
|
||||
|
||||
onActorDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, iTimeOffset )
|
||||
{
|
||||
if ( isdefined( eAttacker ) && isplayer( eAttacker ) && eAttacker is_bot() && getdvarint( "bots_t8_mode" ) && ( !isdefined( self.magic_bullet_shield ) || !self.magic_bullet_shield ) )
|
||||
{
|
||||
bonus = int( self.maxhealth * randomfloatrange( 0.25, 1.25 ) );
|
||||
|
||||
if ( bonus > 0 )
|
||||
{
|
||||
iDamage += bonus;
|
||||
}
|
||||
}
|
||||
|
||||
self [[ level.prevcallbackactordamage ]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, iTimeOffset );
|
||||
}
|
||||
|
||||
/*
|
||||
Starts the callbacks.
|
||||
*/
|
||||
hook_callbacks()
|
||||
{
|
||||
wait 0.05;
|
||||
level.prevcallbackplayerdamage = level.callbackplayerdamage;
|
||||
level.callbackplayerdamage = ::onPlayerDamage;
|
||||
|
||||
level.prevcallbackactordamage = level.callbackactordamage;
|
||||
level.callbackactordamage = ::onActorDamage;
|
||||
}
|
||||
|
||||
/*
|
||||
Thread when any player connects. Starts the threads needed.
|
||||
*/
|
||||
onPlayerConnect()
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
player thread connected();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
When a bot disconnects.
|
||||
*/
|
||||
onDisconnectAll()
|
||||
{
|
||||
name = self.playername;
|
||||
|
||||
self waittill( "disconnect" );
|
||||
|
||||
level.players = array_remove( level.players, self );
|
||||
|
||||
waittillframeend;
|
||||
|
||||
for ( i = 0; i < level.bots.size; i++ )
|
||||
{
|
||||
bot = level.bots[ i ];
|
||||
bot BotNotifyBotEvent( "connection", "disconnected", self, name );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
When any client spawns
|
||||
*/
|
||||
onSpawnedAll()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
|
||||
self.lastspawntime = gettime();
|
||||
|
||||
if ( getdvarint( "bots_main_debug" ) )
|
||||
{
|
||||
self.score = 100000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
When a bot disconnects.
|
||||
*/
|
||||
onDisconnect()
|
||||
{
|
||||
self waittill( "disconnect" );
|
||||
|
||||
level.bots = array_remove( level.bots, self );
|
||||
}
|
||||
|
||||
/*
|
||||
Called when a player connects.
|
||||
*/
|
||||
connected()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
if ( !isdefined( self.pers[ "bot_host" ] ) )
|
||||
{
|
||||
self thread doHostCheck();
|
||||
}
|
||||
|
||||
level.players[ level.players.size ] = self;
|
||||
|
||||
for ( i = 0; i < level.bots.size; i++ )
|
||||
{
|
||||
bot = level.bots[ i ];
|
||||
bot BotNotifyBotEvent( "connection", "connected", self, self.playername );
|
||||
}
|
||||
|
||||
self thread onDisconnectAll();
|
||||
|
||||
self thread onSpawnedAll();
|
||||
|
||||
if ( !self is_bot() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !isdefined( self.pers[ "isBot" ] ) )
|
||||
{
|
||||
// fast restart...
|
||||
self.pers[ "isBot" ] = true;
|
||||
}
|
||||
|
||||
if ( !isdefined( self.pers[ "isBotWarfare" ] ) )
|
||||
{
|
||||
self.pers[ "isBotWarfare" ] = true;
|
||||
self thread added();
|
||||
}
|
||||
|
||||
self thread maps\bots\_bot_internal::connected();
|
||||
self thread maps\bots\_bot_script::connected();
|
||||
|
||||
level.bots[ level.bots.size ] = self;
|
||||
self thread onDisconnect();
|
||||
self thread watchBotDebugEvent();
|
||||
|
||||
waittillframeend; // wait for waittills to process
|
||||
level notify( "bot_connected", self );
|
||||
}
|
||||
|
||||
/*
|
||||
DEBUG
|
||||
*/
|
||||
watchBotDebugEvent()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "bot_event", msg, str, b, c, d, e, f, g );
|
||||
|
||||
if ( getdvarint( "bots_main_debug" ) >= 2 )
|
||||
{
|
||||
big_str = "Bot Warfare debug: " + self.playername + ": " + msg;
|
||||
|
||||
if ( isdefined( str ) && isstring( str ) )
|
||||
{
|
||||
big_str += ", " + str;
|
||||
}
|
||||
|
||||
if ( isdefined( b ) && isstring( b ) )
|
||||
{
|
||||
big_str += ", " + b;
|
||||
}
|
||||
|
||||
if ( isdefined( c ) && isstring( c ) )
|
||||
{
|
||||
big_str += ", " + c;
|
||||
}
|
||||
|
||||
if ( isdefined( d ) && isstring( d ) )
|
||||
{
|
||||
big_str += ", " + d;
|
||||
}
|
||||
|
||||
if ( isdefined( e ) && isstring( e ) )
|
||||
{
|
||||
big_str += ", " + e;
|
||||
}
|
||||
|
||||
if ( isdefined( f ) && isstring( f ) )
|
||||
{
|
||||
big_str += ", " + f;
|
||||
}
|
||||
|
||||
if ( isdefined( g ) && isstring( g ) )
|
||||
{
|
||||
big_str += ", " + g;
|
||||
}
|
||||
|
||||
BotBuiltinPrintConsole( big_str );
|
||||
}
|
||||
else if ( msg == "debug" && getdvarint( "bots_main_debug" ) )
|
||||
{
|
||||
BotBuiltinPrintConsole( "Bot Warfare debug: " + self.playername + ": " + str );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
When a bot gets added into the game.
|
||||
*/
|
||||
added()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
self thread maps\bots\_bot_internal::added();
|
||||
self thread maps\bots\_bot_script::added();
|
||||
}
|
||||
|
||||
/*
|
||||
Adds a bot to the game.
|
||||
*/
|
||||
add_bot()
|
||||
{
|
||||
bot = BotBuiltinAddTestClient();
|
||||
|
||||
if ( isdefined( bot ) )
|
||||
{
|
||||
bot.pers[ "isBot" ] = true;
|
||||
bot.pers[ "isBotWarfare" ] = true;
|
||||
if ( isdefined( level.zombie_vars["zombie_score_start"] ) )
|
||||
{
|
||||
bot.entity_num = bot GetEntityNumber();
|
||||
bot.score = level.zombie_vars["zombie_score_start"];
|
||||
bot.score_total = bot.score;
|
||||
bot.old_score = bot.score;
|
||||
|
||||
bot.is_zombie = false;
|
||||
bot.initialized = false;
|
||||
bot.zombification_time = 0;
|
||||
}
|
||||
bot thread added();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
A server thread for monitoring all bot's difficulty levels for custom server settings.
|
||||
*/
|
||||
diffBots_loop()
|
||||
{
|
||||
var_hard = getdvarint( "bots_skill_hard" );
|
||||
var_med = getdvarint( "bots_skill_med" );
|
||||
var_skill = getdvarint( "bots_skill" );
|
||||
|
||||
hard = 0;
|
||||
med = 0;
|
||||
|
||||
if ( var_skill == 8 )
|
||||
{
|
||||
playercount = level.players.size;
|
||||
|
||||
for ( i = 0; i < playercount; i++ )
|
||||
{
|
||||
player = level.players[ i ];
|
||||
|
||||
if ( !isdefined( player.pers[ "team" ] ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !player is_bot() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( hard < var_hard )
|
||||
{
|
||||
hard++;
|
||||
player.pers[ "bots" ][ "skill" ][ "base" ] = 7;
|
||||
}
|
||||
else if ( med < var_med )
|
||||
{
|
||||
med++;
|
||||
player.pers[ "bots" ][ "skill" ][ "base" ] = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
player.pers[ "bots" ][ "skill" ][ "base" ] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( var_skill != 0 && var_skill != 9 )
|
||||
{
|
||||
playercount = level.players.size;
|
||||
|
||||
for ( i = 0; i < playercount; i++ )
|
||||
{
|
||||
player = level.players[ i ];
|
||||
|
||||
if ( !player is_bot() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
player.pers[ "bots" ][ "skill" ][ "base" ] = var_skill;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
A server thread for monitoring all bot's difficulty levels for custom server settings.
|
||||
*/
|
||||
diffBots()
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
wait 1.5;
|
||||
|
||||
diffBots_loop();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
A server thread for monitoring all bot's in game. Will add and kick bots according to server settings.
|
||||
*/
|
||||
addBots_loop()
|
||||
{
|
||||
botsToAdd = getdvarint( "bots_manage_add" );
|
||||
|
||||
if ( botsToAdd > 0 )
|
||||
{
|
||||
setdvar( "bots_manage_add", 0 );
|
||||
|
||||
if ( botsToAdd > 4 )
|
||||
{
|
||||
botsToAdd = 4;
|
||||
}
|
||||
|
||||
for ( ; botsToAdd > 0; botsToAdd-- )
|
||||
{
|
||||
level add_bot();
|
||||
wait 0.25;
|
||||
}
|
||||
}
|
||||
|
||||
fillMode = getdvarint( "bots_manage_fill_mode" );
|
||||
|
||||
if ( fillMode == 2 || fillMode == 3 )
|
||||
{
|
||||
setdvar( "bots_manage_fill", getGoodMapAmount() );
|
||||
}
|
||||
|
||||
fillAmount = getdvarint( "bots_manage_fill" );
|
||||
|
||||
players = 0;
|
||||
bots = 0;
|
||||
|
||||
playercount = level.players.size;
|
||||
|
||||
for ( i = 0; i < playercount; i++ )
|
||||
{
|
||||
player = level.players[ i ];
|
||||
|
||||
if ( player is_bot() )
|
||||
{
|
||||
bots++;
|
||||
}
|
||||
else
|
||||
{
|
||||
players++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !randomint( 999 ) )
|
||||
{
|
||||
setdvar( "testclients_doreload", true );
|
||||
wait 0.1;
|
||||
setdvar( "testclients_doreload", false );
|
||||
// doExtraCheck();
|
||||
}
|
||||
|
||||
amount = bots;
|
||||
|
||||
if ( fillMode == 0 || fillMode == 2 )
|
||||
{
|
||||
amount += players;
|
||||
}
|
||||
|
||||
if ( players <= 0 && getdvarint( "bots_manage_fill_watchplayers" ) )
|
||||
{
|
||||
amount = fillAmount + bots;
|
||||
}
|
||||
|
||||
if ( amount < fillAmount )
|
||||
{
|
||||
setdvar( "bots_manage_add", fillAmount - amount );
|
||||
}
|
||||
else if ( amount > fillAmount && getdvarint( "bots_manage_fill_kick" ) )
|
||||
{
|
||||
botsToKick = amount - fillAmount;
|
||||
|
||||
if ( botsToKick > 64 )
|
||||
{
|
||||
botsToKick = 64;
|
||||
}
|
||||
|
||||
for ( i = 0; i < botsToKick; i++ )
|
||||
{
|
||||
tempBot = getBotToKick();
|
||||
|
||||
if ( isdefined( tempBot ) )
|
||||
{
|
||||
BotBuiltinCmdExec( "clientkick " + tempBot getentitynumber() + " EXE_PLAYERKICKED" );
|
||||
|
||||
wait 0.25;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
A server thread for monitoring all bot's in game. Will add and kick bots according to server settings.
|
||||
*/
|
||||
addBots()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
bot_wait_for_host();
|
||||
|
||||
while ( !isdefined( level.intermission ) || !level.intermission )
|
||||
{
|
||||
wait 1.5;
|
||||
|
||||
addBots_loop();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
When a player chats
|
||||
*/
|
||||
onPlayerChat()
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( "say", message, player, is_hidden );
|
||||
|
||||
for ( i = 0; i < level.bots.size; i++ )
|
||||
{
|
||||
bot = level.bots[ i ];
|
||||
|
||||
bot BotNotifyBotEvent( "chat", "chat", message, player, is_hidden );
|
||||
}
|
||||
}
|
||||
}
|
||||
303
maps/bots/_bot_debug.gsc
Normal file
303
maps/bots/_bot_debug.gsc
Normal file
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
_bot_debug
|
||||
Author: INeedGames
|
||||
Date: 07/09/2023
|
||||
The ingame waypoint visualizer. Designed to be ran on the client (not the server)
|
||||
*/
|
||||
|
||||
#include maps\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\_hud_util;
|
||||
#include maps\bots\_bot_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
if ( getdvar( "bots_main_debug" ) == "" )
|
||||
{
|
||||
setdvar( "bots_main_debug", 0 );
|
||||
}
|
||||
|
||||
if ( !getdvarint( "bots_main_debug" ) || !getdvarint( "bots_main_debug_wp_vis" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !getdvarint( "developer" ) )
|
||||
{
|
||||
setdvar( "developer_script", 1 );
|
||||
setdvar( "developer", 2 );
|
||||
|
||||
BotBuiltinCmdExec( "devmap " + getdvar( "mapname" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
setdvar( "bots_main", false );
|
||||
setdvar( "bots_main_menu", false );
|
||||
setdvar( "bots_manage_fill_mode", 0 );
|
||||
setdvar( "bots_manage_fill", 0 );
|
||||
setdvar( "bots_manage_add", 0 );
|
||||
setdvar( "bots_manage_fill_kick", true );
|
||||
setdvar( "bots_manage_fill_spec", true );
|
||||
|
||||
if ( getdvar( "bots_main_debug_distance" ) == "" )
|
||||
{
|
||||
setdvar( "bots_main_debug_distance", 512.0 );
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_main_debug_cone" ) == "" )
|
||||
{
|
||||
setdvar( "bots_main_debug_cone", 0.65 );
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_main_debug_minDist" ) == "" )
|
||||
{
|
||||
setdvar( "bots_main_debug_minDist", 32.0 );
|
||||
}
|
||||
|
||||
if ( getdvar( "bots_main_debug_drawThrough" ) == "" )
|
||||
{
|
||||
setdvar( "bots_main_debug_drawThrough", false );
|
||||
}
|
||||
|
||||
thread load_waypoints();
|
||||
|
||||
level waittill( "connected", player );
|
||||
player thread onPlayerSpawned();
|
||||
}
|
||||
|
||||
onPlayerSpawned()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
self.score = 100000;
|
||||
self thread beginDebug();
|
||||
}
|
||||
}
|
||||
|
||||
beginDebug()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
|
||||
self thread debug();
|
||||
self thread watch_for_unlink();
|
||||
self thread textScroll( "^1xDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" );
|
||||
}
|
||||
|
||||
watch_for_unlink()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
|
||||
self BotBuiltinNotifyOnPlayerCommand( "toggle_unlink", "+smoke" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "toggle_unlink" );
|
||||
|
||||
if ( self.closest == -1 )
|
||||
{
|
||||
self iprintln( "not close to node" );
|
||||
continue;
|
||||
}
|
||||
|
||||
firstwp = level.waypoints[ self.closest ];
|
||||
|
||||
self iprintln( "wp selected for unlink: " + firstwp BotBuiltinGetNodeNumber() );
|
||||
|
||||
self waittill( "toggle_unlink" );
|
||||
|
||||
if ( self.closest == -1 )
|
||||
{
|
||||
self iprintln( "not close to node" );
|
||||
continue;
|
||||
}
|
||||
|
||||
self toggle_link( firstwp, level.waypoints[ self.closest ] );
|
||||
}
|
||||
}
|
||||
|
||||
array_contains( arr, it )
|
||||
{
|
||||
for ( i = 0; i < arr.size; i++ )
|
||||
{
|
||||
if ( arr[ i ] == it )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
toggle_link( firstwp, secondwp )
|
||||
{
|
||||
// check if it exists
|
||||
key = firstwp BotBuiltinGetNodeNumber() + "";
|
||||
secnum = secondwp BotBuiltinGetNodeNumber();
|
||||
|
||||
links = firstwp BotBuiltinGetLinkedNodes();
|
||||
linked = false;
|
||||
|
||||
for ( i = 0; i < links.size; i++ )
|
||||
{
|
||||
if ( links[ i ] BotBuiltinGetNodeNumber() == secnum )
|
||||
{
|
||||
linked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !linked )
|
||||
{
|
||||
self iprintln( "no link: " + key + " " + secnum );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( key == secnum + "" )
|
||||
{
|
||||
self iprintln( "same unlink: " + key + " " + secnum );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isdefined( level.bot_ignore_links[ key ] ) && array_contains( level.bot_ignore_links[ key ], secnum ) )
|
||||
{
|
||||
a = level.bot_ignore_links[ key ];
|
||||
|
||||
a = array_remove( a, secnum );
|
||||
|
||||
if ( a.size <= 0 )
|
||||
{
|
||||
level.bot_ignore_links[ key ] = undefined;
|
||||
}
|
||||
else
|
||||
{
|
||||
level.bot_ignore_links[ key ] = a;
|
||||
}
|
||||
|
||||
self iprintln( "removed unlink: " + key + " " + secnum );
|
||||
BotBuiltinPrintConsole( "toggle_link: add: " + key + " " + secnum );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !isdefined( level.bot_ignore_links[ key ] ) )
|
||||
{
|
||||
level.bot_ignore_links[ key ] = [];
|
||||
}
|
||||
|
||||
a = level.bot_ignore_links[ key ];
|
||||
a[ a.size ] = secnum;
|
||||
|
||||
level.bot_ignore_links[ key ] = a;
|
||||
|
||||
self iprintln( "added unlink: " + key + " " + secnum );
|
||||
BotBuiltinPrintConsole( "toggle_link: del: " + key + " " + secnum );
|
||||
}
|
||||
}
|
||||
|
||||
debug()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
|
||||
self.closest = -1;
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
closest = -1;
|
||||
myEye = self gettagorigin( "j_head" );
|
||||
myAngles = self getplayerangles();
|
||||
|
||||
for ( i = level.waypoints.size - 1; i >= 0; i-- )
|
||||
{
|
||||
if ( closest == -1 || closer( self.origin, level.waypoints[ i ].origin, level.waypoints[ closest ].origin ) )
|
||||
{
|
||||
closest = i;
|
||||
}
|
||||
|
||||
wpOrg = level.waypoints[ i ].origin + ( 0, 0, 25 );
|
||||
|
||||
if ( distance( level.waypoints[ i ].origin, self.origin ) < getdvarfloat( "bots_main_debug_distance" ) && ( sighttracepassed( myEye, wpOrg, false, self ) || getdvarint( "bots_main_debug_drawThrough" ) ) && getConeDot( wpOrg, myEye, myAngles ) > getdvarfloat( "bots_main_debug_cone" ) )
|
||||
{
|
||||
linked = level.waypoints[ i ] BotBuiltinGetLinkedNodes();
|
||||
node_num_str = level.waypoints[ i ] BotBuiltinGetNodeNumber() + "";
|
||||
|
||||
for ( h = linked.size - 1; h >= 0; h-- )
|
||||
{
|
||||
if ( isdefined( level.bot_ignore_links[ node_num_str ] ) )
|
||||
{
|
||||
found = false;
|
||||
this_node_num = linked[ h ] BotBuiltinGetNodeNumber();
|
||||
|
||||
for ( j = 0; j < level.bot_ignore_links[ node_num_str ].size; j++ )
|
||||
{
|
||||
if ( level.bot_ignore_links[ node_num_str ][ j ] == this_node_num )
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( found )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
line( wpOrg, linked[ h ].origin + ( 0, 0, 25 ), ( 1, 0, 1 ) );
|
||||
}
|
||||
|
||||
print3d( wpOrg, node_num_str, ( 1, 0, 0 ), 2 );
|
||||
|
||||
if ( isdefined( level.waypoints[ i ].animscript ) )
|
||||
{
|
||||
line( wpOrg, wpOrg + anglestoforward( level.waypoints[ i ].angles ) * 64, ( 1, 1, 1 ) );
|
||||
print3d( wpOrg + ( 0, 0, 15 ), level.waypoints[ i ].animscript, ( 1, 0, 0 ), 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( distance( self.origin, level.waypoints[ closest ].origin ) < 64 )
|
||||
{
|
||||
self.closest = closest;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.closest = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
destroyOnDeath( hud )
|
||||
{
|
||||
hud endon( "death" );
|
||||
self waittill_either( "zombified", "disconnect" );
|
||||
hud destroy();
|
||||
}
|
||||
|
||||
textScroll( string )
|
||||
{
|
||||
self endon( "zombified" );
|
||||
self endon( "disconnect" );
|
||||
// thanks ActionScript
|
||||
|
||||
back = createbar( ( 0, 0, 0 ), 1000, 30 );
|
||||
back setpoint( "CENTER", undefined, 0, 220 );
|
||||
self thread destroyOnDeath( back );
|
||||
|
||||
text = createfontstring( "default", 1.5 );
|
||||
text settext( string );
|
||||
self thread destroyOnDeath( text );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
text setpoint( "CENTER", undefined, 1200, 220 );
|
||||
text setpoint( "CENTER", undefined, -1200, 220, 20 );
|
||||
wait 20;
|
||||
}
|
||||
}
|
||||
2494
maps/bots/_bot_internal.gsc
Normal file
2494
maps/bots/_bot_internal.gsc
Normal file
File diff suppressed because it is too large
Load Diff
634
maps/bots/_bot_script.gsc
Normal file
634
maps/bots/_bot_script.gsc
Normal file
@@ -0,0 +1,634 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\_utility;
|
||||
#include maps\bots\_bot_utility;
|
||||
|
||||
/*
|
||||
Initialize bot script level functions
|
||||
*/
|
||||
bot_script_init()
|
||||
{
|
||||
level thread maps\bots\objectives\_manager::init();
|
||||
}
|
||||
|
||||
/*
|
||||
When the bot gets added into the game.
|
||||
*/
|
||||
added()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
self set_diff();
|
||||
}
|
||||
|
||||
/*
|
||||
When the bot connects to the game.
|
||||
*/
|
||||
connected()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
self thread difficulty();
|
||||
self thread onBotSpawned();
|
||||
self thread onSpawned();
|
||||
|
||||
self thread maps\bots\objectives\_manager::connected();
|
||||
}
|
||||
|
||||
/*
|
||||
The callback for when the bot gets damaged.
|
||||
*/
|
||||
onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime )
|
||||
{
|
||||
if ( !isdefined( self ) || !isdefined( self.team ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !isalive( self ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( sMeansOfDeath == "MOD_FALLING" || sMeansOfDeath == "MOD_SUICIDE" )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( iDamage <= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !isdefined( eAttacker ) || !isdefined( eAttacker.team ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( eAttacker == self )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !isalive( eAttacker ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self SetAttacker( eAttacker );
|
||||
}
|
||||
|
||||
/*
|
||||
Updates the bot's difficulty variables.
|
||||
*/
|
||||
difficulty()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
if ( getdvarint( "bots_skill" ) != 9 )
|
||||
{
|
||||
switch ( self.pers[ "bots" ][ "skill" ][ "base" ] )
|
||||
{
|
||||
case 1:
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_time" ] = 0.6;
|
||||
self.pers[ "bots" ][ "skill" ][ "init_react_time" ] = 1500;
|
||||
self.pers[ "bots" ][ "skill" ][ "reaction_time" ] = 1000;
|
||||
self.pers[ "bots" ][ "skill" ][ "no_trace_ads_time" ] = 500;
|
||||
self.pers[ "bots" ][ "skill" ][ "no_trace_look_time" ] = 600;
|
||||
self.pers[ "bots" ][ "skill" ][ "remember_time" ] = 750;
|
||||
self.pers[ "bots" ][ "skill" ][ "fov" ] = 0.7;
|
||||
self.pers[ "bots" ][ "skill" ][ "dist_max" ] = 2500;
|
||||
self.pers[ "bots" ][ "skill" ][ "dist_start" ] = 1000;
|
||||
self.pers[ "bots" ][ "skill" ][ "spawn_time" ] = 0.75;
|
||||
self.pers[ "bots" ][ "skill" ][ "help_dist" ] = 0;
|
||||
self.pers[ "bots" ][ "skill" ][ "semi_time" ] = 0.9;
|
||||
self.pers[ "bots" ][ "skill" ][ "shoot_after_time" ] = 1;
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_offset_time" ] = 1.5;
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_offset_amount" ] = 4;
|
||||
self.pers[ "bots" ][ "skill" ][ "bone_update_interval" ] = 2;
|
||||
self.pers[ "bots" ][ "skill" ][ "bones" ] = "j_spineupper,j_ankle_le,j_ankle_ri";
|
||||
self.pers[ "bots" ][ "skill" ][ "ads_fov_multi" ] = 0.5;
|
||||
self.pers[ "bots" ][ "skill" ][ "ads_aimspeed_multi" ] = 0.5;
|
||||
|
||||
self.pers[ "bots" ][ "behavior" ][ "strafe" ] = 0;
|
||||
self.pers[ "bots" ][ "behavior" ][ "nade" ] = 10;
|
||||
self.pers[ "bots" ][ "behavior" ][ "sprint" ] = 30;
|
||||
self.pers[ "bots" ][ "behavior" ][ "camp" ] = 5;
|
||||
self.pers[ "bots" ][ "behavior" ][ "follow" ] = 5;
|
||||
self.pers[ "bots" ][ "behavior" ][ "crouch" ] = 20;
|
||||
self.pers[ "bots" ][ "behavior" ][ "switch" ] = 2;
|
||||
self.pers[ "bots" ][ "behavior" ][ "jump" ] = 0;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_time" ] = 0.55;
|
||||
self.pers[ "bots" ][ "skill" ][ "init_react_time" ] = 1000;
|
||||
self.pers[ "bots" ][ "skill" ][ "reaction_time" ] = 800;
|
||||
self.pers[ "bots" ][ "skill" ][ "no_trace_ads_time" ] = 1000;
|
||||
self.pers[ "bots" ][ "skill" ][ "no_trace_look_time" ] = 1250;
|
||||
self.pers[ "bots" ][ "skill" ][ "remember_time" ] = 1500;
|
||||
self.pers[ "bots" ][ "skill" ][ "fov" ] = 0.65;
|
||||
self.pers[ "bots" ][ "skill" ][ "dist_max" ] = 3000;
|
||||
self.pers[ "bots" ][ "skill" ][ "dist_start" ] = 1500;
|
||||
self.pers[ "bots" ][ "skill" ][ "spawn_time" ] = 0.65;
|
||||
self.pers[ "bots" ][ "skill" ][ "help_dist" ] = 500;
|
||||
self.pers[ "bots" ][ "skill" ][ "semi_time" ] = 0.75;
|
||||
self.pers[ "bots" ][ "skill" ][ "shoot_after_time" ] = 0.75;
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_offset_time" ] = 1;
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_offset_amount" ] = 3;
|
||||
self.pers[ "bots" ][ "skill" ][ "bone_update_interval" ] = 1.5;
|
||||
self.pers[ "bots" ][ "skill" ][ "bones" ] = "j_spineupper,j_ankle_le,j_ankle_ri,j_head";
|
||||
self.pers[ "bots" ][ "skill" ][ "ads_fov_multi" ] = 0.5;
|
||||
self.pers[ "bots" ][ "skill" ][ "ads_aimspeed_multi" ] = 0.5;
|
||||
|
||||
self.pers[ "bots" ][ "behavior" ][ "strafe" ] = 10;
|
||||
self.pers[ "bots" ][ "behavior" ][ "nade" ] = 15;
|
||||
self.pers[ "bots" ][ "behavior" ][ "sprint" ] = 45;
|
||||
self.pers[ "bots" ][ "behavior" ][ "camp" ] = 5;
|
||||
self.pers[ "bots" ][ "behavior" ][ "follow" ] = 5;
|
||||
self.pers[ "bots" ][ "behavior" ][ "crouch" ] = 15;
|
||||
self.pers[ "bots" ][ "behavior" ][ "switch" ] = 2;
|
||||
self.pers[ "bots" ][ "behavior" ][ "jump" ] = 10;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_time" ] = 0.4;
|
||||
self.pers[ "bots" ][ "skill" ][ "init_react_time" ] = 750;
|
||||
self.pers[ "bots" ][ "skill" ][ "reaction_time" ] = 500;
|
||||
self.pers[ "bots" ][ "skill" ][ "no_trace_ads_time" ] = 1000;
|
||||
self.pers[ "bots" ][ "skill" ][ "no_trace_look_time" ] = 1500;
|
||||
self.pers[ "bots" ][ "skill" ][ "remember_time" ] = 2000;
|
||||
self.pers[ "bots" ][ "skill" ][ "fov" ] = 0.6;
|
||||
self.pers[ "bots" ][ "skill" ][ "dist_max" ] = 4000;
|
||||
self.pers[ "bots" ][ "skill" ][ "dist_start" ] = 2250;
|
||||
self.pers[ "bots" ][ "skill" ][ "spawn_time" ] = 0.5;
|
||||
self.pers[ "bots" ][ "skill" ][ "help_dist" ] = 750;
|
||||
self.pers[ "bots" ][ "skill" ][ "semi_time" ] = 0.65;
|
||||
self.pers[ "bots" ][ "skill" ][ "shoot_after_time" ] = 0.65;
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_offset_time" ] = 0.75;
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_offset_amount" ] = 2.5;
|
||||
self.pers[ "bots" ][ "skill" ][ "bone_update_interval" ] = 1;
|
||||
self.pers[ "bots" ][ "skill" ][ "bones" ] = "j_spineupper,j_spineupper,j_ankle_le,j_ankle_ri,j_head";
|
||||
self.pers[ "bots" ][ "skill" ][ "ads_fov_multi" ] = 0.5;
|
||||
self.pers[ "bots" ][ "skill" ][ "ads_aimspeed_multi" ] = 0.5;
|
||||
|
||||
self.pers[ "bots" ][ "behavior" ][ "strafe" ] = 20;
|
||||
self.pers[ "bots" ][ "behavior" ][ "nade" ] = 20;
|
||||
self.pers[ "bots" ][ "behavior" ][ "sprint" ] = 50;
|
||||
self.pers[ "bots" ][ "behavior" ][ "camp" ] = 5;
|
||||
self.pers[ "bots" ][ "behavior" ][ "follow" ] = 5;
|
||||
self.pers[ "bots" ][ "behavior" ][ "crouch" ] = 10;
|
||||
self.pers[ "bots" ][ "behavior" ][ "switch" ] = 2;
|
||||
self.pers[ "bots" ][ "behavior" ][ "jump" ] = 25;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_time" ] = 0.3;
|
||||
self.pers[ "bots" ][ "skill" ][ "init_react_time" ] = 600;
|
||||
self.pers[ "bots" ][ "skill" ][ "reaction_time" ] = 400;
|
||||
self.pers[ "bots" ][ "skill" ][ "no_trace_ads_time" ] = 1000;
|
||||
self.pers[ "bots" ][ "skill" ][ "no_trace_look_time" ] = 1500;
|
||||
self.pers[ "bots" ][ "skill" ][ "remember_time" ] = 3000;
|
||||
self.pers[ "bots" ][ "skill" ][ "fov" ] = 0.55;
|
||||
self.pers[ "bots" ][ "skill" ][ "dist_max" ] = 5000;
|
||||
self.pers[ "bots" ][ "skill" ][ "dist_start" ] = 3350;
|
||||
self.pers[ "bots" ][ "skill" ][ "spawn_time" ] = 0.35;
|
||||
self.pers[ "bots" ][ "skill" ][ "help_dist" ] = 1000;
|
||||
self.pers[ "bots" ][ "skill" ][ "semi_time" ] = 0.5;
|
||||
self.pers[ "bots" ][ "skill" ][ "shoot_after_time" ] = 0.5;
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_offset_time" ] = 0.5;
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_offset_amount" ] = 2;
|
||||
self.pers[ "bots" ][ "skill" ][ "bone_update_interval" ] = 0.75;
|
||||
self.pers[ "bots" ][ "skill" ][ "bones" ] = "j_spineupper,j_spineupper,j_ankle_le,j_ankle_ri,j_head,j_head";
|
||||
self.pers[ "bots" ][ "skill" ][ "ads_fov_multi" ] = 0.5;
|
||||
self.pers[ "bots" ][ "skill" ][ "ads_aimspeed_multi" ] = 0.5;
|
||||
|
||||
self.pers[ "bots" ][ "behavior" ][ "strafe" ] = 30;
|
||||
self.pers[ "bots" ][ "behavior" ][ "nade" ] = 25;
|
||||
self.pers[ "bots" ][ "behavior" ][ "sprint" ] = 55;
|
||||
self.pers[ "bots" ][ "behavior" ][ "camp" ] = 5;
|
||||
self.pers[ "bots" ][ "behavior" ][ "follow" ] = 5;
|
||||
self.pers[ "bots" ][ "behavior" ][ "crouch" ] = 10;
|
||||
self.pers[ "bots" ][ "behavior" ][ "switch" ] = 2;
|
||||
self.pers[ "bots" ][ "behavior" ][ "jump" ] = 35;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_time" ] = 0.25;
|
||||
self.pers[ "bots" ][ "skill" ][ "init_react_time" ] = 500;
|
||||
self.pers[ "bots" ][ "skill" ][ "reaction_time" ] = 300;
|
||||
self.pers[ "bots" ][ "skill" ][ "no_trace_ads_time" ] = 1500;
|
||||
self.pers[ "bots" ][ "skill" ][ "no_trace_look_time" ] = 2000;
|
||||
self.pers[ "bots" ][ "skill" ][ "remember_time" ] = 4000;
|
||||
self.pers[ "bots" ][ "skill" ][ "fov" ] = 0.5;
|
||||
self.pers[ "bots" ][ "skill" ][ "dist_max" ] = 7500;
|
||||
self.pers[ "bots" ][ "skill" ][ "dist_start" ] = 5000;
|
||||
self.pers[ "bots" ][ "skill" ][ "spawn_time" ] = 0.25;
|
||||
self.pers[ "bots" ][ "skill" ][ "help_dist" ] = 1500;
|
||||
self.pers[ "bots" ][ "skill" ][ "semi_time" ] = 0.4;
|
||||
self.pers[ "bots" ][ "skill" ][ "shoot_after_time" ] = 0.35;
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_offset_time" ] = 0.35;
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_offset_amount" ] = 1.5;
|
||||
self.pers[ "bots" ][ "skill" ][ "bone_update_interval" ] = 0.5;
|
||||
self.pers[ "bots" ][ "skill" ][ "bones" ] = "j_spineupper,j_head";
|
||||
self.pers[ "bots" ][ "skill" ][ "ads_fov_multi" ] = 0.5;
|
||||
self.pers[ "bots" ][ "skill" ][ "ads_aimspeed_multi" ] = 0.5;
|
||||
|
||||
self.pers[ "bots" ][ "behavior" ][ "strafe" ] = 40;
|
||||
self.pers[ "bots" ][ "behavior" ][ "nade" ] = 35;
|
||||
self.pers[ "bots" ][ "behavior" ][ "sprint" ] = 60;
|
||||
self.pers[ "bots" ][ "behavior" ][ "camp" ] = 5;
|
||||
self.pers[ "bots" ][ "behavior" ][ "follow" ] = 5;
|
||||
self.pers[ "bots" ][ "behavior" ][ "crouch" ] = 10;
|
||||
self.pers[ "bots" ][ "behavior" ][ "switch" ] = 2;
|
||||
self.pers[ "bots" ][ "behavior" ][ "jump" ] = 50;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_time" ] = 0.2;
|
||||
self.pers[ "bots" ][ "skill" ][ "init_react_time" ] = 250;
|
||||
self.pers[ "bots" ][ "skill" ][ "reaction_time" ] = 150;
|
||||
self.pers[ "bots" ][ "skill" ][ "no_trace_ads_time" ] = 2000;
|
||||
self.pers[ "bots" ][ "skill" ][ "no_trace_look_time" ] = 3000;
|
||||
self.pers[ "bots" ][ "skill" ][ "remember_time" ] = 5000;
|
||||
self.pers[ "bots" ][ "skill" ][ "fov" ] = 0.45;
|
||||
self.pers[ "bots" ][ "skill" ][ "dist_max" ] = 10000;
|
||||
self.pers[ "bots" ][ "skill" ][ "dist_start" ] = 7500;
|
||||
self.pers[ "bots" ][ "skill" ][ "spawn_time" ] = 0.2;
|
||||
self.pers[ "bots" ][ "skill" ][ "help_dist" ] = 2000;
|
||||
self.pers[ "bots" ][ "skill" ][ "semi_time" ] = 0.25;
|
||||
self.pers[ "bots" ][ "skill" ][ "shoot_after_time" ] = 0.25;
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_offset_time" ] = 0.25;
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_offset_amount" ] = 1;
|
||||
self.pers[ "bots" ][ "skill" ][ "bone_update_interval" ] = 0.25;
|
||||
self.pers[ "bots" ][ "skill" ][ "bones" ] = "j_spineupper,j_head,j_head";
|
||||
self.pers[ "bots" ][ "skill" ][ "ads_fov_multi" ] = 0.5;
|
||||
self.pers[ "bots" ][ "skill" ][ "ads_aimspeed_multi" ] = 0.5;
|
||||
|
||||
self.pers[ "bots" ][ "behavior" ][ "strafe" ] = 50;
|
||||
self.pers[ "bots" ][ "behavior" ][ "nade" ] = 45;
|
||||
self.pers[ "bots" ][ "behavior" ][ "sprint" ] = 65;
|
||||
self.pers[ "bots" ][ "behavior" ][ "camp" ] = 5;
|
||||
self.pers[ "bots" ][ "behavior" ][ "follow" ] = 5;
|
||||
self.pers[ "bots" ][ "behavior" ][ "crouch" ] = 10;
|
||||
self.pers[ "bots" ][ "behavior" ][ "switch" ] = 2;
|
||||
self.pers[ "bots" ][ "behavior" ][ "jump" ] = 75;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_time" ] = 0.1;
|
||||
self.pers[ "bots" ][ "skill" ][ "init_react_time" ] = 100;
|
||||
self.pers[ "bots" ][ "skill" ][ "reaction_time" ] = 50;
|
||||
self.pers[ "bots" ][ "skill" ][ "no_trace_ads_time" ] = 2500;
|
||||
self.pers[ "bots" ][ "skill" ][ "no_trace_look_time" ] = 4000;
|
||||
self.pers[ "bots" ][ "skill" ][ "remember_time" ] = 7500;
|
||||
self.pers[ "bots" ][ "skill" ][ "fov" ] = 0.4;
|
||||
self.pers[ "bots" ][ "skill" ][ "dist_max" ] = 15000;
|
||||
self.pers[ "bots" ][ "skill" ][ "dist_start" ] = 10000;
|
||||
self.pers[ "bots" ][ "skill" ][ "spawn_time" ] = 0.05;
|
||||
self.pers[ "bots" ][ "skill" ][ "help_dist" ] = 3000;
|
||||
self.pers[ "bots" ][ "skill" ][ "semi_time" ] = 0.1;
|
||||
self.pers[ "bots" ][ "skill" ][ "shoot_after_time" ] = 0;
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_offset_time" ] = 0;
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_offset_amount" ] = 0;
|
||||
self.pers[ "bots" ][ "skill" ][ "bone_update_interval" ] = 0.05;
|
||||
self.pers[ "bots" ][ "skill" ][ "bones" ] = "j_head";
|
||||
self.pers[ "bots" ][ "skill" ][ "ads_fov_multi" ] = 0.5;
|
||||
self.pers[ "bots" ][ "skill" ][ "ads_aimspeed_multi" ] = 0.5;
|
||||
|
||||
self.pers[ "bots" ][ "behavior" ][ "strafe" ] = 65;
|
||||
self.pers[ "bots" ][ "behavior" ][ "nade" ] = 65;
|
||||
self.pers[ "bots" ][ "behavior" ][ "sprint" ] = 70;
|
||||
self.pers[ "bots" ][ "behavior" ][ "camp" ] = 5;
|
||||
self.pers[ "bots" ][ "behavior" ][ "follow" ] = 5;
|
||||
self.pers[ "bots" ][ "behavior" ][ "crouch" ] = 5;
|
||||
self.pers[ "bots" ][ "behavior" ][ "switch" ] = 2;
|
||||
self.pers[ "bots" ][ "behavior" ][ "jump" ] = 90;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wait 5;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Sets the bot difficulty.
|
||||
*/
|
||||
set_diff()
|
||||
{
|
||||
rankVar = getdvarint( "bots_skill" );
|
||||
|
||||
switch ( rankVar )
|
||||
{
|
||||
case 0:
|
||||
self.pers[ "bots" ][ "skill" ][ "base" ] = Round( random_normal_distribution( 3.5, 1.75, 1, 7 ) );
|
||||
break;
|
||||
|
||||
case 8:
|
||||
break;
|
||||
|
||||
case 9:
|
||||
self.pers[ "bots" ][ "skill" ][ "base" ] = randomintrange( 1, 7 );
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_time" ] = 0.05 * randomintrange( 1, 20 );
|
||||
self.pers[ "bots" ][ "skill" ][ "init_react_time" ] = 50 * randomint( 100 );
|
||||
self.pers[ "bots" ][ "skill" ][ "reaction_time" ] = 50 * randomint( 100 );
|
||||
self.pers[ "bots" ][ "skill" ][ "no_trace_ads_time" ] = 50 * randomint( 100 );
|
||||
self.pers[ "bots" ][ "skill" ][ "no_trace_look_time" ] = 50 * randomint( 100 );
|
||||
self.pers[ "bots" ][ "skill" ][ "remember_time" ] = 50 * randomint( 100 );
|
||||
self.pers[ "bots" ][ "skill" ][ "fov" ] = randomfloatrange( -1, 1 );
|
||||
|
||||
randomNum = randomintrange( 500, 25000 );
|
||||
self.pers[ "bots" ][ "skill" ][ "dist_start" ] = randomNum;
|
||||
self.pers[ "bots" ][ "skill" ][ "dist_max" ] = randomNum * 2;
|
||||
|
||||
self.pers[ "bots" ][ "skill" ][ "spawn_time" ] = 0.05 * randomint( 20 );
|
||||
self.pers[ "bots" ][ "skill" ][ "help_dist" ] = randomintrange( 500, 25000 );
|
||||
self.pers[ "bots" ][ "skill" ][ "semi_time" ] = randomfloatrange( 0.05, 1 );
|
||||
self.pers[ "bots" ][ "skill" ][ "shoot_after_time" ] = randomfloatrange( 0.05, 1 );
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_offset_time" ] = randomfloatrange( 0.05, 1 );
|
||||
self.pers[ "bots" ][ "skill" ][ "aim_offset_amount" ] = randomfloatrange( 0.05, 1 );
|
||||
self.pers[ "bots" ][ "skill" ][ "bone_update_interval" ] = randomfloatrange( 0.05, 1 );
|
||||
self.pers[ "bots" ][ "skill" ][ "bones" ] = "j_head,j_spineupper,j_ankle_ri,j_ankle_le";
|
||||
|
||||
self.pers[ "bots" ][ "behavior" ][ "strafe" ] = randomint( 100 );
|
||||
self.pers[ "bots" ][ "behavior" ][ "nade" ] = randomint( 100 );
|
||||
self.pers[ "bots" ][ "behavior" ][ "sprint" ] = randomint( 100 );
|
||||
self.pers[ "bots" ][ "behavior" ][ "camp" ] = randomint( 100 );
|
||||
self.pers[ "bots" ][ "behavior" ][ "follow" ] = randomint( 100 );
|
||||
self.pers[ "bots" ][ "behavior" ][ "crouch" ] = randomint( 100 );
|
||||
self.pers[ "bots" ][ "behavior" ][ "switch" ] = randomint( 100 );
|
||||
self.pers[ "bots" ][ "behavior" ][ "jump" ] = randomint( 100 );
|
||||
break;
|
||||
|
||||
default:
|
||||
self.pers[ "bots" ][ "skill" ][ "base" ] = rankVar;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
When the bot spawned, after the difficulty wait. Start the logic for the bot.
|
||||
*/
|
||||
onBotSpawned()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
level endon( "intermission" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "bot_spawned" );
|
||||
|
||||
self thread start_bot_threads();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
When the bot spawns.
|
||||
*/
|
||||
onSpawned()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
|
||||
self thread maps\bots\objectives\_manager::spawned();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Starts all the bot thinking
|
||||
*/
|
||||
start_bot_threads()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
level endon( "intermission" );
|
||||
self endon( "zombified" );
|
||||
|
||||
self thread doReloadCancel();
|
||||
self thread bot_weapon_think();
|
||||
|
||||
self thread maps\bots\objectives\_manager::start_bot_threads();
|
||||
}
|
||||
|
||||
/*
|
||||
Changes to the weap
|
||||
*/
|
||||
changeToWeapon( weap )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
if ( !self hasweapon( weap ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
self switchtoweapon( weap );
|
||||
|
||||
if ( self getcurrentweapon() == weap )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
self waittill_any_timeout( 5, "weapon_change" );
|
||||
|
||||
return ( self getcurrentweapon() == weap );
|
||||
}
|
||||
|
||||
/*
|
||||
Reload cancels
|
||||
*/
|
||||
doReloadCancel_loop()
|
||||
{
|
||||
ret = self waittill_any_return( "reload", "weapon_change" );
|
||||
|
||||
if ( self BotIsFrozen() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( self usebuttonpressed() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( self inLastStand() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
curWeap = self getcurrentweapon();
|
||||
|
||||
if ( !self isWeaponPrimary( curWeap ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ret == "reload" )
|
||||
{
|
||||
// check single reloads
|
||||
if ( self getweaponammoclip( curWeap ) < weaponclipsize( curWeap ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// check difficulty
|
||||
if ( self.pers[ "bots" ][ "skill" ][ "base" ] <= 3 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// check if got another weapon
|
||||
weaponslist = self getweaponslistprimaries();
|
||||
weap = "";
|
||||
|
||||
while ( weaponslist.size )
|
||||
{
|
||||
weapon = weaponslist[ randomint( weaponslist.size ) ];
|
||||
weaponslist = array_remove( weaponslist, weapon );
|
||||
|
||||
if ( !self isWeaponPrimary( weapon ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( curWeap == weapon || weapon == "none" || weapon == "" )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
weap = weapon;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( weap == "" )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// do the cancel
|
||||
wait 0.1;
|
||||
self thread changeToWeapon( weap );
|
||||
wait 0.25;
|
||||
self thread changeToWeapon( curWeap );
|
||||
wait 2;
|
||||
}
|
||||
|
||||
/*
|
||||
Reload cancels
|
||||
*/
|
||||
doReloadCancel()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self doReloadCancel_loop();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Bot logic for switching weapons.
|
||||
*/
|
||||
bot_weapon_think_loop( data )
|
||||
{
|
||||
ret = self waittill_any_timeout( randomintrange( 2, 4 ), "bot_force_check_switch" );
|
||||
|
||||
if ( self BotIsFrozen() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( self inLastStand() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
hasTarget = self hasThreat();
|
||||
curWeap = self getcurrentweapon();
|
||||
|
||||
force = ( ret == "bot_force_check_switch" );
|
||||
|
||||
if ( data.first )
|
||||
{
|
||||
data.first = false;
|
||||
|
||||
if ( randomint( 100 ) > self.pers[ "bots" ][ "behavior" ][ "initswitch" ] )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( curWeap != "none" && self getammocount( curWeap ) && curWeap != "molotov" && curWeap != "molotov_zombie" )
|
||||
{
|
||||
if ( randomint( 100 ) > self.pers[ "bots" ][ "behavior" ][ "switch" ] )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( hasTarget )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
force = true;
|
||||
}
|
||||
}
|
||||
|
||||
weaponslist = self getweaponslistprimaries();
|
||||
weap = "";
|
||||
|
||||
while ( weaponslist.size )
|
||||
{
|
||||
weapon = weaponslist[ randomint( weaponslist.size ) ];
|
||||
weaponslist = array_remove( weaponslist, weapon );
|
||||
|
||||
if ( !self getammocount( weapon ) && !force )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( curWeap == weapon )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
weap = weapon;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( weap == "" )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self thread changeToWeapon( weap );
|
||||
}
|
||||
|
||||
/*
|
||||
Bot logic for switching weapons.
|
||||
*/
|
||||
bot_weapon_think()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
data = spawnstruct();
|
||||
data.first = true;
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self bot_weapon_think_loop( data );
|
||||
}
|
||||
}
|
||||
1894
maps/bots/_bot_utility.gsc
Normal file
1894
maps/bots/_bot_utility.gsc
Normal file
File diff suppressed because it is too large
Load Diff
168
maps/bots/objectives/_manager.gsc
Normal file
168
maps/bots/objectives/_manager.gsc
Normal file
@@ -0,0 +1,168 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\_utility;
|
||||
#include maps\bots\_bot_utility;
|
||||
#include maps\bots\objectives\_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level.bot_objectives = [];
|
||||
level.bot_objectives[ level.bot_objectives.size ] = CreateObjectiveForManger( "revive", maps\bots\objectives\_revive::Finder, maps\bots\objectives\_revive::Priority, maps\bots\objectives\_revive::Executer, 1000 );
|
||||
level.bot_objectives[ level.bot_objectives.size ] = CreateObjectiveForManger( "powerup", maps\bots\objectives\_powerup::Finder, maps\bots\objectives\_powerup::Priority, maps\bots\objectives\_powerup::Executer, 2500 );
|
||||
level.bot_objectives[ level.bot_objectives.size ] = CreateObjectiveForManger( "wallweapon", maps\bots\objectives\_wallweapon::Finder, maps\bots\objectives\_wallweapon::Priority, maps\bots\objectives\_wallweapon::Executer, 7500 );
|
||||
level.bot_objectives[ level.bot_objectives.size ] = CreateObjectiveForManger( "treasurechest", maps\bots\objectives\_treasurechest::Finder, maps\bots\objectives\_treasurechest::Priority, maps\bots\objectives\_treasurechest::Executer, 7000 );
|
||||
maps\bots\objectives\_perkmachine::init();
|
||||
level.bot_objectives[ level.bot_objectives.size ] = CreateObjectiveForManger( "perkmachine", maps\bots\objectives\_perkmachine::Finder, maps\bots\objectives\_perkmachine::Priority, maps\bots\objectives\_perkmachine::Executer, 10000 );
|
||||
}
|
||||
|
||||
connected()
|
||||
{
|
||||
self.bot_current_objective = undefined;
|
||||
}
|
||||
|
||||
spawned()
|
||||
{
|
||||
self.bot_current_objective = undefined;
|
||||
|
||||
self thread clean_objective_on_completion();
|
||||
self thread watch_for_objective_canceled();
|
||||
}
|
||||
|
||||
watch_for_objective_canceled()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
level endon( "intermission" );
|
||||
self endon( "zombified" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "cancel_bot_objective", reason );
|
||||
|
||||
obj_name = "undefined";
|
||||
|
||||
if ( isdefined( self.bot_current_objective ) )
|
||||
{
|
||||
obj_name = self.bot_current_objective.sname;
|
||||
}
|
||||
|
||||
self BotNotifyBotEvent( "debug", "watch_for_objective_canceled: " + obj_name + ": " + reason );
|
||||
}
|
||||
}
|
||||
|
||||
clean_objective_on_completion()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
level endon( "intermission" );
|
||||
self endon( "zombified" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "completed_bot_objective", successful, reason );
|
||||
|
||||
obj_name = "undefined";
|
||||
|
||||
if ( isdefined( self.bot_current_objective ) )
|
||||
{
|
||||
obj_name = self.bot_current_objective.sname;
|
||||
|
||||
self.bot_current_objective.eparentobj.abotprocesstimes[ self getentitynumber() + "" ] = gettime();
|
||||
}
|
||||
|
||||
self BotNotifyBotEvent( "debug", "clean_objective_on_completion: " + obj_name + ": " + successful + ": " + reason );
|
||||
|
||||
waittillframeend;
|
||||
self.bot_current_objective = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
start_bot_threads()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
level endon( "intermission" );
|
||||
self endon( "zombified" );
|
||||
|
||||
self thread bot_objective_think();
|
||||
}
|
||||
|
||||
bot_objective_think()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
level endon( "intermission" );
|
||||
self endon( "zombified" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 1;
|
||||
|
||||
// find all avail objectives
|
||||
objectives = [];
|
||||
now = gettime();
|
||||
our_key = self getentitynumber() + "";
|
||||
|
||||
for ( i = 0; i < level.bot_objectives.size; i++ )
|
||||
{
|
||||
objective = level.bot_objectives[ i ];
|
||||
|
||||
// check the process rate
|
||||
if ( isdefined( objective.abotprocesstimes[ our_key ] ) && now - objective.abotprocesstimes[ our_key ] < objective.iprocessrate )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
objectives = array_merge( objectives, self [[ objective.fpfinder ]]( objective ) );
|
||||
objective.abotprocesstimes[ our_key ] = now;
|
||||
}
|
||||
|
||||
if ( objectives.size <= 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// sort according to priority
|
||||
heap = NewHeap( ::HeapPriority );
|
||||
|
||||
for ( i = 0; i < objectives.size; i++ )
|
||||
{
|
||||
if ( objectives[ i ].fpriority <= -100 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
heap HeapInsert( objectives[ i ] );
|
||||
}
|
||||
|
||||
// pop the top!
|
||||
best_prio = heap.data[ 0 ];
|
||||
|
||||
if ( !isdefined( best_prio ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// already on a better obj
|
||||
if ( isdefined( self.bot_current_objective ) && ( best_prio.guid == self.bot_current_objective.guid || best_prio.fpriority < self [[ self.bot_current_objective.eparentobj.fppriorty ]]( self.bot_current_objective.eparentobj, self.bot_current_objective.eent ) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// DO THE OBJ
|
||||
// cancel the old obj
|
||||
if ( isdefined( self.bot_current_objective ) )
|
||||
{
|
||||
// cancel it
|
||||
self CancelObjective( "new obj: " + best_prio.sname );
|
||||
|
||||
// wait for it to clean up
|
||||
self waittill( "completed_bot_objective" );
|
||||
|
||||
// redo the loop, should do the obj next iteration
|
||||
best_prio.eparentobj.abotprocesstimes[ our_key ] = undefined;
|
||||
continue;
|
||||
}
|
||||
|
||||
// ready to execute
|
||||
self BotNotifyBotEvent( "debug", "bot_objective_think: " + best_prio.sname );
|
||||
|
||||
self.bot_current_objective = best_prio;
|
||||
self thread [[ best_prio.eparentobj.fpexecuter ]]( best_prio );
|
||||
}
|
||||
}
|
||||
287
maps/bots/objectives/_perkmachine.gsc
Normal file
287
maps/bots/objectives/_perkmachine.gsc
Normal file
@@ -0,0 +1,287 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\_utility;
|
||||
#include maps\bots\_bot_utility;
|
||||
#include maps\bots\objectives\_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
vending_triggers = getentarray( "zombie_vending", "targetname" );
|
||||
|
||||
if ( !isdefined( vending_triggers ) || vending_triggers.size < 1 )
|
||||
{
|
||||
vending_triggers = getentarray( "harrybo21_perk_trigger", "targetname" );
|
||||
|
||||
if ( !isdefined( vending_triggers ) || vending_triggers.size < 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < vending_triggers.size; i++ )
|
||||
{
|
||||
vending_triggers[ i ] thread init_vending_trigger();
|
||||
}
|
||||
}
|
||||
|
||||
init_vending_trigger()
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
if ( self.targetname == "harrybo21_perk_trigger" )
|
||||
{
|
||||
machine = self getMachine();
|
||||
|
||||
machine waittill( "activate_machine" );
|
||||
|
||||
self.bot_powered_on = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
perk = self getVendingPerk();
|
||||
notify_name = perk + "_power_on";
|
||||
|
||||
level waittill( notify_name );
|
||||
|
||||
self.bot_powered_on = true;
|
||||
}
|
||||
}
|
||||
|
||||
Finder( eObj )
|
||||
{
|
||||
answer = [];
|
||||
|
||||
if ( self inLastStand() )
|
||||
{
|
||||
return answer;
|
||||
}
|
||||
|
||||
vending_triggers = getentarray( "zombie_vending", "targetname" );
|
||||
|
||||
if ( !isdefined( vending_triggers ) || vending_triggers.size < 1 )
|
||||
{
|
||||
vending_triggers = getentarray( "harrybo21_perk_trigger", "targetname" );
|
||||
|
||||
if ( !isdefined( vending_triggers ) || vending_triggers.size < 1 )
|
||||
{
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < vending_triggers.size; i++ )
|
||||
{
|
||||
vending = vending_triggers[ i ];
|
||||
|
||||
if ( !isdefined( vending.bot_powered_on ) || !vending.bot_powered_on )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
perk = vending getVendingPerk();
|
||||
cost = vending getPerkCost();
|
||||
|
||||
if ( self.score < cost )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// perk limit??
|
||||
if ( self hasperk( perk ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
machine = vending getMachine();
|
||||
|
||||
if ( !isdefined( machine ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
org = self getOffset( machine );
|
||||
|
||||
if ( GetPathIsInaccessible( self.origin, org ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
answer[ answer.size ] = self CreateFinderObjectiveEZ( eObj, vending );
|
||||
}
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
getMachine()
|
||||
{
|
||||
return getent( self.target, "targetname" );
|
||||
}
|
||||
|
||||
getVendingPerk()
|
||||
{
|
||||
if ( self.targetname == "harrybo21_perk_trigger" )
|
||||
{
|
||||
machine = self getMachine();
|
||||
return machine.script_string;
|
||||
}
|
||||
|
||||
return self.script_noteworthy;
|
||||
}
|
||||
|
||||
getPerkCost()
|
||||
{
|
||||
if ( self.targetname == "harrybo21_perk_trigger" )
|
||||
{
|
||||
return level.zombie_perks[ self getVendingPerk() ].perk_cost;
|
||||
}
|
||||
|
||||
cost = level.zombie_vars[ "zombie_perk_cost" ];
|
||||
|
||||
switch ( self getVendingPerk() )
|
||||
{
|
||||
case "specialty_armorvest":
|
||||
cost = 2500;
|
||||
break;
|
||||
|
||||
case "specialty_quickrevive":
|
||||
cost = 1500;
|
||||
break;
|
||||
|
||||
case "specialty_fastreload":
|
||||
cost = 3000;
|
||||
break;
|
||||
|
||||
case "specialty_rof":
|
||||
cost = 2000;
|
||||
break;
|
||||
|
||||
default:
|
||||
cost = 10000;
|
||||
break;
|
||||
}
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
getOffset( model )
|
||||
{
|
||||
org = model get_angle_offset_node( 40, ( 0, -90, 0 ), ( 0, 0, 1 ) );
|
||||
|
||||
return org;
|
||||
}
|
||||
|
||||
Priority( eObj, eEnt )
|
||||
{
|
||||
// TODO rank perks
|
||||
base_priority = 2;
|
||||
base_priority += ClampLerp( get_path_dist( self.origin, eEnt.origin ), 500, 1600, 3, 0 );
|
||||
|
||||
if ( self HasBotObjective() && self GetBotObjectiveEnt() != eEnt )
|
||||
{
|
||||
base_priority -= 1;
|
||||
}
|
||||
|
||||
return base_priority;
|
||||
}
|
||||
|
||||
Executer( eObj )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
|
||||
vending = eObj.eent;
|
||||
|
||||
self thread WatchForCancel( vending );
|
||||
|
||||
self GoDoPerkMachine( eObj );
|
||||
|
||||
self WatchForCancelCleanup();
|
||||
self ClearScriptAimPos();
|
||||
self ClearScriptGoal();
|
||||
|
||||
self CompletedObjective( eObj.bwassuccessful, eObj.sreason );
|
||||
}
|
||||
|
||||
WatchForCancelCleanup()
|
||||
{
|
||||
self notify( "WatchForCancelPerkmachine" );
|
||||
}
|
||||
|
||||
WatchForCancel( vending )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
self endon( "WatchForCancelPerkmachine" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( self inLastStand() )
|
||||
{
|
||||
self CancelObjective( "self inLastStand()" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WatchToGoToMachine( vending )
|
||||
{
|
||||
self endon( "cancel_bot_objective" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
self endon( "goal" );
|
||||
self endon( "bad_path" );
|
||||
self endon( "new_goal" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( self istouching( vending ) || vending PointInsideUseTrigger( self.origin ) )
|
||||
{
|
||||
self notify( "goal" );
|
||||
break; // is this needed?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GoDoPerkMachine( eObj )
|
||||
{
|
||||
self endon( "cancel_bot_objective" );
|
||||
|
||||
vending = eObj.eent;
|
||||
machine = vending getMachine();
|
||||
perk = vending getVendingPerk();
|
||||
org = self getOffset( machine );
|
||||
|
||||
// go to machine
|
||||
self thread WatchToGoToMachine( vending );
|
||||
self SetScriptGoal( org, 32 );
|
||||
|
||||
result = self waittill_any_return( "goal", "bad_path", "new_goal" );
|
||||
|
||||
if ( result != "goal" )
|
||||
{
|
||||
eObj.sreason = "didn't go to machine";
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !self istouching( vending ) && !vending PointInsideUseTrigger( self.origin ) )
|
||||
{
|
||||
eObj.sreason = "not touching machine";
|
||||
return;
|
||||
}
|
||||
|
||||
// ok we are touching machine, lets look at it
|
||||
self SetScriptAimPos( vending.origin );
|
||||
|
||||
// wait to look at it
|
||||
wait 1;
|
||||
|
||||
// press use
|
||||
self thread BotPressUse( 0.15 );
|
||||
wait 0.1;
|
||||
|
||||
// ok we pressed use, DONE
|
||||
eObj.sreason = "completed " + perk;
|
||||
eObj.bwassuccessful = true;
|
||||
}
|
||||
142
maps/bots/objectives/_powerup.gsc
Normal file
142
maps/bots/objectives/_powerup.gsc
Normal file
@@ -0,0 +1,142 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\_utility;
|
||||
#include maps\bots\_bot_utility;
|
||||
#include maps\bots\objectives\_utility;
|
||||
|
||||
Finder( eObj )
|
||||
{
|
||||
answer = [];
|
||||
|
||||
if ( self inLastStand() )
|
||||
{
|
||||
return answer;
|
||||
}
|
||||
|
||||
ents = getentarray( "script_model", "classname" );
|
||||
|
||||
for ( i = 0; i < ents.size; i++ )
|
||||
{
|
||||
// not a powerup script_model
|
||||
if ( !isdefined( ents[ i ].powerup_name ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// can we path to it?
|
||||
if ( GetPathIsInaccessible( self.origin, ents[ i ].origin ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// make sure we are the only one going for it
|
||||
if ( self GetBotsAmountForEntity( ents[ i ] ) >= 1 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
answer[ answer.size ] = self CreateFinderObjectiveEZ( eObj, ents[ i ] );
|
||||
}
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
Priority( eObj, eEnt )
|
||||
{
|
||||
// TODO: check powerup type
|
||||
base_priority = 0;
|
||||
base_priority += ClampLerp( get_path_dist( self.origin, eEnt.origin ), 300, 700, 2, -2 );
|
||||
|
||||
if ( self HasBotObjective() && self GetBotObjectiveEnt() != eEnt )
|
||||
{
|
||||
base_priority -= 1;
|
||||
}
|
||||
|
||||
return base_priority;
|
||||
}
|
||||
|
||||
Executer( eObj )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
|
||||
powerup = eObj.eent;
|
||||
org = powerup.origin;
|
||||
|
||||
self thread IncrementBotsForEntity( powerup );
|
||||
self thread WatchForCancel( powerup );
|
||||
|
||||
self GoDoPowerup( eObj );
|
||||
|
||||
self WatchForCancelCleanup();
|
||||
self DecrementBotsForEntity( powerup );
|
||||
self ClearScriptGoal();
|
||||
|
||||
if ( distance( org, self.origin ) <= 64 )
|
||||
{
|
||||
eObj.sreason = "completed";
|
||||
eObj.bwassuccessful = true;
|
||||
}
|
||||
|
||||
self CompletedObjective( eObj.bwassuccessful, eObj.sreason );
|
||||
}
|
||||
|
||||
WatchForCancelCleanup()
|
||||
{
|
||||
self notify( "WatchForCancelPowerup" );
|
||||
}
|
||||
|
||||
WatchForCancel( powerup )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
self endon( "WatchForCancelPowerup" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( self inLastStand() )
|
||||
{
|
||||
self CancelObjective( "self inLastStand()" );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !isdefined( powerup ) )
|
||||
{
|
||||
self CancelObjective( "!isdefined( powerup )" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GoDoPowerup( eObj )
|
||||
{
|
||||
self endon( "cancel_bot_objective" );
|
||||
|
||||
powerup = eObj.eent;
|
||||
|
||||
// go to it
|
||||
self SetScriptGoal( powerup.origin, 32 );
|
||||
|
||||
result = self waittill_any_return( "goal", "bad_path", "new_goal" );
|
||||
|
||||
if ( result != "goal" )
|
||||
{
|
||||
eObj.sreason = "didn't go to powerup";
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !isdefined( powerup ) || !isdefined( powerup.origin ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( distance( powerup.origin, self.origin ) > 64 )
|
||||
{
|
||||
eObj.sreason = "not touching it";
|
||||
return;
|
||||
}
|
||||
|
||||
eObj.sreason = "completed";
|
||||
eObj.bwassuccessful = true;
|
||||
}
|
||||
209
maps/bots/objectives/_revive.gsc
Normal file
209
maps/bots/objectives/_revive.gsc
Normal file
@@ -0,0 +1,209 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\_utility;
|
||||
#include maps\bots\_bot_utility;
|
||||
#include maps\bots\objectives\_utility;
|
||||
|
||||
Finder( eObj )
|
||||
{
|
||||
Players = get_players();
|
||||
Answer = [];
|
||||
|
||||
if ( self inLastStand() )
|
||||
{
|
||||
return Answer;
|
||||
}
|
||||
|
||||
for ( i = 0; i < Players.size; i++ )
|
||||
{
|
||||
Player = Players[ i ];
|
||||
|
||||
if ( !isdefined( Player ) || !isdefined( Player.team ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( Player == self )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( Player.sessionstate != "playing" )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !Player inLastStand() || Player.revivetrigger.beingrevived )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( GetPathIsInaccessible( self.origin, Player.origin ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( self GetBotsAmountForEntity( Player ) >= 1 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Answer[ Answer.size ] = self CreateFinderObjectiveEZ( eObj, Player );
|
||||
}
|
||||
|
||||
return Answer;
|
||||
}
|
||||
|
||||
Priority( eObj, eEnt )
|
||||
{
|
||||
base_priority = 3;
|
||||
base_priority += ClampLerp( get_path_dist( self.origin, eEnt.origin ), 500, 1200, 2, 0 );
|
||||
|
||||
if ( self HasBotObjective() && self GetBotObjectiveEnt() != eEnt )
|
||||
{
|
||||
base_priority -= 1;
|
||||
}
|
||||
|
||||
return base_priority;
|
||||
}
|
||||
|
||||
Executer( eObj )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
|
||||
revivee = eObj.eent;
|
||||
|
||||
self thread IncrementBotsForEntity( revivee );
|
||||
self thread WatchForCancelRevive( revivee );
|
||||
|
||||
self GoDoRevive( eObj );
|
||||
|
||||
self WatchForCancelReviveCleanup();
|
||||
self DecrementBotsForEntity( revivee );
|
||||
self ClearScriptAimPos();
|
||||
self ClearScriptGoal();
|
||||
self ClearPriorityObjective();
|
||||
|
||||
self CompletedObjective( eObj.bwassuccessful, eObj.sreason );
|
||||
}
|
||||
|
||||
WatchForCancelReviveCleanup()
|
||||
{
|
||||
self notify( "WatchForCancelRevive" );
|
||||
}
|
||||
|
||||
WatchForCancelRevive( revivee )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
self endon( "WatchForCancelRevive" );
|
||||
|
||||
org = revivee.origin;
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( self inLastStand() )
|
||||
{
|
||||
self CancelObjective( "self inLastStand()" );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !isdefined( revivee ) || !revivee inLastStand() )
|
||||
{
|
||||
self CancelObjective( "!isdefined( revivee ) || !revivee inLastStand()" );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( revivee.revivetrigger.beingrevived && !self isReviving( revivee ) )
|
||||
{
|
||||
self CancelObjective( "revivee.revivetrigger.beingrevived && !self isReviving( revivee )" );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( distance( revivee.origin, org ) > 16 )
|
||||
{
|
||||
self CancelObjective( "distance( revivee.origin, org ) > 16" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WatchToGoToGuy( revivee )
|
||||
{
|
||||
self endon( "cancel_bot_objective" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
self endon( "goal" );
|
||||
self endon( "bad_path" );
|
||||
self endon( "new_goal" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 1;
|
||||
|
||||
if ( self istouching( revivee.revivetrigger ) )
|
||||
{
|
||||
self notify( "goal" );
|
||||
break; // is this needed?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WatchForSuccessRevive( eObj )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
|
||||
revivee = eObj.eent;
|
||||
|
||||
ret = self waittill_either_return( "cancel_bot_objective", "completed_bot_objective" );
|
||||
|
||||
if ( ret == "cancel_bot_objective" && isdefined( revivee ) && !revivee inLastStand() )
|
||||
{
|
||||
eObj.bwassuccessful = true;
|
||||
eObj.sreason = "revived him!";
|
||||
}
|
||||
}
|
||||
|
||||
GoDoRevive( eObj )
|
||||
{
|
||||
self endon( "cancel_bot_objective" );
|
||||
|
||||
revivee = eObj.eent;
|
||||
|
||||
// go to guy
|
||||
self thread WatchToGoToGuy( revivee );
|
||||
self SetPriorityObjective();
|
||||
self SetScriptGoal( revivee.origin, 32 );
|
||||
|
||||
result = self waittill_any_return( "goal", "bad_path", "new_goal" );
|
||||
|
||||
if ( result != "goal" )
|
||||
{
|
||||
eObj.sreason = "didn't go to guy";
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !self istouching( revivee.revivetrigger ) )
|
||||
{
|
||||
eObj.sreason = "not touching guy";
|
||||
return;
|
||||
}
|
||||
|
||||
// ok we are touching guy, lets look at him
|
||||
self SetScriptAimPos( revivee.origin );
|
||||
|
||||
// now lets hold use until he is up or otherwise
|
||||
self thread WatchForSuccessRevive( eObj );
|
||||
|
||||
while ( self istouching( revivee.revivetrigger ) )
|
||||
{
|
||||
self thread BotPressUse( 0.15 );
|
||||
|
||||
wait 0.1;
|
||||
}
|
||||
|
||||
eObj.sreason = "not touching guy";
|
||||
}
|
||||
284
maps/bots/objectives/_treasurechest.gsc
Normal file
284
maps/bots/objectives/_treasurechest.gsc
Normal file
@@ -0,0 +1,284 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\_utility;
|
||||
#include maps\bots\_bot_utility;
|
||||
#include maps\bots\objectives\_utility;
|
||||
|
||||
Finder( eObj )
|
||||
{
|
||||
answer = [];
|
||||
|
||||
if ( self inLastStand() )
|
||||
{
|
||||
return answer;
|
||||
}
|
||||
|
||||
weapons = self getweaponslist();
|
||||
|
||||
// TODO check if need a new weapon, rate weapons too is better then current etc
|
||||
chests = level.chests;
|
||||
|
||||
if ( !isdefined( chests ) )
|
||||
{
|
||||
chests = getentarray( "treasure_chest_use", "targetname" );
|
||||
}
|
||||
|
||||
if ( !isdefined( chests ) || chests.size <= 0 )
|
||||
{
|
||||
return answer;
|
||||
}
|
||||
|
||||
for ( i = 0; i < chests.size; i ++ )
|
||||
{
|
||||
chest = chests[ i ];
|
||||
|
||||
// not active chest
|
||||
if ( isdefined( chest.disabled ) && chest.disabled )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// box is waiting for someone to grab weapon
|
||||
if ( isdefined( chest.grab_weapon_hint ) && chest.grab_weapon_hint )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
cost = 950;
|
||||
|
||||
if ( isdefined( level.zombie_treasure_chest_cost ) )
|
||||
{
|
||||
cost = level.zombie_treasure_chest_cost;
|
||||
}
|
||||
else if ( isdefined( chest.zombie_cost ) )
|
||||
{
|
||||
cost = chest.zombie_cost;
|
||||
}
|
||||
|
||||
// check cost
|
||||
if ( self.score < cost )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
lid = getent( chest.target, "targetname" );
|
||||
|
||||
if ( !isdefined( lid ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
weapon_spawn_org = getent( lid.target, "targetname" );
|
||||
|
||||
if ( !isdefined( weapon_spawn_org ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
org = self getOffset( lid );
|
||||
|
||||
if ( GetPathIsInaccessible( self.origin, org ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
answer[ answer.size ] = self CreateFinderObjectiveEZ( eObj, chest );
|
||||
}
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
getOffset( model )
|
||||
{
|
||||
org = model get_angle_offset_node( 52, ( 0, 90, 0 ), ( 0, 0, 1 ) );
|
||||
|
||||
return org;
|
||||
}
|
||||
|
||||
Priority( eObj, eEnt )
|
||||
{
|
||||
base_priority = 1;
|
||||
base_priority += ClampLerp( get_path_dist( self.origin, eEnt.origin ), 600, 1800, 2, 0 );
|
||||
|
||||
if ( self HasBotObjective() && self GetBotObjectiveEnt() != eEnt )
|
||||
{
|
||||
base_priority -= 1;
|
||||
}
|
||||
|
||||
return base_priority;
|
||||
}
|
||||
|
||||
Executer( eObj )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
|
||||
chest = eObj.eent;
|
||||
|
||||
self thread WatchForCancel( chest );
|
||||
|
||||
self GoDoTreasureChest( eObj );
|
||||
|
||||
self WatchForCancelCleanup();
|
||||
self ClearScriptAimPos();
|
||||
self ClearScriptGoal();
|
||||
self ClearPriorityObjective();
|
||||
|
||||
self CompletedObjective( eObj.bwassuccessful, eObj.sreason );
|
||||
}
|
||||
|
||||
WatchForCancelCleanup()
|
||||
{
|
||||
self notify( "WatchForCancelTreasurechest" );
|
||||
}
|
||||
|
||||
WatchForCancel( chest )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
self endon( "WatchForCancelTreasurechest" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( self inLastStand() )
|
||||
{
|
||||
self CancelObjective( "self inLastStand()" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WatchToGoToChest( chest )
|
||||
{
|
||||
self endon( "cancel_bot_objective" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
self endon( "goal" );
|
||||
self endon( "bad_path" );
|
||||
self endon( "new_goal" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( self istouching( chest ) || chest PointInsideUseTrigger( self.origin ) )
|
||||
{
|
||||
self notify( "goal" );
|
||||
break; // is this needed?
|
||||
}
|
||||
|
||||
if ( isdefined( chest.disabled ) && chest.disabled )
|
||||
{
|
||||
self notify( "bad_path" );
|
||||
break; // is this needed?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GoDoTreasureChest( eObj )
|
||||
{
|
||||
self endon( "cancel_bot_objective" );
|
||||
|
||||
chest = eObj.eent;
|
||||
lid = getent( chest.target, "targetname" );
|
||||
weapon_spawn_org = getent( lid.target, "targetname" );
|
||||
org = self getOffset( lid );
|
||||
|
||||
weap = self getcurrentweapon();
|
||||
|
||||
if ( weap == "none" || !self getammocount( weap ) )
|
||||
{
|
||||
self SetPriorityObjective();
|
||||
}
|
||||
|
||||
// go to box
|
||||
self thread WatchToGoToChest( chest );
|
||||
self SetScriptGoal( org, 32 );
|
||||
|
||||
result = self waittill_any_return( "goal", "bad_path", "new_goal" );
|
||||
|
||||
if ( result != "goal" )
|
||||
{
|
||||
eObj.sreason = "didn't go to chest";
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !self istouching( chest ) && !chest PointInsideUseTrigger( self.origin ) )
|
||||
{
|
||||
eObj.sreason = "not touching chest";
|
||||
return;
|
||||
}
|
||||
|
||||
// ok we are touching weapon, lets look at it
|
||||
self SetScriptAimPos( chest.origin );
|
||||
|
||||
// wait to look at it
|
||||
wait 1;
|
||||
|
||||
// press use
|
||||
self thread BotPressUse( 0.15 );
|
||||
wait 0.25;
|
||||
|
||||
// ok we pressed use, wait for randomization to complete
|
||||
self ClearScriptAimPos();
|
||||
self ClearPriorityObjective();
|
||||
|
||||
// randomization isnt happening...
|
||||
if ( !isdefined( chest.disabled ) || !chest.disabled )
|
||||
{
|
||||
eObj.sreason = "chest isnt randomizing";
|
||||
return;
|
||||
}
|
||||
|
||||
ret = weapon_spawn_org waittill_any_timeout( 5, "randomization_done" );
|
||||
|
||||
if ( ret == "timeout" )
|
||||
{
|
||||
eObj.sreason = "randomization_done timed out";
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isdefined( level.flag[ "moving_chest_now" ] ) && flag( "moving_chest_now" ) )
|
||||
{
|
||||
eObj.sreason = "chest is moving!";
|
||||
return;
|
||||
}
|
||||
|
||||
waittillframeend;
|
||||
weap = weapon_spawn_org.weapon_string;
|
||||
// weapon is done cooking, grabit!
|
||||
self SetPriorityObjective();
|
||||
|
||||
// go to box
|
||||
self thread WatchToGoToChest( chest );
|
||||
self SetScriptGoal( org, 32 );
|
||||
|
||||
result = self waittill_any_return( "goal", "bad_path", "new_goal" );
|
||||
|
||||
if ( result != "goal" )
|
||||
{
|
||||
eObj.sreason = "didn't go to chest";
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !self istouching( chest ) && !chest PointInsideUseTrigger( self.origin ) )
|
||||
{
|
||||
eObj.sreason = "not touching chest";
|
||||
return;
|
||||
}
|
||||
|
||||
// ok we are touching weapon, lets look at it
|
||||
self SetScriptAimPos( chest.origin );
|
||||
|
||||
// wait to look at it
|
||||
wait 1;
|
||||
|
||||
// press use
|
||||
self thread BotPressUse( 0.15 );
|
||||
wait 0.1;
|
||||
|
||||
// complete!
|
||||
eObj.sreason = "completed " + weap;
|
||||
eObj.bwassuccessful = true;
|
||||
}
|
||||
114
maps/bots/objectives/_utility.gsc
Normal file
114
maps/bots/objectives/_utility.gsc
Normal file
@@ -0,0 +1,114 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\_utility;
|
||||
#include maps\bots\_bot_utility;
|
||||
|
||||
CreateObjectiveForManger( sName, fpFinder, fpPriorty, fpExecuter, iProcessRate )
|
||||
{
|
||||
Answer = spawnstruct();
|
||||
|
||||
Answer.sname = sName;
|
||||
Answer.fpfinder = fpFinder;
|
||||
Answer.fpexecuter = fpExecuter;
|
||||
Answer.fppriorty = fpPriorty;
|
||||
|
||||
Answer.abotprocesstimes = [];
|
||||
Answer.iprocessrate = iProcessRate;
|
||||
|
||||
return Answer;
|
||||
}
|
||||
|
||||
CreateFinderObjectiveEZ( eObj, eEnt )
|
||||
{
|
||||
return self CreateFinderObjective( eObj, eObj.sname + "_" + eEnt getentitynumber(), eEnt, self [[ eObj.fppriorty ]]( eObj, eEnt ) );
|
||||
}
|
||||
|
||||
CreateFinderObjective( eObj, sName, eEnt, fPriority )
|
||||
{
|
||||
Answer = spawnstruct();
|
||||
|
||||
Answer.eparentobj = eObj;
|
||||
Answer.sname = sName;
|
||||
Answer.eent = eEnt;
|
||||
Answer.fpriority = fPriority;
|
||||
Answer.guid = eEnt getentitynumber();
|
||||
|
||||
Answer.bwassuccessful = false;
|
||||
Answer.sreason = "canceled";
|
||||
|
||||
return Answer;
|
||||
}
|
||||
|
||||
GetBotsAmountForEntity( eEnt )
|
||||
{
|
||||
if ( !isdefined( eEnt.bots ) )
|
||||
{
|
||||
eEnt.bots = 0;
|
||||
}
|
||||
|
||||
return eEnt.bots;
|
||||
}
|
||||
|
||||
IncrementBotsForEntity( eEnt )
|
||||
{
|
||||
self endon( "bots_for_entity_cleanup" );
|
||||
|
||||
eEnt.bots++;
|
||||
|
||||
self waittill_either( "disconnect", "zombified" );
|
||||
|
||||
if ( isdefined( eEnt ) )
|
||||
{
|
||||
eEnt.bots--;
|
||||
}
|
||||
}
|
||||
|
||||
DecrementBotsForEntity( eEnt )
|
||||
{
|
||||
self notify( "bots_for_entity_cleanup" );
|
||||
|
||||
if ( isdefined( eEnt ) )
|
||||
{
|
||||
eEnt.bots--;
|
||||
}
|
||||
}
|
||||
|
||||
CleanupBotsForEntity( eEnt )
|
||||
{
|
||||
self notify( "bots_for_entity_cleanup" );
|
||||
}
|
||||
|
||||
CancelObjective( reason )
|
||||
{
|
||||
self notify( "cancel_bot_objective", reason );
|
||||
}
|
||||
|
||||
CompletedObjective( successful, reason )
|
||||
{
|
||||
self notify( "completed_bot_objective", successful, reason );
|
||||
}
|
||||
|
||||
GetBotObjectiveEnt()
|
||||
{
|
||||
if ( !self HasBotObjective() )
|
||||
{
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return self GetBotObjective().eent;
|
||||
}
|
||||
|
||||
/*
|
||||
Gets bot objective
|
||||
*/
|
||||
GetBotObjective()
|
||||
{
|
||||
return self.bot_current_objective;
|
||||
}
|
||||
|
||||
/*
|
||||
Does the bot have an objective?
|
||||
*/
|
||||
HasBotObjective()
|
||||
{
|
||||
return isdefined( self GetBotObjective() );
|
||||
}
|
||||
239
maps/bots/objectives/_wallweapon.gsc
Normal file
239
maps/bots/objectives/_wallweapon.gsc
Normal file
@@ -0,0 +1,239 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\_utility;
|
||||
#include maps\bots\_bot_utility;
|
||||
#include maps\bots\objectives\_utility;
|
||||
|
||||
Finder( eObj )
|
||||
{
|
||||
answer = [];
|
||||
|
||||
if ( self inLastStand() )
|
||||
{
|
||||
return answer;
|
||||
}
|
||||
|
||||
weapon_spawns = getentarray( "weapon_upgrade", "targetname" );
|
||||
|
||||
if ( !isdefined( weapon_spawns ) || weapon_spawns.size <= 0 )
|
||||
{
|
||||
return answer;
|
||||
}
|
||||
|
||||
weapons = self getweaponslist();
|
||||
|
||||
// TODO check if need a new weapon, rate weapons too is better then current etc
|
||||
|
||||
for ( i = 0; i < weapon_spawns.size; i++ )
|
||||
{
|
||||
player_has_weapon = false;
|
||||
|
||||
if ( !isdefined( weapon_spawns[ i ].zombie_weapon_upgrade ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( h = 0; h < weapons.size; h++ )
|
||||
{
|
||||
if ( weapons[ h ] == weapon_spawns[ i ].zombie_weapon_upgrade )
|
||||
{
|
||||
player_has_weapon = true;
|
||||
}
|
||||
}
|
||||
|
||||
is_grenade = ( weapontype( weapon_spawns[ i ].zombie_weapon_upgrade ) == "grenade" );
|
||||
|
||||
if ( !player_has_weapon || is_grenade )
|
||||
{
|
||||
//func = BotBuiltinGetFunction( "maps/_zombiemode_weapons", "get_weapon_cost" );
|
||||
func = ::get_weapon_cost;
|
||||
|
||||
if ( self.score < [[ func ]]( weapon_spawns[ i ].zombie_weapon_upgrade ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//func = BotBuiltinGetFunction( "maps/_zombiemode_weapons", "get_ammo_cost" );
|
||||
func = ::get_ammo_cost;
|
||||
|
||||
if ( self.score < [[ func ]]( weapon_spawns[ i ].zombie_weapon_upgrade ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
model = weapon_spawns[ i ];
|
||||
|
||||
if ( isdefined( weapon_spawns[ i ].target ) )
|
||||
{
|
||||
model = getent( weapon_spawns[ i ].target, "targetname" );
|
||||
}
|
||||
|
||||
if ( !isdefined( model ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
org = self getOffset( model, weapon_spawns[ i ] );
|
||||
|
||||
if ( GetPathIsInaccessible( self.origin, org ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
answer[ answer.size ] = self CreateFinderObjectiveEZ( eObj, weapon_spawns[ i ] );
|
||||
}
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
getOffset( model, weapon )
|
||||
{
|
||||
org = model get_angle_offset_node( 40, ( 0, -90, 0 ), ( 0, 0, 1 ) );
|
||||
|
||||
test_org = ( org[ 0 ], org[ 1 ], weapon.origin[ 2 ] );
|
||||
|
||||
if ( !weapon PointInsideUseTrigger( test_org ) )
|
||||
{
|
||||
org = model get_angle_offset_node( 40, ( 0, 90, 0 ), ( 0, 0, 1 ) );
|
||||
}
|
||||
|
||||
return org;
|
||||
}
|
||||
|
||||
Priority( eObj, eEnt )
|
||||
{
|
||||
// TODO: check weallweapon type
|
||||
|
||||
base_priority = 0;
|
||||
base_priority += ClampLerp( get_path_dist( self.origin, eEnt.origin ), 0, 800, 1, -2 );
|
||||
|
||||
if ( self HasBotObjective() && self GetBotObjectiveEnt() != eEnt )
|
||||
{
|
||||
base_priority -= 1;
|
||||
}
|
||||
|
||||
if ( issubstr( eEnt.zombie_weapon_upgrade, "kar98k" ) || issubstr( eEnt.zombie_weapon_upgrade, "type99" ) )
|
||||
{
|
||||
base_priority -= 999;
|
||||
}
|
||||
|
||||
return base_priority;
|
||||
}
|
||||
|
||||
Executer( eObj )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
|
||||
weapon = eObj.eent;
|
||||
|
||||
self thread WatchForCancel( weapon );
|
||||
|
||||
self GoDoWallweapon( eObj );
|
||||
|
||||
self WatchForCancelCleanup();
|
||||
self ClearScriptAimPos();
|
||||
self ClearScriptGoal();
|
||||
self ClearPriorityObjective();
|
||||
|
||||
self CompletedObjective( eObj.bwassuccessful, eObj.sreason );
|
||||
}
|
||||
|
||||
WatchForCancelCleanup()
|
||||
{
|
||||
self notify( "WatchForCancelWallweapon" );
|
||||
}
|
||||
|
||||
WatchForCancel( weapon )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
self endon( "WatchForCancelWallweapon" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( self inLastStand() )
|
||||
{
|
||||
self CancelObjective( "self inLastStand()" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WatchToGoToWeapon( weapon )
|
||||
{
|
||||
self endon( "cancel_bot_objective" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "zombified" );
|
||||
self endon( "goal" );
|
||||
self endon( "bad_path" );
|
||||
self endon( "new_goal" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( self istouching( weapon ) || weapon PointInsideUseTrigger( self.origin ) )
|
||||
{
|
||||
self notify( "goal" );
|
||||
break; // is this needed?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GoDoWallweapon( eObj )
|
||||
{
|
||||
self endon( "cancel_bot_objective" );
|
||||
|
||||
weapon = eObj.eent;
|
||||
model = weapon;
|
||||
|
||||
if ( isdefined( weapon.target ) )
|
||||
{
|
||||
model = getent( weapon.target, "targetname" );
|
||||
}
|
||||
|
||||
org = self getOffset( model, weapon );
|
||||
|
||||
weap = self getcurrentweapon();
|
||||
|
||||
if ( weap == "none" || !self getammocount( weap ) )
|
||||
{
|
||||
self SetPriorityObjective();
|
||||
}
|
||||
|
||||
// go to weapon
|
||||
self thread WatchToGoToWeapon( weapon );
|
||||
self SetScriptGoal( org, 32 );
|
||||
|
||||
result = self waittill_any_return( "goal", "bad_path", "new_goal" );
|
||||
|
||||
if ( result != "goal" )
|
||||
{
|
||||
eObj.sreason = "didn't go to weapon";
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !self istouching( weapon ) && !weapon PointInsideUseTrigger( self.origin ) )
|
||||
{
|
||||
eObj.sreason = "not touching weapon";
|
||||
return;
|
||||
}
|
||||
|
||||
// ok we are touching weapon, lets look at it
|
||||
self SetScriptAimPos( weapon.origin );
|
||||
|
||||
// wait to look at it
|
||||
wait 1;
|
||||
|
||||
// press use
|
||||
self thread BotPressUse( 0.15 );
|
||||
wait 0.1;
|
||||
|
||||
eObj.sreason = "completed";
|
||||
eObj.bwassuccessful = true;
|
||||
}
|
||||
415
maps/pluto/zm_spawn_fix.gsc
Normal file
415
maps/pluto/zm_spawn_fix.gsc
Normal file
@@ -0,0 +1,415 @@
|
||||
#include maps\_utility;
|
||||
#include common_scripts\utility;
|
||||
|
||||
#include maps\bots\_bot_utility;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( GetDvarInt( "scr_disableHotJoinFixes" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
level.endGameInCommonZombiemode = [];
|
||||
level.endGameInCommonZombiemode["nazi_zombie_sumpf"] = true;
|
||||
}
|
||||
|
||||
init()
|
||||
{
|
||||
if ( GetDvarInt( "scr_disableHotJoinFixes" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// do prints, handle hotjoining and leavers
|
||||
level thread onPlayerConnect();
|
||||
|
||||
if ( !isDefined( level.script ) )
|
||||
{
|
||||
level.script = Tolower( GetDvar( "mapname" ) );
|
||||
}
|
||||
|
||||
// setup hot joining
|
||||
level.oldSpawnClient = level.spawnClient;
|
||||
wait 0.05; // vm decomp bug? required for override to work...
|
||||
level.spawnClient = ::spawnClientOverride;
|
||||
|
||||
if ( !isDefined( level.hotJoinPlayer ) )
|
||||
{
|
||||
level.hotJoinPlayer = ::hotJoin;
|
||||
}
|
||||
|
||||
// setup how endgame
|
||||
// if ( !isDefined( level.endGameFunc ) )
|
||||
// {
|
||||
// if ( level.script == "nazi_zombie_prototype" )
|
||||
// {
|
||||
// level.endGameFunc = ::endGamePrototype;
|
||||
// }
|
||||
// else if ( level.script == "nazi_zombie_asylum" )
|
||||
// {
|
||||
// level.endGameFunc = ::endGameAsylum;
|
||||
// }
|
||||
// else if ( isDefined( level.endGameInCommonZombiemode[level.script] ) )
|
||||
// {
|
||||
// level.endGameFunc = ::endGameCommonZombiemodeScript;
|
||||
// }
|
||||
// else if ( isZombieMode() )
|
||||
// {
|
||||
// level.endGameFunc = ::endGameNotify;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// level.endGameFunc = ::endGameSP;
|
||||
// }
|
||||
// }
|
||||
|
||||
if ( !isDefined( level.isPlayerDead ) )
|
||||
{
|
||||
level.isPlayerDead = ::checkIsPlayerDead;
|
||||
}
|
||||
|
||||
// make dead players into spectators
|
||||
// if ( isZombieMode() )
|
||||
// {
|
||||
// level.oldOverridePlayerKilled = level.overridePlayerKilled;
|
||||
// level.overridePlayerKilled = ::playerKilledOverride;
|
||||
|
||||
// // setup this callback
|
||||
// zmb_spawnSpectator = GetFunction( "maps/_callbackglobal", "spawnspectator" );
|
||||
|
||||
// if ( isDefined( zmb_spawnSpectator ) && level.spawnSpectator == zmb_spawnSpectator )
|
||||
// {
|
||||
// if ( level.script == "nazi_zombie_prototype" )
|
||||
// {
|
||||
// zmb_spawnSpectator = GetFunction( "maps/_zombiemode_prototype", "spawnspectator" );
|
||||
|
||||
// if ( isDefined( zmb_spawnSpectator ) )
|
||||
// {
|
||||
// level.spawnSpectator = zmb_spawnSpectator;
|
||||
// }
|
||||
// }
|
||||
// else if ( level.script == "nazi_zombie_asylum" )
|
||||
// {
|
||||
// zmb_spawnSpectator = GetFunction( "maps/_zombiemode_asylum", "spawnspectator" );
|
||||
|
||||
// if ( isDefined( zmb_spawnSpectator ) )
|
||||
// {
|
||||
// level.spawnSpectator = zmb_spawnSpectator;
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// zmb_spawnSpectator = GetFunction( "maps/_zombiemode", "spawnspectator" );
|
||||
|
||||
// if ( isDefined( zmb_spawnSpectator ) )
|
||||
// {
|
||||
// level.spawnSpectator = zmb_spawnSpectator;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
isZombieMode()
|
||||
{
|
||||
return ( isDefined( level.is_zombie_level ) && level.is_zombie_level );
|
||||
}
|
||||
|
||||
// endGamePrototype()
|
||||
// {
|
||||
// func = getFunction( "maps/_zombiemode_prototype", "end_game" );
|
||||
|
||||
// if ( isDefined( func ) )
|
||||
// {
|
||||
// level thread [[func]]();
|
||||
// }
|
||||
// }
|
||||
|
||||
// endGameAsylum()
|
||||
// {
|
||||
// func = getFunction( "maps/_zombiemode_asylum", "end_game" );
|
||||
|
||||
// if ( isDefined( func ) )
|
||||
// {
|
||||
// level thread [[func]]();
|
||||
// }
|
||||
// }
|
||||
|
||||
// endGameCommonZombiemodeScript()
|
||||
// {
|
||||
// func = getFunction( "maps/_zombiemode", "end_game" );
|
||||
|
||||
// if ( isDefined( func ) )
|
||||
// {
|
||||
// level thread [[func]]();
|
||||
// }
|
||||
// }
|
||||
|
||||
endGameNotify()
|
||||
{
|
||||
level notify( "end_game" );
|
||||
}
|
||||
|
||||
endGameSP()
|
||||
{
|
||||
missionfailed();
|
||||
}
|
||||
|
||||
checkIsPlayerDead( player )
|
||||
{
|
||||
in_laststand_func = ::player_is_in_laststand;
|
||||
|
||||
return ( player.sessionstate == "spectator" || ( isDefined( in_laststand_func ) && player [[in_laststand_func]]() ) || ( isDefined( player.is_zombie ) && player.is_zombie ) );
|
||||
}
|
||||
|
||||
playerKilledOverride()
|
||||
{
|
||||
self [[level.player_becomes_zombie]]();
|
||||
checkForAllDead( self );
|
||||
self [[level.oldOverridePlayerKilled]]();
|
||||
}
|
||||
|
||||
spawnClientOverride()
|
||||
{
|
||||
if ( flag( "all_players_spawned" ) )
|
||||
{
|
||||
self thread [[level.hotJoinPlayer]]();
|
||||
}
|
||||
else
|
||||
{
|
||||
self thread [[level.oldSpawnClient]]();
|
||||
}
|
||||
}
|
||||
|
||||
getHotJoinPlayer()
|
||||
{
|
||||
players = get_players();
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
player = players[i];
|
||||
|
||||
if ( !isDefined( player ) || !isDefined( player.sessionstate ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( player == self )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( player.sessionstate == "spectator" )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isDefined( player.is_zombie ) && player.is_zombie )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getHotJoinAi( team )
|
||||
{
|
||||
ais = GetAiArray( team );
|
||||
ai = undefined;
|
||||
|
||||
if ( ais.size )
|
||||
{
|
||||
ai = ais[randomint( ais.size )];
|
||||
}
|
||||
|
||||
return ai;
|
||||
}
|
||||
|
||||
getHotJoinInitSpawn()
|
||||
{
|
||||
structs = getstructarray( "initial_spawn_points", "targetname" );
|
||||
players = get_players();
|
||||
i = 0;
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
if ( !isDefined( players[i] ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( self == players[i] )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
spawn_obj = structs[i];
|
||||
|
||||
if ( !isDefined( spawn_obj ) )
|
||||
{
|
||||
spawn_obj = structs[0];
|
||||
}
|
||||
|
||||
return spawn_obj;
|
||||
}
|
||||
|
||||
hotJoin()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "end_respawn" );
|
||||
|
||||
// quik hax: prevent spectators_respawn from spawning us
|
||||
self.sessionstate = "playing";
|
||||
waittillframeend;
|
||||
self.sessionstate = "spectator";
|
||||
|
||||
player = self getHotJoinPlayer();
|
||||
ally = self getHotJoinAi( "allies" );
|
||||
enemy = self getHotJoinAi( "axis" );
|
||||
spawn_pt = self getHotJoinInitSpawn();
|
||||
|
||||
spawn_obj = spawnStruct();
|
||||
|
||||
if ( isDefined( spawn_pt ) )
|
||||
{
|
||||
spawn_obj = spawn_pt;
|
||||
}
|
||||
else if ( isDefined( player ) )
|
||||
{
|
||||
spawn_obj.origin = player getOrigin();
|
||||
spawn_obj.angles = player.angles;
|
||||
}
|
||||
else if ( isDefined( ally ) )
|
||||
{
|
||||
spawn_obj.origin = ally getOrigin();
|
||||
spawn_obj.angles = ally.angles;
|
||||
}
|
||||
else if ( isDefined( enemy ) )
|
||||
{
|
||||
spawn_obj.origin = enemy getOrigin();
|
||||
spawn_obj.angles = enemy.angles;
|
||||
}
|
||||
else
|
||||
{
|
||||
spawn_obj.origin = ( 0, 0, 0 );
|
||||
spawn_obj.angles = ( 0, 0, 0 );
|
||||
}
|
||||
|
||||
// check if custom logic for hotjoining
|
||||
if ( isDefined( level.customHotJoinPlayer ) )
|
||||
{
|
||||
temp_obj = self [[level.customHotJoinPlayer]]( spawn_obj );
|
||||
|
||||
// check if theres a spawn obj
|
||||
if ( isDefined( temp_obj ) )
|
||||
{
|
||||
// check if we should cancel spawning this player (maybe its already done)
|
||||
if ( isDefined( temp_obj.cancel ) && temp_obj.cancel )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// set our spawn location
|
||||
spawn_obj = temp_obj;
|
||||
}
|
||||
}
|
||||
|
||||
// set spawn params
|
||||
self setorigin( spawn_obj.origin );
|
||||
self setplayerangles( spawn_obj.angles );
|
||||
self.spectator_respawn = spawn_obj;
|
||||
self.respawn_point = spawn_obj;
|
||||
|
||||
// do the spawn
|
||||
println( "*************************Client hotjoin***" );
|
||||
|
||||
self unlink();
|
||||
|
||||
if ( isdefined( self.spectate_cam ) )
|
||||
{
|
||||
self.spectate_cam delete ();
|
||||
}
|
||||
|
||||
if ( ( !isZombieMode() && !level.otherPlayersSpectate && ( !isDefined( spawn_obj.force_spectator ) || !spawn_obj.force_spectator ) ) ||
|
||||
( isDefined( spawn_obj.force_spawn ) && spawn_obj.force_spawn ) )
|
||||
{
|
||||
self thread [[level.spawnPlayer]]();
|
||||
}
|
||||
else
|
||||
{
|
||||
self thread [[level.spawnSpectator]]();
|
||||
checkForAllDead( self );
|
||||
}
|
||||
}
|
||||
|
||||
onDisconnect()
|
||||
{
|
||||
lpselfnum = self getentitynumber();
|
||||
lpguid = self getguid();
|
||||
name = self.playername;
|
||||
|
||||
self waittill( "disconnect" );
|
||||
|
||||
//logprint( "Q;" + lpguid + ";" + lpselfnum + ";" + name + "\n" );
|
||||
|
||||
// check if we need to end the game cause last person left alive left the game
|
||||
checkForAllDead( self );
|
||||
}
|
||||
|
||||
onConnect()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
//logprint( "J;" + self getguid() + ";" + self getentitynumber() + ";" + self.playername + "\n" );
|
||||
}
|
||||
|
||||
onPlayerConnect()
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
iprintln( player.playername + " connected" );
|
||||
|
||||
player thread onDisconnect();
|
||||
player thread onConnect();
|
||||
}
|
||||
}
|
||||
|
||||
checkForAllDead( excluded_player )
|
||||
{
|
||||
players = get_players();
|
||||
count = 0;
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
player = players[ i ];
|
||||
|
||||
if ( !isDefined( player ) || !isDefined( player.sessionstate ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isDefined( excluded_player ) && excluded_player == player )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isdefined( level.isPlayerDead ) && [[level.isPlayerDead]]( player ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
if ( count == 0 && isdefined( level.endGameFunc ) )
|
||||
{
|
||||
level thread [[level.endGameFunc]]();
|
||||
}
|
||||
}
|
||||
@@ -1,423 +0,0 @@
|
||||
#include common_scripts\utility;
|
||||
#include maps\_utility;
|
||||
#include scripts\sp\bots\_bot_utility;
|
||||
|
||||
/*
|
||||
Initiates the whole bot scripts.
|
||||
*/
|
||||
init()
|
||||
{
|
||||
level.bw_VERSION = "2.1.0";
|
||||
|
||||
if ( getDvar( "bots_main" ) == "" )
|
||||
setDvar( "bots_main", true );
|
||||
|
||||
if ( !getDvarInt( "bots_main" ) )
|
||||
return;
|
||||
|
||||
//thread load_waypoints(); //Don't call for now
|
||||
thread hook_callbacks();
|
||||
|
||||
if ( getDvar( "bots_main_GUIDs" ) == "" )
|
||||
setDvar( "bots_main_GUIDs", "" ); //guids of players who will be given host powers, comma seperated
|
||||
|
||||
if ( getDvar( "bots_main_firstIsHost" ) == "" )
|
||||
setDvar( "bots_main_firstIsHost", true ); //first player to connect is a host
|
||||
|
||||
if ( getDvar( "bots_main_waitForHostTime" ) == "" )
|
||||
setDvar( "bots_main_waitForHostTime", 10.0 ); //how long to wait to wait for the host player
|
||||
|
||||
if ( getDvar( "bots_main_kickBotsAtEnd" ) == "" )
|
||||
setDvar( "bots_main_kickBotsAtEnd", false ); //kicks the bots at game end
|
||||
|
||||
if ( getDvar( "bots_manage_add" ) == "" )
|
||||
setDvar( "bots_manage_add", 0 ); //amount of bots to add to the game
|
||||
|
||||
if ( getDvar( "bots_manage_fill" ) == "" )
|
||||
setDvar( "bots_manage_fill", 0 ); //amount of bots to maintain
|
||||
|
||||
if ( getDvar( "bots_manage_fill_mode" ) == "" )
|
||||
setDvar( "bots_manage_fill_mode", 0 ); //fill mode, 0 adds everyone, 1 just bots, 2 maintains at maps, 3 is 2 with 1
|
||||
|
||||
if ( getDvar( "bots_manage_fill_kick" ) == "" )
|
||||
setDvar( "bots_manage_fill_kick", false ); //kick bots if too many
|
||||
|
||||
if ( getDvar( "bots_skill" ) == "" )
|
||||
setDvar( "bots_skill", 0 ); //0 is random, 1 is easy 7 is hard, 8 is custom, 9 is completely random
|
||||
|
||||
if ( getDvar( "bots_skill_hard" ) == "" )
|
||||
setDvar( "bots_skill_hard", 0 ); //amount of hard bots on axis team
|
||||
|
||||
if ( getDvar( "bots_skill_med" ) == "" )
|
||||
setDvar( "bots_skill_med", 0 );
|
||||
|
||||
if ( getDvar( "bots_loadout_rank" ) == "" ) // what rank the bots should be around, -1 is around the players, 0 is all random
|
||||
setDvar( "bots_loadout_rank", -1 );
|
||||
|
||||
if ( getDvar( "bots_loadout_prestige" ) == "" ) // what pretige the bots will be, -1 is the players, -2 is random
|
||||
setDvar( "bots_loadout_prestige", -1 );
|
||||
|
||||
if ( getDvar( "bots_play_move" ) == "" ) //bots move
|
||||
setDvar( "bots_play_move", true );
|
||||
|
||||
if ( getDvar( "bots_play_knife" ) == "" ) //bots knife
|
||||
setDvar( "bots_play_knife", true );
|
||||
|
||||
if ( getDvar( "bots_play_fire" ) == "" ) //bots fire
|
||||
setDvar( "bots_play_fire", true );
|
||||
|
||||
if ( getDvar( "bots_play_nade" ) == "" ) //bots grenade
|
||||
setDvar( "bots_play_nade", true );
|
||||
|
||||
if ( getDvar( "bots_play_ads" ) == "" ) //bot ads
|
||||
setDvar( "bots_play_ads", true );
|
||||
|
||||
if ( getDvar( "bots_play_aim" ) == "" )
|
||||
setDvar( "bots_play_aim", true );
|
||||
|
||||
if ( !isDefined( game["botWarfare"] ) )
|
||||
game["botWarfare"] = true;
|
||||
|
||||
level.bots_minSprintDistance = 315;
|
||||
level.bots_minSprintDistance *= level.bots_minSprintDistance;
|
||||
level.bots_minGrenadeDistance = 256;
|
||||
level.bots_minGrenadeDistance *= level.bots_minGrenadeDistance;
|
||||
level.bots_maxGrenadeDistance = 1024;
|
||||
level.bots_maxGrenadeDistance *= level.bots_maxGrenadeDistance;
|
||||
level.bots_maxKnifeDistance = 80;
|
||||
level.bots_maxKnifeDistance *= level.bots_maxKnifeDistance;
|
||||
level.bots_goalDistance = 27.5;
|
||||
level.bots_goalDistance *= level.bots_goalDistance;
|
||||
level.bots_noADSDistance = 200;
|
||||
level.bots_noADSDistance *= level.bots_noADSDistance;
|
||||
level.bots_maxShotgunDistance = 500;
|
||||
level.bots_maxShotgunDistance *= level.bots_maxShotgunDistance;
|
||||
|
||||
level.players = [];
|
||||
level.bots = [];
|
||||
|
||||
level.bots_fullautoguns = [];
|
||||
level.bots_fullautoguns["thompson"] = true;
|
||||
level.bots_fullautoguns["mp40"] = true;
|
||||
level.bots_fullautoguns["type100smg"] = true;
|
||||
level.bots_fullautoguns["ppsh"] = true;
|
||||
level.bots_fullautoguns["stg44"] = true;
|
||||
level.bots_fullautoguns["30cal"] = true;
|
||||
level.bots_fullautoguns["mg42"] = true;
|
||||
level.bots_fullautoguns["dp28"] = true;
|
||||
level.bots_fullautoguns["bar"] = true;
|
||||
level.bots_fullautoguns["fg42"] = true;
|
||||
level.bots_fullautoguns["type99lmg"] = true;
|
||||
|
||||
level thread onPlayerConnect();
|
||||
level thread handleBots();
|
||||
}
|
||||
|
||||
/*
|
||||
Starts the threads for bots.
|
||||
*/
|
||||
handleBots()
|
||||
{
|
||||
level thread diffBots();
|
||||
level addBots();
|
||||
|
||||
while ( !level.intermission )
|
||||
wait 0.05;
|
||||
|
||||
setDvar( "bots_manage_add", getBotArray().size );
|
||||
|
||||
if ( !getDvarInt( "bots_main_kickBotsAtEnd" ) )
|
||||
return;
|
||||
|
||||
bots = getBotArray();
|
||||
|
||||
for ( i = 0; i < bots.size; i++ )
|
||||
{
|
||||
bots[i] RemoveTestClient();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
The hook callback for when any player becomes damaged.
|
||||
*/
|
||||
onPlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, timeOffset )
|
||||
{
|
||||
if ( self is_bot() )
|
||||
{
|
||||
//self scripts\sp\bots\_bot_internal::onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, timeOffset );
|
||||
self scripts\sp\bots\_bot_script::onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, timeOffset );
|
||||
}
|
||||
|
||||
self [[level.prevCallbackPlayerDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, timeOffset );
|
||||
}
|
||||
|
||||
/*
|
||||
Starts the callbacks.
|
||||
*/
|
||||
hook_callbacks()
|
||||
{
|
||||
wait 0.05;
|
||||
level.prevCallbackPlayerDamage = level.callbackPlayerDamage;
|
||||
level.callbackPlayerDamage = ::onPlayerDamage;
|
||||
}
|
||||
|
||||
/*
|
||||
Thread when any player connects. Starts the threads needed.
|
||||
*/
|
||||
onPlayerConnect()
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
player thread connected();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
When a bot disconnects.
|
||||
*/
|
||||
onDisconnectAll()
|
||||
{
|
||||
self waittill( "disconnect" );
|
||||
|
||||
level.players = array_remove( level.players, self );
|
||||
}
|
||||
|
||||
/*
|
||||
When a bot disconnects.
|
||||
*/
|
||||
onDisconnect()
|
||||
{
|
||||
self waittill( "disconnect" );
|
||||
|
||||
level.bots = array_remove( level.bots, self );
|
||||
}
|
||||
|
||||
/*
|
||||
Called when a player connects.
|
||||
*/
|
||||
connected()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
if ( !isDefined( self.pers["bot_host"] ) )
|
||||
self thread doHostCheck();
|
||||
|
||||
level.players[level.players.size] = self;
|
||||
self thread onDisconnectAll();
|
||||
|
||||
if ( !self is_bot() )
|
||||
return;
|
||||
|
||||
if ( !isDefined( self.pers["isBot"] ) )
|
||||
{
|
||||
// fast restart...
|
||||
self.pers["isBot"] = true;
|
||||
}
|
||||
|
||||
if ( !isDefined( self.pers["isBotWarfare"] ) )
|
||||
{
|
||||
self.pers["isBotWarfare"] = true;
|
||||
self thread added();
|
||||
}
|
||||
|
||||
self thread scripts\sp\bots\_bot_internal::connected();
|
||||
self thread scripts\sp\bots\_bot_script::connected();
|
||||
|
||||
level.bots[level.bots.size] = self;
|
||||
self thread onDisconnect();
|
||||
|
||||
level notify( "bot_connected", self );
|
||||
|
||||
self thread watchBotDebugEvent();
|
||||
}
|
||||
|
||||
/*
|
||||
DEBUG
|
||||
*/
|
||||
watchBotDebugEvent()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "bot_event", msg, str, b, c, d, e, f, g );
|
||||
|
||||
if ( msg == "debug" && GetDvarInt( "bots_main_debug" ) )
|
||||
{
|
||||
PrintConsole( "Bot Warfare debug: " + self.name + ": " + str + "\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
When a bot gets added into the game.
|
||||
*/
|
||||
added()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
self thread scripts\sp\bots\_bot_internal::added();
|
||||
//self thread scripts\sp\bots\_bot_script::added();
|
||||
}
|
||||
|
||||
/*
|
||||
Adds a bot to the game.
|
||||
*/
|
||||
add_bot()
|
||||
{
|
||||
bot = addtestclient();
|
||||
|
||||
if ( isdefined( bot ) )
|
||||
{
|
||||
bot.pers["isBot"] = true;
|
||||
bot.pers["isBotWarfare"] = true;
|
||||
bot thread added();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
A server thread for monitoring all bot's difficulty levels for custom server settings.
|
||||
*/
|
||||
diffBots_loop()
|
||||
{
|
||||
var_hard = getDVarInt( "bots_skill_hard" );
|
||||
var_med = getDVarInt( "bots_skill_med" );
|
||||
var_skill = getDvarInt( "bots_skill" );
|
||||
|
||||
hard = 0;
|
||||
med = 0;
|
||||
|
||||
if ( var_skill == 8 )
|
||||
{
|
||||
playercount = level.players.size;
|
||||
|
||||
for ( i = 0; i < playercount; i++ )
|
||||
{
|
||||
player = level.players[i];
|
||||
|
||||
if ( !isDefined( player.pers["team"] ) )
|
||||
continue;
|
||||
|
||||
if ( !player is_bot() )
|
||||
continue;
|
||||
|
||||
if ( hard < var_hard )
|
||||
{
|
||||
hard++;
|
||||
player.pers["bots"]["skill"]["base"] = 7;
|
||||
}
|
||||
else if ( med < var_med )
|
||||
{
|
||||
med++;
|
||||
player.pers["bots"]["skill"]["base"] = 4;
|
||||
}
|
||||
else
|
||||
player.pers["bots"]["skill"]["base"] = 1;
|
||||
}
|
||||
}
|
||||
else if ( var_skill != 0 && var_skill != 9 )
|
||||
{
|
||||
playercount = level.players.size;
|
||||
|
||||
for ( i = 0; i < playercount; i++ )
|
||||
{
|
||||
player = level.players[i];
|
||||
|
||||
if ( !player is_bot() )
|
||||
continue;
|
||||
|
||||
player.pers["bots"]["skill"]["base"] = var_skill;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
A server thread for monitoring all bot's difficulty levels for custom server settings.
|
||||
*/
|
||||
diffBots()
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
wait 1.5;
|
||||
|
||||
diffBots_loop();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
A server thread for monitoring all bot's in game. Will add and kick bots according to server settings.
|
||||
*/
|
||||
addBots_loop()
|
||||
{
|
||||
botsToAdd = GetDvarInt( "bots_manage_add" );
|
||||
|
||||
if ( botsToAdd > 0 )
|
||||
{
|
||||
SetDvar( "bots_manage_add", 0 );
|
||||
|
||||
if ( botsToAdd > 4 )
|
||||
botsToAdd = 4;
|
||||
|
||||
for ( ; botsToAdd > 0; botsToAdd-- )
|
||||
{
|
||||
level add_bot();
|
||||
wait 0.25;
|
||||
}
|
||||
}
|
||||
|
||||
fillMode = getDVarInt( "bots_manage_fill_mode" );
|
||||
|
||||
if ( fillMode == 2 || fillMode == 3 )
|
||||
setDvar( "bots_manage_fill", getGoodMapAmount() );
|
||||
|
||||
fillAmount = getDvarInt( "bots_manage_fill" );
|
||||
|
||||
players = 0;
|
||||
bots = 0;
|
||||
|
||||
playercount = level.players.size;
|
||||
|
||||
for ( i = 0; i < playercount; i++ )
|
||||
{
|
||||
player = level.players[i];
|
||||
|
||||
if ( player is_bot() )
|
||||
bots++;
|
||||
else
|
||||
players++;
|
||||
}
|
||||
|
||||
amount = bots;
|
||||
|
||||
if ( fillMode == 0 || fillMode == 2 )
|
||||
amount += players;
|
||||
|
||||
if ( amount < fillAmount )
|
||||
setDvar( "bots_manage_add", 1 );
|
||||
else if ( amount > fillAmount && getDvarInt( "bots_manage_fill_kick" ) )
|
||||
{
|
||||
tempBot = PickRandom( getBotArray() );
|
||||
|
||||
if ( isDefined( tempBot ) )
|
||||
tempBot RemoveTestClient();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
A server thread for monitoring all bot's in game. Will add and kick bots according to server settings.
|
||||
*/
|
||||
addBots()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
bot_wait_for_host();
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait 1.5;
|
||||
|
||||
addBots_loop();
|
||||
}
|
||||
}
|
||||
4
scripts/sp/bots.gsc
Normal file
4
scripts/sp/bots.gsc
Normal file
@@ -0,0 +1,4 @@
|
||||
init()
|
||||
{
|
||||
level thread maps\bots\_bot::init();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
126
scripts/sp/bots_adapter_pt4.gsc
Normal file
126
scripts/sp/bots_adapter_pt4.gsc
Normal file
@@ -0,0 +1,126 @@
|
||||
init()
|
||||
{
|
||||
level.bot_builtins[ "printconsole" ] = ::do_printconsole;
|
||||
level.bot_builtins[ "botaction" ] = ::do_botaction;
|
||||
level.bot_builtins[ "botstop" ] = ::do_botstop;
|
||||
level.bot_builtins[ "botmovement" ] = ::do_botmovement;
|
||||
level.bot_builtins[ "botmeleeparams" ] = ::do_botmeleeparams;
|
||||
level.bot_builtins[ "botangles" ] = ::do_botangles;
|
||||
level.bot_builtins[ "isbot" ] = ::do_isbot;
|
||||
level.bot_builtins[ "generatepath" ] = ::do_generatepath;
|
||||
level.bot_builtins[ "getfunction" ] = ::do_getfunction;
|
||||
level.bot_builtins[ "getmins" ] = ::do_getmins;
|
||||
level.bot_builtins[ "getmaxs" ] = ::do_getmaxs;
|
||||
level.bot_builtins[ "getguid" ] = ::do_getguid;
|
||||
level.bot_builtins[ "setallowedtraversals" ] = ::do_setallowedtraversals;
|
||||
level.bot_builtins[ "setignoredlinks" ] = ::do_setignoredlinks;
|
||||
level.bot_builtins[ "getnodenumber" ] = ::do_getnodenumber;
|
||||
level.bot_builtins[ "getlinkednodes" ] = ::do_getlinkednodes;
|
||||
level.bot_builtins[ "addtestclient" ] = ::do_addtestclient;
|
||||
level.bot_builtins[ "notifyonplayercommand" ] = ::do_notifyonplayercommand;
|
||||
level.bot_builtins[ "cmdexec" ] = ::do_cmdexec;
|
||||
level.bot_builtins[ "ishost" ] = ::do_ishost;
|
||||
}
|
||||
|
||||
do_printconsole( s )
|
||||
{
|
||||
printconsole( s );
|
||||
}
|
||||
|
||||
do_botaction( action )
|
||||
{
|
||||
self botaction( action );
|
||||
}
|
||||
|
||||
do_botstop()
|
||||
{
|
||||
self botstop();
|
||||
}
|
||||
|
||||
do_botmovement( left, forward )
|
||||
{
|
||||
self botmovement( left, forward );
|
||||
}
|
||||
|
||||
do_botmeleeparams( yaw, dist )
|
||||
{
|
||||
//self botmeleeparams( yaw, dist );
|
||||
}
|
||||
|
||||
do_botangles( angles )
|
||||
{
|
||||
self setplayerangles( angles );
|
||||
//self botangles( angles );
|
||||
}
|
||||
|
||||
do_isbot()
|
||||
{
|
||||
return self isbot();
|
||||
}
|
||||
|
||||
do_generatepath( from, to, team, best_effort )
|
||||
{
|
||||
return generatepath( from, to, team, best_effort );
|
||||
}
|
||||
|
||||
do_getfunction( file, threadname )
|
||||
{
|
||||
return undefined;
|
||||
//return getfunction( file, threadname );
|
||||
}
|
||||
|
||||
do_getmins()
|
||||
{
|
||||
return self getmins();
|
||||
}
|
||||
|
||||
do_getmaxs()
|
||||
{
|
||||
return self getmaxs();
|
||||
}
|
||||
|
||||
do_getguid()
|
||||
{
|
||||
return self getguid();
|
||||
}
|
||||
|
||||
do_setallowedtraversals( a )
|
||||
{
|
||||
setallowedtraversals( a );
|
||||
}
|
||||
|
||||
do_setignoredlinks( a )
|
||||
{
|
||||
setignoredlinks( a );
|
||||
}
|
||||
|
||||
do_getnodenumber()
|
||||
{
|
||||
return self getnodenumber();
|
||||
}
|
||||
|
||||
do_getlinkednodes()
|
||||
{
|
||||
return self getlinkednodes();
|
||||
}
|
||||
|
||||
do_addtestclient()
|
||||
{
|
||||
return addtestclient();
|
||||
}
|
||||
|
||||
do_notifyonplayercommand( a, b )
|
||||
{
|
||||
//self notifyonplayercommand( a, b );
|
||||
}
|
||||
|
||||
do_cmdexec( a )
|
||||
{
|
||||
//cmdexec( a );
|
||||
}
|
||||
|
||||
do_ishost()
|
||||
{
|
||||
return self == getplayers()[0];
|
||||
//return self ishost();
|
||||
}
|
||||
4
scripts/sp/bots_debug.gsc
Normal file
4
scripts/sp/bots_debug.gsc
Normal file
@@ -0,0 +1,4 @@
|
||||
init()
|
||||
{
|
||||
level thread maps\bots\_bot_debug::init();
|
||||
}
|
||||
Reference in New Issue
Block a user