Spawn function and replacements

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!
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
Kzer-Za
Posts: 522
Joined: Sat Aug 19, 2017 11:52 pm
Graphics Processor: nVidia (Modern GZDoom)

Spawn function and replacements

Post by Kzer-Za »

I have an actor that is supposed to periodically spawn some monsters in non-random order. I want to define the list of monsters that are supposed to be spawned as the names of vanilla monsters, e.g. DoomImp. That way if there are mods that replace the vanilla monsters, my spawned monsters are going to be replaced.

However, if I use, e.g. Spawn("DoomImp"), then DoomImp is precisely the actor that is spawned, even if DoomImp is replaced by other actors when spawned by any other means (placed on map, CCMD "summon", or A_SpawnProjectile). But I kind of don't want to use A_SpawnProjectile to spawn monsters. So, how can I make sure that the spawned monsters are replaced?
User avatar
determin1st
Posts: 57
Joined: Wed Oct 06, 2021 11:23 am
Contact:

Re: Spawn function and replacements

Post by determin1st »

i think it's gzdoom problem, because i have a GiveInventory() script which gives a weapon on map start that should be (i guess) replaced, but not. giving it some unique name will work but.. kinda :shock:
User avatar
Enjay
 
 
Posts: 27378
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland
Contact:

Re: Spawn function and replacements

Post by Enjay »

I have never had a problem using the various spawn functions with "replaces" actors. Spawn, Spawnspot, SpawnSpotForced etc all give me the replacement, not the original. So I suspect that something else is happening here.


As for the weapon, that is different. Weapon replacements don't work like that. You can replace the pickup version of the weapon (so any map placed or spawned weapons will be replaced) but if you are manipulating the inventory directly, then whatever you give to the player is what you give to the player. I'm not sure what the way to get around that is, but I'm sure someone must have done it at some point?
Kzer-Za
Posts: 522
Joined: Sat Aug 19, 2017 11:52 pm
Graphics Processor: nVidia (Modern GZDoom)

Re: Spawn function and replacements

Post by Kzer-Za »

Enjay wrote:I have never had a problem using the various spawn functions with "replaces" actors. Spawn, Spawnspot, SpawnSpotForced etc all give me the replacement, not the original. So I suspect that something else is happening here.
Maybe I am misinterpreting the results I'm getting, but test this yourself: create a mod with this code, and nothing else:

Code: Select all


