New Content - Implemented New path "Actually Ed the Undying"

Ok, heading towards the edge of my knowledge here. What do I change so that item.getCount( KoLConstants.inventory ) doesn't return 1 for both Staff of Ed's, despite only name and not ItemId matching. I guess it's something to do with how matching works for a List<AdventureResult>, and I have to change the matching to be name + itemId rather than just name, but I don't even know where this is set. I would instinctively have believed that all fields in a datatype would have to be equal for them to be considered equal, but it seems this is not the case.

You can imagine this throws quite a problem into the mix!
 
I just finished an Ed ascension, and found that my demon summon is not listed in Daily Deeds. I couldn't find an obvious preference where this is stored, but I'm assuming that Mafia doesn't know the Summoning Chamber is available, since it didn't see me defeat Lord Spookyraven.

Logging out/in didn't fix this; nor did summoning manually in the relay browser.

TL;DR: Mafia should set Lord Spookyraven defeated = true when Ed gives him back the Eye of Ed. Even more robustly, it could be set when the player summons a demon.
 
Last edited:
Ok, heading towards the edge of my knowledge here. What do I change so that item.getCount( KoLConstants.inventory ) doesn't return 1 for both Staff of Ed's, despite only name and not ItemId matching. I guess it's something to do with how matching works for a List<AdventureResult>, and I have to change the matching to be name + itemId rather than just name, but I don't even know where this is set.
That uses list.indexOf to find the AdventureResult in the list. That seems to be specified to use the "equals" method on the objects in the list.

Look at AdventureResult.equals:

Code:
		return ( !ar.isItem() || this.itemId == ar.itemId ) &&
			this.name.equalsIgnoreCase( ar.name );
It looks like that does look at itemIds for objects and otherwise does a case insensitive comparison on the name.

Perhaps the implementation actually uses compareTo for some reason?

Look at AdventureResult.compareTo.

- If "priority" is different - ITEM vs. EFFECT, for example - the difference in priority determines the comparison.
- Else, the objects are the same type, and the "name" is examined. If they are equal, the items are deemed to be equal.
- Else, the names are different, and effects are sorted based on duration and everything else is sorted based on name difference.

I find it suspicious that equals() and compareTo() for adventure results don't agree on what to look for; if a.equals( b ), as implemented, that does NOT mean that a.compareTo( b ) == 0. That can't be right.

Why are these focusing on names? The "name" is the only thing that all AdventureResult objects have, and the assumption was that the namespace for each type of object did not allow duplicates. That is no longer the case. In fact, it was already broken for effects - there are 6 different effects that KoL calls "A Little Bit Evil" - but we had a kludge in place for those to give them different names.

Now we have both objects and effects which can have identical names and different "id"s. Interestingly enough, every AdventureResult object has the following fields:

Code:
	protected String name;
	protected int priority;
	private int count;
	private int itemId;
and the "itemId" field really is stored only for items. Compare to ASH's "Value" object:

Code:
	public Type type;
	public long contentLong = 0;
	public String contentString = null;
	public Object content = null;
where every object has both a string (the "name") and a "long" (the "id") and may have a pointer to an arbitrary data structure.

I would instinctively have believed that all fields in a datatype would have to be equal for them to be considered equal, but it seems this is not the case.
True. And I think that compareTo and equals not agreeing is a Bad Thing.

You can imagine this throws quite a problem into the mix!
I suggest the following:

- AdventureResult has "name" and "id"
- Everything has a "name" and "id" defaults to 0. For items and effects, "id" is set to the specific itemId or effectId.
- AdventureResult.equals requires that priority, id, and name all match - and I see no reason to have the name match be "ignoreCase".
- AdventureResult.compareTo returns 0 (equals) iff AdventureResult.equals would return true:
-- If priorities are not equal, return priority comparison
-- If (priorities are equal and) names are not equal, return name comparison - and I think ignoreCase is fine, here, if the names are not equal, since that will make them sort the same as now.
-- If (priorities and names are equal) and ids are not equal, return id comparison
-- Otherwise, they are equal.
 
Thanks, I'd found it and done something similar, and it works. I can now equip Staff of Fats from maximize, which required far more changes than you might suspect! I'll change to match your suggestion.

Edit, actually I think I'll leave it as it is, which is basically that before doing name comparisions for items it compares itemId. Edit again, no I won't, as that means Item lists are in item id order by default

Incidentally, my syntax for items by item Id in the files is currently [xxxx]Anything, and it only looks at [xxxx], so we can have entries like [7964]Staff of Fats for clarity of reading by humans.

I'm not currently attacking EffectIds. They should be more of an issue, as I think we currently do lookups by name, and certainly AdventureResult handles them by name, so they will be the next challenge after this is live. I may rename itemId id in AdventureResult and use it for both, as priority already distinguishes them.

Actually went with :

