Page 1 of 2 1 2 LastLast
Results 1 to 10 of 19

Thread: More friendly warnings, this time for duplicate names

  1. #1
    Senior Member zarqon's Avatar
    Join Date
    Nov 2007
    Location
    Seoul, Korea
    Posts
    3,460

    Lightbulb More friendly warnings, this time for duplicate names

    Presently, $item[Staff of Ed] and to_item("Staff of Ed") returns the second of the two Staves of Ed without mentioning that it could have just as well returned the first staff. And similarly for the two ancient amulets.

    I would like to request that mafia display a "friendly warning" in cases where the supplied constant name has multiple matches. For example, a script that contains $item[ancient amulet] should print something like

    Multiple matches for "ancient amulet" (somescript.ash, line 123). Clarify by using one of:
    $item[2180]
    $item[7963]
    And a script that uses to_item("Staff of Ed") should print something like:

    Multiple matches for "Staff of Ed" (somescript.ash, line 123). Clarify by using one of:
    "[2325]Staff of Ed"
    "[7961]Staff of Ed"
    Ideally, these warnings would also fire for loading data files, since that's another case where text is matched up to mafia's constants.
    Sig by JakAtk
    My scripts: Prefref Plus | One-Click Wossname | Om******t (??) | Psychose-a-Matic | RandBot
    Combat suite: Best Between Battle | Mer********d (?!) | SmartStasis | BatMan | BatMan RE
    For script authors: ASH Wiki | ZLib | BatBrain | CLI Links | CanAdv | Script Registry | Map Manager | About Bats
    If you appreciate my work, help me become BAT KING OF THE WORLD! Thanks to all donators!

  2. #2
    Developer
    Join Date
    Apr 2010
    Posts
    4,060

    Default

    I think my search is broken. Can only find the word "clarify" three times in all the Mafia build files, and none in that context.

  3. #3
    Developer
    Join Date
    Aug 2009
    Posts
    2,683

    Default

    Darzil: that's because zarqon's suggesting this particular output as a feature request.

  4. #4
    Developer
    Join Date
    Aug 2009
    Posts
    2,683

    Default

    Amusing note when digging a bit into this: to_item("[1]hamsters from outer space") will resolve to $item[seal-clubbing club], as the tag after the brackets is entirely ignored.

    There seem to be a few issues at play here:

    * to_item invokes (at some point) ItemDatabase.getCanonicalName, which in turn looks if the item is present in ItemDatabase.itemIdByName.
    * When populating that map, we happily clobber any existing values without checking for collisions. That's probably why we had so many issues with $item[rock] and $item[2108] (and associated items).

    I imagine we could populate a "name collision" map as well (mapping String itemname -> int[] ids), and simultaneously set the itemIdByName entry to some invalid item ID. Haven't really put too much thought into exactly how that'd work, just yet.

  5. #5
    Developer Veracity's Avatar
    Join Date
    Mar 2006
    Location
    The Unseelie Court
    Posts
    11,112

    Default

    Presently, $item[Staff of Ed] and to_item("Staff of Ed") returns the second of the two Staves of Ed without mentioning that it could have just as well returned the first staff. And similarly for the two ancient amulets.
    Originally Posted by zarqon View Post
    $item[] is a compile-time lookup. to_item() is a run-time lookup - although in the case of a constant string argument, we could optimize it into the compile-time constant.

    Code:
    > ash to_item( "[2325]Staff of Ed" ).to_int()
    
    Returned: 2325
    
    > ash to_item( 2325 ).to_int()
    
    Returned: 2325
    Seems to me that if you know the item id, you could just do to_item( 2325).

    When loading files, presumably we are converting strings into "item" objects.
    And when writing files, we'd need to know that Staff of Ed and ancient amulet are both ambiguous and include the item id.

    This is all connected with DataTypes.parseItemValue() which has the following code:

    Code:
    		// Otherwise, let ItemDatabase parse the name using fuzzy matching.
    		int itemId = ItemDatabase.getItemId( name );
    ItemDatabase.getItemId resolves this via:

    Code:
    ItemDatabase.itemIdByName.get( name )
    Which is to say, a single map lookup. There is no knowledge of which items have ambiguous names. Although, I imagine we could determine that when loading the data file.
    Ph'nglui mglw'nafh Cthulhu
    R'lyeh wgah-nagl fhtagn.

  6. #6
    Developer Veracity's Avatar
    Join Date
    Mar 2006
    Location
    The Unseelie Court
    Posts
    11,112

    Default

    Looks like heeheehee has discovered the same stuff. Heh. Or should that be hehhehheh?
    Ph'nglui mglw'nafh Cthulhu
    R'lyeh wgah-nagl fhtagn.

  7. #7
    Developer Veracity's Avatar
    Join Date
    Mar 2006
    Location
    The Unseelie Court
    Posts
    11,112

    Default

    I imagine we could populate a "name collision" map as well (mapping String itemname -> int[] ids), and simultaneously set the itemIdByName entry to some invalid item ID. Haven't really put too much thought into exactly how that'd work, just yet.
    Originally Posted by heeheehee View Post
    For no obvious reason - given current code - itemIdByName is defined to be a Map<String, Object>, even though we currently only ever map to Integers - and we assume that what is there is an Integer.

    Seems like we could make it a Map<String,int[]>. In the vast majority of cases, the array would be size 1, but in the handful of places where there is a name collision, it would have more than 1.

    ItemDatabase.getItemId() would return the last element in the array (for compatibility).
    ItemDatabase.getItemIds() would return the array. That is the method we'd need to do the kind of stauff zarqon wants.
    Ph'nglui mglw'nafh Cthulhu
    R'lyeh wgah-nagl fhtagn.

  8. #8
    Senior Member zarqon's Avatar
    Join Date
    Nov 2007
    Location
    Seoul, Korea
    Posts
    3,460

    Default

    Appreciate all the swift responses. Not sure if it's helpful but I'd like to suggest that it may be useful to do this in a way that could apply universally to any of KoLmafia's typed constants, not just items. Though to my knowledge, these two items are presently the only duplicates.

    Feature was requested because I have a script that ran into some difficult-to-debug errors a while back due to KoLmafia essentially changing items on me without letting me know. And from several different sources -- one from a data file (where the item was a field in a map of records), and one hardcoded in a script (using to_item(string)).
    Sig by JakAtk
    My scripts: Prefref Plus | One-Click Wossname | Om******t (??) | Psychose-a-Matic | RandBot
    Combat suite: Best Between Battle | Mer********d (?!) | SmartStasis | BatMan | BatMan RE
    For script authors: ASH Wiki | ZLib | BatBrain | CLI Links | CanAdv | Script Registry | Map Manager | About Bats
    If you appreciate my work, help me become BAT KING OF THE WORLD! Thanks to all donators!

  9. #9
    Developer Veracity's Avatar
    Join Date
    Mar 2006
    Location
    The Unseelie Court
    Posts
    11,112

    Default

    I'd like to suggest that it may be useful to do this in a way that could apply universally to any of KoLmafia's typed constants, not just items. Though to my knowledge, these two items are presently the only duplicates.
    Originally Posted by zarqon View Post
    There are multiple effects with the same name, too. A Little Bit Evil, for example. We'd need to be able to, similary, translate an effect name into a set of effect ids.
    Ph'nglui mglw'nafh Cthulhu
    R'lyeh wgah-nagl fhtagn.

  10. #10
    Developer Veracity's Avatar
    Join Date
    Mar 2006
    Location
    The Unseelie Court
    Posts
    11,112

    Default

    I coded up a change to ItemDatabase to let it deal with items that have multiple item ids:

    Code:
    > test itemids seal tooth
    
    seal tooth has 1 itemid: 2
    
    > test itemids Staff of Ed
    
    Staff of Ed has 2 itemids: 2325, 7961
    
    > test itemids ancient amulet
    
    ancient amulet has 2 itemids: 2180, 7963
    For now, I left it such that when KoLmafia (anywhere) asks for the item ID of an ambiguously named item, it gets the last one entered:

    Code:
    > ash to_item( "Staff of Ed" ).to_int()
    
    Returned: 7961
    I think I'll submit this to let any issues with it shake out before deciding where/how to use it.

    ItemDatabase int getItemId( String name, int count, boolean substringMatch )
    (and the overloaded variants) should operate as before.

    ItemDatabase int[] getItemIds( String name, int count, boolean substringMatch )
    is the new method that returns all IDs. getItemId now uses this to do all the heavy lifting.
    Ph'nglui mglw'nafh Cthulhu
    R'lyeh wgah-nagl fhtagn.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •