Jump to content

Changing max ammo values via DECORATE (or via some other ZDoom based solution)


Arsinikk

Recommended Posts

So I've run into a bit of a pickle... So I feel like some extra explanation is necessary.

 

I have an MBF21 WAD that I'd like to get working in Zandronum. Problem is that Zandronum doesn't support DEHEXTRA, so even though I have all the DeHackEd converted to DECORATE, it crashes because it can't find the replaced actors such as "deh_actor_172".

 

Technically I could just put like "Actor ExampleActor 30010", but then in GZDoom, it will complain with error messages like "actors ExampleActor and deh_actor_172 have doomednum 30010".

 

So I thought of a "brilliant" idea of adding a DEHSUPP lump to force all ZDoom based ports to not read DeHackEd and only read the DECORATE. This almost worked beautifully, until I ran into this issue:

 

The DeHackEd includes this line:

Ammo 0 (Bullets)
Max ammo = 250

 

And well, through researching many topics, it seems that there's no easy way to change the max values of existing ammo types in ZDoom ports except for in DeHackEd? I think the main issue is that I'd have to replace the "clip" ammo type with like a "clipnew" actor...

 

However the main issue is the statusbar doesn't update with the new ammo type. I guess I could circumvent this with a new SBARINFO lump, but I really don't like how it would break basically any third party statusbar mod.

 

Anyone have any ideas for dealing with this? As what I thought of my solution to disable the DeHackEd, seems to not have an equivalent in ZDoom ports.

 

 

Bonus question:

I guess if I'm also asking this, I should ask how you'd convert sound effect volumes from DeHackEd into ZDoom ports as well?:

Sound 77 (bspact)
Zero/One = 0
Value = 24

Share this post


Link to post

Perhaps for the Max Ammo you could use the ACS SetAmmoCapacity function in LOADACS Enter & Respawn player scripts.

 

EDIT: It probably requires some additional scripting to account for Backpacks, since the function makes no distinction by itself alone.

Edited by Worst

Share this post


Link to post
59 minutes ago, Worst said:

Perhaps for the Max Ammo you could use the ACS SetAmmoCapacity function in LOADACS Enter & Respawn player scripts.

 

 EDIT: It probably requires some additional scripting to account for Backpacks, since the function makes no distinction by itself alone.

I feel like I'm really close actually... I've actually got the player starting with the new ammo capacity. The only minor problem I currently have is that it requires grabbing two backpacks for it to change the AmmoCapacity higher.

 

Here's the code I have:

 

DECORATE:

ACTOR NewBackpack : CustomInventory replaces Backpack
{
	Height 26
	Inventory.PickupMessage "Picked up a backpack"
	States
	{
	Spawn:
		BPAK A -1
		Stop
	Pickup:
		TNT1 A 0 ACS_NamedExecuteWithResult("BackpackAdjust",0,0,0,0)
		Stop
	}
}

 

ACS:

bool playerbackpack[8] = { FALSE };

script "BackpackAdjust" (void)
{
	if (playerbackpack[PlayerNumber()])
	{
		if (GetAmmoCapacity("Clip") < 500)
		{
			SetAmmoCapacity("Clip", 500);
		}
	}
	else
    {
		playerbackpack[PlayerNumber()] = TRUE;
    }
}

script 998 ENTER
{
	if (GetAmmoCapacity("Clip") > 250)
    {
		playerbackpack[PlayerNumber()] = TRUE;
	}
	else
    {
		SetAmmoCapacity("Clip", 250);
	}
}

script 999 RESPAWN
{
	playerbackpack[PlayerNumber()] = FALSE;
}

 

The other minor problem that I may look into is pressing IDKFA or entering "give all" in the console, does not raise the bullets to 500 and defaults to 400, unless you've already grabbed a backpack. Tbh that's probably not something I'll be able to tweak, so if you cheat then I guess you'll have slightly less bullets :P

Share this post


Link to post
11 hours ago, Arsinikk said:

Technically I could just put like "Actor ExampleActor 30010", but then in GZDoom, it will complain with error messages like "actors ExampleActor and deh_actor_172 have doomednum 30010".

If that does what you want in Zandro, maybe put it into zandronum_patch.wad, add a note in .txt and call it a day? Corruption goes with that approach, and that wad has your name on the author list, so I feel weird suggesting that :)

Share this post


Link to post
44 minutes ago, Doomy__Doom said:

If that does what you want in Zandro, maybe put it into zandronum_patch.wad, add a note in .txt and call it a day? Corruption goes with that approach, and that wad has your name on the author list, so I feel weird suggesting that :)

It's funny that you mention Corruption, cuz this is actually for that. I've been working on finalising the standalone release of Hellcinerator (MAP15) using the resource of the final Corruption WAD when I found quite a few DECORATE things were incorrect, and so I've been fixing them. So we're going to have to have an update specifically for ZDoom based ports anyway.

 

I've never really been happy with having a separate patch, especially since it's only supposed to be for Zandro and old ZDoom ports. I recently learned of DEHSUPP while working on Hell Revealations which actually gave me the idea of possibly eliminating a separate patch altogether, which seems like a win-win scenario for everyone, since then everyone can just use one file and not have to worry about if they need a patch or not.

 

Plus typically I find that many people don't actually read text files anyway :P

 

Regardless, I think I'm really close to solving the ammo solution via DECORATE and ACS anyway.

Edited by Arsinikk

Share this post


Link to post

I think I've solved it, although I think the ACS code could probably be simplified a bit...

 

Adding "SetAmmoCapacity("Clip", 500);" in the else statement of the "BackpackAdjust" script fixed it. It kinda makes sense cuz before it would only apply the new Ammo Capacity when it did the check again (by grabbing another backpack) when "playerbackpack[PlayerNumber()]" was true.

 

Hmm... I'm actually kinda confused about the part in the script "BackpackAdjust" that has the just "if (playerbackpack[PlayerNumber()])" line. I assume it would be a check if the player is one of the 8 players set by the bool variable at the top, but still a little confused cuz apparently the example on the ZDoom wiki works (what this script is based on).

 

Something about the script seems slightly off, and I think it can be revised a bit more.

 

Revised script:

bool playerbackpack[8] = { FALSE };

script "BackpackAdjust" (void)
{
	if (playerbackpack[PlayerNumber()])
		if (GetAmmoCapacity("Clip") < 500)
		{
			SetAmmoCapacity("Clip", 500);
			SetAmmoCapacity("Shell", 100);
			SetAmmoCapacity("RocketAmmo", 100);
			SetAmmoCapacity("Cell", 600);
		}
	}
	else
	{
		playerbackpack[PlayerNumber()] = TRUE;
		SetAmmoCapacity("Clip", 500);
		SetAmmoCapacity("Shell", 100);
		SetAmmoCapacity("RocketAmmo", 100);
		SetAmmoCapacity("Cell", 600);
	}
	GiveInventory("Clip", 10);
	GiveInventory("Shell", 4);
	GiveInventory("RocketAmmo", 1);
	GiveInventory("Cell", 20);
}

script "BackpackLevelCheck" ENTER
{
	if (GetAmmoCapacity("Clip") > 250)
	{
		playerbackpack[PlayerNumber()] = TRUE;
	}
	else
	{
		SetAmmoCapacity("Clip", 250);
	}
}

script "BackpackRespawnReset" RESPAWN
{
	playerbackpack[PlayerNumber()] = FALSE;
}

 

Edit - almost forgot that I needed to also make the backpack give ammo as well as raise the thresholds.

Edit 2 - downside with adding items this way to the backpack is that it is not doubled in Nightmare or ITYTD.

 

Edit 3 - found that if I add items using the ACS backpack script it will adhere to the double ammo rule of Nightmare or ITYTD... so just reverted the DECORATE code and added it to ACS instead.

Edited by Arsinikk

Share this post


Link to post

Couldn't you eliminate checking for backpack when picking it up, after all it's just directly setting the numbers so there shouldn't be a problem with doing it multiple times?

 

Also, maybe it would be more elegant to do this via the Ammo class instead?

 

Quote

Ammo.BackpackAmount amount

The amount of this ammo type received from a backpack.

Ammo.BackpackMaxAmount amount

The maximum amount of this ammo type that can be carried with a backpack.

 

Share this post


Link to post
7 minutes ago, magicsofa said:

Couldn't you eliminate checking for backpack when picking it up, after all it's just directly setting the numbers so there shouldn't be a problem with doing it multiple times?

 

Also, maybe it would be more elegant to do this via the Ammo class instead?

Sorry took me a little while to think through this.

 

The problem with this method is that it requires creating a new clip ammo type to replace the clip actor.

 

