55 Commits

Author SHA1 Message Date
abfa41e24d smaall changes 2022-05-08 18:01:17 -06:00
3339ff2656 Link 2022-05-08 17:51:57 -06:00
a64a0cc810 Version 2.1.0 2022-05-08 17:46:25 -06:00
9c20cf621b bot chatter system 2022-05-08 14:43:51 -06:00
f667c96717 Added bot notifications 2022-05-06 19:06:20 -06:00
c2f86e7120 fixed bombs 2022-05-02 15:25:08 -06:00
d3f2f192f0 frontline waypoints 2022-04-25 16:30:20 -06:00
762257ca8a pick up gun 2022-04-25 11:11:01 -06:00
e773996274 Prep work for bot chatter 2022-04-20 12:57:19 -06:00
7eb6c7d246 Better stuck detection for up and down 2022-04-08 23:43:53 -06:00
15143dbb85 change some values for detecting stuckness 2022-04-08 22:56:23 -06:00
0f95ebacb8 Fix bots getting stuck a bit 2022-04-08 22:43:49 -06:00
2a20a834ec Bot do random action at obj 2022-04-08 20:35:17 -06:00
99dbe2cd87 github supports gsc 2022-03-23 11:49:12 -06:00
090fc5f7a8 better 2021-12-21 21:52:37 -06:00
3258183b1c better code completion 2021-12-21 21:43:42 -06:00
5021547734 table 2021-09-09 12:55:11 -06:00
a4e3fbb42b gitattrs and editorconfig 2021-09-09 11:23:12 -06:00
7c041900ff oops lol 2021-09-05 14:50:56 -06:00
6ee4d2e2fd max clients are needed on the cmd 2021-09-05 00:38:36 -06:00
988d471fdb configs 2021-09-05 00:32:25 -06:00
3711a8e8ad update 2021-09-04 23:59:36 -06:00
c3d3dc8323 cleanup 2021-09-04 23:59:27 -06:00
b5fb8c7760 clean up 2021-09-04 23:59:17 -06:00
c366c041fb Add vscode settings 2021-09-03 10:58:56 -06:00
79592e6056 Added bot_aim dvar 2021-08-26 10:18:53 -06:00
ca9dad8b79 fixed script link error 2021-08-25 13:01:09 -06:00
5fe8aee7e2 Fixed bots classes 2021-08-25 12:56:03 -06:00
fab64bc3ed Merge pull request #9 from Kianda/patch-1
not OP disable RPG on Perks
2021-08-10 12:07:55 -06:00
feb573d43b not OP disable RPG on Perks
Integration for commit d788ce7cb3
2021-08-07 17:22:48 +02:00
d788ce7cb3 no tube weapons if no op allowed 2021-08-06 19:13:43 -06:00
cae032eb9a minor improvement to sprint 2021-07-29 13:38:53 -06:00
d9a8ac04c4 Small fix 2021-07-25 21:56:09 -06:00
e606af216c Needs 4 params 2021-07-13 19:18:48 -06:00
2972d4e497 bots target through glass 2021-07-13 19:02:45 -06:00
ca0b0032eb Format scripts 2021-06-18 14:33:09 -06:00
6d9dbb262a Added deploy and astylerc 2021-06-18 14:17:58 -06:00
a568042934 Abstract class choice 2021-06-14 13:22:12 -06:00
e3a65e892c More sprint 2021-06-13 19:10:29 -06:00
30a9888067 improved bot sight 2021-06-13 14:19:43 -06:00
4dcea05c2a Reduce more script usage 2021-06-04 14:07:11 -06:00
168a2e621c some weap changes 2021-06-02 10:28:59 -06:00
c9f5b6cf33 prevent stuck 2021-05-27 14:17:45 -06:00
3b7669dbd0 Greatly reduce var usage 2021-05-26 10:47:29 -06:00
589fe63bc8 Update wps 2021-05-25 21:06:50 -06:00
712f2c3a37 Added use button 2021-05-25 16:56:48 -06:00
ab612e8ff6 Reduced var usage 2021-05-25 16:53:10 -06:00
a5b3ecc81b Fix runtime error when loading wps 2021-05-23 13:33:38 -06:00
9c1f4552c2 Added low mem mode 2021-05-19 20:09:50 -06:00
91044ff842 Improved bots mantling 2021-05-19 15:40:14 -06:00
e1326342d2 Fix possible runtime error 2021-05-18 14:59:50 -06:00
a6d663b67c formatting 2021-05-15 22:54:01 -06:00
e7bf74894d Link the editor 2021-05-15 22:52:07 -06:00
01dc7ea667 Finally add wp editor md 2021-05-15 22:50:57 -06:00
b1808c66ea Update ss 2021-05-15 00:34:18 -06:00
47 changed files with 18970 additions and 11375 deletions

21
.astylerc Normal file
View File

@ -0,0 +1,21 @@
# try to mimic the original gsc provided
mode=c
style=allman
indent=tab
lineend=windows
pad-oper
pad-paren-in
pad-header
# delete-empty-lines
break-blocks
# remove-braces
indent-switches
indent-cases
indent-after-parens
remove-comment-prefix

11
.editorconfig Normal file
View File

@ -0,0 +1,11 @@
root = true
[*]
indent_style = tab
indent_size = 2
charset = latin1
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
*.gsx linguist-language=GSC

14
.gitignore vendored
View File

