// IW6 GSC SOURCE // Generated by https://github.com/xensik/gsc-tool init() { return; } spawnarmor( var_0, var_1, var_2 ) { var_3 = self vehicle_dospawn( "tank", var_0 ); var_3.health = 3000; var_3.targeting_delay = 1; var_3.team = var_0.team; var_3.pers["team"] = var_3.team; var_3.owner = var_0; var_3 setcandamage( 1 ); var_3.standardspeed = 12; var_3 thread deleteonz(); var_3 addtotanklist(); var_3.damagecallback = ::callback_vehicledamage; return var_3; } deleteonz() { self endon( "death" ); var_0 = self.origin[2]; for (;;) { if ( var_0 - self.origin[2] > 2048 ) { self.health = 0; self notify( "death" ); return; } wait 1.0; } } usetank( var_0 ) { return tryusetank(); } tryusetank() { if ( isdefined( level.tankinuse ) && level.tankinuse ) { self iprintlnbold( "Armor support unavailable." ); return 0; } if ( !isdefined( getvehiclenode( "startnode", "targetname" ) ) ) { self iprintlnbold( "Tank is currently not supported in this level, bug your friendly neighborhood LD." ); return 0; } if ( !vehicle_getspawnerarray().size ) return 0; if ( self.team == "allies" ) var_0 = level.tankspawner["allies"] spawnarmor( self, "vehicle_bradley" ); else var_0 = level.tankspawner["axis"] spawnarmor( self, "vehicle_bmp" ); var_0 starttank(); return 1; } starttank( var_0 ) { var_1 = getvehiclenode( "startnode", "targetname" ); var_2 = getvehiclenode( "waitnode", "targetname" ); self.nodes = getvehiclenodearray( "info_vehicle_node", "classname" ); level.tankinuse = 1; thread tankupdate( var_1, var_2 ); thread tankdamagemonitor(); level.tank = self; if ( level.teambased ) { var_3 = maps\mp\gametypes\_gameobjects::getnextobjid(); objective_add( var_3, "invisible", ( 0, 0, 0 ) ); objective_team( var_3, "allies" ); level.tank.objid["allies"] = var_3; var_4 = maps\mp\gametypes\_gameobjects::getnextobjid(); objective_add( var_4, "invisible", ( 0, 0, 0 ) ); objective_team( var_4, "axis" ); level.tank.objid["axis"] = var_4; var_5 = self.team; level.tank.team = var_5; level.tank.pers["team"] = var_5; } var_6 = spawnturret( "misc_turret", self.origin, "abrams_minigun_mp" ); var_6 linkto( self, "tag_engine_left", ( 0, 0, -20 ), ( 0, 0, 0 ) ); var_6 setmodel( "sentry_minigun" ); var_6.angles = self.angles; var_6.owner = self.owner; var_6 maketurretinoperable(); self.mgturret = var_6; self.mgturret setdefaultdroppitch( 0 ); var_7 = self.angles; self.angles = ( 0, 0, 0 ); var_8 = self gettagorigin( "tag_flash" ); self.angles = var_7; var_9 = var_8 - self.origin; thread waitforchangeteams(); thread waitfordisco(); self.timelastfired = gettime(); var_10 = spawn( "script_origin", self gettagorigin( "tag_flash" ) ); var_10 linkto( self, "tag_origin", var_9, ( 0, 0, 0 ) ); var_10 hide(); self.neutraltarget = var_10; thread tankgettargets(); thread destroytank(); thread tankgetminitargets(); thread checkdanger(); thread watchforthreat(); } waitforchangeteams() { self endon( "death" ); self.owner endon( "disconnect" ); self.owner waittill( "joined_team" ); self.health = 0; self notify( "death" ); } waitfordisco() { self endon( "death" ); self.owner waittill( "disconnect" ); self.health = 0; self notify( "death" ); } setdirection( var_0 ) { if ( self.veh_pathdir != var_0 ) { if ( var_0 == "forward" ) stoptoforward(); else stoptoreverse(); } } setengagementspeed() { self endon( "death" ); self notify( "path_abandoned" ); while ( isdefined( self.changingdirection ) ) wait 0.05; var_0 = 2; self vehicle_setspeed( var_0, 10, 10 ); self.speedtype = "engage"; } setminiengagementspeed() { self endon( "death" ); self notify( "path_abandoned" ); while ( isdefined( self.changingdirection ) ) wait 0.05; var_0 = 2; self vehicle_setspeed( var_0, 10, 10 ); self.speedtype = "engage"; } setstandardspeed() { self endon( "death" ); while ( isdefined( self.changingdirection ) ) wait 0.05; self vehicle_setspeed( self.standardspeed, 10, 10 ); self.speedtype = "standard"; } setevadespeed() { self endon( "death" ); while ( isdefined( self.changingdirection ) ) wait 0.05; self vehicle_setspeed( 15, 15, 15 ); self.speedtype = "evade"; wait 1.5; self vehicle_setspeed( self.standardspeed, 10, 10 ); } setdangerspeed() { self endon( "death" ); while ( isdefined( self.changingdirection ) ) wait 0.05; self vehicle_setspeed( 5, 5, 5 ); self.speedtype = "danger"; } stoptoreverse() { debugprintln2( "tank changing direction at " + gettime() ); self vehicle_setspeed( 0, 5, 6 ); self.changingdirection = 1; while ( self.veh_speed > 0 ) wait 0.05; wait 0.25; self.changingdirection = undefined; debugprintln2( "tank done changing direction" ); self.veh_transmission = "reverse"; self.veh_pathdir = "reverse"; self vehicle_setspeed( self.standardspeed, 5, 6 ); } stoptoforward() { debugprintln2( "tank changing direction at " + gettime() ); self vehicle_setspeed( 0, 5, 6 ); self.changingdirection = 1; while ( self.veh_speed > 0 ) wait 0.05; wait 0.25; self.changingdirection = undefined; debugprintln2( "tank done changing direction" ); self.veh_transmission = "forward"; self.veh_pathdir = "forward"; self vehicle_setspeed( self.standardspeed, 5, 6 ); } checkdanger() { self endon( "death" ); var_0 = []; var_1 = level.players; self.numenemiesclose = 0; for (;;) { foreach ( var_3 in var_1 ) { if ( !isdefined( var_3 ) ) continue; if ( var_3.team == self.team ) { wait 0.05; continue; } var_4 = distance2d( var_3.origin, self.origin ); if ( var_4 < 2048 ) self.numenemiesclose++; wait 0.05; } if ( isdefined( self.speedtype ) && ( self.speedtype == "evade" || self.speedtype == "engage" ) ) { self.numenemiesclose = 0; continue; } if ( self.numenemiesclose > 1 ) thread setdangerspeed(); else thread setstandardspeed(); self.numenemiesclose = 0; wait 0.05; } } tankupdate( var_0, var_1 ) { self endon( "tankDestroyed" ); self endon( "death" ); if ( !isdefined( level.graphnodes ) ) { self startpath( var_0 ); return; } self attachpath( var_0 ); self startpath( var_0 ); var_0 notify( "trigger", self, 1 ); wait 0.05; for (;;) { while ( isdefined( self.changingdirection ) ) wait 0.05; var_2 = getnodenearenemies(); if ( isdefined( var_2 ) ) self.endnode = var_2; else self.endnode = undefined; wait 0.65; } } callback_vehicledamage( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_11 ) { if ( ( var_1 == self || var_1 == self.mgturret || isdefined( var_1.pers ) && var_1.pers["team"] == self.team ) && ( var_1 != self.owner || var_4 == "MOD_MELEE" ) ) return; var_12 = modifydamage( var_4, var_2, var_1 ); self vehicle_finishdamage( var_0, var_1, var_12, var_3, var_4, var_5, var_6, var_7, var_8, var_9, var_10, var_11 ); } tankdamagemonitor() { self endon( "death" ); self.damagetaken = 0; var_0 = self vehicle_getspeed(); var_1 = self.health; var_2 = 0; var_3 = 0; var_4 = 0; for (;;) { self waittill( "damage", var_5, var_6, var_7, var_8, var_9 ); if ( isdefined( var_6.classname ) && var_6.classname == "script_vehicle" ) { if ( isdefined( self.besttarget ) && self.besttarget != var_6 ) { self.forcedtarget = var_6; thread explicitabandontarget(); } } else if ( isplayer( var_6 ) ) { var_6 maps\mp\gametypes\_damagefeedback::updatedamagefeedback( "hitHelicopter" ); if ( var_6 maps\mp\_utility::_hasperk( "specialty_armorpiercing" ) ) { var_10 = var_5 * level.armorpiercingmod; self.health = self.health - int( var_10 ); } } if ( self.health <= 0 ) { self notify( "death" ); return; } else if ( self.health < var_1 / 4 && var_4 == 0 ) var_4 = 1; else if ( self.health < var_1 / 2 && var_3 == 0 ) var_3 = 1; else if ( self.health < var_1 / 1.5 && var_2 == 0 ) var_2 = 1; if ( var_5 > 1000 ) handlethreat( var_6 ); } } handlethreat( var_0 ) { self endon( "death" ); var_1 = randomint( 100 ); if ( isdefined( self.besttarget ) && self.besttarget != var_0 && var_1 > 30 ) { var_2 = []; var_2[0] = self.besttarget; explicitabandontarget( 1, self.besttarget ); thread acquiretarget( var_2 ); } else if ( !isdefined( self.besttarget ) && var_1 > 30 ) { var_2 = []; var_2[0] = var_0; thread acquiretarget( var_2 ); } else if ( var_1 < 30 ) { playfx( level.tankcover, self.origin ); thread setevadespeed(); } else { self fireweapon(); self playsound( "bmp_fire" ); } } handlepossiblethreat( var_0 ) { self endon( "death" ); var_1 = relativeangle( var_0 ); var_2 = distance( self.origin, var_0.origin ); if ( randomint( 4 ) < 3 ) return; if ( var_1 == "front" && var_2 < 768 ) thread setevadespeed(); else if ( var_1 == "rear_side" || var_1 == "rear" && var_2 >= 768 ) { playfx( level.tankcover, self.origin ); thread setevadespeed(); } else if ( var_1 == "rear" && var_2 < 768 ) { stoptoreverse(); setevadespeed(); wait 4; stoptoforward(); } else if ( var_1 == "front_side" || var_1 == "front" ) { playfx( level.tankcover, self.origin ); stoptoreverse(); setevadespeed(); wait 8; stoptoforward(); } } relativeangle( var_0 ) { self endon( "death" ); var_0 endon( "death" ); var_0 endon( "disconnect" ); var_1 = anglestoforward( self.angles ); var_2 = var_0.origin - self.origin; var_1 = var_1 * ( 1, 1, 0 ); var_2 = var_2 * ( 1, 1, 0 ); var_2 = vectornormalize( var_2 ); var_1 = vectornormalize( var_1 ); var_3 = vectordot( var_2, var_1 ); if ( var_3 > 0 ) { if ( var_3 > 0.9 ) return "front"; else return "front_side"; } else if ( var_3 < -0.9 ) return "rear"; else return "rear_side"; var_0 iprintlnbold( var_3 ); } watchforthreat() { self endon( "death" ); for (;;) { var_0 = []; var_1 = level.players; foreach ( var_3 in var_1 ) { if ( !isdefined( var_3 ) ) { wait 0.05; continue; } if ( !istarget( var_3 ) ) { wait 0.05; continue; } var_4 = var_3 getcurrentweapon(); if ( issubstr( var_4, "at4" ) || issubstr( var_4, "stinger" ) || issubstr( var_4, "javelin" ) ) { thread handlepossiblethreat( var_3 ); wait 8; } wait 0.15; } } } checkowner() { if ( !isdefined( self.owner ) || !isdefined( self.owner.pers["team"] ) || self.owner.pers["team"] != self.team ) { self notify( "abandoned" ); return 0; } return 1; } modifydamage( var_0, var_1, var_2 ) { if ( var_0 == "MOD_RIFLE_BULLET" ) return var_1; else if ( var_0 == "MOD_PISTOL_BULLET" ) return var_1; else if ( var_0 == "MOD_IMPACT" ) return var_1; else if ( var_0 == "MOD_MELEE" ) return 0; else if ( var_0 == "MOD_EXPLOSIVE_BULLET" ) return var_1; else if ( var_0 == "MOD_GRENADE" ) return var_1 * 5; else if ( var_0 == "MOD_GRENADE_SPLASH" ) return var_1 * 5; else return var_1 * 10; } destroytank() { self waittill( "death" ); if ( level.teambased ) { var_0 = level.tank.team; objective_state( level.tank.objid[var_0], "invisible" ); objective_state( level.tank.objid[level.otherteam[var_0]], "invisible" ); } self notify( "tankDestroyed" ); self vehicle_setspeed( 0, 10, 10 ); level.tankinuse = 0; playfx( level.spawnfire, self.origin ); playfx( level.tankfire, self.origin ); removefromtanklist(); var_1 = spawn( "script_model", self.origin ); var_1 setmodel( "vehicle_m1a1_abrams_d_static" ); var_1.angles = self.angles; self.mgturret delete(); self delete(); wait 4; var_1 delete(); } onhitpitchclamp() { self notify( "onTargOrTimeOut" ); self endon( "onTargOrTimeOut" ); self endon( "turret_on_target" ); self waittill( "turret_pitch_clamped" ); thread explicitabandontarget( 0, self.besttarget ); } fireontarget() { self endon( "abandonedTarget" ); self endon( "killedTarget" ); self endon( "death" ); self endon( "targetRemoved" ); self endon( "lostLOS" ); for (;;) { onhitpitchclamp(); if ( !isdefined( self.besttarget ) ) continue; var_0 = self gettagorigin( "tag_flash" ); var_1 = bullettrace( self.origin, var_0, 0, self ); if ( var_1["position"] != var_0 ) thread explicitabandontarget( 0, self.besttarget ); var_1 = bullettrace( var_0, self.besttarget.origin, 1, self ); var_2 = distance( self.origin, var_1["position"] ); var_3 = distance( self.besttarget.origin, self.origin ); if ( var_2 < 384 || var_2 + 256 < var_3 ) { wait 0.5; if ( var_2 > 384 ) { waitforturretready(); self fireweapon(); self playsound( "bmp_fire" ); self.timelastfired = gettime(); } var_4 = relativeangle( self.besttarget ); thread explicitabandontarget( 0, self.besttarget ); return; } waitforturretready(); self fireweapon(); self playsound( "bmp_fire" ); self.timelastfired = gettime(); } } waitforturretready() { self endon( "abandonedTarget" ); self endon( "killedTarget" ); self endon( "death" ); self endon( "targetRemoved" ); self endon( "lostLOS" ); var_0 = gettime() - self.timelastfired; if ( var_0 < 1499 ) wait( 1.5 - var_0 / 1000 ); } tankgettargets( var_0 ) { self endon( "death" ); self endon( "leaving" ); var_1 = []; for (;;) { var_1 = []; var_2 = level.players; if ( isdefined( self.forcedtarget ) ) { var_1 = []; var_1[0] = self.forcedtarget; acquiretarget( var_1 ); self.forcedtarget = undefined; } if ( isdefined( level.harrier ) && level.harrier.team != self.team && isalive( level.harrier ) ) { if ( isvehicletarget( level.tank ) ) var_1[var_1.size] = level.tank; } if ( isdefined( level.chopper ) && level.chopper.team != self.team && isalive( level.chopper ) ) { if ( isvehicletarget( level.chopper ) ) var_1[var_1.size] = level.chopper; } foreach ( var_4 in var_2 ) { if ( !isdefined( var_4 ) ) { wait 0.05; continue; } if ( isdefined( var_0 ) && var_4 == var_0 ) continue; if ( istarget( var_4 ) ) { if ( isdefined( var_4 ) ) var_1[var_1.size] = var_4; continue; } continue; } if ( var_1.size > 0 ) { acquiretarget( var_1 ); continue; } wait 1; } } acquiretarget( var_0 ) { self endon( "death" ); if ( var_0.size == 1 ) self.besttarget = var_0[0]; else self.besttarget = getbesttarget( var_0 ); thread setengagementspeed(); thread watchtargetdeath( var_0 ); self setturrettargetent( self.besttarget ); fireontarget(); thread setnotarget(); } setnotarget() { self endon( "death" ); setstandardspeed(); removetarget(); self setturrettargetent( self.neutraltarget ); } getbesttarget( var_0 ) { self endon( "death" ); var_1 = self gettagorigin( "tag_flash" ); var_2 = self.origin; var_3 = undefined; var_4 = undefined; var_5 = 0; foreach ( var_7 in var_0 ) { var_8 = abs( vectortoangles( var_7.origin - self.origin )[1] ); var_9 = abs( self gettagangles( "tag_flash" )[1] ); var_8 = abs( var_8 - var_9 ); if ( isdefined( level.chopper ) && var_7 == level.chopper ) return var_7; if ( isdefined( level.harrier ) && var_7 == level.harrier ) return var_7; var_10 = var_7 getweaponslistitems(); foreach ( var_12 in var_10 ) { if ( issubstr( var_12, "at4" ) || issubstr( var_12, "jav" ) || issubstr( var_12, "c4" ) ) var_8 = var_8 - 40; } if ( !isdefined( var_3 ) ) { var_3 = var_8; var_4 = var_7; continue; } if ( var_3 > var_8 ) { var_3 = var_8; var_4 = var_7; } } return var_4; } watchtargetdeath( var_0 ) { self endon( "abandonedTarget" ); self endon( "lostLOS" ); self endon( "death" ); self endon( "targetRemoved" ); var_1 = self.besttarget; var_1 endon( "disconnect" ); var_1 waittill( "death" ); self notify( "killedTarget" ); removetarget(); setstandardspeed(); thread setnotarget(); } explicitabandontarget( var_0, var_1 ) { self endon( "death" ); self notify( "abandonedTarget" ); setstandardspeed(); thread setnotarget(); removetarget(); if ( isdefined( var_1 ) ) { self.badtarget = var_1; badtargetreset(); } if ( isdefined( var_0 ) && var_0 ) return; return; } badtargetreset() { self endon( "death" ); wait 1.5; self.badtarget = undefined; } removetarget() { self notify( "targetRemoved" ); self.besttarget = undefined; self.lastlosttime = undefined; } isvehicletarget( var_0 ) { if ( distance2d( var_0.origin, self.origin ) > 4096 ) return 0; if ( distance( var_0.origin, self.origin ) < 512 ) return 0; return turretsighttrace( var_0, 0 ); } istarget( var_0 ) { self endon( "death" ); var_1 = distancesquared( var_0.origin, self.origin ); if ( !level.teambased && isdefined( self.owner ) && var_0 == self.owner ) return 0; if ( !isalive( var_0 ) || var_0.sessionstate != "playing" ) return 0; if ( var_1 > 16777216 ) return 0; if ( var_1 < 262144 ) return 0; if ( !isdefined( var_0.pers["team"] ) ) return 0; if ( var_0 == self.owner ) return 0; if ( level.teambased && var_0.pers["team"] == self.team ) return 0; if ( var_0.pers["team"] == "spectator" ) return 0; if ( isdefined( var_0.spawntime ) && ( gettime() - var_0.spawntime ) / 1000 <= 5 ) return 0; if ( var_0 maps\mp\_utility::_hasperk( "specialty_blindeye" ) ) return 0; return self vehicle_canturrettargetpoint( var_0.origin, 1, self ); } turretsighttrace( var_0, var_1 ) { var_2 = var_0 sightconetrace( self gettagorigin( "tag_turret" ), self ); if ( var_2 < 0.7 ) return 0; if ( isdefined( var_1 ) && var_1 ) thread maps\mp\_utility::drawline( var_0.origin, self gettagorigin( "tag_turret" ), 10, ( 1, 0, 0 ) ); return 1; } isminitarget( var_0 ) { self endon( "death" ); if ( !isalive( var_0 ) || var_0.sessionstate != "playing" ) return 0; if ( !isdefined( var_0.pers["team"] ) ) return 0; if ( var_0 == self.owner ) return 0; if ( distancesquared( var_0.origin, self.origin ) > 1048576 ) return 0; if ( level.teambased && var_0.pers["team"] == self.team ) return 0; if ( var_0.pers["team"] == "spectator" ) return 0; if ( isdefined( var_0.spawntime ) && ( gettime() - var_0.spawntime ) / 1000 <= 5 ) return 0; if ( isdefined( self ) ) { var_1 = self.mgturret.origin + ( 0, 0, 64 ); var_2 = var_0 sightconetrace( var_1, self ); if ( var_2 < 1 ) return 0; } return 1; } tankgetminitargets() { self endon( "death" ); self endon( "leaving" ); var_0 = []; for (;;) { var_0 = []; var_1 = level.players; for ( var_2 = 0; var_2 <= var_1.size; var_2++ ) { if ( isminitarget( var_1[var_2] ) ) { if ( isdefined( var_1[var_2] ) ) var_0[var_0.size] = var_1[var_2]; } else continue; wait 0.05; } if ( var_0.size > 0 ) { acquireminitarget( var_0 ); return; } else wait 0.5; } } getbestminitarget( var_0 ) { self endon( "death" ); var_1 = self.origin; var_2 = undefined; var_3 = undefined; foreach ( var_5 in var_0 ) { var_6 = distance( self.origin, var_5.origin ); var_7 = var_5 getcurrentweapon(); if ( issubstr( var_7, "at4" ) || issubstr( var_7, "jav" ) || issubstr( var_7, "c4" ) || issubstr( var_7, "smart" ) || issubstr( var_7, "grenade" ) ) var_6 = var_6 - 200; if ( !isdefined( var_2 ) ) { var_2 = var_6; var_3 = var_5; continue; } if ( var_2 > var_6 ) { var_2 = var_6; var_3 = var_5; } } return var_3; } acquireminitarget( var_0 ) { self endon( "death" ); if ( var_0.size == 1 ) self.bestminitarget = var_0[0]; else self.bestminitarget = getbestminitarget( var_0 ); if ( distance2d( self.origin, self.bestminitarget.origin ) > 768 ) thread setminiengagementspeed(); self notify( "acquiringMiniTarget" ); self.mgturret settargetentity( self.bestminitarget, ( 0, 0, 64 ) ); wait 0.15; thread fireminiontarget(); thread watchminitargetdeath( var_0 ); thread watchminitargetdistance( var_0 ); thread watchminitargetthreat( self.bestminitarget ); } fireminiontarget() { self endon( "death" ); self endon( "abandonedMiniTarget" ); self endon( "killedMiniTarget" ); var_0 = undefined; var_1 = gettime(); if ( !isdefined( self.bestminitarget ) ) return; for (;;) { if ( !isdefined( self.mgturret getturrettarget( 1 ) ) ) { if ( !isdefined( var_0 ) ) var_0 = gettime(); var_2 = gettime(); if ( var_0 - var_2 > 1 ) { var_0 = undefined; thread explicitabandonminitarget(); return; } wait 0.5; continue; } if ( gettime() > var_1 + 1000 && !isdefined( self.besttarget ) ) { if ( distance2d( self.origin, self.bestminitarget.origin ) > 768 ) { var_3[0] = self.bestminitarget; acquiretarget( var_3 ); } } var_4 = randomintrange( 10, 16 ); for ( var_5 = 0; var_5 < var_4; var_5++ ) { self.mgturret shootturret(); wait 0.1; } wait( randomfloatrange( 0.5, 3.0 ) ); } } watchminitargetdeath( var_0 ) { self endon( "abandonedMiniTarget" ); self endon( "death" ); if ( !isdefined( self.bestminitarget ) ) return; self.bestminitarget waittill( "death" ); self notify( "killedMiniTarget" ); self.bestminitarget = undefined; self.mgturret cleartargetentity(); tankgetminitargets(); } watchminitargetdistance( var_0 ) { self endon( "abandonedMiniTarget" ); self endon( "death" ); for (;;) { if ( !isdefined( self.bestminitarget ) ) return; var_1 = bullettrace( self.mgturret.origin, self.bestminitarget.origin, 0, self ); var_2 = distance( self.origin, var_1["position"] ); if ( var_2 > 1024 ) { thread explicitabandonminitarget(); return; } wait 2; } } watchminitargetthreat( var_0 ) { self endon( "abandonedMiniTarget" ); self endon( "death" ); self endon( "killedMiniTarget" ); for (;;) { var_1 = []; var_2 = level.players; for ( var_3 = 0; var_3 <= var_2.size; var_3++ ) { if ( isminitarget( var_2[var_3] ) ) { if ( !isdefined( var_2[var_3] ) ) continue; if ( !isdefined( var_0 ) ) return; var_4 = distance( self.origin, var_0.origin ); var_5 = distance( self.origin, var_2[var_3].origin ); if ( var_5 < var_4 ) { thread explicitabandonminitarget(); return; } } wait 0.05; } wait 0.25; } } explicitabandonminitarget( var_0 ) { self notify( "abandonedMiniTarget" ); self.bestminitarget = undefined; self.mgturret cleartargetentity(); if ( isdefined( var_0 ) && var_0 ) return; thread tankgetminitargets(); return; } addtotanklist() { level.tanks[self getentitynumber()] = self; } removefromtanklist() { level.tanks[self getentitynumber()] = undefined; } getnodenearenemies() { var_0 = []; foreach ( var_2 in level.players ) { if ( var_2.team == "spectator" ) continue; if ( var_2.team == self.team ) continue; if ( !isalive( var_2 ) ) continue; var_2.dist = 0; var_0[var_0.size] = var_2; } if ( !var_0.size ) return undefined; for ( var_4 = 0; var_4 < var_0.size; var_4++ ) { for ( var_5 = var_4 + 1; var_5 < var_0.size; var_5++ ) { var_6 = distancesquared( var_0[var_4].origin, var_0[var_5].origin ); var_0[var_4].dist = var_0[var_4].dist + var_6; var_0[var_5].dist = var_0[var_5].dist + var_6; } } var_7 = var_0[0]; foreach ( var_2 in var_0 ) { if ( var_2.dist < var_7.dist ) var_7 = var_2; } var_10 = var_7.origin; var_11 = sortbydistance( level.graphnodes, var_10 ); return var_11[0]; } setuppaths() { var_0 = []; var_1 = []; var_2 = []; var_3 = []; var_4 = getvehiclenode( "startnode", "targetname" ); var_0[var_0.size] = var_4; var_1[var_1.size] = var_4; while ( isdefined( var_4.target ) ) { var_5 = var_4; var_4 = getvehiclenode( var_4.target, "targetname" ); var_4.prev = var_5; if ( var_4 == var_0[0] ) break; var_0[var_0.size] = var_4; if ( !isdefined( var_4.target ) ) return; } var_0[0].branchnodes = []; var_0[0] thread handlebranchnode( "forward" ); var_3[var_3.size] = var_0[0]; var_6 = getvehiclenodearray( "branchnode", "targetname" ); foreach ( var_8 in var_6 ) { var_4 = var_8; var_0[var_0.size] = var_4; var_1[var_1.size] = var_4; while ( isdefined( var_4.target ) ) { var_5 = var_4; var_4 = getvehiclenode( var_4.target, "targetname" ); var_0[var_0.size] = var_4; var_4.prev = var_5; if ( !isdefined( var_4.target ) ) var_2[var_2.size] = var_4; } } foreach ( var_4 in var_0 ) { var_11 = 0; foreach ( var_13 in var_1 ) { if ( var_13 == var_4 ) continue; if ( var_13.target == var_4.targetname ) continue; if ( isdefined( var_4.target ) && var_4.target == var_13.targetname ) continue; if ( distance2d( var_4.origin, var_13.origin ) > 80 ) continue; var_13 thread handlecapnode( var_4, "reverse" ); var_13.prev = var_4; if ( !isdefined( var_4.branchnodes ) ) var_4.branchnodes = []; var_4.branchnodes[var_4.branchnodes.size] = var_13; var_11 = 1; } if ( var_11 ) var_4 thread handlebranchnode( "forward" ); var_15 = 0; foreach ( var_17 in var_2 ) { if ( var_17 == var_4 ) continue; if ( !isdefined( var_4.target ) ) continue; if ( var_4.target == var_17.targetname ) continue; if ( isdefined( var_17.target ) && var_17.target == var_4.targetname ) continue; if ( distance2d( var_4.origin, var_17.origin ) > 80 ) continue; var_17 thread handlecapnode( var_4, "forward" ); var_17.next = getvehiclenode( var_4.targetname, "targetname" ); var_17.length = distance( var_17.origin, var_4.origin ); if ( !isdefined( var_4.branchnodes ) ) var_4.branchnodes = []; var_4.branchnodes[var_4.branchnodes.size] = var_17; var_15 = 1; } if ( var_15 ) var_4 thread handlebranchnode( "reverse" ); if ( var_15 || var_11 ) var_3[var_3.size] = var_4; } if ( var_3.size < 3 ) { level notify( "end_tankPathHandling" ); return; } var_20 = []; foreach ( var_4 in var_0 ) { if ( !isdefined( var_4.branchnodes ) ) continue; var_20[var_20.size] = var_4; } foreach ( var_24 in var_20 ) { var_4 = var_24; var_25 = 0; while ( isdefined( var_4.target ) ) { var_26 = var_4; var_4 = getvehiclenode( var_4.target, "targetname" ); var_25 = var_25 + distance( var_4.origin, var_26.origin ); if ( var_4 == var_24 ) break; if ( isdefined( var_4.branchnodes ) ) break; } if ( var_25 > 1000 ) { var_4 = var_24; var_27 = 0; while ( isdefined( var_4.target ) ) { var_26 = var_4; var_4 = getvehiclenode( var_4.target, "targetname" ); var_27 = var_27 + distance( var_4.origin, var_26.origin ); if ( var_27 < var_25 / 2 ) continue; var_4.branchnodes = []; var_4 thread handlebranchnode( "forward" ); var_3[var_3.size] = var_4; break; } } } level.graphnodes = initnodegraph( var_3 ); foreach ( var_4 in var_0 ) { if ( !isdefined( var_4.graphid ) ) var_4 thread nodetracker(); } } getrandombranchnode( var_0 ) { var_1 = []; foreach ( var_4, var_3 in self.links ) { if ( self.linkdirs[var_4] != var_0 ) continue; var_1[var_1.size] = var_3; } return var_1[randomint( var_1.size )]; } getnextnodeforendnode( var_0, var_1 ) { var_2 = level.graphnodes[self.graphid]; var_3 = generatepath( var_2, var_0, undefined, var_1 ); var_4 = var_3[0].g; var_5 = generatepath( var_2, var_0, undefined, level.otherdir[var_1] ); var_6 = var_5[0].g; if ( !getdvarint( "tankDebug" ) ) var_6 = 9999999; if ( var_4 <= var_6 ) return var_3[1]; } handlebranchnode( var_0 ) { level endon( "end_tankPathHandling" ); for (;;) { self waittill( "trigger", var_1, var_2 ); var_3 = level.graphnodes[self.graphid]; var_1.node = self; var_4 = undefined; if ( isdefined( var_1.endnode ) && var_1.endnode != var_3 ) { var_4 = getnextnodeforendnode( var_1.endnode, var_1.veh_pathdir ); if ( !isdefined( var_4 ) ) var_1 thread setdirection( level.otherdir[var_1.veh_pathdir] ); } if ( !isdefined( var_4 ) || var_4 == var_3 ) var_4 = var_3 getrandombranchnode( var_1.veh_pathdir ); var_5 = var_3.linkstartnodes[var_4.graphid]; if ( var_1.veh_pathdir == "forward" ) var_6 = getnextnode(); else var_6 = getprevnode(); if ( var_6 != var_5 ) var_1 startpath( var_5 ); } } handlecapnode( var_0, var_1 ) { for (;;) { self waittill( "trigger", var_2 ); if ( var_2.veh_pathdir != var_1 ) continue; debugprintln2( "tank starting path at join node: " + var_0.graphid ); var_2 startpath( var_0 ); } } nodetracker() { self.forwardgraphid = getforwardgraphnode().graphid; self.reversegraphid = getreversegraphnode().graphid; for (;;) { self waittill( "trigger", var_0, var_1 ); var_0.node = self; var_0.forwardgraphid = self.forwardgraphid; var_0.reversegraphid = self.reversegraphid; if ( !isdefined( self.target ) || self.targetname == "branchnode" ) var_2 = "TRANS"; else var_2 = "NODE"; if ( isdefined( var_1 ) ) { debugprint3d( self.origin, var_2, ( 1, 0.5, 0 ), 1, 2, 100 ); continue; } debugprint3d( self.origin, var_2, ( 0, 1, 0 ), 1, 2, 100 ); } } forcetrigger( var_0, var_1, var_2 ) { var_1 endon( "trigger" ); var_0 endon( "trigger" ); var_2 endon( "death" ); var_3 = distancesquared( var_2.origin, var_1.origin ); var_4 = var_2.veh_pathdir; debugprint3d( var_0.origin + ( 0, 0, 30 ), "LAST", ( 0, 0, 1 ), 0.5, 1, 100 ); debugprint3d( var_1.origin + ( 0, 0, 60 ), "NEXT", ( 0, 1, 0 ), 0.5, 1, 100 ); var_5 = 0; for (;;) { wait 0.05; if ( var_4 != var_2.veh_pathdir ) { debugprintln2( "tank missed node: reversing direction" ); var_2 thread forcetrigger( var_1, var_0, var_2 ); return; } if ( var_5 ) { debugprintln2( "... sending notify." ); var_1 notify( "trigger", var_2, 1 ); return; } var_6 = distancesquared( var_2.origin, var_1.origin ); if ( var_6 > var_3 ) { var_5 = 1; debugprintln2( "tank missed node: forcing notify in one frame..." ); } var_3 = var_6; } } getforwardgraphnode() { for ( var_0 = self; !isdefined( var_0.graphid ); var_0 = var_0 getnextnode() ) { } return var_0; } getreversegraphnode() { for ( var_0 = self; !isdefined( var_0.graphid ); var_0 = var_0 getprevnode() ) { } return var_0; } getnextnode() { if ( isdefined( self.target ) ) return getvehiclenode( self.target, "targetname" ); else return self.next; } getprevnode() { return self.prev; } initnodegraph( var_0 ) { var_1 = []; foreach ( var_3 in var_0 ) { var_4 = spawnstruct(); var_4.linkinfos = []; var_4.links = []; var_4.linklengths = []; var_4.linkdirs = []; var_4.linkstartnodes = []; var_4.node = var_3; var_4.origin = var_3.origin; var_4.graphid = var_1.size; var_3.graphid = var_1.size; debugprint3d( var_4.origin + ( 0, 0, 80 ), var_4.graphid, ( 1, 1, 1 ), 0.65, 2, 100000 ); var_1[var_1.size] = var_4; } foreach ( var_3 in var_0 ) { var_7 = var_3.graphid; var_8 = getvehiclenode( var_3.target, "targetname" ); var_9 = distance( var_3.origin, var_8.origin ); var_10 = var_8; while ( !isdefined( var_8.graphid ) ) { var_9 = var_9 + distance( var_8.origin, var_8.prev.origin ); if ( isdefined( var_8.target ) ) { var_8 = getvehiclenode( var_8.target, "targetname" ); continue; } var_8 = var_8.next; } var_1[var_7] addlinknode( var_1[var_8.graphid], var_9, "forward", var_10 ); var_8 = var_3.prev; var_9 = distance( var_3.origin, var_8.origin ); for ( var_10 = var_8; !isdefined( var_8.graphid ); var_8 = var_8.prev ) var_9 = var_9 + distance( var_8.origin, var_8.prev.origin ); var_1[var_7] addlinknode( var_1[var_8.graphid], var_9, "reverse", var_10 ); foreach ( var_12 in var_3.branchnodes ) { var_8 = var_12; var_9 = distance( var_3.origin, var_8.origin ); var_10 = var_8; if ( var_8.targetname == "branchnode" ) { while ( !isdefined( var_8.graphid ) ) { if ( isdefined( var_8.target ) ) var_13 = getvehiclenode( var_8.target, "targetname" ); else var_13 = var_8.next; var_9 = var_9 + distance( var_8.origin, var_13.origin ); var_8 = var_13; } var_1[var_7] addlinknode( var_1[var_8.graphid], var_9, "forward", var_10 ); continue; } while ( !isdefined( var_8.graphid ) ) { var_9 = var_9 + distance( var_8.origin, var_8.prev.origin ); var_8 = var_8.prev; } var_1[var_7] addlinknode( var_1[var_8.graphid], var_9, "reverse", var_10 ); } } return var_1; } addlinknode( var_0, var_1, var_2, var_3 ) { self.links[var_0.graphid] = var_0; self.linklengths[var_0.graphid] = var_1; self.linkdirs[var_0.graphid] = var_2; self.linkstartnodes[var_0.graphid] = var_3; var_4 = spawnstruct(); var_4.tographnode = var_0; var_4.tographid = var_0.graphid; var_4.length = var_1; var_4.direction = var_2; var_4.startnode = var_3; self.linkinfos[var_0.graphid] = var_4; } generatepath( var_0, var_1, var_2, var_3 ) { level.openlist = []; level.closedlist = []; var_4 = 0; var_5 = []; if ( !isdefined( var_2 ) ) var_2 = []; var_1.g = 0; var_1.h = gethvalue( var_1, var_0 ); var_1.f = var_1.g + var_1.h; addtoclosedlist( var_1 ); var_6 = var_1; for (;;) { foreach ( var_9, var_8 in var_6.links ) { if ( is_in_array( var_2, var_8 ) ) continue; if ( is_in_array( level.closedlist, var_8 ) ) continue; if ( isdefined( var_3 ) && var_8.linkdirs[var_6.graphid] != var_3 ) continue; if ( !is_in_array( level.openlist, var_8 ) ) { addtoopenlist( var_8 ); var_8.parentnode = var_6; var_8.g = getgvalue( var_8, var_6 ); var_8.h = gethvalue( var_8, var_0 ); var_8.f = var_8.g + var_8.h; if ( var_8 == var_0 ) var_4 = 1; continue; } if ( var_8.g < getgvalue( var_6, var_8 ) ) continue; var_8.parentnode = var_6; var_8.g = getgvalue( var_8, var_6 ); var_8.f = var_8.g + var_8.h; } if ( var_4 ) break; addtoclosedlist( var_6 ); var_10 = level.openlist[0]; foreach ( var_12 in level.openlist ) { if ( var_12.f > var_10.f ) continue; var_10 = var_12; } addtoclosedlist( var_10 ); var_6 = var_10; } for ( var_6 = var_0; var_6 != var_1; var_6 = var_6.parentnode ) var_5[var_5.size] = var_6; var_5[var_5.size] = var_6; return var_5; } addtoopenlist( var_0 ) { var_0.openlistid = level.openlist.size; level.openlist[level.openlist.size] = var_0; var_0.closedlistid = undefined; } addtoclosedlist( var_0 ) { if ( isdefined( var_0.closedlistid ) ) return; var_0.closedlistid = level.closedlist.size; level.closedlist[level.closedlist.size] = var_0; if ( !is_in_array( level.openlist, var_0 ) ) return; level.openlist[var_0.openlistid] = level.openlist[level.openlist.size - 1]; level.openlist[var_0.openlistid].openlistid = var_0.openlistid; level.openlist[level.openlist.size - 1] = undefined; var_0.openlistid = undefined; } gethvalue( var_0, var_1 ) { return distance( var_0.node.origin, var_1.node.origin ); } getgvalue( var_0, var_1 ) { return var_0.parentnode.g + var_0.linklengths[var_1.graphid]; } is_in_array( var_0, var_1 ) { for ( var_2 = 0; var_2 < var_0.size; var_2++ ) { if ( var_0[var_2] == var_1 ) return 1; } return 0; } drawpath( var_0 ) { for ( var_1 = 1; var_1 < var_0.size; var_1++ ) { var_2 = var_0[var_1 - 1]; var_3 = var_0[var_1]; if ( var_2.linkdirs[var_3.graphid] == "reverse" ) level thread drawlink( var_2.node.origin, var_3.node.origin, ( 1, 0, 0 ) ); else level thread drawlink( var_2.node.origin, var_3.node.origin, ( 0, 1, 0 ) ); var_4 = var_2.linkstartnodes[var_3.graphid]; level thread drawlink( var_2.node.origin + ( 0, 0, 4 ), var_4.origin + ( 0, 0, 4 ), ( 0, 0, 1 ) ); if ( var_2.linkdirs[var_3.graphid] == "reverse" ) { while ( !isdefined( var_4.graphid ) ) { var_5 = var_4; var_4 = var_4.prev; level thread drawlink( var_5.origin + ( 0, 0, 4 ), var_4.origin + ( 0, 0, 4 ), ( 0, 1, 1 ) ); } continue; } while ( !isdefined( var_4.graphid ) ) { var_5 = var_4; if ( isdefined( var_4.target ) ) var_4 = getvehiclenode( var_4.target, "targetname" ); else var_4 = var_4.next; level thread drawlink( var_5.origin + ( 0, 0, 4 ), var_4.origin + ( 0, 0, 4 ), ( 0, 1, 1 ) ); } } } drawgraph( var_0 ) { } drawlink( var_0, var_1, var_2 ) { level endon( "endpath" ); for (;;) wait 0.05; } debugprintln2( var_0 ) { } debugprint( var_0 ) { } debugprint3d( var_0, var_1, var_2, var_3, var_4, var_5 ) { } drawtankgraphids() { }