NAME
NetHack::PriceID - identify NetHack items using shopkeepers
VERSION
version 0.05
SYNOPSIS
use NetHack::PriceID 'priceid';
print join ', ', priceid(
type => '?',
amount => 100,
in => 'sell',
);
# amnesia, create monster, earth, taming
DESCRIPTION
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 priceid
script.
FUNCTIONS
No functions are exported by default. Any of the following functions may be exported in the usual manner.
priceid PARAMHASH
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:
- type => scroll|ring|wand|...|?|=|/|... (required)
-
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.
- amount => INT (required)
-
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. - in => buy|sell|base (default: base)
-
The type of operation.
base
assumes theamount
is the base price.buy
assumes theamount
is the amount of money the shopkeeper is charging you for the item.sell
assumes theamount
is the number of Zorkmids the shopkeeper is willing to give you in exchange for the item. - charisma => 3..25 (required for 'buy')
-
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.
- out => base|names|both (default: names)
-
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. - tourist => BOOL (default: false)
-
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.
- dunce => BOOL (default: false)
-
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.
- angry => BOOL (default: false)
-
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.
- quan => INT (default: 1)
-
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_buy PARAMHASH
Same as priceid
except with a default of in => 'buy'
.
priceid_sell PARAMHASH
Same as priceid
except with a default of in => 'sell'
.
priceid_base PARAMHASH
Same as priceid
, which does have a default of in => 'base'
, but I cannot abide inconsistency.
EXAMPLES
- Selling
-
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')
- Buying with mods
-
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!
TODO
- User-defined item tables
-
This would be mostly useful for Slash'EM and Sporkhack. Does Slash'EM even use the same cost calculations? Probably.
- Ignore trivial identifications
-
Yes, we know that
an unlabeled scroll
is blank paper, andclear potion
is water. We usually don't need the module to report these. - How much would this item cost?
-
This is already implemented, somewhat, it's just hidden in
priceid_buy
andpriceid_sell
. It should be factored out and made into API. - Parse the actual NetHack output
-
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).
- Ignore items I already know
-
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.
SEE ALSO
AUTHOR
Shawn M Moore <code@sartak.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2014 by Shawn M Moore.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.