20 May 2018 Tagged: eulorac++

Being newly satisfied with state of target selection I proceeded to open up the throttle on my botting 'efforts'. I let the bot run for longer. I babysat it sometimes. I tried different things. I explored around different places. In the process I learned a few choice morsels truth.

One thing I learned is that while the weight limit on how much you can carry is a bottleneck to maximizing how much you can get from building claims, for tiny claims, the limited number of inventory slots for keys is a bigger one. You can always place the heavy-yet-stackable 'harvests' on a table. However, tables aren’t much help with keys which are light but don’t stack.

I noticed that foxybot has an option to leave the key in the claim, freeing you from the space burden. Eventually the key turns to dust and you can go back and pick up that valuable dust off the ground. This allows for alot more exploring.

I tried this approach for several days. It works well when you explore the same path, back and forth, over a long period of time because you’re right there when the key disintegrates and can scoop up the dust. But…​

But you have to pickup those little bits o' nothing of the ground manually. For me, that wouldn’t do. So I added so logic to foxybot to take note of all the little bits on the ground and try to pick them up.

Coincidence?
Figure 1. Foxybot bending over to pick something up 'seductively' at the moment I happen to look at the screen. Coincidence?

Oh man, it worked great! I almost wrote you a post about it. In fact, this was almost that post. I used it for days but there was a small problem that bugged me more than a small problem should.

The small problem is that you don’t really get back everything you drop on the ground. Some of it is bound to disappear before you get it. So you’re constantly leaking resources. My first work around was to just stockpile some LBN and not really worry about the leak. But then later, after I burned through my reserves again. I didn’t want to do that again and the whole thing bugged me.

I realized that I don’t like the principle of it. I have too many keys and they are clogging up my inventory and instead of dealing with the problem now, I’m kicking the can down the road. But when the problem comes around later it’s worse than it was before because there’s a cost to procrastination. It’s an unpredictiable cost, and sometimes a small cost. You incur an obligation to go back at some unknown future time and get what you used to own. Only now you hope that that game gods give it back to you, or at least most of it. And they do, mostly. But they could just as easily give it to another.

I have a view on procrastination and it is this: if you’re not sure that you’ll do a thing then procrastination is a signal that maybe it’s not the priority you thought it was. And the benefit of maybe-never having to do it outweighs the cost you will (definitely) pay for having put it off. But if you know for sure that you will do a thing then you must do it when it’s right there in front you and not put it off because it’s never going to get any easier, and if nothing else, you’ll pay the extra price of mental clutter for that open loop.

In that light, since I know I’m going to deal with this inventory problem, then I want to deal with it now. So I turned off 'key dropping' and let them fill my pack. I have to run back to storage to stow them relatively frequently, which is a pain. But as a result I have a guaranteed supply of LBN, which never runs out, or leaks even one single key. And I can explore any location I see fit at anytime, without concern for keeping implict promises to myself.

Luckily for you, I didn’t write this whole post just for the talky talk. I actually solved a problem, and I’m actually more pleased with myself than I have any right to be. So let me set the stage.

Here I am with an over stuffed backpack that’s got to be drained of keys regularly. That’s not the worst of it though. And maybe I even oversold how good this approach is because…​ since keys don’t stack, when you put them in storage you have to click once for each key. With a full inventory that’s almost 80 clicks to unload. Now, while they are stowed they will crumble, but they don’t magically crumble into stacks so you have to click once for each LBN to get it back out: another 80 clicks. But pulling from storage to inventory has a noticable delay, maybe about a second (for me anyway). So that’s hundreds of painful clicks.

I opened the game yesterday and thought, "I dun wanna clicky clicky." I looked at the "Exchange All" button on the storage window and I thought, "I wish there was an ALL ALL button that stores ALL the keys and returns me ALL my LBN".

data/gui/storage.xml
<widget_description> (1)
<widget name="StorageWindow" factory="pawsStorageWindow" visible="no" movable="yes" style="New Standard GUI">

    <frame x="100" y="100" width="640" height="400" border="yes" />
    <title resource="Scaling Title Bar" text="Storage" align="left" close_button="yes"/>

    <widget name="Transact" factory="pawsButton" id="100" tooltip="Exchange items">
        <frame x="580" y="10" width="48" height="48" border="no" />
        <bgimage resource="MerchantTrade" alpha="0" />
    </widget>

     <widget name="TransactAll" factory="pawsButton" id="110" tooltip="Exchange all items">
       <frame x="580" y="62" width="48" height="48" border="no" />
       <bgimage resource="MerchantTrade" alpha="0" />
    </widget>

    <widget name="AllLabel" factory="pawsTextBox">
            <frame x="580" y="100" width="48" height="20" />
            <font name="reteprelieum.ttf" r="246" g="223" b="166" size="8" scalefont="no" />
            <text string="ALL" horizAdjust="CENTRE" />
    </widget>

     <widget name="TransactSingle" factory="pawsButton" id="120" tooltip="Exchange one item">
       <frame x="580" y="114" width="48" height="48" border="no" />
       <bgimage resource="MerchantTrade" alpha="0" />
    </widget>

    <widget name="SingleLabel" factory="pawsTextBox">
            <frame x="580" y="150" width="48" height="20" />
            <font name="reteprelieum.ttf" r="246" g="223" b="166" size="8" scalefont="no" />
            <text string="SINGLE" horizAdjust="CENTRE" />
    </widget>

