mirror of
https://github.com/JezuzLizard/Public-BO2-Mods.git
synced 2025-06-08 02:58:24 -05:00
added more files
This commit is contained in:
parent
80ffa1a3d7
commit
18b75a333d
@ -0,0 +1,523 @@
|
|||||||
|
#include maps/mp/gametypes_zm/_spawnlogic;
|
||||||
|
#include maps/mp/animscripts/traverse/shared;
|
||||||
|
#include maps/mp/animscripts/utility;
|
||||||
|
#include maps/mp/zombies/_load;
|
||||||
|
#include maps/mp/_createfx;
|
||||||
|
#include maps/mp/_music;
|
||||||
|
#include maps/mp/_busing;
|
||||||
|
#include maps/mp/_script_gen;
|
||||||
|
#include maps/mp/_utility;
|
||||||
|
#include common_scripts/utility;
|
||||||
|
|
||||||
|
main( bscriptgened, bcsvgened, bsgenabled )
|
||||||
|
{
|
||||||
|
if ( !isDefined( level.script_gen_dump_reasons ) )
|
||||||
|
{
|
||||||
|
level.script_gen_dump_reasons = [];
|
||||||
|
}
|
||||||
|
if ( !isDefined( bsgenabled ) )
|
||||||
|
{
|
||||||
|
level.script_gen_dump_reasons[ level.script_gen_dump_reasons.size ] = "First run";
|
||||||
|
}
|
||||||
|
if ( !isDefined( bcsvgened ) )
|
||||||
|
{
|
||||||
|
bcsvgened = 0;
|
||||||
|
}
|
||||||
|
level.bcsvgened = bcsvgened;
|
||||||
|
if ( !isDefined( bscriptgened ) )
|
||||||
|
{
|
||||||
|
bscriptgened = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bscriptgened = 1;
|
||||||
|
}
|
||||||
|
level.bscriptgened = bscriptgened;
|
||||||
|
level._loadstarted = 1;
|
||||||
|
struct_class_init();
|
||||||
|
level.clientscripts = getDvar( "cg_usingClientScripts" ) != "";
|
||||||
|
level._client_exploders = [];
|
||||||
|
level._client_exploder_ids = [];
|
||||||
|
if ( !isDefined( level.flag ) )
|
||||||
|
{
|
||||||
|
level.flag = [];
|
||||||
|
level.flags_lock = [];
|
||||||
|
}
|
||||||
|
if ( !isDefined( level.timeofday ) )
|
||||||
|
{
|
||||||
|
level.timeofday = "day";
|
||||||
|
}
|
||||||
|
flag_init( "scriptgen_done" );
|
||||||
|
level.script_gen_dump_reasons = [];
|
||||||
|
if ( !isDefined( level.script_gen_dump ) )
|
||||||
|
{
|
||||||
|
level.script_gen_dump = [];
|
||||||
|
level.script_gen_dump_reasons[ 0 ] = "First run";
|
||||||
|
}
|
||||||
|
if ( !isDefined( level.script_gen_dump2 ) )
|
||||||
|
{
|
||||||
|
level.script_gen_dump2 = [];
|
||||||
|
}
|
||||||
|
if ( isDefined( level.createfxent ) && isDefined( level.script ) )
|
||||||
|
{
|
||||||
|
script_gen_dump_addline( "maps\\mp\\createfx\\" + level.script + "_fx::main();", level.script + "_fx" );
|
||||||
|
}
|
||||||
|
while ( isDefined( level.script_gen_dump_preload ) )
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
while ( i < level.script_gen_dump_preload.size )
|
||||||
|
{
|
||||||
|
script_gen_dump_addline( level.script_gen_dump_preload[ i ].string, level.script_gen_dump_preload[ i ].signature );
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( getDvar( "scr_RequiredMapAspectratio" ) == "" )
|
||||||
|
{
|
||||||
|
setdvar( "scr_RequiredMapAspectratio", "1" );
|
||||||
|
}
|
||||||
|
setdvar( "r_waterFogTest", 0 );
|
||||||
|
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" ) != "";
|
||||||
|
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();
|
||||||
|
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();
|
||||||
|
p = 0;
|
||||||
|
while ( p < 6 )
|
||||||
|
{
|
||||||
|
switch( p )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
triggertype = "trigger_multiple";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
triggertype = "trigger_once";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
triggertype = "trigger_use";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
triggertype = "trigger_radius";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
triggertype = "trigger_lookat";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
assert( p == 5 );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
triggertype = "trigger_damage";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
triggers = getentarray( triggertype, "classname" );
|
||||||
|
i = 0;
|
||||||
|
while ( i < triggers.size )
|
||||||
|
{
|
||||||
|
if ( isDefined( triggers[ i ].script_prefab_exploder ) )
|
||||||
|
{
|
||||||
|
triggers[ i ].script_exploder = triggers[ i ].script_prefab_exploder;
|
||||||
|
}
|
||||||
|
if ( isDefined( triggers[ i ].script_exploder ) )
|
||||||
|
{
|
||||||
|
level thread maps/mp/zombies/_load::exploder_load( triggers[ i ] );
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
level_notify_listener()
|
||||||
|
{
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
val = getDvar( "level_notify" );
|
||||||
|
if ( val != "" )
|
||||||
|
{
|
||||||
|
level notify( val );
|
||||||
|
setdvar( "level_notify", "" );
|
||||||
|
}
|
||||||
|
wait 0.2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
client_notify_listener()
|
||||||
|
{
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
val = getDvar( "client_notify" );
|
||||||
|
if ( val != "" )
|
||||||
|
{
|
||||||
|
clientnotify( val );
|
||||||
|
setdvar( "client_notify", "" );
|
||||||
|
}
|
||||||
|
wait 0.2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footsteps()
|
||||||
|
{
|
||||||
|
if ( is_true( level.fx_exclude_footsteps ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
maps/mp/animscripts/utility::setfootstepeffect( "asphalt", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||||
|
maps/mp/animscripts/utility::setfootstepeffect( "brick", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||||
|
maps/mp/animscripts/utility::setfootstepeffect( "carpet", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||||
|
maps/mp/animscripts/utility::setfootstepeffect( "cloth", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||||
|
maps/mp/animscripts/utility::setfootstepeffect( "concrete", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||||
|
maps/mp/animscripts/utility::setfootstepeffect( "dirt", loadfx( "bio/player/fx_footstep_sand" ) );
|
||||||
|
maps/mp/animscripts/utility::setfootstepeffect( "foliage", loadfx( "bio/player/fx_footstep_sand" ) );
|
||||||
|
maps/mp/animscripts/utility::setfootstepeffect( "gravel", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||||
|
maps/mp/animscripts/utility::setfootstepeffect( "grass", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||||
|
maps/mp/animscripts/utility::setfootstepeffect( "metal", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||||
|
maps/mp/animscripts/utility::setfootstepeffect( "mud", loadfx( "bio/player/fx_footstep_mud" ) );
|
||||||
|
maps/mp/animscripts/utility::setfootstepeffect( "paper", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||||
|
maps/mp/animscripts/utility::setfootstepeffect( "plaster", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||||
|
maps/mp/animscripts/utility::setfootstepeffect( "rock", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||||
|
maps/mp/animscripts/utility::setfootstepeffect( "sand", loadfx( "bio/player/fx_footstep_sand" ) );
|
||||||
|
maps/mp/animscripts/utility::setfootstepeffect( "water", loadfx( "bio/player/fx_footstep_water" ) );
|
||||||
|
maps/mp/animscripts/utility::setfootstepeffect( "wood", loadfx( "bio/player/fx_footstep_dust" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_structs()
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
while ( i < level.struct.size )
|
||||||
|
{
|
||||||
|
if ( isDefined( level.struct[ i ].targetname ) )
|
||||||
|
{
|
||||||
|
if ( level.struct[ i ].targetname == "flak_fire_fx" )
|
||||||
|
{
|
||||||
|
level._effect[ "flak20_fire_fx" ] = loadfx( "weapon/tracer/fx_tracer_flak_single_noExp" );
|
||||||
|
level._effect[ "flak38_fire_fx" ] = loadfx( "weapon/tracer/fx_tracer_quad_20mm_Flak38_noExp" );
|
||||||
|
level._effect[ "flak_cloudflash_night" ] = loadfx( "weapon/flak/fx_flak_cloudflash_night" );
|
||||||
|
level._effect[ "flak_burst_single" ] = loadfx( "weapon/flak/fx_flak_single_day_dist" );
|
||||||
|
}
|
||||||
|
if ( level.struct[ i ].targetname == "fake_fire_fx" )
|
||||||
|
{
|
||||||
|
level._effect[ "distant_muzzleflash" ] = loadfx( "weapon/muzzleflashes/heavy" );
|
||||||
|
}
|
||||||
|
if ( level.struct[ i ].targetname == "spotlight_fx" )
|
||||||
|
{
|
||||||
|
level._effect[ "spotlight_beam" ] = loadfx( "env/light/fx_ray_spotlight_md" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exploder_load( trigger )
|
||||||
|
{
|
||||||
|
level endon( "killexplodertridgers" + trigger.script_exploder );
|
||||||
|
trigger waittill( "trigger" );
|
||||||
|
if ( isDefined( trigger.script_chance ) && randomfloat( 1 ) > trigger.script_chance )
|
||||||
|
{
|
||||||
|
if ( isDefined( trigger.script_delay ) )
|
||||||
|
{
|
||||||
|
wait trigger.script_delay;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wait 4;
|
||||||
|
}
|
||||||
|
level thread exploder_load( trigger );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
maps/mp/_utility::exploder( trigger.script_exploder );
|
||||||
|
level notify( "killexplodertridgers" + trigger.script_exploder );
|
||||||
|
}
|
||||||
|
|
||||||
|
setupexploders()
|
||||||
|
{
|
||||||
|
ents = getentarray( "script_brushmodel", "classname" );
|
||||||
|
smodels = getentarray( "script_model", "classname" );
|
||||||
|
i = 0;
|
||||||
|
while ( i < smodels.size )
|
||||||
|
{
|
||||||
|
ents[ ents.size ] = smodels[ i ];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
while ( i < ents.size )
|
||||||
|
{
|
||||||
|
if ( isDefined( ents[ i ].script_prefab_exploder ) )
|
||||||
|
{
|
||||||
|
ents[ i ].script_exploder = ents[ i ].script_prefab_exploder;
|
||||||
|
}
|
||||||
|
if ( isDefined( ents[ i ].script_exploder ) )
|
||||||
|
{
|
||||||
|
if ( ents[ i ].model == "fx" || !isDefined( ents[ i ].targetname ) && ents[ i ].targetname != "exploderchunk" )
|
||||||
|
{
|
||||||
|
ents[ i ] hide();
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( isDefined( ents[ i ].targetname ) && ents[ i ].targetname == "exploder" )
|
||||||
|
{
|
||||||
|
ents[ i ] hide();
|
||||||
|
ents[ i ] notsolid();
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( isDefined( ents[ i ].targetname ) && ents[ i ].targetname == "exploderchunk" )
|
||||||
|
{
|
||||||
|
ents[ i ] hide();
|
||||||
|
ents[ i ] notsolid();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
script_exploders = [];
|
||||||
|
potentialexploders = getentarray( "script_brushmodel", "classname" );
|
||||||
|
i = 0;
|
||||||
|
while ( i < potentialexploders.size )
|
||||||
|
{
|
||||||
|
if ( isDefined( potentialexploders[ i ].script_prefab_exploder ) )
|
||||||
|
{
|
||||||
|
potentialexploders[ i ].script_exploder = potentialexploders[ i ].script_prefab_exploder;
|
||||||
|
}
|
||||||
|
if ( isDefined( potentialexploders[ i ].script_exploder ) )
|
||||||
|
{
|
||||||
|
script_exploders[ script_exploders.size ] = potentialexploders[ i ];
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
potentialexploders = getentarray( "script_model", "classname" );
|
||||||
|
i = 0;
|
||||||
|
while ( i < potentialexploders.size )
|
||||||
|
{
|
||||||
|
if ( isDefined( potentialexploders[ i ].script_prefab_exploder ) )
|
||||||
|
{
|
||||||
|
potentialexploders[ i ].script_exploder = potentialexploders[ i ].script_prefab_exploder;
|
||||||
|
}
|
||||||
|
if ( isDefined( potentialexploders[ i ].script_exploder ) )
|
||||||
|
{
|
||||||
|
script_exploders[ script_exploders.size ] = potentialexploders[ i ];
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
potentialexploders = getentarray( "item_health", "classname" );
|
||||||
|
i = 0;
|
||||||
|
while ( i < potentialexploders.size )
|
||||||
|
{
|
||||||
|
if ( isDefined( potentialexploders[ i ].script_prefab_exploder ) )
|
||||||
|
{
|
||||||
|
potentialexploders[ i ].script_exploder = potentialexploders[ i ].script_prefab_exploder;
|
||||||
|
}
|
||||||
|
if ( isDefined( potentialexploders[ i ].script_exploder ) )
|
||||||
|
{
|
||||||
|
script_exploders[ script_exploders.size ] = potentialexploders[ i ];
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if ( !isDefined( level.createfxent ) )
|
||||||
|
{
|
||||||
|
level.createfxent = [];
|
||||||
|
}
|
||||||
|
acceptabletargetnames = [];
|
||||||
|
acceptabletargetnames[ "exploderchunk visible" ] = 1;
|
||||||
|
acceptabletargetnames[ "exploderchunk" ] = 1;
|
||||||
|
acceptabletargetnames[ "exploder" ] = 1;
|
||||||
|
i = 0;
|
||||||
|
while ( i < script_exploders.size )
|
||||||
|
{
|
||||||
|
exploder = script_exploders[ i ];
|
||||||
|
ent = createexploder( exploder.script_fxid );
|
||||||
|
ent.v = [];
|
||||||
|
ent.v[ "origin" ] = exploder.origin;
|
||||||
|
ent.v[ "angles" ] = exploder.angles;
|
||||||
|
ent.v[ "delay" ] = exploder.script_delay;
|
||||||
|
ent.v[ "firefx" ] = exploder.script_firefx;
|
||||||
|
ent.v[ "firefxdelay" ] = exploder.script_firefxdelay;
|
||||||
|
ent.v[ "firefxsound" ] = exploder.script_firefxsound;
|
||||||
|
ent.v[ "firefxtimeout" ] = exploder.script_firefxtimeout;
|
||||||
|
ent.v[ "earthquake" ] = exploder.script_earthquake;
|
||||||
|
ent.v[ "damage" ] = exploder.script_damage;
|
||||||
|
ent.v[ "damage_radius" ] = exploder.script_radius;
|
||||||
|
ent.v[ "soundalias" ] = exploder.script_soundalias;
|
||||||
|
ent.v[ "repeat" ] = exploder.script_repeat;
|
||||||
|
ent.v[ "delay_min" ] = exploder.script_delay_min;
|
||||||
|
ent.v[ "delay_max" ] = exploder.script_delay_max;
|
||||||
|
ent.v[ "target" ] = exploder.target;
|
||||||
|
ent.v[ "ender" ] = exploder.script_ender;
|
||||||
|
ent.v[ "type" ] = "exploder";
|
||||||
|
if ( !isDefined( exploder.script_fxid ) )
|
||||||
|
{
|
||||||
|
ent.v[ "fxid" ] = "No FX";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ent.v[ "fxid" ] = exploder.script_fxid;
|
||||||
|
}
|
||||||
|
ent.v[ "exploder" ] = exploder.script_exploder;
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
assert( isDefined( exploder.script_exploder ), "Exploder at origin " + exploder.origin + " has no script_exploder" );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
if ( !isDefined( ent.v[ "delay" ] ) )
|
||||||
|
{
|
||||||
|
ent.v[ "delay" ] = 0;
|
||||||
|
}
|
||||||
|
if ( isDefined( exploder.target ) )
|
||||||
|
{
|
||||||
|
org = getent( ent.v[ "target" ], "targetname" ).origin;
|
||||||
|
ent.v[ "angles" ] = 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();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
level.createfxexploders = [];
|
||||||
|
i = 0;
|
||||||
|
while ( i < level.createfxent.size )
|
||||||
|
{
|
||||||
|
ent = level.createfxent[ i ];
|
||||||
|
if ( ent.v[ "type" ] != "exploder" )
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ent.v[ "exploder_id" ] = getexploderid( ent );
|
||||||
|
if ( !isDefined( level.createfxexploders[ ent.v[ "exploder" ] ] ) )
|
||||||
|
{
|
||||||
|
level.createfxexploders[ ent.v[ "exploder" ] ] = [];
|
||||||
|
}
|
||||||
|
level.createfxexploders[ ent.v[ "exploder" ] ][ level.createfxexploders[ ent.v[ "exploder" ] ].size ] = ent;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_traversals()
|
||||||
|
{
|
||||||
|
potential_traverse_nodes = getallnodes();
|
||||||
|
i = 0;
|
||||||
|
while ( i < potential_traverse_nodes.size )
|
||||||
|
{
|
||||||
|
node = potential_traverse_nodes[ i ];
|
||||||
|
if ( node.type == "Begin" )
|
||||||
|
{
|
||||||
|
node maps/mp/animscripts/traverse/shared::init_traverse();
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
calculate_map_center()
|
||||||
|
{
|
||||||
|
if ( !isDefined( level.mapcenter ) )
|
||||||
|
{
|
||||||
|
level.nodesmins = ( 0, 0, 0 );
|
||||||
|
level.nodesmaxs = ( 0, 0, 0 );
|
||||||
|
level.mapcenter = maps/mp/gametypes_zm/_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 );
|
||||||
|
level.introscreen.immunetodemogamehudsettings = 1;
|
||||||
|
level.introscreen.immunetodemofreecamera = 1;
|
||||||
|
wait 0.05;
|
||||||
|
}
|
||||||
|
level.introscreen.alpha = 1;
|
||||||
|
players = get_players();
|
||||||
|
i = 0;
|
||||||
|
while ( i < players.size )
|
||||||
|
{
|
||||||
|
players[ i ] freezecontrols( 1 );
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
wait 1;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,571 @@
|
|||||||
|
#include maps/mp/animscripts/zm_shared;
|
||||||
|
#include maps/mp/animscripts/zm_run;
|
||||||
|
#include maps/mp/zombies/_zm_ai_basic;
|
||||||
|
#include maps/mp/zombies/_zm_spawner;
|
||||||
|
#include maps/mp/zombies/_zm_utility;
|
||||||
|
#include maps/mp/_utility;
|
||||||
|
#include common_scripts/utility;
|
||||||
|
|
||||||
|
find_flesh()
|
||||||
|
{
|
||||||
|
self endon( "death" );
|
||||||
|
level endon( "intermission" );
|
||||||
|
self endon( "stop_find_flesh" );
|
||||||
|
if ( level.intermission )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.ai_state = "find_flesh";
|
||||||
|
self.helitarget = 1;
|
||||||
|
self.ignoreme = 0;
|
||||||
|
self.nododgemove = 1;
|
||||||
|
self.ignore_player = [];
|
||||||
|
self maps/mp/zombies/_zm_spawner::zombie_history( "find flesh -> start" );
|
||||||
|
self.goalradius = 32;
|
||||||
|
if ( isDefined( self.custom_goalradius_override ) )
|
||||||
|
{
|
||||||
|
self.goalradius = self.custom_goalradius_override;
|
||||||
|
}
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
zombie_poi = undefined;
|
||||||
|
if ( isDefined( level.zombietheaterteleporterseeklogicfunc ) )
|
||||||
|
{
|
||||||
|
self [[ level.zombietheaterteleporterseeklogicfunc ]]();
|
||||||
|
}
|
||||||
|
if ( isDefined( level._poi_override ) )
|
||||||
|
{
|
||||||
|
zombie_poi = self [[ level._poi_override ]]();
|
||||||
|
}
|
||||||
|
if ( !isDefined( zombie_poi ) )
|
||||||
|
{
|
||||||
|
zombie_poi = self get_zombie_point_of_interest( self.origin );
|
||||||
|
}
|
||||||
|
players = get_players();
|
||||||
|
if ( !isDefined( self.ignore_player ) || players.size == 1 )
|
||||||
|
{
|
||||||
|
self.ignore_player = [];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while ( !isDefined( level._should_skip_ignore_player_logic ) || !( [[ level._should_skip_ignore_player_logic ]]() ) )
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
while ( i < self.ignore_player.size )
|
||||||
|
{
|
||||||
|
while ( isDefined( self.ignore_player[ i ] ) && isDefined( self.ignore_player[ i ].ignore_counter ) && self.ignore_player[ i ].ignore_counter > 3 )
|
||||||
|
{
|
||||||
|
self.ignore_player[ i ].ignore_counter = 0;
|
||||||
|
self.ignore_player = arrayremovevalue( self.ignore_player, self.ignore_player[ i ] );
|
||||||
|
if ( !isDefined( self.ignore_player ) )
|
||||||
|
{
|
||||||
|
self.ignore_player = [];
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
player = get_closest_valid_player( self.origin, self.ignore_player );
|
||||||
|
while ( !isDefined( player ) && !isDefined( zombie_poi ) )
|
||||||
|
{
|
||||||
|
self maps/mp/zombies/_zm_spawner::zombie_history( "find flesh -> can't find player, continue" );
|
||||||
|
if ( isDefined( self.ignore_player ) )
|
||||||
|
{
|
||||||
|
while ( isDefined( level._should_skip_ignore_player_logic ) && [[ level._should_skip_ignore_player_logic ]]() )
|
||||||
|
{
|
||||||
|
wait 1;
|
||||||
|
}
|
||||||
|
self.ignore_player = [];
|
||||||
|
}
|
||||||
|
wait 1;
|
||||||
|
}
|
||||||
|
if ( !isDefined( level.check_for_alternate_poi ) || !( [[ level.check_for_alternate_poi ]]() ) )
|
||||||
|
{
|
||||||
|
self.enemyoverride = zombie_poi;
|
||||||
|
self.favoriteenemy = player;
|
||||||
|
}
|
||||||
|
self thread zombie_pathing();
|
||||||
|
while ( players.size > 1 )
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
while ( i < self.ignore_player.size )
|
||||||
|
{
|
||||||
|
if ( isDefined( self.ignore_player[ i ] ) )
|
||||||
|
{
|
||||||
|
if ( !isDefined( self.ignore_player[ i ].ignore_counter ) )
|
||||||
|
{
|
||||||
|
self.ignore_player[ i ].ignore_counter = 0;
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self.ignore_player[ i ].ignore_counter += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self thread attractors_generated_listener();
|
||||||
|
if ( isDefined( level._zombie_path_timer_override ) )
|
||||||
|
{
|
||||||
|
self.zombie_path_timer = [[ level._zombie_path_timer_override ]]();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self.zombie_path_timer = getTime() + ( randomfloatrange( 1, 3 ) * 1000 );
|
||||||
|
}
|
||||||
|
while ( getTime() < self.zombie_path_timer )
|
||||||
|
{
|
||||||
|
wait 0.1;
|
||||||
|
}
|
||||||
|
self notify( "path_timer_done" );
|
||||||
|
self maps/mp/zombies/_zm_spawner::zombie_history( "find flesh -> bottom of loop" );
|
||||||
|
debug_print( "Zombie is re-acquiring enemy, ending breadcrumb search" );
|
||||||
|
self notify( "zombie_acquire_enemy" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init_inert_zombies()
|
||||||
|
{
|
||||||
|
level init_inert_substates();
|
||||||
|
}
|
||||||
|
|
||||||
|
init_inert_substates()
|
||||||
|
{
|
||||||
|
level.inert_substates = [];
|
||||||
|
level.inert_substates[ level.inert_substates.size ] = "inert1";
|
||||||
|
level.inert_substates[ level.inert_substates.size ] = "inert2";
|
||||||
|
level.inert_substates[ level.inert_substates.size ] = "inert3";
|
||||||
|
level.inert_substates[ level.inert_substates.size ] = "inert4";
|
||||||
|
level.inert_substates[ level.inert_substates.size ] = "inert5";
|
||||||
|
level.inert_substates[ level.inert_substates.size ] = "inert6";
|
||||||
|
level.inert_substates[ level.inert_substates.size ] = "inert7";
|
||||||
|
level.inert_substates = array_randomize( level.inert_substates );
|
||||||
|
level.inert_substate_index = 0;
|
||||||
|
level.inert_trans_walk = [];
|
||||||
|
level.inert_trans_walk[ level.inert_trans_walk.size ] = "inert_2_walk_1";
|
||||||
|
level.inert_trans_walk[ level.inert_trans_walk.size ] = "inert_2_walk_2";
|
||||||
|
level.inert_trans_walk[ level.inert_trans_walk.size ] = "inert_2_walk_3";
|
||||||
|
level.inert_trans_walk[ level.inert_trans_walk.size ] = "inert_2_walk_4";
|
||||||
|
level.inert_trans_run = [];
|
||||||
|
level.inert_trans_run[ level.inert_trans_run.size ] = "inert_2_run_1";
|
||||||
|
level.inert_trans_run[ level.inert_trans_run.size ] = "inert_2_run_2";
|
||||||
|
level.inert_trans_sprint = [];
|
||||||
|
level.inert_trans_sprint[ level.inert_trans_sprint.size ] = "inert_2_sprint_1";
|
||||||
|
level.inert_trans_sprint[ level.inert_trans_sprint.size ] = "inert_2_sprint_2";
|
||||||
|
level.inert_crawl_substates = [];
|
||||||
|
level.inert_crawl_substates[ level.inert_crawl_substates.size ] = "inert1";
|
||||||
|
level.inert_crawl_substates[ level.inert_crawl_substates.size ] = "inert2";
|
||||||
|
level.inert_crawl_substates[ level.inert_crawl_substates.size ] = "inert3";
|
||||||
|
level.inert_crawl_substates[ level.inert_crawl_substates.size ] = "inert4";
|
||||||
|
level.inert_crawl_substates[ level.inert_crawl_substates.size ] = "inert5";
|
||||||
|
level.inert_crawl_substates[ level.inert_crawl_substates.size ] = "inert6";
|
||||||
|
level.inert_crawl_substates[ level.inert_crawl_substates.size ] = "inert7";
|
||||||
|
level.inert_crawl_trans_walk = [];
|
||||||
|
level.inert_crawl_trans_walk[ level.inert_crawl_trans_walk.size ] = "inert_2_walk_1";
|
||||||
|
level.inert_crawl_trans_run = [];
|
||||||
|
level.inert_crawl_trans_run[ level.inert_crawl_trans_run.size ] = "inert_2_run_1";
|
||||||
|
level.inert_crawl_trans_run[ level.inert_crawl_trans_run.size ] = "inert_2_run_2";
|
||||||
|
level.inert_crawl_trans_sprint = [];
|
||||||
|
level.inert_crawl_trans_sprint[ level.inert_crawl_trans_sprint.size ] = "inert_2_sprint_1";
|
||||||
|
level.inert_crawl_trans_sprint[ level.inert_crawl_trans_sprint.size ] = "inert_2_sprint_2";
|
||||||
|
level.inert_crawl_substates = array_randomize( level.inert_crawl_substates );
|
||||||
|
level.inert_crawl_substate_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_inert_substate()
|
||||||
|
{
|
||||||
|
substate = level.inert_substates[ level.inert_substate_index ];
|
||||||
|
level.inert_substate_index++;
|
||||||
|
if ( level.inert_substate_index >= level.inert_substates.size )
|
||||||
|
{
|
||||||
|
level.inert_substates = array_randomize( level.inert_substates );
|
||||||
|
level.inert_substate_index = 0;
|
||||||
|
}
|
||||||
|
return substate;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_inert_crawl_substate()
|
||||||
|
{
|
||||||
|
substate = level.inert_crawl_substates[ level.inert_crawl_substate_index ];
|
||||||
|
level.inert_crawl_substate_index++;
|
||||||
|
if ( level.inert_crawl_substate_index >= level.inert_crawl_substates.size )
|
||||||
|
{
|
||||||
|
level.inert_crawl_substates = array_randomize( level.inert_crawl_substates );
|
||||||
|
level.inert_crawl_substate_index = 0;
|
||||||
|
}
|
||||||
|
return substate;
|
||||||
|
}
|
||||||
|
|
||||||
|
start_inert( in_place )
|
||||||
|
{
|
||||||
|
self endon( "death" );
|
||||||
|
if ( isDefined( self.is_inert ) && self.is_inert )
|
||||||
|
{
|
||||||
|
self maps/mp/zombies/_zm_spawner::zombie_history( "is_inert already set " + getTime() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.is_inert = 1;
|
||||||
|
self notify( "start_inert" );
|
||||||
|
self maps/mp/zombies/_zm_spawner::zombie_eye_glow_stop();
|
||||||
|
self maps/mp/zombies/_zm_spawner::zombie_history( "is_inert set " + getTime() );
|
||||||
|
self playsound( "zmb_zombie_go_inert" );
|
||||||
|
if ( isDefined( self.barricade_enter ) && self.barricade_enter )
|
||||||
|
{
|
||||||
|
while ( isDefined( self.barricade_enter ) && self.barricade_enter )
|
||||||
|
{
|
||||||
|
wait 0.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( isDefined( self.ai_state ) && self.ai_state == "zombie_goto_entrance" )
|
||||||
|
{
|
||||||
|
self notify( "stop_zombie_goto_entrance" );
|
||||||
|
self maps/mp/zombies/_zm_spawner::reset_attack_spot();
|
||||||
|
}
|
||||||
|
if ( isDefined( self.completed_emerging_into_playable_area ) && self.completed_emerging_into_playable_area )
|
||||||
|
{
|
||||||
|
self notify( "stop_find_flesh" );
|
||||||
|
self notify( "zombie_acquire_enemy" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
in_place = 1;
|
||||||
|
}
|
||||||
|
if ( isDefined( self.in_the_ground ) && self.in_the_ground )
|
||||||
|
{
|
||||||
|
self waittill( "risen", find_flesh_struct_string );
|
||||||
|
if ( self maps/mp/zombies/_zm_spawner::should_skip_teardown( find_flesh_struct_string ) )
|
||||||
|
{
|
||||||
|
if ( isDefined( self.completed_emerging_into_playable_area ) && !self.completed_emerging_into_playable_area )
|
||||||
|
{
|
||||||
|
self waittill( "completed_emerging_into_playable_area" );
|
||||||
|
}
|
||||||
|
self notify( "stop_find_flesh" );
|
||||||
|
self notify( "zombie_acquire_enemy" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ( isDefined( self.is_traversing ) && self.is_traversing )
|
||||||
|
{
|
||||||
|
while ( self isinscriptedstate() )
|
||||||
|
{
|
||||||
|
wait 0,1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( isDefined( self.doing_equipment_attack ) && self.doing_equipment_attack )
|
||||||
|
{
|
||||||
|
self stopanimscripted();
|
||||||
|
}
|
||||||
|
if ( isDefined( self.inert_delay ) )
|
||||||
|
{
|
||||||
|
self [[ self.inert_delay ]]();
|
||||||
|
self maps/mp/zombies/_zm_spawner::zombie_history( "inert_delay done " + getTime() );
|
||||||
|
}
|
||||||
|
self inert_think( in_place );
|
||||||
|
}
|
||||||
|
|
||||||
|
inert_think( in_place )
|
||||||
|
{
|
||||||
|
self endon( "death" );
|
||||||
|
self.ignoreall = 1;
|
||||||
|
self animmode( "normal" );
|
||||||
|
if ( self.has_legs )
|
||||||
|
{
|
||||||
|
if ( isDefined( in_place ) && in_place )
|
||||||
|
{
|
||||||
|
self setgoalpos( self.origin );
|
||||||
|
if ( randomint( 100 ) > 50 )
|
||||||
|
{
|
||||||
|
self maps/mp/zombies/_zm_spawner::zombie_history( "inert 1 " + getTime() );
|
||||||
|
self setanimstatefromasd( "zm_inert", "inert1" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self maps/mp/zombies/_zm_spawner::zombie_history( "inert 2 " + getTime() );
|
||||||
|
self setanimstatefromasd( "zm_inert", "inert2" );
|
||||||
|
}
|
||||||
|
self.in_place = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
substate = get_inert_substate();
|
||||||
|
if ( isDefined( level.inert_substate_override ) )
|
||||||
|
{
|
||||||
|
substate = self [[ level.inert_substate_override ]]( substate );
|
||||||
|
}
|
||||||
|
self setanimstatefromasd( "zm_inert", substate );
|
||||||
|
self maps/mp/zombies/_zm_spawner::zombie_history( "zm_inert ASD " + getTime() );
|
||||||
|
if ( substate != "inert3" && substate != "inert4" || substate == "inert5" && substate == "inert6" )
|
||||||
|
{
|
||||||
|
self thread inert_watch_goal();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self.in_place = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self setanimstatefromasd( "zm_inert_crawl", get_inert_crawl_substate() );
|
||||||
|
self maps/mp/zombies/_zm_spawner::zombie_history( "zm_inert_crawl ASD " + getTime() );
|
||||||
|
}
|
||||||
|
self thread inert_wakeup();
|
||||||
|
self waittill( "stop_zombie_inert" );
|
||||||
|
self maps/mp/zombies/_zm_spawner::zombie_history( "stop_zombie_inert " + getTime() );
|
||||||
|
self playsound( "zmb_zombie_end_inert" );
|
||||||
|
self inert_transition();
|
||||||
|
self maps/mp/zombies/_zm_spawner::zombie_history( "inert transition done" );
|
||||||
|
if ( isDefined( self.ai_state ) && self.ai_state == "zombie_goto_entrance" )
|
||||||
|
{
|
||||||
|
self thread maps/mp/zombies/_zm_spawner::zombie_goto_entrance( self.first_node );
|
||||||
|
}
|
||||||
|
if ( isDefined( self.inert_wakeup_override ) )
|
||||||
|
{
|
||||||
|
self [[ self.inert_wakeup_override ]]();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( isDefined( self.completed_emerging_into_playable_area ) && self.completed_emerging_into_playable_area )
|
||||||
|
{
|
||||||
|
self.ignoreall = 0;
|
||||||
|
if ( isDefined( level.ignore_find_flesh ) && !( self [[ level.ignore_find_flesh ]]() ) )
|
||||||
|
{
|
||||||
|
self thread maps/mp/zombies/_zm_ai_basic::find_flesh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.becoming_inert = undefined;
|
||||||
|
self.is_inert = undefined;
|
||||||
|
self.in_place = undefined;
|
||||||
|
self maps/mp/animscripts/zm_run::needsupdate();
|
||||||
|
self maps/mp/zombies/_zm_spawner::zombie_history( "is_inert cleared " + getTime() );
|
||||||
|
}
|
||||||
|
|
||||||
|
inert_watch_goal()
|
||||||
|
{
|
||||||
|
self endon( "death" );
|
||||||
|
self endon( "stop_zombie_inert" );
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
self waittill( "goal" );
|
||||||
|
locs = array_randomize( level.enemy_dog_locations );
|
||||||
|
_a481 = locs;
|
||||||
|
_k481 = getFirstArrayKey( _a481 );
|
||||||
|
while ( isDefined( _k481 ) )
|
||||||
|
{
|
||||||
|
loc = _a481[ _k481 ];
|
||||||
|
dist_sq = distancesquared( self.origin, loc.origin );
|
||||||
|
if ( dist_sq > 90000 )
|
||||||
|
{
|
||||||
|
self setgoalpos( loc.origin );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_k481 = getNextArrayKey( _a481, _k481 );
|
||||||
|
}
|
||||||
|
if ( locs.size > 0 )
|
||||||
|
{
|
||||||
|
self setgoalpos( locs[ 0 ].origin );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inert_wakeup()
|
||||||
|
{
|
||||||
|
self endon( "death" );
|
||||||
|
self endon( "stop_zombie_inert" );
|
||||||
|
wait 0.1;
|
||||||
|
self thread inert_damage();
|
||||||
|
self thread inert_bump();
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
current_time = getTime();
|
||||||
|
players = get_players();
|
||||||
|
_a522 = players;
|
||||||
|
_k522 = getFirstArrayKey( _a522 );
|
||||||
|
while ( isDefined( _k522 ) )
|
||||||
|
{
|
||||||
|
player = _a522[ _k522 ];
|
||||||
|
dist_sq = distancesquared( self.origin, player.origin );
|
||||||
|
if ( dist_sq < 4096 )
|
||||||
|
{
|
||||||
|
self stop_inert();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( dist_sq < 360000 )
|
||||||
|
{
|
||||||
|
if ( player issprinting() )
|
||||||
|
{
|
||||||
|
self stop_inert();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( dist_sq < 5760000 )
|
||||||
|
{
|
||||||
|
if ( ( current_time - player.lastfiretime ) < 100 )
|
||||||
|
{
|
||||||
|
self stop_inert();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_k522 = getNextArrayKey( _a522, _k522 );
|
||||||
|
}
|
||||||
|
wait 0.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inert_bump()
|
||||||
|
{
|
||||||
|
self endon( "death" );
|
||||||
|
self endon( "stop_zombie_inert" );
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
zombies = getaiarray( level.zombie_team );
|
||||||
|
_a562 = zombies;
|
||||||
|
_k562 = getFirstArrayKey( _a562 );
|
||||||
|
while ( isDefined( _k562 ) )
|
||||||
|
{
|
||||||
|
zombie = _a562[ _k562 ];
|
||||||
|
if ( zombie == self )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if ( isDefined( zombie.is_inert ) && zombie.is_inert )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( isDefined( zombie.becoming_inert ) && zombie.becoming_inert )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dist_sq = distancesquared( self.origin, zombie.origin );
|
||||||
|
if ( dist_sq < 1296 )
|
||||||
|
{
|
||||||
|
self stop_inert();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_k562 = getNextArrayKey( _a562, _k562 );
|
||||||
|
}
|
||||||
|
wait 0.2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inert_damage()
|
||||||
|
{
|
||||||
|
self endon( "death" );
|
||||||
|
self endon( "stop_zombie_inert" );
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
self waittill( "damage", amount, inflictor, direction, point, type, tagname, modelname, partname, weaponname, idflags );
|
||||||
|
while ( weaponname == "emp_grenade_zm" )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
while ( isDefined( inflictor ) )
|
||||||
|
{
|
||||||
|
if ( isDefined( inflictor._trap_type ) && inflictor._trap_type == "fire" )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self stop_inert();
|
||||||
|
}
|
||||||
|
|
||||||
|
grenade_watcher( grenade )
|
||||||
|
{
|
||||||
|
grenade waittill( "explode", grenade_origin );
|
||||||
|
zombies = get_array_of_closest( grenade_origin, get_round_enemy_array(), undefined, undefined, 2400 );
|
||||||
|
if ( !isDefined( zombies ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_a633 = zombies;
|
||||||
|
_k633 = getFirstArrayKey( _a633 );
|
||||||
|
while ( isDefined( _k633 ) )
|
||||||
|
{
|
||||||
|
zombie = _a633[ _k633 ];
|
||||||
|
zombie stop_inert();
|
||||||
|
_k633 = getNextArrayKey( _a633, _k633 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_inert()
|
||||||
|
{
|
||||||
|
self notify( "stop_zombie_inert" );
|
||||||
|
}
|
||||||
|
|
||||||
|
inert_transition()
|
||||||
|
{
|
||||||
|
self endon( "death" );
|
||||||
|
self endon( "stop_zombie_inert_transition" );
|
||||||
|
trans_num = 4;
|
||||||
|
trans_set = level.inert_trans_walk;
|
||||||
|
animstate = "zm_inert_trans";
|
||||||
|
if ( !self.has_legs )
|
||||||
|
{
|
||||||
|
trans_num = 1;
|
||||||
|
trans_set = level.inert_crawl_trans_walk;
|
||||||
|
animstate = "zm_inert_crawl_trans";
|
||||||
|
}
|
||||||
|
if ( self.zombie_move_speed == "run" )
|
||||||
|
{
|
||||||
|
if ( self.has_legs )
|
||||||
|
{
|
||||||
|
trans_set = level.inert_trans_run;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
trans_set = level.inert_crawl_trans_run;
|
||||||
|
}
|
||||||
|
trans_num = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( self.zombie_move_speed == "sprint" )
|
||||||
|
{
|
||||||
|
if ( self.has_legs )
|
||||||
|
{
|
||||||
|
trans_set = level.inert_trans_sprint;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
trans_set = level.inert_crawl_trans_sprint;
|
||||||
|
}
|
||||||
|
trans_num = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self thread inert_eye_glow();
|
||||||
|
self setanimstatefromasd( animstate, trans_set[ randomint( trans_num ) ] );
|
||||||
|
self maps/mp/zombies/_zm_spawner::zombie_history( "inert_trans_anim " + getTime() );
|
||||||
|
maps/mp/animscripts/zm_shared::donotetracks( "inert_trans_anim" );
|
||||||
|
}
|
||||||
|
|
||||||
|
inert_eye_glow()
|
||||||
|
{
|
||||||
|
self endon( "death" );
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
self waittill( "inert_trans_anim", note );
|
||||||
|
if ( note == "end" )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( note == "zmb_awaken" )
|
||||||
|
{
|
||||||
|
self maps/mp/zombies/_zm_spawner::zombie_eye_glow();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,642 @@
|
|||||||
|
#include maps/mp/zombies/_zm_laststand;
|
||||||
|
#include maps/mp/animscripts/zm_shared;
|
||||||
|
#include maps/mp/zombies/_zm_spawner;
|
||||||
|
#include maps/mp/zombies/_zm_utility;
|
||||||
|
#include maps/mp/_utility;
|
||||||
|
#include common_scripts/utility;
|
||||||
|
|
||||||
|
zombie_faller_delete()
|
||||||
|
{
|
||||||
|
level.zombie_total++;
|
||||||
|
self maps/mp/zombies/_zm_spawner::reset_attack_spot();
|
||||||
|
if ( isDefined( self.zombie_faller_location ) )
|
||||||
|
{
|
||||||
|
self.zombie_faller_location.is_enabled = 1;
|
||||||
|
self.zombie_faller_location = undefined;
|
||||||
|
}
|
||||||
|
self delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
faller_script_parameters()
|
||||||
|
{
|
||||||
|
while ( isDefined( self.script_parameters ) )
|
||||||
|
{
|
||||||
|
parms = strtok( self.script_parameters, ";" );
|
||||||
|
while ( isDefined( parms ) && parms.size > 0 )
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
while ( i < parms.size )
|
||||||
|
{
|
||||||
|
if ( parms[ i ] == "drop_now" )
|
||||||
|
{
|
||||||
|
self.drop_now = 1;
|
||||||
|
}
|
||||||
|
if ( parms[ i ] == "drop_not_occupied" )
|
||||||
|
{
|
||||||
|
self.drop_not_occupied = 1;
|
||||||
|
}
|
||||||
|
if ( parms[ i ] == "emerge_top" )
|
||||||
|
{
|
||||||
|
self.emerge_top = 1;
|
||||||
|
}
|
||||||
|
if ( parms[ i ] == "emerge_bottom" )
|
||||||
|
{
|
||||||
|
self.emerge_bottom = 1;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_deathfunc( func_name )
|
||||||
|
{
|
||||||
|
self endon( "death" );
|
||||||
|
while ( isDefined( self.zombie_init_done ) && !self.zombie_init_done )
|
||||||
|
{
|
||||||
|
wait_network_frame();
|
||||||
|
}
|
||||||
|
if ( isDefined( func_name ) )
|
||||||
|
{
|
||||||
|
self.deathfunction = func_name;
|
||||||
|
}
|
||||||
|
else if ( isDefined( level.custom_faller_death ) )
|
||||||
|
{
|
||||||
|
self.deathfunction = level.custom_faller_death;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self.deathfunction = ::zombie_fall_death_func;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
do_zombie_fall( spot )
|
||||||
|
{
|
||||||
|
self endon( "death" );
|
||||||
|
self.zombie_faller_location = spot;
|
||||||
|
self.zombie_faller_location.is_enabled = 0;
|
||||||
|
self.zombie_faller_location faller_script_parameters();
|
||||||
|
if ( isDefined( self.zombie_faller_location.emerge_bottom ) || self.zombie_faller_location.emerge_bottom && isDefined( self.zombie_faller_location.emerge_top ) && self.zombie_faller_location.emerge_top )
|
||||||
|
{
|
||||||
|
self do_zombie_emerge( spot );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self thread setup_deathfunc();
|
||||||
|
self.no_powerups = 1;
|
||||||
|
self.in_the_ceiling = 1;
|
||||||
|
self.anchor = spawn( "script_origin", self.origin );
|
||||||
|
self.anchor.angles = self.angles;
|
||||||
|
self linkto( self.anchor );
|
||||||
|
if ( !isDefined( spot.angles ) )
|
||||||
|
{
|
||||||
|
spot.angles = ( 0, 0, -1 );
|
||||||
|
}
|
||||||
|
anim_org = spot.origin;
|
||||||
|
anim_ang = spot.angles;
|
||||||
|
self ghost();
|
||||||
|
self.anchor moveto( anim_org, 0,05 );
|
||||||
|
self.anchor waittill( "movedone" );
|
||||||
|
target_org = get_desired_origin();
|
||||||
|
if ( isDefined( target_org ) )
|
||||||
|
{
|
||||||
|
anim_ang = vectorToAngles( target_org - self.origin );
|
||||||
|
self.anchor rotateto( ( 0, anim_ang[ 1 ], 0 ), 0,05 );
|
||||||
|
self.anchor waittill( "rotatedone" );
|
||||||
|
}
|
||||||
|
self unlink();
|
||||||
|
if ( isDefined( self.anchor ) )
|
||||||
|
{
|
||||||
|
self.anchor delete();
|
||||||
|
}
|
||||||
|
self thread maps/mp/zombies/_zm_spawner::hide_pop();
|
||||||
|
self thread zombie_fall_death( spot );
|
||||||
|
self thread zombie_fall_fx( spot );
|
||||||
|
self thread zombie_faller_death_wait();
|
||||||
|
self thread zombie_faller_do_fall();
|
||||||
|
self.no_powerups = 0;
|
||||||
|
self notify( "risen" );
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_faller_do_fall()
|
||||||
|
{
|
||||||
|
self endon( "death" );
|
||||||
|
self animscripted( self.origin, self.zombie_faller_location.angles, "zm_faller_emerge" );
|
||||||
|
self maps/mp/animscripts/zm_shared::donotetracks( "emerge_anim", ::handle_fall_notetracks, self.zombie_faller_location );
|
||||||
|
self.zombie_faller_wait_start = getTime();
|
||||||
|
self.zombie_faller_should_drop = 0;
|
||||||
|
self thread zombie_fall_wait();
|
||||||
|
self thread zombie_faller_watch_all_players();
|
||||||
|
while ( !self.zombie_faller_should_drop )
|
||||||
|
{
|
||||||
|
if ( self zombie_fall_should_attack( self.zombie_faller_location ) )
|
||||||
|
{
|
||||||
|
self animscripted( self.origin, self.zombie_faller_location.angles, "zm_faller_attack" );
|
||||||
|
self maps/mp/animscripts/zm_shared::donotetracks( "attack_anim", ::handle_fall_notetracks, self.zombie_faller_location );
|
||||||
|
if ( !self zombie_faller_always_drop() && randomfloat( 1 ) > 0.5 )
|
||||||
|
{
|
||||||
|
self.zombie_faller_should_drop = 1;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if ( self zombie_faller_always_drop() )
|
||||||
|
{
|
||||||
|
self.zombie_faller_should_drop = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if ( getTime() >= ( self.zombie_faller_wait_start + 20000 ) )
|
||||||
|
{
|
||||||
|
self.zombie_faller_should_drop = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if ( self zombie_faller_drop_not_occupied() )
|
||||||
|
{
|
||||||
|
self.zombie_faller_should_drop = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else self animscripted( self.origin, self.zombie_faller_location.angles, "zm_faller_attack" );
|
||||||
|
self maps/mp/animscripts/zm_shared::donotetracks( "attack_anim", ::handle_fall_notetracks, self.zombie_faller_location );
|
||||||
|
}
|
||||||
|
self notify( "falling" );
|
||||||
|
spot = self.zombie_faller_location;
|
||||||
|
self zombie_faller_enable_location();
|
||||||
|
self animscripted( self.origin, spot.angles, "zm_faller_fall" );
|
||||||
|
self maps/mp/animscripts/zm_shared::donotetracks( "fall_anim", ::handle_fall_notetracks, spot );
|
||||||
|
self.deathfunction = ::zombie_death_animscript;
|
||||||
|
self notify( "fall_anim_finished" );
|
||||||
|
spot notify( "stop_zombie_fall_fx" );
|
||||||
|
self stopanimscripted();
|
||||||
|
landanimdelta = 15;
|
||||||
|
ground_pos = groundpos_ignore_water_new( self.origin );
|
||||||
|
physdist = ( self.origin[ 2 ] - ground_pos[ 2 ] ) + landanimdelta;
|
||||||
|
if ( physdist > 0 )
|
||||||
|
{
|
||||||
|
self animcustom( ::zombie_fall_loop );
|
||||||
|
self waittill( "faller_on_ground" );
|
||||||
|
self animcustom( ::zombie_land );
|
||||||
|
self waittill( "zombie_land_done" );
|
||||||
|
}
|
||||||
|
self.in_the_ceiling = 0;
|
||||||
|
self traversemode( "gravity" );
|
||||||
|
self.no_powerups = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_fall_loop()
|
||||||
|
{
|
||||||
|
self endon( "death" );
|
||||||
|
self setanimstatefromasd( "zm_faller_fall_loop" );
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
ground_pos = groundpos_ignore_water_new( self.origin );
|
||||||
|
if ( ( self.origin[ 2 ] - ground_pos[ 2 ] ) < 20 )
|
||||||
|
{
|
||||||
|
self notify( "faller_on_ground" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wait 0.05;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_land()
|
||||||
|
{
|
||||||
|
self setanimstatefromasd( "zm_faller_land" );
|
||||||
|
maps/mp/animscripts/zm_shared::donotetracks( "land_anim" );
|
||||||
|
self notify( "zombie_land_done" );
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_faller_always_drop()
|
||||||
|
{
|
||||||
|
if ( isDefined( self.zombie_faller_location.drop_now ) && self.zombie_faller_location.drop_now )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_faller_drop_not_occupied()
|
||||||
|
{
|
||||||
|
if ( isDefined( self.zombie_faller_location.drop_not_occupied ) && self.zombie_faller_location.drop_not_occupied )
|
||||||
|
{
|
||||||
|
if ( isDefined( self.zone_name ) && isDefined( level.zones[ self.zone_name ] ) )
|
||||||
|
{
|
||||||
|
return !level.zones[ self.zone_name ].is_occupied;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_faller_watch_all_players()
|
||||||
|
{
|
||||||
|
players = get_players();
|
||||||
|
i = 0;
|
||||||
|
while ( i < players.size )
|
||||||
|
{
|
||||||
|
self thread zombie_faller_watch_player( players[ i ] );
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_faller_watch_player( player )
|
||||||
|
{
|
||||||
|
self endon( "falling" );
|
||||||
|
self endon( "death" );
|
||||||
|
player endon( "disconnect" );
|
||||||
|
range = 200;
|
||||||
|
rangesqr = range * range;
|
||||||
|
timer = 5000;
|
||||||
|
inrange = 0;
|
||||||
|
inrangetime = 0;
|
||||||
|
closerange = 60;
|
||||||
|
closerangesqr = closerange * closerange;
|
||||||
|
dirtoplayerenter = ( 0, 0, -1 );
|
||||||
|
incloserange = 0;
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
distsqr = distance2dsquared( self.origin, player.origin );
|
||||||
|
if ( distsqr < rangesqr )
|
||||||
|
{
|
||||||
|
if ( inrange )
|
||||||
|
{
|
||||||
|
if ( ( inrangetime + timer ) < getTime() )
|
||||||
|
{
|
||||||
|
self.zombie_faller_should_drop = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inrange = 1;
|
||||||
|
inrangetime = getTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inrange = 0;
|
||||||
|
}
|
||||||
|
if ( distsqr < closerangesqr )
|
||||||
|
{
|
||||||
|
if ( !incloserange )
|
||||||
|
{
|
||||||
|
dirtoplayerenter = player.origin - self.origin;
|
||||||
|
dirtoplayerenter = ( dirtoplayerenter[ 0 ], dirtoplayerenter[ 1 ], 0 );
|
||||||
|
dirtoplayerenter = vectornormalize( dirtoplayerenter );
|
||||||
|
}
|
||||||
|
incloserange = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( incloserange )
|
||||||
|
{
|
||||||
|
dirtoplayerexit = player.origin - self.origin;
|
||||||
|
dirtoplayerexit = ( dirtoplayerexit[ 0 ], dirtoplayerexit[ 1 ], 0 );
|
||||||
|
dirtoplayerexit = vectornormalize( dirtoplayerexit );
|
||||||
|
if ( vectordot( dirtoplayerenter, dirtoplayerexit ) < 0 )
|
||||||
|
{
|
||||||
|
self.zombie_faller_should_drop = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
incloserange = 0;
|
||||||
|
}
|
||||||
|
wait 0.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_fall_wait()
|
||||||
|
{
|
||||||
|
self endon( "falling" );
|
||||||
|
self endon( "death" );
|
||||||
|
while ( isDefined( self.zone_name ) )
|
||||||
|
{
|
||||||
|
while ( isDefined( level.zones ) && isDefined( level.zones[ self.zone_name ] ) )
|
||||||
|
{
|
||||||
|
zone = level.zones[ self.zone_name ];
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
if ( !zone.is_enabled || !zone.is_active )
|
||||||
|
{
|
||||||
|
if ( !self potentially_visible( 2250000 ) )
|
||||||
|
{
|
||||||
|
if ( self.health != level.zombie_health )
|
||||||
|
{
|
||||||
|
self.zombie_faller_should_drop = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else self zombie_faller_delete();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wait 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_fall_should_attack( spot )
|
||||||
|
{
|
||||||
|
victims = zombie_fall_get_vicitims( spot );
|
||||||
|
return victims.size > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_fall_get_vicitims( spot )
|
||||||
|
{
|
||||||
|
ret = [];
|
||||||
|
players = getplayers();
|
||||||
|
checkdist2 = 40;
|
||||||
|
checkdist2 *= checkdist2;
|
||||||
|
i = 0;
|
||||||
|
while ( i < players.size )
|
||||||
|
{
|
||||||
|
player = players[ i ];
|
||||||
|
if ( player maps/mp/zombies/_zm_laststand::player_is_in_laststand() )
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else stance = player getstance();
|
||||||
|
if ( stance == "crouch" || stance == "prone" )
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zcheck = self.origin[ 2 ] - player.origin[ 2 ];
|
||||||
|
if ( zcheck < 0 || zcheck > 120 )
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dist2 = distance2dsquared( player.origin, self.origin );
|
||||||
|
if ( dist2 < checkdist2 )
|
||||||
|
{
|
||||||
|
ret[ ret.size ] = player;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_fall_anim( spot )
|
||||||
|
{
|
||||||
|
return level._zombie_fall_anims[ self.animname ][ "fall" ];
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_faller_enable_location()
|
||||||
|
{
|
||||||
|
if ( isDefined( self.zombie_faller_location ) )
|
||||||
|
{
|
||||||
|
self.zombie_faller_location.is_enabled = 1;
|
||||||
|
self.zombie_faller_location = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_faller_death_wait( endon_notify )
|
||||||
|
{
|
||||||
|
self endon( "falling" );
|
||||||
|
if ( isDefined( endon_notify ) )
|
||||||
|
{
|
||||||
|
self endon( endon_notify );
|
||||||
|
}
|
||||||
|
self waittill( "death" );
|
||||||
|
self zombie_faller_enable_location();
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_fall_death_func()
|
||||||
|
{
|
||||||
|
self animmode( "noclip" );
|
||||||
|
self.deathanim = "zm_faller_emerge_death";
|
||||||
|
return self maps/mp/zombies/_zm_spawner::zombie_death_animscript();
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_fall_death( spot )
|
||||||
|
{
|
||||||
|
self endon( "fall_anim_finished" );
|
||||||
|
while ( self.health > 1 )
|
||||||
|
{
|
||||||
|
self waittill( "damage", amount, attacker, dir, p, type );
|
||||||
|
}
|
||||||
|
self stopanimscripted();
|
||||||
|
spot notify( "stop_zombie_fall_fx" );
|
||||||
|
}
|
||||||
|
|
||||||
|
_damage_mod_to_damage_type( type )
|
||||||
|
{
|
||||||
|
toks = strtok( type, "_" );
|
||||||
|
if ( toks.size < 2 )
|
||||||
|
{
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
returnstr = toks[ 1 ];
|
||||||
|
i = 2;
|
||||||
|
while ( i < toks.size )
|
||||||
|
{
|
||||||
|
returnstr += toks[ i ];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
returnstr = tolower( returnstr );
|
||||||
|
return returnstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_fall_fx( spot )
|
||||||
|
{
|
||||||
|
spot thread zombie_fall_dust_fx( self );
|
||||||
|
spot thread zombie_fall_burst_fx();
|
||||||
|
playsoundatposition( "zmb_zombie_spawn", spot.origin );
|
||||||
|
self endon( "death" );
|
||||||
|
spot endon( "stop_zombie_fall_fx" );
|
||||||
|
wait 1;
|
||||||
|
if ( self.zombie_move_speed != "sprint" )
|
||||||
|
{
|
||||||
|
wait 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_fall_burst_fx()
|
||||||
|
{
|
||||||
|
self endon( "stop_zombie_fall_fx" );
|
||||||
|
self endon( "fall_anim_finished" );
|
||||||
|
playfx( level._effect[ "rise_burst" ], self.origin + ( 0, 0, randomintrange( 5, 10 ) ) );
|
||||||
|
wait 0.25;
|
||||||
|
playfx( level._effect[ "rise_billow" ], self.origin + ( randomintrange( -10, 10 ), randomintrange( -10, 10 ), randomintrange( 5, 10 ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_fall_dust_fx( zombie )
|
||||||
|
{
|
||||||
|
dust_tag = "J_SpineUpper";
|
||||||
|
self endon( "stop_zombie_fall_dust_fx" );
|
||||||
|
self thread stop_zombie_fall_dust_fx( zombie );
|
||||||
|
dust_time = 4.5;
|
||||||
|
dust_interval = 0.3;
|
||||||
|
t = 0;
|
||||||
|
while ( t < dust_time )
|
||||||
|
{
|
||||||
|
playfxontag( level._effect[ "rise_dust" ], zombie, dust_tag );
|
||||||
|
wait dust_interval;
|
||||||
|
t += dust_interval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_zombie_fall_dust_fx( zombie )
|
||||||
|
{
|
||||||
|
zombie waittill( "death" );
|
||||||
|
self notify( "stop_zombie_fall_dust_fx" );
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_fall_notetracks( note, spot )
|
||||||
|
{
|
||||||
|
if ( note == "deathout" )
|
||||||
|
{
|
||||||
|
self.deathfunction = ::faller_death_ragdoll;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while ( note == "fire" )
|
||||||
|
{
|
||||||
|
victims = zombie_fall_get_vicitims( spot );
|
||||||
|
i = 0;
|
||||||
|
while ( i < victims.size )
|
||||||
|
{
|
||||||
|
victims[ i ] dodamage( self.meleedamage, self.origin, self, self, "none", "MOD_MELEE" );
|
||||||
|
self.zombie_faller_should_drop = 1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
faller_death_ragdoll()
|
||||||
|
{
|
||||||
|
self startragdoll();
|
||||||
|
self launchragdoll( ( 0, 0, -1 ) );
|
||||||
|
return self maps/mp/zombies/_zm_spawner::zombie_death_animscript();
|
||||||
|
}
|
||||||
|
|
||||||
|
in_player_fov( player )
|
||||||
|
{
|
||||||
|
playerangles = player getplayerangles();
|
||||||
|
playerforwardvec = anglesToForward( playerangles );
|
||||||
|
playerunitforwardvec = vectornormalize( playerforwardvec );
|
||||||
|
banzaipos = self.origin;
|
||||||
|
playerpos = player getorigin();
|
||||||
|
playertobanzaivec = banzaipos - playerpos;
|
||||||
|
playertobanzaiunitvec = vectornormalize( playertobanzaivec );
|
||||||
|
forwarddotbanzai = vectordot( playerunitforwardvec, playertobanzaiunitvec );
|
||||||
|
anglefromcenter = acos( forwarddotbanzai );
|
||||||
|
playerfov = getDvarFloat( "cg_fov" );
|
||||||
|
banzaivsplayerfovbuffer = getDvarFloat( "g_banzai_player_fov_buffer" );
|
||||||
|
if ( banzaivsplayerfovbuffer <= 0 )
|
||||||
|
{
|
||||||
|
banzaivsplayerfovbuffer = 0.2;
|
||||||
|
}
|
||||||
|
inplayerfov = anglefromcenter <= ( ( playerfov * 0.5 ) * ( 1 - banzaivsplayerfovbuffer ) );
|
||||||
|
return inplayerfov;
|
||||||
|
}
|
||||||
|
|
||||||
|
potentially_visible( how_close )
|
||||||
|
{
|
||||||
|
if ( !isDefined( how_close ) )
|
||||||
|
{
|
||||||
|
how_close = 1000000;
|
||||||
|
}
|
||||||
|
potentiallyvisible = 0;
|
||||||
|
players = getplayers();
|
||||||
|
i = 0;
|
||||||
|
while ( i < players.size )
|
||||||
|
{
|
||||||
|
dist = distancesquared( self.origin, players[ i ].origin );
|
||||||
|
if ( dist < how_close )
|
||||||
|
{
|
||||||
|
inplayerfov = self in_player_fov( players[ i ] );
|
||||||
|
if ( inplayerfov )
|
||||||
|
{
|
||||||
|
potentiallyvisible = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return potentiallyvisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
do_zombie_emerge( spot )
|
||||||
|
{
|
||||||
|
self endon( "death" );
|
||||||
|
self thread setup_deathfunc( ::faller_death_ragdoll );
|
||||||
|
self.no_powerups = 1;
|
||||||
|
self.in_the_ceiling = 1;
|
||||||
|
anim_org = spot.origin;
|
||||||
|
anim_ang = spot.angles;
|
||||||
|
self thread zombie_emerge_fx( spot );
|
||||||
|
self thread zombie_faller_death_wait( "risen" );
|
||||||
|
if ( isDefined( level.custom_faller_entrance_logic ) )
|
||||||
|
{
|
||||||
|
self thread [[ level.custom_faller_entrance_logic ]]();
|
||||||
|
}
|
||||||
|
self zombie_faller_emerge( spot );
|
||||||
|
self.create_eyes = 1;
|
||||||
|
wait 0.1;
|
||||||
|
self notify( "risen" );
|
||||||
|
self zombie_faller_enable_location();
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_faller_emerge( spot )
|
||||||
|
{
|
||||||
|
self endon( "death" );
|
||||||
|
if ( isDefined( self.zombie_faller_location.emerge_bottom ) && self.zombie_faller_location.emerge_bottom )
|
||||||
|
{
|
||||||
|
self animscripted( self.zombie_faller_location.origin, self.zombie_faller_location.angles, "zombie_riser_elevator_from_floor" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self animscripted( self.zombie_faller_location.origin, self.zombie_faller_location.angles, "zombie_riser_elevator_from_ceiling" );
|
||||||
|
}
|
||||||
|
self maps/mp/animscripts/zm_shared::donotetracks( "rise_anim" );
|
||||||
|
self.deathfunction = ::zombie_death_animscript;
|
||||||
|
self.in_the_ceiling = 0;
|
||||||
|
self.no_powerups = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_emerge_fx( spot )
|
||||||
|
{
|
||||||
|
spot thread zombie_emerge_dust_fx( self );
|
||||||
|
playsoundatposition( "zmb_zombie_spawn", spot.origin );
|
||||||
|
self endon( "death" );
|
||||||
|
spot endon( "stop_zombie_fall_fx" );
|
||||||
|
wait 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
zombie_emerge_dust_fx( zombie )
|
||||||
|
{
|
||||||
|
dust_tag = "J_SpineUpper";
|
||||||
|
self endon( "stop_zombie_fall_dust_fx" );
|
||||||
|
self thread stop_zombie_fall_dust_fx( zombie );
|
||||||
|
dust_time = 3.5;
|
||||||
|
dust_interval = 0.5;
|
||||||
|
t = 0;
|
||||||
|
while ( t < dust_time )
|
||||||
|
{
|
||||||
|
playfxontag( level._effect[ "rise_dust" ], zombie, dust_tag );
|
||||||
|
wait dust_interval;
|
||||||
|
t += dust_interval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_zombie_emerge_dust_fx( zombie )
|
||||||
|
{
|
||||||
|
zombie waittill( "death" );
|
||||||
|
self notify( "stop_zombie_fall_dust_fx" );
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,915 @@
|
|||||||
|
#include maps/mp/zombies/_zm_equip_hacker;
|
||||||
|
#include maps/mp/zombies/_zm_audio;
|
||||||
|
#include maps/mp/gametypes_zm/_hud_util;
|
||||||
|
#include maps/mp/zombies/_zm_laststand;
|
||||||
|
#include maps/mp/zombies/_zm_score;
|
||||||
|
#include maps/mp/zombies/_zm_equipment;
|
||||||
|
#include maps/mp/zombies/_zm_utility;
|
||||||
|
#include maps/mp/_utility;
|
||||||
|
#include common_scripts/utility;
|
||||||
|
|
||||||
|
init()
|
||||||
|
{
|
||||||
|
if ( !maps/mp/zombies/_zm_equipment::is_equipment_included( "equip_hacker_zm" ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
maps/mp/zombies/_zm_equipment::register_equipment( "equip_hacker_zm", &"ZOMBIE_EQUIP_HACKER_PICKUP_HINT_STRING", &"ZOMBIE_EQUIP_HACKER_HOWTO", undefined, "hacker" );
|
||||||
|
level._hackable_objects = [];
|
||||||
|
level._pooled_hackable_objects = [];
|
||||||
|
onplayerconnect_callback( ::hacker_on_player_connect );
|
||||||
|
level thread hack_trigger_think();
|
||||||
|
level thread hacker_trigger_pool_think();
|
||||||
|
level thread hacker_round_reward();
|
||||||
|
/*
|
||||||
|
if ( getDvarInt( #"53BD7080" ) == 1 )
|
||||||
|
{
|
||||||
|
level thread hacker_debug();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
hacker_round_reward()
|
||||||
|
{
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
level waittill( "end_of_round" );
|
||||||
|
if ( !isDefined( level._from_nml ) )
|
||||||
|
{
|
||||||
|
players = get_players();
|
||||||
|
i = 0;
|
||||||
|
while ( i < players.size )
|
||||||
|
{
|
||||||
|
if ( isDefined( players[ i ] get_player_equipment() ) && players[ i ] get_player_equipment() == "equip_hacker_zm" )
|
||||||
|
{
|
||||||
|
if ( isDefined( players[ i ].equipment_got_in_round[ "equip_hacker_zm" ] ) )
|
||||||
|
{
|
||||||
|
got_in_round = players[ i ].equipment_got_in_round[ "equip_hacker_zm" ];
|
||||||
|
rounds_kept = level.round_number - got_in_round;
|
||||||
|
rounds_kept -= 1;
|
||||||
|
if ( rounds_kept > 0 )
|
||||||
|
{
|
||||||
|
rounds_kept = min( rounds_kept, 5 );
|
||||||
|
score = rounds_kept * 500;
|
||||||
|
players[ i ] maps/mp/zombies/_zm_score::add_to_player_score( int( score ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else level._from_nml = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hacker_debug()
|
||||||
|
{
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
while ( i < level._hackable_objects.size )
|
||||||
|
{
|
||||||
|
hackable = level._hackable_objects[ i ];
|
||||||
|
if ( isDefined( hackable.pooled ) && hackable.pooled )
|
||||||
|
{
|
||||||
|
if ( isDefined( hackable._trigger ) )
|
||||||
|
{
|
||||||
|
col = vectorScale( ( 0, 0, 1 ), 255 );
|
||||||
|
if ( isDefined( hackable.custom_debug_color ) )
|
||||||
|
{
|
||||||
|
col = hackable.custom_debug_color;
|
||||||
|
}
|
||||||
|
/#
|
||||||
|
print3d( hackable.origin, "+", col, 1, 1 );
|
||||||
|
#/
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/#
|
||||||
|
print3d( hackable.origin, "+", vectorScale( ( 0, 0, 1 ), 255 ), 1, 1 );
|
||||||
|
#/
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/#
|
||||||
|
print3d( hackable.origin, "+", vectorScale( ( 0, 0, 1 ), 255 ), 1, 1 );
|
||||||
|
#/
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
wait 0.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hacker_trigger_pool_think()
|
||||||
|
{
|
||||||
|
if ( !isDefined( level._zombie_hacker_trigger_pool_size ) )
|
||||||
|
{
|
||||||
|
level._zombie_hacker_trigger_pool_size = 8;
|
||||||
|
}
|
||||||
|
pool_active = 0;
|
||||||
|
level._hacker_pool = [];
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
if ( pool_active )
|
||||||
|
{
|
||||||
|
if ( !any_hackers_active() )
|
||||||
|
{
|
||||||
|
destroy_pooled_items();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sweep_pooled_items();
|
||||||
|
add_eligable_pooled_items();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( any_hackers_active() )
|
||||||
|
{
|
||||||
|
pool_active = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wait 0.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy_pooled_items()
|
||||||
|
{
|
||||||
|
pool_active = 0;
|
||||||
|
i = 0;
|
||||||
|
while ( i < level._hacker_pool.size )
|
||||||
|
{
|
||||||
|
level._hacker_pool[ i ]._trigger delete();
|
||||||
|
level._hacker_pool[ i ]._trigger = undefined;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
level._hacker_pool = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
sweep_pooled_items()
|
||||||
|
{
|
||||||
|
new_hacker_pool = [];
|
||||||
|
i = 0;
|
||||||
|
while ( i < level._hacker_pool.size )
|
||||||
|
{
|
||||||
|
if ( level._hacker_pool[ i ] should_pooled_object_exist() )
|
||||||
|
{
|
||||||
|
new_hacker_pool[ new_hacker_pool.size ] = level._hacker_pool[ i ];
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( isDefined( level._hacker_pool[ i ]._trigger ) )
|
||||||
|
{
|
||||||
|
level._hacker_pool[ i ]._trigger delete();
|
||||||
|
}
|
||||||
|
level._hacker_pool[ i ]._trigger = undefined;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
level._hacker_pool = new_hacker_pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
should_pooled_object_exist()
|
||||||
|
{
|
||||||
|
players = get_players();
|
||||||
|
i = 0;
|
||||||
|
while ( i < players.size )
|
||||||
|
{
|
||||||
|
if ( players[ i ] hacker_active() )
|
||||||
|
{
|
||||||
|
if ( isDefined( self.entity ) )
|
||||||
|
{
|
||||||
|
if ( self.entity != players[ i ] )
|
||||||
|
{
|
||||||
|
if ( distance2dsquared( players[ i ].origin, self.entity.origin ) <= ( self.radius * self.radius ) )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( distance2dsquared( players[ i ].origin, self.origin ) <= ( self.radius * self.radius ) )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_eligable_pooled_items()
|
||||||
|
{
|
||||||
|
candidates = [];
|
||||||
|
i = 0;
|
||||||
|
while ( i < level._hackable_objects.size )
|
||||||
|
{
|
||||||
|
hackable = level._hackable_objects[ i ];
|
||||||
|
if ( isDefined( hackable.pooled ) && hackable.pooled && !isDefined( hackable._trigger ) )
|
||||||
|
{
|
||||||
|
if ( !isinarray( level._hacker_pool, hackable ) )
|
||||||
|
{
|
||||||
|
if ( hackable should_pooled_object_exist() )
|
||||||
|
{
|
||||||
|
candidates[ candidates.size ] = hackable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
while ( i < candidates.size )
|
||||||
|
{
|
||||||
|
candidate = candidates[ i ];
|
||||||
|
height = 72;
|
||||||
|
radius = 32;
|
||||||
|
if ( isDefined( candidate.radius ) )
|
||||||
|
{
|
||||||
|
radius = candidate.radius;
|
||||||
|
}
|
||||||
|
if ( isDefined( candidate.height ) )
|
||||||
|
{
|
||||||
|
height = candidate.height;
|
||||||
|
}
|
||||||
|
trigger = spawn( "trigger_radius_use", candidate.origin, 0, radius, height );
|
||||||
|
trigger usetriggerrequirelookat();
|
||||||
|
trigger triggerignoreteam();
|
||||||
|
trigger setcursorhint( "HINT_NOICON" );
|
||||||
|
trigger.radius = radius;
|
||||||
|
trigger.height = height;
|
||||||
|
trigger.beinghacked = 0;
|
||||||
|
candidate._trigger = trigger;
|
||||||
|
level._hacker_pool[ level._hacker_pool.size ] = candidate;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get_hackable_trigger()
|
||||||
|
{
|
||||||
|
if ( isDefined( self.door ) )
|
||||||
|
{
|
||||||
|
return self.door;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( isDefined( self.perk ) )
|
||||||
|
{
|
||||||
|
return self.perk;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( isDefined( self.window ) )
|
||||||
|
{
|
||||||
|
return self.window.unitrigger_stub.trigger;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( isDefined( self.classname ) && getsubstr( self.classname, 0, 7 ) == "trigger_" )
|
||||||
|
{
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
any_hackers_active()
|
||||||
|
{
|
||||||
|
players = get_players();
|
||||||
|
i = 0;
|
||||||
|
while ( i < players.size )
|
||||||
|
{
|
||||||
|
if ( players[ i ] hacker_active() )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
register_hackable( name, callback_func, qualifier_func )
|
||||||
|
{
|
||||||
|
structs = getstructarray( name, "script_noteworthy" );
|
||||||
|
if ( !isDefined( structs ) )
|
||||||
|
{
|
||||||
|
/#
|
||||||
|
println( "Error: register_hackable called on script_noteworthy " + name + " but no such structs exist." );
|
||||||
|
#/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
while ( i < structs.size )
|
||||||
|
{
|
||||||
|
if ( !isinarray( level._hackable_objects, structs[ i ] ) )
|
||||||
|
{
|
||||||
|
structs[ i ]._hack_callback_func = callback_func;
|
||||||
|
structs[ i ]._hack_qualifier_func = qualifier_func;
|
||||||
|
structs[ i ].pooled = level._hacker_pooled;
|
||||||
|
if ( isDefined( structs[ i ].targetname ) )
|
||||||
|
{
|
||||||
|
structs[ i ].hacker_target = getent( structs[ i ].targetname, "targetname" );
|
||||||
|
}
|
||||||
|
level._hackable_objects[ level._hackable_objects.size ] = structs[ i ];
|
||||||
|
if ( isDefined( level._hacker_pooled ) )
|
||||||
|
{
|
||||||
|
level._pooled_hackable_objects[ level._pooled_hackable_objects.size ] = structs[ i ];
|
||||||
|
}
|
||||||
|
structs[ i ] thread hackable_object_thread();
|
||||||
|
wait_network_frame();
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
register_hackable_struct( struct, callback_func, qualifier_func )
|
||||||
|
{
|
||||||
|
if ( !isinarray( level._hackable_objects, struct ) )
|
||||||
|
{
|
||||||
|
struct._hack_callback_func = callback_func;
|
||||||
|
struct._hack_qualifier_func = qualifier_func;
|
||||||
|
struct.pooled = level._hacker_pooled;
|
||||||
|
if ( isDefined( struct.targetname ) )
|
||||||
|
{
|
||||||
|
struct.hacker_target = getent( struct.targetname, "targetname" );
|
||||||
|
}
|
||||||
|
level._hackable_objects[ level._hackable_objects.size ] = struct;
|
||||||
|
if ( isDefined( level._hacker_pooled ) )
|
||||||
|
{
|
||||||
|
level._pooled_hackable_objects[ level._pooled_hackable_objects.size ] = struct;
|
||||||
|
}
|
||||||
|
struct thread hackable_object_thread();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
register_pooled_hackable_struct( struct, callback_func, qualifier_func )
|
||||||
|
{
|
||||||
|
level._hacker_pooled = 1;
|
||||||
|
register_hackable_struct( struct, callback_func, qualifier_func );
|
||||||
|
level._hacker_pooled = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
register_pooled_hackable( name, callback_func, qualifier_func )
|
||||||
|
{
|
||||||
|
level._hacker_pooled = 1;
|
||||||
|
register_hackable( name, callback_func, qualifier_func );
|
||||||
|
level._hacker_pooled = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
deregister_hackable_struct( struct )
|
||||||
|
{
|
||||||
|
if ( isinarray( level._hackable_objects, struct ) )
|
||||||
|
{
|
||||||
|
new_list = [];
|
||||||
|
i = 0;
|
||||||
|
while ( i < level._hackable_objects.size )
|
||||||
|
{
|
||||||
|
if ( level._hackable_objects[ i ] != struct )
|
||||||
|
{
|
||||||
|
new_list[ new_list.size ] = level._hackable_objects[ i ];
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
level._hackable_objects[ i ] notify( "hackable_deregistered" );
|
||||||
|
if ( isDefined( level._hackable_objects[ i ]._trigger ) )
|
||||||
|
{
|
||||||
|
level._hackable_objects[ i ]._trigger delete();
|
||||||
|
}
|
||||||
|
if ( isDefined( level._hackable_objects[ i ].pooled ) && level._hackable_objects[ i ].pooled )
|
||||||
|
{
|
||||||
|
arrayremovevalue( level._hacker_pool, level._hackable_objects[ i ] );
|
||||||
|
arrayremovevalue( level._pooled_hackable_objects, level._hackable_objects[ i ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
level._hackable_objects = new_list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deregister_hackable( noteworthy )
|
||||||
|
{
|
||||||
|
new_list = [];
|
||||||
|
i = 0;
|
||||||
|
while ( i < level._hackable_objects.size )
|
||||||
|
{
|
||||||
|
if ( !isDefined( level._hackable_objects[ i ].script_noteworthy ) || level._hackable_objects[ i ].script_noteworthy != noteworthy )
|
||||||
|
{
|
||||||
|
new_list[ new_list.size ] = level._hackable_objects[ i ];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
level._hackable_objects[ i ] notify( "hackable_deregistered" );
|
||||||
|
if ( isDefined( level._hackable_objects[ i ]._trigger ) )
|
||||||
|
{
|
||||||
|
level._hackable_objects[ i ]._trigger delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( isDefined( level._hackable_objects[ i ].pooled ) && level._hackable_objects[ i ].pooled )
|
||||||
|
{
|
||||||
|
arrayremovevalue( level._hacker_pool, level._hackable_objects[ i ] );
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
level._hackable_objects = new_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
hack_trigger_think()
|
||||||
|
{
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
players = get_players();
|
||||||
|
i = 0;
|
||||||
|
while ( i < players.size )
|
||||||
|
{
|
||||||
|
player = players[ i ];
|
||||||
|
j = 0;
|
||||||
|
while ( j < level._hackable_objects.size )
|
||||||
|
{
|
||||||
|
hackable = level._hackable_objects[ j ];
|
||||||
|
if ( isDefined( hackable._trigger ) )
|
||||||
|
{
|
||||||
|
qualifier_passed = 1;
|
||||||
|
if ( isDefined( hackable._hack_qualifier_func ) )
|
||||||
|
{
|
||||||
|
qualifier_passed = hackable [[ hackable._hack_qualifier_func ]]( player );
|
||||||
|
}
|
||||||
|
if ( player hacker_active() && qualifier_passed && !hackable._trigger.beinghacked )
|
||||||
|
{
|
||||||
|
hackable._trigger setinvisibletoplayer( player, 0 );
|
||||||
|
j++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hackable._trigger setinvisibletoplayer( player, 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
wait 0.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is_facing( facee )
|
||||||
|
{
|
||||||
|
orientation = self getplayerangles();
|
||||||
|
forwardvec = anglesToForward( orientation );
|
||||||
|
forwardvec2d = ( forwardvec[ 0 ], forwardvec[ 1 ], 0 );
|
||||||
|
unitforwardvec2d = vectornormalize( forwardvec2d );
|
||||||
|
tofaceevec = facee.origin - self.origin;
|
||||||
|
tofaceevec2d = ( tofaceevec[ 0 ], tofaceevec[ 1 ], 0 );
|
||||||
|
unittofaceevec2d = vectornormalize( tofaceevec2d );
|
||||||
|
dotproduct = vectordot( unitforwardvec2d, unittofaceevec2d );
|
||||||
|
dot_limit = 0.8;
|
||||||
|
if ( isDefined( facee.dot_limit ) )
|
||||||
|
{
|
||||||
|
dot_limit = facee.dot_limit;
|
||||||
|
}
|
||||||
|
return dotproduct > dot_limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
can_hack( hackable )
|
||||||
|
{
|
||||||
|
if ( !isalive( self ) )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( self maps/mp/zombies/_zm_laststand::player_is_in_laststand() )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( !self hacker_active() )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( !isDefined( hackable._trigger ) )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( isDefined( hackable.player ) )
|
||||||
|
{
|
||||||
|
if ( hackable.player != self )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( self throwbuttonpressed() )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( self fragbuttonpressed() )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( isDefined( hackable._hack_qualifier_func ) )
|
||||||
|
{
|
||||||
|
if ( !( hackable [[ hackable._hack_qualifier_func ]]( self ) ) )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !isinarray( level._hackable_objects, hackable ) )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
radsquared = 1024;
|
||||||
|
if ( isDefined( hackable.radius ) )
|
||||||
|
{
|
||||||
|
radsquared = hackable.radius * hackable.radius;
|
||||||
|
}
|
||||||
|
origin = hackable.origin;
|
||||||
|
if ( isDefined( hackable.entity ) )
|
||||||
|
{
|
||||||
|
origin = hackable.entity.origin;
|
||||||
|
}
|
||||||
|
if ( distance2dsquared( self.origin, origin ) > radsquared )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( !isDefined( hackable.no_touch_check ) && !self istouching( hackable._trigger ) )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( !self is_facing( hackable ) )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( !isDefined( hackable.no_sight_check ) && !sighttracepassed( self.origin + vectorScale( ( 0, 0, 1 ), 50 ), origin, 0, undefined ) )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( !isDefined( hackable.no_bullet_trace ) && !bullettracepassed( self.origin + vectorScale( ( 0, 0, 1 ), 50 ), origin, 0, undefined ) )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_hacking( hackable )
|
||||||
|
{
|
||||||
|
if ( can_hack( hackable ) )
|
||||||
|
{
|
||||||
|
return self usebuttonpressed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set_hack_hint_string()
|
||||||
|
{
|
||||||
|
if ( isDefined( self._trigger ) )
|
||||||
|
{
|
||||||
|
if ( isDefined( self.custom_string ) )
|
||||||
|
{
|
||||||
|
self._trigger sethintstring( self.custom_string );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if ( !isDefined( self.script_int ) || self.script_int <= 0 )
|
||||||
|
{
|
||||||
|
self._trigger sethintstring( &"ZOMBIE_HACK_NO_COST" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self._trigger sethintstring( &"ZOMBIE_HACK", self.script_int );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tidy_on_deregister( hackable )
|
||||||
|
{
|
||||||
|
self endon( "clean_up_tidy_up" );
|
||||||
|
hackable waittill( "hackable_deregistered" );
|
||||||
|
if ( isDefined( self.hackerprogressbar ) )
|
||||||
|
{
|
||||||
|
self.hackerprogressbar maps/mp/gametypes_zm/_hud_util::destroyelem();
|
||||||
|
}
|
||||||
|
if ( isDefined( self.hackertexthud ) )
|
||||||
|
{
|
||||||
|
self.hackertexthud destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hacker_do_hack( hackable )
|
||||||
|
{
|
||||||
|
timer = 0;
|
||||||
|
hacked = 0;
|
||||||
|
hackable._trigger.beinghacked = 1;
|
||||||
|
if ( !isDefined( self.hackerprogressbar ) )
|
||||||
|
{
|
||||||
|
self.hackerprogressbar = self maps/mp/gametypes_zm/_hud_util::createprimaryprogressbar();
|
||||||
|
}
|
||||||
|
if ( !isDefined( self.hackertexthud ) )
|
||||||
|
{
|
||||||
|
self.hackertexthud = newclienthudelem( self );
|
||||||
|
}
|
||||||
|
hack_duration = hackable.script_float;
|
||||||
|
if ( self hasperk( "specialty_fastreload" ) )
|
||||||
|
{
|
||||||
|
hack_duration *= 0.66;
|
||||||
|
}
|
||||||
|
hack_duration = max( 1.5, hack_duration );
|
||||||
|
self thread tidy_on_deregister( hackable );
|
||||||
|
self.hackerprogressbar maps/mp/gametypes_zm/_hud_util::updatebar( 0.01, 1 / hack_duration );
|
||||||
|
self.hackertexthud.alignx = "center";
|
||||||
|
self.hackertexthud.aligny = "middle";
|
||||||
|
self.hackertexthud.horzalign = "center";
|
||||||
|
self.hackertexthud.vertalign = "bottom";
|
||||||
|
self.hackertexthud.y = -113;
|
||||||
|
if ( issplitscreen() )
|
||||||
|
{
|
||||||
|
self.hackertexthud.y = -107;
|
||||||
|
}
|
||||||
|
self.hackertexthud.foreground = 1;
|
||||||
|
self.hackertexthud.font = "default";
|
||||||
|
self.hackertexthud.fontscale = 1.8;
|
||||||
|
self.hackertexthud.alpha = 1;
|
||||||
|
self.hackertexthud.color = ( 0, 0, 1 );
|
||||||
|
self.hackertexthud settext( &"ZOMBIE_HACKING" );
|
||||||
|
self playloopsound( "zmb_progress_bar", 0,5 );
|
||||||
|
while ( self is_hacking( hackable ) )
|
||||||
|
{
|
||||||
|
wait 0.05;
|
||||||
|
timer += 0.05;
|
||||||
|
if ( self maps/mp/zombies/_zm_laststand::player_is_in_laststand() )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if ( timer >= hack_duration )
|
||||||
|
{
|
||||||
|
hacked = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self stoploopsound( 0.5 );
|
||||||
|
if ( hacked )
|
||||||
|
{
|
||||||
|
self playsound( "vox_mcomp_hack_success" );
|
||||||
|
}
|
||||||
|
else self playsound( "vox_mcomp_hack_fail" );
|
||||||
|
if ( isDefined( self.hackerprogressbar ) )
|
||||||
|
{
|
||||||
|
self.hackerprogressbar maps/mp/gametypes_zm/_hud_util::destroyelem();
|
||||||
|
}
|
||||||
|
if ( isDefined( self.hackertexthud ) )
|
||||||
|
{
|
||||||
|
self.hackertexthud destroy();
|
||||||
|
}
|
||||||
|
hackable set_hack_hint_string();
|
||||||
|
if ( isDefined( hackable._trigger ) )
|
||||||
|
{
|
||||||
|
hackable._trigger.beinghacked = 0;
|
||||||
|
}
|
||||||
|
self notify( "clean_up_tidy_up" );
|
||||||
|
return hacked;
|
||||||
|
}
|
||||||
|
|
||||||
|
lowreadywatcher( player )
|
||||||
|
{
|
||||||
|
player endon( "disconnected" );
|
||||||
|
self endon( "kill_lowreadywatcher" );
|
||||||
|
self waittill( "hackable_deregistered" );
|
||||||
|
}
|
||||||
|
|
||||||
|
hackable_object_thread()
|
||||||
|
{
|
||||||
|
self endon( "hackable_deregistered" );
|
||||||
|
height = 72;
|
||||||
|
radius = 64;
|
||||||
|
if ( isDefined( self.radius ) )
|
||||||
|
{
|
||||||
|
radius = self.radius;
|
||||||
|
}
|
||||||
|
if ( isDefined( self.height ) )
|
||||||
|
{
|
||||||
|
height = self.height;
|
||||||
|
}
|
||||||
|
if ( !isDefined( self.pooled ) )
|
||||||
|
{
|
||||||
|
trigger = spawn( "trigger_radius_use", self.origin, 0, radius, height );
|
||||||
|
trigger usetriggerrequirelookat();
|
||||||
|
trigger setcursorhint( "HINT_NOICON" );
|
||||||
|
trigger.radius = radius;
|
||||||
|
trigger.height = height;
|
||||||
|
trigger.beinghacked = 0;
|
||||||
|
self._trigger = trigger;
|
||||||
|
}
|
||||||
|
cost = 0;
|
||||||
|
if ( isDefined( self.script_int ) )
|
||||||
|
{
|
||||||
|
cost = self.script_int;
|
||||||
|
}
|
||||||
|
duration = 1;
|
||||||
|
if ( isDefined( self.script_float ) )
|
||||||
|
{
|
||||||
|
duration = self.script_float;
|
||||||
|
}
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
wait 0.1;
|
||||||
|
while ( !isDefined( self._trigger ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
players = get_players();
|
||||||
|
if ( isDefined( self._trigger ) )
|
||||||
|
{
|
||||||
|
if ( isDefined( self.entity ) )
|
||||||
|
{
|
||||||
|
self.origin = self.entity.origin;
|
||||||
|
self._trigger.origin = self.entity.origin;
|
||||||
|
if ( isDefined( self.trigger_offset ) )
|
||||||
|
{
|
||||||
|
self._trigger.origin += self.trigger_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
while ( i < players.size )
|
||||||
|
{
|
||||||
|
if ( players[ i ] can_hack( self ) )
|
||||||
|
{
|
||||||
|
self set_hack_hint_string();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
while ( i < players.size )
|
||||||
|
{
|
||||||
|
hacker = players[ i ];
|
||||||
|
if ( !hacker is_hacking( self ) )
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if ( hacker.score >= cost || cost <= 0 )
|
||||||
|
{
|
||||||
|
self thread lowreadywatcher( hacker );
|
||||||
|
hack_success = hacker hacker_do_hack( self );
|
||||||
|
self notify( "kill_lowreadywatcher" );
|
||||||
|
if ( isDefined( hacker ) )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
if ( isDefined( hacker ) && hack_success )
|
||||||
|
{
|
||||||
|
if ( cost )
|
||||||
|
{
|
||||||
|
if ( cost > 0 )
|
||||||
|
{
|
||||||
|
hacker maps/mp/zombies/_zm_score::minus_to_player_score( cost );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hacker maps/mp/zombies/_zm_score::add_to_player_score( cost * -1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hacker notify( "successful_hack" );
|
||||||
|
if ( isDefined( self._hack_callback_func ) )
|
||||||
|
{
|
||||||
|
self thread [[ self._hack_callback_func ]]( hacker );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hacker play_sound_on_ent( "no_purchase" );
|
||||||
|
hacker maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "no_money", undefined, 1 );
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hacker_on_player_connect()
|
||||||
|
{
|
||||||
|
struct = spawnstruct();
|
||||||
|
struct.origin = self.origin;
|
||||||
|
struct.radius = 48;
|
||||||
|
struct.height = 64;
|
||||||
|
struct.script_float = 10;
|
||||||
|
struct.script_int = 500;
|
||||||
|
struct.entity = self;
|
||||||
|
struct.trigger_offset = vectorScale( ( 0, 0, 1 ), 48 );
|
||||||
|
register_pooled_hackable_struct( struct, ::player_hack, ::player_qualifier );
|
||||||
|
struct thread player_hack_disconnect_watcher( self );
|
||||||
|
}
|
||||||
|
|
||||||
|
player_hack_disconnect_watcher( player )
|
||||||
|
{
|
||||||
|
player waittill( "disconnect" );
|
||||||
|
deregister_hackable_struct( self );
|
||||||
|
}
|
||||||
|
|
||||||
|
player_hack( hacker )
|
||||||
|
{
|
||||||
|
if ( isDefined( self.entity ) )
|
||||||
|
{
|
||||||
|
self.entity maps/mp/zombies/_zm_score::player_add_points( "hacker_transfer", 500 );
|
||||||
|
}
|
||||||
|
if ( isDefined( hacker ) )
|
||||||
|
{
|
||||||
|
hacker thread maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "hack_plr" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
player_qualifier( player )
|
||||||
|
{
|
||||||
|
if ( player == self.entity )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( self.entity maps/mp/zombies/_zm_laststand::player_is_in_laststand() )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( player maps/mp/zombies/_zm_laststand::player_is_in_laststand() )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( isDefined( self.entity.sessionstate == "spectator" ) && self.entity.sessionstate == "spectator" )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
hide_hint_when_hackers_active( custom_logic_func, custom_logic_func_param )
|
||||||
|
{
|
||||||
|
invis_to_any = 0;
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
if ( isDefined( custom_logic_func ) )
|
||||||
|
{
|
||||||
|
self [[ custom_logic_func ]]( custom_logic_func_param );
|
||||||
|
}
|
||||||
|
if ( maps/mp/zombies/_zm_equip_hacker::any_hackers_active() )
|
||||||
|
{
|
||||||
|
players = get_players();
|
||||||
|
i = 0;
|
||||||
|
while ( i < players.size )
|
||||||
|
{
|
||||||
|
if ( players[ i ] hacker_active() )
|
||||||
|
{
|
||||||
|
self setinvisibletoplayer( players[ i ], 1 );
|
||||||
|
invis_to_any = 1;
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self setinvisibletoplayer( players[ i ], 0 );
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else while ( invis_to_any )
|
||||||
|
{
|
||||||
|
invis_to_any = 0;
|
||||||
|
players = get_players();
|
||||||
|
i = 0;
|
||||||
|
while ( i < players.size )
|
||||||
|
{
|
||||||
|
self setinvisibletoplayer( players[ i ], 0 );
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wait 0.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hacker_debug_print( msg, color )
|
||||||
|
{
|
||||||
|
/#
|
||||||
|
if ( !getDvarInt( #"428DE100" ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( !isDefined( color ) )
|
||||||
|
{
|
||||||
|
color = ( 0, 0, 1 );
|
||||||
|
}
|
||||||
|
print3d( self.origin + vectorScale( ( 0, 0, 1 ), 60 ), msg, color, 1, 1, 40 );
|
||||||
|
#/
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,81 @@
|
|||||||
|
#include maps/mp/zombies/_zm_utility;
|
||||||
|
#include maps/mp/_utility;
|
||||||
|
#include common_scripts/utility;
|
||||||
|
|
||||||
|
init()
|
||||||
|
{
|
||||||
|
if ( isDefined( level.disable_blackscreen_clientfield ) && !level.disable_blackscreen_clientfield )
|
||||||
|
{
|
||||||
|
registerclientfield( "toplayer", "blackscreen", 1, 1, "int" );
|
||||||
|
}
|
||||||
|
if ( !isDefined( level.uses_gumps ) )
|
||||||
|
{
|
||||||
|
level.uses_gumps = 0;
|
||||||
|
}
|
||||||
|
if ( isDefined( level.uses_gumps ) && level.uses_gumps )
|
||||||
|
{
|
||||||
|
onplayerconnect_callback( ::player_connect_gump );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
player_teleport_blackscreen_on()
|
||||||
|
{
|
||||||
|
if ( isDefined( level.disable_blackscreen_clientfield ) && level.disable_blackscreen_clientfield )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( isDefined( level.uses_gumps ) && level.uses_gumps )
|
||||||
|
{
|
||||||
|
self setclientfieldtoplayer( "blackscreen", 1 );
|
||||||
|
wait 0.05;
|
||||||
|
self setclientfieldtoplayer( "blackscreen", 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
player_connect_gump()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
player_watch_spectate_change()
|
||||||
|
{
|
||||||
|
if ( isDefined( level.disable_blackscreen_clientfield ) && level.disable_blackscreen_clientfield )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self endon( "disconnect" );
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
self waittill( "spectator_cycle" );
|
||||||
|
self setclientfieldtoplayer( "blackscreen", 1 );
|
||||||
|
wait 0.05;
|
||||||
|
self setclientfieldtoplayer( "blackscreen", 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gump_test()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
wait 10;
|
||||||
|
pos1 = ( -4904, -7657, 4 );
|
||||||
|
pos3 = ( 7918, -6506, 177 );
|
||||||
|
pos2 = ( 1986, -73, 4 );
|
||||||
|
players = get_players();
|
||||||
|
if ( isDefined( players[ 0 ] ) )
|
||||||
|
{
|
||||||
|
players[ 0 ] setorigin( pos1 );
|
||||||
|
}
|
||||||
|
wait 0.05;
|
||||||
|
if ( isDefined( players[ 1 ] ) )
|
||||||
|
{
|
||||||
|
players[ 1 ] setorigin( pos2 );
|
||||||
|
}
|
||||||
|
wait 0.05;
|
||||||
|
if ( isDefined( players[ 2 ] ) )
|
||||||
|
{
|
||||||
|
players[ 2 ] setorigin( pos3 );
|
||||||
|
#/
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,131 @@
|
|||||||
|
#include maps/mp/zombies/_zm_blockers;
|
||||||
|
#include maps/mp/zombies/_zm_score;
|
||||||
|
#include maps/mp/zombies/_zm_equip_hacker;
|
||||||
|
#include maps/mp/zombies/_zm_utility;
|
||||||
|
#include maps/mp/_utility;
|
||||||
|
#include common_scripts/utility;
|
||||||
|
|
||||||
|
hack_boards()
|
||||||
|
{
|
||||||
|
windows = getstructarray( "exterior_goal", "targetname" );
|
||||||
|
i = 0;
|
||||||
|
while ( i < windows.size )
|
||||||
|
{
|
||||||
|
window = windows[ i ];
|
||||||
|
struct = spawnstruct();
|
||||||
|
spot = window;
|
||||||
|
if ( isDefined( window.trigger_location ) )
|
||||||
|
{
|
||||||
|
spot = window.trigger_location;
|
||||||
|
}
|
||||||
|
org = groundpos( spot.origin ) + vectorScale( ( 0, 0, 1 ), 4 );
|
||||||
|
r = 96;
|
||||||
|
h = 96;
|
||||||
|
if ( isDefined( spot.radius ) )
|
||||||
|
{
|
||||||
|
r = spot.radius;
|
||||||
|
}
|
||||||
|
if ( isDefined( spot.height ) )
|
||||||
|
{
|
||||||
|
h = spot.height;
|
||||||
|
}
|
||||||
|
struct.origin = org + vectorScale( ( 0, 0, 1 ), 48 );
|
||||||
|
struct.radius = r;
|
||||||
|
struct.height = h;
|
||||||
|
struct.script_float = 2;
|
||||||
|
struct.script_int = 0;
|
||||||
|
struct.window = window;
|
||||||
|
struct.no_bullet_trace = 1;
|
||||||
|
struct.no_sight_check = 1;
|
||||||
|
struct.dot_limit = 0.7;
|
||||||
|
struct.no_touch_check = 1;
|
||||||
|
struct.last_hacked_round = 0;
|
||||||
|
struct.num_hacks = 0;
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::register_pooled_hackable_struct( struct, ::board_hack, ::board_qualifier );
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
board_hack( hacker )
|
||||||
|
{
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::deregister_hackable_struct( self );
|
||||||
|
num_chunks_checked = 0;
|
||||||
|
last_repaired_chunk = undefined;
|
||||||
|
if ( self.last_hacked_round != level.round_number )
|
||||||
|
{
|
||||||
|
self.last_hacked_round = level.round_number;
|
||||||
|
self.num_hacks = 0;
|
||||||
|
}
|
||||||
|
self.num_hacks++;
|
||||||
|
if ( self.num_hacks < 3 )
|
||||||
|
{
|
||||||
|
hacker maps/mp/zombies/_zm_score::add_to_player_score( 100 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cost = int( min( 300, hacker.score ) );
|
||||||
|
if ( cost )
|
||||||
|
{
|
||||||
|
hacker maps/mp/zombies/_zm_score::minus_to_player_score( cost );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
if ( all_chunks_intact( self.window, self.window.barrier_chunks ) )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else chunk = get_random_destroyed_chunk( self.window, self.window.barrier_chunks );
|
||||||
|
if ( !isDefined( chunk ) )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else self.window thread maps/mp/zombies/_zm_blockers::replace_chunk( self.window, chunk, undefined, 0, 1 );
|
||||||
|
last_repaired_chunk = chunk;
|
||||||
|
if ( isDefined( self.clip ) )
|
||||||
|
{
|
||||||
|
self.window.clip enable_trigger();
|
||||||
|
self.window.clip disconnectpaths();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
blocker_disconnect_paths( self.window.neg_start, self.window.neg_end );
|
||||||
|
}
|
||||||
|
wait_network_frame();
|
||||||
|
num_chunks_checked++;
|
||||||
|
if ( num_chunks_checked >= 20 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( isDefined( self.window.zbarrier ) )
|
||||||
|
{
|
||||||
|
while ( isDefined( last_repaired_chunk ) )
|
||||||
|
{
|
||||||
|
while ( self.window.zbarrier getzbarrierpiecestate( last_repaired_chunk ) == "closing" )
|
||||||
|
{
|
||||||
|
wait 0.05;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else while ( isDefined( last_repaired_chunk ) && last_repaired_chunk.state == "mid_repair" )
|
||||||
|
{
|
||||||
|
wait 0.05;
|
||||||
|
}
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::register_pooled_hackable_struct( self, ::board_hack, ::board_qualifier );
|
||||||
|
self.window notify( "blocker_hacked" );
|
||||||
|
self.window notify( "no valid boards" );
|
||||||
|
}
|
||||||
|
|
||||||
|
board_qualifier( player )
|
||||||
|
{
|
||||||
|
if ( all_chunks_intact( self.window, self.window.barrier_chunks ) || no_valid_repairable_boards( self.window, self.window.barrier_chunks ) )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,371 @@
|
|||||||
|
#include maps/mp/zombies/_zm_audio;
|
||||||
|
#include maps/mp/zombies/_zm_weapons;
|
||||||
|
#include maps/mp/zombies/_zm_equip_hacker;
|
||||||
|
#include maps/mp/zombies/_zm_magicbox;
|
||||||
|
#include maps/mp/zombies/_zm_utility;
|
||||||
|
#include maps/mp/_utility;
|
||||||
|
#include common_scripts/utility;
|
||||||
|
|
||||||
|
box_hacks()
|
||||||
|
{
|
||||||
|
boxes = getstructarray( "treasure_chest_use", "targetname" );
|
||||||
|
i = 0;
|
||||||
|
while ( i < boxes.size )
|
||||||
|
{
|
||||||
|
box = boxes[ i ];
|
||||||
|
box.box_hacks[ "respin" ] = ::init_box_respin;
|
||||||
|
box.box_hacks[ "respin_respin" ] = ::init_box_respin_respin;
|
||||||
|
box.box_hacks[ "summon_box" ] = ::init_summon_box;
|
||||||
|
box.last_hacked_round = 0;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
level._zombiemode_chest_joker_chance_override_func = ::check_for_free_locations;
|
||||||
|
level._zombiemode_custom_box_move_logic = ::custom_box_move_logic;
|
||||||
|
level._zombiemode_check_firesale_loc_valid_func = ::custom_check_firesale_loc_valid_func;
|
||||||
|
init_summon_hacks();
|
||||||
|
}
|
||||||
|
|
||||||
|
custom_check_firesale_loc_valid_func()
|
||||||
|
{
|
||||||
|
if ( isDefined( self.unitrigger_stub ) )
|
||||||
|
{
|
||||||
|
box = self.unitrigger_stub.trigger_target;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( isDefined( self.stub ) )
|
||||||
|
{
|
||||||
|
box = self.stub.trigger_target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( box.last_hacked_round >= level.round_number )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
custom_box_move_logic()
|
||||||
|
{
|
||||||
|
num_hacked_locs = 0;
|
||||||
|
i = 0;
|
||||||
|
while ( i < level.chests.size )
|
||||||
|
{
|
||||||
|
if ( level.chests[ i ].last_hacked_round >= level.round_number )
|
||||||
|
{
|
||||||
|
num_hacked_locs++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if ( num_hacked_locs == 0 )
|
||||||
|
{
|
||||||
|
maps/mp/zombies/_zm_magicbox::default_box_move_logic();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
found_loc = 0;
|
||||||
|
original_spot = level.chest_index;
|
||||||
|
while ( !found_loc )
|
||||||
|
{
|
||||||
|
level.chest_index++;
|
||||||
|
if ( original_spot == level.chest_index )
|
||||||
|
{
|
||||||
|
level.chest_index++;
|
||||||
|
}
|
||||||
|
level.chest_index %= level.chests.size;
|
||||||
|
if ( level.chests[ level.chest_index ].last_hacked_round < level.round_number )
|
||||||
|
{
|
||||||
|
found_loc = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
check_for_free_locations( chance )
|
||||||
|
{
|
||||||
|
boxes = level.chests;
|
||||||
|
stored_chance = chance;
|
||||||
|
chance = -1;
|
||||||
|
i = 0;
|
||||||
|
while ( i < boxes.size )
|
||||||
|
{
|
||||||
|
if ( i == level.chest_index )
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if ( boxes[ i ].last_hacked_round < level.round_number )
|
||||||
|
{
|
||||||
|
chance = stored_chance;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return chance;
|
||||||
|
}
|
||||||
|
|
||||||
|
init_box_respin( chest, player )
|
||||||
|
{
|
||||||
|
self thread box_respin_think( chest, player );
|
||||||
|
}
|
||||||
|
|
||||||
|
box_respin_think( chest, player )
|
||||||
|
{
|
||||||
|
respin_hack = spawnstruct();
|
||||||
|
respin_hack.origin = self.origin + vectorScale( ( 0, 0, 1 ), 24 );
|
||||||
|
respin_hack.radius = 48;
|
||||||
|
respin_hack.height = 72;
|
||||||
|
respin_hack.script_int = 600;
|
||||||
|
respin_hack.script_float = 1.5;
|
||||||
|
respin_hack.player = player;
|
||||||
|
respin_hack.no_bullet_trace = 1;
|
||||||
|
respin_hack.chest = chest;
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::register_pooled_hackable_struct( respin_hack, ::respin_box, ::hack_box_qualifier );
|
||||||
|
self.weapon_model waittill_either( "death", "kill_respin_think_thread" );
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::deregister_hackable_struct( respin_hack );
|
||||||
|
}
|
||||||
|
|
||||||
|
respin_box_thread( hacker )
|
||||||
|
{
|
||||||
|
if ( isDefined( self.chest.zbarrier.weapon_model ) )
|
||||||
|
{
|
||||||
|
self.chest.zbarrier.weapon_model notify( "kill_respin_think_thread" );
|
||||||
|
}
|
||||||
|
self.chest.no_fly_away = 1;
|
||||||
|
self.chest.zbarrier notify( "box_hacked_respin" );
|
||||||
|
self.chest disable_trigger();
|
||||||
|
play_sound_at_pos( "open_chest", self.chest.zbarrier.origin );
|
||||||
|
play_sound_at_pos( "music_chest", self.chest.zbarrier.origin );
|
||||||
|
maps/mp/zombies/_zm_weapons::unacquire_weapon_toggle( self.chest.zbarrier.weapon_string );
|
||||||
|
self.chest.zbarrier thread maps/mp/zombies/_zm_magicbox::treasure_chest_weapon_spawn( self.chest, hacker, 1 );
|
||||||
|
self.chest.zbarrier waittill( "randomization_done" );
|
||||||
|
self.chest.no_fly_away = undefined;
|
||||||
|
if ( !flag( "moving_chest_now" ) )
|
||||||
|
{
|
||||||
|
self.chest enable_trigger();
|
||||||
|
self.chest thread maps/mp/zombies/_zm_magicbox::treasure_chest_timeout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
respin_box( hacker )
|
||||||
|
{
|
||||||
|
self thread respin_box_thread( hacker );
|
||||||
|
}
|
||||||
|
|
||||||
|
hack_box_qualifier( player )
|
||||||
|
{
|
||||||
|
if ( player == self.chest.chest_user && isDefined( self.chest.weapon_out ) )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
init_box_respin_respin( chest, player )
|
||||||
|
{
|
||||||
|
self thread box_respin_respin_think( chest, player );
|
||||||
|
}
|
||||||
|
|
||||||
|
box_respin_respin_think( chest, player )
|
||||||
|
{
|
||||||
|
respin_hack = spawnstruct();
|
||||||
|
respin_hack.origin = self.origin + vectorScale( ( 0, 0, 1 ), 24 );
|
||||||
|
respin_hack.radius = 48;
|
||||||
|
respin_hack.height = 72;
|
||||||
|
respin_hack.script_int = -950;
|
||||||
|
respin_hack.script_float = 1.5;
|
||||||
|
respin_hack.player = player;
|
||||||
|
respin_hack.no_bullet_trace = 1;
|
||||||
|
respin_hack.chest = chest;
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::register_pooled_hackable_struct( respin_hack, ::respin_respin_box, ::hack_box_qualifier );
|
||||||
|
self.weapon_model waittill_either( "death", "kill_respin_respin_think_thread" );
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::deregister_hackable_struct( respin_hack );
|
||||||
|
}
|
||||||
|
|
||||||
|
respin_respin_box( hacker )
|
||||||
|
{
|
||||||
|
org = self.chest.zbarrier.origin;
|
||||||
|
if ( isDefined( self.chest.zbarrier.weapon_model ) )
|
||||||
|
{
|
||||||
|
self.chest.zbarrier.weapon_model notify( "kill_respin_respin_think_thread" );
|
||||||
|
self.chest.zbarrier.weapon_model notify( "kill_weapon_movement" );
|
||||||
|
self.chest.zbarrier.weapon_model moveto( org + vectorScale( ( 0, 0, 1 ), 40 ), 0,5 );
|
||||||
|
}
|
||||||
|
if ( isDefined( self.chest.zbarrier.weapon_model_dw ) )
|
||||||
|
{
|
||||||
|
self.chest.zbarrier.weapon_model_dw notify( "kill_weapon_movement" );
|
||||||
|
self.chest.zbarrier.weapon_model_dw moveto( ( org + vectorScale( ( 0, 0, 1 ), 40 ) ) - vectorScale( ( 0, 0, 1 ), 3 ), 0,5 );
|
||||||
|
}
|
||||||
|
self.chest.zbarrier notify( "box_hacked_rerespin" );
|
||||||
|
self.chest.box_rerespun = 1;
|
||||||
|
self thread fake_weapon_powerup_thread( self.chest.zbarrier.weapon_model, self.chest.zbarrier.weapon_model_dw );
|
||||||
|
}
|
||||||
|
|
||||||
|
fake_weapon_powerup_thread( weapon1, weapon2 )
|
||||||
|
{
|
||||||
|
weapon1 endon( "death" );
|
||||||
|
playfxontag( level._effect[ "powerup_on_solo" ], weapon1, "tag_origin" );
|
||||||
|
playsoundatposition( "zmb_spawn_powerup", weapon1.origin );
|
||||||
|
weapon1 playloopsound( "zmb_spawn_powerup_loop" );
|
||||||
|
self thread fake_weapon_powerup_timeout( weapon1, weapon2 );
|
||||||
|
while ( isDefined( weapon1 ) )
|
||||||
|
{
|
||||||
|
waittime = randomfloatrange( 2.5, 5 );
|
||||||
|
yaw = randomint( 360 );
|
||||||
|
if ( yaw > 300 )
|
||||||
|
{
|
||||||
|
yaw = 300;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( yaw < 60 )
|
||||||
|
{
|
||||||
|
yaw = 60;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
yaw = weapon1.angles[ 1 ] + yaw;
|
||||||
|
weapon1 rotateto( ( -60 + randomint( 120 ), yaw, -45 + randomint( 90 ) ), waittime, waittime * 0.5, waittime * 0.5 );
|
||||||
|
if ( isDefined( weapon2 ) )
|
||||||
|
{
|
||||||
|
weapon2 rotateto( ( -60 + randomint( 120 ), yaw, -45 + randomint( 90 ) ), waittime, waittime * 0.5, waittime * 0.5 );
|
||||||
|
}
|
||||||
|
wait randomfloat( waittime - 0,1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fake_weapon_powerup_timeout( weapon1, weapon2 )
|
||||||
|
{
|
||||||
|
weapon1 endon( "death" );
|
||||||
|
wait 15;
|
||||||
|
i = 0;
|
||||||
|
while ( i < 40 )
|
||||||
|
{
|
||||||
|
if ( i % 2 )
|
||||||
|
{
|
||||||
|
weapon1 hide();
|
||||||
|
if ( isDefined( weapon2 ) )
|
||||||
|
{
|
||||||
|
weapon2 hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
weapon1 show();
|
||||||
|
if ( isDefined( weapon2 ) )
|
||||||
|
{
|
||||||
|
weapon2 hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( i < 15 )
|
||||||
|
{
|
||||||
|
wait 0.5;
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if ( i < 25 )
|
||||||
|
{
|
||||||
|
wait 0.25;
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wait 0.1;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
self.chest notify( "trigger" );
|
||||||
|
if ( isDefined( weapon1 ) )
|
||||||
|
{
|
||||||
|
weapon1 delete();
|
||||||
|
}
|
||||||
|
if ( isDefined( weapon2 ) )
|
||||||
|
{
|
||||||
|
weapon2 delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init_summon_hacks()
|
||||||
|
{
|
||||||
|
chests = getstructarray( "treasure_chest_use", "targetname" );
|
||||||
|
i = 0;
|
||||||
|
while ( i < chests.size )
|
||||||
|
{
|
||||||
|
chest = chests[ i ];
|
||||||
|
chest init_summon_box( chest.hidden );
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init_summon_box( create )
|
||||||
|
{
|
||||||
|
if ( create )
|
||||||
|
{
|
||||||
|
if ( isDefined( self._summon_hack_struct ) )
|
||||||
|
{
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::deregister_hackable_struct( self._summon_hack_struct );
|
||||||
|
self._summon_hack_struct = undefined;
|
||||||
|
}
|
||||||
|
struct = spawnstruct();
|
||||||
|
struct.origin = self.chest_box.origin + vectorScale( ( 0, 0, 1 ), 24 );
|
||||||
|
struct.radius = 48;
|
||||||
|
struct.height = 72;
|
||||||
|
struct.script_int = 1200;
|
||||||
|
struct.script_float = 5;
|
||||||
|
struct.no_bullet_trace = 1;
|
||||||
|
struct.chest = self;
|
||||||
|
self._summon_hack_struct = struct;
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::register_pooled_hackable_struct( struct, ::summon_box, ::summon_box_qualifier );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( isDefined( self._summon_hack_struct ) )
|
||||||
|
{
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::deregister_hackable_struct( self._summon_hack_struct );
|
||||||
|
self._summon_hack_struct = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
summon_box_thread( hacker )
|
||||||
|
{
|
||||||
|
self.chest.last_hacked_round = level.round_number + randomintrange( 2, 5 );
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::deregister_hackable_struct( self );
|
||||||
|
self.chest thread maps/mp/zombies/_zm_magicbox::show_chest();
|
||||||
|
self.chest notify( "kill_chest_think" );
|
||||||
|
self.chest.auto_open = 1;
|
||||||
|
self.chest.no_charge = 1;
|
||||||
|
self.chest.no_fly_away = 1;
|
||||||
|
self.chest.forced_user = hacker;
|
||||||
|
self.chest thread maps/mp/zombies/_zm_magicbox::treasure_chest_think();
|
||||||
|
self.chest.zbarrier waittill( "closed" );
|
||||||
|
self.chest.forced_user = undefined;
|
||||||
|
self.chest.auto_open = undefined;
|
||||||
|
self.chest.no_charge = undefined;
|
||||||
|
self.chest.no_fly_away = undefined;
|
||||||
|
self.chest thread maps/mp/zombies/_zm_magicbox::hide_chest();
|
||||||
|
}
|
||||||
|
|
||||||
|
summon_box( hacker )
|
||||||
|
{
|
||||||
|
self thread summon_box_thread( hacker );
|
||||||
|
if ( isDefined( hacker ) )
|
||||||
|
{
|
||||||
|
hacker thread maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "hack_box" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
summon_box_qualifier( player )
|
||||||
|
{
|
||||||
|
if ( self.chest.last_hacked_round > level.round_number )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( isDefined( self.chest.zbarrier.chest_moving ) && self.chest.zbarrier.chest_moving )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,108 @@
|
|||||||
|
#include maps/mp/zombies/_zm_equip_hacker;
|
||||||
|
#include maps/mp/zombies/_zm_blockers;
|
||||||
|
#include maps/mp/zombies/_zm_utility;
|
||||||
|
#include maps/mp/_utility;
|
||||||
|
#include common_scripts/utility;
|
||||||
|
|
||||||
|
door_struct_debug()
|
||||||
|
{
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
wait 0.1;
|
||||||
|
origin = self.origin;
|
||||||
|
point = origin;
|
||||||
|
i = 1;
|
||||||
|
while ( i < 5 )
|
||||||
|
{
|
||||||
|
point = origin + ( anglesToForward( self.door.angles ) * ( i * 2 ) );
|
||||||
|
passed = bullettracepassed( point, origin, 0, undefined );
|
||||||
|
color = vectorScale( ( 1, 0, 0 ), 255 );
|
||||||
|
if ( !passed )
|
||||||
|
{
|
||||||
|
color = vectorScale( ( 1, 0, 0 ), 255 );
|
||||||
|
}
|
||||||
|
/#
|
||||||
|
print3d( point, "+", color, 1, 1 );
|
||||||
|
#/
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hack_doors( targetname, door_activate_func )
|
||||||
|
{
|
||||||
|
if ( !isDefined( targetname ) )
|
||||||
|
{
|
||||||
|
targetname = "zombie_door";
|
||||||
|
}
|
||||||
|
doors = getentarray( targetname, "targetname" );
|
||||||
|
if ( !isDefined( door_activate_func ) )
|
||||||
|
{
|
||||||
|
door_activate_func = ::maps/mp/zombies/_zm_blockers::door_opened;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
while ( i < doors.size )
|
||||||
|
{
|
||||||
|
door = doors[ i ];
|
||||||
|
struct = spawnstruct();
|
||||||
|
struct.origin = door.origin + ( anglesToForward( door.angles ) * 2 );
|
||||||
|
struct.radius = 48;
|
||||||
|
struct.height = 72;
|
||||||
|
struct.script_float = 32.7;
|
||||||
|
struct.script_int = 200;
|
||||||
|
struct.door = door;
|
||||||
|
struct.no_bullet_trace = 1;
|
||||||
|
struct.door_activate_func = door_activate_func;
|
||||||
|
trace_passed = 0;
|
||||||
|
door thread hide_door_buy_when_hacker_active( struct );
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::register_pooled_hackable_struct( struct, ::door_hack );
|
||||||
|
door thread watch_door_for_open( struct );
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hide_door_buy_when_hacker_active( door_struct )
|
||||||
|
{
|
||||||
|
self endon( "death" );
|
||||||
|
self endon( "door_hacked" );
|
||||||
|
self endon( "door_opened" );
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::hide_hint_when_hackers_active();
|
||||||
|
}
|
||||||
|
|
||||||
|
watch_door_for_open( door_struct )
|
||||||
|
{
|
||||||
|
self waittill( "door_opened" );
|
||||||
|
self endon( "door_hacked" );
|
||||||
|
remove_all_door_hackables_that_target_door( door_struct.door );
|
||||||
|
}
|
||||||
|
|
||||||
|
door_hack( hacker )
|
||||||
|
{
|
||||||
|
self.door notify( "door_hacked" );
|
||||||
|
self.door notify( "kill_door_think" );
|
||||||
|
remove_all_door_hackables_that_target_door( self.door );
|
||||||
|
self.door [[ self.door_activate_func ]]();
|
||||||
|
self.door._door_open = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_all_door_hackables_that_target_door( door )
|
||||||
|
{
|
||||||
|
candidates = [];
|
||||||
|
i = 0;
|
||||||
|
while ( i < level._hackable_objects.size )
|
||||||
|
{
|
||||||
|
obj = level._hackable_objects[ i ];
|
||||||
|
if ( isDefined( obj.door ) && obj.door.target == door.target )
|
||||||
|
{
|
||||||
|
candidates[ candidates.size ] = obj;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
while ( i < candidates.size )
|
||||||
|
{
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::deregister_hackable_struct( candidates[ i ] );
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
|||||||
|
#include maps/mp/zombies/_zm_equip_hacker;
|
||||||
|
#include maps/mp/zombies/_zm_utility;
|
||||||
|
#include maps/mp/_utility;
|
||||||
|
#include common_scripts/utility;
|
||||||
|
|
||||||
|
hack_packapunch()
|
||||||
|
{
|
||||||
|
vending_weapon_upgrade_trigger = getentarray( "specialty_weapupgrade", "script_noteworthy" );
|
||||||
|
perk = getent( vending_weapon_upgrade_trigger[ 0 ].target, "targetname" );
|
||||||
|
if ( isDefined( perk ) )
|
||||||
|
{
|
||||||
|
struct = spawnstruct();
|
||||||
|
struct.origin = perk.origin + ( anglesToRight( perk.angles ) * 26 ) + vectorScale( ( 0, 0, 1 ), 48 );
|
||||||
|
struct.radius = 48;
|
||||||
|
struct.height = 48;
|
||||||
|
struct.script_float = 5;
|
||||||
|
struct.script_int = -1000;
|
||||||
|
level._pack_hack_struct = struct;
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::register_pooled_hackable_struct( level._pack_hack_struct, ::packapunch_hack );
|
||||||
|
level._pack_hack_struct pack_trigger_think();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pack_trigger_think()
|
||||||
|
{
|
||||||
|
if ( !flag_exists( "enter_nml" ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
flag_wait( "enter_nml" );
|
||||||
|
self.script_int = -1000;
|
||||||
|
while ( flag( "enter_nml" ) )
|
||||||
|
{
|
||||||
|
wait 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
packapunch_hack( hacker )
|
||||||
|
{
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::deregister_hackable_struct( level._pack_hack_struct );
|
||||||
|
level._pack_hack_struct.script_int = 0;
|
||||||
|
level notify( "packapunch_hacked" );
|
||||||
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
#include maps/mp/zombies/_zm_equip_hacker;
|
||||||
|
#include maps/mp/zombies/_zm_utility;
|
||||||
|
#include maps/mp/_utility;
|
||||||
|
#include common_scripts/utility;
|
||||||
|
|
||||||
|
hack_perks()
|
||||||
|
{
|
||||||
|
vending_triggers = getentarray( "zombie_vending", "targetname" );
|
||||||
|
i = 0;
|
||||||
|
while ( i < vending_triggers.size )
|
||||||
|
{
|
||||||
|
struct = spawnstruct();
|
||||||
|
if ( isDefined( vending_triggers[ i ].machine ) )
|
||||||
|
{
|
||||||
|
machine[ 0 ] = vending_triggers[ i ].machine;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
machine = getentarray( vending_triggers[ i ].target, "targetname" );
|
||||||
|
}
|
||||||
|
struct.origin = machine[ 0 ].origin + ( anglesToRight( machine[ 0 ].angles ) * 18 ) + vectorScale( ( 0, 0, 1 ), 48 );
|
||||||
|
struct.radius = 48;
|
||||||
|
struct.height = 64;
|
||||||
|
struct.script_float = 5;
|
||||||
|
while ( !isDefined( vending_triggers[ i ].cost ) )
|
||||||
|
{
|
||||||
|
wait 0.05;
|
||||||
|
}
|
||||||
|
struct.script_int = int( vending_triggers[ i ].cost * -1 );
|
||||||
|
struct.perk = vending_triggers[ i ];
|
||||||
|
if ( isDefined( level._hack_perks_override ) )
|
||||||
|
{
|
||||||
|
struct = struct [[ level._hack_perks_override ]]();
|
||||||
|
}
|
||||||
|
vending_triggers[ i ].hackable = struct;
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::register_pooled_hackable_struct( struct, ::perk_hack, ::perk_hack_qualifier );
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
level._solo_revive_machine_expire_func = ::solo_revive_expire_func;
|
||||||
|
}
|
||||||
|
|
||||||
|
solo_revive_expire_func()
|
||||||
|
{
|
||||||
|
if ( isDefined( self.hackable ) )
|
||||||
|
{
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::deregister_hackable_struct( self.hackable );
|
||||||
|
self.hackable = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
perk_hack_qualifier( player )
|
||||||
|
{
|
||||||
|
if ( isDefined( player._retain_perks ) )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( isDefined( self.perk ) && isDefined( self.perk.script_noteworthy ) )
|
||||||
|
{
|
||||||
|
if ( player hasperk( self.perk.script_noteworthy ) )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
perk_hack( hacker )
|
||||||
|
{
|
||||||
|
if ( flag( "solo_game" ) && self.perk.script_noteworthy == "specialty_quickrevive" )
|
||||||
|
{
|
||||||
|
hacker.lives--;
|
||||||
|
|
||||||
|
}
|
||||||
|
hacker notify( self.perk.script_noteworthy + "_stop" );
|
||||||
|
hacker playsoundtoplayer( "evt_perk_throwup", hacker );
|
||||||
|
while ( isDefined( hacker.perk_hud ) )
|
||||||
|
{
|
||||||
|
keys = getarraykeys( hacker.perk_hud );
|
||||||
|
i = 0;
|
||||||
|
while ( i < hacker.perk_hud.size )
|
||||||
|
{
|
||||||
|
hacker.perk_hud[ keys[ i ] ].x = i * 30;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,79 @@
|
|||||||
|
#include maps/mp/zombies/_zm_powerups;
|
||||||
|
#include maps/mp/zombies/_zm_net;
|
||||||
|
#include maps/mp/zombies/_zm_equip_hacker;
|
||||||
|
#include maps/mp/zombies/_zm_utility;
|
||||||
|
#include maps/mp/_utility;
|
||||||
|
#include common_scripts/utility;
|
||||||
|
|
||||||
|
unhackable_powerup( name )
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
switch( name )
|
||||||
|
{
|
||||||
|
case "bonus_points_player":
|
||||||
|
case "bonus_points_team":
|
||||||
|
case "lose_points_team":
|
||||||
|
case "random_weapon":
|
||||||
|
ret = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
hack_powerups()
|
||||||
|
{
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
level waittill( "powerup_dropped", powerup );
|
||||||
|
if ( !unhackable_powerup( powerup.powerup_name ) )
|
||||||
|
{
|
||||||
|
struct = spawnstruct();
|
||||||
|
struct.origin = powerup.origin;
|
||||||
|
struct.radius = 65;
|
||||||
|
struct.height = 72;
|
||||||
|
struct.script_float = 5;
|
||||||
|
struct.script_int = 5000;
|
||||||
|
struct.powerup = powerup;
|
||||||
|
powerup thread powerup_pickup_watcher( struct );
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::register_pooled_hackable_struct( struct, ::powerup_hack );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
powerup_pickup_watcher( powerup_struct )
|
||||||
|
{
|
||||||
|
self endon( "hacked" );
|
||||||
|
self waittill( "death" );
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::deregister_hackable_struct( powerup_struct );
|
||||||
|
}
|
||||||
|
|
||||||
|
powerup_hack( hacker )
|
||||||
|
{
|
||||||
|
self.powerup notify( "hacked" );
|
||||||
|
if ( isDefined( self.powerup.zombie_grabbable ) && self.powerup.zombie_grabbable )
|
||||||
|
{
|
||||||
|
self.powerup notify( "powerup_timedout" );
|
||||||
|
origin = self.powerup.origin;
|
||||||
|
self.powerup delete();
|
||||||
|
self.powerup = maps/mp/zombies/_zm_net::network_safe_spawn( "powerup", 1, "script_model", origin );
|
||||||
|
if ( isDefined( self.powerup ) )
|
||||||
|
{
|
||||||
|
self.powerup maps/mp/zombies/_zm_powerups::powerup_setup( "full_ammo" );
|
||||||
|
self.powerup thread maps/mp/zombies/_zm_powerups::powerup_timeout();
|
||||||
|
self.powerup thread maps/mp/zombies/_zm_powerups::powerup_wobble();
|
||||||
|
self.powerup thread maps/mp/zombies/_zm_powerups::powerup_grab();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( self.powerup.powerup_name == "full_ammo" )
|
||||||
|
{
|
||||||
|
self.powerup maps/mp/zombies/_zm_powerups::powerup_setup( "fire_sale" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self.powerup maps/mp/zombies/_zm_powerups::powerup_setup( "full_ammo" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::deregister_hackable_struct( self );
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
#include maps/mp/zombies/_zm_equip_hacker;
|
||||||
|
#include maps/mp/zombies/_zm_utility;
|
||||||
|
#include maps/mp/_utility;
|
||||||
|
#include common_scripts/utility;
|
||||||
|
|
||||||
|
hack_wallbuys()
|
||||||
|
{
|
||||||
|
weapon_spawns = getstructarray( "weapon_upgrade", "targetname" );
|
||||||
|
i = 0;
|
||||||
|
while ( i < weapon_spawns.size )
|
||||||
|
{
|
||||||
|
if ( weapontype( weapon_spawns[ i ].zombie_weapon_upgrade ) == "grenade" )
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if ( weapontype( weapon_spawns[ i ].zombie_weapon_upgrade ) == "melee" )
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if ( weapontype( weapon_spawns[ i ].zombie_weapon_upgrade ) == "mine" )
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if ( weapontype( weapon_spawns[ i ].zombie_weapon_upgrade ) == "bomb" )
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct = spawnstruct();
|
||||||
|
struct.origin = weapon_spawns[ i ].origin;
|
||||||
|
struct.radius = 48;
|
||||||
|
struct.height = 48;
|
||||||
|
struct.script_float = 2;
|
||||||
|
struct.script_int = 3000;
|
||||||
|
struct.wallbuy = weapon_spawns[ i ];
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::register_pooled_hackable_struct( struct, ::wallbuy_hack );
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
bowie_triggers = getentarray( "bowie_upgrade", "targetname" );
|
||||||
|
array_thread( bowie_triggers, ::maps/mp/zombies/_zm_equip_hacker::hide_hint_when_hackers_active );
|
||||||
|
}
|
||||||
|
|
||||||
|
wallbuy_hack( hacker )
|
||||||
|
{
|
||||||
|
self.wallbuy.hacked = 1;
|
||||||
|
self.clientfieldname = ( self.wallbuy.zombie_weapon_upgrade + "_" ) + self.origin;
|
||||||
|
level setclientfield( self.clientfieldname, 2 );
|
||||||
|
maps/mp/zombies/_zm_equip_hacker::deregister_hackable_struct( self );
|
||||||
|
}
|
@ -0,0 +1,685 @@
|
|||||||
|
#include maps/mp/zombies/_zm_pers_upgrades_functions;
|
||||||
|
#include maps/mp/zombies/_zm_perks;
|
||||||
|
#include maps/mp/zombies/_zm_powerups;
|
||||||
|
#include maps/mp/zombies/_zm_stats;
|
||||||
|
#include maps/mp/zombies/_zm_pers_upgrades;
|
||||||
|
#include maps/mp/zombies/_zm_pers_upgrades_system;
|
||||||
|
#include maps/mp/zombies/_zm_utility;
|
||||||
|
#include maps/mp/_utility;
|
||||||
|
#include common_scripts/utility;
|
||||||
|
|
||||||
|
pers_upgrade_init()
|
||||||
|
{
|
||||||
|
setup_pers_upgrade_boards();
|
||||||
|
setup_pers_upgrade_revive();
|
||||||
|
setup_pers_upgrade_multi_kill_headshots();
|
||||||
|
setup_pers_upgrade_cash_back();
|
||||||
|
setup_pers_upgrade_insta_kill();
|
||||||
|
setup_pers_upgrade_jugg();
|
||||||
|
setup_pers_upgrade_carpenter();
|
||||||
|
setup_pers_upgrade_flopper();
|
||||||
|
setup_pers_upgrade_perk_lose();
|
||||||
|
setup_pers_upgrade_pistol_points();
|
||||||
|
setup_pers_upgrade_double_points();
|
||||||
|
setup_pers_upgrade_sniper();
|
||||||
|
setup_pers_upgrade_box_weapon();
|
||||||
|
setup_pers_upgrade_nube();
|
||||||
|
level thread pers_upgrades_monitor();
|
||||||
|
}
|
||||||
|
|
||||||
|
pers_abilities_init_globals()
|
||||||
|
{
|
||||||
|
self.successful_revives = 0;
|
||||||
|
self.failed_revives = 0;
|
||||||
|
self.failed_cash_back_prones = 0;
|
||||||
|
self.pers[ "last_headshot_kill_time" ] = getTime();
|
||||||
|
self.pers[ "zombies_multikilled" ] = 0;
|
||||||
|
self.non_headshot_kill_counter = 0;
|
||||||
|
if ( isDefined( level.pers_upgrade_box_weapon ) && level.pers_upgrade_box_weapon )
|
||||||
|
{
|
||||||
|
self.pers_box_weapon_awarded = undefined;
|
||||||
|
}
|
||||||
|
if ( isDefined( level.pers_upgrade_nube ) && level.pers_upgrade_nube )
|
||||||
|
{
|
||||||
|
self thread pers_nube_unlock_watcher();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is_pers_system_active()
|
||||||
|
{
|
||||||
|
if ( !is_classic() )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ( is_pers_system_disabled() )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_pers_system_disabled()
|
||||||
|
{
|
||||||
|
if ( level flag_exists( "sq_minigame_active" ) && flag( "sq_minigame_active" ) )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_pers_upgrade_boards()
|
||||||
|
{
|
||||||
|
if ( isDefined( level.pers_upgrade_boards ) && level.pers_upgrade_boards )
|
||||||
|
{
|
||||||
|
level.pers_boarding_round_start = 10;
|
||||||
|
level.pers_boarding_number_of_boards_required = 74;
|
||||||
|
pers_register_upgrade( "board", ::pers_upgrade_boards_active, "pers_boarding", level.pers_boarding_number_of_boards_required, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_pers_upgrade_revive()
|
||||||
|
{
|
||||||
|
if ( isDefined( level.pers_upgrade_revive ) && level.pers_upgrade_revive )
|
||||||
|
{
|
||||||
|
level.pers_revivenoperk_number_of_revives_required = 17;
|
||||||
|
level.pers_revivenoperk_number_of_chances_to_keep = 1;
|
||||||
|
pers_register_upgrade( "revive", ::pers_upgrade_revive_active, "pers_revivenoperk", level.pers_revivenoperk_number_of_revives_required, 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_pers_upgrade_multi_kill_headshots()
|
||||||
|
{
|
||||||
|
if ( isDefined( level.pers_upgrade_multi_kill_headshots ) && level.pers_upgrade_multi_kill_headshots )
|
||||||
|
{
|
||||||
|
level.pers_multikill_headshots_required = 5;
|
||||||
|
level.pers_multikill_headshots_upgrade_reset_counter = 25;
|
||||||
|
pers_register_upgrade( "multikill_headshots", ::pers_upgrade_headshot_active, "pers_multikill_headshots", level.pers_multikill_headshots_required, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_pers_upgrade_cash_back()
|
||||||
|
{
|
||||||
|
if ( isDefined( level.pers_upgrade_cash_back ) && level.pers_upgrade_cash_back )
|
||||||
|
{
|
||||||
|
level.pers_cash_back_num_perks_required = 50;
|
||||||
|
level.pers_cash_back_perk_buys_prone_required = 15;
|
||||||
|
level.pers_cash_back_failed_prones = 1;
|
||||||
|
level.pers_cash_back_money_reward = 1000;
|
||||||
|
pers_register_upgrade( "cash_back", ::pers_upgrade_cash_back_active, "pers_cash_back_bought", level.pers_cash_back_num_perks_required, 0 );
|
||||||
|
add_pers_upgrade_stat( "cash_back", "pers_cash_back_prone", level.pers_cash_back_perk_buys_prone_required );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_pers_upgrade_insta_kill()
|
||||||
|
{
|
||||||
|
if ( isDefined( level.pers_upgrade_insta_kill ) && level.pers_upgrade_insta_kill )
|
||||||
|
{
|
||||||
|
level.pers_insta_kill_num_required = 2;
|
||||||
|
level.pers_insta_kill_upgrade_active_time = 18;
|
||||||
|
pers_register_upgrade( "insta_kill", ::pers_upgrade_insta_kill_active, "pers_insta_kill", level.pers_insta_kill_num_required, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_pers_upgrade_jugg()
|
||||||
|
{
|
||||||
|
if ( isDefined( level.pers_upgrade_jugg ) && level.pers_upgrade_jugg )
|
||||||
|
{
|
||||||
|
level.pers_jugg_hit_and_die_total = 3;
|
||||||
|
level.pers_jugg_hit_and_die_round_limit = 2;
|
||||||
|
level.pers_jugg_round_reached_max = 1;
|
||||||
|
level.pers_jugg_round_lose_target = 15;
|
||||||
|
level.pers_jugg_upgrade_health_bonus = 90;
|
||||||
|
pers_register_upgrade( "jugg", ::pers_upgrade_jugg_active, "pers_jugg", level.pers_jugg_hit_and_die_total, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_pers_upgrade_carpenter()
|
||||||
|
{
|
||||||
|
if ( isDefined( level.pers_upgrade_carpenter ) && level.pers_upgrade_carpenter )
|
||||||
|
{
|
||||||
|
level.pers_carpenter_zombie_kills = 1;
|
||||||
|
pers_register_upgrade( "carpenter", ::pers_upgrade_carpenter_active, "pers_carpenter", level.pers_carpenter_zombie_kills, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_pers_upgrade_flopper()
|
||||||
|
{
|
||||||
|
if ( isDefined( level.pers_upgrade_flopper ) && level.pers_upgrade_flopper )
|
||||||
|
{
|
||||||
|
level.pers_flopper_damage_counter = 6;
|
||||||
|
level.pers_flopper_counter = 1;
|
||||||
|
level.pers_flopper_min_fall_damage_activate = 30;
|
||||||
|
level.pers_flopper_min_fall_damage_deactivate = 50;
|
||||||
|
pers_register_upgrade( "flopper", ::pers_upgrade_flopper_active, "pers_flopper_counter", level.pers_flopper_counter, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_pers_upgrade_perk_lose()
|
||||||
|
{
|
||||||
|
if ( isDefined( level.pers_upgrade_perk_lose ) && level.pers_upgrade_perk_lose )
|
||||||
|
{
|
||||||
|
level.pers_perk_round_reached_max = 6;
|
||||||
|
level.pers_perk_lose_counter = 3;
|
||||||
|
pers_register_upgrade( "perk_lose", ::pers_upgrade_perk_lose_active, "pers_perk_lose_counter", level.pers_perk_lose_counter, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_pers_upgrade_pistol_points()
|
||||||
|
{
|
||||||
|
if ( isDefined( level.pers_upgrade_pistol_points ) && level.pers_upgrade_pistol_points )
|
||||||
|
{
|
||||||
|
level.pers_pistol_points_num_kills_in_game = 8;
|
||||||
|
level.pers_pistol_points_accuracy = 0.25;
|
||||||
|
level.pers_pistol_points_counter = 1;
|
||||||
|
pers_register_upgrade( "pistol_points", ::pers_upgrade_pistol_points_active, "pers_pistol_points_counter", level.pers_pistol_points_counter, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_pers_upgrade_double_points()
|
||||||
|
{
|
||||||
|
if ( isDefined( level.pers_upgrade_double_points ) && level.pers_upgrade_double_points )
|
||||||
|
{
|
||||||
|
level.pers_double_points_score = 2500;
|
||||||
|
level.pers_double_points_counter = 1;
|
||||||
|
pers_register_upgrade( "double_points", ::pers_upgrade_double_points_active, "pers_double_points_counter", level.pers_double_points_counter, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_pers_upgrade_sniper()
|
||||||
|
{
|
||||||
|
if ( isDefined( level.pers_upgrade_sniper ) && level.pers_upgrade_sniper )
|
||||||
|
{
|
||||||
|
level.pers_sniper_round_kills_counter = 5;
|
||||||
|
level.pers_sniper_kill_distance = 800;
|
||||||
|
level.pers_sniper_counter = 1;
|
||||||
|
level.pers_sniper_misses = 3;
|
||||||
|
pers_register_upgrade( "sniper", ::pers_upgrade_sniper_active, "pers_sniper_counter", level.pers_sniper_counter, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_pers_upgrade_box_weapon()
|
||||||
|
{
|
||||||
|
if ( isDefined( level.pers_upgrade_box_weapon ) && level.pers_upgrade_box_weapon )
|
||||||
|
{
|
||||||
|
level.pers_box_weapon_counter = 5;
|
||||||
|
level.pers_box_weapon_lose_round = 10;
|
||||||
|
pers_register_upgrade( "box_weapon", ::pers_upgrade_box_weapon_active, "pers_box_weapon_counter", level.pers_box_weapon_counter, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_pers_upgrade_nube()
|
||||||
|
{
|
||||||
|
if ( isDefined( level.pers_upgrade_nube ) && level.pers_upgrade_nube )
|
||||||
|
{
|
||||||
|
level.pers_nube_counter = 1;
|
||||||
|
level.pers_nube_lose_round = 10;
|
||||||
|
level.pers_numb_num_kills_unlock = 5;
|
||||||
|
pers_register_upgrade( "nube", ::pers_upgrade_nube_active, "pers_nube_counter", level.pers_nube_counter, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pers_upgrade_boards_active()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
last_round_number = level.round_number;
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
self waittill( "pers_stats_end_of_round" );
|
||||||
|
if ( level.round_number >= last_round_number )
|
||||||
|
{
|
||||||
|
if ( maps/mp/zombies/_zm_pers_upgrades::is_pers_system_active() )
|
||||||
|
{
|
||||||
|
if ( self.rebuild_barrier_reward == 0 )
|
||||||
|
{
|
||||||
|
self maps/mp/zombies/_zm_stats::zero_client_stat( "pers_boarding", 0 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
last_round_number = level.round_number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pers_upgrade_revive_active()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
self waittill( "player_failed_revive" );
|
||||||
|
if ( maps/mp/zombies/_zm_pers_upgrades::is_pers_system_active() )
|
||||||
|
{
|
||||||
|
if ( self.failed_revives >= level.pers_revivenoperk_number_of_chances_to_keep )
|
||||||
|
{
|
||||||
|
self maps/mp/zombies/_zm_stats::zero_client_stat( "pers_revivenoperk", 0 );
|
||||||
|
self.failed_revives = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pers_upgrade_headshot_active()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
self waittill( "zombie_death_no_headshot" );
|
||||||
|
if ( maps/mp/zombies/_zm_pers_upgrades::is_pers_system_active() )
|
||||||
|
{
|
||||||
|
self.non_headshot_kill_counter++;
|
||||||
|
if ( self.non_headshot_kill_counter >= level.pers_multikill_headshots_upgrade_reset_counter )
|
||||||
|
{
|
||||||
|
self maps/mp/zombies/_zm_stats::zero_client_stat( "pers_multikill_headshots", 0 );
|
||||||
|
self.non_headshot_kill_counter = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pers_upgrade_cash_back_active()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
wait 0.5;
|
||||||
|
|
||||||
|
wait 0.5;
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
self waittill( "cash_back_failed_prone" );
|
||||||
|
wait 0.1;
|
||||||
|
|
||||||
|
if ( maps/mp/zombies/_zm_pers_upgrades::is_pers_system_active() )
|
||||||
|
{
|
||||||
|
self.failed_cash_back_prones++;
|
||||||
|
if ( self.failed_cash_back_prones >= level.pers_cash_back_failed_prones )
|
||||||
|
{
|
||||||
|
self maps/mp/zombies/_zm_stats::zero_client_stat( "pers_cash_back_bought", 0 );
|
||||||
|
self maps/mp/zombies/_zm_stats::zero_client_stat( "pers_cash_back_prone", 0 );
|
||||||
|
self.failed_cash_back_prones = 0;
|
||||||
|
wait 0.4;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pers_upgrade_insta_kill_active()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
wait 0.2;
|
||||||
|
|
||||||
|
wait 0.2;
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
self waittill( "pers_melee_swipe" );
|
||||||
|
if ( maps/mp/zombies/_zm_pers_upgrades::is_pers_system_active() )
|
||||||
|
{
|
||||||
|
if ( isDefined( level.pers_melee_swipe_zombie_swiper ) )
|
||||||
|
{
|
||||||
|
e_zombie = level.pers_melee_swipe_zombie_swiper;
|
||||||
|
if ( isalive( e_zombie ) && isDefined( e_zombie.is_zombie ) && e_zombie.is_zombie )
|
||||||
|
{
|
||||||
|
e_zombie.marked_for_insta_upgraded_death = 1;
|
||||||
|
e_zombie dodamage( e_zombie.health + 666, e_zombie.origin, self, self, "none", "MOD_PISTOL_BULLET", 0, "knife_zm" );
|
||||||
|
}
|
||||||
|
level.pers_melee_swipe_zombie_swiper = undefined;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self maps/mp/zombies/_zm_stats::zero_client_stat( "pers_insta_kill", 0 );
|
||||||
|
self kill_insta_kill_upgrade_hud_icon();
|
||||||
|
wait 0.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_insta_kill_upgraded_and_active()
|
||||||
|
{
|
||||||
|
if ( maps/mp/zombies/_zm_pers_upgrades::is_pers_system_active() )
|
||||||
|
{
|
||||||
|
if ( self maps/mp/zombies/_zm_powerups::is_insta_kill_active() )
|
||||||
|
{
|
||||||
|
if ( isDefined( self.pers_upgrades_awarded[ "insta_kill" ] ) && self.pers_upgrades_awarded[ "insta_kill" ] )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pers_upgrade_jugg_active()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
wait 0.5;
|
||||||
|
|
||||||
|
wait 0.5;
|
||||||
|
self maps/mp/zombies/_zm_perks::perk_set_max_health_if_jugg( "jugg_upgrade", 1, 0 );
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
level waittill( "start_of_round" );
|
||||||
|
if ( maps/mp/zombies/_zm_pers_upgrades::is_pers_system_active() )
|
||||||
|
{
|
||||||
|
if ( level.round_number == level.pers_jugg_round_lose_target )
|
||||||
|
{
|
||||||
|
self maps/mp/zombies/_zm_stats::increment_client_stat( "pers_jugg_downgrade_count", 0 );
|
||||||
|
wait 0.5;
|
||||||
|
if ( self.pers[ "pers_jugg_downgrade_count" ] >= level.pers_jugg_round_reached_max )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self maps/mp/zombies/_zm_perks::perk_set_max_health_if_jugg( "jugg_upgrade", 1, 1 );
|
||||||
|
self maps/mp/zombies/_zm_stats::zero_client_stat( "pers_jugg", 0 );
|
||||||
|
self maps/mp/zombies/_zm_stats::zero_client_stat( "pers_jugg_downgrade_count", 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
pers_upgrade_carpenter_active()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
wait 0.2;
|
||||||
|
|
||||||
|
wait 0.2;
|
||||||
|
level waittill( "carpenter_finished" );
|
||||||
|
self.pers_carpenter_kill = undefined;
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
self waittill( "carpenter_zombie_killed_check_finished" );
|
||||||
|
if ( maps/mp/zombies/_zm_pers_upgrades::is_pers_system_active() )
|
||||||
|
{
|
||||||
|
if ( !isDefined( self.pers_carpenter_kill ) )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
self.pers_carpenter_kill = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self maps/mp/zombies/_zm_stats::zero_client_stat( "pers_carpenter", 0 );
|
||||||
|
wait 0.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
persistent_carpenter_ability_check()
|
||||||
|
{
|
||||||
|
if ( isDefined( level.pers_upgrade_carpenter ) && level.pers_upgrade_carpenter )
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
|
||||||
|
if ( isDefined( self.pers_upgrades_awarded[ "carpenter" ] ) && self.pers_upgrades_awarded[ "carpenter" ] )
|
||||||
|
{
|
||||||
|
level.pers_carpenter_boards_active = 1;
|
||||||
|
}
|
||||||
|
self.pers_carpenter_zombie_check_active = 1;
|
||||||
|
self.pers_carpenter_kill = undefined;
|
||||||
|
carpenter_extra_time = 3;
|
||||||
|
carpenter_finished_start_time = undefined;
|
||||||
|
level.carpenter_finished_start_time = undefined;
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
if ( !is_pers_system_disabled() )
|
||||||
|
{
|
||||||
|
if ( !isDefined( level.carpenter_powerup_active ) )
|
||||||
|
{
|
||||||
|
if ( !isDefined( level.carpenter_finished_start_time ) )
|
||||||
|
{
|
||||||
|
level.carpenter_finished_start_time = getTime();
|
||||||
|
}
|
||||||
|
time = getTime();
|
||||||
|
dt = ( time - level.carpenter_finished_start_time ) / 1000;
|
||||||
|
if ( dt >= carpenter_extra_time )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( isDefined( self.pers_carpenter_kill ) )
|
||||||
|
{
|
||||||
|
if ( isDefined( self.pers_upgrades_awarded[ "carpenter" ] ) && self.pers_upgrades_awarded[ "carpenter" ] )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else self maps/mp/zombies/_zm_stats::increment_client_stat( "pers_carpenter", 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wait 0.05;
|
||||||
|
}
|
||||||
|
self notify( "carpenter_zombie_killed_check_finished" );
|
||||||
|
self.pers_carpenter_zombie_check_active = undefined;
|
||||||
|
level.pers_carpenter_boards_active = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pers_zombie_death_location_check( attacker, v_pos )
|
||||||
|
{
|
||||||
|
if ( maps/mp/zombies/_zm_pers_upgrades::is_pers_system_active() )
|
||||||
|
{
|
||||||
|
if ( is_player_valid( attacker ) )
|
||||||
|
{
|
||||||
|
if ( isDefined( attacker.pers_carpenter_zombie_check_active ) )
|
||||||
|
{
|
||||||
|
if ( !check_point_in_playable_area( v_pos ) )
|
||||||
|
{
|
||||||
|
attacker.pers_carpenter_kill = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
insta_kill_pers_upgrade_icon()
|
||||||
|
{
|
||||||
|
if ( self.zombie_vars[ "zombie_powerup_insta_kill_ug_on" ] )
|
||||||
|
{
|
||||||
|
self.zombie_vars[ "zombie_powerup_insta_kill_ug_time" ] = level.pers_insta_kill_upgrade_active_time;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.zombie_vars[ "zombie_powerup_insta_kill_ug_on" ] = 1;
|
||||||
|
self._show_solo_hud = 1;
|
||||||
|
self thread time_remaining_pers_upgrade();
|
||||||
|
}
|
||||||
|
|
||||||
|
time_remaining_pers_upgrade()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
self endon( "kill_insta_kill_upgrade_hud_icon" );
|
||||||
|
while ( self.zombie_vars[ "zombie_powerup_insta_kill_ug_time" ] >= 0 )
|
||||||
|
{
|
||||||
|
wait 0.05;
|
||||||
|
self.zombie_vars[ "zombie_powerup_insta_kill_ug_time" ] -= 0.05;
|
||||||
|
}
|
||||||
|
self kill_insta_kill_upgrade_hud_icon();
|
||||||
|
}
|
||||||
|
|
||||||
|
kill_insta_kill_upgrade_hud_icon()
|
||||||
|
{
|
||||||
|
self.zombie_vars[ "zombie_powerup_insta_kill_ug_on" ] = 0;
|
||||||
|
self._show_solo_hud = 0;
|
||||||
|
self.zombie_vars[ "zombie_powerup_insta_kill_ug_time" ] = level.pers_insta_kill_upgrade_active_time;
|
||||||
|
self notify( "kill_insta_kill_upgrade_hud_icon" );
|
||||||
|
}
|
||||||
|
|
||||||
|
pers_upgrade_flopper_active()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
wait 0.5;
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
iprintlnbold( "*** WE'VE GOT FLOPPER UPGRADED ***" );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
wait 0.5;
|
||||||
|
self thread maps/mp/zombies/_zm_pers_upgrades_functions::pers_upgrade_flopper_watcher();
|
||||||
|
self waittill( "pers_flopper_lost" );
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
iprintlnbold( "*** OH NO: Lost FLOPPER Upgrade ***" );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
self maps/mp/zombies/_zm_stats::zero_client_stat( "pers_flopper_counter", 0 );
|
||||||
|
self.pers_num_flopper_damages = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pers_upgrade_perk_lose_active()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
wait 0.5;
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
iprintlnbold( "*** WE'VE GOT PERK LOSE UPGRADED ***" );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
wait 0.5;
|
||||||
|
self.pers_perk_lose_start_round = level.round_number;
|
||||||
|
self waittill( "pers_perk_lose_lost" );
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
iprintlnbold( "*** OH NO: Lost PERK LOSE Upgrade ***" );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
self maps/mp/zombies/_zm_stats::zero_client_stat( "pers_perk_lose_counter", 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
pers_upgrade_pistol_points_active()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
wait 0.5;
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
iprintlnbold( "*** WE'VE GOT PISTOL POINTS UPGRADED ***" );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
wait 0.5;
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
self waittill( "pers_pistol_points_kill" );
|
||||||
|
accuracy = self maps/mp/zombies/_zm_pers_upgrades_functions::pers_get_player_accuracy();
|
||||||
|
if ( accuracy > level.pers_pistol_points_accuracy )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
iprintlnbold( "*** OH NO: Lost PISTOL POINTS Upgrade ***" );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
self maps/mp/zombies/_zm_stats::zero_client_stat( "pers_pistol_points_counter", 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
pers_upgrade_double_points_active()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
wait 0.5;
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
iprintlnbold( "*** WE'VE GOT DOUBLE POINTS UPGRADED ***" );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
wait 0.5;
|
||||||
|
self waittill( "double_points_lost" );
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
iprintlnbold( "*** OH NO: Lost DOUBLE POINTS Upgrade ***" );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
self maps/mp/zombies/_zm_stats::zero_client_stat( "pers_double_points_counter", 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
pers_upgrade_sniper_active()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
wait 0.5;
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
iprintlnbold( "*** WE'VE GOT SNIPER UPGRADED ***" );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
wait 0.5;
|
||||||
|
self waittill( "pers_sniper_lost" );
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
iprintlnbold( "*** OH NO: Lost SNIPER Upgrade ***" );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
self maps/mp/zombies/_zm_stats::zero_client_stat( "pers_sniper_counter", 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
pers_upgrade_box_weapon_active()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
wait 0.5;
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
iprintlnbold( "*** WE'VE GOT BOX WEAPON UPGRADED ***" );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
self thread maps/mp/zombies/_zm_pers_upgrades_functions::pers_magic_box_teddy_bear();
|
||||||
|
wait 0.5;
|
||||||
|
self.pers_box_weapon_awarded = 1;
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
level waittill( "start_of_round" );
|
||||||
|
if ( maps/mp/zombies/_zm_pers_upgrades::is_pers_system_active() )
|
||||||
|
{
|
||||||
|
if ( level.round_number >= level.pers_box_weapon_lose_round )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
iprintlnbold( "*** OH NO: Lost BOX WEAPON Upgrade ***" );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
self maps/mp/zombies/_zm_stats::zero_client_stat( "pers_box_weapon_counter", 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
pers_upgrade_nube_active()
|
||||||
|
{
|
||||||
|
self endon( "disconnect" );
|
||||||
|
wait 0.5;
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
iprintlnbold( "*** WE'VE GOT NUBE UPGRADED ***" );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
wait 0.5;
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
level waittill( "start_of_round" );
|
||||||
|
if ( maps/mp/zombies/_zm_pers_upgrades::is_pers_system_active() )
|
||||||
|
{
|
||||||
|
if ( level.round_number >= level.pers_nube_lose_round )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
iprintlnbold( "*** OH NO: Lost NUBE Upgrade ***" );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
self maps/mp/zombies/_zm_stats::zero_client_stat( "pers_nube_counter", 0 );
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,278 @@
|
|||||||
|
#include maps/mp/zombies/_zm_stats;
|
||||||
|
#include maps/mp/zombies/_zm;
|
||||||
|
#include maps/mp/zombies/_zm_audio;
|
||||||
|
#include maps/mp/zombies/_zm_utility;
|
||||||
|
#include maps/mp/_utility;
|
||||||
|
#include common_scripts/utility;
|
||||||
|
|
||||||
|
pers_register_upgrade( name, upgrade_active_func, stat_name, stat_desired_value, game_end_reset_if_not_achieved )
|
||||||
|
{
|
||||||
|
if ( !isDefined( level.pers_upgrades ) )
|
||||||
|
{
|
||||||
|
level.pers_upgrades = [];
|
||||||
|
level.pers_upgrades_keys = [];
|
||||||
|
}
|
||||||
|
if ( isDefined( level.pers_upgrades[ name ] ) )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
assert( 0, "A persistent upgrade is already registered for name: " + name );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
level.pers_upgrades_keys[ level.pers_upgrades_keys.size ] = name;
|
||||||
|
level.pers_upgrades[ name ] = spawnstruct();
|
||||||
|
level.pers_upgrades[ name ].stat_names = [];
|
||||||
|
level.pers_upgrades[ name ].stat_desired_values = [];
|
||||||
|
level.pers_upgrades[ name ].upgrade_active_func = upgrade_active_func;
|
||||||
|
level.pers_upgrades[ name ].game_end_reset_if_not_achieved = game_end_reset_if_not_achieved;
|
||||||
|
add_pers_upgrade_stat( name, stat_name, stat_desired_value );
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
if ( isDefined( level.devgui_add_ability ) )
|
||||||
|
{
|
||||||
|
[[ level.devgui_add_ability ]]( name, upgrade_active_func, stat_name, stat_desired_value, game_end_reset_if_not_achieved );
|
||||||
|
#/
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
add_pers_upgrade_stat( name, stat_name, stat_desired_value )
|
||||||
|
{
|
||||||
|
if ( !isDefined( level.pers_upgrades[ name ] ) )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
assert( 0, name + " - Persistent upgrade is not registered yet." );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
stats_size = level.pers_upgrades[ name ].stat_names.size;
|
||||||
|
level.pers_upgrades[ name ].stat_names[ stats_size ] = stat_name;
|
||||||
|
level.pers_upgrades[ name ].stat_desired_values[ stats_size ] = stat_desired_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
pers_upgrades_monitor()
|
||||||
|
{
|
||||||
|
if ( !isDefined( level.pers_upgrades ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( !is_classic() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
level thread wait_for_game_end();
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
waittillframeend;
|
||||||
|
players = getplayers();
|
||||||
|
player_index = 0;
|
||||||
|
while ( player_index < players.size )
|
||||||
|
{
|
||||||
|
player = players[ player_index ];
|
||||||
|
if ( is_player_valid( player ) && isDefined( player.stats_this_frame ) )
|
||||||
|
{
|
||||||
|
if ( !player.stats_this_frame.size && isDefined( player.pers_upgrade_force_test ) && !player.pers_upgrade_force_test )
|
||||||
|
{
|
||||||
|
player_index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pers_upgrade_index = 0;
|
||||||
|
while ( pers_upgrade_index < level.pers_upgrades_keys.size )
|
||||||
|
{
|
||||||
|
pers_upgrade = level.pers_upgrades[ level.pers_upgrades_keys[ pers_upgrade_index ] ];
|
||||||
|
is_stat_updated = player is_any_pers_upgrade_stat_updated( pers_upgrade );
|
||||||
|
if ( is_stat_updated )
|
||||||
|
{
|
||||||
|
should_award = player check_pers_upgrade( pers_upgrade );
|
||||||
|
if ( should_award )
|
||||||
|
{
|
||||||
|
if ( isDefined( player.pers_upgrades_awarded[ level.pers_upgrades_keys[ pers_upgrade_index ] ] ) && player.pers_upgrades_awarded[ level.pers_upgrades_keys[ pers_upgrade_index ] ] )
|
||||||
|
{
|
||||||
|
//this checks whether the play already has the upgrade
|
||||||
|
pers_upgrade_index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player.pers_upgrades_awarded[ level.pers_upgrades_keys[ pers_upgrade_index ] ] = 1;
|
||||||
|
if ( flag( "initial_blackscreen_passed" ) && !is_true( player.is_hotjoining ) )
|
||||||
|
{
|
||||||
|
type = "upgrade";
|
||||||
|
if ( isDefined( level.snd_pers_upgrade_force_type ) )
|
||||||
|
{
|
||||||
|
type = level.snd_pers_upgrade_force_type;
|
||||||
|
}
|
||||||
|
player playsoundtoplayer( "evt_player_upgrade", player );
|
||||||
|
if ( isDefined( level.pers_upgrade_vo_spoken ) && level.pers_upgrade_vo_spoken )
|
||||||
|
{
|
||||||
|
player delay_thread( 1, ::create_and_play_dialog, "general", type, undefined, level.snd_pers_upgrade_force_variant );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player delay_thread( 1, ::play_vox_to_player, "general", type, level.snd_pers_upgrade_force_variant );
|
||||||
|
}
|
||||||
|
if ( isDefined( player.upgrade_fx_origin ) )
|
||||||
|
{
|
||||||
|
fx_org = player.upgrade_fx_origin;
|
||||||
|
player.upgrade_fx_origin = undefined;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fx_org = player.origin;
|
||||||
|
v_dir = anglesToForward( player getplayerangles() );
|
||||||
|
v_up = anglesToUp( player getplayerangles() );
|
||||||
|
fx_org = ( fx_org + ( v_dir * 30 ) ) + ( v_up * 12 );
|
||||||
|
}
|
||||||
|
playfx( level._effect[ "upgrade_aquired" ], fx_org );
|
||||||
|
level thread maps/mp/zombies/_zm::disable_end_game_intermission( 1.5 );
|
||||||
|
}
|
||||||
|
/#
|
||||||
|
player iprintlnbold( "Upgraded!" );
|
||||||
|
#/
|
||||||
|
if ( isDefined( pers_upgrade.upgrade_active_func ) )
|
||||||
|
{
|
||||||
|
player thread [[ pers_upgrade.upgrade_active_func ]]();
|
||||||
|
}
|
||||||
|
pers_upgrade_index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( isDefined( player.pers_upgrades_awarded[ level.pers_upgrades_keys[ pers_upgrade_index ] ] ) && player.pers_upgrades_awarded[ level.pers_upgrades_keys[ pers_upgrade_index ] ] )
|
||||||
|
{
|
||||||
|
if ( flag( "initial_blackscreen_passed" ) && !is_true( player.is_hotjoining ) )
|
||||||
|
{
|
||||||
|
player playsoundtoplayer( "evt_player_downgrade", player );
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
player iprintlnbold( "Downgraded!" );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
player.pers_upgrades_awarded[ level.pers_upgrades_keys[ pers_upgrade_index ] ] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pers_upgrade_index++;
|
||||||
|
}
|
||||||
|
player.pers_upgrade_force_test = 0;
|
||||||
|
player.stats_this_frame = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
player_index++;
|
||||||
|
}
|
||||||
|
wait 0.05;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_game_end()
|
||||||
|
{
|
||||||
|
if ( !is_classic() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
level waittill( "end_game" );
|
||||||
|
players = getplayers();
|
||||||
|
player_index = 0;
|
||||||
|
while ( player_index < players.size )
|
||||||
|
{
|
||||||
|
player = players[ player_index ];
|
||||||
|
index = 0;
|
||||||
|
while ( index < level.pers_upgrades_keys.size )
|
||||||
|
{
|
||||||
|
str_name = level.pers_upgrades_keys[ index ];
|
||||||
|
game_end_reset_if_not_achieved = level.pers_upgrades[ str_name ].game_end_reset_if_not_achieved;
|
||||||
|
while ( isDefined( game_end_reset_if_not_achieved ) && game_end_reset_if_not_achieved == 1 )
|
||||||
|
{
|
||||||
|
while ( isDefined( player.pers_upgrades_awarded[ str_name ] ) && !player.pers_upgrades_awarded[ str_name ] )
|
||||||
|
{
|
||||||
|
stat_index = 0;
|
||||||
|
while ( stat_index < level.pers_upgrades[ str_name ].stat_names.size )
|
||||||
|
{
|
||||||
|
player maps/mp/zombies/_zm_stats::zero_client_stat( level.pers_upgrades[ str_name ].stat_names[ stat_index ], 0 );
|
||||||
|
stat_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
player_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
check_pers_upgrade( pers_upgrade )
|
||||||
|
{
|
||||||
|
should_award = 1;
|
||||||
|
i = 0;
|
||||||
|
while ( i < pers_upgrade.stat_names.size )
|
||||||
|
{
|
||||||
|
stat_name = pers_upgrade.stat_names[ i ];
|
||||||
|
should_award = self check_pers_upgrade_stat( stat_name, pers_upgrade.stat_desired_values[ i ] );
|
||||||
|
if ( !should_award )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return should_award;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_any_pers_upgrade_stat_updated( pers_upgrade )
|
||||||
|
{
|
||||||
|
if ( isDefined( self.pers_upgrade_force_test ) && self.pers_upgrade_force_test )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
result = 0;
|
||||||
|
i = 0;
|
||||||
|
while ( i < pers_upgrade.stat_names.size )
|
||||||
|
{
|
||||||
|
stat_name = pers_upgrade.stat_names[ i ];
|
||||||
|
if ( isDefined( self.stats_this_frame[ stat_name ] ) )
|
||||||
|
{
|
||||||
|
result = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
check_pers_upgrade_stat( stat_name, stat_desired_value )
|
||||||
|
{
|
||||||
|
should_award = 1;
|
||||||
|
current_stat_value = self maps/mp/zombies/_zm_stats::get_global_stat( stat_name );
|
||||||
|
if ( current_stat_value < stat_desired_value )
|
||||||
|
{
|
||||||
|
should_award = 0;
|
||||||
|
}
|
||||||
|
return should_award;
|
||||||
|
}
|
||||||
|
|
||||||
|
round_end()
|
||||||
|
{
|
||||||
|
if ( !is_classic() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self notify( "pers_stats_end_of_round" );
|
||||||
|
if ( isDefined( self.pers[ "pers_max_round_reached" ] ) )
|
||||||
|
{
|
||||||
|
if ( level.round_number > self.pers[ "pers_max_round_reached" ] )
|
||||||
|
{
|
||||||
|
self maps/mp/zombies/_zm_stats::set_client_stat( "pers_max_round_reached", level.round_number, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,397 @@
|
|||||||
|
#include maps/mp/zombies/_zm_pers_upgrades_functions;
|
||||||
|
#include maps/mp/zombies/_zm_stats;
|
||||||
|
#include maps/mp/zombies/_zm_utility;
|
||||||
|
#include maps/mp/_utility;
|
||||||
|
#include common_scripts/utility;
|
||||||
|
|
||||||
|
init()
|
||||||
|
{
|
||||||
|
level.score_cf_info = [];
|
||||||
|
score_cf_register_info( "damage", 1, 7 );
|
||||||
|
score_cf_register_info( "death_normal", 1, 3 );
|
||||||
|
score_cf_register_info( "death_torso", 1, 3 );
|
||||||
|
score_cf_register_info( "death_neck", 1, 3 );
|
||||||
|
score_cf_register_info( "death_head", 1, 3 );
|
||||||
|
score_cf_register_info( "death_melee", 1, 3 );
|
||||||
|
if ( !level.createfx_enabled )
|
||||||
|
{
|
||||||
|
registerclientfield( "allplayers", "score_cf_double_points_active", 1, 1, "int" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
score_cf_register_info( name, version, max_count )
|
||||||
|
{
|
||||||
|
if ( level.createfx_enabled )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
info = spawnstruct();
|
||||||
|
info.name = name;
|
||||||
|
info.cf_field = "score_cf_" + name;
|
||||||
|
info.version = version;
|
||||||
|
info.max_count = max_count;
|
||||||
|
info.bit_count = getminbitcountfornum( max_count );
|
||||||
|
info.players = [];
|
||||||
|
level.score_cf_info[ name ] = info;
|
||||||
|
registerclientfield( "allplayers", info.cf_field, info.version, info.bit_count, "int" );
|
||||||
|
}
|
||||||
|
|
||||||
|
score_cf_increment_info( name )
|
||||||
|
{
|
||||||
|
info = level.score_cf_info[ name ];
|
||||||
|
player_ent_index = self getentitynumber();
|
||||||
|
if ( !isDefined( info.players[ player_ent_index ] ) )
|
||||||
|
{
|
||||||
|
info.players[ player_ent_index ] = 0;
|
||||||
|
}
|
||||||
|
info.players[ player_ent_index ]++;
|
||||||
|
if ( info.players[ player_ent_index ] > info.max_count )
|
||||||
|
{
|
||||||
|
info.players[ player_ent_index ] = 0;
|
||||||
|
}
|
||||||
|
self setclientfield( info.cf_field, info.players[ player_ent_index ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
score_cf_monitor()
|
||||||
|
{
|
||||||
|
if ( level.createfx_enabled )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
info_keys = getarraykeys( level.score_cf_info );
|
||||||
|
while ( 1 )
|
||||||
|
{
|
||||||
|
wait_network_frame();
|
||||||
|
players = get_players();
|
||||||
|
player_index = 0;
|
||||||
|
while ( player_index < players.size )
|
||||||
|
{
|
||||||
|
player = players[ player_index ];
|
||||||
|
player_ent_index = player getentitynumber();
|
||||||
|
info_index = 0;
|
||||||
|
while ( info_index < info_keys.size )
|
||||||
|
{
|
||||||
|
info = level.score_cf_info[ info_keys[ info_index ] ];
|
||||||
|
info.players[ player_ent_index ] = 0;
|
||||||
|
player setclientfield( info.cf_field, 0 );
|
||||||
|
info_index++;
|
||||||
|
}
|
||||||
|
player_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
player_add_points( event, mod, hit_location, is_dog, zombie_team, damage_weapon )
|
||||||
|
{
|
||||||
|
if ( level.intermission )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( !is_player_valid( self ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
player_points = 0;
|
||||||
|
team_points = 0;
|
||||||
|
multiplier = get_points_multiplier( self );
|
||||||
|
switch( event )
|
||||||
|
{
|
||||||
|
case "death":
|
||||||
|
player_points = get_zombie_death_player_points();
|
||||||
|
team_points = get_zombie_death_team_points();
|
||||||
|
points = self player_add_points_kill_bonus( mod, hit_location );
|
||||||
|
if ( level.zombie_vars[ self.team ][ "zombie_powerup_insta_kill_on" ] == 1 && mod == "MOD_UNKNOWN" )
|
||||||
|
{
|
||||||
|
points *= 2;
|
||||||
|
}
|
||||||
|
player_points += points;
|
||||||
|
if ( team_points > 0 )
|
||||||
|
{
|
||||||
|
team_points += points;
|
||||||
|
}
|
||||||
|
if ( mod == "MOD_GRENADE" || mod == "MOD_GRENADE_SPLASH" )
|
||||||
|
{
|
||||||
|
self maps/mp/zombies/_zm_stats::increment_client_stat( "grenade_kills" );
|
||||||
|
self maps/mp/zombies/_zm_stats::increment_player_stat( "grenade_kills" );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "ballistic_knife_death":
|
||||||
|
player_points = get_zombie_death_player_points() + level.zombie_vars[ "zombie_score_bonus_melee" ];
|
||||||
|
self score_cf_increment_info( "death_melee" );
|
||||||
|
break;
|
||||||
|
case "damage_light":
|
||||||
|
player_points = level.zombie_vars[ "zombie_score_damage_light" ];
|
||||||
|
self score_cf_increment_info( "damage" );
|
||||||
|
break;
|
||||||
|
case "damage":
|
||||||
|
player_points = level.zombie_vars[ "zombie_score_damage_normal" ];
|
||||||
|
self score_cf_increment_info( "damage" );
|
||||||
|
break;
|
||||||
|
case "damage_ads":
|
||||||
|
player_points = int( level.zombie_vars[ "zombie_score_damage_normal" ] * 1.25 );
|
||||||
|
self score_cf_increment_info( "damage" );
|
||||||
|
break;
|
||||||
|
case "carpenter_powerup":
|
||||||
|
case "rebuild_board":
|
||||||
|
player_points = mod;
|
||||||
|
break;
|
||||||
|
case "bonus_points_powerup":
|
||||||
|
player_points = mod;
|
||||||
|
break;
|
||||||
|
case "nuke_powerup":
|
||||||
|
player_points = mod;
|
||||||
|
team_points = mod;
|
||||||
|
break;
|
||||||
|
case "jetgun_fling":
|
||||||
|
case "riotshield_fling":
|
||||||
|
case "thundergun_fling":
|
||||||
|
player_points = mod;
|
||||||
|
break;
|
||||||
|
case "hacker_transfer":
|
||||||
|
player_points = mod;
|
||||||
|
break;
|
||||||
|
case "reviver":
|
||||||
|
player_points = mod;
|
||||||
|
break;
|
||||||
|
case "vulture":
|
||||||
|
player_points = mod;
|
||||||
|
break;
|
||||||
|
case "build_wallbuy":
|
||||||
|
player_points = mod;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
assert( 0, "Unknown point event" );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
player_points = multiplier * round_up_score( player_points, 5 );
|
||||||
|
team_points = multiplier * round_up_score( team_points, 5 );
|
||||||
|
if ( isDefined( self.point_split_receiver ) || event == "death" && event == "ballistic_knife_death" )
|
||||||
|
{
|
||||||
|
split_player_points = player_points - round_up_score( player_points * self.point_split_keep_percent, 10 );
|
||||||
|
self.point_split_receiver add_to_player_score( split_player_points );
|
||||||
|
player_points -= split_player_points;
|
||||||
|
}
|
||||||
|
if ( is_true( level.pers_upgrade_pistol_points ) )
|
||||||
|
{
|
||||||
|
player_points = self maps/mp/zombies/_zm_pers_upgrades_functions::pers_upgrade_pistol_points_set_score( player_points, event, mod, damage_weapon );
|
||||||
|
}
|
||||||
|
self add_to_player_score( player_points );
|
||||||
|
self.pers[ "score" ] = self.score;
|
||||||
|
if ( isDefined( level._game_module_point_adjustment ) )
|
||||||
|
{
|
||||||
|
level [[ level._game_module_point_adjustment ]]( self, zombie_team, player_points );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get_points_multiplier( player )
|
||||||
|
{
|
||||||
|
multiplier = level.zombie_vars[ player.team ][ "zombie_point_scalar" ];
|
||||||
|
if ( isDefined( level.current_game_module ) && level.current_game_module == 2 )
|
||||||
|
{
|
||||||
|
if ( isDefined( level._race_team_double_points ) && level._race_team_double_points == player._race_team )
|
||||||
|
{
|
||||||
|
return multiplier;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_zombie_death_player_points()
|
||||||
|
{
|
||||||
|
players = get_players();
|
||||||
|
if ( players.size == 1 )
|
||||||
|
{
|
||||||
|
points = level.zombie_vars[ "zombie_score_kill_1player" ];
|
||||||
|
}
|
||||||
|
else if ( players.size == 2 )
|
||||||
|
{
|
||||||
|
points = level.zombie_vars[ "zombie_score_kill_2player" ];
|
||||||
|
}
|
||||||
|
else if ( players.size == 3 )
|
||||||
|
{
|
||||||
|
points = level.zombie_vars[ "zombie_score_kill_3player" ];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
points = level.zombie_vars[ "zombie_score_kill_4player" ];
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_zombie_death_team_points()
|
||||||
|
{
|
||||||
|
players = get_players();
|
||||||
|
if ( players.size == 1 )
|
||||||
|
{
|
||||||
|
points = level.zombie_vars[ "zombie_score_kill_1p_team" ];
|
||||||
|
}
|
||||||
|
else if ( players.size == 2 )
|
||||||
|
{
|
||||||
|
points = level.zombie_vars[ "zombie_score_kill_2p_team" ];
|
||||||
|
}
|
||||||
|
else if ( players.size == 3 )
|
||||||
|
{
|
||||||
|
points = level.zombie_vars[ "zombie_score_kill_3p_team" ];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
points = level.zombie_vars[ "zombie_score_kill_4p_team" ];
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
player_add_points_kill_bonus( mod, hit_location )
|
||||||
|
{
|
||||||
|
if ( mod == "MOD_MELEE" )
|
||||||
|
{
|
||||||
|
self score_cf_increment_info( "death_melee" );
|
||||||
|
return level.zombie_vars[ "zombie_score_bonus_melee" ];
|
||||||
|
}
|
||||||
|
if ( mod == "MOD_BURNED" )
|
||||||
|
{
|
||||||
|
self score_cf_increment_info( "death_torso" );
|
||||||
|
return level.zombie_vars[ "zombie_score_bonus_burn" ];
|
||||||
|
}
|
||||||
|
score = 0;
|
||||||
|
if ( isDefined( hit_location ) )
|
||||||
|
{
|
||||||
|
switch( hit_location )
|
||||||
|
{
|
||||||
|
case "head":
|
||||||
|
case "helmet":
|
||||||
|
self score_cf_increment_info( "death_head" );
|
||||||
|
score = level.zombie_vars[ "zombie_score_bonus_head" ];
|
||||||
|
break;
|
||||||
|
case "neck":
|
||||||
|
self score_cf_increment_info( "death_neck" );
|
||||||
|
score = level.zombie_vars[ "zombie_score_bonus_neck" ];
|
||||||
|
break;
|
||||||
|
case "torso_lower":
|
||||||
|
case "torso_upper":
|
||||||
|
self score_cf_increment_info( "death_torso" );
|
||||||
|
score = level.zombie_vars[ "zombie_score_bonus_torso" ];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
self score_cf_increment_info( "death_normal" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
|
player_reduce_points( event, mod, hit_location )
|
||||||
|
{
|
||||||
|
if ( level.intermission )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
points = 0;
|
||||||
|
switch( event )
|
||||||
|
{
|
||||||
|
case "no_revive_penalty":
|
||||||
|
percent = level.zombie_vars[ "penalty_no_revive" ];
|
||||||
|
points = self.score * percent;
|
||||||
|
break;
|
||||||
|
case "died":
|
||||||
|
percent = level.zombie_vars[ "penalty_died" ];
|
||||||
|
points = self.score * percent;
|
||||||
|
break;
|
||||||
|
case "downed":
|
||||||
|
percent = level.zombie_vars[ "penalty_downed" ];
|
||||||
|
self notify( "I_am_down" );
|
||||||
|
points = self.score * percent;
|
||||||
|
self.score_lost_when_downed = round_up_to_ten( int( points ) );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
assert( 0, "Unknown point event" );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
points = self.score - round_up_to_ten( int( points ) );
|
||||||
|
if ( points < 0 )
|
||||||
|
{
|
||||||
|
points = 0;
|
||||||
|
}
|
||||||
|
self.score = points;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_to_player_score( points, add_to_total )
|
||||||
|
{
|
||||||
|
if ( !isDefined( add_to_total ) )
|
||||||
|
{
|
||||||
|
add_to_total = 1;
|
||||||
|
}
|
||||||
|
if ( !isDefined( points ) || level.intermission )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.score += points;
|
||||||
|
self.pers[ "score" ] = self.score;
|
||||||
|
if ( add_to_total )
|
||||||
|
{
|
||||||
|
self.score_total += points;
|
||||||
|
}
|
||||||
|
self incrementplayerstat( "score", points );
|
||||||
|
}
|
||||||
|
|
||||||
|
minus_to_player_score( points, ignore_double_points_upgrade )
|
||||||
|
{
|
||||||
|
if ( !isDefined( points ) || level.intermission )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( !is_true( ignore_double_points_upgrade ) )
|
||||||
|
{
|
||||||
|
if ( is_true( level.pers_upgrade_double_points ) )
|
||||||
|
{
|
||||||
|
points = maps/mp/zombies/_zm_pers_upgrades_functions::pers_upgrade_double_points_set_score( points );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.score -= points;
|
||||||
|
self.pers[ "score" ] = self.score;
|
||||||
|
level notify( "spent_points" );
|
||||||
|
}
|
||||||
|
|
||||||
|
add_to_team_score( points )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
minus_to_team_score( points )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
player_died_penalty()
|
||||||
|
{
|
||||||
|
players = get_players( self.team );
|
||||||
|
i = 0;
|
||||||
|
while ( i < players.size )
|
||||||
|
{
|
||||||
|
if ( players[ i ] != self && !players[ i ].is_zombie )
|
||||||
|
{
|
||||||
|
players[ i ] player_reduce_points( "no_revive_penalty" );
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
player_downed_penalty()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
/#
|
||||||
|
println( "ZM >> LAST STAND - player_downed_penalty " );
|
||||||
|
#/
|
||||||
|
*/
|
||||||
|
self player_reduce_points( "downed" );
|
||||||
|
}
|
||||||
|
|
@ -1,25 +1,55 @@
|
|||||||
**The following gscs compile and run successfully with no known errors:**
|
###The following gscs compile and run successfully with no known errors:
|
||||||
|
```
|
||||||
|
patch_zm/maps/mp/zombies/_zm_ai_basic.gsc
|
||||||
patch_zm/maps/mp/zombies/_zm_ai_dogs.gsc
|
patch_zm/maps/mp/zombies/_zm_ai_dogs.gsc
|
||||||
patch_zm/maps/mp/zombies/_zm_tombstone.gsc
|
patch_zm/maps/mp/zombies/_zm_ai_faller.gsc
|
||||||
patch_zm/maps/mp/zombies/_zm_bot.gsc
|
patch_zm/maps/mp/zombies/_zm_bot.gsc
|
||||||
|
patch_zm/maps/mp/zombies/_zm_equip_hacker.gsc
|
||||||
|
patch_zm/maps/mp/zombies/_zm_hackables_boards.gsc
|
||||||
|
patch_zm/maps/mp/zombies/_zm_hackables_box.gsc
|
||||||
|
patch_zm/maps/mp/zombies/_zm_hackables_doors.gsc
|
||||||
|
patch_zm/maps/mp/zombies/_zm_hackables_packapunch.gsc
|
||||||
|
patch_zm/maps/mp/zombies/_zm_hackables_perks.gsc
|
||||||
|
patch_zm/maps/mp/zombies/_zm_hackables_powerups.gsc
|
||||||
|
patch_zm/maps/mp/zombies/_zm_hackables_wallbuys.gsc
|
||||||
|
patch_zm/maps/mp/zombies/_zm_pers_upgrades.gsc
|
||||||
|
patch_zm/maps/mp/zombies/_zm_pers_upgrades_functions.gsc
|
||||||
|
patch_zm/maps/mp/zombies/_zm_pers_upgrades_system.gsc
|
||||||
|
patch_zm/maps/mp/zombies/_zm_score.gsc
|
||||||
|
patch_zm/maps/mp/zombies/_zm_tombstone.gsc
|
||||||
|
```
|
||||||
|
```
|
||||||
patch_zm/maps/mp/gametypes_zm/_scoreboard.gsc
|
patch_zm/maps/mp/gametypes_zm/_scoreboard.gsc
|
||||||
patch_zm/maps/mp/gametypes_zm/_shellshock.gsc
|
patch_zm/maps/mp/gametypes_zm/_shellshock.gsc
|
||||||
|
|
||||||
zm_transit_patch/maps/mp/zm_transit_utility.gsc
|
|
||||||
|
|
||||||
**The following scripts compile and run successfully with no known errors but required minor changes to run**
|
|
||||||
patch_zm/maps/mp/gametypes_zm/zclassic.gsc
|
patch_zm/maps/mp/gametypes_zm/zclassic.gsc
|
||||||
|
```
|
||||||
**The following scripts compile and run successfully with minor errors:**
|
```
|
||||||
|
zm_transit_patch/maps/mp/zm_transit_utility.gsc
|
||||||
|
```
|
||||||
|
###The following scripts compile and run successfully with minor errors:
|
||||||
|
```
|
||||||
zm_transit_patch/maps/mp/gametypes_zm/zgrief.gsc
|
zm_transit_patch/maps/mp/gametypes_zm/zgrief.gsc
|
||||||
|
```
|
||||||
**The following scripts compile and run successfully with major errors:**
|
###The following scripts compile and run successfully with major errors:
|
||||||
|
```
|
||||||
zm_transit_patch/maps/mp/zombies/_zm_weap_jetgun.gsc
|
zm_transit_patch/maps/mp/zombies/_zm_weap_jetgun.gsc
|
||||||
|
```
|
||||||
**The following scripts compile but cause a minidump or other severe error:**
|
###The following scripts compile and run serverside but clients cannot join due to exe_client_field_mismatch
|
||||||
|
```
|
||||||
|
patch_zm/maps/mp/zombies/_zm_weapons.gsc
|
||||||
|
patch_zm/maps/mp/zombies/_zm_gump.gsc
|
||||||
|
patch_zm/maps/mp/zombies/_zm_equipment.gsc
|
||||||
|
patch_zm/maps/mp/zombies/_zm_perks.gsc
|
||||||
|
```
|
||||||
|
###The following scripts compile but cause a minidump or other severe error:
|
||||||
|
```
|
||||||
|
patch_zm/maps/mp/zombies/_load.gsc
|
||||||
patch_zm/maps/mp/zombies/_zm.gsc
|
patch_zm/maps/mp/zombies/_zm.gsc
|
||||||
patch_zm/maps/mp/zombies/_zm_powerups.gsc
|
patch_zm/maps/mp/zombies/_zm_powerups.gsc
|
||||||
patch_zm/maps/mp/zombies/_zm_magicbox.gsc
|
patch_zm/maps/mp/zombies/_zm_magicbox.gsc
|
||||||
|
```
|
||||||
|
|
||||||
**notes:**
|
###notes:
|
||||||
|
```
|
||||||
zm_transit_utility.gsc can be recompiled to fix tombstone
|
zm_transit_utility.gsc can be recompiled to fix tombstone
|
||||||
|
```
|
Loading…
x
Reference in New Issue
Block a user