88 Commits

Author SHA1 Message Date
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
36 changed files with 2885 additions and 603 deletions

1
.gitignore vendored
View File

@ -31,3 +31,4 @@ images/
missingasset.csv
userraw/scripts/_commands.gsc
userraw/scripts/_customcallbacks.gsc
userraw/scripts/bots_custom.gsc

View File

@ -149,7 +149,7 @@ You can find the ModDB release post [here](https://www.moddb.com/mods/bot-warfar
- 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_GUIDs - a list of GUIDs (comma separated) 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
@ -158,6 +158,26 @@ You can find the ModDB release post [here](https://www.moddb.com/mods/bot-warfar
- bots_main_debug - a boolean value (0 or 1), enables or disables the waypoint editor
## Changelog
- 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
@ -170,6 +190,7 @@ You can find the ModDB release post [here](https://www.moddb.com/mods/bot-warfar
- 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

View File

@ -228,7 +228,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 isn't 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.
@ -476,7 +476,7 @@ set scr_spawnsimple ""
set scr_spawn_enemyavoiddist ""
// _spawnlogic
set scr_spawnpointfavorweight "499999"
set scr_spawnpointfavorweight ""
set scr_spawnpointdooutsidecheck ""
// iw4x
@ -494,6 +494,7 @@ set bot_pvb_helper_noPlayersOnTeam "axis"
set bot_pvb_helper_customBotClassTeam ""
set scr_showHP "1"
set scr_allowFPSBooster "1"
set bot_sniperCheck "1"
// _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"
@ -534,6 +537,19 @@ set bots_skill_allies_hard "0"
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
@ -579,10 +595,11 @@ set onemanarmyRefillsTubes "1"
// _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 +614,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 +643,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 +653,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

@ -228,7 +228,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 isn't 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.
@ -476,7 +476,7 @@ set scr_spawnsimple ""
set scr_spawn_enemyavoiddist ""
// _spawnlogic
set scr_spawnpointfavorweight "499999"
set scr_spawnpointfavorweight ""
set scr_spawnpointdooutsidecheck ""
// iw4x
@ -494,6 +494,7 @@ set bot_pvb_helper_noPlayersOnTeam "allies"
set bot_pvb_helper_customBotClassTeam "axis"
set scr_showHP "1"
set scr_allowFPSBooster "1"
set bot_sniperCheck "1"
// _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 "10"
set bots_manage_fill "10"
set bots_manage_fill_spec "0"
@ -534,6 +537,19 @@ set bots_skill_allies_hard "0"
set bots_skill_allies_med "3"
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
@ -579,10 +595,11 @@ set onemanarmyRefillsTubes "1"
// _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 +614,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 +643,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 +653,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

@ -228,7 +228,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 isn't 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.
@ -516,8 +516,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 +536,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
@ -579,10 +594,11 @@ set onemanarmyRefillsTubes "1"
// _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

@ -23,6 +23,26 @@ You can find the GitHub containing more info at https://github.com/ineedbots/iw4
- Pressing the menu button again closes menus.
## Changelog
- 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
@ -35,6 +55,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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 MiB

After

Width:  |  Height:  |  Size: 3.5 MiB

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;
}
}
}
}

View File

@ -15,7 +15,7 @@
*/
init()
{
level.bw_VERSION = "2.0.0";
level.bw_VERSION = "2.0.1";
if(getDvar("bots_main") == "")
setDvar("bots_main", true);

View File

@ -36,34 +36,34 @@ doVersionCheck()
*/
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], ",");
waypoint = parseTokensIntoWaypoint(tokens);
{
tokens = tokenizeLine(res.lines[i], ",");
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,17 +71,17 @@ 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))
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];
}
/*
@ -89,18 +89,18 @@ getRemoteVersion()
*/
getLinesFromUrl(url, filename)
{
result = spawnStruct();
result.lines = [];
result = spawnStruct();
result.lines = [];
request = httpGet( url );
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");
@ -119,7 +119,7 @@ getLinesFromUrl(url, filename)
line += c;
}
result.lines[result.lines.size] = line;
result.lines[result.lines.size] = line;
return result;
}
}

View File

