Page 1 of 1

[ZSCRIPT]Ideas for containers

Posted: Sat Sep 09, 2023 11:46 am
by Sir Robin
I want to create containers - you know, crates, boxes, barrels, chests, whatever - that when used or destroyed they spew out their contents. That part of the coding I can handle.
What I want to know is how to assign contents to a container. I could hard-code the contents, then have a subclass of the container for each item it might contain. That seems kinda excessive.
I'm thinking one way could be to put the content items outside the map, give them all a specific TID, and the container has that TID as an arg and when it's opened/destroyed it teleports all items with that TID to itself and spews them out.
Another way could be to set the string arg with a CSV of classes of items to be spawned on the container open/destruction event.
So obviously my goal here is to be able to set the container's content from a map editor.
Any ideas on the best way to do that?
I guess this might be similar to how you would give a baddie a key or some other quest item to drop when they die?

Re: [ZSCRIPT]Ideas for containers

Posted: Sat Sep 09, 2023 12:46 pm
by Jarewill
Your first idea of using TIDs to tell what a container should drop can be done using an ActorIterator.
For example:

Code: Select all

Class Container : Actor replaces TechLamp{
	bool empty;
	Default{Height 64;}
	States{Spawn: COLU A -1; Stop;}
	Override bool Used(Actor user){
		If(empty||args[0]==0){Return 0;} //If the container is empty or first arg is invalid, return
		ActorIterator i = level.CreateActorIterator(args[0]); //Create an actor iterator with a specified TID
		Actor thing;
		While(thing = i.Next()){
			If(thing){ //If a thing with the TID exists
				thing.SetOrigin(pos,0); //Move it to the container
				thing.vel=(frandom(-4,4),frandom(-4,4),frandom(4,8)); //And set the velocity
			}
		}
		empty=1; //Mark the container as empty
		Return 1;
	}
}

Re: [ZSCRIPT]Ideas for containers

Posted: Sat Sep 09, 2023 4:45 pm
by AshHouswares
Personally, I code containers the same way I code monsters. They drop an item of a designated type or value in their decorate / zscript code on destruction.

Re: [ZSCRIPT]Ideas for containers

Posted: Sat Sep 09, 2023 6:08 pm
by AFADoomer
If you are using UDMF maps you can use user variables to do this.

Declare a "user_dropitem" (or whatever you want to name it, as long as it starts with 'user_') variable in your Container actor, then use A_DropItem to spawn that class in the Death state.

You can set the value in the editor to the class name that you want to spawn. In Ultimate Doom Builder it's in the thing's 'Custom' tab'.

Code: Select all

Actor Container : Actor
{
	String user_dropitem;

	States
	{
		Death:
			/* other frames */
			 DEAD A 1 A_DropItem(user_dropitem);
			/* more frames */
			Stop;
	}
}
Alternatively, you could hard-code options that you select with one of the actor arguments, then use ZScript to manually spawn them when the actor is used/dies. I did this in Blade of Agony with the supply chests - it's an overly complicated example, but has some comments and might help.

Re: [ZSCRIPT]Ideas for containers

Posted: Mon Sep 11, 2023 9:03 pm
by Sir Robin
Wow, thanks everyone for the answers and example code.
Jarewill wrote: Sat Sep 09, 2023 12:46 pm Your first idea of using TIDs to tell what a container should drop can be done using an ActorIterator.
Perfect! I'm playing around with this example. I added this line:

Code: Select all

				if (thing is "inventory") inventory(thing).droptime = 70 + random(0,30);
So that I can see what was in the container before I gobble it up

AshHouswares wrote: Sat Sep 09, 2023 4:45 pm Personally, I code containers the same way I code monsters. They drop an item of a designated type or value in their decorate / zscript code on destruction.
This is what I meant when I said hard-coding, it's what I'm trying to avoid. I'd have to create an actor for each combination of container and contained object.
So for example, Box_HealthBonus, Box_ArmorBonus, Box_Stimpack, Box_BlueKey, Box_RedKey, etc, for each item
Then I have to create Crate_*, Barrel_*, Chest_*, Sack_*, etc for each container type.
Then if I want to have containers with 2 or 3 items, I have to create all those combinations. It's a whole lot of code, a whole lot of dehacked numbers, A whole lot to scroll through when looking to place an item on the map.

