// IW6 GSC SOURCE // Generated by https://github.com/xensik/gsc-tool seeder_level_init() { if ( !isdefined( level.alien_funcs ) ) level.agent_funcs = []; level.alien_funcs["seeder"]["approach"] = maps\mp\agents\alien\_alien_think::default_approach; level.alien_funcs["seeder"]["combat"] = ::seeder_combat; level.alien_funcs["seeder"]["badpath"] = maps\mp\agents\alien\_alien_think::handle_badpath; if ( !isdefined( level.seeder_active_turrets ) ) level.seeder_active_turrets = []; level.seeder_active_pet_turrets = 0; } seeder_init() { self.gas_cloud_available = 1; self.num_active_turrets = 0; self.skipstartmove = 1; self.total_turrets_spawned = 0; } load_seeder_fx() { level._effect["spit_AOE"] = loadfx( "vfx/gameplay/alien/vfx_alien_spitter_gas_cloud" ); level._effect["spit_AOE_small"] = loadfx( "vfx/gameplay/alien/vfx_alien_spitter_gas_cloud_64" ); level._effect["spore_darts_fire"] = loadfx( "vfx/gameplay/alien/vfx_alien_spore_darts_01" ); level._effect["spore_death_fx"] = loadfx( "vfx/gameplay/alien/vfx_alien_seeder_spore_death" ); level._effect["spore_birth_fx"] = loadfx( "vfx/gameplay/alien/vfx_alien_seeder_spore_birth" ); level._effect["alien_seeder_preexplode"] = loadfx( "vfx/gameplay/alien/vfx_alien_minion_preexplosion" ); level._effect["alien_seeder_explode"] = loadfx( "vfx/gameplay/alien/vfx_alien_minion_explode" ); } seeder_death( var_0 ) { if ( !var_0 ) level thread seeder_explode_on_death( self ); maps\mp\agents\alien\_alien_spitter::release_spit_node(); if ( isdefined( self.pet ) && level.seeder_active_pet_turrets > 0 ) { foreach ( var_2 in level.seeder_active_turrets ) { if ( isdefined( var_2.parent ) && var_2.parent == self && isdefined( var_2.pet ) ) var_2 notify( "death" ); } } } seeder_combat( var_0 ) { self endon( "bad_path" ); self endon( "death" ); self endon( "alien_main_loop_restart" ); var_1 = undefined; for (;;) { var_2 = maps\mp\agents\alien\_alien_spitter::find_spitter_attack_node( self.enemy ); var_3 = 0; if ( isdefined( var_2 ) ) { maps\mp\agents\alien\_alien_spitter::move_to_spitter_attack_node( var_2 ); var_4 = get_seeder_val( "min_desired" ); var_5 = get_seeder_val( "max_desired" ); var_6 = level.seeder_active_turrets.size - level.seeder_active_pet_turrets; if ( var_6 < var_4 ) var_3 = 1; else if ( var_6 >= var_4 && var_6 < var_5 ) { if ( common_scripts\utility::cointoss() ) var_3 = 1; } if ( self.total_turrets_spawned >= get_seeder_val( "ammo" ) ) var_3 = 0; if ( var_3 ) seeder_attack( self.enemy ); else maps\mp\agents\alien\_alien_spitter::spitter_attack( self.enemy ); } else wait 0.05; var_1 = var_2; } } seeder_attack( var_0 ) { self endon( "spitter_node_move_requested" ); if ( !isdefined( self.current_spit_node ) ) { maps\mp\agents\alien\_alien_spitter::choose_spit_type( "close_range" ); maps\mp\agents\alien\_alien_spitter::spit_projectile( var_0 ); self.valid_moving_spit_attack_time = gettime() + randomfloatrange( 1.5, 2.5 ) * 1000.0; return; } if ( !maps\mp\agents\alien\_alien_spitter::is_escape_sequence_active() ) wait( randomfloatrange( 1.5, 2.5 ) * 0.5 ); for (;;) { var_1 = undefined; var_2 = 0.0; var_3 = get_seeder_val( "max_per_alien" ); while ( !isdefined( var_1 ) ) { var_2 = var_2 + 0.2; if ( var_2 >= 1.0 ) return; wait 0.2; if ( level.seeder_active_turrets.size + 1 > 12 || isdefined( self.num_active_turrets ) && self.num_active_turrets + 1 > var_3 ) continue; if ( self.total_turrets_spawned >= get_seeder_val( "ammo" ) ) return; var_1 = get_best_turret_location( var_0 ); if ( isdefined( var_1 ) ) break; } self.spit_type = "long_range"; self.spit_target_location = var_1; self.melee_type = "seeder_spit"; maps\mp\agents\alien\_alien_think::alien_melee( var_0 ); wait( randomfloatrange( 1.5, 2.5 ) ); } } match_node_orientation( var_0 ) { var_1 = anglestoup( var_0.angles ); var_2 = anglestoforward( self.angles ); var_3 = vectorcross( var_1, var_2 ); var_2 = vectorcross( var_3, var_1 ); var_4 = ( 0, 0, 0 ) - var_3; var_5 = axistoangles( var_2, var_4, var_1 ); self scragentsetorientmode( "face angle abs", var_5 ); for ( var_6 = 0; var_6 < 10; var_6++ ) { if ( abs( angleclamp180( self.angles[0] - var_5[0] ) ) < 2 && abs( angleclamp180( self.angles[2] - var_5[2] ) ) < 2 ) break; wait 0.05; } } seeder_spit_attack( var_0 ) { self endon( "melee_pain_interrupt" ); var_1 = var_0; var_1 endon( "death" ); var_2 = self.spit_target_location; if ( isdefined( self.current_spit_node ) ) match_node_orientation( self.current_spit_node ); turntowardsorigin( var_2 ); self.looktarget = var_1; maps\mp\alien\_utility::set_alien_emissive( 0.2, 1.0 ); if ( isdefined( self.current_spit_node ) && !maps\mp\alien\_utility::is_normal_upright( anglestoup( self.current_spit_node.angles ) ) ) { var_3 = anglestoup( self.current_spit_node.angles ); var_4 = anglestoforward( self.angles ); var_5 = vectorcross( var_3, var_4 ); var_4 = vectorcross( var_5, var_3 ); var_6 = ( 0, 0, 0 ) - var_5; var_7 = axistoangles( var_4, var_6, var_3 ); } else { var_4 = vectornormalize( var_2 - self.origin ); if ( isdefined( self.current_spit_node ) ) var_3 = anglestoup( self.current_spit_node.angles ); else var_3 = anglestoup( self.angles ); var_5 = vectorcross( var_3, var_4 ); var_4 = vectorcross( var_5, var_3 ); var_6 = ( 0, 0, 0 ) - var_5; var_7 = axistoangles( var_4, var_6, var_3 ); } self scragentsetorientmode( "face angle abs", var_7 ); self.spit_type = "long_range"; if ( self.oriented ) self scragentsetanimmode( "anim angle delta" ); else self scragentsetanimmode( "anim deltas" ); if ( common_scripts\utility::cointoss() ) maps\mp\agents\_scriptedagents::playanimuntilnotetrack( "close_spit_attack", "spit_attack", "end", ::handleattacknotetracks ); else maps\mp\agents\_scriptedagents::playanimuntilnotetrack( "turret_spit_attack", "spit_attack", "end", ::handleattacknotetracks ); maps\mp\alien\_utility::set_alien_emissive_default( 0.2 ); self.looktarget = undefined; self.spit_type = undefined; } handleattacknotetracks( var_0, var_1, var_2, var_3 ) { if ( var_0 == "spit" ) return fire_seeder_projectile(); } fire_seeder_projectile() { if ( !isdefined( self.spit_target_location ) ) return; var_0 = self.spit_target_location; var_1 = self gettagorigin( "TAG_BREATH" ); var_2 = magicbullet( "seeder_spit_mp", var_1, var_0, self ); var_2.parent = self; if ( isdefined( var_2 ) ) var_2 thread seeder_projectile_impact_monitor( self ); } seeder_projectile_impact_monitor( var_0 ) { self waittill( "explode", var_1 ); if ( !isdefined( var_1 ) ) return; if ( !isdefined( var_0 ) ) return; if ( isdefined( self.spit_target_location ) ) var_1 = self.spit_target_location; if ( isalive( var_0 ) ) thread seeder_spawn_turret( var_0, var_1, var_0.pet, 0 ); } get_best_turret_location( var_0 ) { if ( !isdefined( var_0 ) || !isdefined( var_0.origin ) ) return undefined; var_1 = get_best_seeder_node( var_0.origin, 0, 0, 1, self gettagorigin( "TAG_BREATH" ) ); if ( !isdefined( var_1 ) ) return undefined; if ( !turret_capsule_trace_passed( var_1 ) ) { var_1.bad_turret_spot = 1; return undefined; } self.spit_target_node = var_1; self.spit_target_location = var_1.origin; if ( !isdefined( var_1 ) || !isdefined( var_1.origin ) ) return undefined; return var_1.origin; } get_best_seeder_node( var_0, var_1, var_2, var_3, var_4 ) { var_5 = 64; var_6 = 512; var_7 = 512; if ( isdefined( var_1 ) && var_1 ) { var_5 = 0; var_6 = 96; var_7 = 96; } var_8 = getnodesinradius( var_0, var_6, var_5, var_7, "jump attack" ); var_9 = getnodesinradius( var_0, var_6, var_5, var_7, "path" ); var_8 = common_scripts\utility::array_combine( var_8, var_9 ); var_10 = []; foreach ( var_12 in var_8 ) { if ( !isdefined( var_12 ) || isdefined( var_12.claimed ) && var_12.claimed == 1 ) continue; if ( var_10.size > 1 && var_12.type == "Path" && randomint( 100 ) < 90 ) continue; if ( isdefined( var_2 ) && var_2 ) { var_13 = anglestoup( var_12.angles ); var_14 = ( 0, 0, 1 ); if ( vectordot( var_13, var_14 ) < 0.3 ) continue; } if ( isdefined( var_3 ) && var_3 ) { var_15 = bullettrace( var_4, var_12.origin, 1 ); if ( !isdefined( var_15 ) || distancesquared( var_15["position"], var_12.origin ) > 64 ) continue; } var_10[var_10.size] = var_12; } if ( var_10.size == 0 ) return undefined; return common_scripts\utility::random( var_10 ); } turntowardsorigin( var_0 ) { var_1 = var_0 - self.origin; return maps\mp\agents\alien\_alien_anim_utils::turntowardsvector( var_1 ); } seeder_explode_on_death( var_0 ) { var_1 = var_0.origin; common_scripts\utility::waitframe(); playfx( level._effect["alien_seeder_explode"], var_1 + ( 0, 0, 32 ) ); playsoundatpos( var_1, "alien_minion_explode" ); radiusdamage( var_1, 150, level.alien_types["minion"].attributes["explode_max_damage"], level.alien_types["minion"].attributes["explode_min_damage"], var_0, "MOD_EXPLOSIVE", "alien_minion_explosion" ); } seeder_spawn_turret( var_0, var_1, var_2, var_3 ) { if ( isdefined( var_0.spit_target_node ) ) var_4 = var_0.spit_target_node; else var_4 = get_best_seeder_node( var_1, 1, var_3 ); if ( isdefined( var_2 ) ) var_1 = common_scripts\utility::drop_to_ground( var_1, 5, -1000 ); if ( turret_spawn_failed( var_0, var_1, var_2, var_4 ) ) return; if ( isdefined( var_2 ) && isdefined( self.force_use_attacknode ) && isdefined( var_4 ) ) var_1 = var_4.origin; var_5 = spawn( "script_model", var_1 ); var_5 setmodel( "alien_spore" ); var_5 solid(); var_5.parent = var_0; var_5.team = var_0.team; var_5.origin = var_1; var_5.alien_type = "seeder_spore"; var_5 thermaldrawenable(); if ( isdefined( var_4 ) ) { var_5.angles = var_4.angles; var_5.origin = var_4.origin; var_5.claimed_node = var_4; var_5.claimed_node.claimed = 1; } else var_5.angles = ( 0, 0, 0 ); if ( isdefined( var_2 ) && var_2 ) { var_5.pet = 1; maps\mp\alien\_outline_proto::enable_outline( var_5, 3, 1 ); } level.seeder_active_turrets = common_scripts\utility::array_add( level.seeder_active_turrets, var_5 ); if ( isdefined( var_5.pet ) ) level.seeder_active_pet_turrets = level.seeder_active_pet_turrets + 1; if ( isdefined( var_0.alien_type ) ) { if ( !isdefined( var_0.total_turrets_spawned ) ) var_0.total_turrets_spawned = 0; var_0.total_turrets_spawned = var_0.total_turrets_spawned + 1; if ( !isdefined( var_0.num_active_turrets ) ) var_0.num_active_turrets = 0; var_0.num_active_turrets = var_0.num_active_turrets + 1; } var_5 thread seeder_turret_anim_state_machine(); var_5 thread seeder_turret_face_target(); var_5 thread seeder_turret_spit_attack(); var_5 thread seeder_turret_timeout(); var_5 thread seeder_turret_cleanup(); var_5 notify( "play_anim_spawn" ); wait 0.05; if ( !isdefined( var_5 ) ) return; var_5.coll_model = spawn( "script_model", var_1 ); var_5.coll_model setmodel( "alien_spore_hitbox" ); var_5.coll_model.origin = var_5 gettagorigin( "J_Spore_hitbox" ); var_5.coll_model.angles = var_5.angles; var_5.coll_model.parent = var_5; var_5.coll_model.team = var_5.team; var_5.coll_model linkto( var_5, "J_Spore_hitbox" ); var_5.coll_model setcandamage( 1 ); var_5.coll_model setcanradiusdamage( 1 ); var_5.coll_model.alien_type = "seeder_spore"; var_5.coll_model thread seeder_turret_damage_watcher(); wait 0.05; if ( isdefined( var_5 ) ) playsoundatpos( var_5.origin, "spore_spawn" ); } turret_spawn_failed( var_0, var_1, var_2, var_3 ) { self endon( "death" ); if ( !isdefined( var_2 ) && level.seeder_active_turrets.size > 12 ) return 1; var_4 = get_seeder_val( "max_per_alien" ); if ( !isdefined( var_2 ) && !isdefined( var_0.num_active_turrets ) && ( isdefined( var_0.num_active_turrets ) && var_0.num_active_turrets > var_4 ) ) return 1; if ( !isdefined( self ) ) return 1; var_5 = maps\mp\alien\_utility::get_closest_living_player(); if ( distancesquared( var_5.origin, var_1 ) > 1440000 ) return 1; if ( !check_is_turret_pos_clear( var_1 ) ) return 1; if ( !isdefined( var_2 ) && !isdefined( var_3 ) ) return 1; if ( isdefined( var_2 ) ) { if ( isplayer( var_0 ) && !capsuletracepassed( var_1 + ( 0, 0, 5 ), 20, 100, undefined, 1, 1 ) ) { if ( isdefined( var_3 ) && var_0 turret_capsule_trace_passed( var_3 ) ) self.force_use_attacknode = 1; else return 1; } if ( level.seeder_active_turrets.size >= 12 ) { var_6 = common_scripts\utility::random( level.seeder_active_turrets ); var_6 notify( "death" ); } if ( level.seeder_active_pet_turrets >= 5 ) { for ( var_7 = 0; !isdefined( level.seeder_active_turrets[var_7].pet ) && var_7 < 12; var_7 = var_7 + 1 ) { } level.seeder_active_turrets[var_7] notify( "death" ); } } else if ( !var_0 turret_capsule_trace_passed( var_3 ) ) return 1; return 0; } turret_capsule_trace_passed( var_0 ) { var_1 = anglestoup( var_0.angles ); var_2 = var_0.origin + var_1 * 50; var_3 = var_0.origin + var_1 * 100; var_4 = self aiphysicstracepassed( var_2, var_3, 10, 20, 0 ); if ( !var_4 ) return 0; return 1; } seeder_turret_anim_state_machine() { self.idle = "alien_seeder_spore_idle_a_dlc"; var_0 = undefined; self.current_anim = "none"; for (;;) { var_0 = common_scripts\utility::waittill_any_return( "play_anim_spawn", "play_anim_idle", "play_anim_attack", "play_anim_attack_up", "play_anim_pain", "play_anim_death" ); if ( !isdefined( var_0 ) ) continue; switch ( var_0 ) { case "play_anim_spawn": self.current_anim = var_0; thread seeder_play_interruptible_anim_and_wait( "alien_seeder_spore_growth_dlc", 2.86, 1 ); var_1 = self gettagorigin( "TAG_origin" ); var_2 = anglestoforward( self.angles ); var_3 = anglestoup( self.angles ); playfx( level._effect["spore_birth_fx"], var_1, var_2, var_3 ); break; case "play_anim_idle": if ( self.current_anim == "none" ) { self.current_anim = var_0; thread seeder_play_interruptible_anim_and_wait( self.idle, 2.86, 0, 1 ); } else { } break; case "play_anim_attack_up": case "play_anim_attack": self playsound( "scn_spore_attack" ); if ( self.current_anim == "none" || self.current_anim == "play_anim_idle" || self.current_anim == "play_anim_pain" ) { self.current_anim = var_0; if ( var_0 == "play_anim_attack_up" ) thread seeder_play_interruptible_anim_and_wait( "alien_seeder_spore_attack_up_dlc", 2.0, 1 ); else thread seeder_play_interruptible_anim_and_wait( "alien_seeder_spore_attack_dlc", 2.63, 1 ); } else { } break; case "play_anim_pain": if ( self.current_anim == "none" || self.current_anim == "play_anim_idle" || self.current_anim == "play_anim_pain" ) { self.current_anim = var_0; thread seeder_play_interruptible_anim_and_wait( "alien_seeder_spore_pain_dlc", 0.73, 0 ); } else { } break; case "play_anim_death": self notify( "seeder_stop_anims" ); wait 0.1; var_1 = self gettagorigin( "TAG_origin" ); var_2 = anglestoforward( self.angles ); var_3 = anglestoup( self.angles ); playfx( level._effect["spore_death_fx"], var_1, var_2, var_3 ); self notify( "do_after_death_cleanup" ); return; default: break; } } } seeder_play_interruptible_anim_and_wait( var_0, var_1, var_2, var_3 ) { self endon( "death" ); self endon( "seeder_stop_anims" ); self scriptmodelclearanim(); if ( var_2 ) self scriptmodelplayanimdeltamotion( var_0 ); else self scriptmodelplayanim( var_0 ); wait( var_1 ); if ( !isdefined( self ) ) return; if ( !isdefined( var_3 ) || var_3 == 0 ) { self.current_anim = "none"; self notify( "play_anim_idle" ); self.can_rotate = 1; } } seeder_turret_damage_watcher() { self.parent endon( "death" ); self setcandamage( 1 ); self.spore_maxhealth = get_seeder_val( "health" ); self.spore_health = self.spore_maxhealth; self.health = 10000; thread seeder_turret_death_watcher(); for (;;) { self waittill( "damage", var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ); maps\mp\alien\_chaos::process_chaos_event( "refill_combo_meter" ); var_10 = var_1; var_11 = "none"; var_12 = 0; var_0 = onaliensporedamaged( var_10, var_1, var_0, var_8, var_4, var_9, var_3, var_2, var_11, var_12 ); if ( isdefined( var_9 ) && weaponclass( var_9 ) == "spread" ) var_0 = var_0 * 4.0; self.spore_health = self.spore_health - var_0; if ( self.spore_health <= 0 ) { if ( isdefined( var_1 ) && isdefined( var_1.owner ) && isplayer( var_1.owner ) ) var_1 = var_1.owner; if ( maps\mp\alien\_utility::is_chaos_mode() ) maps\mp\alien\_chaos::update_alien_killed_event( maps\mp\alien\_utility::get_alien_type(), self.origin, var_1 ); if ( isdefined( var_1 ) && isplayer( var_1 ) ) { var_13 = 25; maps\mp\alien\_gamescore::givekillreward( var_1, var_13, undefined, var_11 ); maps\mp\alien\_achievement::update_alien_kill_achievements( var_10, var_1, var_0, var_4, var_9, var_2, var_11 ); } return; } self.parent notify( "play_anim_pain" ); } } seeder_turret_death_watcher() { self endon( "death" ); self.parent endon( "death" ); wait 0.1; for (;;) { if ( !isdefined( self ) || !isdefined( self.parent ) || !isdefined( self.spore_health ) ) return; if ( self.spore_health <= 0 ) { self.parent notify( "death" ); return; } wait 0.2; } } onaliensporedamaged( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ) { if ( isdefined( var_5 ) && ( var_5 == "alienspit_mp" || var_5 == "alienspit_gas_mp" ) ) var_2 = int( var_2 * 5 ); if ( isdefined( var_1 ) && isdefined( self.parent.pet ) && isdefined( var_1.team ) && self.parent.team == var_1.team ) return 0; var_2 = maps\mp\alien\_damage::set_alien_damage_by_weapon_type( var_4, var_5, var_2, var_1 ); if ( isplayer( var_1 ) && !maps\mp\alien\_utility::is_trap( var_0 ) ) { var_2 = maps\mp\alien\_damage::scale_alien_damage_by_perks( var_1, var_2, var_4, var_5 ); var_2 = maps\mp\alien\_damage::scale_alien_damage_by_weapon_type( var_1, var_2, var_4, var_5, var_8 ); } if ( var_2 <= 0 ) return 0; if ( isdefined( var_1 ) && var_1 != self && var_2 > 0 ) { if ( isdefined( level.attack_heli ) && var_1 == level.attack_heli ) var_2 = int( var_2 * 0.6 ); } var_2 = maps\mp\alien\_damage::scale_alien_damage_by_prestige( var_1, var_2 ); if ( isdefined( var_1 ) && isdefined( var_5 ) ) level thread maps\mp\alien\_challenge_function::update_alien_damage_challenge( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9, self ); var_1 thread maps\mp\gametypes\_damagefeedback::updatedamagefeedback( "standard" ); return var_2; } seeder_turret_spit_attack() { self endon( "death" ); var_0 = turret_get_new_target(); wait 5.86; if ( isdefined( self.pet ) ) var_1 = "spore_pet_beam_mp"; else var_1 = "spore_beam_mp"; for (;;) { if ( common_scripts\utility::cointoss() || !isdefined( var_0 ) ) var_0 = turret_get_new_target(); if ( !isdefined( var_0 ) ) { wait 2.0; continue; } self.can_rotate = 0; if ( self.is_rotating ) { wait 0.5; continue; } if ( ( isplayer( var_0 ) || issentient( var_0 ) ) && !var_0 maps\mp\_utility::isusingremote() ) var_2 = var_0 geteye() + ( 0, 0, -15 ); else if ( isdefined( var_0.alien_type ) && var_0.alien_type == "seeder_spore" ) var_2 = var_0 gettagorigin( "J_Spore_46" ); else var_2 = var_0.origin + ( 0, 0, 32 ); var_3 = self gettagorigin( "J_Spore_46" ); var_4 = "play_anim_attack"; if ( target_is_above_turret( var_2 ) ) var_4 = "play_anim_attack_up"; self notify( var_4 ); wait 0.84; var_5 = 3; while ( var_5 > 0 ) { if ( !isdefined( self ) || !isdefined( self.coll_model ) || !isdefined( var_0 ) || isdefined( self.current_anim ) && self.current_anim == "play_anim_death" || isdefined( self.coll_model.spore_health ) && self.coll_model.spore_health <= 0 ) { if ( isdefined( self ) && isdefined( self.fxent ) ) self.fxent delete(); return; } if ( ( isplayer( var_0 ) || issentient( var_0 ) ) && !var_0 maps\mp\_utility::isusingremote() ) var_2 = var_0 geteye() + ( 0, 0, -15 ); else if ( isdefined( var_0.alien_type ) && var_0.alien_type == "seeder_spore" ) var_2 = var_0 gettagorigin( "J_Spore_46" ); else var_2 = var_0.origin + ( 0, 0, 32 ); var_6 = var_2 - self gettagorigin( "J_Spore_46" ); var_6 = vectortoangles( var_6 ); if ( !isdefined( self.fxent ) ) self.fxent = spawnfx( level._effect["spore_darts_fire"], self gettagorigin( "J_Spore_46" ), anglestoforward( var_6 ), anglestoup( var_6 ) ); else { self.fxent.origin = self gettagorigin( "J_Spore_46" ); self.fxent.angles = var_6; } triggerfx( self.fxent ); common_scripts\utility::noself_delaycall( 0.2, ::magicbullet, var_1, self gettagorigin( "J_Spore_46" ), var_2, self.parent ); var_5 = var_5 - 1; wait 0.35; if ( isdefined( self ) && isdefined( self.fxent ) ) self.fxent delete(); } self.can_rotate = 1; if ( isdefined( self.pet ) ) { wait( randomfloatrange( 2.0, 5.0 ) ); continue; } wait( randomfloatrange( 2.5, 6.7 ) ); } } target_is_above_turret( var_0 ) { var_1 = self gettagorigin( "J_Spore_46" ); var_2 = vectornormalize( anglestoup( self.angles ) ); var_3 = vectornormalize( var_0 - var_1 ); var_4 = vectordot( var_2, var_3 ); if ( var_4 > 0.32 ) return 1; return 0; } rotatedartfx() { self endon( "death" ); self rotateyaw( -20, 1, 0.2, 0.1 ); wait 1; self rotateyaw( 40, 1, 0.2, 0.1 ); wait 1; self rotateyaw( -20, 1, 0.2, 0.1 ); } seeder_turret_cleanup() { self waittill( "death" ); level.seeder_active_turrets = common_scripts\utility::array_remove( level.seeder_active_turrets, self ); if ( isdefined( self.pet ) ) level.seeder_active_pet_turrets = level.seeder_active_pet_turrets - 1; if ( isdefined( self.parent ) && !isplayer( self.parent ) && isdefined( self.parent.num_active_turrets ) ) self.parent.num_active_turrets = self.parent.num_active_turrets - 1; if ( isdefined( self.coll_model ) ) self.coll_model delete(); if ( isdefined( self.fxent ) ) self.fxent delete(); self notify( "play_anim_death" ); self waittill( "do_after_death_cleanup" ); wait 0.4; if ( isdefined( self.claimed_node ) ) self.claimed_node.claimed = 0; self delete(); } seeder_turret_face_target() { self endon( "death" ); self.can_rotate = 0; self.is_rotating = 0; if ( isdefined( self.pet ) ) var_0 = 0.15; else var_0 = 0.45; var_1 = 1; wait 3.06; for (;;) { if ( !isdefined( self ) ) return; if ( !isdefined( self.enemy ) ) { wait 1.0; continue; } var_2 = self.enemy.origin - self.origin; var_3 = vectornormalize( projectvectortoplane( var_2, vectornormalize( anglestoup( self.angles ) ) ) ); var_4 = anglestoforward( self.angles ); var_5 = vectordot( var_3, var_4 ); if ( var_5 < 1 ) { var_6 = acos( var_5 ); var_7 = vectordot( vectorcross( var_3, var_4 ), vectornormalize( anglestoup( self.angles ) ) ); if ( var_7 > 0 ) var_6 = var_6 * -1; var_8 = var_0 / 0.05; var_9 = var_6 / var_8; if ( self.can_rotate && self.current_anim == "play_anim_idle" ) { for ( self.is_rotating = 1; var_8; var_8 = var_8 - 1 ) { if ( var_1 > 0 ) { self dontinterpolate(); var_1 = var_1 - 1; } self.angles = combineangles( self.angles, ( 0, var_9, 0 ) ); wait 0.05; } } } wait( var_0 ); self.is_rotating = 0; wait 0.2; wait 0.2; } } projectvectortoplane( var_0, var_1 ) { var_2 = vectordot( var_0, var_1 ); var_3 = var_0 - var_1 * var_2; return var_3; } turret_get_new_target() { self endon( "death" ); if ( !isdefined( self.pet ) ) { if ( isdefined( self.parent.favoriteenemy ) ) { self.enemy = self.parent.favoriteenemy; return self.parent.favoriteenemy; } if ( isdefined( self.favoriteenemy ) ) { self.enemy = self.favoriteenemy; return self.favoriteenemy; } var_0 = maps\mp\alien\_utility::get_closest_living_player(); self.enemy = var_0; return var_0; } else { var_1 = maps\mp\alien\_spawnlogic::get_alive_agents(); var_2 = 4; while ( var_1.size > 0 && var_2 > 0 ) { var_3 = common_scripts\utility::random( var_1 ); if ( isdefined( var_3 ) && !isdefined( var_3.pet ) ) { if ( isagent( var_3 ) && isalive( var_3 ) && bullettracepassed( self gettagorigin( "J_Spore_hitbox" ), var_3 gettagorigin( "TAG_EYE" ), 0, self ) ) { self.enemy = var_3; return var_3; } else if ( isdefined( var_3.alien_type ) && var_3.alien_type == "seeder_spore" && bullettracepassed( self gettagorigin( "J_Spore_hitbox" ), var_3 gettagorigin( "J_Spore_hitbox" ), 0, self ) ) { self.enemy = var_3; return var_3; } } var_2 = var_2 - 1; wait 0.1; } } } seeder_turret_timeout() { self endon( "death" ); var_0 = 60000; if ( isdefined( self.pet ) ) var_0 = 60000; var_1 = gettime(); for (;;) { if ( gettime() - var_1 > var_0 ) self notify( "death" ); wait 0.2; } } check_is_turret_pos_clear( var_0 ) { for ( var_1 = 0; var_1 < level.seeder_active_turrets.size; var_1++ ) { if ( var_1 >= 12 ) return 0; if ( isdefined( level.seeder_active_turrets[var_1] ) && distancesquared( var_0, level.seeder_active_turrets[var_1].origin ) < 1024 ) return 0; } return 1; } get_seeder_val( var_0 ) { if ( level.players.size == 1 ) { switch ( var_0 ) { case "health": return 275; case "max_per_alien": return 2; case "min_desired": return 1; case "max_desired": return 3; case "ammo": return 3; } } else if ( level.players.size == 2 ) { switch ( var_0 ) { case "health": return 350; case "max_per_alien": return 3; case "min_desired": return 2; case "max_desired": return 3; case "ammo": return 5; } } else if ( level.players.size == 3 ) { switch ( var_0 ) { case "health": return 500; case "max_per_alien": return 4; case "min_desired": return 2; case "max_desired": return 4; case "ammo": return 5; } } else if ( level.players.size == 4 ) { switch ( var_0 ) { case "health": return 500; case "max_per_alien": return 4; case "min_desired": return 2; case "max_desired": return 4; case "ammo": return 7; } } return 1; }