Feature - Implemented Coin Master API

Veracity

Developer
Staff member
Over on this thread I wrote:

What about an API - a way to trade tokens for items via the various Coin Masters in CLI and/or ASH scripts without having to hardcode visit_url() calls.

- We need a way to visit specific stores
- We need a way to trade - buy or sell - specific items.
- Do we care about specifying which store to get specific items from? They are unambiguous, so far.

GValko wanted to sell stuff, to which I responded, "My suggestion: have a developer write a cli or ash command to interface with it. How about a Feature Request?"

Bale suggested:
It would be good to be able to query token types so that I could check to see if I have enough of them to acquire an item. It might be best if the token type returned was a string so it could be "store credit" or "meat".

string purchase_type(item)

I already added (without notice) a "boolean is_coinmaster_item( item )" function to ASH, like the existing "boolean is_npc_item( item )" function. Presumably, there should be a corresponding "int coinmaster_price( item )", like the existing "int npc_price( item )", where the returned int is the number of tokens.

The issue with tokens is that although some are items - and we look at inventory to see how many are available, on the coinmaster frame, or in "accessible" places, when using "acquire" - some are pseudo-items: dimes, quarters, game shoppe credits. For the latter, we have properties to keep the number available.

Perhaps we need a new type: $coinmaster[ big brother ], for example. Add "coinmaster item_coinmaster( item )" to get the (single) coinmaster that buys or sells the item. Add proxy fields to the $coinmaster: string token, boolean is_item, int available_tokens, and so on.

Alternatively, item_coinmaster returns a string(the coinmaster name), and we have a plethora of new functions: string coinmaster_token( string ), and so on.

I want to know how people would use this and design the API to fit the expected usage.
 

Bale

Minion
Well, if we are going to make a $coinmaster type with proxy fields (which I think a fantastic idea), then to find out what coinmaster is associated with an item the relevant function would be to_coinmaster().

if(to_coinmaster(doodad) == $coinmaster[none]) then an item is neither purchasable or sell-able at a coinmaster.

We might want both:
  • coinmaster to_coinmaster(item)
  • coinmaster to_coinmaster(string)
    The reason for the second is so that we can pass it a token type.
    Some tokens are strings and there might be times.
 

Veracity

Developer
Staff member
Well... I am not sure to_coinmaster( string ) should convert token to coinmaster datatype. I have coded up the $coinmaster datatype and defined that function as a name lookup: to_coinmaster( "b b" ) --> $coinmaster[ Big Brother ]. That is consistent with to_location, to_element, to_monster, and every other data type.

Here is what I have so far. I'll check it in, so people can play with it, but I don't have the rest of the API - a way to visit, buy, or sell, map item to coinmaster, map item to token price - there yet. That is undesigned, so far.

> ash to_coinmaster( "b b" )

Returned: Big Brother
token => sand dollar
item => sand dollar
property =>

> ash to_coinmaster( "dime" )

Returned: Dimemaster
token => dime
item => none
property => availableDimes
 

Bale

Minion
:D I'm happy with working with whatever commands you like, even if that was different from my expectation. I really like having the $coinmaster type and the proxy records though.

How about

  • boolean cash_in(item) - trades items to a coinmaster for credit/tokens
  • coinmaster get_coinmaster(item) - returns the coinmaster that either buys or sells the item
  • int coinmaster_price(item) - Returns the number of tokens an item costs or can be traded for.
 

Veracity

Developer
Staff member
Revision 9553 adds a few more things:

Proxy fields:

int available_tokens
boolean buys
boolean sells

ASH functions:

coinmaster coinmaster_selling_item( item )
coinmaster coinmaster_buying_item( item)
boolean coinmaster_buys_item( coinmaster, item )
int coinmaster_buy_price( cooinmaster, item )
boolean coinmaster_sells_item( coinmaster, item )
int coinmaster_sell_price( coinmaster, item )

I intend to add:

boolean coinmaster_accessible( coinmaster)
boolean coinmaster_visit( coinmaster )
boolean coinmaster_buy( coinmaster, int, item )
boolean coinmaster_sell( coinmaster, int, item )

I could make overloaded versions of the last two in which you don't specify the coinmaster, obviating looking up who buys or sells the item, since there is currently only one coinmaster trading in a given item in the given direction. (The Dimemaster sells things that the Quartersmaster buys and vice versa, but nobody sells or buys the same items, yet). Do we care?

  • coinmaster get_coinmaster(item) - returns the coinmaster that either buys or sells the item
  • int coinmaster_price(item) - Returns the number of tokens an item costs or can be traded for.
Consider the Dimemaster and Quartersmaster...
 
Last edited:

Bale

Minion
Consider the Dimemaster and Quartersmaster...

Pwnzed!

boolean coinmaster_buy( coinmaster, int, item )
boolean coinmaster_sell( coinmaster, int, item )

I could make overloaded versions of the last two in which you don't specify the coinmaster, obviating looking up who buys or sells the item, since there is currently only one coinmaster trading in a given item in the given direction. (The Dimemaster sells things that the Quartersmaster buys and vice versa, but nobody sells or buys the same items, yet). Do we care?

Not a big deal since I can always do:

coinmaster_buy( coinmaster_buying_item(doodad), quantity, doodad )

That will always automatically fill in the coinmaster just like the three parameter version.

It should be noted that if there is ever multiple coinmasters that will buy the same item, then coinmaster_buying_item() will be broken and so would the three parameter version of that function... I wouldn't put it past jick to do such a thing. Give you the option of a set of three coinmasters that all buy the same item for different credits, then he'd call it a "choice"...
 

Veracity

