Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: [1] 2

Author Topic: Is there a DFHack script to merge stacks or the contents of barrels?  (Read 6565 times)

kane_t

  • Bay Watcher
    • View Profile

I've found myself in a situation where I have a barrel full of single strawberries or plump helmets, which my brewer then turns into multiple barrels each containing 5 units of alcohol.  It's a bit of a waste.  Seems like if a hauler brings a barrel with 5 units of strawberry wine to a stockpile with another barrel containing 5 units of strawberry wine, they should just pour the contents into the existing barrel and leave the one they were carrying empty.

I was thinking of trying to make a script that just checks if there are multiple barrels of the same kind of alcohol in a stockpile and, if so, merges their contents up to some sensible maximum, by removing the contents of one barrel and just marking up the stack size in another barrel.  Or, solving the problem on the other end by just looking at a single barrel (of fruit, in this case) and merging the stacks within it (so all my strawberries [2] become a single strawberries [26]). 

But this seems like such an obvious problem, I figured somebody must have already made a script or plugin to do it.  Does anybody know of such a plugin?  I tried looking around but haven't been able to find anything.
Logged

Arx

  • Bay Watcher
  • Iron within, iron without.
    • View Profile
    • Art!
Re: Is there a DFHack script to merge stacks or the contents of barrels?
« Reply #1 on: June 16, 2015, 01:37:06 pm »

None mentioned in the readme or the most recent thread, so I guess not. It might be some kind of horribly thorny problem though.
Logged

I am on Discord as Arx#2415.
Hail to the mind of man! / Fire in the sky
I've been waiting for you / On this day we die.

milo christiansen

  • Bay Watcher
  • Something generic here
    • View Profile
Re: Is there a DFHack script to merge stacks or the contents of barrels?
« Reply #2 on: June 17, 2015, 12:03:25 pm »

It's a kinda hard problem to solve, how do you decide which items to merge?
Logged
Rubble 8 - The most powerful modding suite in existence!
After all, coke is for furnaces, not for snorting.
You're not true dwarven royalty unless you own the complete 'Signature Collection' baby-bone bedroom set from NOKEAS

kane_t

  • Bay Watcher
    • View Profile
Re: Is there a DFHack script to merge stacks or the contents of barrels?
« Reply #3 on: June 17, 2015, 01:49:34 pm »

It's a kinda hard problem to solve, how do you decide which items to merge?

Well, the simplest solution would be to just leave control up to the user.  Have them select an item in a container, and merge any items of the same type in the stockpile into it up to a maximum stack size (and container capacity).  There are already scripts that work on the selected item, you could just c/p that functionality.

The more complex, automated approach would be to, whenever a dwarf stores a container in a stockpile, for each element in the container, search the stockpile for a stack of that item of less than maximum size in a container which isn't full and, if found, merge into the other container up until the maximum stack size or container capacity.  Continue until either all the items in the stack have been moved out of the barrel, or there are no valid destinations for merging, then move on to the next element of the container.

I took a quick look at the data structure for stockpiles in dfhack, and it looks like stack size is just an int you could increment, and you can iterate the contents of a stockpile pretty easily.  The only complication I can see is whether it's possible (or desirable) to straight-up remove an item from a container.  How well the game handles something like that.
Logged

milo christiansen

  • Bay Watcher
  • Something generic here
    • View Profile
Re: Is there a DFHack script to merge stacks or the contents of barrels?
« Reply #4 on: June 20, 2015, 12:26:10 pm »

Doing it automatically could kill fps with large stockpiles, this would need testing. Manually would be possible, even fairly easy, but would be a lot of micro management to make it really effective.

Annother option is to make a "stacker" workshop, as long as the workshop is powered it will take an item from it's inputs (using the Rubble powered workshop API, which is the easiest system available for making automated workshops) and try to stack it up to a user settable limit using other items at it's inputs. This would be easy to do, but I don't have much time right now, so we will see.
Logged
Rubble 8 - The most powerful modding suite in existence!
After all, coke is for furnaces, not for snorting.
You're not true dwarven royalty unless you own the complete 'Signature Collection' baby-bone bedroom set from NOKEAS

kane_t

  • Bay Watcher
    • View Profile
Re: Is there a DFHack script to merge stacks or the contents of barrels?
« Reply #5 on: June 20, 2015, 02:07:34 pm »

