Shop Inventory Alias/Trigger?

Posted by Kuldaj on Fri 17 Jul 2015 04:26 AM — 7 posts, 25,900 views.

USA #0
So I am looking for a way to comb through a shop's inventory in my mud, looking for items of a certain quality, and then when it finds the item or reaches the end then it stops.

So just for an example lets say I am looking for a sword with a 100% Condition and the shop I am at has 50 of the swords. But they are in now way sorted by condition. Currently I have to manually type "inspect 1.sword", "inspect 2.sword", etc... I am looking for an alias that I can type in that will search through all the swords and then stop when it either reaches one of the condition OR runs out of items to inspect.

So the line to stop the search based on meeting the condition would be:

Size: * Condition: perfect (100%)

and the line to stop it because you ran out of items to inspect would be:

* tells you 'I don't sell that -- try 'list' '

The main problem I am having is I can't seem to find the way to make an alias/trigger that will basically continue counting and filling in the # part of the inspect command.

Help? Guidance?
Australia Forum Administrator #1
Template:faq=37
Please read the MUSHclient FAQ - point 37.
USA #2
Unless I am just not seeing something that doesn't seem like it would help with what I am trying to do. I am not trying to record my shop's inventory, but search each item in a shop for a specifix condition/quality of item.

I just can't figure out the command to increase the # in the command "inspect #.item".

So basically an alias like "finditem *".
Which will then send "inspect 1.%1" in to the mud, followed by "inspect 2.%1" , then "inspect 3.%1", etc.

And if any item comes up with the line
"Size: * Condition: perfect (100%)"
or I get the message
"* tells you 'I don't sell that -- try 'list' ' "
the inspecting would stop.

I don't need to capture multiple lines at once, and record it, I am just trying to search through multiples of the same item looking for one of a specific condition. I just can't find a good way to make the # in the inspect command increase by one each time.
Australia Forum Administrator #3
Hmm, I see. Can you copy and paste some actual MUD output to help me guide you? Go to a shop, find some swords, and do manually what you want the alias/trigger to do, and paste the results here.
USA #4
Okay thanks! Hope we can figure this out.

Here is the log. Obviously sadly this shop didn't have any 100% items, which is why it can get difficult to find sometimes.

Log File said:


