Groovy maid scripts

Forum for alternative clients, mods & discussions on the same.

Moderator: Phades

Groovy maid scripts

Postby Detharon » Thu Apr 24, 2014 6:00 pm

There's a very active thread with Union client scripts, but apparently almost nothing has been published for groovy maid, so analyzing some working examples is next to impossible. That's why I've decided to create this thread.

Info:
Here you can find some information about groovy maid engine.
It's bundled with Anemone client, with few improvements.

Here's my plowdrink script, as written in the description, it plows a single tile, drinks water, and gets more water from a well. To succesfully run it, you need a bucket, waterflask / waterskin, and a well in given radius (30 tiles by default).

Code: Select all
/* ====================================================================================================
   Simple script to burn hunger, it plows a single tile and drinks water.
   To properly works, it requires: A bucket, waterflask or waterskin, an accessible well.
   
   It will keep plowing, drinking water, and refilling water when needed.
   Stops working when hunger drops below 30% (default value) of very hungry bar.
   
   Although it uses a pathfinder, it may occasionally get stuck if there are too many items
   between the well and plowing place.
*///====================================================================================================

import java.util.*;
import java.lang.*;
import haven.event.*;
import haven.*;

// ==================================================
// Settings         
// ==================================================

// Script will look for a well in given radius
int wellRadius = 30;
// A stop condition, minimum value of very hungry bar
int minHunger = 30;

// ==================================================
// Some checks   
// ==================================================

Item cup;
Item bucket;
Gob well;
inv = maid.getInventory();
Coord pos = maid.getCoord();

// Checking for a waterflask / waterskin
if (hasItem("waterflask") == true) {
   cup = maid.getItems(inv, "waterflask")[0];
} else if (hasItem("waterskin") == true) {
   cup = maid.getItems(inv, "waterskin")[0];
} else {
   println("Waterflask or waterskin is missing.");
   return;
}

// Checking for a bucket
if (hasItem("bucket") == true) {
   bucket = maid.getItems(inv, "bucket")[0];
} else {
   println("Bucket is missing.");
   return;
}

// Looking for a well
well = maid.doAreaFind(wellRadius, "well");
if (well == null) {
   println("Well was not found.");
   return;
}

// ==================================================
// Main loop   
// ==================================================

// Will work until the hunger bar drops below the given value of very hungry bar

starving = checkStarvation(minHunger);

while (!starving) {
   if (maid.meterStamina.value < 50) {
      if (getWaterValue(bucket) < 1) {
         getWater(well, bucket); // If we're running out of water, get some
         bucket = maid.getItems(inv, "bucket")[0]; // Need to reload the dropped bucket
         maid.pathFind(pos, 6, false); // Return to previous place
      }
      
      drinkSome(cup, bucket);
      bucket = maid.getItems(inv, "bucket")[0]; // Need to reload the dropped bucket
   }
   
   maid.doAction("act", "plow"); // Time to plow!
   maid.doLeftClick(pos)
   maid.doRightClick(pos); // Get rid of plow icon
   maid.waitForTask();

   starving = checkStarvation(minHunger);
}
      
// ==================================================
// Helper functions         
// ==================================================

boolean checkStarvation(int minHunger) {
   if (maid.meterHunger.type == MeterEventObjectHunger.HungerType.VERY_HUNGRY && maid.meterHunger.value < minHunger) {
      return true;
   }
   return false;
}

void getWater(Gob well, Item bucket) {
   maid.pathFind(maid.getCoord(well), 6, false);

   Coord bucketplace = maid.getCoord(bucket);

   maid.doTake(bucket);
   maid.waitForGrab();
   maid.doInteract(well);
   
   Thread.sleep(4500); // Not event based, error-prone
   
   inv.drop(null, new Coord(bucketplace.x*32,bucketplace.y*32)); // meh
   maid.waitForItemCreate();
}

boolean hasItem(String itemName) {
   if (maid.getItems(inv, itemName).length != 0) return true;
   return false;
}

void drinkSome(Item cup, Item bucket) {
   Coord bucketplace = maid.getCoord(bucket);

   maid.doTake(bucket);
   maid.waitForGrab();
   maid.doInteract(cup, 1);
   inv.drop(null, new Coord(bucketplace.x*32,bucketplace.y*32));
   
   maid.doInteract(cup);
   menu = maid.waitForFlowerMenu();
   maid.doSelect(menu, "Drink");
   maid.waitForTask();

}

