mirror of
https://github.com/JezuzLizard/Recompilable-gscs-for-BO2-zombies-and-multiplayer.git
synced 2025-06-28 03:27:51 -05:00
Update scripts to better decompiled scripts.
This commit is contained in:
149
MP/Core/maps/mp/_acousticsensor.gsc
Normal file
149
MP/Core/maps/mp/_acousticsensor.gsc
Normal file
@ -0,0 +1,149 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\gametypes\_weaponobjects;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\killstreaks\_emp;
|
||||
#include maps\mp\_challenges;
|
||||
#include maps\mp\_scoreevents;
|
||||
#include maps\mp\gametypes\_globallogic_player;
|
||||
#include maps\mp\gametypes\_damagefeedback;
|
||||
|
||||
init()
|
||||
{
|
||||
level._effect["acousticsensor_enemy_light"] = loadfx( "misc/fx_equip_light_red" );
|
||||
level._effect["acousticsensor_friendly_light"] = loadfx( "misc/fx_equip_light_green" );
|
||||
}
|
||||
|
||||
createacousticsensorwatcher()
|
||||
{
|
||||
watcher = self maps\mp\gametypes\_weaponobjects::createuseweaponobjectwatcher( "acoustic_sensor", "acoustic_sensor_mp", self.team );
|
||||
watcher.onspawn = ::onspawnacousticsensor;
|
||||
watcher.detonate = ::acousticsensordetonate;
|
||||
watcher.stun = maps\mp\gametypes\_weaponobjects::weaponstun;
|
||||
watcher.stuntime = 5;
|
||||
watcher.reconmodel = "t5_weapon_acoustic_sensor_world_detect";
|
||||
watcher.hackable = 1;
|
||||
watcher.ondamage = ::watchacousticsensordamage;
|
||||
}
|
||||
|
||||
onspawnacousticsensor( watcher, player )
|
||||
{
|
||||
self endon( "death" );
|
||||
self thread maps\mp\gametypes\_weaponobjects::onspawnuseweaponobject( watcher, player );
|
||||
player.acousticsensor = self;
|
||||
self setowner( player );
|
||||
self setteam( player.team );
|
||||
self.owner = player;
|
||||
self playloopsound( "fly_acoustic_sensor_lp" );
|
||||
|
||||
if ( !self maps\mp\_utility::ishacked() )
|
||||
player addweaponstat( "acoustic_sensor_mp", "used", 1 );
|
||||
|
||||
self thread watchshutdown( player, self.origin );
|
||||
}
|
||||
|
||||
acousticsensordetonate( attacker, weaponname )
|
||||
{
|
||||
from_emp = maps\mp\killstreaks\_emp::isempweapon( weaponname );
|
||||
|
||||
if ( !from_emp )
|
||||
playfx( level._equipment_explode_fx, self.origin );
|
||||
|
||||
if ( isdefined( attacker ) )
|
||||
{
|
||||
if ( self.owner isenemyplayer( attacker ) )
|
||||
{
|
||||
attacker maps\mp\_challenges::destroyedequipment( weaponname );
|
||||
maps\mp\_scoreevents::processscoreevent( "destroyed_motion_sensor", attacker, self.owner, weaponname );
|
||||
}
|
||||
}
|
||||
|
||||
playsoundatposition( "dst_equipment_destroy", self.origin );
|
||||
self destroyent();
|
||||
}
|
||||
|
||||
destroyent()
|
||||
{
|
||||
self delete();
|
||||
}
|
||||
|
||||
watchshutdown( player, origin )
|
||||
{
|
||||
self waittill_any( "death", "hacked" );
|
||||
|
||||
if ( isdefined( player ) )
|
||||
player.acousticsensor = undefined;
|
||||
}
|
||||
|
||||
watchacousticsensordamage( watcher )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "hacked" );
|
||||
self setcandamage( 1 );
|
||||
damagemax = 100;
|
||||
|
||||
if ( !self maps\mp\_utility::ishacked() )
|
||||
self.damagetaken = 0;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self.maxhealth = 100000;
|
||||
self.health = self.maxhealth;
|
||||
|
||||
self waittill( "damage", damage, attacker, direction, point, type, tagname, modelname, partname, weaponname, idflags );
|
||||
|
||||
if ( !isdefined( attacker ) || !isplayer( attacker ) )
|
||||
continue;
|
||||
|
||||
if ( level.teambased && attacker.team == self.owner.team && attacker != self.owner )
|
||||
continue;
|
||||
|
||||
if ( isdefined( weaponname ) )
|
||||
{
|
||||
switch ( weaponname )
|
||||
{
|
||||
case "flash_grenade_mp":
|
||||
case "concussion_grenade_mp":
|
||||
if ( watcher.stuntime > 0 )
|
||||
self thread maps\mp\gametypes\_weaponobjects::stunstart( watcher, watcher.stuntime );
|
||||
|
||||
if ( level.teambased && self.owner.team != attacker.team )
|
||||
{
|
||||
if ( maps\mp\gametypes\_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
attacker maps\mp\gametypes\_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
else if ( !level.teambased && self.owner != attacker )
|
||||
{
|
||||
if ( maps\mp\gametypes\_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
attacker maps\mp\gametypes\_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
|
||||
continue;
|
||||
case "emp_grenade_mp":
|
||||
damage = damagemax;
|
||||
default:
|
||||
if ( maps\mp\gametypes\_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
attacker maps\mp\gametypes\_damagefeedback::updatedamagefeedback();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
weaponname = "";
|
||||
|
||||
if ( isplayer( attacker ) && level.teambased && isdefined( attacker.team ) && self.owner.team == attacker.team && attacker != self.owner )
|
||||
continue;
|
||||
|
||||
if ( type == "MOD_MELEE" )
|
||||
self.damagetaken = damagemax;
|
||||
else
|
||||
self.damagetaken += damage;
|
||||
|
||||
if ( self.damagetaken >= damagemax )
|
||||
{
|
||||
watcher thread maps\mp\gametypes\_weaponobjects::waitanddetonate( self, 0.0, attacker, weaponname );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
3
MP/Core/maps/mp/_ambientpackage.gsc
Normal file
3
MP/Core/maps/mp/_ambientpackage.gsc
Normal file
@ -0,0 +1,3 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
|
473
MP/Core/maps/mp/_art.gsc
Normal file
473
MP/Core/maps/mp/_art.gsc
Normal file
@ -0,0 +1,473 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
|
||||
main()
|
||||
{
|
||||
/#
|
||||
if ( getdvar( "scr_art_tweak" ) == "" || getdvar( "scr_art_tweak" ) == "0" )
|
||||
setdvar( "scr_art_tweak", 0 );
|
||||
|
||||
if ( getdvar( "scr_dof_enable" ) == "" )
|
||||
setdvar( "scr_dof_enable", "1" );
|
||||
|
||||
if ( getdvar( "scr_cinematic_autofocus" ) == "" )
|
||||
setdvar( "scr_cinematic_autofocus", "1" );
|
||||
|
||||
if ( getdvar( "scr_art_visionfile" ) == "" && isdefined( level.script ) )
|
||||
setdvar( "scr_art_visionfile", level.script );
|
||||
|
||||
if ( getdvar( "debug_reflection" ) == "" )
|
||||
setdvar( "debug_reflection", "0" );
|
||||
|
||||
if ( getdvar( "debug_reflection_matte" ) == "" )
|
||||
setdvar( "debug_reflection_matte", "0" );
|
||||
|
||||
if ( getdvar( "debug_color_pallete" ) == "" )
|
||||
setdvar( "debug_color_pallete", "0" );
|
||||
|
||||
precachemodel( "test_sphere_lambert" );
|
||||
precachemodel( "test_macbeth_chart" );
|
||||
precachemodel( "test_macbeth_chart_unlit" );
|
||||
precachemodel( "test_sphere_silver" );
|
||||
level thread debug_reflection();
|
||||
level thread debug_reflection_matte();
|
||||
level thread debug_color_pallete();
|
||||
#/
|
||||
if ( !isdefined( level.dofdefault ) )
|
||||
{
|
||||
level.dofdefault["nearStart"] = 0;
|
||||
level.dofdefault["nearEnd"] = 1;
|
||||
level.dofdefault["farStart"] = 8000;
|
||||
level.dofdefault["farEnd"] = 10000;
|
||||
level.dofdefault["nearBlur"] = 6;
|
||||
level.dofdefault["farBlur"] = 0;
|
||||
}
|
||||
|
||||
level.curdof = ( level.dofdefault["farStart"] - level.dofdefault["nearEnd"] ) / 2;
|
||||
/#
|
||||
thread tweakart();
|
||||
#/
|
||||
if ( !isdefined( level.script ) )
|
||||
level.script = tolower( getdvar( "mapname" ) );
|
||||
}
|
||||
|
||||
artfxprintln( file, string )
|
||||
{
|
||||
/#
|
||||
if ( file == -1 )
|
||||
return;
|
||||
|
||||
fprintln( file, string );
|
||||
#/
|
||||
}
|
||||
|
||||
strtok_loc( string, par1 )
|
||||
{
|
||||
stringlist = [];
|
||||
indexstring = "";
|
||||
|
||||
for ( i = 0; i < string.size; i++ )
|
||||
{
|
||||
if ( string[i] == " " )
|
||||
{
|
||||
stringlist[stringlist.size] = indexstring;
|
||||
indexstring = "";
|
||||
continue;
|
||||
}
|
||||
|
||||
indexstring += string[i];
|
||||
}
|
||||
|
||||
if ( indexstring.size )
|
||||
stringlist[stringlist.size] = indexstring;
|
||||
|
||||
return stringlist;
|
||||
}
|
||||
|
||||
setfogsliders()
|
||||
{
|
||||
fogall = strtok_loc( getdvar( "g_fogColorReadOnly" ), " " );
|
||||
red = fogall[0];
|
||||
green = fogall[1];
|
||||
blue = fogall[2];
|
||||
halfplane = getdvar( "g_fogHalfDistReadOnly" );
|
||||
nearplane = getdvar( "g_fogStartDistReadOnly" );
|
||||
|
||||
if ( !isdefined( red ) || !isdefined( green ) || !isdefined( blue ) || !isdefined( halfplane ) )
|
||||
{
|
||||
red = 1;
|
||||
green = 1;
|
||||
blue = 1;
|
||||
halfplane = 10000001;
|
||||
nearplane = 10000000;
|
||||
}
|
||||
|
||||
setdvar( "scr_fog_exp_halfplane", halfplane );
|
||||
setdvar( "scr_fog_nearplane", nearplane );
|
||||
setdvar( "scr_fog_color", red + " " + green + " " + blue );
|
||||
}
|
||||
|
||||
tweakart()
|
||||
{
|
||||
/#
|
||||
if ( !isdefined( level.tweakfile ) )
|
||||
level.tweakfile = 0;
|
||||
|
||||
if ( getdvar( "scr_fog_baseheight" ) == "" )
|
||||
{
|
||||
setdvar( "scr_fog_exp_halfplane", "500" );
|
||||
setdvar( "scr_fog_exp_halfheight", "500" );
|
||||
setdvar( "scr_fog_nearplane", "0" );
|
||||
setdvar( "scr_fog_baseheight", "0" );
|
||||
}
|
||||
|
||||
setdvar( "scr_fog_fraction", "1.0" );
|
||||
setdvar( "scr_art_dump", "0" );
|
||||
setdvar( "scr_art_sun_fog_dir_set", "0" );
|
||||
setdvar( "scr_dof_nearStart", level.dofdefault["nearStart"] );
|
||||
setdvar( "scr_dof_nearEnd", level.dofdefault["nearEnd"] );
|
||||
setdvar( "scr_dof_farStart", level.dofdefault["farStart"] );
|
||||
setdvar( "scr_dof_farEnd", level.dofdefault["farEnd"] );
|
||||
setdvar( "scr_dof_nearBlur", level.dofdefault["nearBlur"] );
|
||||
setdvar( "scr_dof_farBlur", level.dofdefault["farBlur"] );
|
||||
file = undefined;
|
||||
filename = undefined;
|
||||
tweak_toggle = 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
while ( getdvarint( "scr_art_tweak" ) == 0 )
|
||||
{
|
||||
tweak_toggle = 1;
|
||||
wait 0.05;
|
||||
}
|
||||
|
||||
if ( tweak_toggle )
|
||||
{
|
||||
tweak_toggle = 0;
|
||||
fogsettings = getfogsettings();
|
||||
setdvar( "scr_fog_nearplane", fogsettings[0] );
|
||||
setdvar( "scr_fog_exp_halfplane", fogsettings[1] );
|
||||
setdvar( "scr_fog_exp_halfheight", fogsettings[3] );
|
||||
setdvar( "scr_fog_baseheight", fogsettings[2] );
|
||||
setdvar( "scr_fog_color", fogsettings[4] + " " + fogsettings[5] + " " + fogsettings[6] );
|
||||
setdvar( "scr_fog_color_scale", fogsettings[7] );
|
||||
setdvar( "scr_sun_fog_color", fogsettings[8] + " " + fogsettings[9] + " " + fogsettings[10] );
|
||||
level.fogsundir = [];
|
||||
level.fogsundir[0] = fogsettings[11];
|
||||
level.fogsundir[1] = fogsettings[12];
|
||||
level.fogsundir[2] = fogsettings[13];
|
||||
setdvar( "scr_sun_fog_start_angle", fogsettings[14] );
|
||||
setdvar( "scr_sun_fog_end_angle", fogsettings[15] );
|
||||
setdvar( "scr_fog_max_opacity", fogsettings[16] );
|
||||
}
|
||||
|
||||
level.fogexphalfplane = getdvarfloat( "scr_fog_exp_halfplane" );
|
||||
level.fogexphalfheight = getdvarfloat( "scr_fog_exp_halfheight" );
|
||||
level.fognearplane = getdvarfloat( "scr_fog_nearplane" );
|
||||
level.fogbaseheight = getdvarfloat( "scr_fog_baseheight" );
|
||||
level.fogcolorred = getdvarcolorred( "scr_fog_color" );
|
||||
level.fogcolorgreen = getdvarcolorgreen( "scr_fog_color" );
|
||||
level.fogcolorblue = getdvarcolorblue( "scr_fog_color" );
|
||||
level.fogcolorscale = getdvarfloat( "scr_fog_color_scale" );
|
||||
level.sunfogcolorred = getdvarcolorred( "scr_sun_fog_color" );
|
||||
level.sunfogcolorgreen = getdvarcolorgreen( "scr_sun_fog_color" );
|
||||
level.sunfogcolorblue = getdvarcolorblue( "scr_sun_fog_color" );
|
||||
level.sunstartangle = getdvarfloat( "scr_sun_fog_start_angle" );
|
||||
level.sunendangle = getdvarfloat( "scr_sun_fog_end_angle" );
|
||||
level.fogmaxopacity = getdvarfloat( "scr_fog_max_opacity" );
|
||||
|
||||
if ( getdvarint( "scr_art_sun_fog_dir_set" ) )
|
||||
{
|
||||
setdvar( "scr_art_sun_fog_dir_set", "0" );
|
||||
println( "Setting sun fog direction to facing of player" );
|
||||
players = get_players();
|
||||
dir = vectornormalize( anglestoforward( players[0] getplayerangles() ) );
|
||||
level.fogsundir = [];
|
||||
level.fogsundir[0] = dir[0];
|
||||
level.fogsundir[1] = dir[1];
|
||||
level.fogsundir[2] = dir[2];
|
||||
}
|
||||
|
||||
fovslidercheck();
|
||||
dumpsettings();
|
||||
|
||||
if ( !getdvarint( _hash_DBBD8F3B ) )
|
||||
{
|
||||
if ( !isdefined( level.fogsundir ) )
|
||||
{
|
||||
level.fogsundir = [];
|
||||
level.fogsundir[0] = 1;
|
||||
level.fogsundir[1] = 0;
|
||||
level.fogsundir[2] = 0;
|
||||
}
|
||||
|
||||
setvolfog( level.fognearplane, level.fogexphalfplane, level.fogexphalfheight, level.fogbaseheight, level.fogcolorred, level.fogcolorgreen, level.fogcolorblue, level.fogcolorscale, level.sunfogcolorred, level.sunfogcolorgreen, level.sunfogcolorblue, level.fogsundir[0], level.fogsundir[1], level.fogsundir[2], level.sunstartangle, level.sunendangle, 0, level.fogmaxopacity );
|
||||
}
|
||||
else
|
||||
setexpfog( 100000000, 100000001, 0, 0, 0, 0 );
|
||||
|
||||
wait 0.1;
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
fovslidercheck()
|
||||
{
|
||||
if ( level.dofdefault["nearStart"] >= level.dofdefault["nearEnd"] )
|
||||
{
|
||||
level.dofdefault["nearStart"] = level.dofdefault["nearEnd"] - 1;
|
||||
setdvar( "scr_dof_nearStart", level.dofdefault["nearStart"] );
|
||||
}
|
||||
|
||||
if ( level.dofdefault["nearEnd"] <= level.dofdefault["nearStart"] )
|
||||
{
|
||||
level.dofdefault["nearEnd"] = level.dofdefault["nearStart"] + 1;
|
||||
setdvar( "scr_dof_nearEnd", level.dofdefault["nearEnd"] );
|
||||
}
|
||||
|
||||
if ( level.dofdefault["farStart"] >= level.dofdefault["farEnd"] )
|
||||
{
|
||||
level.dofdefault["farStart"] = level.dofdefault["farEnd"] - 1;
|
||||
setdvar( "scr_dof_farStart", level.dofdefault["farStart"] );
|
||||
}
|
||||
|
||||
if ( level.dofdefault["farEnd"] <= level.dofdefault["farStart"] )
|
||||
{
|
||||
level.dofdefault["farEnd"] = level.dofdefault["farStart"] + 1;
|
||||
setdvar( "scr_dof_farEnd", level.dofdefault["farEnd"] );
|
||||
}
|
||||
|
||||
if ( level.dofdefault["farBlur"] >= level.dofdefault["nearBlur"] )
|
||||
{
|
||||
level.dofdefault["farBlur"] = level.dofdefault["nearBlur"] - 0.1;
|
||||
setdvar( "scr_dof_farBlur", level.dofdefault["farBlur"] );
|
||||
}
|
||||
|
||||
if ( level.dofdefault["farStart"] <= level.dofdefault["nearEnd"] )
|
||||
{
|
||||
level.dofdefault["farStart"] = level.dofdefault["nearEnd"] + 1;
|
||||
setdvar( "scr_dof_farStart", level.dofdefault["farStart"] );
|
||||
}
|
||||
}
|
||||
|
||||
dumpsettings()
|
||||
{
|
||||
/#
|
||||
if ( getdvar( "scr_art_dump" ) != "0" )
|
||||
{
|
||||
println( "\\tstart_dist = " + level.fognearplane + ";" );
|
||||
println( "\\thalf_dist = " + level.fogexphalfplane + ";" );
|
||||
println( "\\thalf_height = " + level.fogexphalfheight + ";" );
|
||||
println( "\\tbase_height = " + level.fogbaseheight + ";" );
|
||||
println( "\\tfog_r = " + level.fogcolorred + ";" );
|
||||
println( "\\tfog_g = " + level.fogcolorgreen + ";" );
|
||||
println( "\\tfog_b = " + level.fogcolorblue + ";" );
|
||||
println( "\\tfog_scale = " + level.fogcolorscale + ";" );
|
||||
println( "\\tsun_col_r = " + level.sunfogcolorred + ";" );
|
||||
println( "\\tsun_col_g = " + level.sunfogcolorgreen + ";" );
|
||||
println( "\\tsun_col_b = " + level.sunfogcolorblue + ";" );
|
||||
println( "\\tsun_dir_x = " + level.fogsundir[0] + ";" );
|
||||
println( "\\tsun_dir_y = " + level.fogsundir[1] + ";" );
|
||||
println( "\\tsun_dir_z = " + level.fogsundir[2] + ";" );
|
||||
println( "\\tsun_start_ang = " + level.sunstartangle + ";" );
|
||||
println( "\\tsun_stop_ang = " + level.sunendangle + ";" );
|
||||
println( "\\ttime = 0;" );
|
||||
println( "\\tmax_fog_opacity = " + level.fogmaxopacity + ";" );
|
||||
println( "" );
|
||||
println( "\\tsetVolFog(start_dist, half_dist, half_height, base_height, fog_r, fog_g, fog_b, fog_scale," );
|
||||
println( "\\t\\tsun_col_r, sun_col_g, sun_col_b, sun_dir_x, sun_dir_y, sun_dir_z, sun_start_ang, " );
|
||||
println( "\\t\\tsun_stop_ang, time, max_fog_opacity);" );
|
||||
setdvar( "scr_art_dump", "0" );
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
debug_reflection()
|
||||
{
|
||||
/#
|
||||
level.debug_reflection = 0;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
wait 0.1;
|
||||
|
||||
if ( getdvar( "debug_reflection" ) == "2" && level.debug_reflection != 2 || getdvar( "debug_reflection" ) == "3" && level.debug_reflection != 3 )
|
||||
{
|
||||
remove_reflection_objects();
|
||||
|
||||
if ( getdvar( "debug_reflection" ) == "2" )
|
||||
{
|
||||
create_reflection_objects();
|
||||
level.debug_reflection = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
create_reflection_objects();
|
||||
create_reflection_object();
|
||||
level.debug_reflection = 3;
|
||||
}
|
||||
}
|
||||
else if ( getdvar( "debug_reflection" ) == "1" && level.debug_reflection != 1 )
|
||||
{
|
||||
setdvar( "debug_reflection_matte", "0" );
|
||||
setdvar( "debug_color_pallete", "0" );
|
||||
remove_reflection_objects();
|
||||
create_reflection_object();
|
||||
level.debug_reflection = 1;
|
||||
}
|
||||
else if ( getdvar( "debug_reflection" ) == "0" && level.debug_reflection != 0 )
|
||||
{
|
||||
remove_reflection_objects();
|
||||
level.debug_reflection = 0;
|
||||
}
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
remove_reflection_objects()
|
||||
{
|
||||
/#
|
||||
if ( ( level.debug_reflection == 2 || level.debug_reflection == 3 ) && isdefined( level.debug_reflection_objects ) )
|
||||
{
|
||||
for ( i = 0; i < level.debug_reflection_objects.size; i++ )
|
||||
level.debug_reflection_objects[i] delete();
|
||||
|
||||
level.debug_reflection_objects = undefined;
|
||||
}
|
||||
|
||||
if ( level.debug_reflection == 1 || level.debug_reflection == 3 || level.debug_reflection_matte == 1 || level.debug_color_pallete == 1 || level.debug_color_pallete == 2 )
|
||||
{
|
||||
if ( isdefined( level.debug_reflectionobject ) )
|
||||
level.debug_reflectionobject delete();
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
create_reflection_objects()
|
||||
{
|
||||
/#
|
||||
reflection_locs = getreflectionlocs();
|
||||
|
||||
for ( i = 0; i < reflection_locs.size; i++ )
|
||||
{
|
||||
level.debug_reflection_objects[i] = spawn( "script_model", reflection_locs[i] );
|
||||
level.debug_reflection_objects[i] setmodel( "test_sphere_silver" );
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
create_reflection_object( model = "test_sphere_silver" )
|
||||
{
|
||||
/#
|
||||
if ( isdefined( level.debug_reflectionobject ) )
|
||||
level.debug_reflectionobject delete();
|
||||
|
||||
players = get_players();
|
||||
player = players[0];
|
||||
level.debug_reflectionobject = spawn( "script_model", player geteye() + vectorscale( anglestoforward( player.angles ), 100 ) );
|
||||
level.debug_reflectionobject setmodel( model );
|
||||
level.debug_reflectionobject.origin = player geteye() + vectorscale( anglestoforward( player getplayerangles() ), 100 );
|
||||
level.debug_reflectionobject linkto( player );
|
||||
thread debug_reflection_buttons();
|
||||
#/
|
||||
}
|
||||
|
||||
debug_reflection_buttons()
|
||||
{
|
||||
/#
|
||||
level notify( "new_reflection_button_running" );
|
||||
level endon( "new_reflection_button_running" );
|
||||
level.debug_reflectionobject endon( "death" );
|
||||
offset = 100;
|
||||
lastoffset = offset;
|
||||
|
||||
while ( getdvar( "debug_reflection" ) == "1" || getdvar( "debug_reflection" ) == "3" || getdvar( "debug_reflection_matte" ) == "1" || getdvar( "debug_color_pallete" ) == "1" || getdvar( "debug_color_pallete" ) == "2" )
|
||||
{
|
||||
players = get_players();
|
||||
|
||||
if ( players[0] buttonpressed( "BUTTON_X" ) )
|
||||
offset += 50;
|
||||
|
||||
if ( players[0] buttonpressed( "BUTTON_Y" ) )
|
||||
offset -= 50;
|
||||
|
||||
if ( offset > 1000 )
|
||||
offset = 1000;
|
||||
|
||||
if ( offset < 64 )
|
||||
offset = 64;
|
||||
|
||||
level.debug_reflectionobject unlink();
|
||||
level.debug_reflectionobject.origin = players[0] geteye() + vectorscale( anglestoforward( players[0] getplayerangles() ), offset );
|
||||
temp_angles = vectortoangles( players[0].origin - level.debug_reflectionobject.origin );
|
||||
level.debug_reflectionobject.angles = ( 0, temp_angles[1], 0 );
|
||||
lastoffset = offset;
|
||||
line( level.debug_reflectionobject.origin, getreflectionorigin( level.debug_reflectionobject.origin ), ( 1, 0, 0 ), 1, 1 );
|
||||
wait 0.05;
|
||||
|
||||
if ( isdefined( level.debug_reflectionobject ) )
|
||||
level.debug_reflectionobject linkto( players[0] );
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
debug_reflection_matte()
|
||||
{
|
||||
/#
|
||||
level.debug_reflection_matte = 0;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
wait 0.1;
|
||||
|
||||
if ( getdvar( "debug_reflection_matte" ) == "1" && level.debug_reflection_matte != 1 )
|
||||
{
|
||||
setdvar( "debug_reflection", "0" );
|
||||
setdvar( "debug_color_pallete", "0" );
|
||||
remove_reflection_objects();
|
||||
create_reflection_object( "test_sphere_lambert" );
|
||||
level.debug_reflection_matte = 1;
|
||||
}
|
||||
else if ( getdvar( "debug_reflection_matte" ) == "0" && level.debug_reflection_matte != 0 )
|
||||
{
|
||||
remove_reflection_objects();
|
||||
level.debug_reflection_matte = 0;
|
||||
}
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
debug_color_pallete()
|
||||
{
|
||||
/#
|
||||
level.debug_color_pallete = 0;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
wait 0.1;
|
||||
|
||||
if ( getdvar( "debug_color_pallete" ) == "1" && level.debug_color_pallete != 1 )
|
||||
{
|
||||
setdvar( "debug_reflection", "0" );
|
||||
setdvar( "debug_reflection_matte", "0" );
|
||||
remove_reflection_objects();
|
||||
create_reflection_object( "test_macbeth_chart" );
|
||||
level.debug_color_pallete = 1;
|
||||
}
|
||||
else if ( getdvar( "debug_color_pallete" ) == "2" && level.debug_color_pallete != 2 )
|
||||
{
|
||||
remove_reflection_objects();
|
||||
create_reflection_object( "test_macbeth_chart_unlit" );
|
||||
level.debug_color_pallete = 2;
|
||||
}
|
||||
else if ( getdvar( "debug_color_pallete" ) == "0" && level.debug_color_pallete != 0 )
|
||||
{
|
||||
remove_reflection_objects();
|
||||
level.debug_color_pallete = 0;
|
||||
}
|
||||
}
|
||||
#/
|
||||
}
|
139
MP/Core/maps/mp/_audio.gsc
Normal file
139
MP/Core/maps/mp/_audio.gsc
Normal file
@ -0,0 +1,139 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
|
||||
init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
wait_until_first_player()
|
||||
{
|
||||
players = get_players();
|
||||
|
||||
if ( !isdefined( players[0] ) )
|
||||
level waittill( "first_player_ready" );
|
||||
|
||||
players = get_players();
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
players[i] thread monitor_player_sprint();
|
||||
}
|
||||
|
||||
stand_think( trig )
|
||||
{
|
||||
killtext = "kill_stand_think" + trig getentitynumber();
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self endon( killtext );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
if ( self.player_is_moving )
|
||||
trig playsound( trig.script_label );
|
||||
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
|
||||
monitor_player_sprint()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self thread monitor_player_movement();
|
||||
|
||||
for ( self._is_sprinting = 0; 1; self._is_sprinting = 0 )
|
||||
{
|
||||
self waittill( "sprint_begin" );
|
||||
|
||||
self._is_sprinting = 1;
|
||||
|
||||
self waittill( "sprint_end" );
|
||||
}
|
||||
}
|
||||
|
||||
monitor_player_movement()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
org_1 = self.origin;
|
||||
wait 1.0;
|
||||
org_2 = self.origin;
|
||||
distancemoved = distancesquared( org_1, org_2 );
|
||||
|
||||
if ( distancemoved > 4096 )
|
||||
self.player_is_moving = 1;
|
||||
else
|
||||
self.player_is_moving = 0;
|
||||
}
|
||||
}
|
||||
|
||||
thread_enter_exit_sound( trig )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
trig.touchingplayers[self getentitynumber()] = 1;
|
||||
|
||||
if ( isdefined( trig.script_sound ) && trig.script_activated && self._is_sprinting )
|
||||
self playsound( trig.script_sound );
|
||||
|
||||
self thread stand_think( trig );
|
||||
|
||||
while ( self istouching( trig ) )
|
||||
wait 0.1;
|
||||
|
||||
self notify( "kill_stand_think" + trig getentitynumber() );
|
||||
self playsound( trig.script_noteworthy );
|
||||
trig.touchingplayers[self getentitynumber()] = 0;
|
||||
}
|
||||
|
||||
thread_step_trigger()
|
||||
{
|
||||
if ( !isdefined( self.script_activated ) )
|
||||
self.script_activated = 1;
|
||||
|
||||
if ( !isdefined( self.touchingplayers ) )
|
||||
{
|
||||
self.touchingplayers = [];
|
||||
|
||||
for ( i = 0; i < 4; i++ )
|
||||
self.touchingplayers[i] = 0;
|
||||
}
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self waittill( "trigger", who );
|
||||
|
||||
if ( self.touchingplayers[who getentitynumber()] == 0 )
|
||||
who thread thread_enter_exit_sound( self );
|
||||
}
|
||||
}
|
||||
|
||||
disable_bump_trigger( triggername )
|
||||
{
|
||||
triggers = getentarray( "audio_bump_trigger", "targetname" );
|
||||
|
||||
if ( isdefined( triggers ) )
|
||||
{
|
||||
for ( i = 0; i < triggers.size; i++ )
|
||||
{
|
||||
if ( isdefined( triggers[i].script_label ) && triggers[i].script_label == triggername )
|
||||
triggers[i].script_activated = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get_player_index_number( player )
|
||||
{
|
||||
players = get_players();
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
if ( players[i] == player )
|
||||
return i;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
262
MP/Core/maps/mp/_ballistic_knife.gsc
Normal file
262
MP/Core/maps/mp/_ballistic_knife.gsc
Normal file
@ -0,0 +1,262 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_challenges;
|
||||
|
||||
init()
|
||||
{
|
||||
precachemodel( "t6_wpn_ballistic_knife_projectile" );
|
||||
precachemodel( "t6_wpn_ballistic_knife_blade_retrieve" );
|
||||
}
|
||||
|
||||
onspawn( watcher, player )
|
||||
{
|
||||
player endon( "death" );
|
||||
player endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
self waittill( "stationary", endpos, normal, angles, attacker, prey, bone );
|
||||
|
||||
isfriendly = 0;
|
||||
|
||||
if ( isdefined( endpos ) )
|
||||
{
|
||||
retrievable_model = spawn( "script_model", endpos );
|
||||
retrievable_model setmodel( "t6_wpn_ballistic_knife_projectile" );
|
||||
retrievable_model setteam( player.team );
|
||||
retrievable_model setowner( player );
|
||||
retrievable_model.owner = player;
|
||||
retrievable_model.angles = angles;
|
||||
retrievable_model.name = watcher.weapon;
|
||||
retrievable_model.targetname = "sticky_weapon";
|
||||
|
||||
if ( isdefined( prey ) )
|
||||
{
|
||||
if ( level.teambased && isplayer( prey ) && player.team == prey.team )
|
||||
isfriendly = 1;
|
||||
else if ( level.teambased && isai( prey ) && player.team == prey.aiteam )
|
||||
isfriendly = 1;
|
||||
|
||||
if ( !isfriendly )
|
||||
{
|
||||
if ( isalive( prey ) )
|
||||
retrievable_model droptoground( retrievable_model.origin, 80 );
|
||||
else
|
||||
retrievable_model linkto( prey, bone );
|
||||
}
|
||||
else if ( isfriendly )
|
||||
{
|
||||
retrievable_model physicslaunch( normal, ( randomint( 10 ), randomint( 10 ), randomint( 10 ) ) );
|
||||
normal = ( 0, 0, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
watcher.objectarray[watcher.objectarray.size] = retrievable_model;
|
||||
|
||||
if ( isfriendly )
|
||||
retrievable_model waittill( "stationary" );
|
||||
|
||||
retrievable_model thread dropknivestoground();
|
||||
|
||||
if ( isfriendly )
|
||||
player notify( "ballistic_knife_stationary", retrievable_model, normal );
|
||||
else
|
||||
player notify( "ballistic_knife_stationary", retrievable_model, normal, prey );
|
||||
|
||||
retrievable_model thread wait_to_show_glowing_model( prey );
|
||||
}
|
||||
}
|
||||
|
||||
wait_to_show_glowing_model( prey )
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
self endon( "death" );
|
||||
glowing_retrievable_model = spawn( "script_model", self.origin );
|
||||
self.glowing_model = glowing_retrievable_model;
|
||||
glowing_retrievable_model.angles = self.angles;
|
||||
glowing_retrievable_model linkto( self );
|
||||
|
||||
if ( isdefined( prey ) && !isalive( prey ) )
|
||||
wait 2;
|
||||
|
||||
glowing_retrievable_model setmodel( "t6_wpn_ballistic_knife_blade_retrieve" );
|
||||
}
|
||||
|
||||
watch_shutdown()
|
||||
{
|
||||
pickuptrigger = self.pickuptrigger;
|
||||
glowing_model = self.glowing_model;
|
||||
|
||||
self waittill( "death" );
|
||||
|
||||
if ( isdefined( pickuptrigger ) )
|
||||
pickuptrigger delete();
|
||||
|
||||
if ( isdefined( glowing_model ) )
|
||||
glowing_model delete();
|
||||
}
|
||||
|
||||
onspawnretrievetrigger( watcher, player )
|
||||
{
|
||||
player endon( "death" );
|
||||
player endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
|
||||
player waittill( "ballistic_knife_stationary", retrievable_model, normal, prey );
|
||||
|
||||
if ( !isdefined( retrievable_model ) )
|
||||
return;
|
||||
|
||||
vec_scale = 10;
|
||||
trigger_pos = [];
|
||||
|
||||
if ( isdefined( prey ) && ( isplayer( prey ) || isai( prey ) ) )
|
||||
{
|
||||
trigger_pos[0] = prey.origin[0];
|
||||
trigger_pos[1] = prey.origin[1];
|
||||
trigger_pos[2] = prey.origin[2] + vec_scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_pos[0] = retrievable_model.origin[0] + vec_scale * normal[0];
|
||||
trigger_pos[1] = retrievable_model.origin[1] + vec_scale * normal[1];
|
||||
trigger_pos[2] = retrievable_model.origin[2] + vec_scale * normal[2];
|
||||
}
|
||||
|
||||
trigger_pos[2] -= 50.0;
|
||||
pickup_trigger = spawn( "trigger_radius", ( trigger_pos[0], trigger_pos[1], trigger_pos[2] ), 0, 50, 100 );
|
||||
pickup_trigger.owner = player;
|
||||
retrievable_model.pickuptrigger = pickup_trigger;
|
||||
pickup_trigger enablelinkto();
|
||||
|
||||
if ( isdefined( prey ) )
|
||||
pickup_trigger linkto( prey );
|
||||
else
|
||||
pickup_trigger linkto( retrievable_model );
|
||||
|
||||
retrievable_model thread watch_use_trigger( pickup_trigger, retrievable_model, ::pick_up, watcher.pickupsoundplayer, watcher.pickupsound );
|
||||
retrievable_model thread watch_shutdown();
|
||||
}
|
||||
|
||||
watch_use_trigger( trigger, model, callback, playersoundonuse, npcsoundonuse )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "delete" );
|
||||
level endon( "game_ended" );
|
||||
max_ammo = weaponmaxammo( "knife_ballistic_mp" ) + 1;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
trigger waittill( "trigger", player );
|
||||
|
||||
if ( !isalive( player ) )
|
||||
continue;
|
||||
|
||||
if ( !player isonground() )
|
||||
continue;
|
||||
|
||||
if ( isdefined( trigger.triggerteam ) && player.team != trigger.triggerteam )
|
||||
continue;
|
||||
|
||||
if ( isdefined( trigger.claimedby ) && player != trigger.claimedby )
|
||||
continue;
|
||||
|
||||
if ( !player hasweapon( "knife_ballistic_mp" ) )
|
||||
continue;
|
||||
|
||||
ammo_stock = player getweaponammostock( "knife_ballistic_mp" );
|
||||
ammo_clip = player getweaponammoclip( "knife_ballistic_mp" );
|
||||
current_weapon = player getcurrentweapon();
|
||||
total_ammo = ammo_stock + ammo_clip;
|
||||
hasreloaded = 1;
|
||||
|
||||
if ( total_ammo > 0 && ammo_stock == total_ammo && current_weapon == "knife_ballistic_mp" )
|
||||
hasreloaded = 0;
|
||||
|
||||
if ( total_ammo >= max_ammo || !hasreloaded )
|
||||
continue;
|
||||
|
||||
if ( isdefined( playersoundonuse ) )
|
||||
player playlocalsound( playersoundonuse );
|
||||
|
||||
if ( isdefined( npcsoundonuse ) )
|
||||
player playsound( npcsoundonuse );
|
||||
|
||||
self thread [[ callback ]]( player );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pick_up( player )
|
||||
{
|
||||
self destroy_ent();
|
||||
current_weapon = player getcurrentweapon();
|
||||
player maps\mp\_challenges::pickedupballisticknife();
|
||||
|
||||
if ( current_weapon != "knife_ballistic_mp" )
|
||||
{
|
||||
clip_ammo = player getweaponammoclip( "knife_ballistic_mp" );
|
||||
|
||||
if ( !clip_ammo )
|
||||
player setweaponammoclip( "knife_ballistic_mp", 1 );
|
||||
else
|
||||
{
|
||||
new_ammo_stock = player getweaponammostock( "knife_ballistic_mp" ) + 1;
|
||||
player setweaponammostock( "knife_ballistic_mp", new_ammo_stock );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new_ammo_stock = player getweaponammostock( "knife_ballistic_mp" ) + 1;
|
||||
player setweaponammostock( "knife_ballistic_mp", new_ammo_stock );
|
||||
}
|
||||
}
|
||||
|
||||
destroy_ent()
|
||||
{
|
||||
if ( isdefined( self ) )
|
||||
{
|
||||
pickuptrigger = self.pickuptrigger;
|
||||
|
||||
if ( isdefined( pickuptrigger ) )
|
||||
pickuptrigger delete();
|
||||
|
||||
if ( isdefined( self.glowing_model ) )
|
||||
self.glowing_model delete();
|
||||
|
||||
self delete();
|
||||
}
|
||||
}
|
||||
|
||||
dropknivestoground()
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
level waittill( "drop_objects_to_ground", origin, radius );
|
||||
|
||||
self droptoground( origin, radius );
|
||||
}
|
||||
}
|
||||
|
||||
droptoground( origin, radius )
|
||||
{
|
||||
if ( distancesquared( origin, self.origin ) < radius * radius )
|
||||
{
|
||||
self physicslaunch( ( 0, 0, 1 ), vectorscale( ( 1, 1, 1 ), 5.0 ) );
|
||||
self thread updateretrievetrigger();
|
||||
}
|
||||
}
|
||||
|
||||
updateretrievetrigger()
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
self waittill( "stationary" );
|
||||
|
||||
trigger = self.pickuptrigger;
|
||||
trigger.origin = ( self.origin[0], self.origin[1], self.origin[2] + 10 );
|
||||
trigger linkto( self );
|
||||
}
|
89
MP/Core/maps/mp/_bb.gsc
Normal file
89
MP/Core/maps/mp/_bb.gsc
Normal file
@ -0,0 +1,89 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level thread onplayerconnect();
|
||||
}
|
||||
|
||||
onplayerconnect()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
player thread onplayerspawned();
|
||||
player thread onplayerdeath();
|
||||
}
|
||||
}
|
||||
|
||||
onplayerspawned()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self._bbdata = [];
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
|
||||
self._bbdata["score"] = 0;
|
||||
self._bbdata["momentum"] = 0;
|
||||
self._bbdata["spawntime"] = gettime();
|
||||
self._bbdata["shots"] = 0;
|
||||
self._bbdata["hits"] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
onplayerdisconnect()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "disconnect" );
|
||||
|
||||
self commitspawndata();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
onplayerdeath()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "death" );
|
||||
|
||||
self commitspawndata();
|
||||
}
|
||||
}
|
||||
|
||||
commitspawndata()
|
||||
{
|
||||
assert( isdefined( self._bbdata ) );
|
||||
|
||||
if ( !isdefined( self._bbdata ) )
|
||||
return;
|
||||
|
||||
bbprint( "mpplayerlives", "gametime %d spawnid %d lifescore %d lifemomentum %d lifetime %d name %s", gettime(), getplayerspawnid( self ), self._bbdata["score"], self._bbdata["momentum"], gettime() - self._bbdata["spawntime"], self.name );
|
||||
}
|
||||
|
||||
commitweapondata( spawnid, currentweapon, time0 )
|
||||
{
|
||||
assert( isdefined( self._bbdata ) );
|
||||
|
||||
if ( !isdefined( self._bbdata ) )
|
||||
return;
|
||||
|
||||
time1 = gettime();
|
||||
bbprint( "mpweapons", "spawnid %d name %s duration %d shots %d hits %d", spawnid, currentweapon, time1 - time0, self._bbdata["shots"], self._bbdata["hits"] );
|
||||
self._bbdata["shots"] = 0;
|
||||
self._bbdata["hits"] = 0;
|
||||
}
|
||||
|
||||
bbaddtostat( statname, delta )
|
||||
{
|
||||
if ( isdefined( self._bbdata ) && isdefined( self._bbdata[statname] ) )
|
||||
self._bbdata[statname] += delta;
|
||||
}
|
173
MP/Core/maps/mp/_bouncingbetty.gsc
Normal file
173
MP/Core/maps/mp/_bouncingbetty.gsc
Normal file
@ -0,0 +1,173 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\gametypes\_weaponobjects;
|
||||
#include maps\mp\_challenges;
|
||||
#include maps\mp\_scoreevents;
|
||||
|
||||
init()
|
||||
{
|
||||
precachemodel( "t6_wpn_bouncing_betty_world" );
|
||||
level.bettyexplosionfx = loadfx( "weapon/bouncing_betty/fx_betty_explosion" );
|
||||
level.bettydestroyedfx = loadfx( "weapon/bouncing_betty/fx_betty_destroyed" );
|
||||
level.bettylaunchfx = loadfx( "weapon/bouncing_betty/fx_betty_launch_dust" );
|
||||
level._effect["fx_betty_friendly_light"] = loadfx( "weapon/bouncing_betty/fx_betty_light_green" );
|
||||
level._effect["fx_betty_enemy_light"] = loadfx( "weapon/bouncing_betty/fx_betty_light_red" );
|
||||
level.bettymindist = 20;
|
||||
level.bettygraceperiod = 0.6;
|
||||
level.bettyradius = 192;
|
||||
level.bettystuntime = 1;
|
||||
level.bettydamageradius = 256;
|
||||
level.bettydamagemax = 210;
|
||||
level.bettydamagemin = 70;
|
||||
level.bettyjumpheight = 65;
|
||||
level.bettyjumptime = 0.65;
|
||||
level.bettyrotatevelocity = ( 0, 750, 32 );
|
||||
level.bettyactivationdelay = 0.1;
|
||||
}
|
||||
|
||||
createbouncingbettywatcher()
|
||||
{
|
||||
watcher = self createproximityweaponobjectwatcher( "bouncingbetty", "bouncingbetty_mp", self.team );
|
||||
watcher.onspawn = ::onspawnbouncingbetty;
|
||||
watcher.watchforfire = 1;
|
||||
watcher.detonate = ::bouncingbettydetonate;
|
||||
watcher.activatesound = "wpn_claymore_alert";
|
||||
watcher.hackable = 1;
|
||||
watcher.hackertoolradius = level.equipmenthackertoolradius;
|
||||
watcher.hackertooltimems = level.equipmenthackertooltimems;
|
||||
watcher.reconmodel = "t6_wpn_bouncing_betty_world_detect";
|
||||
watcher.ownergetsassist = 1;
|
||||
watcher.ignoredirection = 1;
|
||||
watcher.detectionmindist = level.bettymindist;
|
||||
watcher.detectiongraceperiod = level.bettygraceperiod;
|
||||
watcher.detonateradius = level.bettyradius;
|
||||
watcher.stun = ::weaponstun;
|
||||
watcher.stuntime = level.bettystuntime;
|
||||
watcher.activationdelay = level.bettyactivationdelay;
|
||||
}
|
||||
|
||||
onspawnbouncingbetty( watcher, owner )
|
||||
{
|
||||
onspawnproximityweaponobject( watcher, owner );
|
||||
self thread spawnminemover();
|
||||
}
|
||||
|
||||
spawnminemover()
|
||||
{
|
||||
self waittillnotmoving();
|
||||
minemover = spawn( "script_model", self.origin );
|
||||
minemover.angles = self.angles;
|
||||
minemover setmodel( "tag_origin" );
|
||||
minemover.owner = self.owner;
|
||||
minemover.killcamoffset = ( 0, 0, getdvarfloatdefault( "scr_bouncing_betty_killcam_offset", 8.0 ) );
|
||||
killcament = spawn( "script_model", minemover.origin + minemover.killcamoffset );
|
||||
killcament.angles = ( 0, 0, 0 );
|
||||
killcament setmodel( "tag_origin" );
|
||||
killcament setweapon( "bouncingbetty_mp" );
|
||||
minemover.killcament = killcament;
|
||||
self.minemover = minemover;
|
||||
self thread killminemoveronpickup();
|
||||
}
|
||||
|
||||
killminemoveronpickup()
|
||||
{
|
||||
self.minemover endon( "death" );
|
||||
self waittill_any( "picked_up", "hacked" );
|
||||
self killminemover();
|
||||
}
|
||||
|
||||
killminemover()
|
||||
{
|
||||
if ( isdefined( self.minemover ) )
|
||||
{
|
||||
if ( isdefined( self.minemover.killcament ) )
|
||||
self.minemover.killcament delete();
|
||||
|
||||
self.minemover delete();
|
||||
}
|
||||
}
|
||||
|
||||
bouncingbettydetonate( attacker, weaponname )
|
||||
{
|
||||
if ( isdefined( weaponname ) )
|
||||
{
|
||||
if ( isdefined( attacker ) )
|
||||
{
|
||||
if ( self.owner isenemyplayer( attacker ) )
|
||||
{
|
||||
attacker maps\mp\_challenges::destroyedexplosive( weaponname );
|
||||
maps\mp\_scoreevents::processscoreevent( "destroyed_bouncingbetty", attacker, self.owner, weaponname );
|
||||
}
|
||||
}
|
||||
|
||||
self bouncingbettydestroyed();
|
||||
}
|
||||
else if ( isdefined( self.minemover ) )
|
||||
{
|
||||
self.minemover setmodel( self.model );
|
||||
self.minemover thread bouncingbettyjumpandexplode();
|
||||
self delete();
|
||||
}
|
||||
else
|
||||
self bouncingbettydestroyed();
|
||||
}
|
||||
|
||||
bouncingbettydestroyed()
|
||||
{
|
||||
playfx( level.bettydestroyedfx, self.origin );
|
||||
playsoundatposition( "dst_equipment_destroy", self.origin );
|
||||
|
||||
if ( isdefined( self.trigger ) )
|
||||
self.trigger delete();
|
||||
|
||||
if ( isdefined( self.minemover ) )
|
||||
{
|
||||
if ( isdefined( self.minemover.killcament ) )
|
||||
self.minemover.killcament delete();
|
||||
|
||||
self.minemover delete();
|
||||
}
|
||||
|
||||
self radiusdamage( self.origin, 128, 110, 10, self.owner, "MOD_EXPLOSIVE", "bouncingbetty_mp" );
|
||||
self delete();
|
||||
}
|
||||
|
||||
bouncingbettyjumpandexplode()
|
||||
{
|
||||
explodepos = self.origin + ( 0, 0, level.bettyjumpheight );
|
||||
self moveto( explodepos, level.bettyjumptime, level.bettyjumptime, 0 );
|
||||
self.killcament moveto( explodepos + self.killcamoffset, level.bettyjumptime, 0, level.bettyjumptime );
|
||||
playfx( level.bettylaunchfx, self.origin );
|
||||
self rotatevelocity( level.bettyrotatevelocity, level.bettyjumptime, 0, level.bettyjumptime );
|
||||
self playsound( "fly_betty_jump" );
|
||||
wait( level.bettyjumptime );
|
||||
self thread mineexplode();
|
||||
}
|
||||
|
||||
mineexplode()
|
||||
{
|
||||
if ( !isdefined( self ) || !isdefined( self.owner ) )
|
||||
return;
|
||||
|
||||
self playsound( "fly_betty_explo" );
|
||||
wait 0.05;
|
||||
|
||||
if ( !isdefined( self ) || !isdefined( self.owner ) )
|
||||
return;
|
||||
|
||||
self hide();
|
||||
self radiusdamage( self.origin, level.bettydamageradius, level.bettydamagemax, level.bettydamagemin, self.owner, "MOD_EXPLOSIVE", "bouncingbetty_mp" );
|
||||
playfx( level.bettyexplosionfx, self.origin );
|
||||
wait 0.2;
|
||||
|
||||
if ( !isdefined( self ) || !isdefined( self.owner ) )
|
||||
return;
|
||||
|
||||
if ( isdefined( self.trigger ) )
|
||||
self.trigger delete();
|
||||
|
||||
self.killcament delete();
|
||||
self delete();
|
||||
}
|
569
MP/Core/maps/mp/_burnplayer.gsc
Normal file
569
MP/Core/maps/mp/_burnplayer.gsc
Normal file
@ -0,0 +1,569 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_globallogic_player;
|
||||
#include maps\mp\gametypes\_damagefeedback;
|
||||
|
||||
initburnplayer()
|
||||
{
|
||||
level.flamedamage = 15;
|
||||
level.flameburntime = 1.5;
|
||||
}
|
||||
|
||||
hitwithincendiary( attacker, inflictor, mod )
|
||||
{
|
||||
if ( isdefined( self.burning ) )
|
||||
return;
|
||||
|
||||
self starttanning();
|
||||
self thread waitthenstoptanning( level.flameburntime );
|
||||
self endon( "disconnect" );
|
||||
attacker endon( "disconnect" );
|
||||
waittillframeend;
|
||||
self.burning = 1;
|
||||
self thread burn_blocker();
|
||||
tagarray = [];
|
||||
|
||||
if ( isai( self ) )
|
||||
{
|
||||
tagarray[tagarray.size] = "J_Wrist_RI";
|
||||
tagarray[tagarray.size] = "J_Wrist_LE";
|
||||
tagarray[tagarray.size] = "J_Elbow_LE";
|
||||
tagarray[tagarray.size] = "J_Elbow_RI";
|
||||
tagarray[tagarray.size] = "J_Knee_RI";
|
||||
tagarray[tagarray.size] = "J_Knee_LE";
|
||||
tagarray[tagarray.size] = "J_Ankle_RI";
|
||||
tagarray[tagarray.size] = "J_Ankle_LE";
|
||||
}
|
||||
else
|
||||
{
|
||||
tagarray[tagarray.size] = "J_Wrist_RI";
|
||||
tagarray[tagarray.size] = "J_Wrist_LE";
|
||||
tagarray[tagarray.size] = "J_Elbow_LE";
|
||||
tagarray[tagarray.size] = "J_Elbow_RI";
|
||||
tagarray[tagarray.size] = "J_Knee_RI";
|
||||
tagarray[tagarray.size] = "J_Knee_LE";
|
||||
tagarray[tagarray.size] = "J_Ankle_RI";
|
||||
tagarray[tagarray.size] = "J_Ankle_LE";
|
||||
|
||||
if ( isplayer( self ) && self.health > 0 )
|
||||
self setburn( 3.0 );
|
||||
}
|
||||
|
||||
if ( isdefined( level._effect["character_fire_death_torso"] ) )
|
||||
{
|
||||
for ( arrayindex = 0; arrayindex < tagarray.size; arrayindex++ )
|
||||
playfxontag( level._effect["character_fire_death_sm"], self, tagarray[arrayindex] );
|
||||
}
|
||||
|
||||
if ( isai( self ) )
|
||||
playfxontag( level._effect["character_fire_death_torso"], self, "J_Spine1" );
|
||||
else
|
||||
playfxontag( level._effect["character_fire_death_torso"], self, "J_SpineLower" );
|
||||
|
||||
if ( !isalive( self ) )
|
||||
return;
|
||||
|
||||
if ( isplayer( self ) )
|
||||
{
|
||||
self thread watchforwater( 7 );
|
||||
self thread watchfordeath();
|
||||
}
|
||||
}
|
||||
|
||||
hitwithnapalmstrike( attacker, inflictor, mod )
|
||||
{
|
||||
if ( isdefined( self.burning ) || self hasperk( "specialty_fireproof" ) )
|
||||
return;
|
||||
|
||||
self starttanning();
|
||||
self thread waitthenstoptanning( level.flameburntime );
|
||||
self endon( "disconnect" );
|
||||
attacker endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
|
||||
if ( isdefined( self.burning ) )
|
||||
return;
|
||||
|
||||
self thread burn_blocker();
|
||||
waittillframeend;
|
||||
self.burning = 1;
|
||||
self thread burn_blocker();
|
||||
tagarray = [];
|
||||
|
||||
if ( isai( self ) )
|
||||
{
|
||||
tagarray[tagarray.size] = "J_Wrist_RI";
|
||||
tagarray[tagarray.size] = "J_Wrist_LE";
|
||||
tagarray[tagarray.size] = "J_Elbow_LE";
|
||||
tagarray[tagarray.size] = "J_Elbow_RI";
|
||||
tagarray[tagarray.size] = "J_Knee_RI";
|
||||
tagarray[tagarray.size] = "J_Knee_LE";
|
||||
tagarray[tagarray.size] = "J_Ankle_RI";
|
||||
tagarray[tagarray.size] = "J_Ankle_LE";
|
||||
}
|
||||
else
|
||||
{
|
||||
tagarray[tagarray.size] = "J_Wrist_RI";
|
||||
tagarray[tagarray.size] = "J_Wrist_LE";
|
||||
tagarray[tagarray.size] = "J_Elbow_LE";
|
||||
tagarray[tagarray.size] = "J_Elbow_RI";
|
||||
tagarray[tagarray.size] = "J_Knee_RI";
|
||||
tagarray[tagarray.size] = "J_Knee_LE";
|
||||
tagarray[tagarray.size] = "J_Ankle_RI";
|
||||
tagarray[tagarray.size] = "J_Ankle_LE";
|
||||
|
||||
if ( isplayer( self ) )
|
||||
self setburn( 3.0 );
|
||||
}
|
||||
|
||||
if ( isdefined( level._effect["character_fire_death_sm"] ) )
|
||||
{
|
||||
for ( arrayindex = 0; arrayindex < tagarray.size; arrayindex++ )
|
||||
playfxontag( level._effect["character_fire_death_sm"], self, tagarray[arrayindex] );
|
||||
}
|
||||
|
||||
if ( isdefined( level._effect["character_fire_death_torso"] ) )
|
||||
playfxontag( level._effect["character_fire_death_torso"], self, "J_SpineLower" );
|
||||
|
||||
if ( !isalive( self ) )
|
||||
return;
|
||||
|
||||
self thread donapalmstrikedamage( attacker, inflictor, mod );
|
||||
|
||||
if ( isplayer( self ) )
|
||||
{
|
||||
self thread watchforwater( 7 );
|
||||
self thread watchfordeath();
|
||||
}
|
||||
}
|
||||
|
||||
walkedthroughflames( attacker, inflictor, weapon )
|
||||
{
|
||||
if ( isdefined( self.burning ) || self hasperk( "specialty_fireproof" ) )
|
||||
return;
|
||||
|
||||
self starttanning();
|
||||
self thread waitthenstoptanning( level.flameburntime );
|
||||
self endon( "disconnect" );
|
||||
waittillframeend;
|
||||
self.burning = 1;
|
||||
self thread burn_blocker();
|
||||
tagarray = [];
|
||||
|
||||
if ( isai( self ) )
|
||||
{
|
||||
tagarray[tagarray.size] = "J_Wrist_RI";
|
||||
tagarray[tagarray.size] = "J_Wrist_LE";
|
||||
tagarray[tagarray.size] = "J_Elbow_LE";
|
||||
tagarray[tagarray.size] = "J_Elbow_RI";
|
||||
tagarray[tagarray.size] = "J_Knee_RI";
|
||||
tagarray[tagarray.size] = "J_Knee_LE";
|
||||
tagarray[tagarray.size] = "J_Ankle_RI";
|
||||
tagarray[tagarray.size] = "J_Ankle_LE";
|
||||
}
|
||||
else
|
||||
{
|
||||
tagarray[tagarray.size] = "J_Knee_RI";
|
||||
tagarray[tagarray.size] = "J_Knee_LE";
|
||||
tagarray[tagarray.size] = "J_Ankle_RI";
|
||||
tagarray[tagarray.size] = "J_Ankle_LE";
|
||||
}
|
||||
|
||||
if ( isdefined( level._effect["character_fire_player_sm"] ) )
|
||||
{
|
||||
for ( arrayindex = 0; arrayindex < tagarray.size; arrayindex++ )
|
||||
playfxontag( level._effect["character_fire_player_sm"], self, tagarray[arrayindex] );
|
||||
}
|
||||
|
||||
if ( !isalive( self ) )
|
||||
return;
|
||||
|
||||
self thread doflamedamage( attacker, inflictor, weapon, 1.0 );
|
||||
|
||||
if ( isplayer( self ) )
|
||||
{
|
||||
self thread watchforwater( 7 );
|
||||
self thread watchfordeath();
|
||||
}
|
||||
}
|
||||
|
||||
burnedwithflamethrower( attacker, inflictor, weapon )
|
||||
{
|
||||
if ( isdefined( self.burning ) )
|
||||
return;
|
||||
|
||||
self starttanning();
|
||||
self thread waitthenstoptanning( level.flameburntime );
|
||||
self endon( "disconnect" );
|
||||
waittillframeend;
|
||||
self.burning = 1;
|
||||
self thread burn_blocker();
|
||||
tagarray = [];
|
||||
|
||||
if ( isai( self ) )
|
||||
{
|
||||
tagarray[0] = "J_Spine1";
|
||||
tagarray[1] = "J_Elbow_LE";
|
||||
tagarray[2] = "J_Elbow_RI";
|
||||
tagarray[3] = "J_Head";
|
||||
tagarray[4] = "j_knee_ri";
|
||||
tagarray[5] = "j_knee_le";
|
||||
}
|
||||
else
|
||||
{
|
||||
tagarray[0] = "J_Elbow_RI";
|
||||
tagarray[1] = "j_knee_ri";
|
||||
tagarray[2] = "j_knee_le";
|
||||
|
||||
if ( isplayer( self ) && self.health > 0 )
|
||||
self setburn( 3.0 );
|
||||
}
|
||||
|
||||
if ( isplayer( self ) && isalive( self ) )
|
||||
{
|
||||
self thread watchforwater( 7 );
|
||||
self thread watchfordeath();
|
||||
}
|
||||
|
||||
if ( isdefined( level._effect["character_fire_player_sm"] ) )
|
||||
{
|
||||
for ( arrayindex = 0; arrayindex < tagarray.size; arrayindex++ )
|
||||
playfxontag( level._effect["character_fire_player_sm"], self, tagarray[arrayindex] );
|
||||
}
|
||||
}
|
||||
|
||||
burnedwithdragonsbreath( attacker, inflictor, weapon )
|
||||
{
|
||||
if ( isdefined( self.burning ) )
|
||||
return;
|
||||
|
||||
self starttanning();
|
||||
self thread waitthenstoptanning( level.flameburntime );
|
||||
self endon( "disconnect" );
|
||||
waittillframeend;
|
||||
self.burning = 1;
|
||||
self thread burn_blocker();
|
||||
tagarray = [];
|
||||
|
||||
if ( isai( self ) )
|
||||
{
|
||||
tagarray[0] = "J_Spine1";
|
||||
tagarray[1] = "J_Elbow_LE";
|
||||
tagarray[2] = "J_Elbow_RI";
|
||||
tagarray[3] = "J_Head";
|
||||
tagarray[4] = "j_knee_ri";
|
||||
tagarray[5] = "j_knee_le";
|
||||
}
|
||||
else
|
||||
{
|
||||
tagarray[0] = "j_spinelower";
|
||||
tagarray[1] = "J_Elbow_RI";
|
||||
tagarray[2] = "j_knee_ri";
|
||||
tagarray[3] = "j_knee_le";
|
||||
|
||||
if ( isplayer( self ) && self.health > 0 )
|
||||
self setburn( 3.0 );
|
||||
}
|
||||
|
||||
if ( isplayer( self ) && isalive( self ) )
|
||||
{
|
||||
self thread watchforwater( 7 );
|
||||
self thread watchfordeath();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isdefined( level._effect["character_fire_player_sm"] ) )
|
||||
{
|
||||
for ( arrayindex = 0; arrayindex < tagarray.size; arrayindex++ )
|
||||
playfxontag( level._effect["character_fire_player_sm"], self, tagarray[arrayindex] );
|
||||
}
|
||||
}
|
||||
|
||||
burnedtodeath()
|
||||
{
|
||||
self.burning = 1;
|
||||
self thread burn_blocker();
|
||||
self starttanning();
|
||||
self thread doburningsound();
|
||||
self thread waitthenstoptanning( level.flameburntime );
|
||||
}
|
||||
|
||||
watchfordeath()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self notify( "watching for death while on fire" );
|
||||
self endon( "watching for death while on fire" );
|
||||
|
||||
self waittill( "death" );
|
||||
|
||||
if ( isplayer( self ) )
|
||||
self _stopburning();
|
||||
|
||||
self.burning = undefined;
|
||||
}
|
||||
|
||||
watchforwater( time )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self notify( "watching for water" );
|
||||
self endon( "watching for water" );
|
||||
wait 0.1;
|
||||
looptime = 0.1;
|
||||
|
||||
while ( time > 0 )
|
||||
{
|
||||
wait( looptime );
|
||||
|
||||
if ( self depthofplayerinwater() > 0 )
|
||||
{
|
||||
finish_burn();
|
||||
time = 0;
|
||||
}
|
||||
|
||||
time -= looptime;
|
||||
}
|
||||
}
|
||||
|
||||
finish_burn()
|
||||
{
|
||||
self notify( "stop burn damage" );
|
||||
tagarray = [];
|
||||
tagarray[0] = "j_spinelower";
|
||||
tagarray[1] = "J_Elbow_RI";
|
||||
tagarray[2] = "J_Head";
|
||||
tagarray[3] = "j_knee_ri";
|
||||
tagarray[4] = "j_knee_le";
|
||||
|
||||
if ( isdefined( level._effect["fx_fire_player_sm_smk_2sec"] ) )
|
||||
{
|
||||
for ( arrayindex = 0; arrayindex < tagarray.size; arrayindex++ )
|
||||
playfxontag( level._effect["fx_fire_player_sm_smk_2sec"], self, tagarray[arrayindex] );
|
||||
}
|
||||
|
||||
self.burning = undefined;
|
||||
self _stopburning();
|
||||
self.ingroundnapalm = 0;
|
||||
}
|
||||
|
||||
donapalmstrikedamage( attacker, inflictor, mod )
|
||||
{
|
||||
if ( isai( self ) )
|
||||
{
|
||||
dodognapalmstrikedamage( attacker, inflictor, mod );
|
||||
return;
|
||||
}
|
||||
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
attacker endon( "disconnect" );
|
||||
self endon( "stop burn damage" );
|
||||
|
||||
while ( isdefined( level.napalmstrikedamage ) && isdefined( self ) && self depthofplayerinwater() < 1 )
|
||||
{
|
||||
self dodamage( level.napalmstrikedamage, self.origin, attacker, attacker, "none", mod, 0, "napalm_mp" );
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
|
||||
donapalmgrounddamage( attacker, inflictor, mod )
|
||||
{
|
||||
if ( self hasperk( "specialty_fireproof" ) )
|
||||
return;
|
||||
|
||||
if ( level.teambased )
|
||||
{
|
||||
if ( attacker != self && attacker.team == self.team )
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isai( self ) )
|
||||
{
|
||||
dodognapalmgrounddamage( attacker, inflictor, mod );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isdefined( self.burning ) )
|
||||
return;
|
||||
|
||||
self thread burn_blocker();
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
attacker endon( "disconnect" );
|
||||
self endon( "stop burn damage" );
|
||||
|
||||
if ( isdefined( level.groundburntime ) )
|
||||
{
|
||||
if ( getdvar( _hash_6EC13261 ) == "" )
|
||||
waittime = level.groundburntime;
|
||||
else
|
||||
waittime = getdvarfloat( _hash_6EC13261 );
|
||||
}
|
||||
else
|
||||
waittime = 100;
|
||||
|
||||
self walkedthroughflames( attacker, inflictor, "napalm_mp" );
|
||||
self.ingroundnapalm = 1;
|
||||
|
||||
if ( isdefined( level.napalmgrounddamage ) )
|
||||
{
|
||||
if ( getdvar( _hash_3FFA6673 ) == "" )
|
||||
napalmgrounddamage = level.napalmgrounddamage;
|
||||
else
|
||||
napalmgrounddamage = getdvarfloat( _hash_3FFA6673 );
|
||||
|
||||
while ( isdefined( self ) && isdefined( inflictor ) && self depthofplayerinwater() < 1 && waittime > 0 )
|
||||
{
|
||||
self dodamage( level.napalmgrounddamage, self.origin, attacker, inflictor, "none", mod, 0, "napalm_mp" );
|
||||
|
||||
if ( isplayer( self ) )
|
||||
self setburn( 1.1 );
|
||||
|
||||
wait 1;
|
||||
waittime -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
self.ingroundnapalm = 0;
|
||||
}
|
||||
|
||||
dodognapalmstrikedamage( attacker, inflictor, mod )
|
||||
{
|
||||
attacker endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self endon( "stop burn damage" );
|
||||
|
||||
while ( isdefined( level.napalmstrikedamage ) && isdefined( self ) )
|
||||
{
|
||||
self dodamage( level.napalmstrikedamage, self.origin, attacker, attacker, "none", mod );
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
|
||||
dodognapalmgrounddamage( attacker, inflictor, mod )
|
||||
{
|
||||
attacker endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self endon( "stop burn damage" );
|
||||
|
||||
while ( isdefined( level.napalmgrounddamage ) && isdefined( self ) )
|
||||
{
|
||||
self dodamage( level.napalmgrounddamage, self.origin, attacker, attacker, "none", mod, 0, "napalm_mp" );
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
|
||||
burn_blocker()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
wait 3;
|
||||
self.burning = undefined;
|
||||
}
|
||||
|
||||
doflamedamage( attacker, inflictor, weapon, time )
|
||||
{
|
||||
if ( isai( self ) )
|
||||
{
|
||||
dodogflamedamage( attacker, inflictor, weapon, time );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isdefined( attacker ) )
|
||||
attacker endon( "disconnect" );
|
||||
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "stop burn damage" );
|
||||
self thread doburningsound();
|
||||
self notify( "snd_burn_scream" );
|
||||
wait_time = 1.0;
|
||||
|
||||
while ( isdefined( level.flamedamage ) && isdefined( self ) && self depthofplayerinwater() < 1 && time > 0 )
|
||||
{
|
||||
if ( isdefined( attacker ) && isdefined( inflictor ) && isdefined( weapon ) )
|
||||
{
|
||||
if ( maps\mp\gametypes\_globallogic_player::dodamagefeedback( weapon, attacker ) )
|
||||
attacker maps\mp\gametypes\_damagefeedback::updatedamagefeedback();
|
||||
|
||||
self dodamage( level.flamedamage, self.origin, attacker, inflictor, "none", "MOD_BURNED", 0, weapon );
|
||||
}
|
||||
else
|
||||
self dodamage( level.flamedamage, self.origin );
|
||||
|
||||
wait( wait_time );
|
||||
time -= wait_time;
|
||||
}
|
||||
|
||||
self thread finish_burn();
|
||||
}
|
||||
|
||||
dodogflamedamage( attacker, inflictor, weapon, time )
|
||||
{
|
||||
if ( !isdefined( attacker ) || !isdefined( inflictor ) || !isdefined( weapon ) )
|
||||
return;
|
||||
|
||||
attacker endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self endon( "stop burn damage" );
|
||||
self thread doburningsound();
|
||||
wait_time = 1.0;
|
||||
|
||||
while ( isdefined( level.flamedamage ) && isdefined( self ) && time > 0 )
|
||||
{
|
||||
self dodamage( level.flamedamage, self.origin, attacker, inflictor, "none", "MOD_BURNED", 0, weapon );
|
||||
wait( wait_time );
|
||||
time -= wait_time;
|
||||
}
|
||||
}
|
||||
|
||||
waitthenstoptanning( time )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
wait( time );
|
||||
self _stopburning();
|
||||
}
|
||||
|
||||
doburningsound()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
fire_sound_ent = spawn( "script_origin", self.origin );
|
||||
fire_sound_ent linkto( self, "tag_origin", ( 0, 0, 0 ), ( 0, 0, 0 ) );
|
||||
fire_sound_ent playloopsound( "mpl_player_burn_loop" );
|
||||
self thread firesounddeath( fire_sound_ent );
|
||||
|
||||
self waittill( "StopBurnSound" );
|
||||
|
||||
if ( isdefined( fire_sound_ent ) )
|
||||
fire_sound_ent stoploopsound( 0.5 );
|
||||
|
||||
wait 0.5;
|
||||
|
||||
if ( isdefined( fire_sound_ent ) )
|
||||
fire_sound_ent delete();
|
||||
/#
|
||||
println( "sound stop burning" );
|
||||
#/
|
||||
}
|
||||
|
||||
_stopburning()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self notify( "StopBurnSound" );
|
||||
|
||||
if ( isdefined( self ) )
|
||||
self stopburning();
|
||||
}
|
||||
|
||||
firesounddeath( ent )
|
||||
{
|
||||
ent endon( "death" );
|
||||
self waittill_any( "death", "disconnect" );
|
||||
ent delete();
|
||||
/#
|
||||
println( "sound delete burning" );
|
||||
#/
|
||||
}
|
18
MP/Core/maps/mp/_busing.gsc
Normal file
18
MP/Core/maps/mp/_busing.gsc
Normal file
@ -0,0 +1,18 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
|
||||
businit()
|
||||
{
|
||||
assert( level.clientscripts );
|
||||
level.busstate = "";
|
||||
registerclientsys( "busCmd" );
|
||||
}
|
||||
|
||||
setbusstate( state )
|
||||
{
|
||||
if ( level.busstate != state )
|
||||
setclientsysstate( "busCmd", state );
|
||||
|
||||
level.busstate = state;
|
||||
}
|
1876
MP/Core/maps/mp/_challenges.gsc
Normal file
1876
MP/Core/maps/mp/_challenges.gsc
Normal file
File diff suppressed because it is too large
Load Diff
76
MP/Core/maps/mp/_compass.gsc
Normal file
76
MP/Core/maps/mp/_compass.gsc
Normal file
@ -0,0 +1,76 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
|
||||
setupminimap( material )
|
||||
{
|
||||
requiredmapaspectratio = getdvarfloat( "scr_RequiredMapAspectratio" );
|
||||
corners = getentarray( "minimap_corner", "targetname" );
|
||||
|
||||
if ( corners.size != 2 )
|
||||
{
|
||||
/#
|
||||
println( "^1Error: There are not exactly two \"minimap_corner\" entities in the map. Could not set up minimap." );
|
||||
#/
|
||||
return;
|
||||
}
|
||||
|
||||
corner0 = ( corners[0].origin[0], corners[0].origin[1], 0 );
|
||||
corner1 = ( corners[1].origin[0], corners[1].origin[1], 0 );
|
||||
cornerdiff = corner1 - corner0;
|
||||
north = ( cos( getnorthyaw() ), sin( getnorthyaw() ), 0 );
|
||||
west = ( 0 - north[1], north[0], 0 );
|
||||
|
||||
if ( vectordot( cornerdiff, west ) > 0 )
|
||||
{
|
||||
if ( vectordot( cornerdiff, north ) > 0 )
|
||||
{
|
||||
northwest = corner1;
|
||||
southeast = corner0;
|
||||
}
|
||||
else
|
||||
{
|
||||
side = vecscale( north, vectordot( cornerdiff, north ) );
|
||||
northwest = corner1 - side;
|
||||
southeast = corner0 + side;
|
||||
}
|
||||
}
|
||||
else if ( vectordot( cornerdiff, north ) > 0 )
|
||||
{
|
||||
side = vecscale( north, vectordot( cornerdiff, north ) );
|
||||
northwest = corner0 + side;
|
||||
southeast = corner1 - side;
|
||||
}
|
||||
else
|
||||
{
|
||||
northwest = corner0;
|
||||
southeast = corner1;
|
||||
}
|
||||
|
||||
if ( requiredmapaspectratio > 0 )
|
||||
{
|
||||
northportion = vectordot( northwest - southeast, north );
|
||||
westportion = vectordot( northwest - southeast, west );
|
||||
mapaspectratio = westportion / northportion;
|
||||
|
||||
if ( mapaspectratio < requiredmapaspectratio )
|
||||
{
|
||||
incr = requiredmapaspectratio / mapaspectratio;
|
||||
addvec = vecscale( west, westportion * ( incr - 1 ) * 0.5 );
|
||||
}
|
||||
else
|
||||
{
|
||||
incr = mapaspectratio / requiredmapaspectratio;
|
||||
addvec = vecscale( north, northportion * ( incr - 1 ) * 0.5 );
|
||||
}
|
||||
|
||||
northwest += addvec;
|
||||
southeast -= addvec;
|
||||
}
|
||||
|
||||
setminimap( material, northwest[0], northwest[1], southeast[0], southeast[1] );
|
||||
}
|
||||
|
||||
vecscale( vec, scalar )
|
||||
{
|
||||
return ( vec[0] * scalar, vec[1] * scalar, vec[2] * scalar );
|
||||
}
|
2944
MP/Core/maps/mp/_createfx.gsc
Normal file
2944
MP/Core/maps/mp/_createfx.gsc
Normal file
File diff suppressed because it is too large
Load Diff
941
MP/Core/maps/mp/_createfxmenu.gsc
Normal file
941
MP/Core/maps/mp/_createfxmenu.gsc
Normal file
@ -0,0 +1,941 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\_createfx;
|
||||
#include maps\mp\_createfxundo;
|
||||
|
||||
menu( name )
|
||||
{
|
||||
/#
|
||||
return level.create_fx_menu == name;
|
||||
#/
|
||||
}
|
||||
|
||||
setmenu( name )
|
||||
{
|
||||
/#
|
||||
level.create_fx_menu = name;
|
||||
#/
|
||||
}
|
||||
|
||||
create_fx_menu()
|
||||
{
|
||||
/#
|
||||
if ( button_is_clicked( "escape", "x" ) )
|
||||
{
|
||||
exit_menu();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( menu( "creation" ) )
|
||||
{
|
||||
if ( button_is_clicked( "1" ) )
|
||||
{
|
||||
setmenu( "create_oneshot" );
|
||||
draw_effects_list();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( button_is_clicked( "2" ) )
|
||||
{
|
||||
setmenu( "create_loopfx" );
|
||||
draw_effects_list();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( button_is_clicked( "3" ) )
|
||||
{
|
||||
setmenu( "create_exploder" );
|
||||
draw_effects_list();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( button_is_clicked( "4" ) )
|
||||
{
|
||||
setmenu( "create_loopsound" );
|
||||
ent = createloopsound();
|
||||
finish_creating_entity( ent );
|
||||
setmenu( "none" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( menu( "create_oneshot" ) || menu( "create_loopfx" ) || menu( "create_exploder" ) || menu( "change_fxid" ) )
|
||||
{
|
||||
if ( button_is_clicked( "rightarrow" ) )
|
||||
{
|
||||
increment_list_offset();
|
||||
draw_effects_list();
|
||||
}
|
||||
|
||||
if ( button_is_clicked( "leftarrow" ) )
|
||||
{
|
||||
decrement_list_offset();
|
||||
draw_effects_list();
|
||||
}
|
||||
|
||||
menu_fx_creation();
|
||||
}
|
||||
else if ( menu( "none" ) )
|
||||
{
|
||||
menu_change_selected_fx();
|
||||
|
||||
if ( entities_are_selected() )
|
||||
{
|
||||
display_fx_info( get_last_selected_entity() );
|
||||
|
||||
if ( button_is_clicked( "a" ) )
|
||||
{
|
||||
clear_settable_fx();
|
||||
setmenu( "add_options" );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( menu( "add_options" ) )
|
||||
{
|
||||
if ( !entities_are_selected() )
|
||||
{
|
||||
clear_fx_hudelements();
|
||||
setmenu( "none" );
|
||||
return;
|
||||
}
|
||||
|
||||
display_fx_add_options( get_last_selected_entity() );
|
||||
|
||||
if ( button_is_clicked( "rightarrow" ) )
|
||||
increment_list_offset();
|
||||
|
||||
if ( button_is_clicked( "leftarrow" ) )
|
||||
decrement_list_offset();
|
||||
}
|
||||
else if ( menu( "jump_to_effect" ) )
|
||||
{
|
||||
if ( button_is_clicked( "rightarrow" ) )
|
||||
{
|
||||
increment_list_offset();
|
||||
draw_effects_list( "Select effect to jump to:" );
|
||||
}
|
||||
|
||||
if ( button_is_clicked( "leftarrow" ) )
|
||||
{
|
||||
decrement_list_offset();
|
||||
draw_effects_list( "Select effect to jump to:" );
|
||||
}
|
||||
|
||||
jump_to_effect();
|
||||
}
|
||||
else if ( menu( "select_by_property" ) )
|
||||
{
|
||||
menu_selection();
|
||||
|
||||
if ( button_is_clicked( "rightarrow" ) )
|
||||
increment_list_offset();
|
||||
|
||||
if ( button_is_clicked( "leftarrow" ) )
|
||||
decrement_list_offset();
|
||||
}
|
||||
else if ( menu( "change_type" ) )
|
||||
{
|
||||
if ( !entities_are_selected() )
|
||||
{
|
||||
clear_fx_hudelements();
|
||||
setmenu( "none" );
|
||||
return;
|
||||
}
|
||||
else
|
||||
menu_fx_type();
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
exit_menu()
|
||||
{
|
||||
/#
|
||||
clear_fx_hudelements();
|
||||
clear_entity_selection();
|
||||
update_selected_entities();
|
||||
setmenu( "none" );
|
||||
#/
|
||||
}
|
||||
|
||||
get_last_selected_entity()
|
||||
{
|
||||
/#
|
||||
return level.selected_fx_ents[level.selected_fx_ents.size - 1];
|
||||
#/
|
||||
}
|
||||
|
||||
menu_fx_creation()
|
||||
{
|
||||
/#
|
||||
count = 0;
|
||||
picked_fx = undefined;
|
||||
keys = get_level_ambient_fx();
|
||||
|
||||
for ( i = level.effect_list_offset; i < keys.size; i++ )
|
||||
{
|
||||
count += 1;
|
||||
button_to_check = count;
|
||||
|
||||
if ( button_to_check == 10 )
|
||||
button_to_check = 0;
|
||||
|
||||
if ( button_is_clicked( button_to_check + "" ) && !button_is_held( "f" ) )
|
||||
{
|
||||
picked_fx = keys[i];
|
||||
break;
|
||||
}
|
||||
|
||||
if ( count > level.effect_list_offset_max )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !isdefined( picked_fx ) )
|
||||
return;
|
||||
|
||||
if ( menu( "change_fxid" ) )
|
||||
{
|
||||
apply_option_to_selected_fx( get_option( "fxid" ), picked_fx );
|
||||
level.effect_list_offset = 0;
|
||||
clear_fx_hudelements();
|
||||
setmenu( "none" );
|
||||
return;
|
||||
}
|
||||
|
||||
ent = undefined;
|
||||
|
||||
if ( menu( "create_loopfx" ) )
|
||||
ent = createloopeffect( picked_fx );
|
||||
|
||||
if ( menu( "create_oneshot" ) )
|
||||
{
|
||||
ent = createoneshoteffect( picked_fx );
|
||||
delay_min = getdvarint( "createfx_oneshot_min_delay" );
|
||||
delay_max = getdvarint( "createfx_oneshot_max_delay" );
|
||||
|
||||
if ( delay_min > delay_max )
|
||||
{
|
||||
temp = delay_min;
|
||||
delay_min = delay_max;
|
||||
delay_max = temp;
|
||||
}
|
||||
|
||||
ent.v["delay"] = randomintrange( delay_min, delay_max );
|
||||
}
|
||||
|
||||
if ( menu( "create_exploder" ) )
|
||||
ent = createexploder( picked_fx );
|
||||
|
||||
finish_creating_entity( ent );
|
||||
|
||||
if ( level.cfx_last_action != "none" )
|
||||
store_undo_state( "edit", level.selected_fx_ents );
|
||||
|
||||
store_undo_state( "add", level.createfxent[level.createfxent.size - 1] );
|
||||
level.cfx_last_action = "none";
|
||||
setmenu( "none" );
|
||||
#/
|
||||
}
|
||||
|
||||
finish_creating_entity( ent )
|
||||
{
|
||||
/#
|
||||
ent.v["angles"] = vectortoangles( ent.v["origin"] + vectorscale( ( 0, 0, 1 ), 100.0 ) - ent.v["origin"] );
|
||||
assert( isdefined( ent ) );
|
||||
ent post_entity_creation_function();
|
||||
clear_entity_selection();
|
||||
select_last_entity( "skip_undo" );
|
||||
move_selection_to_cursor( "skip_undo" );
|
||||
update_selected_entities();
|
||||
#/
|
||||
}
|
||||
|
||||
change_effect_to_oneshot( ent )
|
||||
{
|
||||
/#
|
||||
if ( ent.v["type"] == "oneshotfx" )
|
||||
return;
|
||||
|
||||
if ( ent.v["type"] == "exploder" )
|
||||
{
|
||||
ent.v["exploder"] = undefined;
|
||||
ent.v["exploder_type"] = undefined;
|
||||
ent.v["soundalias"] = undefined;
|
||||
}
|
||||
|
||||
if ( !isdefined( ent.v["delay"] ) || ent.v["delay"] == 0 )
|
||||
{
|
||||
delay_min = getdvarint( "createfx_oneshot_min_delay" );
|
||||
delay_max = getdvarint( "createfx_oneshot_max_delay" );
|
||||
|
||||
if ( delay_min > delay_max )
|
||||
{
|
||||
temp = delay_min;
|
||||
delay_min = delay_max;
|
||||
delay_max = temp;
|
||||
}
|
||||
|
||||
ent.v["delay"] = randomintrange( delay_min, delay_max );
|
||||
}
|
||||
|
||||
ent.v["type"] = "oneshotfx";
|
||||
#/
|
||||
}
|
||||
|
||||
change_effect_to_loop( ent )
|
||||
{
|
||||
/#
|
||||
if ( ent.v["type"] == "loopfx" )
|
||||
return;
|
||||
|
||||
if ( ent.v["type"] == "exploder" )
|
||||
{
|
||||
ent.v["exploder"] = undefined;
|
||||
ent.v["exploder_type"] = undefined;
|
||||
ent.v["soundalias"] = undefined;
|
||||
}
|
||||
|
||||
if ( !isdefined( ent.v["delay"] ) || ent.v["delay"] <= 0 )
|
||||
ent.v["delay"] = 1;
|
||||
|
||||
ent.v["type"] = "loopfx";
|
||||
#/
|
||||
}
|
||||
|
||||
change_effect_to_exploder( ent )
|
||||
{
|
||||
/#
|
||||
if ( ent.v["type"] == "exploder" )
|
||||
return;
|
||||
|
||||
ent.v["type"] = "exploder";
|
||||
|
||||
if ( !isdefined( ent.v["delay"] ) || ent.v["delay"] < 0 )
|
||||
ent.v["delay"] = 0;
|
||||
|
||||
ent.v["exploder"] = 1;
|
||||
ent.v["exploder_type"] = "normal";
|
||||
#/
|
||||
}
|
||||
|
||||
change_ent_type( newtype )
|
||||
{
|
||||
/#
|
||||
store_undo_state( "edit", level.selected_fx_ents );
|
||||
level.cfx_last_action = "ent_type";
|
||||
|
||||
if ( newtype == "oneshotfx" )
|
||||
{
|
||||
for ( i = 0; i < level.selected_fx_ents.size; i++ )
|
||||
change_effect_to_oneshot( level.selected_fx_ents[i] );
|
||||
}
|
||||
else if ( newtype == "loopfx" )
|
||||
{
|
||||
for ( i = 0; i < level.selected_fx_ents.size; i++ )
|
||||
change_effect_to_loop( level.selected_fx_ents[i] );
|
||||
}
|
||||
else if ( newtype == "exploder" )
|
||||
{
|
||||
for ( i = 0; i < level.selected_fx_ents.size; i++ )
|
||||
change_effect_to_exploder( level.selected_fx_ents[i] );
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
menu_init()
|
||||
{
|
||||
/#
|
||||
level.createfx_options = [];
|
||||
addoption( "string", "type", "Type", "oneshotfx", "fx" );
|
||||
addoption( "string", "fxid", "Name", "nil", "fx" );
|
||||
addoption( "vector", "origin", "Origin", ( 0, 0, 0 ), "fx" );
|
||||
addoption( "vector", "angles", "Angles", ( 0, 0, 0 ), "fx" );
|
||||
addoption( "float", "delay", "Repeat rate/start delay", 0.5, "fx" );
|
||||
addoption( "int", "repeat", "Number of times to repeat", 5, "exploder" );
|
||||
addoption( "float", "primlightfrac", "Primary light fraction", 1.0, "fx" );
|
||||
addoption( "int", "lightoriginoffs", "Light origin offset", 64, "fx" );
|
||||
addoption( "float", "delay_min", "Minimum time between repeats", 1, "exploder" );
|
||||
addoption( "float", "delay_max", "Maximum time between repeats", 2, "exploder" );
|
||||
addoption( "float", "fire_range", "Fire damage range", 0, "fx" );
|
||||
addoption( "string", "firefx", "2nd FX id", "nil", "exploder" );
|
||||
addoption( "float", "firefxdelay", "2nd FX id repeat rate", 0.5, "exploder" );
|
||||
addoption( "float", "firefxtimeout", "2nd FX timeout", 5, "exploder" );
|
||||
addoption( "string", "firefxsound", "2nd FX soundalias", "nil", "exploder" );
|
||||
addoption( "string", "ender", "Level notify for ending 2nd FX", "nil", "exploder" );
|
||||
addoption( "string", "rumble", "Rumble", "nil", "exploder" );
|
||||
addoption( "float", "damage", "Radius damage", 150, "exploder" );
|
||||
addoption( "float", "damage_radius", "Radius of radius damage", 250, "exploder" );
|
||||
addoption( "int", "exploder", "Exploder", 1, "exploder" );
|
||||
addoption( "string", "earthquake", "Earthquake", "nil", "exploder" );
|
||||
addoption( "string", "soundalias", "Soundalias", "nil", "all" );
|
||||
addoption( "int", "stoppable", "Can be stopped from script", "1", "all" );
|
||||
level.effect_list_offset = 0;
|
||||
level.effect_list_offset_max = 9;
|
||||
level.createfxmasks = [];
|
||||
level.createfxmasks["all"] = [];
|
||||
level.createfxmasks["all"]["exploder"] = 1;
|
||||
level.createfxmasks["all"]["oneshotfx"] = 1;
|
||||
level.createfxmasks["all"]["loopfx"] = 1;
|
||||
level.createfxmasks["all"]["soundfx"] = 1;
|
||||
level.createfxmasks["fx"] = [];
|
||||
level.createfxmasks["fx"]["exploder"] = 1;
|
||||
level.createfxmasks["fx"]["oneshotfx"] = 1;
|
||||
level.createfxmasks["fx"]["loopfx"] = 1;
|
||||
level.createfxmasks["exploder"] = [];
|
||||
level.createfxmasks["exploder"]["exploder"] = 1;
|
||||
level.createfxmasks["loopfx"] = [];
|
||||
level.createfxmasks["loopfx"]["loopfx"] = 1;
|
||||
level.createfxmasks["oneshotfx"] = [];
|
||||
level.createfxmasks["oneshotfx"]["oneshotfx"] = 1;
|
||||
level.createfxmasks["soundfx"] = [];
|
||||
level.createfxmasks["soundfx"]["soundalias"] = 1;
|
||||
#/
|
||||
}
|
||||
|
||||
get_last_selected_ent()
|
||||
{
|
||||
/#
|
||||
return level.selected_fx_ents[level.selected_fx_ents.size - 1];
|
||||
#/
|
||||
}
|
||||
|
||||
entities_are_selected()
|
||||
{
|
||||
/#
|
||||
return level.selected_fx_ents.size > 0;
|
||||
#/
|
||||
}
|
||||
|
||||
menu_change_selected_fx()
|
||||
{
|
||||
/#
|
||||
if ( !level.selected_fx_ents.size )
|
||||
return;
|
||||
|
||||
count = 0;
|
||||
drawncount = 0;
|
||||
ent = get_last_selected_ent();
|
||||
|
||||
for ( i = 0; i < level.createfx_options.size; i++ )
|
||||
{
|
||||
option = level.createfx_options[i];
|
||||
|
||||
if ( !isdefined( ent.v[option["name"]] ) )
|
||||
continue;
|
||||
|
||||
count++;
|
||||
|
||||
if ( count < level.effect_list_offset )
|
||||
continue;
|
||||
|
||||
drawncount++;
|
||||
button_to_check = drawncount;
|
||||
|
||||
if ( button_to_check == 10 )
|
||||
button_to_check = 0;
|
||||
|
||||
if ( button_is_clicked( button_to_check + "" ) && !button_is_held( "f" ) )
|
||||
{
|
||||
prepare_option_for_change( option, drawncount );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( drawncount > level.effect_list_offset_max )
|
||||
break;
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
prepare_option_for_change( option, drawncount )
|
||||
{
|
||||
/#
|
||||
if ( option["name"] == "fxid" )
|
||||
{
|
||||
setmenu( "change_fxid" );
|
||||
draw_effects_list();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( option["name"] == "type" )
|
||||
{
|
||||
setmenu( "change_type" );
|
||||
return;
|
||||
}
|
||||
|
||||
level.createfx_inputlocked = 1;
|
||||
set_option_index( option["name"] );
|
||||
setdvar( "fx", "nil" );
|
||||
level.createfxhudelements[drawncount + 1][0].color = ( 1, 1, 0 );
|
||||
#/
|
||||
}
|
||||
|
||||
menu_fx_option_set()
|
||||
{
|
||||
/#
|
||||
if ( getdvar( "fx" ) == "nil" )
|
||||
return;
|
||||
|
||||
option = get_selected_option();
|
||||
setting = undefined;
|
||||
|
||||
if ( option["type"] == "string" )
|
||||
setting = getdvar( "fx" );
|
||||
|
||||
if ( option["type"] == "int" )
|
||||
setting = getdvarint( "fx" );
|
||||
|
||||
if ( option["type"] == "float" )
|
||||
setting = getdvarfloat( "fx" );
|
||||
|
||||
if ( option["type"] == "vector" )
|
||||
{
|
||||
setting = getdvar( "fx" );
|
||||
temparray = strtok( setting, " " );
|
||||
|
||||
if ( temparray.size == 3 )
|
||||
setting = ( float( temparray[0] ), float( temparray[1] ), float( temparray[2] ) );
|
||||
else
|
||||
{
|
||||
clear_settable_fx();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
apply_option_to_selected_fx( option, setting );
|
||||
#/
|
||||
}
|
||||
|
||||
menu_fx_type()
|
||||
{
|
||||
/#
|
||||
clear_fx_hudelements();
|
||||
set_fx_hudelement( "Change effect type to:" );
|
||||
set_fx_hudelement( " (1) Oneshot" );
|
||||
set_fx_hudelement( " (2) Looped" );
|
||||
set_fx_hudelement( " (3) Exploder" );
|
||||
set_fx_hudelement( "(x) Exit >" );
|
||||
|
||||
if ( button_is_clicked( "1" ) && !button_is_held( "f" ) )
|
||||
{
|
||||
change_ent_type( "oneshotfx" );
|
||||
setmenu( "none" );
|
||||
}
|
||||
else if ( button_is_clicked( "2" ) && !button_is_held( "f" ) )
|
||||
{
|
||||
change_ent_type( "loopfx" );
|
||||
setmenu( "none" );
|
||||
}
|
||||
else if ( button_is_clicked( "3" ) && !button_is_held( "f" ) )
|
||||
{
|
||||
change_ent_type( "exploder" );
|
||||
setmenu( "none" );
|
||||
}
|
||||
|
||||
if ( menu( "none" ) )
|
||||
update_selected_entities();
|
||||
#/
|
||||
}
|
||||
|
||||
menu_selection()
|
||||
{
|
||||
/#
|
||||
clear_fx_hudelements();
|
||||
set_fx_hudelement( "Select all by property:" );
|
||||
drawncount = 0;
|
||||
option_number = 0;
|
||||
ent = level.selected_fx_ents[level.selected_fx_ents.size - 1];
|
||||
|
||||
if ( level.selected_fx_ents.size < 1 )
|
||||
set_fx_hudelement( "No ent is selected." );
|
||||
else
|
||||
{
|
||||
for ( i = level.effect_list_offset; i < level.createfx_options.size; i++ )
|
||||
{
|
||||
if ( drawncount > level.effect_list_offset_max )
|
||||
break;
|
||||
|
||||
if ( drawncount > ent.v.size )
|
||||
break;
|
||||
|
||||
prop_name = level.createfx_options[i]["name"];
|
||||
option_number = drawncount + 1;
|
||||
|
||||
if ( isdefined( ent.v[prop_name] ) )
|
||||
{
|
||||
if ( button_is_clicked( option_number + "" ) && !button_is_held( "f" ) )
|
||||
{
|
||||
level.cfx_selected_prop = prop_name;
|
||||
menunone();
|
||||
level.effect_list_offset = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
prop_desc = level.createfx_options[i]["description"];
|
||||
set_fx_hudelement( option_number + ". " + prop_desc + ": " + ent.v[prop_name] );
|
||||
drawncount++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( drawncount > level.effect_list_offset_max )
|
||||
{
|
||||
pages = ceil( ent.v.size / level.effect_list_offset_max );
|
||||
current_page = level.effect_list_offset / level.effect_list_offset_max + 1;
|
||||
set_fx_hudelement( "(<-) Page " + current_page + " of " + pages + " (->)" );
|
||||
}
|
||||
|
||||
set_fx_hudelement( "(x) Exit >" );
|
||||
#/
|
||||
}
|
||||
|
||||
apply_option_to_selected_fx( option, setting )
|
||||
{
|
||||
/#
|
||||
if ( level.cfx_last_action != option["name"] )
|
||||
{
|
||||
store_undo_state( "edit", level.selected_fx_ents );
|
||||
level.cfx_last_action = option["name"];
|
||||
}
|
||||
|
||||
for ( i = 0; i < level.selected_fx_ents.size; i++ )
|
||||
{
|
||||
ent = level.selected_fx_ents[i];
|
||||
|
||||
if ( mask( option["mask"], ent.v["type"] ) )
|
||||
ent.v[option["name"]] = setting;
|
||||
}
|
||||
|
||||
update_selected_entities();
|
||||
clear_settable_fx();
|
||||
#/
|
||||
}
|
||||
|
||||
set_option_index( name )
|
||||
{
|
||||
/#
|
||||
for ( i = 0; i < level.createfx_options.size; i++ )
|
||||
{
|
||||
if ( level.createfx_options[i]["name"] != name )
|
||||
continue;
|
||||
|
||||
level.selected_fx_option_index = i;
|
||||
return;
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
get_selected_option()
|
||||
{
|
||||
/#
|
||||
return level.createfx_options[level.selected_fx_option_index];
|
||||
#/
|
||||
}
|
||||
|
||||
mask( type, name )
|
||||
{
|
||||
/#
|
||||
return isdefined( level.createfxmasks[type][name] );
|
||||
#/
|
||||
}
|
||||
|
||||
addoption( type, name, description, defaultsetting, mask )
|
||||
{
|
||||
/#
|
||||
option = [];
|
||||
option["type"] = type;
|
||||
option["name"] = name;
|
||||
option["description"] = description;
|
||||
option["default"] = defaultsetting;
|
||||
option["mask"] = mask;
|
||||
level.createfx_options[level.createfx_options.size] = option;
|
||||
#/
|
||||
}
|
||||
|
||||
get_option( name )
|
||||
{
|
||||
/#
|
||||
for ( i = 0; i < level.createfx_options.size; i++ )
|
||||
{
|
||||
if ( level.createfx_options[i]["name"] == name )
|
||||
return level.createfx_options[i];
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
display_fx_info( ent )
|
||||
{
|
||||
/#
|
||||
if ( !menu( "none" ) )
|
||||
return;
|
||||
|
||||
clear_fx_hudelements();
|
||||
|
||||
if ( !level.createfx_draw_enabled )
|
||||
return;
|
||||
|
||||
set_fx_hudelement( "Selected: " + level.selected_fx_ents.size + " Distance: " + get_distance_from_ent( ent ) );
|
||||
level.createfxhudelements[0][0].color = ( 1, 1, 0 );
|
||||
set_fx_hudelement( "Name: " + ent.v["fxid"] );
|
||||
|
||||
if ( entities_are_selected() )
|
||||
{
|
||||
count = 0;
|
||||
drawncount = 0;
|
||||
|
||||
for ( i = 0; i < level.createfx_options.size; i++ )
|
||||
{
|
||||
option = level.createfx_options[i];
|
||||
|
||||
if ( !isdefined( ent.v[option["name"]] ) )
|
||||
continue;
|
||||
|
||||
count++;
|
||||
|
||||
if ( count < level.effect_list_offset )
|
||||
continue;
|
||||
|
||||
drawncount++;
|
||||
set_fx_hudelement( drawncount + ". " + option["description"] + ": " + ent.v[option["name"]] );
|
||||
|
||||
if ( drawncount > level.effect_list_offset_max )
|
||||
{
|
||||
more = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( count > level.effect_list_offset_max )
|
||||
{
|
||||
pages = ceil( level.createfx_options.size / level.effect_list_offset_max );
|
||||
current_page = level.effect_list_offset / level.effect_list_offset_max + 1;
|
||||
set_fx_hudelement( "(<-) Page " + current_page + " of " + pages + " (->)" );
|
||||
}
|
||||
|
||||
set_fx_hudelement( "(a) Add >" );
|
||||
set_fx_hudelement( "(x) Exit >" );
|
||||
}
|
||||
else
|
||||
{
|
||||
set_fx_hudelement( "Origin: " + ent.v["origin"] );
|
||||
set_fx_hudelement( "Angles: " + ent.v["angles"] );
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
display_fx_add_options( ent )
|
||||
{
|
||||
/#
|
||||
assert( menu( "add_options" ) );
|
||||
assert( entities_are_selected() );
|
||||
clear_fx_hudelements();
|
||||
set_fx_hudelement( "Selected: " + level.selected_fx_ents.size + " Distance: " + get_distance_from_ent( ent ) );
|
||||
level.createfxhudelements[0][0].color = ( 1, 1, 0 );
|
||||
set_fx_hudelement( "Name: " + ent.v["fxid"] );
|
||||
set_fx_hudelement( "Origin: " + ent.v["origin"] );
|
||||
set_fx_hudelement( "Angles: " + ent.v["angles"] );
|
||||
count = 0;
|
||||
drawncount = 0;
|
||||
|
||||
if ( level.effect_list_offset >= level.createfx_options.size )
|
||||
level.effect_list_offset = 0;
|
||||
|
||||
for ( i = 0; i < level.createfx_options.size; i++ )
|
||||
{
|
||||
option = level.createfx_options[i];
|
||||
|
||||
if ( isdefined( ent.v[option["name"]] ) )
|
||||
continue;
|
||||
|
||||
if ( !mask( option["mask"], ent.v["type"] ) )
|
||||
continue;
|
||||
|
||||
count++;
|
||||
|
||||
if ( count < level.effect_list_offset )
|
||||
continue;
|
||||
|
||||
if ( drawncount >= level.effect_list_offset_max )
|
||||
continue;
|
||||
|
||||
drawncount++;
|
||||
button_to_check = drawncount;
|
||||
|
||||
if ( button_to_check == 10 )
|
||||
button_to_check = 0;
|
||||
|
||||
if ( button_is_clicked( button_to_check + "" ) && !button_is_held( "f" ) )
|
||||
{
|
||||
add_option_to_selected_entities( option );
|
||||
menunone();
|
||||
return;
|
||||
}
|
||||
|
||||
set_fx_hudelement( button_to_check + ". " + option["description"] );
|
||||
}
|
||||
|
||||
if ( count > level.effect_list_offset_max )
|
||||
{
|
||||
pages = ceil( level.createfx_options.size / level.effect_list_offset_max );
|
||||
current_page = level.effect_list_offset / level.effect_list_offset_max + 1;
|
||||
set_fx_hudelement( "(<-) Page " + current_page + " of " + pages + " (->)" );
|
||||
}
|
||||
|
||||
set_fx_hudelement( "(x) Exit >" );
|
||||
#/
|
||||
}
|
||||
|
||||
add_option_to_selected_entities( option )
|
||||
{
|
||||
/#
|
||||
for ( i = 0; i < level.selected_fx_ents.size; i++ )
|
||||
{
|
||||
ent = level.selected_fx_ents[i];
|
||||
|
||||
if ( mask( option["mask"], ent.v["type"] ) )
|
||||
ent.v[option["name"]] = option["default"];
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
menunone()
|
||||
{
|
||||
/#
|
||||
level.effect_list_offset = 0;
|
||||
clear_fx_hudelements();
|
||||
setmenu( "none" );
|
||||
#/
|
||||
}
|
||||
|
||||
draw_effects_list( title )
|
||||
{
|
||||
/#
|
||||
clear_fx_hudelements();
|
||||
|
||||
if ( !isdefined( title ) )
|
||||
title = "Pick an effect:";
|
||||
|
||||
set_fx_hudelement( title );
|
||||
count = 0;
|
||||
more = 0;
|
||||
keys = get_level_ambient_fx();
|
||||
|
||||
if ( level.effect_list_offset >= keys.size )
|
||||
level.effect_list_offset = 0;
|
||||
else if ( level.effect_list_offset < 0 )
|
||||
level.effect_list_offset = int( floor( keys.size / level.effect_list_offset_max ) * level.effect_list_offset_max );
|
||||
|
||||
for ( i = level.effect_list_offset; i < keys.size; i++ )
|
||||
{
|
||||
count += 1;
|
||||
set_fx_hudelement( count + ". " + keys[i] );
|
||||
|
||||
if ( count >= level.effect_list_offset_max )
|
||||
{
|
||||
more = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( keys.size > level.effect_list_offset_max )
|
||||
{
|
||||
pages = ceil( keys.size / level.effect_list_offset_max );
|
||||
current_page = level.effect_list_offset / level.effect_list_offset_max + 1;
|
||||
set_fx_hudelement( "(<-) Page " + current_page + " of " + pages + " (->)" );
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
increment_list_offset()
|
||||
{
|
||||
/#
|
||||
level.effect_list_offset += level.effect_list_offset_max;
|
||||
#/
|
||||
}
|
||||
|
||||
decrement_list_offset()
|
||||
{
|
||||
/#
|
||||
level.effect_list_offset -= level.effect_list_offset_max;
|
||||
#/
|
||||
}
|
||||
|
||||
jump_to_effect()
|
||||
{
|
||||
/#
|
||||
count = 0;
|
||||
picked_fxid = undefined;
|
||||
keys = get_level_ambient_fx();
|
||||
|
||||
for ( i = level.effect_list_offset; i < keys.size; i++ )
|
||||
{
|
||||
count += 1;
|
||||
button_to_check = count;
|
||||
|
||||
if ( button_to_check == 10 )
|
||||
button_to_check = 0;
|
||||
|
||||
if ( button_is_clicked( button_to_check + "" ) && !button_is_held( "f" ) )
|
||||
{
|
||||
picked_fxid = keys[i];
|
||||
break;
|
||||
}
|
||||
|
||||
if ( count > level.effect_list_offset_max )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !isdefined( picked_fxid ) )
|
||||
return;
|
||||
|
||||
clear_entity_selection();
|
||||
ent = get_next_ent_with_same_id( -1, picked_fxid );
|
||||
|
||||
if ( isdefined( ent ) )
|
||||
{
|
||||
level.cfx_next_ent = ent;
|
||||
move_player_to_next_same_effect( 1 );
|
||||
}
|
||||
else
|
||||
iprintln( "Effect " + picked_fxid + " has not been placed." );
|
||||
|
||||
level.effect_list_offset = 0;
|
||||
clear_fx_hudelements();
|
||||
setmenu( "none" );
|
||||
#/
|
||||
}
|
||||
|
||||
get_level_ambient_fx()
|
||||
{
|
||||
/#
|
||||
if ( !isdefined( level._effect_keys ) )
|
||||
{
|
||||
keys = getarraykeys( level._effect );
|
||||
level._effect_keys = [];
|
||||
k = 0;
|
||||
|
||||
for ( i = 0; i < keys.size; i++ )
|
||||
{
|
||||
if ( issubstr( keys[i], "fx_" ) )
|
||||
{
|
||||
level._effect_keys[k] = keys[i];
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( level._effect_keys.size == 0 )
|
||||
level._effect_keys = keys;
|
||||
}
|
||||
|
||||
return level._effect_keys;
|
||||
#/
|
||||
}
|
||||
|
||||
get_distance_from_ent( ent )
|
||||
{
|
||||
/#
|
||||
player = get_players()[0];
|
||||
return distance( player geteye(), ent.v["origin"] );
|
||||
#/
|
||||
}
|
508
MP/Core/maps/mp/_createfxundo.gsc
Normal file
508
MP/Core/maps/mp/_createfxundo.gsc
Normal file
@ -0,0 +1,508 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\_createfx;
|
||||
#include maps\mp\_createfxmenu;
|
||||
|
||||
store_undo_state( change_type, ents )
|
||||
{
|
||||
if ( !isdefined( level.cfx_undo_states ) )
|
||||
{
|
||||
level.cfx_undo_states = [];
|
||||
level.cfx_redo_states = [];
|
||||
level.cfx_limbo_state = spawnstruct();
|
||||
level.cfx_max_states = 10;
|
||||
}
|
||||
|
||||
if ( !isarray( ents ) )
|
||||
ents = array( ents );
|
||||
|
||||
temp_array = [];
|
||||
|
||||
for ( i = 0; i < ents.size; i++ )
|
||||
temp_array[i] = copy_fx_ent( ents[i] );
|
||||
|
||||
state = spawnstruct();
|
||||
state.operation = change_type;
|
||||
state.last_action = level.cfx_last_action;
|
||||
state.ent_array = temp_array;
|
||||
|
||||
if ( level.cfx_undo_states.size >= level.cfx_max_states )
|
||||
level.cfx_undo_states = array_drop( level.cfx_undo_states );
|
||||
|
||||
level.cfx_undo_states[level.cfx_undo_states.size] = state;
|
||||
level.cfx_redo_states = [];
|
||||
level.cfx_limbo_state = undefined;
|
||||
debug_print_latest_state( "undo" );
|
||||
}
|
||||
|
||||
undo()
|
||||
{
|
||||
if ( !isdefined( level.createfxent ) || !isdefined( level.cfx_undo_states ) || level.cfx_undo_states.size < 1 )
|
||||
return;
|
||||
|
||||
revert_state = level.cfx_undo_states[level.cfx_undo_states.size - 1];
|
||||
|
||||
if ( level.cfx_last_action != "none" )
|
||||
{
|
||||
store_undo_state( "edit", level.selected_fx_ents );
|
||||
move_undo_state_to_redo();
|
||||
clear_entity_selection( "skip_undo" );
|
||||
apply_state_change( "undo", revert_state );
|
||||
move_undo_state_to_limbo();
|
||||
level.cfx_last_action = "none";
|
||||
}
|
||||
else
|
||||
{
|
||||
clear_entity_selection( "skip_undo" );
|
||||
|
||||
if ( revert_state.operation != "edit" )
|
||||
{
|
||||
apply_state_change( "undo", revert_state );
|
||||
move_undo_state_to_redo();
|
||||
level.cfx_last_action = "none";
|
||||
}
|
||||
else if ( isdefined( level.cfx_limbo_state ) )
|
||||
{
|
||||
move_limbo_state_to_redo();
|
||||
apply_state_change( "undo", revert_state );
|
||||
move_undo_state_to_limbo();
|
||||
level.cfx_last_action = "none";
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( level.cfx_undo_states.size > 1 )
|
||||
{
|
||||
move_undo_state_to_redo();
|
||||
revert_state = level.cfx_undo_states[level.cfx_undo_states.size - 1];
|
||||
}
|
||||
|
||||
apply_state_change( "undo", revert_state );
|
||||
move_undo_state_to_limbo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply_state_change( type, revert_state )
|
||||
{
|
||||
if ( type == "undo" )
|
||||
{
|
||||
/#
|
||||
println( "^2CreateFX: Undo operation" );
|
||||
#/
|
||||
if ( revert_state.operation == "edit" )
|
||||
undo_edit( revert_state.ent_array );
|
||||
else if ( revert_state.operation == "add" )
|
||||
undo_add( revert_state.ent_array );
|
||||
else if ( revert_state.operation == "delete" )
|
||||
undo_delete( revert_state.ent_array );
|
||||
}
|
||||
else
|
||||
{
|
||||
/#
|
||||
println( "^2CreateFX: Redo operation" );
|
||||
#/
|
||||
if ( revert_state.operation == "edit" )
|
||||
undo_edit( revert_state.ent_array );
|
||||
else if ( revert_state.operation == "add" )
|
||||
undo_delete( revert_state.ent_array );
|
||||
else if ( revert_state.operation == "delete" )
|
||||
undo_add( revert_state.ent_array );
|
||||
}
|
||||
}
|
||||
|
||||
move_undo_state_to_redo()
|
||||
{
|
||||
if ( level.cfx_redo_states.size >= level.cfx_max_states )
|
||||
level.cfx_redo_states = array_drop( level.cfx_redo_states );
|
||||
|
||||
level.cfx_redo_states[level.cfx_redo_states.size] = level.cfx_undo_states[level.cfx_undo_states.size - 1];
|
||||
level.cfx_undo_states = array_pop( level.cfx_undo_states );
|
||||
debug_print_latest_state( "undo" );
|
||||
debug_print_latest_state( "redo" );
|
||||
}
|
||||
|
||||
move_redo_state_to_undo()
|
||||
{
|
||||
if ( level.cfx_undo_states.size >= level.cfx_max_states )
|
||||
level.cfx_undo_states = array_drop( level.cfx_undo_states );
|
||||
|
||||
level.cfx_undo_states[level.cfx_undo_states.size] = level.cfx_redo_states[level.cfx_redo_states.size - 1];
|
||||
level.cfx_redo_states = array_pop( level.cfx_redo_states );
|
||||
debug_print_latest_state( "undo" );
|
||||
debug_print_latest_state( "redo" );
|
||||
}
|
||||
|
||||
move_undo_state_to_limbo()
|
||||
{
|
||||
level.cfx_limbo_state = level.cfx_undo_states[level.cfx_undo_states.size - 1];
|
||||
level.cfx_undo_states = array_pop( level.cfx_undo_states );
|
||||
debug_print_latest_state( "undo" );
|
||||
debug_print_latest_state( "limbo" );
|
||||
}
|
||||
|
||||
move_redo_state_to_limbo()
|
||||
{
|
||||
level.cfx_limbo_state = level.cfx_redo_states[level.cfx_redo_states.size - 1];
|
||||
level.cfx_redo_states = array_pop( level.cfx_redo_states );
|
||||
debug_print_latest_state( "redo" );
|
||||
debug_print_latest_state( "limbo" );
|
||||
}
|
||||
|
||||
move_limbo_state_to_undo()
|
||||
{
|
||||
if ( level.cfx_undo_states.size >= level.cfx_max_states )
|
||||
level.cfx_undo_states = array_drop( level.cfx_undo_states );
|
||||
|
||||
level.cfx_undo_states[level.cfx_undo_states.size] = level.cfx_limbo_state;
|
||||
level.cfx_limbo_state = undefined;
|
||||
debug_print_latest_state( "undo" );
|
||||
debug_print_latest_state( "limbo" );
|
||||
}
|
||||
|
||||
move_limbo_state_to_redo()
|
||||
{
|
||||
if ( level.cfx_redo_states.size >= level.cfx_max_states )
|
||||
level.cfx_redo_states = array_drop( level.cfx_redo_states );
|
||||
|
||||
level.cfx_redo_states[level.cfx_redo_states.size] = level.cfx_limbo_state;
|
||||
level.cfx_limbo_state = undefined;
|
||||
debug_print_latest_state( "redo" );
|
||||
}
|
||||
|
||||
undo_edit( ent_array )
|
||||
{
|
||||
ent_array = reorder_ent_array_by_uniqueid( ent_array );
|
||||
/#
|
||||
println( "^3CreateFX: Undoing edit" );
|
||||
debug_print_ent_array( ent_array, "ent_array[]" );
|
||||
debug_print_ent_array( level.createfxent, "level.createFXent[]" );
|
||||
#/
|
||||
last_id = ent_array[ent_array.size - 1].uniqueid;
|
||||
|
||||
if ( last_id > level.createfxent.size - 1 )
|
||||
last_id = level.createfxent.size - 1;
|
||||
|
||||
j = ent_array.size - 1;
|
||||
source_ent = ent_array[j];
|
||||
|
||||
for ( i = last_id; i >= 0; i-- )
|
||||
{
|
||||
target_ent = level.createfxent[i];
|
||||
|
||||
if ( source_ent.uniqueid == target_ent.uniqueid )
|
||||
{
|
||||
copy_values_between_fx_ents( source_ent, target_ent );
|
||||
select_entity( i, target_ent, "skip_undo" );
|
||||
j--;
|
||||
|
||||
if ( j < 0 )
|
||||
break;
|
||||
|
||||
source_ent = ent_array[j];
|
||||
}
|
||||
}
|
||||
|
||||
update_selected_entities();
|
||||
/#
|
||||
println( "^1CreateFX: Finished edit" );
|
||||
debug_print_ent_array( level.createfxent, "level.createFXent[]" );
|
||||
#/
|
||||
}
|
||||
|
||||
undo_add( ent_array )
|
||||
{
|
||||
ent_array = reorder_ent_array_by_uniqueid( ent_array );
|
||||
/#
|
||||
println( "^3createfx: Undoing add." );
|
||||
debug_print_ent_array( ent_array, "ent_array[]" );
|
||||
debug_print_ent_array( level.createfxent, "level.createFXent[]" );
|
||||
#/
|
||||
last_id = ent_array[ent_array.size - 1].uniqueid;
|
||||
|
||||
if ( last_id > level.createfxent.size - 1 )
|
||||
last_id = level.createfxent.size - 1;
|
||||
|
||||
j = ent_array.size - 1;
|
||||
source_ent = ent_array[j];
|
||||
|
||||
for ( i = last_id; i >= 0; i-- )
|
||||
{
|
||||
target_ent = level.createfxent[i];
|
||||
|
||||
if ( source_ent.uniqueid == target_ent.uniqueid )
|
||||
{
|
||||
if ( isdefined( target_ent.looper ) )
|
||||
target_ent.looper delete();
|
||||
|
||||
target_ent notify( "stop_loop" );
|
||||
level.createfxent[i] = undefined;
|
||||
j--;
|
||||
|
||||
if ( j < 0 )
|
||||
break;
|
||||
|
||||
source_ent = ent_array[j];
|
||||
}
|
||||
}
|
||||
/#
|
||||
debug_print_ent_array( level.createfxent, "level.createFXent[]" );
|
||||
println( "createfx: Starting array_remove_undefined()" );
|
||||
#/
|
||||
arrayremovevalue( level.createfxent, undefined );
|
||||
/#
|
||||
println( "^1CreateFX: Finished undo add." );
|
||||
debug_print_ent_array( level.createfxent, "level.createFXent[]" );
|
||||
#/
|
||||
clear_fx_hudelements();
|
||||
}
|
||||
|
||||
undo_delete( ent_array )
|
||||
{
|
||||
/#
|
||||
println( "^3CreateFX: Undoing delete" );
|
||||
debug_print_ent_array( ent_array, "ent_array in undo_delete()" );
|
||||
debug_print_ent_array( level.createfxent, "level.createFXent[]" );
|
||||
#/
|
||||
ent_array = reorder_ent_array_by_uniqueid( ent_array );
|
||||
|
||||
if ( level.createfxent.size == 0 )
|
||||
{
|
||||
for ( i = 0; i < ent_array.size; i++ )
|
||||
level.createfxent[i] = copy_fx_ent( ent_array[i] );
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_array = [];
|
||||
i = 0;
|
||||
|
||||
for ( j = 0; j < level.createfxent.size; j++ )
|
||||
{
|
||||
target_ent = level.createfxent[j];
|
||||
|
||||
if ( i >= ent_array.size )
|
||||
{
|
||||
temp_array[temp_array.size] = target_ent;
|
||||
continue;
|
||||
}
|
||||
|
||||
source_ent = ent_array[i];
|
||||
|
||||
if ( target_ent.uniqueid < source_ent.uniqueid )
|
||||
{
|
||||
temp_array[temp_array.size] = target_ent;
|
||||
continue;
|
||||
}
|
||||
|
||||
temp_array[temp_array.size] = copy_fx_ent( source_ent );
|
||||
j--;
|
||||
i++;
|
||||
}
|
||||
|
||||
while ( i < ent_array.size )
|
||||
{
|
||||
temp_array[temp_array.size] = ent_array[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
level.createfxent = temp_array;
|
||||
}
|
||||
/#
|
||||
println( "^1Createfx: Finished undoing delete, pre-selection" );
|
||||
debug_print_ent_array( level.createfxent, "level.createFXent[]" );
|
||||
#/
|
||||
last_id = ent_array[ent_array.size - 1].uniqueid;
|
||||
|
||||
if ( last_id > level.createfxent.size - 1 )
|
||||
last_id = level.createfxent.size - 1;
|
||||
|
||||
j = ent_array.size - 1;
|
||||
source_ent = ent_array[j];
|
||||
|
||||
for ( i = last_id; i >= 0; i-- )
|
||||
{
|
||||
target_ent = level.createfxent[i];
|
||||
|
||||
if ( source_ent.uniqueid == target_ent.uniqueid )
|
||||
{
|
||||
target_ent post_entity_creation_function();
|
||||
select_entity( i, target_ent, "skip_undo" );
|
||||
j--;
|
||||
|
||||
if ( j < 0 )
|
||||
break;
|
||||
|
||||
source_ent = ent_array[j];
|
||||
}
|
||||
}
|
||||
|
||||
update_selected_entities();
|
||||
}
|
||||
|
||||
redo()
|
||||
{
|
||||
if ( !isdefined( level.createfxent ) || !isdefined( level.cfx_redo_states ) || level.cfx_redo_states.size < 1 )
|
||||
return;
|
||||
|
||||
clear_entity_selection( "skip_undo" );
|
||||
|
||||
if ( isdefined( level.cfx_limbo_state ) )
|
||||
{
|
||||
move_limbo_state_to_undo();
|
||||
move_redo_state_to_limbo();
|
||||
apply_state_change( "redo", level.cfx_limbo_state );
|
||||
}
|
||||
else
|
||||
{
|
||||
revert_state = level.cfx_redo_states[level.cfx_redo_states.size - 1];
|
||||
apply_state_change( "redo", revert_state );
|
||||
|
||||
if ( revert_state.operation == "edit" )
|
||||
move_redo_state_to_limbo();
|
||||
else
|
||||
move_redo_state_to_undo();
|
||||
}
|
||||
|
||||
level.cfx_last_action = "none";
|
||||
}
|
||||
|
||||
reorder_ent_array_by_uniqueid( ent_array )
|
||||
{
|
||||
if ( ent_array.size <= 1 )
|
||||
return ent_array;
|
||||
|
||||
array_size = ent_array.size;
|
||||
|
||||
for ( i = 0; i < array_size - 1; i++ )
|
||||
{
|
||||
for ( j = i + 1; j < array_size; j++ )
|
||||
{
|
||||
if ( ent_array[i].uniqueid > ent_array[j].uniqueid )
|
||||
{
|
||||
temp_ent = ent_array[i];
|
||||
ent_array[i] = ent_array[j];
|
||||
ent_array[j] = temp_ent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ent_array;
|
||||
}
|
||||
|
||||
copy_fx_ent( ent )
|
||||
{
|
||||
temp_ent = spawnstruct();
|
||||
temp_ent.drawn = ent.drawn;
|
||||
temp_ent.drawn_axis_model = ent.drawn_axis_model;
|
||||
temp_ent.last_fx_index = ent.last_fx_index;
|
||||
temp_ent.textalpha = ent.textalpha;
|
||||
temp_ent.uniqueid = ent.uniqueid;
|
||||
temp_ent.v = ent.v;
|
||||
return temp_ent;
|
||||
}
|
||||
|
||||
copy_values_between_fx_ents( source, dest )
|
||||
{
|
||||
dest.drawn = source.drawn;
|
||||
dest.drawn_axis_model = source.drawn_axis_model;
|
||||
dest.last_fx_index = source.last_fx_index;
|
||||
dest.textalpha = source.textalpha;
|
||||
dest.v = source.v;
|
||||
return dest;
|
||||
}
|
||||
|
||||
array_pop( array )
|
||||
{
|
||||
array_size = array.size - 1;
|
||||
temp_array = [];
|
||||
|
||||
if ( array_size <= 0 )
|
||||
return temp_array;
|
||||
|
||||
for ( i = 0; i < array_size; i++ )
|
||||
temp_array[i] = array[i];
|
||||
|
||||
array = temp_array;
|
||||
return array;
|
||||
}
|
||||
|
||||
array_drop( array )
|
||||
{
|
||||
if ( array.size > 0 )
|
||||
{
|
||||
temp_array = [];
|
||||
|
||||
for ( i = 1; i < array.size; i++ )
|
||||
temp_array[i - 1] = array[i];
|
||||
|
||||
array = temp_array;
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
debug_print_ent_array( array, name )
|
||||
{
|
||||
/#
|
||||
if ( isdefined( name ) )
|
||||
println( "Printing out " + name );
|
||||
else
|
||||
println( "Printing out some array" );
|
||||
|
||||
for ( i = 0; i < array.size; i++ )
|
||||
{
|
||||
if ( !isdefined( array[i] ) )
|
||||
{
|
||||
println( "" + i + ": deleted effect" );
|
||||
continue;
|
||||
}
|
||||
|
||||
println( "" + i + ": uniqueid: " + array[i].uniqueid + " fxid: " + array[i].v["fxid"] );
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
debug_print_latest_state( type )
|
||||
{
|
||||
/#
|
||||
println( "^3Saving " + type + " state" );
|
||||
|
||||
if ( type == "undo" )
|
||||
{
|
||||
if ( !isdefined( level.cfx_undo_states[level.cfx_undo_states.size - 1] ) )
|
||||
{
|
||||
println( "There are no undo states." );
|
||||
return;
|
||||
}
|
||||
|
||||
state = level.cfx_undo_states[level.cfx_undo_states.size - 1];
|
||||
size = level.cfx_undo_states.size - 1;
|
||||
}
|
||||
else if ( type == "redo" )
|
||||
{
|
||||
if ( !isdefined( level.cfx_redo_states[level.cfx_redo_states.size - 1] ) )
|
||||
{
|
||||
println( "There are no redo states." );
|
||||
return;
|
||||
}
|
||||
|
||||
state = level.cfx_redo_states[level.cfx_redo_states.size - 1];
|
||||
size = level.cfx_redo_states.size - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !isdefined( level.cfx_limbo_state ) )
|
||||
{
|
||||
println( "There is no limbo state." );
|
||||
return;
|
||||
}
|
||||
|
||||
state = level.cfx_limbo_state;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
println( "State " + size + " - " + state.operation + ": " + state.last_action );
|
||||
debug_print_ent_array( state.ent_array, "save state ent_array" );
|
||||
#/
|
||||
}
|
356
MP/Core/maps/mp/_decoy.gsc
Normal file
356
MP/Core/maps/mp/_decoy.gsc
Normal file
@ -0,0 +1,356 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_weaponobjects;
|
||||
#include maps\mp\_entityheadicons;
|
||||
|
||||
init()
|
||||
{
|
||||
level.decoyweapons = [];
|
||||
level.decoyweapons["fullauto"] = [];
|
||||
level.decoyweapons["semiauto"] = [];
|
||||
level.decoyweapons["fullauto"][level.decoyweapons["fullauto"].size] = "uzi_mp";
|
||||
level.decoyweapons["semiauto"][level.decoyweapons["semiauto"].size] = "m1911_mp";
|
||||
level.decoyweapons["semiauto"][level.decoyweapons["semiauto"].size] = "python_mp";
|
||||
level.decoyweapons["semiauto"][level.decoyweapons["semiauto"].size] = "cz75_mp";
|
||||
level.decoyweapons["semiauto"][level.decoyweapons["semiauto"].size] = "fnfal_mp";
|
||||
}
|
||||
|
||||
createdecoywatcher()
|
||||
{
|
||||
watcher = self maps\mp\gametypes\_weaponobjects::createuseweaponobjectwatcher( "nightingale", "nightingale_mp", self.team );
|
||||
watcher.onspawn = ::onspawndecoy;
|
||||
watcher.detonate = ::decoydetonate;
|
||||
watcher.deleteondifferentobjectspawn = 0;
|
||||
watcher.headicon = 0;
|
||||
}
|
||||
|
||||
onspawndecoy( watcher, owner )
|
||||
{
|
||||
owner endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
maps\mp\gametypes\_weaponobjects::onspawnuseweaponobject( watcher, owner );
|
||||
self.initial_velocity = self getvelocity();
|
||||
delay = 1;
|
||||
wait( delay );
|
||||
decoy_time = 30;
|
||||
spawn_time = gettime();
|
||||
owner addweaponstat( "nightingale_mp", "used", 1 );
|
||||
self thread simulateweaponfire( owner );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
if ( gettime() > spawn_time + decoy_time * 1000 )
|
||||
{
|
||||
self destroydecoy( watcher, owner );
|
||||
return;
|
||||
}
|
||||
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
movedecoy( owner, count, fire_time, main_dir, max_offset_angle )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "done" );
|
||||
|
||||
if ( !self isonground() )
|
||||
return;
|
||||
|
||||
min_speed = 100;
|
||||
max_speed = 200;
|
||||
min_up_speed = 100;
|
||||
max_up_speed = 200;
|
||||
current_main_dir = randomintrange( main_dir - max_offset_angle, main_dir + max_offset_angle );
|
||||
avel = ( randomfloatrange( 800, 1800 ) * ( randomintrange( 0, 2 ) * 2 - 1 ), 0, randomfloatrange( 580, 940 ) * ( randomintrange( 0, 2 ) * 2 - 1 ) );
|
||||
intial_up = randomfloatrange( min_up_speed, max_up_speed );
|
||||
start_time = gettime();
|
||||
gravity = getdvarint( "bg_gravity" );
|
||||
|
||||
for ( i = 0; i < 1; i++ )
|
||||
{
|
||||
angles = ( 0, randomintrange( current_main_dir - max_offset_angle, current_main_dir + max_offset_angle ), 0 );
|
||||
dir = anglestoforward( angles );
|
||||
dir = vectorscale( dir, randomfloatrange( min_speed, max_speed ) );
|
||||
deltatime = ( gettime() - start_time ) * 0.001;
|
||||
up = ( 0, 0, intial_up - 800 * deltatime );
|
||||
self launch( dir + up, avel );
|
||||
wait( fire_time );
|
||||
}
|
||||
}
|
||||
|
||||
destroydecoy( watcher, owner )
|
||||
{
|
||||
self notify( "done" );
|
||||
self maps\mp\_entityheadicons::setentityheadicon( "none" );
|
||||
}
|
||||
|
||||
decoydetonate( attacker )
|
||||
{
|
||||
self notify( "done" );
|
||||
self maps\mp\_entityheadicons::setentityheadicon( "none" );
|
||||
}
|
||||
|
||||
getweaponfordecoy( owner )
|
||||
{
|
||||
weapon = pickrandomweapon();
|
||||
return weapon;
|
||||
}
|
||||
|
||||
simulateweaponfire( owner )
|
||||
{
|
||||
owner endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self endon( "done" );
|
||||
weapon = getweaponfordecoy( owner );
|
||||
|
||||
if ( weapon == "none" )
|
||||
return;
|
||||
|
||||
self thread watchforexplosion( owner, weapon );
|
||||
self thread trackmaindirection();
|
||||
self.max_offset_angle = 30;
|
||||
weapon_class = getweaponclass( weapon );
|
||||
|
||||
switch ( weapon_class )
|
||||
{
|
||||
case "weapon_smg":
|
||||
case "weapon_lmg":
|
||||
case "weapon_hmg":
|
||||
case "weapon_cqb":
|
||||
case "weapon_assault":
|
||||
simulateweaponfiremachinegun( owner, weapon );
|
||||
break;
|
||||
case "weapon_sniper":
|
||||
simulateweaponfiresniper( owner, weapon );
|
||||
break;
|
||||
case "weapon_pistol":
|
||||
simulateweaponfirepistol( owner, weapon );
|
||||
break;
|
||||
case "weapon_shotgun":
|
||||
simulateweaponfireshotgun( owner, weapon );
|
||||
break;
|
||||
default:
|
||||
simulateweaponfiremachinegun( owner, weapon );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
simulateweaponfiremachinegun( owner, weapon )
|
||||
{
|
||||
if ( weaponissemiauto( weapon ) )
|
||||
simulateweaponfiremachinegunsemiauto( owner, weapon );
|
||||
else
|
||||
simulateweaponfiremachinegunfullauto( owner, weapon );
|
||||
}
|
||||
|
||||
simulateweaponfiremachinegunsemiauto( owner, weapon )
|
||||
{
|
||||
firetime = weaponfiretime( weapon );
|
||||
clipsize = weaponclipsize( weapon );
|
||||
reloadtime = weaponreloadtime( weapon );
|
||||
burst_spacing_min = 4;
|
||||
burst_spacing_max = 10;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
if ( clipsize <= 1 )
|
||||
burst_count = 1;
|
||||
else
|
||||
burst_count = randomintrange( 1, clipsize );
|
||||
|
||||
self thread movedecoy( owner, burst_count, firetime, self.main_dir, self.max_offset_angle );
|
||||
self fireburst( owner, weapon, firetime, burst_count, 1 );
|
||||
finishwhileloop( weapon, reloadtime, burst_spacing_min, burst_spacing_max );
|
||||
}
|
||||
}
|
||||
|
||||
simulateweaponfirepistol( owner, weapon )
|
||||
{
|
||||
firetime = weaponfiretime( weapon );
|
||||
clipsize = weaponclipsize( weapon );
|
||||
reloadtime = weaponreloadtime( weapon );
|
||||
burst_spacing_min = 0.5;
|
||||
burst_spacing_max = 4;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
burst_count = randomintrange( 1, clipsize );
|
||||
self thread movedecoy( owner, burst_count, firetime, self.main_dir, self.max_offset_angle );
|
||||
self fireburst( owner, weapon, firetime, burst_count, 0 );
|
||||
finishwhileloop( weapon, reloadtime, burst_spacing_min, burst_spacing_max );
|
||||
}
|
||||
}
|
||||
|
||||
simulateweaponfireshotgun( owner, weapon )
|
||||
{
|
||||
firetime = weaponfiretime( weapon );
|
||||
clipsize = weaponclipsize( weapon );
|
||||
reloadtime = weaponreloadtime( weapon );
|
||||
|
||||
if ( clipsize > 2 )
|
||||
clipsize = 2;
|
||||
|
||||
burst_spacing_min = 0.5;
|
||||
burst_spacing_max = 4;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
burst_count = randomintrange( 1, clipsize );
|
||||
self thread movedecoy( owner, burst_count, firetime, self.main_dir, self.max_offset_angle );
|
||||
self fireburst( owner, weapon, firetime, burst_count, 0 );
|
||||
finishwhileloop( weapon, reloadtime, burst_spacing_min, burst_spacing_max );
|
||||
}
|
||||
}
|
||||
|
||||
simulateweaponfiremachinegunfullauto( owner, weapon )
|
||||
{
|
||||
firetime = weaponfiretime( weapon );
|
||||
clipsize = weaponclipsize( weapon );
|
||||
reloadtime = weaponreloadtime( weapon );
|
||||
|
||||
if ( clipsize > 30 )
|
||||
clipsize = 30;
|
||||
|
||||
burst_spacing_min = 2;
|
||||
burst_spacing_max = 6;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
burst_count = randomintrange( int( clipsize * 0.6 ), clipsize );
|
||||
interrupt = 0;
|
||||
self thread movedecoy( owner, burst_count, firetime, self.main_dir, self.max_offset_angle );
|
||||
self fireburst( owner, weapon, firetime, burst_count, interrupt );
|
||||
finishwhileloop( weapon, reloadtime, burst_spacing_min, burst_spacing_max );
|
||||
}
|
||||
}
|
||||
|
||||
simulateweaponfiresniper( owner, weapon )
|
||||
{
|
||||
firetime = weaponfiretime( weapon );
|
||||
clipsize = weaponclipsize( weapon );
|
||||
reloadtime = weaponreloadtime( weapon );
|
||||
|
||||
if ( clipsize > 2 )
|
||||
clipsize = 2;
|
||||
|
||||
burst_spacing_min = 3;
|
||||
burst_spacing_max = 5;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
burst_count = randomintrange( 1, clipsize );
|
||||
self thread movedecoy( owner, burst_count, firetime, self.main_dir, self.max_offset_angle );
|
||||
self fireburst( owner, weapon, firetime, burst_count, 0 );
|
||||
finishwhileloop( weapon, reloadtime, burst_spacing_min, burst_spacing_max );
|
||||
}
|
||||
}
|
||||
|
||||
fireburst( owner, weapon, firetime, count, interrupt )
|
||||
{
|
||||
interrupt_shot = count;
|
||||
|
||||
if ( interrupt )
|
||||
interrupt_shot = int( count * randomfloatrange( 0.6, 0.8 ) );
|
||||
|
||||
self fakefire( owner, self.origin, weapon, interrupt_shot );
|
||||
wait( firetime * interrupt_shot );
|
||||
|
||||
if ( interrupt )
|
||||
{
|
||||
self fakefire( owner, self.origin, weapon, count - interrupt_shot );
|
||||
wait( firetime * ( count - interrupt_shot ) );
|
||||
}
|
||||
}
|
||||
|
||||
finishwhileloop( weapon, reloadtime, burst_spacing_min, burst_spacing_max )
|
||||
{
|
||||
if ( shouldplayreloadsound() )
|
||||
playreloadsounds( weapon, reloadtime );
|
||||
else
|
||||
wait( randomfloatrange( burst_spacing_min, burst_spacing_max ) );
|
||||
}
|
||||
|
||||
playreloadsounds( weapon, reloadtime )
|
||||
{
|
||||
divy_it_up = ( reloadtime - 0.1 ) / 2;
|
||||
wait 0.1;
|
||||
self playsound( "fly_assault_reload_npc_mag_out" );
|
||||
wait( divy_it_up );
|
||||
self playsound( "fly_assault_reload_npc_mag_in" );
|
||||
wait( divy_it_up );
|
||||
}
|
||||
|
||||
watchforexplosion( owner, weapon )
|
||||
{
|
||||
self thread watchfordeathbeforeexplosion();
|
||||
owner endon( "disconnect" );
|
||||
self endon( "death_before_explode" );
|
||||
|
||||
self waittill( "explode", pos );
|
||||
|
||||
level thread doexplosion( owner, pos, weapon, randomintrange( 5, 10 ) );
|
||||
}
|
||||
|
||||
watchfordeathbeforeexplosion()
|
||||
{
|
||||
self waittill( "death" );
|
||||
|
||||
wait 0.1;
|
||||
self notify( "death_before_explode" );
|
||||
}
|
||||
|
||||
doexplosion( owner, pos, weapon, count )
|
||||
{
|
||||
min_offset = 100;
|
||||
max_offset = 500;
|
||||
|
||||
for ( i = 0; i < count; i++ )
|
||||
{
|
||||
wait( randomfloatrange( 0.1, 0.5 ) );
|
||||
offset = ( randomfloatrange( min_offset, max_offset ) * ( randomintrange( 0, 2 ) * 2 - 1 ), randomfloatrange( min_offset, max_offset ) * ( randomintrange( 0, 2 ) * 2 - 1 ), 0 );
|
||||
owner fakefire( owner, pos + offset, weapon, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
pickrandomweapon()
|
||||
{
|
||||
type = "fullauto";
|
||||
|
||||
if ( randomintrange( 0, 10 ) < 3 )
|
||||
type = "semiauto";
|
||||
|
||||
randomval = randomintrange( 0, level.decoyweapons[type].size );
|
||||
/#
|
||||
println( "Decoy type: " + type + " weapon: " + level.decoyweapons[type][randomval] );
|
||||
#/
|
||||
return level.decoyweapons[type][randomval];
|
||||
}
|
||||
|
||||
shouldplayreloadsound()
|
||||
{
|
||||
if ( randomintrange( 0, 5 ) == 1 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
trackmaindirection()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "done" );
|
||||
self.main_dir = int( vectortoangles( ( self.initial_velocity[0], self.initial_velocity[1], 0 ) )[1] );
|
||||
up = ( 0, 0, 1 );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self waittill( "grenade_bounce", pos, normal );
|
||||
|
||||
dot = vectordot( normal, up );
|
||||
|
||||
if ( dot < 0.5 && dot > -0.5 )
|
||||
self.main_dir = int( vectortoangles( ( normal[0], normal[1], 0 ) )[1] );
|
||||
}
|
||||
}
|
90
MP/Core/maps/mp/_demo.gsc
Normal file
90
MP/Core/maps/mp/_demo.gsc
Normal file
@ -0,0 +1,90 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
|
||||
init()
|
||||
{
|
||||
level.bookmark["kill"] = 0;
|
||||
level.bookmark["event"] = 1;
|
||||
level.bookmark["zm_round_end"] = 2;
|
||||
level.bookmark["zm_player_downed"] = 3;
|
||||
level.bookmark["zm_player_revived"] = 4;
|
||||
level.bookmark["zm_player_bledout"] = 5;
|
||||
level.bookmark["zm_player_use_magicbox"] = 6;
|
||||
level.bookmark["score_event"] = 7;
|
||||
level.bookmark["medal"] = 8;
|
||||
level.bookmark["round_result"] = 9;
|
||||
level.bookmark["game_result"] = 10;
|
||||
level.bookmark["zm_powerup_dropped"] = 11;
|
||||
level.bookmark["zm_player_powerup_grabbed"] = 12;
|
||||
level.bookmark["zm_player_perk"] = 13;
|
||||
level.bookmark["zm_power"] = 14;
|
||||
level.bookmark["zm_player_door"] = 15;
|
||||
level.bookmark["zm_player_buildable_placed"] = 16;
|
||||
level.bookmark["zm_player_use_packapunch"] = 17;
|
||||
level.bookmark["zm_player_rampage"] = 18;
|
||||
level.bookmark["zm_player_grenade_special"] = 19;
|
||||
level.bookmark["zm_player_grenade_multiattack"] = 20;
|
||||
level.bookmark["zm_player_meat_stink"] = 21;
|
||||
level.bookmark["zm_player_grabbed_magicbox"] = 22;
|
||||
level.bookmark["zm_player_grabbed_packapunch"] = 23;
|
||||
level.bookmark["zm_player_grenade_special_long"] = 24;
|
||||
}
|
||||
|
||||
bookmark( type, time, clientent1, clientent2, eventpriority, inflictorent, overrideentitycamera, actorent )
|
||||
{
|
||||
assert( isdefined( level.bookmark[type] ), "Unable to find a bookmark type for type - " + type );
|
||||
client1 = 255;
|
||||
client2 = 255;
|
||||
inflictorentnum = -1;
|
||||
inflictorenttype = 0;
|
||||
inflictorbirthtime = 0;
|
||||
actorentnum = undefined;
|
||||
scoreeventpriority = 0;
|
||||
|
||||
if ( isdefined( clientent1 ) )
|
||||
client1 = clientent1 getentitynumber();
|
||||
|
||||
if ( isdefined( clientent2 ) )
|
||||
client2 = clientent2 getentitynumber();
|
||||
|
||||
if ( isdefined( eventpriority ) )
|
||||
scoreeventpriority = eventpriority;
|
||||
|
||||
if ( isdefined( inflictorent ) )
|
||||
{
|
||||
inflictorentnum = inflictorent getentitynumber();
|
||||
inflictorenttype = inflictorent getentitytype();
|
||||
|
||||
if ( isdefined( inflictorent.birthtime ) )
|
||||
inflictorbirthtime = inflictorent.birthtime;
|
||||
}
|
||||
|
||||
if ( !isdefined( overrideentitycamera ) )
|
||||
overrideentitycamera = 0;
|
||||
|
||||
if ( isdefined( actorent ) )
|
||||
actorentnum = actorent getentitynumber();
|
||||
|
||||
adddemobookmark( level.bookmark[type], time, client1, client2, scoreeventpriority, inflictorentnum, inflictorenttype, inflictorbirthtime, overrideentitycamera, actorentnum );
|
||||
}
|
||||
|
||||
gameresultbookmark( type, winningteamindex, losingteamindex )
|
||||
{
|
||||
assert( isdefined( level.bookmark[type] ), "Unable to find a bookmark type for type - " + type );
|
||||
client1 = 255;
|
||||
client2 = 255;
|
||||
scoreeventpriority = 0;
|
||||
inflictorentnum = -1;
|
||||
inflictorenttype = 0;
|
||||
inflictorbirthtime = 0;
|
||||
overrideentitycamera = 0;
|
||||
actorentnum = undefined;
|
||||
|
||||
if ( isdefined( winningteamindex ) )
|
||||
client1 = winningteamindex;
|
||||
|
||||
if ( isdefined( losingteamindex ) )
|
||||
client2 = losingteamindex;
|
||||
|
||||
adddemobookmark( level.bookmark[type], gettime(), client1, client2, scoreeventpriority, inflictorentnum, inflictorenttype, inflictorbirthtime, overrideentitycamera, actorentnum );
|
||||
}
|
440
MP/Core/maps/mp/_destructible.gsc
Normal file
440
MP/Core/maps/mp/_destructible.gsc
Normal file
@ -0,0 +1,440 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\gametypes\_globallogic_player;
|
||||
#include maps\mp\_challenges;
|
||||
|
||||
#using_animtree("mp_vehicles");
|
||||
|
||||
init()
|
||||
{
|
||||
level.destructible_callbacks = [];
|
||||
destructibles = getentarray( "destructible", "targetname" );
|
||||
|
||||
if ( destructibles.size <= 0 )
|
||||
return;
|
||||
|
||||
precacheitem( "destructible_car_mp" );
|
||||
precacheitem( "explodable_barrel_mp" );
|
||||
|
||||
for ( i = 0; i < destructibles.size; i++ )
|
||||
{
|
||||
if ( getsubstr( destructibles[i].destructibledef, 0, 4 ) == "veh_" )
|
||||
{
|
||||
destructibles[i] thread destructible_car_death_think();
|
||||
destructibles[i] thread destructible_car_grenade_stuck_think();
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( issubstr( destructibles[i].destructibledef, "barrel" ) )
|
||||
{
|
||||
destructibles[i] thread destructible_barrel_death_think();
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( issubstr( destructibles[i].destructibledef, "gaspump" ) )
|
||||
{
|
||||
destructibles[i] thread destructible_barrel_death_think();
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( destructibles[i].destructibledef == "fxdest_upl_metal_tank_01" )
|
||||
destructibles[i] thread destructible_tank_grenade_stuck_think();
|
||||
}
|
||||
|
||||
destructible_anims = [];
|
||||
destructible_anims["car"] = %veh_car_destroy;
|
||||
}
|
||||
|
||||
destructible_event_callback( destructible_event, attacker, weapon )
|
||||
{
|
||||
explosion_radius = 0;
|
||||
|
||||
if ( issubstr( destructible_event, "explode" ) && destructible_event != "explode" )
|
||||
{
|
||||
tokens = strtok( destructible_event, "_" );
|
||||
explosion_radius = tokens[1];
|
||||
|
||||
if ( explosion_radius == "sm" )
|
||||
explosion_radius = 150;
|
||||
else if ( explosion_radius == "lg" )
|
||||
explosion_radius = 450;
|
||||
else
|
||||
explosion_radius = int( explosion_radius );
|
||||
|
||||
destructible_event = "explode_complex";
|
||||
}
|
||||
|
||||
if ( issubstr( destructible_event, "simple_timed_explosion" ) )
|
||||
{
|
||||
self thread simple_timed_explosion( destructible_event, attacker );
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( destructible_event )
|
||||
{
|
||||
case "destructible_car_explosion":
|
||||
self destructible_car_explosion( attacker );
|
||||
|
||||
if ( isdefined( weapon ) )
|
||||
self.destroyingweapon = weapon;
|
||||
|
||||
break;
|
||||
case "destructible_car_fire":
|
||||
self thread destructible_car_fire_think( attacker );
|
||||
|
||||
if ( isdefined( weapon ) )
|
||||
self.destroyingweapon = weapon;
|
||||
|
||||
break;
|
||||
case "destructible_barrel_fire":
|
||||
self thread destructible_barrel_fire_think( attacker );
|
||||
break;
|
||||
case "destructible_barrel_explosion":
|
||||
self destructible_barrel_explosion( attacker );
|
||||
break;
|
||||
case "explode":
|
||||
self thread simple_explosion( attacker );
|
||||
break;
|
||||
case "explode_complex":
|
||||
self thread complex_explosion( attacker, explosion_radius );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( isdefined( level.destructible_callbacks[destructible_event] ) )
|
||||
self thread [[ level.destructible_callbacks[destructible_event] ]]( destructible_event, attacker );
|
||||
}
|
||||
|
||||
simple_explosion( attacker )
|
||||
{
|
||||
if ( is_true( self.exploded ) )
|
||||
return;
|
||||
|
||||
self.exploded = 1;
|
||||
offset = vectorscale( ( 0, 0, 1 ), 5.0 );
|
||||
self radiusdamage( self.origin + offset, 256, 300, 75, attacker, "MOD_EXPLOSIVE", "explodable_barrel_mp" );
|
||||
physicsexplosionsphere( self.origin, 255, 254, 0.3, 400, 25 );
|
||||
|
||||
if ( isdefined( attacker ) )
|
||||
self dodamage( self.health + 10000, self.origin + offset, attacker );
|
||||
else
|
||||
self dodamage( self.health + 10000, self.origin + offset );
|
||||
}
|
||||
|
||||
simple_timed_explosion( destructible_event, attacker )
|
||||
{
|
||||
self endon( "death" );
|
||||
wait_times = [];
|
||||
str = getsubstr( destructible_event, 23 );
|
||||
tokens = strtok( str, "_" );
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
complex_explosion( attacker, max_radius )
|
||||
{
|
||||
offset = vectorscale( ( 0, 0, 1 ), 5.0 );
|
||||
|
||||
if ( isdefined( attacker ) )
|
||||
self radiusdamage( self.origin + offset, max_radius, 300, 100, attacker );
|
||||
else
|
||||
self radiusdamage( self.origin + offset, max_radius, 300, 100 );
|
||||
|
||||
playrumbleonposition( "grenade_rumble", self.origin );
|
||||
earthquake( 0.5, 0.5, self.origin, max_radius );
|
||||
physicsexplosionsphere( self.origin + offset, max_radius, max_radius - 1, 0.3 );
|
||||
|
||||
if ( isdefined( attacker ) )
|
||||
self dodamage( 20000, self.origin + offset, attacker );
|
||||
else
|
||||
self dodamage( 20000, self.origin + offset );
|
||||
}
|
||||
|
||||
destructible_car_explosion( attacker, physics_explosion )
|
||||
{
|
||||
if ( self.car_dead )
|
||||
return;
|
||||
|
||||
if ( !isdefined( physics_explosion ) )
|
||||
physics_explosion = 1;
|
||||
|
||||
players = get_players();
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
body = players[i].body;
|
||||
|
||||
if ( !isdefined( body ) )
|
||||
continue;
|
||||
|
||||
if ( distancesquared( body.origin, self.origin ) > 9216 )
|
||||
continue;
|
||||
|
||||
if ( body.origin[2] - self.origin[2] + 32 > 0 )
|
||||
body.origin = ( body.origin[0], body.origin[1], body.origin[2] + 16 );
|
||||
|
||||
body maps\mp\gametypes\_globallogic_player::start_explosive_ragdoll();
|
||||
}
|
||||
|
||||
self notify( "car_dead" );
|
||||
self.car_dead = 1;
|
||||
self thread destructible_car_explosion_animate();
|
||||
|
||||
if ( isdefined( attacker ) )
|
||||
self radiusdamage( self.origin, 256, 300, 75, attacker, "MOD_EXPLOSIVE", "destructible_car_mp" );
|
||||
else
|
||||
self radiusdamage( self.origin, 256, 300, 75 );
|
||||
|
||||
playrumbleonposition( "grenade_rumble", self.origin );
|
||||
earthquake( 0.5, 0.5, self.origin, 800 );
|
||||
|
||||
if ( physics_explosion )
|
||||
physicsexplosionsphere( self.origin, 255, 254, 0.3, 400, 25 );
|
||||
|
||||
if ( isdefined( attacker ) )
|
||||
attacker thread maps\mp\_challenges::destroyed_car();
|
||||
|
||||
level.globalcarsdestroyed++;
|
||||
|
||||
if ( isdefined( attacker ) )
|
||||
self dodamage( self.health + 10000, self.origin + ( 0, 0, 1 ), attacker );
|
||||
else
|
||||
self dodamage( self.health + 10000, self.origin + ( 0, 0, 1 ) );
|
||||
|
||||
self setclientflag( 3 );
|
||||
}
|
||||
|
||||
destructible_tank_grenade_stuck_think()
|
||||
{
|
||||
self endon( "destructible_base_piece_death" );
|
||||
self endon( "death" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "grenade_stuck", missile );
|
||||
|
||||
if ( !isdefined( missile ) || !isdefined( missile.model ) )
|
||||
continue;
|
||||
|
||||
if ( missile.model == "t5_weapon_crossbow_bolt" || missile.model == "t6_wpn_grenade_semtex_projectile" || missile.model == "t6_wpn_c4_world" )
|
||||
self thread destructible_tank_grenade_stuck_explode( missile );
|
||||
}
|
||||
}
|
||||
|
||||
destructible_tank_grenade_stuck_explode( missile )
|
||||
{
|
||||
self endon( "destructible_base_piece_death" );
|
||||
self endon( "death" );
|
||||
owner = getmissileowner( missile );
|
||||
|
||||
if ( isdefined( owner ) && missile.model == "t6_wpn_c4_world" )
|
||||
{
|
||||
owner endon( "disconnect" );
|
||||
owner endon( "weapon_object_destroyed" );
|
||||
missile endon( "picked_up" );
|
||||
missile thread destructible_tank_hacked_c4( self );
|
||||
}
|
||||
|
||||
missile waittill( "explode" );
|
||||
|
||||
if ( isdefined( owner ) )
|
||||
self dodamage( self.health + 10000, self.origin + ( 0, 0, 1 ), owner );
|
||||
else
|
||||
self dodamage( self.health + 10000, self.origin + ( 0, 0, 1 ) );
|
||||
}
|
||||
|
||||
destructible_tank_hacked_c4( tank )
|
||||
{
|
||||
tank endon( "destructible_base_piece_death" );
|
||||
tank endon( "death" );
|
||||
self endon( "death" );
|
||||
|
||||
self waittill( "hacked" );
|
||||
|
||||
self notify( "picked_up" );
|
||||
tank thread destructible_tank_grenade_stuck_explode( self );
|
||||
}
|
||||
|
||||
destructible_car_death_think()
|
||||
{
|
||||
self endon( "car_dead" );
|
||||
self.car_dead = 0;
|
||||
self thread destructible_car_death_notify();
|
||||
|
||||
self waittill( "destructible_base_piece_death", attacker );
|
||||
|
||||
if ( isdefined( self ) )
|
||||
self thread destructible_car_explosion( attacker, 0 );
|
||||
}
|
||||
|
||||
destructible_car_grenade_stuck_think()
|
||||
{
|
||||
self endon( "destructible_base_piece_death" );
|
||||
self endon( "car_dead" );
|
||||
self endon( "death" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "grenade_stuck", missile );
|
||||
|
||||
if ( !isdefined( missile ) || !isdefined( missile.model ) )
|
||||
continue;
|
||||
|
||||
if ( missile.model == "t5_weapon_crossbow_bolt" || missile.model == "t6_wpn_grenade_semtex_projectile" || missile.model == "t6_wpn_c4_world" )
|
||||
self thread destructible_car_grenade_stuck_explode( missile );
|
||||
}
|
||||
}
|
||||
|
||||
destructible_car_grenade_stuck_explode( missile )
|
||||
{
|
||||
self endon( "destructible_base_piece_death" );
|
||||
self endon( "car_dead" );
|
||||
self endon( "death" );
|
||||
owner = getmissileowner( missile );
|
||||
|
||||
if ( isdefined( owner ) && missile.model == "t6_wpn_c4_world" )
|
||||
{
|
||||
owner endon( "disconnect" );
|
||||
owner endon( "weapon_object_destroyed" );
|
||||
missile endon( "picked_up" );
|
||||
missile thread destructible_car_hacked_c4( self );
|
||||
}
|
||||
|
||||
missile waittill( "explode" );
|
||||
|
||||
if ( isdefined( owner ) )
|
||||
self dodamage( self.health + 10000, self.origin + ( 0, 0, 1 ), owner );
|
||||
else
|
||||
self dodamage( self.health + 10000, self.origin + ( 0, 0, 1 ) );
|
||||
}
|
||||
|
||||
destructible_car_hacked_c4( car )
|
||||
{
|
||||
car endon( "destructible_base_piece_death" );
|
||||
car endon( "car_dead" );
|
||||
car endon( "death" );
|
||||
self endon( "death" );
|
||||
|
||||
self waittill( "hacked" );
|
||||
|
||||
self notify( "picked_up" );
|
||||
car thread destructible_car_grenade_stuck_explode( self );
|
||||
}
|
||||
|
||||
destructible_car_death_notify()
|
||||
{
|
||||
self endon( "car_dead" );
|
||||
|
||||
self waittill( "death", attacker );
|
||||
|
||||
self notify( "destructible_base_piece_death", attacker );
|
||||
}
|
||||
|
||||
destructible_car_explosion_animate()
|
||||
{
|
||||
self setclientflag( 12 );
|
||||
end_origin = self.origin;
|
||||
self.origin = ( self.origin[0], self.origin[1], self.origin[2] + 16 );
|
||||
wait 0.3;
|
||||
items = getdroppedweapons();
|
||||
|
||||
for ( i = 0; i < items.size; i++ )
|
||||
{
|
||||
if ( distancesquared( end_origin, items[i].origin ) < 16384 )
|
||||
{
|
||||
if ( items[i].origin[2] - end_origin[2] + 32 > 0 )
|
||||
items[i] delete();
|
||||
}
|
||||
}
|
||||
|
||||
self moveto( end_origin, 0.3, 0.15 );
|
||||
self clearclientflag( 12 );
|
||||
}
|
||||
|
||||
destructible_car_fire_think( attacker )
|
||||
{
|
||||
self endon( "death" );
|
||||
wait( randomintrange( 7, 10 ) );
|
||||
self thread destructible_car_explosion( attacker );
|
||||
}
|
||||
|
||||
codecallback_destructibleevent( event, param1, param2, param3 )
|
||||
{
|
||||
if ( event == "broken" )
|
||||
{
|
||||
notify_type = param1;
|
||||
attacker = param2;
|
||||
weapon = param3;
|
||||
destructible_event_callback( notify_type, attacker, weapon );
|
||||
self notify( event, notify_type, attacker );
|
||||
}
|
||||
else if ( event == "breakafter" )
|
||||
{
|
||||
piece = param1;
|
||||
time = param2;
|
||||
damage = param3;
|
||||
self thread breakafter( time, damage, piece );
|
||||
}
|
||||
}
|
||||
|
||||
breakafter( time, damage, piece )
|
||||
{
|
||||
self notify( "breakafter" );
|
||||
self endon( "breakafter" );
|
||||
wait( time );
|
||||
self dodamage( damage, self.origin, undefined, undefined );
|
||||
}
|
||||
|
||||
destructible_barrel_death_think()
|
||||
{
|
||||
self endon( "barrel_dead" );
|
||||
|
||||
self waittill( "death", attacker );
|
||||
|
||||
if ( isdefined( self ) )
|
||||
self thread destructible_barrel_explosion( attacker, 0 );
|
||||
}
|
||||
|
||||
destructible_barrel_fire_think( attacker )
|
||||
{
|
||||
self endon( "barrel_dead" );
|
||||
self endon( "explode" );
|
||||
self endon( "death" );
|
||||
wait( randomintrange( 7, 10 ) );
|
||||
self thread destructible_barrel_explosion( attacker );
|
||||
}
|
||||
|
||||
destructible_barrel_explosion( attacker, physics_explosion = 1 )
|
||||
{
|
||||
self notify( "barrel_dead" );
|
||||
|
||||
if ( isdefined( self.target ) )
|
||||
{
|
||||
dest_clip = getent( self.target, "targetname" );
|
||||
dest_clip delete();
|
||||
}
|
||||
|
||||
self radiusdamage( self.origin, 256, 300, 75, attacker, "MOD_EXPLOSIVE", "explodable_barrel_mp" );
|
||||
playrumbleonposition( "grenade_rumble", self.origin );
|
||||
earthquake( 0.5, 0.5, self.origin, 800 );
|
||||
|
||||
if ( physics_explosion )
|
||||
physicsexplosionsphere( self.origin, 255, 254, 0.3, 400, 25 );
|
||||
|
||||
level.globalbarrelsdestroyed++;
|
||||
self dodamage( self.health + 10000, self.origin + ( 0, 0, 1 ), attacker );
|
||||
self setclientflag( 3 );
|
||||
}
|
9
MP/Core/maps/mp/_development_dvars.gsc
Normal file
9
MP/Core/maps/mp/_development_dvars.gsc
Normal file
@ -0,0 +1,9 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
|
||||
init()
|
||||
{
|
||||
|
||||
}
|
175
MP/Core/maps/mp/_empgrenade.gsc
Normal file
175
MP/Core/maps/mp/_empgrenade.gsc
Normal file
@ -0,0 +1,175 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\killstreaks\_emp;
|
||||
|
||||
init()
|
||||
{
|
||||
precacheshellshock( "flashbang" );
|
||||
thread onplayerconnect();
|
||||
}
|
||||
|
||||
onplayerconnect()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
player thread onplayerspawned();
|
||||
}
|
||||
}
|
||||
|
||||
onplayerspawned()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
|
||||
self thread monitorempgrenade();
|
||||
}
|
||||
}
|
||||
|
||||
monitorempgrenade()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self.empendtime = 0;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self waittill( "emp_grenaded", attacker );
|
||||
|
||||
if ( !isalive( self ) || self hasperk( "specialty_immuneemp" ) )
|
||||
continue;
|
||||
|
||||
hurtvictim = 1;
|
||||
hurtattacker = 0;
|
||||
assert( isdefined( self.team ) );
|
||||
|
||||
if ( level.teambased && isdefined( attacker ) && isdefined( attacker.team ) && attacker.team == self.team && attacker != self )
|
||||
{
|
||||
if ( level.friendlyfire == 0 )
|
||||
continue;
|
||||
else if ( level.friendlyfire == 1 )
|
||||
{
|
||||
hurtattacker = 0;
|
||||
hurtvictim = 1;
|
||||
}
|
||||
else if ( level.friendlyfire == 2 )
|
||||
{
|
||||
hurtvictim = 0;
|
||||
hurtattacker = 1;
|
||||
}
|
||||
else if ( level.friendlyfire == 3 )
|
||||
{
|
||||
hurtattacker = 1;
|
||||
hurtvictim = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( hurtvictim && isdefined( self ) )
|
||||
self thread applyemp( attacker );
|
||||
|
||||
if ( hurtattacker && isdefined( attacker ) )
|
||||
attacker thread applyemp( attacker );
|
||||
}
|
||||
}
|
||||
|
||||
applyemp( attacker )
|
||||
{
|
||||
self notify( "applyEmp" );
|
||||
self endon( "applyEmp" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
wait 0.05;
|
||||
|
||||
if ( self == attacker )
|
||||
{
|
||||
if ( isdefined( self.empendtime ) )
|
||||
{
|
||||
emp_time_left_ms = self.empendtime - gettime();
|
||||
|
||||
if ( emp_time_left_ms > 1000 )
|
||||
self.empduration = emp_time_left_ms / 1000;
|
||||
else
|
||||
self.empduration = 1;
|
||||
}
|
||||
else
|
||||
self.empduration = 1;
|
||||
}
|
||||
else
|
||||
self.empduration = 12;
|
||||
|
||||
self.empgrenaded = 1;
|
||||
self shellshock( "flashbang", 1 );
|
||||
self.empendtime = gettime() + self.empduration * 1000;
|
||||
self thread emprumbleloop( 0.75 );
|
||||
self setempjammed( 1 );
|
||||
self thread empgrenadedeathwaiter();
|
||||
wait( self.empduration );
|
||||
self notify( "empGrenadeTimedOut" );
|
||||
self checktoturnoffemp();
|
||||
}
|
||||
|
||||
empgrenadedeathwaiter()
|
||||
{
|
||||
self notify( "empGrenadeDeathWaiter" );
|
||||
self endon( "empGrenadeDeathWaiter" );
|
||||
self endon( "empGrenadeTimedOut" );
|
||||
|
||||
self waittill( "death" );
|
||||
|
||||
self checktoturnoffemp();
|
||||
}
|
||||
|
||||
checktoturnoffemp()
|
||||
{
|
||||
self.empgrenaded = 0;
|
||||
|
||||
if ( level.teambased && maps\mp\killstreaks\_emp::emp_isteamemped( self.team ) || !level.teambased && isdefined( level.empplayer ) && level.empplayer != self )
|
||||
return;
|
||||
|
||||
self setempjammed( 0 );
|
||||
}
|
||||
|
||||
emprumbleloop( duration )
|
||||
{
|
||||
self endon( "emp_rumble_loop" );
|
||||
self notify( "emp_rumble_loop" );
|
||||
goaltime = gettime() + duration * 1000;
|
||||
|
||||
while ( gettime() < goaltime )
|
||||
{
|
||||
self playrumbleonentity( "damage_heavy" );
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
watchempexplosion( owner, weaponname )
|
||||
{
|
||||
owner endon( "disconnect" );
|
||||
owner endon( "team_changed" );
|
||||
self endon( "shutdown_empgrenade" );
|
||||
self thread watchempgrenadeshutdown();
|
||||
owner addweaponstat( weaponname, "used", 1 );
|
||||
|
||||
self waittill( "explode", origin, surface );
|
||||
|
||||
ents = getdamageableentarray( origin, 512 );
|
||||
|
||||
foreach ( ent in ents )
|
||||
ent dodamage( 1, origin, owner, owner, "none", "MOD_GRENADE_SPLASH", 0, weaponname );
|
||||
}
|
||||
|
||||
watchempgrenadeshutdown()
|
||||
{
|
||||
self endon( "explode" );
|
||||
|
||||
self waittill( "death" );
|
||||
|
||||
wait 0.05;
|
||||
self notify( "shutdown_empgrenade" );
|
||||
}
|
139
MP/Core/maps/mp/_entityheadicons.gsc
Normal file
139
MP/Core/maps/mp/_entityheadicons.gsc
Normal file
@ -0,0 +1,139 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
|
||||
init()
|
||||
{
|
||||
if ( isdefined( level.initedentityheadicons ) )
|
||||
return;
|
||||
|
||||
if ( level.createfx_enabled )
|
||||
return;
|
||||
|
||||
level.initedentityheadicons = 1;
|
||||
assert( isdefined( game["entity_headicon_allies"] ), "Allied head icons are not defined. Check the team set for the level." );
|
||||
assert( isdefined( game["entity_headicon_axis"] ), "Axis head icons are not defined. Check the team set for the level." );
|
||||
precacheshader( game["entity_headicon_allies"] );
|
||||
precacheshader( game["entity_headicon_axis"] );
|
||||
|
||||
if ( !level.teambased )
|
||||
return;
|
||||
|
||||
level.entitieswithheadicons = [];
|
||||
}
|
||||
|
||||
setentityheadicon( team, owner, offset, icon, constant_size )
|
||||
{
|
||||
if ( !level.teambased && !isdefined( owner ) )
|
||||
return;
|
||||
|
||||
if ( !isdefined( constant_size ) )
|
||||
constant_size = 0;
|
||||
|
||||
if ( !isdefined( self.entityheadiconteam ) )
|
||||
{
|
||||
self.entityheadiconteam = "none";
|
||||
self.entityheadicons = [];
|
||||
}
|
||||
|
||||
if ( level.teambased && !isdefined( owner ) )
|
||||
{
|
||||
if ( team == self.entityheadiconteam )
|
||||
return;
|
||||
|
||||
self.entityheadiconteam = team;
|
||||
}
|
||||
|
||||
if ( isdefined( offset ) )
|
||||
self.entityheadiconoffset = offset;
|
||||
else
|
||||
self.entityheadiconoffset = ( 0, 0, 0 );
|
||||
|
||||
if ( isdefined( self.entityheadicons ) )
|
||||
{
|
||||
for ( i = 0; i < self.entityheadicons.size; i++ )
|
||||
{
|
||||
if ( isdefined( self.entityheadicons[i] ) )
|
||||
self.entityheadicons[i] destroy();
|
||||
}
|
||||
}
|
||||
|
||||
self.entityheadicons = [];
|
||||
self notify( "kill_entity_headicon_thread" );
|
||||
|
||||
if ( !isdefined( icon ) )
|
||||
icon = game["entity_headicon_" + team];
|
||||
|
||||
if ( isdefined( owner ) && !level.teambased )
|
||||
{
|
||||
if ( !isplayer( owner ) )
|
||||
{
|
||||
assert( isdefined( owner.owner ), "entity has to have an owner if it's not a player" );
|
||||
owner = owner.owner;
|
||||
}
|
||||
|
||||
owner updateentityheadclienticon( self, icon, constant_size );
|
||||
}
|
||||
else if ( isdefined( owner ) && team != "none" )
|
||||
owner updateentityheadteamicon( self, team, icon, constant_size );
|
||||
|
||||
self thread destroyheadiconsondeath();
|
||||
}
|
||||
|
||||
updateentityheadteamicon( entity, team, icon, constant_size )
|
||||
{
|
||||
headicon = newteamhudelem( team );
|
||||
headicon.archived = 1;
|
||||
headicon.x = entity.entityheadiconoffset[0];
|
||||
headicon.y = entity.entityheadiconoffset[1];
|
||||
headicon.z = entity.entityheadiconoffset[2];
|
||||
headicon.alpha = 0.8;
|
||||
headicon setshader( icon, 6, 6 );
|
||||
headicon setwaypoint( constant_size );
|
||||
headicon settargetent( entity );
|
||||
entity.entityheadicons[entity.entityheadicons.size] = headicon;
|
||||
}
|
||||
|
||||
updateentityheadclienticon( entity, icon, constant_size )
|
||||
{
|
||||
headicon = newclienthudelem( self );
|
||||
headicon.archived = 1;
|
||||
headicon.x = entity.entityheadiconoffset[0];
|
||||
headicon.y = entity.entityheadiconoffset[1];
|
||||
headicon.z = entity.entityheadiconoffset[2];
|
||||
headicon.alpha = 0.8;
|
||||
headicon setshader( icon, 6, 6 );
|
||||
headicon setwaypoint( constant_size );
|
||||
headicon settargetent( entity );
|
||||
entity.entityheadicons[entity.entityheadicons.size] = headicon;
|
||||
}
|
||||
|
||||
destroyheadiconsondeath()
|
||||
{
|
||||
self waittill_any( "death", "hacked" );
|
||||
|
||||
for ( i = 0; i < self.entityheadicons.size; i++ )
|
||||
{
|
||||
if ( isdefined( self.entityheadicons[i] ) )
|
||||
self.entityheadicons[i] destroy();
|
||||
}
|
||||
}
|
||||
|
||||
destroyentityheadicons()
|
||||
{
|
||||
if ( isdefined( self.entityheadicons ) )
|
||||
{
|
||||
for ( i = 0; i < self.entityheadicons.size; i++ )
|
||||
{
|
||||
if ( isdefined( self.entityheadicons[i] ) )
|
||||
self.entityheadicons[i] destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateentityheadiconpos( headicon )
|
||||
{
|
||||
headicon.x = self.origin[0] + self.entityheadiconoffset[0];
|
||||
headicon.y = self.origin[1] + self.entityheadiconoffset[1];
|
||||
headicon.z = self.origin[2] + self.entityheadiconoffset[2];
|
||||
}
|
15
MP/Core/maps/mp/_explosive_bolt.gsc
Normal file
15
MP/Core/maps/mp/_explosive_bolt.gsc
Normal file
@ -0,0 +1,15 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
|
||||
init()
|
||||
{
|
||||
loadfx( "weapon/crossbow/fx_trail_crossbow_blink_grn_os" );
|
||||
loadfx( "weapon/crossbow/fx_trail_crossbow_blink_red_os" );
|
||||
}
|
||||
|
||||
watch_bolt_detonation( owner )
|
||||
{
|
||||
|
||||
}
|
201
MP/Core/maps/mp/_flashgrenades.gsc
Normal file
201
MP/Core/maps/mp/_flashgrenades.gsc
Normal file
@ -0,0 +1,201 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
|
||||
main()
|
||||
{
|
||||
precacheshellshock( "flashbang" );
|
||||
level.sound_flash_start = "";
|
||||
level.sound_flash_loop = "";
|
||||
level.sound_flash_stop = "";
|
||||
}
|
||||
|
||||
startmonitoringflash()
|
||||
{
|
||||
self thread monitorflash();
|
||||
}
|
||||
|
||||
stopmonitoringflash( disconnected )
|
||||
{
|
||||
self notify( "stop_monitoring_flash" );
|
||||
}
|
||||
|
||||
flashrumbleloop( duration )
|
||||
{
|
||||
self endon( "stop_monitoring_flash" );
|
||||
self endon( "flash_rumble_loop" );
|
||||
self notify( "flash_rumble_loop" );
|
||||
goaltime = gettime() + duration * 1000;
|
||||
|
||||
while ( gettime() < goaltime )
|
||||
{
|
||||
self playrumbleonentity( "damage_heavy" );
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
monitorflash_internal( amount_distance, amount_angle, attacker, direct_on_player )
|
||||
{
|
||||
hurtattacker = 0;
|
||||
hurtvictim = 1;
|
||||
|
||||
if ( amount_angle < 0.5 )
|
||||
amount_angle = 0.5;
|
||||
else if ( amount_angle > 0.8 )
|
||||
amount_angle = 1;
|
||||
|
||||
if ( isdefined( attacker ) && attacker == self )
|
||||
amount_distance *= 0.5;
|
||||
|
||||
duration = amount_distance * amount_angle * 6;
|
||||
|
||||
if ( duration < 0.25 )
|
||||
return;
|
||||
|
||||
rumbleduration = undefined;
|
||||
|
||||
if ( duration > 2 )
|
||||
rumbleduration = 0.75;
|
||||
else
|
||||
rumbleduration = 0.25;
|
||||
|
||||
assert( isdefined( self.team ) );
|
||||
|
||||
if ( level.teambased && isdefined( attacker ) && isdefined( attacker.team ) && attacker.team == self.team && attacker != self )
|
||||
{
|
||||
if ( level.friendlyfire == 0 )
|
||||
return;
|
||||
else if ( level.friendlyfire == 1 )
|
||||
{
|
||||
|
||||
}
|
||||
else if ( level.friendlyfire == 2 )
|
||||
{
|
||||
duration *= 0.5;
|
||||
rumbleduration *= 0.5;
|
||||
hurtvictim = 0;
|
||||
hurtattacker = 1;
|
||||
}
|
||||
else if ( level.friendlyfire == 3 )
|
||||
{
|
||||
duration *= 0.5;
|
||||
rumbleduration *= 0.5;
|
||||
hurtattacker = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( self hasperk( "specialty_flashprotection" ) )
|
||||
{
|
||||
duration *= 0.1;
|
||||
rumbleduration *= 0.1;
|
||||
}
|
||||
|
||||
if ( hurtvictim )
|
||||
{
|
||||
if ( self mayapplyscreeneffect() || !direct_on_player && self isremotecontrolling() )
|
||||
{
|
||||
if ( self != attacker )
|
||||
{
|
||||
attacker addweaponstat( "flash_grenade_mp", "hits", 1 );
|
||||
attacker addweaponstat( "flash_grenade_mp", "used", 1 );
|
||||
}
|
||||
|
||||
self thread applyflash( duration, rumbleduration, attacker );
|
||||
}
|
||||
}
|
||||
|
||||
if ( hurtattacker )
|
||||
{
|
||||
if ( attacker mayapplyscreeneffect() )
|
||||
attacker thread applyflash( duration, rumbleduration, attacker );
|
||||
}
|
||||
}
|
||||
|
||||
monitorflash()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self.flashendtime = 0;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self waittill( "flashbang", amount_distance, amount_angle, attacker );
|
||||
|
||||
if ( !isalive( self ) )
|
||||
continue;
|
||||
|
||||
self monitorflash_internal( amount_distance, amount_angle, attacker, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
monitorrcbombflash()
|
||||
{
|
||||
self endon( "death" );
|
||||
self.flashendtime = 0;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self waittill( "flashbang", amount_distance, amount_angle, attacker );
|
||||
|
||||
driver = self getseatoccupant( 0 );
|
||||
|
||||
if ( !isdefined( driver ) || !isalive( driver ) )
|
||||
continue;
|
||||
|
||||
driver monitorflash_internal( amount_distance, amount_angle, attacker, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
applyflash( duration, rumbleduration, attacker )
|
||||
{
|
||||
if ( !isdefined( self.flashduration ) || duration > self.flashduration )
|
||||
self.flashduration = duration;
|
||||
|
||||
if ( !isdefined( self.flashrumbleduration ) || rumbleduration > self.flashrumbleduration )
|
||||
self.flashrumbleduration = rumbleduration;
|
||||
|
||||
self thread playflashsound( duration );
|
||||
wait 0.05;
|
||||
|
||||
if ( isdefined( self.flashduration ) )
|
||||
{
|
||||
self shellshock( "flashbang", self.flashduration, 0 );
|
||||
self.flashendtime = gettime() + self.flashduration * 1000;
|
||||
self.lastflashedby = attacker;
|
||||
}
|
||||
|
||||
if ( isdefined( self.flashrumbleduration ) )
|
||||
self thread flashrumbleloop( self.flashrumbleduration );
|
||||
|
||||
self.flashduration = undefined;
|
||||
self.flashrumbleduration = undefined;
|
||||
}
|
||||
|
||||
playflashsound( duration )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
flashsound = spawn( "script_origin", ( 0, 0, 1 ) );
|
||||
flashsound.origin = self.origin;
|
||||
flashsound linkto( self );
|
||||
flashsound thread deleteentonownerdeath( self );
|
||||
flashsound playsound( level.sound_flash_start );
|
||||
flashsound playloopsound( level.sound_flash_loop );
|
||||
|
||||
if ( duration > 0.5 )
|
||||
wait( duration - 0.5 );
|
||||
|
||||
flashsound playsound( level.sound_flash_start );
|
||||
flashsound stoploopsound( 0.5 );
|
||||
wait 0.5;
|
||||
flashsound notify( "delete" );
|
||||
flashsound delete();
|
||||
}
|
||||
|
||||
deleteentonownerdeath( owner )
|
||||
{
|
||||
self endon( "delete" );
|
||||
|
||||
owner waittill( "death" );
|
||||
|
||||
self delete();
|
||||
}
|
453
MP/Core/maps/mp/_fx.gsc
Normal file
453
MP/Core/maps/mp/_fx.gsc
Normal file
@ -0,0 +1,453 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\_createfx;
|
||||
|
||||
print_org( fxcommand, fxid, fxpos, waittime )
|
||||
{
|
||||
/#
|
||||
if ( getdvar( _hash_F49A52C ) == "1" )
|
||||
{
|
||||
println( "{" );
|
||||
println( "\"origin\" \"" + fxpos[0] + " " + fxpos[1] + " " + fxpos[2] + "\"" );
|
||||
println( "\"classname\" \"script_model\"" );
|
||||
println( "\"model\" \"fx\"" );
|
||||
println( "\"script_fxcommand\" \"" + fxcommand + "\"" );
|
||||
println( "\"script_fxid\" \"" + fxid + "\"" );
|
||||
println( "\"script_delay\" \"" + waittime + "\"" );
|
||||
println( "}" );
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
oneshotfx( fxid, fxpos, waittime, fxpos2 )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
oneshotfxthread()
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( self.v["delay"] > 0 )
|
||||
wait( self.v["delay"] );
|
||||
|
||||
create_triggerfx();
|
||||
}
|
||||
|
||||
create_triggerfx()
|
||||
{
|
||||
self.looper = spawnfx_wrapper( self.v["fxid"], self.v["origin"], self.v["forward"], self.v["up"] );
|
||||
triggerfx( self.looper, self.v["delay"] );
|
||||
create_loopsound();
|
||||
}
|
||||
|
||||
exploderfx( num, fxid, fxpos, waittime, fxpos2, firefx, firefxdelay, firefxsound, fxsound, fxquake, fxdamage, soundalias, repeat, delay_min, delay_max, damage_radius, firefxtimeout, exploder_group )
|
||||
{
|
||||
if ( 1 )
|
||||
{
|
||||
ent = createexploder( fxid );
|
||||
ent.v["origin"] = fxpos;
|
||||
ent.v["angles"] = ( 0, 0, 0 );
|
||||
|
||||
if ( isdefined( fxpos2 ) )
|
||||
ent.v["angles"] = vectortoangles( fxpos2 - fxpos );
|
||||
|
||||
ent.v["delay"] = waittime;
|
||||
ent.v["exploder"] = num;
|
||||
return;
|
||||
}
|
||||
|
||||
fx = spawn( "script_origin", ( 0, 0, 0 ) );
|
||||
fx.origin = fxpos;
|
||||
fx.angles = vectortoangles( fxpos2 - fxpos );
|
||||
fx.script_exploder = num;
|
||||
fx.script_fxid = fxid;
|
||||
fx.script_delay = waittime;
|
||||
fx.script_firefx = firefx;
|
||||
fx.script_firefxdelay = firefxdelay;
|
||||
fx.script_firefxsound = firefxsound;
|
||||
fx.script_sound = fxsound;
|
||||
fx.script_earthquake = fxquake;
|
||||
fx.script_damage = fxdamage;
|
||||
fx.script_radius = damage_radius;
|
||||
fx.script_soundalias = soundalias;
|
||||
fx.script_firefxtimeout = firefxtimeout;
|
||||
fx.script_repeat = repeat;
|
||||
fx.script_delay_min = delay_min;
|
||||
fx.script_delay_max = delay_max;
|
||||
fx.script_exploder_group = exploder_group;
|
||||
forward = anglestoforward( fx.angles );
|
||||
forward = vectorscale( forward, 150 );
|
||||
fx.targetpos = fxpos + forward;
|
||||
|
||||
if ( !isdefined( level._script_exploders ) )
|
||||
level._script_exploders = [];
|
||||
|
||||
level._script_exploders[level._script_exploders.size] = fx;
|
||||
maps\mp\_createfx::createfx_showorigin( fxid, fxpos, waittime, fxpos2, "exploderfx", fx, undefined, firefx, firefxdelay, firefxsound, fxsound, fxquake, fxdamage, soundalias, repeat, delay_min, delay_max, damage_radius, firefxtimeout );
|
||||
}
|
||||
|
||||
loopfx( fxid, fxpos, waittime, fxpos2, fxstart, fxstop, timeout )
|
||||
{
|
||||
/#
|
||||
println( "Loopfx is deprecated!" );
|
||||
#/
|
||||
ent = createloopeffect( fxid );
|
||||
ent.v["origin"] = fxpos;
|
||||
ent.v["angles"] = ( 0, 0, 0 );
|
||||
|
||||
if ( isdefined( fxpos2 ) )
|
||||
ent.v["angles"] = vectortoangles( fxpos2 - fxpos );
|
||||
|
||||
ent.v["delay"] = waittime;
|
||||
}
|
||||
|
||||
create_looper()
|
||||
{
|
||||
self.looper = playloopedfx( level._effect[self.v["fxid"]], self.v["delay"], self.v["origin"], 0, self.v["forward"], self.v["up"] );
|
||||
create_loopsound();
|
||||
}
|
||||
|
||||
create_loopsound()
|
||||
{
|
||||
self notify( "stop_loop" );
|
||||
|
||||
if ( isdefined( self.v["soundalias"] ) && self.v["soundalias"] != "nil" )
|
||||
{
|
||||
if ( isdefined( self.looper ) )
|
||||
self.looper thread maps\mp\_utility::loop_fx_sound( self.v["soundalias"], self.v["origin"], "death" );
|
||||
else
|
||||
thread maps\mp\_utility::loop_fx_sound( self.v["soundalias"], self.v["origin"], "stop_loop" );
|
||||
}
|
||||
}
|
||||
|
||||
stop_loopsound()
|
||||
{
|
||||
self notify( "stop_loop" );
|
||||
}
|
||||
|
||||
loopfxthread()
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( isdefined( self.fxstart ) )
|
||||
level waittill( "start fx" + self.fxstart );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
create_looper();
|
||||
|
||||
if ( isdefined( self.timeout ) )
|
||||
thread loopfxstop( self.timeout );
|
||||
|
||||
if ( isdefined( self.fxstop ) )
|
||||
level waittill( "stop fx" + self.fxstop );
|
||||
else
|
||||
return;
|
||||
|
||||
if ( isdefined( self.looper ) )
|
||||
self.looper delete();
|
||||
|
||||
if ( isdefined( self.fxstart ) )
|
||||
level waittill( "start fx" + self.fxstart );
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
loopfxchangeid( ent )
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
ent waittill( "effect id changed", change );
|
||||
}
|
||||
|
||||
loopfxchangeorg( ent )
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
ent waittill( "effect org changed", change );
|
||||
|
||||
self.origin = change;
|
||||
}
|
||||
}
|
||||
|
||||
loopfxchangedelay( ent )
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
ent waittill( "effect delay changed", change );
|
||||
}
|
||||
|
||||
loopfxdeletion( ent )
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
ent waittill( "effect deleted" );
|
||||
|
||||
self delete();
|
||||
}
|
||||
|
||||
loopfxstop( timeout )
|
||||
{
|
||||
self endon( "death" );
|
||||
wait( timeout );
|
||||
self.looper delete();
|
||||
}
|
||||
|
||||
loopsound( sound, pos, waittime )
|
||||
{
|
||||
level thread loopsoundthread( sound, pos, waittime );
|
||||
}
|
||||
|
||||
loopsoundthread( sound, pos, waittime )
|
||||
{
|
||||
org = spawn( "script_origin", pos );
|
||||
org.origin = pos;
|
||||
org playloopsound( sound );
|
||||
}
|
||||
|
||||
gunfireloopfx( fxid, fxpos, shotsmin, shotsmax, shotdelaymin, shotdelaymax, betweensetsmin, betweensetsmax )
|
||||
{
|
||||
thread gunfireloopfxthread( fxid, fxpos, shotsmin, shotsmax, shotdelaymin, shotdelaymax, betweensetsmin, betweensetsmax );
|
||||
}
|
||||
|
||||
gunfireloopfxthread( fxid, fxpos, shotsmin, shotsmax, shotdelaymin, shotdelaymax, betweensetsmin, betweensetsmax )
|
||||
{
|
||||
level endon( "stop all gunfireloopfx" );
|
||||
wait 0.05;
|
||||
|
||||
if ( betweensetsmax < betweensetsmin )
|
||||
{
|
||||
temp = betweensetsmax;
|
||||
betweensetsmax = betweensetsmin;
|
||||
betweensetsmin = temp;
|
||||
}
|
||||
|
||||
betweensetsbase = betweensetsmin;
|
||||
betweensetsrange = betweensetsmax - betweensetsmin;
|
||||
|
||||
if ( shotdelaymax < shotdelaymin )
|
||||
{
|
||||
temp = shotdelaymax;
|
||||
shotdelaymax = shotdelaymin;
|
||||
shotdelaymin = temp;
|
||||
}
|
||||
|
||||
shotdelaybase = shotdelaymin;
|
||||
shotdelayrange = shotdelaymax - shotdelaymin;
|
||||
|
||||
if ( shotsmax < shotsmin )
|
||||
{
|
||||
temp = shotsmax;
|
||||
shotsmax = shotsmin;
|
||||
shotsmin = temp;
|
||||
}
|
||||
|
||||
shotsbase = shotsmin;
|
||||
shotsrange = shotsmax - shotsmin;
|
||||
fxent = spawnfx( level._effect[fxid], fxpos );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
shotnum = shotsbase + randomint( shotsrange );
|
||||
|
||||
for ( i = 0; i < shotnum; i++ )
|
||||
{
|
||||
triggerfx( fxent );
|
||||
wait( shotdelaybase + randomfloat( shotdelayrange ) );
|
||||
}
|
||||
|
||||
wait( betweensetsbase + randomfloat( betweensetsrange ) );
|
||||
}
|
||||
}
|
||||
|
||||
gunfireloopfxvec( fxid, fxpos, fxpos2, shotsmin, shotsmax, shotdelaymin, shotdelaymax, betweensetsmin, betweensetsmax )
|
||||
{
|
||||
thread gunfireloopfxvecthread( fxid, fxpos, fxpos2, shotsmin, shotsmax, shotdelaymin, shotdelaymax, betweensetsmin, betweensetsmax );
|
||||
}
|
||||
|
||||
gunfireloopfxvecthread( fxid, fxpos, fxpos2, shotsmin, shotsmax, shotdelaymin, shotdelaymax, betweensetsmin, betweensetsmax )
|
||||
{
|
||||
level endon( "stop all gunfireloopfx" );
|
||||
wait 0.05;
|
||||
|
||||
if ( betweensetsmax < betweensetsmin )
|
||||
{
|
||||
temp = betweensetsmax;
|
||||
betweensetsmax = betweensetsmin;
|
||||
betweensetsmin = temp;
|
||||
}
|
||||
|
||||
betweensetsbase = betweensetsmin;
|
||||
betweensetsrange = betweensetsmax - betweensetsmin;
|
||||
|
||||
if ( shotdelaymax < shotdelaymin )
|
||||
{
|
||||
temp = shotdelaymax;
|
||||
shotdelaymax = shotdelaymin;
|
||||
shotdelaymin = temp;
|
||||
}
|
||||
|
||||
shotdelaybase = shotdelaymin;
|
||||
shotdelayrange = shotdelaymax - shotdelaymin;
|
||||
|
||||
if ( shotsmax < shotsmin )
|
||||
{
|
||||
temp = shotsmax;
|
||||
shotsmax = shotsmin;
|
||||
shotsmin = temp;
|
||||
}
|
||||
|
||||
shotsbase = shotsmin;
|
||||
shotsrange = shotsmax - shotsmin;
|
||||
fxpos2 = vectornormalize( fxpos2 - fxpos );
|
||||
fxent = spawnfx( level._effect[fxid], fxpos, fxpos2 );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
shotnum = shotsbase + randomint( shotsrange );
|
||||
|
||||
for ( i = 0; i < int( shotnum / level.fxfireloopmod ); i++ )
|
||||
{
|
||||
triggerfx( fxent );
|
||||
delay = ( shotdelaybase + randomfloat( shotdelayrange ) ) * level.fxfireloopmod;
|
||||
|
||||
if ( delay < 0.05 )
|
||||
delay = 0.05;
|
||||
|
||||
wait( delay );
|
||||
}
|
||||
|
||||
wait( shotdelaybase + randomfloat( shotdelayrange ) );
|
||||
wait( betweensetsbase + randomfloat( betweensetsrange ) );
|
||||
}
|
||||
}
|
||||
|
||||
setfireloopmod( value )
|
||||
{
|
||||
level.fxfireloopmod = 1 / value;
|
||||
}
|
||||
|
||||
setup_fx()
|
||||
{
|
||||
if ( !isdefined( self.script_fxid ) || !isdefined( self.script_fxcommand ) || !isdefined( self.script_delay ) )
|
||||
return;
|
||||
|
||||
org = undefined;
|
||||
|
||||
if ( isdefined( self.target ) )
|
||||
{
|
||||
ent = getent( self.target, "targetname" );
|
||||
|
||||
if ( isdefined( ent ) )
|
||||
org = ent.origin;
|
||||
}
|
||||
|
||||
fxstart = undefined;
|
||||
|
||||
if ( isdefined( self.script_fxstart ) )
|
||||
fxstart = self.script_fxstart;
|
||||
|
||||
fxstop = undefined;
|
||||
|
||||
if ( isdefined( self.script_fxstop ) )
|
||||
fxstop = self.script_fxstop;
|
||||
|
||||
if ( self.script_fxcommand == "OneShotfx" )
|
||||
oneshotfx( self.script_fxid, self.origin, self.script_delay, org );
|
||||
|
||||
if ( self.script_fxcommand == "loopfx" )
|
||||
loopfx( self.script_fxid, self.origin, self.script_delay, org, fxstart, fxstop );
|
||||
|
||||
if ( self.script_fxcommand == "loopsound" )
|
||||
loopsound( self.script_fxid, self.origin, self.script_delay );
|
||||
|
||||
self delete();
|
||||
}
|
||||
|
||||
script_print_fx()
|
||||
{
|
||||
/#
|
||||
if ( !isdefined( self.script_fxid ) || !isdefined( self.script_fxcommand ) || !isdefined( self.script_delay ) )
|
||||
{
|
||||
println( "Effect at origin ", self.origin, " doesn't have script_fxid/script_fxcommand/script_delay" );
|
||||
self delete();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isdefined( self.target ) )
|
||||
org = getent( self.target, "targetname" ).origin;
|
||||
else
|
||||
org = "undefined";
|
||||
|
||||
if ( self.script_fxcommand == "OneShotfx" )
|
||||
println( "mapsmp_fx::OneShotfx(\"" + self.script_fxid + "\", " + self.origin + ", " + self.script_delay + ", " + org + ");" );
|
||||
|
||||
if ( self.script_fxcommand == "loopfx" )
|
||||
println( "mapsmp_fx::LoopFx(\"" + self.script_fxid + "\", " + self.origin + ", " + self.script_delay + ", " + org + ");" );
|
||||
|
||||
if ( self.script_fxcommand == "loopsound" )
|
||||
println( "mapsmp_fx::LoopSound(\"" + self.script_fxid + "\", " + self.origin + ", " + self.script_delay + ", " + org + ");" );
|
||||
#/
|
||||
}
|
||||
|
||||
script_playfx( id, pos, pos2 )
|
||||
{
|
||||
if ( !id )
|
||||
return;
|
||||
|
||||
if ( isdefined( pos2 ) )
|
||||
playfx( id, pos, pos2 );
|
||||
else
|
||||
playfx( id, pos );
|
||||
}
|
||||
|
||||
script_playfxontag( id, ent, tag )
|
||||
{
|
||||
if ( !id )
|
||||
return;
|
||||
|
||||
playfxontag( id, ent, tag );
|
||||
}
|
||||
|
||||
grenadeexplosionfx( pos )
|
||||
{
|
||||
playfx( level._effect["mechanical explosion"], pos );
|
||||
earthquake( 0.15, 0.5, pos, 250 );
|
||||
}
|
||||
|
||||
soundfx( fxid, fxpos, endonnotify )
|
||||
{
|
||||
org = spawn( "script_origin", ( 0, 0, 0 ) );
|
||||
org.origin = fxpos;
|
||||
org playloopsound( fxid );
|
||||
|
||||
if ( isdefined( endonnotify ) )
|
||||
org thread soundfxdelete( endonnotify );
|
||||
}
|
||||
|
||||
soundfxdelete( endonnotify )
|
||||
{
|
||||
level waittill( endonnotify );
|
||||
|
||||
self delete();
|
||||
}
|
||||
|
||||
blenddelete( blend )
|
||||
{
|
||||
self waittill( "death" );
|
||||
|
||||
blend delete();
|
||||
}
|
||||
|
||||
spawnfx_wrapper( fx_id, origin, forward, up )
|
||||
{
|
||||
assert( isdefined( level._effect[fx_id] ), "Missing level._effect[\"" + fx_id + "\"]. You did not setup the fx before calling it in createFx." );
|
||||
fx_object = spawnfx( level._effect[fx_id], origin, forward, up );
|
||||
return fx_object;
|
||||
}
|
8
MP/Core/maps/mp/_fxanim.gsc
Normal file
8
MP/Core/maps/mp/_fxanim.gsc
Normal file
@ -0,0 +1,8 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
|
||||
init()
|
||||
{
|
||||
level.scr_anim = [];
|
||||
level.scr_anim["fxanim_props"] = [];
|
||||
}
|
513
MP/Core/maps/mp/_gameadvertisement.gsc
Normal file
513
MP/Core/maps/mp/_gameadvertisement.gsc
Normal file
@ -0,0 +1,513 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_globallogic_utils;
|
||||
#include maps\mp\gametypes\_dev;
|
||||
|
||||
init()
|
||||
{
|
||||
/#
|
||||
level.sessionadvertstatus = 1;
|
||||
thread sessionadvertismentupdatedebughud();
|
||||
#/
|
||||
thread sessionadvertisementcheck();
|
||||
}
|
||||
|
||||
setadvertisedstatus( onoff )
|
||||
{
|
||||
/#
|
||||
level.sessionadvertstatus = onoff;
|
||||
#/
|
||||
changeadvertisedstatus( onoff );
|
||||
}
|
||||
|
||||
sessionadvertisementcheck()
|
||||
{
|
||||
if ( sessionmodeisprivate() )
|
||||
return;
|
||||
|
||||
if ( sessionmodeiszombiesgame() )
|
||||
{
|
||||
setadvertisedstatus( 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
runrules = getgametyperules();
|
||||
|
||||
if ( !isdefined( runrules ) )
|
||||
return;
|
||||
|
||||
level endon( "game_end" );
|
||||
|
||||
level waittill( "prematch_over" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
sessionadvertcheckwait = getdvarintdefault( "sessionAdvertCheckwait", 1 );
|
||||
wait( sessionadvertcheckwait );
|
||||
advertise = [[ runrules ]]();
|
||||
setadvertisedstatus( advertise );
|
||||
}
|
||||
}
|
||||
|
||||
getgametyperules()
|
||||
{
|
||||
gametype = level.gametype;
|
||||
|
||||
switch ( gametype )
|
||||
{
|
||||
case "dm":
|
||||
return ::dm_rules;
|
||||
case "tdm":
|
||||
return ::tdm_rules;
|
||||
case "dom":
|
||||
return ::dom_rules;
|
||||
case "hq":
|
||||
return ::hq_rules;
|
||||
case "sd":
|
||||
return ::sd_rules;
|
||||
case "dem":
|
||||
return ::dem_rules;
|
||||
case "ctf":
|
||||
return ::ctf_rules;
|
||||
case "koth":
|
||||
return ::koth_rules;
|
||||
case "conf":
|
||||
return ::conf_rules;
|
||||
case "oic":
|
||||
return ::oic_rules;
|
||||
case "sas":
|
||||
return ::sas_rules;
|
||||
case "gun":
|
||||
return ::gun_rules;
|
||||
case "shrp":
|
||||
return ::shrp_rules;
|
||||
}
|
||||
}
|
||||
|
||||
teamscorelimitcheck( rulescorepercent )
|
||||
{
|
||||
if ( level.scorelimit )
|
||||
{
|
||||
minscorepercentageleft = 100;
|
||||
|
||||
foreach ( team in level.teams )
|
||||
{
|
||||
scorepercentageleft = 100 - game["teamScores"][team] / level.scorelimit * 100;
|
||||
|
||||
if ( minscorepercentageleft > scorepercentageleft )
|
||||
minscorepercentageleft = scorepercentageleft;
|
||||
|
||||
if ( rulescorepercent >= scorepercentageleft )
|
||||
{
|
||||
/#
|
||||
updatedebughud( 3, "Score Percentage Left: ", int( scorepercentageleft ) );
|
||||
#/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/#
|
||||
updatedebughud( 3, "Score Percentage Left: ", int( minscorepercentageleft ) );
|
||||
#/
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
timelimitcheck( ruletimeleft )
|
||||
{
|
||||
maxtime = level.timelimit;
|
||||
|
||||
if ( maxtime != 0 )
|
||||
{
|
||||
timeleft = maps\mp\gametypes\_globallogic_utils::gettimeremaining();
|
||||
|
||||
if ( ruletimeleft >= timeleft )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
dm_rules()
|
||||
{
|
||||
rulescorepercent = 35;
|
||||
ruletimeleft = 60000 * 1.5;
|
||||
/#
|
||||
updatedebughud( 1, "Any player is within percent of score cap: ", rulescorepercent );
|
||||
updatedebughud( 2, "Time limit has less than minutes remaining: ", ruletimeleft / 60000 );
|
||||
#/
|
||||
if ( level.scorelimit )
|
||||
{
|
||||
highestscore = 0;
|
||||
players = get_players();
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
if ( players[i].pointstowin > highestscore )
|
||||
highestscore = players[i].pointstowin;
|
||||
}
|
||||
|
||||
scorepercentageleft = 100 - highestscore / level.scorelimit * 100;
|
||||
/#
|
||||
updatedebughud( 3, "Score Percentage Left: ", int( scorepercentageleft ) );
|
||||
#/
|
||||
if ( rulescorepercent >= scorepercentageleft )
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( timelimitcheck( ruletimeleft ) == 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
tdm_rules()
|
||||
{
|
||||
rulescorepercent = 15;
|
||||
ruletimeleft = 60000 * 1.5;
|
||||
/#
|
||||
updatedebughud( 1, "Any player is within percent of score cap: ", rulescorepercent );
|
||||
updatedebughud( 2, "Time limit has less than minutes remaining: ", ruletimeleft / 60000 );
|
||||
#/
|
||||
if ( teamscorelimitcheck( rulescorepercent ) == 0 )
|
||||
return false;
|
||||
|
||||
if ( timelimitcheck( ruletimeleft ) == 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
dom_rules()
|
||||
{
|
||||
rulescorepercent = 15;
|
||||
ruletimeleft = 60000 * 1.5;
|
||||
ruleround = 3;
|
||||
currentround = game["roundsplayed"] + 1;
|
||||
/#
|
||||
updatedebughud( 1, "Time limit 1.5 minutes remaining in final round. Any player is within percent of score cap: ", rulescorepercent );
|
||||
updatedebughud( 2, "Is round: ", ruleround );
|
||||
updatedebughud( 4, "Current Round: ", currentround );
|
||||
#/
|
||||
if ( currentround >= 2 )
|
||||
{
|
||||
if ( teamscorelimitcheck( rulescorepercent ) == 0 )
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( timelimitcheck( ruletimeleft ) == 0 )
|
||||
return false;
|
||||
|
||||
if ( ruleround <= currentround )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
hq_rules()
|
||||
{
|
||||
return koth_rules();
|
||||
}
|
||||
|
||||
sd_rules()
|
||||
{
|
||||
ruleround = 3;
|
||||
/#
|
||||
updatedebughud( 1, "Any team has won rounds: ", ruleround );
|
||||
#/
|
||||
maxroundswon = 0;
|
||||
|
||||
foreach ( team in level.teams )
|
||||
{
|
||||
roundswon = game["teamScores"][team];
|
||||
|
||||
if ( maxroundswon < roundswon )
|
||||
maxroundswon = roundswon;
|
||||
|
||||
if ( ruleround <= roundswon )
|
||||
{
|
||||
/#
|
||||
updatedebughud( 3, "Max Rounds Won: ", maxroundswon );
|
||||
#/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/#
|
||||
updatedebughud( 3, "Max Rounds Won: ", maxroundswon );
|
||||
#/
|
||||
return true;
|
||||
}
|
||||
|
||||
dem_rules()
|
||||
{
|
||||
return ctf_rules();
|
||||
}
|
||||
|
||||
ctf_rules()
|
||||
{
|
||||
ruleround = 3;
|
||||
roundsplayed = game["roundsplayed"];
|
||||
/#
|
||||
updatedebughud( 1, "Is round or later: ", ruleround );
|
||||
updatedebughud( 3, "Rounds Played: ", roundsplayed );
|
||||
#/
|
||||
if ( ruleround <= roundsplayed )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
koth_rules()
|
||||
{
|
||||
rulescorepercent = 20;
|
||||
ruletimeleft = 60000 * 1.5;
|
||||
/#
|
||||
updatedebughud( 1, "Any player is within percent of score cap: ", rulescorepercent );
|
||||
updatedebughud( 2, "Time limit has less than minutes remaining: ", ruletimeleft / 60000 );
|
||||
#/
|
||||
if ( teamscorelimitcheck( rulescorepercent ) == 0 )
|
||||
return false;
|
||||
|
||||
if ( timelimitcheck( ruletimeleft ) == 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
conf_rules()
|
||||
{
|
||||
return tdm_rules();
|
||||
}
|
||||
|
||||
oic_rules()
|
||||
{
|
||||
/#
|
||||
updatedebughud( 1, "No join in progress, so shouldn<64>t advertise to matchmaking once the countdown timer ends.", 0 );
|
||||
#/
|
||||
return 0;
|
||||
}
|
||||
|
||||
sas_rules()
|
||||
{
|
||||
rulescorepercent = 35;
|
||||
ruletimeleft = 60000 * 1.5;
|
||||
/#
|
||||
updatedebughud( 1, "Any player is within percent of score cap: ", rulescorepercent );
|
||||
updatedebughud( 2, "Time limit has less than minutes remaining: ", ruletimeleft / 60000 );
|
||||
#/
|
||||
if ( teamscorelimitcheck( rulescorepercent ) == 0 )
|
||||
return false;
|
||||
|
||||
if ( timelimitcheck( ruletimeleft ) == 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gun_rules()
|
||||
{
|
||||
ruleweaponsleft = 3;
|
||||
/#
|
||||
updatedebughud( 1, "Any player is within X weapons from winning: ", ruleweaponsleft );
|
||||
#/
|
||||
minweaponsleft = level.gunprogression.size;
|
||||
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
shrp_rules()
|
||||
{
|
||||
rulescorepercent = 35;
|
||||
ruletimeleft = 60000 * 1.5;
|
||||
/#
|
||||
updatedebughud( 1, "Any player is within percent of score cap: ", rulescorepercent );
|
||||
updatedebughud( 2, "Time limit has less than minutes remaining: ", ruletimeleft / 60000 );
|
||||
#/
|
||||
if ( teamscorelimitcheck( rulescorepercent ) == 0 )
|
||||
return false;
|
||||
|
||||
if ( timelimitcheck( ruletimeleft ) == 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
sessionadvertismentcreatedebughud( linenum, alignx )
|
||||
{
|
||||
/#
|
||||
debug_hud = maps\mp\gametypes\_dev::new_hud( "session_advert", "debug_hud", 0, 0, 1 );
|
||||
debug_hud.hidewheninmenu = 1;
|
||||
debug_hud.horzalign = "right";
|
||||
debug_hud.vertalign = "middle";
|
||||
debug_hud.alignx = "right";
|
||||
debug_hud.aligny = "middle";
|
||||
debug_hud.x = alignx;
|
||||
debug_hud.y = -50 + linenum * 15;
|
||||
debug_hud.foreground = 1;
|
||||
debug_hud.font = "default";
|
||||
debug_hud.fontscale = 1.5;
|
||||
debug_hud.color = ( 1, 1, 1 );
|
||||
debug_hud.alpha = 1;
|
||||
debug_hud settext( "" );
|
||||
return debug_hud;
|
||||
#/
|
||||
}
|
||||
|
||||
updatedebughud( hudindex, text, value )
|
||||
{
|
||||
/#
|
||||
switch ( hudindex )
|
||||
{
|
||||
case 1:
|
||||
level.sessionadverthud_1a_text = text;
|
||||
level.sessionadverthud_1b_text = value;
|
||||
break;
|
||||
case 2:
|
||||
level.sessionadverthud_2a_text = text;
|
||||
level.sessionadverthud_2b_text = value;
|
||||
break;
|
||||
case 3:
|
||||
level.sessionadverthud_3a_text = text;
|
||||
level.sessionadverthud_3b_text = value;
|
||||
break;
|
||||
case 4:
|
||||
level.sessionadverthud_4a_text = text;
|
||||
level.sessionadverthud_4b_text = value;
|
||||
break;
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
sessionadvertismentupdatedebughud()
|
||||
{
|
||||
/#
|
||||
level endon( "game_end" );
|
||||
sessionadverthud_0 = undefined;
|
||||
sessionadverthud_1a = undefined;
|
||||
sessionadverthud_1b = undefined;
|
||||
sessionadverthud_2a = undefined;
|
||||
sessionadverthud_2b = undefined;
|
||||
sessionadverthud_3a = undefined;
|
||||
sessionadverthud_3b = undefined;
|
||||
sessionadverthud_4a = undefined;
|
||||
sessionadverthud_4b = undefined;
|
||||
level.sessionadverthud_0_text = "";
|
||||
level.sessionadverthud_1a_text = "";
|
||||
level.sessionadverthud_1b_text = "";
|
||||
level.sessionadverthud_2a_text = "";
|
||||
level.sessionadverthud_2b_text = "";
|
||||
level.sessionadverthud_3a_text = "";
|
||||
level.sessionadverthud_3b_text = "";
|
||||
level.sessionadverthud_4a_text = "";
|
||||
level.sessionadverthud_4b_text = "";
|
||||
|
||||
while ( true )
|
||||
{
|
||||
wait 1;
|
||||
showdebughud = getdvarintdefault( "sessionAdvertShowDebugHud", 0 );
|
||||
level.sessionadverthud_0_text = "Session is advertised";
|
||||
|
||||
if ( level.sessionadvertstatus == 0 )
|
||||
level.sessionadverthud_0_text = "Session is not advertised";
|
||||
|
||||
if ( !isdefined( sessionadverthud_0 ) && showdebughud != 0 )
|
||||
{
|
||||
host = gethostplayer();
|
||||
|
||||
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 = vectorscale( ( 0, 1, 0 ), 0.5 );
|
||||
sessionadverthud_1b.color = vectorscale( ( 0, 1, 0 ), 0.5 );
|
||||
sessionadverthud_2a.color = vectorscale( ( 0, 1, 0 ), 0.5 );
|
||||
sessionadverthud_2b.color = vectorscale( ( 0, 1, 0 ), 0.5 );
|
||||
}
|
||||
|
||||
if ( isdefined( sessionadverthud_0 ) )
|
||||
{
|
||||
if ( showdebughud == 0 )
|
||||
{
|
||||
sessionadverthud_0 destroy();
|
||||
sessionadverthud_1a destroy();
|
||||
sessionadverthud_1b destroy();
|
||||
sessionadverthud_2a destroy();
|
||||
sessionadverthud_2b destroy();
|
||||
sessionadverthud_3a destroy();
|
||||
sessionadverthud_3b destroy();
|
||||
sessionadverthud_4a destroy();
|
||||
sessionadverthud_4b destroy();
|
||||
sessionadverthud_0 = undefined;
|
||||
sessionadverthud_1a = undefined;
|
||||
sessionadverthud_1b = undefined;
|
||||
sessionadverthud_2a = undefined;
|
||||
sessionadverthud_2b = undefined;
|
||||
sessionadverthud_3a = undefined;
|
||||
sessionadverthud_3b = undefined;
|
||||
sessionadverthud_4a = undefined;
|
||||
sessionadverthud_4b = undefined;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( level.sessionadvertstatus == 1 )
|
||||
sessionadverthud_0.color = ( 1, 1, 1 );
|
||||
else
|
||||
sessionadverthud_0.color = vectorscale( ( 1, 0, 0 ), 0.9 );
|
||||
|
||||
sessionadverthud_0 settext( level.sessionadverthud_0_text );
|
||||
|
||||
if ( level.sessionadverthud_1a_text != "" )
|
||||
{
|
||||
sessionadverthud_1a settext( level.sessionadverthud_1a_text );
|
||||
sessionadverthud_1b setvalue( level.sessionadverthud_1b_text );
|
||||
}
|
||||
|
||||
if ( level.sessionadverthud_2a_text != "" )
|
||||
{
|
||||
sessionadverthud_2a settext( level.sessionadverthud_2a_text );
|
||||
sessionadverthud_2b setvalue( level.sessionadverthud_2b_text );
|
||||
}
|
||||
|
||||
if ( level.sessionadverthud_3a_text != "" )
|
||||
{
|
||||
sessionadverthud_3a settext( level.sessionadverthud_3a_text );
|
||||
sessionadverthud_3b setvalue( level.sessionadverthud_3b_text );
|
||||
}
|
||||
|
||||
if ( level.sessionadverthud_4a_text != "" )
|
||||
{
|
||||
sessionadverthud_4a settext( level.sessionadverthud_4a_text );
|
||||
sessionadverthud_4b setvalue( level.sessionadverthud_4b_text );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#/
|
||||
}
|
370
MP/Core/maps/mp/_gamerep.gsc
Normal file
370
MP/Core/maps/mp/_gamerep.gsc
Normal file
@ -0,0 +1,370 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_rank;
|
||||
#include maps\mp\bots\_bot;
|
||||
|
||||
init()
|
||||
{
|
||||
if ( !isgamerepenabled() )
|
||||
return;
|
||||
|
||||
if ( isgamerepinitialized() )
|
||||
return;
|
||||
|
||||
game["gameRepInitialized"] = 1;
|
||||
game["gameRep"]["players"] = [];
|
||||
game["gameRep"]["playerNames"] = [];
|
||||
game["gameRep"]["max"] = [];
|
||||
game["gameRep"]["playerCount"] = 0;
|
||||
gamerepinitializeparams();
|
||||
}
|
||||
|
||||
isgamerepinitialized()
|
||||
{
|
||||
if ( !isdefined( game["gameRepInitialized"] ) || !game["gameRepInitialized"] )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
isgamerepenabled()
|
||||
{
|
||||
if ( maps\mp\bots\_bot::is_bot_ranked_match() )
|
||||
return false;
|
||||
|
||||
if ( sessionmodeiszombiesgame() )
|
||||
return false;
|
||||
|
||||
if ( !level.rankedmatch )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gamerepinitializeparams()
|
||||
{
|
||||
threshold_exceeded_score = 0;
|
||||
threshold_exceeded_score_per_min = 1;
|
||||
threshold_exceeded_kills = 2;
|
||||
threshold_exceeded_deaths = 3;
|
||||
threshold_exceeded_kd_ratio = 4;
|
||||
threshold_exceeded_kills_per_min = 5;
|
||||
threshold_exceeded_plants = 6;
|
||||
threshold_exceeded_defuses = 7;
|
||||
threshold_exceeded_captures = 8;
|
||||
threshold_exceeded_defends = 9;
|
||||
threshold_exceeded_total_time_played = 10;
|
||||
threshold_exceeded_tactical_insertion_use = 11;
|
||||
threshold_exceeded_join_attempts = 12;
|
||||
threshold_exceeded_xp = 13;
|
||||
threshold_exceeded_splitscreen = 14;
|
||||
game["gameRep"]["params"] = [];
|
||||
game["gameRep"]["params"][0] = "score";
|
||||
game["gameRep"]["params"][1] = "scorePerMin";
|
||||
game["gameRep"]["params"][2] = "kills";
|
||||
game["gameRep"]["params"][3] = "deaths";
|
||||
game["gameRep"]["params"][4] = "killDeathRatio";
|
||||
game["gameRep"]["params"][5] = "killsPerMin";
|
||||
game["gameRep"]["params"][6] = "plants";
|
||||
game["gameRep"]["params"][7] = "defuses";
|
||||
game["gameRep"]["params"][8] = "captures";
|
||||
game["gameRep"]["params"][9] = "defends";
|
||||
game["gameRep"]["params"][10] = "totalTimePlayed";
|
||||
game["gameRep"]["params"][11] = "tacticalInsertions";
|
||||
game["gameRep"]["params"][12] = "joinAttempts";
|
||||
game["gameRep"]["params"][13] = "xp";
|
||||
game["gameRep"]["ignoreParams"] = [];
|
||||
game["gameRep"]["ignoreParams"][0] = "totalTimePlayed";
|
||||
game["gameRep"]["gameLimit"] = [];
|
||||
game["gameRep"]["gameLimit"]["default"] = [];
|
||||
game["gameRep"]["gameLimit"]["tdm"] = [];
|
||||
game["gameRep"]["gameLimit"]["dm"] = [];
|
||||
game["gameRep"]["gameLimit"]["dom"] = [];
|
||||
game["gameRep"]["gameLimit"]["hq"] = [];
|
||||
game["gameRep"]["gameLimit"]["sd"] = [];
|
||||
game["gameRep"]["gameLimit"]["dem"] = [];
|
||||
game["gameRep"]["gameLimit"]["ctf"] = [];
|
||||
game["gameRep"]["gameLimit"]["koth"] = [];
|
||||
game["gameRep"]["gameLimit"]["conf"] = [];
|
||||
game["gameRep"]["gameLimit"]["id"]["score"] = threshold_exceeded_score;
|
||||
game["gameRep"]["gameLimit"]["default"]["score"] = 20000;
|
||||
game["gameRep"]["gameLimit"]["id"]["scorePerMin"] = threshold_exceeded_score_per_min;
|
||||
game["gameRep"]["gameLimit"]["default"]["scorePerMin"] = 250;
|
||||
game["gameRep"]["gameLimit"]["dem"]["scorePerMin"] = 1000;
|
||||
game["gameRep"]["gameLimit"]["tdm"]["scorePerMin"] = 700;
|
||||
game["gameRep"]["gameLimit"]["dm"]["scorePerMin"] = 950;
|
||||
game["gameRep"]["gameLimit"]["dom"]["scorePerMin"] = 1000;
|
||||
game["gameRep"]["gameLimit"]["sd"]["scorePerMin"] = 200;
|
||||
game["gameRep"]["gameLimit"]["ctf"]["scorePerMin"] = 600;
|
||||
game["gameRep"]["gameLimit"]["hq"]["scorePerMin"] = 1000;
|
||||
game["gameRep"]["gameLimit"]["koth"]["scorePerMin"] = 1000;
|
||||
game["gameRep"]["gameLimit"]["conf"]["scorePerMin"] = 1000;
|
||||
game["gameRep"]["gameLimit"]["id"]["kills"] = threshold_exceeded_kills;
|
||||
game["gameRep"]["gameLimit"]["default"]["kills"] = 75;
|
||||
game["gameRep"]["gameLimit"]["tdm"]["kills"] = 40;
|
||||
game["gameRep"]["gameLimit"]["sd"]["kills"] = 15;
|
||||
game["gameRep"]["gameLimit"]["dm"]["kills"] = 31;
|
||||
game["gameRep"]["gameLimit"]["id"]["deaths"] = threshold_exceeded_deaths;
|
||||
game["gameRep"]["gameLimit"]["default"]["deaths"] = 50;
|
||||
game["gameRep"]["gameLimit"]["dm"]["deaths"] = 15;
|
||||
game["gameRep"]["gameLimit"]["tdm"]["deaths"] = 40;
|
||||
game["gameRep"]["gameLimit"]["id"]["killDeathRatio"] = threshold_exceeded_kd_ratio;
|
||||
game["gameRep"]["gameLimit"]["default"]["killDeathRatio"] = 30;
|
||||
game["gameRep"]["gameLimit"]["tdm"]["killDeathRatio"] = 50;
|
||||
game["gameRep"]["gameLimit"]["sd"]["killDeathRatio"] = 20;
|
||||
game["gameRep"]["gameLimit"]["id"]["killsPerMin"] = threshold_exceeded_kills_per_min;
|
||||
game["gameRep"]["gameLimit"]["default"]["killsPerMin"] = 15;
|
||||
game["gameRep"]["gameLimit"]["id"]["plants"] = threshold_exceeded_plants;
|
||||
game["gameRep"]["gameLimit"]["default"]["plants"] = 10;
|
||||
game["gameRep"]["gameLimit"]["id"]["defuses"] = threshold_exceeded_defuses;
|
||||
game["gameRep"]["gameLimit"]["default"]["defuses"] = 10;
|
||||
game["gameRep"]["gameLimit"]["id"]["captures"] = threshold_exceeded_captures;
|
||||
game["gameRep"]["gameLimit"]["default"]["captures"] = 30;
|
||||
game["gameRep"]["gameLimit"]["id"]["defends"] = threshold_exceeded_defends;
|
||||
game["gameRep"]["gameLimit"]["default"]["defends"] = 50;
|
||||
game["gameRep"]["gameLimit"]["id"]["totalTimePlayed"] = threshold_exceeded_total_time_played;
|
||||
game["gameRep"]["gameLimit"]["default"]["totalTimePlayed"] = 600;
|
||||
game["gameRep"]["gameLimit"]["dom"]["totalTimePlayed"] = 600;
|
||||
game["gameRep"]["gameLimit"]["dem"]["totalTimePlayed"] = 1140;
|
||||
game["gameRep"]["gameLimit"]["id"]["tacticalInsertions"] = threshold_exceeded_tactical_insertion_use;
|
||||
game["gameRep"]["gameLimit"]["default"]["tacticalInsertions"] = 20;
|
||||
game["gameRep"]["gameLimit"]["id"]["joinAttempts"] = threshold_exceeded_join_attempts;
|
||||
game["gameRep"]["gameLimit"]["default"]["joinAttempts"] = 3;
|
||||
game["gameRep"]["gameLimit"]["id"]["xp"] = threshold_exceeded_xp;
|
||||
game["gameRep"]["gameLimit"]["default"]["xp"] = 25000;
|
||||
game["gameRep"]["gameLimit"]["id"]["splitscreen"] = threshold_exceeded_splitscreen;
|
||||
game["gameRep"]["gameLimit"]["default"]["splitscreen"] = 8;
|
||||
}
|
||||
|
||||
gamerepplayerconnected()
|
||||
{
|
||||
if ( !isgamerepenabled() )
|
||||
return;
|
||||
|
||||
name = self.name;
|
||||
/#
|
||||
|
||||
#/
|
||||
if ( !isdefined( game["gameRep"]["players"][name] ) )
|
||||
{
|
||||
game["gameRep"]["players"][name] = [];
|
||||
|
||||
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"] = 1;
|
||||
game["gameRep"]["players"][name]["xpStart"] = self getrankxpstat();
|
||||
game["gameRep"]["playerNames"][game["gameRep"]["playerCount"]] = name;
|
||||
game["gameRep"]["playerCount"]++;
|
||||
}
|
||||
else if ( !game["gameRep"]["players"][name]["connected"] )
|
||||
{
|
||||
game["gameRep"]["players"][name]["joinAttempts"]++;
|
||||
game["gameRep"]["players"][name]["connected"] = 1;
|
||||
game["gameRep"]["players"][name]["xpStart"] = self getrankxpstat();
|
||||
}
|
||||
}
|
||||
|
||||
gamerepplayerdisconnected()
|
||||
{
|
||||
if ( !isgamerepenabled() )
|
||||
return;
|
||||
|
||||
name = self.name;
|
||||
|
||||
if ( !isdefined( game["gameRep"]["players"][name] ) || !isdefined( self.pers["summary"] ) )
|
||||
return;
|
||||
/#
|
||||
|
||||
#/
|
||||
self gamerepupdatenonpersistentplayerinformation();
|
||||
self gamerepupdatepersistentplayerinformation();
|
||||
game["gameRep"]["players"][name]["connected"] = 0;
|
||||
}
|
||||
|
||||
gamerepupdatenonpersistentplayerinformation()
|
||||
{
|
||||
name = self.name;
|
||||
|
||||
if ( !isdefined( game["gameRep"]["players"][name] ) )
|
||||
return;
|
||||
|
||||
game["gameRep"]["players"][name]["totalTimePlayed"] += self.timeplayed["total"];
|
||||
|
||||
if ( isdefined( self.tacticalinsertioncount ) )
|
||||
game["gameRep"]["players"][name]["tacticalInsertions"] += self.tacticalinsertioncount;
|
||||
}
|
||||
|
||||
gamerepupdatepersistentplayerinformation()
|
||||
{
|
||||
name = self.name;
|
||||
|
||||
if ( !isdefined( game["gameRep"]["players"][name] ) )
|
||||
return;
|
||||
|
||||
if ( game["gameRep"]["players"][name]["totalTimePlayed"] != 0 )
|
||||
timeplayed = game["gameRep"]["players"][name]["totalTimePlayed"];
|
||||
else
|
||||
timeplayed = 1;
|
||||
|
||||
game["gameRep"]["players"][name]["score"] = self.score;
|
||||
game["gameRep"]["players"][name]["scorePerMin"] = int( game["gameRep"]["players"][name]["score"] / ( timeplayed / 60 ) );
|
||||
game["gameRep"]["players"][name]["kills"] = self.kills;
|
||||
game["gameRep"]["players"][name]["deaths"] = self.deaths;
|
||||
|
||||
if ( game["gameRep"]["players"][name]["deaths"] != 0 )
|
||||
game["gameRep"]["players"][name]["killDeathRatio"] = int( game["gameRep"]["players"][name]["kills"] / game["gameRep"]["players"][name]["deaths"] * 100 );
|
||||
else
|
||||
game["gameRep"]["players"][name]["killDeathRatio"] = game["gameRep"]["players"][name]["kills"] * 100;
|
||||
|
||||
game["gameRep"]["players"][name]["killsPerMin"] = int( game["gameRep"]["players"][name]["kills"] / ( timeplayed / 60 ) );
|
||||
game["gameRep"]["players"][name]["plants"] = self.plants;
|
||||
game["gameRep"]["players"][name]["defuses"] = self.defuses;
|
||||
game["gameRep"]["players"][name]["captures"] = self.captures;
|
||||
game["gameRep"]["players"][name]["defends"] = self.defends;
|
||||
game["gameRep"]["players"][name]["xp"] = self getrankxpstat() - game["gameRep"]["players"][name]["xpStart"];
|
||||
game["gameRep"]["players"][name]["xpStart"] = self getrankxpstat();
|
||||
}
|
||||
|
||||
getparamvalueforplayer( playername, paramname )
|
||||
{
|
||||
if ( isdefined( game["gameRep"]["players"][playername][paramname] ) )
|
||||
return game["gameRep"]["players"][playername][paramname];
|
||||
/#
|
||||
assertmsg( "Unknown parameter " + paramname + "for individual player" );
|
||||
#/
|
||||
}
|
||||
|
||||
isgamerepparamvalid( paramname )
|
||||
{
|
||||
gametype = level.gametype;
|
||||
|
||||
if ( !isdefined( game["gameRep"] ) )
|
||||
return false;
|
||||
|
||||
if ( !isdefined( game["gameRep"]["gameLimit"] ) )
|
||||
return false;
|
||||
|
||||
if ( !isdefined( game["gameRep"]["gameLimit"][gametype] ) )
|
||||
return false;
|
||||
|
||||
if ( !isdefined( game["gameRep"]["gameLimit"][gametype][paramname] ) && !isdefined( game["gameRep"]["gameLimit"]["default"][paramname] ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
isgamerepparamignoredforreporting( paramname )
|
||||
{
|
||||
if ( isdefined( game["gameRep"]["ignoreParams"][paramname] ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
getgamerepparamlimit( paramname )
|
||||
{
|
||||
gametype = level.gametype;
|
||||
|
||||
if ( isdefined( game["gameRep"]["gameLimit"][gametype] ) )
|
||||
{
|
||||
if ( isdefined( game["gameRep"]["gameLimit"][gametype][paramname] ) )
|
||||
return game["gameRep"]["gameLimit"][gametype][paramname];
|
||||
}
|
||||
|
||||
if ( isdefined( game["gameRep"]["gameLimit"]["default"][paramname] ) )
|
||||
return game["gameRep"]["gameLimit"]["default"][paramname];
|
||||
/#
|
||||
assertmsg( "Default values for parameter " + paramname + " is not defined." );
|
||||
#/
|
||||
}
|
||||
|
||||
setmaximumparamvalueforcurrentgame( paramname, value )
|
||||
{
|
||||
if ( !isdefined( game["gameRep"]["max"][paramname] ) )
|
||||
{
|
||||
game["gameRep"]["max"][paramname] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( game["gameRep"]["max"][paramname] < value )
|
||||
game["gameRep"]["max"][paramname] = value;
|
||||
}
|
||||
|
||||
gamerepupdateinformationforround()
|
||||
{
|
||||
if ( !isgamerepenabled() )
|
||||
return;
|
||||
|
||||
players = get_players();
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
player = players[i];
|
||||
player gamerepupdatenonpersistentplayerinformation();
|
||||
}
|
||||
}
|
||||
|
||||
gamerepanalyzeandreport()
|
||||
{
|
||||
if ( !isgamerepenabled() )
|
||||
return;
|
||||
|
||||
players = get_players();
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
player = players[i];
|
||||
player gamerepupdatepersistentplayerinformation();
|
||||
}
|
||||
|
||||
splitscreenplayercount = 0;
|
||||
|
||||
for ( i = 0; i < game["gameRep"]["playerNames"].size; i++ )
|
||||
{
|
||||
playername = game["gameRep"]["playerNames"][i];
|
||||
|
||||
for ( j = 0; j < game["gameRep"]["params"].size; j++ )
|
||||
{
|
||||
paramname = game["gameRep"]["params"][j];
|
||||
|
||||
if ( isgamerepparamvalid( paramname ) )
|
||||
setmaximumparamvalueforcurrentgame( paramname, getparamvalueforplayer( playername, paramname ) );
|
||||
}
|
||||
|
||||
paramname = "splitscreen";
|
||||
splitscreenplayercount += getparamvalueforplayer( playername, paramname );
|
||||
}
|
||||
|
||||
setmaximumparamvalueforcurrentgame( paramname, splitscreenplayercount );
|
||||
|
||||
for ( j = 0; j < game["gameRep"]["params"].size; j++ )
|
||||
{
|
||||
paramname = game["gameRep"]["params"][j];
|
||||
|
||||
if ( isgamerepparamvalid( paramname ) && game["gameRep"]["max"][paramname] >= getgamerepparamlimit( paramname ) )
|
||||
gamerepprepareandreport( paramname );
|
||||
}
|
||||
|
||||
paramname = "splitscreen";
|
||||
|
||||
if ( game["gameRep"]["max"][paramname] >= getgamerepparamlimit( paramname ) )
|
||||
gamerepprepareandreport( paramname );
|
||||
}
|
||||
|
||||
gamerepprepareandreport( paramname )
|
||||
{
|
||||
if ( !isdefined( game["gameRep"]["gameLimit"]["id"][paramname] ) )
|
||||
return;
|
||||
|
||||
if ( isgamerepparamignoredforreporting( paramname ) )
|
||||
return;
|
||||
|
||||
gamerepthresholdexceeded( game["gameRep"]["gameLimit"]["id"][paramname] );
|
||||
}
|
53
MP/Core/maps/mp/_global_fx.gsc
Normal file
53
MP/Core/maps/mp/_global_fx.gsc
Normal file
@ -0,0 +1,53 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
|
||||
main()
|
||||
{
|
||||
randomstartdelay = randomfloatrange( -20, -15 );
|
||||
global_fx( "barrel_fireFX_origin", "global_barrel_fire", "fire/firelp_barrel_pm", randomstartdelay, "fire_barrel_small" );
|
||||
global_fx( "ch_streetlight_02_FX_origin", "ch_streetlight_02_FX", "misc/lighthaze", randomstartdelay );
|
||||
global_fx( "me_streetlight_01_FX_origin", "me_streetlight_01_FX", "misc/lighthaze_bog_a", randomstartdelay );
|
||||
global_fx( "ch_street_light_01_on", "lamp_glow_FX", "misc/light_glow_white", randomstartdelay );
|
||||
global_fx( "highway_lamp_post", "ch_streetlight_02_FX", "misc/lighthaze_villassault", randomstartdelay );
|
||||
global_fx( "cs_cargoship_spotlight_on_FX_origin", "cs_cargoship_spotlight_on_FX", "misc/lighthaze", randomstartdelay );
|
||||
global_fx( "me_dumpster_fire_FX_origin", "me_dumpster_fire_FX", "fire/firelp_med_pm_nodistort", randomstartdelay, "fire_dumpster_medium" );
|
||||
global_fx( "com_tires_burning01_FX_origin", "com_tires_burning01_FX", "fire/tire_fire_med", randomstartdelay );
|
||||
global_fx( "icbm_powerlinetower_FX_origin", "icbm_powerlinetower_FX", "misc/power_tower_light_red_blink", randomstartdelay );
|
||||
}
|
||||
|
||||
global_fx( targetname, fxname, fxfile, delay, soundalias )
|
||||
{
|
||||
ents = getstructarray( targetname, "targetname" );
|
||||
|
||||
if ( !isdefined( ents ) )
|
||||
return;
|
||||
|
||||
if ( ents.size <= 0 )
|
||||
return;
|
||||
|
||||
for ( i = 0; i < ents.size; i++ )
|
||||
ents[i] global_fx_create( fxname, fxfile, delay, soundalias );
|
||||
}
|
||||
|
||||
global_fx_create( fxname, fxfile, delay, soundalias )
|
||||
{
|
||||
if ( !isdefined( level._effect ) )
|
||||
level._effect = [];
|
||||
|
||||
if ( !isdefined( level._effect[fxname] ) )
|
||||
level._effect[fxname] = loadfx( fxfile );
|
||||
|
||||
if ( !isdefined( self.angles ) )
|
||||
self.angles = ( 0, 0, 0 );
|
||||
|
||||
ent = createoneshoteffect( fxname );
|
||||
ent.v["origin"] = self.origin;
|
||||
ent.v["angles"] = self.angles;
|
||||
ent.v["fxid"] = fxname;
|
||||
ent.v["delay"] = delay;
|
||||
|
||||
if ( isdefined( soundalias ) )
|
||||
ent.v["soundalias"] = soundalias;
|
||||
}
|
716
MP/Core/maps/mp/_hacker_tool.gsc
Normal file
716
MP/Core/maps/mp/_hacker_tool.gsc
Normal file
@ -0,0 +1,716 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
#include maps\mp\_heatseekingmissile;
|
||||
#include maps\mp\killstreaks\_supplydrop;
|
||||
#include maps\mp\gametypes\_weaponobjects;
|
||||
|
||||
init()
|
||||
{
|
||||
level.hackertoolmaxequipmentdistance = 2000;
|
||||
level.hackertoolmaxequipmentdistancesq = level.hackertoolmaxequipmentdistance * level.hackertoolmaxequipmentdistance;
|
||||
level.hackertoolnosighthackdistance = 750;
|
||||
level.hackertoollostsightlimitms = 450;
|
||||
level.hackertoollockonradius = 20;
|
||||
level.hackertoollockonfov = 65;
|
||||
level.hackertoolhacktimems = 0.5;
|
||||
level.equipmenthackertoolradius = 60;
|
||||
level.equipmenthackertooltimems = 50;
|
||||
level.carepackagehackertoolradius = 60;
|
||||
level.carepackagehackertooltimems = getgametypesetting( "crateCaptureTime" ) * 500;
|
||||
level.carepackagefriendlyhackertooltimems = getgametypesetting( "crateCaptureTime" ) * 2000;
|
||||
level.carepackageownerhackertooltimems = 250;
|
||||
level.sentryhackertoolradius = 80;
|
||||
level.sentryhackertooltimems = 4000;
|
||||
level.microwavehackertoolradius = 80;
|
||||
level.microwavehackertooltimems = 4000;
|
||||
level.vehiclehackertoolradius = 80;
|
||||
level.vehiclehackertooltimems = 4000;
|
||||
level.rcxdhackertooltimems = 1500;
|
||||
level.rcxdhackertoolradius = 20;
|
||||
level.uavhackertooltimems = 4000;
|
||||
level.uavhackertoolradius = 40;
|
||||
level.cuavhackertooltimems = 4000;
|
||||
level.cuavhackertoolradius = 40;
|
||||
level.carepackagechopperhackertooltimems = 3000;
|
||||
level.carepackagechopperhackertoolradius = 60;
|
||||
level.littlebirdhackertooltimems = 4000;
|
||||
level.littlebirdhackertoolradius = 80;
|
||||
level.qrdronehackertooltimems = 3000;
|
||||
level.qrdronehackertoolradius = 60;
|
||||
level.aitankhackertooltimems = 4000;
|
||||
level.aitankhackertoolradius = 60;
|
||||
level.stealthchopperhackertooltimems = 4000;
|
||||
level.stealthchopperhackertoolradius = 80;
|
||||
level.warthoghackertooltimems = 4000;
|
||||
level.warthoghackertoolradius = 80;
|
||||
level.lodestarhackertooltimems = 4000;
|
||||
level.lodestarhackertoolradius = 60;
|
||||
level.choppergunnerhackertooltimems = 4000;
|
||||
level.choppergunnerhackertoolradius = 260;
|
||||
thread onplayerconnect();
|
||||
}
|
||||
|
||||
onplayerconnect()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
level waittill( "connecting", player );
|
||||
|
||||
player thread onplayerspawned();
|
||||
}
|
||||
}
|
||||
|
||||
onplayerspawned()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
|
||||
self clearhackertarget();
|
||||
self thread watchhackertooluse();
|
||||
self thread watchhackertoolfired();
|
||||
}
|
||||
}
|
||||
|
||||
clearhackertarget()
|
||||
{
|
||||
self notify( "stop_lockon_sound" );
|
||||
self notify( "stop_locked_sound" );
|
||||
self.stingerlocksound = undefined;
|
||||
self stoprumble( "stinger_lock_rumble" );
|
||||
self.hackertoollockstarttime = 0;
|
||||
self.hackertoollockstarted = 0;
|
||||
self.hackertoollockfinalized = 0;
|
||||
self.hackertoollocktimeelapsed = 0.0;
|
||||
self setweaponheatpercent( "pda_hack_mp", 0.0 );
|
||||
|
||||
if ( isdefined( self.hackertooltarget ) )
|
||||
{
|
||||
lockingon( self.hackertooltarget, 0 );
|
||||
lockedon( self.hackertooltarget, 0 );
|
||||
}
|
||||
|
||||
self.hackertooltarget = undefined;
|
||||
self weaponlockfree();
|
||||
self weaponlocktargettooclose( 0 );
|
||||
self weaponlocknoclearance( 0 );
|
||||
self stoplocalsound( game["locking_on_sound"] );
|
||||
self stoplocalsound( game["locked_on_sound"] );
|
||||
self destroylockoncanceledmessage();
|
||||
}
|
||||
|
||||
watchhackertoolfired()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self waittill( "hacker_tool_fired", hackertooltarget );
|
||||
|
||||
if ( isdefined( hackertooltarget ) )
|
||||
{
|
||||
if ( isentityhackablecarepackage( hackertooltarget ) )
|
||||
{
|
||||
maps\mp\killstreaks\_supplydrop::givecratecapturemedal( hackertooltarget, self );
|
||||
hackertooltarget notify( "captured", self, 1 );
|
||||
}
|
||||
|
||||
if ( isentityhackableweaponobject( hackertooltarget ) || isdefined( hackertooltarget.hackertrigger ) )
|
||||
hackertooltarget.hackertrigger notify( "trigger", self, 1 );
|
||||
else
|
||||
{
|
||||
if ( isdefined( hackertooltarget.classname ) && hackertooltarget.classname == "grenade" )
|
||||
damage = 1;
|
||||
else if ( isdefined( hackertooltarget.maxhealth ) )
|
||||
damage = hackertooltarget.maxhealth + 1;
|
||||
else
|
||||
damage = 999999;
|
||||
|
||||
if ( isdefined( hackertooltarget.numflares ) && hackertooltarget.numflares > 0 )
|
||||
{
|
||||
damage = 1;
|
||||
hackertooltarget.numflares--;
|
||||
hackertooltarget maps\mp\_heatseekingmissile::missiletarget_playflarefx();
|
||||
}
|
||||
|
||||
hackertooltarget dodamage( damage, self.origin, self, self, 0, "MOD_UNKNOWN", 0, "pda_hack_mp" );
|
||||
}
|
||||
|
||||
self addplayerstat( "hack_enemy_target", 1 );
|
||||
self addweaponstat( "pda_hack_mp", "used", 1 );
|
||||
}
|
||||
|
||||
clearhackertarget();
|
||||
self forceoffhandend();
|
||||
clip_ammo = self getweaponammoclip( "pda_hack_mp" );
|
||||
clip_ammo--;
|
||||
assert( clip_ammo >= 0 );
|
||||
self setweaponammoclip( "pda_hack_mp", clip_ammo );
|
||||
self switchtoweapon( self getlastweapon() );
|
||||
}
|
||||
}
|
||||
|
||||
watchhackertooluse()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "grenade_pullback", weapon );
|
||||
|
||||
if ( weapon == "pda_hack_mp" )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( self isusingoffhand() && self getcurrentoffhand() == "pda_hack_mp" )
|
||||
{
|
||||
self thread hackertooltargetloop();
|
||||
self thread watchhackertoolend();
|
||||
self thread watchforgrenadefire();
|
||||
self thread watchhackertoolinterrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watchhackertoolinterrupt()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "hacker_tool_fired" );
|
||||
self endon( "death" );
|
||||
self endon( "weapon_change" );
|
||||
self endon( "grenade_fire" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
level waittill( "use_interrupt", interrupttarget );
|
||||
|
||||
if ( self.hackertooltarget == interrupttarget )
|
||||
clearhackertarget();
|
||||
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
watchhackertoolend()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "hacker_tool_fired" );
|
||||
msg = self waittill_any_return( "weapon_change", "death" );
|
||||
clearhackertarget();
|
||||
}
|
||||
|
||||
watchforgrenadefire()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "hacker_tool_fired" );
|
||||
self endon( "weapon_change" );
|
||||
self endon( "death" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self waittill( "grenade_fire", grenade, grenadename, respawnfromhack );
|
||||
|
||||
if ( isdefined( respawnfromhack ) && respawnfromhack )
|
||||
continue;
|
||||
|
||||
clearhackertarget();
|
||||
clip_ammo = self getweaponammoclip( "pda_hack_mp" );
|
||||
clip_max_ammo = weaponclipsize( "pda_hack_mp" );
|
||||
|
||||
if ( clip_ammo < clip_max_ammo )
|
||||
clip_ammo++;
|
||||
|
||||
self setweaponammoclip( "pda_hack_mp", clip_ammo );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hackertooltargetloop()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self endon( "weapon_change" );
|
||||
self endon( "grenade_fire" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( self.hackertoollockfinalized )
|
||||
{
|
||||
if ( !self isvalidhackertooltarget( self.hackertooltarget ) )
|
||||
{
|
||||
self clearhackertarget();
|
||||
continue;
|
||||
}
|
||||
|
||||
passed = self hackersoftsighttest();
|
||||
|
||||
if ( !passed )
|
||||
continue;
|
||||
|
||||
lockingon( self.hackertooltarget, 0 );
|
||||
lockedon( self.hackertooltarget, 1 );
|
||||
thread looplocallocksound( game["locked_on_sound"], 0.75 );
|
||||
self notify( "hacker_tool_fired", self.hackertooltarget );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( self.hackertoollockstarted )
|
||||
{
|
||||
if ( !self isvalidhackertooltarget( self.hackertooltarget ) )
|
||||
{
|
||||
self clearhackertarget();
|
||||
continue;
|
||||
}
|
||||
|
||||
locklengthms = self gethacktime( self.hackertooltarget );
|
||||
|
||||
if ( locklengthms == 0 )
|
||||
{
|
||||
self clearhackertarget();
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( self.hackertoollocktimeelapsed == 0.0 )
|
||||
self playlocalsound( "evt_hacker_hacking" );
|
||||
|
||||
lockingon( self.hackertooltarget, 1 );
|
||||
lockedon( self.hackertooltarget, 0 );
|
||||
passed = self hackersoftsighttest();
|
||||
|
||||
if ( !passed )
|
||||
continue;
|
||||
|
||||
if ( self.hackertoollostsightlinetime == 0 )
|
||||
{
|
||||
self.hackertoollocktimeelapsed += 0.05;
|
||||
hackpercentage = self.hackertoollocktimeelapsed / ( locklengthms / 1000 );
|
||||
self setweaponheatpercent( "pda_hack_mp", hackpercentage );
|
||||
}
|
||||
|
||||
if ( self.hackertoollocktimeelapsed < locklengthms / 1000 )
|
||||
continue;
|
||||
|
||||
assert( isdefined( self.hackertooltarget ) );
|
||||
self notify( "stop_lockon_sound" );
|
||||
self.hackertoollockfinalized = 1;
|
||||
self weaponlockfinalize( self.hackertooltarget );
|
||||
continue;
|
||||
}
|
||||
|
||||
besttarget = self getbesthackertooltarget();
|
||||
|
||||
if ( !isdefined( besttarget ) )
|
||||
{
|
||||
self destroylockoncanceledmessage();
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !self locksighttest( besttarget ) && distance2d( self.origin, besttarget.origin ) > level.hackertoolnosighthackdistance )
|
||||
{
|
||||
self destroylockoncanceledmessage();
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( self locksighttest( besttarget ) && isdefined( besttarget.lockondelay ) && besttarget.lockondelay )
|
||||
{
|
||||
self displaylockoncanceledmessage();
|
||||
continue;
|
||||
}
|
||||
|
||||
self destroylockoncanceledmessage();
|
||||
initlockfield( besttarget );
|
||||
self.hackertooltarget = besttarget;
|
||||
self.hackertoollockstarttime = gettime();
|
||||
self.hackertoollockstarted = 1;
|
||||
self.hackertoollostsightlinetime = 0;
|
||||
self.hackertoollocktimeelapsed = 0.0;
|
||||
self setweaponheatpercent( "pda_hack_mp", 0.0 );
|
||||
self thread looplocalseeksound( game["locking_on_sound"], 0.6 );
|
||||
}
|
||||
}
|
||||
|
||||
getbesthackertooltarget()
|
||||
{
|
||||
targetsvalid = [];
|
||||
targetsall = arraycombine( target_getarray(), level.missileentities, 0, 0 );
|
||||
targetsall = arraycombine( targetsall, level.hackertooltargets, 0, 0 );
|
||||
|
||||
for ( idx = 0; idx < targetsall.size; idx++ )
|
||||
{
|
||||
target_ent = targetsall[idx];
|
||||
|
||||
if ( !isdefined( target_ent ) || !isdefined( target_ent.owner ) )
|
||||
continue;
|
||||
/#
|
||||
if ( getdvar( "scr_freelock" ) == "1" )
|
||||
{
|
||||
if ( self iswithinhackertoolreticle( targetsall[idx] ) )
|
||||
targetsvalid[targetsvalid.size] = targetsall[idx];
|
||||
|
||||
continue;
|
||||
}
|
||||
#/
|
||||
if ( level.teambased )
|
||||
{
|
||||
if ( isentityhackablecarepackage( target_ent ) )
|
||||
{
|
||||
if ( self iswithinhackertoolreticle( target_ent ) )
|
||||
targetsvalid[targetsvalid.size] = target_ent;
|
||||
}
|
||||
else if ( isdefined( target_ent.team ) )
|
||||
{
|
||||
if ( target_ent.team != self.team )
|
||||
{
|
||||
if ( self iswithinhackertoolreticle( target_ent ) )
|
||||
targetsvalid[targetsvalid.size] = target_ent;
|
||||
}
|
||||
}
|
||||
else if ( isdefined( target_ent.owner.team ) )
|
||||
{
|
||||
if ( target_ent.owner.team != self.team )
|
||||
{
|
||||
if ( self iswithinhackertoolreticle( target_ent ) )
|
||||
targetsvalid[targetsvalid.size] = target_ent;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( self iswithinhackertoolreticle( target_ent ) )
|
||||
{
|
||||
if ( isentityhackablecarepackage( target_ent ) )
|
||||
{
|
||||
targetsvalid[targetsvalid.size] = target_ent;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isdefined( target_ent.owner ) && self != target_ent.owner )
|
||||
targetsvalid[targetsvalid.size] = target_ent;
|
||||
}
|
||||
}
|
||||
|
||||
chosenent = undefined;
|
||||
|
||||
if ( targetsvalid.size != 0 )
|
||||
chosenent = targetsvalid[0];
|
||||
|
||||
return chosenent;
|
||||
}
|
||||
|
||||
iswithinhackertoolreticle( target )
|
||||
{
|
||||
radius = gethackertoolradius( target );
|
||||
return target_isincircle( target, self, level.hackertoollockonfov, radius, 0.0 );
|
||||
}
|
||||
|
||||
isentityhackableweaponobject( entity )
|
||||
{
|
||||
if ( isdefined( entity.classname ) && entity.classname == "grenade" )
|
||||
{
|
||||
if ( isdefined( entity.name ) )
|
||||
{
|
||||
watcher = maps\mp\gametypes\_weaponobjects::getweaponobjectwatcherbyweapon( entity.name );
|
||||
|
||||
if ( isdefined( watcher ) )
|
||||
{
|
||||
if ( watcher.hackable )
|
||||
{
|
||||
/#
|
||||
assert( isdefined( watcher.hackertoolradius ) );
|
||||
assert( isdefined( watcher.hackertooltimems ) );
|
||||
#/
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
getweaponobjecthackerradius( entity )
|
||||
{
|
||||
/#
|
||||
assert( isdefined( entity.classname ) );
|
||||
assert( isdefined( entity.name ) );
|
||||
#/
|
||||
watcher = maps\mp\gametypes\_weaponobjects::getweaponobjectwatcherbyweapon( entity.name );
|
||||
/#
|
||||
assert( watcher.hackable );
|
||||
assert( isdefined( watcher.hackertoolradius ) );
|
||||
#/
|
||||
return watcher.hackertoolradius;
|
||||
}
|
||||
|
||||
getweaponobjecthacktimems( entity )
|
||||
{
|
||||
/#
|
||||
assert( isdefined( entity.classname ) );
|
||||
assert( isdefined( entity.name ) );
|
||||
#/
|
||||
watcher = maps\mp\gametypes\_weaponobjects::getweaponobjectwatcherbyweapon( entity.name );
|
||||
/#
|
||||
assert( watcher.hackable );
|
||||
assert( isdefined( watcher.hackertooltimems ) );
|
||||
#/
|
||||
return watcher.hackertooltimems;
|
||||
}
|
||||
|
||||
isentityhackablecarepackage( entity )
|
||||
{
|
||||
if ( isdefined( entity.model ) )
|
||||
return entity.model == "t6_wpn_supply_drop_ally";
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
isvalidhackertooltarget( ent )
|
||||
{
|
||||
if ( !isdefined( ent ) )
|
||||
return false;
|
||||
|
||||
if ( self isusingremote() )
|
||||
return false;
|
||||
|
||||
if ( self isempjammed() )
|
||||
return false;
|
||||
|
||||
if ( !target_istarget( ent ) && !isentityhackableweaponobject( ent ) && !isinarray( level.hackertooltargets, ent ) )
|
||||
return false;
|
||||
|
||||
if ( isentityhackableweaponobject( ent ) )
|
||||
{
|
||||
if ( distancesquared( self.origin, ent.origin ) > level.hackertoolmaxequipmentdistancesq )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
hackersoftsighttest()
|
||||
{
|
||||
passed = 1;
|
||||
locklengthms = 0;
|
||||
|
||||
if ( isdefined( self.hackertooltarget ) )
|
||||
locklengthms = self gethacktime( self.hackertooltarget );
|
||||
|
||||
if ( self isempjammed() || locklengthms == 0 )
|
||||
{
|
||||
self clearhackertarget();
|
||||
passed = 0;
|
||||
}
|
||||
else if ( iswithinhackertoolreticle( self.hackertooltarget ) )
|
||||
self.hackertoollostsightlinetime = 0;
|
||||
else
|
||||
{
|
||||
if ( self.hackertoollostsightlinetime == 0 )
|
||||
self.hackertoollostsightlinetime = gettime();
|
||||
|
||||
timepassed = gettime() - self.hackertoollostsightlinetime;
|
||||
|
||||
if ( timepassed >= level.hackertoollostsightlimitms )
|
||||
{
|
||||
self clearhackertarget();
|
||||
passed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
registerwithhackertool( radius, hacktimems )
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
if ( isdefined( radius ) )
|
||||
self.hackertoolradius = radius;
|
||||
else
|
||||
self.hackertoolradius = level.hackertoollockonradius;
|
||||
|
||||
if ( isdefined( hacktimems ) )
|
||||
self.hackertooltimems = hacktimems;
|
||||
else
|
||||
self.hackertooltimems = level.hackertoolhacktimems;
|
||||
|
||||
self thread watchhackableentitydeath();
|
||||
level.hackertooltargets[level.hackertooltargets.size] = self;
|
||||
}
|
||||
|
||||
watchhackableentitydeath()
|
||||
{
|
||||
self waittill( "death" );
|
||||
|
||||
arrayremovevalue( level.hackertooltargets, self );
|
||||
}
|
||||
|
||||
gethackertoolradius( target )
|
||||
{
|
||||
radius = 20;
|
||||
|
||||
if ( isentityhackablecarepackage( target ) )
|
||||
{
|
||||
assert( isdefined( target.hackertoolradius ) );
|
||||
radius = target.hackertoolradius;
|
||||
}
|
||||
else if ( isentityhackableweaponobject( target ) )
|
||||
radius = getweaponobjecthackerradius( target );
|
||||
else if ( isdefined( target.hackertoolradius ) )
|
||||
radius = target.hackertoolradius;
|
||||
else
|
||||
{
|
||||
radius = level.vehiclehackertoolradius;
|
||||
|
||||
switch ( target.model )
|
||||
{
|
||||
case "veh_t6_drone_uav":
|
||||
radius = level.uavhackertoolradius;
|
||||
break;
|
||||
case "veh_t6_drone_cuav":
|
||||
radius = level.cuavhackertoolradius;
|
||||
break;
|
||||
case "t5_veh_rcbomb_axis":
|
||||
radius = level.rcxdhackertoolradius;
|
||||
break;
|
||||
case "veh_iw_mh6_littlebird_mp":
|
||||
radius = level.carepackagechopperhackertoolradius;
|
||||
break;
|
||||
case "veh_t6_drone_quad_rotor_mp_alt":
|
||||
case "veh_t6_drone_quad_rotor_mp":
|
||||
radius = level.qrdronehackertoolradius;
|
||||
break;
|
||||
case "veh_t6_drone_tank_alt":
|
||||
case "veh_t6_drone_tank":
|
||||
radius = level.aitankhackertoolradius;
|
||||
break;
|
||||
case "veh_t6_air_attack_heli_mp_light":
|
||||
case "veh_t6_air_attack_heli_mp_dark":
|
||||
radius = level.stealthchopperhackertoolradius;
|
||||
break;
|
||||
case "veh_t6_drone_overwatch_light":
|
||||
case "veh_t6_drone_overwatch_dark":
|
||||
radius = level.littlebirdhackertoolradius;
|
||||
break;
|
||||
case "veh_t6_drone_pegasus":
|
||||
radius = level.lodestarhackertoolradius;
|
||||
break;
|
||||
case "veh_iw_air_apache_killstreak":
|
||||
radius = level.choppergunnerhackertoolradius;
|
||||
break;
|
||||
case "veh_t6_air_a10f_alt":
|
||||
case "veh_t6_air_a10f":
|
||||
radius = level.warthoghackertoolradius;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return radius;
|
||||
}
|
||||
|
||||
gethacktime( target )
|
||||
{
|
||||
time = 500;
|
||||
|
||||
if ( isentityhackablecarepackage( target ) )
|
||||
{
|
||||
assert( isdefined( target.hackertooltimems ) );
|
||||
|
||||
if ( isdefined( target.owner ) && target.owner == self )
|
||||
time = level.carepackageownerhackertooltimems;
|
||||
else if ( isdefined( target.owner ) && target.owner.team == self.team )
|
||||
time = level.carepackagefriendlyhackertooltimems;
|
||||
else
|
||||
time = level.carepackagehackertooltimems;
|
||||
}
|
||||
else if ( isentityhackableweaponobject( target ) )
|
||||
time = getweaponobjecthacktimems( target );
|
||||
else if ( isdefined( target.hackertooltimems ) )
|
||||
time = target.hackertooltimems;
|
||||
else
|
||||
{
|
||||
time = level.vehiclehackertooltimems;
|
||||
|
||||
switch ( target.model )
|
||||
{
|
||||
case "veh_t6_drone_uav":
|
||||
time = level.uavhackertooltimems;
|
||||
break;
|
||||
case "veh_t6_drone_cuav":
|
||||
time = level.cuavhackertooltimems;
|
||||
break;
|
||||
case "t5_veh_rcbomb_axis":
|
||||
time = level.rcxdhackertooltimems;
|
||||
break;
|
||||
case "veh_t6_drone_supply_alt":
|
||||
case "veh_t6_drone_supply_alt":
|
||||
time = level.carepackagechopperhackertooltimems;
|
||||
break;
|
||||
case "veh_t6_drone_quad_rotor_mp_alt":
|
||||
case "veh_t6_drone_quad_rotor_mp":
|
||||
time = level.qrdronehackertooltimems;
|
||||
break;
|
||||
case "veh_t6_drone_tank_alt":
|
||||
case "veh_t6_drone_tank":
|
||||
time = level.aitankhackertooltimems;
|
||||
break;
|
||||
case "veh_t6_air_attack_heli_mp_light":
|
||||
case "veh_t6_air_attack_heli_mp_dark":
|
||||
time = level.stealthchopperhackertooltimems;
|
||||
break;
|
||||
case "veh_t6_drone_overwatch_light":
|
||||
case "veh_t6_drone_overwatch_dark":
|
||||
time = level.littlebirdhackertooltimems;
|
||||
break;
|
||||
case "veh_t6_drone_pegasus":
|
||||
time = level.lodestarhackertooltimems;
|
||||
break;
|
||||
case "veh_t6_air_v78_vtol_killstreak_alt":
|
||||
case "veh_t6_air_v78_vtol_killstreak":
|
||||
time = level.choppergunnerhackertooltimems;
|
||||
break;
|
||||
case "veh_t6_air_a10f_alt":
|
||||
case "veh_t6_air_a10f":
|
||||
time = level.warthoghackertooltimems;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
tunables()
|
||||
{
|
||||
/#
|
||||
while ( true )
|
||||
{
|
||||
level.hackertoollostsightlimitms = weapons_get_dvar_int( "scr_hackerToolLostSightLimitMs", 1000 );
|
||||
level.hackertoollockonradius = weapons_get_dvar( "scr_hackerToolLockOnRadius", 20 );
|
||||
level.hackertoollockonfov = weapons_get_dvar_int( "scr_hackerToolLockOnFOV", 65 );
|
||||
level.rcxd_time = weapons_get_dvar( "scr_rcxd_time", 1.5 );
|
||||
level.uav_time = weapons_get_dvar_int( "scr_uav_time", 4 );
|
||||
level.cuav_time = weapons_get_dvar_int( "scr_cuav_time", 4 );
|
||||
level.care_package_chopper_time = weapons_get_dvar_int( "scr_care_package_chopper_time", 3 );
|
||||
level.guardian_time = weapons_get_dvar_int( "scr_guardian_time", 5 );
|
||||
level.sentry_time = weapons_get_dvar_int( "scr_sentry_time", 5 );
|
||||
level.wasp_time = weapons_get_dvar_int( "scr_wasp_time", 5 );
|
||||
level.agr_time = weapons_get_dvar_int( "scr_agr_time", 5 );
|
||||
level.stealth_helicopter_time = weapons_get_dvar_int( "scr_stealth_helicopter_time", 7 );
|
||||
level.escort_drone_time = weapons_get_dvar_int( "scr_escort_drone_time", 7 );
|
||||
level.warthog_time = weapons_get_dvar_int( "scr_warthog_time", 7 );
|
||||
level.lodestar_time = weapons_get_dvar_int( "scr_lodestar_time", 7 );
|
||||
level.chopper_gunner_time = weapons_get_dvar_int( "scr_chopper_gunner_time", 7 );
|
||||
wait 1.0;
|
||||
}
|
||||
#/
|
||||
}
|
680
MP/Core/maps/mp/_heatseekingmissile.gsc
Normal file
680
MP/Core/maps/mp/_heatseekingmissile.gsc
Normal file
@ -0,0 +1,680 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\gametypes\_weapon_utils;
|
||||
#include maps\mp\killstreaks\_helicopter;
|
||||
#include maps\mp\killstreaks\_airsupport;
|
||||
|
||||
init()
|
||||
{
|
||||
precacherumble( "stinger_lock_rumble" );
|
||||
game["locking_on_sound"] = "uin_alert_lockon_start";
|
||||
game["locked_on_sound"] = "uin_alert_lockon";
|
||||
precachestring( &"MP_CANNOT_LOCKON_TO_TARGET" );
|
||||
thread onplayerconnect();
|
||||
level.fx_flare = loadfx( "vehicle/vexplosion/fx_heli_chaff" );
|
||||
/#
|
||||
setdvar( "scr_freelock", "0" );
|
||||
#/
|
||||
}
|
||||
|
||||
onplayerconnect()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
level waittill( "connecting", player );
|
||||
|
||||
player thread onplayerspawned();
|
||||
}
|
||||
}
|
||||
|
||||
onplayerspawned()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
|
||||
self clearirtarget();
|
||||
thread stingertoggleloop();
|
||||
self thread stingerfirednotify();
|
||||
}
|
||||
}
|
||||
|
||||
clearirtarget()
|
||||
{
|
||||
self notify( "stinger_irt_cleartarget" );
|
||||
self notify( "stop_lockon_sound" );
|
||||
self notify( "stop_locked_sound" );
|
||||
self.stingerlocksound = undefined;
|
||||
self stoprumble( "stinger_lock_rumble" );
|
||||
self.stingerlockstarttime = 0;
|
||||
self.stingerlockstarted = 0;
|
||||
self.stingerlockfinalized = 0;
|
||||
|
||||
if ( isdefined( self.stingertarget ) )
|
||||
{
|
||||
lockingon( self.stingertarget, 0 );
|
||||
lockedon( self.stingertarget, 0 );
|
||||
}
|
||||
|
||||
self.stingertarget = undefined;
|
||||
self weaponlockfree();
|
||||
self weaponlocktargettooclose( 0 );
|
||||
self weaponlocknoclearance( 0 );
|
||||
self stoplocalsound( game["locking_on_sound"] );
|
||||
self stoplocalsound( game["locked_on_sound"] );
|
||||
self destroylockoncanceledmessage();
|
||||
}
|
||||
|
||||
stingerfirednotify()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self waittill( "missile_fire", missile, weap );
|
||||
|
||||
if ( maps\mp\gametypes\_weapon_utils::isguidedrocketlauncherweapon( weap ) )
|
||||
{
|
||||
if ( isdefined( self.stingertarget ) && self.stingerlockfinalized )
|
||||
self.stingertarget notify( "stinger_fired_at_me", missile, weap, self );
|
||||
|
||||
level notify( "missile_fired", self, missile, self.stingertarget, self.stingerlockfinalized );
|
||||
self notify( "stinger_fired", missile, weap );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stingertoggleloop()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "weapon_change", weapon );
|
||||
|
||||
while ( maps\mp\gametypes\_weapon_utils::isguidedrocketlauncherweapon( weapon ) )
|
||||
{
|
||||
abort = 0;
|
||||
|
||||
while ( !self playerstingerads() )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( !maps\mp\gametypes\_weapon_utils::isguidedrocketlauncherweapon( self getcurrentweapon() ) )
|
||||
{
|
||||
abort = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( abort )
|
||||
break;
|
||||
|
||||
self thread stingerirtloop();
|
||||
|
||||
while ( self playerstingerads() )
|
||||
wait 0.05;
|
||||
|
||||
self notify( "stinger_IRT_off" );
|
||||
self clearirtarget();
|
||||
weapon = self getcurrentweapon();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stingerirtloop()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self endon( "stinger_IRT_off" );
|
||||
locklength = self getlockonspeed();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( self.stingerlockfinalized )
|
||||
{
|
||||
passed = softsighttest();
|
||||
|
||||
if ( !passed )
|
||||
continue;
|
||||
|
||||
if ( !isstillvalidtarget( self.stingertarget ) )
|
||||
{
|
||||
self clearirtarget();
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !self.stingertarget.locked_on )
|
||||
self.stingertarget notify( "missile_lock", self );
|
||||
|
||||
lockingon( self.stingertarget, 0 );
|
||||
lockedon( self.stingertarget, 1 );
|
||||
thread looplocallocksound( game["locked_on_sound"], 0.75 );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( self.stingerlockstarted )
|
||||
{
|
||||
if ( !isstillvalidtarget( self.stingertarget ) )
|
||||
{
|
||||
self clearirtarget();
|
||||
continue;
|
||||
}
|
||||
|
||||
lockingon( self.stingertarget, 1 );
|
||||
lockedon( self.stingertarget, 0 );
|
||||
passed = softsighttest();
|
||||
|
||||
if ( !passed )
|
||||
continue;
|
||||
|
||||
timepassed = gettime() - self.stingerlockstarttime;
|
||||
|
||||
if ( timepassed < locklength )
|
||||
continue;
|
||||
|
||||
assert( isdefined( self.stingertarget ) );
|
||||
self notify( "stop_lockon_sound" );
|
||||
self.stingerlockfinalized = 1;
|
||||
self weaponlockfinalize( self.stingertarget );
|
||||
continue;
|
||||
}
|
||||
|
||||
besttarget = self getbeststingertarget();
|
||||
|
||||
if ( !isdefined( besttarget ) )
|
||||
{
|
||||
self destroylockoncanceledmessage();
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !self locksighttest( besttarget ) )
|
||||
{
|
||||
self destroylockoncanceledmessage();
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( self locksighttest( besttarget ) && isdefined( besttarget.lockondelay ) && besttarget.lockondelay )
|
||||
{
|
||||
self displaylockoncanceledmessage();
|
||||
continue;
|
||||
}
|
||||
|
||||
self destroylockoncanceledmessage();
|
||||
initlockfield( besttarget );
|
||||
self.stingertarget = besttarget;
|
||||
self.stingerlockstarttime = gettime();
|
||||
self.stingerlockstarted = 1;
|
||||
self.stingerlostsightlinetime = 0;
|
||||
self thread looplocalseeksound( game["locking_on_sound"], 0.6 );
|
||||
}
|
||||
}
|
||||
|
||||
destroylockoncanceledmessage()
|
||||
{
|
||||
if ( isdefined( self.lockoncanceledmessage ) )
|
||||
self.lockoncanceledmessage destroy();
|
||||
}
|
||||
|
||||
displaylockoncanceledmessage()
|
||||
{
|
||||
if ( isdefined( self.lockoncanceledmessage ) )
|
||||
return;
|
||||
|
||||
self.lockoncanceledmessage = newclienthudelem( self );
|
||||
self.lockoncanceledmessage.fontscale = 1.25;
|
||||
self.lockoncanceledmessage.x = 0;
|
||||
self.lockoncanceledmessage.y = 50;
|
||||
self.lockoncanceledmessage.alignx = "center";
|
||||
self.lockoncanceledmessage.aligny = "top";
|
||||
self.lockoncanceledmessage.horzalign = "center";
|
||||
self.lockoncanceledmessage.vertalign = "top";
|
||||
self.lockoncanceledmessage.foreground = 1;
|
||||
self.lockoncanceledmessage.hidewhendead = 0;
|
||||
self.lockoncanceledmessage.hidewheninmenu = 1;
|
||||
self.lockoncanceledmessage.archived = 0;
|
||||
self.lockoncanceledmessage.alpha = 1.0;
|
||||
self.lockoncanceledmessage settext( &"MP_CANNOT_LOCKON_TO_TARGET" );
|
||||
}
|
||||
|
||||
getbeststingertarget()
|
||||
{
|
||||
targetsall = target_getarray();
|
||||
targetsvalid = [];
|
||||
|
||||
for ( idx = 0; idx < targetsall.size; idx++ )
|
||||
{
|
||||
/#
|
||||
if ( getdvar( "scr_freelock" ) == "1" )
|
||||
{
|
||||
if ( self insidestingerreticlenolock( targetsall[idx] ) )
|
||||
targetsvalid[targetsvalid.size] = targetsall[idx];
|
||||
|
||||
continue;
|
||||
}
|
||||
#/
|
||||
if ( level.teambased )
|
||||
{
|
||||
if ( isdefined( targetsall[idx].team ) && targetsall[idx].team != self.team )
|
||||
{
|
||||
if ( self insidestingerreticlenolock( targetsall[idx] ) )
|
||||
targetsvalid[targetsvalid.size] = targetsall[idx];
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( self insidestingerreticlenolock( targetsall[idx] ) )
|
||||
{
|
||||
if ( isdefined( targetsall[idx].owner ) && self != targetsall[idx].owner )
|
||||
targetsvalid[targetsvalid.size] = targetsall[idx];
|
||||
}
|
||||
}
|
||||
|
||||
if ( targetsvalid.size == 0 )
|
||||
return undefined;
|
||||
|
||||
chosenent = targetsvalid[0];
|
||||
|
||||
if ( targetsvalid.size > 1 )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return chosenent;
|
||||
}
|
||||
|
||||
insidestingerreticlenolock( target )
|
||||
{
|
||||
radius = self getlockonradius();
|
||||
return target_isincircle( target, self, 65, radius );
|
||||
}
|
||||
|
||||
insidestingerreticlelocked( target )
|
||||
{
|
||||
radius = self getlockonradius();
|
||||
return target_isincircle( target, self, 65, radius );
|
||||
}
|
||||
|
||||
isstillvalidtarget( ent )
|
||||
{
|
||||
if ( !isdefined( ent ) )
|
||||
return false;
|
||||
|
||||
if ( !target_istarget( ent ) )
|
||||
return false;
|
||||
|
||||
if ( !insidestingerreticlelocked( ent ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
playerstingerads()
|
||||
{
|
||||
return self playerads() == 1.0;
|
||||
}
|
||||
|
||||
looplocalseeksound( alias, interval )
|
||||
{
|
||||
self endon( "stop_lockon_sound" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self playlocalsound( alias );
|
||||
self playrumbleonentity( "stinger_lock_rumble" );
|
||||
wait( interval / 2 );
|
||||
}
|
||||
}
|
||||
|
||||
looplocallocksound( alias, interval )
|
||||
{
|
||||
self endon( "stop_locked_sound" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
|
||||
if ( isdefined( self.stingerlocksound ) )
|
||||
return;
|
||||
|
||||
self.stingerlocksound = 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self playlocalsound( alias );
|
||||
self playrumbleonentity( "stinger_lock_rumble" );
|
||||
wait( interval / 6 );
|
||||
self playlocalsound( alias );
|
||||
self playrumbleonentity( "stinger_lock_rumble" );
|
||||
wait( interval / 6 );
|
||||
self playlocalsound( alias );
|
||||
self playrumbleonentity( "stinger_lock_rumble" );
|
||||
wait( interval / 6 );
|
||||
self stoprumble( "stinger_lock_rumble" );
|
||||
}
|
||||
|
||||
self.stingerlocksound = undefined;
|
||||
}
|
||||
|
||||
locksighttest( target )
|
||||
{
|
||||
eyepos = self geteye();
|
||||
|
||||
if ( !isdefined( target ) )
|
||||
return false;
|
||||
|
||||
passed = bullettracepassed( eyepos, target.origin, 0, target );
|
||||
|
||||
if ( passed )
|
||||
return true;
|
||||
|
||||
front = target getpointinbounds( 1, 0, 0 );
|
||||
passed = bullettracepassed( eyepos, front, 0, target );
|
||||
|
||||
if ( passed )
|
||||
return true;
|
||||
|
||||
back = target getpointinbounds( -1, 0, 0 );
|
||||
passed = bullettracepassed( eyepos, back, 0, target );
|
||||
|
||||
if ( passed )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
softsighttest()
|
||||
{
|
||||
lost_sight_limit = 500;
|
||||
|
||||
if ( self locksighttest( self.stingertarget ) )
|
||||
{
|
||||
self.stingerlostsightlinetime = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( self.stingerlostsightlinetime == 0 )
|
||||
self.stingerlostsightlinetime = gettime();
|
||||
|
||||
timepassed = gettime() - self.stingerlostsightlinetime;
|
||||
|
||||
if ( timepassed >= lost_sight_limit )
|
||||
{
|
||||
self clearirtarget();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
initlockfield( target )
|
||||
{
|
||||
if ( isdefined( target.locking_on ) )
|
||||
return;
|
||||
|
||||
target.locking_on = 0;
|
||||
target.locked_on = 0;
|
||||
}
|
||||
|
||||
lockingon( target, lock )
|
||||
{
|
||||
assert( isdefined( target.locking_on ) );
|
||||
clientnum = self getentitynumber();
|
||||
|
||||
if ( lock )
|
||||
{
|
||||
target notify( "locking on" );
|
||||
target.locking_on |= 1 << clientnum;
|
||||
self thread watchclearlockingon( target, clientnum );
|
||||
}
|
||||
else
|
||||
{
|
||||
self notify( "locking_on_cleared" );
|
||||
target.locking_on &= ~( 1 << clientnum );
|
||||
}
|
||||
}
|
||||
|
||||
watchclearlockingon( target, clientnum )
|
||||
{
|
||||
target endon( "death" );
|
||||
self endon( "locking_on_cleared" );
|
||||
self waittill_any( "death", "disconnect" );
|
||||
target.locking_on &= ~( 1 << clientnum );
|
||||
}
|
||||
|
||||
lockedon( target, lock )
|
||||
{
|
||||
assert( isdefined( target.locked_on ) );
|
||||
clientnum = self getentitynumber();
|
||||
|
||||
if ( lock )
|
||||
{
|
||||
target.locked_on |= 1 << clientnum;
|
||||
self thread watchclearlockedon( target, clientnum );
|
||||
}
|
||||
else
|
||||
{
|
||||
self notify( "locked_on_cleared" );
|
||||
target.locked_on &= ~( 1 << clientnum );
|
||||
}
|
||||
}
|
||||
|
||||
watchclearlockedon( target, clientnum )
|
||||
{
|
||||
self endon( "locked_on_cleared" );
|
||||
self waittill_any( "death", "disconnect" );
|
||||
|
||||
if ( isdefined( target ) )
|
||||
target.locked_on &= ~( 1 << clientnum );
|
||||
}
|
||||
|
||||
missiletarget_lockonmonitor( player, endon1, endon2 )
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
if ( isdefined( endon1 ) )
|
||||
self endon( endon1 );
|
||||
|
||||
if ( isdefined( endon2 ) )
|
||||
self endon( endon2 );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ( target_istarget( self ) )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
wait 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
_incomingmissile( missile )
|
||||
{
|
||||
if ( !isdefined( self.incoming_missile ) )
|
||||
self.incoming_missile = 0;
|
||||
|
||||
self.incoming_missile++;
|
||||
self thread _incomingmissiletracker( missile );
|
||||
}
|
||||
|
||||
_incomingmissiletracker( missile )
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
missile waittill( "death" );
|
||||
|
||||
self.incoming_missile--;
|
||||
assert( self.incoming_missile >= 0 );
|
||||
}
|
||||
|
||||
missiletarget_ismissileincoming()
|
||||
{
|
||||
if ( !isdefined( self.incoming_missile ) )
|
||||
return false;
|
||||
|
||||
if ( self.incoming_missile )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
missiletarget_handleincomingmissile( responsefunc, endon1, endon2 )
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
self endon( "death" );
|
||||
|
||||
if ( isdefined( endon1 ) )
|
||||
self endon( endon1 );
|
||||
|
||||
if ( isdefined( endon2 ) )
|
||||
self endon( endon2 );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "stinger_fired_at_me", missile, weap, attacker );
|
||||
|
||||
_incomingmissile( missile );
|
||||
|
||||
if ( isdefined( responsefunc ) )
|
||||
[[ responsefunc ]]( missile, attacker, weap, endon1, endon2 );
|
||||
}
|
||||
}
|
||||
|
||||
missiletarget_proximitydetonateincomingmissile( endon1, endon2 )
|
||||
{
|
||||
missiletarget_handleincomingmissile( ::missiletarget_proximitydetonate, endon1, endon2 );
|
||||
}
|
||||
|
||||
_missiledetonate( attacker, weapon )
|
||||
{
|
||||
self endon( "death" );
|
||||
radiusdamage( self.origin, 500, 600, 600, attacker, undefined, weapon );
|
||||
wait 0.05;
|
||||
self detonate();
|
||||
wait 0.05;
|
||||
self delete();
|
||||
}
|
||||
|
||||
missiletarget_proximitydetonate( missile, attacker, weapon, endon1, endon2 )
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
missile endon( "death" );
|
||||
|
||||
if ( isdefined( endon1 ) )
|
||||
self endon( endon1 );
|
||||
|
||||
if ( isdefined( endon2 ) )
|
||||
self endon( endon2 );
|
||||
|
||||
mindist = distance( missile.origin, self.origin );
|
||||
lastcenter = self.origin;
|
||||
missile missile_settarget( self );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ( !isdefined( self ) )
|
||||
center = lastcenter;
|
||||
else
|
||||
center = self.origin;
|
||||
|
||||
lastcenter = center;
|
||||
curdist = distance( missile.origin, center );
|
||||
|
||||
if ( curdist < 3500 && isdefined( self.numflares ) && self.numflares > 0 )
|
||||
{
|
||||
self.numflares--;
|
||||
self thread missiletarget_playflarefx();
|
||||
self maps\mp\killstreaks\_helicopter::trackassists( attacker, 0, 1 );
|
||||
newtarget = self missiletarget_deployflares( missile.origin, missile.angles );
|
||||
missile missile_settarget( newtarget );
|
||||
missiletarget = newtarget;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( curdist < mindist )
|
||||
mindist = curdist;
|
||||
|
||||
if ( curdist > mindist )
|
||||
{
|
||||
if ( curdist > 500 )
|
||||
return;
|
||||
|
||||
missile thread _missiledetonate( attacker, weapon );
|
||||
}
|
||||
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
missiletarget_playflarefx()
|
||||
{
|
||||
if ( !isdefined( self ) )
|
||||
return;
|
||||
|
||||
flare_fx = level.fx_flare;
|
||||
|
||||
if ( isdefined( self.fx_flare ) )
|
||||
flare_fx = self.fx_flare;
|
||||
|
||||
if ( isdefined( self.flare_ent ) )
|
||||
playfxontag( flare_fx, self.flare_ent, "tag_origin" );
|
||||
else
|
||||
playfxontag( flare_fx, self, "tag_origin" );
|
||||
|
||||
if ( isdefined( self.owner ) )
|
||||
self playsoundtoplayer( "veh_huey_chaff_drop_plr", self.owner );
|
||||
|
||||
self playsound( "veh_huey_chaff_explo_npc" );
|
||||
}
|
||||
|
||||
missiletarget_deployflares( origin, angles )
|
||||
{
|
||||
vec_toforward = anglestoforward( self.angles );
|
||||
vec_toright = anglestoright( self.angles );
|
||||
vec_tomissileforward = anglestoforward( angles );
|
||||
delta = self.origin - origin;
|
||||
dot = vectordot( vec_tomissileforward, vec_toright );
|
||||
sign = 1;
|
||||
|
||||
if ( dot > 0 )
|
||||
sign = -1;
|
||||
|
||||
flare_dir = vectornormalize( vectorscale( vec_toforward, -0.5 ) + vectorscale( vec_toright, sign ) );
|
||||
velocity = vectorscale( flare_dir, randomintrange( 200, 400 ) );
|
||||
velocity = ( velocity[0], velocity[1], velocity[2] - randomintrange( 10, 100 ) );
|
||||
flareorigin = self.origin;
|
||||
flareorigin += vectorscale( flare_dir, randomintrange( 500, 700 ) );
|
||||
flareorigin += vectorscale( ( 0, 0, 1 ), 500.0 );
|
||||
|
||||
if ( isdefined( self.flareoffset ) )
|
||||
flareorigin += self.flareoffset;
|
||||
|
||||
flareobject = spawn( "script_origin", flareorigin );
|
||||
flareobject.angles = self.angles;
|
||||
flareobject setmodel( "tag_origin" );
|
||||
flareobject movegravity( velocity, 5.0 );
|
||||
flareobject thread deleteaftertime( 5.0 );
|
||||
self thread debug_tracker( flareobject );
|
||||
return flareobject;
|
||||
}
|
||||
|
||||
debug_tracker( target )
|
||||
{
|
||||
target endon( "death" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
maps\mp\killstreaks\_airsupport::debug_sphere( target.origin, 10, ( 1, 0, 0 ), 1, 1 );
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
387
MP/Core/maps/mp/_interactive_objects.gsc
Normal file
387
MP/Core/maps/mp/_interactive_objects.gsc
Normal file
@ -0,0 +1,387 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level.barrelexplodingthisframe = 0;
|
||||
qbarrels = 0;
|
||||
all_barrels = [];
|
||||
barrels = getentarray( "explodable_barrel", "targetname" );
|
||||
|
||||
if ( isdefined( barrels ) && barrels.size > 0 )
|
||||
{
|
||||
qbarrels = 1;
|
||||
|
||||
for ( i = 0; i < barrels.size; i++ )
|
||||
all_barrels[all_barrels.size] = barrels[i];
|
||||
}
|
||||
|
||||
barrels = getentarray( "explodable_barrel", "script_noteworthy" );
|
||||
|
||||
if ( isdefined( barrels ) && barrels.size > 0 )
|
||||
{
|
||||
qbarrels = 1;
|
||||
|
||||
for ( i = 0; i < barrels.size; i++ )
|
||||
all_barrels[all_barrels.size] = barrels[i];
|
||||
}
|
||||
|
||||
if ( qbarrels )
|
||||
{
|
||||
precachemodel( "global_explosive_barrel" );
|
||||
level.barrelburn = 100;
|
||||
level.barrelhealth = 250;
|
||||
level.barrelingsound = "exp_redbarrel_ignition";
|
||||
level.barrelexpsound = "exp_redbarrel";
|
||||
level.breakables_fx["barrel"]["burn_start"] = loadfx( "destructibles/fx_barrel_ignite" );
|
||||
level.breakables_fx["barrel"]["burn"] = loadfx( "destructibles/fx_barrel_fire_top" );
|
||||
level.breakables_fx["barrel"]["explode"] = loadfx( "destructibles/fx_dest_barrelexp" );
|
||||
array_thread( all_barrels, ::explodable_barrel_think );
|
||||
}
|
||||
|
||||
qcrates = 0;
|
||||
all_crates = [];
|
||||
crates = getentarray( "flammable_crate", "targetname" );
|
||||
|
||||
if ( isdefined( crates ) && crates.size > 0 )
|
||||
{
|
||||
qcrates = 1;
|
||||
|
||||
for ( i = 0; i < crates.size; i++ )
|
||||
all_crates[all_crates.size] = crates[i];
|
||||
}
|
||||
|
||||
crates = getentarray( "flammable_crate", "script_noteworthy" );
|
||||
|
||||
if ( isdefined( crates ) && crates.size > 0 )
|
||||
{
|
||||
qcrates = 1;
|
||||
|
||||
for ( i = 0; i < crates.size; i++ )
|
||||
all_crates[all_crates.size] = crates[i];
|
||||
}
|
||||
|
||||
if ( qcrates )
|
||||
{
|
||||
precachemodel( "global_flammable_crate_jap_piece01_d" );
|
||||
level.crateburn = 100;
|
||||
level.cratehealth = 200;
|
||||
level.breakables_fx["ammo_crate"]["burn_start"] = loadfx( "destructibles/fx_ammobox_ignite" );
|
||||
level.breakables_fx["ammo_crate"]["burn"] = loadfx( "destructibles/fx_ammobox_fire_top" );
|
||||
level.breakables_fx["ammo_crate"]["explode"] = loadfx( "destructibles/fx_ammoboxExp" );
|
||||
level.crateignsound = "Ignition_ammocrate";
|
||||
level.crateexpsound = "Explo_ammocrate";
|
||||
array_thread( all_crates, ::flammable_crate_think );
|
||||
}
|
||||
|
||||
if ( !qbarrels && !qcrates )
|
||||
return;
|
||||
}
|
||||
|
||||
explodable_barrel_think()
|
||||
{
|
||||
if ( self.classname != "script_model" )
|
||||
return;
|
||||
|
||||
self endon( "exploding" );
|
||||
self breakable_clip();
|
||||
self.health = level.barrelhealth;
|
||||
self setcandamage( 1 );
|
||||
self.targetname = "explodable_barrel";
|
||||
|
||||
if ( sessionmodeiszombiesgame() )
|
||||
self.removeexplodable = 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "damage", amount, attacker, direction_vec, p, type );
|
||||
/#
|
||||
println( "BARRELDAMAGE: " + type );
|
||||
#/
|
||||
if ( type == "MOD_MELEE" || type == "MOD_IMPACT" )
|
||||
continue;
|
||||
|
||||
if ( isdefined( self.script_requires_player ) && self.script_requires_player && !isplayer( attacker ) )
|
||||
continue;
|
||||
|
||||
if ( isdefined( self.script_selfisattacker ) && self.script_selfisattacker )
|
||||
self.damageowner = self;
|
||||
else
|
||||
self.damageowner = attacker;
|
||||
|
||||
self.health -= amount;
|
||||
|
||||
if ( self.health <= level.barrelburn )
|
||||
self thread explodable_barrel_burn();
|
||||
}
|
||||
}
|
||||
|
||||
explodable_barrel_burn()
|
||||
{
|
||||
count = 0;
|
||||
startedfx = 0;
|
||||
up = anglestoup( vectorscale( ( 0, 1, 0 ), 90.0 ) );
|
||||
worldup = anglestoup( vectorscale( ( 0, 1, 0 ), 90.0 ) );
|
||||
dot = vectordot( up, worldup );
|
||||
offset1 = ( 0, 0, 0 );
|
||||
offset2 = up * vectorscale( ( 0, 0, 1 ), 44.0 );
|
||||
|
||||
if ( dot < 0.5 )
|
||||
{
|
||||
offset1 = up * vectorscale( ( 0, 0, 1 ), 22.0 ) - vectorscale( ( 0, 0, 1 ), 30.0 );
|
||||
offset2 = up * vectorscale( ( 0, 0, 1 ), 22.0 ) + vectorscale( ( 0, 0, 1 ), 14.0 );
|
||||
}
|
||||
|
||||
while ( self.health > 0 )
|
||||
{
|
||||
if ( !startedfx )
|
||||
{
|
||||
playfx( level.breakables_fx["barrel"]["burn_start"], self.origin + offset1 );
|
||||
level thread play_sound_in_space( level.barrelingsound, self.origin );
|
||||
startedfx = 1;
|
||||
}
|
||||
|
||||
if ( count > 20 )
|
||||
count = 0;
|
||||
|
||||
playfx( level.breakables_fx["barrel"]["burn"], self.origin + offset2 );
|
||||
self playloopsound( "barrel_fuse" );
|
||||
|
||||
if ( count == 0 )
|
||||
self.health -= 10 + randomint( 10 );
|
||||
|
||||
count++;
|
||||
wait 0.05;
|
||||
}
|
||||
|
||||
level notify( "explosion_started" );
|
||||
self thread explodable_barrel_explode();
|
||||
}
|
||||
|
||||
explodable_barrel_explode()
|
||||
{
|
||||
self notify( "exploding" );
|
||||
self death_notify_wrapper();
|
||||
up = anglestoup( vectorscale( ( 0, 1, 0 ), 90.0 ) );
|
||||
worldup = anglestoup( vectorscale( ( 0, 1, 0 ), 90.0 ) );
|
||||
dot = vectordot( up, worldup );
|
||||
offset = ( 0, 0, 0 );
|
||||
|
||||
if ( dot < 0.5 )
|
||||
{
|
||||
start = self.origin + vectorscale( up, 22 );
|
||||
trace = physicstrace( start, start + vectorscale( ( 0, 0, -1 ), 64.0 ) );
|
||||
end = trace["position"];
|
||||
offset = end - self.origin;
|
||||
}
|
||||
|
||||
offset += vectorscale( ( 0, 0, 1 ), 4.0 );
|
||||
mindamage = 1;
|
||||
maxdamage = 250;
|
||||
blastradius = 250;
|
||||
level thread play_sound_in_space( level.barrelexpsound, self.origin );
|
||||
playfx( level.breakables_fx["barrel"]["explode"], self.origin + offset );
|
||||
physicsexplosionsphere( self.origin + offset, 100, 80, 1, maxdamage, mindamage );
|
||||
level.barrelexplodingthisframe = 1;
|
||||
|
||||
if ( isdefined( self.remove ) )
|
||||
self.remove delete();
|
||||
|
||||
if ( isdefined( self.radius ) )
|
||||
blastradius = self.radius;
|
||||
|
||||
self radiusdamage( self.origin + vectorscale( ( 0, 0, 1 ), 56.0 ), blastradius, maxdamage, mindamage, self.damageowner );
|
||||
attacker = undefined;
|
||||
|
||||
if ( isdefined( self.damageowner ) )
|
||||
attacker = self.damageowner;
|
||||
|
||||
level.lastexplodingbarrel["time"] = gettime();
|
||||
level.lastexplodingbarrel["origin"] = self.origin + vectorscale( ( 0, 0, 1 ), 30.0 );
|
||||
|
||||
if ( isdefined( self.removeexplodable ) )
|
||||
self hide();
|
||||
else
|
||||
self setmodel( "global_explosive_barrel" );
|
||||
|
||||
if ( dot < 0.5 )
|
||||
{
|
||||
start = self.origin + vectorscale( up, 22 );
|
||||
trace = physicstrace( start, start + vectorscale( ( 0, 0, -1 ), 64.0 ) );
|
||||
pos = trace["position"];
|
||||
self.origin = pos;
|
||||
self.angles += vectorscale( ( 0, 0, 1 ), 90.0 );
|
||||
}
|
||||
|
||||
wait 0.05;
|
||||
level.barrelexplodingthisframe = 0;
|
||||
}
|
||||
|
||||
flammable_crate_think()
|
||||
{
|
||||
if ( self.classname != "script_model" )
|
||||
return;
|
||||
|
||||
self endon( "exploding" );
|
||||
self breakable_clip();
|
||||
self.health = level.cratehealth;
|
||||
self setcandamage( 1 );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "damage", amount, attacker, direction_vec, p, type );
|
||||
|
||||
if ( isdefined( self.script_requires_player ) && self.script_requires_player && !isplayer( attacker ) )
|
||||
continue;
|
||||
|
||||
if ( isdefined( self.script_selfisattacker ) && self.script_selfisattacker )
|
||||
self.damageowner = self;
|
||||
else
|
||||
self.damageowner = attacker;
|
||||
|
||||
if ( level.barrelexplodingthisframe )
|
||||
wait( randomfloat( 1 ) );
|
||||
|
||||
self.health -= amount;
|
||||
|
||||
if ( self.health <= level.crateburn )
|
||||
self thread flammable_crate_burn();
|
||||
}
|
||||
}
|
||||
|
||||
flammable_crate_burn()
|
||||
{
|
||||
count = 0;
|
||||
startedfx = 0;
|
||||
up = anglestoup( vectorscale( ( 0, 1, 0 ), 90.0 ) );
|
||||
worldup = anglestoup( vectorscale( ( 0, 1, 0 ), 90.0 ) );
|
||||
dot = vectordot( up, worldup );
|
||||
offset1 = ( 0, 0, 0 );
|
||||
offset2 = up * vectorscale( ( 0, 0, 1 ), 44.0 );
|
||||
|
||||
if ( dot < 0.5 )
|
||||
{
|
||||
offset1 = up * vectorscale( ( 0, 0, 1 ), 22.0 ) - vectorscale( ( 0, 0, 1 ), 30.0 );
|
||||
offset2 = up * vectorscale( ( 0, 0, 1 ), 22.0 ) + vectorscale( ( 0, 0, 1 ), 14.0 );
|
||||
}
|
||||
|
||||
while ( self.health > 0 )
|
||||
{
|
||||
if ( !startedfx )
|
||||
{
|
||||
playfx( level.breakables_fx["ammo_crate"]["burn_start"], self.origin );
|
||||
level thread play_sound_in_space( level.crateignsound, self.origin );
|
||||
startedfx = 1;
|
||||
}
|
||||
|
||||
if ( count > 20 )
|
||||
count = 0;
|
||||
|
||||
playfx( level.breakables_fx["ammo_crate"]["burn"], self.origin );
|
||||
|
||||
if ( count == 0 )
|
||||
self.health -= 10 + randomint( 10 );
|
||||
|
||||
count++;
|
||||
wait 0.05;
|
||||
}
|
||||
|
||||
self thread flammable_crate_explode();
|
||||
}
|
||||
|
||||
flammable_crate_explode()
|
||||
{
|
||||
self notify( "exploding" );
|
||||
self death_notify_wrapper();
|
||||
up = anglestoup( vectorscale( ( 0, 1, 0 ), 90.0 ) );
|
||||
worldup = anglestoup( vectorscale( ( 0, 1, 0 ), 90.0 ) );
|
||||
dot = vectordot( up, worldup );
|
||||
offset = ( 0, 0, 0 );
|
||||
|
||||
if ( dot < 0.5 )
|
||||
{
|
||||
start = self.origin + vectorscale( up, 22 );
|
||||
trace = physicstrace( start, start + vectorscale( ( 0, 0, -1 ), 64.0 ) );
|
||||
end = trace["position"];
|
||||
offset = end - self.origin;
|
||||
}
|
||||
|
||||
offset += vectorscale( ( 0, 0, 1 ), 4.0 );
|
||||
mindamage = 1;
|
||||
maxdamage = 250;
|
||||
blastradius = 250;
|
||||
level thread play_sound_in_space( level.crateexpsound, self.origin );
|
||||
playfx( level.breakables_fx["ammo_crate"]["explode"], self.origin );
|
||||
physicsexplosionsphere( self.origin + offset, 100, 80, 1, maxdamage, mindamage );
|
||||
level.barrelexplodingthisframe = 1;
|
||||
|
||||
if ( isdefined( self.remove ) )
|
||||
self.remove delete();
|
||||
|
||||
if ( isdefined( self.radius ) )
|
||||
blastradius = self.radius;
|
||||
|
||||
attacker = undefined;
|
||||
|
||||
if ( isdefined( self.damageowner ) )
|
||||
attacker = self.damageowner;
|
||||
|
||||
self radiusdamage( self.origin + vectorscale( ( 0, 0, 1 ), 30.0 ), blastradius, maxdamage, mindamage, attacker );
|
||||
self setmodel( "global_flammable_crate_jap_piece01_d" );
|
||||
|
||||
if ( dot < 0.5 )
|
||||
{
|
||||
start = self.origin + vectorscale( up, 22 );
|
||||
trace = physicstrace( start, start + vectorscale( ( 0, 0, -1 ), 64.0 ) );
|
||||
pos = trace["position"];
|
||||
self.origin = pos;
|
||||
self.angles += vectorscale( ( 0, 0, 1 ), 90.0 );
|
||||
}
|
||||
|
||||
wait 0.05;
|
||||
level.barrelexplodingthisframe = 0;
|
||||
}
|
||||
|
||||
breakable_clip()
|
||||
{
|
||||
if ( isdefined( self.target ) )
|
||||
{
|
||||
targ = getent( self.target, "targetname" );
|
||||
|
||||
if ( targ.classname == "script_brushmodel" )
|
||||
{
|
||||
self.remove = targ;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isdefined( level.breakables_clip ) && level.breakables_clip.size > 0 )
|
||||
self.remove = getclosestent( self.origin, level.breakables_clip );
|
||||
|
||||
if ( isdefined( self.remove ) )
|
||||
arrayremovevalue( level.breakables_clip, self.remove );
|
||||
}
|
||||
|
||||
getclosestent( org, array )
|
||||
{
|
||||
if ( array.size < 1 )
|
||||
return;
|
||||
|
||||
dist = 256;
|
||||
ent = undefined;
|
||||
|
||||
for ( i = 0; i < array.size; i++ )
|
||||
{
|
||||
newdist = distance( array[i] getorigin(), org );
|
||||
|
||||
if ( newdist >= dist )
|
||||
continue;
|
||||
|
||||
dist = newdist;
|
||||
ent = array[i];
|
||||
}
|
||||
|
||||
return ent;
|
||||
}
|
513
MP/Core/maps/mp/_load.gsc
Normal file
513
MP/Core/maps/mp/_load.gsc
Normal file
@ -0,0 +1,513 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\_script_gen;
|
||||
#include maps\mp\gametypes\_spawning;
|
||||
#include maps\mp\gametypes\_tweakables;
|
||||
#include maps\mp\_destructible;
|
||||
#include maps\mp\_riotshield;
|
||||
#include maps\mp\_vehicles;
|
||||
#include maps\mp\killstreaks\_dogs;
|
||||
#include maps\mp\killstreaks\_ai_tank;
|
||||
#include maps\mp\killstreaks\_rcbomb;
|
||||
#include maps\mp\killstreaks\_helicopter_guard;
|
||||
#include maps\mp\_trophy_system;
|
||||
#include maps\mp\_proximity_grenade;
|
||||
#include maps\mp\_audio;
|
||||
#include maps\mp\_busing;
|
||||
#include maps\mp\_music;
|
||||
#include maps\mp\_fxanim;
|
||||
#include maps\mp\_interactive_objects;
|
||||
#include maps\mp\_serverfaceanim_mp;
|
||||
#include maps\mp\_art;
|
||||
#include maps\mp\_createfx;
|
||||
#include maps\mp\_global_fx;
|
||||
#include maps\mp\_demo;
|
||||
#include maps\mp\_development_dvars;
|
||||
#include maps\mp\_load;
|
||||
#include maps\mp\animscripts\utility;
|
||||
#include maps\mp\animscripts\traverse\shared;
|
||||
#include maps\mp\gametypes\_spawnlogic;
|
||||
|
||||
main( bscriptgened, bcsvgened, bsgenabled )
|
||||
{
|
||||
if ( !isdefined( level.script_gen_dump_reasons ) )
|
||||
level.script_gen_dump_reasons = [];
|
||||
|
||||
if ( !isdefined( bsgenabled ) )
|
||||
level.script_gen_dump_reasons[level.script_gen_dump_reasons.size] = "First run";
|
||||
|
||||
if ( !isdefined( bcsvgened ) )
|
||||
bcsvgened = 0;
|
||||
|
||||
level.bcsvgened = bcsvgened;
|
||||
|
||||
if ( !isdefined( bscriptgened ) )
|
||||
bscriptgened = 0;
|
||||
else
|
||||
bscriptgened = 1;
|
||||
|
||||
level.bscriptgened = bscriptgened;
|
||||
level._loadstarted = 1;
|
||||
struct_class_init();
|
||||
level.clientscripts = getdvar( "cg_usingClientScripts" ) != "";
|
||||
level._client_exploders = [];
|
||||
level._client_exploder_ids = [];
|
||||
|
||||
if ( !isdefined( level.flag ) )
|
||||
{
|
||||
level.flag = [];
|
||||
level.flags_lock = [];
|
||||
}
|
||||
|
||||
if ( !isdefined( level.timeofday ) )
|
||||
level.timeofday = "day";
|
||||
|
||||
flag_init( "scriptgen_done" );
|
||||
level.script_gen_dump_reasons = [];
|
||||
|
||||
if ( !isdefined( level.script_gen_dump ) )
|
||||
{
|
||||
level.script_gen_dump = [];
|
||||
level.script_gen_dump_reasons[0] = "First run";
|
||||
}
|
||||
|
||||
if ( !isdefined( level.script_gen_dump2 ) )
|
||||
level.script_gen_dump2 = [];
|
||||
|
||||
if ( isdefined( level.createfxent ) )
|
||||
script_gen_dump_addline( "maps\\mp\\createfx\\" + level.script + "_fx::main();", level.script + "_fx" );
|
||||
|
||||
if ( isdefined( level.script_gen_dump_preload ) )
|
||||
{
|
||||
for ( i = 0; i < level.script_gen_dump_preload.size; i++ )
|
||||
script_gen_dump_addline( level.script_gen_dump_preload[i].string, level.script_gen_dump_preload[i].signature );
|
||||
}
|
||||
|
||||
if ( getdvar( "scr_RequiredMapAspectratio" ) == "" )
|
||||
setdvar( "scr_RequiredMapAspectratio", "1" );
|
||||
|
||||
setdvar( "r_waterFogTest", 0 );
|
||||
setdvar( "tu6_player_shallowWaterHeight", "0.0" );
|
||||
precacherumble( "reload_small" );
|
||||
precacherumble( "reload_medium" );
|
||||
precacherumble( "reload_large" );
|
||||
precacherumble( "reload_clipin" );
|
||||
precacherumble( "reload_clipout" );
|
||||
precacherumble( "reload_rechamber" );
|
||||
precacherumble( "pullout_small" );
|
||||
precacherumble( "buzz_high" );
|
||||
precacherumble( "riotshield_impact" );
|
||||
registerclientsys( "levelNotify" );
|
||||
level.aitriggerspawnflags = getaitriggerflags();
|
||||
level.vehicletriggerspawnflags = getvehicletriggerflags();
|
||||
level.physicstracemaskphysics = 1;
|
||||
level.physicstracemaskvehicle = 2;
|
||||
level.physicstracemaskwater = 4;
|
||||
level.physicstracemaskclip = 8;
|
||||
level.physicstracecontentsvehicleclip = 16;
|
||||
level.createfx_enabled = getdvar( "createfx" ) != "";
|
||||
|
||||
if ( !sessionmodeiszombiesgame() )
|
||||
{
|
||||
thread maps\mp\gametypes\_spawning::init();
|
||||
thread maps\mp\gametypes\_tweakables::init();
|
||||
thread maps\mp\_destructible::init();
|
||||
thread maps\mp\_riotshield::register();
|
||||
thread maps\mp\_vehicles::init();
|
||||
thread maps\mp\killstreaks\_dogs::init();
|
||||
thread maps\mp\killstreaks\_ai_tank::register();
|
||||
thread maps\mp\killstreaks\_rcbomb::register();
|
||||
thread maps\mp\killstreaks\_helicopter_guard::register();
|
||||
thread maps\mp\_trophy_system::register();
|
||||
thread maps\mp\_proximity_grenade::register();
|
||||
maps\mp\_audio::init();
|
||||
thread maps\mp\_busing::businit();
|
||||
thread maps\mp\_music::music_init();
|
||||
thread maps\mp\_fxanim::init();
|
||||
}
|
||||
else
|
||||
{
|
||||
level thread start_intro_screen_zm();
|
||||
thread maps\mp\_interactive_objects::init();
|
||||
maps\mp\_audio::init();
|
||||
thread maps\mp\_busing::businit();
|
||||
thread maps\mp\_music::music_init();
|
||||
thread maps\mp\_fxanim::init();
|
||||
thread maps\mp\_serverfaceanim_mp::init();
|
||||
|
||||
if ( level.createfx_enabled )
|
||||
setinitialplayersconnected();
|
||||
}
|
||||
|
||||
visionsetnight( "default_night" );
|
||||
setup_traversals();
|
||||
maps\mp\_art::main();
|
||||
setupexploders();
|
||||
parse_structs();
|
||||
|
||||
if ( sessionmodeiszombiesgame() )
|
||||
thread footsteps();
|
||||
/#
|
||||
level thread level_notify_listener();
|
||||
level thread client_notify_listener();
|
||||
#/
|
||||
thread maps\mp\_createfx::fx_init();
|
||||
|
||||
if ( level.createfx_enabled )
|
||||
{
|
||||
calculate_map_center();
|
||||
maps\mp\_createfx::createfx();
|
||||
}
|
||||
|
||||
if ( getdvar( "r_reflectionProbeGenerate" ) == "1" )
|
||||
{
|
||||
maps\mp\_global_fx::main();
|
||||
|
||||
level waittill( "eternity" );
|
||||
}
|
||||
|
||||
thread maps\mp\_global_fx::main();
|
||||
maps\mp\_demo::init();
|
||||
|
||||
if ( !sessionmodeiszombiesgame() )
|
||||
thread maps\mp\_development_dvars::init();
|
||||
|
||||
for ( p = 0; p < 6; p++ )
|
||||
{
|
||||
switch ( p )
|
||||
{
|
||||
case 0:
|
||||
triggertype = "trigger_multiple";
|
||||
break;
|
||||
case 1:
|
||||
triggertype = "trigger_once";
|
||||
break;
|
||||
case 2:
|
||||
triggertype = "trigger_use";
|
||||
break;
|
||||
case 3:
|
||||
triggertype = "trigger_radius";
|
||||
break;
|
||||
case 4:
|
||||
triggertype = "trigger_lookat";
|
||||
break;
|
||||
default:
|
||||
assert( p == 5 );
|
||||
triggertype = "trigger_damage";
|
||||
break;
|
||||
}
|
||||
|
||||
triggers = getentarray( triggertype, "classname" );
|
||||
|
||||
for ( i = 0; i < triggers.size; i++ )
|
||||
{
|
||||
if ( isdefined( triggers[i].script_prefab_exploder ) )
|
||||
triggers[i].script_exploder = triggers[i].script_prefab_exploder;
|
||||
|
||||
if ( isdefined( triggers[i].script_exploder ) )
|
||||
level thread maps\mp\_load::exploder_load( triggers[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
level_notify_listener()
|
||||
{
|
||||
while ( true )
|
||||
{
|
||||
val = getdvar( "level_notify" );
|
||||
|
||||
if ( val != "" )
|
||||
{
|
||||
level notify( val );
|
||||
setdvar( "level_notify", "" );
|
||||
}
|
||||
|
||||
wait 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
client_notify_listener()
|
||||
{
|
||||
while ( true )
|
||||
{
|
||||
val = getdvar( "client_notify" );
|
||||
|
||||
if ( val != "" )
|
||||
{
|
||||
clientnotify( val );
|
||||
setdvar( "client_notify", "" );
|
||||
}
|
||||
|
||||
wait 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
footsteps()
|
||||
{
|
||||
maps\mp\animscripts\utility::setfootstepeffect( "asphalt", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps\mp\animscripts\utility::setfootstepeffect( "brick", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps\mp\animscripts\utility::setfootstepeffect( "carpet", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps\mp\animscripts\utility::setfootstepeffect( "cloth", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps\mp\animscripts\utility::setfootstepeffect( "concrete", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps\mp\animscripts\utility::setfootstepeffect( "dirt", loadfx( "bio/player/fx_footstep_sand" ) );
|
||||
maps\mp\animscripts\utility::setfootstepeffect( "foliage", loadfx( "bio/player/fx_footstep_sand" ) );
|
||||
maps\mp\animscripts\utility::setfootstepeffect( "gravel", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps\mp\animscripts\utility::setfootstepeffect( "grass", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps\mp\animscripts\utility::setfootstepeffect( "metal", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps\mp\animscripts\utility::setfootstepeffect( "mud", loadfx( "bio/player/fx_footstep_mud" ) );
|
||||
maps\mp\animscripts\utility::setfootstepeffect( "paper", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps\mp\animscripts\utility::setfootstepeffect( "plaster", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps\mp\animscripts\utility::setfootstepeffect( "rock", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
maps\mp\animscripts\utility::setfootstepeffect( "sand", loadfx( "bio/player/fx_footstep_sand" ) );
|
||||
maps\mp\animscripts\utility::setfootstepeffect( "water", loadfx( "bio/player/fx_footstep_water" ) );
|
||||
maps\mp\animscripts\utility::setfootstepeffect( "wood", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||
}
|
||||
|
||||
parse_structs()
|
||||
{
|
||||
for ( i = 0; i < level.struct.size; i++ )
|
||||
{
|
||||
if ( isdefined( level.struct[i].targetname ) )
|
||||
{
|
||||
if ( level.struct[i].targetname == "flak_fire_fx" )
|
||||
{
|
||||
level._effect["flak20_fire_fx"] = loadfx( "weapon/tracer/fx_tracer_flak_single_noExp" );
|
||||
level._effect["flak38_fire_fx"] = loadfx( "weapon/tracer/fx_tracer_quad_20mm_Flak38_noExp" );
|
||||
level._effect["flak_cloudflash_night"] = loadfx( "weapon/flak/fx_flak_cloudflash_night" );
|
||||
level._effect["flak_burst_single"] = loadfx( "weapon/flak/fx_flak_single_day_dist" );
|
||||
}
|
||||
|
||||
if ( level.struct[i].targetname == "fake_fire_fx" )
|
||||
level._effect["distant_muzzleflash"] = loadfx( "weapon/muzzleflashes/heavy" );
|
||||
|
||||
if ( level.struct[i].targetname == "spotlight_fx" )
|
||||
level._effect["spotlight_beam"] = loadfx( "env/light/fx_ray_spotlight_md" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exploder_load( trigger )
|
||||
{
|
||||
level endon( "killexplodertridgers" + trigger.script_exploder );
|
||||
|
||||
trigger waittill( "trigger" );
|
||||
|
||||
if ( isdefined( trigger.script_chance ) && randomfloat( 1 ) > trigger.script_chance )
|
||||
{
|
||||
if ( isdefined( trigger.script_delay ) )
|
||||
wait( trigger.script_delay );
|
||||
else
|
||||
wait 4;
|
||||
|
||||
level thread exploder_load( trigger );
|
||||
return;
|
||||
}
|
||||
|
||||
maps\mp\_utility::exploder( trigger.script_exploder );
|
||||
level notify( "killexplodertridgers" + trigger.script_exploder );
|
||||
}
|
||||
|
||||
setupexploders()
|
||||
{
|
||||
ents = getentarray( "script_brushmodel", "classname" );
|
||||
smodels = getentarray( "script_model", "classname" );
|
||||
|
||||
for ( i = 0; i < smodels.size; i++ )
|
||||
ents[ents.size] = smodels[i];
|
||||
|
||||
for ( i = 0; i < ents.size; i++ )
|
||||
{
|
||||
if ( isdefined( ents[i].script_prefab_exploder ) )
|
||||
ents[i].script_exploder = ents[i].script_prefab_exploder;
|
||||
|
||||
if ( isdefined( ents[i].script_exploder ) )
|
||||
{
|
||||
if ( ents[i].model == "fx" && ( !isdefined( ents[i].targetname ) || ents[i].targetname != "exploderchunk" ) )
|
||||
{
|
||||
ents[i] hide();
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isdefined( ents[i].targetname ) && ents[i].targetname == "exploder" )
|
||||
{
|
||||
ents[i] hide();
|
||||
ents[i] notsolid();
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isdefined( ents[i].targetname ) && ents[i].targetname == "exploderchunk" )
|
||||
{
|
||||
ents[i] hide();
|
||||
ents[i] notsolid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
script_exploders = [];
|
||||
potentialexploders = getentarray( "script_brushmodel", "classname" );
|
||||
|
||||
for ( i = 0; i < potentialexploders.size; i++ )
|
||||
{
|
||||
if ( isdefined( potentialexploders[i].script_prefab_exploder ) )
|
||||
potentialexploders[i].script_exploder = potentialexploders[i].script_prefab_exploder;
|
||||
|
||||
if ( isdefined( potentialexploders[i].script_exploder ) )
|
||||
script_exploders[script_exploders.size] = potentialexploders[i];
|
||||
}
|
||||
|
||||
potentialexploders = getentarray( "script_model", "classname" );
|
||||
|
||||
for ( i = 0; i < potentialexploders.size; i++ )
|
||||
{
|
||||
if ( isdefined( potentialexploders[i].script_prefab_exploder ) )
|
||||
potentialexploders[i].script_exploder = potentialexploders[i].script_prefab_exploder;
|
||||
|
||||
if ( isdefined( potentialexploders[i].script_exploder ) )
|
||||
script_exploders[script_exploders.size] = potentialexploders[i];
|
||||
}
|
||||
|
||||
potentialexploders = getentarray( "item_health", "classname" );
|
||||
|
||||
for ( i = 0; i < potentialexploders.size; i++ )
|
||||
{
|
||||
if ( isdefined( potentialexploders[i].script_prefab_exploder ) )
|
||||
potentialexploders[i].script_exploder = potentialexploders[i].script_prefab_exploder;
|
||||
|
||||
if ( isdefined( potentialexploders[i].script_exploder ) )
|
||||
script_exploders[script_exploders.size] = potentialexploders[i];
|
||||
}
|
||||
|
||||
if ( !isdefined( level.createfxent ) )
|
||||
level.createfxent = [];
|
||||
|
||||
acceptabletargetnames = [];
|
||||
acceptabletargetnames["exploderchunk visible"] = 1;
|
||||
acceptabletargetnames["exploderchunk"] = 1;
|
||||
acceptabletargetnames["exploder"] = 1;
|
||||
|
||||
for ( i = 0; i < script_exploders.size; i++ )
|
||||
{
|
||||
exploder = script_exploders[i];
|
||||
ent = createexploder( exploder.script_fxid );
|
||||
ent.v = [];
|
||||
ent.v["origin"] = exploder.origin;
|
||||
ent.v["angles"] = exploder.angles;
|
||||
ent.v["delay"] = exploder.script_delay;
|
||||
ent.v["firefx"] = exploder.script_firefx;
|
||||
ent.v["firefxdelay"] = exploder.script_firefxdelay;
|
||||
ent.v["firefxsound"] = exploder.script_firefxsound;
|
||||
ent.v["firefxtimeout"] = exploder.script_firefxtimeout;
|
||||
ent.v["earthquake"] = exploder.script_earthquake;
|
||||
ent.v["damage"] = exploder.script_damage;
|
||||
ent.v["damage_radius"] = exploder.script_radius;
|
||||
ent.v["soundalias"] = exploder.script_soundalias;
|
||||
ent.v["repeat"] = exploder.script_repeat;
|
||||
ent.v["delay_min"] = exploder.script_delay_min;
|
||||
ent.v["delay_max"] = exploder.script_delay_max;
|
||||
ent.v["target"] = exploder.target;
|
||||
ent.v["ender"] = exploder.script_ender;
|
||||
ent.v["type"] = "exploder";
|
||||
|
||||
if ( !isdefined( exploder.script_fxid ) )
|
||||
ent.v["fxid"] = "No FX";
|
||||
else
|
||||
ent.v["fxid"] = exploder.script_fxid;
|
||||
|
||||
ent.v["exploder"] = exploder.script_exploder;
|
||||
assert( isdefined( exploder.script_exploder ), "Exploder at origin " + exploder.origin + " has no script_exploder" );
|
||||
|
||||
if ( !isdefined( ent.v["delay"] ) )
|
||||
ent.v["delay"] = 0;
|
||||
|
||||
if ( isdefined( exploder.target ) )
|
||||
{
|
||||
org = getent( ent.v["target"], "targetname" ).origin;
|
||||
ent.v["angles"] = vectortoangles( org - ent.v["origin"] );
|
||||
}
|
||||
|
||||
if ( exploder.classname == "script_brushmodel" || isdefined( exploder.model ) )
|
||||
{
|
||||
ent.model = exploder;
|
||||
ent.model.disconnect_paths = exploder.script_disconnectpaths;
|
||||
}
|
||||
|
||||
if ( isdefined( exploder.targetname ) && isdefined( acceptabletargetnames[exploder.targetname] ) )
|
||||
ent.v["exploder_type"] = exploder.targetname;
|
||||
else
|
||||
ent.v["exploder_type"] = "normal";
|
||||
|
||||
ent maps\mp\_createfx::post_entity_creation_function();
|
||||
}
|
||||
|
||||
level.createfxexploders = [];
|
||||
|
||||
for ( i = 0; i < level.createfxent.size; i++ )
|
||||
{
|
||||
ent = level.createfxent[i];
|
||||
|
||||
if ( ent.v["type"] != "exploder" )
|
||||
continue;
|
||||
|
||||
ent.v["exploder_id"] = getexploderid( ent );
|
||||
|
||||
if ( !isdefined( level.createfxexploders[ent.v["exploder"]] ) )
|
||||
level.createfxexploders[ent.v["exploder"]] = [];
|
||||
|
||||
level.createfxexploders[ent.v["exploder"]][level.createfxexploders[ent.v["exploder"]].size] = ent;
|
||||
}
|
||||
}
|
||||
|
||||
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 maps\mp\animscripts\traverse\shared::init_traverse();
|
||||
}
|
||||
}
|
||||
|
||||
calculate_map_center()
|
||||
{
|
||||
if ( !isdefined( level.mapcenter ) )
|
||||
{
|
||||
level.nodesmins = ( 0, 0, 0 );
|
||||
level.nodesmaxs = ( 0, 0, 0 );
|
||||
level.mapcenter = maps\mp\gametypes\_spawnlogic::findboxcenter( level.nodesmins, level.nodesmaxs );
|
||||
/#
|
||||
println( "map center: ", level.mapcenter );
|
||||
#/
|
||||
setmapcenter( level.mapcenter );
|
||||
}
|
||||
}
|
||||
|
||||
start_intro_screen_zm()
|
||||
{
|
||||
if ( level.createfx_enabled )
|
||||
return;
|
||||
|
||||
if ( !isdefined( level.introscreen ) )
|
||||
{
|
||||
level.introscreen = newhudelem();
|
||||
level.introscreen.x = 0;
|
||||
level.introscreen.y = 0;
|
||||
level.introscreen.horzalign = "fullscreen";
|
||||
level.introscreen.vertalign = "fullscreen";
|
||||
level.introscreen.foreground = 0;
|
||||
level.introscreen setshader( "black", 640, 480 );
|
||||
wait 0.05;
|
||||
}
|
||||
|
||||
level.introscreen.alpha = 1;
|
||||
players = get_players();
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
players[i] freezecontrols( 1 );
|
||||
|
||||
wait 1;
|
||||
}
|
44
MP/Core/maps/mp/_medals.gsc
Normal file
44
MP/Core/maps/mp/_medals.gsc
Normal file
@ -0,0 +1,44 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\_scoreevents;
|
||||
#include common_scripts\utility;
|
||||
|
||||
init()
|
||||
{
|
||||
level.medalinfo = [];
|
||||
level.medalcallbacks = [];
|
||||
level.numkills = 0;
|
||||
level thread onplayerconnect();
|
||||
}
|
||||
|
||||
onplayerconnect()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
player.lastkilledby = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
setlastkilledby( attacker )
|
||||
{
|
||||
self.lastkilledby = attacker;
|
||||
}
|
||||
|
||||
offenseglobalcount()
|
||||
{
|
||||
level.globalteammedals++;
|
||||
}
|
||||
|
||||
defenseglobalcount()
|
||||
{
|
||||
level.globalteammedals++;
|
||||
}
|
||||
|
||||
codecallback_medal( medalindex )
|
||||
{
|
||||
self luinotifyevent( &"medal_received", 1, medalindex );
|
||||
self luinotifyeventtospectators( &"medal_received", 1, medalindex );
|
||||
}
|
7
MP/Core/maps/mp/_menus.gsc
Normal file
7
MP/Core/maps/mp/_menus.gsc
Normal file
@ -0,0 +1,7 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
|
||||
init()
|
||||
{
|
||||
|
||||
}
|
277
MP/Core/maps/mp/_mgturret.gsc
Normal file
277
MP/Core/maps/mp/_mgturret.gsc
Normal file
@ -0,0 +1,277 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( getdvar( _hash_7C9A91DF ) == "" )
|
||||
setdvar( "mgTurret", "off" );
|
||||
|
||||
level.magic_distance = 24;
|
||||
turretinfos = getentarray( "turretInfo", "targetname" );
|
||||
|
||||
for ( index = 0; index < turretinfos.size; index++ )
|
||||
turretinfos[index] delete();
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
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"] = 0.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"] = 0.4;
|
||||
level.mgturretsettings["fu"]["suppressionTime"] = 3.0;
|
||||
level.mgturretsettings["fu"]["accuracy"] = 0.38;
|
||||
level.mgturretsettings["fu"]["aiSpread"] = 2;
|
||||
level.mgturretsettings["fu"]["playerSpread"] = 0.5;
|
||||
}
|
||||
|
||||
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"];
|
||||
}
|
||||
|
||||
turret_suppression_fire( targets )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "stop_suppression_fire" );
|
||||
|
||||
if ( !isdefined( self.suppresionfire ) )
|
||||
self.suppresionfire = 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
while ( self.suppresionfire )
|
||||
{
|
||||
self settargetentity( targets[randomint( targets.size )] );
|
||||
wait( 2 + randomfloat( 2 ) );
|
||||
}
|
||||
|
||||
self cleartargetentity();
|
||||
|
||||
while ( !self.suppresionfire )
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
|
||||
burst_fire_settings( setting )
|
||||
{
|
||||
if ( setting == "delay" )
|
||||
return 0.2;
|
||||
else if ( setting == "delay_range" )
|
||||
return 0.5;
|
||||
else if ( setting == "burst" )
|
||||
return 0.5;
|
||||
else if ( setting == "burst_range" )
|
||||
return 4;
|
||||
}
|
||||
|
||||
burst_fire( turret, manual_target )
|
||||
{
|
||||
turret endon( "death" );
|
||||
turret endon( "stopfiring" );
|
||||
self endon( "stop_using_built_in_burst_fire" );
|
||||
|
||||
if ( isdefined( turret.script_delay_min ) )
|
||||
turret_delay = turret.script_delay_min;
|
||||
else
|
||||
turret_delay = burst_fire_settings( "delay" );
|
||||
|
||||
if ( isdefined( turret.script_delay_max ) )
|
||||
turret_delay_range = turret.script_delay_max - turret_delay;
|
||||
else
|
||||
turret_delay_range = burst_fire_settings( "delay_range" );
|
||||
|
||||
if ( isdefined( turret.script_burst_min ) )
|
||||
turret_burst = turret.script_burst_min;
|
||||
else
|
||||
turret_burst = burst_fire_settings( "burst" );
|
||||
|
||||
if ( isdefined( turret.script_burst_max ) )
|
||||
turret_burst_range = turret.script_burst_max - turret_burst;
|
||||
else
|
||||
turret_burst_range = burst_fire_settings( "burst_range" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
turret startfiring();
|
||||
|
||||
if ( isdefined( manual_target ) )
|
||||
turret thread random_spread( manual_target );
|
||||
|
||||
turret do_shoot();
|
||||
wait( turret_burst + randomfloat( turret_burst_range ) );
|
||||
turret stopshootturret();
|
||||
turret stopfiring();
|
||||
wait( turret_delay + randomfloat( turret_delay_range ) );
|
||||
}
|
||||
}
|
||||
|
||||
burst_fire_unmanned()
|
||||
{
|
||||
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";
|
||||
self.script_shooting = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ( isdefined( self.manual_targets ) )
|
||||
{
|
||||
self cleartargetentity();
|
||||
self settargetentity( self.manual_targets[randomint( self.manual_targets.size )] );
|
||||
}
|
||||
|
||||
duration = ( pauseuntiltime - gettime() ) * 0.001;
|
||||
|
||||
if ( self isfiringturret() && duration <= 0 )
|
||||
{
|
||||
if ( turretstate != "fire" )
|
||||
{
|
||||
turretstate = "fire";
|
||||
self playsound( "mpl_turret_alert" );
|
||||
self thread do_shoot();
|
||||
self.script_shooting = 1;
|
||||
}
|
||||
|
||||
duration = turret_burst + randomfloat( turret_burst_range );
|
||||
self thread turret_timer( duration );
|
||||
|
||||
self waittill( "turretstatechange" );
|
||||
|
||||
self.script_shooting = 0;
|
||||
duration = turret_delay + randomfloat( turret_delay_range );
|
||||
pauseuntiltime = gettime() + int( duration * 1000 );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( turretstate != "aim" )
|
||||
turretstate = "aim";
|
||||
|
||||
self thread turret_timer( duration );
|
||||
|
||||
self waittill( "turretstatechange" );
|
||||
}
|
||||
}
|
||||
|
||||
do_shoot()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "turretstatechange" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self shootturret();
|
||||
wait 0.112;
|
||||
}
|
||||
}
|
||||
|
||||
turret_timer( duration )
|
||||
{
|
||||
if ( duration <= 0 )
|
||||
return;
|
||||
|
||||
self endon( "turretstatechange" );
|
||||
wait( duration );
|
||||
|
||||
if ( isdefined( self ) )
|
||||
self notify( "turretstatechange" );
|
||||
}
|
||||
|
||||
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 ( true )
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
7
MP/Core/maps/mp/_multi_extracam.gsc
Normal file
7
MP/Core/maps/mp/_multi_extracam.gsc
Normal file
@ -0,0 +1,7 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
|
||||
init()
|
||||
{
|
||||
|
||||
}
|
26
MP/Core/maps/mp/_music.gsc
Normal file
26
MP/Core/maps/mp/_music.gsc
Normal file
@ -0,0 +1,26 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
|
||||
music_init()
|
||||
{
|
||||
assert( level.clientscripts );
|
||||
level.musicstate = "";
|
||||
registerclientsys( "musicCmd" );
|
||||
}
|
||||
|
||||
setmusicstate( state, player )
|
||||
{
|
||||
if ( isdefined( level.musicstate ) )
|
||||
{
|
||||
if ( isdefined( player ) )
|
||||
{
|
||||
setclientsysstate( "musicCmd", state, player );
|
||||
return;
|
||||
}
|
||||
else if ( level.musicstate != state )
|
||||
setclientsysstate( "musicCmd", state );
|
||||
}
|
||||
|
||||
level.musicstate = state;
|
||||
}
|
7
MP/Core/maps/mp/_pc.gsc
Normal file
7
MP/Core/maps/mp/_pc.gsc
Normal file
@ -0,0 +1,7 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
|
||||
pcserver()
|
||||
{
|
||||
pcserverupdateplaylist();
|
||||
}
|
331
MP/Core/maps/mp/_popups.gsc
Normal file
331
MP/Core/maps/mp/_popups.gsc
Normal file
@ -0,0 +1,331 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_medals;
|
||||
#include maps\mp\gametypes\_persistence;
|
||||
#include maps\mp\gametypes\_rank;
|
||||
#include maps\mp\gametypes\_hud_message;
|
||||
|
||||
init()
|
||||
{
|
||||
level.contractsettings = spawnstruct();
|
||||
level.contractsettings.waittime = 4.2;
|
||||
level.killstreaksettings = spawnstruct();
|
||||
level.killstreaksettings.waittime = 3;
|
||||
level.ranksettings = spawnstruct();
|
||||
level.ranksettings.waittime = 3;
|
||||
level.startmessage = spawnstruct();
|
||||
level.startmessagedefaultduration = 2.0;
|
||||
level.endmessagedefaultduration = 2.0;
|
||||
level.challengesettings = spawnstruct();
|
||||
level.challengesettings.waittime = 3;
|
||||
level.teammessage = spawnstruct();
|
||||
level.teammessage.waittime = 3;
|
||||
level.regulargamemessages = spawnstruct();
|
||||
level.regulargamemessages.waittime = 6;
|
||||
level.wagersettings = spawnstruct();
|
||||
level.wagersettings.waittime = 3;
|
||||
level.momentumnotifywaittime = 0;
|
||||
level.momentumnotifywaitlasttime = 0;
|
||||
level.teammessagequeuemax = 8;
|
||||
precachestring( &"KILLSTREAK_DESTROYED_UAV" );
|
||||
precachestring( &"KILLSTREAK_DESTROYED_COUNTERUAV" );
|
||||
precachestring( &"KILLSTREAK_DESTROYED_REMOTE_MORTAR" );
|
||||
precachestring( &"KILLSTREAK_MP40_INBOUND" );
|
||||
precachestring( &"KILLSTREAK_M220_TOW_INBOUND" );
|
||||
precachestring( &"KILLSTREAK_MINIGUN_INBOUND" );
|
||||
precachestring( &"KILLSTREAK_M202_FLASH_INBOUND" );
|
||||
precachestring( &"KILLSTREAK_M32_INBOUND" );
|
||||
precachestring( &"MP_CAPTURED_THE_FLAG" );
|
||||
precachestring( &"MP_KILLED_FLAG_CARRIER" );
|
||||
precachestring( &"MP_FRIENDLY_FLAG_DROPPED" );
|
||||
precachestring( &"MP_ENEMY_FLAG_DROPPED" );
|
||||
precachestring( &"MP_FRIENDLY_FLAG_RETURNED" );
|
||||
precachestring( &"MP_ENEMY_FLAG_RETURNED" );
|
||||
precachestring( &"MP_FRIENDLY_FLAG_TAKEN" );
|
||||
precachestring( &"MP_ENEMY_FLAG_TAKEN" );
|
||||
precachestring( &"MP_ENEMY_FLAG_CAPTURED" );
|
||||
precachestring( &"MP_FRIENDLY_FLAG_CAPTURED" );
|
||||
precachestring( &"MP_EXPLOSIVES_BLOWUP_BY" );
|
||||
precachestring( &"MP_EXPLOSIVES_DEFUSED_BY" );
|
||||
precachestring( &"MP_EXPLOSIVES_PLANTED_BY" );
|
||||
precachestring( &"MP_HQ_DESTROYED_BY" );
|
||||
precachestring( &"KILLSTREAK_DESTROYED_HELICOPTER" );
|
||||
/#
|
||||
level thread popupsfromconsole();
|
||||
#/
|
||||
level thread onplayerconnect();
|
||||
}
|
||||
|
||||
popupsfromconsole()
|
||||
{
|
||||
/#
|
||||
while ( true )
|
||||
{
|
||||
timeout = getdvarintdefault( "scr_popuptime", 1.0 );
|
||||
|
||||
if ( timeout == 0 )
|
||||
timeout = 1;
|
||||
|
||||
wait( timeout );
|
||||
medal = getdvarintdefault( "scr_popupmedal", 0 );
|
||||
challenge = getdvarintdefault( "scr_popupchallenge", 0 );
|
||||
rank = getdvarintdefault( "scr_popuprank", 0 );
|
||||
gun = getdvarintdefault( "scr_popupgun", 0 );
|
||||
contractpass = getdvarintdefault( "scr_popupcontractpass", 0 );
|
||||
contractfail = getdvarintdefault( "scr_popupcontractfail", 0 );
|
||||
gamemodemsg = getdvarintdefault( "scr_gamemodeslideout", 0 );
|
||||
teammsg = getdvarintdefault( "scr_teamslideout", 0 );
|
||||
challengeindex = getdvarintdefault( "scr_challengeIndex", 1 );
|
||||
|
||||
for ( i = 0; i < medal; i++ )
|
||||
level.players[0] maps\mp\_medals::codecallback_medal( 4 );
|
||||
|
||||
for ( i = 0; i < challenge; i++ )
|
||||
{
|
||||
level.players[0] maps\mp\gametypes\_persistence::codecallback_challengecomplete( 2500, 1, 84, 3, 0, 0, 851 );
|
||||
level.players[0] maps\mp\gametypes\_persistence::codecallback_challengecomplete( 500, 1, 22, 2, 0, 0, 533 );
|
||||
}
|
||||
|
||||
for ( i = 0; i < rank; i++ )
|
||||
level.players[0] maps\mp\gametypes\_rank::codecallback_rankup( 4, 0, 0 );
|
||||
|
||||
for ( i = 0; i < gun; i++ )
|
||||
level.players[0] maps\mp\gametypes\_persistence::codecallback_gunchallengecomplete( 0, 20, 25, 0 );
|
||||
|
||||
for ( i = 0; i < contractpass; i++ )
|
||||
level.players[0] maps\mp\gametypes\_persistence::addcontracttoqueue( 12, 1 );
|
||||
|
||||
for ( i = 0; i < contractfail; i++ )
|
||||
level.players[0] maps\mp\gametypes\_persistence::addcontracttoqueue( 12, 0 );
|
||||
|
||||
for ( i = 0; i < teammsg; i++ )
|
||||
{
|
||||
player = level.players[0];
|
||||
|
||||
if ( isdefined( level.players[1] ) )
|
||||
player = level.players[1];
|
||||
|
||||
level.players[0] displayteammessagetoall( &"KILLSTREAK_DESTROYED_HELICOPTER", player );
|
||||
}
|
||||
|
||||
reset = getdvarintdefault( "scr_popupreset", 1 );
|
||||
|
||||
if ( reset )
|
||||
{
|
||||
if ( medal )
|
||||
setdvar( "scr_popupmedal", 0 );
|
||||
|
||||
if ( challenge )
|
||||
setdvar( "scr_popupchallenge", 0 );
|
||||
|
||||
if ( gun )
|
||||
setdvar( "scr_popupgun", 0 );
|
||||
|
||||
if ( rank )
|
||||
setdvar( "scr_popuprank", 0 );
|
||||
|
||||
if ( contractpass )
|
||||
setdvar( "scr_popupcontractpass", 0 );
|
||||
|
||||
if ( contractfail )
|
||||
setdvar( "scr_popupcontractfail", 0 );
|
||||
|
||||
if ( gamemodemsg )
|
||||
setdvar( "scr_gamemodeslideout", 0 );
|
||||
|
||||
if ( teammsg )
|
||||
setdvar( "scr_teamslideout", 0 );
|
||||
}
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
displaykillstreakteammessagetoall( killstreak, player )
|
||||
{
|
||||
if ( !isdefined( level.killstreaks[killstreak] ) )
|
||||
return;
|
||||
|
||||
if ( !isdefined( level.killstreaks[killstreak].inboundtext ) )
|
||||
return;
|
||||
|
||||
message = level.killstreaks[killstreak].inboundtext;
|
||||
self displayteammessagetoall( message, player );
|
||||
}
|
||||
|
||||
shoulddisplayteammessages()
|
||||
{
|
||||
if ( level.hardcoremode == 1 || level.splitscreen == 1 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
displayteammessagetoall( message, player )
|
||||
{
|
||||
if ( !shoulddisplayteammessages() )
|
||||
return;
|
||||
|
||||
for ( i = 0; i < level.players.size; i++ )
|
||||
{
|
||||
cur_player = level.players[i];
|
||||
|
||||
if ( cur_player isempjammed() )
|
||||
continue;
|
||||
|
||||
size = cur_player.teammessagequeue.size;
|
||||
|
||||
if ( size >= level.teammessagequeuemax )
|
||||
continue;
|
||||
|
||||
cur_player.teammessagequeue[size] = spawnstruct();
|
||||
cur_player.teammessagequeue[size].message = message;
|
||||
cur_player.teammessagequeue[size].player = player;
|
||||
cur_player notify( "received teammessage" );
|
||||
}
|
||||
}
|
||||
|
||||
displayteammessagetoteam( message, player, team )
|
||||
{
|
||||
if ( !shoulddisplayteammessages() )
|
||||
return;
|
||||
|
||||
for ( i = 0; i < level.players.size; i++ )
|
||||
{
|
||||
cur_player = level.players[i];
|
||||
|
||||
if ( cur_player.team != team )
|
||||
continue;
|
||||
|
||||
if ( cur_player isempjammed() )
|
||||
continue;
|
||||
|
||||
size = cur_player.teammessagequeue.size;
|
||||
|
||||
if ( size >= level.teammessagequeuemax )
|
||||
continue;
|
||||
|
||||
cur_player.teammessagequeue[size] = spawnstruct();
|
||||
cur_player.teammessagequeue[size].message = message;
|
||||
cur_player.teammessagequeue[size].player = player;
|
||||
cur_player notify( "received teammessage" );
|
||||
}
|
||||
}
|
||||
|
||||
displayteammessagewaiter()
|
||||
{
|
||||
if ( !shoulddisplayteammessages() )
|
||||
return;
|
||||
|
||||
self endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
self.teammessagequeue = [];
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ( self.teammessagequeue.size == 0 )
|
||||
self waittill( "received teammessage" );
|
||||
|
||||
if ( self.teammessagequeue.size > 0 )
|
||||
{
|
||||
nextnotifydata = self.teammessagequeue[0];
|
||||
arrayremoveindex( self.teammessagequeue, 0, 0 );
|
||||
|
||||
if ( !isdefined( nextnotifydata.player ) || !isplayer( nextnotifydata.player ) )
|
||||
continue;
|
||||
|
||||
if ( self isempjammed() )
|
||||
continue;
|
||||
|
||||
self luinotifyevent( &"player_callout", 2, nextnotifydata.message, nextnotifydata.player.entnum );
|
||||
}
|
||||
|
||||
wait( level.teammessage.waittime );
|
||||
}
|
||||
}
|
||||
|
||||
displaypopupswaiter()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self.ranknotifyqueue = [];
|
||||
|
||||
if ( !isdefined( self.pers["challengeNotifyQueue"] ) )
|
||||
self.pers["challengeNotifyQueue"] = [];
|
||||
|
||||
if ( !isdefined( self.pers["contractNotifyQueue"] ) )
|
||||
self.pers["contractNotifyQueue"] = [];
|
||||
|
||||
self.messagenotifyqueue = [];
|
||||
self.startmessagenotifyqueue = [];
|
||||
self.wagernotifyqueue = [];
|
||||
|
||||
while ( !level.gameended )
|
||||
{
|
||||
if ( self.startmessagenotifyqueue.size == 0 && self.messagenotifyqueue.size == 0 )
|
||||
self waittill( "received award" );
|
||||
|
||||
waittillframeend;
|
||||
|
||||
if ( level.gameended )
|
||||
break;
|
||||
|
||||
if ( self.startmessagenotifyqueue.size > 0 )
|
||||
{
|
||||
nextnotifydata = self.startmessagenotifyqueue[0];
|
||||
arrayremoveindex( self.startmessagenotifyqueue, 0, 0 );
|
||||
|
||||
if ( isdefined( nextnotifydata.duration ) )
|
||||
duration = nextnotifydata.duration;
|
||||
else
|
||||
duration = level.startmessagedefaultduration;
|
||||
|
||||
self maps\mp\gametypes\_hud_message::shownotifymessage( nextnotifydata, duration );
|
||||
wait( duration );
|
||||
}
|
||||
else if ( self.messagenotifyqueue.size > 0 )
|
||||
{
|
||||
nextnotifydata = self.messagenotifyqueue[0];
|
||||
arrayremoveindex( self.messagenotifyqueue, 0, 0 );
|
||||
|
||||
if ( isdefined( nextnotifydata.duration ) )
|
||||
duration = nextnotifydata.duration;
|
||||
else
|
||||
duration = level.regulargamemessages.waittime;
|
||||
|
||||
self maps\mp\gametypes\_hud_message::shownotifymessage( nextnotifydata, duration );
|
||||
}
|
||||
else
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
|
||||
onplayerconnect()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
level waittill( "connecting", player );
|
||||
|
||||
player.resetgameoverhudrequired = 0;
|
||||
player thread displaypopupswaiter();
|
||||
|
||||
if ( !level.hardcoremode )
|
||||
player thread displayteammessagewaiter();
|
||||
}
|
||||
}
|
||||
|
||||
milestonenotify( index, itemindex, type, tier )
|
||||
{
|
||||
level.globalchallenges++;
|
||||
|
||||
if ( !isdefined( type ) )
|
||||
type = "global";
|
||||
|
||||
size = self.pers["challengeNotifyQueue"].size;
|
||||
self.pers["challengeNotifyQueue"][size] = [];
|
||||
self.pers["challengeNotifyQueue"][size]["tier"] = tier;
|
||||
self.pers["challengeNotifyQueue"][size]["index"] = index;
|
||||
self.pers["challengeNotifyQueue"][size]["itemIndex"] = itemindex;
|
||||
self.pers["challengeNotifyQueue"][size]["type"] = type;
|
||||
self notify( "received award" );
|
||||
}
|
247
MP/Core/maps/mp/_proximity_grenade.gsc
Normal file
247
MP/Core/maps/mp/_proximity_grenade.gsc
Normal file
@ -0,0 +1,247 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\gametypes\_weaponobjects;
|
||||
#include maps\mp\_challenges;
|
||||
#include maps\mp\_scoreevents;
|
||||
|
||||
init()
|
||||
{
|
||||
precacheshader( "gfx_fxt_fx_screen_droplets_02" );
|
||||
precacherumble( "proximity_grenade" );
|
||||
precacheitem( "proximity_grenade_aoe_mp" );
|
||||
level._effect["prox_grenade_friendly_default"] = loadfx( "weapon/grenade/fx_prox_grenade_scan_grn" );
|
||||
level._effect["prox_grenade_friendly_warning"] = loadfx( "weapon/grenade/fx_prox_grenade_wrn_grn" );
|
||||
level._effect["prox_grenade_enemy_default"] = loadfx( "weapon/grenade/fx_prox_grenade_scan_red" );
|
||||
level._effect["prox_grenade_enemy_warning"] = loadfx( "weapon/grenade/fx_prox_grenade_wrn_red" );
|
||||
level._effect["prox_grenade_player_shock"] = loadfx( "weapon/grenade/fx_prox_grenade_impact_player_spwner" );
|
||||
level.proximitygrenadedetectionradius = weapons_get_dvar_int( "scr_proximityGrenadeDetectionRadius", "150" );
|
||||
level.proximitygrenadegraceperiod = weapons_get_dvar( "scr_proximityGrenadeGracePeriod", 0.1 );
|
||||
level.proximitygrenadedamageradius = weapons_get_dvar_int( "scr_proximityGrenadeDamageRadius", "200" );
|
||||
level.proximitygrenadedotdamageamount = weapons_get_dvar_int( "scr_proximityGrenadeDOTDamageAmount", "1" );
|
||||
level.proximitygrenadedotdamageamounthardcore = weapons_get_dvar_int( "scr_proximityGrenadeDOTDamageAmountHardcore", "1" );
|
||||
level.proximitygrenadedotdamagetime = weapons_get_dvar( "scr_proximityGrenadeDOTDamageTime", 0.15 );
|
||||
level.proximitygrenadedotdamageinstances = weapons_get_dvar_int( "scr_proximityGrenadeDOTDamageInstances", "4" );
|
||||
level.proximitygrenademaxinstances = weapons_get_dvar_int( "scr_proximityGrenadeMaxInstances", "3" );
|
||||
level.proximitygrenadeeffectdebug = weapons_get_dvar_int( "scr_proximityGrenadeEffectDebug", "0" );
|
||||
level.proximitygrenadeactivationtime = weapons_get_dvar( "scr_proximityGrenadeActivationTime", 0.1 );
|
||||
level.poisonfxduration = 6;
|
||||
/#
|
||||
level thread updatedvars();
|
||||
#/
|
||||
}
|
||||
|
||||
register()
|
||||
{
|
||||
registerclientfield( "toplayer", "tazered", 1000, 1, "int" );
|
||||
}
|
||||
|
||||
updatedvars()
|
||||
{
|
||||
while ( true )
|
||||
{
|
||||
level.proximitygrenadedetectionradius = weapons_get_dvar_int( "scr_proximityGrenadeDetectionRadius", level.proximitygrenadedetectionradius );
|
||||
level.proximitygrenadegraceperiod = weapons_get_dvar( "scr_proximityGrenadeGracePeriod", level.proximitygrenadegraceperiod );
|
||||
level.proximitygrenadedamageradius = weapons_get_dvar_int( "scr_proximityGrenadeDamageRadius", level.proximitygrenadedamageradius );
|
||||
level.proximitygrenadedotdamageamount = weapons_get_dvar_int( "scr_proximityGrenadeDOTDamageAmount", level.proximitygrenadedotdamageamount );
|
||||
level.proximitygrenadedotdamageamounthardcore = weapons_get_dvar_int( "scr_proximityGrenadeDOTDamageAmountHardcore", level.proximitygrenadedotdamageamounthardcore );
|
||||
level.proximitygrenadedotdamagetime = weapons_get_dvar( "scr_proximityGrenadeDOTDamageTime", level.proximitygrenadedotdamagetime );
|
||||
level.proximitygrenadedotdamageinstances = weapons_get_dvar_int( "scr_proximityGrenadeDOTDamageInstances", level.proximitygrenadedotdamageinstances );
|
||||
level.proximitygrenademaxinstances = weapons_get_dvar_int( "scr_proximityGrenadeMaxInstances", level.proximitygrenademaxinstances );
|
||||
level.proximitygrenadeeffectdebug = weapons_get_dvar_int( "scr_proximityGrenadeEffectDebug", level.proximitygrenadeeffectdebug );
|
||||
level.proximitygrenadeactivationtime = weapons_get_dvar( "scr_proximityGrenadeActivationTime", level.proximitygrenadeactivationtime );
|
||||
wait 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
createproximitygrenadewatcher()
|
||||
{
|
||||
watcher = self maps\mp\gametypes\_weaponobjects::createproximityweaponobjectwatcher( "proximity_grenade", "proximity_grenade_mp", self.team );
|
||||
watcher.watchforfire = 1;
|
||||
watcher.hackable = 1;
|
||||
watcher.hackertoolradius = level.equipmenthackertoolradius;
|
||||
watcher.hackertooltimems = level.equipmenthackertooltimems;
|
||||
watcher.headicon = 0;
|
||||
watcher.reconmodel = "t6_wpn_taser_mine_world_detect";
|
||||
watcher.activatefx = 1;
|
||||
watcher.ownergetsassist = 1;
|
||||
watcher.ignoredirection = 1;
|
||||
watcher.immediatedetonation = 1;
|
||||
watcher.detectiongraceperiod = level.proximitygrenadegraceperiod;
|
||||
watcher.detonateradius = level.proximitygrenadedetectionradius;
|
||||
watcher.stun = maps\mp\gametypes\_weaponobjects::weaponstun;
|
||||
watcher.stuntime = 1;
|
||||
watcher.detonate = ::proximitydetonate;
|
||||
watcher.activationdelay = level.proximitygrenadeactivationtime;
|
||||
watcher.onspawn = ::onspawnproximitygrenadeweaponobject;
|
||||
}
|
||||
|
||||
onspawnproximitygrenadeweaponobject( watcher, owner )
|
||||
{
|
||||
self thread setupkillcament();
|
||||
owner addweaponstat( "proximity_grenade_mp", "used", 1 );
|
||||
onspawnproximityweaponobject( watcher, owner );
|
||||
}
|
||||
|
||||
setupkillcament()
|
||||
{
|
||||
self endon( "death" );
|
||||
self waittillnotmoving();
|
||||
self.killcament = spawn( "script_model", self.origin + vectorscale( ( 0, 0, 1 ), 8.0 ) );
|
||||
self thread cleanupkillcamentondeath();
|
||||
}
|
||||
|
||||
cleanupkillcamentondeath()
|
||||
{
|
||||
self waittill( "death" );
|
||||
|
||||
self.killcament deleteaftertime( 3 + level.proximitygrenadedotdamagetime * level.proximitygrenadedotdamageinstances );
|
||||
}
|
||||
|
||||
proximitydetonate( attacker, weaponname )
|
||||
{
|
||||
if ( isdefined( weaponname ) )
|
||||
{
|
||||
if ( isdefined( attacker ) )
|
||||
{
|
||||
if ( self.owner isenemyplayer( attacker ) )
|
||||
{
|
||||
attacker maps\mp\_challenges::destroyedexplosive( weaponname );
|
||||
maps\mp\_scoreevents::processscoreevent( "destroyed_proxy", attacker, self.owner, weaponname );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
maps\mp\gametypes\_weaponobjects::weapondetonate( attacker, weaponname );
|
||||
}
|
||||
|
||||
proximitygrenadedamageplayer( eattacker, einflictor )
|
||||
{
|
||||
if ( !self hasperk( "specialty_proximityprotection" ) )
|
||||
{
|
||||
if ( !level.proximitygrenadeeffectdebug )
|
||||
self thread damageplayerinradius( einflictor.origin, eattacker, einflictor );
|
||||
}
|
||||
}
|
||||
|
||||
watchproximitygrenadehitplayer( owner )
|
||||
{
|
||||
self endon( "death" );
|
||||
self setowner( owner );
|
||||
self setteam( owner.team );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self waittill( "grenade_bounce", pos, normal, ent, surface );
|
||||
|
||||
if ( isdefined( ent ) && isplayer( ent ) && surface != "riotshield" )
|
||||
{
|
||||
if ( level.teambased && ent.team == self.owner.team )
|
||||
continue;
|
||||
|
||||
self proximitydetonate( self.owner, undefined );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
performhudeffects( position, distancetogrenade )
|
||||
{
|
||||
forwardvec = vectornormalize( anglestoforward( self.angles ) );
|
||||
rightvec = vectornormalize( anglestoright( self.angles ) );
|
||||
explosionvec = vectornormalize( position - self.origin );
|
||||
fdot = vectordot( explosionvec, forwardvec );
|
||||
rdot = vectordot( explosionvec, rightvec );
|
||||
fangle = acos( fdot );
|
||||
rangle = acos( rdot );
|
||||
}
|
||||
|
||||
damageplayerinradius( position, owner, einflictor )
|
||||
{
|
||||
self notify( "proximityGrenadeDamageStart" );
|
||||
self endon( "proximityGrenadeDamageStart" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
owner endon( "disconnect" );
|
||||
self thread watch_death();
|
||||
|
||||
if ( !isdefined( einflictor.killcament ) )
|
||||
{
|
||||
killcament = spawn( "script_model", self.origin + vectorscale( ( 0, 0, 1 ), 8.0 ) );
|
||||
killcament deleteaftertime( 3 + level.proximitygrenadedotdamagetime * level.proximitygrenadedotdamageinstances );
|
||||
killcament.soundmod = "taser_spike";
|
||||
}
|
||||
else
|
||||
{
|
||||
killcament = einflictor.killcament;
|
||||
killcament.soundmod = "taser_spike";
|
||||
}
|
||||
|
||||
damage = level.proximitygrenadedotdamageamount;
|
||||
playfxontag( level._effect["prox_grenade_player_shock"], self, "J_SpineUpper" );
|
||||
|
||||
if ( level.hardcoremode )
|
||||
damage = level.proximitygrenadedotdamageamounthardcore;
|
||||
|
||||
if ( self mayapplyscreeneffect() )
|
||||
{
|
||||
shellshock_duration = 1.5;
|
||||
self shellshock( "proximity_grenade", shellshock_duration, 0 );
|
||||
self setclientfieldtoplayer( "tazered", 1 );
|
||||
}
|
||||
|
||||
self playrumbleonentity( "proximity_grenade" );
|
||||
self playsound( "wpn_taser_mine_zap" );
|
||||
self setclientuivisibilityflag( "hud_visible", 0 );
|
||||
|
||||
for ( i = 0; i < level.proximitygrenadedotdamageinstances; i++ )
|
||||
{
|
||||
wait( level.proximitygrenadedotdamagetime );
|
||||
assert( isdefined( owner ) );
|
||||
assert( isdefined( killcament ) );
|
||||
self dodamage( damage, position, owner, killcament, "none", "MOD_GAS", 0, "proximity_grenade_aoe_mp" );
|
||||
}
|
||||
|
||||
wait 0.85;
|
||||
self shellshock( "proximity_grenade_exit", 0.6, 0 );
|
||||
self setclientuivisibilityflag( "hud_visible", 1 );
|
||||
self setclientfieldtoplayer( "tazered", 0 );
|
||||
}
|
||||
|
||||
deleteentonownerdeath( owner )
|
||||
{
|
||||
self thread deleteentontimeout();
|
||||
self thread deleteentaftertime();
|
||||
self endon( "delete" );
|
||||
|
||||
owner waittill( "death" );
|
||||
|
||||
self notify( "deleteSound" );
|
||||
}
|
||||
|
||||
deleteentaftertime()
|
||||
{
|
||||
self endon( "delete" );
|
||||
wait 10.0;
|
||||
self notify( "deleteSound" );
|
||||
}
|
||||
|
||||
deleteentontimeout()
|
||||
{
|
||||
self endon( "delete" );
|
||||
|
||||
self waittill( "deleteSound" );
|
||||
|
||||
self delete();
|
||||
}
|
||||
|
||||
watch_death()
|
||||
{
|
||||
self waittill( "death" );
|
||||
|
||||
self stoprumble( "proximity_grenade" );
|
||||
self setblur( 0, 0 );
|
||||
self setclientuivisibilityflag( "hud_visible", 1 );
|
||||
self setclientfieldtoplayer( "tazered", 0 );
|
||||
}
|
453
MP/Core/maps/mp/_riotshield.gsc
Normal file
453
MP/Core/maps/mp/_riotshield.gsc
Normal file
@ -0,0 +1,453 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\killstreaks\_killstreaks;
|
||||
#include maps\mp\killstreaks\_killstreak_weapons;
|
||||
#include maps\mp\_scoreevents;
|
||||
|
||||
#using_animtree("mp_riotshield");
|
||||
|
||||
init()
|
||||
{
|
||||
if ( !isdefined( level.riotshield_name ) )
|
||||
{
|
||||
level.riotshield_name = "riotshield_mp";
|
||||
|
||||
if ( isdefined( level.is_zombie_level ) && level.is_zombie_level )
|
||||
level.riotshield_name = "riotshield_zm";
|
||||
}
|
||||
|
||||
level.deployedshieldmodel = "t6_wpn_shield_carry_world";
|
||||
level.stowedshieldmodel = "t6_wpn_shield_stow_world";
|
||||
level.carriedshieldmodel = "t6_wpn_shield_carry_world";
|
||||
level.detectshieldmodel = "t6_wpn_shield_carry_world_detect";
|
||||
|
||||
if ( isdefined( level.is_zombie_level ) && level.is_zombie_level )
|
||||
{
|
||||
level.deployedshieldmodel = "t6_wpn_zmb_shield_world";
|
||||
level.stowedshieldmodel = "t6_wpn_zmb_shield_stow";
|
||||
level.carriedshieldmodel = "t6_wpn_zmb_shield_world";
|
||||
}
|
||||
|
||||
precachemodel( level.stowedshieldmodel );
|
||||
precachemodel( level.carriedshieldmodel );
|
||||
precachemodel( level.detectshieldmodel );
|
||||
level.riotshielddestroyanim = %o_riot_stand_destroyed;
|
||||
level.riotshielddeployanim = %o_riot_stand_deploy;
|
||||
level.riotshieldshotanimfront = %o_riot_stand_shot;
|
||||
level.riotshieldshotanimback = %o_riot_stand_shot_back;
|
||||
level.riotshieldmeleeanimfront = %o_riot_stand_melee_front;
|
||||
level.riotshieldmeleeanimback = %o_riot_stand_melee_back;
|
||||
loadfx( "weapon/riotshield/fx_riotshield_depoly_lights" );
|
||||
loadfx( "weapon/riotshield/fx_riotshield_depoly_dust" );
|
||||
level.riotshield_placement_zoffset = 26;
|
||||
}
|
||||
|
||||
register()
|
||||
{
|
||||
registerclientfield( "scriptmover", "riotshield_state", 1, 2, "int" );
|
||||
}
|
||||
|
||||
watchpregameclasschange()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "track_riot_shield" );
|
||||
|
||||
self waittill( "changed_class" );
|
||||
|
||||
if ( level.ingraceperiod && !self.hasdonecombat )
|
||||
{
|
||||
self clearstowedweapon();
|
||||
self refreshshieldattachment();
|
||||
self thread trackriotshield();
|
||||
}
|
||||
}
|
||||
|
||||
watchriotshieldpickup()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "track_riot_shield" );
|
||||
self notify( "watch_riotshield_pickup" );
|
||||
self endon( "watch_riotshield_pickup" );
|
||||
|
||||
self waittill( "pickup_riotshield" );
|
||||
|
||||
self endon( "weapon_change" );
|
||||
/#
|
||||
println( "Picked up riotshield, expecting weapon_change notify..." );
|
||||
#/
|
||||
wait 0.5;
|
||||
/#
|
||||
println( "picked up shield but didn't change weapons, attach it!" );
|
||||
#/
|
||||
self.hasriotshield = self hasweapon( level.riotshield_name );
|
||||
self.hasriotshieldequipped = self getcurrentweapon() == level.riotshield_name;
|
||||
self refreshshieldattachment();
|
||||
}
|
||||
|
||||
trackriotshield()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self notify( "track_riot_shield" );
|
||||
self endon( "track_riot_shield" );
|
||||
self thread watchpregameclasschange();
|
||||
|
||||
self waittill( "weapon_change", newweapon );
|
||||
|
||||
self refreshshieldattachment();
|
||||
self.hasriotshield = self hasweapon( level.riotshield_name );
|
||||
self.hasriotshieldequipped = self getcurrentweapon() == level.riotshield_name;
|
||||
self.lastnonshieldweapon = "none";
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self thread watchriotshieldpickup();
|
||||
currentweapon = self getcurrentweapon();
|
||||
self.hasriotshield = self hasweapon( level.riotshield_name );
|
||||
self.hasriotshieldequipped = self getcurrentweapon() == level.riotshield_name;
|
||||
refresh_attach = 0;
|
||||
|
||||
self waittill( "weapon_change", newweapon );
|
||||
|
||||
if ( newweapon == level.riotshield_name )
|
||||
{
|
||||
refresh_attach = 1;
|
||||
|
||||
if ( isdefined( self.riotshieldentity ) )
|
||||
self notify( "destroy_riotshield" );
|
||||
|
||||
if ( self.hasriotshield )
|
||||
{
|
||||
if ( isdefined( self.riotshieldtakeweapon ) )
|
||||
{
|
||||
self takeweapon( self.riotshieldtakeweapon );
|
||||
self.riotshieldtakeweapon = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isvalidnonshieldweapon( currentweapon ) )
|
||||
self.lastnonshieldweapon = currentweapon;
|
||||
}
|
||||
|
||||
if ( self.hasriotshield || refresh_attach == 1 )
|
||||
self refreshshieldattachment();
|
||||
}
|
||||
}
|
||||
|
||||
isvalidnonshieldweapon( weapon )
|
||||
{
|
||||
if ( maps\mp\killstreaks\_killstreaks::iskillstreakweapon( weapon ) )
|
||||
return false;
|
||||
|
||||
if ( maps\mp\killstreaks\_killstreak_weapons::isheldkillstreakweapon( weapon ) )
|
||||
return false;
|
||||
|
||||
if ( maps\mp\killstreaks\_killstreak_weapons::isgameplayweapon( weapon ) )
|
||||
return false;
|
||||
|
||||
if ( weapon == "none" )
|
||||
return false;
|
||||
|
||||
if ( isweaponequipment( weapon ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
startriotshielddeploy()
|
||||
{
|
||||
self notify( "start_riotshield_deploy" );
|
||||
self thread watchriotshielddeploy();
|
||||
}
|
||||
|
||||
resetreconmodelvisibility( owner )
|
||||
{
|
||||
if ( !isdefined( self ) )
|
||||
return;
|
||||
|
||||
self setinvisibletoall();
|
||||
self setforcenocull();
|
||||
|
||||
if ( !isdefined( owner ) )
|
||||
return;
|
||||
|
||||
for ( i = 0; i < level.players.size; i++ )
|
||||
{
|
||||
if ( level.players[i] hasperk( "specialty_showenemyequipment" ) )
|
||||
{
|
||||
if ( level.players[i].team == "spectator" )
|
||||
continue;
|
||||
|
||||
isenemy = 1;
|
||||
|
||||
if ( level.teambased )
|
||||
{
|
||||
if ( level.players[i].team == owner.team )
|
||||
isenemy = 0;
|
||||
}
|
||||
else if ( level.players[i] == owner )
|
||||
isenemy = 0;
|
||||
|
||||
if ( isenemy )
|
||||
self setvisibletoplayer( level.players[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resetreconmodelonevent( eventname, owner )
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
level waittill( eventname, newowner );
|
||||
|
||||
if ( isdefined( newowner ) )
|
||||
owner = newowner;
|
||||
|
||||
self resetreconmodelvisibility( owner );
|
||||
}
|
||||
}
|
||||
|
||||
attachreconmodel( modelname, owner )
|
||||
{
|
||||
if ( !isdefined( self ) )
|
||||
return;
|
||||
|
||||
reconmodel = spawn( "script_model", self.origin );
|
||||
reconmodel.angles = self.angles;
|
||||
reconmodel setmodel( modelname );
|
||||
reconmodel.model_name = modelname;
|
||||
reconmodel linkto( self );
|
||||
reconmodel setcontents( 0 );
|
||||
reconmodel resetreconmodelvisibility( owner );
|
||||
reconmodel thread resetreconmodelonevent( "joined_team", owner );
|
||||
reconmodel thread resetreconmodelonevent( "player_spawned", owner );
|
||||
self.reconmodel = reconmodel;
|
||||
}
|
||||
|
||||
spawnriotshieldcover( origin, angles )
|
||||
{
|
||||
shield_ent = spawn( "script_model", origin, 1 );
|
||||
shield_ent.targetname = "riotshield_mp";
|
||||
shield_ent.angles = angles;
|
||||
shield_ent setmodel( level.deployedshieldmodel );
|
||||
shield_ent setowner( self );
|
||||
shield_ent.owner = self;
|
||||
shield_ent.team = self.team;
|
||||
shield_ent setteam( self.team );
|
||||
shield_ent attachreconmodel( level.detectshieldmodel, self );
|
||||
shield_ent useanimtree( #animtree );
|
||||
shield_ent setscriptmoverflag( 0 );
|
||||
shield_ent disconnectpaths();
|
||||
return shield_ent;
|
||||
}
|
||||
|
||||
watchriotshielddeploy()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self endon( "start_riotshield_deploy" );
|
||||
|
||||
self waittill( "deploy_riotshield", deploy_attempt );
|
||||
|
||||
self setheldweaponmodel( 0 );
|
||||
self setplacementhint( 1 );
|
||||
placement_hint = 0;
|
||||
|
||||
if ( deploy_attempt )
|
||||
{
|
||||
placement = self canplaceriotshield( "deploy_riotshield" );
|
||||
|
||||
if ( placement["result"] )
|
||||
{
|
||||
self.hasdonecombat = 1;
|
||||
zoffset = level.riotshield_placement_zoffset;
|
||||
shield_ent = self spawnriotshieldcover( placement["origin"] + ( 0, 0, zoffset ), placement["angles"] );
|
||||
item_ent = deployriotshield( self, shield_ent );
|
||||
primaries = self getweaponslistprimaries();
|
||||
/#
|
||||
assert( isdefined( item_ent ) );
|
||||
assert( !isdefined( self.riotshieldretrievetrigger ) );
|
||||
assert( !isdefined( self.riotshieldentity ) );
|
||||
|
||||
if ( level.gametype != "shrp" )
|
||||
assert( primaries.size > 0 );
|
||||
#/
|
||||
shield_ent setclientfield( "riotshield_state", 1 );
|
||||
shield_ent.reconmodel setclientfield( "riotshield_state", 1 );
|
||||
|
||||
if ( level.gametype != "shrp" )
|
||||
{
|
||||
if ( self.lastnonshieldweapon != "none" && self hasweapon( self.lastnonshieldweapon ) )
|
||||
self switchtoweapon( self.lastnonshieldweapon );
|
||||
else
|
||||
self switchtoweapon( primaries[0] );
|
||||
}
|
||||
|
||||
if ( !self hasweapon( "knife_held_mp" ) )
|
||||
{
|
||||
self giveweapon( "knife_held_mp" );
|
||||
self.riotshieldtakeweapon = "knife_held_mp";
|
||||
}
|
||||
|
||||
self.riotshieldretrievetrigger = item_ent;
|
||||
self.riotshieldentity = shield_ent;
|
||||
self thread watchdeployedriotshieldents();
|
||||
self thread deleteshieldontriggerdeath( self.riotshieldretrievetrigger );
|
||||
self thread deleteshieldonplayerdeathordisconnect( shield_ent );
|
||||
self.riotshieldentity thread watchdeployedriotshielddamage();
|
||||
level notify( "riotshield_planted", self );
|
||||
}
|
||||
else
|
||||
{
|
||||
placement_hint = 1;
|
||||
clip_max_ammo = weaponclipsize( level.riotshield_name );
|
||||
self setweaponammoclip( level.riotshield_name, clip_max_ammo );
|
||||
}
|
||||
}
|
||||
else
|
||||
placement_hint = 1;
|
||||
|
||||
if ( placement_hint )
|
||||
self setriotshieldfailhint();
|
||||
}
|
||||
|
||||
riotshielddistancetest( origin )
|
||||
{
|
||||
assert( isdefined( origin ) );
|
||||
min_dist_squared = getdvarfloat( "riotshield_deploy_limit_radius" );
|
||||
min_dist_squared *= min_dist_squared;
|
||||
|
||||
for ( i = 0; i < level.players.size; i++ )
|
||||
{
|
||||
if ( isdefined( level.players[i].riotshieldentity ) )
|
||||
{
|
||||
dist_squared = distancesquared( level.players[i].riotshieldentity.origin, origin );
|
||||
|
||||
if ( min_dist_squared > dist_squared )
|
||||
{
|
||||
/#
|
||||
println( "Shield placement denied! Failed distance check to other riotshields." );
|
||||
#/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
watchdeployedriotshieldents()
|
||||
{
|
||||
/#
|
||||
assert( isdefined( self.riotshieldretrievetrigger ) );
|
||||
assert( isdefined( self.riotshieldentity ) );
|
||||
#/
|
||||
self waittill( "destroy_riotshield" );
|
||||
|
||||
if ( isdefined( self.riotshieldretrievetrigger ) )
|
||||
self.riotshieldretrievetrigger delete();
|
||||
|
||||
if ( isdefined( self.riotshieldentity ) )
|
||||
{
|
||||
if ( isdefined( self.riotshieldentity.reconmodel ) )
|
||||
self.riotshieldentity.reconmodel delete();
|
||||
|
||||
self.riotshieldentity connectpaths();
|
||||
self.riotshieldentity delete();
|
||||
}
|
||||
}
|
||||
|
||||
watchdeployedriotshielddamage()
|
||||
{
|
||||
self endon( "death" );
|
||||
damagemax = getdvarint( "riotshield_deployed_health" );
|
||||
self.damagetaken = 0;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self.maxhealth = 100000;
|
||||
self.health = self.maxhealth;
|
||||
|
||||
self waittill( "damage", damage, attacker, direction, point, type, tagname, modelname, partname, weaponname, idflags );
|
||||
|
||||
if ( !isdefined( attacker ) )
|
||||
continue;
|
||||
|
||||
assert( isdefined( self.owner ) && isdefined( self.owner.team ) );
|
||||
|
||||
if ( isplayer( attacker ) )
|
||||
{
|
||||
if ( level.teambased && attacker.team == self.owner.team && attacker != self.owner )
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( type == "MOD_MELEE" )
|
||||
damage *= getdvarfloat( "riotshield_melee_damage_scale" );
|
||||
else if ( type == "MOD_PISTOL_BULLET" || type == "MOD_RIFLE_BULLET" )
|
||||
damage *= getdvarfloat( "riotshield_bullet_damage_scale" );
|
||||
else if ( type == "MOD_GRENADE" || type == "MOD_GRENADE_SPLASH" || type == "MOD_EXPLOSIVE" || type == "MOD_EXPLOSIVE_SPLASH" || type == "MOD_PROJECTILE" || type == "MOD_PROJECTILE_SPLASH" )
|
||||
damage *= getdvarfloat( "riotshield_explosive_damage_scale" );
|
||||
else if ( type == "MOD_IMPACT" )
|
||||
damage *= getdvarfloat( "riotshield_projectile_damage_scale" );
|
||||
else if ( type == "MOD_CRUSH" )
|
||||
damage = damagemax;
|
||||
|
||||
self.damagetaken += damage;
|
||||
|
||||
if ( self.damagetaken >= damagemax )
|
||||
{
|
||||
self thread damagethendestroyriotshield( attacker, weaponname );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
damagethendestroyriotshield( attacker, weaponname )
|
||||
{
|
||||
self notify( "damageThenDestroyRiotshield" );
|
||||
self endon( "death" );
|
||||
|
||||
if ( isdefined( self.owner.riotshieldretrievetrigger ) )
|
||||
self.owner.riotshieldretrievetrigger delete();
|
||||
|
||||
if ( isdefined( self.reconmodel ) )
|
||||
self.reconmodel delete();
|
||||
|
||||
self connectpaths();
|
||||
self.owner.riotshieldentity = undefined;
|
||||
self notsolid();
|
||||
self setclientfield( "riotshield_state", 2 );
|
||||
|
||||
if ( isdefined( attacker ) && isdefined( weaponname ) && attacker != self.owner && isplayer( attacker ) )
|
||||
maps\mp\_scoreevents::processscoreevent( "destroyed_shield", attacker, self.owner, weaponname );
|
||||
|
||||
wait( getdvarfloat( "riotshield_destroyed_cleanup_time" ) );
|
||||
self delete();
|
||||
}
|
||||
|
||||
deleteshieldontriggerdeath( shield_trigger )
|
||||
{
|
||||
shield_trigger waittill_any( "trigger", "death" );
|
||||
self notify( "destroy_riotshield" );
|
||||
}
|
||||
|
||||
deleteshieldonplayerdeathordisconnect( shield_ent )
|
||||
{
|
||||
shield_ent endon( "death" );
|
||||
shield_ent endon( "damageThenDestroyRiotshield" );
|
||||
self waittill_any( "death", "disconnect", "remove_planted_weapons" );
|
||||
shield_ent thread damagethendestroyriotshield();
|
||||
}
|
||||
|
||||
watchriotshieldstuckentitydeath( grenade, owner )
|
||||
{
|
||||
grenade endon( "death" );
|
||||
self waittill_any( "damageThenDestroyRiotshield", "death", "disconnect", "weapon_change", "deploy_riotshield" );
|
||||
grenade detonate( owner );
|
||||
}
|
49
MP/Core/maps/mp/_satchel_charge.gsc
Normal file
49
MP/Core/maps/mp/_satchel_charge.gsc
Normal file
@ -0,0 +1,49 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_weaponobjects;
|
||||
#include maps\mp\killstreaks\_emp;
|
||||
#include maps\mp\_challenges;
|
||||
#include maps\mp\_scoreevents;
|
||||
|
||||
init()
|
||||
{
|
||||
level._effect["satchel_charge_enemy_light"] = loadfx( "weapon/c4/fx_c4_light_red" );
|
||||
level._effect["satchel_charge_friendly_light"] = loadfx( "weapon/c4/fx_c4_light_green" );
|
||||
}
|
||||
|
||||
createsatchelwatcher()
|
||||
{
|
||||
watcher = self maps\mp\gametypes\_weaponobjects::createuseweaponobjectwatcher( "satchel_charge", "satchel_charge_mp", self.team );
|
||||
watcher.altdetonate = 1;
|
||||
watcher.watchforfire = 1;
|
||||
watcher.hackable = 1;
|
||||
watcher.hackertoolradius = level.equipmenthackertoolradius;
|
||||
watcher.hackertooltimems = level.equipmenthackertooltimems;
|
||||
watcher.headicon = 1;
|
||||
watcher.detonate = ::satcheldetonate;
|
||||
watcher.stun = maps\mp\gametypes\_weaponobjects::weaponstun;
|
||||
watcher.stuntime = 1;
|
||||
watcher.altweapon = "satchel_charge_detonator_mp";
|
||||
watcher.reconmodel = "t6_wpn_c4_world_detect";
|
||||
watcher.ownergetsassist = 1;
|
||||
}
|
||||
|
||||
satcheldetonate( attacker, weaponname )
|
||||
{
|
||||
from_emp = maps\mp\killstreaks\_emp::isempkillstreakweapon( weaponname );
|
||||
|
||||
if ( !isdefined( from_emp ) || !from_emp )
|
||||
{
|
||||
if ( isdefined( attacker ) )
|
||||
{
|
||||
if ( self.owner isenemyplayer( attacker ) )
|
||||
{
|
||||
attacker maps\mp\_challenges::destroyedexplosive( weaponname );
|
||||
maps\mp\_scoreevents::processscoreevent( "destroyed_c4", attacker, self.owner, weaponname );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
maps\mp\gametypes\_weaponobjects::weapondetonate( attacker, weaponname );
|
||||
}
|
772
MP/Core/maps/mp/_scoreevents.gsc
Normal file
772
MP/Core/maps/mp/_scoreevents.gsc
Normal file
@ -0,0 +1,772 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_scoreevents;
|
||||
#include maps\mp\_challenges;
|
||||
#include maps\mp\killstreaks\_killstreaks;
|
||||
#include maps\mp\gametypes\_rank;
|
||||
#include maps\mp\gametypes\_globallogic_score;
|
||||
|
||||
init()
|
||||
{
|
||||
level.scoreeventcallbacks = [];
|
||||
level.scoreeventgameendcallback = ::ongameend;
|
||||
registerscoreeventcallback( "playerKilled", maps\mp\_scoreevents::scoreeventplayerkill );
|
||||
}
|
||||
|
||||
scoreeventtablelookupint( index, scoreeventcolumn )
|
||||
{
|
||||
return int( tablelookup( "mp/scoreInfo.csv", 0, index, scoreeventcolumn ) );
|
||||
}
|
||||
|
||||
scoreeventtablelookup( index, scoreeventcolumn )
|
||||
{
|
||||
return tablelookup( "mp/scoreInfo.csv", 0, index, scoreeventcolumn );
|
||||
}
|
||||
|
||||
getscoreeventcolumn( gametype )
|
||||
{
|
||||
columnoffset = getcolumnoffsetforgametype( gametype );
|
||||
assert( columnoffset >= 0 );
|
||||
|
||||
if ( columnoffset >= 0 )
|
||||
columnoffset += 0;
|
||||
|
||||
return columnoffset;
|
||||
}
|
||||
|
||||
getxpeventcolumn( gametype )
|
||||
{
|
||||
columnoffset = getcolumnoffsetforgametype( gametype );
|
||||
assert( columnoffset >= 0 );
|
||||
|
||||
if ( columnoffset >= 0 )
|
||||
columnoffset += 1;
|
||||
|
||||
return columnoffset;
|
||||
}
|
||||
|
||||
getcolumnoffsetforgametype( gametype )
|
||||
{
|
||||
foundgamemode = 0;
|
||||
|
||||
if ( !isdefined( level.scoreeventtableid ) )
|
||||
level.scoreeventtableid = getscoreeventtableid();
|
||||
|
||||
assert( isdefined( level.scoreeventtableid ) );
|
||||
|
||||
if ( !isdefined( level.scoreeventtableid ) )
|
||||
return -1;
|
||||
|
||||
gamemodecolumn = 11;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
column_header = tablelookupcolumnforrow( level.scoreeventtableid, 0, gamemodecolumn );
|
||||
|
||||
if ( column_header == "" )
|
||||
{
|
||||
gamemodecolumn = 11;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( column_header == level.gametype + " score" )
|
||||
{
|
||||
foundgamemode = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
gamemodecolumn += 2;
|
||||
}
|
||||
|
||||
assert( foundgamemode, "Could not find gamemode in scoreInfo.csv:" + gametype );
|
||||
return gamemodecolumn;
|
||||
}
|
||||
|
||||
getscoreeventtableid()
|
||||
{
|
||||
scoreinfotableloaded = 0;
|
||||
scoreinfotableid = tablelookupfindcoreasset( "mp/scoreInfo.csv" );
|
||||
|
||||
if ( isdefined( scoreinfotableid ) )
|
||||
scoreinfotableloaded = 1;
|
||||
|
||||
assert( scoreinfotableloaded, "Score Event Table is not loaded: " + "mp/scoreInfo.csv" );
|
||||
return scoreinfotableid;
|
||||
}
|
||||
|
||||
isregisteredevent( type )
|
||||
{
|
||||
if ( isdefined( level.scoreinfo[type] ) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
shouldaddrankxp( player )
|
||||
{
|
||||
if ( !isdefined( level.rankcap ) || level.rankcap == 0 )
|
||||
return true;
|
||||
|
||||
if ( player.pers["plevel"] > 0 || player.pers["rank"] > level.rankcap )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
processscoreevent( event, player, victim, weapon )
|
||||
{
|
||||
pixbeginevent( "processScoreEvent" );
|
||||
scoregiven = 0;
|
||||
|
||||
if ( !isplayer( player ) )
|
||||
{
|
||||
/#
|
||||
assertmsg( "processScoreEvent called on non player entity: " + event );
|
||||
#/
|
||||
return scoregiven;
|
||||
}
|
||||
|
||||
player thread maps\mp\_challenges::eventreceived( event );
|
||||
|
||||
if ( isregisteredevent( event ) )
|
||||
{
|
||||
allowplayerscore = 0;
|
||||
|
||||
if ( !isdefined( weapon ) || maps\mp\killstreaks\_killstreaks::iskillstreakweapon( weapon ) == 0 )
|
||||
allowplayerscore = 1;
|
||||
else
|
||||
allowplayerscore = maps\mp\gametypes\_rank::killstreakweaponsallowedscore( event );
|
||||
|
||||
if ( allowplayerscore )
|
||||
{
|
||||
scoregiven = maps\mp\gametypes\_globallogic_score::giveplayerscore( event, player, victim, weapon, undefined );
|
||||
isscoreevent = scoregiven > 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( shouldaddrankxp( player ) )
|
||||
player addrankxp( event, weapon, isscoreevent );
|
||||
|
||||
pixendevent();
|
||||
return scoregiven;
|
||||
}
|
||||
|
||||
registerscoreeventcallback( callback, func )
|
||||
{
|
||||
if ( !isdefined( level.scoreeventcallbacks[callback] ) )
|
||||
level.scoreeventcallbacks[callback] = [];
|
||||
|
||||
level.scoreeventcallbacks[callback][level.scoreeventcallbacks[callback].size] = func;
|
||||
}
|
||||
|
||||
scoreeventplayerkill( data, time )
|
||||
{
|
||||
victim = data.victim;
|
||||
attacker = data.attacker;
|
||||
time = data.time;
|
||||
level.numkills++;
|
||||
victim = data.victim;
|
||||
attacker.lastkilledplayer = victim;
|
||||
wasdefusing = data.wasdefusing;
|
||||
wasplanting = data.wasplanting;
|
||||
wasonground = data.victimonground;
|
||||
meansofdeath = data.smeansofdeath;
|
||||
|
||||
if ( isdefined( data.sweapon ) )
|
||||
{
|
||||
weapon = data.sweapon;
|
||||
weaponclass = getweaponclass( data.sweapon );
|
||||
killstreak = getkillstreakfromweapon( data.sweapon );
|
||||
}
|
||||
|
||||
victim.anglesondeath = victim getplayerangles();
|
||||
|
||||
if ( meansofdeath == "MOD_GRENADE" || meansofdeath == "MOD_GRENADE_SPLASH" || meansofdeath == "MOD_EXPLOSIVE" || meansofdeath == "MOD_EXPLOSIVE_SPLASH" || meansofdeath == "MOD_PROJECTILE" || meansofdeath == "MOD_PROJECTILE_SPLASH" )
|
||||
{
|
||||
if ( weapon == "none" && isdefined( data.victim.explosiveinfo["weapon"] ) )
|
||||
weapon = data.victim.explosiveinfo["weapon"];
|
||||
}
|
||||
|
||||
if ( level.teambased )
|
||||
{
|
||||
attacker.lastkilltime = time;
|
||||
|
||||
if ( isdefined( victim.lastkilltime ) && victim.lastkilltime > time - 3000 )
|
||||
{
|
||||
if ( isdefined( victim.lastkilledplayer ) && victim.lastkilledplayer isenemyplayer( attacker ) == 0 && attacker != victim.lastkilledplayer )
|
||||
{
|
||||
processscoreevent( "kill_enemy_who_killed_teammate", attacker, victim, weapon );
|
||||
victim recordkillmodifier( "avenger" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isdefined( victim.damagedplayers ) )
|
||||
{
|
||||
keys = getarraykeys( victim.damagedplayers );
|
||||
|
||||
for ( i = 0; i < keys.size; i++ )
|
||||
{
|
||||
key = keys[i];
|
||||
|
||||
if ( key == attacker.clientid )
|
||||
continue;
|
||||
|
||||
if ( !isdefined( victim.damagedplayers[key].entity ) )
|
||||
continue;
|
||||
|
||||
if ( attacker isenemyplayer( victim.damagedplayers[key].entity ) )
|
||||
continue;
|
||||
|
||||
if ( time - victim.damagedplayers[key].time < 1000 )
|
||||
{
|
||||
processscoreevent( "kill_enemy_injuring_teammate", attacker, victim, weapon );
|
||||
|
||||
if ( isdefined( victim.damagedplayers[key].entity ) )
|
||||
{
|
||||
victim.damagedplayers[key].entity.lastrescuedby = attacker;
|
||||
victim.damagedplayers[key].entity.lastrescuedtime = time;
|
||||
}
|
||||
|
||||
victim recordkillmodifier( "defender" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch ( weapon )
|
||||
{
|
||||
case "hatchet_mp":
|
||||
attacker.pers["tomahawks"]++;
|
||||
attacker.tomahawks = attacker.pers["tomahawks"];
|
||||
processscoreevent( "hatchet_kill", attacker, victim, weapon );
|
||||
|
||||
if ( isdefined( data.victim.explosiveinfo["projectile_bounced"] ) && data.victim.explosiveinfo["projectile_bounced"] == 1 )
|
||||
{
|
||||
level.globalbankshots++;
|
||||
processscoreevent( "bounce_hatchet_kill", attacker, victim, weapon );
|
||||
}
|
||||
|
||||
break;
|
||||
case "knife_ballistic_mp":
|
||||
if ( meansofdeath == "MOD_PISTOL_BULLET" || meansofdeath == "MOD_HEAD_SHOT" )
|
||||
processscoreevent( "ballistic_knife_kill", attacker, victim, data.sweapon );
|
||||
|
||||
attacker addweaponstat( weapon, "ballistic_knife_kill", 1 );
|
||||
break;
|
||||
case "supplydrop_mp":
|
||||
case "inventory_supplydrop_mp":
|
||||
if ( meansofdeath == "MOD_HIT_BY_OBJECT" || meansofdeath == "MOD_CRUSH" )
|
||||
processscoreevent( "kill_enemy_with_care_package_crush", attacker, victim, weapon );
|
||||
else
|
||||
processscoreevent( "kill_enemy_with_hacked_care_package", attacker, victim, weapon );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ( isdefined( data.victimweapon ) )
|
||||
{
|
||||
if ( data.victimweapon == "minigun_mp" )
|
||||
processscoreevent( "killed_death_machine_enemy", attacker, victim, weapon );
|
||||
else if ( data.victimweapon == "m32_mp" )
|
||||
processscoreevent( "killed_multiple_grenade_launcher_enemy", attacker, victim, weapon );
|
||||
}
|
||||
|
||||
attacker thread updatemultikills( weapon, weaponclass, killstreak );
|
||||
|
||||
if ( level.numkills == 1 )
|
||||
{
|
||||
victim recordkillmodifier( "firstblood" );
|
||||
processscoreevent( "first_kill", attacker, victim, weapon );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isdefined( attacker.lastkilledby ) )
|
||||
{
|
||||
if ( attacker.lastkilledby == victim )
|
||||
{
|
||||
level.globalpaybacks++;
|
||||
processscoreevent( "revenge_kill", attacker, victim, weapon );
|
||||
attacker addweaponstat( weapon, "revenge_kill", 1 );
|
||||
victim recordkillmodifier( "revenge" );
|
||||
attacker.lastkilledby = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if ( victim maps\mp\killstreaks\_killstreaks::isonakillstreak() )
|
||||
{
|
||||
level.globalbuzzkills++;
|
||||
processscoreevent( "stop_enemy_killstreak", attacker, victim, weapon );
|
||||
victim recordkillmodifier( "buzzkill" );
|
||||
}
|
||||
|
||||
if ( isdefined( victim.lastmansd ) && victim.lastmansd == 1 )
|
||||
{
|
||||
processscoreevent( "final_kill_elimination", attacker, victim, weapon );
|
||||
|
||||
if ( isdefined( attacker.lastmansd ) && attacker.lastmansd == 1 )
|
||||
processscoreevent( "elimination_and_last_player_alive", attacker, victim, weapon );
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_weapon_valid( meansofdeath, weapon, weaponclass ) )
|
||||
{
|
||||
if ( isdefined( victim.vattackerorigin ) )
|
||||
attackerorigin = victim.vattackerorigin;
|
||||
else
|
||||
attackerorigin = attacker.origin;
|
||||
|
||||
disttovictim = distancesquared( victim.origin, attackerorigin );
|
||||
weap_min_dmg_range = get_distance_for_weapon( weapon, weaponclass );
|
||||
|
||||
if ( disttovictim > weap_min_dmg_range )
|
||||
{
|
||||
attacker maps\mp\_challenges::longdistancekill();
|
||||
|
||||
if ( weapon == "hatchet_mp" )
|
||||
attacker maps\mp\_challenges::longdistancehatchetkill();
|
||||
|
||||
processscoreevent( "longshot_kill", attacker, victim, weapon );
|
||||
attacker addweaponstat( weapon, "longshot_kill", 1 );
|
||||
attacker.pers["longshots"]++;
|
||||
attacker.longshots = attacker.pers["longshots"];
|
||||
victim recordkillmodifier( "longshot" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isalive( attacker ) )
|
||||
{
|
||||
if ( attacker.health < attacker.maxhealth * 0.35 )
|
||||
{
|
||||
attacker.lastkillwheninjured = time;
|
||||
processscoreevent( "kill_enemy_when_injured", attacker, victim, weapon );
|
||||
attacker addweaponstat( weapon, "kill_enemy_when_injured", 1 );
|
||||
|
||||
if ( attacker hasperk( "specialty_bulletflinch" ) )
|
||||
attacker addplayerstat( "perk_bulletflinch_kills", 1 );
|
||||
}
|
||||
}
|
||||
else if ( isdefined( attacker.deathtime ) && attacker.deathtime + 800 < time && !attacker isinvehicle() )
|
||||
{
|
||||
level.globalafterlifes++;
|
||||
processscoreevent( "kill_enemy_after_death", attacker, victim, weapon );
|
||||
victim recordkillmodifier( "posthumous" );
|
||||
}
|
||||
|
||||
if ( attacker.cur_death_streak >= 3 )
|
||||
{
|
||||
level.globalcomebacks++;
|
||||
processscoreevent( "comeback_from_deathstreak", attacker, victim, weapon );
|
||||
victim recordkillmodifier( "comeback" );
|
||||
}
|
||||
|
||||
if ( isdefined( victim.beingmicrowavedby ) && weapon != "microwave_turret_mp" )
|
||||
{
|
||||
if ( victim.beingmicrowavedby != attacker && attacker isenemyplayer( victim.beingmicrowavedby ) == 0 )
|
||||
{
|
||||
scoregiven = processscoreevent( "microwave_turret_assist", victim.beingmicrowavedby, victim, weapon );
|
||||
|
||||
if ( isdefined( scoregiven ) && isdefined( victim.beingmicrowavedby ) )
|
||||
victim.beingmicrowavedby maps\mp\_challenges::earnedmicrowaveassistscore( scoregiven );
|
||||
}
|
||||
else
|
||||
attacker maps\mp\_challenges::killwhiledamagingwithhpm();
|
||||
}
|
||||
|
||||
if ( meansofdeath == "MOD_MELEE" && weapon != "riotshield_mp" )
|
||||
{
|
||||
attacker.pers["stabs"]++;
|
||||
attacker.stabs = attacker.pers["stabs"];
|
||||
vangles = victim.anglesondeath[1];
|
||||
pangles = attacker.anglesonkill[1];
|
||||
anglediff = angleclamp180( vangles - pangles );
|
||||
|
||||
if ( anglediff > -30 && anglediff < 70 )
|
||||
{
|
||||
level.globalbackstabs++;
|
||||
processscoreevent( "backstabber_kill", attacker, victim, weapon );
|
||||
attacker addweaponstat( weapon, "backstabber_kill", 1 );
|
||||
attacker.pers["backstabs"]++;
|
||||
attacker.backstabs = attacker.pers["backstabs"];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isdefined( victim.firsttimedamaged ) && victim.firsttimedamaged == time )
|
||||
{
|
||||
if ( weaponclass == "weapon_sniper" )
|
||||
{
|
||||
attacker thread updateoneshotmultikills( victim, weapon, victim.firsttimedamaged );
|
||||
attacker addweaponstat( weapon, "kill_enemy_one_bullet", 1 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isdefined( attacker.tookweaponfrom[weapon] ) && isdefined( attacker.tookweaponfrom[weapon].previousowner ) )
|
||||
{
|
||||
pickedupweapon = attacker.tookweaponfrom[weapon];
|
||||
|
||||
if ( pickedupweapon.previousowner == victim )
|
||||
{
|
||||
processscoreevent( "kill_enemy_with_their_weapon", attacker, victim, weapon );
|
||||
attacker addweaponstat( weapon, "kill_enemy_with_their_weapon", 1 );
|
||||
|
||||
if ( isdefined( pickedupweapon.sweapon ) && isdefined( pickedupweapon.smeansofdeath ) )
|
||||
{
|
||||
if ( pickedupweapon.sweapon == "knife_held_mp" && pickedupweapon.smeansofdeath == "MOD_MELEE" )
|
||||
attacker addweaponstat( "knife_held_mp", "kill_enemy_with_their_weapon", 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( wasdefusing )
|
||||
processscoreevent( "killed_bomb_defuser", attacker, victim, weapon );
|
||||
else if ( wasplanting )
|
||||
processscoreevent( "killed_bomb_planter", attacker, victim, weapon );
|
||||
|
||||
specificweaponkill( attacker, victim, weapon, killstreak );
|
||||
|
||||
if ( !isdefined( killstreak ) && isdefined( attacker.dtptime ) && attacker.dtptime + 5000 > time )
|
||||
{
|
||||
attacker.dtptime = 0;
|
||||
|
||||
if ( attacker getstance() == "prone" )
|
||||
processscoreevent( "kill_enemy_recent_dive_prone", attacker, self, weapon );
|
||||
}
|
||||
|
||||
if ( isdefined( killstreak ) )
|
||||
victim recordkillmodifier( "killstreak" );
|
||||
|
||||
attacker.cur_death_streak = 0;
|
||||
attacker disabledeathstreak();
|
||||
}
|
||||
|
||||
specificweaponkill( attacker, victim, weapon, killstreak )
|
||||
{
|
||||
switchweapon = weapon;
|
||||
|
||||
if ( isdefined( killstreak ) )
|
||||
switchweapon = killstreak;
|
||||
|
||||
switch ( switchweapon )
|
||||
{
|
||||
case "explosive_bolt_mp":
|
||||
case "crossbow_mp":
|
||||
if ( isdefined( victim.explosiveinfo["stuckToPlayer"] ) && victim.explosiveinfo["stuckToPlayer"] == victim )
|
||||
event = "crossbow_kill";
|
||||
else
|
||||
return;
|
||||
|
||||
break;
|
||||
case "rcbomb_mp":
|
||||
event = "rcxd_kill";
|
||||
break;
|
||||
case "remote_missile_mp":
|
||||
event = "remote_missile_kill";
|
||||
break;
|
||||
case "missile_drone_mp":
|
||||
event = "missile_drone_kill";
|
||||
break;
|
||||
case "autoturret_mp":
|
||||
event = "sentry_gun_kill";
|
||||
break;
|
||||
case "planemortar_mp":
|
||||
event = "plane_mortar_kill";
|
||||
break;
|
||||
case "minigun_mp":
|
||||
case "inventory_minigun_mp":
|
||||
event = "death_machine_kill";
|
||||
break;
|
||||
case "m32_mp":
|
||||
case "inventory_m32_mp":
|
||||
event = "multiple_grenade_launcher_kill";
|
||||
break;
|
||||
case "qrdrone_mp":
|
||||
event = "qrdrone_kill";
|
||||
break;
|
||||
case "ai_tank_drop_mp":
|
||||
event = "aitank_kill";
|
||||
break;
|
||||
case "helicopter_guard_mp":
|
||||
event = "helicopter_guard_kill";
|
||||
break;
|
||||
case "straferun_mp":
|
||||
event = "strafe_run_kill";
|
||||
break;
|
||||
case "remote_mortar_mp":
|
||||
event = "remote_mortar_kill";
|
||||
break;
|
||||
case "helicopter_player_gunner_mp":
|
||||
event = "helicopter_gunner_kill";
|
||||
break;
|
||||
case "dogs_mp":
|
||||
event = "dogs_kill";
|
||||
break;
|
||||
case "missile_swarm_mp":
|
||||
event = "missile_swarm_kill";
|
||||
break;
|
||||
case "helicopter_comlink_mp":
|
||||
event = "helicopter_comlink_kill";
|
||||
break;
|
||||
case "microwaveturret_mp":
|
||||
event = "microwave_turret_kill";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
processscoreevent( event, attacker, victim, weapon );
|
||||
}
|
||||
|
||||
multikill( killcount, weapon )
|
||||
{
|
||||
assert( killcount > 1 );
|
||||
self maps\mp\_challenges::multikill( killcount, weapon );
|
||||
|
||||
if ( killcount > 8 )
|
||||
processscoreevent( "multikill_more_than_8", self, undefined, weapon );
|
||||
else
|
||||
processscoreevent( "multikill_" + killcount, self, undefined, weapon );
|
||||
|
||||
self recordmultikill( killcount );
|
||||
}
|
||||
|
||||
uninterruptedobitfeedkills( attacker, sweapon )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
wait 0.1;
|
||||
waittillslowprocessallowed();
|
||||
wait 0.1;
|
||||
maps\mp\_scoreevents::processscoreevent( "uninterrupted_obit_feed_kills", attacker, self, sweapon );
|
||||
}
|
||||
|
||||
is_weapon_valid( meansofdeath, weapon, weaponclass )
|
||||
{
|
||||
valid_weapon = 0;
|
||||
|
||||
if ( get_distance_for_weapon( weapon, weaponclass ) == 0 )
|
||||
valid_weapon = 0;
|
||||
else if ( meansofdeath == "MOD_PISTOL_BULLET" || meansofdeath == "MOD_RIFLE_BULLET" )
|
||||
valid_weapon = 1;
|
||||
else if ( meansofdeath == "MOD_HEAD_SHOT" )
|
||||
valid_weapon = 1;
|
||||
else if ( weapon == "hatchet_mp" && meansofdeath == "MOD_IMPACT" )
|
||||
valid_weapon = 1;
|
||||
|
||||
return valid_weapon;
|
||||
}
|
||||
|
||||
updatemultikills( weapon, weaponclass, killstreak )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
self notify( "updateRecentKills" );
|
||||
self endon( "updateRecentKills" );
|
||||
baseweaponname = getreffromitemindex( getbaseweaponitemindex( weapon ) ) + "_mp";
|
||||
|
||||
if ( !isdefined( self.recentkillcount ) )
|
||||
self.recentkillcount = 0;
|
||||
|
||||
if ( !isdefined( self.recentkillcountweapon ) || self.recentkillcountweapon != baseweaponname )
|
||||
{
|
||||
self.recentkillcountsameweapon = 0;
|
||||
self.recentkillcountweapon = baseweaponname;
|
||||
}
|
||||
|
||||
if ( !isdefined( killstreak ) )
|
||||
{
|
||||
self.recentkillcountsameweapon++;
|
||||
self.recentkillcount++;
|
||||
}
|
||||
|
||||
if ( !isdefined( self.recent_lmg_smg_killcount ) )
|
||||
self.recent_lmg_smg_killcount = 0;
|
||||
|
||||
if ( !isdefined( self.recentremotemissilekillcount ) )
|
||||
self.recentremotemissilekillcount = 0;
|
||||
|
||||
if ( !isdefined( self.recentremotemissileattackerkillcount ) )
|
||||
self.recentremotemissileattackerkillcount = 0;
|
||||
|
||||
if ( !isdefined( self.recentrcbombkillcount ) )
|
||||
self.recentrcbombkillcount = 0;
|
||||
|
||||
if ( !isdefined( self.recentrcbombattackerkillcount ) )
|
||||
self.recentrcbombattackerkillcount = 0;
|
||||
|
||||
if ( !isdefined( self.recentmglkillcount ) )
|
||||
self.recentmglkillcount = 0;
|
||||
|
||||
if ( isdefined( weaponclass ) )
|
||||
{
|
||||
if ( weaponclass == "weapon_lmg" || weaponclass == "weapon_smg" )
|
||||
{
|
||||
if ( self playerads() < 1.0 )
|
||||
self.recent_lmg_smg_killcount++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isdefined( killstreak ) )
|
||||
{
|
||||
switch ( killstreak )
|
||||
{
|
||||
case "remote_missile_mp":
|
||||
self.recentremotemissilekillcount++;
|
||||
break;
|
||||
case "rcbomb_mp":
|
||||
self.recentrcbombkillcount++;
|
||||
break;
|
||||
case "m32_mp":
|
||||
case "inventory_m32_mp":
|
||||
self.recentmglkillcount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( self.recentkillcountsameweapon == 2 )
|
||||
self addweaponstat( weapon, "multikill_2", 1 );
|
||||
else if ( self.recentkillcountsameweapon == 3 )
|
||||
self addweaponstat( weapon, "multikill_3", 1 );
|
||||
|
||||
self waittilltimeoutordeath( 4.0 );
|
||||
|
||||
if ( self.recent_lmg_smg_killcount >= 3 )
|
||||
self maps\mp\_challenges::multi_lmg_smg_kill();
|
||||
|
||||
if ( self.recentrcbombkillcount >= 2 )
|
||||
self maps\mp\_challenges::multi_rcbomb_kill();
|
||||
|
||||
if ( self.recentmglkillcount >= 3 )
|
||||
self maps\mp\_challenges::multi_mgl_kill();
|
||||
|
||||
if ( self.recentremotemissilekillcount >= 3 )
|
||||
self maps\mp\_challenges::multi_remotemissile_kill();
|
||||
|
||||
if ( self.recentkillcount > 1 )
|
||||
self multikill( self.recentkillcount, weapon );
|
||||
|
||||
self.recentkillcount = 0;
|
||||
self.recentkillcountsameweapon = 0;
|
||||
self.recentkillcountweapon = undefined;
|
||||
self.recent_lmg_smg_killcount = 0;
|
||||
self.recentremotemissilekillcount = 0;
|
||||
self.recentremotemissileattackerkillcount = 0;
|
||||
self.recentrcbombkillcount = 0;
|
||||
self.recentmglkillcount = 0;
|
||||
}
|
||||
|
||||
waittilltimeoutordeath( timeout )
|
||||
{
|
||||
self endon( "death" );
|
||||
wait( timeout );
|
||||
}
|
||||
|
||||
updateoneshotmultikills( victim, weapon, firsttimedamaged )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self notify( "updateoneshotmultikills" + firsttimedamaged );
|
||||
self endon( "updateoneshotmultikills" + firsttimedamaged );
|
||||
|
||||
if ( !isdefined( self.oneshotmultikills ) )
|
||||
self.oneshotmultikills = 0;
|
||||
|
||||
self.oneshotmultikills++;
|
||||
wait 1.0;
|
||||
|
||||
if ( self.oneshotmultikills > 1 )
|
||||
processscoreevent( "kill_enemies_one_bullet", self, victim, weapon );
|
||||
else
|
||||
processscoreevent( "kill_enemy_one_bullet", self, victim, weapon );
|
||||
|
||||
self.oneshotmultikills = 0;
|
||||
}
|
||||
|
||||
get_distance_for_weapon( weapon, weaponclass )
|
||||
{
|
||||
distance = 0;
|
||||
|
||||
switch ( weaponclass )
|
||||
{
|
||||
case "weapon_smg":
|
||||
distance = 1562500;
|
||||
break;
|
||||
case "weapon_assault":
|
||||
distance = 2250000;
|
||||
break;
|
||||
case "weapon_lmg":
|
||||
distance = 2250000;
|
||||
break;
|
||||
case "weapon_sniper":
|
||||
distance = 3062500;
|
||||
break;
|
||||
case "weapon_pistol":
|
||||
distance = 490000;
|
||||
break;
|
||||
case "weapon_cqb":
|
||||
distance = 422500;
|
||||
break;
|
||||
case "weapon_special":
|
||||
if ( weapon == "knife_ballistic_mp" )
|
||||
distance = 2250000;
|
||||
else if ( weapon == "crossbow_mp" )
|
||||
distance = 2250000;
|
||||
else if ( weapon == "metalstorm_mp" )
|
||||
distance = 3062500;
|
||||
|
||||
break;
|
||||
case "weapon_grenade":
|
||||
if ( weapon == "hatchet_mp" )
|
||||
distance = 6250000;
|
||||
|
||||
break;
|
||||
default:
|
||||
distance = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return distance;
|
||||
}
|
||||
|
||||
decrementlastobituaryplayercountafterfade()
|
||||
{
|
||||
level endon( "reset_obituary_count" );
|
||||
wait 5;
|
||||
level.lastobituaryplayercount--;
|
||||
assert( level.lastobituaryplayercount >= 0 );
|
||||
}
|
||||
|
||||
ongameend( data )
|
||||
{
|
||||
player = data.player;
|
||||
winner = data.winner;
|
||||
|
||||
if ( isdefined( winner ) )
|
||||
{
|
||||
if ( level.teambased )
|
||||
{
|
||||
if ( winner != "tie" && player.team == winner )
|
||||
{
|
||||
processscoreevent( "won_match", player );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
placement = level.placement["all"];
|
||||
topthreeplayers = min( 3, placement.size );
|
||||
|
||||
for ( index = 0; index < topthreeplayers; index++ )
|
||||
{
|
||||
if ( level.placement["all"][index] == player )
|
||||
{
|
||||
processscoreevent( "won_match", player );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processscoreevent( "completed_match", player );
|
||||
}
|
193
MP/Core/maps/mp/_scrambler.gsc
Normal file
193
MP/Core/maps/mp/_scrambler.gsc
Normal file
@ -0,0 +1,193 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\gametypes\_weaponobjects;
|
||||
#include maps\mp\killstreaks\_emp;
|
||||
#include maps\mp\_challenges;
|
||||
#include maps\mp\gametypes\_globallogic_player;
|
||||
#include maps\mp\gametypes\_damagefeedback;
|
||||
|
||||
init()
|
||||
{
|
||||
level._effect["scrambler_enemy_light"] = loadfx( "misc/fx_equip_light_red" );
|
||||
level._effect["scrambler_friendly_light"] = loadfx( "misc/fx_equip_light_green" );
|
||||
level.scramblerweapon = "scrambler_mp";
|
||||
level.scramblerlength = 30.0;
|
||||
level.scramblerouterradiussq = 1000000;
|
||||
level.scramblerinnerradiussq = 360000;
|
||||
}
|
||||
|
||||
createscramblerwatcher()
|
||||
{
|
||||
watcher = self maps\mp\gametypes\_weaponobjects::createuseweaponobjectwatcher( "scrambler", "scrambler_mp", self.team );
|
||||
watcher.onspawn = ::onspawnscrambler;
|
||||
watcher.detonate = ::scramblerdetonate;
|
||||
watcher.stun = maps\mp\gametypes\_weaponobjects::weaponstun;
|
||||
watcher.stuntime = 5;
|
||||
watcher.reconmodel = "t5_weapon_scrambler_world_detect";
|
||||
watcher.hackable = 1;
|
||||
watcher.ondamage = ::watchscramblerdamage;
|
||||
}
|
||||
|
||||
onspawnscrambler( watcher, player )
|
||||
{
|
||||
player endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self thread maps\mp\gametypes\_weaponobjects::onspawnuseweaponobject( watcher, player );
|
||||
player.scrambler = self;
|
||||
self setowner( player );
|
||||
self setteam( player.team );
|
||||
self.owner = player;
|
||||
self setclientflag( 3 );
|
||||
|
||||
if ( !self maps\mp\_utility::ishacked() )
|
||||
player addweaponstat( "scrambler_mp", "used", 1 );
|
||||
|
||||
self thread watchshutdown( player );
|
||||
level notify( "scrambler_spawn" );
|
||||
}
|
||||
|
||||
scramblerdetonate( attacker, weaponname )
|
||||
{
|
||||
from_emp = maps\mp\killstreaks\_emp::isempweapon( weaponname );
|
||||
|
||||
if ( !from_emp )
|
||||
playfx( level._equipment_explode_fx, self.origin );
|
||||
|
||||
if ( self.owner isenemyplayer( attacker ) )
|
||||
attacker maps\mp\_challenges::destroyedequipment( weaponname );
|
||||
|
||||
playsoundatposition( "dst_equipment_destroy", self.origin );
|
||||
self delete();
|
||||
}
|
||||
|
||||
watchshutdown( player )
|
||||
{
|
||||
self waittill_any( "death", "hacked" );
|
||||
level notify( "scrambler_death" );
|
||||
|
||||
if ( isdefined( player ) )
|
||||
player.scrambler = undefined;
|
||||
}
|
||||
|
||||
destroyent()
|
||||
{
|
||||
self delete();
|
||||
}
|
||||
|
||||
watchscramblerdamage( watcher )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "hacked" );
|
||||
self setcandamage( 1 );
|
||||
damagemax = 100;
|
||||
|
||||
if ( !self maps\mp\_utility::ishacked() )
|
||||
self.damagetaken = 0;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self.maxhealth = 100000;
|
||||
self.health = self.maxhealth;
|
||||
|
||||
self waittill( "damage", damage, attacker, direction, point, type, tagname, modelname, partname, weaponname, idflags );
|
||||
|
||||
if ( !isdefined( attacker ) || !isplayer( attacker ) )
|
||||
continue;
|
||||
|
||||
if ( level.teambased && attacker.team == self.owner.team && attacker != self.owner )
|
||||
continue;
|
||||
|
||||
if ( isdefined( weaponname ) )
|
||||
{
|
||||
switch ( weaponname )
|
||||
{
|
||||
case "flash_grenade_mp":
|
||||
case "concussion_grenade_mp":
|
||||
if ( watcher.stuntime > 0 )
|
||||
self thread maps\mp\gametypes\_weaponobjects::stunstart( watcher, watcher.stuntime );
|
||||
|
||||
if ( level.teambased && self.owner.team != attacker.team )
|
||||
{
|
||||
if ( maps\mp\gametypes\_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
attacker maps\mp\gametypes\_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
else if ( !level.teambased && self.owner != attacker )
|
||||
{
|
||||
if ( maps\mp\gametypes\_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
attacker maps\mp\gametypes\_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
|
||||
continue;
|
||||
case "emp_grenade_mp":
|
||||
damage = damagemax;
|
||||
default:
|
||||
if ( maps\mp\gametypes\_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
attacker maps\mp\gametypes\_damagefeedback::updatedamagefeedback();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
weaponname = "";
|
||||
|
||||
if ( isplayer( attacker ) && level.teambased && isdefined( attacker.team ) && self.owner.team == attacker.team && attacker != self.owner )
|
||||
continue;
|
||||
|
||||
if ( type == "MOD_MELEE" )
|
||||
self.damagetaken = damagemax;
|
||||
else
|
||||
self.damagetaken += damage;
|
||||
|
||||
if ( self.damagetaken >= damagemax )
|
||||
watcher thread maps\mp\gametypes\_weaponobjects::waitanddetonate( self, 0.0, attacker, weaponname );
|
||||
}
|
||||
}
|
||||
|
||||
ownersameteam( owner1, owner2 )
|
||||
{
|
||||
if ( !level.teambased )
|
||||
return 0;
|
||||
|
||||
if ( !isdefined( owner1 ) || !isdefined( owner2 ) )
|
||||
return 0;
|
||||
|
||||
if ( !isdefined( owner1.team ) || !isdefined( owner2.team ) )
|
||||
return 0;
|
||||
|
||||
return owner1.team == owner2.team;
|
||||
}
|
||||
|
||||
checkscramblerstun()
|
||||
{
|
||||
scramblers = getentarray( "grenade", "classname" );
|
||||
|
||||
if ( isdefined( self.name ) && self.name == "scrambler_mp" )
|
||||
return false;
|
||||
|
||||
for ( i = 0; i < scramblers.size; i++ )
|
||||
{
|
||||
scrambler = scramblers[i];
|
||||
|
||||
if ( !isalive( scrambler ) )
|
||||
continue;
|
||||
|
||||
if ( !isdefined( scrambler.name ) )
|
||||
continue;
|
||||
|
||||
if ( scrambler.name != "scrambler_mp" )
|
||||
continue;
|
||||
|
||||
if ( ownersameteam( self.owner, scrambler.owner ) )
|
||||
continue;
|
||||
|
||||
flattenedselforigin = ( self.origin[0], self.origin[1], 0 );
|
||||
flattenedscramblerorigin = ( scrambler.origin[0], scrambler.origin[1], 0 );
|
||||
|
||||
if ( distancesquared( flattenedselforigin, flattenedscramblerorigin ) < level.scramblerouterradiussq )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
290
MP/Core/maps/mp/_script_gen.gsc
Normal file
290
MP/Core/maps/mp/_script_gen.gsc
Normal file
@ -0,0 +1,290 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\_script_gen;
|
||||
|
||||
script_gen_dump_checksaved()
|
||||
{
|
||||
signatures = getarraykeys( level.script_gen_dump );
|
||||
|
||||
for ( i = 0; i < signatures.size; i++ )
|
||||
{
|
||||
if ( !isdefined( level.script_gen_dump2[signatures[i]] ) )
|
||||
{
|
||||
level.script_gen_dump[signatures[i]] = undefined;
|
||||
level.script_gen_dump_reasons[level.script_gen_dump_reasons.size] = "Signature unmatched( removed feature ): " + signatures[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
script_gen_dump()
|
||||
{
|
||||
/#
|
||||
script_gen_dump_checksaved();
|
||||
|
||||
if ( !level.script_gen_dump_reasons.size )
|
||||
{
|
||||
flag_set( "scriptgen_done" );
|
||||
return;
|
||||
}
|
||||
|
||||
firstrun = 0;
|
||||
|
||||
if ( level.bscriptgened )
|
||||
{
|
||||
println( " " );
|
||||
println( " " );
|
||||
println( " " );
|
||||
println( "^2 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- " );
|
||||
println( "^3Dumping scriptgen dump for these reasons" );
|
||||
println( "^2 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- " );
|
||||
|
||||
for ( i = 0; i < level.script_gen_dump_reasons.size; i++ )
|
||||
{
|
||||
if ( issubstr( level.script_gen_dump_reasons[i], "nowrite" ) )
|
||||
{
|
||||
substr = getsubstr( level.script_gen_dump_reasons[i], 15 );
|
||||
println( i + ". ) " + substr );
|
||||
}
|
||||
else
|
||||
println( i + ". ) " + level.script_gen_dump_reasons[i] );
|
||||
|
||||
if ( level.script_gen_dump_reasons[i] == "First run" )
|
||||
firstrun = 1;
|
||||
}
|
||||
|
||||
println( "^2 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- " );
|
||||
println( " " );
|
||||
|
||||
if ( firstrun )
|
||||
{
|
||||
println( "for First Run make sure you delete all of the vehicle precache script calls, createart calls, createfx calls( most commonly placed in maps\\" + level.script + "_fx.gsc ) " );
|
||||
println( " " );
|
||||
println( "replace:" );
|
||||
println( "maps\\_load::main( 1 );" );
|
||||
println( " " );
|
||||
println( "with( don't forget to add this file to P4 ):" );
|
||||
println( "maps\\scriptgen\\" + level.script + "_scriptgen::main();" );
|
||||
println( " " );
|
||||
}
|
||||
|
||||
println( "^2 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- " );
|
||||
println( " " );
|
||||
println( "^2 / \\ / \\ / \\" );
|
||||
println( "^2scroll up" );
|
||||
println( "^2 / \\ / \\ / \\" );
|
||||
println( " " );
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
filename = "scriptgen/" + level.script + "_scriptgen.gsc";
|
||||
csvfilename = "zone_source/" + level.script + ".csv";
|
||||
|
||||
if ( level.bscriptgened )
|
||||
file = openfile( filename, "write" );
|
||||
else
|
||||
file = 0;
|
||||
|
||||
assert( file != -1, "File not writeable( check it and and restart the map ): " + filename );
|
||||
script_gen_dumpprintln( file, "// script generated script do not write your own script here it will go away if you do." );
|
||||
script_gen_dumpprintln( file, "main()" );
|
||||
script_gen_dumpprintln( file, "{" );
|
||||
script_gen_dumpprintln( file, "" );
|
||||
script_gen_dumpprintln( file, "\\tlevel.script_gen_dump = [];" );
|
||||
script_gen_dumpprintln( file, "" );
|
||||
signatures = getarraykeys( level.script_gen_dump );
|
||||
|
||||
for ( i = 0; i < signatures.size; i++ )
|
||||
{
|
||||
if ( !issubstr( level.script_gen_dump[signatures[i]], "nowrite" ) )
|
||||
script_gen_dumpprintln( file, "\\t" + level.script_gen_dump[signatures[i]] );
|
||||
}
|
||||
|
||||
for ( i = 0; i < signatures.size; i++ )
|
||||
{
|
||||
if ( !issubstr( level.script_gen_dump[signatures[i]], "nowrite" ) )
|
||||
{
|
||||
script_gen_dumpprintln( file, "\\tlevel.script_gen_dump[ " + "\"" + signatures[i] + "\"" + " ] = " + "\"" + signatures[i] + "\"" + ";" );
|
||||
continue;
|
||||
}
|
||||
|
||||
script_gen_dumpprintln( file, "\\tlevel.script_gen_dump[ " + "\"" + signatures[i] + "\"" + " ] = " + "\"nowrite\"" + ";" );
|
||||
}
|
||||
|
||||
script_gen_dumpprintln( file, "" );
|
||||
keys1 = undefined;
|
||||
keys2 = undefined;
|
||||
|
||||
if ( isdefined( level.sg_precacheanims ) )
|
||||
keys1 = getarraykeys( level.sg_precacheanims );
|
||||
|
||||
if ( isdefined( keys1 ) )
|
||||
{
|
||||
for ( i = 0; i < keys1.size; i++ )
|
||||
script_gen_dumpprintln( file, "\\tanim_precach_" + keys1[i] + "();" );
|
||||
}
|
||||
|
||||
script_gen_dumpprintln( file, "\\tmaps\\_load::main( 1, " + level.bcsvgened + ", 1 );" );
|
||||
script_gen_dumpprintln( file, "}" );
|
||||
script_gen_dumpprintln( file, "" );
|
||||
|
||||
if ( isdefined( level.sg_precacheanims ) )
|
||||
keys1 = getarraykeys( level.sg_precacheanims );
|
||||
|
||||
if ( isdefined( keys1 ) )
|
||||
{
|
||||
for ( i = 0; i < keys1.size; i++ )
|
||||
{
|
||||
script_gen_dumpprintln( file, "#using_animtree( \"" + keys1[i] + "\" );" );
|
||||
script_gen_dumpprintln( file, "anim_precach_" + keys1[i] + "()" );
|
||||
script_gen_dumpprintln( file, "{" );
|
||||
script_gen_dumpprintln( file, "\\tlevel.sg_animtree[ \"" + keys1[i] + "\" ] = #animtree;" );
|
||||
keys2 = getarraykeys( level.sg_precacheanims[keys1[i]] );
|
||||
|
||||
if ( isdefined( keys2 ) )
|
||||
{
|
||||
for ( j = 0; j < keys2.size; j++ )
|
||||
script_gen_dumpprintln( file, "\\tlevel.sg_anim[ \"" + keys2[j] + "\" ] = %" + keys2[j] + ";" );
|
||||
}
|
||||
|
||||
script_gen_dumpprintln( file, "}" );
|
||||
script_gen_dumpprintln( file, "" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( level.bscriptgened )
|
||||
saved = closefile( file );
|
||||
else
|
||||
saved = 1;
|
||||
|
||||
if ( level.bcsvgened )
|
||||
csvfile = openfile( csvfilename, "write" );
|
||||
else
|
||||
csvfile = 0;
|
||||
|
||||
assert( csvfile != -1, "File not writeable( check it and and restart the map ): " + csvfilename );
|
||||
signatures = getarraykeys( level.script_gen_dump );
|
||||
|
||||
for ( i = 0; i < signatures.size; i++ )
|
||||
script_gen_csvdumpprintln( csvfile, signatures[i] );
|
||||
|
||||
if ( level.bcsvgened )
|
||||
csvfilesaved = closefile( csvfile );
|
||||
else
|
||||
csvfilesaved = 1;
|
||||
|
||||
assert( csvfilesaved == 1, "csv not saved( see above message? ): " + csvfilename );
|
||||
assert( saved == 1, "map not saved( see above message? ): " + filename );
|
||||
#/
|
||||
assert( !level.bscriptgened, "SCRIPTGEN generated: follow instructions listed above this error in the console" );
|
||||
|
||||
if ( level.bscriptgened )
|
||||
{
|
||||
/#
|
||||
assertmsg( "SCRIPTGEN updated: Rebuild fast file and run map again" );
|
||||
#/
|
||||
}
|
||||
|
||||
flag_set( "scriptgen_done" );
|
||||
}
|
||||
|
||||
script_gen_csvdumpprintln( file, signature )
|
||||
{
|
||||
prefix = undefined;
|
||||
writtenprefix = undefined;
|
||||
path = "";
|
||||
extension = "";
|
||||
|
||||
if ( issubstr( signature, "ignore" ) )
|
||||
prefix = "ignore";
|
||||
else if ( issubstr( signature, "col_map_sp" ) )
|
||||
prefix = "col_map_sp";
|
||||
else if ( issubstr( signature, "gfx_map" ) )
|
||||
prefix = "gfx_map";
|
||||
else if ( issubstr( signature, "rawfile" ) )
|
||||
prefix = "rawfile";
|
||||
else if ( issubstr( signature, "sound" ) )
|
||||
prefix = "sound";
|
||||
else if ( issubstr( signature, "xmodel" ) )
|
||||
prefix = "xmodel";
|
||||
else if ( issubstr( signature, "xanim" ) )
|
||||
prefix = "xanim";
|
||||
else if ( issubstr( signature, "item" ) )
|
||||
{
|
||||
prefix = "item";
|
||||
writtenprefix = "weapon";
|
||||
path = "sp/";
|
||||
}
|
||||
else if ( issubstr( signature, "fx" ) )
|
||||
prefix = "fx";
|
||||
else if ( issubstr( signature, "menu" ) )
|
||||
{
|
||||
prefix = "menu";
|
||||
writtenprefix = "menufile";
|
||||
path = "ui / scriptmenus/";
|
||||
extension = ".menu";
|
||||
}
|
||||
else if ( issubstr( signature, "rumble" ) )
|
||||
{
|
||||
prefix = "rumble";
|
||||
writtenprefix = "rawfile";
|
||||
path = "rumble/";
|
||||
}
|
||||
else if ( issubstr( signature, "shader" ) )
|
||||
{
|
||||
prefix = "shader";
|
||||
writtenprefix = "material";
|
||||
}
|
||||
else if ( issubstr( signature, "shock" ) )
|
||||
{
|
||||
prefix = "shock";
|
||||
writtenprefix = "rawfile";
|
||||
extension = ".shock";
|
||||
path = "shock/";
|
||||
}
|
||||
else if ( issubstr( signature, "string" ) )
|
||||
{
|
||||
prefix = "string";
|
||||
/#
|
||||
assertmsg( "string not yet supported by scriptgen" );
|
||||
#/
|
||||
}
|
||||
else if ( issubstr( signature, "turret" ) )
|
||||
{
|
||||
prefix = "turret";
|
||||
writtenprefix = "weapon";
|
||||
path = "sp/";
|
||||
}
|
||||
else if ( issubstr( signature, "vehicle" ) )
|
||||
{
|
||||
prefix = "vehicle";
|
||||
writtenprefix = "rawfile";
|
||||
path = "vehicles/";
|
||||
}
|
||||
|
||||
if ( !isdefined( prefix ) )
|
||||
return;
|
||||
|
||||
if ( !isdefined( writtenprefix ) )
|
||||
string = prefix + ", " + getsubstr( signature, prefix.size + 1, signature.size );
|
||||
else
|
||||
string = writtenprefix + ", " + path + getsubstr( signature, prefix.size + 1, signature.size ) + extension;
|
||||
/#
|
||||
if ( file == -1 || !level.bcsvgened )
|
||||
println( string );
|
||||
else
|
||||
fprintln( file, string );
|
||||
#/
|
||||
}
|
||||
|
||||
script_gen_dumpprintln( file, string )
|
||||
{
|
||||
/#
|
||||
if ( file == -1 || !level.bscriptgened )
|
||||
println( string );
|
||||
else
|
||||
fprintln( file, string );
|
||||
#/
|
||||
}
|
207
MP/Core/maps/mp/_sensor_grenade.gsc
Normal file
207
MP/Core/maps/mp/_sensor_grenade.gsc
Normal file
@ -0,0 +1,207 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\gametypes\_weaponobjects;
|
||||
#include maps\mp\_hacker_tool;
|
||||
#include maps\mp\killstreaks\_emp;
|
||||
#include maps\mp\_challenges;
|
||||
#include maps\mp\_scoreevents;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_globallogic_player;
|
||||
#include maps\mp\gametypes\_damagefeedback;
|
||||
|
||||
init()
|
||||
{
|
||||
level.isplayertrackedfunc = ::isplayertracked;
|
||||
}
|
||||
|
||||
createsensorgrenadewatcher()
|
||||
{
|
||||
watcher = self maps\mp\gametypes\_weaponobjects::createuseweaponobjectwatcher( "sensor_grenade", "sensor_grenade_mp", self.team );
|
||||
watcher.headicon = 0;
|
||||
watcher.onspawn = ::onspawnsensorgrenade;
|
||||
watcher.detonate = ::sensorgrenadedestroyed;
|
||||
watcher.stun = maps\mp\gametypes\_weaponobjects::weaponstun;
|
||||
watcher.stuntime = 0;
|
||||
watcher.reconmodel = "t6_wpn_motion_sensor_world_detect";
|
||||
watcher.ondamage = ::watchsensorgrenadedamage;
|
||||
watcher.enemydestroy = 1;
|
||||
}
|
||||
|
||||
onspawnsensorgrenade( watcher, player )
|
||||
{
|
||||
self endon( "death" );
|
||||
self thread maps\mp\gametypes\_weaponobjects::onspawnuseweaponobject( watcher, player );
|
||||
self setowner( player );
|
||||
self setteam( player.team );
|
||||
self.owner = player;
|
||||
self playloopsound( "fly_sensor_nade_lp" );
|
||||
self maps\mp\_hacker_tool::registerwithhackertool( level.equipmenthackertoolradius, level.equipmenthackertooltimems );
|
||||
player addweaponstat( "sensor_grenade_mp", "used", 1 );
|
||||
self thread watchforstationary( player );
|
||||
self thread watchforexplode( player );
|
||||
}
|
||||
|
||||
watchforstationary( owner )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "hacked" );
|
||||
self endon( "explode" );
|
||||
owner endon( "death" );
|
||||
owner endon( "disconnect" );
|
||||
|
||||
self waittill( "stationary" );
|
||||
|
||||
checkfortracking( self.origin );
|
||||
}
|
||||
|
||||
watchforexplode( owner )
|
||||
{
|
||||
self endon( "hacked" );
|
||||
self endon( "delete" );
|
||||
owner endon( "death" );
|
||||
owner endon( "disconnect" );
|
||||
|
||||
self waittill( "explode", origin );
|
||||
|
||||
checkfortracking( origin + ( 0, 0, 1 ) );
|
||||
}
|
||||
|
||||
checkfortracking( origin )
|
||||
{
|
||||
if ( isdefined( self.owner ) == 0 )
|
||||
return;
|
||||
|
||||
players = level.players;
|
||||
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( player isenemyplayer( self.owner ) )
|
||||
{
|
||||
if ( !player hasperk( "specialty_nomotionsensor" ) )
|
||||
{
|
||||
if ( distancesquared( player.origin, origin ) < 562500 )
|
||||
{
|
||||
trace = bullettrace( origin, player.origin + vectorscale( ( 0, 0, 1 ), 12.0 ), 0, player );
|
||||
|
||||
if ( trace["fraction"] == 1 )
|
||||
self.owner tracksensorgrenadevictim( player );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tracksensorgrenadevictim( victim )
|
||||
{
|
||||
if ( !isdefined( self.sensorgrenadedata ) )
|
||||
self.sensorgrenadedata = [];
|
||||
|
||||
if ( !isdefined( self.sensorgrenadedata[victim.clientid] ) )
|
||||
self.sensorgrenadedata[victim.clientid] = gettime();
|
||||
}
|
||||
|
||||
isplayertracked( player, time )
|
||||
{
|
||||
playertracked = 0;
|
||||
|
||||
if ( isdefined( self.sensorgrenadedata ) && isdefined( self.sensorgrenadedata[player.clientid] ) )
|
||||
{
|
||||
if ( self.sensorgrenadedata[player.clientid] + 10000 > time )
|
||||
playertracked = 1;
|
||||
}
|
||||
|
||||
return playertracked;
|
||||
}
|
||||
|
||||
sensorgrenadedestroyed( attacker, weaponname )
|
||||
{
|
||||
from_emp = maps\mp\killstreaks\_emp::isempweapon( weaponname );
|
||||
|
||||
if ( !from_emp )
|
||||
playfx( level._equipment_explode_fx, self.origin );
|
||||
|
||||
if ( isdefined( attacker ) )
|
||||
{
|
||||
if ( self.owner isenemyplayer( attacker ) )
|
||||
{
|
||||
attacker maps\mp\_challenges::destroyedequipment( weaponname );
|
||||
maps\mp\_scoreevents::processscoreevent( "destroyed_motion_sensor", attacker, self.owner, weaponname );
|
||||
}
|
||||
}
|
||||
|
||||
playsoundatposition( "dst_equipment_destroy", self.origin );
|
||||
self delete();
|
||||
}
|
||||
|
||||
watchsensorgrenadedamage( watcher )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "hacked" );
|
||||
self setcandamage( 1 );
|
||||
damagemax = 1;
|
||||
|
||||
if ( !self maps\mp\_utility::ishacked() )
|
||||
self.damagetaken = 0;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self.maxhealth = 100000;
|
||||
self.health = self.maxhealth;
|
||||
|
||||
self waittill( "damage", damage, attacker, direction, point, type, tagname, modelname, partname, weaponname, idflags );
|
||||
|
||||
if ( !isdefined( attacker ) || !isplayer( attacker ) )
|
||||
continue;
|
||||
|
||||
if ( level.teambased && isplayer( attacker ) )
|
||||
{
|
||||
if ( !level.hardcoremode && self.owner.team == attacker.pers["team"] && self.owner != attacker )
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isdefined( weaponname ) )
|
||||
{
|
||||
switch ( weaponname )
|
||||
{
|
||||
case "flash_grenade_mp":
|
||||
case "concussion_grenade_mp":
|
||||
if ( watcher.stuntime > 0 )
|
||||
self thread maps\mp\gametypes\_weaponobjects::stunstart( watcher, watcher.stuntime );
|
||||
|
||||
if ( level.teambased && self.owner.team != attacker.team )
|
||||
{
|
||||
if ( maps\mp\gametypes\_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
attacker maps\mp\gametypes\_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
else if ( !level.teambased && self.owner != attacker )
|
||||
{
|
||||
if ( maps\mp\gametypes\_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
attacker maps\mp\gametypes\_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
|
||||
continue;
|
||||
case "emp_grenade_mp":
|
||||
damage = damagemax;
|
||||
default:
|
||||
if ( maps\mp\gametypes\_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
attacker maps\mp\gametypes\_damagefeedback::updatedamagefeedback();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
weaponname = "";
|
||||
|
||||
if ( type == "MOD_MELEE" )
|
||||
self.damagetaken = damagemax;
|
||||
else
|
||||
self.damagetaken += damage;
|
||||
|
||||
if ( self.damagetaken >= damagemax )
|
||||
{
|
||||
watcher thread maps\mp\gametypes\_weaponobjects::waitanddetonate( self, 0.0, attacker, weaponname );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
61
MP/Core/maps/mp/_serverfaceanim_mp.gsc
Normal file
61
MP/Core/maps/mp/_serverfaceanim_mp.gsc
Normal file
@ -0,0 +1,61 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
|
||||
init()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
level waittill( "connecting", player );
|
||||
|
||||
player thread onplayerspawned();
|
||||
}
|
||||
}
|
||||
|
||||
onplayerspawned()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
|
||||
self thread init_serverfaceanim();
|
||||
}
|
||||
}
|
||||
|
||||
init_serverfaceanim()
|
||||
{
|
||||
self.do_face_anims = 1;
|
||||
|
||||
if ( !isdefined( level.face_event_handler ) )
|
||||
{
|
||||
level.face_event_handler = spawnstruct();
|
||||
level.face_event_handler.events = [];
|
||||
level.face_event_handler.events["death"] = "face_death";
|
||||
level.face_event_handler.events["grenade danger"] = "face_alert";
|
||||
level.face_event_handler.events["bulletwhizby"] = "face_alert";
|
||||
level.face_event_handler.events["projectile_impact"] = "face_alert";
|
||||
level.face_event_handler.events["explode"] = "face_alert";
|
||||
level.face_event_handler.events["alert"] = "face_alert";
|
||||
level.face_event_handler.events["shoot"] = "face_shoot_single";
|
||||
level.face_event_handler.events["melee"] = "face_melee";
|
||||
level.face_event_handler.events["damage"] = "face_pain";
|
||||
level thread wait_for_face_event();
|
||||
}
|
||||
}
|
||||
|
||||
wait_for_face_event()
|
||||
{
|
||||
while ( true )
|
||||
{
|
||||
level waittill( "face", face_notify, ent );
|
||||
|
||||
if ( isdefined( ent ) && isdefined( ent.do_face_anims ) && ent.do_face_anims )
|
||||
{
|
||||
if ( isdefined( level.face_event_handler.events[face_notify] ) )
|
||||
ent sendfaceevent( level.face_event_handler.events[face_notify] );
|
||||
}
|
||||
}
|
||||
}
|
66
MP/Core/maps/mp/_smokegrenade.gsc
Normal file
66
MP/Core/maps/mp/_smokegrenade.gsc
Normal file
@ -0,0 +1,66 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\killstreaks\_airsupport;
|
||||
#include maps\mp\killstreaks\_dogs;
|
||||
|
||||
init()
|
||||
{
|
||||
level.willypetedamageradius = 300;
|
||||
level.willypetedamageheight = 128;
|
||||
level.sound_smoke_start = "wpn_smoke_hiss_start";
|
||||
level.sound_smoke_loop = "wpn_smoke_hiss_lp";
|
||||
level.sound_smoke_stop = "wpn_smoke_hiss_end";
|
||||
level.smokesoundduration = 8;
|
||||
level.fx_smokegrenade_single = "smoke_center_mp";
|
||||
precacheitem( level.fx_smokegrenade_single );
|
||||
}
|
||||
|
||||
watchsmokegrenadedetonation( owner )
|
||||
{
|
||||
owner addweaponstat( "willy_pete_mp", "used", 1 );
|
||||
|
||||
self waittill( "explode", position, surface );
|
||||
|
||||
if ( !isdefined( level.water_duds ) || level.water_duds == 1 )
|
||||
{
|
||||
if ( isdefined( surface ) && surface == "water" )
|
||||
return;
|
||||
}
|
||||
|
||||
onefoot = vectorscale( ( 0, 0, 1 ), 12.0 );
|
||||
startpos = position + onefoot;
|
||||
ent = spawntimedfx( level.fx_smokegrenade_single, position, ( 0, 0, 1 ), 12 );
|
||||
ent thread blocksight();
|
||||
|
||||
if ( isdefined( owner ) )
|
||||
{
|
||||
owner.smokegrenadetime = gettime();
|
||||
owner.smokegrenadeposition = position;
|
||||
}
|
||||
|
||||
thread playsmokesound( position, level.smokesoundduration, level.sound_smoke_start, level.sound_smoke_stop, level.sound_smoke_loop );
|
||||
damageeffectarea( owner, startpos, level.willypetedamageradius, level.willypetedamageheight, undefined );
|
||||
}
|
||||
|
||||
damageeffectarea( owner, position, radius, height, killcament )
|
||||
{
|
||||
effectarea = spawn( "trigger_radius", position, 0, radius, height );
|
||||
owner thread maps\mp\killstreaks\_dogs::flash_dogs( effectarea );
|
||||
effectarea delete();
|
||||
}
|
||||
|
||||
blocksight()
|
||||
{
|
||||
self endon( "death" );
|
||||
radius = 64;
|
||||
fxblocksight( self, radius );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
wait 0.75;
|
||||
radius = clamp( radius * 1.5, 10, 150 );
|
||||
fxblocksight( self, radius );
|
||||
}
|
||||
}
|
15
MP/Core/maps/mp/_sticky_grenade.gsc
Normal file
15
MP/Core/maps/mp/_sticky_grenade.gsc
Normal file
@ -0,0 +1,15 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
|
||||
init()
|
||||
{
|
||||
loadfx( "weapon/crossbow/fx_trail_crossbow_blink_grn_os" );
|
||||
loadfx( "weapon/crossbow/fx_trail_crossbow_blink_red_os" );
|
||||
}
|
||||
|
||||
watch_bolt_detonation( owner )
|
||||
{
|
||||
|
||||
}
|
517
MP/Core/maps/mp/_tabun.gsc
Normal file
517
MP/Core/maps/mp/_tabun.gsc
Normal file
@ -0,0 +1,517 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\killstreaks\_airsupport;
|
||||
#include maps\mp\killstreaks\_dogs;
|
||||
#include maps\mp\gametypes\_battlechatter_mp;
|
||||
|
||||
init()
|
||||
{
|
||||
level.tabuninitialgasshockduration = weapons_get_dvar_int( "scr_tabunInitialGasShockDuration", "7" );
|
||||
level.tabunwalkingasshockduration = weapons_get_dvar_int( "scr_tabunWalkInGasShockDuration", "4" );
|
||||
level.tabungasshockradius = weapons_get_dvar_int( "scr_tabun_shock_radius", "185" );
|
||||
level.tabungasshockheight = weapons_get_dvar_int( "scr_tabun_shock_height", "20" );
|
||||
level.tabungaspoisonradius = weapons_get_dvar_int( "scr_tabun_effect_radius", "185" );
|
||||
level.tabungaspoisonheight = weapons_get_dvar_int( "scr_tabun_shock_height", "20" );
|
||||
level.tabungasduration = weapons_get_dvar_int( "scr_tabunGasDuration", "8" );
|
||||
level.poisonduration = weapons_get_dvar_int( "scr_poisonDuration", "8" );
|
||||
level.poisondamage = weapons_get_dvar_int( "scr_poisonDamage", "13" );
|
||||
level.poisondamagehardcore = weapons_get_dvar_int( "scr_poisonDamageHardcore", "5" );
|
||||
level.fx_tabun_0 = "tabun_tiny_mp";
|
||||
level.fx_tabun_1 = "tabun_small_mp";
|
||||
level.fx_tabun_2 = "tabun_medium_mp";
|
||||
level.fx_tabun_3 = "tabun_large_mp";
|
||||
level.fx_tabun_single = "tabun_center_mp";
|
||||
precacheitem( level.fx_tabun_0 );
|
||||
precacheitem( level.fx_tabun_1 );
|
||||
precacheitem( level.fx_tabun_2 );
|
||||
precacheitem( level.fx_tabun_3 );
|
||||
precacheitem( level.fx_tabun_single );
|
||||
level.fx_tabun_radius0 = weapons_get_dvar_int( "scr_fx_tabun_radius0", 55 );
|
||||
level.fx_tabun_radius1 = weapons_get_dvar_int( "scr_fx_tabun_radius1", 55 );
|
||||
level.fx_tabun_radius2 = weapons_get_dvar_int( "scr_fx_tabun_radius2", 50 );
|
||||
level.fx_tabun_radius3 = weapons_get_dvar_int( "scr_fx_tabun_radius3", 25 );
|
||||
level.sound_tabun_start = "wpn_gas_hiss_start";
|
||||
level.sound_tabun_loop = "wpn_gas_hiss_lp";
|
||||
level.sound_tabun_stop = "wpn_gas_hiss_end";
|
||||
level.sound_shock_tabun_start = "";
|
||||
level.sound_shock_tabun_loop = "";
|
||||
level.sound_shock_tabun_stop = "";
|
||||
/#
|
||||
level thread checkdvarupdates();
|
||||
#/
|
||||
}
|
||||
|
||||
checkdvarupdates()
|
||||
{
|
||||
while ( true )
|
||||
{
|
||||
level.tabungaspoisonradius = weapons_get_dvar_int( "scr_tabun_effect_radius", level.tabungaspoisonradius );
|
||||
level.tabungaspoisonheight = weapons_get_dvar_int( "scr_tabun_shock_height", level.tabungaspoisonheight );
|
||||
level.tabungasshockradius = weapons_get_dvar_int( "scr_tabun_shock_radius", level.tabungasshockradius );
|
||||
level.tabungasshockheight = weapons_get_dvar_int( "scr_tabun_shock_height", level.tabungasshockheight );
|
||||
level.tabuninitialgasshockduration = weapons_get_dvar_int( "scr_tabunInitialGasShockDuration", level.tabuninitialgasshockduration );
|
||||
level.tabunwalkingasshockduration = weapons_get_dvar_int( "scr_tabunWalkInGasShockDuration", level.tabunwalkingasshockduration );
|
||||
level.tabungasduration = weapons_get_dvar_int( "scr_tabunGasDuration", level.tabungasduration );
|
||||
level.poisonduration = weapons_get_dvar_int( "scr_poisonDuration", level.poisonduration );
|
||||
level.poisondamage = weapons_get_dvar_int( "scr_poisonDamage", level.poisondamage );
|
||||
level.poisondamagehardcore = weapons_get_dvar_int( "scr_poisonDamageHardcore", level.poisondamagehardcore );
|
||||
level.fx_tabun_radius0 = weapons_get_dvar_int( "scr_fx_tabun_radius0", level.fx_tabun_radius0 );
|
||||
level.fx_tabun_radius1 = weapons_get_dvar_int( "scr_fx_tabun_radius1", level.fx_tabun_radius1 );
|
||||
level.fx_tabun_radius2 = weapons_get_dvar_int( "scr_fx_tabun_radius2", level.fx_tabun_radius2 );
|
||||
level.fx_tabun_radius3 = weapons_get_dvar_int( "scr_fx_tabun_radius3", level.fx_tabun_radius3 );
|
||||
wait 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
watchtabungrenadedetonation( owner )
|
||||
{
|
||||
self waittill( "explode", position, surface );
|
||||
|
||||
if ( !isdefined( level.water_duds ) || level.water_duds == 1 )
|
||||
{
|
||||
if ( isdefined( surface ) && surface == "water" )
|
||||
return;
|
||||
}
|
||||
|
||||
if ( weapons_get_dvar_int( "scr_enable_new_tabun", 1 ) )
|
||||
generatelocations( position, owner );
|
||||
else
|
||||
singlelocation( position, owner );
|
||||
}
|
||||
|
||||
damageeffectarea( owner, position, radius, height, killcament )
|
||||
{
|
||||
shockeffectarea = spawn( "trigger_radius", position, 0, radius, height );
|
||||
gaseffectarea = spawn( "trigger_radius", position, 0, radius, height );
|
||||
/#
|
||||
if ( getdvarint( "scr_draw_triggers" ) )
|
||||
level thread drawcylinder( position, radius, height, undefined, "tabun_draw_cylinder_stop" );
|
||||
#/
|
||||
owner thread maps\mp\killstreaks\_dogs::flash_dogs( shockeffectarea );
|
||||
owner thread maps\mp\killstreaks\_dogs::flash_dogs( gaseffectarea );
|
||||
loopwaittime = 0.5;
|
||||
|
||||
for ( durationoftabun = level.tabungasduration; durationoftabun > 0; durationoftabun -= loopwaittime )
|
||||
{
|
||||
players = get_players();
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
if ( level.friendlyfire == 0 )
|
||||
{
|
||||
if ( players[i] != owner )
|
||||
{
|
||||
if ( !isdefined( owner ) || !isdefined( owner.team ) )
|
||||
continue;
|
||||
|
||||
if ( level.teambased && players[i].team == owner.team )
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !isdefined( players[i].inpoisonarea ) || players[i].inpoisonarea == 0 )
|
||||
{
|
||||
if ( players[i] istouching( gaseffectarea ) && players[i].sessionstate == "playing" )
|
||||
{
|
||||
if ( !players[i] hasperk( "specialty_proximityprotection" ) )
|
||||
{
|
||||
trace = bullettrace( position, players[i].origin + vectorscale( ( 0, 0, 1 ), 12.0 ), 0, players[i] );
|
||||
|
||||
if ( trace["fraction"] == 1 )
|
||||
{
|
||||
players[i].lastpoisonedby = owner;
|
||||
players[i] thread damageinpoisonarea( shockeffectarea, killcament, trace, position );
|
||||
}
|
||||
}
|
||||
|
||||
players[i] thread maps\mp\gametypes\_battlechatter_mp::incomingspecialgrenadetracking( "gas" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wait( loopwaittime );
|
||||
}
|
||||
|
||||
if ( level.tabungasduration < level.poisonduration )
|
||||
wait( level.poisonduration - level.tabungasduration );
|
||||
|
||||
shockeffectarea delete();
|
||||
gaseffectarea delete();
|
||||
/#
|
||||
if ( getdvarint( "scr_draw_triggers" ) )
|
||||
level notify( "tabun_draw_cylinder_stop" );
|
||||
#/
|
||||
}
|
||||
|
||||
damageinpoisonarea( gaseffectarea, killcament, trace, position )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self thread watch_death();
|
||||
self.inpoisonarea = 1;
|
||||
self startpoisoning();
|
||||
tabunshocksound = spawn( "script_origin", ( 0, 0, 1 ) );
|
||||
tabunshocksound thread deleteentonownerdeath( self );
|
||||
tabunshocksound.origin = position;
|
||||
tabunshocksound playsound( level.sound_shock_tabun_start );
|
||||
tabunshocksound playloopsound( level.sound_shock_tabun_loop );
|
||||
timer = 0;
|
||||
|
||||
while ( trace["fraction"] == 1 && isdefined( gaseffectarea ) && self istouching( gaseffectarea ) && self.sessionstate == "playing" && isdefined( self.lastpoisonedby ) )
|
||||
{
|
||||
damage = level.poisondamage;
|
||||
|
||||
if ( level.hardcoremode )
|
||||
damage = level.poisondamagehardcore;
|
||||
|
||||
self dodamage( damage, gaseffectarea.origin, self.lastpoisonedby, killcament, "none", "MOD_GAS", 0, "tabun_gas_mp" );
|
||||
|
||||
if ( self mayapplyscreeneffect() )
|
||||
{
|
||||
switch ( timer )
|
||||
{
|
||||
case 0:
|
||||
self shellshock( "tabun_gas_mp", 1.0 );
|
||||
break;
|
||||
case 1:
|
||||
self shellshock( "tabun_gas_nokick_mp", 1.0 );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
timer++;
|
||||
|
||||
if ( timer >= 2 )
|
||||
timer = 0;
|
||||
|
||||
self hide_hud();
|
||||
}
|
||||
|
||||
wait 1.0;
|
||||
trace = bullettrace( position, self.origin + vectorscale( ( 0, 0, 1 ), 12.0 ), 0, self );
|
||||
}
|
||||
|
||||
tabunshocksound stoploopsound( 0.5 );
|
||||
wait 0.5;
|
||||
thread playsoundinspace( level.sound_shock_tabun_stop, position );
|
||||
wait 0.5;
|
||||
tabunshocksound notify( "delete" );
|
||||
tabunshocksound delete();
|
||||
self show_hud();
|
||||
self stoppoisoning();
|
||||
self.inpoisonarea = 0;
|
||||
}
|
||||
|
||||
deleteentonownerdeath( owner )
|
||||
{
|
||||
self endon( "delete" );
|
||||
|
||||
owner waittill( "death" );
|
||||
|
||||
self delete();
|
||||
}
|
||||
|
||||
watch_death()
|
||||
{
|
||||
self waittill( "death" );
|
||||
|
||||
self show_hud();
|
||||
}
|
||||
|
||||
hide_hud()
|
||||
{
|
||||
self setclientuivisibilityflag( "hud_visible", 0 );
|
||||
}
|
||||
|
||||
show_hud()
|
||||
{
|
||||
self setclientuivisibilityflag( "hud_visible", 1 );
|
||||
}
|
||||
|
||||
weapons_get_dvar_int( dvar, def )
|
||||
{
|
||||
return int( weapons_get_dvar( dvar, def ) );
|
||||
}
|
||||
|
||||
weapons_get_dvar( dvar, def )
|
||||
{
|
||||
if ( getdvar( dvar ) != "" )
|
||||
return getdvarfloat( dvar );
|
||||
else
|
||||
{
|
||||
setdvar( dvar, def );
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
generatelocations( position, owner )
|
||||
{
|
||||
onefoot = vectorscale( ( 0, 0, 1 ), 12.0 );
|
||||
startpos = position + onefoot;
|
||||
/#
|
||||
level.tabun_debug = getdvarintdefault( "scr_tabun_debug", 0 );
|
||||
|
||||
if ( level.tabun_debug )
|
||||
{
|
||||
black = vectorscale( ( 1, 1, 1 ), 0.2 );
|
||||
debugstar( startpos, 2000, black );
|
||||
}
|
||||
#/
|
||||
spawnalllocs( owner, startpos );
|
||||
}
|
||||
|
||||
singlelocation( position, owner )
|
||||
{
|
||||
spawntimedfx( level.fx_tabun_single, position );
|
||||
killcament = spawn( "script_model", position + vectorscale( ( 0, 0, 1 ), 60.0 ) );
|
||||
killcament deleteaftertime( 15.0 );
|
||||
killcament.starttime = gettime();
|
||||
damageeffectarea( owner, position, level.tabungaspoisonradius, level.tabungaspoisonheight, killcament );
|
||||
}
|
||||
|
||||
hitpos( start, end, color )
|
||||
{
|
||||
trace = bullettrace( start, end, 0, undefined );
|
||||
/#
|
||||
level.tabun_debug = getdvarintdefault( "scr_tabun_debug", 0 );
|
||||
|
||||
if ( level.tabun_debug )
|
||||
debugstar( trace["position"], 2000, color );
|
||||
|
||||
thread debug_line( start, trace["position"], color, 80 );
|
||||
#/
|
||||
return trace["position"];
|
||||
}
|
||||
|
||||
spawnalllocs( owner, startpos )
|
||||
{
|
||||
defaultdistance = weapons_get_dvar_int( "scr_defaultDistanceTabun", 220 );
|
||||
cos45 = 0.707;
|
||||
negcos45 = -0.707;
|
||||
red = ( 0.9, 0.2, 0.2 );
|
||||
blue = ( 0.2, 0.2, 0.9 );
|
||||
green = ( 0.2, 0.9, 0.2 );
|
||||
white = vectorscale( ( 1, 1, 1 ), 0.9 );
|
||||
north = startpos + ( defaultdistance, 0, 0 );
|
||||
south = startpos - ( defaultdistance, 0, 0 );
|
||||
east = startpos + ( 0, defaultdistance, 0 );
|
||||
west = startpos - ( 0, defaultdistance, 0 );
|
||||
nw = startpos + ( cos45 * defaultdistance, negcos45 * defaultdistance, 0 );
|
||||
ne = startpos + ( cos45 * defaultdistance, cos45 * defaultdistance, 0 );
|
||||
sw = startpos + ( negcos45 * defaultdistance, negcos45 * defaultdistance, 0 );
|
||||
se = startpos + ( negcos45 * defaultdistance, cos45 * defaultdistance, 0 );
|
||||
locations = [];
|
||||
locations["color"] = [];
|
||||
locations["loc"] = [];
|
||||
locations["tracePos"] = [];
|
||||
locations["distSqrd"] = [];
|
||||
locations["fxtoplay"] = [];
|
||||
locations["radius"] = [];
|
||||
locations["color"][0] = red;
|
||||
locations["color"][1] = red;
|
||||
locations["color"][2] = blue;
|
||||
locations["color"][3] = blue;
|
||||
locations["color"][4] = green;
|
||||
locations["color"][5] = green;
|
||||
locations["color"][6] = white;
|
||||
locations["color"][7] = white;
|
||||
locations["point"][0] = north;
|
||||
locations["point"][1] = ne;
|
||||
locations["point"][2] = east;
|
||||
locations["point"][3] = se;
|
||||
locations["point"][4] = south;
|
||||
locations["point"][5] = sw;
|
||||
locations["point"][6] = west;
|
||||
locations["point"][7] = nw;
|
||||
|
||||
for ( count = 0; count < 8; count++ )
|
||||
{
|
||||
trace = hitpos( startpos, locations["point"][count], locations["color"][count] );
|
||||
locations["tracePos"][count] = trace;
|
||||
locations["loc"][count] = startpos / 2 + trace / 2;
|
||||
locations["loc"][count] -= vectorscale( ( 0, 0, 1 ), 12.0 );
|
||||
locations["distSqrd"][count] = distancesquared( startpos, trace );
|
||||
}
|
||||
|
||||
centroid = getcentroid( locations );
|
||||
killcament = spawn( "script_model", centroid + vectorscale( ( 0, 0, 1 ), 60.0 ) );
|
||||
killcament deleteaftertime( 15.0 );
|
||||
killcament.starttime = gettime();
|
||||
center = getcenter( locations );
|
||||
|
||||
for ( i = 0; i < 8; i++ )
|
||||
{
|
||||
fxtoplay = setuptabunfx( owner, locations, i );
|
||||
|
||||
switch ( fxtoplay )
|
||||
{
|
||||
case 0:
|
||||
locations["fxtoplay"][i] = level.fx_tabun_0;
|
||||
locations["radius"][i] = level.fx_tabun_radius0;
|
||||
break;
|
||||
case 1:
|
||||
locations["fxtoplay"][i] = level.fx_tabun_1;
|
||||
locations["radius"][i] = level.fx_tabun_radius1;
|
||||
break;
|
||||
case 2:
|
||||
locations["fxtoplay"][i] = level.fx_tabun_2;
|
||||
locations["radius"][i] = level.fx_tabun_radius2;
|
||||
break;
|
||||
case 3:
|
||||
locations["fxtoplay"][i] = level.fx_tabun_3;
|
||||
locations["radius"][i] = level.fx_tabun_radius3;
|
||||
break;
|
||||
default:
|
||||
locations["fxtoplay"][i] = undefined;
|
||||
locations["radius"][i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
singleeffect = 1;
|
||||
freepassused = 0;
|
||||
|
||||
for ( i = 0; i < 8; i++ )
|
||||
{
|
||||
if ( locations["radius"][i] != level.fx_tabun_radius0 )
|
||||
{
|
||||
if ( freepassused == 0 && locations["radius"][i] == level.fx_tabun_radius1 )
|
||||
{
|
||||
freepassused = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
singleeffect = 0;
|
||||
}
|
||||
}
|
||||
|
||||
onefoot = vectorscale( ( 0, 0, 1 ), 12.0 );
|
||||
startpos -= onefoot;
|
||||
thread playtabunsound( startpos );
|
||||
|
||||
if ( singleeffect == 1 )
|
||||
singlelocation( startpos, owner );
|
||||
else
|
||||
{
|
||||
spawntimedfx( level.fx_tabun_3, startpos );
|
||||
|
||||
for ( count = 0; count < 8; count++ )
|
||||
{
|
||||
if ( isdefined( locations["fxtoplay"][count] ) )
|
||||
{
|
||||
spawntimedfx( locations["fxtoplay"][count], locations["loc"][count] );
|
||||
thread damageeffectarea( owner, locations["loc"][count], locations["radius"][count], locations["radius"][count], killcament );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
playtabunsound( position )
|
||||
{
|
||||
tabunsound = spawn( "script_origin", ( 0, 0, 1 ) );
|
||||
tabunsound.origin = position;
|
||||
tabunsound playsound( level.sound_tabun_start );
|
||||
tabunsound playloopsound( level.sound_tabun_loop );
|
||||
wait( level.tabungasduration );
|
||||
thread playsoundinspace( level.sound_tabun_stop, position );
|
||||
tabunsound stoploopsound( 0.5 );
|
||||
wait 0.5;
|
||||
tabunsound delete();
|
||||
}
|
||||
|
||||
setuptabunfx( owner, locations, count )
|
||||
{
|
||||
fxtoplay = undefined;
|
||||
previous = count - 1;
|
||||
|
||||
if ( previous < 0 )
|
||||
previous += locations["loc"].size;
|
||||
|
||||
next = count + 1;
|
||||
|
||||
if ( next >= locations["loc"].size )
|
||||
next -= locations["loc"].size;
|
||||
|
||||
effect0dist = level.fx_tabun_radius0 * level.fx_tabun_radius0;
|
||||
effect1dist = level.fx_tabun_radius1 * level.fx_tabun_radius1;
|
||||
effect2dist = level.fx_tabun_radius2 * level.fx_tabun_radius2;
|
||||
effect3dist = level.fx_tabun_radius3 * level.fx_tabun_radius3;
|
||||
effect4dist = level.fx_tabun_radius3;
|
||||
fxtoplay = -1;
|
||||
|
||||
if ( locations["distSqrd"][count] > effect0dist && locations["distSqrd"][previous] > effect1dist && locations["distSqrd"][next] > effect1dist )
|
||||
fxtoplay = 0;
|
||||
else if ( locations["distSqrd"][count] > effect1dist && locations["distSqrd"][previous] > effect2dist && locations["distSqrd"][next] > effect2dist )
|
||||
fxtoplay = 1;
|
||||
else if ( locations["distSqrd"][count] > effect2dist && locations["distSqrd"][previous] > effect3dist && locations["distSqrd"][next] > effect3dist )
|
||||
fxtoplay = 2;
|
||||
else if ( locations["distSqrd"][count] > effect3dist && locations["distSqrd"][previous] > effect4dist && locations["distSqrd"][next] > effect4dist )
|
||||
fxtoplay = 3;
|
||||
|
||||
return fxtoplay;
|
||||
}
|
||||
|
||||
getcentroid( locations )
|
||||
{
|
||||
centroid = ( 0, 0, 0 );
|
||||
|
||||
for ( i = 0; i < locations["loc"].size; i++ )
|
||||
centroid += locations["loc"][i] / locations["loc"].size;
|
||||
/#
|
||||
level.tabun_debug = getdvarintdefault( "scr_tabun_debug", 0 );
|
||||
|
||||
if ( level.tabun_debug )
|
||||
{
|
||||
purple = ( 0.9, 0.2, 0.9 );
|
||||
debugstar( centroid, 2000, purple );
|
||||
}
|
||||
#/
|
||||
return centroid;
|
||||
}
|
||||
|
||||
getcenter( locations )
|
||||
{
|
||||
center = ( 0, 0, 0 );
|
||||
curx = locations["tracePos"][0][0];
|
||||
cury = locations["tracePos"][0][1];
|
||||
minx = curx;
|
||||
maxx = curx;
|
||||
miny = cury;
|
||||
maxy = cury;
|
||||
|
||||
for ( i = 1; i < locations["tracePos"].size; i++ )
|
||||
{
|
||||
curx = locations["tracePos"][i][0];
|
||||
cury = locations["tracePos"][i][1];
|
||||
|
||||
if ( curx > maxx )
|
||||
maxx = curx;
|
||||
else if ( curx < minx )
|
||||
minx = curx;
|
||||
|
||||
if ( cury > maxy )
|
||||
{
|
||||
maxy = cury;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( cury < miny )
|
||||
miny = cury;
|
||||
}
|
||||
|
||||
avgx = ( maxx + minx ) / 2;
|
||||
avgy = ( maxy + miny ) / 2;
|
||||
center = ( avgx, avgy, locations["tracePos"][0][2] );
|
||||
/#
|
||||
level.tabun_debug = getdvarintdefault( "scr_tabun_debug", 0 );
|
||||
|
||||
if ( level.tabun_debug )
|
||||
{
|
||||
cyan = ( 0.2, 0.9, 0.9 );
|
||||
debugstar( center, 2000, cyan );
|
||||
}
|
||||
#/
|
||||
return center;
|
||||
}
|
385
MP/Core/maps/mp/_tacticalinsertion.gsc
Normal file
385
MP/Core/maps/mp/_tacticalinsertion.gsc
Normal file
@ -0,0 +1,385 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
#include maps\mp\gametypes\_globallogic_audio;
|
||||
#include maps\mp\_challenges;
|
||||
#include maps\mp\_scoreevents;
|
||||
#include maps\mp\gametypes\_weaponobjects;
|
||||
#include maps\mp\_hacker_tool;
|
||||
#include maps\mp\gametypes\_globallogic_player;
|
||||
#include maps\mp\gametypes\_damagefeedback;
|
||||
|
||||
init()
|
||||
{
|
||||
level.tacticalinsertionweapon = "tactical_insertion_mp";
|
||||
precachemodel( "t6_wpn_tac_insert_world" );
|
||||
loadfx( "misc/fx_equip_tac_insert_light_grn" );
|
||||
loadfx( "misc/fx_equip_tac_insert_light_red" );
|
||||
level._effect["tacticalInsertionFizzle"] = loadfx( "misc/fx_equip_tac_insert_exp" );
|
||||
maps\mp\gametypes\_globallogic_audio::registerdialoggroup( "item_destroyed", 1 );
|
||||
}
|
||||
|
||||
istacspawntouchingcrates( origin, angles )
|
||||
{
|
||||
crate_ents = getentarray( "care_package", "script_noteworthy" );
|
||||
mins = ( -17, -17, -40 );
|
||||
maxs = ( 17, 17, 40 );
|
||||
|
||||
for ( i = 0; i < crate_ents.size; i++ )
|
||||
{
|
||||
if ( crate_ents[i] istouchingvolume( origin + vectorscale( ( 0, 0, 1 ), 40.0 ), mins, maxs ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
overridespawn( ispredictedspawn )
|
||||
{
|
||||
if ( !isdefined( self.tacticalinsertion ) )
|
||||
return false;
|
||||
|
||||
origin = self.tacticalinsertion.origin;
|
||||
angles = self.tacticalinsertion.angles;
|
||||
team = self.tacticalinsertion.team;
|
||||
|
||||
if ( !ispredictedspawn )
|
||||
self.tacticalinsertion destroy_tactical_insertion();
|
||||
|
||||
if ( team != self.team )
|
||||
return false;
|
||||
|
||||
if ( istacspawntouchingcrates( origin ) )
|
||||
return false;
|
||||
|
||||
if ( !ispredictedspawn )
|
||||
{
|
||||
self.tacticalinsertiontime = gettime();
|
||||
self spawn( origin, angles, "tactical insertion" );
|
||||
self setspawnclientflag( "SCDFL_DISABLE_LOGGING" );
|
||||
self addweaponstat( "tactical_insertion_mp", "used", 1 );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
waitanddelete( time )
|
||||
{
|
||||
self endon( "death" );
|
||||
wait 0.05;
|
||||
self delete();
|
||||
}
|
||||
|
||||
watch( player )
|
||||
{
|
||||
if ( isdefined( player.tacticalinsertion ) )
|
||||
player.tacticalinsertion destroy_tactical_insertion();
|
||||
|
||||
player thread spawntacticalinsertion();
|
||||
self waitanddelete( 0.05 );
|
||||
}
|
||||
|
||||
watchusetrigger( trigger, callback, playersoundonuse, npcsoundonuse )
|
||||
{
|
||||
self endon( "delete" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
trigger waittill( "trigger", player );
|
||||
|
||||
if ( !isalive( player ) )
|
||||
continue;
|
||||
|
||||
if ( !player isonground() )
|
||||
continue;
|
||||
|
||||
if ( isdefined( trigger.triggerteam ) && player.team != trigger.triggerteam )
|
||||
continue;
|
||||
|
||||
if ( isdefined( trigger.triggerteamignore ) && player.team == trigger.triggerteamignore )
|
||||
continue;
|
||||
|
||||
if ( isdefined( trigger.claimedby ) && player != trigger.claimedby )
|
||||
continue;
|
||||
|
||||
if ( player usebuttonpressed() && !player.throwinggrenade && !player meleebuttonpressed() )
|
||||
{
|
||||
if ( isdefined( playersoundonuse ) )
|
||||
player playlocalsound( playersoundonuse );
|
||||
|
||||
if ( isdefined( npcsoundonuse ) )
|
||||
player playsound( npcsoundonuse );
|
||||
|
||||
self thread [[ callback ]]( player );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watchdisconnect()
|
||||
{
|
||||
self.tacticalinsertion endon( "delete" );
|
||||
|
||||
self waittill( "disconnect" );
|
||||
|
||||
self.tacticalinsertion thread destroy_tactical_insertion();
|
||||
}
|
||||
|
||||
destroy_tactical_insertion( attacker )
|
||||
{
|
||||
self.owner.tacticalinsertion = undefined;
|
||||
self notify( "delete" );
|
||||
self.owner notify( "tactical_insertion_destroyed" );
|
||||
self.friendlytrigger delete();
|
||||
self.enemytrigger delete();
|
||||
|
||||
if ( isdefined( attacker ) && isdefined( attacker.pers["team"] ) && isdefined( self.owner ) && isdefined( self.owner.pers["team"] ) )
|
||||
{
|
||||
if ( level.teambased )
|
||||
{
|
||||
if ( attacker.pers["team"] != self.owner.pers["team"] )
|
||||
{
|
||||
attacker notify( "destroyed_explosive" );
|
||||
attacker maps\mp\_challenges::destroyedequipment();
|
||||
attacker maps\mp\_challenges::destroyedtacticalinsert();
|
||||
maps\mp\_scoreevents::processscoreevent( "destroyed_tac_insert", attacker );
|
||||
}
|
||||
}
|
||||
else if ( attacker != self.owner )
|
||||
{
|
||||
attacker notify( "destroyed_explosive" );
|
||||
attacker maps\mp\_challenges::destroyedequipment();
|
||||
attacker maps\mp\_challenges::destroyedtacticalinsert();
|
||||
maps\mp\_scoreevents::processscoreevent( "destroyed_tac_insert", attacker );
|
||||
}
|
||||
}
|
||||
|
||||
self delete();
|
||||
}
|
||||
|
||||
fizzle( attacker )
|
||||
{
|
||||
if ( isdefined( self.fizzle ) && self.fizzle )
|
||||
return;
|
||||
|
||||
self.fizzle = 1;
|
||||
playfx( level._effect["tacticalInsertionFizzle"], self.origin );
|
||||
self playsound( "dst_tac_insert_break" );
|
||||
|
||||
if ( isdefined( attacker ) && attacker != self.owner )
|
||||
self.owner maps\mp\gametypes\_globallogic_audio::leaderdialogonplayer( "tact_destroyed", "item_destroyed" );
|
||||
|
||||
self destroy_tactical_insertion( attacker );
|
||||
}
|
||||
|
||||
pickup( attacker )
|
||||
{
|
||||
player = self.owner;
|
||||
self destroy_tactical_insertion();
|
||||
player giveweapon( level.tacticalinsertionweapon );
|
||||
player setweaponammoclip( level.tacticalinsertionweapon, 1 );
|
||||
}
|
||||
|
||||
spawntacticalinsertion()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self.tacticalinsertion = spawn( "script_model", self.origin + ( 0, 0, 1 ) );
|
||||
self.tacticalinsertion setmodel( "t6_wpn_tac_insert_world" );
|
||||
self.tacticalinsertion.origin = self.origin + ( 0, 0, 1 );
|
||||
self.tacticalinsertion.angles = self.angles;
|
||||
self.tacticalinsertion.team = self.team;
|
||||
self.tacticalinsertion setteam( self.team );
|
||||
self.tacticalinsertion.owner = self;
|
||||
self.tacticalinsertion setowner( self );
|
||||
self.tacticalinsertion setweapon( level.tacticalinsertionweapon );
|
||||
self.tacticalinsertion thread maps\mp\gametypes\_weaponobjects::attachreconmodel( "t6_wpn_tac_insert_detect", self );
|
||||
self.tacticalinsertion endon( "delete" );
|
||||
self.tacticalinsertion maps\mp\_hacker_tool::registerwithhackertool( level.equipmenthackertoolradius, level.equipmenthackertooltimems );
|
||||
triggerheight = 64;
|
||||
triggerradius = 128;
|
||||
self.tacticalinsertion.friendlytrigger = spawn( "trigger_radius_use", self.tacticalinsertion.origin + vectorscale( ( 0, 0, 1 ), 3.0 ) );
|
||||
self.tacticalinsertion.friendlytrigger setcursorhint( "HINT_NOICON", self.tacticalinsertion );
|
||||
self.tacticalinsertion.friendlytrigger sethintstring( &"MP_TACTICAL_INSERTION_PICKUP" );
|
||||
|
||||
if ( level.teambased )
|
||||
{
|
||||
self.tacticalinsertion.friendlytrigger setteamfortrigger( self.team );
|
||||
self.tacticalinsertion.friendlytrigger.triggerteam = self.team;
|
||||
}
|
||||
|
||||
self clientclaimtrigger( self.tacticalinsertion.friendlytrigger );
|
||||
self.tacticalinsertion.friendlytrigger.claimedby = self;
|
||||
self.tacticalinsertion.enemytrigger = spawn( "trigger_radius_use", self.tacticalinsertion.origin + vectorscale( ( 0, 0, 1 ), 3.0 ) );
|
||||
self.tacticalinsertion.enemytrigger setcursorhint( "HINT_NOICON", self.tacticalinsertion );
|
||||
self.tacticalinsertion.enemytrigger sethintstring( &"MP_TACTICAL_INSERTION_DESTROY" );
|
||||
self.tacticalinsertion.enemytrigger setinvisibletoplayer( self );
|
||||
|
||||
if ( level.teambased )
|
||||
{
|
||||
self.tacticalinsertion.enemytrigger setexcludeteamfortrigger( self.team );
|
||||
self.tacticalinsertion.enemytrigger.triggerteamignore = self.team;
|
||||
}
|
||||
|
||||
self.tacticalinsertion setclientflag( 2 );
|
||||
self thread watchdisconnect();
|
||||
watcher = maps\mp\gametypes\_weaponobjects::getweaponobjectwatcherbyweapon( level.tacticalinsertionweapon );
|
||||
self.tacticalinsertion thread watchusetrigger( self.tacticalinsertion.friendlytrigger, ::pickup, watcher.pickupsoundplayer, watcher.pickupsound );
|
||||
self.tacticalinsertion thread watchusetrigger( self.tacticalinsertion.enemytrigger, ::fizzle );
|
||||
|
||||
if ( isdefined( self.tacticalinsertioncount ) )
|
||||
self.tacticalinsertioncount++;
|
||||
else
|
||||
self.tacticalinsertioncount = 1;
|
||||
|
||||
self.tacticalinsertion setcandamage( 1 );
|
||||
self.tacticalinsertion.health = 1;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self.tacticalinsertion waittill( "damage", damage, attacker, direction, point, type, tagname, modelname, partname, weaponname, idflags );
|
||||
|
||||
if ( level.teambased && ( !isdefined( attacker ) || !isplayer( attacker ) || attacker.team == self.team ) && attacker != self )
|
||||
continue;
|
||||
|
||||
if ( attacker != self )
|
||||
{
|
||||
attacker maps\mp\_challenges::destroyedequipment( weaponname );
|
||||
attacker maps\mp\_challenges::destroyedtacticalinsert();
|
||||
maps\mp\_scoreevents::processscoreevent( "destroyed_tac_insert", attacker );
|
||||
}
|
||||
|
||||
if ( isdefined( weaponname ) )
|
||||
{
|
||||
switch ( weaponname )
|
||||
{
|
||||
case "flash_grenade_mp":
|
||||
case "concussion_grenade_mp":
|
||||
if ( level.teambased && self.tacticalinsertion.owner.team != attacker.team )
|
||||
{
|
||||
if ( maps\mp\gametypes\_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
attacker maps\mp\gametypes\_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
else if ( !level.teambased && self.tacticalinsertion.owner != attacker )
|
||||
{
|
||||
if ( maps\mp\gametypes\_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
attacker maps\mp\gametypes\_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
if ( maps\mp\gametypes\_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
attacker maps\mp\gametypes\_damagefeedback::updatedamagefeedback();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isdefined( attacker ) && attacker != self )
|
||||
self maps\mp\gametypes\_globallogic_audio::leaderdialogonplayer( "tact_destroyed", "item_destroyed" );
|
||||
|
||||
self.tacticalinsertion thread fizzle();
|
||||
}
|
||||
}
|
||||
|
||||
cancel_button_think()
|
||||
{
|
||||
if ( !isdefined( self.tacticalinsertion ) )
|
||||
return;
|
||||
|
||||
text = cancel_text_create();
|
||||
self thread cancel_button_press();
|
||||
event = self waittill_any_return( "tactical_insertion_destroyed", "disconnect", "end_killcam", "abort_killcam", "tactical_insertion_canceled", "spawned" );
|
||||
|
||||
if ( event == "tactical_insertion_canceled" )
|
||||
self.tacticalinsertion destroy_tactical_insertion();
|
||||
|
||||
if ( isdefined( text ) )
|
||||
text destroy();
|
||||
}
|
||||
|
||||
canceltackinsertionbutton()
|
||||
{
|
||||
if ( level.console )
|
||||
return self changeseatbuttonpressed();
|
||||
else
|
||||
return self jumpbuttonpressed();
|
||||
}
|
||||
|
||||
cancel_button_press()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self endon( "end_killcam" );
|
||||
self endon( "abort_killcam" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
wait 0.05;
|
||||
|
||||
if ( self canceltackinsertionbutton() )
|
||||
break;
|
||||
}
|
||||
|
||||
self notify( "tactical_insertion_canceled" );
|
||||
}
|
||||
|
||||
cancel_text_create()
|
||||
{
|
||||
text = newclienthudelem( self );
|
||||
text.archived = 0;
|
||||
text.y = -100;
|
||||
text.alignx = "center";
|
||||
text.aligny = "middle";
|
||||
text.horzalign = "center";
|
||||
text.vertalign = "bottom";
|
||||
text.sort = 10;
|
||||
text.font = "small";
|
||||
text.foreground = 1;
|
||||
text.hidewheninmenu = 1;
|
||||
|
||||
if ( self issplitscreen() )
|
||||
{
|
||||
text.y = -80;
|
||||
text.fontscale = 1.2;
|
||||
}
|
||||
else
|
||||
text.fontscale = 1.6;
|
||||
|
||||
text settext( &"PLATFORM_PRESS_TO_CANCEL_TACTICAL_INSERTION" );
|
||||
text.alpha = 1;
|
||||
return text;
|
||||
}
|
||||
|
||||
gettacticalinsertions()
|
||||
{
|
||||
tac_inserts = [];
|
||||
|
||||
foreach ( player in level.players )
|
||||
{
|
||||
if ( isdefined( player.tacticalinsertion ) )
|
||||
tac_inserts[tac_inserts.size] = player.tacticalinsertion;
|
||||
}
|
||||
|
||||
return tac_inserts;
|
||||
}
|
||||
|
||||
tacticalinsertiondestroyedbytrophysystem( attacker, trophysystem )
|
||||
{
|
||||
owner = self.owner;
|
||||
|
||||
if ( isdefined( attacker ) )
|
||||
{
|
||||
attacker maps\mp\_challenges::destroyedequipment( trophysystem.name );
|
||||
attacker maps\mp\_challenges::destroyedtacticalinsert();
|
||||
}
|
||||
|
||||
self thread fizzle();
|
||||
|
||||
if ( isdefined( owner ) )
|
||||
{
|
||||
owner endon( "death" );
|
||||
owner endon( "disconnect" );
|
||||
wait 0.05;
|
||||
owner maps\mp\gametypes\_globallogic_audio::leaderdialogonplayer( "tact_destroyed", "item_destroyed" );
|
||||
}
|
||||
}
|
188
MP/Core/maps/mp/_teargrenades.gsc
Normal file
188
MP/Core/maps/mp/_teargrenades.gsc
Normal file
@ -0,0 +1,188 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\gametypes\_perplayer;
|
||||
|
||||
main()
|
||||
{
|
||||
level.tearradius = 170;
|
||||
level.tearheight = 128;
|
||||
level.teargasfillduration = 7;
|
||||
level.teargasduration = 23;
|
||||
level.tearsufferingduration = 3;
|
||||
level.teargrenadetimer = 4;
|
||||
precacheshellshock( "teargas" );
|
||||
fgmonitor = maps\mp\gametypes\_perplayer::init( "tear_grenade_monitor", ::startmonitoringtearusage, ::stopmonitoringtearusage );
|
||||
maps\mp\gametypes\_perplayer::enable( fgmonitor );
|
||||
}
|
||||
|
||||
startmonitoringtearusage()
|
||||
{
|
||||
self thread monitortearusage();
|
||||
}
|
||||
|
||||
stopmonitoringtearusage( disconnected )
|
||||
{
|
||||
self notify( "stop_monitoring_tear_usage" );
|
||||
}
|
||||
|
||||
monitortearusage()
|
||||
{
|
||||
self endon( "stop_monitoring_tear_usage" );
|
||||
wait 0.05;
|
||||
|
||||
if ( !self hasweapon( "tear_grenade_mp" ) )
|
||||
return;
|
||||
|
||||
prevammo = self getammocount( "tear_grenade_mp" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
ammo = self getammocount( "tear_grenade_mp" );
|
||||
|
||||
if ( ammo < prevammo )
|
||||
{
|
||||
num = prevammo - ammo;
|
||||
/#
|
||||
|
||||
#/
|
||||
for ( i = 0; i < num; i++ )
|
||||
{
|
||||
grenades = getentarray( "grenade", "classname" );
|
||||
bestdist = undefined;
|
||||
bestg = undefined;
|
||||
|
||||
for ( g = 0; g < grenades.size; g++ )
|
||||
{
|
||||
if ( !isdefined( grenades[g].teargrenade ) )
|
||||
{
|
||||
dist = distance( grenades[g].origin, self.origin + vectorscale( ( 0, 0, 1 ), 48.0 ) );
|
||||
|
||||
if ( !isdefined( bestdist ) || dist < bestdist )
|
||||
{
|
||||
bestdist = dist;
|
||||
bestg = g;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isdefined( bestdist ) )
|
||||
{
|
||||
grenades[bestg].teargrenade = 1;
|
||||
grenades[bestg] thread teargrenade_think( self.team );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prevammo = ammo;
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
teargrenade_think( team )
|
||||
{
|
||||
wait( level.teargrenadetimer );
|
||||
ent = spawnstruct();
|
||||
ent thread tear( self.origin );
|
||||
}
|
||||
|
||||
tear( pos )
|
||||
{
|
||||
trig = spawn( "trigger_radius", pos, 0, level.tearradius, level.tearheight );
|
||||
starttime = gettime();
|
||||
self thread teartimer();
|
||||
self endon( "tear_timeout" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
trig waittill( "trigger", player );
|
||||
|
||||
if ( player.sessionstate != "playing" )
|
||||
continue;
|
||||
|
||||
time = ( gettime() - starttime ) / 1000;
|
||||
currad = level.tearradius;
|
||||
curheight = level.tearheight;
|
||||
|
||||
if ( time < level.teargasfillduration )
|
||||
{
|
||||
currad *= time / level.teargasfillduration;
|
||||
curheight *= time / level.teargasfillduration;
|
||||
}
|
||||
|
||||
offset = player.origin + vectorscale( ( 0, 0, 1 ), 32.0 ) - pos;
|
||||
offset2d = ( offset[0], offset[1], 0 );
|
||||
|
||||
if ( lengthsquared( offset2d ) > currad * currad )
|
||||
continue;
|
||||
|
||||
if ( player.origin[2] - pos[2] > curheight )
|
||||
continue;
|
||||
|
||||
player.teargasstarttime = gettime();
|
||||
|
||||
if ( !isdefined( player.teargassuffering ) )
|
||||
player thread teargassuffering();
|
||||
}
|
||||
}
|
||||
|
||||
teartimer()
|
||||
{
|
||||
wait( level.teargasduration );
|
||||
self notify( "tear_timeout" );
|
||||
}
|
||||
|
||||
teargassuffering()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "disconnect" );
|
||||
self.teargassuffering = 1;
|
||||
|
||||
if ( self mayapplyscreeneffect() )
|
||||
self shellshock( "teargas", 60 );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
if ( gettime() - self.teargasstarttime > level.tearsufferingduration * 1000 )
|
||||
break;
|
||||
|
||||
wait 1;
|
||||
}
|
||||
|
||||
self shellshock( "teargas", 1 );
|
||||
|
||||
if ( self mayapplyscreeneffect() )
|
||||
self.teargassuffering = undefined;
|
||||
}
|
||||
|
||||
drawcylinder( pos, rad, height )
|
||||
{
|
||||
time = 0;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
currad = rad;
|
||||
curheight = height;
|
||||
|
||||
if ( time < level.teargasfillduration )
|
||||
{
|
||||
currad *= time / level.teargasfillduration;
|
||||
curheight *= time / level.teargasfillduration;
|
||||
}
|
||||
|
||||
for ( r = 0; r < 20; r++ )
|
||||
{
|
||||
theta = r / 20 * 360;
|
||||
theta2 = ( r + 1 ) / 20 * 360;
|
||||
line( pos + ( cos( theta ) * currad, sin( theta ) * currad, 0 ), pos + ( cos( theta2 ) * currad, sin( theta2 ) * currad, 0 ) );
|
||||
line( pos + ( cos( theta ) * currad, sin( theta ) * currad, curheight ), pos + ( cos( theta2 ) * currad, sin( theta2 ) * currad, curheight ) );
|
||||
line( pos + ( cos( theta ) * currad, sin( theta ) * currad, 0 ), pos + ( cos( theta ) * currad, sin( theta ) * currad, curheight ) );
|
||||
}
|
||||
|
||||
time += 0.05;
|
||||
|
||||
if ( time > level.teargasduration )
|
||||
break;
|
||||
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
101
MP/Core/maps/mp/_treadfx.gsc
Normal file
101
MP/Core/maps/mp/_treadfx.gsc
Normal file
@ -0,0 +1,101 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
|
||||
loadtreadfx( vehicle )
|
||||
{
|
||||
treadfx = vehicle.treadfxnamearray;
|
||||
|
||||
if ( isdefined( treadfx ) )
|
||||
{
|
||||
vehicle.treadfx = [];
|
||||
|
||||
if ( isdefined( treadfx["asphalt"] ) && treadfx["asphalt"] != "" )
|
||||
vehicle.treadfx["asphalt"] = loadfx( treadfx["asphalt"] );
|
||||
|
||||
if ( isdefined( treadfx["bark"] ) && treadfx["bark"] != "" )
|
||||
vehicle.treadfx["bark"] = loadfx( treadfx["bark"] );
|
||||
|
||||
if ( isdefined( treadfx["brick"] ) && treadfx["brick"] != "" )
|
||||
vehicle.treadfx["brick"] = loadfx( treadfx["brick"] );
|
||||
|
||||
if ( isdefined( treadfx["carpet"] ) && treadfx["carpet"] != "" )
|
||||
vehicle.treadfx["carpet"] = loadfx( treadfx["carpet"] );
|
||||
|
||||
if ( isdefined( treadfx["ceramic"] ) && treadfx["ceramic"] != "" )
|
||||
vehicle.treadfx["ceramic"] = loadfx( treadfx["ceramic"] );
|
||||
|
||||
if ( isdefined( treadfx["cloth"] ) && treadfx["cloth"] != "" )
|
||||
vehicle.treadfx["cloth"] = loadfx( treadfx["cloth"] );
|
||||
|
||||
if ( isdefined( treadfx["concrete"] ) && treadfx["concrete"] != "" )
|
||||
vehicle.treadfx["concrete"] = loadfx( treadfx["concrete"] );
|
||||
|
||||
if ( isdefined( treadfx["cushion"] ) && treadfx["cushion"] != "" )
|
||||
vehicle.treadfx["cushion"] = loadfx( treadfx["cushion"] );
|
||||
|
||||
if ( isdefined( treadfx["none"] ) && treadfx["none"] != "" )
|
||||
vehicle.treadfx["none"] = loadfx( treadfx["none"] );
|
||||
|
||||
if ( isdefined( treadfx["dirt"] ) && treadfx["dirt"] != "" )
|
||||
vehicle.treadfx["dirt"] = loadfx( treadfx["dirt"] );
|
||||
|
||||
if ( isdefined( treadfx["flesh"] ) && treadfx["flesh"] != "" )
|
||||
vehicle.treadfx["flesh"] = loadfx( treadfx["flesh"] );
|
||||
|
||||
if ( isdefined( treadfx["foliage"] ) && treadfx["foliage"] != "" )
|
||||
vehicle.treadfx["foliage"] = loadfx( treadfx["foliage"] );
|
||||
|
||||
if ( isdefined( treadfx["fruit"] ) && treadfx["fruit"] != "" )
|
||||
vehicle.treadfx["fruit"] = loadfx( treadfx["fruit"] );
|
||||
|
||||
if ( isdefined( treadfx["glass"] ) && treadfx["glass"] != "" )
|
||||
vehicle.treadfx["glass"] = loadfx( treadfx["glass"] );
|
||||
|
||||
if ( isdefined( treadfx["grass"] ) && treadfx["grass"] != "" )
|
||||
vehicle.treadfx["grass"] = loadfx( treadfx["grass"] );
|
||||
|
||||
if ( isdefined( treadfx["gravel"] ) && treadfx["gravel"] != "" )
|
||||
vehicle.treadfx["gravel"] = loadfx( treadfx["gravel"] );
|
||||
|
||||
if ( isdefined( treadfx["metal"] ) && treadfx["metal"] != "" )
|
||||
vehicle.treadfx["metal"] = loadfx( treadfx["metal"] );
|
||||
|
||||
if ( isdefined( treadfx["mud"] ) && treadfx["mud"] != "" )
|
||||
vehicle.treadfx["mud"] = loadfx( treadfx["mud"] );
|
||||
|
||||
if ( isdefined( treadfx["paintedmetal"] ) && treadfx["paintedmetal"] != "" )
|
||||
vehicle.treadfx["paintedmetal"] = loadfx( treadfx["paintedmetal"] );
|
||||
|
||||
if ( isdefined( treadfx["paper"] ) && treadfx["paper"] != "" )
|
||||
vehicle.treadfx["paper"] = loadfx( treadfx["paper"] );
|
||||
|
||||
if ( isdefined( treadfx["plaster"] ) && treadfx["plaster"] != "" )
|
||||
vehicle.treadfx["plaster"] = loadfx( treadfx["plaster"] );
|
||||
|
||||
if ( isdefined( treadfx["plastic"] ) && treadfx["plastic"] != "" )
|
||||
vehicle.treadfx["plastic"] = loadfx( treadfx["plastic"] );
|
||||
|
||||
if ( isdefined( treadfx["rock"] ) && treadfx["rock"] != "" )
|
||||
vehicle.treadfx["rock"] = loadfx( treadfx["rock"] );
|
||||
|
||||
if ( isdefined( treadfx["rubber"] ) && treadfx["rubber"] != "" )
|
||||
vehicle.treadfx["rubber"] = loadfx( treadfx["rubber"] );
|
||||
|
||||
if ( isdefined( treadfx["sand"] ) && treadfx["sand"] != "" )
|
||||
vehicle.treadfx["sand"] = loadfx( treadfx["sand"] );
|
||||
|
||||
if ( isdefined( treadfx["water"] ) && treadfx["water"] != "" )
|
||||
vehicle.treadfx["water"] = loadfx( treadfx["water"] );
|
||||
|
||||
if ( isdefined( treadfx["wood"] ) && treadfx["wood"] != "" )
|
||||
vehicle.treadfx["wood"] = loadfx( treadfx["wood"] );
|
||||
}
|
||||
}
|
||||
|
||||
preloadtreadfx( vehicle )
|
||||
{
|
||||
treadfx = getvehicletreadfxarray( vehicle );
|
||||
|
||||
for ( i = 0; i < treadfx.size; i++ )
|
||||
loadfx( treadfx[i] );
|
||||
}
|
342
MP/Core/maps/mp/_trophy_system.gsc
Normal file
342
MP/Core/maps/mp/_trophy_system.gsc
Normal file
@ -0,0 +1,342 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\gametypes\_weaponobjects;
|
||||
#include maps\mp\gametypes\_globallogic_audio;
|
||||
#include maps\mp\_challenges;
|
||||
#include maps\mp\_scoreevents;
|
||||
#include maps\mp\_tacticalinsertion;
|
||||
#include maps\mp\killstreaks\_emp;
|
||||
#include maps\mp\gametypes\_globallogic_player;
|
||||
#include maps\mp\gametypes\_damagefeedback;
|
||||
|
||||
#using_animtree("mp_trophy_system");
|
||||
|
||||
init()
|
||||
{
|
||||
precachemodel( "t6_wpn_trophy_system_world" );
|
||||
level.trophylongflashfx = loadfx( "weapon/trophy_system/fx_trophy_flash_lng" );
|
||||
level.trophydetonationfx = loadfx( "weapon/trophy_system/fx_trophy_radius_detonation" );
|
||||
level._effect["fx_trophy_friendly_light"] = loadfx( "weapon/trophy_system/fx_trophy_light_friendly" );
|
||||
level._effect["fx_trophy_enemy_light"] = loadfx( "weapon/trophy_system/fx_trophy_light_enemy" );
|
||||
level._effect["fx_trophy_deploy_impact"] = loadfx( "weapon/trophy_system/fx_trophy_deploy_impact" );
|
||||
trophydeployanim = %o_trophy_deploy;
|
||||
trophyspinanim = %o_trophy_spin;
|
||||
}
|
||||
|
||||
register()
|
||||
{
|
||||
registerclientfield( "missile", "trophy_system_state", 1, 2, "int" );
|
||||
registerclientfield( "scriptmover", "trophy_system_state", 1, 2, "int" );
|
||||
}
|
||||
|
||||
createtrophysystemwatcher()
|
||||
{
|
||||
watcher = self maps\mp\gametypes\_weaponobjects::createuseweaponobjectwatcher( "trophy_system", "trophy_system_mp", self.team );
|
||||
watcher.detonate = ::trophysystemdetonate;
|
||||
watcher.activatesound = "wpn_claymore_alert";
|
||||
watcher.hackable = 1;
|
||||
watcher.hackertoolradius = level.equipmenthackertoolradius;
|
||||
watcher.hackertooltimems = level.equipmenthackertooltimems;
|
||||
watcher.reconmodel = "t6_wpn_trophy_system_world_detect";
|
||||
watcher.ownergetsassist = 1;
|
||||
watcher.ignoredirection = 1;
|
||||
watcher.activationdelay = 0.1;
|
||||
watcher.headicon = 1;
|
||||
watcher.enemydestroy = 1;
|
||||
watcher.onspawn = ::ontrophysystemspawn;
|
||||
watcher.ondamage = ::watchtrophysystemdamage;
|
||||
watcher.ondestroyed = ::ontrophysystemsmashed;
|
||||
watcher.stun = ::weaponstun;
|
||||
watcher.stuntime = 1;
|
||||
}
|
||||
|
||||
ontrophysystemspawn( watcher, player )
|
||||
{
|
||||
player endon( "death" );
|
||||
player endon( "disconnect" );
|
||||
level endon( "game_ended" );
|
||||
self maps\mp\gametypes\_weaponobjects::onspawnuseweaponobject( watcher, player );
|
||||
player addweaponstat( "trophy_system_mp", "used", 1 );
|
||||
self.ammo = 2;
|
||||
self thread trophyactive( player );
|
||||
self thread trophywatchhack();
|
||||
self setclientfield( "trophy_system_state", 1 );
|
||||
self playloopsound( "wpn_trophy_spin", 0.25 );
|
||||
|
||||
if ( isdefined( watcher.reconmodel ) )
|
||||
self thread setreconmodeldeployed();
|
||||
}
|
||||
|
||||
setreconmodeldeployed()
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ( isdefined( self.reconmodelentity ) )
|
||||
{
|
||||
self.reconmodelentity setclientfield( "trophy_system_state", 1 );
|
||||
return;
|
||||
}
|
||||
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
trophywatchhack()
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
self waittill( "hacked", player );
|
||||
|
||||
wait 0.05;
|
||||
self thread trophyactive( player );
|
||||
}
|
||||
|
||||
ontrophysystemsmashed( attacker )
|
||||
{
|
||||
playfx( level._effect["tacticalInsertionFizzle"], self.origin );
|
||||
self playsound( "dst_tac_insert_break" );
|
||||
self.owner maps\mp\gametypes\_globallogic_audio::leaderdialogonplayer( "equipment_destroyed", "item_destroyed" );
|
||||
|
||||
if ( isdefined( attacker ) && self.owner isenemyplayer( attacker ) )
|
||||
{
|
||||
attacker maps\mp\_challenges::destroyedequipment();
|
||||
maps\mp\_scoreevents::processscoreevent( "destroyed_trophy_system", attacker, self.owner );
|
||||
}
|
||||
|
||||
self delete();
|
||||
}
|
||||
|
||||
trophyactive( owner )
|
||||
{
|
||||
owner endon( "disconnect" );
|
||||
self endon( "death" );
|
||||
self endon( "hacked" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
tac_inserts = maps\mp\_tacticalinsertion::gettacticalinsertions();
|
||||
|
||||
if ( level.missileentities.size < 1 && tac_inserts.size < 1 || isdefined( self.disabled ) )
|
||||
{
|
||||
wait 0.05;
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( index = 0; index < level.missileentities.size; index++ )
|
||||
{
|
||||
wait 0.05;
|
||||
grenade = level.missileentities[index];
|
||||
|
||||
if ( !isdefined( grenade ) )
|
||||
continue;
|
||||
|
||||
if ( grenade == self )
|
||||
continue;
|
||||
|
||||
if ( isdefined( grenade.weaponname ) )
|
||||
{
|
||||
switch ( grenade.weaponname )
|
||||
{
|
||||
case "claymore_mp":
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isdefined( grenade.name ) && grenade.name == "tactical_insertion_mp" )
|
||||
continue;
|
||||
|
||||
switch ( grenade.model )
|
||||
{
|
||||
case "t6_wpn_grenade_supply_projectile":
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !isdefined( grenade.owner ) )
|
||||
grenade.owner = getmissileowner( grenade );
|
||||
|
||||
if ( isdefined( grenade.owner ) )
|
||||
{
|
||||
if ( level.teambased )
|
||||
{
|
||||
if ( grenade.owner.team == owner.team )
|
||||
continue;
|
||||
}
|
||||
else if ( grenade.owner == owner )
|
||||
continue;
|
||||
|
||||
grenadedistancesquared = distancesquared( grenade.origin, self.origin );
|
||||
|
||||
if ( grenadedistancesquared < 262144 )
|
||||
{
|
||||
if ( bullettracepassed( grenade.origin, self.origin + vectorscale( ( 0, 0, 1 ), 29.0 ), 0, self ) )
|
||||
{
|
||||
playfx( level.trophylongflashfx, self.origin + vectorscale( ( 0, 0, 1 ), 15.0 ), grenade.origin - self.origin, anglestoup( self.angles ) );
|
||||
owner thread projectileexplode( grenade, self );
|
||||
index--;
|
||||
self playsound( "wpn_trophy_alert" );
|
||||
self.ammo--;
|
||||
|
||||
if ( self.ammo <= 0 )
|
||||
self thread trophysystemdetonate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( index = 0; index < tac_inserts.size; index++ )
|
||||
{
|
||||
wait 0.05;
|
||||
tac_insert = tac_inserts[index];
|
||||
|
||||
if ( !isdefined( tac_insert ) )
|
||||
continue;
|
||||
|
||||
if ( isdefined( tac_insert.owner ) )
|
||||
{
|
||||
if ( level.teambased )
|
||||
{
|
||||
if ( tac_insert.owner.team == owner.team )
|
||||
continue;
|
||||
}
|
||||
else if ( tac_insert.owner == owner )
|
||||
continue;
|
||||
|
||||
grenadedistancesquared = distancesquared( tac_insert.origin, self.origin );
|
||||
|
||||
if ( grenadedistancesquared < 262144 )
|
||||
{
|
||||
if ( bullettracepassed( tac_insert.origin, self.origin + vectorscale( ( 0, 0, 1 ), 29.0 ), 0, tac_insert ) )
|
||||
{
|
||||
playfx( level.trophylongflashfx, self.origin + vectorscale( ( 0, 0, 1 ), 15.0 ), tac_insert.origin - self.origin, anglestoup( self.angles ) );
|
||||
owner thread trophydestroytacinsert( tac_insert, self );
|
||||
index--;
|
||||
self playsound( "wpn_trophy_alert" );
|
||||
self.ammo--;
|
||||
|
||||
if ( self.ammo <= 0 )
|
||||
self thread trophysystemdetonate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
projectileexplode( projectile, trophy )
|
||||
{
|
||||
self endon( "death" );
|
||||
projposition = projectile.origin;
|
||||
playfx( level.trophydetonationfx, projposition );
|
||||
projectile delete();
|
||||
trophy radiusdamage( projposition, 128, 105, 10, self );
|
||||
maps\mp\_scoreevents::processscoreevent( "trophy_defense", self );
|
||||
self addplayerstat( "destroy_explosive_with_trophy", 1 );
|
||||
self addweaponstat( "trophy_system_mp", "CombatRecordStat", 1 );
|
||||
}
|
||||
|
||||
trophydestroytacinsert( tacinsert, trophy )
|
||||
{
|
||||
self endon( "death" );
|
||||
tacpos = tacinsert.origin;
|
||||
playfx( level.trophydetonationfx, tacinsert.origin );
|
||||
tacinsert thread maps\mp\_tacticalinsertion::tacticalinsertiondestroyedbytrophysystem( self, trophy );
|
||||
trophy radiusdamage( tacpos, 128, 105, 10, self );
|
||||
maps\mp\_scoreevents::processscoreevent( "trophy_defense", self );
|
||||
self addplayerstat( "destroy_explosive_with_trophy", 1 );
|
||||
self addweaponstat( "trophy_system_mp", "CombatRecordStat", 1 );
|
||||
}
|
||||
|
||||
trophysystemdetonate( attacker, weaponname )
|
||||
{
|
||||
from_emp = maps\mp\killstreaks\_emp::isempweapon( weaponname );
|
||||
|
||||
if ( !from_emp )
|
||||
playfx( level._equipment_explode_fx_lg, self.origin );
|
||||
|
||||
if ( isdefined( attacker ) && self.owner isenemyplayer( attacker ) )
|
||||
{
|
||||
attacker maps\mp\_challenges::destroyedequipment( weaponname );
|
||||
maps\mp\_scoreevents::processscoreevent( "destroyed_trophy_system", attacker, self.owner, weaponname );
|
||||
}
|
||||
|
||||
playsoundatposition( "dst_equipment_destroy", self.origin );
|
||||
self delete();
|
||||
}
|
||||
|
||||
watchtrophysystemdamage( watcher )
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "hacked" );
|
||||
self setcandamage( 1 );
|
||||
damagemax = 20;
|
||||
|
||||
if ( !self maps\mp\_utility::ishacked() )
|
||||
self.damagetaken = 0;
|
||||
|
||||
self.maxhealth = 10000;
|
||||
self.health = self.maxhealth;
|
||||
self setmaxhealth( self.maxhealth );
|
||||
attacker = undefined;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self waittill( "damage", damage, attacker, direction_vec, point, type, modelname, tagname, partname, weaponname, idflags );
|
||||
|
||||
if ( !isplayer( attacker ) )
|
||||
continue;
|
||||
|
||||
if ( level.teambased )
|
||||
{
|
||||
if ( !level.hardcoremode && self.owner.team == attacker.pers["team"] && self.owner != attacker )
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isdefined( weaponname ) )
|
||||
{
|
||||
switch ( weaponname )
|
||||
{
|
||||
case "flash_grenade_mp":
|
||||
case "concussion_grenade_mp":
|
||||
if ( watcher.stuntime > 0 )
|
||||
self thread maps\mp\gametypes\_weaponobjects::stunstart( watcher, watcher.stuntime );
|
||||
|
||||
if ( level.teambased && self.owner.team != attacker.team )
|
||||
{
|
||||
if ( maps\mp\gametypes\_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
attacker maps\mp\gametypes\_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
else if ( !level.teambased && self.owner != attacker )
|
||||
{
|
||||
if ( maps\mp\gametypes\_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
attacker maps\mp\gametypes\_damagefeedback::updatedamagefeedback();
|
||||
}
|
||||
|
||||
continue;
|
||||
case "emp_grenade_mp":
|
||||
damage = damagemax;
|
||||
default:
|
||||
if ( maps\mp\gametypes\_globallogic_player::dodamagefeedback( weaponname, attacker ) )
|
||||
attacker maps\mp\gametypes\_damagefeedback::updatedamagefeedback();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
weaponname = "";
|
||||
|
||||
if ( type == "MOD_MELEE" )
|
||||
self.damagetaken = damagemax;
|
||||
else
|
||||
self.damagetaken += damage;
|
||||
|
||||
if ( self.damagetaken >= damagemax )
|
||||
{
|
||||
watcher thread maps\mp\gametypes\_weaponobjects::waitanddetonate( self, 0.05, attacker, weaponname );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
2671
MP/Core/maps/mp/_utility.gsc
Normal file
2671
MP/Core/maps/mp/_utility.gsc
Normal file
File diff suppressed because it is too large
Load Diff
1543
MP/Core/maps/mp/_vehicles.gsc
Normal file
1543
MP/Core/maps/mp/_vehicles.gsc
Normal file
File diff suppressed because it is too large
Load Diff
105
MP/Core/maps/mp/animscripts/dog_combat.gsc
Normal file
105
MP/Core/maps/mp/animscripts/dog_combat.gsc
Normal file
@ -0,0 +1,105 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\animscripts\shared;
|
||||
#include maps\mp\animscripts\utility;
|
||||
|
||||
main()
|
||||
{
|
||||
debug_anim_print( "dog_combat::main() " );
|
||||
self endon( "killanimscript" );
|
||||
self setaimanimweights( 0, 0 );
|
||||
/#
|
||||
if ( !debug_allow_combat() )
|
||||
{
|
||||
combatidle();
|
||||
return;
|
||||
}
|
||||
#/
|
||||
if ( isdefined( level.hostmigrationtimer ) )
|
||||
{
|
||||
combatidle();
|
||||
return;
|
||||
}
|
||||
|
||||
assert( isdefined( self.enemy ) );
|
||||
|
||||
if ( !isalive( self.enemy ) )
|
||||
{
|
||||
combatidle();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isplayer( self.enemy ) )
|
||||
self meleebiteattackplayer( self.enemy );
|
||||
}
|
||||
|
||||
combatidle()
|
||||
{
|
||||
self set_orient_mode( "face enemy" );
|
||||
self animmode( "zonly_physics", 0 );
|
||||
idleanims = [];
|
||||
idleanims[0] = "combat_attackidle";
|
||||
idleanims[1] = "combat_attackidle_bark";
|
||||
idleanims[2] = "combat_attackidle_growl";
|
||||
idleanim = random( idleanims );
|
||||
debug_anim_print( "dog_combat::combatIdle() - Setting " + idleanim );
|
||||
self setanimstate( idleanim );
|
||||
self maps\mp\animscripts\shared::donotetracks( "done" );
|
||||
debug_anim_print( "dog_combat::combatIdle() - " + idleanim + " notify done." );
|
||||
}
|
||||
|
||||
meleebiteattackplayer( player )
|
||||
{
|
||||
self set_orient_mode( "face enemy" );
|
||||
self animmode( "gravity", 0 );
|
||||
self.safetochangescript = 0;
|
||||
|
||||
if ( use_low_attack() )
|
||||
{
|
||||
self animmode( "angle deltas", 0 );
|
||||
self setanimstate( "combat_attack_player_close_range" );
|
||||
wait 0.35;
|
||||
|
||||
if ( isplayer( self.enemy ) && self.enemy getstance() == "prone" )
|
||||
self meleewithoffset( vectorscale( ( 0, 0, -1 ), 9.0 ) );
|
||||
else
|
||||
self melee();
|
||||
|
||||
self maps\mp\animscripts\shared::donotetracksfortime( 1.2, "done" );
|
||||
self animmode( "gravity", 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
attack_time = 1.2 + randomfloat( 0.4 );
|
||||
debug_anim_print( "dog_combat::meleeBiteAttackPlayer() - Setting combat_run_attack" );
|
||||
self setanimstate( "combat_attack_run" );
|
||||
self maps\mp\animscripts\shared::donotetracksfortime( attack_time, "done", ::handlemeleebiteattacknotetracks, player );
|
||||
debug_anim_print( "dog_combat::meleeBiteAttackPlayer() - combat_attack_run notify done." );
|
||||
}
|
||||
|
||||
self.safetochangescript = 1;
|
||||
self animmode( "none", 0 );
|
||||
}
|
||||
|
||||
handlemeleebiteattacknotetracks( note, player )
|
||||
{
|
||||
if ( note == "dog_melee" )
|
||||
self melee( anglestoforward( self.angles ) );
|
||||
}
|
||||
|
||||
use_low_attack()
|
||||
{
|
||||
if ( isplayer( self.enemy ) )
|
||||
{
|
||||
if ( self.enemy getstance() == "prone" )
|
||||
{
|
||||
attack_height = self.origin[2] + 16;
|
||||
|
||||
if ( self.enemy.origin[2] < attack_height )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
32
MP/Core/maps/mp/animscripts/dog_death.gsc
Normal file
32
MP/Core/maps/mp/animscripts/dog_death.gsc
Normal file
@ -0,0 +1,32 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\utility;
|
||||
#include maps\mp\animscripts\shared;
|
||||
|
||||
main()
|
||||
{
|
||||
debug_anim_print( "dog_death::main()" );
|
||||
self setaimanimweights( 0, 0 );
|
||||
self endon( "killanimscript" );
|
||||
|
||||
if ( isdefined( self.a.nodeath ) )
|
||||
{
|
||||
assert( self.a.nodeath, "Nodeath needs to be set to true or undefined." );
|
||||
wait 3;
|
||||
return;
|
||||
}
|
||||
|
||||
self unlink();
|
||||
|
||||
if ( isdefined( self.enemy ) && isdefined( self.enemy.syncedmeleetarget ) && self.enemy.syncedmeleetarget == self )
|
||||
self.enemy.syncedmeleetarget = undefined;
|
||||
|
||||
death_anim = "death_" + getanimdirection( self.damageyaw );
|
||||
/#
|
||||
println( death_anim );
|
||||
#/
|
||||
self animmode( "gravity", 0 );
|
||||
debug_anim_print( "dog_death::main() - Setting " + death_anim );
|
||||
self setanimstate( death_anim );
|
||||
self maps\mp\animscripts\shared::donotetracks( "done" );
|
||||
}
|
28
MP/Core/maps/mp/animscripts/dog_flashed.gsc
Normal file
28
MP/Core/maps/mp/animscripts/dog_flashed.gsc
Normal file
@ -0,0 +1,28 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\shared;
|
||||
|
||||
main()
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self endon( "stop_flashbang_effect" );
|
||||
wait( randomfloatrange( 0, 0.4 ) );
|
||||
duration = self startflashbanged() * 0.001;
|
||||
self setanimstate( "flashed" );
|
||||
self maps\mp\animscripts\shared::donotetracks( "done" );
|
||||
self setflashbanged( 0 );
|
||||
self.flashed = 0;
|
||||
self notify( "stop_flashbang_effect" );
|
||||
}
|
||||
|
||||
startflashbanged()
|
||||
{
|
||||
if ( isdefined( self.flashduration ) )
|
||||
duration = self.flashduration;
|
||||
else
|
||||
duration = self getflashbangedstrength() * 1000;
|
||||
|
||||
self.flashendtime = gettime() + duration;
|
||||
self notify( "flashed" );
|
||||
return duration;
|
||||
}
|
64
MP/Core/maps/mp/animscripts/dog_init.gsc
Normal file
64
MP/Core/maps/mp/animscripts/dog_init.gsc
Normal file
@ -0,0 +1,64 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\shared;
|
||||
#include maps\mp\animscripts\utility;
|
||||
#include maps\mp\animscripts\dog_move;
|
||||
#include maps\mp\animscripts\dog_combat;
|
||||
|
||||
main()
|
||||
{
|
||||
level.dog_debug_orient = 0;
|
||||
level.dog_debug_anims = 0;
|
||||
level.dog_debug_anims_ent = 0;
|
||||
level.dog_debug_turns = 0;
|
||||
debug_anim_print( "dog_init::main() " );
|
||||
maps\mp\animscripts\dog_move::setup_sound_variables();
|
||||
anim_get_dvar_int( "debug_dog_sound", "0" );
|
||||
anim_get_dvar_int( "debug_dog_notetracks", "0" );
|
||||
anim_get_dvar_int( "dog_force_walk", 0 );
|
||||
anim_get_dvar_int( "dog_force_run", 0 );
|
||||
self.ignoresuppression = 1;
|
||||
self.chatinitialized = 0;
|
||||
self.nododgemove = 1;
|
||||
level.dogrunturnspeed = 20;
|
||||
level.dogrunpainspeed = 20;
|
||||
self.meleeattackdist = 0;
|
||||
self thread setmeleeattackdist();
|
||||
self.a = spawnstruct();
|
||||
self.a.pose = "stand";
|
||||
self.a.nextstandinghitdying = 0;
|
||||
self.a.movement = "run";
|
||||
set_anim_playback_rate();
|
||||
self.suppressionthreshold = 1;
|
||||
self.disablearrivals = 0;
|
||||
level.dogstoppingdistsq = 3416.82;
|
||||
self.stopanimdistsq = level.dogstoppingdistsq;
|
||||
self.pathenemyfightdist = 512;
|
||||
self settalktospecies( "dog" );
|
||||
level.lastdogmeleeplayertime = 0;
|
||||
level.dogmeleeplayercounter = 0;
|
||||
|
||||
if ( !isdefined( level.dog_hits_before_kill ) )
|
||||
level.dog_hits_before_kill = 1;
|
||||
}
|
||||
|
||||
set_anim_playback_rate()
|
||||
{
|
||||
self.animplaybackrate = 0.9 + randomfloat( 0.2 );
|
||||
self.moveplaybackrate = 1;
|
||||
}
|
||||
|
||||
setmeleeattackdist()
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self.meleeattackdist = 0;
|
||||
|
||||
if ( self maps\mp\animscripts\dog_combat::use_low_attack() )
|
||||
self.meleeattackdist = 64;
|
||||
|
||||
wait 1;
|
||||
}
|
||||
}
|
15
MP/Core/maps/mp/animscripts/dog_jump.gsc
Normal file
15
MP/Core/maps/mp/animscripts/dog_jump.gsc
Normal file
@ -0,0 +1,15 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\utility;
|
||||
#include maps\mp\animscripts\shared;
|
||||
|
||||
main()
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
debug_anim_print( "dog_jump::main()" );
|
||||
self setaimanimweights( 0, 0 );
|
||||
self.safetochangescript = 0;
|
||||
self setanimstate( "traverse_wallhop" );
|
||||
maps\mp\animscripts\shared::donotetracks( "done" );
|
||||
self.safetochangescript = 1;
|
||||
}
|
173
MP/Core/maps/mp/animscripts/dog_move.gsc
Normal file
173
MP/Core/maps/mp/animscripts/dog_move.gsc
Normal file
@ -0,0 +1,173 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\utility;
|
||||
#include maps\mp\animscripts\shared;
|
||||
#include maps\mp\animscripts\dog_stop;
|
||||
|
||||
setup_sound_variables()
|
||||
{
|
||||
level.dog_sounds["far"] = spawnstruct();
|
||||
level.dog_sounds["close"] = spawnstruct();
|
||||
level.dog_sounds["close"].minrange = 0;
|
||||
level.dog_sounds["close"].maxrange = 500;
|
||||
level.dog_sounds["close"].sound = "aml_dog_bark_close";
|
||||
level.dog_sounds["close"].soundlengthplaceholder = 0.2;
|
||||
level.dog_sounds["close"].aftersoundwaitmin = 0.1;
|
||||
level.dog_sounds["close"].aftersoundwaitmax = 0.3;
|
||||
level.dog_sounds["close"].minrangesqr = level.dog_sounds["close"].minrange * level.dog_sounds["close"].minrange;
|
||||
level.dog_sounds["close"].maxrangesqr = level.dog_sounds["close"].maxrange * level.dog_sounds["close"].maxrange;
|
||||
level.dog_sounds["far"].minrange = 500;
|
||||
level.dog_sounds["far"].maxrange = 0;
|
||||
level.dog_sounds["far"].sound = "aml_dog_bark";
|
||||
level.dog_sounds["far"].soundlengthplaceholder = 0.2;
|
||||
level.dog_sounds["far"].aftersoundwaitmin = 0.1;
|
||||
level.dog_sounds["far"].aftersoundwaitmax = 0.3;
|
||||
level.dog_sounds["far"].minrangesqr = level.dog_sounds["far"].minrange * level.dog_sounds["far"].minrange;
|
||||
level.dog_sounds["far"].maxrangesqr = level.dog_sounds["far"].maxrange * level.dog_sounds["far"].maxrange;
|
||||
}
|
||||
|
||||
main()
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
debug_anim_print( "dog_move::main()" );
|
||||
self setaimanimweights( 0, 0 );
|
||||
do_movement = 1;
|
||||
/#
|
||||
if ( !debug_allow_movement() )
|
||||
do_movement = 0;
|
||||
#/
|
||||
if ( isdefined( level.hostmigrationtimer ) )
|
||||
do_movement = 0;
|
||||
|
||||
if ( !isdefined( self.traversecomplete ) && !isdefined( self.skipstartmove ) && self.a.movement == "run" && do_movement )
|
||||
{
|
||||
self startmove();
|
||||
blendtime = 0;
|
||||
}
|
||||
else
|
||||
blendtime = 0.2;
|
||||
|
||||
self.traversecomplete = undefined;
|
||||
self.skipstartmove = undefined;
|
||||
|
||||
if ( do_movement )
|
||||
{
|
||||
if ( shouldrun() )
|
||||
{
|
||||
debug_anim_print( "dog_move::main() - Setting move_run" );
|
||||
self setanimstate( "move_run" );
|
||||
maps\mp\animscripts\shared::donotetracksfortime( 0.1, "done" );
|
||||
debug_anim_print( "dog_move::main() - move_run wait 0.1 done " );
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_anim_print( "dog_move::main() - Setting move_start " );
|
||||
self setanimstate( "move_walk" );
|
||||
maps\mp\animscripts\shared::donotetracksfortime( 0.1, "done" );
|
||||
}
|
||||
}
|
||||
|
||||
self thread maps\mp\animscripts\dog_stop::lookattarget( "normal" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self moveloop();
|
||||
|
||||
if ( self.a.movement == "run" )
|
||||
{
|
||||
if ( self.disablearrivals == 0 )
|
||||
self thread stopmove();
|
||||
|
||||
self waittill( "run" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
moveloop()
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self endon( "stop_soon" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
do_movement = 1;
|
||||
/#
|
||||
if ( !debug_allow_movement() )
|
||||
do_movement = 0;
|
||||
#/
|
||||
if ( isdefined( level.hostmigrationtimer ) )
|
||||
do_movement = 0;
|
||||
|
||||
if ( !do_movement )
|
||||
{
|
||||
self setaimanimweights( 0, 0 );
|
||||
self setanimstate( "stop_idle" );
|
||||
maps\mp\animscripts\shared::donotetracks( "done" );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( self.disablearrivals )
|
||||
self.stopanimdistsq = 0;
|
||||
else
|
||||
self.stopanimdistsq = level.dogstoppingdistsq;
|
||||
|
||||
if ( shouldrun() )
|
||||
{
|
||||
debug_anim_print( "dog_move::moveLoop() - Setting move_run" );
|
||||
self setanimstate( "move_run" );
|
||||
maps\mp\animscripts\shared::donotetracksfortime( 0.2, "done" );
|
||||
debug_anim_print( "dog_move::moveLoop() - move_run wait 0.2 done " );
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_anim_print( "dog_move::moveLoop() - Setting move_walk " );
|
||||
self setanimstate( "move_walk" );
|
||||
maps\mp\animscripts\shared::donotetracksfortime( 0.2, "done" );
|
||||
debug_anim_print( "dog_move::moveLoop() - move_walk wait 0.2 done " );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
startmove()
|
||||
{
|
||||
debug_anim_print( "dog_move::startMove() - Setting move_start " );
|
||||
self setanimstate( "move_start" );
|
||||
maps\mp\animscripts\shared::donotetracks( "done" );
|
||||
debug_anim_print( "dog_move::startMove() - move_start notify done." );
|
||||
self animmode( "none", 0 );
|
||||
self set_orient_mode( "face motion" );
|
||||
}
|
||||
|
||||
stopmove()
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self endon( "run" );
|
||||
debug_anim_print( "dog_move::stopMove() - Setting move_stop" );
|
||||
self setanimstate( "move_stop" );
|
||||
maps\mp\animscripts\shared::donotetracks( "done" );
|
||||
debug_anim_print( "dog_move::stopMove() - move_stop notify done." );
|
||||
}
|
||||
|
||||
shouldrun()
|
||||
{
|
||||
/#
|
||||
if ( getdvarint( _hash_DFB12081 ) != 0 )
|
||||
return true;
|
||||
else if ( getdvarint( _hash_D5D7999B ) != 0 )
|
||||
return false;
|
||||
#/
|
||||
if ( isdefined( self.enemy ) )
|
||||
return true;
|
||||
|
||||
if ( self.lookaheaddist <= 90 )
|
||||
return false;
|
||||
|
||||
angles = vectortoangles( self.lookaheaddir );
|
||||
yaw_desired = absangleclamp180( angles[1] );
|
||||
yaw = absangleclamp180( self.angles[1] );
|
||||
|
||||
if ( abs( yaw_desired - yaw ) >= 8 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
28
MP/Core/maps/mp/animscripts/dog_pain.gsc
Normal file
28
MP/Core/maps/mp/animscripts/dog_pain.gsc
Normal file
@ -0,0 +1,28 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\utility;
|
||||
#include maps\mp\animscripts\shared;
|
||||
|
||||
main()
|
||||
{
|
||||
debug_anim_print( "dog_pain::main() " );
|
||||
self endon( "killanimscript" );
|
||||
self setaimanimweights( 0, 0 );
|
||||
|
||||
if ( isdefined( self.enemy ) && isdefined( self.enemy.syncedmeleetarget ) && self.enemy.syncedmeleetarget == self )
|
||||
{
|
||||
self unlink();
|
||||
self.enemy.syncedmeleetarget = undefined;
|
||||
}
|
||||
|
||||
speed = length( self getvelocity() );
|
||||
pain_anim = getanimdirection( self.damageyaw );
|
||||
|
||||
if ( speed > level.dogrunpainspeed )
|
||||
pain_anim = "pain_run_" + pain_anim;
|
||||
else
|
||||
pain_anim = "pain_" + pain_anim;
|
||||
|
||||
self setanimstate( pain_anim );
|
||||
self maps\mp\animscripts\shared::donotetracksfortime( 0.2, "done" );
|
||||
}
|
127
MP/Core/maps/mp/animscripts/dog_stop.gsc
Normal file
127
MP/Core/maps/mp/animscripts/dog_stop.gsc
Normal file
@ -0,0 +1,127 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\shared;
|
||||
#include maps\mp\animscripts\utility;
|
||||
|
||||
main()
|
||||
{
|
||||
debug_anim_print( "dog_stop::main()" );
|
||||
self endon( "killanimscript" );
|
||||
self setaimanimweights( 0, 0 );
|
||||
self thread lookattarget( "attackIdle" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
if ( shouldattackidle() )
|
||||
{
|
||||
self randomattackidle();
|
||||
maps\mp\animscripts\shared::donotetracks( "done" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self set_orient_mode( "face current" );
|
||||
debug_anim_print( "dog_stop::main() - Setting stop_idle" );
|
||||
self notify( "stop tracking" );
|
||||
self setaimanimweights( 0, 0 );
|
||||
self setanimstate( "stop_idle" );
|
||||
maps\mp\animscripts\shared::donotetracks( "done" );
|
||||
self thread lookattarget( "attackIdle" );
|
||||
}
|
||||
|
||||
debug_anim_print( "dog_stop::main() - stop idle loop notify done." );
|
||||
}
|
||||
}
|
||||
|
||||
isfacingenemy( tolerancecosangle )
|
||||
{
|
||||
assert( isdefined( self.enemy ) );
|
||||
vectoenemy = self.enemy.origin - self.origin;
|
||||
disttoenemy = length( vectoenemy );
|
||||
|
||||
if ( disttoenemy < 1 )
|
||||
return 1;
|
||||
|
||||
forward = anglestoforward( self.angles );
|
||||
val1 = forward[0] * vectoenemy[0] + forward[1] * vectoenemy[1];
|
||||
val2 = ( forward[0] * vectoenemy[0] + forward[1] * vectoenemy[1] ) / disttoenemy;
|
||||
return ( forward[0] * vectoenemy[0] + forward[1] * vectoenemy[1] ) / disttoenemy > tolerancecosangle;
|
||||
}
|
||||
|
||||
randomattackidle()
|
||||
{
|
||||
if ( isfacingenemy( -0.5 ) )
|
||||
self set_orient_mode( "face current" );
|
||||
else
|
||||
self set_orient_mode( "face enemy" );
|
||||
|
||||
if ( should_growl() )
|
||||
{
|
||||
debug_anim_print( "dog_stop::main() - Setting stop_attackidle_growl" );
|
||||
self setanimstate( "stop_attackidle_growl" );
|
||||
return;
|
||||
}
|
||||
|
||||
idlechance = 33;
|
||||
barkchance = 66;
|
||||
|
||||
if ( isdefined( self.mode ) )
|
||||
{
|
||||
if ( self.mode == "growl" )
|
||||
{
|
||||
idlechance = 15;
|
||||
barkchance = 30;
|
||||
}
|
||||
else if ( self.mode == "bark" )
|
||||
{
|
||||
idlechance = 15;
|
||||
barkchance = 85;
|
||||
}
|
||||
}
|
||||
|
||||
rand = randomint( 100 );
|
||||
|
||||
if ( rand < idlechance )
|
||||
{
|
||||
debug_anim_print( "dog_stop::main() - Setting stop_attackidle" );
|
||||
self setanimstate( "stop_attackidle" );
|
||||
}
|
||||
else if ( rand < barkchance )
|
||||
{
|
||||
debug_anim_print( "dog_stop::main() - Setting stop_attackidle_bark " );
|
||||
self setanimstate( "stop_attackidle_bark" );
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_anim_print( "dog_stop::main() - Setting stop_attackidle_growl " );
|
||||
self setanimstate( "stop_attackidle_growl" );
|
||||
}
|
||||
}
|
||||
|
||||
shouldattackidle()
|
||||
{
|
||||
return isdefined( self.enemy ) && isalive( self.enemy ) && distancesquared( self.origin, self.enemy.origin ) < 1000000;
|
||||
}
|
||||
|
||||
should_growl()
|
||||
{
|
||||
if ( isdefined( self.script_growl ) )
|
||||
return 1;
|
||||
|
||||
if ( !isalive( self.enemy ) )
|
||||
return 1;
|
||||
|
||||
return !self cansee( self.enemy );
|
||||
}
|
||||
|
||||
lookattarget( lookposeset )
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self endon( "stop tracking" );
|
||||
debug_anim_print( "dog_stop::lookAtTarget() - Starting look at " + lookposeset );
|
||||
self.rightaimlimit = 90;
|
||||
self.leftaimlimit = -90;
|
||||
self.upaimlimit = 45;
|
||||
self.downaimlimit = -45;
|
||||
self maps\mp\animscripts\shared::setanimaimweight( 1, 0.2 );
|
||||
self maps\mp\animscripts\shared::trackloop();
|
||||
}
|
123
MP/Core/maps/mp/animscripts/dog_turn.gsc
Normal file
123
MP/Core/maps/mp/animscripts/dog_turn.gsc
Normal file
@ -0,0 +1,123 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\utility;
|
||||
#include maps\mp\animscripts\shared;
|
||||
|
||||
main()
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
debug_turn_print( "dog_turn::main()" );
|
||||
self setaimanimweights( 0, 0 );
|
||||
self.safetochangescript = 0;
|
||||
deltayaw = self getdeltaturnyaw();
|
||||
|
||||
if ( need_to_turn_around( deltayaw ) )
|
||||
turn_180( deltayaw );
|
||||
else
|
||||
turn_90( deltayaw );
|
||||
|
||||
move_out_of_turn();
|
||||
self.skipstartmove = 1;
|
||||
self.safetochangescript = 1;
|
||||
}
|
||||
|
||||
need_to_turn_around( deltayaw )
|
||||
{
|
||||
angle = getdvarfloat( "dog_turn180_angle" );
|
||||
|
||||
if ( deltayaw >= angle || deltayaw <= -1 * angle )
|
||||
{
|
||||
debug_turn_print( "dog_turn::need_to_turn_around(): " + deltayaw + " YES" );
|
||||
return true;
|
||||
}
|
||||
|
||||
debug_turn_print( "dog_turn::need_to_turn_around(): " + deltayaw + " NO" );
|
||||
return false;
|
||||
}
|
||||
|
||||
do_turn_anim( stopped_anim, run_anim, wait_time, run_wait_time )
|
||||
{
|
||||
speed = length( self getvelocity() );
|
||||
do_anim = stopped_anim;
|
||||
|
||||
if ( level.dogrunturnspeed < speed )
|
||||
{
|
||||
do_anim = run_anim;
|
||||
wait_time = run_wait_time;
|
||||
}
|
||||
|
||||
debug_turn_print( "dog_turn::do_turn_anim() - Setting " + do_anim );
|
||||
self setanimstate( do_anim );
|
||||
maps\mp\animscripts\shared::donotetracksfortime( run_wait_time, "done" );
|
||||
debug_turn_print( "dog_turn::do_turn_anim() - done with " + do_anim + " wait time " + run_wait_time );
|
||||
}
|
||||
|
||||
turn_left()
|
||||
{
|
||||
self do_turn_anim( "move_turn_left", "move_run_turn_left", 0.5, 0.5 );
|
||||
}
|
||||
|
||||
turn_right()
|
||||
{
|
||||
self do_turn_anim( "move_turn_right", "move_run_turn_right", 0.5, 0.5 );
|
||||
}
|
||||
|
||||
turn_180_left()
|
||||
{
|
||||
self do_turn_anim( "move_turn_around_left", "move_run_turn_around_left", 0.5, 0.7 );
|
||||
}
|
||||
|
||||
turn_180_right()
|
||||
{
|
||||
self do_turn_anim( "move_turn_around_right", "move_run_turn_around_right", 0.5, 0.7 );
|
||||
}
|
||||
|
||||
move_out_of_turn()
|
||||
{
|
||||
if ( self.a.movement == "run" )
|
||||
{
|
||||
debug_turn_print( "dog_turn::move_out_of_turn() - Setting move_run" );
|
||||
self setanimstate( "move_run" );
|
||||
maps\mp\animscripts\shared::donotetracksfortime( 0.1, "done" );
|
||||
debug_turn_print( "dog_turn::move_out_of_turn() - move_run wait 0.1 done " );
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_turn_print( "dog_turn::move_out_of_turn() - Setting move_start " );
|
||||
self setanimstate( "move_walk" );
|
||||
}
|
||||
}
|
||||
|
||||
turn_90( deltayaw )
|
||||
{
|
||||
self animmode( "zonly_physics", 0 );
|
||||
debug_turn_print( "dog_turn::turn_90() deltaYaw: " + deltayaw );
|
||||
|
||||
if ( deltayaw > 0 )
|
||||
{
|
||||
debug_turn_print( "dog_turn::turn_90() left", 1 );
|
||||
self turn_left();
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_turn_print( "dog_turn::turn_90() right", 1 );
|
||||
self turn_right();
|
||||
}
|
||||
}
|
||||
|
||||
turn_180( deltayaw )
|
||||
{
|
||||
self animmode( "zonly_physics", 0 );
|
||||
debug_turn_print( "dog_turn::turn_180() deltaYaw: " + deltayaw );
|
||||
|
||||
if ( deltayaw > 0 )
|
||||
{
|
||||
debug_turn_print( "dog_turn::turn_180() left", 1 );
|
||||
self turn_180_left();
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_turn_print( "dog_turn::turn_180() right", 1 );
|
||||
self turn_180_right();
|
||||
}
|
||||
}
|
279
MP/Core/maps/mp/animscripts/shared.gsc
Normal file
279
MP/Core/maps/mp/animscripts/shared.gsc
Normal file
@ -0,0 +1,279 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\animscripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
|
||||
handledogsoundnotetracks( note )
|
||||
{
|
||||
if ( note == "sound_dogstep_run_default" )
|
||||
return true;
|
||||
|
||||
prefix = getsubstr( note, 0, 5 );
|
||||
|
||||
if ( prefix != "sound" )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
growling()
|
||||
{
|
||||
return isdefined( self.script_growl );
|
||||
}
|
||||
|
||||
handlenotetrack( note, flagname, customfunction, var1 )
|
||||
{
|
||||
/#
|
||||
if ( getdvarint( _hash_6EBEB982 ) )
|
||||
println( "dog notetrack: " + flagname + " " + note + " " + gettime() );
|
||||
#/
|
||||
if ( isai( self ) && self.type == "dog" )
|
||||
{
|
||||
if ( handledogsoundnotetracks( note ) )
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( note )
|
||||
{
|
||||
case "undefined":
|
||||
case "finish":
|
||||
case "end":
|
||||
return note;
|
||||
default:
|
||||
if ( isdefined( customfunction ) )
|
||||
{
|
||||
if ( !isdefined( var1 ) )
|
||||
return [[ customfunction ]]( note );
|
||||
else
|
||||
return [[ customfunction ]]( note, var1 );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
donotetracks( flagname, customfunction, var1 )
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
self waittill( flagname, note );
|
||||
|
||||
if ( !isdefined( note ) )
|
||||
note = "undefined";
|
||||
|
||||
val = self handlenotetrack( note, flagname, customfunction, var1 );
|
||||
|
||||
if ( isdefined( val ) )
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
donotetracksforeverproc( notetracksfunc, flagname, killstring, customfunction, var1 )
|
||||
{
|
||||
if ( isdefined( killstring ) )
|
||||
self endon( killstring );
|
||||
|
||||
self endon( "killanimscript" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
time = gettime();
|
||||
returnednote = [[ notetracksfunc ]]( flagname, customfunction, var1 );
|
||||
timetaken = gettime() - time;
|
||||
|
||||
if ( timetaken < 0.05 )
|
||||
{
|
||||
time = gettime();
|
||||
returnednote = [[ notetracksfunc ]]( flagname, customfunction, var1 );
|
||||
timetaken = gettime() - time;
|
||||
|
||||
if ( timetaken < 0.05 )
|
||||
{
|
||||
/#
|
||||
println( gettime() + " mapsmpanimscriptsshared::DoNoteTracksForever is trying to cause an infinite loop on anim " + flagname + ", returned " + returnednote + "." );
|
||||
#/
|
||||
wait( 0.05 - timetaken );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
donotetracksforever( flagname, killstring, customfunction, var1 )
|
||||
{
|
||||
donotetracksforeverproc( ::donotetracks, flagname, killstring, customfunction, var1 );
|
||||
}
|
||||
|
||||
donotetracksfortimeproc( donotetracksforeverfunc, time, flagname, customfunction, ent, var1 )
|
||||
{
|
||||
ent endon( "stop_notetracks" );
|
||||
[[ donotetracksforeverfunc ]]( flagname, undefined, customfunction, var1 );
|
||||
}
|
||||
|
||||
donotetracksfortime( time, flagname, customfunction, var1 )
|
||||
{
|
||||
ent = spawnstruct();
|
||||
ent thread donotetracksfortimeendnotify( time );
|
||||
donotetracksfortimeproc( ::donotetracksforever, time, flagname, customfunction, ent, var1 );
|
||||
}
|
||||
|
||||
donotetracksfortimeendnotify( time )
|
||||
{
|
||||
wait( time );
|
||||
self notify( "stop_notetracks" );
|
||||
}
|
||||
|
||||
trackloop()
|
||||
{
|
||||
players = get_players();
|
||||
deltachangeperframe = 5;
|
||||
aimblendtime = 0.05;
|
||||
prevyawdelta = 0;
|
||||
prevpitchdelta = 0;
|
||||
maxyawdeltachange = 5;
|
||||
maxpitchdeltachange = 5;
|
||||
pitchadd = 0;
|
||||
yawadd = 0;
|
||||
|
||||
if ( self.type == "dog" || self.type == "zombie" || self.type == "zombie_dog" )
|
||||
{
|
||||
domaxanglecheck = 0;
|
||||
self.shootent = self.enemy;
|
||||
}
|
||||
else
|
||||
{
|
||||
domaxanglecheck = 1;
|
||||
|
||||
if ( self.a.script == "cover_crouch" && isdefined( self.a.covermode ) && self.a.covermode == "lean" )
|
||||
pitchadd = -1 * anim.covercrouchleanpitch;
|
||||
|
||||
if ( ( self.a.script == "cover_left" || self.a.script == "cover_right" ) && isdefined( self.a.cornermode ) && self.a.cornermode == "lean" )
|
||||
yawadd = self.covernode.angles[1] - self.angles[1];
|
||||
}
|
||||
|
||||
yawdelta = 0;
|
||||
pitchdelta = 0;
|
||||
firstframe = 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
incranimaimweight();
|
||||
selfshootatpos = ( self.origin[0], self.origin[1], self geteye()[2] );
|
||||
shootpos = undefined;
|
||||
|
||||
if ( isdefined( self.enemy ) )
|
||||
shootpos = self.enemy getshootatpos();
|
||||
|
||||
if ( !isdefined( shootpos ) )
|
||||
{
|
||||
yawdelta = 0;
|
||||
pitchdelta = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vectortoshootpos = shootpos - selfshootatpos;
|
||||
anglestoshootpos = vectortoangles( vectortoshootpos );
|
||||
pitchdelta = 360 - anglestoshootpos[0];
|
||||
pitchdelta = angleclamp180( pitchdelta + pitchadd );
|
||||
yawdelta = self.angles[1] - anglestoshootpos[1];
|
||||
yawdelta = angleclamp180( yawdelta + yawadd );
|
||||
}
|
||||
|
||||
if ( domaxanglecheck && ( abs( yawdelta ) > 60 || abs( pitchdelta ) > 60 ) )
|
||||
{
|
||||
yawdelta = 0;
|
||||
pitchdelta = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( yawdelta > self.rightaimlimit )
|
||||
yawdelta = self.rightaimlimit;
|
||||
else if ( yawdelta < self.leftaimlimit )
|
||||
yawdelta = self.leftaimlimit;
|
||||
|
||||
if ( pitchdelta > self.upaimlimit )
|
||||
pitchdelta = self.upaimlimit;
|
||||
else if ( pitchdelta < self.downaimlimit )
|
||||
pitchdelta = self.downaimlimit;
|
||||
}
|
||||
|
||||
if ( firstframe )
|
||||
firstframe = 0;
|
||||
else
|
||||
{
|
||||
yawdeltachange = yawdelta - prevyawdelta;
|
||||
|
||||
if ( abs( yawdeltachange ) > maxyawdeltachange )
|
||||
yawdelta = prevyawdelta + maxyawdeltachange * sign( yawdeltachange );
|
||||
|
||||
pitchdeltachange = pitchdelta - prevpitchdelta;
|
||||
|
||||
if ( abs( pitchdeltachange ) > maxpitchdeltachange )
|
||||
pitchdelta = prevpitchdelta + maxpitchdeltachange * sign( pitchdeltachange );
|
||||
}
|
||||
|
||||
prevyawdelta = yawdelta;
|
||||
prevpitchdelta = pitchdelta;
|
||||
updown = 0;
|
||||
leftright = 0;
|
||||
|
||||
if ( yawdelta > 0 )
|
||||
{
|
||||
assert( yawdelta <= self.rightaimlimit );
|
||||
weight = yawdelta / self.rightaimlimit * self.a.aimweight;
|
||||
leftright = weight;
|
||||
}
|
||||
else if ( yawdelta < 0 )
|
||||
{
|
||||
assert( yawdelta >= self.leftaimlimit );
|
||||
weight = yawdelta / self.leftaimlimit * self.a.aimweight;
|
||||
leftright = -1 * weight;
|
||||
}
|
||||
|
||||
if ( pitchdelta > 0 )
|
||||
{
|
||||
assert( pitchdelta <= self.upaimlimit );
|
||||
weight = pitchdelta / self.upaimlimit * self.a.aimweight;
|
||||
updown = weight;
|
||||
}
|
||||
else if ( pitchdelta < 0 )
|
||||
{
|
||||
assert( pitchdelta >= self.downaimlimit );
|
||||
weight = pitchdelta / self.downaimlimit * self.a.aimweight;
|
||||
updown = -1 * weight;
|
||||
}
|
||||
|
||||
self setaimanimweights( updown, leftright );
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
setanimaimweight( goalweight, goaltime )
|
||||
{
|
||||
if ( !isdefined( goaltime ) || goaltime <= 0 )
|
||||
{
|
||||
self.a.aimweight = goalweight;
|
||||
self.a.aimweight_start = goalweight;
|
||||
self.a.aimweight_end = goalweight;
|
||||
self.a.aimweight_transframes = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.a.aimweight = goalweight;
|
||||
self.a.aimweight_start = self.a.aimweight;
|
||||
self.a.aimweight_end = goalweight;
|
||||
self.a.aimweight_transframes = int( goaltime * 20 );
|
||||
}
|
||||
|
||||
self.a.aimweight_t = 0;
|
||||
}
|
||||
|
||||
incranimaimweight()
|
||||
{
|
||||
if ( self.a.aimweight_t < self.a.aimweight_transframes )
|
||||
{
|
||||
self.a.aimweight_t++;
|
||||
t = 1.0 * self.a.aimweight_t / self.a.aimweight_transframes;
|
||||
self.a.aimweight = self.a.aimweight_start * ( 1 - t ) + self.a.aimweight_end * t;
|
||||
}
|
||||
}
|
9
MP/Core/maps/mp/animscripts/traverse/jump_down_40.gsc
Normal file
9
MP/Core/maps/mp/animscripts/traverse/jump_down_40.gsc
Normal file
@ -0,0 +1,9 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\traverse\shared;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( self.type == "dog" )
|
||||
dog_jump_down( 40, 3 );
|
||||
}
|
9
MP/Core/maps/mp/animscripts/traverse/jump_down_56.gsc
Normal file
9
MP/Core/maps/mp/animscripts/traverse/jump_down_56.gsc
Normal file
@ -0,0 +1,9 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\traverse\shared;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( self.type == "dog" )
|
||||
dog_jump_down( 56, 7 );
|
||||
}
|
9
MP/Core/maps/mp/animscripts/traverse/jump_down_96.gsc
Normal file
9
MP/Core/maps/mp/animscripts/traverse/jump_down_96.gsc
Normal file
@ -0,0 +1,9 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\traverse\shared;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( self.type == "dog" )
|
||||
dog_jump_down_far( 96, 11, 0.65 );
|
||||
}
|
9
MP/Core/maps/mp/animscripts/traverse/mantle_on_40.gsc
Normal file
9
MP/Core/maps/mp/animscripts/traverse/mantle_on_40.gsc
Normal file
@ -0,0 +1,9 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\traverse\shared;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( self.type == "dog" )
|
||||
dog_jump_up( 40, 3 );
|
||||
}
|
9
MP/Core/maps/mp/animscripts/traverse/mantle_on_56.gsc
Normal file
9
MP/Core/maps/mp/animscripts/traverse/mantle_on_56.gsc
Normal file
@ -0,0 +1,9 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\traverse\shared;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( self.type == "dog" )
|
||||
dog_jump_up( 56.0, 5 );
|
||||
}
|
9
MP/Core/maps/mp/animscripts/traverse/mantle_on_80.gsc
Normal file
9
MP/Core/maps/mp/animscripts/traverse/mantle_on_80.gsc
Normal file
@ -0,0 +1,9 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\traverse\shared;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( self.type == "dog" )
|
||||
dog_jump_up_high( 80.0, 8 );
|
||||
}
|
9
MP/Core/maps/mp/animscripts/traverse/mantle_on_96.gsc
Normal file
9
MP/Core/maps/mp/animscripts/traverse/mantle_on_96.gsc
Normal file
@ -0,0 +1,9 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\traverse\shared;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( self.type == "dog" )
|
||||
dog_jump_up_high( 96.0, 9 );
|
||||
}
|
9
MP/Core/maps/mp/animscripts/traverse/mantle_over_40.gsc
Normal file
9
MP/Core/maps/mp/animscripts/traverse/mantle_over_40.gsc
Normal file
@ -0,0 +1,9 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\traverse\shared;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( self.type == "dog" )
|
||||
dog_wall_and_window_hop( "traverse_window", 40 );
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\traverse\shared;
|
||||
|
||||
main()
|
||||
{
|
||||
if ( self.type == "dog" )
|
||||
dog_wall_and_window_hop( "traverse_window", 36 );
|
||||
}
|
195
MP/Core/maps/mp/animscripts/traverse/shared.gsc
Normal file
195
MP/Core/maps/mp/animscripts/traverse/shared.gsc
Normal file
@ -0,0 +1,195 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\animscripts\shared;
|
||||
|
||||
init_traverse()
|
||||
{
|
||||
point = getent( self.target, "targetname" );
|
||||
|
||||
if ( isdefined( point ) )
|
||||
{
|
||||
self.traverse_height = point.origin[2];
|
||||
point delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
point = getstruct( self.target, "targetname" );
|
||||
|
||||
if ( isdefined( point ) )
|
||||
self.traverse_height = point.origin[2];
|
||||
}
|
||||
}
|
||||
|
||||
teleportthread( verticaloffset )
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self notify( "endTeleportThread" );
|
||||
self endon( "endTeleportThread" );
|
||||
reps = 5;
|
||||
offset = ( 0, 0, verticaloffset / reps );
|
||||
|
||||
for ( i = 0; i < reps; i++ )
|
||||
{
|
||||
self teleport( self.origin + offset );
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
teleportthreadex( verticaloffset, delay, frames )
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self notify( "endTeleportThread" );
|
||||
self endon( "endTeleportThread" );
|
||||
|
||||
if ( verticaloffset == 0 )
|
||||
return;
|
||||
|
||||
wait( delay );
|
||||
amount = verticaloffset / frames;
|
||||
|
||||
if ( amount > 10.0 )
|
||||
amount = 10.0;
|
||||
else if ( amount < -10.0 )
|
||||
amount = -10.0;
|
||||
|
||||
offset = ( 0, 0, amount );
|
||||
|
||||
for ( i = 0; i < frames; i++ )
|
||||
{
|
||||
self teleport( self.origin + offset );
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
dog_wall_and_window_hop( traversename, height )
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self traversemode( "nogravity" );
|
||||
self traversemode( "noclip" );
|
||||
startnode = self getnegotiationstartnode();
|
||||
assert( isdefined( startnode ) );
|
||||
self orientmode( "face angle", startnode.angles[1] );
|
||||
|
||||
if ( isdefined( startnode.traverse_height ) )
|
||||
{
|
||||
realheight = startnode.traverse_height - startnode.origin[2];
|
||||
self thread teleportthread( realheight - height );
|
||||
}
|
||||
else if ( height != 36.0 )
|
||||
self thread teleportthreadex( height - 36.0, 0.2, 7 );
|
||||
|
||||
debug_anim_print( "traverse::dog_wall_and_window_hop() - Setting " + traversename );
|
||||
self setanimstate( traversename );
|
||||
maps\mp\animscripts\shared::donotetracksfortime( 1.0, "done" );
|
||||
debug_anim_print( "traverse::dog_wall_and_window_hop() - " + traversename );
|
||||
self.traversecomplete = 1;
|
||||
}
|
||||
|
||||
dog_jump_down( height, frames, time )
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self traversemode( "noclip" );
|
||||
|
||||
if ( !isdefined( time ) )
|
||||
time = 0.3;
|
||||
|
||||
startnode = self getnegotiationstartnode();
|
||||
assert( isdefined( startnode ) );
|
||||
self orientmode( "face angle", startnode.angles[1] );
|
||||
|
||||
if ( isdefined( startnode.traverse_height ) )
|
||||
{
|
||||
realheight = startnode.traverse_height - startnode.origin[2];
|
||||
self thread teleportthread( realheight - height );
|
||||
}
|
||||
else if ( height != 40.0 )
|
||||
self thread teleportthreadex( height - 40.0, 0.1, frames );
|
||||
|
||||
debug_anim_print( "traverse::dog_jump_down() - Setting traverse_jump_down_40" );
|
||||
self setanimstate( "traverse_jump_down_40" );
|
||||
maps\mp\animscripts\shared::donotetracksfortime( time, "done" );
|
||||
debug_anim_print( "traverse::dog_jump_down() - traverse_jump_down_40 " );
|
||||
self traversemode( "gravity" );
|
||||
self.traversecomplete = 1;
|
||||
}
|
||||
|
||||
dog_jump_down_far( height, frames, time )
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self traversemode( "noclip" );
|
||||
|
||||
if ( !isdefined( time ) )
|
||||
time = 0.3;
|
||||
|
||||
startnode = self getnegotiationstartnode();
|
||||
assert( isdefined( startnode ) );
|
||||
self orientmode( "face angle", startnode.angles[1] );
|
||||
|
||||
if ( isdefined( startnode.traverse_height ) )
|
||||
{
|
||||
realheight = startnode.traverse_height - startnode.origin[2];
|
||||
self thread teleportthread( realheight - height );
|
||||
}
|
||||
else if ( height != 80.0 )
|
||||
self thread teleportthreadex( 80.0 - height, 0.1, frames );
|
||||
|
||||
debug_anim_print( "traverse::dog_jump_down() - Setting traverse_jump_down_80" );
|
||||
self setanimstate( "traverse_jump_down_80" );
|
||||
maps\mp\animscripts\shared::donotetracksfortime( time, "done" );
|
||||
debug_anim_print( "traverse::dog_jump_down() - traverse_jump_down_80 " );
|
||||
self traversemode( "gravity" );
|
||||
self.traversecomplete = 1;
|
||||
}
|
||||
|
||||
dog_jump_up( height, frames )
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self traversemode( "noclip" );
|
||||
startnode = self getnegotiationstartnode();
|
||||
assert( isdefined( startnode ) );
|
||||
self orientmode( "face angle", startnode.angles[1] );
|
||||
|
||||
if ( isdefined( startnode.traverse_height ) )
|
||||
{
|
||||
realheight = startnode.traverse_height - startnode.origin[2];
|
||||
self thread teleportthread( realheight - height );
|
||||
}
|
||||
else if ( height != 40.0 )
|
||||
self thread teleportthreadex( height - 40.0, 0.2, frames );
|
||||
|
||||
debug_anim_print( "traverse::dog_jump_up() - Setting traverse_jump_up_40" );
|
||||
self setanimstate( "traverse_jump_up_40" );
|
||||
maps\mp\animscripts\shared::donotetracksfortime( 0.5, "done" );
|
||||
debug_anim_print( "traverse::dog_jump_up() - traverse_jump_up_40 " );
|
||||
self traversemode( "gravity" );
|
||||
self.traversecomplete = 1;
|
||||
}
|
||||
|
||||
dog_jump_up_high( height, frames )
|
||||
{
|
||||
assert( self.type == "dog", "Only dogs can do this traverse currently." );
|
||||
self endon( "killanimscript" );
|
||||
self traversemode( "nogravity" );
|
||||
self traversemode( "noclip" );
|
||||
startnode = self getnegotiationstartnode();
|
||||
assert( isdefined( startnode ) );
|
||||
self orientmode( "face angle", startnode.angles[1] );
|
||||
|
||||
if ( isdefined( startnode.traverse_height ) )
|
||||
{
|
||||
realheight = startnode.traverse_height - startnode.origin[2];
|
||||
self thread teleportthreadex( height - 80, 0.2, frames );
|
||||
}
|
||||
else if ( height != 80.0 )
|
||||
self thread teleportthreadex( height - 80.0, 0.2, frames );
|
||||
|
||||
debug_anim_print( "traverse::dog_jump_up_80() - Setting traverse_jump_up_80" );
|
||||
self setanimstate( "traverse_jump_up_80" );
|
||||
maps\mp\animscripts\shared::donotetracksfortime( 0.6, "done" );
|
||||
debug_anim_print( "traverse::dog_jump_up_80() - traverse_jump_up_80 " );
|
||||
self traversemode( "gravity" );
|
||||
self.traversecomplete = 1;
|
||||
}
|
27
MP/Core/maps/mp/animscripts/traverse/through_hole_42.gsc
Normal file
27
MP/Core/maps/mp/animscripts/traverse/through_hole_42.gsc
Normal file
@ -0,0 +1,27 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\animscripts\traverse\shared;
|
||||
#include maps\mp\animscripts\utility;
|
||||
#include maps\mp\animscripts\shared;
|
||||
|
||||
main()
|
||||
{
|
||||
self endon( "killanimscript" );
|
||||
self traversemode( "nogravity" );
|
||||
self traversemode( "noclip" );
|
||||
startnode = self getnegotiationstartnode();
|
||||
assert( isdefined( startnode ) );
|
||||
self orientmode( "face angle", startnode.angles[1] );
|
||||
|
||||
if ( isdefined( startnode.traverse_height ) )
|
||||
{
|
||||
realheight = startnode.traverse_height - startnode.origin[2];
|
||||
self thread teleportthread( realheight );
|
||||
}
|
||||
|
||||
debug_anim_print( "traverse::through_hole()" );
|
||||
self setanimstate( "traverse_through_hole_42" );
|
||||
maps\mp\animscripts\shared::donotetracksfortime( 1.0, "done" );
|
||||
debug_anim_print( "traverse::through_hole()" );
|
||||
self.traversecomplete = 1;
|
||||
}
|
135
MP/Core/maps/mp/animscripts/utility.gsc
Normal file
135
MP/Core/maps/mp/animscripts/utility.gsc
Normal file
@ -0,0 +1,135 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
|
||||
anim_get_dvar_int( dvar, def )
|
||||
{
|
||||
return int( anim_get_dvar( dvar, def ) );
|
||||
}
|
||||
|
||||
anim_get_dvar( dvar, def )
|
||||
{
|
||||
if ( getdvar( dvar ) != "" )
|
||||
return getdvarfloat( dvar );
|
||||
else
|
||||
{
|
||||
setdvar( dvar, def );
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
set_orient_mode( mode, val1 )
|
||||
{
|
||||
/#
|
||||
if ( level.dog_debug_orient == self getentnum() )
|
||||
{
|
||||
if ( isdefined( val1 ) )
|
||||
println( "DOG: Setting orient mode: " + mode + " " + val1 + " " + gettime() );
|
||||
else
|
||||
println( "DOG: Setting orient mode: " + mode + " " + gettime() );
|
||||
}
|
||||
#/
|
||||
if ( isdefined( val1 ) )
|
||||
self orientmode( mode, val1 );
|
||||
else
|
||||
self orientmode( mode );
|
||||
}
|
||||
|
||||
debug_anim_print( text )
|
||||
{
|
||||
/#
|
||||
if ( level.dog_debug_anims )
|
||||
println( text + " " + gettime() );
|
||||
|
||||
if ( level.dog_debug_anims_ent == self getentnum() )
|
||||
println( text + " " + gettime() );
|
||||
#/
|
||||
}
|
||||
|
||||
debug_turn_print( text, line )
|
||||
{
|
||||
/#
|
||||
if ( level.dog_debug_turns == self getentnum() )
|
||||
{
|
||||
duration = 200;
|
||||
currentyawcolor = ( 1, 1, 1 );
|
||||
lookaheadyawcolor = ( 1, 0, 0 );
|
||||
desiredyawcolor = ( 1, 1, 0 );
|
||||
currentyaw = angleclamp180( self.angles[1] );
|
||||
desiredyaw = angleclamp180( self.desiredangle );
|
||||
lookaheaddir = self.lookaheaddir;
|
||||
lookaheadangles = vectortoangles( lookaheaddir );
|
||||
lookaheadyaw = angleclamp180( lookaheadangles[1] );
|
||||
println( text + " " + gettime() + " cur: " + currentyaw + " look: " + lookaheadyaw + " desired: " + desiredyaw );
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
debug_allow_movement()
|
||||
{
|
||||
/#
|
||||
return anim_get_dvar_int( "debug_dog_allow_movement", "1" );
|
||||
#/
|
||||
return 1;
|
||||
}
|
||||
|
||||
debug_allow_combat()
|
||||
{
|
||||
/#
|
||||
return anim_get_dvar_int( "debug_dog_allow_combat", "1" );
|
||||
#/
|
||||
return 1;
|
||||
}
|
||||
|
||||
current_yaw_line_debug( duration )
|
||||
{
|
||||
/#
|
||||
currentyawcolor = [];
|
||||
currentyawcolor[0] = ( 0, 0, 1 );
|
||||
currentyawcolor[1] = ( 1, 0, 1 );
|
||||
current_color_index = 0;
|
||||
start_time = gettime();
|
||||
|
||||
if ( !isdefined( level.lastdebugheight ) )
|
||||
level.lastdebugheight = 15;
|
||||
|
||||
while ( gettime() - start_time < 1000 )
|
||||
{
|
||||
pos1 = ( self.origin[0], self.origin[1], self.origin[2] + level.lastdebugheight );
|
||||
pos2 = pos1 + vectorscale( anglestoforward( self.angles ), ( current_color_index + 1 ) * 10 );
|
||||
line( pos1, pos2, currentyawcolor[current_color_index], 0.3, 1, duration );
|
||||
current_color_index = ( current_color_index + 1 ) % currentyawcolor.size;
|
||||
wait 0.05;
|
||||
}
|
||||
|
||||
if ( level.lastdebugheight == 15 )
|
||||
level.lastdebugheight = 30;
|
||||
else
|
||||
level.lastdebugheight = 15;
|
||||
#/
|
||||
}
|
||||
|
||||
getanimdirection( damageyaw )
|
||||
{
|
||||
if ( damageyaw > 135 || damageyaw <= -135 )
|
||||
return "front";
|
||||
else if ( damageyaw > 45 && damageyaw <= 135 )
|
||||
return "right";
|
||||
else if ( damageyaw > -45 && damageyaw <= 45 )
|
||||
return "back";
|
||||
else
|
||||
return "left";
|
||||
|
||||
return "front";
|
||||
}
|
||||
|
||||
setfootstepeffect( name, fx )
|
||||
{
|
||||
assert( isdefined( name ), "Need to define the footstep surface type." );
|
||||
assert( isdefined( fx ), "Need to define the mud footstep effect." );
|
||||
|
||||
if ( !isdefined( anim.optionalstepeffects ) )
|
||||
anim.optionalstepeffects = [];
|
||||
|
||||
anim.optionalstepeffects[anim.optionalstepeffects.size] = name;
|
||||
level._effect["step_" + name] = fx;
|
||||
}
|
2428
MP/Core/maps/mp/bots/_bot.gsc
Normal file
2428
MP/Core/maps/mp/bots/_bot.gsc
Normal file
File diff suppressed because it is too large
Load Diff
1705
MP/Core/maps/mp/bots/_bot_combat.gsc
Normal file
1705
MP/Core/maps/mp/bots/_bot_combat.gsc
Normal file
File diff suppressed because it is too large
Load Diff
88
MP/Core/maps/mp/bots/_bot_conf.gsc
Normal file
88
MP/Core/maps/mp/bots/_bot_conf.gsc
Normal file
@ -0,0 +1,88 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
|
||||
bot_conf_think()
|
||||
{
|
||||
time = gettime();
|
||||
|
||||
if ( time < self.bot.update_objective )
|
||||
return;
|
||||
|
||||
self.bot.update_objective = time + randomintrange( 500, 1500 );
|
||||
goal = self getgoal( "conf_dogtag" );
|
||||
|
||||
if ( isdefined( goal ) )
|
||||
{
|
||||
if ( !conf_tag_in_radius( goal, 64 ) )
|
||||
self cancelgoal( "conf_dogtag" );
|
||||
}
|
||||
|
||||
conf_get_tag_in_sight();
|
||||
}
|
||||
|
||||
conf_get_tag_in_sight()
|
||||
{
|
||||
angles = self getplayerangles();
|
||||
forward = anglestoforward( angles );
|
||||
forward = vectornormalize( forward );
|
||||
closest = 999999;
|
||||
|
||||
foreach ( tag in level.dogtags )
|
||||
{
|
||||
if ( is_true( tag.unreachable ) )
|
||||
continue;
|
||||
|
||||
distsq = distancesquared( tag.curorigin, self.origin );
|
||||
|
||||
if ( distsq > closest )
|
||||
continue;
|
||||
|
||||
delta = tag.curorigin - self.origin;
|
||||
delta = vectornormalize( delta );
|
||||
dot = vectordot( forward, delta );
|
||||
|
||||
if ( dot < self.bot.fov && distsq > 40000 )
|
||||
continue;
|
||||
|
||||
if ( dot > self.bot.fov && distsq > 1440000 )
|
||||
continue;
|
||||
|
||||
nearest = getnearestnode( tag.curorigin );
|
||||
|
||||
if ( !isdefined( nearest ) )
|
||||
{
|
||||
tag.unreachable = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( tag.curorigin[2] - nearest.origin[2] > 18 )
|
||||
{
|
||||
tag.unreachable = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !isdefined( tag.unreachable ) && !findpath( self.origin, tag.curorigin, tag, 0, 1 ) )
|
||||
tag.unreachable = 1;
|
||||
else
|
||||
tag.unreachable = 0;
|
||||
|
||||
closest = distsq;
|
||||
closetag = tag;
|
||||
}
|
||||
|
||||
if ( isdefined( closetag ) )
|
||||
self addgoal( closetag.curorigin, 16, 3, "conf_dogtag" );
|
||||
}
|
||||
|
||||
conf_tag_in_radius( origin, radius )
|
||||
{
|
||||
foreach ( tag in level.dogtags )
|
||||
{
|
||||
if ( distancesquared( origin, tag.curorigin ) < radius * radius )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
359
MP/Core/maps/mp/bots/_bot_ctf.gsc
Normal file
359
MP/Core/maps/mp/bots/_bot_ctf.gsc
Normal file
@ -0,0 +1,359 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\gametypes\ctf;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\bots\_bot;
|
||||
#include maps\mp\bots\_bot_combat;
|
||||
#include maps\mp\gametypes\_gameobjects;
|
||||
|
||||
bot_ctf_think()
|
||||
{
|
||||
time = gettime();
|
||||
|
||||
if ( time < self.bot.update_objective )
|
||||
return;
|
||||
|
||||
self.bot.update_objective = time + randomintrange( 500, 1500 );
|
||||
|
||||
if ( maps\mp\bots\_bot::bot_get_difficulty() != "easy" )
|
||||
{
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
|
||||
if ( flag_mine ishome() && distancesquared( self.origin, flag_mine.curorigin ) < 262144 )
|
||||
{
|
||||
nodes = getnodesinradius( flag_mine.curorigin, 256, 0, 64, "any", 8 );
|
||||
node = random( nodes );
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_proximity( cointoss() ? flag_mine.curorigin : node.origin );
|
||||
self maps\mp\bots\_bot_combat::bot_combat_toss_frag( cointoss() ? flag_mine.curorigin : node.origin );
|
||||
self maps\mp\bots\_bot_combat::bot_combat_toss_flash( cointoss() ? flag_mine.curorigin : node.origin );
|
||||
}
|
||||
}
|
||||
|
||||
if ( bot_should_patrol_flag() )
|
||||
{
|
||||
bot_patrol_flag();
|
||||
return;
|
||||
}
|
||||
|
||||
self cancelgoal( "ctf_flag_patrol" );
|
||||
|
||||
if ( !bot_ctf_defend() )
|
||||
bot_ctf_capture();
|
||||
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
flag_enemy = ctf_get_flag( getotherteam( self.team ) );
|
||||
home_mine = flag_mine ctf_flag_get_home();
|
||||
|
||||
if ( ctf_has_flag( flag_enemy ) && self issprinting() && distancesquared( self.origin, home_mine ) < 36864 )
|
||||
{
|
||||
if ( bot_dot_product( home_mine ) > 0.9 )
|
||||
self bot_dive_to_prone( "stand" );
|
||||
}
|
||||
else if ( !flag_mine ishome() && !isdefined( flag_mine.carrier ) )
|
||||
{
|
||||
if ( self issprinting() && distancesquared( self.origin, flag_mine.curorigin ) < 36864 )
|
||||
{
|
||||
if ( bot_dot_product( flag_mine.curorigin ) > 0.9 )
|
||||
self bot_dive_to_prone( "stand" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_should_patrol_flag()
|
||||
{
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
flag_enemy = ctf_get_flag( getotherteam( self.team ) );
|
||||
home_mine = flag_mine ctf_flag_get_home();
|
||||
|
||||
if ( self hasgoal( "ctf_flag" ) && !self atgoal( "ctf_flag" ) )
|
||||
return false;
|
||||
|
||||
if ( ctf_has_flag( flag_enemy ) )
|
||||
{
|
||||
if ( !flag_mine ishome() )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !flag_mine ishome() )
|
||||
return false;
|
||||
|
||||
if ( distancesquared( self.origin, flag_enemy.curorigin ) < 262144 )
|
||||
return false;
|
||||
|
||||
if ( bot_get_friends().size && self maps\mp\bots\_bot::bot_friend_goal_in_radius( "ctf_flag_patrol", home_mine, 1024 ) == 0 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ctf_get_flag( team )
|
||||
{
|
||||
foreach ( f in level.flags )
|
||||
{
|
||||
if ( f maps\mp\gametypes\_gameobjects::getownerteam() == team )
|
||||
return f;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
ctf_flag_get_home()
|
||||
{
|
||||
return self.trigger.baseorigin;
|
||||
}
|
||||
|
||||
ctf_has_flag( flag )
|
||||
{
|
||||
return isdefined( flag.carrier ) && flag.carrier == self;
|
||||
}
|
||||
|
||||
bot_ctf_capture()
|
||||
{
|
||||
flag_enemy = ctf_get_flag( getotherteam( self.team ) );
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
home_enemy = flag_enemy ctf_flag_get_home();
|
||||
home_mine = flag_mine ctf_flag_get_home();
|
||||
|
||||
if ( ctf_has_flag( flag_enemy ) )
|
||||
self addgoal( home_mine, 16, 4, "ctf_flag" );
|
||||
else if ( isdefined( flag_enemy.carrier ) )
|
||||
{
|
||||
if ( self atgoal( "ctf_flag" ) )
|
||||
self cancelgoal( "ctf_flag" );
|
||||
|
||||
goal = self getgoal( "ctf_flag" );
|
||||
|
||||
if ( isdefined( goal ) && distancesquared( goal, flag_enemy.carrier.origin ) < 589824 )
|
||||
return;
|
||||
|
||||
nodes = getnodesinradius( flag_enemy.carrier.origin, 512, 64, 256, "any", 8 );
|
||||
|
||||
if ( nodes.size )
|
||||
self addgoal( random( nodes ), 16, 3, "ctf_flag" );
|
||||
else
|
||||
self addgoal( flag_enemy.carrier.origin, 16, 3, "ctf_flag" );
|
||||
}
|
||||
else if ( self maps\mp\bots\_bot::bot_friend_goal_in_radius( "ctf_flag", flag_enemy.curorigin, 16 ) <= 1 )
|
||||
self addgoal( flag_enemy.curorigin, 16, 3, "ctf_flag" );
|
||||
}
|
||||
|
||||
bot_ctf_defend()
|
||||
{
|
||||
flag_enemy = ctf_get_flag( getotherteam( self.team ) );
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
home_enemy = flag_enemy ctf_flag_get_home();
|
||||
home_mine = flag_mine ctf_flag_get_home();
|
||||
|
||||
if ( flag_mine ishome() )
|
||||
return 0;
|
||||
|
||||
if ( ctf_has_flag( flag_enemy ) )
|
||||
return 0;
|
||||
|
||||
if ( !isdefined( flag_mine.carrier ) )
|
||||
{
|
||||
if ( self maps\mp\bots\_bot::bot_friend_goal_in_radius( "ctf_flag", flag_mine.curorigin, 16 ) <= 1 )
|
||||
return self bot_ctf_add_goal( flag_mine.curorigin, 4, "ctf_flag" );
|
||||
}
|
||||
else if ( !flag_enemy ishome() || distance2dsquared( self.origin, home_enemy ) > 250000 )
|
||||
return self bot_ctf_add_goal( flag_mine.curorigin, 4, "ctf_flag" );
|
||||
else if ( self maps\mp\bots\_bot::bot_friend_goal_in_radius( "ctf_flag", home_enemy, 16 ) <= 1 )
|
||||
self addgoal( home_enemy, 16, 4, "ctf_flag" );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bot_ctf_add_goal( origin, goal_priority, goal_name )
|
||||
{
|
||||
goal = undefined;
|
||||
|
||||
if ( findpath( self.origin, origin, undefined, 0, 1 ) )
|
||||
goal = origin;
|
||||
else
|
||||
{
|
||||
node = bot_ctf_random_visible_node( origin );
|
||||
|
||||
if ( isdefined( node ) )
|
||||
{
|
||||
if ( findpath( self.origin, node.origin, undefined, 0, 1 ) )
|
||||
{
|
||||
goal = node;
|
||||
self.bot.update_objective += randomintrange( 3000, 5000 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isdefined( goal ) )
|
||||
{
|
||||
self addgoal( goal, 16, goal_priority, goal_name );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_get_look_at()
|
||||
{
|
||||
enemy = self maps\mp\bots\_bot::bot_get_closest_enemy( self.origin, 1 );
|
||||
|
||||
if ( isdefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
|
||||
if ( isdefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
return node.origin;
|
||||
}
|
||||
|
||||
enemies = self maps\mp\bots\_bot::bot_get_enemies( 0 );
|
||||
|
||||
if ( enemies.size )
|
||||
enemy = random( enemies );
|
||||
|
||||
if ( isdefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
|
||||
if ( isdefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
return node.origin;
|
||||
}
|
||||
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
home_mine = flag_mine ctf_flag_get_home();
|
||||
return home_mine;
|
||||
}
|
||||
|
||||
bot_patrol_flag()
|
||||
{
|
||||
self cancelgoal( "ctf_flag" );
|
||||
flag_mine = ctf_get_flag( self.team );
|
||||
|
||||
if ( self atgoal( "ctf_flag_patrol" ) )
|
||||
{
|
||||
node = getnearestnode( self.origin );
|
||||
|
||||
if ( !isdefined( node ) )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "ctf_flag_patrol" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( node.type == "Path" )
|
||||
self setstance( "crouch" );
|
||||
else
|
||||
self setstance( "stand" );
|
||||
|
||||
if ( gettime() > self.bot.update_lookat )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
z = 20;
|
||||
|
||||
if ( distancesquared( origin, self.origin ) > 262144 )
|
||||
z = randomintrange( 16, 60 );
|
||||
|
||||
self lookat( origin + ( 0, 0, z ) );
|
||||
|
||||
if ( distancesquared( origin, self.origin ) > 65536 )
|
||||
{
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = vectorscale( dir, 256 );
|
||||
origin += dir;
|
||||
}
|
||||
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_proximity( origin );
|
||||
self.bot.update_lookat = gettime() + randomintrange( 1500, 3000 );
|
||||
}
|
||||
|
||||
goal = self getgoal( "ctf_flag_patrol" );
|
||||
nearest = base_nearest_node( flag_mine );
|
||||
mine = getnearestnode( goal );
|
||||
|
||||
if ( isdefined( mine ) && !nodesvisible( mine, nearest ) )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "ctf_flag_patrol" );
|
||||
}
|
||||
|
||||
if ( gettime() > self.bot.update_objective_patrol )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "ctf_flag_patrol" );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
nearest = base_nearest_node( flag_mine );
|
||||
|
||||
if ( self hasgoal( "ctf_flag_patrol" ) )
|
||||
{
|
||||
goal = self getgoal( "ctf_flag_patrol" );
|
||||
|
||||
if ( distancesquared( self.origin, goal ) < 65536 )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
self lookat( origin );
|
||||
}
|
||||
|
||||
if ( distancesquared( self.origin, goal ) < 16384 )
|
||||
self.bot.update_objective_patrol = gettime() + randomintrange( 3000, 6000 );
|
||||
|
||||
mine = getnearestnode( goal );
|
||||
|
||||
if ( isdefined( mine ) && !nodesvisible( mine, nearest ) )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "ctf_flag_patrol" );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( gettime() < self.bot.update_objective_patrol )
|
||||
return;
|
||||
|
||||
nodes = getvisiblenodes( nearest );
|
||||
assert( nodes.size );
|
||||
|
||||
for ( i = randomint( nodes.size ); i < nodes.size; i++ )
|
||||
{
|
||||
if ( self maps\mp\bots\_bot::bot_friend_goal_in_radius( "ctf_flag_patrol", nodes[i].origin, 256 ) == 0 )
|
||||
{
|
||||
self addgoal( nodes[i], 24, 3, "ctf_flag_patrol" );
|
||||
self.bot.update_objective_patrol = gettime() + randomintrange( 3000, 6000 );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base_nearest_node( flag )
|
||||
{
|
||||
home = flag ctf_flag_get_home();
|
||||
nodes = getnodesinradiussorted( home, 256, 0 );
|
||||
assert( nodes.size );
|
||||
return nodes[0];
|
||||
}
|
||||
|
||||
bot_ctf_random_visible_node( origin )
|
||||
{
|
||||
nodes = getnodesinradius( origin, 384, 0, 256 );
|
||||
nearest = maps\mp\bots\_bot_combat::bot_nearest_node( origin );
|
||||
|
||||
if ( isdefined( nearest ) && nodes.size )
|
||||
{
|
||||
current = randomintrange( 0, nodes.size );
|
||||
|
||||
for ( i = 0; i < nodes.size; i++ )
|
||||
{
|
||||
current = ( current + 1 ) % nodes.size;
|
||||
|
||||
if ( nodesvisible( nodes[current], nearest ) )
|
||||
return nodes[current];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
329
MP/Core/maps/mp/bots/_bot_dem.gsc
Normal file
329
MP/Core/maps/mp/bots/_bot_dem.gsc
Normal file
@ -0,0 +1,329 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\gametypes\dem;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\bots\_bot_combat;
|
||||
#include maps\mp\bots\_bot;
|
||||
|
||||
bot_dem_think()
|
||||
{
|
||||
if ( !isdefined( level.bombzones[0].dem_nodes ) )
|
||||
{
|
||||
foreach ( zone in level.bombzones )
|
||||
{
|
||||
zone.dem_nodes = [];
|
||||
zone.dem_nodes = getnodesinradius( zone.trigger.origin, 1024, 64, 128, "Path" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( self.team == game["attackers"] )
|
||||
bot_dem_attack_think();
|
||||
else
|
||||
bot_dem_defend_think();
|
||||
}
|
||||
|
||||
bot_dem_attack_think()
|
||||
{
|
||||
zones = dem_get_alive_zones();
|
||||
|
||||
if ( !zones.size )
|
||||
return;
|
||||
|
||||
if ( !isdefined( self.goal_flag ) )
|
||||
{
|
||||
zones = array_randomize( zones );
|
||||
|
||||
foreach ( zone in zones )
|
||||
{
|
||||
if ( zones.size == 1 || is_true( zone.bombplanted ) && !is_true( zone.bombexploded ) )
|
||||
{
|
||||
self.goal_flag = zone;
|
||||
break;
|
||||
}
|
||||
else if ( randomint( 100 ) < 50 )
|
||||
{
|
||||
self.goal_flag = zone;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isdefined( self.goal_flag ) )
|
||||
{
|
||||
if ( is_true( self.goal_flag.bombexploded ) )
|
||||
{
|
||||
self.goal_flag = undefined;
|
||||
self cancelgoal( "dem_guard" );
|
||||
self cancelgoal( "bomb" );
|
||||
}
|
||||
else if ( is_true( self.goal_flag.bombplanted ) )
|
||||
self bot_dem_guard( self.goal_flag, self.goal_flag.dem_nodes, self.goal_flag.trigger.origin );
|
||||
else if ( self bot_dem_friend_interacting( self.goal_flag.trigger.origin ) )
|
||||
self bot_dem_guard( self.goal_flag, self.goal_flag.dem_nodes, self.goal_flag.trigger.origin );
|
||||
else
|
||||
self bot_dem_attack( self.goal_flag );
|
||||
}
|
||||
}
|
||||
|
||||
bot_dem_defend_think()
|
||||
{
|
||||
zones = dem_get_alive_zones();
|
||||
|
||||
if ( !zones.size )
|
||||
return;
|
||||
|
||||
if ( !isdefined( self.goal_flag ) )
|
||||
{
|
||||
zones = array_randomize( zones );
|
||||
|
||||
foreach ( zone in zones )
|
||||
{
|
||||
if ( zones.size == 1 || is_true( zone.bombplanted ) && !is_true( zone.bombexploded ) )
|
||||
{
|
||||
self.goal_flag = zone;
|
||||
break;
|
||||
}
|
||||
else if ( randomint( 100 ) < 50 )
|
||||
{
|
||||
self.goal_flag = zone;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isdefined( self.goal_flag ) )
|
||||
{
|
||||
if ( is_true( self.goal_flag.bombexploded ) )
|
||||
{
|
||||
self.goal_flag = undefined;
|
||||
self cancelgoal( "dem_guard" );
|
||||
self cancelgoal( "bomb" );
|
||||
}
|
||||
else if ( is_true( self.goal_flag.bombplanted ) && !self bot_dem_friend_interacting( self.goal_flag.trigger.origin ) )
|
||||
self bot_dem_defuse( self.goal_flag );
|
||||
else
|
||||
self bot_dem_guard( self.goal_flag, self.goal_flag.dem_nodes, self.goal_flag.trigger.origin );
|
||||
}
|
||||
}
|
||||
|
||||
bot_dem_attack( zone )
|
||||
{
|
||||
self cancelgoal( "dem_guard" );
|
||||
|
||||
if ( !self hasgoal( "bomb" ) )
|
||||
{
|
||||
self.bomb_goal = self dem_get_bomb_goal( zone.visuals[0] );
|
||||
|
||||
if ( isdefined( self.bomb_goal ) )
|
||||
self addgoal( self.bomb_goal, 48, 2, "bomb" );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !self atgoal( "bomb" ) )
|
||||
{
|
||||
if ( !self maps\mp\bots\_bot_combat::bot_combat_throw_smoke( self.bomb_goal ) )
|
||||
{
|
||||
if ( !self maps\mp\bots\_bot_combat::bot_combat_throw_proximity( self.bomb_goal ) )
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_lethal( self.bomb_goal );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self addgoal( self.bomb_goal, 48, 4, "bomb" );
|
||||
self setstance( "prone" );
|
||||
self pressusebutton( level.planttime + 1 );
|
||||
wait 0.5;
|
||||
|
||||
if ( is_true( self.isplanting ) )
|
||||
wait( level.planttime + 1 );
|
||||
|
||||
self pressusebutton( 0 );
|
||||
defenders = self bot_get_enemies();
|
||||
|
||||
foreach ( defender in defenders )
|
||||
{
|
||||
if ( defender is_bot() )
|
||||
defender.goal_flag = undefined;
|
||||
}
|
||||
|
||||
self setstance( "crouch" );
|
||||
wait 0.25;
|
||||
self cancelgoal( "bomb" );
|
||||
self setstance( "stand" );
|
||||
}
|
||||
|
||||
bot_dem_guard( zone, nodes, origin )
|
||||
{
|
||||
self cancelgoal( "bomb" );
|
||||
enemy = self bot_dem_enemy_interacting( origin );
|
||||
|
||||
if ( isdefined( enemy ) )
|
||||
{
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_lethal( enemy.origin );
|
||||
self addgoal( enemy.origin, 128, 3, "dem_guard" );
|
||||
return;
|
||||
}
|
||||
|
||||
enemy = self bot_dem_enemy_nearby( origin );
|
||||
|
||||
if ( isdefined( enemy ) )
|
||||
{
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_lethal( enemy.origin );
|
||||
self addgoal( enemy.origin, 128, 3, "dem_guard" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( self hasgoal( "dem_guard" ) && !self atgoal( "dem_guard" ) )
|
||||
{
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_proximity( origin );
|
||||
return;
|
||||
}
|
||||
|
||||
node = random( nodes );
|
||||
self addgoal( node, 24, 2, "dem_guard" );
|
||||
}
|
||||
|
||||
bot_dem_defuse( zone )
|
||||
{
|
||||
self cancelgoal( "dem_guard" );
|
||||
|
||||
if ( !self hasgoal( "bomb" ) )
|
||||
{
|
||||
self.bomb_goal = self dem_get_bomb_goal( zone.visuals[0] );
|
||||
|
||||
if ( isdefined( self.bomb_goal ) )
|
||||
self addgoal( self.bomb_goal, 48, 2, "bomb" );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !self atgoal( "bomb" ) )
|
||||
{
|
||||
if ( !self maps\mp\bots\_bot_combat::bot_combat_throw_smoke( self.bomb_goal ) )
|
||||
{
|
||||
if ( !self maps\mp\bots\_bot_combat::bot_combat_throw_proximity( self.bomb_goal ) )
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_lethal( self.bomb_goal );
|
||||
}
|
||||
|
||||
if ( self.goal_flag.detonatetime - gettime() < 12000 )
|
||||
self addgoal( self.bomb_goal, 48, 4, "bomb" );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self addgoal( self.bomb_goal, 48, 4, "bomb" );
|
||||
|
||||
if ( cointoss() )
|
||||
self setstance( "crouch" );
|
||||
else
|
||||
self setstance( "prone" );
|
||||
|
||||
self pressusebutton( level.defusetime + 1 );
|
||||
wait 0.5;
|
||||
|
||||
if ( is_true( self.isdefusing ) )
|
||||
wait( level.defusetime + 1 );
|
||||
|
||||
self pressusebutton( 0 );
|
||||
self setstance( "crouch" );
|
||||
wait 0.25;
|
||||
self cancelgoal( "bomb" );
|
||||
self setstance( "stand" );
|
||||
}
|
||||
|
||||
bot_dem_enemy_interacting( origin )
|
||||
{
|
||||
enemies = maps\mp\bots\_bot::bot_get_enemies();
|
||||
|
||||
foreach ( enemy in enemies )
|
||||
{
|
||||
if ( distancesquared( enemy.origin, origin ) > 65536 )
|
||||
continue;
|
||||
|
||||
if ( is_true( enemy.isdefusing ) || is_true( enemy.isplanting ) )
|
||||
return enemy;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
bot_dem_friend_interacting( origin )
|
||||
{
|
||||
friends = maps\mp\bots\_bot::bot_get_friends();
|
||||
|
||||
foreach ( friend in friends )
|
||||
{
|
||||
if ( distancesquared( friend.origin, origin ) > 65536 )
|
||||
continue;
|
||||
|
||||
if ( is_true( friend.isdefusing ) || is_true( friend.isplanting ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_dem_enemy_nearby( origin )
|
||||
{
|
||||
enemy = maps\mp\bots\_bot::bot_get_closest_enemy( origin, 1 );
|
||||
|
||||
if ( isdefined( enemy ) )
|
||||
{
|
||||
if ( distancesquared( enemy.origin, origin ) < 1048576 )
|
||||
return enemy;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
dem_get_alive_zones()
|
||||
{
|
||||
zones = [];
|
||||
|
||||
foreach ( zone in level.bombzones )
|
||||
{
|
||||
if ( is_true( zone.bombexploded ) )
|
||||
continue;
|
||||
|
||||
zones[zones.size] = zone;
|
||||
}
|
||||
|
||||
return zones;
|
||||
}
|
||||
|
||||
dem_get_bomb_goal( ent )
|
||||
{
|
||||
if ( !isdefined( ent.bot_goals ) )
|
||||
{
|
||||
goals = [];
|
||||
ent.bot_goals = [];
|
||||
dir = anglestoforward( ent.angles );
|
||||
dir = vectorscale( dir, 32 );
|
||||
goals[0] = ent.origin + dir;
|
||||
goals[1] = ent.origin - dir;
|
||||
dir = anglestoright( ent.angles );
|
||||
dir = vectorscale( dir, 48 );
|
||||
goals[2] = ent.origin + dir;
|
||||
goals[3] = ent.origin - dir;
|
||||
|
||||
foreach ( goal in goals )
|
||||
{
|
||||
start = goal + vectorscale( ( 0, 0, 1 ), 128.0 );
|
||||
trace = bullettrace( start, goal, 0, undefined );
|
||||
ent.bot_goals[ent.bot_goals.size] = trace["position"];
|
||||
}
|
||||
}
|
||||
|
||||
goals = array_randomize( ent.bot_goals );
|
||||
|
||||
foreach ( goal in goals )
|
||||
{
|
||||
if ( findpath( self.origin, goal, 0 ) )
|
||||
return goal;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
422
MP/Core/maps/mp/bots/_bot_dom.gsc
Normal file
422
MP/Core/maps/mp/bots/_bot_dom.gsc
Normal file
@ -0,0 +1,422 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\gametypes\dom;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\bots\_bot_combat;
|
||||
#include maps\mp\bots\_bot;
|
||||
|
||||
bot_dom_think()
|
||||
{
|
||||
time = gettime();
|
||||
|
||||
if ( time < self.bot.update_objective )
|
||||
return;
|
||||
|
||||
self.bot.update_objective = time + randomintrange( 500, 1500 );
|
||||
|
||||
if ( self bot_is_capturing_flag() )
|
||||
{
|
||||
flag = self dom_get_closest_flag();
|
||||
self bot_capture_flag( flag );
|
||||
return;
|
||||
}
|
||||
|
||||
flag = self dom_get_closest_flag();
|
||||
|
||||
if ( flag getflagteam() != self.team && distance2dsquared( self.origin, flag.origin ) < 147456 && !bot_has_flag_goal( flag ) )
|
||||
{
|
||||
self bot_move_to_flag( flag );
|
||||
return;
|
||||
}
|
||||
|
||||
flag = dom_get_weighted_flag( "neutral" );
|
||||
|
||||
if ( !isdefined( flag ) )
|
||||
flag = dom_get_best_flag( self.team );
|
||||
|
||||
if ( dom_has_two_flags( self.team ) )
|
||||
flag = dom_get_best_flag( self.team );
|
||||
|
||||
if ( !isdefined( flag ) )
|
||||
return;
|
||||
|
||||
if ( !bot_has_flag_goal( flag ) && !self bot_goal_is_enemy_flag() )
|
||||
self bot_move_to_flag( flag );
|
||||
else
|
||||
{
|
||||
if ( !dom_is_game_start() )
|
||||
self bot_flag_grenade( flag );
|
||||
|
||||
if ( distancesquared( self.origin, flag.origin ) < flag.radius * flag.radius && self istouching( flag.useobj.trigger ) )
|
||||
self bot_capture_flag( flag );
|
||||
}
|
||||
}
|
||||
|
||||
bot_move_to_flag( flag )
|
||||
{
|
||||
if ( level.script == "mp_frostbite" )
|
||||
nodes = getnodesinradius( flag.origin, flag.radius, 0, 32 );
|
||||
else
|
||||
nodes = getnodesinradius( flag.origin, flag.radius, 0 );
|
||||
|
||||
assert( nodes.size );
|
||||
node = random( nodes );
|
||||
self addgoal( node, 24, 3, "dom_flag" );
|
||||
}
|
||||
|
||||
bot_is_capturing_flag()
|
||||
{
|
||||
return self atgoal( "dom_flag" );
|
||||
}
|
||||
|
||||
bot_has_flag_goal( flag )
|
||||
{
|
||||
origin = self getgoal( "dom_flag" );
|
||||
|
||||
if ( isdefined( origin ) )
|
||||
{
|
||||
if ( distancesquared( flag.origin, origin ) < flag.radius * flag.radius )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_has_no_goal()
|
||||
{
|
||||
origin = self getgoal( "dom_flag" );
|
||||
|
||||
if ( isdefined( origin ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bot_goal_is_enemy_flag()
|
||||
{
|
||||
origin = self getgoal( "dom_flag" );
|
||||
|
||||
if ( isdefined( origin ) )
|
||||
{
|
||||
foreach ( flag in level.flags )
|
||||
{
|
||||
if ( distancesquared( flag.origin, origin ) < flag.radius * flag.radius )
|
||||
{
|
||||
if ( flag getflagteam() != self.team || dom_is_flag_contested( flag ) )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_flag_grenade( flag )
|
||||
{
|
||||
if ( flag getflagteam() != self.team )
|
||||
{
|
||||
if ( bot_tactical_insertion( flag ) )
|
||||
return;
|
||||
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_smoke( flag.origin );
|
||||
}
|
||||
|
||||
if ( !dom_is_flag_contested( flag ) )
|
||||
return;
|
||||
|
||||
if ( !self maps\mp\bots\_bot_combat::bot_combat_throw_lethal( flag.origin ) )
|
||||
{
|
||||
if ( !self maps\mp\bots\_bot_combat::bot_combat_throw_tactical( flag.origin ) )
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_proximity( flag.origin );
|
||||
}
|
||||
}
|
||||
|
||||
bot_get_look_at( flag )
|
||||
{
|
||||
enemy = self maps\mp\bots\_bot::bot_get_closest_enemy( self.origin, 0 );
|
||||
|
||||
if ( isdefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
|
||||
if ( isdefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
return node.origin;
|
||||
}
|
||||
|
||||
spawn = random( level.spawn_all );
|
||||
node = getvisiblenode( self.origin, spawn.origin );
|
||||
|
||||
if ( isdefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
return node.origin;
|
||||
|
||||
return flag.origin;
|
||||
}
|
||||
|
||||
bot_capture_flag( flag )
|
||||
{
|
||||
time = gettime();
|
||||
|
||||
if ( flag getflagteam() != self.team )
|
||||
{
|
||||
if ( self getstance() == "prone" )
|
||||
self addgoal( self.origin, 24, 4, "dom_flag" );
|
||||
else
|
||||
self addgoal( self.origin, 24, 3, "dom_flag" );
|
||||
|
||||
if ( time > self.bot.update_lookat )
|
||||
{
|
||||
origin = self bot_get_look_at( flag );
|
||||
z = 20;
|
||||
|
||||
if ( distancesquared( origin, self.origin ) > 262144 )
|
||||
z = randomintrange( 16, 60 );
|
||||
|
||||
self lookat( origin + ( 0, 0, z ) );
|
||||
self.bot.update_lookat = time + randomintrange( 1500, 3000 );
|
||||
|
||||
if ( distancesquared( origin, self.origin ) > 65536 )
|
||||
{
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = vectorscale( dir, 256 );
|
||||
origin += dir;
|
||||
}
|
||||
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_proximity( origin );
|
||||
self maps\mp\bots\_bot_combat::bot_combat_toss_frag( self.origin );
|
||||
self maps\mp\bots\_bot_combat::bot_combat_toss_flash( self.origin );
|
||||
|
||||
if ( !dom_is_game_start() )
|
||||
{
|
||||
weapon = self getcurrentweapon();
|
||||
|
||||
if ( weapon == "riotshield_mp" || weapon == "minigun_mp" )
|
||||
{
|
||||
if ( cointoss() )
|
||||
{
|
||||
self addgoal( self.origin, 24, 4, "dom_flag" );
|
||||
self setstance( "crouch" );
|
||||
}
|
||||
}
|
||||
else if ( cointoss() && !bot_friend_in_radius( self.origin, 384 ) )
|
||||
{
|
||||
self addgoal( self.origin, 24, 4, "dom_flag" );
|
||||
wait( randomfloatrange( 0.5, 1 ) );
|
||||
self setstance( "prone" );
|
||||
self.bot.update_lookat += 5000;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( !dom_is_game_start() )
|
||||
{
|
||||
if ( self getstance() == "stand" )
|
||||
{
|
||||
wait( randomfloatrange( 0.5, 1 ) );
|
||||
self setstance( "crouch" );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "dom_flag" );
|
||||
|
||||
if ( self getstance() == "crouch" )
|
||||
{
|
||||
self setstance( "stand" );
|
||||
wait 0.25;
|
||||
}
|
||||
else if ( self getstance() == "prone" )
|
||||
{
|
||||
self setstance( "crouch" );
|
||||
wait 0.25;
|
||||
self setstance( "stand" );
|
||||
wait 0.25;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dom_is_game_start()
|
||||
{
|
||||
assert( isdefined( level.flags ) );
|
||||
|
||||
foreach ( flag in level.flags )
|
||||
{
|
||||
if ( flag getflagteam() != "neutral" )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
dom_get_closest_flag()
|
||||
{
|
||||
flags = arraysort( level.flags, self.origin );
|
||||
return flags[0];
|
||||
}
|
||||
|
||||
dom_get_weighted_flag( owner )
|
||||
{
|
||||
assert( isdefined( level.flags ) );
|
||||
best = undefined;
|
||||
distsq = 9999999;
|
||||
|
||||
foreach ( flag in level.flags )
|
||||
{
|
||||
if ( isdefined( owner ) && flag getflagteam() != owner )
|
||||
continue;
|
||||
|
||||
d = distancesquared( self.origin, flag.origin );
|
||||
|
||||
if ( distsq == 9999999 || d < distsq && randomint( 100 ) < 70 || randomint( 100 ) > 70 )
|
||||
{
|
||||
best = flag;
|
||||
distsq = d;
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
dom_get_weighted_enemy_flag( team )
|
||||
{
|
||||
assert( isdefined( level.flags ) );
|
||||
best = undefined;
|
||||
distsq = 9999999;
|
||||
|
||||
foreach ( flag in level.flags )
|
||||
{
|
||||
if ( flag getflagteam() == team )
|
||||
continue;
|
||||
|
||||
d = distancesquared( self.origin, flag.origin );
|
||||
|
||||
if ( distsq == 9999999 || d < distsq && randomint( 100 ) < 80 || randomint( 100 ) > 80 )
|
||||
{
|
||||
best = flag;
|
||||
distsq = d;
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
dom_is_flag_contested( flag )
|
||||
{
|
||||
enemy = self maps\mp\bots\_bot::bot_get_closest_enemy( flag.origin, 0 );
|
||||
return isdefined( enemy ) && distancesquared( enemy.origin, flag.origin ) < 147456;
|
||||
}
|
||||
|
||||
dom_has_two_flags( team )
|
||||
{
|
||||
count = 0;
|
||||
|
||||
foreach ( flag in level.flags )
|
||||
{
|
||||
if ( dom_is_flag_contested( flag ) )
|
||||
continue;
|
||||
|
||||
if ( flag getflagteam() == team )
|
||||
count++;
|
||||
}
|
||||
|
||||
return count >= 2;
|
||||
}
|
||||
|
||||
dom_get_weighted_contested_flag( team )
|
||||
{
|
||||
assert( isdefined( level.flags ) );
|
||||
best = undefined;
|
||||
distsq = 9999999;
|
||||
|
||||
foreach ( flag in level.flags )
|
||||
{
|
||||
if ( !dom_is_flag_contested( flag ) )
|
||||
continue;
|
||||
|
||||
d = distancesquared( self.origin, flag.origin );
|
||||
|
||||
if ( distsq == 9999999 || d < distsq && randomint( 100 ) < 80 || randomint( 100 ) > 80 )
|
||||
{
|
||||
best = flag;
|
||||
distsq = d;
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
dom_get_random_flag( owner )
|
||||
{
|
||||
assert( isdefined( level.flags ) );
|
||||
flagindex = randomintrange( 0, level.flags.size );
|
||||
|
||||
if ( !isdefined( owner ) )
|
||||
return level.flags[flagindex];
|
||||
|
||||
for ( i = 0; i < level.flags.size; i++ )
|
||||
{
|
||||
if ( level.flags[flagindex] getflagteam() == owner )
|
||||
return level.flags[flagindex];
|
||||
|
||||
flagindex = ( flagindex + 1 ) % level.flags.size;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
dom_get_best_flag( team )
|
||||
{
|
||||
flag1 = dom_get_weighted_enemy_flag( team );
|
||||
flag2 = dom_get_weighted_contested_flag( team );
|
||||
|
||||
if ( !isdefined( flag1 ) )
|
||||
return flag2;
|
||||
|
||||
if ( !isdefined( flag2 ) )
|
||||
return flag1;
|
||||
|
||||
offchance = randomint( 100 ) > 80;
|
||||
|
||||
if ( distancesquared( self.origin, flag1.origin ) < distancesquared( self.origin, flag2.origin ) )
|
||||
{
|
||||
if ( !offchance )
|
||||
return flag1;
|
||||
else
|
||||
return flag2;
|
||||
}
|
||||
|
||||
if ( !offchance )
|
||||
return flag2;
|
||||
else
|
||||
return flag1;
|
||||
}
|
||||
|
||||
bot_tactical_insertion( flag )
|
||||
{
|
||||
if ( self getweaponammostock( "tactical_insertion_mp" ) <= 0 )
|
||||
return 0;
|
||||
|
||||
dist = self getlookaheaddist();
|
||||
dir = self getlookaheaddir();
|
||||
|
||||
if ( !isdefined( dist ) || !isdefined( dir ) )
|
||||
return 0;
|
||||
|
||||
node = bot_nearest_node( flag.origin );
|
||||
mine = bot_nearest_node( self.origin );
|
||||
|
||||
if ( isdefined( mine ) && !nodesvisible( mine, node ) )
|
||||
{
|
||||
origin = self.origin + vectorscale( dir, dist );
|
||||
next = bot_nearest_node( origin );
|
||||
|
||||
if ( next isdangerous( self.team ) )
|
||||
return 0;
|
||||
|
||||
if ( isdefined( next ) && nodesvisible( next, node ) )
|
||||
return bot_combat_tactical_insertion( self.origin );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
177
MP/Core/maps/mp/bots/_bot_hack.gsc
Normal file
177
MP/Core/maps/mp/bots/_bot_hack.gsc
Normal file
@ -0,0 +1,177 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\gametypes\ctf;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\bots\_bot;
|
||||
|
||||
bot_hack_tank_get_goal_origin( tank )
|
||||
{
|
||||
nodes = getnodesinradiussorted( tank.origin, 256, 0, 64, "Path" );
|
||||
|
||||
foreach ( node in nodes )
|
||||
{
|
||||
dir = vectornormalize( node.origin - tank.origin );
|
||||
dir = vectorscale( dir, 32 );
|
||||
goal = tank.origin + dir;
|
||||
|
||||
if ( findpath( self.origin, goal, 0 ) )
|
||||
return goal;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
bot_hack_has_goal( tank )
|
||||
{
|
||||
goal = self getgoal( "hack" );
|
||||
|
||||
if ( isdefined( goal ) )
|
||||
{
|
||||
if ( distancesquared( goal, tank.origin ) < 16384 )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_hack_at_goal()
|
||||
{
|
||||
if ( self atgoal( "hack" ) )
|
||||
return true;
|
||||
|
||||
goal = self getgoal( "hack" );
|
||||
|
||||
if ( isdefined( goal ) )
|
||||
{
|
||||
tanks = getentarray( "talon", "targetname" );
|
||||
tanks = arraysort( tanks, self.origin );
|
||||
|
||||
foreach ( tank in tanks )
|
||||
{
|
||||
if ( distancesquared( goal, tank.origin ) < 16384 )
|
||||
{
|
||||
if ( isdefined( tank.trigger ) && self istouching( tank.trigger ) )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_hack_goal_pregame( tanks )
|
||||
{
|
||||
foreach ( tank in tanks )
|
||||
{
|
||||
if ( isdefined( tank.owner ) )
|
||||
continue;
|
||||
|
||||
if ( isdefined( tank.team ) && tank.team == self.team )
|
||||
continue;
|
||||
|
||||
goal = self bot_hack_tank_get_goal_origin( tank );
|
||||
|
||||
if ( isdefined( goal ) )
|
||||
{
|
||||
if ( self addgoal( goal, 24, 2, "hack" ) )
|
||||
{
|
||||
self.goal_flag = tank;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_hack_think()
|
||||
{
|
||||
if ( bot_hack_at_goal() )
|
||||
{
|
||||
self setstance( "crouch" );
|
||||
wait 0.25;
|
||||
self addgoal( self.origin, 24, 4, "hack" );
|
||||
self pressusebutton( level.drone_hack_time + 1 );
|
||||
wait( level.drone_hack_time + 1 );
|
||||
self setstance( "stand" );
|
||||
self cancelgoal( "hack" );
|
||||
}
|
||||
|
||||
tanks = getentarray( "talon", "targetname" );
|
||||
tanks = arraysort( tanks, self.origin );
|
||||
|
||||
if ( !is_true( level.drones_spawned ) )
|
||||
self bot_hack_goal_pregame( tanks );
|
||||
else
|
||||
{
|
||||
foreach ( tank in tanks )
|
||||
{
|
||||
if ( isdefined( tank.owner ) && tank.owner == self )
|
||||
continue;
|
||||
|
||||
if ( !isdefined( tank.owner ) )
|
||||
{
|
||||
if ( self bot_hack_has_goal( tank ) )
|
||||
return;
|
||||
|
||||
goal = self bot_hack_tank_get_goal_origin( tank );
|
||||
|
||||
if ( isdefined( goal ) )
|
||||
{
|
||||
self addgoal( goal, 24, 2, "hack" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( tank.isstunned && distancesquared( self.origin, tank.origin ) < 262144 )
|
||||
{
|
||||
goal = self bot_hack_tank_get_goal_origin( tank );
|
||||
|
||||
if ( isdefined( goal ) )
|
||||
{
|
||||
self addgoal( goal, 24, 3, "hack" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !maps\mp\bots\_bot::bot_vehicle_weapon_ammo( "emp_grenade_mp" ) )
|
||||
{
|
||||
ammo = getentarray( "weapon_scavenger_item_hack_mp", "classname" );
|
||||
ammo = arraysort( ammo, self.origin );
|
||||
|
||||
foreach ( bag in ammo )
|
||||
{
|
||||
if ( findpath( self.origin, bag.origin, 0 ) )
|
||||
{
|
||||
self addgoal( bag.origin, 24, 2, "hack" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( tank in tanks )
|
||||
{
|
||||
if ( isdefined( tank.owner ) && tank.owner == self )
|
||||
continue;
|
||||
|
||||
if ( tank.isstunned )
|
||||
continue;
|
||||
|
||||
if ( self throwgrenade( "emp_grenade_mp", tank.origin ) )
|
||||
{
|
||||
self waittill( "grenade_fire" );
|
||||
|
||||
goal = self bot_hack_tank_get_goal_origin( tank );
|
||||
|
||||
if ( isdefined( goal ) )
|
||||
{
|
||||
self addgoal( goal, 24, 3, "hack" );
|
||||
wait 0.5;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
361
MP/Core/maps/mp/bots/_bot_hq.gsc
Normal file
361
MP/Core/maps/mp/bots/_bot_hq.gsc
Normal file
@ -0,0 +1,361 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\gametypes\koth;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\bots\_bot_combat;
|
||||
#include maps\mp\bots\_bot;
|
||||
|
||||
bot_hq_think()
|
||||
{
|
||||
time = gettime();
|
||||
|
||||
if ( time < self.bot.update_objective )
|
||||
return;
|
||||
|
||||
self.bot.update_objective = time + randomintrange( 500, 1500 );
|
||||
|
||||
if ( bot_should_patrol_hq() )
|
||||
self bot_patrol_hq();
|
||||
else if ( !bot_has_hq_goal() )
|
||||
self bot_move_to_hq();
|
||||
|
||||
if ( self bot_is_capturing_hq() )
|
||||
self bot_capture_hq();
|
||||
|
||||
bot_hq_tactical_insertion();
|
||||
bot_hq_grenade();
|
||||
|
||||
if ( !bot_is_capturing_hq() && !self atgoal( "hq_patrol" ) )
|
||||
{
|
||||
mine = getnearestnode( self.origin );
|
||||
node = hq_nearest_node();
|
||||
|
||||
if ( isdefined( mine ) && nodesvisible( mine, node ) )
|
||||
self lookat( level.radio.baseorigin + vectorscale( ( 0, 0, 1 ), 30.0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
bot_has_hq_goal()
|
||||
{
|
||||
origin = self getgoal( "hq_radio" );
|
||||
|
||||
if ( isdefined( origin ) )
|
||||
{
|
||||
foreach ( node in level.radio.nodes )
|
||||
{
|
||||
if ( distancesquared( origin, node.origin ) < 4096 )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_is_capturing_hq()
|
||||
{
|
||||
return self atgoal( "hq_radio" );
|
||||
}
|
||||
|
||||
bot_should_patrol_hq()
|
||||
{
|
||||
if ( level.radio.gameobject.ownerteam == "neutral" )
|
||||
return false;
|
||||
|
||||
if ( level.radio.gameobject.ownerteam != self.team )
|
||||
return false;
|
||||
|
||||
if ( hq_is_contested() )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bot_patrol_hq()
|
||||
{
|
||||
self cancelgoal( "hq_radio" );
|
||||
|
||||
if ( self atgoal( "hq_patrol" ) )
|
||||
{
|
||||
node = getnearestnode( self.origin );
|
||||
|
||||
if ( node.type == "Path" )
|
||||
self setstance( "crouch" );
|
||||
else
|
||||
self setstance( "stand" );
|
||||
|
||||
if ( gettime() > self.bot.update_lookat )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
z = 20;
|
||||
|
||||
if ( distancesquared( origin, self.origin ) > 262144 )
|
||||
z = randomintrange( 16, 60 );
|
||||
|
||||
self lookat( origin + ( 0, 0, z ) );
|
||||
|
||||
if ( distancesquared( origin, self.origin ) > 65536 )
|
||||
{
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = vectorscale( dir, 256 );
|
||||
origin += dir;
|
||||
}
|
||||
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_proximity( origin );
|
||||
self.bot.update_lookat = gettime() + randomintrange( 1500, 3000 );
|
||||
}
|
||||
|
||||
goal = self getgoal( "hq_patrol" );
|
||||
nearest = hq_nearest_node();
|
||||
mine = getnearestnode( goal );
|
||||
|
||||
if ( isdefined( mine ) && !nodesvisible( mine, nearest ) )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "hq_patrol" );
|
||||
}
|
||||
|
||||
if ( gettime() > self.bot.update_objective_patrol )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "hq_patrol" );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
nearest = hq_nearest_node();
|
||||
|
||||
if ( self hasgoal( "hq_patrol" ) )
|
||||
{
|
||||
goal = self getgoal( "hq_patrol" );
|
||||
|
||||
if ( distancesquared( self.origin, goal ) < 65536 )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
self lookat( origin );
|
||||
}
|
||||
|
||||
if ( distancesquared( self.origin, goal ) < 16384 )
|
||||
self.bot.update_objective_patrol = gettime() + randomintrange( 3000, 6000 );
|
||||
|
||||
mine = getnearestnode( goal );
|
||||
|
||||
if ( isdefined( mine ) && !nodesvisible( mine, nearest ) )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "hq_patrol" );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
nodes = getvisiblenodes( nearest );
|
||||
assert( nodes.size );
|
||||
|
||||
for ( i = randomint( nodes.size ); i < nodes.size; i++ )
|
||||
{
|
||||
if ( self maps\mp\bots\_bot::bot_friend_goal_in_radius( "hq_radio", nodes[i].origin, 128 ) == 0 )
|
||||
{
|
||||
if ( self maps\mp\bots\_bot::bot_friend_goal_in_radius( "hq_patrol", nodes[i].origin, 256 ) == 0 )
|
||||
{
|
||||
self addgoal( nodes[i], 24, 3, "hq_patrol" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_move_to_hq()
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "hq_radio" );
|
||||
self cancelgoal( "hq_patrol" );
|
||||
|
||||
if ( self getstance() == "prone" )
|
||||
{
|
||||
self setstance( "crouch" );
|
||||
wait 0.25;
|
||||
}
|
||||
|
||||
if ( self getstance() == "crouch" )
|
||||
{
|
||||
self setstance( "stand" );
|
||||
wait 0.25;
|
||||
}
|
||||
|
||||
nodes = array_randomize( level.radio.nodes );
|
||||
|
||||
foreach ( node in nodes )
|
||||
{
|
||||
if ( self maps\mp\bots\_bot::bot_friend_goal_in_radius( "hq_radio", node.origin, 64 ) == 0 )
|
||||
{
|
||||
self addgoal( node, 24, 3, "hq_radio" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
self addgoal( random( nodes ), 24, 3, "hq_radio" );
|
||||
}
|
||||
|
||||
bot_get_look_at()
|
||||
{
|
||||
enemy = self maps\mp\bots\_bot::bot_get_closest_enemy( self.origin, 1 );
|
||||
|
||||
if ( isdefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
|
||||
if ( isdefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
return node.origin;
|
||||
}
|
||||
|
||||
enemies = self maps\mp\bots\_bot::bot_get_enemies( 0 );
|
||||
|
||||
if ( enemies.size )
|
||||
enemy = random( enemies );
|
||||
|
||||
if ( isdefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
|
||||
if ( isdefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
return node.origin;
|
||||
}
|
||||
|
||||
spawn = random( level.spawnpoints );
|
||||
node = getvisiblenode( self.origin, spawn.origin );
|
||||
|
||||
if ( isdefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
return node.origin;
|
||||
|
||||
return level.radio.baseorigin;
|
||||
}
|
||||
|
||||
bot_capture_hq()
|
||||
{
|
||||
self addgoal( self.origin, 24, 3, "hq_radio" );
|
||||
self setstance( "crouch" );
|
||||
|
||||
if ( gettime() > self.bot.update_lookat )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
z = 20;
|
||||
|
||||
if ( distancesquared( origin, self.origin ) > 262144 )
|
||||
z = randomintrange( 16, 60 );
|
||||
|
||||
self lookat( origin + ( 0, 0, z ) );
|
||||
|
||||
if ( distancesquared( origin, self.origin ) > 65536 )
|
||||
{
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = vectorscale( dir, 256 );
|
||||
origin += dir;
|
||||
}
|
||||
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_proximity( origin );
|
||||
self.bot.update_lookat = gettime() + randomintrange( 1500, 3000 );
|
||||
}
|
||||
}
|
||||
|
||||
any_other_team_touching( skip_team )
|
||||
{
|
||||
foreach ( team in level.teams )
|
||||
{
|
||||
if ( team == skip_team )
|
||||
continue;
|
||||
|
||||
if ( level.radio.gameobject.numtouching[team] )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
is_hq_contested( skip_team )
|
||||
{
|
||||
if ( any_other_team_touching( skip_team ) )
|
||||
return true;
|
||||
|
||||
enemy = self maps\mp\bots\_bot::bot_get_closest_enemy( level.radio.baseorigin, 1 );
|
||||
|
||||
if ( isdefined( enemy ) && distancesquared( enemy.origin, level.radio.baseorigin ) < 262144 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_hq_grenade()
|
||||
{
|
||||
enemies = bot_get_enemies();
|
||||
|
||||
if ( !enemies.size )
|
||||
return;
|
||||
|
||||
if ( self atgoal( "hq_patrol" ) || self atgoal( "hq_radio" ) )
|
||||
{
|
||||
if ( self getweaponammostock( "proximity_grenade_mp" ) > 0 )
|
||||
{
|
||||
origin = bot_get_look_at();
|
||||
|
||||
if ( self maps\mp\bots\_bot_combat::bot_combat_throw_proximity( origin ) )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !is_hq_contested( self.team ) )
|
||||
{
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_smoke( level.radio.baseorigin );
|
||||
return;
|
||||
}
|
||||
|
||||
enemy = self maps\mp\bots\_bot::bot_get_closest_enemy( level.radio.baseorigin, 0 );
|
||||
|
||||
if ( isdefined( enemy ) )
|
||||
origin = enemy.origin;
|
||||
else
|
||||
origin = level.radio.baseorigin;
|
||||
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = ( 0, dir[1], 0 );
|
||||
origin += vectorscale( dir, 128 );
|
||||
|
||||
if ( !self maps\mp\bots\_bot_combat::bot_combat_throw_lethal( origin ) )
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_tactical( origin );
|
||||
}
|
||||
|
||||
bot_hq_tactical_insertion()
|
||||
{
|
||||
if ( !self hasweapon( "tactical_insertion_mp" ) )
|
||||
return;
|
||||
|
||||
dist = self getlookaheaddist();
|
||||
dir = self getlookaheaddir();
|
||||
|
||||
if ( !isdefined( dist ) || !isdefined( dir ) )
|
||||
return;
|
||||
|
||||
node = hq_nearest_node();
|
||||
mine = getnearestnode( self.origin );
|
||||
|
||||
if ( isdefined( mine ) && !nodesvisible( mine, node ) )
|
||||
{
|
||||
origin = self.origin + vectorscale( dir, dist );
|
||||
next = getnearestnode( origin );
|
||||
|
||||
if ( isdefined( next ) && nodesvisible( next, node ) )
|
||||
bot_combat_tactical_insertion( self.origin );
|
||||
}
|
||||
}
|
||||
|
||||
hq_nearest_node()
|
||||
{
|
||||
return random( level.radio.nodes );
|
||||
}
|
||||
|
||||
hq_is_contested()
|
||||
{
|
||||
enemy = self maps\mp\bots\_bot::bot_get_closest_enemy( level.radio.baseorigin, 0 );
|
||||
return isdefined( enemy ) && distancesquared( enemy.origin, level.radio.baseorigin ) < level.radio.node_radius * level.radio.node_radius;
|
||||
}
|
288
MP/Core/maps/mp/bots/_bot_koth.gsc
Normal file
288
MP/Core/maps/mp/bots/_bot_koth.gsc
Normal file
@ -0,0 +1,288 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\gametypes\koth;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\bots\_bot;
|
||||
#include maps\mp\bots\_bot_combat;
|
||||
|
||||
bot_koth_think()
|
||||
{
|
||||
if ( !isdefined( level.zone.trig.goal_radius ) )
|
||||
{
|
||||
maxs = level.zone.trig getmaxs();
|
||||
maxs = level.zone.trig.origin + maxs;
|
||||
level.zone.trig.goal_radius = distance( level.zone.trig.origin, maxs );
|
||||
/#
|
||||
println( "distance: " + level.zone.trig.goal_radius );
|
||||
#/
|
||||
ground = bullettrace( level.zone.gameobject.curorigin, level.zone.gameobject.curorigin - vectorscale( ( 0, 0, 1 ), 1024.0 ), 0, undefined );
|
||||
level.zone.trig.goal = ground["position"] + vectorscale( ( 0, 0, 1 ), 8.0 );
|
||||
}
|
||||
|
||||
if ( !bot_has_hill_goal() )
|
||||
self bot_move_to_hill();
|
||||
|
||||
if ( self bot_is_at_hill() )
|
||||
self bot_capture_hill();
|
||||
|
||||
bot_hill_tactical_insertion();
|
||||
bot_hill_grenade();
|
||||
}
|
||||
|
||||
bot_has_hill_goal()
|
||||
{
|
||||
origin = self getgoal( "koth_hill" );
|
||||
|
||||
if ( isdefined( origin ) )
|
||||
{
|
||||
if ( distance2dsquared( level.zone.gameobject.curorigin, origin ) < level.zone.trig.goal_radius * level.zone.trig.goal_radius )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_is_at_hill()
|
||||
{
|
||||
return self atgoal( "koth_hill" );
|
||||
}
|
||||
|
||||
bot_move_to_hill()
|
||||
{
|
||||
if ( gettime() < self.bot.update_objective + 4000 )
|
||||
return;
|
||||
|
||||
self clearlookat();
|
||||
self cancelgoal( "koth_hill" );
|
||||
|
||||
if ( self getstance() == "prone" )
|
||||
{
|
||||
self setstance( "crouch" );
|
||||
wait 0.25;
|
||||
}
|
||||
|
||||
if ( self getstance() == "crouch" )
|
||||
{
|
||||
self setstance( "stand" );
|
||||
wait 0.25;
|
||||
}
|
||||
|
||||
nodes = getnodesinradiussorted( level.zone.trig.goal, level.zone.trig.goal_radius, 0, 128 );
|
||||
|
||||
foreach ( node in nodes )
|
||||
{
|
||||
if ( self maps\mp\bots\_bot::bot_friend_goal_in_radius( "koth_hill", node.origin, 64 ) == 0 )
|
||||
{
|
||||
if ( findpath( self.origin, node.origin, self, 0, 1 ) )
|
||||
{
|
||||
self addgoal( node, 24, 3, "koth_hill" );
|
||||
self.bot.update_objective = gettime();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_get_look_at()
|
||||
{
|
||||
enemy = self maps\mp\bots\_bot::bot_get_closest_enemy( self.origin, 1 );
|
||||
|
||||
if ( isdefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
|
||||
if ( isdefined( node ) && distancesquared( self.origin, node.origin ) > 1024 )
|
||||
return node.origin;
|
||||
}
|
||||
|
||||
enemies = self maps\mp\bots\_bot::bot_get_enemies( 0 );
|
||||
|
||||
if ( enemies.size )
|
||||
enemy = random( enemies );
|
||||
|
||||
if ( isdefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
|
||||
if ( isdefined( node ) && distancesquared( self.origin, node.origin ) > 1024 )
|
||||
return node.origin;
|
||||
}
|
||||
|
||||
spawn = random( level.spawnpoints );
|
||||
node = getvisiblenode( self.origin, spawn.origin );
|
||||
|
||||
if ( isdefined( node ) && distancesquared( self.origin, node.origin ) > 1024 )
|
||||
return node.origin;
|
||||
|
||||
return level.zone.gameobject.curorigin;
|
||||
}
|
||||
|
||||
bot_capture_hill()
|
||||
{
|
||||
self addgoal( self.origin, 24, 3, "koth_hill" );
|
||||
self setstance( "crouch" );
|
||||
|
||||
if ( gettime() > self.bot.update_lookat )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
z = 20;
|
||||
|
||||
if ( distancesquared( origin, self.origin ) > 262144 )
|
||||
z = randomintrange( 16, 60 );
|
||||
|
||||
self lookat( origin + ( 0, 0, z ) );
|
||||
|
||||
if ( distancesquared( origin, self.origin ) > 65536 )
|
||||
{
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = vectorscale( dir, 256 );
|
||||
origin += dir;
|
||||
}
|
||||
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_proximity( origin );
|
||||
|
||||
if ( cointoss() && lengthsquared( self getvelocity() ) < 2 )
|
||||
{
|
||||
nodes = getnodesinradius( level.zone.trig.goal, level.zone.trig.goal_radius + 128, 0, 128 );
|
||||
|
||||
for ( i = randomintrange( 0, nodes.size ); i < nodes.size; i++ )
|
||||
{
|
||||
node = nodes[i];
|
||||
|
||||
if ( distancesquared( node.origin, self.origin ) > 1024 )
|
||||
{
|
||||
if ( self maps\mp\bots\_bot::bot_friend_goal_in_radius( "koth_hill", node.origin, 128 ) == 0 )
|
||||
{
|
||||
if ( findpath( self.origin, node.origin, self, 0, 1 ) )
|
||||
{
|
||||
self addgoal( node, 24, 3, "koth_hill" );
|
||||
self.bot.update_objective = gettime();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.bot.update_lookat = gettime() + randomintrange( 1500, 3000 );
|
||||
}
|
||||
}
|
||||
|
||||
any_other_team_touching( skip_team )
|
||||
{
|
||||
foreach ( team in level.teams )
|
||||
{
|
||||
if ( team == skip_team )
|
||||
continue;
|
||||
|
||||
if ( level.zone.gameobject.numtouching[team] )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
is_hill_contested( skip_team )
|
||||
{
|
||||
if ( any_other_team_touching( skip_team ) )
|
||||
return true;
|
||||
|
||||
enemy = self maps\mp\bots\_bot::bot_get_closest_enemy( level.zone.gameobject.curorigin, 1 );
|
||||
|
||||
if ( isdefined( enemy ) && distancesquared( enemy.origin, level.zone.gameobject.curorigin ) < 262144 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_hill_grenade()
|
||||
{
|
||||
enemies = bot_get_enemies();
|
||||
|
||||
if ( !enemies.size )
|
||||
return;
|
||||
|
||||
if ( self atgoal( "hill_patrol" ) || self atgoal( "koth_hill" ) )
|
||||
{
|
||||
if ( self getweaponammostock( "proximity_grenade_mp" ) > 0 )
|
||||
{
|
||||
origin = bot_get_look_at();
|
||||
|
||||
if ( self maps\mp\bots\_bot_combat::bot_combat_throw_proximity( origin ) )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !is_hill_contested( self.team ) )
|
||||
{
|
||||
if ( !isdefined( level.next_smoke_time ) )
|
||||
level.next_smoke_time = 0;
|
||||
|
||||
if ( gettime() > level.next_smoke_time )
|
||||
{
|
||||
if ( self maps\mp\bots\_bot_combat::bot_combat_throw_smoke( level.zone.gameobject.curorigin ) )
|
||||
level.next_smoke_time = gettime() + randomintrange( 60000, 120000 );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
enemy = self maps\mp\bots\_bot::bot_get_closest_enemy( level.zone.gameobject.curorigin, 0 );
|
||||
|
||||
if ( isdefined( enemy ) )
|
||||
origin = enemy.origin;
|
||||
else
|
||||
origin = level.zone.gameobject.curorigin;
|
||||
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = ( 0, dir[1], 0 );
|
||||
origin += vectorscale( dir, 128 );
|
||||
|
||||
if ( maps\mp\bots\_bot::bot_get_difficulty() == "easy" )
|
||||
{
|
||||
if ( !isdefined( level.next_grenade_time ) )
|
||||
level.next_grenade_time = 0;
|
||||
|
||||
if ( gettime() > level.next_grenade_time )
|
||||
{
|
||||
if ( !self maps\mp\bots\_bot_combat::bot_combat_throw_lethal( origin ) )
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_tactical( origin );
|
||||
else
|
||||
level.next_grenade_time = gettime() + randomintrange( 60000, 120000 );
|
||||
}
|
||||
}
|
||||
else if ( !self maps\mp\bots\_bot_combat::bot_combat_throw_lethal( origin ) )
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_tactical( origin );
|
||||
}
|
||||
|
||||
bot_hill_tactical_insertion()
|
||||
{
|
||||
if ( !self hasweapon( "tactical_insertion_mp" ) )
|
||||
return;
|
||||
|
||||
dist = self getlookaheaddist();
|
||||
dir = self getlookaheaddir();
|
||||
|
||||
if ( !isdefined( dist ) || !isdefined( dir ) )
|
||||
return;
|
||||
|
||||
node = hill_nearest_node();
|
||||
mine = getnearestnode( self.origin );
|
||||
|
||||
if ( isdefined( mine ) && !nodesvisible( mine, node ) )
|
||||
{
|
||||
origin = self.origin + vectorscale( dir, dist );
|
||||
next = getnearestnode( origin );
|
||||
|
||||
if ( isdefined( next ) && nodesvisible( next, node ) )
|
||||
bot_combat_tactical_insertion( self.origin );
|
||||
}
|
||||
}
|
||||
|
||||
hill_nearest_node()
|
||||
{
|
||||
nodes = getnodesinradiussorted( level.zone.gameobject.curorigin, 256, 0 );
|
||||
assert( nodes.size );
|
||||
return nodes[0];
|
||||
}
|
556
MP/Core/maps/mp/bots/_bot_loadout.gsc
Normal file
556
MP/Core/maps/mp/bots/_bot_loadout.gsc
Normal file
@ -0,0 +1,556 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\bots\_bot;
|
||||
#include maps\mp\gametypes\_rank;
|
||||
|
||||
init()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
level.bot_banned_killstreaks = array( "KILLSTREAK_RCBOMB", "KILLSTREAK_QRDRONE", "KILLSTREAK_REMOTE_MISSILE", "KILLSTREAK_REMOTE_MORTAR", "KILLSTREAK_HELICOPTER_GUNNER" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
level waittill( "connected", player );
|
||||
|
||||
if ( !player istestclient() )
|
||||
continue;
|
||||
|
||||
player thread on_bot_connect();
|
||||
}
|
||||
}
|
||||
|
||||
on_bot_connect()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
if ( isdefined( self.pers["bot_loadout"] ) )
|
||||
return;
|
||||
|
||||
wait 0.1;
|
||||
|
||||
if ( self getentitynumber() % 2 == 0 )
|
||||
wait 0.05;
|
||||
|
||||
self maps\mp\bots\_bot::bot_set_rank();
|
||||
|
||||
if ( level.onlinegame && !sessionmodeisprivate() )
|
||||
{
|
||||
self botsetdefaultclass( 5, "class_assault" );
|
||||
self botsetdefaultclass( 6, "class_smg" );
|
||||
self botsetdefaultclass( 7, "class_lmg" );
|
||||
self botsetdefaultclass( 8, "class_cqb" );
|
||||
self botsetdefaultclass( 9, "class_sniper" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self botsetdefaultclass( 5, "class_assault" );
|
||||
self botsetdefaultclass( 6, "class_smg" );
|
||||
self botsetdefaultclass( 7, "class_lmg" );
|
||||
self botsetdefaultclass( 8, "class_cqb" );
|
||||
self botsetdefaultclass( 9, "class_sniper" );
|
||||
}
|
||||
|
||||
max_allocation = 10;
|
||||
|
||||
for ( i = 1; i <= 3; i++ )
|
||||
{
|
||||
if ( self isitemlocked( maps\mp\gametypes\_rank::getitemindex( "feature_allocation_slot_" + i ) ) )
|
||||
max_allocation--;
|
||||
}
|
||||
|
||||
self bot_construct_loadout( max_allocation );
|
||||
self.pers["bot_loadout"] = 1;
|
||||
}
|
||||
|
||||
bot_construct_loadout( allocation_max )
|
||||
{
|
||||
if ( self isitemlocked( maps\mp\gametypes\_rank::getitemindex( "feature_cac" ) ) )
|
||||
return;
|
||||
|
||||
pixbeginevent( "bot_construct_loadout" );
|
||||
item_list = bot_build_item_list();
|
||||
bot_construct_class( 0, item_list, allocation_max );
|
||||
bot_construct_class( 1, item_list, allocation_max );
|
||||
bot_construct_class( 2, item_list, allocation_max );
|
||||
bot_construct_class( 3, item_list, allocation_max );
|
||||
bot_construct_class( 4, item_list, allocation_max );
|
||||
killstreaks = item_list["killstreak1"];
|
||||
|
||||
if ( isdefined( item_list["killstreak2"] ) )
|
||||
killstreaks = arraycombine( killstreaks, item_list["killstreak2"], 1, 0 );
|
||||
|
||||
if ( isdefined( item_list["killstreak3"] ) )
|
||||
killstreaks = arraycombine( killstreaks, item_list["killstreak3"], 1, 0 );
|
||||
|
||||
if ( isdefined( killstreaks ) && killstreaks.size )
|
||||
{
|
||||
bot_choose_weapon( 0, killstreaks );
|
||||
bot_choose_weapon( 0, killstreaks );
|
||||
bot_choose_weapon( 0, killstreaks );
|
||||
}
|
||||
|
||||
self.claimed_items = undefined;
|
||||
pixendevent();
|
||||
}
|
||||
|
||||
bot_construct_class( class, items, allocation_max )
|
||||
{
|
||||
allocation = 0;
|
||||
claimed_count = bot_build_claimed_list( items );
|
||||
self.claimed_items = [];
|
||||
|
||||
while ( allocation < allocation_max )
|
||||
{
|
||||
secondary_chance = 40;
|
||||
remaining = allocation_max - allocation;
|
||||
|
||||
if ( remaining >= 1 && bot_make_choice( 95, claimed_count["primary"], 1 ) )
|
||||
{
|
||||
weapon = bot_choose_weapon( class, items["primary"] );
|
||||
claimed_count["primary"]++;
|
||||
allocation++;
|
||||
bot_choose_weapon_option( class, "camo", 0 );
|
||||
bot_choose_weapon_option( class, "reticle", 0 );
|
||||
allocation += bot_choose_primary_attachments( class, weapon, allocation, allocation_max );
|
||||
}
|
||||
else if ( !claimed_count["primary"] )
|
||||
secondary_chance = 100;
|
||||
|
||||
remaining = allocation_max - allocation;
|
||||
|
||||
if ( remaining >= 1 && bot_make_choice( secondary_chance, claimed_count["secondary"], 1 ) )
|
||||
{
|
||||
if ( remaining >= 2 && randomint( 100 ) < 10 )
|
||||
{
|
||||
self botclassadditem( class, "BONUSCARD_OVERKILL" );
|
||||
weapon = bot_choose_weapon( class, items["primary"] );
|
||||
allocation++;
|
||||
}
|
||||
else
|
||||
{
|
||||
weapon = bot_choose_weapon( class, items["secondary"] );
|
||||
bot_choose_weapon_option( class, "camo", 1 );
|
||||
}
|
||||
|
||||
allocation++;
|
||||
claimed_count["secondary"]++;
|
||||
allocation += bot_choose_secondary_attachments( class, weapon, allocation, allocation_max );
|
||||
}
|
||||
|
||||
perks_chance = 50;
|
||||
lethal_chance = 30;
|
||||
tactical_chance = 20;
|
||||
|
||||
if ( claimed_count["specialty1"] && claimed_count["specialty2"] && claimed_count["specialty3"] )
|
||||
perks_chance = 0;
|
||||
|
||||
if ( claimed_count["primarygrenade"] )
|
||||
lethal_chance = 0;
|
||||
|
||||
if ( claimed_count["specialgrenade"] )
|
||||
tactical_chance = 0;
|
||||
|
||||
if ( perks_chance + lethal_chance + tactical_chance <= 0 )
|
||||
return;
|
||||
|
||||
next_action = bot_chose_action( "perks", perks_chance, "lethal", lethal_chance, "tactical", tactical_chance, "none", 0 );
|
||||
|
||||
if ( next_action == "perks" )
|
||||
{
|
||||
remaining = allocation_max - allocation;
|
||||
|
||||
if ( remaining >= 3 && !claimed_count["specialty1"] && randomint( 100 ) < 25 )
|
||||
{
|
||||
self botclassadditem( class, "BONUSCARD_PERK_1_GREED" );
|
||||
bot_choose_weapon( class, items["specialty1"] );
|
||||
bot_choose_weapon( class, items["specialty1"] );
|
||||
claimed_count["specialty1"] = 2;
|
||||
allocation += 3;
|
||||
}
|
||||
|
||||
remaining = allocation_max - allocation;
|
||||
|
||||
if ( remaining >= 3 && !claimed_count["specialty2"] && randomint( 100 ) < 25 )
|
||||
{
|
||||
self botclassadditem( class, "BONUSCARD_PERK_2_GREED" );
|
||||
bot_choose_weapon( class, items["specialty2"] );
|
||||
bot_choose_weapon( class, items["specialty2"] );
|
||||
claimed_count["specialty2"] = 2;
|
||||
allocation += 3;
|
||||
}
|
||||
|
||||
remaining = allocation_max - allocation;
|
||||
|
||||
if ( remaining >= 3 && !claimed_count["specialty3"] && randomint( 100 ) < 25 )
|
||||
{
|
||||
self botclassadditem( class, "BONUSCARD_PERK_3_GREED" );
|
||||
bot_choose_weapon( class, items["specialty3"] );
|
||||
bot_choose_weapon( class, items["specialty3"] );
|
||||
claimed_count["specialty3"] = 2;
|
||||
allocation += 3;
|
||||
}
|
||||
|
||||
remaining = allocation_max - allocation;
|
||||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
perks = [];
|
||||
remaining = allocation_max - allocation;
|
||||
|
||||
if ( remaining > 0 )
|
||||
{
|
||||
if ( !claimed_count["specialty1"] )
|
||||
perks[perks.size] = "specialty1";
|
||||
|
||||
if ( !claimed_count["specialty2"] )
|
||||
perks[perks.size] = "specialty2";
|
||||
|
||||
if ( !claimed_count["specialty3"] )
|
||||
perks[perks.size] = "specialty3";
|
||||
|
||||
if ( perks.size )
|
||||
{
|
||||
perk = random( perks );
|
||||
bot_choose_weapon( class, items[perk] );
|
||||
claimed_count[perk]++;
|
||||
allocation++;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( next_action == "lethal" )
|
||||
{
|
||||
remaining = allocation_max - allocation;
|
||||
|
||||
if ( remaining >= 2 && randomint( 100 ) < 50 )
|
||||
{
|
||||
if ( !claimed_count["primarygrenade"] )
|
||||
{
|
||||
bot_choose_weapon( class, items["primarygrenade"] );
|
||||
claimed_count["primarygrenade"]++;
|
||||
allocation++;
|
||||
}
|
||||
|
||||
self botclassadditem( class, "BONUSCARD_DANGER_CLOSE" );
|
||||
allocation++;
|
||||
}
|
||||
else if ( remaining >= 1 && !claimed_count["primarygrenade"] )
|
||||
{
|
||||
bot_choose_weapon( class, items["primarygrenade"] );
|
||||
claimed_count["primarygrenade"]++;
|
||||
allocation++;
|
||||
}
|
||||
}
|
||||
else if ( next_action == "tactical" )
|
||||
{
|
||||
remaining = allocation_max - allocation;
|
||||
|
||||
if ( remaining >= 2 && !claimed_count["specialgrenade"] && randomint( 100 ) < 50 )
|
||||
{
|
||||
weapon = bot_choose_weapon( class, items["specialgrenade"] );
|
||||
|
||||
if ( weapon == "WEAPON_TACTICAL_INSERTION" || weapon == "WEAPON_WILLY_PETE" )
|
||||
{
|
||||
claimed_count["specialgrenade"] = 1;
|
||||
allocation += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
self botclassadditem( class, weapon );
|
||||
claimed_count["specialgrenade"] = 2;
|
||||
allocation += 2;
|
||||
}
|
||||
}
|
||||
else if ( remaining >= 1 && !claimed_count["specialgrenade"] )
|
||||
{
|
||||
bot_choose_weapon( class, items["specialgrenade"] );
|
||||
claimed_count["specialgrenade"]++;
|
||||
allocation++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_make_choice( chance, claimed, max_claim )
|
||||
{
|
||||
return claimed < max_claim && randomint( 100 ) < chance;
|
||||
}
|
||||
|
||||
bot_chose_action( action1, chance1, action2, chance2, action3, chance3, action4, chance4 )
|
||||
{
|
||||
chance1 = int( chance1 / 10 );
|
||||
chance2 = int( chance2 / 10 );
|
||||
chance3 = int( chance3 / 10 );
|
||||
chance4 = int( chance4 / 10 );
|
||||
actions = [];
|
||||
|
||||
for ( i = 0; i < chance1; i++ )
|
||||
actions[actions.size] = action1;
|
||||
|
||||
for ( i = 0; i < chance2; i++ )
|
||||
actions[actions.size] = action2;
|
||||
|
||||
for ( i = 0; i < chance3; i++ )
|
||||
actions[actions.size] = action3;
|
||||
|
||||
for ( i = 0; i < chance4; i++ )
|
||||
actions[actions.size] = action4;
|
||||
|
||||
return random( actions );
|
||||
}
|
||||
|
||||
bot_item_is_claimed( item )
|
||||
{
|
||||
foreach ( claim in self.claimed_items )
|
||||
{
|
||||
if ( claim == item )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_choose_weapon( class, items )
|
||||
{
|
||||
if ( !isdefined( items ) || !items.size )
|
||||
return undefined;
|
||||
|
||||
start = randomint( items.size );
|
||||
|
||||
for ( i = 0; i < items.size; i++ )
|
||||
{
|
||||
weapon = items[start];
|
||||
|
||||
if ( !bot_item_is_claimed( weapon ) )
|
||||
break;
|
||||
|
||||
start = ( start + 1 ) % items.size;
|
||||
}
|
||||
|
||||
self.claimed_items[self.claimed_items.size] = weapon;
|
||||
self botclassadditem( class, weapon );
|
||||
return weapon;
|
||||
}
|
||||
|
||||
bot_build_weapon_options_list( optiontype )
|
||||
{
|
||||
level.botweaponoptionsid[optiontype] = [];
|
||||
level.botweaponoptionsprob[optiontype] = [];
|
||||
prob = 0;
|
||||
|
||||
for ( row = 0; row < 255; row++ )
|
||||
{
|
||||
if ( tablelookupcolumnforrow( "mp/attachmentTable.csv", row, 1 ) == optiontype )
|
||||
{
|
||||
index = level.botweaponoptionsid[optiontype].size;
|
||||
level.botweaponoptionsid[optiontype][index] = int( tablelookupcolumnforrow( "mp/attachmentTable.csv", row, 0 ) );
|
||||
prob += int( tablelookupcolumnforrow( "mp/attachmentTable.csv", row, 15 ) );
|
||||
level.botweaponoptionsprob[optiontype][index] = prob;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_choose_weapon_option( class, optiontype, primary )
|
||||
{
|
||||
if ( !isdefined( level.botweaponoptionsid ) )
|
||||
{
|
||||
level.botweaponoptionsid = [];
|
||||
level.botweaponoptionsprob = [];
|
||||
bot_build_weapon_options_list( "camo" );
|
||||
bot_build_weapon_options_list( "reticle" );
|
||||
}
|
||||
|
||||
if ( !level.onlinegame && !level.systemlink )
|
||||
return;
|
||||
|
||||
numoptions = level.botweaponoptionsprob[optiontype].size;
|
||||
maxprob = level.botweaponoptionsprob[optiontype][numoptions - 1];
|
||||
|
||||
if ( !level.systemlink && self.pers["rank"] < 20 )
|
||||
maxprob += 4 * maxprob * ( 20 - self.pers["rank"] ) / 20;
|
||||
|
||||
rnd = randomint( int( maxprob ) );
|
||||
|
||||
for ( i = 0; i < numoptions; i++ )
|
||||
{
|
||||
if ( level.botweaponoptionsprob[optiontype][i] > rnd )
|
||||
{
|
||||
self botclasssetweaponoption( class, primary, optiontype, level.botweaponoptionsid[optiontype][i] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_choose_primary_attachments( class, weapon, allocation, allocation_max )
|
||||
{
|
||||
attachments = getweaponattachments( weapon );
|
||||
remaining = allocation_max - allocation;
|
||||
|
||||
if ( !attachments.size || !remaining )
|
||||
return 0;
|
||||
|
||||
attachment_action = bot_chose_action( "3_attachments", 25, "2_attachments", 35, "1_attachments", 35, "none", 5 );
|
||||
|
||||
if ( remaining >= 4 && attachment_action == "3_attachments" )
|
||||
{
|
||||
a1 = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a1, "primaryattachment1" );
|
||||
count = 1;
|
||||
attachments = getweaponattachments( weapon, a1 );
|
||||
|
||||
if ( attachments.size )
|
||||
{
|
||||
a2 = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a2, "primaryattachment2" );
|
||||
count++;
|
||||
attachments = getweaponattachments( weapon, a1, a2 );
|
||||
|
||||
if ( attachments.size )
|
||||
{
|
||||
a3 = random( attachments );
|
||||
self botclassadditem( class, "BONUSCARD_PRIMARY_GUNFIGHTER" );
|
||||
self botclassaddattachment( class, weapon, a3, "primaryattachment3" );
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
else if ( remaining >= 2 && attachment_action == "2_attachments" )
|
||||
{
|
||||
a1 = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a1, "primaryattachment1" );
|
||||
attachments = getweaponattachments( weapon, a1 );
|
||||
|
||||
if ( attachments.size )
|
||||
{
|
||||
a2 = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a2, "primaryattachment2" );
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
else if ( remaining >= 1 && attachment_action == "1_attachments" )
|
||||
{
|
||||
a = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a, "primaryattachment1" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_choose_secondary_attachments( class, weapon, allocation, allocation_max )
|
||||
{
|
||||
attachments = getweaponattachments( weapon );
|
||||
remaining = allocation_max - allocation;
|
||||
|
||||
if ( !attachments.size || !remaining )
|
||||
return 0;
|
||||
|
||||
attachment_action = bot_chose_action( "2_attachments", 10, "1_attachments", 40, "none", 50, "none", 0 );
|
||||
|
||||
if ( remaining >= 3 && attachment_action == "2_attachments" )
|
||||
{
|
||||
a1 = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a1, "secondaryattachment1" );
|
||||
attachments = getweaponattachments( weapon, a1 );
|
||||
|
||||
if ( attachments.size )
|
||||
{
|
||||
a2 = random( attachments );
|
||||
self botclassadditem( class, "BONUSCARD_SECONDARY_GUNFIGHTER" );
|
||||
self botclassaddattachment( class, weapon, a2, "secondaryattachment2" );
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
else if ( remaining >= 1 && attachment_action == "1_attachments" )
|
||||
{
|
||||
a = random( attachments );
|
||||
self botclassaddattachment( class, weapon, a, "secondaryattachment1" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bot_build_item_list()
|
||||
{
|
||||
pixbeginevent( "bot_build_item_list" );
|
||||
items = [];
|
||||
|
||||
for ( i = 0; i < 256; i++ )
|
||||
{
|
||||
row = tablelookuprownum( level.statstableid, 0, i );
|
||||
|
||||
if ( row > -1 )
|
||||
{
|
||||
slot = tablelookupcolumnforrow( level.statstableid, row, 13 );
|
||||
|
||||
if ( slot == "" )
|
||||
continue;
|
||||
|
||||
number = int( tablelookupcolumnforrow( level.statstableid, row, 0 ) );
|
||||
|
||||
if ( self isitemlocked( number ) )
|
||||
continue;
|
||||
|
||||
allocation = int( tablelookupcolumnforrow( level.statstableid, row, 12 ) );
|
||||
|
||||
if ( allocation < 0 )
|
||||
continue;
|
||||
|
||||
name = tablelookupcolumnforrow( level.statstableid, row, 3 );
|
||||
|
||||
if ( bot_item_is_banned( slot, name ) )
|
||||
continue;
|
||||
|
||||
if ( !isdefined( items[slot] ) )
|
||||
items[slot] = [];
|
||||
|
||||
items[slot][items[slot].size] = name;
|
||||
}
|
||||
}
|
||||
|
||||
pixendevent();
|
||||
return items;
|
||||
}
|
||||
|
||||
bot_item_is_banned( slot, item )
|
||||
{
|
||||
if ( item == "WEAPON_KNIFE_BALLISTIC" )
|
||||
return true;
|
||||
|
||||
if ( getdvarint( "tu6_enableDLCWeapons" ) == 0 && item == "WEAPON_PEACEKEEPER" )
|
||||
return true;
|
||||
|
||||
if ( slot != "killstreak1" && slot != "killstreak2" && slot != "killstreak3" )
|
||||
return false;
|
||||
|
||||
foreach ( banned in level.bot_banned_killstreaks )
|
||||
{
|
||||
if ( item == banned )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bot_build_claimed_list( items )
|
||||
{
|
||||
claimed = [];
|
||||
keys = getarraykeys( items );
|
||||
|
||||
foreach ( key in keys )
|
||||
claimed[key] = 0;
|
||||
|
||||
return claimed;
|
||||
}
|
440
MP/Core/maps/mp/bots/_bot_sd.gsc
Normal file
440
MP/Core/maps/mp/bots/_bot_sd.gsc
Normal file
@ -0,0 +1,440 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_gameobjects;
|
||||
#include maps\mp\bots\_bot;
|
||||
#include maps\mp\bots\_bot_combat;
|
||||
#include maps\mp\gametypes\_globallogic_utils;
|
||||
|
||||
bot_sd_think()
|
||||
{
|
||||
foreach ( zone in level.bombzones )
|
||||
{
|
||||
if ( !isdefined( zone.nearest_node ) )
|
||||
{
|
||||
nodes = getnodesinradiussorted( zone.trigger.origin, 256, 0 );
|
||||
assert( nodes.size );
|
||||
zone.nearest_node = nodes[0];
|
||||
}
|
||||
}
|
||||
|
||||
zone = sd_get_planted_zone();
|
||||
|
||||
if ( isdefined( zone ) )
|
||||
self bot_sd_defender( zone, 1 );
|
||||
else if ( self.team == game["attackers"] )
|
||||
{
|
||||
if ( level.multibomb )
|
||||
self.isbombcarrier = 1;
|
||||
|
||||
self bot_sd_attacker();
|
||||
}
|
||||
else
|
||||
{
|
||||
zone = random( level.bombzones );
|
||||
self bot_sd_defender( zone );
|
||||
}
|
||||
}
|
||||
|
||||
bot_sd_attacker()
|
||||
{
|
||||
level endon( "game_ended" );
|
||||
|
||||
if ( !level.multibomb && !isdefined( level.sdbomb.carrier ) && !level.bombplanted )
|
||||
{
|
||||
self cancelgoal( "sd_protect_carrier" );
|
||||
|
||||
if ( !level.sdbomb maps\mp\gametypes\_gameobjects::isobjectawayfromhome() )
|
||||
{
|
||||
if ( !self maps\mp\bots\_bot::bot_friend_goal_in_radius( "sd_pickup", level.sdbomb.curorigin, 64 ) )
|
||||
{
|
||||
self addgoal( level.sdbomb.curorigin, 16, 4, "sd_pickup" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self addgoal( level.sdbomb.curorigin, 16, 4, "sd_pickup" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
self cancelgoal( "sd_pickup" );
|
||||
|
||||
if ( is_true( self.isbombcarrier ) )
|
||||
{
|
||||
goal = self getgoal( "sd_plant" );
|
||||
|
||||
if ( isdefined( goal ) )
|
||||
{
|
||||
if ( distancesquared( self.origin, goal ) < 2304 )
|
||||
{
|
||||
self setstance( "prone" );
|
||||
wait 0.5;
|
||||
self pressusebutton( level.planttime + 1 );
|
||||
wait 0.5;
|
||||
|
||||
if ( is_true( self.isplanting ) )
|
||||
wait( level.planttime + 1 );
|
||||
|
||||
self pressusebutton( 0 );
|
||||
self setstance( "crouch" );
|
||||
wait 0.25;
|
||||
self cancelgoal( "sd_plant" );
|
||||
self setstance( "stand" );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if ( gettime() > self.bot["patrol_update"] )
|
||||
{
|
||||
frac = sd_get_time_frac();
|
||||
|
||||
if ( randomint( 100 ) < frac * 100 || frac > 0.85 )
|
||||
{
|
||||
zone = sd_get_closest_bomb();
|
||||
goal = sd_get_bomb_goal( zone.visuals[0] );
|
||||
|
||||
if ( isdefined( goal ) )
|
||||
{
|
||||
if ( frac > 0.85 )
|
||||
self addgoal( goal, 24, 4, "sd_plant" );
|
||||
else
|
||||
self addgoal( goal, 24, 3, "sd_plant" );
|
||||
}
|
||||
}
|
||||
|
||||
self.bot["patrol_update"] = gettime() + randomintrange( 2500, 5000 );
|
||||
}
|
||||
}
|
||||
else if ( isdefined( level.sdbomb.carrier ) && !isplayer( level.sdbomb.carrier ) )
|
||||
{
|
||||
if ( !isdefined( self.protectcarrier ) )
|
||||
{
|
||||
if ( randomint( 100 ) > 70 )
|
||||
self.protectcarrier = 1;
|
||||
else
|
||||
self.protectcarrier = 0;
|
||||
}
|
||||
|
||||
if ( self.protectcarrier )
|
||||
{
|
||||
goal = level.sdbomb.carrier getgoal( "sd_plant" );
|
||||
|
||||
if ( isdefined( goal ) )
|
||||
{
|
||||
nodes = getnodesinradiussorted( goal, 256, 0 );
|
||||
|
||||
if ( isdefined( nodes ) && nodes.size > 0 && !isdefined( self getgoal( "sd_protect_carrier" ) ) )
|
||||
self addgoal( nodes[randomint( nodes.size )], 24, 3, "sd_protect_carrier" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bot_sd_defender( zone, isplanted )
|
||||
{
|
||||
bot_sd_grenade();
|
||||
|
||||
if ( isdefined( isplanted ) && isplanted && self hasgoal( "sd_defend" ) )
|
||||
{
|
||||
goal = self getgoal( "sd_defend" );
|
||||
planted = sd_get_planted_zone();
|
||||
|
||||
foreach ( zone in level.bombzones )
|
||||
{
|
||||
if ( planted != zone && distance2d( goal, zone.nearest_node.origin ) < distance2d( goal, planted.nearest_node.origin ) )
|
||||
self cancelgoal( "sd_defend" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( self atgoal( "sd_defend" ) || self bot_need_to_defuse() )
|
||||
{
|
||||
bot_sd_defender_think( zone );
|
||||
|
||||
if ( self hasgoal( "sd_defend" ) )
|
||||
return;
|
||||
}
|
||||
|
||||
if ( self hasgoal( "enemy_patrol" ) )
|
||||
{
|
||||
goal = self getgoal( "enemy_patrol" );
|
||||
closezone = sd_get_closest_bomb();
|
||||
|
||||
if ( distancesquared( goal, closezone.nearest_node.origin ) < 262144 )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "sd_defend" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( self hasgoal( "sd_defend" ) )
|
||||
{
|
||||
self.bot["patrol_update"] = gettime() + randomintrange( 2500, 5000 );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( self hasgoal( "enemy_patrol" ) )
|
||||
return;
|
||||
|
||||
nodes = getvisiblenodes( zone.nearest_node );
|
||||
best = undefined;
|
||||
highest = -100;
|
||||
|
||||
foreach ( node in nodes )
|
||||
{
|
||||
if ( node.type == "BAD NODE" )
|
||||
continue;
|
||||
|
||||
if ( !canclaimnode( node, self.team ) )
|
||||
continue;
|
||||
|
||||
if ( distancesquared( node.origin, self.origin ) < 65536 )
|
||||
continue;
|
||||
|
||||
if ( self maps\mp\bots\_bot::bot_friend_goal_in_radius( "sd_defend", node.origin, 256 ) > 0 )
|
||||
continue;
|
||||
|
||||
height = node.origin[2] - zone.nearest_node.origin[2];
|
||||
|
||||
if ( isdefined( isplanted ) && isplanted )
|
||||
{
|
||||
dist = distance2d( node.origin, zone.nearest_node.origin );
|
||||
score = 10000 - dist + height;
|
||||
}
|
||||
else
|
||||
score = height;
|
||||
|
||||
if ( score > highest )
|
||||
{
|
||||
highest = score;
|
||||
best = node;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !isdefined( best ) )
|
||||
return;
|
||||
|
||||
self addgoal( best, 24, 3, "sd_defend" );
|
||||
}
|
||||
|
||||
bot_get_look_at()
|
||||
{
|
||||
enemy = self maps\mp\bots\_bot::bot_get_closest_enemy( self.origin, 1 );
|
||||
|
||||
if ( isdefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
|
||||
if ( isdefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
return node.origin;
|
||||
}
|
||||
|
||||
enemies = self maps\mp\bots\_bot::bot_get_enemies( 0 );
|
||||
|
||||
if ( enemies.size )
|
||||
enemy = random( enemies );
|
||||
|
||||
if ( isdefined( enemy ) )
|
||||
{
|
||||
node = getvisiblenode( self.origin, enemy.origin );
|
||||
|
||||
if ( isdefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
return node.origin;
|
||||
}
|
||||
|
||||
zone = sd_get_closest_bomb();
|
||||
node = getvisiblenode( self.origin, zone.nearest_node.origin );
|
||||
|
||||
if ( isdefined( node ) && distancesquared( self.origin, node.origin ) > 16384 )
|
||||
return node.origin;
|
||||
|
||||
forward = anglestoforward( self getplayerangles() );
|
||||
origin = self geteye() + forward * 1024;
|
||||
return origin;
|
||||
}
|
||||
|
||||
bot_sd_defender_think( zone )
|
||||
{
|
||||
if ( self bot_need_to_defuse() )
|
||||
{
|
||||
if ( self maps\mp\bots\_bot::bot_friend_goal_in_radius( "sd_defuse", level.sdbombmodel.origin, 16 ) > 0 )
|
||||
return;
|
||||
|
||||
self clearlookat();
|
||||
goal = self getgoal( "sd_defuse" );
|
||||
|
||||
if ( isdefined( goal ) && distancesquared( self.origin, goal ) < 2304 )
|
||||
{
|
||||
self setstance( "prone" );
|
||||
wait 0.5;
|
||||
self pressusebutton( level.defusetime + 1 );
|
||||
wait 0.5;
|
||||
|
||||
if ( is_true( self.isdefusing ) )
|
||||
wait( level.defusetime + 1 );
|
||||
|
||||
self pressusebutton( 0 );
|
||||
self setstance( "crouch" );
|
||||
wait 0.25;
|
||||
self cancelgoal( "sd_defuse" );
|
||||
self setstance( "stand" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !isdefined( goal ) && distance2dsquared( self.origin, level.sdbombmodel.origin ) < 1000000 )
|
||||
self addgoal( level.sdbombmodel.origin, 24, 4, "sd_defuse" );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( gettime() > self.bot["patrol_update"] )
|
||||
{
|
||||
if ( cointoss() )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "sd_defend" );
|
||||
return;
|
||||
}
|
||||
|
||||
self.bot["patrol_update"] = gettime() + randomintrange( 2500, 5000 );
|
||||
}
|
||||
|
||||
if ( self hasgoal( "enemy_patrol" ) )
|
||||
{
|
||||
goal = self getgoal( "enemy_patrol" );
|
||||
zone = sd_get_closest_bomb();
|
||||
|
||||
if ( distancesquared( goal, zone.nearest_node.origin ) < 262144 )
|
||||
{
|
||||
self clearlookat();
|
||||
self cancelgoal( "sd_defend" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( gettime() > self.bot["lookat_update"] )
|
||||
{
|
||||
origin = self bot_get_look_at();
|
||||
z = 20;
|
||||
|
||||
if ( distancesquared( origin, self.origin ) > 262144 )
|
||||
z = randomintrange( 16, 60 );
|
||||
|
||||
self lookat( origin + ( 0, 0, z ) );
|
||||
self.bot["lookat_update"] = gettime() + randomintrange( 1500, 3000 );
|
||||
|
||||
if ( distancesquared( origin, self.origin ) > 65536 )
|
||||
{
|
||||
dir = vectornormalize( self.origin - origin );
|
||||
dir = vectorscale( dir, 256 );
|
||||
origin += dir;
|
||||
}
|
||||
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_proximity( origin );
|
||||
}
|
||||
}
|
||||
|
||||
bot_need_to_defuse()
|
||||
{
|
||||
return level.bombplanted && self.team == game["defenders"];
|
||||
}
|
||||
|
||||
sd_get_bomb_goal( ent )
|
||||
{
|
||||
goals = [];
|
||||
dir = anglestoforward( ent.angles );
|
||||
dir = vectorscale( dir, 32 );
|
||||
goals[0] = ent.origin + dir;
|
||||
goals[1] = ent.origin - dir;
|
||||
dir = anglestoright( ent.angles );
|
||||
dir = vectorscale( dir, 48 );
|
||||
goals[2] = ent.origin + dir;
|
||||
goals[3] = ent.origin - dir;
|
||||
goals = array_randomize( goals );
|
||||
|
||||
foreach ( goal in goals )
|
||||
{
|
||||
if ( findpath( self.origin, goal, 0 ) )
|
||||
return goal;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
sd_get_time_frac()
|
||||
{
|
||||
remaining = maps\mp\gametypes\_globallogic_utils::gettimeremaining();
|
||||
end = level.timelimit * 60 * 1000;
|
||||
|
||||
if ( end == 0 )
|
||||
{
|
||||
end = self.spawntime + 120000;
|
||||
remaining = end - gettime();
|
||||
}
|
||||
|
||||
return 1 - remaining / end;
|
||||
}
|
||||
|
||||
sd_get_closest_bomb()
|
||||
{
|
||||
best = undefined;
|
||||
distsq = 9999999;
|
||||
|
||||
foreach ( zone in level.bombzones )
|
||||
{
|
||||
d = distancesquared( self.origin, zone.curorigin );
|
||||
|
||||
if ( !isdefined( best ) )
|
||||
{
|
||||
best = zone;
|
||||
distsq = d;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( d < distsq )
|
||||
{
|
||||
best = zone;
|
||||
distsq = d;
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
sd_get_planted_zone()
|
||||
{
|
||||
if ( level.bombplanted )
|
||||
{
|
||||
foreach ( zone in level.bombzones )
|
||||
{
|
||||
if ( zone.interactteam == "none" )
|
||||
return zone;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
bot_sd_grenade()
|
||||
{
|
||||
enemies = bot_get_enemies();
|
||||
|
||||
if ( !enemies.size )
|
||||
return;
|
||||
|
||||
zone = sd_get_closest_bomb();
|
||||
|
||||
foreach ( enemy in enemies )
|
||||
{
|
||||
if ( distancesquared( enemy.origin, zone.nearest_node.origin ) < 147456 )
|
||||
{
|
||||
if ( !self maps\mp\bots\_bot_combat::bot_combat_throw_lethal( enemy.origin ) )
|
||||
self maps\mp\bots\_bot_combat::bot_combat_throw_tactical( enemy.origin );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
1135
MP/Core/maps/mp/gametypes/_battlechatter_mp.gsc
Normal file
1135
MP/Core/maps/mp/gametypes/_battlechatter_mp.gsc
Normal file
File diff suppressed because it is too large
Load Diff
210
MP/Core/maps/mp/gametypes/_callbacksetup.gsc
Normal file
210
MP/Core/maps/mp/gametypes/_callbacksetup.gsc
Normal file
@ -0,0 +1,210 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\_audio;
|
||||
#include maps\mp\gametypes\_globallogic;
|
||||
#include maps\mp\gametypes\_globallogic_player;
|
||||
#include maps\mp\gametypes\_globallogic_actor;
|
||||
#include maps\mp\gametypes\_globallogic_vehicle;
|
||||
#include maps\mp\gametypes\_hostmigration;
|
||||
|
||||
codecallback_startgametype()
|
||||
{
|
||||
if ( !isdefined( level.gametypestarted ) || !level.gametypestarted )
|
||||
{
|
||||
[[ level.callbackstartgametype ]]();
|
||||
level.gametypestarted = 1;
|
||||
}
|
||||
}
|
||||
|
||||
codecallback_finalizeinitialization()
|
||||
{
|
||||
maps\mp\_utility::callback( "on_finalize_initialization" );
|
||||
}
|
||||
|
||||
codecallback_playerconnect()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
self thread maps\mp\_audio::monitor_player_sprint();
|
||||
[[ level.callbackplayerconnect ]]();
|
||||
}
|
||||
|
||||
codecallback_playerdisconnect()
|
||||
{
|
||||
self notify( "disconnect" );
|
||||
level notify( "disconnect", self );
|
||||
client_num = self getentitynumber();
|
||||
[[ level.callbackplayerdisconnect ]]();
|
||||
}
|
||||
|
||||
codecallback_hostmigration()
|
||||
{
|
||||
/#
|
||||
println( "****CodeCallback_HostMigration****" );
|
||||
#/
|
||||
[[ level.callbackhostmigration ]]();
|
||||
}
|
||||
|
||||
codecallback_hostmigrationsave()
|
||||
{
|
||||
/#
|
||||
println( "****CodeCallback_HostMigrationSave****" );
|
||||
#/
|
||||
[[ level.callbackhostmigrationsave ]]();
|
||||
}
|
||||
|
||||
codecallback_playermigrated()
|
||||
{
|
||||
/#
|
||||
println( "****CodeCallback_PlayerMigrated****" );
|
||||
#/
|
||||
[[ level.callbackplayermigrated ]]();
|
||||
}
|
||||
|
||||
codecallback_playerdamage( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, timeoffset, boneindex )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
[[ level.callbackplayerdamage ]]( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, timeoffset, boneindex );
|
||||
}
|
||||
|
||||
codecallback_playerkilled( einflictor, eattacker, idamage, smeansofdeath, sweapon, vdir, shitloc, timeoffset, deathanimduration )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
[[ level.callbackplayerkilled ]]( einflictor, eattacker, idamage, smeansofdeath, sweapon, vdir, shitloc, timeoffset, deathanimduration );
|
||||
}
|
||||
|
||||
codecallback_playerlaststand( einflictor, eattacker, idamage, smeansofdeath, sweapon, vdir, shitloc, timeoffset, deathanimduration )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
[[ level.callbackplayerlaststand ]]( einflictor, eattacker, idamage, smeansofdeath, sweapon, vdir, shitloc, timeoffset, deathanimduration );
|
||||
}
|
||||
|
||||
codecallback_playermelee( eattacker, idamage, sweapon, vorigin, vdir, boneindex, shieldhit )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
[[ level.callbackplayermelee ]]( eattacker, idamage, sweapon, vorigin, vdir, boneindex, shieldhit );
|
||||
}
|
||||
|
||||
codecallback_actordamage( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, timeoffset, boneindex )
|
||||
{
|
||||
[[ level.callbackactordamage ]]( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, timeoffset, boneindex );
|
||||
}
|
||||
|
||||
codecallback_actorkilled( einflictor, eattacker, idamage, smeansofdeath, sweapon, vdir, shitloc, timeoffset )
|
||||
{
|
||||
[[ level.callbackactorkilled ]]( einflictor, eattacker, idamage, smeansofdeath, sweapon, vdir, shitloc, timeoffset );
|
||||
}
|
||||
|
||||
codecallback_vehicledamage( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, timeoffset, damagefromunderneath, modelindex, partname )
|
||||
{
|
||||
[[ level.callbackvehicledamage ]]( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, timeoffset, damagefromunderneath, modelindex, partname );
|
||||
}
|
||||
|
||||
codecallback_vehicleradiusdamage( einflictor, eattacker, idamage, finnerdamage, fouterdamage, idflags, smeansofdeath, sweapon, vpoint, fradius, fconeanglecos, vconedir, timeoffset )
|
||||
{
|
||||
[[ level.callbackvehicleradiusdamage ]]( einflictor, eattacker, idamage, finnerdamage, fouterdamage, idflags, smeansofdeath, sweapon, vpoint, fradius, fconeanglecos, vconedir, timeoffset );
|
||||
}
|
||||
|
||||
codecallback_faceeventnotify( notify_msg, ent )
|
||||
{
|
||||
if ( isdefined( ent ) && isdefined( ent.do_face_anims ) && ent.do_face_anims )
|
||||
{
|
||||
if ( isdefined( level.face_event_handler ) && isdefined( level.face_event_handler.events[notify_msg] ) )
|
||||
ent sendfaceevent( level.face_event_handler.events[notify_msg] );
|
||||
}
|
||||
}
|
||||
|
||||
codecallback_menuresponse( action, arg )
|
||||
{
|
||||
if ( !isdefined( level.menuresponsequeue ) )
|
||||
{
|
||||
level.menuresponsequeue = [];
|
||||
level thread menuresponsequeuepump();
|
||||
}
|
||||
|
||||
index = level.menuresponsequeue.size;
|
||||
level.menuresponsequeue[index] = spawnstruct();
|
||||
level.menuresponsequeue[index].action = action;
|
||||
level.menuresponsequeue[index].arg = arg;
|
||||
level.menuresponsequeue[index].ent = self;
|
||||
level notify( "menuresponse_queue" );
|
||||
}
|
||||
|
||||
menuresponsequeuepump()
|
||||
{
|
||||
while ( true )
|
||||
{
|
||||
level waittill( "menuresponse_queue" );
|
||||
|
||||
do
|
||||
{
|
||||
level.menuresponsequeue[0].ent notify( "menuresponse", level.menuresponsequeue[0].action, level.menuresponsequeue[0].arg );
|
||||
arrayremoveindex( level.menuresponsequeue, 0, 0 );
|
||||
wait 0.05;
|
||||
}
|
||||
while ( level.menuresponsequeue.size > 0 );
|
||||
}
|
||||
}
|
||||
|
||||
setupcallbacks()
|
||||
{
|
||||
setdefaultcallbacks();
|
||||
level.idflags_radius = 1;
|
||||
level.idflags_no_armor = 2;
|
||||
level.idflags_no_knockback = 4;
|
||||
level.idflags_penetration = 8;
|
||||
level.idflags_destructible_entity = 16;
|
||||
level.idflags_shield_explosive_impact = 32;
|
||||
level.idflags_shield_explosive_impact_huge = 64;
|
||||
level.idflags_shield_explosive_splash = 128;
|
||||
level.idflags_no_team_protection = 256;
|
||||
level.idflags_no_protection = 512;
|
||||
level.idflags_passthru = 1024;
|
||||
}
|
||||
|
||||
setdefaultcallbacks()
|
||||
{
|
||||
level.callbackstartgametype = maps\mp\gametypes\_globallogic::callback_startgametype;
|
||||
level.callbackplayerconnect = maps\mp\gametypes\_globallogic_player::callback_playerconnect;
|
||||
level.callbackplayerdisconnect = maps\mp\gametypes\_globallogic_player::callback_playerdisconnect;
|
||||
level.callbackplayerdamage = maps\mp\gametypes\_globallogic_player::callback_playerdamage;
|
||||
level.callbackplayerkilled = maps\mp\gametypes\_globallogic_player::callback_playerkilled;
|
||||
level.callbackplayermelee = maps\mp\gametypes\_globallogic_player::callback_playermelee;
|
||||
level.callbackplayerlaststand = maps\mp\gametypes\_globallogic_player::callback_playerlaststand;
|
||||
level.callbackactordamage = maps\mp\gametypes\_globallogic_actor::callback_actordamage;
|
||||
level.callbackactorkilled = maps\mp\gametypes\_globallogic_actor::callback_actorkilled;
|
||||
level.callbackvehicledamage = maps\mp\gametypes\_globallogic_vehicle::callback_vehicledamage;
|
||||
level.callbackvehicleradiusdamage = maps\mp\gametypes\_globallogic_vehicle::callback_vehicleradiusdamage;
|
||||
level.callbackplayermigrated = maps\mp\gametypes\_globallogic_player::callback_playermigrated;
|
||||
level.callbackhostmigration = maps\mp\gametypes\_hostmigration::callback_hostmigration;
|
||||
level.callbackhostmigrationsave = maps\mp\gametypes\_hostmigration::callback_hostmigrationsave;
|
||||
}
|
||||
|
||||
abortlevel()
|
||||
{
|
||||
/#
|
||||
println( "ERROR: Aborting level - gametype is not supported" );
|
||||
#/
|
||||
level.callbackstartgametype = ::callbackvoid;
|
||||
level.callbackplayerconnect = ::callbackvoid;
|
||||
level.callbackplayerdisconnect = ::callbackvoid;
|
||||
level.callbackplayerdamage = ::callbackvoid;
|
||||
level.callbackplayerkilled = ::callbackvoid;
|
||||
level.callbackplayerlaststand = ::callbackvoid;
|
||||
level.callbackplayermelee = ::callbackvoid;
|
||||
level.callbackactordamage = ::callbackvoid;
|
||||
level.callbackactorkilled = ::callbackvoid;
|
||||
level.callbackvehicledamage = ::callbackvoid;
|
||||
setdvar( "g_gametype", "dm" );
|
||||
exitlevel( 0 );
|
||||
}
|
||||
|
||||
codecallback_glasssmash( pos, dir )
|
||||
{
|
||||
level notify( "glass_smash", pos, dir );
|
||||
}
|
||||
|
||||
callbackvoid()
|
||||
{
|
||||
|
||||
}
|
1129
MP/Core/maps/mp/gametypes/_class.gsc
Normal file
1129
MP/Core/maps/mp/gametypes/_class.gsc
Normal file
File diff suppressed because it is too large
Load Diff
19
MP/Core/maps/mp/gametypes/_clientids.gsc
Normal file
19
MP/Core/maps/mp/gametypes/_clientids.gsc
Normal file
@ -0,0 +1,19 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
|
||||
init()
|
||||
{
|
||||
level.clientid = 0;
|
||||
level thread onplayerconnect();
|
||||
}
|
||||
|
||||
onplayerconnect()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
level waittill( "connecting", player );
|
||||
|
||||
player.clientid = level.clientid;
|
||||
level.clientid++;
|
||||
}
|
||||
}
|
775
MP/Core/maps/mp/gametypes/_copter.gsc
Normal file
775
MP/Core/maps/mp/gametypes/_copter.gsc
Normal file
@ -0,0 +1,775 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
|
||||
init()
|
||||
{
|
||||
level.coptermodel = "vehicle_cobra_helicopter_fly";
|
||||
precachemodel( level.coptermodel );
|
||||
level.copter_maxaccel = 200;
|
||||
level.copter_maxvel = 700;
|
||||
level.copter_rotspeed = 90;
|
||||
level.copter_accellookahead = 2;
|
||||
level.coptercenteroffset = vectorscale( ( 0, 0, 1 ), 72.0 );
|
||||
level.coptertargetoffset = vectorscale( ( 0, 0, 1 ), 45.0 );
|
||||
level.copterexplosion = loadfx( "explosions/fx_default_explosion" );
|
||||
level.copterfinalexplosion = loadfx( "explosions/fx_large_vehicle_explosion" );
|
||||
}
|
||||
|
||||
getabovebuildingslocation( location )
|
||||
{
|
||||
trace = bullettrace( location + vectorscale( ( 0, 0, 1 ), 10000.0 ), location, 0, undefined );
|
||||
startorigin = trace["position"] + vectorscale( ( 0, 0, -1 ), 514.0 );
|
||||
zpos = 0;
|
||||
maxxpos = 13;
|
||||
maxypos = 13;
|
||||
|
||||
for ( xpos = 0; xpos < maxxpos; xpos++ )
|
||||
{
|
||||
for ( ypos = 0; ypos < maxypos; ypos++ )
|
||||
{
|
||||
thisstartorigin = startorigin + ( ( xpos / ( maxxpos - 1 ) - 0.5 ) * 1024, ( ypos / ( maxypos - 1 ) - 0.5 ) * 1024, 0 );
|
||||
thisorigin = bullettrace( thisstartorigin, thisstartorigin + vectorscale( ( 0, 0, -1 ), 10000.0 ), 0, undefined );
|
||||
zpos += thisorigin["position"][2];
|
||||
}
|
||||
}
|
||||
|
||||
zpos /= maxxpos * maxypos;
|
||||
zpos += 850;
|
||||
return ( location[0], location[1], zpos );
|
||||
}
|
||||
|
||||
vectorangle( v1, v2 )
|
||||
{
|
||||
dot = vectordot( v1, v2 );
|
||||
|
||||
if ( dot >= 1 )
|
||||
return 0;
|
||||
else if ( dot <= -1 )
|
||||
return 180;
|
||||
|
||||
return acos( dot );
|
||||
}
|
||||
|
||||
vectortowardsothervector( v1, v2, angle )
|
||||
{
|
||||
dot = vectordot( v1, v2 );
|
||||
|
||||
if ( dot <= -1 )
|
||||
return v1;
|
||||
|
||||
v3 = vectornormalize( v2 - vectorscale( v1, dot ) );
|
||||
return vectorscale( v1, cos( angle ) ) + vectorscale( v3, sin( angle ) );
|
||||
}
|
||||
|
||||
veclength( v )
|
||||
{
|
||||
return distance( ( 0, 0, 0 ), v );
|
||||
}
|
||||
|
||||
createcopter( location, team, damagetrig )
|
||||
{
|
||||
location = getabovebuildingslocation( location );
|
||||
scriptorigin = spawn( "script_origin", location );
|
||||
scriptorigin.angles = vectortoangles( ( 1, 0, 0 ) );
|
||||
copter = spawn( "script_model", location );
|
||||
copter.angles = vectortoangles( ( 0, 1, 0 ) );
|
||||
copter linkto( scriptorigin );
|
||||
scriptorigin.copter = copter;
|
||||
copter setmodel( level.coptermodel );
|
||||
copter playloopsound( "mp_copter_ambience" );
|
||||
damagetrig.origin = scriptorigin.origin;
|
||||
damagetrig thread mylinkto( scriptorigin );
|
||||
scriptorigin.damagetrig = damagetrig;
|
||||
scriptorigin.finaldest = location;
|
||||
scriptorigin.finalzdest = location[2];
|
||||
scriptorigin.desireddir = ( 1, 0, 0 );
|
||||
scriptorigin.desireddirentity = undefined;
|
||||
scriptorigin.desireddirentityoffset = ( 0, 0, 0 );
|
||||
scriptorigin.vel = ( 0, 0, 0 );
|
||||
scriptorigin.dontascend = 0;
|
||||
scriptorigin.health = 2000;
|
||||
|
||||
if ( getdvar( _hash_A8262D2E ) != "" )
|
||||
scriptorigin.health = getdvarfloat( _hash_A8262D2E );
|
||||
|
||||
scriptorigin.team = team;
|
||||
scriptorigin thread copterai();
|
||||
scriptorigin thread copterdamage( damagetrig );
|
||||
return scriptorigin;
|
||||
}
|
||||
|
||||
makecopterpassive()
|
||||
{
|
||||
self.damagetrig notify( "unlink" );
|
||||
self.damagetrig = undefined;
|
||||
self notify( "passive" );
|
||||
self.desireddirentity = undefined;
|
||||
self.desireddir = undefined;
|
||||
}
|
||||
|
||||
makecopteractive( damagetrig )
|
||||
{
|
||||
damagetrig.origin = self.origin;
|
||||
damagetrig thread mylinkto( self );
|
||||
self.damagetrig = damagetrig;
|
||||
self thread copterai();
|
||||
self thread copterdamage( damagetrig );
|
||||
}
|
||||
|
||||
mylinkto( obj )
|
||||
{
|
||||
self endon( "unlink" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self.angles = obj.angles;
|
||||
self.origin = obj.origin;
|
||||
wait 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
setcopterdefensearea( areaent )
|
||||
{
|
||||
self.areaent = areaent;
|
||||
self.areadescentpoints = [];
|
||||
|
||||
if ( isdefined( areaent.target ) )
|
||||
self.areadescentpoints = getentarray( areaent.target, "targetname" );
|
||||
|
||||
for ( i = 0; i < self.areadescentpoints.size; i++ )
|
||||
self.areadescentpoints[i].targetent = getent( self.areadescentpoints[i].target, "targetname" );
|
||||
}
|
||||
|
||||
copterai()
|
||||
{
|
||||
self thread coptermove();
|
||||
self thread coptershoot();
|
||||
self endon( "death" );
|
||||
self endon( "passive" );
|
||||
flying = 1;
|
||||
descendingent = undefined;
|
||||
reacheddescendingent = 0;
|
||||
returningtoarea = 0;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
if ( !isdefined( self.areaent ) )
|
||||
{
|
||||
wait 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
players = level.players;
|
||||
enemytargets = [];
|
||||
|
||||
if ( self.team != "neutral" )
|
||||
{
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
if ( isalive( players[i] ) && isdefined( players[i].pers["team"] ) && players[i].pers["team"] != self.team && !isdefined( players[i].usingobj ) )
|
||||
{
|
||||
playerorigin = players[i].origin;
|
||||
playerorigin = ( playerorigin[0], playerorigin[1], self.areaent.origin[2] );
|
||||
|
||||
if ( distance( playerorigin, self.areaent.origin ) < self.areaent.radius )
|
||||
enemytargets[enemytargets.size] = players[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
insidetargets = [];
|
||||
outsidetargets = [];
|
||||
skyheight = bullettrace( self.origin, self.origin + vectorscale( ( 0, 0, 1 ), 10000.0 ), 0, undefined )["position"][2] - 10;
|
||||
besttarget = undefined;
|
||||
bestweight = 0;
|
||||
|
||||
for ( i = 0; i < enemytargets.size; i++ )
|
||||
{
|
||||
inside = 0;
|
||||
trace = bullettrace( enemytargets[i].origin + vectorscale( ( 0, 0, 1 ), 10.0 ), enemytargets[i].origin + vectorscale( ( 0, 0, 1 ), 10000.0 ), 0, undefined );
|
||||
|
||||
if ( trace["position"][2] >= skyheight )
|
||||
{
|
||||
outsidetargets[outsidetargets.size] = enemytargets[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
insidetargets[insidetargets.size] = enemytargets[i];
|
||||
}
|
||||
|
||||
gotopos = undefined;
|
||||
calcedgotopos = 0;
|
||||
olddescendingent = undefined;
|
||||
|
||||
if ( flying )
|
||||
{
|
||||
if ( outsidetargets.size == 0 && insidetargets.size > 0 && self.areadescentpoints.size > 0 )
|
||||
{
|
||||
flying = 0;
|
||||
result = determinebestent( insidetargets, self.areadescentpoints, self.origin );
|
||||
descendingent = result["descendEnt"];
|
||||
|
||||
if ( isdefined( descendingent ) )
|
||||
gotopos = result["position"];
|
||||
else
|
||||
flying = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
olddescendingent = descendingent;
|
||||
|
||||
if ( insidetargets.size == 0 )
|
||||
flying = 1;
|
||||
else
|
||||
{
|
||||
if ( outsidetargets.size > 0 )
|
||||
{
|
||||
if ( !isdefined( descendingent ) )
|
||||
flying = 1;
|
||||
else
|
||||
{
|
||||
calcedgotopos = 1;
|
||||
gotopos = determinebestpos( insidetargets, descendingent, self.origin );
|
||||
|
||||
if ( !isdefined( gotopos ) )
|
||||
flying = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isdefined( descendingent ) )
|
||||
{
|
||||
if ( !calcedgotopos )
|
||||
gotopos = determinebestpos( insidetargets, descendingent, self.origin );
|
||||
}
|
||||
|
||||
if ( !isdefined( gotopos ) )
|
||||
{
|
||||
result = determinebestent( insidetargets, self.areadescentpoints, self.origin );
|
||||
|
||||
if ( isdefined( result["descendEnt"] ) )
|
||||
{
|
||||
descendingent = result["descendEnt"];
|
||||
gotopos = result["position"];
|
||||
reacheddescendingent = 0;
|
||||
}
|
||||
else if ( isdefined( descendingent ) )
|
||||
{
|
||||
if ( isdefined( self.finaldest ) )
|
||||
gotopos = self.finaldest;
|
||||
else
|
||||
gotopos = descendingent.origin;
|
||||
}
|
||||
else
|
||||
gotopos = undefined;
|
||||
}
|
||||
|
||||
if ( !isdefined( gotopos ) )
|
||||
flying = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( flying )
|
||||
{
|
||||
desireddist = 2560.0;
|
||||
disttoarea = distance( ( self.origin[0], self.origin[1], self.areaent.origin[2] ), self.areaent.origin );
|
||||
|
||||
if ( outsidetargets.size == 0 && disttoarea > self.areaent.radius + desireddist * 0.25 )
|
||||
returningtoarea = 1;
|
||||
else if ( disttoarea < self.areaent.radius * 0.5 )
|
||||
returningtoarea = 0;
|
||||
|
||||
if ( outsidetargets.size == 0 && !returningtoarea )
|
||||
{
|
||||
if ( self.team != "neutral" )
|
||||
{
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
if ( isalive( players[i] ) && isdefined( players[i].pers["team"] ) && players[i].pers["team"] != self.team && !isdefined( players[i].usingobj ) )
|
||||
{
|
||||
playerorigin = players[i].origin;
|
||||
playerorigin = ( playerorigin[0], playerorigin[1], self.areaent.origin[2] );
|
||||
|
||||
if ( distance( players[i].origin, self.areaent.origin ) > self.areaent.radius )
|
||||
outsidetargets[outsidetargets.size] = players[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
best = undefined;
|
||||
bestdist = 0;
|
||||
|
||||
for ( i = 0; i < outsidetargets.size; i++ )
|
||||
{
|
||||
dist = abs( distance( outsidetargets[i].origin, self.origin ) - desireddist );
|
||||
|
||||
if ( !isdefined( best ) || dist < bestdist )
|
||||
{
|
||||
best = outsidetargets[i];
|
||||
bestdist = dist;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isdefined( best ) )
|
||||
{
|
||||
attackpos = best.origin + level.coptertargetoffset;
|
||||
gotopos = determinebestattackpos( attackpos, self.origin, desireddist );
|
||||
self setcopterdest( gotopos, 0 );
|
||||
self.desireddir = vectornormalize( attackpos - gotopos );
|
||||
self.desireddirentity = best;
|
||||
self.desireddirentityoffset = level.coptertargetoffset;
|
||||
wait 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
gotopos = getrandompos( self.areaent.origin, self.areaent.radius );
|
||||
self setcopterdest( gotopos, 0 );
|
||||
self.desireddir = undefined;
|
||||
self.desireddirentity = undefined;
|
||||
wait 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( distance( self.origin, descendingent.origin ) < descendingent.radius )
|
||||
reacheddescendingent = 1;
|
||||
|
||||
godirectly = isdefined( olddescendingent ) && olddescendingent == descendingent;
|
||||
godirectly = godirectly && reacheddescendingent;
|
||||
self.desireddir = vectornormalize( descendingent.targetent.origin - ( gotopos - level.coptercenteroffset ) );
|
||||
self.desireddirentity = descendingent.targetent;
|
||||
self.desireddirentityoffset = ( 0, 0, 0 );
|
||||
|
||||
if ( gotopos != self.origin )
|
||||
{
|
||||
self setcopterdest( gotopos - level.coptercenteroffset, 1, godirectly );
|
||||
wait 0.3;
|
||||
}
|
||||
else
|
||||
wait 0.3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
determinebestpos( targets, descendent, startorigin )
|
||||
{
|
||||
targetpos = descendent.targetent.origin;
|
||||
circleradius = distance( targetpos, descendent.origin );
|
||||
bestpoint = undefined;
|
||||
bestdist = 0;
|
||||
|
||||
for ( i = 0; i < targets.size; i++ )
|
||||
{
|
||||
enemypos = targets[i].origin + level.coptertargetoffset;
|
||||
passed = bullettracepassed( enemypos, targetpos, 0, undefined );
|
||||
|
||||
if ( passed )
|
||||
{
|
||||
dir = targetpos - enemypos;
|
||||
dir = ( dir[0], dir[1], 0 );
|
||||
isect = vectorscale( vectornormalize( dir ), circleradius ) + targetpos;
|
||||
isect = ( isect[0], isect[1], descendent.origin[2] );
|
||||
dist = distance( isect, descendent.origin );
|
||||
|
||||
if ( dist <= descendent.radius )
|
||||
{
|
||||
dist = distance( isect, startorigin );
|
||||
|
||||
if ( !isdefined( bestpoint ) || dist < bestdist )
|
||||
{
|
||||
bestdist = dist;
|
||||
bestpoint = isect;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bestpoint;
|
||||
}
|
||||
|
||||
determinebestent( targets, descendents, startorigin )
|
||||
{
|
||||
result = [];
|
||||
bestpos = undefined;
|
||||
bestent = 0;
|
||||
bestdist = 0;
|
||||
|
||||
for ( i = 0; i < descendents.size; i++ )
|
||||
{
|
||||
thispos = determinebestpos( targets, descendents[i], startorigin );
|
||||
|
||||
if ( isdefined( thispos ) )
|
||||
{
|
||||
thisdist = distance( thispos, startorigin );
|
||||
|
||||
if ( !isdefined( bestpos ) || thisdist < bestdist )
|
||||
{
|
||||
bestpos = thispos;
|
||||
bestent = i;
|
||||
bestdist = thisdist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isdefined( bestpos ) )
|
||||
{
|
||||
result["descendEnt"] = descendents[bestent];
|
||||
result["position"] = bestpos;
|
||||
return result;
|
||||
}
|
||||
|
||||
result["descendEnt"] = undefined;
|
||||
return result;
|
||||
}
|
||||
|
||||
determinebestattackpos( targetpos, curpos, desireddist )
|
||||
{
|
||||
targetposcopterheight = ( targetpos[0], targetpos[1], curpos[2] );
|
||||
attackdirx = curpos - targetposcopterheight;
|
||||
attackdirx = vectornormalize( attackdirx );
|
||||
attackdiry = ( 0 - attackdirx[1], attackdirx[0], 0 );
|
||||
bestpos = undefined;
|
||||
bestdist = 0;
|
||||
|
||||
for ( i = 0; i < 8; i++ )
|
||||
{
|
||||
theta = i / 8.0 * 360;
|
||||
thisdir = vectorscale( attackdirx, cos( theta ) ) + vectorscale( attackdiry, sin( theta ) );
|
||||
traceend = targetposcopterheight + vectorscale( thisdir, desireddist );
|
||||
losexists = bullettracepassed( targetpos, traceend, 0, undefined );
|
||||
|
||||
if ( losexists )
|
||||
{
|
||||
thisdist = distance( traceend, curpos );
|
||||
|
||||
if ( !isdefined( bestpos ) || thisdist < bestdist )
|
||||
{
|
||||
bestpos = traceend;
|
||||
bestdist = thisdist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gotopos = undefined;
|
||||
|
||||
if ( isdefined( bestpos ) )
|
||||
gotopos = bestpos;
|
||||
else
|
||||
{
|
||||
dist = distance( targetposcopterheight, curpos );
|
||||
|
||||
if ( dist > desireddist )
|
||||
gotopos = self.origin + vectorscale( vectornormalize( attackdirx ), 0 - ( dist - desireddist ) );
|
||||
else
|
||||
gotopos = self.origin;
|
||||
}
|
||||
|
||||
return gotopos;
|
||||
}
|
||||
|
||||
getrandompos( origin, radius )
|
||||
{
|
||||
for ( pos = origin + ( ( randomfloat( 2 ) - 1 ) * radius, ( randomfloat( 2 ) - 1 ) * radius, 0 ); distancesquared( pos, origin ) > radius * radius; pos = origin + ( ( randomfloat( 2 ) - 1 ) * radius, ( randomfloat( 2 ) - 1 ) * radius, 0 ) )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
coptershoot()
|
||||
{
|
||||
self endon( "death" );
|
||||
self endon( "passive" );
|
||||
costhreshold = cos( 10 );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
if ( isdefined( self.desireddirentity ) && isdefined( self.desireddirentity.origin ) )
|
||||
{
|
||||
mypos = self.origin + level.coptercenteroffset;
|
||||
enemypos = self.desireddirentity.origin + self.desireddirentityoffset;
|
||||
curdir = anglestoforward( self.angles );
|
||||
enemydirraw = enemypos - mypos;
|
||||
enemydir = vectornormalize( enemydirraw );
|
||||
|
||||
if ( vectordot( curdir, enemydir ) > costhreshold )
|
||||
{
|
||||
canseetarget = bullettracepassed( mypos, enemypos, 0, undefined );
|
||||
|
||||
if ( !canseetarget && isplayer( self.desireddirentity ) && isalive( self.desireddirentity ) )
|
||||
canseetarget = bullettracepassed( mypos, self.desireddirentity geteye(), 0, undefined );
|
||||
|
||||
if ( canseetarget )
|
||||
{
|
||||
self playsound( "mp_copter_shoot" );
|
||||
numshots = 20;
|
||||
|
||||
for ( i = 0; i < numshots; i++ )
|
||||
{
|
||||
mypos = self.origin + level.coptercenteroffset;
|
||||
dir = anglestoforward( self.angles );
|
||||
dir += ( ( randomfloat( 2 ) - 1 ) * 0.015, ( randomfloat( 2 ) - 1 ) * 0.015, ( randomfloat( 2 ) - 1 ) * 0.015 );
|
||||
dir = vectornormalize( dir );
|
||||
self mymagicbullet( mypos, dir );
|
||||
wait 0.075;
|
||||
}
|
||||
|
||||
wait 0.25;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wait 0.25;
|
||||
}
|
||||
}
|
||||
|
||||
mymagicbullet( pos, dir )
|
||||
{
|
||||
damage = 20;
|
||||
|
||||
if ( getdvar( _hash_9E8F8CB7 ) != "" )
|
||||
damage = getdvarint( _hash_9E8F8CB7 );
|
||||
|
||||
trace = bullettrace( pos, pos + vectorscale( dir, 10000 ), 1, undefined );
|
||||
|
||||
if ( isdefined( trace["entity"] ) && isplayer( trace["entity"] ) && isalive( trace["entity"] ) )
|
||||
trace["entity"] thread [[ level.callbackplayerdamage ]]( self, self, damage, 0, "MOD_RIFLE_BULLET", "copter", self.origin, dir, "none", 0, 0 );
|
||||
}
|
||||
|
||||
setcopterdest( newlocation, descend, dontascend )
|
||||
{
|
||||
self.finaldest = getabovebuildingslocation( newlocation );
|
||||
|
||||
if ( isdefined( descend ) && descend )
|
||||
self.finalzdest = newlocation[2];
|
||||
else
|
||||
self.finalzdest = self.finaldest[2];
|
||||
|
||||
self.intransit = 1;
|
||||
self.dontascend = 0;
|
||||
|
||||
if ( isdefined( dontascend ) )
|
||||
self.dontascend = dontascend;
|
||||
}
|
||||
|
||||
notifyarrived()
|
||||
{
|
||||
wait 0.05;
|
||||
self notify( "arrived" );
|
||||
}
|
||||
|
||||
coptermove()
|
||||
{
|
||||
self endon( "death" );
|
||||
|
||||
if ( isdefined( self.coptermoverunning ) )
|
||||
return;
|
||||
|
||||
self.coptermoverunning = 1;
|
||||
self.intransit = 0;
|
||||
interval = 0.15;
|
||||
zinterp = 0.1;
|
||||
tiltamnt = 0;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
horizdistsquared = distancesquared( ( self.origin[0], self.origin[1], 0 ), ( self.finaldest[0], self.finaldest[1], 0 ) );
|
||||
donemoving = horizdistsquared < 100;
|
||||
neardest = horizdistsquared < 65536;
|
||||
self.intransit = 1;
|
||||
desiredz = 0;
|
||||
movinghorizontally = 1;
|
||||
movingvertically = 0;
|
||||
|
||||
if ( self.dontascend )
|
||||
movingvertically = 1;
|
||||
else if ( !neardest )
|
||||
{
|
||||
desiredz = getabovebuildingslocation( self.origin )[2];
|
||||
movinghorizontally = abs( self.origin[2] - desiredz ) <= 256;
|
||||
movingvertically = !movinghorizontally;
|
||||
}
|
||||
else
|
||||
movingvertically = 1;
|
||||
|
||||
if ( movinghorizontally )
|
||||
{
|
||||
if ( movingvertically )
|
||||
thisdest = ( self.finaldest[0], self.finaldest[1], self.finalzdest );
|
||||
else
|
||||
thisdest = self.finaldest;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( movingvertically );
|
||||
thisdest = ( self.origin[0], self.origin[1], desiredz );
|
||||
}
|
||||
|
||||
movevec = thisdest - self.origin;
|
||||
idealaccel = vectorscale( thisdest - self.origin + vectorscale( self.vel, level.copter_accellookahead ), interval );
|
||||
vlen = veclength( idealaccel );
|
||||
|
||||
if ( vlen > level.copter_maxaccel )
|
||||
idealaccel = vectorscale( idealaccel, level.copter_maxaccel / vlen );
|
||||
|
||||
self.vel += idealaccel;
|
||||
vlen = veclength( self.vel );
|
||||
|
||||
if ( vlen > level.copter_maxvel )
|
||||
self.vel = vectorscale( self.vel, level.copter_maxvel / vlen );
|
||||
|
||||
thisdest = self.origin + vectorscale( self.vel, interval );
|
||||
self moveto( thisdest, interval * 0.999 );
|
||||
speed = veclength( self.vel );
|
||||
|
||||
if ( isdefined( self.desireddirentity ) && isdefined( self.desireddirentity.origin ) )
|
||||
self.destdir = vectornormalize( self.desireddirentity.origin + self.desireddirentityoffset - self.origin + level.coptercenteroffset );
|
||||
else if ( isdefined( self.desireddir ) )
|
||||
self.destdir = self.desireddir;
|
||||
else if ( movingvertically )
|
||||
{
|
||||
self.destdir = anglestoforward( self.angles );
|
||||
self.destdir = vectornormalize( ( self.destdir[0], self.destdir[1], 0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
tiltamnt = speed / level.copter_maxvel;
|
||||
tiltamnt = ( tiltamnt - 0.1 ) / 0.9;
|
||||
|
||||
if ( tiltamnt < 0 )
|
||||
tiltamnt = 0;
|
||||
|
||||
self.destdir = movevec;
|
||||
self.destdir = vectornormalize( ( self.destdir[0], self.destdir[1], 0 ) );
|
||||
tiltamnt *= ( 1 - vectorangle( anglestoforward( self.angles ), self.destdir ) / 180 );
|
||||
self.destdir = vectornormalize( ( self.destdir[0], self.destdir[1], tiltamnt * -0.4 ) );
|
||||
}
|
||||
|
||||
newdir = self.destdir;
|
||||
|
||||
if ( newdir[2] < -0.4 )
|
||||
newdir = vectornormalize( ( newdir[0], newdir[1], -0.4 ) );
|
||||
|
||||
copterangles = self.angles;
|
||||
copterangles = combineangles( copterangles, vectorscale( ( 0, 1, 0 ), 90.0 ) );
|
||||
olddir = anglestoforward( copterangles );
|
||||
thisrotspeed = level.copter_rotspeed;
|
||||
olddir2d = vectornormalize( ( olddir[0], olddir[1], 0 ) );
|
||||
newdir2d = vectornormalize( ( newdir[0], newdir[1], 0 ) );
|
||||
angle = vectorangle( olddir2d, newdir2d );
|
||||
angle3d = vectorangle( olddir, newdir );
|
||||
|
||||
if ( angle > 0.001 && thisrotspeed > 0.001 )
|
||||
{
|
||||
thisangle = thisrotspeed * interval;
|
||||
|
||||
if ( thisangle > angle )
|
||||
thisangle = angle;
|
||||
|
||||
newdir2d = vectortowardsothervector( olddir2d, newdir2d, thisangle );
|
||||
oldz = olddir[2] / veclength( ( olddir[0], olddir[1], 0 ) );
|
||||
newz = newdir[2] / veclength( ( newdir[0], newdir[1], 0 ) );
|
||||
interpz = oldz + ( newz - oldz ) * thisangle / angle;
|
||||
newdir = vectornormalize( ( newdir2d[0], newdir2d[1], interpz ) );
|
||||
copterangles = vectortoangles( newdir );
|
||||
copterangles = combineangles( copterangles, vectorscale( ( 0, -1, 0 ), 90.0 ) );
|
||||
self rotateto( copterangles, interval * 0.999 );
|
||||
}
|
||||
else if ( angle3d > 0.001 && thisrotspeed > 0.001 )
|
||||
{
|
||||
thisangle = thisrotspeed * interval;
|
||||
|
||||
if ( thisangle > angle3d )
|
||||
thisangle = angle3d;
|
||||
|
||||
newdir = vectortowardsothervector( olddir, newdir, thisangle );
|
||||
newdir = vectornormalize( newdir );
|
||||
copterangles = vectortoangles( newdir );
|
||||
copterangles = combineangles( copterangles, vectorscale( ( 0, -1, 0 ), 90.0 ) );
|
||||
self rotateto( copterangles, interval * 0.999 );
|
||||
}
|
||||
|
||||
wait( interval );
|
||||
}
|
||||
}
|
||||
|
||||
copterdamage( damagetrig )
|
||||
{
|
||||
self endon( "passive" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
damagetrig waittill( "damage", amount, attacker );
|
||||
|
||||
if ( isdefined( attacker ) && isplayer( attacker ) && isdefined( attacker.pers["team"] ) && attacker.pers["team"] == self.team )
|
||||
continue;
|
||||
|
||||
self.health -= amount;
|
||||
|
||||
if ( self.health <= 0 )
|
||||
{
|
||||
self thread copterdie();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
copterdie()
|
||||
{
|
||||
self endon( "passive" );
|
||||
self death_notify_wrapper();
|
||||
self.dead = 1;
|
||||
self thread copterexplodefx();
|
||||
interval = 0.2;
|
||||
rottime = 15;
|
||||
self rotateyaw( 360 + randomfloat( 360 ), rottime );
|
||||
self rotatepitch( 360 + randomfloat( 360 ), rottime );
|
||||
self rotateroll( 360 + randomfloat( 360 ), rottime );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
self.vel += vectorscale( vectorscale( ( 0, 0, -1 ), 200.0 ), interval );
|
||||
newpos = self.origin + vectorscale( self.vel, interval );
|
||||
pathclear = bullettracepassed( self.origin, newpos, 0, undefined );
|
||||
|
||||
if ( !pathclear )
|
||||
break;
|
||||
|
||||
self moveto( newpos, interval * 0.999 );
|
||||
wait( interval );
|
||||
}
|
||||
|
||||
playfx( level.copterfinalexplosion, self.origin );
|
||||
fakeself = spawn( "script_origin", self.origin );
|
||||
fakeself playsound( "mp_copter_explosion" );
|
||||
self notify( "finaldeath" );
|
||||
deletecopter();
|
||||
wait 2;
|
||||
fakeself delete();
|
||||
}
|
||||
|
||||
deletecopter()
|
||||
{
|
||||
if ( isdefined( self.damagetrig ) )
|
||||
{
|
||||
self.damagetrig notify( "unlink" );
|
||||
self.damagetrig = undefined;
|
||||
}
|
||||
|
||||
self.copter delete();
|
||||
self delete();
|
||||
}
|
||||
|
||||
copterexplodefx()
|
||||
{
|
||||
self endon( "finaldeath" );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
playfx( level.copterexplosion, self.origin );
|
||||
self playsound( "mp_copter_explosion" );
|
||||
wait( 0.5 + randomfloat( 1 ) );
|
||||
}
|
||||
}
|
166
MP/Core/maps/mp/gametypes/_damagefeedback.gsc
Normal file
166
MP/Core/maps/mp/gametypes/_damagefeedback.gsc
Normal file
@ -0,0 +1,166 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
|
||||
init()
|
||||
{
|
||||
precacheshader( "damage_feedback" );
|
||||
precacheshader( "damage_feedback_flak" );
|
||||
precacheshader( "damage_feedback_tac" );
|
||||
level thread onplayerconnect();
|
||||
}
|
||||
|
||||
onplayerconnect()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
level waittill( "connecting", player );
|
||||
|
||||
player.hud_damagefeedback = newdamageindicatorhudelem( player );
|
||||
player.hud_damagefeedback.horzalign = "center";
|
||||
player.hud_damagefeedback.vertalign = "middle";
|
||||
player.hud_damagefeedback.x = -12;
|
||||
player.hud_damagefeedback.y = -12;
|
||||
player.hud_damagefeedback.alpha = 0;
|
||||
player.hud_damagefeedback.archived = 1;
|
||||
player.hud_damagefeedback setshader( "damage_feedback", 24, 48 );
|
||||
player.hitsoundtracker = 1;
|
||||
}
|
||||
}
|
||||
|
||||
updatedamagefeedback( mod, inflictor, perkfeedback )
|
||||
{
|
||||
if ( !isplayer( self ) || sessionmodeiszombiesgame() )
|
||||
return;
|
||||
|
||||
if ( isdefined( mod ) && mod != "MOD_CRUSH" && mod != "MOD_GRENADE_SPLASH" && mod != "MOD_HIT_BY_OBJECT" )
|
||||
{
|
||||
if ( isdefined( inflictor ) && isdefined( inflictor.soundmod ) )
|
||||
{
|
||||
switch ( inflictor.soundmod )
|
||||
{
|
||||
case "player":
|
||||
self playlocalsound( "mpl_hit_alert" );
|
||||
break;
|
||||
case "heli":
|
||||
self thread playhitsound( mod, "mpl_hit_alert_air" );
|
||||
break;
|
||||
case "hpm":
|
||||
self thread playhitsound( mod, "mpl_hit_alert_hpm" );
|
||||
break;
|
||||
case "taser_spike":
|
||||
self thread playhitsound( mod, "mpl_hit_alert_taser_spike" );
|
||||
break;
|
||||
case "straferun":
|
||||
case "dog":
|
||||
break;
|
||||
case "default_loud":
|
||||
self thread playhitsound( mod, "mpl_hit_heli_gunner" );
|
||||
break;
|
||||
default:
|
||||
self thread playhitsound( mod, "mpl_hit_alert_low" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
self playlocalsound( "mpl_hit_alert_low" );
|
||||
}
|
||||
|
||||
if ( isdefined( perkfeedback ) )
|
||||
{
|
||||
switch ( perkfeedback )
|
||||
{
|
||||
case "flakjacket":
|
||||
self.hud_damagefeedback setshader( "damage_feedback_flak", 24, 48 );
|
||||
break;
|
||||
case "tacticalMask":
|
||||
self.hud_damagefeedback setshader( "damage_feedback_tac", 24, 48 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
self.hud_damagefeedback setshader( "damage_feedback", 24, 48 );
|
||||
|
||||
self.hud_damagefeedback.alpha = 1;
|
||||
self.hud_damagefeedback fadeovertime( 1 );
|
||||
self.hud_damagefeedback.alpha = 0;
|
||||
}
|
||||
|
||||
playhitsound( mod, alert )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
if ( self.hitsoundtracker )
|
||||
{
|
||||
self.hitsoundtracker = 0;
|
||||
self playlocalsound( alert );
|
||||
wait 0.05;
|
||||
self.hitsoundtracker = 1;
|
||||
}
|
||||
}
|
||||
|
||||
updatespecialdamagefeedback( hitent )
|
||||
{
|
||||
if ( !isplayer( self ) )
|
||||
return;
|
||||
|
||||
if ( !isdefined( hitent ) )
|
||||
return;
|
||||
|
||||
if ( !isplayer( hitent ) )
|
||||
return;
|
||||
|
||||
wait 0.05;
|
||||
|
||||
if ( !isdefined( self.directionalhitarray ) )
|
||||
{
|
||||
self.directionalhitarray = [];
|
||||
hitentnum = hitent getentitynumber();
|
||||
self.directionalhitarray[hitentnum] = 1;
|
||||
self thread sendhitspecialeventatframeend( hitent );
|
||||
}
|
||||
else
|
||||
{
|
||||
hitentnum = hitent getentitynumber();
|
||||
self.directionalhitarray[hitentnum] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
sendhitspecialeventatframeend( hitent )
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
waittillframeend;
|
||||
enemyshit = 0;
|
||||
value = 1;
|
||||
entbitarray0 = 0;
|
||||
|
||||
for ( i = 0; i < 32; i++ )
|
||||
{
|
||||
if ( isdefined( self.directionalhitarray[i] ) && self.directionalhitarray[i] != 0 )
|
||||
{
|
||||
entbitarray0 += value;
|
||||
enemyshit++;
|
||||
}
|
||||
|
||||
value *= 2;
|
||||
}
|
||||
|
||||
entbitarray1 = 0;
|
||||
|
||||
for ( i = 33; i < 64; i++ )
|
||||
{
|
||||
if ( isdefined( self.directionalhitarray[i] ) && self.directionalhitarray[i] != 0 )
|
||||
{
|
||||
entbitarray1 += value;
|
||||
enemyshit++;
|
||||
}
|
||||
|
||||
value *= 2;
|
||||
}
|
||||
|
||||
if ( enemyshit )
|
||||
self directionalhitindicator( entbitarray0, entbitarray1 );
|
||||
|
||||
self.directionalhitarray = undefined;
|
||||
entbitarray0 = 0;
|
||||
entbitarray1 = 0;
|
||||
}
|
94
MP/Core/maps/mp/gametypes/_deathicons.gsc
Normal file
94
MP/Core/maps/mp/gametypes/_deathicons.gsc
Normal file
@ -0,0 +1,94 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\gametypes\_globallogic_utils;
|
||||
#include maps\mp\gametypes\_deathicons;
|
||||
|
||||
init()
|
||||
{
|
||||
if ( !isdefined( level.ragdoll_override ) )
|
||||
level.ragdoll_override = ::ragdoll_override;
|
||||
|
||||
if ( !level.teambased )
|
||||
return;
|
||||
|
||||
precacheshader( "headicon_dead" );
|
||||
level thread onplayerconnect();
|
||||
}
|
||||
|
||||
onplayerconnect()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
level waittill( "connecting", player );
|
||||
|
||||
player.selfdeathicons = [];
|
||||
}
|
||||
}
|
||||
|
||||
updatedeathiconsenabled()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
adddeathicon( entity, dyingplayer, team, timeout )
|
||||
{
|
||||
if ( !level.teambased )
|
||||
return;
|
||||
|
||||
iconorg = entity.origin;
|
||||
dyingplayer endon( "spawned_player" );
|
||||
dyingplayer endon( "disconnect" );
|
||||
wait 0.05;
|
||||
maps\mp\gametypes\_globallogic_utils::waittillslowprocessallowed();
|
||||
assert( isdefined( level.teams[team] ) );
|
||||
|
||||
if ( getdvar( _hash_F83E8105 ) == "0" )
|
||||
return;
|
||||
|
||||
if ( level.hardcoremode )
|
||||
return;
|
||||
|
||||
if ( isdefined( self.lastdeathicon ) )
|
||||
self.lastdeathicon destroy();
|
||||
|
||||
newdeathicon = newteamhudelem( team );
|
||||
newdeathicon.x = iconorg[0];
|
||||
newdeathicon.y = iconorg[1];
|
||||
newdeathicon.z = iconorg[2] + 54;
|
||||
newdeathicon.alpha = 0.61;
|
||||
newdeathicon.archived = 1;
|
||||
|
||||
if ( level.splitscreen )
|
||||
newdeathicon setshader( "headicon_dead", 14, 14 );
|
||||
else
|
||||
newdeathicon setshader( "headicon_dead", 7, 7 );
|
||||
|
||||
newdeathicon setwaypoint( 1 );
|
||||
self.lastdeathicon = newdeathicon;
|
||||
newdeathicon thread destroyslowly( timeout );
|
||||
}
|
||||
|
||||
destroyslowly( timeout )
|
||||
{
|
||||
self endon( "death" );
|
||||
wait( timeout );
|
||||
self fadeovertime( 1.0 );
|
||||
self.alpha = 0;
|
||||
wait 1.0;
|
||||
self destroy();
|
||||
}
|
||||
|
||||
ragdoll_override( idamage, smeansofdeath, sweapon, shitloc, vdir, vattackerorigin, deathanimduration, einflictor, ragdoll_jib, body )
|
||||
{
|
||||
if ( smeansofdeath == "MOD_FALLING" && self isonground() == 1 )
|
||||
{
|
||||
body startragdoll();
|
||||
|
||||
if ( !isdefined( self.switching_teams ) )
|
||||
thread maps\mp\gametypes\_deathicons::adddeathicon( body, self, self.team, 5.0 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
3317
MP/Core/maps/mp/gametypes/_dev.gsc
Normal file
3317
MP/Core/maps/mp/gametypes/_dev.gsc
Normal file
File diff suppressed because it is too large
Load Diff
533
MP/Core/maps/mp/gametypes/_dev_class.gsc
Normal file
533
MP/Core/maps/mp/gametypes/_dev_class.gsc
Normal file
@ -0,0 +1,533 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
#include maps\mp\_utility;
|
||||
#include maps\mp\gametypes\_dev;
|
||||
|
||||
dev_cac_init()
|
||||
{
|
||||
/#
|
||||
dev_cac_overlay = 0;
|
||||
dev_cac_camera_on = 0;
|
||||
level thread dev_cac_gdt_update_think();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
wait 0.5;
|
||||
reset = 1;
|
||||
|
||||
if ( getdvar( _hash_E6D8B517 ) != "" )
|
||||
continue;
|
||||
|
||||
host = gethostplayer();
|
||||
|
||||
if ( !isdefined( level.dev_cac_player ) )
|
||||
level.dev_cac_player = host;
|
||||
|
||||
switch ( getdvar( "devgui_dev_cac" ) )
|
||||
{
|
||||
case "":
|
||||
reset = 0;
|
||||
break;
|
||||
case "dpad_body":
|
||||
host thread dev_cac_dpad_think( "body", ::dev_cac_cycle_body, "" );
|
||||
break;
|
||||
case "dpad_head":
|
||||
host thread dev_cac_dpad_think( "head", ::dev_cac_cycle_head, "" );
|
||||
break;
|
||||
case "dpad_character":
|
||||
host thread dev_cac_dpad_think( "character", ::dev_cac_cycle_character, "" );
|
||||
break;
|
||||
case "next_player":
|
||||
dev_cac_cycle_player( 1 );
|
||||
break;
|
||||
case "prev_player":
|
||||
dev_cac_cycle_player( 0 );
|
||||
break;
|
||||
case "cac_overlay":
|
||||
level notify( "dev_cac_overlay_think" );
|
||||
|
||||
if ( !dev_cac_overlay )
|
||||
level thread dev_cac_overlay_think();
|
||||
|
||||
dev_cac_overlay = !dev_cac_overlay;
|
||||
break;
|
||||
case "best_bullet_armor":
|
||||
dev_cac_set_model_range( ::sort_greatest, "armor_bullet" );
|
||||
break;
|
||||
case "worst_bullet_armor":
|
||||
dev_cac_set_model_range( ::sort_least, "armor_bullet" );
|
||||
break;
|
||||
case "best_explosive_armor":
|
||||
dev_cac_set_model_range( ::sort_greatest, "armor_explosive" );
|
||||
break;
|
||||
case "worst_explosive_armor":
|
||||
dev_cac_set_model_range( ::sort_least, "armor_explosive" );
|
||||
break;
|
||||
case "best_mobility":
|
||||
dev_cac_set_model_range( ::sort_greatest, "mobility" );
|
||||
break;
|
||||
case "worst_mobility":
|
||||
dev_cac_set_model_range( ::sort_least, "mobility" );
|
||||
break;
|
||||
case "camera":
|
||||
dev_cac_camera_on = !dev_cac_camera_on;
|
||||
dev_cac_camera( dev_cac_camera_on );
|
||||
break;
|
||||
case "dpad_camo":
|
||||
host thread dev_cac_dpad_think( "camo", ::dev_cac_cycle_render_options, "camo" );
|
||||
break;
|
||||
case "dpad_meleecamo":
|
||||
host thread dev_cac_dpad_think( "meleecamo", ::dev_cac_cycle_render_options, "meleecamo" );
|
||||
break;
|
||||
case "dpad_lens":
|
||||
host thread dev_cac_dpad_think( "lens", ::dev_cac_cycle_render_options, "lens" );
|
||||
break;
|
||||
case "dpad_reticle":
|
||||
host thread dev_cac_dpad_think( "reticle", ::dev_cac_cycle_render_options, "reticle" );
|
||||
break;
|
||||
case "dpad_reticle_color":
|
||||
host thread dev_cac_dpad_think( "reticle color", ::dev_cac_cycle_render_options, "reticle_color" );
|
||||
break;
|
||||
case "dpad_emblem":
|
||||
host thread dev_cac_dpad_think( "emblem", ::dev_cac_cycle_render_options, "emblem" );
|
||||
break;
|
||||
case "dpad_tag":
|
||||
host thread dev_cac_dpad_think( "tag", ::dev_cac_cycle_render_options, "tag" );
|
||||
break;
|
||||
case "dpad_facepaint_pattern":
|
||||
host thread dev_cac_dpad_think( "facepaint pattern", ::dev_cac_cycle_render_options, "facepaint_pattern" );
|
||||
break;
|
||||
case "dpad_facepaint_color":
|
||||
host thread dev_cac_dpad_think( "facepaint color", ::dev_cac_cycle_render_options, "facepaint_color" );
|
||||
break;
|
||||
case "dpad_reset":
|
||||
host notify( "dev_cac_dpad_think" );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( reset )
|
||||
setdvar( "devgui_dev_cac", "" );
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
dev_cac_camera( on )
|
||||
{
|
||||
/#
|
||||
if ( on )
|
||||
{
|
||||
self setclientthirdperson( 1 );
|
||||
setdvar( "cg_thirdPersonAngle", "185" );
|
||||
setdvar( "cg_thirdPersonRange", "138" );
|
||||
setdvar( "cg_fov", "20" );
|
||||
}
|
||||
else
|
||||
{
|
||||
self setclientthirdperson( 0 );
|
||||
setdvar( "cg_fov", getdvar( "cg_fov_default" ) );
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
dev_cac_dpad_think( part_name, cycle_function, tag )
|
||||
{
|
||||
/#
|
||||
self notify( "dev_cac_dpad_think" );
|
||||
self endon( "dev_cac_dpad_think" );
|
||||
self endon( "disconnect" );
|
||||
iprintln( "Previous " + part_name + " bound to D-Pad Left" );
|
||||
iprintln( "Next " + part_name + " bound to D-Pad Right" );
|
||||
dpad_left = 0;
|
||||
dpad_right = 0;
|
||||
level.dev_cac_player thread highlight_player();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self setactionslot( 3, "" );
|
||||
self setactionslot( 4, "" );
|
||||
|
||||
if ( !dpad_left && self buttonpressed( "DPAD_LEFT" ) )
|
||||
{
|
||||
[[ cycle_function ]]( 0, tag );
|
||||
dpad_left = 1;
|
||||
}
|
||||
else if ( !self buttonpressed( "DPAD_LEFT" ) )
|
||||
dpad_left = 0;
|
||||
|
||||
if ( !dpad_right && self buttonpressed( "DPAD_RIGHT" ) )
|
||||
{
|
||||
[[ cycle_function ]]( 1, tag );
|
||||
dpad_right = 1;
|
||||
}
|
||||
else if ( !self buttonpressed( "DPAD_RIGHT" ) )
|
||||
dpad_right = 0;
|
||||
|
||||
wait 0.05;
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
next_in_list( value, list )
|
||||
{
|
||||
/#
|
||||
if ( !isdefined( value ) )
|
||||
return list[0];
|
||||
|
||||
for ( i = 0; i < list.size; i++ )
|
||||
{
|
||||
if ( value == list[i] )
|
||||
{
|
||||
if ( isdefined( list[i + 1] ) )
|
||||
value = list[i + 1];
|
||||
else
|
||||
value = list[0];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
#/
|
||||
}
|
||||
|
||||
prev_in_list( value, list )
|
||||
{
|
||||
/#
|
||||
if ( !isdefined( value ) )
|
||||
return list[0];
|
||||
|
||||
for ( i = 0; i < list.size; i++ )
|
||||
{
|
||||
if ( value == list[i] )
|
||||
{
|
||||
if ( isdefined( list[i - 1] ) )
|
||||
value = list[i - 1];
|
||||
else
|
||||
value = list[list.size - 1];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
#/
|
||||
}
|
||||
|
||||
dev_cac_set_player_model()
|
||||
{
|
||||
/#
|
||||
self.tag_stowed_back = undefined;
|
||||
self.tag_stowed_hip = undefined;
|
||||
#/
|
||||
}
|
||||
|
||||
dev_cac_cycle_body( forward, tag )
|
||||
{
|
||||
/#
|
||||
if ( !dev_cac_player_valid() )
|
||||
return;
|
||||
|
||||
player = level.dev_cac_player;
|
||||
keys = getarraykeys( level.cac_functions["set_body_model"] );
|
||||
|
||||
if ( forward )
|
||||
player.cac_body_type = next_in_list( player.cac_body_type, keys );
|
||||
else
|
||||
player.cac_body_type = prev_in_list( player.cac_body_type, keys );
|
||||
|
||||
player dev_cac_set_player_model();
|
||||
#/
|
||||
}
|
||||
|
||||
dev_cac_cycle_head( forward, tag )
|
||||
{
|
||||
/#
|
||||
if ( !dev_cac_player_valid() )
|
||||
return;
|
||||
|
||||
player = level.dev_cac_player;
|
||||
keys = getarraykeys( level.cac_functions["set_head_model"] );
|
||||
|
||||
if ( forward )
|
||||
player.cac_head_type = next_in_list( player.cac_head_type, keys );
|
||||
else
|
||||
player.cac_head_type = prev_in_list( player.cac_head_type, keys );
|
||||
|
||||
player.cac_hat_type = "none";
|
||||
player dev_cac_set_player_model();
|
||||
#/
|
||||
}
|
||||
|
||||
dev_cac_cycle_character( forward, tag )
|
||||
{
|
||||
/#
|
||||
if ( !dev_cac_player_valid() )
|
||||
return;
|
||||
|
||||
player = level.dev_cac_player;
|
||||
keys = getarraykeys( level.cac_functions["set_body_model"] );
|
||||
|
||||
if ( forward )
|
||||
player.cac_body_type = next_in_list( player.cac_body_type, keys );
|
||||
else
|
||||
player.cac_body_type = prev_in_list( player.cac_body_type, keys );
|
||||
|
||||
player.cac_hat_type = "none";
|
||||
player dev_cac_set_player_model();
|
||||
#/
|
||||
}
|
||||
|
||||
dev_cac_cycle_render_options( forward, tag )
|
||||
{
|
||||
/#
|
||||
if ( !dev_cac_player_valid() )
|
||||
return;
|
||||
|
||||
level.dev_cac_player nextplayerrenderoption( tag, forward );
|
||||
#/
|
||||
}
|
||||
|
||||
dev_cac_player_valid()
|
||||
{
|
||||
/#
|
||||
return isdefined( level.dev_cac_player ) && level.dev_cac_player.sessionstate == "playing";
|
||||
#/
|
||||
}
|
||||
|
||||
dev_cac_cycle_player( forward )
|
||||
{
|
||||
/#
|
||||
players = get_players();
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
if ( forward )
|
||||
level.dev_cac_player = next_in_list( level.dev_cac_player, players );
|
||||
else
|
||||
level.dev_cac_player = prev_in_list( level.dev_cac_player, players );
|
||||
|
||||
if ( dev_cac_player_valid() )
|
||||
{
|
||||
level.dev_cac_player thread highlight_player();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
level.dev_cac_player = undefined;
|
||||
#/
|
||||
}
|
||||
|
||||
highlight_player()
|
||||
{
|
||||
/#
|
||||
self sethighlighted( 1 );
|
||||
wait 1.0;
|
||||
self sethighlighted( 0 );
|
||||
#/
|
||||
}
|
||||
|
||||
dev_cac_overlay_think()
|
||||
{
|
||||
/#
|
||||
hud = dev_cac_overlay_create();
|
||||
level thread dev_cac_overlay_update( hud );
|
||||
|
||||
level waittill( "dev_cac_overlay_think" );
|
||||
|
||||
dev_cac_overlay_destroy( hud );
|
||||
#/
|
||||
}
|
||||
|
||||
dev_cac_overlay_update( hud )
|
||||
{
|
||||
/#
|
||||
|
||||
#/
|
||||
}
|
||||
|
||||
dev_cac_overlay_destroy( hud )
|
||||
{
|
||||
/#
|
||||
for ( i = 0; i < hud.menu.size; i++ )
|
||||
hud.menu[i] destroy();
|
||||
|
||||
hud destroy();
|
||||
setdvar( "player_debugSprint", "0" );
|
||||
#/
|
||||
}
|
||||
|
||||
dev_cac_overlay_create()
|
||||
{
|
||||
/#
|
||||
x = -80;
|
||||
y = 140;
|
||||
menu_name = "dev_cac_debug";
|
||||
hud = maps\mp\gametypes\_dev::new_hud( menu_name, undefined, x, y, 1 );
|
||||
hud setshader( "white", 185, 285 );
|
||||
hud.alignx = "left";
|
||||
hud.aligny = "top";
|
||||
hud.sort = 10;
|
||||
hud.alpha = 0.6;
|
||||
hud.color = vectorscale( ( 0, 0, 1 ), 0.5 );
|
||||
x_offset = 100;
|
||||
hud.menu[0] = maps\mp\gametypes\_dev::new_hud( menu_name, "NAME", x + 5, y + 10, 1.3 );
|
||||
hud.menu[1] = maps\mp\gametypes\_dev::new_hud( menu_name, "MODELS", x + 5, y + 25, 1 );
|
||||
hud.menu[2] = maps\mp\gametypes\_dev::new_hud( menu_name, " Body:", x + 5, y + 35, 1 );
|
||||
hud.menu[3] = maps\mp\gametypes\_dev::new_hud( menu_name, " Head:", x + 5, y + 45, 1 );
|
||||
hud.menu[4] = maps\mp\gametypes\_dev::new_hud( menu_name, " Head Gear:", x + 5, y + 55, 1 );
|
||||
hud.menu[5] = maps\mp\gametypes\_dev::new_hud( menu_name, "MOBILITY", x + 5, y + 70, 1 );
|
||||
hud.menu[6] = maps\mp\gametypes\_dev::new_hud( menu_name, " Body:", x + 5, y + 80, 1 );
|
||||
hud.menu[7] = maps\mp\gametypes\_dev::new_hud( menu_name, " Head Gear:", x + 5, y + 90, 1 );
|
||||
hud.menu[8] = maps\mp\gametypes\_dev::new_hud( menu_name, " Speed Scale:", x + 5, y + 100, 1 );
|
||||
hud.menu[9] = maps\mp\gametypes\_dev::new_hud( menu_name, " Sprint Duration:", x + 5, y + 110, 1 );
|
||||
hud.menu[10] = maps\mp\gametypes\_dev::new_hud( menu_name, " Sprint Cooldown:", x + 5, y + 120, 1 );
|
||||
hud.menu[11] = maps\mp\gametypes\_dev::new_hud( menu_name, "ARMOR - BULLET", x + 5, y + 135, 1 );
|
||||
hud.menu[12] = maps\mp\gametypes\_dev::new_hud( menu_name, " Body:", x + 5, y + 145, 1 );
|
||||
hud.menu[13] = maps\mp\gametypes\_dev::new_hud( menu_name, " Head Gear:", x + 5, y + 155, 1 );
|
||||
hud.menu[14] = maps\mp\gametypes\_dev::new_hud( menu_name, "ARMOR - EXPLOSIVE", x + 5, y + 170, 1 );
|
||||
hud.menu[15] = maps\mp\gametypes\_dev::new_hud( menu_name, " Body:", x + 5, y + 180, 1 );
|
||||
hud.menu[16] = maps\mp\gametypes\_dev::new_hud( menu_name, " Head Gear:", x + 5, y + 190, 1 );
|
||||
hud.menu[17] = maps\mp\gametypes\_dev::new_hud( menu_name, "DAMAGE", x + 5, y + 205, 1 );
|
||||
hud.menu[18] = maps\mp\gametypes\_dev::new_hud( menu_name, " Type:", x + 5, y + 215, 1 );
|
||||
hud.menu[19] = maps\mp\gametypes\_dev::new_hud( menu_name, " Original:", x + 5, y + 225, 1 );
|
||||
hud.menu[20] = maps\mp\gametypes\_dev::new_hud( menu_name, " Final:", x + 5, y + 235, 1 );
|
||||
hud.menu[21] = maps\mp\gametypes\_dev::new_hud( menu_name, " Gain/Loss:", x + 5, y + 245, 1 );
|
||||
hud.menu[22] = maps\mp\gametypes\_dev::new_hud( menu_name, " Location:", x + 5, y + 255, 1 );
|
||||
hud.menu[23] = maps\mp\gametypes\_dev::new_hud( menu_name, " Weapon:", x + 5, y + 265, 1 );
|
||||
hud.menu[24] = maps\mp\gametypes\_dev::new_hud( menu_name, " Range:", x + 5, y + 275, 1 );
|
||||
x_offset = 65;
|
||||
hud.menu[25] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 35, 1 );
|
||||
hud.menu[26] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 45, 1 );
|
||||
hud.menu[27] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 55, 1 );
|
||||
x_offset = 100;
|
||||
hud.menu[28] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 80, 1 );
|
||||
hud.menu[29] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 90, 1 );
|
||||
hud.menu[30] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 100, 1 );
|
||||
hud.menu[31] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 110, 1 );
|
||||
hud.menu[32] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 120, 1 );
|
||||
hud.menu[33] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 145, 1 );
|
||||
hud.menu[34] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 155, 1 );
|
||||
hud.menu[35] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 180, 1 );
|
||||
hud.menu[36] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 190, 1 );
|
||||
x_offset = 65;
|
||||
hud.menu[37] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 215, 1 );
|
||||
hud.menu[38] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 225, 1 );
|
||||
hud.menu[39] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 235, 1 );
|
||||
hud.menu[40] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 245, 1 );
|
||||
hud.menu[41] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 255, 1 );
|
||||
hud.menu[42] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 265, 1 );
|
||||
hud.menu[43] = maps\mp\gametypes\_dev::new_hud( menu_name, "", x + x_offset, y + 275, 1 );
|
||||
return hud;
|
||||
#/
|
||||
}
|
||||
|
||||
color( value )
|
||||
{
|
||||
/#
|
||||
r = 1;
|
||||
g = 1;
|
||||
b = 0;
|
||||
color = ( 0, 0, 0 );
|
||||
|
||||
if ( value > 0 )
|
||||
r -= value;
|
||||
else
|
||||
g += value;
|
||||
|
||||
c = ( r, g, b );
|
||||
return c;
|
||||
#/
|
||||
}
|
||||
|
||||
dev_cac_gdt_update_think()
|
||||
{
|
||||
/#
|
||||
for (;;)
|
||||
{
|
||||
level waittill( "gdt_update", asset, keyvalue );
|
||||
|
||||
keyvalue = strtok( keyvalue, "\\" );
|
||||
key = keyvalue[0];
|
||||
|
||||
switch ( key )
|
||||
{
|
||||
case "armorBullet":
|
||||
key = "armor_bullet";
|
||||
break;
|
||||
case "armorExplosive":
|
||||
key = "armor_explosive";
|
||||
break;
|
||||
case "moveSpeed":
|
||||
key = "mobility";
|
||||
break;
|
||||
case "sprintTimeTotal":
|
||||
key = "sprint_time_total";
|
||||
break;
|
||||
case "sprintTimeCooldown":
|
||||
key = "sprint_time_cooldown";
|
||||
break;
|
||||
default:
|
||||
key = undefined;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !isdefined( key ) )
|
||||
continue;
|
||||
|
||||
value = float( keyvalue[1] );
|
||||
level.cac_attributes[key][asset] = value;
|
||||
players = get_players();
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
#/
|
||||
}
|
||||
|
||||
sort_greatest( function, attribute, greatest )
|
||||
{
|
||||
/#
|
||||
keys = getarraykeys( level.cac_functions[function] );
|
||||
greatest = keys[0];
|
||||
|
||||
for ( i = 0; i < keys.size; i++ )
|
||||
{
|
||||
if ( level.cac_attributes[attribute][keys[i]] > level.cac_attributes[attribute][greatest] )
|
||||
greatest = keys[i];
|
||||
}
|
||||
|
||||
return greatest;
|
||||
#/
|
||||
}
|
||||
|
||||
sort_least( function, attribute, least )
|
||||
{
|
||||
/#
|
||||
keys = getarraykeys( level.cac_functions[function] );
|
||||
least = keys[0];
|
||||
|
||||
for ( i = 0; i < keys.size; i++ )
|
||||
{
|
||||
if ( level.cac_attributes[attribute][keys[i]] < level.cac_attributes[attribute][least] )
|
||||
least = keys[i];
|
||||
}
|
||||
|
||||
return least;
|
||||
#/
|
||||
}
|
||||
|
||||
dev_cac_set_model_range( sort_function, attribute )
|
||||
{
|
||||
/#
|
||||
if ( !dev_cac_player_valid() )
|
||||
return;
|
||||
|
||||
player = level.dev_cac_player;
|
||||
player.cac_body_type = [[ sort_function ]]( "set_body_model", attribute );
|
||||
player.cac_head_type = [[ sort_function ]]( "set_head_model", attribute );
|
||||
player.cac_hat_type = [[ sort_function ]]( "set_hat_model", attribute );
|
||||
player dev_cac_set_player_model();
|
||||
#/
|
||||
}
|
111
MP/Core/maps/mp/gametypes/_friendicons.gsc
Normal file
111
MP/Core/maps/mp/gametypes/_friendicons.gsc
Normal file
@ -0,0 +1,111 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
|
||||
init()
|
||||
{
|
||||
if ( level.createfx_enabled || sessionmodeiszombiesgame() )
|
||||
return;
|
||||
|
||||
if ( getdvar( "scr_drawfriend" ) == "" )
|
||||
setdvar( "scr_drawfriend", "0" );
|
||||
|
||||
level.drawfriend = getdvarint( "scr_drawfriend" );
|
||||
assert( isdefined( game["headicon_allies"] ), "Allied head icons are not defined. Check the team set for the level." );
|
||||
assert( isdefined( game["headicon_axis"] ), "Axis head icons are not defined. Check the team set for the level." );
|
||||
precacheheadicon( game["headicon_allies"] );
|
||||
precacheheadicon( game["headicon_axis"] );
|
||||
level thread onplayerconnect();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
updatefriendiconsettings();
|
||||
wait 5;
|
||||
}
|
||||
}
|
||||
|
||||
onplayerconnect()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
level waittill( "connecting", player );
|
||||
|
||||
player thread onplayerspawned();
|
||||
player thread onplayerkilled();
|
||||
}
|
||||
}
|
||||
|
||||
onplayerspawned()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "spawned_player" );
|
||||
|
||||
self thread showfriendicon();
|
||||
}
|
||||
}
|
||||
|
||||
onplayerkilled()
|
||||
{
|
||||
self endon( "disconnect" );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
self waittill( "killed_player" );
|
||||
|
||||
self.headicon = "";
|
||||
}
|
||||
}
|
||||
|
||||
showfriendicon()
|
||||
{
|
||||
if ( level.drawfriend )
|
||||
{
|
||||
team = self.pers["team"];
|
||||
self.headicon = game["headicon_" + team];
|
||||
self.headiconteam = team;
|
||||
}
|
||||
}
|
||||
|
||||
updatefriendiconsettings()
|
||||
{
|
||||
drawfriend = getdvarfloat( "scr_drawfriend" );
|
||||
|
||||
if ( level.drawfriend != drawfriend )
|
||||
{
|
||||
level.drawfriend = drawfriend;
|
||||
updatefriendicons();
|
||||
}
|
||||
}
|
||||
|
||||
updatefriendicons()
|
||||
{
|
||||
players = level.players;
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
player = players[i];
|
||||
|
||||
if ( isdefined( player.pers["team"] ) && player.pers["team"] != "spectator" && player.sessionstate == "playing" )
|
||||
{
|
||||
if ( level.drawfriend )
|
||||
{
|
||||
team = self.pers["team"];
|
||||
self.headicon = game["headicon_" + team];
|
||||
self.headiconteam = team;
|
||||
continue;
|
||||
}
|
||||
|
||||
players = level.players;
|
||||
|
||||
for ( i = 0; i < players.size; i++ )
|
||||
{
|
||||
player = players[i];
|
||||
|
||||
if ( isdefined( player.pers["team"] ) && player.pers["team"] != "spectator" && player.sessionstate == "playing" )
|
||||
player.headicon = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2556
MP/Core/maps/mp/gametypes/_gameobjects.gsc
Normal file
2556
MP/Core/maps/mp/gametypes/_gameobjects.gsc
Normal file
File diff suppressed because it is too large
Load Diff
3
MP/Core/maps/mp/gametypes/_globalentities.gsc
Normal file
3
MP/Core/maps/mp/gametypes/_globalentities.gsc
Normal file
@ -0,0 +1,3 @@
|
||||
// T6 GSC SOURCE
|
||||
// Decompiled by https://github.com/xensik/gsc-tool
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user