class TestImp : DoomImp replaces DoomImp
{
	States
	{
	Spawn:
		TNT1 A 0 NoDelay {Console.Printf("I am test Imp");}
	See:
	Idle:
		TROO A 35;
		goto See;
	Death:
		TNT1 A 0 {Spawn("DoomImp", pos);}
//		TNT1 A 0 {A_SpawnProjectile("DoomImp");}
		goto Super::Death;
	}
}
Start a game with this mod and no other mod. If there are imps on a map, you will see several "I am test Imp" messages in the console. If any of these Imps are killed, they are supposed to spawn another one, the same Imp, when it is killed, it will spawn another one, etc (it's nonsensical, it's just to illustrate that the Spawn function spawns the exact actor, not the replacement). But in fact, when a TestImp is killed, it spawns not another TestImp, but a vanilla DoomImp. You can tell that by 1) not receiving a message "I am test Imp", 2) this new Imp is chasing you (TestImp, as you can see from the code, can't do that), 3) it does not spawn a new Imp upon being killed.

But if you uncomment the "A_SpawnProjectile" line in the code given above and comment the "Spawn" line, THEN the TestImp starts behaving like it's supposed to: spawning upon its death a new TestImp, which upon death spawns a new one, etc.

Which means, that Spawn always spawns the exact actor it is given as its argument, not the replacement.
User avatar
Virathas
Posts: 254
Joined: Thu Aug 10, 2017 9:38 am

Re: Spawn function and replacements

Post by Virathas »

No surprise here. Note carefully what are the parameters from Spawn function.

Code: Select all

static Actor Spawn(class<Actor> type, vector3 pos = (0,0,0), int replace = NO_REPLACE)
As you can see, the third parameter tells the function that no replacing can happen, and that is set by default. You need to adjust this variable (Though i am not sure what are the exact values, i wager it would be 0 to allow replacing).
User avatar
Enjay
 
 
Posts: 27378
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland
Contact:

Re: Spawn function and replacements

Post by Enjay »

I suspect that Virathas has got it. I misinterpreted what you meant when talking about spawn functions. I was talking about what happens when using ACS. I have not tried this in ZScript and what you posted does seem to behave as you described.

One tip I can give you for testing purposes though; if you bring down the console while the crosshair is on an actor and type "info" it will give you a readout of the properties of that actor, including its class name. Or you can bind a key to info.
User avatar
Virathas
Posts: 254
Joined: Thu Aug 10, 2017 9:38 am

Re: Spawn function and replacements

Post by Virathas »

Enjay wrote: One tip I can give you for testing purposes though; if you bring down the console while the crosshair is on an actor and type "info" it will give you a readout of the properties of that actor, including its class name. Or you can bind a key to info.
Woot? I wrote my own ACS functions to get such info, and now i learn that a built-in function exists?! Great thanks!
User avatar
phantombeta
Posts: 2198
Joined: Thu May 02, 2013 1:27 am
Operating System Version (Optional): Windows 10
Graphics Processor: nVidia with Vulkan support
Location: Brazil

Re: Spawn function and replacements

Post by phantombeta »

Virathas wrote: As you can see, the third parameter tells the function that no replacing can happen, and that is set by default. You need to adjust this variable (Though i am not sure what are the exact values, i wager it would be 0 to allow replacing).
What you need to use is the "ALLOW_REPLACE" constant. "0" is the value of NO_REPLACE, the default value.
Additionally, you shouldn't use numbers instead of the constants, using the numbers directly is error-prone and pretty much impossible to read.
User avatar
Enjay
 
 
Posts: 27378
Joined: Tue Jul 15, 2003 4:58 pm
Location: Scotland
Contact:

Re: Spawn function and replacements

Post by Enjay »

Yeah, it's definitely useful. If you bind a key, you get a short version printed up in the top-left of the screen but the full info is still printed to the console for you to check there.
Kzer-Za
Posts: 522
Joined: Sat Aug 19, 2017 11:52 pm
Graphics Processor: nVidia (Modern GZDoom)

Re: Spawn function and replacements

Post by Kzer-Za »

Thanks everyone!

I never saw Spawn function being used with flags on this forum, and didn't think to look into the source code. Since almost everything I know about programming I learned by fiddling with some GZDoom mods, I perceive my skills at that as very low, so looking at the source code of the engine is the last thing that comes to my mind. And the wiki article is about ACS function.

The info about "info" CCMD is also going to be extremely useful! :)
User avatar
determin1st
Posts: 57
Joined: Wed Oct 06, 2021 11:23 am
Contact:

Re: Spawn function and replacements

Post by determin1st »

Enjay wrote:I have never had a problem using the various spawn functions with "replaces" actors. Spawn, Spawnspot, SpawnSpotForced etc all give me the replacement, not the original. So I suspect that something else is happening here.
i've got an error in gzdoom 4.5.0, excluding all the oranges, the red one is (is one that stops the startup, i assume):

Script error, "BADRevolver.pk3:scripts/revolver.dec" line 35:
Cannot replace class Revolver with itself

the line 35:

ACTOR Revolver : BrutalWeapon replaces Revolver
{...}

the same error is in zandronum. removing "replaces" makes both engines start, but.. gzdoom gives the old revolver and zandronum the new one, with this equip ACS code:

Code: Select all

script "revolverEquip" ENTER
{
	if (CheckInventory("BrutalPistol") >= 1)
	{
		TakeInventory("BrutalPistol", 1);
		GiveInventory("Revolver", 1);
		GiveInventory("RevolverAmmo", 6);
	}
}
i know that this is not the way to equip things, but i use it for testing purposes
User avatar
Virathas
Posts: 254
Joined: Thu Aug 10, 2017 9:38 am

Re: Spawn function and replacements

Post by Virathas »

What are you trying to do? As the error says "You can't replace an actor with itself" - That would cause at best an infinite loop. If i understand correctly, you probably should do

Code: Select all

ACTOR Revolver : BrutalWeapon replaces BrutalPistol 
and not any other way around.
In short, "replaces" keyword caues all actors of a particular type that are spawned on the map (on start, or during the game) to be, well, replaced. It will not replace a starting inventory item though, that is why many mods define their own player classes if they want to replace a starting item.
User avatar
determin1st
Posts: 57
Joined: Wed Oct 06, 2021 11:23 am
Contact:

Re: Spawn function and replacements

Post by determin1st »

Virathas wrote:What are you trying to do?
There is a unfinished "Revolver" actor in BD wad/pk (also Revolver2, RevolverAmmo and some other unused actors) they are not in the map, anywhere (not given), so i just want to replace it with my test actor with the same name. That works in zandronum -file BD.pk3 replace.pk3 but for gz i have to specify another name, like MyRevolver
Post Reply

Return to “Scripting”