init
This commit is contained in:
921 files changed
+337975
No files matched your search
@@ -0,0 +1,19 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_acousticsensor;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace acousticsensor;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("acousticsensor",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
acousticsensor::init_shared();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_acousticsensor;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace acousticsensor;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("acousticsensor",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
acousticsensor::init_shared();
|
||||
}
|
||||
+714
@@ -0,0 +1,714 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\array_shared;
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\sound_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#namespace ambient;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("ambient",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
callback::on_localclient_connect( &on_player_connect );
|
||||
}
|
||||
|
||||
function on_player_connect( localclientnum )
|
||||
{
|
||||
thread ceiling_fans_init( localclientnum );
|
||||
thread clocks_init( localclientnum );
|
||||
thread spin_anemometers( localclientnum );
|
||||
if ( isdefined( level._levelSpecificAmbient ) )
|
||||
{
|
||||
thread [[level._levelSpecificAmbient]]( localClientNum );
|
||||
}
|
||||
}
|
||||
|
||||
// setup a script_struct to play scripted Flak88 tracers FX
|
||||
function setup_point_fx(point, fx_id)
|
||||
{
|
||||
if(isdefined(point.script_fxid))
|
||||
{
|
||||
fx_id = point.script_fxid;
|
||||
}
|
||||
|
||||
point.fx_id = fx_id;
|
||||
|
||||
if(isdefined(point.angles))
|
||||
{
|
||||
point.forward = anglesToForward(point.angles);
|
||||
point.up = anglesToUp(point.angles);
|
||||
}
|
||||
else
|
||||
{
|
||||
point.angles = (0, 0, 0);
|
||||
point.forward = (0, 0, 0);
|
||||
point.up = (0, 0, 0);
|
||||
}
|
||||
|
||||
if(point.targetname == "flak_fire_fx")
|
||||
{
|
||||
level thread ambient_flak_think(point);
|
||||
}
|
||||
|
||||
if(point.targetname == "fake_fire_fx")
|
||||
{
|
||||
level thread ambient_fakefire_think(point);
|
||||
}
|
||||
}
|
||||
|
||||
// rotate the Flak88 tracers FX
|
||||
function ambient_flak_think(point)
|
||||
{
|
||||
amount = undefined;
|
||||
speed = undefined;
|
||||
night = false;
|
||||
|
||||
min_delay = 0.4;
|
||||
max_delay = 4;
|
||||
|
||||
min_burst_time = 1;
|
||||
max_burst_time = 3;
|
||||
|
||||
point.is_firing = false;
|
||||
level thread ambient_flak_rotate(point);
|
||||
level thread ambient_flak_flash(point, min_burst_time, max_burst_time);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
timer = randomFloatRange(min_burst_time, max_burst_time);
|
||||
while(timer > 0)
|
||||
{
|
||||
point.is_firing = true;
|
||||
playFX(0, level._effect[point.fx_id], point.origin, point.forward, point.up);
|
||||
thread sound::play_in_space(0, "wpn_triple25_fire", point.origin);
|
||||
wait(0.2);
|
||||
|
||||
timer -= 0.2;
|
||||
}
|
||||
|
||||
point.is_firing = false;
|
||||
wait(randomFloatRange(min_delay, max_delay));
|
||||
}
|
||||
}
|
||||
|
||||
// This mimics the rotation of the FX, but without using an ent (or client-ent)
|
||||
// Updates the forward and up vectors which are used above
|
||||
function ambient_flak_rotate(point)
|
||||
{
|
||||
min_pitch = 30;
|
||||
max_pitch = 80;
|
||||
|
||||
if(isdefined(point.angles))
|
||||
{
|
||||
pointangles = point.angles;
|
||||
}
|
||||
else
|
||||
{
|
||||
pointangles = (0, 0, 0);
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
time = randomFloatRange(0.5, 2);
|
||||
steps = time * 10;
|
||||
|
||||
random_angle = (randomIntRange(min_pitch, max_pitch) * -1, randomInt(360), 0);
|
||||
|
||||
forward = anglesToForward(random_angle);
|
||||
up = anglesToUp(random_angle);
|
||||
|
||||
diff_forward = (forward - point.forward) / steps;
|
||||
diff_up = (up - point.up) / steps;
|
||||
|
||||
for(i = 0; i < steps; i++)
|
||||
{
|
||||
point.forward += diff_forward;
|
||||
point.up += diff_up;
|
||||
|
||||
wait(0.1);
|
||||
}
|
||||
|
||||
point.forward = forward;
|
||||
point.up = up;
|
||||
}
|
||||
}
|
||||
|
||||
// This gives a random chance to play a cloud flash
|
||||
// or flak burst FX for the ambient Flak
|
||||
function ambient_flak_flash(point, min_burst_time, max_burst_time)
|
||||
{
|
||||
min_dist = 5000;
|
||||
max_dist = 6500;
|
||||
|
||||
if(isdefined(point.script_mindist))
|
||||
{
|
||||
min_dist = point.script_mindist;
|
||||
}
|
||||
|
||||
if(isdefined(point.script_maxdist))
|
||||
{
|
||||
max_dist = point.script_maxdist;
|
||||
}
|
||||
|
||||
min_burst_time = 0.25;
|
||||
max_burst_time = 1;
|
||||
|
||||
fxpos = undefined;
|
||||
|
||||
while(1)
|
||||
{
|
||||
if( !point.is_firing )
|
||||
{
|
||||
wait( 0.25 );
|
||||
continue;
|
||||
}
|
||||
|
||||
fxpos = point.origin + VectorScale(point.forward, randomIntRange(min_dist, max_dist));
|
||||
|
||||
playFX(0, level._effect["flak_burst_single"], fxpos);
|
||||
|
||||
if(isdefined(level.timeofday) && (level.timeofday == "evening" || level.timeofday == "night"))
|
||||
{
|
||||
playFX(0, level._effect["flak_cloudflash_night"], fxpos);
|
||||
}
|
||||
|
||||
wait randomFloatRange(min_burst_time, max_burst_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *******************************************************************************************************
|
||||
// Ambient Weapon Muzzleflashes
|
||||
//
|
||||
// point = a script_struct in the map
|
||||
// This is used to play the ambient fake fire fx and sound
|
||||
function ambient_fakefire_think(point)
|
||||
{
|
||||
fireSound = undefined;
|
||||
weapType = undefined;
|
||||
|
||||
burstMin = undefined;
|
||||
burstMax = undefined;
|
||||
betweenShotsMin = undefined;
|
||||
betweenShotsMax = undefined;
|
||||
reloadTimeMin = undefined;
|
||||
reloadTimeMax = undefined;
|
||||
soundChance = undefined;
|
||||
|
||||
if(!isdefined(point.weaponinfo))
|
||||
{
|
||||
point.weaponinfo = "axis_turret";
|
||||
}
|
||||
|
||||
// determine what type of weapon the script_struct is faking
|
||||
switch(point.weaponinfo)
|
||||
{
|
||||
case "allies_assault":
|
||||
|
||||
if(isdefined(level.allies_team) && (level.allies_team == "marines"))
|
||||
{
|
||||
fireSound = "weap_bar_fire";
|
||||
}
|
||||
else
|
||||
{
|
||||
fireSound = "weap_dp28_fire_plr";
|
||||
}
|
||||
|
||||
burstMin = 16;
|
||||
burstMax = 24;
|
||||
betweenShotsMin = 0.05;
|
||||
betweenShotsMax = 0.08;
|
||||
reloadTimeMin = 4;
|
||||
reloadTimeMax = 7;
|
||||
soundChance = 75;
|
||||
weapType = "assault";
|
||||
break;
|
||||
|
||||
case "axis_assault":
|
||||
|
||||
if(isdefined(level.axis_team) && (level.axis_team == "german"))
|
||||
{
|
||||
fireSound = "weap_mp44_fire";
|
||||
}
|
||||
else
|
||||
{
|
||||
fireSound = "weap_type99_fire";
|
||||
}
|
||||
|
||||
burstMin = 16;
|
||||
burstMax = 24;
|
||||
betweenShotsMin = 0.05;
|
||||
betweenShotsMax = 0.08;
|
||||
reloadTimeMin = 4;
|
||||
reloadTimeMax = 7;
|
||||
soundChance = 75;
|
||||
weapType = "assault";
|
||||
break;
|
||||
|
||||
case "allies_rifle":
|
||||
|
||||
if(isdefined(level.allies_team) && (level.allies_team == "marines"))
|
||||
{
|
||||
fireSound = "weap_m1garand_fire";
|
||||
}
|
||||
else
|
||||
{
|
||||
fireSound = "weap_mosinnagant_fire";
|
||||
}
|
||||
|
||||
burstMin = 1;
|
||||
burstMax = 3;
|
||||
betweenShotsMin = 0.8;
|
||||
betweenShotsMax = 1.3;
|
||||
reloadTimeMin = 3;
|
||||
reloadTimeMax = 6;
|
||||
soundChance = 95;
|
||||
weapType = "rifle";
|
||||
break;
|
||||
|
||||
case "axis_rifle":
|
||||
|
||||
if(isdefined(level.axis_team) && (level.axis_team == "german"))
|
||||
{
|
||||
fireSound = "weap_kar98k_fire";
|
||||
}
|
||||
else
|
||||
{
|
||||
fireSound = "weap_arisaka_fire";
|
||||
}
|
||||
|
||||
burstMin = 1;
|
||||
burstMax = 3;
|
||||
betweenShotsMin = 0.8;
|
||||
betweenShotsMax = 1.3;
|
||||
reloadTimeMin = 3;
|
||||
reloadTimeMax = 6;
|
||||
soundChance = 95;
|
||||
weapType = "rifle";
|
||||
break;
|
||||
|
||||
case "allies_smg":
|
||||
|
||||
if(isdefined(level.allies_team) && (level.allies_team == "marines"))
|
||||
{
|
||||
fireSound = "weap_thompson_fire";
|
||||
}
|
||||
else
|
||||
{
|
||||
fireSound = "weap_ppsh_fire";
|
||||
}
|
||||
|
||||
burstMin = 14;
|
||||
burstMax = 28;
|
||||
betweenShotsMin = 0.08;
|
||||
betweenShotsMax = 0.12;
|
||||
reloadTimeMin = 2;
|
||||
reloadTimeMax = 5;
|
||||
soundChance = 75;
|
||||
weapType = "smg";
|
||||
break;
|
||||
|
||||
case "axis_smg":
|
||||
|
||||
if(isdefined(level.axis_team) && (level.axis_team == "german"))
|
||||
{
|
||||
fireSound = "weap_mp40_fire";
|
||||
}
|
||||
else
|
||||
{
|
||||
fireSound = "weap_type100_fire";
|
||||
}
|
||||
|
||||
burstMin = 14;
|
||||
burstMax = 28;
|
||||
betweenShotsMin = 0.08;
|
||||
betweenShotsMax = 0.12;
|
||||
reloadTimeMin = 2;
|
||||
reloadTimeMax = 5;
|
||||
soundChance = 75;
|
||||
weapType = "smg";
|
||||
break;
|
||||
|
||||
case "allies_turret":
|
||||
|
||||
if(isdefined(level.allies_team) && (level.allies_team == "marines"))
|
||||
{
|
||||
fireSound = "weap_30cal_fire";
|
||||
}
|
||||
else
|
||||
{
|
||||
fireSound = "weap_dp28_fire_plr";
|
||||
}
|
||||
|
||||
burstMin = 60;
|
||||
burstMax = 90;
|
||||
betweenShotsMin = 0.05;
|
||||
betweenShotsMax = 0.08;
|
||||
reloadTimeMin = 3;
|
||||
reloadTimeMax = 6;
|
||||
soundChance = 95;
|
||||
weapType = "turret";
|
||||
break;
|
||||
|
||||
case "axis_turret":
|
||||
|
||||
if(isdefined(level.axis_team) && (level.axis_team == "german"))
|
||||
{
|
||||
fireSound = "weap_bar_fire"; //update this if the sound changes
|
||||
}
|
||||
else
|
||||
{
|
||||
fireSound = "weap_type92_fire";
|
||||
}
|
||||
|
||||
burstMin = 60;
|
||||
burstMax = 90;
|
||||
betweenShotsMin = 0.05;
|
||||
betweenShotsMax = 0.08;
|
||||
reloadTimeMin = 3;
|
||||
reloadTimeMax = 6;
|
||||
soundChance = 95;
|
||||
weapType = "turret";
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERTMSG("Ambient Fakefire: Weapon Info '" + point.weaponinfo + "' is not recognized.");
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
// burst fire
|
||||
burst = randomIntRange(burstMin, burstMax);
|
||||
|
||||
for(i = 0; i < burst; i++)
|
||||
{
|
||||
traceDist = 10000;
|
||||
|
||||
target = point.origin + VectorScale(anglesToForward(point.angles + (-3 + randomInt(6), -5 + randomInt(10), 0)), traceDist);
|
||||
|
||||
// -- not using real weaponsettings
|
||||
if ( randomInt(100) <= 20 )
|
||||
{
|
||||
bulletTracer(point.origin, target);
|
||||
}
|
||||
|
||||
playFX(0, level._effect[point.fx_id], point.origin, point.forward);
|
||||
|
||||
// snyder steez - reduce popcorn effect
|
||||
// if(randomInt(100) <= soundChance)
|
||||
// {
|
||||
// thread sound::play_in_space(0, fireSound, point.origin);
|
||||
// }
|
||||
|
||||
wait (randomFloatRange(betweenShotsMin, betweenShotsMax));
|
||||
}
|
||||
|
||||
wait (randomFloatRange(reloadTimeMin, reloadTimeMax));
|
||||
}
|
||||
}
|
||||
|
||||
function ceiling_fans_init(clientNum)
|
||||
{
|
||||
// grab all of the ceiling fans and make them spin
|
||||
fan_array = GetEntArray(clientNum, "ceiling_fan", "targetname");
|
||||
if( isdefined(fan_array) )
|
||||
{
|
||||
/# println("**********fan array is defined, size: " + fan_array.size); #/
|
||||
array::thread_all( fan_array,&spin_fan );
|
||||
}
|
||||
}
|
||||
|
||||
function spin_fan() // self == fan from the array
|
||||
{
|
||||
self endon("entityshutdown");
|
||||
|
||||
//println("**********fan running");
|
||||
// get the speed from the fan, if no speed then make it random
|
||||
if ( !isdefined ( self.speed ) )
|
||||
{
|
||||
self.speed = RandomIntRange(1, 100);
|
||||
self.speed = (self.speed % 10) + 1;
|
||||
}
|
||||
if ( self.speed < 1 )
|
||||
{
|
||||
self.speed = RandomIntRange(1, 100);
|
||||
self.speed = (self.speed % 10) + 1;
|
||||
}
|
||||
|
||||
// see if they want it to wobble
|
||||
do_wobble = false;
|
||||
wobble = self.script_noteworthy;
|
||||
if( isdefined(wobble) )
|
||||
{
|
||||
if( wobble == "wobble" )
|
||||
{
|
||||
do_wobble = true;
|
||||
self.wobble_speed = self.speed * 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
//println("**********fan speed: " + self.speed);
|
||||
//println("**********fan wobble: " + do_wobble);
|
||||
|
||||
while(true)
|
||||
{
|
||||
if( !do_wobble )
|
||||
{
|
||||
self RotateYaw(180, self.speed);
|
||||
self waittill("rotatedone");
|
||||
}
|
||||
else
|
||||
{
|
||||
self RotateYaw(340, self.speed);
|
||||
self waittill("rotatedone");
|
||||
self RotateYaw(20, self.wobble_speed);
|
||||
self waittill("rotatedone");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function clocks_init(clientNum)
|
||||
{
|
||||
// the format should be an array (hour, min, sec), military time
|
||||
// if we pass in a 1 then we'll get GMT 0 London time, else we get the local time on the kit
|
||||
curr_time = GetSystemTime();
|
||||
|
||||
// put the hands in the right place
|
||||
hours = curr_time[0];
|
||||
if( hours > 12 )
|
||||
{
|
||||
hours -= 12;
|
||||
}
|
||||
if( hours == 0 )
|
||||
{
|
||||
hours = 12;
|
||||
}
|
||||
minutes = curr_time[1];
|
||||
seconds = curr_time[2];
|
||||
|
||||
// set the starting time
|
||||
// hoping that all of the hands start pointing straight up at 12
|
||||
// each hour is 30 degrees of rotation ...
|
||||
// it should also rotate a little bit each time the minute hand moves
|
||||
// the math is 30 degrees of rotations in 3600 seconds (1 hour)
|
||||
hour_hand = GetEntArray(clientNum, "hour_hand", "targetname");
|
||||
hour_values = [];
|
||||
hour_values["hand_time"] = hours;
|
||||
hour_values["rotate"] = 30;
|
||||
hour_values["rotate_bit"] = 30 / 3600;
|
||||
// we need to do the first rotation based on the beginning time, if we don't do this the time will look like it's off a little bit
|
||||
hour_values["first_rotate"] = ((minutes * 60) + seconds) * hour_values["rotate_bit"];
|
||||
|
||||
// each minute is 6 degrees of rotation ...
|
||||
// it should also rotate a little bit each time the second hand moves
|
||||
// the math is 6 degrees of rotations in 60 seconds (1 minute)
|
||||
minute_hand = GetEntArray(clientNum, "minute_hand", "targetname");
|
||||
minute_values = [];
|
||||
minute_values["hand_time"] = minutes;
|
||||
minute_values["rotate"] = 6;
|
||||
minute_values["rotate_bit"] = 6 / 60;
|
||||
// we need to do the first rotation based on the beginning time, if we don't do this the time will look like it's off a little bit
|
||||
minute_values["first_rotate"] = seconds * minute_values["rotate_bit"];
|
||||
|
||||
// each second is 6 degrees of rotation
|
||||
second_hand = GetEntArray(clientNum, "second_hand", "targetname");
|
||||
second_values = [];
|
||||
second_values["hand_time"] = seconds;
|
||||
second_values["rotate"] = 6;
|
||||
second_values["rotate_bit"] = 6;
|
||||
|
||||
hour_hand_array = GetEntArray(clientNum, "hour_hand", "targetname");
|
||||
if( isdefined(hour_hand_array) )
|
||||
{
|
||||
/# println("**********hour_hand_array is defined, size: " + hour_hand_array.size); #/
|
||||
array::thread_all( hour_hand_array,&clock_run, hour_values );
|
||||
}
|
||||
minute_hand_array = GetEntArray(clientNum, "minute_hand", "targetname");
|
||||
if( isdefined(minute_hand_array) )
|
||||
{
|
||||
/# println("**********minute_hand_array is defined, size: " + minute_hand_array.size); #/
|
||||
array::thread_all( minute_hand_array,&clock_run, minute_values );
|
||||
}
|
||||
second_hand_array = GetEntArray(clientNum, "second_hand", "targetname");
|
||||
if( isdefined(second_hand_array) )
|
||||
{
|
||||
/# println("**********second_hand_array is defined, size: " + second_hand_array.size); #/
|
||||
array::thread_all( second_hand_array,&clock_run, second_values );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function clock_run(time_values) // self == either hour hand, minute hand, or second hand
|
||||
{
|
||||
self endon("entityshutdown");
|
||||
|
||||
// hour hands will have script_noteworthy = time zone if they want a different time zone
|
||||
if( isdefined(self.script_noteworthy) )
|
||||
{
|
||||
hour = time_values["hand_time"];
|
||||
curr_time = GetSystemTime(1);
|
||||
|
||||
switch( ToLower(self.script_noteworthy) )
|
||||
{
|
||||
case "honolulu": // GMT -10
|
||||
hour = curr_time[0] - 10;
|
||||
break;
|
||||
case "alaska": // GMT -9
|
||||
hour = curr_time[0] - 9;
|
||||
break;
|
||||
case "los angeles": // GMT -8
|
||||
hour = curr_time[0] - 8;
|
||||
break;
|
||||
case "denver": // GMT -7
|
||||
hour = curr_time[0] - 7;
|
||||
break;
|
||||
case "chicago": // GMT -6
|
||||
hour = curr_time[0] - 6;
|
||||
break;
|
||||
case "new york": // GMT -5
|
||||
hour = curr_time[0] - 5;
|
||||
break;
|
||||
case "halifax": // GMT -4
|
||||
hour = curr_time[0] - 4;
|
||||
break;
|
||||
case "greenland": // GMT -3
|
||||
hour = curr_time[0] - 3;
|
||||
break;
|
||||
case "london": // GMT 0
|
||||
hour = curr_time[0];
|
||||
break;
|
||||
case "paris": // GMT +1
|
||||
hour = curr_time[0] + 1;
|
||||
break;
|
||||
case "helsinki": // GMT +2
|
||||
hour = curr_time[0] + 2;
|
||||
break;
|
||||
case "moscow": // GMT +3
|
||||
hour = curr_time[0] + 3;
|
||||
break;
|
||||
case "vietnam": // GMT +7
|
||||
hour = curr_time[0] + 7;
|
||||
break;
|
||||
case "china": // GMT +8
|
||||
hour = curr_time[0] + 8;
|
||||
break;
|
||||
}
|
||||
|
||||
if( hour < 1 )
|
||||
{
|
||||
hour += 12;
|
||||
}
|
||||
if( hour > 12 )
|
||||
{
|
||||
hour -= 12;
|
||||
}
|
||||
time_values["hand_time"] = hour;
|
||||
}
|
||||
|
||||
self RotatePitch(time_values["hand_time"] * time_values["rotate"], 0.05);
|
||||
self waittill("rotatedone");
|
||||
|
||||
if( isdefined(time_values["first_rotate"]) )
|
||||
{
|
||||
self RotatePitch(time_values["first_rotate"], 0.05);
|
||||
self waittill("rotatedone");
|
||||
}
|
||||
|
||||
prev_time = GetSystemTime();
|
||||
|
||||
while(true)
|
||||
{
|
||||
curr_time = GetSystemTime();
|
||||
if( prev_time != curr_time )
|
||||
{
|
||||
self RotatePitch(time_values["rotate_bit"], 0.05);
|
||||
|
||||
prev_time = curr_time;
|
||||
}
|
||||
|
||||
wait(1.0);
|
||||
}
|
||||
}
|
||||
|
||||
//Makes it so anemometers will spin whenever builders drop them into their map
|
||||
function spin_anemometers( clientNum )
|
||||
{
|
||||
spoon_spinners = GetEntArray(clientNum, "spinner1","targetname");
|
||||
flat_spinners = GetEntArray( clientNum, "spinner2","targetname");
|
||||
|
||||
if( isdefined( spoon_spinners ))
|
||||
{
|
||||
/# println("**********spoon_spinners is defined, size: " + spoon_spinners.size); #/
|
||||
array::thread_all( spoon_spinners,&spoon_spin_func);
|
||||
}
|
||||
|
||||
if( isdefined( flat_spinners ))
|
||||
{
|
||||
/# println("**********flat_spinners is defined, size: " + flat_spinners.size); #/
|
||||
array::thread_all( flat_spinners,&arrow_spin_func);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Self is the "spoon" like script model within the anemometer
|
||||
function spoon_spin_func()
|
||||
{
|
||||
self endon( "entityshutdown" );
|
||||
|
||||
if(isdefined( self.script_float))
|
||||
{
|
||||
model_speed = self.script_float;
|
||||
}
|
||||
else
|
||||
{
|
||||
model_speed = 2;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
speed = RandomFloatRange( model_speed * .6, model_speed);
|
||||
self RotateYaw( 1200, speed);
|
||||
self waittill ("rotatedone");
|
||||
}
|
||||
}
|
||||
|
||||
//Self is the "arrow" like script model within the anemometer
|
||||
function arrow_spin_func()
|
||||
{
|
||||
self endon( "entityshutdown" );
|
||||
|
||||
if(isdefined( self.script_int))
|
||||
{
|
||||
model_direction_change = self.script_int;
|
||||
}
|
||||
else
|
||||
{
|
||||
model_direction_change = 25;
|
||||
}
|
||||
|
||||
if(isdefined( self.script_float))
|
||||
{
|
||||
model_speed = self.script_float;
|
||||
}
|
||||
else
|
||||
{
|
||||
model_speed = .8;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
direction_change = model_direction_change + RandomIntRange(-11, 11);
|
||||
speed_change = RandomFloatRange(model_speed * .3, model_speed);
|
||||
|
||||
self RotateYaw( direction_change, speed_change);
|
||||
self waittill ("rotatedone");
|
||||
self RotateYaw( (direction_change * -1), speed_change);
|
||||
self waittill ("rotatedone");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\teams\_teams;
|
||||
|
||||
#namespace arena;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("arena",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
callback::on_connect( &on_connect );
|
||||
}
|
||||
|
||||
function on_connect()
|
||||
{
|
||||
if( isdefined( self.pers["arenaInit"] ) && self.pers["arenaInit"] == 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
draftEnabled = ( GetGametypeSetting( "pregameDraftEnabled" ) == 1 );
|
||||
voteEnabled = ( GetGametypeSetting( "pregameItemVoteEnabled" ) == 1 );
|
||||
|
||||
if( !draftEnabled && !voteEnabled )
|
||||
{
|
||||
self ArenaBeginMatch();
|
||||
}
|
||||
|
||||
self.pers["arenaInit"] = 1;
|
||||
}
|
||||
|
||||
function update_arena_challenge_seasons()
|
||||
{
|
||||
perSeasonWins = self GetDStat( "arenaPerSeasonStats", "wins" );
|
||||
if( perSeasonWins >= GetDvarInt( "arena_seasonVetChallengeWins" ) )
|
||||
{
|
||||
arenaSlot = ArenaGetSlot();
|
||||
currentSeason = self GetDStat( "arenaStats", arenaSlot, "season" );
|
||||
seasonVetChallengeArrayCount = self GetDStatArrayCount( "arenaChallengeSeasons" );
|
||||
for( i = 0; i < seasonVetChallengeArrayCount; i++ )
|
||||
{
|
||||
challengeSeason = self GetDStat( "arenaChallengeSeasons", i );
|
||||
if( challengeSeason == currentSeason ) // don't add a single season more than once
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( challengeSeason == 0 )
|
||||
{
|
||||
self SetDStat( "arenaChallengeSeasons", i, currentSeason );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function match_end( winner )
|
||||
{
|
||||
for( index = 0; index < level.players.size; index++ )
|
||||
{
|
||||
player = level.players[index];
|
||||
|
||||
if( isdefined( player.pers["arenaInit"] ) && player.pers["arenaInit"] == 1 )
|
||||
{
|
||||
if( winner == "tie" )
|
||||
{
|
||||
player ArenaEndMatch( 0 );
|
||||
}
|
||||
else if( winner == player.pers["team"] )
|
||||
{
|
||||
player ArenaEndMatch( 1 );
|
||||
player arena::update_arena_challenge_seasons();
|
||||
}
|
||||
else
|
||||
{
|
||||
player ArenaEndMatch( -1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\weapons\_proximity_grenade;
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#namespace armblade;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("armblade",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
level.weaponArmblade = GetWeapon( "hero_armblade" );
|
||||
callback::on_spawned( &on_player_spawned );
|
||||
}
|
||||
|
||||
function on_player_spawned()
|
||||
{
|
||||
self thread armblade_sound_thread();
|
||||
}
|
||||
|
||||
function armblade_sound_thread()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
for( ;; )
|
||||
{
|
||||
result = self util::waittill_any_return( "weapon_change", "disconnect" );
|
||||
if( IsDefined( result ) )
|
||||
{
|
||||
if( ( result == "weapon_change" ) && ( self GetCurrentWeapon() == level.weaponArmblade ) )
|
||||
{
|
||||
if( !IsDefined( self.armblade_loop_sound ) )
|
||||
{
|
||||
self.armblade_loop_sound = spawn( "script_origin", self.origin );
|
||||
self.armblade_loop_sound linkto( self );
|
||||
}
|
||||
|
||||
self.armblade_loop_sound PlayLoopSound( "wpn_armblade_idle", 0.25 );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( IsDefined( self.armblade_loop_sound ) )
|
||||
{
|
||||
self.armblade_loop_sound StopLoopSound( 0.25 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\math_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
#precache( "lui_menu_data", "hudItems.armorPercent" );
|
||||
|
||||
#namespace armor;
|
||||
|
||||
function setLightArmorHP( newValue )
|
||||
{
|
||||
if ( IsDefined( newValue ) )
|
||||
{
|
||||
self.lightArmorHP = newValue;
|
||||
if( IsPlayer( self ) && IsDefined( self.maxLightArmorHP ) && self.maxLightArmorHP > 0 )
|
||||
{
|
||||
lightArmorPercent = math::clamp( self.lightArmorHP / self.maxLightArmorHP, 0, 1 );
|
||||
self SetControllerUIModelValue( "hudItems.armorPercent", lightArmorPercent );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self.lightArmorHP = undefined;
|
||||
self.maxLightArmorHP = undefined;
|
||||
self SetControllerUIModelValue( "hudItems.armorPercent", 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// ARMOR: give a health boost
|
||||
function setLightArmor( optionalArmorValue )
|
||||
{
|
||||
self notify( "give_light_armor" );
|
||||
|
||||
if( IsDefined( self.lightArmorHP ) )
|
||||
unsetLightArmor();
|
||||
|
||||
self thread removeLightArmorOnDeath();
|
||||
self thread removeLightArmorOnMatchEnd();
|
||||
|
||||
if( IsDefined( optionalArmorValue ) )
|
||||
self.maxLightArmorHP = optionalArmorValue;
|
||||
else
|
||||
self.maxLightArmorHP = 150;
|
||||
|
||||
self setLightArmorHP( self.maxLightArmorHP );
|
||||
}
|
||||
|
||||
function removeLightArmorOnDeath()
|
||||
{
|
||||
self endon ( "disconnect" );
|
||||
self endon( "give_light_armor" );
|
||||
self endon( "remove_light_armor" );
|
||||
|
||||
self waittill ( "death" );
|
||||
unsetLightArmor();
|
||||
}
|
||||
|
||||
function unsetLightArmor()
|
||||
{
|
||||
self setLightArmorHP( undefined );
|
||||
|
||||
self notify( "remove_light_armor" );
|
||||
}
|
||||
|
||||
function removeLightArmorOnMatchEnd()
|
||||
{
|
||||
self endon ( "disconnect" );
|
||||
self endon ( "remove_light_armor" );
|
||||
|
||||
level waittill( "game_ended" );
|
||||
|
||||
self thread unsetLightArmor();
|
||||
}
|
||||
|
||||
function hasLightArmor()
|
||||
{
|
||||
return ( IsDefined( self.lightArmorHP ) && self.lightArmorHP > 0 );
|
||||
}
|
||||
|
||||
function getArmor()
|
||||
{
|
||||
if( IsDefined( self.lightArmorHP ) )
|
||||
{
|
||||
return self.lightArmorHP;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+332
@@ -0,0 +1,332 @@
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#namespace art;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("art",&__init__,undefined,undefined); }
|
||||
|
||||
// This function should take care of grain and glow settings for each map, plus anything else that artists
|
||||
// need to be able to tweak without bothering level designers.
|
||||
|
||||
function __init__()
|
||||
{
|
||||
/#
|
||||
if( GetDvarString( "scr_art_tweak" ) == "" || GetDvarString( "scr_art_tweak" ) == "0" )
|
||||
{
|
||||
SetDvar( "scr_art_tweak", 0 );
|
||||
}
|
||||
|
||||
if( GetDvarString( "scr_dof_enable" ) == "" )
|
||||
{
|
||||
SetDvar( "scr_dof_enable", "1" );
|
||||
}
|
||||
|
||||
if( GetDvarString( "scr_cinematic_autofocus" ) == "" )
|
||||
{
|
||||
SetDvar( "scr_cinematic_autofocus", "1" );
|
||||
}
|
||||
|
||||
if( GetDvarString( "scr_art_visionfile" ) == "" && isdefined(level.script) )
|
||||
{
|
||||
SetDvar( "scr_art_visionfile", level.script );
|
||||
}
|
||||
#/
|
||||
|
||||
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();
|
||||
#/
|
||||
}
|
||||
|
||||
function artfxprintln( file, string )
|
||||
{
|
||||
/#
|
||||
// printing to file is optional now
|
||||
if( file == -1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
fprintln( file, string );
|
||||
#/
|
||||
}
|
||||
|
||||
|
||||
// Nate - hack Fixmed and replace with proper script command call once it's fixed.
|
||||
// assumes " " as the deliiter. I'm not getting fancy.
|
||||
// I would really like to go work on jeepride so here's a
|
||||
// quick function that works for now untill engineering fixes strtok.
|
||||
|
||||
function strtok_loc( string, par1 )
|
||||
{
|
||||
stringlist = [];
|
||||
indexstring = "";
|
||||
for( i = 0 ; i < string.size ; i ++ )
|
||||
{
|
||||
if( string[i] == " " )
|
||||
{
|
||||
stringlist[stringlist.size] = indexstring;
|
||||
indexstring = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
indexstring = indexstring+string[i];
|
||||
}
|
||||
}
|
||||
if( indexstring.size )
|
||||
{
|
||||
stringlist[stringlist.size] = indexstring;
|
||||
}
|
||||
return stringlist;
|
||||
}
|
||||
|
||||
|
||||
function setfogsliders()
|
||||
{
|
||||
//fixme. replace strtok_loc with strtok if it ever works properly.
|
||||
fogall = strtok_loc( GetDvarString( "g_fogColorReadOnly" ), " " ) ;
|
||||
red = fogall[ 0 ];
|
||||
green = fogall[ 1 ];
|
||||
blue = fogall[ 2 ];
|
||||
halfplane = GetDvarString( "g_fogHalfDistReadOnly" );
|
||||
nearplane = GetDvarString( "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);
|
||||
}
|
||||
|
||||
function tweakart()
|
||||
{
|
||||
/#
|
||||
if( !isdefined( level.tweakfile ) )
|
||||
{
|
||||
level.tweakfile = false;
|
||||
}
|
||||
|
||||
|
||||
// Default values
|
||||
|
||||
if(GetDvarString( "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" );
|
||||
}
|
||||
|
||||
// not in DEVGUI
|
||||
SetDvar( "scr_fog_fraction", "1.0" );
|
||||
SetDvar( "scr_art_dump", "0" );
|
||||
SetDvar("scr_art_sun_fog_dir_set", "0");
|
||||
|
||||
// update the devgui variables to current settings
|
||||
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;
|
||||
|
||||
// set dofvars from < levelname > _art.gsc
|
||||
|
||||
|
||||
tweak_toggle = 1;
|
||||
for( ;; )
|
||||
{
|
||||
while(GetDvarint( "scr_art_tweak" ) == 0 )
|
||||
{
|
||||
tweak_toggle = 1;
|
||||
wait .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]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//translate the slider values to script variables
|
||||
|
||||
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");
|
||||
|
||||
colors = StrTok(GetDvarString("scr_fog_color")," ");
|
||||
level.fogcolorred = int(colors[0]);
|
||||
level.fogcolorgreen = int(colors[1]);
|
||||
level.fogcolorblue = int(colors[2]);
|
||||
level.fogcolorscale = GetDvarfloat( "scr_fog_color_scale");
|
||||
|
||||
colors = StrTok(GetDvarString("scr_sun_fog_color")," ");
|
||||
level.sunfogcolorred = int(colors[0]);
|
||||
level.sunfogcolorgreen = int(colors[1]);
|
||||
level.sunfogcolorblue = int(colors[2]);
|
||||
|
||||
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 = GetPlayers();
|
||||
|
||||
dir = VectorNormalize( AnglesToForward( players[0] GetPlayerAngles() ) );
|
||||
|
||||
level.fogsundir = [];
|
||||
level.fogsundir[0] = dir[0];
|
||||
level.fogsundir[1] = dir[1];
|
||||
level.fogsundir[2] = dir[2];
|
||||
}
|
||||
|
||||
|
||||
// catch all those cases where a slider can be pushed to a place of conflict
|
||||
fovslidercheck();
|
||||
|
||||
dumpsettings(); // dumps and returns true if the dump dvar is set
|
||||
|
||||
// updates fog to the variables
|
||||
|
||||
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 ); // couldn't find discreet fog disabling other than to never set it in the first place
|
||||
}
|
||||
|
||||
wait .1;
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
function fovslidercheck()
|
||||
{
|
||||
// catch all those cases where a slider can be pushed to a place of conflict
|
||||
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"] - .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"] );
|
||||
}
|
||||
}
|
||||
|
||||
function dumpsettings()
|
||||
{
|
||||
/#
|
||||
if ( GetDvarString( "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" );
|
||||
}
|
||||
#/
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\weapons\_ballistic_knife;
|
||||
|
||||
Line truncated
|
||||
|
||||
#namespace ballistic_knife;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("ballistic_knife",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
ballistic_knife::init_shared();
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
#using scripts\codescripts\struct;
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\bb_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#namespace bb;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("bb",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
bb::init_shared();
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
#using scripts\shared\math_shared;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#namespace behaviorTracker;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
///// Inititialize & Finaliize ////
|
||||
/////////////////////////////////////////////////////
|
||||
function SetupTraits()
|
||||
{
|
||||
if ( isDefined( self.behaviorTracker.traits ) )
|
||||
return;
|
||||
|
||||
self.behaviorTracker.traits = [];
|
||||
// Define the traits with a default value. This default value will be used if we dont have stats.
|
||||
// Add the information to the BBPrint()
|
||||
self.behaviorTracker.traits["effectiveCombat"] = 0.5;
|
||||
self.behaviorTracker.traits["effectiveWallRunCombat"] = 0.5;
|
||||
self.behaviorTracker.traits["effectiveDoubleJumpCombat"] = 0.5;
|
||||
self.behaviorTracker.traits["effectiveSlideCombat"] = 0.5;
|
||||
|
||||
if ( self.behaviorTracker.version != 0 )
|
||||
{
|
||||
traits = getArrayKeys( self.behaviorTracker.traits );
|
||||
|
||||
for ( i = 0; i < traits.size; i++ )
|
||||
{
|
||||
trait = traits[i];
|
||||
self.behaviorTracker.traits[trait] = float( self GetTraitStatValue( trait ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Initialize()
|
||||
{
|
||||
if ( isdefined( self.pers["isBot"] ) )
|
||||
return;
|
||||
|
||||
if ( isDefined( self.behaviorTracker ) )
|
||||
return;
|
||||
|
||||
if ( isdefined( level.disableBehaviorTracker ) && level.disableBehaviorTracker == true )
|
||||
return;
|
||||
|
||||
self.behaviorTracker = spawnstruct();
|
||||
self.behaviorTracker.version = int( self GetTraitStatValue( "version" ) );
|
||||
self.behaviorTracker.numRecords = int( self GetTraitStatValue( "numRecords" ) ) + 1;
|
||||
self SetupTraits();
|
||||
|
||||
self.behaviorTracker.valid = true;
|
||||
}
|
||||
|
||||
function Finalize()
|
||||
{
|
||||
if ( !( self IsAllowed() ) )
|
||||
return;
|
||||
|
||||
self SetTraitStats();
|
||||
|
||||
self PrintTrackerToBlackBox();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
///// Utility Functions ////
|
||||
/////////////////////////////////////////////////////
|
||||
function IsAllowed()
|
||||
{
|
||||
if ( !isDefined( self ) )
|
||||
return false;
|
||||
|
||||
if ( !isDefined( self.behaviorTracker ) )
|
||||
return false;
|
||||
|
||||
if ( !self.behaviorTracker.valid )
|
||||
return false;
|
||||
|
||||
if ( isdefined( level.disableBehaviorTracker ) && level.disableBehaviorTracker == true )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function PrintTrackerToBlackBox()
|
||||
{
|
||||
// Prepare the list of traits & its values
|
||||
// TODO: Construct the string with all the traits so that it can just be added as a single variable in the print.
|
||||
/*traitsStr = "";
|
||||
traits = getArrayKeys( self.behaviorTracker.traits );
|
||||
|
||||
for ( i = 0; i < traits.size; i++ )
|
||||
{
|
||||
trait = traits[i];
|
||||
value = self.behaviorTracker.traits[trait];
|
||||
|
||||
traitsStr = traitsStr + trait + " " + value + " ";
|
||||
}
|
||||
|
||||
bbPrint( "mpbehaviortracker", "username %s version %d numRecords %d %s", self.name, self.behaviorTracker.version, self.behaviorTracker.numRecords, traitsStr ); */
|
||||
|
||||
bbPrint( "mpbehaviortracker", "username %s version %d numRecords %d effectiveSlideCombat %f effectiveDoubleJumpCombat %f effectiveWallRunCombat %f effectiveCombat %f",
|
||||
self.name, self.behaviorTracker.version, self.behaviorTracker.numRecords, self.behaviorTracker.traits["effectiveSlideCombat"],
|
||||
self.behaviorTracker.traits["effectiveDoubleJumpCombat"], self.behaviorTracker.traits["effectiveWallRunCombat"], self.behaviorTracker.traits["effectiveCombat"] );
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
///// Set, Get & Update Trait ////
|
||||
/////////////////////////////////////////////////////
|
||||
function GetTraitValue( trait )
|
||||
{
|
||||
return self.behaviorTracker.traits[ trait ];
|
||||
}
|
||||
|
||||
function SetTraitValue( trait, value )
|
||||
{
|
||||
self.behaviorTracker.traits[trait] = value;
|
||||
}
|
||||
|
||||
function UpdateTrait( trait, percent )
|
||||
{
|
||||
if ( !( self IsAllowed() ) )
|
||||
return;
|
||||
|
||||
math::clamp( percent, -1.0, 1.0 );
|
||||
|
||||
currentValue = self GetTraitValue( trait );
|
||||
|
||||
if ( percent >= 0 )
|
||||
{
|
||||
delta = ( 1.0 - currentValue ) * percent;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = ( currentValue - 0.0 ) * percent;
|
||||
}
|
||||
|
||||
weightedDelta = 0.1 * delta;
|
||||
|
||||
newValue = currentvalue + weightedDelta;
|
||||
newValue = math::clamp( newValue, 0.0, 1.0 );
|
||||
self SetTraitValue( trait, newValue );
|
||||
|
||||
bbprint( "mpbehaviortraitupdate", "username %s trait %s percent %f", self.name, trait, percent );
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
///// Game Side Hooks ////
|
||||
/////////////////////////////////////////////////////
|
||||
function UpdatePlayerDamage( attacker, victim, damage )
|
||||
{
|
||||
if ( isDefined( victim ) && victim IsAllowed() )
|
||||
{
|
||||
damageRatio = float( damage ) / float( victim.maxhealth );
|
||||
math::clamp( damageRatio, 0.0, 1.0 );
|
||||
|
||||
damageRatio = damageRatio * -1.0; // Negative damage percent since this is the victim
|
||||
|
||||
victim UpdateTrait( "effectiveCombat", damageRatio );
|
||||
|
||||
if ( victim IsWallRunning() )
|
||||
{
|
||||
victim UpdateTrait( "effectiveWallRunCombat", damageRatio );
|
||||
}
|
||||
|
||||
if ( victim IsSliding() )
|
||||
{
|
||||
victim UpdateTrait( "effectiveSlideCombat", damageRatio );
|
||||
}
|
||||
|
||||
if ( victim IsDoubleJumping() )
|
||||
{
|
||||
victim UpdateTrait( "effectiveDoubleJumpCombat", damageRatio );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isDefined( attacker ) && ( attacker IsAllowed() ) && attacker != victim )
|
||||
{
|
||||
damageRatio = float( damage ) / float( attacker.maxhealth );
|
||||
math::clamp( damageRatio, 0.0, 1.0 );
|
||||
|
||||
attacker UpdateTrait( "effectiveCombat", damageRatio );
|
||||
|
||||
if ( attacker IsWallRunning() )
|
||||
{
|
||||
attacker UpdateTrait( "effectiveWallRunCombat", damageRatio );
|
||||
}
|
||||
|
||||
if ( attacker IsSliding() )
|
||||
{
|
||||
attacker UpdateTrait( "effectiveSlideCombat", damageRatio );
|
||||
}
|
||||
|
||||
if ( attacker IsDoubleJumping() )
|
||||
{
|
||||
attacker UpdateTrait( "effectiveDoubleJumpCombat", damageRatio );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function UpdatePlayerKilled( attacker, victim )
|
||||
{
|
||||
if ( isDefined( victim ) && victim IsAllowed() )
|
||||
{
|
||||
// Passing -1.0 since to denote negative 100%.
|
||||
victim UpdateTrait( "effectiveCombat", -1.0 );
|
||||
|
||||
if ( victim IsWallRunning() )
|
||||
{
|
||||
victim UpdateTrait( "effectiveWallRunCombat", -1.0 );
|
||||
}
|
||||
|
||||
if ( victim IsSliding() )
|
||||
{
|
||||
victim UpdateTrait( "effectiveSlideCombat", -1.0 );
|
||||
}
|
||||
|
||||
if ( victim IsDoubleJumping() )
|
||||
{
|
||||
victim UpdateTrait( "effectiveDoubleJumpCombat", -1.0 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isDefined( attacker ) && ( attacker IsAllowed() ) && attacker != victim )
|
||||
{
|
||||
// Passing 1.0 since to denote positive 100%.
|
||||
attacker UpdateTrait( "effectiveCombat", 1.0 );
|
||||
|
||||
if ( attacker IsWallRunning() )
|
||||
{
|
||||
attacker UpdateTrait( "effectiveWallRunCombat", 1.0 );
|
||||
}
|
||||
|
||||
if ( attacker IsSliding() )
|
||||
{
|
||||
attacker UpdateTrait( "effectiveSlideCombat", 1.0 );
|
||||
}
|
||||
|
||||
if ( attacker IsDoubleJumping() )
|
||||
{
|
||||
attacker UpdateTrait( "effectiveDoubleJumpCombat", 1.0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
///// Stats Related ////
|
||||
/////////////////////////////////////////////////////
|
||||
function SetTraitStats()
|
||||
{
|
||||
if ( self.behaviorTracker.version == 0 )
|
||||
return;
|
||||
|
||||
self.behaviorTracker.numRecords = self.behaviorTracker.numRecords + 1;
|
||||
self SetTraitStatValue( "numRecords", self.behaviorTracker.numRecords );
|
||||
|
||||
traits = getArrayKeys( self.behaviorTracker.traits );
|
||||
|
||||
for ( i = 0; i < traits.size; i++ )
|
||||
{
|
||||
trait = traits[i];
|
||||
value = self.behaviorTracker.traits[trait];
|
||||
|
||||
self SetTraitStatValue( trait, value );
|
||||
}
|
||||
}
|
||||
|
||||
function GetTraitStatValue( trait )
|
||||
{
|
||||
return self getDStat( "behaviorTracker", trait );
|
||||
}
|
||||
|
||||
function SetTraitStatValue( trait, value )
|
||||
{
|
||||
self setDStat( "behaviorTracker", trait, value );
|
||||
}
|
||||
@@ -0,0 +1,405 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\challenges_shared;
|
||||
#using scripts\shared\drown;
|
||||
#using scripts\shared\scoreevents_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_weapon_utils;
|
||||
|
||||
#using scripts\mp\_challenges;
|
||||
#using scripts\mp\gametypes\_loadout;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
|
||||
|
||||
|
||||
// for blackjack challenge: kills while using a specialist weapon or ability
|
||||
// for blackjack challenge: count of unique specialist weapons or abilities used to kill
|
||||
|
||||
#namespace blackjack_challenges;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("blackjack_challenges",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
callback::on_start_gametype( &start_gametype );
|
||||
}
|
||||
|
||||
function start_gametype()
|
||||
{
|
||||
if ( !isdefined( level.ChallengesCallbacks ) )
|
||||
{
|
||||
level.ChallengesCallbacks = [];
|
||||
}
|
||||
|
||||
waittillframeend;
|
||||
|
||||
if ( challenges::canProcessChallenges() )
|
||||
{
|
||||
challenges::registerChallengesCallback( "playerKilled",&challenge_kills );
|
||||
challenges::registerChallengesCallback( "roundEnd",&challenge_round_ended );
|
||||
challenges::registerChallengesCallback( "gameEnd",&challenge_game_ended );
|
||||
scoreevents::register_hero_ability_kill_event( &on_hero_ability_kill );
|
||||
}
|
||||
|
||||
callback::on_connect( &on_player_connect );
|
||||
}
|
||||
|
||||
function on_player_connect()
|
||||
{
|
||||
player = self;
|
||||
if ( challenges::canProcessChallenges() )
|
||||
{
|
||||
specialistIndex = player GetSpecialistIndex();
|
||||
isBlackjack = ( specialistIndex == 9 );
|
||||
if ( isBlackjack )
|
||||
{
|
||||
player thread track_blackjack_consumable();
|
||||
|
||||
if ( !isdefined( self.pers[ "blackjack_challenge_active" ] ) )
|
||||
{
|
||||
remaining_time = player ConsumableGet( "blackjack", "awarded" ) - player ConsumableGet( "blackjack", "consumed" );
|
||||
|
||||
if ( remaining_time > 0 )
|
||||
{
|
||||
special_card_earned = player get_challenge_stat( "special_card_earned" );
|
||||
if ( !special_card_earned )
|
||||
{
|
||||
player.pers[ "blackjack_challenge_active" ] = true;
|
||||
player.pers[ "blackjack_unique_specialist_kills" ] = 0;
|
||||
player.pers[ "blackjack_specialist_kills" ] = 0;
|
||||
player.pers[ "blackjack_unique_weapon_mask" ] = 0;
|
||||
player.pers[ "blackjack_unique_ability_mask" ] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function is_challenge_active()
|
||||
{
|
||||
return ( self.pers[ "blackjack_challenge_active" ] === true );
|
||||
}
|
||||
|
||||
function on_hero_ability_kill( ability, victimAbility )
|
||||
{
|
||||
player = self;
|
||||
|
||||
if ( !isdefined( player ) || !isplayer( player ) )
|
||||
return;
|
||||
|
||||
if ( !isdefined( player.isRoulette ) || !player.isRoulette )
|
||||
return;
|
||||
|
||||
if ( player is_challenge_active() )
|
||||
{
|
||||
player.pers[ "blackjack_specialist_kills" ]++;
|
||||
|
||||
currentHeroAbilityMask = player.pers[ "blackjack_unique_ability_mask" ];
|
||||
heroAbilityMask = get_hero_ability_mask( ability );
|
||||
newHeroAbilityMask = heroAbilityMask | currentHeroAbilityMask;
|
||||
if ( newHeroAbilityMask != currentHeroAbilityMask )
|
||||
{
|
||||
player.pers[ "blackjack_unique_specialist_kills" ]++;
|
||||
player.pers[ "blackjack_unique_ability_mask" ] = newHeroAbilityMask;
|
||||
}
|
||||
|
||||
player check_blackjack_challenge();
|
||||
}
|
||||
}
|
||||
|
||||
/#
|
||||
function debug_print_already_earned()
|
||||
{
|
||||
if ( GetDvarInt( "scr_blackjack_sidebet_debug", 0 ) == 0 )
|
||||
return;
|
||||
|
||||
IPrintLn( "Blackjack Side Bet already earned this game." );
|
||||
}
|
||||
#/
|
||||
|
||||
/#
|
||||
function debug_print_kill_info()
|
||||
{
|
||||
if ( GetDvarInt( "scr_blackjack_sidebet_debug", 0 ) == 0 )
|
||||
return;
|
||||
|
||||
player = self;
|
||||
IPrintLn( "Blackjack Side Bet kills: " + player.pers[ "blackjack_specialist_kills" ] + " uniques: " + player.pers[ "blackjack_unique_specialist_kills" ] );
|
||||
}
|
||||
#/
|
||||
|
||||
/#
|
||||
function debug_print_earned()
|
||||
{
|
||||
if ( GetDvarInt( "scr_blackjack_sidebet_debug", 0 ) == 0 )
|
||||
return;
|
||||
|
||||
IPrintLn( "Blackjack Side Bet earned!!!" );
|
||||
}
|
||||
#/
|
||||
|
||||
function check_blackjack_challenge()
|
||||
{
|
||||
player = self;
|
||||
|
||||
/# debug_print_kill_info(); #/
|
||||
|
||||
special_card_earned = player get_challenge_stat( "special_card_earned" );
|
||||
if ( special_card_earned )
|
||||
{
|
||||
/# debug_print_already_earned(); #/
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ( player.pers[ "blackjack_specialist_kills" ] >= 4 ) &&
|
||||
( player.pers[ "blackjack_unique_specialist_kills" ] >= 2 ) )
|
||||
{
|
||||
player set_challenge_stat( "special_card_earned", 1 );
|
||||
player AddPlayerStat( "blackjack_challenge", 1 );
|
||||
|
||||
/# debug_print_earned(); #/
|
||||
}
|
||||
}
|
||||
|
||||
function challenge_kills( data )
|
||||
{
|
||||
attackerisThief = data.attackerIsThief;
|
||||
attackerIsRoulette = data.attackerIsRoulette;
|
||||
attackerIsThiefOrRoulette = attackerisThief || attackerIsRoulette;
|
||||
|
||||
if ( !attackerIsThiefOrRoulette )
|
||||
return;
|
||||
|
||||
victim = data.victim;
|
||||
attacker = data.attacker;
|
||||
player = attacker;
|
||||
weapon = data.weapon;
|
||||
|
||||
if ( !isdefined( weapon ) || ( weapon == level.weaponNone ) )
|
||||
return;
|
||||
|
||||
if ( !isdefined( player ) || !isplayer( player ) )
|
||||
return;
|
||||
|
||||
if ( attackerIsThief )
|
||||
{
|
||||
if ( weapon.isHeroWeapon === true )
|
||||
{
|
||||
if ( player is_challenge_active() )
|
||||
{
|
||||
player.pers[ "blackjack_specialist_kills" ]++;
|
||||
|
||||
currentHeroWeaponMask = player.pers[ "blackjack_unique_weapon_mask" ];
|
||||
heroWeaponMask = get_hero_weapon_mask( attacker, weapon );
|
||||
newHeroWeaponMask = heroWeaponMask | currentHeroWeaponMask;
|
||||
if ( newHeroWeaponMask != currentHeroWeaponMask )
|
||||
{
|
||||
player.pers[ "blackjack_unique_specialist_kills" ] += 1;
|
||||
player.pers[ "blackjack_unique_weapon_mask" ] = newHeroWeaponMask;
|
||||
}
|
||||
|
||||
player check_blackjack_challenge();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ability kills are handled as events fired from score events
|
||||
// if ( attackerIsRoulette )
|
||||
// {
|
||||
// }
|
||||
}
|
||||
|
||||
function get_challenge_stat( stat_name )
|
||||
{
|
||||
return self GetDStat( "tenthspecialistcontract", stat_name );
|
||||
}
|
||||
|
||||
function set_challenge_stat( stat_name, stat_value )
|
||||
{
|
||||
return self SetDStat( "tenthspecialistcontract", stat_name, stat_value );
|
||||
}
|
||||
|
||||
function get_hero_weapon_mask( attacker, weapon )
|
||||
{
|
||||
if ( !isdefined( weapon ) )
|
||||
return 0;
|
||||
|
||||
if ( isdefined( weapon.isHeroWeapon ) && !weapon.isHeroWeapon )
|
||||
return 0;
|
||||
|
||||
switch( weapon.name )
|
||||
{
|
||||
case "hero_minigun":
|
||||
case "hero_minigun_body3":
|
||||
return 1; // note: heroWeaponMask needs to stay unique and consistent for function across TUs and FFOTDs
|
||||
break;
|
||||
case "hero_flamethrower":
|
||||
return 1 << 1;
|
||||
break;
|
||||
case "hero_lightninggun":
|
||||
case "hero_lightninggun_arc":
|
||||
return 1 << 2;
|
||||
break;
|
||||
case "hero_chemicalgelgun":
|
||||
case "hero_firefly_swarm":
|
||||
return 1 << 3;
|
||||
break;
|
||||
case "hero_pineapplegun":
|
||||
case "hero_pineapple_grenade":
|
||||
return 1 << 4;
|
||||
break;
|
||||
case "hero_armblade":
|
||||
return 1 << 5;
|
||||
break;
|
||||
case "hero_bowlauncher":
|
||||
case "hero_bowlauncher2":
|
||||
case "hero_bowlauncher3":
|
||||
case "hero_bowlauncher4":
|
||||
return 1 << 6;
|
||||
break;
|
||||
case "hero_gravityspikes":
|
||||
return 1 << 7;
|
||||
break;
|
||||
case "hero_annihilator":
|
||||
return 1 << 8;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function get_hero_ability_mask( ability )
|
||||
{
|
||||
if ( !isdefined( ability ) )
|
||||
return 0;
|
||||
|
||||
switch( ability.name )
|
||||
{
|
||||
case "gadget_clone":
|
||||
return 1; // note: heroAbilityMask needs to stay unique and consistent for functions across TUs and FFOTDs
|
||||
break;
|
||||
case "gadget_heat_wave":
|
||||
return 1 << 1;
|
||||
break;
|
||||
case "gadget_flashback":
|
||||
return 1 << 2;
|
||||
break;
|
||||
case "gadget_resurrect":
|
||||
return 1 << 3;
|
||||
break;
|
||||
case "gadget_armor":
|
||||
return 1 << 4;
|
||||
break;
|
||||
case "gadget_camo":
|
||||
return 1 << 5;
|
||||
break;
|
||||
case "gadget_vision_pulse":
|
||||
return 1 << 6;
|
||||
break;
|
||||
case "gadget_speed_burst":
|
||||
return 1 << 7;
|
||||
break;
|
||||
case "gadget_combat_efficiency":
|
||||
return 1 << 8;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function challenge_game_ended( data )
|
||||
{
|
||||
if ( !isdefined( data ) )
|
||||
return;
|
||||
|
||||
player = data.player;
|
||||
if ( !isdefined( player ) )
|
||||
return;
|
||||
|
||||
if ( !isPlayer( player ) )
|
||||
return;
|
||||
|
||||
if ( player util::is_bot() )
|
||||
return;
|
||||
|
||||
if ( !player is_challenge_active() )
|
||||
return;
|
||||
|
||||
player report_consumable();
|
||||
}
|
||||
|
||||
function challenge_round_ended( data )
|
||||
{
|
||||
if ( !isdefined( data ) )
|
||||
return;
|
||||
|
||||
player = data.player;
|
||||
if ( !isdefined( player ) )
|
||||
return;
|
||||
|
||||
if ( !isPlayer( player ) )
|
||||
return;
|
||||
|
||||
if ( player util::is_bot() )
|
||||
return;
|
||||
|
||||
if ( !player is_challenge_active() )
|
||||
return;
|
||||
|
||||
player report_consumable();
|
||||
}
|
||||
|
||||
function track_blackjack_consumable()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
self notify( "track_blackjack_consumable_singleton" );
|
||||
self endon( "track_blackjack_consumable_singleton" );
|
||||
self endon( "disconnect" );
|
||||
|
||||
player = self;
|
||||
|
||||
if ( !isdefined( player.last_blackjack_consumable_time ) )
|
||||
player.last_blackjack_consumable_time = 0;
|
||||
|
||||
while ( isdefined( player ) )
|
||||
{
|
||||
random_wait_time = GetDvarFloat( "mp_blackjack_consumable_wait", 20.0 ) + RandomFloatRange( -5.0, 5.0 );
|
||||
wait random_wait_time;
|
||||
|
||||
player report_consumable();
|
||||
}
|
||||
}
|
||||
|
||||
function report_consumable()
|
||||
{
|
||||
player = self;
|
||||
|
||||
if ( !isdefined( player ) )
|
||||
return;
|
||||
|
||||
if ( !isdefined( player.timePlayed ) || !isdefined( player.timePlayed["total"] ) )
|
||||
return;
|
||||
|
||||
current_time_played = player.timePlayed["total"];
|
||||
|
||||
time_to_report = current_time_played - player.last_blackjack_consumable_time;
|
||||
|
||||
if ( time_to_report > 0 )
|
||||
{
|
||||
max_time_to_report = player ConsumableGet( "blackjack", "awarded" ) - player ConsumableGet( "blackjack", "consumed" );
|
||||
consumable_increment = int( min( time_to_report, max_time_to_report ) );
|
||||
if ( consumable_increment > 0 )
|
||||
{
|
||||
player ConsumableIncrement( "blackjack", "consumed", consumable_increment ); // so we don't go over awarded time
|
||||
}
|
||||
}
|
||||
|
||||
player.last_blackjack_consumable_time = current_time_played;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
// bonusCards_t
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_bouncingbetty;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace bouncingbetty;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("bouncingbetty",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__( localClientNum )
|
||||
{
|
||||
bouncingbetty::init_shared();
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_bouncingbetty;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace bouncingbetty;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("bouncingbetty",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
bouncingbetty::init_shared();
|
||||
|
||||
level.trackBouncingBettiesOnOwner = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,301 @@
|
||||
#using scripts\shared\audio_shared;
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\exploder_shared;
|
||||
#using scripts\shared\filter_shared;
|
||||
#using scripts\shared\footsteps_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\vehicle_shared;
|
||||
#using scripts\shared\vehicles\_driving_fx;
|
||||
#using scripts\shared\abilities\gadgets\_gadget_vision_pulse;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\shared\weapons\_sticky_grenade;
|
||||
|
||||
#using scripts\mp\killstreaks\_ai_tank;
|
||||
#using scripts\mp\killstreaks\_airsupport;
|
||||
#using scripts\mp\killstreaks\_helicopter;
|
||||
#using scripts\mp\killstreaks\_qrdrone;
|
||||
#using scripts\mp\killstreaks\_rcbomb;
|
||||
#using scripts\shared\_burnplayer;
|
||||
#using scripts\mp\_callbacks;
|
||||
#using scripts\mp\_util;
|
||||
#using scripts\mp\_vehicle;
|
||||
|
||||
#using scripts\mp\gametypes\_globallogic;
|
||||
#using scripts\mp\gametypes\_globallogic_actor;
|
||||
|
||||
#namespace callback;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("callback",&__init__,undefined,undefined); }
|
||||
|
||||
// Callback set up, clientside.
|
||||
function __init__()
|
||||
{
|
||||
level thread set_default_callbacks();
|
||||
}
|
||||
|
||||
function set_default_callbacks()
|
||||
{
|
||||
level.callbackPlayerSpawned = &playerspawned;
|
||||
level.callbackLocalClientConnect = &localclientconnect;
|
||||
level.callbackCreatingCorpse = &creating_corpse;
|
||||
level.callbackEntitySpawned = &entityspawned;
|
||||
level.callbackAirSupport = &airsupport;
|
||||
//level.callbackDogSoundNotify = &dogs::play_dog_sound;
|
||||
level.callbackPlayAIFootstep = &footsteps::playaifootstep;
|
||||
level.callbackPlayLightLoopExploder = &exploder::playlightloopexploder;
|
||||
|
||||
level._custom_weapon_CB_Func = &callback::spawned_weapon_type;
|
||||
|
||||
level.gadgetVisionPulse_reveal_func = &gadget_vision_pulse::gadget_visionpulse_reveal;
|
||||
}
|
||||
|
||||
function localclientconnect( localClientNum )
|
||||
{
|
||||
/# println( "*** Client script VM : Local client connect " + localClientNum ); #/
|
||||
|
||||
if ( isdefined( level.characterCustomizationSetup ) )
|
||||
{
|
||||
[[ level.characterCustomizationSetup ]]( localclientnum );
|
||||
}
|
||||
|
||||
callback::callback( #"on_localclient_connect", localClientNum );
|
||||
}
|
||||
|
||||
function playerspawned(localClientNum)
|
||||
{
|
||||
self endon( "entityshutdown" );
|
||||
self notify( "playerspawned_callback" );
|
||||
self endon( "playerspawned_callback" );
|
||||
|
||||
player = GetLocalPlayer(localClientNum);
|
||||
|
||||
if ( isdefined( level.infraredVisionset ) )
|
||||
{
|
||||
player SetInfraredVisionset( level.infraredVisionset );
|
||||
}
|
||||
|
||||
if ( isdefined( level._playerspawned_override ) )
|
||||
{
|
||||
self thread [[level._playerspawned_override]]( localClientNum );
|
||||
return;
|
||||
}
|
||||
|
||||
/# PrintLn( "Player spawned" ); #/
|
||||
if ( self isLocalPlayer() )
|
||||
callback::callback( #"on_localplayer_spawned", localClientNum );
|
||||
|
||||
callback::callback( #"on_player_spawned", localClientNum );
|
||||
}
|
||||
|
||||
function entityspawned(localClientNum)
|
||||
{
|
||||
self endon( "entityshutdown" );
|
||||
|
||||
if( self IsPlayer() )
|
||||
{
|
||||
if( isdefined( level._clientFaceAnimOnPlayerSpawned ) )
|
||||
{
|
||||
self thread [[level._clientFaceAnimOnPlayerSpawned]](localClientNum);
|
||||
}
|
||||
}
|
||||
|
||||
if ( isdefined( level._entityspawned_override ) )
|
||||
{
|
||||
self thread [[level._entityspawned_override]]( localClientNum );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !isdefined( self.type ) )
|
||||
{
|
||||
/# println( "Entity type undefined!" ); #/
|
||||
return;
|
||||
}
|
||||
|
||||
if ( self.type == "missile" )
|
||||
{
|
||||
if( isdefined( level._custom_weapon_CB_Func ) )
|
||||
{
|
||||
self thread [[level._custom_weapon_CB_Func]]( localClientNum );
|
||||
}
|
||||
}
|
||||
else if ( self.type == "vehicle" || self.type == "helicopter" || self.type == "plane" )
|
||||
{
|
||||
if( isdefined(level._customVehicleCBFunc) )
|
||||
{
|
||||
self thread [[level._customVehicleCBFunc]](localClientNum);
|
||||
}
|
||||
|
||||
self thread vehicle::field_toggle_exhaustfx_handler( localClientNum, undefined, false, true );
|
||||
self thread vehicle::field_toggle_lights_handler( localClientNum, undefined, false, true );
|
||||
|
||||
if ( self.type == "plane" || self.type == "helicopter" )
|
||||
{
|
||||
self thread vehicle::aircraft_dustkick();
|
||||
}
|
||||
else
|
||||
{
|
||||
self thread driving_fx::play_driving_fx(localClientNum);
|
||||
self thread vehicle::vehicle_rumble(localClientNum);
|
||||
}
|
||||
|
||||
if( self.type == "helicopter" )
|
||||
{
|
||||
self thread helicopter::startfx_loop( localClientNum );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( self.type == "actor" )
|
||||
{
|
||||
if( isdefined(level._customActorCBFunc) )
|
||||
{
|
||||
self thread [[level._customActorCBFunc]](localClientNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function airsupport( localClientNum, x, y, z, type, yaw, team, teamfaction, owner, exittype, time, height )
|
||||
{
|
||||
pos = ( x, y, z );
|
||||
switch( teamFaction )
|
||||
{
|
||||
case "v":
|
||||
teamfaction = "vietcong";
|
||||
break;
|
||||
case "n":
|
||||
case "nva":
|
||||
teamfaction = "nva";
|
||||
break;
|
||||
case "j":
|
||||
teamfaction = "japanese";
|
||||
break;
|
||||
case "m":
|
||||
teamfaction = "marines";
|
||||
break;
|
||||
case "s":
|
||||
teamfaction = "specops";
|
||||
break;
|
||||
case "r":
|
||||
teamfaction = "russian";
|
||||
break;
|
||||
default:
|
||||
/# println( "Warning: Invalid team char provided, defaulted to marines" ); #/
|
||||
/# println( "Teamfaction received: " + teamFaction + "\n" ); #/
|
||||
teamfaction = "marines";
|
||||
break;
|
||||
}
|
||||
|
||||
switch( team )
|
||||
{
|
||||
case "x":
|
||||
team = "axis";
|
||||
break;
|
||||
case "l":
|
||||
team = "allies";
|
||||
break;
|
||||
case "r":
|
||||
team = "free";
|
||||
break;
|
||||
default:
|
||||
/# println( "Invalid team used with playclientAirstike/napalm: " + team + "\n"); #/
|
||||
team = "allies";
|
||||
break;
|
||||
}
|
||||
|
||||
data = spawnstruct();
|
||||
|
||||
data.team = team;
|
||||
data.owner = owner;
|
||||
data.bombsite = pos;
|
||||
data.yaw = yaw;
|
||||
direction = ( 0, yaw, 0 );
|
||||
data.direction = direction;
|
||||
data.flyHeight = height;
|
||||
|
||||
if ( type == "a" )
|
||||
{
|
||||
planeHalfDistance = 12000;
|
||||
data.planeHalfDistance = planeHalfDistance;
|
||||
data.startPoint = pos + VectorScale( anglestoforward( direction ), -1 * planeHalfDistance );
|
||||
data.endPoint = pos + VectorScale( anglestoforward( direction ), planeHalfDistance );
|
||||
data.planeModel = "t5_veh_air_b52";
|
||||
data.flyBySound = "null";
|
||||
data.washSound = "veh_b52_flyby_wash";
|
||||
data.apexTime = 6145;
|
||||
data.exitType = -1;
|
||||
data.flySpeed = 2000;
|
||||
data.flyTime = ( ( planeHalfDistance * 2 ) / data.flySpeed );
|
||||
planeType = "airstrike";
|
||||
//_airstrike::addPlaneEvent( localClientNum, planeType, data, time );
|
||||
}
|
||||
else if ( type == "n" )
|
||||
{
|
||||
planeHalfDistance = 24000;
|
||||
data.planeHalfDistance = planeHalfDistance;
|
||||
data.startPoint = pos + VectorScale( anglestoforward( direction ), -1 * planeHalfDistance );
|
||||
data.endPoint = pos + VectorScale( anglestoforward( direction ), planeHalfDistance );
|
||||
data.planeModel = airsupport::getPlaneModel( teamFaction );
|
||||
data.flyBySound = "null";
|
||||
data.washSound = "evt_us_napalm_wash";
|
||||
data.apexTime = 2362;
|
||||
data.exitType = exitType;
|
||||
data.flySpeed = 7000;
|
||||
data.flyTime = ( ( planeHalfDistance * 2 ) / data.flySpeed );
|
||||
planeType = "napalm";
|
||||
//_plane::addPlaneEvent( localClientNum, planeType, data, time );
|
||||
}
|
||||
else
|
||||
{
|
||||
/#
|
||||
println( "" );
|
||||
println( "Unhandled airsupport type, only A (airstrike) and N (napalm) supported" );
|
||||
println( type );
|
||||
println( "" );
|
||||
#/
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function creating_corpse(localClientNum, player )
|
||||
{
|
||||
}
|
||||
|
||||
function callback_stunned( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
||||
{
|
||||
self.stunned = newVal;
|
||||
|
||||
/# PrintLn("stunned_callback"); #/
|
||||
|
||||
if ( newVal )
|
||||
{
|
||||
self notify("stunned");
|
||||
}
|
||||
else
|
||||
{
|
||||
self notify("not_stunned");
|
||||
}
|
||||
}
|
||||
|
||||
function callback_emp( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
||||
{
|
||||
self.emp = newVal;
|
||||
|
||||
/# PrintLn("emp_callback"); #/
|
||||
|
||||
if ( newVal )
|
||||
{
|
||||
self notify("emp");
|
||||
}
|
||||
else
|
||||
{
|
||||
self notify("not_emp");
|
||||
}
|
||||
}
|
||||
|
||||
function callback_proximity( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
||||
{
|
||||
self.enemyInProximity = newVal;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
#using scripts\codescripts\struct;
|
||||
#using scripts\shared\ai\systems\blackboard;
|
||||
#using scripts\shared\audio_shared;
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\gametypes\_globallogic;
|
||||
#using scripts\mp\gametypes\_globallogic_actor;
|
||||
#using scripts\mp\gametypes\_globallogic_player;
|
||||
#using scripts\mp\gametypes\_globallogic_vehicle;
|
||||
#using scripts\mp\gametypes\_hostmigration;
|
||||
#using scripts\shared\bots\bot_traversals;
|
||||
|
||||
#namespace callback;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("callback",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
set_default_callbacks();
|
||||
}
|
||||
|
||||
// Callback Setup
|
||||
// This script provides the hooks from code into script for the gametype callback functions.
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*================
|
||||
Setup any misc callbacks stuff like defines and default callbacks
|
||||
================*/
|
||||
|
||||
/*================
|
||||
Called from the gametype script to store off the default callback functions.
|
||||
This allows the callbacks to be overridden by level script, but not lost.
|
||||
================*/
|
||||
function set_default_callbacks()
|
||||
{
|
||||
level.callbackStartGameType = &globallogic::Callback_StartGameType;
|
||||
level.callbackPlayerConnect = &globallogic_player::Callback_PlayerConnect;
|
||||
level.callbackPlayerDisconnect = &globallogic_player::Callback_PlayerDisconnect;
|
||||
level.callbackPlayerDamage = &globallogic_player::Callback_PlayerDamage;
|
||||
level.callbackPlayerKilled = &globallogic_player::Callback_PlayerKilled;
|
||||
level.callbackPlayerMelee = &globallogic_player::Callback_PlayerMelee;
|
||||
level.callbackPlayerLastStand = &globallogic_player::Callback_PlayerLastStand;
|
||||
level.callbackActorSpawned = &globallogic_actor::Callback_ActorSpawned;
|
||||
level.callbackActorDamage = &globallogic_actor::Callback_ActorDamage;
|
||||
level.callbackActorKilled = &globallogic_actor::Callback_ActorKilled;
|
||||
level.callbackActorCloned = &globallogic_actor::Callback_ActorCloned;
|
||||
level.callbackVehicleSpawned = &globallogic_vehicle::Callback_VehicleSpawned;
|
||||
level.callbackVehicleDamage = &globallogic_vehicle::Callback_VehicleDamage;
|
||||
level.callbackVehicleKilled = &globallogic_vehicle::Callback_VehicleKilled;
|
||||
level.callbackVehicleRadiusDamage = &globallogic_vehicle::Callback_VehicleRadiusDamage;
|
||||
level.callbackPlayerMigrated = &globallogic_player::Callback_PlayerMigrated;
|
||||
level.callbackHostMigration = &hostmigration::Callback_HostMigration;
|
||||
level.callbackHostMigrationSave = &hostmigration::Callback_HostMigrationSave;
|
||||
level.callbackPreHostMigrationSave = &hostmigration::Callback_PreHostMigrationSave;
|
||||
level.callbackBotEnteredUserEdge = &bot::Callback_BotEnteredUserEdge;
|
||||
|
||||
level._custom_weapon_damage_func = &callback::callback_weapon_damage;
|
||||
|
||||
level._gametype_default = "tdm";
|
||||
}
|
||||
+1952
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,45 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#precache( "client_fx", "_t6/weapon/claymore/fx_claymore_laser" );
|
||||
|
||||
#namespace claymore;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("claymore",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__( localClientNum )
|
||||
{
|
||||
level._effect["fx_claymore_laser"] = "_t6/weapon/claymore/fx_claymore_laser";
|
||||
|
||||
callback::add_weapon_type( "claymore", &spawned );
|
||||
}
|
||||
|
||||
function spawned( localClientNum )
|
||||
{
|
||||
self endon( "entityshutdown" );
|
||||
|
||||
self util::waittill_dobj(localClientNum);
|
||||
|
||||
while( true )
|
||||
{
|
||||
if( isdefined( self.stunned ) && self.stunned )
|
||||
{
|
||||
wait( 0.1 );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
self.claymoreLaserFXId = PlayFXOnTag( localClientNum, level._effect["fx_claymore_laser"], self, "tag_fx" );
|
||||
|
||||
self waittill( "stunned" );
|
||||
stopfx(localClientNum, self.claymoreLaserFXId);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,991 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\challenges_shared;
|
||||
#using scripts\shared\drown;
|
||||
#using scripts\shared\scoreevents_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_weapon_utils;
|
||||
|
||||
#using scripts\mp\_util;
|
||||
#using scripts\mp\_challenges;
|
||||
#using scripts\mp\gametypes\_globallogic;
|
||||
#using scripts\mp\gametypes\_globallogic_score;
|
||||
#using scripts\mp\gametypes\_loadout;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
|
||||
|
||||
|
||||
// look for dvar loot_cryptokeyCost
|
||||
// look for dvar loot_cryptokeyCost
|
||||
|
||||
|
||||
|
||||
|
||||
// should coincide with contracts array size on mp_stats.ddl
|
||||
|
||||
|
||||
|
||||
// contract string table and columns
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// mp_stats.ddl, PlayerStatsList[ <stat_name> ]
|
||||
// mp_stats.ddl, PlayerStatsList[ <stat_name> ]
|
||||
// mp_stats.ddl
|
||||
|
||||
// table index values from mp_contractTable.csv
|
||||
|
||||
// weekly contracts
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// daily contracts
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// special contracts
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#namespace contracts;
|
||||
|
||||
#precache( "eventstring", "mp_daily_challenge_complete" );
|
||||
#precache( "eventstring", "mp_weekly_challenge_complete" );
|
||||
#precache( "eventstring", "mp_special_contract_complete" );
|
||||
|
||||
function autoexec __init__sytem__() { system::register("contracts",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
callback::on_start_gametype( &start_gametype );
|
||||
|
||||
/# level thread watch_contract_debug(); #/
|
||||
}
|
||||
|
||||
function start_gametype()
|
||||
{
|
||||
if ( !isdefined( level.ChallengesCallbacks ) )
|
||||
{
|
||||
level.ChallengesCallbacks = [];
|
||||
}
|
||||
|
||||
util::init_player_contract_events(); // must always initialize
|
||||
|
||||
waittillframeend;
|
||||
|
||||
if ( can_process_contracts() )
|
||||
{
|
||||
/# execdevgui( "devgui/mp/mp_devgui_contracts" ); #/
|
||||
|
||||
challenges::registerChallengesCallback( "playerKilled",&contract_kills );
|
||||
challenges::registerChallengesCallback( "gameEnd",&contract_game_ended );
|
||||
globallogic_score::registerContractWinEvent( &contract_win );
|
||||
scoreevents::register_hero_ability_kill_event( &on_hero_ability_kill );
|
||||
scoreevents::register_hero_ability_multikill_event( &on_hero_ability_multikill );
|
||||
scoreevents::register_hero_weapon_multikill_event( &on_hero_weapon_multikill );
|
||||
|
||||
util::register_player_contract_event( "score", &on_player_score, 1 );
|
||||
util::register_player_contract_event( "killstreak_score", &on_killstreak_score, 2 );
|
||||
util::register_player_contract_event( "offender_kill", &on_offender_kill );
|
||||
util::register_player_contract_event( "defender_kill", &on_defender_kill );
|
||||
util::register_player_contract_event( "headshot", &on_headshot_kill );
|
||||
util::register_player_contract_event( "killed_hero_ability_enemy", &on_killed_hero_ability_enemy );
|
||||
util::register_player_contract_event( "killed_hero_weapon_enemy", &on_killed_hero_weapon_enemy );
|
||||
util::register_player_contract_event( "earned_specialist_ability_medal", &on_hero_ability_medal );
|
||||
|
||||
// globallogic::registerOtherLootXPAwards( &award_loot_xp ); // intentionally commented out, will use mp_loot_xp_due instead for now
|
||||
}
|
||||
|
||||
callback::on_connect( &on_player_connect );
|
||||
}
|
||||
|
||||
function on_killed_hero_ability_enemy()
|
||||
{
|
||||
self add_stat( 1014 );
|
||||
}
|
||||
|
||||
function on_killed_hero_weapon_enemy()
|
||||
{
|
||||
self add_stat( 1014 );
|
||||
}
|
||||
|
||||
function on_player_connect()
|
||||
{
|
||||
player = self;
|
||||
|
||||
if ( can_process_contracts() )
|
||||
{
|
||||
player setup_player_contracts();
|
||||
}
|
||||
}
|
||||
|
||||
function can_process_contracts()
|
||||
{
|
||||
if ( GetDvarInt( "contracts_enabled_mp", 1 ) == 0 ) // mp contracts kill switch
|
||||
return false;
|
||||
|
||||
return challenges::canProcessChallenges();
|
||||
}
|
||||
|
||||
function setup_player_contracts()
|
||||
{
|
||||
player = self;
|
||||
|
||||
player.pers["contracts"] = [];
|
||||
|
||||
// no need to setup active contracts for bots
|
||||
if ( player util::is_bot() )
|
||||
return;
|
||||
|
||||
for( slot = 0; slot < 10; slot++ )
|
||||
{
|
||||
if ( get_contract_stat( slot, "active" ) && !get_contract_stat( slot, "award_given" ) )
|
||||
{
|
||||
contract_index = get_contract_stat( slot, "index" );
|
||||
player.pers["contracts"][contract_index] = SpawnStruct();
|
||||
player.pers["contracts"][contract_index].slot = slot;
|
||||
table_row = TableLookupRowNum( "gamedata/tables/mp/mp_contractTable.csv", 0, contract_index );
|
||||
player.pers["contracts"][contract_index].table_row = table_row;
|
||||
player.pers["contracts"][contract_index].target_value = int( TableLookupColumnForRow( "gamedata/tables/mp/mp_contractTable.csv", table_row, 2 ) );
|
||||
player.pers["contracts"][contract_index].calling_card_stat = TableLookupColumnForRow( "gamedata/tables/mp/mp_contractTable.csv", table_row, 7 );
|
||||
player.pers["contracts"][contract_index].weapon_camo_stat = TableLookupColumnForRow( "gamedata/tables/mp/mp_contractTable.csv", table_row, 8 );
|
||||
player.pers["contracts"][contract_index].absolute_stat_path = TableLookupColumnForRow( "gamedata/tables/mp/mp_contractTable.csv", table_row, 9 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/#
|
||||
function watch_contract_debug()
|
||||
{
|
||||
level notify( "watch_contract_debug_singleton" );
|
||||
level endon( "watch_contract_debug_singleton" );
|
||||
|
||||
level endon( "game_ended" );
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
if ( GetDvarInt( "scr_contract_deactivate_all_slots" ) > 0 )
|
||||
{
|
||||
if ( isdefined( level.players ) )
|
||||
{
|
||||
new_index = GetDvarInt( "scr_contract_new_test_index", 0 );
|
||||
|
||||
foreach( player in level.players )
|
||||
{
|
||||
if ( !isdefined( player ) )
|
||||
continue;
|
||||
|
||||
if ( player util::is_bot() )
|
||||
continue;
|
||||
|
||||
for ( slot = 0; slot < 10; slot++ )
|
||||
{
|
||||
player set_contract_stat( slot, "active", 0 );
|
||||
}
|
||||
|
||||
IPrintLn( "All contract slots deactivated for " + player.name );
|
||||
|
||||
player setup_player_contracts();
|
||||
}
|
||||
}
|
||||
|
||||
SetDvar( "scr_contract_deactivate_all_slots", 0 );
|
||||
}
|
||||
|
||||
if ( GetDvarInt( "scr_contract_new_test_index", 0 ) > 0 )
|
||||
{
|
||||
if ( isdefined( level.players ) )
|
||||
{
|
||||
new_index = GetDvarInt( "scr_contract_new_test_index", 0 );
|
||||
|
||||
foreach( player in level.players )
|
||||
{
|
||||
if ( !isdefined( player ) )
|
||||
continue;
|
||||
|
||||
if ( player util::is_bot() )
|
||||
continue;
|
||||
|
||||
test_slot = GetDvarInt( "scr_contract_debug_slot", 10 - 1 );
|
||||
|
||||
player set_contract_stat( test_slot, "active", 1 );
|
||||
player set_contract_stat( test_slot, "index", new_index );
|
||||
player set_contract_stat( test_slot, "progress", 0 );
|
||||
player set_contract_stat( test_slot, "award_given", 0 );
|
||||
player setup_player_contracts();
|
||||
|
||||
IPrintLn( "Contract Slot " + test_slot + " table index set to " + new_index + " for " + player.name + ". Progress reset." );
|
||||
}
|
||||
}
|
||||
|
||||
SetDvar( "scr_contract_new_test_index", 0 );
|
||||
}
|
||||
|
||||
if ( GetDvarInt( "scr_contract_deactivate_debug_slot", 0 ) > 0 )
|
||||
{
|
||||
if ( isdefined( level.players ) )
|
||||
{
|
||||
test_slot = GetDvarInt( "scr_contract_debug_slot", 10 - 1 );
|
||||
IPrintLn( "Contract Debug Off" );
|
||||
|
||||
foreach( player in level.players )
|
||||
{
|
||||
if ( !isdefined( player ) )
|
||||
continue;
|
||||
|
||||
if ( player util::is_bot() )
|
||||
continue;
|
||||
|
||||
if ( test_slot >= 3 )
|
||||
{
|
||||
player set_contract_stat( test_slot, "active", 0 );
|
||||
player setup_player_contracts();
|
||||
|
||||
IPrintLn( "Contract Slot " + test_slot + " deactivated for " + player.name );
|
||||
}
|
||||
else
|
||||
{
|
||||
IPrintLn( "Contract Slot " + test_slot + " left active for " + player.name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetDvar( "scr_contract_deactivate_debug_slot", 0 );
|
||||
}
|
||||
|
||||
if ( GetDvarInt( "scr_contract_msg_front_end_only", 0 ) > 0 )
|
||||
{
|
||||
IPrintLn( "Assign Slot menu(s) only available in FrontEnd." );
|
||||
SetDvar( "scr_contract_msg_front_end_only", 0 );
|
||||
}
|
||||
|
||||
if ( GetDvarInt( "scr_contract_msg_debug_on", 0 ) > 0 )
|
||||
{
|
||||
IPrintLn( "Contracts Debug On. No slots altered." );
|
||||
SetDvar( "scr_contract_msg_debug_on", 0 );
|
||||
}
|
||||
|
||||
wait 0.5;
|
||||
}
|
||||
}
|
||||
#/
|
||||
|
||||
function is_contract_active( challenge_index )
|
||||
{
|
||||
if ( !isPlayer( self ) )
|
||||
return false;
|
||||
|
||||
if ( !isdefined( self.pers["contracts"] ) )
|
||||
return false;
|
||||
|
||||
if ( !isdefined( self.pers["contracts"][challenge_index] ) )
|
||||
return false;
|
||||
|
||||
// sanity check... better than causing an SRE
|
||||
if ( self.pers["contracts"][challenge_index].table_row == -1 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function on_hero_ability_kill( ability, victimAbility )
|
||||
{
|
||||
player = self;
|
||||
|
||||
if ( !isdefined( player ) || !isplayer( player ) )
|
||||
return;
|
||||
}
|
||||
|
||||
function on_hero_ability_medal()
|
||||
{
|
||||
player = self;
|
||||
|
||||
if ( !isdefined( player ) || !isplayer( player ) )
|
||||
return;
|
||||
|
||||
player add_stat( 1013 );
|
||||
player add_stat( 3 );
|
||||
}
|
||||
|
||||
function on_hero_ability_multikill( killcount, ability )
|
||||
{
|
||||
player = self;
|
||||
|
||||
if ( !isdefined( player ) || !isplayer( player ) )
|
||||
return;
|
||||
}
|
||||
|
||||
function on_hero_weapon_multikill( killcount, weapon )
|
||||
{
|
||||
player = self;
|
||||
|
||||
if ( !isdefined( player ) || !isplayer( player ) )
|
||||
return;
|
||||
}
|
||||
|
||||
function on_player_score( delta_score )
|
||||
{
|
||||
self add_stat( 1009, delta_score );
|
||||
self add_stat( 5, delta_score );
|
||||
}
|
||||
|
||||
function on_killstreak_score( delta_score, killstreak_purchased )
|
||||
{
|
||||
if ( killstreak_purchased )
|
||||
{
|
||||
self add_stat( 1011, delta_score );
|
||||
}
|
||||
}
|
||||
|
||||
function contract_kills( data )
|
||||
{
|
||||
victim = data.victim;
|
||||
attacker = data.attacker;
|
||||
player = attacker;
|
||||
weapon = data.weapon;
|
||||
time = data.time;
|
||||
|
||||
if ( !isdefined( weapon ) || ( weapon == level.weaponNone ) )
|
||||
return;
|
||||
|
||||
if ( !isdefined( player ) || !isplayer( player ) )
|
||||
return;
|
||||
|
||||
player add_stat( 1015 );
|
||||
player add_stat( 4 );
|
||||
|
||||
if ( weapon.isHeroWeapon === true )
|
||||
{
|
||||
player add_stat( 1012 );
|
||||
player add_stat( 7 );
|
||||
player add_stat( 3006 );
|
||||
}
|
||||
|
||||
isKillstreak = isdefined( data.eInflictor ) && isdefined( data.eInflictor.killstreakid );
|
||||
if ( !isKillstreak && isdefined( level.isKillstreakWeapon ) )
|
||||
{
|
||||
isKillstreakWeapon = [[level.isKillstreakWeapon]]( weapon );
|
||||
}
|
||||
|
||||
if ( isKillstreak || ( isKillstreakWeapon === true ) )
|
||||
{
|
||||
player add_stat( 1010 );
|
||||
player add_stat( 8 );
|
||||
}
|
||||
|
||||
statItemIndex = weapon.statIndex;
|
||||
|
||||
if ( player isItemPurchased( statItemIndex ) )
|
||||
{
|
||||
weaponClass = util::getWeaponClass( weapon );
|
||||
|
||||
switch ( weaponClass ) // aka group in mp_statsTable
|
||||
{
|
||||
case "weapon_assault":
|
||||
player add_stat( 1019 );
|
||||
player add_stat( 3001 );
|
||||
break;
|
||||
|
||||
case "weapon_smg":
|
||||
player add_stat( 1020 );
|
||||
player add_stat( 3000 );
|
||||
break;
|
||||
|
||||
case "weapon_sniper":
|
||||
player add_stat( 1021 );
|
||||
player add_stat( 3004 );
|
||||
break;
|
||||
|
||||
case "weapon_lmg":
|
||||
player add_stat( 1022 );
|
||||
player add_stat( 3003 );
|
||||
break;
|
||||
|
||||
case "weapon_cqb":
|
||||
player add_stat( 1023 );
|
||||
player add_stat( 3002 );
|
||||
break;
|
||||
|
||||
case "weapon_pistol":
|
||||
player add_stat( 1024 );
|
||||
break;
|
||||
|
||||
case "weapon_knife":
|
||||
player add_stat( 3005 );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
total_unlocked = player GetTotalUnlockedWeaponAttachments( weapon );
|
||||
if ( total_unlocked >= 4 )
|
||||
{
|
||||
player add_stat( 1025 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function add_stat( contract_index, delta )
|
||||
{
|
||||
if ( self is_contract_active( contract_index ) )
|
||||
{
|
||||
self add_active_stat( contract_index, delta );
|
||||
}
|
||||
}
|
||||
|
||||
function add_active_stat( contract_index, delta = 1 )
|
||||
{
|
||||
slot = self.pers["contracts"][contract_index].slot;
|
||||
target_value = self.pers["contracts"][contract_index].target_value;
|
||||
|
||||
/#
|
||||
if ( GetDvarInt( "scr_contract_debug_multiplier", 0 ) > 0 )
|
||||
delta *= GetDvarInt( "scr_contract_debug_multiplier", 1 );
|
||||
#/
|
||||
|
||||
old_progress = get_contract_stat( slot, "progress" );
|
||||
new_progress = old_progress + delta;
|
||||
|
||||
if ( new_progress > target_value )
|
||||
new_progress = target_value;
|
||||
|
||||
if ( new_progress != old_progress )
|
||||
self set_contract_stat( slot, "progress", new_progress );
|
||||
|
||||
just_completed = false;
|
||||
if ( old_progress < target_value && target_value <= new_progress )
|
||||
{
|
||||
just_completed = true;
|
||||
|
||||
// notify contract achieved
|
||||
event = &"mp_weekly_challenge_complete";
|
||||
display_rewards = false;
|
||||
|
||||
if ( slot == 2 )
|
||||
{
|
||||
event = &"mp_daily_challenge_complete";
|
||||
display_rewards = true;
|
||||
|
||||
self award_loot_xp_due( award_daily_contract() );
|
||||
self set_contract_stat( 2, "award_given", 1 );
|
||||
}
|
||||
else if ( slot == 0 || slot == 1 )
|
||||
{
|
||||
other_slot = 1;
|
||||
if ( slot == 1 )
|
||||
{
|
||||
other_slot = 0;
|
||||
}
|
||||
|
||||
foreach ( c_index,c_data in self.pers["contracts"] )
|
||||
{
|
||||
if ( c_data.slot == other_slot )
|
||||
{
|
||||
if ( c_data.target_value <= get_contract_stat( other_slot, "progress" ) )
|
||||
{
|
||||
display_rewards = true;
|
||||
|
||||
self award_loot_xp_due( award_weekly_contract() );
|
||||
self set_contract_stat( 0, "award_given", 1 );
|
||||
self set_contract_stat( 1, "award_given", 1 );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( slot == 3 )
|
||||
{
|
||||
event = &"mp_special_contract_complete";
|
||||
display_rewards = true;
|
||||
|
||||
absolute_stat_path = self.pers["contracts"][contract_index].absolute_stat_path;
|
||||
if ( absolute_stat_path != "" )
|
||||
{
|
||||
set_contract_award_stat_from_path( absolute_stat_path, true );
|
||||
}
|
||||
|
||||
calling_card_stat = self.pers["contracts"][contract_index].calling_card_stat;
|
||||
if ( calling_card_stat != "" )
|
||||
{
|
||||
set_contract_award_stat( "calling_card", calling_card_stat );
|
||||
}
|
||||
|
||||
weapon_camo_stat = self.pers["contracts"][contract_index].weapon_camo_stat;
|
||||
if ( weapon_camo_stat != "" )
|
||||
{
|
||||
set_contract_award_stat( "weapon_camo", weapon_camo_stat );
|
||||
}
|
||||
|
||||
self set_contract_stat( 3, "award_given", 1 );
|
||||
}
|
||||
|
||||
/#
|
||||
test_slot = GetDvarInt( "scr_contract_debug_slot", 10 - 1 );
|
||||
if ( slot == test_slot )
|
||||
{
|
||||
if ( contract_index >= 1000 && contract_index <= 2999 )
|
||||
{
|
||||
event = &"mp_daily_challenge_complete";
|
||||
}
|
||||
display_rewards = true;
|
||||
}
|
||||
#/
|
||||
|
||||
self LUINotifyEvent( event, 2, contract_index, display_rewards );
|
||||
}
|
||||
|
||||
/#
|
||||
if ( GetDvarInt( "scr_contract_debug", 0 ) > 0 )
|
||||
{
|
||||
IPrintLn( "Contract Slot "+ slot + " table index " + contract_index + " progress: " + new_progress + "/" + target_value );
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
function get_contract_stat( slot, stat_name )
|
||||
{
|
||||
return self GetDStat( "contracts", slot, stat_name );
|
||||
}
|
||||
|
||||
function set_contract_stat( slot, stat_name, stat_value )
|
||||
{
|
||||
return self SetDStat( "contracts", slot, stat_name, stat_value );
|
||||
}
|
||||
|
||||
function set_contract_award_stat( award_type, stat_name, stat_value = 1 )
|
||||
{
|
||||
// award_type is unused for now as we use PlayerStatsList for now
|
||||
|
||||
return self AddPlayerStat( stat_name, stat_value );
|
||||
}
|
||||
|
||||
function set_contract_award_stat_from_path( stat_path, stat_value )
|
||||
{
|
||||
stat_path_array = StrTok( stat_path, " " );
|
||||
|
||||
string_path_1 = "";
|
||||
string_path_2 = "";
|
||||
string_path_3 = "";
|
||||
string_path_4 = "";
|
||||
string_path_5 = "";
|
||||
|
||||
switch( stat_path_array.size )
|
||||
{
|
||||
case 5:
|
||||
string_path_5 = stat_path_array[4];
|
||||
if( StrIsNumber( string_path_5 ) )
|
||||
{
|
||||
string_path_5 = Int( string_path_5 );
|
||||
}
|
||||
case 4:
|
||||
string_path_4 = stat_path_array[3];
|
||||
if( StrIsNumber( string_path_4 ) )
|
||||
{
|
||||
string_path_4 = Int( string_path_4 );
|
||||
}
|
||||
case 3:
|
||||
string_path_3 = stat_path_array[2];
|
||||
if( StrIsNumber( string_path_3 ) )
|
||||
{
|
||||
string_path_3 = Int( string_path_3 );
|
||||
}
|
||||
case 2:
|
||||
string_path_2 = stat_path_array[1];
|
||||
if( StrIsNumber( string_path_2 ) )
|
||||
{
|
||||
string_path_2 = Int( string_path_2 );
|
||||
}
|
||||
case 1:
|
||||
string_path_1 = stat_path_array[0];
|
||||
if( StrIsNumber( string_path_1 ) )
|
||||
{
|
||||
string_path_1 = Int( string_path_1 );
|
||||
}
|
||||
}
|
||||
|
||||
switch( stat_path_array.size )
|
||||
{
|
||||
case 1:
|
||||
return self SetDStat( string_path_1, stat_value );
|
||||
break;
|
||||
case 2:
|
||||
return self SetDStat( string_path_1, string_path_2, stat_value );
|
||||
break;
|
||||
case 3:
|
||||
return self SetDStat( string_path_1, string_path_2, string_path_3, stat_value );
|
||||
break;
|
||||
case 4:
|
||||
return self SetDStat( string_path_1, string_path_2, string_path_3, string_path_4, stat_value );
|
||||
break;
|
||||
case 5:
|
||||
return self SetDStat( string_path_1, string_path_2, string_path_3, string_path_4, string_path_5, stat_value );
|
||||
break;
|
||||
default:
|
||||
AssertMsg( "Stat path depth of " + stat_path_array.size + " is too large. Limit to 5 deep" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function award_loot_xp_due( amount )
|
||||
{
|
||||
if ( !isdefined( self ) )
|
||||
return;
|
||||
|
||||
if ( amount <= 0 )
|
||||
return;
|
||||
|
||||
current_amount = (isdefined(self GetDStat( "mp_loot_xp_due" ))?self GetDStat( "mp_loot_xp_due" ):0);
|
||||
new_amount = current_amount + amount;
|
||||
self SetDStat( "mp_loot_xp_due", new_amount );
|
||||
}
|
||||
|
||||
function get_hero_weapon_mask( attacker, weapon )
|
||||
{
|
||||
if ( !isdefined( weapon ) )
|
||||
return 0;
|
||||
|
||||
if ( isdefined( weapon.isHeroWeapon ) && !weapon.isHeroWeapon )
|
||||
return 0;
|
||||
|
||||
switch( weapon.name )
|
||||
{
|
||||
case "hero_minigun":
|
||||
case "hero_minigun_body3":
|
||||
return 1; // note: heroWeaponMask needs to stay unique and consistent for function across TUs and FFOTDs
|
||||
break;
|
||||
case "hero_flamethrower":
|
||||
return 1 << 1;
|
||||
break;
|
||||
case "hero_lightninggun":
|
||||
case "hero_lightninggun_arc":
|
||||
return 1 << 2;
|
||||
break;
|
||||
case "hero_chemicalgelgun":
|
||||
case "hero_firefly_swarm":
|
||||
return 1 << 3;
|
||||
break;
|
||||
case "hero_pineapplegun":
|
||||
case "hero_pineapple_grenade":
|
||||
return 1 << 4;
|
||||
break;
|
||||
case "hero_armblade":
|
||||
return 1 << 5;
|
||||
break;
|
||||
case "hero_bowlauncher":
|
||||
case "hero_bowlauncher2":
|
||||
case "hero_bowlauncher3":
|
||||
case "hero_bowlauncher4":
|
||||
return 1 << 6;
|
||||
break;
|
||||
case "hero_gravityspikes":
|
||||
return 1 << 7;
|
||||
break;
|
||||
case "hero_annihilator":
|
||||
return 1 << 8;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function get_hero_ability_mask( ability )
|
||||
{
|
||||
if ( !isdefined( ability ) )
|
||||
return 0;
|
||||
|
||||
switch( ability.name )
|
||||
{
|
||||
case "gadget_clone":
|
||||
return 1; // note: heroAbilityMask needs to stay unique and consistent for functions across TUs and FFOTDs
|
||||
break;
|
||||
case "gadget_heat_wave":
|
||||
return 1 << 1;
|
||||
break;
|
||||
case "gadget_flashback":
|
||||
return 1 << 2;
|
||||
break;
|
||||
case "gadget_resurrect":
|
||||
return 1 << 3;
|
||||
break;
|
||||
case "gadget_armor":
|
||||
return 1 << 4;
|
||||
break;
|
||||
case "gadget_camo":
|
||||
return 1 << 5;
|
||||
break;
|
||||
case "gadget_vision_pulse":
|
||||
return 1 << 6;
|
||||
break;
|
||||
case "gadget_speed_burst":
|
||||
return 1 << 7;
|
||||
break;
|
||||
case "gadget_combat_efficiency":
|
||||
return 1 << 8;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function contract_game_ended( data )
|
||||
{
|
||||
// TODO: award challenge award here: maybe
|
||||
}
|
||||
|
||||
function contract_win( winner )
|
||||
{
|
||||
winner add_stat( 1000 );
|
||||
winner add_stat( 1 );
|
||||
winner add_stat( 3007 );
|
||||
winner add_stat( 3008 );
|
||||
winner add_stat( 3009 );
|
||||
winner add_stat( 3010 );
|
||||
winner add_stat( 3011 );
|
||||
winner add_stat( 3012 );
|
||||
winner add_stat( 3013 );
|
||||
winner add_stat( 3014 );
|
||||
winner add_stat( 3015 );
|
||||
winner add_stat( 3016 );
|
||||
winner add_stat( 3017 );
|
||||
winner add_stat( 3018 );
|
||||
winner add_stat( 3019 );
|
||||
winner add_stat( 3020 );
|
||||
winner add_stat( 3021 );
|
||||
winner add_stat( 3022 );
|
||||
winner add_stat( 3023 );
|
||||
winner add_stat( 3024 );
|
||||
winner add_stat( 3025 );
|
||||
winner add_stat( 3026 );
|
||||
winner add_stat( 3027 );
|
||||
winner add_stat( 3028 );
|
||||
|
||||
if ( util::is_objective_game( level.gametype ) )
|
||||
{
|
||||
winner add_stat( 2 );
|
||||
}
|
||||
|
||||
if ( IsArenaMode() )
|
||||
{
|
||||
winner add_stat( 1001 );
|
||||
}
|
||||
|
||||
gametype_win( winner );
|
||||
}
|
||||
|
||||
function gametype_win( winner )
|
||||
{
|
||||
switch ( level.gametype )
|
||||
{
|
||||
case "tdm":
|
||||
winner add_stat( 1002 );
|
||||
break;
|
||||
|
||||
case "ball":
|
||||
winner add_stat( 1003 );
|
||||
break;
|
||||
|
||||
case "escort":
|
||||
winner add_stat( 1004 );
|
||||
break;
|
||||
|
||||
case "conf":
|
||||
winner add_stat( 1005 );
|
||||
break;
|
||||
|
||||
case "sd":
|
||||
winner add_stat( 1006 );
|
||||
break;
|
||||
|
||||
case "koth":
|
||||
winner add_stat( 1007 );
|
||||
break;
|
||||
|
||||
case "dom":
|
||||
winner add_stat( 1008 );
|
||||
break;
|
||||
|
||||
case "ctf":
|
||||
winner add_stat( 1026 );
|
||||
break;
|
||||
|
||||
case "dem":
|
||||
winner add_stat( 1027 );
|
||||
break;
|
||||
|
||||
case "dm":
|
||||
winner add_stat( 1028 );
|
||||
break;
|
||||
|
||||
case "clean":
|
||||
winner add_stat( 1029 );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function on_offender_kill()
|
||||
{
|
||||
self add_stat( 1018 );
|
||||
self add_stat( 6 );
|
||||
}
|
||||
|
||||
function on_defender_kill()
|
||||
{
|
||||
self add_stat( 1017 );
|
||||
self add_stat( 6 );
|
||||
}
|
||||
|
||||
function on_headshot_kill()
|
||||
{
|
||||
self add_stat( 1016, 1 );
|
||||
}
|
||||
|
||||
function award_loot_xp()
|
||||
{
|
||||
player = self;
|
||||
|
||||
if ( !isdefined( player.pers["contracts"] ) )
|
||||
return 0;
|
||||
|
||||
loot_xp = 0;
|
||||
|
||||
//
|
||||
// daily contract
|
||||
//
|
||||
daily_slot = 2;
|
||||
if ( get_contract_stat( daily_slot, "active" ) && !get_contract_stat( daily_slot, "award_given" ) )
|
||||
{
|
||||
if ( contract_slot_met( daily_slot ) )
|
||||
{
|
||||
loot_xp += player award_daily_contract();
|
||||
player set_contract_stat( daily_slot, "award_given", 1 );
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// weekly contract
|
||||
//
|
||||
weekly_slot_A = 0;
|
||||
weekly_slot_B = 1;
|
||||
if ( get_contract_stat( weekly_slot_A, "active" ) && !get_contract_stat( weekly_slot_A, "award_given" ) &&
|
||||
get_contract_stat( weekly_slot_B, "active" ) && !get_contract_stat( weekly_slot_B, "award_given" ) )
|
||||
{
|
||||
if ( contract_slot_met( weekly_slot_A ) && contract_slot_met( weekly_slot_B ) )
|
||||
{
|
||||
loot_xp += player award_weekly_contract();
|
||||
player set_contract_stat( weekly_slot_A, "award_given", 1 );
|
||||
player set_contract_stat( weekly_slot_B, "award_given", 1 );
|
||||
}
|
||||
}
|
||||
|
||||
return loot_xp;
|
||||
}
|
||||
|
||||
function contract_slot_met( slot )
|
||||
{
|
||||
player = self;
|
||||
|
||||
contract_index = get_contract_stat( slot, "index" );
|
||||
|
||||
if ( !isdefined( player.pers["contracts"][contract_index] ) )
|
||||
return false;
|
||||
|
||||
progress = player get_contract_stat( slot, "progress" );
|
||||
target_value = player.pers["contracts"][contract_index].target_value;
|
||||
|
||||
return ( progress >= target_value );
|
||||
}
|
||||
|
||||
function award_daily_contract()
|
||||
{
|
||||
return GetDvarInt( "daily_contract_cryptokey_reward_count", 10 ) * GetDvarInt( "loot_cryptokeyCost", 100 );
|
||||
}
|
||||
|
||||
function award_weekly_contract()
|
||||
{
|
||||
self award_blackjack_contract();
|
||||
|
||||
return GetDvarInt( "weekly_contract_cryptokey_reward_count", 30 ) * GetDvarInt( "loot_cryptokeyCost", 100 );
|
||||
}
|
||||
|
||||
function award_blackjack_contract()
|
||||
{
|
||||
contract_count = self GetDStat( "blackjack_contract_count" );
|
||||
reward_count = GetDvarInt( "weekly_contract_blackjack_contract_reward_count", 1 );
|
||||
self SetDStat( "blackjack_contract_count", contract_count + reward_count );
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// mp contract header
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#namespace client_flag;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("client_flag",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
clientfield::register( "scriptmover", "ctf_flag_away", 1, 1, "int", &setCTFAway, !true, !true );
|
||||
}
|
||||
|
||||
function setCTFAway( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
||||
{
|
||||
team = self.team;
|
||||
|
||||
SetFlagAsAway( localClientNum, team, newVal );
|
||||
|
||||
self thread clearCTFAway( localClientNum, team );
|
||||
}
|
||||
|
||||
function clearCTFAway( localClientNum, team )
|
||||
{
|
||||
self waittill( "entityshutdown" );
|
||||
|
||||
SetFlagAsAway( localClientNum, team, 0 );
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\weapons\_decoy;
|
||||
|
||||
Line truncated
|
||||
|
||||
#namespace decoy;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("decoy",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
decoy::init_shared();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_decoy;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace decoy;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("decoy",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
decoy::init_shared();
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
|
||||
|
||||
#namespace destructible;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("destructible",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
clientfield::register( "scriptmover", "start_destructible_explosion", 1, 10, "int", &doExplosion, !true, !true );
|
||||
}
|
||||
|
||||
function playGrenadeRumble( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
||||
{
|
||||
PlayRumbleOnPosition( localClientNum, "grenade_rumble", self.origin );
|
||||
GetLocalPlayer( localClientNum ) Earthquake( 0.5, 0.5, self.origin, 800 );
|
||||
}
|
||||
|
||||
function doExplosion( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
||||
{
|
||||
if( newVal == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
physics_explosion = false;
|
||||
|
||||
if( newVal & ( 1 << ( 10 - 1 ) ) )
|
||||
{
|
||||
physics_explosion = true;
|
||||
|
||||
newVal -= ( 1 << ( 10 - 1 ) ) ;
|
||||
}
|
||||
|
||||
physics_force = 0.3;
|
||||
|
||||
if( physics_explosion )
|
||||
{
|
||||
PhysicsExplosionSphere( localClientNum, self.origin, newVal, newVal - 1, physics_force, 25, 400 );
|
||||
}
|
||||
|
||||
playGrenadeRumble( localClientNum, self.origin );
|
||||
}
|
||||
@@ -0,0 +1,610 @@
|
||||
#using scripts\shared\challenges_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
|
||||
#using scripts\mp\gametypes\_battlechatter;
|
||||
#using scripts\mp\gametypes\_globallogic_player;
|
||||
|
||||
#using scripts\mp\_challenges;
|
||||
|
||||
|
||||
|
||||
#namespace destructible;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("destructible",&__init__,undefined,undefined); }
|
||||
|
||||
#using_animtree ( "mp_vehicles" );
|
||||
|
||||
function __init__()
|
||||
{
|
||||
clientfield::register( "scriptmover", "start_destructible_explosion", 1, 10, "int" );
|
||||
|
||||
level.destructible_callbacks = [];
|
||||
destructibles = GetEntArray( "destructible", "targetname" );
|
||||
|
||||
// since this is globally run, only continue if we have a destructible in the level
|
||||
if( destructibles.size <= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// array::thread_all( destructibles,&destructible_think );
|
||||
|
||||
for ( i = 0; i < destructibles.size; i++ )
|
||||
{
|
||||
if ( GetSubStr( destructibles[i].destructibledef, 0, 4 ) == "veh_" )
|
||||
{
|
||||
destructibles[i] thread car_death_think();
|
||||
destructibles[i] thread car_grenade_stuck_think();
|
||||
}
|
||||
else if ( destructibles[i].destructibledef == "fxdest_upl_metal_tank_01" )
|
||||
{
|
||||
destructibles[i] thread tank_grenade_stuck_think();
|
||||
}
|
||||
}
|
||||
|
||||
init_explosions();
|
||||
}
|
||||
|
||||
function init_explosions()
|
||||
{
|
||||
level.explosion_manager = SpawnStruct();
|
||||
level.explosion_manager.count = 0;
|
||||
level.explosion_manager.a_explosions = [];
|
||||
|
||||
i = 0;
|
||||
while( i < 32 )
|
||||
{
|
||||
sExplosion = Spawn( "script_model", (0,0,0) );
|
||||
if ( !isdefined( level.explosion_manager.a_explosions ) ) level.explosion_manager.a_explosions = []; else if ( !IsArray( level.explosion_manager.a_explosions ) ) level.explosion_manager.a_explosions = array( level.explosion_manager.a_explosions ); level.explosion_manager.a_explosions[level.explosion_manager.a_explosions.size]=sExplosion;;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
function get_unused_explosion()
|
||||
{
|
||||
foreach( explosion in level.explosion_manager.a_explosions )
|
||||
{
|
||||
if( !( isdefined( explosion.in_use ) && explosion.in_use ) )
|
||||
{
|
||||
return explosion;
|
||||
}
|
||||
}
|
||||
return level.explosion_manager.a_explosions[0];
|
||||
}
|
||||
|
||||
//assumes explosion radius will never be greater than 2 ^ ( DESTRUCTIBLE_CLIENTFIELD_NUM_BITS )
|
||||
function physics_explosion_and_rumble( origin, radius, physics_explosion )
|
||||
{
|
||||
sExplosion = get_unused_explosion();
|
||||
sExplosion.in_use = true;
|
||||
sExplosion.origin = origin;
|
||||
|
||||
assert( radius <= pow( 2, 10 ) - 1 );
|
||||
|
||||
if( ( isdefined( physics_explosion ) && physics_explosion ) )
|
||||
{
|
||||
radius += ( 1 << ( 10 - 1 ) );
|
||||
}
|
||||
|
||||
{wait(.05);};
|
||||
|
||||
sExplosion clientfield::set( "start_destructible_explosion", radius );
|
||||
|
||||
sExplosion.in_use = false;
|
||||
}
|
||||
|
||||
function event_callback( destructible_event, attacker, weapon ) // self == the destructible object (like the car or barrel)
|
||||
{
|
||||
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"; // use a different explosion function
|
||||
}
|
||||
|
||||
if( IsSubStr( destructible_event, "explosive" ) )
|
||||
{
|
||||
tokens = StrTok(destructible_event, "_");
|
||||
explosion_radius_type = tokens[3];
|
||||
|
||||
if(explosion_radius_type == "small")
|
||||
{
|
||||
explosion_radius = 150;
|
||||
}
|
||||
else if(explosion_radius_type == "large")
|
||||
{
|
||||
explosion_radius = 450;
|
||||
}
|
||||
else
|
||||
{
|
||||
explosion_radius = 300;
|
||||
}
|
||||
}
|
||||
|
||||
if ( IsSubStr( destructible_event, "simple_timed_explosion" ) )
|
||||
{
|
||||
self thread simple_timed_explosion( destructible_event, attacker );
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( destructible_event )
|
||||
{
|
||||
case "destructible_car_explosion":
|
||||
self car_explosion( attacker );
|
||||
if ( isdefined( weapon ) )
|
||||
{
|
||||
self.destroyingWeapon = weapon;
|
||||
}
|
||||
break;
|
||||
|
||||
case "destructible_car_fire":
|
||||
level thread battlechatter::on_player_near_explodable( self, "car" );
|
||||
self thread car_fire_think(attacker);
|
||||
if ( isdefined( weapon ) )
|
||||
{
|
||||
self.destroyingWeapon = weapon;
|
||||
}
|
||||
break;
|
||||
|
||||
case "explode":
|
||||
self thread simple_explosion( attacker );
|
||||
break;
|
||||
|
||||
case "explode_complex":
|
||||
self thread complex_explosion( attacker, explosion_radius );
|
||||
break;
|
||||
|
||||
case "destructible_explosive_incendiary_small":
|
||||
case "destructible_explosive_incendiary_large":
|
||||
self explosive_incendiary_explosion( attacker, explosion_radius, false );
|
||||
if ( isdefined( weapon ) )
|
||||
{
|
||||
self.destroyingWeapon = weapon;
|
||||
}
|
||||
break;
|
||||
|
||||
case "destructible_explosive_electrical_small":
|
||||
case "destructible_explosive_electrical_large":
|
||||
self explosive_electrical_explosion( attacker, explosion_radius, false );
|
||||
if ( isdefined( weapon ) )
|
||||
{
|
||||
self.destroyingWeapon = weapon;
|
||||
}
|
||||
break;
|
||||
|
||||
case "destructible_explosive_concussive_small":
|
||||
case "destructible_explosive_concussive_large":
|
||||
self explosive_concussive_explosion( attacker, explosion_radius, false );
|
||||
if ( isdefined( weapon ) )
|
||||
{
|
||||
self.destroyingWeapon = weapon;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
//iprintln( "_destructible.gsc: unknown destructible event: '" + destructible_event + "'" );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( isdefined( level.destructible_callbacks[ destructible_event ] ) )
|
||||
{
|
||||
self thread [[level.destructible_callbacks[ destructible_event ]]]( destructible_event, attacker, weapon );
|
||||
}
|
||||
}
|
||||
|
||||
function simple_explosion( attacker )
|
||||
{
|
||||
if ( ( isdefined( self.exploded ) && self.exploded ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self.exploded = true;
|
||||
|
||||
offset = (0, 0, 5);
|
||||
self RadiusDamage( self.origin + offset, 256, 300, 75, attacker, "MOD_EXPLOSIVE", GetWeapon( "explodable_barrel" ) );
|
||||
physics_explosion_and_rumble( self.origin, 255, true );
|
||||
|
||||
if ( isdefined( attacker ) )
|
||||
{
|
||||
self DoDamage( self.health + 10000, self.origin + offset, attacker );
|
||||
}
|
||||
else
|
||||
{
|
||||
self DoDamage( self.health + 10000, self.origin + offset );
|
||||
}
|
||||
}
|
||||
|
||||
function simple_timed_explosion( destructible_event, attacker )
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
wait_times = [];
|
||||
|
||||
str = GetSubStr( destructible_event, 23 /* strlen( simple_timed_explosion ) */ );
|
||||
tokens = StrTok( str, "_" );
|
||||
|
||||
for ( i = 0; i < tokens.size; i++ )
|
||||
{
|
||||
wait_times[ wait_times.size ] = Int( tokens[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 );
|
||||
}
|
||||
|
||||
function complex_explosion( attacker, max_radius )
|
||||
{
|
||||
offset = (0, 0, 5);
|
||||
|
||||
if( isdefined( attacker ) )
|
||||
{
|
||||
self RadiusDamage( self.origin + offset, max_radius, 300, 100, attacker );
|
||||
}
|
||||
else
|
||||
{
|
||||
self RadiusDamage( self.origin + offset, max_radius, 300, 100 );
|
||||
}
|
||||
|
||||
physics_explosion_and_rumble( self.origin, max_radius, true );
|
||||
if( isdefined( attacker ) )
|
||||
{
|
||||
self DoDamage( 20000, self.origin + offset, attacker );
|
||||
}
|
||||
else
|
||||
{
|
||||
self DoDamage( 20000, self.origin + offset );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function car_explosion( attacker, physics_explosion )
|
||||
{
|
||||
if ( isdefined( self.car_dead ) && self.car_dead )
|
||||
{
|
||||
// prevents recursive entry caused by DoDamage call below
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !isdefined( physics_explosion ) )
|
||||
{
|
||||
physics_explosion = true;
|
||||
}
|
||||
|
||||
self notify( "car_dead" );
|
||||
self.car_dead = true;
|
||||
|
||||
if ( isdefined( attacker ))
|
||||
{
|
||||
self RadiusDamage( self.origin, 256, 300, 75, attacker, "MOD_EXPLOSIVE", GetWeapon( "destructible_car" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
self RadiusDamage( self.origin, 256, 300, 75 );
|
||||
}
|
||||
|
||||
physics_explosion_and_rumble( self.origin, 255, physics_explosion );
|
||||
|
||||
if ( isdefined ( attacker ) )
|
||||
attacker thread 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 MarkDestructibleDestroyed();
|
||||
}
|
||||
|
||||
function 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;
|
||||
}
|
||||
|
||||
if ( missile.model == "t5_weapon_crossbow_bolt" || missile.model == "t6_wpn_grenade_semtex_projectile" || missile.model == "wpn_t7_c4_world" )
|
||||
{
|
||||
self thread tank_grenade_stuck_explode( missile );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function tank_grenade_stuck_explode( missile )
|
||||
{
|
||||
self endon( "destructible_base_piece_death" );
|
||||
self endon( "death" );
|
||||
|
||||
owner = GetMissileOwner( missile );
|
||||
|
||||
if ( IsDefined( owner ) && missile.model == "wpn_t7_c4_world" )
|
||||
{
|
||||
owner endon( "disconnect" );
|
||||
owner endon( "weapon_object_destroyed" );
|
||||
missile endon( "picked_up" );
|
||||
|
||||
missile thread 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) );
|
||||
}
|
||||
}
|
||||
|
||||
function 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 tank_grenade_stuck_explode( self );
|
||||
}
|
||||
|
||||
function car_death_think()
|
||||
{
|
||||
self endon( "car_dead" );
|
||||
self.car_dead = false;
|
||||
|
||||
self thread car_death_notify();
|
||||
|
||||
self waittill( "destructible_base_piece_death", attacker );
|
||||
|
||||
if ( isdefined( self ) )
|
||||
{
|
||||
self thread car_explosion( attacker, false );
|
||||
}
|
||||
}
|
||||
|
||||
function 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;
|
||||
}
|
||||
|
||||
if ( missile.model == "t5_weapon_crossbow_bolt" || missile.model == "t6_wpn_grenade_semtex_projectile" || missile.model == "wpn_t7_c4_world" )
|
||||
{
|
||||
self thread car_grenade_stuck_explode( missile );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function 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 == "wpn_t7_c4_world" )
|
||||
{
|
||||
owner endon( "disconnect" );
|
||||
owner endon( "weapon_object_destroyed" );
|
||||
missile endon( "picked_up" );
|
||||
|
||||
missile thread 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) );
|
||||
}
|
||||
}
|
||||
|
||||
function 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 car_grenade_stuck_explode( self );
|
||||
}
|
||||
|
||||
function car_death_notify()
|
||||
{
|
||||
self endon( "car_dead" );
|
||||
|
||||
self waittill( "death", attacker );
|
||||
self notify( "destructible_base_piece_death", attacker );
|
||||
}
|
||||
|
||||
function car_fire_think(attacker)
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
wait( RandomIntRange( 7, 10 ) );
|
||||
|
||||
self thread car_explosion( attacker );
|
||||
}
|
||||
|
||||
function CodeCallback_DestructibleEvent( event, param1, param2, param3, param4 )
|
||||
{
|
||||
if( event == "broken" )
|
||||
{
|
||||
notify_type = param1;
|
||||
attacker = param2;
|
||||
piece = param3;
|
||||
weapon = param4;
|
||||
|
||||
event_callback( notify_type, attacker, weapon );
|
||||
|
||||
self notify( event, notify_type, attacker );
|
||||
}
|
||||
else if( event == "breakafter" )
|
||||
{
|
||||
piece = param1;
|
||||
time = param2;
|
||||
damage = param3;
|
||||
self thread breakAfter( time, damage, piece );
|
||||
}
|
||||
}
|
||||
|
||||
function breakAfter( time, damage, piece )
|
||||
{
|
||||
self notify( "breakafter" );
|
||||
self endon( "breakafter" );
|
||||
|
||||
wait time;
|
||||
|
||||
// this does not work in mp. DoDamage does not take a piece for mp.
|
||||
self dodamage( damage, self.origin, undefined, /*piece*/undefined );
|
||||
}
|
||||
|
||||
function explosive_incendiary_explosion( attacker, explosion_radius, physics_explosion )
|
||||
{
|
||||
if ( !IsVehicle( self ) )
|
||||
{
|
||||
offset = (0, 0, 5);
|
||||
if ( isdefined( attacker ))
|
||||
{
|
||||
self RadiusDamage( self.origin + offset, explosion_radius, 256, 75, attacker, "MOD_BURNED", GetWeapon( "incendiary_fire" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
self RadiusDamage( self.origin + offset, explosion_radius, 256, 75 );
|
||||
}
|
||||
physics_explosion_and_rumble( self.origin, 255, physics_explosion );
|
||||
|
||||
}
|
||||
|
||||
|
||||
// delete the clip that is attached
|
||||
if( isdefined( self.target ) )
|
||||
{
|
||||
dest_clip = GetEnt( self.target, "targetname" );
|
||||
if( isDefined( dest_clip ) )
|
||||
{
|
||||
dest_clip delete();
|
||||
}
|
||||
}
|
||||
|
||||
self MarkDestructibleDestroyed();
|
||||
}
|
||||
|
||||
function explosive_electrical_explosion( attacker, explosion_radius, physics_explosion )
|
||||
{
|
||||
if ( !IsVehicle( self ) )
|
||||
{
|
||||
offset = (0, 0, 5);
|
||||
if ( isdefined( attacker ))
|
||||
{
|
||||
self RadiusDamage( self.origin + offset, explosion_radius, 256, 75, attacker, "MOD_ELECTROCUTED" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self RadiusDamage( self.origin + offset, explosion_radius, 256, 75 );
|
||||
}
|
||||
physics_explosion_and_rumble( self.origin, 255, physics_explosion );
|
||||
}
|
||||
|
||||
|
||||
// delete the clip that is attached
|
||||
if( isdefined( self.target ) )
|
||||
{
|
||||
dest_clip = GetEnt( self.target, "targetname" );
|
||||
if( isDefined( dest_clip ) )
|
||||
{
|
||||
dest_clip delete();
|
||||
}
|
||||
}
|
||||
|
||||
self MarkDestructibleDestroyed();
|
||||
}
|
||||
|
||||
function explosive_concussive_explosion( attacker, explosion_radius, physics_explosion )
|
||||
{
|
||||
if ( !IsVehicle( self ) )
|
||||
{
|
||||
offset = (0, 0, 5);
|
||||
if ( isdefined( attacker ))
|
||||
{
|
||||
self RadiusDamage( self.origin + offset, explosion_radius, 256, 75, attacker, "MOD_GRENADE" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self RadiusDamage( self.origin + offset, explosion_radius, 256, 75 );
|
||||
}
|
||||
physics_explosion_and_rumble( self.origin, 255, physics_explosion );
|
||||
}
|
||||
|
||||
|
||||
// delete the clip that is attached
|
||||
if( isdefined( self.target ) )
|
||||
{
|
||||
dest_clip = GetEnt( self.target, "targetname" );
|
||||
if( isDefined( dest_clip ) )
|
||||
{
|
||||
dest_clip delete();
|
||||
}
|
||||
}
|
||||
|
||||
self MarkDestructibleDestroyed();
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
|
||||
+915
@@ -0,0 +1,915 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\array_shared;
|
||||
#using scripts\shared\flag_shared;
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\dev_shared;
|
||||
#using scripts\shared\killstreaks_shared;
|
||||
#using scripts\shared\load_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons_shared;
|
||||
#using scripts\shared\weapons\_weapons;
|
||||
#using scripts\shared\vehicle_ai_shared;
|
||||
#using scripts\shared\vehicle_shared;
|
||||
#using scripts\mp\_vehicle;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\killstreaks\_killstreaks;
|
||||
#using scripts\shared\bots\_bot;
|
||||
|
||||
/#
|
||||
|
||||
#namespace devgui;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function autoexec __init__sytem__() { system::register("devgui",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
SetDvar( "mp_weap_devgui", "" );
|
||||
SetDvar( "debug_center_screen", 0 );
|
||||
SetDvar( "mp_lockspawn_command_devgui", 0 );
|
||||
SetDvar( "mp_weap_use_give_console_command_devgui", 0 );
|
||||
SetDvar( "mp_weap_asset_name_display_devgui", 0 );
|
||||
SetDvar( "mp_weap_attachment_cosmetic_variant_index_devgui", 0 );
|
||||
SetDvar( "mp_weap_attachment_cosmetic_variant_attachment_1_devgui", "none" );
|
||||
SetDvar( "mp_weap_attachment_cosmetic_variant_attachment_2_devgui", "none" );
|
||||
|
||||
SetDvar( "mp_attachment_cycling_state_devgui", "none" );
|
||||
|
||||
SetDvar( "mp_attachment_cycling_1_devgui", "none" );
|
||||
SetDvar( "mp_attachment_cycling_2_devgui", "none" );
|
||||
SetDvar( "mp_attachment_cycling_3_devgui", "none" );
|
||||
SetDvar( "mp_attachment_cycling_4_devgui", "none" );
|
||||
SetDvar( "mp_attachment_cycling_5_devgui", "none" );
|
||||
SetDvar( "mp_attachment_cycling_6_devgui", "none" );
|
||||
|
||||
level.attachment_cycling_dvars = [];
|
||||
level.attachment_cycling_dvars[level.attachment_cycling_dvars.size] = "mp_attachment_cycling_1_devgui";
|
||||
level.attachment_cycling_dvars[level.attachment_cycling_dvars.size] = "mp_attachment_cycling_2_devgui";
|
||||
level.attachment_cycling_dvars[level.attachment_cycling_dvars.size] = "mp_attachment_cycling_3_devgui";
|
||||
level.attachment_cycling_dvars[level.attachment_cycling_dvars.size] = "mp_attachment_cycling_4_devgui";
|
||||
level.attachment_cycling_dvars[level.attachment_cycling_dvars.size] = "mp_attachment_cycling_5_devgui";
|
||||
level.attachment_cycling_dvars[level.attachment_cycling_dvars.size] = "mp_attachment_cycling_6_devgui";
|
||||
|
||||
SetDvar( "mp_acv_cycling_1_devgui", 0 );
|
||||
SetDvar( "mp_acv_cycling_2_devgui", 0 );
|
||||
SetDvar( "mp_acv_cycling_3_devgui", 0 );
|
||||
SetDvar( "mp_acv_cycling_4_devgui", 0 );
|
||||
SetDvar( "mp_acv_cycling_5_devgui", 0 );
|
||||
SetDvar( "mp_acv_cycling_6_devgui", 0 );
|
||||
|
||||
level.acv_cycling_dvars = [];
|
||||
level.acv_cycling_dvars[level.acv_cycling_dvars.size] = "mp_acv_cycling_1_devgui";
|
||||
level.acv_cycling_dvars[level.acv_cycling_dvars.size] = "mp_acv_cycling_2_devgui";
|
||||
level.acv_cycling_dvars[level.acv_cycling_dvars.size] = "mp_acv_cycling_3_devgui";
|
||||
level.acv_cycling_dvars[level.acv_cycling_dvars.size] = "mp_acv_cycling_4_devgui";
|
||||
level.acv_cycling_dvars[level.acv_cycling_dvars.size] = "mp_acv_cycling_5_devgui";
|
||||
level.acv_cycling_dvars[level.acv_cycling_dvars.size] = "mp_acv_cycling_6_devgui";
|
||||
|
||||
level thread devgui_weapon_think();
|
||||
level thread devgui_weapon_asset_name_display_think();
|
||||
level thread devgui_player_weapons();
|
||||
level thread devgui_test_chart_think();
|
||||
level thread devgui_player_spawn_think();
|
||||
level thread devgui_vehicle_spawn_think();
|
||||
|
||||
// center lines for making sure the gun aims properly
|
||||
thread init_debug_center_screen();
|
||||
|
||||
level thread dev::body_customization_devgui( 1 );
|
||||
|
||||
callback::on_connect( &hero_art_on_player_connect );
|
||||
callback::on_connect( &on_player_connect );
|
||||
}
|
||||
|
||||
function on_player_connect()
|
||||
{
|
||||
/#
|
||||
self.devguiLockSpawn = false;
|
||||
self thread devgui_player_spawn();
|
||||
#/
|
||||
}
|
||||
|
||||
function devgui_player_spawn()
|
||||
{
|
||||
wait(1);
|
||||
|
||||
player_devgui_base_mp = "devgui_cmd \"Player/Lock Spawn/";
|
||||
|
||||
{wait(.05);}; // so we don't overflow the Cbuf_InsertText()
|
||||
|
||||
players = GetPlayers();
|
||||
foreach( player in players )
|
||||
{
|
||||
if ( player != self )
|
||||
continue;
|
||||
|
||||
temp = player_devgui_base_mp + player.playername + "\" \"set " + "mp_lockspawn_command_devgui" + " " + player.playername + "\"\n";
|
||||
|
||||
AddDebugCommand( player_devgui_base_mp + player.playername + "\" \"set " + "mp_lockspawn_command_devgui" + " " + player.playername + "\"\n");
|
||||
}
|
||||
}
|
||||
|
||||
function devgui_player_spawn_think()
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
playername = GetDvarString( "mp_lockspawn_command_devgui" );
|
||||
if (playername=="")
|
||||
{
|
||||
{wait(.05);};
|
||||
continue;
|
||||
}
|
||||
|
||||
players = GetPlayers();
|
||||
foreach( player in players )
|
||||
{
|
||||
if ( player.playername != playername )
|
||||
continue;
|
||||
|
||||
player.devguiLockSpawn = !player.devguiLockSpawn;
|
||||
if ( player.devguiLockSpawn )
|
||||
{
|
||||
player.resurrect_origin = player.origin;
|
||||
player.resurrect_angles = player.angles;
|
||||
}
|
||||
}
|
||||
|
||||
SetDvar( "mp_lockspawn_command_devgui", "" );
|
||||
wait( 0.5 );
|
||||
}
|
||||
}
|
||||
|
||||
function devgui_vehicle_spawn_think()
|
||||
{
|
||||
{wait(.05);};
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
val = GetDvarInt( "scr_spawnvehicle" );
|
||||
if( val != 0 )
|
||||
{
|
||||
if( val == 1 ) add_vehicle_at_eye_trace( "siegebot" );
|
||||
else if( val == 2 ) add_vehicle_at_eye_trace( "siegebot_boss" );
|
||||
else if( val == 3 ) add_vehicle_at_eye_trace( "quadtank" );
|
||||
else if( val == 4 ) add_vehicle_at_eye_trace( "mechtank" );
|
||||
SetDvar( "scr_spawnvehicle", "0" );
|
||||
}
|
||||
{wait(.05);};
|
||||
}
|
||||
}
|
||||
|
||||
function devgui_player_weapons()
|
||||
{
|
||||
if ( ( isdefined( game["devgui_weapons_added"] ) && game["devgui_weapons_added"] ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
level flag::wait_till("all_players_spawned" );
|
||||
|
||||
a_weapons = EnumerateWeapons( "weapon" );
|
||||
|
||||
a_weapons_mp = [];
|
||||
a_grenades_mp = [];
|
||||
a_misc_mp = [];
|
||||
|
||||
// For misc weapons not in statstable
|
||||
|
||||
for ( i = 0; i < a_weapons.size; i++ )
|
||||
{
|
||||
if ( ( weapons::is_primary_weapon( a_weapons[i] ) || weapons::is_side_arm( a_weapons[i] ) ) && !killstreaks::is_killstreak_weapon( a_weapons[i] ) )
|
||||
{
|
||||
ArrayInsert( a_weapons_mp, a_weapons[i], 0 );
|
||||
}
|
||||
else if ( weapons::is_grenade( a_weapons[i] ) )
|
||||
{
|
||||
ArrayInsert( a_grenades_mp, a_weapons[i], 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
ArrayInsert( a_misc_mp, a_weapons[i], 0 );
|
||||
}
|
||||
}
|
||||
|
||||
player_devgui_base_mp = "devgui_cmd \"Player/Weapons/";
|
||||
|
||||
menu_index = 1;
|
||||
// *** T8 INTEGRATION ***: do NOT integrate; T8 has better solution
|
||||
level thread devgui_add_player_weapons( player_devgui_base_mp, "All", 0, a_weapons_mp, "Guns", menu_index );
|
||||
menu_index++;
|
||||
// *** T8 INTEGRATION ***: do NOT integrate; T8 has better solution
|
||||
level thread devgui_add_player_weapons( player_devgui_base_mp, "All", 0, a_grenades_mp, "Grenades", menu_index );
|
||||
menu_index++;
|
||||
// *** T8 INTEGRATION ***: do NOT integrate; T8 has better solution
|
||||
level thread devgui_add_player_weapons( player_devgui_base_mp, "All", 0, a_misc_mp, "Misc", menu_index );
|
||||
menu_index++;
|
||||
|
||||
game["devgui_weapons_added"] = true;
|
||||
{wait(.05);}; // so we don't overflow the Cbuf_InsertText()
|
||||
|
||||
AddDebugCommand( player_devgui_base_mp + "Toggle Use Give Cmd" + "\" \"toggle " + "mp_weap_use_give_console_command_devgui" + " 1 0\" \n");
|
||||
menu_index++;
|
||||
|
||||
AddDebugCommand( player_devgui_base_mp + "Toggle Debug Center Screen" + "\" \"toggle " + "debug_center_screen" + " 1 0\" \n");
|
||||
menu_index++;
|
||||
|
||||
AddDebugCommand( player_devgui_base_mp + "Toggle Weapon Asset Name Display" + "\" \"toggle " + "mp_weap_asset_name_display_devgui" + " 1 0\" \n");
|
||||
menu_index++;
|
||||
|
||||
acv_devgui_base_mp = player_devgui_base_mp + "Cosmetic Variants" + "/";
|
||||
menu_index++;
|
||||
|
||||
acv_menu_index = 1;
|
||||
acv_sub_menu_index = 1;
|
||||
for ( i = 0; i <= 3; i++ )
|
||||
{
|
||||
AddDebugCommand( acv_devgui_base_mp + "Variant Index" + "/" + i + "\" \"set " + "mp_weap_attachment_cosmetic_variant_index_devgui" + " " + i + "\" \n");
|
||||
acv_sub_menu_index++;
|
||||
}
|
||||
acv_menu_index++;
|
||||
|
||||
attachmentNames = GetAttachmentNames();
|
||||
|
||||
acv_sub_menu_index = 1;
|
||||
for ( i = 0; i < attachmentNames.size; i++ )
|
||||
{
|
||||
if ( IsSubStr( attachmentNames[i], "gmod" ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// *** T8 INTEGRATION ***: do NOT integrate; T8 has better solution
|
||||
devgui_wait();
|
||||
|
||||
AddDebugCommand( acv_devgui_base_mp + "Attachment 1" + "/" + attachmentNames[i] + "\" \"set " + "mp_weap_attachment_cosmetic_variant_attachment_1_devgui" + " " + attachmentNames[i] + "\" \n");
|
||||
acv_sub_menu_index++;
|
||||
}
|
||||
acv_menu_index++;
|
||||
|
||||
acv_sub_menu_index = 1;
|
||||
for ( i = 0; i < attachmentNames.size; i++ )
|
||||
{
|
||||
if ( IsSubStr( attachmentNames[i], "gmod" ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// *** T8 INTEGRATION ***: do NOT integrate; T8 has better solution
|
||||
devgui_wait();
|
||||
|
||||
AddDebugCommand( acv_devgui_base_mp + "Attachment 2" + "/" + attachmentNames[i] + "\" \"set " + "mp_weap_attachment_cosmetic_variant_attachment_2_devgui" + " " + attachmentNames[i] + "\" \n");
|
||||
acv_sub_menu_index++;
|
||||
}
|
||||
acv_menu_index++;
|
||||
|
||||
{wait(.05);}; // so we don't overflow the Cbuf_InsertText()
|
||||
|
||||
attachment_cycling_devgui_base_mp = player_devgui_base_mp + "Attachment Cycling" + "/";
|
||||
AddDebugCommand( attachment_cycling_devgui_base_mp + "Clear All\" \"set " + "mp_attachment_cycling_state_devgui" + " clear all\" \n");
|
||||
AddDebugCommand( attachment_cycling_devgui_base_mp + "Reapply\" \"set " + "mp_attachment_cycling_state_devgui" + " update\" \n");
|
||||
|
||||
for ( i = 0; i < 6; i++ )
|
||||
{
|
||||
attachment_cycling_sub_menu_index = 1;
|
||||
|
||||
AddDebugCommand( attachment_cycling_devgui_base_mp + "Attachment " + (i + 1) + "/Clear:1\" \"set " + "mp_attachment_cycling_state_devgui" + " clear " + i + "\" \n");
|
||||
|
||||
for ( attachmentName = 0; attachmentName < attachmentNames.size; attachmentName++ )
|
||||
{
|
||||
if ( IsSubStr( attachmentNames[attachmentName], "gmod" ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// *** T8 INTEGRATION ***: do NOT integrate; T8 has better solution
|
||||
devgui_wait();
|
||||
|
||||
AddDebugCommand( attachment_cycling_devgui_base_mp + "Attachment " + (i + 1) + "/" + attachmentNames[attachmentName] + "\" \"set " + "mp_attachment_cycling_state_devgui" + " update; set " + level.attachment_cycling_dvars[i] + " " + attachmentNames[attachmentName] + "; set " + level.acv_cycling_dvars[i] + " " + 0 + "\" \n");
|
||||
attachment_cycling_sub_menu_index++;
|
||||
|
||||
AddDebugCommand( attachment_cycling_devgui_base_mp + "Attachment " + (i + 1) + "/" + attachmentNames[attachmentName] + " Variant 1\" \"set " + "mp_attachment_cycling_state_devgui" + " update; set " + level.attachment_cycling_dvars[i] + " " + attachmentNames[attachmentName] + "; set " + level.acv_cycling_dvars[i] + " " + 1 + "\" \n");
|
||||
attachment_cycling_sub_menu_index++;
|
||||
}
|
||||
}
|
||||
|
||||
level thread devgui_attachment_cosmetic_variant_think();
|
||||
level thread devgui_attachment_cycling_think();
|
||||
}
|
||||
|
||||
function devgui_add_player_weapons( root, pname, index, a_weapons, weapon_type, mindex )
|
||||
{
|
||||
if( isDedicated() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
devgui_root = root + weapon_type + "/";
|
||||
|
||||
if ( IsDefined( a_weapons ) )
|
||||
{
|
||||
for ( i = 0; i < a_weapons.size; i++ )
|
||||
{
|
||||
attachments = a_weapons[i].supportedAttachments;
|
||||
name = a_weapons[i].name;
|
||||
|
||||
if ( attachments.size )
|
||||
{
|
||||
devgui_add_player_weap_command( devgui_root + name + "/", index, name, i + 1 );
|
||||
|
||||
foreach( att in attachments )
|
||||
{
|
||||
if ( att != "none" )
|
||||
{
|
||||
devgui_add_player_weap_command( devgui_root + name + "/", index, name + "+" + att, i + 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
devgui_add_player_weap_command( devgui_root, index, name, i + 1 );
|
||||
}
|
||||
|
||||
{wait(.05);};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *** T8 INTEGRATION ***: do NOT integrate; T8 has better solution
|
||||
function devgui_wait()
|
||||
{
|
||||
if(!isdefined(level.devgui_add_count))level.devgui_add_count=0;
|
||||
|
||||
// prevent input buffer overflow
|
||||
level.devgui_add_count++;
|
||||
if ( level.devgui_add_count % 10 == 0 )
|
||||
wait RandomIntRange( 2, 5 ) * .05;
|
||||
}
|
||||
|
||||
function devgui_add_player_weap_command( root, pid, weap_name, cmdindex )
|
||||
{
|
||||
// *** T8 INTEGRATION ***: do NOT integrate; T8 has better solution
|
||||
devgui_wait();
|
||||
|
||||
AddDebugCommand( root + weap_name+"\" \"set "+"mp_weap_devgui"+" "+weap_name+"\" \n");
|
||||
}
|
||||
|
||||
function devgui_weapon_think()
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
weapon_name = GetDvarString( "mp_weap_devgui" );
|
||||
|
||||
if ( weapon_name != "" )
|
||||
{
|
||||
devgui_handle_player_command( &devgui_give_weapon, weapon_name );
|
||||
}
|
||||
|
||||
SetDvar( "mp_weap_devgui", "" );
|
||||
|
||||
wait( 0.5 );
|
||||
}
|
||||
}
|
||||
|
||||
function hero_art_on_player_connect()
|
||||
{
|
||||
self._debugHeroModels = SpawnStruct();
|
||||
}
|
||||
|
||||
|
||||
|
||||
function devgui_weapon_asset_name_display_think()
|
||||
{
|
||||
update_time = 1;
|
||||
|
||||
print_duration = Int( update_time / .05 );
|
||||
|
||||
printlnbold_update = Int( 1 / update_time );
|
||||
printlnbold_counter = 0;
|
||||
|
||||
colors = [];
|
||||
colors[colors.size] = (1, 1, 1);
|
||||
colors[colors.size] = (1, 0, 0);
|
||||
colors[colors.size] = (0, 1, 0);
|
||||
colors[colors.size] = (1, 1, 0);
|
||||
colors[colors.size] = (1, 0, 1);
|
||||
colors[colors.size] = (0, 1, 1);
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait( update_time );
|
||||
|
||||
display = GetDvarInt( "mp_weap_asset_name_display_devgui" );
|
||||
|
||||
if ( !display )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !printlnbold_counter )
|
||||
{
|
||||
iPrintLnBold( level.players[0] GetCurrentWeapon().name );
|
||||
}
|
||||
printlnbold_counter++;
|
||||
if ( printlnbold_counter >= printlnbold_update )
|
||||
{
|
||||
printlnbold_counter = 0;
|
||||
}
|
||||
|
||||
color_index = 0;
|
||||
for ( i = 1; i < level.players.size; i++ )
|
||||
{
|
||||
player = level.players[i];
|
||||
weapon = player GetCurrentWeapon();
|
||||
|
||||
if ( !IsDefined( weapon ) || level.weaponNone == weapon )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Print3D( player GetTagOrigin( "tag_flash" ), weapon.name, colors[color_index], 1, 0.15, print_duration );
|
||||
|
||||
color_index++;
|
||||
if ( color_index >= colors.size )
|
||||
{
|
||||
color_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
color_index = 0;
|
||||
ai_list = GetAIArray();
|
||||
for ( i = 0; i < ai_list.size; i++ )
|
||||
{
|
||||
ai = ai_list[i];
|
||||
if ( IsVehicle( ai ) )
|
||||
{
|
||||
weapon = ai.turretweapon;
|
||||
}
|
||||
else
|
||||
{
|
||||
weapon = ai.weapon;
|
||||
}
|
||||
|
||||
if ( !IsDefined( weapon ) || level.weaponNone == weapon )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Print3D( ai GetTagOrigin( "tag_flash" ), weapon.name, colors[color_index], 1, 0.15, print_duration );
|
||||
|
||||
color_index++;
|
||||
if ( color_index >= colors.size )
|
||||
{
|
||||
color_index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function devgui_attachment_cosmetic_variant_think()
|
||||
{
|
||||
old_index = 0;
|
||||
old_attachment_1 = "none";
|
||||
old_attachment_2 = "none";
|
||||
for ( ;; )
|
||||
{
|
||||
index = GetDvarInt( "mp_weap_attachment_cosmetic_variant_index_devgui" );
|
||||
attachment_1 = GetDvarString( "mp_weap_attachment_cosmetic_variant_attachment_1_devgui" );
|
||||
attachment_2 = GetDvarString( "mp_weap_attachment_cosmetic_variant_attachment_2_devgui" );
|
||||
|
||||
if ( old_attachment_1 != attachment_1 || old_attachment_2 != attachment_2 || old_index != index )
|
||||
{
|
||||
devgui_handle_player_command( &devgui_update_attachment_cosmetic_variant, attachment_1, attachment_2 );
|
||||
}
|
||||
|
||||
old_index = index;
|
||||
old_attachment_1 = attachment_1;
|
||||
old_attachment_2 = attachment_2;
|
||||
|
||||
wait( 0.5 );
|
||||
}
|
||||
}
|
||||
|
||||
function devgui_attachment_cycling_clear( index )
|
||||
{
|
||||
SetDvar( level.attachment_cycling_dvars[index], "none" );
|
||||
SetDvar( level.acv_cycling_dvars[index], 0 );
|
||||
}
|
||||
|
||||
function devgui_attachment_cycling_update()
|
||||
{
|
||||
currentWeapon = self GetCurrentWeapon();
|
||||
|
||||
rootweapon = currentWeapon.rootweapon;
|
||||
supportedAttachments = currentWeapon.supportedattachments;
|
||||
|
||||
textColors = [];
|
||||
attachments = [];
|
||||
acvs = [];
|
||||
originalAttachments = [];
|
||||
originalAcvs = [];
|
||||
for ( i = 0; i < 6; i++ )
|
||||
{
|
||||
originalAttachments[i] = GetDvarString( level.attachment_cycling_dvars[i] );
|
||||
originalAcvs[i] = GetDvarInt( level.acv_cycling_dvars[i] );
|
||||
|
||||
textColor[i] = "^7";
|
||||
attachments[i] = "none";
|
||||
acvs[i] = 0;
|
||||
|
||||
name = originalAttachments[i];
|
||||
if ( "none" == name )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
textColor[i] = "^1";
|
||||
for ( supportedIndex = 0; supportedIndex < supportedAttachments.size; supportedIndex++ )
|
||||
{
|
||||
if ( name == supportedAttachments[supportedIndex] )
|
||||
{
|
||||
textColor[i] = "^7";
|
||||
attachments[i] = name;
|
||||
acvs[i] = originalAcvs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( i = 0; i < 6; i++ )
|
||||
{
|
||||
if ( "none" == originalAttachments[i] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( j = i + 1; j < 6; j++ )
|
||||
{
|
||||
if ( originalAttachments[i] == originalAttachments[j] )
|
||||
{
|
||||
textColor[j] = "^6";
|
||||
attachments[j] = "none";
|
||||
acvs[j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
msg = "";
|
||||
for ( i = 0; i < 6; i++ )
|
||||
{
|
||||
if ( "none" == originalAttachments[i] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
msg += textColor[i];
|
||||
msg += i;
|
||||
msg += ": ";
|
||||
msg += originalAttachments[i];
|
||||
msg += ", ";
|
||||
msg += originalAcvs[i];
|
||||
msg += ", ";
|
||||
}
|
||||
|
||||
IPrintLnBold( msg );
|
||||
|
||||
self TakeWeapon( currentWeapon );
|
||||
|
||||
currentWeapon = GetWeapon( rootweapon.name, attachments[0], attachments[1], attachments[2], attachments[3], attachments[4], attachments[5] );
|
||||
acvi = GetAttachmentCosmeticVariantIndexes( currentWeapon, attachments[0], acvs[0], attachments[1], acvs[1], attachments[2], acvs[2], attachments[3], acvs[3], attachments[4], acvs[4], attachments[5], acvs[5] );
|
||||
|
||||
wait( 0.25 ); // wait a little bit so that the weapon viewmodel will rebuild
|
||||
|
||||
self GiveWeapon( currentWeapon, undefined, acvi );
|
||||
self SwitchToWeapon( currentWeapon );
|
||||
}
|
||||
|
||||
function devgui_attachment_cycling_think()
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
state = GetDvarString( "mp_attachment_cycling_state_devgui" );
|
||||
SetDvar( "mp_attachment_cycling_state_devgui", "none" );
|
||||
|
||||
if ( IsSubStr( state, "clear " ) )
|
||||
{
|
||||
if ( "clear all" == state )
|
||||
{
|
||||
for ( i = 0; i < 6; i++ )
|
||||
{
|
||||
devgui_attachment_cycling_clear( i );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
index = Int( GetSubStr( state, 6, 7 ) );
|
||||
devgui_attachment_cycling_clear( index );
|
||||
}
|
||||
|
||||
state = "update";
|
||||
}
|
||||
|
||||
if ( "update" == state )
|
||||
{
|
||||
array::thread_all( GetPlayers(), &devgui_attachment_cycling_update );
|
||||
}
|
||||
|
||||
wait( 0.5 );
|
||||
}
|
||||
}
|
||||
|
||||
function devgui_test_chart_think()
|
||||
{
|
||||
{wait(.05);}; // wait to get 0 initially
|
||||
|
||||
old_val = GetDvarInt( "scr_debug_test_chart" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
val = GetDvarInt( "scr_debug_test_chart" );
|
||||
|
||||
if ( old_val != val )
|
||||
{
|
||||
if ( IsDefined( level.test_chart_model ) )
|
||||
{
|
||||
level.test_chart_model delete();
|
||||
level.test_chart_model = undefined;
|
||||
}
|
||||
|
||||
if ( val )
|
||||
{
|
||||
player = GetPlayers()[0];
|
||||
|
||||
direction = player GetPlayerAngles();
|
||||
direction_vec = AnglesToForward( (0, direction[1], 0) ); // only want the player's yaw
|
||||
|
||||
scale = 120;
|
||||
direction_vec = (direction_vec[0] * scale, direction_vec[1] * scale, direction_vec[2] * scale);
|
||||
|
||||
level.test_chart_model = Spawn( "script_model", player GetEye() + direction_vec );
|
||||
level.test_chart_model SetModel( "test_chart_model" );
|
||||
level.test_chart_model.angles = (0, direction[1], 0) + (0, 90, 0); // only want the yaw
|
||||
}
|
||||
}
|
||||
|
||||
old_val = val;
|
||||
{wait(.05);};
|
||||
}
|
||||
}
|
||||
|
||||
function devgui_give_weapon( weapon_name )
|
||||
{
|
||||
assert( IsDefined( self ) );
|
||||
assert( IsPlayer( self ) );
|
||||
assert( IsAlive( self ) );
|
||||
|
||||
self notify( "devgui_give_ammo" );
|
||||
self endon( "devgui_give_ammo" );
|
||||
|
||||
currentWeapon = self GetCurrentWeapon();
|
||||
|
||||
split = StrTok( weapon_name, "+" );
|
||||
switch ( split.size )
|
||||
{
|
||||
default:
|
||||
case 1:
|
||||
weapon = GetWeapon( split[0] );
|
||||
break;
|
||||
case 2:
|
||||
weapon = GetWeapon( split[0], split[1] );
|
||||
break;
|
||||
case 3:
|
||||
weapon = GetWeapon( split[0], split[1], split[2] );
|
||||
break;
|
||||
case 4:
|
||||
weapon = GetWeapon( split[0], split[1], split[2], split[3] );
|
||||
break;
|
||||
case 5:
|
||||
weapon = GetWeapon( split[0], split[1], split[2], split[3], split[4] );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( currentWeapon != weapon )
|
||||
{
|
||||
// if the player already has 2 grenades, take one away
|
||||
if ( weapon.isGrenadeWeapon )
|
||||
{
|
||||
grenades = 0;
|
||||
pweapons = self GetWeaponsList();
|
||||
foreach( pweapon in pweapons )
|
||||
{
|
||||
if ( pweapon!=weapon && pweapon.isGrenadeWeapon )
|
||||
{
|
||||
grenades++;
|
||||
}
|
||||
}
|
||||
if ( grenades > 1 )
|
||||
{
|
||||
foreach( pweapon in pweapons )
|
||||
{
|
||||
if ( pweapon!=weapon && pweapon.isGrenadeWeapon )
|
||||
{
|
||||
grenades--;
|
||||
self TakeWeapon(pweapon);
|
||||
if ( grenades < 2 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( GetDvarInt( "mp_weap_use_give_console_command_devgui" ) )
|
||||
{
|
||||
AddDebugCommand( "give " + weapon_name );
|
||||
{wait(.05);}; // wait a frame to let the command take
|
||||
}
|
||||
else
|
||||
{
|
||||
self GiveWeapon( weapon );
|
||||
if ( !weapon.isGrenadeWeapon )
|
||||
self SwitchToWeapon( weapon );
|
||||
}
|
||||
|
||||
max = weapon.maxAmmo;
|
||||
|
||||
if ( max )
|
||||
{
|
||||
self SetWeaponAmmoStock( weapon, max );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function devgui_update_attachment_cosmetic_variant( attachment_1, attachment_2 )
|
||||
{
|
||||
assert( IsDefined( self ) );
|
||||
assert( IsPlayer( self ) );
|
||||
assert( IsAlive( self ) );
|
||||
|
||||
currentWeapon = self GetCurrentWeapon();
|
||||
variant_index = GetDvarInt( "mp_weap_attachment_cosmetic_variant_index_devgui" );
|
||||
acvi = GetAttachmentCosmeticVariantIndexes( currentWeapon, attachment_1, variant_index, attachment_2, variant_index );
|
||||
self TakeWeapon( currentWeapon );
|
||||
wait( 0.25 ); // wait a little bit so that the weapon viewmodel will rebuild
|
||||
self GiveWeapon( currentWeapon, undefined, acvi );
|
||||
self SwitchToWeapon( currentWeapon );
|
||||
}
|
||||
|
||||
function devgui_handle_player_command( playercallback, pcb_param_1, pcb_param_2 )
|
||||
{
|
||||
pid = GetDvarInt( "mp_weap_devgui" );
|
||||
if (pid>0)
|
||||
{
|
||||
player = GetPlayers()[pid-1];
|
||||
if (IsDefined(player))
|
||||
{
|
||||
if (IsDefined( pcb_param_2 ))
|
||||
player thread [[playercallback]]( pcb_param_1, pcb_param_2 );
|
||||
else if (IsDefined( pcb_param_1 ))
|
||||
player thread [[playercallback]]( pcb_param_1 );
|
||||
else
|
||||
player thread [[playercallback]]();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
array::thread_all( GetPlayers(), playercallback, pcb_param_1, pcb_param_2 );
|
||||
}
|
||||
SetDvar( "mp_weap_devgui", "-1" );
|
||||
}
|
||||
|
||||
// *** Debug the Center of the Screen ***
|
||||
// Allows you to draw a large crosshair in the center of the screen by pressing in both sticks at once
|
||||
function init_debug_center_screen()
|
||||
{
|
||||
zero_idle_movement = "0";
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if( GetDvarInt( "debug_center_screen" ) )
|
||||
{
|
||||
if (!isdefined (level.center_screen_debug_hudelem_active) || level.center_screen_debug_hudelem_active == false)
|
||||
{
|
||||
thread debug_center_screen();
|
||||
|
||||
zero_idle_movement = GetDvarString( "zero_idle_movement" );
|
||||
if( isdefined( zero_idle_movement ) && zero_idle_movement == "0" )
|
||||
{
|
||||
SetDvar( "zero_idle_movement", "1" );
|
||||
zero_idle_movement = "1";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
level notify ("stop center screen debug");
|
||||
|
||||
if( zero_idle_movement == "1" )
|
||||
{
|
||||
SetDvar( "zero_idle_movement", "0" );
|
||||
zero_idle_movement = "0";
|
||||
}
|
||||
}
|
||||
wait (0.05);
|
||||
}
|
||||
}
|
||||
|
||||
// draws the center screen debug marker
|
||||
function debug_center_screen()
|
||||
{
|
||||
level.center_screen_debug_hudelem_active = true;
|
||||
wait 0.1;
|
||||
|
||||
level.center_screen_debug_hudelem1 = newclienthudelem ( level.players[0] );
|
||||
level.center_screen_debug_hudelem1.alignX = "center";
|
||||
level.center_screen_debug_hudelem1.alignY = "middle";
|
||||
level.center_screen_debug_hudelem1.fontScale = 1;
|
||||
level.center_screen_debug_hudelem1.alpha = 0.5;
|
||||
level.center_screen_debug_hudelem1.x = (640/2) - 1;
|
||||
level.center_screen_debug_hudelem1.y = (480/2);
|
||||
level.center_screen_debug_hudelem1 setshader("white", 1000, 1);
|
||||
|
||||
level.center_screen_debug_hudelem2 = newclienthudelem ( level.players[0] );
|
||||
level.center_screen_debug_hudelem2.alignX = "center";
|
||||
level.center_screen_debug_hudelem2.alignY = "middle";
|
||||
level.center_screen_debug_hudelem2.fontScale = 1;
|
||||
level.center_screen_debug_hudelem2.alpha = 0.5;
|
||||
level.center_screen_debug_hudelem2.x = (640/2) - 1;
|
||||
level.center_screen_debug_hudelem2.y = (480/2);
|
||||
level.center_screen_debug_hudelem2 setshader("white", 1, 480);
|
||||
|
||||
level waittill ("stop center screen debug");
|
||||
|
||||
level.center_screen_debug_hudelem1 destroy();
|
||||
level.center_screen_debug_hudelem2 destroy();
|
||||
level.center_screen_debug_hudelem_active = false;
|
||||
}
|
||||
|
||||
function add_vehicle_at_eye_trace( vehicleName )
|
||||
{
|
||||
host = util::getHostPlayer();
|
||||
|
||||
trace = host bot::eye_trace();
|
||||
|
||||
//vehicle = SpawnVehicle( vehicleName, trace[ "position" ] + ( 0, 0, 20 ) , ( 0, 0, 0 ), "test_siege" );
|
||||
veh_spawner = GetEnt( vehicleName + "_spawner", "targetname" );
|
||||
vehicle = veh_spawner SpawnFromSpawner( vehicleName, true, true, true );
|
||||
if( isdefined( vehicle.archetype ) )
|
||||
vehicle ASMRequestSubstate( "locomotion@movement" );
|
||||
|
||||
{wait(.05);};
|
||||
|
||||
vehicle.origin = trace[ "position" ];
|
||||
|
||||
vehicle thread vehicle::VehicleTeamThread();
|
||||
|
||||
vehicle thread watch_player_death();
|
||||
|
||||
return vehicle;
|
||||
}
|
||||
|
||||
function watch_player_death()
|
||||
{
|
||||
self endon( "death" );
|
||||
vehicle = self;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
driver = self GetSeatOccupant( 0 );
|
||||
if( isdefined( driver ) && !IsAlive( driver ) )
|
||||
driver unlink();
|
||||
{wait(.05);};
|
||||
}
|
||||
}
|
||||
|
||||
#/
|
||||
@@ -0,0 +1,319 @@
|
||||
#using scripts\codescripts\struct;
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\end_game_taunts;
|
||||
#using scripts\shared\scene_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
Line truncated
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#using_animtree("all_player");
|
||||
#namespace end_game_flow;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("end_game_flow",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
clientfield::register( "world", "displayTop3Players", 1, 1, "int", &handleTopThreePlayers, !true, !true );
|
||||
clientfield::register( "world", "triggerScoreboardCamera", 1, 1, "int", &showScoreboard, !true, !true );
|
||||
clientfield::register( "world", "playTop0Gesture", 1000, 3, "int", &handlePlayTop0Gesture, !true, !true );
|
||||
clientfield::register( "world", "playTop1Gesture", 1000, 3, "int", &handlePlayTop1Gesture, !true, !true );
|
||||
clientfield::register( "world", "playTop2Gesture", 1000, 3, "int", &handlePlayTop2Gesture, !true, !true );
|
||||
|
||||
level thread streamerWatcher();
|
||||
}
|
||||
|
||||
function setAnimationOnModel( localClientNum, characterModel, topPlayerIndex )
|
||||
{
|
||||
anim_name = end_game_taunts::getidleanimname( localClientNum, characterModel, topPlayerIndex );
|
||||
|
||||
if( isDefined(anim_name) )
|
||||
{
|
||||
characterModel util::waittill_dobj( localClientNum );
|
||||
|
||||
if( !characterModel HasAnimTree() )
|
||||
{
|
||||
characterModel UseAnimTree( #animtree );
|
||||
}
|
||||
|
||||
characterModel SetAnim( anim_name );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function loadCharacterOnModel( localClientNum, characterModel, topPlayerIndex )
|
||||
{
|
||||
assert( isdefined( characterModel ) );
|
||||
|
||||
// swap out our body
|
||||
bodyModel = GetTopPlayersBodyModel( localClientNum, topPlayerIndex );
|
||||
displayTopPlayerModel = CreateUIModel( GetUIModelForController( localClientNum ), "displayTopPlayer" + (topPlayerIndex+1) );
|
||||
SetUIModelValue( displayTopPlayerModel, 1 );
|
||||
|
||||
// This happens when the client has never spawned in, we should not show his model and not show his playercard as well.
|
||||
if ( !IsDefined( bodyModel ) || bodymodel == "" )
|
||||
{
|
||||
SetUIModelValue( displayTopPlayerModel, 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
characterModel SetModel( bodyModel );
|
||||
|
||||
// swap out our helmet
|
||||
helmetModel = GetTopPlayersHelmetModel( localClientNum, topPlayerIndex );
|
||||
|
||||
if ( !( characterModel IsAttached( helmetModel, "" ) ) )
|
||||
{
|
||||
characterModel.helmetModel = helmetModel; // Keep refcount on this string because we'll need it later
|
||||
characterModel Attach( helmetModel, "" );
|
||||
}
|
||||
|
||||
// set up our render options
|
||||
modeRenderOptions = GetCharacterModeRenderOptions( CurrentSessionMode() );
|
||||
bodyRenderOptions = GetTopPlayersBodyRenderOptions( localClientNum, topPlayerIndex );
|
||||
helmetRenderOptions = GetTopPlayersHelmetRenderOptions( localClientNum, topPlayerIndex );
|
||||
weaponRenderOptions = GetTopPlayersWeaponRenderOptions( localClientNum, topPlayerIndex );
|
||||
|
||||
// Used by epic taunts to clone the model and match skins
|
||||
characterModel.bodyModel = bodyModel;
|
||||
// Headmodel is attached above
|
||||
characterModel.modeRenderOptions = modeRenderOptions;
|
||||
characterModel.bodyRenderOptions = bodyRenderOptions;
|
||||
characterModel.helmetRenderOptions = helmetRenderOptions;
|
||||
characterModel.headRenderOptions = helmetRenderOptions;
|
||||
|
||||
weapon_right = GetTopPlayersWeaponInfo( localClientNum, topPlayerIndex );
|
||||
|
||||
if ( !isDefined( level.weaponNone ) )
|
||||
{
|
||||
level.weaponNone = GetWeapon( "none" );
|
||||
}
|
||||
|
||||
characterModel SetBodyRenderOptions( modeRenderOptions, bodyRenderOptions, helmetRenderOptions, helmetRenderOptions );
|
||||
|
||||
if ( weapon_right["weapon"] == level.weaponNone )
|
||||
{
|
||||
weapon_right["weapon"] = GetWeapon("ar_standard");
|
||||
characterModel.showcaseWeapon = weapon_right["weapon"];
|
||||
characterModel AttachWeapon( weapon_right["weapon"] );
|
||||
}
|
||||
else
|
||||
{
|
||||
characterModel.showcaseWeapon = weapon_right["weapon"];
|
||||
characterModel.showcaseWeaponRenderOptions = weaponRenderOptions;
|
||||
characterModel.showcaseWeaponACVI = weapon_right["acvi"];
|
||||
|
||||
characterModel AttachWeapon( weapon_right["weapon"], weaponRenderOptions, weapon_right["acvi"] );
|
||||
characterModel UseWeaponHideTags( weapon_right["weapon"] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function setupModelAndAnimation( localClientNum, characterModel, topPlayerIndex )
|
||||
{
|
||||
characterModel endon("entityshutdown");
|
||||
|
||||
loadCharacterOnModel( localClientNum, characterModel, topPlayerIndex );
|
||||
setAnimationOnModel( localClientNum, characterModel, topPlayerIndex );
|
||||
}
|
||||
|
||||
|
||||
|
||||
function prepareTopThreePlayers( localClientNum )
|
||||
{
|
||||
numClients = GetTopScorerCount( localClientNum );
|
||||
position = struct::get( "endgame_top_players_struct", "targetname" );
|
||||
|
||||
if( !isdefined( position ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for( index = 0; index < 3; index++ )
|
||||
{
|
||||
if ( index < numClients )
|
||||
{
|
||||
model = Spawn( localClientNum, position.origin, "script_model" );
|
||||
loadCharacterOnModel( localClientNum, model, index );
|
||||
model Hide();
|
||||
model SetHighDetail( true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showTopThreePlayers( localClientNum )
|
||||
{
|
||||
level.topPlayerCharacters = [];
|
||||
topPlayerScriptStructs = [];
|
||||
|
||||
topPlayerScriptStructs[0] = struct::get( "TopPlayer1", "targetname" );
|
||||
topPlayerScriptStructs[1] = struct::get( "TopPlayer2", "targetname" );
|
||||
topPlayerScriptStructs[2] = struct::get( "TopPlayer3", "targetname" );
|
||||
|
||||
foreach( index, scriptStruct in topPlayerScriptStructs )
|
||||
{
|
||||
level.topPlayerCharacters[index] = Spawn( localClientNum, scriptStruct.origin, "script_model" );
|
||||
// level.topPlayerCharacters[index] SetDedicatedShadow( true );
|
||||
level.topPlayerCharacters[index].angles = scriptStruct.angles;
|
||||
}
|
||||
numClients = GetTopScorerCount( localClientNum );
|
||||
|
||||
foreach( index, characterModel in level.topPlayerCharacters )
|
||||
{
|
||||
if ( index < numClients )
|
||||
{
|
||||
thread setupModelAndAnimation( localClientNum, characterModel, index );
|
||||
|
||||
if ( index == 0 )
|
||||
{
|
||||
thread end_game_taunts::playCurrentTaunt( localClientNum, characterModel, index );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/#
|
||||
level thread end_game_taunts::check_force_taunt();
|
||||
level thread end_game_taunts::check_force_gesture();
|
||||
level thread end_game_taunts::draw_runner_up_bounds();
|
||||
#/
|
||||
|
||||
position = struct::get( "endgame_top_players_struct", "targetname" );
|
||||
PlayMainCamXCam( localClientNum, level.endGameXCamName, 0, "cam_topscorers", "topscorers", position.origin, position.angles );
|
||||
PlayRadiantExploder( localClientNum, "exploder_mp_endgame_lights" );
|
||||
|
||||
SetUIModelValue( CreateUIModel( GetUIModelForController( localClientNum ), "displayTop3Players" ), 1 );
|
||||
|
||||
thread spamUIModelValue( localClientNum );
|
||||
thread checkForGestures( localClientNum );
|
||||
}
|
||||
|
||||
function spamUIModelValue( localClientNum )
|
||||
{
|
||||
while( 1 )
|
||||
{
|
||||
wait (0.25);
|
||||
SetUIModelValue( CreateUIModel( GetUIModelForController( localClientNum ), "displayTop3Players" ), 1 );
|
||||
}
|
||||
}
|
||||
|
||||
function checkForGestures( localClientNum )
|
||||
{
|
||||
localPlayers = GetLocalPlayers();
|
||||
|
||||
for ( i = 0; i < localPlayers.size; i++ )
|
||||
{
|
||||
thread checkForPlayerGestures( localClientNum, localPlayers[i], i );
|
||||
}
|
||||
}
|
||||
|
||||
function checkForPlayerGestures( localClientNum, localPlayer, playerIndex )
|
||||
{
|
||||
localTopPlayerIndex = localPlayer GetTopPlayersIndex( localClientNum );
|
||||
|
||||
if ( !isdefined( localTopPlayerIndex ) ||
|
||||
!isdefined( level.topPlayerCharacters ) ||
|
||||
localTopPlayerIndex >= level.topPlayerCharacters.size )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
characterModel = level.topPlayerCharacters[localTopPlayerIndex];
|
||||
|
||||
if ( localTopPlayerIndex > 0 )
|
||||
{
|
||||
wait( 3 );
|
||||
}
|
||||
else if ( isdefined( characterModel.playingTaunt ) )
|
||||
{
|
||||
characterModel waittill( "tauntFinished" );
|
||||
}
|
||||
|
||||
showGestures( localClientNum, playerIndex );
|
||||
}
|
||||
|
||||
function showGestures( localClientNum, playerIndex )
|
||||
{
|
||||
gesturesModel = GetUIModel( GetUIModelForController( localClientNum ), "topPlayerInfo.showGestures" );
|
||||
if ( isdefined( gesturesModel ) )
|
||||
{
|
||||
SetUIModelValue( gesturesModel, true );
|
||||
AllowActionSlotInput( playerIndex );
|
||||
}
|
||||
}
|
||||
|
||||
function handlePlayTop0Gesture( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
||||
{
|
||||
handlePlayGesture( localClientNum, 0, newVal );
|
||||
}
|
||||
|
||||
function handlePlayTop1Gesture( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
||||
{
|
||||
handlePlayGesture( localClientNum, 1, newVal );
|
||||
}
|
||||
|
||||
function handlePlayTop2Gesture( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
||||
{
|
||||
handlePlayGesture( localClientNum, 2, newVal );
|
||||
}
|
||||
|
||||
function handlePlayGesture( localClientNum, topPlayerIndex, gestureType )
|
||||
{
|
||||
if ( gestureType > 2 ||
|
||||
!isdefined( level.topPlayerCharacters ) ||
|
||||
topPlayerIndex >= level.topPlayerCharacters.size )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
characterModel = level.topPlayerCharacters[topPlayerIndex];
|
||||
|
||||
if ( isdefined( characterModel.playingTaunt ) ||
|
||||
( isdefined( characterModel.playingGesture ) && characterModel.playingGesture ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
thread end_game_taunts::playGestureType( localClientNum, characterModel, topPlayerIndex, gestureType );
|
||||
}
|
||||
|
||||
function streamerWatcher()
|
||||
{
|
||||
while( true )
|
||||
{
|
||||
level waittill( "streamFKsl", localClientNum );
|
||||
prepareTopThreePlayers( localClientNum );
|
||||
end_game_taunts::stream_epic_models();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function handleTopThreePlayers( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
||||
{
|
||||
if ( isdefined( newVal ) && newVal > 0 && isDefined( level.endGameXCamName ) )
|
||||
{
|
||||
level.showedTopThreePlayers = true;
|
||||
showTopThreePlayers( localClientNum );
|
||||
}
|
||||
}
|
||||
|
||||
function showScoreboard( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
||||
{
|
||||
if ( isdefined( newVal ) && newVal > 0 && isDefined( level.endGameXCamName ) )
|
||||
{
|
||||
end_game_taunts::stop_stream_epic_models();
|
||||
end_game_taunts::deleteCameraGlass( undefined );
|
||||
position = struct::get( "endgame_top_players_struct", "targetname" );
|
||||
PlayMainCamXCam( localClientNum, level.endGameXCamName, 0, "cam_topscorers", "", position.origin, position.angles );
|
||||
SetUIModelValue( CreateUIModel( GetUIModelForController( localClientNum ), "forceScoreboard" ), 1 );
|
||||
level.inEndGameFlow = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\entityheadicons_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#namespace entityheadicons;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("entityheadicons",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
entityheadicons::init_shared();
|
||||
}
|
||||
|
||||
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\gametypes\_globallogic_utils;
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace events;
|
||||
|
||||
/*------------------------------------
|
||||
Adds an event based on the current value of the gametypes timer
|
||||
------------------------------------*/
|
||||
function add_timed_event( seconds, notify_string, client_notify_string )
|
||||
{
|
||||
assert( seconds >= 0 );
|
||||
|
||||
if ( level.timelimit > 0 )
|
||||
{
|
||||
level thread timed_event_monitor( seconds, notify_string, client_notify_string );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------
|
||||
checks the game/level timer for timed events
|
||||
------------------------------------*/
|
||||
function timed_event_monitor( seconds, notify_string, client_notify_string )
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
wait( 0.5 );
|
||||
|
||||
if( !isdefined( level.startTime ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//get the time remaining and see if events need to be fired off
|
||||
millisecs_remaining = globallogic_utils::getTimeRemaining();
|
||||
seconds_remaining = millisecs_remaining / 1000;
|
||||
|
||||
if( seconds_remaining <= seconds )
|
||||
{
|
||||
event_notify( notify_string, client_notify_string );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function add_score_event( score, notify_string, client_notify_string )
|
||||
{
|
||||
assert( score >= 0 );
|
||||
|
||||
if ( level.scoreLimit > 0 )
|
||||
{
|
||||
if ( level.teamBased )
|
||||
{
|
||||
level thread score_team_event_monitor( score, notify_string, client_notify_string );
|
||||
}
|
||||
else
|
||||
{
|
||||
level thread score_event_monitor( score, notify_string, client_notify_string );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function add_round_score_event( score, notify_string, client_notify_string )
|
||||
{
|
||||
assert( score >= 0 );
|
||||
|
||||
if ( level.roundScoreLimit > 0 )
|
||||
{
|
||||
roundScoreToBeat = ( level.roundScoreLimit * game[ "roundsplayed" ] ) + score;
|
||||
if ( level.teamBased )
|
||||
{
|
||||
level thread score_team_event_monitor( roundScoreToBeat, notify_string, client_notify_string );
|
||||
}
|
||||
else
|
||||
{
|
||||
level thread score_event_monitor( roundScoreToBeat, notify_string, client_notify_string );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function any_team_reach_score( score )
|
||||
{
|
||||
foreach( team in level.teams )
|
||||
{
|
||||
if ( game["teamScores"][team] >= score )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function score_team_event_monitor( score, notify_string, client_notify_string )
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
wait( 0.5 );
|
||||
|
||||
if ( any_team_reach_score( score ) )
|
||||
{
|
||||
event_notify( notify_string, client_notify_string );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function score_event_monitor( score, notify_string, client_notify_string )
|
||||
{
|
||||
for ( ;; )
|
||||
{
|
||||
wait ( 0.5 );
|
||||
|
||||
players = GetPlayers();
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
if ( isdefined( players[i].score ) && players[i].score >= score )
|
||||
{
|
||||
event_notify( notify_string, client_notify_string );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function event_notify( notify_string, client_notify_string )
|
||||
{
|
||||
if ( isdefined( notify_string ) )
|
||||
{
|
||||
level notify( notify_string );
|
||||
}
|
||||
|
||||
if ( isdefined( client_notify_string ) )
|
||||
{
|
||||
util::clientNotify( client_notify_string );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\math_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#precache( "client_fx", "weapon/fx_equip_light_os" );
|
||||
#namespace explosive_bolt;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("explosive_bolt",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
level._effect["crossbow_light"] = "weapon/fx_equip_light_os";
|
||||
|
||||
callback::add_weapon_type( "explosive_bolt", &spawned );
|
||||
}
|
||||
|
||||
function spawned( localClientNum )
|
||||
{
|
||||
if ( self isGrenadeDud() )
|
||||
return;
|
||||
|
||||
self thread fx_think( localClientNum );
|
||||
}
|
||||
|
||||
function fx_think( localClientNum )
|
||||
{
|
||||
self notify( "light_disable" );
|
||||
|
||||
self endon( "entityshutdown" );
|
||||
self endon( "light_disable" );
|
||||
|
||||
self util::waittill_dobj( localClientNum );
|
||||
|
||||
interval = 0.3;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
self stop_light_fx( localClientNum );
|
||||
self start_light_fx( localClientNum );
|
||||
self fullscreen_fx( localClientNum );
|
||||
self PlaySound( localClientNum, "wpn_semtex_alert" );
|
||||
|
||||
util::server_wait( localClientNum, interval, .016, "player_switch" );
|
||||
interval = math::clamp( ( interval / 1.2 ), 0.08, 0.3 );
|
||||
}
|
||||
}
|
||||
|
||||
function start_light_fx( localClientNum )
|
||||
{
|
||||
player = GetLocalPlayer( localClientNum );
|
||||
|
||||
self.fx = PlayFxOnTag( localClientNum, level._effect["crossbow_light"], self, "tag_origin" );
|
||||
}
|
||||
|
||||
function stop_light_fx( localClientNum )
|
||||
{
|
||||
if ( isdefined( self.fx ) && self.fx != 0 )
|
||||
{
|
||||
StopFx( localClientNum, self.fx );
|
||||
self.fx = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function fullscreen_fx( localClientNum )
|
||||
{
|
||||
player = GetLocalPlayer( localClientNum );
|
||||
|
||||
if ( isdefined( player ) )
|
||||
{
|
||||
if ( player GetInKillcam( localClientNum ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if ( player util::is_player_view_linked_to_entity( localClientNum ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( self util::friend_not_foe( localClientNum ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
parent = self GetParentEntity();
|
||||
|
||||
if ( isdefined( parent ) && parent == player )
|
||||
{
|
||||
parent PlayRumbleOnEntity( localClientNum, "buzz_high" );
|
||||
|
||||
// support for this has been removed with the .menu system
|
||||
/*
|
||||
if ( IsSplitscreen() )
|
||||
{
|
||||
AnimateUI( localClientNum, "sticky_grenade_overlay_ss"+localClientNum, "overlay", "pulse", 0 );
|
||||
|
||||
if ( GetDvarint( "ui_hud_hardcore" ) == 0 )
|
||||
{
|
||||
AnimateUI( localClientNum, "stuck_ss"+localClientNum, "explosive_bolt", "pulse", 0 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AnimateUI( localClientNum, "sticky_grenade_overlay"+localClientNum, "overlay", "pulse", 0 );
|
||||
|
||||
if ( GetDvarint( "ui_hud_hardcore" ) == 0 )
|
||||
{
|
||||
AnimateUI( localClientNum, "stuck"+localClientNum, "explosive_bolt", "pulse", 0 );
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_weapons;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#precache( "fx", "weapon/fx_equip_light_os" );
|
||||
|
||||
#namespace explosive_bolt;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("explosive_bolt",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
callback::on_spawned( &on_player_spawned );
|
||||
}
|
||||
|
||||
function on_player_spawned()
|
||||
{
|
||||
self thread begin_other_grenade_tracking();
|
||||
}
|
||||
|
||||
function begin_other_grenade_tracking()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
|
||||
self notify( "boltTrackingStart" );
|
||||
self endon( "boltTrackingStart" );
|
||||
|
||||
weapon_bolt = GetWeapon( "explosive_bolt" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill ( "grenade_fire", grenade, weapon, cookTime );
|
||||
|
||||
if ( grenade util::isHacked() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( weapon == weapon_bolt )
|
||||
{
|
||||
grenade.ownerWeaponAtLaunch = self.currentWeapon;
|
||||
grenade.ownerAdsAtLaunch = ( self PlayerAds() == 1 ? true : false );
|
||||
grenade thread watch_bolt_detonation( self );
|
||||
grenade thread weapons::check_stuck_to_player( true, false, weapon );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function watch_bolt_detonation( owner ) // self == explosive_bolt entity
|
||||
{
|
||||
//self SetTeam( owner.team );
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\visionset_mgr_shared;
|
||||
#using scripts\shared\weapons\_flashgrenades;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace flashgrenades;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("flashgrenades",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__( localClientNum )
|
||||
{
|
||||
flashgrenades::init_shared();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\weapons\_flashgrenades;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace flashgrenades;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("flashgrenades",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
flashgrenades::init_shared();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,488 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\gametypes\_dev;
|
||||
#using scripts\mp\gametypes\_globallogic_utils;
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace gameadvertisement;
|
||||
|
||||
function init()
|
||||
{
|
||||
/#
|
||||
level.sessionAdvertStatus = true;
|
||||
thread sessionAdvertismentUpdateDebugHud();
|
||||
#/
|
||||
|
||||
level.gameAdvertisementRuleScorePercent = GetGametypeSetting( "gameAdvertisementRuleScorePercent" );
|
||||
level.gameAdvertisementRuleTimeLeft = ( 1000 * 60 ) * GetGametypeSetting( "gameAdvertisementRuleTimeLeft" );
|
||||
level.gameAdvertisementRuleRound = GetGametypeSetting( "gameAdvertisementRuleRound" );
|
||||
level.gameAdvertisementRuleRoundsWon = GetGametypeSetting( "gameAdvertisementRuleRoundsWon" );
|
||||
|
||||
thread sessionAdvertisementCheck();
|
||||
}
|
||||
|
||||
|
||||
function setAdvertisedStatus( onOff )
|
||||
{
|
||||
/#
|
||||
level.sessionAdvertStatus = onOff;
|
||||
#/
|
||||
changeAdvertisedStatus( onOff );
|
||||
}
|
||||
|
||||
function sessionAdvertisementCheck()
|
||||
{
|
||||
if( SessionModeIsPrivate() )
|
||||
return;
|
||||
|
||||
runRules = getGameTypeRules();
|
||||
|
||||
if( !isdefined( runRules ) )
|
||||
return;
|
||||
|
||||
level endon( "game_end" );
|
||||
|
||||
level waittill( "prematch_over" );
|
||||
|
||||
currentAdvertisedStatus = undefined;
|
||||
while( true )
|
||||
{
|
||||
sessionAdvertCheckwait = GetDvarInt( "sessionAdvertCheckwait", 1 );
|
||||
|
||||
wait( sessionAdvertCheckwait );
|
||||
|
||||
advertise = [[runRules]]();
|
||||
if ( !isdefined( currentAdvertisedStatus ) || ( isdefined( advertise ) && ( currentAdvertisedStatus != advertise ) ) )
|
||||
{
|
||||
setAdvertisedStatus( advertise );
|
||||
}
|
||||
currentAdvertisedStatus = advertise;
|
||||
}
|
||||
}
|
||||
|
||||
function getGameTypeRules()
|
||||
{
|
||||
gametype = level.gametype;
|
||||
|
||||
switch( gametype )
|
||||
{
|
||||
case "gun":
|
||||
return &gun_rules;
|
||||
default:
|
||||
return &default_rules;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
function teamScoreLimitCheck( ruleScorePercent, debug_count )
|
||||
{
|
||||
scoreLimit = 0;
|
||||
|
||||
//====================================================================
|
||||
// score check
|
||||
|
||||
if ( level.roundScoreLimit )
|
||||
{
|
||||
scoreLimit = util::get_current_round_score_limit();
|
||||
}
|
||||
else if ( level.scoreLimit )
|
||||
{
|
||||
scoreLimit = level.scoreLimit;
|
||||
}
|
||||
|
||||
if ( scoreLimit )
|
||||
{
|
||||
minScorePercentageLeft = 100;
|
||||
|
||||
foreach ( team in level.teams )
|
||||
{
|
||||
scorePercentageLeft = 100 - ( ( game[ "teamScores" ][ team ] / scoreLimit ) * 100 );
|
||||
|
||||
if( minScorePercentageLeft > scorePercentageLeft )
|
||||
minScorePercentageLeft = scorePercentageLeft;
|
||||
|
||||
if( ruleScorePercent >= scorePercentageLeft )
|
||||
{
|
||||
/#
|
||||
debug_count = updateDebugHud( debug_count, "Score Percentage Left: ", int( scorePercentageLeft ) );
|
||||
#/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/#
|
||||
debug_count = updateDebugHud( debug_count, "Score Percentage Left: ", int( minScorePercentageLeft ) );
|
||||
#/
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function timeLimitCheck( ruleTimeLeft )
|
||||
{
|
||||
maxTime = level.timeLimit;
|
||||
|
||||
if( maxTime != 0 )
|
||||
{
|
||||
timeLeft = globallogic_utils::getTimeRemaining();
|
||||
|
||||
if( ruleTimeLeft >= timeLeft )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//========================================================================================================================================
|
||||
//========================================================================================================================================
|
||||
//========================================================================================================================================
|
||||
|
||||
function default_rules()
|
||||
{
|
||||
|
||||
//====================================================================
|
||||
|
||||
currentRound = game[ "roundsplayed" ] + 1;
|
||||
|
||||
debug_count = 1;
|
||||
|
||||
//====================================================================
|
||||
|
||||
|
||||
//====================================================================
|
||||
// score check
|
||||
|
||||
if( level.gameAdvertisementRuleScorePercent )
|
||||
{
|
||||
/#
|
||||
debug_count = updateDebugHud( debug_count, "Any player/team is within percent of score cap: ", level.gameAdvertisementRuleScorePercent );
|
||||
#/
|
||||
if ( level.teambased )
|
||||
{
|
||||
if ( (currentRound >= (level.gameAdvertisementRuleRound - 1)) )
|
||||
{
|
||||
if ( teamScoreLimitCheck( level.gameAdvertisementRuleScorePercent, debug_count ) == false )
|
||||
return false;
|
||||
|
||||
/#
|
||||
debug_count++;
|
||||
#/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( level.scoreLimit )
|
||||
{
|
||||
highestScore = 0;
|
||||
players = GetPlayers();
|
||||
|
||||
for( i = 0; i < players.size; i++)
|
||||
{
|
||||
if( players[i].pointstowin > highestScore )
|
||||
highestScore = players[i].pointstowin;
|
||||
}
|
||||
|
||||
scorePercentageLeft = 100 - ( ( highestScore / level.scoreLimit ) * 100 );
|
||||
|
||||
/#
|
||||
debug_count = updateDebugHud( debug_count, "Score Percentage Left: ", int( scorePercentageLeft ) );
|
||||
#/
|
||||
|
||||
if( level.gameAdvertisementRuleScorePercent >= scorePercentageLeft )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
// time left check
|
||||
|
||||
if( level.gameAdvertisementRuleTimeLeft && (currentRound >= (level.gameAdvertisementRuleRound - 1)) )
|
||||
{
|
||||
/#
|
||||
debug_count = updateDebugHud( debug_count, "Time limit has less than minutes remaining: ", level.gameAdvertisementRuleTimeLeft/( 1000 * 60 ) );
|
||||
#/
|
||||
if ( timeLimitCheck( level.gameAdvertisementRuleTimeLeft ) == false )
|
||||
return false;
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
// round check
|
||||
|
||||
if( level.gameAdvertisementRuleRound )
|
||||
{
|
||||
/#
|
||||
debug_count = updateDebugHud( debug_count, "Is round: ", level.gameAdvertisementRuleRound );
|
||||
debug_count = updateDebugHud( debug_count, "Current Round: ", currentRound );
|
||||
#/
|
||||
if ( level.gameAdvertisementRuleRound <= currentRound )
|
||||
return false;
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
// round won check
|
||||
|
||||
if ( level.gameAdvertisementRuleRoundsWon )
|
||||
{
|
||||
/#
|
||||
debug_count = updateDebugHud( debug_count, "Any team has won rounds: ", level.gameAdvertisementRuleRoundsWon );
|
||||
#/
|
||||
maxRoundsWon = 0;
|
||||
foreach ( team in level.teams )
|
||||
{
|
||||
roundsWon = game[ "teamScores" ][ team ];
|
||||
|
||||
if( maxRoundsWon < roundsWon )
|
||||
maxRoundsWon = roundsWon;
|
||||
|
||||
if( level.gameAdvertisementRuleRoundsWon <= roundsWon )
|
||||
{
|
||||
/#
|
||||
debug_count = updateDebugHud( debug_count, "Max Rounds Won: ", maxRoundsWon );
|
||||
#/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/#
|
||||
debug_count = updateDebugHud( debug_count, "Max Rounds Won: ", maxRoundsWon );
|
||||
#/
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function gun_rules()
|
||||
{
|
||||
// Any player is within 3 weapons from winning
|
||||
|
||||
//====================================================================
|
||||
|
||||
ruleWeaponsLeft = 3; // within 3 weapons of winning
|
||||
|
||||
//====================================================================
|
||||
|
||||
/#
|
||||
updateDebugHud( 1, "Any player is within X weapons from winning: ", ruleWeaponsLeft );
|
||||
#/
|
||||
|
||||
//====================================================================
|
||||
// weapons check
|
||||
minWeaponsLeft = level.gunProgression.size;
|
||||
|
||||
foreach ( player in level.activePlayers )
|
||||
{
|
||||
if ( !isdefined( player ) )
|
||||
continue;
|
||||
|
||||
if ( !isdefined( player.gunProgress ) )
|
||||
continue;
|
||||
|
||||
weaponsLeft = level.gunProgression.size - player.gunProgress;
|
||||
|
||||
if( minWeaponsLeft > weaponsLeft )
|
||||
minWeaponsLeft = weaponsLeft;
|
||||
|
||||
if( ruleWeaponsLeft >= minWeaponsLeft )
|
||||
{
|
||||
/#
|
||||
updateDebugHud( 3, "Weapons Left: ", minWeaponsLeft );
|
||||
#/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/#
|
||||
updateDebugHud( 3, "Weapons Left: ", minWeaponsLeft );
|
||||
#/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//========================================================================================================================================
|
||||
//========================================================================================================================================
|
||||
//========================================================================================================================================
|
||||
|
||||
/#
|
||||
function sessionAdvertismentCreateDebugHud( lineNum, alignX )
|
||||
{
|
||||
debug_hud = dev::new_hud( "session_advert", "debug_hud", 0, 0, 1 );
|
||||
debug_hud.hidewheninmenu = true;
|
||||
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 = true;
|
||||
debug_hud.font = "default";
|
||||
debug_hud.fontScale = 1.5;
|
||||
debug_hud.color = ( 1.0, 1.0, 1.0 );
|
||||
debug_hud.alpha = 1;
|
||||
|
||||
debug_hud setText( "" );
|
||||
|
||||
return debug_hud;
|
||||
}
|
||||
|
||||
function 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;
|
||||
}
|
||||
return hudIndex+1;
|
||||
}
|
||||
|
||||
function 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( true )
|
||||
{
|
||||
wait( 1 );
|
||||
|
||||
showDebugHud = GetDvarInt( "sessionAdvertShowDebugHud", 0 );
|
||||
|
||||
//====================================================================
|
||||
|
||||
level.sessionAdvertHud_0_text = "Session is advertised";
|
||||
if( level.sessionAdvertStatus == false )
|
||||
level.sessionAdvertHud_0_text = "Session is not advertised";
|
||||
|
||||
//====================================================================
|
||||
|
||||
if( !isdefined( sessionAdvertHud_0 ) && showDebugHud != 0 )
|
||||
{
|
||||
host = util::getHostPlayer();
|
||||
|
||||
if( !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 = ( 0.0, 0.5, 0.0 );
|
||||
sessionAdvertHud_1B.color = ( 0.0, 0.5, 0.0 );
|
||||
sessionAdvertHud_2A.color = ( 0.0, 0.5, 0.0 );
|
||||
sessionAdvertHud_2B.color = ( 0.0, 0.5, 0.0 );
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( level.sessionAdvertStatus == true )
|
||||
sessionAdvertHud_0.color = ( 1.0, 1.0, 1.0 );
|
||||
else
|
||||
sessionAdvertHud_0.color = ( 0.9, 0.0, 0.0 );
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#/
|
||||
+459
@@ -0,0 +1,459 @@
|
||||
Line truncated
|
||||
|
||||
#using scripts\shared\rank_shared;
|
||||
|
||||
#using scripts\shared\bots\_bot;
|
||||
|
||||
#namespace gamerep;
|
||||
|
||||
function init()
|
||||
{
|
||||
if ( !isGameRepEnabled() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isGameRepInitialized() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
game["gameRepInitialized"] = true;
|
||||
|
||||
game["gameRep"]["players"] = [];
|
||||
game["gameRep"]["playerNames"] = [];
|
||||
game["gameRep"]["max"] = [];
|
||||
game["gameRep"]["playerCount"] = 0;
|
||||
|
||||
gameRepInitializeParams();
|
||||
}
|
||||
|
||||
function isGameRepInitialized()
|
||||
{
|
||||
if ( !isdefined( game["gameRepInitialized"] ) || !game["gameRepInitialized"] )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function isGameRepEnabled()
|
||||
{
|
||||
if( bot::is_bot_ranked_match() )
|
||||
return false;
|
||||
|
||||
if ( !level.rankedMatch )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function gameRepInitializeParams()
|
||||
{
|
||||
// this should match the thresholdExceeded_e in live_anticheat.cpp
|
||||
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;
|
||||
|
||||
// Parameter Names (for individual players)
|
||||
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";
|
||||
|
||||
// New Param additions go here.
|
||||
|
||||
// Parameters which we want to track, but not use for reporting. (for individual players)
|
||||
game["gameRep"]["ignoreParams"] = [];
|
||||
game["gameRep"]["ignoreParams"][0] = "totalTimePlayed";
|
||||
|
||||
// Game limit parameters
|
||||
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"] = [];
|
||||
|
||||
// Score
|
||||
game["gameRep"]["gameLimit"]["id"]["score"] = THRESHOLD_EXCEEDED_SCORE;
|
||||
game["gameRep"]["gameLimit"]["default"]["score"] = 20000;
|
||||
|
||||
// Score per min
|
||||
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;
|
||||
|
||||
// Kills
|
||||
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;
|
||||
|
||||
// Deaths
|
||||
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;
|
||||
|
||||
// KD Ratio
|
||||
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;
|
||||
|
||||
// Kills per min
|
||||
game["gameRep"]["gameLimit"]["id"]["killsPerMin"] = THRESHOLD_EXCEEDED_KILLS_PER_MIN;
|
||||
game["gameRep"]["gameLimit"]["default"]["killsPerMin"] = 15;
|
||||
|
||||
// Plants
|
||||
game["gameRep"]["gameLimit"]["id"]["plants"] = THRESHOLD_EXCEEDED_PLANTS;
|
||||
game["gameRep"]["gameLimit"]["default"]["plants"] = 10;
|
||||
|
||||
// Defuses
|
||||
game["gameRep"]["gameLimit"]["id"]["defuses"] = THRESHOLD_EXCEEDED_DEFUSES;
|
||||
game["gameRep"]["gameLimit"]["default"]["defuses"] = 10;
|
||||
|
||||
// Captures
|
||||
game["gameRep"]["gameLimit"]["id"]["captures"] = THRESHOLD_EXCEEDED_CAPTURES;
|
||||
game["gameRep"]["gameLimit"]["default"]["captures"] = 30;
|
||||
|
||||
// Defends
|
||||
game["gameRep"]["gameLimit"]["id"]["defends"] = THRESHOLD_EXCEEDED_DEFENDS;
|
||||
game["gameRep"]["gameLimit"]["default"]["defends"] = 50;
|
||||
|
||||
// Total Time played (in sec)
|
||||
game["gameRep"]["gameLimit"]["id"]["totalTimePlayed"] = THRESHOLD_EXCEEDED_TOTAL_TIME_PLAYED;
|
||||
game["gameRep"]["gameLimit"]["default"]["totalTimePlayed"] = 10 * 60;
|
||||
game["gameRep"]["gameLimit"]["dom"]["totalTimePlayed"] = 10 * 60;
|
||||
game["gameRep"]["gameLimit"]["dem"]["totalTimePlayed"] = 19 * 60;
|
||||
|
||||
// Tactical Insertion use
|
||||
game["gameRep"]["gameLimit"]["id"]["tacticalInsertions"] = THRESHOLD_EXCEEDED_TACTICAL_INSERTION_USE;
|
||||
game["gameRep"]["gameLimit"]["default"]["tacticalInsertions"] = 20;
|
||||
|
||||
// Join attempts
|
||||
game["gameRep"]["gameLimit"]["id"]["joinAttempts"] = THRESHOLD_EXCEEDED_JOIN_ATTEMPTS;
|
||||
game["gameRep"]["gameLimit"]["default"]["joinAttempts"] = 3;
|
||||
|
||||
// XP
|
||||
game["gameRep"]["gameLimit"]["id"]["xp"] = THRESHOLD_EXCEEDED_XP;
|
||||
game["gameRep"]["gameLimit"]["default"]["xp"] = 25000;
|
||||
|
||||
// Splitscreen (total)
|
||||
game["gameRep"]["gameLimit"]["id"]["splitscreen"] = THRESHOLD_EXCEEDED_SPLITSCREEN;
|
||||
game["gameRep"]["gameLimit"]["default"]["splitscreen"] = 8;
|
||||
|
||||
}
|
||||
|
||||
function gameRepPlayerConnected()
|
||||
{
|
||||
if ( !isGameRepEnabled() )
|
||||
return;
|
||||
|
||||
name = self.name;
|
||||
|
||||
/#
|
||||
// println( "gameRepPlayerConnected() for player " + name );
|
||||
#/
|
||||
|
||||
if ( !isdefined( game["gameRep"]["players"][name] ) )
|
||||
{
|
||||
game["gameRep"]["players"][name] = [];
|
||||
|
||||
for( j = 0; j < game["gameRep"]["params"].size; j++ )
|
||||
{
|
||||
paramName = game["gameRep"]["params"][j];
|
||||
game["gameRep"]["players"][name][ paramName ] = 0;
|
||||
}
|
||||
|
||||
game["gameRep"]["players"][name]["splitscreen"] = self IsSplitScreen();
|
||||
game["gameRep"]["players"][name]["joinAttempts"] = 1;
|
||||
game["gameRep"]["players"][name]["connected"] = true;
|
||||
game["gameRep"]["players"][name]["xpStart"] = self rank::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"] = true;
|
||||
game["gameRep"]["players"][name]["xpStart"] = self rank::getRankXpStat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function gameRepPlayerDisconnected()
|
||||
{
|
||||
if ( !isGameRepEnabled() )
|
||||
return;
|
||||
|
||||
name = self.name;
|
||||
|
||||
if( !isdefined( game["gameRep"]["players"][name] )
|
||||
|| !isdefined( self.pers["summary"] ) )
|
||||
{
|
||||
// we are probably migrating
|
||||
return;
|
||||
}
|
||||
|
||||
/#
|
||||
// println( "gameRepPlayerDisconnected() for player " + name );
|
||||
#/
|
||||
|
||||
self gameRepUpdateNonPersistentPlayerInformation();
|
||||
self gameRepUpdatePersistentPlayerInformation();
|
||||
game["gameRep"]["players"][name]["connected"] = false;
|
||||
}
|
||||
|
||||
function 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;
|
||||
|
||||
// New Non-Persistent Param Calculations go here.
|
||||
|
||||
/*println( "gameRepUpdatePersistentPlayerInformation() for player " + name );
|
||||
paramName = "totalTimePlayed";
|
||||
println( "Param: " + paramName + "Value: " + getParamValueForPlayer( name, paramName ) );*/
|
||||
}
|
||||
|
||||
function 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 rank::getRankXpStat() - game["gameRep"]["players"][name]["xpStart"];
|
||||
game["gameRep"]["players"][name]["xpStart"] = self rank::getRankXpStat();
|
||||
|
||||
// New Persistent Param Calculations go here.
|
||||
|
||||
/*println( "gameRepUpdatePersistentPlayerInformation() for player " + name );
|
||||
for ( j = 0; j < game["gameRep"]["params"].size; j++ )
|
||||
{
|
||||
paramName = game["gameRep"]["params"][j];
|
||||
if ( isGameRepParamValid( paramName ) )
|
||||
println( "Param: " + paramName + "Value: " + getParamValueForPlayer( name, paramName ) );
|
||||
}*/
|
||||
}
|
||||
|
||||
function getParamValueForPlayer( playerName, paramName )
|
||||
{
|
||||
if ( isdefined( game["gameRep"]["players"][playerName][paramName] ) )
|
||||
return game["gameRep"]["players"][playerName][paramName];
|
||||
|
||||
assertmsg( "Unknown parameter " + paramName + "for individual player" );
|
||||
}
|
||||
|
||||
function isGameRepParamValid( paramName )
|
||||
{
|
||||
gametype = level.gametype;
|
||||
|
||||
if ( !isdefined( game["gameRep"] ) )
|
||||
return false;
|
||||
|
||||
if ( !isdefined( game["gameRep"]["gameLimit"] ) )
|
||||
return false;
|
||||
|
||||
if ( !isdefined( game["gameRep"]["gameLimit"][gametype] ) )
|
||||
return false;
|
||||
|
||||
if ( !isdefined( game["gameRep"]["gameLimit"][gametype][paramName] ) )
|
||||
return false;
|
||||
|
||||
if ( !isdefined( game["gameRep"]["gameLimit"][gametype][paramName] ) && !isdefined( game["gameRep"]["gameLimit"]["default"][paramName] ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function isGameRepParamIgnoredForReporting( paramName )
|
||||
{
|
||||
if ( isdefined( game["gameRep"]["ignoreParams"][paramName] ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function 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." );
|
||||
}
|
||||
|
||||
function 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;
|
||||
}
|
||||
}
|
||||
|
||||
function gameRepUpdateInformationForRound()
|
||||
{
|
||||
if ( !isGameRepEnabled() )
|
||||
return;
|
||||
|
||||
// We will update only non persistent data between rounds.
|
||||
players = GetPlayers();
|
||||
for( i = 0; i < players.size; i++ )
|
||||
{
|
||||
player = players[i];
|
||||
player gameRepUpdateNonPersistentPlayerInformation();
|
||||
}
|
||||
}
|
||||
|
||||
function gameRepAnalyzeAndReport()
|
||||
{
|
||||
if ( !isGameRepEnabled() )
|
||||
return;
|
||||
|
||||
// Non persistent data is already updated at the end of the round.
|
||||
// So, lets update only the persistent data for the current players.
|
||||
players = GetPlayers();
|
||||
for( i = 0; i < players.size; i++ )
|
||||
{
|
||||
player = players[i];
|
||||
player gameRepUpdatePersistentPlayerInformation();
|
||||
}
|
||||
|
||||
splitscreenPlayerCount = 0;
|
||||
// Set the maximums for this game (comparing for all players)
|
||||
for ( i = 0; i < game["gameRep"]["playerNames"].size; i++ )
|
||||
{
|
||||
playerName = game["gameRep"]["playerNames"][i];
|
||||
|
||||
// Individual Params
|
||||
for ( j = 0; j < game["gameRep"]["params"].size; j++ )
|
||||
{
|
||||
paramName = game["gameRep"]["params"][j];
|
||||
if ( isGameRepParamValid( paramName ) )
|
||||
setMaximumParamValueForCurrentGame( paramName, getParamValueForPlayer( playerName, paramName ) );
|
||||
}
|
||||
|
||||
// Splitscreen Players count
|
||||
paramName = "splitscreen";
|
||||
splitscreenPlayerCount += getParamValueForPlayer( playerName, paramName );
|
||||
}
|
||||
|
||||
setMaximumParamValueForCurrentGame( paramName, splitscreenPlayerCount );
|
||||
|
||||
// Check if any of the params reached the maximum limit.
|
||||
// If any of them reaches the maximum limit, then we will prepare and report this film.
|
||||
for ( j = 0; j < game["gameRep"]["params"].size; j++ )
|
||||
{
|
||||
paramName = game["gameRep"]["params"][j];
|
||||
|
||||
//println( "Param: " + paramName + " Max: " + game["gameRep"]["max"][ paramName ] + " Limit: " + getGameRepParamLimit( paramName ) );
|
||||
|
||||
if ( isGameRepParamValid( paramName ) && game["gameRep"]["max"][ paramName ] >= getGameRepParamLimit( paramName ) )
|
||||
{
|
||||
gameRepPrepareAndReport( paramName );
|
||||
}
|
||||
}
|
||||
|
||||
paramName = "splitscreen";
|
||||
if ( game["gameRep"]["max"][ paramName ] >= getGameRepParamLimit( paramName ) )
|
||||
{
|
||||
gameRepPrepareAndReport( paramName );
|
||||
}
|
||||
}
|
||||
|
||||
function gameRepPrepareAndReport( paramName )
|
||||
{
|
||||
if ( !isdefined( game["gameRep"]["gameLimit"]["id"][paramName] ) )
|
||||
return;
|
||||
|
||||
if ( isGameRepParamIgnoredForReporting( paramName ) )
|
||||
return;
|
||||
|
||||
gameRepThresholdExceeded( game["gameRep"]["gameLimit"]["id"][ paramName ] );
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\fx_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#namespace global_fx;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("global_fx",&__init__,&main,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
wind_initial_setting();
|
||||
}
|
||||
|
||||
function main()
|
||||
{
|
||||
check_for_wind_override();
|
||||
}
|
||||
|
||||
function wind_initial_setting()
|
||||
{
|
||||
SetSavedDvar( "enable_global_wind", 0 ); // enable wind for your level
|
||||
SetSavedDvar( "wind_global_vector", "0 0 0" ); // change "0 0 0" to your wind vector
|
||||
SetSavedDvar( "wind_global_low_altitude", 0 ); // change 0 to your wind's lower bound
|
||||
SetSavedDvar( "wind_global_hi_altitude", 10000 ); // change 10000 to your wind's upper bound
|
||||
SetSavedDvar( "wind_global_low_strength_percent", 0.5 ); // change 0.5 to your desired wind strength percentage
|
||||
}
|
||||
|
||||
function check_for_wind_override()
|
||||
{
|
||||
//Allow for level overrides of global wind settings
|
||||
if( isdefined( level.custom_wind_callback ) )
|
||||
{
|
||||
level thread [[level.custom_wind_callback]]();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\audio_shared;
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\_explode;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#precache( "client_fx", "weapon/fx_hero_grvity_spk_grnd_hit_dust" );
|
||||
|
||||
#namespace gravity_spikes;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("gravity_spikes",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
level._effect["gravity_spike_dust"] = "weapon/fx_hero_grvity_spk_grnd_hit_dust";
|
||||
level.gravity_spike_table = "surface_explosion_gravityspikes";
|
||||
|
||||
level thread watchForGravitySpikeExplosion();
|
||||
|
||||
level.dirt_enable_gravity_spikes = GetDvarInt( "scr_dirt_enable_gravity_spikes", 0 );
|
||||
/#
|
||||
level thread updateDvars();
|
||||
#/
|
||||
}
|
||||
|
||||
/#
|
||||
function updateDvars()
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
level.dirt_enable_gravity_spikes = GetDvarInt( "scr_dirt_enable_gravity_spikes", level.dirt_enable_gravity_spikes );
|
||||
|
||||
wait(1.0);
|
||||
}
|
||||
}
|
||||
#/
|
||||
|
||||
function watchForGravitySpikeExplosion()
|
||||
{
|
||||
if ( GetActiveLocalClients() > 1 )
|
||||
return;
|
||||
|
||||
weapon_proximity = GetWeapon( "hero_gravityspikes" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
level waittill( "explode", localClientNum, position, mod, weapon, owner_cent );
|
||||
|
||||
if ( weapon.rootWeapon != weapon_proximity )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( isdefined(owner_cent) && ( GetLocalPlayer( localClientNum ) == owner_cent ) && level.dirt_enable_gravity_spikes )
|
||||
{
|
||||
owner_cent thread explode::dothedirty( localClientNum, 0, 1.0, 0, 1000, 500 );
|
||||
}
|
||||
|
||||
thread do_gravity_spike_fx( localClientNum, owner_cent, weapon, position );
|
||||
thread audio::doRattle(position,200,700);
|
||||
}
|
||||
}
|
||||
|
||||
function do_gravity_spike_fx( localClientNum, owner, weapon, position )
|
||||
{
|
||||
// this value will bring in the outermost circle so the effects don't spawn
|
||||
// right on the outer edge of the explosion
|
||||
radius_of_effect = 40;
|
||||
|
||||
number_of_circles = 3;
|
||||
base_number_of_effects = 3;
|
||||
additional_number_of_effects_per_circle = 7;
|
||||
|
||||
explosion_radius = weapon.explosionRadius;
|
||||
radius_per_circle = ( explosion_radius - radius_of_effect ) / number_of_circles;
|
||||
|
||||
for ( circle = 0; circle < number_of_circles; circle++ )
|
||||
{
|
||||
wait( 0.1 );
|
||||
radius_for_this_circle = radius_per_circle * (circle + 1);
|
||||
number_for_this_circle = base_number_of_effects + (additional_number_of_effects_per_circle * circle);
|
||||
thread do_gravity_spike_fx_circle( localClientNum, owner, position, radius_for_this_circle, number_for_this_circle );
|
||||
}
|
||||
}
|
||||
|
||||
function getIdealLocationForFX( startPos, fxIndex, fxCount, defaultDistance, rotation )
|
||||
{
|
||||
currentAngle = ( ( 360 / fxCount ) * fxIndex );
|
||||
cosCurrent = cos( currentAngle + rotation );
|
||||
sinCurrent = sin( currentAngle + rotation );
|
||||
|
||||
return startPos + ( defaultDistance * cosCurrent, defaultDistance * sinCurrent, 0 );
|
||||
}
|
||||
|
||||
function randomizeLocation( startPos, max_x_offset, max_y_offset )
|
||||
{
|
||||
half_x = int(max_x_offset / 2);
|
||||
half_y = int(max_y_offset / 2);
|
||||
rand_x = RandomIntRange( -half_x, half_x );
|
||||
rand_y = RandomIntRange( -half_y, half_y );
|
||||
|
||||
return startPos + ( rand_x, rand_y, 0 );
|
||||
}
|
||||
|
||||
function ground_trace( startPos, owner )
|
||||
{
|
||||
trace_height = 50;
|
||||
trace_depth = 100;
|
||||
|
||||
return bullettrace( startPos + ( 0,0,trace_height ), startPos - ( 0,0,trace_depth ), false, owner );
|
||||
}
|
||||
|
||||
|
||||
function do_gravity_spike_fx_circle( localClientNum, owner, center, radius, count )
|
||||
{
|
||||
segment = 360 / count;
|
||||
up = ( 0,0,1 );
|
||||
|
||||
randomization = 40;
|
||||
sphere_size = 5;
|
||||
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
fx_position = getIdealLocationForFX( center, i, count, radius, 0 );
|
||||
/#
|
||||
// Sphere( fx_position, sphere_size, CYAN, 1, true, 8, 300 );
|
||||
#/
|
||||
fx_position = randomizeLocation( fx_position, randomization, randomization );
|
||||
|
||||
trace = ground_trace( fx_position, owner );
|
||||
|
||||
if ( trace["fraction"] < 1.0 )
|
||||
{
|
||||
/#
|
||||
// Sphere( fx_position, sphere_size, PURPLE, 1, true, 8, 300 );
|
||||
// Sphere( trace["position"], sphere_size, YELLOW, 1, true, 8, 300 );
|
||||
#/
|
||||
|
||||
fx = GetFXFromSurfaceTable( level.gravity_spike_table, trace["surfacetype"] );
|
||||
|
||||
if ( isdefined( fx ) )
|
||||
{
|
||||
angles = ( 0, RandomIntRange(0,359), 0 );
|
||||
forward = AnglesToForward( angles );
|
||||
|
||||
normal = trace["normal"];
|
||||
if ( LengthSquared( normal ) == 0 )
|
||||
{
|
||||
normal = ( 1, 0, 0);
|
||||
}
|
||||
PlayFx( localClientNum, fx, trace["position"], normal, forward );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/#
|
||||
// Line( fx_position + ( 0,0,50 ), fx_position - ( 0,0,50 ), RED, 1, false, 300 );
|
||||
#/
|
||||
}
|
||||
|
||||
{wait(.016);};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_hacker_tool;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#namespace hacker_tool;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("hacker_tool",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
hacker_tool::init_shared();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_hacker_tool;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace hacker_tool;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("hacker_tool",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
hacker_tool::init_shared();
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_heatseekingmissile;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace heatseekingmissile;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("heatseekingmissile",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
level.lockOnCloseRange = 220;
|
||||
level.lockOnCloseRadiusScaler = 1;
|
||||
|
||||
heatseekingmissile::init_shared();
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,23 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_hive_gun;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace hive_gun;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("hive_gun",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
hive_gun::init_shared();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\weapons\_hive_gun;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace hive_gun;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("hive_gun",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
hive_gun::init_shared();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,488 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\challenges_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\damagefeedback_shared;
|
||||
#using scripts\shared\entityheadicons_shared;
|
||||
#using scripts\shared\killcam_shared;
|
||||
#using scripts\shared\scoreevents_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_tacticalinsertion;
|
||||
#using scripts\shared\weapons\_weaponobjects;
|
||||
#using scripts\shared\_burnplayer;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
|
||||
#namespace incendiary;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("incendiary_grenade",&init_shared,undefined,undefined); }
|
||||
|
||||
|
||||
function init_shared()
|
||||
{
|
||||
level.incendiaryfireDamage = GetDvarInt( "scr_incendiaryfireDamage", 35 ); // how much damage will the fire do each tick
|
||||
level.incendiaryfireDamageHardcore = GetDvarInt( "scr_incendiaryfireDamageHardcore", 15 ); // how much damage will the fire do each tick in hardcore
|
||||
level.incendiaryfireDuration = GetDvarInt ("scr_incendiaryfireDuration", 5 ); // time damage triggers will last.
|
||||
level.incendiaryfxDuration = GetDvarFloat( "scr_incendiaryfxDuration", 0.4 ); // Incendiary fx duration
|
||||
level.incendiaryDamageRadius = GetDvarInt( "scr_incendiaryDamageRadius", 125 ); // radius of individual damages
|
||||
level.incendiaryfireDamageTickTime = GetDvarFloat( "scr_incendiaryfireDamageTickTime", 1 ); // time between damage hits
|
||||
|
||||
|
||||
level.incendiaryDamageThisTick = [];
|
||||
|
||||
callback::on_spawned( &create_incendiary_watcher );
|
||||
}
|
||||
|
||||
/#
|
||||
function updateIncendiaryFromDvars()
|
||||
{
|
||||
level.incendiaryfireDamage = GetDvarInt( "scr_incendiaryfireDamage", level.incendiaryfireDamage );
|
||||
level.incendiaryfireDamageHardcore = GetDvarInt( "scr_incendiaryfireDamageHardcore", level.incendiaryfireDamageHardcore );
|
||||
level.incendiaryfireDuration = GetDvarInt( "scr_incendiaryfireDuration", level.incendiaryfireDuration );
|
||||
level.incendiaryDamageRadius = GetDvarInt( "scr_incendiaryDamageRadius", level.incendiaryDamageRadius );
|
||||
level.incendiaryfireDamageTickTime = GetDvarFloat( "scr_incendiaryfireDamageTickTime", level.incendiaryfireDamageTickTime );
|
||||
level.incendiaryfxDuration = GetDvarFloat( "scr_incendiaryfxDuration", level.incendiaryfxDuration );
|
||||
}
|
||||
#/
|
||||
|
||||
function create_incendiary_watcher() // self == player
|
||||
{
|
||||
watcher = self weaponobjects::createUseWeaponObjectWatcher( "incendiary_grenade", self.team );
|
||||
|
||||
watcher.onSpawn = &incendiary_system_spawn;
|
||||
}
|
||||
|
||||
function incendiary_system_spawn( watcher, player ) // self == incendiary grenade
|
||||
{
|
||||
player endon( "death" );
|
||||
player endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
player AddWeaponStat( self.weapon, "used", 1 );
|
||||
thread watchForExplode( player );
|
||||
}
|
||||
|
||||
|
||||
function watchForExplode( owner )
|
||||
{
|
||||
self endon( "hacked" );
|
||||
self endon( "delete" );
|
||||
|
||||
killCamEnt = spawn( "script_model", self.origin );
|
||||
killCamEnt util::deleteAfterTime( 15.0 );
|
||||
killCamEnt.startTime = gettime();
|
||||
killCamEnt linkto( self );
|
||||
killCamEnt setWeapon( self.weapon );
|
||||
|
||||
killcamEnt killcam::store_killcam_entity_on_entity(self);
|
||||
|
||||
self waittill( "projectile_impact_explode", origin, normal, surface );
|
||||
killCamEnt unlink();
|
||||
/#
|
||||
updateIncendiaryFromDvars();
|
||||
#/
|
||||
PlaySoundAtPosition ("wpn_incendiary_core_start" ,self.origin);
|
||||
|
||||
generateLocations( origin, owner, normal, killCamEnt );
|
||||
}
|
||||
|
||||
function getstepoutdistance( normal )
|
||||
{
|
||||
if ( normal[2] < 0.5 )
|
||||
{
|
||||
stepoutdistance = normal * GetDvarInt( "scr_incendiary_stepout_wall", 50 );
|
||||
}
|
||||
else
|
||||
{
|
||||
stepoutdistance = normal * GetDvarInt( "scr_incendiary_stepout_ground", 12 );
|
||||
}
|
||||
return stepoutdistance;
|
||||
}
|
||||
|
||||
function generateLocations( position, owner, normal, killCamEnt )
|
||||
{
|
||||
startPos = position + getstepoutdistance( normal );
|
||||
desiredEndPos = startPos + ( 0, 0, 60 );
|
||||
physTrace = PhysicsTrace( startPos, desiredEndPos, ( -4, -4, -4 ), ( 4, 4, 4 ), self, (1 << 0) );
|
||||
goalPos = ( ( physTrace[ "fraction" ] < 1 ) ? physTrace[ "position"] : desiredEndPos );
|
||||
|
||||
killCamEnt moveto( goalPos, 0.5 );
|
||||
rotation = RandomInt( 360 );
|
||||
|
||||
if ( normal[2] < 0.1 ) // vertical wall
|
||||
{
|
||||
black = ( 0.1, 0.1, 0.1 );
|
||||
|
||||
trace = hitPos( startPos, startpos + ( -normal * 70 ) + ( 0,0, -1 ) * 70, black );
|
||||
tracePosition = trace["position"];
|
||||
incendiaryGrenade = GetWeapon( "incendiary_fire" );
|
||||
|
||||
if ( trace["fraction"] < 0.9 )
|
||||
{
|
||||
wallnormal = trace["normal"];
|
||||
SpawnTimedFX( incendiaryGrenade, trace["position"], wallnormal, level.incendiaryfireDuration, self.team );
|
||||
}
|
||||
}
|
||||
|
||||
fxCount = GetDvarInt( "scr_incendiary_fx_count", 6 );
|
||||
spawnAllLocs( owner, startPos, normal, 1, rotation, killcament, fxCount );
|
||||
}
|
||||
|
||||
function getLocationForFX( startPos, fxIndex, fxCount, defaultDistance, rotation )
|
||||
{
|
||||
currentAngle = ( ( 360 / fxCount ) * fxIndex );
|
||||
cosCurrent = cos( currentAngle + rotation );
|
||||
sinCurrent = sin( currentAngle + rotation );
|
||||
|
||||
return startPos + ( defaultDistance * cosCurrent, defaultDistance * sinCurrent, 0 );
|
||||
}
|
||||
|
||||
function spawnAllLocs( owner, startPos, normal, multiplier, rotation, killcament, fxCount )
|
||||
{
|
||||
defaultDistance = GetDvarInt( "scr_incendiary_trace_distance", 220 ) * multiplier;
|
||||
defaultDropDistance = GetDvarInt( "scr_incendiary_trace_down_distance", 90 );
|
||||
|
||||
// DROCHE:TODO
|
||||
// if we are going to keep this grenade this should be moved to code
|
||||
|
||||
colorArray = [];
|
||||
colorArray[colorArray.size] = ( 0.9, 0.2, 0.2 );
|
||||
colorArray[colorArray.size] = ( 0.2, 0.9, 0.2 );
|
||||
colorArray[colorArray.size] = ( 0.2, 0.2, 0.9 );
|
||||
colorArray[colorArray.size] = ( 0.9, 0.9, 0.9 );
|
||||
|
||||
|
||||
locations = [];
|
||||
locations["color"] = [];
|
||||
locations["loc"] = [];
|
||||
locations["tracePos"] = [];
|
||||
locations["distSqrd"] = [];
|
||||
locations["fxtoplay"] = [];
|
||||
locations["radius"] = [];
|
||||
|
||||
|
||||
for( fxIndex = 0; fxIndex < fxCount; fxIndex++ )
|
||||
{
|
||||
locations["point"][fxIndex] = getLocationForFX( startPos, fxIndex, fxCount, defaultDistance, rotation );
|
||||
locations["color"][fxIndex] = colorArray[fxIndex % colorArray.size];
|
||||
}
|
||||
|
||||
for ( count = 0; count < fxCount; count++ )
|
||||
{
|
||||
trace = hitPos( startPos, locations["point"][count], locations["color"][count] );
|
||||
tracePosition = trace["position"];
|
||||
locations["tracePos"][count] = tracePosition;
|
||||
|
||||
if ( trace["fraction"] < 0.7 )
|
||||
{
|
||||
locations["loc"][count] = tracePosition;
|
||||
locations["normal"][count] = trace["normal"];
|
||||
continue;
|
||||
}
|
||||
|
||||
average = startPos/2 + tracePosition/2;
|
||||
|
||||
trace = hitPos( average, average - ( 0, 0, defaultDropDistance ), locations["color"][count] );
|
||||
if ( trace["fraction"] != 1 )
|
||||
{
|
||||
locations["loc"][count] = trace["position"];
|
||||
locations["normal"][count] = trace["normal"];
|
||||
}
|
||||
}
|
||||
|
||||
// startPos = startPos - getstepoutdistance( normal ); // start pos is already a good position for fx, we are using a different sized trigger now.
|
||||
|
||||
incendiaryGrenade = GetWeapon( "incendiary_fire" );
|
||||
|
||||
SpawnTimedFX( incendiaryGrenade, startPos, normal, level.incendiaryfireDuration, self.team );
|
||||
|
||||
level.incendiaryDamageRadius = GetDvarInt( "scr_incendiaryDamageRadius", level.incendiaryDamageRadius );
|
||||
|
||||
thread damageEffectArea ( owner, startPos, level.incendiaryDamageRadius, level.incendiaryDamageRadius, killCamEnt );
|
||||
|
||||
for ( count = 0; count < locations["point"].size; count++ )
|
||||
{
|
||||
if ( isdefined ( locations["loc"][count] ) )
|
||||
{
|
||||
normal = locations["normal"][count];
|
||||
|
||||
SpawnTimedFX( incendiaryGrenade, locations["loc"][count], normal, level.incendiaryfireDuration, self.team );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/#
|
||||
function incendiary_debug_line( from, to, color, depthTest, time )
|
||||
{
|
||||
debug_rcbomb = GetDvarInt( "scr_incendiary_debug", 0 );
|
||||
if ( debug_rcbomb == 1 )
|
||||
{
|
||||
if ( !isdefined(time) )
|
||||
{
|
||||
time = 100;
|
||||
}
|
||||
if ( !isdefined(depthTest) )
|
||||
{
|
||||
depthTest = true;
|
||||
}
|
||||
Line( from, to, color, 1, depthTest, time);
|
||||
}
|
||||
}
|
||||
#/
|
||||
|
||||
|
||||
|
||||
function damageEffectArea ( owner, position, radius, height, killCamEnt )
|
||||
{
|
||||
trigger_radius_position = position - ( 0 , 0, height );
|
||||
trigger_radius_height = height * 2;
|
||||
|
||||
fireEffectArea = spawn( "trigger_radius", trigger_radius_position, 0, radius, trigger_radius_height );
|
||||
|
||||
// Create head icon
|
||||
// objective = GetEquipmentHeadObjective( GetWeapon( "incendiary_grenade" ) );
|
||||
// killCamEnt entityheadicons::setEntityHeadIcon( owner.pers["team"], owner, (0,0,0), objective );
|
||||
|
||||
/#
|
||||
if( GetDvarint( "scr_draw_triggers" ) )
|
||||
level thread util::drawcylinder( trigger_radius_position, radius, trigger_radius_height, undefined, "incendiary_draw_cylinder_stop" );
|
||||
#/
|
||||
|
||||
// raps stuff
|
||||
if ( isdefined( level.rapsOnBurnRaps ) )
|
||||
{
|
||||
owner thread [[level.rapsOnBurnRaps]]( fireEffectArea );
|
||||
}
|
||||
|
||||
ownerOriginalTeam = owner.team;
|
||||
|
||||
// loop variables
|
||||
loopWaitTime = level.incendiaryFireDamageTickTime;
|
||||
durationOfIncendiary = level.incendiaryFireDuration;
|
||||
|
||||
// loop for the duration of the effect
|
||||
while (durationOfIncendiary > 0)
|
||||
{
|
||||
if ( isdefined( owner ) && owner.team !== ownerOriginalTeam )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
durationOfIncendiary -= loopWaitTime;
|
||||
damageApplied = false;
|
||||
|
||||
potential_targets = self getPotentialTargets( owner );
|
||||
foreach( target in potential_targets )
|
||||
{
|
||||
self tryToApplyFireDamage( target, owner, position, fireEffectArea, loopWaitTime, killcament );
|
||||
}
|
||||
|
||||
wait (loopWaitTime);
|
||||
}
|
||||
|
||||
// Delete head icon
|
||||
if ( isdefined( killCamEnt ) )
|
||||
killCamEnt entityheadicons::destroyEntityHeadIcons();
|
||||
// clean up
|
||||
fireEffectArea delete();
|
||||
|
||||
/#
|
||||
if( GetDvarint( "scr_draw_triggers" ) )
|
||||
level notify( "incendiary_draw_cylinder_stop" );
|
||||
#/
|
||||
}
|
||||
|
||||
function getPotentialTargets( owner ) // self == incendiary grenade
|
||||
{
|
||||
// try getting team based targets first
|
||||
owner_team = ( isdefined( owner ) ? owner.team : undefined );
|
||||
if ( level.teambased && isdefined( owner_team ) && level.friendlyfire == 0 )
|
||||
{
|
||||
enemy_team = ( owner_team == "axis" ? "allies" : "axis" );
|
||||
potential_targets = [];
|
||||
potential_targets = ArrayCombine( potential_targets, GetPlayers( enemy_team ), false, false );
|
||||
potential_targets = ArrayCombine( potential_targets, GetAITeamArray( enemy_team ), false, false );
|
||||
potential_targets = ArrayCombine( potential_targets, GetVehicleTeamArray( enemy_team ), false, false );
|
||||
potential_targets[ potential_targets.size ] = owner;
|
||||
return potential_targets;
|
||||
}
|
||||
|
||||
// now get all targets
|
||||
all_targets = [];
|
||||
all_targets = ArrayCombine( all_targets, level.players, false, false );
|
||||
all_targets = ArrayCombine( all_targets, GetAIArray(), false, false );
|
||||
all_targets = ArrayCombine( all_targets, GetVehicleArray(), false, false );
|
||||
|
||||
// if this is hardcore, then every entity is a potential target
|
||||
if ( level.friendlyfire > 0 )
|
||||
return all_targets;
|
||||
|
||||
// remove all targets not on the same team, except owner
|
||||
potential_targets = [];
|
||||
foreach( target in all_targets )
|
||||
{
|
||||
if ( !isdefined( target ) )
|
||||
continue;
|
||||
|
||||
if( !isdefined( target.team ) )
|
||||
continue;
|
||||
|
||||
if( isdefined( owner ) )
|
||||
{
|
||||
if( target != owner )
|
||||
{
|
||||
if( !isdefined( owner_team ) )
|
||||
continue;
|
||||
|
||||
if( target.team == owner_team )
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !isdefined( self ) )
|
||||
continue;
|
||||
|
||||
if( !isdefined( self.team ) )
|
||||
continue;
|
||||
|
||||
if( target.team == self.team )
|
||||
continue;
|
||||
}
|
||||
|
||||
potential_targets[ potential_targets.size ] = target;
|
||||
}
|
||||
|
||||
return potential_targets;
|
||||
}
|
||||
|
||||
function tryToApplyFireDamage( target, owner, position, fireEffectArea, resetFireTime, killcament ) // self == incendiary grenade
|
||||
{
|
||||
// see if we're not in the fire area
|
||||
if ( ( !isdefined(target.infireArea) ) || (target.infireArea == false) )
|
||||
{
|
||||
// since we're not in the poison area, now see if we're in the fire area
|
||||
if ( target istouching(fireEffectArea) && ( !isdefined(target.sessionstate) || target.sessionstate == "playing" ) )
|
||||
{
|
||||
trace = bullettrace( position, target GetShootAtPos(), false, target, true );
|
||||
|
||||
if ( trace["fraction"] == 1 )
|
||||
{
|
||||
target.lastburnedBy = owner;
|
||||
target thread damageInFireArea( fireEffectArea, killcament, trace, position, resetFireTime );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function damageInFireArea( fireEffectArea, killcament, trace, position, resetFireTime ) // self == player in fire area
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
|
||||
timer = 0;
|
||||
|
||||
damage = level.incendiaryfireDamage;
|
||||
if( level.hardcoreMode )
|
||||
{
|
||||
damage = level.incendiaryfireDamageHardcore;
|
||||
}
|
||||
|
||||
if ( canDoFireDamage( killCamEnt, self, resetFireTime ) )
|
||||
{
|
||||
/#
|
||||
level.incendiary_debug = GetDvarInt( "scr_incendiary_debug", 0 );
|
||||
if ( level.incendiary_debug )
|
||||
{
|
||||
if ( !isdefined( level.incendiaryDamageTime ) )
|
||||
{
|
||||
level.incendiaryDamageTime = GetTime();
|
||||
}
|
||||
|
||||
iprintlnbold( level.incendiaryDamageTime - getTime() );
|
||||
level.incendiaryDamageTime = getTime();
|
||||
}
|
||||
#/
|
||||
self DoDamage( damage, fireEffectArea.origin, self.lastburnedBy, killCamEnt, "none", "MOD_BURNED", 0, GetWeapon( "incendiary_fire" ) );
|
||||
|
||||
entnum = self getentitynumber();
|
||||
|
||||
self thread sndFireDamage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function sndFireDamage()
|
||||
{
|
||||
self notify( "sndFire" );
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "sndFire" );
|
||||
|
||||
if( !isdefined( self.sndFireEnt ) )
|
||||
{
|
||||
self.sndFireEnt = spawn( "script_origin", self.origin );
|
||||
self.sndFireEnt linkto( self, "tag_origin" );
|
||||
self.sndFireEnt playsound( "chr_burn_start" );
|
||||
self thread sndFireDamage_DeleteEnt(self.sndFireEnt);
|
||||
}
|
||||
|
||||
self.sndFireEnt playloopsound( "chr_burn_start_loop", .5 );
|
||||
wait(3);
|
||||
self.sndFireEnt delete();
|
||||
self.sndFireEnt = undefined;
|
||||
}
|
||||
function sndFireDamage_DeleteEnt(ent)
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self waittill( "death" );
|
||||
|
||||
if( isdefined( ent ) )
|
||||
ent delete(); //pfx_fire_incendiary
|
||||
}
|
||||
|
||||
|
||||
function hitPos( start, end, color )
|
||||
{
|
||||
trace = bullettrace( start, end, false, undefined );
|
||||
|
||||
/#
|
||||
level.incendiary_debug = GetDvarInt( "scr_incendiary_debug", 0 );
|
||||
if ( level.incendiary_debug )
|
||||
{
|
||||
debugstar(trace["position"], 2 * 1000, color);
|
||||
}
|
||||
|
||||
thread incendiary_debug_line( start, trace["position"], color, true, 80 );
|
||||
#/
|
||||
|
||||
return trace;
|
||||
}
|
||||
|
||||
function canDoFireDamage( killCamEnt, victim, resetFireTime )
|
||||
{
|
||||
entNum = victim getentitynumber();
|
||||
if ( !isdefined( level.incendiaryDamageThisTick[entNum] ) )
|
||||
{
|
||||
level.incendiaryDamageThisTick[entNum] = 0;
|
||||
level thread resetFireDamage( entnum, resetFireTime );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function resetFireDamage( entnum, time )
|
||||
{
|
||||
if ( time > 0.05 )
|
||||
{
|
||||
wait( time - 0.05 );
|
||||
}
|
||||
level.incendiaryDamageThisTick[entnum] = undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
// tagTMR<NOTE>: this is a stripped down last stand implementation for the purposes of hooking into
|
||||
// the resurrect gadget. Removed suicide and revive triggers, all hud elements, anything cp/zm specific
|
||||
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\demo_shared;
|
||||
#using scripts\shared\flag_shared;
|
||||
#using scripts\shared\hud_util_shared;
|
||||
#using scripts\shared\killcam_shared;
|
||||
#using scripts\shared\laststand_shared;
|
||||
#using scripts\shared\scoreevents_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
|
||||
#using scripts\shared\abilities\gadgets\_gadget_resurrect;
|
||||
#using scripts\shared\abilities\_ability_util;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#using scripts\mp\gametypes\_globallogic_player;
|
||||
#using scripts\mp\gametypes\_globallogic_spawn;
|
||||
#using scripts\mp\gametypes\_killcam;
|
||||
|
||||
#namespace laststand;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("laststand",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
if (level.script=="frontend")
|
||||
{
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
function player_last_stand_stats( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
|
||||
{
|
||||
//stat tracking
|
||||
if ( IsDefined( attacker ) && IsPlayer( attacker ) && attacker != self )
|
||||
{
|
||||
attacker.kills++;
|
||||
|
||||
if (isdefined(weapon))
|
||||
{
|
||||
dmgweapon = weapon;
|
||||
|
||||
weaponPickedUp = false;
|
||||
if( isdefined( attacker.pickedUpWeapons ) && isdefined( attacker.pickedUpWeapons[weapon] ) )
|
||||
{
|
||||
weaponPickedUp = true;
|
||||
}
|
||||
|
||||
attacker AddWeaponStat(dmgweapon, "kills", 1, attacker.class_num, weaponPickedUp );
|
||||
}
|
||||
}
|
||||
|
||||
self.downs++;
|
||||
}
|
||||
|
||||
function PlayerLastStand( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, delayOverride )
|
||||
{
|
||||
if( self player_is_in_laststand() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isdefined( self.resurrect_not_allowed_by ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self globallogic_player::Callback_PlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, 0, true );
|
||||
|
||||
self notify("entering_last_stand");
|
||||
|
||||
// check to see if we are in a game module that wants to do something with PvP damage
|
||||
if( isDefined( level._game_module_player_laststand_callback ) )
|
||||
{
|
||||
self [[ level._game_module_player_laststand_callback ]]( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, delayOverride );
|
||||
}
|
||||
|
||||
self.lastStandParams = spawnstruct();
|
||||
self.lastStandParams.eInflictor = eInflictor;
|
||||
self.lastStandParams.attacker = attacker;
|
||||
self.lastStandParams.iDamage = iDamage;
|
||||
self.lastStandParams.sMeansOfDeath = sMeansOfDeath;
|
||||
self.lastStandParams.sWeapon = weapon;
|
||||
self.lastStandParams.vDir = vDir;
|
||||
self.lastStandParams.sHitLoc = sHitLoc;
|
||||
self.lastStandParams.lastStandStartTime = gettime();
|
||||
self.lastStandParams.killcam_entity_info_cached = killcam::get_killcam_entity_info( attacker, eInflictor, weapon );
|
||||
|
||||
self thread player_last_stand_stats( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, delayOverride );
|
||||
|
||||
self.health = 1;
|
||||
self.laststand = true;
|
||||
self.ignoreme = true;
|
||||
self EnableInvulnerability();
|
||||
self.meleeAttackers = undefined;
|
||||
self.no_revive_trigger = true;
|
||||
|
||||
callback::callback( #"on_player_laststand" );
|
||||
|
||||
assert( IsDefined( self.resurrect_weapon ) ); // defined in gadget_resurrect.gsc
|
||||
assert( self.resurrect_weapon != level.weaponNone );
|
||||
|
||||
slot = self ability_util::gadget_slot_for_type( 40 );
|
||||
self GadgetStateChange( slot, self.resurrect_weapon, 2 );
|
||||
self laststand_disable_player_weapons();
|
||||
self thread MakeSureSwitchToWeapon();
|
||||
self thread resurrect::enter_rejack_standby(); // UI and input watchers
|
||||
self thread watch_player_input();
|
||||
|
||||
demo::bookmark( "player_downed", gettime(), self );
|
||||
}
|
||||
|
||||
function MakeSureSwitchToWeapon()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "bleed_out" );
|
||||
self endon( "player_input_revive" );
|
||||
self endon( "player_input_suicide" );
|
||||
level endon("game_ended");
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
if( self getcurrentweapon() != self.resurrect_weapon )
|
||||
{
|
||||
self SwitchToWeapon( self.resurrect_weapon );
|
||||
}
|
||||
{wait(.05);};
|
||||
}
|
||||
}
|
||||
|
||||
// self = a player
|
||||
function laststand_disable_player_weapons()
|
||||
{
|
||||
weaponInventory = self GetWeaponsList( true );
|
||||
self.lastActiveWeapon = self GetCurrentWeapon();
|
||||
if ( self IsThrowingGrenade() )
|
||||
{
|
||||
primaryWeapons = self GetWeaponsListPrimaries();
|
||||
if( IsDefined( primaryWeapons ) && primaryWeapons.size > 0 )
|
||||
{
|
||||
self.lastActiveWeapon = primaryWeapons[0];
|
||||
self SwitchToWeaponImmediate( self.lastActiveWeapon );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function laststand_enable_player_weapons( b_allow_grenades = true ) // self == player
|
||||
{
|
||||
self EnableWeaponCycling();
|
||||
|
||||
if ( b_allow_grenades )
|
||||
{
|
||||
self EnableOffhandWeapons();
|
||||
}
|
||||
|
||||
if( IsDefined(self.lastActiveWeapon) && (self.lastActiveWeapon != level.weaponNone) && self HasWeapon( self.lastActiveWeapon ) )
|
||||
{
|
||||
self SwitchToWeapon( self.lastActiveWeapon );
|
||||
}
|
||||
else
|
||||
{
|
||||
primaryWeapons = self GetWeaponsListPrimaries();
|
||||
if( IsDefined( primaryWeapons ) && primaryWeapons.size > 0 )
|
||||
{
|
||||
self SwitchToWeapon( primaryWeapons[0] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function laststand_clean_up_on_interrupt( playerBeingRevived, reviverGun )
|
||||
{
|
||||
self endon( "do_revive_ended_normally" );
|
||||
|
||||
reviveTrigger = playerBeingRevived.revivetrigger;
|
||||
|
||||
playerBeingRevived util::waittill_any( "disconnect", "game_ended", "death" );
|
||||
|
||||
if( isdefined( reviveTrigger ) )
|
||||
{
|
||||
reviveTrigger delete();
|
||||
}
|
||||
self cleanup_suicide_hud();
|
||||
|
||||
if( isdefined( self.reviveProgressBar ) )
|
||||
{
|
||||
self.reviveProgressBar hud::destroyElem();
|
||||
}
|
||||
|
||||
if( isdefined( self.reviveTextHud ) )
|
||||
{
|
||||
self.reviveTextHud destroy();
|
||||
}
|
||||
}
|
||||
|
||||
function laststand_clean_up_reviving_any( playerBeingRevived )
|
||||
{
|
||||
self endon( "do_revive_ended_normally" );
|
||||
|
||||
playerBeingRevived util::waittill_any( "disconnect", "zombified", "stop_revive_trigger" );
|
||||
|
||||
self.is_reviving_any--;
|
||||
if ( 0 > self.is_reviving_any )
|
||||
{
|
||||
self.is_reviving_any = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function bleed_out()
|
||||
{
|
||||
demo::bookmark( "player_bledout", gettime(), self, undefined, 1 );
|
||||
|
||||
level notify("bleed_out", self.characterindex);
|
||||
|
||||
self UndoLastStand();
|
||||
self.ignoreme = false;
|
||||
self.laststand = undefined;
|
||||
|
||||
self.useLastStandParams = true;
|
||||
|
||||
// attacker may have become undefined if the player that killed me has disconnected
|
||||
if ( !isDefined( self.lastStandParams.attacker ) )
|
||||
{
|
||||
self.lastStandParams.attacker = self;
|
||||
}
|
||||
|
||||
self suicide();
|
||||
}
|
||||
|
||||
function watch_player_input() // self == player
|
||||
{
|
||||
self thread watch_player_input_revive();
|
||||
self thread watch_player_input_suicide();
|
||||
}
|
||||
|
||||
function watch_player_input_revive() // self == player
|
||||
{
|
||||
level endon("game_ended");
|
||||
|
||||
self endon( "player_input_bleed_out" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
|
||||
self waittill("player_input_revive");
|
||||
|
||||
demo::bookmark( "player_revived", gettime(), self, self );
|
||||
|
||||
self Rejack(); // TODO: split this out into gadget-specific territory and keep this file last stand only
|
||||
|
||||
self laststand_enable_player_weapons();
|
||||
|
||||
self.ignoreme = false;
|
||||
self DisableInvulnerability();
|
||||
self.laststand = undefined;
|
||||
}
|
||||
|
||||
function watch_player_input_suicide() // self == player
|
||||
{
|
||||
level endon("game_ended");
|
||||
|
||||
self endon( "player_input_revive" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
|
||||
self waittill("player_input_suicide");
|
||||
|
||||
self bleed_out();
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_lightninggun;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace lightninggun;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("lightninggun",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
lightninggun::init_shared();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\weapons\_lightninggun;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#namespace lightninggun;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("lightninggun",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
lightninggun::init_shared();
|
||||
}
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\archetype_shared\archetype_shared;
|
||||
#using scripts\shared\audio_shared;//DO NOT REMOVE - needed for system registration
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\clientfaceanim_shared;
|
||||
#using scripts\shared\flagsys_shared;
|
||||
#using scripts\shared\footsteps_shared;//DO NOT REMOVE - needed for system registration
|
||||
#using scripts\shared\load_shared;
|
||||
#using scripts\shared\music_shared;
|
||||
#using scripts\shared\player_shared;//DO NOT REMOVE - needed for system registration
|
||||
#using scripts\shared\_oob;
|
||||
#using scripts\shared\scene_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\turret_shared;
|
||||
#using scripts\shared\postfx_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\vehicle_shared;
|
||||
#using scripts\shared\weapons\_bouncingbetty;
|
||||
#using scripts\shared\weapons\_hive_gun;
|
||||
#using scripts\shared\weapons\spike_charge;
|
||||
#using scripts\shared\weapons\_lightninggun;
|
||||
#using scripts\shared\weapons\_pineapple_gun;
|
||||
#using scripts\shared\weapons\_proximity_grenade;
|
||||
#using scripts\shared\weapons\_riotshield;
|
||||
#using scripts\shared\weapons\_satchel_charge;
|
||||
#using scripts\shared\weapons\_tacticalinsertion;
|
||||
#using scripts\shared\weapons\_trophy_system;
|
||||
#using scripts\shared\weapons\_weaponobjects;
|
||||
#using scripts\shared\weapons\multilockapguidance;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
//System registration
|
||||
#using scripts\mp\_ambient;
|
||||
#using scripts\shared\_burnplayer;
|
||||
#using scripts\mp\_callbacks;
|
||||
#using scripts\mp\_ctf;
|
||||
#using scripts\mp\_destructible;
|
||||
// #using scripts\mp\_devgui; // never add this to mp (it's for mp frontend only)
|
||||
#using scripts\mp\_global_fx;
|
||||
#using scripts\mp\_multi_extracam;
|
||||
#using scripts\mp\_perks;
|
||||
#using scripts\mp\_radiant_live_update;
|
||||
#using scripts\mp\_rewindobjects;
|
||||
#using scripts\mp\_rotating_object;
|
||||
#using scripts\mp\_vehicle;
|
||||
#using scripts\mp\_end_game_flow;
|
||||
#using scripts\mp\mpdialog;
|
||||
|
||||
//Gametype registration
|
||||
#using scripts\mp\gametypes\_classicmode;
|
||||
|
||||
//Weapon registration
|
||||
#using scripts\shared\weapons\_sticky_grenade;
|
||||
#using scripts\mp\_bouncingbetty;
|
||||
#using scripts\mp\_hacker_tool;
|
||||
#using scripts\mp\_hive_gun;
|
||||
#using scripts\mp\_claymore;
|
||||
#using scripts\mp\_decoy;
|
||||
#using scripts\mp\_explosive_bolt;
|
||||
#using scripts\mp\_flashgrenades;
|
||||
#using scripts\mp\_gravity_spikes;
|
||||
#using scripts\mp\_lightninggun;
|
||||
#using scripts\mp\_proximity_grenade;
|
||||
#using scripts\mp\_riotshield;
|
||||
#using scripts\mp\_satchel_charge;
|
||||
#using scripts\mp\_threat_detector;
|
||||
#using scripts\mp\_tacticalinsertion;
|
||||
#using scripts\mp\_trophy_system;
|
||||
#using scripts\mp\gametypes\_weaponobjects;
|
||||
|
||||
//Killstreak registration
|
||||
#using scripts\mp\_helicopter_sounds;
|
||||
#using scripts\mp\killstreaks\_counteruav;
|
||||
#using scripts\mp\killstreaks\_dart;
|
||||
#using scripts\mp\killstreaks\_emp;
|
||||
#using scripts\mp\killstreaks\_helicopter;
|
||||
#using scripts\mp\killstreaks\_helicopter_gunner;
|
||||
#using scripts\mp\killstreaks\_flak_drone;
|
||||
#using scripts\mp\killstreaks\_microwave_turret;
|
||||
#using scripts\mp\killstreaks\_planemortar;
|
||||
#using scripts\mp\killstreaks\_remotemissile;
|
||||
#using scripts\mp\killstreaks\_raps;
|
||||
#using scripts\mp\killstreaks\_turret;
|
||||
#using scripts\mp\killstreaks\_killstreak_detect;
|
||||
|
||||
|
||||
//Abilities registration
|
||||
#using scripts\shared\abilities\_ability_player;
|
||||
|
||||
#namespace load;
|
||||
|
||||
function levelNotifyHandler(clientNum, state, oldState)
|
||||
{
|
||||
if(state != "")
|
||||
{
|
||||
level notify(state,clientNum);
|
||||
}
|
||||
}
|
||||
|
||||
function main()
|
||||
{
|
||||
/#
|
||||
|
||||
Assert( isdefined( level.first_frame ), "There should be no waits before load::main." );
|
||||
|
||||
#/
|
||||
|
||||
level thread util::serverTime();
|
||||
level thread util::init_utility();
|
||||
|
||||
util::registerSystem("levelNotify",&levelNotifyHandler);
|
||||
|
||||
register_clientfields();
|
||||
|
||||
level.createFX_disable_fx = (GetDvarInt("disable_fx") == 1);
|
||||
|
||||
//The functions are threaded just in case any of them create 'wait's. Note these functions should not have 'wait's in their 'init' and 'main' functions.
|
||||
|
||||
// footsteps();
|
||||
|
||||
system::wait_till( "all" );
|
||||
|
||||
level flagsys::set( "load_main_complete" );
|
||||
}
|
||||
|
||||
/*footsteps()
|
||||
{
|
||||
util::setFootstepEffect( "asphalt", "_t6/bio/player/fx_footstep_dust" );
|
||||
util::setFootstepEffect( "brick", "_t6/bio/player/fx_footstep_dust" );
|
||||
util::setFootstepEffect( "carpet", "_t6/bio/player/fx_footstep_dust" );
|
||||
util::setFootstepEffect( "cloth", "_t6/bio/player/fx_footstep_dust" );
|
||||
util::setFootstepEffect( "concrete", "_t6/bio/player/fx_footstep_dust" );
|
||||
util::setFootstepEffect( "dirt", "_t6/bio/player/fx_footstep_sand" );
|
||||
util::setFootstepEffect( "foliage", "_t6/bio/player/fx_footstep_dust" );
|
||||
util::setFootstepEffect( "gravel", "_t6/bio/player/fx_footstep_sand" );
|
||||
util::setFootstepEffect( "grass", "_t6/bio/player/fx_footstep_sand" );
|
||||
util::setFootstepEffect( "metal", "_t6/bio/player/fx_footstep_dust" );
|
||||
util::setFootstepEffect( "mud", "_t6/bio/player/fx_footstep_mud" );
|
||||
util::setFootstepEffect( "paper", "_t6/bio/player/fx_footstep_dust" );
|
||||
util::setFootstepEffect( "plaster", "_t6/bio/player/fx_footstep_dust" );
|
||||
util::setFootstepEffect( "rock", "_t6/bio/player/fx_footstep_sand" );
|
||||
util::setFootstepEffect( "sand", "_t6/bio/player/fx_footstep_sand" );
|
||||
util::setFootstepEffect( "water", "_t6/bio/player/fx_footstep_water" );
|
||||
util::setFootstepEffect( "wood", "_t6/bio/player/fx_footstep_dust" );
|
||||
}*/
|
||||
|
||||
function register_clientfields()
|
||||
{
|
||||
clientfield::register( "missile", "cf_m_proximity", 1, 1, "int", &callback::callback_proximity, !true, !true );
|
||||
clientfield::register( "missile", "cf_m_emp", 1, 1, "int", &callback::callback_emp, !true, !true );
|
||||
clientfield::register( "missile", "cf_m_stun", 1, 1, "int", &callback::callback_stunned, !true, !true );
|
||||
|
||||
//clientfield::register( "scriptmover", "cf_s_emp", VERSION_SHIP, 1, "int", &callback::callback_emp, !CF_HOST_ONLY, !CF_CALLBACK_ZERO_ON_NEW_ENT );
|
||||
//clientfield::register( "scriptmover", "cf_s_stun", VERSION_SHIP, 1, "int", &callback::callback_stunned, !CF_HOST_ONLY, !CF_CALLBACK_ZERO_ON_NEW_ENT );
|
||||
|
||||
}
|
||||
+214
@@ -0,0 +1,214 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
//TODO T7 - move what we can into load_shared once ZM gets a pass
|
||||
#using scripts\shared\archetype_shared\archetype_shared;
|
||||
#using scripts\shared\audio_shared;//DO NOT REMOVE - needed for system registration
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\demo_shared;
|
||||
#using scripts\shared\entityheadicons_shared;
|
||||
#using scripts\shared\flag_shared;
|
||||
#using scripts\shared\flagsys_shared;
|
||||
#using scripts\shared\hostmigration_shared;
|
||||
#using scripts\shared\load_shared;
|
||||
#using scripts\shared\math_shared;
|
||||
#using scripts\shared\medals_shared;
|
||||
#using scripts\shared\music_shared;//DO NOT REMOVE - needed for system registration
|
||||
#using scripts\shared\player_shared;//DO NOT REMOVE - needed for system registration
|
||||
#using scripts\shared\objpoints_shared;
|
||||
#using scripts\shared\_oob;
|
||||
#using scripts\shared\popups_shared;
|
||||
#using scripts\shared\scene_shared;
|
||||
#using scripts\shared\serverfaceanim_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\turret_shared;
|
||||
#using scripts\shared\tweakables_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_ballistic_knife;
|
||||
#using scripts\shared\weapons\_bouncingbetty;
|
||||
#using scripts\shared\weapons\_hive_gun;
|
||||
#using scripts\shared\weapons\_tacticalinsertion;
|
||||
#using scripts\shared\weapons\_trophy_system;
|
||||
#using scripts\shared\weapons\_flashgrenades;
|
||||
#using scripts\shared\weapons\_lightninggun;
|
||||
#using scripts\shared\weapons\_proximity_grenade;
|
||||
#using scripts\shared\weapons\_riotshield;
|
||||
#using scripts\shared\weapons\_satchel_charge;
|
||||
#using scripts\shared\weapons\_sensor_grenade;
|
||||
#using scripts\shared\weapons\_weaponobjects;
|
||||
#using scripts\shared\weapons\multilockapguidance;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#using scripts\mp\_art;
|
||||
#using scripts\mp\_destructible;
|
||||
#using scripts\mp\_load;
|
||||
#using scripts\mp\_util;
|
||||
|
||||
//REGISTRATION - These scripts are initialized here
|
||||
//Do not remove unless you are removing the script from the game
|
||||
|
||||
//System registration
|
||||
#using scripts\mp\_arena;
|
||||
#using scripts\mp\_bb;
|
||||
#using scripts\shared\_burnplayer;
|
||||
#using scripts\mp\_callbacks;
|
||||
#using scripts\mp\_devgui;
|
||||
#using scripts\mp\_perks;
|
||||
#using scripts\mp\_vehicle;
|
||||
#using scripts\mp\_pickup_items;
|
||||
|
||||
//Gametypes Registration - DO NOT REMOVE
|
||||
#using scripts\mp\gametypes\_globallogic_audio;
|
||||
#using scripts\mp\gametypes\_spawning;
|
||||
#using scripts\mp\gametypes\_classicmode;
|
||||
|
||||
//Killstreak registration
|
||||
#using scripts\mp\killstreaks\_ai_tank;
|
||||
#using scripts\mp\killstreaks\_counteruav;
|
||||
#using scripts\mp\killstreaks\_dogs;
|
||||
#using scripts\mp\killstreaks\_drone_strike;
|
||||
#using scripts\mp\killstreaks\_rcbomb;
|
||||
#using scripts\mp\killstreaks\_placeables;
|
||||
#using scripts\mp\killstreaks\_satellite;
|
||||
#using scripts\mp\killstreaks\_uav;
|
||||
#using scripts\mp\killstreaks\_killstreak_detect;
|
||||
|
||||
//Weapon registration
|
||||
#using scripts\shared\weapons\_pineapple_gun;
|
||||
#using scripts\shared\weapons\_sticky_grenade;
|
||||
#using scripts\mp\_ballistic_knife;
|
||||
#using scripts\mp\_bouncingbetty;
|
||||
#using scripts\mp\_hive_gun;
|
||||
#using scripts\mp\_explosive_bolt;
|
||||
#using scripts\mp\_flashgrenades;
|
||||
#using scripts\mp\_hacker_tool;
|
||||
#using scripts\mp\_heatseekingmissile;
|
||||
#using scripts\mp\_incendiary;
|
||||
#using scripts\mp\_armblade;
|
||||
#using scripts\mp\_lightninggun;
|
||||
#using scripts\mp\_proximity_grenade;
|
||||
#using scripts\mp\_riotshield;
|
||||
#using scripts\mp\_satchel_charge;
|
||||
#using scripts\mp\_sensor_grenade;
|
||||
#using scripts\mp\_threat_detector;
|
||||
#using scripts\mp\_smokegrenade;
|
||||
#using scripts\mp\_tacticalinsertion;
|
||||
#using scripts\mp\_trophy_system;
|
||||
#using scripts\mp\gametypes\_weaponobjects;
|
||||
|
||||
//Abilities registration
|
||||
#using scripts\shared\abilities\_ability_player;
|
||||
|
||||
// Blackjack registration
|
||||
#using scripts\mp\_blackjack_challenges;
|
||||
|
||||
// Contract registration
|
||||
#using scripts\mp\_contracts;
|
||||
|
||||
#precache( "fx", "_t6/bio/player/fx_footstep_dust" );
|
||||
#precache( "fx", "_t6/bio/player/fx_footstep_sand" );
|
||||
#precache( "fx", "_t6/bio/player/fx_footstep_mud" );
|
||||
#precache( "fx", "_t6/bio/player/fx_footstep_water" );
|
||||
|
||||
#namespace load;
|
||||
|
||||
function main()
|
||||
{
|
||||
/#
|
||||
|
||||
Assert( isdefined( level.first_frame ), "There should be no waits before load::main." );
|
||||
|
||||
#/
|
||||
|
||||
level._loadStarted = true;
|
||||
|
||||
SetClearanceCeiling( 30 ); // slightly larger than the amws
|
||||
|
||||
register_clientfields();
|
||||
|
||||
level.aiTriggerSpawnFlags = getaitriggerflags();
|
||||
level.vehicleTriggerSpawnFlags = getvehicletriggerflags();
|
||||
|
||||
setup_traversals();
|
||||
|
||||
//TODO T7 - remove once globallogic_audio is shared
|
||||
level.globallogic_audio_dialog_on_player_override = &globallogic_audio::leader_dialog_on_player;
|
||||
level.growing_hitmarker = true;
|
||||
|
||||
system::wait_till( "all" );
|
||||
level flagsys::set( "load_main_complete" );
|
||||
}
|
||||
|
||||
function 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;
|
||||
}
|
||||
|
||||
function footsteps()
|
||||
{
|
||||
setFootstepEffect( "asphalt", "_t6/bio/player/fx_footstep_dust" );
|
||||
setFootstepEffect( "brick", "_t6/bio/player/fx_footstep_dust" );
|
||||
setFootstepEffect( "carpet", "_t6/bio/player/fx_footstep_dust" );
|
||||
setFootstepEffect( "cloth", "_t6/bio/player/fx_footstep_dust" );
|
||||
setFootstepEffect( "concrete", "_t6/bio/player/fx_footstep_dust" );
|
||||
setFootstepEffect( "dirt", "_t6/bio/player/fx_footstep_sand" );
|
||||
setFootstepEffect( "foliage", "_t6/bio/player/fx_footstep_sand" );
|
||||
setFootstepEffect( "gravel", "_t6/bio/player/fx_footstep_dust" );
|
||||
setFootstepEffect( "grass", "_t6/bio/player/fx_footstep_dust" );
|
||||
setFootstepEffect( "metal", "_t6/bio/player/fx_footstep_dust" );
|
||||
setFootstepEffect( "mud", "_t6/bio/player/fx_footstep_mud" );
|
||||
setFootstepEffect( "paper", "_t6/bio/player/fx_footstep_dust" );
|
||||
setFootstepEffect( "plaster", "_t6/bio/player/fx_footstep_dust" );
|
||||
setFootstepEffect( "rock", "_t6/bio/player/fx_footstep_dust" );
|
||||
setFootstepEffect( "sand", "_t6/bio/player/fx_footstep_sand" );
|
||||
setFootstepEffect( "water", "_t6/bio/player/fx_footstep_water" );
|
||||
setFootstepEffect( "wood", "_t6/bio/player/fx_footstep_dust" );
|
||||
}
|
||||
|
||||
// All "Begin" nodes get passed in here through _load.gsc
|
||||
function init_traverse()
|
||||
{
|
||||
point = GetEnt(self.target, "targetname");
|
||||
if (isdefined(point))
|
||||
{
|
||||
self.traverse_height = point.origin[2];
|
||||
point Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
point = struct::get(self.target, "targetname");
|
||||
if (isdefined(point))
|
||||
{
|
||||
self.traverse_height = point.origin[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setup_traversals()
|
||||
{
|
||||
potential_traverse_nodes = GetAllNodes();
|
||||
for (i = 0; i < potential_traverse_nodes.size; i++)
|
||||
{
|
||||
node = potential_traverse_nodes[i];
|
||||
if (node.type == "Begin")
|
||||
{
|
||||
node init_traverse();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function register_clientfields()
|
||||
{
|
||||
clientfield::register( "missile", "cf_m_proximity", 1, 1, "int" );
|
||||
clientfield::register( "missile", "cf_m_emp", 1, 1, "int" );
|
||||
clientfield::register( "missile", "cf_m_stun", 1, 1, "int" );
|
||||
|
||||
//clientfield::register( "scriptmover", "cf_s_emp", VERSION_SHIP, 1, "int" );
|
||||
//clientfield::register( "scriptmover", "cf_s_stun", VERSION_SHIP, 1, "int" );
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
Line truncated
|
||||
|
||||
#namespace mgturret;
|
||||
|
||||
//TODO T7 - nothing is calling main() anymore, do we need this?
|
||||
function main()
|
||||
{
|
||||
// TODO: what does this main do exactly?
|
||||
// TODO: change this dvar name to turret or something; really? we have a dvar named mg42
|
||||
if( GetDvarString( "mg42" ) == "" )
|
||||
{
|
||||
SetDvar( "mgTurret", "off" );
|
||||
}
|
||||
|
||||
level.magic_distance = 24;
|
||||
|
||||
turretInfos = getEntArray( "turretInfo", "targetname" );
|
||||
for( index = 0; index < turretInfos.size; index++ )
|
||||
{
|
||||
turretInfos[index] Delete();
|
||||
}
|
||||
}
|
||||
|
||||
function set_difficulty( difficulty )
|
||||
{
|
||||
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;
|
||||
case "medium":
|
||||
difficulty = "medium";
|
||||
break;
|
||||
case "hard":
|
||||
difficulty = "hard";
|
||||
break;
|
||||
case "fu":
|
||||
difficulty = "fu";
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
turret_set_difficulty( turrets[index], difficulty );
|
||||
}
|
||||
}
|
||||
|
||||
function init_turret_difficulty_settings()
|
||||
{
|
||||
level.mgTurretSettings["easy"]["convergenceTime"] = 2.5;
|
||||
level.mgTurretSettings["easy"]["suppressionTime"] = 3.0;
|
||||
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.0;
|
||||
level.mgTurretSettings["medium"]["accuracy"] = 0.38;
|
||||
level.mgTurretSettings["medium"]["aiSpread"] = 2;
|
||||
level.mgTurretSettings["medium"]["playerSpread"] = 0.5;
|
||||
|
||||
level.mgTurretSettings["hard"]["convergenceTime"] = .8;
|
||||
level.mgTurretSettings["hard"]["suppressionTime"] = 3.0;
|
||||
level.mgTurretSettings["hard"]["accuracy"] = 0.38;
|
||||
level.mgTurretSettings["hard"]["aiSpread"] = 2;
|
||||
level.mgTurretSettings["hard"]["playerSpread"] = 0.5;
|
||||
|
||||
level.mgTurretSettings["fu"]["convergenceTime"] = .4;
|
||||
level.mgTurretSettings["fu"]["suppressionTime"] = 3.0;
|
||||
level.mgTurretSettings["fu"]["accuracy"] = 0.38;
|
||||
level.mgTurretSettings["fu"]["aiSpread"] = 2;
|
||||
level.mgTurretSettings["fu"]["playerSpread"] = 0.5;
|
||||
}
|
||||
|
||||
function turret_set_difficulty( turret, difficulty )
|
||||
{
|
||||
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"];
|
||||
}
|
||||
|
||||
function turret_suppression_fire( targets ) // self == turret
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "stop_suppression_fire" );
|
||||
if( !isdefined( self.suppresionFire ) )
|
||||
{
|
||||
self.suppresionFire = true;
|
||||
}
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
while( self.suppresionFire )
|
||||
{
|
||||
self SetTargetEntity( targets[RandomInt( targets.size )] );
|
||||
wait( 2 + RandomFloat( 2 ) );
|
||||
}
|
||||
|
||||
self ClearTargetEntity();
|
||||
while( !self.suppresionFire )
|
||||
{
|
||||
wait( 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns a time frame for the burst fire depending on the setting parameter
|
||||
function burst_fire_settings( setting )
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// makes the turret burst fire with delays in between
|
||||
function burst_fire( turret, manual_target )
|
||||
{
|
||||
turret endon( "death" ); // MikeD: Incase we delete the turret.
|
||||
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 ) );
|
||||
}
|
||||
}
|
||||
|
||||
// auto targeting and burst firing at the targets
|
||||
function burst_fire_unmanned() // self == turret
|
||||
{
|
||||
self notify( "stop_burst_fire_unmanned" );
|
||||
self endon( "stop_burst_fire_unmanned" );
|
||||
self endon( "death" );
|
||||
self endon( "remote_start" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
if ( isdefined( self.controlled ) && 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";
|
||||
// SRS 05/02/07 - added this for link_turrets() so we can accurately tell when the function is
|
||||
// actually firing or just waiting between bursts (IsFiringTurret() returns true the whole time)
|
||||
self.script_shooting = false;
|
||||
|
||||
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"); // Play a state change sound CDC
|
||||
|
||||
self thread do_shoot();
|
||||
self.script_shooting = true;
|
||||
}
|
||||
|
||||
duration = turret_burst + RandomFloat( turret_burst_range );
|
||||
|
||||
//println( "fire duration: ", duration );
|
||||
self thread turret_timer( duration );
|
||||
|
||||
self waittill( "turretstatechange" ); // code or script
|
||||
|
||||
self.script_shooting = false;
|
||||
|
||||
duration = turret_delay + RandomFloat( turret_delay_range );
|
||||
//println( "stop fire duration: ", duration );
|
||||
|
||||
pauseUntilTime = GetTime() + Int( duration * 1000 );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( turretState != "aim" )
|
||||
{
|
||||
turretState = "aim";
|
||||
}
|
||||
|
||||
//println( "aim duration: ", duration );
|
||||
self thread turret_timer( duration );
|
||||
|
||||
// TODO: make the turret scan back and forth
|
||||
|
||||
self waittill( "turretstatechange" ); // code or script
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function do_shoot()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "turretstatechange" ); // code or script
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
self ShootTurret();
|
||||
wait( 0.112 );
|
||||
}
|
||||
}
|
||||
|
||||
// waits for a duration and sends a turret state change notify
|
||||
function turret_timer( duration )
|
||||
{
|
||||
if( duration <= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self endon( "turretstatechange" ); // code
|
||||
|
||||
//println( "start turret timer" );
|
||||
|
||||
wait( duration );
|
||||
if( isdefined( self ) )
|
||||
{
|
||||
self notify( "turretstatechange" );
|
||||
}
|
||||
|
||||
//println( "end turret timer" );
|
||||
}
|
||||
|
||||
function random_spread( ent )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
|
||||
// SCRIPTER_MOD
|
||||
// MikeD( 3/21/2007 ): No more level.player
|
||||
// if( ent == level.player )
|
||||
// ent.origin = self.manual_target GetOrigin();
|
||||
// else
|
||||
// ent.origin = self.manual_target.origin;
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\array_shared;
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
|
||||
|
||||
#namespace multi_extracam;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("multi_extracam",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__( localClientNum )
|
||||
{
|
||||
callback::on_localclient_connect( &multi_extracam_init );
|
||||
}
|
||||
|
||||
function multi_extracam_init( localClientNum )
|
||||
{
|
||||
triggers = GetEntArray( localClientNum, "multicam_enable", "targetname" );
|
||||
|
||||
for( i=1 ; i<=4 ; i++ )
|
||||
{
|
||||
cameraStruct = struct::get( "extracam" + i, "targetname" );
|
||||
if ( isdefined( cameraStruct ) )
|
||||
{
|
||||
camera_ent = Spawn( localClientNum, cameraStruct.origin, "script_origin" );
|
||||
camera_ent.angles = cameraStruct.angles;
|
||||
|
||||
width = ( isdefined( cameraStruct.extracam_width ) ? cameraStruct.extracam_width : -1 );
|
||||
height = ( isdefined( cameraStruct.extracam_height ) ? cameraStruct.extracam_height : -1 );
|
||||
|
||||
camera_ent SetExtraCam( i-1, width, height );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
#using scripts\shared\ai_shared;
|
||||
#using scripts\shared\ai\archetype_mannequin;
|
||||
#using scripts\shared\music_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
|
||||
#precache( "fx", "dlc0/nuketown/fx_de_rez_man_spawn" );
|
||||
|
||||
#namespace NuketownMannequin;
|
||||
|
||||
function SpawnMannequin( origin, angles, gender = "male", speed = undefined, weepingAngel )
|
||||
{
|
||||
if(!IsDefined ( level.mannequinspawn_music))
|
||||
{
|
||||
level.mannequinspawn_music = 1;
|
||||
music::setmusicstate( "mann" );
|
||||
}
|
||||
|
||||
if ( gender == "male" )
|
||||
{
|
||||
mannequin = SpawnActor( "spawner_bo3_mannequin_male", origin, angles, "", true, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
mannequin = SpawnActor( "spawner_bo3_mannequin_female", origin, angles, "", true, true );
|
||||
}
|
||||
|
||||
// Select an initial speed.
|
||||
rand = RandomInt( 100 );
|
||||
|
||||
if( rand <= 35 )
|
||||
{
|
||||
mannequin.zombie_move_speed = "walk";
|
||||
}
|
||||
else if( rand <= 70 )
|
||||
{
|
||||
mannequin.zombie_move_speed = "run";
|
||||
}
|
||||
else
|
||||
{
|
||||
mannequin.zombie_move_speed = "sprint";
|
||||
}
|
||||
|
||||
if ( IsDefined( speed ) )
|
||||
{
|
||||
mannequin.zombie_move_speed = speed;
|
||||
}
|
||||
|
||||
if( IsDefined( level.zm_variant_type_max ) )
|
||||
{
|
||||
// Don't select variant 0 since those animations don't have proper footstep notetracks.
|
||||
mannequin.variant_type = RandomIntRange( 1, level.zm_variant_type_max[ mannequin.zombie_move_speed ][ mannequin.zombie_arms_position ] );
|
||||
}
|
||||
|
||||
mannequin ai::set_behavior_attribute( "can_juke", true );
|
||||
mannequin ASMSetAnimationRate( RandomFloatRange( 0.98, 1.02 ) ); // Slightly vary animation playback.
|
||||
mannequin.holdFire = true; // No firing, performance gain
|
||||
|
||||
// sjakatdar (10/24/2015) - Disabling the optimization for updating the sight. It will prevent ais from picking up
|
||||
// new enemy. To be able to use this optimization, the script has to explicitly set favorite enemy, which is not being done
|
||||
// for mannequins. Fixes DT#139243.
|
||||
//mannequin.updateSight = false; // No sight update
|
||||
|
||||
mannequin.canStumble = true;
|
||||
mannequin.should_turn = true;
|
||||
mannequin thread watch_game_ended();
|
||||
mannequin.team = "free";
|
||||
mannequin.overrideActorDamage = &mannequinDamage; // prevent mannequins from deal accidental melee damage to each other.
|
||||
|
||||
mannequins = GetAIArchetypeArray( "mannequin" );
|
||||
|
||||
foreach ( otherMannequin in mannequins )
|
||||
{
|
||||
if ( otherMannequin.archetype == "mannequin" )
|
||||
{
|
||||
otherMannequin SetIgnoreEnt( mannequin, true );
|
||||
mannequin SetIgnoreEnt( otherMannequin, true );
|
||||
}
|
||||
}
|
||||
|
||||
if( weepingAngel )
|
||||
{
|
||||
mannequin thread _mannequin_unfreeze_ragdoll();
|
||||
mannequin.is_looking_at_me = true;
|
||||
mannequin.was_looking_at_me = false;
|
||||
mannequin _mannequin_update_freeze( mannequin.is_looking_at_me );
|
||||
}
|
||||
|
||||
PlayFx( "dlc0/nuketown/fx_de_rez_man_spawn", mannequin.origin, AnglesToForward( mannequin.angles ) );
|
||||
|
||||
return mannequin;
|
||||
}
|
||||
|
||||
function mannequinDamage( inflictor, attacker, damage, dFlags, mod, weapon, point, dir, hitLoc, offsetTime, boneIndex, modelIndex )
|
||||
{
|
||||
if ( IsDefined( inflictor ) && IsActor( inflictor ) && inflictor.archetype == "mannequin" )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return damage;
|
||||
}
|
||||
|
||||
function private watch_game_ended()
|
||||
{
|
||||
self endon ( "death" );
|
||||
|
||||
level waittill ( "game_ended" );
|
||||
|
||||
self SetEntityPaused( true );
|
||||
|
||||
level waittill ( "endgame_sequence" );
|
||||
|
||||
self Hide();
|
||||
}
|
||||
|
||||
function private _mannequin_unfreeze_ragdoll()
|
||||
{
|
||||
self waittill( "death" );
|
||||
|
||||
if ( IsDefined( self ) )
|
||||
{
|
||||
self SetEntityPaused( false );
|
||||
|
||||
if ( !self IsRagdoll() )
|
||||
{
|
||||
self StartRagdoll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function private _mannequin_update_freeze( frozen )
|
||||
{
|
||||
self.is_looking_at_me = frozen;
|
||||
|
||||
if( self.is_looking_at_me && !self.was_looking_at_me )
|
||||
{
|
||||
self SetEntityPaused( true );
|
||||
}
|
||||
else if( !self.is_looking_at_me && self.was_looking_at_me )
|
||||
{
|
||||
self SetEntityPaused( false );
|
||||
}
|
||||
|
||||
self.was_looking_at_me = self.is_looking_at_me;
|
||||
}
|
||||
|
||||
function watch_player_looking()
|
||||
{
|
||||
level endon ( "game_ended" );
|
||||
level endon ( "mannequin_force_cleanup" );
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
mannequins = GetAIArchetypeArray( "mannequin" );
|
||||
foreach( mannequin in mannequins )
|
||||
{
|
||||
mannequin.can_player_see_me = true;
|
||||
}
|
||||
|
||||
players = GetPlayers();
|
||||
|
||||
unseenMannequins = mannequins;
|
||||
foreach( player in players )
|
||||
{
|
||||
unseenMannequins = player CantSeeEntities( unseenMannequins, .67, false );
|
||||
}
|
||||
|
||||
foreach( mannequin in unseenMannequins )
|
||||
{
|
||||
mannequin.can_player_see_me = false;
|
||||
}
|
||||
|
||||
foreach( mannequin in mannequins )
|
||||
{
|
||||
mannequin _mannequin_update_freeze( mannequin.can_player_see_me );
|
||||
}
|
||||
|
||||
{wait(.05);};
|
||||
}
|
||||
}
|
||||
|
||||
+746
@@ -0,0 +1,746 @@
|
||||
#using scripts\codescripts\struct;
|
||||
#using scripts\shared\abilities\_ability_util;
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\filter_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#using scripts\shared\system_shared;
|
||||
|
||||
#namespace perks;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("perks",&__init__,undefined,undefined); }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#precache( "client_fx", "player/fx_plyr_footstep_tracker_l" );
|
||||
#precache( "client_fx", "player/fx_plyr_footstep_tracker_r" );
|
||||
#precache( "client_fx", "player/fx_plyr_flying_tracker_l" );
|
||||
#precache( "client_fx", "player/fx_plyr_flying_tracker_r" );
|
||||
#precache( "client_fx", "player/fx_plyr_footstep_tracker_lf" );
|
||||
#precache( "client_fx", "player/fx_plyr_footstep_tracker_rf" );
|
||||
#precache( "client_fx", "player/fx_plyr_flying_tracker_lf" );
|
||||
#precache( "client_fx", "player/fx_plyr_flying_tracker_rf" );
|
||||
|
||||
|
||||
function __init__()
|
||||
{
|
||||
clientfield::register( "allplayers", "flying", 1, 1, "int", &flying_callback, !true, true );
|
||||
|
||||
callback::on_localclient_connect( &on_local_client_connect );
|
||||
callback::on_localplayer_spawned( &on_localplayer_spawned );
|
||||
callback::on_spawned( &on_player_spawned );
|
||||
|
||||
// kill tracker FX when tracked player dies
|
||||
level.killTrackerFXEnable = true;
|
||||
level._monitor_tracker = &monitor_tracker_perk;
|
||||
|
||||
level.sitrepscan1_enable = GetDvarInt( "scr_sitrepscan1_enable", 2 );
|
||||
level.sitrepscan1_setoutline = GetDvarInt( "scr_sitrepscan1_setoutline", 1 );
|
||||
level.sitrepscan1_setsolid = GetDvarInt( "scr_sitrepscan1_setsolid", 1 );
|
||||
level.sitrepscan1_setlinewidth = GetDvarInt( "scr_sitrepscan1_setlinewidth", 1 );
|
||||
level.sitrepscan1_setradius = GetDvarInt( "scr_sitrepscan1_setradius", 50000 );
|
||||
level.sitrepscan1_setfalloff = GetDvarFloat( "scr_sitrepscan1_setfalloff", .01 );
|
||||
level.sitrepscan1_setdesat = GetDvarFloat( "scr_sitrepscan1_setdesat", .4 );
|
||||
|
||||
level.sitrepscan2_enable = GetDvarInt( "scr_sitrepscan2_enable", 2 );
|
||||
level.sitrepscan2_setoutline = GetDvarInt( "scr_sitrepscan2_setoutline", 10 );
|
||||
level.sitrepscan2_setsolid = GetDvarInt( "scr_sitrepscan2_setsolid", 0 );
|
||||
level.sitrepscan2_setlinewidth = GetDvarInt( "scr_sitrepscan2_setlinewidth", 1 );
|
||||
level.sitrepscan2_setradius = GetDvarInt( "scr_sitrepscan2_setradius", 50000 );
|
||||
level.sitrepscan2_setfalloff = GetDvarFloat( "scr_sitrepscan2_setfalloff", .01 );
|
||||
level.sitrepscan2_setdesat = GetDvarFloat( "scr_sitrepscan2_setdesat", .4 );
|
||||
|
||||
/#
|
||||
level thread updateDvars();
|
||||
#/
|
||||
}
|
||||
|
||||
function updateSitrepScan()
|
||||
{
|
||||
self endon ( "entityshutdown" );
|
||||
while(1)
|
||||
{
|
||||
self oed_sitrepscan_enable( level.sitrepscan1_enable );
|
||||
self oed_sitrepscan_setoutline( level.sitrepscan1_setoutline );
|
||||
self oed_sitrepscan_setsolid( level.sitrepscan1_setsolid );
|
||||
self oed_sitrepscan_setlinewidth( level.sitrepscan1_setlinewidth );
|
||||
self oed_sitrepscan_setradius( level.sitrepscan1_setradius );
|
||||
self oed_sitrepscan_setfalloff( level.sitrepscan1_setfalloff );
|
||||
self oed_sitrepscan_setdesat( level.sitrepscan1_setdesat );
|
||||
|
||||
self oed_sitrepscan_enable( level.sitrepscan2_enable, 1 );
|
||||
self oed_sitrepscan_setoutline( level.sitrepscan2_setoutline, 1 );
|
||||
self oed_sitrepscan_setsolid( level.sitrepscan2_setsolid, 1 );
|
||||
self oed_sitrepscan_setlinewidth( level.sitrepscan2_setlinewidth, 1 );
|
||||
self oed_sitrepscan_setradius( level.sitrepscan2_setradius, 1 );
|
||||
self oed_sitrepscan_setfalloff( level.sitrepscan2_setfalloff, 1 );
|
||||
self oed_sitrepscan_setdesat( level.sitrepscan2_setdesat, 1 );
|
||||
wait(1.0);
|
||||
}
|
||||
}
|
||||
|
||||
/#
|
||||
function updateDvars()
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
level.sitrepscan1_enable = GetDvarInt( "scr_sitrepscan1_enable", level.sitrepscan1_enable );
|
||||
level.sitrepscan1_setoutline = GetDvarInt( "scr_sitrepscan1_setoutline", level.sitrepscan1_setoutline );
|
||||
level.sitrepscan1_setsolid = GetDvarInt( "scr_sitrepscan1_setsolid", level.sitrepscan1_setsolid );
|
||||
level.sitrepscan1_setlinewidth = GetDvarInt( "scr_sitrepscan1_setlinewidth", level.sitrepscan1_setlinewidth );
|
||||
level.sitrepscan1_setradius = GetDvarInt( "scr_sitrepscan1_setradius", level.sitrepscan1_setradius );
|
||||
level.sitrepscan1_setfalloff = GetDvarFloat( "scr_sitrepscan1_setfalloff", level.sitrepscan1_setfalloff );
|
||||
level.sitrepscan1_setdesat = GetDvarFloat( "scr_sitrepscan1_setdesat", level.sitrepscan1_setdesat );
|
||||
|
||||
level.sitrepscan2_enable = GetDvarInt( "scr_sitrepscan2_enable", level.sitrepscan2_enable );
|
||||
level.sitrepscan2_setoutline = GetDvarInt( "scr_sitrepscan2_setoutline", level.sitrepscan2_setoutline );
|
||||
level.sitrepscan2_setsolid = GetDvarInt( "scr_sitrepscan2_setsolid", level.sitrepscan2_setsolid );
|
||||
level.sitrepscan2_setlinewidth = GetDvarInt( "scr_sitrepscan2_setlinewidth", level.sitrepscan2_setlinewidth );
|
||||
level.sitrepscan2_setradius = GetDvarInt( "scr_sitrepscan2_setradius", level.sitrepscan2_setradius );
|
||||
level.sitrepscan2_setfalloff = GetDvarFloat( "scr_sitrepscan2_setfalloff", level.sitrepscan2_setfalloff );
|
||||
level.sitrepscan2_setdesat = GetDvarFloat( "scr_sitrepscan2_setdesat", level.sitrepscan2_setdesat );
|
||||
|
||||
level.friendlyContentOutlines = GetDvarInt( "friendlyContentOutlines", level.friendlyContentOutlines );
|
||||
|
||||
wait(1.0);
|
||||
}
|
||||
}
|
||||
#/
|
||||
|
||||
function flying_callback( local_client_num, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
||||
{
|
||||
self.flying = newVal;
|
||||
}
|
||||
|
||||
function on_local_client_connect( local_client_num )
|
||||
{
|
||||
RegisterRewindFX( local_client_num, "player/fx_plyr_footstep_tracker_l" );
|
||||
RegisterRewindFX( local_client_num, "player/fx_plyr_footstep_tracker_r" );
|
||||
RegisterRewindFX( local_client_num, "player/fx_plyr_flying_tracker_l" );
|
||||
RegisterRewindFX( local_client_num, "player/fx_plyr_flying_tracker_r" );
|
||||
RegisterRewindFX( local_client_num, "player/fx_plyr_footstep_tracker_lf" );
|
||||
RegisterRewindFX( local_client_num, "player/fx_plyr_footstep_tracker_rf" );
|
||||
RegisterRewindFX( local_client_num, "player/fx_plyr_flying_tracker_lf" );
|
||||
RegisterRewindFX( local_client_num, "player/fx_plyr_flying_tracker_rf" );
|
||||
}
|
||||
|
||||
function on_localplayer_spawned( local_client_num )
|
||||
{
|
||||
if( self != GetLocalPlayer( local_client_num ) )
|
||||
return;
|
||||
|
||||
self thread monitor_tracker_perk_killcam( local_client_num );
|
||||
self thread monitor_detectnearbyenemies( local_client_num );
|
||||
self thread monitor_tracker_existing_players( local_client_num );
|
||||
}
|
||||
|
||||
function on_player_spawned( local_client_num )
|
||||
{
|
||||
/#
|
||||
self thread watch_perks_change(local_client_num);
|
||||
#/
|
||||
self notify("perks_changed");
|
||||
self thread updateSitrepScan();
|
||||
/#
|
||||
self thread updateSitrepScan();
|
||||
#/
|
||||
self thread killTrackerFX_on_death( local_client_num );
|
||||
self thread monitor_tracker_perk( local_client_num );
|
||||
}
|
||||
|
||||
/#
|
||||
|
||||
function array_equal( &a, &b )
|
||||
{
|
||||
if ( IsDefined(a) && IsDefined(b) && IsArray(a) && IsArray(b) && a.size==b.size )
|
||||
{
|
||||
for ( i=0; i<a.size; i++ )
|
||||
{
|
||||
if (!( a[i] === b[i] ))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function watch_perks_change(local_client_num)
|
||||
{
|
||||
self notify( "watch_perks_change" );
|
||||
self endon( "entityshutdown" );
|
||||
self endon( "watch_perks_change" );
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self.last_perks = self GetPerks(local_client_num);
|
||||
while(IsDefined(self))
|
||||
{
|
||||
perks = self GetPerks(local_client_num);
|
||||
if ( !array_equal(perks,self.last_perks) )
|
||||
{
|
||||
self.last_perks = perks;
|
||||
self notify("perks_changed");
|
||||
}
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
#/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// keep the handle to the last 40 tracker fx
|
||||
// handle fx older than this are ignored
|
||||
|
||||
function get_players( local_client_num )
|
||||
{
|
||||
players = [];
|
||||
entities = GetEntArray( local_client_num );
|
||||
if (IsDefined(entities))
|
||||
{
|
||||
foreach( ent in entities )
|
||||
{
|
||||
if ( ent IsPlayer() )
|
||||
{
|
||||
players[players.size] = ent;
|
||||
}
|
||||
}
|
||||
}
|
||||
return players;
|
||||
}
|
||||
|
||||
function monitor_tracker_existing_players( local_client_num ) // self == localplayer
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon ( "monitor_tracker_existing_players" );
|
||||
self notify( "monitor_tracker_existing_players" );
|
||||
players = GetPlayers( local_client_num );
|
||||
foreach( player in players )
|
||||
{
|
||||
if ( isdefined( player ) && player != self )
|
||||
{
|
||||
player thread monitor_tracker_perk( local_client_num );
|
||||
}
|
||||
{wait(.016);};
|
||||
}
|
||||
}
|
||||
|
||||
function monitor_tracker_perk_killcam( local_client_num )
|
||||
{
|
||||
self notify( "monitor_tracker_perk_killcam" + local_client_num );
|
||||
self endon( "monitor_tracker_perk_killcam" + local_client_num );
|
||||
self endon( "entityshutdown" );
|
||||
|
||||
predictedLocalPlayer = getlocalplayer( local_client_num );
|
||||
if ( !isdefined( level.trackerSpecialtySelf ) )
|
||||
{
|
||||
level.trackerSpecialtySelf = [];
|
||||
|
||||
level.trackerSpecialtyCounter = 0;
|
||||
}
|
||||
|
||||
if ( !isdefined( level.trackerSpecialtySelf[local_client_num] ) )
|
||||
{
|
||||
level.trackerSpecialtySelf[local_client_num] = [];
|
||||
}
|
||||
|
||||
if ( predictedLocalPlayer GetInKillcam( local_client_num ) )
|
||||
{
|
||||
nonPredictedLocalPlayer = GetNonPredictedLocalPlayer( local_client_num );
|
||||
if ( predictedLocalPlayer HasPerk( local_client_num, "specialty_tracker" ) )
|
||||
{
|
||||
serverTime = getServerTime( local_client_num );
|
||||
for(count = 0; count < level.trackerSpecialtySelf[local_client_num].size; count++ )
|
||||
{
|
||||
if ( level.trackerSpecialtySelf[local_client_num][count].time < serverTime && level.trackerSpecialtySelf[local_client_num][count].time > serverTime - 5000 )
|
||||
{
|
||||
positionAndRotationStruct = level.trackerSpecialtySelf[local_client_num][count];
|
||||
tracker_playFX(local_client_num, positionAndRotationStruct);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
positionAndRotationStruct = self getTrackerFXPosition( local_client_num );
|
||||
if ( isdefined ( positionAndRotationStruct ) )
|
||||
{
|
||||
positionAndRotationStruct.time = getServerTime( local_client_num );
|
||||
|
||||
level.trackerSpecialtySelf[local_client_num][level.trackerSpecialtyCounter] = positionAndRotationStruct;
|
||||
level.trackerSpecialtyCounter++;
|
||||
if ( level.trackerSpecialtyCounter > 20 )
|
||||
{
|
||||
level.trackerSpecialtyCounter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function monitor_tracker_perk( local_client_num )
|
||||
{
|
||||
self notify( "monitor_tracker_perk" );
|
||||
self endon( "monitor_tracker_perk" );
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "entityshutdown" );
|
||||
|
||||
self.flying = false;
|
||||
self.tracker_flying = false;
|
||||
self.tracker_last_pos = self.origin;
|
||||
|
||||
offset = ( 0,0,GetDvarFloat( "perk_tracker_fx_foot_height", 0 ) );
|
||||
dist2 = ( 32 * 32 );
|
||||
|
||||
while(IsDefined(self))
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
watcher = GetLocalPlayer( local_client_num );
|
||||
|
||||
if ( !isdefined( watcher ) || self == watcher )
|
||||
return; // no need to monitor the watcher
|
||||
|
||||
if ( IsDefined( watcher ) && watcher HasPerk( local_client_num, "specialty_tracker" ) )
|
||||
{
|
||||
friend = self isFriendly( local_client_num, true );
|
||||
|
||||
camoOff = true;
|
||||
if( !isDefined( self._isClone ) || !self._isClone )
|
||||
{
|
||||
camo_val = self clientfield::get( "camo_shader" );
|
||||
if( camo_val != 0 )
|
||||
{
|
||||
camoOff = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !friend && IsAlive(self) && camoOff )
|
||||
{
|
||||
positionAndRotationStruct = self getTrackerFXPosition( local_client_num );
|
||||
if ( isdefined( positionAndRotationStruct ) )
|
||||
{
|
||||
self tracker_playFX(local_client_num, positionAndRotationStruct);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self.tracker_flying = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function tracker_playFX( local_client_num, positionAndRotationStruct )
|
||||
{
|
||||
handle = playFX( local_client_num, positionAndRotationStruct.fx, positionAndRotationStruct.pos, positionAndRotationStruct.fwd, positionAndRotationStruct.up );
|
||||
|
||||
self killTrackerFX_track( local_client_num, handle );
|
||||
}
|
||||
|
||||
function killTrackerFX_track( local_client_num, handle )
|
||||
{
|
||||
if ( handle && isdefined( self.killTrackerFX ) )
|
||||
{
|
||||
serverTime = getServerTime( local_client_num );
|
||||
|
||||
killFXStruct = SpawnStruct();
|
||||
killFXStruct.time = serverTime;
|
||||
killFXStruct.handle = handle;
|
||||
|
||||
index = self.killTrackerFX.index;
|
||||
|
||||
if ( index >= 40 )
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
self.killTrackerFX.array[index] = killFXStruct;
|
||||
self.killTrackerFX.index = index + 1;
|
||||
}
|
||||
}
|
||||
|
||||
function killTrackerFX_on_death( local_client_num )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
if ( !( isdefined( level.killTrackerFXEnable ) && level.killTrackerFXEnable ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
predictedLocalPlayer = getlocalplayer( local_client_num );
|
||||
|
||||
if ( predictedLocalPlayer == self )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isdefined( self.killTrackerFX ) )
|
||||
{
|
||||
self.killTrackerFX.array = [];
|
||||
self.killTrackerFX.index = 0;
|
||||
self.killTrackerFX = undefined;
|
||||
}
|
||||
|
||||
killTrackerFX = SpawnStruct();
|
||||
killTrackerFX.array = [];
|
||||
killTrackerFX.index = 0;
|
||||
|
||||
self.killTrackerFX = killTrackerFX;
|
||||
|
||||
self waittill( "entityshutdown" );
|
||||
|
||||
serverTime = getServerTime( local_client_num );
|
||||
|
||||
foreach( killFXStruct in killTrackerFX.array )
|
||||
{
|
||||
if ( isdefined( killFXStruct ) && killFXStruct.time + 5000 > serverTime )
|
||||
{
|
||||
KillFX( local_client_num, killFXStruct.handle );
|
||||
}
|
||||
}
|
||||
|
||||
killTrackerFX.array = [];
|
||||
killTrackerFX.index = 0;
|
||||
killTrackerFX = undefined;
|
||||
}
|
||||
|
||||
function getTrackerFXPosition( local_client_num )
|
||||
{
|
||||
positionAndRotation = undefined;
|
||||
player = self;
|
||||
if( ( isdefined( self._isClone ) && self._isClone ) )
|
||||
{
|
||||
player = self.owner;
|
||||
}
|
||||
playFastFX = player hasperk( local_client_num, "specialty_trackerjammer" );
|
||||
if ( ( isdefined( self.flying ) && self.flying ) )
|
||||
{
|
||||
offset = ( 0,0,GetDvarFloat( "perk_tracker_fx_fly_height", 0 ) );
|
||||
dist2 = ( 32 * 32 );
|
||||
if ( ( isdefined( self.trailRightFoot ) && self.trailRightFoot ) )
|
||||
{
|
||||
if ( playFastFX )
|
||||
{
|
||||
fx = "player/fx_plyr_flying_tracker_rf";
|
||||
}
|
||||
else
|
||||
{
|
||||
fx = "player/fx_plyr_flying_tracker_r";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( playFastFX )
|
||||
{
|
||||
fx = "player/fx_plyr_flying_tracker_lf";
|
||||
}
|
||||
else
|
||||
{
|
||||
fx = "player/fx_plyr_flying_tracker_l";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = ( 0,0,GetDvarFloat( "perk_tracker_fx_foot_height", 0 ) );
|
||||
dist2 = ( 32 * 32 );
|
||||
if ( ( isdefined( self.trailRightFoot ) && self.trailRightFoot ) )
|
||||
{
|
||||
if ( playFastFX )
|
||||
{
|
||||
fx = "player/fx_plyr_footstep_tracker_rf";
|
||||
}
|
||||
else
|
||||
{
|
||||
fx = "player/fx_plyr_footstep_tracker_r";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( playFastFX )
|
||||
{
|
||||
fx = "player/fx_plyr_footstep_tracker_lf";
|
||||
}
|
||||
else
|
||||
{
|
||||
fx = "player/fx_plyr_footstep_tracker_l";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pos = self.origin + offset;
|
||||
fwd = AnglesToForward( self.angles );
|
||||
right = AnglesToRight( self.angles );
|
||||
up = AnglesToUp( self.angles );
|
||||
|
||||
vel = self getvelocity();
|
||||
if (LengthSquared(vel) > ( 1 * 1 ))
|
||||
{
|
||||
up = VectorCross(vel,right);
|
||||
if ( LengthSquared( up ) < 0.0001 )
|
||||
{
|
||||
up = VectorCross(fwd, vel);
|
||||
}
|
||||
fwd = vel;
|
||||
}
|
||||
|
||||
if( self isplayer() && self isplayerwallrunning() )
|
||||
{
|
||||
if( self isplayerwallrunningright() )
|
||||
{
|
||||
up = VectorCross( up, fwd );
|
||||
}
|
||||
else
|
||||
{
|
||||
up = VectorCross( fwd, up );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !self.tracker_flying )
|
||||
{
|
||||
self.tracker_flying = true;
|
||||
self.tracker_last_pos = self.origin;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( DistanceSquared( self.tracker_last_pos, pos ) > dist2 )
|
||||
{
|
||||
positionAndRotation = SpawnStruct();
|
||||
positionAndRotation.fx = fx;
|
||||
positionAndRotation.pos = pos;
|
||||
positionAndRotation.fwd = fwd;
|
||||
positionAndRotation.up = up;
|
||||
|
||||
self.tracker_last_pos = self.origin;
|
||||
|
||||
if ( ( isdefined( self.trailRightFoot ) && self.trailRightFoot ) )
|
||||
{
|
||||
self.trailRightFoot = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.trailRightFoot = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return positionAndRotation;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function monitor_detectnearbyenemies( local_client_num )
|
||||
{
|
||||
self endon( "entityshutdown" );
|
||||
|
||||
controllerModel = GetUIModelForController( local_client_num );
|
||||
sixthsenseModel = CreateUIModel( controllerModel, "hudItems.sixthsense" );
|
||||
|
||||
enemyNearbyTime = 0.0;
|
||||
enemyLostTime = 0.0;
|
||||
previousEnemyDetectedBitField = 0;
|
||||
|
||||
SetUIModelValue( sixthsenseModel, 0 );
|
||||
|
||||
while(1)
|
||||
{
|
||||
localPlayer = GetLocalPlayer( local_client_num );
|
||||
|
||||
if ( !( localPlayer IsPlayer() ) ||
|
||||
( localPlayer HasPerk( local_client_num, "specialty_detectnearbyenemies" ) == false ) ||
|
||||
( localPlayer GetInKillcam( local_client_num ) == true || IsAlive( localPlayer ) == false ) )
|
||||
{
|
||||
SetUIModelValue( sixthsenseModel, 0 );
|
||||
previousEnemyDetectedBitField = 0;
|
||||
self util::waittill_any( "death", "spawned", "perks_changed" );
|
||||
continue;
|
||||
}
|
||||
|
||||
enemyNearbyFront = false;
|
||||
enemyNearbyBack = false;
|
||||
enemyNearbyLeft = false;
|
||||
enemyNearbyRight = false;
|
||||
enemyDetectedBitField = 0;
|
||||
|
||||
team = localPlayer.team;
|
||||
innerDetect = getdvarint( "specialty_detectnearbyenemies_inner", 1 );
|
||||
outerDetect = getdvarint( "specialty_detectnearbyenemies_outer", 1 );
|
||||
zDetect = getdvarint( "specialty_detectnearbyenemies_zthreshold", 1 );
|
||||
|
||||
localPlayerAnglesToForward = anglesToForward( localPlayer.Angles );
|
||||
|
||||
players = getplayers( local_client_num );
|
||||
clones = getclones( local_client_num );
|
||||
sixthSenseEnts = arraycombine( players, clones, false, false );
|
||||
foreach( sixthSenseEnt in sixthSenseEnts )
|
||||
{
|
||||
if ( sixthSenseEnt isfriendly( local_client_num, true ) || sixthSenseEnt == localPlayer ) // SJC: IsEntityFriendly check returns false on yourself in FFA
|
||||
continue;
|
||||
|
||||
if( !isAlive( sixthSenseEnt ) )
|
||||
continue;
|
||||
|
||||
distanceScalarSq = 1;
|
||||
zScalarSq = 1;
|
||||
|
||||
player = sixthSenseEnt;
|
||||
if( ( isdefined( sixthSenseEnt._isClone ) && sixthSenseEnt._isClone ) )
|
||||
{
|
||||
player = sixthSenseEnt.owner;
|
||||
}
|
||||
|
||||
if ( player isplayer() && player HasPerk( local_client_num, "specialty_sixthsensejammer" ) )
|
||||
{
|
||||
distanceScalarSq = GetDvarFloat( "specialty_sixthsensejammer_distance_scalar", 0.01 );
|
||||
zScalarSq = GetDvarFloat( "specialty_sixthsensejammer_z_scalar", 0.01 );
|
||||
}
|
||||
|
||||
if ( previousEnemyDetectedBitField == 0 )
|
||||
{
|
||||
distanceSq = 300 * 300 * distanceScalarSq;
|
||||
}
|
||||
else
|
||||
{
|
||||
distanceSq = 350 * 350 * distanceScalarSq;
|
||||
}
|
||||
|
||||
distCurrentSq = DistanceSquared( sixthSenseEnt.origin, localPlayer.origin );
|
||||
zdistCurrent = sixthSenseEnt.origin[2] - localPlayer.origin[2];
|
||||
zdistCurrentSq = zdistCurrent * zdistCurrent;
|
||||
if ( distCurrentSq < distanceSq )
|
||||
{
|
||||
distanceMask = 1;
|
||||
|
||||
if ( previousEnemyDetectedBitField > 16 )
|
||||
{
|
||||
zNearbyCheck = 350 * 350 * zScalarSq;
|
||||
}
|
||||
else
|
||||
{
|
||||
zNearbyCheck = 50 * 50 * zScalarSq;
|
||||
}
|
||||
|
||||
if ( zdistCurrentSq < zNearbyCheck && zDetect )
|
||||
{
|
||||
distanceMask = 16;
|
||||
}
|
||||
|
||||
vector = sixthSenseEnt.origin - localPlayer.origin;
|
||||
vector = ( vector[0], vector[1], 0 );
|
||||
vectorFlat = vectorNormalize( vector );
|
||||
cosAngle = VectorDot( vectorFlat, localPlayerAnglesToForward );
|
||||
|
||||
if ( cosAngle > 0.7071 )
|
||||
{
|
||||
enemyDetectedBitField = enemyDetectedBitField | ( ( 1 << 0 ) * distanceMask );
|
||||
|
||||
}
|
||||
else if ( cosAngle < -0.7071 )
|
||||
{
|
||||
enemyDetectedBitField = enemyDetectedBitField | ( ( 1 << 1 ) * distanceMask );
|
||||
}
|
||||
else
|
||||
{
|
||||
localPlayerAnglesToRight = anglesToRight( localPlayer.Angles );
|
||||
cosAngle = VectorDot( vectorFlat, localPlayerAnglesToRight );
|
||||
if ( cosAngle < 0 )
|
||||
{
|
||||
enemyDetectedBitField = enemyDetectedBitField | ( ( 1 << 2 ) * distanceMask );
|
||||
}
|
||||
else
|
||||
{
|
||||
enemyDetectedBitField = enemyDetectedBitField | ( ( 1 << 3 ) * distanceMask );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( enemyDetectedBitField )
|
||||
{
|
||||
enemyLostTime = 0;
|
||||
if ( previousEnemyDetectedBitField != enemyDetectedBitField && enemyNearbyTime >= 0.05 )
|
||||
{
|
||||
SetUIModelValue( sixthsenseModel, enemyDetectedBitField );
|
||||
enemyNearbyTime = 0;
|
||||
|
||||
diff = enemyDetectedBitField ^ previousEnemyDetectedBitField;
|
||||
if ( diff & enemyDetectedBitField )
|
||||
{
|
||||
// SOUND DEPT
|
||||
// player has entered area
|
||||
self playsound (0, "uin_sixth_sense_ping_on");
|
||||
}
|
||||
if ( diff & previousEnemyDetectedBitField )
|
||||
{
|
||||
// SOUND DEPT
|
||||
// player has left area
|
||||
//self playsound (0, "uin_sixth_sense_off");
|
||||
}
|
||||
|
||||
previousEnemyDetectedBitField = enemyDetectedBitField;
|
||||
}
|
||||
enemyNearbyTime += 0.05;
|
||||
}
|
||||
else
|
||||
{
|
||||
enemyNearbyTime = 0;
|
||||
if ( previousEnemyDetectedBitField != 0 && enemyLostTime >= 0.05 )
|
||||
{
|
||||
SetUIModelValue( sixthsenseModel, 0 );
|
||||
previousEnemyDetectedBitField = 0;
|
||||
}
|
||||
enemyLostTime += 0.05;
|
||||
}
|
||||
|
||||
wait( 0.05 );
|
||||
}
|
||||
SetUIModelValue( sixthsenseModel, 0 );
|
||||
}
|
||||
|
||||
+290
@@ -0,0 +1,290 @@
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\flag_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_tacticalinsertion;
|
||||
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#using scripts\mp\gametypes\_spawnlogic;
|
||||
|
||||
|
||||
#using scripts\mp\_util;
|
||||
#using scripts\mp\killstreaks\_airsupport;
|
||||
|
||||
#namespace spawning;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("perks",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
clientfield::register( "allplayers", "flying", 1, 1, "int" );
|
||||
|
||||
callback::on_connect( &on_player_connect );
|
||||
callback::on_spawned( &on_player_spawned );
|
||||
}
|
||||
|
||||
function on_player_connect( local_client_num )
|
||||
{
|
||||
}
|
||||
|
||||
function on_player_spawned( local_client_num )
|
||||
{
|
||||
self thread monitorGPSJammer();
|
||||
self thread monitorSenGrenJammer();
|
||||
self thread monitorFlight();
|
||||
}
|
||||
|
||||
function monitorFlight()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
|
||||
self.flying = false;
|
||||
while( IsDefined(self) )
|
||||
{
|
||||
flying = !( self isOnGround() );
|
||||
if ( self.flying != flying )
|
||||
{
|
||||
self clientfield::set("flying",flying);
|
||||
self.flying = flying;
|
||||
}
|
||||
|
||||
{wait(.05);};
|
||||
}
|
||||
}
|
||||
|
||||
function monitorGPSJammer()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
|
||||
|
||||
require_perk = true;
|
||||
/#
|
||||
require_perk = false;
|
||||
#/
|
||||
|
||||
if ( require_perk && self HasPerk( "specialty_gpsjammer" ) == false )
|
||||
return;
|
||||
|
||||
self clientfield::set( "gps_jammer_active", ( self HasPerk( "specialty_gpsjammer" ) ? 1 : 0 ) );
|
||||
gracePeriods = GetDvarInt( "perk_gpsjammer_graceperiods", 4 );
|
||||
minspeed = GetDvarInt( "perk_gpsjammer_min_speed", 100 );
|
||||
mindistance = GetDvarInt( "perk_gpsjammer_min_distance", 10 );
|
||||
timePeriod = GetDvarInt( "perk_gpsjammer_time_period", 200 );
|
||||
timePeriodSec = timePeriod/1000;
|
||||
minspeedSq = minspeed * minspeed;
|
||||
mindistanceSq = mindistance * mindistance;
|
||||
|
||||
if ( minspeedSq == 0 ) // will never fail min speed check below so early out.
|
||||
return;
|
||||
|
||||
assert ( timePeriodSec >= 0.05 );
|
||||
if ( timePeriodSec < 0.05 )
|
||||
return;
|
||||
|
||||
hasPerk = true;
|
||||
stateChange = false;
|
||||
failedDistanceCheck = false;
|
||||
currentFailCount = 0;
|
||||
timePassed = 0;
|
||||
timeSinceDistanceCheck = 0;
|
||||
previousOrigin = self.origin;
|
||||
GPSJammerProtection = false;
|
||||
|
||||
while(1)
|
||||
{
|
||||
/#
|
||||
gracePeriods = GetDvarInt( "perk_gpsjammer_graceperiods", gracePeriods );
|
||||
minspeed = GetDvarInt( "perk_gpsjammer_min_speed", minspeed );
|
||||
mindistance = GetDvarInt( "perk_gpsjammer_min_distance", mindistance );
|
||||
timePeriod = GetDvarInt( "perk_gpsjammer_time_period", timePeriod );
|
||||
timePeriodSec = timePeriod/1000;
|
||||
minspeedSq = minspeed * minspeed;
|
||||
mindistanceSq = mindistance * mindistance;
|
||||
#/
|
||||
GPSJammerProtection = false;
|
||||
if ( util::isUsingRemote() || ( isdefined( self.isPlanting ) && self.isPlanting ) || ( isdefined( self.isDefusing ) && self.isDefusing ) )
|
||||
{
|
||||
GPSJammerProtection = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( timeSinceDistanceCheck > 1 )
|
||||
{
|
||||
timeSinceDistanceCheck = 0;
|
||||
if ( DistanceSquared( previousOrigin, self.origin ) < mindistanceSq )
|
||||
{
|
||||
failedDistanceCheck = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
failedDistanceCheck = false;
|
||||
}
|
||||
previousOrigin = self.origin;
|
||||
}
|
||||
velocity = self GetVelocity();
|
||||
|
||||
speedsq = lengthsquared( velocity );
|
||||
|
||||
if ( speedSq > minspeedSq && failedDistanceCheck == false )
|
||||
{
|
||||
GPSJammerProtection = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( GPSJammerProtection == true && self HasPerk( "specialty_gpsjammer" ) )
|
||||
{
|
||||
/#
|
||||
if (GetDvarint( "scr_debug_perk_gpsjammer")!=0)
|
||||
{
|
||||
sphere( self.origin + (0,0,70), 12, (0,0,1), 1, true, 16, 3 );
|
||||
}
|
||||
#/
|
||||
currentFailCount = 0;
|
||||
if ( hasPerk == false )
|
||||
{
|
||||
stateChange = false;
|
||||
hasPerk = true;
|
||||
self clientfield::set( "gps_jammer_active", 1 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
currentFailCount++;
|
||||
|
||||
if ( hasPerk == true && currentFailCount >= gracePeriods )
|
||||
{
|
||||
stateChange = true;
|
||||
hasPerk = false;
|
||||
self clientfield::set( "gps_jammer_active", 0 );
|
||||
}
|
||||
}
|
||||
if ( stateChange == true )
|
||||
{
|
||||
level notify("radar_status_change");
|
||||
}
|
||||
timeSinceDistanceCheck += timePeriodSec;
|
||||
wait( timePeriodSec );
|
||||
}
|
||||
}
|
||||
|
||||
function monitorSenGrenJammer()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
|
||||
require_perk = true;
|
||||
/#
|
||||
require_perk = false;
|
||||
#/
|
||||
|
||||
if ( require_perk && self HasPerk( "specialty_sengrenjammer" ) == false )
|
||||
return;
|
||||
|
||||
self clientfield::set( "sg_jammer_active", ( self HasPerk( "specialty_sengrenjammer" ) ? 1 : 0 ) );
|
||||
gracePeriods = GetDvarInt( "perk_sgjammer_graceperiods", 4 );
|
||||
minspeed = GetDvarInt( "perk_sgjammer_min_speed", 100 );
|
||||
mindistance = GetDvarInt( "perk_sgjammer_min_distance", 10 );
|
||||
timePeriod = GetDvarInt( "perk_sgjammer_time_period", 200 );
|
||||
timePeriodSec = timePeriod/1000;
|
||||
minspeedSq = minspeed * minspeed;
|
||||
mindistanceSq = mindistance * mindistance;
|
||||
|
||||
if ( minspeedSq == 0 ) // will never fail min speed check below so early out.
|
||||
return;
|
||||
|
||||
assert ( timePeriodSec >= 0.05 );
|
||||
if ( timePeriodSec < 0.05 )
|
||||
return;
|
||||
|
||||
hasPerk = true;
|
||||
stateChange = false;
|
||||
failedDistanceCheck = false;
|
||||
currentFailCount = 0;
|
||||
timePassed = 0;
|
||||
timeSinceDistanceCheck = 0;
|
||||
previousOrigin = self.origin;
|
||||
SGJammerProtection = false;
|
||||
|
||||
while(1)
|
||||
{
|
||||
/#
|
||||
gracePeriods = GetDvarInt( "perk_sgjammer_graceperiods", gracePeriods );
|
||||
minspeed = GetDvarInt( "perk_sgjammer_min_speed", minspeed );
|
||||
mindistance = GetDvarInt( "perk_sgjammer_min_distance", mindistance );
|
||||
timePeriod = GetDvarInt( "perk_sgjammer_time_period", timePeriod );
|
||||
timePeriodSec = timePeriod/1000;
|
||||
minspeedSq = minspeed * minspeed;
|
||||
mindistanceSq = mindistance * mindistance;
|
||||
#/
|
||||
SGJammerProtection = false;
|
||||
if ( util::isUsingRemote() || ( isdefined( self.isPlanting ) && self.isPlanting ) || ( isdefined( self.isDefusing ) && self.isDefusing ) )
|
||||
{
|
||||
SGJammerProtection = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( timeSinceDistanceCheck > 1 )
|
||||
{
|
||||
timeSinceDistanceCheck = 0;
|
||||
if ( DistanceSquared( previousOrigin, self.origin ) < mindistanceSq )
|
||||
{
|
||||
failedDistanceCheck = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
failedDistanceCheck = false;
|
||||
}
|
||||
previousOrigin = self.origin;
|
||||
}
|
||||
velocity = self GetVelocity();
|
||||
|
||||
speedsq = lengthsquared( velocity );
|
||||
|
||||
if ( speedSq > minspeedSq && failedDistanceCheck == false )
|
||||
{
|
||||
SGJammerProtection = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( SGJammerProtection == true && self HasPerk( "specialty_sengrenjammer" ) )
|
||||
{
|
||||
/#
|
||||
if (GetDvarint( "scr_debug_perk_sengrenjammer")!=0)
|
||||
{
|
||||
sphere( self.origin + (0,0,65), 12, (0,1,0), 1, true, 16, 3 );
|
||||
}
|
||||
#/
|
||||
currentFailCount = 0;
|
||||
if ( hasPerk == false )
|
||||
{
|
||||
stateChange = false;
|
||||
hasPerk = true;
|
||||
self clientfield::set( "sg_jammer_active", 1 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
currentFailCount++;
|
||||
|
||||
if ( hasPerk == true && currentFailCount >= gracePeriods )
|
||||
{
|
||||
stateChange = true;
|
||||
hasPerk = false;
|
||||
self clientfield::set( "sg_jammer_active", 0 );
|
||||
}
|
||||
}
|
||||
if ( stateChange == true )
|
||||
{
|
||||
level notify("radar_status_change");
|
||||
}
|
||||
timeSinceDistanceCheck += timePeriodSec;
|
||||
wait( timePeriodSec );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,537 @@
|
||||
Line truncated
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\array_shared;
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\gameobjects_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_weaponobjects;
|
||||
#using scripts\shared\weapons\_weapons;
|
||||
|
||||
#using scripts\mp\_util;
|
||||
#using scripts\mp\gametypes\_weaponobjects;
|
||||
|
||||
|
||||
|
||||
#namespace pickup_items;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("pickup_items",&__init__,undefined,undefined); }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// group 1 - blue
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_flakjacket" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_blind_eye" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_hardline" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_ghost" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_jetsilencer" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_lightweight" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_jetcharge" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_overcharge" );
|
||||
|
||||
// group 2 - green
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_hardwired" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_scavenger" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_cold_blooded" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_fasthands" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_toughness" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_tracker" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_ante_up" );
|
||||
|
||||
// group 3 - red
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_dexterity" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_engineer" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_deadsilence" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_tacticalmask" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_awareness" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_sixthsense" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_marathon" );
|
||||
#precache( "xmodel", "p7_perk_t7_hud_perk_gungho" );
|
||||
|
||||
#precache( "objective", "pickup_item" );
|
||||
|
||||
function __init__()
|
||||
{
|
||||
callback::on_start_gametype( &start_gametype );
|
||||
|
||||
level.nullPrimaryOffhand = GetWeapon( "null_offhand_primary" );
|
||||
level.nullSecondaryOffhand = GetWeapon( "null_offhand_secondary" );
|
||||
|
||||
level.pickup_items = [];
|
||||
|
||||
level.pickupItemRespawn = true;
|
||||
}
|
||||
|
||||
function on_player_spawned() // self == player
|
||||
{
|
||||
self.pickup_damage_scale = undefined;
|
||||
self.pickup_damage_scale_time = undefined;
|
||||
}
|
||||
|
||||
function start_gametype()
|
||||
{
|
||||
callback::on_spawned( &on_player_spawned );
|
||||
|
||||
pickup_triggers = GetEntArray( "pickup_item", "targetname" );
|
||||
pickup_models = GetEntArray( "pickup_model", "targetname" );
|
||||
|
||||
visuals = [];
|
||||
|
||||
foreach( trigger in pickup_triggers )
|
||||
{
|
||||
visuals[0] = get_visual_for_trigger( trigger, pickup_models );
|
||||
assert( isDefined( visuals[0]) );
|
||||
|
||||
visuals[0] pickup_item_init();
|
||||
|
||||
pickup_item_object = gameobjects::create_use_object( "neutral", trigger, visuals, (0,0,32), istring("pickup_item") );
|
||||
pickup_item_object gameobjects::allow_use( "any" );
|
||||
pickup_item_object gameobjects::set_use_time( 0 );
|
||||
pickup_item_object.onUse = &on_touch;
|
||||
|
||||
|
||||
level.pickup_items[level.pickup_items.size] = pickup_item_object;
|
||||
}
|
||||
}
|
||||
|
||||
function get_visual_for_trigger( trigger, pickup_models )
|
||||
{
|
||||
foreach( model in pickup_models )
|
||||
{
|
||||
if ( model istouchingswept( trigger ) )
|
||||
return model;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function set_pickup_bobbing()
|
||||
{
|
||||
self Bobbing( (0,0,1), 4, 1 );
|
||||
}
|
||||
|
||||
function set_pickup_rotation()
|
||||
{
|
||||
self Rotate( (0,175,0) );
|
||||
}
|
||||
|
||||
function get_item_for_pickup()
|
||||
{
|
||||
if( self.items.size == 1 )
|
||||
{
|
||||
return self.items[0];
|
||||
}
|
||||
|
||||
if ( self.items_shuffle.size == 0 )
|
||||
{
|
||||
self.items_shuffle = ArrayCopy( self.items );
|
||||
array::randomize( self.items_shuffle );
|
||||
}
|
||||
|
||||
return array::pop_front( self.items_shuffle );
|
||||
}
|
||||
|
||||
function cycle_item()
|
||||
{
|
||||
self.current_item = self get_item_for_pickup();
|
||||
|
||||
if ( isdefined( self.current_item.model ) )
|
||||
{
|
||||
self SetModel( self.current_item.model );
|
||||
}
|
||||
}
|
||||
|
||||
function get_item_from_string_ammo(perks_string)
|
||||
{
|
||||
item_struct = SpawnStruct();
|
||||
|
||||
item_struct.name = "ammo";
|
||||
item_struct.weapon = GetWeapon( "scavenger_item" );
|
||||
item_struct.model = item_struct.weapon.worldmodel;
|
||||
self.angles = ( 0, 0, 90 );
|
||||
|
||||
self thread weapons::scavenger_think();
|
||||
|
||||
return item_struct;
|
||||
}
|
||||
|
||||
function get_item_from_string_damage(perks_string)
|
||||
{
|
||||
item_struct = SpawnStruct();
|
||||
|
||||
item_struct.name = "damage";
|
||||
item_struct.damage_scale = float(perks_string);
|
||||
item_struct.model = "wpn_t7_igc_bullet_prop";
|
||||
self.angles = ( -45, 0, 0 );
|
||||
self SetScale ( 2 );
|
||||
|
||||
return item_struct;
|
||||
}
|
||||
|
||||
function get_item_from_string_health(perks_string)
|
||||
{
|
||||
item_struct = SpawnStruct();
|
||||
|
||||
item_struct.name = "health";
|
||||
item_struct.extra_health = int(perks_string);
|
||||
item_struct.model = "p7_medical_surgical_tools_syringe";
|
||||
self.angles = ( -45, 0, 45 );
|
||||
self SetScale ( 5 );
|
||||
|
||||
return item_struct;
|
||||
}
|
||||
|
||||
function get_item_from_string_perk(perks_string)
|
||||
{
|
||||
item_struct = SpawnStruct();
|
||||
|
||||
if ( !IsDefined(level.perkSpecialties[ perks_string ]) )
|
||||
{
|
||||
/#
|
||||
util::error("Invalid perk name " + perks_string + " for pick up item at " + self.origin);
|
||||
#/
|
||||
return;
|
||||
}
|
||||
|
||||
item_struct.name = perks_string;
|
||||
item_struct.specialties = StrTok( level.perkSpecialties[ perks_string ], "|" );
|
||||
item_struct.model = "p7_perk_" + level.perkIcons[ perks_string ];
|
||||
self SetScale ( 2 );
|
||||
|
||||
return item_struct;
|
||||
}
|
||||
|
||||
function get_item_from_string_weapon(weapon_and_attachments_string)
|
||||
{
|
||||
item_struct = SpawnStruct();
|
||||
|
||||
weapon_and_attachments = strtok(weapon_and_attachments_string, "+");
|
||||
weapon_name = GetSubStr(weapon_and_attachments[0],0,weapon_and_attachments[0].size);
|
||||
|
||||
attachments = array::remove_index( weapon_and_attachments, 0 );
|
||||
|
||||
item_struct.name = weapon_name;
|
||||
item_struct.weapon = GetWeapon( weapon_name, attachments );
|
||||
item_struct.model = item_struct.weapon.worldmodel;
|
||||
self SetScale ( 1.5 );
|
||||
|
||||
return item_struct;
|
||||
}
|
||||
|
||||
function get_item_from_string( item_string )
|
||||
{
|
||||
switch( self.script_noteworthy )
|
||||
{
|
||||
case "ammo":
|
||||
return self get_item_from_string_ammo( item_string );
|
||||
case "damage":
|
||||
return self get_item_from_string_damage( item_string );
|
||||
case "health":
|
||||
return self get_item_from_string_health( item_string );
|
||||
case "perk":
|
||||
return self get_item_from_string_perk( item_string );
|
||||
case "weapon":
|
||||
return self get_item_from_string_weapon( item_string );
|
||||
}
|
||||
}
|
||||
|
||||
function init_items_for_pickup()
|
||||
{
|
||||
items_string = self.script_parameters;
|
||||
|
||||
items_array = strtok(items_string, " ");
|
||||
|
||||
items = [];
|
||||
|
||||
foreach( item_string in items_array )
|
||||
{
|
||||
items[items.size] = self get_item_from_string( item_string );
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
function pickup_item_respawn_time()
|
||||
{
|
||||
switch( self.script_noteworthy )
|
||||
{
|
||||
case "ammo":
|
||||
return 10;
|
||||
case "damage":
|
||||
return 60;
|
||||
case "health":
|
||||
return 10;
|
||||
case "perk":
|
||||
return 10;
|
||||
case "weapon":
|
||||
return 30;
|
||||
}
|
||||
}
|
||||
|
||||
function pickup_item_sound_pickup()
|
||||
{
|
||||
switch( self.script_noteworthy )
|
||||
{
|
||||
case "ammo":
|
||||
return "wpn_ammo_pickup_oldschool";
|
||||
case "damage":
|
||||
return "wpn_weap_pickup_oldschool";
|
||||
case "health":
|
||||
return "wpn_weap_pickup_oldschool";
|
||||
case "perk":
|
||||
return "wpn_weap_pickup_oldschool";
|
||||
case "weapon":
|
||||
return "wpn_weap_pickup_oldschool";
|
||||
}
|
||||
}
|
||||
|
||||
function pickup_item_sound_respawn()
|
||||
{
|
||||
switch( self.script_noteworthy )
|
||||
{
|
||||
case "ammo":
|
||||
return "wpn_ammo_pickup_oldschool";
|
||||
case "damage":
|
||||
return "wpn_weap_pickup_oldschool";
|
||||
case "health":
|
||||
return "wpn_weap_pickup_oldschool";
|
||||
case "perk":
|
||||
return "wpn_weap_pickup_oldschool";
|
||||
case "weapon":
|
||||
return "wpn_weap_pickup_oldschool";
|
||||
}
|
||||
}
|
||||
|
||||
function pickup_item_init()
|
||||
{
|
||||
self.items_shuffle = [];
|
||||
|
||||
// start the bobbing before calling the init functions so we can change the orientation of
|
||||
// the models on items without affecting the bob
|
||||
self set_pickup_bobbing();
|
||||
|
||||
self.items = self init_items_for_pickup();
|
||||
self.respawn_time = self pickup_item_respawn_time();
|
||||
self.sound_pickup = self pickup_item_sound_pickup();
|
||||
self.sound_respawn = self pickup_item_sound_respawn();
|
||||
|
||||
self set_pickup_rotation();
|
||||
self cycle_item();
|
||||
}
|
||||
|
||||
function on_touch( player )
|
||||
{
|
||||
self endon("respawned");
|
||||
|
||||
pickup_item = self.visuals[0];
|
||||
switch( pickup_item.script_noteworthy )
|
||||
{
|
||||
case "ammo":
|
||||
pickup_item on_touch_ammo( player );
|
||||
break;
|
||||
case "damage":
|
||||
pickup_item on_touch_damage( player );
|
||||
break;
|
||||
case "health":
|
||||
pickup_item on_touch_health( player );
|
||||
break;
|
||||
case "perk":
|
||||
pickup_item on_touch_perk( player );
|
||||
break;
|
||||
case "weapon":
|
||||
if ( !pickup_item on_touch_weapon( player ) )
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
pickup_item PlaySound( pickup_item.sound_pickup );
|
||||
|
||||
self gameobjects::set_model_visibility( false );
|
||||
self gameobjects::allow_use( "none" );
|
||||
|
||||
if ( level.pickupItemRespawn )
|
||||
{
|
||||
wait ( pickup_item.respawn_time );
|
||||
self thread respawn_pickup();
|
||||
}
|
||||
}
|
||||
|
||||
function respawn_pickup()
|
||||
{
|
||||
self notify("respawned");
|
||||
pickup_item = self.visuals[0];
|
||||
pickup_item PlaySound( pickup_item.sound_respawn );
|
||||
|
||||
pickup_item cycle_item();
|
||||
|
||||
self gameobjects::set_model_visibility( true );
|
||||
self gameobjects::allow_use( "any" );
|
||||
}
|
||||
|
||||
function respawn_all_pickups()
|
||||
{
|
||||
foreach( item in level.pickup_items )
|
||||
{
|
||||
item respawn_pickup();
|
||||
}
|
||||
}
|
||||
|
||||
function on_touch_ammo( player )
|
||||
{
|
||||
self notify( "scavenger", player );
|
||||
player PickupAmmoEvent();
|
||||
}
|
||||
|
||||
function on_touch_damage( player )
|
||||
{
|
||||
damage_scale_length = 15 * 1000;
|
||||
player.pickup_damage_scale = self.current_item.damage_scale;
|
||||
player.pickup_damage_scale_time = GetTime() + damage_scale_length;
|
||||
}
|
||||
|
||||
function on_touch_health( player )
|
||||
{
|
||||
if ( self.current_item.extra_health <= 100 )
|
||||
{
|
||||
health = player.health + self.current_item.extra_health;
|
||||
|
||||
if ( health > 100 )
|
||||
health = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
health = self.current_item.extra_health;
|
||||
}
|
||||
|
||||
player.health = health;
|
||||
}
|
||||
|
||||
function on_touch_perk( player )
|
||||
{
|
||||
foreach( specialty in self.current_item.specialties )
|
||||
{
|
||||
player setPerk( specialty );
|
||||
}
|
||||
}
|
||||
|
||||
function has_active_gadget()
|
||||
{
|
||||
weapons = self GetWeaponsList( true );
|
||||
foreach ( weapon in weapons )
|
||||
{
|
||||
if ( !weapon.isgadget )
|
||||
continue;
|
||||
|
||||
if ( !weapon.isheroweapon && weapon.offhandslot !== "Gadget" )
|
||||
continue;
|
||||
|
||||
slot = self GadgetGetSlot( weapon );
|
||||
if ( self GadgetIsActive( slot ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function take_player_gadgets()
|
||||
{
|
||||
weapons = self GetWeaponsList( true );
|
||||
foreach ( weapon in weapons )
|
||||
{
|
||||
if ( weapon.isgadget )
|
||||
{
|
||||
self TakeWeapon(weapon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function take_offhand_weapon( offhandSlot )
|
||||
{
|
||||
weapons = self GetWeaponsList( true );
|
||||
foreach ( weapon in weapons )
|
||||
{
|
||||
if ( weapon.offhandSlot == offhandSlot )
|
||||
{
|
||||
self TakeWeapon(weapon);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function should_switch_to_pickup_weapon( weapon )
|
||||
{
|
||||
if ( weapon.isgadget )
|
||||
return false;
|
||||
|
||||
if ( weapon.isgrenadeweapon )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function on_touch_weapon( player )
|
||||
{
|
||||
weapon = self.current_item.weapon;
|
||||
had_weapon = player HasWeapon( weapon );
|
||||
|
||||
// ammo_in_clip = GetWeaponAmmoClip( weapon );
|
||||
ammo_in_reserve = player GetWeaponAmmoStock( weapon );
|
||||
|
||||
if ( weapon.isgadget )
|
||||
{
|
||||
if ( player has_active_gadget() )
|
||||
return false;
|
||||
|
||||
// need to take away what they currently have
|
||||
player take_player_gadgets();
|
||||
}
|
||||
|
||||
if ( weapon.inventoryType == "offhand" )
|
||||
{
|
||||
player take_offhand_weapon( weapon.offhandslot );
|
||||
}
|
||||
|
||||
player PickupWeaponEvent(weapon);
|
||||
|
||||
player GiveWeapon( weapon );
|
||||
|
||||
// if for some reason we did not get the weapon drop out
|
||||
if ( !player HasWeapon( weapon ) )
|
||||
return false;
|
||||
|
||||
if ( isDefined(self.script_ammo_clip) && isDefined(self.script_ammo_extra) )
|
||||
{
|
||||
// if they already have the weapon put everything into the reserve
|
||||
if ( had_weapon )
|
||||
{
|
||||
player SetWeaponAmmoStock( weapon, ammo_in_reserve + self.script_ammo_clip + self.script_ammo_extra );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( self.script_ammo_clip >= 0 )
|
||||
{
|
||||
player SetWeaponAmmoClip( weapon, self.script_ammo_clip );
|
||||
}
|
||||
if ( self.script_ammo_extra >= 0 )
|
||||
{
|
||||
player SetWeaponAmmoStock( weapon, self.script_ammo_extra );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( weapon.isgadget )
|
||||
{
|
||||
slot = player GadgetGetSlot( weapon );
|
||||
player GadgetPowerSet( slot, 100.0 );
|
||||
}
|
||||
|
||||
if ( !had_weapon && should_switch_to_pickup_weapon( weapon ) )
|
||||
{
|
||||
player SwitchToWeapon(weapon);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_proximity_grenade;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace proximity_grenade;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("proximity_grenade",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
proximity_grenade::init_shared();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\weapons\_proximity_grenade;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#namespace proximity_grenade;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("proximity_grenade",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
proximity_grenade::init_shared();
|
||||
|
||||
level.trackProximityGrenadesOnOwner = true;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#using scripts\shared\system_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#namespace radiant_live_update;
|
||||
|
||||
/#
|
||||
function autoexec __init__sytem__() { system::register("radiant_live_update",&__init__,undefined,undefined); }
|
||||
|
||||
/* ---------------------------------------------------------------------------------
|
||||
This script handles player radiant live update commands
|
||||
-----------------------------------------------------------------------------------*/
|
||||
|
||||
function __init__()
|
||||
{
|
||||
thread scriptstruct_debug_render();
|
||||
}
|
||||
|
||||
function scriptstruct_debug_render()
|
||||
{
|
||||
while( 1 )
|
||||
{
|
||||
level waittill( "liveupdate", selected_struct );
|
||||
|
||||
if( isdefined(selected_struct) )
|
||||
{
|
||||
level thread render_struct( selected_struct );
|
||||
}
|
||||
else
|
||||
{
|
||||
level notify( "stop_struct_render" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function render_struct( selected_struct )
|
||||
{
|
||||
self endon( "stop_struct_render" );
|
||||
|
||||
if( !isdefined( selected_struct.origin ) )
|
||||
return;
|
||||
|
||||
while( isdefined( selected_struct ) )
|
||||
{
|
||||
Box( selected_struct.origin, (-16, -16, -16), (16, 16, 16), 0, (1, 0.4, 0.4) );
|
||||
{wait(.016);};
|
||||
}
|
||||
}
|
||||
|
||||
#/
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\rat_shared;
|
||||
#using scripts\shared\array_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
#using scripts\mp\bots\_bot;
|
||||
#using scripts\mp\gametypes\_dev;
|
||||
|
||||
/#
|
||||
#namespace rat;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("rat",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
rat_shared::init();
|
||||
|
||||
// Set up common function for the shared rat script commands to call
|
||||
level.rat.common.gethostplayer = &util::getHostPlayer;
|
||||
level.rat.deathCount = 0;
|
||||
rat_shared::addRATScriptCmd( "addenemy", &rscAddEnemy );
|
||||
SetDvar( "rat_death_count", 0 );
|
||||
|
||||
}
|
||||
|
||||
function rscAddEnemy( params )
|
||||
{
|
||||
player = [[level.rat.common.gethostplayer]]();
|
||||
team = "axis";
|
||||
|
||||
if( isdefined( player.pers["team"] ) )
|
||||
{
|
||||
team = util::getOtherTeam( player.pers["team"] );
|
||||
}
|
||||
|
||||
bot = dev::getOrMakeBot( team );
|
||||
if ( !isdefined( bot ) ) {
|
||||
println("Could not add test client");
|
||||
RatReportCommandResult( params._id, 0, "Could not add test client" );
|
||||
return;
|
||||
}
|
||||
|
||||
bot thread TestEnemy( team );
|
||||
bot thread DeathCounter();
|
||||
|
||||
// waiting for bot to respawn
|
||||
wait 2;
|
||||
|
||||
pos = ( Float(params.x), Float(params.y), Float(params.z) );
|
||||
bot SetOrigin(pos);
|
||||
|
||||
if( isdefined( params.ax ) )
|
||||
{
|
||||
angles = ( Float(params.ax), Float(params.ay), Float(params.az) );
|
||||
bot SetPlayerAngles(angles);
|
||||
}
|
||||
|
||||
RatReportCommandResult( params._id, 1 );
|
||||
}
|
||||
|
||||
function TestEnemy(team) // self == test client
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
while(!isdefined(self.pers["team"]))
|
||||
wait .05;
|
||||
|
||||
if ( level.teambased )
|
||||
{
|
||||
self notify("menuresponse", game["menu_team"], team);
|
||||
}
|
||||
}
|
||||
|
||||
function DeathCounter()
|
||||
{
|
||||
self waittill("death");
|
||||
level.rat.deathCount++;
|
||||
SetDvar( "rat_death_count", level.rat.deathCount );
|
||||
}
|
||||
|
||||
#/
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,296 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\system_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#namespace rewindobjects;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("rewindobjects",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
level.rewindWatcherArray = [];
|
||||
|
||||
}
|
||||
|
||||
function initRewindObjectWatchers( localClientNum )
|
||||
{
|
||||
level.rewindWatcherArray[localClientNum] = [];
|
||||
createNapalmRewindWatcher( localClientNum );
|
||||
createAirstrikeRewindWatcher( localClientNum );
|
||||
level thread watchRewindableEvents( localClientNum );
|
||||
}
|
||||
|
||||
function watchRewindableEvents( localClientNum )
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if ( isdefined( level.rewindWatcherArray[localClientNum] ) )
|
||||
{
|
||||
rewindWatcherKeys = getArrayKeys( level.rewindWatcherArray[localClientNum] );
|
||||
for ( i = 0; i < rewindWatcherKeys.size; i++ )
|
||||
{
|
||||
rewindWatcher = level.rewindWatcherArray[localClientNum][rewindWatcherKeys[i]];
|
||||
|
||||
if ( !isdefined( rewindWatcher ) )
|
||||
continue;
|
||||
|
||||
if ( !isdefined( rewindWatcher.event ) )
|
||||
continue;
|
||||
|
||||
timeKeys = getArrayKeys( rewindWatcher.event );
|
||||
for ( j = 0; j < timeKeys.size; j++ )
|
||||
{
|
||||
timeKey = timeKeys[j];
|
||||
if ( rewindWatcher.event[timeKey].inProgress == true )
|
||||
continue;
|
||||
|
||||
if ( level.serverTime >= timeKey )
|
||||
{
|
||||
rewindWatcher thread startRewindableEvent( localClientNum, timeKey );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
wait( 0.1 );
|
||||
}
|
||||
}
|
||||
|
||||
function startRewindableEvent( localClientNum, timeKey )
|
||||
{
|
||||
player = getlocalplayer( localClientNum );
|
||||
level endon( "demo_jump" + localClientNum );
|
||||
self.event[timeKey].inProgress = true;
|
||||
allFunctionsStarted = false;
|
||||
while( allFunctionsStarted == false )
|
||||
{
|
||||
allFunctionsStarted = true;
|
||||
assert(isdefined( self.timedFunctions ) );
|
||||
timedFunctionKeys = getArrayKeys( self.timedFunctions );
|
||||
|
||||
for ( i = 0; i < timedFunctionKeys.size; i++ )
|
||||
{
|
||||
timedFunction = self.timedFunctions[timedFunctionKeys[i]];
|
||||
timedFunctionKey = timedFunctionKeys[i];
|
||||
if ( self.event[timeKey].timedFunction[timedFunctionKey] == true )
|
||||
continue;
|
||||
startTime = timeKey + ( timedFunction.startTimeSec * 1000 );
|
||||
if ( startTime > level.serverTime )
|
||||
{
|
||||
allFunctionsStarted = false;
|
||||
continue;
|
||||
}
|
||||
self.event[timeKey].timedFunction[timedFunctionKey] = true;
|
||||
|
||||
level thread [[timedFunction.func]]( localClientNum, startTime, timedFunction.startTimeSec, self.event[timeKey].data );
|
||||
}
|
||||
wait( 0.1 );
|
||||
}
|
||||
}
|
||||
|
||||
function createNapalmRewindWatcher( localClientNum )
|
||||
{
|
||||
napalmRewindWatcher = createRewindWatcher( localClientNum, "napalm" );
|
||||
|
||||
timeIncreaseBetweenPlanes = 0;
|
||||
|
||||
//napalmRewindWatcher addTimedFunction( "napalmPlane", _plane::flyPlane, timeIncreaseBetweenPlanes );
|
||||
}
|
||||
|
||||
function createAirstrikeRewindWatcher( localClientNum )
|
||||
{
|
||||
airstrikeRewindWatcher = createRewindWatcher( localClientNum, "airstrike" );
|
||||
// airstrikeRewindWatcher addTimedFunction( "aistrikePlane", _airstrike::flyAirstrikePlane, 0 );
|
||||
}
|
||||
|
||||
|
||||
function createRewindWatcher( localClientNum, name )
|
||||
{
|
||||
player = getlocalplayer( localClientNum );
|
||||
if ( !isdefined(level.rewindWatcherArray[localClientNum]) )
|
||||
{
|
||||
level.rewindWatcherArray[localClientNum] = [];
|
||||
}
|
||||
|
||||
rewindWatcher = getRewindWatcher( localClientNum, name );
|
||||
|
||||
if ( !isdefined( rewindWatcher ) )
|
||||
{
|
||||
rewindWatcher = SpawnStruct();
|
||||
level.rewindWatcherArray[localClientNum][level.rewindWatcherArray[localClientNum].size] = rewindWatcher;
|
||||
}
|
||||
|
||||
rewindWatcher.name = name;
|
||||
rewindWatcher.event = [];
|
||||
|
||||
rewindWatcher thread resetOnDemoJump( localClientNum );
|
||||
|
||||
return rewindWatcher;
|
||||
}
|
||||
|
||||
function resetOnDemoJump( localClientNum )
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
level waittill( "demo_jump" + localClientNum );
|
||||
|
||||
self.inProgress = false;
|
||||
|
||||
timedFunctionKeys = getArrayKeys( self.timedFunctions );
|
||||
|
||||
for ( i = 0; i < timedFunctionKeys.size; i++ )
|
||||
{
|
||||
self.timedFunctions[timedFunctionKeys[i]].inProgress = false;
|
||||
}
|
||||
|
||||
eventKeys = getArrayKeys( self.event );
|
||||
for ( i = 0; i < eventKeys.size; i++ )
|
||||
{
|
||||
self.event[eventKeys[i]].inProgress = false;
|
||||
timedFunctionKeys = getArrayKeys( self.event[eventKeys[i]].timedFunction );
|
||||
for ( index = 0; index < timedFunctionKeys.size; index++ )
|
||||
{
|
||||
self.event[eventKeys[i]].timedFunction[timedFunctionKeys[index]] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addTimedFunction( name, func, relativeStartTimeInSecs )
|
||||
{
|
||||
if ( !isdefined(self.timedFunctions) )
|
||||
{
|
||||
self.timedFunctions = [];
|
||||
}
|
||||
|
||||
assert( !isdefined(self.timedFunctions[name] ) );
|
||||
|
||||
self.timedFunctions[name] = spawnStruct();
|
||||
self.timedFunctions[name].inProgress = false;
|
||||
self.timedFunctions[name].func = func;
|
||||
self.timedFunctions[name].startTimeSec = relativeStartTimeInSecs;
|
||||
}
|
||||
|
||||
function getRewindWatcher( localClientNum, name )
|
||||
{
|
||||
if ( !isdefined( level.rewindWatcherArray[localClientNum] ) )
|
||||
{
|
||||
return undefined;
|
||||
}
|
||||
|
||||
for ( watcher = 0; watcher < level.rewindWatcherArray[localClientNum].size; watcher++ )
|
||||
{
|
||||
if (level.rewindWatcherArray[localClientNum][watcher].name == name )
|
||||
{
|
||||
return level.rewindWatcherArray[localClientNum][watcher];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function addRewindableEventToWatcher( startTime, data )
|
||||
{
|
||||
// duplicate message
|
||||
if ( isdefined( self.event[startTime] ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self.event[startTime] = spawnStruct();
|
||||
self.event[startTime].data = data;
|
||||
self.event[startTime].inprogress = false;
|
||||
|
||||
if ( isdefined( self.timedFunctions ) )
|
||||
{
|
||||
timedFunctionKeys = getArrayKeys( self.timedFunctions );
|
||||
self.event[startTime].timedFunction = [];
|
||||
for ( i = 0; i < timedFunctionKeys.size; i++ )
|
||||
{
|
||||
timedFunctionKey = timedFunctionKeys[i];
|
||||
self.event[startTime].timedFunction[timedFunctionKey] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function serverTimedMoveTo( localClientNum, startPoint, endPoint, startTime, duration )
|
||||
{
|
||||
level endon( "demo_jump" + localClientNum );
|
||||
timeElapsed = ( level.serverTime - startTime ) * 0.001;
|
||||
assert( duration > 0 );
|
||||
doJump = true;
|
||||
if ( timeElapsed < 0.02 )
|
||||
doJump = false;
|
||||
if ( timeElapsed < duration )
|
||||
{
|
||||
moveTime = duration - timeElapsed;
|
||||
if ( doJump )
|
||||
{
|
||||
jumpPoint = getPointOnLine( startPoint, endPoint, ( timeElapsed / duration ) );
|
||||
self.origin = jumpPoint;
|
||||
}
|
||||
self moveTo( endPoint, moveTime, 0, 0 );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.origin = endPoint;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function serverTimedRotateTo( localClientNum, angles, startTime, duration, timeIn, timeout )
|
||||
{
|
||||
level endon( "demo_jump" + localClientNum );
|
||||
timeElapsed = ( level.serverTime - startTime ) * 0.001;
|
||||
if ( !isdefined ( timeIn ) )
|
||||
{
|
||||
timeIn = 0;
|
||||
}
|
||||
if ( !isdefined( timeout ) )
|
||||
{
|
||||
timeOut = 0;
|
||||
}
|
||||
|
||||
assert( duration > 0 );
|
||||
if ( timeElapsed < duration )
|
||||
{
|
||||
rotateTime = duration - timeElapsed;
|
||||
self RotateTo(angles, rotateTime, timeIn, timeOut );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.angles = angles;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function waitForServerTime( localClientNum, timeFromStart )
|
||||
{
|
||||
while( timeFromStart > level.serverTime )
|
||||
{
|
||||
{wait(.016);};
|
||||
}
|
||||
}
|
||||
|
||||
function removeClientEntOnJump( clientEnt, localClientNum )
|
||||
{
|
||||
clientEnt endon( "complete" );
|
||||
player = GetLocalPlayer( localClientNum );
|
||||
level waittill( "demo_jump" + localClientNum );
|
||||
|
||||
clientEnt notify( "delete" );
|
||||
clientEnt forcedelete();
|
||||
}
|
||||
|
||||
function getPointOnLine( startPoint, endPoint, ratio )
|
||||
{
|
||||
nextPoint = ( startPoint[0] + ( ( endPoint[0] - startPoint[0] ) * ratio ) ,
|
||||
startPoint[1] + ( ( endPoint[1] - startPoint[1] ) * ratio ) ,
|
||||
startPoint[2] + ( ( endPoint[2] - startPoint[2] ) * ratio ) );
|
||||
|
||||
return nextPoint;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_riotshield;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace riotshield;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("riotshield",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
riotshield::init_shared();
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\killstreaks_shared;
|
||||
#using scripts\shared\scoreevents_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_riotshield;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace riotshield;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("riotshield",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
riotshield::init_shared();
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\array_shared;
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#namespace rotating_object;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("rotating_object",&__init__,undefined,undefined); }
|
||||
|
||||
/*
|
||||
This script sets up functionality in multiplayer where an object can be rotated. It must be given the "rotating_object" targetname.
|
||||
It must also have a script_float, which determines how many seconds it take for the object to complete a full 360 degree rotation.
|
||||
This script is called by the _load.csc
|
||||
*/
|
||||
|
||||
function __init__()
|
||||
{
|
||||
callback::on_localclient_connect( &init );
|
||||
}
|
||||
|
||||
//Start a rotation thread on each object with the appropriate targetname and set a rotation speed dvar.
|
||||
function init( localClientNum )
|
||||
{
|
||||
rotating_objects = GetEntArray( localClientNum, "rotating_object", "targetname" );
|
||||
array::thread_all( rotating_objects,&rotating_object_think );
|
||||
}
|
||||
|
||||
//Set up rotation behvahior. 'Self' is the rotating object.
|
||||
function rotating_object_think()
|
||||
{
|
||||
self endon ("entityshutdown");
|
||||
|
||||
util::waitforallclients();
|
||||
|
||||
//I create this variable to manage what kind of rotate I want to use
|
||||
axis = "yaw";
|
||||
direction = 360;
|
||||
revolutions = 100;
|
||||
rotate_time = 12;
|
||||
|
||||
if( isdefined( self.script_noteworthy ) )
|
||||
{
|
||||
axis = self.script_noteworthy;
|
||||
}
|
||||
|
||||
if( isdefined( self.script_float ) )
|
||||
{
|
||||
//The script_float on the object determines how fast it spins, if it is defined
|
||||
rotate_time = self.script_float;
|
||||
}
|
||||
|
||||
//Prevent SRE if zero were to be passed as a time value in the rotate function
|
||||
if ( rotate_time == 0 )
|
||||
{
|
||||
//Default spin speed
|
||||
rotate_time = 12;
|
||||
}
|
||||
|
||||
if ( rotate_time < 0 )
|
||||
{
|
||||
direction *= -1;
|
||||
rotate_time *= -1;
|
||||
}
|
||||
|
||||
angles = self.angles;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
switch( axis )
|
||||
{
|
||||
case "roll":
|
||||
self RotateRoll( direction * revolutions, rotate_time * revolutions );
|
||||
break;
|
||||
|
||||
case "pitch":
|
||||
self RotatePitch( direction * revolutions, rotate_time * revolutions );
|
||||
break;
|
||||
|
||||
case "yaw":
|
||||
default:
|
||||
self RotateYaw( direction * revolutions, rotate_time * revolutions );
|
||||
break;
|
||||
}
|
||||
|
||||
self waittill( "rotatedone" );
|
||||
self.angles = angles;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_satchel_charge;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace satchel_charge;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("satchel_charge",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__( localClientNum )
|
||||
{
|
||||
satchel_charge::init_shared();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\weapons\_satchel_charge;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace satchel_charge;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("satchel_charge",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
satchel_charge::init_shared();
|
||||
}
|
||||
+1694
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,22 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\fx_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_scrambler;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
|
||||
|
||||
#namespace scrambler;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("scrambler",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
scrambler::init_shared();
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_scrambler;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace scrambler;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("scrambler",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
scrambler::init_shared();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\weapons\_sensor_grenade;
|
||||
|
||||
|
||||
Line truncated
|
||||
|
||||
#namespace sensor_grenade;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("sensor_grenade",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
sensor_grenade::init_shared();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\system_shared;
|
||||
|
||||
#namespace shoutcaster;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function is_shoutcaster(localClientNum)
|
||||
{
|
||||
return IsShoutcaster(localClientNum);
|
||||
}
|
||||
|
||||
function is_shoutcaster_using_team_identity(localClientNum)
|
||||
{
|
||||
return (is_shoutcaster(localClientNum) && GetShoutcasterSetting(localClientNum, "shoutcaster_team_identity" ));
|
||||
}
|
||||
|
||||
function get_team_color_id( localClientNum, team )
|
||||
{
|
||||
if ( team == "allies" )
|
||||
{
|
||||
return GetShoutcasterSetting(localClientNum, "shoutcaster_fe_team1_color" );
|
||||
}
|
||||
|
||||
return GetShoutcasterSetting(localClientNum, "shoutcaster_fe_team2_color" );
|
||||
}
|
||||
|
||||
function get_team_color_fx( localClientNum, team, script_bundle )
|
||||
{
|
||||
color = get_team_color_id( localClientNum, team );
|
||||
return script_bundle.objects[color].fx_colorid;
|
||||
}
|
||||
|
||||
function get_color_fx( localClientNum, script_bundle )
|
||||
{
|
||||
effects = [];
|
||||
effects["allies"] = get_team_color_fx( localClientNum, "allies", script_bundle );
|
||||
effects["axis"] = get_team_color_fx( localClientNum, "axis", script_bundle );
|
||||
return effects;
|
||||
}
|
||||
|
||||
function is_friendly( localClientNum )
|
||||
{
|
||||
localplayer = getlocalplayer( localClientNum );
|
||||
|
||||
scorepanel_flipped = GetShoutcasterSetting(localClientNum, "shoutcaster_flip_scorepanel" );
|
||||
|
||||
if ( !scorepanel_flipped )
|
||||
friendly = ( self.team == "allies" );
|
||||
else
|
||||
friendly = ( self.team == "axis" );
|
||||
|
||||
return friendly;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\math_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_smokegrenade;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace smokegrenade;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("smokegrenade",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
smokegrenade::init_shared();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#using scripts\codescripts\struct;
|
||||
#using scripts\shared\sound_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_tabun;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace tabun;
|
||||
|
||||
function init()
|
||||
{
|
||||
tabun::init_shared();
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_tacticalinsertion;
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#namespace tacticalinsertion;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("tacticalinsertion",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
tacticalinsertion::init_shared();
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_tacticalinsertion;
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#namespace tacticalinsertion;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("tacticalinsertion",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
tacticalinsertion::init_shared();
|
||||
}
|
||||
+355
@@ -0,0 +1,355 @@
|
||||
#using scripts\codescripts\struct;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\mp\killstreaks\_killstreaks;
|
||||
#using scripts\mp\gametypes\_globallogic_utils;
|
||||
#using scripts\mp\gametypes\_globallogic_audio;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\sound_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
|
||||
#namespace teamops;
|
||||
|
||||
function getTeamopsTableID()
|
||||
{
|
||||
teamopsInfoTableLoaded = false;
|
||||
teamopsInfoTableID = TableLookupFindCoreAsset( "gamedata/tables/mp/teamops.csv" );
|
||||
|
||||
if ( isdefined( teamopsInfoTableID ) )
|
||||
{
|
||||
teamopsInfoTableLoaded = true;
|
||||
}
|
||||
assert( teamopsInfoTableLoaded, "Team Ops Event Table is not loaded: " + "gamedata/tables/mp/teamops.csv" );
|
||||
return teamopsInfoTableID;
|
||||
}
|
||||
|
||||
function init()
|
||||
{
|
||||
game["teamops"] = SpawnStruct();
|
||||
|
||||
game["teamops"].data = [];
|
||||
game["teamops"].teamProgress = [];
|
||||
game["teamops"].teamopsName = undefined;
|
||||
|
||||
foreach( team in level.teams )
|
||||
{
|
||||
game["teamops"].teamProgress[team] = 0;
|
||||
}
|
||||
|
||||
level.teamopsOnProcessPlayerEvent = &teamops::processPlayerEvent;
|
||||
|
||||
tableID = getTeamopsTableID();
|
||||
|
||||
assert( isdefined( tableID ) );
|
||||
if( !isdefined( tableID ) )
|
||||
{
|
||||
game["teamops"].teamopsInitialed = false;
|
||||
return;
|
||||
}
|
||||
|
||||
for( row = 1; row < 256; row++ )
|
||||
{
|
||||
name = tableLookupColumnForRow( tableID, row, 0 );
|
||||
if( name != "" )
|
||||
{
|
||||
game["teamops"].data[name] = SpawnStruct();
|
||||
game["teamops"].data[name].description = tableLookupColumnForRow( tableID, row, 1 );
|
||||
game["teamops"].data[name].pushevent = tableLookupColumnForRow( tableID, row, 2 );
|
||||
game["teamops"].data[name].popevent = tableLookupColumnForRow( tableID, row, 3 );
|
||||
game["teamops"].data[name].resetevent = tableLookupColumnForRow( tableID, row, 4 );
|
||||
game["teamops"].data[name].count = int( tableLookupColumnForRow( tableID, row, 5 ) );
|
||||
game["teamops"].data[name].time = int( tableLookupColumnForRow( tableID, row, 6 ) );
|
||||
game["teamops"].data[name].modes = StrTok( tableLookupColumnForRow( tableID, row, 7 ), "," );
|
||||
game["teamops"].data[name].rewards = StrTok( tableLookupColumnForRow( tableID, row, 8 ), "," );
|
||||
}
|
||||
}
|
||||
|
||||
game["teamops"].teamopsInitialized = true;
|
||||
}
|
||||
|
||||
function getID( name )
|
||||
{
|
||||
tableID = getTeamopsTableID();
|
||||
for( row = 1; row < 256; row++ )
|
||||
{
|
||||
_name = tableLookupColumnForRow( tableID, row, 0 );
|
||||
if( name == _name )
|
||||
return row;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function teamOpsAllowed( name )
|
||||
{
|
||||
teamops = game["teamops"].data[name];
|
||||
|
||||
if( teamops.modes.size == 0 )
|
||||
return true;
|
||||
|
||||
for( mi = 0; mi < teamops.modes.size; mi++ )
|
||||
{
|
||||
if( teamops.modes[mi] == level.gameType )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function startTeamops( name )
|
||||
{
|
||||
level notify( "teamops_starting" );
|
||||
level.teamopsOnPlayerKilled = undefined;
|
||||
if( !teamOpsAllowed( name ) )
|
||||
return;
|
||||
|
||||
TeamOpsShowHUD( 0 );
|
||||
|
||||
preAnounceTime = GetDvarInt( "teamOpsPreanounceTime", 5 );
|
||||
|
||||
foreach( team in level.teams )
|
||||
{
|
||||
globallogic_audio::leader_dialog( "teamops_preannounce", team );
|
||||
}
|
||||
|
||||
wait ( preAnounceTime );
|
||||
|
||||
for( i = 0; i < level.players.size; i++ )
|
||||
{
|
||||
player = level.players[i];
|
||||
if( isdefined( player ) )
|
||||
player playlocalsound( "uin_objective_updated" );
|
||||
}
|
||||
|
||||
teamops = game["teamops"].data[name];
|
||||
|
||||
game["teamops"].teamopsName = name;
|
||||
game["teamops"].teamOpsID = getID( name );
|
||||
game["teamops"].teamopsRewardIndex = RandomIntRange( 0, teamops.rewards.size );
|
||||
game["teamops"].teamopsReward = teamops.rewards[game["teamops"].teamopsRewardIndex];
|
||||
game["teamops"].teamopsStartTime = GetTime();
|
||||
|
||||
foreach( team in level.teams )
|
||||
{
|
||||
game["teamops"].teamProgress[team] = 0;
|
||||
}
|
||||
|
||||
wait 0.1;
|
||||
|
||||
TeamOpsStart( game["teamops"].teamOpsID, game["teamops"].teamopsRewardIndex, game["teamops"].teamopsStartTime, teamops.time );
|
||||
|
||||
wait 0.1;
|
||||
|
||||
TeamOpsShowHUD( 1 );
|
||||
TeamOpsUpdateProgress( "axis", 0 );
|
||||
TeamOpsUpdateProgress( "allies", 0 );
|
||||
|
||||
level thread teamOpsWatcher();
|
||||
}
|
||||
|
||||
function teamOpsWatcher()
|
||||
{
|
||||
while( isdefined( game["teamops"].teamopsName ) )
|
||||
{
|
||||
time = game["teamops"].data[game["teamops"].teamopsName].time;
|
||||
if( isdefined( time ) && ( time > 0 ) )
|
||||
{
|
||||
elapsed = GetTime() - game["teamops"].teamopsStartTime;
|
||||
if( elapsed > time * 1000 )
|
||||
{
|
||||
stopTeamops();
|
||||
foreach( team in level.teams )
|
||||
{
|
||||
globallogic_audio::leader_dialog( "teamops_timeout", team );
|
||||
}
|
||||
}
|
||||
}
|
||||
wait 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
function stopTeamops()
|
||||
{
|
||||
TeamOpsShowHUD( 0 );
|
||||
game["teamops"].teamopsName = undefined;
|
||||
game["teamops"].teamopsReward = undefined;
|
||||
game["teamops"].teamopsStartTime = undefined;
|
||||
|
||||
foreach( team in level.teams )
|
||||
{
|
||||
game["teamops"].teamProgress[team] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function processPlayerEvent( event, player )
|
||||
{
|
||||
teamopsName = game["teamops"].teamopsName;
|
||||
|
||||
if( isplayer( player ) && isdefined( teamopsName ) )
|
||||
{
|
||||
level processTeamEvent( event, player, player.team );
|
||||
}
|
||||
}
|
||||
|
||||
function processTeamEvent( event, player, team )
|
||||
{
|
||||
teamopsName = game["teamops"].teamopsName;
|
||||
teamops = game["teamops"].data[teamopsName];
|
||||
|
||||
if( isdefined( teamops.pushevent ) && ( event == teamops.pushevent ) )
|
||||
{
|
||||
game["teamops"].teamProgress[team] += 1;
|
||||
level updateTeamOps( event, player, team );
|
||||
}
|
||||
|
||||
if( isdefined( teamops.popevent ) && ( event == teamops.popevent ) )
|
||||
{
|
||||
game["teamops"].teamProgress[team] -= 1;
|
||||
if( game["teamops"].teamProgress[team] < 0 )
|
||||
game["teamops"].teamProgress[team]= 0;
|
||||
level updateTeamOps( event, player, team );
|
||||
}
|
||||
|
||||
if( isdefined( teamops.resetevent ) && ( event == teamops.resetevent ) )
|
||||
{
|
||||
game["teamops"].teamProgress[team] = 0;
|
||||
level updateTeamOps( event, player, team );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function updateTeamOps( event, player, team )
|
||||
{
|
||||
teamopsName = game["teamops"].teamopsName;
|
||||
teamops = game["teamops"].data[teamopsName];
|
||||
|
||||
count_target = teamops.count;
|
||||
progress = int( ( 100 * game["teamops"].teamProgress[team] ) / count_target );
|
||||
|
||||
TeamOpsUpdateProgress( team, progress );
|
||||
|
||||
if( game["teamops"].teamProgress[team] >= teamops.count )
|
||||
{
|
||||
if( isdefined( player ) )
|
||||
{
|
||||
level thread teamOpsAcheived( player, team );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function teamOpsAcheived( player, team )
|
||||
{
|
||||
game["teamops"].teamopsName = undefined;
|
||||
wait 0.5;
|
||||
TeamOpsShowHUD( 0 );
|
||||
|
||||
wait 2;
|
||||
globallogic_audio::leader_dialog( "teamops_win", team );
|
||||
globallogic_audio::leader_dialog_for_other_teams( "teamops_lose", team );
|
||||
|
||||
player killstreaks::give( game["teamops"].teamopsReward, 1 );
|
||||
wait 2;
|
||||
player killstreaks::useKillstreak( game["teamops"].teamopsReward, 1 );
|
||||
}
|
||||
|
||||
function main()
|
||||
{
|
||||
thread watchTeamOpsTime();
|
||||
level.teamopsTargetKills = GetDvarInt( "teamOpsKillsCountTrigger_" + level.gameType, 37 );
|
||||
if ( level.teamopsTargetKills > 0 )
|
||||
{
|
||||
level.teamopsOnPlayerKilled = &teamops::onPlayerKilled;
|
||||
}
|
||||
}
|
||||
|
||||
function GetCompatibleOperation()
|
||||
{
|
||||
operations = StrTok( GetDvarString( "teamOpsName" ), "," );
|
||||
|
||||
// try to pickup a random one
|
||||
for( i = 0; i < 20; i++ )
|
||||
{
|
||||
operation = operations[RandomIntRange( 0, operations.size )];
|
||||
if( teamOpsAllowed( operation ) )
|
||||
return operation;
|
||||
}
|
||||
|
||||
// check if we have any compatible operation
|
||||
for( i = 0; i < operations.size; i++ )
|
||||
{
|
||||
operation = operations[i];
|
||||
if( teamOpsAllowed( operation ) )
|
||||
return operation;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function watchTeamOpsTime()
|
||||
{
|
||||
level endon( "teamops_starting" );
|
||||
|
||||
if ( ( isdefined( level.inPrematchPeriod ) && level.inPrematchPeriod ) )
|
||||
level waittill("prematch_over");
|
||||
|
||||
activeTeamOps = GetCompatibleOperation();
|
||||
if( !isdefined( activeTeamOps ) )
|
||||
return;
|
||||
|
||||
startDelay = GetDvarInt( "teamOpsStartDelay_" + level.gameType, 300 );
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
if( isdefined( game["teamops"].teamopsName ) )
|
||||
{
|
||||
if ( GetDvarInt( "scr_stop_teamops" ) == 1 )
|
||||
{
|
||||
teamops::stopTeamops();
|
||||
SetDvar( "scr_stop_teamops", 0 );
|
||||
}
|
||||
}
|
||||
|
||||
timePassed = globallogic_utils::getTimePassed() / 1000;
|
||||
|
||||
startTeamOps = 0;
|
||||
if( timePassed > startDelay )
|
||||
{
|
||||
level thread startTeamops( activeTeamOps );
|
||||
break;
|
||||
}
|
||||
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
|
||||
{
|
||||
level endon( "teamops_starting" );
|
||||
|
||||
if ( isPlayer( attacker ) == false || attacker.team == self.team )
|
||||
return;
|
||||
|
||||
if ( !isdefined( level.teamopsKillTracker ) )
|
||||
{
|
||||
level.teamopsKillTracker = [];
|
||||
}
|
||||
|
||||
if ( !isdefined( level.teamopsKillTracker[attacker.team] ) )
|
||||
{
|
||||
level.teamopsKillTracker[attacker.team] = 0;
|
||||
}
|
||||
|
||||
level.teamopsKillTracker[attacker.team]++;
|
||||
|
||||
if ( level.teamopsKillTracker[attacker.team] >= level.teamopsTargetKills )
|
||||
{
|
||||
activeTeamOps = GetCompatibleOperation();
|
||||
if( !isdefined( activeTeamOps ) )
|
||||
return;
|
||||
|
||||
level thread startTeamops( activeTeamOps );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\system_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#namespace teamset;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("teamset_seals",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
level.allies_team = "allies";
|
||||
level.axis_team = "axis";
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\gametypes\_perplayer;
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
function main()
|
||||
{
|
||||
level.tearradius = 170;
|
||||
level.tearheight = 128;
|
||||
level.teargasfillduration = 7; // time until gas fills the area specified
|
||||
level.teargasduration = 23; // duration gas remains in area
|
||||
level.tearsufferingduration = 3; // (duration after leaving area of effect)
|
||||
|
||||
level.teargrenadetimer = 4; // should match time to appearance of effect
|
||||
|
||||
fgmonitor = perplayer::init("tear_grenade_monitor",&startMonitoringTearUsage,&stopMonitoringTearUsage);
|
||||
perplayer::enable(fgmonitor);
|
||||
}
|
||||
|
||||
function startMonitoringTearUsage()
|
||||
{
|
||||
self thread monitorTearUsage();
|
||||
}
|
||||
function stopMonitoringTearUsage(disconnected)
|
||||
{
|
||||
self notify("stop_monitoring_tear_usage");
|
||||
}
|
||||
|
||||
function monitorTearUsage()
|
||||
{
|
||||
self endon("stop_monitoring_tear_usage");
|
||||
|
||||
wait .05;
|
||||
|
||||
weapon = GetWeapon( "tear_grenade" );
|
||||
if (!self hasWeapon( weapon ))
|
||||
return;
|
||||
|
||||
// when this player's tear grenade ammo goes down, assume the nearest "grenade" entity is a tear grenade.
|
||||
|
||||
prevammo = self getammocount( weapon );
|
||||
while(1)
|
||||
{
|
||||
ammo = self getammocount( weapon );
|
||||
if (ammo < prevammo)
|
||||
{
|
||||
num = prevammo - ammo;
|
||||
/#
|
||||
// iprintln(num);
|
||||
#/
|
||||
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 + (0,0,48));
|
||||
if (!isdefined(bestdist) || dist < bestdist)
|
||||
{
|
||||
bestdist = dist;
|
||||
bestg = g;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isdefined(bestdist))
|
||||
{
|
||||
grenades[bestg].teargrenade = true;
|
||||
grenades[bestg] thread tearGrenade_think(self.team);
|
||||
}
|
||||
}
|
||||
}
|
||||
prevammo = ammo;
|
||||
wait .05;
|
||||
}
|
||||
}
|
||||
|
||||
function tearGrenade_think(team)
|
||||
{
|
||||
// wait for death
|
||||
|
||||
// (grenade doesn't actually die until finished smoking)
|
||||
wait level.teargrenadetimer;
|
||||
|
||||
ent = spawnstruct();
|
||||
ent thread tear(self.origin);
|
||||
}
|
||||
|
||||
function tear(pos)
|
||||
{
|
||||
trig = spawn("trigger_radius", pos, 0, level.tearradius, level.tearheight);
|
||||
|
||||
//thread drawcylinder(pos, 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 + (0,0,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(); // purposely overriding old value
|
||||
if (!isdefined(player.teargassuffering))
|
||||
player thread teargassuffering();
|
||||
}
|
||||
}
|
||||
function teartimer()
|
||||
{
|
||||
wait level.teargasduration;
|
||||
self notify("tear_timeout");
|
||||
}
|
||||
|
||||
function teargassuffering()
|
||||
{
|
||||
self endon("death");
|
||||
self endon("disconnect");
|
||||
|
||||
self.teargassuffering = true;
|
||||
|
||||
if ( self util::mayApplyScreenEffect() )
|
||||
self shellshock("teargas", 60);
|
||||
|
||||
while(1)
|
||||
{
|
||||
if (gettime() - self.teargasstarttime > level.tearsufferingduration * 1000)
|
||||
break;
|
||||
|
||||
wait 1;
|
||||
}
|
||||
|
||||
self shellshock("teargas", 1);
|
||||
|
||||
if ( self util::mayApplyScreenEffect() )
|
||||
self.teargassuffering = undefined;
|
||||
}
|
||||
|
||||
function drawcylinder(pos, rad, height)
|
||||
{
|
||||
/#
|
||||
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 += .05;
|
||||
if (time > level.teargasduration)
|
||||
break;
|
||||
wait .05;
|
||||
}
|
||||
#/
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
#using scripts\codescripts\struct;
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_decoy;
|
||||
#using scripts\shared\weapons\_weaponobjects;
|
||||
#using scripts\shared\duplicaterender_mgr;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#namespace threat_detector;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("threat_detector",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
level.sensorHandle = 1;
|
||||
level.sensors = [];
|
||||
|
||||
clientfield::register( "missile", "threat_detector", 1, 1, "int", &spawnedThreatDetector,!true, !true );
|
||||
}
|
||||
|
||||
function spawnedThreatDetector( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump)
|
||||
{
|
||||
if( newVal != 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( GetLocalPlayer( localClientNum ) != self.owner )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sensorIndex = level.sensors.size;
|
||||
level.sensorHandle++;
|
||||
|
||||
level.sensors[ sensorIndex ] = spawnstruct();
|
||||
level.sensors[ sensorIndex ].handle = level.sensorHandle;
|
||||
level.sensors[ sensorIndex ].cent = self;
|
||||
level.sensors[ sensorIndex ].team = self.team;
|
||||
level.sensors[ sensorIndex ].owner = self GetOwner( localClientNum );
|
||||
|
||||
level.sensors[ sensorIndex ].owner AddSensorGrenadeArea( self.origin, level.sensorHandle );
|
||||
|
||||
self.owner thread sensorGrenadeThink( self, level.sensorHandle, localClientNum );
|
||||
self.owner thread clearThreatDetectorOnDelete( self, level.sensorHandle, localClientNum );
|
||||
}
|
||||
|
||||
function sensorGrenadeThink( sensorEnt, sensorHandle, localClientNum )
|
||||
{
|
||||
sensorEnt endon( "entityshutdown" );
|
||||
|
||||
if( isdefined( sensorEnt.owner ) == false )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while( true )
|
||||
{
|
||||
players = GetPlayers( localClientNum );
|
||||
foreach( player in players )
|
||||
{
|
||||
if( self util::IsEnemyPlayer( player ) )
|
||||
{
|
||||
if( player hasPerk( localClientNum, "specialty_nomotionsensor" ) || player hasPerk( localClientNum, "specialty_sengrenjammer" ) )
|
||||
{
|
||||
player duplicate_render::set_player_threat_detected( localClientNum, false );
|
||||
continue;
|
||||
}
|
||||
|
||||
threatDetectorRadius = GetDvarFloat( "cg_threatDetectorRadius", 0 );
|
||||
threatDetectorRadiusSqrd = threatDetectorRadius * threatDetectorRadius;
|
||||
|
||||
if( DistanceSquared( player.origin, sensorEnt.origin ) < threatDetectorRadiusSqrd )
|
||||
{
|
||||
player duplicate_render::set_player_threat_detected( localClientNum, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
player duplicate_render::set_player_threat_detected( localClientNum, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wait( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
function clearThreatDetectorOnDelete( sensorEnt, sensorHandle, localClientNum )
|
||||
{
|
||||
sensorEnt waittill( "entityshutdown" );
|
||||
|
||||
entIndex = 0;
|
||||
for( i = 0; i < level.sensors.size; i++ )
|
||||
{
|
||||
size = level.sensors.size;
|
||||
if( sensorHandle == level.sensors[ i ].handle )
|
||||
{
|
||||
level.sensors[ i ].owner RemoveSensorGrenadeArea( sensorHandle );
|
||||
entIndex = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
players = GetPlayers( localClientNum );
|
||||
foreach( player in players )
|
||||
{
|
||||
if( self util::IsEnemyPlayer( player ) )
|
||||
{
|
||||
player duplicate_render::set_player_threat_detected( localClientNum, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\challenges_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\damagefeedback_shared;
|
||||
#using scripts\shared\scoreevents_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_hacker_tool;
|
||||
#using scripts\shared\weapons\_weaponobjects;
|
||||
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
|
||||
#namespace threat_detector;
|
||||
|
||||
|
||||
function autoexec __init__sytem__() { system::register("threat_detector",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
clientfield::register( "missile", "threat_detector", 1, 1, "int" );
|
||||
callback::add_weapon_watcher( &createThreatDetectorWatcher );
|
||||
}
|
||||
|
||||
function createThreatDetectorWatcher()
|
||||
{
|
||||
watcher = self weaponobjects::createUseWeaponObjectWatcher( "threat_detector", self.team );
|
||||
watcher.headicon = false;
|
||||
watcher.onSpawn =&onSpawnThreatDetector;
|
||||
watcher.onDetonateCallback =&threatDetectorDestroyed;
|
||||
watcher.stun = &weaponobjects::weaponStun;
|
||||
watcher.stunTime = 0;
|
||||
watcher.onDamage =&watchThreatDetectorDamage;
|
||||
|
||||
watcher.enemyDestroy = true;
|
||||
}
|
||||
|
||||
function onSpawnThreatDetector( watcher, player )
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
self thread weaponobjects::onSpawnUseWeaponObject( watcher, player );
|
||||
|
||||
self SetOwner( player );
|
||||
self SetTeam( player.team );
|
||||
self.owner = player;
|
||||
|
||||
self PlayLoopSound( "wpn_sensor_nade_lp" );
|
||||
self hacker_tool::registerWithHackerTool( level.equipmentHackerToolRadius, level.equipmentHackerToolTimeMs );
|
||||
|
||||
player AddWeaponStat( self.weapon, "used", 1 );
|
||||
|
||||
self thread watchForStationary( player );
|
||||
}
|
||||
|
||||
function watchForStationary( owner )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "hacked" );
|
||||
self endon( "explode" );
|
||||
owner endon( "death" );
|
||||
owner endon( "disconnect" );
|
||||
|
||||
self waittill("stationary" );
|
||||
self clientfield::set( "threat_detector", 1 );
|
||||
}
|
||||
|
||||
function trackSensorGrenadeVictim( victim )
|
||||
{
|
||||
if( !isdefined( self.sensorGrenadeData ) )
|
||||
{
|
||||
self.sensorGrenadeData = [];
|
||||
}
|
||||
|
||||
if ( !isdefined( self.sensorGrenadeData[victim.clientid] ) )
|
||||
{
|
||||
self.sensorGrenadeData[victim.clientid] = getTime();
|
||||
}
|
||||
|
||||
self clientfield::set_to_player( "threat_detected", 1 );
|
||||
}
|
||||
|
||||
//******************************************************************
|
||||
// *
|
||||
// *
|
||||
//******************************************************************
|
||||
function threatDetectorDestroyed( attacker, weapon, target )
|
||||
{
|
||||
if ( !isdefined( weapon ) || !weapon.isEmp )
|
||||
{
|
||||
PlayFX( level._equipment_explode_fx, self.origin );
|
||||
}
|
||||
|
||||
if ( isdefined( attacker ) )
|
||||
{
|
||||
if ( self.owner util::IsEnemyPlayer( attacker ) )
|
||||
{
|
||||
attacker challenges::destroyedEquipment( weapon );
|
||||
scoreevents::processScoreEvent( "destroyed_motion_sensor", attacker, self.owner, weapon );
|
||||
}
|
||||
}
|
||||
|
||||
PlaySoundAtPosition ( "wpn_sensor_nade_explo", self.origin );
|
||||
self delete();
|
||||
}
|
||||
|
||||
//******************************************************************
|
||||
// *
|
||||
// *
|
||||
//******************************************************************
|
||||
function watchThreatDetectorDamage( watcher ) // self == sensor grenade
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "hacked" );
|
||||
|
||||
self SetCanDamage( true );
|
||||
damageMax = 1;
|
||||
|
||||
if ( !self util::isHacked() )
|
||||
{
|
||||
self.damageTaken = 0;
|
||||
}
|
||||
|
||||
while( true )
|
||||
{
|
||||
self.maxhealth = 100000;
|
||||
self.health = self.maxhealth;
|
||||
|
||||
self waittill( "damage", damage, attacker, direction, point, type, tagName, modelName, partname, weapon, iDFlags );
|
||||
|
||||
if( !isdefined( attacker ) || !isplayer( attacker ) )
|
||||
continue;
|
||||
|
||||
if ( level.teambased && IsPlayer( attacker ) )
|
||||
{
|
||||
// if we're not hardcore and the team is the same, do not destroy
|
||||
if( !level.hardcoreMode && self.owner.team == attacker.pers["team"] && self.owner != attacker )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// most equipment should be flash/concussion-able, so it'll disable for a short period of time
|
||||
// check to see if the equipment has been flashed/concussed and disable it (checking damage < 5 is a bad idea, so check the weapon name)
|
||||
// we're currently allowing the owner/teammate to flash their own
|
||||
// do damage feedback
|
||||
if ( watcher.stunTime > 0 && weapon.doStun )
|
||||
{
|
||||
self thread weaponobjects::stunStart( watcher, watcher.stunTime );
|
||||
}
|
||||
|
||||
if ( weapon.doDamageFeedback )
|
||||
{
|
||||
// if we're not on the same team then show damage feedback
|
||||
if ( level.teambased && self.owner.team != attacker.team )
|
||||
{
|
||||
if ( damagefeedback::doDamageFeedback( weapon, attacker ) )
|
||||
attacker damagefeedback::update();
|
||||
}
|
||||
// for ffa just make sure the owner isn't the same
|
||||
else if ( !level.teambased && self.owner != attacker )
|
||||
{
|
||||
if ( damagefeedback::doDamageFeedback( weapon, attacker ) )
|
||||
attacker damagefeedback::update();
|
||||
}
|
||||
}
|
||||
|
||||
if ( type == "MOD_MELEE" || weapon.isEmp )
|
||||
{
|
||||
self.damageTaken = damageMax;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.damageTaken += damage;
|
||||
}
|
||||
|
||||
if( self.damageTaken >= damageMax )
|
||||
{
|
||||
watcher thread weaponobjects::waitAndDetonate( self, 0.0, attacker, weapon );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons\_trophy_system;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace trophy_system;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("trophy_system",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__( localClientNum )
|
||||
{
|
||||
trophy_system::init_shared();
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\weapons\_trophy_system;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace trophy_system;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("trophy_system",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
trophy_system::init_shared();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#namespace util;
|
||||
|
||||
|
||||
|
||||
+1270
File diff suppressed because it is too large.
Load diff
+202
@@ -0,0 +1,202 @@
|
||||
#using scripts\shared\clientfield_shared;
|
||||
#using scripts\shared\math_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\vehicle_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
|
||||
//Vehicle registration
|
||||
#using scripts\mp\killstreaks\_ai_tank;
|
||||
#using scripts\mp\killstreaks\_qrdrone;
|
||||
#using scripts\mp\killstreaks\_rcbomb;
|
||||
|
||||
#namespace vehicle;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("vehicle",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
if( !isdefined( level._effect ) )
|
||||
{
|
||||
level._effect = [];
|
||||
}
|
||||
level.vehicles_inited = true;
|
||||
|
||||
clientfield::register( "vehicle", "timeout_beep", 1, 2, "int",&timeout_beep, !true, !true );
|
||||
}
|
||||
|
||||
function vehicle_rumble(localClientNum)
|
||||
{
|
||||
self endon( "entityshutdown" );
|
||||
|
||||
if(!isdefined(level.vehicle_rumble))
|
||||
return;
|
||||
|
||||
type = self.vehicletype;
|
||||
|
||||
if( !isdefined( level.vehicle_rumble[ type ] ) )
|
||||
return;
|
||||
|
||||
rumblestruct = level.vehicle_rumble[ type ];
|
||||
height = rumblestruct.radius * 2;
|
||||
zoffset = -1 * rumblestruct.radius;
|
||||
|
||||
if( !isdefined( self.rumbleon ) )
|
||||
self.rumbleon = true;
|
||||
|
||||
if( isdefined( rumblestruct.scale ) )
|
||||
self.rumble_scale = rumblestruct.scale;
|
||||
else
|
||||
self.rumble_scale = 0.15;
|
||||
|
||||
if( isdefined( rumblestruct.duration ) )
|
||||
self.rumble_duration = rumblestruct.duration;
|
||||
else
|
||||
self.rumble_duration = 4.5;
|
||||
|
||||
if( isdefined( rumblestruct.radius ) )
|
||||
self.rumble_radius = rumblestruct.radius;
|
||||
else
|
||||
self.rumble_radius = 600;
|
||||
if( isdefined( rumblestruct.basetime ) )
|
||||
self.rumble_basetime = rumblestruct.basetime;
|
||||
else
|
||||
self.rumble_basetime = 1;
|
||||
if( isdefined( rumblestruct.randomaditionaltime ) )
|
||||
self.rumble_randomaditionaltime = rumblestruct.randomaditionaltime;
|
||||
else
|
||||
self.rumble_randomaditionaltime = 1;
|
||||
|
||||
self.player_touching = 0;
|
||||
|
||||
// This is threaded on each vehicle, per local client - so we only need to be concerned with checking on
|
||||
// client that we've been threaded on.
|
||||
|
||||
radius_squared = rumblestruct.radius * rumblestruct.radius;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
if( (distancesquared(self.origin, level.localPlayers[localClientNum].origin) > radius_squared) || self getspeed() < 35 )
|
||||
{
|
||||
wait(0.2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(isdefined(self.rumbleon) && !self.rumbleon)
|
||||
{
|
||||
wait(0.2);
|
||||
continue;
|
||||
}
|
||||
|
||||
self PlayRumbleLoopOnEntity( localClientNum, level.vehicle_rumble[ type ].rumble );
|
||||
|
||||
while((distancesquared(self.origin, level.localPlayers[localClientNum].origin) < radius_squared) && (self getspeed() > 5))
|
||||
{
|
||||
//self earthquake( self.rumble_scale, self.rumble_duration, self.origin, self.rumble_radius ); // scale duration source radius
|
||||
wait( self.rumble_basetime + randomfloat( self.rumble_randomaditionaltime ) );
|
||||
}
|
||||
|
||||
self StopRumble( localClientNum, level.vehicle_rumble[ type ].rumble );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function set_static_amount( staticAmount )
|
||||
{
|
||||
driverLocalClient = self GetLocalClientDriver();
|
||||
if ( isdefined( driverLocalClient ) )
|
||||
{
|
||||
driver = GetLocalPlayer( driverLocalClient );
|
||||
if ( isdefined( driver ) )
|
||||
{
|
||||
setfilterpassconstant( driver.localClientNum, 4, 0, 1, staticAmount );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function vehicle_variants( localClientNum )
|
||||
{
|
||||
// NOT YET SUPPORTED IN MP
|
||||
/*if(isdefined(level.vehicleGearModels))
|
||||
{
|
||||
if(isdefined(level.vehicleGearModels[self.vehicletype]))
|
||||
{
|
||||
numGear = level.vehicleGearModels[self.vehicletype].size;
|
||||
maxGear = 2;
|
||||
if(numGear<maxGear)
|
||||
{
|
||||
maxGear = numGear;
|
||||
}
|
||||
maxGear = randomInt(maxGear+1);
|
||||
for(i=0;i<maxGear;i++)
|
||||
{
|
||||
alreadyChosen = true;
|
||||
gearChoices[i] = -1;
|
||||
while(alreadyChosen)
|
||||
{
|
||||
alreadyChosen = false;
|
||||
gearChoices[i] = randomInt(numGear);
|
||||
for(j=0;j<i;j++)
|
||||
{
|
||||
if(gearChoices[j]==gearChoices[i])
|
||||
{
|
||||
alreadyChosen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
self attach(level.vehicleGearModels[self.vehicletype][gearChoices[i]],level.vehicleGearTags[self.vehicletype][gearChoices[i]]);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
function timeout_beep( localClientNum, oldVal, newVal, bNewEnt, bInitialSnap, fieldName, bWasTimeJump )
|
||||
{
|
||||
self notify( "timeout_beep" );
|
||||
|
||||
if ( !newVal )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isdefined( self.killstreakBundle ) )
|
||||
{
|
||||
beepAlias = self.killstreakBundle.ksTimeoutBeepAlias;
|
||||
}
|
||||
|
||||
self endon( "entityshutdown" );
|
||||
self endon( "timeout_beep" );
|
||||
|
||||
interval = 1;
|
||||
|
||||
if ( newVal == 2 )
|
||||
{
|
||||
interval = 0.133;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
if ( isdefined( beepAlias ) )
|
||||
{
|
||||
self PlaySound( localClientNum, beepAlias );
|
||||
}
|
||||
|
||||
if ( self.timeoutLightsOff === true )
|
||||
{
|
||||
self vehicle::lights_on( localClientNum );
|
||||
self.timeoutLightsOff = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
self vehicle::lights_off( localClientNum );
|
||||
self.timeoutLightsOff = true;
|
||||
}
|
||||
|
||||
util::server_wait( localClientNum, interval );
|
||||
interval = math::clamp( ( interval / 1.17 ), 0.1, 1 );
|
||||
}
|
||||
}
|
||||
+2383
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,191 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\filter_shared;
|
||||
#using scripts\shared\postfx_shared;
|
||||
#using scripts\shared\trigger_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\water_surface;
|
||||
|
||||
#using scripts\mp\_load;
|
||||
#using scripts\mp\_util;
|
||||
|
||||
Line truncated
|
||||
|
||||
#namespace waterfall;
|
||||
|
||||
function waterfallOverlay( localClientNum )
|
||||
{
|
||||
triggers = GetEntArray( localClientNum, "waterfall", "targetname" );
|
||||
foreach( trigger in triggers )
|
||||
{
|
||||
trigger thread setupWaterfall( localClientNum );
|
||||
}
|
||||
}
|
||||
|
||||
function waterfallMistOverlay( localClientNum )
|
||||
{
|
||||
triggers = GetEntArray( localClientNum, "waterfall_mist", "targetname" );
|
||||
foreach( trigger in triggers )
|
||||
{
|
||||
trigger thread setupWaterfallMist( localClientNum );
|
||||
}
|
||||
}
|
||||
|
||||
function waterfallMistOverlayReset( localClientNum )
|
||||
{
|
||||
localPlayer = GetLocalPlayer( localClientNum );
|
||||
localPlayer.rainOpacity = 0.0;
|
||||
}
|
||||
|
||||
function setupWaterfallMist( localClientNum )
|
||||
{
|
||||
level notify( "setupWaterfallmist_waterfall_csc" + localclientnum );
|
||||
level endon ( "setupWaterfallmist_waterfall_csc" + localclientnum );
|
||||
|
||||
trigger = self;
|
||||
for(;;)
|
||||
{
|
||||
trigger waittill( "trigger", trigPlayer );
|
||||
|
||||
if ( !trigPlayer islocalplayer() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
localclientnum = trigPlayer getlocalclientnumber();
|
||||
if ( isdefined( localclientnum ) )
|
||||
{
|
||||
localplayer = getlocalplayer( localclientnum );
|
||||
}
|
||||
else
|
||||
{
|
||||
localplayer = trigPlayer;
|
||||
}
|
||||
|
||||
filter::init_filter_sprite_rain( localplayer );
|
||||
trigger thread trigger::function_thread( localplayer, &trig_enter_waterfall_mist, &trig_leave_waterfall_mist );
|
||||
}
|
||||
}
|
||||
|
||||
function setupWaterfall( localClientNum, localowner )
|
||||
{
|
||||
level notify( "setupWaterfall_waterfall_csc" + localclientnum );
|
||||
level endon ( "setupWaterfall_waterfall_csc" + localclientnum );
|
||||
|
||||
trigger = self;
|
||||
for(;;)
|
||||
{
|
||||
trigger waittill( "trigger", trigPlayer );
|
||||
|
||||
if ( !trigPlayer islocalplayer() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
localclientnum = trigPlayer getlocalclientnumber();
|
||||
if ( isdefined( localclientnum ) )
|
||||
{
|
||||
localplayer = getlocalplayer( localclientnum );
|
||||
}
|
||||
else
|
||||
{
|
||||
localplayer = trigPlayer;
|
||||
}
|
||||
|
||||
trigger thread trigger::function_thread( localplayer, &trig_enter_waterfall, &trig_leave_waterfall );
|
||||
}
|
||||
}
|
||||
|
||||
function trig_enter_waterfall( localplayer )
|
||||
{
|
||||
trigger = self;
|
||||
localclientnum = localplayer.localclientnum;
|
||||
localplayer thread postfx::playPostfxBundle( "pstfx_waterfall" );
|
||||
|
||||
playsound(0, "amb_waterfall_hit", (0,0,0));
|
||||
|
||||
while ( trigger istouching( localplayer ) )
|
||||
{
|
||||
localplayer PlayRumbleOnEntity( localClientNum, "waterfall_rumble" );
|
||||
wait( 0.1 );
|
||||
}
|
||||
}
|
||||
|
||||
function trig_leave_waterfall( localplayer )
|
||||
{
|
||||
trigger = self;
|
||||
localClientNum = localplayer.localClientNum;
|
||||
localplayer postfx::StopPostfxBundle();
|
||||
if ( IsUnderwater( localClientNum ) == false )
|
||||
{
|
||||
localplayer thread water_surface::startWaterSheeting();
|
||||
}
|
||||
}
|
||||
|
||||
function trig_enter_waterfall_mist( localPlayer )
|
||||
{
|
||||
localPlayer endon( "entityshutdown" );
|
||||
trigger = self;
|
||||
|
||||
if ( !isdefined( localPlayer.rainOpacity ) )
|
||||
localPlayer.rainOpacity = 0;
|
||||
|
||||
if ( localPlayer.rainOpacity == 0 )
|
||||
{
|
||||
filter::set_filter_sprite_rain_seed_offset( localPlayer, 0, RandomFloat( 1 ) );
|
||||
}
|
||||
|
||||
filter::enable_filter_sprite_rain( localPlayer, 0 );
|
||||
while ( trigger istouching( localPlayer ) )
|
||||
{
|
||||
localClientNum = trigger.localClientNum;
|
||||
if ( !isdefined( localClientNum ) )
|
||||
{
|
||||
localClientNum = localPlayer getlocalclientnumber();
|
||||
}
|
||||
if ( IsUnderwater( localClientNum ) )
|
||||
{
|
||||
filter::disable_filter_sprite_rain( localPlayer, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
localPlayer.rainOpacity += 0.003;
|
||||
if ( localPlayer.rainOpacity > 1 )
|
||||
{
|
||||
localPlayer.rainOpacity = 1;
|
||||
}
|
||||
filter::set_filter_sprite_rain_opacity( localPlayer, 0, localPlayer.rainOpacity );
|
||||
filter::set_filter_sprite_rain_elapsed( localPlayer, 0, localPlayer getClientTime() );
|
||||
|
||||
{wait(.016);};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function trig_leave_waterfall_mist( localPlayer )
|
||||
{
|
||||
localPlayer endon( "entityshutdown" );
|
||||
trigger = self;
|
||||
|
||||
if ( isdefined( localPlayer.rainOpacity ) )
|
||||
{
|
||||
while ( !( trigger istouching( localPlayer ) ) && localPlayer.rainOpacity > 0.0 )
|
||||
{
|
||||
localClientNum = trigger.localClientNum;
|
||||
if ( IsUnderwater( localClientNum ) )
|
||||
{
|
||||
filter::disable_filter_sprite_rain( localPlayer, 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
localPlayer.rainOpacity -= 0.005;
|
||||
filter::set_filter_sprite_rain_opacity( localPlayer, 0, localPlayer.rainOpacity );
|
||||
filter::set_filter_sprite_rain_elapsed( localPlayer, 0, localPlayer getClientTime() );
|
||||
{wait(.016);};
|
||||
}
|
||||
}
|
||||
|
||||
localPlayer.rainOpacity = 0;
|
||||
filter::disable_filter_sprite_rain( localPlayer, 0 );
|
||||
}
|
||||
@@ -0,0 +1,954 @@
|
||||
#using scripts\codescripts\struct;
|
||||
#using scripts\shared\array_shared;
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\killstreaks_shared;
|
||||
#using scripts\shared\math_shared;
|
||||
#using scripts\shared\rank_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons_shared;
|
||||
#using scripts\shared\weapons\_weapons;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
|
||||
#using scripts\shared\bots\_bot;
|
||||
#using scripts\shared\bots\_bot_combat;
|
||||
#using scripts\shared\bots\bot_traversals;
|
||||
#using scripts\shared\bots\bot_buttons;
|
||||
#using scripts\mp\bots\_bot_ball;
|
||||
#using scripts\mp\bots\_bot_clean;
|
||||
#using scripts\mp\bots\_bot_combat;
|
||||
#using scripts\mp\bots\_bot_conf;
|
||||
#using scripts\mp\bots\_bot_ctf;
|
||||
#using scripts\mp\bots\_bot_dem;
|
||||
#using scripts\mp\bots\_bot_dom;
|
||||
#using scripts\mp\bots\_bot_escort;
|
||||
#using scripts\mp\bots\_bot_hq;
|
||||
#using scripts\mp\bots\_bot_koth;
|
||||
#using scripts\mp\bots\_bot_loadout;
|
||||
#using scripts\mp\bots\_bot_sd;
|
||||
|
||||
#using scripts\mp\killstreaks\_killstreakrules;
|
||||
#using scripts\mp\killstreaks\_killstreaks;
|
||||
#using scripts\mp\killstreaks\_uav;
|
||||
#using scripts\mp\killstreaks\_satellite;
|
||||
#using scripts\mp\killstreaks\_emp;
|
||||
#using scripts\mp\teams\_teams;
|
||||
#using scripts\mp\_util;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#namespace bot;
|
||||
|
||||
function autoexec __init__sytem__() { system::register("bot_mp",&__init__,undefined,undefined); }
|
||||
|
||||
function __init__()
|
||||
{
|
||||
callback::on_start_gametype( &init );
|
||||
|
||||
level.getBotSettings = &get_bot_settings;
|
||||
|
||||
level.onBotConnect = &on_bot_connect;
|
||||
level.onBotSpawned = &on_bot_spawned;
|
||||
level.onBotKilled = &on_bot_killed;
|
||||
|
||||
level.botIdle = &bot_idle;
|
||||
|
||||
level.botThreatLost = &bot_combat::chase_threat;
|
||||
|
||||
level.botPreCombat = &bot_combat::mp_pre_combat;
|
||||
level.botCombat = &bot_combat::combat_think;
|
||||
level.botPostCombat = &bot_combat::mp_post_combat;
|
||||
|
||||
level.botIgnoreThreat = &bot_combat::bot_ignore_threat;
|
||||
|
||||
level.enemyEmpActive = &emp::EnemyEmpActive;
|
||||
|
||||
/#
|
||||
level.botDevguiCmd = &bot_devgui_cmd;
|
||||
level thread system_devgui_gadget_think();
|
||||
#/
|
||||
}
|
||||
|
||||
function init()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
level.botSoak = is_bot_soak();
|
||||
|
||||
if ( ( level.rankedMatch && !level.botSoak ) || !init_bot_gametype() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
wait_for_host();
|
||||
|
||||
level thread populate_bots();
|
||||
}
|
||||
|
||||
// Init Utils
|
||||
//========================================
|
||||
|
||||
function is_bot_soak()
|
||||
{
|
||||
/#
|
||||
return GetDvarInt( "sv_botsoak", 0 );
|
||||
#/
|
||||
return IsDedicated() && GetDvarInt( "sv_botsoak", 0 );
|
||||
}
|
||||
|
||||
function wait_for_host()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
if ( level.botSoak )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
host = util::getHostPlayerForBots();
|
||||
|
||||
while ( !isdefined( host ) )
|
||||
{
|
||||
wait( 0.25 );
|
||||
host = util::getHostPlayerForBots();
|
||||
}
|
||||
}
|
||||
|
||||
function get_host_team()
|
||||
{
|
||||
host = util::getHostPlayerForBots();
|
||||
|
||||
if ( !isdefined( host ) || host.team == "spectator" )
|
||||
{
|
||||
return "allies";
|
||||
}
|
||||
|
||||
return host.team;
|
||||
}
|
||||
|
||||
function is_bot_comp_stomp()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Bot Events
|
||||
//========================================
|
||||
|
||||
function on_bot_connect()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
if ( ( isdefined( level.disableClassSelection ) && level.disableClassSelection ) )
|
||||
{
|
||||
self set_rank();
|
||||
|
||||
// Doesn't work if we don't do it in this order
|
||||
self bot_loadout::pick_hero_gadget();
|
||||
self bot_loadout::pick_killstreaks();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !( isdefined( self.pers["bot_loadout"] ) && self.pers["bot_loadout"] ) )
|
||||
{
|
||||
self set_rank();
|
||||
|
||||
// Doesn't work if we don't do it in this order
|
||||
self bot_loadout::build_classes();
|
||||
self bot_loadout::pick_hero_gadget();
|
||||
self bot_loadout::pick_killstreaks();
|
||||
|
||||
self.pers["bot_loadout"] = true;
|
||||
}
|
||||
|
||||
self bot_loadout::pick_classes();
|
||||
self choose_class();
|
||||
}
|
||||
|
||||
function on_bot_spawned()
|
||||
{
|
||||
self.bot.goalTag = undefined;
|
||||
/#
|
||||
weapon = undefined;
|
||||
|
||||
if ( GetDvarInt( "scr_botsHasPlayerWeapon" ) != 0 )
|
||||
{
|
||||
player = util::getHostPlayer();
|
||||
weapon = player GetCurrentWeapon();
|
||||
}
|
||||
|
||||
if ( GetDvarString( "devgui_bot_weapon", "" ) != "" )
|
||||
{
|
||||
weapon = GetWeapon( GetDvarString( "devgui_bot_weapon" ) );
|
||||
}
|
||||
|
||||
if ( isdefined( weapon ) && level.weaponNone != weapon )
|
||||
{
|
||||
self weapons::detach_all_weapons();
|
||||
self TakeAllWeapons();
|
||||
self GiveWeapon( weapon );
|
||||
self SwitchToWeapon( weapon );
|
||||
self SetSpawnWeapon( weapon );
|
||||
|
||||
self teams::set_player_model( self.team, weapon );
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
function on_bot_killed()
|
||||
{
|
||||
self endon("disconnect");
|
||||
level endon( "game_ended" );
|
||||
self endon( "spawned" );
|
||||
self waittill ( "death_delay_finished" );
|
||||
|
||||
wait 0.1;
|
||||
|
||||
if ( self choose_class() && level.playerForceRespawn )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self thread respawn();
|
||||
}
|
||||
|
||||
function respawn()
|
||||
{
|
||||
self endon( "spawned" );
|
||||
self endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
self bot::tap_use_button();
|
||||
|
||||
wait 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
function bot_idle()
|
||||
{
|
||||
if ( self do_supplydrop() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Look for an enemy radar blip
|
||||
// TODO: Get points on navmesh and feed into the spawn system to see if an enemy is likely to spawn there
|
||||
self bot::navmesh_wander();
|
||||
self bot::sprint_to_goal();
|
||||
}
|
||||
|
||||
// Crate maxs: 23.1482
|
||||
|
||||
// Wild guess on usable radius
|
||||
|
||||
function do_supplydrop( maxRange = 1400 ) // A little under minimap width
|
||||
{
|
||||
crates = GetEntArray( "care_package", "script_noteworthy" );
|
||||
|
||||
maxRangeSq = maxRange * maxRange;
|
||||
|
||||
useRadiusSq = 62 * 62;
|
||||
|
||||
closestCrate = undefined;
|
||||
closestCrateDistSq = undefined;
|
||||
|
||||
foreach( crate in crates )
|
||||
{
|
||||
if ( !crate IsOnGround() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
crateDistSq = Distance2DSquared( self.origin, crate.origin );
|
||||
|
||||
if ( crateDistSq > maxRangeSq )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
inUse = isdefined( crate.useEnt ) && ( isdefined( crate.useEnt.inUse ) && crate.useEnt.inUse );
|
||||
|
||||
if ( crateDistSq <= useRadiusSq )
|
||||
{
|
||||
if ( inUse && !self useButtonPressed() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
self bot::press_use_button();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( !self has_minimap() && !self BotSightTracePassed( crate ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !isdefined( closestCrate ) || crateDistSq < closestCrateDistSq )
|
||||
{
|
||||
closestCrate = crate;
|
||||
closestCrateDistSq = crateDistSq;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isdefined( closestCrate ) )
|
||||
{
|
||||
randomAngle = ( 0, RandomInt( 360 ), 0 );
|
||||
randomVec = AnglesToForward( randomAngle );
|
||||
|
||||
point = closestCrate.origin + randomVec * 39;
|
||||
|
||||
if ( self BotSetGoal( point ) )
|
||||
{
|
||||
self thread watch_crate( closestCrate );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function watch_crate( crate )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "bot_goal_reached" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
while ( isdefined( crate ) && !self bot_combat::has_threat() )
|
||||
{
|
||||
wait level.botSettings.thinkInterval;
|
||||
}
|
||||
|
||||
self BotSetGoal( self.origin );
|
||||
}
|
||||
|
||||
// Bot Team Population
|
||||
//========================================
|
||||
|
||||
function populate_bots()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
if ( level.teambased )
|
||||
{
|
||||
maxAllies = GetDvarInt( "bot_maxAllies", 0 );
|
||||
maxAxis = GetDvarInt( "bot_maxAxis", 0 );
|
||||
|
||||
level thread monitor_bot_team_population( maxAllies, maxAxis );
|
||||
}
|
||||
else
|
||||
{
|
||||
maxFree = GetDvarInt( "bot_maxFree", 0 );
|
||||
|
||||
level thread monitor_bot_population( maxFree );
|
||||
}
|
||||
}
|
||||
|
||||
function monitor_bot_team_population( maxAllies, maxAxis )
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
if ( !maxAllies && !maxAxis )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
fill_balanced_teams( maxAllies, maxAxis );
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
wait 3;
|
||||
|
||||
// TODO: Get a player count that includes 'CON_CONNECTING' players
|
||||
allies = GetPlayers( "allies" );
|
||||
axis = GetPlayers( "axis" );
|
||||
|
||||
if ( allies.size > maxAllies &&
|
||||
remove_best_bot( allies ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( axis.size > maxAxis &&
|
||||
remove_best_bot( axis ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( allies.size < maxAllies || axis.size < maxAxis )
|
||||
{
|
||||
add_balanced_bot( allies, maxAllies, axis, maxAxis );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fill_balanced_teams( maxAllies, maxAxis )
|
||||
{
|
||||
allies = GetPlayers( "allies" );
|
||||
axis = GetPlayers( "axis" );
|
||||
|
||||
while ( ( allies.size < maxAllies || axis.size < maxAxis ) &&
|
||||
add_balanced_bot( allies, maxAllies, axis, maxAxis ) )
|
||||
{
|
||||
{wait(.05);};
|
||||
|
||||
allies = GetPlayers( "allies" );
|
||||
axis = GetPlayers( "axis" );
|
||||
}
|
||||
}
|
||||
|
||||
function add_balanced_bot( allies, maxAllies, axis, maxAxis )
|
||||
{
|
||||
bot = undefined;
|
||||
|
||||
if ( allies.size < maxAllies &&
|
||||
( allies.size <= axis.size || axis.size >= maxAxis ) )
|
||||
{
|
||||
bot = add_bot( "allies" );
|
||||
}
|
||||
else if ( axis.size < maxAxis )
|
||||
{
|
||||
bot = add_bot( "axis" );
|
||||
}
|
||||
|
||||
return isdefined( bot );
|
||||
}
|
||||
|
||||
function monitor_bot_population( maxFree )
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
if ( !maxFree )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Initial Fill
|
||||
players = GetPlayers( );
|
||||
while ( players.size < maxFree )
|
||||
{
|
||||
add_bot();
|
||||
{wait(.05);};
|
||||
players = GetPlayers( );
|
||||
}
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
wait 3;
|
||||
|
||||
// TODO: Get a player count that includes 'CON_CONNECTING' players
|
||||
players = GetPlayers( );
|
||||
|
||||
if ( players.size < maxFree )
|
||||
{
|
||||
add_bot();
|
||||
}
|
||||
else if ( players.size > maxFree )
|
||||
{
|
||||
remove_best_bot( players );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function remove_best_bot( players )
|
||||
{
|
||||
bots = filter_bots( players );
|
||||
|
||||
if ( !bots.size )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prefer non-combat bots
|
||||
bestBots = [];
|
||||
|
||||
foreach( bot in bots )
|
||||
{
|
||||
// Don't kick bots in the process of connecting
|
||||
if ( bot.sessionstate == "spectator" )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( bot.sessionstate == "dead" || !bot bot_combat::has_threat() )
|
||||
{
|
||||
bestBots[bestBots.size] = bot;
|
||||
}
|
||||
}
|
||||
|
||||
if ( bestBots.size )
|
||||
{
|
||||
remove_bot( bestBots[RandomInt( bestBots.size )] );
|
||||
}
|
||||
else
|
||||
{
|
||||
remove_bot( bots[RandomInt( bots.size )] );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Bot Loadouts
|
||||
//========================================
|
||||
|
||||
function choose_class()
|
||||
{
|
||||
if ( ( isdefined( level.disableClassSelection ) && level.disableClassSelection ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
currClass = self bot_loadout::get_current_class();
|
||||
|
||||
if ( !isdefined( currClass ) || RandomInt( 100 ) < (isdefined(level.botSettings.changeClassWeight)?level.botSettings.changeClassWeight:0) )
|
||||
{
|
||||
classIndex = RandomInt( self.loadoutClasses.size );
|
||||
className = self.loadoutClasses[classIndex].name;
|
||||
}
|
||||
|
||||
if ( !isdefined(className) || className === currClass )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
self notify( "menuresponse", "ChooseClass_InGame", className );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Killstreaks
|
||||
//========================================
|
||||
|
||||
function use_killstreak()
|
||||
{
|
||||
if ( !level.loadoutKillstreaksEnabled ||
|
||||
self emp::EnemyEMPActive() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
weapons = self GetWeaponsList();
|
||||
inventoryWeapon = self GetInventoryWeapon();
|
||||
|
||||
foreach( weapon in weapons )
|
||||
{
|
||||
killstreak = killstreaks::get_killstreak_for_weapon( weapon );
|
||||
|
||||
if ( !isdefined( killstreak ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( weapon != inventoryWeapon && !self GetWeaponAmmoClip( weapon ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( self killstreakrules::isKillstreakAllowed( killstreak, self.team ) )
|
||||
{
|
||||
useWeapon = weapon;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !isdefined( useWeapon ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
killstreak_ref = killstreaks::get_menu_name( killstreak );
|
||||
|
||||
switch( killstreak_ref )
|
||||
{
|
||||
case "killstreak_uav":
|
||||
case "killstreak_counteruav":
|
||||
case "killstreak_satellite":
|
||||
case "killstreak_helicopter_player_gunner":
|
||||
case "killstreak_raps":
|
||||
case "killstreak_sentinel":
|
||||
self SwitchToWeapon( useWeapon );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function has_radar()
|
||||
{
|
||||
if ( level.teambased )
|
||||
{
|
||||
return ( uav::HasUAV( self.team ) || satellite::HasSatellite( self.team ) );
|
||||
}
|
||||
|
||||
return ( uav::HasUAV( self.entnum ) || satellite::HasSatellite( self.entnum ) );
|
||||
}
|
||||
|
||||
function has_minimap()
|
||||
{
|
||||
if ( self IsEmpJammed() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ( isdefined( level.hardcoreMode ) && level.hardcoreMode ) )
|
||||
{
|
||||
return self has_radar();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function get_enemies( on_radar )
|
||||
{
|
||||
if ( !isdefined( on_radar ) )
|
||||
{
|
||||
on_radar = false;
|
||||
}
|
||||
|
||||
enemies = self GetEnemies();
|
||||
|
||||
/#
|
||||
for ( i = 0; i < enemies.size; i++ )
|
||||
{
|
||||
if ( isplayer( enemies[i] ) && enemies[i] IsInMoveMode( "ufo", "noclip" ) )
|
||||
{
|
||||
ArrayRemoveIndex( enemies, i );
|
||||
i--;
|
||||
}
|
||||
}
|
||||
#/
|
||||
|
||||
if ( on_radar && !self has_radar() )
|
||||
{
|
||||
for ( i = 0; i < enemies.size; i++ )
|
||||
{
|
||||
if ( !isdefined( enemies[i].lastFireTime ) )
|
||||
{
|
||||
ArrayRemoveIndex( enemies, i );
|
||||
i--;
|
||||
}
|
||||
else if ( GetTime() - enemies[i].lastFireTime > 2000 )
|
||||
{
|
||||
ArrayRemoveIndex( enemies, i );
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return enemies;
|
||||
}
|
||||
|
||||
function set_rank()
|
||||
{
|
||||
players = GetPlayers();
|
||||
|
||||
ranks = [];
|
||||
bot_ranks = [];
|
||||
human_ranks = [];
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
if ( players[i] == self )
|
||||
continue;
|
||||
|
||||
if ( isdefined( players[i].pers[ "rank" ] ) )
|
||||
{
|
||||
if ( players[i] util::is_bot() )
|
||||
{
|
||||
bot_ranks[ bot_ranks.size ] = players[i].pers[ "rank" ];
|
||||
}
|
||||
else
|
||||
{
|
||||
human_ranks[ human_ranks.size ] = players[i].pers[ "rank" ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !human_ranks.size )
|
||||
human_ranks[ human_ranks.size ] = 10;
|
||||
|
||||
human_avg = math::array_average( human_ranks );
|
||||
|
||||
while ( bot_ranks.size + human_ranks.size < 5 )
|
||||
{
|
||||
// add some random ranks for better random number distribution
|
||||
r = human_avg + RandomIntRange( -5, 5 );
|
||||
rank = math::clamp( r, 0, level.maxRank );
|
||||
human_ranks[ human_ranks.size ] = rank;
|
||||
}
|
||||
|
||||
ranks = ArrayCombine( human_ranks, bot_ranks, true, false );
|
||||
|
||||
avg = math::array_average( ranks );
|
||||
s = math::array_std_deviation( ranks, avg );
|
||||
|
||||
rank = Int( math::random_normal_distribution( avg, s, 0, level.maxRank ) );
|
||||
|
||||
while ( !isdefined( self.pers["codpoints"] ) )
|
||||
{
|
||||
wait 0.1;
|
||||
}
|
||||
|
||||
self.pers[ "rank" ] = rank;
|
||||
self.pers[ "rankxp" ] = rank::getRankInfoMinXP( rank );
|
||||
|
||||
self setRank( rank );
|
||||
self rank::syncXPStat();
|
||||
}
|
||||
|
||||
function init_bot_gametype()
|
||||
{
|
||||
switch( level.gameType )
|
||||
{
|
||||
case "ball":
|
||||
bot_ball::init();
|
||||
return true;
|
||||
case "conf":
|
||||
bot_conf::init();
|
||||
return true;
|
||||
case "ctf":
|
||||
bot_ctf::init();
|
||||
return true;
|
||||
case "dem":
|
||||
bot_dem::init();
|
||||
return true;
|
||||
case "dm":
|
||||
return true;
|
||||
case "dom":
|
||||
bot_dom::init();
|
||||
return true;
|
||||
case "escort":
|
||||
bot_escort::init();
|
||||
return true;
|
||||
case "infect":
|
||||
return true;
|
||||
case "gun":
|
||||
return true;
|
||||
case "koth":
|
||||
bot_koth::init();
|
||||
return true;
|
||||
case "sd":
|
||||
bot_sd::init();
|
||||
return true;
|
||||
case "clean":
|
||||
bot_clean::init();
|
||||
return true;
|
||||
case "tdm":
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function get_bot_settings()
|
||||
{
|
||||
switch ( GetDvarInt( "bot_difficulty", 1 ) )
|
||||
{
|
||||
case 0:
|
||||
bundleName = "bot_mp_easy";
|
||||
break;
|
||||
|
||||
case 1:
|
||||
bundleName = "bot_mp_normal";
|
||||
break;
|
||||
case 2:
|
||||
bundleName = "bot_mp_hard";
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
bundleName = "bot_mp_veteran";
|
||||
break;
|
||||
}
|
||||
|
||||
return struct::get_script_bundle( "botsettings", bundleName );
|
||||
}
|
||||
|
||||
function friend_goal_in_radius( goal_name, origin, radius )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
function friend_in_radius( goal_name, origin, radius )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function get_friends()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
function get_closest_enemy( origin, someFlag )
|
||||
{
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function bot_vehicle_weapon_ammo( weaponName )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function navmesh_points_visible( origin, point )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function dive_to_prone( exit_stance )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/#
|
||||
|
||||
// Devgui
|
||||
//========================================
|
||||
|
||||
function bot_devgui_cmd( cmd )
|
||||
{
|
||||
cmdTokens = strtok( cmd," ");
|
||||
|
||||
if ( cmdTokens.size == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
host = util::getHostPlayerForBots();
|
||||
team = get_host_team();
|
||||
|
||||
switch( cmdTokens[0] )
|
||||
{
|
||||
case "spawn_enemy":
|
||||
team = util::getotherteam(team);
|
||||
case "spawn_friendly":
|
||||
count = 1;
|
||||
if ( cmdTokens.size > 1 )
|
||||
{
|
||||
count = int( cmdTokens[1] );
|
||||
}
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
add_bot( team );
|
||||
}
|
||||
return true;
|
||||
case "remove_enemy":
|
||||
team = util::getotherteam(team);
|
||||
case "remove_friendly":
|
||||
remove_bots( undefined, team );
|
||||
return true;
|
||||
case "fixed_spawn_enemy":
|
||||
team = util::getotherteam(team);
|
||||
case "fixed_spawn_friendly":
|
||||
bot = add_bot_at_eye_trace( team );
|
||||
if ( isdefined( bot ) )
|
||||
{
|
||||
bot thread fixed_spawn_override();
|
||||
}
|
||||
return true;
|
||||
|
||||
case "player_weapon":
|
||||
players = GetPlayers();
|
||||
foreach( player in players )
|
||||
{
|
||||
if ( !player util::is_bot() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
weapon = host GetCurrentWeapon();
|
||||
|
||||
player weapons::detach_all_weapons();
|
||||
player TakeAllWeapons();
|
||||
player GiveWeapon( weapon );
|
||||
player SwitchToWeapon( weapon );
|
||||
player SetSpawnWeapon( weapon );
|
||||
|
||||
player teams::set_player_model( player.team, weapon );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function system_devgui_gadget_think()
|
||||
{
|
||||
SetDvar( "devgui_bot_gadget", "" );
|
||||
|
||||
for ( ;; )
|
||||
{
|
||||
wait( 1 );
|
||||
|
||||
gadget = GetDvarString( "devgui_bot_gadget" );
|
||||
|
||||
if ( gadget != "" )
|
||||
{
|
||||
bot_turn_on_gadget( GetWeapon(gadget) );
|
||||
SetDvar( "devgui_bot_gadget", "" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function bot_turn_on_gadget( gadget )
|
||||
{
|
||||
players = GetPlayers();
|
||||
|
||||
foreach( player in players )
|
||||
{
|
||||
if ( !player util::is_bot() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
host = util::getHostPlayer();
|
||||
weapon = host GetCurrentWeapon();
|
||||
|
||||
if ( !isdefined( weapon ) || weapon == level.weaponNone || weapon == level.weaponNull )
|
||||
{
|
||||
weapon = GetWeapon( "smg_standard" );
|
||||
}
|
||||
|
||||
player weapons::detach_all_weapons();
|
||||
player TakeAllWeapons();
|
||||
player GiveWeapon( weapon );
|
||||
player SwitchToWeapon( weapon );
|
||||
player SetSpawnWeapon( weapon );
|
||||
|
||||
player teams::set_player_model( player.team, weapon );
|
||||
|
||||
player GiveWeapon( gadget );
|
||||
slot = player GadgetGetSlot( gadget );
|
||||
player GadgetPowerSet( slot, 100.0 );
|
||||
player BotPressButtonForGadget( gadget );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function fixed_spawn_override()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
spawnOrigin = self.origin;
|
||||
spawnAngles = self.angles;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
|
||||
self SetOrigin( spawnOrigin );
|
||||
self SetPlayerAngles( spawnAngles );
|
||||
}
|
||||
}
|
||||
|
||||
#/
|
||||
@@ -0,0 +1,57 @@
|
||||
// matches the enum in bot.h
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 65 degrees
|
||||
// 85 degrees
|
||||
// 100 degrees
|
||||
// 160 degrees
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
#using scripts\shared\array_shared;
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\math_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
|
||||
#using scripts\mp\bots\_bot;
|
||||
#using scripts\mp\bots\_bot_combat;
|
||||
#using scripts\shared\bots\_bot;
|
||||
#using scripts\shared\bots\_bot_combat;
|
||||
#using scripts\shared\bots\bot_traversals;
|
||||
#using scripts\shared\bots\bot_buttons;
|
||||
|
||||
|
||||
#using scripts\mp\teams\_teams;
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace bot_ball;
|
||||
|
||||
function init()
|
||||
{
|
||||
level.botIdle = &bot_idle;
|
||||
level.botCombat = &bot_combat;
|
||||
level.botPreCombat = &bot_pre_combat;
|
||||
}
|
||||
|
||||
function release_control_on_landing()
|
||||
{
|
||||
self endon( "death" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
while ( self IsOnGround() )
|
||||
{
|
||||
{wait(.05);};
|
||||
}
|
||||
|
||||
while ( !self IsOnGround() )
|
||||
{
|
||||
{wait(.05);};
|
||||
}
|
||||
|
||||
self BotReleaseManualControl();
|
||||
}
|
||||
|
||||
function bot_pre_combat()
|
||||
{
|
||||
if ( isdefined( self.carryObject ) )
|
||||
{
|
||||
if ( self IsOnGround() && self BotGoalSet() )
|
||||
{
|
||||
goal = level.ball_goals[util::getotherteam( self.team )];
|
||||
|
||||
radius = 300;
|
||||
radiusSq = radius * radius;
|
||||
|
||||
if ( Distance2DSquared( self.origin, goal.trigger.origin ) <= radiusSq )
|
||||
{
|
||||
if ( self BotSightTrace( goal.trigger ) )
|
||||
{
|
||||
self BotTakeManualControl();
|
||||
self thread bot::jump_to( goal.trigger.origin );
|
||||
self thread release_control_on_landing();
|
||||
|
||||
// TODO: Try throwing the ball
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !self IsMeleeing() )
|
||||
{
|
||||
self bot::use_killstreak();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self bot_combat::mp_pre_combat();
|
||||
}
|
||||
|
||||
function bot_combat()
|
||||
{
|
||||
if ( isdefined( self.carryObject ) )
|
||||
{
|
||||
if ( self bot_combat::has_threat() )
|
||||
{
|
||||
self bot_combat::clear_threat();
|
||||
}
|
||||
|
||||
meleeThreat = bot_combat::get_greatest_threat( level.botSettings.meleeRange );
|
||||
|
||||
if ( isdefined( meleeThreat ) )
|
||||
{
|
||||
angles = self GetPlayerAngles();
|
||||
fwd = AnglesToForward( angles );
|
||||
|
||||
threatDir = meleeThreat.origin - self.origin ;
|
||||
threatDir = VectorNormalize( threatDir );
|
||||
|
||||
dot = VectorDot( fwd, threatDir );
|
||||
|
||||
if ( dot > level.botSettings.meleeDot )
|
||||
{
|
||||
self bot::tap_melee_button();
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self bot_combat::combat_think();
|
||||
}
|
||||
|
||||
function bot_idle()
|
||||
{
|
||||
if ( isdefined( self.carryObject ) )
|
||||
{
|
||||
if ( !self BotGoalSet() )
|
||||
{
|
||||
// The goal trigger is too far off the navmesh
|
||||
goal = level.ball_goals[util::getotherteam( self.team )];
|
||||
goalPoint = goal.origin - ( 0, 0, 125 );
|
||||
self bot::approach_point( goalPoint );
|
||||
self bot::sprint_to_goal();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
triggers = [];
|
||||
balls = array::randomize( level.balls );
|
||||
|
||||
foreach( ball in balls )
|
||||
{
|
||||
if ( !isdefined( ball.carrier ) && !ball.in_goal )
|
||||
{
|
||||
triggers[triggers.size] = ball.trigger;
|
||||
}
|
||||
else if ( isdefined( ball.carrier ) && ball.carrier.team != self.team )
|
||||
{
|
||||
// Don't go straight for the carrier since the objective doesn't update perfectly
|
||||
self bot::approach_point( ball.carrier.origin, 250, 1000, 128 );
|
||||
self bot::sprint_to_goal();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Go pick up the closest ball
|
||||
if ( triggers.size > 0 )
|
||||
{
|
||||
triggers = ArraySort( triggers, self.origin );
|
||||
|
||||
self BotSetGoal( triggers[0].origin );
|
||||
self bot::sprint_to_goal();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self bot::bot_idle();
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
#using scripts\shared\array_shared;
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\math_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
|
||||
#using scripts\mp\bots\_bot;
|
||||
#using scripts\mp\bots\_bot_combat;
|
||||
#using scripts\shared\bots\_bot;
|
||||
#using scripts\shared\bots\_bot_combat;
|
||||
#using scripts\shared\bots\bot_traversals;
|
||||
#using scripts\shared\bots\bot_buttons;
|
||||
|
||||
|
||||
#using scripts\mp\teams\_teams;
|
||||
#using scripts\mp\_util;
|
||||
|
||||
#namespace bot_clean;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function init()
|
||||
{
|
||||
level.botPostCombat = &bot_post_combat;
|
||||
level.botIdle = &bot_idle;
|
||||
|
||||
level.botUpdateThreatGoal = &update_threat_goal;
|
||||
}
|
||||
|
||||
function bot_post_combat()
|
||||
{
|
||||
// Forget about the current target or hub when entering combat
|
||||
//if ( self bot_combat::has_threat() )
|
||||
//{
|
||||
// self.targetTaco = undefined;
|
||||
// self.targetHub = undefined;
|
||||
//}
|
||||
|
||||
// Ditch the hub if it's inactive or out of tacos
|
||||
if ( isdefined( self.targetHub ) )
|
||||
{
|
||||
if ( self.carriedTacos == 0 || self.targetHub.interactTeam == "none" )
|
||||
{
|
||||
self.targetHub = undefined;
|
||||
self BotSetGoal( self.origin );
|
||||
}
|
||||
}
|
||||
|
||||
// Ditch the taco if it's inactive or recycled
|
||||
if ( isdefined( self.targetTaco ) )
|
||||
{
|
||||
if ( self.targetTaco.interactTeam == "none" || self.targetTaco.DropTime != self.targetTacoDropTime )
|
||||
{
|
||||
self.targetTaco = undefined;
|
||||
self BotSetGoal( self.origin );
|
||||
}
|
||||
}
|
||||
|
||||
// Check for nearby tacos
|
||||
if ( !self bot_combat::has_threat() )
|
||||
{
|
||||
look_for_taco( 1024 );
|
||||
}
|
||||
|
||||
self bot_combat::mp_post_combat();
|
||||
}
|
||||
|
||||
function bot_idle()
|
||||
{
|
||||
// Go to/stay in the deposit point
|
||||
if ( isdefined( self.targetHub ) )
|
||||
{
|
||||
self bot::path_to_point_in_trigger( self.targetHub.trigger );
|
||||
self bot::sprint_to_goal();
|
||||
return;
|
||||
}
|
||||
|
||||
// Go look for a deposit point
|
||||
if ( RandomInt( 10 ) < self.carriedTacos )
|
||||
{
|
||||
foreach( hub in level.cleanDepositHubs )
|
||||
{
|
||||
if ( hub.interactTeam == "any" )
|
||||
{
|
||||
self.targetHub = hub;
|
||||
self.targetTaco = undefined;
|
||||
self bot::path_to_point_in_trigger( self.targetHub.trigger );
|
||||
self bot::sprint_to_goal();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( look_for_taco( 1024 ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self bot::bot_idle();
|
||||
}
|
||||
|
||||
function look_for_taco( radius )
|
||||
{
|
||||
bestTaco = get_best_taco( radius );
|
||||
|
||||
if ( !isdefined( bestTaco ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
self.targetTaco = bestTaco;
|
||||
self.targetTacoDropTime = bestTaco.dropTime;
|
||||
|
||||
self bot::path_to_point_in_trigger( bestTaco.trigger );
|
||||
self bot::sprint_to_goal();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function get_best_taco( radius )
|
||||
{
|
||||
radiusSq = radius * radius;
|
||||
|
||||
// Look for the closest taco in the nearby radius, or the closest one on the map
|
||||
bestTaco = undefined;
|
||||
bestTacoDistSq = undefined;
|
||||
|
||||
foreach ( taco in level.tacos )
|
||||
{
|
||||
if ( taco.interactTeam == "none" || !IsPointOnNavMesh( taco.origin , self ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
tacoDistSq = Distance2DSquared( self.origin, taco.origin );
|
||||
|
||||
if ( taco.attacker != self && tacoDistSq > radiusSq )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !isdefined( bestTaco ) || tacoDistSq < bestTacoDistSq )
|
||||
{
|
||||
bestTaco = taco;
|
||||
bestTacoDistSq = tacoDistSq;
|
||||
}
|
||||
}
|
||||
|
||||
return bestTaco;
|
||||
}
|
||||
|
||||
function update_threat_goal()
|
||||
{
|
||||
if ( isdefined( self.targetHub ) )
|
||||
{
|
||||
if ( !self BotGoalSet() )
|
||||
{
|
||||
self bot::path_to_point_in_trigger( self.targetHub.trigger );
|
||||
self bot::sprint_to_goal();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
radiusSq = 256 * 256;
|
||||
|
||||
if ( isdefined( self.targetTaco ) )
|
||||
{
|
||||
tacoDistSq = Distance2DSquared( self.origin, self.targetTaco.origin );
|
||||
if ( tacoDistSq > radiusSq )
|
||||
{
|
||||
self.targetTaco = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isdefined( self.targetTaco ) || self look_for_taco( 1024 ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self bot_combat::update_threat_goal();
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
#using scripts\shared\array_shared;
|
||||
#using scripts\shared\gameobjects_shared;
|
||||
#using scripts\shared\math_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
#using scripts\shared\weapons_shared;
|
||||
#using scripts\shared\weapons\_weapon_utils;
|
||||
#using scripts\shared\weapons\_weapons;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\_util;
|
||||
#using scripts\mp\bots\_bot;
|
||||
#using scripts\shared\bots\_bot;
|
||||
#using scripts\shared\bots\_bot_combat;
|
||||
#using scripts\shared\bots\bot_traversals;
|
||||
#using scripts\shared\killstreaks_shared;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 128 * 128
|
||||
|
||||
#namespace bot_combat;
|
||||
|
||||
function bot_ignore_threat( entity )
|
||||
{
|
||||
if ( threat_requires_launcher( entity ) && !self bot::has_launcher() )
|
||||
{
|
||||
return true;
|
||||
/* TODO:
|
||||
eyePos = self GetEye();
|
||||
|
||||
pitchMax = GetDvarFloat( "player_view_pitch_up" );
|
||||
pitchMin = -GetDvarFloat( "player_view_pitch_down" );
|
||||
|
||||
// Entity is in FOV but outside pitch range
|
||||
threatAngles = VectorToAngles( entity.origin - eyePos );
|
||||
|
||||
// TODO: Is threatAngles[0] in 0 to 360 or -180 to 180?
|
||||
if ( threatAngles[0] > pitchMax || threatAngles[0] < pitchMin )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function mp_pre_combat()
|
||||
{
|
||||
self bot_combat::bot_pre_combat();
|
||||
|
||||
if ( self IsReloading() ||
|
||||
self IsSwitchingWeapons() ||
|
||||
self IsThrowingGrenade() ||
|
||||
self IsMeleeing() ||
|
||||
self IsRemoteControlling() ||
|
||||
self IsInVehicle() ||
|
||||
self IsWeaponViewOnlyLinked() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( self has_threat() )
|
||||
{
|
||||
self threat_switch_weapon();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( self switch_weapon() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( self reload_weapon() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self bot::use_killstreak();
|
||||
}
|
||||
|
||||
|
||||
function mp_post_combat()
|
||||
{
|
||||
// Dogtag handling
|
||||
if( !IsDefined( level.dogtags ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isdefined( self.bot.goalTag ) )
|
||||
{
|
||||
if ( !self.bot.goalTag gameobjects::can_interact_with( self ) )
|
||||
{
|
||||
// Cancel the tag
|
||||
self.bot.goalTag = undefined;
|
||||
|
||||
if ( !self bot_combat::has_threat() && self BotGoalSet() )
|
||||
{
|
||||
self BotSetGoal( self.origin );
|
||||
}
|
||||
}
|
||||
else if ( !self.bot.goalTagOnGround &&
|
||||
!self bot_combat::has_threat() &&
|
||||
self IsOnGround() &&
|
||||
Distance2DSquared( self.origin , self.bot.goalTag.origin ) < 16384 &&
|
||||
self BotSightTrace( self.bot.goalTag ) )
|
||||
{
|
||||
self thread bot::jump_to( self.bot.goalTag.origin );
|
||||
}
|
||||
}
|
||||
else if ( !self BotGoalSet() )
|
||||
{
|
||||
closestTag = self get_closest_tag();
|
||||
|
||||
if ( isdefined( closestTag ) )
|
||||
{
|
||||
// Trigger radius from _dogtags.gsc
|
||||
self set_goal_tag( closestTag );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function threat_requires_launcher( enemy )
|
||||
{
|
||||
if ( !isdefined( enemy ) || IsPlayer( enemy ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
killstreakType = undefined;
|
||||
|
||||
if ( isdefined( enemy.killstreakType ) )
|
||||
{
|
||||
killstreakType = enemy.killstreakType;
|
||||
}
|
||||
else if ( isdefined( enemy.parentStruct ) && isdefined( enemy.parentStruct.killstreakType ) )
|
||||
{
|
||||
killstreakType = enemy.parentStruct.killstreakType;
|
||||
}
|
||||
|
||||
if ( !isdefined( killstreakType ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch( killstreakType )
|
||||
{
|
||||
case "uav":
|
||||
case "counteruav":
|
||||
case "satellite":
|
||||
case "helicopter_gunner":
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function combat_throw_proximity( origin )
|
||||
{
|
||||
}
|
||||
|
||||
function combat_throw_smoke( origin )
|
||||
{
|
||||
}
|
||||
|
||||
function combat_throw_lethal( origin )
|
||||
{
|
||||
}
|
||||
|
||||
function combat_throw_tactical( origin )
|
||||
{
|
||||
}
|
||||
|
||||
function combat_toss_frag( origin )
|
||||
{
|
||||
}
|
||||
|
||||
function combat_toss_flash( origin )
|
||||
{
|
||||
}
|
||||
|
||||
function combat_tactical_insertion( origin )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function nearest_node( origin )
|
||||
{
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function dot_product( origin )
|
||||
{
|
||||
return bot::fwd_dot( origin );
|
||||
}
|
||||
|
||||
// Dogtags
|
||||
//========================================
|
||||
|
||||
function get_closest_tag()
|
||||
{
|
||||
closestTag = undefined;
|
||||
closestTagDistSq = undefined;
|
||||
|
||||
foreach( tag in level.dogtags )
|
||||
{
|
||||
if ( !tag gameobjects::can_interact_with( self ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
distSq = DistanceSquared( self.origin, tag.origin );
|
||||
|
||||
if ( !isdefined( closestTag ) || distSq < closestTagDistSq )
|
||||
{
|
||||
closestTag = tag;
|
||||
closestTagDistSq = distSq;
|
||||
}
|
||||
}
|
||||
|
||||
return closestTag;
|
||||
}
|
||||
|
||||
function set_goal_tag( tag )
|
||||
{
|
||||
self.bot.goalTag = tag;
|
||||
|
||||
traceStart = tag.origin;
|
||||
traceEnd = tag.origin + (0,0,-64);
|
||||
trace = BulletTrace( traceStart, traceEnd, false, undefined );
|
||||
|
||||
self.bot.goalTagOnGround = ( trace["fraction"] < 1 );
|
||||
|
||||
self bot::path_to_trigger( tag.trigger );
|
||||
self bot::sprint_to_goal();
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#using scripts\codescripts\struct;
|
||||
|
||||
#using scripts\shared\gameobjects_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\shared\bots\_bot;
|
||||
#using scripts\shared\bots\_bot_combat;
|
||||
#using scripts\shared\bots\bot_traversals;
|
||||
#using scripts\mp\bots\_bot;
|
||||
#using scripts\mp\bots\_bot_combat;
|
||||
|
||||
|
||||
|
||||
|
||||
#namespace bot_conf;
|
||||
|
||||
function init()
|
||||
{
|
||||
// Handled by the base tag seeking behavior now
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
#using scripts\shared\array_shared;
|
||||
#using scripts\shared\gameobjects_shared;
|
||||
#using scripts\shared\math_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\gametypes\ctf;
|
||||
|
||||
#using scripts\mp\_util;
|
||||
#using scripts\shared\bots\_bot;
|
||||
#using scripts\shared\bots\_bot_combat;
|
||||
#using scripts\mp\bots\_bot;
|
||||
#using scripts\mp\bots\_bot_combat;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#namespace bot_ctf;
|
||||
|
||||
function init()
|
||||
{
|
||||
level.onBotConnect = &on_bot_connect;
|
||||
level.botIdle = &bot_idle;
|
||||
}
|
||||
|
||||
function on_bot_connect()
|
||||
{
|
||||
foreach( flag in level.flags )
|
||||
{
|
||||
if ( flag gameobjects::get_owner_team() == self.team )
|
||||
{
|
||||
self.bot.flag = flag;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.bot.enemyFlag = flag;
|
||||
}
|
||||
}
|
||||
|
||||
self bot::on_bot_connect();
|
||||
}
|
||||
|
||||
function bot_idle()
|
||||
{
|
||||
carrier = self.bot.enemyFlag gameobjects::get_carrier();
|
||||
|
||||
// Carrying the enemy flag
|
||||
if ( isdefined( carrier ) && carrier == self )
|
||||
{
|
||||
// Wander around the home flag area until it comes back
|
||||
if ( self.bot.flag gameobjects::is_object_away_from_home() )
|
||||
{
|
||||
self bot::approach_point( self.bot.flag.flagBase.trigger.origin, 0, 1024 );
|
||||
}
|
||||
// Capture the enemy flag
|
||||
else
|
||||
{
|
||||
self bot::approach_goal_trigger( self.bot.flag.flagBase.trigger );
|
||||
}
|
||||
|
||||
self bot::sprint_to_goal();
|
||||
return;
|
||||
}
|
||||
// Defend home base
|
||||
else if ( Distance2DSquared( self.origin, self.bot.flag.flagBase.trigger.origin ) < ( 1024 * 1024 ) &&
|
||||
RandomInt( 100 ) < 80 )
|
||||
{
|
||||
self bot::approach_point( self.bot.flag.flagBase.trigger.origin, 0, 1024 );
|
||||
self bot::sprint_to_goal();
|
||||
return;
|
||||
}
|
||||
// Return the friendly flag
|
||||
else if ( self.bot.flag gameobjects::is_object_away_from_home() )
|
||||
{
|
||||
enemyCarrier = self.bot.flag gameobjects::get_carrier();
|
||||
|
||||
if ( isdefined( enemyCarrier ) )
|
||||
{
|
||||
// Don't go straight for the carrier since the objective doesn't update perfectly
|
||||
self bot::approach_point( enemyCarrier.origin, 250, 1000, 128 );
|
||||
self bot::sprint_to_goal();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
self BotSetGoal( self.bot.flag.trigger.origin );
|
||||
self bot::sprint_to_goal();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Take the enemy flag
|
||||
else if ( !isdefined( carrier ) )
|
||||
{
|
||||
self bot::approach_goal_trigger( self.bot.enemyFlag.trigger );
|
||||
self bot::sprint_to_goal();
|
||||
return;
|
||||
}
|
||||
|
||||
self bot::bot_idle();
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
#using scripts\shared\array_shared;
|
||||
#using scripts\shared\gameobjects_shared;
|
||||
#using scripts\shared\math_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
#using scripts\shared\bots\_bot;
|
||||
#using scripts\shared\bots\_bot_combat;
|
||||
#using scripts\shared\bots\bot_buttons;
|
||||
#using scripts\mp\bots\_bot;
|
||||
#using scripts\mp\bots\_bot_combat;
|
||||
|
||||
|
||||
|
||||
#namespace bot_dem;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function init()
|
||||
{
|
||||
level.botIdle = &bot_idle;
|
||||
level.botCombat = &combat_think;
|
||||
level.botThreatLost = &bot_threat_lost;
|
||||
}
|
||||
|
||||
function bot_idle()
|
||||
{
|
||||
approachRadiusSq = 750 * 750;
|
||||
|
||||
// Check for Plant / Defuse
|
||||
foreach( zone in level.bombZones )
|
||||
{
|
||||
if ( ( isdefined( zone.bombExploded ) && zone.bombExploded ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( self IsTouching( zone.trigger ) )
|
||||
{
|
||||
if ( self can_plant( zone ) || self can_defuse( zone ) )
|
||||
{
|
||||
self bot::press_use_button();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( DistanceSquared( self.origin, zone.trigger.origin ) < approachRadiusSq )
|
||||
{
|
||||
// Defuse / Plant nearby zone
|
||||
if ( self can_plant( zone ) || self can_defuse( zone ) )
|
||||
{
|
||||
self bot::path_to_trigger( zone.trigger );
|
||||
self bot::sprint_to_goal();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shuffle zones
|
||||
zones = array::randomize( level.bombZones );
|
||||
|
||||
// Check for zones to defuse
|
||||
foreach( zone in zones )
|
||||
{
|
||||
if ( ( isdefined( zone.bombExploded ) && zone.bombExploded ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( self can_defuse( zone ) && RandomInt( 100 ) < 70 )
|
||||
{
|
||||
self bot::approach_goal_trigger( zone.trigger, 750 );
|
||||
self bot::sprint_to_goal();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Go to a random zone to plant / guard
|
||||
foreach( zone in zones )
|
||||
{
|
||||
if ( ( isdefined( zone.bombExploded ) && zone.bombExploded ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Defend the nearby point
|
||||
if ( DistanceSquared( self.origin, zone.trigger.origin ) < approachRadiusSq &&
|
||||
RandomInt( 100 ) < 70 )
|
||||
{
|
||||
triggerRadius = self bot::get_trigger_radius( zone.trigger );
|
||||
self bot::approach_point( zone.trigger.origin, triggerRadius, 750 );
|
||||
self bot::sprint_to_goal();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
self bot::bot_idle();
|
||||
}
|
||||
|
||||
function can_plant( zone )
|
||||
{
|
||||
return !( isdefined( zone.bombPlanted ) && zone.bombPlanted ) && self.team != zone gameobjects::get_owner_team();
|
||||
}
|
||||
|
||||
function can_defuse( zone )
|
||||
{
|
||||
return ( isdefined( zone.bombPlanted ) && zone.bombPlanted ) && self.team == zone gameobjects::get_owner_team();
|
||||
}
|
||||
|
||||
|
||||
function combat_think()
|
||||
{
|
||||
if ( ( isdefined( self.isPlanting ) && self.isPlanting ) ||
|
||||
( isdefined( self.isDefusing ) && self.isDefusing ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self bot_combat::combat_think();
|
||||
}
|
||||
|
||||
function bot_threat_lost()
|
||||
{
|
||||
approachRadiusSq = 750 * 750;
|
||||
|
||||
// Don't chase enemies if near a plantable/defusable zone
|
||||
foreach( zone in level.bombZones )
|
||||
{
|
||||
if ( ( isdefined( zone.bombExploded ) && zone.bombExploded ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( DistanceSquared( self.origin, zone.trigger.origin ) < approachRadiusSq )
|
||||
{
|
||||
// Defuse / Plant nearby zone
|
||||
if ( self can_plant( zone ) || self can_defuse( zone ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self bot_combat::chase_threat();
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
#using scripts\shared\array_shared;
|
||||
#using scripts\shared\gameobjects_shared;
|
||||
#using scripts\shared\math_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
Line truncated
|
||||
|
||||
#using scripts\mp\gametypes\dom;
|
||||
|
||||
#using scripts\shared\bots\_bot;
|
||||
#using scripts\shared\bots\_bot_combat;
|
||||
#using scripts\mp\bots\_bot;
|
||||
#using scripts\mp\bots\_bot_combat;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#namespace bot_dom;
|
||||
|
||||
// size of radius trigger in BO2
|
||||
|
||||
|
||||
// Default Radius * 2.5
|
||||
|
||||
|
||||
function init()
|
||||
{
|
||||
level.botUpdate = &bot_update;
|
||||
level.botPreCombat = &bot_pre_combat;
|
||||
level.botUpdateThreatGoal = &bot_update_threat_goal;
|
||||
level.botIdle = &bot_idle;
|
||||
}
|
||||
|
||||
function bot_update()
|
||||
{
|
||||
self.bot.capturingFlag = self get_capturing_flag();
|
||||
|
||||
self.bot.goalFlag = undefined;
|
||||
|
||||
if ( !self BotGoalReached() )
|
||||
{
|
||||
foreach( flag in level.domFlags )
|
||||
{
|
||||
if ( self bot::goal_in_trigger( flag.trigger ) )
|
||||
{
|
||||
self.bot.goalFlag = flag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self bot::bot_update();
|
||||
}
|
||||
|
||||
function bot_pre_combat()
|
||||
{
|
||||
// Stop heading to goals that have been captured
|
||||
if ( !self bot_combat::has_threat() &&
|
||||
isdefined( self.bot.goalFlag ) &&
|
||||
self.bot.goalflag gameobjects::get_owner_team() == self.team )
|
||||
{
|
||||
self BotSetGoal( self.origin );
|
||||
}
|
||||
|
||||
self bot_combat::mp_pre_combat();
|
||||
}
|
||||
|
||||
|
||||
function bot_idle()
|
||||
{
|
||||
if ( isdefined( self.bot.capturingFlag ) )
|
||||
{
|
||||
self bot::path_to_point_in_trigger( self.bot.capturingFlag.trigger );
|
||||
return;
|
||||
}
|
||||
|
||||
bestFlag = get_best_flag();
|
||||
|
||||
if ( isdefined( bestFlag ) )
|
||||
{
|
||||
self bot::approach_goal_trigger( bestFlag.trigger );
|
||||
self bot::sprint_to_goal();
|
||||
return;
|
||||
}
|
||||
|
||||
self bot::bot_idle();
|
||||
}
|
||||
|
||||
// Combat
|
||||
//========================================
|
||||
|
||||
// Stay inside the goal when attacking
|
||||
function bot_update_threat_goal()
|
||||
{
|
||||
if ( isdefined( self.bot.capturingFlag ) )
|
||||
{
|
||||
if ( self BotGoalReached() )
|
||||
{
|
||||
self bot::path_to_point_in_trigger( self.bot.capturingFlag.trigger );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
self bot_combat::update_threat_goal();
|
||||
}
|
||||
|
||||
// Dom Flags
|
||||
//========================================
|
||||
|
||||
function get_capturing_flag()
|
||||
{
|
||||
foreach( flag in level.domFlags )
|
||||
{
|
||||
if ( self.team != flag gameobjects::get_owner_team() && self IsTouching( flag.trigger ) )
|
||||
{
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function get_best_flag()
|
||||
{
|
||||
bestFlag = undefined;
|
||||
bestFlagDistSq = undefined;
|
||||
|
||||
// Closest flag under attack by the enemy, or not owned by their team
|
||||
foreach( flag in level.domFlags )
|
||||
{
|
||||
ownerTeam = flag gameobjects::get_owner_team();
|
||||
contested = flag gameobjects::get_num_touching_except_team( ownerTeam );
|
||||
distSq = Distance2DSquared( self.origin, flag.origin );
|
||||
|
||||
if ( ownerTeam == self.team && !contested )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !isdefined( bestFlag ) ||
|
||||
distSq < bestFlagDistSq )
|
||||
{
|
||||
bestFlag = flag;
|
||||
bestFlagDistSq = distSq;
|
||||
}
|
||||
}
|
||||
|
||||
return bestFlag;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
#using scripts\shared\array_shared;
|
||||
#using scripts\shared\callbacks_shared;
|
||||
#using scripts\shared\math_shared;
|
||||
#using scripts\shared\system_shared;
|
||||
#using scripts\shared\util_shared;
|
||||
|
||||
Line truncated
|
||||
|
||||
|
||||
|
||||
#using scripts\mp\bots\_bot;
|
||||
#using scripts\shared\bots\_bot;
|
||||
#using scripts\shared\bots\_bot_combat;
|
||||
#using scripts\shared\bots\bot_traversals;
|
||||
#using scripts\shared\bots\bot_buttons;
|
||||
|
||||
|
||||
#using scripts\mp\teams\_teams;
|
||||
#using scripts\mp\_util;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#namespace bot_escort;
|
||||
|
||||
function init()
|
||||
{
|
||||
level.botIdle = &bot_idle;
|
||||
}
|
||||
|
||||
function bot_idle()
|
||||
{
|
||||
if ( self.team == game["attackers"] )
|
||||
{
|
||||
self attackers_idle();
|
||||
}
|
||||
else
|
||||
{
|
||||
self defenders_idle();
|
||||
}
|
||||
}
|
||||
|
||||
function attackers_idle()
|
||||
{
|
||||
if ( isdefined( level.moveObject ) && ( level.robot.active || level.rebootPlayers > 0 ) )
|
||||
{
|
||||
if ( !level.robot.moving || math::cointoss() )
|
||||
{
|
||||
self bot::path_to_point_in_trigger( level.moveObject.trigger );
|
||||
}
|
||||
else
|
||||
{
|
||||
self bot::approach_point( level.moveObject.trigger.origin, 160, 400 );
|
||||
}
|
||||
|
||||
self bot::sprint_to_goal();
|
||||
return;
|
||||
}
|
||||
|
||||
self bot::bot_idle();
|
||||
}
|
||||
|
||||
function defenders_idle()
|
||||
{
|
||||
if ( isdefined( level.moveObject ) && level.robot.active )
|
||||
{
|
||||
self bot::approach_point( level.moveObject.trigger.origin, 160, 400 );
|
||||
self bot::sprint_to_goal();
|
||||
return;
|
||||
}
|
||||
|
||||
self bot::bot_idle();
|
||||
}
|
||||
Loaded 100 of 921 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user