mirror of
https://github.com/JezuzLizard/Recompilable-gscs-for-BO2-zombies-and-multiplayer.git
synced 2025-06-10 18:57:58 -05:00
Reorganized the scripts so its easier to search thru.
This commit is contained in:
@ -0,0 +1,12 @@
|
||||
|
||||
main()
|
||||
{
|
||||
self setmodel( "german_shepherd_vest" );
|
||||
self.voice = "american";
|
||||
self.skeleton = "base";
|
||||
}
|
||||
|
||||
precache()
|
||||
{
|
||||
precachemodel( "german_shepherd_vest" );
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
|
||||
main()
|
||||
{
|
||||
self setmodel( "german_shepherd_vest_black" );
|
||||
self.voice = "american";
|
||||
self.skeleton = "base";
|
||||
}
|
||||
|
||||
precache()
|
||||
{
|
||||
precachemodel( "german_shepherd_vest_black" );
|
||||
}
|
56
Multiplayer Core/common_mp/maps/mp/_serverfaceanim_mp.gsc
Normal file
56
Multiplayer Core/common_mp/maps/mp/_serverfaceanim_mp.gsc
Normal file
@ -0,0 +1,56 @@
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( "connecting", player );
|
||||
player thread onplayerspawned();
|
||||
}
|
||||
}
|
||||
|
||||
onplayerspawned()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
self thread init_serverfaceanim();
|
||||
}
|
||||
}
|
||||
|
||||
init_serverfaceanim()
|
||||
{
|
||||
self.do_face_anims = 1;
|
||||
if ( !isDefined( level.face_event_handler ) )
|
||||
{
|
||||
level.face_event_handler = spawnstruct();
|
||||
level.face_event_handler.events = [];
|
||||
level.face_event_handler.events[ "death" ] = "face_death";
|
||||
level.face_event_handler.events[ "grenade danger" ] = "face_alert";
|
||||
level.face_event_handler.events[ "bulletwhizby" ] = "face_alert";
|
||||
level.face_event_handler.events[ "projectile_impact" ] = "face_alert";
|
||||
level.face_event_handler.events[ "explode" ] = "face_alert";
|
||||
level.face_event_handler.events[ "alert" ] = "face_alert";
|
||||
level.face_event_handler.events[ "shoot" ] = "face_shoot_single";
|
||||
level.face_event_handler.events[ "melee" ] = "face_melee";
|
||||
level.face_event_handler.events[ "damage" ] = "face_pain";
|
||||
level thread wait_for_face_event();
|
||||
}
|
||||
}
|
||||
|
||||
wait_for_face_event()
|
||||
{
|
||||
while ( 1 )
|
||||
{
|
||||
level waittill( "face", face_notify, ent );
|
||||
if ( isDefined( ent ) && isDefined( ent.do_face_anims ) && ent.do_face_anims )
|
||||
{
|
||||
if ( isDefined( level.face_event_handler.events[ face_notify ] ) )
|
||||
{
|
||||
ent sendfaceevent( level.face_event_handler.events[ face_notify ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
#include maps/mp/animscripts/utility;
|
||||
#include maps/mp/animscripts/shared;
|
||||
#include common_scripts/utility;
|
||||
|
||||
main()
|
||||
{
|
||||
debug_anim_print( "dog_combat::main() " );
|
||||
self endon( "killanimscript" );
|
||||
self setaimanimweights( 0, 0 );
|
||||
/#
|
||||
if ( !debug_allow_combat() )
|
||||
{
|
||||
combatidle();
|
||||
return;
|
||||
#/
|
||||
}
|
||||
if ( isDefined( level.hostmigrationtimer ) )
|
||||
{
|
||||
combatidle();
|
||||
return;
|
||||
}
|
||||
/#
|
||||
assert( isDefined( self.enemy ) );
|
||||
#/
|
||||
if ( !isalive( self.enemy ) )
|
||||
{
|
||||
combatidle();
|
||||
return;
|
||||
}
|
||||
if ( isplayer( self.enemy ) )
|
||||
{
|
||||
self meleebiteattackplayer( self.enemy );
|
||||
}
|
||||
}
|
||||
|
||||
combatidle()
|
||||
{
|
||||
self set_orient_mode( "face enemy" );
|
||||
self animmode( "zonly_physics", 0 );
|
||||
idleanims = [];
|
||||
idleanims[ 0 ] = "combat_attackidle";
|
||||
idleanims[ 1 ] = "combat_attackidle_bark";
|
||||
idleanims[ 2 ] = "combat_attackidle_growl";
|
||||
idleanim = random( idleanims );
|
||||
debug_anim_print( "dog_combat::combatIdle() - Setting " + idleanim );
|
||||
self setanimstate( idleanim );
|
||||
self maps/mp/animscripts/shared::donotetracks( "done" );
|
||||
debug_anim_print( "dog_combat::combatIdle() - " + idleanim + " notify done." );
|
||||
}
|
||||
|
||||
meleebiteattackplayer( player )
|
||||
{
|
||||
self set_orient_mode( "face enemy" );
|
||||
self animmode( "gravity", 0 );
|
||||
self.safetochangescript = 0;
|
||||
if ( use_low_attack() )
|
||||
{
|
||||
self animmode( "angle deltas", 0 );
|
||||
self setanimstate( "combat_attack_player_close_range" );
|
||||
self maps/mp/animscripts/shared::donotetracksfortime( 1,4, "done" );
|
||||
self animmode( "gravity", 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
attack_time = 1,2 + randomfloat( 0,4 );
|
||||
debug_anim_print( "dog_combat::meleeBiteAttackPlayer() - Setting combat_run_attack" );
|
||||
self setanimstate( "combat_attack_run" );
|
||||
self maps/mp/animscripts/shared::donotetracksfortime( attack_time, "done", ::handlemeleebiteattacknotetracks, player );
|
||||
debug_anim_print( "dog_combat::meleeBiteAttackPlayer() - combat_attack_run notify done." );
|
||||
}
|
||||
self.safetochangescript = 1;
|
||||
self animmode( "none", 0 );
|
||||
}
|
||||
|
||||
handlemeleebiteattacknotetracks( note, player )
|
||||
{
|
||||
if ( note == "dog_melee" )
|
||||
{
|
||||
self melee( anglesToForward( self.angles ) );
|
||||
}
|
||||
}
|
||||
|
||||
use_low_attack( player )
|
||||
{
|
||||
return 0;
|
||||
}
|
30
Multiplayer Core/common_mp/maps/mp/animscripts/dog_death.gsc
Normal file
30
Multiplayer Core/common_mp/maps/mp/animscripts/dog_death.gsc
Normal file
@ -0,0 +1,30 @@
|
||||
#include maps/mp/animscripts/shared;
|
||||
#include maps/mp/animscripts/utility;
|
||||
|
||||
main()
|
||||
{
|
||||
debug_anim_print( "dog_death::main()" );
|
||||
self setaimanimweights( 0, 0 );
|
||||
self endon( "killanimscript" );
|
||||
if ( isDefined( self.a.nodeath ) )
|
||||
{
|
||||
/#
|
||||
assert( self.a.nodeath, "Nodeath needs to be set to true or undefined." );
|
||||
#/
|
||||
wait 3;
|
||||
return;
|
||||
}
|
||||
self unlink();
|
||||
if ( isDefined( self.enemy ) && isDefined( self.enemy.syncedmeleetarget ) && self.enemy.syncedmeleetarget == self )
|
||||
{
|
||||
self.enemy.syncedmeleetarget = undefined;
|
||||
}
|
||||
death_anim = "death_" + getanimdirection( self.damageyaw );
|
||||
/#
|
||||
println( death_anim );
|
||||
#/
|
||||
self animmode( "gravity", 0 );
|
||||
debug_anim_print( "dog_death::main() - Setting " + death_anim );
|
||||
self setanimstate( death_anim );
|
||||
self maps/mp/animscripts/shared::donotetracks( "done" );
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
#include maps/mp/animscripts/shared;
|
||||
|
||||
main()
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self endon( "stop_flashbang_effect" );
|
||||
wait randomfloatrange( 0, 0,4 );
|
||||
duration = self startflashbanged() * 0,001;
|
||||
self setanimstate( "flashed" );
|
||||
self maps/mp/animscripts/shared::donotetracks( "done" );
|
||||
self setflashbanged( 0 );
|
||||
self.flashed = 0;
|
||||
self notify( "stop_flashbang_effect" );
|
||||
}
|
||||
|
||||
startflashbanged()
|
||||
{
|
||||
if ( isDefined( self.flashduration ) )
|
||||
{
|
||||
duration = self.flashduration;
|
||||
}
|
||||
else
|
||||
{
|
||||
duration = self getflashbangedstrength() * 1000;
|
||||
}
|
||||
self.flashendtime = getTime() + duration;
|
||||
self notify( "flashed" );
|
||||
return duration;
|
||||
}
|
78
Multiplayer Core/common_mp/maps/mp/animscripts/dog_init.gsc
Normal file
78
Multiplayer Core/common_mp/maps/mp/animscripts/dog_init.gsc
Normal file
@ -0,0 +1,78 @@
|
||||
#include maps/mp/animscripts/dog_move;
|
||||
#include maps/mp/animscripts/utility;
|
||||
#include maps/mp/animscripts/shared;
|
||||
|
||||
main()
|
||||
{
|
||||
level.dog_debug_orient = 0;
|
||||
level.dog_debug_anims = 0;
|
||||
level.dog_debug_anims_ent = 0;
|
||||
level.dog_debug_turns = 0;
|
||||
debug_anim_print( "dog_init::main() " );
|
||||
maps/mp/animscripts/dog_move::setup_sound_variables();
|
||||
anim_get_dvar_int( "debug_dog_sound", "0" );
|
||||
anim_get_dvar_int( "debug_dog_notetracks", "0" );
|
||||
anim_get_dvar_int( "dog_force_walk", 0 );
|
||||
anim_get_dvar_int( "dog_force_run", 0 );
|
||||
self.ignoresuppression = 1;
|
||||
self.chatinitialized = 0;
|
||||
self.nododgemove = 1;
|
||||
level.dogattackplayerdist = 50;
|
||||
level.dogattackplayercloserangedist = 50;
|
||||
level.dogrunturnspeed = 20;
|
||||
level.dogrunpainspeed = 20;
|
||||
self.meleeattackdist = 0;
|
||||
self thread setmeleeattackdist();
|
||||
self.a = spawnstruct();
|
||||
self.a.pose = "stand";
|
||||
self.a.nextstandinghitdying = 0;
|
||||
self.a.movement = "run";
|
||||
set_anim_playback_rate();
|
||||
self.suppressionthreshold = 1;
|
||||
self.disablearrivals = 0;
|
||||
level.dogstoppingdistsq = 3416,82;
|
||||
self.stopanimdistsq = level.dogstoppingdistsq;
|
||||
self.pathenemyfightdist = 512;
|
||||
self settalktospecies( "dog" );
|
||||
level.lastdogmeleeplayertime = 0;
|
||||
level.dogmeleeplayercounter = 0;
|
||||
if ( !isDefined( level.dog_hits_before_kill ) )
|
||||
{
|
||||
level.dog_hits_before_kill = 1;
|
||||
}
|
||||
}
|
||||
|
||||
set_anim_playback_rate()
|
||||
{
|
||||
self.animplaybackrate = 0,9 + randomfloat( 0,2 );
|
||||
self.moveplaybackrate = 1;
|
||||
}
|
||||
|
||||
setmeleeattackdist()
|
||||
{
|
||||
self endon( "death" );
|
||||
while ( 1 )
|
||||
{
|
||||
if ( isDefined( self.enemy ) )
|
||||
{
|
||||
if ( isplayer( self.enemy ) )
|
||||
{
|
||||
stance = self.enemy getstance();
|
||||
if ( stance == "prone" )
|
||||
{
|
||||
self.meleeattackdist = level.dogattackplayercloserangedist;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.meleeattackdist = level.dogattackplayerdist;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.meleeattackdist = level.dogattackplayerdist;
|
||||
}
|
||||
}
|
||||
wait 1;
|
||||
}
|
||||
}
|
13
Multiplayer Core/common_mp/maps/mp/animscripts/dog_jump.gsc
Normal file
13
Multiplayer Core/common_mp/maps/mp/animscripts/dog_jump.gsc
Normal file
@ -0,0 +1,13 @@
|
||||
#include maps/mp/animscripts/shared;
|
||||
#include maps/mp/animscripts/utility;
|
||||
|
||||
main()
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
debug_anim_print( "dog_jump::main()" );
|
||||
self setaimanimweights( 0, 0 );
|
||||
self.safetochangescript = 0;
|
||||
self setanimstate( "traverse_wallhop" );
|
||||
maps/mp/animscripts/shared::donotetracks( "done" );
|
||||
self.safetochangescript = 1;
|
||||
}
|
185
Multiplayer Core/common_mp/maps/mp/animscripts/dog_move.gsc
Normal file
185
Multiplayer Core/common_mp/maps/mp/animscripts/dog_move.gsc
Normal file
@ -0,0 +1,185 @@
|
||||
#include maps/mp/animscripts/dog_stop;
|
||||
#include maps/mp/animscripts/shared;
|
||||
#include maps/mp/animscripts/utility;
|
||||
|
||||
setup_sound_variables()
|
||||
{
|
||||
level.dog_sounds[ "far" ] = spawnstruct();
|
||||
level.dog_sounds[ "close" ] = spawnstruct();
|
||||
level.dog_sounds[ "close" ].minrange = 0;
|
||||
level.dog_sounds[ "close" ].maxrange = 500;
|
||||
level.dog_sounds[ "close" ].sound = "aml_dog_bark_close";
|
||||
level.dog_sounds[ "close" ].soundlengthplaceholder = 0,2;
|
||||
level.dog_sounds[ "close" ].aftersoundwaitmin = 0,1;
|
||||
level.dog_sounds[ "close" ].aftersoundwaitmax = 0,3;
|
||||
level.dog_sounds[ "close" ].minrangesqr = level.dog_sounds[ "close" ].minrange * level.dog_sounds[ "close" ].minrange;
|
||||
level.dog_sounds[ "close" ].maxrangesqr = level.dog_sounds[ "close" ].maxrange * level.dog_sounds[ "close" ].maxrange;
|
||||
level.dog_sounds[ "far" ].minrange = 500;
|
||||
level.dog_sounds[ "far" ].maxrange = 0;
|
||||
level.dog_sounds[ "far" ].sound = "aml_dog_bark";
|
||||
level.dog_sounds[ "far" ].soundlengthplaceholder = 0,2;
|
||||
level.dog_sounds[ "far" ].aftersoundwaitmin = 0,1;
|
||||
level.dog_sounds[ "far" ].aftersoundwaitmax = 0,3;
|
||||
level.dog_sounds[ "far" ].minrangesqr = level.dog_sounds[ "far" ].minrange * level.dog_sounds[ "far" ].minrange;
|
||||
level.dog_sounds[ "far" ].maxrangesqr = level.dog_sounds[ "far" ].maxrange * level.dog_sounds[ "far" ].maxrange;
|
||||
}
|
||||
|
||||
main()
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
debug_anim_print( "dog_move::main()" );
|
||||
self setaimanimweights( 0, 0 );
|
||||
do_movement = 1;
|
||||
/#
|
||||
if ( !debug_allow_movement() )
|
||||
{
|
||||
do_movement = 0;
|
||||
#/
|
||||
}
|
||||
if ( isDefined( level.hostmigrationtimer ) )
|
||||
{
|
||||
do_movement = 0;
|
||||
}
|
||||
if ( !isDefined( self.traversecomplete ) && !isDefined( self.skipstartmove ) && self.a.movement == "run" && do_movement )
|
||||
{
|
||||
self startmove();
|
||||
blendtime = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
blendtime = 0,2;
|
||||
}
|
||||
self.traversecomplete = undefined;
|
||||
self.skipstartmove = undefined;
|
||||
if ( do_movement )
|
||||
{
|
||||
if ( shouldrun() )
|
||||
{
|
||||
debug_anim_print( "dog_move::main() - Setting move_run" );
|
||||
self setanimstate( "move_run" );
|
||||
maps/mp/animscripts/shared::donotetracksfortime( 0,1, "done" );
|
||||
debug_anim_print( "dog_move::main() - move_run wait 0.1 done " );
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_anim_print( "dog_move::main() - Setting move_start " );
|
||||
self setanimstate( "move_walk" );
|
||||
maps/mp/animscripts/shared::donotetracksfortime( 0,1, "done" );
|
||||
}
|
||||
}
|
||||
self thread maps/mp/animscripts/dog_stop::lookattarget( "normal" );
|
||||
while ( 1 )
|
||||
{
|
||||
self moveloop();
|
||||
if ( self.a.movement == "run" )
|
||||
{
|
||||
if ( self.disablearrivals == 0 )
|
||||
{
|
||||
self thread stopmove();
|
||||
}
|
||||
self waittill( "run" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
moveloop()
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self endon( "stop_soon" );
|
||||
while ( 1 )
|
||||
{
|
||||
do_movement = 1;
|
||||
/#
|
||||
if ( !debug_allow_movement() )
|
||||
{
|
||||
do_movement = 0;
|
||||
#/
|
||||
}
|
||||
if ( isDefined( level.hostmigrationtimer ) )
|
||||
{
|
||||
do_movement = 0;
|
||||
}
|
||||
while ( !do_movement )
|
||||
{
|
||||
self setaimanimweights( 0, 0 );
|
||||
self setanimstate( "stop_idle" );
|
||||
maps/mp/animscripts/shared::donotetracks( "done" );
|
||||
}
|
||||
if ( self.disablearrivals )
|
||||
{
|
||||
self.stopanimdistsq = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.stopanimdistsq = level.dogstoppingdistsq;
|
||||
}
|
||||
if ( shouldrun() )
|
||||
{
|
||||
debug_anim_print( "dog_move::moveLoop() - Setting move_run" );
|
||||
self setanimstate( "move_run" );
|
||||
maps/mp/animscripts/shared::donotetracksfortime( 0,2, "done" );
|
||||
debug_anim_print( "dog_move::moveLoop() - move_run wait 0.2 done " );
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_anim_print( "dog_move::moveLoop() - Setting move_walk " );
|
||||
self setanimstate( "move_walk" );
|
||||
maps/mp/animscripts/shared::donotetracksfortime( 0,2, "done" );
|
||||
debug_anim_print( "dog_move::moveLoop() - move_walk wait 0.2 done " );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
startmove()
|
||||
{
|
||||
debug_anim_print( "dog_move::startMove() - Setting move_start " );
|
||||
self setanimstate( "move_start" );
|
||||
maps/mp/animscripts/shared::donotetracks( "done" );
|
||||
debug_anim_print( "dog_move::startMove() - move_start notify done." );
|
||||
self animmode( "none", 0 );
|
||||
self set_orient_mode( "face motion" );
|
||||
}
|
||||
|
||||
stopmove()
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self endon( "run" );
|
||||
debug_anim_print( "dog_move::stopMove() - Setting move_stop" );
|
||||
self setanimstate( "move_stop" );
|
||||
maps/mp/animscripts/shared::donotetracks( "done" );
|
||||
debug_anim_print( "dog_move::stopMove() - move_stop notify done." );
|
||||
}
|
||||
|
||||
shouldrun()
|
||||
{
|
||||
/#
|
||||
if ( getDvarInt( #"DFB12081" ) != 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( getDvarInt( #"D5D7999B" ) != 0 )
|
||||
{
|
||||
return 0;
|
||||
#/
|
||||
}
|
||||
}
|
||||
if ( isDefined( self.enemy ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if ( self.lookaheaddist <= 90 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
angles = vectorToAngle( self.lookaheaddir );
|
||||
yaw_desired = absangleclamp180( angles[ 1 ] );
|
||||
yaw = absangleclamp180( self.angles[ 1 ] );
|
||||
if ( abs( yaw_desired - yaw ) >= 8 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
26
Multiplayer Core/common_mp/maps/mp/animscripts/dog_pain.gsc
Normal file
26
Multiplayer Core/common_mp/maps/mp/animscripts/dog_pain.gsc
Normal file
@ -0,0 +1,26 @@
|
||||
#include maps/mp/animscripts/shared;
|
||||
#include maps/mp/animscripts/utility;
|
||||
|
||||
main()
|
||||
{
|
||||
debug_anim_print( "dog_pain::main() " );
|
||||
self endon( "killanimscript" );
|
||||
self setaimanimweights( 0, 0 );
|
||||
if ( isDefined( self.enemy ) && isDefined( self.enemy.syncedmeleetarget ) && self.enemy.syncedmeleetarget == self )
|
||||
{
|
||||
self unlink();
|
||||
self.enemy.syncedmeleetarget = undefined;
|
||||
}
|
||||
speed = length( self getvelocity() );
|
||||
pain_anim = getanimdirection( self.damageyaw );
|
||||
if ( speed > level.dogrunpainspeed )
|
||||
{
|
||||
pain_anim = "pain_run_" + pain_anim;
|
||||
}
|
||||
else
|
||||
{
|
||||
pain_anim = "pain_" + pain_anim;
|
||||
}
|
||||
self setanimstate( pain_anim );
|
||||
self maps/mp/animscripts/shared::donotetracksfortime( 0,2, "done" );
|
||||
}
|
132
Multiplayer Core/common_mp/maps/mp/animscripts/dog_stop.gsc
Normal file
132
Multiplayer Core/common_mp/maps/mp/animscripts/dog_stop.gsc
Normal file
@ -0,0 +1,132 @@
|
||||
#include maps/mp/animscripts/utility;
|
||||
#include maps/mp/animscripts/shared;
|
||||
|
||||
main()
|
||||
{
|
||||
debug_anim_print( "dog_stop::main()" );
|
||||
self endon( "killanimscript" );
|
||||
self setaimanimweights( 0, 0 );
|
||||
self thread lookattarget( "attackIdle" );
|
||||
while ( 1 )
|
||||
{
|
||||
if ( shouldattackidle() )
|
||||
{
|
||||
self randomattackidle();
|
||||
maps/mp/animscripts/shared::donotetracks( "done" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self set_orient_mode( "face current" );
|
||||
debug_anim_print( "dog_stop::main() - Setting stop_idle" );
|
||||
self notify( "stop tracking" );
|
||||
self setaimanimweights( 0, 0 );
|
||||
self setanimstate( "stop_idle" );
|
||||
maps/mp/animscripts/shared::donotetracks( "done" );
|
||||
self thread lookattarget( "attackIdle" );
|
||||
}
|
||||
debug_anim_print( "dog_stop::main() - stop idle loop notify done." );
|
||||
}
|
||||
}
|
||||
|
||||
isfacingenemy( tolerancecosangle )
|
||||
{
|
||||
/#
|
||||
assert( isDefined( self.enemy ) );
|
||||
#/
|
||||
vectoenemy = self.enemy.origin - self.origin;
|
||||
disttoenemy = length( vectoenemy );
|
||||
if ( disttoenemy < 1 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
forward = anglesToForward( self.angles );
|
||||
val1 = ( forward[ 0 ] * vectoenemy[ 0 ] ) + ( forward[ 1 ] * vectoenemy[ 1 ] );
|
||||
val2 = ( ( forward[ 0 ] * vectoenemy[ 0 ] ) + ( forward[ 1 ] * vectoenemy[ 1 ] ) ) / disttoenemy;
|
||||
return ( ( ( forward[ 0 ] * vectoenemy[ 0 ] ) + ( forward[ 1 ] * vectoenemy[ 1 ] ) ) / disttoenemy ) > tolerancecosangle;
|
||||
}
|
||||
|
||||
randomattackidle()
|
||||
{
|
||||
if ( isfacingenemy( -0,5 ) )
|
||||
{
|
||||
self set_orient_mode( "face current" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self set_orient_mode( "face enemy" );
|
||||
}
|
||||
if ( should_growl() )
|
||||
{
|
||||
debug_anim_print( "dog_stop::main() - Setting stop_attackidle_growl" );
|
||||
self setanimstate( "stop_attackidle_growl" );
|
||||
return;
|
||||
}
|
||||
idlechance = 33;
|
||||
barkchance = 66;
|
||||
if ( isDefined( self.mode ) )
|
||||
{
|
||||
if ( self.mode == "growl" )
|
||||
{
|
||||
idlechance = 15;
|
||||
barkchance = 30;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( self.mode == "bark" )
|
||||
{
|
||||
idlechance = 15;
|
||||
barkchance = 85;
|
||||
}
|
||||
}
|
||||
}
|
||||
rand = randomint( 100 );
|
||||
if ( rand < idlechance )
|
||||
{
|
||||
debug_anim_print( "dog_stop::main() - Setting stop_attackidle" );
|
||||
self setanimstate( "stop_attackidle" );
|
||||
}
|
||||
else if ( rand < barkchance )
|
||||
{
|
||||
debug_anim_print( "dog_stop::main() - Setting stop_attackidle_bark " );
|
||||
self setanimstate( "stop_attackidle_bark" );
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_anim_print( "dog_stop::main() - Setting stop_attackidle_growl " );
|
||||
self setanimstate( "stop_attackidle_growl" );
|
||||
}
|
||||
}
|
||||
|
||||
shouldattackidle()
|
||||
{
|
||||
if ( isDefined( self.enemy ) && isalive( self.enemy ) )
|
||||
{
|
||||
return distancesquared( self.origin, self.enemy.origin ) < 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
should_growl()
|
||||
{
|
||||
if ( isDefined( self.script_growl ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if ( !isalive( self.enemy ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return !self cansee( self.enemy );
|
||||
}
|
||||
|
||||
lookattarget( lookposeset )
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self endon( "stop tracking" );
|
||||
debug_anim_print( "dog_stop::lookAtTarget() - Starting look at " + lookposeset );
|
||||
self.rightaimlimit = 90;
|
||||
self.leftaimlimit = -90;
|
||||
self.upaimlimit = 45;
|
||||
self.downaimlimit = -45;
|
||||
self maps/mp/animscripts/shared::setanimaimweight( 1, 0,2 );
|
||||
self maps/mp/animscripts/shared::trackloop();
|
||||
}
|
117
Multiplayer Core/common_mp/maps/mp/animscripts/dog_turn.gsc
Normal file
117
Multiplayer Core/common_mp/maps/mp/animscripts/dog_turn.gsc
Normal file
@ -0,0 +1,117 @@
|
||||
#include maps/mp/animscripts/shared;
|
||||
#include maps/mp/animscripts/utility;
|
||||
|
||||
main()
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
debug_turn_print( "dog_turn::main()" );
|
||||
self setaimanimweights( 0, 0 );
|
||||
self.safetochangescript = 0;
|
||||
deltayaw = self getdeltaturnyaw();
|
||||
if ( need_to_turn_around( deltayaw ) )
|
||||
{
|
||||
turn_180( deltayaw );
|
||||
}
|
||||
else
|
||||
{
|
||||
turn_90( deltayaw );
|
||||
}
|
||||
move_out_of_turn();
|
||||
self.skipstartmove = 1;
|
||||
self.safetochangescript = 1;
|
||||
}
|
||||
|
||||
need_to_turn_around( deltayaw )
|
||||
{
|
||||
angle = getDvarFloat( "dog_turn180_angle" );
|
||||
if ( deltayaw >= angle || deltayaw <= ( -1 * angle ) )
|
||||
{
|
||||
debug_turn_print( "dog_turn::need_to_turn_around(): " + deltayaw + " YES" );
|
||||
return 1;
|
||||
}
|
||||
debug_turn_print( "dog_turn::need_to_turn_around(): " + deltayaw + " NO" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
do_turn_anim( stopped_anim, run_anim, wait_time, run_wait_time )
|
||||
{
|
||||
speed = length( self getvelocity() );
|
||||
do_anim = stopped_anim;
|
||||
if ( level.dogrunturnspeed < speed )
|
||||
{
|
||||
do_anim = run_anim;
|
||||
wait_time = run_wait_time;
|
||||
}
|
||||
debug_turn_print( "dog_turn::do_turn_anim() - Setting " + do_anim );
|
||||
self setanimstate( do_anim );
|
||||
maps/mp/animscripts/shared::donotetracksfortime( run_wait_time, "done" );
|
||||
debug_turn_print( "dog_turn::do_turn_anim() - done with " + do_anim + " wait time " + run_wait_time );
|
||||
}
|
||||
|
||||
turn_left()
|
||||
{
|
||||
self do_turn_anim( "move_turn_left", "move_run_turn_left", 0,5, 0,5 );
|
||||
}
|
||||
|
||||
turn_right()
|
||||
{
|
||||
self do_turn_anim( "move_turn_right", "move_run_turn_right", 0,5, 0,5 );
|
||||
}
|
||||
|
||||
turn_180_left()
|
||||
{
|
||||
self do_turn_anim( "move_turn_around_left", "move_run_turn_around_left", 0,5, 0,7 );
|
||||
}
|
||||
|
||||
turn_180_right()
|
||||
{
|
||||
self do_turn_anim( "move_turn_around_right", "move_run_turn_around_right", 0,5, 0,7 );
|
||||
}
|
||||
|
||||
move_out_of_turn()
|
||||
{
|
||||
if ( self.a.movement == "run" )
|
||||
{
|
||||
debug_turn_print( "dog_turn::move_out_of_turn() - Setting move_run" );
|
||||
self setanimstate( "move_run" );
|
||||
maps/mp/animscripts/shared::donotetracksfortime( 0,1, "done" );
|
||||
debug_turn_print( "dog_turn::move_out_of_turn() - move_run wait 0.1 done " );
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_turn_print( "dog_turn::move_out_of_turn() - Setting move_start " );
|
||||
self setanimstate( "move_walk" );
|
||||
}
|
||||
}
|
||||
|
||||
turn_90( deltayaw )
|
||||
{
|
||||
self animmode( "zonly_physics", 0 );
|
||||
debug_turn_print( "dog_turn::turn_90() deltaYaw: " + deltayaw );
|
||||
if ( deltayaw > 0 )
|
||||
{
|
||||
debug_turn_print( "dog_turn::turn_90() left", 1 );
|
||||
self turn_left();
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_turn_print( "dog_turn::turn_90() right", 1 );
|
||||
self turn_right();
|
||||
}
|
||||
}
|
||||
|
||||
turn_180( deltayaw )
|
||||
{
|
||||
self animmode( "zonly_physics", 0 );
|
||||
debug_turn_print( "dog_turn::turn_180() deltaYaw: " + deltayaw );
|
||||
if ( deltayaw > 0 )
|
||||
{
|
||||
debug_turn_print( "dog_turn::turn_180() left", 1 );
|
||||
self turn_180_left();
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_turn_print( "dog_turn::turn_180() right", 1 );
|
||||
self turn_180_right();
|
||||
}
|
||||
}
|
306
Multiplayer Core/common_mp/maps/mp/animscripts/shared.gsc
Normal file
306
Multiplayer Core/common_mp/maps/mp/animscripts/shared.gsc
Normal file
@ -0,0 +1,306 @@
|
||||
#include maps/mp/_utility;
|
||||
#include maps/mp/animscripts/utility;
|
||||
#include common_scripts/utility;
|
||||
|
||||
handledogsoundnotetracks( note )
|
||||
{
|
||||
if ( note == "sound_dogstep_run_default" )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
prefix = getsubstr( note, 0, 5 );
|
||||
if ( prefix != "sound" )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
growling()
|
||||
{
|
||||
return isDefined( self.script_growl );
|
||||
}
|
||||
|
||||
handlenotetrack( note, flagname, customfunction, var1 )
|
||||
{
|
||||
/#
|
||||
if ( getDvarInt( #"6EBEB982" ) )
|
||||
{
|
||||
println( "dog notetrack: " + flagname + " " + note + " " + getTime() );
|
||||
#/
|
||||
}
|
||||
if ( isai( self ) && self.type == "dog" )
|
||||
{
|
||||
if ( handledogsoundnotetracks( note ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
switch( note )
|
||||
{
|
||||
case "end":
|
||||
case "finish":
|
||||
case "undefined":
|
||||
return note;
|
||||
default:
|
||||
if ( isDefined( customfunction ) )
|
||||
{
|
||||
if ( !isDefined( var1 ) )
|
||||
{
|
||||
return [[ customfunction ]]( note );
|
||||
}
|
||||
else
|
||||
{
|
||||
return [[ customfunction ]]( note, var1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
donotetracks( flagname, customfunction, var1 )
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( flagname, note );
|
||||
if ( !isDefined( note ) )
|
||||
{
|
||||
note = "undefined";
|
||||
}
|
||||
val = self handlenotetrack( note, flagname, customfunction, var1 );
|
||||
if ( isDefined( val ) )
|
||||
{
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
donotetracksforeverproc( notetracksfunc, flagname, killstring, customfunction, var1 )
|
||||
{
|
||||
if ( isDefined( killstring ) )
|
||||
{
|
||||
self endon( killstring );
|
||||
}
|
||||
self endon( "killanimscript" );
|
||||
for ( ;; )
|
||||
{
|
||||
time = getTime();
|
||||
returnednote = [[ notetracksfunc ]]( flagname, customfunction, var1 );
|
||||
timetaken = getTime() - time;
|
||||
if ( timetaken < 0,05 )
|
||||
{
|
||||
time = getTime();
|
||||
returnednote = [[ notetracksfunc ]]( flagname, customfunction, var1 );
|
||||
timetaken = getTime() - time;
|
||||
if ( timetaken < 0,05 )
|
||||
{
|
||||
/#
|
||||
println( getTime() + " mapsmpanimscriptsshared::DoNoteTracksForever is trying to cause an infinite loop on anim " + flagname + ", returned " + returnednote + "." );
|
||||
#/
|
||||
wait ( 0,05 - timetaken );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
donotetracksforever( flagname, killstring, customfunction, var1 )
|
||||
{
|
||||
donotetracksforeverproc( ::donotetracks, flagname, killstring, customfunction, var1 );
|
||||
}
|
||||
|
||||
donotetracksfortimeproc( donotetracksforeverfunc, time, flagname, customfunction, ent, var1 )
|
||||
{
|
||||
ent endon( "stop_notetracks" );
|
||||
[[ donotetracksforeverfunc ]]( flagname, undefined, customfunction, var1 );
|
||||
}
|
||||
|
||||
donotetracksfortime( time, flagname, customfunction, var1 )
|
||||
{
|
||||
ent = spawnstruct();
|
||||
ent thread donotetracksfortimeendnotify( time );
|
||||
donotetracksfortimeproc( ::donotetracksforever, time, flagname, customfunction, ent, var1 );
|
||||
}
|
||||
|
||||
donotetracksfortimeendnotify( time )
|
||||
{
|
||||
wait time;
|
||||
self notify( "stop_notetracks" );
|
||||
}
|
||||
|
||||
trackloop()
|
||||
{
|
||||
players = get_players();
|
||||
deltachangeperframe = 5;
|
||||
aimblendtime = 0,05;
|
||||
prevyawdelta = 0;
|
||||
prevpitchdelta = 0;
|
||||
maxyawdeltachange = 5;
|
||||
maxpitchdeltachange = 5;
|
||||
pitchadd = 0;
|
||||
yawadd = 0;
|
||||
if ( self.type != "dog" || self.type == "zombie" && self.type == "zombie_dog" )
|
||||
{
|
||||
domaxanglecheck = 0;
|
||||
self.shootent = self.enemy;
|
||||
}
|
||||
else
|
||||
{
|
||||
domaxanglecheck = 1;
|
||||
if ( self.a.script == "cover_crouch" && isDefined( self.a.covermode ) && self.a.covermode == "lean" )
|
||||
{
|
||||
pitchadd = -1 * anim.covercrouchleanpitch;
|
||||
}
|
||||
if ( self.a.script != "cover_left" && self.a.script == "cover_right" && isDefined( self.a.cornermode ) && self.a.cornermode == "lean" )
|
||||
{
|
||||
yawadd = self.covernode.angles[ 1 ] - self.angles[ 1 ];
|
||||
}
|
||||
}
|
||||
yawdelta = 0;
|
||||
pitchdelta = 0;
|
||||
firstframe = 1;
|
||||
for ( ;; )
|
||||
{
|
||||
incranimaimweight();
|
||||
selfshootatpos = ( self.origin[ 0 ], self.origin[ 1 ], self geteye()[ 2 ] );
|
||||
shootpos = undefined;
|
||||
if ( isDefined( self.enemy ) )
|
||||
{
|
||||
shootpos = self.enemy getshootatpos();
|
||||
}
|
||||
if ( !isDefined( shootpos ) )
|
||||
{
|
||||
yawdelta = 0;
|
||||
pitchdelta = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vectortoshootpos = shootpos - selfshootatpos;
|
||||
anglestoshootpos = vectorToAngle( vectortoshootpos );
|
||||
pitchdelta = 360 - anglestoshootpos[ 0 ];
|
||||
pitchdelta = angleClamp180( pitchdelta + pitchadd );
|
||||
yawdelta = self.angles[ 1 ] - anglestoshootpos[ 1 ];
|
||||
yawdelta = angleClamp180( yawdelta + yawadd );
|
||||
}
|
||||
if ( domaxanglecheck || abs( yawdelta ) > 60 && abs( pitchdelta ) > 60 )
|
||||
{
|
||||
yawdelta = 0;
|
||||
pitchdelta = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( yawdelta > self.rightaimlimit )
|
||||
{
|
||||
yawdelta = self.rightaimlimit;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( yawdelta < self.leftaimlimit )
|
||||
{
|
||||
yawdelta = self.leftaimlimit;
|
||||
}
|
||||
}
|
||||
if ( pitchdelta > self.upaimlimit )
|
||||
{
|
||||
pitchdelta = self.upaimlimit;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pitchdelta < self.downaimlimit )
|
||||
{
|
||||
pitchdelta = self.downaimlimit;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( firstframe )
|
||||
{
|
||||
firstframe = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
yawdeltachange = yawdelta - prevyawdelta;
|
||||
if ( abs( yawdeltachange ) > maxyawdeltachange )
|
||||
{
|
||||
yawdelta = prevyawdelta + ( maxyawdeltachange * sign( yawdeltachange ) );
|
||||
}
|
||||
pitchdeltachange = pitchdelta - prevpitchdelta;
|
||||
if ( abs( pitchdeltachange ) > maxpitchdeltachange )
|
||||
{
|
||||
pitchdelta = prevpitchdelta + ( maxpitchdeltachange * sign( pitchdeltachange ) );
|
||||
}
|
||||
}
|
||||
prevyawdelta = yawdelta;
|
||||
prevpitchdelta = pitchdelta;
|
||||
updown = 0;
|
||||
leftright = 0;
|
||||
if ( yawdelta > 0 )
|
||||
{
|
||||
/#
|
||||
assert( yawdelta <= self.rightaimlimit );
|
||||
#/
|
||||
weight = ( yawdelta / self.rightaimlimit ) * self.a.aimweight;
|
||||
leftright = weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( yawdelta < 0 )
|
||||
{
|
||||
/#
|
||||
assert( yawdelta >= self.leftaimlimit );
|
||||
#/
|
||||
weight = ( yawdelta / self.leftaimlimit ) * self.a.aimweight;
|
||||
leftright = -1 * weight;
|
||||
}
|
||||
}
|
||||
if ( pitchdelta > 0 )
|
||||
{
|
||||
/#
|
||||
assert( pitchdelta <= self.upaimlimit );
|
||||
#/
|
||||
weight = ( pitchdelta / self.upaimlimit ) * self.a.aimweight;
|
||||
updown = weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pitchdelta < 0 )
|
||||
{
|
||||
/#
|
||||
assert( pitchdelta >= self.downaimlimit );
|
||||
#/
|
||||
weight = ( pitchdelta / self.downaimlimit ) * self.a.aimweight;
|
||||
updown = -1 * weight;
|
||||
}
|
||||
}
|
||||
self setaimanimweights( updown, leftright );
|
||||
wait 0,05;
|
||||
}
|
||||
}
|
||||
|
||||
setanimaimweight( goalweight, goaltime )
|
||||
{
|
||||
if ( !isDefined( goaltime ) || goaltime <= 0 )
|
||||
{
|
||||
self.a.aimweight = goalweight;
|
||||
self.a.aimweight_start = goalweight;
|
||||
self.a.aimweight_end = goalweight;
|
||||
self.a.aimweight_transframes = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.a.aimweight = goalweight;
|
||||
self.a.aimweight_start = self.a.aimweight;
|
||||
self.a.aimweight_end = goalweight;
|
||||
self.a.aimweight_transframes = int( goaltime * 20 );
|
||||
}
|
||||
self.a.aimweight_t = 0;
|
||||
}
|
||||
|
||||
incranimaimweight()
|
||||
{
|
||||
if ( self.a.aimweight_t < self.a.aimweight_transframes )
|
||||
{
|
||||
self.a.aimweight_t++;
|
||||
t = ( 1 * self.a.aimweight_t ) / self.a.aimweight_transframes;
|
||||
self.a.aimweight = ( self.a.aimweight_start * ( 1 - t ) ) + ( self.a.aimweight_end * t );
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#include maps/mp/animscripts/traverse/shared;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( self.type == "dog" )
|
||||
{
|
||||
dog_jump_down( 40, 3 );
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#include maps/mp/animscripts/traverse/shared;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( self.type == "dog" )
|
||||
{
|
||||
dog_jump_down( 56, 7 );
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#include maps/mp/animscripts/traverse/shared;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( self.type == "dog" )
|
||||
{
|
||||
dog_jump_down_far( 96, 11, 0,65 );
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#include maps/mp/animscripts/traverse/shared;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( self.type == "dog" )
|
||||
{
|
||||
dog_jump_up( 40, 3 );
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#include maps/mp/animscripts/traverse/shared;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( self.type == "dog" )
|
||||
{
|
||||
dog_jump_up( 56, 5 );
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#include maps/mp/animscripts/traverse/shared;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( self.type == "dog" )
|
||||
{
|
||||
dog_jump_up_high( 80, 8 );
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#include maps/mp/animscripts/traverse/shared;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( self.type == "dog" )
|
||||
{
|
||||
dog_jump_up_high( 96, 9 );
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#include maps/mp/animscripts/traverse/shared;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( self.type == "dog" )
|
||||
{
|
||||
dog_wall_and_window_hop( "traverse_window", 40 );
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#include maps/mp/animscripts/traverse/shared;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( self.type == "dog" )
|
||||
{
|
||||
dog_wall_and_window_hop( "traverse_window", 36 );
|
||||
}
|
||||
}
|
@ -0,0 +1,227 @@
|
||||
#include maps/mp/animscripts/shared;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
#include maps/mp/animscripts/utility;
|
||||
|
||||
init_traverse()
|
||||
{
|
||||
point = getent( self.target, "targetname" );
|
||||
if ( isDefined( point ) )
|
||||
{
|
||||
self.traverse_height = point.origin[ 2 ];
|
||||
point delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
point = getstruct( self.target, "targetname" );
|
||||
if ( isDefined( point ) )
|
||||
{
|
||||
self.traverse_height = point.origin[ 2 ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
teleportthread( verticaloffset )
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self notify( "endTeleportThread" );
|
||||
self endon( "endTeleportThread" );
|
||||
reps = 5;
|
||||
offset = ( 0, 0, verticaloffset / reps );
|
||||
i = 0;
|
||||
while ( i < reps )
|
||||
{
|
||||
self teleport( self.origin + offset );
|
||||
wait 0,05;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
teleportthreadex( verticaloffset, delay, frames )
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self notify( "endTeleportThread" );
|
||||
self endon( "endTeleportThread" );
|
||||
if ( verticaloffset == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
wait delay;
|
||||
amount = verticaloffset / frames;
|
||||
if ( amount > 10 )
|
||||
{
|
||||
amount = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( amount < -10 )
|
||||
{
|
||||
amount = -10;
|
||||
}
|
||||
}
|
||||
offset = ( 0, 0, amount );
|
||||
i = 0;
|
||||
while ( i < frames )
|
||||
{
|
||||
self teleport( self.origin + offset );
|
||||
wait 0,05;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
dog_wall_and_window_hop( traversename, height )
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self traversemode( "nogravity" );
|
||||
self traversemode( "noclip" );
|
||||
startnode = self getnegotiationstartnode();
|
||||
/#
|
||||
assert( isDefined( startnode ) );
|
||||
#/
|
||||
self orientmode( "face angle", startnode.angles[ 1 ] );
|
||||
if ( isDefined( startnode.traverse_height ) )
|
||||
{
|
||||
realheight = startnode.traverse_height - startnode.origin[ 2 ];
|
||||
self thread teleportthread( realheight - height );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( height != 36 )
|
||||
{
|
||||
self thread teleportthreadex( height - 36, 0,2, 7 );
|
||||
}
|
||||
}
|
||||
debug_anim_print( "traverse::dog_wall_and_window_hop() - Setting " + traversename );
|
||||
self setanimstate( traversename );
|
||||
maps/mp/animscripts/shared::donotetracksfortime( 1, "done" );
|
||||
debug_anim_print( "traverse::dog_wall_and_window_hop() - " + traversename );
|
||||
self.traversecomplete = 1;
|
||||
}
|
||||
|
||||
dog_jump_down( height, frames, time )
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self traversemode( "noclip" );
|
||||
if ( !isDefined( time ) )
|
||||
{
|
||||
time = 0,3;
|
||||
}
|
||||
startnode = self getnegotiationstartnode();
|
||||
/#
|
||||
assert( isDefined( startnode ) );
|
||||
#/
|
||||
self orientmode( "face angle", startnode.angles[ 1 ] );
|
||||
if ( isDefined( startnode.traverse_height ) )
|
||||
{
|
||||
realheight = startnode.traverse_height - startnode.origin[ 2 ];
|
||||
self thread teleportthread( realheight - height );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( height != 40 )
|
||||
{
|
||||
self thread teleportthreadex( height - 40, 0,1, frames );
|
||||
}
|
||||
}
|
||||
debug_anim_print( "traverse::dog_jump_down() - Setting traverse_jump_down_40" );
|
||||
self setanimstate( "traverse_jump_down_40" );
|
||||
maps/mp/animscripts/shared::donotetracksfortime( time, "done" );
|
||||
debug_anim_print( "traverse::dog_jump_down() - traverse_jump_down_40 " );
|
||||
self traversemode( "gravity" );
|
||||
self.traversecomplete = 1;
|
||||
}
|
||||
|
||||
dog_jump_down_far( height, frames, time )
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self traversemode( "noclip" );
|
||||
if ( !isDefined( time ) )
|
||||
{
|
||||
time = 0,3;
|
||||
}
|
||||
startnode = self getnegotiationstartnode();
|
||||
/#
|
||||
assert( isDefined( startnode ) );
|
||||
#/
|
||||
self orientmode( "face angle", startnode.angles[ 1 ] );
|
||||
if ( isDefined( startnode.traverse_height ) )
|
||||
{
|
||||
realheight = startnode.traverse_height - startnode.origin[ 2 ];
|
||||
self thread teleportthread( realheight - height );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( height != 80 )
|
||||
{
|
||||
self thread teleportthreadex( 80 - height, 0,1, frames );
|
||||
}
|
||||
}
|
||||
debug_anim_print( "traverse::dog_jump_down() - Setting traverse_jump_down_80" );
|
||||
self setanimstate( "traverse_jump_down_80" );
|
||||
maps/mp/animscripts/shared::donotetracksfortime( time, "done" );
|
||||
debug_anim_print( "traverse::dog_jump_down() - traverse_jump_down_80 " );
|
||||
self traversemode( "gravity" );
|
||||
self.traversecomplete = 1;
|
||||
}
|
||||
|
||||
dog_jump_up( height, frames )
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self traversemode( "noclip" );
|
||||
startnode = self getnegotiationstartnode();
|
||||
/#
|
||||
assert( isDefined( startnode ) );
|
||||
#/
|
||||
self orientmode( "face angle", startnode.angles[ 1 ] );
|
||||
if ( isDefined( startnode.traverse_height ) )
|
||||
{
|
||||
realheight = startnode.traverse_height - startnode.origin[ 2 ];
|
||||
self thread teleportthread( realheight - height );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( height != 40 )
|
||||
{
|
||||
self thread teleportthreadex( height - 40, 0,2, frames );
|
||||
}
|
||||
}
|
||||
debug_anim_print( "traverse::dog_jump_up() - Setting traverse_jump_up_40" );
|
||||
self setanimstate( "traverse_jump_up_40" );
|
||||
maps/mp/animscripts/shared::donotetracksfortime( 0,5, "done" );
|
||||
debug_anim_print( "traverse::dog_jump_up() - traverse_jump_up_40 " );
|
||||
self traversemode( "gravity" );
|
||||
self.traversecomplete = 1;
|
||||
}
|
||||
|
||||
dog_jump_up_high( height, frames )
|
||||
{
|
||||
/#
|
||||
assert( self.type == "dog", "Only dogs can do this traverse currently." );
|
||||
#/
|
||||
self endon( "killanimscript" );
|
||||
self traversemode( "nogravity" );
|
||||
self traversemode( "noclip" );
|
||||
startnode = self getnegotiationstartnode();
|
||||
/#
|
||||
assert( isDefined( startnode ) );
|
||||
#/
|
||||
self orientmode( "face angle", startnode.angles[ 1 ] );
|
||||
if ( isDefined( startnode.traverse_height ) )
|
||||
{
|
||||
realheight = startnode.traverse_height - startnode.origin[ 2 ];
|
||||
self thread teleportthreadex( height - 80, 0,2, frames );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( height != 80 )
|
||||
{
|
||||
self thread teleportthreadex( height - 80, 0,2, frames );
|
||||
}
|
||||
}
|
||||
debug_anim_print( "traverse::dog_jump_up_80() - Setting traverse_jump_up_80" );
|
||||
self setanimstate( "traverse_jump_up_80" );
|
||||
maps/mp/animscripts/shared::donotetracksfortime( 0,6, "done" );
|
||||
debug_anim_print( "traverse::dog_jump_up_80() - traverse_jump_up_80 " );
|
||||
self traversemode( "gravity" );
|
||||
self.traversecomplete = 1;
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
#include maps/mp/animscripts/shared;
|
||||
#include maps/mp/animscripts/utility;
|
||||
#include maps/mp/animscripts/traverse/shared;
|
||||
|
||||
main()
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self traversemode( "nogravity" );
|
||||
self traversemode( "noclip" );
|
||||
startnode = self getnegotiationstartnode();
|
||||
/#
|
||||
assert( isDefined( startnode ) );
|
||||
#/
|
||||
self orientmode( "face angle", startnode.angles[ 1 ] );
|
||||
if ( isDefined( startnode.traverse_height ) )
|
||||
{
|
||||
realheight = startnode.traverse_height - startnode.origin[ 2 ];
|
||||
self thread teleportthread( realheight );
|
||||
}
|
||||
debug_anim_print( "traverse::through_hole()" );
|
||||
self setanimstate( "traverse_through_hole_42" );
|
||||
maps/mp/animscripts/shared::donotetracksfortime( 1, "done" );
|
||||
debug_anim_print( "traverse::through_hole()" );
|
||||
self.traversecomplete = 1;
|
||||
}
|
166
Multiplayer Core/common_mp/maps/mp/animscripts/utility.gsc
Normal file
166
Multiplayer Core/common_mp/maps/mp/animscripts/utility.gsc
Normal file
@ -0,0 +1,166 @@
|
||||
|
||||
anim_get_dvar_int( dvar, def )
|
||||
{
|
||||
return int( anim_get_dvar( dvar, def ) );
|
||||
}
|
||||
|
||||
anim_get_dvar( dvar, def )
|
||||
{
|
||||
if ( getDvar( dvar ) != "" )
|
||||
{
|
||||
return getDvarFloat( dvar );
|
||||
}
|
||||
else
|
||||
{
|
||||
setdvar( dvar, def );
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
set_orient_mode( mode, val1 )
|
||||
{
|
||||
/#
|
||||
if ( level.dog_debug_orient == self getentnum() )
|
||||
{
|
||||
if ( isDefined( val1 ) )
|
||||
{
|
||||
println( "DOG: Setting orient mode: " + mode + " " + val1 + " " + getTime() );
|
||||
}
|
||||
else
|
||||
{
|
||||
println( "DOG: Setting orient mode: " + mode + " " + getTime() );
|
||||
#/
|
||||
}
|
||||
}
|
||||
if ( isDefined( val1 ) )
|
||||
{
|
||||
self orientmode( mode, val1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
self orientmode( mode );
|
||||
}
|
||||
}
|
||||
|
||||
debug_anim_print( text )
|
||||
{
|
||||
/#
|
||||
if ( level.dog_debug_anims )
|
||||
{
|
||||
println( ( text + " " ) + getTime() );
|
||||
}
|
||||
if ( level.dog_debug_anims_ent == self getentnum() )
|
||||
{
|
||||
println( ( text + " " ) + getTime() );
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
debug_turn_print( text, line )
|
||||
{
|
||||
/#
|
||||
if ( level.dog_debug_turns == self getentnum() )
|
||||
{
|
||||
duration = 200;
|
||||
currentyawcolor = ( 1, 0, 1 );
|
||||
lookaheadyawcolor = ( 1, 0, 1 );
|
||||
desiredyawcolor = ( 1, 0, 1 );
|
||||
currentyaw = angleClamp180( self.angles[ 1 ] );
|
||||
desiredyaw = angleClamp180( self.desiredangle );
|
||||
lookaheaddir = self.lookaheaddir;
|
||||
lookaheadangles = vectorToAngle( lookaheaddir );
|
||||
lookaheadyaw = angleClamp180( lookaheadangles[ 1 ] );
|
||||
println( ( text + " " ) + getTime() + " cur: " + currentyaw + " look: " + lookaheadyaw + " desired: " + desiredyaw );
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
debug_allow_movement()
|
||||
{
|
||||
/#
|
||||
return anim_get_dvar_int( "debug_dog_allow_movement", "1" );
|
||||
#/
|
||||
return 1;
|
||||
}
|
||||
|
||||
debug_allow_combat()
|
||||
{
|
||||
/#
|
||||
return anim_get_dvar_int( "debug_dog_allow_combat", "1" );
|
||||
#/
|
||||
return 1;
|
||||
}
|
||||
|
||||
current_yaw_line_debug( duration )
|
||||
{
|
||||
/#
|
||||
currentyawcolor = [];
|
||||
currentyawcolor[ 0 ] = ( 1, 0, 1 );
|
||||
currentyawcolor[ 1 ] = ( 1, 0, 1 );
|
||||
current_color_index = 0;
|
||||
start_time = getTime();
|
||||
if ( !isDefined( level.lastdebugheight ) )
|
||||
{
|
||||
level.lastdebugheight = 15;
|
||||
}
|
||||
while ( ( getTime() - start_time ) < 1000 )
|
||||
{
|
||||
pos1 = ( self.origin[ 0 ], self.origin[ 1 ], self.origin[ 2 ] + level.lastdebugheight );
|
||||
pos2 = pos1 + vectorScale( anglesToForward( self.angles ), ( current_color_index + 1 ) * 10 );
|
||||
line( pos1, pos2, currentyawcolor[ current_color_index ], 0,3, 1, duration );
|
||||
current_color_index = ( current_color_index + 1 ) % currentyawcolor.size;
|
||||
wait 0,05;
|
||||
}
|
||||
if ( level.lastdebugheight == 15 )
|
||||
{
|
||||
level.lastdebugheight = 30;
|
||||
}
|
||||
else
|
||||
{
|
||||
level.lastdebugheight = 15;
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
getanimdirection( damageyaw )
|
||||
{
|
||||
if ( damageyaw > 135 || damageyaw <= -135 )
|
||||
{
|
||||
return "front";
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( damageyaw > 45 && damageyaw <= 135 )
|
||||
{
|
||||
return "right";
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( damageyaw > -45 && damageyaw <= 45 )
|
||||
{
|
||||
return "back";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "left";
|
||||
}
|
||||
}
|
||||
}
|
||||
return "front";
|
||||
}
|
||||
|
||||
setfootstepeffect( name, fx )
|
||||
{
|
||||
/#
|
||||
assert( isDefined( name ), "Need to define the footstep surface type." );
|
||||
#/
|
||||
/#
|
||||
assert( isDefined( fx ), "Need to define the mud footstep effect." );
|
||||
#/
|
||||
if ( !isDefined( anim.optionalstepeffects ) )
|
||||
{
|
||||
anim.optionalstepeffects = [];
|
||||
}
|
||||
anim.optionalstepeffects[ anim.optionalstepeffects.size ] = name;
|
||||
level._effect[ "step_" + name ] = fx;
|
||||
}
|
963
Multiplayer Core/common_mp/maps/mp/killstreaks/_dogs.gsc
Normal file
963
Multiplayer Core/common_mp/maps/mp/killstreaks/_dogs.gsc
Normal file
@ -0,0 +1,963 @@
|
||||
#include maps/mp/gametypes/_dev;
|
||||
#include maps/mp/killstreaks/_supplydrop;
|
||||
#include maps/mp/_scoreevents;
|
||||
#include maps/mp/gametypes/_weapons;
|
||||
#include maps/mp/gametypes/_spawning;
|
||||
#include maps/mp/gametypes/_battlechatter_mp;
|
||||
#include maps/mp/killstreaks/_killstreakrules;
|
||||
#include maps/mp/killstreaks/_killstreaks;
|
||||
#include maps/mp/gametypes/_tweakables;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
precachemodel( "german_shepherd_vest" );
|
||||
precachemodel( "german_shepherd_vest_black" );
|
||||
level.dog_targets = [];
|
||||
level.dog_targets[ level.dog_targets.size ] = "trigger_radius";
|
||||
level.dog_targets[ level.dog_targets.size ] = "trigger_multiple";
|
||||
level.dog_targets[ level.dog_targets.size ] = "trigger_use_touch";
|
||||
/#
|
||||
level thread devgui_dog_think();
|
||||
#/
|
||||
}
|
||||
|
||||
initkillstreak()
|
||||
{
|
||||
if ( maps/mp/gametypes/_tweakables::gettweakablevalue( "killstreak", "allowdogs" ) )
|
||||
{
|
||||
maps/mp/killstreaks/_killstreaks::registerkillstreak( "dogs_mp", "dogs_mp", "killstreak_dogs", "dogs_used", ::usekillstreakdogs, 1 );
|
||||
maps/mp/killstreaks/_killstreaks::registerkillstreakstrings( "dogs_mp", &"KILLSTREAK_EARNED_DOGS", &"KILLSTREAK_DOGS_NOT_AVAILABLE", &"KILLSTREAK_DOGS_INBOUND" );
|
||||
maps/mp/killstreaks/_killstreaks::registerkillstreakdialog( "dogs_mp", "mpl_killstreak_dogs", "kls_dogs_used", "", "kls_dogs_enemy", "", "kls_dogs_ready" );
|
||||
maps/mp/killstreaks/_killstreaks::registerkillstreakdevdvar( "dogs_mp", "scr_givedogs" );
|
||||
maps/mp/killstreaks/_killstreaks::setkillstreakteamkillpenaltyscale( "dogs_mp", 0 );
|
||||
maps/mp/killstreaks/_killstreaks::registerkillstreakaltweapon( "dogs_mp", "dog_bite_mp" );
|
||||
}
|
||||
}
|
||||
|
||||
usekillstreakdogs( hardpointtype )
|
||||
{
|
||||
if ( !dog_killstreak_init() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( !self maps/mp/killstreaks/_killstreakrules::iskillstreakallowed( hardpointtype, self.team ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
killstreak_id = self maps/mp/killstreaks/_killstreakrules::killstreakstart( "dogs_mp", self.team );
|
||||
self thread ownerhadactivedogs();
|
||||
if ( killstreak_id == -1 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
while ( level.teambased )
|
||||
{
|
||||
_a71 = level.teams;
|
||||
_k71 = getFirstArrayKey( _a71 );
|
||||
while ( isDefined( _k71 ) )
|
||||
{
|
||||
team = _a71[ _k71 ];
|
||||
if ( team == self.team )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
thread maps/mp/gametypes/_battlechatter_mp::onkillstreakused( "dogs", team );
|
||||
}
|
||||
_k71 = getNextArrayKey( _a71, _k71 );
|
||||
}
|
||||
}
|
||||
self maps/mp/killstreaks/_killstreaks::playkillstreakstartdialog( "dogs_mp", self.team, 1 );
|
||||
level.globalkillstreakscalled++;
|
||||
self addweaponstat( "dogs_mp", "used", 1 );
|
||||
ownerdeathcount = self.deathcount;
|
||||
level thread dog_manager_spawn_dogs( self, ownerdeathcount, killstreak_id );
|
||||
level notify( "called_in_the_dogs" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
ownerhadactivedogs()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self.dogsactive = 1;
|
||||
self.dogsactivekillstreak = 0;
|
||||
self waittill_any( "death", "game_over", "dogs_complete" );
|
||||
self.dogsactivekillstreak = 0;
|
||||
self.dogsactive = undefined;
|
||||
}
|
||||
|
||||
dog_killstreak_init()
|
||||
{
|
||||
dog_spawner = getent( "dog_spawner", "targetname" );
|
||||
if ( !isDefined( dog_spawner ) )
|
||||
{
|
||||
/#
|
||||
println( "No dog spawners found in map" );
|
||||
#/
|
||||
return 0;
|
||||
}
|
||||
spawns = getnodearray( "spawn", "script_noteworthy" );
|
||||
if ( spawns.size <= 0 )
|
||||
{
|
||||
/#
|
||||
println( "No dog spawn nodes found in map" );
|
||||
#/
|
||||
return 0;
|
||||
}
|
||||
exits = getnodearray( "exit", "script_noteworthy" );
|
||||
if ( exits.size <= 0 )
|
||||
{
|
||||
/#
|
||||
println( "No dog exit nodes found in map" );
|
||||
#/
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
dog_set_model()
|
||||
{
|
||||
self setmodel( "german_shepherd_vest" );
|
||||
self setenemymodel( "german_shepherd_vest_black" );
|
||||
}
|
||||
|
||||
init_dog()
|
||||
{
|
||||
/#
|
||||
assert( isai( self ) );
|
||||
#/
|
||||
self.targetname = "attack_dog";
|
||||
self.animtree = "dog.atr";
|
||||
self.type = "dog";
|
||||
self.accuracy = 0,2;
|
||||
self.health = 100;
|
||||
self.maxhealth = 100;
|
||||
self.aiweapon = "dog_bite_mp";
|
||||
self.secondaryweapon = "";
|
||||
self.sidearm = "";
|
||||
self.grenadeammo = 0;
|
||||
self.goalradius = 128;
|
||||
self.nododgemove = 1;
|
||||
self.ignoresuppression = 1;
|
||||
self.suppressionthreshold = 1;
|
||||
self.disablearrivals = 0;
|
||||
self.pathenemyfightdist = 512;
|
||||
self.soundmod = "dog";
|
||||
self.meleeattackdist = 90;
|
||||
self thread dog_health_regen();
|
||||
self thread selfdefensechallenge();
|
||||
}
|
||||
|
||||
get_spawn_node( owner, team )
|
||||
{
|
||||
spawns = getnodearray( "spawn", "script_noteworthy" );
|
||||
return spawns[ randomint( spawns.size ) ];
|
||||
}
|
||||
|
||||
get_score_for_spawn( origin, team )
|
||||
{
|
||||
players = get_players();
|
||||
score = 0;
|
||||
_a201 = players;
|
||||
_k201 = getFirstArrayKey( _a201 );
|
||||
while ( isDefined( _k201 ) )
|
||||
{
|
||||
player = _a201[ _k201 ];
|
||||
if ( !isDefined( player ) )
|
||||
{
|
||||
}
|
||||
else if ( !isalive( player ) )
|
||||
{
|
||||
}
|
||||
else if ( player.sessionstate != "playing" )
|
||||
{
|
||||
}
|
||||
else if ( distancesquared( player.origin, origin ) > 4194304 )
|
||||
{
|
||||
}
|
||||
else if ( player.team == team )
|
||||
{
|
||||
score++;
|
||||
}
|
||||
else
|
||||
{
|
||||
score--;
|
||||
|
||||
}
|
||||
_k201 = getNextArrayKey( _a201, _k201 );
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
||||
dog_set_owner( owner, team, requireddeathcount )
|
||||
{
|
||||
self setentityowner( owner );
|
||||
self.aiteam = team;
|
||||
self.requireddeathcount = requireddeathcount;
|
||||
}
|
||||
|
||||
dog_create_spawn_influencer()
|
||||
{
|
||||
self maps/mp/gametypes/_spawning::create_dog_influencers();
|
||||
}
|
||||
|
||||
dog_manager_spawn_dog( owner, team, spawn_node, requireddeathcount )
|
||||
{
|
||||
dog_spawner = getent( "dog_spawner", "targetname" );
|
||||
dog = dog_spawner spawnactor();
|
||||
dog forceteleport( spawn_node.origin, spawn_node.angles );
|
||||
dog init_dog();
|
||||
dog dog_set_owner( owner, team, requireddeathcount );
|
||||
dog dog_set_model();
|
||||
dog dog_create_spawn_influencer();
|
||||
dog thread dog_owner_kills();
|
||||
dog thread dog_notify_level_on_death();
|
||||
dog thread dog_patrol();
|
||||
dog thread maps/mp/gametypes/_weapons::monitor_dog_special_grenades();
|
||||
return dog;
|
||||
}
|
||||
|
||||
dog_manager_spawn_dogs( owner, deathcount, killstreak_id )
|
||||
{
|
||||
requireddeathcount = deathcount;
|
||||
team = owner.team;
|
||||
level.dog_abort = 0;
|
||||
owner thread dog_manager_abort();
|
||||
level thread dog_manager_game_ended();
|
||||
count = 0;
|
||||
while ( count < 10 )
|
||||
{
|
||||
if ( level.dog_abort )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
dogs = dog_manager_get_dogs();
|
||||
while ( dogs.size < 5 && count < 10 && !level.dog_abort )
|
||||
{
|
||||
node = get_spawn_node( owner, team );
|
||||
level dog_manager_spawn_dog( owner, team, node, requireddeathcount );
|
||||
count++;
|
||||
wait randomfloatrange( 2, 5 );
|
||||
dogs = dog_manager_get_dogs();
|
||||
}
|
||||
level waittill( "dog_died" );
|
||||
}
|
||||
}
|
||||
for ( ;; )
|
||||
{
|
||||
dogs = dog_manager_get_dogs();
|
||||
if ( dogs.size <= 0 )
|
||||
{
|
||||
maps/mp/killstreaks/_killstreakrules::killstreakstop( "dogs_mp", team, killstreak_id );
|
||||
if ( isDefined( owner ) )
|
||||
{
|
||||
owner notify( "dogs_complete" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
level waittill( "dog_died" );
|
||||
}
|
||||
}
|
||||
|
||||
dog_abort()
|
||||
{
|
||||
level.dog_abort = 1;
|
||||
dogs = dog_manager_get_dogs();
|
||||
_a324 = dogs;
|
||||
_k324 = getFirstArrayKey( _a324 );
|
||||
while ( isDefined( _k324 ) )
|
||||
{
|
||||
dog = _a324[ _k324 ];
|
||||
dog notify( "abort" );
|
||||
_k324 = getNextArrayKey( _a324, _k324 );
|
||||
}
|
||||
level notify( "dog_abort" );
|
||||
}
|
||||
|
||||
dog_manager_abort()
|
||||
{
|
||||
level endon( "dog_abort" );
|
||||
self wait_endon( 50, "disconnect", "joined_team", "joined_specators" );
|
||||
dog_abort();
|
||||
}
|
||||
|
||||
dog_manager_game_ended()
|
||||
{
|
||||
level endon( "dog_abort" );
|
||||
level waittill( "game_ended" );
|
||||
dog_abort();
|
||||
}
|
||||
|
||||
dog_notify_level_on_death()
|
||||
{
|
||||
self waittill( "death" );
|
||||
level notify( "dog_died" );
|
||||
}
|
||||
|
||||
dog_leave()
|
||||
{
|
||||
self clearentitytarget();
|
||||
self.ignoreall = 1;
|
||||
self.goalradius = 30;
|
||||
self setgoalnode( self dog_get_exit_node() );
|
||||
self wait_endon( 20, "goal", "bad_path" );
|
||||
self delete();
|
||||
}
|
||||
|
||||
dog_patrol()
|
||||
{
|
||||
self endon( "death" );
|
||||
/#
|
||||
self endon( "debug_patrol" );
|
||||
#/
|
||||
for ( ;; )
|
||||
{
|
||||
if ( level.dog_abort )
|
||||
{
|
||||
self dog_leave();
|
||||
return;
|
||||
}
|
||||
if ( isDefined( self.enemy ) )
|
||||
{
|
||||
wait randomintrange( 3, 5 );
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
nodes = [];
|
||||
objectives = dog_patrol_near_objective();
|
||||
i = 0;
|
||||
while ( i < objectives.size )
|
||||
{
|
||||
objective = random( objectives );
|
||||
nodes = getnodesinradius( objective.origin, 256, 64, 512, "Path", 16 );
|
||||
if ( nodes.size )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if ( !nodes.size )
|
||||
{
|
||||
player = self dog_patrol_near_enemy();
|
||||
if ( isDefined( player ) )
|
||||
{
|
||||
nodes = getnodesinradius( player.origin, 1024, 0, 128, "Path", 8 );
|
||||
}
|
||||
}
|
||||
if ( !nodes.size && isDefined( self.script_owner ) )
|
||||
{
|
||||
if ( isalive( self.script_owner ) && self.script_owner.sessionstate == "playing" )
|
||||
{
|
||||
nodes = getnodesinradius( self.script_owner.origin, 512, 256, 512, "Path", 16 );
|
||||
}
|
||||
}
|
||||
if ( !nodes.size )
|
||||
{
|
||||
nodes = getnodesinradius( self.origin, 1024, 512, 512, "Path" );
|
||||
}
|
||||
while ( nodes.size )
|
||||
{
|
||||
nodes = array_randomize( nodes );
|
||||
_a429 = nodes;
|
||||
_k429 = getFirstArrayKey( _a429 );
|
||||
while ( isDefined( _k429 ) )
|
||||
{
|
||||
node = _a429[ _k429 ];
|
||||
if ( isDefined( node.script_noteworthy ) )
|
||||
{
|
||||
}
|
||||
else if ( isDefined( node.dog_claimed ) && isalive( node.dog_claimed ) )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
self setgoalnode( node );
|
||||
node.dog_claimed = self;
|
||||
nodes = [];
|
||||
event = self waittill_any_return( "goal", "bad_path", "enemy", "abort" );
|
||||
if ( event == "goal" )
|
||||
{
|
||||
wait_endon( randomintrange( 3, 5 ), "damage", "enemy", "abort" );
|
||||
}
|
||||
node.dog_claimed = undefined;
|
||||
break;
|
||||
}
|
||||
_k429 = getNextArrayKey( _a429, _k429 );
|
||||
}
|
||||
}
|
||||
wait 0,5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dog_patrol_near_objective()
|
||||
{
|
||||
if ( !isDefined( level.dog_objectives ) )
|
||||
{
|
||||
level.dog_objectives = [];
|
||||
level.dog_objective_next_update = 0;
|
||||
}
|
||||
if ( level.gametype == "tdm" || level.gametype == "dm" )
|
||||
{
|
||||
return level.dog_objectives;
|
||||
}
|
||||
if ( getTime() >= level.dog_objective_next_update )
|
||||
{
|
||||
level.dog_objectives = [];
|
||||
_a478 = level.dog_targets;
|
||||
_k478 = getFirstArrayKey( _a478 );
|
||||
while ( isDefined( _k478 ) )
|
||||
{
|
||||
target = _a478[ _k478 ];
|
||||
ents = getentarray( target, "classname" );
|
||||
_a482 = ents;
|
||||
_k482 = getFirstArrayKey( _a482 );
|
||||
while ( isDefined( _k482 ) )
|
||||
{
|
||||
ent = _a482[ _k482 ];
|
||||
if ( level.gametype == "koth" )
|
||||
{
|
||||
if ( isDefined( ent.targetname ) && ent.targetname == "radiotrigger" )
|
||||
{
|
||||
level.dog_objectives[ level.dog_objectives.size ] = ent;
|
||||
}
|
||||
}
|
||||
else if ( level.gametype == "sd" )
|
||||
{
|
||||
if ( isDefined( ent.targetname ) && ent.targetname == "bombzone" )
|
||||
{
|
||||
level.dog_objectives[ level.dog_objectives.size ] = ent;
|
||||
}
|
||||
}
|
||||
else if ( !isDefined( ent.script_gameobjectname ) )
|
||||
{
|
||||
}
|
||||
else if ( !issubstr( ent.script_gameobjectname, level.gametype ) )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
level.dog_objectives[ level.dog_objectives.size ] = ent;
|
||||
}
|
||||
_k482 = getNextArrayKey( _a482, _k482 );
|
||||
}
|
||||
_k478 = getNextArrayKey( _a478, _k478 );
|
||||
}
|
||||
level.dog_objective_next_update = getTime() + randomintrange( 5000, 10000 );
|
||||
}
|
||||
return level.dog_objectives;
|
||||
}
|
||||
|
||||
dog_patrol_near_enemy()
|
||||
{
|
||||
players = get_players();
|
||||
closest = undefined;
|
||||
distsq = 99999999;
|
||||
_a531 = players;
|
||||
_k531 = getFirstArrayKey( _a531 );
|
||||
while ( isDefined( _k531 ) )
|
||||
{
|
||||
player = _a531[ _k531 ];
|
||||
if ( !isDefined( player ) )
|
||||
{
|
||||
}
|
||||
else if ( !isalive( player ) )
|
||||
{
|
||||
}
|
||||
else if ( player.sessionstate != "playing" )
|
||||
{
|
||||
}
|
||||
else if ( isDefined( self.script_owner ) && player == self.script_owner )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( level.teambased )
|
||||
{
|
||||
if ( player.team == self.aiteam )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( ( getTime() - player.lastfiretime ) > 3000 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if ( !isDefined( closest ) )
|
||||
{
|
||||
closest = player;
|
||||
distsq = distancesquared( self.origin, player.origin );
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
d = distancesquared( self.origin, player.origin );
|
||||
if ( d < distsq )
|
||||
{
|
||||
closest = player;
|
||||
distsq = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
_k531 = getNextArrayKey( _a531, _k531 );
|
||||
}
|
||||
return closest;
|
||||
}
|
||||
|
||||
dog_manager_get_dogs()
|
||||
{
|
||||
dogs = getentarray( "attack_dog", "targetname" );
|
||||
return dogs;
|
||||
}
|
||||
|
||||
dog_owner_kills()
|
||||
{
|
||||
if ( !isDefined( self.script_owner ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self endon( "clear_owner" );
|
||||
self endon( "death" );
|
||||
self.script_owner endon( "disconnect" );
|
||||
while ( 1 )
|
||||
{
|
||||
self waittill( "killed", player );
|
||||
self.script_owner notify( "dog_handler" );
|
||||
}
|
||||
}
|
||||
|
||||
dog_health_regen()
|
||||
{
|
||||
self endon( "death" );
|
||||
interval = 0,5;
|
||||
regen_interval = int( ( self.health / 5 ) * interval );
|
||||
regen_start = 2;
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "damage", damage, attacker, direction, point, type, tagname, modelname, partname, weaponname, idflags );
|
||||
self trackattackerdamage( attacker, weaponname );
|
||||
self thread dog_health_regen_think( regen_start, interval, regen_interval );
|
||||
}
|
||||
}
|
||||
|
||||
trackattackerdamage( attacker, weapon )
|
||||
{
|
||||
if ( isDefined( attacker ) || !isplayer( attacker ) && !isDefined( self.script_owner ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( level.teambased || attacker.team == self.script_owner.team && attacker == self )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( !isDefined( self.attackerdata ) || !isDefined( self.attackers ) )
|
||||
{
|
||||
self.attackerdata = [];
|
||||
self.attackers = [];
|
||||
}
|
||||
if ( !isDefined( self.attackerdata[ attacker.clientid ] ) )
|
||||
{
|
||||
self.attackerclientid[ attacker.clientid ] = spawnstruct();
|
||||
self.attackers[ self.attackers.size ] = attacker;
|
||||
}
|
||||
}
|
||||
|
||||
resetattackerdamage()
|
||||
{
|
||||
self.attackerdata = [];
|
||||
self.attackers = [];
|
||||
}
|
||||
|
||||
dog_health_regen_think( delay, interval, regen_interval )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "damage" );
|
||||
wait delay;
|
||||
step = 0;
|
||||
while ( step <= 5 )
|
||||
{
|
||||
if ( self.health >= 100 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.health += regen_interval;
|
||||
wait interval;
|
||||
step += interval;
|
||||
}
|
||||
}
|
||||
self resetattackerdamage();
|
||||
self.health = 100;
|
||||
}
|
||||
|
||||
selfdefensechallenge()
|
||||
{
|
||||
self waittill( "death", attacker );
|
||||
if ( isDefined( attacker ) && isplayer( attacker ) )
|
||||
{
|
||||
if ( isDefined( self.script_owner ) && self.script_owner == attacker )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( level.teambased && isDefined( self.script_owner ) && self.script_owner.team == attacker.team )
|
||||
{
|
||||
return;
|
||||
}
|
||||
while ( isDefined( self.attackers ) )
|
||||
{
|
||||
_a689 = self.attackers;
|
||||
_k689 = getFirstArrayKey( _a689 );
|
||||
while ( isDefined( _k689 ) )
|
||||
{
|
||||
player = _a689[ _k689 ];
|
||||
if ( player != attacker )
|
||||
{
|
||||
maps/mp/_scoreevents::processscoreevent( "killed_dog_assist", player );
|
||||
}
|
||||
_k689 = getNextArrayKey( _a689, _k689 );
|
||||
}
|
||||
}
|
||||
attacker notify( "selfdefense_dog" );
|
||||
}
|
||||
}
|
||||
|
||||
dog_get_exit_node()
|
||||
{
|
||||
exits = getnodearray( "exit", "script_noteworthy" );
|
||||
return getclosest( self.origin, exits );
|
||||
}
|
||||
|
||||
flash_dogs( area )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
dogs = dog_manager_get_dogs();
|
||||
_a714 = dogs;
|
||||
_k714 = getFirstArrayKey( _a714 );
|
||||
while ( isDefined( _k714 ) )
|
||||
{
|
||||
dog = _a714[ _k714 ];
|
||||
if ( !isalive( dog ) )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( dog istouching( area ) )
|
||||
{
|
||||
do_flash = 1;
|
||||
if ( isplayer( self ) )
|
||||
{
|
||||
if ( level.teambased && dog.aiteam == self.team )
|
||||
{
|
||||
do_flash = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !level.teambased && isDefined( dog.script_owner ) && self == dog.script_owner )
|
||||
{
|
||||
do_flash = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( isDefined( dog.lastflashed ) && ( dog.lastflashed + 1500 ) > getTime() )
|
||||
{
|
||||
do_flash = 0;
|
||||
}
|
||||
if ( do_flash )
|
||||
{
|
||||
dog setflashbanged( 1, 500 );
|
||||
dog.lastflashed = getTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
_k714 = getNextArrayKey( _a714, _k714 );
|
||||
}
|
||||
}
|
||||
|
||||
devgui_dog_think()
|
||||
{
|
||||
/#
|
||||
setdvar( "devgui_dog", "" );
|
||||
debug_patrol = 0;
|
||||
for ( ;; )
|
||||
{
|
||||
cmd = getDvar( "devgui_dog" );
|
||||
switch( cmd )
|
||||
{
|
||||
case "spawn_friendly":
|
||||
player = gethostplayer();
|
||||
devgui_dog_spawn( player.team );
|
||||
break;
|
||||
case "spawn_enemy":
|
||||
player = gethostplayer();
|
||||
_a769 = level.teams;
|
||||
_k769 = getFirstArrayKey( _a769 );
|
||||
while ( isDefined( _k769 ) )
|
||||
{
|
||||
team = _a769[ _k769 ];
|
||||
if ( team == player.team )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
devgui_dog_spawn( team );
|
||||
}
|
||||
_k769 = getNextArrayKey( _a769, _k769 );
|
||||
}
|
||||
case "delete_dogs":
|
||||
level dog_abort();
|
||||
break;
|
||||
case "dog_camera":
|
||||
devgui_dog_camera();
|
||||
break;
|
||||
case "spawn_crate":
|
||||
devgui_crate_spawn();
|
||||
break;
|
||||
case "delete_crates":
|
||||
devgui_crate_delete();
|
||||
break;
|
||||
case "show_spawns":
|
||||
devgui_spawn_show();
|
||||
break;
|
||||
case "show_exits":
|
||||
devgui_exit_show();
|
||||
break;
|
||||
case "debug_route":
|
||||
devgui_debug_route();
|
||||
break;
|
||||
}
|
||||
if ( cmd != "" )
|
||||
{
|
||||
setdvar( "devgui_dog", "" );
|
||||
}
|
||||
wait 0,5;
|
||||
#/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
devgui_dog_spawn( team )
|
||||
{
|
||||
/#
|
||||
player = gethostplayer();
|
||||
dog_spawner = getent( "dog_spawner", "targetname" );
|
||||
level.dog_abort = 0;
|
||||
if ( !isDefined( dog_spawner ) )
|
||||
{
|
||||
iprintln( "No dog spawners found in map" );
|
||||
return;
|
||||
}
|
||||
direction = player getplayerangles();
|
||||
direction_vec = anglesToForward( direction );
|
||||
eye = player geteye();
|
||||
scale = 8000;
|
||||
direction_vec = ( direction_vec[ 0 ] * scale, direction_vec[ 1 ] * scale, direction_vec[ 2 ] * scale );
|
||||
trace = bullettrace( eye, eye + direction_vec, 0, undefined );
|
||||
nodes = getnodesinradius( trace[ "position" ], 256, 0, 128, "Path", 8 );
|
||||
if ( !nodes.size )
|
||||
{
|
||||
iprintln( "No nodes found near crosshair position" );
|
||||
return;
|
||||
}
|
||||
iprintln( "Spawning dog at your crosshair position" );
|
||||
node = getclosest( trace[ "position" ], nodes );
|
||||
dog = dog_manager_spawn_dog( player, player.team, node, 5 );
|
||||
if ( team != player.team )
|
||||
{
|
||||
dog.aiteam = team;
|
||||
dog clearentityowner();
|
||||
dog notify( "clear_owner" );
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
devgui_dog_camera()
|
||||
{
|
||||
/#
|
||||
player = gethostplayer();
|
||||
if ( !isDefined( level.devgui_dog_camera ) )
|
||||
{
|
||||
level.devgui_dog_camera = 0;
|
||||
}
|
||||
dog = undefined;
|
||||
dogs = dog_manager_get_dogs();
|
||||
if ( dogs.size <= 0 )
|
||||
{
|
||||
level.devgui_dog_camera = undefined;
|
||||
player cameraactivate( 0 );
|
||||
return;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < dogs.size )
|
||||
{
|
||||
dog = dogs[ i ];
|
||||
if ( !isDefined( dog ) || !isalive( dog ) )
|
||||
{
|
||||
dog = undefined;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !isDefined( dog.cam ) )
|
||||
{
|
||||
forward = anglesToForward( dog.angles );
|
||||
dog.cam = spawn( "script_model", ( dog.origin + vectorScale( ( 1, 0, 0 ), 50 ) ) + ( forward * -100 ) );
|
||||
dog.cam setmodel( "tag_origin" );
|
||||
dog.cam linkto( dog );
|
||||
}
|
||||
if ( dog getentitynumber() <= level.devgui_dog_camera )
|
||||
{
|
||||
dog = undefined;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if ( isDefined( dog ) )
|
||||
{
|
||||
level.devgui_dog_camera = dog getentitynumber();
|
||||
player camerasetposition( dog.cam );
|
||||
player camerasetlookat( dog );
|
||||
player cameraactivate( 1 );
|
||||
}
|
||||
else level.devgui_dog_camera = undefined;
|
||||
player cameraactivate( 0 );
|
||||
#/
|
||||
}
|
||||
|
||||
devgui_crate_spawn()
|
||||
{
|
||||
/#
|
||||
player = gethostplayer();
|
||||
direction = player getplayerangles();
|
||||
direction_vec = anglesToForward( direction );
|
||||
eye = player geteye();
|
||||
scale = 8000;
|
||||
direction_vec = ( direction_vec[ 0 ] * scale, direction_vec[ 1 ] * scale, direction_vec[ 2 ] * scale );
|
||||
trace = bullettrace( eye, eye + direction_vec, 0, undefined );
|
||||
killcament = spawn( "script_model", player.origin );
|
||||
level thread maps/mp/killstreaks/_supplydrop::dropcrate( trace[ "position" ] + vectorScale( ( 1, 0, 0 ), 25 ), direction, "supplydrop_mp", player, player.team, killcament );
|
||||
#/
|
||||
}
|
||||
|
||||
devgui_crate_delete()
|
||||
{
|
||||
/#
|
||||
if ( !isDefined( level.devgui_crates ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < level.devgui_crates.size )
|
||||
{
|
||||
level.devgui_crates[ i ] delete();
|
||||
i++;
|
||||
}
|
||||
level.devgui_crates = [];
|
||||
#/
|
||||
}
|
||||
|
||||
devgui_spawn_show()
|
||||
{
|
||||
/#
|
||||
if ( !isDefined( level.dog_spawn_show ) )
|
||||
{
|
||||
level.dog_spawn_show = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
level.dog_spawn_show = !level.dog_spawn_show;
|
||||
}
|
||||
if ( !level.dog_spawn_show )
|
||||
{
|
||||
level notify( "hide_dog_spawns" );
|
||||
return;
|
||||
}
|
||||
spawns = getnodearray( "spawn", "script_noteworthy" );
|
||||
color = ( 1, 0, 0 );
|
||||
i = 0;
|
||||
while ( i < spawns.size )
|
||||
{
|
||||
maps/mp/gametypes/_dev::showonespawnpoint( spawns[ i ], color, "hide_dog_spawns", 32, "dog_spawn" );
|
||||
i++;
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
devgui_exit_show()
|
||||
{
|
||||
/#
|
||||
if ( !isDefined( level.dog_exit_show ) )
|
||||
{
|
||||
level.dog_exit_show = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
level.dog_exit_show = !level.dog_exit_show;
|
||||
}
|
||||
if ( !level.dog_exit_show )
|
||||
{
|
||||
level notify( "hide_dog_exits" );
|
||||
return;
|
||||
}
|
||||
exits = getnodearray( "exit", "script_noteworthy" );
|
||||
color = ( 1, 0, 0 );
|
||||
i = 0;
|
||||
while ( i < exits.size )
|
||||
{
|
||||
maps/mp/gametypes/_dev::showonespawnpoint( exits[ i ], color, "hide_dog_exits", 32, "dog_exit" );
|
||||
i++;
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
dog_debug_patrol( node1, node2 )
|
||||
{
|
||||
/#
|
||||
self endon( "death" );
|
||||
self endon( "debug_patrol" );
|
||||
for ( ;; )
|
||||
{
|
||||
self setgoalnode( node1 );
|
||||
self waittill_any( "goal", "bad_path" );
|
||||
wait 1;
|
||||
self setgoalnode( node2 );
|
||||
self waittill_any( "goal", "bad_path" );
|
||||
wait 1;
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
devgui_debug_route()
|
||||
{
|
||||
/#
|
||||
iprintln( "Choose nodes with 'A' or press 'B' to cancel" );
|
||||
nodes = maps/mp/gametypes/_dev::dev_get_node_pair();
|
||||
if ( !isDefined( nodes ) )
|
||||
{
|
||||
iprintln( "Route Debug Cancelled" );
|
||||
return;
|
||||
}
|
||||
iprintln( "Sending dog to chosen nodes" );
|
||||
dogs = dog_manager_get_dogs();
|
||||
if ( isDefined( dogs[ 0 ] ) )
|
||||
{
|
||||
dogs[ 0 ] notify( "debug_patrol" );
|
||||
dogs[ 0 ] thread dog_debug_patrol( nodes[ 0 ], nodes[ 1 ] );
|
||||
#/
|
||||
}
|
||||
}
|
20
Multiplayer Core/patch_mp/codescripts/character_mp.gsc
Normal file
20
Multiplayer Core/patch_mp/codescripts/character_mp.gsc
Normal file
@ -0,0 +1,20 @@
|
||||
//checked includes matches cerberus output
|
||||
#include codescripts/character;
|
||||
|
||||
setmodelfromarray( a ) //checked matches cerberus output
|
||||
{
|
||||
self setmodel( a[ randomint( a.size ) ] );
|
||||
}
|
||||
|
||||
precachemodelarray( a ) //checked changed to match cerberus output
|
||||
{
|
||||
for ( i = 0; i < a.size; i++ )
|
||||
{
|
||||
precachemodel( a[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
attachfromarray( a ) //checked matches cerberus output
|
||||
{
|
||||
self attach( codescripts/character::randomelement( a ), "", 1 );
|
||||
}
|
27
Multiplayer Core/patch_mp/codescripts/delete.gsc
Normal file
27
Multiplayer Core/patch_mp/codescripts/delete.gsc
Normal file
@ -0,0 +1,27 @@
|
||||
|
||||
main() //checked changed to match cerberus output
|
||||
{
|
||||
/*
|
||||
/#
|
||||
assert( isDefined( self ) );
|
||||
#/
|
||||
*/
|
||||
wait 0;
|
||||
if ( isDefined( self ) )
|
||||
{
|
||||
/*
|
||||
/#
|
||||
if ( isDefined( self.classname ) )
|
||||
{
|
||||
if ( self.classname == "trigger_once" || self.classname == "trigger_radius" || self.classname == "trigger_multiple" )
|
||||
{
|
||||
println( "" );
|
||||
println( "*** trigger debug: delete.gsc is deleting trigger with ent#: " + self getentitynumber() + " at origin: " + self.origin );
|
||||
println( "" );
|
||||
#/
|
||||
}
|
||||
}
|
||||
*/
|
||||
self delete();
|
||||
}
|
||||
}
|
29
Multiplayer Core/patch_mp/codescripts/struct.gsc
Normal file
29
Multiplayer Core/patch_mp/codescripts/struct.gsc
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
initstructs() //checked matches cerberus output
|
||||
{
|
||||
level.struct = [];
|
||||
}
|
||||
|
||||
createstruct() //checked matches cerberus output
|
||||
{
|
||||
struct = spawnstruct();
|
||||
level.struct[ level.struct.size ] = struct;
|
||||
return struct;
|
||||
}
|
||||
|
||||
findstruct( position ) //checked changed to match cerberus output see info.md
|
||||
{
|
||||
foreach ( key in level.struct_class_names )
|
||||
{
|
||||
foreach ( s_array in level.struct_class_names[ key ] )
|
||||
{
|
||||
foreach ( struct in s_array )
|
||||
{
|
||||
if(distancesquared( struct.origin, position ) < 1 )
|
||||
{
|
||||
return struct;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2011
Multiplayer Core/patch_mp/common_scripts/utility.gsc
Normal file
2011
Multiplayer Core/patch_mp/common_scripts/utility.gsc
Normal file
File diff suppressed because it is too large
Load Diff
159
Multiplayer Core/patch_mp/maps/mp/_acousticsensor.gsc
Normal file
159
Multiplayer Core/patch_mp/maps/mp/_acousticsensor.gsc
Normal file
@ -0,0 +1,159 @@
|
||||
//checked includes match cerberus output
|
||||
#include maps/mp/gametypes/_damagefeedback;
|
||||
#include maps/mp/gametypes/_globallogic_player;
|
||||
#include maps/mp/_scoreevents;
|
||||
#include maps/mp/_challenges;
|
||||
#include maps/mp/killstreaks/_emp;
|
||||
#include maps/mp/_utility;
|
||||
#include maps/mp/gametypes/_weaponobjects;
|
||||
#include common_scripts/utility;
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
level._effect[ "acousticsensor_enemy_light" ] = loadfx( "misc/fx_equip_light_red" );
|
||||
level._effect[ "acousticsensor_friendly_light" ] = loadfx( "misc/fx_equip_light_green" );
|
||||
}
|
||||
|
||||
createacousticsensorwatcher() //checked matches cerberus output
|
||||
{
|
||||
watcher = self maps/mp/gametypes/_weaponobjects::createuseweaponobjectwatcher( "acoustic_sensor", "acoustic_sensor_mp", self.team );
|
||||
watcher.onspawn = ::onspawnacousticsensor;
|
||||
watcher.detonate = ::acousticsensordetonate;
|
||||
watcher.stun = maps/mp/gametypes/_weaponobjects::weaponstun;
|
||||
watcher.stuntime = 5;
|
||||
watcher.reconmodel = "t5_weapon_acoustic_sensor_world_detect";
|
||||
watcher.hackable = 1;
|
||||
watcher.ondamage = ::watchacousticsensordamage;
|
||||
}
|
||||
|
||||
onspawnacousticsensor( watcher, player ) //checked matches cerberus output
|
||||
{
|
||||
self endon( "death" );
|
||||
self thread maps/mp/gametypes/_weaponobjects::onspawnuseweaponobject( watcher, player );
|
||||
player.acousticsensor = self;
|
||||
self setowner( player );
|
||||
self setteam( player.team );
|
||||
self.owner = player;
|
||||
self playloopsound( "fly_acoustic_sensor_lp" );
|
||||
if ( !self maps/mp/_utility::ishacked() )
|
||||
{
|
||||
player addweaponstat( "acoustic_sensor_mp", "used", 1 );
|
||||
}
|
||||
self thread watchshutdown( player, self.origin );
|
||||
}
|
||||
|
||||
acousticsensordetonate( attacker, weaponname ) //checked matches cerberus output
|
||||
{
|
||||
from_emp = maps/mp/killstreaks/_emp::isempweapon( weaponname );
|
||||
if ( !from_emp )
|
||||
{
|
||||
playfx( level._equipment_explode_fx, self.origin );
|
||||
}
|
||||
if ( isDefined( attacker ) )
|
||||
{
|
||||
if ( self.owner isenemyplayer( attacker ) )
|
||||
{
|
||||
attacker maps/mp/_challenges::destroyedequipment( weaponname );
|
||||
maps/mp/_scoreevents::processscoreevent( "destroyed_motion_sensor", attacker, self.owner, weaponname );
|
||||
}
|
||||
}
|
||||
playsoundatposition( "dst_equipment_destroy", self.origin );
|
||||
self destroyent();
|
||||
}
|
||||
|
||||
destroyent() //checked matches cerberus output
|
||||
{
|
||||
self delete();
|
||||
}
|
||||
|
||||
watchshutdown( player, origin ) //checked matches cerberus output
|
||||
{
|
||||
self waittill_any( "death", "hacked" );
|
||||
if ( isDefined( player ) )
|
||||
{
|
||||
player.acousticsensor = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
watchacousticsensordamage( watcher ) //checked changed to match cerberus output
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "hacked" );
|
||||
self setcandamage( 1 );
|
||||
damagemax = 100;
|
||||
if ( !self maps/mp/_utility::ishacked() )
|
||||
{
|
||||
self.damagetaken = 0;
|
||||
}
|
||||
while ( 1 )
|
||||
{
|
||||
self.maxhealth = 100000;
|
||||
self.health = self.maxhealth;
|
||||
self waittill( "damage", damage, attacker, direction, point, type, tagname, modelname, partname, weaponname, idflags );
|
||||
if ( !isDefined( attacker ) || !isplayer( attacker ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( level.teambased && attacker.team == self.owner.team && attacker != self.owner )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( isDefined( weaponname ) )
|
||||
{
|
||||
switch( weaponname )
|
||||
{
|
||||
case "concussion_grenade_mp":
|
||||
case "flash_grenade_mp":
|
||||
if ( watcher.stuntime > 0 )
|
||||
{
|
||||
self thread maps/mp/gametypes/_weaponobjects::stunstart( watcher, watcher.stuntime );
|
||||
}
|
||||
if ( level.teambased && self.owner.team != attacker.team )
|
||||
{
|
||||
if ( maps/mp/gametypes/_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
{
|
||||
attacker maps/mp/gametypes/_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
}
|
||||
else if ( !level.teambased && self.owner != attacker )
|
||||
{
|
||||
if ( maps/mp/gametypes/_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
{
|
||||
attacker maps/mp/gametypes/_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
}
|
||||
continue;
|
||||
case "emp_grenade_mp":
|
||||
damage = damagemax;
|
||||
default:
|
||||
if ( maps/mp/gametypes/_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
{
|
||||
attacker maps/mp/gametypes/_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
weaponname = "";
|
||||
}
|
||||
if ( isplayer( attacker ) && level.teambased && isDefined( attacker.team ) && self.owner.team == attacker.team && attacker != self.owner )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( type == "MOD_MELEE" )
|
||||
{
|
||||
self.damagetaken = damagemax;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.damagetaken += damage;
|
||||
}
|
||||
if ( self.damagetaken >= damagemax )
|
||||
{
|
||||
watcher thread maps/mp/gametypes/_weaponobjects::waitanddetonate( self, 0, attacker, weaponname );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
497
Multiplayer Core/patch_mp/maps/mp/_art.gsc
Normal file
497
Multiplayer Core/patch_mp/maps/mp/_art.gsc
Normal file
@ -0,0 +1,497 @@
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
|
||||
main()
|
||||
{
|
||||
/#
|
||||
if ( getDvar( "scr_art_tweak" ) == "" || getDvar( "scr_art_tweak" ) == "0" )
|
||||
{
|
||||
setdvar( "scr_art_tweak", 0 );
|
||||
}
|
||||
if ( getDvar( "scr_dof_enable" ) == "" )
|
||||
{
|
||||
setdvar( "scr_dof_enable", "1" );
|
||||
}
|
||||
if ( getDvar( "scr_cinematic_autofocus" ) == "" )
|
||||
{
|
||||
setdvar( "scr_cinematic_autofocus", "1" );
|
||||
}
|
||||
if ( getDvar( "scr_art_visionfile" ) == "" && isDefined( level.script ) )
|
||||
{
|
||||
setdvar( "scr_art_visionfile", level.script );
|
||||
}
|
||||
if ( getDvar( "debug_reflection" ) == "" )
|
||||
{
|
||||
setdvar( "debug_reflection", "0" );
|
||||
}
|
||||
if ( getDvar( "debug_reflection_matte" ) == "" )
|
||||
{
|
||||
setdvar( "debug_reflection_matte", "0" );
|
||||
}
|
||||
if ( getDvar( "debug_color_pallete" ) == "" )
|
||||
{
|
||||
setdvar( "debug_color_pallete", "0" );
|
||||
}
|
||||
precachemodel( "test_sphere_lambert" );
|
||||
precachemodel( "test_macbeth_chart" );
|
||||
precachemodel( "test_macbeth_chart_unlit" );
|
||||
precachemodel( "test_sphere_silver" );
|
||||
level thread debug_reflection();
|
||||
level thread debug_reflection_matte();
|
||||
level thread debug_color_pallete();
|
||||
#/
|
||||
if ( !isDefined( level.dofdefault ) )
|
||||
{
|
||||
level.dofdefault[ "nearStart" ] = 0;
|
||||
level.dofdefault[ "nearEnd" ] = 1;
|
||||
level.dofdefault[ "farStart" ] = 8000;
|
||||
level.dofdefault[ "farEnd" ] = 10000;
|
||||
level.dofdefault[ "nearBlur" ] = 6;
|
||||
level.dofdefault[ "farBlur" ] = 0;
|
||||
}
|
||||
level.curdof = ( level.dofdefault[ "farStart" ] - level.dofdefault[ "nearEnd" ] ) / 2;
|
||||
/#
|
||||
thread tweakart();
|
||||
#/
|
||||
if ( !isDefined( level.script ) )
|
||||
{
|
||||
level.script = tolower( getDvar( "mapname" ) );
|
||||
}
|
||||
}
|
||||
|
||||
artfxprintln( file, string )
|
||||
{
|
||||
/#
|
||||
if ( file == -1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
fprintln( file, string );
|
||||
#/
|
||||
}
|
||||
|
||||
strtok_loc( string, par1 )
|
||||
{
|
||||
stringlist = [];
|
||||
indexstring = "";
|
||||
i = 0;
|
||||
while ( i < string.size )
|
||||
{
|
||||
if ( string[ i ] == " " )
|
||||
{
|
||||
stringlist[ stringlist.size ] = indexstring;
|
||||
indexstring = "";
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
indexstring += string[ i ];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if ( indexstring.size )
|
||||
{
|
||||
stringlist[ stringlist.size ] = indexstring;
|
||||
}
|
||||
return stringlist;
|
||||
}
|
||||
|
||||
setfogsliders()
|
||||
{
|
||||
fogall = strtok_loc( getDvar( "g_fogColorReadOnly" ), " " );
|
||||
red = fogall[ 0 ];
|
||||
green = fogall[ 1 ];
|
||||
blue = fogall[ 2 ];
|
||||
halfplane = getDvar( "g_fogHalfDistReadOnly" );
|
||||
nearplane = getDvar( "g_fogStartDistReadOnly" );
|
||||
if ( isDefined( red ) && isDefined( green ) || !isDefined( blue ) && !isDefined( halfplane ) )
|
||||
{
|
||||
red = 1;
|
||||
green = 1;
|
||||
blue = 1;
|
||||
halfplane = 10000001;
|
||||
nearplane = 10000000;
|
||||
}
|
||||
setdvar( "scr_fog_exp_halfplane", halfplane );
|
||||
setdvar( "scr_fog_nearplane", nearplane );
|
||||
setdvar( "scr_fog_color", ( red + " " ) + green + " " + blue );
|
||||
}
|
||||
|
||||
tweakart()
|
||||
{
|
||||
/#
|
||||
if ( !isDefined( level.tweakfile ) )
|
||||
{
|
||||
level.tweakfile = 0;
|
||||
}
|
||||
if ( getDvar( "scr_fog_baseheight" ) == "" )
|
||||
{
|
||||
setdvar( "scr_fog_exp_halfplane", "500" );
|
||||
setdvar( "scr_fog_exp_halfheight", "500" );
|
||||
setdvar( "scr_fog_nearplane", "0" );
|
||||
setdvar( "scr_fog_baseheight", "0" );
|
||||
}
|
||||
setdvar( "scr_fog_fraction", "1.0" );
|
||||
setdvar( "scr_art_dump", "0" );
|
||||
setdvar( "scr_art_sun_fog_dir_set", "0" );
|
||||
setdvar( "scr_dof_nearStart", level.dofdefault[ "nearStart" ] );
|
||||
setdvar( "scr_dof_nearEnd", level.dofdefault[ "nearEnd" ] );
|
||||
setdvar( "scr_dof_farStart", level.dofdefault[ "farStart" ] );
|
||||
setdvar( "scr_dof_farEnd", level.dofdefault[ "farEnd" ] );
|
||||
setdvar( "scr_dof_nearBlur", level.dofdefault[ "nearBlur" ] );
|
||||
setdvar( "scr_dof_farBlur", level.dofdefault[ "farBlur" ] );
|
||||
file = undefined;
|
||||
filename = undefined;
|
||||
tweak_toggle = 1;
|
||||
for ( ;; )
|
||||
{
|
||||
while ( getDvarInt( "scr_art_tweak" ) == 0 )
|
||||
{
|
||||
tweak_toggle = 1;
|
||||
wait 0,05;
|
||||
}
|
||||
if ( tweak_toggle )
|
||||
{
|
||||
tweak_toggle = 0;
|
||||
fogsettings = getfogsettings();
|
||||
setdvar( "scr_fog_nearplane", fogsettings[ 0 ] );
|
||||
setdvar( "scr_fog_exp_halfplane", fogsettings[ 1 ] );
|
||||
setdvar( "scr_fog_exp_halfheight", fogsettings[ 3 ] );
|
||||
setdvar( "scr_fog_baseheight", fogsettings[ 2 ] );
|
||||
setdvar( "scr_fog_color", fogsettings[ 4 ] + " " + fogsettings[ 5 ] + " " + fogsettings[ 6 ] );
|
||||
setdvar( "scr_fog_color_scale", fogsettings[ 7 ] );
|
||||
setdvar( "scr_sun_fog_color", fogsettings[ 8 ] + " " + fogsettings[ 9 ] + " " + fogsettings[ 10 ] );
|
||||
level.fogsundir = [];
|
||||
level.fogsundir[ 0 ] = fogsettings[ 11 ];
|
||||
level.fogsundir[ 1 ] = fogsettings[ 12 ];
|
||||
level.fogsundir[ 2 ] = fogsettings[ 13 ];
|
||||
setdvar( "scr_sun_fog_start_angle", fogsettings[ 14 ] );
|
||||
setdvar( "scr_sun_fog_end_angle", fogsettings[ 15 ] );
|
||||
setdvar( "scr_fog_max_opacity", fogsettings[ 16 ] );
|
||||
}
|
||||
level.fogexphalfplane = getDvarFloat( "scr_fog_exp_halfplane" );
|
||||
level.fogexphalfheight = getDvarFloat( "scr_fog_exp_halfheight" );
|
||||
level.fognearplane = getDvarFloat( "scr_fog_nearplane" );
|
||||
level.fogbaseheight = getDvarFloat( "scr_fog_baseheight" );
|
||||
level.fogcolorred = getDvarColorRed( "scr_fog_color" );
|
||||
level.fogcolorgreen = getDvarColorGreen( "scr_fog_color" );
|
||||
level.fogcolorblue = getDvarColorBlue( "scr_fog_color" );
|
||||
level.fogcolorscale = getDvarFloat( "scr_fog_color_scale" );
|
||||
level.sunfogcolorred = getDvarColorRed( "scr_sun_fog_color" );
|
||||
level.sunfogcolorgreen = getDvarColorGreen( "scr_sun_fog_color" );
|
||||
level.sunfogcolorblue = getDvarColorBlue( "scr_sun_fog_color" );
|
||||
level.sunstartangle = getDvarFloat( "scr_sun_fog_start_angle" );
|
||||
level.sunendangle = getDvarFloat( "scr_sun_fog_end_angle" );
|
||||
level.fogmaxopacity = getDvarFloat( "scr_fog_max_opacity" );
|
||||
if ( getDvarInt( "scr_art_sun_fog_dir_set" ) )
|
||||
{
|
||||
setdvar( "scr_art_sun_fog_dir_set", "0" );
|
||||
println( "Setting sun fog direction to facing of player" );
|
||||
players = get_players();
|
||||
dir = vectornormalize( anglesToForward( players[ 0 ] getplayerangles() ) );
|
||||
level.fogsundir = [];
|
||||
level.fogsundir[ 0 ] = dir[ 0 ];
|
||||
level.fogsundir[ 1 ] = dir[ 1 ];
|
||||
level.fogsundir[ 2 ] = dir[ 2 ];
|
||||
}
|
||||
fovslidercheck();
|
||||
dumpsettings();
|
||||
if ( !getDvarInt( "scr_fog_disable" ) )
|
||||
{
|
||||
if ( !isDefined( level.fogsundir ) )
|
||||
{
|
||||
level.fogsundir = [];
|
||||
level.fogsundir[ 0 ] = 1;
|
||||
level.fogsundir[ 1 ] = 0;
|
||||
level.fogsundir[ 2 ] = 0;
|
||||
}
|
||||
setvolfog( level.fognearplane, level.fogexphalfplane, level.fogexphalfheight, level.fogbaseheight, level.fogcolorred, level.fogcolorgreen, level.fogcolorblue, level.fogcolorscale, level.sunfogcolorred, level.sunfogcolorgreen, level.sunfogcolorblue, level.fogsundir[ 0 ], level.fogsundir[ 1 ], level.fogsundir[ 2 ], level.sunstartangle, level.sunendangle, 0, level.fogmaxopacity );
|
||||
}
|
||||
else
|
||||
{
|
||||
setexpfog( 100000000, 100000001, 0, 0, 0, 0 );
|
||||
}
|
||||
wait 0,1;
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
fovslidercheck()
|
||||
{
|
||||
if ( level.dofdefault[ "nearStart" ] >= level.dofdefault[ "nearEnd" ] )
|
||||
{
|
||||
level.dofdefault[ "nearStart" ] = level.dofdefault[ "nearEnd" ] - 1;
|
||||
setdvar( "scr_dof_nearStart", level.dofdefault[ "nearStart" ] );
|
||||
}
|
||||
if ( level.dofdefault[ "nearEnd" ] <= level.dofdefault[ "nearStart" ] )
|
||||
{
|
||||
level.dofdefault[ "nearEnd" ] = level.dofdefault[ "nearStart" ] + 1;
|
||||
setdvar( "scr_dof_nearEnd", level.dofdefault[ "nearEnd" ] );
|
||||
}
|
||||
if ( level.dofdefault[ "farStart" ] >= level.dofdefault[ "farEnd" ] )
|
||||
{
|
||||
level.dofdefault[ "farStart" ] = level.dofdefault[ "farEnd" ] - 1;
|
||||
setdvar( "scr_dof_farStart", level.dofdefault[ "farStart" ] );
|
||||
}
|
||||
if ( level.dofdefault[ "farEnd" ] <= level.dofdefault[ "farStart" ] )
|
||||
{
|
||||
level.dofdefault[ "farEnd" ] = level.dofdefault[ "farStart" ] + 1;
|
||||
setdvar( "scr_dof_farEnd", level.dofdefault[ "farEnd" ] );
|
||||
}
|
||||
if ( level.dofdefault[ "farBlur" ] >= level.dofdefault[ "nearBlur" ] )
|
||||
{
|
||||
level.dofdefault[ "farBlur" ] = level.dofdefault[ "nearBlur" ] - 0,1;
|
||||
setdvar( "scr_dof_farBlur", level.dofdefault[ "farBlur" ] );
|
||||
}
|
||||
if ( level.dofdefault[ "farStart" ] <= level.dofdefault[ "nearEnd" ] )
|
||||
{
|
||||
level.dofdefault[ "farStart" ] = level.dofdefault[ "nearEnd" ] + 1;
|
||||
setdvar( "scr_dof_farStart", level.dofdefault[ "farStart" ] );
|
||||
}
|
||||
}
|
||||
|
||||
dumpsettings()
|
||||
{
|
||||
/#
|
||||
if ( getDvar( "scr_art_dump" ) != "0" )
|
||||
{
|
||||
println( "\tstart_dist = " + level.fognearplane + ";" );
|
||||
println( "\thalf_dist = " + level.fogexphalfplane + ";" );
|
||||
println( "\thalf_height = " + level.fogexphalfheight + ";" );
|
||||
println( "\tbase_height = " + level.fogbaseheight + ";" );
|
||||
println( "\tfog_r = " + level.fogcolorred + ";" );
|
||||
println( "\tfog_g = " + level.fogcolorgreen + ";" );
|
||||
println( "\tfog_b = " + level.fogcolorblue + ";" );
|
||||
println( "\tfog_scale = " + level.fogcolorscale + ";" );
|
||||
println( "\tsun_col_r = " + level.sunfogcolorred + ";" );
|
||||
println( "\tsun_col_g = " + level.sunfogcolorgreen + ";" );
|
||||
println( "\tsun_col_b = " + level.sunfogcolorblue + ";" );
|
||||
println( "\tsun_dir_x = " + level.fogsundir[ 0 ] + ";" );
|
||||
println( "\tsun_dir_y = " + level.fogsundir[ 1 ] + ";" );
|
||||
println( "\tsun_dir_z = " + level.fogsundir[ 2 ] + ";" );
|
||||
println( "\tsun_start_ang = " + level.sunstartangle + ";" );
|
||||
println( "\tsun_stop_ang = " + level.sunendangle + ";" );
|
||||
println( "\ttime = 0;" );
|
||||
println( "\tmax_fog_opacity = " + level.fogmaxopacity + ";" );
|
||||
println( "" );
|
||||
println( "\tsetVolFog(start_dist, half_dist, half_height, base_height, fog_r, fog_g, fog_b, fog_scale," );
|
||||
println( "\t\tsun_col_r, sun_col_g, sun_col_b, sun_dir_x, sun_dir_y, sun_dir_z, sun_start_ang, " );
|
||||
println( "\t\tsun_stop_ang, time, max_fog_opacity);" );
|
||||
setdvar( "scr_art_dump", "0" );
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
debug_reflection()
|
||||
{
|
||||
/#
|
||||
level.debug_reflection = 0;
|
||||
while ( 1 )
|
||||
{
|
||||
wait 0,1;
|
||||
if ( getDvar( "debug_reflection" ) == "2" || level.debug_reflection != 2 && getDvar( "debug_reflection" ) == "3" && level.debug_reflection != 3 )
|
||||
{
|
||||
remove_reflection_objects();
|
||||
if ( getDvar( "debug_reflection" ) == "2" )
|
||||
{
|
||||
create_reflection_objects();
|
||||
level.debug_reflection = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
create_reflection_objects();
|
||||
create_reflection_object();
|
||||
level.debug_reflection = 3;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( getDvar( "debug_reflection" ) == "1" && level.debug_reflection != 1 )
|
||||
{
|
||||
setdvar( "debug_reflection_matte", "0" );
|
||||
setdvar( "debug_color_pallete", "0" );
|
||||
remove_reflection_objects();
|
||||
create_reflection_object();
|
||||
level.debug_reflection = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( getDvar( "debug_reflection" ) == "0" && level.debug_reflection != 0 )
|
||||
{
|
||||
remove_reflection_objects();
|
||||
level.debug_reflection = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
remove_reflection_objects()
|
||||
{
|
||||
/#
|
||||
if ( level.debug_reflection != 2 && level.debug_reflection == 3 && isDefined( level.debug_reflection_objects ) )
|
||||
{
|
||||
i = 0;
|
||||
while ( i < level.debug_reflection_objects.size )
|
||||
{
|
||||
level.debug_reflection_objects[ i ] delete();
|
||||
i++;
|
||||
}
|
||||
level.debug_reflection_objects = undefined;
|
||||
}
|
||||
if ( level.debug_reflection != 1 && level.debug_reflection != 3 && level.debug_reflection_matte != 1 || level.debug_color_pallete == 1 && level.debug_color_pallete == 2 )
|
||||
{
|
||||
if ( isDefined( level.debug_reflectionobject ) )
|
||||
{
|
||||
level.debug_reflectionobject delete();
|
||||
#/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
create_reflection_objects()
|
||||
{
|
||||
/#
|
||||
reflection_locs = getreflectionlocs();
|
||||
i = 0;
|
||||
while ( i < reflection_locs.size )
|
||||
{
|
||||
level.debug_reflection_objects[ i ] = spawn( "script_model", reflection_locs[ i ] );
|
||||
level.debug_reflection_objects[ i ] setmodel( "test_sphere_silver" );
|
||||
i++;
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
create_reflection_object( model )
|
||||
{
|
||||
if ( !isDefined( model ) )
|
||||
{
|
||||
model = "test_sphere_silver";
|
||||
}
|
||||
/#
|
||||
if ( isDefined( level.debug_reflectionobject ) )
|
||||
{
|
||||
level.debug_reflectionobject delete();
|
||||
}
|
||||
players = get_players();
|
||||
player = players[ 0 ];
|
||||
level.debug_reflectionobject = spawn( "script_model", player geteye() + vectorScale( anglesToForward( player.angles ), 100 ) );
|
||||
level.debug_reflectionobject setmodel( model );
|
||||
level.debug_reflectionobject.origin = player geteye() + vectorScale( anglesToForward( player getplayerangles() ), 100 );
|
||||
level.debug_reflectionobject linkto( player );
|
||||
thread debug_reflection_buttons();
|
||||
#/
|
||||
}
|
||||
|
||||
debug_reflection_buttons()
|
||||
{
|
||||
/#
|
||||
level notify( "new_reflection_button_running" );
|
||||
level endon( "new_reflection_button_running" );
|
||||
level.debug_reflectionobject endon( "death" );
|
||||
offset = 100;
|
||||
lastoffset = offset;
|
||||
while ( getDvar( "debug_reflection" ) != "1" && getDvar( "debug_reflection" ) != "3" && getDvar( "debug_reflection_matte" ) != "1" || getDvar( "debug_color_pallete" ) == "1" && getDvar( "debug_color_pallete" ) == "2" )
|
||||
{
|
||||
players = get_players();
|
||||
if ( players[ 0 ] buttonpressed( "BUTTON_X" ) )
|
||||
{
|
||||
offset += 50;
|
||||
}
|
||||
if ( players[ 0 ] buttonpressed( "BUTTON_Y" ) )
|
||||
{
|
||||
offset -= 50;
|
||||
}
|
||||
if ( offset > 1000 )
|
||||
{
|
||||
offset = 1000;
|
||||
}
|
||||
if ( offset < 64 )
|
||||
{
|
||||
offset = 64;
|
||||
}
|
||||
level.debug_reflectionobject unlink();
|
||||
level.debug_reflectionobject.origin = players[ 0 ] geteye() + vectorScale( anglesToForward( players[ 0 ] getplayerangles() ), offset );
|
||||
temp_angles = vectorToAngle( players[ 0 ].origin - level.debug_reflectionobject.origin );
|
||||
level.debug_reflectionobject.angles = ( 0, temp_angles[ 1 ], 0 );
|
||||
lastoffset = offset;
|
||||
line( level.debug_reflectionobject.origin, getreflectionorigin( level.debug_reflectionobject.origin ), ( 1, 0, 0 ), 1, 1 );
|
||||
wait 0,05;
|
||||
if ( isDefined( level.debug_reflectionobject ) )
|
||||
{
|
||||
level.debug_reflectionobject linkto( players[ 0 ] );
|
||||
}
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
debug_reflection_matte()
|
||||
{
|
||||
/#
|
||||
level.debug_reflection_matte = 0;
|
||||
while ( 1 )
|
||||
{
|
||||
wait 0,1;
|
||||
if ( getDvar( "debug_reflection_matte" ) == "1" && level.debug_reflection_matte != 1 )
|
||||
{
|
||||
setdvar( "debug_reflection", "0" );
|
||||
setdvar( "debug_color_pallete", "0" );
|
||||
remove_reflection_objects();
|
||||
create_reflection_object( "test_sphere_lambert" );
|
||||
level.debug_reflection_matte = 1;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( getDvar( "debug_reflection_matte" ) == "0" && level.debug_reflection_matte != 0 )
|
||||
{
|
||||
remove_reflection_objects();
|
||||
level.debug_reflection_matte = 0;
|
||||
}
|
||||
}
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
debug_color_pallete()
|
||||
{
|
||||
/#
|
||||
level.debug_color_pallete = 0;
|
||||
while ( 1 )
|
||||
{
|
||||
wait 0,1;
|
||||
if ( getDvar( "debug_color_pallete" ) == "1" && level.debug_color_pallete != 1 )
|
||||
{
|
||||
setdvar( "debug_reflection", "0" );
|
||||
setdvar( "debug_reflection_matte", "0" );
|
||||
remove_reflection_objects();
|
||||
create_reflection_object( "test_macbeth_chart" );
|
||||
level.debug_color_pallete = 1;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( getDvar( "debug_color_pallete" ) == "2" && level.debug_color_pallete != 2 )
|
||||
{
|
||||
remove_reflection_objects();
|
||||
create_reflection_object( "test_macbeth_chart_unlit" );
|
||||
level.debug_color_pallete = 2;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( getDvar( "debug_color_pallete" ) == "0" && level.debug_color_pallete != 0 )
|
||||
{
|
||||
remove_reflection_objects();
|
||||
level.debug_color_pallete = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#/
|
||||
}
|
||||
}
|
143
Multiplayer Core/patch_mp/maps/mp/_audio.gsc
Normal file
143
Multiplayer Core/patch_mp/maps/mp/_audio.gsc
Normal file
@ -0,0 +1,143 @@
|
||||
//checked includes match cerberus output
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
}
|
||||
|
||||
wait_until_first_player() //checked changed to match cerberus output
|
||||
{
|
||||
players = get_players();
|
||||
if ( !isDefined( players[ 0 ] ) )
|
||||
{
|
||||
level waittill( "first_player_ready" );
|
||||
}
|
||||
players = get_players();
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
players[ i ] thread monitor_player_sprint();
|
||||
}
|
||||
}
|
||||
|
||||
stand_think( trig ) //checked matches cerberus output
|
||||
{
|
||||
killtext = "kill_stand_think" + trig getentitynumber();
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self endon( killtext );
|
||||
while ( 1 )
|
||||
{
|
||||
if ( self.player_is_moving )
|
||||
{
|
||||
trig playsound( trig.script_label );
|
||||
}
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
|
||||
monitor_player_sprint() //checked matches cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self thread monitor_player_movement();
|
||||
self._is_sprinting = 0;
|
||||
while ( 1 )
|
||||
{
|
||||
self waittill( "sprint_begin" );
|
||||
self._is_sprinting = 1;
|
||||
self waittill( "sprint_end" );
|
||||
self._is_sprinting = 0;
|
||||
}
|
||||
}
|
||||
|
||||
monitor_player_movement() //checked matches cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
while ( 1 )
|
||||
{
|
||||
org_1 = self.origin;
|
||||
wait 1;
|
||||
org_2 = self.origin;
|
||||
distancemoved = distancesquared( org_1, org_2 );
|
||||
if ( distancemoved > 4096 )
|
||||
{
|
||||
self.player_is_moving = 1;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.player_is_moving = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
thread_enter_exit_sound( trig ) //checked matches cerberus output
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
trig.touchingplayers[ self getentitynumber() ] = 1;
|
||||
if ( isDefined( trig.script_sound ) && trig.script_activated && self._is_sprinting )
|
||||
{
|
||||
self playsound( trig.script_sound );
|
||||
}
|
||||
self thread stand_think( trig );
|
||||
while ( self istouching( trig ) )
|
||||
{
|
||||
wait 0.1;
|
||||
}
|
||||
self notify( "kill_stand_think" + trig getentitynumber() );
|
||||
self playsound( trig.script_noteworthy );
|
||||
trig.touchingplayers[ self getentitynumber() ] = 0;
|
||||
}
|
||||
|
||||
thread_step_trigger() //checked changed to match cerberus output
|
||||
{
|
||||
if ( !isDefined( self.script_activated ) )
|
||||
{
|
||||
self.script_activated = 1;
|
||||
}
|
||||
if ( !isDefined( self.touchingplayers ) )
|
||||
{
|
||||
self.touchingplayers = [];
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
self.touchingplayers[ i ] = 0;
|
||||
}
|
||||
}
|
||||
while ( 1 )
|
||||
{
|
||||
self waittill( "trigger", who );
|
||||
if ( self.touchingplayers[ who getentitynumber() ] == 0 )
|
||||
{
|
||||
who thread thread_enter_exit_sound( self );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
disable_bump_trigger( triggername ) //checked changed to match cerberus output
|
||||
{
|
||||
triggers = getentarray( "audio_bump_trigger", "targetname" );
|
||||
if ( isDefined( triggers ) )
|
||||
{
|
||||
for ( i = 0; i < triggers.size; i++ )
|
||||
{
|
||||
if ( isDefined( triggers[ i ].script_label ) && triggers[ i ].script_label == triggername )
|
||||
{
|
||||
triggers[ i ].script_activated = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get_player_index_number( player ) //checked changed to match cerberus output
|
||||
{
|
||||
players = get_players();
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
if ( players[ i ] == player )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
269
Multiplayer Core/patch_mp/maps/mp/_ballistic_knife.gsc
Normal file
269
Multiplayer Core/patch_mp/maps/mp/_ballistic_knife.gsc
Normal file
@ -0,0 +1,269 @@
|
||||
//checked includes match cerberus output
|
||||
#include maps/mp/_challenges;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
precachemodel( "t6_wpn_ballistic_knife_projectile" );
|
||||
precachemodel( "t6_wpn_ballistic_knife_blade_retrieve" );
|
||||
}
|
||||
|
||||
onspawn( watcher, player ) //checked changed to match cerberus output
|
||||
{
|
||||
player endon( "death" );
|
||||
player endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
self waittill( "stationary", endpos, normal, angles, attacker, prey, bone );
|
||||
isfriendly = 0;
|
||||
if ( isDefined( endpos ) )
|
||||
{
|
||||
retrievable_model = spawn( "script_model", endpos );
|
||||
retrievable_model setmodel( "t6_wpn_ballistic_knife_projectile" );
|
||||
retrievable_model setteam( player.team );
|
||||
retrievable_model setowner( player );
|
||||
retrievable_model.owner = player;
|
||||
retrievable_model.angles = angles;
|
||||
retrievable_model.name = watcher.weapon;
|
||||
retrievable_model.targetname = "sticky_weapon";
|
||||
if ( isDefined( prey ) )
|
||||
{
|
||||
if ( level.teambased && isplayer( prey ) && player.team == prey.team )
|
||||
{
|
||||
isfriendly = 1;
|
||||
}
|
||||
else if ( level.teambased && isai( prey ) && player.team == prey.aiteam )
|
||||
{
|
||||
isfriendly = 1;
|
||||
}
|
||||
if ( !isfriendly )
|
||||
{
|
||||
if ( isalive( prey ) )
|
||||
{
|
||||
retrievable_model droptoground( retrievable_model.origin, 80 );
|
||||
}
|
||||
else
|
||||
{
|
||||
retrievable_model linkto( prey, bone );
|
||||
}
|
||||
}
|
||||
else if ( isfriendly )
|
||||
{
|
||||
retrievable_model physicslaunch( normal, ( randomint( 10 ), randomint( 10 ), randomint( 10 ) ) );
|
||||
normal = ( 0, 0, 1 );
|
||||
}
|
||||
}
|
||||
watcher.objectarray[ watcher.objectarray.size ] = retrievable_model;
|
||||
if ( isfriendly )
|
||||
{
|
||||
retrievable_model waittill( "stationary" );
|
||||
}
|
||||
retrievable_model thread dropknivestoground();
|
||||
if ( isfriendly )
|
||||
{
|
||||
player notify( "ballistic_knife_stationary" );
|
||||
}
|
||||
else
|
||||
{
|
||||
player notify( "ballistic_knife_stationary" );
|
||||
}
|
||||
retrievable_model thread wait_to_show_glowing_model( prey );
|
||||
}
|
||||
}
|
||||
|
||||
wait_to_show_glowing_model( prey ) //checked matches cerberus output
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
self endon( "death" );
|
||||
glowing_retrievable_model = spawn( "script_model", self.origin );
|
||||
self.glowing_model = glowing_retrievable_model;
|
||||
glowing_retrievable_model.angles = self.angles;
|
||||
glowing_retrievable_model linkto( self );
|
||||
if ( !is_true( prey ) )
|
||||
{
|
||||
wait 2;
|
||||
}
|
||||
glowing_retrievable_model setmodel( "t6_wpn_ballistic_knife_blade_retrieve" );
|
||||
}
|
||||
|
||||
watch_shutdown() //checked matches cerberus output
|
||||
{
|
||||
pickuptrigger = self.pickuptrigger;
|
||||
glowing_model = self.glowing_model;
|
||||
self waittill( "death" );
|
||||
if ( isDefined( pickuptrigger ) )
|
||||
{
|
||||
pickuptrigger delete();
|
||||
}
|
||||
if ( isDefined( glowing_model ) )
|
||||
{
|
||||
glowing_model delete();
|
||||
}
|
||||
}
|
||||
|
||||
onspawnretrievetrigger( watcher, player ) //checked matches cerberus output
|
||||
{
|
||||
player endon( "death" );
|
||||
player endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
player waittill( "ballistic_knife_stationary", retrievable_model, normal, prey );
|
||||
if ( !isDefined( retrievable_model ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
vec_scale = 10;
|
||||
trigger_pos = [];
|
||||
if ( isDefined( prey ) || isplayer( prey ) && isai( prey ) )
|
||||
{
|
||||
trigger_pos[ 0 ] = prey.origin[ 0 ];
|
||||
trigger_pos[ 1 ] = prey.origin[ 1 ];
|
||||
trigger_pos[ 2 ] = prey.origin[ 2 ] + vec_scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_pos[ 0 ] = retrievable_model.origin[ 0 ] + ( vec_scale * normal[ 0 ] );
|
||||
trigger_pos[ 1 ] = retrievable_model.origin[ 1 ] + ( vec_scale * normal[ 1 ] );
|
||||
trigger_pos[ 2 ] = retrievable_model.origin[ 2 ] + ( vec_scale * normal[ 2 ] );
|
||||
}
|
||||
trigger_pos[ 2 ] -= 50;
|
||||
pickup_trigger = spawn( "trigger_radius", ( trigger_pos[ 0 ], trigger_pos[ 1 ], trigger_pos[ 2 ] ), 0, 50, 100 );
|
||||
pickup_trigger.owner = player;
|
||||
retrievable_model.pickuptrigger = pickup_trigger;
|
||||
pickup_trigger enablelinkto();
|
||||
if ( isDefined( prey ) )
|
||||
{
|
||||
pickup_trigger linkto( prey );
|
||||
}
|
||||
else
|
||||
{
|
||||
pickup_trigger linkto( retrievable_model );
|
||||
}
|
||||
retrievable_model thread watch_use_trigger( pickup_trigger, retrievable_model, ::pick_up, watcher.pickupsoundplayer, watcher.pickupsound );
|
||||
retrievable_model thread watch_shutdown();
|
||||
}
|
||||
|
||||
watch_use_trigger( trigger, model, callback, playersoundonuse, npcsoundonuse ) //checked changed to match cerberus output
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "delete" );
|
||||
level endon( "game_ended" );
|
||||
max_ammo = weaponmaxammo( "knife_ballistic_mp" ) + 1;
|
||||
while ( 1 )
|
||||
{
|
||||
trigger waittill( "trigger", player );
|
||||
if ( !isalive( player ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( !player isonground() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( isDefined( trigger.triggerteam ) && player.team != trigger.triggerteam )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( isDefined( trigger.claimedby ) && player != trigger.claimedby )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( !player hasweapon( "knife_ballistic_mp" ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ammo_stock = player getweaponammostock( "knife_ballistic_mp" );
|
||||
ammo_clip = player getweaponammoclip( "knife_ballistic_mp" );
|
||||
current_weapon = player getcurrentweapon();
|
||||
total_ammo = ammo_stock + ammo_clip;
|
||||
hasreloaded = 1;
|
||||
if ( total_ammo > 0 && ammo_stock == total_ammo && current_weapon == "knife_ballistic_mp" )
|
||||
{
|
||||
hasreloaded = 0;
|
||||
}
|
||||
if ( total_ammo >= max_ammo || !hasreloaded )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( isDefined( playersoundonuse ) )
|
||||
{
|
||||
player playlocalsound( playersoundonuse );
|
||||
}
|
||||
if ( isDefined( npcsoundonuse ) )
|
||||
{
|
||||
player playsound( npcsoundonuse );
|
||||
}
|
||||
self thread [[ callback ]]( player );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pick_up( player ) //checked matches cerberus output
|
||||
{
|
||||
self destroy_ent();
|
||||
current_weapon = player getcurrentweapon();
|
||||
player maps/mp/_challenges::pickedupballisticknife();
|
||||
if ( current_weapon != "knife_ballistic_mp" )
|
||||
{
|
||||
clip_ammo = player getweaponammoclip( "knife_ballistic_mp" );
|
||||
if ( !clip_ammo )
|
||||
{
|
||||
player setweaponammoclip( "knife_ballistic_mp", 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
new_ammo_stock = player getweaponammostock( "knife_ballistic_mp" ) + 1;
|
||||
player setweaponammostock( "knife_ballistic_mp", new_ammo_stock );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new_ammo_stock = player getweaponammostock( "knife_ballistic_mp" ) + 1;
|
||||
player setweaponammostock( "knife_ballistic_mp", new_ammo_stock );
|
||||
}
|
||||
}
|
||||
|
||||
destroy_ent() //checked matches cerberus output
|
||||
{
|
||||
if ( isDefined( self ) )
|
||||
{
|
||||
pickuptrigger = self.pickuptrigger;
|
||||
if ( isDefined( pickuptrigger ) )
|
||||
{
|
||||
pickuptrigger delete();
|
||||
}
|
||||
if ( isDefined( self.glowing_model ) )
|
||||
{
|
||||
self.glowing_model delete();
|
||||
}
|
||||
self delete();
|
||||
}
|
||||
}
|
||||
|
||||
dropknivestoground() //checked matches cerberus output
|
||||
{
|
||||
self endon( "death" );
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( "drop_objects_to_ground", origin, radius );
|
||||
self droptoground( origin, radius );
|
||||
}
|
||||
}
|
||||
|
||||
droptoground( origin, radius ) //checked changed to match cerberus output
|
||||
{
|
||||
if ( distancesquared( origin, self.origin ) < ( radius * radius ) )
|
||||
{
|
||||
self physicslaunch( ( 0, 0, 1 ), vectorScale( ( 1, 1, 1 ), 5 ) );
|
||||
self thread updateretrievetrigger();
|
||||
}
|
||||
}
|
||||
|
||||
updateretrievetrigger() //checked matches cerberus output
|
||||
{
|
||||
self endon( "death" );
|
||||
self waittill( "stationary" );
|
||||
trigger = self.pickuptrigger;
|
||||
trigger.origin = ( self.origin[ 0 ], self.origin[ 1 ], self.origin[ 2 ] + 10 );
|
||||
trigger linkto( self );
|
||||
}
|
||||
|
92
Multiplayer Core/patch_mp/maps/mp/_bb.gsc
Normal file
92
Multiplayer Core/patch_mp/maps/mp/_bb.gsc
Normal file
@ -0,0 +1,92 @@
|
||||
//includes match cerberus output
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
level thread onplayerconnect();
|
||||
}
|
||||
|
||||
onplayerconnect() //checked matches cerberus output
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
player thread onplayerspawned();
|
||||
player thread onplayerdeath();
|
||||
}
|
||||
}
|
||||
|
||||
onplayerspawned() //checked matches cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self._bbdata = [];
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
self._bbdata[ "score" ] = 0;
|
||||
self._bbdata[ "momentum" ] = 0;
|
||||
self._bbdata[ "spawntime" ] = getTime();
|
||||
self._bbdata[ "shots" ] = 0;
|
||||
self._bbdata[ "hits" ] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
onplayerdisconnect() //checked changed to match beta dump
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "disconnect" );
|
||||
self commitspawndata();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
onplayerdeath() //checked matches cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "death" );
|
||||
self commitspawndata();
|
||||
}
|
||||
}
|
||||
|
||||
commitspawndata() //checked matches cerberus output
|
||||
{
|
||||
/*
|
||||
/#
|
||||
assert( isDefined( self._bbdata ) );
|
||||
#/
|
||||
*/
|
||||
if ( !isDefined( self._bbdata ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
bbprint( "mpplayerlives", "gametime %d spawnid %d lifescore %d lifemomentum %d lifetime %d name %s", getTime(), getplayerspawnid( self ), self._bbdata[ "score" ], self._bbdata[ "momentum" ], getTime() - self._bbdata[ "spawntime" ], self.name );
|
||||
}
|
||||
|
||||
commitweapondata( spawnid, currentweapon, time0 ) //checked matches cerberus output
|
||||
{
|
||||
/*
|
||||
/#
|
||||
assert( isDefined( self._bbdata ) );
|
||||
#/
|
||||
*/
|
||||
if ( !isDefined( self._bbdata ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
time1 = getTime();
|
||||
bbprint( "mpweapons", "spawnid %d name %s duration %d shots %d hits %d", spawnid, currentweapon, time1 - time0, self._bbdata[ "shots" ], self._bbdata[ "hits" ] );
|
||||
self._bbdata[ "shots" ] = 0;
|
||||
self._bbdata[ "hits" ] = 0;
|
||||
}
|
||||
|
||||
bbaddtostat( statname, delta ) //checked matches cerberus output
|
||||
{
|
||||
if ( isDefined( self._bbdata ) && isDefined( self._bbdata[ statname ] ) )
|
||||
{
|
||||
self._bbdata[ statname ] += delta;
|
||||
}
|
||||
}
|
177
Multiplayer Core/patch_mp/maps/mp/_bouncingbetty.gsc
Normal file
177
Multiplayer Core/patch_mp/maps/mp/_bouncingbetty.gsc
Normal file
@ -0,0 +1,177 @@
|
||||
//checked includes match cerberus output
|
||||
#include maps/mp/_scoreevents;
|
||||
#include maps/mp/_challenges;
|
||||
#include maps/mp/gametypes/_weaponobjects;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
precachemodel( "t6_wpn_bouncing_betty_world" );
|
||||
level.bettyexplosionfx = loadfx( "weapon/bouncing_betty/fx_betty_explosion" );
|
||||
level.bettydestroyedfx = loadfx( "weapon/bouncing_betty/fx_betty_destroyed" );
|
||||
level.bettylaunchfx = loadfx( "weapon/bouncing_betty/fx_betty_launch_dust" );
|
||||
level._effect[ "fx_betty_friendly_light" ] = loadfx( "weapon/bouncing_betty/fx_betty_light_green" );
|
||||
level._effect[ "fx_betty_enemy_light" ] = loadfx( "weapon/bouncing_betty/fx_betty_light_red" );
|
||||
level.bettymindist = 20;
|
||||
level.bettygraceperiod = 0.6;
|
||||
level.bettyradius = 192;
|
||||
level.bettystuntime = 1;
|
||||
level.bettydamageradius = 256;
|
||||
level.bettydamagemax = 210;
|
||||
level.bettydamagemin = 70;
|
||||
level.bettyjumpheight = 65;
|
||||
level.bettyjumptime = 0.65;
|
||||
level.bettyrotatevelocity = ( 0, 750, 32 );
|
||||
level.bettyactivationdelay = 0.1;
|
||||
}
|
||||
|
||||
createbouncingbettywatcher() //checked matches cerberus output
|
||||
{
|
||||
watcher = self createproximityweaponobjectwatcher( "bouncingbetty", "bouncingbetty_mp", self.team );
|
||||
watcher.onspawn = ::onspawnbouncingbetty;
|
||||
watcher.watchforfire = 1;
|
||||
watcher.detonate = ::bouncingbettydetonate;
|
||||
watcher.activatesound = "wpn_claymore_alert";
|
||||
watcher.hackable = 1;
|
||||
watcher.hackertoolradius = level.equipmenthackertoolradius;
|
||||
watcher.hackertooltimems = level.equipmenthackertooltimems;
|
||||
watcher.reconmodel = "t6_wpn_bouncing_betty_world_detect";
|
||||
watcher.ownergetsassist = 1;
|
||||
watcher.ignoredirection = 1;
|
||||
watcher.detectionmindist = level.bettymindist;
|
||||
watcher.detectiongraceperiod = level.bettygraceperiod;
|
||||
watcher.detonateradius = level.bettyradius;
|
||||
watcher.stun = ::weaponstun;
|
||||
watcher.stuntime = level.bettystuntime;
|
||||
watcher.activationdelay = level.bettyactivationdelay;
|
||||
}
|
||||
|
||||
onspawnbouncingbetty( watcher, owner ) //checked matches cerberus output
|
||||
{
|
||||
onspawnproximityweaponobject( watcher, owner );
|
||||
self thread spawnminemover();
|
||||
}
|
||||
|
||||
spawnminemover()
|
||||
{
|
||||
self waittillnotmoving();
|
||||
minemover = spawn( "script_model", self.origin );
|
||||
minemover.angles = self.angles;
|
||||
minemover setmodel( "tag_origin" );
|
||||
minemover.owner = self.owner;
|
||||
minemover.killcamoffset = ( 0, 0, getdvarfloatdefault( "scr_bouncing_betty_killcam_offset", 8 ) );
|
||||
killcament = spawn( "script_model", minemover.origin + minemover.killcamoffset );
|
||||
killcament.angles = ( 0, 0, 0 );
|
||||
killcament setmodel( "tag_origin" );
|
||||
killcament setweapon( "bouncingbetty_mp" );
|
||||
minemover.killcament = killcament;
|
||||
self.minemover = minemover;
|
||||
self thread killminemoveronpickup();
|
||||
}
|
||||
|
||||
killminemoveronpickup() //checked matches cerberus output
|
||||
{
|
||||
self.minemover endon( "death" );
|
||||
self waittill_any( "picked_up", "hacked" );
|
||||
self killminemover();
|
||||
}
|
||||
|
||||
killminemover() //checked matches cerberus output
|
||||
{
|
||||
if ( isDefined( self.minemover ) )
|
||||
{
|
||||
if ( isDefined( self.minemover.killcament ) )
|
||||
{
|
||||
self.minemover.killcament delete();
|
||||
}
|
||||
self.minemover delete();
|
||||
}
|
||||
}
|
||||
|
||||
bouncingbettydetonate( attacker, weaponname ) //checked matches cerberus output
|
||||
{
|
||||
if ( isDefined( weaponname ) )
|
||||
{
|
||||
if ( isDefined( attacker ) )
|
||||
{
|
||||
if ( self.owner isenemyplayer( attacker ) )
|
||||
{
|
||||
attacker maps/mp/_challenges::destroyedexplosive( weaponname );
|
||||
maps/mp/_scoreevents::processscoreevent( "destroyed_bouncingbetty", attacker, self.owner, weaponname );
|
||||
}
|
||||
}
|
||||
self bouncingbettydestroyed();
|
||||
}
|
||||
else if ( isDefined( self.minemover ) )
|
||||
{
|
||||
self.minemover setmodel( self.model );
|
||||
self.minemover thread bouncingbettyjumpandexplode();
|
||||
self delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
self bouncingbettydestroyed();
|
||||
}
|
||||
}
|
||||
|
||||
bouncingbettydestroyed() //checked matches cerberus output
|
||||
{
|
||||
playfx( level.bettydestroyedfx, self.origin );
|
||||
playsoundatposition( "dst_equipment_destroy", self.origin );
|
||||
if ( isDefined( self.trigger ) )
|
||||
{
|
||||
self.trigger delete();
|
||||
}
|
||||
if ( isDefined( self.minemover ) )
|
||||
{
|
||||
if ( isDefined( self.minemover.killcament ) )
|
||||
{
|
||||
self.minemover.killcament delete();
|
||||
}
|
||||
self.minemover delete();
|
||||
}
|
||||
self radiusdamage( self.origin, 128, 110, 10, self.owner, "MOD_EXPLOSIVE", "bouncingbetty_mp" );
|
||||
self delete();
|
||||
}
|
||||
|
||||
bouncingbettyjumpandexplode() //checked matches cerberus output
|
||||
{
|
||||
explodepos = self.origin + ( 0, 0, level.bettyjumpheight );
|
||||
self moveto( explodepos, level.bettyjumptime, level.bettyjumptime, 0 );
|
||||
self.killcament moveto( explodepos + self.killcamoffset, level.bettyjumptime, 0, level.bettyjumptime );
|
||||
playfx( level.bettylaunchfx, self.origin );
|
||||
self rotatevelocity( level.bettyrotatevelocity, level.bettyjumptime, 0, level.bettyjumptime );
|
||||
self playsound( "fly_betty_jump" );
|
||||
wait level.bettyjumptime;
|
||||
self thread mineexplode();
|
||||
}
|
||||
|
||||
mineexplode() //checked matches cerberus output
|
||||
{
|
||||
if ( !isDefined( self ) || !isDefined( self.owner ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self playsound( "fly_betty_explo" );
|
||||
wait 0.05;
|
||||
if ( !isDefined( self ) || !isDefined( self.owner ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self hide();
|
||||
self radiusdamage( self.origin, level.bettydamageradius, level.bettydamagemax, level.bettydamagemin, self.owner, "MOD_EXPLOSIVE", "bouncingbetty_mp" );
|
||||
playfx( level.bettyexplosionfx, self.origin );
|
||||
wait 0.2;
|
||||
if ( !isDefined( self ) || !isDefined( self.owner ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( isDefined( self.trigger ) )
|
||||
{
|
||||
self.trigger delete();
|
||||
}
|
||||
self.killcament delete();
|
||||
self delete();
|
||||
}
|
||||
|
582
Multiplayer Core/patch_mp/maps/mp/_burnplayer.gsc
Normal file
582
Multiplayer Core/patch_mp/maps/mp/_burnplayer.gsc
Normal file
@ -0,0 +1,582 @@
|
||||
//checked includes match cerberus output
|
||||
#include maps/mp/gametypes/_damagefeedback;
|
||||
#include maps/mp/gametypes/_globallogic_player;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
|
||||
initburnplayer() //checked matches cerberus output
|
||||
{
|
||||
level.flamedamage = 15;
|
||||
level.flameburntime = 1.5;
|
||||
}
|
||||
|
||||
hitwithincendiary( attacker, inflictor, mod ) //checked changed to match cerberus output
|
||||
{
|
||||
if ( isDefined( self.burning ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self starttanning();
|
||||
self thread waitthenstoptanning( level.flameburntime );
|
||||
self endon( "disconnect" );
|
||||
attacker endon( "disconnect" );
|
||||
waittillframeend;
|
||||
self.burning = 1;
|
||||
self thread burn_blocker();
|
||||
tagarray = [];
|
||||
if ( isai( self ) )
|
||||
{
|
||||
tagarray[ tagarray.size ] = "J_Wrist_RI";
|
||||
tagarray[ tagarray.size ] = "J_Wrist_LE";
|
||||
tagarray[ tagarray.size ] = "J_Elbow_LE";
|
||||
tagarray[ tagarray.size ] = "J_Elbow_RI";
|
||||
tagarray[ tagarray.size ] = "J_Knee_RI";
|
||||
tagarray[ tagarray.size ] = "J_Knee_LE";
|
||||
tagarray[ tagarray.size ] = "J_Ankle_RI";
|
||||
tagarray[ tagarray.size ] = "J_Ankle_LE";
|
||||
}
|
||||
else
|
||||
{
|
||||
tagarray[ tagarray.size ] = "J_Wrist_RI";
|
||||
tagarray[ tagarray.size ] = "J_Wrist_LE";
|
||||
tagarray[ tagarray.size ] = "J_Elbow_LE";
|
||||
tagarray[ tagarray.size ] = "J_Elbow_RI";
|
||||
tagarray[ tagarray.size ] = "J_Knee_RI";
|
||||
tagarray[ tagarray.size ] = "J_Knee_LE";
|
||||
tagarray[ tagarray.size ] = "J_Ankle_RI";
|
||||
tagarray[ tagarray.size ] = "J_Ankle_LE";
|
||||
if ( isplayer( self ) && self.health > 0 )
|
||||
{
|
||||
self setburn( 3 );
|
||||
}
|
||||
}
|
||||
if ( isDefined( level._effect[ "character_fire_death_torso" ] ) )
|
||||
{
|
||||
for ( arrayIndex = 0; arrayIndex < tagArray.size; arrayIndex++ )
|
||||
{
|
||||
playfxontag( level._effect[ "character_fire_death_sm" ], self, tagarray[ arrayindex ] );
|
||||
}
|
||||
}
|
||||
if ( isai( self ) )
|
||||
{
|
||||
playfxontag( level._effect[ "character_fire_death_torso" ], self, "J_Spine1" );
|
||||
}
|
||||
else
|
||||
{
|
||||
playfxontag( level._effect[ "character_fire_death_torso" ], self, "J_SpineLower" );
|
||||
}
|
||||
if ( !isalive( self ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( isplayer( self ) )
|
||||
{
|
||||
self thread watchforwater( 7 );
|
||||
self thread watchfordeath();
|
||||
}
|
||||
}
|
||||
|
||||
hitwithnapalmstrike( attacker, inflictor, mod ) //checked changed to match cerberus output
|
||||
{
|
||||
if ( isDefined( self.burning ) || self hasperk( "specialty_fireproof" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self starttanning();
|
||||
self thread waitthenstoptanning( level.flameburntime );
|
||||
self endon( "disconnect" );
|
||||
attacker endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
if ( isDefined( self.burning ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self thread burn_blocker();
|
||||
waittillframeend;
|
||||
self.burning = 1;
|
||||
self thread burn_blocker();
|
||||
tagarray = [];
|
||||
if ( isai( self ) )
|
||||
{
|
||||
tagarray[ tagarray.size ] = "J_Wrist_RI";
|
||||
tagarray[ tagarray.size ] = "J_Wrist_LE";
|
||||
tagarray[ tagarray.size ] = "J_Elbow_LE";
|
||||
tagarray[ tagarray.size ] = "J_Elbow_RI";
|
||||
tagarray[ tagarray.size ] = "J_Knee_RI";
|
||||
tagarray[ tagarray.size ] = "J_Knee_LE";
|
||||
tagarray[ tagarray.size ] = "J_Ankle_RI";
|
||||
tagarray[ tagarray.size ] = "J_Ankle_LE";
|
||||
}
|
||||
else
|
||||
{
|
||||
tagarray[ tagarray.size ] = "J_Wrist_RI";
|
||||
tagarray[ tagarray.size ] = "J_Wrist_LE";
|
||||
tagarray[ tagarray.size ] = "J_Elbow_LE";
|
||||
tagarray[ tagarray.size ] = "J_Elbow_RI";
|
||||
tagarray[ tagarray.size ] = "J_Knee_RI";
|
||||
tagarray[ tagarray.size ] = "J_Knee_LE";
|
||||
tagarray[ tagarray.size ] = "J_Ankle_RI";
|
||||
tagarray[ tagarray.size ] = "J_Ankle_LE";
|
||||
if ( isplayer( self ) )
|
||||
{
|
||||
self setburn( 3 );
|
||||
}
|
||||
}
|
||||
if ( isDefined( level._effect[ "character_fire_death_sm" ] ) )
|
||||
{
|
||||
for ( arrayindex = 0; arrayindex < tagarray.size; arrayindex++ )
|
||||
{
|
||||
playfxontag( level._effect[ "character_fire_death_sm" ], self, tagarray[ arrayindex ] );
|
||||
arrayindex++;
|
||||
}
|
||||
}
|
||||
if ( isDefined( level._effect[ "character_fire_death_torso" ] ) )
|
||||
{
|
||||
playfxontag( level._effect[ "character_fire_death_torso" ], self, "J_SpineLower" );
|
||||
}
|
||||
if ( !isalive( self ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self thread donapalmstrikedamage( attacker, inflictor, mod );
|
||||
if ( isplayer( self ) )
|
||||
{
|
||||
self thread watchforwater( 7 );
|
||||
self thread watchfordeath();
|
||||
}
|
||||
}
|
||||
|
||||
walkedthroughflames( attacker, inflictor, weapon ) //checked changed to match cerberus output
|
||||
{
|
||||
if ( isDefined( self.burning ) || self hasperk( "specialty_fireproof" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self starttanning();
|
||||
self thread waitthenstoptanning( level.flameburntime );
|
||||
self endon( "disconnect" );
|
||||
waittillframeend;
|
||||
self.burning = 1;
|
||||
self thread burn_blocker();
|
||||
tagarray = [];
|
||||
if ( isai( self ) )
|
||||
{
|
||||
tagarray[ tagarray.size ] = "J_Wrist_RI";
|
||||
tagarray[ tagarray.size ] = "J_Wrist_LE";
|
||||
tagarray[ tagarray.size ] = "J_Elbow_LE";
|
||||
tagarray[ tagarray.size ] = "J_Elbow_RI";
|
||||
tagarray[ tagarray.size ] = "J_Knee_RI";
|
||||
tagarray[ tagarray.size ] = "J_Knee_LE";
|
||||
tagarray[ tagarray.size ] = "J_Ankle_RI";
|
||||
tagarray[ tagarray.size ] = "J_Ankle_LE";
|
||||
}
|
||||
else
|
||||
{
|
||||
tagarray[ tagarray.size ] = "J_Knee_RI";
|
||||
tagarray[ tagarray.size ] = "J_Knee_LE";
|
||||
tagarray[ tagarray.size ] = "J_Ankle_RI";
|
||||
tagarray[ tagarray.size ] = "J_Ankle_LE";
|
||||
}
|
||||
if ( isDefined( level._effect[ "character_fire_player_sm" ] ) )
|
||||
{
|
||||
for ( arrayindex = 0; arrayindex < tagarray.size; arrayindex++ )
|
||||
{
|
||||
playfxontag( level._effect[ "character_fire_player_sm" ], self, tagarray[ arrayindex ] );
|
||||
}
|
||||
}
|
||||
if ( !isalive( self ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self thread doflamedamage( attacker, inflictor, weapon, 1 );
|
||||
if ( isplayer( self ) )
|
||||
{
|
||||
self thread watchforwater( 7 );
|
||||
self thread watchfordeath();
|
||||
}
|
||||
}
|
||||
|
||||
burnedwithflamethrower( attacker, inflictor, weapon ) //checked changed to match cerberus output
|
||||
{
|
||||
if ( isDefined( self.burning ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self starttanning();
|
||||
self thread waitthenstoptanning( level.flameburntime );
|
||||
self endon( "disconnect" );
|
||||
waittillframeend;
|
||||
self.burning = 1;
|
||||
self thread burn_blocker();
|
||||
tagarray = [];
|
||||
if ( isai( self ) )
|
||||
{
|
||||
tagarray[ 0 ] = "J_Spine1";
|
||||
tagarray[ 1 ] = "J_Elbow_LE";
|
||||
tagarray[ 2 ] = "J_Elbow_RI";
|
||||
tagarray[ 3 ] = "J_Head";
|
||||
tagarray[ 4 ] = "j_knee_ri";
|
||||
tagarray[ 5 ] = "j_knee_le";
|
||||
}
|
||||
else
|
||||
{
|
||||
tagarray[ 0 ] = "J_Elbow_RI";
|
||||
tagarray[ 1 ] = "j_knee_ri";
|
||||
tagarray[ 2 ] = "j_knee_le";
|
||||
if ( isplayer( self ) && self.health > 0 )
|
||||
{
|
||||
self setburn( 3 );
|
||||
}
|
||||
}
|
||||
if ( isplayer( self ) && isalive( self ) )
|
||||
{
|
||||
self thread watchforwater( 7 );
|
||||
self thread watchfordeath();
|
||||
}
|
||||
if ( isDefined( level._effect[ "character_fire_player_sm" ] ) )
|
||||
{
|
||||
for ( arrayindex = 0; arrayindex < tagarray.size; arrayindex++ )
|
||||
{
|
||||
playfxontag( level._effect[ "character_fire_player_sm" ], self, tagarray[ arrayindex ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
burnedwithdragonsbreath( attacker, inflictor, weapon ) //checked changed to match cerberus output
|
||||
{
|
||||
if ( isDefined( self.burning ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self starttanning();
|
||||
self thread waitthenstoptanning( level.flameburntime );
|
||||
self endon( "disconnect" );
|
||||
waittillframeend;
|
||||
self.burning = 1;
|
||||
self thread burn_blocker();
|
||||
tagarray = [];
|
||||
if ( isai( self ) )
|
||||
{
|
||||
tagarray[ 0 ] = "J_Spine1";
|
||||
tagarray[ 1 ] = "J_Elbow_LE";
|
||||
tagarray[ 2 ] = "J_Elbow_RI";
|
||||
tagarray[ 3 ] = "J_Head";
|
||||
tagarray[ 4 ] = "j_knee_ri";
|
||||
tagarray[ 5 ] = "j_knee_le";
|
||||
}
|
||||
else
|
||||
{
|
||||
tagarray[ 0 ] = "j_spinelower";
|
||||
tagarray[ 1 ] = "J_Elbow_RI";
|
||||
tagarray[ 2 ] = "j_knee_ri";
|
||||
tagarray[ 3 ] = "j_knee_le";
|
||||
if ( isplayer( self ) && self.health > 0 )
|
||||
{
|
||||
self setburn( 3 );
|
||||
}
|
||||
}
|
||||
if ( isplayer( self ) && isalive( self ) )
|
||||
{
|
||||
self thread watchforwater( 7 );
|
||||
self thread watchfordeath();
|
||||
return;
|
||||
}
|
||||
if ( isDefined( level._effect[ "character_fire_player_sm" ] ) )
|
||||
{
|
||||
for ( arrayindex = 0; arrayindex < tagarray.size; arrayindex++ )
|
||||
{
|
||||
playfxontag( level._effect[ "character_fire_player_sm" ], self, tagarray[ arrayindex ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
burnedtodeath() //checked matches cerberus output
|
||||
{
|
||||
self.burning = 1;
|
||||
self thread burn_blocker();
|
||||
self starttanning();
|
||||
self thread doburningsound();
|
||||
self thread waitthenstoptanning( level.flameburntime );
|
||||
}
|
||||
|
||||
watchfordeath() //checked matches cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self notify( "watching for death while on fire" );
|
||||
self endon( "watching for death while on fire" );
|
||||
self waittill( "death" );
|
||||
if ( isplayer( self ) )
|
||||
{
|
||||
self _stopburning();
|
||||
}
|
||||
self.burning = undefined;
|
||||
}
|
||||
|
||||
watchforwater( time ) //checked matches cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self notify( "watching for water" );
|
||||
self endon( "watching for water" );
|
||||
wait 0.1;
|
||||
looptime = 0.1;
|
||||
while ( time > 0 )
|
||||
{
|
||||
wait looptime;
|
||||
if ( self depthofplayerinwater() > 0 )
|
||||
{
|
||||
finish_burn();
|
||||
time = 0;
|
||||
}
|
||||
time -= looptime;
|
||||
}
|
||||
}
|
||||
|
||||
finish_burn() //checked changed to match cerberus output
|
||||
{
|
||||
self notify( "stop burn damage" );
|
||||
tagarray = [];
|
||||
tagarray[ 0 ] = "j_spinelower";
|
||||
tagarray[ 1 ] = "J_Elbow_RI";
|
||||
tagarray[ 2 ] = "J_Head";
|
||||
tagarray[ 3 ] = "j_knee_ri";
|
||||
tagarray[ 4 ] = "j_knee_le";
|
||||
if ( isDefined( level._effect[ "fx_fire_player_sm_smk_2sec" ] ) )
|
||||
{
|
||||
for ( arrayindex = 0; arrayindex < tagarray.size; arrayindex++ )
|
||||
{
|
||||
playfxontag( level._effect[ "fx_fire_player_sm_smk_2sec" ], self, tagarray[ arrayindex ] );
|
||||
}
|
||||
}
|
||||
self.burning = undefined;
|
||||
self _stopburning();
|
||||
self.ingroundnapalm = 0;
|
||||
}
|
||||
|
||||
donapalmstrikedamage( attacker, inflictor, mod ) //checked matches cerberus output
|
||||
{
|
||||
if ( isai( self ) )
|
||||
{
|
||||
dodognapalmstrikedamage( attacker, inflictor, mod );
|
||||
return;
|
||||
}
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
attacker endon( "disconnect" );
|
||||
self endon( "stop burn damage" );
|
||||
while ( isDefined( level.napalmstrikedamage ) && isDefined( self ) && self depthofplayerinwater() < 1 )
|
||||
{
|
||||
self dodamage( level.napalmstrikedamage, self.origin, attacker, attacker, "none", mod, 0, "napalm_mp" );
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
|
||||
donapalmgrounddamage( attacker, inflictor, mod ) //checked changed to match cerberus output dvars taken from beta dump
|
||||
{
|
||||
if ( self hasperk( "specialty_fireproof" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( level.teambased )
|
||||
{
|
||||
if ( attacker != self && attacker.team == self.team )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ( isai( self ) )
|
||||
{
|
||||
dodognapalmgrounddamage( attacker, inflictor, mod );
|
||||
return;
|
||||
}
|
||||
if ( isDefined( self.burning ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self thread burn_blocker();
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
attacker endon( "disconnect" );
|
||||
self endon( "stop burn damage" );
|
||||
if ( isDefined( level.groundburntime ) )
|
||||
{
|
||||
if ( getDvar( "scr_groundBurnTime" ) == "" )
|
||||
{
|
||||
waittime = level.groundburntime;
|
||||
}
|
||||
else
|
||||
{
|
||||
waittime = getDvarFloat( "scr_groundBurnTime" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
waittime = 100;
|
||||
}
|
||||
self walkedthroughflames( attacker, inflictor, "napalm_mp" );
|
||||
self.ingroundnapalm = 1;
|
||||
while ( isDefined( level.napalmgrounddamage ) )
|
||||
{
|
||||
if ( getDvar( "scr_napalmGroundDamage" ) == "" )
|
||||
{
|
||||
napalmgrounddamage = level.napalmgrounddamage;
|
||||
}
|
||||
else
|
||||
{
|
||||
napalmgrounddamage = getDvarFloat( "scr_napalmGroundDamage" );
|
||||
}
|
||||
while ( isDefined( self ) && isDefined( inflictor ) && self depthofplayerinwater() < 1 && waittime > 0 )
|
||||
{
|
||||
self dodamage( level.napalmgrounddamage, self.origin, attacker, inflictor, "none", mod, 0, "napalm_mp" );
|
||||
if ( isplayer( self ) )
|
||||
{
|
||||
self setburn( 1.1 );
|
||||
}
|
||||
wait 1;
|
||||
waittime -= 1;
|
||||
}
|
||||
}
|
||||
self.ingroundnapalm = 0;
|
||||
}
|
||||
|
||||
dodognapalmstrikedamage( attacker, inflictor, mod ) //checked matches cerberus output
|
||||
{
|
||||
attacker endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self endon( "stop burn damage" );
|
||||
while ( isDefined( level.napalmstrikedamage ) && isDefined( self ) )
|
||||
{
|
||||
self dodamage( level.napalmstrikedamage, self.origin, attacker, attacker, "none", mod );
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
|
||||
dodognapalmgrounddamage( attacker, inflictor, mod ) //checked matches cerberus output
|
||||
{
|
||||
attacker endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self endon( "stop burn damage" );
|
||||
while ( isDefined( level.napalmgrounddamage ) && isDefined( self ) )
|
||||
{
|
||||
self dodamage( level.napalmgrounddamage, self.origin, attacker, attacker, "none", mod, 0, "napalm_mp" );
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
|
||||
burn_blocker() //checked matches cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
wait 3;
|
||||
self.burning = undefined;
|
||||
}
|
||||
|
||||
doflamedamage( attacker, inflictor, weapon, time ) //checked matches cerberus output
|
||||
{
|
||||
if ( isai( self ) )
|
||||
{
|
||||
dodogflamedamage( attacker, inflictor, weapon, time );
|
||||
return;
|
||||
}
|
||||
if ( isDefined( attacker ) )
|
||||
{
|
||||
attacker endon( "disconnect" );
|
||||
}
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "stop burn damage" );
|
||||
self thread doburningsound();
|
||||
self notify( "snd_burn_scream" );
|
||||
wait_time = 1;
|
||||
while ( isDefined( level.flamedamage ) && isDefined( self ) && self depthofplayerinwater() < 1 && time > 0 )
|
||||
{
|
||||
if ( isDefined( attacker ) && isDefined( inflictor ) && isDefined( weapon ) )
|
||||
{
|
||||
if ( maps/mp/gametypes/_globallogic_player::dodamagefeedback( weapon, attacker ) )
|
||||
{
|
||||
attacker maps/mp/gametypes/_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
self dodamage( level.flamedamage, self.origin, attacker, inflictor, "none", "MOD_BURNED", 0, weapon );
|
||||
}
|
||||
else
|
||||
{
|
||||
self dodamage( level.flamedamage, self.origin );
|
||||
}
|
||||
wait wait_time;
|
||||
time -= wait_time;
|
||||
}
|
||||
self thread finish_burn();
|
||||
}
|
||||
|
||||
dodogflamedamage( attacker, inflictor, weapon, time ) //checked changed to match cerberus output
|
||||
{
|
||||
if ( isDefined( attacker ) || !isDefined( inflictor ) || !isDefined( weapon ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
attacker endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self endon( "stop burn damage" );
|
||||
self thread doburningsound();
|
||||
wait_time = 1;
|
||||
while ( isDefined( level.flamedamage ) && isDefined( self ) && time > 0 )
|
||||
{
|
||||
self dodamage( level.flamedamage, self.origin, attacker, inflictor, "none", "MOD_BURNED", 0, weapon );
|
||||
wait wait_time;
|
||||
time -= wait_time;
|
||||
}
|
||||
}
|
||||
|
||||
waitthenstoptanning( time ) //checked matches cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
wait time;
|
||||
self _stopburning();
|
||||
}
|
||||
|
||||
doburningsound() //checked matches cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
fire_sound_ent = spawn( "script_origin", self.origin );
|
||||
fire_sound_ent linkto( self, "tag_origin", ( 0, 0, 0 ), ( 0, 0, 0 ) );
|
||||
fire_sound_ent playloopsound( "mpl_player_burn_loop" );
|
||||
self thread firesounddeath( fire_sound_ent );
|
||||
self waittill( "StopBurnSound" );
|
||||
if ( isDefined( fire_sound_ent ) )
|
||||
{
|
||||
fire_sound_ent stoploopsound( 0.5 );
|
||||
}
|
||||
wait 0.5;
|
||||
if ( isDefined( fire_sound_ent ) )
|
||||
{
|
||||
fire_sound_ent delete();
|
||||
}
|
||||
/*
|
||||
/#
|
||||
println( "sound stop burning" );
|
||||
#/
|
||||
*/
|
||||
}
|
||||
|
||||
_stopburning() //checked matches cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self notify( "StopBurnSound" );
|
||||
if ( isDefined( self ) )
|
||||
{
|
||||
self stopburning();
|
||||
}
|
||||
}
|
||||
|
||||
firesounddeath( ent ) //checked matches cerberus output
|
||||
{
|
||||
ent endon( "death" );
|
||||
self waittill_any( "death", "disconnect" );
|
||||
ent delete();
|
||||
/*
|
||||
/#
|
||||
println( "sound delete burning" );
|
||||
#/
|
||||
*/
|
||||
}
|
22
Multiplayer Core/patch_mp/maps/mp/_busing.gsc
Normal file
22
Multiplayer Core/patch_mp/maps/mp/_busing.gsc
Normal file
@ -0,0 +1,22 @@
|
||||
//checked includes match cerberus output
|
||||
#include maps/mp/_utility;
|
||||
|
||||
businit() //checked matches cerberus output
|
||||
{
|
||||
/*
|
||||
/#
|
||||
assert( level.clientscripts );
|
||||
#/
|
||||
*/
|
||||
level.busstate = "";
|
||||
registerclientsys( "busCmd" );
|
||||
}
|
||||
|
||||
setbusstate( state ) //checked matches cerberus output
|
||||
{
|
||||
if ( level.busstate != state )
|
||||
{
|
||||
setclientsysstate( "busCmd", state );
|
||||
}
|
||||
level.busstate = state;
|
||||
}
|
2117
Multiplayer Core/patch_mp/maps/mp/_challenges.gsc
Normal file
2117
Multiplayer Core/patch_mp/maps/mp/_challenges.gsc
Normal file
File diff suppressed because it is too large
Load Diff
69
Multiplayer Core/patch_mp/maps/mp/_compass.gsc
Normal file
69
Multiplayer Core/patch_mp/maps/mp/_compass.gsc
Normal file
@ -0,0 +1,69 @@
|
||||
|
||||
setupminimap( material ) //checked matches cerberus output
|
||||
{
|
||||
requiredmapaspectratio = getDvarFloat( "scr_RequiredMapAspectratio" );
|
||||
corners = getentarray( "minimap_corner", "targetname" );
|
||||
if ( corners.size != 2 )
|
||||
{
|
||||
/*
|
||||
/#
|
||||
println( "^1Error: There are not exactly two "minimap_corner" entities in the map. Could not set up minimap." );
|
||||
#/
|
||||
*/
|
||||
return;
|
||||
}
|
||||
corner0 = ( corners[ 0 ].origin[ 0 ], corners[ 0 ].origin[ 1 ], 0 );
|
||||
corner1 = ( corners[ 1 ].origin[ 0 ], corners[ 1 ].origin[ 1 ], 0 );
|
||||
cornerdiff = corner1 - corner0;
|
||||
north = ( cos( getnorthyaw() ), sin( getnorthyaw() ), 0 );
|
||||
west = ( 0 - north[ 1 ], north[ 0 ], 0 );
|
||||
if ( vectordot( cornerdiff, west ) > 0 )
|
||||
{
|
||||
if ( vectordot( cornerdiff, north ) > 0 )
|
||||
{
|
||||
northwest = corner1;
|
||||
southeast = corner0;
|
||||
}
|
||||
else
|
||||
{
|
||||
side = vecscale( north, vectordot( cornerdiff, north ) );
|
||||
northwest = corner1 - side;
|
||||
southeast = corner0 + side;
|
||||
}
|
||||
}
|
||||
else if ( vectordot( cornerdiff, north ) > 0 )
|
||||
{
|
||||
side = vecscale( north, vectordot( cornerdiff, north ) );
|
||||
northwest = corner0 + side;
|
||||
southeast = corner1 - side;
|
||||
}
|
||||
else
|
||||
{
|
||||
northwest = corner0;
|
||||
southeast = corner1;
|
||||
}
|
||||
if ( requiredmapaspectratio > 0 )
|
||||
{
|
||||
northportion = vectordot( northwest - southeast, north );
|
||||
westportion = vectordot( northwest - southeast, west );
|
||||
mapaspectratio = westportion / northportion;
|
||||
if ( mapaspectratio < requiredmapaspectratio )
|
||||
{
|
||||
incr = requiredmapaspectratio / mapaspectratio;
|
||||
addvec = vecscale( west, westportion * ( incr - 1 ) * 0.5 );
|
||||
}
|
||||
else
|
||||
{
|
||||
incr = mapaspectratio / requiredmapaspectratio;
|
||||
addvec = vecscale( north, northportion * ( incr - 1 ) * 0.5 );
|
||||
}
|
||||
northwest += addvec;
|
||||
southeast -= addvec;
|
||||
}
|
||||
setminimap( material, northwest[ 0 ], northwest[ 1 ], southeast[ 0 ], southeast[ 1 ] );
|
||||
}
|
||||
|
||||
vecscale( vec, scalar ) //checked matches cerberus output
|
||||
{
|
||||
return ( vec[ 0 ] * scalar, vec[ 1 ] * scalar, vec[ 2 ] * scalar );
|
||||
}
|
3273
Multiplayer Core/patch_mp/maps/mp/_createfx.gsc
Normal file
3273
Multiplayer Core/patch_mp/maps/mp/_createfx.gsc
Normal file
File diff suppressed because it is too large
Load Diff
1019
Multiplayer Core/patch_mp/maps/mp/_createfxmenu.gsc
Normal file
1019
Multiplayer Core/patch_mp/maps/mp/_createfxmenu.gsc
Normal file
File diff suppressed because it is too large
Load Diff
545
Multiplayer Core/patch_mp/maps/mp/_createfxundo.gsc
Normal file
545
Multiplayer Core/patch_mp/maps/mp/_createfxundo.gsc
Normal file
@ -0,0 +1,545 @@
|
||||
#include maps/mp/_createfxmenu;
|
||||
#include maps/mp/_createfx;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
|
||||
store_undo_state( change_type, ents )
|
||||
{
|
||||
if ( !isDefined( level.cfx_undo_states ) )
|
||||
{
|
||||
level.cfx_undo_states = [];
|
||||
level.cfx_redo_states = [];
|
||||
level.cfx_limbo_state = spawnstruct();
|
||||
level.cfx_max_states = 10;
|
||||
}
|
||||
if ( !isarray( ents ) )
|
||||
{
|
||||
ents = array( ents );
|
||||
}
|
||||
temp_array = [];
|
||||
i = 0;
|
||||
while ( i < ents.size )
|
||||
{
|
||||
temp_array[ i ] = copy_fx_ent( ents[ i ] );
|
||||
i++;
|
||||
}
|
||||
state = spawnstruct();
|
||||
state.operation = change_type;
|
||||
state.last_action = level.cfx_last_action;
|
||||
state.ent_array = temp_array;
|
||||
if ( level.cfx_undo_states.size >= level.cfx_max_states )
|
||||
{
|
||||
level.cfx_undo_states = array_drop( level.cfx_undo_states );
|
||||
}
|
||||
level.cfx_undo_states[ level.cfx_undo_states.size ] = state;
|
||||
level.cfx_redo_states = [];
|
||||
level.cfx_limbo_state = undefined;
|
||||
debug_print_latest_state( "undo" );
|
||||
}
|
||||
|
||||
undo()
|
||||
{
|
||||
if ( isDefined( level.createfxent ) || !isDefined( level.cfx_undo_states ) && level.cfx_undo_states.size < 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
revert_state = level.cfx_undo_states[ level.cfx_undo_states.size - 1 ];
|
||||
if ( level.cfx_last_action != "none" )
|
||||
{
|
||||
store_undo_state( "edit", level.selected_fx_ents );
|
||||
move_undo_state_to_redo();
|
||||
clear_entity_selection( "skip_undo" );
|
||||
apply_state_change( "undo", revert_state );
|
||||
move_undo_state_to_limbo();
|
||||
level.cfx_last_action = "none";
|
||||
}
|
||||
else clear_entity_selection( "skip_undo" );
|
||||
if ( revert_state.operation != "edit" )
|
||||
{
|
||||
apply_state_change( "undo", revert_state );
|
||||
move_undo_state_to_redo();
|
||||
level.cfx_last_action = "none";
|
||||
}
|
||||
else if ( isDefined( level.cfx_limbo_state ) )
|
||||
{
|
||||
move_limbo_state_to_redo();
|
||||
apply_state_change( "undo", revert_state );
|
||||
move_undo_state_to_limbo();
|
||||
level.cfx_last_action = "none";
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( level.cfx_undo_states.size > 1 )
|
||||
{
|
||||
move_undo_state_to_redo();
|
||||
revert_state = level.cfx_undo_states[ level.cfx_undo_states.size - 1 ];
|
||||
}
|
||||
apply_state_change( "undo", revert_state );
|
||||
move_undo_state_to_limbo();
|
||||
}
|
||||
}
|
||||
|
||||
apply_state_change( type, revert_state )
|
||||
{
|
||||
if ( type == "undo" )
|
||||
{
|
||||
/#
|
||||
println( "^2CreateFX: Undo operation" );
|
||||
#/
|
||||
if ( revert_state.operation == "edit" )
|
||||
{
|
||||
undo_edit( revert_state.ent_array );
|
||||
}
|
||||
else if ( revert_state.operation == "add" )
|
||||
{
|
||||
undo_add( revert_state.ent_array );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( revert_state.operation == "delete" )
|
||||
{
|
||||
undo_delete( revert_state.ent_array );
|
||||
}
|
||||
}
|
||||
}
|
||||
else /#
|
||||
println( "^2CreateFX: Redo operation" );
|
||||
#/
|
||||
if ( revert_state.operation == "edit" )
|
||||
{
|
||||
undo_edit( revert_state.ent_array );
|
||||
}
|
||||
else if ( revert_state.operation == "add" )
|
||||
{
|
||||
undo_delete( revert_state.ent_array );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( revert_state.operation == "delete" )
|
||||
{
|
||||
undo_add( revert_state.ent_array );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
move_undo_state_to_redo()
|
||||
{
|
||||
if ( level.cfx_redo_states.size >= level.cfx_max_states )
|
||||
{
|
||||
level.cfx_redo_states = array_drop( level.cfx_redo_states );
|
||||
}
|
||||
level.cfx_redo_states[ level.cfx_redo_states.size ] = level.cfx_undo_states[ level.cfx_undo_states.size - 1 ];
|
||||
level.cfx_undo_states = array_pop( level.cfx_undo_states );
|
||||
debug_print_latest_state( "undo" );
|
||||
debug_print_latest_state( "redo" );
|
||||
}
|
||||
|
||||
move_redo_state_to_undo()
|
||||
{
|
||||
if ( level.cfx_undo_states.size >= level.cfx_max_states )
|
||||
{
|
||||
level.cfx_undo_states = array_drop( level.cfx_undo_states );
|
||||
}
|
||||
level.cfx_undo_states[ level.cfx_undo_states.size ] = level.cfx_redo_states[ level.cfx_redo_states.size - 1 ];
|
||||
level.cfx_redo_states = array_pop( level.cfx_redo_states );
|
||||
debug_print_latest_state( "undo" );
|
||||
debug_print_latest_state( "redo" );
|
||||
}
|
||||
|
||||
move_undo_state_to_limbo()
|
||||
{
|
||||
level.cfx_limbo_state = level.cfx_undo_states[ level.cfx_undo_states.size - 1 ];
|
||||
level.cfx_undo_states = array_pop( level.cfx_undo_states );
|
||||
debug_print_latest_state( "undo" );
|
||||
debug_print_latest_state( "limbo" );
|
||||
}
|
||||
|
||||
move_redo_state_to_limbo()
|
||||
{
|
||||
level.cfx_limbo_state = level.cfx_redo_states[ level.cfx_redo_states.size - 1 ];
|
||||
level.cfx_redo_states = array_pop( level.cfx_redo_states );
|
||||
debug_print_latest_state( "redo" );
|
||||
debug_print_latest_state( "limbo" );
|
||||
}
|
||||
|
||||
move_limbo_state_to_undo()
|
||||
{
|
||||
if ( level.cfx_undo_states.size >= level.cfx_max_states )
|
||||
{
|
||||
level.cfx_undo_states = array_drop( level.cfx_undo_states );
|
||||
}
|
||||
level.cfx_undo_states[ level.cfx_undo_states.size ] = level.cfx_limbo_state;
|
||||
level.cfx_limbo_state = undefined;
|
||||
debug_print_latest_state( "undo" );
|
||||
debug_print_latest_state( "limbo" );
|
||||
}
|
||||
|
||||
move_limbo_state_to_redo()
|
||||
{
|
||||
if ( level.cfx_redo_states.size >= level.cfx_max_states )
|
||||
{
|
||||
level.cfx_redo_states = array_drop( level.cfx_redo_states );
|
||||
}
|
||||
level.cfx_redo_states[ level.cfx_redo_states.size ] = level.cfx_limbo_state;
|
||||
level.cfx_limbo_state = undefined;
|
||||
debug_print_latest_state( "redo" );
|
||||
}
|
||||
|
||||
undo_edit( ent_array )
|
||||
{
|
||||
ent_array = reorder_ent_array_by_uniqueid( ent_array );
|
||||
/#
|
||||
println( "^3CreateFX: Undoing edit" );
|
||||
debug_print_ent_array( ent_array, "ent_array[]" );
|
||||
debug_print_ent_array( level.createfxent, "level.createFXent[]" );
|
||||
#/
|
||||
last_id = ent_array[ ent_array.size - 1 ].uniqueid;
|
||||
if ( last_id > ( level.createfxent.size - 1 ) )
|
||||
{
|
||||
last_id = level.createfxent.size - 1;
|
||||
}
|
||||
j = ent_array.size - 1;
|
||||
source_ent = ent_array[ j ];
|
||||
i = last_id;
|
||||
while ( i >= 0 )
|
||||
{
|
||||
target_ent = level.createfxent[ i ];
|
||||
if ( source_ent.uniqueid == target_ent.uniqueid )
|
||||
{
|
||||
copy_values_between_fx_ents( source_ent, target_ent );
|
||||
select_entity( i, target_ent, "skip_undo" );
|
||||
j--;
|
||||
|
||||
if ( j < 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
source_ent = ent_array[ j ];
|
||||
}
|
||||
i--;
|
||||
|
||||
}
|
||||
}
|
||||
update_selected_entities();
|
||||
/#
|
||||
println( "^1CreateFX: Finished edit" );
|
||||
debug_print_ent_array( level.createfxent, "level.createFXent[]" );
|
||||
#/
|
||||
}
|
||||
|
||||
undo_add( ent_array )
|
||||
{
|
||||
ent_array = reorder_ent_array_by_uniqueid( ent_array );
|
||||
/#
|
||||
println( "^3createfx: Undoing add." );
|
||||
debug_print_ent_array( ent_array, "ent_array[]" );
|
||||
debug_print_ent_array( level.createfxent, "level.createFXent[]" );
|
||||
#/
|
||||
last_id = ent_array[ ent_array.size - 1 ].uniqueid;
|
||||
if ( last_id > ( level.createfxent.size - 1 ) )
|
||||
{
|
||||
last_id = level.createfxent.size - 1;
|
||||
}
|
||||
j = ent_array.size - 1;
|
||||
source_ent = ent_array[ j ];
|
||||
i = last_id;
|
||||
while ( i >= 0 )
|
||||
{
|
||||
target_ent = level.createfxent[ i ];
|
||||
if ( source_ent.uniqueid == target_ent.uniqueid )
|
||||
{
|
||||
if ( isDefined( target_ent.looper ) )
|
||||
{
|
||||
target_ent.looper delete();
|
||||
}
|
||||
target_ent notify( "stop_loop" );
|
||||
j--;
|
||||
|
||||
if ( j < 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
source_ent = ent_array[ j ];
|
||||
}
|
||||
i--;
|
||||
|
||||
}
|
||||
}
|
||||
/#
|
||||
debug_print_ent_array( level.createfxent, "level.createFXent[]" );
|
||||
println( "createfx: Starting array_remove_undefined()" );
|
||||
#/
|
||||
arrayremovevalue( level.createfxent, undefined );
|
||||
/#
|
||||
println( "^1CreateFX: Finished undo add." );
|
||||
debug_print_ent_array( level.createfxent, "level.createFXent[]" );
|
||||
#/
|
||||
clear_fx_hudelements();
|
||||
}
|
||||
|
||||
undo_delete( ent_array )
|
||||
{
|
||||
/#
|
||||
println( "^3CreateFX: Undoing delete" );
|
||||
debug_print_ent_array( ent_array, "ent_array in undo_delete()" );
|
||||
debug_print_ent_array( level.createfxent, "level.createFXent[]" );
|
||||
#/
|
||||
ent_array = reorder_ent_array_by_uniqueid( ent_array );
|
||||
if ( level.createfxent.size == 0 )
|
||||
{
|
||||
i = 0;
|
||||
while ( i < ent_array.size )
|
||||
{
|
||||
level.createfxent[ i ] = copy_fx_ent( ent_array[ i ] );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else temp_array = [];
|
||||
i = 0;
|
||||
j = 0;
|
||||
while ( j < level.createfxent.size )
|
||||
{
|
||||
target_ent = level.createfxent[ j ];
|
||||
if ( i >= ent_array.size )
|
||||
{
|
||||
temp_array[ temp_array.size ] = target_ent;
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
else source_ent = ent_array[ i ];
|
||||
if ( target_ent.uniqueid < source_ent.uniqueid )
|
||||
{
|
||||
temp_array[ temp_array.size ] = target_ent;
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_array[ temp_array.size ] = copy_fx_ent( source_ent );
|
||||
j--;
|
||||
|
||||
i++;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
while ( i < ent_array.size )
|
||||
{
|
||||
temp_array[ temp_array.size ] = ent_array[ i ];
|
||||
i++;
|
||||
}
|
||||
level.createfxent = temp_array;
|
||||
/#
|
||||
println( "^1Createfx: Finished undoing delete, pre-selection" );
|
||||
debug_print_ent_array( level.createfxent, "level.createFXent[]" );
|
||||
#/
|
||||
last_id = ent_array[ ent_array.size - 1 ].uniqueid;
|
||||
if ( last_id > ( level.createfxent.size - 1 ) )
|
||||
{
|
||||
last_id = level.createfxent.size - 1;
|
||||
}
|
||||
j = ent_array.size - 1;
|
||||
source_ent = ent_array[ j ];
|
||||
i = last_id;
|
||||
while ( i >= 0 )
|
||||
{
|
||||
target_ent = level.createfxent[ i ];
|
||||
if ( source_ent.uniqueid == target_ent.uniqueid )
|
||||
{
|
||||
target_ent post_entity_creation_function();
|
||||
select_entity( i, target_ent, "skip_undo" );
|
||||
j--;
|
||||
|
||||
if ( j < 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
source_ent = ent_array[ j ];
|
||||
}
|
||||
i--;
|
||||
|
||||
}
|
||||
}
|
||||
update_selected_entities();
|
||||
}
|
||||
|
||||
redo()
|
||||
{
|
||||
if ( isDefined( level.createfxent ) || !isDefined( level.cfx_redo_states ) && level.cfx_redo_states.size < 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
clear_entity_selection( "skip_undo" );
|
||||
if ( isDefined( level.cfx_limbo_state ) )
|
||||
{
|
||||
move_limbo_state_to_undo();
|
||||
move_redo_state_to_limbo();
|
||||
apply_state_change( "redo", level.cfx_limbo_state );
|
||||
}
|
||||
else revert_state = level.cfx_redo_states[ level.cfx_redo_states.size - 1 ];
|
||||
apply_state_change( "redo", revert_state );
|
||||
if ( revert_state.operation == "edit" )
|
||||
{
|
||||
move_redo_state_to_limbo();
|
||||
}
|
||||
else
|
||||
{
|
||||
move_redo_state_to_undo();
|
||||
}
|
||||
level.cfx_last_action = "none";
|
||||
}
|
||||
|
||||
reorder_ent_array_by_uniqueid( ent_array )
|
||||
{
|
||||
if ( ent_array.size <= 1 )
|
||||
{
|
||||
return ent_array;
|
||||
}
|
||||
array_size = ent_array.size;
|
||||
i = 0;
|
||||
while ( i < ( array_size - 1 ) )
|
||||
{
|
||||
j = i + 1;
|
||||
while ( j < array_size )
|
||||
{
|
||||
if ( ent_array[ i ].uniqueid > ent_array[ j ].uniqueid )
|
||||
{
|
||||
temp_ent = ent_array[ i ];
|
||||
ent_array[ i ] = ent_array[ j ];
|
||||
ent_array[ j ] = temp_ent;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return ent_array;
|
||||
}
|
||||
|
||||
copy_fx_ent( ent )
|
||||
{
|
||||
temp_ent = spawnstruct();
|
||||
temp_ent.drawn = ent.drawn;
|
||||
temp_ent.drawn_axis_model = ent.drawn_axis_model;
|
||||
temp_ent.last_fx_index = ent.last_fx_index;
|
||||
temp_ent.textalpha = ent.textalpha;
|
||||
temp_ent.uniqueid = ent.uniqueid;
|
||||
temp_ent.v = ent.v;
|
||||
return temp_ent;
|
||||
}
|
||||
|
||||
copy_values_between_fx_ents( source, dest )
|
||||
{
|
||||
dest.drawn = source.drawn;
|
||||
dest.drawn_axis_model = source.drawn_axis_model;
|
||||
dest.last_fx_index = source.last_fx_index;
|
||||
dest.textalpha = source.textalpha;
|
||||
dest.v = source.v;
|
||||
return dest;
|
||||
}
|
||||
|
||||
array_pop( array )
|
||||
{
|
||||
array_size = array.size - 1;
|
||||
temp_array = [];
|
||||
if ( array_size <= 0 )
|
||||
{
|
||||
return temp_array;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < array_size )
|
||||
{
|
||||
temp_array[ i ] = array[ i ];
|
||||
i++;
|
||||
}
|
||||
array = temp_array;
|
||||
return array;
|
||||
}
|
||||
|
||||
array_drop( array )
|
||||
{
|
||||
if ( array.size > 0 )
|
||||
{
|
||||
temp_array = [];
|
||||
i = 1;
|
||||
while ( i < array.size )
|
||||
{
|
||||
temp_array[ i - 1 ] = array[ i ];
|
||||
i++;
|
||||
}
|
||||
array = temp_array;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
debug_print_ent_array( array, name )
|
||||
{
|
||||
/#
|
||||
if ( isDefined( name ) )
|
||||
{
|
||||
println( "Printing out " + name );
|
||||
}
|
||||
else
|
||||
{
|
||||
println( "Printing out some array" );
|
||||
}
|
||||
i = 0;
|
||||
while ( i < array.size )
|
||||
{
|
||||
if ( !isDefined( array[ i ] ) )
|
||||
{
|
||||
println( "" + i + ": deleted effect" );
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
println( "" + i + ": uniqueid: " + array[ i ].uniqueid + " fxid: " + array[ i ].v[ "fxid" ] );
|
||||
}
|
||||
i++;
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
debug_print_latest_state( type )
|
||||
{
|
||||
/#
|
||||
println( "^3Saving " + type + " state" );
|
||||
if ( type == "undo" )
|
||||
{
|
||||
if ( !isDefined( level.cfx_undo_states[ level.cfx_undo_states.size - 1 ] ) )
|
||||
{
|
||||
println( "There are no undo states." );
|
||||
return;
|
||||
}
|
||||
state = level.cfx_undo_states[ level.cfx_undo_states.size - 1 ];
|
||||
size = level.cfx_undo_states.size - 1;
|
||||
}
|
||||
else if ( type == "redo" )
|
||||
{
|
||||
if ( !isDefined( level.cfx_redo_states[ level.cfx_redo_states.size - 1 ] ) )
|
||||
{
|
||||
println( "There are no redo states." );
|
||||
return;
|
||||
}
|
||||
state = level.cfx_redo_states[ level.cfx_redo_states.size - 1 ];
|
||||
size = level.cfx_redo_states.size - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !isDefined( level.cfx_limbo_state ) )
|
||||
{
|
||||
println( "There is no limbo state." );
|
||||
return;
|
||||
}
|
||||
state = level.cfx_limbo_state;
|
||||
size = 0;
|
||||
}
|
||||
println( "State " + size + " - " + state.operation + ": " + state.last_action );
|
||||
debug_print_ent_array( state.ent_array, "save state ent_array" );
|
||||
#/
|
||||
}
|
355
Multiplayer Core/patch_mp/maps/mp/_decoy.gsc
Normal file
355
Multiplayer Core/patch_mp/maps/mp/_decoy.gsc
Normal file
@ -0,0 +1,355 @@
|
||||
#include maps/mp/_entityheadicons;
|
||||
#include maps/mp/gametypes/_weaponobjects;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level.decoyweapons = [];
|
||||
level.decoyweapons[ "fullauto" ] = [];
|
||||
level.decoyweapons[ "semiauto" ] = [];
|
||||
level.decoyweapons[ "fullauto" ][ level.decoyweapons[ "fullauto" ].size ] = "uzi_mp";
|
||||
level.decoyweapons[ "semiauto" ][ level.decoyweapons[ "semiauto" ].size ] = "m1911_mp";
|
||||
level.decoyweapons[ "semiauto" ][ level.decoyweapons[ "semiauto" ].size ] = "python_mp";
|
||||
level.decoyweapons[ "semiauto" ][ level.decoyweapons[ "semiauto" ].size ] = "cz75_mp";
|
||||
level.decoyweapons[ "semiauto" ][ level.decoyweapons[ "semiauto" ].size ] = "fnfal_mp";
|
||||
}
|
||||
|
||||
createdecoywatcher()
|
||||
{
|
||||
watcher = self maps/mp/gametypes/_weaponobjects::createuseweaponobjectwatcher( "nightingale", "nightingale_mp", self.team );
|
||||
watcher.onspawn = ::onspawndecoy;
|
||||
watcher.detonate = ::decoydetonate;
|
||||
watcher.deleteondifferentobjectspawn = 0;
|
||||
watcher.headicon = 0;
|
||||
}
|
||||
|
||||
onspawndecoy( watcher, owner )
|
||||
{
|
||||
owner endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
maps/mp/gametypes/_weaponobjects::onspawnuseweaponobject( watcher, owner );
|
||||
self.initial_velocity = self getvelocity();
|
||||
delay = 1;
|
||||
wait delay;
|
||||
decoy_time = 30;
|
||||
spawn_time = getTime();
|
||||
owner addweaponstat( "nightingale_mp", "used", 1 );
|
||||
self thread simulateweaponfire( owner );
|
||||
while ( 1 )
|
||||
{
|
||||
if ( getTime() > ( spawn_time + ( decoy_time * 1000 ) ) )
|
||||
{
|
||||
self destroydecoy( watcher, owner );
|
||||
return;
|
||||
}
|
||||
wait 0,05;
|
||||
}
|
||||
}
|
||||
|
||||
movedecoy( owner, count, fire_time, main_dir, max_offset_angle )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "done" );
|
||||
if ( !self isonground() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
min_speed = 100;
|
||||
max_speed = 200;
|
||||
min_up_speed = 100;
|
||||
max_up_speed = 200;
|
||||
current_main_dir = randomintrange( main_dir - max_offset_angle, main_dir + max_offset_angle );
|
||||
avel = ( randomfloatrange( 800, 1800 ) * ( ( randomintrange( 0, 2 ) * 2 ) - 1 ), 0, randomfloatrange( 580, 940 ) * ( ( randomintrange( 0, 2 ) * 2 ) - 1 ) );
|
||||
intial_up = randomfloatrange( min_up_speed, max_up_speed );
|
||||
start_time = getTime();
|
||||
gravity = getDvarInt( "bg_gravity" );
|
||||
i = 0;
|
||||
while ( i < 1 )
|
||||
{
|
||||
angles = ( 0, randomintrange( current_main_dir - max_offset_angle, current_main_dir + max_offset_angle ), 0 );
|
||||
dir = anglesToForward( angles );
|
||||
dir = vectorScale( dir, randomfloatrange( min_speed, max_speed ) );
|
||||
deltatime = ( getTime() - start_time ) * 0,001;
|
||||
up = ( 0, 0, intial_up - ( 800 * deltatime ) );
|
||||
self launch( dir + up, avel );
|
||||
wait fire_time;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
destroydecoy( watcher, owner )
|
||||
{
|
||||
self notify( "done" );
|
||||
self maps/mp/_entityheadicons::setentityheadicon( "none" );
|
||||
}
|
||||
|
||||
decoydetonate( attacker )
|
||||
{
|
||||
self notify( "done" );
|
||||
self maps/mp/_entityheadicons::setentityheadicon( "none" );
|
||||
}
|
||||
|
||||
getweaponfordecoy( owner )
|
||||
{
|
||||
weapon = pickrandomweapon();
|
||||
return weapon;
|
||||
}
|
||||
|
||||
simulateweaponfire( owner )
|
||||
{
|
||||
owner endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self endon( "done" );
|
||||
weapon = getweaponfordecoy( owner );
|
||||
if ( weapon == "none" )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self thread watchforexplosion( owner, weapon );
|
||||
self thread trackmaindirection();
|
||||
self.max_offset_angle = 30;
|
||||
weapon_class = getweaponclass( weapon );
|
||||
switch( weapon_class )
|
||||
{
|
||||
case "weapon_assault":
|
||||
case "weapon_cqb":
|
||||
case "weapon_hmg":
|
||||
case "weapon_lmg":
|
||||
case "weapon_smg":
|
||||
simulateweaponfiremachinegun( owner, weapon );
|
||||
break;
|
||||
case "weapon_sniper":
|
||||
simulateweaponfiresniper( owner, weapon );
|
||||
break;
|
||||
case "weapon_pistol":
|
||||
simulateweaponfirepistol( owner, weapon );
|
||||
break;
|
||||
case "weapon_shotgun":
|
||||
simulateweaponfireshotgun( owner, weapon );
|
||||
break;
|
||||
default:
|
||||
simulateweaponfiremachinegun( owner, weapon );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
simulateweaponfiremachinegun( owner, weapon )
|
||||
{
|
||||
if ( weaponissemiauto( weapon ) )
|
||||
{
|
||||
simulateweaponfiremachinegunsemiauto( owner, weapon );
|
||||
}
|
||||
else
|
||||
{
|
||||
simulateweaponfiremachinegunfullauto( owner, weapon );
|
||||
}
|
||||
}
|
||||
|
||||
simulateweaponfiremachinegunsemiauto( owner, weapon )
|
||||
{
|
||||
firetime = weaponfiretime( weapon );
|
||||
clipsize = weaponclipsize( weapon );
|
||||
reloadtime = weaponreloadtime( weapon );
|
||||
burst_spacing_min = 4;
|
||||
burst_spacing_max = 10;
|
||||
while ( 1 )
|
||||
{
|
||||
if ( clipsize <= 1 )
|
||||
{
|
||||
burst_count = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
burst_count = randomintrange( 1, clipsize );
|
||||
}
|
||||
self thread movedecoy( owner, burst_count, firetime, self.main_dir, self.max_offset_angle );
|
||||
self fireburst( owner, weapon, firetime, burst_count, 1 );
|
||||
finishwhileloop( weapon, reloadtime, burst_spacing_min, burst_spacing_max );
|
||||
}
|
||||
}
|
||||
|
||||
simulateweaponfirepistol( owner, weapon )
|
||||
{
|
||||
firetime = weaponfiretime( weapon );
|
||||
clipsize = weaponclipsize( weapon );
|
||||
reloadtime = weaponreloadtime( weapon );
|
||||
burst_spacing_min = 0,5;
|
||||
burst_spacing_max = 4;
|
||||
while ( 1 )
|
||||
{
|
||||
burst_count = randomintrange( 1, clipsize );
|
||||
self thread movedecoy( owner, burst_count, firetime, self.main_dir, self.max_offset_angle );
|
||||
self fireburst( owner, weapon, firetime, burst_count, 0 );
|
||||
finishwhileloop( weapon, reloadtime, burst_spacing_min, burst_spacing_max );
|
||||
}
|
||||
}
|
||||
|
||||
simulateweaponfireshotgun( owner, weapon )
|
||||
{
|
||||
firetime = weaponfiretime( weapon );
|
||||
clipsize = weaponclipsize( weapon );
|
||||
reloadtime = weaponreloadtime( weapon );
|
||||
if ( clipsize > 2 )
|
||||
{
|
||||
clipsize = 2;
|
||||
}
|
||||
burst_spacing_min = 0,5;
|
||||
burst_spacing_max = 4;
|
||||
while ( 1 )
|
||||
{
|
||||
burst_count = randomintrange( 1, clipsize );
|
||||
self thread movedecoy( owner, burst_count, firetime, self.main_dir, self.max_offset_angle );
|
||||
self fireburst( owner, weapon, firetime, burst_count, 0 );
|
||||
finishwhileloop( weapon, reloadtime, burst_spacing_min, burst_spacing_max );
|
||||
}
|
||||
}
|
||||
|
||||
simulateweaponfiremachinegunfullauto( owner, weapon )
|
||||
{
|
||||
firetime = weaponfiretime( weapon );
|
||||
clipsize = weaponclipsize( weapon );
|
||||
reloadtime = weaponreloadtime( weapon );
|
||||
if ( clipsize > 30 )
|
||||
{
|
||||
clipsize = 30;
|
||||
}
|
||||
burst_spacing_min = 2;
|
||||
burst_spacing_max = 6;
|
||||
while ( 1 )
|
||||
{
|
||||
burst_count = randomintrange( int( clipsize * 0,6 ), clipsize );
|
||||
interrupt = 0;
|
||||
self thread movedecoy( owner, burst_count, firetime, self.main_dir, self.max_offset_angle );
|
||||
self fireburst( owner, weapon, firetime, burst_count, interrupt );
|
||||
finishwhileloop( weapon, reloadtime, burst_spacing_min, burst_spacing_max );
|
||||
}
|
||||
}
|
||||
|
||||
simulateweaponfiresniper( owner, weapon )
|
||||
{
|
||||
firetime = weaponfiretime( weapon );
|
||||
clipsize = weaponclipsize( weapon );
|
||||
reloadtime = weaponreloadtime( weapon );
|
||||
if ( clipsize > 2 )
|
||||
{
|
||||
clipsize = 2;
|
||||
}
|
||||
burst_spacing_min = 3;
|
||||
burst_spacing_max = 5;
|
||||
while ( 1 )
|
||||
{
|
||||
burst_count = randomintrange( 1, clipsize );
|
||||
self thread movedecoy( owner, burst_count, firetime, self.main_dir, self.max_offset_angle );
|
||||
self fireburst( owner, weapon, firetime, burst_count, 0 );
|
||||
finishwhileloop( weapon, reloadtime, burst_spacing_min, burst_spacing_max );
|
||||
}
|
||||
}
|
||||
|
||||
fireburst( owner, weapon, firetime, count, interrupt )
|
||||
{
|
||||
interrupt_shot = count;
|
||||
if ( interrupt )
|
||||
{
|
||||
interrupt_shot = int( count * randomfloatrange( 0,6, 0,8 ) );
|
||||
}
|
||||
self fakefire( owner, self.origin, weapon, interrupt_shot );
|
||||
wait ( firetime * interrupt_shot );
|
||||
if ( interrupt )
|
||||
{
|
||||
self fakefire( owner, self.origin, weapon, count - interrupt_shot );
|
||||
wait ( firetime * ( count - interrupt_shot ) );
|
||||
}
|
||||
}
|
||||
|
||||
finishwhileloop( weapon, reloadtime, burst_spacing_min, burst_spacing_max )
|
||||
{
|
||||
if ( shouldplayreloadsound() )
|
||||
{
|
||||
playreloadsounds( weapon, reloadtime );
|
||||
}
|
||||
else
|
||||
{
|
||||
wait randomfloatrange( burst_spacing_min, burst_spacing_max );
|
||||
}
|
||||
}
|
||||
|
||||
playreloadsounds( weapon, reloadtime )
|
||||
{
|
||||
divy_it_up = ( reloadtime - 0,1 ) / 2;
|
||||
wait 0,1;
|
||||
self playsound( "fly_assault_reload_npc_mag_out" );
|
||||
wait divy_it_up;
|
||||
self playsound( "fly_assault_reload_npc_mag_in" );
|
||||
wait divy_it_up;
|
||||
}
|
||||
|
||||
watchforexplosion( owner, weapon )
|
||||
{
|
||||
self thread watchfordeathbeforeexplosion();
|
||||
owner endon( "disconnect" );
|
||||
self endon( "death_before_explode" );
|
||||
self waittill( "explode", pos );
|
||||
level thread doexplosion( owner, pos, weapon, randomintrange( 5, 10 ) );
|
||||
}
|
||||
|
||||
watchfordeathbeforeexplosion()
|
||||
{
|
||||
self waittill( "death" );
|
||||
wait 0,1;
|
||||
self notify( "death_before_explode" );
|
||||
}
|
||||
|
||||
doexplosion( owner, pos, weapon, count )
|
||||
{
|
||||
min_offset = 100;
|
||||
max_offset = 500;
|
||||
i = 0;
|
||||
while ( i < count )
|
||||
{
|
||||
wait randomfloatrange( 0,1, 0,5 );
|
||||
offset = ( randomfloatrange( min_offset, max_offset ) * ( ( randomintrange( 0, 2 ) * 2 ) - 1 ), randomfloatrange( min_offset, max_offset ) * ( ( randomintrange( 0, 2 ) * 2 ) - 1 ), 0 );
|
||||
owner fakefire( owner, pos + offset, weapon, 1 );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
pickrandomweapon()
|
||||
{
|
||||
type = "fullauto";
|
||||
if ( randomintrange( 0, 10 ) < 3 )
|
||||
{
|
||||
type = "semiauto";
|
||||
}
|
||||
randomval = randomintrange( 0, level.decoyweapons[ type ].size );
|
||||
/#
|
||||
println( "Decoy type: " + type + " weapon: " + level.decoyweapons[ type ][ randomval ] );
|
||||
#/
|
||||
return level.decoyweapons[ type ][ randomval ];
|
||||
}
|
||||
|
||||
shouldplayreloadsound()
|
||||
{
|
||||
if ( randomintrange( 0, 5 ) == 1 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
trackmaindirection()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "done" );
|
||||
self.main_dir = int( vectorToAngle( ( self.initial_velocity[ 0 ], self.initial_velocity[ 1 ], 0 ) )[ 1 ] );
|
||||
up = ( 0, 0, 1 );
|
||||
while ( 1 )
|
||||
{
|
||||
self waittill( "grenade_bounce", pos, normal );
|
||||
dot = vectordot( normal, up );
|
||||
if ( dot < 0,5 && dot > -0,5 )
|
||||
{
|
||||
self.main_dir = int( vectorToAngle( ( normal[ 0 ], normal[ 1 ], 0 ) )[ 1 ] );
|
||||
}
|
||||
}
|
||||
}
|
102
Multiplayer Core/patch_mp/maps/mp/_demo.gsc
Normal file
102
Multiplayer Core/patch_mp/maps/mp/_demo.gsc
Normal file
@ -0,0 +1,102 @@
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
level.bookmark[ "kill" ] = 0;
|
||||
level.bookmark[ "event" ] = 1;
|
||||
level.bookmark[ "zm_round_end" ] = 2;
|
||||
level.bookmark[ "zm_player_downed" ] = 3;
|
||||
level.bookmark[ "zm_player_revived" ] = 4;
|
||||
level.bookmark[ "zm_player_bledout" ] = 5;
|
||||
level.bookmark[ "zm_player_use_magicbox" ] = 6;
|
||||
level.bookmark[ "score_event" ] = 7;
|
||||
level.bookmark[ "medal" ] = 8;
|
||||
level.bookmark[ "round_result" ] = 9;
|
||||
level.bookmark[ "game_result" ] = 10;
|
||||
level.bookmark[ "zm_powerup_dropped" ] = 11;
|
||||
level.bookmark[ "zm_player_powerup_grabbed" ] = 12;
|
||||
level.bookmark[ "zm_player_perk" ] = 13;
|
||||
level.bookmark[ "zm_power" ] = 14;
|
||||
level.bookmark[ "zm_player_door" ] = 15;
|
||||
level.bookmark[ "zm_player_buildable_placed" ] = 16;
|
||||
level.bookmark[ "zm_player_use_packapunch" ] = 17;
|
||||
level.bookmark[ "zm_player_rampage" ] = 18;
|
||||
level.bookmark[ "zm_player_grenade_special" ] = 19;
|
||||
level.bookmark[ "zm_player_grenade_multiattack" ] = 20;
|
||||
level.bookmark[ "zm_player_meat_stink" ] = 21;
|
||||
level.bookmark[ "zm_player_grabbed_magicbox" ] = 22;
|
||||
level.bookmark[ "zm_player_grabbed_packapunch" ] = 23;
|
||||
level.bookmark[ "zm_player_grenade_special_long" ] = 24;
|
||||
}
|
||||
|
||||
bookmark( type, time, clientent1, clientent2, eventpriority, inflictorent, overrideentitycamera, actorent ) //checked matches cerberus output
|
||||
{
|
||||
/*
|
||||
/#
|
||||
assert( isDefined( level.bookmark[ type ] ), "Unable to find a bookmark type for type - " + type );
|
||||
#/
|
||||
*/
|
||||
client1 = 255;
|
||||
client2 = 255;
|
||||
inflictorentnum = -1;
|
||||
inflictorenttype = 0;
|
||||
inflictorbirthtime = 0;
|
||||
actorentnum = undefined;
|
||||
scoreeventpriority = 0;
|
||||
if ( isDefined( clientent1 ) )
|
||||
{
|
||||
client1 = clientent1 getentitynumber();
|
||||
}
|
||||
if ( isDefined( clientent2 ) )
|
||||
{
|
||||
client2 = clientent2 getentitynumber();
|
||||
}
|
||||
if ( isDefined( eventpriority ) )
|
||||
{
|
||||
scoreeventpriority = eventpriority;
|
||||
}
|
||||
if ( isDefined( inflictorent ) )
|
||||
{
|
||||
inflictorentnum = inflictorent getentitynumber();
|
||||
inflictorenttype = inflictorent getentitytype();
|
||||
if ( isDefined( inflictorent.birthtime ) )
|
||||
{
|
||||
inflictorbirthtime = inflictorent.birthtime;
|
||||
}
|
||||
}
|
||||
if ( !isDefined( overrideentitycamera ) )
|
||||
{
|
||||
overrideentitycamera = 0;
|
||||
}
|
||||
if ( isDefined( actorent ) )
|
||||
{
|
||||
actorentnum = actorent getentitynumber();
|
||||
}
|
||||
adddemobookmark( level.bookmark[ type ], time, client1, client2, scoreeventpriority, inflictorentnum, inflictorenttype, inflictorbirthtime, overrideentitycamera, actorentnum );
|
||||
}
|
||||
|
||||
gameresultbookmark( type, winningteamindex, losingteamindex ) //checked matches cerberus output
|
||||
{
|
||||
/*
|
||||
/#
|
||||
assert( isDefined( level.bookmark[ type ] ), "Unable to find a bookmark type for type - " + type );
|
||||
#/
|
||||
*/
|
||||
client1 = 255;
|
||||
client2 = 255;
|
||||
scoreeventpriority = 0;
|
||||
inflictorentnum = -1;
|
||||
inflictorenttype = 0;
|
||||
inflictorbirthtime = 0;
|
||||
overrideentitycamera = 0;
|
||||
actorentnum = undefined;
|
||||
if ( isDefined( winningteamindex ) )
|
||||
{
|
||||
client1 = winningteamindex;
|
||||
}
|
||||
if ( isDefined( losingteamindex ) )
|
||||
{
|
||||
client2 = losingteamindex;
|
||||
}
|
||||
adddemobookmark( level.bookmark[ type ], getTime(), client1, client2, scoreeventpriority, inflictorentnum, inflictorenttype, inflictorbirthtime, overrideentitycamera, actorentnum );
|
||||
}
|
||||
|
480
Multiplayer Core/patch_mp/maps/mp/_destructible.gsc
Normal file
480
Multiplayer Core/patch_mp/maps/mp/_destructible.gsc
Normal file
@ -0,0 +1,480 @@
|
||||
#include maps/mp/_challenges;
|
||||
#include maps/mp/gametypes/_globallogic_player;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
#using_animtree( "mp_vehicles" );
|
||||
|
||||
init()
|
||||
{
|
||||
level.destructible_callbacks = [];
|
||||
destructibles = getentarray( "destructible", "targetname" );
|
||||
if ( destructibles.size <= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
precacheitem( "destructible_car_mp" );
|
||||
precacheitem( "explodable_barrel_mp" );
|
||||
i = 0;
|
||||
while ( i < destructibles.size )
|
||||
{
|
||||
if ( getsubstr( destructibles[ i ].destructibledef, 0, 4 ) == "veh_" )
|
||||
{
|
||||
destructibles[ i ] thread destructible_car_death_think();
|
||||
destructibles[ i ] thread destructible_car_grenade_stuck_think();
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if ( issubstr( destructibles[ i ].destructibledef, "barrel" ) )
|
||||
{
|
||||
destructibles[ i ] thread destructible_barrel_death_think();
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if ( issubstr( destructibles[ i ].destructibledef, "gaspump" ) )
|
||||
{
|
||||
destructibles[ i ] thread destructible_barrel_death_think();
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( destructibles[ i ].destructibledef == "fxdest_upl_metal_tank_01" )
|
||||
{
|
||||
destructibles[ i ] thread destructible_tank_grenade_stuck_think();
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
destructible_anims = [];
|
||||
destructible_anims[ "car" ] = %veh_car_destroy;
|
||||
}
|
||||
|
||||
destructible_event_callback( destructible_event, attacker, weapon )
|
||||
{
|
||||
explosion_radius = 0;
|
||||
if ( issubstr( destructible_event, "explode" ) && destructible_event != "explode" )
|
||||
{
|
||||
tokens = strtok( destructible_event, "_" );
|
||||
explosion_radius = tokens[ 1 ];
|
||||
if ( explosion_radius == "sm" )
|
||||
{
|
||||
explosion_radius = 150;
|
||||
}
|
||||
else if ( explosion_radius == "lg" )
|
||||
{
|
||||
explosion_radius = 450;
|
||||
}
|
||||
else
|
||||
{
|
||||
explosion_radius = int( explosion_radius );
|
||||
}
|
||||
destructible_event = "explode_complex";
|
||||
}
|
||||
if ( issubstr( destructible_event, "simple_timed_explosion" ) )
|
||||
{
|
||||
self thread simple_timed_explosion( destructible_event, attacker );
|
||||
return;
|
||||
}
|
||||
switch( destructible_event )
|
||||
{
|
||||
case "destructible_car_explosion":
|
||||
self destructible_car_explosion( attacker );
|
||||
if ( isDefined( weapon ) )
|
||||
{
|
||||
self.destroyingweapon = weapon;
|
||||
}
|
||||
break;
|
||||
case "destructible_car_fire":
|
||||
self thread destructible_car_fire_think( attacker );
|
||||
if ( isDefined( weapon ) )
|
||||
{
|
||||
self.destroyingweapon = weapon;
|
||||
}
|
||||
break;
|
||||
case "destructible_barrel_fire":
|
||||
self thread destructible_barrel_fire_think( attacker );
|
||||
break;
|
||||
case "destructible_barrel_explosion":
|
||||
self destructible_barrel_explosion( attacker );
|
||||
break;
|
||||
case "explode":
|
||||
self thread simple_explosion( attacker );
|
||||
break;
|
||||
case "explode_complex":
|
||||
self thread complex_explosion( attacker, explosion_radius );
|
||||
break;
|
||||
default:
|
||||
}
|
||||
if ( isDefined( level.destructible_callbacks[ destructible_event ] ) )
|
||||
{
|
||||
self thread [[ level.destructible_callbacks[ destructible_event ] ]]( destructible_event, attacker );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simple_explosion( attacker )
|
||||
{
|
||||
if ( is_true( self.exploded ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self.exploded = 1;
|
||||
offset = vectorScale( ( 0, 0, 1 ), 5 );
|
||||
self radiusdamage( self.origin + offset, 256, 300, 75, attacker, "MOD_EXPLOSIVE", "explodable_barrel_mp" );
|
||||
physicsexplosionsphere( self.origin, 255, 254, 0,3, 400, 25 );
|
||||
if ( isDefined( attacker ) )
|
||||
{
|
||||
self dodamage( self.health + 10000, self.origin + offset, attacker );
|
||||
}
|
||||
else
|
||||
{
|
||||
self dodamage( self.health + 10000, self.origin + offset );
|
||||
}
|
||||
}
|
||||
|
||||
simple_timed_explosion( destructible_event, attacker )
|
||||
{
|
||||
self endon( "death" );
|
||||
wait_times = [];
|
||||
str = getsubstr( destructible_event, 23 );
|
||||
tokens = strtok( str, "_" );
|
||||
i = 0;
|
||||
while ( i < tokens.size )
|
||||
{
|
||||
wait_times[ wait_times.size ] = int( tokens[ i ] );
|
||||
i++;
|
||||
}
|
||||
if ( wait_times.size <= 0 )
|
||||
{
|
||||
wait_times[ 0 ] = 5;
|
||||
wait_times[ 1 ] = 10;
|
||||
}
|
||||
wait randomintrange( wait_times[ 0 ], wait_times[ 1 ] );
|
||||
simple_explosion( attacker );
|
||||
}
|
||||
|
||||
complex_explosion( attacker, max_radius )
|
||||
{
|
||||
offset = vectorScale( ( 0, 0, 1 ), 5 );
|
||||
if ( isDefined( attacker ) )
|
||||
{
|
||||
self radiusdamage( self.origin + offset, max_radius, 300, 100, attacker );
|
||||
}
|
||||
else
|
||||
{
|
||||
self radiusdamage( self.origin + offset, max_radius, 300, 100 );
|
||||
}
|
||||
playrumbleonposition( "grenade_rumble", self.origin );
|
||||
earthquake( 0,5, 0,5, self.origin, max_radius );
|
||||
physicsexplosionsphere( self.origin + offset, max_radius, max_radius - 1, 0,3 );
|
||||
if ( isDefined( attacker ) )
|
||||
{
|
||||
self dodamage( 20000, self.origin + offset, attacker );
|
||||
}
|
||||
else
|
||||
{
|
||||
self dodamage( 20000, self.origin + offset );
|
||||
}
|
||||
}
|
||||
|
||||
destructible_car_explosion( attacker, physics_explosion )
|
||||
{
|
||||
if ( self.car_dead )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( !isDefined( physics_explosion ) )
|
||||
{
|
||||
physics_explosion = 1;
|
||||
}
|
||||
players = get_players();
|
||||
i = 0;
|
||||
while ( i < players.size )
|
||||
{
|
||||
body = players[ i ].body;
|
||||
if ( !isDefined( body ) )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if ( distancesquared( body.origin, self.origin ) > 9216 )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ( body.origin[ 2 ] - ( self.origin[ 2 ] + 32 ) ) > 0 )
|
||||
{
|
||||
body.origin = ( body.origin[ 0 ], body.origin[ 1 ], body.origin[ 2 ] + 16 );
|
||||
}
|
||||
body maps/mp/gametypes/_globallogic_player::start_explosive_ragdoll();
|
||||
}
|
||||
i++;
|
||||
}
|
||||
self notify( "car_dead" );
|
||||
self.car_dead = 1;
|
||||
self thread destructible_car_explosion_animate();
|
||||
if ( isDefined( attacker ) )
|
||||
{
|
||||
self radiusdamage( self.origin, 256, 300, 75, attacker, "MOD_EXPLOSIVE", "destructible_car_mp" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self radiusdamage( self.origin, 256, 300, 75 );
|
||||
}
|
||||
playrumbleonposition( "grenade_rumble", self.origin );
|
||||
earthquake( 0,5, 0,5, self.origin, 800 );
|
||||
if ( physics_explosion )
|
||||
{
|
||||
physicsexplosionsphere( self.origin, 255, 254, 0,3, 400, 25 );
|
||||
}
|
||||
if ( isDefined( attacker ) )
|
||||
{
|
||||
attacker thread maps/mp/_challenges::destroyed_car();
|
||||
}
|
||||
level.globalcarsdestroyed++;
|
||||
if ( isDefined( attacker ) )
|
||||
{
|
||||
self dodamage( self.health + 10000, self.origin + ( 0, 0, 1 ), attacker );
|
||||
}
|
||||
else
|
||||
{
|
||||
self dodamage( self.health + 10000, self.origin + ( 0, 0, 1 ) );
|
||||
}
|
||||
self setclientflag( 3 );
|
||||
}
|
||||
|
||||
destructible_tank_grenade_stuck_think()
|
||||
{
|
||||
self endon( "destructible_base_piece_death" );
|
||||
self endon( "death" );
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "grenade_stuck", missile );
|
||||
if ( !isDefined( missile ) || !isDefined( missile.model ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( missile.model != "t5_weapon_crossbow_bolt" || missile.model == "t6_wpn_grenade_semtex_projectile" && missile.model == "t6_wpn_c4_world" )
|
||||
{
|
||||
self thread destructible_tank_grenade_stuck_explode( missile );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
destructible_tank_grenade_stuck_explode( missile )
|
||||
{
|
||||
self endon( "destructible_base_piece_death" );
|
||||
self endon( "death" );
|
||||
owner = getmissileowner( missile );
|
||||
if ( isDefined( owner ) && missile.model == "t6_wpn_c4_world" )
|
||||
{
|
||||
owner endon( "disconnect" );
|
||||
owner endon( "weapon_object_destroyed" );
|
||||
missile endon( "picked_up" );
|
||||
missile thread destructible_tank_hacked_c4( self );
|
||||
}
|
||||
missile waittill( "explode" );
|
||||
if ( isDefined( owner ) )
|
||||
{
|
||||
self dodamage( self.health + 10000, self.origin + ( 0, 0, 1 ), owner );
|
||||
}
|
||||
else
|
||||
{
|
||||
self dodamage( self.health + 10000, self.origin + ( 0, 0, 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
destructible_tank_hacked_c4( tank )
|
||||
{
|
||||
tank endon( "destructible_base_piece_death" );
|
||||
tank endon( "death" );
|
||||
self endon( "death" );
|
||||
self waittill( "hacked" );
|
||||
self notify( "picked_up" );
|
||||
tank thread destructible_tank_grenade_stuck_explode( self );
|
||||
}
|
||||
|
||||
destructible_car_death_think()
|
||||
{
|
||||
self endon( "car_dead" );
|
||||
self.car_dead = 0;
|
||||
self thread destructible_car_death_notify();
|
||||
self waittill( "destructible_base_piece_death", attacker );
|
||||
if ( isDefined( self ) )
|
||||
{
|
||||
self thread destructible_car_explosion( attacker, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
destructible_car_grenade_stuck_think()
|
||||
{
|
||||
self endon( "destructible_base_piece_death" );
|
||||
self endon( "car_dead" );
|
||||
self endon( "death" );
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "grenade_stuck", missile );
|
||||
if ( !isDefined( missile ) || !isDefined( missile.model ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( missile.model != "t5_weapon_crossbow_bolt" || missile.model == "t6_wpn_grenade_semtex_projectile" && missile.model == "t6_wpn_c4_world" )
|
||||
{
|
||||
self thread destructible_car_grenade_stuck_explode( missile );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
destructible_car_grenade_stuck_explode( missile )
|
||||
{
|
||||
self endon( "destructible_base_piece_death" );
|
||||
self endon( "car_dead" );
|
||||
self endon( "death" );
|
||||
owner = getmissileowner( missile );
|
||||
if ( isDefined( owner ) && missile.model == "t6_wpn_c4_world" )
|
||||
{
|
||||
owner endon( "disconnect" );
|
||||
owner endon( "weapon_object_destroyed" );
|
||||
missile endon( "picked_up" );
|
||||
missile thread destructible_car_hacked_c4( self );
|
||||
}
|
||||
missile waittill( "explode" );
|
||||
if ( isDefined( owner ) )
|
||||
{
|
||||
self dodamage( self.health + 10000, self.origin + ( 0, 0, 1 ), owner );
|
||||
}
|
||||
else
|
||||
{
|
||||
self dodamage( self.health + 10000, self.origin + ( 0, 0, 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
destructible_car_hacked_c4( car )
|
||||
{
|
||||
car endon( "destructible_base_piece_death" );
|
||||
car endon( "car_dead" );
|
||||
car endon( "death" );
|
||||
self endon( "death" );
|
||||
self waittill( "hacked" );
|
||||
self notify( "picked_up" );
|
||||
car thread destructible_car_grenade_stuck_explode( self );
|
||||
}
|
||||
|
||||
destructible_car_death_notify()
|
||||
{
|
||||
self endon( "car_dead" );
|
||||
self waittill( "death", attacker );
|
||||
self notify( "destructible_base_piece_death" );
|
||||
}
|
||||
|
||||
destructible_car_explosion_animate()
|
||||
{
|
||||
self setclientflag( 12 );
|
||||
end_origin = self.origin;
|
||||
self.origin = ( self.origin[ 0 ], self.origin[ 1 ], self.origin[ 2 ] + 16 );
|
||||
wait 0,3;
|
||||
items = getdroppedweapons();
|
||||
i = 0;
|
||||
while ( i < items.size )
|
||||
{
|
||||
if ( distancesquared( end_origin, items[ i ].origin ) < 16384 )
|
||||
{
|
||||
if ( ( items[ i ].origin[ 2 ] - ( end_origin[ 2 ] + 32 ) ) > 0 )
|
||||
{
|
||||
items[ i ] delete();
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
self moveto( end_origin, 0,3, 0,15 );
|
||||
self clearclientflag( 12 );
|
||||
}
|
||||
|
||||
destructible_car_fire_think( attacker )
|
||||
{
|
||||
self endon( "death" );
|
||||
wait randomintrange( 7, 10 );
|
||||
self thread destructible_car_explosion( attacker );
|
||||
}
|
||||
|
||||
codecallback_destructibleevent( event, param1, param2, param3 )
|
||||
{
|
||||
if ( event == "broken" )
|
||||
{
|
||||
notify_type = param1;
|
||||
attacker = param2;
|
||||
weapon = param3;
|
||||
destructible_event_callback( notify_type, attacker, weapon );
|
||||
self notify( event );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( event == "breakafter" )
|
||||
{
|
||||
piece = param1;
|
||||
time = param2;
|
||||
damage = param3;
|
||||
self thread breakafter( time, damage, piece );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
breakafter( time, damage, piece )
|
||||
{
|
||||
self notify( "breakafter" );
|
||||
self endon( "breakafter" );
|
||||
wait time;
|
||||
self dodamage( damage, self.origin, undefined, undefined );
|
||||
}
|
||||
|
||||
destructible_barrel_death_think()
|
||||
{
|
||||
self endon( "barrel_dead" );
|
||||
self waittill( "death", attacker );
|
||||
if ( isDefined( self ) )
|
||||
{
|
||||
self thread destructible_barrel_explosion( attacker, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
destructible_barrel_fire_think( attacker )
|
||||
{
|
||||
self endon( "barrel_dead" );
|
||||
self endon( "explode" );
|
||||
self endon( "death" );
|
||||
wait randomintrange( 7, 10 );
|
||||
self thread destructible_barrel_explosion( attacker );
|
||||
}
|
||||
|
||||
destructible_barrel_explosion( attacker, physics_explosion )
|
||||
{
|
||||
if ( !isDefined( physics_explosion ) )
|
||||
{
|
||||
physics_explosion = 1;
|
||||
}
|
||||
self notify( "barrel_dead" );
|
||||
if ( isDefined( self.target ) )
|
||||
{
|
||||
dest_clip = getent( self.target, "targetname" );
|
||||
dest_clip delete();
|
||||
}
|
||||
self radiusdamage( self.origin, 256, 300, 75, attacker, "MOD_EXPLOSIVE", "explodable_barrel_mp" );
|
||||
playrumbleonposition( "grenade_rumble", self.origin );
|
||||
earthquake( 0,5, 0,5, self.origin, 800 );
|
||||
if ( physics_explosion )
|
||||
{
|
||||
physicsexplosionsphere( self.origin, 255, 254, 0,3, 400, 25 );
|
||||
}
|
||||
level.globalbarrelsdestroyed++;
|
||||
self dodamage( self.health + 10000, self.origin + ( 0, 0, 1 ), attacker );
|
||||
self setclientflag( 3 );
|
||||
}
|
7
Multiplayer Core/patch_mp/maps/mp/_development_dvars.gsc
Normal file
7
Multiplayer Core/patch_mp/maps/mp/_development_dvars.gsc
Normal file
@ -0,0 +1,7 @@
|
||||
//checked includes match cerberus output
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
}
|
180
Multiplayer Core/patch_mp/maps/mp/_empgrenade.gsc
Normal file
180
Multiplayer Core/patch_mp/maps/mp/_empgrenade.gsc
Normal file
@ -0,0 +1,180 @@
|
||||
//checked includes match cerberus output
|
||||
#include maps/mp/killstreaks/_emp;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
precacheshellshock( "flashbang" );
|
||||
thread onplayerconnect();
|
||||
}
|
||||
|
||||
onplayerconnect() //checked matches cerberus output
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
player thread onplayerspawned();
|
||||
}
|
||||
}
|
||||
|
||||
onplayerspawned() //checked matches cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
self thread monitorempgrenade();
|
||||
}
|
||||
}
|
||||
|
||||
monitorempgrenade() //checked changed to match cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self.empendtime = 0;
|
||||
for ( ;; )
|
||||
{
|
||||
while ( 1 )
|
||||
{
|
||||
self waittill( "emp_grenaded", attacker );
|
||||
if ( !isalive( self ) || self hasperk( "specialty_immuneemp" ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
hurtvictim = 1;
|
||||
hurtattacker = 0;
|
||||
/*
|
||||
/#
|
||||
assert( isDefined( self.team ) );
|
||||
#/
|
||||
*/
|
||||
if ( level.teambased && isDefined( attacker ) && isDefined( attacker.team ) && attacker.team == self.team && attacker != self )
|
||||
{
|
||||
if ( level.friendlyfire == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if ( level.friendlyfire == 1 )
|
||||
{
|
||||
hurtattacker = 0;
|
||||
hurtvictim = 1;
|
||||
}
|
||||
else if ( level.friendlyfire == 2 )
|
||||
{
|
||||
hurtvictim = 0;
|
||||
hurtattacker = 1;
|
||||
}
|
||||
else if ( level.friendlyfire == 3 )
|
||||
{
|
||||
hurtattacker = 1;
|
||||
hurtvictim = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( hurtvictim && isDefined( self ) )
|
||||
{
|
||||
self thread applyemp( attacker );
|
||||
}
|
||||
if ( hurtattacker && isDefined( attacker ) )
|
||||
{
|
||||
attacker thread applyemp( attacker );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
applyemp( attacker ) //checked matches cerberus output
|
||||
{
|
||||
self notify( "applyEmp" );
|
||||
self endon( "applyEmp" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
wait 0.05;
|
||||
if ( self == attacker )
|
||||
{
|
||||
if ( isDefined( self.empendtime ) )
|
||||
{
|
||||
emp_time_left_ms = self.empendtime - getTime();
|
||||
if ( emp_time_left_ms > 1000 )
|
||||
{
|
||||
self.empduration = emp_time_left_ms / 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.empduration = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self.empduration = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self.empduration = 12;
|
||||
}
|
||||
self.empgrenaded = 1;
|
||||
self shellshock( "flashbang", 1 );
|
||||
self.empendtime = getTime() + ( self.empduration * 1000 );
|
||||
self thread emprumbleloop( 0.75 );
|
||||
self setempjammed( 1 );
|
||||
self thread empgrenadedeathwaiter();
|
||||
wait self.empduration;
|
||||
self notify( "empGrenadeTimedOut" );
|
||||
self checktoturnoffemp();
|
||||
}
|
||||
|
||||
empgrenadedeathwaiter() //checked matches cerberus output
|
||||
{
|
||||
self notify( "empGrenadeDeathWaiter" );
|
||||
self endon( "empGrenadeDeathWaiter" );
|
||||
self endon( "empGrenadeTimedOut" );
|
||||
self waittill( "death" );
|
||||
self checktoturnoffemp();
|
||||
}
|
||||
|
||||
checktoturnoffemp() //checked changed to match cerberus output
|
||||
{
|
||||
self.empgrenaded = 0;
|
||||
if ( level.teambased && maps/mp/killstreaks/_emp::emp_isteamemped( self.team ) || !level.teambased && isDefined( level.empplayer ) && level.empplayer != self )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self setempjammed( 0 );
|
||||
}
|
||||
|
||||
emprumbleloop( duration ) //checked matches cerberus output
|
||||
{
|
||||
self endon( "emp_rumble_loop" );
|
||||
self notify( "emp_rumble_loop" );
|
||||
goaltime = getTime() + ( duration * 1000 );
|
||||
while ( getTime() < goaltime )
|
||||
{
|
||||
self playrumbleonentity( "damage_heavy" );
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
watchempexplosion( owner, weaponname ) //checked changed to match cerberus output
|
||||
{
|
||||
owner endon( "disconnect" );
|
||||
owner endon( "team_changed" );
|
||||
self endon( "shutdown_empgrenade" );
|
||||
self thread watchempgrenadeshutdown();
|
||||
owner addweaponstat( weaponname, "used", 1 );
|
||||
self waittill( "explode", origin, surface );
|
||||
ents = getdamageableentarray( origin, 512 );
|
||||
foreach ( ent in ents )
|
||||
{
|
||||
ent dodamage( 1, origin, owner, owner, "none", "MOD_GRENADE_SPLASH", 0, weaponname );
|
||||
}
|
||||
}
|
||||
|
||||
watchempgrenadeshutdown() //checked matches cerberus output
|
||||
{
|
||||
self endon( "explode" );
|
||||
self waittill( "death" );
|
||||
wait 0.05;
|
||||
self notify( "shutdown_empgrenade" );
|
||||
}
|
||||
|
159
Multiplayer Core/patch_mp/maps/mp/_entityheadicons.gsc
Normal file
159
Multiplayer Core/patch_mp/maps/mp/_entityheadicons.gsc
Normal file
@ -0,0 +1,159 @@
|
||||
//checked includes match cerberus output
|
||||
#include common_scripts/utility;
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
if ( isDefined( level.initedentityheadicons ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( level.createfx_enabled )
|
||||
{
|
||||
return;
|
||||
}
|
||||
level.initedentityheadicons = 1;
|
||||
/*
|
||||
/#
|
||||
assert( isDefined( game[ "entity_headicon_allies" ] ), "Allied head icons are not defined. Check the team set for the level." );
|
||||
#/
|
||||
/#
|
||||
assert( isDefined( game[ "entity_headicon_axis" ] ), "Axis head icons are not defined. Check the team set for the level." );
|
||||
#/
|
||||
*/
|
||||
precacheshader( game[ "entity_headicon_allies" ] );
|
||||
precacheshader( game[ "entity_headicon_axis" ] );
|
||||
if ( !level.teambased )
|
||||
{
|
||||
return;
|
||||
}
|
||||
level.entitieswithheadicons = [];
|
||||
}
|
||||
|
||||
setentityheadicon( team, owner, offset, icon, constant_size ) //checked changed to match cerberus output
|
||||
{
|
||||
if ( !level.teambased && !isDefined( owner ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( !isDefined( constant_size ) )
|
||||
{
|
||||
constant_size = 0;
|
||||
}
|
||||
if ( !isDefined( self.entityheadiconteam ) )
|
||||
{
|
||||
self.entityheadiconteam = "none";
|
||||
self.entityheadicons = [];
|
||||
}
|
||||
if ( level.teambased && !isDefined( owner ) )
|
||||
{
|
||||
if ( team == self.entityheadiconteam )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self.entityheadiconteam = team;
|
||||
}
|
||||
if ( isDefined( offset ) )
|
||||
{
|
||||
self.entityheadiconoffset = offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.entityheadiconoffset = ( 0, 0, 0 );
|
||||
}
|
||||
if ( isDefined( self.entityheadicons ) )
|
||||
{
|
||||
for ( i = 0; i < self.entityheadicons.size; i++ )
|
||||
{
|
||||
if ( isDefined( self.entityheadicons[ i ] ) )
|
||||
{
|
||||
self.entityheadicons[ i ] destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
self.entityheadicons = [];
|
||||
self notify( "kill_entity_headicon_thread" );
|
||||
if ( !isDefined( icon ) )
|
||||
{
|
||||
icon = game[ "entity_headicon_" + team ];
|
||||
}
|
||||
if ( isDefined( owner ) && !level.teambased )
|
||||
{
|
||||
if ( !isplayer( owner ) )
|
||||
{
|
||||
/*
|
||||
/#
|
||||
assert( isDefined( owner.owner ), "entity has to have an owner if it's not a player" );
|
||||
#/
|
||||
*/
|
||||
owner = owner.owner;
|
||||
}
|
||||
owner updateentityheadclienticon( self, icon, constant_size );
|
||||
}
|
||||
else if ( isDefined( owner ) && team != "none" )
|
||||
{
|
||||
owner updateentityheadteamicon( self, team, icon, constant_size );
|
||||
}
|
||||
self thread destroyheadiconsondeath();
|
||||
}
|
||||
|
||||
updateentityheadteamicon( entity, team, icon, constant_size ) //checked matches cerberus output
|
||||
{
|
||||
headicon = newteamhudelem( team );
|
||||
headicon.archived = 1;
|
||||
headicon.x = entity.entityheadiconoffset[ 0 ];
|
||||
headicon.y = entity.entityheadiconoffset[ 1 ];
|
||||
headicon.z = entity.entityheadiconoffset[ 2 ];
|
||||
headicon.alpha = 0.8;
|
||||
headicon setshader( icon, 6, 6 );
|
||||
headicon setwaypoint( constant_size );
|
||||
headicon settargetent( entity );
|
||||
entity.entityheadicons[ entity.entityheadicons.size ] = headicon;
|
||||
}
|
||||
|
||||
updateentityheadclienticon( entity, icon, constant_size ) //checked matches cerberus output
|
||||
{
|
||||
headicon = newclienthudelem( self );
|
||||
headicon.archived = 1;
|
||||
headicon.x = entity.entityheadiconoffset[ 0 ];
|
||||
headicon.y = entity.entityheadiconoffset[ 1 ];
|
||||
headicon.z = entity.entityheadiconoffset[ 2 ];
|
||||
headicon.alpha = 0.8;
|
||||
headicon setshader( icon, 6, 6 );
|
||||
headicon setwaypoint( constant_size );
|
||||
headicon settargetent( entity );
|
||||
entity.entityheadicons[ entity.entityheadicons.size ] = headicon;
|
||||
}
|
||||
|
||||
destroyheadiconsondeath() //checked changed to match cerberus output
|
||||
{
|
||||
self waittill_any( "death", "hacked" );
|
||||
for ( i = 0; i < self.entityheadicons.size; i++ )
|
||||
{
|
||||
if ( isDefined( self.entityheadicons[ i ] ) )
|
||||
{
|
||||
self.entityheadicons[ i ] destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
destroyentityheadicons() //checked changed to match cerberus output
|
||||
{
|
||||
if ( isDefined( self.entityheadicons ) )
|
||||
{
|
||||
for ( i = 0; i < self.entityheadicons.size; i++ )
|
||||
{
|
||||
if ( isDefined( self.entityheadicons[ i ] ) )
|
||||
{
|
||||
self.entityheadicons[ i ] destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateentityheadiconpos( headicon ) //checked matches cerberus output
|
||||
{
|
||||
headicon.x = self.origin[ 0 ] + self.entityheadiconoffset[ 0 ];
|
||||
headicon.y = self.origin[ 1 ] + self.entityheadiconoffset[ 1 ];
|
||||
headicon.z = self.origin[ 2 ] + self.entityheadiconoffset[ 2 ];
|
||||
}
|
||||
|
13
Multiplayer Core/patch_mp/maps/mp/_explosive_bolt.gsc
Normal file
13
Multiplayer Core/patch_mp/maps/mp/_explosive_bolt.gsc
Normal file
@ -0,0 +1,13 @@
|
||||
//checked includes match cerberus output
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
loadfx( "weapon/crossbow/fx_trail_crossbow_blink_grn_os" );
|
||||
loadfx( "weapon/crossbow/fx_trail_crossbow_blink_red_os" );
|
||||
}
|
||||
|
||||
watch_bolt_detonation( owner ) //checked matches cerberus output
|
||||
{
|
||||
}
|
203
Multiplayer Core/patch_mp/maps/mp/_flashgrenades.gsc
Normal file
203
Multiplayer Core/patch_mp/maps/mp/_flashgrenades.gsc
Normal file
@ -0,0 +1,203 @@
|
||||
//checked includes match cerberus output
|
||||
#include maps/mp/_utility;
|
||||
|
||||
main() //checked matches cerberus output
|
||||
{
|
||||
precacheshellshock( "flashbang" );
|
||||
level.sound_flash_start = "";
|
||||
level.sound_flash_loop = "";
|
||||
level.sound_flash_stop = "";
|
||||
}
|
||||
|
||||
startmonitoringflash() //checked matches cerberus output
|
||||
{
|
||||
self thread monitorflash();
|
||||
}
|
||||
|
||||
stopmonitoringflash( disconnected ) //checked matches cerberus output
|
||||
{
|
||||
self notify( "stop_monitoring_flash" );
|
||||
}
|
||||
|
||||
flashrumbleloop( duration ) //checked matches cerberus output
|
||||
{
|
||||
self endon( "stop_monitoring_flash" );
|
||||
self endon( "flash_rumble_loop" );
|
||||
self notify( "flash_rumble_loop" );
|
||||
goaltime = getTime() + ( duration * 1000 );
|
||||
while ( getTime() < goaltime )
|
||||
{
|
||||
self playrumbleonentity( "damage_heavy" );
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
monitorflash_internal( amount_distance, amount_angle, attacker, direct_on_player ) //checked changed to match cerberus output
|
||||
{
|
||||
hurtattacker = 0;
|
||||
hurtvictim = 1;
|
||||
if ( amount_angle < 0.5 )
|
||||
{
|
||||
amount_angle = 0.5;
|
||||
}
|
||||
else if ( amount_angle > 0.8 )
|
||||
{
|
||||
amount_angle = 1;
|
||||
}
|
||||
if ( isDefined( attacker ) && attacker == self )
|
||||
{
|
||||
amount_distance *= 0.5;
|
||||
}
|
||||
duration = amount_distance * amount_angle * 6;
|
||||
if ( duration < 0.25 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
rumbleduration = undefined;
|
||||
if ( duration > 2 )
|
||||
{
|
||||
rumbleduration = 0.75;
|
||||
}
|
||||
else
|
||||
{
|
||||
rumbleduration = 0.25;
|
||||
}
|
||||
/*
|
||||
/#
|
||||
assert( isDefined( self.team ) );
|
||||
#/
|
||||
*/
|
||||
if ( level.teambased && isDefined( attacker ) && isDefined( attacker.team ) && attacker.team == self.team && attacker != self )
|
||||
{
|
||||
if ( level.friendlyfire == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if ( level.friendlyfire == 1 )
|
||||
{
|
||||
}
|
||||
else if ( level.friendlyfire == 2 )
|
||||
{
|
||||
duration *= 0.5;
|
||||
rumbleduration *= 0.5;
|
||||
hurtvictim = 0;
|
||||
hurtattacker = 1;
|
||||
}
|
||||
else if ( level.friendlyfire == 3 )
|
||||
{
|
||||
duration *= 0.5;
|
||||
rumbleduration *= 0.5;
|
||||
hurtattacker = 1;
|
||||
}
|
||||
}
|
||||
if ( self hasperk( "specialty_flashprotection" ) )
|
||||
{
|
||||
duration *= 0.1;
|
||||
rumbleduration *= 0.1;
|
||||
}
|
||||
if ( hurtvictim )
|
||||
{
|
||||
if ( self mayapplyscreeneffect() || !direct_on_player && self isremotecontrolling() )
|
||||
{
|
||||
if ( self != attacker )
|
||||
{
|
||||
attacker addweaponstat( "flash_grenade_mp", "hits", 1 );
|
||||
attacker addweaponstat( "flash_grenade_mp", "used", 1 );
|
||||
}
|
||||
self thread applyflash( duration, rumbleduration, attacker );
|
||||
}
|
||||
}
|
||||
if ( hurtattacker )
|
||||
{
|
||||
if ( attacker mayapplyscreeneffect() )
|
||||
{
|
||||
attacker thread applyflash( duration, rumbleduration, attacker );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
monitorflash() //checked changed to match cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self.flashendtime = 0;
|
||||
while ( 1 )
|
||||
{
|
||||
self waittill( "flashbang", amount_distance, amount_angle, attacker );
|
||||
if ( !isalive( self ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
self monitorflash_internal( amount_distance, amount_angle, attacker, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
monitorrcbombflash() //checked matches cerberus output
|
||||
{
|
||||
self endon( "death" );
|
||||
self.flashendtime = 0;
|
||||
while ( 1 )
|
||||
{
|
||||
self waittill( "flashbang", amount_distance, amount_angle, attacker );
|
||||
driver = self getseatoccupant( 0 );
|
||||
if ( !isDefined( driver ) || !isalive( driver ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
driver monitorflash_internal( amount_distance, amount_angle, attacker, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
applyflash( duration, rumbleduration, attacker ) //checked matches cerberus output
|
||||
{
|
||||
if ( !isDefined( self.flashduration ) || duration > self.flashduration )
|
||||
{
|
||||
self.flashduration = duration;
|
||||
}
|
||||
if ( !isDefined( self.flashrumbleduration ) || rumbleduration > self.flashrumbleduration )
|
||||
{
|
||||
self.flashrumbleduration = rumbleduration;
|
||||
}
|
||||
self thread playflashsound( duration );
|
||||
wait 0.05;
|
||||
if ( isDefined( self.flashduration ) )
|
||||
{
|
||||
self shellshock( "flashbang", self.flashduration, 0 );
|
||||
self.flashendtime = getTime() + ( self.flashduration * 1000 );
|
||||
self.lastflashedby = attacker;
|
||||
}
|
||||
if ( isDefined( self.flashrumbleduration ) )
|
||||
{
|
||||
self thread flashrumbleloop( self.flashrumbleduration );
|
||||
}
|
||||
self.flashduration = undefined;
|
||||
self.flashrumbleduration = undefined;
|
||||
}
|
||||
|
||||
playflashsound( duration ) //checked matches cerberus output
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
flashsound = spawn( "script_origin", ( 0, 0, 1 ) );
|
||||
flashsound.origin = self.origin;
|
||||
flashsound linkto( self );
|
||||
flashsound thread deleteentonownerdeath( self );
|
||||
flashsound playsound( level.sound_flash_start );
|
||||
flashsound playloopsound( level.sound_flash_loop );
|
||||
if ( duration > 0.5 )
|
||||
{
|
||||
wait ( duration - 0.5 );
|
||||
}
|
||||
flashsound playsound( level.sound_flash_start );
|
||||
flashsound stoploopsound( 0.5 );
|
||||
wait 0.5;
|
||||
flashsound notify( "delete" );
|
||||
flashsound delete();
|
||||
}
|
||||
|
||||
deleteentonownerdeath( owner ) //checked matches cerberus output
|
||||
{
|
||||
self endon( "delete" );
|
||||
owner waittill( "death" );
|
||||
self delete();
|
||||
}
|
||||
|
458
Multiplayer Core/patch_mp/maps/mp/_fx.gsc
Normal file
458
Multiplayer Core/patch_mp/maps/mp/_fx.gsc
Normal file
@ -0,0 +1,458 @@
|
||||
#include maps/mp/_createfx;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
|
||||
print_org( fxcommand, fxid, fxpos, waittime )
|
||||
{
|
||||
/#
|
||||
if ( getDvar( "debug" ) == "1" )
|
||||
{
|
||||
println( "{" );
|
||||
println( ""origin" "" + fxpos[ 0 ] + " " + fxpos[ 1 ] + " " + fxpos[ 2 ] + """ );
|
||||
println( ""classname" "script_model"" );
|
||||
println( ""model" "fx"" );
|
||||
println( ""script_fxcommand" "" + fxcommand + """ );
|
||||
println( ""script_fxid" "" + fxid + """ );
|
||||
println( ""script_delay" "" + waittime + """ );
|
||||
println( "}" );
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
oneshotfx( fxid, fxpos, waittime, fxpos2 )
|
||||
{
|
||||
}
|
||||
|
||||
oneshotfxthread()
|
||||
{
|
||||
wait 0,05;
|
||||
if ( self.v[ "delay" ] > 0 )
|
||||
{
|
||||
wait self.v[ "delay" ];
|
||||
}
|
||||
create_triggerfx();
|
||||
}
|
||||
|
||||
create_triggerfx()
|
||||
{
|
||||
self.looper = spawnfx_wrapper( self.v[ "fxid" ], self.v[ "origin" ], self.v[ "forward" ], self.v[ "up" ] );
|
||||
triggerfx( self.looper, self.v[ "delay" ] );
|
||||
create_loopsound();
|
||||
}
|
||||
|
||||
exploderfx( num, fxid, fxpos, waittime, fxpos2, firefx, firefxdelay, firefxsound, fxsound, fxquake, fxdamage, soundalias, repeat, delay_min, delay_max, damage_radius, firefxtimeout, exploder_group )
|
||||
{
|
||||
if ( 1 )
|
||||
{
|
||||
ent = createexploder( fxid );
|
||||
ent.v[ "origin" ] = fxpos;
|
||||
ent.v[ "angles" ] = ( 0, 0, 0 );
|
||||
if ( isDefined( fxpos2 ) )
|
||||
{
|
||||
ent.v[ "angles" ] = vectorToAngle( fxpos2 - fxpos );
|
||||
}
|
||||
ent.v[ "delay" ] = waittime;
|
||||
ent.v[ "exploder" ] = num;
|
||||
return;
|
||||
}
|
||||
fx = spawn( "script_origin", ( 0, 0, 0 ) );
|
||||
fx.origin = fxpos;
|
||||
fx.angles = vectorToAngle( fxpos2 - fxpos );
|
||||
fx.script_exploder = num;
|
||||
fx.script_fxid = fxid;
|
||||
fx.script_delay = waittime;
|
||||
fx.script_firefx = firefx;
|
||||
fx.script_firefxdelay = firefxdelay;
|
||||
fx.script_firefxsound = firefxsound;
|
||||
fx.script_sound = fxsound;
|
||||
fx.script_earthquake = fxquake;
|
||||
fx.script_damage = fxdamage;
|
||||
fx.script_radius = damage_radius;
|
||||
fx.script_soundalias = soundalias;
|
||||
fx.script_firefxtimeout = firefxtimeout;
|
||||
fx.script_repeat = repeat;
|
||||
fx.script_delay_min = delay_min;
|
||||
fx.script_delay_max = delay_max;
|
||||
fx.script_exploder_group = exploder_group;
|
||||
forward = anglesToForward( fx.angles );
|
||||
forward = vectorScale( forward, 150 );
|
||||
fx.targetpos = fxpos + forward;
|
||||
if ( !isDefined( level._script_exploders ) )
|
||||
{
|
||||
level._script_exploders = [];
|
||||
}
|
||||
level._script_exploders[ level._script_exploders.size ] = fx;
|
||||
maps/mp/_createfx::createfx_showorigin( fxid, fxpos, waittime, fxpos2, "exploderfx", fx, undefined, firefx, firefxdelay, firefxsound, fxsound, fxquake, fxdamage, soundalias, repeat, delay_min, delay_max, damage_radius, firefxtimeout );
|
||||
}
|
||||
|
||||
loopfx( fxid, fxpos, waittime, fxpos2, fxstart, fxstop, timeout )
|
||||
{
|
||||
/#
|
||||
println( "Loopfx is deprecated!" );
|
||||
#/
|
||||
ent = createloopeffect( fxid );
|
||||
ent.v[ "origin" ] = fxpos;
|
||||
ent.v[ "angles" ] = ( 0, 0, 0 );
|
||||
if ( isDefined( fxpos2 ) )
|
||||
{
|
||||
ent.v[ "angles" ] = vectorToAngle( fxpos2 - fxpos );
|
||||
}
|
||||
ent.v[ "delay" ] = waittime;
|
||||
}
|
||||
|
||||
create_looper()
|
||||
{
|
||||
self.looper = playloopedfx( level._effect[ self.v[ "fxid" ] ], self.v[ "delay" ], self.v[ "origin" ], 0, self.v[ "forward" ], self.v[ "up" ] );
|
||||
create_loopsound();
|
||||
}
|
||||
|
||||
create_loopsound()
|
||||
{
|
||||
self notify( "stop_loop" );
|
||||
if ( isDefined( self.v[ "soundalias" ] ) && self.v[ "soundalias" ] != "nil" )
|
||||
{
|
||||
if ( isDefined( self.looper ) )
|
||||
{
|
||||
self.looper thread maps/mp/_utility::loop_fx_sound( self.v[ "soundalias" ], self.v[ "origin" ], "death" );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
thread maps/mp/_utility::loop_fx_sound( self.v[ "soundalias" ], self.v[ "origin" ], "stop_loop" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stop_loopsound()
|
||||
{
|
||||
self notify( "stop_loop" );
|
||||
}
|
||||
|
||||
loopfxthread()
|
||||
{
|
||||
wait 0,05;
|
||||
if ( isDefined( self.fxstart ) )
|
||||
{
|
||||
level waittill( "start fx" + self.fxstart );
|
||||
}
|
||||
while ( 1 )
|
||||
{
|
||||
create_looper();
|
||||
if ( isDefined( self.timeout ) )
|
||||
{
|
||||
thread loopfxstop( self.timeout );
|
||||
}
|
||||
if ( isDefined( self.fxstop ) )
|
||||
{
|
||||
level waittill( "stop fx" + self.fxstop );
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( isDefined( self.looper ) )
|
||||
{
|
||||
self.looper delete();
|
||||
}
|
||||
if ( isDefined( self.fxstart ) )
|
||||
{
|
||||
level waittill( "start fx" + self.fxstart );
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loopfxchangeid( ent )
|
||||
{
|
||||
self endon( "death" );
|
||||
ent waittill( "effect id changed", change );
|
||||
}
|
||||
|
||||
loopfxchangeorg( ent )
|
||||
{
|
||||
self endon( "death" );
|
||||
for ( ;; )
|
||||
{
|
||||
ent waittill( "effect org changed", change );
|
||||
self.origin = change;
|
||||
}
|
||||
}
|
||||
|
||||
loopfxchangedelay( ent )
|
||||
{
|
||||
self endon( "death" );
|
||||
ent waittill( "effect delay changed", change );
|
||||
}
|
||||
|
||||
loopfxdeletion( ent )
|
||||
{
|
||||
self endon( "death" );
|
||||
ent waittill( "effect deleted" );
|
||||
self delete();
|
||||
}
|
||||
|
||||
loopfxstop( timeout )
|
||||
{
|
||||
self endon( "death" );
|
||||
wait timeout;
|
||||
self.looper delete();
|
||||
}
|
||||
|
||||
loopsound( sound, pos, waittime )
|
||||
{
|
||||
level thread loopsoundthread( sound, pos, waittime );
|
||||
}
|
||||
|
||||
loopsoundthread( sound, pos, waittime )
|
||||
{
|
||||
org = spawn( "script_origin", pos );
|
||||
org.origin = pos;
|
||||
org playloopsound( sound );
|
||||
}
|
||||
|
||||
gunfireloopfx( fxid, fxpos, shotsmin, shotsmax, shotdelaymin, shotdelaymax, betweensetsmin, betweensetsmax )
|
||||
{
|
||||
thread gunfireloopfxthread( fxid, fxpos, shotsmin, shotsmax, shotdelaymin, shotdelaymax, betweensetsmin, betweensetsmax );
|
||||
}
|
||||
|
||||
gunfireloopfxthread( fxid, fxpos, shotsmin, shotsmax, shotdelaymin, shotdelaymax, betweensetsmin, betweensetsmax )
|
||||
{
|
||||
level endon( "stop all gunfireloopfx" );
|
||||
wait 0,05;
|
||||
if ( betweensetsmax < betweensetsmin )
|
||||
{
|
||||
temp = betweensetsmax;
|
||||
betweensetsmax = betweensetsmin;
|
||||
betweensetsmin = temp;
|
||||
}
|
||||
betweensetsbase = betweensetsmin;
|
||||
betweensetsrange = betweensetsmax - betweensetsmin;
|
||||
if ( shotdelaymax < shotdelaymin )
|
||||
{
|
||||
temp = shotdelaymax;
|
||||
shotdelaymax = shotdelaymin;
|
||||
shotdelaymin = temp;
|
||||
}
|
||||
shotdelaybase = shotdelaymin;
|
||||
shotdelayrange = shotdelaymax - shotdelaymin;
|
||||
if ( shotsmax < shotsmin )
|
||||
{
|
||||
temp = shotsmax;
|
||||
shotsmax = shotsmin;
|
||||
shotsmin = temp;
|
||||
}
|
||||
shotsbase = shotsmin;
|
||||
shotsrange = shotsmax - shotsmin;
|
||||
fxent = spawnfx( level._effect[ fxid ], fxpos );
|
||||
for ( ;; )
|
||||
{
|
||||
shotnum = shotsbase + randomint( shotsrange );
|
||||
i = 0;
|
||||
while ( i < shotnum )
|
||||
{
|
||||
triggerfx( fxent );
|
||||
wait ( shotdelaybase + randomfloat( shotdelayrange ) );
|
||||
i++;
|
||||
}
|
||||
wait ( betweensetsbase + randomfloat( betweensetsrange ) );
|
||||
}
|
||||
}
|
||||
|
||||
gunfireloopfxvec( fxid, fxpos, fxpos2, shotsmin, shotsmax, shotdelaymin, shotdelaymax, betweensetsmin, betweensetsmax )
|
||||
{
|
||||
thread gunfireloopfxvecthread( fxid, fxpos, fxpos2, shotsmin, shotsmax, shotdelaymin, shotdelaymax, betweensetsmin, betweensetsmax );
|
||||
}
|
||||
|
||||
gunfireloopfxvecthread( fxid, fxpos, fxpos2, shotsmin, shotsmax, shotdelaymin, shotdelaymax, betweensetsmin, betweensetsmax )
|
||||
{
|
||||
level endon( "stop all gunfireloopfx" );
|
||||
wait 0,05;
|
||||
if ( betweensetsmax < betweensetsmin )
|
||||
{
|
||||
temp = betweensetsmax;
|
||||
betweensetsmax = betweensetsmin;
|
||||
betweensetsmin = temp;
|
||||
}
|
||||
betweensetsbase = betweensetsmin;
|
||||
betweensetsrange = betweensetsmax - betweensetsmin;
|
||||
if ( shotdelaymax < shotdelaymin )
|
||||
{
|
||||
temp = shotdelaymax;
|
||||
shotdelaymax = shotdelaymin;
|
||||
shotdelaymin = temp;
|
||||
}
|
||||
shotdelaybase = shotdelaymin;
|
||||
shotdelayrange = shotdelaymax - shotdelaymin;
|
||||
if ( shotsmax < shotsmin )
|
||||
{
|
||||
temp = shotsmax;
|
||||
shotsmax = shotsmin;
|
||||
shotsmin = temp;
|
||||
}
|
||||
shotsbase = shotsmin;
|
||||
shotsrange = shotsmax - shotsmin;
|
||||
fxpos2 = vectornormalize( fxpos2 - fxpos );
|
||||
fxent = spawnfx( level._effect[ fxid ], fxpos, fxpos2 );
|
||||
for ( ;; )
|
||||
{
|
||||
shotnum = shotsbase + randomint( shotsrange );
|
||||
i = 0;
|
||||
while ( i < int( shotnum / level.fxfireloopmod ) )
|
||||
{
|
||||
triggerfx( fxent );
|
||||
delay = ( shotdelaybase + randomfloat( shotdelayrange ) ) * level.fxfireloopmod;
|
||||
if ( delay < 0,05 )
|
||||
{
|
||||
delay = 0,05;
|
||||
}
|
||||
wait delay;
|
||||
i++;
|
||||
}
|
||||
wait ( shotdelaybase + randomfloat( shotdelayrange ) );
|
||||
wait ( betweensetsbase + randomfloat( betweensetsrange ) );
|
||||
}
|
||||
}
|
||||
|
||||
setfireloopmod( value )
|
||||
{
|
||||
level.fxfireloopmod = 1 / value;
|
||||
}
|
||||
|
||||
setup_fx()
|
||||
{
|
||||
if ( isDefined( self.script_fxid ) || !isDefined( self.script_fxcommand ) && !isDefined( self.script_delay ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
org = undefined;
|
||||
if ( isDefined( self.target ) )
|
||||
{
|
||||
ent = getent( self.target, "targetname" );
|
||||
if ( isDefined( ent ) )
|
||||
{
|
||||
org = ent.origin;
|
||||
}
|
||||
}
|
||||
fxstart = undefined;
|
||||
if ( isDefined( self.script_fxstart ) )
|
||||
{
|
||||
fxstart = self.script_fxstart;
|
||||
}
|
||||
fxstop = undefined;
|
||||
if ( isDefined( self.script_fxstop ) )
|
||||
{
|
||||
fxstop = self.script_fxstop;
|
||||
}
|
||||
if ( self.script_fxcommand == "OneShotfx" )
|
||||
{
|
||||
oneshotfx( self.script_fxid, self.origin, self.script_delay, org );
|
||||
}
|
||||
if ( self.script_fxcommand == "loopfx" )
|
||||
{
|
||||
loopfx( self.script_fxid, self.origin, self.script_delay, org, fxstart, fxstop );
|
||||
}
|
||||
if ( self.script_fxcommand == "loopsound" )
|
||||
{
|
||||
loopsound( self.script_fxid, self.origin, self.script_delay );
|
||||
}
|
||||
self delete();
|
||||
}
|
||||
|
||||
script_print_fx()
|
||||
{
|
||||
/#
|
||||
if ( isDefined( self.script_fxid ) || !isDefined( self.script_fxcommand ) && !isDefined( self.script_delay ) )
|
||||
{
|
||||
println( "Effect at origin ", self.origin, " doesn't have script_fxid/script_fxcommand/script_delay" );
|
||||
self delete();
|
||||
return;
|
||||
}
|
||||
if ( isDefined( self.target ) )
|
||||
{
|
||||
org = getent( self.target, "targetname" ).origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
org = "undefined";
|
||||
}
|
||||
if ( self.script_fxcommand == "OneShotfx" )
|
||||
{
|
||||
println( "mapsmp_fx::OneShotfx("" + self.script_fxid + "", " + self.origin + ", " + self.script_delay + ", " + org + ");" );
|
||||
}
|
||||
if ( self.script_fxcommand == "loopfx" )
|
||||
{
|
||||
println( "mapsmp_fx::LoopFx("" + self.script_fxid + "", " + self.origin + ", " + self.script_delay + ", " + org + ");" );
|
||||
}
|
||||
if ( self.script_fxcommand == "loopsound" )
|
||||
{
|
||||
println( "mapsmp_fx::LoopSound("" + self.script_fxid + "", " + self.origin + ", " + self.script_delay + ", " + org + ");" );
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
script_playfx( id, pos, pos2 )
|
||||
{
|
||||
if ( !id )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( isDefined( pos2 ) )
|
||||
{
|
||||
playfx( id, pos, pos2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
playfx( id, pos );
|
||||
}
|
||||
}
|
||||
|
||||
script_playfxontag( id, ent, tag )
|
||||
{
|
||||
if ( !id )
|
||||
{
|
||||
return;
|
||||
}
|
||||
playfxontag( id, ent, tag );
|
||||
}
|
||||
|
||||
grenadeexplosionfx( pos )
|
||||
{
|
||||
playfx( level._effect[ "mechanical explosion" ], pos );
|
||||
earthquake( 0,15, 0,5, pos, 250 );
|
||||
}
|
||||
|
||||
soundfx( fxid, fxpos, endonnotify )
|
||||
{
|
||||
org = spawn( "script_origin", ( 0, 0, 0 ) );
|
||||
org.origin = fxpos;
|
||||
org playloopsound( fxid );
|
||||
if ( isDefined( endonnotify ) )
|
||||
{
|
||||
org thread soundfxdelete( endonnotify );
|
||||
}
|
||||
}
|
||||
|
||||
soundfxdelete( endonnotify )
|
||||
{
|
||||
level waittill( endonnotify );
|
||||
self delete();
|
||||
}
|
||||
|
||||
blenddelete( blend )
|
||||
{
|
||||
self waittill( "death" );
|
||||
blend delete();
|
||||
}
|
||||
|
||||
spawnfx_wrapper( fx_id, origin, forward, up )
|
||||
{
|
||||
/#
|
||||
assert( isDefined( level._effect[ fx_id ] ), "Missing level._effect["" + fx_id + ""]. You did not setup the fx before calling it in createFx." );
|
||||
#/
|
||||
fx_object = spawnfx( level._effect[ fx_id ], origin, forward, up );
|
||||
return fx_object;
|
||||
}
|
6
Multiplayer Core/patch_mp/maps/mp/_fxanim.gsc
Normal file
6
Multiplayer Core/patch_mp/maps/mp/_fxanim.gsc
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
level.scr_anim = [];
|
||||
level.scr_anim[ "fxanim_props" ] = [];
|
||||
}
|
530
Multiplayer Core/patch_mp/maps/mp/_gameadvertisement.gsc
Normal file
530
Multiplayer Core/patch_mp/maps/mp/_gameadvertisement.gsc
Normal file
@ -0,0 +1,530 @@
|
||||
#include maps/mp/gametypes/_dev;
|
||||
#include maps/mp/gametypes/_globallogic_utils;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
/#
|
||||
level.sessionadvertstatus = 1;
|
||||
thread sessionadvertismentupdatedebughud();
|
||||
#/
|
||||
thread sessionadvertisementcheck();
|
||||
}
|
||||
|
||||
setadvertisedstatus( onoff )
|
||||
{
|
||||
/#
|
||||
level.sessionadvertstatus = onoff;
|
||||
#/
|
||||
changeadvertisedstatus( onoff );
|
||||
}
|
||||
|
||||
sessionadvertisementcheck()
|
||||
{
|
||||
if ( sessionmodeisprivate() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( sessionmodeiszombiesgame() )
|
||||
{
|
||||
setadvertisedstatus( 0 );
|
||||
return;
|
||||
}
|
||||
runrules = getgametyperules();
|
||||
if ( !isDefined( runrules ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
level endon( "game_end" );
|
||||
level waittill( "prematch_over" );
|
||||
while ( 1 )
|
||||
{
|
||||
sessionadvertcheckwait = getdvarintdefault( "sessionAdvertCheckwait", 1 );
|
||||
wait sessionadvertcheckwait;
|
||||
advertise = [[ runrules ]]();
|
||||
setadvertisedstatus( advertise );
|
||||
}
|
||||
}
|
||||
|
||||
getgametyperules()
|
||||
{
|
||||
gametype = level.gametype;
|
||||
switch( gametype )
|
||||
{
|
||||
case "dm":
|
||||
return ::dm_rules;
|
||||
case "tdm":
|
||||
return ::tdm_rules;
|
||||
case "dom":
|
||||
return ::dom_rules;
|
||||
case "hq":
|
||||
return ::hq_rules;
|
||||
case "sd":
|
||||
return ::sd_rules;
|
||||
case "dem":
|
||||
return ::dem_rules;
|
||||
case "ctf":
|
||||
return ::ctf_rules;
|
||||
case "koth":
|
||||
return ::koth_rules;
|
||||
case "conf":
|
||||
return ::conf_rules;
|
||||
case "oic":
|
||||
return ::oic_rules;
|
||||
case "sas":
|
||||
return ::sas_rules;
|
||||
case "gun":
|
||||
return ::gun_rules;
|
||||
case "shrp":
|
||||
return ::shrp_rules;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
teamscorelimitcheck( rulescorepercent )
|
||||
{
|
||||
if ( level.scorelimit )
|
||||
{
|
||||
minscorepercentageleft = 100;
|
||||
_a100 = level.teams;
|
||||
_k100 = getFirstArrayKey( _a100 );
|
||||
while ( isDefined( _k100 ) )
|
||||
{
|
||||
team = _a100[ _k100 ];
|
||||
scorepercentageleft = 100 - ( ( game[ "teamScores" ][ team ] / level.scorelimit ) * 100 );
|
||||
if ( minscorepercentageleft > scorepercentageleft )
|
||||
{
|
||||
minscorepercentageleft = scorepercentageleft;
|
||||
}
|
||||
if ( rulescorepercent >= scorepercentageleft )
|
||||
{
|
||||
/#
|
||||
updatedebughud( 3, "Score Percentage Left: ", int( scorepercentageleft ) );
|
||||
#/
|
||||
return 0;
|
||||
}
|
||||
_k100 = getNextArrayKey( _a100, _k100 );
|
||||
}
|
||||
/#
|
||||
updatedebughud( 3, "Score Percentage Left: ", int( minscorepercentageleft ) );
|
||||
#/
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
timelimitcheck( ruletimeleft )
|
||||
{
|
||||
maxtime = level.timelimit;
|
||||
if ( maxtime != 0 )
|
||||
{
|
||||
timeleft = maps/mp/gametypes/_globallogic_utils::gettimeremaining();
|
||||
if ( ruletimeleft >= timeleft )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
dm_rules()
|
||||
{
|
||||
rulescorepercent = 35;
|
||||
ruletimeleft = 60000 * 1,5;
|
||||
/#
|
||||
updatedebughud( 1, "Any player is within percent of score cap: ", rulescorepercent );
|
||||
updatedebughud( 2, "Time limit has less than minutes remaining: ", ruletimeleft / 60000 );
|
||||
#/
|
||||
if ( level.scorelimit )
|
||||
{
|
||||
highestscore = 0;
|
||||
players = get_players();
|
||||
i = 0;
|
||||
while ( i < players.size )
|
||||
{
|
||||
if ( players[ i ].pointstowin > highestscore )
|
||||
{
|
||||
highestscore = players[ i ].pointstowin;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
scorepercentageleft = 100 - ( ( highestscore / level.scorelimit ) * 100 );
|
||||
/#
|
||||
updatedebughud( 3, "Score Percentage Left: ", int( scorepercentageleft ) );
|
||||
#/
|
||||
if ( rulescorepercent >= scorepercentageleft )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if ( timelimitcheck( ruletimeleft ) == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
tdm_rules()
|
||||
{
|
||||
rulescorepercent = 15;
|
||||
ruletimeleft = 60000 * 1,5;
|
||||
/#
|
||||
updatedebughud( 1, "Any player is within percent of score cap: ", rulescorepercent );
|
||||
updatedebughud( 2, "Time limit has less than minutes remaining: ", ruletimeleft / 60000 );
|
||||
#/
|
||||
if ( teamscorelimitcheck( rulescorepercent ) == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( timelimitcheck( ruletimeleft ) == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
dom_rules()
|
||||
{
|
||||
rulescorepercent = 15;
|
||||
ruletimeleft = 60000 * 1,5;
|
||||
ruleround = 3;
|
||||
currentround = game[ "roundsplayed" ] + 1;
|
||||
/#
|
||||
updatedebughud( 1, "Time limit 1.5 minutes remaining in final round. Any player is within percent of score cap: ", rulescorepercent );
|
||||
updatedebughud( 2, "Is round: ", ruleround );
|
||||
updatedebughud( 4, "Current Round: ", currentround );
|
||||
#/
|
||||
if ( currentround >= 2 )
|
||||
{
|
||||
if ( teamscorelimitcheck( rulescorepercent ) == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if ( timelimitcheck( ruletimeleft ) == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( ruleround <= currentround )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
hq_rules()
|
||||
{
|
||||
return koth_rules();
|
||||
}
|
||||
|
||||
sd_rules()
|
||||
{
|
||||
ruleround = 3;
|
||||
/#
|
||||
updatedebughud( 1, "Any team has won rounds: ", ruleround );
|
||||
#/
|
||||
maxroundswon = 0;
|
||||
_a299 = level.teams;
|
||||
_k299 = getFirstArrayKey( _a299 );
|
||||
while ( isDefined( _k299 ) )
|
||||
{
|
||||
team = _a299[ _k299 ];
|
||||
roundswon = game[ "teamScores" ][ team ];
|
||||
if ( maxroundswon < roundswon )
|
||||
{
|
||||
maxroundswon = roundswon;
|
||||
}
|
||||
if ( ruleround <= roundswon )
|
||||
{
|
||||
/#
|
||||
updatedebughud( 3, "Max Rounds Won: ", maxroundswon );
|
||||
#/
|
||||
return 0;
|
||||
}
|
||||
_k299 = getNextArrayKey( _a299, _k299 );
|
||||
}
|
||||
/#
|
||||
updatedebughud( 3, "Max Rounds Won: ", maxroundswon );
|
||||
#/
|
||||
return 1;
|
||||
}
|
||||
|
||||
dem_rules()
|
||||
{
|
||||
return ctf_rules();
|
||||
}
|
||||
|
||||
ctf_rules()
|
||||
{
|
||||
ruleround = 3;
|
||||
roundsplayed = game[ "roundsplayed" ];
|
||||
/#
|
||||
updatedebughud( 1, "Is round or later: ", ruleround );
|
||||
updatedebughud( 3, "Rounds Played: ", roundsplayed );
|
||||
#/
|
||||
if ( ruleround <= roundsplayed )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
koth_rules()
|
||||
{
|
||||
rulescorepercent = 20;
|
||||
ruletimeleft = 60000 * 1,5;
|
||||
/#
|
||||
updatedebughud( 1, "Any player is within percent of score cap: ", rulescorepercent );
|
||||
updatedebughud( 2, "Time limit has less than minutes remaining: ", ruletimeleft / 60000 );
|
||||
#/
|
||||
if ( teamscorelimitcheck( rulescorepercent ) == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( timelimitcheck( ruletimeleft ) == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
conf_rules()
|
||||
{
|
||||
return tdm_rules();
|
||||
}
|
||||
|
||||
oic_rules()
|
||||
{
|
||||
/#
|
||||
updatedebughud( 1, "No join in progress, so shouldnt advertise to matchmaking once the countdown timer ends.", 0 );
|
||||
#/
|
||||
return 0;
|
||||
}
|
||||
|
||||
sas_rules()
|
||||
{
|
||||
rulescorepercent = 35;
|
||||
ruletimeleft = 60000 * 1,5;
|
||||
/#
|
||||
updatedebughud( 1, "Any player is within percent of score cap: ", rulescorepercent );
|
||||
updatedebughud( 2, "Time limit has less than minutes remaining: ", ruletimeleft / 60000 );
|
||||
#/
|
||||
if ( teamscorelimitcheck( rulescorepercent ) == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( timelimitcheck( ruletimeleft ) == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
gun_rules()
|
||||
{
|
||||
ruleweaponsleft = 3;
|
||||
/#
|
||||
updatedebughud( 1, "Any player is within X weapons from winning: ", ruleweaponsleft );
|
||||
#/
|
||||
minweaponsleft = level.gunprogression.size;
|
||||
_a455 = level.players;
|
||||
_k455 = getFirstArrayKey( _a455 );
|
||||
while ( isDefined( _k455 ) )
|
||||
{
|
||||
player = _a455[ _k455 ];
|
||||
weaponsleft = level.gunprogression.size - player.gunprogress;
|
||||
if ( minweaponsleft > weaponsleft )
|
||||
{
|
||||
minweaponsleft = weaponsleft;
|
||||
}
|
||||
if ( ruleweaponsleft >= minweaponsleft )
|
||||
{
|
||||
/#
|
||||
updatedebughud( 3, "Weapons Left: ", minweaponsleft );
|
||||
#/
|
||||
return 0;
|
||||
}
|
||||
_k455 = getNextArrayKey( _a455, _k455 );
|
||||
}
|
||||
/#
|
||||
updatedebughud( 3, "Weapons Left: ", minweaponsleft );
|
||||
#/
|
||||
return 1;
|
||||
}
|
||||
|
||||
shrp_rules()
|
||||
{
|
||||
rulescorepercent = 35;
|
||||
ruletimeleft = 60000 * 1,5;
|
||||
/#
|
||||
updatedebughud( 1, "Any player is within percent of score cap: ", rulescorepercent );
|
||||
updatedebughud( 2, "Time limit has less than minutes remaining: ", ruletimeleft / 60000 );
|
||||
#/
|
||||
if ( teamscorelimitcheck( rulescorepercent ) == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( timelimitcheck( ruletimeleft ) == 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
sessionadvertismentcreatedebughud( linenum, alignx )
|
||||
{
|
||||
/#
|
||||
debug_hud = maps/mp/gametypes/_dev::new_hud( "session_advert", "debug_hud", 0, 0, 1 );
|
||||
debug_hud.hidewheninmenu = 1;
|
||||
debug_hud.horzalign = "right";
|
||||
debug_hud.vertalign = "middle";
|
||||
debug_hud.alignx = "right";
|
||||
debug_hud.aligny = "middle";
|
||||
debug_hud.x = alignx;
|
||||
debug_hud.y = -50 + ( linenum * 15 );
|
||||
debug_hud.foreground = 1;
|
||||
debug_hud.font = "default";
|
||||
debug_hud.fontscale = 1,5;
|
||||
debug_hud.color = ( 1, 0, 0 );
|
||||
debug_hud.alpha = 1;
|
||||
debug_hud settext( "" );
|
||||
return debug_hud;
|
||||
#/
|
||||
}
|
||||
|
||||
updatedebughud( hudindex, text, value )
|
||||
{
|
||||
/#
|
||||
switch( hudindex )
|
||||
{
|
||||
case 1:
|
||||
level.sessionadverthud_1a_text = text;
|
||||
level.sessionadverthud_1b_text = value;
|
||||
break;
|
||||
case 2:
|
||||
level.sessionadverthud_2a_text = text;
|
||||
level.sessionadverthud_2b_text = value;
|
||||
break;
|
||||
case 3:
|
||||
level.sessionadverthud_3a_text = text;
|
||||
level.sessionadverthud_3b_text = value;
|
||||
break;
|
||||
case 4:
|
||||
level.sessionadverthud_4a_text = text;
|
||||
level.sessionadverthud_4b_text = value;
|
||||
break;
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
sessionadvertismentupdatedebughud()
|
||||
{
|
||||
/#
|
||||
level endon( "game_end" );
|
||||
sessionadverthud_0 = undefined;
|
||||
sessionadverthud_1a = undefined;
|
||||
sessionadverthud_1b = undefined;
|
||||
sessionadverthud_2a = undefined;
|
||||
sessionadverthud_2b = undefined;
|
||||
sessionadverthud_3a = undefined;
|
||||
sessionadverthud_3b = undefined;
|
||||
sessionadverthud_4a = undefined;
|
||||
sessionadverthud_4b = undefined;
|
||||
level.sessionadverthud_0_text = "";
|
||||
level.sessionadverthud_1a_text = "";
|
||||
level.sessionadverthud_1b_text = "";
|
||||
level.sessionadverthud_2a_text = "";
|
||||
level.sessionadverthud_2b_text = "";
|
||||
level.sessionadverthud_3a_text = "";
|
||||
level.sessionadverthud_3b_text = "";
|
||||
level.sessionadverthud_4a_text = "";
|
||||
level.sessionadverthud_4b_text = "";
|
||||
while ( 1 )
|
||||
{
|
||||
wait 1;
|
||||
showdebughud = getdvarintdefault( "sessionAdvertShowDebugHud", 0 );
|
||||
level.sessionadverthud_0_text = "Session is advertised";
|
||||
if ( level.sessionadvertstatus == 0 )
|
||||
{
|
||||
level.sessionadverthud_0_text = "Session is not advertised";
|
||||
}
|
||||
if ( !isDefined( sessionadverthud_0 ) && showdebughud != 0 )
|
||||
{
|
||||
host = gethostplayer();
|
||||
while ( !isDefined( host ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
sessionadverthud_0 = host sessionadvertismentcreatedebughud( 0, 0 );
|
||||
sessionadverthud_1a = host sessionadvertismentcreatedebughud( 1, -20 );
|
||||
sessionadverthud_1b = host sessionadvertismentcreatedebughud( 1, 0 );
|
||||
sessionadverthud_2a = host sessionadvertismentcreatedebughud( 2, -20 );
|
||||
sessionadverthud_2b = host sessionadvertismentcreatedebughud( 2, 0 );
|
||||
sessionadverthud_3a = host sessionadvertismentcreatedebughud( 3, -20 );
|
||||
sessionadverthud_3b = host sessionadvertismentcreatedebughud( 3, 0 );
|
||||
sessionadverthud_4a = host sessionadvertismentcreatedebughud( 4, -20 );
|
||||
sessionadverthud_4b = host sessionadvertismentcreatedebughud( 4, 0 );
|
||||
sessionadverthud_1a.color = vectorScale( ( 1, 0, 0 ), 0,5 );
|
||||
sessionadverthud_1b.color = vectorScale( ( 1, 0, 0 ), 0,5 );
|
||||
sessionadverthud_2a.color = vectorScale( ( 1, 0, 0 ), 0,5 );
|
||||
sessionadverthud_2b.color = vectorScale( ( 1, 0, 0 ), 0,5 );
|
||||
}
|
||||
if ( isDefined( sessionadverthud_0 ) )
|
||||
{
|
||||
if ( showdebughud == 0 )
|
||||
{
|
||||
sessionadverthud_0 destroy();
|
||||
sessionadverthud_1a destroy();
|
||||
sessionadverthud_1b destroy();
|
||||
sessionadverthud_2a destroy();
|
||||
sessionadverthud_2b destroy();
|
||||
sessionadverthud_3a destroy();
|
||||
sessionadverthud_3b destroy();
|
||||
sessionadverthud_4a destroy();
|
||||
sessionadverthud_4b destroy();
|
||||
sessionadverthud_0 = undefined;
|
||||
sessionadverthud_1a = undefined;
|
||||
sessionadverthud_1b = undefined;
|
||||
sessionadverthud_2a = undefined;
|
||||
sessionadverthud_2b = undefined;
|
||||
sessionadverthud_3a = undefined;
|
||||
sessionadverthud_3b = undefined;
|
||||
sessionadverthud_4a = undefined;
|
||||
sessionadverthud_4b = undefined;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( level.sessionadvertstatus == 1 )
|
||||
{
|
||||
sessionadverthud_0.color = ( 1, 0, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
sessionadverthud_0.color = vectorScale( ( 1, 0, 0 ), 0,9 );
|
||||
}
|
||||
sessionadverthud_0 settext( level.sessionadverthud_0_text );
|
||||
if ( level.sessionadverthud_1a_text != "" )
|
||||
{
|
||||
sessionadverthud_1a settext( level.sessionadverthud_1a_text );
|
||||
sessionadverthud_1b setvalue( level.sessionadverthud_1b_text );
|
||||
}
|
||||
if ( level.sessionadverthud_2a_text != "" )
|
||||
{
|
||||
sessionadverthud_2a settext( level.sessionadverthud_2a_text );
|
||||
sessionadverthud_2b setvalue( level.sessionadverthud_2b_text );
|
||||
}
|
||||
if ( level.sessionadverthud_3a_text != "" )
|
||||
{
|
||||
sessionadverthud_3a settext( level.sessionadverthud_3a_text );
|
||||
sessionadverthud_3b setvalue( level.sessionadverthud_3b_text );
|
||||
}
|
||||
if ( level.sessionadverthud_4a_text != "" )
|
||||
{
|
||||
sessionadverthud_4a settext( level.sessionadverthud_4a_text );
|
||||
sessionadverthud_4b setvalue( level.sessionadverthud_4b_text );
|
||||
}
|
||||
}
|
||||
}
|
||||
#/
|
||||
}
|
||||
}
|
401
Multiplayer Core/patch_mp/maps/mp/_gamerep.gsc
Normal file
401
Multiplayer Core/patch_mp/maps/mp/_gamerep.gsc
Normal file
@ -0,0 +1,401 @@
|
||||
#include maps/mp/bots/_bot;
|
||||
#include maps/mp/gametypes/_rank;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
if ( !isgamerepenabled() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( isgamerepinitialized() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
game[ "gameRepInitialized" ] = 1;
|
||||
game[ "gameRep" ][ "players" ] = [];
|
||||
game[ "gameRep" ][ "playerNames" ] = [];
|
||||
game[ "gameRep" ][ "max" ] = [];
|
||||
game[ "gameRep" ][ "playerCount" ] = 0;
|
||||
gamerepinitializeparams();
|
||||
}
|
||||
|
||||
isgamerepinitialized()
|
||||
{
|
||||
if ( !isDefined( game[ "gameRepInitialized" ] ) || !game[ "gameRepInitialized" ] )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
isgamerepenabled()
|
||||
{
|
||||
if ( maps/mp/bots/_bot::is_bot_ranked_match() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( sessionmodeiszombiesgame() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( !level.rankedmatch )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
gamerepinitializeparams()
|
||||
{
|
||||
threshold_exceeded_score = 0;
|
||||
threshold_exceeded_score_per_min = 1;
|
||||
threshold_exceeded_kills = 2;
|
||||
threshold_exceeded_deaths = 3;
|
||||
threshold_exceeded_kd_ratio = 4;
|
||||
threshold_exceeded_kills_per_min = 5;
|
||||
threshold_exceeded_plants = 6;
|
||||
threshold_exceeded_defuses = 7;
|
||||
threshold_exceeded_captures = 8;
|
||||
threshold_exceeded_defends = 9;
|
||||
threshold_exceeded_total_time_played = 10;
|
||||
threshold_exceeded_tactical_insertion_use = 11;
|
||||
threshold_exceeded_join_attempts = 12;
|
||||
threshold_exceeded_xp = 13;
|
||||
threshold_exceeded_splitscreen = 14;
|
||||
game[ "gameRep" ][ "params" ] = [];
|
||||
game[ "gameRep" ][ "params" ][ 0 ] = "score";
|
||||
game[ "gameRep" ][ "params" ][ 1 ] = "scorePerMin";
|
||||
game[ "gameRep" ][ "params" ][ 2 ] = "kills";
|
||||
game[ "gameRep" ][ "params" ][ 3 ] = "deaths";
|
||||
game[ "gameRep" ][ "params" ][ 4 ] = "killDeathRatio";
|
||||
game[ "gameRep" ][ "params" ][ 5 ] = "killsPerMin";
|
||||
game[ "gameRep" ][ "params" ][ 6 ] = "plants";
|
||||
game[ "gameRep" ][ "params" ][ 7 ] = "defuses";
|
||||
game[ "gameRep" ][ "params" ][ 8 ] = "captures";
|
||||
game[ "gameRep" ][ "params" ][ 9 ] = "defends";
|
||||
game[ "gameRep" ][ "params" ][ 10 ] = "totalTimePlayed";
|
||||
game[ "gameRep" ][ "params" ][ 11 ] = "tacticalInsertions";
|
||||
game[ "gameRep" ][ "params" ][ 12 ] = "joinAttempts";
|
||||
game[ "gameRep" ][ "params" ][ 13 ] = "xp";
|
||||
game[ "gameRep" ][ "ignoreParams" ] = [];
|
||||
game[ "gameRep" ][ "ignoreParams" ][ 0 ] = "totalTimePlayed";
|
||||
game[ "gameRep" ][ "gameLimit" ] = [];
|
||||
game[ "gameRep" ][ "gameLimit" ][ "default" ] = [];
|
||||
game[ "gameRep" ][ "gameLimit" ][ "tdm" ] = [];
|
||||
game[ "gameRep" ][ "gameLimit" ][ "dm" ] = [];
|
||||
game[ "gameRep" ][ "gameLimit" ][ "dom" ] = [];
|
||||
game[ "gameRep" ][ "gameLimit" ][ "hq" ] = [];
|
||||
game[ "gameRep" ][ "gameLimit" ][ "sd" ] = [];
|
||||
game[ "gameRep" ][ "gameLimit" ][ "dem" ] = [];
|
||||
game[ "gameRep" ][ "gameLimit" ][ "ctf" ] = [];
|
||||
game[ "gameRep" ][ "gameLimit" ][ "koth" ] = [];
|
||||
game[ "gameRep" ][ "gameLimit" ][ "conf" ] = [];
|
||||
game[ "gameRep" ][ "gameLimit" ][ "id" ][ "score" ] = threshold_exceeded_score;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "default" ][ "score" ] = 20000;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "id" ][ "scorePerMin" ] = threshold_exceeded_score_per_min;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "default" ][ "scorePerMin" ] = 250;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "dem" ][ "scorePerMin" ] = 1000;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "tdm" ][ "scorePerMin" ] = 700;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "dm" ][ "scorePerMin" ] = 950;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "dom" ][ "scorePerMin" ] = 1000;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "sd" ][ "scorePerMin" ] = 200;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "ctf" ][ "scorePerMin" ] = 600;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "hq" ][ "scorePerMin" ] = 1000;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "koth" ][ "scorePerMin" ] = 1000;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "conf" ][ "scorePerMin" ] = 1000;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "id" ][ "kills" ] = threshold_exceeded_kills;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "default" ][ "kills" ] = 75;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "tdm" ][ "kills" ] = 40;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "sd" ][ "kills" ] = 15;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "dm" ][ "kills" ] = 31;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "id" ][ "deaths" ] = threshold_exceeded_deaths;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "default" ][ "deaths" ] = 50;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "dm" ][ "deaths" ] = 15;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "tdm" ][ "deaths" ] = 40;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "id" ][ "killDeathRatio" ] = threshold_exceeded_kd_ratio;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "default" ][ "killDeathRatio" ] = 30;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "tdm" ][ "killDeathRatio" ] = 50;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "sd" ][ "killDeathRatio" ] = 20;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "id" ][ "killsPerMin" ] = threshold_exceeded_kills_per_min;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "default" ][ "killsPerMin" ] = 15;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "id" ][ "plants" ] = threshold_exceeded_plants;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "default" ][ "plants" ] = 10;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "id" ][ "defuses" ] = threshold_exceeded_defuses;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "default" ][ "defuses" ] = 10;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "id" ][ "captures" ] = threshold_exceeded_captures;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "default" ][ "captures" ] = 30;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "id" ][ "defends" ] = threshold_exceeded_defends;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "default" ][ "defends" ] = 50;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "id" ][ "totalTimePlayed" ] = threshold_exceeded_total_time_played;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "default" ][ "totalTimePlayed" ] = 600;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "dom" ][ "totalTimePlayed" ] = 600;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "dem" ][ "totalTimePlayed" ] = 1140;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "id" ][ "tacticalInsertions" ] = threshold_exceeded_tactical_insertion_use;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "default" ][ "tacticalInsertions" ] = 20;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "id" ][ "joinAttempts" ] = threshold_exceeded_join_attempts;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "default" ][ "joinAttempts" ] = 3;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "id" ][ "xp" ] = threshold_exceeded_xp;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "default" ][ "xp" ] = 25000;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "id" ][ "splitscreen" ] = threshold_exceeded_splitscreen;
|
||||
game[ "gameRep" ][ "gameLimit" ][ "default" ][ "splitscreen" ] = 8;
|
||||
}
|
||||
|
||||
gamerepplayerconnected()
|
||||
{
|
||||
if ( !isgamerepenabled() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
name = self.name;
|
||||
/#
|
||||
#/
|
||||
if ( !isDefined( game[ "gameRep" ][ "players" ][ name ] ) )
|
||||
{
|
||||
game[ "gameRep" ][ "players" ][ name ] = [];
|
||||
j = 0;
|
||||
while ( j < game[ "gameRep" ][ "params" ].size )
|
||||
{
|
||||
paramname = game[ "gameRep" ][ "params" ][ j ];
|
||||
game[ "gameRep" ][ "players" ][ name ][ paramname ] = 0;
|
||||
j++;
|
||||
}
|
||||
game[ "gameRep" ][ "players" ][ name ][ "splitscreen" ] = self issplitscreen();
|
||||
game[ "gameRep" ][ "players" ][ name ][ "joinAttempts" ] = 1;
|
||||
game[ "gameRep" ][ "players" ][ name ][ "connected" ] = 1;
|
||||
game[ "gameRep" ][ "players" ][ name ][ "xpStart" ] = self getrankxpstat();
|
||||
game[ "gameRep" ][ "playerNames" ][ game[ "gameRep" ][ "playerCount" ] ] = name;
|
||||
game[ "gameRep" ][ "playerCount" ]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !game[ "gameRep" ][ "players" ][ name ][ "connected" ] )
|
||||
{
|
||||
game[ "gameRep" ][ "players" ][ name ][ "joinAttempts" ]++;
|
||||
game[ "gameRep" ][ "players" ][ name ][ "connected" ] = 1;
|
||||
game[ "gameRep" ][ "players" ][ name ][ "xpStart" ] = self getrankxpstat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gamerepplayerdisconnected()
|
||||
{
|
||||
if ( !isgamerepenabled() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
name = self.name;
|
||||
if ( !isDefined( game[ "gameRep" ][ "players" ][ name ] ) || !isDefined( self.pers[ "summary" ] ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
/#
|
||||
#/
|
||||
self gamerepupdatenonpersistentplayerinformation();
|
||||
self gamerepupdatepersistentplayerinformation();
|
||||
game[ "gameRep" ][ "players" ][ name ][ "connected" ] = 0;
|
||||
}
|
||||
|
||||
gamerepupdatenonpersistentplayerinformation()
|
||||
{
|
||||
name = self.name;
|
||||
if ( !isDefined( game[ "gameRep" ][ "players" ][ name ] ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
game[ "gameRep" ][ "players" ][ name ][ "totalTimePlayed" ] += self.timeplayed[ "total" ];
|
||||
if ( isDefined( self.tacticalinsertioncount ) )
|
||||
{
|
||||
game[ "gameRep" ][ "players" ][ name ][ "tacticalInsertions" ] += self.tacticalinsertioncount;
|
||||
}
|
||||
}
|
||||
|
||||
gamerepupdatepersistentplayerinformation()
|
||||
{
|
||||
name = self.name;
|
||||
if ( !isDefined( game[ "gameRep" ][ "players" ][ name ] ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( game[ "gameRep" ][ "players" ][ name ][ "totalTimePlayed" ] != 0 )
|
||||
{
|
||||
timeplayed = game[ "gameRep" ][ "players" ][ name ][ "totalTimePlayed" ];
|
||||
}
|
||||
else
|
||||
{
|
||||
timeplayed = 1;
|
||||
}
|
||||
game[ "gameRep" ][ "players" ][ name ][ "score" ] = self.score;
|
||||
game[ "gameRep" ][ "players" ][ name ][ "scorePerMin" ] = int( game[ "gameRep" ][ "players" ][ name ][ "score" ] / ( timeplayed / 60 ) );
|
||||
game[ "gameRep" ][ "players" ][ name ][ "kills" ] = self.kills;
|
||||
game[ "gameRep" ][ "players" ][ name ][ "deaths" ] = self.deaths;
|
||||
if ( game[ "gameRep" ][ "players" ][ name ][ "deaths" ] != 0 )
|
||||
{
|
||||
game[ "gameRep" ][ "players" ][ name ][ "killDeathRatio" ] = int( ( game[ "gameRep" ][ "players" ][ name ][ "kills" ] / game[ "gameRep" ][ "players" ][ name ][ "deaths" ] ) * 100 );
|
||||
}
|
||||
else
|
||||
{
|
||||
game[ "gameRep" ][ "players" ][ name ][ "killDeathRatio" ] = game[ "gameRep" ][ "players" ][ name ][ "kills" ] * 100;
|
||||
}
|
||||
game[ "gameRep" ][ "players" ][ name ][ "killsPerMin" ] = int( game[ "gameRep" ][ "players" ][ name ][ "kills" ] / ( timeplayed / 60 ) );
|
||||
game[ "gameRep" ][ "players" ][ name ][ "plants" ] = self.plants;
|
||||
game[ "gameRep" ][ "players" ][ name ][ "defuses" ] = self.defuses;
|
||||
game[ "gameRep" ][ "players" ][ name ][ "captures" ] = self.captures;
|
||||
game[ "gameRep" ][ "players" ][ name ][ "defends" ] = self.defends;
|
||||
game[ "gameRep" ][ "players" ][ name ][ "xp" ] = self getrankxpstat() - game[ "gameRep" ][ "players" ][ name ][ "xpStart" ];
|
||||
game[ "gameRep" ][ "players" ][ name ][ "xpStart" ] = self getrankxpstat();
|
||||
}
|
||||
|
||||
getparamvalueforplayer( playername, paramname )
|
||||
{
|
||||
if ( isDefined( game[ "gameRep" ][ "players" ][ playername ][ paramname ] ) )
|
||||
{
|
||||
return game[ "gameRep" ][ "players" ][ playername ][ paramname ];
|
||||
}
|
||||
/#
|
||||
assertmsg( "Unknown parameter " + paramname + "for individual player" );
|
||||
#/
|
||||
}
|
||||
|
||||
isgamerepparamvalid( paramname )
|
||||
{
|
||||
gametype = level.gametype;
|
||||
if ( !isDefined( game[ "gameRep" ] ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( !isDefined( game[ "gameRep" ][ "gameLimit" ] ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( !isDefined( game[ "gameRep" ][ "gameLimit" ][ gametype ] ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( !isDefined( game[ "gameRep" ][ "gameLimit" ][ gametype ][ paramname ] ) && !isDefined( game[ "gameRep" ][ "gameLimit" ][ "default" ][ paramname ] ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
isgamerepparamignoredforreporting( paramname )
|
||||
{
|
||||
if ( isDefined( game[ "gameRep" ][ "ignoreParams" ][ paramname ] ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
getgamerepparamlimit( paramname )
|
||||
{
|
||||
gametype = level.gametype;
|
||||
if ( isDefined( game[ "gameRep" ][ "gameLimit" ][ gametype ] ) )
|
||||
{
|
||||
if ( isDefined( game[ "gameRep" ][ "gameLimit" ][ gametype ][ paramname ] ) )
|
||||
{
|
||||
return game[ "gameRep" ][ "gameLimit" ][ gametype ][ paramname ];
|
||||
}
|
||||
}
|
||||
if ( isDefined( game[ "gameRep" ][ "gameLimit" ][ "default" ][ paramname ] ) )
|
||||
{
|
||||
return game[ "gameRep" ][ "gameLimit" ][ "default" ][ paramname ];
|
||||
}
|
||||
/#
|
||||
assertmsg( "Default values for parameter " + paramname + " is not defined." );
|
||||
#/
|
||||
}
|
||||
|
||||
setmaximumparamvalueforcurrentgame( paramname, value )
|
||||
{
|
||||
if ( !isDefined( game[ "gameRep" ][ "max" ][ paramname ] ) )
|
||||
{
|
||||
game[ "gameRep" ][ "max" ][ paramname ] = value;
|
||||
return;
|
||||
}
|
||||
if ( game[ "gameRep" ][ "max" ][ paramname ] < value )
|
||||
{
|
||||
game[ "gameRep" ][ "max" ][ paramname ] = value;
|
||||
}
|
||||
}
|
||||
|
||||
gamerepupdateinformationforround()
|
||||
{
|
||||
if ( !isgamerepenabled() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
players = get_players();
|
||||
i = 0;
|
||||
while ( i < players.size )
|
||||
{
|
||||
player = players[ i ];
|
||||
player gamerepupdatenonpersistentplayerinformation();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
gamerepanalyzeandreport()
|
||||
{
|
||||
if ( !isgamerepenabled() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
players = get_players();
|
||||
i = 0;
|
||||
while ( i < players.size )
|
||||
{
|
||||
player = players[ i ];
|
||||
player gamerepupdatepersistentplayerinformation();
|
||||
i++;
|
||||
}
|
||||
splitscreenplayercount = 0;
|
||||
i = 0;
|
||||
while ( i < game[ "gameRep" ][ "playerNames" ].size )
|
||||
{
|
||||
playername = game[ "gameRep" ][ "playerNames" ][ i ];
|
||||
j = 0;
|
||||
while ( j < game[ "gameRep" ][ "params" ].size )
|
||||
{
|
||||
paramname = game[ "gameRep" ][ "params" ][ j ];
|
||||
if ( isgamerepparamvalid( paramname ) )
|
||||
{
|
||||
setmaximumparamvalueforcurrentgame( paramname, getparamvalueforplayer( playername, paramname ) );
|
||||
}
|
||||
j++;
|
||||
}
|
||||
paramname = "splitscreen";
|
||||
splitscreenplayercount += getparamvalueforplayer( playername, paramname );
|
||||
i++;
|
||||
}
|
||||
setmaximumparamvalueforcurrentgame( paramname, splitscreenplayercount );
|
||||
j = 0;
|
||||
while ( j < game[ "gameRep" ][ "params" ].size )
|
||||
{
|
||||
paramname = game[ "gameRep" ][ "params" ][ j ];
|
||||
if ( isgamerepparamvalid( paramname ) && game[ "gameRep" ][ "max" ][ paramname ] >= getgamerepparamlimit( paramname ) )
|
||||
{
|
||||
gamerepprepareandreport( paramname );
|
||||
}
|
||||
j++;
|
||||
}
|
||||
paramname = "splitscreen";
|
||||
if ( game[ "gameRep" ][ "max" ][ paramname ] >= getgamerepparamlimit( paramname ) )
|
||||
{
|
||||
gamerepprepareandreport( paramname );
|
||||
}
|
||||
}
|
||||
|
||||
gamerepprepareandreport( paramname )
|
||||
{
|
||||
if ( !isDefined( game[ "gameRep" ][ "gameLimit" ][ "id" ][ paramname ] ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( isgamerepparamignoredforreporting( paramname ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
gamerepthresholdexceeded( game[ "gameRep" ][ "gameLimit" ][ "id" ][ paramname ] );
|
||||
}
|
59
Multiplayer Core/patch_mp/maps/mp/_global_fx.gsc
Normal file
59
Multiplayer Core/patch_mp/maps/mp/_global_fx.gsc
Normal file
@ -0,0 +1,59 @@
|
||||
//checked includes match cerberus output
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
|
||||
main() //checked matches cerberus output
|
||||
{
|
||||
randomstartdelay = randomfloatrange( -20, -15 );
|
||||
global_fx( "barrel_fireFX_origin", "global_barrel_fire", "fire/firelp_barrel_pm", randomstartdelay, "fire_barrel_small" );
|
||||
global_fx( "ch_streetlight_02_FX_origin", "ch_streetlight_02_FX", "misc/lighthaze", randomstartdelay );
|
||||
global_fx( "me_streetlight_01_FX_origin", "me_streetlight_01_FX", "misc/lighthaze_bog_a", randomstartdelay );
|
||||
global_fx( "ch_street_light_01_on", "lamp_glow_FX", "misc/light_glow_white", randomstartdelay );
|
||||
global_fx( "highway_lamp_post", "ch_streetlight_02_FX", "misc/lighthaze_villassault", randomstartdelay );
|
||||
global_fx( "cs_cargoship_spotlight_on_FX_origin", "cs_cargoship_spotlight_on_FX", "misc/lighthaze", randomstartdelay );
|
||||
global_fx( "me_dumpster_fire_FX_origin", "me_dumpster_fire_FX", "fire/firelp_med_pm_nodistort", randomstartdelay, "fire_dumpster_medium" );
|
||||
global_fx( "com_tires_burning01_FX_origin", "com_tires_burning01_FX", "fire/tire_fire_med", randomstartdelay );
|
||||
global_fx( "icbm_powerlinetower_FX_origin", "icbm_powerlinetower_FX", "misc/power_tower_light_red_blink", randomstartdelay );
|
||||
}
|
||||
|
||||
global_fx( targetname, fxname, fxfile, delay, soundalias ) //checked changed to match cerberus output
|
||||
{
|
||||
ents = getstructarray( targetname, "targetname" );
|
||||
if ( !isDefined( ents ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( ents.size <= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
for ( i = 0; i < ents.size; i++ )
|
||||
{
|
||||
ents[ i ] global_fx_create( fxname, fxfile, delay, soundalias );
|
||||
}
|
||||
}
|
||||
|
||||
global_fx_create( fxname, fxfile, delay, soundalias ) //checked matches cerberus output
|
||||
{
|
||||
if ( !isDefined( level._effect ) )
|
||||
{
|
||||
level._effect = [];
|
||||
}
|
||||
if ( !isDefined( level._effect[ fxname ] ) )
|
||||
{
|
||||
level._effect[ fxname ] = loadfx( fxfile );
|
||||
}
|
||||
if ( !isDefined( self.angles ) )
|
||||
{
|
||||
self.angles = ( 0, 0, 0 );
|
||||
}
|
||||
ent = createoneshoteffect( fxname );
|
||||
ent.v[ "origin" ] = self.origin;
|
||||
ent.v[ "angles" ] = self.angles;
|
||||
ent.v[ "fxid" ] = fxname;
|
||||
ent.v[ "delay" ] = delay;
|
||||
if ( isDefined( soundalias ) )
|
||||
{
|
||||
ent.v[ "soundalias" ] = soundalias;
|
||||
}
|
||||
}
|
746
Multiplayer Core/patch_mp/maps/mp/_hacker_tool.gsc
Normal file
746
Multiplayer Core/patch_mp/maps/mp/_hacker_tool.gsc
Normal file
@ -0,0 +1,746 @@
|
||||
#include maps/mp/gametypes/_weaponobjects;
|
||||
#include maps/mp/killstreaks/_supplydrop;
|
||||
#include maps/mp/_heatseekingmissile;
|
||||
#include maps/mp/gametypes/_hud_util;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level.hackertoolmaxequipmentdistance = 2000;
|
||||
level.hackertoolmaxequipmentdistancesq = level.hackertoolmaxequipmentdistance * level.hackertoolmaxequipmentdistance;
|
||||
level.hackertoolnosighthackdistance = 750;
|
||||
level.hackertoollostsightlimitms = 450;
|
||||
level.hackertoollockonradius = 20;
|
||||
level.hackertoollockonfov = 65;
|
||||
level.hackertoolhacktimems = 0,5;
|
||||
level.equipmenthackertoolradius = 60;
|
||||
level.equipmenthackertooltimems = 50;
|
||||
level.carepackagehackertoolradius = 60;
|
||||
level.carepackagehackertooltimems = getgametypesetting( "crateCaptureTime" ) * 500;
|
||||
level.carepackagefriendlyhackertooltimems = getgametypesetting( "crateCaptureTime" ) * 2000;
|
||||
level.carepackageownerhackertooltimems = 250;
|
||||
level.sentryhackertoolradius = 80;
|
||||
level.sentryhackertooltimems = 4000;
|
||||
level.microwavehackertoolradius = 80;
|
||||
level.microwavehackertooltimems = 4000;
|
||||
level.vehiclehackertoolradius = 80;
|
||||
level.vehiclehackertooltimems = 4000;
|
||||
level.rcxdhackertooltimems = 1500;
|
||||
level.rcxdhackertoolradius = 20;
|
||||
level.uavhackertooltimems = 4000;
|
||||
level.uavhackertoolradius = 40;
|
||||
level.cuavhackertooltimems = 4000;
|
||||
level.cuavhackertoolradius = 40;
|
||||
level.carepackagechopperhackertooltimems = 3000;
|
||||
level.carepackagechopperhackertoolradius = 60;
|
||||
level.littlebirdhackertooltimems = 4000;
|
||||
level.littlebirdhackertoolradius = 80;
|
||||
level.qrdronehackertooltimems = 3000;
|
||||
level.qrdronehackertoolradius = 60;
|
||||
level.aitankhackertooltimems = 4000;
|
||||
level.aitankhackertoolradius = 60;
|
||||
level.stealthchopperhackertooltimems = 4000;
|
||||
level.stealthchopperhackertoolradius = 80;
|
||||
level.warthoghackertooltimems = 4000;
|
||||
level.warthoghackertoolradius = 80;
|
||||
level.lodestarhackertooltimems = 4000;
|
||||
level.lodestarhackertoolradius = 60;
|
||||
level.choppergunnerhackertooltimems = 4000;
|
||||
level.choppergunnerhackertoolradius = 260;
|
||||
thread onplayerconnect();
|
||||
}
|
||||
|
||||
onplayerconnect()
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( "connecting", player );
|
||||
player thread onplayerspawned();
|
||||
}
|
||||
}
|
||||
|
||||
onplayerspawned()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
self clearhackertarget();
|
||||
self thread watchhackertooluse();
|
||||
self thread watchhackertoolfired();
|
||||
}
|
||||
}
|
||||
|
||||
clearhackertarget()
|
||||
{
|
||||
self notify( "stop_lockon_sound" );
|
||||
self notify( "stop_locked_sound" );
|
||||
self.stingerlocksound = undefined;
|
||||
self stoprumble( "stinger_lock_rumble" );
|
||||
self.hackertoollockstarttime = 0;
|
||||
self.hackertoollockstarted = 0;
|
||||
self.hackertoollockfinalized = 0;
|
||||
self.hackertoollocktimeelapsed = 0;
|
||||
self setweaponheatpercent( "pda_hack_mp", 0 );
|
||||
if ( isDefined( self.hackertooltarget ) )
|
||||
{
|
||||
lockingon( self.hackertooltarget, 0 );
|
||||
lockedon( self.hackertooltarget, 0 );
|
||||
}
|
||||
self.hackertooltarget = undefined;
|
||||
self weaponlockfree();
|
||||
self weaponlocktargettooclose( 0 );
|
||||
self weaponlocknoclearance( 0 );
|
||||
self stoplocalsound( game[ "locking_on_sound" ] );
|
||||
self stoplocalsound( game[ "locked_on_sound" ] );
|
||||
self destroylockoncanceledmessage();
|
||||
}
|
||||
|
||||
watchhackertoolfired()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
while ( 1 )
|
||||
{
|
||||
self waittill( "hacker_tool_fired", hackertooltarget );
|
||||
if ( isDefined( hackertooltarget ) )
|
||||
{
|
||||
if ( isentityhackablecarepackage( hackertooltarget ) )
|
||||
{
|
||||
maps/mp/killstreaks/_supplydrop::givecratecapturemedal( hackertooltarget, self );
|
||||
hackertooltarget notify( "captured" );
|
||||
}
|
||||
if ( isentityhackableweaponobject( hackertooltarget ) || isDefined( hackertooltarget.hackertrigger ) )
|
||||
{
|
||||
hackertooltarget.hackertrigger notify( "trigger" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isDefined( hackertooltarget.classname ) && hackertooltarget.classname == "grenade" )
|
||||
{
|
||||
damage = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isDefined( hackertooltarget.maxhealth ) )
|
||||
{
|
||||
damage = hackertooltarget.maxhealth + 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
damage = 999999;
|
||||
}
|
||||
}
|
||||
if ( isDefined( hackertooltarget.numflares ) && hackertooltarget.numflares > 0 )
|
||||
{
|
||||
damage = 1;
|
||||
hackertooltarget.numflares--;
|
||||
|
||||
hackertooltarget maps/mp/_heatseekingmissile::missiletarget_playflarefx();
|
||||
}
|
||||
hackertooltarget dodamage( damage, self.origin, self, self, 0, "MOD_UNKNOWN", 0, "pda_hack_mp" );
|
||||
}
|
||||
self addplayerstat( "hack_enemy_target", 1 );
|
||||
self addweaponstat( "pda_hack_mp", "used", 1 );
|
||||
}
|
||||
clearhackertarget();
|
||||
self forceoffhandend();
|
||||
clip_ammo = self getweaponammoclip( "pda_hack_mp" );
|
||||
clip_ammo--;
|
||||
|
||||
/#
|
||||
assert( clip_ammo >= 0 );
|
||||
#/
|
||||
self setweaponammoclip( "pda_hack_mp", clip_ammo );
|
||||
self switchtoweapon( self getlastweapon() );
|
||||
}
|
||||
}
|
||||
|
||||
watchhackertooluse()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "grenade_pullback", weapon );
|
||||
if ( weapon == "pda_hack_mp" )
|
||||
{
|
||||
wait 0,05;
|
||||
if ( self isusingoffhand() && self getcurrentoffhand() == "pda_hack_mp" )
|
||||
{
|
||||
self thread hackertooltargetloop();
|
||||
self thread watchhackertoolend();
|
||||
self thread watchforgrenadefire();
|
||||
self thread watchhackertoolinterrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watchhackertoolinterrupt()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "hacker_tool_fired" );
|
||||
self endon( "death" );
|
||||
self endon( "weapon_change" );
|
||||
self endon( "grenade_fire" );
|
||||
while ( 1 )
|
||||
{
|
||||
level waittill( "use_interrupt", interrupttarget );
|
||||
if ( self.hackertooltarget == interrupttarget )
|
||||
{
|
||||
clearhackertarget();
|
||||
}
|
||||
wait 0,05;
|
||||
}
|
||||
}
|
||||
|
||||
watchhackertoolend()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "hacker_tool_fired" );
|
||||
msg = self waittill_any_return( "weapon_change", "death" );
|
||||
clearhackertarget();
|
||||
}
|
||||
|
||||
watchforgrenadefire()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "hacker_tool_fired" );
|
||||
self endon( "weapon_change" );
|
||||
self endon( "death" );
|
||||
while ( 1 )
|
||||
{
|
||||
self waittill( "grenade_fire", grenade, grenadename, respawnfromhack );
|
||||
if ( isDefined( respawnfromhack ) && respawnfromhack )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
clearhackertarget();
|
||||
clip_ammo = self getweaponammoclip( "pda_hack_mp" );
|
||||
clip_max_ammo = weaponclipsize( "pda_hack_mp" );
|
||||
if ( clip_ammo < clip_max_ammo )
|
||||
{
|
||||
clip_ammo++;
|
||||
}
|
||||
self setweaponammoclip( "pda_hack_mp", clip_ammo );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
hackertooltargetloop()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self endon( "weapon_change" );
|
||||
self endon( "grenade_fire" );
|
||||
while ( 1 )
|
||||
{
|
||||
wait 0,05;
|
||||
if ( self.hackertoollockfinalized )
|
||||
{
|
||||
while ( !self isvalidhackertooltarget( self.hackertooltarget ) )
|
||||
{
|
||||
self clearhackertarget();
|
||||
}
|
||||
passed = self hackersoftsighttest();
|
||||
while ( !passed )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
lockingon( self.hackertooltarget, 0 );
|
||||
lockedon( self.hackertooltarget, 1 );
|
||||
thread looplocallocksound( game[ "locked_on_sound" ], 0,75 );
|
||||
self notify( "hacker_tool_fired" );
|
||||
return;
|
||||
}
|
||||
while ( self.hackertoollockstarted )
|
||||
{
|
||||
while ( !self isvalidhackertooltarget( self.hackertooltarget ) )
|
||||
{
|
||||
self clearhackertarget();
|
||||
}
|
||||
locklengthms = self gethacktime( self.hackertooltarget );
|
||||
while ( locklengthms == 0 )
|
||||
{
|
||||
self clearhackertarget();
|
||||
}
|
||||
if ( self.hackertoollocktimeelapsed == 0 )
|
||||
{
|
||||
self playlocalsound( "evt_hacker_hacking" );
|
||||
}
|
||||
lockingon( self.hackertooltarget, 1 );
|
||||
lockedon( self.hackertooltarget, 0 );
|
||||
passed = self hackersoftsighttest();
|
||||
while ( !passed )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( self.hackertoollostsightlinetime == 0 )
|
||||
{
|
||||
self.hackertoollocktimeelapsed += 0,05;
|
||||
hackpercentage = self.hackertoollocktimeelapsed / ( locklengthms / 1000 );
|
||||
self setweaponheatpercent( "pda_hack_mp", hackpercentage );
|
||||
}
|
||||
while ( self.hackertoollocktimeelapsed < ( locklengthms / 1000 ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/#
|
||||
assert( isDefined( self.hackertooltarget ) );
|
||||
#/
|
||||
self notify( "stop_lockon_sound" );
|
||||
self.hackertoollockfinalized = 1;
|
||||
self weaponlockfinalize( self.hackertooltarget );
|
||||
}
|
||||
besttarget = self getbesthackertooltarget();
|
||||
while ( !isDefined( besttarget ) )
|
||||
{
|
||||
self destroylockoncanceledmessage();
|
||||
}
|
||||
while ( !self locksighttest( besttarget ) && distance2d( self.origin, besttarget.origin ) > level.hackertoolnosighthackdistance )
|
||||
{
|
||||
self destroylockoncanceledmessage();
|
||||
}
|
||||
while ( self locksighttest( besttarget ) && isDefined( besttarget.lockondelay ) && besttarget.lockondelay )
|
||||
{
|
||||
self displaylockoncanceledmessage();
|
||||
}
|
||||
self destroylockoncanceledmessage();
|
||||
initlockfield( besttarget );
|
||||
self.hackertooltarget = besttarget;
|
||||
self.hackertoollockstarttime = getTime();
|
||||
self.hackertoollockstarted = 1;
|
||||
self.hackertoollostsightlinetime = 0;
|
||||
self.hackertoollocktimeelapsed = 0;
|
||||
self setweaponheatpercent( "pda_hack_mp", 0 );
|
||||
self thread looplocalseeksound( game[ "locking_on_sound" ], 0,6 );
|
||||
}
|
||||
}
|
||||
|
||||
getbesthackertooltarget()
|
||||
{
|
||||
targetsvalid = [];
|
||||
targetsall = arraycombine( target_getarray(), level.missileentities, 0, 0 );
|
||||
targetsall = arraycombine( targetsall, level.hackertooltargets, 0, 0 );
|
||||
idx = 0;
|
||||
while ( idx < targetsall.size )
|
||||
{
|
||||
target_ent = targetsall[ idx ];
|
||||
if ( !isDefined( target_ent ) || !isDefined( target_ent.owner ) )
|
||||
{
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/#
|
||||
if ( getDvar( "scr_freelock" ) == "1" )
|
||||
{
|
||||
if ( self iswithinhackertoolreticle( targetsall[ idx ] ) )
|
||||
{
|
||||
targetsvalid[ targetsvalid.size ] = targetsall[ idx ];
|
||||
}
|
||||
idx++;
|
||||
continue;
|
||||
#/
|
||||
}
|
||||
else if ( level.teambased )
|
||||
{
|
||||
if ( isentityhackablecarepackage( target_ent ) )
|
||||
{
|
||||
if ( self iswithinhackertoolreticle( target_ent ) )
|
||||
{
|
||||
targetsvalid[ targetsvalid.size ] = target_ent;
|
||||
}
|
||||
}
|
||||
else if ( isDefined( target_ent.team ) )
|
||||
{
|
||||
if ( target_ent.team != self.team )
|
||||
{
|
||||
if ( self iswithinhackertoolreticle( target_ent ) )
|
||||
{
|
||||
targetsvalid[ targetsvalid.size ] = target_ent;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isDefined( target_ent.owner.team ) )
|
||||
{
|
||||
if ( target_ent.owner.team != self.team )
|
||||
{
|
||||
if ( self iswithinhackertoolreticle( target_ent ) )
|
||||
{
|
||||
targetsvalid[ targetsvalid.size ] = target_ent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
else if ( self iswithinhackertoolreticle( target_ent ) )
|
||||
{
|
||||
if ( isentityhackablecarepackage( target_ent ) )
|
||||
{
|
||||
targetsvalid[ targetsvalid.size ] = target_ent;
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isDefined( target_ent.owner ) && self != target_ent.owner )
|
||||
{
|
||||
targetsvalid[ targetsvalid.size ] = target_ent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
chosenent = undefined;
|
||||
if ( targetsvalid.size != 0 )
|
||||
{
|
||||
chosenent = targetsvalid[ 0 ];
|
||||
}
|
||||
return chosenent;
|
||||
}
|
||||
|
||||
iswithinhackertoolreticle( target )
|
||||
{
|
||||
radius = gethackertoolradius( target );
|
||||
return target_isincircle( target, self, level.hackertoollockonfov, radius, 0 );
|
||||
}
|
||||
|
||||
isentityhackableweaponobject( entity )
|
||||
{
|
||||
if ( isDefined( entity.classname ) && entity.classname == "grenade" )
|
||||
{
|
||||
if ( isDefined( entity.name ) )
|
||||
{
|
||||
watcher = maps/mp/gametypes/_weaponobjects::getweaponobjectwatcherbyweapon( entity.name );
|
||||
if ( isDefined( watcher ) )
|
||||
{
|
||||
if ( watcher.hackable )
|
||||
{
|
||||
/#
|
||||
assert( isDefined( watcher.hackertoolradius ) );
|
||||
assert( isDefined( watcher.hackertooltimems ) );
|
||||
#/
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
getweaponobjecthackerradius( entity )
|
||||
{
|
||||
/#
|
||||
assert( isDefined( entity.classname ) );
|
||||
assert( isDefined( entity.name ) );
|
||||
#/
|
||||
watcher = maps/mp/gametypes/_weaponobjects::getweaponobjectwatcherbyweapon( entity.name );
|
||||
/#
|
||||
assert( watcher.hackable );
|
||||
assert( isDefined( watcher.hackertoolradius ) );
|
||||
#/
|
||||
return watcher.hackertoolradius;
|
||||
}
|
||||
|
||||
getweaponobjecthacktimems( entity )
|
||||
{
|
||||
/#
|
||||
assert( isDefined( entity.classname ) );
|
||||
assert( isDefined( entity.name ) );
|
||||
#/
|
||||
watcher = maps/mp/gametypes/_weaponobjects::getweaponobjectwatcherbyweapon( entity.name );
|
||||
/#
|
||||
assert( watcher.hackable );
|
||||
assert( isDefined( watcher.hackertooltimems ) );
|
||||
#/
|
||||
return watcher.hackertooltimems;
|
||||
}
|
||||
|
||||
isentityhackablecarepackage( entity )
|
||||
{
|
||||
if ( isDefined( entity.model ) )
|
||||
{
|
||||
return entity.model == "t6_wpn_supply_drop_ally";
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
isvalidhackertooltarget( ent )
|
||||
{
|
||||
if ( !isDefined( ent ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( self isusingremote() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( self isempjammed() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( !target_istarget( ent ) && !isentityhackableweaponobject( ent ) && !isinarray( level.hackertooltargets, ent ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( isentityhackableweaponobject( ent ) )
|
||||
{
|
||||
if ( distancesquared( self.origin, ent.origin ) > level.hackertoolmaxequipmentdistancesq )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
hackersoftsighttest()
|
||||
{
|
||||
passed = 1;
|
||||
locklengthms = 0;
|
||||
if ( isDefined( self.hackertooltarget ) )
|
||||
{
|
||||
locklengthms = self gethacktime( self.hackertooltarget );
|
||||
}
|
||||
if ( self isempjammed() || locklengthms == 0 )
|
||||
{
|
||||
self clearhackertarget();
|
||||
passed = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( iswithinhackertoolreticle( self.hackertooltarget ) )
|
||||
{
|
||||
self.hackertoollostsightlinetime = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( self.hackertoollostsightlinetime == 0 )
|
||||
{
|
||||
self.hackertoollostsightlinetime = getTime();
|
||||
}
|
||||
timepassed = getTime() - self.hackertoollostsightlinetime;
|
||||
if ( timepassed >= level.hackertoollostsightlimitms )
|
||||
{
|
||||
self clearhackertarget();
|
||||
passed = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return passed;
|
||||
}
|
||||
|
||||
registerwithhackertool( radius, hacktimems )
|
||||
{
|
||||
self endon( "death" );
|
||||
if ( isDefined( radius ) )
|
||||
{
|
||||
self.hackertoolradius = radius;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.hackertoolradius = level.hackertoollockonradius;
|
||||
}
|
||||
if ( isDefined( hacktimems ) )
|
||||
{
|
||||
self.hackertooltimems = hacktimems;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.hackertooltimems = level.hackertoolhacktimems;
|
||||
}
|
||||
self thread watchhackableentitydeath();
|
||||
level.hackertooltargets[ level.hackertooltargets.size ] = self;
|
||||
}
|
||||
|
||||
watchhackableentitydeath()
|
||||
{
|
||||
self waittill( "death" );
|
||||
arrayremovevalue( level.hackertooltargets, self );
|
||||
}
|
||||
|
||||
gethackertoolradius( target )
|
||||
{
|
||||
radius = 20;
|
||||
if ( isentityhackablecarepackage( target ) )
|
||||
{
|
||||
/#
|
||||
assert( isDefined( target.hackertoolradius ) );
|
||||
#/
|
||||
radius = target.hackertoolradius;
|
||||
break;
|
||||
}
|
||||
else if ( isentityhackableweaponobject( target ) )
|
||||
{
|
||||
radius = getweaponobjecthackerradius( target );
|
||||
break;
|
||||
}
|
||||
else if ( isDefined( target.hackertoolradius ) )
|
||||
{
|
||||
radius = target.hackertoolradius;
|
||||
break;
|
||||
}
|
||||
else radius = level.vehiclehackertoolradius;
|
||||
switch( target.model )
|
||||
{
|
||||
case "veh_t6_drone_uav":
|
||||
radius = level.uavhackertoolradius;
|
||||
break;
|
||||
case "veh_t6_drone_cuav":
|
||||
radius = level.cuavhackertoolradius;
|
||||
break;
|
||||
case "t5_veh_rcbomb_axis":
|
||||
radius = level.rcxdhackertoolradius;
|
||||
break;
|
||||
case "veh_iw_mh6_littlebird_mp":
|
||||
radius = level.carepackagechopperhackertoolradius;
|
||||
break;
|
||||
case "veh_t6_drone_quad_rotor_mp":
|
||||
case "veh_t6_drone_quad_rotor_mp_alt":
|
||||
radius = level.qrdronehackertoolradius;
|
||||
break;
|
||||
case "veh_t6_drone_tank":
|
||||
case "veh_t6_drone_tank_alt":
|
||||
radius = level.aitankhackertoolradius;
|
||||
break;
|
||||
case "veh_t6_air_attack_heli_mp_dark":
|
||||
case "veh_t6_air_attack_heli_mp_light":
|
||||
radius = level.stealthchopperhackertoolradius;
|
||||
break;
|
||||
case "veh_t6_drone_overwatch_dark":
|
||||
case "veh_t6_drone_overwatch_light":
|
||||
radius = level.littlebirdhackertoolradius;
|
||||
break;
|
||||
case "veh_t6_drone_pegasus":
|
||||
radius = level.lodestarhackertoolradius;
|
||||
break;
|
||||
case "veh_iw_air_apache_killstreak":
|
||||
radius = level.choppergunnerhackertoolradius;
|
||||
break;
|
||||
case "veh_t6_air_a10f":
|
||||
case "veh_t6_air_a10f_alt":
|
||||
radius = level.warthoghackertoolradius;
|
||||
break;
|
||||
}
|
||||
return radius;
|
||||
}
|
||||
|
||||
gethacktime( target )
|
||||
{
|
||||
time = 500;
|
||||
if ( isentityhackablecarepackage( target ) )
|
||||
{
|
||||
/#
|
||||
assert( isDefined( target.hackertooltimems ) );
|
||||
#/
|
||||
if ( isDefined( target.owner ) && target.owner == self )
|
||||
{
|
||||
time = level.carepackageownerhackertooltimems;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isDefined( target.owner ) && target.owner.team == self.team )
|
||||
{
|
||||
time = level.carepackagefriendlyhackertooltimems;
|
||||
}
|
||||
else
|
||||
{
|
||||
time = level.carepackagehackertooltimems;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if ( isentityhackableweaponobject( target ) )
|
||||
{
|
||||
time = getweaponobjecthacktimems( target );
|
||||
break;
|
||||
}
|
||||
else if ( isDefined( target.hackertooltimems ) )
|
||||
{
|
||||
time = target.hackertooltimems;
|
||||
break;
|
||||
}
|
||||
else time = level.vehiclehackertooltimems;
|
||||
switch( target.model )
|
||||
{
|
||||
case "veh_t6_drone_uav":
|
||||
time = level.uavhackertooltimems;
|
||||
break;
|
||||
case "veh_t6_drone_cuav":
|
||||
time = level.cuavhackertooltimems;
|
||||
break;
|
||||
case "t5_veh_rcbomb_axis":
|
||||
time = level.rcxdhackertooltimems;
|
||||
break;
|
||||
case "veh_t6_drone_supply_alt":
|
||||
case "veh_t6_drone_supply_alt":
|
||||
time = level.carepackagechopperhackertooltimems;
|
||||
break;
|
||||
case "veh_t6_drone_quad_rotor_mp":
|
||||
case "veh_t6_drone_quad_rotor_mp_alt":
|
||||
time = level.qrdronehackertooltimems;
|
||||
break;
|
||||
case "veh_t6_drone_tank":
|
||||
case "veh_t6_drone_tank_alt":
|
||||
time = level.aitankhackertooltimems;
|
||||
break;
|
||||
case "veh_t6_air_attack_heli_mp_dark":
|
||||
case "veh_t6_air_attack_heli_mp_light":
|
||||
time = level.stealthchopperhackertooltimems;
|
||||
break;
|
||||
case "veh_t6_drone_overwatch_dark":
|
||||
case "veh_t6_drone_overwatch_light":
|
||||
time = level.littlebirdhackertooltimems;
|
||||
break;
|
||||
case "veh_t6_drone_pegasus":
|
||||
time = level.lodestarhackertooltimems;
|
||||
break;
|
||||
case "veh_t6_air_v78_vtol_killstreak":
|
||||
case "veh_t6_air_v78_vtol_killstreak_alt":
|
||||
time = level.choppergunnerhackertooltimems;
|
||||
break;
|
||||
case "veh_t6_air_a10f":
|
||||
case "veh_t6_air_a10f_alt":
|
||||
time = level.warthoghackertooltimems;
|
||||
break;
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
tunables()
|
||||
{
|
||||
/#
|
||||
while ( 1 )
|
||||
{
|
||||
level.hackertoollostsightlimitms = weapons_get_dvar_int( "scr_hackerToolLostSightLimitMs", 1000 );
|
||||
level.hackertoollockonradius = weapons_get_dvar( "scr_hackerToolLockOnRadius", 20 );
|
||||
level.hackertoollockonfov = weapons_get_dvar_int( "scr_hackerToolLockOnFOV", 65 );
|
||||
level.rcxd_time = weapons_get_dvar( "scr_rcxd_time", 1,5 );
|
||||
level.uav_time = weapons_get_dvar_int( "scr_uav_time", 4 );
|
||||
level.cuav_time = weapons_get_dvar_int( "scr_cuav_time", 4 );
|
||||
level.care_package_chopper_time = weapons_get_dvar_int( "scr_care_package_chopper_time", 3 );
|
||||
level.guardian_time = weapons_get_dvar_int( "scr_guardian_time", 5 );
|
||||
level.sentry_time = weapons_get_dvar_int( "scr_sentry_time", 5 );
|
||||
level.wasp_time = weapons_get_dvar_int( "scr_wasp_time", 5 );
|
||||
level.agr_time = weapons_get_dvar_int( "scr_agr_time", 5 );
|
||||
level.stealth_helicopter_time = weapons_get_dvar_int( "scr_stealth_helicopter_time", 7 );
|
||||
level.escort_drone_time = weapons_get_dvar_int( "scr_escort_drone_time", 7 );
|
||||
level.warthog_time = weapons_get_dvar_int( "scr_warthog_time", 7 );
|
||||
level.lodestar_time = weapons_get_dvar_int( "scr_lodestar_time", 7 );
|
||||
level.chopper_gunner_time = weapons_get_dvar_int( "scr_chopper_gunner_time", 7 );
|
||||
wait 1;
|
||||
#/
|
||||
}
|
||||
}
|
688
Multiplayer Core/patch_mp/maps/mp/_heatseekingmissile.gsc
Normal file
688
Multiplayer Core/patch_mp/maps/mp/_heatseekingmissile.gsc
Normal file
@ -0,0 +1,688 @@
|
||||
#include maps/mp/killstreaks/_airsupport;
|
||||
#include maps/mp/killstreaks/_helicopter;
|
||||
#include maps/mp/gametypes/_weapon_utils;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
precacherumble( "stinger_lock_rumble" );
|
||||
game[ "locking_on_sound" ] = "uin_alert_lockon_start";
|
||||
game[ "locked_on_sound" ] = "uin_alert_lockon";
|
||||
precachestring( &"MP_CANNOT_LOCKON_TO_TARGET" );
|
||||
thread onplayerconnect();
|
||||
level.fx_flare = loadfx( "vehicle/vexplosion/fx_heli_chaff" );
|
||||
/#
|
||||
setdvar( "scr_freelock", "0" );
|
||||
#/
|
||||
}
|
||||
|
||||
onplayerconnect()
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( "connecting", player );
|
||||
player thread onplayerspawned();
|
||||
}
|
||||
}
|
||||
|
||||
onplayerspawned()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
self clearirtarget();
|
||||
thread stingertoggleloop();
|
||||
self thread stingerfirednotify();
|
||||
}
|
||||
}
|
||||
|
||||
clearirtarget()
|
||||
{
|
||||
self notify( "stinger_irt_cleartarget" );
|
||||
self notify( "stop_lockon_sound" );
|
||||
self notify( "stop_locked_sound" );
|
||||
self.stingerlocksound = undefined;
|
||||
self stoprumble( "stinger_lock_rumble" );
|
||||
self.stingerlockstarttime = 0;
|
||||
self.stingerlockstarted = 0;
|
||||
self.stingerlockfinalized = 0;
|
||||
if ( isDefined( self.stingertarget ) )
|
||||
{
|
||||
lockingon( self.stingertarget, 0 );
|
||||
lockedon( self.stingertarget, 0 );
|
||||
}
|
||||
self.stingertarget = undefined;
|
||||
self weaponlockfree();
|
||||
self weaponlocktargettooclose( 0 );
|
||||
self weaponlocknoclearance( 0 );
|
||||
self stoplocalsound( game[ "locking_on_sound" ] );
|
||||
self stoplocalsound( game[ "locked_on_sound" ] );
|
||||
self destroylockoncanceledmessage();
|
||||
}
|
||||
|
||||
stingerfirednotify()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
while ( 1 )
|
||||
{
|
||||
self waittill( "missile_fire", missile, weap );
|
||||
if ( maps/mp/gametypes/_weapon_utils::isguidedrocketlauncherweapon( weap ) )
|
||||
{
|
||||
if ( isDefined( self.stingertarget ) && self.stingerlockfinalized )
|
||||
{
|
||||
self.stingertarget notify( "stinger_fired_at_me" );
|
||||
}
|
||||
level notify( "missile_fired" );
|
||||
self notify( "stinger_fired" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stingertoggleloop()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "weapon_change", weapon );
|
||||
while ( maps/mp/gametypes/_weapon_utils::isguidedrocketlauncherweapon( weapon ) )
|
||||
{
|
||||
abort = 0;
|
||||
while ( !self playerstingerads() )
|
||||
{
|
||||
wait 0,05;
|
||||
if ( !maps/mp/gametypes/_weapon_utils::isguidedrocketlauncherweapon( self getcurrentweapon() ) )
|
||||
{
|
||||
abort = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
if ( abort )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else self thread stingerirtloop();
|
||||
while ( self playerstingerads() )
|
||||
{
|
||||
wait 0,05;
|
||||
}
|
||||
self notify( "stinger_IRT_off" );
|
||||
self clearirtarget();
|
||||
weapon = self getcurrentweapon();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stingerirtloop()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self endon( "stinger_IRT_off" );
|
||||
locklength = self getlockonspeed();
|
||||
for ( ;; )
|
||||
{
|
||||
wait 0,05;
|
||||
if ( self.stingerlockfinalized )
|
||||
{
|
||||
passed = softsighttest();
|
||||
if ( !passed )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if ( !isstillvalidtarget( self.stingertarget ) )
|
||||
{
|
||||
self clearirtarget();
|
||||
continue;
|
||||
}
|
||||
else if ( !self.stingertarget.locked_on )
|
||||
{
|
||||
self.stingertarget notify( "missile_lock" );
|
||||
}
|
||||
lockingon( self.stingertarget, 0 );
|
||||
lockedon( self.stingertarget, 1 );
|
||||
thread looplocallocksound( game[ "locked_on_sound" ], 0,75 );
|
||||
continue;
|
||||
}
|
||||
else if ( self.stingerlockstarted )
|
||||
{
|
||||
if ( !isstillvalidtarget( self.stingertarget ) )
|
||||
{
|
||||
self clearirtarget();
|
||||
continue;
|
||||
}
|
||||
else lockingon( self.stingertarget, 1 );
|
||||
lockedon( self.stingertarget, 0 );
|
||||
passed = softsighttest();
|
||||
if ( !passed )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else timepassed = getTime() - self.stingerlockstarttime;
|
||||
if ( timepassed < locklength )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else /#
|
||||
assert( isDefined( self.stingertarget ) );
|
||||
#/
|
||||
self notify( "stop_lockon_sound" );
|
||||
self.stingerlockfinalized = 1;
|
||||
self weaponlockfinalize( self.stingertarget );
|
||||
continue;
|
||||
}
|
||||
else besttarget = self getbeststingertarget();
|
||||
if ( !isDefined( besttarget ) )
|
||||
{
|
||||
self destroylockoncanceledmessage();
|
||||
continue;
|
||||
}
|
||||
else if ( !self locksighttest( besttarget ) )
|
||||
{
|
||||
self destroylockoncanceledmessage();
|
||||
continue;
|
||||
}
|
||||
else if ( self locksighttest( besttarget ) && isDefined( besttarget.lockondelay ) && besttarget.lockondelay )
|
||||
{
|
||||
self displaylockoncanceledmessage();
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
self destroylockoncanceledmessage();
|
||||
initlockfield( besttarget );
|
||||
self.stingertarget = besttarget;
|
||||
self.stingerlockstarttime = getTime();
|
||||
self.stingerlockstarted = 1;
|
||||
self.stingerlostsightlinetime = 0;
|
||||
self thread looplocalseeksound( game[ "locking_on_sound" ], 0,6 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
destroylockoncanceledmessage()
|
||||
{
|
||||
if ( isDefined( self.lockoncanceledmessage ) )
|
||||
{
|
||||
self.lockoncanceledmessage destroy();
|
||||
}
|
||||
}
|
||||
|
||||
displaylockoncanceledmessage()
|
||||
{
|
||||
if ( isDefined( self.lockoncanceledmessage ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self.lockoncanceledmessage = newclienthudelem( self );
|
||||
self.lockoncanceledmessage.fontscale = 1,25;
|
||||
self.lockoncanceledmessage.x = 0;
|
||||
self.lockoncanceledmessage.y = 50;
|
||||
self.lockoncanceledmessage.alignx = "center";
|
||||
self.lockoncanceledmessage.aligny = "top";
|
||||
self.lockoncanceledmessage.horzalign = "center";
|
||||
self.lockoncanceledmessage.vertalign = "top";
|
||||
self.lockoncanceledmessage.foreground = 1;
|
||||
self.lockoncanceledmessage.hidewhendead = 0;
|
||||
self.lockoncanceledmessage.hidewheninmenu = 1;
|
||||
self.lockoncanceledmessage.archived = 0;
|
||||
self.lockoncanceledmessage.alpha = 1;
|
||||
self.lockoncanceledmessage settext( &"MP_CANNOT_LOCKON_TO_TARGET" );
|
||||
}
|
||||
|
||||
getbeststingertarget()
|
||||
{
|
||||
targetsall = target_getarray();
|
||||
targetsvalid = [];
|
||||
idx = 0;
|
||||
while ( idx < targetsall.size )
|
||||
{
|
||||
/#
|
||||
if ( getDvar( "scr_freelock" ) == "1" )
|
||||
{
|
||||
if ( self insidestingerreticlenolock( targetsall[ idx ] ) )
|
||||
{
|
||||
targetsvalid[ targetsvalid.size ] = targetsall[ idx ];
|
||||
}
|
||||
idx++;
|
||||
continue;
|
||||
#/
|
||||
}
|
||||
else if ( level.teambased )
|
||||
{
|
||||
if ( isDefined( targetsall[ idx ].team ) && targetsall[ idx ].team != self.team )
|
||||
{
|
||||
if ( self insidestingerreticlenolock( targetsall[ idx ] ) )
|
||||
{
|
||||
targetsvalid[ targetsvalid.size ] = targetsall[ idx ];
|
||||
}
|
||||
}
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( self insidestingerreticlenolock( targetsall[ idx ] ) )
|
||||
{
|
||||
if ( isDefined( targetsall[ idx ].owner ) && self != targetsall[ idx ].owner )
|
||||
{
|
||||
targetsvalid[ targetsvalid.size ] = targetsall[ idx ];
|
||||
}
|
||||
}
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
if ( targetsvalid.size == 0 )
|
||||
{
|
||||
return undefined;
|
||||
}
|
||||
chosenent = targetsvalid[ 0 ];
|
||||
if ( targetsvalid.size > 1 )
|
||||
{
|
||||
}
|
||||
return chosenent;
|
||||
}
|
||||
|
||||
insidestingerreticlenolock( target )
|
||||
{
|
||||
radius = self getlockonradius();
|
||||
return target_isincircle( target, self, 65, radius );
|
||||
}
|
||||
|
||||
insidestingerreticlelocked( target )
|
||||
{
|
||||
radius = self getlockonradius();
|
||||
return target_isincircle( target, self, 65, radius );
|
||||
}
|
||||
|
||||
isstillvalidtarget( ent )
|
||||
{
|
||||
if ( !isDefined( ent ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( !target_istarget( ent ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( !insidestingerreticlelocked( ent ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
playerstingerads()
|
||||
{
|
||||
return self playerads() == 1;
|
||||
}
|
||||
|
||||
looplocalseeksound( alias, interval )
|
||||
{
|
||||
self endon( "stop_lockon_sound" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
for ( ;; )
|
||||
{
|
||||
self playlocalsound( alias );
|
||||
self playrumbleonentity( "stinger_lock_rumble" );
|
||||
wait ( interval / 2 );
|
||||
}
|
||||
}
|
||||
|
||||
looplocallocksound( alias, interval )
|
||||
{
|
||||
self endon( "stop_locked_sound" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
if ( isDefined( self.stingerlocksound ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self.stingerlocksound = 1;
|
||||
for ( ;; )
|
||||
{
|
||||
self playlocalsound( alias );
|
||||
self playrumbleonentity( "stinger_lock_rumble" );
|
||||
wait ( interval / 6 );
|
||||
self playlocalsound( alias );
|
||||
self playrumbleonentity( "stinger_lock_rumble" );
|
||||
wait ( interval / 6 );
|
||||
self playlocalsound( alias );
|
||||
self playrumbleonentity( "stinger_lock_rumble" );
|
||||
wait ( interval / 6 );
|
||||
self stoprumble( "stinger_lock_rumble" );
|
||||
}
|
||||
self.stingerlocksound = undefined;
|
||||
}
|
||||
|
||||
locksighttest( target )
|
||||
{
|
||||
eyepos = self geteye();
|
||||
if ( !isDefined( target ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
passed = bullettracepassed( eyepos, target.origin, 0, target );
|
||||
if ( passed )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
front = target getpointinbounds( 1, 0, 0 );
|
||||
passed = bullettracepassed( eyepos, front, 0, target );
|
||||
if ( passed )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
back = target getpointinbounds( -1, 0, 0 );
|
||||
passed = bullettracepassed( eyepos, back, 0, target );
|
||||
if ( passed )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
softsighttest()
|
||||
{
|
||||
lost_sight_limit = 500;
|
||||
if ( self locksighttest( self.stingertarget ) )
|
||||
{
|
||||
self.stingerlostsightlinetime = 0;
|
||||
return 1;
|
||||
}
|
||||
if ( self.stingerlostsightlinetime == 0 )
|
||||
{
|
||||
self.stingerlostsightlinetime = getTime();
|
||||
}
|
||||
timepassed = getTime() - self.stingerlostsightlinetime;
|
||||
if ( timepassed >= lost_sight_limit )
|
||||
{
|
||||
self clearirtarget();
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
initlockfield( target )
|
||||
{
|
||||
if ( isDefined( target.locking_on ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
target.locking_on = 0;
|
||||
target.locked_on = 0;
|
||||
}
|
||||
|
||||
lockingon( target, lock )
|
||||
{
|
||||
/#
|
||||
assert( isDefined( target.locking_on ) );
|
||||
#/
|
||||
clientnum = self getentitynumber();
|
||||
if ( lock )
|
||||
{
|
||||
target notify( "locking on" );
|
||||
target.locking_on |= 1 << clientnum;
|
||||
self thread watchclearlockingon( target, clientnum );
|
||||
}
|
||||
else
|
||||
{
|
||||
self notify( "locking_on_cleared" );
|
||||
target.locking_on &= 1 << clientnum;
|
||||
}
|
||||
}
|
||||
|
||||
watchclearlockingon( target, clientnum )
|
||||
{
|
||||
target endon( "death" );
|
||||
self endon( "locking_on_cleared" );
|
||||
self waittill_any( "death", "disconnect" );
|
||||
target.locking_on &= 1 << clientnum;
|
||||
}
|
||||
|
||||
lockedon( target, lock )
|
||||
{
|
||||
/#
|
||||
assert( isDefined( target.locked_on ) );
|
||||
#/
|
||||
clientnum = self getentitynumber();
|
||||
if ( lock )
|
||||
{
|
||||
target.locked_on |= 1 << clientnum;
|
||||
self thread watchclearlockedon( target, clientnum );
|
||||
}
|
||||
else
|
||||
{
|
||||
self notify( "locked_on_cleared" );
|
||||
target.locked_on &= 1 << clientnum;
|
||||
}
|
||||
}
|
||||
|
||||
watchclearlockedon( target, clientnum )
|
||||
{
|
||||
self endon( "locked_on_cleared" );
|
||||
self waittill_any( "death", "disconnect" );
|
||||
if ( isDefined( target ) )
|
||||
{
|
||||
target.locked_on &= 1 << clientnum;
|
||||
}
|
||||
}
|
||||
|
||||
missiletarget_lockonmonitor( player, endon1, endon2 )
|
||||
{
|
||||
self endon( "death" );
|
||||
if ( isDefined( endon1 ) )
|
||||
{
|
||||
self endon( endon1 );
|
||||
}
|
||||
if ( isDefined( endon2 ) )
|
||||
{
|
||||
self endon( endon2 );
|
||||
}
|
||||
for ( ;; )
|
||||
{
|
||||
if ( target_istarget( self ) )
|
||||
{
|
||||
}
|
||||
wait 0,1;
|
||||
}
|
||||
}
|
||||
|
||||
_incomingmissile( missile )
|
||||
{
|
||||
if ( !isDefined( self.incoming_missile ) )
|
||||
{
|
||||
self.incoming_missile = 0;
|
||||
}
|
||||
self.incoming_missile++;
|
||||
self thread _incomingmissiletracker( missile );
|
||||
}
|
||||
|
||||
_incomingmissiletracker( missile )
|
||||
{
|
||||
self endon( "death" );
|
||||
missile waittill( "death" );
|
||||
self.incoming_missile--;
|
||||
|
||||
/#
|
||||
assert( self.incoming_missile >= 0 );
|
||||
#/
|
||||
}
|
||||
|
||||
missiletarget_ismissileincoming()
|
||||
{
|
||||
if ( !isDefined( self.incoming_missile ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( self.incoming_missile )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
missiletarget_handleincomingmissile( responsefunc, endon1, endon2 )
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
self endon( "death" );
|
||||
if ( isDefined( endon1 ) )
|
||||
{
|
||||
self endon( endon1 );
|
||||
}
|
||||
if ( isDefined( endon2 ) )
|
||||
{
|
||||
self endon( endon2 );
|
||||
}
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "stinger_fired_at_me", missile, weap, attacker );
|
||||
_incomingmissile( missile );
|
||||
if ( isDefined( responsefunc ) )
|
||||
{
|
||||
[[ responsefunc ]]( missile, attacker, weap, endon1, endon2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
missiletarget_proximitydetonateincomingmissile( endon1, endon2 )
|
||||
{
|
||||
missiletarget_handleincomingmissile( ::missiletarget_proximitydetonate, endon1, endon2 );
|
||||
}
|
||||
|
||||
_missiledetonate( attacker, weapon )
|
||||
{
|
||||
self endon( "death" );
|
||||
radiusdamage( self.origin, 500, 600, 600, attacker, undefined, weapon );
|
||||
wait 0,05;
|
||||
self detonate();
|
||||
wait 0,05;
|
||||
self delete();
|
||||
}
|
||||
|
||||
missiletarget_proximitydetonate( missile, attacker, weapon, endon1, endon2 )
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
missile endon( "death" );
|
||||
if ( isDefined( endon1 ) )
|
||||
{
|
||||
self endon( endon1 );
|
||||
}
|
||||
if ( isDefined( endon2 ) )
|
||||
{
|
||||
self endon( endon2 );
|
||||
}
|
||||
mindist = distance( missile.origin, self.origin );
|
||||
lastcenter = self.origin;
|
||||
missile missile_settarget( self );
|
||||
for ( ;; )
|
||||
{
|
||||
if ( !isDefined( self ) )
|
||||
{
|
||||
center = lastcenter;
|
||||
}
|
||||
else
|
||||
{
|
||||
center = self.origin;
|
||||
}
|
||||
lastcenter = center;
|
||||
curdist = distance( missile.origin, center );
|
||||
if ( curdist < 3500 && isDefined( self.numflares ) && self.numflares > 0 )
|
||||
{
|
||||
self.numflares--;
|
||||
|
||||
self thread missiletarget_playflarefx();
|
||||
self maps/mp/killstreaks/_helicopter::trackassists( attacker, 0, 1 );
|
||||
newtarget = self missiletarget_deployflares( missile.origin, missile.angles );
|
||||
missile missile_settarget( newtarget );
|
||||
missiletarget = newtarget;
|
||||
return;
|
||||
}
|
||||
if ( curdist < mindist )
|
||||
{
|
||||
mindist = curdist;
|
||||
}
|
||||
if ( curdist > mindist )
|
||||
{
|
||||
if ( curdist > 500 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
missile thread _missiledetonate( attacker, weapon );
|
||||
}
|
||||
wait 0,05;
|
||||
}
|
||||
}
|
||||
|
||||
missiletarget_playflarefx()
|
||||
{
|
||||
if ( !isDefined( self ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
flare_fx = level.fx_flare;
|
||||
if ( isDefined( self.fx_flare ) )
|
||||
{
|
||||
flare_fx = self.fx_flare;
|
||||
}
|
||||
if ( isDefined( self.flare_ent ) )
|
||||
{
|
||||
playfxontag( flare_fx, self.flare_ent, "tag_origin" );
|
||||
}
|
||||
else
|
||||
{
|
||||
playfxontag( flare_fx, self, "tag_origin" );
|
||||
}
|
||||
if ( isDefined( self.owner ) )
|
||||
{
|
||||
self playsoundtoplayer( "veh_huey_chaff_drop_plr", self.owner );
|
||||
}
|
||||
self playsound( "veh_huey_chaff_explo_npc" );
|
||||
}
|
||||
|
||||
missiletarget_deployflares( origin, angles )
|
||||
{
|
||||
vec_toforward = anglesToForward( self.angles );
|
||||
vec_toright = anglesToRight( self.angles );
|
||||
vec_tomissileforward = anglesToForward( angles );
|
||||
delta = self.origin - origin;
|
||||
dot = vectordot( vec_tomissileforward, vec_toright );
|
||||
sign = 1;
|
||||
if ( dot > 0 )
|
||||
{
|
||||
sign = -1;
|
||||
}
|
||||
flare_dir = vectornormalize( vectorScale( vec_toforward, -0,5 ) + vectorScale( vec_toright, sign ) );
|
||||
velocity = vectorScale( flare_dir, randomintrange( 200, 400 ) );
|
||||
velocity = ( velocity[ 0 ], velocity[ 1 ], velocity[ 2 ] - randomintrange( 10, 100 ) );
|
||||
flareorigin = self.origin;
|
||||
flareorigin += vectorScale( flare_dir, randomintrange( 500, 700 ) );
|
||||
flareorigin += vectorScale( ( 1, 0, 0 ), 500 );
|
||||
if ( isDefined( self.flareoffset ) )
|
||||
{
|
||||
flareorigin += self.flareoffset;
|
||||
}
|
||||
flareobject = spawn( "script_origin", flareorigin );
|
||||
flareobject.angles = self.angles;
|
||||
flareobject setmodel( "tag_origin" );
|
||||
flareobject movegravity( velocity, 5 );
|
||||
flareobject thread deleteaftertime( 5 );
|
||||
self thread debug_tracker( flareobject );
|
||||
return flareobject;
|
||||
}
|
||||
|
||||
debug_tracker( target )
|
||||
{
|
||||
target endon( "death" );
|
||||
while ( 1 )
|
||||
{
|
||||
maps/mp/killstreaks/_airsupport::debug_sphere( target.origin, 10, ( 1, 0, 0 ), 1, 1 );
|
||||
wait 0,05;
|
||||
}
|
||||
}
|
407
Multiplayer Core/patch_mp/maps/mp/_interactive_objects.gsc
Normal file
407
Multiplayer Core/patch_mp/maps/mp/_interactive_objects.gsc
Normal file
@ -0,0 +1,407 @@
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level.barrelexplodingthisframe = 0;
|
||||
qbarrels = 0;
|
||||
all_barrels = [];
|
||||
barrels = getentarray( "explodable_barrel", "targetname" );
|
||||
while ( isDefined( barrels ) && barrels.size > 0 )
|
||||
{
|
||||
qbarrels = 1;
|
||||
i = 0;
|
||||
while ( i < barrels.size )
|
||||
{
|
||||
all_barrels[ all_barrels.size ] = barrels[ i ];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
barrels = getentarray( "explodable_barrel", "script_noteworthy" );
|
||||
while ( isDefined( barrels ) && barrels.size > 0 )
|
||||
{
|
||||
qbarrels = 1;
|
||||
i = 0;
|
||||
while ( i < barrels.size )
|
||||
{
|
||||
all_barrels[ all_barrels.size ] = barrels[ i ];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if ( qbarrels )
|
||||
{
|
||||
precachemodel( "global_explosive_barrel" );
|
||||
level.barrelburn = 100;
|
||||
level.barrelhealth = 250;
|
||||
level.barrelingsound = "exp_redbarrel_ignition";
|
||||
level.barrelexpsound = "exp_redbarrel";
|
||||
level.breakables_fx[ "barrel" ][ "burn_start" ] = loadfx( "destructibles/fx_barrel_ignite" );
|
||||
level.breakables_fx[ "barrel" ][ "burn" ] = loadfx( "destructibles/fx_barrel_fire_top" );
|
||||
level.breakables_fx[ "barrel" ][ "explode" ] = loadfx( "destructibles/fx_dest_barrelexp" );
|
||||
array_thread( all_barrels, ::explodable_barrel_think );
|
||||
}
|
||||
qcrates = 0;
|
||||
all_crates = [];
|
||||
crates = getentarray( "flammable_crate", "targetname" );
|
||||
while ( isDefined( crates ) && crates.size > 0 )
|
||||
{
|
||||
qcrates = 1;
|
||||
i = 0;
|
||||
while ( i < crates.size )
|
||||
{
|
||||
all_crates[ all_crates.size ] = crates[ i ];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
crates = getentarray( "flammable_crate", "script_noteworthy" );
|
||||
while ( isDefined( crates ) && crates.size > 0 )
|
||||
{
|
||||
qcrates = 1;
|
||||
i = 0;
|
||||
while ( i < crates.size )
|
||||
{
|
||||
all_crates[ all_crates.size ] = crates[ i ];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if ( qcrates )
|
||||
{
|
||||
precachemodel( "global_flammable_crate_jap_piece01_d" );
|
||||
level.crateburn = 100;
|
||||
level.cratehealth = 200;
|
||||
level.breakables_fx[ "ammo_crate" ][ "burn_start" ] = loadfx( "destructibles/fx_ammobox_ignite" );
|
||||
level.breakables_fx[ "ammo_crate" ][ "burn" ] = loadfx( "destructibles/fx_ammobox_fire_top" );
|
||||
level.breakables_fx[ "ammo_crate" ][ "explode" ] = loadfx( "destructibles/fx_ammoboxExp" );
|
||||
level.crateignsound = "Ignition_ammocrate";
|
||||
level.crateexpsound = "Explo_ammocrate";
|
||||
array_thread( all_crates, ::flammable_crate_think );
|
||||
}
|
||||
if ( !qbarrels && !qcrates )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
explodable_barrel_think()
|
||||
{
|
||||
if ( self.classname != "script_model" )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self endon( "exploding" );
|
||||
self breakable_clip();
|
||||
self.health = level.barrelhealth;
|
||||
self setcandamage( 1 );
|
||||
self.targetname = "explodable_barrel";
|
||||
if ( sessionmodeiszombiesgame() )
|
||||
{
|
||||
self.removeexplodable = 1;
|
||||
}
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "damage", amount, attacker, direction_vec, p, type );
|
||||
/#
|
||||
println( "BARRELDAMAGE: " + type );
|
||||
#/
|
||||
if ( type == "MOD_MELEE" || type == "MOD_IMPACT" )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isDefined( self.script_requires_player ) && self.script_requires_player && !isplayer( attacker ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isDefined( self.script_selfisattacker ) && self.script_selfisattacker )
|
||||
{
|
||||
self.damageowner = self;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.damageowner = attacker;
|
||||
}
|
||||
self.health -= amount;
|
||||
if ( self.health <= level.barrelburn )
|
||||
{
|
||||
self thread explodable_barrel_burn();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
explodable_barrel_burn()
|
||||
{
|
||||
count = 0;
|
||||
startedfx = 0;
|
||||
up = anglesToUp( vectorScale( ( 0, 0, 1 ), 90 ) );
|
||||
worldup = anglesToUp( vectorScale( ( 0, 0, 1 ), 90 ) );
|
||||
dot = vectordot( up, worldup );
|
||||
offset1 = ( 0, 0, 1 );
|
||||
offset2 = up * vectorScale( ( 0, 0, 1 ), 44 );
|
||||
if ( dot < 0,5 )
|
||||
{
|
||||
offset1 = ( up * vectorScale( ( 0, 0, 1 ), 22 ) ) - vectorScale( ( 0, 0, 1 ), 30 );
|
||||
offset2 = ( up * vectorScale( ( 0, 0, 1 ), 22 ) ) + vectorScale( ( 0, 0, 1 ), 14 );
|
||||
}
|
||||
while ( self.health > 0 )
|
||||
{
|
||||
if ( !startedfx )
|
||||
{
|
||||
playfx( level.breakables_fx[ "barrel" ][ "burn_start" ], self.origin + offset1 );
|
||||
level thread play_sound_in_space( level.barrelingsound, self.origin );
|
||||
startedfx = 1;
|
||||
}
|
||||
if ( count > 20 )
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
playfx( level.breakables_fx[ "barrel" ][ "burn" ], self.origin + offset2 );
|
||||
self playloopsound( "barrel_fuse" );
|
||||
if ( count == 0 )
|
||||
{
|
||||
self.health -= 10 + randomint( 10 );
|
||||
}
|
||||
count++;
|
||||
wait 0,05;
|
||||
}
|
||||
level notify( "explosion_started" );
|
||||
self thread explodable_barrel_explode();
|
||||
}
|
||||
|
||||
explodable_barrel_explode()
|
||||
{
|
||||
self notify( "exploding" );
|
||||
self death_notify_wrapper();
|
||||
up = anglesToUp( vectorScale( ( 0, 0, 1 ), 90 ) );
|
||||
worldup = anglesToUp( vectorScale( ( 0, 0, 1 ), 90 ) );
|
||||
dot = vectordot( up, worldup );
|
||||
offset = ( 0, 0, 1 );
|
||||
if ( dot < 0,5 )
|
||||
{
|
||||
start = self.origin + vectorScale( up, 22 );
|
||||
trace = physicstrace( start, start + vectorScale( ( 0, 0, 1 ), 64 ) );
|
||||
end = trace[ "position" ];
|
||||
offset = end - self.origin;
|
||||
}
|
||||
offset += vectorScale( ( 0, 0, 1 ), 4 );
|
||||
mindamage = 1;
|
||||
maxdamage = 250;
|
||||
blastradius = 250;
|
||||
level thread play_sound_in_space( level.barrelexpsound, self.origin );
|
||||
playfx( level.breakables_fx[ "barrel" ][ "explode" ], self.origin + offset );
|
||||
physicsexplosionsphere( self.origin + offset, 100, 80, 1, maxdamage, mindamage );
|
||||
level.barrelexplodingthisframe = 1;
|
||||
if ( isDefined( self.remove ) )
|
||||
{
|
||||
self.remove delete();
|
||||
}
|
||||
if ( isDefined( self.radius ) )
|
||||
{
|
||||
blastradius = self.radius;
|
||||
}
|
||||
self radiusdamage( self.origin + vectorScale( ( 0, 0, 1 ), 56 ), blastradius, maxdamage, mindamage, self.damageowner );
|
||||
attacker = undefined;
|
||||
if ( isDefined( self.damageowner ) )
|
||||
{
|
||||
attacker = self.damageowner;
|
||||
}
|
||||
level.lastexplodingbarrel[ "time" ] = getTime();
|
||||
level.lastexplodingbarrel[ "origin" ] = self.origin + vectorScale( ( 0, 0, 1 ), 30 );
|
||||
if ( isDefined( self.removeexplodable ) )
|
||||
{
|
||||
self hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
self setmodel( "global_explosive_barrel" );
|
||||
}
|
||||
if ( dot < 0,5 )
|
||||
{
|
||||
start = self.origin + vectorScale( up, 22 );
|
||||
trace = physicstrace( start, start + vectorScale( ( 0, 0, 1 ), 64 ) );
|
||||
pos = trace[ "position" ];
|
||||
self.origin = pos;
|
||||
self.angles += vectorScale( ( 0, 0, 1 ), 90 );
|
||||
}
|
||||
wait 0,05;
|
||||
level.barrelexplodingthisframe = 0;
|
||||
}
|
||||
|
||||
flammable_crate_think()
|
||||
{
|
||||
if ( self.classname != "script_model" )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self endon( "exploding" );
|
||||
self breakable_clip();
|
||||
self.health = level.cratehealth;
|
||||
self setcandamage( 1 );
|
||||
for ( ;; )
|
||||
{
|
||||
self waittill( "damage", amount, attacker, direction_vec, p, type );
|
||||
if ( isDefined( self.script_requires_player ) && self.script_requires_player && !isplayer( attacker ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isDefined( self.script_selfisattacker ) && self.script_selfisattacker )
|
||||
{
|
||||
self.damageowner = self;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.damageowner = attacker;
|
||||
}
|
||||
if ( level.barrelexplodingthisframe )
|
||||
{
|
||||
wait randomfloat( 1 );
|
||||
}
|
||||
self.health -= amount;
|
||||
if ( self.health <= level.crateburn )
|
||||
{
|
||||
self thread flammable_crate_burn();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flammable_crate_burn()
|
||||
{
|
||||
count = 0;
|
||||
startedfx = 0;
|
||||
up = anglesToUp( vectorScale( ( 0, 0, 1 ), 90 ) );
|
||||
worldup = anglesToUp( vectorScale( ( 0, 0, 1 ), 90 ) );
|
||||
dot = vectordot( up, worldup );
|
||||
offset1 = ( 0, 0, 1 );
|
||||
offset2 = up * vectorScale( ( 0, 0, 1 ), 44 );
|
||||
if ( dot < 0,5 )
|
||||
{
|
||||
offset1 = ( up * vectorScale( ( 0, 0, 1 ), 22 ) ) - vectorScale( ( 0, 0, 1 ), 30 );
|
||||
offset2 = ( up * vectorScale( ( 0, 0, 1 ), 22 ) ) + vectorScale( ( 0, 0, 1 ), 14 );
|
||||
}
|
||||
while ( self.health > 0 )
|
||||
{
|
||||
if ( !startedfx )
|
||||
{
|
||||
playfx( level.breakables_fx[ "ammo_crate" ][ "burn_start" ], self.origin );
|
||||
level thread play_sound_in_space( level.crateignsound, self.origin );
|
||||
startedfx = 1;
|
||||
}
|
||||
if ( count > 20 )
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
playfx( level.breakables_fx[ "ammo_crate" ][ "burn" ], self.origin );
|
||||
if ( count == 0 )
|
||||
{
|
||||
self.health -= 10 + randomint( 10 );
|
||||
}
|
||||
count++;
|
||||
wait 0,05;
|
||||
}
|
||||
self thread flammable_crate_explode();
|
||||
}
|
||||
|
||||
flammable_crate_explode()
|
||||
{
|
||||
self notify( "exploding" );
|
||||
self death_notify_wrapper();
|
||||
up = anglesToUp( vectorScale( ( 0, 0, 1 ), 90 ) );
|
||||
worldup = anglesToUp( vectorScale( ( 0, 0, 1 ), 90 ) );
|
||||
dot = vectordot( up, worldup );
|
||||
offset = ( 0, 0, 1 );
|
||||
if ( dot < 0,5 )
|
||||
{
|
||||
start = self.origin + vectorScale( up, 22 );
|
||||
trace = physicstrace( start, start + vectorScale( ( 0, 0, 1 ), 64 ) );
|
||||
end = trace[ "position" ];
|
||||
offset = end - self.origin;
|
||||
}
|
||||
offset += vectorScale( ( 0, 0, 1 ), 4 );
|
||||
mindamage = 1;
|
||||
maxdamage = 250;
|
||||
blastradius = 250;
|
||||
level thread play_sound_in_space( level.crateexpsound, self.origin );
|
||||
playfx( level.breakables_fx[ "ammo_crate" ][ "explode" ], self.origin );
|
||||
physicsexplosionsphere( self.origin + offset, 100, 80, 1, maxdamage, mindamage );
|
||||
level.barrelexplodingthisframe = 1;
|
||||
if ( isDefined( self.remove ) )
|
||||
{
|
||||
self.remove delete();
|
||||
}
|
||||
if ( isDefined( self.radius ) )
|
||||
{
|
||||
blastradius = self.radius;
|
||||
}
|
||||
attacker = undefined;
|
||||
if ( isDefined( self.damageowner ) )
|
||||
{
|
||||
attacker = self.damageowner;
|
||||
}
|
||||
self radiusdamage( self.origin + vectorScale( ( 0, 0, 1 ), 30 ), blastradius, maxdamage, mindamage, attacker );
|
||||
self setmodel( "global_flammable_crate_jap_piece01_d" );
|
||||
if ( dot < 0,5 )
|
||||
{
|
||||
start = self.origin + vectorScale( up, 22 );
|
||||
trace = physicstrace( start, start + vectorScale( ( 0, 0, 1 ), 64 ) );
|
||||
pos = trace[ "position" ];
|
||||
self.origin = pos;
|
||||
self.angles += vectorScale( ( 0, 0, 1 ), 90 );
|
||||
}
|
||||
wait 0,05;
|
||||
level.barrelexplodingthisframe = 0;
|
||||
}
|
||||
|
||||
breakable_clip()
|
||||
{
|
||||
if ( isDefined( self.target ) )
|
||||
{
|
||||
targ = getent( self.target, "targetname" );
|
||||
if ( targ.classname == "script_brushmodel" )
|
||||
{
|
||||
self.remove = targ;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ( isDefined( level.breakables_clip ) && level.breakables_clip.size > 0 )
|
||||
{
|
||||
self.remove = getclosestent( self.origin, level.breakables_clip );
|
||||
}
|
||||
if ( isDefined( self.remove ) )
|
||||
{
|
||||
arrayremovevalue( level.breakables_clip, self.remove );
|
||||
}
|
||||
}
|
||||
|
||||
getclosestent( org, array )
|
||||
{
|
||||
if ( array.size < 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
dist = 256;
|
||||
ent = undefined;
|
||||
i = 0;
|
||||
while ( i < array.size )
|
||||
{
|
||||
newdist = distance( array[ i ] getorigin(), org );
|
||||
if ( newdist >= dist )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
dist = newdist;
|
||||
ent = array[ i ];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return ent;
|
||||
}
|
537
Multiplayer Core/patch_mp/maps/mp/_load.gsc
Normal file
537
Multiplayer Core/patch_mp/maps/mp/_load.gsc
Normal file
@ -0,0 +1,537 @@
|
||||
#include maps/mp/gametypes/_spawnlogic;
|
||||
#include maps/mp/animscripts/traverse/shared;
|
||||
#include maps/mp/animscripts/utility;
|
||||
#include maps/mp/_load;
|
||||
#include maps/mp/_createfx;
|
||||
#include maps/mp/_music;
|
||||
#include maps/mp/_busing;
|
||||
#include maps/mp/_script_gen;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
|
||||
main( bscriptgened, bcsvgened, bsgenabled )
|
||||
{
|
||||
if ( !isDefined( level.script_gen_dump_reasons ) )
|
||||
{
|
||||
level.script_gen_dump_reasons = [];
|
||||
}
|
||||
if ( !isDefined( bsgenabled ) )
|
||||
{
|
||||
level.script_gen_dump_reasons[ level.script_gen_dump_reasons.size ] = "First run";
|
||||
}
|
||||
if ( !isDefined( bcsvgened ) )
|
||||
{
|
||||
bcsvgened = 0;
|
||||
}
|
||||
level.bcsvgened = bcsvgened;
|
||||
if ( !isDefined( bscriptgened ) )
|
||||
{
|
||||
bscriptgened = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bscriptgened = 1;
|
||||
}
|
||||
level.bscriptgened = bscriptgened;
|
||||
level._loadstarted = 1;
|
||||
struct_class_init();
|
||||
level.clientscripts = getDvar( "cg_usingClientScripts" ) != "";
|
||||
level._client_exploders = [];
|
||||
level._client_exploder_ids = [];
|
||||
if ( !isDefined( level.flag ) )
|
||||
{
|
||||
level.flag = [];
|
||||
level.flags_lock = [];
|
||||
}
|
||||
if ( !isDefined( level.timeofday ) )
|
||||
{
|
||||
level.timeofday = "day";
|
||||
}
|
||||
flag_init( "scriptgen_done" );
|
||||
level.script_gen_dump_reasons = [];
|
||||
if ( !isDefined( level.script_gen_dump ) )
|
||||
{
|
||||
level.script_gen_dump = [];
|
||||
level.script_gen_dump_reasons[ 0 ] = "First run";
|
||||
}
|
||||
if ( !isDefined( level.script_gen_dump2 ) )
|
||||
{
|
||||
level.script_gen_dump2 = [];
|
||||
}
|
||||
if ( isDefined( level.createfxent ) )
|
||||
{
|
||||
script_gen_dump_addline( "maps\\mp\\createfx\\" + level.script + "_fx::main();", level.script + "_fx" );
|
||||
}
|
||||
while ( isDefined( level.script_gen_dump_preload ) )
|
||||
{
|
||||
i = 0;
|
||||
while ( i < level.script_gen_dump_preload.size )
|
||||
{
|
||||
script_gen_dump_addline( level.script_gen_dump_preload[ i ].string, level.script_gen_dump_preload[ i ].signature );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if ( getDvar( "scr_RequiredMapAspectratio" ) == "" )
|
||||
{
|
||||
setdvar( "scr_RequiredMapAspectratio", "1" );
|
||||
}
|
||||
setdvar( "r_waterFogTest", 0 );
|
||||
setdvar( "tu6_player_shallowWaterHeight", "0.0" );
|
||||
precacherumble( "reload_small" );
|
||||
precacherumble( "reload_medium" );
|
||||
precacherumble( "reload_large" );
|
||||
precacherumble( "reload_clipin" );
|
||||
precacherumble( "reload_clipout" );
|
||||
precacherumble( "reload_rechamber" );
|
||||
precacherumble( "pullout_small" );
|
||||
precacherumble( "buzz_high" );
|
||||
precacherumble( "riotshield_impact" );
|
||||
registerclientsys( "levelNotify" );
|
||||
level.aitriggerspawnflags = getaitriggerflags();
|
||||
level.vehicletriggerspawnflags = getvehicletriggerflags();
|
||||
level.physicstracemaskphysics = 1;
|
||||
level.physicstracemaskvehicle = 2;
|
||||
level.physicstracemaskwater = 4;
|
||||
level.physicstracemaskclip = 8;
|
||||
level.physicstracecontentsvehicleclip = 16;
|
||||
level.createfx_enabled = getDvar( "createfx" ) != "";
|
||||
if ( !sessionmodeiszombiesgame() )
|
||||
{
|
||||
thread maps/mp/gametypes/_spawning::init();
|
||||
thread maps/mp/gametypes/_tweakables::init();
|
||||
thread maps/mp/_destructible::init();
|
||||
thread maps/mp/_riotshield::register();
|
||||
thread maps/mp/_vehicles::init();
|
||||
thread maps/mp/killstreaks/_dogs::init();
|
||||
thread maps/mp/killstreaks/_ai_tank::register();
|
||||
thread maps/mp/killstreaks/_rcbomb::register();
|
||||
thread maps/mp/killstreaks/_helicopter_guard::register();
|
||||
thread maps/mp/_trophy_system::register();
|
||||
thread maps/mp/_proximity_grenade::register();
|
||||
maps/mp/_audio::init();
|
||||
thread maps/mp/_busing::businit();
|
||||
thread maps/mp/_music::music_init();
|
||||
thread maps/mp/_fxanim::init();
|
||||
}
|
||||
else
|
||||
{
|
||||
level thread start_intro_screen_zm();
|
||||
thread maps/mp/_interactive_objects::init();
|
||||
maps/mp/_audio::init();
|
||||
thread maps/mp/_busing::businit();
|
||||
thread maps/mp/_music::music_init();
|
||||
thread maps/mp/_fxanim::init();
|
||||
thread maps/mp/_serverfaceanim_mp::init();
|
||||
if ( level.createfx_enabled )
|
||||
{
|
||||
setinitialplayersconnected();
|
||||
}
|
||||
}
|
||||
visionsetnight( "default_night" );
|
||||
setup_traversals();
|
||||
maps/mp/_art::main();
|
||||
setupexploders();
|
||||
parse_structs();
|
||||
if ( sessionmodeiszombiesgame() )
|
||||
{
|
||||
thread footsteps();
|
||||
}
|
||||
/#
|
||||
level thread level_notify_listener();
|
||||
level thread client_notify_listener();
|
||||
#/
|
||||
thread maps/mp/_createfx::fx_init();
|
||||
if ( level.createfx_enabled )
|
||||
{
|
||||
calculate_map_center();
|
||||
maps/mp/_createfx::createfx();
|
||||
}
|
||||
if ( getDvar( #"F7B30924" ) == "1" )
|
||||
{
|
||||
maps/mp/_global_fx::main();
|
||||
level waittill( "eternity" );
|
||||
}
|
||||
thread maps/mp/_global_fx::main();
|
||||
maps/mp/_demo::init();
|
||||
if ( !sessionmodeiszombiesgame() )
|
||||
{
|
||||
thread maps/mp/_development_dvars::init();
|
||||
}
|
||||
p = 0;
|
||||
while ( p < 6 )
|
||||
{
|
||||
switch( p )
|
||||
{
|
||||
case 0:
|
||||
triggertype = "trigger_multiple";
|
||||
break;
|
||||
case 1:
|
||||
triggertype = "trigger_once";
|
||||
break;
|
||||
case 2:
|
||||
triggertype = "trigger_use";
|
||||
break;
|
||||
case 3:
|
||||
triggertype = "trigger_radius";
|
||||
break;
|
||||
case 4:
|
||||
triggertype = "trigger_lookat";
|
||||
break;
|
||||
default:
|
||||
/#
|
||||
assert( p == 5 );
|
||||
#/
|
||||
triggertype = "trigger_damage";
|
||||
break;
|
||||
}
|
||||
triggers = getentarray( triggertype, "classname" );
|
||||
i = 0;
|
||||
while ( i < triggers.size )
|
||||
{
|
||||
if ( isDefined( triggers[ i ].script_prefab_exploder ) )
|
||||
{
|
||||
triggers[ i ].script_exploder = triggers[ i ].script_prefab_exploder;
|
||||
}
|
||||
if ( isDefined( triggers[ i ].script_exploder ) )
|
||||
{
|
||||
level thread maps/mp/_load::exploder_load( triggers[ i ] );
|
||||
}
|
||||
i++;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
level_notify_listener()
|
||||
{
|
||||
while ( 1 )
|
||||
{
|
||||
val = getDvar( "level_notify" );
|
||||
if ( val != "" )
|
||||
{
|
||||
level notify( val );
|
||||
setdvar( "level_notify", "" );
|
||||
}
|
||||
wait 0,2;
|
||||
}
|
||||
}
|
||||
|
||||
client_notify_listener()
|
||||
{
|
||||
while ( 1 )
|
||||
{
|
||||
val = getDvar( "client_notify" );
|
||||
if ( val != "" )
|
||||
{
|
||||
clientnotify( val );
|
||||
setdvar( "client_notify", "" );
|
||||
}
|
||||
wait 0,2;
|
||||
}
|
||||
}
|
||||
|
||||
footsteps()
|
||||
{
|
||||
maps/mp/animscripts/utility::setfootstepeffect( "asphalt", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps/mp/animscripts/utility::setfootstepeffect( "brick", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps/mp/animscripts/utility::setfootstepeffect( "carpet", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps/mp/animscripts/utility::setfootstepeffect( "cloth", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps/mp/animscripts/utility::setfootstepeffect( "concrete", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps/mp/animscripts/utility::setfootstepeffect( "dirt", loadfx( "bio/player/fx_footstep_sand" ) );
|
||||
maps/mp/animscripts/utility::setfootstepeffect( "foliage", loadfx( "bio/player/fx_footstep_sand" ) );
|
||||
maps/mp/animscripts/utility::setfootstepeffect( "gravel", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps/mp/animscripts/utility::setfootstepeffect( "grass", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps/mp/animscripts/utility::setfootstepeffect( "metal", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps/mp/animscripts/utility::setfootstepeffect( "mud", loadfx( "bio/player/fx_footstep_mud" ) );
|
||||
maps/mp/animscripts/utility::setfootstepeffect( "paper", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps/mp/animscripts/utility::setfootstepeffect( "plaster", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps/mp/animscripts/utility::setfootstepeffect( "rock", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps/mp/animscripts/utility::setfootstepeffect( "sand", loadfx( "bio/player/fx_footstep_sand" ) );
|
||||
maps/mp/animscripts/utility::setfootstepeffect( "water", loadfx( "bio/player/fx_footstep_water" ) );
|
||||
maps/mp/animscripts/utility::setfootstepeffect( "wood", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
}
|
||||
|
||||
parse_structs()
|
||||
{
|
||||
i = 0;
|
||||
while ( i < level.struct.size )
|
||||
{
|
||||
if ( isDefined( level.struct[ i ].targetname ) )
|
||||
{
|
||||
if ( level.struct[ i ].targetname == "flak_fire_fx" )
|
||||
{
|
||||
level._effect[ "flak20_fire_fx" ] = loadfx( "weapon/tracer/fx_tracer_flak_single_noExp" );
|
||||
level._effect[ "flak38_fire_fx" ] = loadfx( "weapon/tracer/fx_tracer_quad_20mm_Flak38_noExp" );
|
||||
level._effect[ "flak_cloudflash_night" ] = loadfx( "weapon/flak/fx_flak_cloudflash_night" );
|
||||
level._effect[ "flak_burst_single" ] = loadfx( "weapon/flak/fx_flak_single_day_dist" );
|
||||
}
|
||||
if ( level.struct[ i ].targetname == "fake_fire_fx" )
|
||||
{
|
||||
level._effect[ "distant_muzzleflash" ] = loadfx( "weapon/muzzleflashes/heavy" );
|
||||
}
|
||||
if ( level.struct[ i ].targetname == "spotlight_fx" )
|
||||
{
|
||||
level._effect[ "spotlight_beam" ] = loadfx( "env/light/fx_ray_spotlight_md" );
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
exploder_load( trigger )
|
||||
{
|
||||
level endon( "killexplodertridgers" + trigger.script_exploder );
|
||||
trigger waittill( "trigger" );
|
||||
if ( isDefined( trigger.script_chance ) && randomfloat( 1 ) > trigger.script_chance )
|
||||
{
|
||||
if ( isDefined( trigger.script_delay ) )
|
||||
{
|
||||
wait trigger.script_delay;
|
||||
}
|
||||
else
|
||||
{
|
||||
wait 4;
|
||||
}
|
||||
level thread exploder_load( trigger );
|
||||
return;
|
||||
}
|
||||
maps/mp/_utility::exploder( trigger.script_exploder );
|
||||
level notify( "killexplodertridgers" + trigger.script_exploder );
|
||||
}
|
||||
|
||||
setupexploders()
|
||||
{
|
||||
ents = getentarray( "script_brushmodel", "classname" );
|
||||
smodels = getentarray( "script_model", "classname" );
|
||||
i = 0;
|
||||
while ( i < smodels.size )
|
||||
{
|
||||
ents[ ents.size ] = smodels[ i ];
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < ents.size )
|
||||
{
|
||||
if ( isDefined( ents[ i ].script_prefab_exploder ) )
|
||||
{
|
||||
ents[ i ].script_exploder = ents[ i ].script_prefab_exploder;
|
||||
}
|
||||
if ( isDefined( ents[ i ].script_exploder ) )
|
||||
{
|
||||
if ( ents[ i ].model == "fx" || !isDefined( ents[ i ].targetname ) && ents[ i ].targetname != "exploderchunk" )
|
||||
{
|
||||
ents[ i ] hide();
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isDefined( ents[ i ].targetname ) && ents[ i ].targetname == "exploder" )
|
||||
{
|
||||
ents[ i ] hide();
|
||||
ents[ i ] notsolid();
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isDefined( ents[ i ].targetname ) && ents[ i ].targetname == "exploderchunk" )
|
||||
{
|
||||
ents[ i ] hide();
|
||||
ents[ i ] notsolid();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
script_exploders = [];
|
||||
potentialexploders = getentarray( "script_brushmodel", "classname" );
|
||||
i = 0;
|
||||
while ( i < potentialexploders.size )
|
||||
{
|
||||
if ( isDefined( potentialexploders[ i ].script_prefab_exploder ) )
|
||||
{
|
||||
potentialexploders[ i ].script_exploder = potentialexploders[ i ].script_prefab_exploder;
|
||||
}
|
||||
if ( isDefined( potentialexploders[ i ].script_exploder ) )
|
||||
{
|
||||
script_exploders[ script_exploders.size ] = potentialexploders[ i ];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
potentialexploders = getentarray( "script_model", "classname" );
|
||||
i = 0;
|
||||
while ( i < potentialexploders.size )
|
||||
{
|
||||
if ( isDefined( potentialexploders[ i ].script_prefab_exploder ) )
|
||||
{
|
||||
potentialexploders[ i ].script_exploder = potentialexploders[ i ].script_prefab_exploder;
|
||||
}
|
||||
if ( isDefined( potentialexploders[ i ].script_exploder ) )
|
||||
{
|
||||
script_exploders[ script_exploders.size ] = potentialexploders[ i ];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
potentialexploders = getentarray( "item_health", "classname" );
|
||||
i = 0;
|
||||
while ( i < potentialexploders.size )
|
||||
{
|
||||
if ( isDefined( potentialexploders[ i ].script_prefab_exploder ) )
|
||||
{
|
||||
potentialexploders[ i ].script_exploder = potentialexploders[ i ].script_prefab_exploder;
|
||||
}
|
||||
if ( isDefined( potentialexploders[ i ].script_exploder ) )
|
||||
{
|
||||
script_exploders[ script_exploders.size ] = potentialexploders[ i ];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if ( !isDefined( level.createfxent ) )
|
||||
{
|
||||
level.createfxent = [];
|
||||
}
|
||||
acceptabletargetnames = [];
|
||||
acceptabletargetnames[ "exploderchunk visible" ] = 1;
|
||||
acceptabletargetnames[ "exploderchunk" ] = 1;
|
||||
acceptabletargetnames[ "exploder" ] = 1;
|
||||
i = 0;
|
||||
while ( i < script_exploders.size )
|
||||
{
|
||||
exploder = script_exploders[ i ];
|
||||
ent = createexploder( exploder.script_fxid );
|
||||
ent.v = [];
|
||||
ent.v[ "origin" ] = exploder.origin;
|
||||
ent.v[ "angles" ] = exploder.angles;
|
||||
ent.v[ "delay" ] = exploder.script_delay;
|
||||
ent.v[ "firefx" ] = exploder.script_firefx;
|
||||
ent.v[ "firefxdelay" ] = exploder.script_firefxdelay;
|
||||
ent.v[ "firefxsound" ] = exploder.script_firefxsound;
|
||||
ent.v[ "firefxtimeout" ] = exploder.script_firefxtimeout;
|
||||
ent.v[ "earthquake" ] = exploder.script_earthquake;
|
||||
ent.v[ "damage" ] = exploder.script_damage;
|
||||
ent.v[ "damage_radius" ] = exploder.script_radius;
|
||||
ent.v[ "soundalias" ] = exploder.script_soundalias;
|
||||
ent.v[ "repeat" ] = exploder.script_repeat;
|
||||
ent.v[ "delay_min" ] = exploder.script_delay_min;
|
||||
ent.v[ "delay_max" ] = exploder.script_delay_max;
|
||||
ent.v[ "target" ] = exploder.target;
|
||||
ent.v[ "ender" ] = exploder.script_ender;
|
||||
ent.v[ "type" ] = "exploder";
|
||||
if ( !isDefined( exploder.script_fxid ) )
|
||||
{
|
||||
ent.v[ "fxid" ] = "No FX";
|
||||
}
|
||||
else
|
||||
{
|
||||
ent.v[ "fxid" ] = exploder.script_fxid;
|
||||
}
|
||||
ent.v[ "exploder" ] = exploder.script_exploder;
|
||||
/#
|
||||
assert( isDefined( exploder.script_exploder ), "Exploder at origin " + exploder.origin + " has no script_exploder" );
|
||||
#/
|
||||
if ( !isDefined( ent.v[ "delay" ] ) )
|
||||
{
|
||||
ent.v[ "delay" ] = 0;
|
||||
}
|
||||
if ( isDefined( exploder.target ) )
|
||||
{
|
||||
org = getent( ent.v[ "target" ], "targetname" ).origin;
|
||||
ent.v[ "angles" ] = vectorToAngle( org - ent.v[ "origin" ] );
|
||||
}
|
||||
if ( exploder.classname == "script_brushmodel" || isDefined( exploder.model ) )
|
||||
{
|
||||
ent.model = exploder;
|
||||
ent.model.disconnect_paths = exploder.script_disconnectpaths;
|
||||
}
|
||||
if ( isDefined( exploder.targetname ) && isDefined( acceptabletargetnames[ exploder.targetname ] ) )
|
||||
{
|
||||
ent.v[ "exploder_type" ] = exploder.targetname;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent.v[ "exploder_type" ] = "normal";
|
||||
}
|
||||
ent maps/mp/_createfx::post_entity_creation_function();
|
||||
i++;
|
||||
}
|
||||
level.createfxexploders = [];
|
||||
i = 0;
|
||||
while ( i < level.createfxent.size )
|
||||
{
|
||||
ent = level.createfxent[ i ];
|
||||
if ( ent.v[ "type" ] != "exploder" )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent.v[ "exploder_id" ] = getexploderid( ent );
|
||||
if ( !isDefined( level.createfxexploders[ ent.v[ "exploder" ] ] ) )
|
||||
{
|
||||
level.createfxexploders[ ent.v[ "exploder" ] ] = [];
|
||||
}
|
||||
level.createfxexploders[ ent.v[ "exploder" ] ][ level.createfxexploders[ ent.v[ "exploder" ] ].size ] = ent;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
setup_traversals()
|
||||
{
|
||||
potential_traverse_nodes = getallnodes();
|
||||
i = 0;
|
||||
while ( i < potential_traverse_nodes.size )
|
||||
{
|
||||
node = potential_traverse_nodes[ i ];
|
||||
if ( node.type == "Begin" )
|
||||
{
|
||||
node maps/mp/animscripts/traverse/shared::init_traverse();
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
calculate_map_center()
|
||||
{
|
||||
if ( !isDefined( level.mapcenter ) )
|
||||
{
|
||||
level.nodesmins = ( 0, 0, 0 );
|
||||
level.nodesmaxs = ( 0, 0, 0 );
|
||||
level.mapcenter = maps/mp/gametypes/_spawnlogic::findboxcenter( level.nodesmins, level.nodesmaxs );
|
||||
/#
|
||||
println( "map center: ", level.mapcenter );
|
||||
#/
|
||||
setmapcenter( level.mapcenter );
|
||||
}
|
||||
}
|
||||
|
||||
start_intro_screen_zm()
|
||||
{
|
||||
if ( level.createfx_enabled )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( !isDefined( level.introscreen ) )
|
||||
{
|
||||
level.introscreen = newhudelem();
|
||||
level.introscreen.x = 0;
|
||||
level.introscreen.y = 0;
|
||||
level.introscreen.horzalign = "fullscreen";
|
||||
level.introscreen.vertalign = "fullscreen";
|
||||
level.introscreen.foreground = 0;
|
||||
level.introscreen setshader( "black", 640, 480 );
|
||||
wait 0,05;
|
||||
}
|
||||
level.introscreen.alpha = 1;
|
||||
players = get_players();
|
||||
i = 0;
|
||||
while ( i < players.size )
|
||||
{
|
||||
players[ i ] freezecontrols( 1 );
|
||||
i++;
|
||||
}
|
||||
wait 1;
|
||||
}
|
42
Multiplayer Core/patch_mp/maps/mp/_medals.gsc
Normal file
42
Multiplayer Core/patch_mp/maps/mp/_medals.gsc
Normal file
@ -0,0 +1,42 @@
|
||||
//checked includes match cerberus output
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_scoreevents;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
level.medalinfo = [];
|
||||
level.medalcallbacks = [];
|
||||
level.numkills = 0;
|
||||
level thread onplayerconnect();
|
||||
}
|
||||
|
||||
onplayerconnect() //checked matches cerberus output
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
player.lastkilledby = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
setlastkilledby( attacker ) //checked matches cerberus output
|
||||
{
|
||||
self.lastkilledby = attacker;
|
||||
}
|
||||
|
||||
offenseglobalcount() //checked matches cerberus output
|
||||
{
|
||||
level.globalteammedals++;
|
||||
}
|
||||
|
||||
defenseglobalcount() //checked matches cerberus output
|
||||
{
|
||||
level.globalteammedals++;
|
||||
}
|
||||
|
||||
codecallback_medal( medalindex ) //checked matches cerberus output
|
||||
{
|
||||
self luinotifyevent( &"medal_received", 1, medalindex );
|
||||
self luinotifyeventtospectators( &"medal_received", 1, medalindex );
|
||||
}
|
4
Multiplayer Core/patch_mp/maps/mp/_menus.gsc
Normal file
4
Multiplayer Core/patch_mp/maps/mp/_menus.gsc
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
}
|
306
Multiplayer Core/patch_mp/maps/mp/_mgturret.gsc
Normal file
306
Multiplayer Core/patch_mp/maps/mp/_mgturret.gsc
Normal file
@ -0,0 +1,306 @@
|
||||
//checked includes match cerberus output
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
main() //checked changed to match cerberus output dvar taken from beta dump
|
||||
{
|
||||
if ( getDvar( "mg42" ) == "" )
|
||||
{
|
||||
setdvar( "mgTurret", "off" );
|
||||
}
|
||||
level.magic_distance = 24;
|
||||
turretinfos = getentarray( "turretInfo", "targetname" );
|
||||
for ( index = 0; index < turretinfos.size; index++ )
|
||||
{
|
||||
turretinfos[ index ] delete();
|
||||
}
|
||||
}
|
||||
|
||||
set_difficulty( difficulty ) //checked changed to match cerberus output
|
||||
{
|
||||
init_turret_difficulty_settings();
|
||||
turrets = getentarray( "misc_turret", "classname" );
|
||||
for ( index = 0; index < turrets.size; index++ )
|
||||
{
|
||||
if ( isDefined( turrets[ index ].script_skilloverride ) )
|
||||
{
|
||||
switch( turrets[ index ].script_skilloverride )
|
||||
{
|
||||
case "easy":
|
||||
difficulty = "easy";
|
||||
break;
|
||||
break;
|
||||
case "medium":
|
||||
difficulty = "medium";
|
||||
break;
|
||||
break;
|
||||
case "hard":
|
||||
difficulty = "hard";
|
||||
break;
|
||||
break;
|
||||
case "fu":
|
||||
difficulty = "fu";
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
turret_set_difficulty( turrets[ index ], difficulty );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init_turret_difficulty_settings() //checked matches cerberus output
|
||||
{
|
||||
level.mgturretsettings[ "easy" ][ "convergenceTime" ] = 2.5;
|
||||
level.mgturretsettings[ "easy" ][ "suppressionTime" ] = 3;
|
||||
level.mgturretsettings[ "easy" ][ "accuracy" ] = 0.38;
|
||||
level.mgturretsettings[ "easy" ][ "aiSpread" ] = 2;
|
||||
level.mgturretsettings[ "easy" ][ "playerSpread" ] = 0.5;
|
||||
level.mgturretsettings[ "medium" ][ "convergenceTime" ] = 1.5;
|
||||
level.mgturretsettings[ "medium" ][ "suppressionTime" ] = 3;
|
||||
level.mgturretsettings[ "medium" ][ "accuracy" ] = 0.38;
|
||||
level.mgturretsettings[ "medium" ][ "aiSpread" ] = 2;
|
||||
level.mgturretsettings[ "medium" ][ "playerSpread" ] = 0.5;
|
||||
level.mgturretsettings[ "hard" ][ "convergenceTime" ] = 0.8;
|
||||
level.mgturretsettings[ "hard" ][ "suppressionTime" ] = 3;
|
||||
level.mgturretsettings[ "hard" ][ "accuracy" ] = 0.38;
|
||||
level.mgturretsettings[ "hard" ][ "aiSpread" ] = 2;
|
||||
level.mgturretsettings[ "hard" ][ "playerSpread" ] = 0.5;
|
||||
level.mgturretsettings[ "fu" ][ "convergenceTime" ] = 0.4;
|
||||
level.mgturretsettings[ "fu" ][ "suppressionTime" ] = 3;
|
||||
level.mgturretsettings[ "fu" ][ "accuracy" ] = 0.38;
|
||||
level.mgturretsettings[ "fu" ][ "aiSpread" ] = 2;
|
||||
level.mgturretsettings[ "fu" ][ "playerSpread" ] = 0.5;
|
||||
}
|
||||
|
||||
turret_set_difficulty( turret, difficulty ) //checked matches cerberus output
|
||||
{
|
||||
turret.convergencetime = level.mgturretsettings[ difficulty ][ "convergenceTime" ];
|
||||
turret.suppressiontime = level.mgturretsettings[ difficulty ][ "suppressionTime" ];
|
||||
turret.accuracy = level.mgturretsettings[ difficulty ][ "accuracy" ];
|
||||
turret.aispread = level.mgturretsettings[ difficulty ][ "aiSpread" ];
|
||||
turret.playerspread = level.mgturretsettings[ difficulty ][ "playerSpread" ];
|
||||
}
|
||||
|
||||
turret_suppression_fire( targets ) //checked matches beta dump
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "stop_suppression_fire" );
|
||||
if ( !isDefined( self.suppresionfire ) )
|
||||
{
|
||||
self.suppresionfire = 1;
|
||||
}
|
||||
for ( ;; )
|
||||
{
|
||||
while ( self.suppresionfire )
|
||||
{
|
||||
self settargetentity( targets[ randomint( targets.size ) ] );
|
||||
wait ( 2 + randomfloat( 2 ) );
|
||||
}
|
||||
self cleartargetentity();
|
||||
while ( !self.suppresionfire )
|
||||
{
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
burst_fire_settings( setting ) //checked changed to match cerberus output
|
||||
{
|
||||
if ( setting == "delay" )
|
||||
{
|
||||
return 0.2;
|
||||
}
|
||||
else if ( setting == "delay_range" )
|
||||
{
|
||||
return 0.5;
|
||||
}
|
||||
else if ( setting == "burst" )
|
||||
{
|
||||
return 0.5;
|
||||
}
|
||||
else if ( setting == "burst_range" )
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
burst_fire( turret, manual_target ) //checked matches cerberus output
|
||||
{
|
||||
turret endon( "death" );
|
||||
turret endon( "stopfiring" );
|
||||
self endon( "stop_using_built_in_burst_fire" );
|
||||
if ( isDefined( turret.script_delay_min ) )
|
||||
{
|
||||
turret_delay = turret.script_delay_min;
|
||||
}
|
||||
else
|
||||
{
|
||||
turret_delay = burst_fire_settings( "delay" );
|
||||
}
|
||||
if ( isDefined( turret.script_delay_max ) )
|
||||
{
|
||||
turret_delay_range = turret.script_delay_max - turret_delay;
|
||||
}
|
||||
else
|
||||
{
|
||||
turret_delay_range = burst_fire_settings( "delay_range" );
|
||||
}
|
||||
if ( isDefined( turret.script_burst_min ) )
|
||||
{
|
||||
turret_burst = turret.script_burst_min;
|
||||
}
|
||||
else
|
||||
{
|
||||
turret_burst = burst_fire_settings( "burst" );
|
||||
}
|
||||
if ( isDefined( turret.script_burst_max ) )
|
||||
{
|
||||
turret_burst_range = turret.script_burst_max - turret_burst;
|
||||
}
|
||||
else
|
||||
{
|
||||
turret_burst_range = burst_fire_settings( "burst_range" );
|
||||
}
|
||||
while ( 1 )
|
||||
{
|
||||
turret startfiring();
|
||||
if ( isDefined( manual_target ) )
|
||||
{
|
||||
turret thread random_spread( manual_target );
|
||||
}
|
||||
turret do_shoot();
|
||||
wait ( turret_burst + randomfloat( turret_burst_range ) );
|
||||
turret stopshootturret();
|
||||
turret stopfiring();
|
||||
wait ( turret_delay + randomfloat( turret_delay_range ) );
|
||||
}
|
||||
}
|
||||
|
||||
burst_fire_unmanned() //checked changed at own discretion
|
||||
{
|
||||
self notify( "stop_burst_fire_unmanned" );
|
||||
self endon( "stop_burst_fire_unmanned" );
|
||||
self endon( "death" );
|
||||
self endon( "remote_start" );
|
||||
level endon( "game_ended" );
|
||||
if ( is_true( self.controlled ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( isDefined( self.script_delay_min ) )
|
||||
{
|
||||
turret_delay = self.script_delay_min;
|
||||
}
|
||||
else
|
||||
{
|
||||
turret_delay = burst_fire_settings( "delay" );
|
||||
}
|
||||
if ( isDefined( self.script_delay_max ) )
|
||||
{
|
||||
turret_delay_range = self.script_delay_max - turret_delay;
|
||||
}
|
||||
else
|
||||
{
|
||||
turret_delay_range = burst_fire_settings( "delay_range" );
|
||||
}
|
||||
if ( isDefined( self.script_burst_min ) )
|
||||
{
|
||||
turret_burst = self.script_burst_min;
|
||||
}
|
||||
else
|
||||
{
|
||||
turret_burst = burst_fire_settings( "burst" );
|
||||
}
|
||||
if ( isDefined( self.script_burst_max ) )
|
||||
{
|
||||
turret_burst_range = self.script_burst_max - turret_burst;
|
||||
}
|
||||
else
|
||||
{
|
||||
turret_burst_range = burst_fire_settings( "burst_range" );
|
||||
}
|
||||
pauseuntiltime = getTime();
|
||||
turretstate = "start";
|
||||
self.script_shooting = 0;
|
||||
for ( ;; )
|
||||
{
|
||||
if ( isDefined( self.manual_targets ) )
|
||||
{
|
||||
self cleartargetentity();
|
||||
self settargetentity( self.manual_targets[ randomint( self.manual_targets.size ) ] );
|
||||
}
|
||||
duration = ( pauseuntiltime - getTime() ) * 0.001;
|
||||
if ( self isfiringturret() && duration <= 0 )
|
||||
{
|
||||
if ( turretstate != "fire" )
|
||||
{
|
||||
turretstate = "fire";
|
||||
self playsound( "mpl_turret_alert" );
|
||||
self thread do_shoot();
|
||||
self.script_shooting = 1;
|
||||
}
|
||||
duration = turret_burst + randomfloat( turret_burst_range );
|
||||
self thread turret_timer( duration );
|
||||
self waittill( "turretstatechange" );
|
||||
self.script_shooting = 0;
|
||||
duration = turret_delay + randomfloat( turret_delay_range );
|
||||
pauseuntiltime = getTime() + int( duration * 1000 );
|
||||
}
|
||||
else if ( turretstate != "aim" )
|
||||
{
|
||||
turretstate = "aim";
|
||||
}
|
||||
self thread turret_timer( duration );
|
||||
self waittill( "turretstatechange" );
|
||||
}
|
||||
}
|
||||
|
||||
do_shoot() //checked matches cerberus output
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "turretstatechange" );
|
||||
for ( ;; )
|
||||
{
|
||||
self shootturret();
|
||||
wait 0.112;
|
||||
}
|
||||
}
|
||||
|
||||
turret_timer( duration ) //checked matches cerberus output
|
||||
{
|
||||
if ( duration <= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self endon( "turretstatechange" );
|
||||
wait duration;
|
||||
if ( isDefined( self ) )
|
||||
{
|
||||
self notify( "turretstatechange" );
|
||||
}
|
||||
}
|
||||
|
||||
random_spread( ent ) //checked matches cerberus output
|
||||
{
|
||||
self endon( "death" );
|
||||
self notify( "stop random_spread" );
|
||||
self endon( "stop random_spread" );
|
||||
self endon( "stopfiring" );
|
||||
self settargetentity( ent );
|
||||
self.manual_target = ent;
|
||||
while ( 1 )
|
||||
{
|
||||
if ( isplayer( ent ) )
|
||||
{
|
||||
ent.origin = self.manual_target getorigin();
|
||||
}
|
||||
else
|
||||
{
|
||||
ent.origin = self.manual_target.origin;
|
||||
}
|
||||
ent.origin += ( 20 - randomfloat( 40 ), 20 - randomfloat( 40 ), 20 - randomfloat( 60 ) );
|
||||
wait 0.2;
|
||||
}
|
||||
}
|
||||
|
4
Multiplayer Core/patch_mp/maps/mp/_multi_extracam.gsc
Normal file
4
Multiplayer Core/patch_mp/maps/mp/_multi_extracam.gsc
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
}
|
30
Multiplayer Core/patch_mp/maps/mp/_music.gsc
Normal file
30
Multiplayer Core/patch_mp/maps/mp/_music.gsc
Normal file
@ -0,0 +1,30 @@
|
||||
//checked includes match cerberus output
|
||||
#include maps/mp/_utility;
|
||||
|
||||
music_init() //checked matches cerberus output
|
||||
{
|
||||
/*
|
||||
/#
|
||||
assert( level.clientscripts );
|
||||
#/
|
||||
*/
|
||||
level.musicstate = "";
|
||||
registerclientsys( "musicCmd" );
|
||||
}
|
||||
|
||||
setmusicstate( state, player ) //checked changed to match cerberus output
|
||||
{
|
||||
if ( isDefined( level.musicstate ) )
|
||||
{
|
||||
if ( isDefined( player ) )
|
||||
{
|
||||
setclientsysstate( "musicCmd", state, player );
|
||||
return;
|
||||
}
|
||||
else if ( level.musicstate != state )
|
||||
{
|
||||
setclientsysstate( "musicCmd", state );
|
||||
}
|
||||
}
|
||||
level.musicstate = state;
|
||||
}
|
5
Multiplayer Core/patch_mp/maps/mp/_pc.gsc
Normal file
5
Multiplayer Core/patch_mp/maps/mp/_pc.gsc
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
pcserver() //checked matches cerberus output
|
||||
{
|
||||
pcserverupdateplaylist();
|
||||
}
|
393
Multiplayer Core/patch_mp/maps/mp/_popups.gsc
Normal file
393
Multiplayer Core/patch_mp/maps/mp/_popups.gsc
Normal file
@ -0,0 +1,393 @@
|
||||
#include maps/mp/gametypes/_hud_message;
|
||||
#include maps/mp/gametypes/_rank;
|
||||
#include maps/mp/gametypes/_persistence;
|
||||
#include maps/mp/_medals;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level.contractsettings = spawnstruct();
|
||||
level.contractsettings.waittime = 4,2;
|
||||
level.killstreaksettings = spawnstruct();
|
||||
level.killstreaksettings.waittime = 3;
|
||||
level.ranksettings = spawnstruct();
|
||||
level.ranksettings.waittime = 3;
|
||||
level.startmessage = spawnstruct();
|
||||
level.startmessagedefaultduration = 2;
|
||||
level.endmessagedefaultduration = 2;
|
||||
level.challengesettings = spawnstruct();
|
||||
level.challengesettings.waittime = 3;
|
||||
level.teammessage = spawnstruct();
|
||||
level.teammessage.waittime = 3;
|
||||
level.regulargamemessages = spawnstruct();
|
||||
level.regulargamemessages.waittime = 6;
|
||||
level.wagersettings = spawnstruct();
|
||||
level.wagersettings.waittime = 3;
|
||||
level.momentumnotifywaittime = 0;
|
||||
level.momentumnotifywaitlasttime = 0;
|
||||
level.teammessagequeuemax = 8;
|
||||
precachestring( &"KILLSTREAK_DESTROYED_UAV" );
|
||||
precachestring( &"KILLSTREAK_DESTROYED_COUNTERUAV" );
|
||||
precachestring( &"KILLSTREAK_DESTROYED_REMOTE_MORTAR" );
|
||||
precachestring( &"KILLSTREAK_MP40_INBOUND" );
|
||||
precachestring( &"KILLSTREAK_M220_TOW_INBOUND" );
|
||||
precachestring( &"KILLSTREAK_MINIGUN_INBOUND" );
|
||||
precachestring( &"KILLSTREAK_M202_FLASH_INBOUND" );
|
||||
precachestring( &"KILLSTREAK_M32_INBOUND" );
|
||||
precachestring( &"MP_CAPTURED_THE_FLAG" );
|
||||
precachestring( &"MP_KILLED_FLAG_CARRIER" );
|
||||
precachestring( &"MP_FRIENDLY_FLAG_DROPPED" );
|
||||
precachestring( &"MP_ENEMY_FLAG_DROPPED" );
|
||||
precachestring( &"MP_FRIENDLY_FLAG_RETURNED" );
|
||||
precachestring( &"MP_ENEMY_FLAG_RETURNED" );
|
||||
precachestring( &"MP_FRIENDLY_FLAG_TAKEN" );
|
||||
precachestring( &"MP_ENEMY_FLAG_TAKEN" );
|
||||
precachestring( &"MP_ENEMY_FLAG_CAPTURED" );
|
||||
precachestring( &"MP_FRIENDLY_FLAG_CAPTURED" );
|
||||
precachestring( &"MP_EXPLOSIVES_BLOWUP_BY" );
|
||||
precachestring( &"MP_EXPLOSIVES_DEFUSED_BY" );
|
||||
precachestring( &"MP_EXPLOSIVES_PLANTED_BY" );
|
||||
precachestring( &"MP_HQ_DESTROYED_BY" );
|
||||
precachestring( &"KILLSTREAK_DESTROYED_HELICOPTER" );
|
||||
/#
|
||||
level thread popupsfromconsole();
|
||||
#/
|
||||
level thread onplayerconnect();
|
||||
}
|
||||
|
||||
popupsfromconsole()
|
||||
{
|
||||
/#
|
||||
while ( 1 )
|
||||
{
|
||||
timeout = getdvarintdefault( "scr_popuptime", 1 );
|
||||
if ( timeout == 0 )
|
||||
{
|
||||
timeout = 1;
|
||||
}
|
||||
wait timeout;
|
||||
medal = getdvarintdefault( "scr_popupmedal", 0 );
|
||||
challenge = getdvarintdefault( "scr_popupchallenge", 0 );
|
||||
rank = getdvarintdefault( "scr_popuprank", 0 );
|
||||
gun = getdvarintdefault( "scr_popupgun", 0 );
|
||||
contractpass = getdvarintdefault( "scr_popupcontractpass", 0 );
|
||||
contractfail = getdvarintdefault( "scr_popupcontractfail", 0 );
|
||||
gamemodemsg = getdvarintdefault( "scr_gamemodeslideout", 0 );
|
||||
teammsg = getdvarintdefault( "scr_teamslideout", 0 );
|
||||
challengeindex = getdvarintdefault( "scr_challengeIndex", 1 );
|
||||
i = 0;
|
||||
while ( i < medal )
|
||||
{
|
||||
level.players[ 0 ] maps/mp/_medals::codecallback_medal( 4 );
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < challenge )
|
||||
{
|
||||
level.players[ 0 ] maps/mp/gametypes/_persistence::codecallback_challengecomplete( 2500, 1, 84, 3, 0, 0, 851 );
|
||||
level.players[ 0 ] maps/mp/gametypes/_persistence::codecallback_challengecomplete( 500, 1, 22, 2, 0, 0, 533 );
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < rank )
|
||||
{
|
||||
level.players[ 0 ] maps/mp/gametypes/_rank::codecallback_rankup( 4, 0, 0 );
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < gun )
|
||||
{
|
||||
level.players[ 0 ] maps/mp/gametypes/_persistence::codecallback_gunchallengecomplete( 0, 20, 25, 0 );
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < contractpass )
|
||||
{
|
||||
level.players[ 0 ] maps/mp/gametypes/_persistence::addcontracttoqueue( 12, 1 );
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < contractfail )
|
||||
{
|
||||
level.players[ 0 ] maps/mp/gametypes/_persistence::addcontracttoqueue( 12, 0 );
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < teammsg )
|
||||
{
|
||||
player = level.players[ 0 ];
|
||||
if ( isDefined( level.players[ 1 ] ) )
|
||||
{
|
||||
player = level.players[ 1 ];
|
||||
}
|
||||
level.players[ 0 ] displayteammessagetoall( &"KILLSTREAK_DESTROYED_HELICOPTER", player );
|
||||
i++;
|
||||
}
|
||||
reset = getdvarintdefault( "scr_popupreset", 1 );
|
||||
if ( reset )
|
||||
{
|
||||
if ( medal )
|
||||
{
|
||||
setdvar( "scr_popupmedal", 0 );
|
||||
}
|
||||
if ( challenge )
|
||||
{
|
||||
setdvar( "scr_popupchallenge", 0 );
|
||||
}
|
||||
if ( gun )
|
||||
{
|
||||
setdvar( "scr_popupgun", 0 );
|
||||
}
|
||||
if ( rank )
|
||||
{
|
||||
setdvar( "scr_popuprank", 0 );
|
||||
}
|
||||
if ( contractpass )
|
||||
{
|
||||
setdvar( "scr_popupcontractpass", 0 );
|
||||
}
|
||||
if ( contractfail )
|
||||
{
|
||||
setdvar( "scr_popupcontractfail", 0 );
|
||||
}
|
||||
if ( gamemodemsg )
|
||||
{
|
||||
setdvar( "scr_gamemodeslideout", 0 );
|
||||
}
|
||||
if ( teammsg )
|
||||
{
|
||||
setdvar( "scr_teamslideout", 0 );
|
||||
}
|
||||
}
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
displaykillstreakteammessagetoall( killstreak, player )
|
||||
{
|
||||
if ( !isDefined( level.killstreaks[ killstreak ] ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( !isDefined( level.killstreaks[ killstreak ].inboundtext ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
message = level.killstreaks[ killstreak ].inboundtext;
|
||||
self displayteammessagetoall( message, player );
|
||||
}
|
||||
|
||||
shoulddisplayteammessages()
|
||||
{
|
||||
if ( level.hardcoremode == 1 || level.splitscreen == 1 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
displayteammessagetoall( message, player )
|
||||
{
|
||||
if ( !shoulddisplayteammessages() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < level.players.size )
|
||||
{
|
||||
cur_player = level.players[ i ];
|
||||
if ( cur_player isempjammed() )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else size = cur_player.teammessagequeue.size;
|
||||
if ( size >= level.teammessagequeuemax )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_player.teammessagequeue[ size ] = spawnstruct();
|
||||
cur_player.teammessagequeue[ size ].message = message;
|
||||
cur_player.teammessagequeue[ size ].player = player;
|
||||
cur_player notify( "received teammessage" );
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
displayteammessagetoteam( message, player, team )
|
||||
{
|
||||
if ( !shoulddisplayteammessages() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < level.players.size )
|
||||
{
|
||||
cur_player = level.players[ i ];
|
||||
if ( cur_player.team != team )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if ( cur_player isempjammed() )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else size = cur_player.teammessagequeue.size;
|
||||
if ( size >= level.teammessagequeuemax )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_player.teammessagequeue[ size ] = spawnstruct();
|
||||
cur_player.teammessagequeue[ size ].message = message;
|
||||
cur_player.teammessagequeue[ size ].player = player;
|
||||
cur_player notify( "received teammessage" );
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
displayteammessagewaiter()
|
||||
{
|
||||
if ( !shoulddisplayteammessages() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
self.teammessagequeue = [];
|
||||
for ( ;; )
|
||||
{
|
||||
if ( self.teammessagequeue.size == 0 )
|
||||
{
|
||||
self waittill( "received teammessage" );
|
||||
}
|
||||
if ( self.teammessagequeue.size > 0 )
|
||||
{
|
||||
nextnotifydata = self.teammessagequeue[ 0 ];
|
||||
arrayremoveindex( self.teammessagequeue, 0, 0 );
|
||||
if ( !isDefined( nextnotifydata.player ) || !isplayer( nextnotifydata.player ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( self isempjammed() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
self luinotifyevent( &"player_callout", 2, nextnotifydata.message, nextnotifydata.player.entnum );
|
||||
}
|
||||
wait level.teammessage.waittime;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
displaypopupswaiter()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self.ranknotifyqueue = [];
|
||||
if ( !isDefined( self.pers[ "challengeNotifyQueue" ] ) )
|
||||
{
|
||||
self.pers[ "challengeNotifyQueue" ] = [];
|
||||
}
|
||||
if ( !isDefined( self.pers[ "contractNotifyQueue" ] ) )
|
||||
{
|
||||
self.pers[ "contractNotifyQueue" ] = [];
|
||||
}
|
||||
self.messagenotifyqueue = [];
|
||||
self.startmessagenotifyqueue = [];
|
||||
self.wagernotifyqueue = [];
|
||||
while ( !level.gameended )
|
||||
{
|
||||
if ( self.startmessagenotifyqueue.size == 0 && self.messagenotifyqueue.size == 0 )
|
||||
{
|
||||
self waittill( "received award" );
|
||||
}
|
||||
waittillframeend;
|
||||
if ( level.gameended )
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( self.startmessagenotifyqueue.size > 0 )
|
||||
{
|
||||
nextnotifydata = self.startmessagenotifyqueue[ 0 ];
|
||||
arrayremoveindex( self.startmessagenotifyqueue, 0, 0 );
|
||||
if ( isDefined( nextnotifydata.duration ) )
|
||||
{
|
||||
duration = nextnotifydata.duration;
|
||||
}
|
||||
else
|
||||
{
|
||||
duration = level.startmessagedefaultduration;
|
||||
}
|
||||
self maps/mp/gametypes/_hud_message::shownotifymessage( nextnotifydata, duration );
|
||||
wait duration;
|
||||
continue;
|
||||
}
|
||||
else if ( self.messagenotifyqueue.size > 0 )
|
||||
{
|
||||
nextnotifydata = self.messagenotifyqueue[ 0 ];
|
||||
arrayremoveindex( self.messagenotifyqueue, 0, 0 );
|
||||
if ( isDefined( nextnotifydata.duration ) )
|
||||
{
|
||||
duration = nextnotifydata.duration;
|
||||
}
|
||||
else
|
||||
{
|
||||
duration = level.regulargamemessages.waittime;
|
||||
}
|
||||
self maps/mp/gametypes/_hud_message::shownotifymessage( nextnotifydata, duration );
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onplayerconnect()
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( "connecting", player );
|
||||
player.resetgameoverhudrequired = 0;
|
||||
player thread displaypopupswaiter();
|
||||
if ( !level.hardcoremode )
|
||||
{
|
||||
player thread displayteammessagewaiter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
milestonenotify( index, itemindex, type, tier )
|
||||
{
|
||||
level.globalchallenges++;
|
||||
if ( !isDefined( type ) )
|
||||
{
|
||||
type = "global";
|
||||
}
|
||||
size = self.pers[ "challengeNotifyQueue" ].size;
|
||||
self.pers[ "challengeNotifyQueue" ][ size ] = [];
|
||||
self.pers[ "challengeNotifyQueue" ][ size ][ "tier" ] = tier;
|
||||
self.pers[ "challengeNotifyQueue" ][ size ][ "index" ] = index;
|
||||
self.pers[ "challengeNotifyQueue" ][ size ][ "itemIndex" ] = itemindex;
|
||||
self.pers[ "challengeNotifyQueue" ][ size ][ "type" ] = type;
|
||||
self notify( "received award" );
|
||||
}
|
240
Multiplayer Core/patch_mp/maps/mp/_proximity_grenade.gsc
Normal file
240
Multiplayer Core/patch_mp/maps/mp/_proximity_grenade.gsc
Normal file
@ -0,0 +1,240 @@
|
||||
#include maps/mp/_scoreevents;
|
||||
#include maps/mp/_challenges;
|
||||
#include maps/mp/gametypes/_weaponobjects;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
precacheshader( "gfx_fxt_fx_screen_droplets_02" );
|
||||
precacherumble( "proximity_grenade" );
|
||||
precacheitem( "proximity_grenade_aoe_mp" );
|
||||
level._effect[ "prox_grenade_friendly_default" ] = loadfx( "weapon/grenade/fx_prox_grenade_scan_grn" );
|
||||
level._effect[ "prox_grenade_friendly_warning" ] = loadfx( "weapon/grenade/fx_prox_grenade_wrn_grn" );
|
||||
level._effect[ "prox_grenade_enemy_default" ] = loadfx( "weapon/grenade/fx_prox_grenade_scan_red" );
|
||||
level._effect[ "prox_grenade_enemy_warning" ] = loadfx( "weapon/grenade/fx_prox_grenade_wrn_red" );
|
||||
level._effect[ "prox_grenade_player_shock" ] = loadfx( "weapon/grenade/fx_prox_grenade_impact_player_spwner" );
|
||||
level.proximitygrenadedetectionradius = weapons_get_dvar_int( "scr_proximityGrenadeDetectionRadius", "150" );
|
||||
level.proximitygrenadegraceperiod = weapons_get_dvar( "scr_proximityGrenadeGracePeriod", 0,1 );
|
||||
level.proximitygrenadedamageradius = weapons_get_dvar_int( "scr_proximityGrenadeDamageRadius", "200" );
|
||||
level.proximitygrenadedotdamageamount = weapons_get_dvar_int( "scr_proximityGrenadeDOTDamageAmount", "1" );
|
||||
level.proximitygrenadedotdamageamounthardcore = weapons_get_dvar_int( "scr_proximityGrenadeDOTDamageAmountHardcore", "1" );
|
||||
level.proximitygrenadedotdamagetime = weapons_get_dvar( "scr_proximityGrenadeDOTDamageTime", 0,15 );
|
||||
level.proximitygrenadedotdamageinstances = weapons_get_dvar_int( "scr_proximityGrenadeDOTDamageInstances", "4" );
|
||||
level.proximitygrenademaxinstances = weapons_get_dvar_int( "scr_proximityGrenadeMaxInstances", "3" );
|
||||
level.proximitygrenadeeffectdebug = weapons_get_dvar_int( "scr_proximityGrenadeEffectDebug", "0" );
|
||||
level.proximitygrenadeactivationtime = weapons_get_dvar( "scr_proximityGrenadeActivationTime", 0,1 );
|
||||
level.poisonfxduration = 6;
|
||||
/#
|
||||
level thread updatedvars();
|
||||
#/
|
||||
}
|
||||
|
||||
register()
|
||||
{
|
||||
registerclientfield( "toplayer", "tazered", 1000, 1, "int" );
|
||||
}
|
||||
|
||||
updatedvars()
|
||||
{
|
||||
while ( 1 )
|
||||
{
|
||||
level.proximitygrenadedetectionradius = weapons_get_dvar_int( "scr_proximityGrenadeDetectionRadius", level.proximitygrenadedetectionradius );
|
||||
level.proximitygrenadegraceperiod = weapons_get_dvar( "scr_proximityGrenadeGracePeriod", level.proximitygrenadegraceperiod );
|
||||
level.proximitygrenadedamageradius = weapons_get_dvar_int( "scr_proximityGrenadeDamageRadius", level.proximitygrenadedamageradius );
|
||||
level.proximitygrenadedotdamageamount = weapons_get_dvar_int( "scr_proximityGrenadeDOTDamageAmount", level.proximitygrenadedotdamageamount );
|
||||
level.proximitygrenadedotdamageamounthardcore = weapons_get_dvar_int( "scr_proximityGrenadeDOTDamageAmountHardcore", level.proximitygrenadedotdamageamounthardcore );
|
||||
level.proximitygrenadedotdamagetime = weapons_get_dvar( "scr_proximityGrenadeDOTDamageTime", level.proximitygrenadedotdamagetime );
|
||||
level.proximitygrenadedotdamageinstances = weapons_get_dvar_int( "scr_proximityGrenadeDOTDamageInstances", level.proximitygrenadedotdamageinstances );
|
||||
level.proximitygrenademaxinstances = weapons_get_dvar_int( "scr_proximityGrenadeMaxInstances", level.proximitygrenademaxinstances );
|
||||
level.proximitygrenadeeffectdebug = weapons_get_dvar_int( "scr_proximityGrenadeEffectDebug", level.proximitygrenadeeffectdebug );
|
||||
level.proximitygrenadeactivationtime = weapons_get_dvar( "scr_proximityGrenadeActivationTime", level.proximitygrenadeactivationtime );
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
|
||||
createproximitygrenadewatcher()
|
||||
{
|
||||
watcher = self maps/mp/gametypes/_weaponobjects::createproximityweaponobjectwatcher( "proximity_grenade", "proximity_grenade_mp", self.team );
|
||||
watcher.watchforfire = 1;
|
||||
watcher.hackable = 1;
|
||||
watcher.hackertoolradius = level.equipmenthackertoolradius;
|
||||
watcher.hackertooltimems = level.equipmenthackertooltimems;
|
||||
watcher.headicon = 0;
|
||||
watcher.reconmodel = "t6_wpn_taser_mine_world_detect";
|
||||
watcher.activatefx = 1;
|
||||
watcher.ownergetsassist = 1;
|
||||
watcher.ignoredirection = 1;
|
||||
watcher.immediatedetonation = 1;
|
||||
watcher.detectiongraceperiod = level.proximitygrenadegraceperiod;
|
||||
watcher.detonateradius = level.proximitygrenadedetectionradius;
|
||||
watcher.stun = maps/mp/gametypes/_weaponobjects::weaponstun;
|
||||
watcher.stuntime = 1;
|
||||
watcher.detonate = ::proximitydetonate;
|
||||
watcher.activationdelay = level.proximitygrenadeactivationtime;
|
||||
watcher.onspawn = ::onspawnproximitygrenadeweaponobject;
|
||||
}
|
||||
|
||||
onspawnproximitygrenadeweaponobject( watcher, owner )
|
||||
{
|
||||
self thread setupkillcament();
|
||||
owner addweaponstat( "proximity_grenade_mp", "used", 1 );
|
||||
onspawnproximityweaponobject( watcher, owner );
|
||||
}
|
||||
|
||||
setupkillcament()
|
||||
{
|
||||
self endon( "death" );
|
||||
self waittillnotmoving();
|
||||
self.killcament = spawn( "script_model", self.origin + vectorScale( ( 0, 0, 1 ), 8 ) );
|
||||
self thread cleanupkillcamentondeath();
|
||||
}
|
||||
|
||||
cleanupkillcamentondeath()
|
||||
{
|
||||
self waittill( "death" );
|
||||
self.killcament deleteaftertime( 3 + ( level.proximitygrenadedotdamagetime * level.proximitygrenadedotdamageinstances ) );
|
||||
}
|
||||
|
||||
proximitydetonate( attacker, weaponname )
|
||||
{
|
||||
if ( isDefined( weaponname ) )
|
||||
{
|
||||
if ( isDefined( attacker ) )
|
||||
{
|
||||
if ( self.owner isenemyplayer( attacker ) )
|
||||
{
|
||||
attacker maps/mp/_challenges::destroyedexplosive( weaponname );
|
||||
maps/mp/_scoreevents::processscoreevent( "destroyed_proxy", attacker, self.owner, weaponname );
|
||||
}
|
||||
}
|
||||
}
|
||||
maps/mp/gametypes/_weaponobjects::weapondetonate( attacker, weaponname );
|
||||
}
|
||||
|
||||
proximitygrenadedamageplayer( eattacker, einflictor )
|
||||
{
|
||||
if ( !self hasperk( "specialty_proximityprotection" ) )
|
||||
{
|
||||
if ( !level.proximitygrenadeeffectdebug )
|
||||
{
|
||||
self thread damageplayerinradius( einflictor.origin, eattacker, einflictor );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watchproximitygrenadehitplayer( owner )
|
||||
{
|
||||
self endon( "death" );
|
||||
self setowner( owner );
|
||||
self setteam( owner.team );
|
||||
while ( 1 )
|
||||
{
|
||||
self waittill( "grenade_bounce", pos, normal, ent, surface );
|
||||
if ( isDefined( ent ) && isplayer( ent ) && surface != "riotshield" )
|
||||
{
|
||||
if ( level.teambased && ent.team == self.owner.team )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
self proximitydetonate( self.owner, undefined );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
performhudeffects( position, distancetogrenade )
|
||||
{
|
||||
forwardvec = vectornormalize( anglesToForward( self.angles ) );
|
||||
rightvec = vectornormalize( anglesToRight( self.angles ) );
|
||||
explosionvec = vectornormalize( position - self.origin );
|
||||
fdot = vectordot( explosionvec, forwardvec );
|
||||
rdot = vectordot( explosionvec, rightvec );
|
||||
fangle = acos( fdot );
|
||||
rangle = acos( rdot );
|
||||
}
|
||||
|
||||
damageplayerinradius( position, owner, einflictor )
|
||||
{
|
||||
self notify( "proximityGrenadeDamageStart" );
|
||||
self endon( "proximityGrenadeDamageStart" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
owner endon( "disconnect" );
|
||||
self thread watch_death();
|
||||
if ( !isDefined( einflictor.killcament ) )
|
||||
{
|
||||
killcament = spawn( "script_model", self.origin + vectorScale( ( 0, 0, 1 ), 8 ) );
|
||||
killcament deleteaftertime( 3 + ( level.proximitygrenadedotdamagetime * level.proximitygrenadedotdamageinstances ) );
|
||||
killcament.soundmod = "taser_spike";
|
||||
}
|
||||
else
|
||||
{
|
||||
killcament = einflictor.killcament;
|
||||
killcament.soundmod = "taser_spike";
|
||||
}
|
||||
damage = level.proximitygrenadedotdamageamount;
|
||||
playfxontag( level._effect[ "prox_grenade_player_shock" ], self, "J_SpineUpper" );
|
||||
if ( level.hardcoremode )
|
||||
{
|
||||
damage = level.proximitygrenadedotdamageamounthardcore;
|
||||
}
|
||||
if ( self mayapplyscreeneffect() )
|
||||
{
|
||||
shellshock_duration = 1,5;
|
||||
self shellshock( "proximity_grenade", shellshock_duration, 0 );
|
||||
self setclientfieldtoplayer( "tazered", 1 );
|
||||
}
|
||||
self playrumbleonentity( "proximity_grenade" );
|
||||
self playsound( "wpn_taser_mine_zap" );
|
||||
self setclientuivisibilityflag( "hud_visible", 0 );
|
||||
i = 0;
|
||||
while ( i < level.proximitygrenadedotdamageinstances )
|
||||
{
|
||||
wait level.proximitygrenadedotdamagetime;
|
||||
/#
|
||||
assert( isDefined( owner ) );
|
||||
#/
|
||||
/#
|
||||
assert( isDefined( killcament ) );
|
||||
#/
|
||||
self dodamage( damage, position, owner, killcament, "none", "MOD_GAS", 0, "proximity_grenade_aoe_mp" );
|
||||
i++;
|
||||
}
|
||||
wait 0,85;
|
||||
self shellshock( "proximity_grenade_exit", 0,6, 0 );
|
||||
self setclientuivisibilityflag( "hud_visible", 1 );
|
||||
self setclientfieldtoplayer( "tazered", 0 );
|
||||
}
|
||||
|
||||
deleteentonownerdeath( owner )
|
||||
{
|
||||
self thread deleteentontimeout();
|
||||
self thread deleteentaftertime();
|
||||
self endon( "delete" );
|
||||
owner waittill( "death" );
|
||||
self notify( "deleteSound" );
|
||||
}
|
||||
|
||||
deleteentaftertime()
|
||||
{
|
||||
self endon( "delete" );
|
||||
wait 10;
|
||||
self notify( "deleteSound" );
|
||||
}
|
||||
|
||||
deleteentontimeout()
|
||||
{
|
||||
self endon( "delete" );
|
||||
self waittill( "deleteSound" );
|
||||
self delete();
|
||||
}
|
||||
|
||||
watch_death()
|
||||
{
|
||||
self waittill( "death" );
|
||||
self stoprumble( "proximity_grenade" );
|
||||
self setblur( 0, 0 );
|
||||
self setclientuivisibilityflag( "hud_visible", 1 );
|
||||
self setclientfieldtoplayer( "tazered", 0 );
|
||||
}
|
491
Multiplayer Core/patch_mp/maps/mp/_riotshield.gsc
Normal file
491
Multiplayer Core/patch_mp/maps/mp/_riotshield.gsc
Normal file
@ -0,0 +1,491 @@
|
||||
#include maps/mp/_scoreevents;
|
||||
#include maps/mp/killstreaks/_killstreak_weapons;
|
||||
#include maps/mp/killstreaks/_killstreaks;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
#using_animtree( "mp_riotshield" );
|
||||
|
||||
init()
|
||||
{
|
||||
if ( !isDefined( level.riotshield_name ) )
|
||||
{
|
||||
level.riotshield_name = "riotshield_mp";
|
||||
if ( isDefined( level.is_zombie_level ) && level.is_zombie_level )
|
||||
{
|
||||
level.riotshield_name = "riotshield_zm";
|
||||
}
|
||||
}
|
||||
level.deployedshieldmodel = "t6_wpn_shield_carry_world";
|
||||
level.stowedshieldmodel = "t6_wpn_shield_stow_world";
|
||||
level.carriedshieldmodel = "t6_wpn_shield_carry_world";
|
||||
level.detectshieldmodel = "t6_wpn_shield_carry_world_detect";
|
||||
if ( isDefined( level.is_zombie_level ) && level.is_zombie_level )
|
||||
{
|
||||
level.deployedshieldmodel = "t6_wpn_zmb_shield_world";
|
||||
level.stowedshieldmodel = "t6_wpn_zmb_shield_stow";
|
||||
level.carriedshieldmodel = "t6_wpn_zmb_shield_world";
|
||||
}
|
||||
precachemodel( level.stowedshieldmodel );
|
||||
precachemodel( level.carriedshieldmodel );
|
||||
precachemodel( level.detectshieldmodel );
|
||||
level.riotshielddestroyanim = %o_riot_stand_destroyed;
|
||||
level.riotshielddeployanim = %o_riot_stand_deploy;
|
||||
level.riotshieldshotanimfront = %o_riot_stand_shot;
|
||||
level.riotshieldshotanimback = %o_riot_stand_shot_back;
|
||||
level.riotshieldmeleeanimfront = %o_riot_stand_melee_front;
|
||||
level.riotshieldmeleeanimback = %o_riot_stand_melee_back;
|
||||
loadfx( "weapon/riotshield/fx_riotshield_depoly_lights" );
|
||||
loadfx( "weapon/riotshield/fx_riotshield_depoly_dust" );
|
||||
level.riotshield_placement_zoffset = 26;
|
||||
}
|
||||
|
||||
register()
|
||||
{
|
||||
registerclientfield( "scriptmover", "riotshield_state", 1, 2, "int" );
|
||||
}
|
||||
|
||||
watchpregameclasschange()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "track_riot_shield" );
|
||||
self waittill( "changed_class" );
|
||||
if ( level.ingraceperiod && !self.hasdonecombat )
|
||||
{
|
||||
self clearstowedweapon();
|
||||
self refreshshieldattachment();
|
||||
self thread trackriotshield();
|
||||
}
|
||||
}
|
||||
|
||||
watchriotshieldpickup()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "track_riot_shield" );
|
||||
self notify( "watch_riotshield_pickup" );
|
||||
self endon( "watch_riotshield_pickup" );
|
||||
self waittill( "pickup_riotshield" );
|
||||
self endon( "weapon_change" );
|
||||
/#
|
||||
println( "Picked up riotshield, expecting weapon_change notify..." );
|
||||
#/
|
||||
wait 0,5;
|
||||
/#
|
||||
println( "picked up shield but didn't change weapons, attach it!" );
|
||||
#/
|
||||
self.hasriotshield = self hasweapon( level.riotshield_name );
|
||||
self.hasriotshieldequipped = self getcurrentweapon() == level.riotshield_name;
|
||||
self refreshshieldattachment();
|
||||
}
|
||||
|
||||
trackriotshield()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self notify( "track_riot_shield" );
|
||||
self endon( "track_riot_shield" );
|
||||
self thread watchpregameclasschange();
|
||||
self waittill( "weapon_change", newweapon );
|
||||
self refreshshieldattachment();
|
||||
self.hasriotshield = self hasweapon( level.riotshield_name );
|
||||
self.hasriotshieldequipped = self getcurrentweapon() == level.riotshield_name;
|
||||
self.lastnonshieldweapon = "none";
|
||||
while ( 1 )
|
||||
{
|
||||
self thread watchriotshieldpickup();
|
||||
currentweapon = self getcurrentweapon();
|
||||
self.hasriotshield = self hasweapon( level.riotshield_name );
|
||||
self.hasriotshieldequipped = self getcurrentweapon() == level.riotshield_name;
|
||||
refresh_attach = 0;
|
||||
self waittill( "weapon_change", newweapon );
|
||||
if ( newweapon == level.riotshield_name )
|
||||
{
|
||||
refresh_attach = 1;
|
||||
if ( isDefined( self.riotshieldentity ) )
|
||||
{
|
||||
self notify( "destroy_riotshield" );
|
||||
}
|
||||
if ( self.hasriotshield )
|
||||
{
|
||||
if ( isDefined( self.riotshieldtakeweapon ) )
|
||||
{
|
||||
self takeweapon( self.riotshieldtakeweapon );
|
||||
self.riotshieldtakeweapon = undefined;
|
||||
}
|
||||
}
|
||||
if ( isvalidnonshieldweapon( currentweapon ) )
|
||||
{
|
||||
self.lastnonshieldweapon = currentweapon;
|
||||
}
|
||||
}
|
||||
if ( self.hasriotshield || refresh_attach == 1 )
|
||||
{
|
||||
self refreshshieldattachment();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isvalidnonshieldweapon( weapon )
|
||||
{
|
||||
if ( maps/mp/killstreaks/_killstreaks::iskillstreakweapon( weapon ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( maps/mp/killstreaks/_killstreak_weapons::isheldkillstreakweapon( weapon ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( maps/mp/killstreaks/_killstreak_weapons::isgameplayweapon( weapon ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( weapon == "none" )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( isweaponequipment( weapon ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
startriotshielddeploy()
|
||||
{
|
||||
self notify( "start_riotshield_deploy" );
|
||||
self thread watchriotshielddeploy();
|
||||
}
|
||||
|
||||
resetreconmodelvisibility( owner )
|
||||
{
|
||||
if ( !isDefined( self ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self setinvisibletoall();
|
||||
self setforcenocull();
|
||||
if ( !isDefined( owner ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < level.players.size )
|
||||
{
|
||||
if ( level.players[ i ] hasperk( "specialty_showenemyequipment" ) )
|
||||
{
|
||||
if ( level.players[ i ].team == "spectator" )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
isenemy = 1;
|
||||
if ( level.teambased )
|
||||
{
|
||||
if ( level.players[ i ].team == owner.team )
|
||||
{
|
||||
isenemy = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( level.players[ i ] == owner )
|
||||
{
|
||||
isenemy = 0;
|
||||
}
|
||||
}
|
||||
if ( isenemy )
|
||||
{
|
||||
self setvisibletoplayer( level.players[ i ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
resetreconmodelonevent( eventname, owner )
|
||||
{
|
||||
self endon( "death" );
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( eventname, newowner );
|
||||
if ( isDefined( newowner ) )
|
||||
{
|
||||
owner = newowner;
|
||||
}
|
||||
self resetreconmodelvisibility( owner );
|
||||
}
|
||||
}
|
||||
|
||||
attachreconmodel( modelname, owner )
|
||||
{
|
||||
if ( !isDefined( self ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
reconmodel = spawn( "script_model", self.origin );
|
||||
reconmodel.angles = self.angles;
|
||||
reconmodel setmodel( modelname );
|
||||
reconmodel.model_name = modelname;
|
||||
reconmodel linkto( self );
|
||||
reconmodel setcontents( 0 );
|
||||
reconmodel resetreconmodelvisibility( owner );
|
||||
reconmodel thread resetreconmodelonevent( "joined_team", owner );
|
||||
reconmodel thread resetreconmodelonevent( "player_spawned", owner );
|
||||
self.reconmodel = reconmodel;
|
||||
}
|
||||
|
||||
spawnriotshieldcover( origin, angles )
|
||||
{
|
||||
shield_ent = spawn( "script_model", origin, 1 );
|
||||
shield_ent.targetname = "riotshield_mp";
|
||||
shield_ent.angles = angles;
|
||||
shield_ent setmodel( level.deployedshieldmodel );
|
||||
shield_ent setowner( self );
|
||||
shield_ent.owner = self;
|
||||
shield_ent.team = self.team;
|
||||
shield_ent setteam( self.team );
|
||||
shield_ent attachreconmodel( level.detectshieldmodel, self );
|
||||
shield_ent useanimtree( -1 );
|
||||
shield_ent setscriptmoverflag( 0 );
|
||||
shield_ent disconnectpaths();
|
||||
return shield_ent;
|
||||
}
|
||||
|
||||
watchriotshielddeploy()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "start_riotshield_deploy" );
|
||||
self waittill( "deploy_riotshield", deploy_attempt );
|
||||
self setheldweaponmodel( 0 );
|
||||
self setplacementhint( 1 );
|
||||
placement_hint = 0;
|
||||
if ( deploy_attempt )
|
||||
{
|
||||
placement = self canplaceriotshield( "deploy_riotshield" );
|
||||
if ( placement[ "result" ] )
|
||||
{
|
||||
self.hasdonecombat = 1;
|
||||
zoffset = level.riotshield_placement_zoffset;
|
||||
shield_ent = self spawnriotshieldcover( placement[ "origin" ] + ( 0, 0, zoffset ), placement[ "angles" ] );
|
||||
item_ent = deployriotshield( self, shield_ent );
|
||||
primaries = self getweaponslistprimaries();
|
||||
/#
|
||||
assert( isDefined( item_ent ) );
|
||||
assert( !isDefined( self.riotshieldretrievetrigger ) );
|
||||
assert( !isDefined( self.riotshieldentity ) );
|
||||
if ( level.gametype != "shrp" )
|
||||
{
|
||||
assert( primaries.size > 0 );
|
||||
#/
|
||||
}
|
||||
shield_ent setclientfield( "riotshield_state", 1 );
|
||||
shield_ent.reconmodel setclientfield( "riotshield_state", 1 );
|
||||
if ( level.gametype != "shrp" )
|
||||
{
|
||||
if ( self.lastnonshieldweapon != "none" && self hasweapon( self.lastnonshieldweapon ) )
|
||||
{
|
||||
self switchtoweapon( self.lastnonshieldweapon );
|
||||
}
|
||||
else
|
||||
{
|
||||
self switchtoweapon( primaries[ 0 ] );
|
||||
}
|
||||
}
|
||||
if ( !self hasweapon( "knife_held_mp" ) )
|
||||
{
|
||||
self giveweapon( "knife_held_mp" );
|
||||
self.riotshieldtakeweapon = "knife_held_mp";
|
||||
}
|
||||
self.riotshieldretrievetrigger = item_ent;
|
||||
self.riotshieldentity = shield_ent;
|
||||
self thread watchdeployedriotshieldents();
|
||||
self thread deleteshieldontriggerdeath( self.riotshieldretrievetrigger );
|
||||
self thread deleteshieldonplayerdeathordisconnect( shield_ent );
|
||||
self.riotshieldentity thread watchdeployedriotshielddamage();
|
||||
level notify( "riotshield_planted" );
|
||||
}
|
||||
else
|
||||
{
|
||||
placement_hint = 1;
|
||||
clip_max_ammo = weaponclipsize( level.riotshield_name );
|
||||
self setweaponammoclip( level.riotshield_name, clip_max_ammo );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
placement_hint = 1;
|
||||
}
|
||||
if ( placement_hint )
|
||||
{
|
||||
self setriotshieldfailhint();
|
||||
}
|
||||
}
|
||||
|
||||
riotshielddistancetest( origin )
|
||||
{
|
||||
/#
|
||||
assert( isDefined( origin ) );
|
||||
#/
|
||||
min_dist_squared = getDvarFloat( "riotshield_deploy_limit_radius" );
|
||||
min_dist_squared *= min_dist_squared;
|
||||
i = 0;
|
||||
while ( i < level.players.size )
|
||||
{
|
||||
if ( isDefined( level.players[ i ].riotshieldentity ) )
|
||||
{
|
||||
dist_squared = distancesquared( level.players[ i ].riotshieldentity.origin, origin );
|
||||
if ( min_dist_squared > dist_squared )
|
||||
{
|
||||
/#
|
||||
println( "Shield placement denied! Failed distance check to other riotshields." );
|
||||
#/
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
watchdeployedriotshieldents()
|
||||
{
|
||||
/#
|
||||
assert( isDefined( self.riotshieldretrievetrigger ) );
|
||||
assert( isDefined( self.riotshieldentity ) );
|
||||
#/
|
||||
self waittill( "destroy_riotshield" );
|
||||
if ( isDefined( self.riotshieldretrievetrigger ) )
|
||||
{
|
||||
self.riotshieldretrievetrigger delete();
|
||||
}
|
||||
if ( isDefined( self.riotshieldentity ) )
|
||||
{
|
||||
if ( isDefined( self.riotshieldentity.reconmodel ) )
|
||||
{
|
||||
self.riotshieldentity.reconmodel delete();
|
||||
}
|
||||
self.riotshieldentity connectpaths();
|
||||
self.riotshieldentity delete();
|
||||
}
|
||||
}
|
||||
|
||||
watchdeployedriotshielddamage()
|
||||
{
|
||||
self endon( "death" );
|
||||
damagemax = getDvarInt( "riotshield_deployed_health" );
|
||||
self.damagetaken = 0;
|
||||
while ( 1 )
|
||||
{
|
||||
self.maxhealth = 100000;
|
||||
self.health = self.maxhealth;
|
||||
self waittill( "damage", damage, attacker, direction, point, type, tagname, modelname, partname, weaponname, idflags );
|
||||
while ( !isDefined( attacker ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/#
|
||||
if ( isDefined( self.owner ) )
|
||||
{
|
||||
assert( isDefined( self.owner.team ) );
|
||||
}
|
||||
#/
|
||||
while ( isplayer( attacker ) )
|
||||
{
|
||||
while ( level.teambased && attacker.team == self.owner.team && attacker != self.owner )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ( type == "MOD_MELEE" )
|
||||
{
|
||||
damage *= getDvarFloat( "riotshield_melee_damage_scale" );
|
||||
}
|
||||
else if ( type == "MOD_PISTOL_BULLET" || type == "MOD_RIFLE_BULLET" )
|
||||
{
|
||||
damage *= getDvarFloat( "riotshield_bullet_damage_scale" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( type != "MOD_GRENADE" && type != "MOD_GRENADE_SPLASH" && type != "MOD_EXPLOSIVE" && type != "MOD_EXPLOSIVE_SPLASH" || type == "MOD_PROJECTILE" && type == "MOD_PROJECTILE_SPLASH" )
|
||||
{
|
||||
damage *= getDvarFloat( "riotshield_explosive_damage_scale" );
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( type == "MOD_IMPACT" )
|
||||
{
|
||||
damage *= getDvarFloat( "riotshield_projectile_damage_scale" );
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( type == "MOD_CRUSH" )
|
||||
{
|
||||
damage = damagemax;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.damagetaken += damage;
|
||||
if ( self.damagetaken >= damagemax )
|
||||
{
|
||||
self thread damagethendestroyriotshield( attacker, weaponname );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
damagethendestroyriotshield( attacker, weaponname )
|
||||
{
|
||||
self notify( "damageThenDestroyRiotshield" );
|
||||
self endon( "death" );
|
||||
if ( isDefined( self.owner.riotshieldretrievetrigger ) )
|
||||
{
|
||||
self.owner.riotshieldretrievetrigger delete();
|
||||
}
|
||||
if ( isDefined( self.reconmodel ) )
|
||||
{
|
||||
self.reconmodel delete();
|
||||
}
|
||||
self connectpaths();
|
||||
self.owner.riotshieldentity = undefined;
|
||||
self notsolid();
|
||||
self setclientfield( "riotshield_state", 2 );
|
||||
if ( isDefined( attacker ) && isDefined( weaponname ) && attacker != self.owner && isplayer( attacker ) )
|
||||
{
|
||||
maps/mp/_scoreevents::processscoreevent( "destroyed_shield", attacker, self.owner, weaponname );
|
||||
}
|
||||
wait getDvarFloat( "riotshield_destroyed_cleanup_time" );
|
||||
self delete();
|
||||
}
|
||||
|
||||
deleteshieldontriggerdeath( shield_trigger )
|
||||
{
|
||||
shield_trigger waittill_any( "trigger", "death" );
|
||||
self notify( "destroy_riotshield" );
|
||||
}
|
||||
|
||||
deleteshieldonplayerdeathordisconnect( shield_ent )
|
||||
{
|
||||
shield_ent endon( "death" );
|
||||
shield_ent endon( "damageThenDestroyRiotshield" );
|
||||
self waittill_any( "death", "disconnect", "remove_planted_weapons" );
|
||||
shield_ent thread damagethendestroyriotshield();
|
||||
}
|
||||
|
||||
watchriotshieldstuckentitydeath( grenade, owner )
|
||||
{
|
||||
grenade endon( "death" );
|
||||
self waittill_any( "damageThenDestroyRiotshield", "death", "disconnect", "weapon_change", "deploy_riotshield" );
|
||||
grenade detonate( owner );
|
||||
}
|
46
Multiplayer Core/patch_mp/maps/mp/_satchel_charge.gsc
Normal file
46
Multiplayer Core/patch_mp/maps/mp/_satchel_charge.gsc
Normal file
@ -0,0 +1,46 @@
|
||||
//checked includes match cerberus output
|
||||
#include maps/mp/_scoreevents;
|
||||
#include maps/mp/_challenges;
|
||||
#include maps/mp/killstreaks/_emp;
|
||||
#include maps/mp/gametypes/_weaponobjects;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
level._effect[ "satchel_charge_enemy_light" ] = loadfx( "weapon/c4/fx_c4_light_red" );
|
||||
level._effect[ "satchel_charge_friendly_light" ] = loadfx( "weapon/c4/fx_c4_light_green" );
|
||||
}
|
||||
|
||||
createsatchelwatcher() //checked matches cerberus output
|
||||
{
|
||||
watcher = self maps/mp/gametypes/_weaponobjects::createuseweaponobjectwatcher( "satchel_charge", "satchel_charge_mp", self.team );
|
||||
watcher.altdetonate = 1;
|
||||
watcher.watchforfire = 1;
|
||||
watcher.hackable = 1;
|
||||
watcher.hackertoolradius = level.equipmenthackertoolradius;
|
||||
watcher.hackertooltimems = level.equipmenthackertooltimems;
|
||||
watcher.headicon = 1;
|
||||
watcher.detonate = ::satcheldetonate;
|
||||
watcher.stun = maps/mp/gametypes/_weaponobjects::weaponstun;
|
||||
watcher.stuntime = 1;
|
||||
watcher.altweapon = "satchel_charge_detonator_mp";
|
||||
watcher.reconmodel = "t6_wpn_c4_world_detect";
|
||||
watcher.ownergetsassist = 1;
|
||||
}
|
||||
|
||||
satcheldetonate( attacker, weaponname ) //checked matches cerberus output
|
||||
{
|
||||
from_emp = maps/mp/killstreaks/_emp::isempkillstreakweapon( weaponname );
|
||||
if ( !isDefined( from_emp ) || !from_emp )
|
||||
{
|
||||
if ( isDefined( attacker ) )
|
||||
{
|
||||
if ( self.owner isenemyplayer( attacker ) )
|
||||
{
|
||||
attacker maps/mp/_challenges::destroyedexplosive( weaponname );
|
||||
maps/mp/_scoreevents::processscoreevent( "destroyed_c4", attacker, self.owner, weaponname );
|
||||
}
|
||||
}
|
||||
}
|
||||
maps/mp/gametypes/_weaponobjects::weapondetonate( attacker, weaponname );
|
||||
}
|
838
Multiplayer Core/patch_mp/maps/mp/_scoreevents.gsc
Normal file
838
Multiplayer Core/patch_mp/maps/mp/_scoreevents.gsc
Normal file
@ -0,0 +1,838 @@
|
||||
#include maps/mp/gametypes/_globallogic_score;
|
||||
#include maps/mp/gametypes/_rank;
|
||||
#include maps/mp/killstreaks/_killstreaks;
|
||||
#include maps/mp/_scoreevents;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level.scoreeventcallbacks = [];
|
||||
level.scoreeventgameendcallback = ::ongameend;
|
||||
registerscoreeventcallback( "playerKilled", ::scoreeventplayerkill );
|
||||
}
|
||||
|
||||
scoreeventtablelookupint( index, scoreeventcolumn )
|
||||
{
|
||||
return int( tablelookup( "mp/scoreInfo.csv", 0, index, scoreeventcolumn ) );
|
||||
}
|
||||
|
||||
scoreeventtablelookup( index, scoreeventcolumn )
|
||||
{
|
||||
return tablelookup( "mp/scoreInfo.csv", 0, index, scoreeventcolumn );
|
||||
}
|
||||
|
||||
getscoreeventcolumn( gametype )
|
||||
{
|
||||
columnoffset = getcolumnoffsetforgametype( gametype );
|
||||
/#
|
||||
assert( columnoffset >= 0 );
|
||||
#/
|
||||
if ( columnoffset >= 0 )
|
||||
{
|
||||
columnoffset += 0;
|
||||
}
|
||||
return columnoffset;
|
||||
}
|
||||
|
||||
getxpeventcolumn( gametype )
|
||||
{
|
||||
columnoffset = getcolumnoffsetforgametype( gametype );
|
||||
/#
|
||||
assert( columnoffset >= 0 );
|
||||
#/
|
||||
if ( columnoffset >= 0 )
|
||||
{
|
||||
columnoffset += 1;
|
||||
}
|
||||
return columnoffset;
|
||||
}
|
||||
|
||||
getcolumnoffsetforgametype( gametype )
|
||||
{
|
||||
foundgamemode = 0;
|
||||
if ( !isDefined( level.scoreeventtableid ) )
|
||||
{
|
||||
level.scoreeventtableid = getscoreeventtableid();
|
||||
}
|
||||
/#
|
||||
assert( isDefined( level.scoreeventtableid ) );
|
||||
#/
|
||||
if ( !isDefined( level.scoreeventtableid ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
gamemodecolumn = 11;
|
||||
for ( ;; )
|
||||
{
|
||||
column_header = tablelookupcolumnforrow( level.scoreeventtableid, 0, gamemodecolumn );
|
||||
if ( column_header == "" )
|
||||
{
|
||||
gamemodecolumn = 11;
|
||||
break;
|
||||
}
|
||||
else if ( column_header == ( level.gametype + " score" ) )
|
||||
{
|
||||
foundgamemode = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
gamemodecolumn += 2;
|
||||
}
|
||||
}
|
||||
/#
|
||||
assert( foundgamemode, "Could not find gamemode in scoreInfo.csv:" + gametype );
|
||||
#/
|
||||
return gamemodecolumn;
|
||||
}
|
||||
|
||||
getscoreeventtableid()
|
||||
{
|
||||
scoreinfotableloaded = 0;
|
||||
scoreinfotableid = tablelookupfindcoreasset( "mp/scoreInfo.csv" );
|
||||
if ( isDefined( scoreinfotableid ) )
|
||||
{
|
||||
scoreinfotableloaded = 1;
|
||||
}
|
||||
/#
|
||||
assert( scoreinfotableloaded, "Score Event Table is not loaded: " + "mp/scoreInfo.csv" );
|
||||
#/
|
||||
return scoreinfotableid;
|
||||
}
|
||||
|
||||
isregisteredevent( type )
|
||||
{
|
||||
if ( isDefined( level.scoreinfo[ type ] ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
shouldaddrankxp( player )
|
||||
{
|
||||
if ( !isDefined( level.rankcap ) || level.rankcap == 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if ( player.pers[ "plevel" ] > 0 || player.pers[ "rank" ] > level.rankcap )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
processscoreevent( event, player, victim, weapon )
|
||||
{
|
||||
pixbeginevent( "processScoreEvent" );
|
||||
scoregiven = 0;
|
||||
if ( !isplayer( player ) )
|
||||
{
|
||||
/#
|
||||
assertmsg( "processScoreEvent called on non player entity: " + event );
|
||||
#/
|
||||
return scoregiven;
|
||||
}
|
||||
player thread maps/mp/_challenges::eventreceived( event );
|
||||
if ( isregisteredevent( event ) )
|
||||
{
|
||||
allowplayerscore = 0;
|
||||
if ( !isDefined( weapon ) || maps/mp/killstreaks/_killstreaks::iskillstreakweapon( weapon ) == 0 )
|
||||
{
|
||||
allowplayerscore = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
allowplayerscore = maps/mp/gametypes/_rank::killstreakweaponsallowedscore( event );
|
||||
}
|
||||
if ( allowplayerscore )
|
||||
{
|
||||
scoregiven = maps/mp/gametypes/_globallogic_score::giveplayerscore( event, player, victim, weapon, undefined );
|
||||
isscoreevent = scoregiven > 0;
|
||||
}
|
||||
}
|
||||
if ( shouldaddrankxp( player ) )
|
||||
{
|
||||
player addrankxp( event, weapon, isscoreevent );
|
||||
}
|
||||
pixendevent();
|
||||
return scoregiven;
|
||||
}
|
||||
|
||||
registerscoreeventcallback( callback, func )
|
||||
{
|
||||
if ( !isDefined( level.scoreeventcallbacks[ callback ] ) )
|
||||
{
|
||||
level.scoreeventcallbacks[ callback ] = [];
|
||||
}
|
||||
level.scoreeventcallbacks[ callback ][ level.scoreeventcallbacks[ callback ].size ] = func;
|
||||
}
|
||||
|
||||
scoreeventplayerkill( data, time )
|
||||
{
|
||||
victim = data.victim;
|
||||
attacker = data.attacker;
|
||||
time = data.time;
|
||||
level.numkills++;
|
||||
victim = data.victim;
|
||||
attacker.lastkilledplayer = victim;
|
||||
wasdefusing = data.wasdefusing;
|
||||
wasplanting = data.wasplanting;
|
||||
wasonground = data.victimonground;
|
||||
meansofdeath = data.smeansofdeath;
|
||||
if ( isDefined( data.sweapon ) )
|
||||
{
|
||||
weapon = data.sweapon;
|
||||
weaponclass = getweaponclass( data.sweapon );
|
||||
killstreak = getkillstreakfromweapon( data.sweapon );
|
||||
}
|
||||
victim.anglesondeath = victim getplayerangles();
|
||||
if ( meansofdeath != "MOD_GRENADE" && meansofdeath != "MOD_GRENADE_SPLASH" && meansofdeath != "MOD_EXPLOSIVE" && meansofdeath != "MOD_EXPLOSIVE_SPLASH" || meansofdeath == "MOD_PROJECTILE" && meansofdeath == "MOD_PROJECTILE_SPLASH" )
|
||||
{
|
||||
if ( weapon == "none" && isDefined( data.victim.explosiveinfo[ "weapon" ] ) )
|
||||
{
|
||||
weapon = data.victim.explosiveinfo[ "weapon" ];
|
||||
}
|
||||
}
|
||||
while ( level.teambased )
|
||||
{
|
||||
attacker.lastkilltime = time;
|
||||
if ( isDefined( victim.lastkilltime ) && victim.lastkilltime > ( time - 3000 ) )
|
||||
{
|
||||
if ( isDefined( victim.lastkilledplayer ) && victim.lastkilledplayer isenemyplayer( attacker ) == 0 && attacker != victim.lastkilledplayer )
|
||||
{
|
||||
processscoreevent( "kill_enemy_who_killed_teammate", attacker, victim, weapon );
|
||||
victim recordkillmodifier( "avenger" );
|
||||
}
|
||||
}
|
||||
while ( isDefined( victim.damagedplayers ) )
|
||||
{
|
||||
keys = getarraykeys( victim.damagedplayers );
|
||||
i = 0;
|
||||
while ( i < keys.size )
|
||||
{
|
||||
key = keys[ i ];
|
||||
if ( key == attacker.clientid )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if ( !isDefined( victim.damagedplayers[ key ].entity ) )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if ( attacker isenemyplayer( victim.damagedplayers[ key ].entity ) )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ( time - victim.damagedplayers[ key ].time ) < 1000 )
|
||||
{
|
||||
processscoreevent( "kill_enemy_injuring_teammate", attacker, victim, weapon );
|
||||
if ( isDefined( victim.damagedplayers[ key ].entity ) )
|
||||
{
|
||||
victim.damagedplayers[ key ].entity.lastrescuedby = attacker;
|
||||
victim.damagedplayers[ key ].entity.lastrescuedtime = time;
|
||||
}
|
||||
victim recordkillmodifier( "defender" );
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch( weapon )
|
||||
{
|
||||
case "hatchet_mp":
|
||||
attacker.pers[ "tomahawks" ]++;
|
||||
attacker.tomahawks = attacker.pers[ "tomahawks" ];
|
||||
processscoreevent( "hatchet_kill", attacker, victim, weapon );
|
||||
if ( isDefined( data.victim.explosiveinfo[ "projectile_bounced" ] ) && data.victim.explosiveinfo[ "projectile_bounced" ] == 1 )
|
||||
{
|
||||
level.globalbankshots++;
|
||||
processscoreevent( "bounce_hatchet_kill", attacker, victim, weapon );
|
||||
}
|
||||
break;
|
||||
case "knife_ballistic_mp":
|
||||
if ( meansofdeath == "MOD_PISTOL_BULLET" || meansofdeath == "MOD_HEAD_SHOT" )
|
||||
{
|
||||
processscoreevent( "ballistic_knife_kill", attacker, victim, data.sweapon );
|
||||
}
|
||||
attacker addweaponstat( weapon, "ballistic_knife_kill", 1 );
|
||||
break;
|
||||
case "inventory_supplydrop_mp":
|
||||
case "supplydrop_mp":
|
||||
if ( meansofdeath == "MOD_HIT_BY_OBJECT" || meansofdeath == "MOD_CRUSH" )
|
||||
{
|
||||
processscoreevent( "kill_enemy_with_care_package_crush", attacker, victim, weapon );
|
||||
}
|
||||
else
|
||||
{
|
||||
processscoreevent( "kill_enemy_with_hacked_care_package", attacker, victim, weapon );
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ( isDefined( data.victimweapon ) )
|
||||
{
|
||||
if ( data.victimweapon == "minigun_mp" )
|
||||
{
|
||||
processscoreevent( "killed_death_machine_enemy", attacker, victim, weapon );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( data.victimweapon == "m32_mp" )
|
||||
{
|
||||
processscoreevent( "killed_multiple_grenade_launcher_enemy", attacker, victim, weapon );
|
||||
}
|
||||
}
|
||||
}
|
||||
attacker thread updatemultikills( weapon, weaponclass, killstreak );
|
||||
if ( level.numkills == 1 )
|
||||
{
|
||||
victim recordkillmodifier( "firstblood" );
|
||||
processscoreevent( "first_kill", attacker, victim, weapon );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isDefined( attacker.lastkilledby ) )
|
||||
{
|
||||
if ( attacker.lastkilledby == victim )
|
||||
{
|
||||
level.globalpaybacks++;
|
||||
processscoreevent( "revenge_kill", attacker, victim, weapon );
|
||||
attacker addweaponstat( weapon, "revenge_kill", 1 );
|
||||
victim recordkillmodifier( "revenge" );
|
||||
attacker.lastkilledby = undefined;
|
||||
}
|
||||
}
|
||||
if ( victim maps/mp/killstreaks/_killstreaks::isonakillstreak() )
|
||||
{
|
||||
level.globalbuzzkills++;
|
||||
processscoreevent( "stop_enemy_killstreak", attacker, victim, weapon );
|
||||
victim recordkillmodifier( "buzzkill" );
|
||||
}
|
||||
if ( isDefined( victim.lastmansd ) && victim.lastmansd == 1 )
|
||||
{
|
||||
processscoreevent( "final_kill_elimination", attacker, victim, weapon );
|
||||
if ( isDefined( attacker.lastmansd ) && attacker.lastmansd == 1 )
|
||||
{
|
||||
processscoreevent( "elimination_and_last_player_alive", attacker, victim, weapon );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( is_weapon_valid( meansofdeath, weapon, weaponclass ) )
|
||||
{
|
||||
if ( isDefined( victim.vattackerorigin ) )
|
||||
{
|
||||
attackerorigin = victim.vattackerorigin;
|
||||
}
|
||||
else
|
||||
{
|
||||
attackerorigin = attacker.origin;
|
||||
}
|
||||
disttovictim = distancesquared( victim.origin, attackerorigin );
|
||||
weap_min_dmg_range = get_distance_for_weapon( weapon, weaponclass );
|
||||
if ( disttovictim > weap_min_dmg_range )
|
||||
{
|
||||
attacker maps/mp/_challenges::longdistancekill();
|
||||
if ( weapon == "hatchet_mp" )
|
||||
{
|
||||
attacker maps/mp/_challenges::longdistancehatchetkill();
|
||||
}
|
||||
processscoreevent( "longshot_kill", attacker, victim, weapon );
|
||||
attacker addweaponstat( weapon, "longshot_kill", 1 );
|
||||
attacker.pers[ "longshots" ]++;
|
||||
attacker.longshots = attacker.pers[ "longshots" ];
|
||||
victim recordkillmodifier( "longshot" );
|
||||
}
|
||||
}
|
||||
if ( isalive( attacker ) )
|
||||
{
|
||||
if ( attacker.health < ( attacker.maxhealth * 0,35 ) )
|
||||
{
|
||||
attacker.lastkillwheninjured = time;
|
||||
processscoreevent( "kill_enemy_when_injured", attacker, victim, weapon );
|
||||
attacker addweaponstat( weapon, "kill_enemy_when_injured", 1 );
|
||||
if ( attacker hasperk( "specialty_bulletflinch" ) )
|
||||
{
|
||||
attacker addplayerstat( "perk_bulletflinch_kills", 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isDefined( attacker.deathtime ) && ( attacker.deathtime + 800 ) < time && !attacker isinvehicle() )
|
||||
{
|
||||
level.globalafterlifes++;
|
||||
processscoreevent( "kill_enemy_after_death", attacker, victim, weapon );
|
||||
victim recordkillmodifier( "posthumous" );
|
||||
}
|
||||
}
|
||||
if ( attacker.cur_death_streak >= 3 )
|
||||
{
|
||||
level.globalcomebacks++;
|
||||
processscoreevent( "comeback_from_deathstreak", attacker, victim, weapon );
|
||||
victim recordkillmodifier( "comeback" );
|
||||
}
|
||||
if ( isDefined( victim.beingmicrowavedby ) && weapon != "microwave_turret_mp" )
|
||||
{
|
||||
if ( victim.beingmicrowavedby != attacker && attacker isenemyplayer( victim.beingmicrowavedby ) == 0 )
|
||||
{
|
||||
scoregiven = processscoreevent( "microwave_turret_assist", victim.beingmicrowavedby, victim, weapon );
|
||||
if ( isDefined( scoregiven ) && isDefined( victim.beingmicrowavedby ) )
|
||||
{
|
||||
victim.beingmicrowavedby maps/mp/_challenges::earnedmicrowaveassistscore( scoregiven );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
attacker maps/mp/_challenges::killwhiledamagingwithhpm();
|
||||
}
|
||||
}
|
||||
if ( meansofdeath == "MOD_MELEE" && weapon != "riotshield_mp" )
|
||||
{
|
||||
attacker.pers[ "stabs" ]++;
|
||||
attacker.stabs = attacker.pers[ "stabs" ];
|
||||
vangles = victim.anglesondeath[ 1 ];
|
||||
pangles = attacker.anglesonkill[ 1 ];
|
||||
anglediff = angleClamp180( vangles - pangles );
|
||||
if ( anglediff > -30 && anglediff < 70 )
|
||||
{
|
||||
level.globalbackstabs++;
|
||||
processscoreevent( "backstabber_kill", attacker, victim, weapon );
|
||||
attacker addweaponstat( weapon, "backstabber_kill", 1 );
|
||||
attacker.pers[ "backstabs" ]++;
|
||||
attacker.backstabs = attacker.pers[ "backstabs" ];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isDefined( victim.firsttimedamaged ) && victim.firsttimedamaged == time )
|
||||
{
|
||||
if ( weaponclass == "weapon_sniper" )
|
||||
{
|
||||
attacker thread updateoneshotmultikills( victim, weapon, victim.firsttimedamaged );
|
||||
attacker addweaponstat( weapon, "kill_enemy_one_bullet", 1 );
|
||||
}
|
||||
}
|
||||
if ( isDefined( attacker.tookweaponfrom[ weapon ] ) && isDefined( attacker.tookweaponfrom[ weapon ].previousowner ) )
|
||||
{
|
||||
pickedupweapon = attacker.tookweaponfrom[ weapon ];
|
||||
if ( pickedupweapon.previousowner == victim )
|
||||
{
|
||||
processscoreevent( "kill_enemy_with_their_weapon", attacker, victim, weapon );
|
||||
attacker addweaponstat( weapon, "kill_enemy_with_their_weapon", 1 );
|
||||
if ( isDefined( pickedupweapon.sweapon ) && isDefined( pickedupweapon.smeansofdeath ) )
|
||||
{
|
||||
if ( pickedupweapon.sweapon == "knife_held_mp" && pickedupweapon.smeansofdeath == "MOD_MELEE" )
|
||||
{
|
||||
attacker addweaponstat( "knife_held_mp", "kill_enemy_with_their_weapon", 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( wasdefusing )
|
||||
{
|
||||
processscoreevent( "killed_bomb_defuser", attacker, victim, weapon );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( wasplanting )
|
||||
{
|
||||
processscoreevent( "killed_bomb_planter", attacker, victim, weapon );
|
||||
}
|
||||
}
|
||||
specificweaponkill( attacker, victim, weapon, killstreak );
|
||||
if ( !isDefined( killstreak ) && isDefined( attacker.dtptime ) && ( attacker.dtptime + 5000 ) > time )
|
||||
{
|
||||
attacker.dtptime = 0;
|
||||
if ( attacker getstance() == "prone" )
|
||||
{
|
||||
processscoreevent( "kill_enemy_recent_dive_prone", attacker, self, weapon );
|
||||
}
|
||||
}
|
||||
if ( isDefined( killstreak ) )
|
||||
{
|
||||
victim recordkillmodifier( "killstreak" );
|
||||
}
|
||||
attacker.cur_death_streak = 0;
|
||||
attacker disabledeathstreak();
|
||||
}
|
||||
|
||||
specificweaponkill( attacker, victim, weapon, killstreak )
|
||||
{
|
||||
switchweapon = weapon;
|
||||
if ( isDefined( killstreak ) )
|
||||
{
|
||||
switchweapon = killstreak;
|
||||
}
|
||||
switch( switchweapon )
|
||||
{
|
||||
case "crossbow_mp":
|
||||
case "explosive_bolt_mp":
|
||||
if ( isDefined( victim.explosiveinfo[ "stuckToPlayer" ] ) && victim.explosiveinfo[ "stuckToPlayer" ] == victim )
|
||||
{
|
||||
event = "crossbow_kill";
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "rcbomb_mp":
|
||||
event = "rcxd_kill";
|
||||
break;
|
||||
case "remote_missile_mp":
|
||||
event = "remote_missile_kill";
|
||||
break;
|
||||
case "missile_drone_mp":
|
||||
event = "missile_drone_kill";
|
||||
break;
|
||||
case "autoturret_mp":
|
||||
event = "sentry_gun_kill";
|
||||
break;
|
||||
case "planemortar_mp":
|
||||
event = "plane_mortar_kill";
|
||||
break;
|
||||
case "inventory_minigun_mp":
|
||||
case "minigun_mp":
|
||||
event = "death_machine_kill";
|
||||
break;
|
||||
case "inventory_m32_mp":
|
||||
case "m32_mp":
|
||||
event = "multiple_grenade_launcher_kill";
|
||||
break;
|
||||
case "qrdrone_mp":
|
||||
event = "qrdrone_kill";
|
||||
break;
|
||||
case "ai_tank_drop_mp":
|
||||
event = "aitank_kill";
|
||||
break;
|
||||
case "helicopter_guard_mp":
|
||||
event = "helicopter_guard_kill";
|
||||
break;
|
||||
case "straferun_mp":
|
||||
event = "strafe_run_kill";
|
||||
break;
|
||||
case "remote_mortar_mp":
|
||||
event = "remote_mortar_kill";
|
||||
break;
|
||||
case "helicopter_player_gunner_mp":
|
||||
event = "helicopter_gunner_kill";
|
||||
break;
|
||||
case "dogs_mp":
|
||||
event = "dogs_kill";
|
||||
break;
|
||||
case "missile_swarm_mp":
|
||||
event = "missile_swarm_kill";
|
||||
break;
|
||||
case "helicopter_comlink_mp":
|
||||
event = "helicopter_comlink_kill";
|
||||
break;
|
||||
case "microwaveturret_mp":
|
||||
event = "microwave_turret_kill";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
processscoreevent( event, attacker, victim, weapon );
|
||||
}
|
||||
|
||||
multikill( killcount, weapon )
|
||||
{
|
||||
/#
|
||||
assert( killcount > 1 );
|
||||
#/
|
||||
self maps/mp/_challenges::multikill( killcount, weapon );
|
||||
if ( killcount > 8 )
|
||||
{
|
||||
processscoreevent( "multikill_more_than_8", self, undefined, weapon );
|
||||
}
|
||||
else
|
||||
{
|
||||
processscoreevent( "multikill_" + killcount, self, undefined, weapon );
|
||||
}
|
||||
self recordmultikill( killcount );
|
||||
}
|
||||
|
||||
uninterruptedobitfeedkills( attacker, sweapon )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
wait 0,1;
|
||||
waittillslowprocessallowed();
|
||||
wait 0,1;
|
||||
maps/mp/_scoreevents::processscoreevent( "uninterrupted_obit_feed_kills", attacker, self, sweapon );
|
||||
}
|
||||
|
||||
is_weapon_valid( meansofdeath, weapon, weaponclass )
|
||||
{
|
||||
valid_weapon = 0;
|
||||
if ( get_distance_for_weapon( weapon, weaponclass ) == 0 )
|
||||
{
|
||||
valid_weapon = 0;
|
||||
}
|
||||
else if ( meansofdeath == "MOD_PISTOL_BULLET" || meansofdeath == "MOD_RIFLE_BULLET" )
|
||||
{
|
||||
valid_weapon = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( meansofdeath == "MOD_HEAD_SHOT" )
|
||||
{
|
||||
valid_weapon = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( weapon == "hatchet_mp" && meansofdeath == "MOD_IMPACT" )
|
||||
{
|
||||
valid_weapon = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return valid_weapon;
|
||||
}
|
||||
|
||||
updatemultikills( weapon, weaponclass, killstreak )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
self notify( "updateRecentKills" );
|
||||
self endon( "updateRecentKills" );
|
||||
baseweaponname = getreffromitemindex( getbaseweaponitemindex( weapon ) ) + "_mp";
|
||||
if ( !isDefined( self.recentkillcount ) )
|
||||
{
|
||||
self.recentkillcount = 0;
|
||||
}
|
||||
if ( !isDefined( self.recentkillcountweapon ) || self.recentkillcountweapon != baseweaponname )
|
||||
{
|
||||
self.recentkillcountsameweapon = 0;
|
||||
self.recentkillcountweapon = baseweaponname;
|
||||
}
|
||||
if ( !isDefined( killstreak ) )
|
||||
{
|
||||
self.recentkillcountsameweapon++;
|
||||
self.recentkillcount++;
|
||||
}
|
||||
if ( !isDefined( self.recent_lmg_smg_killcount ) )
|
||||
{
|
||||
self.recent_lmg_smg_killcount = 0;
|
||||
}
|
||||
if ( !isDefined( self.recentremotemissilekillcount ) )
|
||||
{
|
||||
self.recentremotemissilekillcount = 0;
|
||||
}
|
||||
if ( !isDefined( self.recentremotemissileattackerkillcount ) )
|
||||
{
|
||||
self.recentremotemissileattackerkillcount = 0;
|
||||
}
|
||||
if ( !isDefined( self.recentrcbombkillcount ) )
|
||||
{
|
||||
self.recentrcbombkillcount = 0;
|
||||
}
|
||||
if ( !isDefined( self.recentrcbombattackerkillcount ) )
|
||||
{
|
||||
self.recentrcbombattackerkillcount = 0;
|
||||
}
|
||||
if ( !isDefined( self.recentmglkillcount ) )
|
||||
{
|
||||
self.recentmglkillcount = 0;
|
||||
}
|
||||
if ( isDefined( weaponclass ) )
|
||||
{
|
||||
if ( weaponclass == "weapon_lmg" || weaponclass == "weapon_smg" )
|
||||
{
|
||||
if ( self playerads() < 1 )
|
||||
{
|
||||
self.recent_lmg_smg_killcount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( isDefined( killstreak ) )
|
||||
{
|
||||
switch( killstreak )
|
||||
{
|
||||
case "remote_missile_mp":
|
||||
self.recentremotemissilekillcount++;
|
||||
break;
|
||||
case "rcbomb_mp":
|
||||
self.recentrcbombkillcount++;
|
||||
break;
|
||||
case "inventory_m32_mp":
|
||||
case "m32_mp":
|
||||
self.recentmglkillcount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( self.recentkillcountsameweapon == 2 )
|
||||
{
|
||||
self addweaponstat( weapon, "multikill_2", 1 );
|
||||
}
|
||||
else if ( self.recentkillcountsameweapon == 3 )
|
||||
{
|
||||
self addweaponstat( weapon, "multikill_3", 1 );
|
||||
}
|
||||
self waittilltimeoutordeath( 4 );
|
||||
if ( self.recent_lmg_smg_killcount >= 3 )
|
||||
{
|
||||
self maps/mp/_challenges::multi_lmg_smg_kill();
|
||||
}
|
||||
if ( self.recentrcbombkillcount >= 2 )
|
||||
{
|
||||
self maps/mp/_challenges::multi_rcbomb_kill();
|
||||
}
|
||||
if ( self.recentmglkillcount >= 3 )
|
||||
{
|
||||
self maps/mp/_challenges::multi_mgl_kill();
|
||||
}
|
||||
if ( self.recentremotemissilekillcount >= 3 )
|
||||
{
|
||||
self maps/mp/_challenges::multi_remotemissile_kill();
|
||||
}
|
||||
if ( self.recentkillcount > 1 )
|
||||
{
|
||||
self multikill( self.recentkillcount, weapon );
|
||||
}
|
||||
self.recentkillcount = 0;
|
||||
self.recentkillcountsameweapon = 0;
|
||||
self.recentkillcountweapon = undefined;
|
||||
self.recent_lmg_smg_killcount = 0;
|
||||
self.recentremotemissilekillcount = 0;
|
||||
self.recentremotemissileattackerkillcount = 0;
|
||||
self.recentrcbombkillcount = 0;
|
||||
self.recentmglkillcount = 0;
|
||||
}
|
||||
|
||||
waittilltimeoutordeath( timeout )
|
||||
{
|
||||
self endon( "death" );
|
||||
wait timeout;
|
||||
}
|
||||
|
||||
updateoneshotmultikills( victim, weapon, firsttimedamaged )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self notify( "updateoneshotmultikills" + firsttimedamaged );
|
||||
self endon( "updateoneshotmultikills" + firsttimedamaged );
|
||||
if ( !isDefined( self.oneshotmultikills ) )
|
||||
{
|
||||
self.oneshotmultikills = 0;
|
||||
}
|
||||
self.oneshotmultikills++;
|
||||
wait 1;
|
||||
if ( self.oneshotmultikills > 1 )
|
||||
{
|
||||
processscoreevent( "kill_enemies_one_bullet", self, victim, weapon );
|
||||
}
|
||||
else
|
||||
{
|
||||
processscoreevent( "kill_enemy_one_bullet", self, victim, weapon );
|
||||
}
|
||||
self.oneshotmultikills = 0;
|
||||
}
|
||||
|
||||
get_distance_for_weapon( weapon, weaponclass )
|
||||
{
|
||||
distance = 0;
|
||||
switch( weaponclass )
|
||||
{
|
||||
case "weapon_smg":
|
||||
distance = 1562500;
|
||||
break;
|
||||
case "weapon_assault":
|
||||
distance = 2250000;
|
||||
break;
|
||||
case "weapon_lmg":
|
||||
distance = 2250000;
|
||||
break;
|
||||
case "weapon_sniper":
|
||||
distance = 3062500;
|
||||
break;
|
||||
case "weapon_pistol":
|
||||
distance = 490000;
|
||||
break;
|
||||
case "weapon_cqb":
|
||||
distance = 422500;
|
||||
break;
|
||||
case "weapon_special":
|
||||
if ( weapon == "knife_ballistic_mp" )
|
||||
{
|
||||
distance = 2250000;
|
||||
}
|
||||
else if ( weapon == "crossbow_mp" )
|
||||
{
|
||||
distance = 2250000;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( weapon == "metalstorm_mp" )
|
||||
{
|
||||
distance = 3062500;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "weapon_grenade":
|
||||
if ( weapon == "hatchet_mp" )
|
||||
{
|
||||
distance = 6250000;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
distance = 0;
|
||||
break;
|
||||
}
|
||||
return distance;
|
||||
}
|
||||
|
||||
decrementlastobituaryplayercountafterfade()
|
||||
{
|
||||
level endon( "reset_obituary_count" );
|
||||
wait 5;
|
||||
level.lastobituaryplayercount--;
|
||||
|
||||
/#
|
||||
assert( level.lastobituaryplayercount >= 0 );
|
||||
#/
|
||||
}
|
||||
|
||||
ongameend( data )
|
||||
{
|
||||
player = data.player;
|
||||
winner = data.winner;
|
||||
while ( isDefined( winner ) )
|
||||
{
|
||||
if ( level.teambased )
|
||||
{
|
||||
if ( winner != "tie" && player.team == winner )
|
||||
{
|
||||
processscoreevent( "won_match", player );
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
placement = level.placement[ "all" ];
|
||||
topthreeplayers = min( 3, placement.size );
|
||||
index = 0;
|
||||
while ( index < topthreeplayers )
|
||||
{
|
||||
if ( level.placement[ "all" ][ index ] == player )
|
||||
{
|
||||
processscoreevent( "won_match", player );
|
||||
return;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
processscoreevent( "completed_match", player );
|
||||
}
|
219
Multiplayer Core/patch_mp/maps/mp/_scrambler.gsc
Normal file
219
Multiplayer Core/patch_mp/maps/mp/_scrambler.gsc
Normal file
@ -0,0 +1,219 @@
|
||||
//checked includes match cerberus output
|
||||
#include maps/mp/gametypes/_damagefeedback;
|
||||
#include maps/mp/gametypes/_globallogic_player;
|
||||
#include maps/mp/_challenges;
|
||||
#include maps/mp/killstreaks/_emp;
|
||||
#include maps/mp/gametypes/_weaponobjects;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
level._effect[ "scrambler_enemy_light" ] = loadfx( "misc/fx_equip_light_red" );
|
||||
level._effect[ "scrambler_friendly_light" ] = loadfx( "misc/fx_equip_light_green" );
|
||||
level.scramblerweapon = "scrambler_mp";
|
||||
level.scramblerlength = 30;
|
||||
level.scramblerouterradiussq = 1000000;
|
||||
level.scramblerinnerradiussq = 360000;
|
||||
}
|
||||
|
||||
createscramblerwatcher() //checked matches cerberus output
|
||||
{
|
||||
watcher = self maps/mp/gametypes/_weaponobjects::createuseweaponobjectwatcher( "scrambler", "scrambler_mp", self.team );
|
||||
watcher.onspawn = ::onspawnscrambler;
|
||||
watcher.detonate = ::scramblerdetonate;
|
||||
watcher.stun = maps/mp/gametypes/_weaponobjects::weaponstun;
|
||||
watcher.stuntime = 5;
|
||||
watcher.reconmodel = "t5_weapon_scrambler_world_detect";
|
||||
watcher.hackable = 1;
|
||||
watcher.ondamage = ::watchscramblerdamage;
|
||||
}
|
||||
|
||||
onspawnscrambler( watcher, player ) //checked matches cerberus output
|
||||
{
|
||||
player endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self thread maps/mp/gametypes/_weaponobjects::onspawnuseweaponobject( watcher, player );
|
||||
player.scrambler = self;
|
||||
self setowner( player );
|
||||
self setteam( player.team );
|
||||
self.owner = player;
|
||||
self setclientflag( 3 );
|
||||
if ( !self maps/mp/_utility::ishacked() )
|
||||
{
|
||||
player addweaponstat( "scrambler_mp", "used", 1 );
|
||||
}
|
||||
self thread watchshutdown( player );
|
||||
level notify( "scrambler_spawn" );
|
||||
}
|
||||
|
||||
scramblerdetonate( attacker, weaponname ) //checked matches cerberus output
|
||||
{
|
||||
from_emp = maps/mp/killstreaks/_emp::isempweapon( weaponname );
|
||||
if ( !from_emp )
|
||||
{
|
||||
playfx( level._equipment_explode_fx, self.origin );
|
||||
}
|
||||
if ( self.owner isenemyplayer( attacker ) )
|
||||
{
|
||||
attacker maps/mp/_challenges::destroyedequipment( weaponname );
|
||||
}
|
||||
playsoundatposition( "dst_equipment_destroy", self.origin );
|
||||
self delete();
|
||||
}
|
||||
|
||||
watchshutdown( player ) //checked matches cerberus output
|
||||
{
|
||||
self waittill_any( "death", "hacked" );
|
||||
level notify( "scrambler_death" );
|
||||
if ( isDefined( player ) )
|
||||
{
|
||||
player.scrambler = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
destroyent() //checked matches cerberus output
|
||||
{
|
||||
self delete();
|
||||
}
|
||||
|
||||
watchscramblerdamage( watcher ) //checked changed to match beta dump
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "hacked" );
|
||||
self setcandamage( 1 );
|
||||
damagemax = 100;
|
||||
if ( !self maps/mp/_utility::ishacked() )
|
||||
{
|
||||
self.damagetaken = 0;
|
||||
}
|
||||
while ( 1 )
|
||||
{
|
||||
self.maxhealth = 100000;
|
||||
self.health = self.maxhealth;
|
||||
self waittill( "damage", damage, attacker, direction, point, type, tagname, modelname, partname, weaponname, idflags );
|
||||
if ( !isDefined( attacker ) || !isplayer( attacker ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( level.teambased && attacker.team == self.owner.team && attacker != self.owner )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( isDefined( weaponname ) )
|
||||
{
|
||||
switch( weaponname )
|
||||
{
|
||||
case "concussion_grenade_mp":
|
||||
case "flash_grenade_mp":
|
||||
if ( watcher.stuntime > 0 )
|
||||
{
|
||||
self thread maps/mp/gametypes/_weaponobjects::stunstart( watcher, watcher.stuntime );
|
||||
}
|
||||
if ( level.teambased && self.owner.team != attacker.team )
|
||||
{
|
||||
if ( maps/mp/gametypes/_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
{
|
||||
attacker maps/mp/gametypes/_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
}
|
||||
else if ( !level.teambased && self.owner != attacker )
|
||||
{
|
||||
if ( maps/mp/gametypes/_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
{
|
||||
attacker maps/mp/gametypes/_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
}
|
||||
continue;
|
||||
case "emp_grenade_mp":
|
||||
damage = damagemax;
|
||||
default:
|
||||
if ( maps/mp/gametypes/_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
{
|
||||
attacker maps/mp/gametypes/_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
weaponname = "";
|
||||
}
|
||||
if ( isplayer( attacker ) && level.teambased && isDefined( attacker.team ) && self.owner.team == attacker.team && attacker != self.owner )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( type == "MOD_MELEE" )
|
||||
{
|
||||
self.damagetaken = damagemax;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.damagetaken += damage;
|
||||
}
|
||||
if ( self.damagetaken >= damagemax )
|
||||
{
|
||||
watcher thread maps/mp/gametypes/_weaponobjects::waitanddetonate( self, 0, attacker, weaponname );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ownersameteam( owner1, owner2 ) //checked matches cerberus output
|
||||
{
|
||||
if ( !level.teambased )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( !isDefined( owner1 ) || !isDefined( owner2 ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( !isDefined( owner1.team ) || !isDefined( owner2.team ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return owner1.team == owner2.team;
|
||||
}
|
||||
|
||||
checkscramblerstun() //checked partially changed to match cerberus output see info.md
|
||||
{
|
||||
scramblers = getentarray( "grenade", "classname" );
|
||||
if ( isDefined( self.name ) && self.name == "scrambler_mp" )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < scramblers.size )
|
||||
{
|
||||
scrambler = scramblers[ i ];
|
||||
if ( !isalive( scrambler ) )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if ( !isDefined( scrambler.name ) )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if ( scrambler.name != "scrambler_mp" )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if ( ownersameteam( self.owner, scrambler.owner ) )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
flattenedselforigin = ( self.origin[ 0 ], self.origin[ 1 ], 0 );
|
||||
flattenedscramblerorigin = ( scrambler.origin[ 0 ], scrambler.origin[ 1 ], 0 );
|
||||
if ( distancesquared( flattenedselforigin, flattenedscramblerorigin ) < level.scramblerouterradiussq )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
342
Multiplayer Core/patch_mp/maps/mp/_script_gen.gsc
Normal file
342
Multiplayer Core/patch_mp/maps/mp/_script_gen.gsc
Normal file
@ -0,0 +1,342 @@
|
||||
#include maps/mp/_script_gen;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
|
||||
script_gen_dump_checksaved()
|
||||
{
|
||||
signatures = getarraykeys( level.script_gen_dump );
|
||||
i = 0;
|
||||
while ( i < signatures.size )
|
||||
{
|
||||
if ( !isDefined( level.script_gen_dump2[ signatures[ i ] ] ) )
|
||||
{
|
||||
level.script_gen_dump_reasons[ level.script_gen_dump_reasons.size ] = "Signature unmatched( removed feature ): " + signatures[ i ];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
script_gen_dump()
|
||||
{
|
||||
/#
|
||||
script_gen_dump_checksaved();
|
||||
if ( !level.script_gen_dump_reasons.size )
|
||||
{
|
||||
flag_set( "scriptgen_done" );
|
||||
return;
|
||||
}
|
||||
firstrun = 0;
|
||||
if ( level.bscriptgened )
|
||||
{
|
||||
println( " " );
|
||||
println( " " );
|
||||
println( " " );
|
||||
println( "^2 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- " );
|
||||
println( "^3Dumping scriptgen dump for these reasons" );
|
||||
println( "^2 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- " );
|
||||
i = 0;
|
||||
while ( i < level.script_gen_dump_reasons.size )
|
||||
{
|
||||
if ( issubstr( level.script_gen_dump_reasons[ i ], "nowrite" ) )
|
||||
{
|
||||
substr = getsubstr( level.script_gen_dump_reasons[ i ], 15 );
|
||||
println( ( i + ". ) " ) + substr );
|
||||
}
|
||||
else
|
||||
{
|
||||
println( ( i + ". ) " ) + level.script_gen_dump_reasons[ i ] );
|
||||
}
|
||||
if ( level.script_gen_dump_reasons[ i ] == "First run" )
|
||||
{
|
||||
firstrun = 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
println( "^2 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- " );
|
||||
println( " " );
|
||||
if ( firstrun )
|
||||
{
|
||||
println( "for First Run make sure you delete all of the vehicle precache script calls, createart calls, createfx calls( most commonly placed in maps\\" + level.script + "_fx.gsc ) " );
|
||||
println( " " );
|
||||
println( "replace:" );
|
||||
println( "maps\\_load::main( 1 );" );
|
||||
println( " " );
|
||||
println( "with( don't forget to add this file to P4 ):" );
|
||||
println( "maps\\scriptgen\\" + level.script + "_scriptgen::main();" );
|
||||
println( " " );
|
||||
}
|
||||
println( "^2 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- " );
|
||||
println( " " );
|
||||
println( "^2 / \\ / \\ / \\" );
|
||||
println( "^2scroll up" );
|
||||
println( "^2 / \\ / \\ / \\" );
|
||||
println( " " );
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
filename = "scriptgen/" + level.script + "_scriptgen.gsc";
|
||||
csvfilename = "zone_source/" + level.script + ".csv";
|
||||
if ( level.bscriptgened )
|
||||
{
|
||||
file = openfile( filename, "write" );
|
||||
}
|
||||
else
|
||||
{
|
||||
file = 0;
|
||||
}
|
||||
assert( file != -1, "File not writeable( check it and and restart the map ): " + filename );
|
||||
script_gen_dumpprintln( file, "// script generated script do not write your own script here it will go away if you do." );
|
||||
script_gen_dumpprintln( file, "main()" );
|
||||
script_gen_dumpprintln( file, "{" );
|
||||
script_gen_dumpprintln( file, "" );
|
||||
script_gen_dumpprintln( file, "\tlevel.script_gen_dump = [];" );
|
||||
script_gen_dumpprintln( file, "" );
|
||||
signatures = getarraykeys( level.script_gen_dump );
|
||||
i = 0;
|
||||
while ( i < signatures.size )
|
||||
{
|
||||
if ( !issubstr( level.script_gen_dump[ signatures[ i ] ], "nowrite" ) )
|
||||
{
|
||||
script_gen_dumpprintln( file, "\t" + level.script_gen_dump[ signatures[ i ] ] );
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < signatures.size )
|
||||
{
|
||||
if ( !issubstr( level.script_gen_dump[ signatures[ i ] ], "nowrite" ) )
|
||||
{
|
||||
script_gen_dumpprintln( file, "\tlevel.script_gen_dump[ " + """ + signatures[ i ] + """ + " ] = " + """ + signatures[ i ] + """ + ";" );
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
script_gen_dumpprintln( file, "\tlevel.script_gen_dump[ " + """ + signatures[ i ] + """ + " ] = " + ""nowrite"" + ";" );
|
||||
}
|
||||
i++;
|
||||
}
|
||||
script_gen_dumpprintln( file, "" );
|
||||
keys1 = undefined;
|
||||
keys2 = undefined;
|
||||
if ( isDefined( level.sg_precacheanims ) )
|
||||
{
|
||||
keys1 = getarraykeys( level.sg_precacheanims );
|
||||
}
|
||||
while ( isDefined( keys1 ) )
|
||||
{
|
||||
i = 0;
|
||||
while ( i < keys1.size )
|
||||
{
|
||||
script_gen_dumpprintln( file, "\tanim_precach_" + keys1[ i ] + "();" );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
script_gen_dumpprintln( file, "\tmaps\\_load::main( 1, " + level.bcsvgened + ", 1 );" );
|
||||
script_gen_dumpprintln( file, "}" );
|
||||
script_gen_dumpprintln( file, "" );
|
||||
if ( isDefined( level.sg_precacheanims ) )
|
||||
{
|
||||
keys1 = getarraykeys( level.sg_precacheanims );
|
||||
}
|
||||
while ( isDefined( keys1 ) )
|
||||
{
|
||||
i = 0;
|
||||
while ( i < keys1.size )
|
||||
{
|
||||
script_gen_dumpprintln( file, "#using_animtree( "" + keys1[ i ] + "" );" );
|
||||
script_gen_dumpprintln( file, "anim_precach_" + keys1[ i ] + "()" );
|
||||
script_gen_dumpprintln( file, "{" );
|
||||
script_gen_dumpprintln( file, "\tlevel.sg_animtree[ "" + keys1[ i ] + "" ] = #animtree;" );
|
||||
keys2 = getarraykeys( level.sg_precacheanims[ keys1[ i ] ] );
|
||||
while ( isDefined( keys2 ) )
|
||||
{
|
||||
j = 0;
|
||||
while ( j < keys2.size )
|
||||
{
|
||||
script_gen_dumpprintln( file, "\tlevel.sg_anim[ "" + keys2[ j ] + "" ] = %" + keys2[ j ] + ";" );
|
||||
j++;
|
||||
}
|
||||
}
|
||||
script_gen_dumpprintln( file, "}" );
|
||||
script_gen_dumpprintln( file, "" );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if ( level.bscriptgened )
|
||||
{
|
||||
saved = closefile( file );
|
||||
}
|
||||
else
|
||||
{
|
||||
saved = 1;
|
||||
}
|
||||
if ( level.bcsvgened )
|
||||
{
|
||||
csvfile = openfile( csvfilename, "write" );
|
||||
}
|
||||
else
|
||||
{
|
||||
csvfile = 0;
|
||||
}
|
||||
assert( csvfile != -1, "File not writeable( check it and and restart the map ): " + csvfilename );
|
||||
signatures = getarraykeys( level.script_gen_dump );
|
||||
i = 0;
|
||||
while ( i < signatures.size )
|
||||
{
|
||||
script_gen_csvdumpprintln( csvfile, signatures[ i ] );
|
||||
i++;
|
||||
}
|
||||
if ( level.bcsvgened )
|
||||
{
|
||||
csvfilesaved = closefile( csvfile );
|
||||
}
|
||||
else
|
||||
{
|
||||
csvfilesaved = 1;
|
||||
}
|
||||
assert( csvfilesaved == 1, "csv not saved( see above message? ): " + csvfilename );
|
||||
assert( saved == 1, "map not saved( see above message? ): " + filename );
|
||||
#/
|
||||
/#
|
||||
assert( !level.bscriptgened, "SCRIPTGEN generated: follow instructions listed above this error in the console" );
|
||||
#/
|
||||
if ( level.bscriptgened )
|
||||
{
|
||||
/#
|
||||
assertmsg( "SCRIPTGEN updated: Rebuild fast file and run map again" );
|
||||
#/
|
||||
}
|
||||
flag_set( "scriptgen_done" );
|
||||
}
|
||||
|
||||
script_gen_csvdumpprintln( file, signature )
|
||||
{
|
||||
prefix = undefined;
|
||||
writtenprefix = undefined;
|
||||
path = "";
|
||||
extension = "";
|
||||
if ( issubstr( signature, "ignore" ) )
|
||||
{
|
||||
prefix = "ignore";
|
||||
}
|
||||
else if ( issubstr( signature, "col_map_sp" ) )
|
||||
{
|
||||
prefix = "col_map_sp";
|
||||
}
|
||||
else if ( issubstr( signature, "gfx_map" ) )
|
||||
{
|
||||
prefix = "gfx_map";
|
||||
}
|
||||
else if ( issubstr( signature, "rawfile" ) )
|
||||
{
|
||||
prefix = "rawfile";
|
||||
}
|
||||
else if ( issubstr( signature, "sound" ) )
|
||||
{
|
||||
prefix = "sound";
|
||||
}
|
||||
else if ( issubstr( signature, "xmodel" ) )
|
||||
{
|
||||
prefix = "xmodel";
|
||||
}
|
||||
else if ( issubstr( signature, "xanim" ) )
|
||||
{
|
||||
prefix = "xanim";
|
||||
}
|
||||
else if ( issubstr( signature, "item" ) )
|
||||
{
|
||||
prefix = "item";
|
||||
writtenprefix = "weapon";
|
||||
path = "sp/";
|
||||
}
|
||||
else if ( issubstr( signature, "fx" ) )
|
||||
{
|
||||
prefix = "fx";
|
||||
}
|
||||
else if ( issubstr( signature, "menu" ) )
|
||||
{
|
||||
prefix = "menu";
|
||||
writtenprefix = "menufile";
|
||||
path = "ui / scriptmenus/";
|
||||
extension = ".menu";
|
||||
}
|
||||
else if ( issubstr( signature, "rumble" ) )
|
||||
{
|
||||
prefix = "rumble";
|
||||
writtenprefix = "rawfile";
|
||||
path = "rumble/";
|
||||
}
|
||||
else if ( issubstr( signature, "shader" ) )
|
||||
{
|
||||
prefix = "shader";
|
||||
writtenprefix = "material";
|
||||
}
|
||||
else if ( issubstr( signature, "shock" ) )
|
||||
{
|
||||
prefix = "shock";
|
||||
writtenprefix = "rawfile";
|
||||
extension = ".shock";
|
||||
path = "shock/";
|
||||
}
|
||||
else if ( issubstr( signature, "string" ) )
|
||||
{
|
||||
prefix = "string";
|
||||
/#
|
||||
assertmsg( "string not yet supported by scriptgen" );
|
||||
#/
|
||||
}
|
||||
else if ( issubstr( signature, "turret" ) )
|
||||
{
|
||||
prefix = "turret";
|
||||
writtenprefix = "weapon";
|
||||
path = "sp/";
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( issubstr( signature, "vehicle" ) )
|
||||
{
|
||||
prefix = "vehicle";
|
||||
writtenprefix = "rawfile";
|
||||
path = "vehicles/";
|
||||
}
|
||||
}
|
||||
if ( !isDefined( prefix ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( !isDefined( writtenprefix ) )
|
||||
{
|
||||
string = ( prefix + ", " ) + getsubstr( signature, prefix.size + 1, signature.size );
|
||||
}
|
||||
else
|
||||
{
|
||||
string = ( writtenprefix + ", " ) + path + getsubstr( signature, prefix.size + 1, signature.size ) + extension;
|
||||
}
|
||||
/#
|
||||
if ( file == -1 || !level.bcsvgened )
|
||||
{
|
||||
println( string );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintln( file, string );
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
script_gen_dumpprintln( file, string )
|
||||
{
|
||||
/#
|
||||
if ( file == -1 || !level.bscriptgened )
|
||||
{
|
||||
println( string );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintln( file, string );
|
||||
#/
|
||||
}
|
||||
}
|
218
Multiplayer Core/patch_mp/maps/mp/_sensor_grenade.gsc
Normal file
218
Multiplayer Core/patch_mp/maps/mp/_sensor_grenade.gsc
Normal file
@ -0,0 +1,218 @@
|
||||
//checked includes match cerberus output
|
||||
#include maps/mp/gametypes/_damagefeedback;
|
||||
#include maps/mp/gametypes/_globallogic_player;
|
||||
#include maps/mp/_utility;
|
||||
#include maps/mp/_scoreevents;
|
||||
#include maps/mp/_challenges;
|
||||
#include maps/mp/killstreaks/_emp;
|
||||
#include maps/mp/_hacker_tool;
|
||||
#include maps/mp/gametypes/_weaponobjects;
|
||||
#include common_scripts/utility;
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
level.isplayertrackedfunc = ::isplayertracked;
|
||||
}
|
||||
|
||||
createsensorgrenadewatcher() //checked matches cerberus output
|
||||
{
|
||||
watcher = self maps/mp/gametypes/_weaponobjects::createuseweaponobjectwatcher( "sensor_grenade", "sensor_grenade_mp", self.team );
|
||||
watcher.headicon = 0;
|
||||
watcher.onspawn = ::onspawnsensorgrenade;
|
||||
watcher.detonate = ::sensorgrenadedestroyed;
|
||||
watcher.stun = maps/mp/gametypes/_weaponobjects::weaponstun;
|
||||
watcher.stuntime = 0;
|
||||
watcher.reconmodel = "t6_wpn_motion_sensor_world_detect";
|
||||
watcher.ondamage = ::watchsensorgrenadedamage;
|
||||
watcher.enemydestroy = 1;
|
||||
}
|
||||
|
||||
onspawnsensorgrenade( watcher, player ) //checked matches cerberus output
|
||||
{
|
||||
self endon( "death" );
|
||||
self thread maps/mp/gametypes/_weaponobjects::onspawnuseweaponobject( watcher, player );
|
||||
self setowner( player );
|
||||
self setteam( player.team );
|
||||
self.owner = player;
|
||||
self playloopsound( "fly_sensor_nade_lp" );
|
||||
self maps/mp/_hacker_tool::registerwithhackertool( level.equipmenthackertoolradius, level.equipmenthackertooltimems );
|
||||
player addweaponstat( "sensor_grenade_mp", "used", 1 );
|
||||
self thread watchforstationary( player );
|
||||
self thread watchforexplode( player );
|
||||
}
|
||||
|
||||
watchforstationary( owner ) //checked matches cerberus output
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "hacked" );
|
||||
self endon( "explode" );
|
||||
owner endon( "death" );
|
||||
owner endon( "disconnect" );
|
||||
self waittill( "stationary" );
|
||||
checkfortracking( self.origin );
|
||||
}
|
||||
|
||||
watchforexplode( owner ) //checked matches cerberus output
|
||||
{
|
||||
self endon( "hacked" );
|
||||
self endon( "delete" );
|
||||
owner endon( "death" );
|
||||
owner endon( "disconnect" );
|
||||
self waittill( "explode", origin );
|
||||
checkfortracking( origin + ( 0, 0, 1 ) );
|
||||
}
|
||||
|
||||
checkfortracking( origin ) //checked changed to match cerberus output
|
||||
{
|
||||
if ( isDefined( self.owner ) == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
players = level.players;
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( player isenemyplayer( self.owner ) )
|
||||
{
|
||||
if ( !player hasperk( "specialty_nomotionsensor" ) )
|
||||
{
|
||||
if ( distancesquared( player.origin, origin ) < 562500 )
|
||||
{
|
||||
trace = bullettrace( origin, player.origin + vectorScale( ( 0, 0, 1 ), 12 ), 0, player );
|
||||
if ( trace[ "fraction" ] == 1 )
|
||||
{
|
||||
self.owner tracksensorgrenadevictim( player );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tracksensorgrenadevictim( victim ) //checked matches cerberus output
|
||||
{
|
||||
if ( !isDefined( self.sensorgrenadedata ) )
|
||||
{
|
||||
self.sensorgrenadedata = [];
|
||||
}
|
||||
if ( !isDefined( self.sensorgrenadedata[ victim.clientid ] ) )
|
||||
{
|
||||
self.sensorgrenadedata[ victim.clientid ] = getTime();
|
||||
}
|
||||
}
|
||||
|
||||
isplayertracked( player, time ) //checked matches cerberus output
|
||||
{
|
||||
playertracked = 0;
|
||||
if ( isDefined( self.sensorgrenadedata ) && isDefined( self.sensorgrenadedata[ player.clientid ] ) )
|
||||
{
|
||||
if ( ( self.sensorgrenadedata[ player.clientid ] + 10000 ) > time )
|
||||
{
|
||||
playertracked = 1;
|
||||
}
|
||||
}
|
||||
return playertracked;
|
||||
}
|
||||
|
||||
sensorgrenadedestroyed( attacker, weaponname ) //checked matches cerberus output
|
||||
{
|
||||
from_emp = maps/mp/killstreaks/_emp::isempweapon( weaponname );
|
||||
if ( !from_emp )
|
||||
{
|
||||
playfx( level._equipment_explode_fx, self.origin );
|
||||
}
|
||||
if ( isDefined( attacker ) )
|
||||
{
|
||||
if ( self.owner isenemyplayer( attacker ) )
|
||||
{
|
||||
attacker maps/mp/_challenges::destroyedequipment( weaponname );
|
||||
maps/mp/_scoreevents::processscoreevent( "destroyed_motion_sensor", attacker, self.owner, weaponname );
|
||||
}
|
||||
}
|
||||
playsoundatposition( "dst_equipment_destroy", self.origin );
|
||||
self delete();
|
||||
}
|
||||
|
||||
watchsensorgrenadedamage( watcher ) //checked changed to match beta dump
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "hacked" );
|
||||
self setcandamage( 1 );
|
||||
damagemax = 1;
|
||||
if ( !self maps/mp/_utility::ishacked() )
|
||||
{
|
||||
self.damagetaken = 0;
|
||||
}
|
||||
while ( 1 )
|
||||
{
|
||||
self.maxhealth = 100000;
|
||||
self.health = self.maxhealth;
|
||||
self waittill( "damage", damage, attacker, direction, point, type, tagname, modelname, partname, weaponname, idflags );
|
||||
if ( !isDefined( attacker ) || !isplayer( attacker ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( level.teambased && isplayer( attacker ) )
|
||||
{
|
||||
if ( !level.hardcoremode && self.owner.team == attacker.pers[ "team" ] && self.owner != attacker )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ( isDefined( weaponname ) )
|
||||
{
|
||||
switch( weaponname )
|
||||
{
|
||||
case "concussion_grenade_mp":
|
||||
case "flash_grenade_mp":
|
||||
if ( watcher.stuntime > 0 )
|
||||
{
|
||||
self thread maps/mp/gametypes/_weaponobjects::stunstart( watcher, watcher.stuntime );
|
||||
}
|
||||
if ( level.teambased && self.owner.team != attacker.team )
|
||||
{
|
||||
if ( maps/mp/gametypes/_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
{
|
||||
attacker maps/mp/gametypes/_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !level.teambased && self.owner != attacker )
|
||||
{
|
||||
if ( maps/mp/gametypes/_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
{
|
||||
attacker maps/mp/gametypes/_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
case "emp_grenade_mp":
|
||||
damage = damagemax;
|
||||
default:
|
||||
if ( maps/mp/gametypes/_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
{
|
||||
attacker maps/mp/gametypes/_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
weaponname = "";
|
||||
}
|
||||
if ( type == "MOD_MELEE" )
|
||||
{
|
||||
self.damagetaken = damagemax;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.damagetaken += damage;
|
||||
}
|
||||
if ( self.damagetaken >= damagemax )
|
||||
{
|
||||
watcher thread maps/mp/gametypes/_weaponobjects::waitanddetonate( self, 0, attacker, weaponname );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
61
Multiplayer Core/patch_mp/maps/mp/_smokegrenade.gsc
Normal file
61
Multiplayer Core/patch_mp/maps/mp/_smokegrenade.gsc
Normal file
@ -0,0 +1,61 @@
|
||||
//includes match cerberus output
|
||||
#include maps/mp/killstreaks/_dogs;
|
||||
#include maps/mp/killstreaks/_airsupport;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
level.willypetedamageradius = 300;
|
||||
level.willypetedamageheight = 128;
|
||||
level.sound_smoke_start = "wpn_smoke_hiss_start";
|
||||
level.sound_smoke_loop = "wpn_smoke_hiss_lp";
|
||||
level.sound_smoke_stop = "wpn_smoke_hiss_end";
|
||||
level.smokesoundduration = 8;
|
||||
level.fx_smokegrenade_single = "smoke_center_mp";
|
||||
precacheitem( level.fx_smokegrenade_single );
|
||||
}
|
||||
|
||||
watchsmokegrenadedetonation( owner ) //checked matches cerberus output
|
||||
{
|
||||
owner addweaponstat( "willy_pete_mp", "used", 1 );
|
||||
self waittill( "explode", position, surface );
|
||||
if ( !isDefined( level.water_duds ) || level.water_duds == 1 )
|
||||
{
|
||||
if ( isDefined( surface ) && surface == "water" )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
onefoot = vectorScale( ( 0, 0, 1 ), 12 );
|
||||
startpos = position + onefoot;
|
||||
ent = spawntimedfx( level.fx_smokegrenade_single, position, ( 0, 0, 1 ), 12 );
|
||||
ent thread blocksight();
|
||||
if ( isDefined( owner ) )
|
||||
{
|
||||
owner.smokegrenadetime = getTime();
|
||||
owner.smokegrenadeposition = position;
|
||||
}
|
||||
thread playsmokesound( position, level.smokesoundduration, level.sound_smoke_start, level.sound_smoke_stop, level.sound_smoke_loop );
|
||||
damageeffectarea( owner, startpos, level.willypetedamageradius, level.willypetedamageheight, undefined );
|
||||
}
|
||||
|
||||
damageeffectarea( owner, position, radius, height, killcament ) //checked matches cerberus output
|
||||
{
|
||||
effectarea = spawn( "trigger_radius", position, 0, radius, height );
|
||||
owner thread maps/mp/killstreaks/_dogs::flash_dogs( effectarea );
|
||||
effectarea delete();
|
||||
}
|
||||
|
||||
blocksight() //checked matches cerberus output
|
||||
{
|
||||
self endon( "death" );
|
||||
radius = 64;
|
||||
fxblocksight( self, radius );
|
||||
for ( ;; )
|
||||
{
|
||||
wait 0.75;
|
||||
radius = clamp( radius * 1.5, 10, 150 );
|
||||
fxblocksight( self, radius );
|
||||
}
|
||||
}
|
13
Multiplayer Core/patch_mp/maps/mp/_sticky_grenade.gsc
Normal file
13
Multiplayer Core/patch_mp/maps/mp/_sticky_grenade.gsc
Normal file
@ -0,0 +1,13 @@
|
||||
//checked includes match cerberus output
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init() //checked matches cerberus output
|
||||
{
|
||||
loadfx( "weapon/crossbow/fx_trail_crossbow_blink_grn_os" );
|
||||
loadfx( "weapon/crossbow/fx_trail_crossbow_blink_red_os" );
|
||||
}
|
||||
|
||||
watch_bolt_detonation( owner ) //checked matches cerberus output
|
||||
{
|
||||
}
|
566
Multiplayer Core/patch_mp/maps/mp/_tabun.gsc
Normal file
566
Multiplayer Core/patch_mp/maps/mp/_tabun.gsc
Normal file
@ -0,0 +1,566 @@
|
||||
#include maps/mp/gametypes/_battlechatter_mp;
|
||||
#include maps/mp/killstreaks/_dogs;
|
||||
#include maps/mp/killstreaks/_airsupport;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level.tabuninitialgasshockduration = weapons_get_dvar_int( "scr_tabunInitialGasShockDuration", "7" );
|
||||
level.tabunwalkingasshockduration = weapons_get_dvar_int( "scr_tabunWalkInGasShockDuration", "4" );
|
||||
level.tabungasshockradius = weapons_get_dvar_int( "scr_tabun_shock_radius", "185" );
|
||||
level.tabungasshockheight = weapons_get_dvar_int( "scr_tabun_shock_height", "20" );
|
||||
level.tabungaspoisonradius = weapons_get_dvar_int( "scr_tabun_effect_radius", "185" );
|
||||
level.tabungaspoisonheight = weapons_get_dvar_int( "scr_tabun_shock_height", "20" );
|
||||
level.tabungasduration = weapons_get_dvar_int( "scr_tabunGasDuration", "8" );
|
||||
level.poisonduration = weapons_get_dvar_int( "scr_poisonDuration", "8" );
|
||||
level.poisondamage = weapons_get_dvar_int( "scr_poisonDamage", "13" );
|
||||
level.poisondamagehardcore = weapons_get_dvar_int( "scr_poisonDamageHardcore", "5" );
|
||||
level.fx_tabun_0 = "tabun_tiny_mp";
|
||||
level.fx_tabun_1 = "tabun_small_mp";
|
||||
level.fx_tabun_2 = "tabun_medium_mp";
|
||||
level.fx_tabun_3 = "tabun_large_mp";
|
||||
level.fx_tabun_single = "tabun_center_mp";
|
||||
precacheitem( level.fx_tabun_0 );
|
||||
precacheitem( level.fx_tabun_1 );
|
||||
precacheitem( level.fx_tabun_2 );
|
||||
precacheitem( level.fx_tabun_3 );
|
||||
precacheitem( level.fx_tabun_single );
|
||||
level.fx_tabun_radius0 = weapons_get_dvar_int( "scr_fx_tabun_radius0", 55 );
|
||||
level.fx_tabun_radius1 = weapons_get_dvar_int( "scr_fx_tabun_radius1", 55 );
|
||||
level.fx_tabun_radius2 = weapons_get_dvar_int( "scr_fx_tabun_radius2", 50 );
|
||||
level.fx_tabun_radius3 = weapons_get_dvar_int( "scr_fx_tabun_radius3", 25 );
|
||||
level.sound_tabun_start = "wpn_gas_hiss_start";
|
||||
level.sound_tabun_loop = "wpn_gas_hiss_lp";
|
||||
level.sound_tabun_stop = "wpn_gas_hiss_end";
|
||||
level.sound_shock_tabun_start = "";
|
||||
level.sound_shock_tabun_loop = "";
|
||||
level.sound_shock_tabun_stop = "";
|
||||
/#
|
||||
level thread checkdvarupdates();
|
||||
#/
|
||||
}
|
||||
|
||||
checkdvarupdates()
|
||||
{
|
||||
while ( 1 )
|
||||
{
|
||||
level.tabungaspoisonradius = weapons_get_dvar_int( "scr_tabun_effect_radius", level.tabungaspoisonradius );
|
||||
level.tabungaspoisonheight = weapons_get_dvar_int( "scr_tabun_shock_height", level.tabungaspoisonheight );
|
||||
level.tabungasshockradius = weapons_get_dvar_int( "scr_tabun_shock_radius", level.tabungasshockradius );
|
||||
level.tabungasshockheight = weapons_get_dvar_int( "scr_tabun_shock_height", level.tabungasshockheight );
|
||||
level.tabuninitialgasshockduration = weapons_get_dvar_int( "scr_tabunInitialGasShockDuration", level.tabuninitialgasshockduration );
|
||||
level.tabunwalkingasshockduration = weapons_get_dvar_int( "scr_tabunWalkInGasShockDuration", level.tabunwalkingasshockduration );
|
||||
level.tabungasduration = weapons_get_dvar_int( "scr_tabunGasDuration", level.tabungasduration );
|
||||
level.poisonduration = weapons_get_dvar_int( "scr_poisonDuration", level.poisonduration );
|
||||
level.poisondamage = weapons_get_dvar_int( "scr_poisonDamage", level.poisondamage );
|
||||
level.poisondamagehardcore = weapons_get_dvar_int( "scr_poisonDamageHardcore", level.poisondamagehardcore );
|
||||
level.fx_tabun_radius0 = weapons_get_dvar_int( "scr_fx_tabun_radius0", level.fx_tabun_radius0 );
|
||||
level.fx_tabun_radius1 = weapons_get_dvar_int( "scr_fx_tabun_radius1", level.fx_tabun_radius1 );
|
||||
level.fx_tabun_radius2 = weapons_get_dvar_int( "scr_fx_tabun_radius2", level.fx_tabun_radius2 );
|
||||
level.fx_tabun_radius3 = weapons_get_dvar_int( "scr_fx_tabun_radius3", level.fx_tabun_radius3 );
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
|
||||
watchtabungrenadedetonation( owner )
|
||||
{
|
||||
self waittill( "explode", position, surface );
|
||||
if ( !isDefined( level.water_duds ) || level.water_duds == 1 )
|
||||
{
|
||||
if ( isDefined( surface ) && surface == "water" )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ( weapons_get_dvar_int( "scr_enable_new_tabun", 1 ) )
|
||||
{
|
||||
generatelocations( position, owner );
|
||||
}
|
||||
else
|
||||
{
|
||||
singlelocation( position, owner );
|
||||
}
|
||||
}
|
||||
|
||||
damageeffectarea( owner, position, radius, height, killcament )
|
||||
{
|
||||
shockeffectarea = spawn( "trigger_radius", position, 0, radius, height );
|
||||
gaseffectarea = spawn( "trigger_radius", position, 0, radius, height );
|
||||
/#
|
||||
if ( getDvarInt( "scr_draw_triggers" ) )
|
||||
{
|
||||
level thread drawcylinder( position, radius, height, undefined, "tabun_draw_cylinder_stop" );
|
||||
#/
|
||||
}
|
||||
owner thread maps/mp/killstreaks/_dogs::flash_dogs( shockeffectarea );
|
||||
owner thread maps/mp/killstreaks/_dogs::flash_dogs( gaseffectarea );
|
||||
loopwaittime = 0,5;
|
||||
durationoftabun = level.tabungasduration;
|
||||
while ( durationoftabun > 0 )
|
||||
{
|
||||
players = get_players();
|
||||
i = 0;
|
||||
while ( i < players.size )
|
||||
{
|
||||
if ( level.friendlyfire == 0 )
|
||||
{
|
||||
if ( players[ i ] != owner )
|
||||
{
|
||||
if ( !isDefined( owner ) || !isDefined( owner.team ) )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( level.teambased && players[ i ].team == owner.team )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !isDefined( players[ i ].inpoisonarea ) || players[ i ].inpoisonarea == 0 )
|
||||
{
|
||||
if ( players[ i ] istouching( gaseffectarea ) && players[ i ].sessionstate == "playing" )
|
||||
{
|
||||
if ( !players[ i ] hasperk( "specialty_proximityprotection" ) )
|
||||
{
|
||||
trace = bullettrace( position, players[ i ].origin + vectorScale( ( 0, 0, 0 ), 12 ), 0, players[ i ] );
|
||||
if ( trace[ "fraction" ] == 1 )
|
||||
{
|
||||
players[ i ].lastpoisonedby = owner;
|
||||
players[ i ] thread damageinpoisonarea( shockeffectarea, killcament, trace, position );
|
||||
}
|
||||
}
|
||||
players[ i ] thread maps/mp/gametypes/_battlechatter_mp::incomingspecialgrenadetracking( "gas" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
wait loopwaittime;
|
||||
durationoftabun -= loopwaittime;
|
||||
}
|
||||
if ( level.tabungasduration < level.poisonduration )
|
||||
{
|
||||
wait ( level.poisonduration - level.tabungasduration );
|
||||
}
|
||||
shockeffectarea delete();
|
||||
gaseffectarea delete();
|
||||
/#
|
||||
if ( getDvarInt( "scr_draw_triggers" ) )
|
||||
{
|
||||
level notify( "tabun_draw_cylinder_stop" );
|
||||
#/
|
||||
}
|
||||
}
|
||||
|
||||
damageinpoisonarea( gaseffectarea, killcament, trace, position )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self thread watch_death();
|
||||
self.inpoisonarea = 1;
|
||||
self startpoisoning();
|
||||
tabunshocksound = spawn( "script_origin", ( 0, 0, 0 ) );
|
||||
tabunshocksound thread deleteentonownerdeath( self );
|
||||
tabunshocksound.origin = position;
|
||||
tabunshocksound playsound( level.sound_shock_tabun_start );
|
||||
tabunshocksound playloopsound( level.sound_shock_tabun_loop );
|
||||
timer = 0;
|
||||
while ( trace[ "fraction" ] == 1 && isDefined( gaseffectarea ) && self istouching( gaseffectarea ) && self.sessionstate == "playing" && isDefined( self.lastpoisonedby ) )
|
||||
{
|
||||
damage = level.poisondamage;
|
||||
if ( level.hardcoremode )
|
||||
{
|
||||
damage = level.poisondamagehardcore;
|
||||
}
|
||||
self dodamage( damage, gaseffectarea.origin, self.lastpoisonedby, killcament, "none", "MOD_GAS", 0, "tabun_gas_mp" );
|
||||
if ( self mayapplyscreeneffect() )
|
||||
{
|
||||
switch( timer )
|
||||
{
|
||||
case 0:
|
||||
self shellshock( "tabun_gas_mp", 1 );
|
||||
break;
|
||||
timer++;
|
||||
continue;
|
||||
case 1:
|
||||
self shellshock( "tabun_gas_nokick_mp", 1 );
|
||||
break;
|
||||
timer++;
|
||||
continue;
|
||||
default:
|
||||
}
|
||||
timer++;
|
||||
if ( timer >= 2 )
|
||||
{
|
||||
timer = 0;
|
||||
}
|
||||
self hide_hud();
|
||||
}
|
||||
wait 1;
|
||||
trace = bullettrace( position, self.origin + vectorScale( ( 0, 0, 0 ), 12 ), 0, self );
|
||||
}
|
||||
tabunshocksound stoploopsound( 0,5 );
|
||||
wait 0,5;
|
||||
thread playsoundinspace( level.sound_shock_tabun_stop, position );
|
||||
wait 0,5;
|
||||
tabunshocksound notify( "delete" );
|
||||
tabunshocksound delete();
|
||||
self show_hud();
|
||||
self stoppoisoning();
|
||||
self.inpoisonarea = 0;
|
||||
}
|
||||
}
|
||||
|
||||
deleteentonownerdeath( owner )
|
||||
{
|
||||
self endon( "delete" );
|
||||
owner waittill( "death" );
|
||||
self delete();
|
||||
}
|
||||
|
||||
watch_death()
|
||||
{
|
||||
self waittill( "death" );
|
||||
self show_hud();
|
||||
}
|
||||
|
||||
hide_hud()
|
||||
{
|
||||
self setclientuivisibilityflag( "hud_visible", 0 );
|
||||
}
|
||||
|
||||
show_hud()
|
||||
{
|
||||
self setclientuivisibilityflag( "hud_visible", 1 );
|
||||
}
|
||||
|
||||
weapons_get_dvar_int( dvar, def )
|
||||
{
|
||||
return int( weapons_get_dvar( dvar, def ) );
|
||||
}
|
||||
|
||||
weapons_get_dvar( dvar, def )
|
||||
{
|
||||
if ( getDvar( dvar ) != "" )
|
||||
{
|
||||
return getDvarFloat( dvar );
|
||||
}
|
||||
else
|
||||
{
|
||||
setdvar( dvar, def );
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
generatelocations( position, owner )
|
||||
{
|
||||
onefoot = vectorScale( ( 0, 0, 0 ), 12 );
|
||||
startpos = position + onefoot;
|
||||
/#
|
||||
level.tabun_debug = getdvarintdefault( "scr_tabun_debug", 0 );
|
||||
if ( level.tabun_debug )
|
||||
{
|
||||
black = vectorScale( ( 0, 0, 0 ), 0,2 );
|
||||
debugstar( startpos, 2000, black );
|
||||
#/
|
||||
}
|
||||
spawnalllocs( owner, startpos );
|
||||
}
|
||||
|
||||
singlelocation( position, owner )
|
||||
{
|
||||
spawntimedfx( level.fx_tabun_single, position );
|
||||
killcament = spawn( "script_model", position + vectorScale( ( 0, 0, 0 ), 60 ) );
|
||||
killcament deleteaftertime( 15 );
|
||||
killcament.starttime = getTime();
|
||||
damageeffectarea( owner, position, level.tabungaspoisonradius, level.tabungaspoisonheight, killcament );
|
||||
}
|
||||
|
||||
hitpos( start, end, color )
|
||||
{
|
||||
trace = bullettrace( start, end, 0, undefined );
|
||||
/#
|
||||
level.tabun_debug = getdvarintdefault( "scr_tabun_debug", 0 );
|
||||
if ( level.tabun_debug )
|
||||
{
|
||||
debugstar( trace[ "position" ], 2000, color );
|
||||
}
|
||||
thread debug_line( start, trace[ "position" ], color, 80 );
|
||||
#/
|
||||
return trace[ "position" ];
|
||||
}
|
||||
|
||||
spawnalllocs( owner, startpos )
|
||||
{
|
||||
defaultdistance = weapons_get_dvar_int( "scr_defaultDistanceTabun", 220 );
|
||||
cos45 = 0,707;
|
||||
negcos45 = -0,707;
|
||||
red = ( 0,9, 0,2, 0,2 );
|
||||
blue = ( 0,2, 0,2, 0,9 );
|
||||
green = ( 0,2, 0,9, 0,2 );
|
||||
white = vectorScale( ( 0, 0, 0 ), 0,9 );
|
||||
north = startpos + ( defaultdistance, 0, 0 );
|
||||
south = startpos - ( defaultdistance, 0, 0 );
|
||||
east = startpos + ( 0, defaultdistance, 0 );
|
||||
west = startpos - ( 0, defaultdistance, 0 );
|
||||
nw = startpos + ( cos45 * defaultdistance, negcos45 * defaultdistance, 0 );
|
||||
ne = startpos + ( cos45 * defaultdistance, cos45 * defaultdistance, 0 );
|
||||
sw = startpos + ( negcos45 * defaultdistance, negcos45 * defaultdistance, 0 );
|
||||
se = startpos + ( negcos45 * defaultdistance, cos45 * defaultdistance, 0 );
|
||||
locations = [];
|
||||
locations[ "color" ] = [];
|
||||
locations[ "loc" ] = [];
|
||||
locations[ "tracePos" ] = [];
|
||||
locations[ "distSqrd" ] = [];
|
||||
locations[ "fxtoplay" ] = [];
|
||||
locations[ "radius" ] = [];
|
||||
locations[ "color" ][ 0 ] = red;
|
||||
locations[ "color" ][ 1 ] = red;
|
||||
locations[ "color" ][ 2 ] = blue;
|
||||
locations[ "color" ][ 3 ] = blue;
|
||||
locations[ "color" ][ 4 ] = green;
|
||||
locations[ "color" ][ 5 ] = green;
|
||||
locations[ "color" ][ 6 ] = white;
|
||||
locations[ "color" ][ 7 ] = white;
|
||||
locations[ "point" ][ 0 ] = north;
|
||||
locations[ "point" ][ 1 ] = ne;
|
||||
locations[ "point" ][ 2 ] = east;
|
||||
locations[ "point" ][ 3 ] = se;
|
||||
locations[ "point" ][ 4 ] = south;
|
||||
locations[ "point" ][ 5 ] = sw;
|
||||
locations[ "point" ][ 6 ] = west;
|
||||
locations[ "point" ][ 7 ] = nw;
|
||||
count = 0;
|
||||
while ( count < 8 )
|
||||
{
|
||||
trace = hitpos( startpos, locations[ "point" ][ count ], locations[ "color" ][ count ] );
|
||||
locations[ "tracePos" ][ count ] = trace;
|
||||
locations[ "loc" ][ count ] = ( startpos / 2 ) + ( trace / 2 );
|
||||
locations[ "loc" ][ count ] -= vectorScale( ( 0, 0, 0 ), 12 );
|
||||
locations[ "distSqrd" ][ count ] = distancesquared( startpos, trace );
|
||||
count++;
|
||||
}
|
||||
centroid = getcentroid( locations );
|
||||
killcament = spawn( "script_model", centroid + vectorScale( ( 0, 0, 0 ), 60 ) );
|
||||
killcament deleteaftertime( 15 );
|
||||
killcament.starttime = getTime();
|
||||
center = getcenter( locations );
|
||||
i = 0;
|
||||
while ( i < 8 )
|
||||
{
|
||||
fxtoplay = setuptabunfx( owner, locations, i );
|
||||
switch( fxtoplay )
|
||||
{
|
||||
case 0:
|
||||
locations[ "fxtoplay" ][ i ] = level.fx_tabun_0;
|
||||
locations[ "radius" ][ i ] = level.fx_tabun_radius0;
|
||||
break;
|
||||
i++;
|
||||
continue;
|
||||
case 1:
|
||||
locations[ "fxtoplay" ][ i ] = level.fx_tabun_1;
|
||||
locations[ "radius" ][ i ] = level.fx_tabun_radius1;
|
||||
break;
|
||||
i++;
|
||||
continue;
|
||||
case 2:
|
||||
locations[ "fxtoplay" ][ i ] = level.fx_tabun_2;
|
||||
locations[ "radius" ][ i ] = level.fx_tabun_radius2;
|
||||
break;
|
||||
i++;
|
||||
continue;
|
||||
case 3:
|
||||
locations[ "fxtoplay" ][ i ] = level.fx_tabun_3;
|
||||
locations[ "radius" ][ i ] = level.fx_tabun_radius3;
|
||||
break;
|
||||
i++;
|
||||
continue;
|
||||
default:
|
||||
locations[ "radius" ][ i ] = 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
singleeffect = 1;
|
||||
freepassused = 0;
|
||||
i = 0;
|
||||
while ( i < 8 )
|
||||
{
|
||||
if ( locations[ "radius" ][ i ] != level.fx_tabun_radius0 )
|
||||
{
|
||||
if ( freepassused == 0 && locations[ "radius" ][ i ] == level.fx_tabun_radius1 )
|
||||
{
|
||||
freepassused = 1;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
singleeffect = 0;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
onefoot = vectorScale( ( 0, 0, 0 ), 12 );
|
||||
startpos -= onefoot;
|
||||
thread playtabunsound( startpos );
|
||||
if ( singleeffect == 1 )
|
||||
{
|
||||
singlelocation( startpos, owner );
|
||||
}
|
||||
else
|
||||
{
|
||||
spawntimedfx( level.fx_tabun_3, startpos );
|
||||
count = 0;
|
||||
while ( count < 8 )
|
||||
{
|
||||
if ( isDefined( locations[ "fxtoplay" ][ count ] ) )
|
||||
{
|
||||
spawntimedfx( locations[ "fxtoplay" ][ count ], locations[ "loc" ][ count ] );
|
||||
thread damageeffectarea( owner, locations[ "loc" ][ count ], locations[ "radius" ][ count ], locations[ "radius" ][ count ], killcament );
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
playtabunsound( position )
|
||||
{
|
||||
tabunsound = spawn( "script_origin", ( 0, 0, 0 ) );
|
||||
tabunsound.origin = position;
|
||||
tabunsound playsound( level.sound_tabun_start );
|
||||
tabunsound playloopsound( level.sound_tabun_loop );
|
||||
wait level.tabungasduration;
|
||||
thread playsoundinspace( level.sound_tabun_stop, position );
|
||||
tabunsound stoploopsound( 0,5 );
|
||||
wait 0,5;
|
||||
tabunsound delete();
|
||||
}
|
||||
|
||||
setuptabunfx( owner, locations, count )
|
||||
{
|
||||
fxtoplay = undefined;
|
||||
previous = count - 1;
|
||||
if ( previous < 0 )
|
||||
{
|
||||
previous += locations[ "loc" ].size;
|
||||
}
|
||||
next = count + 1;
|
||||
if ( next >= locations[ "loc" ].size )
|
||||
{
|
||||
next -= locations[ "loc" ].size;
|
||||
}
|
||||
effect0dist = level.fx_tabun_radius0 * level.fx_tabun_radius0;
|
||||
effect1dist = level.fx_tabun_radius1 * level.fx_tabun_radius1;
|
||||
effect2dist = level.fx_tabun_radius2 * level.fx_tabun_radius2;
|
||||
effect3dist = level.fx_tabun_radius3 * level.fx_tabun_radius3;
|
||||
effect4dist = level.fx_tabun_radius3;
|
||||
fxtoplay = -1;
|
||||
if ( locations[ "distSqrd" ][ count ] > effect0dist && locations[ "distSqrd" ][ previous ] > effect1dist && locations[ "distSqrd" ][ next ] > effect1dist )
|
||||
{
|
||||
fxtoplay = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( locations[ "distSqrd" ][ count ] > effect1dist && locations[ "distSqrd" ][ previous ] > effect2dist && locations[ "distSqrd" ][ next ] > effect2dist )
|
||||
{
|
||||
fxtoplay = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( locations[ "distSqrd" ][ count ] > effect2dist && locations[ "distSqrd" ][ previous ] > effect3dist && locations[ "distSqrd" ][ next ] > effect3dist )
|
||||
{
|
||||
fxtoplay = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( locations[ "distSqrd" ][ count ] > effect3dist && locations[ "distSqrd" ][ previous ] > effect4dist && locations[ "distSqrd" ][ next ] > effect4dist )
|
||||
{
|
||||
fxtoplay = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return fxtoplay;
|
||||
}
|
||||
|
||||
getcentroid( locations )
|
||||
{
|
||||
centroid = ( 0, 0, 0 );
|
||||
i = 0;
|
||||
while ( i < locations[ "loc" ].size )
|
||||
{
|
||||
centroid += locations[ "loc" ][ i ] / locations[ "loc" ].size;
|
||||
i++;
|
||||
}
|
||||
/#
|
||||
level.tabun_debug = getdvarintdefault( "scr_tabun_debug", 0 );
|
||||
if ( level.tabun_debug )
|
||||
{
|
||||
purple = ( 0,9, 0,2, 0,9 );
|
||||
debugstar( centroid, 2000, purple );
|
||||
#/
|
||||
}
|
||||
return centroid;
|
||||
}
|
||||
|
||||
getcenter( locations )
|
||||
{
|
||||
center = ( 0, 0, 0 );
|
||||
curx = locations[ "tracePos" ][ 0 ][ 0 ];
|
||||
cury = locations[ "tracePos" ][ 0 ][ 1 ];
|
||||
minx = curx;
|
||||
maxx = curx;
|
||||
miny = cury;
|
||||
maxy = cury;
|
||||
i = 1;
|
||||
while ( i < locations[ "tracePos" ].size )
|
||||
{
|
||||
curx = locations[ "tracePos" ][ i ][ 0 ];
|
||||
cury = locations[ "tracePos" ][ i ][ 1 ];
|
||||
if ( curx > maxx )
|
||||
{
|
||||
maxx = curx;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( curx < minx )
|
||||
{
|
||||
minx = curx;
|
||||
}
|
||||
}
|
||||
if ( cury > maxy )
|
||||
{
|
||||
maxy = cury;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( cury < miny )
|
||||
{
|
||||
miny = cury;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
avgx = ( maxx + minx ) / 2;
|
||||
avgy = ( maxy + miny ) / 2;
|
||||
center = ( avgx, avgy, locations[ "tracePos" ][ 0 ][ 2 ] );
|
||||
/#
|
||||
level.tabun_debug = getdvarintdefault( "scr_tabun_debug", 0 );
|
||||
if ( level.tabun_debug )
|
||||
{
|
||||
cyan = ( 0,2, 0,9, 0,9 );
|
||||
debugstar( center, 2000, cyan );
|
||||
#/
|
||||
}
|
||||
return center;
|
||||
}
|
408
Multiplayer Core/patch_mp/maps/mp/_tacticalinsertion.gsc
Normal file
408
Multiplayer Core/patch_mp/maps/mp/_tacticalinsertion.gsc
Normal file
@ -0,0 +1,408 @@
|
||||
#include maps/mp/gametypes/_damagefeedback;
|
||||
#include maps/mp/gametypes/_globallogic_player;
|
||||
#include maps/mp/_hacker_tool;
|
||||
#include maps/mp/gametypes/_weaponobjects;
|
||||
#include maps/mp/_scoreevents;
|
||||
#include maps/mp/_challenges;
|
||||
#include maps/mp/gametypes/_globallogic_audio;
|
||||
#include maps/mp/gametypes/_hud_util;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level.tacticalinsertionweapon = "tactical_insertion_mp";
|
||||
precachemodel( "t6_wpn_tac_insert_world" );
|
||||
loadfx( "misc/fx_equip_tac_insert_light_grn" );
|
||||
loadfx( "misc/fx_equip_tac_insert_light_red" );
|
||||
level._effect[ "tacticalInsertionFizzle" ] = loadfx( "misc/fx_equip_tac_insert_exp" );
|
||||
maps/mp/gametypes/_globallogic_audio::registerdialoggroup( "item_destroyed", 1 );
|
||||
}
|
||||
|
||||
istacspawntouchingcrates( origin, angles )
|
||||
{
|
||||
crate_ents = getentarray( "care_package", "script_noteworthy" );
|
||||
mins = ( -17, -17, -40 );
|
||||
maxs = ( 17, 17, 40 );
|
||||
i = 0;
|
||||
while ( i < crate_ents.size )
|
||||
{
|
||||
if ( crate_ents[ i ] istouchingvolume( origin + vectorScale( ( 0, 0, 1 ), 40 ), mins, maxs ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
overridespawn( ispredictedspawn )
|
||||
{
|
||||
if ( !isDefined( self.tacticalinsertion ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
origin = self.tacticalinsertion.origin;
|
||||
angles = self.tacticalinsertion.angles;
|
||||
team = self.tacticalinsertion.team;
|
||||
if ( !ispredictedspawn )
|
||||
{
|
||||
self.tacticalinsertion destroy_tactical_insertion();
|
||||
}
|
||||
if ( team != self.team )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( istacspawntouchingcrates( origin ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( !ispredictedspawn )
|
||||
{
|
||||
self.tacticalinsertiontime = getTime();
|
||||
self spawn( origin, angles, "tactical insertion" );
|
||||
self setspawnclientflag( "SCDFL_DISABLE_LOGGING" );
|
||||
self addweaponstat( "tactical_insertion_mp", "used", 1 );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
waitanddelete( time )
|
||||
{
|
||||
self endon( "death" );
|
||||
wait 0,05;
|
||||
self delete();
|
||||
}
|
||||
|
||||
watch( player )
|
||||
{
|
||||
if ( isDefined( player.tacticalinsertion ) )
|
||||
{
|
||||
player.tacticalinsertion destroy_tactical_insertion();
|
||||
}
|
||||
player thread spawntacticalinsertion();
|
||||
self waitanddelete( 0,05 );
|
||||
}
|
||||
|
||||
watchusetrigger( trigger, callback, playersoundonuse, npcsoundonuse )
|
||||
{
|
||||
self endon( "delete" );
|
||||
while ( 1 )
|
||||
{
|
||||
trigger waittill( "trigger", player );
|
||||
while ( !isalive( player ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
while ( !player isonground() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( isDefined( trigger.triggerteam ) && player.team != trigger.triggerteam )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( isDefined( trigger.triggerteamignore ) && player.team == trigger.triggerteamignore )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( isDefined( trigger.claimedby ) && player != trigger.claimedby )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( player usebuttonpressed() && !player.throwinggrenade && !player meleebuttonpressed() )
|
||||
{
|
||||
if ( isDefined( playersoundonuse ) )
|
||||
{
|
||||
player playlocalsound( playersoundonuse );
|
||||
}
|
||||
if ( isDefined( npcsoundonuse ) )
|
||||
{
|
||||
player playsound( npcsoundonuse );
|
||||
}
|
||||
self thread [[ callback ]]( player );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watchdisconnect()
|
||||
{
|
||||
self.tacticalinsertion endon( "delete" );
|
||||
self waittill( "disconnect" );
|
||||
self.tacticalinsertion thread destroy_tactical_insertion();
|
||||
}
|
||||
|
||||
destroy_tactical_insertion( attacker )
|
||||
{
|
||||
self.owner.tacticalinsertion = undefined;
|
||||
self notify( "delete" );
|
||||
self.owner notify( "tactical_insertion_destroyed" );
|
||||
self.friendlytrigger delete();
|
||||
self.enemytrigger delete();
|
||||
if ( isDefined( attacker ) && isDefined( attacker.pers[ "team" ] ) && isDefined( self.owner ) && isDefined( self.owner.pers[ "team" ] ) )
|
||||
{
|
||||
if ( level.teambased )
|
||||
{
|
||||
if ( attacker.pers[ "team" ] != self.owner.pers[ "team" ] )
|
||||
{
|
||||
attacker notify( "destroyed_explosive" );
|
||||
attacker maps/mp/_challenges::destroyedequipment();
|
||||
attacker maps/mp/_challenges::destroyedtacticalinsert();
|
||||
maps/mp/_scoreevents::processscoreevent( "destroyed_tac_insert", attacker );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( attacker != self.owner )
|
||||
{
|
||||
attacker notify( "destroyed_explosive" );
|
||||
attacker maps/mp/_challenges::destroyedequipment();
|
||||
attacker maps/mp/_challenges::destroyedtacticalinsert();
|
||||
maps/mp/_scoreevents::processscoreevent( "destroyed_tac_insert", attacker );
|
||||
}
|
||||
}
|
||||
}
|
||||
self delete();
|
||||
}
|
||||
|
||||
fizzle( attacker )
|
||||
{
|
||||
if ( isDefined( self.fizzle ) && self.fizzle )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self.fizzle = 1;
|
||||
playfx( level._effect[ "tacticalInsertionFizzle" ], self.origin );
|
||||
self playsound( "dst_tac_insert_break" );
|
||||
if ( isDefined( attacker ) && attacker != self.owner )
|
||||
{
|
||||
self.owner maps/mp/gametypes/_globallogic_audio::leaderdialogonplayer( "tact_destroyed", "item_destroyed" );
|
||||
}
|
||||
self destroy_tactical_insertion( attacker );
|
||||
}
|
||||
|
||||
pickup( attacker )
|
||||
{
|
||||
player = self.owner;
|
||||
self destroy_tactical_insertion();
|
||||
player giveweapon( level.tacticalinsertionweapon );
|
||||
player setweaponammoclip( level.tacticalinsertionweapon, 1 );
|
||||
}
|
||||
|
||||
spawntacticalinsertion()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self.tacticalinsertion = spawn( "script_model", self.origin + ( 0, 0, 1 ) );
|
||||
self.tacticalinsertion setmodel( "t6_wpn_tac_insert_world" );
|
||||
self.tacticalinsertion.origin = self.origin + ( 0, 0, 1 );
|
||||
self.tacticalinsertion.angles = self.angles;
|
||||
self.tacticalinsertion.team = self.team;
|
||||
self.tacticalinsertion setteam( self.team );
|
||||
self.tacticalinsertion.owner = self;
|
||||
self.tacticalinsertion setowner( self );
|
||||
self.tacticalinsertion setweapon( level.tacticalinsertionweapon );
|
||||
self.tacticalinsertion thread maps/mp/gametypes/_weaponobjects::attachreconmodel( "t6_wpn_tac_insert_detect", self );
|
||||
self.tacticalinsertion endon( "delete" );
|
||||
self.tacticalinsertion maps/mp/_hacker_tool::registerwithhackertool( level.equipmenthackertoolradius, level.equipmenthackertooltimems );
|
||||
triggerheight = 64;
|
||||
triggerradius = 128;
|
||||
self.tacticalinsertion.friendlytrigger = spawn( "trigger_radius_use", self.tacticalinsertion.origin + vectorScale( ( 0, 0, 1 ), 3 ) );
|
||||
self.tacticalinsertion.friendlytrigger setcursorhint( "HINT_NOICON", self.tacticalinsertion );
|
||||
self.tacticalinsertion.friendlytrigger sethintstring( &"MP_TACTICAL_INSERTION_PICKUP" );
|
||||
if ( level.teambased )
|
||||
{
|
||||
self.tacticalinsertion.friendlytrigger setteamfortrigger( self.team );
|
||||
self.tacticalinsertion.friendlytrigger.triggerteam = self.team;
|
||||
}
|
||||
self clientclaimtrigger( self.tacticalinsertion.friendlytrigger );
|
||||
self.tacticalinsertion.friendlytrigger.claimedby = self;
|
||||
self.tacticalinsertion.enemytrigger = spawn( "trigger_radius_use", self.tacticalinsertion.origin + vectorScale( ( 0, 0, 1 ), 3 ) );
|
||||
self.tacticalinsertion.enemytrigger setcursorhint( "HINT_NOICON", self.tacticalinsertion );
|
||||
self.tacticalinsertion.enemytrigger sethintstring( &"MP_TACTICAL_INSERTION_DESTROY" );
|
||||
self.tacticalinsertion.enemytrigger setinvisibletoplayer( self );
|
||||
if ( level.teambased )
|
||||
{
|
||||
self.tacticalinsertion.enemytrigger setexcludeteamfortrigger( self.team );
|
||||
self.tacticalinsertion.enemytrigger.triggerteamignore = self.team;
|
||||
}
|
||||
self.tacticalinsertion setclientflag( 2 );
|
||||
self thread watchdisconnect();
|
||||
watcher = maps/mp/gametypes/_weaponobjects::getweaponobjectwatcherbyweapon( level.tacticalinsertionweapon );
|
||||
self.tacticalinsertion thread watchusetrigger( self.tacticalinsertion.friendlytrigger, ::pickup, watcher.pickupsoundplayer, watcher.pickupsound );
|
||||
self.tacticalinsertion thread watchusetrigger( self.tacticalinsertion.enemytrigger, ::fizzle );
|
||||
if ( isDefined( self.tacticalinsertioncount ) )
|
||||
{
|
||||
self.tacticalinsertioncount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.tacticalinsertioncount = 1;
|
||||
}
|
||||
self.tacticalinsertion setcandamage( 1 );
|
||||
self.tacticalinsertion.health = 1;
|
||||
while ( 1 )
|
||||
{
|
||||
self.tacticalinsertion waittill( "damage", damage, attacker, direction, point, type, tagname, modelname, partname, weaponname, idflags );
|
||||
while ( level.teambased && isDefined( attacker ) && isplayer( attacker ) && attacker.team == self.team && attacker != self )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( attacker != self )
|
||||
{
|
||||
attacker maps/mp/_challenges::destroyedequipment( weaponname );
|
||||
attacker maps/mp/_challenges::destroyedtacticalinsert();
|
||||
maps/mp/_scoreevents::processscoreevent( "destroyed_tac_insert", attacker );
|
||||
}
|
||||
if ( isDefined( weaponname ) )
|
||||
{
|
||||
switch( weaponname )
|
||||
{
|
||||
case "concussion_grenade_mp":
|
||||
case "flash_grenade_mp":
|
||||
if ( level.teambased && self.tacticalinsertion.owner.team != attacker.team )
|
||||
{
|
||||
if ( maps/mp/gametypes/_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
{
|
||||
attacker maps/mp/gametypes/_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !level.teambased && self.tacticalinsertion.owner != attacker )
|
||||
{
|
||||
if ( maps/mp/gametypes/_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
{
|
||||
attacker maps/mp/gametypes/_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
if ( maps/mp/gametypes/_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
{
|
||||
attacker maps/mp/gametypes/_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( isDefined( attacker ) && attacker != self )
|
||||
{
|
||||
self maps/mp/gametypes/_globallogic_audio::leaderdialogonplayer( "tact_destroyed", "item_destroyed" );
|
||||
}
|
||||
self.tacticalinsertion thread fizzle();
|
||||
}
|
||||
}
|
||||
|
||||
cancel_button_think()
|
||||
{
|
||||
if ( !isDefined( self.tacticalinsertion ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
text = cancel_text_create();
|
||||
self thread cancel_button_press();
|
||||
event = self waittill_any_return( "tactical_insertion_destroyed", "disconnect", "end_killcam", "abort_killcam", "tactical_insertion_canceled", "spawned" );
|
||||
if ( event == "tactical_insertion_canceled" )
|
||||
{
|
||||
self.tacticalinsertion destroy_tactical_insertion();
|
||||
}
|
||||
if ( isDefined( text ) )
|
||||
{
|
||||
text destroy();
|
||||
}
|
||||
}
|
||||
|
||||
canceltackinsertionbutton()
|
||||
{
|
||||
if ( level.console )
|
||||
{
|
||||
return self changeseatbuttonpressed();
|
||||
}
|
||||
else
|
||||
{
|
||||
return self jumpbuttonpressed();
|
||||
}
|
||||
}
|
||||
|
||||
cancel_button_press()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "end_killcam" );
|
||||
self endon( "abort_killcam" );
|
||||
while ( 1 )
|
||||
{
|
||||
wait 0,05;
|
||||
if ( self canceltackinsertionbutton() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
self notify( "tactical_insertion_canceled" );
|
||||
}
|
||||
|
||||
cancel_text_create()
|
||||
{
|
||||
text = newclienthudelem( self );
|
||||
text.archived = 0;
|
||||
text.y = -100;
|
||||
text.alignx = "center";
|
||||
text.aligny = "middle";
|
||||
text.horzalign = "center";
|
||||
text.vertalign = "bottom";
|
||||
text.sort = 10;
|
||||
text.font = "small";
|
||||
text.foreground = 1;
|
||||
text.hidewheninmenu = 1;
|
||||
if ( self issplitscreen() )
|
||||
{
|
||||
text.y = -80;
|
||||
text.fontscale = 1,2;
|
||||
}
|
||||
else
|
||||
{
|
||||
text.fontscale = 1,6;
|
||||
}
|
||||
text settext( &"PLATFORM_PRESS_TO_CANCEL_TACTICAL_INSERTION" );
|
||||
text.alpha = 1;
|
||||
return text;
|
||||
}
|
||||
|
||||
gettacticalinsertions()
|
||||
{
|
||||
tac_inserts = [];
|
||||
_a393 = level.players;
|
||||
_k393 = getFirstArrayKey( _a393 );
|
||||
while ( isDefined( _k393 ) )
|
||||
{
|
||||
player = _a393[ _k393 ];
|
||||
if ( isDefined( player.tacticalinsertion ) )
|
||||
{
|
||||
tac_inserts[ tac_inserts.size ] = player.tacticalinsertion;
|
||||
}
|
||||
_k393 = getNextArrayKey( _a393, _k393 );
|
||||
}
|
||||
return tac_inserts;
|
||||
}
|
||||
|
||||
tacticalinsertiondestroyedbytrophysystem( attacker, trophysystem )
|
||||
{
|
||||
owner = self.owner;
|
||||
if ( isDefined( attacker ) )
|
||||
{
|
||||
attacker maps/mp/_challenges::destroyedequipment( trophysystem.name );
|
||||
attacker maps/mp/_challenges::destroyedtacticalinsert();
|
||||
}
|
||||
self thread fizzle();
|
||||
if ( isDefined( owner ) )
|
||||
{
|
||||
owner endon( "death" );
|
||||
owner endon( "disconnect" );
|
||||
wait 0,05;
|
||||
owner maps/mp/gametypes/_globallogic_audio::leaderdialogonplayer( "tact_destroyed", "item_destroyed" );
|
||||
}
|
||||
}
|
175
Multiplayer Core/patch_mp/maps/mp/_teargrenades.gsc
Normal file
175
Multiplayer Core/patch_mp/maps/mp/_teargrenades.gsc
Normal file
@ -0,0 +1,175 @@
|
||||
//checked includes match cerberus output
|
||||
#include maps/mp/gametypes/_perplayer;
|
||||
|
||||
main() //checked matches cerberus output
|
||||
{
|
||||
level.tearradius = 170;
|
||||
level.tearheight = 128;
|
||||
level.teargasfillduration = 7;
|
||||
level.teargasduration = 23;
|
||||
level.tearsufferingduration = 3;
|
||||
level.teargrenadetimer = 4;
|
||||
precacheshellshock( "teargas" );
|
||||
fgmonitor = maps/mp/gametypes/_perplayer::init( "tear_grenade_monitor", ::startmonitoringtearusage, ::stopmonitoringtearusage );
|
||||
maps/mp/gametypes/_perplayer::enable( fgmonitor );
|
||||
}
|
||||
|
||||
startmonitoringtearusage() //checked matches cerberus output
|
||||
{
|
||||
self thread monitortearusage();
|
||||
}
|
||||
|
||||
stopmonitoringtearusage( disconnected ) //checked matches cerberus output
|
||||
{
|
||||
self notify( "stop_monitoring_tear_usage" );
|
||||
}
|
||||
|
||||
monitortearusage() //checked changed to match cerberus output
|
||||
{
|
||||
self endon( "stop_monitoring_tear_usage" );
|
||||
wait 0.05;
|
||||
if ( !self hasweapon( "tear_grenade_mp" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
prevammo = self getammocount( "tear_grenade_mp" );
|
||||
while ( 1 )
|
||||
{
|
||||
ammo = self getammocount( "tear_grenade_mp" );
|
||||
if ( ammo < prevammo )
|
||||
{
|
||||
num = prevammo - ammo;
|
||||
for ( i = 0; i < num; i++ )
|
||||
{
|
||||
grenades = getentarray( "grenade", "classname" );
|
||||
bestdist = undefined;
|
||||
bestg = undefined;
|
||||
for ( g = 0; g < grenades.size; g++ )
|
||||
{
|
||||
if ( !isDefined( grenades[ g ].teargrenade ) )
|
||||
{
|
||||
dist = distance( grenades[ g ].origin, self.origin + vectorScale( ( 0, 0, 1 ), 48 ) );
|
||||
if ( !isDefined( bestdist ) || dist < bestdist )
|
||||
{
|
||||
bestdist = dist;
|
||||
bestg = g;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( isDefined( bestdist ) )
|
||||
{
|
||||
grenades[ bestg ].teargrenade = 1;
|
||||
grenades[ bestg ] thread teargrenade_think( self.team );
|
||||
}
|
||||
}
|
||||
}
|
||||
prevammo = ammo;
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
teargrenade_think( team ) //checked matches cerberus output
|
||||
{
|
||||
wait level.teargrenadetimer;
|
||||
ent = spawnstruct();
|
||||
ent thread tear( self.origin );
|
||||
}
|
||||
|
||||
tear( pos ) //checked changed to match beta dump
|
||||
{
|
||||
trig = spawn( "trigger_radius", pos, 0, level.tearradius, level.tearheight );
|
||||
starttime = getTime();
|
||||
self thread teartimer();
|
||||
self endon( "tear_timeout" );
|
||||
while ( 1 )
|
||||
{
|
||||
trig waittill( "trigger", player );
|
||||
if ( player.sessionstate != "playing" )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
time = ( getTime() - starttime ) / 1000;
|
||||
currad = level.tearradius;
|
||||
curheight = level.tearheight;
|
||||
if ( time < level.teargasfillduration )
|
||||
{
|
||||
currad = currad * ( time / level.teargasfillduration );
|
||||
curheight = curheight * ( time / level.teargasfillduration );
|
||||
}
|
||||
offset = ( player.origin + vectorScale( ( 0, 0, 1 ), 32 ) ) - pos;
|
||||
offset2d = ( offset[ 0 ], offset[ 1 ], 0 );
|
||||
if ( lengthsquared( offset2d ) > ( currad * currad ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( ( player.origin[ 2 ] - pos[ 2 ] ) > curheight )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
player.teargasstarttime = getTime();
|
||||
if ( !isDefined( player.teargassuffering ) )
|
||||
{
|
||||
player thread teargassuffering();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
teartimer() //checked matches cerberus output
|
||||
{
|
||||
wait level.teargasduration;
|
||||
self notify( "tear_timeout" );
|
||||
}
|
||||
|
||||
teargassuffering() //checked changed to match cerberus output
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self.teargassuffering = 1;
|
||||
if ( self mayapplyscreeneffect() )
|
||||
{
|
||||
self shellshock( "teargas", 60 );
|
||||
}
|
||||
while ( 1 )
|
||||
{
|
||||
if ( ( getTime() - self.teargasstarttime ) > ( level.tearsufferingduration * 1000 ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
wait 1;
|
||||
}
|
||||
self shellshock( "teargas", 1 );
|
||||
if ( self mayapplyscreeneffect() )
|
||||
{
|
||||
self.teargassuffering = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
drawcylinder( pos, rad, height ) //checked changed to match beta dump
|
||||
{
|
||||
time = 0;
|
||||
while ( 1 )
|
||||
{
|
||||
currad = rad;
|
||||
curheight = height;
|
||||
if ( time < level.teargasfillduration )
|
||||
{
|
||||
currad = currad * ( time / level.teargasfillduration );
|
||||
curheight = curheight * ( time / level.teargasfillduration );
|
||||
}
|
||||
for ( r = 0; r < 20; r++ )
|
||||
{
|
||||
theta = ( r / 20 ) * 360;
|
||||
theta2 = ( ( r + 1 ) / 20 ) * 360;
|
||||
line( pos + ( cos( theta ) * currad, sin( theta ) * currad, 0 ), pos + ( cos( theta2 ) * currad, sin( theta2 ) * currad, 0 ) );
|
||||
line( pos + ( cos( theta ) * currad, sin( theta ) * currad, curheight ), pos + ( cos( theta2 ) * currad, sin( theta2 ) * currad, curheight ) );
|
||||
line( pos + ( cos( theta ) * currad, sin( theta ) * currad, 0 ), pos + ( cos( theta ) * currad, sin( theta ) * currad, curheight ) );
|
||||
}
|
||||
time += 0.05;
|
||||
if ( time > level.teargasduration )
|
||||
{
|
||||
return;
|
||||
}
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
127
Multiplayer Core/patch_mp/maps/mp/_treadfx.gsc
Normal file
127
Multiplayer Core/patch_mp/maps/mp/_treadfx.gsc
Normal file
@ -0,0 +1,127 @@
|
||||
|
||||
loadtreadfx( vehicle ) //checked matches cerberus output
|
||||
{
|
||||
treadfx = vehicle.treadfxnamearray;
|
||||
if ( isDefined( treadfx ) )
|
||||
{
|
||||
vehicle.treadfx = [];
|
||||
if ( isDefined( treadfx[ "asphalt" ] ) && treadfx[ "asphalt" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "asphalt" ] = loadfx( treadfx[ "asphalt" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "bark" ] ) && treadfx[ "bark" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "bark" ] = loadfx( treadfx[ "bark" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "brick" ] ) && treadfx[ "brick" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "brick" ] = loadfx( treadfx[ "brick" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "carpet" ] ) && treadfx[ "carpet" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "carpet" ] = loadfx( treadfx[ "carpet" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "ceramic" ] ) && treadfx[ "ceramic" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "ceramic" ] = loadfx( treadfx[ "ceramic" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "cloth" ] ) && treadfx[ "cloth" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "cloth" ] = loadfx( treadfx[ "cloth" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "concrete" ] ) && treadfx[ "concrete" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "concrete" ] = loadfx( treadfx[ "concrete" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "cushion" ] ) && treadfx[ "cushion" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "cushion" ] = loadfx( treadfx[ "cushion" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "none" ] ) && treadfx[ "none" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "none" ] = loadfx( treadfx[ "none" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "dirt" ] ) && treadfx[ "dirt" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "dirt" ] = loadfx( treadfx[ "dirt" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "flesh" ] ) && treadfx[ "flesh" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "flesh" ] = loadfx( treadfx[ "flesh" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "foliage" ] ) && treadfx[ "foliage" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "foliage" ] = loadfx( treadfx[ "foliage" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "fruit" ] ) && treadfx[ "fruit" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "fruit" ] = loadfx( treadfx[ "fruit" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "glass" ] ) && treadfx[ "glass" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "glass" ] = loadfx( treadfx[ "glass" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "grass" ] ) && treadfx[ "grass" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "grass" ] = loadfx( treadfx[ "grass" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "gravel" ] ) && treadfx[ "gravel" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "gravel" ] = loadfx( treadfx[ "gravel" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "metal" ] ) && treadfx[ "metal" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "metal" ] = loadfx( treadfx[ "metal" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "mud" ] ) && treadfx[ "mud" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "mud" ] = loadfx( treadfx[ "mud" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "paintedmetal" ] ) && treadfx[ "paintedmetal" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "paintedmetal" ] = loadfx( treadfx[ "paintedmetal" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "paper" ] ) && treadfx[ "paper" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "paper" ] = loadfx( treadfx[ "paper" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "plaster" ] ) && treadfx[ "plaster" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "plaster" ] = loadfx( treadfx[ "plaster" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "plastic" ] ) && treadfx[ "plastic" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "plastic" ] = loadfx( treadfx[ "plastic" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "rock" ] ) && treadfx[ "rock" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "rock" ] = loadfx( treadfx[ "rock" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "rubber" ] ) && treadfx[ "rubber" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "rubber" ] = loadfx( treadfx[ "rubber" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "sand" ] ) && treadfx[ "sand" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "sand" ] = loadfx( treadfx[ "sand" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "water" ] ) && treadfx[ "water" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "water" ] = loadfx( treadfx[ "water" ] );
|
||||
}
|
||||
if ( isDefined( treadfx[ "wood" ] ) && treadfx[ "wood" ] != "" )
|
||||
{
|
||||
vehicle.treadfx[ "wood" ] = loadfx( treadfx[ "wood" ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
preloadtreadfx( vehicle ) //checked changed to match cerberus output
|
||||
{
|
||||
treadfx = getvehicletreadfxarray( vehicle );
|
||||
for ( i = 0; i < treadfx.size; i++ )
|
||||
{
|
||||
loadfx( treadfx[ i ] );
|
||||
}
|
||||
}
|
||||
|
379
Multiplayer Core/patch_mp/maps/mp/_trophy_system.gsc
Normal file
379
Multiplayer Core/patch_mp/maps/mp/_trophy_system.gsc
Normal file
@ -0,0 +1,379 @@
|
||||
#include maps/mp/gametypes/_damagefeedback;
|
||||
#include maps/mp/gametypes/_globallogic_player;
|
||||
#include maps/mp/killstreaks/_emp;
|
||||
#include maps/mp/_tacticalinsertion;
|
||||
#include maps/mp/_scoreevents;
|
||||
#include maps/mp/_challenges;
|
||||
#include maps/mp/gametypes/_globallogic_audio;
|
||||
#include maps/mp/gametypes/_weaponobjects;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/_utility;
|
||||
|
||||
#using_animtree( "mp_trophy_system" );
|
||||
|
||||
init()
|
||||
{
|
||||
precachemodel( "t6_wpn_trophy_system_world" );
|
||||
level.trophylongflashfx = loadfx( "weapon/trophy_system/fx_trophy_flash_lng" );
|
||||
level.trophydetonationfx = loadfx( "weapon/trophy_system/fx_trophy_radius_detonation" );
|
||||
level._effect[ "fx_trophy_friendly_light" ] = loadfx( "weapon/trophy_system/fx_trophy_light_friendly" );
|
||||
level._effect[ "fx_trophy_enemy_light" ] = loadfx( "weapon/trophy_system/fx_trophy_light_enemy" );
|
||||
level._effect[ "fx_trophy_deploy_impact" ] = loadfx( "weapon/trophy_system/fx_trophy_deploy_impact" );
|
||||
trophydeployanim = %o_trophy_deploy;
|
||||
trophyspinanim = %o_trophy_spin;
|
||||
}
|
||||
|
||||
register()
|
||||
{
|
||||
registerclientfield( "missile", "trophy_system_state", 1, 2, "int" );
|
||||
registerclientfield( "scriptmover", "trophy_system_state", 1, 2, "int" );
|
||||
}
|
||||
|
||||
createtrophysystemwatcher()
|
||||
{
|
||||
watcher = self maps/mp/gametypes/_weaponobjects::createuseweaponobjectwatcher( "trophy_system", "trophy_system_mp", self.team );
|
||||
watcher.detonate = ::trophysystemdetonate;
|
||||
watcher.activatesound = "wpn_claymore_alert";
|
||||
watcher.hackable = 1;
|
||||
watcher.hackertoolradius = level.equipmenthackertoolradius;
|
||||
watcher.hackertooltimems = level.equipmenthackertooltimems;
|
||||
watcher.reconmodel = "t6_wpn_trophy_system_world_detect";
|
||||
watcher.ownergetsassist = 1;
|
||||
watcher.ignoredirection = 1;
|
||||
watcher.activationdelay = 0,1;
|
||||
watcher.headicon = 1;
|
||||
watcher.enemydestroy = 1;
|
||||
watcher.onspawn = ::ontrophysystemspawn;
|
||||
watcher.ondamage = ::watchtrophysystemdamage;
|
||||
watcher.ondestroyed = ::ontrophysystemsmashed;
|
||||
watcher.stun = ::weaponstun;
|
||||
watcher.stuntime = 1;
|
||||
}
|
||||
|
||||
ontrophysystemspawn( watcher, player )
|
||||
{
|
||||
player endon( "death" );
|
||||
player endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
self maps/mp/gametypes/_weaponobjects::onspawnuseweaponobject( watcher, player );
|
||||
player addweaponstat( "trophy_system_mp", "used", 1 );
|
||||
self.ammo = 2;
|
||||
self thread trophyactive( player );
|
||||
self thread trophywatchhack();
|
||||
self setclientfield( "trophy_system_state", 1 );
|
||||
self playloopsound( "wpn_trophy_spin", 0,25 );
|
||||
if ( isDefined( watcher.reconmodel ) )
|
||||
{
|
||||
self thread setreconmodeldeployed();
|
||||
}
|
||||
}
|
||||
|
||||
setreconmodeldeployed()
|
||||
{
|
||||
self endon( "death" );
|
||||
for ( ;; )
|
||||
{
|
||||
if ( isDefined( self.reconmodelentity ) )
|
||||
{
|
||||
self.reconmodelentity setclientfield( "trophy_system_state", 1 );
|
||||
return;
|
||||
}
|
||||
wait 0,05;
|
||||
}
|
||||
}
|
||||
|
||||
trophywatchhack()
|
||||
{
|
||||
self endon( "death" );
|
||||
self waittill( "hacked", player );
|
||||
wait 0,05;
|
||||
self thread trophyactive( player );
|
||||
}
|
||||
|
||||
ontrophysystemsmashed( attacker )
|
||||
{
|
||||
playfx( level._effect[ "tacticalInsertionFizzle" ], self.origin );
|
||||
self playsound( "dst_tac_insert_break" );
|
||||
self.owner maps/mp/gametypes/_globallogic_audio::leaderdialogonplayer( "equipment_destroyed", "item_destroyed" );
|
||||
if ( isDefined( attacker ) && self.owner isenemyplayer( attacker ) )
|
||||
{
|
||||
attacker maps/mp/_challenges::destroyedequipment();
|
||||
maps/mp/_scoreevents::processscoreevent( "destroyed_trophy_system", attacker, self.owner );
|
||||
}
|
||||
self delete();
|
||||
}
|
||||
|
||||
trophyactive( owner )
|
||||
{
|
||||
owner endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self endon( "hacked" );
|
||||
while ( 1 )
|
||||
{
|
||||
tac_inserts = maps/mp/_tacticalinsertion::gettacticalinsertions();
|
||||
while ( level.missileentities.size < 1 || tac_inserts.size < 1 && isDefined( self.disabled ) )
|
||||
{
|
||||
wait 0,05;
|
||||
}
|
||||
index = 0;
|
||||
while ( index < level.missileentities.size )
|
||||
{
|
||||
wait 0,05;
|
||||
grenade = level.missileentities[ index ];
|
||||
if ( !isDefined( grenade ) )
|
||||
{
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
else if ( grenade == self )
|
||||
{
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
else if ( isDefined( grenade.weaponname ) )
|
||||
{
|
||||
switch( grenade.weaponname )
|
||||
{
|
||||
case "claymore_mp":
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ( isDefined( grenade.name ) && grenade.name == "tactical_insertion_mp" )
|
||||
{
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
else switch( grenade.model )
|
||||
{
|
||||
case "t6_wpn_grenade_supply_projectile":
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
if ( !isDefined( grenade.owner ) )
|
||||
{
|
||||
grenade.owner = getmissileowner( grenade );
|
||||
}
|
||||
if ( isDefined( grenade.owner ) )
|
||||
{
|
||||
if ( level.teambased )
|
||||
{
|
||||
if ( grenade.owner.team == owner.team )
|
||||
{
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
else }
|
||||
else if ( grenade.owner == owner )
|
||||
{
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
grenadedistancesquared = distancesquared( grenade.origin, self.origin );
|
||||
if ( grenadedistancesquared < 262144 )
|
||||
{
|
||||
if ( bullettracepassed( grenade.origin, self.origin + vectorScale( ( 0, 0, 1 ), 29 ), 0, self ) )
|
||||
{
|
||||
playfx( level.trophylongflashfx, self.origin + vectorScale( ( 0, 0, 1 ), 15 ), grenade.origin - self.origin, anglesToUp( self.angles ) );
|
||||
owner thread projectileexplode( grenade, self );
|
||||
index--;
|
||||
|
||||
self playsound( "wpn_trophy_alert" );
|
||||
self.ammo--;
|
||||
|
||||
if ( self.ammo <= 0 )
|
||||
{
|
||||
self thread trophysystemdetonate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
index = 0;
|
||||
while ( index < tac_inserts.size )
|
||||
{
|
||||
wait 0,05;
|
||||
tac_insert = tac_inserts[ index ];
|
||||
if ( !isDefined( tac_insert ) )
|
||||
{
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
else if ( isDefined( tac_insert.owner ) )
|
||||
{
|
||||
if ( level.teambased )
|
||||
{
|
||||
if ( tac_insert.owner.team == owner.team )
|
||||
{
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
else }
|
||||
else if ( tac_insert.owner == owner )
|
||||
{
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
grenadedistancesquared = distancesquared( tac_insert.origin, self.origin );
|
||||
if ( grenadedistancesquared < 262144 )
|
||||
{
|
||||
if ( bullettracepassed( tac_insert.origin, self.origin + vectorScale( ( 0, 0, 1 ), 29 ), 0, tac_insert ) )
|
||||
{
|
||||
playfx( level.trophylongflashfx, self.origin + vectorScale( ( 0, 0, 1 ), 15 ), tac_insert.origin - self.origin, anglesToUp( self.angles ) );
|
||||
owner thread trophydestroytacinsert( tac_insert, self );
|
||||
index--;
|
||||
|
||||
self playsound( "wpn_trophy_alert" );
|
||||
self.ammo--;
|
||||
|
||||
if ( self.ammo <= 0 )
|
||||
{
|
||||
self thread trophysystemdetonate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
projectileexplode( projectile, trophy )
|
||||
{
|
||||
self endon( "death" );
|
||||
projposition = projectile.origin;
|
||||
playfx( level.trophydetonationfx, projposition );
|
||||
projectile delete();
|
||||
trophy radiusdamage( projposition, 128, 105, 10, self );
|
||||
maps/mp/_scoreevents::processscoreevent( "trophy_defense", self );
|
||||
self addplayerstat( "destroy_explosive_with_trophy", 1 );
|
||||
self addweaponstat( "trophy_system_mp", "CombatRecordStat", 1 );
|
||||
}
|
||||
|
||||
trophydestroytacinsert( tacinsert, trophy )
|
||||
{
|
||||
self endon( "death" );
|
||||
tacpos = tacinsert.origin;
|
||||
playfx( level.trophydetonationfx, tacinsert.origin );
|
||||
tacinsert thread maps/mp/_tacticalinsertion::tacticalinsertiondestroyedbytrophysystem( self, trophy );
|
||||
trophy radiusdamage( tacpos, 128, 105, 10, self );
|
||||
maps/mp/_scoreevents::processscoreevent( "trophy_defense", self );
|
||||
self addplayerstat( "destroy_explosive_with_trophy", 1 );
|
||||
self addweaponstat( "trophy_system_mp", "CombatRecordStat", 1 );
|
||||
}
|
||||
|
||||
trophysystemdetonate( attacker, weaponname )
|
||||
{
|
||||
from_emp = maps/mp/killstreaks/_emp::isempweapon( weaponname );
|
||||
if ( !from_emp )
|
||||
{
|
||||
playfx( level._equipment_explode_fx_lg, self.origin );
|
||||
}
|
||||
if ( isDefined( attacker ) && self.owner isenemyplayer( attacker ) )
|
||||
{
|
||||
attacker maps/mp/_challenges::destroyedequipment( weaponname );
|
||||
maps/mp/_scoreevents::processscoreevent( "destroyed_trophy_system", attacker, self.owner, weaponname );
|
||||
}
|
||||
playsoundatposition( "dst_equipment_destroy", self.origin );
|
||||
self delete();
|
||||
}
|
||||
|
||||
watchtrophysystemdamage( watcher )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "hacked" );
|
||||
self setcandamage( 1 );
|
||||
damagemax = 20;
|
||||
if ( !self maps/mp/_utility::ishacked() )
|
||||
{
|
||||
self.damagetaken = 0;
|
||||
}
|
||||
self.maxhealth = 10000;
|
||||
self.health = self.maxhealth;
|
||||
self setmaxhealth( self.maxhealth );
|
||||
attacker = undefined;
|
||||
for ( ;; )
|
||||
{
|
||||
while ( 1 )
|
||||
{
|
||||
self waittill( "damage", damage, attacker, direction_vec, point, type, modelname, tagname, partname, weaponname, idflags );
|
||||
while ( !isplayer( attacker ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
while ( level.teambased )
|
||||
{
|
||||
while ( !level.hardcoremode && self.owner.team == attacker.pers[ "team" ] && self.owner != attacker )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ( isDefined( weaponname ) )
|
||||
{
|
||||
switch( weaponname )
|
||||
{
|
||||
case "concussion_grenade_mp":
|
||||
case "flash_grenade_mp":
|
||||
if ( watcher.stuntime > 0 )
|
||||
{
|
||||
self thread maps/mp/gametypes/_weaponobjects::stunstart( watcher, watcher.stuntime );
|
||||
}
|
||||
if ( level.teambased && self.owner.team != attacker.team )
|
||||
{
|
||||
if ( maps/mp/gametypes/_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
{
|
||||
attacker maps/mp/gametypes/_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !level.teambased && self.owner != attacker )
|
||||
{
|
||||
if ( maps/mp/gametypes/_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
{
|
||||
attacker maps/mp/gametypes/_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case "emp_grenade_mp":
|
||||
damage = damagemax;
|
||||
default:
|
||||
if ( maps/mp/gametypes/_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
{
|
||||
attacker maps/mp/gametypes/_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
weaponname = "";
|
||||
}
|
||||
if ( type == "MOD_MELEE" )
|
||||
{
|
||||
self.damagetaken = damagemax;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.damagetaken += damage;
|
||||
}
|
||||
if ( self.damagetaken >= damagemax )
|
||||
{
|
||||
watcher thread maps/mp/gametypes/_weaponobjects::waitanddetonate( self, 0,05, attacker, weaponname );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3077
Multiplayer Core/patch_mp/maps/mp/_utility.gsc
Normal file
3077
Multiplayer Core/patch_mp/maps/mp/_utility.gsc
Normal file
File diff suppressed because it is too large
Load Diff
1633
Multiplayer Core/patch_mp/maps/mp/_vehicles.gsc
Normal file
1633
Multiplayer Core/patch_mp/maps/mp/_vehicles.gsc
Normal file
File diff suppressed because it is too large
Load Diff
106
Multiplayer Core/patch_mp/maps/mp/animscripts/dog_combat.gsc
Normal file
106
Multiplayer Core/patch_mp/maps/mp/animscripts/dog_combat.gsc
Normal file
@ -0,0 +1,106 @@
|
||||
#include maps/mp/animscripts/utility;
|
||||
#include maps/mp/animscripts/shared;
|
||||
#include common_scripts/utility;
|
||||
|
||||
main()
|
||||
{
|
||||
debug_anim_print( "dog_combat::main() " );
|
||||
self endon( "killanimscript" );
|
||||
self setaimanimweights( 0, 0 );
|
||||
/#
|
||||
if ( !debug_allow_combat() )
|
||||
{
|
||||
combatidle();
|
||||
return;
|
||||
#/
|
||||
}
|
||||
if ( isDefined( level.hostmigrationtimer ) )
|
||||
{
|
||||
combatidle();
|
||||
return;
|
||||
}
|
||||
/#
|
||||
assert( isDefined( self.enemy ) );
|
||||
#/
|
||||
if ( !isalive( self.enemy ) )
|
||||
{
|
||||
combatidle();
|
||||
return;
|
||||
}
|
||||
if ( isplayer( self.enemy ) )
|
||||
{
|
||||
self meleebiteattackplayer( self.enemy );
|
||||
}
|
||||
}
|
||||
|
||||
combatidle()
|
||||
{
|
||||
self set_orient_mode( "face enemy" );
|
||||
self animmode( "zonly_physics", 0 );
|
||||
idleanims = [];
|
||||
idleanims[ 0 ] = "combat_attackidle";
|
||||
idleanims[ 1 ] = "combat_attackidle_bark";
|
||||
idleanims[ 2 ] = "combat_attackidle_growl";
|
||||
idleanim = random( idleanims );
|
||||
debug_anim_print( "dog_combat::combatIdle() - Setting " + idleanim );
|
||||
self setanimstate( idleanim );
|
||||
self maps/mp/animscripts/shared::donotetracks( "done" );
|
||||
debug_anim_print( "dog_combat::combatIdle() - " + idleanim + " notify done." );
|
||||
}
|
||||
|
||||
meleebiteattackplayer( player )
|
||||
{
|
||||
self set_orient_mode( "face enemy" );
|
||||
self animmode( "gravity", 0 );
|
||||
self.safetochangescript = 0;
|
||||
if ( use_low_attack() )
|
||||
{
|
||||
self animmode( "angle deltas", 0 );
|
||||
self setanimstate( "combat_attack_player_close_range" );
|
||||
wait 0,35;
|
||||
if ( isplayer( self.enemy ) && self.enemy getstance() == "prone" )
|
||||
{
|
||||
self meleewithoffset( vectorScale( ( 0, 0, -1 ), 9 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
self melee();
|
||||
}
|
||||
self maps/mp/animscripts/shared::donotetracksfortime( 1,2, "done" );
|
||||
self animmode( "gravity", 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
attack_time = 1,2 + randomfloat( 0,4 );
|
||||
debug_anim_print( "dog_combat::meleeBiteAttackPlayer() - Setting combat_run_attack" );
|
||||
self setanimstate( "combat_attack_run" );
|
||||
self maps/mp/animscripts/shared::donotetracksfortime( attack_time, "done", ::handlemeleebiteattacknotetracks, player );
|
||||
debug_anim_print( "dog_combat::meleeBiteAttackPlayer() - combat_attack_run notify done." );
|
||||
}
|
||||
self.safetochangescript = 1;
|
||||
self animmode( "none", 0 );
|
||||
}
|
||||
|
||||
handlemeleebiteattacknotetracks( note, player )
|
||||
{
|
||||
if ( note == "dog_melee" )
|
||||
{
|
||||
self melee( anglesToForward( self.angles ) );
|
||||
}
|
||||
}
|
||||
|
||||
use_low_attack()
|
||||
{
|
||||
if ( isplayer( self.enemy ) )
|
||||
{
|
||||
if ( self.enemy getstance() == "prone" )
|
||||
{
|
||||
attack_height = self.origin[ 2 ] + 16;
|
||||
if ( self.enemy.origin[ 2 ] < attack_height )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
62
Multiplayer Core/patch_mp/maps/mp/animscripts/dog_init.gsc
Normal file
62
Multiplayer Core/patch_mp/maps/mp/animscripts/dog_init.gsc
Normal file
@ -0,0 +1,62 @@
|
||||
#include maps/mp/animscripts/dog_combat;
|
||||
#include maps/mp/animscripts/dog_move;
|
||||
#include maps/mp/animscripts/utility;
|
||||
#include maps/mp/animscripts/shared;
|
||||
|
||||
main()
|
||||
{
|
||||
level.dog_debug_orient = 0;
|
||||
level.dog_debug_anims = 0;
|
||||
level.dog_debug_anims_ent = 0;
|
||||
level.dog_debug_turns = 0;
|
||||
debug_anim_print( "dog_init::main() " );
|
||||
maps/mp/animscripts/dog_move::setup_sound_variables();
|
||||
anim_get_dvar_int( "debug_dog_sound", "0" );
|
||||
anim_get_dvar_int( "debug_dog_notetracks", "0" );
|
||||
anim_get_dvar_int( "dog_force_walk", 0 );
|
||||
anim_get_dvar_int( "dog_force_run", 0 );
|
||||
self.ignoresuppression = 1;
|
||||
self.chatinitialized = 0;
|
||||
self.nododgemove = 1;
|
||||
level.dogrunturnspeed = 20;
|
||||
level.dogrunpainspeed = 20;
|
||||
self.meleeattackdist = 0;
|
||||
self thread setmeleeattackdist();
|
||||
self.a = spawnstruct();
|
||||
self.a.pose = "stand";
|
||||
self.a.nextstandinghitdying = 0;
|
||||
self.a.movement = "run";
|
||||
set_anim_playback_rate();
|
||||
self.suppressionthreshold = 1;
|
||||
self.disablearrivals = 0;
|
||||
level.dogstoppingdistsq = 3416,82;
|
||||
self.stopanimdistsq = level.dogstoppingdistsq;
|
||||
self.pathenemyfightdist = 512;
|
||||
self settalktospecies( "dog" );
|
||||
level.lastdogmeleeplayertime = 0;
|
||||
level.dogmeleeplayercounter = 0;
|
||||
if ( !isDefined( level.dog_hits_before_kill ) )
|
||||
{
|
||||
level.dog_hits_before_kill = 1;
|
||||
}
|
||||
}
|
||||
|
||||
set_anim_playback_rate()
|
||||
{
|
||||
self.animplaybackrate = 0,9 + randomfloat( 0,2 );
|
||||
self.moveplaybackrate = 1;
|
||||
}
|
||||
|
||||
setmeleeattackdist()
|
||||
{
|
||||
self endon( "death" );
|
||||
while ( 1 )
|
||||
{
|
||||
self.meleeattackdist = 0;
|
||||
if ( self maps/mp/animscripts/dog_combat::use_low_attack() )
|
||||
{
|
||||
self.meleeattackdist = 64;
|
||||
}
|
||||
wait 1;
|
||||
}
|
||||
}
|
2583
Multiplayer Core/patch_mp/maps/mp/bots/_bot.gsc
Normal file
2583
Multiplayer Core/patch_mp/maps/mp/bots/_bot.gsc
Normal file
File diff suppressed because it is too large
Load Diff
1870
Multiplayer Core/patch_mp/maps/mp/bots/_bot_combat.gsc
Normal file
1870
Multiplayer Core/patch_mp/maps/mp/bots/_bot_combat.gsc
Normal file
File diff suppressed because it is too large
Load Diff
100
Multiplayer Core/patch_mp/maps/mp/bots/_bot_conf.gsc
Normal file
100
Multiplayer Core/patch_mp/maps/mp/bots/_bot_conf.gsc
Normal file
@ -0,0 +1,100 @@
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
|
||||
bot_conf_think() //checked matches cerberus output
|
||||
{
|
||||
time = getTime();
|
||||
if ( time < self.bot.update_objective )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self.bot.update_objective = time + randomintrange( 500, 1500 );
|
||||
goal = self getgoal( "conf_dogtag" );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
if ( !conf_tag_in_radius( goal, 64 ) )
|
||||
{
|
||||
self cancelgoal( "conf_dogtag" );
|
||||
}
|
||||
}
|
||||
conf_get_tag_in_sight();
|
||||
}
|
||||
|
||||
conf_get_tag_in_sight() //checked partially changed to match cerberus output did not use foreach see github for more info
|
||||
{
|
||||
angles = self getplayerangles();
|
||||
forward = anglesToForward( angles );
|
||||
forward = vectornormalize( forward );
|
||||
closest = 999999;
|
||||
tags = level.dogtags;
|
||||
i = 0;
|
||||
while ( i < tags.size )
|
||||
{
|
||||
if ( is_true( tags[ i ].unreachable ) )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
distsq = distancesquared( tags[ i ].curorigin, self.origin );
|
||||
if ( distsq > closest )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
delta = tags[ i ].curorigin - self.origin;
|
||||
delta = vectornormalize( delta );
|
||||
dot = vectordot( forward, delta );
|
||||
if ( dot < self.bot.fov && distsq > 40000 )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if ( dot > self.bot.fov && distsq > 1440000 )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
nearest = getnearestnode( tags[ i ].curorigin );
|
||||
if ( !isDefined( nearest ) )
|
||||
{
|
||||
tags[ i ].unreachable = 1;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if ( ( tags[ i ].curorigin[ 2 ] - nearest.origin[ 2 ] ) > 18 )
|
||||
{
|
||||
tags[ i ].unreachable = 1;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if ( !isDefined( tags[ i ].unreachable ) && !findpath( self.origin, tags[ i ].curorigin, tags[ i ], 0, 1 ) )
|
||||
{
|
||||
tags[ i ].unreachable = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tags[ i ].unreachable = 0;
|
||||
}
|
||||
closest = distsq;
|
||||
closetag = tags[ i ];
|
||||
i++;
|
||||
}
|
||||
if ( isDefined( closetag ) )
|
||||
{
|
||||
self addgoal( closetag.curorigin, 16, 3, "conf_dogtag" );
|
||||
}
|
||||
}
|
||||
|
||||
conf_tag_in_radius( origin, radius ) //checked changed to match cerberus output
|
||||
{
|
||||
foreach ( tag in level.dogtags )
|
||||
{
|
||||
if ( distancesquared( origin, tag.curorigin ) < radius * radius )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
383
Multiplayer Core/patch_mp/maps/mp/bots/_bot_ctf.gsc
Normal file
383
Multiplayer Core/patch_mp/maps/mp/bots/_bot_ctf.gsc
Normal file
@ -0,0 +1,383 @@
|
||||
//checked includes match cerberus output
|
||||
#include maps/mp/gametypes/_gameobjects;
|
||||
#include maps/mp/bots/_bot_combat;
|
||||
#include maps/mp/bots/_bot;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/gametypes/ctf;
|
||||
|
||||
bot_ctf_think() //checked changed to match cerberus output changed at own discretion
|
||||
{
|
||||
time = getTime();
|
||||
if ( time < self.bot.update_objective )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self.bot.update_objective = time + randomintrange( 500, 1500 );
|
||||
if ( maps/mp/bots/_bot::bot_get_difficulty() != "easy" )
|
||||
{
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
if ( flag_mine ishome() && distancesquared( self.origin, flag_mine.curorigin ) < 262144 )
|
||||
{
|
||||
nodes = getnodesinradius( flag_mine.curorigin, 256, 0, 64, "any", 8 );
|
||||
node = random( nodes );
|
||||
if ( cointoss() )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( node.origin );
|
||||
}
|
||||
if ( cointoss() )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_toss_frag( node.origin );
|
||||
}
|
||||
if ( cointoss() )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_toss_flash( node.origin );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( bot_should_patrol_flag() )
|
||||
{
|
||||
bot_patrol_flag();
|
||||
return;
|
||||
}
|
||||
self cancelgoal( "ctf_flag_patrol" );
|
||||
if ( !bot_ctf_defend() )
|
||||
{
|
||||
bot_ctf_capture();
|
||||
}
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
flag_enemy = ctf_get_flag( getotherteam( self.team ) );
|
||||
home_mine = flag_mine ctf_flag_get_home();
|
||||
if ( ctf_has_flag( flag_enemy ) && self issprinting() && distancesquared( self.origin, home_mine ) < 36864 )
|
||||
{
|
||||
if ( bot_dot_product( home_mine ) > 0.9 )
|
||||
{
|
||||
self bot_dive_to_prone( "stand" );
|
||||
}
|
||||
}
|
||||
else if ( !flag_mine ishome() && !isDefined( flag_mine.carrier ) )
|
||||
{
|
||||
if ( self issprinting() && distancesquared( self.origin, flag_mine.curorigin ) < 36864 )
|
||||
{
|
||||
if ( bot_dot_product( flag_mine.curorigin ) > 0.9 )
|
||||
{
|
||||
self bot_dive_to_prone( "stand" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_should_patrol_flag() //checked matches cerberus output
|
||||
{
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
flag_enemy = ctf_get_flag( getotherteam( self.team ) );
|
||||
home_mine = flag_mine ctf_flag_get_home();
|
||||
if ( self hasgoal( "ctf_flag" ) && !self atgoal( "ctf_flag" ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( ctf_has_flag( flag_enemy ) )
|
||||
{
|
||||
if ( !flag_mine ishome() )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if ( !flag_mine ishome() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( distancesquared( self.origin, flag_enemy.curorigin ) < 262144 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( bot_get_friends().size && self maps/mp/bots/_bot::bot_friend_goal_in_radius( "ctf_flag_patrol", home_mine, 1024 ) == 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctf_get_flag( team ) //checked changed to match cerberus output
|
||||
{
|
||||
foreach ( f in level.flags )
|
||||
{
|
||||
if ( f maps/mp/gametypes/_gameobjects::getownerteam() == team )
|
||||
{
|
||||
return f;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
ctf_flag_get_home() //checked matches cerberus output
|
||||
{
|
||||
return self.trigger.baseorigin;
|
||||
}
|
||||
|
||||
ctf_has_flag( flag ) //checked changed at own discretion
|
||||
{
|
||||
if ( isDefined( flag.carrier ) && flag.carrier == self )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_ctf_capture() //checked changed to match cerberus output
|
||||
{
|
||||
flag_enemy = ctf_get_flag( getotherteam( self.team ) );
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
home_enemy = flag_enemy ctf_flag_get_home();
|
||||
home_mine = flag_mine ctf_flag_get_home();
|
||||
if ( ctf_has_flag( flag_enemy ) )
|
||||
{
|
||||
self addgoal( home_mine, 16, 4, "ctf_flag" );
|
||||
}
|
||||
else if ( isDefined( flag_enemy.carrier ) )
|
||||
{
|
||||
if ( self atgoal( "ctf_flag" ) )
|
||||
{
|
||||
self cancelgoal( "ctf_flag" );
|
||||
}
|
||||
goal = self getgoal( "ctf_flag" );
|
||||
if ( isDefined( goal ) && distancesquared( goal, flag_enemy.carrier.origin ) < 589824 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
nodes = getnodesinradius( flag_enemy.carrier.origin, 512, 64, 256, "any", 8 );
|
||||
if ( nodes.size )
|
||||
{
|
||||
self addgoal( random( nodes ), 16, 3, "ctf_flag" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self addgoal( flag_enemy.carrier.origin, 16, 3, "ctf_flag" );
|
||||
}
|
||||
}
|
||||
else if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "ctf_flag", flag_enemy.curorigin, 16 ) <= 1 )
|
||||
{
|
||||
self addgoal( flag_enemy.curorigin, 16, 3, "ctf_flag" );
|
||||
}
|
||||
}
|
||||
|
||||
bot_ctf_defend() //checked changed to match cerberus output
|
||||
{
|
||||
flag_enemy = ctf_get_flag( getotherteam( self.team ) );
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
home_enemy = flag_enemy ctf_flag_get_home();
|
||||
home_mine = flag_mine ctf_flag_get_home();
|
||||
if ( flag_mine ishome() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( ctf_has_flag( flag_enemy ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( !isDefined( flag_mine.carrier ) )
|
||||
{
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "ctf_flag", flag_mine.curorigin, 16 ) <= 1 )
|
||||
{
|
||||
return self bot_ctf_add_goal( flag_mine.curorigin, 4, "ctf_flag" );
|
||||
}
|
||||
}
|
||||
else if ( !flag_enemy ishome() || distance2dsquared( self.origin, home_enemy ) > 250000 )
|
||||
{
|
||||
return self bot_ctf_add_goal( flag_mine.curorigin, 4, "ctf_flag" );
|
||||
}
|
||||
else if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "ctf_flag", home_enemy, 16 ) <= 1 )
|
||||
{
|
||||
self addgoal( home_enemy, 16, 4, "ctf_flag" );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bot_ctf_add_goal( origin, goal_priority, goal_name ) //checked matches cerberus output
|
||||
{
|
||||
goal = undefined;
|
||||
if ( findpath( self.origin, origin, undefined, 0, 1 ) )
|
||||
{
|
||||
goal = origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
node = bot_ctf_random_visible_node( origin );
|
||||
if ( isDefined( node ) )
|
||||
{
|
||||
if ( findpath( self.origin, node.origin, undefined, 0, 1 ) )
|
||||
{
|
||||
goal = node;
|
||||
self.bot.update_objective += randomintrange( 3000, 5000 );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
self addgoal( goal, 16, goal_priority, goal_name );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_get_look_at() //checked matches cerberus output
|
||||
{
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( self.origin, 1 );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
}
|
||||
enemies = self maps/mp/bots/_bot::bot_get_enemies( 0 );
|
||||
if ( enemies.size )
|
||||
{
|
||||
enemy = random( enemies );
|
||||
}
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
}
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
home_mine = flag_mine ctf_flag_get_home();
|
||||
return home_mine;
|
||||
}
|
||||
|
||||
bot_patrol_flag() //checked changed to match cerberus output
|
||||
{
|
||||
self cancelgoal( "ctf_flag" );
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
if ( self atgoal( "ctf_flag_patrol" ) )
|
||||
{
|
||||
node = getnearestnode( self.origin );
|
||||
if ( !isDefined( node ) )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "ctf_flag_patrol" );
|
||||
return;
|
||||
}
|
||||
if ( node.type == "Path" )
|
||||
{
|
||||
self setstance( "crouch" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self setstance( "stand" );
|
||||
}
|
||||
if ( getTime() > self.bot.update_lookat )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
z = 20;
|
||||
if ( distancesquared( origin, self.origin ) > 262144 )
|
||||
{
|
||||
z = randomintrange( 16, 60 );
|
||||
}
|
||||
self lookat( origin + ( 0, 0, z ) );
|
||||
if ( distancesquared( origin, self.origin ) > 65536 )
|
||||
{
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = vectorScale( dir, 256 );
|
||||
origin += dir;
|
||||
}
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( origin );
|
||||
self.bot.update_lookat = getTime() + randomintrange( 1500, 3000 );
|
||||
}
|
||||
goal = self getgoal( "ctf_flag_patrol" );
|
||||
nearest = base_nearest_node( flag_mine );
|
||||
mine = getnearestnode( goal );
|
||||
if ( isDefined( mine ) && !nodesvisible( mine, nearest ) )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "ctf_flag_patrol" );
|
||||
}
|
||||
if ( getTime() > self.bot.update_objective_patrol )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "ctf_flag_patrol" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
nearest = base_nearest_node( flag_mine );
|
||||
if ( self hasgoal( "ctf_flag_patrol" ) )
|
||||
{
|
||||
goal = self getgoal( "ctf_flag_patrol" );
|
||||
if ( distancesquared( self.origin, goal ) < 65536 )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
self lookat( origin );
|
||||
}
|
||||
if ( distancesquared( self.origin, goal ) < 16384 )
|
||||
{
|
||||
self.bot.update_objective_patrol = getTime() + randomintrange( 3000, 6000 );
|
||||
}
|
||||
mine = getnearestnode( goal );
|
||||
if ( isDefined( mine ) && !nodesvisible( mine, nearest ) )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "ctf_flag_patrol" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ( getTime() < self.bot.update_objective_patrol )
|
||||
{
|
||||
return;
|
||||
}
|
||||
nodes = getvisiblenodes( nearest );
|
||||
/*
|
||||
/#
|
||||
assert( nodes.size );
|
||||
#/
|
||||
*/
|
||||
for ( i = randomint(nodes.size); i < nodes.size; i++ )
|
||||
{
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "ctf_flag_patrol", nodes[ i ].origin, 256 ) == 0 )
|
||||
{
|
||||
self addgoal( nodes[ i ], 24, 3, "ctf_flag_patrol" );
|
||||
self.bot.update_objective_patrol = getTime() + randomintrange( 3000, 6000 );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base_nearest_node( flag ) //checked matches cerberus output
|
||||
{
|
||||
home = flag ctf_flag_get_home();
|
||||
nodes = getnodesinradiussorted( home, 256, 0 );
|
||||
/*
|
||||
/#
|
||||
assert( nodes.size );
|
||||
#/
|
||||
*/
|
||||
return nodes[ 0 ];
|
||||
}
|
||||
|
||||
bot_ctf_random_visible_node( origin ) //checked changed to match cerberus output
|
||||
{
|
||||
nodes = getnodesinradius( origin, 384, 0, 256 );
|
||||
nearest = maps/mp/bots/_bot_combat::bot_nearest_node( origin );
|
||||
if ( isDefined( nearest ) && nodes.size )
|
||||
{
|
||||
current = randomintrange( 0, nodes.size );
|
||||
for ( i = 0; i < nodes.size; i++ )
|
||||
{
|
||||
current = ( current + 1 ) % nodes.size;
|
||||
if ( nodesvisible( nodes[ current ], nearest ) )
|
||||
{
|
||||
return nodes[ current ];
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
331
Multiplayer Core/patch_mp/maps/mp/bots/_bot_dem.gsc
Normal file
331
Multiplayer Core/patch_mp/maps/mp/bots/_bot_dem.gsc
Normal file
@ -0,0 +1,331 @@
|
||||
//checked changed includes to match cerberus output
|
||||
#include maps/mp/bots/_bot;
|
||||
#include maps/mp/bots/_bot_combat;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/gametypes/dem;
|
||||
|
||||
bot_dem_think() //checked changed to match cerberus output
|
||||
{
|
||||
if ( !isDefined( level.bombzones[ 0 ].dem_nodes ) )
|
||||
{
|
||||
foreach ( zone in level.bombzones )
|
||||
{
|
||||
zone.dem_nodes = [];
|
||||
zone.dem_nodes = getnodesinradius( zone.trigger.origin, 1024, 64, 128, "Path" );
|
||||
}
|
||||
}
|
||||
if ( self.team == game[ "attackers" ] )
|
||||
{
|
||||
bot_dem_attack_think();
|
||||
}
|
||||
else
|
||||
{
|
||||
bot_dem_defend_think();
|
||||
}
|
||||
}
|
||||
|
||||
bot_dem_attack_think() //checked partially changed to match cerberus output changed at own discretion
|
||||
{
|
||||
zones = dem_get_alive_zones();
|
||||
if ( !zones.size )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( !isDefined( self.goal_flag ) )
|
||||
{
|
||||
zones = array_randomize( zones );
|
||||
foreach ( zone in zones )
|
||||
{
|
||||
if ( zones.size == 1 || is_true( zone.bombplanted ) && !is_true( zone.bombexploded ) )
|
||||
{
|
||||
self.goal_flag = zone;
|
||||
break;
|
||||
}
|
||||
if ( randomint( 100 ) < 50 )
|
||||
{
|
||||
self.goal_flag = zone;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( isDefined( self.goal_flag ) )
|
||||
{
|
||||
if ( is_true( self.goal_flag.bombexploded ) )
|
||||
{
|
||||
self.goal_flag = undefined;
|
||||
self cancelgoal( "dem_guard" );
|
||||
self cancelgoal( "bomb" );
|
||||
}
|
||||
else if ( is_true( self.goal_flag.bombplanted ) )
|
||||
{
|
||||
self bot_dem_guard( self.goal_flag, self.goal_flag.dem_nodes, self.goal_flag.trigger.origin );
|
||||
}
|
||||
else if ( self bot_dem_friend_interacting( self.goal_flag.trigger.origin ) )
|
||||
{
|
||||
self bot_dem_guard( self.goal_flag, self.goal_flag.dem_nodes, self.goal_flag.trigger.origin );
|
||||
}
|
||||
else
|
||||
{
|
||||
self bot_dem_attack( self.goal_flag );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_dem_defend_think() //checked partially changed to match cerberus output changed at own discretion
|
||||
{
|
||||
zones = dem_get_alive_zones();
|
||||
if ( !zones.size )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( !isDefined( self.goal_flag ) )
|
||||
{
|
||||
zones = array_randomize( zones );
|
||||
foreach ( zone in zones )
|
||||
{
|
||||
if ( zones.size == 1 || is_true( zone.bombplanted ) && !is_true( zone.bombexploded ) )
|
||||
{
|
||||
self.goal_flag = zone;
|
||||
break;
|
||||
}
|
||||
if ( randomint( 100 ) < 50 )
|
||||
{
|
||||
self.goal_flag = zone;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( isDefined( self.goal_flag ) )
|
||||
{
|
||||
if ( is_true( self.goal_flag.bombexploded ) )
|
||||
{
|
||||
self.goal_flag = undefined;
|
||||
self cancelgoal( "dem_guard" );
|
||||
self cancelgoal( "bomb" );
|
||||
}
|
||||
else if ( is_true( self.goal_flag.bombplanted ) && !self bot_dem_friend_interacting( self.goal_flag.trigger.origin ) )
|
||||
{
|
||||
self bot_dem_defuse( self.goal_flag );
|
||||
}
|
||||
else
|
||||
{
|
||||
self bot_dem_guard( self.goal_flag, self.goal_flag.dem_nodes, self.goal_flag.trigger.origin );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_dem_attack( zone ) //checked changed to match cerberus output
|
||||
{
|
||||
self cancelgoal( "dem_guard" );
|
||||
if ( !self hasgoal( "bomb" ) )
|
||||
{
|
||||
self.bomb_goal = self dem_get_bomb_goal( zone.visuals[ 0 ] );
|
||||
if ( isDefined( self.bomb_goal ) )
|
||||
{
|
||||
self addgoal( self.bomb_goal, 48, 2, "bomb" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ( !self atgoal( "bomb" ) )
|
||||
{
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_smoke( self.bomb_goal ) )
|
||||
{
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( self.bomb_goal ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_lethal( self.bomb_goal );
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
self addgoal( self.bomb_goal, 48, 4, "bomb" );
|
||||
self setstance( "prone" );
|
||||
self pressusebutton( level.planttime + 1 );
|
||||
wait 0.5;
|
||||
if ( is_true( self.isplanting ) )
|
||||
{
|
||||
wait ( level.planttime + 1 );
|
||||
}
|
||||
self pressusebutton( 0 );
|
||||
defenders = self bot_get_enemies();
|
||||
foreach ( defender in defenders )
|
||||
{
|
||||
if ( defender is_bot() )
|
||||
{
|
||||
defender.goal_flag = undefined;
|
||||
}
|
||||
}
|
||||
self setstance( "crouch" );
|
||||
wait 0.25;
|
||||
self cancelgoal( "bomb" );
|
||||
self setstance( "stand" );
|
||||
}
|
||||
|
||||
bot_dem_guard( zone, nodes, origin ) //checked matches cerberus output
|
||||
{
|
||||
self cancelgoal( "bomb" );
|
||||
enemy = self bot_dem_enemy_interacting( origin );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_lethal( enemy.origin );
|
||||
self addgoal( enemy.origin, 128, 3, "dem_guard" );
|
||||
return;
|
||||
}
|
||||
enemy = self bot_dem_enemy_nearby( origin );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_lethal( enemy.origin );
|
||||
self addgoal( enemy.origin, 128, 3, "dem_guard" );
|
||||
return;
|
||||
}
|
||||
if ( self hasgoal( "dem_guard" ) && !self atgoal( "dem_guard" ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( origin );
|
||||
return;
|
||||
}
|
||||
node = random( nodes );
|
||||
self addgoal( node, 24, 2, "dem_guard" );
|
||||
}
|
||||
|
||||
bot_dem_defuse( zone ) //checked matches cerberus output
|
||||
{
|
||||
self cancelgoal( "dem_guard" );
|
||||
if ( !self hasgoal( "bomb" ) )
|
||||
{
|
||||
self.bomb_goal = self dem_get_bomb_goal( zone.visuals[ 0 ] );
|
||||
if ( isDefined( self.bomb_goal ) )
|
||||
{
|
||||
self addgoal( self.bomb_goal, 48, 2, "bomb" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ( !self atgoal( "bomb" ) )
|
||||
{
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_smoke( self.bomb_goal ) )
|
||||
{
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( self.bomb_goal ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_lethal( self.bomb_goal );
|
||||
}
|
||||
}
|
||||
if ( ( self.goal_flag.detonatetime - getTime() ) < 12000 )
|
||||
{
|
||||
self addgoal( self.bomb_goal, 48, 4, "bomb" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
self addgoal( self.bomb_goal, 48, 4, "bomb" );
|
||||
if ( cointoss() )
|
||||
{
|
||||
self setstance( "crouch" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self setstance( "prone" );
|
||||
}
|
||||
self pressusebutton( level.defusetime + 1 );
|
||||
wait 0.5;
|
||||
if ( is_true( self.isdefusing ) )
|
||||
{
|
||||
wait ( level.defusetime + 1 );
|
||||
}
|
||||
self pressusebutton( 0 );
|
||||
self setstance( "crouch" );
|
||||
wait 0.25;
|
||||
self cancelgoal( "bomb" );
|
||||
self setstance( "stand" );
|
||||
}
|
||||
|
||||
bot_dem_enemy_interacting( origin ) //checked partially changed to match cerberus output did not use continue see github for more info
|
||||
{
|
||||
enemies = maps/mp/bots/_bot::bot_get_enemies();
|
||||
foreach ( enemy in enemies )
|
||||
{
|
||||
if ( distancesquared( enemy.origin, origin ) > 65536 )
|
||||
{
|
||||
}
|
||||
else if ( is_true( enemy.isdefusing ) || is_true( enemy.isplanting ) )
|
||||
{
|
||||
return enemy;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
bot_dem_friend_interacting( origin ) //checked partially changed to match cerberus output did not use continue see github for more info
|
||||
{
|
||||
friends = maps/mp/bots/_bot::bot_get_friends();
|
||||
foreach ( friend in friends )
|
||||
{
|
||||
if ( distancesquared( friend.origin, origin ) > 65536 )
|
||||
{
|
||||
}
|
||||
else if ( is_true( friend.isdefusing ) || is_true( friend.isplanting ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_dem_enemy_nearby( origin ) //checked matches cerberus output
|
||||
{
|
||||
enemy = maps/mp/bots/_bot::bot_get_closest_enemy( origin, 1 );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
if ( distancesquared( enemy.origin, origin ) < 1048576 )
|
||||
{
|
||||
return enemy;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
dem_get_alive_zones() //checked partially changed to match cerberus output did not use continue see github for more info
|
||||
{
|
||||
zones = [];
|
||||
foreach ( zone in level.bombzones )
|
||||
{
|
||||
if ( is_true( zone.bombexploded ) )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
zones[ zones.size ] = zone;
|
||||
}
|
||||
}
|
||||
return zones;
|
||||
}
|
||||
|
||||
dem_get_bomb_goal( ent ) //checked changed to match cerberus output
|
||||
{
|
||||
if ( !isDefined( ent.bot_goals ) )
|
||||
{
|
||||
goals = [];
|
||||
ent.bot_goals = [];
|
||||
dir = anglesToForward( ent.angles );
|
||||
dir = vectorScale( dir, 32 );
|
||||
goals[ 0 ] = ent.origin + dir;
|
||||
goals[ 1 ] = ent.origin - dir;
|
||||
dir = anglesToRight( ent.angles );
|
||||
dir = vectorScale( dir, 48 );
|
||||
goals[ 2 ] = ent.origin + dir;
|
||||
goals[ 3 ] = ent.origin - dir;
|
||||
foreach ( goal in goals )
|
||||
{
|
||||
start = goal + vectorScale( ( 0, 0, 1 ), 128 );
|
||||
trace = bullettrace( start, goal, 0, undefined );
|
||||
ent.bot_goals[ ent.bot_goals.size ] = trace[ "position" ];
|
||||
}
|
||||
}
|
||||
goals = array_randomize( ent.bot_goals );
|
||||
foreach ( goal in goals )
|
||||
{
|
||||
if ( findpath( self.origin, goal, 0 ) )
|
||||
{
|
||||
return goal;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
463
Multiplayer Core/patch_mp/maps/mp/bots/_bot_dom.gsc
Normal file
463
Multiplayer Core/patch_mp/maps/mp/bots/_bot_dom.gsc
Normal file
@ -0,0 +1,463 @@
|
||||
//checked includes match cerberus output
|
||||
#include maps/mp/bots/_bot;
|
||||
#include maps/mp/bots/_bot_combat;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/gametypes/dom;
|
||||
|
||||
bot_dom_think() //checked changed to match cerberus output
|
||||
{
|
||||
time = getTime();
|
||||
if ( time < self.bot.update_objective )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self.bot.update_objective = time + randomintrange( 500, 1500 );
|
||||
if ( self bot_is_capturing_flag() )
|
||||
{
|
||||
flag = self dom_get_closest_flag();
|
||||
self bot_capture_flag( flag );
|
||||
return;
|
||||
}
|
||||
flag = self dom_get_closest_flag();
|
||||
if ( flag getflagteam() != self.team && distance2dsquared( self.origin, flag.origin ) < 147456 && !bot_has_flag_goal( flag ) )
|
||||
{
|
||||
self bot_move_to_flag( flag );
|
||||
return;
|
||||
}
|
||||
flag = dom_get_weighted_flag( "neutral" );
|
||||
if ( !isDefined( flag ) )
|
||||
{
|
||||
flag = dom_get_best_flag( self.team );
|
||||
}
|
||||
if ( dom_has_two_flags( self.team ) )
|
||||
{
|
||||
flag = dom_get_best_flag( self.team );
|
||||
}
|
||||
if ( !isDefined( flag ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( !bot_has_flag_goal( flag ) && !self bot_goal_is_enemy_flag() )
|
||||
{
|
||||
self bot_move_to_flag( flag );
|
||||
}
|
||||
else if ( !dom_is_game_start() )
|
||||
{
|
||||
self bot_flag_grenade( flag );
|
||||
}
|
||||
if ( distancesquared( self.origin, flag.origin ) < ( flag.radius * flag.radius ) && self istouching( flag.useobj.trigger ) )
|
||||
{
|
||||
self bot_capture_flag( flag );
|
||||
}
|
||||
}
|
||||
|
||||
bot_move_to_flag( flag ) //checked matches cerberus output
|
||||
{
|
||||
if ( level.script == "mp_frostbite" )
|
||||
{
|
||||
nodes = getnodesinradius( flag.origin, flag.radius, 0, 32 );
|
||||
}
|
||||
else
|
||||
{
|
||||
nodes = getnodesinradius( flag.origin, flag.radius, 0 );
|
||||
}
|
||||
/*
|
||||
/#
|
||||
assert( nodes.size );
|
||||
#/
|
||||
*/
|
||||
node = random( nodes );
|
||||
self addgoal( node, 24, 3, "dom_flag" );
|
||||
}
|
||||
|
||||
bot_is_capturing_flag() //checked matches cerberus output
|
||||
{
|
||||
return self atgoal( "dom_flag" );
|
||||
}
|
||||
|
||||
bot_has_flag_goal( flag ) //checked matches cerberus output
|
||||
{
|
||||
origin = self getgoal( "dom_flag" );
|
||||
if ( isDefined( origin ) )
|
||||
{
|
||||
if ( distancesquared( flag.origin, origin ) < ( flag.radius * flag.radius ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_has_no_goal() //checked matches cerberus output
|
||||
{
|
||||
origin = self getgoal( "dom_flag" );
|
||||
if ( isDefined( origin ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bot_goal_is_enemy_flag() //checked changed to match cerberus output
|
||||
{
|
||||
origin = self getgoal( "dom_flag" );
|
||||
if ( isDefined( origin ) )
|
||||
{
|
||||
foreach(flag in level.flags)
|
||||
{
|
||||
if ( distancesquared( flag.origin, origin ) < ( flag.radius * flag.radius ) )
|
||||
{
|
||||
if ( flag getflagteam() != self.team || dom_is_flag_contested( flag ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_flag_grenade( flag ) //checked matches cerberus output
|
||||
{
|
||||
if ( flag getflagteam() != self.team )
|
||||
{
|
||||
if ( bot_tactical_insertion( flag ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_smoke( flag.origin );
|
||||
}
|
||||
if ( !dom_is_flag_contested( flag ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_lethal( flag.origin ) )
|
||||
{
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_tactical( flag.origin ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( flag.origin );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_get_look_at( flag ) //checked matches cerberus output
|
||||
{
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( self.origin, 0 );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
}
|
||||
spawn = random( level.spawn_all );
|
||||
node = getvisiblenode( self.origin, spawn.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
return flag.origin;
|
||||
}
|
||||
|
||||
bot_capture_flag( flag ) //checked changed to match cerberus output
|
||||
{
|
||||
time = getTime();
|
||||
if ( flag getflagteam() != self.team )
|
||||
{
|
||||
if ( self getstance() == "prone" )
|
||||
{
|
||||
self addgoal( self.origin, 24, 4, "dom_flag" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self addgoal( self.origin, 24, 3, "dom_flag" );
|
||||
}
|
||||
if ( time > self.bot.update_lookat )
|
||||
{
|
||||
origin = self bot_get_look_at( flag );
|
||||
z = 20;
|
||||
if ( distancesquared( origin, self.origin ) > 262144 )
|
||||
{
|
||||
z = randomintrange( 16, 60 );
|
||||
}
|
||||
self lookat( origin + ( 0, 0, z ) );
|
||||
self.bot.update_lookat = time + randomintrange( 1500, 3000 );
|
||||
if ( distancesquared( origin, self.origin ) > 65536 )
|
||||
{
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = vectorScale( dir, 256 );
|
||||
origin += dir;
|
||||
}
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( origin );
|
||||
self maps/mp/bots/_bot_combat::bot_combat_toss_frag( self.origin );
|
||||
self maps/mp/bots/_bot_combat::bot_combat_toss_flash( self.origin );
|
||||
if ( !dom_is_game_start() )
|
||||
{
|
||||
weapon = self getcurrentweapon();
|
||||
if ( weapon == "riotshield_mp" || weapon == "minigun_mp" )
|
||||
{
|
||||
if ( cointoss() )
|
||||
{
|
||||
self addgoal( self.origin, 24, 4, "dom_flag" );
|
||||
self setstance( "crouch" );
|
||||
}
|
||||
}
|
||||
else if ( cointoss() && !bot_friend_in_radius( self.origin, 384 ) )
|
||||
{
|
||||
self addgoal( self.origin, 24, 4, "dom_flag" );
|
||||
wait randomfloatrange( 0.5, 1 );
|
||||
self setstance( "prone" );
|
||||
self.bot.update_lookat += 5000;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( !dom_is_game_start() )
|
||||
{
|
||||
if ( self getstance() == "stand" )
|
||||
{
|
||||
wait randomfloatrange( 0.5, 1 );
|
||||
self setstance( "crouch" );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "dom_flag" );
|
||||
if ( self getstance() == "crouch" )
|
||||
{
|
||||
self setstance( "stand" );
|
||||
wait 0.25;
|
||||
}
|
||||
else if ( self getstance() == "prone" )
|
||||
{
|
||||
self setstance( "crouch" );
|
||||
wait 0.25;
|
||||
self setstance( "stand" );
|
||||
wait 0.25;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dom_is_game_start() //checked changed to match cerberus output
|
||||
{
|
||||
/*
|
||||
/#
|
||||
assert( isDefined( level.flags ) );
|
||||
#/
|
||||
*/
|
||||
foreach ( flag in level.flags )
|
||||
{
|
||||
if ( flag getflagteam() != "neutral" )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
dom_get_closest_flag() //checked matches cerberus output
|
||||
{
|
||||
flags = arraysort( level.flags, self.origin );
|
||||
return flags[ 0 ];
|
||||
}
|
||||
|
||||
dom_get_weighted_flag( owner ) //checked partially changed to match cerberus output did not use continue see github for more info
|
||||
{
|
||||
/*
|
||||
/#
|
||||
assert( isDefined( level.flags ) );
|
||||
#/
|
||||
*/
|
||||
best = undefined;
|
||||
distsq = 9999999;
|
||||
foreach ( flag in level.flags )
|
||||
{
|
||||
if ( isDefined( owner ) && flag getflagteam() != owner )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
d = distancesquared( self.origin, flag.origin );
|
||||
if ( distsq != 9999999 && d < distsq || randomint( 100 ) < 70 && randomint( 100 ) > 70 )
|
||||
{
|
||||
best = flag;
|
||||
distsq = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
dom_get_weighted_enemy_flag( team ) //checked partially changed to match cerberus output did not use continue see github for more info
|
||||
{
|
||||
/*
|
||||
/#
|
||||
assert( isDefined( level.flags ) );
|
||||
#/
|
||||
*/
|
||||
best = undefined;
|
||||
distsq = 9999999;
|
||||
foreach ( flag in level.flags )
|
||||
{
|
||||
if ( flag getflagteam() == team )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
d = distancesquared( self.origin, flag.origin );
|
||||
if ( distsq != 9999999 && d < distsq || randomint( 100 ) < 80 && randomint( 100 ) > 80 )
|
||||
{
|
||||
best = flag;
|
||||
distsq = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
dom_is_flag_contested( flag ) //checked changed at own discretion
|
||||
{
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( flag.origin, 0 );
|
||||
if ( isDefined( enemy ) && distancesquared( enemy.origin, flag.origin ) < 147456 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
dom_has_two_flags( team ) //checked partially changed to match cerberus output did not use continue see github for more info
|
||||
{
|
||||
count = 0;
|
||||
foreach ( flag in level.flags )
|
||||
{
|
||||
if ( dom_is_flag_contested( flag ) )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( flag getflagteam() == team )
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count >= 2;
|
||||
}
|
||||
|
||||
dom_get_weighted_contested_flag( team ) //checked partially changed to match cerberus output did not use continue see github for more info
|
||||
{
|
||||
/*
|
||||
/#
|
||||
assert( isDefined( level.flags ) );
|
||||
#/
|
||||
*/
|
||||
best = undefined;
|
||||
distsq = 9999999;
|
||||
foreach ( flag in level.flags )
|
||||
{
|
||||
if ( !dom_is_flag_contested( flag ) )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
d = distancesquared( self.origin, flag.origin );
|
||||
if ( distsq != 9999999 && d < distsq || randomint( 100 ) < 80 && randomint( 100 ) > 80 )
|
||||
{
|
||||
best = flag;
|
||||
distsq = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
dom_get_random_flag( owner ) //checked changed to match cerberus output
|
||||
{
|
||||
/*
|
||||
/#
|
||||
assert( isDefined( level.flags ) );
|
||||
#/
|
||||
*/
|
||||
flagindex = randomintrange( 0, level.flags.size );
|
||||
if ( !isDefined( owner ) )
|
||||
{
|
||||
return level.flags[ flagindex ];
|
||||
}
|
||||
for ( i = 0; i < level.flags.size; i++ )
|
||||
{
|
||||
if ( level.flags[ flagindex ] getflagteam() == owner )
|
||||
{
|
||||
return level.flags[ flagindex ];
|
||||
}
|
||||
flagindex = ( flagindex + 1 ) % level.flags.size;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
dom_get_best_flag( team ) //checked matches cerberus output
|
||||
{
|
||||
flag1 = dom_get_weighted_enemy_flag( team );
|
||||
flag2 = dom_get_weighted_contested_flag( team );
|
||||
if ( !isDefined( flag1 ) )
|
||||
{
|
||||
return flag2;
|
||||
}
|
||||
if ( !isDefined( flag2 ) )
|
||||
{
|
||||
return flag1;
|
||||
}
|
||||
offchance = randomint( 100 ) > 80;
|
||||
if ( distancesquared( self.origin, flag1.origin ) < distancesquared( self.origin, flag2.origin ) )
|
||||
{
|
||||
if ( !offchance )
|
||||
{
|
||||
return flag1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return flag2;
|
||||
}
|
||||
}
|
||||
if ( !offchance )
|
||||
{
|
||||
return flag2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return flag1;
|
||||
}
|
||||
}
|
||||
|
||||
bot_tactical_insertion( flag ) //checked matches cerberus output
|
||||
{
|
||||
if ( self getweaponammostock( "tactical_insertion_mp" ) <= 0 )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
dist = self getlookaheaddist();
|
||||
dir = self getlookaheaddir();
|
||||
if ( !isDefined( dist ) || !isDefined( dir ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
node = bot_nearest_node( flag.origin );
|
||||
mine = bot_nearest_node( self.origin );
|
||||
if ( isDefined( mine ) && !nodesvisible( mine, node ) )
|
||||
{
|
||||
origin = self.origin + vectorScale( dir, dist );
|
||||
next = bot_nearest_node( origin );
|
||||
if ( next isdangerous( self.team ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( isDefined( next ) && nodesvisible( next, node ) )
|
||||
{
|
||||
return bot_combat_tactical_insertion( self.origin );
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
179
Multiplayer Core/patch_mp/maps/mp/bots/_bot_hack.gsc
Normal file
179
Multiplayer Core/patch_mp/maps/mp/bots/_bot_hack.gsc
Normal file
@ -0,0 +1,179 @@
|
||||
#include maps/mp/bots/_bot;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/gametypes/ctf;
|
||||
|
||||
bot_hack_tank_get_goal_origin( tank ) //checked changed to match cerberus output
|
||||
{
|
||||
nodes = getnodesinradiussorted( tank.origin, 256, 0, 64, "Path" );
|
||||
foreach ( node in nodes )
|
||||
{
|
||||
dir = vectornormalize( node.origin - tank.origin );
|
||||
dir = vectorScale( dir, 32 );
|
||||
goal = tank.origin + dir;
|
||||
if ( findpath( self.origin, goal, 0 ) )
|
||||
{
|
||||
return goal;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
bot_hack_has_goal( tank ) //checked matches cerberus output
|
||||
{
|
||||
goal = self getgoal( "hack" );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
if ( distancesquared( goal, tank.origin ) < 16384 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_hack_at_goal() //checked changed to match cerberus output
|
||||
{
|
||||
if ( self atgoal( "hack" ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
goal = self getgoal( "hack" );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
tanks = getentarray( "talon", "targetname" );
|
||||
tanks = arraysort( tanks, self.origin );
|
||||
foreach ( tank in tanks )
|
||||
{
|
||||
if ( distancesquared( goal, tank.origin ) < 16384 )
|
||||
{
|
||||
if ( isDefined( tank.trigger ) && self istouching( tank.trigger ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_hack_goal_pregame( tanks ) //checked partially changed to match cerberus output did not use foreach see github for more info
|
||||
{
|
||||
i = 0;
|
||||
while ( i < tanks.size )
|
||||
{
|
||||
if ( isDefined( tanks[ i ].owner ) )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if ( isDefined( tanks[ i ].team ) && tanks[ i ].team == self.team )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
goal = self bot_hack_tank_get_goal_origin( tanks[ i ] );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
if ( self addgoal( goal, 24, 2, "hack" ) )
|
||||
{
|
||||
self.goal_flag = tanks[ i ];
|
||||
return;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
bot_hack_think() //checked partially changed to match cerberus output did not us foreach see github for more info
|
||||
{
|
||||
if ( bot_hack_at_goal() )
|
||||
{
|
||||
self setstance( "crouch" );
|
||||
wait 0.25;
|
||||
self addgoal( self.origin, 24, 4, "hack" );
|
||||
self pressusebutton( level.drone_hack_time + 1 );
|
||||
wait ( level.drone_hack_time + 1 );
|
||||
self setstance( "stand" );
|
||||
self cancelgoal( "hack" );
|
||||
}
|
||||
tanks = getentarray( "talon", "targetname" );
|
||||
tanks = arraysort( tanks, self.origin );
|
||||
if ( !is_true( level.drones_spawned ) )
|
||||
{
|
||||
self bot_hack_goal_pregame( tanks );
|
||||
}
|
||||
i = 0;
|
||||
while ( i < tanks.size )
|
||||
{
|
||||
if ( isDefined( tanks[ i ].owner ) && tanks[ i ].owner == self )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if ( !isDefined( tanks[ i ].owner ) )
|
||||
{
|
||||
if ( self bot_hack_has_goal( tanks[ i ] ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
goal = self bot_hack_tank_get_goal_origin( tanks[ i ] );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
self addgoal( goal, 24, 2, "hack" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ( tanks[ i ].isstunned && distancesquared( self.origin, tanks[ i ].origin ) < 262144 )
|
||||
{
|
||||
goal = self bot_hack_tank_get_goal_origin( tanks[ i ] );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
self addgoal( goal, 24, 3, "hack" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if ( !maps/mp/bots/_bot::bot_vehicle_weapon_ammo( "emp_grenade_mp" ) )
|
||||
{
|
||||
ammo = getentarray( "weapon_scavenger_item_hack_mp", "classname" );
|
||||
ammo = arraysort( ammo, self.origin );
|
||||
foreach ( bag in ammo )
|
||||
{
|
||||
if ( findpath( self.origin, bag.origin, 0 ) )
|
||||
{
|
||||
self addgoal( bag.origin, 24, 2, "hack" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
i = 0;
|
||||
while ( i < tanks.size )
|
||||
{
|
||||
if ( isDefined( tanks[ i ].owner ) && tanks[ i ].owner == self )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if ( tanks[ i ].isstunned )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if ( self throwgrenade( "emp_grenade_mp", tanks[ i ].origin ) )
|
||||
{
|
||||
self waittill( "grenade_fire" );
|
||||
goal = self bot_hack_tank_get_goal_origin( tanks[ i ] );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
self addgoal( goal, 24, 3, "hack" );
|
||||
wait 0.5;
|
||||
return;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
362
Multiplayer Core/patch_mp/maps/mp/bots/_bot_hq.gsc
Normal file
362
Multiplayer Core/patch_mp/maps/mp/bots/_bot_hq.gsc
Normal file
@ -0,0 +1,362 @@
|
||||
//checked includes changed to match cerberus output
|
||||
#include maps/mp/bots/_bot;
|
||||
#include maps/mp/bots/_bot_combat;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/gametypes/koth;
|
||||
|
||||
bot_hq_think() //checked changed to match cerberus output
|
||||
{
|
||||
time = getTime();
|
||||
if ( time < self.bot.update_objective )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self.bot.update_objective = time + randomintrange( 500, 1500 );
|
||||
if ( bot_should_patrol_hq() )
|
||||
{
|
||||
self bot_patrol_hq();
|
||||
}
|
||||
else if ( !bot_has_hq_goal() )
|
||||
{
|
||||
self bot_move_to_hq();
|
||||
}
|
||||
if ( self bot_is_capturing_hq() )
|
||||
{
|
||||
self bot_capture_hq();
|
||||
}
|
||||
bot_hq_tactical_insertion();
|
||||
bot_hq_grenade();
|
||||
if ( !bot_is_capturing_hq() && !self atgoal( "hq_patrol" ) )
|
||||
{
|
||||
mine = getnearestnode( self.origin );
|
||||
node = hq_nearest_node();
|
||||
if ( isDefined( mine ) && nodesvisible( mine, node ) )
|
||||
{
|
||||
self lookat( level.radio.baseorigin + vectorScale( ( 0, 0, 1 ), 30 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_has_hq_goal() //checked changed to match cerberus output
|
||||
{
|
||||
origin = self getgoal( "hq_radio" );
|
||||
if ( isDefined( origin ) )
|
||||
{
|
||||
foreach ( node in level.radio.nodes )
|
||||
{
|
||||
if ( distancesquared( origin, node.origin ) < 4096 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_is_capturing_hq() //checked matches cerberus output
|
||||
{
|
||||
return self atgoal( "hq_radio" );
|
||||
}
|
||||
|
||||
bot_should_patrol_hq() //checked matches cerberus output
|
||||
{
|
||||
if ( level.radio.gameobject.ownerteam == "neutral" )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( level.radio.gameobject.ownerteam != self.team )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( hq_is_contested() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bot_patrol_hq() //checked changed to match cerberus output
|
||||
{
|
||||
self cancelgoal( "hq_radio" );
|
||||
if ( self atgoal( "hq_patrol" ) )
|
||||
{
|
||||
node = getnearestnode( self.origin );
|
||||
if ( node.type == "Path" )
|
||||
{
|
||||
self setstance( "crouch" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self setstance( "stand" );
|
||||
}
|
||||
if ( getTime() > self.bot.update_lookat )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
z = 20;
|
||||
if ( distancesquared( origin, self.origin ) > 262144 )
|
||||
{
|
||||
z = randomintrange( 16, 60 );
|
||||
}
|
||||
self lookat( origin + ( 0, 0, z ) );
|
||||
if ( distancesquared( origin, self.origin ) > 65536 )
|
||||
{
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = vectorScale( dir, 256 );
|
||||
origin += dir;
|
||||
}
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( origin );
|
||||
self.bot.update_lookat = getTime() + randomintrange( 1500, 3000 );
|
||||
}
|
||||
goal = self getgoal( "hq_patrol" );
|
||||
nearest = hq_nearest_node();
|
||||
mine = getnearestnode( goal );
|
||||
if ( isDefined( mine ) && !nodesvisible( mine, nearest ) )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "hq_patrol" );
|
||||
}
|
||||
if ( getTime() > self.bot.update_objective_patrol )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "hq_patrol" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
nearest = hq_nearest_node();
|
||||
if ( self hasgoal( "hq_patrol" ) )
|
||||
{
|
||||
goal = self getgoal( "hq_patrol" );
|
||||
if ( distancesquared( self.origin, goal ) < 65536 )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
self lookat( origin );
|
||||
}
|
||||
if ( distancesquared( self.origin, goal ) < 16384 )
|
||||
{
|
||||
self.bot.update_objective_patrol = getTime() + randomintrange( 3000, 6000 );
|
||||
}
|
||||
mine = getnearestnode( goal );
|
||||
if ( isDefined( mine ) && !nodesvisible( mine, nearest ) )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "hq_patrol" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
nodes = getvisiblenodes( nearest );
|
||||
/*
|
||||
/#
|
||||
assert( nodes.size );
|
||||
#/
|
||||
*/
|
||||
for ( i = randomint( nodes.size ); i < nodes.size; i++ )
|
||||
{
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "hq_radio", nodes[ i ].origin, 128 ) == 0 )
|
||||
{
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "hq_patrol", nodes[ i ].origin, 256 ) == 0 )
|
||||
{
|
||||
self addgoal( nodes[ i ], 24, 3, "hq_patrol" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_move_to_hq() //checked changed to match cerberus output
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "hq_radio" );
|
||||
self cancelgoal( "hq_patrol" );
|
||||
if ( self getstance() == "prone" )
|
||||
{
|
||||
self setstance( "crouch" );
|
||||
wait 0.25;
|
||||
}
|
||||
if ( self getstance() == "crouch" )
|
||||
{
|
||||
self setstance( "stand" );
|
||||
wait 0.25;
|
||||
}
|
||||
nodes = array_randomize( level.radio.nodes );
|
||||
foreach ( node in nodes )
|
||||
{
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "hq_radio", node.origin, 64 ) == 0 )
|
||||
{
|
||||
self addgoal( node, 24, 3, "hq_radio" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
self addgoal( random( nodes ), 24, 3, "hq_radio" );
|
||||
}
|
||||
|
||||
bot_get_look_at() //checked matches cerberus output
|
||||
{
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( self.origin, 1 );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
}
|
||||
enemies = self maps/mp/bots/_bot::bot_get_enemies( 0 );
|
||||
if ( enemies.size )
|
||||
{
|
||||
enemy = random( enemies );
|
||||
}
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
}
|
||||
spawn = random( level.spawnpoints );
|
||||
node = getvisiblenode( self.origin, spawn.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
return level.radio.baseorigin;
|
||||
}
|
||||
|
||||
bot_capture_hq() //checked matches cerberus output
|
||||
{
|
||||
self addgoal( self.origin, 24, 3, "hq_radio" );
|
||||
self setstance( "crouch" );
|
||||
if ( getTime() > self.bot.update_lookat )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
z = 20;
|
||||
if ( distancesquared( origin, self.origin ) > 262144 )
|
||||
{
|
||||
z = randomintrange( 16, 60 );
|
||||
}
|
||||
self lookat( origin + ( 0, 0, z ) );
|
||||
if ( distancesquared( origin, self.origin ) > 65536 )
|
||||
{
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = vectorScale( dir, 256 );
|
||||
origin += dir;
|
||||
}
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( origin );
|
||||
self.bot.update_lookat = getTime() + randomintrange( 1500, 3000 );
|
||||
}
|
||||
}
|
||||
|
||||
any_other_team_touching( skip_team ) //checked partially changed to match cerberus output did not use continue see github for more info
|
||||
{
|
||||
foreach ( team in level.teams )
|
||||
{
|
||||
if ( team == skip_team )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( level.radio.gameobject.numtouching[ team ] )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
is_hq_contested( skip_team ) //checked matches cerberus output
|
||||
{
|
||||
if ( any_other_team_touching( skip_team ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( level.radio.baseorigin, 1 );
|
||||
if ( isDefined( enemy ) && distancesquared( enemy.origin, level.radio.baseorigin ) < 262144 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_hq_grenade() //checked matches cerberus output
|
||||
{
|
||||
enemies = bot_get_enemies();
|
||||
if ( !enemies.size )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( self atgoal( "hq_patrol" ) || self atgoal( "hq_radio" ) )
|
||||
{
|
||||
if ( self getweaponammostock( "proximity_grenade_mp" ) > 0 )
|
||||
{
|
||||
origin = bot_get_look_at();
|
||||
if ( self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( origin ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !is_hq_contested( self.team ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_smoke( level.radio.baseorigin );
|
||||
return;
|
||||
}
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( level.radio.baseorigin, 0 );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
origin = enemy.origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
origin = level.radio.baseorigin;
|
||||
}
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = ( 0, dir[ 1 ], 0 );
|
||||
origin += vectorScale( dir, 128 );
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_lethal( origin ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_tactical( origin );
|
||||
}
|
||||
}
|
||||
|
||||
bot_hq_tactical_insertion() //checked matches cerberus output
|
||||
{
|
||||
if ( !self hasweapon( "tactical_insertion_mp" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
dist = self getlookaheaddist();
|
||||
dir = self getlookaheaddir();
|
||||
if ( !isDefined( dist ) || !isDefined( dir ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
node = hq_nearest_node();
|
||||
mine = getnearestnode( self.origin );
|
||||
if ( isDefined( mine ) && !nodesvisible( mine, node ) )
|
||||
{
|
||||
origin = self.origin + vectorScale( dir, dist );
|
||||
next = getnearestnode( origin );
|
||||
if ( isDefined( next ) && nodesvisible( next, node ) )
|
||||
{
|
||||
bot_combat_tactical_insertion( self.origin );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hq_nearest_node() //checked matches cerberus output
|
||||
{
|
||||
return random( level.radio.nodes );
|
||||
}
|
||||
|
||||
hq_is_contested() //checked changed at own discretion
|
||||
{
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( level.radio.baseorigin, 0 );
|
||||
if ( isDefined( enemy ) && distancesquared( enemy.origin, level.radio.baseorigin ) < ( level.radio.node_radius * level.radio.node_radius ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
298
Multiplayer Core/patch_mp/maps/mp/bots/_bot_koth.gsc
Normal file
298
Multiplayer Core/patch_mp/maps/mp/bots/_bot_koth.gsc
Normal file
@ -0,0 +1,298 @@
|
||||
#include maps/mp/bots/_bot_combat;
|
||||
#include maps/mp/bots/_bot;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
#include maps/mp/gametypes/koth;
|
||||
|
||||
bot_koth_think() //checked matches cerberus output
|
||||
{
|
||||
if ( !isDefined( level.zone.trig.goal_radius ) )
|
||||
{
|
||||
maxs = level.zone.trig getmaxs();
|
||||
maxs = level.zone.trig.origin + maxs;
|
||||
level.zone.trig.goal_radius = distance( level.zone.trig.origin, maxs );
|
||||
/*
|
||||
/#
|
||||
println( "distance: " + level.zone.trig.goal_radius );
|
||||
#/
|
||||
*/
|
||||
ground = bullettrace( level.zone.gameobject.curorigin, level.zone.gameobject.curorigin - vectorScale( ( 0, 0, 1 ), 1024 ), 0, undefined );
|
||||
level.zone.trig.goal = ground[ "position" ] + vectorScale( ( 0, 0, 1 ), 8 );
|
||||
}
|
||||
if ( !bot_has_hill_goal() )
|
||||
{
|
||||
self bot_move_to_hill();
|
||||
}
|
||||
if ( self bot_is_at_hill() )
|
||||
{
|
||||
self bot_capture_hill();
|
||||
}
|
||||
bot_hill_tactical_insertion();
|
||||
bot_hill_grenade();
|
||||
}
|
||||
|
||||
bot_has_hill_goal() //checked matches cerberus output
|
||||
{
|
||||
origin = self getgoal( "koth_hill" );
|
||||
if ( isDefined( origin ) )
|
||||
{
|
||||
if ( distance2dsquared( level.zone.gameobject.curorigin, origin ) < level.zone.trig.goal_radius * level.zone.trig.goal_radius )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_is_at_hill() //checked matches cerberus output
|
||||
{
|
||||
return self atgoal( "koth_hill" );
|
||||
}
|
||||
|
||||
bot_move_to_hill() //checked changed to match cerberus output
|
||||
{
|
||||
if ( getTime() < ( self.bot.update_objective + 4000 ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self clearlookat();
|
||||
self cancelgoal( "koth_hill" );
|
||||
if ( self getstance() == "prone" )
|
||||
{
|
||||
self setstance( "crouch" );
|
||||
wait 0.25;
|
||||
}
|
||||
if ( self getstance() == "crouch" )
|
||||
{
|
||||
self setstance( "stand" );
|
||||
wait 0.25;
|
||||
}
|
||||
nodes = getnodesinradiussorted( level.zone.trig.goal, level.zone.trig.goal_radius, 0, 128 );
|
||||
foreach ( node in nodes )
|
||||
{
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "koth_hill", node.origin, 64 ) == 0 )
|
||||
{
|
||||
if ( findpath( self.origin, node.origin, self, 0, 1 ) )
|
||||
{
|
||||
self addgoal( node, 24, 3, "koth_hill" );
|
||||
self.bot.update_objective = getTime();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_get_look_at() //checked matches cerberus output
|
||||
{
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( self.origin, 1 );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 1024 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
}
|
||||
enemies = self maps/mp/bots/_bot::bot_get_enemies( 0 );
|
||||
if ( enemies.size )
|
||||
{
|
||||
enemy = random( enemies );
|
||||
}
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 1024 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
}
|
||||
spawn = random( level.spawnpoints );
|
||||
node = getvisiblenode( self.origin, spawn.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 1024 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
return level.zone.gameobject.curorigin;
|
||||
}
|
||||
|
||||
bot_capture_hill() //checked changed to match cerberus output
|
||||
{
|
||||
self addgoal( self.origin, 24, 3, "koth_hill" );
|
||||
self setstance( "crouch" );
|
||||
if ( getTime() > self.bot.update_lookat )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
z = 20;
|
||||
if ( distancesquared( origin, self.origin ) > 262144 )
|
||||
{
|
||||
z = randomintrange( 16, 60 );
|
||||
}
|
||||
self lookat( origin + ( 0, 0, z ) );
|
||||
if ( distancesquared( origin, self.origin ) > 65536 )
|
||||
{
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = vectorScale( dir, 256 );
|
||||
origin += dir;
|
||||
}
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( origin );
|
||||
if ( cointoss() && lengthsquared( self getvelocity() ) < 2 )
|
||||
{
|
||||
nodes = getnodesinradius( level.zone.trig.goal, level.zone.trig.goal_radius + 128, 0, 128 );
|
||||
for ( i = randomintrange( 0, nodes.size ); i < nodes.size; i++ )
|
||||
{
|
||||
node = nodes[ i ];
|
||||
if ( distancesquared( node.origin, self.origin ) > 1024 )
|
||||
{
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "koth_hill", node.origin, 128 ) == 0 )
|
||||
{
|
||||
if ( findpath( self.origin, node.origin, self, 0, 1 ) )
|
||||
{
|
||||
self addgoal( node, 24, 3, "koth_hill" );
|
||||
self.bot.update_objective = getTime();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.bot.update_lookat = getTime() + randomintrange( 1500, 3000 );
|
||||
}
|
||||
}
|
||||
|
||||
any_other_team_touching( skip_team ) //checked partially changed to match cerberus output did not use foreach see github for more info
|
||||
{
|
||||
teams = getArrayKeys( level.teams );
|
||||
while ( i < teams.size )
|
||||
{
|
||||
if ( teams[ i ] == skip_team )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ( level.zone.gameobject.numtouching[ teams[ i ] ] )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
is_hill_contested( skip_team ) //checked matches cerberus output
|
||||
{
|
||||
if ( any_other_team_touching( skip_team ) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( level.zone.gameobject.curorigin, 1 );
|
||||
if ( isDefined( enemy ) && distancesquared( enemy.origin, level.zone.gameobject.curorigin ) < 262144 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_hill_grenade() //checked changed to match cerberus output
|
||||
{
|
||||
enemies = bot_get_enemies();
|
||||
if ( !enemies.size )
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ( self atgoal( "hill_patrol" ) || self atgoal( "koth_hill" ) )
|
||||
{
|
||||
if ( self getweaponammostock( "proximity_grenade_mp" ) > 0 )
|
||||
{
|
||||
origin = bot_get_look_at();
|
||||
if ( self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( origin ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !is_hill_contested( self.team ) )
|
||||
{
|
||||
if ( !isDefined( level.next_smoke_time ) )
|
||||
{
|
||||
level.next_smoke_time = 0;
|
||||
}
|
||||
if ( getTime() > level.next_smoke_time )
|
||||
{
|
||||
if ( self maps/mp/bots/_bot_combat::bot_combat_throw_smoke( level.zone.gameobject.curorigin ) )
|
||||
{
|
||||
level.next_smoke_time = getTime() + randomintrange( 60000, 120000 );
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( level.zone.gameobject.curorigin, 0 );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
origin = enemy.origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
origin = level.zone.gameobject.curorigin;
|
||||
}
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = ( 0, dir[ 1 ], 0 );
|
||||
origin += vectorScale( dir, 128 );
|
||||
if ( maps/mp/bots/_bot::bot_get_difficulty() == "easy" )
|
||||
{
|
||||
if ( !isDefined( level.next_grenade_time ) )
|
||||
{
|
||||
level.next_grenade_time = 0;
|
||||
}
|
||||
if ( getTime() > level.next_grenade_time )
|
||||
{
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_lethal( origin ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_tactical( origin );
|
||||
}
|
||||
else
|
||||
{
|
||||
level.next_grenade_time = getTime() + randomintrange( 60000, 120000 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_lethal( origin ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_tactical( origin );
|
||||
}
|
||||
}
|
||||
|
||||
bot_hill_tactical_insertion() //checked matches cerberus output
|
||||
{
|
||||
if ( !self hasweapon( "tactical_insertion_mp" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
dist = self getlookaheaddist();
|
||||
dir = self getlookaheaddir();
|
||||
if ( !isDefined( dist ) || !isDefined( dir ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
node = hill_nearest_node();
|
||||
mine = getnearestnode( self.origin );
|
||||
if ( isDefined( mine ) && !nodesvisible( mine, node ) )
|
||||
{
|
||||
origin = self.origin + vectorScale( dir, dist );
|
||||
next = getnearestnode( origin );
|
||||
if ( isDefined( next ) && nodesvisible( next, node ) )
|
||||
{
|
||||
bot_combat_tactical_insertion( self.origin );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hill_nearest_node() //checked matches cerberus output
|
||||
{
|
||||
nodes = getnodesinradiussorted( level.zone.gameobject.curorigin, 256, 0 );
|
||||
/*
|
||||
/#
|
||||
assert( nodes.size );
|
||||
#/
|
||||
*/
|
||||
return nodes[ 0 ];
|
||||
}
|
||||
|
||||
|
546
Multiplayer Core/patch_mp/maps/mp/bots/_bot_loadout.gsc
Normal file
546
Multiplayer Core/patch_mp/maps/mp/bots/_bot_loadout.gsc
Normal file
@ -0,0 +1,546 @@
|
||||
#include maps/mp/gametypes/_rank;
|
||||
#include maps/mp/bots/_bot;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
|
||||
init() //checked changed to match cerberus output
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
level.bot_banned_killstreaks = array( "KILLSTREAK_RCBOMB", "KILLSTREAK_QRDRONE", "KILLSTREAK_REMOTE_MISSILE", "KILLSTREAK_REMOTE_MORTAR", "KILLSTREAK_HELICOPTER_GUNNER" );
|
||||
for ( ;; )
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
if ( !player istestclient() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
player thread on_bot_connect();
|
||||
}
|
||||
}
|
||||
|
||||
on_bot_connect() //checked changed to match cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
if ( isDefined( self.pers[ "bot_loadout" ] ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
wait 0.1;
|
||||
if ( ( self getentitynumber() % 2 ) == 0 )
|
||||
{
|
||||
wait 0.05;
|
||||
}
|
||||
self maps/mp/bots/_bot::bot_set_rank();
|
||||
if ( level.onlinegame && !sessionmodeisprivate() )
|
||||
{
|
||||
self botsetdefaultclass( 5, "class_assault" );
|
||||
self botsetdefaultclass( 6, "class_smg" );
|
||||
self botsetdefaultclass( 7, "class_lmg" );
|
||||
self botsetdefaultclass( 8, "class_cqb" );
|
||||
self botsetdefaultclass( 9, "class_sniper" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self botsetdefaultclass( 5, "class_assault" );
|
||||
self botsetdefaultclass( 6, "class_smg" );
|
||||
self botsetdefaultclass( 7, "class_lmg" );
|
||||
self botsetdefaultclass( 8, "class_cqb" );
|
||||
self botsetdefaultclass( 9, "class_sniper" );
|
||||
}
|
||||
max_allocation = 10;
|
||||
for ( i = 1; i <= 3; i++ )
|
||||
{
|
||||
if ( self isitemlocked( maps/mp/gametypes/_rank::getitemindex( "feature_allocation_slot_" + i ) ) )
|
||||
{
|
||||
max_allocation--;
|
||||
}
|
||||
}
|
||||
self bot_construct_loadout( max_allocation );
|
||||
self.pers[ "bot_loadout" ] = 1;
|
||||
}
|
||||
|
||||
bot_construct_loadout( allocation_max ) //checked matches cerberus output
|
||||
{
|
||||
if ( self isitemlocked( maps/mp/gametypes/_rank::getitemindex( "feature_cac" ) ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
pixbeginevent( "bot_construct_loadout" );
|
||||
item_list = bot_build_item_list();
|
||||
bot_construct_class( 0, item_list, allocation_max );
|
||||
bot_construct_class( 1, item_list, allocation_max );
|
||||
bot_construct_class( 2, item_list, allocation_max );
|
||||
bot_construct_class( 3, item_list, allocation_max );
|
||||
bot_construct_class( 4, item_list, allocation_max );
|
||||
killstreaks = item_list[ "killstreak1" ];
|
||||
if ( isDefined( item_list[ "killstreak2" ] ) )
|
||||
{
|
||||
killstreaks = arraycombine( killstreaks, item_list[ "killstreak2" ], 1, 0 );
|
||||
}
|
||||
if ( isDefined( item_list[ "killstreak3" ] ) )
|
||||
{
|
||||
killstreaks = arraycombine( killstreaks, item_list[ "killstreak3" ], 1, 0 );
|
||||
}
|
||||
if ( isDefined( killstreaks ) && killstreaks.size )
|
||||
{
|
||||
bot_choose_weapon( 0, killstreaks );
|
||||
bot_choose_weapon( 0, killstreaks );
|
||||
bot_choose_weapon( 0, killstreaks );
|
||||
}
|
||||
self.claimed_items = undefined;
|
||||
pixendevent();
|
||||
}
|
||||
|
||||
bot_construct_class( class, items, allocation_max ) //checked partially changed to match cerberus output did not change while loop to for loop see github for more info
|
||||
{
|
||||
allocation = 0;
|
||||
claimed_count = bot_build_claimed_list( items );
|
||||
self.claimed_items = [];
|
||||
while ( allocation < allocation_max )
|
||||
{
|
||||
secondary_chance = 40;
|
||||
remaining = allocation_max - allocation;
|
||||
if ( remaining >= 1 && bot_make_choice( 95, claimed_count[ "primary" ], 1 ) )
|
||||
{
|
||||
weapon = bot_choose_weapon( class, items[ "primary" ] );
|
||||
claimed_count[ "primary" ]++;
|
||||
allocation++;
|
||||
bot_choose_weapon_option( class, "camo", 0 );
|
||||
bot_choose_weapon_option( class, "reticle", 0 );
|
||||
allocation += bot_choose_primary_attachments( class, weapon, allocation, allocation_max );
|
||||
}
|
||||
else if ( !claimed_count[ "primary" ] )
|
||||
{
|
||||
secondary_chance = 100;
|
||||
}
|
||||
remaining = allocation_max - allocation;
|
||||
if ( remaining >= 1 && bot_make_choice( secondary_chance, claimed_count[ "secondary" ], 1 ) )
|
||||
{
|
||||
if ( remaining >= 2 && randomint( 100 ) < 10 )
|
||||
{
|
||||
self botclassadditem( class, "BONUSCARD_OVERKILL" );
|
||||
weapon = bot_choose_weapon( class, items[ "primary" ] );
|
||||
allocation++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
weapon = bot_choose_weapon( class, items[ "secondary" ] );
|
||||
bot_choose_weapon_option( class, "camo", 1 );
|
||||
}
|
||||
allocation++;
|
||||
claimed_count[ "secondary" ]++;
|
||||
allocation += bot_choose_secondary_attachments( class, weapon, allocation, allocation_max );
|
||||
}
|
||||
perks_chance = 50;
|
||||
lethal_chance = 30;
|
||||
tactical_chance = 20;
|
||||
if ( claimed_count[ "specialty1" ] && claimed_count[ "specialty2" ] && claimed_count[ "specialty3" ] )
|
||||
{
|
||||
perks_chance = 0;
|
||||
}
|
||||
if ( claimed_count[ "primarygrenade" ] )
|
||||
{
|
||||
lethal_chance = 0;
|
||||
}
|
||||
if ( claimed_count[ "specialgrenade" ] )
|
||||
{
|
||||
tactical_chance = 0;
|
||||
}
|
||||
if ( ( perks_chance + lethal_chance + tactical_chance ) <= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
next_action = bot_chose_action( "perks", perks_chance, "lethal", lethal_chance, "tactical", tactical_chance, "none", 0 );
|
||||
if ( next_action == "perks" )
|
||||
{
|
||||
remaining = allocation_max - allocation;
|
||||
if ( remaining >= 3 && !claimed_count[ "specialty1" ] && randomint( 100 ) < 25 )
|
||||
{
|
||||
self botclassadditem( class, "BONUSCARD_PERK_1_GREED" );
|
||||
bot_choose_weapon( class, items[ "specialty1" ] );
|
||||
bot_choose_weapon( class, items[ "specialty1" ] );
|
||||
claimed_count[ "specialty1" ] = 2;
|
||||
allocation += 3;
|
||||
}
|
||||
remaining = allocation_max - allocation;
|
||||
if ( remaining >= 3 && !claimed_count[ "specialty2" ] && randomint( 100 ) < 25 )
|
||||
{
|
||||
self botclassadditem( class, "BONUSCARD_PERK_2_GREED" );
|
||||
bot_choose_weapon( class, items[ "specialty2" ] );
|
||||
bot_choose_weapon( class, items[ "specialty2" ] );
|
||||
claimed_count[ "specialty2" ] = 2;
|
||||
allocation += 3;
|
||||
}
|
||||
remaining = allocation_max - allocation;
|
||||
if ( remaining >= 3 && !claimed_count[ "specialty3" ] && randomint( 100 ) < 25 )
|
||||
{
|
||||
self botclassadditem( class, "BONUSCARD_PERK_3_GREED" );
|
||||
bot_choose_weapon( class, items[ "specialty3" ] );
|
||||
bot_choose_weapon( class, items[ "specialty3" ] );
|
||||
claimed_count[ "specialty3" ] = 2;
|
||||
allocation += 3;
|
||||
}
|
||||
remaining = allocation_max - allocation;
|
||||
i = 0;
|
||||
while ( i < 3 )
|
||||
{
|
||||
perks = [];
|
||||
remaining = allocation_max - allocation;
|
||||
if ( remaining > 0 )
|
||||
{
|
||||
if ( !claimed_count[ "specialty1" ] )
|
||||
{
|
||||
perks[ perks.size ] = "specialty1";
|
||||
}
|
||||
if ( !claimed_count[ "specialty2" ] )
|
||||
{
|
||||
perks[ perks.size ] = "specialty2";
|
||||
}
|
||||
if ( !claimed_count[ "specialty3" ] )
|
||||
{
|
||||
perks[ perks.size ] = "specialty3";
|
||||
}
|
||||
if ( perks.size )
|
||||
{
|
||||
perk = random( perks );
|
||||
bot_choose_weapon( class, items[ perk ] );
|
||||
claimed_count[ perk ]++;
|
||||
allocation++;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if ( next_action == "lethal" )
|
||||
{
|
||||
remaining = allocation_max - allocation;
|
||||
if ( remaining >= 2 && randomint( 100 ) < 50 )
|
||||
{
|
||||
if ( !claimed_count[ "primarygrenade" ] )
|
||||
{
|
||||
bot_choose_weapon( class, items[ "primarygrenade" ] );
|
||||
claimed_count[ "primarygrenade" ]++;
|
||||
allocation++;
|
||||
}
|
||||
self botclassadditem( class, "BONUSCARD_DANGER_CLOSE" );
|
||||
allocation++;
|
||||
}
|
||||
else if ( remaining >= 1 && !claimed_count[ "primarygrenade" ] )
|
||||
{
|
||||
bot_choose_weapon( class, items[ "primarygrenade" ] );
|
||||
claimed_count[ "primarygrenade" ]++;
|
||||
allocation++;
|
||||
}
|
||||
}
|
||||
else if ( next_action == "tactical" )
|
||||
{
|
||||
remaining = allocation_max - allocation;
|
||||
if ( remaining >= 2 && !claimed_count[ "specialgrenade" ] && randomint( 100 ) < 50 )
|
||||
{
|
||||
weapon = bot_choose_weapon( class, items[ "specialgrenade" ] );
|
||||
if ( weapon == "WEAPON_TACTICAL_INSERTION" || weapon == "WEAPON_WILLY_PETE" )
|
||||
{
|
||||
claimed_count[ "specialgrenade" ] = 1;
|
||||
allocation += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
self botclassadditem( class, weapon );
|
||||
claimed_count[ "specialgrenade" ] = 2;
|
||||
allocation += 2;
|
||||
}
|
||||
}
|
||||
else if ( remaining >= 1 && !claimed_count[ "specialgrenade" ] )
|
||||
{
|
||||
bot_choose_weapon( class, items[ "specialgrenade" ] );
|
||||
claimed_count[ "specialgrenade" ]++;
|
||||
allocation++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_make_choice( chance, claimed, max_claim ) //checked changed at own discretion
|
||||
{
|
||||
if ( claimed < max_claim && randomint( 100 ) < chance )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_chose_action( action1, chance1, action2, chance2, action3, chance3, action4, chance4 ) //checked changed to match cerberus output
|
||||
{
|
||||
chance1 = int( chance1 / 10 );
|
||||
chance2 = int( chance2 / 10 );
|
||||
chance3 = int( chance3 / 10 );
|
||||
chance4 = int( chance4 / 10 );
|
||||
actions = [];
|
||||
for ( i = 0; i < chance1; i++ )
|
||||
{
|
||||
actions[ actions.size ] = action1;
|
||||
}
|
||||
for ( i = 0; i < chance2; i++ )
|
||||
{
|
||||
actions[ actions.size ] = action2;
|
||||
}
|
||||
for ( i = 0; i < chance3; i++ )
|
||||
{
|
||||
actions[ actions.size ] = action3;
|
||||
}
|
||||
for ( i = 0; i < chance4; i++ )
|
||||
{
|
||||
actions[ actions.size ] = action4;
|
||||
}
|
||||
return random( actions );
|
||||
}
|
||||
|
||||
bot_item_is_claimed( item ) //checked changed to match cerberus output
|
||||
{
|
||||
foreach ( claim in self.claimed_items )
|
||||
{
|
||||
if ( claim == item )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_choose_weapon( class, items ) //checked changed to match cerberus output
|
||||
{
|
||||
if ( !isDefined( items ) || !items.size )
|
||||
{
|
||||
return undefined;
|
||||
}
|
||||
start = randomint( items.size );
|
||||
for ( i = 0; i < items.size; i++ )
|
||||
{
|
||||
weapon = items[ start ];
|
||||
if ( !bot_item_is_claimed( weapon ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
start = ( start + 1 ) % items.size;
|
||||
}
|
||||
self.claimed_items[ self.claimed_items.size ] = weapon;
|
||||
self botclassadditem( class, weapon );
|
||||
return weapon;
|
||||
}
|
||||
|
||||
bot_build_weapon_options_list( optiontype ) //checked changed to match cerberus output
|
||||
{
|
||||
level.botweaponoptionsid[ optiontype ] = [];
|
||||
level.botweaponoptionsprob[ optiontype ] = [];
|
||||
prob = 0;
|
||||
for ( row = 0; row < 255; row++ )
|
||||
{
|
||||
if ( tablelookupcolumnforrow( "mp/attachmentTable.csv", row, 1 ) == optiontype )
|
||||
{
|
||||
index = level.botweaponoptionsid[ optiontype ].size;
|
||||
level.botweaponoptionsid[ optiontype ][ index ] = int( tablelookupcolumnforrow( "mp/attachmentTable.csv", row, 0 ) );
|
||||
prob += int( tablelookupcolumnforrow( "mp/attachmentTable.csv", row, 15 ) );
|
||||
level.botweaponoptionsprob[ optiontype ][ index ] = prob;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_choose_weapon_option( class, optiontype, primary ) //checked changed to match cerberus output may need to review order of operations
|
||||
{
|
||||
if ( !isDefined( level.botweaponoptionsid ) )
|
||||
{
|
||||
level.botweaponoptionsid = [];
|
||||
level.botweaponoptionsprob = [];
|
||||
bot_build_weapon_options_list( "camo" );
|
||||
bot_build_weapon_options_list( "reticle" );
|
||||
}
|
||||
if ( !level.onlinegame && !level.systemlink )
|
||||
{
|
||||
return;
|
||||
}
|
||||
numoptions = level.botweaponoptionsprob[ optiontype ].size;
|
||||
maxprob = level.botweaponoptionsprob[ optiontype ][ numoptions - 1 ];
|
||||
if ( !level.systemlink && self.pers[ "rank" ] < 20 )
|
||||
{
|
||||
maxprob += ( 4 * maxprob ) * ( ( 20 - self.pers[ "rank" ] ) / 20 );
|
||||
}
|
||||
rnd = randomint( int( maxprob ) );
|
||||
for ( i = 0; i < numoptions; i++ )
|
||||
{
|
||||
if ( level.botweaponoptionsprob[ optiontype ][ i ] > rnd )
|
||||
{
|
||||
self botclasssetweaponoption( class, primary, optiontype, level.botweaponoptionsid[ optiontype ][ i ] );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_choose_primary_attachments( class, weapon, allocation, allocation_max ) //checked changed to match cerberus output
|
||||
{
|
||||
attachments = getweaponattachments( weapon );
|
||||
remaining = allocation_max - allocation;
|
||||
if ( !attachments.size || !remaining )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
attachment_action = bot_chose_action( "3_attachments", 25, "2_attachments", 35, "1_attachments", 35, "none", 5 );
|
||||
if ( remaining >= 4 && attachment_action == "3_attachments" )
|
||||
{
|
||||
a1 = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a1, "primaryattachment1" );
|
||||
count = 1;
|
||||
attachments = getweaponattachments( weapon, a1 );
|
||||
if ( attachments.size )
|
||||
{
|
||||
a2 = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a2, "primaryattachment2" );
|
||||
count++;
|
||||
attachments = getweaponattachments( weapon, a1, a2 );
|
||||
if ( attachments.size )
|
||||
{
|
||||
a3 = random( attachments );
|
||||
self botclassadditem( class, "BONUSCARD_PRIMARY_GUNFIGHTER" );
|
||||
self botclassaddattachment( class, weapon, a3, "primaryattachment3" );
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
else if ( remaining >= 2 && attachment_action == "2_attachments" )
|
||||
{
|
||||
a1 = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a1, "primaryattachment1" );
|
||||
attachments = getweaponattachments( weapon, a1 );
|
||||
if ( attachments.size )
|
||||
{
|
||||
a2 = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a2, "primaryattachment2" );
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else if ( remaining >= 1 && attachment_action == "1_attachments" )
|
||||
{
|
||||
a = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a, "primaryattachment1" );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_choose_secondary_attachments( class, weapon, allocation, allocation_max ) //checked changed to match cerberus output
|
||||
{
|
||||
attachments = getweaponattachments( weapon );
|
||||
remaining = allocation_max - allocation;
|
||||
if ( !attachments.size || !remaining )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
attachment_action = bot_chose_action( "2_attachments", 10, "1_attachments", 40, "none", 50, "none", 0 );
|
||||
if ( remaining >= 3 && attachment_action == "2_attachments" )
|
||||
{
|
||||
a1 = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a1, "secondaryattachment1" );
|
||||
attachments = getweaponattachments( weapon, a1 );
|
||||
if ( attachments.size )
|
||||
{
|
||||
a2 = random( attachments );
|
||||
self botclassadditem( class, "BONUSCARD_SECONDARY_GUNFIGHTER" );
|
||||
self botclassaddattachment( class, weapon, a2, "secondaryattachment2" );
|
||||
return 3;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else if ( remaining >= 1 && attachment_action == "1_attachments" )
|
||||
{
|
||||
a = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a, "secondaryattachment1" );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_build_item_list() //checked partially changed to match cerberus output did not change while loop to for loop see github for more info
|
||||
{
|
||||
pixbeginevent( "bot_build_item_list" );
|
||||
items = [];
|
||||
i = 0;
|
||||
while ( i < 256 )
|
||||
{
|
||||
row = tablelookuprownum( level.statstableid, 0, i );
|
||||
if ( row > -1 )
|
||||
{
|
||||
slot = tablelookupcolumnforrow( level.statstableid, row, 13 );
|
||||
if ( slot == "" )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
number = int( tablelookupcolumnforrow( level.statstableid, row, 0 ) );
|
||||
if ( self isitemlocked( number ) )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
allocation = int( tablelookupcolumnforrow( level.statstableid, row, 12 ) );
|
||||
if ( allocation < 0 )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
name = tablelookupcolumnforrow( level.statstableid, row, 3 );
|
||||
if ( bot_item_is_banned( slot, name ) )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if ( !isDefined( items[ slot ] ) )
|
||||
{
|
||||
items[ slot ] = [];
|
||||
}
|
||||
items[ slot ][ items[ slot ].size ] = name;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
pixendevent();
|
||||
return items;
|
||||
}
|
||||
|
||||
bot_item_is_banned( slot, item ) //checked changed to match cerberus output
|
||||
{
|
||||
if ( item == "WEAPON_KNIFE_BALLISTIC" )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if ( /* getDvarInt( #"97A055DA" ) == 0 && */ item == "WEAPON_PEACEKEEPER" )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if ( slot != "killstreak1" && slot != "killstreak2" && slot != "killstreak3" )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
foreach ( banned in level.bot_banned_killstreaks )
|
||||
{
|
||||
if ( item == banned )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_build_claimed_list( items ) //checked changed to match cerberus output
|
||||
{
|
||||
claimed = [];
|
||||
keys = getarraykeys( items );
|
||||
foreach ( key in keys )
|
||||
{
|
||||
claimed[ key ] = 0;
|
||||
}
|
||||
return claimed;
|
||||
}
|
||||
|
442
Multiplayer Core/patch_mp/maps/mp/bots/_bot_sd.gsc
Normal file
442
Multiplayer Core/patch_mp/maps/mp/bots/_bot_sd.gsc
Normal file
@ -0,0 +1,442 @@
|
||||
//changed includes to match cerberus output
|
||||
#include maps/mp/gametypes/_globallogic_utils;
|
||||
#include maps/mp/bots/_bot_combat;
|
||||
#include maps/mp/bots/_bot;
|
||||
#include maps/mp/gametypes/_gameobjects;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
|
||||
bot_sd_think() //checked changed to match cerberus output
|
||||
{
|
||||
foreach ( zone in level.bombzones )
|
||||
{
|
||||
if ( !isDefined( zone.nearest_node ) )
|
||||
{
|
||||
nodes = getnodesinradiussorted( zone.trigger.origin, 256, 0 );
|
||||
/*
|
||||
/#
|
||||
assert( nodes.size );
|
||||
#/
|
||||
*/
|
||||
zone.nearest_node = nodes[ 0 ];
|
||||
}
|
||||
}
|
||||
zone = sd_get_planted_zone();
|
||||
if ( isDefined( zone ) )
|
||||
{
|
||||
self bot_sd_defender( zone, 1 );
|
||||
}
|
||||
else if ( self.team == game[ "attackers" ] )
|
||||
{
|
||||
if ( level.multibomb )
|
||||
{
|
||||
self.isbombcarrier = 1;
|
||||
}
|
||||
self bot_sd_attacker();
|
||||
}
|
||||
else
|
||||
{
|
||||
zone = random( level.bombzones );
|
||||
self bot_sd_defender( zone );
|
||||
}
|
||||
}
|
||||
|
||||
bot_sd_attacker() //checked changed to match cerberus output
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
if ( !level.multibomb && !isDefined( level.sdbomb.carrier ) && !level.bombplanted )
|
||||
{
|
||||
self cancelgoal( "sd_protect_carrier" );
|
||||
if ( !level.sdbomb maps/mp/gametypes/_gameobjects::isobjectawayfromhome() )
|
||||
{
|
||||
if ( !self maps/mp/bots/_bot::bot_friend_goal_in_radius( "sd_pickup", level.sdbomb.curorigin, 64 ) )
|
||||
{
|
||||
self addgoal( level.sdbomb.curorigin, 16, 4, "sd_pickup" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self addgoal( level.sdbomb.curorigin, 16, 4, "sd_pickup" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self cancelgoal( "sd_pickup" );
|
||||
}
|
||||
if ( is_true( self.isbombcarrier ) )
|
||||
{
|
||||
goal = self getgoal( "sd_plant" );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
if ( distancesquared( self.origin, goal ) < 2304 )
|
||||
{
|
||||
self setstance( "prone" );
|
||||
wait 0.5;
|
||||
self pressusebutton( level.planttime + 1 );
|
||||
wait 0.5;
|
||||
if ( is_true( self.isplanting ) )
|
||||
{
|
||||
wait ( level.planttime + 1 );
|
||||
}
|
||||
self pressusebutton( 0 );
|
||||
self setstance( "crouch" );
|
||||
wait 0.25;
|
||||
self cancelgoal( "sd_plant" );
|
||||
self setstance( "stand" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if ( getTime() > self.bot[ "patrol_update" ] )
|
||||
{
|
||||
frac = sd_get_time_frac();
|
||||
if ( randomint( 100 ) < ( frac * 100 ) || frac > 0.85 )
|
||||
{
|
||||
zone = sd_get_closest_bomb();
|
||||
goal = sd_get_bomb_goal( zone.visuals[ 0 ] );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
if ( frac > 0.85 )
|
||||
{
|
||||
self addgoal( goal, 24, 4, "sd_plant" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self addgoal( goal, 24, 3, "sd_plant" );
|
||||
}
|
||||
}
|
||||
}
|
||||
self.bot[ "patrol_update" ] = getTime() + randomintrange( 2500, 5000 );
|
||||
}
|
||||
}
|
||||
else if ( isDefined( level.sdbomb.carrier ) && !isplayer( level.sdbomb.carrier ) )
|
||||
{
|
||||
if ( !isDefined( self.protectcarrier ) )
|
||||
{
|
||||
if ( randomint( 100 ) > 70 )
|
||||
{
|
||||
self.protectcarrier = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.protectcarrier = 0;
|
||||
}
|
||||
}
|
||||
if ( self.protectcarrier )
|
||||
{
|
||||
goal = level.sdbomb.carrier getgoal( "sd_plant" );
|
||||
if ( isDefined( goal ) )
|
||||
{
|
||||
nodes = getnodesinradiussorted( goal, 256, 0 );
|
||||
if ( isDefined( nodes ) && nodes.size > 0 && !isDefined( self getgoal( "sd_protect_carrier" ) ) )
|
||||
{
|
||||
self addgoal( nodes[ randomint( nodes.size ) ], 24, 3, "sd_protect_carrier" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_sd_defender( zone, isplanted ) //checked partially changed to match cerberus output did not use foreach see github for more info
|
||||
{
|
||||
bot_sd_grenade();
|
||||
if ( isDefined( isplanted ) && isplanted && self hasgoal( "sd_defend" ) )
|
||||
{
|
||||
goal = self getgoal( "sd_defend" );
|
||||
planted = sd_get_planted_zone();
|
||||
foreach ( zone in level.bombzones )
|
||||
{
|
||||
if ( planted != zone && distance2d( goal, zone.nearest_node.origin ) < distance2d( goal, planted.nearest_node.origin ) )
|
||||
{
|
||||
self cancelgoal( "sd_defend" );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( self atgoal( "sd_defend" ) || self bot_need_to_defuse() )
|
||||
{
|
||||
bot_sd_defender_think( zone );
|
||||
if ( self hasgoal( "sd_defend" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ( self hasgoal( "enemy_patrol" ) )
|
||||
{
|
||||
goal = self getgoal( "enemy_patrol" );
|
||||
closezone = sd_get_closest_bomb();
|
||||
if ( distancesquared( goal, closezone.nearest_node.origin ) < 262144 )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "sd_defend" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ( self hasgoal( "sd_defend" ) )
|
||||
{
|
||||
self.bot[ "patrol_update" ] = getTime() + randomintrange( 2500, 5000 );
|
||||
return;
|
||||
}
|
||||
if ( self hasgoal( "enemy_patrol" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
nodes = getvisiblenodes( zone.nearest_node );
|
||||
best = undefined;
|
||||
highest = -100;
|
||||
i = 0;
|
||||
while ( i < nodes.size )
|
||||
{
|
||||
if ( node[ i ].type == "BAD NODE" )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if ( !canclaimnode( node[ i ], self.team ) )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if ( distancesquared( node[ i ].origin, self.origin ) < 65536 )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "sd_defend", node[ i ].origin, 256 ) > 0 )
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
height = node[ i ].origin[ 2 ] - zone.nearest_node.origin[ 2 ];
|
||||
if ( is_true( isplanted ) )
|
||||
{
|
||||
dist = distance2d( node[ i ].origin, zone.nearest_node.origin );
|
||||
score = ( 10000 - dist ) + height;
|
||||
}
|
||||
else
|
||||
{
|
||||
score = height;
|
||||
}
|
||||
if ( score > highest )
|
||||
{
|
||||
highest = score;
|
||||
best = node;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if ( !isDefined( best ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self addgoal( best, 24, 3, "sd_defend" );
|
||||
}
|
||||
|
||||
bot_get_look_at() //checked matches cebrerus output
|
||||
{
|
||||
enemy = self maps/mp/bots/_bot::bot_get_closest_enemy( self.origin, 1 );
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
}
|
||||
enemies = self maps/mp/bots/_bot::bot_get_enemies( 0 );
|
||||
if ( enemies.size )
|
||||
{
|
||||
enemy = random( enemies );
|
||||
}
|
||||
if ( isDefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
}
|
||||
zone = sd_get_closest_bomb();
|
||||
node = getvisiblenode( self.origin, zone.nearest_node.origin );
|
||||
if ( isDefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
{
|
||||
return node.origin;
|
||||
}
|
||||
forward = anglesToForward( self getplayerangles() );
|
||||
origin = self geteye() + ( forward * 1024 );
|
||||
return origin;
|
||||
}
|
||||
|
||||
bot_sd_defender_think( zone ) //checked matches cerberus output
|
||||
{
|
||||
if ( self bot_need_to_defuse() )
|
||||
{
|
||||
if ( self maps/mp/bots/_bot::bot_friend_goal_in_radius( "sd_defuse", level.sdbombmodel.origin, 16 ) > 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
self clearlookat();
|
||||
goal = self getgoal( "sd_defuse" );
|
||||
if ( isDefined( goal ) && distancesquared( self.origin, goal ) < 2304 )
|
||||
{
|
||||
self setstance( "prone" );
|
||||
wait 0.5;
|
||||
self pressusebutton( level.defusetime + 1 );
|
||||
wait 0.5;
|
||||
if ( is_true( self.isdefusing ) )
|
||||
{
|
||||
wait ( level.defusetime + 1 );
|
||||
}
|
||||
self pressusebutton( 0 );
|
||||
self setstance( "crouch" );
|
||||
wait 0.25;
|
||||
self cancelgoal( "sd_defuse" );
|
||||
self setstance( "stand" );
|
||||
return;
|
||||
}
|
||||
if ( !isDefined( goal ) && distance2dsquared( self.origin, level.sdbombmodel.origin ) < 1000000 )
|
||||
{
|
||||
self addgoal( level.sdbombmodel.origin, 24, 4, "sd_defuse" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ( getTime() > self.bot[ "patrol_update" ] )
|
||||
{
|
||||
if ( cointoss() )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "sd_defend" );
|
||||
return;
|
||||
}
|
||||
self.bot[ "patrol_update" ] = getTime() + randomintrange( 2500, 5000 );
|
||||
}
|
||||
if ( self hasgoal( "enemy_patrol" ) )
|
||||
{
|
||||
goal = self getgoal( "enemy_patrol" );
|
||||
zone = sd_get_closest_bomb();
|
||||
if ( distancesquared( goal, zone.nearest_node.origin ) < 262144 )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "sd_defend" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ( getTime() > self.bot[ "lookat_update" ] )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
z = 20;
|
||||
if ( distancesquared( origin, self.origin ) > 262144 )
|
||||
{
|
||||
z = randomintrange( 16, 60 );
|
||||
}
|
||||
self lookat( origin + ( 0, 0, z ) );
|
||||
self.bot[ "lookat_update" ] = getTime() + randomintrange( 1500, 3000 );
|
||||
if ( distancesquared( origin, self.origin ) > 65536 )
|
||||
{
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = vectorScale( dir, 256 );
|
||||
origin += dir;
|
||||
}
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_proximity( origin );
|
||||
}
|
||||
}
|
||||
|
||||
bot_need_to_defuse() //checked changed at own discretion
|
||||
{
|
||||
if ( level.bombplanted && self.team == game[ "defenders" ] )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
sd_get_bomb_goal( ent ) //checked changed to match cerberus output
|
||||
{
|
||||
goals = [];
|
||||
dir = anglesToForward( ent.angles );
|
||||
dir = vectorScale( dir, 32 );
|
||||
goals[ 0 ] = ent.origin + dir;
|
||||
goals[ 1 ] = ent.origin - dir;
|
||||
dir = anglesToRight( ent.angles );
|
||||
dir = vectorScale( dir, 48 );
|
||||
goals[ 2 ] = ent.origin + dir;
|
||||
goals[ 3 ] = ent.origin - dir;
|
||||
goals = array_randomize( goals );
|
||||
foreach ( goal in goals )
|
||||
{
|
||||
if ( findpath( self.origin, goal, 0 ) )
|
||||
{
|
||||
return goal;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
sd_get_time_frac() //checked matches cerberus output
|
||||
{
|
||||
remaining = maps/mp/gametypes/_globallogic_utils::gettimeremaining();
|
||||
end = ( level.timelimit * 60 ) * 1000;
|
||||
if ( end == 0 )
|
||||
{
|
||||
end = self.spawntime + 120000;
|
||||
remaining = end - getTime();
|
||||
}
|
||||
return 1 - ( remaining / end );
|
||||
}
|
||||
|
||||
sd_get_closest_bomb() //checked partially changed to match cerberus output did not use continue see github for more info
|
||||
{
|
||||
best = undefined;
|
||||
distsq = 9999999;
|
||||
foreach ( zone in level.bombzones )
|
||||
{
|
||||
d = distancesquared( self.origin, zone.curorigin );
|
||||
if ( !isDefined( best ) )
|
||||
{
|
||||
best = zone;
|
||||
distsq = d;
|
||||
}
|
||||
else if ( d < distsq )
|
||||
{
|
||||
best = zone;
|
||||
distsq = d;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
sd_get_planted_zone() //checked changed to match cerberus output
|
||||
{
|
||||
if ( level.bombplanted )
|
||||
{
|
||||
foreach ( zone in level.bombzones )
|
||||
{
|
||||
if ( zone.interactteam == "none" )
|
||||
{
|
||||
return zone;
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
bot_sd_grenade() //checked changed to match cerberus output
|
||||
{
|
||||
enemies = bot_get_enemies();
|
||||
if ( !enemies.size )
|
||||
{
|
||||
return;
|
||||
}
|
||||
zone = sd_get_closest_bomb();
|
||||
foreach ( enemy in enemies )
|
||||
{
|
||||
if ( distancesquared( enemy.origin, zone.nearest_node.origin ) < 147456 )
|
||||
{
|
||||
if ( !self maps/mp/bots/_bot_combat::bot_combat_throw_lethal( enemy.origin ) )
|
||||
{
|
||||
self maps/mp/bots/_bot_combat::bot_combat_throw_tactical( enemy.origin );
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1141
Multiplayer Core/patch_mp/maps/mp/gametypes/_battlechatter_mp.gsc
Normal file
1141
Multiplayer Core/patch_mp/maps/mp/gametypes/_battlechatter_mp.gsc
Normal file
File diff suppressed because it is too large
Load Diff
213
Multiplayer Core/patch_mp/maps/mp/gametypes/_callbacksetup.gsc
Normal file
213
Multiplayer Core/patch_mp/maps/mp/gametypes/_callbacksetup.gsc
Normal file
@ -0,0 +1,213 @@
|
||||
#include maps/mp/gametypes/_hostmigration;
|
||||
#include maps/mp/gametypes/_globallogic_vehicle;
|
||||
#include maps/mp/gametypes/_globallogic_actor;
|
||||
#include maps/mp/gametypes/_globallogic_player;
|
||||
#include maps/mp/gametypes/_globallogic;
|
||||
#include maps/mp/_audio;
|
||||
#include maps/mp/_utility;
|
||||
#include common_scripts/utility;
|
||||
|
||||
codecallback_startgametype() //checked matches cerberus output
|
||||
{
|
||||
if ( !isDefined( level.gametypestarted ) || !level.gametypestarted )
|
||||
{
|
||||
[[ level.callbackstartgametype ]]();
|
||||
level.gametypestarted = 1;
|
||||
}
|
||||
}
|
||||
|
||||
codecallback_finalizeinitialization() //checked matches cerberus output
|
||||
{
|
||||
maps/mp/_utility::callback( "on_finalize_initialization" );
|
||||
}
|
||||
|
||||
codecallback_playerconnect() //checked matches cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self thread maps/mp/_audio::monitor_player_sprint();
|
||||
[[ level.callbackplayerconnect ]]();
|
||||
}
|
||||
|
||||
codecallback_playerdisconnect() //checked matches cerberus output
|
||||
{
|
||||
self notify( "disconnect" );
|
||||
level notify( "disconnect" );
|
||||
client_num = self getentitynumber();
|
||||
[[ level.callbackplayerdisconnect ]]();
|
||||
}
|
||||
|
||||
codecallback_hostmigration() //checked matches cerberus output
|
||||
{
|
||||
/*
|
||||
/#
|
||||
println( "****CodeCallback_HostMigration****" );
|
||||
#/
|
||||
*/
|
||||
[[ level.callbackhostmigration ]]();
|
||||
}
|
||||
|
||||
codecallback_hostmigrationsave() //checked matches cerberus output
|
||||
{
|
||||
/*
|
||||
/#
|
||||
println( "****CodeCallback_HostMigrationSave****" );
|
||||
#/
|
||||
*/
|
||||
[[ level.callbackhostmigrationsave ]]();
|
||||
}
|
||||
|
||||
codecallback_playermigrated() //checked matches cerberus output
|
||||
{
|
||||
/*
|
||||
/#
|
||||
println( "****CodeCallback_PlayerMigrated****" );
|
||||
#/
|
||||
*/
|
||||
[[ level.callbackplayermigrated ]]();
|
||||
}
|
||||
|
||||
codecallback_playerdamage( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, timeoffset, boneindex ) //checked matches cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
[[ level.callbackplayerdamage ]]( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, timeoffset, boneindex );
|
||||
}
|
||||
|
||||
codecallback_playerkilled( einflictor, eattacker, idamage, smeansofdeath, sweapon, vdir, shitloc, timeoffset, deathanimduration ) //checked matches cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
[[ level.callbackplayerkilled ]]( einflictor, eattacker, idamage, smeansofdeath, sweapon, vdir, shitloc, timeoffset, deathanimduration );
|
||||
}
|
||||
|
||||
codecallback_playerlaststand( einflictor, eattacker, idamage, smeansofdeath, sweapon, vdir, shitloc, timeoffset, deathanimduration ) //checked matches cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
[[ level.callbackplayerlaststand ]]( einflictor, eattacker, idamage, smeansofdeath, sweapon, vdir, shitloc, timeoffset, deathanimduration );
|
||||
}
|
||||
|
||||
codecallback_playermelee( eattacker, idamage, sweapon, vorigin, vdir, boneindex, shieldhit ) //checked matches cerberus output
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
[[ level.callbackplayermelee ]]( eattacker, idamage, sweapon, vorigin, vdir, boneindex, shieldhit );
|
||||
}
|
||||
|
||||
codecallback_actordamage( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, timeoffset, boneindex ) //checked matches cerberus output
|
||||
{
|
||||
[[ level.callbackactordamage ]]( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, timeoffset, boneindex );
|
||||
}
|
||||
|
||||
codecallback_actorkilled( einflictor, eattacker, idamage, smeansofdeath, sweapon, vdir, shitloc, timeoffset ) //checked matches cerberus output
|
||||
{
|
||||
[[ level.callbackactorkilled ]]( einflictor, eattacker, idamage, smeansofdeath, sweapon, vdir, shitloc, timeoffset );
|
||||
}
|
||||
|
||||
codecallback_vehicledamage( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, timeoffset, damagefromunderneath, modelindex, partname ) //checked matches cerberus output
|
||||
{
|
||||
[[ level.callbackvehicledamage ]]( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, timeoffset, damagefromunderneath, modelindex, partname );
|
||||
}
|
||||
|
||||
codecallback_vehicleradiusdamage( einflictor, eattacker, idamage, finnerdamage, fouterdamage, idflags, smeansofdeath, sweapon, vpoint, fradius, fconeanglecos, vconedir, timeoffset ) //checked matches cerberus output
|
||||
{
|
||||
[[ level.callbackvehicleradiusdamage ]]( einflictor, eattacker, idamage, finnerdamage, fouterdamage, idflags, smeansofdeath, sweapon, vpoint, fradius, fconeanglecos, vconedir, timeoffset );
|
||||
}
|
||||
|
||||
codecallback_faceeventnotify( notify_msg, ent ) //checked matches cerberus output
|
||||
{
|
||||
if ( isDefined( ent ) && is_true( ent.do_face_anims ) )
|
||||
{
|
||||
if ( isDefined( level.face_event_handler ) && isDefined( level.face_event_handler.events[ notify_msg ] ) )
|
||||
{
|
||||
ent sendfaceevent( level.face_event_handler.events[ notify_msg ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
codecallback_menuresponse( action, arg ) //checked matches cerberus output
|
||||
{
|
||||
if ( !isDefined( level.menuresponsequeue ) )
|
||||
{
|
||||
level.menuresponsequeue = [];
|
||||
level thread menuresponsequeuepump();
|
||||
}
|
||||
index = level.menuresponsequeue.size;
|
||||
level.menuresponsequeue[ index ] = spawnstruct();
|
||||
level.menuresponsequeue[ index ].action = action;
|
||||
level.menuresponsequeue[ index ].arg = arg;
|
||||
level.menuresponsequeue[ index ].ent = self;
|
||||
level notify( "menuresponse_queue" );
|
||||
}
|
||||
|
||||
menuresponsequeuepump() //checked changed to match cerberus output
|
||||
{
|
||||
while ( 1 )
|
||||
{
|
||||
level waittill( "menuresponse_queue" );
|
||||
level.menuresponsequeue[ 0 ].ent notify( "menuresponse", level.menuresponsequeue[0].action, level.menuresponsequeue[0].arg );
|
||||
arrayremoveindex( level.menuresponsequeue, 0, 0 );
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
setupcallbacks() //checked matches cerberus output
|
||||
{
|
||||
setdefaultcallbacks();
|
||||
level.idflags_radius = 1;
|
||||
level.idflags_no_armor = 2;
|
||||
level.idflags_no_knockback = 4;
|
||||
level.idflags_penetration = 8;
|
||||
level.idflags_destructible_entity = 16;
|
||||
level.idflags_shield_explosive_impact = 32;
|
||||
level.idflags_shield_explosive_impact_huge = 64;
|
||||
level.idflags_shield_explosive_splash = 128;
|
||||
level.idflags_no_team_protection = 256;
|
||||
level.idflags_no_protection = 512;
|
||||
level.idflags_passthru = 1024;
|
||||
}
|
||||
|
||||
setdefaultcallbacks() //checked matches cerberus output
|
||||
{
|
||||
level.callbackstartgametype = maps/mp/gametypes/_globallogic::callback_startgametype;
|
||||
level.callbackplayerconnect = maps/mp/gametypes/_globallogic_player::callback_playerconnect;
|
||||
level.callbackplayerdisconnect = maps/mp/gametypes/_globallogic_player::callback_playerdisconnect;
|
||||
level.callbackplayerdamage = maps/mp/gametypes/_globallogic_player::callback_playerdamage;
|
||||
level.callbackplayerkilled = maps/mp/gametypes/_globallogic_player::callback_playerkilled;
|
||||
level.callbackplayermelee = maps/mp/gametypes/_globallogic_player::callback_playermelee;
|
||||
level.callbackplayerlaststand = maps/mp/gametypes/_globallogic_player::callback_playerlaststand;
|
||||
level.callbackactordamage = maps/mp/gametypes/_globallogic_actor::callback_actordamage;
|
||||
level.callbackactorkilled = maps/mp/gametypes/_globallogic_actor::callback_actorkilled;
|
||||
level.callbackvehicledamage = maps/mp/gametypes/_globallogic_vehicle::callback_vehicledamage;
|
||||
level.callbackvehicleradiusdamage = maps/mp/gametypes/_globallogic_vehicle::callback_vehicleradiusdamage;
|
||||
level.callbackplayermigrated = maps/mp/gametypes/_globallogic_player::callback_playermigrated;
|
||||
level.callbackhostmigration = maps/mp/gametypes/_hostmigration::callback_hostmigration;
|
||||
level.callbackhostmigrationsave = maps/mp/gametypes/_hostmigration::callback_hostmigrationsave;
|
||||
}
|
||||
|
||||
abortlevel() //checked matches cerberus output
|
||||
{
|
||||
/*
|
||||
/#
|
||||
println( "ERROR: Aborting level - gametype is not supported" );
|
||||
#/
|
||||
*/
|
||||
level.callbackstartgametype = ::callbackvoid;
|
||||
level.callbackplayerconnect = ::callbackvoid;
|
||||
level.callbackplayerdisconnect = ::callbackvoid;
|
||||
level.callbackplayerdamage = ::callbackvoid;
|
||||
level.callbackplayerkilled = ::callbackvoid;
|
||||
level.callbackplayerlaststand = ::callbackvoid;
|
||||
level.callbackplayermelee = ::callbackvoid;
|
||||
level.callbackactordamage = ::callbackvoid;
|
||||
level.callbackactorkilled = ::callbackvoid;
|
||||
level.callbackvehicledamage = ::callbackvoid;
|
||||
setdvar( "g_gametype", "dm" );
|
||||
exitlevel( 0 );
|
||||
}
|
||||
|
||||
codecallback_glasssmash( pos, dir ) //checked matches cerberus output
|
||||
{
|
||||
level notify( "glass_smash" );
|
||||
}
|
||||
|
||||
callbackvoid() //checked matches cerberus output
|
||||
{
|
||||
}
|
||||
|
1300
Multiplayer Core/patch_mp/maps/mp/gametypes/_class.gsc
Normal file
1300
Multiplayer Core/patch_mp/maps/mp/gametypes/_class.gsc
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user