224 Commits

Author SHA1 Message Date
0b50f51ed4 Release 2.1.0 2022-05-05 10:34:52 -06:00
6755cc3b43 adjust some values 2022-05-05 10:01:03 -06:00
c21f2d5a38 fixed bombs 2022-05-02 15:26:41 -06:00
cae7c993f5 check for nuke killstreak 2022-04-28 17:06:36 -06:00
119f9bccf9 All chat stubs 2022-04-26 12:46:58 -06:00
918bb4020a pick up guns 2022-04-25 11:19:10 -06:00
f64ba9cccf Small opti 2022-04-20 12:58:45 -06:00
f3b58c5966 add 2022-04-19 18:01:36 -06:00
a51fa98d02 fix 2022-04-19 18:00:37 -06:00
5392d3152e Air drop changes for chat 2022-04-19 16:41:29 -06:00
c372229b6a less 2022-04-18 18:58:03 -06:00
ae2b16fb47 debug listener 2022-04-18 17:11:51 -06:00
d9c5cbac3e more chatter! 2022-04-18 17:08:17 -06:00
16c813ed53 More chatter 2022-04-18 16:50:00 -06:00
27422d01a5 equ, nade and jav chatter 2022-04-18 16:25:54 -06:00
9984878a25 rename to bot events 2022-04-18 16:12:49 -06:00
05bb24f587 follow chat 2022-04-18 16:10:27 -06:00
6ff815d10e camp chat 2022-04-18 16:06:32 -06:00
7a9e28f03d bot_chat_follow_threat_watch 2022-04-18 16:02:41 -06:00
5f44a7b455 A lot of chat stuff 2022-04-18 15:58:21 -06:00
f58e91b762 Stop move on game end 2022-04-18 15:01:42 -06:00
835b3d597c Fix dev script setPlayerData errors 2022-04-18 15:01:33 -06:00
17e36e08c7 Fix scr errors with missing perk in table 2022-04-18 15:00:49 -06:00
89c2abb5f1 Fix switch on float error 2022-04-18 15:00:37 -06:00
e71722bbe9 a lot 2022-04-17 14:32:30 -06:00
15ec54bfd4 Better approach 2022-04-17 13:35:24 -06:00
b6e06f73f4 Some bot chatter foundations 2022-04-17 13:15:38 -06:00
551e01326d Update 2022-04-17 12:27:30 -06:00
d851ad1ebc Small vip fix, added chat notifications 2022-04-17 12:27:12 -06:00
d740ae15f6 Added bots_skill_min max 2022-04-17 12:26:53 -06:00
8ee6e9888c better stuck 2022-04-08 23:56:38 -06:00
78cba84b75 Read me 2022-04-08 21:11:26 -06:00
5e2c90b1d2 Bots do random action at obj 2022-04-08 21:03:32 -06:00
ebfba23513 Merge pull request #42 from Boxhead78/master
Improve bot camping
2022-04-06 15:05:15 -06:00
569388324b Update wps 2022-04-06 15:03:49 -06:00
cc30a756cb Update wps 2022-04-06 15:03:05 -06:00
0690a9703d Add warnings if waypoint unreachable 2022-04-06 15:03:01 -06:00
a06c33823b Improve bot camping
- They camp longer
- They stop camping if 1 minute game time is remaining
2022-04-05 08:10:23 +02:00
e73c553308 Bots play vip 2022-04-04 19:41:54 -06:00
c42a72f742 fix vip 2022-04-04 19:41:45 -06:00
f234ef2023 common_mp 2022-04-04 13:22:09 -06:00
d8dbd975db remove 2022-04-03 18:23:04 -06:00
7664f491de better 2022-04-03 18:20:14 -06:00
9b8627ba4b Bots crouch with riot 2022-04-03 14:33:16 -06:00
fd5d1272fe fix scr error on ffa 2022-03-31 09:14:54 -06:00
a015aed62a new dvar 2022-03-24 16:19:57 -06:00
395a991b6f github supports gsc 2022-03-23 11:49:38 -06:00
9ac9df8db1 They play arena now 2022-03-20 16:08:43 -06:00
94142d7aa9 Fix the watchdog 2022-01-22 21:51:18 -06:00
a28db1e2fd better 2021-12-21 21:51:11 -06:00
c4bf34d1ff better code complete 2021-12-21 21:45:17 -06:00
26d2d487b8 fix 2021-11-27 00:05:13 -06:00
893dfa5bf0 Revert "fix"
This reverts commit 590d5091fa.
2021-11-27 00:04:46 -06:00
590d5091fa fix 2021-11-26 23:58:03 -06:00
1706cef05e nukes 2021-11-23 12:03:54 -06:00
ea39456fd9 dvars 2021-11-14 15:53:20 -06:00
72d9223f48 oen more 2021-11-11 23:54:56 -06:00
97236e2e5f more script fixes 2021-11-11 23:13:37 -06:00
18c67cb334 one more... 2021-11-10 16:29:42 -06:00
ea14b71f5b one more 2021-11-10 16:10:12 -06:00
9fc6a8b56b fix another 2021-11-10 16:04:34 -06:00
d34c33e74b fix up errors 2021-11-10 15:54:34 -06:00
9fa8506daf Remove test 2021-10-24 02:17:34 -06:00
af35ec3a8f Update to use findstr 2021-10-24 02:17:14 -06:00
7b667f511d oops 2021-10-23 17:54:04 -06:00
79aa5963d5 use games_mp 2021-10-23 17:52:53 -06:00
81c3c0e5e9 Fix 2021-10-23 17:37:27 -06:00
c23d556d9e Added for other servers 2021-10-23 17:15:51 -06:00
d4220bd70d add watchdog scripts 2021-10-23 17:05:34 -06:00
a512fcbf45 again 2021-09-14 15:46:51 -06:00
ca2f3c8f7c fix error 2021-09-14 15:46:34 -06:00
e0ad486ee0 formatting 2021-09-09 12:41:02 -06:00
fe5f775a71 Tablify dvars 2021-09-09 12:32:53 -06:00
f7816d351c editorconfig and gitattr 2021-09-09 11:27:04 -06:00
039b2a6aca fix 2021-09-04 23:34:50 -06:00
3898e17925 Configs 2021-09-04 23:30:02 -06:00
5ffd3b793a cleanup 2021-09-04 23:13:53 -06:00
c45ee94ff5 cleanup 2021-09-04 23:13:26 -06:00
f8a2f020f5 Added vscode settings 2021-09-03 11:02:32 -06:00
f7016cd704 toggle onemanarmy flare 2021-09-01 21:21:54 -06:00
562d7f5cf5 hasperk 2021-08-27 12:10:27 -06:00
fa14c3d77c Added bot_aim dvar 2021-08-26 10:41:55 -06:00
44075bbfdb Fix bots changing classes 2021-08-25 12:37:25 -06:00
3d314cf267 fix returning flag oneflag 2021-08-25 11:01:37 -06:00
53441151a8 Update README.md 2021-08-06 19:32:55 -06:00
ef21c631e0 if behind 2021-08-02 16:23:11 -06:00
d4480b7246 improved sprinting 2021-07-29 13:54:42 -06:00
a6d7dae5b9 added oneflag 2021-07-27 14:50:20 -06:00
f8719a3b3e revive and fixs 2021-07-25 23:11:21 -06:00
b76ed0995b test 2021-07-25 20:48:40 -06:00
91a7d462e1 gtnw 2021-07-25 15:05:28 -06:00
339c6ed864 better 2021-07-24 20:40:02 -06:00
3e406c5492 show speed 2021-07-24 20:36:03 -06:00
0a5cf7b895 4 para 2021-07-13 19:50:02 -06:00
6c031612ce target through glass 2021-07-13 18:52:39 -06:00
a202d2bba9 splash 2021-07-07 15:58:26 -06:00
d755d3be01 swap the colors 2021-07-07 15:24:41 -06:00
4d3bd2603d chnge color 2021-07-07 14:53:00 -06:00
b7053cba21 pen 2021-07-07 14:22:44 -06:00
d00e230c58 dvars 2021-07-01 13:10:38 -06:00
46cd853c21 triple cap script 2021-07-01 12:59:46 -06:00
cc4c29c515 Update deploy script 2021-06-18 13:53:52 -06:00
27be561a42 Format all scripts 2021-06-18 13:27:21 -06:00
4eced4bc93 Set title 2021-06-18 00:34:10 -06:00
cda0902e1e Merge branch 'master' of https://github.com/ineedbots/mw2_bot_warfare 2021-06-18 00:29:57 -06:00
59903db458 Add deploy scripts 2021-06-18 00:29:49 -06:00
ebce2ef641 Update README.md 2021-06-17 23:30:48 -06:00
a2f9f1f9ee Update README.md 2021-06-17 22:56:04 -06:00
143b03ccf8 Update 2021-06-17 22:10:10 -06:00
bd346f2df9 small change 2021-06-17 22:06:32 -06:00
39136e195b More accurate styling 2021-06-17 21:58:19 -06:00
b272ded713 Add astylerc 2021-06-17 21:31:44 -06:00
dcbee17c25 Fixed thirdperson 2021-06-16 16:09:47 -06:00
fe4e761c64 Sync with iw5 changes 2021-06-14 13:13:05 -06:00
b4bade0106 Fix bots walking around with a killstreak 2021-06-13 21:21:10 -06:00
d443aab063 more sprintage 2021-06-13 19:07:12 -06:00
22fcb5f990 Fixed bot target exploits 2021-06-13 13:50:17 -06:00
f109ab8fbb Reduce var usage 2021-06-04 14:15:21 -06:00
a18aa4c446 up 2021-06-02 23:29:08 -06:00
c115a01ea7 Some future stuff 2021-06-02 23:17:54 -06:00
ee356e9b2c fix dist remote 2021-06-02 10:50:44 -06:00
ca239187f4 Change up sum weaps 2021-06-02 10:20:44 -06:00
00ca687083 prevent stuck crouch 2021-05-27 14:15:56 -06:00
06bedd0df9 Greatly reduce var usage 2021-05-27 14:14:49 -06:00
40d5b03bcf Reduce var usage no kd tree 2021-05-27 11:18:39 -06:00
6c1b6218a6 some fix up 2021-05-26 12:48:48 -06:00
c81a4e2472 Fix up Salvage 2021-05-23 13:34:40 -06:00
1f131d72b4 improved favela wps 2021-05-20 10:36:47 -06:00
e14196e3fc Added low memory mode 2021-05-19 20:07:04 -06:00
7a0dc3b7f9 Improved aiming 2021-05-19 15:23:53 -06:00
c2c7b94c79 Fix up some mantling issues 2021-05-19 13:08:10 -06:00
5a5f5dec58 Improved mantling 2021-05-19 12:20:36 -06:00
56bf257976 Merge pull request #10 from IKennyAgain/master
Updated
2021-05-19 11:40:38 -06:00
953d694a74 Updated
Bots are now mantling in "stand" stance, that prevents them from stuck.
2021-05-19 15:10:34 +03:00
a2ef57ff50 Better print damage 2021-05-18 20:26:46 -06:00
ba24e61852 Fix possible runtime errors 2021-05-18 15:02:43 -06:00
1cd164e5ea Push update 2.0.1 2021-05-16 12:21:29 -06:00
c31f0d2bfa Update wps 2021-05-14 16:42:30 -06:00
22b5c75197 Improved c4 2021-05-14 15:28:51 -06:00
23dbbb9439 Fix up wpedit 2021-05-09 11:44:56 -06:00
20bc803498 Fixed wp editor runtime errors 2021-05-08 14:18:46 -06:00
888a0225e6 Update README.md 2021-05-07 02:31:24 -06:00
e438ea2f02 Added optimization 2021-05-04 17:30:11 -06:00
80a00b019b Added c4 support 2021-05-04 16:15:05 -06:00
06990751c0 Fixed weapon swap vars and added c4 watcher 2021-05-04 14:41:50 -06:00
6bd638ab00 smol 2021-05-03 23:46:11 -06:00
75ed617320 Fix int overflows, better formatting 2021-05-01 13:39:15 -06:00
fc1e8f48d2 move unused 2021-04-27 20:33:57 -07:00
8bde752124 Added xp rewards to killstreak streaks 2021-04-27 14:39:40 -07:00
e0dfadbe48 play fx when empd 2021-04-14 01:01:13 -06:00
1613497335 patch airstrike teamswitch exploit 2021-04-14 00:51:08 -06:00
4a13410976 Fix being stuck in spectator 2021-04-13 19:21:45 -06:00
f94a845a2f fix gren missile death bug, c4 claymore emp bug 2021-04-13 18:59:02 -06:00
bc6595eef5 oops 2021-04-13 11:36:14 -06:00
60d3fa7c33 nukeslowmo addition 2021-04-13 11:23:09 -06:00
66a66212ca Added weapon sswitch anim cancel, and init weapon switch on spawn 2021-03-24 02:34:10 -06:00
bc888f95cf remove test 2021-03-19 14:53:11 -06:00
3204c22f16 Fix sentry weapon, and reload cancel edge case 2021-03-19 14:49:19 -06:00
52e9373610 improve checking for sniper and reload 2021-03-19 14:04:57 -06:00
dbe50d85e2 Add reload canceling 2021-03-18 16:34:19 -06:00
c00dbd64bf update 2021-03-16 15:37:07 -06:00
80693d15b1 more keks fixed 2021-03-12 18:39:00 -06:00
b2cb93ce7a common_mp 2021-03-12 18:37:49 -06:00
003f4faaac fixed the kekware 2021-03-12 18:33:17 -06:00
37fd34fb3f iw4x 2021-03-12 18:32:10 -06:00
c25ce6e06f custom default classes 2021-03-12 18:31:30 -06:00
ff670e2a43 patch_mp 2021-03-12 18:31:21 -06:00
7497b656cb common_mp 2021-03-12 18:30:29 -06:00
b9c63488ae update changelog 2021-03-12 14:55:00 -06:00
037de678a5 Clean up 2021-03-12 14:05:24 -06:00
17f15bdafd wps 2021-03-12 13:55:35 -06:00
36d4809796 qs 2021-03-11 16:12:58 -06:00
c98583bd62 added bot quickscope 2021-03-11 16:03:03 -06:00
5a4bffdbaa bot_sniperCheck 2021-03-11 16:02:52 -06:00
d7f877e40f qs 2021-03-11 15:38:17 -06:00
cdbf9ef9c1 Merge branch 'master' of https://github.com/ineedbots/mw2_bot_warfare into master 2021-03-11 15:25:35 -06:00
18eabe21fc Added lastKiller 2021-03-11 15:24:45 -06:00
6a53dd9d20 Fixed rubbering 2021-03-11 15:12:01 -06:00
7e09fc17c9 added lastKiller 2021-03-11 15:11:53 -06:00
41648436d7 sniper 2021-03-11 01:56:20 -06:00
96216a77b4 Added change log 2021-03-10 17:19:53 -06:00
b84483abec Added emp heli queue 2021-03-10 17:06:54 -06:00
0604980d8e Better 2021-03-10 15:16:14 -06:00
440a3c561b Improved crouching and mantling 2021-03-09 16:34:37 -06:00
6e841d9732 update wps 2021-03-09 16:24:33 -06:00
87e83f12d9 Update wps 2021-03-09 15:10:58 -06:00
7b3c27f723 More sprints 2021-03-03 22:55:04 -06:00
e2e40ea3d1 update wps 2021-03-03 18:10:15 -06:00
43f88e9fb1 added weapon class dist mutiplier 2021-03-03 18:10:00 -06:00
c417ddba39 fix bot laptop aim
add bot mw2
2021-03-01 03:43:54 -06:00
e7fef2e080 fix bots stance using remote
added bot ads aimspeed slow
2021-03-01 03:43:18 -06:00
578ae5cd2b better 2021-03-01 03:42:39 -06:00
f102962ffa Add forgotten doc 2021-02-27 15:00:58 -06:00
28ca878a9f Bots play dom harder if they are losing 2021-02-27 14:39:50 -06:00
527f63b771 improved mantling and knifing glass 2021-02-27 14:25:32 -06:00
49c98fe467 greatly reduced crouching, greatly increased sprinting 2021-02-27 14:25:17 -06:00
296a5c6e63 fix emp switch team 2021-02-24 13:28:09 -06:00
06587f67fe Fix finally 2021-02-24 13:08:28 -06:00
dd87fe8c25 fix dd 2021-02-17 22:34:53 -06:00
2b5c2ff10d Fix bots aiming and stuff with pred 2021-02-14 01:19:39 -06:00
20dc9c9bed aa 2021-02-13 15:40:12 -06:00
2c015fb9e7 fix scr error 2021-01-19 13:30:29 -06:00
7399aea5ab ignore carepackage 2021-01-18 13:24:38 -06:00
cda07629ca dont wait 2021-01-18 01:28:33 -06:00
1ae35a14fd Fix 2021-01-14 09:53:19 -06:00
33fb299c27 revive stub 2021-01-13 16:22:27 -06:00
779a83a83a Fix possible script errors 2021-01-13 16:21:29 -06:00
89bb00de88 update wps 2021-01-12 23:18:43 -06:00
60ca814764 dvars 2021-01-12 19:03:25 -06:00
919c60d024 Fixed more 2021-01-12 19:02:20 -06:00
7092b5a40c Fixed the actual airstrike bug 2021-01-12 18:56:13 -06:00
1c1eac6b1d dvar 2021-01-12 18:02:27 -06:00
23621698c9 fixStealthBomberDupe fast_harrier 2021-01-12 18:01:26 -06:00
48d8348a09 no limit 2021-01-12 14:28:12 -06:00
6c28abdbaa fast ac130 2021-01-12 14:28:00 -06:00
433b9e787f remove chopper queue on nuke end game 2021-01-12 14:13:34 -06:00
abb05306f5 fix emp leave friendlyfire 2021-01-12 14:07:40 -06:00
9ee21cb5e5 added missing dvars 2021-01-12 13:29:02 -06:00
226254e501 cur rollover dvar 2021-01-12 13:24:21 -06:00
0d589ec89e Added readme 2021-01-09 17:12:10 -06:00
dfe68e0edb update 2021-01-09 16:49:03 -06:00
4f290ec518 removed wps, use the repo 2021-01-09 16:46:50 -06:00
dd0e1bbb5d fix carepackage 2021-01-09 00:18:56 -06:00
fc9b03d9ac Fix 2021-01-04 14:53:53 -06:00
60 changed files with 16689 additions and 8252 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

18
.gitignore vendored
View File

