[ZScript/ACS] Call script on map with map name?

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
User avatar
Gutawer
Posts: 469
Joined: Sat Apr 16, 2016 6:01 am
Preferred Pronouns: She/Her

[ZScript/ACS] Call script on map with map name?

Post by Gutawer »

I'm creating a system which will use ACS as a convenient map scripting frontend to a backend written in ZScript, and one of the things the system needs to be able to do is call these scripts on any map. It would be much nicer in terms of the outward facing API to use a map lump's name rather than its LevelNum, so I was just wondering if this were possible. It would alleviate the need to define level nums in MAPINFO and remember them for calling scripts correctly, so this is something I'd like to know how to do.
gramps
Posts: 300
Joined: Thu Oct 18, 2018 2:16 pm

Re: [ZScript/ACS] Call script on map with map name?

Post by gramps »

Was just looking for this myself... try some of the fields of global "levels," it's a struct of type "LevelLocals" (defined in gzdoom.pk3/zscript/base.txt).
User avatar
Nash
 
 
Posts: 17487
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia
Contact:

Re: [ZScript/ACS] Call script on map with map name?

Post by Nash »

The problem here is that the first parameter for ACS_NamedExecute and friends takes in an int, which is the LevelNum value of a map. What Gutawer is asking if it's somehow possible to use map lump name instead. I think new functions would have to be made because the current ones expect int as the first parameter.

The use case here is that LevelNums are cumbersome to work with, requiring management because one would have to remember which LevelNum is for which map - doesn't make sense for projects that completely bypass LevelNum because the game isn't even in a linear format (think something along the lines of Strife).

Moreover, the same reason why one wouldn't want to use LevelNums is the same reason why one wouldn't want to use script numbers in ACS and would rather use named scripts. It's just so much more user-friendly.
gramps
Posts: 300
Joined: Thu Oct 18, 2018 2:16 pm

Re: [ZScript/ACS] Call script on map with map name?

Post by gramps »

Hmm, couldn't you write a little function to get level number by name? Iterate all levels until levelname matches, then return levelnum or a good "do nothing" value if possible when nothing matches.

Then do something like ACS_NamedExecute(getLevelNum("somewhere"), ...)

Or does ACS_ExecuteAlways need to be called from ACS in this scenario, not zscript? Not sure about info passing between zscript and ACS, haven't tried that yet.
stan423321
Posts: 32
Joined: Tue Mar 25, 2014 2:35 pm

Re: [ZScript/ACS] Call script on map with map name?

Post by stan423321 »

You can call ACS_ExecuteWhatever from ZScript, otherwise porting existing DECORATE code would be extremely painful.

The "iterate levelnums" setup is sounds like it would probably result in player seeing the initial map transitions, which is extremely ugly.

If you don't care about object activator, or it's always a player pawn, here's what I would try doing in ZScript. Give player pawn an unselectable inventory item containing script activation details. Then write an EventHandler that checks current map's lump name, then checks through player pawn inventories for applicable items, and if the name matches, fires the script and removes the item. If the rest of the code is in ACS, you should be able to utilize ScriptCall to pipe it to the ZScript part.
User avatar
Gutawer
Posts: 469
Joined: Sat Apr 16, 2016 6:01 am
Preferred Pronouns: She/Her

Re: [ZScript/ACS] Call script on map with map name?

Post by Gutawer »

I've decided to just not use ACS at all for this, but yes, that was going to be what I did, minus use of inventory items to do it.
gramps
Posts: 300
Joined: Thu Oct 18, 2018 2:16 pm

Re: [ZScript/ACS] Call script on map with map name?

Post by gramps »

@stan423321 oops, you're right, I was thinking it was "levels" but it's just the current "level."

What would really help here is if zscript had access to the wad/pk3 filesystem.

...in fact I just found this, gonna try it out now.
gramps
Posts: 300
Joined: Thu Oct 18, 2018 2:16 pm

Re: [ZScript/ACS] Call script on map with map name?

Post by gramps »

Just in case anyone else come across this, here's an extremely hacky (but apparently working) method.

Code: Select all

const MF_MAX_LUMPS = 2000;

class MapFinder {
	Array<int> indices;
	
	static MapFinder create() {
		let instance = new("MapFinder");
		instance.init();
		return instance;
	}
	
	void init() {
		indices.clear();
		for (int i = 1; i < MF_MAX_LUMPS; i++) {
			if (wads.readLump(i).length() == 1) {
				indices.push(i);
			}
		}
	}
	
	int find(string lumpName) {
		let index = wads.findLump(lumpName);
		if (index < 0) return -1;
		let len = indices.size();
		
		for (int i = 1; i < len; i++) {
			if (indices[i] == index) {
				return i + 1;
			}
		}
		return -1;
	}
}
Not quite sure how to properly deal with initialization; haven't found anything like constructors or default values. A static "create" function seems to work, though.

The array seems sketchy to me though, can anyone tell me whether that's properly initialized?
Post Reply

Return to “Scripting”