AFADoomer wrote: Sat Sep 09, 2023 6:08 pm If you are using UDMF maps you can use user variables to do this.

Alternatively, you could hard-code options that you select with one of the actor arguments, then use ZScript to manually spawn them when the actor is used/dies. I did this in Blade of Agony with the supply chests - it's an overly complicated example, but has some comments and might help.
Oh, yes, I knew there was a way to pass a string. I forgot about user variables, great tip!
I'd make it User_DropItems so I could give it a CSV list of items to pop out (just take in the string and break it up with split())
And thanks fot the link to the BoA container. I like how you use arg[0] to a reference to a predefined loot list or you can give it a custom item.
It's also a good example of how to handle keys, counted items, and attaching scripts. Excellent, thank you.


A question about something I'm noticing: So I put an override Used function on an actor and now it's able to be used. But if the actor is near a wall when it's used the player still makes a grunt noise like he's trying to open a door. How to fix that?

And another question, when scrolling inventory and I press the query key I get something like "CarriedStimpack (x3)" printed to the console. Can I change that output or is it hard-coded?

Re: [ZSCRIPT]Ideas for containers

Posted: Tue Sep 12, 2023 2:38 am
by Jarewill
Sir Robin wrote: Mon Sep 11, 2023 9:03 pm And another question, when scrolling inventory and I press the query key I get something like "CarriedStimpack (x3)" printed to the console. Can I change that output or is it hard-coded?
While I don't know how to fix the first problem, the second problem can be fixed by giving the item a Tag.
Query displays the item's tag, so if you give it Tag "Stimpack"; it will then display as "Stimpack (x3)".

Re: [ZSCRIPT]Ideas for containers

Posted: Sat Sep 16, 2023 6:20 am
by Sir Robin
Good tip, thanks.

But I'm looking for a way to override the text and put my own in there. So for example it could say "Stimpack (x3) - Use this to recover a little health" or "flashlight (x1) with 80% battery remaining"

Re: [ZSCRIPT]Ideas for containers

Posted: Fri Sep 22, 2023 8:24 pm
by Sir Robin
Sir Robin wrote: Mon Sep 11, 2023 9:03 pm A question about something I'm noticing: So I put an override Used function on an actor and now it's able to be used. But if the actor is near a wall when it's used the player still makes a grunt noise like he's trying to open a door. How to fix that?
Solution: The Used() method needs to return true when the actor has been successfully used, this will stop the "use tracer" from continuing
Sir Robin wrote: Mon Sep 11, 2023 9:03 pm And another question, when scrolling inventory and I press the query key I get something like "CarriedStimpack (x3)" printed to the console. Can I change that output or is it hard-coded?
Sir Robin wrote: Sat Sep 16, 2023 6:20 am I'm looking for a way to override the text and put my own in there. So for example it could say "Stimpack (x3) - Use this to recover a little health" or "flashlight (x1) with 80% battery remaining"
The "Query Item" feature binds to console command "invquery". There doesn't seem to be anywhere to override this and it can't be aliased. The only way seem to be to create a new query feature and bind it to another key.

Re: [ZSCRIPT]Ideas for containers

Posted: Sun Sep 24, 2023 11:38 am
by AFADoomer
Unfortunately, the 'invquery' console command is hard-coded to print the item's tag/name and amount... I don't think this could be easily changed in any universal way.

Re: [ZSCRIPT]Ideas for containers

Posted: Wed Sep 27, 2023 5:19 pm
by Sir Robin
I got it going, thanks to all for the help!

I made it so that you give the container a TID in args and it takes all actors with that TID as its contents. Then if the player USE it ingame, it displays it's contents above. If player backs away, the contents go back into the container, but if player USE again then contents are flung into the world to be picked up.
Spoiler:

Re: [ZSCRIPT]Ideas for containers

Posted: Wed Sep 27, 2023 5:21 pm
by AFADoomer
Very nice effect!

Re: [ZSCRIPT]Ideas for containers

Posted: Wed Sep 27, 2023 5:42 pm
by Dan_The_Noob
a container that is effectively an unmoving monster with the items spawned as a projectile is probably the quickest easiest way.
then just have a loot table/spawner list for items.