/** * 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.textui.command; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import net.sourceforge.kolmafia.AdventureResult; import net.sourceforge.kolmafia.KoLAdventure; 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.AdventureDatabase; import net.sourceforge.kolmafia.persistence.ItemFinder; import net.sourceforge.kolmafia.preferences.Preferences; import net.sourceforge.kolmafia.request.BeerPongRequest; import net.sourceforge.kolmafia.request.OrcChasmRequest; import net.sourceforge.kolmafia.session.EquipmentManager; import net.sourceforge.kolmafia.session.GoalManager; import net.sourceforge.kolmafia.utilities.StringUtilities; public class ConditionsCommand extends AbstractCommand { private static final Pattern MEAT_PATTERN = Pattern.compile( "[\\d,]+ meat" ); public ConditionsCommand() { this.usage = " clear | check | add <condition> | remove <condition> | set <condition> - modify your adventuring goals."; } @Override public void run( final String cmd, final String parameters ) { if ( parameters.equals( "" ) ) { RequestLogger.printList( GoalManager.getGoals() ); return; } String option = parameters.split( " " )[ 0 ]; if ( option.equals( "list" ) ) { RequestLogger.printList( GoalManager.getGoals() ); return; } if ( option.equals( "clear" ) ) { ConditionsCommand.clear(); return; } if ( option.equals( "check" ) ) { ConditionsCommand.check(); return; } if ( option.equals( "add" ) || option.equals( "remove" ) || option.equals( "set" ) ) { String conditionListString = parameters.substring( option.length() ).toLowerCase().trim(); ConditionsCommand.update( option, conditionListString ); return; } } public static void clear() { GoalManager.clearGoals(); RequestLogger.printLine( "Conditions list cleared." ); } public static void check() { KoLmafia.checkRequirements( GoalManager.getGoals() ); RequestLogger.printLine( "Conditions list validated against available items." ); } public static boolean update( final String option, final String conditionListString ) { String[] conditionList = conditionListString.split( "\\s*,\\s*" ); boolean hasUpdate = false; for ( int i = 0; i < conditionList.length; ++i ) { AdventureResult condition = ConditionsCommand.extractCondition( conditionList[ i ] ); if ( condition != null ) { if ( option.equals( "set" ) ) { GoalManager.setGoal( condition ); } else if ( option.equals( "remove" ) ) { GoalManager.addGoal( condition.getNegation() ); } else if ( condition.getCount() > 0 ) { GoalManager.addGoal( condition ); } hasUpdate = true; } } return hasUpdate; } private static AdventureResult extractCondition( String conditionString ) { if ( conditionString.length() == 0 ) { return null; } conditionString = conditionString.toLowerCase(); Matcher meatMatcher = ConditionsCommand.MEAT_PATTERN.matcher( conditionString ); boolean isMeatCondition = meatMatcher.find() ? meatMatcher.group().length() == conditionString.length() : false; if ( isMeatCondition ) { String[] splitCondition = conditionString.split( "\\s+" ); int amount = StringUtilities.parseInt( splitCondition[ 0 ] ); return new AdventureResult( AdventureResult.MEAT, amount ); } if ( conditionString.endsWith( "choiceadv" ) || conditionString.endsWith( "choices" ) || conditionString.endsWith( "choice" ) ) { // If it's a choice adventure condition, parse out the // number of choice adventures the user wishes to do. String[] splitCondition = conditionString.split( "\\s+" ); int count = splitCondition.length > 1 ? StringUtilities.parseInt( splitCondition[ 0 ] ) : 1; return GoalManager.GOAL_CHOICE.getInstance( count ); } if ( conditionString.endsWith( "manuel" ) || conditionString.endsWith( "factoid" ) || conditionString.endsWith( "factoids" ) ) { // parse the number of manuel entries the user wishes to find String[] splitCondition = conditionString.split( "\\s+" ); int count = splitCondition.length > 1 ? StringUtilities.parseInt( splitCondition[ 0 ] ) : 1; return GoalManager.GOAL_FACTOID.getInstance( count ); } if ( conditionString.endsWith( "floundry fish" ) ) { // parse the number of fish the user wishes to catch String[] splitCondition = conditionString.split( "\\s+" ); int count = splitCondition.length > 1 ? StringUtilities.parseInt( splitCondition[ 0 ] ) : 1; return GoalManager.GOAL_FLOUNDRY.getInstance( count ); } if ( conditionString.endsWith( "autostop" ) ) { String[] splitCondition = conditionString.split( "\\s+" ); int count = splitCondition.length > 1 ? StringUtilities.parseInt( splitCondition[ 0 ] ) : 1; return GoalManager.GOAL_AUTOSTOP.getInstance( count ); } if ( conditionString.endsWith( "pirate insult" ) || conditionString.endsWith( "pirate insults" ) ) { String[] splitCondition = conditionString.split( "\\s+" ); int count = splitCondition.length > 1 ? StringUtilities.parseInt( splitCondition[ 0 ] ) : 1; return new AdventureResult( AdventureResult.PSEUDO_ITEM_PRIORITY, "pirate insult", count ) { @Override public int getCount( List list ) { if ( list != KoLConstants.inventory ) { return 0; } return BeerPongRequest.countPirateInsults(); } }; } if ( conditionString.endsWith( "arena flyer ml" ) ) { String[] splitCondition = conditionString.split( "\\s+" ); int count = splitCondition.length > 1 ? StringUtilities.parseInt( splitCondition[ 0 ] ) : 1; return new AdventureResult( AdventureResult.PSEUDO_ITEM_PRIORITY, "Arena flyer ML", count ) { @Override public int getCount( List list ) { if ( list != KoLConstants.inventory ) { return 0; } return Preferences.getInteger( "flyeredML" ); } }; } if ( conditionString.equals( "chasm bridge" ) || conditionString.endsWith( "chasm bridge progress" ) ) { String[] splitCondition = conditionString.split( "\\s+" ); int count = Math.min( StringUtilities.isNumeric( splitCondition[ 0 ] ) ? StringUtilities.parseInt( splitCondition[ 0 ] ) : 30, 30 ); return new AdventureResult( AdventureResult.PSEUDO_ITEM_PRIORITY, "Chasm Bridge Progress", count ) { @Override public int getCount( List list ) { if ( list != KoLConstants.inventory ) { return 0; } return OrcChasmRequest.getChasmProgress(); } }; } if ( conditionString.startsWith( "level" ) ) { // If the condition is a level, then determine how many // substat points are required to the next level and // add the substat points as a condition. String[] splitCondition = conditionString.split( "\\s+" ); int level = StringUtilities.parseInt( splitCondition[ 1 ] ); int primeIndex = KoLCharacter.getPrimeIndex(); GoalManager.GOAL_SUBSTATS_COUNTS[ primeIndex ] = (int) ( KoLCharacter.calculateSubpoints( ( level - 1 ) * ( level - 1 ) + 4, 0 ) - KoLCharacter.getTotalPrime() ); return GoalManager.GOAL_SUBSTATS; } if ( conditionString.endsWith( "muscle" ) || conditionString.endsWith( "mysticality" ) || conditionString.endsWith( "moxie" ) || conditionString.endsWith( "mus" ) || conditionString.endsWith( "mys" ) || conditionString.endsWith( "myst" ) || conditionString.endsWith( "mox" ) ) { String[] splitCondition = conditionString.split( "\\s+" ); int points = StringUtilities.parseInt( splitCondition[ 0 ] ); int statIndex = conditionString.indexOf( "mus" ) != -1 ? 0 : conditionString.indexOf( "mys" ) != -1 ? 1 : 2; GoalManager.GOAL_SUBSTATS_COUNTS[ statIndex ] = (int) KoLCharacter.calculateSubpoints( points, 0 ); GoalManager.GOAL_SUBSTATS_COUNTS[ statIndex ] = Math.max( 0, GoalManager.GOAL_SUBSTATS_COUNTS[ statIndex ] - (int) ( conditionString.indexOf( "mus" ) != -1 ? KoLCharacter.getTotalMuscle() : conditionString.indexOf( "mys" ) != -1 ? KoLCharacter.getTotalMysticality() : KoLCharacter.getTotalMoxie() ) ); return GoalManager.GOAL_SUBSTATS; } if ( conditionString.endsWith( "health" ) || conditionString.endsWith( "mana" ) ) { String type; int max, current; if ( conditionString.endsWith( "health" ) ) { type = AdventureResult.HP; max = KoLCharacter.getMaximumHP(); current = KoLCharacter.getCurrentHP(); } else { type = AdventureResult.MP; max = KoLCharacter.getMaximumMP(); current = KoLCharacter.getCurrentMP(); } String numberString = conditionString.split( "\\s+" )[ 0 ]; int points; if ( numberString.endsWith( "%" ) ) { int num = StringUtilities.parseInt( numberString.substring( 0, numberString.length() - 1 ) ); points = (int) ( (float) num * (float) max / 100.0f ); } else { points = StringUtilities.parseInt( numberString ); } points -= current; AdventureResult condition = new AdventureResult( type, points ); condition = condition.getInstance( condition.getCount() - GoalManager.getGoalCount( condition )); return condition; } if ( conditionString.endsWith( "outfit" ) ) { // Usage: conditions add <location> outfit String outfitLocation; if ( conditionString.equals( "outfit" ) ) { outfitLocation = Preferences.getString( "lastAdventure" ); } else { outfitLocation = conditionString.substring( 0, conditionString.length() - 7 ); } // Try to support outfit names by mapping some outfits to their locations if ( outfitLocation.equals( "guard" ) || outfitLocation.equals( "elite" ) || outfitLocation.equals( "elite guard" ) ) { outfitLocation = "treasury"; } if ( outfitLocation.equals( "rift" ) ) { outfitLocation = "battlefield"; } if ( outfitLocation.equals( "cloaca-cola" ) || outfitLocation.equals( "cloaca cola" ) ) { outfitLocation = "cloaca"; } if ( outfitLocation.equals( "dyspepsi-cola" ) || outfitLocation.equals( "dyspepsi cola" ) ) { outfitLocation = "dyspepsi"; } KoLAdventure lastAdventure = AdventureDatabase.getAdventure( outfitLocation ); if ( !EquipmentManager.addOutfitConditions( lastAdventure ) ) { KoLmafia.updateDisplay( MafiaState.ERROR, "No outfit corresponds to " + lastAdventure.getAdventureName() + "." ); } return null; } AdventureResult rv = AdventureResult.WildcardResult.getInstance( conditionString ); return rv != null ? rv : ItemFinder.getFirstMatchingItem( conditionString ); } }