+    <widget name="TransactAllAll" factory="pawsButton" id="111" tooltip="Exchange all items with this name">
+      <frame x="580" y="170" width="48" height="48" border="no" />
+      <bgimage resource="MerchantTrade" alpha="0" />
+   </widget>
+
+   <widget name="AllAllLabel" factory="pawsTextBox">
+           <frame x="580" y="218" width="48" height="20" />
+           <font name="reteprelieum.ttf" r="246" g="223" b="166" size="8" scalefont="no" />
+           <text string="ALLALL" horizAdjust="CENTRE" />
+   </widget>
1 Skip all that stuff up there, new stuff at the bottom.

That adds the button and the label.

src/client/gui/pawsstoragewindow.h(68)
-   void TradeSelectedItem( bool all = false, bool single = false );
+   void TradeSelectedItem( bool all = false, bool single = false, bool allall = false );
src/client/gui/pawsstoragewindow.cpp(51)
/////////////////////////////////////////////////////////////////////////////
//  GUI BUTTON IDENTIFIERS
/////////////////////////////////////////////////////////////////////////////
        #define CATEGORY_LIST         10
        #define ITEM_LIST             11
        #define EXCHANGE_AMT          100
        #define EXCHANGE_ALL          110
+       #define EXCHANGE_ALL_ALL      111
        #define EXCHANGE_SINGLE       120
        #define VIEW_ITEM             150
        #define WITHDRAW_RADIO_BUTTON 1000
        #define STORE_RADIO_BUTTON    2000
src/client/gui/pawsstoragewindow.cpp(368)
-void pawsStorageWindow::TradeSelectedItem(bool all, bool single)
+void pawsStorageWindow::TradeSelectedItem(bool all, bool single, bool allall)
 {
    pawsListBoxRow* row = itemsBox->GetSelectedRow();
    selectedItem = itemsBox->GetSelection();
    if ( row == NULL )
	{
        return;
	}

+	if (allall)
+	{
+		csString selectedRowItemName = GetColumnText(row, 5);
+		csHash<csString, csString> matchingRowItems;
+
+		// cache id and count of all 'name matching' rows
+		for(int i = 0; i < itemsBox->GetRowCount(); i++)
+		{
+			pawsListBoxRow* currentRow = itemsBox->GetRow(i);
+			csString currentRowItemName = GetColumnText(currentRow, 5);
+			if (currentRowItemName == selectedRowItemName)
+			{
+				csString currentId = GetColumnText(currentRow, 4);
+				csString currentRowItemCount = GetColumnText(currentRow, 0);
+				matchingRowItems.PutUnique(currentId, currentRowItemCount);
+			}
+		}
+
+		// trade each of the cached matches
+		csHash<csString, csString>::GlobalIterator iter(matchingRowItems.GetIterator());
+
+		while (iter.HasNext()) {
+			csString currentId;
+			csString count = iter.Next(currentId);
+			DoTrade(atoi(count),selectedRowItemName, currentId);
+		}
+		return;
+	}
    // If the merchant only has 1 item or if we want to trade all, no need to request the count from the user
    if (atoi(GetColumnText(row, 0)) == 1 || all || single)
    {
            DoTrade(single?1:atoi(GetColumnText(row, 0)),GetColumnText(row, 5), GetColumnText(row, 4));
            return;
    }

    currentItem = GetColumnText(row,5);
    currentID   = GetColumnText(row,4);

    pawsNumberPromptWindow::Create("Enter count", -1, 1, atoi(GetColumnText(row, 0)),
                                   this, "Count" );
 }

THAT, my friends, is the added code for an ALL ALL button.

And THIS is what it looks like in action:

When I say 'All', you say 'All'

That is slick as shit. And if you needed someone to tell you that, you’re in the right place!

Who’s yo daddy?

Daniel P. Barron - 2018-05-21 05:23:31

I’ve probably left hundreds of thousands if not millions of keys in claims. Cool fix. Can’t say I’m in a hurry to try it, but many noobs will thank you!

hanbot - 2018-06-09 06:53:17

This was a pleasure to read and a neat fix idea, changes went smoothly over here. If you can figure out how to make storage eat/spit large (i.e., overweight-causin') chunks at a time in addition to the "all all" feature, it’d be a…​huge timesaver, definitely #1 on my botting wishlist atm.

Mocky - 2018-06-10 02:38:19

Daniel P. Barron: yeah, I’m all about making the noob life easier, for 'practical' reasons, or was it self-serving reasons.

hanbot: that’s a good idea. I’ve started to feel some of that pain myself. I’ve added that to the pipeline.

Also, beware the use of this powerful All All button. I’ve recently become aware that it is basically spamming the server with a potentially large number of requests and no rate limit. I’ve stopped using it for that reason with anything more than 10 items.

Also in the pipeline is a domestication of this wild feature.


Add a Comment