Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: [DFHack][Script] automilk autoshear; encrust gems of any material via manager  (Read 5956 times)

Erendir

  • Bay Watcher
    • View Profile

Short version:

Place this script into your DF/hack/scripts folder (if for some reason not already there); run following in DFHack-console
Code: [Select]
repeat -time 1 -timeUnits days -command [ workorder ShearCreature ] -name autoShearCreature
repeat -time 1 -timeUnits days -command [ workorder MilkCreature ] -name autoMilkCreature
and enjoy having your manager automatically queue "Shear Animal" and "Milk Animal" work orders.

Longer version:

It always annoyed me there is no easy way to automate wool and milk production: there is no good trigger condition we can use (AFAIK). Additionally, while I appreciate the workflow plugin, I personally feel it shouldn't be necessary anymore with work order conditions from vanilla DF.

So here it is, consisting of 2 parts:
  • a core functionality to queue manager jobs (can do any jobs, like `orders` plugin);
  • functions to count creatures that can be milked or sheared.
Current most useful use-case: make it repeat "workorder ShearCreature" and "workorder MilkCreature" (see above).

If an amount is defined the work order is just queued.

Otherwise it determines amount needed -- currently only for ShearCreature and MilkCreature -- and then reduces it by outstanding identical work orders. Is it still greater 0, a new work order is created.

Other uses:
  • add an order to `EncrustWithGems` `finished_goods` using any material (since not specified):
Code: [Select]
workorder "{\"job\":\"EncrustWithGems\",\"item_category\":[\"finished_goods\"],\"amount_total\":5}"
  • same as `workorder MilkCreature` but with an item condition ("at least 2 empty buckets"):
Code: [Select]
workorder "{\"job\":\"MilkCreature\",\"item_conditions\":[{\"condition\":\"AtLeast\",\"value\":2,\"flags\":[\"empty\"],\"item_type\":\"BUCKET\"}]}"
The main differences with `orders`-plugin are ignoring order's state (`is_active`, `amount_left` etc) and dynamically determining and adjusting of amount_total depending on other orders.
« Last Edit: December 29, 2020, 08:59:45 am by Erendir »
Logged

PatrikLundell

  • Bay Watcher
    • View Profile
Re: [DFHack][Script] automilk autoshear animals
« Reply #1 on: February 22, 2020, 09:13:12 am »

For milking you probably should check there are available buckets (excluding those locked up in the hospital to be admired and the ones containing left over water).
Logged

Erendir

  • Bay Watcher
    • View Profile

For milking you probably should check there are available buckets (excluding those locked up in the hospital to be admired and the ones containing left over water).

I personally prefer spam about missing buckets -- it will let me know I need to do something. But with the newest version of the script there is a way.

Code: [Select]
repeat -time 1 -timeUnits days -command [ workorder "{\"job\":\"MilkCreature\",\"item_conditions\":[{\"condition\":\"AtLeast\",\"value\":2,\"flags\":[\"empty\"],\"item_type\":\"BUCKET\"}]}" ] -name autoMilkCreatureBucket
Logged

Taras

  • Bay Watcher
    • View Profile

What script I need, if I want milk venom from serpent man?
Logged

Erendir

  • Bay Watcher
    • View Profile

What script I need, if I want milk venom from serpent man?

Not this one. All this does is creating a generic "milk animal" work order (same as what you would normally achieve on the j-m-q screen).
Logged

mightymushroom

  • Bay Watcher
    • View Profile

I just experimented with this using PeridexisErrant's Starter Pack 0.47.04-r05 (which is not the absolute newest pack but I don't see any obvious changes when comparing my copy to the GitHub linked above) and have the following issues:


1) I don't know what's gone wrong, but MilkCreatures wants to schedule milking jobs for my male animals as well as the females. Tested on a fresh worldgen, fresh embark. Very verbose mode confirms the same 4 animal IDs as ShearCreature (2 male sheep, 2 female sheep) are also being picked up by MilkCreature. And also the two wagon-pulling horses, 1 male 1 female, both scheduled for milking (but, properly, not for shearing).

Edit: So, yeah. Poked a bit more and dfhack.units.isMilkable() returns true for the whole race if any caste is milkable. Something more specific is needed here.



2) If the most useful intended deployment is to schedule jobs using DFHack 'repeat' – or potentially other scripts that might call yours – then I feel that the default frequency ought to be one-time orders. Let the other script decide when to post the job(s) again according to whatever desired logic that script calculates.

In particular for the included 'MilkCreature' and 'ShearCreature' job types, the special feature here is to run the Lua that checks how many creatures are currently eligible. Creating 'Daily' jobs to milk or shear defeats that purpose by posting condition-less work orders that don't use any special logic after the first day when the desired number was verified by script.

I suppose I could change the frequency using the less beginner-friendly JSON input in my repeat script, but I don't understand why it isn't the default.
« Last Edit: May 29, 2020, 07:01:20 pm by mightymushroom »
Logged

Erendir

  • Bay Watcher
    • View Profile

1) I don't know what's gone wrong, but MilkCreatures wants to schedule milking jobs for my male animals as well as the females. Tested on a fresh worldgen, fresh embark. Very verbose mode confirms the same 4 animal IDs as ShearCreature (2 male sheep, 2 female sheep) are also being picked up by MilkCreature. And also the two wagon-pulling horses, 1 male 1 female, both scheduled for milking (but, properly, not for shearing).

Edit: So, yeah. Poked a bit more and dfhack.units.isMilkable() returns true for the whole race if any caste is milkable. Something more specific is needed here.
I opened an issue for this. It's probably possible to reimplement this function in Lua and adjust accordingly -- I'll look into in some time soon, I hope.

