/** * Copyright (c) 2005-2017, KoLmafia development team * http://kolmafia.sourceforge.net/ * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * [1] Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * [2] Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * [3] Neither the name "KoLmafia" nor the names of its contributors may * be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ package net.sourceforge.kolmafia.request; import net.sourceforge.kolmafia.AdventureResult; import net.sourceforge.kolmafia.KoLCharacter; import net.sourceforge.kolmafia.KoLConstants; import net.sourceforge.kolmafia.KoLConstants.MafiaState; import net.sourceforge.kolmafia.KoLmafia; import net.sourceforge.kolmafia.RequestLogger; import net.sourceforge.kolmafia.objectpool.ItemPool; import net.sourceforge.kolmafia.persistence.ConcoctionDatabase; import net.sourceforge.kolmafia.persistence.ConsumablesDatabase; import net.sourceforge.kolmafia.persistence.ItemDatabase; import net.sourceforge.kolmafia.preferences.Preferences; import net.sourceforge.kolmafia.session.InventoryManager; import net.sourceforge.kolmafia.session.ResponseTextParser; import net.sourceforge.kolmafia.session.ResultProcessor; import net.sourceforge.kolmafia.swingui.GenericFrame; public class SpleenItemRequest extends UseItemRequest { public SpleenItemRequest( final AdventureResult item ) { super( ItemDatabase.getConsumptionType( item.getItemId() ), item ); } @Override public int getAdventuresUsed() { return 0; } public static final int maximumUses( final int itemId, final String itemName, final int spleenHit ) { if ( KoLCharacter.inNuclearAutumn() && ConsumablesDatabase.getSpleenHit( itemName ) > 1 ) { return 0; } // Some spleen items also heal HP or MP int restorationMaximum = UseItemRequest.getRestorationMaximum( itemName ); UseItemRequest.limiter = ( restorationMaximum < Integer.MAX_VALUE ) ? "needed restoration or spleen" : "spleen"; int limit = KoLCharacter.getSpleenLimit(); int spleenLeft = limit - KoLCharacter.getSpleenUse(); return Math.min( restorationMaximum, spleenLeft / spleenHit ); } @Override public void run() { if ( GenericRequest.abortIfInFightOrChoice() ) { return; } if ( !ConsumablesDatabase.meetsLevelRequirement( this.itemUsed.getName() ) ) { UseItemRequest.lastUpdate = "Insufficient level to consume " + this.itemUsed; KoLmafia.updateDisplay( MafiaState.ERROR, UseItemRequest.lastUpdate ); return; } int itemId = this.itemUsed.getItemId(); UseItemRequest.lastUpdate = ""; int maximumUses = UseItemRequest.maximumUses( itemId ); if ( maximumUses < this.itemUsed.getCount() ) { KoLmafia.updateDisplay( "(usable quantity of " + this.itemUsed + " is limited to " + maximumUses + " by " + UseItemRequest.limiter + ")" ); this.itemUsed = this.itemUsed.getInstance( maximumUses ); } if ( this.itemUsed.getCount() < 1 ) { return; } int iterations = 1; int origCount = this.itemUsed.getCount(); if ( origCount > 1 && this.singleConsume() ) { iterations = origCount; this.itemUsed = this.itemUsed.getInstance( 1 ); } String originalURLString = this.getURLString(); for ( int i = 1; i <= iterations && KoLmafia.permitsContinue(); ++i ) { if ( !this.allowSpleenConsumption() ) { return; } this.constructURLString( originalURLString ); this.useOnce( i, iterations, "Chewing" ); } if ( KoLmafia.permitsContinue() ) { KoLmafia.updateDisplay( "Finished chewing " + origCount + " " + this.itemUsed.getName() + "." ); } } @Override public void useOnce( final int currentIteration, final int totalIterations, String useTypeAsString ) { UseItemRequest.lastUpdate = ""; // Check to make sure the character has the item in their // inventory first - if not, report the error message and // return from the method. if ( !InventoryManager.retrieveItem( this.itemUsed ) ) { UseItemRequest.lastUpdate = "Insufficient items to chew."; return; } this.addFormField( "ajax", "1" ); this.addFormField( "quantity", String.valueOf( this.itemUsed.getCount() ) ); super.runOneIteration( currentIteration, totalIterations, useTypeAsString ); } private final boolean singleConsume() { return this.consumptionType == KoLConstants.CONSUME_USE; } private final boolean allowSpleenConsumption() { if ( !GenericFrame.instanceExists() ) { return true; } String itemName = this.itemUsed.getName(); if ( !UseItemRequest.askAboutPvP( itemName ) ) { return false; } return true; } public static final void parseConsumption( final AdventureResult item, final AdventureResult helper, final String responseText ) { if ( responseText.contains( "You don't have the item" ) ) { // Double clicked a use link, say return; } // Spleen is restricted by Standard. if ( responseText.contains( "That item is too old to be used on this path" ) ) { UseItemRequest.lastUpdate = item.getName() + " is too old to be used on this path."; KoLmafia.updateDisplay( MafiaState.ERROR, UseItemRequest.lastUpdate ); return; } if ( responseText.contains( "That item isn't usable in quantity" ) ) { int attrs = ItemDatabase.getAttributes( item.getItemId() ); if ( ( attrs & ItemDatabase.ATTR_MULTIPLE ) == 0 ) { // Multi-use was attempted and failed, but the request was not generated by KoLmafia // because KoLmafia already knows that it cannot be multi-used return; } KoLmafia.updateDisplay( MafiaState.ERROR, "Internal data error: item incorrectly flagged as multi-usable." ); return; } int spleenHit = ConsumablesDatabase.getSpleenHit( item.getName() ); int count = item.getCount(); int spleenUse = spleenHit * count; if ( responseText.contains( "rupture" ) ) { UseItemRequest.lastUpdate = "Your spleen might go kablooie."; KoLmafia.updateDisplay( MafiaState.ERROR, UseItemRequest.lastUpdate ); // If we have no spleen data for this item, we can't tell what, // if anything, consumption did to our spleen. if ( spleenHit == 0 ) { return; } int maxSpleen = KoLCharacter.getSpleenLimit(); int currentSpleen = KoLCharacter.getSpleenUse(); int estimatedSpleen = maxSpleen - spleenUse + 1; if ( estimatedSpleen > currentSpleen ) { KoLCharacter.setSpleenUse( estimatedSpleen ); } KoLCharacter.updateStatus(); return; } // The spleen item was consumed successfully KoLCharacter.setSpleenUse( KoLCharacter.getSpleenUse() + spleenUse ); ResultProcessor.processResult( item.getNegation() ); KoLCharacter.updateStatus(); // Re-sort consumables list if needed if ( Preferences.getBoolean( "sortByRoom" ) ) { ConcoctionDatabase.getUsables().sort(); } // Perform item-specific processing switch ( item.getItemId() ) { case ItemPool.STEEL_SPLEEN: if ( responseText.contains( "You acquire a skill" ) ) { ResponseTextParser.learnSkill( "Spleen of Steel" ); } break; case ItemPool.TURKEY_BLASTER: if ( responseText.contains( "can't handle" ) ) { Preferences.setInteger( "_turkeyBlastersUsed", 3 ); } else { Preferences.increment( "_turkeyBlastersUsed" ); } break; } } public static final boolean registerRequest() { AdventureResult item = UseItemRequest.lastItemUsed; int count = item.getCount(); String name = item.getName(); String useString = "chew " + count + " " + name ; RequestLogger.updateSessionLog(); RequestLogger.updateSessionLog( useString ); return true; } }