// Stolen, I mean, adapted from Anemone client code. Slightly modified. Lemme know if there's a better way to do that
double getWaterValue(Item bucket) {
   if (bucket.tooltip.indexOf('/') < 0) return 0;

   String valStr = bucket.tooltip.substring(bucket.tooltip.indexOf('(') + 1, bucket.tooltip.indexOf('/'));
   double val = Double.parseDouble(valStr);
}


Over time, I'll keep adding other scripts.
Last edited by Detharon on Thu Apr 24, 2014 8:54 pm, edited 1 time in total.
Detharon
 
Posts: 45
Joined: Sat Mar 26, 2011 2:16 pm

Re: Groovy maid scripts

Postby caz » Thu Apr 24, 2014 6:11 pm

thanks for making this :)
Image
User avatar
caz
 
Posts: 202
Joined: Fri Jul 16, 2010 7:27 pm

Re: Groovy maid scripts

Postby mvgulik » Sat Feb 28, 2015 7:53 pm

Just some Anemone script-related index.
* Limited to stuff in this topic.
* Order: Posted.
* Updates: Whenever I feel like it.

=== index ===

* plowdrink » Detharon » Apr 2014.
Code: Did not work for me on Anemone client. Seems incomplete. But was useful as example script.

* printing to area chat » romovs » Mar 2015.
Doc: In a nutshell. maid.doSayAreaChat("Hello World") only works with old chat-box enabled.

* getCropTypeNearCurrentLocation() » mvgulik » Apr 2015.
Code: Experimental crop detection code.

* fill_barrel_from_well() » mvgulik » May 2015.
Code: Taking the sting out of well clicking. [v0.2]

* session break detection. » mvgulik » May 2015.
Code: Running scripts could linger around in closed sessions, this can fix that.

* Open seedbag shuffle. » mvgulik » Juni 2015.
Code: Just for fun and giggles. [v0.1]

* getPlayerOrientation() » mvgulik » Juli 2015.
Code: working snippet. [v0.1]

* getTileCenter() » mvgulik » Juli 2015.
Code: working snippet. [v0.1]

* "Walk around object" experiment. » mvgulik » Aug 2015.
Code: working example. [v0.2]

--- Old post content ---
Anemone client.

