Call of Duty 5: FXs Script Struct
This tutorial describe an alternative method to spawn FXs and Sound in a map using Radiant and a few scripts. It is similar to the old struct method as done by zeroy. This version is by coldair, I have made a couple of additions so people can see how to specify non standard sounds. Have fun wakka.
Create the csc files (Client Side)
The example is based on coldairs ripac map files. You will need to change it to match your map name, please make sure you change any other referenced names within the files. these go in the raw/clientscripts/maps/mp folder
_ripac_struct.csc
// This script automaticly plays a users specified oneshot effect on all prefabs that have the
// specified "script_struct" and "targetname" It also excepts angles from the "script_struct"
// but will set a default angle of ( 0, 0, 0 ) if none is defined.
//
// example of the syntax:
// global_FX( "targetname", "fxIDname", "fxFile", "delay"
#include clientscripts\mp\_utility;
main()
{
//Assigning a random delay for start of FX
randomStartDelay = randomfloatrange( -20, -15);
//Each line describes a different FX
global_FX( "oil_fire_mdFX_origin", "global_fire", "env/fire/fx_fire_thick_smoke_md", randomStartDelay, "fire_thick_smoke_md" );
global_FX( "wood_chimney_smoke_medFX_origin", "global_smoke", "env/smoke/fx_smoke_wood_chimney_med", randomStartDelay, "smoke_wood_chimney_med" );
global_FX( "pollen_foliage_lgFX_origin", "global_foliage", "env/foliage/fx_pollen_lg", randomStartDelay, "pollen_lg" );
global_FX( "sand_blowing_dirt_lg_wFX_origin", "global_dirt", "env/dirt/fx_sand_blowing_lg_w", randomStartDelay, "sand_blowing_lg_w" );
global_FX( "wire_sparks_electrical_elecFX_origin", "global_electrical", "env/electrical/fx_elec_wire_sparks", randomStartDelay, "elec_wire_sparks" );
global_FX( "rainbow_weatherFX_origin", "global_weather", "env/weather/fx_rainbow", randomStartDelay, "rainbow" );
global_FX( "ray_sun_light_medFX_origin", "global_light", "env/light/fx_ray_sun_med", randomStartDelay, "ray_sun_med" );
}
global_FX( targetname, fxName, fxFile, delay, soundalias )
{
// script_structs
ents = getstructarray(targetname,"targetname");
if ( !isdefined( ents ) )
return;
if ( ents.size <= 0 )
return;
println("*** Client : _global_FX - creating " + ents.size + " globalFX " + fxName);
for ( i = 0 ; i < ents.size ; i++ )
{
ent = ents[i] global_FX_create( fxName, fxFile, delay, soundalias );
if ( !isdefined( ents[ i ].script_noteworthy ) )
continue;
note = ents[ i ].script_noteworthy;
if ( !isdefined( level._global_fx_ents[ note ] ) )
{
level._global_fx_ents[ note ] = [];
}
level._global_fx_ents[ note ][ level._global_fx_ents[ note ].size ] = ent;
}
}
global_FX_create( fxName, fxFile, delay, soundalias )
{
if ( !isdefined( level._effect ) )
level._effect = [];
if ( !isdefined( level._effect[ fxName ] ) )
level._effect[ fxName ] = loadedfx( fxFile );
// default effect angles if they dont exist
if ( !isdefined( self.angles ) )
self.angles = ( 0, 0, 0 );
ent = clientscripts\mp\_fx::createOneshotEffect( fxName );
ent.v[ "origin" ] = ( self.origin );
ent.v[ "angles" ] = ( self.angles );
ent.v[ "fxid" ] = fxName;
ent.v[ "delay" ] = delay;
if ( isdefined( soundalias ) )
{
ent.v[ "soundalias" ] = soundalias;
}
return ent;
}
mp_ripac.csc
// Test clientside script for mp_ripac
#include clientscripts\mp\_utility;
main()
{
// teams
level.allies_team = "marines";
level.axis_team = "german";
// _load!
clientscripts\mp\_load::main();
clientscripts\mp\_ripac_struct::main();
// For tanks Eexhaust and treads
clientscripts\mp\_panzeriv::main( "vehicle_ger_tracked_panzer4_mp" );
thread clientscripts\mp\_fx::fx_init(0);
thread clientscripts\mp\_audio::audio_init(0);
// thread clientscripts\mp\mp_ripac_amb::main();
// This needs to be called after all systems have been registered.
thread waitforclient(0);
println("*** Client : mp_ripac running...");
}
Create the GSC files (server side)
So as an Example, coldairs mp_ripac.gsc looks like this: You will need to change it to match your map name, please make sure you change any other referenced names within the files.
main()
{
maps\mp\_load::main();
maps\mp\_ripac_struct::main();
maps\mp\createart\mp_ripac_art::main();
maps\mp\_compass::setupMiniMap("compass_map_mp_ripac");
game["allies"] = "marines";
game["axis"] = "german";
game["attackers"] = "allies";
game["defenders"] = "axis";
game["allies_soldiertype"] = "pacific";
game["axis_soldiertype"] = "german";
//setdvar("compassmaxrange","1000");
maps\mp\gametypes\_spawning::level_use_unified_spawning(true);
}
- Save and exit
- Using Notepad create a new file under /raw/maps/mp/ called _ripac_struct.gsc, inside copy paste the following code:
#include common_scripts\utility;
#include maps\mp\_utility;
main()
{
//Assigning a random delay for start of FX
randomStartDelay = randomfloatrange( -20, -15);
//Each line describes a different FX
global_FX( "oil_fire_mdFX_origin", "global_fire", "env/fire/fx_fire_thick_smoke_md", randomStartDelay, "fire_thick_smoke_md" );
global_FX( "wood_chimney_smoke_medFX_origin", "global_smoke", "env/smoke/fx_smoke_wood_chimney_med", randomStartDelay, "smoke_wood_chimney_med" );
global_FX( "pollen_foliage_lgFX_origin", "global_foliage", "env/foliage/fx_pollen_lg", randomStartDelay, "pollen_lg" );
global_FX( "sand_blowing_dirt_lg_wFX_origin", "global_dirt", "env/dirt/fx_sand_blowing_lg_w", randomStartDelay, "sand_blowing_lg_w" );
global_FX( "wire_sparks_electrical_elecFX_origin", "global_electrical", "env/electrical/fx_elec_wire_sparks", randomStartDelay, "elec_wire_sparks" );
global_FX( "rainbow_weatherFX_origin", "global_weather", "env/weather/fx_rainbow", randomStartDelay, "rainbow" );
global_FX( "ray_sun_light_medFX_origin", "global_light", "env/light/fx_ray_sun_med", randomStartDelay, "ray_sun_med" );
}
global_FX( targetname, fxName, fxFile, delay, soundalias )
{
// get script_structs created in Radiant
ents = getstructarray(targetname,"targetname");
if ( !isdefined( ents ) )
return;
if ( ents.size <= 0 )
return;
for ( i = 0 ; i < ents.size ; i++ )
ents[i] global_FX_create( fxName, fxFile, delay, soundalias );
}
global_FX_create( fxName, fxFile, delay, soundalias )
{
if ( !isdefined( level._effect ) )
level._effect = [];
if ( !isdefined( level._effect[ fxName ] ) )
level._effect[ fxName ] = loadfx( fxFile );
// default effect angles if they dont exist
if ( !isdefined( self.angles ) )
self.angles = ( 0, 0, 0 );
ent = createOneshotEffect( fxName );
ent.v[ "origin" ] = ( self.origin );
ent.v[ "angles" ] = ( self.angles );
ent.v[ "fxid" ] = fxName;
ent.v[ "delay" ] = delay;
if ( isdefined( soundalias ) )
{
ent.v[ "soundalias" ] = soundalias;
}
}
- Save and Exit
- Finally add the FXs and the new files to your /zone_source/mp_yourmap.csv
// Specify the server and client side scripts
rawfile,maps/mp/mp_ripac.gsc
rawfile,maps/mp/_ripac_struct.gsc
rawfile,clientscripts/mp/mp_ripac.csc
rawfile,clientscripts/mp/_ripac_struct.csc
// Below are the Fxs, put the ones you use in, below is an example
fx,env/smoke/fx_smoke_crater
fx,env/fire/fx_fire_barrel_small
fx,env/fire/fx_fire_barrel_pm
If we look at this line found in both server and client side. "global_FX( "oil_fire_mdFX_origin", "global_fire", "env/fire/fx_fire_thick_smoke_md", randomStartDelay, "fire_thick_smoke_md" );"
We can see the fx it uses and also the sound, the sound listed is from stock and is the last section in "" after randomStartDelay.
We could specify a custom sound, this will mean you need a soundalias file.
To do this, create the sound alias file within /raw/soundaliases
mp_ripac.csv
name,sequence,file,platform,vol_min,vol_max,pitch_min,pitch_max,dist_min,dist_max,dist_reverb_max,limit_count,limit_type,entity_limit_count,entity_limit_type,bus,priority,spatialized,type,probability,loop,masterslave,loadspec,reverb_falloff_curve,subtitle,compression,randomize_type,secondaryaliasname,chainaliasname,volumefalloffcurve,startdelay,speakermap,reverb_send,lfe percentage,center percentage,platform,envelop_min,envelop_max,envelop percentage,occlusion_level,min_priority,max_priority,min_priority_threshold,max_priority_threshold
# Ambient SFX - Static,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
# all static global noises u want
customsoundone,,sfx/Levels/pby_fly/fleet/alarm/fires_and_screams.wav,!wii,0.4,0.8,0.9,1.1,50,300,500,,,,,ambience,60,3d,,0.65,,,,curve3,,,pitch,,,curve2,,,,,,,,,,0.2,30,50,0.1,1
We could then change or add a line to the client and serverside like so
"global_FX( "oil_fire_mdFX_origin", "global_fire", "env/fire/fx_fire_thick_smoke_md", randomStartDelay, "customsoundone" );"
The result would be some insane screaming when you go near the fx in question.
Finally we need to add the structs to the map
EDIT wakka. 11/02/2009 17:28
- If you wish only to have a sound and not fx Do this
"global_FX( "oil_fire_mdFX_origin", "global_fire", "", randomStartDelay, "customsoundone" );"
In Radiant
This method of spawning FXs uses script_struct entities, they are placed in your Level in Radiant
- In radiant, in the 2D view, Right-click and select script>script_struct
- Now move and place the Script_struct entity where you want your FX to show up
- With the Script_struct entity selected bring up its properties with n
- Now add the targetname for the FX required (as entered in the _ripac_struct,gsc file above)
Key:Targetname Value:depends on FX you wish
Possible Values in this Example:
barrel_fireFX_origin barrel_fireFX_small_origin barrel_smokeFX_origin oil_fire_mdFX_origin
- Another thing to do might be the Angle, if you need to orient your FXs.
Key: angles Value: Depends on the direction you want to the FX to show, for Fire (going upwards) it would be 180 0 0 ; For a Streetlight (pointing downwards) it would be 90 0 0