Spawn Item Alongside Preexisting Item

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
JossTheFox
Posts: 32
Joined: Sat Jun 19, 2021 6:35 am
Preferred Pronouns: She/Her

Spawn Item Alongside Preexisting Item

Post by JossTheFox »

Hello again! I've been beating my head against a wall for way too long trying to figure this out, so I figured I should ask for some help.

I'm currently making a Doom mod that includes a lot of custom content, mostly weapons and stuff but also a custom campaign. I had the idea to have some unlockable weapons, that you could find in a level and then choose if you wanted to spawn anywhere else (admittedly, this is mainly because I like playing the vanilla doom maps with my mod and thought it'd be nice for them to spawn in those too). My idea for this spawning is that each weapon can either spawn in your inventory or spawn alongside backpacks. I've gotten the first one to work, but I'm having a lot of trouble for the second one.

My idea is to have a Custom Inventory object that replaces the backpack, then spawns the backpack and has a chance to spawn the unlockables you have enabled. This is the DECORATE code for said backpack:

Actor BackpackSpawner : CustomInventory replaces Backpack { States { Spawn: //check if any unlockable spawning is set to "Find In Map" CSDL A 0 A_JumpIf(CallACS("BackpackRevolverCheck", 0, 0, 0) == 1, "SpawnRevolver") CSDL A 0 A_JumpIf(CallACS("BackpackGarandCheck", 0, 0, 0) == 1, "SpawnGarand") CSDL A 0 A_JumpIf(CallACS("BackpackScepterCheck", 0, 0, 0) == 1, "SpawnScepter") //if not, just drop backpack CSDL A 0 A_DropItem("CombatSaddlebag", 1) Stop SpawnRevolver: CSDL A 0 A_DropItem("RevolverUnlocker", 1, 256) CSDL A 0 A_JumpIf(CallACS("BackpackGarandCheck", 0, 0, 0) == 1, "SpawnGarand") CSDL A 0 A_JumpIf(CallACS("BackpackScepterCheck", 0, 0, 0) == 1, "SpawnScepter") CSDL A 0 A_DropItem("CombatSaddlebag", 1) Stop SpawnGarand: CSDL A 0 A_DropItem("GarandUnlocker", 1, 256) CSDL A 0 A_JumpIf(CallACS("BackpackScepterCheck", 0, 0, 0) == 1, "SpawnScepter") CSDL A 0 A_DropItem("CombatSaddlebag", 1) Stop SpawnScepter: CSDL A 0 A_DropItem("ScepterUnlocker", 1, 256) CSDL A 0 A_DropItem("CombatSaddlebag", 1) Stop } }

I have the chances set to max right now for testing.
The CVars I'm using for this are user variables, because the same options controls whether the unlockable shows up in the map or if you spawn with it, and I don't want to make everyone in a multiplayer game (or just me and my friend because he's the only on who would play this in mutliplayer) spawn with all the unlockables just because one person wants to.
And here are the ACS scripts I'm using for this:

script "BackpackRevolverCheck" (void) { int PlayerNum = 0; for(PlayerNum = 0; PlayerNum < 8; PlayerNum++) { if(getUserCVar(PlayerNum, "spawn_revolver") == 1) { setResultValue(1); terminate; } } setResultValue(0); } script "BackpackGarandCheck" (void) { int PlayerNum = 0; for(PlayerNum = 0; PlayerNum < 8; PlayerNum++) { if(getUserCVar(PlayerNum, "spawn_garand") == 1) { setResultValue(1); terminate; } } setResultValue(0); } script "BackpackScepterCheck" (void) { int PlayerNum = 0; for(PlayerNum = 0; PlayerNum < 8; PlayerNum++) { if(getUserCVar(PlayerNum, "spawn_scepter") == 1) { setResultValue(1); terminate; } } setResultValue(0); }

With this setup, nothing happens. I loaded into a test map at least 15 times with the CVars set to 1, and only the backpacks dropped. None of the unlockables did.
I defined all the CVars and the items to drop, and other scripts/DECORATE actors can find them.
I am horrible with ACS, so I can't see what I'm doing wrong. Maybe one of you can, though?
Jarewill
 
 
Posts: 1855
Joined: Sun Jul 21, 2019 8:54 am

Re: Spawn Item Alongside Preexisting Item

Post by Jarewill »

The first jump doesn't happen because the engine skips the first frame, either use the NoDelay keyword there or include an empty TNT1 A 0 frame first.
However copying your code, it works fine for me, could you provide an example snippet of your project?

Alternatively, you could use GetCVar in DECORATE with server CVars.
If you define your CVars as server instead of user, you can then do this: A_JumpIf(GetCVar("spawn_revolver"),"SpawnRevolver")
JossTheFox
Posts: 32
Joined: Sat Jun 19, 2021 6:35 am
Preferred Pronouns: She/Her

Re: Spawn Item Alongside Preexisting Item

Post by JossTheFox »

Jarewill wrote: Fri Mar 08, 2024 5:20 pm The first jump doesn't happen because the engine skips the first frame, either use the NoDelay keyword there or include an empty TNT1 A 0 frame first.
However copying your code, it works fine for me, could you provide an example snippet of your project?

Alternatively, you could use GetCVar in DECORATE with server CVars.
If you define your CVars as server instead of user, you can then do this: A_JumpIf(GetCVar("spawn_revolver"),"SpawnRevolver")
Okay, I feel really stupid now. I just booted my mod up and tested it again, and it seems like I somehow forgot to set the other CVars? I had spawn_revolver set, but the other two were just default.
But, I'll go ahead and add a frame, then! Thank you :)
peewee_RotA
Posts: 407
Joined: Fri Feb 07, 2014 6:45 am

Re: Spawn Item Alongside Preexisting Item

Post by peewee_RotA »

I spawn 2 weapons in HRPG during the PostBeginPlay virtual function:

HRpgWeapon.zs

Code: Select all

const EXTRA_SPAWN_DIST = 20.0;

class HRpgWeapon : HereticWeapon
{
	class<Actor> extraSpawnItem;
	property ExtraSpawnItem : extraSpawnItem;
	
	override void PostBeginPlay()
	{
		//If spawning additional items and not an owned item (not in inventory)
		if (ExtraSpawnItem && ExtraSpawnItem != "" && !Owner)
		{
			let randomX = random(EXTRA_SPAWN_DIST * -1.0, EXTRA_SPAWN_DIST);
			let randomY = random(EXTRA_SPAWN_DIST * -1.0, EXTRA_SPAWN_DIST);
			let newItem = Spawn(ExtraSpawnItem, (Pos.X + randomX, Pos.Y + randomY, Pos.Z));

			ExtraSpawnItem = "";
		}
		
		Super.PostBeginPlay();
	}
...
HRpgPhoenixRod.zs

Code: Select all

class HRpgPhoenixRod : NonHeathenWeapon replaces PhoenixRod
{
	Default
	{
		+WEAPON.NOAUTOFIRE
		Weapon.SelectionOrder 2600;
		Weapon.Kickback 150;
		Weapon.YAdjust 15;
		Weapon.AmmoUse 1;
		Weapon.AmmoGive 2;
		Weapon.AmmoType "PhoenixRodAmmo";
		Weapon.Sisterweapon "HRpgPhoenixRodPowered";
		Inventory.PickupMessage "$TXT_WPNPHOENIXROD";
		Tag "$TAG_PHOENIXROD";
		
		HRpgWeapon.ExtraSpawnItem "HRpgMaul";
	}
...

https://github.com/cabbruzzese/hrpg/blo ... pon.zs#L15
Post Reply

Return to “Scripting”