Any help, or examples, on how to do some on-screen (game-window, not console) feedback in Anemone/Maid client. (either with @#Chat or some other way.)
The simpler the better, with plenty of info if possible, as I'm having two left hands when it comes to Java/Groovy or internal Haven.stuff.

(Scrounged some other script related topics, but I came up empty.)
Last edited by mvgulik on Fri Aug 14, 2015 12:38 pm, edited 7 times in total.
mvgulik
 
Posts: 3742
Joined: Fri May 21, 2010 2:29 am

Re: Groovy maid scripts

Postby mvgulik » Thu Mar 05, 2015 3:12 pm

Nothing so far. Bummer. O well.
mvgulik
 
Posts: 3742
Joined: Fri May 21, 2010 2:29 am

Re: Groovy maid scripts

Postby romovs » Thu Mar 05, 2015 5:47 pm

There is a method for printing to area chat:

Code: Select all
maid.doSayAreaChat("hello");


It only works if "use new chat" is enabled in the settings and doesn't work with the vanilla chat. Or maybe it's vice versa, can't recall...
User avatar
romovs
 
Posts: 1473
Joined: Sun Sep 29, 2013 9:26 am
Location: The Tabouret

Re: Groovy maid scripts

Postby shubla » Thu Mar 05, 2015 6:19 pm

Is it okay to make bot that spams something stupid and then afk with it somewhere?
Image
I'm not sure that I have a strong argument against sketch colors - Jorb, November 2019
http://i.imgur.com/CRrirds.png?1
Join the moderated unofficial discord for the game! https://discord.gg/2TAbGj2
Purus Pasta, The Best Client
User avatar
shubla
 
Posts: 13043
Joined: Sun Nov 03, 2013 11:26 am
Location: Finland

Re: Groovy maid scripts

Postby mvgulik » Thu Mar 05, 2015 9:33 pm

romovs wrote:There is a method for printing to area chat:

Code: Select all
maid.doSayAreaChat("hello");


It only works if "use new chat" is enabled in the settings and doesn't work with the vanilla chat. Or maybe it's vice versa, can't recall...

*big sigh*. So that's why it was trowing me a general error. I was using the wrong chat. :cry:

Thanks for the info.

---

shubla wrote:Is it okay to make bot that spams something stupid and then afk with it somewhere?

Duh ... *Checked user's posts* ... No. Wrong thread to, now shoo.
mvgulik
 
Posts: 3742
Joined: Fri May 21, 2010 2:29 am

Re: Groovy maid scripts

Postby mvgulik » Thu Mar 26, 2015 1:13 am

Anemone client.

Kinda bored with manual fishing for fishing data ...
Ergo: A other try to pry lose some more scripting related information.

How to go about getting character equipment data ?
Like ... character current equipped fishing pole setup.
mvgulik
 
Posts: 3742
Joined: Fri May 21, 2010 2:29 am

Re: Groovy maid scripts

Postby mvgulik » Thu Apr 02, 2015 9:26 pm

Pfew, finally something that seems to work.
Still WIP stage. Only stage I know.

Code: Select all
def getCropTypeNearCurrentLocation() {

   def range = 1.0;
   def target = '/plants/';
   def clip = 'gfx/terobjs/plants/';

   // excluded: tobacco, pumpkin.
   def crops = ['beetroot','carrot','flax','hemp','hops','onion','peas','pepper','poppy','tea','wheat','wine'];
   def cropdata = ['beetroot':[0,6,null],
            'carrot':[0,3,null],
            'flax':[3,0,'flaxfibre'],
            'hemp':[3,0,'flaxfibre'],
            'hops':[0,3,null],
            'onion':[0,3,null],
            'peas':[0,3,null],
            'pepper':[3,0,null],
            'poppy':[3,0,'flower-poppy'],
            'tea':[2,2,null],
            'wheat':[0,3,'straw'],
            'wine':[0,3,null]];

   def cord = maid.getCoord(maid.getPlayer());
   
   def crop_gob = maid.doAreaFind(cord, range, target);
   if (crop_gob == null){
      return null;
   };

   def crop_str = maid.getName(crop_gob);
   crop_str = crop_str.replace(clip, '');

   if (crops.contains(crop_str)) {
      def stage = crop_gob.getblob(0);
      return [crop_str,stage,cropdata[crop_str]];
   } else {
      return null;
   }
   
}

def output = getCropTypeNearCurrentLocation();
maid.doSay("output == " + output);
return

index
Last edited by mvgulik on Wed Jul 15, 2015 9:39 am, edited 2 times in total.
mvgulik
 
Posts: 3742
Joined: Fri May 21, 2010 2:29 am

Re: Groovy maid scripts

Postby mvgulik » Sun May 31, 2015 6:57 am

Anemone client.
Code: Select all
def Item fill_barrel_from_well(Gob well, Gob barrel, Item bucket) {
   // The only detectable change here is if the bucket changes.
   // This code don't cares if its a barrel, or a tanning tub.
   def bucket_pos_last = maid.getCoord(bucket);
   maid.doTake(bucket);
   maid.waitForGrab();
   def wdg = getDraggedItem();
   while (true){// untill bucket no longer empties.
      if (wdg != null && wdg.GetResName() != 'gfx/invobjs/buckete') {
         maid.doInteract(barrel);
         waitForEmptyBucket(wdg);
         if (wdg != null && wdg.GetResName() != 'gfx/invobjs/buckete') {
            maid.getInventory().drop(null, new Coord(bucket_pos_last.x*32,bucket_pos_last.y*32));
            bucket = maid.waitForItemCreate();
            maid.doRightClick(barrel);
            break;
         }
      }
      maid.doInteract(well);// waiting untill bucket fills up.
      while (wdg != null && wdg.GetResName() == 'gfx/invobjs/buckete'){
         Thread.sleep(250);
      }
   }
   return bucket;
}

def getDraggedItem() {
   if (!maid.isDragging()) {return null}
   def wdg_out = null;
   def Widget root = UI.instance.root;
   for (Widget wdg = root.child; wdg != null; wdg = wdg.next) {
      if (wdg.getClass() == haven.Item) {
         wdg_out = wdg
         break
      }
   }
   return wdg_out;
}

def void waitForEmptyBucket(wdg, int timeout=1000, int timestep=100) {
   def int baileout = timeout/timestep;
   while (wdg != null && wdg.GetResName() != 'gfx/invobjs/buckete') {
      baileout -= 1;
      if (baileout < 0) {break}
      Thread.sleep(timestep);
   }
}
[v0.2]: fixed weak point in code.
index
Last edited by mvgulik on Wed Jul 15, 2015 9:39 am, edited 2 times in total.
mvgulik
 
Posts: 3742
Joined: Fri May 21, 2010 2:29 am

Next

Return to The Wizards' Tower

Who is online

Users browsing this forum: Ahrefs [Bot] and 1 guest