Developer
Staff member
How about this?

> ash coinmaster_accessible( $coinmaster[ dimemaster ] )

Returned: false

> ash coinmaster_inaccessible_reason( $coinmaster[ dimemaster ] )

Returned: You're not at war.

> ash coinmaster_visit( $coinmaster[ dimemaster ] )

You're not at war.
Returned: false

> ash coinmaster_visit( $coinmaster[ game shoppe ] )

Visiting the Game Shoppe...
Game Shoppe successfully looted!
Returned: true

> ash coinmaster_buy( $coinmaster[ game shoppe ], 1, $item[ snorkel ] )

You can't buy snorkel from Game Shoppe
Returned: false

> ash $coinmaster[ game shoppe ].available_tokens

Returned: 0

> inv alice's army ninja

Alice's Army Ninja

> ash coinmaster_sell( $coinmaster[ game shoppe ], 1, $item[ alice's army ninja ] )

Visiting the Game Shoppe...
Game Shoppe successfully looted!
Returned: true

> ash $coinmaster[ game shoppe ].available_tokens

Returned: 1

> inv alice's army ninja

Revision 9554 adds:

boolean coinmaster_accessible( coinmaster )
string coinmaster_inaccessible_reason( coinmaster )
boolean coinmaster_visit( coinmaster )
boolean coinmaster_buy( coinmaster, count, item )
boolean coinmaster_sell( coinmaster, count, item )

Go wild.

In the mean time, I need to think about CLI commands - later.
 

Nifft

Member
Code:
> ash to_coinmaster( "b b" )

Returned: Big Brother
token => sand dollar
item => sand dollar
property =>

> ash to_coinmaster( "dime" )

Returned: Dimemaster
token => dime
item => none
property => availableDimes

What is the "item" proxy field here compared to "token"? IE: why is sand dollar both but a dime only a token? Does it have to do with something you mentioned somewhere in one of the other coinmaster threads about one of them being an actual item in inventory (sand dollar) but the other not (dime)?

Everything seems to be shaping up quite nicely :)

~ Nifft
 

Veracity

Developer
Staff member
A sand dollar is an item which is the token you use to transact with Big Brother
A dime is not an item but is the token you use to transact with the Dimemaster. We keep the count in the availableDimes property.

You know....I am considering removing the coinmaster_ prefix from all those functions because of the little trick hola added a long time ago:

coinmaster cm;
print( coinmaster_accessible( cm ) );
print( coinmaster_visit( cm ) );

compare those to:

coinmaster cm;
print( cm.is_accessible() );
print( cm.visit() );
 
Last edited:

Veracity

Developer
Staff member
Yes. Revision 9555 provides this ASH API:


coinmaster data type with proxy fields:

string .token
item .item
string .property
int .available_tokens
boolean .buys
boolean .sells

Utility functions:

coinmaster to_coinmaster( string )
boolean is_coinmaster_item( item ) -> acquirable if autoSatisfyWithCoinmasters
coinmaster coinmaster_buying_item( item )
coinmaster coinmaster_selling_item( item )

Inquiries:

boolean buys_item( coinmaster, item )
int buy_price( coinmaster, item )
boolean sells_item( coinmaster, item )
int sell_price( coinmaster, item )

Coinmaster transactions:

boolean is_accessible( coinmaster )
string inaccessible_reason( coinmaster )
boolean visit( coinmaster )
boolean buy( coinmaster, int, item )
boolean sell( coinmaster, int, item )
 

Veracity

Developer
Staff member
Change:

coinmaster coinmaster_buying_item( item )
coinmaster coinmaster_selling_item( item )

are gone. Instead, I added two proxy fields to items: buyer and seller are coinmaster values.

> ash $item[ kicks ]

Returned: kick-ass kicks
plural => kix-ass kix
descid => 147761182
image => kicks.gif
levelreq => 0
fullness => 0
inebriety => 0
spleen => 0
notes =>
combat => false
reusable => false
usable => false
multi => false
seller => Quartersmaster
buyer => Dimemaster

Revision 9563
 

Veracity

Developer
Staff member
I'm marking this Implemented, since it provides everything you need for ASH, I think, and I am ready to take a break from KoLmafia development after I spin a release.

We still need CLI commands for this, so that you can "trade" or "tradein" via the gCLI, but I find writing commands like that to be tedious, and I don't feel like doing it right now. The Coin Masters used to be 100% GUI, and CLI users are, at least, no worse off for STILL not having an interface to them. :)
 

Winterbay

Active member
Is there a reason why Sand Dollars are not marked as sellable to Big Brother?

Edit: Could it be because I do not have access to him yet? I guess that would be a valid reason even though I'd like to be able to check if something could be sold and not just that I can sell it and where.

Edit, edit: Scrap that. Forgot it was my multi who is a level 43 DB and most definitely have access to big brother. So, should it be marked in the proxy item or is the fact that its the currency of his shop the reason?
 
Last edited:

slyz

Developer
Sand dollars are the currency Big Brother uses. You can use them to buy items from him, but you can't sell him the sand dollars themselves.

During the War, you can sell certain items to obtain the Coinmasters' currency (dimes or quarters). Those items are marked as sellable to X.
 

Winterbay

Active member
Yes, I realise this was something of a confusion from my side on what was implied by "selling" and "buying". In my mind sellable meant "can give to" and buyable "can get from" which is obviously not what was meant in this case :)
 

Bale

Minion
Sure you can sell sand dollars! Just yesterday I went to the store and sold some dollar bills and coins in exchange for a quart of milk. This is no different.

(Yeah that was unnecessary, but the idea amused me.)
 
Top