NetHack::PriceID - identify NetHack items using shopkeepers
use NetHack::PriceID 'priceid'; print join ', ', priceid( type => '?', amount => 100, in => 'sell', ); # amnesia, create monster, earth, taming
NetHack, the game of princes, has a large item-identification subgame. The quickest way to gauge how useful an item is is to "price identify" it. This involves trying to buy or sell the item in a store, which tells you its price. Item types (scrolls, potions, wands, etc) are each divided into about five price groups -- price IDing cuts down a large number of possible identities of an item.
The calculations for price IDing aren't that difficult, but making sure to get all the edge cases (such as trying to identify items while the shopkeeper is attacking you -- and charging you more money) can be twiddly.
This module also comes with a
No functions are exported by default. Any of the following functions may be exported in the usual manner.
This is the method most people will be using. It will transform an amount and other information into possible identities. Its arguments are passed as a hash:
The item type. Valid values are the type name or its glyph: scroll (?), ring (=), wand (/), amulet ("), spellbook (+), potion (!), tool ((), or armor ([). Tools are broken down further into bag, lamp, flute, and horn. Armor is broken down further into cloak, helmet, gloves, boots. Not specifying a type, or specifying an invalid type, will cause an error to be thrown.
The amount ("cost") of the item. How the priceid function interprets this amount is dependent on the
in parameter. Not specifying an amount will cause an error to be thrown.
The type of operation.
base assumes the
amount is the base price.
buy assumes the
amount is the amount of money the shopkeeper is charging you for the item.
sell assumes the
amount is the number of Zorkmids the shopkeeper is willing to give you in exchange for the item.
The charisma of the character. Base and sell prices are independent of charisma, so it's required only for buying. This will croak if you try to buy price-ID without setting the charisma.
The output format.
base will return 0, 1, or 2 possible base prices that the input can possibly be. Buying and selling always map to two prices, but usually one of those prices has no items, so it is not given.
names will return the actual names of the possible items.
both will return a list of array references with the first element of each being the base price, and following elements being the item names.
Determines whether the character suffers from the "tourist" surcharge. Shopkeepers (as they presumably do in real life) will charge extra if they think you're a tourist. Characters that are in the tourist class and less than experience level 15 suffer this charge. Also, any character that is wearing a Hawaiian shirt or T-shirt without body armor or cloak suffers this charge.
Determines whether the character suffers from the "dunce" surcharge. This applies to any character who is wearing a dunce cap. Whoops, should price ID those conical hats to filter for cornuthaums.
Determines whether the character suffers from the "angry shopkeeper" surcharge. If the shopkeeper is attacking you, you'll probably want to set this one to true. Warning: if you try to sell an item to an angry shopkeeper, they'll just take it. That doesn't help much for identification.
How many items in the stack you're buying/selling. Most people try to identify with only one item, but this is available if you take the path less trodden.
priceid except with a default of
in => 'buy'.
priceid except with a default of
in => 'sell'.
priceid, which does have a default of
in => 'base', but I cannot abide inconsistency.
You are selling an unknown ring and want to know what kind it may be. We have no unusual surcharges (and charisma is not needed when sell IDing).
"Wonotobo offers 75 gold pieces for your clay ring. Sell it?"; priceid(in => 'sell', type => 'ring', amount => 75); => ('aggravate monster', 'cold resistance', 'fire resistance', 'free action', 'gain constitution', 'gain strength', 'increase accuracy', 'increase damage', 'invisibility', 'levitation', 'poison resistance', 'regeneration', 'searching', 'see invisible', 'shock resistance', 'slow digestion', 'teleportation')
Well, that's an awful lot of hits. Let's just look at the actual base prices that we get back.
priceid(in => 'sell', type => 'ring', amount => 75, out => 'base'); => (150, 200)
Ah. So we are at one of those "could be two possible categories" sweet spots. So we continue dropping the ring until we get a different price (which will reflect a change in whether we get a random surcharge).
"Wonotobo offers 100 gold pieces for your clay ring. Sell it?"; priceid(in => 'sell', type => 'ring', amount => 100) => ('fire resistance', 'free action', 'levitation', 'regeneration', 'searching', 'slow digestion', 'teleportation')
This game has not been going well. This wizard has had his cloak of magic resistance stolen by a nymph. The conical hat that he hurriedly put on turned out to be a dunce cap. Furthermore, nothing is covering his cursed Hawaiian shirt. He has just found a store and is pricing the items in it. He picks up a wand...
"For you, most gracious sir; only 888 for this curved wand."; priceid(charisma => 9, in => 'buy', type => 'wand', dunce => 1, tourist => 1, amount => 888) => ('death', 'wishing')
He quickly zaps the wand, wishes for a cockatrice corpse with which to kill the shopkeeper, and turns to stone... oops, no gloves!
This would be mostly useful for Slash'EM and Sporkhack. Does Slash'EM even use the same cost calculations? Probably.
Yes, we know that
an unlabeled scroll is blank paper, and
clear potion is water. We usually don't need the module to report these.
This is already implemented, somewhat, it's just hidden in
priceid_sell. It should be factored out and made into API.
It'd be great if all we had to do is hand in the string
Wonotobo offers 30 gold pieces for your scroll labeled KIRJE. Sell it?
and have the module figure out the relevant bits. Also, possibly, the entire screen (so that charisma could be discerned).
You could pass in a list of items that you've already identified or ruled out, and the module would not include those in the list of possibilities.
Shawn M Moore,
Copyright 2007-2009 Shawn M Moore.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.