Call of Duty 5: FXs Script Struct
This tutorial describe an alternative method to spawn FXs in a map using Radiant and a few scripts.
The example below will show you how to spawn 3 FXs in your map:
env/smoke/fx_smoke_crater env/fire/fx_fire_barrel_small env/fire/fx_fire_barrel_pm
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"; game["strings"]["war_callsign_a"] = &"MP_RIPAC_CALLSIGN_LOCATION_A"; game["strings"]["war_callsign_b"] = &"MP_RIPAC_CALLSIGN_LOCATION_B"; game["strings"]["war_callsign_c"] = &"MP_RIPAC_CALLSIGN_LOCATION_C"; game["strings"]["war_callsign_d"] = &"MP_RIPAC_CALLSIGN_LOCATION_D"; game["strings"]["war_callsign_e"] = &"MP_RIPAC_CALLSIGN_LOCATION_E"; game["strings_menu"]["war_callsign_a"] = "@RIPAC_CALLSIGN_LOCATION_A"; game["strings_menu"]["war_callsign_b"] = "@RIPAC_CALLSIGN_LOCATION_B"; game["strings_menu"]["war_callsign_c"] = "@RIPAC_CALLSIGN_LOCATION_C"; game["strings_menu"]["war_callsign_d"] = "@RIPAC_CALLSIGN_LOCATION_D"; game["strings_menu"]["war_callsign_e"] = "@RIPAC_CALLSIGN_LOCATION_E"; setdvar( "r_specularcolorscale", "1" ); setdvar("compassmaxrange","1000"); // setExpFog(100, 1000, 0.4, 0.425, 0.44, 0.0); 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 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
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 _example_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
- 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