Replacing multiple actors with a single new actor?
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!)
-
- Posts: 4
- Joined: Sat Dec 26, 2020 12:12 pm
- Graphics Processor: nVidia (Modern GZDoom)
Replacing multiple actors with a single new actor?
Hey all! Long-time, first-time here--tried searching the wiki and forums for an answer to this question and couldn't find it.
I'm working on my first .pk3 and adding some new weapons via DECORATE as replacements for extant ones--specifically a shotgun replacement. I was wondering if there was a way to use the "replaces" function for multiple actors? If I wanted my new gun to replace both the shotgun and ssg, for instance? Is there another DECORATE function that could do this?
Apologies if this has already been answered elsewhere--I started making this (my first-ever digital game project of any kind, really!) last week so I'm still learning the terminology to search for! Thanks!
I'm working on my first .pk3 and adding some new weapons via DECORATE as replacements for extant ones--specifically a shotgun replacement. I was wondering if there was a way to use the "replaces" function for multiple actors? If I wanted my new gun to replace both the shotgun and ssg, for instance? Is there another DECORATE function that could do this?
Apologies if this has already been answered elsewhere--I started making this (my first-ever digital game project of any kind, really!) last week so I'm still learning the terminology to search for! Thanks!
- Caligari87
- Admin
- Posts: 6174
- Joined: Thu Feb 26, 2004 3:02 pm
- Preferred Pronouns: He/Him
- Contact:
Re: Replacing multiple actors with a single new actor?
The naive approach would be to replace all the actors with a dummy actor that spawns the actor you want. Example:
A cleaner possibility is using MAPINFO Editor Number remapping to force certain editor numbers to remap to a different actor.
If you're willing to use ZScript, a CheckReplacement() handler is one extremely robust method.
Code: Select all
actor DummyShotgunReplacer replaces Shotgun {
States {
Spawn:
TNT1 A 0 A_SpawnItemEx("MyCustomWeapon")
Stop
}
}
actor DummyChaingunReplacer replaces Chaingun {
States {
Spawn:
TNT1 A 0 A_SpawnItemEx("MyCustomWeapon")
Stop
}
}
Code: Select all
DoomEdNums
{
2001 = MyCustomWeapon //shotgun
2002 = MyCustomWeapon // chaingun
}
-
- Posts: 4949
- Joined: Sun Nov 14, 2010 12:59 am
Re: Replacing multiple actors with a single new actor?
^^ The "naive approach" is better replaced with the [wiki=Classes:WeaponGiver]WeaponGiver[/wiki] one. The MAPINFO one only replaces map-placed actors.
- Player701
-
- Posts: 1640
- Joined: Wed May 13, 2009 3:15 am
- Graphics Processor: nVidia with Vulkan support
- Contact:
Re: Replacing multiple actors with a single new actor?
Note that this code will not work as-is unless NODELAY is added before A_SpawnItemEx calls. It will also not play well with "items respawn" / "weapons stay" gameplay options, since all dynamically spawned items are considered "dropped" and are not subject to those. WeaponGiver is probably the best non-ZScript based solution here.Caligari87 wrote:Code: Select all
actor DummyShotgunReplacer replaces Shotgun { States { Spawn: TNT1 A 0 A_SpawnItemEx("MyCustomWeapon") Stop } } actor DummyChaingunReplacer replaces Chaingun { States { Spawn: TNT1 A 0 A_SpawnItemEx("MyCustomWeapon") Stop } }
Re: Replacing multiple actors with a single new actor?
Sorry for the late response on this! These replies are really helpful, but after perusing it looks like adding a ZScript definition might be the cleanest way to go. Does anyone have any resources/tutorials they'd recommend on creating/editing ZScript docs? Can these run in parallel in my extant DECORATE script, a la KEYCONF or SNDINFO, or would I need to port my DECORATE work over to ZScript? Thanks so much everyone!!
- Player701
-
- Posts: 1640
- Joined: Wed May 13, 2009 3:15 am
- Graphics Processor: nVidia with Vulkan support
- Contact:
Re: Replacing multiple actors with a single new actor?
You can combine ZScript with DECORATE, but you cannot use DECORATE-based actors in your ZScript code because DECORATE is parsed after ZScript. However, this does not prevent you from using CheckReplacement to manage replacements of existing actors with your custom DECORATE-based actors. This is possible because CheckReplacement deals with class names rather than actual actor instances, so your ZScript will compile without errors.
For the most comprehensive ZScript language and API documentation available at the moment, see here. Also check out the wiki for many useful articles on various ZScript topics. In particular, a lot of information on event handlers can be found here.
Now, regarding your particular use case. This is what Caligari87's code would look like in ZScript with CheckReplacement:
You should not forget to add your event handler in your MAPINFO lump, otherwise GZDoom will not register it in the game:
For the most comprehensive ZScript language and API documentation available at the moment, see here. Also check out the wiki for many useful articles on various ZScript topics. In particular, a lot of information on event handlers can be found here.
Now, regarding your particular use case. This is what Caligari87's code would look like in ZScript with CheckReplacement:
Code: Select all
version "4.5"
class MyEventHandler : EventHandler
{
override void CheckReplacement(ReplaceEvent e)
{
if (e.Replacee == 'Shotgun' || e.Replacee == 'Chaingun')
{
e.Replacement = 'MyCustomWeapon';
}
}
}
Code: Select all
gameinfo
{
AddEventHandlers = "MyEventHandler"
}
-
- Posts: 4
- Joined: Sat Dec 26, 2020 12:12 pm
- Graphics Processor: nVidia (Modern GZDoom)
Re: Replacing multiple actors with a single new actor?
Oh, neat! So I can just keep a separate ZScript.txt "in front of" my DECORATE script with the checkreplacement handler, call it in MAPINFO, and don't need to tweak anything in DECORATE for the time being? That's awesome! Thanks so much everyone!
-
- Posts: 4
- Joined: Sat Dec 26, 2020 12:12 pm
- Graphics Processor: nVidia (Modern GZDoom)
Re: Replacing multiple actors with a single new actor?
Sorry, one point of clarification here--how would ZScript recognize my custom actors if it's parsing first? I'm running into a debug code where the ZScript function I've added isn't recognizing my custom weapon name, and I assume that's why. Do I need to add a definition section in ZScript that points to DECORATE? I'm sorry for bugging you about this again, I just don't quite know how to phrase my question in such a way that the extant ZScript documentation is helpful for this rn.Player701 wrote:You can combine ZScript with DECORATE, but you cannot use DECORATE-based actors in your ZScript code because DECORATE is parsed after ZScript. However, this does not prevent you from using CheckReplacement to manage replacements of existing actors with your custom DECORATE-based actors. This is possible because CheckReplacement deals with class names rather than actual actor instances, so your ZScript will compile without errors.
- Player701
-
- Posts: 1640
- Joined: Wed May 13, 2009 3:15 am
- Graphics Processor: nVidia with Vulkan support
- Contact:
Re: Replacing multiple actors with a single new actor?
Like I said before, the CheckReplacement event does not create actors by itself, so it doesn't deal with any variables or fields of types that are defined in DECORATE (and are thus yet unknown to ZScript). You only specify a class name, and those are evaluated at runtime, when everything has already been parsed.
Here's an example of code that won't work due to DECORATE / ZScript parsing order:
In short: You cannot create variables of DECORATE-defined class types, nor can you cast a variable to such a type. Everything else should work.
Here's an example of code that won't work due to DECORATE / ZScript parsing order:
Code: Select all
//DECORATE
actor MyCoolWeapon : Weapon
{
...
}
// ZScript
class MyClass
{
void MyMethod()
{
class<Weapon> weap = 'MyCoolWeapon'; // OK: just a class name
MyCoolWeapon mcw; // Error: Unknown type MyCoolWeapon
...
}
}