@ -2,15 +2,17 @@
/*
# Files to not ignore
!/.vscode
!/.gitignore
!/z_devserver.bat
!/z_dev.bat
!/z_serverdev.bat
!/.editorconfig
!/.gitattributes
!/z_server.bat
!/z_bots.bat
!/z_client.bat
!/z_server_watchdog.bat
!/z_server_pvbrust.bat
!/z_server_pvbrust_watchdog.bat
!/z_server_pvbvote.bat
!/z_server_pvbvote_watchdog.bat
# Folder to not ignore
!/userraw
@ -22,6 +24,11 @@
!/README.md
!/out
!/.astylerc
!/z_deploy.bat
!/deploy.bat
!/deploy.js
*.zip
*.log
*.stat
@ -31,3 +38,4 @@ images/
missingasset.csv
userraw/scripts/_commands.gsc
userraw/scripts/_customcallbacks.gsc
userraw/scripts/bots_custom.gsc

15
.vscode/settings.json vendored Normal file
View 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
}

173
README.md
View File

@ -73,103 +73,108 @@ You can find the ModDB release post [here](https://www.moddb.com/mods/bot-warfar
- 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.
- 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 (like no miniuzi bling with acog rapidfire and hardline for example)
- bots_loadout_allow_op - a boolean value (0 or 1), whether or not if the bots are allowed to use deathstreaks, noobtubes, rpg, laststand, 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_take_carepackages - a boolean value (0 or 1), whether or not if the bots will take carepackages
- 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. | false |
| 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_take_carepackages | If the bots can take carepackages. | 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
- Fix bots slowly reacting in remote streaks
- Improved bots mantling and stuck
- Improved bots aim
- Fix some runtime errors
- Fixed bots aim in third person
- Bots sprint more
- Improved bots sight on enemies
- Bots play hidden gamemodes like one-flag and arena
- 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
- Fixed demolition spawn killing
- Improved domination
- Bots use explosives more if they have it
- Fixed bots moving their player when using remote
- Bots aim slower when ads'ing
- Fixed bots holding breath
- Bots are more smart when waiting for carepackages
- Improved and fixed various waypoints for maps
- 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
- TODOs
- A variable leak in _menu (script)
- Recoil for bots (engine, maybe script)
- Use proper activate button for bombs, carepackages, etc (script, use +activate)
- Proper weapon swaps, including altmode (engine, then script)
- Use static turrets in maps (script)
- Proper use of pred missile (script and engine)
- Fix testclient view angle clamping (messes with ac130 and chopper gunner) (engine)
## Credits
- IW4x Team - https://github.com/XLabsProject/iw4x-client
- 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
- tinkie101 - https://web.archive.org/web/20120326060712/http://alteriw.net/viewtopic.php?f=72&t=4869
- PeZBot team - http://www.moddb.com/mods/pezbot
- apdonato - http://rsebots.blogspot.ca/
- Ability
- Salvation
- VicRattlehead - https://www.moddb.com/members/vicrattlehead
Feel free to use code, host on other sites, host on servers, mod it and merge mods with it, just give credit where credit is due!
-INeedGames/INeedBot(s) @ ineedbots@outlook.com

6
deploy.bat Normal file
View File

@ -0,0 +1,6 @@
xcopy iw4x_bot_warfare\userraw\maps userraw\maps\ /Y /I /E /H /C
xcopy iw4x_bot_warfare\userraw\scripts userraw\scripts\ /Y /I /E /H /C
xcopy iw4x_bot_warfare\userraw\waypoints userraw\waypoints\ /Y /I /E /H /C
xcopy iw4x_bot_warfare\userraw\mp userraw\mp\ /Y /I /E /H /C
xcopy iw4x_bot_warfare\main main\ /Y /I /E /H /C
xcopy iw4x_bot_warfare\userraw\bots.txt userraw\ /Y /I /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 = 'iw4x_bot_warfare'
const repo_url = `https://github.com/ineedbots/${repo_name}`
const deploy_check_rate = 60000
const title = 'IW4x 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

@ -48,7 +48,6 @@ set sv_wwwDownload "1"
// NON-GAMEPLAY CONFIGURATION //
//////////////////////////////////////////////////
set rcon_password "qazqaz" // Access to your server to change stuff remotely or ingame. empty disabled
set sv_securityLevel "23" // Configures the servers security level.
set sv_customTextColor "" // custom color for ^;
set g_password "" // Password Protected Server. Leave blank if you want players to join
@ -114,10 +113,10 @@ set scr_classic "0" // Enable IW3 killstreak system
// //
// DO NOT ABUSE! Some people like to rank. //
// DON'T BE A DICK! Warn HIGH XP via hostname. //
// Don't know what you doing? Don't touch it! //
// Don't know what you doing? Dont touch it! //
//////////////////////////////////////////////////
set scr_xpscale "10" // IW's way of Double XP.
set scr_xpscale "10" // IWs way of Double XP.
//set scr_war_score_kill "0" // Amount of XP by each kill.
//set scr_war_score_headshot "0" // Amount of XP by each headshot.
@ -203,7 +202,7 @@ set scr_airdrop_mega_nuke "1"
//////////////////////////////////////////////////
set scr_dm_scorelimit "10000" // Score limit to win the game.
set scr_dm_timelimit "10" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_dm_timelimit "10" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_dm_playerrespawndelay "0" // How long player will wait until respawn.
set scr_dm_numlives "0" // Number of lives per player 0 for unlimited.
set scr_dm_roundlimit "1" // Rounds per game.
@ -215,7 +214,7 @@ set scr_dm_promode "0"
//////////////////////////////////////////////////
set scr_war_scorelimit "25600" // Score limit to win the game.
set scr_war_timelimit "10" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_war_timelimit "10" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_war_playerrespawndelay "0" // How long player will wait until respawn.
set scr_war_waverespawndelay "0" // Duration is seconds before the first respawn in each round.
set scr_war_numlives "0" // Number of lives per player 0 for unlimited.
@ -228,7 +227,7 @@ set scr_war_promode "0"
//////////////////////////////////////////////////
set scr_dom_scorelimit "300" // Score limit to win the game.
set scr_dom_timelimit "0" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_dom_timelimit "30" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_dom_playerrespawndelay "0" // How long player will wait until respawn.
set scr_dom_waverespawndelay "0" // Duration is seconds before the first respawn in each round.
set scr_dom_numlives "0" // Number of lives per player per game. 0 is unlimited.
@ -241,7 +240,7 @@ set scr_dom_promode "0"
//////////////////////////////////////////////////
set scr_dd_scorelimit "1" // Score limit needed to win.
set scr_dd_timelimit "2.5" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_dd_timelimit "2.5" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_dd_playerrespawndelay "0" // How long player will wait until respawn.
set scr_dd_waverespawndelay "0" // Duration is seconds before the first respawn in each round.
set scr_dd_numlives "0" // Number of lives per player per game. 0 is unlimited.
@ -257,7 +256,7 @@ set scr_dd_promode "0"
//////////////////////////////////////////////////
set scr_sd_scorelimit "1" // Score limit required to win the game.
set scr_sd_timelimit "2.5" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_sd_timelimit "2.5" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_sd_playerrespawndelay "0" // How long player will wait until respawn.
set scr_sd_waverespawndelay "0" // Duration is seconds before the first respawn in each round.
set scr_sd_numlives "1" // Number of lives per player per game.
@ -276,7 +275,7 @@ set scr_sd_promode "0"
//////////////////////////////////////////////////
set scr_sab_scorelimit "0" // Score limit to win the match.
set scr_sab_timelimit "20" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_sab_timelimit "20" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_sab_bombtimer "30" // Duration in seconds the bomb takes to detonate.
set scr_sab_defusetime "5" // Time taken to defuse the bomb.
set scr_sab_hotpotato "0" // One bomb that the teams must fight over. One defending and one have to plant at the site.
@ -294,7 +293,7 @@ set scr_sab_promode "0"
//////////////////////////////////////////////////
set scr_ctf_scorelimit "0" // Target score before the round ends.
set scr_ctf_timelimit "10" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_ctf_timelimit "10" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_ctf_numlives "0" // Number of lives per player 0 for unlimited.
set scr_ctf_halftime "1" // Half-Time
set scr_ctf_roundlimit "1" // How many rounds match would last.
@ -308,7 +307,7 @@ set scr_ctf_promode "0"
//////////////////////////////////////////////////
set scr_oneflag_scorelimit "1" // Target score before the round ends.
set scr_oneflag_timelimit "3" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_oneflag_timelimit "3" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_oneflag_numlives "0" // number of lives per player 0 for unlimited.
set scr_oneflag_playerrespawndelay "0" // Respawn wait in seconds.
set scr_oneflag_roundlimit "1" // How many rounds match would last.
@ -321,7 +320,7 @@ set scr_oneflag_promode "0"
//////////////////////////////////////////////////
set scr_koth_scorelimit "250" // Score limit to win the game.
set scr_koth_timelimit "15" // Duration in minutes the game will continue if the score isn't reached.
set scr_koth_timelimit "15" // Duration in minutes the game will continue if the score isnt reached.
set scr_koth_numlives "0" // Number of lives per game. 0 for unlimited.
set scr_koth_playerrespawndelay "0" // Players respawn wait.
set scr_koth_roundlimit "1" // Rounds to be played.
@ -335,7 +334,7 @@ set scr_koth_promode "0"
//////////////////////////////////////////////////
set scr_arena_scorelimit "1" // Score limit to win the game.
set scr_arena_timelimit "2.5" // Duration in minutes the game will continue if the score isn't reached.
set scr_arena_timelimit "2.5" // Duration in minutes the game will continue if the score isnt reached.
set scr_arena_numlives "1" // Number of lives per game 0 for unlimited.
set scr_arena_roundlimit "0" // Rounds to be played.
set scr_arena_roundswitch "3" // Rounds before the teams switch sides.
@ -348,7 +347,7 @@ set scr_arena_promode "0"
//////////////////////////////////////////////////
set scr_gtnw_scorelimit "101" // Score limit to win the game.
set scr_gtnw_timelimit "10" // Duration in minutes the game will continue if the score isn't reached.
set scr_gtnw_timelimit "10" // Duration in minutes the game will continue if the score isnt reached.
set scr_gtnw_numlives "0" // Number of lives per game 0 for unlimited.
set scr_gtnw_playerrespawndelay "0" // Players respawn wait.
set scr_gtnw_roundlimit "1" // Rounds to be played.
@ -476,7 +475,7 @@ set scr_spawnsimple ""
set scr_spawn_enemyavoiddist ""
// _spawnlogic
set scr_spawnpointfavorweight "499999"
set scr_spawnpointfavorweight ""
set scr_spawnpointdooutsidecheck ""
// iw4x
@ -491,9 +490,11 @@ set iw4x_onelog ""
// CUSTOM
set bot_pvb_helper_noPlayersOnTeam "axis"
set bot_pvb_helper_customBotClassTeam ""
set bot_pvb_helper_customBotClassTeam "allies"
set scr_showHP "1"
set scr_allowFPSBooster "1"
set bot_sniperCheck "1"
set dom_lastFlagUseTimeMulti "4.0"
// _class
// set scr_allow_ "0"
@ -516,8 +517,10 @@ set scr_player_forceclassselection ""
set scr_player_allowChangeTeam "1"
// _bot
set bot_main "1"
set bots_main "1"
set bots_main_GUIDs ""
set bots_main_firstIsHost "0"
set bots_main_waitForHostTime "10"
set bots_manage_add "9"
set bots_manage_fill "9"
set bots_manage_fill_spec "0"
@ -526,18 +529,31 @@ set bots_manage_fill_kick "1"
set bots_team "axis"
set bots_team_amount "0"
set bots_team_force "1"
set bots_team_mode "0"
set bots_skill "0"
set bots_team_mode "1"
set bots_skill "8"
set bots_skill_axis_hard "0"
set bots_skill_axis_med "0"
set bots_skill_axis_med "4"
set bots_skill_allies_hard "0"
set bots_skill_allies_med "0"
set bots_skill_allies_med "4"
set bots_loadout_reasonable "0"
set bots_loadout_allow_op "0"
set bots_loadout_rank "-1"
set bots_loadout_prestige "-1"
set bots_play_move "1"
set bots_play_knife "1"
set bots_play_fire "1"
set bots_play_nade "1"
set bots_play_take_carepackages "1"
set bots_play_obj "1"
set bots_play_camp "1"
set bots_play_jumpdrop "1"
set bots_play_target_other "1"
set bots_play_killstreak "1"
set bots_play_ads "1"
// iw4madmin
set sv_printradarupdates "1"
set sv_printradarupdates "0"
// _killcam
@ -576,13 +592,15 @@ set scr_deleteNadeOnTeamChange "1"
// _perkfunctions
set combathighIsJuiced "1"
set onemanarmyRefillsTubes "1"
set fix_onemanarmyFlareBug "0"
// _killstreaks
set scr_killstreak_rollover "1"
set scr_currentRolloverKillstreaksOnlyIncrease "1"
set scr_killstreakHud "1"
set scr_maxKillstreakRollover "1"
set scr_killstreak_mod "0"
set scr_killstreak_print "1"
set scr_killstreak_print "2"
set scr_specialist "1"
//set scr_specialist_killCount_ "4"
set scr_specialist_perks1 "specialty_scavenger,specialty_fastreload,specialty_marathon"
@ -597,7 +615,7 @@ set scr_nuke_perm_vision "1"
set scr_nuke_canCall_whenTimePassed "0"
set scr_nuke_canCall_whenScoreLimitClose "0"
set scr_nuke_canCall_whenScoreLimitClose_selfOnly "0"
set scr_nuke_doSlowmo "1"
set scr_nuke_doSlowmo "2"
// _emp
set scr_emp_doesFriendlyFire "0"
@ -626,6 +644,7 @@ set scr_airdrop_patchDupeGlitch "0"
// _ac130
set scr_ac130_duration "30"
set scr_ac130_flares "1"
set scr_ac130_fast "1"
// _uav
set scr_uav_timeout "30"
@ -635,3 +654,6 @@ set scr_uav_does_print "1"
// _airstrike
set scr_harrier_duration "30"
set scr_harrier_fast "1"
set scr_airstrike_mutate_fix "1"
set scr_airstrike_teamChangeFix "1"

View File

@ -48,7 +48,6 @@ set sv_wwwDownload "1"
// NON-GAMEPLAY CONFIGURATION //
//////////////////////////////////////////////////
set rcon_password "qazqaz" // Access to your server to change stuff remotely or ingame. empty disabled
set sv_securityLevel "23" // Configures the servers security level.
set sv_customTextColor "" // custom color for ^;
set g_password "" // Password Protected Server. Leave blank if you want players to join
@ -114,10 +113,10 @@ set scr_classic "0" // Enable IW3 killstreak system
// //
// DO NOT ABUSE! Some people like to rank. //
// DON'T BE A DICK! Warn HIGH XP via hostname. //
// Don't know what you doing? Don't touch it! //
// Don't know what you doing? Dont touch it! //
//////////////////////////////////////////////////
set scr_xpscale "10" // IW's way of Double XP.
set scr_xpscale "10" // IWs way of Double XP.
//set scr_war_score_kill "0" // Amount of XP by each kill.
//set scr_war_score_headshot "0" // Amount of XP by each headshot.
@ -203,7 +202,7 @@ set scr_airdrop_mega_nuke "1"
//////////////////////////////////////////////////
set scr_dm_scorelimit "10000" // Score limit to win the game.
set scr_dm_timelimit "10" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_dm_timelimit "10" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_dm_playerrespawndelay "0" // How long player will wait until respawn.
set scr_dm_numlives "0" // Number of lives per player 0 for unlimited.
set scr_dm_roundlimit "1" // Rounds per game.
@ -215,7 +214,7 @@ set scr_dm_promode "0"
//////////////////////////////////////////////////
set scr_war_scorelimit "25600" // Score limit to win the game.
set scr_war_timelimit "10" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_war_timelimit "10" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_war_playerrespawndelay "0" // How long player will wait until respawn.
set scr_war_waverespawndelay "0" // Duration is seconds before the first respawn in each round.
set scr_war_numlives "0" // Number of lives per player 0 for unlimited.
@ -228,7 +227,7 @@ set scr_war_promode "0"
//////////////////////////////////////////////////
set scr_dom_scorelimit "300" // Score limit to win the game.
set scr_dom_timelimit "0" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_dom_timelimit "30" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_dom_playerrespawndelay "0" // How long player will wait until respawn.
set scr_dom_waverespawndelay "0" // Duration is seconds before the first respawn in each round.
set scr_dom_numlives "0" // Number of lives per player per game. 0 is unlimited.
@ -241,7 +240,7 @@ set scr_dom_promode "0"
//////////////////////////////////////////////////
set scr_dd_scorelimit "1" // Score limit needed to win.
set scr_dd_timelimit "2.5" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_dd_timelimit "2.5" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_dd_playerrespawndelay "0" // How long player will wait until respawn.
set scr_dd_waverespawndelay "0" // Duration is seconds before the first respawn in each round.
set scr_dd_numlives "0" // Number of lives per player per game. 0 is unlimited.
@ -257,7 +256,7 @@ set scr_dd_promode "0"
//////////////////////////////////////////////////
set scr_sd_scorelimit "1" // Score limit required to win the game.
set scr_sd_timelimit "2.5" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_sd_timelimit "2.5" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_sd_playerrespawndelay "0" // How long player will wait until respawn.
set scr_sd_waverespawndelay "0" // Duration is seconds before the first respawn in each round.
set scr_sd_numlives "1" // Number of lives per player per game.
@ -276,7 +275,7 @@ set scr_sd_promode "0"
//////////////////////////////////////////////////
set scr_sab_scorelimit "0" // Score limit to win the match.
set scr_sab_timelimit "20" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_sab_timelimit "20" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_sab_bombtimer "30" // Duration in seconds the bomb takes to detonate.
set scr_sab_defusetime "5" // Time taken to defuse the bomb.
set scr_sab_hotpotato "0" // One bomb that the teams must fight over. One defending and one have to plant at the site.
@ -294,7 +293,7 @@ set scr_sab_promode "0"
//////////////////////////////////////////////////
set scr_ctf_scorelimit "0" // Target score before the round ends.
set scr_ctf_timelimit "10" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_ctf_timelimit "10" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_ctf_numlives "0" // Number of lives per player 0 for unlimited.
set scr_ctf_halftime "1" // Half-Time
set scr_ctf_roundlimit "1" // How many rounds match would last.
@ -308,7 +307,7 @@ set scr_ctf_promode "0"
//////////////////////////////////////////////////
set scr_oneflag_scorelimit "1" // Target score before the round ends.
set scr_oneflag_timelimit "3" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_oneflag_timelimit "3" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_oneflag_numlives "0" // number of lives per player 0 for unlimited.
set scr_oneflag_playerrespawndelay "0" // Respawn wait in seconds.
set scr_oneflag_roundlimit "1" // How many rounds match would last.
@ -321,7 +320,7 @@ set scr_oneflag_promode "0"
//////////////////////////////////////////////////
set scr_koth_scorelimit "250" // Score limit to win the game.
set scr_koth_timelimit "15" // Duration in minutes the game will continue if the score isn't reached.
set scr_koth_timelimit "15" // Duration in minutes the game will continue if the score isnt reached.
set scr_koth_numlives "0" // Number of lives per game. 0 for unlimited.
set scr_koth_playerrespawndelay "0" // Players respawn wait.
set scr_koth_roundlimit "1" // Rounds to be played.
@ -335,7 +334,7 @@ set scr_koth_promode "0"
//////////////////////////////////////////////////
set scr_arena_scorelimit "1" // Score limit to win the game.
set scr_arena_timelimit "2.5" // Duration in minutes the game will continue if the score isn't reached.
set scr_arena_timelimit "2.5" // Duration in minutes the game will continue if the score isnt reached.
set scr_arena_numlives "1" // Number of lives per game 0 for unlimited.
set scr_arena_roundlimit "0" // Rounds to be played.
set scr_arena_roundswitch "3" // Rounds before the teams switch sides.
@ -348,7 +347,7 @@ set scr_arena_promode "0"
//////////////////////////////////////////////////
set scr_gtnw_scorelimit "101" // Score limit to win the game.
set scr_gtnw_timelimit "10" // Duration in minutes the game will continue if the score isn't reached.
set scr_gtnw_timelimit "10" // Duration in minutes the game will continue if the score isnt reached.
set scr_gtnw_numlives "0" // Number of lives per game 0 for unlimited.
set scr_gtnw_playerrespawndelay "0" // Players respawn wait.
set scr_gtnw_roundlimit "1" // Rounds to be played.
@ -476,7 +475,7 @@ set scr_spawnsimple ""
set scr_spawn_enemyavoiddist ""
// _spawnlogic
set scr_spawnpointfavorweight "499999"
set scr_spawnpointfavorweight ""
set scr_spawnpointdooutsidecheck ""
// iw4x
@ -490,10 +489,12 @@ set iw4x_onelog ""
// CUSTOM
set bot_pvb_helper_noPlayersOnTeam "allies"
set bot_pvb_helper_customBotClassTeam "axis"
set bot_pvb_helper_noPlayersOnTeam "axis"
set bot_pvb_helper_customBotClassTeam ""
set scr_showHP "1"
set scr_allowFPSBooster "1"
set bot_sniperCheck "1"
set dom_lastFlagUseTimeMulti "4.0"
// _class
// set scr_allow_ "0"
@ -516,24 +517,39 @@ set scr_player_forceclassselection ""
set scr_player_allowChangeTeam "1"
// _bot
set bot_main "1"
set bots_main "1"
set bots_main_GUIDs ""
set bots_manage_add "10"
set bots_manage_fill "10"
set bots_main_firstIsHost "0"
set bots_main_waitForHostTime "10"
set bots_manage_add "9"
set bots_manage_fill "9"
set bots_manage_fill_spec "0"
set bots_manage_fill_mode "1"
set bots_manage_fill_kick "1"
set bots_team "custom"
set bots_team_amount "1"
set bots_team "axis"
set bots_team_amount "0"
set bots_team_force "1"
set bots_team_mode "1"
set bots_team_mode "0"
set bots_skill "8"
set bots_skill_axis_hard "1"
set bots_skill_axis_med "0"
set bots_skill_axis_hard "0"
set bots_skill_axis_med "3"
set bots_skill_allies_hard "0"
set bots_skill_allies_med "3"
set bots_skill_allies_med "0"
set bots_loadout_reasonable "0"
set bots_loadout_allow_op "0"
set bots_loadout_rank "-1"
set bots_loadout_prestige "-1"
set bots_play_move "1"
set bots_play_knife "1"
set bots_play_fire "1"
set bots_play_nade "1"
set bots_play_take_carepackages "1"
set bots_play_obj "1"
set bots_play_camp "1"
set bots_play_jumpdrop "1"
set bots_play_target_other "1"
set bots_play_killstreak "1"
set bots_play_ads "1"
// iw4madmin
@ -576,13 +592,15 @@ set scr_deleteNadeOnTeamChange "1"
// _perkfunctions
set combathighIsJuiced "1"
set onemanarmyRefillsTubes "1"
set fix_onemanarmyFlareBug "0"
// _killstreaks
set scr_killstreak_rollover "1"
set scr_currentRolloverKillstreaksOnlyIncrease "1"
set scr_killstreakHud "1"
set scr_maxKillstreakRollover "1"
set scr_killstreak_mod "0"
set scr_killstreak_print "1"
set scr_killstreak_print "2"
set scr_specialist "1"
//set scr_specialist_killCount_ "4"
set scr_specialist_perks1 "specialty_scavenger,specialty_fastreload,specialty_marathon"
@ -597,7 +615,7 @@ set scr_nuke_perm_vision "1"
set scr_nuke_canCall_whenTimePassed "0"
set scr_nuke_canCall_whenScoreLimitClose "0"
set scr_nuke_canCall_whenScoreLimitClose_selfOnly "0"
set scr_nuke_doSlowmo "1"
set scr_nuke_doSlowmo "2"
// _emp
set scr_emp_doesFriendlyFire "0"
@ -626,6 +644,7 @@ set scr_airdrop_patchDupeGlitch "0"
// _ac130
set scr_ac130_duration "30"
set scr_ac130_flares "1"
set scr_ac130_fast "1"
// _uav
set scr_uav_timeout "30"
@ -635,3 +654,6 @@ set scr_uav_does_print "1"
// _airstrike
set scr_harrier_duration "30"
set scr_harrier_fast "1"
set scr_airstrike_mutate_fix "1"
set scr_airstrike_teamChangeFix "1"

View File

@ -48,7 +48,6 @@ set sv_wwwDownload "1"
// NON-GAMEPLAY CONFIGURATION //
//////////////////////////////////////////////////
set rcon_password "qazqaz" // Access to your server to change stuff remotely or ingame. empty disabled
set sv_securityLevel "23" // Configures the servers security level.
set sv_customTextColor "" // custom color for ^;
set g_password "" // Password Protected Server. Leave blank if you want players to join
@ -114,10 +113,10 @@ set scr_classic "0" // Enable IW3 killstreak system
// //
// DO NOT ABUSE! Some people like to rank. //
// DON'T BE A DICK! Warn HIGH XP via hostname. //
// Don't know what you doing? Don't touch it! //
// Don't know what you doing? Dont touch it! //
//////////////////////////////////////////////////
set scr_xpscale "10" // IW's way of Double XP.
set scr_xpscale "10" // IWs way of Double XP.
//set scr_war_score_kill "0" // Amount of XP by each kill.
//set scr_war_score_headshot "0" // Amount of XP by each headshot.
@ -203,7 +202,7 @@ set scr_airdrop_mega_nuke "1"
//////////////////////////////////////////////////
set scr_dm_scorelimit "10000" // Score limit to win the game.
set scr_dm_timelimit "10" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_dm_timelimit "10" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_dm_playerrespawndelay "0" // How long player will wait until respawn.
set scr_dm_numlives "0" // Number of lives per player 0 for unlimited.
set scr_dm_roundlimit "1" // Rounds per game.
@ -215,7 +214,7 @@ set scr_dm_promode "0"
//////////////////////////////////////////////////
set scr_war_scorelimit "25600" // Score limit to win the game.
set scr_war_timelimit "10" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_war_timelimit "10" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_war_playerrespawndelay "0" // How long player will wait until respawn.
set scr_war_waverespawndelay "0" // Duration is seconds before the first respawn in each round.
set scr_war_numlives "0" // Number of lives per player 0 for unlimited.
@ -228,7 +227,7 @@ set scr_war_promode "0"
//////////////////////////////////////////////////
set scr_dom_scorelimit "300" // Score limit to win the game.
set scr_dom_timelimit "0" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_dom_timelimit "30" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_dom_playerrespawndelay "0" // How long player will wait until respawn.
set scr_dom_waverespawndelay "0" // Duration is seconds before the first respawn in each round.
set scr_dom_numlives "0" // Number of lives per player per game. 0 is unlimited.
@ -241,7 +240,7 @@ set scr_dom_promode "0"
//////////////////////////////////////////////////
set scr_dd_scorelimit "1" // Score limit needed to win.
set scr_dd_timelimit "2.5" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_dd_timelimit "2.5" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_dd_playerrespawndelay "0" // How long player will wait until respawn.
set scr_dd_waverespawndelay "0" // Duration is seconds before the first respawn in each round.
set scr_dd_numlives "0" // Number of lives per player per game. 0 is unlimited.
@ -257,7 +256,7 @@ set scr_dd_promode "0"
//////////////////////////////////////////////////
set scr_sd_scorelimit "1" // Score limit required to win the game.
set scr_sd_timelimit "2.5" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_sd_timelimit "2.5" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_sd_playerrespawndelay "0" // How long player will wait until respawn.
set scr_sd_waverespawndelay "0" // Duration is seconds before the first respawn in each round.
set scr_sd_numlives "1" // Number of lives per player per game.
@ -276,7 +275,7 @@ set scr_sd_promode "0"
//////////////////////////////////////////////////
set scr_sab_scorelimit "0" // Score limit to win the match.
set scr_sab_timelimit "20" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_sab_timelimit "20" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_sab_bombtimer "30" // Duration in seconds the bomb takes to detonate.
set scr_sab_defusetime "5" // Time taken to defuse the bomb.
set scr_sab_hotpotato "0" // One bomb that the teams must fight over. One defending and one have to plant at the site.
@ -294,7 +293,7 @@ set scr_sab_promode "0"
//////////////////////////////////////////////////
set scr_ctf_scorelimit "0" // Target score before the round ends.
set scr_ctf_timelimit "10" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_ctf_timelimit "10" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_ctf_numlives "0" // Number of lives per player 0 for unlimited.
set scr_ctf_halftime "1" // Half-Time
set scr_ctf_roundlimit "1" // How many rounds match would last.
@ -308,7 +307,7 @@ set scr_ctf_promode "0"
//////////////////////////////////////////////////
set scr_oneflag_scorelimit "1" // Target score before the round ends.
set scr_oneflag_timelimit "3" // Duration in minutes for the game to end if the score limit isn't reached.
set scr_oneflag_timelimit "3" // Duration in minutes for the game to end if the score limit isnt reached.
set scr_oneflag_numlives "0" // number of lives per player 0 for unlimited.
set scr_oneflag_playerrespawndelay "0" // Respawn wait in seconds.
set scr_oneflag_roundlimit "1" // How many rounds match would last.
@ -321,7 +320,7 @@ set scr_oneflag_promode "0"
//////////////////////////////////////////////////
set scr_koth_scorelimit "250" // Score limit to win the game.
set scr_koth_timelimit "15" // Duration in minutes the game will continue if the score isn't reached.
set scr_koth_timelimit "15" // Duration in minutes the game will continue if the score isnt reached.
set scr_koth_numlives "0" // Number of lives per game. 0 for unlimited.
set scr_koth_playerrespawndelay "0" // Players respawn wait.
set scr_koth_roundlimit "1" // Rounds to be played.
@ -335,7 +334,7 @@ set scr_koth_promode "0"
//////////////////////////////////////////////////
set scr_arena_scorelimit "1" // Score limit to win the game.
set scr_arena_timelimit "2.5" // Duration in minutes the game will continue if the score isn't reached.
set scr_arena_timelimit "2.5" // Duration in minutes the game will continue if the score isnt reached.
set scr_arena_numlives "1" // Number of lives per game 0 for unlimited.
set scr_arena_roundlimit "0" // Rounds to be played.
set scr_arena_roundswitch "3" // Rounds before the teams switch sides.
@ -348,7 +347,7 @@ set scr_arena_promode "0"
//////////////////////////////////////////////////
set scr_gtnw_scorelimit "101" // Score limit to win the game.
set scr_gtnw_timelimit "10" // Duration in minutes the game will continue if the score isn't reached.
set scr_gtnw_timelimit "10" // Duration in minutes the game will continue if the score isnt reached.
set scr_gtnw_numlives "0" // Number of lives per game 0 for unlimited.
set scr_gtnw_playerrespawndelay "0" // Players respawn wait.
set scr_gtnw_roundlimit "1" // Rounds to be played.
@ -516,8 +515,10 @@ set scr_player_forceclassselection ""
set scr_player_allowChangeTeam "1"
// _bot
set bot_main "1"
set bots_main "1"
set bots_main_GUIDs ""
set bots_main_firstIsHost "0"
set bots_main_waitForHostTime "10"
set bots_manage_add "12"
set bots_manage_fill "12"
set bots_manage_fill_spec "0"
@ -534,6 +535,19 @@ set bots_skill_allies_hard "0"
set bots_skill_allies_med "0"
set bots_loadout_reasonable "1"
set bots_loadout_allow_op "0"
set bots_loadout_rank "-1"
set bots_loadout_prestige "-1"
set bots_play_move "1"
set bots_play_knife "1"
set bots_play_fire "1"
set bots_play_nade "1"
set bots_play_take_carepackages "1"
set bots_play_obj "1"
set bots_play_camp "1"
set bots_play_jumpdrop "1"
set bots_play_target_other "1"
set bots_play_killstreak "1"
set bots_play_ads "1"
// iw4madmin
@ -576,13 +590,15 @@ set scr_deleteNadeOnTeamChange "1"
// _perkfunctions
set combathighIsJuiced "1"
set onemanarmyRefillsTubes "1"
set fix_onemanarmyFlareBug "0"
// _killstreaks
set scr_killstreak_rollover "1"
set scr_currentRolloverKillstreaksOnlyIncrease "1"
set scr_killstreakHud "1"
set scr_maxKillstreakRollover "1"
set scr_killstreak_mod "0"
set scr_killstreak_print "1"
set scr_killstreak_print "2"
set scr_specialist "1"
//set scr_specialist_killCount_ "4"
set scr_specialist_perks1 "specialty_scavenger,specialty_fastreload,specialty_marathon"
@ -597,7 +613,7 @@ set scr_nuke_perm_vision "1"
set scr_nuke_canCall_whenTimePassed "0"
set scr_nuke_canCall_whenScoreLimitClose "0"
set scr_nuke_canCall_whenScoreLimitClose_selfOnly "0"
set scr_nuke_doSlowmo "1"
set scr_nuke_doSlowmo "2"
// _emp
set scr_emp_doesFriendlyFire "0"
@ -626,6 +642,7 @@ set scr_airdrop_patchDupeGlitch "0"
// _ac130
set scr_ac130_duration "30"
set scr_ac130_flares "1"
set scr_ac130_fast "1"
// _uav
set scr_uav_timeout "30"
@ -635,3 +652,6 @@ set scr_uav_does_print "1"
// _airstrike
set scr_harrier_duration "30"
set scr_harrier_fast "1"
set scr_airstrike_mutate_fix "1"
set scr_airstrike_teamChangeFix "1"

View File

@ -1,4 +1,4 @@
# IW4x Bot Warfare v2.0.0
# IW4x Bot Warfare v2.1.0
Bot Warfare is a GSC mod for the IW4x project.
It aims to add playable AI to the multiplayer games of Modern Warfare 2.
@ -23,9 +23,54 @@ You can find the GitHub containing more info at https://github.com/ineedbots/iw4
- Pressing the menu button again closes menus.
## Changelog
- v2.1.0
- Bot chatter system, bots_main_chat
- Greatly reduce script variable usage
- Fix bots slowly reacting in remote streaks
- Improved bots mantling and stuck
- Improved bots aim
- Fix some runtime errors
- Fixed bots aim in third person
- Bots sprint more
- Improved bots sight on enemies
- Bots play hidden gamemodes like one-flag and arena
- 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
- Fixed demolition spawn killing
- Improved domination
- Bots use explosives more if they have it
- Fixed bots moving their player when using remote
- Bots aim slower when ads'ing
- Fixed bots holding breath
- Bots are more smart when waiting for carepackages
- Improved and fixed various waypoints for maps
- 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
- TODOs
- A variable leak in _menu (script)
- Recoil for bots (engine, maybe script)
- Use proper activate button for bombs, carepackages, etc (script, use +activate)
- Proper weapon swaps, including altmode (engine, then script)
- Use static turrets in maps (script)
- Proper use of pred missile (script and engine)
- Fix testclient view angle clamping (messes with ac130 and chopper gunner) (engine)
## Credits
- IW4x Team - https://github.com/XLabsProject/iw4x-client
- CoD4x Team - https://github.com/callofduty4x/CoD4x_Server
@ -35,6 +80,7 @@ You can find the GitHub containing more info at https://github.com/ineedbots/iw4
- apdonato - http://rsebots.blogspot.ca/
- Ability
- Salvation
- VicRattlehead - https://www.moddb.com/members/vicrattlehead
Feel free to use code, host on other sites, host on servers, mod it and merge mods with it, just give credit where credit is due!
-INeedGames/INeedBot(s) @ ineedbots@outlook.com

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: 2.9 MiB

View File

@ -1,26 +1,26 @@
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
bota
botb
botc
botd
bote
botf
botg
both
boti
botj
botk
botl
botm
botn
boto
botp
botq
botr
bots
bott
botu
botv
botw
botx
boty
botz

View File

@ -0,0 +1,360 @@
InitStingerUsage()
{
self.stingerStage = undefined;
self.stingerTarget = undefined;
self.stingerLockStartTime = undefined;
self.stingerLostSightlineTime = undefined;
self thread ResetStingerLockingOnDeath();
level.stingerTargets = [];
}
ResetStingerLocking()
{
if ( !IsDefined( self.stingerUseEntered ) )
return;
self.stingerUseEntered = undefined;
self notify( "stop_javelin_locking_feedback" );
self notify( "stop_javelin_locked_feedback" );
self WeaponLockFree();
InitStingerUsage();
}
ResetStingerLockingOnDeath()
{
self endon( "disconnect" );
self notify ( "ResetStingerLockingOnDeath" );
self endon ( "ResetStingerLockingOnDeath" );
for ( ;; )
{
self waittill( "death" );
self ResetStingerLocking();
}
}
StillValidStingerLock( ent )
{
assert( IsDefined( self ) );
if ( !IsDefined( ent ) )
return false;
if ( !(self WorldPointInReticle_Circle( ent.origin, 65, 85 )) )
return false;
if ( self.stingerTarget == level.ac130.planeModel && !isDefined( level.ac130player ) )
return false;
return true;
}
LoopStingerLockingFeedback()
{
self endon( "stop_javelin_locking_feedback" );
for ( ;; )
{
if ( isDefined( level.chopper ) && isDefined( level.chopper.gunner ) && isDefined( self.stingerTarget ) && self.stingerTarget == level.chopper )
level.chopper.gunner playLocalSound( "missile_locking" );
if ( isDefined( level.ac130player ) && isDefined( self.stingerTarget ) && self.stingerTarget == level.ac130.planeModel )
level.ac130player playLocalSound( "missile_locking" );
self playLocalSound( "stinger_locking" );
self PlayRumbleOnEntity( "ac130_25mm_fire" );
wait 0.6;
}
}
LoopStingerLockedFeedback()
{
self endon( "stop_javelin_locked_feedback" );
for ( ;; )
{
if ( isDefined( level.chopper ) && isDefined( level.chopper.gunner ) && isDefined( self.stingerTarget ) && self.stingerTarget == level.chopper )
level.chopper.gunner playLocalSound( "missile_locking" );
if ( isDefined( level.ac130player ) && isDefined( self.stingerTarget ) && self.stingerTarget == level.ac130.planeModel )
level.ac130player playLocalSound( "missile_locking" );
self playLocalSound( "stinger_locked" );
self PlayRumbleOnEntity( "ac130_25mm_fire" );
wait 0.25;
}
}
/#
DrawStar( point )
{
Line( point + (10,0,0), point - (10,0,0) );
Line( point + (0,10,0), point - (0,10,0) );
Line( point + (0,0,10), point - (0,0,10) );
}
#/
LockSightTest( target )
{
eyePos = self GetEye();
if ( !isDefined( target ) ) //targets can disapear during targeting.
return false;
passed = BulletTracePassed( eyePos, target.origin, false, target );
if ( passed )
return true;
front = target GetPointInBounds( 1, 0, 0 );
passed = BulletTracePassed( eyePos, front, false, target );
if ( passed )
return true;
back = target GetPointInBounds( -1, 0, 0 );
passed = BulletTracePassed( eyePos, back, false, target );
if ( passed )
return true;
return false;
}
StingerDebugDraw( target )
{
/#
if ( GetDVar( "missileDebugDraw" ) != "1" )
return;
if ( !IsDefined( target ) )
return;
org = target.origin;
DrawStar( org );
org = target GetPointInBounds( 1, 0, 0 );
DrawStar( org );
org = target GetPointInBounds( -1, 0, 0 );
DrawStar( org );
#/
}
SoftSightTest()
{
LOST_SIGHT_LIMIT = 500;
if ( self LockSightTest( self.stingerTarget ) )
{
self.stingerLostSightlineTime = 0;
return true;
}
if ( self.stingerLostSightlineTime == 0 )
self.stingerLostSightlineTime = getTime();
timePassed = GetTime() - self.stingerLostSightlineTime;
//PrintLn( "Losing sight of target [", timePassed, "]..." );
if ( timePassed >= LOST_SIGHT_LIMIT )
{
//PrintLn( "Lost sight of target." );
ResetStingerLocking();
return false;
}
return true;
}
GetTargetList()
{
targets = [];
if ( level.teamBased )
{
if ( IsDefined( level.chopper ) && ( level.chopper.team != self.team || level.chopper.owner == self ) )
targets[targets.size] = level.chopper;
if ( isDefined( level.ac130player ) && level.ac130player.team != self.team )
targets[targets.size] = level.ac130.planemodel;
if ( isDefined( level.harriers) )
{
foreach( harrier in level.harriers )
{
if ( isDefined( harrier ) && ( harrier.team != self.team || ( isDefined( harrier.owner ) && harrier.owner == self ) ) )
targets[targets.size] = harrier;
}
}
if ( level.UAVModels[level.otherTeam[self.team]].size )
{
foreach ( UAV in level.UAVModels[level.otherTeam[self.team]] )
targets[targets.size] = UAV;
}
if ( isDefined( level.littleBird ) )
{
foreach ( bird in level.littleBird )
{
if ( !isDefined( bird ) )
continue;
if ( self.team != bird.owner.team || self == bird.owner )
targets[targets.size] = bird;
}
}
}
else
{
if ( IsDefined( level.chopper ) && ( level.chopper.owner != self ) ) ///check for teams
targets[targets.size] = level.chopper;
if ( isDefined( level.ac130player ) )
targets[targets.size] = level.ac130.planemodel;
if ( isDefined( level.harriers) )
{
foreach( harrier in level.harriers )
{
if ( isDefined( harrier ) )
targets[targets.size] = harrier;
}
}
if ( level.UAVModels.size )
{
foreach ( ownerGuid, UAV in level.UAVModels )
{
if ( isDefined( UAV.owner ) && UAV.owner == self )
continue;
targets[targets.size] = UAV;
}
}
}
return targets;
}
StingerUsageLoop()
{
self endon("death");
self endon("disconnect");
LOCK_LENGTH = 1000;
InitStingerUsage();
for( ;; )
{
wait 0.05;
weapon = self getCurrentWeapon();
if ( weapon != "stinger_mp" && weapon != "at4_mp" )
{
ResetStingerLocking();
continue;
}
if ( self PlayerADS() < 0.95 )
{
ResetStingerLocking();
continue;
}
self.stingerUseEntered = true;
if ( !IsDefined( self.stingerStage ) )
self.stingerStage = 0;
StingerDebugDraw( self.stingerTarget );
if ( self.stingerStage == 0 ) // searching for target
{
targets = GetTargetList();
if ( targets.size == 0 )
continue;
targetsInReticle = [];
foreach ( target in targets )
{
if ( !isDefined( target ) )
continue;
insideReticle = self WorldPointInReticle_Circle( target.origin, 65, 75 );
if ( insideReticle )
targetsInReticle[targetsInReticle.size] = target;
}
if ( targetsInReticle.size == 0 )
continue;
sortedTargets = SortByDistance( targetsInReticle, self.origin );
if ( !( self LockSightTest( sortedTargets[0] ) ) )
continue;
//PrintLn( "Found a target to lock to..." );
thread LoopStingerLockingFeedback();
self.stingerTarget = sortedTargets[0];
self.stingerLockStartTime = GetTime();
self.stingerStage = 1;
self.stingerLostSightlineTime = 0;
}
if ( self.stingerStage == 1 ) // locking on to a target
{
if ( !(self StillValidStingerLock( self.stingerTarget )) )
{
//PrintLn( "Failed to get lock." );
ResetStingerLocking();
continue;
}
passed = SoftSightTest();
if ( !passed )
continue;
timePassed = getTime() - self.stingerLockStartTime;
//PrintLn( "Locking [", timePassed, "]..." );
if ( timePassed < LOCK_LENGTH )
continue;
self notify( "stop_javelin_locking_feedback" );
thread LoopStingerLockedFeedback();
//PrintLn( "Locked!");
if ( self.stingerTarget.model == "vehicle_av8b_harrier_jet_mp" || self.stingerTarget.model == "vehicle_little_bird_armed" )
self WeaponLockFinalize( self.stingerTarget );
else
self WeaponLockFinalize( self.stingerTarget, (100,0,-32) );
self.stingerStage = 2;
}
if ( self.stingerStage == 2 ) // target locked
{
passed = SoftSightTest();
if ( !passed )
continue;
if ( !(self StillValidStingerLock( self.stingerTarget )) )
{
//PrintLn( "Gave up lock." );
ResetStingerLocking();
continue;
}
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -14,56 +14,56 @@ 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;
}
/*
Will attempt to retreive waypoints from the internet
*/
getRemoteWaypoints(mapname)
getRemoteWaypoints( mapname )
{
url = "https://raw.githubusercontent.com/ineedbots/iw4x_waypoints/master/" + mapname + "_wp.csv";
url = "https://raw.githubusercontent.com/ineedbots/iw4x_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" );
}
}
/*
@ -71,45 +71,46 @@ getRemoteWaypoints(mapname)
*/
getRemoteVersion()
{
request = httpGet( "https://raw.githubusercontent.com/ineedbots/iw4x_waypoints/master/version.txt" );
request = httpGet( "https://raw.githubusercontent.com/ineedbots/iw4x_waypoints/master/version.txt" );
if (!isDefined(request))
if ( !isDefined( request ) )
return undefined;
request waittill( "done", success, data );
request waittill( "done", success, data );
if (!success)
return undefined;
if ( !success )
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 = [];
request = httpGet( url );
if (!isDefined(request))
if ( !isDefined( request ) )
return result;
request waittill( "done", success, data );
request waittill( "done", success, data );
if (!success)
return result;
if ( !success )
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;
@ -119,7 +120,8 @@ getLinesFromUrl(url, filename)
line += c;
}
result.lines[result.lines.size] = line;
result.lines[result.lines.size] = line;
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