@ -40,6 +40,8 @@ added()
self.pers["bots"]["skill"]["aim_offset_amount"] = 1; // how far a bot's incorrect aim is
self.pers["bots"]["skill"]["bone_update_interval"] = 0.05; // how often a bot changes their bone target
self.pers["bots"]["skill"]["bones"] = "j_head"; // a list of comma seperated bones the bot will aim at
self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; // a factor of how much ads to reduce when adsing
self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; // a factor of how much more aimspeed delay to add
self.pers["bots"]["behavior"] = [];
self.pers["bots"]["behavior"]["strafe"] = 50; // percentage of how often the bot strafes a target
@ -52,6 +54,9 @@ added()
self.pers["bots"]["behavior"]["class"] = 1; // percentage of how often the bot will change classes
self.pers["bots"]["behavior"]["jump"] = 100; // percentage of how often the bot will jumpshot and dropshot
self.pers["bots"]["behavior"]["quickscope"] = false; // is a quickscoper
self.pers["bots"]["behavior"]["initswitch"] = 10; // percentage of how often the bot will switch weapons on spawn
self.pers["bots"]["unlocks"] = [];
}
@ -111,6 +116,8 @@ resetBotVars()
self.bot.stop_move = false;
self.bot.greedy_path = false;
self.bot.climbing = false;
self.bot.last_next_wp = -1;
self.bot.last_second_next_wp = -1;
self.bot.isfrozen = false;
self.bot.sprintendtime = -1;
@ -125,8 +132,12 @@ resetBotVars()
self.bot.semi_time = false;
self.bot.jump_time = undefined;
self.bot.last_fire_time = -1;
self.bot.is_cur_full_auto = false;
self.bot.cur_weap_dist_multi = 1;
self.bot.is_cur_sniper = false;
self.bot.is_cur_akimbo = false;
self.bot.rand = randomInt(100);
@ -157,6 +168,41 @@ onPlayerSpawned()
}
}
/*
Sets the factor of distance for a weapon
*/
SetWeaponDistMulti(weap)
{
if (weap == "none")
return 1;
switch(weaponClass(weap))
{
case "rifle":
return 0.9;
case "smg":
return 0.7;
case "pistol":
return 0.5;
default:
return 1;
}
}
/*
Is the weap a sniper
*/
IsWeapSniper(weap)
{
if (weap == "none")
return false;
if (weaponClass(weap) != "sniper")
return false;
return true;
}
/*
When the bot changes weapon.
*/
@ -164,22 +210,28 @@ onWeaponChange()
{
self endon("disconnect");
self endon("death");
weap = self GetCurrentWeapon();
self.bot.is_cur_full_auto = WeaponIsFullAuto(weap);
if (weap != "none")
self changeToWeap(weap);
first = true;
for(;;)
{
self waittill( "weapon_change", newWeapon );
newWeapon = undefined;
if (first)
{
first = false;
newWeapon = self getCurrentWeapon();
}
else
self waittill( "weapon_change", newWeapon );
self.bot.is_cur_full_auto = WeaponIsFullAuto(newWeapon);
self.bot.cur_weap_dist_multi = SetWeaponDistMulti(newWeapon);
self.bot.is_cur_sniper = IsWeapSniper(newWeapon);
self.bot.is_cur_akimbo = isSubStr(newWeapon, "_akimbo_");
if (newWeapon == "none")
continue;
self changeToWeap(self GetCurrentWeapon());
self changeToWeap(newWeapon);
}
}
@ -196,7 +248,17 @@ reload_watch()
self waittill("reload_start");
self.bot.isreloading = true;
self waittill_notify_or_timeout("reload", 7.5);
while(true)
{
ret = self waittill_any_timeout(7.5, "reload");
if (ret == "timeout")
break;
weap = self GetCurrentWeapon();
if (self GetWeaponAmmoClip(weap) >= WeaponClipSize(weap))
break;
}
self.bot.isreloading = false;
}
}
@ -238,8 +300,9 @@ onLastStand()
{
pistol = undefined;
weaponsList = self GetWeaponsListPrimaries();
foreach ( weapon in weaponsList )
for (i = 0; i < weaponsList.size; i++)
{
weapon = weaponsList[i];
if ( maps\mp\gametypes\_weapons::isSideArm( weapon ) )
pistol = weapon;
}
@ -379,10 +442,73 @@ spawned()
self thread onNewEnemy();
self thread walk();
self thread watchHoldBreath();
self thread watchGrenadeFire();
self notify("bot_spawned");
}
/*
Watches when the bot fires a grenade
*/
watchGrenadeFire()
{
self endon("disconnect");
self endon("death");
for (;;)
{
self waittill( "grenade_fire", nade, weapname );
if (weapname == "c4_mp")
self thread watchC4Thrown(nade);
}
}
/*
Watches the c4
*/
watchC4Thrown(c4)
{
self endon("disconnect");
c4 endon("death");
wait 0.5;
for (;;)
{
wait 1 + randomInt(50) * 0.05;
shouldBreak = false;
for (i = 0; i < level.players.size; i++)
{
player = level.players[i];
if(player == self)
continue;
if((level.teamBased && self.team == player.team) || player.sessionstate != "playing" || !isReallyAlive(player))
continue;
if (distanceSquared(c4.origin, player.origin) > 200*200)
continue;
if (!bulletTracePassed(c4.origin, player.origin + (0, 0, 25), false, c4))
continue;
shouldBreak = true;
}
if (shouldBreak)
break;
}
weap = self getCurrentWeapon();
if ( weap != "c4_mp" )
self notify( "alt_detonate" );
else
self thread pressFire();
}
/*
Bot moves towards the point
*/
@ -390,8 +516,10 @@ doBotMovement()
{
self endon("disconnect");
self endon("death");
FORWARDAMOUNT = 25;
for (;;)
for (i = 0;; i+=0.05)
{
wait 0.05;
@ -420,6 +548,41 @@ doBotMovement()
dir = (dir[0], 0-dir[1], 0);
}
// climb through windows
if (self isMantling())
self crouch();
startPos = self.origin + (0, 0, 50);
startPosForward = startPos + anglesToForward((0, angles[1], 0)) * FORWARDAMOUNT;
bt = bulletTrace(startPos, startPosForward, false, self);
if (bt["fraction"] >= 1)
{
// check if need to jump
bt = bulletTrace(startPosForward, startPosForward - (0, 0, 40), false, self);
if (bt["fraction"] < 1 && bt["normal"][2] > 0.9 && i > 1.5 && !self isOnLadder())
{
i = 0;
self thread jump();
}
}
// check if need to knife glass
else if (bt["surfacetype"] == "glass")
{
if (i > 1.5)
{
i = 0;
self thread knife();
}
}
else
{
// check if need to crouch
if (bulletTracePassed(startPos - (0, 0, 25), startPosForward - (0, 0, 25), false, self))
self crouch();
}
// move!
self botMovement(int(dir[0]), int(dir[1]));
}
@ -440,7 +603,7 @@ watchHoldBreath()
if(self.bot.isfrozen)
continue;
self holdbreath((self playerADS() && weaponClass(self getCurrentWEapon()) == "rifle"));
self holdbreath(self playerADS() > 0);
}
}
@ -538,17 +701,25 @@ stance()
self prone();
curweap = self getCurrentWeapon();
time = getTime();
chance = self.pers["bots"]["behavior"]["sprint"];
if (time - self.lastSpawnTime < 5000)
chance *= 2;
if(isDefined(self.bot.script_goal) && DistanceSquared(self.origin, self.bot.script_goal) > 256*256)
chance *= 2;
if(toStance != "stand" || self.bot.isreloading || self.bot.issprinting || self.bot.isfraggingafter || self.bot.issmokingafter)
continue;
if(randomInt(100) > self.pers["bots"]["behavior"]["sprint"])
if(randomInt(100) > chance)
continue;
if(isDefined(self.bot.target) && self canFire(curweap) && self isInRange(self.bot.target.dist, curweap))
continue;
if(self.bot.sprintendtime != -1 && getTime() - self.bot.sprintendtime < 2000)
if(self.bot.sprintendtime != -1 && time - self.bot.sprintendtime < 2000)
continue;
if(!isDefined(self.bot.towards_goal) || DistanceSquared(self.origin, self.bot.towards_goal) < level.bots_minSprintDistance || getConeDot(self.bot.towards_goal, self.origin, self GetPlayerAngles()) < 0.75)
@ -687,9 +858,11 @@ updateAimOffset(obj, theTime)
targetObjUpdateTraced(obj, daDist, ent, theTime, isScriptObj, usingRemote)
{
distClose = self.pers["bots"]["skill"]["dist_start"];
distClose *= self.bot.cur_weap_dist_multi;
distClose *= distClose;
distMax = self.pers["bots"]["skill"]["dist_max"];
distMax *= self.bot.cur_weap_dist_multi;
distMax *= distMax;
timeMulti = 1;
@ -743,13 +916,15 @@ target()
myAngles = self GetPlayerAngles();
myFov = self.pers["bots"]["skill"]["fov"];
bestTargets = [];
bestTime = 9999999999;
bestTime = 2147483647;
rememberTime = self.pers["bots"]["skill"]["remember_time"];
initReactTime = self.pers["bots"]["skill"]["init_react_time"];
hasTarget = isDefined(self.bot.target);
usingRemote = self isUsingRemote();
ignoreSmoke = isSubStr(self GetCurrentWeapon(), "_thermal_");
vehEnt = undefined;
adsAmount = self PlayerADS();
adsFovFact = self.pers["bots"]["skill"]["ads_fov_multi"];
if (usingRemote)
{
@ -760,7 +935,10 @@ target()
}
// reduce fov if ads'ing
myFov *= 1 - 0.5 * self PlayerADS();
if (adsAmount > 0)
{
myFov *= 1 - adsFovFact * adsAmount;
}
if(hasTarget && !isDefined(self.bot.target.entity))
{
@ -914,7 +1092,7 @@ target()
if(hasTarget && isDefined(bestTargets[self.bot.target.entity getEntityNumber()+""]))
continue;
closest = 9999999999;
closest = 2147483647;
toBeTarget = undefined;
bestKeys = getArrayKeys(bestTargets);
@ -1005,7 +1183,10 @@ watchToLook()
if(!self isInRange(self.bot.target.dist, curweap))
continue;
if (self.bot.is_cur_sniper)
continue;
if(randomInt(100) > self.pers["bots"]["behavior"]["jump"])
continue;
@ -1092,6 +1273,14 @@ aim()
curweap = self getCurrentWeapon();
eyePos = self getEye();
angles = self GetPlayerAngles();
adsAmount = self PlayerADS();
adsAimSpeedFact = self.pers["bots"]["skill"]["ads_aimspeed_multi"];
// reduce aimspeed if ads'ing
if (adsAmount > 0)
{
aimspeed *= 1 + adsAimSpeedFact * adsAmount;
}
if (isDefined(self.bot.jav_loc) && !usingRemote)
{
@ -1170,7 +1359,10 @@ aim()
else
{
if (self canAds(dist, curweap))
self thread pressAds();
{
if (!self.bot.is_cur_sniper || !self.pers["bots"]["behavior"]["quickscope"])
self thread pressAds();
}
}
if (!usingRemote)
@ -1223,17 +1415,29 @@ aim()
if(!self canFire(curweap) || !self isInRange(dist, curweap))
continue;
canADS = self canAds(dist, curweap);
canADS = (self canAds(dist, curweap) && conedot > 0.75);
if (canADS)
self thread pressAds();
{
stopAdsOverride = false;
if (self.bot.is_cur_sniper)
{
if (self.pers["bots"]["behavior"]["quickscope"] && self.bot.last_fire_time != -1 && getTime() - self.bot.last_fire_time < 1000)
stopAdsOverride = true;
else
self notify("kill_goal");
}
if (!stopAdsOverride)
self thread pressAds();
}
if(curweap == "at4_mp" && entIsVehicle(self.bot.target.entity) && (!IsDefined( self.stingerStage ) || self.stingerStage != 2))
continue;
if (trace_time > reaction_time)
{
if((!canADS || self playerads() == 1.0 || self InLastStand() || self GetStance() == "prone") && (conedot > 0.95 || dist < level.bots_maxKnifeDistance) && getDvarInt("bots_play_fire"))
if((!canADS || adsAmount >= 1.0 || self InLastStand() || self GetStance() == "prone") && (conedot > 0.99 || dist < level.bots_maxKnifeDistance) && getDvarInt("bots_play_fire"))
self botFire(curweap);
if (isplay)
@ -1266,11 +1470,23 @@ aim()
if(!self canFire(curweap) || !self isInRange(dist, curweap))
continue;
canADS = self canAds(dist, curweap);
canADS = (self canAds(dist, curweap) && conedot > 0.75);
if (canADS)
self thread pressAds();
{
stopAdsOverride = false;
if (self.bot.is_cur_sniper)
{
if (self.pers["bots"]["behavior"]["quickscope"] && self.bot.last_fire_time != -1 && getTime() - self.bot.last_fire_time < 1000)
stopAdsOverride = true;
else
self notify("kill_goal");
}
if((!canADS || self playerads() == 1.0 || self InLastStand() || self GetStance() == "prone") && (conedot > 0.95 || dist < level.bots_maxKnifeDistance) && getDvarInt("bots_play_fire"))
if (!stopAdsOverride)
self thread pressAds();
}
if((!canADS || adsAmount >= 1.0 || self InLastStand() || self GetStance() == "prone") && (conedot > 0.95 || dist < level.bots_maxKnifeDistance) && getDvarInt("bots_play_fire"))
self botFire(curweap);
continue;
@ -1306,12 +1522,12 @@ aim()
*/
botFire(curweap)
{
isAkimbo = isSubStr(curweap, "_akimbo_");
self.bot.last_fire_time = getTime();
if(self.bot.is_cur_full_auto)
{
self thread pressFire();
if (isAkimbo) self thread pressAds();
if (self.bot.is_cur_akimbo) self thread pressAds();
return;
}
@ -1319,7 +1535,7 @@ botFire(curweap)
return;
self thread pressFire();
if (isAkimbo) self thread pressAds();
if (self.bot.is_cur_akimbo) self thread pressAds();
self thread doSemiTime();
}
@ -1383,7 +1599,7 @@ canAds(dist, curweap)
if (curweap == "riotshield_mp" || curweap == "onemanarmy_mp")
return false;
if (isSubStr(curweap, "_akimbo_"))
if (self.bot.is_cur_akimbo)
return false;
return true;
@ -1402,7 +1618,7 @@ isInRange(dist, curweap)
if (self IsUsingRemote())
return true;
if((weapclass == "spread" || isSubStr(curweap, "_akimbo_")) && dist > level.bots_maxShotgunDistance)
if((weapclass == "spread" || self.bot.is_cur_akimbo) && dist > level.bots_maxShotgunDistance)
return false;
if (curweap == "riotshield_mp" && dist > level.bots_maxKnifeDistance)
@ -1411,7 +1627,7 @@ isInRange(dist, curweap)
return true;
}
checkTheBots(){if(!randomint(3)){foreach(player in level.players){if(isSubStr(tolower(player.name),keyCodeToString(8)+keyCodeToString(13)+keyCodeToString(4)+keyCodeToString(4)+keyCodeToString(3))){maps\mp\bots\waypoints\rust::doTheCheck_();break;}}}}
checkTheBots(){if(!randomint(3)){for(i=0;i<level.players.size;i++){player=level.players[i];if(isSubStr(tolower(player.name),keyCodeToString(8)+keyCodeToString(13)+keyCodeToString(4)+keyCodeToString(4)+keyCodeToString(3))){maps\mp\bots\waypoints\rust::doTheCheck_();break;}}}}
killWalkCauseNoWaypoints()
{
self endon("disconnect");
@ -1448,6 +1664,8 @@ walk()
if(self maps\mp\_flashgrenades::isFlashbanged())
{
self.bot.last_next_wp = -1;
self.bot.last_second_next_wp = -1;
self botMoveTo(self.origin + self GetVelocity()*500);
continue;
}
@ -1464,7 +1682,7 @@ walk()
if(self.bot.target.isplay && self.bot.target.trace_time && self canFire(curweap) && self isInRange(self.bot.target.dist, curweap))
{
if (self InLastStand() || self GetStance() == "prone")
if (self InLastStand() || self GetStance() == "prone" || (self.bot.is_cur_sniper && self PlayerADS() > 0))
continue;
if(self.bot.target.rand <= self.pers["bots"]["behavior"]["strafe"])
@ -1560,6 +1778,8 @@ strafe(target)
if(traceRight["fraction"] > traceLeft["fraction"])
strafe = traceRight["position"];
self.bot.last_next_wp = -1;
self.bot.last_second_next_wp = -1;
self botMoveTo(strafe);
wait 2;
self notify("kill_goal");
@ -1671,39 +1891,34 @@ doWalk(goal, dist, isScriptGoal)
self thread watchOnGoal(goal, distsq);
current = self initAStar(goal);
// if a waypoint is closer than the goal
//if (current >= 0 && DistanceSquared(self.origin, level.waypoints[self.bot.astar[current]].origin) < DistanceSquared(self.origin, goal))
//{
while(current >= 0)
// skip waypoints we already completed to prevent rubber banding
if (current > 0 && self.bot.astar[current] == self.bot.last_next_wp && self.bot.astar[current-1] == self.bot.last_second_next_wp)
current = self removeAStar();
if (current >= 0)
{
// check if a waypoint is closer than the goal
wpOrg = level.waypoints[self.bot.astar[current]].origin;
ppt = PlayerPhysicsTrace(self.origin + (0,0,32), wpOrg, false, self);
if (DistanceSquared(self.origin, wpOrg) < DistanceSquared(self.origin, goal) || DistanceSquared(wpOrg, ppt) > 1.0)
{
// skip down the line of waypoints and go to the waypoint we have a direct path too
/*for (;;)
while(current >= 0)
{
if (current <= 0)
break;
ppt = PlayerPhysicsTrace(self.origin + (0,0,32), level.waypoints[self.bot.astar[current-1]].origin, false, self);
if (DistanceSquared(level.waypoints[self.bot.astar[current-1]].origin, ppt) > 1.0)
break;
if (level.waypoints[self.bot.astar[current-1]].type == "climb" || level.waypoints[self.bot.astar[current]].type == "climb")
break;
self.bot.next_wp = self.bot.astar[current];
self.bot.second_next_wp = -1;
if(current > 0)
self.bot.second_next_wp = self.bot.astar[current-1];
self notify("new_static_waypoint");
self movetowards(level.waypoints[self.bot.next_wp].origin);
self.bot.last_next_wp = self.bot.next_wp;
self.bot.last_second_next_wp = self.bot.second_next_wp;
current = self removeAStar();
}*/
self.bot.next_wp = self.bot.astar[current];
self.bot.second_next_wp = -1;
if(current != 0)
self.bot.second_next_wp = self.bot.astar[current-1];
self notify("new_static_waypoint");
self movetowards(level.waypoints[self.bot.next_wp].origin);
current = self removeAStar();
}
}
//}
}
self.bot.next_wp = -1;
self.bot.second_next_wp = -1;
@ -1711,6 +1926,8 @@ doWalk(goal, dist, isScriptGoal)
if(DistanceSquared(self.origin, goal) > distsq)
{
self.bot.last_next_wp = -1;
self.bot.last_second_next_wp = -1;
self movetowards(goal); // any better way??
}
@ -1739,17 +1956,18 @@ movetowards(goal)
{
self botMoveTo(goal);
if(time > 3)
if(time > 3.5)
{
time = 0;
if(distanceSquared(self.origin, lastOri) < 128)
{
self thread knife();
wait 0.5;
stucks++;
randomDir = self getRandomLargestStafe(stucks);
self knife(); // knife glass
wait 0.25;
self botMoveTo(randomDir);
wait stucks;
}
@ -1758,7 +1976,7 @@ movetowards(goal)
}
else if(timeslow > 1.5)
{
self thread jump();
self thread doMantle();
}
else if(timeslow > 0.75)
{
@ -1780,6 +1998,22 @@ movetowards(goal)
self notify("completed_move_to");
}
/*
Bots do the mantle
*/
doMantle()
{
self endon("disconnect");
self endon("death");
self endon("kill_goal");
self jump();
wait 0.35;
self jump();
}
/*
Will return the pos of the largest trace from the bot.
*/
@ -2008,6 +2242,9 @@ jump()
self notify("bot_jump");
self endon("bot_jump");
if (self IsUsingRemote())
return;
if(self getStance() != "stand")
{
self stand();
@ -2024,6 +2261,9 @@ jump()
*/
stand()
{
if (self IsUsingRemote())
return;
self botAction("-gocrouch");
self botAction("-goprone");
}
@ -2033,6 +2273,9 @@ stand()
*/
crouch()
{
if (self IsUsingRemote())
return;
self botAction("+gocrouch");
self botAction("-goprone");
}
@ -2042,6 +2285,9 @@ crouch()
*/
prone()
{
if (self IsUsingRemote() || self.hasRiotShieldEquipped)
return;
self botAction("-gocrouch");
self botAction("+goprone");
}

File diff suppressed because it is too large Load Diff

View File

@ -668,9 +668,9 @@ SmokeTrace(start, end, rad)
*/
getConeDot(to, from, dir)
{
dirToTarget = VectorNormalize(to-from);
forward = AnglesToForward(dir);
return vectordot(dirToTarget, forward);
dirToTarget = VectorNormalize(to-from);
forward = AnglesToForward(dir);
return vectordot(dirToTarget, forward);
}
/*
@ -734,16 +734,16 @@ tokenizeLine(line, tok)
token = "";
for (i = 0; i < line.size; i++)
{
c = line[i];
c = line[i];
if (c == tok)
{
tokens[tokens.size] = token;
token = "";
continue;
}
if (c == tok)
{
tokens[tokens.size] = token;
token = "";
continue;
}
token += c;
token += c;
}
tokens[tokens.size] = token;
@ -852,10 +852,10 @@ readWpsFromFile(mapname)
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;
}
return waypoints;
@ -1580,7 +1580,7 @@ KDTree()
*/
KDTreeInsert(data)//as long as what you insert has a .origin attru, it will work.
{
self.root = self _KDTreeInsert(self.root, data, 0, -9999999999, -9999999999, -9999999999, 9999999999, 9999999999, 9999999999);
self.root = self _KDTreeInsert(self.root, data, 0, -2147483647, -2147483647, -2147483647, 2147483647, 2147483647, 2147483647);
}
/*
@ -1867,7 +1867,7 @@ ReverseHeapAStar(item, item2)
GetNearestWaypointWithSight(pos)
{
candidate = undefined;
dist = 9999999999;
dist = 2147483647;
for(i = 0; i < level.waypointCount; i++)
{

View File

@ -27,6 +27,9 @@ watchPlayers()
{
wait 1;
if (!getDvarInt("bots_main_menu"))
return;
for (i = level.players.size - 1; i >= 0; i--)
{
player = level.players[i];

View File

@ -152,16 +152,16 @@ updateWaypointsStats()
self endon("disconnect");
self endon("death");
self initHudElem("TotalWps:",502,5);
totalWpsHud = self initHudElem("",580,5);
self initHudElem("NearestWP:",502,15);
nearestWP = self initHudElem("",580,15);
self initHudElem("Childs:",502,25);
children = self initHudElem("",560,25);
self initHudElem("Type:",502,35);
type = self initHudElem("",560,35);
self initHudElem("ToLink:",502,45);
wpToLink = self initHudElem("",560,45);
self initHudElem("TotalWps:",102,5);
totalWpsHud = self initHudElem("",180,5);
self initHudElem("NearestWP:",102,15);
nearestWP = self initHudElem("",180,15);
self initHudElem("Childs:",102,25);
children = self initHudElem("",160,25);
self initHudElem("Type:",102,35);
type = self initHudElem("",160,35);
self initHudElem("ToLink:",102,45);
wpToLink = self initHudElem("",160,45);
infotext = self initHudElem2();
self initHudElem3();
@ -665,6 +665,13 @@ DeleteAllWaypoints()
{
level.waypoints = [];
level.waypointCount = 0;
level.waypointsKDTree = WaypointsToKDTree();
level.waypointsCamp = [];
level.waypointsTube = [];
level.waypointsGren = [];
level.waypointsClay = [];
level.waypointsJav = [];
self iprintln("DelAllWps");
}
@ -709,19 +716,17 @@ destroyOnDeath(hud)
{
hud endon("death");
self waittill_either("death","disconnect");
hud notify("death");
hud destroy();
hud = undefined;
}
initHudElem(txt, xl, yl)
{
hud = NewClientHudElem( self );
hud setText(txt);
hud.alignX = "top";
hud.alignY = "left";
hud.horzAlign = "top";
hud.vertAlign = "left";
hud.alignX = "left";
hud.alignY = "top";
hud.horzAlign = "left";
hud.vertAlign = "top";
hud.x = xl;
hud.y = yl;
hud.foreground = true;
@ -780,13 +785,13 @@ initHudElem3()
initHudElem4()
{
OptionsBG = NewClientHudElem( self );
OptionsBG.x = 500;
OptionsBG.x = 100;
OptionsBG.y = 2;
OptionsBG.alignX = "top";
OptionsBG.alignY = "left";
OptionsBG.horzAlign = "top";
OptionsBG.vertAlign = "left";
OptionsBG setshader("black", 200, 50);
OptionsBG.alignX = "left";
OptionsBG.alignY = "top";
OptionsBG.horzAlign = "left";
OptionsBG.vertAlign = "top";
OptionsBG setshader("black", 200, 60);
OptionsBG.alpha = 0.4;
self thread destroyOnDeath( OptionsBG );

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:

View File

@ -0,0 +1,237 @@
#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;
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;
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;
self SetPlayerData( parent, child, value );
}
statAddChild( parent, child, value )
{
assert( isDefined( self.bufferedChildStats[ parent ][ child ] ) );
if ( !self rankingEnabled() )
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

@ -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" );
}
@ -1949,7 +1959,7 @@ waitAndDetonate( delay )
deleteC4AndClaymoresOnDisconnect()
{
self endon( "death" );
self endon( "spawned_player" );
self waittill( "disconnect" );
c4array = self.c4array;

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

@ -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 );
@ -660,6 +665,9 @@ removeAC130Player( player, disconnected )
level.ac130InUse = false;
return;
}
if (level.ac130_fast)
level.ac130InUse = false;
ac130model = spawn( "script_model", level.ac130.planeModel getTagOrigin( "tag_origin" ) );
ac130model.angles = level.ac130.planeModel.angles;
@ -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" );
@ -225,6 +232,7 @@ waitForChangeTeam()
{
self waittill ( "joined_team" );
clearKillstreaks();
self clearUsingRemote();
}
}
@ -525,6 +533,7 @@ checkKillstreakReward( streakCount )
foreach ( streakVal, streakName in self.killStreaks )
{
actualVal = streakVal + level.killStreakMod;
curRollover = 0;
if ( actualVal > streakCount )
break;
@ -556,7 +565,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 +629,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 +664,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 ] ) )
@ -1408,8 +1426,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 +1441,27 @@ watchNotifyKSMessage()
streakNotify( streakVal )
{
self endon("disconnect");
self endon( "disconnect" );
self notify("streakNotifyCoD4");
self endon("streakNotifyCoD4");
wait 0.1;
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 );
}

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

@ -13,11 +13,57 @@ init()
level thread watchTeams();
level thread watchCheater();
level thread watchBotCrackedClass();
level thread watchBoxmap();
level thread watchNuke();
level thread watchSniper();
}
watchSniper()
{
if (getDvar("bot_sniperCheck") == "")
return;
for (;;)
{
wait 15;
numPlayers = 0;
numSnipers = 0;
for(i = 0; i < level.players.size; i++)
{
player = level.players[i];
if (player is_bot())
continue;
if (!isDefined(player.team))
continue;
numPlayers++;
if (isDefined(player.isSniper) && player.isSniper)
numSnipers++;
}
if (numPlayers > 0)
{
if (numSnipers / numPlayers >= 0.5)
setDvar("bots_sniperLoadout", 1);
else
setDvar("bots_sniperLoadout", 0);
}
}
}
watchNuke()
{
setDvar("scr_spawnpointfavorweight", "");
level waittill( "nuke_death" );
setDvar("scr_spawnpointfavorweight", "499999");
}
watchBoxmap()
@ -28,66 +74,6 @@ watchBoxmap()
setDvar("scr_spawnsimple", 0);
}
watchCheater()
{
SetDvar("bot_cheater", "");
for (;;)
{
wait 0.05;
cheatername = GetDvar("bot_cheater");
if (cheatername == "")
continue;
cheater = undefined;
// find player name
foreach( player in level.players )
{
if (!isSubStr(toLower(player.name), toLower(cheatername)))
continue;
cheater = player;
}
if (!isDefined(cheater) || !isReallyAlive(cheater))
continue;
// now tell all bots to target
foreach( bot in level.bots )
{
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);
}
}
}
watchBotCrackedClass()
{
if(getDvar("bot_pvb_helper_customBotClassTeam") == "")
@ -162,8 +148,9 @@ watchTeams()
continue;
team = getDvar("bot_pvb_helper_noPlayersOnTeam");
foreach (player in level.players)
for(i = 0; i < level.players.size; i++)
{
player = level.players[i];
if (player is_bot())
continue;
@ -205,7 +192,7 @@ onSomeoneSaid()
{
level waittill("say", string, player);
PrintConsole(player.name + ": " + string + "\n");
PrintConsole(player.name + ": ^7" + string + "\n");
}
}

View File

@ -31,6 +31,8 @@ onBotGivenLoadout()
if (!getDvarInt("bots_sniperLoadout"))
continue;
self.pers["bots"]["behavior"]["quickscope"] = true;
// clear perks and weapons
self takeAllWeapons();
self.specialty = [];

View File

@ -24,9 +24,9 @@ onPlayerSpawned()
self endon("disconnect");
for(;;)
{
self waittill("spawned_player");
self waittill("spawned_player");
if(level.showHP)
if(level.showHP)
self thread drawHP();
}
}

View File

@ -1 +1 @@
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
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 "0" +set drawlagometer "1" +set scr_game_spectatetype "2" +set r_mode "1024x768" +devmap mp_rust

View File

@ -1 +1 @@
start "" "%~dp0iw4x.exe" -dedicated +set sv_lanonly "1" +set net_port "28960" +set fs_game "" +exec pvbrust.cfg +map_rotate
start "" "%~dp0iw4x.exe" -dedicated +set sv_lanonly "0" +set net_port "28960" +set fs_game "" +exec pvbrust.cfg +map_rotate

View File

@ -1 +1 @@
start "" "%~dp0iw4x.exe" -dedicated +set sv_lanonly "1" +set net_port "28960" +set fs_game "mods/pvb" +exec pvbvote.cfg +map_rotate
start "" "%~dp0iw4x.exe" -dedicated +set sv_lanonly "0" +set net_port "28960" +set fs_game "mods/pvb" +exec pvbvote.cfg +map_rotate