Could level init be hooked with zscript events?

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Post Reply
gramps
Posts: 300
Joined: Thu Oct 18, 2018 2:16 pm

Could level init be hooked with zscript events?

Post by gramps »

This is a long shot, but haven't seen any discussion of it, so I'm gonna throw it out there.

Would it be remotely possible in some future zscript to hook into level init with some virtual method of StaticEventHandler? In other words, might it be possible at some point to create a zscript that has access to some of the action specials marked as "no script" -- for example, using "SetLineSpecial" to set "Line_Horizon" on a line?
_mental_
 
 
Posts: 3820
Joined: Sun Aug 07, 2011 4:32 am

Re: Could level init be hooked with zscript events?

Post by _mental_ »

It’s possible. There was a discussion about making internal map compatibility handler available to modders in some way or another.
Nothing was done yet in this direction. This feature is still waiting for an implementer :)
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49230
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Could level init be hooked with zscript events?

Post by Graf Zahl »

_mental_ wrote:It’s possible. There was a discussion about making internal map compatibility handler available to modders in some way or another.
Nothing was done yet in this direction.
Actually, it was silently added by processing all subclasses of LevelCompatibility in sequence. But keep in mind that this code is run before any actors are spawned so you cannot use it to initate any gameplay related actions. It's solely meant to alter the level itself.
gramps
Posts: 300
Joined: Thu Oct 18, 2018 2:16 pm

Re: Could level init be hooked with zscript events?

Post by gramps »

Well, this sounds like the best news I've heard all year.

So how does this work exactly? It looks like LevelCompatibility does everything in Apply, which isn't virtual... how do subclasses of LevelCompatibility do their thing?
User avatar
Enjay
 
 
Posts: 26991
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland
Contact:

Re: Could level init be hooked with zscript events?

Post by Enjay »

gramps wrote:Well, this sounds like the best news I've heard all year.
The Date wrote:Tue Jan 01, 2019
Image
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49230
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Could level init be hooked with zscript events?

Post by Graf Zahl »

gramps wrote:Well, this sounds like the best news I've heard all year.

So how does this work exactly? It looks like LevelCompatibility does everything in Apply, which isn't virtual... how do subclasses of LevelCompatibility do their thing?

It just goes through all classes, fetches their 'Apply' method and calls it. What exactly would you do with it? Like I said, right now it is pretty much limited to stuff that can be done in an editor.
gramps
Posts: 300
Joined: Thu Oct 18, 2018 2:16 pm

Re: Could level init be hooked with zscript events?

Post by gramps »

Ahh, thanks, I'll try it!

Basically my overall goal is to be able to put portals all over the place without things getting too screwy. I was going to mess with Static_Init[1] and see if I could use it to get sky angle to render properly across portals.

But it looks like individual vertices can be moved around with this class, and I might even try "physically" rotating some geometry and putting in static portals.

[1] - It looks like this thing would be running at a point when it would be alright to use Static_Init and other "no-script" specials, but will that actually work?
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49230
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: Could level init be hooked with zscript events?

Post by Graf Zahl »

Yes, it runs before static line specials get evaluated.
gramps
Posts: 300
Joined: Thu Oct 18, 2018 2:16 pm

Re: Could level init be hooked with zscript events?

Post by gramps »

I'm having some trouble getting this to work.

Here's what I have right now:

Code: Select all

class RLP_LevelInit : LevelCompatibility
{
	private static void Apply(Name checksum)
	{
		level.sectors[50].SetTexture(Sector.Ceiling,
			TexMan.CheckForTexture("FLAT3", TexMan.Type_Flat));
	}
	
}
I know that it's at least being parsed, because it will throw errors on type mismatches and so on.

I'm not sure it's ever being evaluated, though. Console.printf doesn't seem to work; should it work here?

This code should change the ceiling of the sector where the player spawns, but nothing happens. Maybe something's wrong with the code? What's the simplest thing I can do in my LevelCompatibility subclass to test if it's actually being evaluated?
_mental_
 
 
Posts: 3820
Joined: Sun Aug 07, 2011 4:32 am

Re: Could level init be hooked with zscript events?

Post by _mental_ »

The problem is the missing test for map checksum. Please note that you need to add comparison with it as a name, not as a string. The internal handler does this in switch statement.
gramps
Posts: 300
Joined: Thu Oct 18, 2018 2:16 pm

Re: Could level init be hooked with zscript events?

Post by gramps »

@_mental_, thanks, do you happen to know where the C++ code is that does the special handling for LevelCompatibility subclasses? I feel like there's either something I'm not understanding, or some serious black magic going on here... is it really checking whether I checked a checksum or not inside that function, instead of just running it?

I tried this:

Code: Select all

class RLP_LevelInit : LevelCompatibility
{
	protected void Apply(Name checksum)
	{
		switch (checksum)
		{			
			case 'deb751282d80fd59f56ae0240aa2e22b':
			{
				console.printf("it worked");
				level.sectors[50].SetTexture(Sector.Ceiling,
					TexMan.CheckForTexture("FLAT3", TexMan.Type_Flat));
			}
		}
	}
}
Unfortunately, it still never seems to fire.

That's the checksum for the map wad, as reported by md5sum. The script, the map wad and other lumps are in a pk3-style unzipped directory. I hope that's not what I need a checksum for; that would be impossible because the checksum itself would need to be included in the thing being checksummed.

Tested on 3.7.1 and latest nightly.
_mental_
 
 
Posts: 3820
Joined: Sun Aug 07, 2011 4:32 am

Re: Could level init be hooked with zscript events?

Post by _mental_ »

User defined compatibility handler is present in devbuilds only.
You should use checksum calculated by mapchecksum CCMD.
gramps
Posts: 300
Joined: Thu Oct 18, 2018 2:16 pm

Re: Could level init be hooked with zscript events?

Post by gramps »

Awesome, let me try that, thanks for your help :)

...Alright, mapchecksum did the trick.

I have no idea how this works internally, though.

Code: Select all

class Blah : LevelCompatibility
{
	protected void Apply(Name checksum)
	{
		console.printf("its working....");
		switch (checksum)
		{			
			case 'goodchecksum':
				console.printf("it worked");
		}
	}
}
With the right checksum, both messages are printed to the console, but with the wrong checksum, neither one prints.

What's going on here? I'd like to avoid using checksums for my own maps if possible; I'd rather identify them by map name or level number or whatever.

---

Played with it a bit more. Apparently what's necessary for the function to fire is just that the checksum appears somewhere in the function. A statement containing only a string literal with the checksum in it will trigger it. It can be placed anywhere in the function, even at the end, after a return, where it would never execute.

Code: Select all

class Blah: LevelCompatibility
{
	protected void Apply(Name checksum)
	{
		console.printf("it works");
		return;
		'goodchecksum';
	}
}
Weird, right? Haven't found any way around having that string literal there. Anyway, I'll play around with it and maybe put in a feature suggestion for hooking it up to event handlers or similar later.
Post Reply

Return to “Scripting”