[zscript]minilib for global variables

Post your example zscripts/ACS scripts/etc here.
Forum rules
The Projects forums are only for projects. If you are asking questions about a project, either find that project's thread, or start a thread in the General section instead.

Got a cool project idea but nothing else? Put it in the project ideas thread instead!

Projects for any Doom-based engine (especially 3DGE) are perfectly acceptable here too.

Please read the full rules for more details.
User avatar
Sir Robin
Posts: 537
Joined: Wed Dec 22, 2021 7:02 pm
Graphics Processor: Intel (Modern GZDoom)
Location: Medellin, Colombia

[zscript]minilib for global variables

Post by Sir Robin »

I needed a way to keep global variables, and move them from map to map. One way is to put them in an inventory object and give it to the player. But in multiplayer, it's possible that this player is killed or disconnected and the item is lost. So I created this small library where I can store things in a global class and then use handlers to move that class from map to map.

Note this doesn't work to move things attached to the map, for example actors. But It could be used to store actor information (for example, classname, health, etc) and destroy that actor from one map and then spawn it into another map.

One thing I use it for is to synchronize activated actors between maps. ACS has a mechanism to call scripts on other maps but I couldn't find an easy way to do this in ZScript so I use this globals library to keep a list of TIDs to activate on other maps.

It's pretty easy to use, just pack your variables and/or functions on to the MWR_Globals class and then you can access them from MWR_Globals.GetInstance() anywhere in your code. It also has its own WorldLoaded and WorldUnloaded functions, so you can put your setup and teardown code in there.

Here's the code, it has my activators code baked-in. If you don't need that you can rip it out and still use the rest:

Code: Select all

//----------MAPINFO
GameInfo
{
    AddEventHandlers = "MWR_Globals_WorldHandler","MWR_Globals_MapHandler"
}

//----------ZSCRIPT
//don't forget a version, or to include from a versioned file
class MWR_Globals play
{
	static MWR_Globals GetInstance()
	{
		return MWR_Globals_MapHandler.GetGlobals();
	}
	
	array<int> ThingActivations;
	array<int> ThingDeactivations;
	
	void SetThingActivation(int tid)//add this tid to the activation list if it doesn't exist already
	{
		//clear tid out of all the lists if it exists in any
		ClearThingActivation(tid);

		//insert it in numerical order, just because
		int i=0;
		int max=ThingActivations.size();//cache this is faster?
		while (i < max && tid < ThingActivations[i]) {i++;}
		ThingActivations.insert(i, tid);
	}
	void SetThingDeactivation(int tid)//add this tid to the deactivation list if it doesn't exist already
	{
		//clear tid out of all the lists if it exists in any
		ClearThingActivation(tid);

		//insert it in numerical order, just because
		int i=0;
		int max=ThingDeactivations.size();//cache this is faster?
		while (i < max && tid < ThingDeactivations[i]) {i++;}
		ThingDeactivations.insert(i, tid);
	}
	void ClearThingActivation(int tid)//clear this tid out of both the activations and deactivations lists
	{
		int i;
		i=ThingActivations.find(tid);
		if (i!=ThingActivations.size()) ThingActivations.delete(i);
		i=ThingDeactivations.find(tid);
		if (i!=ThingDeactivations.size()) ThingDeactivations.delete(i);
	}
	void WorldLoaded (WorldEvent e)
	{
		//perform activations
		for (int i=0;i<ThingActivations.size();i++) Level.ExecuteSpecial(130, null, null, false, ThingActivations[i], 0, 0, 0, 0);
		//perform deactivations
		for (int i=0;i<ThingDeactivations.size();i++) Level.ExecuteSpecial(131, null, null, false, ThingDeactivations[i], 0, 0, 0, 0);
	}
	void WorldUnloaded (WorldEvent e)
	{
	}
}

class MWR_Globals_WorldHandler : StaticEventHandler
{
	MWR_Globals globals;

	override void NewGame ()
	{
		globals = new("MWR_Globals");
	}

	override void WorldLoaded (WorldEvent e)
	{
		if (e.isSaveGame) globals=MWR_Globals_MapHandler.GetGlobals();
	}

	override void WorldUnloaded  (WorldEvent e)
	{
		if (!e.isSaveGame) globals=MWR_Globals_MapHandler.GetGlobals();
	}

    static MWR_Globals_WorldHandler GetInstance()
    {
        let h = MWR_Globals_WorldHandler(StaticEventHandler.Find('MWR_Globals_WorldHandler'));

        if (h == null) ThrowAbortException("Could not find the instance of MWR_Globals_WorldHandler.");

        return h;
    }

	static MWR_Globals GetGlobals()
	{
		return GetInstance().globals;
	}
}

class MWR_Globals_MapHandler : EventHandler
{
	MWR_Globals globals;

	override void NewGame ()
	{
		globals=MWR_Globals_WorldHandler.GetGlobals();
	}

	override void WorldLoaded (WorldEvent e)
	{
		if (!e.isSaveGame) globals=MWR_Globals_WorldHandler.GetGlobals();
		globals.WorldLoaded(e);
	}

	override void WorldUnloaded  (WorldEvent e)
	{
		globals.WorldUnloaded(e);
	}

    static MWR_Globals_MapHandler GetInstance()
    {
        let h = MWR_Globals_MapHandler(EventHandler.Find('MWR_Globals_MapHandler'));

        if (h == null) ThrowAbortException("Could not find the instance of MWR_Globals_MapHandler.");

        return h;
    }
	
	static MWR_Globals GetGlobals()
	{
		return GetInstance().globals;
	}
}

Return to “Script Library”