mirror of
https://github.com/ineedbots/iw4_bot_warfare.git
synced 2025-07-04 18:21:52 +00:00
Compare commits
88 Commits
Author | SHA1 | Date | |
---|---|---|---|
1cd164e5ea | |||
c31f0d2bfa | |||
22b5c75197 | |||
23dbbb9439 | |||
20bc803498 | |||
888a0225e6 | |||
e438ea2f02 | |||
80a00b019b | |||
06990751c0 | |||
6bd638ab00 | |||
75ed617320 | |||
fc1e8f48d2 | |||
8bde752124 | |||
e0dfadbe48 | |||
1613497335 | |||
4a13410976 | |||
f94a845a2f | |||
bc6595eef5 | |||
60d3fa7c33 | |||
66a66212ca | |||
bc888f95cf | |||
3204c22f16 | |||
52e9373610 | |||
dbe50d85e2 | |||
c00dbd64bf | |||
80693d15b1 | |||
b2cb93ce7a | |||
003f4faaac | |||
37fd34fb3f | |||
c25ce6e06f | |||
ff670e2a43 | |||
7497b656cb | |||
b9c63488ae | |||
037de678a5 | |||
17f15bdafd | |||
36d4809796 | |||
c98583bd62 | |||
5a4bffdbaa | |||
d7f877e40f | |||
cdbf9ef9c1 | |||
18eabe21fc | |||
6a53dd9d20 | |||
7e09fc17c9 | |||
41648436d7 | |||
96216a77b4 | |||
b84483abec | |||
0604980d8e | |||
440a3c561b | |||
6e841d9732 | |||
87e83f12d9 | |||
7b3c27f723 | |||
e2e40ea3d1 | |||
43f88e9fb1 | |||
c417ddba39 | |||
e7fef2e080 | |||
578ae5cd2b | |||
f102962ffa | |||
28ca878a9f | |||
527f63b771 | |||
49c98fe467 | |||
296a5c6e63 | |||
06587f67fe | |||
dd87fe8c25 | |||
2b5c2ff10d | |||
20dc9c9bed | |||
2c015fb9e7 | |||
7399aea5ab | |||
cda07629ca | |||
1ae35a14fd | |||
33fb299c27 | |||
779a83a83a | |||
89bb00de88 | |||
60ca814764 | |||
919c60d024 | |||
7092b5a40c | |||
1c1eac6b1d | |||
23621698c9 | |||
48d8348a09 | |||
6c28abdbaa | |||
433b9e787f | |||
abb05306f5 | |||
9ee21cb5e5 | |||
226254e501 | |||
0d589ec89e | |||
dfe68e0edb | |||
4f290ec518 | |||
dd0e1bbb5d | |||
fc9b03d9ac |
1
.gitignore
vendored
1
.gitignore
vendored
@ -31,3 +31,4 @@ images/
|
||||
missingasset.csv
|
||||
userraw/scripts/_commands.gsc
|
||||
userraw/scripts/_customcallbacks.gsc
|
||||
userraw/scripts/bots_custom.gsc
|
||||
|
23
README.md
23
README.md
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
Binary file not shown.
@ -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
|
||||
|
BIN
out/ss.png
BIN
out/ss.png
Binary file not shown.
Before Width: | Height: | Size: 2.9 MiB After Width: | Height: | Size: 3.5 MiB |
360
userraw/maps/mp/_stinger.gsc
Normal file
360
userraw/maps/mp/_stinger.gsc
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
@ -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++)
|
||||
{
|
||||
|
@ -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];
|
||||
|
@ -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 );
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
237
userraw/maps/mp/gametypes/_persistence.gsc
Normal file
237
userraw/maps/mp/gametypes/_persistence.gsc
Normal 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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
909
userraw/maps/mp/gametypes/dd.gsc
Normal file
909
userraw/maps/mp/gametypes/dd.gsc
Normal 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 );
|
||||
}
|
@ -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 );
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
@ -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 ) )
|
||||
|
@ -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)
|
||||
|
@ -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
18
userraw/mp/classtable.csv
Normal 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
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,8 @@ onBotGivenLoadout()
|
||||
if (!getDvarInt("bots_sniperLoadout"))
|
||||
continue;
|
||||
|
||||
self.pers["bots"]["behavior"]["quickscope"] = true;
|
||||
|
||||
// clear perks and weapons
|
||||
self takeAllWeapons();
|
||||
self.specialty = [];
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
Submodule userraw/waypoints updated: c2eb59adf5...9770210fc2
@ -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
|
@ -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
|
@ -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
|
Reference in New Issue
Block a user