[ZScript/ACS] Call script on map with map name?
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!)
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!)
[ZScript/ACS] Call script on map with map name?
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.
Re: [ZScript/ACS] Call script on map with map name?
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).
Re: [ZScript/ACS] Call script on map with map name?
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.
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.
Re: [ZScript/ACS] Call script on map with map name?
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.
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.
-
- Posts: 32
- Joined: Tue Mar 25, 2014 2:35 pm
Re: [ZScript/ACS] Call script on map with map name?
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.
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.
Re: [ZScript/ACS] Call script on map with map name?
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.
Re: [ZScript/ACS] Call script on map with map name?
@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.
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.
Re: [ZScript/ACS] Call script on map with map name?
Just in case anyone else come across this, here's an extremely hacky (but apparently working) method.
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?
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;
}
}
The array seems sketchy to me though, can anyone tell me whether that's properly initialized?