I cooked up most of a quick manual script myself this morning, but haven't had time to test it.  I'll let you know how it goes when I get a chance to finish it.  Personally, for me, the main thing it's a problem with is alcohol, so the manual approach works just fine for my purposes.  If other people want a copy of the finished script I can fancy it up a bit with some user-settable options for maximum stack size and such and post it here.

I wouldn't think the automated approach would cause performance problems, as long as there's an Event for "item stored in stockpile."  Actually iterating stockpile items and increasing or decreasing their stack_size should be trivial, and depending on how fast dfhack's items.remove() function is, removing empty stacks shouldn't be a problem.  It's just finding out when a dwarf puts a barrel in a stockpile. 

I wasn't able to find documentation for plugins (and didn't feel like going through the source) but one of the events exported to Lua is "onJobCompleted," and a quick skim through the job class suggests that it's possible to just check a flag to see if it's a hauling job.  I'd just have to look into it in more detail to see if it's possible to extract the item that was hauled from that event.
Logged

milo christiansen

  • Bay Watcher
  • Something generic here
    • View Profile
Re: Is there a DFHack script to merge stacks or the contents of barrels?
« Reply #6 on: June 20, 2015, 02:16:53 pm »

I was thinking of having to iterate all items in the stockpile looking for a merge candidate, if no mergable items exist and you are doing a lot of hauling it could be a real fps drag (if the stockpiles are really large). Obviously this needs to be tested to see if it is actually the case, it may not be a problem.

I like my automated workshop idea, but it would need some modifying to prevent problems with rotting...
Logged
Rubble 8 - The most powerful modding suite in existence!
After all, coke is for furnaces, not for snorting.
You're not true dwarven royalty unless you own the complete 'Signature Collection' baby-bone bedroom set from NOKEAS

Roses

  • Bay Watcher
    • View Profile
Re: Is there a DFHack script to merge stacks or the contents of barrels?
« Reply #7 on: June 20, 2015, 02:28:32 pm »

I don't know if there is an event for "item stored in stockpile", but I would just have it run every X number of ticks. Otherwise if you have 10 dwarves bringing something at roughly the same time to a stockpile of 100 items, none of them stackable, you are going to run through the same 100 items 10 times. I don't think it would make much of a fps as that is still a relatively small number of things to check, but it is inefficient. Where as checking every X number of ticks shouldn't be too bad.

You also have an issue of dwarves going to get an item from a stockpile and then it suddenly being gone. Not sure how much of an impact that would have.
Logged

milo christiansen

  • Bay Watcher
  • Something generic here
    • View Profile
Re: Is there a DFHack script to merge stacks or the contents of barrels?
« Reply #8 on: June 20, 2015, 02:43:24 pm »

Well, my stockpiles generally have closer to 10000 items...
Logged
Rubble 8 - The most powerful modding suite in existence!
After all, coke is for furnaces, not for snorting.
You're not true dwarven royalty unless you own the complete 'Signature Collection' baby-bone bedroom set from NOKEAS

kane_t

  • Bay Watcher
    • View Profile
Re: Is there a DFHack script to merge stacks or the contents of barrels?
« Reply #9 on: June 20, 2015, 03:22:06 pm »

I don't know if there is an event for "item stored in stockpile" [...]
You also have an issue of dwarves going to get an item from a stockpile and then it suddenly being gone. Not sure how much of an impact that would have.

Isn't that the onJobCompleted event?  Or does "store item in stockpile" not count as a job for the purposes of that event?  (Or, I guess, is it only available though the Lua interface or not possible to extract the stored item...)  If the onJobCompleted event works, that also solves the problem of dwarves cancelling a job because the item disappeared: presumably, the event is fired on the same tick that the item is stored, before another dwarf has a chance to claim the item.  Items can't be claimed while they're being hauled, after all, and in my experience it takes a few ticks before they become aware of a newly-available item.

Well, my stockpiles generally have closer to 10000 items...

Okay, yeah, that's a couple orders of magnitude beyond any fort I've gotten off the ground ;)

Still, I wouldn't expect it to be a big deal, since it's just iterating an array and doing straight integer comparisons.  Even if you need to do a couple pointer indirections/table lookups to get a pointer with the right type, it's nothing.  That's assuming you do it in C++ as a plugin, rather than in Lua, which might be slower.
Logged