File diff suppressed because it is too large Load Diff

View File

@ -1114,6 +1114,9 @@ setKillstreaks( streak1, streak2, streak3 )
// defcon rollover
maxRollOvers = 10;
if (isDefined(level.maxKillstreakRollover))
maxRollOvers = level.maxKillstreakRollover;
newKillstreaks = self.killstreaks;
for ( rollOver = 1; rollOver <= maxRollOvers; rollOver++ )
{
@ -1124,6 +1127,7 @@ setKillstreaks( streak1, streak2, streak3 )
}
self.killstreaks = newKillstreaks;
self.maxKillstreakVal = maxVal;
}

View File

@ -251,17 +251,30 @@ handleNormalDeath( lifeId, attacker, eInflictor, sWeapon, sMeansOfDeath )
{
if (level.killstreaksIncreaseKillstreak)
{
toLifeId = attacker.pers["deaths"];
if (isDefined(attacker.maxKillstreakVal) && attacker.maxKillstreakVal > 0 && isDefined(level.rolloverKillstreaksOnlyIncrease) && level.rolloverKillstreaksOnlyIncrease)
{
curRollover = int(attacker.pers["cur_kill_streak"]/attacker.maxKillstreakVal);
if (curRollover > 0)
{
if (curRollover == 1)
toLifeId += 0.75;
else
toLifeId += 1/curRollover;
}
}
switch ( sWeapon )
{
case "ac130_105mm_mp":
case "ac130_40mm_mp":
case "ac130_25mm_mp":
if ( attacker.ac130LifeId == attacker.pers["deaths"] )
if ( attacker.ac130LifeId == toLifeId )
attacker.pers["cur_kill_streak"]++;
break;
case "cobra_player_minigun_mp":
case "weapon_cobra_mk19_mp":
if ( attacker.heliRideLifeId == attacker.pers["deaths"] )
if ( attacker.heliRideLifeId == toLifeId )
attacker.pers["cur_kill_streak"]++;
break;
case "cobra_20mm_mp":
@ -277,7 +290,7 @@ handleNormalDeath( lifeId, attacker, eInflictor, sWeapon, sMeansOfDeath )
else
killstreakLifeId = attacker.lifeId;
if ( killstreakLifeId == attacker.pers["deaths"] && (level.nukeIncreasesStreak || sWeapon != "nuke_mp") )
if ( killstreakLifeId == toLifeId && (level.nukeIncreasesStreak || sWeapon != "nuke_mp") )
attacker.pers["cur_kill_streak"]++;
break;
default:
@ -1447,7 +1460,7 @@ Callback_PlayerDamage_internal( eInflictor, eAttacker, victim, iDamage, iDFlags,
if ( attackerIsNPC && isDefined( eAttacker.gunner ) )
damager = eAttacker.gunner;
else if( level.extraDamageFeedback && isDefined( eAttacker.owner ) )
else if( level.extraDamageFeedback && isDefined( eAttacker ) && isDefined( eAttacker.owner ) )
damager = eAttacker.owner;
else
damager = eAttacker;
@ -1579,17 +1592,62 @@ Callback_PlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, s
}
doPrintDamage(dmg, hitloc, flags)
{
self endon( "disconnect" );
huddamage = newclienthudelem(self);
huddamage.alignx = "center";
huddamage.horzalign = "center";
huddamage.x = 10;
huddamage.y = 235;
huddamage.fontscale = 1.6;
huddamage.font = "objective";
huddamage setvalue(dmg);
if ((flags & level.iDFLAGS_RADIUS) != 0)
huddamage.color = (0.25, 0.25, 0.25);
if ((flags & level.iDFLAGS_PENETRATION) != 0)
huddamage.color = (1, 1, 0.25);
if (hitloc == "head")
huddamage.color = (1, 0.25, 0.25);
huddamage moveovertime(1);
huddamage fadeovertime(1);
huddamage.alpha = 0;
huddamage.x = randomIntRange(25, 70);
val = 1;
if (cointoss())
val = -1;
huddamage.y = 235 + randomIntRange(25, 70) * val;
wait 1;
if ( isDefined( huddamage ) )
huddamage destroy();
}
finishPlayerDamageWrapper( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, psOffsetTime, stunFraction )
{
if( level.allowPrintDamage )
{
if ( isDefined( eAttacker ) && isPlayer( eAttacker ) && eAttacker.printDamage )
eAttacker iPrintLnBold( iDamage );
if ( !isDefined( eAttacker ) )
{
if ( !isDefined( eInflictor ) && self.printDamage )
self thread doPrintDamage( iDamage, sHitLoc, iDFlags );
}
else if ( isPlayer( eAttacker ) && eAttacker.printDamage )
eAttacker thread doPrintDamage( iDamage, sHitLoc, iDFlags );
else if( isDefined( eAttacker.owner ) && isPlayer( eAttacker.owner ) && eAttacker.owner.printDamage )
eAttacker.owner iPrintLnBold( iDamage );
eAttacker.owner thread doPrintDamage( iDamage, sHitLoc, iDFlags );
}
if( level.extraDamageFeedback )
if( isDefined( eAttacker ) && level.extraDamageFeedback )
{
if( sWeapon == "nuke_mp" )
{
@ -1605,7 +1663,7 @@ finishPlayerDamageWrapper( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeat
if( sHitLoc == "head" || sHitLoc == "helmet" )
{
if ( isDefined( eAttacker ) && isPlayer( eAttacker ) )
if ( isPlayer( eAttacker ) )
eAttacker playLocalSound( "bullet_impact_headshot_2" );
else if( isDefined( eAttacker.owner ) && isPlayer( eAttacker.owner ) )
eAttacker.owner playLocalSound( "bullet_impact_headshot_2" );

View File

@ -0,0 +1,249 @@
#include maps\mp\_utility;
init()
{
level.persistentDataInfo = [];
maps\mp\gametypes\_class::init();
maps\mp\gametypes\_rank::init();
maps\mp\gametypes\_missions::init();
maps\mp\gametypes\_playercards::init();
level thread updateBufferedStats();
}
initBufferedStats()
{
self.bufferedStats = [];
self.bufferedStats[ "totalShots" ] = self getPlayerData( "totalShots" );
self.bufferedStats[ "accuracy" ] = self getPlayerData( "accuracy" );
self.bufferedStats[ "misses" ] = self getPlayerData( "misses" );
self.bufferedStats[ "hits" ] = self getPlayerData( "hits" );
self.bufferedStats[ "timePlayedAllies" ] = self getPlayerData( "timePlayedAllies" );
self.bufferedStats[ "timePlayedOpfor" ] = self getPlayerData( "timePlayedOpfor" );
self.bufferedStats[ "timePlayedOther" ] = self getPlayerData( "timePlayedOther" );
self.bufferedStats[ "timePlayedTotal" ] = self getPlayerData( "timePlayedTotal" );
self.bufferedChildStats = [];
self.bufferedChildStats[ "round" ] = [];
self.bufferedChildStats[ "round" ][ "timePlayed" ] = self getPlayerData( "round", "timePlayed" );
}
// ==========================================
// Script persistent data functions
// These are made for convenience, so persistent data can be tracked by strings.
// They make use of code functions which are prototyped below.
/*
=============
statGet
Returns the value of the named stat
=============
*/
statGet( dataName )
{
assert( !isDefined( self.bufferedStats[ dataName ] ) ); // should use statGetBuffered consistently with statSetBuffered
return self GetPlayerData( dataName );
}
/*
=============
statSet
Sets the value of the named stat
=============
*/
statSet( dataName, value )
{
assert( !isDefined( self.bufferedStats[ dataName ] ) ); // should use statGetBuffered consistently with statSetBuffered
if ( !self rankingEnabled() )
return;
if (getDvarInt("developer_script"))
return;
self SetPlayerData( dataName, value );
}
/*
=============
statAdd
Adds the passed value to the value of the named stat
=============
*/
statAdd( dataName, value )
{
assert( !isDefined( self.bufferedStats[ dataName ] ) ); // should use statGetBuffered consistently with statSetBuffered
if ( !self rankingEnabled() )
return;
if (getDvarInt("developer_script"))
return;
curValue = self GetPlayerData( dataName );
self SetPlayerData( dataName, value + curValue );
}
statGetChild( parent, child )
{
return self GetPlayerData( parent, child );
}
statSetChild( parent, child, value )
{
if ( !self rankingEnabled() )
return;
if (getDvarInt("developer_script"))
return;
self SetPlayerData( parent, child, value );
}
statAddChild( parent, child, value )
{
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
if ( !self rankingEnabled() )
return;
if (getDvarInt("developer_script"))
return;
curValue = self GetPlayerData( parent, child );
self SetPlayerData( parent, child, curValue + value );
}
statGetChildBuffered( parent, child )
{
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
return self.bufferedChildStats[ parent ][ child ];
}
statSetChildBuffered( parent, child, value )
{
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
if ( !self rankingEnabled() )
return;
self.bufferedChildStats[ parent ][ child ] = value;
}
statAddChildBuffered( parent, child, value )
{
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
if ( !self rankingEnabled() )
return;
curValue = statGetChildBuffered( parent, child );
statSetChildBuffered( parent, child, curValue + value );
}
/*
=============
statGetBuffered
Returns the value of the named stat
=============
*/
statGetBuffered( dataName )
{
assert( isDefined( self.bufferedStats[ dataName ] ) );
return self.bufferedStats[ dataName ];
}
/*
=============
statSet
Sets the value of the named stat
=============
*/
statSetBuffered( dataName, value )
{
assert( isDefined( self.bufferedStats[ dataName ] ) );
if ( !self rankingEnabled() )
return;
self.bufferedStats[ dataName ] = value;
}
/*
=============
statAdd
Adds the passed value to the value of the named stat
=============
*/
statAddBuffered( dataName, value )
{
assert( isDefined( self.bufferedStats[ dataName ] ) );
if ( !self rankingEnabled() )
return;
curValue = statGetBuffered( dataName );
statSetBuffered( dataName, curValue + value );
}
updateBufferedStats()
{
// give the first player time to connect
wait ( 0.15 );
nextToUpdate = 0;
while ( !level.gameEnded )
{
nextToUpdate++;
if ( nextToUpdate >= level.players.size )
nextToUpdate = 0;
if ( isDefined( level.players[nextToUpdate] ) )
level.players[nextToUpdate] writeBufferedStats();
wait ( 2.0 );
}
foreach ( player in level.players )
player writeBufferedStats();
}
writeBufferedStats()
{
if (getDvarInt("developer_script"))
return;
foreach ( statName, statVal in self.bufferedStats )
{
self setPlayerData( statName, statVal );
}
foreach ( statName, statVal in self.bufferedChildStats )
{
foreach ( childStatName, childStatVal in statVal )
self setPlayerData( statName, childStatName, childStatVal );
}
}

View File

@ -609,6 +609,8 @@ getSpawnpoint_NearTeam( spawnpoints, favoredspawnpoints )
obj = spawnstruct();
alliedDistanceWeight = 2;
if ( getDVar( "scr_alliedDistanceWeight" ) != "" )
alliedDistanceWeight = getDVarFloat( "scr_alliedDistanceWeight" );
//prof_begin(" spawn_basicsumdists");
myTeam = self.team;

View File

@ -7,6 +7,8 @@
Fixes claymores from tripping when the victim is elevated from the claymore.
Fixes stuns and flashes friendly fire on claymores and c4s.
Fixes direct impact stun stunning the victim.
Fixes missile and grenade threads being killed on death.
Fixes new c4s and claymores after an emp not being affected
DVARS:
- scr_allowDropWeaponOnCommand <bool>
@ -1179,7 +1181,7 @@ friendlyFireCheck( owner, attacker, forcedFriendlyFireRule )
watchGrenadeUsage()
{
self endon( "death" );
self endon( "spawned_player" );
self endon( "disconnect" );
self.throwingGrenade = undefined;
@ -1247,6 +1249,7 @@ watchGrenadeUsage()
deleteOnOwnerTeamChange( owner )
{
self notify( "delete_on_team_overlap" );
self endon( "delete_on_team_overlap" );
self endon( "death" );
@ -1258,7 +1261,7 @@ deleteOnOwnerTeamChange( owner )
beginGrenadeTracking()
{
self endon( "death" );
self endon( "spawned_player" );
self endon( "disconnect" );
self endon( "offhand_end" );
self endon( "weapon_change" );
@ -1329,7 +1332,7 @@ AddMissileToSightTraces( team )
watchMissileUsage()
{
self endon( "death" );
self endon( "spawned_player" );
self endon( "disconnect" );
for ( ;; )
@ -1412,7 +1415,7 @@ empExplodeWaiter()
beginC4Tracking()
{
self endon( "death" );
self endon( "spawned_player" );
self endon( "disconnect" );
self waittill_any( "grenade_fire", "weapon_change", "offhand_end" );
@ -1421,7 +1424,7 @@ beginC4Tracking()
watchForThrowbacks()
{
self endon( "death" );
self endon( "spawned_player" );
self endon( "disconnect" );
for ( ;; )
@ -1446,10 +1449,7 @@ watchForThrowbacks()
if( level.extraTeamIcons )
grenade thread setClaymoreTeamHeadIcon( self.pers[ "team" ] );
if ( level.deleteNadeOnTeamChange )
{
grenade notify( "delete_on_team_overlap" );
grenade thread deleteOnOwnerTeamChange( self );
}
}
}
@ -1529,12 +1529,22 @@ c4EMPKillstreakWait()
{
self endon( "death" );
if ( (level.teamBased && level.teamEMPed[self.team]) || (!level.teamBased && isDefined( level.empPlayer ) && level.empPlayer != self.owner ) )
{
playfxOnTag( getfx( "sentry_explode_mp" ), self, "tag_origin" );
self.disabled = true;
self notify( "disabled" );
}
for ( ;; )
{
level waittill( "emp_update" );
if ( (level.teamBased && level.teamEMPed[self.team]) || (!level.teamBased && isDefined( level.empPlayer ) && level.empPlayer != self.owner ) )
{
playfxOnTag( getfx( "sentry_explode_mp" ), self, "tag_origin" );
self.disabled = true;
self notify( "disabled" );
}
@ -1562,7 +1572,7 @@ setClaymoreTeamHeadIcon( team )
{
self endon( "death" );
if ( self.weaponname == "claymore_mp" && !level.allowExtendedClaymoreTrace )
if ( isDefined( self.weaponname ) && self.weaponname == "claymore_mp" && !level.allowExtendedClaymoreTrace )
{
self waittill( "missile_stuck" );
self waittill( "claymore_trace_fixed" );
@ -1570,6 +1580,9 @@ setClaymoreTeamHeadIcon( team )
else
wait 0.05;
if ( !isDefined( self ) )
return;
if ( isDefined( self.entityHeadIcon ) )
{
self.entityHeadIconTeam = "none";
@ -1949,7 +1962,7 @@ waitAndDetonate( delay )
deleteC4AndClaymoresOnDisconnect()
{
self endon( "death" );
self endon( "spawned_player" );
self waittill( "disconnect" );
c4array = self.c4array;
@ -2679,6 +2692,42 @@ detach_hip_weapon()
}
FixHideTagList( hideTagList, stowWeapon )
{
answer = [];
for ( i = 0; i < hideTagList.size; i++ )
{
tag = hideTagList[ i ];
if ( stowWeapon == "weapon_ak74u" )
{
if ( tag == "tag_reflex_sight" || tag == "tag_acog" || tag == "tag_ak47_mount" )
continue;
}
else if ( stowWeapon == "weapon_ak47_classic" )
{
if ( tag == "tag_reflex_sight" || tag == "tag_acog" || tag == "tag_ak47_mount" )
continue;
}
else if ( stowWeapon == "worldmodel_bo2_peacekeeper" )
{
if ( tag == "tag_holo" || tag == "tag_reflex" || tag == "tag_silencer" )
continue;
}
else if ( stowWeapon == "weapon_beretta" )
{
if ( tag == "tag_knife" )
continue;
}
answer[ answer.size ] = tag;
}
return answer;
}
stow_on_back()
{
prof_begin( "stow_on_back" );
@ -2769,6 +2818,8 @@ stow_on_back()
return;
}
hideTagList = FixHideTagList( hideTagList, self.tag_stowed_back );
for ( i = 0; i < hideTagList.size; i++ )
self HidePart( hideTagList[ i ], self.tag_stowed_back );
@ -2806,6 +2857,8 @@ stow_on_hip()
if ( !isDefined( hideTagList ) )
return;
hideTagList = FixHideTagList( hideTagList, self.tag_stowed_hip );
for ( i = 0; i < hideTagList.size; i++ )
self HidePart( hideTagList[ i ], self.tag_stowed_hip );
}

View File

@ -0,0 +1,909 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
Action SAB/SD = DD
Attackers objective: Bomb both of 2 positions
Defenders objective: Defend these 2 positions / Defuse planted bombs
Round ends: When one team defends for duration of match, both sites are destroyed.
Map ends: When one team reaches the score limit, or time limit or round limit is reached
Respawning: Players respawn indefinetly and immediately
Level requirements
------------------
Allied Spawnpoints:
classname mp_sd_spawn_attacker
Allied players spawn from these. Place at least 16 of these relatively close together.
Axis Spawnpoints:
classname mp_sd_spawn_defender
Axis players spawn from these. Place at least 16 of these relatively close together.
Spectator Spawnpoints:
classname mp_global_intermission
Spectators spawn from these and intermission is viewed from these positions.
Atleast one is required, any more and they are randomly chosen between.
Bombzones:
classname trigger_multiple
targetname bombzone
script_gameobjectname bombzone
script_bombmode_original <if defined this bombzone will be used in the original bomb mode>
script_bombmode_single <if defined this bombzone will be used in the single bomb mode>
script_bombmode_dual <if defined this bombzone will be used in the dual bomb mode>
script_team Set to allies or axis. This is used to set which team a bombzone is used by in dual bomb mode.
script_label Set to A or B. This sets the letter shown on the compass in original mode.
This is a volume of space in which the bomb can planted. Must contain an origin brush.
Bomb:
classname trigger_lookat
targetname bombtrigger
script_gameobjectname bombzone
This should be a 16x16 unit trigger with an origin brush placed so that it's center lies on the bottom plane of the trigger.
Must be in the level somewhere. This is the trigger that is used when defusing a bomb.
It gets moved to the position of the planted bomb model.
Level script requirements
-------------------------
Team Definitions:
game["attackers"] = "allies";
game["defenders"] = "axis";
This sets which team is attacking and which team is defending. Attackers plant the bombs. Defenders protect the targets.
Exploder Effects:
Setting script_noteworthy on a bombzone trigger to an exploder group can be used to trigger additional effects.
multiple bombs
multiple targets
spawning
round handling when both sites are destroyed
*/
/*QUAKED mp_dd_spawn_attacker_a (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn near bomb a.*/
/*QUAKED mp_dd_spawn_attacker_b (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn near bomb b.*/
/*QUAKED mp_dd_spawn_attacker (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_dd_spawn_defender (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_dd_spawn_defender_a (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn near bomb site a.*/
/*QUAKED mp_dd_spawn_defender_b (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn near bomb site b.*/
/*QUAKED mp_dd_spawn_attacker_start (0.0 1.0 0.0) (-16 -16 0) (16 16 72)
Attacking players spawn randomly at one of these positions at the beginning of a round.*/
/*QUAKED mp_dd_spawn_defender_start (1.0 0.0 0.0) (-16 -16 0) (16 16 72)
Defending players spawn randomly at one of these positions at the beginning of a round.*/
main()
{
if(getdvar("mapname") == "mp_background")
return;
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerRoundSwitchDvar( level.gameType, 1, 0, 9 );
registerTimeLimitDvar( level.gameType, 3, 0, 1440 );
registerScoreLimitDvar( level.gameType, 0, 0, 500 );
registerRoundLimitDvar( level.gameType, 3, 0, 12 );
registerWinLimitDvar( level.gameType, 2, 0, 12 );
registerNumLivesDvar( level.gameType, 0, 0, 10 );
registerHalfTimeDvar( level.gameType, 0, 0, 1 );
level.objectiveBased = true;
level.teamBased = true;
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onSpawnPlayer = ::onSpawnPlayer;
level.onDeadEvent = ::onDeadEvent;
level.onTimeLimit = ::onTimeLimit;
level.onNormalDeath = ::onNormalDeath;
level.initGametypeAwards = ::initGametypeAwards;
level.dd = true;
level.bombsPlanted = 0;
level.ddBombModel = []
setBombTimerDvar();
makeDvarServerInfo( "ui_bombtimer_a", -1 );
makeDvarServerInfo( "ui_bombtimer_b", -1 );
game["dialog"]["gametype"] = "demolition";
if ( getDvarInt( "g_hardcore" ) )
game["dialog"]["gametype"] = "hc_" + game["dialog"]["gametype"];
else if ( getDvarInt( "camera_thirdPerson" ) )
game["dialog"]["gametype"] = "thirdp_" + game["dialog"]["gametype"];
else if ( getDvarInt( "scr_diehard" ) )
game["dialog"]["gametype"] = "dh_" + game["dialog"]["gametype"];
else if (getDvarInt( "scr_" + level.gameType + "_promode" ) )
game["dialog"]["gametype"] = game["dialog"]["gametype"] + "_pro";
game["dialog"]["offense_obj"] = "obj_destroy";
game["dialog"]["defense_obj"] = "obj_defend";
}
onPrecacheGameType()
{
game["bomb_dropped_sound"] = "mp_war_objective_lost";
game["bomb_recovered_sound"] = "mp_war_objective_taken";
precacheShader("waypoint_bomb");
precacheShader("hud_suitcase_bomb");
precacheShader("waypoint_target");
precacheShader("waypoint_target_a");
precacheShader("waypoint_target_b");
precacheShader("waypoint_defend");
precacheShader("waypoint_defend_a");
precacheShader("waypoint_defend_b");
precacheShader("waypoint_defuse_a");
precacheShader("waypoint_defuse_b");
precacheShader("waypoint_target");
precacheShader("waypoint_target_a");
precacheShader("waypoint_target_b");
precacheShader("waypoint_defend");
precacheShader("waypoint_defend_a");
precacheShader("waypoint_defend_b");
precacheShader("waypoint_defuse");
precacheShader("waypoint_defuse_a");
precacheShader("waypoint_defuse_b");
precacheString( &"MP_EXPLOSIVES_RECOVERED_BY" );
precacheString( &"MP_EXPLOSIVES_DROPPED_BY" );
precacheString( &"MP_EXPLOSIVES_PLANTED_BY" );
precacheString( &"MP_EXPLOSIVES_DEFUSED_BY" );
precacheString( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
precacheString( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
precacheString( &"MP_CANT_PLANT_WITHOUT_BOMB" );
precacheString( &"MP_PLANTING_EXPLOSIVE" );
precacheString( &"MP_DEFUSING_EXPLOSIVE" );
precacheString( &"MP_BOMB_A_TIMER" );
precacheString( &"MP_BOMB_B_TIMER" );
precacheString( &"MP_BOMBSITE_IN_USE" );
}
onStartGameType()
{
if ( !isDefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
level.useStartSpawns = true;
setClientNameMode( "manual_change" );
game["strings"]["target_destroyed"] = &"MP_TARGET_DESTROYED";
game["strings"]["bomb_defused"] = &"MP_BOMB_DEFUSED";
precacheString( game["strings"]["target_destroyed"] );
precacheString( game["strings"]["bomb_defused"] );
level._effect["bombexplosion"] = loadfx("explosions/tanker_explosion");
setObjectiveText( game["attackers"], &"OBJECTIVES_DD_ATTACKER" );
setObjectiveText( game["defenders"], &"OBJECTIVES_DD_DEFENDER" );
if ( level.splitscreen )
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_DD_ATTACKER" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_DD_DEFENDER" );
}
else
{
setObjectiveScoreText( game["attackers"], &"OBJECTIVES_DD_ATTACKER_SCORE" );
setObjectiveScoreText( game["defenders"], &"OBJECTIVES_DD_DEFENDER_SCORE" );
}
setObjectiveHintText( game["attackers"], &"OBJECTIVES_DD_ATTACKER_HINT" );
setObjectiveHintText( game["defenders"], &"OBJECTIVES_DD_DEFENDER_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
if ( getDvar( "mapname" ) == "mp_shipment_long" )
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["defenders"], "mp_cha_spawn_axis" );
else
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["defenders"], "mp_dd_spawn_defender" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["defenders"], "mp_dd_spawn_defender_a", true );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["defenders"], "mp_dd_spawn_defender_b", true );
if ( getDvar( "mapname" ) == "mp_shipment_long" )
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_cha_spawn_axis_start" );
else
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_dd_spawn_defender_start" );
if ( getDvar( "mapname" ) == "mp_shipment_long" )
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["attackers"], "mp_cha_spawn_allies" );
else
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["attackers"], "mp_dd_spawn_attacker" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["attackers"], "mp_dd_spawn_attacker_a", true );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( game["attackers"], "mp_dd_spawn_attacker_b", true );
if ( getDvar( "mapname" ) == "mp_shipment_long" )
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_cha_spawn_allies_start" );
else
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_dd_spawn_attacker_start" );
if ( getDvar( "mapname" ) == "mp_shipment_long" )
level.spawn_defenders = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_cha_spawn_axis" );
else
level.spawn_defenders = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_defender" );
level.spawn_defenders_a = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_defender_a" );
level.spawn_defenders_a = array_combine( level.spawn_defenders, level.spawn_defenders_a );
level.spawn_defenders_b = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_defender_b" );
level.spawn_defenders_b = array_combine( level.spawn_defenders, level.spawn_defenders_b );
if ( getDvar( "mapname" ) == "mp_shipment_long" )
level.spawn_attackers = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_cha_spawn_allies" );
else
level.spawn_attackers = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_attacker" );
level.spawn_attackers_a = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_attacker_a" );
level.spawn_attackers_a = array_combine( level.spawn_attackers, level.spawn_attackers_a );
level.spawn_attackers_b = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_attacker_b" );
level.spawn_attackers_b = array_combine( level.spawn_attackers, level.spawn_attackers_b );
if ( getDvar( "mapname" ) == "mp_shipment_long" )
{
level.spawn_defenders_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_cha_spawn_axis_start" );
level.spawn_attackers_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_cha_spawn_allies_start" );
}
else
{
level.spawn_defenders_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_defender_start" );
level.spawn_attackers_start = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_attacker_start" );
}
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
level.aPlanted = false;
level.bPlanted = false;
setMapCenter( level.mapCenter );
maps\mp\gametypes\_rank::registerScoreInfo( "win", 2 );
maps\mp\gametypes\_rank::registerScoreInfo( "loss", 1 );
maps\mp\gametypes\_rank::registerScoreInfo( "tie", 1.5 );
maps\mp\gametypes\_rank::registerScoreInfo( "kill", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "headshot", 50 );
maps\mp\gametypes\_rank::registerScoreInfo( "assist", 20 );
maps\mp\gametypes\_rank::registerScoreInfo( "plant", 100 );
maps\mp\gametypes\_rank::registerScoreInfo( "defuse", 100 );
thread updateGametypeDvars();
thread waitToProcess();
winlimit = getWatchedDvar("winlimit");
allowed[0] = "dd";
bombZones = getEntArray( "dd_bombzone", "targetname" );
if ( bombZones.size )
allowed[1] = "dd_bombzone";
else
allowed[1] = "bombzone";
allowed[2] = "blocker";
maps\mp\gametypes\_gameobjects::main(allowed);
thread bombs();
}
waitToProcess()
{
level endon( "game_end" );
for ( ;; )
{
if ( level.inGracePeriod == 0 )
break;
wait ( 0.05 );
}
level.useStartSpawns = false;
}
getSpawnPoint()
{
spawnteam = self.pers["team"];
if ( level.useStartSpawns )
{
if ( spawnteam == game["attackers"] )
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_attackers_start);
else
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random(level.spawn_defenders_start);
}
else
{
if (spawnteam == game["attackers"] )
{
if ( (!level.aPlanted && !level.bPlanted) )
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
else if ( level.aPlanted && !level.bPlanted )
spawnPoints = level.spawn_attackers_a;
else if ( level.bPlanted && !level.aPlanted )
spawnPoints = level.spawn_attackers_b;
else
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
else
{
if ( (!level.aPlanted && !level.bPlanted) )
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
else if ( level.aPlanted && !level.bPlanted )
spawnPoints = level.spawn_defenders_a;
else if ( level.bPlanted && !level.aPlanted )
spawnPoints = level.spawn_defenders_b;
else
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
}
assert( isDefined(spawnpoint) );
return spawnpoint;
}
onSpawnPlayer()
{
if ( self.pers["team"] == game["attackers"] )
{
self.isPlanting = false;
self.isDefusing = false;
self.isBombCarrier = true;
if ( level.splitscreen )
{
self.carryIcon = createIcon( "hud_suitcase_bomb", 33, 33 );
self.carryIcon setPoint( "BOTTOM RIGHT", "BOTTOM RIGHT", 0, -78 );
self.carryIcon.alpha = 0.75;
}
else
{
self.carryIcon = createIcon( "hud_suitcase_bomb", 50, 50 );
self.carryIcon setPoint( "BOTTOM RIGHT", "BOTTOM RIGHT", -90, -65 );
self.carryIcon.alpha = 0.75;
}
}
else
{
self.isPlanting = false;
self.isDefusing = false;
self.isBombCarrier = false;
if ( isDefined( self.carryIcon ) )
{
self.carryIcon Destroy();
}
}
level notify ( "spawned_player" );
}
dd_endGame( winningTeam, endReasonText )
{
thread maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
}
onDeadEvent( team )
{
if ( level.bombExploded || level.bombDefused )
return;
if ( team == "all" )
{
if ( level.bombPlanted )
dd_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
else
dd_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
}
else if ( team == game["attackers"] )
{
if ( level.bombPlanted )
return;
level thread dd_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
}
else if ( team == game["defenders"] )
{
level thread dd_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
}
}
onNormalDeath( victim, attacker, lifeId )
{
score = maps\mp\gametypes\_rank::getScoreInfoValue( "kill" );
assert( isDefined( score ) );
team = victim.team;
if ( game["state"] == "postgame" && (victim.team == game["defenders"] || !level.bombPlanted) )
attacker.finalKill = true;
if ( victim.isPlanting )
{
thread maps\mp\_matchdata::logKillEvent( lifeId, "planting" );
}
else if ( victim.isDefusing )
{
thread maps\mp\_matchdata::logKillEvent( lifeId, "defusing" );
}
}
onTimeLimit()
{
dd_endGame( game["defenders"], game["strings"]["time_limit_reached"] );
}
updateGametypeDvars()
{
level.plantTime = dvarFloatValue( "planttime", 5, 0, 20 );
level.defuseTime = dvarFloatValue( "defusetime", 5, 0, 20 );
level.bombTimer = dvarIntValue( "bombtimer", 45, 1, 300 );
level.ddTimeToAdd = dvarFloatValue( "addtime", 2, 0, 5 );; //how much time is added to the match when a target is destroyed
}
bombs()
{
level.bombPlanted = false;
level.bombDefused = false;
level.bombExploded = 0;
level.bombZones = [];
bombZones = getEntArray( "dd_bombzone", "targetname" );
if ( !bombZones.size )
bombZones = getEntArray( "bombzone", "targetname" );
for ( index = 0; index < bombZones.size; index++ )
{
trigger = bombZones[index];
visuals = getEntArray( bombZones[index].target, "targetname" );
bombZone = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,64) );
bombZone maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
bombZone maps\mp\gametypes\_gameobjects::setUseTime( level.plantTime );
bombZone maps\mp\gametypes\_gameobjects::setUseText( &"MP_PLANTING_EXPLOSIVE" );
bombZone maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
bombZone maps\mp\gametypes\_gameobjects::setKeyObject( level.ddBomb );
label = bombZone maps\mp\gametypes\_gameobjects::getLabel();
bombZone.label = label;
bombZone.index = index;
bombZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defend" + label );
bombZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" + label );
bombZone maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_target" + label );
bombZone maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_target" + label );
bombZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
bombZone.onBeginUse = ::onBeginUse;
bombZone.onEndUse = ::onEndUse;
bombZone.onUse = ::onUseObject;
bombZone.onCantUse = ::onCantUse;
bombZone.useWeapon = "briefcase_bomb_mp";
bombZone.visuals[0].killCamEnt = spawn( "script_model", bombZone.visuals[0].origin + (0,0,128) );
for ( i = 0; i < visuals.size; i++ )
{
if ( isDefined( visuals[i].script_exploder ) )
{
bombZone.exploderIndex = visuals[i].script_exploder;
break;
}
}
level.bombZones[level.bombZones.size] = bombZone;
bombZone.bombDefuseTrig = getent( visuals[0].target, "targetname" );
assert( isdefined( bombZone.bombDefuseTrig ) );
bombZone.bombDefuseTrig.origin += (0,0,-10000);
bombZone.bombDefuseTrig.label = label;
}
for ( index = 0; index < level.bombZones.size; index++ )
{
array = [];
for ( otherindex = 0; otherindex < level.bombZones.size; otherindex++ )
{
if ( otherindex != index )
array[ array.size ] = level.bombZones[otherindex];
}
level.bombZones[index].otherBombZones = array;
}
}
onUseObject( player )
{
team = player.pers["team"];
otherTeam = level.otherTeam[team];
if ( !self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
{
player notify ( "bomb_planted" );
player playSound( "mp_bomb_plant" );
thread teamPlayerCardSplash( "callout_bombplanted", player );
//iPrintLn( &"MP_EXPLOSIVES_PLANTED_BY", player );
leaderDialog( "bomb_planted" );
player thread maps\mp\gametypes\_hud_message::SplashNotify( "plant", maps\mp\gametypes\_rank::getScoreInfoValue( "plant" ) );
player thread maps\mp\gametypes\_rank::giveRankXP( "plant" );
maps\mp\gametypes\_gamescore::givePlayerScore( "plant", player );
player incPlayerStat( "bombsplanted", 1 );
player thread maps\mp\_matchdata::logGameEvent( "plant", player.origin );
player.bombPlantedTime = getTime();
level thread bombPlanted( self, player );
level.bombOwner = player;
self.useWeapon = "briefcase_bomb_defuse_mp";
self setUpForDefusing();
}
else // defused the bomb
{
self thread bombHandler( player, "defused" );
}
}
resetBombZone()
{
self maps\mp\gametypes\_gameobjects::allowUse( "enemy" );
self maps\mp\gametypes\_gameobjects::setUseTime( level.plantTime );
self maps\mp\gametypes\_gameobjects::setUseText( &"MP_PLANTING_EXPLOSIVE" );
self maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_PLANT_EXPLOSIVES" );
self maps\mp\gametypes\_gameobjects::setKeyObject( level.ddBomb );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defend" + self.label );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend" + self.label );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_target" + self.label );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_target" + self.label );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
self.useWeapon = "briefcase_bomb_mp";
}
setUpForDefusing()
{
self maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
self maps\mp\gametypes\_gameobjects::setUseTime( level.defuseTime );
self maps\mp\gametypes\_gameobjects::setUseText( &"MP_DEFUSING_EXPLOSIVE" );
self maps\mp\gametypes\_gameobjects::setUseHintText( &"PLATFORM_HOLD_TO_DEFUSE_EXPLOSIVES" );
self maps\mp\gametypes\_gameobjects::setKeyObject( undefined );
self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "waypoint_defuse" + self.label );
self maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defuse" + self.label );
self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", "waypoint_defend" + self.label );
self maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", "waypoint_defend" + self.label );
self maps\mp\gametypes\_gameobjects::setVisibleTeam( "any" );
}
onBeginUse( player )
{
if ( self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
{
player playSound( "mp_bomb_defuse" );
player.isDefusing = true;
bestDistance = 9000000;
closestBomb = undefined;
if ( isDefined( level.ddBombModel ) )
{
foreach ( bomb in level.ddBombModel )
{
if ( !isDefined( bomb ) )
continue;
dist = distanceSquared( player.origin, bomb.origin );
if ( dist < bestDistance )
{
bestDistance = dist;
closestBomb = bomb;
}
}
assert( isDefined(closestBomb) );
player.defusing = closestBomb;
closestBomb hide();
}
}
else
{
player.isPlanting = true;
}
}
onEndUse( team, player, result )
{
if ( !isDefined( player ) )
return;
if ( isAlive( player ) )
{
player.isDefusing = false;
player.isPlanting = false;
}
if ( self maps\mp\gametypes\_gameobjects::isFriendlyTeam( player.pers["team"] ) )
{
if ( isDefined( player.defusing ) && !result )
{
player.defusing show();
}
}
}
onCantUse( player )
{
player iPrintLnBold( &"MP_BOMBSITE_IN_USE" );
}
onReset()
{
}
bombPlanted( destroyedObj, player )
{
destroyedObj endon( "defused" );
level.bombsPlanted += 1;
self setBombTimerDvar();
maps\mp\gametypes\_gamelogic::pauseTimer();
level.timePauseStart = getTime();
level.timeLimitOverride = true;
level.bombPlanted = true;
level.destroyedObject = destroyedObj;
if ( level.destroyedObject.label == "_a" )
level.aPlanted = true;
else
level.bPlanted = true;
level.destroyedObject.bombPlanted = true;
destroyedObj.visuals[0] thread playDemolitionTickingSound(destroyedObj);
level.tickingObject = destroyedObj.visuals[0];
self dropBombModel( player, destroyedObj.label );
destroyedObj.bombDefused = false;
destroyedObj maps\mp\gametypes\_gameobjects::allowUse( "none" );
destroyedObj maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
destroyedObj setUpForDefusing();
destroyedObj BombTimerWait(destroyedObj); //waits for bomb to explode!
destroyedObj thread bombHandler( player ,"explode" );
}
bombHandler( player, destType )
{
self.visuals[0] notify( "stopTicking" );
level.bombsPlanted -= 1;
if ( self.label == "_a" )
level.aPlanted = false;
else
level.bPlanted = false;
self.bombPlanted = 0;
self restartTimer();
self setBombTimerDvar();
setDvar( "ui_bombtimer" + self.label, -1 );
//self maps\mp\gametypes\_gameobjects::updateTimer( 0, false );
if ( level.gameEnded )
return;
if ( destType == "explode" )
{
level.bombExploded += 1;
explosionOrigin = self.curorigin;
level.ddBombModel[ self.label ] Delete();
if ( isdefined( player ) )
{
self.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20, player );
player incPlayerStat( "targetsdestroyed", 1 );
}
else
{
self.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20 );
}
rot = randomfloat(360);
explosionEffect = spawnFx( level._effect["bombexplosion"], explosionOrigin + (0,0,50), (0,0,1), (cos(rot),sin(rot),0) );
triggerFx( explosionEffect );
PlayRumbleOnPosition( "grenade_rumble", explosionOrigin );
earthquake( 0.75, 2.0, explosionOrigin, 2000 );
thread playSoundinSpace( "exp_suitcase_bomb_main", explosionOrigin );
sabBomb = getEnt( "sab_bomb", "targetname" );
sabBomb Delete();
if ( isDefined( self.exploderIndex ) )
exploder( self.exploderIndex );
self maps\mp\gametypes\_gameobjects::disableObject();
if ( level.bombExploded < 2 )
{
foreach ( splashPlayer in level.players )
splashPlayer thread maps\mp\gametypes\_hud_message::SplashNotify( "time_added" );
}
wait 2;
if ( level.bombExploded > 1 )
dd_endGame( game["attackers"], game["strings"]["target_destroyed"] );
else
level thread teamPlayerCardSplash( "callout_time_added", player );
}
else //defused
{
player notify ( "bomb_defused" );
self notify( "defused" );
// if ( !level.hardcoreMode )
// iPrintLn( &"MP_EXPLOSIVES_DEFUSED_BY", player );
leaderDialog( "bomb_defused" );
level thread teamPlayerCardSplash( "callout_bombdefused", player );
level thread bombDefused( self );
self resetBombzone();
if ( isDefined( level.bombOwner ) && ( level.bombOwner.bombPlantedTime + 4000 + (level.defuseTime*1000) ) > getTime() && isReallyAlive( level.bombOwner ) )
player thread maps\mp\gametypes\_hud_message::SplashNotify( "ninja_defuse", ( maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) ) );
else
player thread maps\mp\gametypes\_hud_message::SplashNotify( "defuse", maps\mp\gametypes\_rank::getScoreInfoValue( "defuse" ) );
player thread maps\mp\gametypes\_rank::giveRankXP( "defuse" );
maps\mp\gametypes\_gamescore::givePlayerScore( "defuse", player );
player incPlayerStat( "bombsdefused", 1 );
player thread maps\mp\_matchdata::logGameEvent( "defuse", player.origIn );
}
}
playDemolitionTickingSound( site )
{
self endon("death");
self endon("stopTicking");
level endon("game_ended");
while(1)
{
self playSound( "ui_mp_suitcasebomb_timer" );
if ( !isDefined( site.waitTime ) || site.waitTime > 10 )
wait 1.0;
else if ( isDefined( site.waitTime ) && site.waitTime > 5 )
wait 0.5;
else
wait 0.25;
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
}
}
setBombTimerDvar()
{
println( "BOMBS PLANTED: " + level.bombsPlanted );
if ( level.bombsPlanted == 1 )
setDvar( "ui_bomb_timer", 2 );
else if ( level.bombsPlanted == 2 )
setDvar( "ui_bomb_timer", 3 );
else
setDvar( "ui_bomb_timer", 0 );
}
dropBombModel( player, site )
{
trace = bulletTrace( player.origin + (0,0,20), player.origin - (0,0,2000), false, player );
tempAngle = randomfloat( 360 );
forward = (cos( tempAngle ), sin( tempAngle ), 0);
forward = vectornormalize( forward - common_scripts\utility::vector_multiply( trace["normal"], vectordot( forward, trace["normal"] ) ) );
dropAngles = vectortoangles( forward );
level.ddBombModel[ site ] = spawn( "script_model", trace["position"] );
level.ddBombModel[ site ].angles = dropAngles;
level.ddBombModel[ site ] setModel( "prop_suitcase_bomb" );
}
restartTimer()
{
if ( level.bombsPlanted <= 0 )
{
maps\mp\gametypes\_gamelogic::resumeTimer();
level.timePaused = ( getTime() - level.timePauseStart ) ;
level.timeLimitOverride = false;
}
}
BombTimerWait(siteLoc)
{
level endon("game_ended");
level endon("bomb_defused" + siteLoc.label );
siteLoc.waitTime = level.bombTimer;
while ( siteLoc.waitTime >= 0 )
{
siteLoc.waitTime--;
setDvar( "ui_bombtimer" + siteLoc.label, siteLoc.waitTime );
//self maps\mp\gametypes\_gameobjects::updateTimer( waitTime, true );
if ( siteLoc.waitTime >= 0 )
wait( 1 );
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
}
}
bombDefused( siteDefused )
{
level.tickingObject maps\mp\gametypes\_gamelogic::stopTickingSound();
siteDefused.bombDefused = true;
self setBombTimerDvar();
setDvar( "ui_bombtimer" + siteDefused.label, -1 );
level notify("bomb_defused" + siteDefused.label);
}
initGametypeAwards()
{
maps\mp\_awards::initStatAward( "targetsdestroyed", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombsplanted", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombsdefused", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombcarrierkills", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "bombscarried", 0, maps\mp\_awards::highestWins );
maps\mp\_awards::initStatAward( "killsasbombcarrier", 0, maps\mp\_awards::highestWins );
}

View File

@ -0,0 +1,454 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
/*
VIP
Objective: Escort the VIP to safety, or eliminate the VIP beofore he reaches extraction
Map ends: When one team eliminates the enemy team, or the flag is reached
Respawning: Beginning of next round
Level requirementss
------------------
Spawnpoints:
classname mp_tdm_spawn
Spectator Spawnpoints:
classname mp_global_intermission
*/
main()
{
if(getdvar("mapname") == "mp_background")
return;
maps\mp\gametypes\_globallogic::init();
maps\mp\gametypes\_callbacksetup::SetupCallbacks();
maps\mp\gametypes\_globallogic::SetupCallbacks();
registerRoundSwitchDvar( level.gameType, 0, 0, 9 );
registerTimeLimitDvar( level.gameType, 10, 0, 1440 );
registerScoreLimitDvar( level.gameType, 500, 0, 5000 );
registerRoundLimitDvar( level.gameType, 1, 0, 10 );
registerWinLimitDvar( level.gameType, 1, 0, 10 );
registerRoundSwitchDvar( level.gameType, 3, 0, 30 );
registerNumLivesDvar( level.gameType, 1, 0, 10 );
registerWatchDvarInt( "halftime", 0 );
level.teamBased = true;
level.objectiveBased = true;
level.onPrecacheGameType = ::onPrecacheGameType;
level.onStartGameType = ::onStartGameType;
level.getSpawnPoint = ::getSpawnPoint;
level.onSpawnPlayer = ::onSpawnPlayer;
level.onNormalDeath = ::onNormalDeath;
level.onPlayerKilled = ::onPlayerKilled;
level.onDeadEvent = ::onDeadEvent;
game["dialog"]["gametype"] = "VIP";
}
onPrecacheGameType()
{
precacheShader( "compass_waypoint_captureneutral" );
precacheShader( "compass_waypoint_capture" );
precacheShader( "compass_waypoint_defend" );
precacheShader( "waypoint_captureneutral" );
precacheShader( "waypoint_capture" );
precacheShader( "waypoint_defend" );
precacheString( &"MP_ELIMINATED_VIP" );
precacheString( &"MP_DEFENDED_VIP" );
precacheString( &"SPLASHES_VIP" );
game["flagmodels"] = [];
game["flagmodels"]["neutral"] = "prop_flag_neutral";
game["flagmodels"]["allies"] = maps\mp\gametypes\_teams::getTeamFlagModel( "allies" );
game["flagmodels"]["axis"] = maps\mp\gametypes\_teams::getTeamFlagModel( "axis" );
precacheModel( game["flagmodels"]["neutral"] );
precacheModel( game["flagmodels"]["allies"] );
precacheModel( game["flagmodels"]["axis"] );
}
onStartGameType()
{
setClientNameMode("auto_change");
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
if ( game["switchedsides"] )
{
oldAttackers = game["attackers"];
oldDefenders = game["defenders"];
game["attackers"] = oldDefenders;
game["defenders"] = oldAttackers;
}
setObjectiveText( "allies", &"OBJECTIVES_VIP" );
setObjectiveText( "axis", &"OBJECTIVES_VIP" );
if ( level.splitscreen )
{
setObjectiveScoreText( "allies", &"OBJECTIVES_VIP" );
setObjectiveScoreText( "axis", &"OBJECTIVES_VIP" );
}
else
{
setObjectiveScoreText( "allies", &"OBJECTIVES_VIP_SCORE" );
setObjectiveScoreText( "axis", &"OBJECTIVES_VIP_SCORE" );
}
setObjectiveHintText( "allies", &"OBJECTIVES_VIP_HINT" );
setObjectiveHintText( "axis", &"OBJECTIVES_VIP_HINT" );
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_allies_start" );
maps\mp\gametypes\_spawnlogic::placeSpawnPoints( "mp_tdm_spawn_axis_start" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "allies", "mp_tdm_spawn" );
maps\mp\gametypes\_spawnlogic::addSpawnPoints( "axis", "mp_tdm_spawn" );
level.mapCenter = maps\mp\gametypes\_spawnlogic::findBoxCenter( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
allowed[0] = "vip";
allowed[1] = "sd";
allowed[2] = "airdrop_pallet";
allowed[3] = "gtnw";
allowed[4] = "gtnw_zone";
//maps\mp\gametypes\_rank::registerScoreInfo( "capture", 200 );
maps\mp\gametypes\_gameobjects::main(allowed);
self thread waitToProcess();
}
waitToProcess()
{
level endon( "game_end" );
level endon( "waitSkipped" );
self thread extractionZone();
self thread skipWait();
gameFlagWait( "prematch_done" );
gameFlagWait( "graceperiod_done" );
self notify( "graceComplete" );
self thread vipSelection();
}
skipWait()
{
self endon( "graceComplete" );
for(;;)
{
if( level.players.size > 2 )
break;
wait( .5 );
}
self notify( "waitSkipped" );
self thread vipSelection();
}
getSpawnPoint()
{
spawnteam = self.pers["team"];
if ( game["switchedsides"] )
spawnteam = getOtherTeam( spawnteam );
if ( level.inGracePeriod )
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_tdm_spawn_" + spawnteam + "_start" );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints );
}
else
{
spawnPoints = maps\mp\gametypes\_spawnlogic::getTeamSpawnPoints( spawnteam );
spawnPoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_NearTeam( spawnPoints );
}
return spawnPoint;
}
onSpawnPlayer()
{
self.isVip = false;
self.usingObj = undefined;
level notify ( "spawned_player" );
}
onNormalDeath( victim, attacker, lifeId )
{
score = maps\mp\gametypes\_rank::getScoreInfoValue( "kill" );
assert( isDefined( score ) );
attacker maps\mp\gametypes\_gamescore::giveTeamScoreForObjective( attacker.pers["team"], score );
team = victim.team;
if ( isDefined( victim.isVip ) && victim.isVip )
{
level thread vip_endGame( game["attackers"], &"MP_ELIMINATED_VIP" );
attacker.finalKill = true;
}
}
onPlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration, killId)
{
thread checkAllowSpectating();
}
onTimeLimit()
{
if ( game["status"] == "overtime" )
{
winner = "forfeit";
}
else if ( game["teamScores"]["allies"] == game["teamScores"]["axis"] )
{
winner = "overtime";
}
else if ( game["teamScores"]["axis"] > game["teamScores"]["allies"] )
{
winner = "axis";
}
else
{
winner = "allies";
}
thread maps\mp\gametypes\_gamelogic::endGame( winner, game["strings"]["time_limit_reached"] );
}
checkAllowSpectating()
{
wait ( 0.05 );
update = false;
if ( !level.aliveCount[ game["attackers"] ] )
{
level.spectateOverride[game["attackers"]].allowEnemySpectate = 1;
update = true;
}
if ( !level.aliveCount[ game["defenders"] ] )
{
level.spectateOverride[game["defenders"]].allowEnemySpectate = 1;
update = true;
}
if ( update )
maps\mp\gametypes\_spectating::updateSpectateSettings();
}
onDeadEvent( team )
{
if ( team == game["attackers"] )
{
level thread vip_endGame( game["defenders"], game["strings"][game["attackers"]+"_eliminated"] );
}
else if ( team == game["defenders"] )
{
level thread vip_endGame( game["attackers"], game["strings"][game["defenders"]+"_eliminated"] );
}
}
vip_endGame( winningTeam, endReasonText )
{
thread maps\mp\gametypes\_gamelogic::endGame( winningTeam, endReasonText );
}
vipSelection()
{
println( "SELECTION" );
potentialVIPs = [];
abortTime = 0;
for( ;; )
{
if ( level.players.size >= 2 )
break;
if ( abortTime >= 100 )
{
iPrintlnBold( "Game mode only playable with 2 or more players" );
wait( 2 );
maps\mp\gametypes\_callbacksetup::AbortLevel();
}
abortTime++;
wait( .1 );
}
foreach ( player in level.players )
{
if ( player.team == game["defenders"] )
potentialVIPs[ potentialVIPs.size ] = player;
}
selectedVIPNum = RandomIntRange( 0, potentialVIPs.size );
selectedPlayer = potentialVIPs[ selectedVIPNum ];
if ( !isAlive(selectedPlayer ) && !isSubStr( selectedPlayer.guid, "bot" ) )
selectedPlayer forceVIPSpawn();
setupVip( selectedPlayer );
}
setupVip ( vipPlayer )
{
vipPlayer TakeAllWeapons();
vipPlayer _clearPerks();
vipPlayer.isVip = true;
vipPlayer giveWeapon( "deserteagle_fmj_mp" );
vipPlayer giveStartAmmo( "deserteagle_fmj_mp" );
vipPlayer giveWeapon( "riotshield_mp" );
vipPlayer switchToWeapon( "riotshield_mp" );
vipPlayer _setPerk( "specialty_armorvest" );
vipPlayer _setPerk( "specialty_finalstand" );
vipPlayer iPrintlnBold( "You Are the VIP" );
//TO DO: add defend icon on the VIP
}
extractionZone()
{
extractionZones = getEntArray("extraction_vip", "targetname");
// check to see if zone is available.
if ( !extractionZones.size )
{
println("WARNING: no extraction zone specified" );
printLn( "^1Not enough extraction zones found in level!" );
extractionZones = getEntArray( "gtnw_zone", "targetname" );
if (!extractionZones.size)
{
maps\mp\gametypes\_callbacksetup::AbortLevel();
return;
}
}
trigger = extractionZones[0];
if ( isDefined( trigger.target ) )
{
visuals[0] = getEnt( trigger.target, "targetname" );
}
else
{
visuals[0] = spawn( "script_model", trigger.origin );
visuals[0].angles = trigger.angles;
}
extractionZone = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,100) );
extractionZone maps\mp\gametypes\_gameobjects::allowUse( "friendly" );
extractionZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" );
extractionZone maps\mp\gametypes\_gameobjects::setUseText( &"MP_CALLING_EXTRACTION" );
extractionZone maps\mp\gametypes\_gameobjects::setUseTime( 0 );
extractionZone.onUse = ::onUse;
extractionZone.onCantUse = ::onCantUse;
traceStart = trigger.origin + (0,0,32);
traceEnd = trigger.origin + (0,0,-32);
trace = bulletTrace( traceStart, traceEnd, false, undefined );
fx = maps\mp\gametypes\_teams::getTeamFlagFX( game["defenders"] );
fxid = loadfx( fx );
upangles = vectorToAngles( trace["normal"] );
forward = anglesToForward( upangles );
right = anglesToRight( upangles );
thread spawnFxDelay( fxid, trace["position"], forward, right, 0.5 );
extractionZone maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", "compass_waypoint_defend");
extractionZone maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", "waypoint_defend");
extractionZone maps\mp\gametypes\_gameobjects::setVisibleTeam( "friendly" );
level.extractionZone = extractionZone;
}
setVIPUse()
{
foreach (player in level.players)
{
if ( ! player.isVip )
self.trigger disablePlayerUse(player);
}
}
onUse( player )
{
if ( !isDefined( player.isVip ) || ! player.isVip )
{
return;
}
iPrintlnBold( "Extraction on its way" );
self handleTimer( player );
}
handleTimer( player )
{
player endon( "death" );
level endon( "game_end" );
level.extractionTime = 45;
maps\mp\gametypes\_gamelogic::pauseTimer();
level.timeLimitOverride = true;
setGameEndTime( int( getTime() + (level.extractionTime * 1000) ) );
wait level.extractionTime;
//call the sentry airdrops
level thread vip_endGame( game["defenders"], &"MP_DEFENDED_VIP" );
}
onEndUse( team, player, success )
{
println( "End Use" );
}
onCantUse( player )
{
// player iPrintLnBold( &"MP_CANT_PLANT_WITHOUT_BOMB" );
}
spawnFxDelay( fxid, pos, forward, right, delay )
{
wait delay;
effect = spawnFx( fxid, pos, forward, right );
triggerFx( effect );
}
forceVIPSpawn()
{
self endon ( "death" );
self endon ( "disconnect" );
self endon ( "spawned" );
if ( self.hasSpawned )
return;
if ( !isValidClass( self.pers["class"] ) )
{
self.pers["class"] = "CLASS_CUSTOM1";
self.class = self.pers["class"];
}
self closeMenus();
self thread maps\mp\gametypes\_playerlogic::spawnClient();
}

View File

@ -10,6 +10,9 @@
- scr_ac130_flares <int>
2 - (default) how many flares a ac130 has
- scr_ac130_fast <bool>
0 - (default) if to allow users to use ac130 faster
Thanks: H3X1C, Emosewaj
*/
@ -22,8 +25,10 @@ init()
setDvarIfUninitialized( "scr_ac130_duration", 40 );
setDvarIfUninitialized( "scr_ac130_flares", 2 );
setDvarIfUninitialized( "scr_ac130_fast", false );
level.ac130_use_duration = getDvarInt( "scr_ac130_duration" );
level.ac130_num_flares= getDvarInt( "scr_ac130_flares" );
level.ac130_fast= getDvarInt( "scr_ac130_fast" );
makeDvarServerInfo( "ui_ac130usetime", level.ac130_use_duration );
@ -661,6 +666,9 @@ removeAC130Player( player, disconnected )
return;
}
if (level.ac130_fast)
level.ac130InUse = false;
ac130model = spawn( "script_model", level.ac130.planeModel getTagOrigin( "tag_origin" ) );
ac130model.angles = level.ac130.planeModel.angles;
ac130model setModel( "vehicle_ac130_coop" );
@ -676,7 +684,8 @@ removeAC130Player( player, disconnected )
wait ( 5.0 );
ac130model thread deployFlares( true );
level.ac130InUse = false;
if (!level.ac130_fast)
level.ac130InUse = false;
wait ( 30.0 );

View File

@ -1295,8 +1295,12 @@ killstreakCrateThink( dropType )
player playLocalSound( "ammo_crate_use" );
curRollover = undefined;
if (isDefined(player.maxKillstreakVal) && player.maxKillstreakVal > 0 && isDefined(level.rolloverKillstreaksOnlyIncrease) && level.rolloverKillstreaksOnlyIncrease)
curRollover = int(player.pers["cur_kill_streak"]/player.maxKillstreakVal);
doesIncreaseKS = level.airdropKillstreaksIncreaseStreak;
player thread maps\mp\killstreaks\_killstreaks::giveKillstreak( self.crateType, doesIncreaseKS, doesIncreaseKS, self.owner );
player thread maps\mp\killstreaks\_killstreaks::giveKillstreak( self.crateType, doesIncreaseKS, doesIncreaseKS, self.owner, curRollover );
player maps\mp\gametypes\_hud_message::killstreakSplashNotify( self.crateType, undefined, "pickup" );
@ -1378,8 +1382,12 @@ deleteCrate()
sentryUseTracker(owner)
{
curRollover = undefined;
if (isDefined(self.maxKillstreakVal) && self.maxKillstreakVal > 0 && isDefined(level.rolloverKillstreaksOnlyIncrease) && level.rolloverKillstreaksOnlyIncrease)
curRollover = int(self.pers["cur_kill_streak"]/self.maxKillstreakVal);
// if ( !self maps\mp\killstreaks\_autosentry::giveSentry( "sentry_minigun" ) )
self maps\mp\killstreaks\_killstreaks::giveKillstreak( "sentry", true, true, owner );
self maps\mp\killstreaks\_killstreaks::giveKillstreak( "sentry", true, true, owner, curRollover );
}

View File

@ -6,6 +6,15 @@
DVAR:
- scr_harrier_duration <int>
45 - (default) amount of seconds a harrier sticks around for
- scr_harrier_fast <bool>
0 - (default) allow players to call in harrier sooner (as it leaves, instead of being deleted)
- scr_airstrike_mutate_fix <bool>
0 - (default) fixes a bug where calling in airstrikes too fast will cause them to mutate types
- scr_airstrike_teamChangeFix <bool>
false - (default) if should prevent players from doing damage when changing teams and airstriking
*/
#include maps\mp\_utility;
@ -37,7 +46,13 @@ init()
PrecacheMiniMapIcon( "hud_minimap_harrier_red" );
setDvarIfUninitialized( "scr_harrier_duration", 45 );
setDvarIfUninitialized( "scr_harrier_fast", false );
setDvarIfUninitialized( "scr_airstrike_mutate_fix", false );
setDvarIfUninitialized( "scr_airstrike_teamChangeFix", false );
level.harrierDuration = getDvarInt( "scr_harrier_duration" );
level.harrier_fast = getDvarInt( "scr_harrier_fast" );
level.airstrike_mutate_fix = getDvarInt( "scr_airstrike_mutate_fix" );
level.airstrike_teamChangeFix = getDvarInt( "scr_airstrike_teamChangeFix" );
level.onfirefx = loadfx ("fire/fire_smoke_trail_L");
@ -154,15 +169,18 @@ tryUseAirstrike( lifeId, airStrikeType )
}
doAirstrike( lifeId, origin, yaw, owner, team )
doAirstrike( lifeId, origin, yaw, owner, team, airStrikeType )
{
assert( isDefined( origin ) );
assert( isDefined( yaw ) );
if ( isDefined( self.airStrikeType ) )
airstrikeType = self.airStrikeType;
else
airstrikeType = "default";
if (!level.airstrike_mutate_fix || !isDefined(airStrikeType))
{
if ( isDefined( self.airStrikeType ) )
airstrikeType = self.airStrikeType;
else
airstrikeType = "default";
}
if ( airStrikeType == "harrier" )
level.planes++;
@ -200,7 +218,7 @@ doAirstrike( lifeId, origin, yaw, owner, team )
playerteam = player.pers["team"];
if ( isdefined( playerteam ) )
{
if ( playerteam == team && self.airStrikeType != "stealth" )
if ( playerteam == team && airStrikeType != "stealth" )
player iprintln( &"MP_WAR_AIRSTRIKE_INBOUND", owner );
}
}
@ -222,7 +240,7 @@ doAirstrike( lifeId, origin, yaw, owner, team )
level.artilleryDangerCenters[ level.artilleryDangerCenters.size ] = dangerCenter;
/# level thread debugArtilleryDangerCenters( airstrikeType ); #/
harrierEnt = callStrike( lifeId, owner, targetpos, yaw );
harrierEnt = self callStrike( lifeId, owner, targetpos, yaw, airstrikeType, team );
wait( 1.0 );
level.airstrikeInProgress = undefined;
@ -250,13 +268,25 @@ doAirstrike( lifeId, origin, yaw, owner, team )
if ( airStrikeType != "harrier" )
return;
while ( isDefined( harrierEnt ) )
wait ( 0.1 );
if (isDefined(harrierEnt))
harrierEnt waitForHarrierToDie();
level.planes--;
}
waitForHarrierToDie()
{
self endon("death");
if (level.harrier_fast)
self endon("leaving");
while ( isDefined( self ) )
wait ( 0.1 );
}
clearProgress( delay )
{
wait ( 2.0 );
@ -375,8 +405,14 @@ pointIsInAirstrikeArea( point, targetpos, yaw, airstrikeType )
}
losRadiusDamage( pos, radius, max, min, owner, eInflictor, sWeapon )
losRadiusDamage( pos, radius, max, min, owner, eInflictor, sWeapon, team )
{
if (level.airstrike_teamChangeFix && level.teambased && isDefined(team))
{
if (!isDefined(owner) || owner.team != team)
return;
}
ents = maps\mp\gametypes\_weapons::getDamageableEnts(pos, radius, true);
glassRadiusDamage( pos, radius, max, min );
@ -522,7 +558,7 @@ traceBomb()
#/
doBomberStrike( lifeId, owner, requiredDeathCount, bombsite, startPoint, endPoint, bombTime, flyTime, direction, airStrikeType )
doBomberStrike( lifeId, owner, requiredDeathCount, bombsite, startPoint, endPoint, bombTime, flyTime, direction, airStrikeType, team )
{
// plane spawning randomness = up to 125 units, biased towards 0
// radius of bomb damage is 512
@ -550,7 +586,7 @@ doBomberStrike( lifeId, owner, requiredDeathCount, bombsite, startPoint, endPoin
thread stealthBomber_killCam( plane, pathEnd, flyTime, airStrikeType );
thread bomberDropBombs( plane, bombsite, owner );
thread bomberDropBombs( plane, bombsite, owner, team );
// Delete the plane after its flyby
wait ( flyTime );
@ -559,7 +595,7 @@ doBomberStrike( lifeId, owner, requiredDeathCount, bombsite, startPoint, endPoin
}
bomberDropBombs( plane, bombSite, owner )
bomberDropBombs( plane, bombSite, owner, team )
{
while ( !targetIsClose( plane, bombsite, 5000 ) )
wait ( 0.05 );
@ -584,7 +620,7 @@ bomberDropBombs( plane, bombSite, owner )
showFx = !showFx;
if ( dist < 4500 )
plane thread callStrike_bomb( plane.origin, owner, (0,0,0), showFx );
plane thread callStrike_bomb( plane.origin, owner, (0,0,0), showFx, team );
wait ( 0.1 );
}
@ -625,7 +661,7 @@ stealthBomber_killCam( plane, pathEnd, flyTime, typeOfStrike )
}
callStrike_bomb( coord, owner, offset, showFx )
callStrike_bomb( coord, owner, offset, showFx, team )
{
if ( !isDefined( owner ) || owner isEMPed() )
{
@ -664,11 +700,11 @@ callStrike_bomb( coord, owner, offset, showFx )
thread playSoundInSpace( "exp_airstrike_bomb", bombPoint );
radiusArtilleryShellshock( bombPoint, 512, 8, 4, owner.team );
losRadiusDamage( bombPoint + (0,0,16), 896, 300, 50, owner, self, "stealth_bomb_mp" ); // targetpos, radius, maxdamage, mindamage, player causing damage
losRadiusDamage( bombPoint + (0,0,16), 896, 300, 50, owner, self, "stealth_bomb_mp", team ); // targetpos, radius, maxdamage, mindamage, player causing damage
}
doPlaneStrike( lifeId, owner, requiredDeathCount, bombsite, startPoint, endPoint, bombTime, flyTime, direction, typeOfStrike )
doPlaneStrike( lifeId, owner, requiredDeathCount, bombsite, startPoint, endPoint, bombTime, flyTime, direction, typeOfStrike, team )
{
// plane spawning randomness = up to 125 units, biased towards 0
// radius of bomb damage is 512
@ -714,7 +750,7 @@ doPlaneStrike( lifeId, owner, requiredDeathCount, bombsite, startPoint, endPoint
#/
//thread callStrike_planeSound( plane, bombsite );
thread callStrike_bombEffect( plane, pathEnd, flyTime, bombTime - 1.0, owner, requiredDeathCount, typeOfStrike );
thread callStrike_bombEffect( plane, pathEnd, flyTime, bombTime - 1.0, owner, requiredDeathCount, typeOfStrike, team );
// Delete the plane after its flyby
wait flyTime;
@ -722,7 +758,7 @@ doPlaneStrike( lifeId, owner, requiredDeathCount, bombsite, startPoint, endPoint
plane delete();
}
callStrike_bombEffect( plane, pathEnd, flyTime, launchTime, owner, requiredDeathCount, typeOfStrike )
callStrike_bombEffect( plane, pathEnd, flyTime, launchTime, owner, requiredDeathCount, typeOfStrike, team )
{
wait ( launchTime );
@ -804,7 +840,7 @@ callStrike_bombEffect( plane, pathEnd, flyTime, launchTime, owner, requiredDeath
thread airstrikeLine( bombOrigin, traceHit, (1,0,0), 40 );
#/
thread losRadiusDamage( traceHit + (0,0,16), 512, 200, 30, owner, bomb, "artillery_mp" ); // targetpos, radius, maxdamage, mindamage, player causing damage, entity that player used to cause damage
thread losRadiusDamage( traceHit + (0,0,16), 512, 200, 30, owner, bomb, "artillery_mp", team ); // targetpos, radius, maxdamage, mindamage, player causing damage, entity that player used to cause damage
if ( i%3 == 0 )
{
@ -857,8 +893,10 @@ playPlaneFx()
playfxontag( level.fx_airstrike_contrail, self, "tag_left_wingtip" );
}
callStrike( lifeId, owner, coord, yaw )
callStrike( lifeId, owner, coord, yaw, airStrikeType, team )
{
if (!isDefined(airStrikeType))
airStrikeType = self.airStrikeType;
heightEnt = undefined;
planeBombExplodeDistance = 0;
@ -866,7 +904,7 @@ callStrike( lifeId, owner, coord, yaw )
direction = ( 0, yaw, 0 );
heightEnt = GetEnt( "airstrikeheight", "targetname" );
if ( self.airStrikeType == "stealth" )
if ( airStrikeType == "stealth" )
{
thread teamPlayerCardSplash( "used_stealth_airstrike", owner, owner.team );
@ -915,7 +953,7 @@ callStrike( lifeId, owner, coord, yaw )
startPoint += ( 0, 0, planeFlyHeight );
if ( self.airStrikeType == "stealth" )
if ( airStrikeType == "stealth" )
endPoint = coord + vector_multiply( anglestoforward( direction ), planeHalfDistance*4 );
else
endPoint = coord + vector_multiply( anglestoforward( direction ), planeHalfDistance );
@ -943,44 +981,48 @@ callStrike( lifeId, owner, coord, yaw )
level.airStrikeDamagedEntsCount = 0;
level.airStrikeDamagedEntsIndex = 0;
if ( self.airStrikeType == "harrier" )
if ( airStrikeType == "harrier" )
{
level thread doPlaneStrike( lifeId, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(500)), endPoint+(0,0,randomInt(500)), bombTime, flyTime, direction, self.airStrikeType );
level thread doPlaneStrike( lifeId, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(500)), endPoint+(0,0,randomInt(500)), bombTime, flyTime, direction, airStrikeType, team );
wait randomfloatrange( 1.5, 2.5 );
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
level thread doPlaneStrike( lifeId, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(200)), endPoint+(0,0,randomInt(200)), bombTime, flyTime, direction, self.airStrikeType );
level thread doPlaneStrike( lifeId, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(200)), endPoint+(0,0,randomInt(200)), bombTime, flyTime, direction, airStrikeType, team );
wait randomfloatrange( 1.5, 2.5 );
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
harrier = beginHarrier( lifeId, startPoint, coord );
harrier = beginHarrier( lifeId, startPoint, coord, team );
if (!isDefined(harrier))
return;
owner thread defendLocation( harrier );
return harrier;
//owner thread harrierMissileStrike( startPoint, coord );
}
else if ( self.airStrikeType == "stealth" )
else if ( airStrikeType == "stealth" )
{
level thread doBomberStrike( lifeId, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(1000)), endPoint+(0,0,randomInt(1000)), bombTime, flyTime, direction, self.airStrikeType );
level thread doBomberStrike( lifeId, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(1000)), endPoint+(0,0,randomInt(1000)), bombTime, flyTime, direction, airStrikeType, team );
}
else //common airstrike
{
level thread doPlaneStrike( lifeId, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(500)), endPoint+(0,0,randomInt(500)), bombTime, flyTime, direction, self.airStrikeType );
level thread doPlaneStrike( lifeId, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(500)), endPoint+(0,0,randomInt(500)), bombTime, flyTime, direction, airStrikeType, team );
wait randomfloatrange( 1.5, 2.5 );
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
level thread doPlaneStrike( lifeId, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(200)), endPoint+(0,0,randomInt(200)), bombTime, flyTime, direction, self.airStrikeType );
level thread doPlaneStrike( lifeId, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(200)), endPoint+(0,0,randomInt(200)), bombTime, flyTime, direction, airStrikeType, team );
wait randomfloatrange( 1.5, 2.5 );
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
level thread doPlaneStrike( lifeId, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(200)), endPoint+(0,0,randomInt(200)), bombTime, flyTime, direction, self.airStrikeType );
level thread doPlaneStrike( lifeId, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(200)), endPoint+(0,0,randomInt(200)), bombTime, flyTime, direction, airStrikeType, team );
if ( self.airStrikeType == "super" )
if ( airStrikeType == "super" )
{
wait randomfloatrange( 2.5, 3.5 );
maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
level thread doPlaneStrike( lifeId, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(200)), endPoint+(0,0,randomInt(200)), bombTime, flyTime, direction, self.airStrikeType );
level thread doPlaneStrike( lifeId, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(200)), endPoint+(0,0,randomInt(200)), bombTime, flyTime, direction, airStrikeType, team );
}
}
}
@ -1102,11 +1144,11 @@ selectAirstrikeLocation( lifeId, airStrikeType )
return false;
}
self thread finishAirstrikeUsage( lifeId, location, directionYaw );
self thread finishAirstrikeUsage( lifeId, location, directionYaw, airStrikeType );
return true;
}
finishAirstrikeUsage( lifeId, location, directionYaw )
finishAirstrikeUsage( lifeId, location, directionYaw, airStrikeType )
{
self notify( "used" );
@ -1114,7 +1156,7 @@ finishAirstrikeUsage( lifeId, location, directionYaw )
trace = bullettrace( level.mapCenter + (0,0,1000000), level.mapCenter, false, undefined );
location = (location[0], location[1], trace["position"][2] - 514);
thread doAirstrike( lifeId, location, directionYaw, self, self.pers["team"] );
self thread doAirstrike( lifeId, location, directionYaw, self, self.pers["team"], airStrikeType );
}