2) If the most useful intended deployment is to schedule jobs using DFHack 'repeat' – or potentially other scripts that might call yours – then I feel that the default frequency ought to be one-time orders. Let the other script decide when to post the job(s) again according to whatever desired logic that script calculates.

In particular for the included 'MilkCreature' and 'ShearCreature' job types, the special feature here is to run the Lua that checks how many creatures are currently eligible. Creating 'Daily' jobs to milk or shear defeats that purpose by posting condition-less work orders that don't use any special logic after the first day when the desired number was verified by script.

I suppose I could change the frequency using the less beginner-friendly JSON input in my repeat script, but I don't understand why it isn't the default.

I sense some confusion here, but maybe I'm wrong (or the script has yet another bug).
What calling `workorder MilkCreature` every day does is check how many ready-to-be-milked creatures are there, and in case their number is greater than 0, schedule that much (but only if not already scheduled). So you should only occasionally see scheduled `Milk Creature` jobs, not daily.

Also, since `repeat` script is external to this one, it already "Let the other script decide when to post the job(s) again". It's actually up to you how often do you want the check to be done. No need to switch to JSON in this case, f.e.
Code: [Select]
repeat -time 14 -timeUnits days -command [ workorder MilkCreature ] -name autoMilkCreatureschedules a check every 14 days instead.
Logged

mightymushroom

  • Bay Watcher
    • View Profile

Regarding 1), I should note that the same is true of "isShearable" and a couple other "is<Something>" functions nearby. It doesn't make a difference in vanilla because all castes of the shearable animals are actually shearable, unlike milking or egg laying. But a sufficiently determined demented modder could break it.

I wonder if the original intention was to find breeding pairs of certain types, say for autobutcher or some trading script? That's the only explanation I have for performing a caste tag check at the race level.

In my local copy I've snuck in "and uu.isFemale(u)"  for counting milk orders but this is something again that a modder could break.



Regarding 2)
Code: [Select]
repeat -time 14 -timeUnits days -command [ workorder MilkCreature ] -name autoMilkCreature
What will happen with that code is that every 14 days workorder does its thing: checks for creatures that need milking, reduces its count by any existing order(s), and then creates a new order for the remainder if any. So far this is exactly what I'm looking for.

By the current default, however, the form of the created order in the job manager will have the frequency to restart "Daily" if none of the nonexistent conditions are false. So for example, once my 3 cows and 4 pigs have been milked, the very next day the manager, not the script, will activate 7 milking jobs again. Unless it is an incredibly long walk between my pasture and my milking station, none of those animals will be ready for milking yet. Job cancellation ensues, and will happen every day until I manually erase the order from the manager's queue or it is time for milking again.

Even though workorder can cancel creating a new order when unneeded, I don't see any functionality that would remove or alter quantity on existing orders if they are too high. I'm not sure if this is a true bug or a difference in design philosophy that considers some other use-cases. For milking I believe it is less than ideal. When keeping a sufficiently large number of animals it could be true that a different set of 7 is ready for milking the next day, but not for small populations. Heaven help me on shearing with a 300 day regrowth interval. I understand and at least partially agree with the above rationale against checking for buckets: a bucket-related cancellation tells the overseer it's time to pay attention to fortress supplies. But a no animal available cancellation can be solved only with time and doesn't help the overseer one bit.



My practice: the way I have personally set up milking and shearing is to
Code: [Select]
repeat <some-other-stuff> workorder MilkCreature ; workorder ShearCreature <more-other-stuff> on a regular basis (1200 ticks, piggybacking on an pre-existing repeat for other purposes). After changing the default frequency in my local copy this generates "RunOnce" orders to milk/shear the number of creatures ready at the time of the check and once completed that order disappears from the manager's list. The next time the repeat executes workorder will perform the appropriate checks once again and order the correct number once again. Instead of the manager thinking we need to do that same number every day. With this absurdly frequent interval I'm surely checking more often than necessary, yet the auto-decrement ensures that jobs are never over-counted even if an earlier run is not completed before the current execution.

At least I think it works, I haven't gotten a chance to advance time very far yet.  :P
Logged

Erendir

  • Bay Watcher
    • View Profile

so, 1) is fixed in dfhack by BenLubar (alongside other similar things), but I have no idea when it will be released.

As of 2), you are absolutely right, the default should've been `OneTime`, not `Daily` -- latter making sense only for more complicated stuff using JSON, but in that case, it's actually trivial to just override the default. I have no memory whatsoever why I thought Daily is a good default (and even wrote so in the documentation...) When/if this pull request is resolved OneTime will become the default.
Logged

mightymushroom

  • Bay Watcher
    • View Profile

Thanks!  :)

It's a useful script already and I hope it grows as a supplement to the vanilla manager!
Logged

Erendir

  • Bay Watcher
    • View Profile

Thanks!  :)

It's a useful script already and I hope it grows as a supplement to the vanilla manager!

Well, I'm glad someone finds it useful  :)

I actually hope someday the vanilla manager will do everything we want and this script won't be necessary.

On another note, in case you find any other use-cases, please share them.
Logged

xzaxza

  • Bay Watcher
    • View Profile

Seems pretty good. I was just missing something like this the other day.
Logged
Known issues
You may get a dwarf that likes bugged stockpiles.

wooks

  • Bay Watcher
    • View Profile

PTW
Logged
In a game like Dwarf Fortress, going to the wiki being cheating is like saying bringing a parachute is cheating for skydiving.
"Has it been 4 days? Better check if my penis is still there again."