Advanced GSC tutorial - Pointer Function & Function Variables
Pointer Function The Pointer Function gives you the ability to execute a specific function without having to worry about duplicate functions or having to include some other script to use a specific function provided that the script path(if given) actually exists.
The Pointer Function primarily comes in two forms: A direct function call that ONLY executes a function in the same script OR an indirect function call that executes a function in another script not included in the library.
The first form specifically is only used when passing a function as a variable to another function like so:
default_start( ::event1_start );
Or alternatively put into a variable directly to execute later:
level.drone_spawnFunction["axis"] = ::drone_character_axis;
(More on executing variables that hold a function below)
The second form is the more popular use of the pointer function. As explained above this indirectly executes a function in another script - even if that function is named the same as one in the script you are calling it from(For examples, main() or init()):
maps\mak_fx::main();
Note: Passing variables, self, threading the function, etc all work the same as any other function call.
Pointer Variable Calling Executing function variables deals with the first form of pointer functions when a variable holds the function to be executed later or managed by another function.
In most cases(like 99% of the time) this isn't necessary as putting functions into variables just causes more code than is needed. However, in some situations it can actually reduce code usage and make your script MUCH more effeciant.
You can execute a variable that holds a function by doing so:
[[level.drone_spawnFunction["axis"]]]();
One of the ways in which I've personally used this method is with my "Soviet" mod which uses lots of variables that dictate how much weapons & perks cost, spawn delays, and a bunch of other things per gamemode when not necessary like so:
level.common_settings = :: common_settings; level.deathmatch_settings = ::deathmatch_settings; level.ctf_settings = ::ctf_settings; level.hotzone_settings = ::hotzone_settings; level.round_deathmatch_settings = ::round_deathmatch_settings; level.target_settings = ::target_settings;
common_settings() { // Only for perks ATM - pre _weapons and _perks scripts level.string[level.gamemode] = []; level.string[level.gamemode]["specialty_armorvest"] = "Press F to buy Juggernaut[Requires " + level.cost[level.gamemode]["specialty_armorvest"] + level.ctype + "]"; level.string[level.gamemode]["specialty_fastreload"] = "Press F to buy Speed Cola[Requires " + level.cost[level.gamemode]["specialty_fastreload"] + level.ctype + "]"; level.string[level.gamemode]["specialty_rof"] = "Press F to buy Double Tap[Requires " + level.cost[level.gamemode]["specialty_rof"] + level.ctype + "]"; level.shader["specialty_fastreload"] = "specialty_fastreload_zombies"; level.shader["specialty_rof"] = "specialty_doubletap_zombies"; } deathmatch_settings() { level.powerup["model"] = []; level.powerup["model"]["powerup_doublepoints"] = "zombie_x2_icon"; level.powerup["model"]["powerup_instakill"] = "zombie_skull"; // level.powerup["func"] = []; // level.powerup["func"]["powerup_doublepoints"] = maps\_soviet\_soviet_powerups:: // level.powerup["func"]["powerup_instakill"] level.cost["deathmatch"] = []; // DO NOT REMOVE level.cost["deathmatch"]["dp28"] = 168; level.cost["deathmatch"]["tokarev"] = 10; level.cost["deathmatch"]["walther"] = 10; level.cost["deathmatch"]["svt40"] = 20; level.cost["deathmatch"]["ppsh"] = 230; level.cost["deathmatch"]["panzerschrek"] = 30; level.cost["deathmatch"]["ptrs41"] = 35; level.cost["deathmatch"]["gewehr43"] = 25; level.cost["deathmatch"]["mg42"] = 200; level.cost["deathmatch"]["mp40"] = 55; level.cost["deathmatch"]["mosin_rifle"] = 65; level.cost["deathmatch"]["kar98k_scoped"] = 85; level.cost["deathmatch"]["doublebarrel"] = 45; level.cost["deathmatch"]["fg42"] = 100; level.cost["deathmatch"]["30cal"] = 160; level.cost["deathmatch"]["specialty_armorvest"] = 150; level.cost["deathmatch"]["specialty_fastreload"] = 110; level.cost["deathmatch"]["specialty_rof"] = 75; level.delay["deathmatch"] = []; // DO NOT REMOVE level.delay["deathmatch"]["bolt"] = 1.5; level.delay["deathmatch"]["rifle"] = 1.2; level.delay["deathmatch"]["smg"] = 1.6; level.delay["deathmatch"]["sniper"] = 2.3; level.delay["deathmatch"]["rocket"] = 3; level.delay["deathmatch"]["mg"] = 4; level.delay["deathmatch"]["dog"] = 3; } ctf_settings() { level.cost["ctf"] = []; // DO NOT REMOVE level.cost["ctf"]["dp28"] = 9; level.cost["ctf"]["tokarev"] = 1; level.cost["ctf"]["walther"] = 1; level.cost["ctf"]["svt40"] = 2; level.cost["ctf"]["ppsh"] = 14; level.cost["ctf"]["panzerschrek"] = 4; level.cost["ctf"]["ptrs41"] = 6; level.cost["ctf"]["gewehr43"] = 2; level.cost["ctf"]["mg42"] = 12; level.cost["ctf"]["mp40"] = 6; level.cost["ctf"]["mosin_rifle"] = 3; level.cost["ctf"]["kar98k_scoped"] = 7; level.cost["ctf"]["doublebarrel"] = 4; level.cost["ctf"]["fg42"] = 8; level.cost["ctf"]["30cal"] = 10; level.cost["ctf"]["specialty_armorvest"] = 15; level.cost["ctf"]["specialty_fastreload"] = 12; level.cost["ctf"]["specialty_rof"] = 8; level.delay["ctf"] = []; // DO NOT REMOVE level.delay["ctf"]["bolt"] = 1.5; level.delay["ctf"]["rifle"] = 1.2; level.delay["ctf"]["smg"] = 1.6; level.delay["ctf"]["sniper"] = 2.3; level.delay["ctf"]["rocket"] = 3; level.delay["ctf"]["mg"] = 4; level.delay["ctf"]["dog"] = 3; } hotzone_settings() { level.shader["obj_capture"] = "compass_waypoint_capture"; level.shader["obj_defend"] = "compass_waypoint_defend"; level.cost["hotzone"] = []; // DO NOT REMOVE level.cost["hotzone"]["dp28"] = 9; level.cost["hotzone"]["tokarev"] = 1; level.cost["hotzone"]["walther"] = 1; level.cost["hotzone"]["svt40"] = 2; level.cost["hotzone"]["ppsh"] = 14; level.cost["hotzone"]["panzerschrek"] = 4; level.cost["hotzone"]["ptrs41"] = 6; level.cost["hotzone"]["gewehr43"] = 2; level.cost["hotzone"]["mg42"] = 12; level.cost["hotzone"]["mp40"] = 6; level.cost["hotzone"]["mosin_rifle"] = 3; level.cost["hotzone"]["kar98k_scoped"] = 7; level.cost["hotzone"]["doublebarrel"] = 4; level.cost["hotzone"]["fg42"] = 8; level.cost["hotzone"]["30cal"] = 10; level.cost["hotzone"]["hotzone_count"] = 100; level.cost["hotzone"]["specialty_armorvest"] = 15; level.cost["hotzone"]["specialty_fastreload"] = 12; level.cost["hotzone"]["specialty_rof"] = 8; level.delay["hotzone"] = []; // DO NOT REMOVE level.delay["hotzone"]["bolt"] = 3; level.delay["hotzone"]["rifle"] = 2; level.delay["hotzone"]["smg"] = 3; level.delay["hotzone"]["sniper"] = 4; level.delay["hotzone"]["rocket"] = 6; level.delay["hotzone"]["mg"] = 7; level.delay["hotzone"]["dog"] = 6; } round_deathmatch_settings() { level.cost["round_deathmatch"] = []; // DO NOT REMOVE level.cost["round_deathmatch"]["dp28"] = 168; level.cost["round_deathmatch"]["tokarev"] = 10; level.cost["round_deathmatch"]["walther"] = 10; level.cost["round_deathmatch"]["svt40"] = 20; level.cost["round_deathmatch"]["ppsh"] = 230; level.cost["round_deathmatch"]["panzerschrek"] = 30; level.cost["round_deathmatch"]["ptrs41"] = 35; level.cost["round_deathmatch"]["gewehr43"] = 25; level.cost["round_deathmatch"]["mg42"] = 200; level.cost["round_deathmatch"]["mp40"] = 55; level.cost["round_deathmatch"]["mosin_rifle"] = 65; level.cost["round_deathmatch"]["kar98k_scoped"] = 85; level.cost["round_deathmatch"]["doublebarrel"] = 45; level.cost["round_deathmatch"]["fg42"] = 100; level.cost["round_deathmatch"]["30cal"] = 160; level.cost["round_deathmatch"]["specialty_armorvest"] = 150; level.cost["round_deathmatch"]["specialty_fastreload"] = 110; level.cost["round_deathmatch"]["specialty_rof"] = 75; level.delay["round_deathmatch"] = []; } target_settings() { level.cost["target_practice"] = []; // DO NOT REMOVE level.cost["target_practice"]["dp28"] = 9; level.cost["target_practice"]["tokarev"] = 1; level.cost["target_practice"]["walther"] = 1; level.cost["target_practice"]["svt40"] = 2; level.cost["target_practice"]["ppsh"] = 14; level.cost["target_practice"]["panzerschrek"] = 4; level.cost["target_practice"]["ptrs41"] = 6; level.cost["target_practice"]["gewehr43"] = 2; level.cost["target_practice"]["mg42"] = 12; level.cost["target_practice"]["mp40"] = 6; level.cost["target_practice"]["mosin_rifle"] = 3; level.cost["target_practice"]["kar98k_scoped"] = 7; level.cost["target_practice"]["doublebarrel"] = 4; level.cost["target_practice"]["fg42"] = 8; level.cost["target_practice"]["30cal"] = 10; level.cost["target_practice"]["specialty_armorvest"] = 15; level.cost["target_practice"]["specialty_fastreload"] = 12; level.cost["target_practice"]["specialty_rof"] = 8; level.delay["target_practice"] = []; // DO NOT REMOVE level.delay["target_practice"]["bolt"] = 3; level.delay["target_practice"]["rifle"] = 2; level.delay["target_practice"]["smg"] = 3; level.delay["target_practice"]["sniper"] = 4; level.delay["target_practice"]["rocket"] = 6; level.delay["target_practice"]["mg"] = 7; level.delay["target_practice"]["dog"] = 6; }
Which i then use an if condition statement to figure out which settings i want to execute based on the current gamemode:
mod_init() { if(level.gamemode == "ctf") { [[level.ctf_settings]](); level.ctype = " captures"; level.gamemode_text = "Captures: "; thread ctf_init(); } else if(level.gamemode == "hotzone") { [[level.hotzone_settings]](); level.ctype = " hotzones"; level.gamemode_text = "Hotzone: "; thread hotzone_init(); } else if(level.gamemode == "deathmatch") { [[level.deathmatch_settings]](); level.ctype = " kills"; level.gamemode_text = "Kills: "; thread deathmatch_init(); } else if(level.gamemode == "round_deathmatch") { [[level.round_deathmatch_settings]](); level.ctype = " rounds"; level.gamemode_text = "Round: "; thread round_deathmatch_init(); } else if(level.gamemode == "target_practice") { [[level.target_settings]](); level.ctype = " score"; level.gamemode_text = "Score: "; thread targets_init(); } [[level.common_settings]](); thread common_init(); thread gamemode_hud(); }
Effectively reducing the amount of variable being set.
(If i missed anything or didn't explain something right please tell me, this was kind of a spur of the moment thing)
(Soviet mod code needs to be optimized better i know but it gets the point across so shhh
)