[ZSCRIPT]Ideas for containers
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: 537
- Joined: Wed Dec 22, 2021 7:02 pm
- Graphics Processor: Intel (Modern GZDoom)
- Location: Medellin, Colombia
[ZSCRIPT]Ideas for containers
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?
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?
-
-
- Posts: 1822
- Joined: Sun Jul 21, 2019 8:54 am
Re: [ZSCRIPT]Ideas for containers
Your first idea of using TIDs to tell what a container should drop can be done using an ActorIterator.
For example:
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;
}
}
-
- Posts: 145
- Joined: Fri Jun 03, 2022 11:31 am
- Graphics Processor: Not Listed
Re: [ZSCRIPT]Ideas for containers
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.
-
- Posts: 1337
- Joined: Tue Jul 15, 2003 4:18 pm
Re: [ZSCRIPT]Ideas for containers
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'.
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.
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;
}
}
-
- Posts: 537
- Joined: Wed Dec 22, 2021 7:02 pm
- Graphics Processor: Intel (Modern GZDoom)
- Location: Medellin, Colombia
Re: [ZSCRIPT]Ideas for containers
Wow, thanks everyone for the answers and example code.
So that I can see what was in the container before I gobble it up
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.
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?
Perfect! I'm playing around with this example. I added this line: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.
Code: Select all
if (thing is "inventory") inventory(thing).droptime = 70 + random(0,30);
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.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.
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.
Oh, yes, I knew there was a way to pass a string. I forgot about user variables, great tip!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.
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?
-
-
- Posts: 1822
- Joined: Sun Jul 21, 2019 8:54 am
Re: [ZSCRIPT]Ideas for containers
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)".
-
- Posts: 537
- Joined: Wed Dec 22, 2021 7:02 pm
- Graphics Processor: Intel (Modern GZDoom)
- Location: Medellin, Colombia
Re: [ZSCRIPT]Ideas for containers
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"
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"
-
- Posts: 537
- Joined: Wed Dec 22, 2021 7:02 pm
- Graphics Processor: Intel (Modern GZDoom)
- Location: Medellin, Colombia
Re: [ZSCRIPT]Ideas for containers
Solution: The Used() method needs to return true when the actor has been successfully used, this will stop the "use tracer" from continuing
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.
-
- Posts: 1337
- Joined: Tue Jul 15, 2003 4:18 pm
Re: [ZSCRIPT]Ideas for containers
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.
-
- Posts: 537
- Joined: Wed Dec 22, 2021 7:02 pm
- Graphics Processor: Intel (Modern GZDoom)
- Location: Medellin, Colombia
Re: [ZSCRIPT]Ideas for containers
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.
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:
-
- Posts: 1337
- Joined: Tue Jul 15, 2003 4:18 pm
Re: [ZSCRIPT]Ideas for containers
Very nice effect!
-
- Posts: 878
- Joined: Tue May 07, 2019 12:24 pm
- Graphics Processor: nVidia with Vulkan support
Re: [ZSCRIPT]Ideas for containers
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.
then just have a loot table/spawner list for items.