[ 9:30am ] <1995/1995HP 702/773MP 162MV> Exits:N (#4 Hecate Way)
look
#4 Hecate Way
  Swords: a Fencer's Friend
Wracks line the side and back walls, all with bare bladed swords of every
description and type.  Near the front of the stall, a bald headed mul
stands, waiting to help.

 [Exits: north  ]
A rugged looking mul stands here.

[ 9:30am ] <1995/1995HP 702/773MP 162MV> Exits:N (#4 Hecate Way)
list
[Lv Blues Silver Qty] Item
[ 5     0   1522  8 ] a bronze great sword
[25     0  16240 14 ] a fine alloy great sword
[15     0   4060 42 ] a steel great sword
[ 8     0   1827 39 ] an iron long sword
[ 5     0   1522  6 ] a bronze great sword
[27     0  25375  5 ] a mithril broadsword
[51    13   9750  3 ] a grand arcanium sword

[ 9:30am ] <1995/1995HP 702/773MP 162MV> Exits:N (#4 Hecate Way)
inspect 1.grand
Object 'grand arcanium sword' is type weapon, extra flags none.
Weight is 9, value is 540000, level is 51.
The object is made of metal.
Weapon type is sword.
Damage is 4d10 (average 22).
Condition: excellent (95%)
Crafted By: Saiboth
Crafted By: Lothaw
Crafted By: Nathrak
Crafted By: Nazirah
Crafted By: Morbazan
Crafted By: Grumf

[ 9:30am ] <1995/1995HP 702/773MP 162MV> Exits:N (#4 Hecate Way)
inspect 2.grand
Object 'grand arcanium sword' is type weapon, extra flags none.
Weight is 9, value is 540000, level is 51.
The object is made of metal.
Weapon type is sword.
Damage is 4d10 (average 22).
Condition: excellent (95%)
Crafted By: Saiboth
Crafted By: Lothaw
Crafted By: Nathrak
Crafted By: Nazirah
Crafted By: Morbazan
Crafted By: Grumf

[ 9:30am ] <1995/1995HP 702/773MP 162MV> Exits:N (#4 Hecate Way)
inspect 3.grand
Object 'grand arcanium sword' is type weapon, extra flags none.
Weight is 9, value is 540000, level is 51.
The object is made of metal.
Weapon type is sword.
Damage is 4d10 (average 22).
Condition: excellent (95%)
Crafted By: Saiboth
Crafted By: Lothaw
Crafted By: Nathrak
Crafted By: Nazirah
Crafted By: Morbazan
Crafted By: Grumf

[ 9:30am ] <1995/1995HP 702/773MP 162MV> Exits:N (#4 Hecate Way)
inspect 4.grand
Felidor the Mul tells you 'I don't sell that -- try 'list' '



So basically to keep inputting the "inspect #.item" command until I either receive the tell with "I don't sell that" OR an item come up with (100%). I have got the gist of the IF statements I would need. Just not how to tie it in to a command that will continue to inspect items of a certain type, until either they are found or I run out of items to inspect.
Amended on Sat 18 Jul 2015 11:50 PM by Nick Gammon
Australia Forum Administrator #5
This is easiest done with a coroutine, which lets you loop, sending things and checking the response.


<aliases>
  <alias
   match="finditem *"
   enabled="y"
   send_to="12"
   sequence="100"
  >
  <send>
require "wait"

-- backslashes have to be entered as four backslashes (sigh)
re = "(Condition: excellent ~((?P&lt;percent&gt;~d+)%%~)|I don't sell that)"
re = string.gsub (re, '~', '\\\\')

wait.make (function ()

  -- try 100 items

  for i = 1, 100 do
    
    -- inspect it
    Send ("inspect " .. i .. ".%1")

    -- wait for a response or not found, within 10 seconds
    line, wildcards = wait.regexp (re, 10)

    if not line then
      ColourNote ("orange", "", "Timeout finding item.")
      return
    end -- if

    -- if not found, give up    
    if string.match (line, "I don't sell that") then
      ColourNote ("orange", "", "Item not found.")
      return  -- done
    end -- if not found

    -- found, check percentage
    if wildcards.percent == "100" then
      ColourNote ("orange", "", "Item found! - " .. i .. ".%1")
      return
    end -- found one

  end -- for

end) 
</send>
  </alias>
</aliases>



Template:pasting
For advice on how to copy the above, and paste it into MUSHclient, please see Pasting XML.



The important part of the above is the script:


require "wait"

-- backslashes have to be entered as four backslashes (sigh)
re = "(Condition: excellent ~((?P<percent>~d+)%%~)|I don't sell that)"
re = string.gsub (re, '~', '\\\\')

wait.make (function ()

  -- try 100 items

  for i = 1, 100 do
    
    -- inspect it
    Send ("inspect " .. i .. ".%1")

    -- wait for a response or not found, within 10 seconds
    line, wildcards = wait.regexp (re, 10)

    if not line then
      ColourNote ("orange", "", "Timeout finding item.")
      return
    end -- if

    -- if not found, give up    
    if string.match (line, "I don't sell that") then
      ColourNote ("orange", "", "Item not found.")
      return  -- done
    end -- if not found

    -- found, check percentage
    if wildcards.percent == "100" then
      ColourNote ("orange", "", "Item found! - " .. i .. ".%1")
      return
    end -- found one

  end -- for

end) 


What that does is loop around, trying items 1 to 100, sending "inspect x.item" where x is the current number.

It then does a wait.match with a timeout, looking for both the line "Condition" or "I don't sell that".

Depending on what it gets, it tries again, or exits.

More explanation here: http://www.gammon.com.au/forum/?id=4957
USA #6
Works perfectly so far, thanks a ton.

Only had to change the word after Condition: to a wildcard as well so that it record properly for items labeled excellent/poor/broken/perfect.

Which I changed it to the following. It seems to work properly.

-- backslashes have to be entered as four backslashes (sigh)
re = "(Condition: (?P<condition>.*) ~((?P<percent>~d+)%%~)|I don't sell that)"
re = string.gsub (re, '~', '\\\\')

Thanks so much for your help.