See ALL Tutorials
DESCRIPTION
In the previous tutorial, I talked about starting your script in the yourmapname.gsc file, because it will be run when you map is run. However, we don't want to have to put everything we script inside that one .gsc file.Though it is personal preference, the only things I keep inside the yourmapname.gsc file are very small scripts that are map-specific. Everything else I have in a separate .gsc file.
CREATING A GSC FILE
The easiest way to create a .gsc file is to copy an existing one and rename it. Though we can have .gsc files in other directories than (Bo3Root\usermaps\yourmapname\scripts\zm) to keep things simple we'll stay inside that directory.Copy any .gsc there, such as yourmapname.gsc, and rename it to anything you like. In this example, I will call it my_external_script :

Next thing we will have to do is parse it in the yourmapname.zone. This will let launcher know that we'd like to use this file at some point when our map is run.
Let's open our yourmapname.zone (located in Bo3Root\usermaps\yourmapname\zone_source). It should look something like this:
>class,zm_mod_levelTo parse our script, we add the line:
>group,modtools
xmodel,skybox_default_day
material,luts_t7_default
// BSP
col_map,maps/zm/zm_yourmapname.d3dbsp
gfx_map,maps/zm/zm_yourmapname.d3dbsp
// Audio
sound,zm_yourmapname
scriptparsetree,scripts/zm/zm_yourmapname.gsc
scriptparsetree,scripts/zm/zm_yourmapname.csc
scriptparsetree,scripts/zm/my_external_script.gscto the bottom.
CALLING AN EXTERNAL FUNCTION
Now we have our script recognized by launcher, however this does not mean it will be run. We still need to call it from a script that will already be run, such yourmapname.gsc.Before we get to that however, let's give this script something to do. Delete everything inside the .gsc (you can select all with ctrl + a) so we can start from scratch.
Let's add another simple print function like in the last tutorial.
function my_cool_print_function()this can be it for our external script. Now let's find a way to call it.
{
IPrintLnBold("Your Mom looks like a Turtle");
}
Go back to yourmapname.gsc and back into the function main(). It should look something like this, after the last tutorial:
function main()Since we also want this function to be called after all players have connected, and then 10 seconds after that, we should call it below the wait(10); line.
{
zm_usermap::main();
level._zombie_custom_add_weapons =&custom_add_weapons;
//Setup the levels Zombie Zone Volumes
level.zones = ;
level.zone_manager_init_func =&usermap_test_zone_init;
init_zones[0] = "start_zone";
level thread zm_zonemgr::manage_zones( init_zones );
level.pathdist_type = PATHDIST_ORIGINAL;
level waittill("all_players_connected");
wait(10);
thread my_awesome_function();
}
function my_awesome_function()
{
IPrintLnBold("Hello Everybody");
}
the way you call an external function is basically the same as a normal function:
my_external_script::my_cool_print_function();notice:
- the name of the .gsc file is first
- followed by two colons ::
- followed by the name of the specific function within the .gsc file we want to call.
thread my_external_script::my_cool_print_function();So, let's show it all in place:
function main()
{
zm_usermap::main();
level._zombie_custom_add_weapons =&custom_add_weapons;
//Setup the levels Zombie Zone Volumes
level.zones = ;
level.zone_manager_init_func =&usermap_test_zone_init;
init_zones[0] = "start_zone";
level thread zm_zonemgr::manage_zones( init_zones );
level.pathdist_type = PATHDIST_ORIGINAL;
level waittill("all_players_connected");
wait(10);
thread my_awesome_function();
thread my_external_script::my_cool_print_function();
}
function my_awesome_function()
{
IPrintLnBold("Hello Everybody");
}
#USING A SCRIPT
This is almost complete, however if we try to link now, launcher will throw an error like this:********************************************************************************this is because anytime you call a function from an external .gsc file, you must include that file in the #using's at the stop of the script that's calling it.
UNRECOVERABLE ERROR:
^1SCRIPT ERROR: No generated data for 'scripts/zm/zm_yourmapname.gsc'
ERR(6E) scripts/zm/zm_yourmapname.gsc (93,0) : Compiler Internal Error : Unresolved external 'my_external_script::my_cool_print_function'
Linker will now terminate.
********************************************************************************
A #using looks like this:
#using scripts\zm\my_external_script;notice:
- the #using
- the filepath (automatically assumes we are starting from the folder Bo3Root\usermaps\yourmapname OR Bo3Root\Share\Raw)
- a #using does not include the .gsc at the end of the filename
- uses a ;
#using scripts\codescripts\struct;Now in-game you should notice both the print function inside yourmapname.gsc and the print function in the my_external_script.gsc being called, at pretty much the same exact time.
#using scripts\shared\array_shared;
#using scripts\shared\callbacks_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\compass;
#using scripts\shared\exploder_shared;
#using scripts\shared\flag_shared;
#using scripts\shared\laststand_shared;
#using scripts\shared\math_shared;
#using scripts\shared\scene_shared;
#using scripts\shared\util_shared;
#insert scripts\shared\shared.gsh;
#insert scripts\shared\version.gsh;
#insert scripts\zm\_zm_utility.gsh;
#using scripts\zm\_load;
#using scripts\zm\_zm;
#using scripts\zm\_zm_audio;
#using scripts\zm\_zm_powerups;
#using scripts\zm\_zm_utility;
#using scripts\zm\_zm_weapons;
#using scripts\zm\_zm_zonemgr;
#using scripts\shared\ai\zombie_utility;
//Perks
#using scripts\zm\_zm_pack_a_punch;
#using scripts\zm\_zm_pack_a_punch_util;
#using scripts\zm\_zm_perk_additionalprimaryweapon;
#using scripts\zm\_zm_perk_doubletap2;
#using scripts\zm\_zm_perk_deadshot;
#using scripts\zm\_zm_perk_juggernaut;
#using scripts\zm\_zm_perk_quick_revive;
#using scripts\zm\_zm_perk_sleight_of_hand;
#using scripts\zm\_zm_perk_staminup;
//Powerups
#using scripts\zm\_zm_powerup_double_points;
#using scripts\zm\_zm_powerup_carpenter;
#using scripts\zm\_zm_powerup_fire_sale;
#using scripts\zm\_zm_powerup_free_perk;
#using scripts\zm\_zm_powerup_full_ammo;
#using scripts\zm\_zm_powerup_insta_kill;
#using scripts\zm\_zm_powerup_nuke;
//#using scripts\zm\_zm_powerup_weapon_minigun;
//Traps
#using scripts\zm\_zm_trap_electric;
#using scripts\zm\zm_usermap;
#using scripts\zm\my_external_script;
//*****************************************************************************
// MAIN
//*****************************************************************************
function main()
{
zm_usermap::main();
level._zombie_custom_add_weapons =&custom_add_weapons;
//Setup the levels Zombie Zone Volumes
level.zones = ;
level.zone_manager_init_func =&usermap_test_zone_init;
init_zones[0] = "start_zone";
level thread zm_zonemgr::manage_zones( init_zones );
level.pathdist_type = PATHDIST_ORIGINAL;
level waittill("all_players_connected");
wait(10);
thread my_awesome_function();
thread my_external_script::my_cool_print_function();
}
function my_awesome_function()
{
IPrintLnBold("Hello Everybody");
}
function usermap_test_zone_init()
{
level flag::init( "always_on" );
level flag::set( "always_on" );
}
function custom_add_weapons()
{
zm_weapons::load_weapon_spec_from_table("gamedata/weapons/zm/zm_levelcommon_weapons.csv", 1);
}
#NAMESPACE'S
You may see in some scripts a #namespace. These basically designates a different name for the script than its actual filename. A #namespace goes in the preamble and looks like this:#namespace zombie_utility;it's as simple as putting #namespace followed by the name you want to give the script.
Note that:
- You can only use one #namespace per script. (that wouldn't make sense anyway)
- the #namespace only changes the name you use when calling the external function. When parsing the script in the mapname.zone or when putting the script as a #using, you must still use the actual filename.
- Treyarch uses these all the time
USING TREYARCH'S CODE
There are a lot of great things you can do with the list of [You are not allowed to view external links. Register or Login to see them] , however now that we know how to use external functions, we have access to so much more.Treyarch has tons of scripts that we can look through and use the functions of in (Bo3Root\share\raw\scripts). For example, one function that I like to use often for EE's and such is the spawn_zombie function, located in (Bo3Root\share\raw\scripts\shared\ai\zombie_utility.gsc)
This lets me spawn a zombie at a specific struct, and I can use it from any .gsc like this:
zom = zombie_utility::spawn_zombie( spawner, target_name, location, round_number );I just have to remember to have the #using for the script at the top of my script:
#using scripts\shared\ai\zombie_utility;and remember to make sure I'm calling the function by whatever #namespace Treyarch gave that script, not necessarily the filename (though in this case they are the same)
See ALL Tutorials