This would mean I'd have to create a new SBARINFO lump to track the new ammo value and any hud mods would not work with the new ammo type.

 

I highlighted the issues I had with this approach here:

14 hours ago, Arsinikk said:

think the main issue is that I'd have to replace the "clip" ammo type with like a "clipnew" actor...

 

However the main issue is the statusbar doesn't update with the new ammo type. I guess I could circumvent this with a new SBARINFO lump, but I really don't like how it would break basically any third party statusbar mod.

 

Share this post


Link to post

I think you could do this without using Decorate at all, by using a script like this/this script:

Script "MaxAmmoEnter"   ENTER   { ACS_NamedExecuteAlways("MaxAmmoSpawn", 0); }
Script "MaxAmmoRespawn" RESPAWN { ACS_NamedExecuteAlways("MaxAmmoSpawn", 0); }
Script "MaxAmmoSpawn" (void)
{
	// Using -1 here to force updating the Ammo capacity on spawn.
	int prev_backpack = -1;

	// Run this script as long as the player is alive
	while (GetActorProperty(0, APROP_Health) > 0)
	{
		// Note: Backpack count is always either 0 or 1.
		int backpack = CheckInventory("Backpack");

		// Only do this when backpack status changes.
		if (prev_backpack != backpack)
		{
			prev_backpack = backpack;

			if (backpack)
			{
				SetAmmoCapacity("Clip"      , 500); // 400 in vanilla
				SetAmmoCapacity("Shell"     , 100); // 100 in vanilla
				SetAmmoCapacity("RocketAmmo", 100); // 100 in vanilla
				SetAmmoCapacity("Cell"      , 600); // 600 in vanilla
			}
			else // if no backpack
			{
				SetAmmoCapacity("Clip"      , 200); // 200 in vanilla
				SetAmmoCapacity("Shell"     ,  50); // 50 in vanilla
				SetAmmoCapacity("RocketAmmo",  50); // 50 in vanilla
				SetAmmoCapacity("Cell"      , 300); // 300 in vanilla
			}
		}

		Delay(1);
	}
}

This also works without messing with boolean arrays(and thus not limiting the script to a specific amount of players), since it just checks directly whether the player has the backpack.

Share this post


Link to post
13 minutes ago, Worst said:

I think you could do this without using Decorate at all, by using a script like this/this script:



 

You are a fucking acs genius!

 

Yes, this is an amazing implementation. It's honestly the replacing of the backpack that was causing alot of problems. But this is a much better script (that like you said isn't limited to any amount of players).

 

The only minor thing I'd say is that the default clip ammo should be 250, but I just fixed that so it's no biggy.

It even mostly works with give all / IDKFA - max ammo is set to 500, but only 400 bullets are given.

 

Thanks so much for this. It's a much better way of dealing with max ammo counts. :)

Edited by Arsinikk

Share this post


Link to post
15 hours ago, Arsinikk said:

Bonus question:

I guess if I'm also asking this, I should ask how you'd convert sound effect volumes from DeHackEd into ZDoom ports as well?:


Sound 77 (bspact)
Zero/One = 0
Value = 24

So first off, it seems like GZDoom/ZDoom doesn't actually support patching sounds in this manner in Dehacked. I checked latest GZDoom code, and it has this comment, and the code just silently ignores all the Sound definitions:

// The only remotely useful thing Dehacked sound patches could do
// was change where the sound's name was stored. Since there is no
// real benefit to doing this, and it would be very difficult for
// me to emulate it, I have disabled them entirely.

