#include common_scripts\utility; #include maps\mp\_utility; #include maps\mp\gametypes\_hud_util; main() { thread main_thread(); } main_thread() { breach_precache(); waitframe(); breach = getstructarray("breach", "targetname"); array_thread(breach, ::breach_init); } breach_precache() { level.breach_icon_count = -1; level._effect["default"] = loadfx("fx/explosions/breach_room_cheap"); } breach_init() { if( getDvar( "r_reflectionProbeGenerate" ) == "1" ) return; if(!IsDefined(self.target)) return; self.breach_targets = []; self.auto_breach_gametypes = []; if(IsDefined(self.script_noteworthy)) { toks = StrTok(self.script_noteworthy, ","); foreach(tok in toks) { if(GetSubStr(tok,0,7) == "not_in_") { self.auto_breach_gametypes[self.auto_breach_gametypes.size] = GetSubStr(tok,7,tok.size); } if(tok == "only_if_allowClassChoice") { if(!allowClassChoice()) { self.auto_breach_gametypes[self.auto_breach_gametypes.size] = level.gameType; } } } } ents = GetEntArray(self.target, "targetname"); structs = getstructarray(self.target, "targetname"); targets = array_combine(ents, structs); nodes = self getLinknameNodes(); foreach (node in nodes) { node.isPathNode = true; } targets = array_combine(targets, nodes); foreach(target in targets) { if(!IsDefined(target.script_noteworthy)) { target.script_noteworthy = target.classname; } if(target.script_noteworthy == "trigger_use_touch") { target UseTriggerRequireLookAt(); target.script_noteworthy = "trigger_use"; } if(!IsDefined(target.isPathNode) || target.isPathNode == false) target.script_noteworthy = ToLower(target.script_noteworthy); types = StrTok(target.script_noteworthy, ", "); foreach(type in types) { event_name = undefined; toks = StrTok(type, "_"); if(toks.size>=3 && toks[toks.size-2] == "on") { event_name = toks[toks.size-1]; type = toks[0]; for(i=1;i=2 && toks[toks.size-1] == "useside") { useSide = true; type = toks[0]; for(i=1;i0) { return targets[0]; } else { return undefined; } } get_breach_targets(action, event_name, player) { targets = []; if(!IsDefined(event_name)) event_name = "activate"; if(!IsDefined(self.breach_targets[event_name])) return targets; if(!IsDefined(self.breach_targets[event_name][action])) return targets; foreach(s in self.breach_targets[event_name][action]) { if(IsDefined(s.facing_dir) && IsDefined(player)) { player_dir = player.origin - s.target.origin; if(!s.facing_angles3d) player_dir = (player_dir[0], player_dir[1], 0); player_dir = VectorNormalize(player_dir); dot = VectorDot(player_dir, s.facing_dir); if(dot 1 ) { sound_targets = SortByDistance( sound_targets, player.origin ); sound_ent = sound_targets[0]; } else if ( sound_targets.size > 0 ) { sound_ent = sound_targets[0]; } breaching_team = player.team; // need to store this in case the player switches teams between starting and finishing the breach if(IsDefined(sound_ent)) { for(i=0;i<3; i++) { sound_ent PlaySound("breach_beep"); wait .75; } if( IsDefined( sound_ent.script_parameters ) ) { params = StrTok( sound_ent.script_parameters, ";" ); foreach ( param in params ) { toks = StrTok( param, "=" ); if ( toks.size < 2 ) { continue; } switch( toks[ 0 ] ) { case "play_sound": switch( toks[ 1 ] ) { case "concrete": sound_ent PlaySound( "detpack_explo_concrete" ); break; case "wood": sound_ent PlaySound( "detpack_explo_wood" ); break; case "custom": if ( toks.size == 3 ) { sound_ent PlaySound( toks[2] ); } break; case "metal": case "undefined": default: sound_ent PlaySound( "detpack_explo_metal" ); break; } break; default: break; } } } else { sound_ent PlaySound( "detpack_explo_metal" ); } } self.parent notify( "breach_activated", player, undefined, breaching_team ); } breach_onEndUse( team, player, success ) { if( IsPlayer( player ) ) { player maps\mp\gametypes\_gameobjects::updateUIProgress( self, false ); } } breach_set_2dIcon( icon ) { self maps\mp\gametypes\_gameobjects::set2DIcon( "enemy" , icon ); self maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", icon ); } breach_warning_icon( useObject ) { icon_origin = useObject.curOrigin + ( 0, 0, 5 ); if ( useobject.parent get_breach_targets( "use_icon" ).size ) icon_origin = useobject.parent get_breach_targets( "use_icon" )[ 0 ].origin; useObject.parent thread breach_icon( "warning", icon_origin, undefined, "breach_activated" ); } breach_icon( type, origin, angles, end_ons ) { if ( level.createFX_enabled ) return; level.breach_icon_count++; icon_id = "breach_icon_" + level.breach_icon_count; breach_icon_update( type, origin, angles, icon_id, end_ons ); foreach ( player in level.players ) { if ( IsDefined( player.breach_icons ) && IsDefined( player.breach_icons[ icon_id ] ) ) { player.breach_icons[ icon_id ] thread breach_icon_fade_out(); } } } breach_icon_update( type, origin, angles, icon_id, end_ons ) { if ( IsDefined( end_ons ) ) { if ( IsString( end_ons ) ) end_ons = [ end_ons ]; foreach ( end_on in end_ons ) self endon( end_on ); } show_dist = 100; show_z = 70; icon = "hud_grenadeicon"; pin = true; switch( type ) { case "use": show_dist = 300; icon = "breach_icon"; pin = false; break; case "warning": show_dist = 400; damage_info = get_breach_target( "damage" ); if ( IsDefined( damage_info ) ) show_dist = damage_info.radius; icon = "hud_grenadeicon"; pin = true; break; default: break; } show_dir = undefined; if ( IsDefined( angles ) ) { show_dir = AnglesToForward( angles ); } while ( 1 ) { foreach ( player in level.players ) { if ( !IsDefined( player.breach_icons ) ) player.breach_icons = []; if ( breach_icon_update_is_player_in_range( player, origin, show_dist, show_dir, show_z ) ) { if ( !IsDefined( player.breach_icons[ icon_id ] ) ) { player.breach_icons[ icon_id ] = breach_icon_create( player, icon, origin, pin ); player.breach_icons[ icon_id ].alpha = 0; } player.breach_icons[ icon_id ] notify( "stop_fade" ); player.breach_icons[ icon_id ] thread breach_icon_fade_in(); } else { if ( IsDefined( player.breach_icons[ icon_id ] ) ) { player.breach_icons[ icon_id ] thread breach_icon_fade_out(); } } } wait 0.05; } } breach_icon_update_is_player_in_range( player, origin, show_dist, show_dir, show_z ) { test_origin = player.origin+(0,0,30); if(IsDefined(show_z) && abs(test_origin[2] - origin[2]) > show_z) return false; if(IsDefined(show_dist)) { show_dist_sqr = show_dist*show_dist; dist_sqr = DistanceSquared(test_origin, origin); if(dist_sqr>show_dist_sqr) return false; } if(IsDefined(show_dir)) { dir_to_player = test_origin - origin; //Normalize dir_to_player if not checking against zero. if(VectorDot(show_dir, dir_to_player)<0) return false; } return true; } breach_icon_create(player, icon, origin, pin) { icon = player createIcon( icon, 16, 16 ); icon setWayPoint( true, pin ); icon.x = origin[0]; icon.y = origin[1]; icon.z = origin[2]; return icon; } breach_icon_fade_in() { self endon("death"); if(self.alpha == 1) return; self FadeOverTime(.5); self.alpha = 1; } breach_icon_fade_out() { self endon("death"); self endon("stop_fade"); if(self.alpha == 0) return; time = .5; self FadeOverTime(time); self.alpha = 0; wait time; self Destroy(); }