milo christiansen

  • Bay Watcher
  • Something generic here
    • View Profile
Re: Is there a DFHack script to merge stacks or the contents of barrels?
« Reply #10 on: June 20, 2015, 03:30:47 pm »

You know you have a lot of items if when scrolling the stocks screen it pauses for up to a second when reaching prepared meals, logs, bars, or boulders...

And yes, it really does that. Makes using the stocks screen a real pain sometimes. Not sure how an automatic stacking script would react to such a fort, but it couldn't be good, particularly since all items are stored in one of 4 stockpiles... (the fort is only 10 years old, I hate to see what it would be like later in life)

More sane fortresses will probably be fine though.

Logged
Rubble 8 - The most powerful modding suite in existence!
After all, coke is for furnaces, not for snorting.
You're not true dwarven royalty unless you own the complete 'Signature Collection' baby-bone bedroom set from NOKEAS

Roses

  • Bay Watcher
    • View Profile
Re: Is there a DFHack script to merge stacks or the contents of barrels?
« Reply #11 on: June 20, 2015, 03:52:02 pm »

You know you have a lot of items if when scrolling the stocks screen it pauses for up to a second when reaching prepared meals, logs, bars, or boulders...

And yes, it really does that. Makes using the stocks screen a real pain sometimes. Not sure how an automatic stacking script would react to such a fort, but it couldn't be good, particularly since all items are stored in one of 4 stockpiles... (the fort is only 10 years old, I hate to see what it would be like later in life)

More sane fortresses will probably be fine though.

Yes, but the stocks screen is actually displaying something, not just checking numbers, which will be much faster.

Just a quick check I did, a stockpile has a list of all barrels/bins/wheelbarrows in it. The dfhack.items.getContainedItems() command can then easily check for contained items, and you can check those against some list you have prepared. If you want to put even more work into it you can have a flag that says you have already checked a certain barrel/bin and not to check it again unless it has changed. Overall I can't see it having much of a performance impact, except for maybe if you used it on a fully grown fortress, but that would be a one time thing, and then would be much faster after it has merged all stacks. (But I could also be very wrong!)
Logged

kane_t

  • Bay Watcher
    • View Profile
Re: Is there a DFHack script to merge stacks or the contents of barrels?
« Reply #12 on: June 20, 2015, 06:01:00 pm »

Just a heads up, I just checked the onJobCompleted event exported to Lua and, for some reason, it doesn't report the completion of hauling jobs.  Not sure if that's intentional or a bug, though, or if it's just a limitation of the Lua interface's less sophisticated event handling.

Shame about that, because the job struct includes a vector of the items that were included in the job.  From the item you can get the container and stockpile, which would've made this a lot easier.
Logged

ldog

  • Bay Watcher
    • View Profile
Re: Is there a DFHack script to merge stacks or the contents of barrels?
« Reply #13 on: June 25, 2015, 02:30:30 pm »

PTW
I'm very interested in this, even if only for booze. I have been toying with the idea of making custom reactions for it, but it seems like too many places for it to go wrong.
Logged
Quote from: Dirst
For example, if you wanted to check if a unit was eligible to be a politician or a car salesman, you'd first want to verify that there is no soul present...

Quote from: gchristopher
The more appropriate question becomes, are they awesome and dwarven enough.

kane_t

  • Bay Watcher
    • View Profile
Re: Is there a DFHack script to merge stacks or the contents of barrels?
« Reply #14 on: June 26, 2015, 01:31:18 pm »

PTW
I'm very interested in this, even if only for booze. I have been toying with the idea of making custom reactions for it, but it seems like too many places for it to go wrong.

Then you're in luck, sorta, because I made some scripts that merge both plants and drinks manually.  The links to them and a description of their use is here, in the DFHack thread.  They aren't the most convenient ever, I'm afraid, but I don't have a ton of time right now to improve them.

I did, just now, upload the current version I've been using, which adds support for flour to combine_plants, and lets you specify a container or stockpile ID with -stockpile (for _plants and _drinks) and -container (for _plants).  That way, you can use the repeat script to run my combine scripts at a regular interval, if you want.  Anything more complex than that will have to wait until I have some free time.

If you notice any bugs, give me a shout and I'll fix them as I'm able.
Logged
Pages: [1] 2