Hey guys today I'm going to release something that I've been using for awhile in my der riese mod and thought it would probably help other people who use CSC. Today I'm releasing my fake client systems, which basically use one WaW engine client system to pass info in other "fake" systems.
This solves two problems that I have noticed with WaW client systems:
1. There is a limit of 8 in WaW, and 7 are used by default 2. When a player is spectating and you call a client system callback on them, it does not actually thread to them. Basically I use a separate way to specify which player you are threading to in CSC.
The setup is pretty simple. First create a GSC script called _xS78_fake_clientsystems.gsc Put this into the script:
Now open a utility file in GSC ( preferably _zombiemode_utility.gsc ) and place this function at the bottom:
Code Snippet
Plaintext
set_client_system_state( system_name, system_state, player ) { if( IsDefined( player ) ) { player_num = string( player GetEntityNumber() ); } else { player_num = "all"; } state = player_num + "," + string( system_name.size ) + "|" + system_name + system_state; setClientSysState( "fake_client_systems", state ); }
For the next part, you will need to add stuff to _utility.csc Thanks to my friend I found out that this script is not in raw or included with the script placer or anything so here is one:
// fancy quicker struct array handling, assumes array elements are objects with which an index can be asigned to( IE: can't do 5.struct_array_index ) // also have to be sure that objects can't be a part of another structarray setup as the index position is asigned to the object
array = level.struct_class_names[ type ][ name ]; if( !IsDefined( array ) ) { println("**** Getstruct returns undefined on " + name + " : " + " type."); return undefined; }
if( array.size > 1 ) { assertMsg( "getstruct used for more than one struct of type " + type + " called " + name + "." ); return undefined; } return array[ 0 ]; }
getstructarray( name, type ) { assertEx( IsDefined( level.struct_class_names ), "Tried to getstruct before the structs were init" );
/* ============= ///ScriptDocBegin "Name: array_thread( <entities> , <process> , <var1> , <var2> , <var3> )" "Summary: Threads the < process > function on every entity in the < entities > array. The entity will become "self" in the specified function." "Module: Array" "CallOn: " "MandatoryArg: <entities> : array of entities to thread the process" "MandatoryArg: <process> : pointer to a script function" "OptionalArg: <var1> : parameter 1 to pass to the process" "OptionalArg: <var2> : parameter 2 to pass to the process" "OptionalArg: <var3> : parameter 3 to pass to the process" "Example: array_thread( getaiarray( "allies" ), ::set_ignoreme, false );" "SPMP: both" ///ScriptDocEnd ============= */ array_thread( entities, process, var1, var2, var3 ) { keys = getArrayKeys( entities );
if ( IsDefined( var3 ) ) { for( i = 0 ; i < keys.size ; i ++ ) entities[ keys[ i ] ] thread [[ process ]]( var1, var2, var3 );
return; }
if ( IsDefined( var2 ) ) { for( i = 0 ; i < keys.size ; i ++ ) entities[ keys[ i ] ] thread [[ process ]]( var1, var2 );
return; }
if ( IsDefined( var1 ) ) { for( i = 0 ; i < keys.size ; i ++ ) entities[ keys[ i ] ] thread [[ process ]]( var1 );
return; }
for( i = 0 ; i < keys.size ; i ++ ) entities[ keys[ i ] ] thread [[ process ]](); }
// Also support script_structs to work as exploders for( i = 0; i < level.struct.size; i++ ) { if( IsDefined( level.struct[i].script_prefab_exploder ) ) { level.struct[i].script_exploder = level.struct[i].script_prefab_exploder; }
// MikeD( 4/14/2008 ): Attempt to use the fxid as the sound reference, this way Sound can add sounds to anything // without the scripter needing to modify the map if( IsDefined( exploder.script_sound ) ) { ent.v["soundalias"] = exploder.script_sound; } else if( ent.v["fxid"] != "No FX" ) { if( IsDefined( level.scr_sound ) && IsDefined( level.scr_sound[ent.v["fxid"]] ) ) { ent.v["soundalias"] = level.scr_sound[ent.v["fxid"]]; } }
/* ============= ///CScriptDocBegin "Name: splitscreen_populate_dvars( <clientNum> )" "Summary: Populates profile dvars with settings read from clientNum's profile data." "Module: System" "MandatoryArg: <clientNum> : the local client num of the profile to be read" "Example: splitscreen_populate_dvars( 1 );" "SPMP: singleplayer" ///CScriptDocEnd ============= */ splitscreen_populate_dvars( clientNum ) { if ( getlocalplayers().size <= 1 ) { return; }
UpdateDvarsFromProfile( clientNum ); }
/* ============= ///CScriptDocBegin "Name: splitscreen_restore_dvars()" "Summary: Restores profile dvars with settings read from client 0's profile data." "Module: System" "Example: splitscreen_restore_dvars();" "SPMP: singleplayer" ///CScriptDocEnd ============= */ splitscreen_restore_dvars() { if ( getlocalplayers().size <= 1 ) { return; }
Now open maps\_zombiemode.gsc and look at the top function called main(). Under this:
Code Snippet
Plaintext
maps\_zombiemode_auto_turret::init();
Place this:
Code Snippet
Plaintext
maps\_xS78_fake_clientsystems::init();
Now open clientscripts\{MAPNAME}.csc and look at the function called main(). Under this:
Code Snippet
Plaintext
clientscripts\_load::main();
Place this:
Code Snippet
Plaintext
clientscripts\_xS78_fake_clientsystems::init();
That should be it. Remember to tick those new scripts in mod builder.
Now you can use set_client_system_state in GSC the same way you could use the original, if you don't know how I'm sure there are tutorials somewhere. And you no longer have to register new client systems in the GSC, you can just immediately call them from where ever you want. And in CSC you can use register_client_system the same way you could use the origins ( again, find you own tutorial ).
Last Edit: June 27, 2016, 10:17:21 pm by alaurenc9