static int PatchSound (int soundNum)
{

I also checked out the old ZDoom 1.21 source code from 1999, and it ignores them just the same. So it's probably not been supported in any version ever since either.

Also from what little documentation I could quickly find about patching sounds in this manner, it appears that the "Value" property is for the relative priority of the sound, not the sound volume. But perhaps your code was just an example. According to Eternity dehacked docs, the property for sound volume would be "Zero 3".

Either way, if it's sound volume that you want to change, this seems to be possible with a SNDINFO lump, using the $volume command. And the "Zero/One" dehacked property can probably be recreated with SNDINFO $singular or $limit commands. Though there doesn't seem to be a command for making an alreardy singular sound not singular anymore.

Share this post


Link to post
13 minutes ago, Worst said:

So first off, it seems like GZDoom/ZDoom doesn't actually support patching sounds in this manner in Dehacked. I checked latest GZDoom code, and it has this comment, and the code just silently ignores all the Sound definitions:

Ah actually you just reminded me that dehacked "value" for sound definitions is actually the sound priority, as vanilla would only be able to play a certain amount of sounds at a time. It makes sense that gzdoom would ignore this since it doesn't exactly have a limit on how many sounds can be played at once.

 

13 minutes ago, Worst said:

it appears that the "Value" property is for the relative priority of the sound, not the sound volume.

My bad. Yeah it doesn't really need to be added then.

 

13 minutes ago, Worst said:

And the "Zero/One" dehacked property can probably be recreated with SNDINFO $singular or $limit commands.

I may look into this however for some certain sounds used in the wad since some are meant to be full volume everywhere in the map.

 

^ ignore this I had a brain fart.  It's singular or plural.

 

Thanks for doing some research in the DEHACKED sound thing as it's really helpful to know that gzdoom just ignores that in general.

Edited by Arsinikk

Share this post


Link to post

So, for decorate, you need to find the ammo definitions, here: https://zdoom.org/wiki/Classes:Doom#Ammo

 

Then you need to create new ammo actors, which will have changed the maxamount values.

So, for example, rocket. Base class looks like this:

ACTOR RocketAmmo : Ammo
{
  Inventory.PickupMessage "$GOTROCKET" // "Picked up a rocket."
  Inventory.Amount 1
  Inventory.MaxAmount 50
  Ammo.BackpackAmount 1
  Ammo.BackpackMaxAmount 100
  Inventory.Icon "ROCKA0"
  States
  {
  Spawn:
    ROCK A -1
    Stop
  }
}

To change the value, just do this:

ACTOR myNewRocketAmmo : Ammo replaces RocketAmmo
{
  Inventory.PickupMessage "$GOTROCKET" // "Picked up a rocket."
  Inventory.Amount 1
  Inventory.MaxAmount 500
  Ammo.BackpackAmount 1
  Ammo.BackpackMaxAmount 1000
  Inventory.Icon "ROCKA0"
  States
  {
  Spawn:
    ROCK A -1
    Stop
  }
}

So, the important part here is the 'replaces' keyword used after the parent definition, as this basically tells gzdoom to replace actor RocketAmmo with the myNewRocketAmmo.

Share this post


Link to post
On mardi 14 novembre 2023 at 4:35 PM, Arsinikk said:

I recently learned of DEHSUPP while working on Hell Revealations which actually gave me the idea of possibly eliminating a separate patch altogether, which seems like a win-win scenario for everyone, since then everyone can just use one file and not have to worry about if they need a patch or not.

The people for whom it's not a win is the GZDoom developers because that's one less mod with which to test proper DEHACKED support.

 

9 minutes ago, ramon.dexter said:

So, for decorate, you need to find the ammo definitions, here: https://zdoom.org/wiki/Classes:Doom#Ammo

Yeah but it's awful because all that's wanted is to change the ammo amount, and you can't change just that. You need to change the entire ammo type. As a result, you need to also change the entire weapons so that they use the new ammo types. Then you need to change the player class so that it uses the new weapon types. Then you need to change the status bar code so it uses the new ammo types, too. Also while doing all these changes, you completely break compatibility with any sort of gameplay mod.

 

Changing ammo properties has always been one of the weak points of DECORATE; something it's been really awful at doing.

Share this post


Link to post
14 hours ago, Gez said:

The people for whom it's not a win is the GZDoom developers because that's one less mod with which to test proper DEHACKED support.

I emphasise with this point of view, but unfortunately as a mapper, my main goal is to get my WAD working with as many ports as possible. With the current WAD working even on the discontinued ZDoom without a patch, I see that as a win when it comes to the player. My perspective always comes from the mapper or player, so I can see how it's less of a win for source port developers. However this is the exact same reason I will almost always use DECORATE over ZScript, since only GZDoom supports ZScript. It's the unfortunate truth when trying to support as many ZDoom-based ports as possible.

 

We mainly want this WAD to be at least compatible with Zandronum since it has multiplayer support. ZDaemon support is far too complicated to implement in this WAD as I don't even know if it would have enough states available via Heretic / Hexen frames via DEHSUPP. Not even mentioning the MBF21 specific codepointers that are used. We are lucky that DECORATE pretty much has equivalents to most MBF21 codepointers.

 

This specific case is a bit different since it's MBF21 which is a very new format, but often my WAD projects are Vanilla projects so getting those WADs to work with every port possible is the best outcome. You'd be surprised how difficult it is to get some Vanilla stuff working correctly in ZDoom ports (such as ghost monsters or using jank donut functionality).

Share this post


Link to post
14 hours ago, Arsinikk said:

I emphasise with this point of view, but unfortunately as a mapper, my main goal is to get my WAD working with as many ports as possible. With the current WAD working even on the discontinued ZDoom without a patch, I see that as a win when it comes to the player. My perspective always comes from the mapper or player, so I can see how it's less of a win for source port developers. However this is the exact same reason I will almost always use DECORATE over ZScript, since only GZDoom supports ZScript. It's the unfortunate truth when trying to support as many ZDoom-based ports as possible.

 

We mainly want this WAD to be at least compatible with Zandronum since it has multiplayer support. ZDaemon support is far too complicated to implement in this WAD as I don't even know if it would have enough states available via Heretic / Hexen frames via DEHSUPP. Not even mentioning the MBF21 specific codepointers that are used. We are lucky that DECORATE pretty much has equivalents to most MBF21 codepointers.

 

This specific case is a bit different since it's MBF21 which is a very new format, but often my WAD projects are Vanilla projects so getting those WADs to work with every port possible is the best outcome. You'd be surprised how difficult it is to get some Vanilla stuff working correctly in ZDoom ports (such as ghost monsters or using jank donut functionality).

 

GZDoom Supports MBF21. ZDoom, LZDoom and Zandronum do not. 

 

In the case of Zandronum Decorate syntax you are dealing with an older form of Decorate that uses now deprecated versions of commands that in GZDoom. Aka its Middle English vs Old English but still mostly the same. The GOOD part is that GZDoom can usually play anything that runs on Zandronum.

So in the case of Zandronum, you'll need to replace all the special actors that your MBF file would cover. Ramon Dexter covered the Ammo question perfectly. Any other non-vanilla actor would also have to be covered, 

 

Decorate is a hugely powerful language even though it may not seem like it. Its designed to be flexible. The important thing to remember is that Inheritance makes things much faster if the base is of the special actor is going to be similar to the vanilla counterpart. The inheritance will copy the base actor and then you just change the parts you want changed to be different. That way you dont need to write out an entire complete actor block. 

 

ACTOR myNewShell : Shell replaces shell
{
  Inventory.Amount 2
  Inventory.MaxAmount 20
  Ammo.BackpackMaxAmount 50
}


ACTOR myNewShellbox : Shellbox replaces shellbox
{
  Inventory.Amount 10
}

 

Basically this is a good shorthand for how to quickly make new ammo types and amounts quickly.

Edited by kalensar

Share this post


Link to post
4 hours ago, kalensar said:

Ramon Dexter covered the Ammo question perfectly.

 

lol AGAIN... this was already discussed multiple times, I know because I was the first one to not read

Share this post


Link to post
1 hour ago, magicsofa said:

 

lol AGAIN... this was already discussed multiple times, I know because I was the first one to not read

 

How many ways are there to change a lightbulb? Depends on if you're using a torque wrench, a blow dryer or having to blow the glass from scratch.

 

Anyways, Each version of doing the same task is different from each other on a technical level. ACS, Full new decorate actor , or inherited edit decorate actor are all just different techniques towards the same goal. Just because they all perform the same task doesn't mean the syntax to arrive there is identical with each other.

Share this post


Link to post

@kalensar They don't perform the same task, in fact your code doesn't work at all because only actors that inherit directly from the Ammo type can use the MaxAmount properties. Furthermore if that was rectified by inheriting from Ammo and thus creating a whole new ammo type, then the status bar will not show the new ammo type without modification. And doing that would mess up other status bar mods which is very common as it's only a cosmetic change... so yeah DECORATE is out

Share this post


Link to post
12 minutes ago, magicsofa said:

@kalensar They don't perform the same task, in fact your code doesn't work at all because only actors that inherit directly from the Ammo type can use the MaxAmount properties. Furthermore if that was rectified by inheriting from Ammo and thus creating a whole new ammo type, then the status bar will not show the new ammo type without modification. And doing that would mess up other status bar mods which is very common as it's only a cosmetic change... so yeah DECORATE is out

 

 Not arguing. Everything I wrote is direct application straight from zdoom wiki. No need to have a sour attitude over a language you clearly don't like. If its not your cup of tea then put some sugar in it. Chocolate works too. 

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...