Compare commits
89 Commits
Author | SHA1 | Date | |
---|---|---|---|
14b161b3ed | |||
edd674fdbe | |||
4258aa872b | |||
45e13c60ad | |||
58fdabc2cf | |||
fa835e7ff1 | |||
11f170073c | |||
257ffd6d61 | |||
38eba8089f | |||
1e055b5bf5 | |||
4db478c8f1 | |||
86477e579f | |||
dd635903c6 | |||
cda591313e | |||
d0e67be25a | |||
a66e849dfe | |||
07bbe8aade | |||
e032ecd4c8 | |||
5dbfb2f2ad | |||
d5cdb98ffb | |||
7f9f9d0eb6 | |||
4d56d1e77f | |||
a0d443c295 | |||
d641264cca | |||
9b1158341b | |||
cf034fce87 | |||
f438568a70 | |||
bcf607e2f3 | |||
6619087af1 | |||
5892e46daa | |||
b6991b3754 | |||
b877ecffda | |||
4cdde8e7a5 | |||
0884902695 | |||
bdea53b670 | |||
8f5f1e0572 | |||
d90a1a29b8 | |||
cf377c976e | |||
a4819bacf4 | |||
ed8fd1db01 | |||
a11119abe3 | |||
26e0344a56 | |||
10576118ee | |||
2e10706c4c | |||
7d8ed25cdc | |||
831a63032b | |||
95755e1749 | |||
30eae3d3d9 | |||
bb74baec06 | |||
cc9c873ce7 | |||
fb6daae114 | |||
d435111091 | |||
417faa0353 | |||
65eaedd9d4 | |||
8d108b0fc5 | |||
e3253d291a | |||
ea26141601 | |||
84768fce13 | |||
2e145d7093 | |||
87744ba13a | |||
837bec9c73 | |||
5d9c90cc25 | |||
93ce2ae1b5 | |||
cf40501f60 | |||
979d1135be | |||
5afc002126 | |||
6225ae74fb | |||
ca71fbee4b | |||
4059b373c2 | |||
73dc1c17b1 | |||
f41ab46747 | |||
1d26bbd492 | |||
52f1062793 | |||
9744ff6ccd | |||
3c7e07866f | |||
f0aa54189d | |||
ff413d513b | |||
795ed863f6 | |||
861430e884 | |||
a9ccf1bcbd | |||
9d0bc09dee | |||
e7e13bffc0 | |||
edc183c7e2 | |||
dbe69a395a | |||
1578001094 | |||
1718f7c37a | |||
49597887f3 | |||
ad07563755 | |||
2e775d9fb2 |
21
.astylerc
Normal 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
@ -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
|
13
.gitignore
vendored
@ -3,18 +3,21 @@
|
||||
|
||||
# Files to not ignore
|
||||
!/.gitignore
|
||||
!/.vscode
|
||||
!/.editorconfig
|
||||
!/.gitattributes
|
||||
|
||||
!/z_client.bat
|
||||
!/z_dev.bat
|
||||
!/z_devserver.bat
|
||||
!/z_server.bat
|
||||
!/z_serverdev.bat
|
||||
!/z_bots.bat
|
||||
!/README.md
|
||||
!/out
|
||||
|
||||
*.zip
|
||||
|
||||
!/.astylerc
|
||||
!/z_deploy.bat
|
||||
!/deploy.bat
|
||||
!/deploy.js
|
||||
|
||||
!/main/
|
||||
!/main_shared/
|
||||
/main/*
|
||||
|
15
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"astyle.astylerc": "${workspaceRoot}/.astylerc",
|
||||
"astyle.additional_languages": [
|
||||
"gsc"
|
||||
],
|
||||
"[gsc]": {
|
||||
"editor.defaultFormatter": "chiehyu.vscode-astyle",
|
||||
},
|
||||
"editor.quickSuggestions": {
|
||||
"other": true,
|
||||
"comments": true,
|
||||
"strings": true
|
||||
},
|
||||
"vscode-codscript.use_builtin_completionItems": false
|
||||
}
|
160
README.md
@ -1,7 +1,7 @@
|
||||

|
||||
|
||||
# T4M Bot Warfare
|
||||
Bot Warfare is a GSC mod for the [T4M project](https://github.com/ineedbots/T4M).
|
||||
Bot Warfare is a GSC mod for the [T4M project](https://github.com/ineedbots/T4M) and [PlutoniumT4 project](https://plutonium.pw/).
|
||||
|
||||
It aims to add playable AI to the multiplayer games of World at War.
|
||||
|
||||
@ -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,9 +57,7 @@ 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
|
||||
T4M requires an unpacked steamless version of the multiplayer World at War executable (otherwise known as LanFixed). You can use a [Steam Unpacker](https://github.com/atom0s/Steamless) on your multiplayer World at War Steam executable to acquire the required executable.
|
||||
|
||||
0. Make sure that [T4M](https://github.com/ineedbots/T4M) is installed, updated and working properly.
|
||||
0. Make sure that [Plutonium T4](https://plutonium.pw/docs/install/) is installed, updated and working properly.
|
||||
- Download the [latest release](https://github.com/ineedbots/t4m_bot_warfare/releases) of Bot Warfare.
|
||||
1. Extract all the files from the Bot Warfare release archive you downloaded to anywhere on your computer.
|
||||
2. Run the 'install.bat'. This copies the mod to your WaW mods folder.
|
||||
@ -78,96 +76,82 @@ T4M requires an unpacked steamless version of the multiplayer World at War execu
|
||||
- Pressing the menu buttons 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.
|
||||
|
||||
- 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_loadout_prestige - an integer number, bots will be this prestige, -1 is the same as player, -2 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
|
||||
| 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_loadout_prestige | What prestige to set the bots.<ul><li>`-1` - Same as host player in the match.</li><li>`-2` - All random.</li><li>`0` or higher - Sets the bots' prestige 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 |
|
||||
|
||||
## 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
|
||||
- Improved bots mantling, crouching and knifing glass when needed
|
||||
- Fixed possible script runtime errors
|
||||
- Improved domination
|
||||
- Bots use explosives more if they have it
|
||||
- Bots aim slower when ads'ing
|
||||
- Fixed bots holding breath
|
||||
- Fixed bots rubberbanding movement when their goal changes
|
||||
- Added bots quickscoping with snipers
|
||||
- Added bots reload canceling and fast swaps
|
||||
- Bots use C4
|
||||
- Improved revenge
|
||||
- Bots can swap weapons on spawn more likely
|
||||
|
||||
- v2.0.0
|
||||
- Initial reboot release
|
||||
|
||||
## Credits
|
||||
- iAmThatMichael - https://github.com/iAmThatMichael/T4M
|
||||
- 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
|
||||
|
4
deploy.bat
Normal file
@ -0,0 +1,4 @@
|
||||
xcopy t4m_bot_warfare\main_shared\maps main_shared\maps\ /Y /I /E /H /C
|
||||
xcopy t4m_bot_warfare\main_shared\waypoints main_shared\waypoints\ /Y /I /E /H /C
|
||||
xcopy t4m_bot_warfare\main main\ /Y /I /E /H /C
|
||||
xcopy t4m_bot_warfare\main_shared\bots.txt main_shared\ /Y /I /H /C
|
54
deploy.js
Normal file
@ -0,0 +1,54 @@
|
||||
// nodejs 14+
|
||||
|
||||
const exec = require('util').promisify(require('child_process').exec)
|
||||
|
||||
const repo_name = 't4m_bot_warfare'
|
||||
const repo_url = `https://github.com/ineedbots/${repo_name}`
|
||||
const deploy_check_rate = 60000
|
||||
const title = 'T4M 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)
|
@ -2,7 +2,7 @@
|
||||
// Color Codes
|
||||
//******************************************************************************
|
||||
// Colors for text. Do not clear the comment in front of the color codes.
|
||||
// Useful for your server name, motd msg's - Information and ref use only
|
||||
// Useful for your server name, motd msgs - Information and ref use only
|
||||
//
|
||||
// ^1 = Red
|
||||
// ^2 = Green
|
||||
@ -26,11 +26,12 @@ sets _modver ""
|
||||
sets _modupdate ""
|
||||
set scr_motd "^1Bot ^3War^5fare"
|
||||
|
||||
set sv_maxclients "64"
|
||||
|
||||
//******************************************************************************
|
||||
// Common Server Settings
|
||||
//******************************************************************************
|
||||
// Password Settings
|
||||
set rcon_password "qazqaz"
|
||||
set sv_privatepassword ""
|
||||
set g_password ""
|
||||
set scr_xpscale_ "10"
|
||||
@ -250,7 +251,7 @@ set sv_maprotation "gametype dom map mp_dome"
|
||||
// Additional DVAR's
|
||||
//******************************************************************************
|
||||
// There are simply too many DVAR's for AGrcon to explicitly list and index
|
||||
// for you. All additional DVAR's (such as weapon configs and player configs) are
|
||||
// for you. All additional DVARs (such as weapon configs and player configs) are
|
||||
// listed below.
|
||||
|
||||
// WEAPONS / ATTACHMENTS
|
||||
|
BIN
main_shared/bw-assets/console.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
main_shared/bw-assets/disable_pb.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
main_shared/bw-assets/editor-addwp.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
main_shared/bw-assets/editor-addwp2.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
main_shared/bw-assets/editor-link.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
main_shared/bw-assets/editor.png
Normal file
After Width: | Height: | Size: 1.5 MiB |
BIN
main_shared/bw-assets/saved.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
96
main_shared/bw-assets/wpedit.md
Normal file
@ -0,0 +1,96 @@
|
||||
# T4M 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 World at War 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 game, and load up the Bot Warfare mod. Now open your console with tilde(~).
|
||||
|
||||
In the console, type in ```set bots_main_debug 1```.<br>
|
||||

|
||||
|
||||
Now start a match with the map you want to edit.
|
||||
|
||||
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/t4m_waypoints) for the waypoints
|
||||
|
||||
If all fail to load waypoints, there will be no waypoints and the bots will not know how to navigate the map.
|
||||
|
||||
## The Editor
|
||||
<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, betty and tube waypoints. It's used to tell the bot where to look at when grenading/betty, 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>
|
||||

|
||||
|
||||
And I added a second waypoint.<br>
|
||||

|
||||
|
||||
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 betty or a charge
|
||||
- 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 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>
|
||||

|
||||
|
||||
You can share your waypoints publicly (and can be loaded by other users of Bot Warfare remotely) by making a Pull Request to the [T4M_Waypoints repo](https://github.com/ineedbots/t4m_waypoints).
|
2273
main_shared/maps/mp/bots/_bot_chat.gsc
Normal file
@ -10,36 +10,36 @@
|
||||
/*
|
||||
Will attempt to retreive waypoints from the internet
|
||||
*/
|
||||
getRemoteWaypoints(mapname)
|
||||
getRemoteWaypoints( mapname )
|
||||
{
|
||||
url = "https://raw.githubusercontent.com/ineedbots/t4m_waypoints/master/" + mapname + "_wp.csv";
|
||||
url = "https://raw.githubusercontent.com/ineedbots/t4m_waypoints/master/" + mapname + "_wp.csv";
|
||||
filename = "waypoints/" + mapname + "_wp.csv";
|
||||
|
||||
PrintConsole("Attempting to get remote waypoints from " + url + "\n");
|
||||
res = getLinesFromUrl(url, filename);
|
||||
PrintConsole( "Attempting to get remote waypoints from " + url + "\n" );
|
||||
res = getLinesFromUrl( url, filename );
|
||||
|
||||
if (!res.lines.size)
|
||||
return;
|
||||
if ( !res.lines.size )
|
||||
return;
|
||||
|
||||
waypointCount = int(res.lines[0]);
|
||||
waypointCount = int( res.lines[0] );
|
||||
|
||||
waypoints = [];
|
||||
PrintConsole("Loading remote waypoints...\n");
|
||||
PrintConsole( "Loading remote waypoints...\n" );
|
||||
|
||||
for (i = 1; i <= waypointCount; i++)
|
||||
{
|
||||
tokens = tokenizeLine(res.lines[i], ",");
|
||||
for ( i = 1; i <= waypointCount; i++ )
|
||||
{
|
||||
tokens = tokenizeLine( res.lines[i], "," );
|
||||
|
||||
waypoint = parseTokensIntoWaypoint(tokens);
|
||||
waypoint = parseTokensIntoWaypoint( tokens );
|
||||
|
||||
waypoints[i-1] = waypoint;
|
||||
}
|
||||
waypoints[i - 1] = waypoint;
|
||||
}
|
||||
|
||||
if (waypoints.size)
|
||||
{
|
||||
level.waypoints = waypoints;
|
||||
PrintConsole("Loaded " + waypoints.size + " waypoints from remote.\n");
|
||||
}
|
||||
if ( waypoints.size )
|
||||
{
|
||||
level.waypoints = waypoints;
|
||||
PrintConsole( "Loaded " + waypoints.size + " waypoints from remote.\n" );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -49,20 +49,20 @@ doVersionCheck()
|
||||
{
|
||||
remoteVersion = getRemoteVersion();
|
||||
|
||||
if (!isDefined(remoteVersion))
|
||||
if ( !isDefined( remoteVersion ) )
|
||||
{
|
||||
PrintConsole("Error getting remote version of Bot Warfare.\n");
|
||||
PrintConsole( "Error getting remote version of Bot Warfare.\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if (level.bw_VERSION != remoteVersion)
|
||||
if ( level.bw_VERSION != remoteVersion )
|
||||
{
|
||||
PrintConsole("There is a new version of Bot Warfare!\n");
|
||||
PrintConsole("You are on version " + level.bw_VERSION + " but " + remoteVersion + " is available!\n");
|
||||
PrintConsole( "There is a new version of Bot Warfare!\n" );
|
||||
PrintConsole( "You are on version " + level.bw_VERSION + " but " + remoteVersion + " is available!\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
PrintConsole("You are on the latest version of Bot Warfare!\n");
|
||||
PrintConsole( "You are on the latest version of Bot Warfare!\n" );
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -71,35 +71,36 @@ doVersionCheck()
|
||||
*/
|
||||
getRemoteVersion()
|
||||
{
|
||||
data = httpGet( "https://raw.githubusercontent.com/ineedbots/t4m_waypoints/master/version.txt" );
|
||||
data = httpGet( "https://raw.githubusercontent.com/ineedbots/t4m_waypoints/master/version.txt" );
|
||||
|
||||
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 = [];
|
||||
result = spawnStruct();
|
||||
result.lines = [];
|
||||
|
||||
data = HTTPGet(url);
|
||||
data = HTTPGet( url );
|
||||
|
||||
if (!isDefined(data))
|
||||
if ( !isDefined( data ) )
|
||||
return result;
|
||||
|
||||
fileWrite(filename, data, "write");
|
||||
fileWrite( filename, data, "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;
|
||||
|
||||
@ -109,7 +110,8 @@ getLinesFromUrl(url, filename)
|
||||
|
||||
line += c;
|
||||
}
|
||||
result.lines[result.lines.size] = line;
|
||||
|
||||
result.lines[result.lines.size] = line;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -12,68 +12,69 @@
|
||||
|
||||
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 );
|
||||
|
||||
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;
|
||||
@ -83,10 +84,10 @@ beginDebug()
|
||||
self clearPerks();
|
||||
self takeAllWeapons();
|
||||
self.specialty = [];
|
||||
self giveWeapon("m1garand_gl_mp");
|
||||
self giveWeapon( "m1garand_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();
|
||||
@ -95,253 +96,264 @@ 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" );
|
||||
|
||||
for(;;)
|
||||
for ( ;; )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
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));
|
||||
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 ) );
|
||||
|
||||
if(getConeDot(wpOrg, myEye, myAngles) > getDvarFloat("bots_main_debug_cone"))
|
||||
print3d(wpOrg, i, (1,0,0), 2);
|
||||
if ( getConeDot( wpOrg, myEye, myAngles ) > getDvarFloat( "bots_main_debug_cone" ) )
|
||||
print3d( wpOrg, i, ( 1, 0, 0 ), 2 );
|
||||
|
||||
if (isDefined(level.waypoints[i].angles) && level.waypoints[i].type != "stand")
|
||||
line(wpOrg, wpOrg + AnglesToForward(level.waypoints[i].angles) * 64, (1,1,1));
|
||||
if ( isDefined( level.waypoints[i].angles ) && level.waypoints[i].type != "stand" )
|
||||
line( wpOrg, wpOrg + AnglesToForward( level.waypoints[i].angles ) * 64, ( 1, 1, 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
print3d(level.waypoints[closest].origin + (0, 0, 15), level.waypoints[closest].type, (0,1,0), 2);
|
||||
print3d( level.waypoints[closest].origin + ( 0, 0, 35 ), stringChildren, ( 0, 1, 0 ), 2 );
|
||||
|
||||
print3d( level.waypoints[closest].origin + ( 0, 0, 15 ), level.waypoints[closest].type, ( 0, 1, 0 ), 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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";
|
||||
logprint( "*/return waypoints;\n}\n\n\n\n" );
|
||||
|
||||
PrintLn("********* Start Bot Warfare WPDump *********");
|
||||
PrintLn(level.waypointCount);
|
||||
filename = "waypoints/" + getdvar( "mapname" ) + "_wp.csv";
|
||||
|
||||
fileWrite(filename, level.waypointCount+"\n", "write");
|
||||
for(i = 0; i < level.waypointCount; i++)
|
||||
PrintLn( "********* Start Bot Warfare WPDump *********" );
|
||||
PrintLn( level.waypointCount );
|
||||
|
||||
fileWrite( filename, level.waypointCount + "\n", "write" );
|
||||
|
||||
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);
|
||||
fileWrite(filename, str+"\n", "append");
|
||||
PrintLn( str );
|
||||
fileWrite( filename, str + "\n", "append" );
|
||||
}
|
||||
PrintLn("\n\n\n\n\n\n");
|
||||
|
||||
self iprintln("Saved!!! to " + filename);
|
||||
PrintLn( "\n\n\n\n\n\n" );
|
||||
|
||||
self iprintln( "Saved!!! to " + filename );
|
||||
}
|
||||
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.nearest;
|
||||
level.wpToLink = self.closest;
|
||||
}
|
||||
}
|
||||
|
||||
self.command = undefined;
|
||||
|
||||
while(self useButtonPressed() && self attackButtonPressed())
|
||||
while ( self useButtonPressed() && self attackButtonPressed() )
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
@ -349,7 +361,7 @@ watchSaveWaypointsCommand()
|
||||
LoadWaypoints()
|
||||
{
|
||||
self DeleteAllWaypoints();
|
||||
self iPrintlnBold("Loading WPS...");
|
||||
self iPrintlnBold( "Loading WPS..." );
|
||||
load_waypoints();
|
||||
|
||||
wait 1;
|
||||
@ -359,53 +371,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" );
|
||||
}
|
||||
}
|
||||
|
||||
@ -414,33 +423,31 @@ DeleteAllWaypoints()
|
||||
level.waypoints = [];
|
||||
level.waypointCount = 0;
|
||||
|
||||
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]--;
|
||||
}
|
||||
}
|
||||
@ -449,33 +456,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();
|
||||
@ -483,17 +492,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
|
||||
{
|
||||
@ -501,62 +509,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;
|
||||
@ -564,49 +571,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 notify("death");
|
||||
hud endon( "death" );
|
||||
self waittill_either( "death", "disconnect" );
|
||||
hud destroy();
|
||||
hud = undefined;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ init()
|
||||
{
|
||||
level.clientid = 0;
|
||||
|
||||
level.allowPrintDamage = true;
|
||||
|
||||
level thread onPlayerConnect();
|
||||
|
||||
wait 1;
|
||||
@ -20,5 +22,7 @@ onPlayerConnect()
|
||||
|
||||
player.clientid = level.clientid;
|
||||
level.clientid++; // Is this safe? What if a server runs for a long time and many people join/leave
|
||||
|
||||
player.printDamage = true;
|
||||
}
|
||||
}
|
||||
|
7817
main_shared/maps/mp/gametypes/_globallogic.gsc
Normal file
@ -1,4 +1,4 @@
|
||||
# T4M Bot Warfare
|
||||
# T4M Bot Warfare v2.1.0
|
||||
Bot Warfare is a GSC mod for the T4M project.
|
||||
|
||||
It aims to add playable AI to the multiplayer games of World at War.
|
||||
@ -11,14 +11,12 @@ This is so inexperienced users of the mod can access with menu without any confi
|
||||
Make sure to disable this DVAR by adding 'set bots_main_firstIsHost 0' in your server config!
|
||||
|
||||
## Installation
|
||||
T4M requires an unpacked steamless version of the multiplayer World at War executable (otherwise known as LanFixed). You can use a Steam Unpacker on your multiplayer World at War Steam executable to acquire the required executable.
|
||||
|
||||
0. Make sure that T4M is installed, updated and working properly.
|
||||
0. Make sure that PlutoniumT4 is installed, updated and working properly.
|
||||
1. Extract all the files from the Bot Warfare release archive you downloaded to anywhere on your computer.
|
||||
2. Run the 'install.bat'. This copies the mod to your WaW mods folder.
|
||||
3. The mod is now installed, now run your game.
|
||||
- If you are a dedicated server, you will need to set the DVAR 'fs_game' to 'mods/mp_bots'
|
||||
- If you are not a dedicated server, open the 'Mods' option from the main menu of the game and select 'mp_bots' and then 'Launch'.
|
||||
- If you are a dedicated server, you will need to set the DVAR 'fs_game' to 'mods/mp_bots'
|
||||
- If you are not a dedicated server, open the 'Mods' option from the main menu of the game and select 'mp_bots' and then 'Launch'.
|
||||
4. The mod should be loaded! Now go start a map and play!
|
||||
|
||||
## Menu Usage
|
||||
@ -29,6 +27,33 @@ T4M requires an unpacked steamless version of the multiplayer World at War execu
|
||||
- Pressing the menu buttons 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
|
||||
- Improved bots mantling, crouching and knifing glass when needed
|
||||
- Fixed possible script runtime errors
|
||||
- Improved domination
|
||||
- Bots use explosives more if they have it
|
||||
- Bots aim slower when ads'ing
|
||||
- Fixed bots holding breath
|
||||
- Fixed bots rubberbanding movement when their goal changes
|
||||
- Added bots quickscoping with snipers
|
||||
- Added bots reload canceling and fast swaps
|
||||
- Bots use C4
|
||||
- Improved revenge
|
||||
- Bots can swap weapons on spawn more likely
|
||||
|
||||
- v2.0.0
|
||||
- Initial reboot release
|
||||
|
||||
|
BIN
out/ss.jpg
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
out/ss.png
Before Width: | Height: | Size: 3.4 MiB |
@ -1 +0,0 @@
|
||||
start "" "%~dp0CoDWaWmp_LanFixed.exe" +set r_fullscreen "0" +set cg_drawlagometer "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 scr_tdm_scorelimit "0" +set bots_manage_add "7" +set fs_game "mods/mp_bots" +map mp_dome
|
@ -1 +0,0 @@
|
||||
start "" "%~dp0CoDWaWmp_LanFixed.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
@ -0,0 +1 @@
|
||||
start "" "node" deploy.js
|
@ -1 +0,0 @@
|
||||
start "" "%~dp0CoDWaWmp_LanFixed.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 scr_tdm_scorelimit "0" +set bots_manage_add "7" +set fs_game "mods/mp_dev" +devmap mp_dome
|
@ -1 +0,0 @@
|
||||
start "" "%~dp0CoDWaWmp_LanFixed.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/mp_dev" +set sv_cheats "1" +connect 127.0.0.1
|
30
z_server.bat
@ -1 +1,29 @@
|
||||
start "" "%~dp0CoDWaWmp_LanFixed.exe" +set dedicated "2" +set sv_maxclients "64" +set sv_punkbuster "0" +set net_port "28960" +set fs_game "mods/mp_bots" +exec server.cfg +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=PT4 Bot Warfare
|
||||
::Port used by the server (default: 28960)
|
||||
set port=28968
|
||||
::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%
|
||||
|
||||
title PlutoniumT4 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.
|
||||
|
||||
cd /D %LOCALAPPDATA%\Plutonium
|
||||
:server
|
||||
start /wait /abovenormal "%name%" "bin\plutonium-bootstrapper-win32.exe" t4mp "%gamepath%" -dedicated -key "%key%" +set net_ip "%ip%" +set net_port "%port%" +set rcon_password "%rcon_password%" +set fs_game "%mod%" +exec "%cfg%" +map_rotate
|
||||
echo (%date%) - (%time%) WARNING: %name% server closed or dropped... server restarts.
|
||||
goto Server
|
||||
|
@ -1 +0,0 @@
|
||||
start "" "%~dp0CoDWaWmp_LanFixed.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/mp_dev" +set bots_manage_add "12" +set sv_punkbuster "0" +set scr_tdm_scorelimit "0" +set net_port "28960" +devmap mp_dome
|