@ -3,15 +3,14 @@
# Files to not ignore
!/.gitignore
!/botnames.txt
!/z_devserver.bat
!/z_serverdev.bat
!/.editorconfig
!/.gitattributes
!/z_server.bat
!/z_client.bat
!/z_dev.bat
# Folder to not ignore
!/main_shared/
!/.vscode
*.gsx
!/main_shared/maps/mp/gametypes/_callbacksetup.gsx
main_shared/maps/mp/gametypes/_globallogic.gsx
@ -20,6 +19,11 @@ main_shared/maps/mp/gametypes/_hardpoints.gsx
*.zip
!/out
!/.astylerc
!/z_deploy.bat
!/deploy.bat
!/deploy.js
!/main/
/main/*
!/main/server.cfg

19
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,19 @@
{
"astyle.astylerc": "${workspaceRoot}/.astylerc",
"astyle.additional_languages": [
"gsc",
"gsx"
],
"[gsc]": {
"editor.defaultFormatter": "chiehyu.vscode-astyle",
},
"editor.quickSuggestions": {
"other": true,
"comments": true,
"strings": true
},
"vscode-codscript.use_builtin_completionItems": false,
"files.associations": {
"*.gsx": "gsc"
}
}

144
README.md
View File

@ -5,7 +5,7 @@ Bot Warfare is a GSC mod for the [CoD4x project](https://github.com/callofduty4x
It aims to add playable AI to the multiplayer games of CoD4.
You can find the ModDB release post [here](https://www.moddb.com/mods/bot-warfare/downloads/cod4x-bot-warfare-latest) and the CoD4x.me post [here](https://cod4x.me/index.php?/forums/topic/3116-release-bot-warfare/).
You can find the ModDB release post [here](https://www.moddb.com/mods/bot-warfare/downloads/cod4x-bot-warfare-latest) and the CoD4x forum post [here](https://cod4x.ovh/index.php?/forums/topic/3116-release-bot-warfare/).
## <span style="color:red">Important to public dedicated servers</span>
The ```bots_main_firstIsHost``` DVAR is enabled by default!
@ -22,7 +22,7 @@ Make sure to disable this DVAR by adding ```set bots_main_firstIsHost 0``` in yo
- [Credits](#Credits)
## Features
- A Waypoint Editor for creating and modifying bot's waypoints of traversing the map. Have a look at [Using the Waypoint editor]().
- A Waypoint Editor for creating and modifying bot's waypoints of traversing the map. Have a look at [Using the Waypoint editor](/main_shared/bw-assets/wpedit.md).
- A clean and nice menu, you can edit every bot DVAR within in-game.
@ -57,15 +57,15 @@ Make sure to disable this DVAR by adding ```set bots_main_firstIsHost 0``` in yo
- ... And pretty much everything you expect a Combat Training bot to have
## Installation
Using CoD4x's extended functionality requires to use their Dedicated server, as explained [here](https://cod4x.me/index.php?/forums/topic/2047-add-cod4x-server-gsc-functions-to-the-client/).
Using CoD4x's extended functionality requires to use their Dedicated server, as explained [here](https://cod4x.ovh/index.php?/forums/topic/2047-add-cod4x-server-gsc-functions-to-the-client/).
You can easily setup a local LAN dedicated server for you to join and play on. Have a look at [Setting up a CoD4x server]().
You can easily setup a local LAN dedicated server for you to join and play on. Have a look at [Setting up a CoD4x server](https://github.com/callofduty4x/CoD4x_Server/wiki/Server-setup).
0. Make sure that [CoD4x server + client](https://cod4x.me/) is installed, updated and working properly.
0. Make sure that [CoD4x server + client](https://cod4x.ovh/) is installed, updated and working properly.
- Download the [latest release](https://github.com/ineedbots/cod4x_bot_warfare/releases) of Bot Warfare.
1. Locate your CoD4x server install folder.
2. Move the files/folders found in 'Add to root of CoD4x server' from the Bot Warfare release archive you downloaded to the root of your CoD4x server folder.
- The folder/file structure should follow as '.CoD4x server folder\main_shared\maps\mp\bots\_bot.gsc'.
- The folder/file structure should follow as `.CoD4x server folder\main_shared\maps\mp\bots\_bot.gsc`.
3. The mod is now installed, now start your server, change the DVARs and start a map.
4. Now start your CoD4x client and connect to your server ('connect 127.0.0.1' in the console most likely) and play!
@ -79,88 +79,60 @@ You can easily setup a local LAN dedicated server for you to join and play on. H
- Pressing the menu button again closes menus.
### DVARs
- bots_manage_add - an integer amount of bots to add to the game, resets to 0 once the bots have been added.
- for example: 'bots_manage_add 10' will add 10 bots to the game.
| Dvar | Description | Default Value |
|----------------------------------|---------------------------------------------------------------------------------------------|--------------:|
| bots_main | Enable this mod. | true |
| bots_main_firstIsHost | The first player to connect will be given host. | true |
| bots_main_GUIDs | A comma separated list of GUIDs of players who will be given host. | "" |
| bots_main_waitForHostTime | How many seconds to wait for the host player to connect before adding bots to the match. | 10 |
| bots_main_menu | Enable the in-game menu for hosts. | true |
| bots_main_debug | Enable the in-game waypoint editor. | false |
| bots_main_kickBotsAtEnd | Kick the bots at the end of a match. | false |
| bots_main_chat | The rate bots will chat at, set to 0 to disable. | 1.0 |
| bots_manage_add | Amount of bots to add to the game, once bots are added, resets back to `0`. | 0 |
| bots_manage_fill | Amount of players/bots (look at `bots_manage_fill_mode`) to maintain in the match. | 0 |
| bots_manage_fill_mode | `bots_manage_fill` players/bots counting method.<ul><li>`0` - counts both players and bots.</li><li>`1` - only counts bots.</li></ul> | 0 |
| bots_manage_fill_kick | If the amount of players/bots in the match exceeds `bots_manage_fill`, kick bots until no longer exceeds. | false |
| bots_manage_fill_spec | If when counting players for `bots_manage_fill` should include spectators. | true |
| bots_team | One of `autoassign`, `allies`, `axis`, `spectator`, or `custom`. What team the bots should be on. | autoassign |
| bots_team_amount | When `bots_team` is set to `custom`. The amount of bots to be placed on the axis team. The remainder will be placed on the allies team. | 0 |
| bots_team_force | If the server should force bots' teams according to the `bots_team` value. When `bots_team` is `autoassign`, unbalanced teams will be balanced. This dvar is ignored when `bots_team` is `custom`. | false |
| bots_team_mode | When `bots_team_force` is `true` and `bots_team` is `autoassign`, players/bots counting method. <ul><li>`0` - counts both players and bots.</li><li>`1` - only counts bots</li></ul> | 0 |
| bots_skill | Bots' difficulty.<ul><li>`0` - Random difficulty for each bot.</li><li>`1` - Easiest difficulty for all bots.</li><li>`2` to `6` - Between easy and hard difficulty for all bots.</li><li>`7` - The hardest difficulty for all bots.</li><li>`8` - custom (look at the `bots_skill_<team>_<difficulty>` dvars</li></ul> | 0 |
| bots_skill_axis_hard | When `bots_skill` is set to `8`, the amount of hard difficulty bots to set on the axis team. | 0 |
| bots_skill_axis_med | When `bots_skill` is set to `8`, the amount of medium difficulty bots to set on the axis team. The remaining bots on the team will be set to easy difficulty. | 0 |
| bots_skill_allies_hard | When `bots_skill` is set to `8`, the amount of hard difficulty bots to set on the allies team. | 0 |
| bots_skill_allies_med | When `bots_skill` is set to `8`, the amount of medium difficulty bots to set on the allies team. The remaining bots on the team will be set to easy difficulty. | 0 |
| bots_skill_min | The minimum difficulty level for the bots. | 1 |
| bots_skill_max | The maximum difficulty level for the bots. | 7 |
| bots_loadout_reasonable | If the bots should filter bad performing create-a-class selections. | false |
| bots_loadout_allow_op | If the bots should be able to use overpowered and annoying create-a-class selections. | true |
| bots_loadout_rank | What rank to set the bots.<ul><li>`-1` - Average of all players in the match.</li><li>`0` - All random.</li><li>`1` or higher - Sets the bots' rank to this.</li></ul> | -1 |
| bots_play_move | If the bots can move. | true |
| bots_play_knife | If the bots can knife. | true |
| bots_play_fire | If the bots can fire. | true |
| bots_play_nade | If the bots can grenade. | true |
| bots_play_obj | If the bots can play the objective. | true |
| bots_play_camp | If the bots can camp. | true |
| bots_play_jumpdrop | If the bots can jump/drop shot. | true |
| bots_play_target_other | If the bots can target other entities other than players. | true |
| bots_play_killstreak | If the bots can call in killstreaks. | true |
| bots_play_ads | If the bots can aim down sights. | true |
| bots_play_aim | If the bots can aim. | true |
- bots_manage_fill - an integer amount of players/bots (depends on bots_manage_fill_mode) to retain on the server, it will automatically add bots to fill player space.
- for example: 'bots_manage_fill 10' will have the server retain 10 players in the server, if there are less than 10, it will add bots until that value is reached.
- bots_manage_fill_mode - a value to indicate if the server should consider only bots or players and bots when filling player space.
- 0 will consider both players and bots.
- 1 will only consider bots.
- bots_manage_fill_kick - a boolean value (0 or 1), whether or not if the server should kick bots if the amount of players/bots (depends on bots_manage_fill_mode) exceeds the value of bots_manage_fill.
- bots_manage_fill_spec - a boolean value (0 or 1), whether or not if the server should consider players who are on the spectator team when filling player space.
---
- bots_team - a string, the value indicates what team the bots should join:
- 'autoassign' will have bots balance the teams
- 'allies' will have the bots join the allies team
- 'axis' will have the bots join the axis team
- 'custom' will have bots_team_amount bots on the axis team, the rest will be on the allies team
- bots_team_amount - an integer amount of bots to have on the axis team if bots_team is set to 'custom', the rest of the bots will be placed on the allies team.
- for example: there are 5 bots on the server and 'bots_team_amount 3', then 3 bots will be placed on the axis team, the other 2 will be placed on the allies team.
- bots_team_force - a boolean value (0 or 1), whether or not if the server should enforce periodically the bot's team instead of just a single team when the bot is added to the game.
- for example: 'bots_team_force 1' and 'bots_team autoassign' and the teams become to far unbalanced, then the server will change a bot's team to make it balanced again.
- bots_team_mode - a value to indicate if the server should consider only bots or players and bots when counting players on the teams.
- 0 will consider both players and bots.
- 1 will only consider bots.
---
- bots_skill - value to indicate how difficult the bots should be.
- 0 will be mixed difficultly
- 1 will be the most easy
- 2-6 will be in between most easy and most hard
- 7 will be the most hard.
- 8 will be custom.
- bots_skill_axis_hard - an integer amount of hard bots on the axis team.
- bots_skill_axis_med - an integer amount of medium bots on the axis team.
- bots_skill_allies_hard - an integer amount of hard bots on the allies team.
- bots_skill_allies_med - an integer amount of medium bots on the allies team
- if bots_skill is 8 (custom). The remaining bots on the team will become easy bots
- for example: having 5 bots on the allies team, 'bots_skill_allies_hard 2' and 'bots_skill_allies_med 2' will have 2 hard bots, 2 medium bots, and 1 easy bot on the allies team.
---
- bots_loadout_reasonable - a boolean value (0 or 1), whether or not if the bots should filter out bad create a class selections
- bots_loadout_allow_op - a boolean value (0 or 1), whether or not if the bots are allowed to use jug, marty, etc.
- bots_loadout_rank - an integer number, bots will be around this rank, -1 is average of all players in game, 0 is all random
- bots_play_move - a boolean value (0 or 1), whether or not if the bots will move
- bots_play_knife - a boolean value (0 or 1), whether or not if the bots will use the knife
- bots_play_fire - a boolean value (0 or 1), whether or not if the bots will fire their weapons
- bots_play_nade - a boolean value (0 or 1), whether or not if the bots will grenade
- bots_play_obj - a boolean value (0 or 1), whether or not if the bots will play the objective
- bots_play_camp - a boolean value (0 or 1), whether or not if the bots will camp
- bots_play_jumpdrop - a boolean value (0 or 1), whether or not if the bots will jump shot or drop shot
- bots_play_target_other - a boolean value (0 or 1), whether or not if the bots will target claymores, killstreaks, etc.
- bots_play_killstreak - a boolean value (0 or 1), whether or not if the bots will use killstreaks
- bots_play_ads - a boolean value (0 or 1), whether or not if the bots will ads
---
- bots_main - a boolean value (0 or 1), enables or disables the mod
- bots_main_firstIsHost - a boolean value (0 or 1), the first player to connect is considered a host
- bots_main_GUIDs - a list of GUIDs (comma seperated) of players who will be considered a host
- bots_main_waitForHostTime - a float value, how long in seconds to wait for the host player to connect before adding in bots
- bots_main_menu - a boolean value (0 or 1), enables or disables the menu
- bots_main_debug - a boolean value (0 or 1), enables or disables the waypoint editor
## Changelog
- v2.1.0
- Bot chatter system, bots_main_chat
- Greatly reduce script variable usage
- Improved bots mantling and stuck
- Fix some runtime errors
- Bots sprint more
- Improved bots sight on enemies
- Bots do random actions while waiting at an objective
- Improved bots from getting stuck
- Better bot difficulty management, bots_skill_min and bots_skill_max
- v2.0.1
- Reduced bots crouching
- Increased bots sprinting
@ -182,7 +154,7 @@ You can easily setup a local LAN dedicated server for you to join and play on. H
## Credits
- CoD4x Team - https://github.com/callofduty4x/CoD4x_Server
- INeedGames(me) - http://www.moddb.com/mods/bot-warfare
- INeedGames - http://www.moddb.com/mods/bot-warfare
- PeZBot team - http://www.moddb.com/mods/pezbot
- Ability
- Salvation

2
deploy.bat Normal file
View File

@ -0,0 +1,2 @@
xcopy cod4x_bot_warfare\main_shared\maps\mp\bots main_shared\maps\mp\bots\ /Y /I /E /H /C
xcopy cod4x_bot_warfare\main main\ /Y /I /E /H /C

54
deploy.js Normal file
View File

@ -0,0 +1,54 @@
// nodejs 14+
const exec = require('util').promisify(require('child_process').exec)
const repo_name = 'cod4x_bot_warfare'
const repo_url = `https://github.com/ineedbots/${repo_name}`
const deploy_check_rate = 60000
const title = 'CoD4x Bot Warfare Git Deployer'
function printToConsole(what, error = false)
{
log = error ? console.error : console.log
log(`[${new Date().toISOString()}]:`, what)
}
async function doDeploy() {
try {
const { stdout, stderr } = await exec(`cd ${repo_name} && git fetch`)
if (stderr.length <= 0)
return
if (stderr.startsWith('From '))
{
printToConsole('git fetched! Pulling...')
await exec(`cd ${repo_name} && git pull && git submodule update --init --recursive`)
printToConsole('Deploying...')
await exec('deploy.bat')
printToConsole('Deployed!')
}
} catch (e) {
printToConsole(e, true)
if (!e.stderr.startsWith('The system cannot find the path specified'))
return
printToConsole('Cloning repo...')
try {
await exec(`git clone ${repo_url} && cd ${repo_name} && git submodule update --init --recursive`)
printToConsole('Cloned!')
printToConsole('Deploying...')
await exec('deploy.bat')
printToConsole('Deployed!')
} catch (f) {
printToConsole(f, true)
}
}
}
process.stdout.write(`${String.fromCharCode(27)}]0;${title}${String.fromCharCode(7)}`)
doDeploy()
setInterval(doDeploy, deploy_check_rate)

View File

@ -9,7 +9,7 @@
/// features only available on CoD4X 1.8+ servers ///
/// ///
////////////////////////////////////////////////////////////
loadplugin "httpget"
// Meta Information, not required
sets _Admin "Admin"
@ -23,15 +23,11 @@ sets _Gametype ""
// Basics
set sv_hostname "^1Bot ^3War^5fare ^724/7 Shipment 10x"
set g_motd "" // Message of the day, which getting shown to every player on his 1st spawn
set dedicated "2" // 0 = Listen, 1 = LAN, 2 = Internet ( you probably want 2 )
set rcon_password "qazqaz" // password for remote access, leave empty to deactivate, min 8 characters
set g_password "" // join password, leave empty to deactivate
set sv_privateClients "" //Private Clients, number of slots that can only be changed with a password
set sv_privatePassword "" // the password to join private slots
set sv_authorizemode "-1" // cdkey validation
set sv_showasranked "1" // 0 = show modded server as not ranked, 1 = shows server as ranked altough it is modded
set sv_authtoken "12312321"
// Log File
set g_logsync "2" // 0=no log, 1=buffered, 2=continuous, 3=append
@ -41,16 +37,14 @@ set sv_log_damage "1"
set sv_statusfile "serverstatus.xml" // writes an xml serverstatus to disc, leave empty to disable
// Networking
// set net_ip "0.0.0.0" // not necessary to be set
// set net_port 28960 // network port
// set sv_maxRate 25000
set sv_minPing "0" // minimal ping [ms] for a player to join the server
set sv_maxPing "0" // maximal ping [ms] for a player to join the server
set sv_timeout 40 // Seconds to keep a client on server without a new clientmessage
set sv_connectTimeout 90 // Seconds to wait for a client which is loading a map without a new clientmessage
set sv_zombieTime 2 // Seconds to keep a disconnected client on server to transmit the last message
set sv_reconnectlimit 5 // Seconds to disallow a prior connected client to reconnect to the server
set sv_timeout "40" // Seconds to keep a client on server without a new clientmessage
set sv_connectTimeout "90" // Seconds to wait for a client which is loading a map without a new clientmessage
set sv_zombieTime "2" // Seconds to keep a disconnected client on server to transmit the last message
set sv_reconnectlimit "5" // Seconds to disallow a prior connected client to reconnect to the server
// Floodprotection is enabled by default!
// sv_floodProtect, sv_maxRate,
@ -58,10 +52,10 @@ set sv_reconnectlimit 5 // Seconds to disallow a prior connected client to recon
// Variables you should not touch :)
// set sv_fps "20" //Server-FPS (do not change!)
// set sv_punkbuster "0" //Punkbuster, PB is not supported on CoD4x
// set sv_pure "1" //check IWD-data 0 = off, 1 = on
set sv_punkbuster "0" //Punkbuster, PB is not supported on CoD4x
set sv_pure "0" //check IWD-data 0 = off, 1 = on
// set g_antilag "1" //0 = off, 1 = on // Anti lag checks for weapon hits
// set ModStats 1 // 1 = use player stats file for mods (normal behaviours), 0 = use player stats file of basegame (DANGEROUS!!! as it can overwrite your stats)
// set ModStats "1" // 1 = use player stats file for mods (normal behaviours), 0 = use player stats file of basegame (DANGEROUS!!! as it can overwrite your stats)
@ -74,23 +68,23 @@ set sv_allowAnonymous "0" // Anonymous //0 = off 1 = on
// Maps
set sv_mapRotation "map mp_shipment" // maps that will be played automatically
// set sv_randomMapRotation 1 // 0 = sv_mapRotation is randomized, 1 = sequential order of sv_mapRotation
// set sv_randomMapRotation "1" // 0 = sv_mapRotation is randomized, 1 = sequential order of sv_mapRotation
set g_deadChat "1" // dead can chat // 0 = off, 1 = on
set voice_deadChat "0" // dead can use voicechat //0 = off, 1 = on
set g_gravity "800" //Gravity //Standard 800
set sv_disableClientConsole "0" //deactivate console for clients //0 = no, 1 = yes
set scr_teambalance "0" //auto-teambalance //0 = no, 1 = yes
set scr_teambalance "1" //auto-teambalance //0 = no, 1 = yes
set scr_team_fftype "0" //friendly-fire //0 = off, 1 = on, //2 = reflect damage, 3 = shared damage
set scr_game_spectatetype "2" // spectator // 0 = off, 1 = only Team/player, 2 = free
set scr_hardcore 0 //Hardcore Mode //0 = off 1 = on
set scr_hardcore "0" //Hardcore Mode //0 = off 1 = on
set scr_oldschool "0" //Oldschool Mode //0 = off, 1 = on
set g_friendlyPlayerCanBlock 0 // 1 = player collision between friendly players, 0 = collision between friendly players is disabled
set g_FFAPlayerCanBlock 1 // same for FFA (non team based) gamemode
set g_friendlyPlayerCanBlock "0" // 1 = player collision between friendly players, 0 = collision between friendly players is disabled
set g_FFAPlayerCanBlock "1" // same for FFA (non team based) gamemode
// Less interesting Gameplay stuff
set scr_drawfriend "1" //show team mates //0 = off, 1 = on
set scr_drawfriend "0" //show team mates //0 = off, 1 = on
set scr_enable_scoretext "1" //hit-message //0 = no, 1 = yes
set scr_game_allowkillcam "1" //Killcam //0 = no, 1 = yes // Allow to play killcam after you got killed
set scr_game_deathpointloss "0" //points-distraction when hit //0 = no, 1 = yes
@ -126,9 +120,9 @@ set scr_war_waverespawndelay "0"
//Domination (dom)
set scr_dom_scorelimit "300"
set scr_dom_timelimit "0"
set scr_dom_timelimit "30"
set scr_dom_numlives "0"
set scr_dom_playerrespawndelay "3"
set scr_dom_playerrespawndelay "0"
set scr_dom_roundlimit "1"
set scr_dom_waverespawndelay "0"
@ -177,10 +171,10 @@ set scr_sd_waverespawndelay "0"
set g_gametype "dom" // gamemode, one of [war, dm, sd, sab, koth]
// Amazing Stuff
//set sv_autodemorecord 1 // Records demos of players on the serverside, demos are stored in "demos" folder
set sv_autodemorecord "1" // Records demos of players on the serverside, demos are stored in "demos" folder
//set sv_demoCompletedCmd "" // program to execute when a demo has been saved
//set sv_screenshotArrivedCmd "" // program to execute when a screenshot was taken
//set sv_legacyguidmode 0 // 1 = old 32 character guids are used, 0 = new cod4x guid format is used ( like steamids )
//set sv_legacyguidmode "0" // 1 = old 32 character guids are used, 0 = new cod4x guid format is used ( like steamids )
///////////////////////////
// Setup for custom maps when running a mod
@ -190,7 +184,7 @@ seta sv_wwwDlDisconnected "1" // disconnect clients while downloading
///////////////////////////
set sv_nosteamnames 1 // 1 = Use names from steam if steam is available
set sv_nosteamnames "1" // 1 = Use names from steam if steam is available
set bots_manage_add "12"
set bots_main_firstIsHost "0"
@ -200,3 +194,5 @@ set bots_team_force "1"
set bots_loadout_allow_op "0"
set bots_loadout_reasonable "1"
set bots_manage_fill_spec "0"
exec config.cfg

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@ -0,0 +1,99 @@
# CoD4x Bot Warfare Waypoint Editor
First things first, Bot Warfare uses the [AStar search algorithm](https://en.wikipedia.org/wiki/A*_search_algorithm) for creating paths for the bots to find their way through a map.
The AStar search algorithm requires a [set of waypoints](https://en.wikipedia.org/wiki/Graph_(discrete_mathematics)) defining where all the paths are in the map.
Now if you want to modify existing or create new waypoints for CoD4x maps, this is the read for you.
## Contents
- [Setting up the Waypoint Editor](#Setting-up-the-Waypoint-Editor)
- [The Editor](#The-Editor)
## Setting up the Waypoint Editor
The Bot Warfare mod comes with the Waypoint Editor out of the box, so its just a matter of telling the mod you want to use it. Its a matter of setting the `bots_main_debug` DVAR to `1`.
Start your server with the Bot Warfare mod.
In the server console, type in ```set bots_main_debug 1```.<br>
![Setting the dvar](/main_shared/bw-assets/console.png)
Now start a match with the map you want to edit with the `devmap <mapname>` command.<br>
![Starting a map](/main_shared/bw-assets/console-map.png)
It should be noted that waypoints load in this following order;
1. checks the 'waypoints' folder (FS_Game\waypoints) for a csv file
2. loads the waypoints from GSC (maps\mp\bots\waypoints)
3. checks online at [this repo](https://github.com/ineedbots/cod4x_waypoints) for the waypoints (if httpget plugin loaded)
If all fail to load waypoints, there will be no waypoints and the bots will not know how to navigate the map.
Connect to the server with the CoD4x client, you'll be introduced to the Waypoint Editor.
## The Editor
![The editor](/main_shared/bw-assets/editor.png)<br>
This is the Waypoint Editor. You can view, edit and create the waypoint graph.
- Each red number you see in the world is a waypoint.
- The green string you see is the type of that waypoint.
- The green list of numbers are the waypoints linked to that waypoint.
- The pink lines show the links between the waypoints, a link defines that a bot can walk from A to B.
- The white lines show the 'angles' that a waypoint has, these are used for grenade, claymore and tube waypoints. It's used to tell the bot where to look at when grenading/claymoring, etc.
---
Pressing any of these buttons will initiate a command to the Waypoint Editor.
Each button has a secondary modifier button, and can be pressed shortly after pressing the primary button.
- SecondaryOffhand (stun) - Add Waypoint
- Press nothing - Make a waypoint of your stance
- ADS - Make a climb waypoint
- Attack + Use - Make a tube waypoint
- Attack - Make a grenade waypoint
- Use - Make a claymore waypoint
- Melee - Link Waypoint
- Press nothing - Link
- ADS - Unlink
- FragButton (grenade) - Delete Waypoint
- Press nothing - Delete Waypoint
- Attack - Delete all waypoints
- ADS - (Re)Load Waypoints
- UseButton + Attack - Save Waypoints
- Press nothing - Save waypoints
- ADS - Toggle autolink waypoints (links waypoints as you create them)
---
Okay, now that you know how to control the Editor, lets now go ahead and create some waypoints.
Here I added a waypoint.<br>
![Adding a waypoint](/main_shared/bw-assets/editor-addwp.png)
And I added a second waypoint.<br>
![Adding another waypoint](/main_shared/bw-assets/editor-addwp2.png)
There are several types of waypoints, holding a modifier button before pressing the add waypoint button will create a special type of waypoint.
- Types of waypoints:
- any stance ('stand', 'crouch', 'prone') - bots will have this stance upon reaching this waypoint
- grenade - bots will look at the angles you were looking at when you made the waypoint and throw a grenade from the waypoint
- tube - bots will look at the angles you were looking at when you made the waypoint and switch to a launcher and fire
- claymore - bots will look at the angles you were looking at when you made the waypoint and place a claymore or c4
- camp ('crouch' waypoint with only one linked waypoint) - bots will look at the angles you were looking at when you made the waypoint and camp
- climb - bots will look at the angles you were looking at when you made the waypoint and climb (use this for ladders and mantles)
Here I linked the two waypoints together.<br>
![Linking waypoints](/main_shared/bw-assets/editor-link.png)
Linking waypoints are very important, it tells the bots that they can reach waypoint 1 from waypoint 0, and vice versa.
Now go and waypoint the whole map out. This may take awhile and can be pretty tedious.
Once you feel like you are done, press the Save buttons. This will generate a [CSV](https://en.wikipedia.org/wiki/Comma-separated_values) output to your waypoints folder!
That is it! The waypoints should load next time you start your game!
Your waypoints CSV file will be located at ```<fs_game>/waypoints/<mapname>_wp.csv```. (main folder if fs_game is blank)<br>
![Location](/main_shared/bw-assets/saved.png)
You can share your waypoints publicly (and can be loaded by other users of Bot Warfare remotely) by making a Pull Request to the [CoD4x_Waypoints repo](https://github.com/ineedbots/cod4x_waypoints).

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -10,35 +10,35 @@
/*
Will attempt to retreive waypoints from the internet
*/
getRemoteWaypoints(mapname)
getRemoteWaypoints( mapname )
{
url = "https://raw.githubusercontent.com/ineedbots/cod4x_waypoints/master/" + mapname + "_wp.csv";
filename = "waypoints/" + mapname + "_wp.csv";
printToConsole("Attempting to get remote waypoints from " + url);
res = getLinesFromUrl(url, filename);
printToConsole( "Attempting to get remote waypoints from " + url );
res = getLinesFromUrl( url, filename );
if (!res.lines.size)
if ( !res.lines.size )
return;
waypointCount = int(res.lines[0]);
waypointCount = int( res.lines[0] );
waypoints = [];
printToConsole("Loading remote waypoints...");
printToConsole( "Loading remote waypoints..." );
for (i = 1; i <= waypointCount; i++)
for ( i = 1; i <= waypointCount; i++ )
{
tokens = tokenizeLine(res.lines[i], ",");
tokens = tokenizeLine( res.lines[i], "," );
waypoint = parseTokensIntoWaypoint(tokens);
waypoint = parseTokensIntoWaypoint( tokens );
waypoints[i-1] = waypoint;
waypoints[i - 1] = waypoint;
}
if (waypoints.size)
if ( waypoints.size )
{
level.waypoints = waypoints;
printToConsole("Loaded " + waypoints.size + " waypoints from remote.");
printToConsole( "Loaded " + waypoints.size + " waypoints from remote." );
}
}
@ -49,20 +49,20 @@ doVersionCheck()
{
remoteVersion = getRemoteVersion();
if (!isDefined(remoteVersion))
if ( !isDefined( remoteVersion ) )
{
printToConsole("Error getting remote version of Bot Warfare.");
printToConsole( "Error getting remote version of Bot Warfare." );
return false;
}
if (level.bw_VERSION != remoteVersion)
if ( level.bw_VERSION != remoteVersion )
{
printToConsole("There is a new version of Bot Warfare!");
printToConsole("You are on version " + level.bw_VERSION + " but " + remoteVersion + " is available!");
printToConsole( "There is a new version of Bot Warfare!" );
printToConsole( "You are on version " + level.bw_VERSION + " but " + remoteVersion + " is available!" );
return false;
}
printToConsole("You are on the latest version of Bot Warfare!");
printToConsole( "You are on the latest version of Bot Warfare!" );
return true;
}
@ -77,16 +77,16 @@ getRemoteVersion()
data = undefined;
#endif
if (!isDefined(data))
if ( !isDefined( data ) )
return undefined;
return strtok(data, "\n")[0];
return strtok( data, "\n" )[0];
}
/*
Returns an array of each line from the response of the http url request
*/
getLinesFromUrl(url, filename)
getLinesFromUrl( url, filename )
{
result = spawnStruct();
result.lines = [];
@ -97,25 +97,26 @@ getLinesFromUrl(url, filename)
data = undefined;
#endif
if (!isDefined(data))
if ( !isDefined( data ) )
return result;
fd = FS_FOpen(filename, "write");
fd = FS_FOpen( filename, "write" );
line = "";
for (i=0;i<data.size;i++)
for ( i = 0; i < data.size; i++ )
{
c = data[i];
if (c == "\n")
if ( c == "\n" )
{
result.lines[result.lines.size] = line;
if (fd > 0)
if ( fd > 0 )
{
if (!FS_WriteLine(fd, line))
if ( !FS_WriteLine( fd, line ) )
{
FS_FClose(fd);
FS_FClose( fd );
fd = 0;
}
}
@ -126,10 +127,11 @@ getLinesFromUrl(url, filename)
line += c;
}
result.lines[result.lines.size] = line;
if (fd > 0)
FS_FClose(fd);
if ( fd > 0 )
FS_FClose( fd );
return result;
}

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

File diff suppressed because it is too large Load Diff

View File

@ -12,80 +12,81 @@
init()
{
if(getDvar("bots_main_debug") == "")
setDvar("bots_main_debug", 0);
if ( getDvar( "bots_main_debug" ) == "" )
setDvar( "bots_main_debug", 0 );
if(!getDVarint("bots_main_debug"))
if ( !getDVarint( "bots_main_debug" ) )
return;
if(!getDVarint("developer"))
if ( !getDVarint( "developer" ) )
{
setdvar("developer_script", 1);
setdvar("developer", 1);
setdvar( "developer_script", 1 );
setdvar( "developer", 1 );
setdvar("sv_mapRotation", "map "+getDvar("mapname"));
exitLevel(false);
setdvar( "sv_mapRotation", "map " + getDvar( "mapname" ) );
exitLevel( false );
}
setDvar("bots_main", 0);
setdvar("bots_main_menu", 0);
setdvar("bots_manage_fill_mode", 0);
setdvar("bots_manage_fill", 0);
setdvar("bots_manage_add", 0);
setdvar("bots_manage_fill_kick", 1);
setDvar("bots_manage_fill_spec", 1);
setDvar( "bots_main", 0 );
setdvar( "bots_main_menu", 0 );
setdvar( "bots_manage_fill_mode", 0 );
setdvar( "bots_manage_fill", 0 );
setdvar( "bots_manage_add", 0 );
setdvar( "bots_manage_fill_kick", 1 );
setDvar( "bots_manage_fill_spec", 1 );
if (getDvar("bots_main_debug_distance") == "")
setDvar("bots_main_debug_distance", 512.0);
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_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_minDist" ) == "" )
setDvar( "bots_main_debug_minDist", 32.0 );
if (getDvar("bots_main_debug_drawThrough") == "")
setDvar("bots_main_debug_drawThrough", false);
if ( getDvar( "bots_main_debug_drawThrough" ) == "" )
setDvar( "bots_main_debug_drawThrough", false );
if(getDvar("bots_main_debug_commandWait") == "")
setDvar("bots_main_debug_commandWait", 0.5);
if ( getDvar( "bots_main_debug_commandWait" ) == "" )
setDvar( "bots_main_debug_commandWait", 0.5 );
if(getDvar("bots_main_debug_framerate") == "")
setDvar("bots_main_debug_framerate", 58);
if ( getDvar( "bots_main_debug_framerate" ) == "" )
setDvar( "bots_main_debug_framerate", 58 );
if(getDvar("bots_main_debug_lineDuration") == "")
setDvar("bots_main_debug_lineDuration", 3);
if ( getDvar( "bots_main_debug_lineDuration" ) == "" )
setDvar( "bots_main_debug_lineDuration", 3 );
if(getDvar("bots_main_debug_printDuration") == "")
setDvar("bots_main_debug_printDuration", 3);
if ( getDvar( "bots_main_debug_printDuration" ) == "" )
setDvar( "bots_main_debug_printDuration", 3 );
if(getDvar("bots_main_debug_debugRate") == "")
setDvar("bots_main_debug_debugRate", 0.5);
if ( getDvar( "bots_main_debug_debugRate" ) == "" )
setDvar( "bots_main_debug_debugRate", 0.5 );
setDvar("player_sustainAmmo", 1);
setDvar( "player_sustainAmmo", 1 );
level.waypoints = [];
level.waypointCount = 0;
level waittill( "connected", player);
level waittill( "connected", player );
player thread onPlayerSpawned();
}
onPlayerSpawned()
{
self endon("disconnect");
for(;;)
self endon( "disconnect" );
for ( ;; )
{
self waittill("spawned_player");
self waittill( "spawned_player" );
self thread beginDebug();
}
}
beginDebug()
{
self endon("disconnect");
self endon("death");
self endon( "disconnect" );
self endon( "death" );
level.wpToLink = -1;
level.autoLink = false;
@ -95,10 +96,10 @@ beginDebug()
self clearPerks();
self takeAllWeapons();
self.specialty = [];
self giveWeapon("m16_gl_mp");
self giveWeapon( "m16_gl_mp" );
self SetActionSlot( 3, "altMode" );
self giveWeapon("frag_grenade_mp");
self freezecontrols(false);
self giveWeapon( "frag_grenade_mp" );
self freezecontrols( false );
self thread debug();
self thread addWaypoints();
@ -107,266 +108,277 @@ beginDebug()
self thread watchSaveWaypointsCommand();
self thread sayExtras();
self thread textScroll("^1SecondaryOffhand - ^2Add Waypoint; ^3MeleeButton - ^4Link Waypoint; ^5FragButton - ^6Delete Waypoint; ^7UseButton + AttackButton - ^8Save");
self thread textScroll( "^1SecondaryOffhand - ^2Add Waypoint; ^3MeleeButton - ^4Link Waypoint; ^5FragButton - ^6Delete Waypoint; ^7UseButton + AttackButton - ^8Save" );
}
sayExtras()
{
self endon("disconnect");
self endon("death");
self iprintln("Making a crouch waypoint with only one link...");
self iprintln("Makes a camping waypoint.");
self endon( "disconnect" );
self endon( "death" );
self iprintln( "Making a crouch waypoint with only one link..." );
self iprintln( "Makes a camping waypoint." );
}
debug()
{
self endon("disconnect");
self endon("death");
self endon( "disconnect" );
self endon( "death" );
self setClientDvar("com_maxfps", getDvarInt("bots_main_debug_framerate"));
self setClientDvar( "com_maxfps", getDvarInt( "bots_main_debug_framerate" ) );
for(;;)
for ( ;; )
{
wait getDvarFloat("bots_main_debug_debugRate");
wait getDvarFloat( "bots_main_debug_debugRate" );
if(isDefined(self.command))
if ( isDefined( self.command ) )
continue;
closest = -1;
myEye = self getTagOrigin( "j_head" );
myAngles = self GetPlayerAngles();
for(i = 0; i < level.waypointCount; i++)
for ( i = 0; i < level.waypointCount; i++ )
{
if(closest == -1 || closer(self.origin, level.waypoints[i].origin, level.waypoints[closest].origin))
if ( closest == -1 || closer( self.origin, level.waypoints[i].origin, level.waypoints[closest].origin ) )
closest = i;
wpOrg = level.waypoints[i].origin + (0, 0, 25);
wpOrg = level.waypoints[i].origin + ( 0, 0, 25 );
if(distance(level.waypoints[i].origin, self.origin) < getDvarFloat("bots_main_debug_distance") && (bulletTracePassed(myEye, wpOrg, false, self) || getDVarint("bots_main_debug_drawThrough")))
if ( distance( level.waypoints[i].origin, self.origin ) < getDvarFloat( "bots_main_debug_distance" ) && ( bulletTracePassed( myEye, wpOrg, false, self ) || getDVarint( "bots_main_debug_drawThrough" ) ) )
{
for(h = 0; h < level.waypoints[i].childCount; h++)
line(wpOrg, level.waypoints[level.waypoints[i].children[h]].origin + (0, 0, 25), (1,0,1), 1, 1, getDvarInt("bots_main_debug_lineDuration"));
for ( h = level.waypoints[i].children.size - 1; h >= 0; h-- )
line( wpOrg, level.waypoints[level.waypoints[i].children[h]].origin + ( 0, 0, 25 ), ( 1, 0, 1 ), 1, 1, getDvarInt( "bots_main_debug_lineDuration" ) );
if(getConeDot(wpOrg, myEye, myAngles) > getDvarFloat("bots_main_debug_cone"))
print3d(wpOrg, i, (1,0,0), 2, 1, 6);
if ( getConeDot( wpOrg, myEye, myAngles ) > getDvarFloat( "bots_main_debug_cone" ) )
print3d( wpOrg, i, ( 1, 0, 0 ), 2, 1, 6 );
if (isDefined(level.waypoints[i].angles) && level.waypoints[i].type != "stand")
line(wpOrg, wpOrg + AnglesToForward(level.waypoints[i].angles) * 64, (1,1,1), 1, 1, getDvarInt("bots_main_debug_lineDuration"));
if ( isDefined( level.waypoints[i].angles ) && level.waypoints[i].type != "stand" )
line( wpOrg, wpOrg + AnglesToForward( level.waypoints[i].angles ) * 64, ( 1, 1, 1 ), 1, 1, getDvarInt( "bots_main_debug_lineDuration" ) );
}
}
self.closest = closest;
if(closest != -1)
if ( closest != -1 )
{
stringChildren = "";
for(i = 0; i < level.waypoints[closest].childCount; i++)
for ( i = 0; i < level.waypoints[closest].children.size; i++ )
{
if(i != 0)
if ( i != 0 )
stringChildren = stringChildren + "," + level.waypoints[closest].children[i];
else
stringChildren = stringChildren + level.waypoints[closest].children[i];
}
print3d(level.waypoints[closest].origin + (0, 0, 35), stringChildren, (0,1,0), 2, 1, getDvarInt("bots_main_debug_printDuration"));
print3d(level.waypoints[closest].origin + (0, 0, 15), level.waypoints[closest].type, (0,1,0), 2, 1, getDvarInt("bots_main_debug_printDuration"));
print3d( level.waypoints[closest].origin + ( 0, 0, 35 ), stringChildren, ( 0, 1, 0 ), 2, 1, getDvarInt( "bots_main_debug_printDuration" ) );
print3d( level.waypoints[closest].origin + ( 0, 0, 15 ), level.waypoints[closest].type, ( 0, 1, 0 ), 2, 1, getDvarInt( "bots_main_debug_printDuration" ) );
}
}
}
AddWaypoints()
{
self endon("disconnect");
self endon("death");
for(;;)
self endon( "disconnect" );
self endon( "death" );
for ( ;; )
{
while(!self SecondaryOffhandButtonPressed() || isDefined(self.command))
while ( !self SecondaryOffhandButtonPressed() || isDefined( self.command ) )
wait 0.05;
pos = self getOrigin();
self.command = true;
self iprintln("Adding a waypoint...");
self iprintln("ADS - climb; Attack + Use - tube");
self iprintln("Attack - grenade; Use - claymore");
self iprintln("Else(wait) - your stance");
self iprintln( "Adding a waypoint..." );
self iprintln( "ADS - climb; Attack + Use - tube" );
self iprintln( "Attack - grenade; Use - claymore" );
self iprintln( "Else(wait) - your stance" );
wait getDvarFloat("bots_main_debug_commandWait");
wait getDvarFloat( "bots_main_debug_commandWait" );
self addWaypoint(pos);
self addWaypoint( pos );
self.command = undefined;
while(self SecondaryOffhandButtonPressed())
while ( self SecondaryOffhandButtonPressed() )
wait 0.05;
}
}
linkWaypoints()
{
self endon("disconnect");
self endon("death");
for(;;)
self endon( "disconnect" );
self endon( "death" );
for ( ;; )
{
while(!self MeleeButtonPressed() || isDefined(self.command))
while ( !self MeleeButtonPressed() || isDefined( self.command ) )
wait 0.05;
self.command = true;
self iprintln("ADS - Unlink; Else(wait) - Link");
self iprintln( "ADS - Unlink; Else(wait) - Link" );
wait getDvarFloat("bots_main_debug_commandWait");
wait getDvarFloat( "bots_main_debug_commandWait" );
if(!self adsButtonPressed())
self LinkWaypoint(self.closest);
if ( !self adsButtonPressed() )
self LinkWaypoint( self.closest );
else
self UnLinkWaypoint(self.closest);
self UnLinkWaypoint( self.closest );
self.command = undefined;
while(self MeleeButtonPressed())
while ( self MeleeButtonPressed() )
wait 0.05;
}
}
deleteWaypoints()
{
self endon("disconnect");
self endon("death");
for(;;)
self endon( "disconnect" );
self endon( "death" );
for ( ;; )
{
while(!self fragButtonPressed() || isDefined(self.command))
while ( !self fragButtonPressed() || isDefined( self.command ) )
wait 0.05;
self.command = true;
self iprintln("Attack - DeleteAll; ADS - Load");
self iprintln("Else(wait) - Delete");
self iprintln( "Attack - DeleteAll; ADS - Load" );
self iprintln( "Else(wait) - Delete" );
wait getDvarFloat("bots_main_debug_commandWait");
wait getDvarFloat( "bots_main_debug_commandWait" );
if(self attackButtonPressed())
if ( self attackButtonPressed() )
self deleteAllWaypoints();
else if(self adsButtonPressed())
else if ( self adsButtonPressed() )
self LoadWaypoints();
else
self DeleteWaypoint(self.closest);
self DeleteWaypoint( self.closest );
self.command = undefined;
while(self fragButtonPressed())
while ( self fragButtonPressed() )
wait 0.05;
}
}
watchSaveWaypointsCommand()
{
self endon("death");
self endon("disconnect");
self endon( "death" );
self endon( "disconnect" );
for(;;)
for ( ;; )
{
while(!self useButtonPressed() || !self attackButtonPressed() || isDefined(self.command))
while ( !self useButtonPressed() || !self attackButtonPressed() || isDefined( self.command ) )
wait 0.05;
self.command = true;
self iprintln("ADS - Autolink; Else(wait) - Save");
self iprintln( "ADS - Autolink; Else(wait) - Save" );
wait getDvarFloat("bots_main_debug_commandWait");
wait getDvarFloat( "bots_main_debug_commandWait" );
if(!self adsButtonPressed())
if ( !self adsButtonPressed() )
{
self checkForWarnings();
wait 1;
logprint("***********ABiliTy's WPDump**************\n\n");
logprint("\n\n\n\n");
mpnm=getMapName(getdvar("mapname"));
logprint("\n\n"+mpnm+"()\n{\n/*");
logprint("*/waypoints = [];\n/*");
for(i = 0; i < level.waypointCount; i++)
logprint( "***********ABiliTy's WPDump**************\n\n" );
logprint( "\n\n\n\n" );
mpnm = getMapName( getdvar( "mapname" ) );
logprint( "\n\n" + mpnm + "()\n{\n/*" );
logprint( "*/waypoints = [];\n/*" );
for ( i = 0; i < level.waypointCount; i++ )
{
logprint("*/waypoints["+i+"] = spawnstruct();\n/*");
logprint("*/waypoints["+i+"].origin = "+level.waypoints[i].origin+";\n/*");
logprint("*/waypoints["+i+"].type = \""+level.waypoints[i].type+"\";\n/*");
logprint("*/waypoints["+i+"].childCount = "+level.waypoints[i].childCount+";\n/*");
for(c = 0; c < level.waypoints[i].childCount; c++)
logprint( "*/waypoints[" + i + "] = spawnstruct();\n/*" );
logprint( "*/waypoints[" + i + "].origin = " + level.waypoints[i].origin + ";\n/*" );
logprint( "*/waypoints[" + i + "].type = \"" + level.waypoints[i].type + "\";\n/*" );
for ( c = 0; c < level.waypoints[i].children.size; c++ )
{
logprint("*/waypoints["+i+"].children["+c+"] = "+level.waypoints[i].children[c]+";\n/*");
logprint( "*/waypoints[" + i + "].children[" + c + "] = " + level.waypoints[i].children[c] + ";\n/*" );
}
if(isDefined(level.waypoints[i].angles) && (level.waypoints[i].type == "claymore" || level.waypoints[i].type == "tube" || (level.waypoints[i].type == "crouch" && level.waypoints[i].childCount == 1) || level.waypoints[i].type == "climb" || level.waypoints[i].type == "grenade"))
logprint("*/waypoints["+i+"].angles = "+level.waypoints[i].angles+";\n/*");
if ( isDefined( level.waypoints[i].angles ) && ( level.waypoints[i].type == "claymore" || level.waypoints[i].type == "tube" || ( level.waypoints[i].type == "crouch" && level.waypoints[i].children.size == 1 ) || level.waypoints[i].type == "climb" || level.waypoints[i].type == "grenade" ) )
logprint( "*/waypoints[" + i + "].angles = " + level.waypoints[i].angles + ";\n/*" );
}
logprint("*/return waypoints;\n}\n\n\n\n");
filename = "waypoints/" + getdvar("mapname") + "_wp.csv";
fd = FS_FOpen(filename, "write");
logprint( "*/return waypoints;\n}\n\n\n\n" );
PrintLn("********* Start Bot Warfare WPDump *********");
PrintLn(level.waypointCount);
filename = "waypoints/" + getdvar( "mapname" ) + "_wp.csv";
fd = FS_FOpen( filename, "write" );
if (fd > 0)
PrintLn( "********* Start Bot Warfare WPDump *********" );
PrintLn( level.waypointCount );
if ( fd > 0 )
{
if (!FS_WriteLine(fd, level.waypointCount+""))
if ( !FS_WriteLine( fd, level.waypointCount + "" ) )
{
FS_FClose(fd);
FS_FClose( fd );
fd = 0;
}
}
for(i = 0; i < level.waypointCount; i++)
for ( i = 0; i < level.waypointCount; i++ )
{
str = "";
wp = level.waypoints[i];
str += wp.origin[0] + " " + wp.origin[1] + " " + wp.origin[2] + ",";
for(h = 0; h < wp.childCount; h++)
for ( h = 0; h < wp.children.size; h++ )
{
str += wp.children[h];
if (h < wp.childCount - 1)
if ( h < wp.children.size - 1 )
str += " ";
}
str += "," + wp.type + ",";
if (isDefined(wp.angles))
if ( isDefined( wp.angles ) )
str += wp.angles[0] + " " + wp.angles[1] + " " + wp.angles[2] + ",";
else
str += ",";
str += ",";
PrintLn(str);
PrintLn( str );
if (fd > 0)
if ( fd > 0 )
{
if (!FS_WriteLine(fd, str))
if ( !FS_WriteLine( fd, str ) )
{
FS_FClose(fd);
FS_FClose( fd );
fd = 0;
}
}
}
PrintLn("\n\n\n\n\n\n");
self iprintln("Saved!!! to " + filename);
PrintLn( "\n\n\n\n\n\n" );
if (fd > 0)
FS_FClose(fd);
self iprintln( "Saved!!! to " + filename );
if ( fd > 0 )
FS_FClose( fd );
}
else
{
if(level.autoLink)
if ( level.autoLink )
{
self iPrintlnBold("Auto link disabled");
self iPrintlnBold( "Auto link disabled" );
level.autoLink = false;
level.wpToLink = -1;
}
else
{
self iPrintlnBold("Auto link enabled");
self iPrintlnBold( "Auto link enabled" );
level.autoLink = true;
level.wpToLink = self.closest;
}
@ -374,7 +386,7 @@ watchSaveWaypointsCommand()
self.command = undefined;
while(self useButtonPressed() && self attackButtonPressed())
while ( self useButtonPressed() && self attackButtonPressed() )
wait 0.05;
}
}
@ -382,7 +394,7 @@ watchSaveWaypointsCommand()
LoadWaypoints()
{
self DeleteAllWaypoints();
self iPrintlnBold("Loading WPS...");
self iPrintlnBold( "Loading WPS..." );
load_waypoints();
wait 1;
@ -392,53 +404,50 @@ LoadWaypoints()
checkForWarnings()
{
if(level.waypointCount <= 0)
self iprintln("WARNING: waypointCount is "+level.waypointCount);
if ( level.waypointCount <= 0 )
self iprintln( "WARNING: waypointCount is " + level.waypointCount );
if(level.waypointCount != level.waypoints.size)
self iprintln("WARNING: waypointCount is not "+level.waypoints.size);
if ( level.waypointCount != level.waypoints.size )
self iprintln( "WARNING: waypointCount is not " + level.waypoints.size );
for(i = 0; i < level.waypointCount; i++)
for ( i = 0; i < level.waypointCount; i++ )
{
if(!isDefined(level.waypoints[i]))
if ( !isDefined( level.waypoints[i] ) )
{
self iprintln("WARNING: waypoint "+i+" is undefined");
self iprintln( "WARNING: waypoint " + i + " is undefined" );
continue;
}
if(level.waypoints[i].childCount <= 0)
self iprintln("WARNING: waypoint "+i+" childCount is "+level.waypoints[i].childCount);
if ( level.waypoints[i].children.size <= 0 )
self iprintln( "WARNING: waypoint " + i + " childCount is " + level.waypoints[i].children.size );
else
{
if (!isDefined(level.waypoints[i].children) || !isDefined(level.waypoints[i].children.size))
if ( !isDefined( level.waypoints[i].children ) || !isDefined( level.waypoints[i].children.size ) )
{
self iprintln("WARNING: waypoint "+i+" children is not defined");
self iprintln( "WARNING: waypoint " + i + " children is not defined" );
}
else
{
if(level.waypoints[i].childCount != level.waypoints[i].children.size)
self iprintln("WARNING: waypoint "+i+" childCount is not "+level.waypoints[i].children.size);
for (h = 0; h < level.waypoints[i].childCount; h++)
for ( h = level.waypoints[i].children.size - 1; h >= 0; h-- )
{
child = level.waypoints[i].children[h];
if(!isDefined(level.waypoints[child]))
self iprintln("WARNING: waypoint "+i+" child "+child+" is undefined");
else if(child == i)
self iprintln("WARNING: waypoint "+i+" child "+child+" is itself");
if ( !isDefined( level.waypoints[child] ) )
self iprintln( "WARNING: waypoint " + i + " child " + child + " is undefined" );
else if ( child == i )
self iprintln( "WARNING: waypoint " + i + " child " + child + " is itself" );
}
}
}
if(!isDefined(level.waypoints[i].type))
if ( !isDefined( level.waypoints[i].type ) )
{
self iprintln("WARNING: waypoint "+i+" type is undefined");
self iprintln( "WARNING: waypoint " + i + " type is undefined" );
continue;
}
if(!isDefined(level.waypoints[i].angles) && (level.waypoints[i].type == "claymore" || level.waypoints[i].type == "tube" || (level.waypoints[i].type == "crouch" && level.waypoints[i].childCount == 1) || level.waypoints[i].type == "climb" || level.waypoints[i].type == "grenade"))
self iprintln("WARNING: waypoint "+i+" angles is undefined");
if ( !isDefined( level.waypoints[i].angles ) && ( level.waypoints[i].type == "claymore" || level.waypoints[i].type == "tube" || ( level.waypoints[i].type == "crouch" && level.waypoints[i].children.size == 1 ) || level.waypoints[i].type == "climb" || level.waypoints[i].type == "grenade" ) )
self iprintln( "WARNING: waypoint " + i + " angles is undefined" );
}
}
@ -446,40 +455,32 @@ DeleteAllWaypoints()
{
level.waypoints = [];
level.waypointCount = 0;
level.waypointsKDTree = WaypointsToKDTree();
level.waypointsCamp = [];
level.waypointsTube = [];
level.waypointsGren = [];
level.waypointsClay = [];
self iprintln("DelAllWps");
self iprintln( "DelAllWps" );
}
DeleteWaypoint(nwp)
DeleteWaypoint( nwp )
{
if(nwp == -1 || distance(self.origin, level.waypoints[nwp].origin) > getDvarFloat("bots_main_debug_minDist"))
if ( nwp == -1 || distance( self.origin, level.waypoints[nwp].origin ) > getDvarFloat( "bots_main_debug_minDist" ) )
{
self iprintln("No close enough waypoint to delete.");
self iprintln( "No close enough waypoint to delete." );
return;
}
level.wpToLink = -1;
for(i = 0; i < level.waypoints[nwp].childCount; i++)
for ( i = level.waypoints[nwp].children.size - 1; i >= 0; i-- )
{
child = level.waypoints[nwp].children[i];
level.waypoints[child].children = array_remove(level.waypoints[child].children, nwp);
level.waypoints[child].childCount = level.waypoints[child].children.size;
level.waypoints[child].children = array_remove( level.waypoints[child].children, nwp );
}
for(i = 0; i < level.waypointCount; i++)
for ( i = 0; i < level.waypointCount; i++ )
{
for(h = 0; h < level.waypoints[i].childCount; h++)
for ( h = level.waypoints[i].children.size - 1; h >= 0; h-- )
{
if(level.waypoints[i].children[h] > nwp)
if ( level.waypoints[i].children[h] > nwp )
level.waypoints[i].children[h]--;
}
}
@ -488,33 +489,35 @@ DeleteWaypoint(nwp)
{
if ( entry == nwp )
{
while ( entry < level.waypointCount-1 )
while ( entry < level.waypointCount - 1 )
{
level.waypoints[entry] = level.waypoints[entry+1];
level.waypoints[entry] = level.waypoints[entry + 1];
entry++;
}
level.waypoints[entry] = undefined;
break;
}
}
level.waypointCount--;
self iprintln("DelWp "+nwp);
self iprintln( "DelWp " + nwp );
}
addWaypoint(pos)
addWaypoint( pos )
{
level.waypoints[level.waypointCount] = spawnstruct();
level.waypoints[level.waypointCount].origin = pos;
if(self AdsButtonPressed())
if ( self AdsButtonPressed() )
level.waypoints[level.waypointCount].type = "climb";
else if(self AttackButtonPressed() && self UseButtonPressed())
else if ( self AttackButtonPressed() && self UseButtonPressed() )
level.waypoints[level.waypointCount].type = "tube";
else if(self AttackButtonPressed())
else if ( self AttackButtonPressed() )
level.waypoints[level.waypointCount].type = "grenade";
else if(self UseButtonPressed())
else if ( self UseButtonPressed() )
level.waypoints[level.waypointCount].type = "claymore";
else
level.waypoints[level.waypointCount].type = self getStance();
@ -522,17 +525,16 @@ addWaypoint(pos)
level.waypoints[level.waypointCount].angles = self getPlayerAngles();
level.waypoints[level.waypointCount].children = [];
level.waypoints[level.waypointCount].childCount = 0;
self iprintln(level.waypoints[level.waypointCount].type + " Waypoint "+ level.waypointCount +" Added at "+pos);
self iprintln( level.waypoints[level.waypointCount].type + " Waypoint " + level.waypointCount + " Added at " + pos );
if(level.autoLink)
if ( level.autoLink )
{
if(level.wpToLink == -1)
if ( level.wpToLink == -1 )
level.wpToLink = level.waypointCount - 1;
level.waypointCount++;
self LinkWaypoint(level.waypointCount - 1);
self LinkWaypoint( level.waypointCount - 1 );
}
else
{
@ -540,62 +542,61 @@ addWaypoint(pos)
}
}
UnLinkWaypoint(nwp)
UnLinkWaypoint( nwp )
{
if(nwp == -1 || distance(self.origin, level.waypoints[nwp].origin) > getDvarFloat("bots_main_debug_minDist"))
if ( nwp == -1 || distance( self.origin, level.waypoints[nwp].origin ) > getDvarFloat( "bots_main_debug_minDist" ) )
{
self iprintln("Waypoint Unlink Cancelled "+level.wpToLink);
self iprintln( "Waypoint Unlink Cancelled " + level.wpToLink );
level.wpToLink = -1;
return;
}
if(level.wpToLink == -1 || nwp == level.wpToLink)
if ( level.wpToLink == -1 || nwp == level.wpToLink )
{
level.wpToLink = nwp;
self iprintln("Waypoint Unlink Started "+nwp);
self iprintln( "Waypoint Unlink Started " + nwp );
return;
}
level.waypoints[nwp].children = array_remove(level.waypoints[nwp].children, level.wpToLink);
level.waypoints[level.wpToLink].children = array_remove(level.waypoints[level.wpToLink].children, nwp);
level.waypoints[nwp].children = array_remove( level.waypoints[nwp].children, level.wpToLink );
level.waypoints[level.wpToLink].children = array_remove( level.waypoints[level.wpToLink].children, nwp );
level.waypoints[nwp].childCount = level.waypoints[nwp].children.size;
level.waypoints[level.wpToLink].childCount = level.waypoints[level.wpToLink].children.size;
self iprintln("Waypoint " + nwp + " Broken to " + level.wpToLink);
self iprintln( "Waypoint " + nwp + " Broken to " + level.wpToLink );
level.wpToLink = -1;
}
LinkWaypoint(nwp)
LinkWaypoint( nwp )
{
if(nwp == -1 || distance(self.origin, level.waypoints[nwp].origin) > getDvarFloat("bots_main_debug_minDist"))
if ( nwp == -1 || distance( self.origin, level.waypoints[nwp].origin ) > getDvarFloat( "bots_main_debug_minDist" ) )
{
self iprintln("Waypoint Link Cancelled "+level.wpToLink);
self iprintln( "Waypoint Link Cancelled " + level.wpToLink );
level.wpToLink = -1;
return;
}
if(level.wpToLink == -1 || nwp == level.wpToLink)
if ( level.wpToLink == -1 || nwp == level.wpToLink )
{
level.wpToLink = nwp;
self iprintln("Waypoint Link Started "+nwp);
self iprintln( "Waypoint Link Started " + nwp );
return;
}
weGood = true;
for(i = 0; i < level.waypoints[level.wpToLink].childCount; i++)
for ( i = level.waypoints[level.wpToLink].children.size - 1; i >= 0; i-- )
{
if(level.waypoints[level.wpToLink].children[i] == nwp)
if ( level.waypoints[level.wpToLink].children[i] == nwp )
{
weGood = false;
break;
}
}
if(weGood)
if ( weGood )
{
for(i = 0; i < level.waypoints[nwp].childCount; i++)
for ( i = level.waypoints[nwp].children.size - 1; i >= 0; i-- )
{
if(level.waypoints[nwp].children[i] == level.wpToLink)
if ( level.waypoints[nwp].children[i] == level.wpToLink )
{
weGood = false;
break;
@ -603,47 +604,45 @@ LinkWaypoint(nwp)
}
}
if (!weGood )
if ( !weGood )
{
self iprintln("Waypoint Link Cancelled "+nwp+" and "+level.wpToLink+" already linked.");
self iprintln( "Waypoint Link Cancelled " + nwp + " and " + level.wpToLink + " already linked." );
level.wpToLink = -1;
return;
}
level.waypoints[level.wpToLink].children[level.waypoints[level.wpToLink].childcount] = nwp;
level.waypoints[level.wpToLink].childcount++;
level.waypoints[nwp].children[level.waypoints[nwp].childcount] = level.wpToLink;
level.waypoints[nwp].childcount++;
level.waypoints[level.wpToLink].children[level.waypoints[level.wpToLink].children.size] = nwp;
level.waypoints[nwp].children[level.waypoints[nwp].children.size] = level.wpToLink;
self iprintln("Waypoint " + nwp + " Linked to " + level.wpToLink);
self iprintln( "Waypoint " + nwp + " Linked to " + level.wpToLink );
level.wpToLink = -1;
}
destroyOnDeath(hud)
destroyOnDeath( hud )
{
hud endon("death");
self waittill_either("death","disconnect");
hud endon( "death" );
self waittill_either( "death", "disconnect" );
hud destroy();
}
textScroll(string)
textScroll( string )
{
self endon("death");
self endon("disconnect");
self endon( "death" );
self endon( "disconnect" );
//thanks ActionScript
back = createBar((0,0,0), 1000, 30);
back setPoint("CENTER", undefined, 0, 220);
self thread destroyOnDeath(back);
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);
text = createFontString( "default", 1.5 );
text setText( string );
self thread destroyOnDeath( text );
for (;;)
for ( ;; )
{
text setPoint("CENTER", undefined, 1200, 220);
text setPoint("CENTER", undefined, -1200, 220, 20);
text setPoint( "CENTER", undefined, 1200, 220 );
text setPoint( "CENTER", undefined, -1200, 220, 20 );
wait 20;
}
}

View File

@ -17,6 +17,7 @@ CodeCallback_StartGameType()
level.gametypestarted = true; // so we know that the gametype has been started up
level thread maps\mp\bots\_bot::init();
level thread maps\mp\bots\_bot_chat::init();
level thread maps\mp\bots\_menu::init();
level thread maps\mp\bots\_wp_editor::init();
}

View File

@ -1 +1,7 @@
loadplugin "httpget"
set sv_hostname "^1Bot ^3War^5fare ^7Local server"
set sv_punkbuster "0"
set g_gametype "dom"
set sv_mapRotation "map mp_shipment"

File diff suppressed because it is too large Load Diff

View File

@ -10,35 +10,35 @@
/*
Will attempt to retreive waypoints from the internet
*/
getRemoteWaypoints(mapname)
getRemoteWaypoints( mapname )
{
url = "https://raw.githubusercontent.com/ineedbots/cod4x_waypoints/master/" + mapname + "_wp.csv";
filename = "waypoints/" + mapname + "_wp.csv";
printToConsole("Attempting to get remote waypoints from " + url);
res = getLinesFromUrl(url, filename);
printToConsole( "Attempting to get remote waypoints from " + url );
res = getLinesFromUrl( url, filename );
if (!res.lines.size)
if ( !res.lines.size )
return;
waypointCount = int(res.lines[0]);
waypointCount = int( res.lines[0] );
waypoints = [];
printToConsole("Loading remote waypoints...");
printToConsole( "Loading remote waypoints..." );
for (i = 1; i <= waypointCount; i++)
for ( i = 1; i <= waypointCount; i++ )
{
tokens = tokenizeLine(res.lines[i], ",");
tokens = tokenizeLine( res.lines[i], "," );
waypoint = parseTokensIntoWaypoint(tokens);
waypoint = parseTokensIntoWaypoint( tokens );
waypoints[i-1] = waypoint;
waypoints[i - 1] = waypoint;
}
if (waypoints.size)
if ( waypoints.size )
{
level.waypoints = waypoints;
printToConsole("Loaded " + waypoints.size + " waypoints from remote.");
printToConsole( "Loaded " + waypoints.size + " waypoints from remote." );
}
}
@ -49,20 +49,20 @@ doVersionCheck()
{
remoteVersion = getRemoteVersion();
if (!isDefined(remoteVersion))
if ( !isDefined( remoteVersion ) )
{
printToConsole("Error getting remote version of Bot Warfare.");
printToConsole( "Error getting remote version of Bot Warfare." );
return false;
}
if (level.bw_VERSION != remoteVersion)
if ( level.bw_VERSION != remoteVersion )
{
printToConsole("There is a new version of Bot Warfare!");
printToConsole("You are on version " + level.bw_VERSION + " but " + remoteVersion + " is available!");
printToConsole( "There is a new version of Bot Warfare!" );
printToConsole( "You are on version " + level.bw_VERSION + " but " + remoteVersion + " is available!" );
return false;
}
printToConsole("You are on the latest version of Bot Warfare!");
printToConsole( "You are on the latest version of Bot Warfare!" );
return true;
}
@ -77,16 +77,16 @@ getRemoteVersion()
data = undefined;
#endif
if (!isDefined(data))
if ( !isDefined( data ) )
return undefined;
return strtok(data, "\n")[0];
return strtok( data, "\n" )[0];
}
/*
Returns an array of each line from the response of the http url request
*/
getLinesFromUrl(url, filename)
getLinesFromUrl( url, filename )
{
result = spawnStruct();
result.lines = [];
@ -97,25 +97,26 @@ getLinesFromUrl(url, filename)
data = undefined;
#endif
if (!isDefined(data))
if ( !isDefined( data ) )
return result;
fd = FS_FOpen(filename, "write");
fd = FS_FOpen( filename, "write" );
line = "";
for (i=0;i<data.size;i++)
for ( i = 0; i < data.size; i++ )
{
c = data[i];
if (c == "\n")
if ( c == "\n" )
{
result.lines[result.lines.size] = line;
if (fd > 0)
if ( fd > 0 )
{
if (!FS_WriteLine(fd, line))
if ( !FS_WriteLine( fd, line ) )
{
FS_FClose(fd);
FS_FClose( fd );
fd = 0;
}
}
@ -126,10 +127,11 @@ getLinesFromUrl(url, filename)
line += c;
}
result.lines[result.lines.size] = line;
if (fd > 0)
FS_FClose(fd);
if ( fd > 0 )
FS_FClose( fd );
return result;
}

View File

@ -12,80 +12,81 @@
init()
{
if(getDvar("bots_main_debug") == "")
setDvar("bots_main_debug", 0);
if ( getDvar( "bots_main_debug" ) == "" )
setDvar( "bots_main_debug", 0 );
if(!getDVarint("bots_main_debug"))
if ( !getDVarint( "bots_main_debug" ) )
return;
if(!getDVarint("developer"))
if ( !getDVarint( "developer" ) )
{
setdvar("developer_script", 1);
setdvar("developer", 1);
setdvar( "developer_script", 1 );
setdvar( "developer", 1 );
setdvar("sv_mapRotation", "map "+getDvar("mapname"));
exitLevel(false);
setdvar( "sv_mapRotation", "map " + getDvar( "mapname" ) );
exitLevel( false );
}
setDvar("bots_main", 0);
setdvar("bots_main_menu", 0);
setdvar("bots_manage_fill_mode", 0);
setdvar("bots_manage_fill", 0);
setdvar("bots_manage_add", 0);
setdvar("bots_manage_fill_kick", 1);
setDvar("bots_manage_fill_spec", 1);
setDvar( "bots_main", 0 );
setdvar( "bots_main_menu", 0 );
setdvar( "bots_manage_fill_mode", 0 );
setdvar( "bots_manage_fill", 0 );
setdvar( "bots_manage_add", 0 );
setdvar( "bots_manage_fill_kick", 1 );
setDvar( "bots_manage_fill_spec", 1 );
if (getDvar("bots_main_debug_distance") == "")
setDvar("bots_main_debug_distance", 512.0);
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_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_minDist" ) == "" )
setDvar( "bots_main_debug_minDist", 32.0 );
if (getDvar("bots_main_debug_drawThrough") == "")
setDvar("bots_main_debug_drawThrough", false);
if ( getDvar( "bots_main_debug_drawThrough" ) == "" )
setDvar( "bots_main_debug_drawThrough", false );
if(getDvar("bots_main_debug_commandWait") == "")
setDvar("bots_main_debug_commandWait", 0.5);
if ( getDvar( "bots_main_debug_commandWait" ) == "" )
setDvar( "bots_main_debug_commandWait", 0.5 );
if(getDvar("bots_main_debug_framerate") == "")
setDvar("bots_main_debug_framerate", 58);
if ( getDvar( "bots_main_debug_framerate" ) == "" )
setDvar( "bots_main_debug_framerate", 58 );
if(getDvar("bots_main_debug_lineDuration") == "")
setDvar("bots_main_debug_lineDuration", 3);
if ( getDvar( "bots_main_debug_lineDuration" ) == "" )
setDvar( "bots_main_debug_lineDuration", 3 );
if(getDvar("bots_main_debug_printDuration") == "")
setDvar("bots_main_debug_printDuration", 3);
if ( getDvar( "bots_main_debug_printDuration" ) == "" )
setDvar( "bots_main_debug_printDuration", 3 );
if(getDvar("bots_main_debug_debugRate") == "")
setDvar("bots_main_debug_debugRate", 0.5);
if ( getDvar( "bots_main_debug_debugRate" ) == "" )
setDvar( "bots_main_debug_debugRate", 0.5 );
setDvar("player_sustainAmmo", 1);
setDvar( "player_sustainAmmo", 1 );
level.waypoints = [];
level.waypointCount = 0;
level waittill( "connected", player);
level waittill( "connected", player );
player thread onPlayerSpawned();
}
onPlayerSpawned()
{
self endon("disconnect");
for(;;)
self endon( "disconnect" );
for ( ;; )
{
self waittill("spawned_player");
self waittill( "spawned_player" );
self thread beginDebug();
}
}
beginDebug()
{
self endon("disconnect");
self endon("death");
self endon( "disconnect" );
self endon( "death" );
level.wpToLink = -1;
level.autoLink = false;
@ -95,10 +96,10 @@ beginDebug()
self clearPerks();
self takeAllWeapons();
self.specialty = [];
self giveWeapon("m16_gl_mp");
self giveWeapon( "m16_gl_mp" );
self SetActionSlot( 3, "altMode" );
self giveWeapon("frag_grenade_mp");
self freezecontrols(false);
self giveWeapon( "frag_grenade_mp" );
self freezecontrols( false );
self thread debug();
self thread addWaypoints();
@ -107,266 +108,277 @@ beginDebug()
self thread watchSaveWaypointsCommand();
self thread sayExtras();
self thread textScroll("^1SecondaryOffhand - ^2Add Waypoint; ^3MeleeButton - ^4Link Waypoint; ^5FragButton - ^6Delete Waypoint; ^7UseButton + AttackButton - ^8Save");
self thread textScroll( "^1SecondaryOffhand - ^2Add Waypoint; ^3MeleeButton - ^4Link Waypoint; ^5FragButton - ^6Delete Waypoint; ^7UseButton + AttackButton - ^8Save" );
}
sayExtras()
{
self endon("disconnect");
self endon("death");
self iprintln("Making a crouch waypoint with only one link...");
self iprintln("Makes a camping waypoint.");
self endon( "disconnect" );
self endon( "death" );
self iprintln( "Making a crouch waypoint with only one link..." );
self iprintln( "Makes a camping waypoint." );
}
debug()
{
self endon("disconnect");
self endon("death");
self endon( "disconnect" );
self endon( "death" );
self setClientDvar("com_maxfps", getDvarInt("bots_main_debug_framerate"));
self setClientDvar( "com_maxfps", getDvarInt( "bots_main_debug_framerate" ) );
for(;;)
for ( ;; )
{
wait getDvarFloat("bots_main_debug_debugRate");
wait getDvarFloat( "bots_main_debug_debugRate" );
if(isDefined(self.command))
if ( isDefined( self.command ) )
continue;
closest = -1;
myEye = self getTagOrigin( "j_head" );
myAngles = self GetPlayerAngles();
for(i = 0; i < level.waypointCount; i++)
for ( i = 0; i < level.waypointCount; i++ )
{
if(closest == -1 || closer(self.origin, level.waypoints[i].origin, level.waypoints[closest].origin))
if ( closest == -1 || closer( self.origin, level.waypoints[i].origin, level.waypoints[closest].origin ) )
closest = i;
wpOrg = level.waypoints[i].origin + (0, 0, 25);
wpOrg = level.waypoints[i].origin + ( 0, 0, 25 );
if(distance(level.waypoints[i].origin, self.origin) < getDvarFloat("bots_main_debug_distance") && (bulletTracePassed(myEye, wpOrg, false, self) || getDVarint("bots_main_debug_drawThrough")))
if ( distance( level.waypoints[i].origin, self.origin ) < getDvarFloat( "bots_main_debug_distance" ) && ( bulletTracePassed( myEye, wpOrg, false, self ) || getDVarint( "bots_main_debug_drawThrough" ) ) )
{
for(h = 0; h < level.waypoints[i].childCount; h++)
line(wpOrg, level.waypoints[level.waypoints[i].children[h]].origin + (0, 0, 25), (1,0,1), 1, 1, getDvarInt("bots_main_debug_lineDuration"));
for ( h = level.waypoints[i].children.size - 1; h >= 0; h-- )
line( wpOrg, level.waypoints[level.waypoints[i].children[h]].origin + ( 0, 0, 25 ), ( 1, 0, 1 ), 1, 1, getDvarInt( "bots_main_debug_lineDuration" ) );
if(getConeDot(wpOrg, myEye, myAngles) > getDvarFloat("bots_main_debug_cone"))
print3d(wpOrg, i, (1,0,0), 2, 1, 6);
if ( getConeDot( wpOrg, myEye, myAngles ) > getDvarFloat( "bots_main_debug_cone" ) )
print3d( wpOrg, i, ( 1, 0, 0 ), 2, 1, 6 );
if (isDefined(level.waypoints[i].angles) && level.waypoints[i].type != "stand")
line(wpOrg, wpOrg + AnglesToForward(level.waypoints[i].angles) * 64, (1,1,1), 1, 1, getDvarInt("bots_main_debug_lineDuration"));
if ( isDefined( level.waypoints[i].angles ) && level.waypoints[i].type != "stand" )
line( wpOrg, wpOrg + AnglesToForward( level.waypoints[i].angles ) * 64, ( 1, 1, 1 ), 1, 1, getDvarInt( "bots_main_debug_lineDuration" ) );
}
}
self.closest = closest;
if(closest != -1)
if ( closest != -1 )
{
stringChildren = "";
for(i = 0; i < level.waypoints[closest].childCount; i++)
for ( i = 0; i < level.waypoints[closest].children.size; i++ )
{
if(i != 0)
if ( i != 0 )
stringChildren = stringChildren + "," + level.waypoints[closest].children[i];
else
stringChildren = stringChildren + level.waypoints[closest].children[i];
}
print3d(level.waypoints[closest].origin + (0, 0, 35), stringChildren, (0,1,0), 2, 1, getDvarInt("bots_main_debug_printDuration"));
print3d(level.waypoints[closest].origin + (0, 0, 15), level.waypoints[closest].type, (0,1,0), 2, 1, getDvarInt("bots_main_debug_printDuration"));
print3d( level.waypoints[closest].origin + ( 0, 0, 35 ), stringChildren, ( 0, 1, 0 ), 2, 1, getDvarInt( "bots_main_debug_printDuration" ) );
print3d( level.waypoints[closest].origin + ( 0, 0, 15 ), level.waypoints[closest].type, ( 0, 1, 0 ), 2, 1, getDvarInt( "bots_main_debug_printDuration" ) );
}
}
}
AddWaypoints()
{
self endon("disconnect");
self endon("death");
for(;;)
self endon( "disconnect" );
self endon( "death" );
for ( ;; )
{
while(!self SecondaryOffhandButtonPressed() || isDefined(self.command))
while ( !self SecondaryOffhandButtonPressed() || isDefined( self.command ) )
wait 0.05;
pos = self getOrigin();
self.command = true;
self iprintln("Adding a waypoint...");
self iprintln("ADS - climb; Attack + Use - tube");
self iprintln("Attack - grenade; Use - claymore");
self iprintln("Else(wait) - your stance");
self iprintln( "Adding a waypoint..." );
self iprintln( "ADS - climb; Attack + Use - tube" );
self iprintln( "Attack - grenade; Use - claymore" );
self iprintln( "Else(wait) - your stance" );
wait getDvarFloat("bots_main_debug_commandWait");
wait getDvarFloat( "bots_main_debug_commandWait" );
self addWaypoint(pos);
self addWaypoint( pos );
self.command = undefined;
while(self SecondaryOffhandButtonPressed())
while ( self SecondaryOffhandButtonPressed() )
wait 0.05;
}
}
linkWaypoints()
{
self endon("disconnect");
self endon("death");
for(;;)
self endon( "disconnect" );
self endon( "death" );
for ( ;; )
{
while(!self MeleeButtonPressed() || isDefined(self.command))
while ( !self MeleeButtonPressed() || isDefined( self.command ) )
wait 0.05;
self.command = true;
self iprintln("ADS - Unlink; Else(wait) - Link");
self iprintln( "ADS - Unlink; Else(wait) - Link" );
wait getDvarFloat("bots_main_debug_commandWait");
wait getDvarFloat( "bots_main_debug_commandWait" );
if(!self adsButtonPressed())
self LinkWaypoint(self.closest);
if ( !self adsButtonPressed() )
self LinkWaypoint( self.closest );
else
self UnLinkWaypoint(self.closest);
self UnLinkWaypoint( self.closest );
self.command = undefined;
while(self MeleeButtonPressed())
while ( self MeleeButtonPressed() )
wait 0.05;
}
}
deleteWaypoints()
{
self endon("disconnect");
self endon("death");
for(;;)
self endon( "disconnect" );
self endon( "death" );
for ( ;; )
{
while(!self fragButtonPressed() || isDefined(self.command))
while ( !self fragButtonPressed() || isDefined( self.command ) )
wait 0.05;
self.command = true;
self iprintln("Attack - DeleteAll; ADS - Load");
self iprintln("Else(wait) - Delete");
self iprintln( "Attack - DeleteAll; ADS - Load" );
self iprintln( "Else(wait) - Delete" );
wait getDvarFloat("bots_main_debug_commandWait");
wait getDvarFloat( "bots_main_debug_commandWait" );
if(self attackButtonPressed())
if ( self attackButtonPressed() )
self deleteAllWaypoints();
else if(self adsButtonPressed())
else if ( self adsButtonPressed() )
self LoadWaypoints();
else
self DeleteWaypoint(self.closest);
self DeleteWaypoint( self.closest );
self.command = undefined;
while(self fragButtonPressed())
while ( self fragButtonPressed() )
wait 0.05;
}
}
watchSaveWaypointsCommand()
{
self endon("death");
self endon("disconnect");
self endon( "death" );
self endon( "disconnect" );
for(;;)
for ( ;; )
{
while(!self useButtonPressed() || !self attackButtonPressed() || isDefined(self.command))
while ( !self useButtonPressed() || !self attackButtonPressed() || isDefined( self.command ) )
wait 0.05;
self.command = true;
self iprintln("ADS - Autolink; Else(wait) - Save");
self iprintln( "ADS - Autolink; Else(wait) - Save" );
wait getDvarFloat("bots_main_debug_commandWait");
wait getDvarFloat( "bots_main_debug_commandWait" );
if(!self adsButtonPressed())
if ( !self adsButtonPressed() )
{
self checkForWarnings();
wait 1;
logprint("***********ABiliTy's WPDump**************\n\n");
logprint("\n\n\n\n");
mpnm=getMapName(getdvar("mapname"));
logprint("\n\n"+mpnm+"()\n{\n/*");
logprint("*/waypoints = [];\n/*");
for(i = 0; i < level.waypointCount; i++)
logprint( "***********ABiliTy's WPDump**************\n\n" );
logprint( "\n\n\n\n" );
mpnm = getMapName( getdvar( "mapname" ) );
logprint( "\n\n" + mpnm + "()\n{\n/*" );
logprint( "*/waypoints = [];\n/*" );
for ( i = 0; i < level.waypointCount; i++ )
{
logprint("*/waypoints["+i+"] = spawnstruct();\n/*");
logprint("*/waypoints["+i+"].origin = "+level.waypoints[i].origin+";\n/*");
logprint("*/waypoints["+i+"].type = \""+level.waypoints[i].type+"\";\n/*");
logprint("*/waypoints["+i+"].childCount = "+level.waypoints[i].childCount+";\n/*");
for(c = 0; c < level.waypoints[i].childCount; c++)
logprint( "*/waypoints[" + i + "] = spawnstruct();\n/*" );
logprint( "*/waypoints[" + i + "].origin = " + level.waypoints[i].origin + ";\n/*" );
logprint( "*/waypoints[" + i + "].type = \"" + level.waypoints[i].type + "\";\n/*" );
for ( c = 0; c < level.waypoints[i].children.size; c++ )
{
logprint("*/waypoints["+i+"].children["+c+"] = "+level.waypoints[i].children[c]+";\n/*");
logprint( "*/waypoints[" + i + "].children[" + c + "] = " + level.waypoints[i].children[c] + ";\n/*" );
}
if(isDefined(level.waypoints[i].angles) && (level.waypoints[i].type == "claymore" || level.waypoints[i].type == "tube" || (level.waypoints[i].type == "crouch" && level.waypoints[i].childCount == 1) || level.waypoints[i].type == "climb" || level.waypoints[i].type == "grenade"))
logprint("*/waypoints["+i+"].angles = "+level.waypoints[i].angles+";\n/*");
if ( isDefined( level.waypoints[i].angles ) && ( level.waypoints[i].type == "claymore" || level.waypoints[i].type == "tube" || ( level.waypoints[i].type == "crouch" && level.waypoints[i].children.size == 1 ) || level.waypoints[i].type == "climb" || level.waypoints[i].type == "grenade" ) )
logprint( "*/waypoints[" + i + "].angles = " + level.waypoints[i].angles + ";\n/*" );
}
logprint("*/return waypoints;\n}\n\n\n\n");
filename = "waypoints/" + getdvar("mapname") + "_wp.csv";
fd = FS_FOpen(filename, "write");
logprint( "*/return waypoints;\n}\n\n\n\n" );
PrintLn("********* Start Bot Warfare WPDump *********");
PrintLn(level.waypointCount);
filename = "waypoints/" + getdvar( "mapname" ) + "_wp.csv";
fd = FS_FOpen( filename, "write" );
if (fd > 0)
PrintLn( "********* Start Bot Warfare WPDump *********" );
PrintLn( level.waypointCount );
if ( fd > 0 )
{
if (!FS_WriteLine(fd, level.waypointCount+""))
if ( !FS_WriteLine( fd, level.waypointCount + "" ) )
{
FS_FClose(fd);
FS_FClose( fd );
fd = 0;
}
}
for(i = 0; i < level.waypointCount; i++)
for ( i = 0; i < level.waypointCount; i++ )
{
str = "";
wp = level.waypoints[i];
str += wp.origin[0] + " " + wp.origin[1] + " " + wp.origin[2] + ",";
for(h = 0; h < wp.childCount; h++)
for ( h = 0; h < wp.children.size; h++ )
{
str += wp.children[h];
if (h < wp.childCount - 1)
if ( h < wp.children.size - 1 )
str += " ";
}
str += "," + wp.type + ",";
if (isDefined(wp.angles))
if ( isDefined( wp.angles ) )
str += wp.angles[0] + " " + wp.angles[1] + " " + wp.angles[2] + ",";
else
str += ",";
str += ",";
PrintLn(str);
PrintLn( str );
if (fd > 0)
if ( fd > 0 )
{
if (!FS_WriteLine(fd, str))
if ( !FS_WriteLine( fd, str ) )
{
FS_FClose(fd);
FS_FClose( fd );
fd = 0;
}
}
}
PrintLn("\n\n\n\n\n\n");
self iprintln("Saved!!! to " + filename);
PrintLn( "\n\n\n\n\n\n" );
if (fd > 0)
FS_FClose(fd);
self iprintln( "Saved!!! to " + filename );
if ( fd > 0 )
FS_FClose( fd );
}
else
{
if(level.autoLink)
if ( level.autoLink )
{
self iPrintlnBold("Auto link disabled");
self iPrintlnBold( "Auto link disabled" );
level.autoLink = false;
level.wpToLink = -1;
}
else
{
self iPrintlnBold("Auto link enabled");
self iPrintlnBold( "Auto link enabled" );
level.autoLink = true;
level.wpToLink = self.closest;
}
@ -374,7 +386,7 @@ watchSaveWaypointsCommand()
self.command = undefined;
while(self useButtonPressed() && self attackButtonPressed())
while ( self useButtonPressed() && self attackButtonPressed() )
wait 0.05;
}
}
@ -382,7 +394,7 @@ watchSaveWaypointsCommand()
LoadWaypoints()
{
self DeleteAllWaypoints();
self iPrintlnBold("Loading WPS...");
self iPrintlnBold( "Loading WPS..." );
load_waypoints();
wait 1;
@ -392,53 +404,50 @@ LoadWaypoints()
checkForWarnings()
{
if(level.waypointCount <= 0)
self iprintln("WARNING: waypointCount is "+level.waypointCount);
if ( level.waypointCount <= 0 )
self iprintln( "WARNING: waypointCount is " + level.waypointCount );
if(level.waypointCount != level.waypoints.size)
self iprintln("WARNING: waypointCount is not "+level.waypoints.size);
if ( level.waypointCount != level.waypoints.size )
self iprintln( "WARNING: waypointCount is not " + level.waypoints.size );
for(i = 0; i < level.waypointCount; i++)
for ( i = 0; i < level.waypointCount; i++ )
{
if(!isDefined(level.waypoints[i]))
if ( !isDefined( level.waypoints[i] ) )
{
self iprintln("WARNING: waypoint "+i+" is undefined");
self iprintln( "WARNING: waypoint " + i + " is undefined" );
continue;
}
if(level.waypoints[i].childCount <= 0)
self iprintln("WARNING: waypoint "+i+" childCount is "+level.waypoints[i].childCount);
if ( level.waypoints[i].children.size <= 0 )
self iprintln( "WARNING: waypoint " + i + " childCount is " + level.waypoints[i].children.size );
else
{
if (!isDefined(level.waypoints[i].children) || !isDefined(level.waypoints[i].children.size))
if ( !isDefined( level.waypoints[i].children ) || !isDefined( level.waypoints[i].children.size ) )
{
self iprintln("WARNING: waypoint "+i+" children is not defined");
self iprintln( "WARNING: waypoint " + i + " children is not defined" );
}
else
{
if(level.waypoints[i].childCount != level.waypoints[i].children.size)
self iprintln("WARNING: waypoint "+i+" childCount is not "+level.waypoints[i].children.size);
for (h = 0; h < level.waypoints[i].childCount; h++)
for ( h = level.waypoints[i].children.size - 1; h >= 0; h-- )
{
child = level.waypoints[i].children[h];
if(!isDefined(level.waypoints[child]))
self iprintln("WARNING: waypoint "+i+" child "+child+" is undefined");
else if(child == i)
self iprintln("WARNING: waypoint "+i+" child "+child+" is itself");
if ( !isDefined( level.waypoints[child] ) )
self iprintln( "WARNING: waypoint " + i + " child " + child + " is undefined" );
else if ( child == i )
self iprintln( "WARNING: waypoint " + i + " child " + child + " is itself" );
}
}
}
if(!isDefined(level.waypoints[i].type))
if ( !isDefined( level.waypoints[i].type ) )
{
self iprintln("WARNING: waypoint "+i+" type is undefined");
self iprintln( "WARNING: waypoint " + i + " type is undefined" );
continue;
}
if(!isDefined(level.waypoints[i].angles) && (level.waypoints[i].type == "claymore" || level.waypoints[i].type == "tube" || (level.waypoints[i].type == "crouch" && level.waypoints[i].childCount == 1) || level.waypoints[i].type == "climb" || level.waypoints[i].type == "grenade"))
self iprintln("WARNING: waypoint "+i+" angles is undefined");
if ( !isDefined( level.waypoints[i].angles ) && ( level.waypoints[i].type == "claymore" || level.waypoints[i].type == "tube" || ( level.waypoints[i].type == "crouch" && level.waypoints[i].children.size == 1 ) || level.waypoints[i].type == "climb" || level.waypoints[i].type == "grenade" ) )
self iprintln( "WARNING: waypoint " + i + " angles is undefined" );
}
}
@ -446,40 +455,32 @@ DeleteAllWaypoints()
{
level.waypoints = [];
level.waypointCount = 0;
level.waypointsKDTree = WaypointsToKDTree();
level.waypointsCamp = [];
level.waypointsTube = [];
level.waypointsGren = [];
level.waypointsClay = [];
self iprintln("DelAllWps");
self iprintln( "DelAllWps" );
}
DeleteWaypoint(nwp)
DeleteWaypoint( nwp )
{
if(nwp == -1 || distance(self.origin, level.waypoints[nwp].origin) > getDvarFloat("bots_main_debug_minDist"))
if ( nwp == -1 || distance( self.origin, level.waypoints[nwp].origin ) > getDvarFloat( "bots_main_debug_minDist" ) )
{
self iprintln("No close enough waypoint to delete.");
self iprintln( "No close enough waypoint to delete." );
return;
}
level.wpToLink = -1;
for(i = 0; i < level.waypoints[nwp].childCount; i++)
for ( i = level.waypoints[nwp].children.size - 1; i >= 0; i-- )
{
child = level.waypoints[nwp].children[i];
level.waypoints[child].children = array_remove(level.waypoints[child].children, nwp);
level.waypoints[child].childCount = level.waypoints[child].children.size;
level.waypoints[child].children = array_remove( level.waypoints[child].children, nwp );
}
for(i = 0; i < level.waypointCount; i++)
for ( i = 0; i < level.waypointCount; i++ )
{
for(h = 0; h < level.waypoints[i].childCount; h++)
for ( h = level.waypoints[i].children.size - 1; h >= 0; h-- )
{
if(level.waypoints[i].children[h] > nwp)
if ( level.waypoints[i].children[h] > nwp )
level.waypoints[i].children[h]--;
}
}
@ -488,33 +489,35 @@ DeleteWaypoint(nwp)
{
if ( entry == nwp )
{
while ( entry < level.waypointCount-1 )
while ( entry < level.waypointCount - 1 )
{
level.waypoints[entry] = level.waypoints[entry+1];
level.waypoints[entry] = level.waypoints[entry + 1];
entry++;
}
level.waypoints[entry] = undefined;
break;
}
}
level.waypointCount--;
self iprintln("DelWp "+nwp);
self iprintln( "DelWp " + nwp );
}
addWaypoint(pos)
addWaypoint( pos )
{
level.waypoints[level.waypointCount] = spawnstruct();
level.waypoints[level.waypointCount].origin = pos;
if(self AdsButtonPressed())
if ( self AdsButtonPressed() )
level.waypoints[level.waypointCount].type = "climb";
else if(self AttackButtonPressed() && self UseButtonPressed())
else if ( self AttackButtonPressed() && self UseButtonPressed() )
level.waypoints[level.waypointCount].type = "tube";
else if(self AttackButtonPressed())
else if ( self AttackButtonPressed() )
level.waypoints[level.waypointCount].type = "grenade";
else if(self UseButtonPressed())
else if ( self UseButtonPressed() )
level.waypoints[level.waypointCount].type = "claymore";
else
level.waypoints[level.waypointCount].type = self getStance();
@ -522,17 +525,16 @@ addWaypoint(pos)
level.waypoints[level.waypointCount].angles = self getPlayerAngles();
level.waypoints[level.waypointCount].children = [];
level.waypoints[level.waypointCount].childCount = 0;
self iprintln(level.waypoints[level.waypointCount].type + " Waypoint "+ level.waypointCount +" Added at "+pos);
self iprintln( level.waypoints[level.waypointCount].type + " Waypoint " + level.waypointCount + " Added at " + pos );
if(level.autoLink)
if ( level.autoLink )
{
if(level.wpToLink == -1)
if ( level.wpToLink == -1 )
level.wpToLink = level.waypointCount - 1;
level.waypointCount++;
self LinkWaypoint(level.waypointCount - 1);
self LinkWaypoint( level.waypointCount - 1 );
}
else
{
@ -540,62 +542,61 @@ addWaypoint(pos)
}
}
UnLinkWaypoint(nwp)
UnLinkWaypoint( nwp )
{
if(nwp == -1 || distance(self.origin, level.waypoints[nwp].origin) > getDvarFloat("bots_main_debug_minDist"))
if ( nwp == -1 || distance( self.origin, level.waypoints[nwp].origin ) > getDvarFloat( "bots_main_debug_minDist" ) )
{
self iprintln("Waypoint Unlink Cancelled "+level.wpToLink);
self iprintln( "Waypoint Unlink Cancelled " + level.wpToLink );
level.wpToLink = -1;
return;
}
if(level.wpToLink == -1 || nwp == level.wpToLink)
if ( level.wpToLink == -1 || nwp == level.wpToLink )
{
level.wpToLink = nwp;
self iprintln("Waypoint Unlink Started "+nwp);
self iprintln( "Waypoint Unlink Started " + nwp );
return;
}
level.waypoints[nwp].children = array_remove(level.waypoints[nwp].children, level.wpToLink);
level.waypoints[level.wpToLink].children = array_remove(level.waypoints[level.wpToLink].children, nwp);
level.waypoints[nwp].children = array_remove( level.waypoints[nwp].children, level.wpToLink );
level.waypoints[level.wpToLink].children = array_remove( level.waypoints[level.wpToLink].children, nwp );
level.waypoints[nwp].childCount = level.waypoints[nwp].children.size;
level.waypoints[level.wpToLink].childCount = level.waypoints[level.wpToLink].children.size;
self iprintln("Waypoint " + nwp + " Broken to " + level.wpToLink);
self iprintln( "Waypoint " + nwp + " Broken to " + level.wpToLink );
level.wpToLink = -1;
}
LinkWaypoint(nwp)
LinkWaypoint( nwp )
{
if(nwp == -1 || distance(self.origin, level.waypoints[nwp].origin) > getDvarFloat("bots_main_debug_minDist"))
if ( nwp == -1 || distance( self.origin, level.waypoints[nwp].origin ) > getDvarFloat( "bots_main_debug_minDist" ) )
{
self iprintln("Waypoint Link Cancelled "+level.wpToLink);
self iprintln( "Waypoint Link Cancelled " + level.wpToLink );
level.wpToLink = -1;
return;
}
if(level.wpToLink == -1 || nwp == level.wpToLink)
if ( level.wpToLink == -1 || nwp == level.wpToLink )
{
level.wpToLink = nwp;
self iprintln("Waypoint Link Started "+nwp);
self iprintln( "Waypoint Link Started " + nwp );
return;
}
weGood = true;
for(i = 0; i < level.waypoints[level.wpToLink].childCount; i++)
for ( i = level.waypoints[level.wpToLink].children.size - 1; i >= 0; i-- )
{
if(level.waypoints[level.wpToLink].children[i] == nwp)
if ( level.waypoints[level.wpToLink].children[i] == nwp )
{
weGood = false;
break;
}
}
if(weGood)
if ( weGood )
{
for(i = 0; i < level.waypoints[nwp].childCount; i++)
for ( i = level.waypoints[nwp].children.size - 1; i >= 0; i-- )
{
if(level.waypoints[nwp].children[i] == level.wpToLink)
if ( level.waypoints[nwp].children[i] == level.wpToLink )
{
weGood = false;
break;
@ -603,47 +604,45 @@ LinkWaypoint(nwp)
}
}
if (!weGood )
if ( !weGood )
{
self iprintln("Waypoint Link Cancelled "+nwp+" and "+level.wpToLink+" already linked.");
self iprintln( "Waypoint Link Cancelled " + nwp + " and " + level.wpToLink + " already linked." );
level.wpToLink = -1;
return;
}
level.waypoints[level.wpToLink].children[level.waypoints[level.wpToLink].childcount] = nwp;
level.waypoints[level.wpToLink].childcount++;
level.waypoints[nwp].children[level.waypoints[nwp].childcount] = level.wpToLink;
level.waypoints[nwp].childcount++;
level.waypoints[level.wpToLink].children[level.waypoints[level.wpToLink].children.size] = nwp;
level.waypoints[nwp].children[level.waypoints[nwp].children.size] = level.wpToLink;
self iprintln("Waypoint " + nwp + " Linked to " + level.wpToLink);
self iprintln( "Waypoint " + nwp + " Linked to " + level.wpToLink );
level.wpToLink = -1;
}
destroyOnDeath(hud)
destroyOnDeath( hud )
{
hud endon("death");
self waittill_either("death","disconnect");
hud endon( "death" );
self waittill_either( "death", "disconnect" );
hud destroy();
}
textScroll(string)
textScroll( string )
{
self endon("death");
self endon("disconnect");
self endon( "death" );
self endon( "disconnect" );
//thanks ActionScript
back = createBar((0,0,0), 1000, 30);
back setPoint("CENTER", undefined, 0, 220);
self thread destroyOnDeath(back);
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);
text = createFontString( "default", 1.5 );
text setText( string );
self thread destroyOnDeath( text );
for (;;)
for ( ;; )
{
text setPoint("CENTER", undefined, 1200, 220);
text setPoint("CENTER", undefined, -1200, 220, 20);
text setPoint( "CENTER", undefined, 1200, 220 );
text setPoint( "CENTER", undefined, -1200, 220, 20 );
wait 20;
}
}

View File

@ -1 +1 @@
start "" "%~dp0cod4x18_dedrun.exe" +set dedicated "1" +set sv_maxclients "64" +set sv_punkbuster "0" +set net_port "28965" +set fs_game "mods/bots" +exec localbotserver.cfg +loadplugin httpget +map_rotate
start "" "%~dp0cod4x18_dedrun.exe" +set dedicated "1" +set sv_maxclients "64" +set net_port "28965" +set fs_game "mods/bots" +exec localbotserver.cfg +map_rotate

View File

@ -1,4 +1,4 @@
# CoD4x Bot Warfare
# CoD4x Bot Warfare v2.1.0
Bot Warfare is a GSC mod for the CoD4x project.
It aims to add playable AI to the multiplayer games of CoD4.
@ -12,7 +12,7 @@ Make sure to disable this DVAR by adding 'set bots_main_firstIsHost 0' in your s
## Installation
0. Make sure that CoD4x server + client is installed, updated and working properly.
- Go to https://cod4x.me/ and download the Windows Server zip file. Move the contents of 'cod4x-windows-server' into your CoD4 game folder.
- Go to https://cod4x.ovh/ and download the Windows Server zip file. Move the contents of 'cod4x-windows-server' into your CoD4 game folder.
1. Locate your CoD4x server install folder.
2. Move the files/folders found in 'Add to root of CoD4x server' from the Bot Warfare release archive you downloaded to the root of your CoD4x server folder.
- The folder/file structure should follow as '.CoD4x server folder\main_shared\maps\mp\bots\_bot.gsc'.
@ -30,6 +30,17 @@ Make sure to disable this DVAR by adding 'set bots_main_firstIsHost 0' in your s
- Pressing the menu button again closes menus.
## Changelog
- v2.1.0
- Bot chatter system, bots_main_chat
- Greatly reduce script variable usage
- Improved bots mantling and stuck
- Fix some runtime errors
- Bots sprint more
- Improved bots sight on enemies
- Bots do random actions while waiting at an objective
- Improved bots from getting stuck
- Better bot difficulty management, bots_skill_min and bots_skill_max
- v2.0.1
- Reduced bots crouching
- Increased bots sprinting

BIN
out/ss.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 MiB

View File

@ -1 +0,0 @@
start "" "%~dp0iw3mp.exe" +set r_fullscreen "1" +set cg_drawlagometer "0" +set cg_drawfps "0" +set cg_drawsnapshot "0" +set r_mode "1920x1080" +set r_monitor "0"

1
z_deploy.bat Normal file
View File

@ -0,0 +1 @@
start "" "node" deploy.js

View File

@ -1 +0,0 @@
start "" "%~dp0iw3mp.exe" +set r_fullscreen "0" +set cg_drawlagometer "1" +set developer "1" +set developer_script "1" +set logfile "2" +set cg_drawfps "3" +set cg_drawsnapshot "1" +set scr_game_spectatetype "2" +set r_mode "1024x768" +set thereisacow "1" +set sv_cheats "1" +set fs_game "mods/dev" +devmap mp_shipment

View File

@ -1 +0,0 @@
start "" "%~dp0iw3mp.exe" +set r_fullscreen "0" +set cg_drawlagometer "1" +set developer "1" +set developer_script "1" +set logfile "2" +set cg_drawfps "3" +set cg_drawsnapshot "1" +set scr_game_spectatetype "2" +set r_mode "1024x768" +set thereisacow "1" +set fs_game "mods/dev" +set sv_cheats "1" +connect 127.0.0.1

View File

@ -1 +1,30 @@
start "" "%~dp0cod4x18_dedrun.exe" +set dedicated "2" +set sv_maxclients "64" +set sv_punkbuster "0" +set net_port "28960" +set fs_game "mods/bots" +exec server.cfg +loadplugin httpget +map_rotate
@echo off
::Paste the server key from https://platform.plutonium.pw/serverkeys here
set key=
::RemoteCONtrol password, needed for most management tools like IW4MADMIN and B3. Do not skip if you installing IW4MADMIN.
set rcon_password=
::Name of the config file the server should use.
set cfg=server.cfg
::Name of the server shown in the title of the cmd window. This will NOT bet shown ingame.
set name=CoD4x Bot Warfare
::Port used by the server (default: 28960)
set port=28969
::What ip to bind too
set ip=0.0.0.0
::Mod name (default "")
set mod=
::Only change this when you don't want to keep the bat files in the game folder. MOST WON'T NEED TO EDIT THIS!
set gamepath=%cd%
::Max clients in your server
set maxclients=64
title CoD4x MP - %name% - Server restarter
echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates!
echo Server "%name%" will load "%cfg%" and listen on port "%port%" UDP with IP "%ip%"!
echo To shut down the server close this window first!
echo (%date%) - (%time%) %name% server start.
:server
start /wait /abovenormal "%name%" "%~dp0cod4x18_dedrun.exe" +set dedicated "2" +set sv_authtoken "%key%" +set net_ip "%ip%" +set net_port "%port%" +set rcon_password "%rcon_password%" +set fs_game "%mod%" +set sv_maxclients "%maxclients%" +exec "%cfg%" +map_rotate
echo (%date%) - (%time%) WARNING: %name% server closed or dropped... server restarts.
goto Server

View File

@ -1 +0,0 @@
start "" "%~dp0cod4x18_dedrun_dbg.exe" +set dedicated "1" +set developer "1" +set developer_script "1" +set logfile "2" +set scr_game_spectatetype "2" +set thereisacow "1" +set sv_cheats "1" +set sv_maxclients "64" +set fs_game "mods/dev" +set bots_manage_add "12" +set sv_punkbuster "0" +set scr_war_scorelimit "0" +set net_port "28960" +devmap mp_shipment