- AdventureResult has "name" and "id"
- Everything has a "name" and "id" defaults to 0. For items and effects, "id" is set to the specific itemId (and later effectId).
- AdventureResult.equals requires that priority, id, and name all match - and I see no reason to have the name match be "ignoreCase".
- AdventureResult.compareTo returns 0 (equals) iff AdventureResult.equals would return true: (nearly, for sorting effects it isn't this)
-- If priorities are not equal, return priority comparison
-- If (priorities are equal and) names and items are equal, they are equal
-- If it's a status effect, return difference in turns (sorts effects by turns).
-- If (priorities are equal and) names are not equal, return name comparison
-- Otherwise return id comparison
 
Last edited:
r15461 puts this live. Hopefully nothing is too broken, but we'll see . . .

One important thing scripters should note is that the various modifier commands that return modifier numbers, strings etc work if you pass a $skill[], $item[] or $effect[] but will fail if you pass a string until the string is updated to the new internal format (type:name) for modifier lookup.

Most things now work with items specified as [itemid] (eg [2268]) or [itemid]name, if you want to still have item clarity. This certainly includes equip, acquire, buy etc, but I've not tried everything I'm sure.

Edit - Don't try having Staff of Fats in an outfit, though, as we can't parse item Id's for custom outfits, as KoL doesn't give them to us.
 
Last edited:
This is new:

> closet take * dusty zin

Removing items from closet...
You acquire dusty bottle of great Zinfandel (6)
Requests complete.

> drink dusty zin

[dusty zin] has no matches.
 
Some plurals in r15468:

Code:
mummified beef haunch is not multiusable, but KoLmafia thought it was
Unexpected plural of 'mummified beef haunch' found: mummified beef haunches
You acquire mummified beef haunch (7)

Unexpected plural of 'sacramental wine' found: bottles of sacramental wine
You acquire sacramental wine (10)

Unexpected plural of 'spirit beer' found: bottles of spirit beer
You acquire spirit beer (10)

Unexpected plural of 'holy spring water' found: bottles of holy spring water
You acquire holy spring water (10)

Unexpected plural of 'cotton bandages' found: rolls of cotton bandages
You acquire cotton bandages (5)

Unexpected plural of 'linen bandages' found: rolls of linen bandages
You acquire linen bandages (5)
mummified loaf of bread is not multiusable, but KoLmafia thought it was

Unexpected plural of 'mummified loaf of bread' found: mummified loaves of bread
You acquire mummified loaf of bread (5)
 
Unsurprisingly, attempting to plant a florist plant with visit_url() doesn't work in the underworld. It also causes florist_available() to return false, and I couldn't work out a way to make it return true again other than closing and reopening mafia.

I guess that's a two part request:
1. The florist not being reached from within a limitmode shouldn't cause mafia to think the florist is unavailable.
2. Mafia should become aware that the florist is available if the florist is successfully visited and/or if flowers are present in fights.
 
I agree that visiting the florist could make mafia realize it's available, and the florist command should probably not do anything in any limitmode.
 
I lost a fight via Chateau to Bram the Stoker, which Mafia counted against my semirare counter. I assume it's the returning-to-the-fight encounter that triggers this, because the Chateau already has a check for it.
 
I lost a fight via Chateau to Bram the Stoker, which Mafia counted against my semirare counter. I assume it's the returning-to-the-fight encounter that triggers this, because the Chateau already has a check for it.

That seems really darn odd because mafia actually does not count adventures. It just accepts your charpane's adventure count as correct.
 
What I think he means is that encountering Bram for the second time reset the semirare counter, even though we are careful to not do that for wandering or summoned monsters. I.e., the chateau painting did not reset it, but when he died and fought Bram again, we counted that as actually finding the semirare.
 
Talking about mafia counting adventures: Currently reviving into a combat increments the turns_spent proxy record of a location.

(I noticed this because it causes Ezandora's Guide delay tracking to go wonky)
 
Talking about mafia counting adventures: Currently reviving into a combat increments the turns_spent proxy record of a location.

Similarly, the "Like a Bat out of Hell" (when you go to the underworld) and "Underworld Body Shop" choice adventures are currently added to that location's noncombat_queue.
 
You can still install the fancier oven and cocktailcrafting equipment and cook via the [craft] menu in-browser. Is there any way to automate that via mafia?
 
Looks like there is now a message in the UI that tells us when our servants give us their skills when they are level 21. http://pastebin.com/cS2mLsGR is an example of the frame when it happened, note the section:

Code:
<table><tr><td valign=center>You acquire a skill:  </td><td><img src="/images/itemimages/edserv5.gif" onClick='javascript:poop("desc_skill.php?whichskill=17025&self=true","skill", 350, 300)' width=30 height=30></td><td><b><a onClick='javascript:poop("desc_skill.php?whichskill=17025&self=true","skill", 350, 300)'>Gift of the Scribe</a></b></td></tr></table><center><table class="item" style="float: none" rel="id=4448&s=0&q=0&d=1&g=0&t=0&n=1&m=1&p=0&u=s&ou=use">

Any chance we can get this logged in the session logger?

Currently all I see is:
Code:
Round 9: bombar wins the fight!
You acquire an item: Instant Karma
You acquire an item: still-beating spleen
You acquire an item: thwaitgold scarab beetle statuette
You acquire an item: Ka coin (2)
You gain 27 Strengthliness
You gain 54 Wizardliness
You gain 17 Roguishness
 
According to KoL Spading HERE, Ed's Servants, the Cat and Maid are equivalent to Fairy and Leprechaun of equivalent level. (Assuming that Cat is at least functionally level 7.)

Also, Cat's passive skill "Gift of the Cat" is +25% item drop bonus.

Is the data not yet conclusive enough to implement this?
 
I'm surprised mafia isn't already recognizing (and logging) that you learned a new skill. I would expect it to work even with a version that doesn't know about the skill, though mafia does know about those skills and what they do.
 
Back
Top