cod5-sdk/raw/maps/_audio.gsc
2009-04-10 00:00:00 +00:00

420 lines
No EOL
11 KiB
Text

#include maps\_utility;
#include common_scripts\utility;
/*/////////////////////////// _audio.gsc ///////////////////////////////////////////////
Functionality:
Line Emitters: Used to play a moving sound along a line.
Line emitters are set up by placing a trigger (either a brush or a
script_radius) in radiant. The trigger is then targeted at a script_stuct
which will make the start point. The script_struct will target another
script_struct which will make the end point. Emitter will begin once
trigger is hit. Multiple emitters can be targeted from one trigger.
KV Pairs: For the trigger:
targetname: Must be set to "sound_trigger" in order to work.
KV Pairs: For the first script_struct:
script_label: Must be set to "line_emitter" in order to work.
script_sound: The alias of the sound to play.
script_looping: Allows for looping sounds to be played. Sound must
be set to looping in the .CSV or the sound will
not play.
script_noteworthy: Only set if you plan on killing the line emitter.
Set this to a custom string, then pass that string
into stop_line_sound() to kill the emitter.
Static Sound Loopers: Used to play a looping sound from a trigger.
Static sound loopers are set up by placing a trigger (either a brush or a
script_radius) in radiant. The trigger is then targeted at a script_origin
which is where the sound will play. Multiple loopers can be targeted from
one trigger.
KV Pairs: For the trigger:
targetname: Must be set to "audio_sound_trigger" in order to work.
KV Pairs: On the script_origin:
script_label: Must be set to "looper" in order to work.
script_sound: The alias of the sound to play.
Static Sound Randoms: Used to play a sound at random intervals from a trigger.
Static sound randoms are set up by placing a trigger (either a brush or a
script_radius) in radiant. The trigger is then targeted at a script_origin
which is where the sound will play. Multiple randoms can be targeted from
one trigger.
KV Pairs: For the trigger:
targetname: Must be set to "sound_trigger" in order to work.
KV Pairs: On the script_origin:
script_label: Must be set to "random" in order to work.
script_sound: The alias of the sound to play.
script_wait_min: The minimum time to wait between plays
script_wait_max: The maximum time to wait between plays
Note: One trigger can be pointed at any or all combinations of loopers, line emitters
or randoms.
*///////////////////////////////////////////////////////////////////////////////////////
// This is called from _load.gsc, which grabs all the triggers and sets them up.
main()
{
array_thread( GetEntArray( "audio_sound_trigger", "targetname" ), ::thread_sound_trigger );
array_thread( GetEntArray( "audio_bump_trigger", "targetname"), :: thread_bump_trigger);
//array_thread( GetEntArray( "line_emitter", "targetname" ), ::thread_line_sound );
//array_thread( GetEntArray( "static_sound_looper", "targetname" ), ::thread_static_sound_looper );
//array_thread( GetEntArray( "static_sound_random", "targetname" ), ::thread_static_sound_random );
}
wait_until_first_player()
{
players = get_players();
if( !IsDefined( players[0] ) )
{
level waittill( "first_player_ready" );
}
}
thread_sound_trigger()
{
self waittill ("trigger");
struct_targs = getstructarray(self.target, "targetname");
ent_targs = getentarray(self.target,"targetname");
// structs should be line emitters for now
if (isdefined(struct_targs))
{
for (i = 0; i < struct_targs.size; i++)
{
// CODER_MOD
// Migrating line emitters to the client. DSL
if(!level.clientscripts)
{
if( !IsDefined( struct_targs[i].script_sound ) )
{
assertmsg( "_audio::thread_sound_trigger(): script_sound is UNDEFINED! Aborting..." + struct_targs[i].origin );
return;
}
struct_targs[i] thread spawn_line_sound(struct_targs[i].script_sound);
}
}
}
// ents are loopers and randoms
if (isdefined(ent_targs))
{
for (i = 0; i < ent_targs.size; i++)
{
if( !IsDefined( ent_targs[i].script_sound ) )
{
assertmsg( "_audio::thread_sound_trigger(): script_sound is UNDEFINED! Aborting... " + ent_targs[i].origin );
return;
}
if (isdefined(ent_targs[i].script_label) && ent_targs[i].script_label == "random")
{
// CODER_MOD
// Migrating randoms to the client. DSL
if(!level.clientscripts)
{
ent_targs[i] thread static_sound_random_play(ent_targs[i]);
}
}
else if (isdefined(ent_targs[i].script_label) && ent_targs[i].script_label == "looper")
{
// CODER_MOD
// Migrating loopers to the client. DSL
if(!level.clientscripts)
{
ent_targs[i] thread static_sound_loop_play(ent_targs[i]);
}
}
}
}
}
// self is the trigger
// grabs a SCRIPT_STRUCT (not script_origin) for the start and end points.
// spawns in a scipt_origin for the mover.
spawn_line_sound(sound)
{
startOfLine = self;
if( !IsDefined( startOfLine ) )
{
assertmsg( "_audio::spawn_line_sound(): Could not find start of line entity! Aborting..." );
return;
}
self.soundmover = [];
endOfLineEntity = getstruct( startOfLine.target, "targetname" );
if( isdefined( endOfLineEntity ) )
{
start = startOfLine.origin;
end = endOfLineEntity.origin;
soundMover = spawn("script_origin", start);
soundMover.script_sound = sound;
self.soundmover = soundMover;
if (isdefined (self.script_looping))
{
soundMover.script_looping = self.script_looping;
}
if( isdefined( soundMover ) )
{
soundMover.start = start;
soundMover.end = end;
soundMover line_sound_player();
soundMover thread move_sound_along_line();
}
else
{
assertmsg( "Unable to create line emitter script origin" );
}
}
else
{
assertmsg( "_audio::spawn_line_sound(): Could not find end of line entity! Aborting..." );
}
//}
}
// determine whether or not to loop
line_sound_player()
{
self endon ("end line sound");
if (isdefined (self.script_looping))
{
self playloopsound(self.script_sound);
}
else
{
self playsound (self.script_sound);
}
}
// self is the script origin mover
// moves the sound along the line
move_sound_along_line()
{
self endon ("end line sound");
wait_until_first_player();
closest_dist = undefined;
while(1)
{
self closest_point_on_line_to_point( get_players()[0].origin, self.start, self.end);
/#
if( getdvarint( "debug_audio" ) > 0 )
{
line( self.start, self.end, (0,1,0));
print3d (self.start, "START", (1.0, 0.8, 0.5), 1, 3);
print3d (self.end, "END", (1.0, 0.8, 0.5), 1, 3);
print3d (self.origin, self.script_sound, (1.0, 0.8, 0.5), 1, 3);
}
#/
//Update the sound based on distance to the point
closest_dist = DistanceSquared( get_players()[0].origin, self.origin );
if( closest_dist > 1024 * 1024 )
{
wait( 2 );
}
else if( closest_dist > 512 * 512 )
{
wait( 0.2);
}
else
{
wait( 0.05);
}
}
}
// self is the script origin mover
// the crazy math Alex C wrote on COD3, convered to GSC for COD5
closest_point_on_line_to_point( Point, LineStart, LineEnd )
{
self endon ("end line sound");
LineMagSqrd = lengthsquared(LineEnd - LineStart);
t = ( ( ( Point[0] - LineStart[0] ) * ( LineEnd[0] - LineStart[0] ) ) +
( ( Point[1] - LineStart[1] ) * ( LineEnd[1] - LineStart[1] ) ) +
( ( Point[2] - LineStart[2] ) * ( LineEnd[2] - LineStart[2] ) ) ) /
( LineMagSqrd );
if( t < 0.0 )
{
self.origin = LineStart;
}
else if( t > 1.0 )
{
self.origin = LineEnd;
}
else
{
start_x = LineStart[0] + t * ( LineEnd[0] - LineStart[0] );
start_y = LineStart[1] + t * ( LineEnd[1] - LineStart[1] );
start_z = LineStart[2] + t * ( LineEnd[2] - LineStart[2] );
self.origin = (start_x,start_y,start_z);
}
}
// Stops called in script manually for now.
stop_line_sound(startOfLineEntity)
{
startpoints = getstructarray(startOfLineEntity, "script_noteworthy");
for (i = 0; i < startpoints.size; i++)
{
if( !IsDefined( startpoints[i].soundmover ) )
{
println ("Line emitter wasn't spawned before delete call... are you sure this isn't messed up?");
return;
}
// this should stop all the associated threads
startpoints[i].soundmover notify ("end line sound");
// delete the entities, cleanup time
startpoints[i].soundmover delete();
}
}
// self is the trigger
// logic for playing the sound at random intervals
static_sound_random_play(soundpoint)
{
// what is this for?
wait(RandomIntRange(1, 5));
if (!isdefined (self.script_wait_min))
{
self.script_wait_min = 1;
}
if (!isdefined (self.script_wait_max))
{
self.script_wait_max = 3;
}
while(1)
{
wait( RandomFloatRange( self.script_wait_min, self.script_wait_max ) );
soundpoint playsound(self.script_sound);
/#
if( getdvarint( "debug_audio" ) > 0 )
{
print3d (soundpoint.origin, self.script_sound, (1.0, 0.8, 0.5), 1, 3, 5);
}
#/
}
}
// self is the trigger
// logic for playing the sound on a loop, looping sound must be set to looping in the CSV
static_sound_loop_play(soundpoint)
{
self playloopsound(self.script_sound);
/#
if( getdvarint( "debug_audio" ) > 0 )
{
while(1)
{
print3d (soundpoint.origin, self.script_sound, (1.0, 0.8, 0.5), 1, 3, 5);
wait (1);
}
}
#/
}
thread_bump_trigger()
{
// iprintlnbold("found_a_bump_trig");
self thread bump_trigger_listener();
if(!IsDefined(self.script_activated)) //Sets a flag to turn the trigger on or off
{
self.script_activated = 1;
}
while(1)
{
self waittill("trigger", who);
// iprintlnbold("Triggered:");
//Store sound to play in script_sound/ alias name
if(IsDefined (self.script_sound) && self.script_activated)
{
self playsound (self.script_sound);
//iprintlnbold(self.script_sound);
}
while(IsDefined (who) && (who) IsTouching (self))
{
wait(0.1);
}
}
}
disable_bump_trigger(triggername)
{
triggers = GetEntArray( "audio_bump_trigger", "targetname");
if(IsDefined (triggers))
{
for(i=0;i<triggers.size;i++)
{
if (IsDefined (triggers[i].script_label) && triggers[i].script_label == triggername)
{
triggers[i].script_activated =0;
}
}
}
}
bump_trigger_listener() //This will deactivate the trigger on a level notify if its stored on the trigger
{
//Store End-On conditions in script_label so you can turn off the bump trigger if a condition is met
if(IsDefined (self.script_label))
{
level waittill(self.script_label);
self.script_activated =0;
}
}
get_player_index_number(player)
{
players = get_players();
for(i=0; i<players.size; i++)
{
if (players[i] == player)
{
return i;
}
}
return 1;
}
//targs = getarray("blah","targetname");
//
//for (i = 0; i < targs; i++)
//{
// targs[i] thread static_sound_loop_play(targs[i])
//}