View File

@ -13,6 +13,9 @@
- scr_emp_doesFriendlyFire <bool>
true - (default) whether or not if an emp destroies all killstreaks reguardless of friendly fire
- scr_emp_checkHeliQueue <bool>
false - (default) whether or not if an emp destroies helicopters in the queue
Thanks: H3X1C, Emosewaj
*/
@ -37,9 +40,11 @@ init()
setDvarIfUninitialized( "scr_emp_duration", 60 );
setDvarIfUninitialized( "scr_emp_doesFriendlyFire", true );
setDvarIfUninitialized( "scr_emp_checkHeliQueue", false );
level.empduration = getDvarInt( "scr_emp_duration" );
level.empDoesFriendlyFire = getDvarInt( "scr_emp_doesFriendlyFire" );
level.empCheckHeliQueue = getDvarInt( "scr_emp_checkHeliQueue" );
level thread onPlayerConnect();
}
@ -134,7 +139,7 @@ EMP_JamTeam( teamName, duration, delay, silent )
level.teamEMPed[teamName] = true;
level notify ( "emp_update" );
level destroyActiveVehicles( self, !level.empDoesFriendlyFire );
level destroyActiveVehicles( self, !level.empDoesFriendlyFire, teamName );
maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( duration );
@ -157,7 +162,7 @@ EMP_JamPlayers( owner, duration, delay, silent )
level notify ( "EMP_JamPlayers" );
level endon ( "EMP_JamPlayers" );
assert( isDefined( owner ) );
//assert( isDefined( owner ) );
//wait ( delay );
@ -165,7 +170,7 @@ EMP_JamPlayers( owner, duration, delay, silent )
{
player playLocalSound( "emp_activate" );
if ( player == owner )
if ( isDefined( owner ) && player == owner )
continue;
if ( player _hasPerk( "specialty_localjammer" ) )
@ -198,7 +203,7 @@ EMP_JamPlayers( owner, duration, delay, silent )
foreach ( player in level.players )
{
if ( player == owner )
if ( isDefined( owner ) && player == owner )
continue;
if ( player _hasPerk( "specialty_localjammer" ) )
@ -284,37 +289,58 @@ EMP_PlayerTracker()
}
}
destroyActiveVehicles( attacker, friendlyFireCheck )
destroyActiveVehicles( attacker, friendlyFireCheck, teamName )
{
if (!isDefined(friendlyFireCheck))
friendlyFireCheck = false;
if (level.empCheckHeliQueue && isDefined(level.queues) && isDefined(level.queues["helicopter"]))
{
newQueue = [];
foreach ( element in level.queues[ "helicopter" ] )
{
if ( !isDefined( element ) )
continue;
if (!friendlyFireCheck || !isDefined(element.player) || !isDefined(element.player.team) || (level.teamBased && (!isDefined(teamName) || element.player.team == teamName)) || (!level.teamBased && (!isDefined(attacker) || element.player != attacker)))
{
element delete();
continue;
}
newQueue[newQueue.size] = element;
}
level.queues[ "helicopter" ] = newQueue;
}
if ( isDefined( attacker ) )
{
foreach ( heli in level.helis )
if (!friendlyFireCheck || (level.teamBased && heli.team != attacker.team) || (!level.teamBased && (!isDefined(heli.owner) || heli.owner != attacker)))
if (!friendlyFireCheck || (level.teamBased && (!isDefined(teamName) || heli.team == teamName)) || (!level.teamBased && (!isDefined(heli.owner) || heli.owner != attacker)))
radiusDamage( heli.origin, 384, 5000, 5000, attacker );
foreach ( littleBird in level.littleBird )
if (!friendlyFireCheck || (level.teamBased && littleBird.team != attacker.team) || (!level.teamBased && (!isDefined(littleBird.owner) || littleBird.owner != attacker)))
if (!friendlyFireCheck || (level.teamBased && (!isDefined(teamName) || littleBird.team == teamName)) || (!level.teamBased && (!isDefined(littleBird.owner) || littleBird.owner != attacker)))
radiusDamage( littleBird.origin, 384, 5000, 5000, attacker );
foreach ( turret in level.turrets )
if (!friendlyFireCheck || (level.teamBased && turret.team != attacker.team) || (!level.teamBased && (!isDefined(turret.owner) || turret.owner != attacker)))
if (!friendlyFireCheck || (level.teamBased && (!isDefined(teamName) || turret.team == teamName)) || (!level.teamBased && (!isDefined(turret.owner) || turret.owner != attacker)))
radiusDamage( turret.origin, 16, 5000, 5000, attacker );
foreach ( rocket in level.rockets )
if (!friendlyFireCheck || (level.teamBased && rocket.team != attacker.team) || (!level.teamBased && (!isDefined(rocket.owner) || rocket.owner != attacker)))
if (!friendlyFireCheck || (level.teamBased && (!isDefined(teamName) || rocket.team == teamName)) || (!level.teamBased && (!isDefined(rocket.owner) || rocket.owner != attacker)))
rocket notify ( "death" );
if ( level.teamBased )
{
foreach ( uav in level.uavModels["allies"] )
if (!friendlyFireCheck || uav.team != attacker.team)
if (!friendlyFireCheck || !isDefined(teamName) || uav.team == teamName)
radiusDamage( uav.origin, 384, 5000, 5000, attacker );
foreach ( uav in level.uavModels["axis"] )
if (!friendlyFireCheck || uav.team != attacker.team)
if (!friendlyFireCheck || !isDefined(teamName) || uav.team == teamName)
radiusDamage( uav.origin, 384, 5000, 5000, attacker );
}
else
@ -325,30 +351,36 @@ destroyActiveVehicles( attacker, friendlyFireCheck )
}
if ( isDefined( level.ac130player ) )
if (!friendlyFireCheck || (level.teamBased && level.ac130player.team != attacker.team) || (!level.teamBased && level.ac130player != attacker))
if (!friendlyFireCheck || (level.teamBased && (!isDefined(teamName) || level.ac130player.team == teamName)) || (!level.teamBased && level.ac130player != attacker))
radiusDamage( level.ac130.planeModel.origin+(0,0,10), 1000, 5000, 5000, attacker );
}
else
{
foreach ( heli in level.helis )
radiusDamage( heli.origin, 384, 5000, 5000 );
if (!friendlyFireCheck || (level.teamBased && (!isDefined(teamName) || heli.team == teamName)) || !level.teamBased)
radiusDamage( heli.origin, 384, 5000, 5000 );
foreach ( littleBird in level.littleBird )
radiusDamage( littleBird.origin, 384, 5000, 5000 );
if (!friendlyFireCheck || (level.teamBased && (!isDefined(teamName) || littleBird.team == teamName)) || !level.teamBased)
radiusDamage( littleBird.origin, 384, 5000, 5000 );
foreach ( turret in level.turrets )
radiusDamage( turret.origin, 16, 5000, 5000 );
if (!friendlyFireCheck || (level.teamBased && (!isDefined(teamName) || turret.team == teamName)) || !level.teamBased)
radiusDamage( turret.origin, 16, 5000, 5000 );
foreach ( rocket in level.rockets )
rocket notify ( "death" );
if (!friendlyFireCheck || (level.teamBased && (!isDefined(teamName) || rocket.team == teamName)) || !level.teamBased)
rocket notify ( "death" );
if ( level.teamBased )
{
foreach ( uav in level.uavModels["allies"] )
radiusDamage( uav.origin, 384, 5000, 5000 );
if (!friendlyFireCheck || !isDefined(teamName) || uav.team == teamName)
radiusDamage( uav.origin, 384, 5000, 5000 );
foreach ( uav in level.uavModels["axis"] )
radiusDamage( uav.origin, 384, 5000, 5000 );
if (!friendlyFireCheck || !isDefined(teamName) || uav.team == teamName)
radiusDamage( uav.origin, 384, 5000, 5000 );
}
else
{
@ -357,6 +389,7 @@ destroyActiveVehicles( attacker, friendlyFireCheck )
}
if ( isDefined( level.ac130player ) )
radiusDamage( level.ac130.planeModel.origin+(0,0,10), 1000, 5000, 5000 );
if (!friendlyFireCheck || (level.teamBased && (!isDefined(teamName) || level.ac130player.team == teamName)) || !level.teamBased)
radiusDamage( level.ac130.planeModel.origin+(0,0,10), 1000, 5000, 5000 );
}
}

View File

@ -16,8 +16,14 @@
// Jordan Hirsh Dec. 18th 2008
********************************************************************/
beginHarrier( lifeId, startPoint, pos )
beginHarrier( lifeId, startPoint, pos, team )
{
if (isDefined(level.airstrike_teamChangeFix) && level.airstrike_teamChangeFix && level.teambased && isDefined(team))
{
if (!isDefined(self) || self.team != team)
return;
}
heightEnt = GetEnt( "airstrikeheight", "targetname" );
if ( isDefined( heightEnt ) )

View File

@ -2,7 +2,7 @@
_killstreaks modded
Author: INeedGames
Date: 09/22/2020
Adds killstreak rollover and killstreak HUD.origin
Adds killstreak rollover and killstreak HUD
DVARS:
- scr_killstreak_rollover <int>
@ -11,7 +11,10 @@
2 - killstreaks rollover only with hardline pro
- scr_maxKillstreakRollover <int>
10 - (default) allow to rollover killstreaks <int> times. (remember you are limited to 10 rollovers as defined in _class.gsc)
10 - (default) allow to rollover killstreaks <int> times.
- scr_currentRolloverKillstreaksOnlyIncrease <bool>
0 - (default) if only killstreaks from their current rollover will increase streak
- scr_killstreak_mod <int>
0 - (default) offsets all killstreaks reward costs by <int> amount
@ -21,8 +24,10 @@
1 - use Puffiamo's killstreak HUD
2 - use NoFate's MW3 killstreak HUD
- scr_killstreak_print <bool>
false - (default) enables the CoD4 (10 Kill Streak!) messages
- scr_killstreak_print <int>
0 - (default) none
1 - enables the CoD4 (10 Kill Streak!) messages
2 - adds exp rewards for each 5 kills
- scr_specialist <bool>
false - (default) enable specialist from mw3, a player must only have the nuke selected as their killstreak
@ -77,6 +82,7 @@ init()
level.killstreakRoundDelay = getIntProperty( "scr_game_killstreakdelay", 8 );
setDvarIfUninitialized( "scr_killstreak_rollover", false );
setDvarIfUninitialized( "scr_currentRolloverKillstreaksOnlyIncrease", false );
setDvarIfUninitialized( "scr_maxKillstreakRollover", 10 );
setDvarIfUninitialized( "scr_killstreakHud", false );
setDvarIfUninitialized( "scr_killstreak_mod", 0 );
@ -89,6 +95,7 @@ init()
level.killstreaksRollOver = getDvarInt("scr_killstreak_rollover");
level.maxKillstreakRollover = getDvarInt("scr_maxKillstreakRollover");
level.rolloverKillstreaksOnlyIncrease = getDvarInt("scr_currentRolloverKillstreaksOnlyIncrease");
level.killstreakHud = getDvarInt("scr_killstreakHud");
level.killStreakMod = getDvarInt( "scr_killstreak_mod" );
level.killstreakPrint = getDvarInt( "scr_killstreak_print" );
@ -224,7 +231,10 @@ waitForChangeTeam()
for ( ;; )
{
self waittill ( "joined_team" );
clearKillstreaks();
self clearKillstreaks();
if ( self isUsingRemote() )
self clearUsingRemote();
}
}
@ -525,6 +535,7 @@ checkKillstreakReward( streakCount )
foreach ( streakVal, streakName in self.killStreaks )
{
actualVal = streakVal + level.killStreakMod;
curRollover = 0;
if ( actualVal > streakCount )
break;
@ -556,7 +567,7 @@ checkKillstreakReward( streakCount )
useStreakName = streakName;
}
if ( self tryGiveKillstreak( useStreakName, int(max( actualVal, streakCount )) ) )
if ( self tryGiveKillstreak( useStreakName, int(max( actualVal, streakCount )), curRollover ) )
{
self thread killstreakEarned( useStreakName );
self.pers["lastEarnedStreak"] = streakName;
@ -620,19 +631,19 @@ rewardNotify( streakName, streakVal )
}
tryGiveKillstreak( streakName, streakVal )
tryGiveKillstreak( streakName, streakVal, curRollover )
{
level notify ( "gave_killstreak", streakName );
if ( !level.gameEnded )
self thread rewardNotify( streakName, streakVal );
self giveKillstreak( streakName, streakVal, true );
self giveKillstreak( streakName, streakVal, true, self, curRollover );
return true;
}
giveKillstreak( streakName, isEarned, awardXp, owner )
giveKillstreak( streakName, isEarned, awardXp, owner, curRollover )
{
self endon ( "disconnect" );
@ -655,10 +666,19 @@ giveKillstreak( streakName, isEarned, awardXp, owner )
self.pers["kID"]++;
toLifeId = self.pers["deaths"];
if (level.rolloverKillstreaksOnlyIncrease && isDefined(curRollover) && curRollover > 0)
{
if (curRollover == 1)
toLifeId += 0.75;
else
toLifeId += 1/curRollover;
}
if ( !self.pers["killstreaks"][0].earned )
self.pers["killstreaks"][0].lifeId = -1;
else
self.pers["killstreaks"][0].lifeId = self.pers["deaths"];
self.pers["killstreaks"][0].lifeId = toLifeId;
// probably obsolete unless we bring back the autoshotty
if ( isdefined( level.killstreakSetupFuncs[ streakName ] ) )
@ -684,8 +704,11 @@ giveKillstreakWeapon( weapon )
self takeWeapon( item );
}
self _giveWeapon( weapon, 0 );
self _setActionSlot( 4, "weapon", weapon );
if ( isDefined( weapon ) && weapon != "" )
{
self _giveWeapon( weapon, 0 );
self _setActionSlot( 4, "weapon", weapon );
}
}
@ -840,7 +863,9 @@ clearRideIntro( delay )
destroyOnEvents(elem)
{
self waittill_either("disconnect", "start_killstreak_hud");
elem destroy();
if ( isDefined( elem ) )
elem destroy();
}
initKillstreakHud(inity)
@ -1408,8 +1433,8 @@ watchNotifyKSMessage()
for (curStreak = lastKs + 1; curStreak <= self.pers["cur_kill_streak"]; curStreak++)
{
if (curStreak == 5)
continue;
//if (curStreak == 5)
// continue;
if (curStreak % 5 != 0)
continue;
@ -1423,19 +1448,27 @@ watchNotifyKSMessage()
streakNotify( streakVal )
{
self endon("disconnect");
self notify("streakNotifyCoD4");
self endon("streakNotifyCoD4");
wait 0.1;
self endon( "disconnect" );
notifyData = spawnStruct();
notifyData.titleText = streakVal + " Kill Streak!";
if (level.killstreakPrint > 1)
{
xpReward = streakVal * 100;
self thread maps\mp\gametypes\_rank::giveRankXP( "killstreak_bonus", xpReward );
notifyData.notifyText = "+" + xpReward;
}
wait .05;
notifyData.titleLabel = &"MP_KILLSTREAK_N";
notifyData.titleText = streakVal;
self maps\mp\gametypes\_hud_message::notifyMessage( notifyData );
iprintln( self.name + " has a killstreak of " + streakVal + "!" );
iprintln( &"RANK_KILL_STREAK_N", self, streakVal );
}
underScorePopup(string, hudColor, glowAlpha)

View File

@ -25,8 +25,10 @@
- scr_nuke_canCall_whenScoreLimitClose_selfOnly <bool>
false - (default) wether or not to take into account just the caller's score, or everyone's score
- scr_nuke_doSlowmo <bool>
true - (default) should do a slowmo effect when nuke
- scr_nuke_doSlowmo <int>
0 - none
1 - (default) should do a slowmo effect when nuke
2 - only do slowmo effect if its the first nuke of the game
Thanks: H3X1C, Emosewaj, RaidMax
*/
@ -54,7 +56,7 @@ init()
setDvarIfUninitialized( "scr_nukeCancelMode", 0 );
setDvarIfUninitialized( "scr_nuke_is_moab", false );
setDvarIfUninitialized( "scr_nuke_doSlowmo", true );
setDvarIfUninitialized( "scr_nuke_doSlowmo", 1 );
setDvarIfUninitialized( "scr_nuke_kills_all", true );
setDvarIfUninitialized( "scr_nuke_emp_duration", 60.0 );
setDvarIfUninitialized( "scr_nuke_perm_vision", true );
@ -319,7 +321,7 @@ nukeEffects()
if ( level.teamBased )
{
if (level.nukeEmpDuration != 0)
level thread maps\mp\killstreaks\_emp::EMP_JamTeam(level.otherTeam[level.nukeInfo.team], level.nukeEmpDuration, 5, level.nukeInfo.player, true);
level.nukeInfo.player thread maps\mp\killstreaks\_emp::EMP_JamTeam(level.otherTeam[level.nukeInfo.team], level.nukeEmpDuration, 5, true);
foreach (player in level.players)
{
@ -333,7 +335,7 @@ nukeEffects()
else
{
if (level.nukeEmpDuration != 0)
level thread maps\mp\killstreaks\_emp::EMP_JamPlayers(level.nukeInfo.player, level.nukeEmpDuration, 5, true);
level.nukeInfo.player thread maps\mp\killstreaks\_emp::EMP_JamPlayers(level.nukeInfo.player, level.nukeEmpDuration, 5, true);
if(isDefined(level.nukeInfo.player))
{
@ -343,7 +345,20 @@ nukeEffects()
}
}
else
level maps\mp\killstreaks\_emp::destroyActiveVehicles( level.nukeInfo.player );
{
// clear the heli queue
while (true)
{
chopper = queueRemoveFirst( "helicopter" );
if (!isDefined(chopper))
break;
chopper delete();
}
level maps\mp\killstreaks\_emp::destroyActiveVehicles( level.nukeInfo.player, false );
}
foreach( player in level.players )
{
@ -409,12 +424,14 @@ nukeAftermathEffect()
nukeSlowMo()
{
if (!level.nukeDoSlowmo)
if (!level.nukeDoSlowmo || (level.nukeDoSlowmo == 2 && isDefined(level.nuked)))
return;
//SetSlowMotion( <startTimescale>, <endTimescale>, <deltaTime> )
setSlowMotion( 1.0, 0.25, 0.5 );
level waittill_either( "nuke_death", "nuke_cancelled" );
level.nuked = true;
setSlowMotion( 0.25, 1, 2.0 );
}

View File

@ -629,8 +629,12 @@ selectOneManArmyClass()
level endon ( "game_ended" );
self _disableWeaponSwitch();
self _disableOffhandWeapons();
self _disableUsability();
if (level.fix_onemanarmyFlareBug)
{
self _disableOffhandWeapons();
self _disableUsability();
}
self openPopupMenu( game["menu_onemanarmy"] );
@ -639,22 +643,34 @@ selectOneManArmyClass()
self waittill ( "menuresponse", menu, className );
self _enableWeaponSwitch();
self _enableOffhandWeapons();
self _enableUsability();
if (level.fix_onemanarmyFlareBug)
{
self _enableOffhandWeapons();
self _enableUsability();
}
if ( className == "back" || !isOneManArmyMenu( menu ) || self isUsingRemote() )
{
if ( self getCurrentWeapon() == "onemanarmy_mp" )
{
self _disableWeaponSwitch();
self _disableOffhandWeapons();
self _disableUsability();
if (level.fix_onemanarmyFlareBug)
{
self _disableOffhandWeapons();
self _disableUsability();
}
self switchToWeapon( self getLastWeapon() );
self waittill ( "weapon_change" );
self _enableWeaponSwitch();
self _enableOffhandWeapons();
self _enableUsability();
if (level.fix_onemanarmyFlareBug)
{
self _enableOffhandWeapons();
self _enableUsability();
}
}
return;
}

View File

@ -12,6 +12,9 @@
- onemanarmyRefillsTubes <bool>
false - (default) One Man Army does not refill the gl attachment
true - it does
- fix_onemanarmyFlareBug <bool>
true - (default) fixes it
*/
#include common_scripts\utility;
@ -200,6 +203,9 @@ init()
setDvarIfUninitialized( "onemanarmyRefillsTubes", false );
level.onemanarmyRefillsTubes = getDvarInt( "onemanarmyRefillsTubes" );
setDvarIfUninitialized( "fix_onemanarmyFlareBug", true );
level.fix_onemanarmyFlareBug = getDvarInt( "fix_onemanarmyFlareBug" );
initPerkDvars();
level thread onPlayerConnect();

18
userraw/mp/classtable.csv Normal file
View File

@ -0,0 +1,18 @@
loadoutName,CLASS_CLASS1,CLASS_CLASS2,CLASS_CLASS3,CLASS_CLASS4,CLASS_CLASS5,CLASS_CLASS1,CLASS_CLASS2,CLASS_CLASS3,CLASS_CLASS4,CLASS_CLASS5,CLASS_DEFAULT
loadoutPrimary,famas,ump45,sa80,barrett,riotshield,m4,mp5k,rpd,cheytac,riotshield,m4
loadoutPrimaryAttachment,gl,eotech,reflex,heartbeat,none,none,none,none,none,none,none
loadoutPrimaryAttachment2,none,none,grip,fmj,none,none,none,none,none,none,none
loadoutPrimaryCamo,none,none,none,none,none,none,none,none,none,none,none
loadoutSecondary,spas12,coltanaconda,at4,usp,pp2000,usp,spas12,at4,pp2000,pp2000,usp
loadoutSecondaryAttachment,silencer,tactical,none,silencer,akimbo,none,none,none,none,none,none
loadoutSecondaryAttachment2,none,none,none,none,none,none,none,none,none,none,none
loadoutSecondaryCamo,none,none,none,none,none,none,none,none,none,none,none
loadoutEquipment,frag_grenade_mp,semtex_mp,semtex_mp,specialty_tacticalinsertion,specialty_blastshield,frag_grenade_mp,semtex_mp,semtex_mp,frag_grenade_mp,frag_grenade_mp,frag_grenade_mp
loadoutPerk1,specialty_scavenger,specialty_marathon,specialty_bling,specialty_bling,specialty_marathon,specialty_fastreload,specialty_marathon,specialty_fastreload,specialty_fastreload,specialty_marathon,specialty_fastreload
loadoutPerk2,specialty_bulletdamage,specialty_lightweight,specialty_explosivedamage,specialty_coldblooded,specialty_hardline,specialty_bulletdamage,specialty_lightweight,specialty_bulletdamage,specialty_bulletdamage,specialty_lightweight,specialty_bulletdamage
loadoutPerk3,specialty_extendedmelee,specialty_heartbreaker,specialty_detectexplosive,specialty_localjammer,specialty_extendedmelee,specialty_bulletaccuracy,specialty_extendedmelee,specialty_extendedmelee,specialty_bulletaccuracy,specialty_extendedmelee,specialty_bulletaccuracy
loadoutOffHand,concussion_grenade,flash_grenade,flash_grenade,smoke_grenade,concussion_grenade,concussion_grenade,flash_grenade,flash_grenade,smoke_grenade,concussion_grenade,concussion_grenade
loadoutStreak1,uav,uav,uav,uav,uav,uav,uav,uav,uav,uav,uav
loadoutStreak2,predator_missile,predator_missile,predator_missile,predator_missile,predator_missile,predator_missile,predator_missile,predator_missile,predator_missile,predator_missile,predator_missile
loadoutStreak3,helicopter,helicopter,helicopter,helicopter,helicopter,helicopter,helicopter,helicopter,helicopter,helicopter,helicopter
loadoutDeathStreak,specialty_copycat,specialty_finalstand,specialty_combathigh,specialty_copycat,specialty_combathigh,specialty_copycat,specialty_copycat,specialty_copycat,specialty_copycat,specialty_copycat,specialty_copycat
1 loadoutName CLASS_CLASS1 CLASS_CLASS2 CLASS_CLASS3 CLASS_CLASS4 CLASS_CLASS5 CLASS_CLASS1 CLASS_CLASS2 CLASS_CLASS3 CLASS_CLASS4 CLASS_CLASS5 CLASS_DEFAULT
2 loadoutPrimary famas ump45 sa80 barrett riotshield m4 mp5k rpd cheytac riotshield m4
3 loadoutPrimaryAttachment gl eotech reflex heartbeat none none none none none none none
4 loadoutPrimaryAttachment2 none none grip fmj none none none none none none none
5 loadoutPrimaryCamo none none none none none none none none none none none
6 loadoutSecondary spas12 coltanaconda at4 usp pp2000 usp spas12 at4 pp2000 pp2000 usp
7 loadoutSecondaryAttachment silencer tactical none silencer akimbo none none none none none none
8 loadoutSecondaryAttachment2 none none none none none none none none none none none
9 loadoutSecondaryCamo none none none none none none none none none none none
10 loadoutEquipment frag_grenade_mp semtex_mp semtex_mp specialty_tacticalinsertion specialty_blastshield frag_grenade_mp semtex_mp semtex_mp frag_grenade_mp frag_grenade_mp frag_grenade_mp
11 loadoutPerk1 specialty_scavenger specialty_marathon specialty_bling specialty_bling specialty_marathon specialty_fastreload specialty_marathon specialty_fastreload specialty_fastreload specialty_marathon specialty_fastreload
12 loadoutPerk2 specialty_bulletdamage specialty_lightweight specialty_explosivedamage specialty_coldblooded specialty_hardline specialty_bulletdamage specialty_lightweight specialty_bulletdamage specialty_bulletdamage specialty_lightweight specialty_bulletdamage
13 loadoutPerk3 specialty_extendedmelee specialty_heartbreaker specialty_detectexplosive specialty_localjammer specialty_extendedmelee specialty_bulletaccuracy specialty_extendedmelee specialty_extendedmelee specialty_bulletaccuracy specialty_extendedmelee specialty_bulletaccuracy
14 loadoutOffHand concussion_grenade flash_grenade flash_grenade smoke_grenade concussion_grenade concussion_grenade flash_grenade flash_grenade smoke_grenade concussion_grenade concussion_grenade
15 loadoutStreak1 uav uav uav uav uav uav uav uav uav uav uav
16 loadoutStreak2 predator_missile predator_missile predator_missile predator_missile predator_missile predator_missile predator_missile predator_missile predator_missile predator_missile predator_missile
17 loadoutStreak3 helicopter helicopter helicopter helicopter helicopter helicopter helicopter helicopter helicopter helicopter helicopter
18 loadoutDeathStreak specialty_copycat specialty_finalstand specialty_combathigh specialty_copycat specialty_combathigh specialty_copycat specialty_copycat specialty_copycat specialty_copycat specialty_copycat specialty_copycat

View File

@ -0,0 +1,4 @@
init()
{
level thread maps\mp\bots\_bot_chat::init();
}

View File

@ -13,89 +13,80 @@ init()
level thread watchTeams();
level thread watchCheater();
level thread watchBotCrackedClass();
level thread watchBoxmap();
level thread watchNuke();
level thread watchSniper();
}
watchBoxmap()
watchSniper()
{
if (getDvar("mapname") == "iw4_credits")
setDvar("scr_spawnsimple", 1);
else
setDvar("scr_spawnsimple", 0);
}
if ( getDvar( "bot_sniperCheck" ) == "" )
return;
watchCheater()
{
SetDvar("bot_cheater", "");
for (;;)
for ( ;; )
{
wait 0.05;
wait 15;
logPrint("keepalive\n");
cheatername = GetDvar("bot_cheater");
if (cheatername == "")
continue;
numPlayers = 0;
numSnipers = 0;
cheater = undefined;
// find player name
foreach( player in level.players )
for ( i = 0; i < level.players.size; i++ )
{
if (!isSubStr(toLower(player.name), toLower(cheatername)))
player = level.players[i];
if ( player is_bot() )
continue;
cheater = player;
if ( !isDefined( player.team ) )
continue;
numPlayers++;
if ( isDefined( player.isSniper ) && player.isSniper )
numSnipers++;
}
if (!isDefined(cheater) || !isReallyAlive(cheater))
continue;
// now tell all bots to target
foreach( bot in level.bots )
if ( numPlayers > 0 )
{
if (randomInt(2) && isDefined(bot.bot.target) && isDefined(bot.bot.target.entity) && bot.bot.target.entity getEntityNumber() == cheater getEntityNumber())
bot thread BotPressAttack(0.1);
bot SetWeaponAmmoClip(bot GetCurrentWeapon(), 999);
bot.pers["bots"]["skill"]["aim_time"] = 0.05;
bot.pers["bots"]["skill"]["init_react_time"] = 0;
bot.pers["bots"]["skill"]["reaction_time"] = 1000;
bot.pers["bots"]["skill"]["no_trace_ads_time"] = 0;
bot.pers["bots"]["skill"]["no_trace_look_time"] = 0;
bot.pers["bots"]["skill"]["remember_time"] = 50;
bot.pers["bots"]["skill"]["fov"] = 1;
bot.pers["bots"]["skill"]["dist"] = 100000;
bot.pers["bots"]["skill"]["spawn_time"] = 0;
bot.pers["bots"]["skill"]["help_dist"] = 0;
bot.pers["bots"]["skill"]["semi_time"] = 0.05;
bot.pers["bots"]["skill"]["bones"] = "j_head";
if (isDefined(bot.bot.target) && isDefined(bot.bot.target.entity))
{
if (bot.bot.target.entity getEntityNumber() != cheater getEntityNumber())
{
bot.bot.targets = [];
bot.bot.target = undefined;
bot notify("new_enemy");
}
}
bot SetAttacker(cheater);
if ( numSnipers / numPlayers >= 0.5 )
setDvar( "bots_sniperLoadout", 1 );
else
setDvar( "bots_sniperLoadout", 0 );
}
}
}
watchNuke()
{
setDvar( "scr_spawnpointfavorweight", "" );
for ( i = 0; i < 3; i++ )
level waittill( "nuke_death" );
setDvar( "scr_spawnpointfavorweight", "499999" );
}
watchBoxmap()
{
if ( getDvar( "mapname" ) == "iw4_credits" )
setDvar( "scr_spawnsimple", 1 );
else
setDvar( "scr_spawnsimple", 0 );
}
watchBotCrackedClass()
{
if(getDvar("bot_pvb_helper_customBotClassTeam") == "")
setDvar("bot_pvb_helper_customBotClassTeam", "");
if ( getDvar( "bot_pvb_helper_customBotClassTeam" ) == "" )
setDvar( "bot_pvb_helper_customBotClassTeam", "" );
for (;;)
for ( ;; )
{
level waittill("bot_connected", bot);
level waittill( "bot_connected", bot );
bot thread watchBotLoadout();
}
@ -103,20 +94,20 @@ watchBotCrackedClass()
watchBotLoadout()
{
self endon("disconnect");
self endon( "disconnect" );
random = randomInt(2);
random = randomInt( 2 );
for (;;)
for ( ;; )
{
self waittill("bot_giveLoadout");
self waittill( "bot_giveLoadout" );
team = getDvar("bot_pvb_helper_customBotClassTeam");
team = getDvar( "bot_pvb_helper_customBotClassTeam" );
if (team == "")
if ( team == "" )
continue;
if (self.team != team)
if ( self.team != team )
continue;
// clear perks and weapons
@ -135,7 +126,8 @@ watchBotLoadout()
self maps\mp\perks\_perks::givePerk( "semtex_mp" );
twoStreak = "helicopter_minigun";
if (random)
if ( random )
twoStreak = "ac130";
self maps\mp\gametypes\_class::setKillstreaks( "harrier_airstrike", twoStreak, "nuke" );
@ -151,26 +143,29 @@ watchBotLoadout()
watchTeams()
{
if(getDvar("bot_pvb_helper_noPlayersOnTeam") == "")
setDvar("bot_pvb_helper_noPlayersOnTeam", "");
if ( getDvar( "bot_pvb_helper_noPlayersOnTeam" ) == "" )
setDvar( "bot_pvb_helper_noPlayersOnTeam", "" );
for (;;)
for ( ;; )
{
wait 1;
if (getDvar("bot_pvb_helper_noPlayersOnTeam") == "")
if ( getDvar( "bot_pvb_helper_noPlayersOnTeam" ) == "" )
continue;
team = getDvar("bot_pvb_helper_noPlayersOnTeam");
foreach (player in level.players)
team = getDvar( "bot_pvb_helper_noPlayersOnTeam" );
for ( i = 0; i < level.players.size; i++ )
{
if (player is_bot())
player = level.players[i];
if ( player is_bot() )
continue;
if (player.team != team)
if ( player.team != team )
continue;
if (team == "axis")
if ( team == "axis" )
player [[level.allies]]();
else
player [[level.axis]]();
@ -180,40 +175,42 @@ watchTeams()
onBotSayVar()
{
SetDvar("bot_say", "");
for (;;)
SetDvar( "bot_say", "" );
for ( ;; )
{
wait 0.05;
toSay = GetDvar("bot_say");
if (toSay == "")
toSay = GetDvar( "bot_say" );
if ( toSay == "" )
continue;
bot = random(getBotArray());
bot = random( getBotArray() );
if (!isDefined(bot))
if ( !isDefined( bot ) )
continue;
SetDvar("bot_say", "");
bot sayall(toSay);
SetDvar( "bot_say", "" );
bot sayall( toSay );
}
}
onSomeoneSaid()
{
for (;;)
for ( ;; )
{
level waittill("say", string, player);
level waittill( "say", string, player );
PrintConsole(player.name + ": " + string + "\n");
PrintConsole( player.name + ": ^7" + string + "\n" );
}
}
onBotConnected()
{
for (;;)
for ( ;; )
{
level waittill("bot_connected", bot);
level waittill( "bot_connected", bot );
bot thread setBotPing();
}
@ -221,12 +218,12 @@ onBotConnected()
setBotPing()
{
self endon("disconnect");
self endon( "disconnect" );
for (;;)
for ( ;; )
{
wait 0.05;
self SetPing(randomIntRange(40, 60));
self SetPing( randomIntRange( 40, 60 ) );
}
}

View File

@ -6,15 +6,18 @@
init()
{
setDvarIfUninitialized( "bots_sniperLoadout", false );
setDvarIfUninitialized( "bots_oneHardIsSniper", false );
level thread onBotConnected();
level thread watchOneHardIsSniper();
}
onBotConnected()
{
for (;;)
for ( ;; )
{
level waittill("bot_connected", bot);
level waittill( "bot_connected", bot );
bot thread onBotGivenLoadout();
}
@ -22,41 +25,72 @@ onBotConnected()
onBotGivenLoadout()
{
self endon("disconnect");
self endon( "disconnect" );
for (;;)
for ( ;; )
{
self waittill( "bot_giveLoadout", allowCopycat );
if (!getDvarInt("bots_sniperLoadout"))
if ( !getDvarInt( "bots_sniperLoadout" ) )
continue;
// clear perks and weapons
self takeAllWeapons();
self.specialty = [];
self _clearPerks();
self maps\mp\gametypes\_class::_detachAll();
// give perks
self maps\mp\perks\_perks::givePerk( "specialty_fastreload" );
self maps\mp\perks\_perks::givePerk( "specialty_quickdraw" );
self maps\mp\perks\_perks::givePerk( "specialty_bulletdamage" );
self maps\mp\perks\_perks::givePerk( "specialty_armorpiercing" );
self maps\mp\perks\_perks::givePerk( "specialty_bulletaccuracy" );
self maps\mp\perks\_perks::givePerk( "specialty_holdbreath" );
// give weapons
self _giveWeapon( "usp_mp", 0 );
self SetWeaponAmmoClip( "usp_mp", 0 );
self SetWeaponAmmoStock( "usp_mp", 0 );
self _giveWeapon( "cheytac_mp", 0 );
self setSpawnWeapon( "cheytac_mp" );
// make into sniper model
if ( level.environment != "" )
self [[game[self.team+"_model"]["GHILLIE"]]]();
else
self [[game[self.team+"_model"]["SNIPER"]]]();
self give_sniper_loadout();
}
}
watchOneHardIsSniper()
{
for(;;)
{
wait 1;
if ( !getDvarInt( "bots_oneHardIsSniper" ) )
continue;
foreach (bot in level.bots)
{
if (bot.pers["bots"]["skill"]["base"] >= 7)
{
if (isAlive(bot) && !bot.isSniper)
bot give_sniper_loadout();
break;
}
}
}
}
give_sniper_loadout()
{
self.pers["bots"]["behavior"]["quickscope"] = true;
// clear perks and weapons
self takeAllWeapons();
self.specialty = [];
self _clearPerks();
self maps\mp\gametypes\_class::_detachAll();
// give perks
self maps\mp\perks\_perks::givePerk( "specialty_fastreload" );
self maps\mp\perks\_perks::givePerk( "specialty_quickdraw" );
self maps\mp\perks\_perks::givePerk( "specialty_bulletdamage" );
self maps\mp\perks\_perks::givePerk( "specialty_armorpiercing" );
self maps\mp\perks\_perks::givePerk( "specialty_bulletaccuracy" );
self maps\mp\perks\_perks::givePerk( "specialty_holdbreath" );
// give weapons
self _giveWeapon( "usp_mp", 0 );
self SetWeaponAmmoClip( "usp_mp", 0 );
self SetWeaponAmmoStock( "usp_mp", 0 );
self _giveWeapon( "cheytac_mp", 0 );
self setSpawnWeapon( "cheytac_mp" );
// make into sniper model
if ( level.environment != "" )
self [[game[self.team + "_model"]["GHILLIE"]]]();
else
self [[game[self.team + "_model"]["SNIPER"]]]();
self.isSniper = true;
}

View File

@ -5,42 +5,52 @@
init()
{
setDvarIfUninitialized( "scr_showHP", false );
level.showHP = getDvarInt("scr_showHP");
level.showHP = getDvarInt( "scr_showHP" );
level thread onPlayerConnect();
}
onPlayerConnect()
{
for(;;)
for ( ;; )
{
level waittill( "connected", player);
level waittill( "connected", player );
player thread onPlayerSpawned();
}
}
onPlayerSpawned()
{
self endon("disconnect");
for(;;)
{
self waittill("spawned_player");
self endon( "disconnect" );
if(level.showHP)
self thread drawHP();
}
for ( ;; )
{
self waittill( "spawned_player" );
if ( level.showHP )
self thread drawHP();
}
}
destoryHPdraw()
{
self waittill_either("disconnect", "death");
self.drawHP destroy();
self endon( "disconnect" );
self waittill( "death" );
if ( isDefined( self.drawHP ) )
self.drawHP destroy();
if ( isDefined( self.drawSpeed ) )
self.drawSpeed destroy();
}
initHPdraw()
{
self.drawHP = self createFontString("default", 1.2);
self.drawHP setPoint("BOTTOMRIGHT", "BOTTOMRIGHT", -150, -20);
self.drawHP = self createFontString( "default", 1.2 );
self.drawHP setPoint( "BOTTOMRIGHT", "BOTTOMRIGHT", -150, -20 );
self.drawSpeed = self createFontString( "default", 1.2 );
self.drawSpeed setPoint( "BOTTOMRIGHT", "BOTTOMRIGHT", -150, -10 );
self thread destoryHPdraw();
}
@ -49,10 +59,14 @@ drawHP()
self endon( "disconnect" );
self endon( "death" );
self initHPdraw();
for(;;)
for ( ;; )
{
//self.drawHP setText("HP: "+self.health+" KS: "+self.pers["cur_kill_streak"]);
self.drawHP setText(self.health);
self.drawHP setValue( self.health );
vel = self getVelocity();
self.drawSpeed setValue( int( length( ( vel[0], vel[1], 0 ) ) ) );
wait 0.05;
}
}

View File

@ -0,0 +1,71 @@
init()
{
if ( getDvarInt( "spawnpoints_test" ) )
level thread doSpawnPointTest();
}
drawNoSight(sp)
{
newdeathicon = newHudElem();
newdeathicon.x = sp.origin[0];
newdeathicon.y = sp.origin[1];
newdeathicon.z = sp.origin[2] + 32;
newdeathicon.alpha = .61;
newdeathicon.archived = true;
newdeathicon setShader( "headicon_dead", 5, 5 );
newdeathicon setwaypoint( true, false );
if (isDefined(sp.wp))
sp.wp destroy();
sp.wp = newdeathicon;
}
drawSight(sp)
{
newdeathicon = newHudElem();
newdeathicon.x = sp.origin[0];
newdeathicon.y = sp.origin[1];
newdeathicon.z = sp.origin[2] + 32;
newdeathicon.alpha = .61;
newdeathicon.archived = true;
newdeathicon setShader( "rank_prestige1", 5, 5 );
newdeathicon setwaypoint( true, false );
if (isDefined(sp.wp))
sp.wp destroy();
sp.wp = newdeathicon;
}
doSpawnPointTest()
{
for ( ;; )
{
wait 0.05;
if ( !isdefined( level.spawnpoints ) )
return;
for (i = 0; i < level.spawnpoints.size; i++)
{
spawnpoint = level.spawnpoints[i];
sight = false;
if (level.teamBased)
{
sight = (spawnpoint.sights["axis"] > 0);
if (!sight)
sight = (spawnpoint.sights["allies"] > 0);
}
else
sight = (spawnpoint.sights > 0);
if (!sight)
drawNoSight(spawnpoint);
else
drawSight(spawnpoint);
}
}
}

View File

@ -0,0 +1,70 @@
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
init()
{
setDvarIfUninitialized( "dom_lastFlagUseTimeMulti", 1.0 );
thread watchFlags();
}
watchFlags()
{
if ( getDvar( "g_gametype" ) != "dom" )
return;
while ( !isDefined( level.domFlags ) )
wait 0.05;
for ( ;; )
{
wait 1;
for ( i = 0; i < level.domFlags.size; i++ )
{
flag = level.domFlags[i];
if ( isDefined( flag.originalUseTime ) )
{
flag.useTime = flag.originalUseTime;
flag.originalUseTime = undefined;
}
}
team = "none";
axisFlags = maps\mp\gametypes\dom::getTeamFlagCount( "axis" );
alliesFlags = maps\mp\gametypes\dom::getTeamFlagCount( "allies" );
if ( alliesFlags == 2 || axisFlags == 2 )
{
if ( alliesFlags == 2 )
team = "allies";
else
team = "axis";
}
if ( game["teamScores"]["axis"] < game["teamScores"]["allies"] && team == "axis" )
continue;
if ( game["teamScores"]["allies"] < game["teamScores"]["axis"] && team == "allies" )
continue;
if ( team != "none" )
{
for ( i = 0; i < level.domFlags.size; i++ )
{
flag = level.domFlags[i];
flagTeam = flag maps\mp\gametypes\_gameobjects::getOwnerTeam();
if ( flagTeam != team && ( flagTeam == "axis" || flagTeam == "allies" ) )
{
flag.originalUseTime = flag.useTime;
flag.useTime *= getDvarFloat( "dom_lastFlagUseTimeMulti" );
}
}
}
}
}

View File

@ -1 +0,0 @@
start "" "%~dp0iw4x.exe" -nosteam -scriptablehttp -console +set r_fullscreen "0" +set sv_lanonly "1" +set r_mode "1024x768" +set drawlagometer "1" +set cg_drawfps "4" +set fs_game "" +set bots_manage_fill "4" +set cg_drawsnapshot "1" +set ui_mapname "mp_rust" +set scr_game_spectatetype "2" +set scr_war_scorelimit "0" +set thereisacow "1" +set sv_cheats "1" +devmap mp_rust

View File

@ -1 +0,0 @@
start "" "%~dp0iw4x.exe" -nosteam -scriptablehttp +set r_fullscreen "1" +set sv_lanonly "1" +set r_monitor "0" +set drawlagometer "0" +set cg_drawfps "0" +set cg_drawsnapshot "0" +set r_mode "1920x1080"

1
z_deploy.bat Normal file
View File

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

View File

@ -1 +0,0 @@
start "" "%~dp0iw4x.exe" -nosteam -dump -console -scriptablehttp +set sv_lanonly "1" +set r_fullscreen "0" +set fs_game "mods/dev" +set developer "1" +set developer_script "1" +set cg_drawfps "4" +set cg_drawsnapshot "1" +set thereisacow "1" +set sv_cheats "1" +set bots_manage_add "8" +set drawlagometer "1" +set scr_game_spectatetype "2" +set r_mode "1024x768" +devmap mp_rust

View File

@ -1 +0,0 @@
start "" "%~dp0iw4x.exe" -nosteam -console -dump -scriptablehttp +set sv_lanonly "1" +set r_fullscreen "0" +set fs_game "mods/dev" +set developer "1" +set developer_script "1" +set cg_drawfps "4" +set cg_drawsnapshot "1" +set thereisacow "1" +set sv_cheats "1" +set drawlagometer "1" +set r_mode "1024x768" +connect 127.0.0.1

View File

@ -1 +1,26 @@
start "" "%~dp0iw4x.exe" -dedicated +set sv_lanonly "0" +set net_port "28960" +set fs_game "" +exec server.cfg +map_rotate
@echo off
::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=IW4x Bot Warfare Server
::Port used by the server (default: 28960)
set port=28960
::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 IW4x 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%" "%~dp0iw4x.exe" -dedicated +set sv_lanonly "0" +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

View File

@ -1 +1,26 @@
start "" "%~dp0iw4x.exe" -dedicated +set sv_lanonly "1" +set net_port "28960" +set fs_game "" +exec pvbrust.cfg +map_rotate
@echo off
::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=pvbrust.cfg
::Name of the server shown in the title of the cmd window. This will NOT bet shown ingame.
set name=IW4x Bot Warfare PvB Rust
::Port used by the server (default: 28960)
set port=28965
::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 IW4x 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%" "%~dp0iw4x.exe" -dedicated +set sv_lanonly "0" +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

View File

@ -0,0 +1,40 @@
@echo off
::Name
set name=IW4x Bot Warfare PvB Rust
::Exe of the server
set server_exe=iw4x.exe
::The regex search for the window name of the server
set server_title_regex=Bot Warfare Players vs bots 24/7 Rust 10x
::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%
::Rate to check if server is hung
set check_rate=300
::Server log location
set log_path=%gamepath%\userraw\logs\pvbrust
set log_file=games_mp.log
title IW4x MP - %name% - Server watchdog
echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates!
echo (%date%) - (%time%) %name% server watchdog start.
::https://superuser.com/questions/699769/batch-file-last-modification-time-with-seconds
dir "%log_path%"\"%log_file%" > nul
for /f "delims=" %%i in ('"forfiles /p "%log_path%" /m "%log_file%" /c "cmd /c echo @ftime" "') do set modif_time_temp=%%i
:Server
set modif_time=%modif_time_temp%
timeout /t %check_rate% /nobreak > nul
dir "%log_path%"\"%log_file%" > nul
for /f "delims=" %%i in ('"forfiles /p "%log_path%" /m "%log_file%" /c "cmd /c echo @ftime" "') do set modif_time_temp=%%i
if "%modif_time_temp%" == "%modif_time%" (
echo "(%date%) - (%time%) WARNING: %name% server hung, killing server..."
::https://stackoverflow.com/questions/26552368/windows-batch-file-taskkill-if-window-title-contains-text
for /f "tokens=2 delims=," %%a in ('
tasklist /fi "imagename eq %server_exe%" /v /fo:csv /nh
^| findstr /r /c:"%server_title_regex%"
') do taskkill /pid %%a /f
)
goto Server

View File

@ -1 +1,26 @@
start "" "%~dp0iw4x.exe" -dedicated +set sv_lanonly "1" +set net_port "28960" +set fs_game "mods/pvb" +exec pvbvote.cfg +map_rotate
@echo off
::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=pvbvote.cfg
::Name of the server shown in the title of the cmd window. This will NOT bet shown ingame.
set name=IW4x Bot Warfare PvB Vote
::Port used by the server (default: 28960)
set port=28966
::What ip to bind too
set ip=0.0.0.0
::Mod name (default "")
set mod=mods/pvb
::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 IW4x 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%" "%~dp0iw4x.exe" -dedicated +set sv_lanonly "0" +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

View File

@ -0,0 +1,40 @@
@echo off
::Name
set name=IW4x Bot Warfare PvB Vote
::Exe of the server
set server_exe=iw4x.exe
::The regex search for the window name of the server
set server_title_regex=Bot Warfare Players vs bots Mapvote 10x
::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%
::Rate to check if server is hung
set check_rate=300
::Server log location
set log_path=%gamepath%\mods\pvb\logs\pvbvote
set log_file=games_mp.log
title IW4x MP - %name% - Server watchdog
echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates!
echo (%date%) - (%time%) %name% server watchdog start.
::https://superuser.com/questions/699769/batch-file-last-modification-time-with-seconds
dir "%log_path%"\"%log_file%" > nul
for /f "delims=" %%i in ('"forfiles /p "%log_path%" /m "%log_file%" /c "cmd /c echo @ftime" "') do set modif_time_temp=%%i
:Server
set modif_time=%modif_time_temp%
timeout /t %check_rate% /nobreak > nul
dir "%log_path%"\"%log_file%" > nul
for /f "delims=" %%i in ('"forfiles /p "%log_path%" /m "%log_file%" /c "cmd /c echo @ftime" "') do set modif_time_temp=%%i
if "%modif_time_temp%" == "%modif_time%" (
echo "(%date%) - (%time%) WARNING: %name% server hung, killing server..."
::https://stackoverflow.com/questions/26552368/windows-batch-file-taskkill-if-window-title-contains-text
for /f "tokens=2 delims=," %%a in ('
tasklist /fi "imagename eq %server_exe%" /v /fo:csv /nh
^| findstr /r /c:"%server_title_regex%"
') do taskkill /pid %%a /f
)
goto Server

40
z_server_watchdog.bat Normal file
View File

@ -0,0 +1,40 @@
@echo off
::Name
set name=IW4x Bot Warfare Server
::Exe of the server
set server_exe=iw4x.exe
::The regex search for the window name of the server
set server_title_regex=Bot Warfare 24/7 Rust 10x
::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%
::Rate to check if server is hung
set check_rate=300
::Server log location
set log_path=%gamepath%\userraw\logs\server
set log_file=games_mp.log
title IW4x MP - %name% - Server watchdog
echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates!
echo (%date%) - (%time%) %name% server watchdog start.
::https://superuser.com/questions/699769/batch-file-last-modification-time-with-seconds
dir "%log_path%"\"%log_file%" > nul
for /f "delims=" %%i in ('"forfiles /p "%log_path%" /m "%log_file%" /c "cmd /c echo @ftime" "') do set modif_time_temp=%%i
:Server
set modif_time=%modif_time_temp%
timeout /t %check_rate% /nobreak > nul
dir "%log_path%"\"%log_file%" > nul
for /f "delims=" %%i in ('"forfiles /p "%log_path%" /m "%log_file%" /c "cmd /c echo @ftime" "') do set modif_time_temp=%%i
if "%modif_time_temp%" == "%modif_time%" (
echo "(%date%) - (%time%) WARNING: %name% server hung, killing server..."
::https://stackoverflow.com/questions/26552368/windows-batch-file-taskkill-if-window-title-contains-text
for /f "tokens=2 delims=," %%a in ('
tasklist /fi "imagename eq %server_exe%" /v /fo:csv /nh
^| findstr /r /c:"%server_title_regex%"
') do taskkill /pid %%a /f
)
goto Server

View File

@ -1 +0,0 @@
start "" "%~dp0iw4x.exe" -dedicated -console -dump +set sv_lanonly "1" +set fs_game "mods/dev" +set net_port "28960" +set developer "1" +set developer_script "1" +set scr_game_spectatetype "2" scr_war_scorelimit "0" +set thereisacow "1" +set sv_cheats "1" +set logfile "2" +set bots_manage_add "8" +set bots_main_firstIsHost "1" +devmap mp_rust