/**
* 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;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.EnumSet;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.IllegalFormatException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.SimpleXmlSerializer;
import org.htmlcleaner.TagNode;
import org.htmlcleaner.XPatherException;
import org.json.JSONException;
import org.json.JSONObject;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.wc.SVNInfo;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
import net.java.dev.spellcast.utilities.LockableListModel;
import net.sourceforge.kolmafia.AdventureResult;
import net.sourceforge.kolmafia.AreaCombatData;
import net.sourceforge.kolmafia.CoinmasterData;
import net.sourceforge.kolmafia.Expression;
import net.sourceforge.kolmafia.EdServantData;
import net.sourceforge.kolmafia.FamiliarData;
import net.sourceforge.kolmafia.KoLAdventure;
import net.sourceforge.kolmafia.KoLCharacter;
import net.sourceforge.kolmafia.KoLConstants;
import net.sourceforge.kolmafia.KoLConstants.CraftingRequirements;
import net.sourceforge.kolmafia.KoLConstants.CraftingType;
import net.sourceforge.kolmafia.KoLConstants.MafiaState;
import net.sourceforge.kolmafia.KoLConstants.Stat;
import net.sourceforge.kolmafia.KoLmafia;
import net.sourceforge.kolmafia.KoLmafiaCLI;
import net.sourceforge.kolmafia.KoLmafiaASH;
import net.sourceforge.kolmafia.ModifierExpression;
import net.sourceforge.kolmafia.Modifiers;
import net.sourceforge.kolmafia.MonsterData;
import net.sourceforge.kolmafia.MonsterExpression;
import net.sourceforge.kolmafia.RequestLogger;
import net.sourceforge.kolmafia.RequestThread;
import net.sourceforge.kolmafia.SpecialOutfit;
import net.sourceforge.kolmafia.StaticEntity;
import net.sourceforge.kolmafia.VYKEACompanionData;
import net.sourceforge.kolmafia.chat.ChatMessage;
import net.sourceforge.kolmafia.chat.ChatPoller;
import net.sourceforge.kolmafia.chat.ChatSender;
import net.sourceforge.kolmafia.chat.InternalMessage;
import net.sourceforge.kolmafia.chat.WhoMessage;
import net.sourceforge.kolmafia.combat.CombatActionManager;
import net.sourceforge.kolmafia.combat.Macrofier;
import net.sourceforge.kolmafia.combat.MonsterStatusTracker;
import net.sourceforge.kolmafia.maximizer.Boost;
import net.sourceforge.kolmafia.maximizer.Maximizer;
import net.sourceforge.kolmafia.moods.Mood;
import net.sourceforge.kolmafia.moods.MoodManager;
import net.sourceforge.kolmafia.moods.RecoveryManager;
import net.sourceforge.kolmafia.objectpool.Concoction;
import net.sourceforge.kolmafia.objectpool.ConcoctionPool;
import net.sourceforge.kolmafia.objectpool.EffectPool;
import net.sourceforge.kolmafia.objectpool.IntegerPool;
import net.sourceforge.kolmafia.objectpool.ItemPool;
import net.sourceforge.kolmafia.persistence.AdventureQueueDatabase;
import net.sourceforge.kolmafia.persistence.CandyDatabase;
import net.sourceforge.kolmafia.persistence.CandyDatabase.Candy;
import net.sourceforge.kolmafia.persistence.CoinmastersDatabase;
import net.sourceforge.kolmafia.persistence.ConcoctionDatabase;
import net.sourceforge.kolmafia.persistence.EffectDatabase;
import net.sourceforge.kolmafia.persistence.EquipmentDatabase;
import net.sourceforge.kolmafia.persistence.FaxBotDatabase;
import net.sourceforge.kolmafia.persistence.FaxBotDatabase.FaxBot;
import net.sourceforge.kolmafia.persistence.FaxBotDatabase.Monster;
import net.sourceforge.kolmafia.persistence.FamiliarDatabase;
import net.sourceforge.kolmafia.persistence.HolidayDatabase;
import net.sourceforge.kolmafia.persistence.ItemDatabase;
import net.sourceforge.kolmafia.persistence.MallPriceDatabase;
import net.sourceforge.kolmafia.persistence.MonsterDatabase;
import net.sourceforge.kolmafia.persistence.MonsterDatabase.Element;
import net.sourceforge.kolmafia.persistence.MonsterDatabase.Phylum;
import net.sourceforge.kolmafia.persistence.NPCStoreDatabase;
import net.sourceforge.kolmafia.persistence.SkillDatabase;
import net.sourceforge.kolmafia.preferences.Preferences;
import net.sourceforge.kolmafia.request.ApiRequest;
import net.sourceforge.kolmafia.request.AutoMallRequest;
import net.sourceforge.kolmafia.request.AutoSellRequest;
import net.sourceforge.kolmafia.request.CampgroundRequest;
import net.sourceforge.kolmafia.request.ChezSnooteeRequest;
import net.sourceforge.kolmafia.request.ClanLoungeRequest;
import net.sourceforge.kolmafia.request.ClanStashRequest;
import net.sourceforge.kolmafia.request.ClosetRequest;
import net.sourceforge.kolmafia.request.CoinMasterRequest;
import net.sourceforge.kolmafia.request.CraftRequest;
import net.sourceforge.kolmafia.request.CreateItemRequest;
import net.sourceforge.kolmafia.request.DeckOfEveryCardRequest;
import net.sourceforge.kolmafia.request.DeckOfEveryCardRequest.EveryCard;
import net.sourceforge.kolmafia.request.DisplayCaseRequest;
import net.sourceforge.kolmafia.request.EquipmentRequest;
import net.sourceforge.kolmafia.request.FamiliarRequest;
import net.sourceforge.kolmafia.request.FightRequest;
import net.sourceforge.kolmafia.request.FloristRequest;
import net.sourceforge.kolmafia.request.FloristRequest.Florist;
import net.sourceforge.kolmafia.request.GenericRequest;
import net.sourceforge.kolmafia.request.InternalChatRequest;
import net.sourceforge.kolmafia.request.ManageStoreRequest;
import net.sourceforge.kolmafia.request.MicroBreweryRequest;
import net.sourceforge.kolmafia.request.MoneyMakingGameRequest;
import net.sourceforge.kolmafia.request.QuestLogRequest;
import net.sourceforge.kolmafia.request.RelayRequest;
import net.sourceforge.kolmafia.request.StandardRequest;
import net.sourceforge.kolmafia.request.StorageRequest;
import net.sourceforge.kolmafia.request.SweetSynthesisRequest;
import net.sourceforge.kolmafia.request.TrendyRequest;
import net.sourceforge.kolmafia.request.UneffectRequest;
import net.sourceforge.kolmafia.request.UseItemRequest;
import net.sourceforge.kolmafia.request.UseSkillRequest;
import net.sourceforge.kolmafia.request.ZapRequest;
import net.sourceforge.kolmafia.session.BanishManager;
import net.sourceforge.kolmafia.session.ChoiceManager;
import net.sourceforge.kolmafia.session.ClanManager;
import net.sourceforge.kolmafia.session.ContactManager;
import net.sourceforge.kolmafia.session.DadManager;
import net.sourceforge.kolmafia.session.DisplayCaseManager;
import net.sourceforge.kolmafia.session.EquipmentManager;
import net.sourceforge.kolmafia.session.FamiliarManager;
import net.sourceforge.kolmafia.session.GoalManager;
import net.sourceforge.kolmafia.session.InventoryManager;
import net.sourceforge.kolmafia.session.MoneyMakingGameManager;
import net.sourceforge.kolmafia.session.MonsterManuelManager;
import net.sourceforge.kolmafia.session.MushroomManager;
import net.sourceforge.kolmafia.session.NumberologyManager;
import net.sourceforge.kolmafia.session.PvpManager;
import net.sourceforge.kolmafia.session.ResultProcessor;
import net.sourceforge.kolmafia.session.SorceressLairManager;
import net.sourceforge.kolmafia.session.StoreManager;
import net.sourceforge.kolmafia.session.StoreManager.SoldItem;
import net.sourceforge.kolmafia.session.TavernManager;
import net.sourceforge.kolmafia.session.TurnCounter;
import net.sourceforge.kolmafia.svn.SVNManager;
import net.sourceforge.kolmafia.swingui.FaxRequestFrame;
import net.sourceforge.kolmafia.swingui.widget.InterruptableDialog;
import net.sourceforge.kolmafia.textui.command.ConditionalStatement;
import net.sourceforge.kolmafia.textui.command.SetPreferencesCommand;
import net.sourceforge.kolmafia.textui.parsetree.AggregateType;
import net.sourceforge.kolmafia.textui.parsetree.AggregateValue;
import net.sourceforge.kolmafia.textui.parsetree.ArrayValue;
import net.sourceforge.kolmafia.textui.parsetree.CompositeValue;
import net.sourceforge.kolmafia.textui.parsetree.FunctionList;
import net.sourceforge.kolmafia.textui.parsetree.LibraryFunction;
import net.sourceforge.kolmafia.textui.parsetree.MapValue;
import net.sourceforge.kolmafia.textui.parsetree.RecordType;
import net.sourceforge.kolmafia.textui.parsetree.RecordValue;
import net.sourceforge.kolmafia.textui.parsetree.Type;
import net.sourceforge.kolmafia.textui.parsetree.Value;
import net.sourceforge.kolmafia.utilities.CharacterEntities;
import net.sourceforge.kolmafia.utilities.ChoiceUtilities;
import net.sourceforge.kolmafia.utilities.FileUtilities;
import net.sourceforge.kolmafia.utilities.HTMLParserUtils;
import net.sourceforge.kolmafia.utilities.InputFieldUtilities;
import net.sourceforge.kolmafia.utilities.LogStream;
import net.sourceforge.kolmafia.utilities.StringUtilities;
import net.sourceforge.kolmafia.webui.RelayServer;
public abstract class RuntimeLibrary
{
private static final RecordType itemDropRec = new RecordType(
"{item drop; int rate; string type;}",
new String[] { "drop", "rate", "type" },
new Type[] { DataTypes.ITEM_TYPE, DataTypes.INT_TYPE, DataTypes.STRING_TYPE } );
private static final RecordType maximizerResults = new RecordType(
"{string display; string command; float score; effect effect; item item; skill skill;}",
new String[] { "display", "command", "score", "effect", "item", "skill" },
new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE, DataTypes.FLOAT_TYPE, DataTypes.EFFECT_TYPE, DataTypes.ITEM_TYPE, DataTypes.SKILL_TYPE } );
private static final RecordType svnInfoRec = new RecordType(
"{string url; int revision; string last_changed_author; int last_changed_rev; string last_changed_date;}",
new String[] { "url", "revision", "last_changed_author", "last_changed_rev", "last_changed_date"},
new Type[] { DataTypes.STRING_TYPE, DataTypes.INT_TYPE, DataTypes.STRING_TYPE, DataTypes.INT_TYPE, DataTypes.STRING_TYPE} );
private static final AggregateType NumberologyType = new AggregateType( DataTypes.INT_TYPE, DataTypes.INT_TYPE );
public static final FunctionList functions = new FunctionList();
// *** Why can't the following go in KoLConstants?
public static final Set<String> frameNames = new HashSet<String>();
static
{
for ( String[] frame : KoLConstants.FRAME_NAMES )
{
RuntimeLibrary.frameNames.add( frame[ 1 ] );
}
RuntimeLibrary.frameNames.add( "AnnouncementFrame" );
RuntimeLibrary.frameNames.add( "CakeArenaFrame" );
RuntimeLibrary.frameNames.add( "ChatFrame" );
RuntimeLibrary.frameNames.add( "CouncilFrame" );
RuntimeLibrary.frameNames.add( "DescriptionFrame" );
RuntimeLibrary.frameNames.add( "LoginFrame" );
RuntimeLibrary.frameNames.add( "MonsterDescriptionFrame" );
RuntimeLibrary.frameNames.add( "ProfileFrame" );
RuntimeLibrary.frameNames.add( "RequestSynchFrame" );
RuntimeLibrary.frameNames.add( "ScriptManageFrame" );
RuntimeLibrary.frameNames.add( "SendMessageFrame" );
RuntimeLibrary.frameNames.add( "TabbedChatFrame" );
RuntimeLibrary.frameNames.add( "TrophyFrame" );
}
public static FunctionList getFunctions()
{
return RuntimeLibrary.functions;
}
static
{
Type[] params;
// Basic utility functions which print information
// or allow for easy testing.
params = new Type[] {};
functions.add( new LibraryFunction( "get_version", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_revision", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_path", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_path_full", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_path_variables", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "batch_open", DataTypes.VOID_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "batch_close", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "enable", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "disable", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "user_confirm", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.INT_TYPE, DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "user_confirm", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "logprint", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "traceprint", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "print", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "print", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "print_html", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "abort", DataTypes.VOID_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "abort", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "cli_execute", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "load_html", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "write", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "writeln", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "form_field", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "form_fields", new AggregateType(
DataTypes.STRING_TYPE, DataTypes.STRING_TYPE ), params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "visit_url", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "visit_url", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "visit_url", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.BOOLEAN_TYPE, DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "visit_url", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.BOOLEAN_TYPE, DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "make_url", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "wait", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "waitq", DataTypes.VOID_TYPE, params ) );
// Type conversion functions which allow conversion
// of one data format to another.
params = new Type[] { DataTypes.ANY_TYPE };
functions.add( new LibraryFunction( "to_json", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "to_string", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "to_string", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.FLOAT_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "to_string", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_boolean", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "to_boolean", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "to_boolean", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_int", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "to_int", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "to_int", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.FLOAT_TYPE };
functions.add( new LibraryFunction( "to_int", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "to_int", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.FAMILIAR_TYPE };
functions.add( new LibraryFunction( "to_int", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.SKILL_TYPE };
functions.add( new LibraryFunction( "to_int", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.EFFECT_TYPE };
functions.add( new LibraryFunction( "to_int", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.CLASS_TYPE };
functions.add( new LibraryFunction( "to_int", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.THRALL_TYPE };
functions.add( new LibraryFunction( "to_int", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.SERVANT_TYPE };
functions.add( new LibraryFunction( "to_int", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.VYKEA_TYPE };
functions.add( new LibraryFunction( "to_int", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_float", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] { DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "to_float", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "to_float", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] { DataTypes.FLOAT_TYPE };
functions.add( new LibraryFunction( "to_float", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_item", DataTypes.ITEM_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "to_item", DataTypes.ITEM_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "to_item", DataTypes.ITEM_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_location", DataTypes.LOCATION_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "to_location", DataTypes.LOCATION_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_class", DataTypes.CLASS_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "to_class", DataTypes.CLASS_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_stat", DataTypes.STAT_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_skill", DataTypes.SKILL_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "to_skill", DataTypes.SKILL_TYPE, params ) );
params = new Type[] { DataTypes.EFFECT_TYPE };
functions.add( new LibraryFunction( "to_skill", DataTypes.SKILL_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_effect", DataTypes.EFFECT_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "to_effect", DataTypes.EFFECT_TYPE, params ) );
params = new Type[] { DataTypes.SKILL_TYPE };
functions.add( new LibraryFunction( "to_effect", DataTypes.EFFECT_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_familiar", DataTypes.FAMILIAR_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "to_familiar", DataTypes.FAMILIAR_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_monster", DataTypes.MONSTER_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "to_monster", DataTypes.MONSTER_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "image_to_monster", DataTypes.MONSTER_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_slot", DataTypes.SLOT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "to_slot", DataTypes.SLOT_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_element", DataTypes.ELEMENT_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_coinmaster", DataTypes.COINMASTER_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_phylum", DataTypes.PHYLUM_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_bounty", DataTypes.BOUNTY_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_thrall", DataTypes.THRALL_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "to_thrall", DataTypes.THRALL_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_servant", DataTypes.SERVANT_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "to_servant", DataTypes.SERVANT_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "to_vykea", DataTypes.VYKEA_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "to_plural", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.LOCATION_TYPE };
functions.add( new LibraryFunction( "to_url", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "desc_to_effect", DataTypes.EFFECT_TYPE, params ) );
// Functions related to daily information which get
// updated usually once per day.
params = new Type[] {};
functions.add( new LibraryFunction( "holiday", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "today_to_string", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "time_to_string", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "now_to_string", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "format_date_time", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "gameday_to_string", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "gameday_to_int", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "gametime_to_int", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "moon_phase", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "moon_light", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "stat_bonus_today", DataTypes.STAT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "stat_bonus_tomorrow", DataTypes.STAT_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "session_logs", new AggregateType( DataTypes.STRING_TYPE, 0 ), params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "session_logs", new AggregateType( DataTypes.STRING_TYPE, 0 ), params ) );
// Major functions related to adventuring and
// item management.
params = new Type[] { DataTypes.LOCATION_TYPE };
functions.add( new LibraryFunction( "set_location", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.LOCATION_TYPE };
functions.add( new LibraryFunction( "adventure", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.LOCATION_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "adventure", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.LOCATION_TYPE, DataTypes.INT_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "adv1", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "get_ccs_action", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "can_still_steal", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "add_item_condition", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "remove_item_condition", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "goal_exists", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "is_goal", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_goals", new AggregateType( DataTypes.STRING_TYPE, 0 ), params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_moods", new AggregateType( DataTypes.STRING_TYPE, 0 ), params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "buy", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "buy", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "buy_using_storage", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "buy_using_storage", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.COINMASTER_TYPE };
functions.add( new LibraryFunction( "is_accessible", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.COINMASTER_TYPE };
functions.add( new LibraryFunction( "inaccessible_reason", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.COINMASTER_TYPE };
functions.add( new LibraryFunction( "visit", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.COINMASTER_TYPE, DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "buy", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.COINMASTER_TYPE, DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "sell", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.INT_TYPE, DataTypes.ITEM_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "craft", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "create", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "use", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "eat", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "eatsilent", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "drink", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "overdrink", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "chew", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "last_item_message", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "empty_closet", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "put_closet", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "put_closet", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "put_shop", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.INT_TYPE, DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "put_shop", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "put_shop_using_storage", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.INT_TYPE, DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "put_shop_using_storage", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "reprice_shop", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "reprice_shop", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "put_stash", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "put_display", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "take_closet", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "take_closet", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "take_shop", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "take_shop", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "take_storage", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "take_display", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "take_stash", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "autosell", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "hermit", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "retrieve_item", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE };
functions.add( new LibraryFunction( "faxbot", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE };
functions.add( new LibraryFunction( "can_faxbot", DataTypes.BOOLEAN_TYPE, params ) );
// Major functions which provide item-related
// information.
params = new Type[] {};
functions.add( new LibraryFunction( "get_inventory", DataTypes.ITEM_TO_INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_closet", DataTypes.ITEM_TO_INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_storage", DataTypes.ITEM_TO_INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_free_pulls", DataTypes.ITEM_TO_INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_shop", DataTypes.ITEM_TO_INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_stash", DataTypes.ITEM_TO_INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_campground", DataTypes.ITEM_TO_INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_clan_lounge", DataTypes.ITEM_TO_INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_clan_rumpus", DataTypes.STRING_TO_INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_chateau", DataTypes.ITEM_TO_INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_dwelling", DataTypes.ITEM_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "get_related", DataTypes.ITEM_TO_INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "is_npc_item", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "is_coinmaster_item", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "is_tradeable", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "is_giftable", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "is_displayable", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "is_discardable", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "autosell_price", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "mall_price", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "npc_price", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "shop_price", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.COINMASTER_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "buys_item", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.COINMASTER_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "buy_price", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.COINMASTER_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "sells_item", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.COINMASTER_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "sell_price", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "historical_price", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "historical_age", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "daily_special", DataTypes.ITEM_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "refresh_shop", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "refresh_stash", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "available_amount", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "item_amount", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "closet_amount", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "equipped_amount", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "creatable_amount", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "creatable_turns", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "creatable_turns", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE, DataTypes.INT_TYPE, DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "creatable_turns", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "get_ingredients", DataTypes.ITEM_TO_INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "storage_amount", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "display_amount", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "shop_amount", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "stash_amount", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "pulls_remaining", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "stills_available", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "have_mushroom_plot", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "craft_type", DataTypes.STRING_TYPE, params ) );
// The following functions pertain to providing updated
// information relating to the player.
params = new Type[] {};
functions.add( new LibraryFunction( "refresh_status", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "restore_hp", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "restore_mp", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "mood_execute", DataTypes.VOID_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_name", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_id", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_hash", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_sign", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_path", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "in_muscle_sign", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "in_mysticality_sign", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "in_moxie_sign", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "in_bad_moon", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_class", DataTypes.CLASS_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_level", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_hp", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_maxhp", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_mp", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_maxmp", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_primestat", DataTypes.STAT_TYPE, params ) );
params = new Type[] { DataTypes.STAT_TYPE };
functions.add( new LibraryFunction( "my_basestat", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.STAT_TYPE };
functions.add( new LibraryFunction( "my_buffedstat", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_fury", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_soulsauce", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_discomomentum", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_audience", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_absorbs", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_thunder", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_rain", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_lightning", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_maxfury", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_meat", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_closet_meat", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_storage_meat", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_session_meat", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_adventures", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_daycount", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_turncount", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_fullness", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "fullness_limit", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_inebriety", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "inebriety_limit", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_spleen_use", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "spleen_limit", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "can_eat", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "can_drink", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "turns_played", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "total_turns_played", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_ascensions", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "can_interact", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "in_hardcore", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "pvp_attacks_left", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "current_pvp_stances", new AggregateType( DataTypes.INT_TYPE, DataTypes.STRING_TYPE ), params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_clan_id", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_clan_name", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "limit_mode", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_florist_plants",
new AggregateType( new AggregateType( DataTypes.STRING_TYPE, 3 ),
DataTypes.LOCATION_TYPE ), params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "total_free_rests", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_ignore_zone_warnings", DataTypes.BOOLEAN_TYPE, params ) );
// Basic skill and effect functions, including those used
// in custom combat consult scripts.
params = new Type[] { DataTypes.SKILL_TYPE };
functions.add( new LibraryFunction( "have_skill", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.SKILL_TYPE };
functions.add( new LibraryFunction( "mp_cost", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.SKILL_TYPE };
functions.add( new LibraryFunction( "adv_cost", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.SKILL_TYPE };
functions.add( new LibraryFunction( "soulsauce_cost", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.SKILL_TYPE };
functions.add( new LibraryFunction( "thunder_cost", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.SKILL_TYPE };
functions.add( new LibraryFunction( "rain_cost", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.SKILL_TYPE };
functions.add( new LibraryFunction( "lightning_cost", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.SKILL_TYPE };
functions.add( new LibraryFunction( "turns_per_cast", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.EFFECT_TYPE };
functions.add( new LibraryFunction( "have_effect", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_effects", new AggregateType(
DataTypes.INT_TYPE, DataTypes.EFFECT_TYPE ), params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.SKILL_TYPE };
functions.add( new LibraryFunction( "use_skill", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.SKILL_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "use_skill", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "last_skill_message", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_auto_attack", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "set_auto_attack", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "set_auto_attack", DataTypes.VOID_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "attack", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "steal", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "runaway", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] { DataTypes.SKILL_TYPE };
functions.add( new LibraryFunction( "use_skill", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "throw_item", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "throw_items", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "run_choice", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "last_choice", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "available_choice_options", DataTypes.INT_TO_STRING_TYPE, params ) );
params = new Type[] { DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "available_choice_options", DataTypes.INT_TO_STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "run_combat", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "run_combat", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "run_turn", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "stun_skill", DataTypes.SKILL_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "reverse_numberology", NumberologyType, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "reverse_numberology", NumberologyType, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "numberology_prize", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRICT_STRING_TYPE };
functions.add( new LibraryFunction( "every_card_name", DataTypes.STRING_TYPE, params ) );
// Equipment functions.
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "can_equip", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "equip", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.SLOT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "equip", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.SLOT_TYPE };
functions.add( new LibraryFunction( "equipped_item", DataTypes.ITEM_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "have_equipped", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_outfits", new AggregateType( DataTypes.STRING_TYPE, 0 ), params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "get_custom_outfits", new AggregateType( DataTypes.STRING_TYPE, 0 ), params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "all_normal_outfits", new AggregateType( DataTypes.STRING_TYPE, 0 ), params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "outfit", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "have_outfit", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "is_wearing_outfit", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "outfit_pieces", new AggregateType( DataTypes.ITEM_TYPE, 0 ), params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "outfit_tattoo", DataTypes.STRING_TYPE, params ) );
// Familiar functions.
params = new Type[] {};
functions.add( new LibraryFunction( "my_familiar", DataTypes.FAMILIAR_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_effective_familiar", DataTypes.FAMILIAR_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_enthroned_familiar", DataTypes.FAMILIAR_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_bjorned_familiar", DataTypes.FAMILIAR_TYPE, params ) );
params = new Type[] { DataTypes.FAMILIAR_TYPE };
functions.add( new LibraryFunction( "have_familiar", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.FAMILIAR_TYPE };
functions.add( new LibraryFunction( "use_familiar", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.FAMILIAR_TYPE };
functions.add( new LibraryFunction( "enthrone_familiar", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.FAMILIAR_TYPE };
functions.add( new LibraryFunction( "bjornify_familiar", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.FAMILIAR_TYPE };
functions.add( new LibraryFunction( "familiar_equipment", DataTypes.ITEM_TYPE, params ) );
params = new Type[] { DataTypes.FAMILIAR_TYPE };
functions.add( new LibraryFunction( "familiar_equipped_equipment", DataTypes.ITEM_TYPE, params ) );
params = new Type[] { DataTypes.FAMILIAR_TYPE };
functions.add( new LibraryFunction( "familiar_weight", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "equip_all_familiars", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "is_familiar_equipment_locked", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "favorite_familiars", new
AggregateType( DataTypes.BOOLEAN_TYPE, DataTypes.FAMILIAR_TYPE ), params ) );
params = new Type[] { DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "lock_familiar_equipment", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "weapon_hands", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "item_type", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "weapon_type", DataTypes.STAT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "get_power", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "minstrel_level", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "minstrel_instrument", DataTypes.ITEM_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "minstrel_quest", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_companion", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_thrall", DataTypes.THRALL_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_servant", DataTypes.SERVANT_TYPE, params ) );
params = new Type[] { DataTypes.SERVANT_TYPE };
functions.add( new LibraryFunction( "have_servant", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.SERVANT_TYPE };
functions.add( new LibraryFunction( "use_servant", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "my_vykea_companion", DataTypes.VYKEA_TYPE, params ) );
// Random other functions related to current in-game
// state, not directly tied to the character.
params = new Type[] {};
functions.add( new LibraryFunction( "council", DataTypes.VOID_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "current_mcd", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "change_mcd", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "current_rad_sickness", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "have_chef", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "have_bartender", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "have_shop", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "have_display", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "hippy_stone_broken", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.INT_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "get_counters", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "eudora", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "eudora", DataTypes.BOOLEAN_TYPE, params ) );
// String parsing functions.
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "is_integer", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "contains_text", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "starts_with", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "ends_with", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "extract_meat", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "extract_items", DataTypes.ITEM_TO_INT_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "length", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "char_at", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "index_of", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "index_of", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "last_index_of", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "last_index_of", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "substring", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.INT_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "substring", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "to_lower_case", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "to_upper_case", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "leetify", DataTypes.STRING_TYPE, params ) );
// String buffer functions
params = new Type[] { DataTypes.BUFFER_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "append", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] { DataTypes.BUFFER_TYPE, DataTypes.INT_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "insert", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] { DataTypes.BUFFER_TYPE, DataTypes.INT_TYPE, DataTypes.INT_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "replace", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] { DataTypes.BUFFER_TYPE, DataTypes.INT_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "delete", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] { DataTypes.BUFFER_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "set_length", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.MATCHER_TYPE, DataTypes.BUFFER_TYPE };
functions.add( new LibraryFunction( "append_tail", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] { DataTypes.MATCHER_TYPE, DataTypes.BUFFER_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "append_replacement", DataTypes.BUFFER_TYPE, params ) );
// Regular expression functions
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "create_matcher", DataTypes.MATCHER_TYPE, params ) );
params = new Type[] { DataTypes.MATCHER_TYPE };
functions.add( new LibraryFunction( "find", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.MATCHER_TYPE };
functions.add( new LibraryFunction( "start", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.MATCHER_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "start", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.MATCHER_TYPE };
functions.add( new LibraryFunction( "end", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.MATCHER_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "end", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.MATCHER_TYPE };
functions.add( new LibraryFunction( "group", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.MATCHER_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "group", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.MATCHER_TYPE };
functions.add( new LibraryFunction( "group_count", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.MATCHER_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "replace_first", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.MATCHER_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "replace_all", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.MATCHER_TYPE };
functions.add( new LibraryFunction( "reset", DataTypes.MATCHER_TYPE, params ) );
params = new Type[] { DataTypes.MATCHER_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "reset", DataTypes.MATCHER_TYPE, params ) );
params = new Type[] { DataTypes.BUFFER_TYPE, DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "replace_string", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "replace_string", DataTypes.BUFFER_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "split_string", new AggregateType(
DataTypes.STRING_TYPE, 0 ), params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "split_string", new AggregateType(
DataTypes.STRING_TYPE, 0 ), params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "group_string", DataTypes.REGEX_GROUP_TYPE, params ) );
// Assorted functions
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "expression_eval", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "modifier_eval", DataTypes.FLOAT_TYPE, params ) );
Type maximizerResultsArray = new AggregateType( maximizerResults, 0 );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "maximize", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.INT_TYPE, DataTypes.INT_TYPE, DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "maximize", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.INT_TYPE, DataTypes.INT_TYPE, DataTypes.BOOLEAN_TYPE, DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "maximize", maximizerResultsArray, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "monster_eval", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "is_online", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "slash_count", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "chat_macro", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "chat_clan", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "chat_clan", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "chat_private", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "chat_notify", DataTypes.VOID_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "who_clan", DataTypes.STRING_TO_BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "get_player_id", DataTypes.STRING_TYPE, params ) );
// Quest handling functions.
params = new Type[] {};
functions.add( new LibraryFunction( "tavern", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "tavern", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "hedge_maze", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "tower_door", DataTypes.BOOLEAN_TYPE, params ) );
// Arithmetic utility functions.
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "random", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.FLOAT_TYPE };
functions.add( new LibraryFunction( "round", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.FLOAT_TYPE };
functions.add( new LibraryFunction( "truncate", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.FLOAT_TYPE };
functions.add( new LibraryFunction( "floor", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.FLOAT_TYPE };
functions.add( new LibraryFunction( "ceil", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.FLOAT_TYPE };
functions.add( new LibraryFunction( "square_root", DataTypes.FLOAT_TYPE, params ) );
// Versions of min and max that return int (if both arguments
// are int) or float (if at least one arg is a float)
//
// The float versions must come first.
params = new Type[] { DataTypes.FLOAT_TYPE, DataTypes.FLOAT_TYPE };
functions.add( new LibraryFunction( "min", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "min", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.FLOAT_TYPE, DataTypes.FLOAT_TYPE };
functions.add( new LibraryFunction( "max", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "max", DataTypes.INT_TYPE, params ) );
// String encoding/decoding functions.
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "url_encode", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "url_decode", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "entity_encode", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "entity_decode", DataTypes.STRING_TYPE, params ) );
// Functions to manipulate settings
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "get_all_properties", DataTypes.STRING_TO_BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "property_exists", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "property_exists", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "property_has_default", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "property_default_value", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "get_property", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "get_property", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "set_property", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "remove_property", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "remove_property", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "rename_property", DataTypes.BOOLEAN_TYPE, params ) );
// Functions for aggregates.
params = new Type[] { DataTypes.AGGREGATE_TYPE };
functions.add( new LibraryFunction( "count", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.AGGREGATE_TYPE };
functions.add( new LibraryFunction( "clear", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.AGGREGATE_TYPE };
functions.add( new LibraryFunction( "file_to_map", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.AGGREGATE_TYPE, DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "file_to_map", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.AGGREGATE_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "map_to_file", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.AGGREGATE_TYPE, DataTypes.STRING_TYPE, DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "map_to_file", DataTypes.BOOLEAN_TYPE, params ) );
// Custom combat helper functions.
params = new Type[] {};
functions.add( new LibraryFunction( "my_location", DataTypes.LOCATION_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "last_monster", DataTypes.MONSTER_TYPE, params ) );
params = new Type[] { DataTypes.LOCATION_TYPE };
functions.add( new LibraryFunction( "get_monsters", new AggregateType(
DataTypes.MONSTER_TYPE, 0 ), params ) );
params = new Type[] { DataTypes.LOCATION_TYPE };
functions.add( new LibraryFunction( "get_location_monsters", new AggregateType( DataTypes.BOOLEAN_TYPE, DataTypes.MONSTER_TYPE ), params ) );
params = new Type[] { DataTypes.LOCATION_TYPE };
functions.add( new LibraryFunction( "appearance_rates", new AggregateType(
DataTypes.FLOAT_TYPE, DataTypes.MONSTER_TYPE ), params ) );
params = new Type[] { DataTypes.LOCATION_TYPE, DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "appearance_rates", new AggregateType(
DataTypes.FLOAT_TYPE, DataTypes.MONSTER_TYPE ), params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "expected_damage", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE };
functions.add( new LibraryFunction( "expected_damage", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "monster_level_adjustment", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "weight_adjustment", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "mana_cost_modifier", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "combat_mana_cost_modifier", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "raw_damage_absorption", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "damage_absorption_percent", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "damage_reduction", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.ELEMENT_TYPE };
functions.add( new LibraryFunction( "elemental_resistance", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "elemental_resistance", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE };
functions.add( new LibraryFunction( "elemental_resistance", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "combat_rate_modifier", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "initiative_modifier", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "experience_bonus", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "meat_drop_modifier", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "item_drop_modifier", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "buffed_hit_stat", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "current_hit_stat", DataTypes.STAT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "monster_element", DataTypes.ELEMENT_TYPE, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE };
functions.add( new LibraryFunction( "monster_element", DataTypes.ELEMENT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "monster_attack", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE };
functions.add( new LibraryFunction( "monster_attack", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "monster_defense", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE };
functions.add( new LibraryFunction( "monster_defense", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "monster_initiative", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE };
functions.add( new LibraryFunction( "monster_initiative", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "monster_hp", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE };
functions.add( new LibraryFunction( "monster_hp", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "monster_phylum", DataTypes.PHYLUM_TYPE, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE };
functions.add( new LibraryFunction( "monster_phylum", DataTypes.PHYLUM_TYPE, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE };
functions.add( new LibraryFunction( "is_banished", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "jump_chance", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE };
functions.add( new LibraryFunction( "jump_chance", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "jump_chance", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE, DataTypes.INT_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "jump_chance", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.LOCATION_TYPE };
functions.add( new LibraryFunction( "jump_chance", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.LOCATION_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "jump_chance", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.LOCATION_TYPE, DataTypes.INT_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "jump_chance", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "item_drops", DataTypes.ITEM_TO_INT_TYPE, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE };
functions.add( new LibraryFunction( "item_drops", DataTypes.ITEM_TO_INT_TYPE, params ) );
Type itemDropRecArray = new AggregateType( itemDropRec, 0 );
params = new Type[] {};
functions.add( new LibraryFunction( "item_drops_array", itemDropRecArray, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE };
functions.add( new LibraryFunction( "item_drops_array", itemDropRecArray, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "meat_drop", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE };
functions.add( new LibraryFunction( "meat_drop", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "will_usually_miss", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "will_usually_dodge", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "dad_sea_monkee_weakness", DataTypes.ELEMENT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "flush_monster_manuel_cache", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE };
functions.add( new LibraryFunction( "monster_manuel_text", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.MONSTER_TYPE, DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "monster_factoids_available", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "all_monsters_with_id", new AggregateType( DataTypes.BOOLEAN_TYPE, DataTypes.MONSTER_TYPE ), params ) );
// Modifier introspection
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "numeric_modifier", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "numeric_modifier", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "numeric_modifier", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] { DataTypes.EFFECT_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "numeric_modifier", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] { DataTypes.SKILL_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "numeric_modifier", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] { DataTypes.FAMILIAR_TYPE, DataTypes.STRING_TYPE, DataTypes.INT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "numeric_modifier", DataTypes.FLOAT_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "boolean_modifier", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "boolean_modifier", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "boolean_modifier", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "string_modifier", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "string_modifier", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "effect_modifier", DataTypes.EFFECT_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "effect_modifier", DataTypes.EFFECT_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "class_modifier", DataTypes.CLASS_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "class_modifier", DataTypes.CLASS_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "skill_modifier", DataTypes.SKILL_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "skill_modifier", DataTypes.SKILL_TYPE, params ) );
params = new Type[] { DataTypes.EFFECT_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "stat_modifier", DataTypes.STAT_TYPE, params ) );
// Quest status inquiries
params = new Type[] {};
functions.add( new LibraryFunction( "white_citadel_available", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "friars_available", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "black_market_available", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "hippy_store_available", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "dispensary_available", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "guild_store_available", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "hidden_temple_unlocked", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "knoll_available", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "canadia_available", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "gnomads_available", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "florist_available", DataTypes.BOOLEAN_TYPE, params ) );
// Path Support
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "is_trendy", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.SKILL_TYPE };
functions.add( new LibraryFunction( "is_trendy", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.FAMILIAR_TYPE };
functions.add( new LibraryFunction( "is_trendy", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "is_trendy", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "is_unrestricted", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.SKILL_TYPE };
functions.add( new LibraryFunction( "is_unrestricted", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.FAMILIAR_TYPE };
functions.add( new LibraryFunction( "is_unrestricted", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "is_unrestricted", DataTypes.BOOLEAN_TYPE, params ) );
// MMG support
params = new Type[] {};
functions.add( new LibraryFunction( "mmg_visit", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "mmg_search", DataTypes.VOID_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "mmg_make_bet", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "mmg_retract_bet", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.BOOLEAN_TYPE };
functions.add( new LibraryFunction( "mmg_take_bet", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "mmg_my_bets", new AggregateType( DataTypes.INT_TYPE, 0 ), params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "mmg_offered_bets", new AggregateType( DataTypes.INT_TYPE, 0 ), params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "mmg_bet_owner", DataTypes.STRING_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "mmg_bet_owner_id", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "mmg_bet_amount", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "mmg_wait_event", DataTypes.INT_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "mmg_bet_taker", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "mmg_bet_taker_id", DataTypes.STRING_TYPE, params ) );
params = new Type[] {};
functions.add( new LibraryFunction( "mmg_bet_winnings", DataTypes.INT_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "svn_exists", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "svn_at_head", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "svn_info", svnInfoRec, params ) );
params = new Type[] { DataTypes.STRING_TYPE, DataTypes.STRING_TYPE };
functions.add( new LibraryFunction( "xpath", new AggregateType( DataTypes.STRING_TYPE, 0 ), params ) );
// Sweet Synthesis
params = new Type[] { DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "candy_for_tier", new AggregateType( DataTypes.ITEM_TYPE, 0 ), params ) );
params = new Type[] { DataTypes.INT_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "candy_for_tier", new AggregateType( DataTypes.ITEM_TYPE, 0 ), params ) );
params = new Type[] { DataTypes.EFFECT_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "sweet_synthesis_pairing", new AggregateType( DataTypes.ITEM_TYPE, 0 ), params ) );
params = new Type[] { DataTypes.EFFECT_TYPE, DataTypes.ITEM_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "sweet_synthesis_pairing", new AggregateType( DataTypes.ITEM_TYPE, 0 ), params ) );
params = new Type[] { DataTypes.ITEM_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "sweet_synthesis_result", DataTypes.EFFECT_TYPE, params ) );
params = new Type[] { DataTypes.EFFECT_TYPE };
functions.add( new LibraryFunction( "sweet_synthesis_pair", new AggregateType( DataTypes.ITEM_TYPE, 0 ), params ) );
params = new Type[] { DataTypes.EFFECT_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "sweet_synthesis_pair", new AggregateType( DataTypes.ITEM_TYPE, 0 ), params ) );
params = new Type[] { DataTypes.EFFECT_TYPE };
functions.add( new LibraryFunction( "sweet_synthesis", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.EFFECT_TYPE, DataTypes.INT_TYPE };
functions.add( new LibraryFunction( "sweet_synthesis", DataTypes.BOOLEAN_TYPE, params ) );
params = new Type[] { DataTypes.ITEM_TYPE, DataTypes.ITEM_TYPE };
functions.add( new LibraryFunction( "sweet_synthesis", DataTypes.BOOLEAN_TYPE, params ) );
}
public static Method findMethod( final String name, final Class[] args )
throws NoSuchMethodException
{
return RuntimeLibrary.class.getMethod( name, args );
}
private static Value continueValue()
{
boolean continueValue = Interpreter.getContinueValue();
Interpreter.forgetPendingState();
return DataTypes.makeBooleanValue( continueValue );
}
// Support for batching of server requests
private static void batchCommand( Interpreter interpreter, String cmd, String prefix, String params )
{
LinkedHashMap<String, LinkedHashMap<String, StringBuilder>> batched = interpreter.batched;
if ( batched == null )
{
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( cmd, prefix == null ? params : (prefix + " " + params) );
return;
}
LinkedHashMap<String, StringBuilder> prefixMap = batched.get( cmd );
if ( prefixMap == null )
{
// First instance of this command
prefixMap = new LinkedHashMap<String, StringBuilder>();
batched.put( cmd, prefixMap );
}
String key = prefix == null ? "" : prefix;
StringBuilder buf = prefixMap.get( key );
if ( buf == null )
{
buf = new StringBuilder( params );
prefixMap.put( key, buf );
}
else
{
buf.append( ", " );
buf.append( params );
}
}
public static Value get_version( Interpreter interpreter )
{
return new Value( KoLConstants.VERSION_NAME );
}
public static Value get_revision( Interpreter interpreter )
{
return new Value( StaticEntity.getRevision() );
}
public static Value get_path( Interpreter interpreter )
{
RelayRequest relayRequest = interpreter.getRelayRequest();
if ( relayRequest == null )
{
return DataTypes.STRING_INIT;
}
return new Value( relayRequest.getBasePath() );
}
public static Value get_path_full( Interpreter interpreter )
{
RelayRequest relayRequest = interpreter.getRelayRequest();
if ( relayRequest == null )
{
return DataTypes.STRING_INIT;
}
return new Value( relayRequest.getPath() );
}
public static Value get_path_variables( Interpreter interpreter )
{
RelayRequest relayRequest = interpreter.getRelayRequest();
if ( relayRequest == null )
{
return DataTypes.STRING_INIT;
}
String value = relayRequest.getPath();
int quest = value.indexOf( "?" );
return quest == -1 ? DataTypes.STRING_INIT : new Value( value.substring( quest ) );
}
public static Value batch_open( Interpreter interpreter )
{
if ( interpreter.batched == null )
{
interpreter.batched = new LinkedHashMap<String, LinkedHashMap<String, StringBuilder>>();
}
return DataTypes.VOID_VALUE;
}
public static Value batch_close( Interpreter interpreter )
{
LinkedHashMap<String, LinkedHashMap<String, StringBuilder>> batched = interpreter.batched;
if ( batched != null )
{
Iterator i1 = batched.entrySet().iterator();
while ( i1.hasNext() && KoLmafia.permitsContinue() )
{
Map.Entry e1 = (Map.Entry) i1.next();
String cmd = (String) e1.getKey();
LinkedHashMap<String, StringBuilder> prefixes = (LinkedHashMap<String, StringBuilder>) e1.getValue();
Iterator i2 = prefixes.entrySet().iterator();
while ( i2.hasNext() && KoLmafia.permitsContinue() )
{
Map.Entry e2 = (Map.Entry) i2.next();
String prefix = (String) e2.getKey();
String params = ((StringBuilder) e2.getValue()).toString();
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( cmd, prefix.equals( "" ) ? params : (prefix + " " + params) );
}
}
interpreter.batched = null;
}
return RuntimeLibrary.continueValue();
}
// Basic utility functions which print information
// or allow for easy testing.
public static Value enable( Interpreter interpreter, final Value name )
{
StaticEntity.enable( name.toString().toLowerCase() );
return DataTypes.VOID_VALUE;
}
public static Value disable( Interpreter interpreter, final Value name )
{
StaticEntity.disable( name.toString().toLowerCase() );
return DataTypes.VOID_VALUE;
}
public static Value user_confirm( Interpreter interpreter, final Value message )
{
return DataTypes.makeBooleanValue( InputFieldUtilities.confirm( message.toString() ) );
}
public static Value user_confirm( Interpreter interpreter, final Value message, final Value timeOut,
final Value defaultBoolean )
{
return InterruptableDialog.confirm( message, timeOut, defaultBoolean );
}
private static String cleanString( Value string )
{
String parameters = string.toString();
parameters = StringUtilities.globalStringDelete( parameters, "\n" );
parameters = StringUtilities.globalStringDelete( parameters, "\r" );
return parameters;
}
public static Value logprint( Interpreter interpreter, final Value string )
{
String parameters = RuntimeLibrary.cleanString( string );
RequestLogger.getSessionStream().println( "> " + parameters );
return DataTypes.VOID_VALUE;
}
public static Value traceprint( Interpreter interpreter, final Value string )
{
if ( RequestLogger.isTracing() )
{
String parameters = RuntimeLibrary.cleanString( string );
RequestLogger.trace( "trace: " + parameters );
}
return DataTypes.VOID_VALUE;
}
public static Value print( Interpreter interpreter, final Value string )
{
String parameters = RuntimeLibrary.cleanString( string );
RequestLogger.getSessionStream().println( "> " + parameters );
parameters = StringUtilities.globalStringReplace( parameters, "<", "<" );
RequestLogger.printLine( parameters );
return DataTypes.VOID_VALUE;
}
public static Value print( Interpreter interpreter, final Value string, final Value color )
{
String parameters = RuntimeLibrary.cleanString( string );
RequestLogger.getSessionStream().println( "> " + parameters );
parameters = StringUtilities.globalStringReplace( parameters, "<", "<" );
String colorString = color.toString();
colorString = StringUtilities.globalStringDelete( colorString, "\"" );
colorString = StringUtilities.globalStringDelete( colorString, "<" );
RequestLogger.printLine( "<font color=\"" + colorString + "\">" + parameters + "</font>" );
return DataTypes.VOID_VALUE;
}
public static Value print_html( Interpreter interpreter, final Value string )
{
RequestLogger.printLine( string.toString() );
return DataTypes.VOID_VALUE;
}
public static Value abort( Interpreter interpreter )
{
RuntimeLibrary.abort( interpreter, "Script aborted." );
return DataTypes.VOID_VALUE;
}
public static Value abort( Interpreter interpreter, final Value string )
{
RuntimeLibrary.abort( interpreter, string.toString() );
return DataTypes.VOID_VALUE;
}
private static Value abort( Interpreter interpreter, final String string )
{
KoLmafia.updateDisplay( MafiaState.ABORT, string );
interpreter.setState( Interpreter.STATE_EXIT );
return DataTypes.VOID_VALUE;
}
public static Value cli_execute( Interpreter interpreter, final Value string )
{
KoLmafiaCLI.DEFAULT_SHELL.executeLine( string.toString(), interpreter );
return RuntimeLibrary.continueValue();
}
public static Value load_html( Interpreter interpreter, final Value string )
{
StringBuffer buffer = new StringBuffer();
Value returnValue = new Value( DataTypes.BUFFER_TYPE, "", buffer );
String location = string.toString();
if ( !location.endsWith( ".htm" ) && !location.endsWith( ".html" ) )
{
return returnValue;
}
byte[] bytes = DataFileCache.getBytes( location );
buffer.append( new String( bytes ) );
return returnValue;
}
public static Value write( Interpreter interpreter, final Value string )
{
RelayRequest relayRequest = interpreter.getRelayRequest();
if ( relayRequest == null )
{
return DataTypes.VOID_VALUE;
}
StringBuffer serverReplyBuffer = interpreter.getServerReplyBuffer();
serverReplyBuffer.append( string.toString() );
return DataTypes.VOID_VALUE;
}
public static Value writeln( Interpreter interpreter, final Value string )
{
RelayRequest relayRequest = interpreter.getRelayRequest();
if ( relayRequest == null )
{
return DataTypes.VOID_VALUE;
}
StringBuffer serverReplyBuffer = interpreter.getServerReplyBuffer();
serverReplyBuffer.append( string.toString() );
serverReplyBuffer.append( KoLConstants.LINE_BREAK );
return DataTypes.VOID_VALUE;
}
public static Value form_field( Interpreter interpreter, final Value key )
{
RelayRequest relayRequest = interpreter.getRelayRequest();
if ( relayRequest == null )
{
return DataTypes.STRING_INIT;
}
String value = relayRequest.getFormField( key.toString() );
return value == null ? DataTypes.STRING_INIT : new Value( value );
}
public static Value form_fields( Interpreter interpreter )
{
AggregateType type = new AggregateType( DataTypes.STRING_TYPE, DataTypes.STRING_TYPE );
MapValue value = new MapValue( type );
RelayRequest relayRequest = interpreter.getRelayRequest();
if ( relayRequest == null )
{
return value;
}
for ( String field : relayRequest.getFormFields() )
{
String[] pieces = field.split( "=", 2 );
String name = pieces[ 0 ];
Value keyval = DataTypes.STRING_INIT;
if ( pieces.length > 1 )
{
keyval = new Value( GenericRequest.decodeField( pieces[ 1 ] ) );
}
Value keyname = new Value( name );
while ( value.contains( keyname ) )
{ // Make a unique name for duplicate fields
name = name + "_";
keyname = new Value( name );
}
value.aset( keyname, keyval );
}
return value;
}
public static Value xpath( Interpreter interpreter, final Value html, final Value xpath )
{
HtmlCleaner cleaner = HTMLParserUtils.configureDefaultParser();
TagNode doc;
try
{
doc = cleaner.clean( html.toString() );
}
catch ( IOException e )
{
StaticEntity.printStackTrace( e );
throw interpreter.runtimeException( "something went wrong while cleaning html" );
}
Object[] result;
try
{
result = doc.evaluateXPath( xpath.toString() );
}
catch ( XPatherException e )
{
throw interpreter.runtimeException( "invalid xpath expression" );
}
AggregateType type = new AggregateType( DataTypes.STRING_TYPE, result.length );
ArrayValue value = new ArrayValue( type );
// convert Tagnode objects to strings consisting of their inner HTML
SimpleXmlSerializer serializer = new SimpleXmlSerializer( cleaner.getProperties() );
for ( int i = 0; i < result.length; i++ )
{
Object ob = result[ i ];
if ( ob instanceof TagNode )
{
TagNode tag = (TagNode) ob;
try
{
result[ i ] = serializer.getXmlAsString( tag );
}
catch ( IOException e )
{
StaticEntity.printStackTrace( e );
throw interpreter.runtimeException( "something went wrong while serializing to html" );
}
}
value.aset( new Value( i ), new Value( result[ i ].toString() ) );
}
return value;
}
public static Value visit_url( Interpreter interpreter )
{
RelayRequest relayRequest = interpreter.getRelayRequest();
if ( relayRequest == null )
{
return new Value( DataTypes.BUFFER_TYPE, "", new StringBuffer() );
}
while ( true )
{
RequestThread.postRequest( relayRequest );
if ( relayRequest.redirectLocation == null )
{
break;
}
relayRequest.constructURLString( relayRequest.redirectLocation, false, false );
if ( KoLmafiaASH.getClientHTML( relayRequest ) )
{
break;
}
}
StringBuffer buffer = new StringBuffer();
if ( relayRequest.responseText != null )
{
buffer.append( relayRequest.responseText );
}
return new Value( DataTypes.BUFFER_TYPE, "", buffer );
}
public static Value visit_url( Interpreter interpreter, final Value string )
{
return RuntimeLibrary.visit_url( interpreter, string.toString(), true, false );
}
public static Value visit_url( Interpreter interpreter, final Value string, final Value usePostMethod )
{
return RuntimeLibrary.visit_url( interpreter, string.toString(), usePostMethod.intValue() == 1, false );
}
public static Value visit_url( Interpreter interpreter, final Value string, final Value usePostMethod, final Value encoded )
{
return RuntimeLibrary.visit_url( interpreter, string.toString(), usePostMethod.intValue() == 1, encoded.intValue() == 1 );
}
private static Value visit_url( Interpreter interpreter, final String location )
{
return RuntimeLibrary.visit_url( interpreter, location, true, false );
}
private static Value visit_url( Interpreter interpreter, final String location, final boolean usePostMethod, final boolean encoded )
{
StringBuffer buffer = new StringBuffer();
Value returnValue = new Value( DataTypes.BUFFER_TYPE, "", buffer );
// See if we are inside a relay override
boolean inRelayOverride = interpreter.getRelayRequest() != null;
// If so, use a RelayRequest rather than a GenericRequest
GenericRequest request = inRelayOverride ? new RelayRequest( false ) : new GenericRequest( "" );
// Build the desired URL
request.constructURLString( RelayServer.trimPrefix( location ), usePostMethod, encoded );
if ( GenericRequest.shouldIgnore( request ) )
{
return returnValue;
}
// If we are not in a relay script, ignore a request to an unstarted fight
if ( !inRelayOverride &&
request.getPath().equals( "fight.php" ) &&
FightRequest.getCurrentRound() == 0 )
{
return returnValue;
}
// Post the request and get the response! Note that if we are
// in a relay script, we have to follow all redirection here.
while ( true )
{
RequestThread.postRequest( request );
if ( !inRelayOverride || request.redirectLocation == null )
{
break;
}
request.constructURLString( request.redirectLocation, false, false );
if ( KoLmafiaASH.getClientHTML( (RelayRequest)request ) )
{
break;
}
}
if ( request.responseText != null )
{
buffer.append( request.responseText );
}
return returnValue;
}
public static Value make_url( Interpreter interpreter, final Value arg1, final Value arg2, final Value arg3 )
{
String location = arg1.toString();
boolean usePostMethod = arg2.intValue() == 1;
boolean encoded = arg3.intValue() == 1;
GenericRequest request = new GenericRequest( "" );
request.constructURLString( location, usePostMethod, encoded );
return new Value( request.getURLString() );
}
public static Value wait( Interpreter interpreter, final Value delay )
{
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "wait", delay.toString() );
return DataTypes.VOID_VALUE;
}
public static Value waitq( Interpreter interpreter, final Value delay )
{
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "waitq", delay.toString() );
return DataTypes.VOID_VALUE;
}
// Type conversion functions which allow conversion
// of one data format to another.
public static Value to_json( Interpreter interpreter, Value val )
throws JSONException
{
Object obj = val.asProxy().toJSON();
return new Value( obj instanceof String ? JSONObject.quote( (String) obj ) : obj.toString() );
}
public static Value to_string( Interpreter interpreter, Value val )
{
// This function previously just returned val, except in the
// case of buffers in which case it's necessary to capture the
// current string value of the buffer. That works fine in most
// cases, but NOT if the value ever gets used as a key in a
// map; having a key that's actually an int (for example) in a
// string map causes the map ordering to become inconsistent,
// because int Values compare differently than string Values.
return val.toStringValue();
}
public static Value to_string( Interpreter interpreter, Value val, Value fmt )
{
try
{
Object arg;
if ( val.getType().equals( DataTypes.TYPE_FLOAT ) )
{
arg = new Double( val.floatValue() );
}
else
{
arg = new Long( val.intValue() );
}
return new Value( String.format( fmt.toString(), arg ) );
}
catch ( IllegalFormatException e )
{
throw interpreter.runtimeException( "Invalid format pattern" );
}
}
public static Value to_boolean( Interpreter interpreter, final Value value )
{
return DataTypes.makeBooleanValue( ( value.intValue() != 0 || value.toString().equalsIgnoreCase( "true" ) ) );
}
public static Value to_int( Interpreter interpreter, final Value value )
{
if ( value.getType().equals( DataTypes.TYPE_STRING ) )
{
String string = value.toString();
try
{
return new Value( StringUtilities.parseLongInternal1( string, true ) );
}
catch ( NumberFormatException e )
{
}
// Try again with lax parsing
try
{
long retval = StringUtilities.parseLongInternal2( string );
Exception ex = interpreter.runtimeException( "The string \"" + string + "\" is not an integer; returning " + retval );
RequestLogger.printLine( ex.getMessage() );
return new Value( retval );
}
catch ( NumberFormatException e )
{
// Even with lax parsing, we failed.
Exception ex = interpreter.runtimeException( "The string \"" + string + "\" does not look like an integer; returning 0" );
RequestLogger.printLine( ex.getMessage() );
return DataTypes.ZERO_VALUE;
}
}
return new Value( value.intValue() );
}
public static Value to_float( Interpreter interpreter, final Value value )
{
if ( value.getType().equals( DataTypes.TYPE_STRING ) )
{
String string = value.toString();
try
{
return new Value( StringUtilities.parseFloat( string ) );
}
catch ( NumberFormatException e )
{
Exception ex = interpreter.runtimeException( "The string \"" + string + "\" is not a float; returning 0.0" );
RequestLogger.printLine( ex.getMessage() );
return DataTypes.ZERO_FLOAT_VALUE;
}
}
return value.toFloatValue();
}
public static Value to_item( Interpreter interpreter, final Value value )
{
if ( value.getType().equals( DataTypes.TYPE_INT ) )
{
return DataTypes.makeItemValue( (int) value.intValue(), true );
}
String s1 = value.toString();
Value item = DataTypes.parseItemValue( s1, true, true );
DataTypes.ITEM_TYPE.validateValue( interpreter, s1, item );
return item;
}
public static Value to_item( Interpreter interpreter, final Value name, final Value count )
{
return DataTypes.makeItemValue( ItemDatabase.getItemId( name.toString(), (int) count.intValue() ), true );
}
public static Value to_class( Interpreter interpreter, final Value value )
{
String name = null;
if ( value.getType() == DataTypes.INT_TYPE )
{
int num = (int) value.intValue();
if ( num >= 0 && num < DataTypes.CLASSES.length )
{
name = DataTypes.CLASSES[ num ];
}
}
else
{
name = value.toString();
}
return DataTypes.parseClassValue( name, true );
}
public static Value to_stat( Interpreter interpreter, final Value value )
{
return DataTypes.parseStatValue( value.toString(), true );
}
public static Value to_skill( Interpreter interpreter, final Value value )
{
if ( value.getType().equals( DataTypes.TYPE_INT ) )
{
return DataTypes.makeSkillValue( (int) value.intValue(), true );
}
if ( value.getType().equals( DataTypes.TYPE_EFFECT ) )
{
return DataTypes.parseSkillValue( UneffectRequest.effectToSkill( value.toString() ), true );
}
return DataTypes.parseSkillValue( value.toString(), true );
}
public static Value desc_to_effect( Interpreter interpreter, final Value value )
{
return DataTypes.makeEffectValue( EffectDatabase.getEffectIdFromDescription( value.toString() ), true );
}
public static Value to_effect( Interpreter interpreter, final Value value )
{
if ( value.getType().equals( DataTypes.TYPE_INT ) )
{
return DataTypes.makeEffectValue( (int) value.intValue(), true );
}
if ( value.getType().equals( DataTypes.TYPE_SKILL ) )
{
return DataTypes.parseEffectValue( UneffectRequest.skillToEffect( value.toString() ), true );
}
String s1 = value.toString();
Value effect = DataTypes.parseEffectValue( s1, true );
DataTypes.EFFECT_TYPE.validateValue( interpreter, s1, effect );
return effect;
}
public static Value to_location( Interpreter interpreter, final Value value )
{
if ( value.getType().equals( DataTypes.TYPE_INT ) )
{
return DataTypes.parseLocationValue( (int) value.intValue(), true );
}
else
{
return DataTypes.parseLocationValue( value.toString(), true );
}
}
public static Value to_familiar( Interpreter interpreter, final Value value )
{
if ( value.getType().equals( DataTypes.TYPE_INT ) )
{
return DataTypes.makeFamiliarValue( (int) value.intValue(), true );
}
return DataTypes.parseFamiliarValue( value.toString(), true );
}
public static Value to_monster( Interpreter interpreter, final Value value )
{
if ( value.getType().equals( DataTypes.TYPE_INT ) )
{
return DataTypes.makeMonsterValue( (int) value.intValue(), true );
}
return DataTypes.parseMonsterValue( value.toString(), true );
}
public static Value image_to_monster( Interpreter interpreter, final Value value )
{
MonsterData monster = MonsterDatabase.findMonsterByImage( value.toString() );
return DataTypes.makeMonsterValue( monster );
}
public static Value to_slot( Interpreter interpreter, final Value item )
{
if ( !item.getType().equals( DataTypes.TYPE_ITEM ) )
{
return DataTypes.parseSlotValue( item.toString(), true );
}
switch ( ItemDatabase.getConsumptionType( (int) item.intValue() ) )
{
case KoLConstants.EQUIP_HAT:
return DataTypes.parseSlotValue( "hat", true );
case KoLConstants.EQUIP_WEAPON:
return DataTypes.parseSlotValue( "weapon", true );
case KoLConstants.EQUIP_OFFHAND:
return DataTypes.parseSlotValue( "off-hand", true );
case KoLConstants.EQUIP_SHIRT:
return DataTypes.parseSlotValue( "shirt", true );
case KoLConstants.EQUIP_PANTS:
return DataTypes.parseSlotValue( "pants", true );
case KoLConstants.EQUIP_CONTAINER:
return DataTypes.parseSlotValue( "container", true );
case KoLConstants.EQUIP_FAMILIAR:
return DataTypes.parseSlotValue( "familiar", true );
case KoLConstants.EQUIP_ACCESSORY:
return DataTypes.parseSlotValue( "acc1", true );
default:
return DataTypes.parseSlotValue( "none", true );
}
}
public static Value to_element( Interpreter interpreter, final Value value )
{
return DataTypes.parseElementValue( value.toString(), true );
}
public static Value to_coinmaster( Interpreter interpreter, final Value value )
{
return DataTypes.parseCoinmasterValue( value.toString(), true );
}
public static Value to_phylum( Interpreter interpreter, final Value value )
{
return DataTypes.parsePhylumValue( value.toString(), true );
}
public static Value to_bounty( Interpreter interpreter, final Value value )
{
String stringValue = value.toString();
int numberIndex = stringValue.indexOf( ":" );
return numberIndex != -1 ? DataTypes.parseBountyValue( stringValue.substring( 0, numberIndex ), true ) :
DataTypes.parseBountyValue( stringValue, true );
}
public static Value to_thrall( Interpreter interpreter, final Value value )
{
if ( value.getType().equals( DataTypes.TYPE_INT ) )
{
return DataTypes.makeThrallValue( (int) value.intValue(), true );
}
return DataTypes.parseThrallValue( value.toString(), true );
}
public static Value to_servant( Interpreter interpreter, final Value value )
{
if ( value.getType().equals( DataTypes.TYPE_INT ) )
{
return DataTypes.makeServantValue( (int) value.intValue(), true );
}
return DataTypes.parseServantValue( value.toString(), true );
}
public static Value to_vykea( Interpreter interpreter, final Value value )
{
return DataTypes.parseVykeaValue( value.toString(), true );
}
public static Value to_plural( Interpreter interpreter, final Value item ) {
return new Value( ItemDatabase.getPluralName( (int) item.intValue() ) );
}
public static Value to_url( Interpreter interpreter, final Value value )
{
KoLAdventure adventure = (KoLAdventure) value.rawValue();
return ( adventure == null ) ? DataTypes.STRING_INIT : new Value( adventure.getRequest().getURLString() );
}
// Functions related to daily information which get
// updated usually once per day.
public static Value holiday( Interpreter interpreter )
{
Date today = new Date();
String gameHoliday = HolidayDatabase.getGameHoliday( today );
String realHoliday = HolidayDatabase.getRealLifeHoliday( today );
String result =
gameHoliday != null && realHoliday != null ?
gameHoliday + "/" + realHoliday :
gameHoliday != null ?
gameHoliday :
realHoliday != null ?
realHoliday :
"";
if ( result.equals( "St. Sneaky Pete's Day/Feast of Boris" ) ||
result.equals( "Feast of Boris/St. Sneaky Pete's Day" ) )
{
result = "Drunksgiving";
}
return new Value( result );
}
public static Value today_to_string( Interpreter interpreter )
{
return new Value( KoLConstants.DAILY_FORMAT.format( new Date() ) );
}
public static Value time_to_string( Interpreter interpreter )
{
Calendar timestamp = new GregorianCalendar();
return new Value( KoLConstants.TIME_FORMAT.format( timestamp.getTime() ) );
}
public static Value now_to_string( Interpreter interpreter, Value dateFormatValue )
{
Calendar timestamp = new GregorianCalendar();
SimpleDateFormat dateFormat = new SimpleDateFormat( dateFormatValue.toString() );
return new Value( dateFormat.format( timestamp.getTime() ) );
}
public static Value format_date_time( Interpreter interpreter, Value inFormat, Value dateTimeString, Value outFormat )
{
Date inDate = null;
SimpleDateFormat dateFormat = null;
Value retVal = null;
try
{
dateFormat = new SimpleDateFormat( inFormat.toString() );
inDate = dateFormat.parse( dateTimeString.toString() );
dateFormat= new SimpleDateFormat( outFormat.toString() );
retVal = new Value( dateFormat.format( inDate ) );
}
catch (Exception e)
{
e.printStackTrace();
retVal = new Value( "Bad parameter(s) passed to format_date_time" );
}
return retVal;
}
public static Value gameday_to_string( Interpreter interpreter )
{
return new Value( HolidayDatabase.getCalendarDayAsString( HolidayDatabase.getCalendarDay( new Date() ) ) );
}
public static Value gameday_to_int( Interpreter interpreter )
{
return new Value( HolidayDatabase.getCalendarDay( new Date() ) );
}
public static Value gametime_to_int( Interpreter interpreter )
{
return new Value( HolidayDatabase.getTimeDifference( new Date() ) );
}
public static Value moon_phase( Interpreter interpreter )
{
return new Value( HolidayDatabase.getPhaseStep() );
}
public static Value moon_light( Interpreter interpreter )
{
return new Value( HolidayDatabase.getMoonlight() );
}
public static Value stat_bonus_today( Interpreter interpreter )
{
if ( ConditionalStatement.test( "today is muscle day" ) )
{
return DataTypes.MUSCLE_VALUE;
}
if ( ConditionalStatement.test( "today is myst day" ) )
{
return DataTypes.MYSTICALITY_VALUE;
}
if ( ConditionalStatement.test( "today is moxie day" ) )
{
return DataTypes.MOXIE_VALUE;
}
return DataTypes.STAT_INIT;
}
public static Value stat_bonus_tomorrow( Interpreter interpreter )
{
if ( ConditionalStatement.test( "tomorrow is muscle day" ) )
{
return DataTypes.MUSCLE_VALUE;
}
if ( ConditionalStatement.test( "tomorrow is myst day" ) )
{
return DataTypes.MYSTICALITY_VALUE;
}
if ( ConditionalStatement.test( "tomorrow is moxie day" ) )
{
return DataTypes.MOXIE_VALUE;
}
return DataTypes.STAT_INIT;
}
public static Value session_logs( Interpreter interpreter, final Value dayCount )
{
return RuntimeLibrary.getSessionLogs( interpreter, KoLCharacter.getUserName(), (int) dayCount.intValue() );
}
public static Value session_logs( Interpreter interpreter, final Value player, final Value dayCount )
{
return RuntimeLibrary.getSessionLogs( interpreter, player.toString(), (int) dayCount.intValue() );
}
private static Value getSessionLogs( Interpreter interpreter, final String name, final int dayCount )
{
if ( dayCount < 0 )
{
throw interpreter.runtimeException( "Can't get session logs for a negative number of days" );
}
AggregateType type = new AggregateType( DataTypes.STRING_TYPE, dayCount );
ArrayValue value = new ArrayValue( type );
if ( dayCount < 1 )
{
return value;
}
String[] files = new String[ dayCount ];
Calendar timestamp = Calendar.getInstance( TimeZone.getTimeZone("GMT-0330") );
StringBuilder contents = new StringBuilder();
for ( int i = 0; i < dayCount; ++i )
{
String filename =
StringUtilities.globalStringReplace( name, " ", "_" ) + "_" + KoLConstants.DAILY_FORMAT.format( timestamp.getTime() ) + ".txt";
File path = new File( KoLConstants.SESSIONS_LOCATION, filename );
BufferedReader reader = FileUtilities.getReader( path );
timestamp.add( Calendar.DATE, -1 );
if ( reader == null )
{
continue;
}
try
{
contents.setLength( 0 );
String line;
while ( ( line = reader.readLine() ) != null )
{
contents.append( line );
contents.append( KoLConstants.LINE_BREAK );
}
}
catch ( Exception e )
{
StaticEntity.printStackTrace( e );
}
value.aset( new Value( i ), new Value( contents.toString() ) );
}
return value;
}
// Major functions related to adventuring and
// item management.
public static Value adventure( Interpreter interpreter, final Value countValue, final Value locationValue )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "adventure", count + " " + locationValue );
return RuntimeLibrary.continueValue();
}
public static Value adventure( Interpreter interpreter, final Value countValue, final Value locationValue, final Value filterFunction )
{
try
{
String filter = filterFunction.toString();
Macrofier.setMacroOverride( filter, interpreter );
return RuntimeLibrary.adventure( interpreter, countValue, locationValue );
}
finally
{
Macrofier.resetMacroOverride();
}
}
public static Value adv1( Interpreter interpreter, final Value locationValue, final Value adventuresUsedValue, final Value filterFunction )
{
KoLAdventure adventure = (KoLAdventure) locationValue.rawValue();
if ( adventure == null )
{
return RuntimeLibrary.continueValue();
}
boolean redoSkippedAdventures = KoLmafia.redoSkippedAdventures;
try
{
adventure.overrideAdventuresUsed( (int) adventuresUsedValue.intValue() );
Macrofier.setMacroOverride( filterFunction.toString(), interpreter );
KoLmafia.redoSkippedAdventures = false;
KoLmafia.makeRequest( adventure, 1 );
}
finally
{
KoLmafia.redoSkippedAdventures = redoSkippedAdventures;
Macrofier.resetMacroOverride();
adventure.overrideAdventuresUsed( -1 );
}
return RuntimeLibrary.continueValue();
}
public static Value get_ccs_action( Interpreter interpreter, final Value index )
{
return new Value(
CombatActionManager.getCombatAction(
FightRequest.getCurrentKey(), (int) index.intValue(), true ) );
}
public static Value can_still_steal( Interpreter interpreter )
{
return new Value( FightRequest.canStillSteal() );
}
public static Value add_item_condition( Interpreter interpreter, final Value countValue, final Value item )
{
int count = (int) countValue.intValue();
int itemId = (int) item.intValue();
if ( count <= 0 || itemId <= 0 )
{
return DataTypes.VOID_VALUE;
}
GoalManager.addItemGoal( itemId, count );
return DataTypes.VOID_VALUE;
}
public static Value remove_item_condition( Interpreter interpreter, final Value countValue, final Value item )
{
int count = (int) countValue.intValue();
int itemId = (int) item.intValue();
if ( count <= 0 || itemId <= 0 )
{
return DataTypes.VOID_VALUE;
}
GoalManager.addItemGoal( itemId, 0 - count );
return DataTypes.VOID_VALUE;
}
public static Value goal_exists( Interpreter interpreter, final Value check )
{
String checkType = check.toString();
for ( AdventureResult goal : GoalManager.getGoals() )
{
if ( checkType.equals( goal.getConditionType() ) )
{
return DataTypes.TRUE_VALUE;
}
}
return DataTypes.FALSE_VALUE;
}
public static Value is_goal( Interpreter interpreter, final Value item )
{
return DataTypes.makeBooleanValue( GoalManager.hasItemGoal( (int) item.intValue() ) );
}
public static Value get_goals( Interpreter interpreter )
{
List<AdventureResult> goals = GoalManager.getGoals();
AggregateType type = new AggregateType( DataTypes.STRING_TYPE, goals.size() );
ArrayValue value = new ArrayValue( type );
for ( int i = 0; i < goals.size(); ++i )
{
value.aset( new Value( i ), new Value( goals.get(i).toConditionString() ) );
}
return value;
}
public static Value get_moods( Interpreter interpreter )
{
List<Mood> moods = MoodManager.getAvailableMoods();
AggregateType type = new AggregateType( DataTypes.STRING_TYPE, moods.size() );
ArrayValue value = new ArrayValue( type );
for ( int i = 0; i < moods.size(); ++i )
{
value.aset( new Value( i ), new Value( moods.get( i ).getName() ) );
}
return value;
}
public static Value buy( Interpreter interpreter, final Value countValue, final Value item )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
int itemId = (int) item.intValue();
AdventureResult itemToBuy = ItemPool.get( itemId );
int initialAmount = itemToBuy.getCount( KoLConstants.inventory );
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "buy", count + " \u00B6" + itemId );
return DataTypes.makeBooleanValue( initialAmount + count == itemToBuy.getCount( KoLConstants.inventory ) );
}
public static Value buy( Interpreter interpreter, final Value arg1, final Value arg2, final Value arg3 )
{
if ( arg1.getType().equals( DataTypes.TYPE_COINMASTER ) )
{
return RuntimeLibrary.coinmaster_buy( interpreter, arg1, arg2, arg3 );
}
int count = (int) arg1.intValue();
if ( count <= 0 )
{
return DataTypes.ZERO_VALUE;
}
int itemId = (int) arg2.intValue();
AdventureResult itemToBuy = ItemPool.get( itemId );
int initialAmount = itemToBuy.getCount( KoLConstants.inventory );
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "buy", count + " \u00B6" + itemId + "@" + arg3.intValue() );
return new Value( itemToBuy.getCount( KoLConstants.inventory ) - initialAmount );
}
public static Value buy_using_storage( Interpreter interpreter, final Value countValue, final Value item )
{
if ( KoLCharacter.canInteract() )
{
return DataTypes.FALSE_VALUE;
}
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return DataTypes.TRUE_VALUE;
}
int itemId = (int) item.intValue();
AdventureResult itemToBuy = ItemPool.get( itemId );
int initialAmount = itemToBuy.getCount( KoLConstants.storage );
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "buy", "using storage " + count + " \u00B6" + itemId );
return DataTypes.makeBooleanValue( initialAmount + count == itemToBuy.getCount( KoLConstants.storage ) );
}
public static Value buy_using_storage( Interpreter interpreter, final Value countValue, final Value item, final Value limitValue )
{
if ( KoLCharacter.canInteract() )
{
return DataTypes.ZERO_VALUE;
}
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return DataTypes.ZERO_VALUE;
}
int itemId = (int) item.intValue();
AdventureResult itemToBuy = ItemPool.get( itemId );
int initialAmount = itemToBuy.getCount( KoLConstants.storage );
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "buy", "using storage " + count + " \u00B6" + itemId + "@" + limitValue.intValue() );
return new Value( itemToBuy.getCount( KoLConstants.storage ) - initialAmount );
}
// Coinmaster functions
public static Value is_accessible( Interpreter interpreter, final Value master )
{
CoinmasterData data = (CoinmasterData) master.rawValue();
return DataTypes.makeBooleanValue( data != null && data.isAccessible() );
}
public static Value inaccessible_reason( Interpreter interpreter, final Value master )
{
CoinmasterData data = (CoinmasterData) master.rawValue();
String reason = data != null ? data.accessible() : null;
return new Value( reason != null ? reason : "" );
}
public static Value visit( Interpreter interpreter, final Value master )
{
CoinmasterData data = (CoinmasterData) master.rawValue();
CoinMasterRequest.visit( data );
return RuntimeLibrary.continueValue();
}
private static Value coinmaster_buy( Interpreter interpreter, final Value master, final Value countValue, final Value itemValue )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
CoinmasterData data = (CoinmasterData) master.rawValue();
AdventureResult item = ItemPool.get( (int) itemValue.intValue(), count );
int initialAmount = item.getCount( KoLConstants.inventory );
CoinMasterRequest.buy( data, item );
return DataTypes.makeBooleanValue( initialAmount + count == item.getCount( KoLConstants.inventory ) );
}
public static Value sell( Interpreter interpreter, final Value master, final Value countValue, final Value itemValue )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
CoinmasterData data = (CoinmasterData) master.rawValue();
int itemId = (int) itemValue.intValue();
if ( interpreter.batched != null )
{
String cmd = "coinmaster";
String prefix = "sell " + data.getNickname();
String params = count + " \u00B6" + itemId;
RuntimeLibrary.batchCommand( interpreter, cmd, prefix, params );
}
else
{
AdventureResult item = ItemPool.get( itemId, count );
CoinMasterRequest.sell( data, item );
}
return RuntimeLibrary.continueValue();
}
public static Value craft( Interpreter interpreter, final Value modeValue, final Value countValue, final Value item1, final Value item2 )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return DataTypes.ZERO_VALUE;
}
String mode = modeValue.toString();
int id1 = (int) item1.intValue();
int id2 = (int) item2.intValue();
CraftRequest req = new CraftRequest( mode, count, id1, id2 );
RequestThread.postRequest( req );
return new Value( req.created() );
}
public static Value create( Interpreter interpreter, final Value countValue, final Value item )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "create", count + " \u00B6" + (int) item.intValue() );
return RuntimeLibrary.continueValue();
}
public static Value use( Interpreter interpreter, final Value countValue, final Value item )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "use", count + " \u00B6" + (int) item.intValue() );
return UseItemRequest.lastUpdate.equals( "" ) ? RuntimeLibrary.continueValue() : DataTypes.FALSE_VALUE;
}
public static Value eat( Interpreter interpreter, final Value countValue, final Value item )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "eat", count + " \u00B6" + (int) item.intValue() );
return UseItemRequest.lastUpdate.equals( "" ) ? RuntimeLibrary.continueValue() : DataTypes.FALSE_VALUE;
}
public static Value eatsilent( Interpreter interpreter, final Value countValue, final Value item )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "eatsilent", count + " \u00B6" + (int) item.intValue() );
return UseItemRequest.lastUpdate.equals( "" ) ? RuntimeLibrary.continueValue() : DataTypes.FALSE_VALUE;
}
public static Value drink( Interpreter interpreter, final Value countValue, final Value item )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "drink", count + " \u00B6" + (int) item.intValue() );
return UseItemRequest.lastUpdate.equals( "" ) ? RuntimeLibrary.continueValue() : DataTypes.FALSE_VALUE;
}
public static Value overdrink( Interpreter interpreter, final Value countValue, final Value item )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "overdrink", count + " \u00B6" + (int) item.intValue() );
return UseItemRequest.lastUpdate.equals( "" ) ? RuntimeLibrary.continueValue() : DataTypes.FALSE_VALUE;
}
public static Value chew( Interpreter interpreter, final Value countValue, final Value item )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "chew", count + " \u00B6" + (int) item.intValue() );
return UseItemRequest.lastUpdate.equals( "" ) ? RuntimeLibrary.continueValue() : DataTypes.FALSE_VALUE;
}
public static Value last_item_message( Interpreter interpreter )
{
return new Value( UseItemRequest.lastUpdate );
}
public static Value empty_closet( Interpreter interpreter )
{
if ( interpreter.batched != null )
{
RuntimeLibrary.batchCommand( interpreter, "closet", null, "empty" );
}
else
{
ClosetRequest request = new ClosetRequest( ClosetRequest.EMPTY_CLOSET );
RequestThread.postRequest( request );
}
return RuntimeLibrary.continueValue();
}
public static Value put_closet( Interpreter interpreter, final Value countValue, final Value itemValue )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
int itemId = (int) itemValue.intValue();
if ( interpreter.batched != null )
{
String cmd = "closet";
String prefix = "put";
String params = count + " \u00B6" + itemId;
RuntimeLibrary.batchCommand( interpreter, cmd, prefix, params );
}
else
{
ClosetRequest request = new ClosetRequest( ClosetRequest.INVENTORY_TO_CLOSET, ItemPool.get( itemId, count ) );
RequestThread.postRequest( request );
}
return RuntimeLibrary.continueValue();
}
public static Value put_closet( Interpreter interpreter, final Value meatValue )
{
long meat = meatValue.intValue();
if ( meat <= 0 )
{
return RuntimeLibrary.continueValue();
}
if ( interpreter.batched != null )
{
String cmd = "closet";
String prefix = "put";
String params = meat + " meat";
RuntimeLibrary.batchCommand( interpreter, cmd, prefix, params );
}
else
{
ClosetRequest request = new ClosetRequest( ClosetRequest.MEAT_TO_CLOSET, (int) meat );
RequestThread.postRequest( request );
}
return RuntimeLibrary.continueValue();
}
public static Value put_shop( Interpreter interpreter, final Value priceValue, final Value limitValue, final Value itemValue )
{
return put_shop( interpreter, priceValue, limitValue, InventoryManager.getCount( (int) itemValue.contentLong ), itemValue, false );
}
public static Value put_shop( Interpreter interpreter, final Value priceValue, final Value limitValue, final Value qtyValue, final Value itemValue )
{
return put_shop( interpreter, priceValue, limitValue, qtyValue.contentLong, itemValue, false );
}
public static Value put_shop_using_storage( Interpreter interpreter, final Value priceValue, final Value limitValue, final Value itemValue )
{
AdventureResult item = ItemPool.get( (int) itemValue.intValue(), 0 );
return put_shop( interpreter, priceValue, limitValue, item.getCount( KoLConstants.storage ), itemValue, true );
}
public static Value put_shop_using_storage( Interpreter interpreter, final Value priceValue, final Value limitValue, final Value qtyValue, final Value itemValue )
{
return put_shop( interpreter, priceValue, limitValue, qtyValue.contentLong, itemValue, true );
}
// Used internally only.
private static Value put_shop( Interpreter interpreter, final Value priceValue, final Value limitValue, final long qty, final Value itemValue, boolean usingStorage )
{
if ( qty <= 0 )
{
return RuntimeLibrary.continueValue();
}
int itemId = (int) itemValue.intValue();
int price = (int) priceValue.intValue();
int limit = (int) limitValue.intValue();
if ( interpreter.batched != null )
{
String cmd = "shop";
String prefix = usingStorage ? "put using storage" : "put";
String params = qty + " \u00B6" + itemId + " @ " + price + " limit " + limit;
RuntimeLibrary.batchCommand( interpreter, cmd, prefix, params );
}
else
{
AdventureResult [] items = { ItemPool.get( itemId, (int) qty ) };
int [] prices = { price };
int [] limits = { limit };
ManageStoreRequest request = new ManageStoreRequest( items, prices, limits, usingStorage );
RequestThread.postRequest( request );
}
return RuntimeLibrary.continueValue();
}
public static Value reprice_shop( Interpreter interpreter, final Value priceValue, final Value itemValue )
{
int itemId = (int) itemValue.intValue();
return reprice_shop( interpreter, priceValue, new Value( StoreManager.getLimit( itemId ) ), itemValue );
}
public static Value reprice_shop( Interpreter interpreter, final Value priceValue, final Value limitValue, final Value itemValue )
{
int itemId = (int) itemValue.intValue();
int price = (int) priceValue.intValue();
int limit = (int) limitValue.intValue();
if ( interpreter.batched != null )
{
String cmd = "shop";
String prefix = "reprice";
String params = "\u00B6" + itemId + " @ " + price + " limit " + limit;
RuntimeLibrary.batchCommand( interpreter, cmd, prefix, params );
}
else
{
int [] itemIds = { itemId };
int [] prices = { price };
int [] limits = { limit };
ManageStoreRequest request = new ManageStoreRequest( itemIds, prices, limits );
RequestThread.postRequest( request );
}
return RuntimeLibrary.continueValue();
}
public static Value put_stash( Interpreter interpreter, final Value countValue, final Value itemValue )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
int itemId = (int) itemValue.intValue();
if ( interpreter.batched != null )
{
String cmd = "stash";
String prefix = "put";
String params = count + " \u00B6" + itemId;
RuntimeLibrary.batchCommand( interpreter, cmd, prefix, params );
}
else
{
AdventureResult[] items = new AdventureResult[ 1 ];
items[ 0 ] = ItemPool.get( itemId, count );
ClanStashRequest request = new ClanStashRequest( items, ClanStashRequest.ITEMS_TO_STASH );
RequestThread.postRequest( request );
}
return RuntimeLibrary.continueValue();
}
public static Value put_display( Interpreter interpreter, final Value countValue, final Value itemValue )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
int itemId = (int) itemValue.intValue();
if ( interpreter.batched != null )
{
String cmd = "display";
String prefix = "put";
String params = count + " \u00B6" + itemId;
RuntimeLibrary.batchCommand( interpreter, cmd, prefix, params );
}
else
{
AdventureResult[] items = new AdventureResult[ 1 ];
items[ 0 ] = ItemPool.get( itemId, count );
DisplayCaseRequest request = new DisplayCaseRequest( items, true );
RequestThread.postRequest( request );
}
return RuntimeLibrary.continueValue();
}
public static Value take_closet( Interpreter interpreter, final Value countValue, final Value itemValue )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
int itemId = (int) itemValue.intValue();
if ( interpreter.batched != null )
{
String cmd = "closet";
String prefix = "take";
String params = count + " \u00B6" + itemId;
RuntimeLibrary.batchCommand( interpreter, cmd, prefix, params );
}
else
{
ClosetRequest request = new ClosetRequest( ClosetRequest.CLOSET_TO_INVENTORY, ItemPool.get( itemId, count ) );
RequestThread.postRequest( request );
}
return RuntimeLibrary.continueValue();
}
public static Value take_closet( Interpreter interpreter, final Value meatValue )
{
long meat = meatValue.intValue();
if ( meat <= 0 )
{
return RuntimeLibrary.continueValue();
}
if ( interpreter.batched != null )
{
String cmd = "closet";
String prefix = "take";
String params = meat + " meat";
RuntimeLibrary.batchCommand( interpreter, cmd, prefix, params );
}
else
{
ClosetRequest request = new ClosetRequest( ClosetRequest.MEAT_TO_INVENTORY, (int) meat );
RequestThread.postRequest( request );
}
return RuntimeLibrary.continueValue();
}
public static Value take_shop( Interpreter interpreter, final Value itemValue )
{
int itemId = (int) itemValue.intValue();
if ( interpreter.batched != null )
{
String cmd = "shop";
String prefix = "take";
String params = "all \u00B6" + itemId;
RuntimeLibrary.batchCommand( interpreter, cmd, prefix, params );
}
else
{
List list = StoreManager.getSoldItemList();
SoldItem soldItem = new SoldItem( itemId, 0, 0, 0, 0 );
int index = list.indexOf( soldItem );
if ( index < 0 )
{
return RuntimeLibrary.continueValue();
}
soldItem = (SoldItem) list.get( index );
int count = soldItem.getQuantity();
ManageStoreRequest request = new ManageStoreRequest( itemId, count );
RequestThread.postRequest( request );
}
return RuntimeLibrary.continueValue();
}
public static Value take_shop( Interpreter interpreter, final Value countValue, final Value itemValue )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
int itemId = (int) itemValue.intValue();
if ( interpreter.batched != null )
{
String cmd = "shop";
String prefix = "take";
String params = count + " \u00B6" + itemId;
RuntimeLibrary.batchCommand( interpreter, cmd, prefix, params );
}
else
{
ManageStoreRequest request = new ManageStoreRequest( itemId, count );
RequestThread.postRequest( request );
}
return RuntimeLibrary.continueValue();
}
public static Value take_storage( Interpreter interpreter, final Value countValue, final Value itemValue )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
int itemId = (int) itemValue.intValue();
if ( interpreter.batched != null )
{
String cmd = "hagnk";
String params = count + " \u00B6" + itemId;
RuntimeLibrary.batchCommand( interpreter, cmd, null, params );
}
else
{
StorageRequest request = new StorageRequest( StorageRequest.STORAGE_TO_INVENTORY, ItemPool.get( itemId, count ) );
RequestThread.postRequest( request );
}
return RuntimeLibrary.continueValue();
}
public static Value take_display( Interpreter interpreter, final Value countValue, final Value itemValue )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
int itemId = (int) itemValue.intValue();
if ( interpreter.batched != null )
{
String cmd = "display";
String prefix = "take";
String params = count + " \u00B6" + itemId;
RuntimeLibrary.batchCommand( interpreter, cmd, prefix, params );
}
else
{
AdventureResult[] items = new AdventureResult[ 1 ];
items[ 0 ] = ItemPool.get( itemId, count );
DisplayCaseRequest request = new DisplayCaseRequest( items, false );
RequestThread.postRequest( request );
}
return RuntimeLibrary.continueValue();
}
public static Value take_stash( Interpreter interpreter, final Value countValue, final Value itemValue )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
int itemId = (int) itemValue.intValue();
if ( interpreter.batched != null )
{
String cmd = "stash";
String prefix = "take";
String params = count + " \u00B6" + itemId;
RuntimeLibrary.batchCommand( interpreter, cmd, prefix, params );
}
else
{
AdventureResult[] items = new AdventureResult[ 1 ];
items[ 0 ] = ItemPool.get( itemId, count );
ClanStashRequest request = new ClanStashRequest( items, ClanStashRequest.STASH_TO_ITEMS );
RequestThread.postRequest( request );
}
return RuntimeLibrary.continueValue();
}
public static Value autosell( Interpreter interpreter, final Value countValue, final Value itemValue )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
int itemId = (int) itemValue.intValue();
if ( interpreter.batched != null )
{
String cmd = "sell";
String params = count + " \u00B6" + itemId;
RuntimeLibrary.batchCommand( interpreter, cmd, null, params );
}
else
{
AdventureResult[] items = new AdventureResult[ 1 ];
items[ 0 ] = ItemPool.get( itemId, count );
AutoSellRequest request = new AutoSellRequest( items );
RequestThread.postRequest( request );
}
return RuntimeLibrary.continueValue();
}
public static Value hermit( Interpreter interpreter, final Value countValue, final Value item )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "hermit", count + " " + ItemDatabase.getItemName( (int) item.intValue() ) );
return RuntimeLibrary.continueValue();
}
public static Value retrieve_item( Interpreter interpreter, final Value countValue, final Value item )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
return DataTypes.makeBooleanValue( InventoryManager.retrieveItem( ItemPool.get( (int) item.intValue(), count ) ) );
}
public static Value faxbot( Interpreter interpreter, final Value arg )
{
MonsterData monster = (MonsterData) arg.rawValue();
if ( monster == null )
{
return DataTypes.FALSE_VALUE;
}
FaxBotDatabase.configure();
String actualName = monster.getName();
for ( FaxBot bot : FaxBotDatabase.faxbots )
{
if ( bot == null )
{
continue;
}
String botName = bot.getName();
if ( botName == null )
{
continue;
}
Monster monsterObject = bot.getMonsterByActualName( actualName );
if ( monsterObject == null )
{
continue;
}
if ( !FaxRequestFrame.isBotOnline( botName ) )
{
continue;
}
return DataTypes.makeBooleanValue( FaxRequestFrame.requestFax( botName, monsterObject, false ) );
}
return DataTypes.FALSE_VALUE;
}
public static Value can_faxbot( Interpreter interpreter, final Value arg )
{
MonsterData monster = (MonsterData) arg.rawValue();
if ( monster == null )
{
return DataTypes.FALSE_VALUE;
}
FaxBotDatabase.configure();
String actualName = monster.getName();
for ( FaxBot bot : FaxBotDatabase.faxbots )
{
if ( bot == null )
{
continue;
}
String botName = bot.getName();
if ( botName == null )
{
continue;
}
Monster monsterObject = bot.getMonsterByActualName( actualName );
if ( monsterObject == null )
{
continue;
}
// Don't check if bot is online til we can do it safely for large numbers of can_faxbot requests
//if ( !FaxRequestFrame.isBotOnline( botName ) )
//{
// continue;
//}
return DataTypes.TRUE_VALUE;
}
return DataTypes.FALSE_VALUE;
}
// Major functions which provide item-related
// information.
public static Value get_inventory( Interpreter interpreter )
{
MapValue value = new MapValue( DataTypes.ITEM_TO_INT_TYPE );
AdventureResult [] items = new AdventureResult[ KoLConstants.inventory.size() ];
KoLConstants.inventory.toArray( items );
for ( int i = 0; i < items.length; ++i )
{
value.aset(
DataTypes.makeItemValue( items[i].getItemId(), true ),
new Value( items[i].getCount() ) );
}
return value;
}
public static Value get_closet( Interpreter interpreter )
{
MapValue value = new MapValue( DataTypes.ITEM_TO_INT_TYPE );
AdventureResult [] items = new AdventureResult[ KoLConstants.closet.size() ];
KoLConstants.closet.toArray( items );
for ( int i = 0; i < items.length; ++i )
{
value.aset(
DataTypes.makeItemValue( items[i].getItemId(), true ),
new Value( items[i].getCount() ) );
}
return value;
}
public static Value get_storage( Interpreter interpreter )
{
MapValue value = new MapValue( DataTypes.ITEM_TO_INT_TYPE );
AdventureResult [] items = new AdventureResult[ KoLConstants.storage.size() ];
KoLConstants.storage.toArray( items );
for ( int i = 0; i < items.length; ++i )
{
value.aset(
DataTypes.makeItemValue( items[i].getItemId(), true ),
new Value( items[i].getCount() ) );
}
return value;
}
public static Value get_free_pulls( Interpreter interpreter )
{
MapValue value = new MapValue( DataTypes.ITEM_TO_INT_TYPE );
AdventureResult [] items = new AdventureResult[ KoLConstants.freepulls.size() ];
KoLConstants.freepulls.toArray( items );
for ( int i = 0; i < items.length; ++i )
{
value.aset(
DataTypes.makeItemValue( items[i].getItemId(), true ),
new Value( items[i].getCount() ) );
}
return value;
}
public static Value get_shop( Interpreter interpreter )
{
MapValue value = new MapValue( DataTypes.ITEM_TO_INT_TYPE );
if ( !KoLCharacter.hasStore() )
{
return value;
}
if ( !StoreManager.soldItemsRetrieved )
{
RequestThread.postRequest( new ManageStoreRequest() );
}
List<SoldItem> list = StoreManager.getSoldItemList();
for ( int i = 0; i < list.size(); ++i )
{
SoldItem item = list.get( i );
value.aset( DataTypes.makeItemValue( item.getItemId(), true ),
new Value( item.getQuantity() ) );
}
return value;
}
public static Value get_stash( Interpreter interpreter )
{
MapValue value = new MapValue( DataTypes.ITEM_TO_INT_TYPE );
if ( !KoLCharacter.hasStore() )
{
return value;
}
if ( !ClanManager.stashRetrieved )
{
RequestThread.postRequest( new ClanStashRequest() );
}
List<AdventureResult> list = ClanManager.getStash();
for ( int i = 0; i < list.size(); ++i )
{
AdventureResult item = list.get( i );
value.aset( DataTypes.makeItemValue( item.getItemId(), true ),
new Value( item.getCount() ) );
}
return value;
}
public static Value get_campground( Interpreter interpreter )
{
MapValue value = new MapValue( DataTypes.ITEM_TO_INT_TYPE );
if ( KoLCharacter.inNuclearAutumn() )
{
for ( AdventureResult item : KoLConstants.falloutShelter )
{
value.aset(
DataTypes.makeItemValue( item.getItemId(), true ),
new Value( item.getCount() ) );
}
}
else
{
// Your dwelling is not in the list of campground items
AdventureResult dwelling = CampgroundRequest.getCurrentDwelling();
value.aset( DataTypes.makeItemValue( dwelling.getItemId(), true ), DataTypes.ONE_VALUE );
for ( AdventureResult item : KoLConstants.campground )
{
value.aset(
DataTypes.makeItemValue( item.getItemId(), true ),
new Value( item.getCount() ) );
}
}
return value;
}
public static Value get_clan_lounge( Interpreter interpreter )
{
MapValue value = new MapValue( DataTypes.ITEM_TO_INT_TYPE );
for ( AdventureResult item : ClanManager.getClanLounge() )
{
value.aset(
DataTypes.makeItemValue( item.getItemId(), true ),
new Value( item.getCount() ) );
}
return value;
}
public static Value get_clan_rumpus( Interpreter interpreter )
{
MapValue value = new MapValue( DataTypes.STRING_TO_INT_TYPE );
for ( String name : ClanManager.getClanRumpus() )
{
int count = 1;
int countIndex = name.indexOf( " (" );
if ( countIndex != -1 )
{
count = StringUtilities.parseInt( name.substring( countIndex + 2, name.length() - 1 ) );
name = name.substring( 0, countIndex );
}
value.aset(
new Value( name ),
new Value( count ) );
}
return value;
}
public static Value get_chateau( Interpreter interpreter )
{
MapValue value = new MapValue( DataTypes.ITEM_TO_INT_TYPE );
for ( AdventureResult item : KoLConstants.chateau )
{
value.aset(
DataTypes.makeItemValue( item.getItemId(), true ),
new Value( item.getCount() ) );
}
return value;
}
public static Value get_dwelling( Interpreter interpreter )
{
return DataTypes.makeItemValue( CampgroundRequest.getCurrentDwelling().getItemId(), true );
}
private static final int WAD2POWDER = -12; // <elem> powder - <elem> wad
private static final int WAD2NUGGET = -6;
private static final int WAD2GEM = 1321;
public static Value get_related( Interpreter interpreter, Value item, Value type )
{
MapValue value = new MapValue( DataTypes.ITEM_TO_INT_TYPE );
String which = type.toString();
if ( which.equals( "zap" ) )
{
String[] zapgroup = ZapRequest.getZapGroup( (int) item.intValue() );
for ( int i = zapgroup.length - 1; i >= 0; --i )
{
Value key = DataTypes.parseItemValue( zapgroup[ i ], true );
if ( key.intValue() != item.intValue() )
{
value.aset( key, DataTypes.ZERO_VALUE );
}
}
}
else if ( which.equals( "fold" ) )
{
ArrayList list = ItemDatabase.getFoldGroup( item.toString() );
if ( list == null ) return value;
// Don't use element 0, that's the damage percentage
for ( int i = list.size() - 1; i > 0; --i )
{
value.aset(
DataTypes.parseItemValue( (String) list.get( i ), true ),
new Value( i ) );
}
}
else if ( which.equals( "pulverize" ) )
{ // All values scaled up by one million
int pulver = EquipmentDatabase.getPulverization( (int) item.intValue() );
if ( pulver == -1 || (pulver & EquipmentDatabase.MALUS_UPGRADE) != 0 )
{
return value;
}
if ( pulver > 0 )
{
value.aset( DataTypes.makeItemValue( pulver, true ),
DataTypes.makeIntValue( 1000000 ) );
return value;
}
ArrayList<Integer> elems = new ArrayList<Integer>();
boolean clusters = ( pulver & EquipmentDatabase.YIELD_1C ) != 0;
if ( (pulver & EquipmentDatabase.ELEM_HOT) != 0 )
{
elems.add( IntegerPool.get( clusters ? ItemPool.HOT_CLUSTER : ItemPool.HOT_WAD ) );
}
if ( (pulver & EquipmentDatabase.ELEM_COLD) != 0 )
{
elems.add( IntegerPool.get( clusters ? ItemPool.COLD_CLUSTER : ItemPool.COLD_WAD ) );
}
if ( (pulver & EquipmentDatabase.ELEM_STENCH) != 0 )
{
elems.add( IntegerPool.get( clusters ? ItemPool.STENCH_CLUSTER : ItemPool.STENCH_WAD ) );
}
if ( (pulver & EquipmentDatabase.ELEM_SPOOKY) != 0 )
{
elems.add( IntegerPool.get( clusters ? ItemPool.SPOOKY_CLUSTER : ItemPool.SPOOKY_WAD ) );
}
if ( (pulver & EquipmentDatabase.ELEM_SLEAZE) != 0 )
{
elems.add( IntegerPool.get( clusters ? ItemPool.SLEAZE_CLUSTER : ItemPool.SLEAZE_WAD ) );
}
if ( (pulver & EquipmentDatabase.ELEM_TWINKLY) != 0 )
{ // Important: twinkly must be last
elems.add( IntegerPool.get( ItemPool.TWINKLY_WAD ) );
}
int nelems = elems.size();
if ( nelems == 0 )
{
return value; // shouldn't happen
}
int powders = 0, nuggets = 0, wads = 0;
if ( (pulver & EquipmentDatabase.YIELD_3W) != 0 )
{
wads = 3000000;
}
else if ( (pulver & EquipmentDatabase.YIELD_1W3N_2W) != 0 )
{
wads = 1500000;
nuggets = 1500000;
}
else if ( (pulver & EquipmentDatabase.YIELD_4N_1W) != 0 )
{
wads = 500000;
nuggets = 2000000;
}
else if ( (pulver & EquipmentDatabase.YIELD_3N) != 0 )
{
nuggets = 3000000;
}
else if ( (pulver & EquipmentDatabase.YIELD_1N3P_2N) != 0 )
{
nuggets = 1500000;
powders = 1500000;
}
else if ( (pulver & EquipmentDatabase.YIELD_4P_1N) != 0 )
{
nuggets = 500000;
powders = 2000000;
}
else if ( (pulver & EquipmentDatabase.YIELD_3P) != 0 )
{
powders = 3000000;
}
else if ( (pulver & EquipmentDatabase.YIELD_2P) != 0 )
{
powders = 2000000;
}
else if ( (pulver & EquipmentDatabase.YIELD_1P) != 0 )
{
powders = 1000000;
}
int gems = wads / 100;
wads -= gems;
for ( int wad : elems )
{
if ( powders > 0 )
{
value.aset( DataTypes.makeItemValue( wad + WAD2POWDER, true ),
DataTypes.makeIntValue( powders / nelems ) );
}
if ( nuggets > 0 )
{
value.aset( DataTypes.makeItemValue( wad + WAD2NUGGET, true ),
DataTypes.makeIntValue( nuggets / nelems ) );
}
if ( wads > 0 )
{
if ( wad == ItemPool.TWINKLY_WAD )
{ // no twinkly gem!
wads += gems;
gems = 0;
}
value.aset( DataTypes.makeItemValue( wad, true ),
DataTypes.makeIntValue( wads / nelems ) );
}
if ( gems > 0 )
{
value.aset( DataTypes.makeItemValue( wad + WAD2GEM, true ),
DataTypes.makeIntValue( gems / nelems ) );
}
if ( clusters )
{
value.aset( DataTypes.makeItemValue( wad, true ),
DataTypes.makeIntValue( 1000000 ) );
}
}
}
return value;
}
public static Value is_tradeable( Interpreter interpreter, final Value item )
{
return DataTypes.makeBooleanValue( ItemDatabase.isTradeable( (int) item.intValue() ) );
}
public static Value is_giftable( Interpreter interpreter, final Value item )
{
return DataTypes.makeBooleanValue( ItemDatabase.isGiftable( (int) item.intValue() ) );
}
public static Value is_displayable( Interpreter interpreter, final Value item )
{
int itemId = (int) item.intValue();
return DataTypes.makeBooleanValue( !ItemDatabase.isQuestItem( itemId ) && !ItemDatabase.isVirtualItem( itemId ) );
}
public static Value is_discardable( Interpreter interpreter, final Value item )
{
return DataTypes.makeBooleanValue( ItemDatabase.isDiscardable( (int) item.intValue() ) );
}
public static Value is_npc_item( Interpreter interpreter, final Value item )
{
return DataTypes.makeBooleanValue( NPCStoreDatabase.contains( (int) item.intValue(), false ) );
}
public static Value is_coinmaster_item( Interpreter interpreter, final Value item )
{
return DataTypes.makeBooleanValue( CoinmastersDatabase.contains( (int) item.intValue(), false ) );
}
public static Value autosell_price( Interpreter interpreter, final Value item )
{
return new Value( ItemDatabase.getPriceById( (int) item.intValue() ) );
}
public static Value mall_price( Interpreter interpreter, final Value item )
{
return new Value( StoreManager.getMallPrice( ItemPool.get( (int) item.intValue(), 0 ) ) );
}
public static Value npc_price( Interpreter interpreter, final Value item )
{
int itemId = (int) item.intValue();
String it = ItemDatabase.getCanonicalName( itemId );
return new Value(
NPCStoreDatabase.contains( itemId, true ) ?
NPCStoreDatabase.price( itemId ) :
ClanLoungeRequest.availableSpeakeasyDrink( it ) ?
ClanLoungeRequest.speakeasyNameToCost( it ).intValue() :
0 );
}
public static Value shop_price( Interpreter interpreter, final Value item )
{
if ( !KoLCharacter.hasStore() )
{
return DataTypes.ZERO_VALUE;
}
if ( !StoreManager.soldItemsRetrieved )
{
RequestThread.postRequest( new ManageStoreRequest() );
}
return new Value( StoreManager.getPrice( (int) item.intValue() ) );
}
// Coinmaster functions
public static Value buys_item( Interpreter interpreter, final Value master, final Value item )
{
CoinmasterData data = (CoinmasterData) master.rawValue();
return DataTypes.makeBooleanValue( data != null && data.canSellItem( (int) item.intValue() ) );
}
public static Value buy_price( Interpreter interpreter, final Value master, final Value item )
{
CoinmasterData data = (CoinmasterData) master.rawValue();
return DataTypes.makeIntValue( data != null ? data.getSellPrice( (int) item.intValue() ) : 0 );
}
public static Value sells_item( Interpreter interpreter, final Value master, final Value item )
{
CoinmasterData data = (CoinmasterData) master.rawValue();
return DataTypes.makeBooleanValue( data != null && data.canBuyItem( (int) item.intValue() ) );
}
public static Value sell_price( Interpreter interpreter, final Value master, final Value item )
{
CoinmasterData data = (CoinmasterData) master.rawValue();
return DataTypes.makeIntValue( data != null ? data.getBuyPrice( (int) item.intValue() ) : 0 );
}
public static Value historical_price( Interpreter interpreter, final Value item )
{
return new Value( MallPriceDatabase.getPrice( (int) item.intValue() ) );
}
public static Value historical_age( Interpreter interpreter, final Value item )
{
return new Value( MallPriceDatabase.getAge( (int) item.intValue() ) );
}
public static Value daily_special( Interpreter interpreter )
{
AdventureResult special =
KoLCharacter.gnomadsAvailable() ? MicroBreweryRequest.getDailySpecial() : KoLCharacter.canadiaAvailable() ? ChezSnooteeRequest.getDailySpecial() : null;
return special == null ? DataTypes.ITEM_INIT : DataTypes.makeItemValue( special.getItemId(), true );
}
public static Value refresh_shop( Interpreter interpreter )
{
RequestThread.postRequest( new ManageStoreRequest() );
return RuntimeLibrary.continueValue();
}
public static Value refresh_stash( Interpreter interpreter )
{
RequestThread.postRequest( new ClanStashRequest() );
return RuntimeLibrary.continueValue();
}
public static Value available_amount( Interpreter interpreter, final Value arg )
{
AdventureResult item = ItemPool.get( (int) arg.intValue(), 0 );
return DataTypes.makeIntValue( InventoryManager.getAccessibleCount( item ) );
}
public static Value item_amount( Interpreter interpreter, final Value arg )
{
AdventureResult item = ItemPool.get( (int) arg.intValue(), 0 );
return new Value( item.getCount( KoLConstants.inventory ) );
}
public static Value closet_amount( Interpreter interpreter, final Value arg )
{
AdventureResult item = ItemPool.get( (int) arg.intValue(), 0 );
return new Value( item.getCount( KoLConstants.closet ) );
}
public static Value equipped_amount( Interpreter interpreter, final Value arg )
{
AdventureResult item = ItemPool.get( (int) arg.intValue(), 0 );
int runningTotal = 0;
for ( int i = 0; i <= EquipmentManager.FAMILIAR; ++i )
{
if ( EquipmentManager.getEquipment( i ).equals( item ) )
{
++runningTotal;
}
}
return new Value( runningTotal );
}
public static Value creatable_amount( Interpreter interpreter, final Value arg )
{
CreateItemRequest item = CreateItemRequest.getInstance( (int) arg.intValue() );
return new Value( item == null ? 0 : item.getQuantityPossible() );
}
public static Value creatable_turns( Interpreter interpreter, final Value itemId )
{
AdventureResult item = ItemPool.get( (int) itemId.intValue() );
if ( item == null )
{
return new Value( 0 );
}
int initialAmount = item.getCount( KoLConstants.inventory );
Concoction concoction = ConcoctionPool.get( item );
return new Value( concoction == null ? 0 : concoction.getAdventuresNeeded( initialAmount + 1 ) );
}
public static Value creatable_turns( Interpreter interpreter, final Value itemId, final Value count )
{
AdventureResult item = ItemPool.get( (int) itemId.intValue() );
int number = (int) count.intValue();
if ( item == null )
{
return new Value( 0 );
}
int initialAmount = item.getCount( KoLConstants.inventory );
Concoction concoction = ConcoctionPool.get( item );
return new Value( concoction == null ? 0 : concoction.getAdventuresNeeded( initialAmount + number ) );
}
public static Value creatable_turns( Interpreter interpreter, final Value itemId, final Value count, final Value freeCrafting )
{
AdventureResult item = ItemPool.get( (int) itemId.intValue() );
int number = (int) count.intValue();
boolean considerFreeCrafting = freeCrafting.intValue() == 1;
if ( item == null )
{
return new Value( 0 );
}
int initialAmount = item.getCount( KoLConstants.inventory );
Concoction concoction = ConcoctionPool.get( item );
return new Value( concoction == null ? 0 : concoction.getAdventuresNeeded( initialAmount + number, considerFreeCrafting ) );
}
public static Value get_ingredients( Interpreter interpreter, final Value arg )
{
MapValue value = new MapValue( DataTypes.ITEM_TO_INT_TYPE );
int itemId = (int) arg.intValue();
CraftingType method = ConcoctionDatabase.getMixingMethod( itemId );
EnumSet<CraftingRequirements> requirements = ConcoctionDatabase.getRequirements( itemId );
if ( !ConcoctionDatabase.isPermittedMethod( method, requirements ) )
{
return value; // can't make it
}
AdventureResult[] data = ConcoctionDatabase.getIngredients( itemId );
for ( int i = 0; i < data.length; ++i )
{
AdventureResult ingredient = data[ i ];
if ( ingredient.getItemId() < 0 )
{
// Skip pseudo-ingredients: coinmaster tokens
continue;
}
int count = ingredient.getCount();
Value key = DataTypes.makeItemValue( ingredient.getItemId(), true );
if ( value.contains( key ) )
{
count += (int) value.aref( key ).intValue();
}
value.aset( key, new Value( count ) );
}
return value;
}
public static Value storage_amount( Interpreter interpreter, final Value arg )
{
AdventureResult item = ItemPool.get( (int) arg.intValue(), 0 );
return new Value( item.getCount( KoLConstants.storage ) + item.getCount( KoLConstants.freepulls ) );
}
public static Value display_amount( Interpreter interpreter, final Value arg )
{
if ( !KoLCharacter.hasDisplayCase() )
{
return DataTypes.ZERO_VALUE;
}
if ( !DisplayCaseManager.collectionRetrieved )
{
RequestThread.postRequest( new DisplayCaseRequest() );
}
AdventureResult item = ItemPool.get( (int) arg.intValue(), 0 );
return new Value( item.getCount( KoLConstants.collection ) );
}
public static Value shop_amount( Interpreter interpreter, final Value arg )
{
if ( !KoLCharacter.hasStore() )
{
return DataTypes.ZERO_VALUE;
}
if ( !StoreManager.soldItemsRetrieved )
{
RequestThread.postRequest( new ManageStoreRequest() );
}
SoldItem item = new SoldItem( (int) arg.intValue(), 0, 0, 0, 0 );
List<SoldItem> list = StoreManager.getSoldItemList();
int index = list.indexOf( item );
if ( index < 0 )
{
return DataTypes.ZERO_VALUE;
}
item = (SoldItem) list.get( index );
return new Value( item.getQuantity() );
}
public static Value stash_amount( Interpreter interpreter, final Value arg )
{
if ( !ClanManager.stashRetrieved )
{
RequestThread.postRequest( new ClanStashRequest() );
}
List stash = ClanManager.getStash();
AdventureResult item = ItemPool.get( (int) arg.intValue(), 0 );
return new Value( item.getCount( stash ) );
}
public static Value pulls_remaining( Interpreter interpreter )
{
return new Value( ConcoctionDatabase.getPullsRemaining() );
}
public static Value stills_available( Interpreter interpreter )
{
return new Value( KoLCharacter.getStillsAvailable() );
}
public static Value have_mushroom_plot( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( MushroomManager.ownsPlot() );
}
public static Value craft_type( Interpreter interpreter, final Value arg )
{
int itemId = (int) arg.intValue();
Concoction conc = ConcoctionPool.get( itemId );
if ( conc == null )
{
return new Value( "none" );
}
CraftingType method = conc.getMixingMethod();
EnumSet<CraftingRequirements> requirements = conc.getRequirements();
return new Value( ConcoctionDatabase.mixingMethodDescription( method, requirements ) );
}
// The following functions pertain to providing updated
// information relating to the player.
public static Value refresh_status( Interpreter interpreter )
{
ApiRequest.updateStatus();
return RuntimeLibrary.continueValue();
}
public static Value restore_hp( Interpreter interpreter, final Value amount )
{
return RuntimeLibrary.restore( true, (int) amount.intValue() );
}
public static Value restore_mp( Interpreter interpreter, final Value amount )
{
return RuntimeLibrary.restore( false, (int) amount.intValue() );
}
private static Value restore( boolean hp, int amount )
{
boolean wasRecoveryActive = RecoveryManager.isRecoveryActive();
try
{
RecoveryManager.setRecoveryActive( true );
SpecialOutfit.createImplicitCheckpoint();
return DataTypes.makeBooleanValue( hp ? RecoveryManager.recoverHP( amount ) : RecoveryManager.recoverMP( amount ) );
}
finally
{
SpecialOutfit.restoreImplicitCheckpoint();
RecoveryManager.setRecoveryActive( wasRecoveryActive );
}
}
public static Value mood_execute( Interpreter interpreter, final Value multiplicity )
{
if ( RecoveryManager.isRecoveryActive() || MoodManager.isExecuting() )
{
return DataTypes.VOID_VALUE;
}
try
{
SpecialOutfit.createImplicitCheckpoint();
MoodManager.execute( (int) multiplicity.intValue() );
return DataTypes.VOID_VALUE;
}
finally
{
SpecialOutfit.restoreImplicitCheckpoint();
}
}
public static Value my_name( Interpreter interpreter )
{
return new Value( KoLCharacter.getUserName() );
}
public static Value my_id( Interpreter interpreter )
{
return new Value( KoLCharacter.getPlayerId() );
}
public static Value my_hash( Interpreter interpreter )
{
return new Value( GenericRequest.passwordHash );
}
public static Value my_sign( Interpreter interpreter )
{
return new Value( KoLCharacter.getSign() );
}
public static Value my_path( Interpreter interpreter )
{
return new Value( KoLCharacter.getPath() );
}
public static Value in_muscle_sign( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.inMuscleSign() );
}
public static Value in_mysticality_sign( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.inMysticalitySign() );
}
public static Value in_moxie_sign( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.inMoxieSign() );
}
public static Value in_bad_moon( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.inBadMoon() );
}
public static Value my_class( Interpreter interpreter )
{
return DataTypes.makeClassValue( KoLCharacter.getClassType() );
}
public static Value my_level( Interpreter interpreter )
{
return new Value( KoLCharacter.getLevel() );
}
public static Value my_hp( Interpreter interpreter )
{
return new Value( KoLCharacter.getCurrentHP() );
}
public static Value my_maxhp( Interpreter interpreter )
{
return new Value( KoLCharacter.getMaximumHP() );
}
public static Value my_mp( Interpreter interpreter )
{
return new Value( KoLCharacter.getCurrentMP() );
}
public static Value my_maxmp( Interpreter interpreter )
{
return new Value( KoLCharacter.getMaximumMP() );
}
public static Value my_primestat( Interpreter interpreter )
{
int primeIndex = KoLCharacter.getPrimeIndex();
return primeIndex == 0 ? DataTypes.MUSCLE_VALUE : primeIndex == 1 ? DataTypes.MYSTICALITY_VALUE : DataTypes.MOXIE_VALUE;
}
public static Value my_basestat( Interpreter interpreter, final Value arg )
{
String stat = arg.toString();
if ( stat.equalsIgnoreCase( Stat.MUSCLE.toString() ) )
{
return new Value( KoLCharacter.getBaseMuscle() );
}
if ( stat.equalsIgnoreCase( Stat.MYSTICALITY.toString() ) )
{
return new Value( KoLCharacter.getBaseMysticality() );
}
if ( stat.equalsIgnoreCase( Stat.MOXIE.toString() ) )
{
return new Value( KoLCharacter.getBaseMoxie() );
}
if ( stat.equalsIgnoreCase( Stat.SUBMUSCLE.toString() ) )
{
return new Value( KoLCharacter.getTotalMuscle() );
}
if ( stat.equalsIgnoreCase( Stat.SUBMYST.toString() ) )
{
return new Value( KoLCharacter.getTotalMysticality() );
}
if ( stat.equalsIgnoreCase( Stat.SUBMOXIE.toString() ) )
{
return new Value( KoLCharacter.getTotalMoxie() );
}
return DataTypes.ZERO_VALUE;
}
public static Value my_buffedstat( Interpreter interpreter, final Value arg )
{
String stat = arg.toString();
if ( stat.equalsIgnoreCase( Stat.MUSCLE.toString() ) )
{
return new Value( KoLCharacter.getAdjustedMuscle() );
}
if ( stat.equalsIgnoreCase( Stat.MYSTICALITY.toString() ) )
{
return new Value( KoLCharacter.getAdjustedMysticality() );
}
if ( stat.equalsIgnoreCase( Stat.MOXIE.toString() ) )
{
return new Value( KoLCharacter.getAdjustedMoxie() );
}
return DataTypes.ZERO_VALUE;
}
public static Value my_fury( Interpreter interpreter )
{
return new Value( KoLCharacter.getFury() );
}
public static Value my_maxfury( Interpreter interpreter )
{
return new Value( KoLCharacter.getFuryLimit() );
}
public static Value my_soulsauce( Interpreter interpreter )
{
return new Value( KoLCharacter.getSoulsauce() );
}
public static Value my_discomomentum( Interpreter interpreter )
{
return new Value( KoLCharacter.getDiscoMomentum() );
}
public static Value my_audience( Interpreter interpreter )
{
return new Value( KoLCharacter.getAudience() );
}
public static Value my_absorbs( Interpreter interpreter )
{
return new Value( KoLCharacter.getAbsorbs() );
}
public static Value my_thunder( Interpreter interpreter )
{
return new Value( KoLCharacter.getThunder() );
}
public static Value my_rain( Interpreter interpreter )
{
return new Value( KoLCharacter.getRain() );
}
public static Value my_lightning( Interpreter interpreter )
{
return new Value( KoLCharacter.getLightning() );
}
public static Value my_meat( Interpreter interpreter )
{
return new Value( KoLCharacter.getAvailableMeat() );
}
public static Value my_closet_meat( Interpreter interpreter )
{
return new Value( KoLCharacter.getClosetMeat() );
}
public static Value my_storage_meat( Interpreter interpreter )
{
return new Value( KoLCharacter.getStorageMeat() );
}
public static Value my_session_meat( Interpreter interpreter )
{
return new Value( KoLCharacter.getSessionMeat() );
}
public static Value my_adventures( Interpreter interpreter )
{
return new Value( KoLCharacter.getAdventuresLeft() );
}
public static Value my_daycount( Interpreter interpreter )
{
return new Value( KoLCharacter.getCurrentDays() );
}
public static Value my_turncount( Interpreter interpreter )
{
return new Value( KoLCharacter.getCurrentRun() );
}
public static Value my_fullness( Interpreter interpreter )
{
return new Value( KoLCharacter.getFullness() );
}
public static Value fullness_limit( Interpreter interpreter )
{
return new Value( KoLCharacter.getFullnessLimit() );
}
public static Value my_inebriety( Interpreter interpreter )
{
return new Value( KoLCharacter.getInebriety() );
}
public static Value inebriety_limit( Interpreter interpreter )
{
return new Value( KoLCharacter.getInebrietyLimit() );
}
public static Value my_spleen_use( Interpreter interpreter )
{
return new Value( KoLCharacter.getSpleenUse() );
}
public static Value spleen_limit( Interpreter interpreter )
{
return new Value( KoLCharacter.getSpleenLimit() );
}
public static Value can_eat( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.canEat() );
}
public static Value can_drink( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.canDrink() );
}
public static Value turns_played( Interpreter interpreter )
{
return new Value( KoLCharacter.getCurrentRun() );
}
public static Value total_turns_played( Interpreter interpreter )
{
return new Value( KoLCharacter.getTurnsPlayed() );
}
public static Value my_ascensions( Interpreter interpreter )
{
return new Value( KoLCharacter.getAscensions() );
}
public static Value can_interact( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.canInteract() );
}
public static Value in_hardcore( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.isHardcore() );
}
public static Value pvp_attacks_left( Interpreter interpreter )
{
return new Value( KoLCharacter.getAttacksLeft() );
}
public static Value current_pvp_stances( Interpreter interpreter )
{
AggregateType type = new AggregateType( DataTypes.INT_TYPE, DataTypes.STRING_TYPE );
MapValue value = new MapValue( type );
if ( PvpManager.checkStances() )
{
for ( Entry<String, Integer> entry : PvpManager.stanceToOption.entrySet() )
{
value.aset( new Value( entry.getKey() ), new Value( entry.getValue() ) );
}
}
return value;
}
public static Value get_clan_id( Interpreter interpreter )
{
return new Value( ClanManager.getClanId() );
}
public static Value get_clan_name( Interpreter interpreter )
{
return new Value( ClanManager.getClanName( true ) );
}
public static Value limit_mode( Interpreter interpreter )
{
return new Value( KoLCharacter.getLimitmode() );
}
public static Value get_florist_plants( Interpreter interpreter )
{
AggregateType plantType = new AggregateType( DataTypes.STRING_TYPE, 3 );
AggregateType type = new AggregateType( plantType, DataTypes.LOCATION_TYPE );
MapValue value = new MapValue( type );
Set locations = FloristRequest.floristPlants.keySet();
Iterator iterator = locations.iterator();
while ( iterator.hasNext() )
{
String loc = (String) iterator.next();
Value location = DataTypes.parseLocationValue( loc, false );
if ( location == null )
{
// The location string from KoL couldn't be
// matched to a location in KoLmafia
continue;
}
ArrayList<Florist> plants = FloristRequest.getPlants( loc );
if ( plants.size() == 0 )
{
continue;
}
ArrayValue plantValue = new ArrayValue( plantType );
for ( int i = 0; i < plants.size(); i++ )
{
plantValue.aset( new Value( i ), new Value( plants.get( i ).toString() ) );
}
value.aset( location, plantValue );
}
return value;
}
public static Value total_free_rests( Interpreter interpreter )
{
return new Value( KoLCharacter.freeRestsAvailable() );
}
public static Value get_ignore_zone_warnings( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.getIgnoreZoneWarnings() );
}
// Basic skill and effect functions, including those used
// in custom combat consult scripts.
public static Value have_skill( Interpreter interpreter, final Value arg )
{
String skillName = SkillDatabase.getSkillName( (int) arg.intValue() );
UseSkillRequest skill = UseSkillRequest.getUnmodifiedInstance( skillName );
return DataTypes.makeBooleanValue( KoLCharacter.hasSkill( skill, KoLConstants.availableSkills ) ||
KoLCharacter.hasSkill( skill, KoLConstants.availableCombatSkills ) );
}
public static Value mp_cost( Interpreter interpreter, final Value skill )
{
return new Value( SkillDatabase.getMPConsumptionById( (int) skill.intValue() ) );
}
public static Value adv_cost( Interpreter interpreter, final Value skill )
{
return new Value( SkillDatabase.getAdventureCost( (int) skill.intValue() ) );
}
public static Value soulsauce_cost( Interpreter interpreter, final Value skill )
{
return new Value( SkillDatabase.getSoulsauceCost( (int) skill.intValue() ) );
}
public static Value thunder_cost( Interpreter interpreter, final Value skill )
{
return new Value( SkillDatabase.getThunderCost( (int) skill.intValue() ) );
}
public static Value rain_cost( Interpreter interpreter, final Value skill )
{
return new Value( SkillDatabase.getRainCost( (int) skill.intValue() ) );
}
public static Value lightning_cost( Interpreter interpreter, final Value skill )
{
return new Value( SkillDatabase.getLightningCost( (int) skill.intValue() ) );
}
public static Value turns_per_cast( Interpreter interpreter, final Value skill )
{
return new Value( SkillDatabase.getEffectDuration( (int) skill.intValue() ) );
}
public static Value have_effect( Interpreter interpreter, final Value arg )
{
if ( arg == DataTypes.EFFECT_INIT )
{
return DataTypes.ZERO_VALUE;
}
int effectId = (int) arg.intValue();
AdventureResult effect = EffectPool.get( effectId, 0 );
return new Value( effect.getCount( KoLConstants.activeEffects ) );
}
public static Value my_effects( Interpreter interpreter )
{
AdventureResult[] effectsArray = new AdventureResult[ KoLConstants.activeEffects.size() ];
KoLConstants.activeEffects.toArray( effectsArray );
AggregateType type = new AggregateType( DataTypes.INT_TYPE, DataTypes.EFFECT_TYPE );
MapValue value = new MapValue( type );
for ( int i = 0; i < effectsArray.length; ++i )
{
AdventureResult effect = effectsArray[ i ];
int duration = effect.getCount();
if ( duration == Integer.MAX_VALUE )
{
duration = -1;
}
value.aset(
DataTypes.makeEffectValue( effect.getEffectId(), true ),
new Value ( duration ) );
}
return value;
}
public static Value use_skill( Interpreter interpreter, final Value countValue, final Value skill )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
// Just in case someone assumed that use_skill would also work
// in combat, go ahead and allow it here.
int skillId = (int) skill.intValue();
if ( SkillDatabase.isCombat( skillId ) )
{
// If we are in combat, go ahead and cast using fight.php
if ( FightRequest.getCurrentRound() > 0 )
{
for ( int i = 0; i < count; ++i )
{
RuntimeLibrary.use_skill( interpreter, skill );
}
return DataTypes.TRUE_VALUE;
}
// If we are not in combat, bail if the skill can't be cast
if ( !SkillDatabase.isNormal( skillId ) )
{
return DataTypes.FALSE_VALUE;
}
}
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "cast", count + " " + SkillDatabase.getSkillName( (int) skill.intValue() ) );
return UseSkillRequest.lastUpdate.equals( "" ) ? RuntimeLibrary.continueValue() : DataTypes.FALSE_VALUE;
}
public static Value use_skill( Interpreter interpreter, final Value skill )
{
// Just in case someone assumed that use_skill would also work
// in combat, go ahead and allow it here.
if ( SkillDatabase.isCombat( (int) skill.intValue() ) && FightRequest.getCurrentRound() > 0 )
{
return RuntimeLibrary.visit_url( interpreter, "fight.php?action=skill&whichskill=" + (int) skill.intValue() );
}
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "cast", "1 " + SkillDatabase.getSkillName( (int) skill.intValue() ) );
return new Value( UseSkillRequest.lastUpdate );
}
public static Value use_skill( Interpreter interpreter, final Value countValue, final Value skill, final Value target )
{
int count = (int) countValue.intValue();
if ( count <= 0 )
{
return RuntimeLibrary.continueValue();
}
// Just in case someone assumed that use_skill would also work
// in combat, go ahead and allow it here.
int skillId = (int) skill.intValue();
if ( SkillDatabase.isCombat( skillId ) )
{
// If we are in combat, go ahead and cast using fight.php
if ( FightRequest.getCurrentRound() > 0 )
{
for ( int i = 0; i < count; ++i )
{
RuntimeLibrary.use_skill( interpreter, skill );
}
return DataTypes.TRUE_VALUE;
}
// If we are not in combat, bail if the skill can't be cast
if ( !SkillDatabase.isNormal( skillId ) )
{
return DataTypes.FALSE_VALUE;
}
}
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "cast", count + " " + SkillDatabase.getSkillName( (int) skill.intValue() ) + " on " + target );
return UseSkillRequest.lastUpdate.equals( "" ) ? RuntimeLibrary.continueValue() : DataTypes.FALSE_VALUE;
}
public static Value last_skill_message( Interpreter interpreter )
{
return new Value( UseSkillRequest.lastUpdate );
}
public static Value get_auto_attack( Interpreter interpreter )
{
return new Value( KoLCharacter.getAutoAttackAction() );
}
public static Value set_auto_attack( Interpreter interpreter, Value attackValue )
{
Type type = attackValue.getType();
String arg =
type.equals( DataTypes.TYPE_STRING ) ? attackValue.toString() :
type.equals( DataTypes.TYPE_INT ) ? String.valueOf( attackValue.intValue() ) :
"none";
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "autoattack", arg );
return DataTypes.VOID_VALUE;
}
public static Value attack( Interpreter interpreter )
{
return RuntimeLibrary.visit_url( interpreter, "fight.php?action=attack" );
}
public static Value steal( Interpreter interpreter )
{
return RuntimeLibrary.visit_url( interpreter, "fight.php?action=steal" );
}
public static Value runaway( Interpreter interpreter )
{
return RuntimeLibrary.visit_url( interpreter, "fight.php?action=runaway" );
}
public static Value throw_item( Interpreter interpreter, final Value item )
{
return RuntimeLibrary.visit_url( interpreter, "fight.php?action=useitem&whichitem=" + (int) item.intValue() );
}
public static Value throw_items( Interpreter interpreter, final Value item1, final Value item2 )
{
return RuntimeLibrary.visit_url( interpreter, "fight.php?action=useitem&whichitem=" + (int) item1.intValue() + "&whichitem2=" + (int) item2.intValue() );
}
public static Value run_choice( Interpreter interpreter, final Value decision )
{
int option = (int) decision.intValue();
String response = null;
if ( ( !ChoiceManager.handlingChoice && !FightRequest.choiceFollowsFight ) || ChoiceManager.lastResponseText == null ||
option == 0 )
{
// If you are not in a choice, or you send 0, just return the last response
response = ChoiceManager.lastResponseText;
}
else if ( option == -1 )
{
// Try to automate using existing settings
response = ChoiceManager.gotoGoal();
}
else if ( option > 0 )
{
// Submit the option chosen
String message = "Submitting option " + option + " for choice " + ChoiceManager.getLastChoice();
RequestLogger.printLine( message );
response = ChoiceManager.processChoiceAdventure( option, false );
}
return new Value( DataTypes.BUFFER_TYPE, "", new StringBuffer( response == null ? "" : response ) );
}
public static Value last_choice( Interpreter interpreter )
{
return DataTypes.makeIntValue( ChoiceManager.lastChoice );
}
public static Value available_choice_options( Interpreter interpreter )
{
return RuntimeLibrary.available_choice_options( false );
}
public static Value available_choice_options( Interpreter interpreter, Value spoilers )
{
return RuntimeLibrary.available_choice_options( spoilers.intValue() == 1 );
}
private static Value available_choice_options( boolean spoilers)
{
MapValue value = new MapValue( DataTypes.INT_TO_STRING_TYPE );
String responseText = ChoiceManager.lastResponseText;
if ( responseText != null && !responseText.equals( "" ) )
{
Map<Integer,String> choices = spoilers ?
ChoiceUtilities.parseChoicesWithSpoilers() :
ChoiceUtilities.parseChoices( responseText );
for ( Entry<Integer,String> entry : choices.entrySet() )
{
value.aset( DataTypes.makeIntValue( entry.getKey() ),
new Value( entry.getValue() ) );
}
}
return value;
}
public static Value run_combat( Interpreter interpreter )
{
RelayRequest relayRequest = interpreter.getRelayRequest();
if ( FightRequest.currentRound > 0 || FightRequest.inMultiFight )
{
RequestThread.postRequest( FightRequest.INSTANCE );
}
String response = relayRequest == null ?
FightRequest.lastResponseText : FightRequest.getNextTrackedRound();
return new Value( DataTypes.BUFFER_TYPE, "", new StringBuffer( response == null ? "" : response ) );
}
public static Value run_combat( Interpreter interpreter, Value filterFunction )
{
if ( FightRequest.currentRound == 0 && !FightRequest.inMultiFight )
{
return new Value( DataTypes.BUFFER_TYPE, "", new StringBuffer( "" ) );
}
try
{
String filter = filterFunction.toString();
Macrofier.setMacroOverride( filter, interpreter );
RequestThread.postRequest( FightRequest.INSTANCE );
}
finally
{
Macrofier.resetMacroOverride();
}
String response = FightRequest.lastResponseText;
return new Value( DataTypes.BUFFER_TYPE, "", new StringBuffer( response == null ? "" : response ) );
}
public static Value run_turn( Interpreter interpreter )
{
if ( FightRequest.currentRound > 0 || FightRequest.inMultiFight )
{
return RuntimeLibrary.run_combat( interpreter );
}
else if ( ( ChoiceManager.handlingChoice && ChoiceManager.lastResponseText != null ) ||
FightRequest.choiceFollowsFight )
{
return RuntimeLibrary.run_choice( interpreter, new Value( -1 ) );
}
return new Value( DataTypes.BUFFER_TYPE, "" );
}
public static Value stun_skill( Interpreter interpreter )
{
String stunSkill = KoLCharacter.getClassStun();
int skill = -1;
if ( !stunSkill.equals( "none" ) )
{
skill = SkillDatabase.getSkillId( stunSkill );
}
return DataTypes.makeSkillValue( skill, true );
}
public static Value reverse_numberology( Interpreter interpreter )
{
return reverse_numberology( interpreter, new Value( 0 ), new Value( 0 ) );
}
public static Value reverse_numberology( Interpreter interpreter, final Value advDelta, final Value spleenDelta )
{
MapValue value = new MapValue( NumberologyType );
Map<Integer, Integer> map = NumberologyManager.reverseNumberology( (int) advDelta.intValue(), (int) spleenDelta.intValue() );
for ( Map.Entry<Integer, Integer> e : map.entrySet() )
{
value.aset( new Value( e.getKey() ), new Value( e.getValue() ) );
}
return value;
}
public static Value numberology_prize( Interpreter interpreter, final Value num )
{
return DataTypes.makeStringValue( NumberologyManager.numberologyPrize( (int) num.intValue() ) );
}
public static Value every_card_name( Interpreter interpreter, final Value name )
{
// Use logic from CLI "play" command
List<String> matchingNames = DeckOfEveryCardRequest.getMatchingNames( name.toString() );
if ( matchingNames.size() == 0 || // No match
matchingNames.size() > 1 ) // Ambiguous
{
return DataTypes.STRING_INIT;
}
EveryCard card = DeckOfEveryCardRequest.canonicalNameToCard( matchingNames.get( 0 ) );
return ( card == null ) ? DataTypes.STRING_INIT : DataTypes.makeStringValue( card.name );
}
// Equipment functions.
public static Value can_equip( Interpreter interpreter, final Value item )
{
int itemId = (int) item.intValue();
switch ( ItemDatabase.getConsumptionType( itemId ) )
{
case KoLConstants.EQUIP_HAT:
case KoLConstants.EQUIP_WEAPON:
case KoLConstants.EQUIP_OFFHAND:
case KoLConstants.EQUIP_SHIRT:
case KoLConstants.EQUIP_PANTS:
case KoLConstants.EQUIP_CONTAINER:
case KoLConstants.EQUIP_FAMILIAR:
case KoLConstants.EQUIP_ACCESSORY:
break;
default:
return DataTypes.FALSE_VALUE;
}
return DataTypes.makeBooleanValue( EquipmentManager.canEquip( ItemDatabase.getItemName( itemId ) ) );
}
public static Value equip( Interpreter interpreter, final Value item )
{
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "equip", "\u00B6" + (int) item.intValue() );
return RuntimeLibrary.continueValue();
}
public static Value equip( Interpreter interpreter, final Value slotValue, final Value item )
{
String slot = slotValue.toString();
if ( item.equals( DataTypes.ITEM_INIT ) )
{
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "unequip", slot );
}
else
{
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "equip", slot + " \u00B6" + (int) item.intValue() );
}
return RuntimeLibrary.continueValue();
}
public static Value equipped_item( Interpreter interpreter, final Value slot )
{
return DataTypes.makeItemValue( EquipmentManager.getEquipment( (int) slot.intValue() ).getName() );
}
public static Value have_equipped( Interpreter interpreter, final Value item )
{
return DataTypes.makeBooleanValue( KoLCharacter.hasEquipped( ItemPool.get( (int) item.intValue() ) ) );
}
public static Value outfit( Interpreter interpreter, final Value outfit )
{
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "outfit", outfit.toString() );
return RuntimeLibrary.continueValue();
}
public static Value have_outfit( Interpreter interpreter, final Value outfit )
{
SpecialOutfit so = EquipmentManager.getMatchingOutfit( outfit.toString() );
if ( so == null )
{
return DataTypes.FALSE_VALUE;
}
int id = so.getOutfitId();
return DataTypes.makeBooleanValue( id < 0 || EquipmentManager.hasOutfit( id ) );
}
public static Value is_wearing_outfit( Interpreter interpreter, final Value outfit )
{
SpecialOutfit so = EquipmentManager.getMatchingOutfit( outfit.toString() );
if ( so == null )
{
return DataTypes.FALSE_VALUE;
}
return DataTypes.makeBooleanValue( EquipmentManager.isWearingOutfit( so ) );
}
public static Value outfit_pieces( Interpreter interpreter, final Value outfit )
{
SpecialOutfit so = EquipmentManager.getMatchingOutfit( outfit.toString() );
if ( so == null )
{
return new ArrayValue( new AggregateType( DataTypes.ITEM_TYPE, 0 ) );
}
AdventureResult[] pieces = so.getPieces();
AggregateType type = new AggregateType( DataTypes.ITEM_TYPE, pieces.length );
ArrayValue value = new ArrayValue( type );
for ( int i = 0; i < pieces.length; ++i )
{
AdventureResult piece = pieces[ i ];
value.aset( DataTypes.makeIntValue( i ),
DataTypes.makeItemValue( piece ) );
}
return value;
}
public static Value outfit_tattoo( Interpreter interpreter, final Value outfit )
{
SpecialOutfit so = EquipmentManager.getMatchingOutfit( outfit.toString() );
if ( so == null || so.getImage() == null )
{
return DataTypes.STRING_INIT;
}
return new Value( so.getImage() );
}
public static Value get_outfits( Interpreter interpreter )
{
return RuntimeLibrary.outfitListToValue( interpreter, EquipmentManager.getOutfits(), false );
}
public static Value get_custom_outfits( Interpreter interpreter )
{
return RuntimeLibrary.outfitListToValue( interpreter, EquipmentManager.getCustomOutfits(), false );
}
public static Value all_normal_outfits( Interpreter interpreter )
{
return RuntimeLibrary.outfitListToValue( interpreter, EquipmentDatabase.normalOutfits.toList(), true );
}
private static Value outfitListToValue( Interpreter interpreter, List<SpecialOutfit> outfits, boolean map )
{
AggregateValue value =
map ?
new MapValue( new AggregateType( DataTypes.STRING_TYPE, DataTypes.INT_TYPE ) ) :
new ArrayValue( new AggregateType( DataTypes.STRING_TYPE, outfits.size() ) );
for ( int i = 1; i < outfits.size(); ++i )
{
SpecialOutfit it = outfits.get( i );
if ( it != null )
{
value.aset( new Value( i ), new Value( it.toString() ) );
}
}
return value;
}
public static Value weapon_hands( Interpreter interpreter, final Value item )
{
return new Value( EquipmentDatabase.getHands( (int) item.intValue() ) );
}
public static Value item_type( Interpreter interpreter, final Value item )
{
String type = EquipmentDatabase.getItemType( (int) item.intValue() );
return new Value( type );
}
public static Value weapon_type( Interpreter interpreter, final Value item )
{
Stat stat = EquipmentDatabase.getWeaponStat( (int) item.intValue() );
return stat == Stat.MUSCLE ? DataTypes.MUSCLE_VALUE : stat == Stat.MYSTICALITY ? DataTypes.MYSTICALITY_VALUE :
stat == Stat.MOXIE ? DataTypes.MOXIE_VALUE : DataTypes.STAT_INIT;
}
public static Value get_power( Interpreter interpreter, final Value item )
{
return new Value( EquipmentDatabase.getPower( (int) item.intValue() ) );
}
public static Value my_familiar( Interpreter interpreter )
{
return DataTypes.makeFamiliarValue( KoLCharacter.getFamiliar().getId(), true );
}
public static Value my_effective_familiar( Interpreter interpreter )
{
return DataTypes.makeFamiliarValue( KoLCharacter.getEffectiveFamiliar().getId(), true );
}
public static Value my_enthroned_familiar( Interpreter interpreter )
{
return DataTypes.makeFamiliarValue( KoLCharacter.getEnthroned().getId(), true );
}
public static Value my_bjorned_familiar( Interpreter interpreter )
{
return DataTypes.makeFamiliarValue( KoLCharacter.getBjorned().getId(), true );
}
public static Value have_familiar( Interpreter interpreter, final Value familiar )
{
int familiarId = (int) familiar.intValue();
return familiarId == -1 ?
DataTypes.FALSE_VALUE :
DataTypes.makeBooleanValue( KoLCharacter.findFamiliar( familiarId ) != null );
}
public static Value use_familiar( Interpreter interpreter, final Value familiar )
{
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "familiar", familiar.toString() );
return RuntimeLibrary.continueValue();
}
public static Value have_servant( Interpreter interpreter, final Value servant )
{
return DataTypes.makeBooleanValue( EdServantData.findEdServant( servant.toString() ) != null );
}
public static Value use_servant( Interpreter interpreter, final Value servant )
{
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "servant", servant.toString() );
return RuntimeLibrary.continueValue();
}
public static Value enthrone_familiar( Interpreter interpreter, final Value familiar )
{
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "enthrone", familiar.toString() );
return RuntimeLibrary.continueValue();
}
public static Value bjornify_familiar( Interpreter interpreter, final Value familiar )
{
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "bjornify", familiar.toString() );
return RuntimeLibrary.continueValue();
}
public static Value familiar_equipment( Interpreter interpreter, final Value familiar )
{
return DataTypes.makeItemValue( FamiliarDatabase.getFamiliarItemId( (int) familiar.intValue() ), true );
}
public static Value familiar_equipped_equipment( Interpreter interpreter, final Value familiar )
{
FamiliarData fam = KoLCharacter.findFamiliar( (int) familiar.intValue() );
AdventureResult item = fam == null ? EquipmentRequest.UNEQUIP : fam.getItem();
return item == EquipmentRequest.UNEQUIP ? DataTypes.ITEM_INIT : DataTypes.makeItemValue( item.getItemId(), true );
}
public static Value familiar_weight( Interpreter interpreter, final Value familiar )
{
FamiliarData fam = KoLCharacter.findFamiliar( (int) familiar.intValue() );
return fam == null ? DataTypes.ZERO_VALUE : new Value( fam.getWeight() );
}
public static Value is_familiar_equipment_locked( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( EquipmentManager.familiarItemLocked() );
}
public static Value favorite_familiars( Interpreter interpreter )
{
AggregateType type = new AggregateType( DataTypes.BOOLEAN_TYPE, DataTypes.FAMILIAR_TYPE );
MapValue value = new MapValue( type );
for ( FamiliarData fam : KoLCharacter.getFamiliarList() )
{
if ( fam.getFavorite() )
{
value.aset( DataTypes.makeFamiliarValue( fam.getId(), true ), DataTypes.makeBooleanValue( fam.canEquip() ) );
}
}
return value;
}
public static Value lock_familiar_equipment( Interpreter interpreter, Value lock )
{
if ( ( lock.intValue() == 1 ) != EquipmentManager.familiarItemLocked() )
{
RequestThread.postRequest( new FamiliarRequest( true ) );
}
return DataTypes.VOID_VALUE;
}
public static Value equip_all_familiars( Interpreter interpreter )
{
FamiliarManager.equipAllFamiliars();
return RuntimeLibrary.continueValue();
}
public static Value minstrel_level( Interpreter interpreter )
{
return DataTypes.makeIntValue( KoLCharacter.getMinstrelLevel() );
}
public static Value minstrel_instrument( Interpreter interpreter )
{
AdventureResult item = KoLCharacter.getCurrentInstrument();
return item == null ? DataTypes.ITEM_INIT : DataTypes.makeItemValue( item.getItemId(), true );
}
public static Value minstrel_quest( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.minstrelAttention );
}
public static Value my_companion( Interpreter interpreter )
{
if ( KoLCharacter.getCompanion() == null )
{
return DataTypes.STRING_INIT;
}
return new Value( KoLCharacter.getCompanion().toString() );
}
public static Value my_thrall( Interpreter interpreter )
{
return DataTypes.makeThrallValue( KoLCharacter.currentPastaThrall(), true );
}
public static Value my_servant( Interpreter interpreter )
{
return DataTypes.makeServantValue( EdServantData.currentServant(), true );
}
public static Value my_vykea_companion( Interpreter interpreter )
{
return DataTypes.makeVykeaValue( VYKEACompanionData.currentCompanion(), true );
}
// Random other functions related to current in-game
// state, not directly tied to the character.
public static Value council( Interpreter interpreter )
{
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "council", "" );
return DataTypes.VOID_VALUE;
}
public static Value current_mcd( Interpreter interpreter )
{
return new Value( KoLCharacter.getMindControlLevel() );
}
public static Value change_mcd( Interpreter interpreter, final Value level )
{
KoLmafiaCLI.DEFAULT_SHELL.executeCommand( "mcd", level.toString() );
return RuntimeLibrary.continueValue();
}
public static Value current_rad_sickness( Interpreter interpreter )
{
return new Value( KoLCharacter.getRadSickness() );
}
public static Value have_chef( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.hasChef() );
}
public static Value have_bartender( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.hasBartender() );
}
public static Value have_shop( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.hasStore() );
}
public static Value have_display( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.hasDisplayCase() );
}
public static Value hippy_stone_broken( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.getHippyStoneBroken() );
}
public static Value get_counters( Interpreter interpreter, final Value label, final Value min, final Value max )
{
return new Value( TurnCounter.getCounters( label.toString(), (int) min.intValue(), (int) max.intValue() ) );
}
public static Value eudora ( Interpreter interpreter )
{
return new Value( KoLCharacter.getEudora() );
}
public static Value eudora( Interpreter interpreter, final Value newEudora )
{
String correspondent = newEudora.toString();
String requestString = "account.php?am=1&action=whichpenpal&ajax=1&pwd=" +
GenericRequest.passwordHash + "&value=";
if ( correspondent.equalsIgnoreCase( "penpal" ) )
{
GenericRequest request = new GenericRequest( requestString + "1" );
request.run();
ApiRequest.updateStatus();
if ( KoLCharacter.getEudora().equals( "Penpal" ) )
{
KoLmafia.updateDisplay( "Switched to Pen Pal" );
return DataTypes.TRUE_VALUE;
}
}
if ( correspondent.equalsIgnoreCase( "game" ) )
{
GenericRequest request = new GenericRequest( requestString + "2" );
request.run();
ApiRequest.updateStatus();
if ( KoLCharacter.getEudora().equals( "GameInformPowerDailyPro Magazine" ) )
{
KoLmafia.updateDisplay( "Switched to Game Magazine" );
return DataTypes.TRUE_VALUE;
}
}
if ( correspondent.equalsIgnoreCase( "xi" ) )
{
GenericRequest request = new GenericRequest( requestString + "3" );
request.run();
ApiRequest.updateStatus();
if ( KoLCharacter.getEudora().equals( "Xi Receiver Unit" ) )
{
KoLmafia.updateDisplay( "Switched to Xi Receiver" );
return DataTypes.TRUE_VALUE;
}
}
if ( correspondent.equalsIgnoreCase( "newyou" ) )
{
GenericRequest request = new GenericRequest( requestString + "4" );
request.run();
ApiRequest.updateStatus();
if ( KoLCharacter.getEudora().equals( "New-You Club" ) )
{
KoLmafia.updateDisplay( "Switched to New-You Club" );
return DataTypes.TRUE_VALUE;
}
}
return DataTypes.FALSE_VALUE;
}
// String parsing functions.
public static Value is_integer( Interpreter interpreter, final Value string )
{
return DataTypes.makeBooleanValue( StringUtilities.isNumeric( string.toString() ) );
}
public static Value contains_text( Interpreter interpreter, final Value source, final Value search )
{
return DataTypes.makeBooleanValue( source.toString().contains( search.toString() ) );
}
public static Value starts_with( Interpreter interpreter, final Value source, final Value prefix )
{
return DataTypes.makeBooleanValue( source.toString().startsWith( prefix.toString() ) );
}
public static Value ends_with( Interpreter interpreter, final Value source, final Value suffix )
{
return DataTypes.makeBooleanValue( source.toString().endsWith( suffix.toString() ) );
}
public static Value extract_meat( Interpreter interpreter, final Value string )
{
ArrayList<AdventureResult> data = new ArrayList<AdventureResult>();
ResultProcessor.processResults( false,
StringUtilities.globalStringReplace( string.toString(), "- ", "-" ),
data );
for ( AdventureResult result : data )
{
if ( result.getName().equals( AdventureResult.MEAT ) )
{
return new Value( result.getCount() );
}
}
return DataTypes.ZERO_VALUE;
}
public static Value extract_items( Interpreter interpreter, final Value string )
{
ArrayList<AdventureResult> data = new ArrayList<AdventureResult>();
ResultProcessor.processResults( false,
StringUtilities.globalStringReplace( string.toString(), "- ", "-" ),
data );
MapValue value = new MapValue( DataTypes.ITEM_TO_INT_TYPE );
for ( AdventureResult result : data )
{
if ( result.isItem() )
{
value.aset(
DataTypes.makeItemValue( result.getItemId(), true ),
DataTypes.parseIntValue( String.valueOf( result.getCount() ), true ) );
}
}
return value;
}
public static Value length( Interpreter interpreter, final Value string )
{
return new Value( string.toString().length() );
}
public static Value char_at( Interpreter interpreter, final Value source, final Value index )
{
String string = source.toString();
int offset = (int) index.intValue();
if ( offset < 0 || offset >= string.length() )
{
throw interpreter.runtimeException( "Offset " + offset + " out of bounds" );
}
return new Value( Character.toString( string.charAt( offset ) ) );
}
public static Value index_of( Interpreter interpreter, final Value source, final Value search )
{
String string = source.toString();
String substring = search.toString();
return new Value( string.indexOf( substring ) );
}
public static Value index_of( Interpreter interpreter, final Value source, final Value search,
final Value start )
{
String string = source.toString();
String substring = search.toString();
int begin = (int) start.intValue();
if ( begin < 0 || begin > string.length() )
{
throw interpreter.runtimeException( "Begin index " + begin + " out of bounds" );
}
return new Value( string.indexOf( substring, begin ) );
}
public static Value last_index_of( Interpreter interpreter, final Value source, final Value search )
{
String string = source.toString();
String substring = search.toString();
return new Value( string.lastIndexOf( substring ) );
}
public static Value last_index_of( Interpreter interpreter, final Value source, final Value search,
final Value start )
{
String string = source.toString();
String substring = search.toString();
int begin = (int) start.intValue();
if ( begin < 0 || begin > string.length() )
{
throw interpreter.runtimeException( "Begin index " + begin + " out of bounds" );
}
return new Value( string.lastIndexOf( substring, begin ) );
}
public static Value substring( Interpreter interpreter, final Value source, final Value start )
{
String string = source.toString();
int begin = (int) start.intValue();
if ( begin < 0 || begin > string.length() )
{
throw interpreter.runtimeException( "Begin index " + begin + " out of bounds" );
}
return new Value( string.substring( begin ) );
}
public static Value substring( Interpreter interpreter, final Value source, final Value start,
final Value finish )
{
String string = source.toString();
int begin = (int) start.intValue();
if ( begin < 0 )
{
throw interpreter.runtimeException( "Begin index " + begin + " out of bounds" );
}
int end = (int) finish.intValue();
if ( end > string.length() )
{
throw interpreter.runtimeException( "End index " + end + " out of bounds" );
}
if ( begin > end )
{
throw interpreter.runtimeException( "Begin index " + begin + " greater than end index " + end );
}
return new Value( string.substring( begin, end ) );
}
public static Value to_upper_case( Interpreter interpreter, final Value string )
{
return new Value( string.toString().toUpperCase() );
}
public static Value to_lower_case( Interpreter interpreter, final Value string )
{
return new Value( string.toString().toLowerCase() );
}
public static Value leetify( Interpreter interpreter, final Value string )
{
return new Value( StringUtilities.leetify( string.toString() ) );
}
public static Value append( Interpreter interpreter, final Value buffer, final Value s )
{
StringBuffer current = (StringBuffer) buffer.rawValue();
current.append( s.toString() );
return buffer;
}
public static Value insert( Interpreter interpreter, final Value buffer, final Value index, final Value s )
{
StringBuffer current = (StringBuffer) buffer.rawValue();
int offset = (int) index.intValue();
if ( offset < 0 || offset > current.length() )
{
throw interpreter.runtimeException( "Index " + index + " out of bounds" );
}
current.insert( offset, s.toString() );
return buffer;
}
public static Value replace( Interpreter interpreter, final Value buffer, final Value start, final Value finish,
final Value s )
{
StringBuffer current = (StringBuffer) buffer.rawValue();
int begin = (int) start.intValue();
if ( begin < 0 )
{
throw interpreter.runtimeException( "Begin index " + begin + " out of bounds" );
}
int end = (int) finish.intValue();
if ( end > current.length() )
{
throw interpreter.runtimeException( "End index " + end + " out of bounds" );
}
if ( begin > end )
{
throw interpreter.runtimeException( "Begin index " + begin + " greater than end index " + end );
}
current.replace( begin, end, s.toString() );
return buffer;
}
public static Value delete( Interpreter interpreter, final Value buffer, final Value start, final Value finish )
{
StringBuffer current = (StringBuffer) buffer.rawValue();
int begin = (int) start.intValue();
if ( begin < 0 )
{
throw interpreter.runtimeException( "Begin index " + begin + " out of bounds" );
}
int end = (int) finish.intValue();
if ( end > current.length() )
{
throw interpreter.runtimeException( "End index " + end + " out of bounds" );
}
if ( begin > end )
{
throw interpreter.runtimeException( "Begin index " + begin + " greater than end index " + end );
}
current.delete( begin, end );
return buffer;
}
public static Value set_length( Interpreter interpreter, final Value buffer, final Value i )
{
StringBuffer current = (StringBuffer) buffer.rawValue();
int length = (int) i.intValue();
if ( length < 0 )
{
throw interpreter.runtimeException( "Desired length is less than zero" );
}
current.setLength( length );
return DataTypes.VOID_VALUE;
}
public static Value append_tail( Interpreter interpreter, final Value matcher, final Value buffer )
{
Matcher m = (Matcher) matcher.rawValue();
StringBuffer current = (StringBuffer) buffer.rawValue();
m.appendTail( current );
return buffer;
}
public static Value append_replacement( Interpreter interpreter, final Value matcher, final Value buffer, final Value replacement )
{
Matcher m = (Matcher) matcher.rawValue();
StringBuffer current = (StringBuffer) buffer.rawValue();
m.appendReplacement( current, replacement.toString() );
return buffer;
}
public static Value create_matcher( Interpreter interpreter, final Value patternValue, final Value stringValue )
{
String pattern = patternValue.toString();
String string = stringValue.toString();
if ( !( patternValue.content instanceof Pattern ) )
{
try
{
patternValue.content = Pattern.compile( pattern, Pattern.DOTALL );
}
catch ( PatternSyntaxException e )
{
throw interpreter.runtimeException( "Invalid pattern syntax" );
}
}
Pattern p = (Pattern) patternValue.content;
return new Value( DataTypes.MATCHER_TYPE, pattern, p.matcher( string ) );
}
public static Value find( Interpreter interpreter, final Value matcher )
{
Matcher m = (Matcher) matcher.rawValue();
return DataTypes.makeBooleanValue( m.find() );
}
public static Value start( Interpreter interpreter, final Value matcher )
{
Matcher m = (Matcher) matcher.rawValue();
try
{
return new Value( m.start() );
}
catch ( IllegalStateException e )
{
throw interpreter.runtimeException( "No match attempted or previous match failed" );
}
}
public static Value start( Interpreter interpreter, final Value matcher, final Value group )
{
Matcher m = (Matcher) matcher.rawValue();
int index = (int) group.intValue();
try
{
return new Value( m.start( index ) );
}
catch ( IllegalStateException e )
{
throw interpreter.runtimeException( "No match attempted or previous match failed" );
}
catch ( IndexOutOfBoundsException e )
{
throw interpreter.runtimeException( "Group " + index + " requested, but pattern only has " + m.groupCount() + " groups" );
}
}
public static Value end( Interpreter interpreter, final Value matcher )
{
Matcher m = (Matcher) matcher.rawValue();
try
{
return new Value( m.end() );
}
catch ( IllegalStateException e )
{
throw interpreter.runtimeException( "No match attempted or previous match failed" );
}
}
public static Value end( Interpreter interpreter, final Value matcher, final Value group )
{
Matcher m = (Matcher) matcher.rawValue();
int index = (int) group.intValue();
try
{
return new Value( m.end( index ) );
}
catch ( IllegalStateException e )
{
throw interpreter.runtimeException( "No match attempted or previous match failed" );
}
catch ( IndexOutOfBoundsException e )
{
throw interpreter.runtimeException( "Group " + index + " requested, but pattern only has " + m.groupCount() + " groups" );
}
}
public static Value group( Interpreter interpreter, final Value matcher )
{
Matcher m = (Matcher) matcher.rawValue();
try
{
return new Value( m.group() );
}
catch ( IllegalStateException e )
{
throw interpreter.runtimeException( "No match attempted or previous match failed" );
}
}
public static Value group( Interpreter interpreter, final Value matcher, final Value group )
{
Matcher m = (Matcher) matcher.rawValue();
int index = (int) group.intValue();
try
{
return new Value( m.group( index ) );
}
catch ( IllegalStateException e )
{
throw interpreter.runtimeException( "No match attempted or previous match failed" );
}
catch ( IndexOutOfBoundsException e )
{
throw interpreter.runtimeException( "Group " + index + " requested, but pattern only has " + m.groupCount() + " groups" );
}
}
public static Value group_count( Interpreter interpreter, final Value matcher )
{
Matcher m = (Matcher) matcher.rawValue();
return new Value( m.groupCount() );
}
public static Value replace_first( Interpreter interpreter, final Value matcher, final Value replacement )
{
Matcher m = (Matcher) matcher.rawValue();
return new Value( m.replaceFirst( replacement.toString() ) );
}
public static Value replace_all( Interpreter interpreter, final Value matcher, final Value replacement )
{
Matcher m = (Matcher) matcher.rawValue();
return new Value( m.replaceAll( replacement.toString() ) );
}
public static Value reset( Interpreter interpreter, final Value matcher )
{
Matcher m = (Matcher) matcher.rawValue();
m.reset();
return matcher;
}
public static Value reset( Interpreter interpreter, final Value matcher, final Value input )
{
Matcher m = (Matcher) matcher.rawValue();
m.reset( input.toString() );
return matcher;
}
public static Value replace_string( Interpreter interpreter, final Value source,
final Value searchValue,
final Value replaceValue )
{
StringBuffer buffer;
Value returnValue;
if ( source.rawValue() instanceof StringBuffer )
{
buffer = (StringBuffer) source.rawValue();
returnValue = source;
}
else
{
buffer = new StringBuffer( source.toString() );
returnValue = new Value( DataTypes.BUFFER_TYPE, "", buffer );
}
String search = searchValue.toString();
String replace = replaceValue.toString();
StringUtilities.globalStringReplace( buffer, search, replace );
return returnValue;
}
public static Value split_string( Interpreter interpreter, final Value string )
{
String[] pieces = string.toString().split( KoLConstants.LINE_BREAK );
AggregateType type = new AggregateType( DataTypes.STRING_TYPE, pieces.length );
ArrayValue value = new ArrayValue( type );
for ( int i = 0; i < pieces.length; ++i )
{
value.aset( new Value( i ), new Value( pieces[ i ] ) );
}
return value;
}
public static Value split_string( Interpreter interpreter, final Value string, final Value regex )
{
Pattern p;
if ( regex.rawValue() instanceof Pattern )
{
p = (Pattern) regex.rawValue();
}
else
{
try
{
p = Pattern.compile( regex.toString() );
if ( regex.content == null )
{
regex.content = p;
}
}
catch ( PatternSyntaxException e )
{
throw interpreter.runtimeException( "Invalid pattern syntax" );
}
}
String[] pieces = p.split( string.toString() );
AggregateType type = new AggregateType( DataTypes.STRING_TYPE, pieces.length );
ArrayValue value = new ArrayValue( type );
for ( int i = 0; i < pieces.length; ++i )
{
value.aset( new Value( i ), new Value( pieces[ i ] ) );
}
return value;
}
public static Value group_string( Interpreter interpreter, final Value string, final Value regex )
{
Pattern p;
if ( regex.rawValue() instanceof Pattern )
{
p = (Pattern) regex.rawValue();
}
else
{
try
{
p = Pattern.compile( regex.toString() );
if ( regex.content == null )
{
regex.content = p;
}
}
catch ( PatternSyntaxException e )
{
throw interpreter.runtimeException( "Invalid pattern syntax" );
}
}
Matcher userPatternMatcher = p.matcher( string.toString() );
MapValue value = new MapValue( DataTypes.REGEX_GROUP_TYPE );
int matchCount = 0;
int groupCount = userPatternMatcher.groupCount();
Value[] groupIndexes = new Value[ groupCount + 1 ];
for ( int i = 0; i <= groupCount; ++i )
{
groupIndexes[ i ] = new Value( i );
}
Value matchIndex;
CompositeValue slice;
try
{
while ( userPatternMatcher.find() )
{
matchIndex = new Value( matchCount );
slice = (CompositeValue) value.initialValue( matchIndex );
value.aset( matchIndex, slice );
for ( int i = 0; i <= groupCount; ++i )
{
slice.aset( groupIndexes[ i ], new Value( userPatternMatcher.group( i ) ) );
}
++matchCount;
}
}
catch ( Exception e )
{
// Because we're doing everything ourselves, this
// error shouldn't get generated. Print a stack
// trace, just in case.
StaticEntity.printStackTrace( e );
}
return value;
}
public static Value expression_eval( Interpreter interpreter, final Value expr )
{
Expression e;
if ( expr.content instanceof Expression )
{
e = (Expression) expr.content;
}
else
{
e = new Expression( expr.toString(), "expression_eval()" );
String errors = e.getExpressionErrors();
if ( errors != null )
{
throw interpreter.runtimeException( errors );
}
if ( expr.content == null )
{
expr.content = e;
}
}
return RuntimeLibrary.eval( interpreter, e );
}
public static Value modifier_eval( Interpreter interpreter, final Value expr )
{
ModifierExpression e;
if ( expr.content instanceof ModifierExpression )
{
e = (ModifierExpression) expr.content;
}
else
{
e = new ModifierExpression( expr.toString(), "modifier_eval()" );
String errors = e.getExpressionErrors();
if ( errors != null )
{
throw interpreter.runtimeException( errors );
}
if ( expr.content == null )
{
expr.content = e;
}
}
return RuntimeLibrary.eval( interpreter, e );
}
private static Value eval( Interpreter interpreter, final Expression expr )
{
try
{
return new Value( expr.evalInternal() );
}
catch ( Exception e )
{
throw interpreter.runtimeException( "Expression evaluation error: " + e.getMessage() );
}
}
public static Value maximize( Interpreter interpreter, final Value maximizerStringValue, final Value isSpeculateOnlyValue )
{
return maximize( interpreter, maximizerStringValue, DataTypes.ZERO_VALUE, DataTypes.ZERO_VALUE, isSpeculateOnlyValue );
}
public static Value maximize( Interpreter interpreter, final Value maximizerStringValue, final Value maxPriceValue, final Value priceLevelValue, final Value isSpeculateOnlyValue )
{
String maximizerString = maximizerStringValue.toString();
int maxPrice = (int) maxPriceValue.intValue();
int priceLevel = (int) priceLevelValue.intValue();
boolean isSpeculateOnly = isSpeculateOnlyValue.intValue() != 0;
return new Value( Maximizer.maximize( maximizerString, maxPrice, priceLevel, isSpeculateOnly ) );
}
public static Value maximize( Interpreter interpreter, final Value maximizerStringValue, final Value maxPriceValue,
final Value priceLevelValue, final Value isSpeculateOnlyValue, final Value showEquipment )
{
String maximizerString = maximizerStringValue.toString();
int maxPrice = (int) maxPriceValue.intValue();
int priceLevel = (int) priceLevelValue.intValue();
boolean isSpeculateOnly = isSpeculateOnlyValue.intValue() != 0;
boolean showEquip = showEquipment.intValue() == 1;
Maximizer.maximize( maximizerString, maxPrice, priceLevel, isSpeculateOnly );
List<Boost> m = Maximizer.boosts;
int lastEquipIndex = 0;
if ( !showEquip )
{
for ( Boost boo : m )
{
if ( !boo.isEquipment() )
break;
lastEquipIndex++ ;
}
}
AggregateType type = new AggregateType( RuntimeLibrary.maximizerResults, m.size() - lastEquipIndex );
ArrayValue value = new ArrayValue( type );
for ( int i = lastEquipIndex; i < m.size(); ++i )
{
Boost boo = m.get( i );
String text = boo.toString();
String cmd = boo.getCmd();
Double boost = boo.getBoost();
AdventureResult arEffect = boo.isEquipment() ? null : boo.getItem();
AdventureResult arItem = boo.getItem( false );
String skill = cmd.startsWith( "cast" ) ? UneffectRequest.effectToSkill( arEffect.getName() ) : null;
// remove the (+ X) from the display text, that info is in the score
int cutIndex = boo.toString().indexOf( " (" );
if ( cutIndex != -1 )
{
text = text.substring( 0, cutIndex );
}
RecordValue rec = (RecordValue) value.aref( new Value( i - lastEquipIndex ) );
rec.aset( 0, DataTypes.parseStringValue( text ), null );
rec.aset( 1, DataTypes.parseStringValue( cmd ), null );
rec.aset( 2, new Value( boost ), null );
rec.aset( 3, arEffect == null ? DataTypes.EFFECT_INIT : DataTypes.parseEffectValue( arEffect.getName(), true ), null );
rec.aset( 4, arItem == null ? DataTypes.ITEM_INIT : DataTypes.makeItemValue( arItem.getItemId(), true ), null );
rec.aset( 5, skill == null ? DataTypes.SKILL_INIT : DataTypes.parseSkillValue( skill, true ), null );
}
return value;
}
public static Value monster_eval( Interpreter interpreter, final Value expr )
{
MonsterExpression e;
if ( expr.content instanceof MonsterExpression )
{
e = (MonsterExpression) expr.rawValue();
}
else
{
e = new MonsterExpression( expr.toString(), "monster_eval()" );
String errors = e.getExpressionErrors();
if ( errors != null )
{
throw interpreter.runtimeException( errors );
}
if ( expr.content == null )
{
expr.content = e;
}
}
return RuntimeLibrary.eval( interpreter, e );
}
public static Value is_online( Interpreter interpreter, final Value arg )
{
String name = arg.toString();
return DataTypes.makeBooleanValue( KoLmafia.isPlayerOnline( name ) );
}
static final Pattern COUNT_PATTERN = Pattern.compile( "You have (\\d+) " );
public static Value slash_count( Interpreter interpreter, final Value arg )
{
String itemName = ItemDatabase.getItemName( (int)arg.intValue() );
InternalChatRequest request = new InternalChatRequest( "/count " + itemName );
RequestThread.postRequest( request );
Matcher m = RuntimeLibrary.COUNT_PATTERN.matcher( request.responseText );
return new Value( m.find() ? StringUtilities.parseInt( m.group( 1 ) ) : 0 );
}
public static Value chat_macro( Interpreter interpreter, final Value macroValue )
{
String macro = macroValue.toString().trim();
ChatSender.executeMacro( macro );
return DataTypes.VOID_VALUE;
}
public static Value chat_clan( Interpreter interpreter, final Value messageValue )
{
String channel = "/clan";
String message = messageValue.toString().trim();
ChatSender.sendMessage( channel, message, true );
return DataTypes.VOID_VALUE;
}
public static Value chat_clan( Interpreter interpreter, final Value messageValue, final Value recipientValue )
{
String channel = "/" + recipientValue.toString().trim();
String message = messageValue.toString().trim();
ChatSender.sendMessage( channel, message, true );
return DataTypes.VOID_VALUE;
}
public static Value chat_private( Interpreter interpreter, final Value recipientValue, final Value messageValue )
{
String recipient = recipientValue.toString();
String message = messageValue.toString();
if ( message.equals( "" ) || message.startsWith( "/" ) )
{
return DataTypes.VOID_VALUE;
}
ChatSender.sendMessage( recipient, message, false );
return DataTypes.VOID_VALUE;
}
public static Value chat_notify( Interpreter interpreter, final Value messageValue, final Value colorValue )
{
String messageString = StringUtilities.globalStringReplace( messageValue.toString(), "<", "<" );
String colorString = StringUtilities.globalStringDelete( colorValue.toString(), "\"" );
colorString = "\"" + colorString + "\"";
InternalMessage message = new InternalMessage( messageString, colorString );
ChatPoller.addEntry( message );
return DataTypes.VOID_VALUE;
}
public static Value who_clan( Interpreter interpreter )
{
InternalChatRequest request = new InternalChatRequest( "/who clan" );
List<ChatMessage> chatMessages = ChatSender.sendRequest( request );
MapValue value = new MapValue( DataTypes.STRING_TO_BOOLEAN_TYPE );
for ( ChatMessage chatMessage : chatMessages )
{
if ( chatMessage instanceof WhoMessage )
{
WhoMessage message = (WhoMessage) chatMessage;
Iterator entryIterator = message.getContacts().entrySet().iterator();
while ( entryIterator.hasNext() )
{
Entry entry = (Entry) entryIterator.next();
value.aset( new Value( (String) entry.getKey() ) , new Value( entry.getValue() == Boolean.TRUE ) );
}
break;
}
}
return value;
}
public static Value get_player_id( Interpreter interpreter, final Value playerNameValue )
{
String playerName = playerNameValue.toString();
return new Value( ContactManager.getPlayerId( playerName, true ) );
}
// Quest completion functions.
public static Value tavern( Interpreter interpreter )
{
int result = TavernManager.locateTavernFaucet();
return new Value( KoLmafia.permitsContinue() ? result : -1 );
}
public static Value tavern( Interpreter interpreter, final Value arg )
{
String goal = arg.toString();
int result = -1;
if ( goal.equalsIgnoreCase( "faucet" ) )
{
result = TavernManager.locateTavernFaucet();
}
else if ( goal.equalsIgnoreCase( "baron" ) )
{
result = TavernManager.locateBaron();
}
else if ( goal.equalsIgnoreCase( "fight" ) )
{
result = TavernManager.fightBaron();
}
else if ( goal.equalsIgnoreCase( "explore" ) )
{
result = TavernManager.exploreTavern();
}
return new Value( KoLmafia.permitsContinue() ? result : -1 );
}
public static Value hedge_maze( Interpreter interpreter, final Value arg )
{
String goal = arg.toString();
SorceressLairManager.hedgeMazeScript( goal );
return RuntimeLibrary.continueValue();
}
public static Value tower_door( Interpreter interpreter )
{
SorceressLairManager.towerDoorScript();
return RuntimeLibrary.continueValue();
}
// Arithmetic utility functions.
public static Value random( Interpreter interpreter, final Value arg )
{
int range = (int) arg.intValue();
if ( range < 2 )
{
throw interpreter.runtimeException( "Random range must be at least 2" );
}
return new Value( KoLConstants.RNG.nextInt( range ) );
}
public static Value round( Interpreter interpreter, final Value arg )
{
return new Value( (long) Math.round( arg.floatValue() ) );
}
public static Value truncate( Interpreter interpreter, final Value arg )
{
return new Value( (long) arg.floatValue() );
}
public static Value floor( Interpreter interpreter, final Value arg )
{
return new Value( (long) Math.floor( arg.floatValue() ) );
}
public static Value ceil( Interpreter interpreter, final Value arg )
{
return new Value( (long) Math.ceil( arg.floatValue() ) );
}
public static Value square_root( Interpreter interpreter, final Value val )
{
double value = val.floatValue();
if ( value < 0.0 )
{
throw interpreter.runtimeException( "Can't take square root of a negative value" );
}
return new Value( Math.sqrt( value ) );
}
public static Value min( Interpreter interpreter, final Value arg1, final Value arg2 )
{
if ( arg1.getType() == DataTypes.INT_TYPE && arg2.getType() == DataTypes.INT_TYPE )
{
return new Value( Math.min( arg1.toIntValue().intValue(),
arg2.toIntValue().intValue() ) );
}
return new Value( Math.min( arg1.toFloatValue().floatValue(),
arg2.toFloatValue().floatValue() ) );
}
public static Value max( Interpreter interpreter, final Value arg1, final Value arg2 )
{
if ( arg1.getType() == DataTypes.INT_TYPE && arg2.getType() == DataTypes.INT_TYPE )
{
return new Value( Math.max( arg1.toIntValue().intValue(),
arg2.toIntValue().intValue() ) );
}
return new Value( Math.max( arg1.toFloatValue().floatValue(),
arg2.toFloatValue().floatValue() ) );
}
// Settings-type functions.
public static Value url_encode( Interpreter interpreter, final Value arg )
{
return new Value( GenericRequest.encodeURL( arg.toString() ) );
}
public static Value url_decode( Interpreter interpreter, final Value arg )
{
return new Value( GenericRequest.decodeField( arg.toString() ) );
}
public static Value entity_encode( Interpreter interpreter, final Value arg )
throws UnsupportedEncodingException
{
return new Value( CharacterEntities.escape( arg.toString() ) );
}
public static Value entity_decode( Interpreter interpreter, final Value arg )
throws UnsupportedEncodingException
{
return new Value( CharacterEntities.unescape( arg.toString() ) );
}
private static boolean built_in_property( String name )
{
return name.startsWith( "choiceAdventure" ) ||
name.startsWith( "skillBurn" ) ||
RuntimeLibrary.frameNames.contains( name ) ||
name.equals( "KoLDesktop" );
}
public static Value get_all_properties( Interpreter interpreter, final Value filterValue, final Value globalValue )
{
// This returns a map from string -> boolean which is property name -> builtin
// filter is a substring (ignoring case) of the property name.
// If filter is "", all properties in the specified scope are returned.
String filter = filterValue.toString().trim().toLowerCase();
boolean all = filter.equals( "" );
boolean global = globalValue.intValue() != 0;
// The following create a case-insensitive map. This makes
// properties sort prettily, but, unfortunately, Preferences
// really are case sensitive.
//
// MapValue value = new MapValue( DataTypes.STRING_TO_BOOLEAN_TYPE, true );
MapValue value = new MapValue( DataTypes.STRING_TO_BOOLEAN_TYPE );
Map<String, String> properties = Preferences.getMap( false, !global );
Map<String, String> defaults = Preferences.getMap( true, !global );
for ( String name : properties.keySet() )
{
if ( !Preferences.isUserEditable( name ) )
{
continue;
}
if ( all || name.toLowerCase().contains( filter ) )
{
boolean builtIn = defaults.containsKey( name );
if ( !builtIn )
{
if ( global )
{
builtIn = Preferences.isPerUserGlobalProperty( name );
}
else
{
builtIn = RuntimeLibrary.built_in_property( name );
}
}
Value key = new Value( name );
Value val = DataTypes.makeBooleanValue( builtIn );
value.aset( key, val );
}
}
return value;
}
public static Value property_exists( Interpreter interpreter, final Value nameValue )
{
// Look up a property (in the specified scope) and return true
// if is present and false otherwise
String name = nameValue.toString();
if ( Preferences.propertyExists( name, true ) || Preferences.propertyExists( name, false ) )
{
return DataTypes.TRUE_VALUE;
}
// All choiceAdventureXXX and skillBurnXXX properties are
// considered to exist in the user scope even if they don't
// appear in defaults.txt.
if ( RuntimeLibrary.built_in_property( name ) )
{
return DataTypes.TRUE_VALUE;
}
return DataTypes.FALSE_VALUE;
}
public static Value property_exists( Interpreter interpreter, final Value nameValue, final Value globalValue )
{
// Look up a property (in the specified scope) and return true
// if is present and false otherwise
String name = nameValue.toString();
boolean global = globalValue.intValue() != 0;
if ( Preferences.propertyExists( name, global ) )
{
return DataTypes.TRUE_VALUE;
}
// All choiceAdventureXXX and skillBurnXXX properties are
// considered to exist in the user scope even if they don't
// appear in defaults.txt.
if ( !global && RuntimeLibrary.built_in_property( name ) )
{
return DataTypes.TRUE_VALUE;
}
return DataTypes.FALSE_VALUE;
}
public static Value property_has_default( Interpreter interpreter, final Value nameValue )
{
String name = nameValue.toString();
return DataTypes.makeBooleanValue( Preferences.containsDefault( name ) );
}
public static Value property_default_value( Interpreter interpreter, final Value nameValue )
{
String name = nameValue.toString();
return Preferences.containsDefault( name ) ?
DataTypes.makeStringValue( Preferences.getDefault( name ) ) :
DataTypes.STRING_INIT;
}
public static Value get_property( Interpreter interpreter, final Value name )
{
String property = name.toString();
if ( property.startsWith( "System." ) )
{
return new Value( System.getProperty( property.substring( 7 ) ) );
}
if ( Preferences.isUserEditable( property ) )
{
return DataTypes.makeStringValue( Preferences.getString( property ) );
}
return DataTypes.STRING_INIT;
}
public static Value get_property( Interpreter interpreter, final Value name, final Value globalValue )
{
String property = name.toString();
if ( !Preferences.isUserEditable( property ) )
{
return DataTypes.STRING_INIT;
}
boolean global = globalValue.intValue() != 0;
// Look up a property (in the specified scope) and return the current value.
if ( Preferences.propertyExists( property, global ) )
{
return DataTypes.makeStringValue( Preferences.getString( property, global ) );
}
// If the property is not found (in the specified scope), "" is returned
return DataTypes.STRING_INIT;
}
public static Value set_property( Interpreter interpreter, final Value nameValue, final Value value )
{
// Avoid code duplication for combat related settings
String name = nameValue.toString();
boolean builtin = Preferences.containsDefault( name );
SetPreferencesCommand.setProperty( name, value.toString(), builtin );
return DataTypes.VOID_VALUE;
}
public static Value remove_property( Interpreter interpreter, final Value nameValue )
{
String name = nameValue.toString();
if ( !Preferences.isUserEditable( name ) || Preferences.isPerUserGlobalProperty( name ) )
{
return DataTypes.STRING_INIT;
}
String oldValue;
// If it is listed in defaults.txt, set property back to default value.
if ( Preferences.containsDefault( name ) )
{
oldValue = Preferences.getString( name );
Preferences.resetToDefault( name );
}
// If it is in the user map, remove from there
else if ( Preferences.propertyExists( name, false ) )
{
oldValue = Preferences.getString( name, false );
Preferences.removeProperty( name, false );
}
// If it is in the global map, remove from there
else if ( Preferences.propertyExists( name, true ) )
{
oldValue = Preferences.getString( name, true );
Preferences.removeProperty( name, true );
}
// If it's not in either map, nothing to do
else
{
oldValue = "";
}
return DataTypes.makeStringValue( oldValue );
}
public static Value remove_property( Interpreter interpreter, final Value nameValue, final Value globalValue )
{
String name = nameValue.toString();
if ( !Preferences.isUserEditable( name ) || Preferences.isPerUserGlobalProperty( name ) )
{
return DataTypes.STRING_INIT;
}
boolean global = globalValue.intValue() != 0;
String oldValue;
// If it's not a known global property but we want to remove
// from global map, we are cleaning up orphaned globals
if ( !Preferences.isGlobalProperty( name ) && global )
{
oldValue = Preferences.getString( name, true );
Preferences.removeProperty( name, true );
}
// If it is a known global property but we want to remove from
// user map, we are cleaning up orphaned user properties
else if ( Preferences.isGlobalProperty( name ) && !global )
{
oldValue = Preferences.getString( name, false );
Preferences.removeProperty( name, false );
}
// If it is listed in defaults.txt, set property back to default value.
else if ( Preferences.containsDefault( name ) )
{
oldValue = Preferences.getString( name );
Preferences.resetToDefault( name );
}
// Otherwise, remove from the specified map.
else
{
oldValue = Preferences.getString( name, global );
Preferences.removeProperty( name, global );
}
return DataTypes.makeStringValue( oldValue );
}
public static Value rename_property( Interpreter interpreter, final Value oldNameValue, final Value newNameValue )
{
String oldName = oldNameValue.toString();
String newName = newNameValue.toString();
// User scripts cannot rename built-in properties
if ( Preferences.containsDefault( oldName ) || Preferences.containsDefault( newName ) )
{
return DataTypes.FALSE_VALUE;
}
// If the old name does not exist, do nothing
if ( !Preferences.propertyExists( oldName, false ) )
{
return DataTypes.FALSE_VALUE;
}
// If the new name does exist, do nothing
if ( Preferences.propertyExists( newName, false ) )
{
return DataTypes.FALSE_VALUE;
}
// Get value of old property in user map
String oldValue = Preferences.getString( oldName, false );
// Remove old property from user map
Preferences.removeProperty( oldName, false );
// Create new property in user map
Preferences.setString( newName, oldValue );
// Return success
return DataTypes.TRUE_VALUE;
}
// Functions for aggregates.
public static Value count( Interpreter interpreter, final Value arg )
{
return new Value( arg.count() );
}
public static Value clear( Interpreter interpreter, final Value arg )
{
arg.clear();
return DataTypes.VOID_VALUE;
}
public static Value file_to_map( Interpreter interpreter, final Value var1, final Value var2 )
{
return file_to_map( interpreter, var1, var2, DataTypes.TRUE_VALUE );
}
public static Value file_to_map( Interpreter interpreter, final Value var1, final Value var2, final Value var3 )
{
String filename = var1.toString();
CompositeValue result = (CompositeValue) var2;
boolean compact = var3.intValue() == 1;
BufferedReader reader = DataFileCache.getReader( filename );
if ( reader == null )
{
return DataTypes.FALSE_VALUE;
}
String[] data = null;
result.clear();
try
{
int line = 0;
while ( ( data = FileUtilities.readData( reader ) ) != null )
{
line++;
if ( data.length > 1 )
{
result.read( data, 0, compact, filename, line );
}
}
}
catch ( Exception e )
{
StringBuilder buffer = new StringBuilder( "Invalid line in data file" );
if ( data != null )
{
buffer.append( ": \"" );
for ( int i = 0; i < data.length; ++i )
{
if ( i > 0 )
{
buffer.append( '\t' );
}
buffer.append( data[ i ] );
}
buffer.append( "\"" );
}
// Print the bad data that caused the error
Exception ex = interpreter.runtimeException( buffer.toString() );
// If it's a ScriptException, we generated it ourself
if ( e instanceof ScriptException )
{
// Print the bad data and the resulting error
RequestLogger.printLine( ex.getMessage() );
RequestLogger.printLine( e.getMessage() );
}
else
{
// Otherwise, print a stack trace
StaticEntity.printStackTrace( e, ex.getMessage() );
}
return DataTypes.FALSE_VALUE;
}
finally
{
try
{
reader.close();
}
catch ( Exception e )
{
}
}
return DataTypes.TRUE_VALUE;
}
public static Value map_to_file( Interpreter interpreter, final Value var1, final Value var2 )
{
return map_to_file( interpreter, var1, var2, DataTypes.TRUE_VALUE );
}
public static Value map_to_file( Interpreter interpreter, final Value var1, final Value var2, final Value var3 )
{
CompositeValue map_variable = (CompositeValue) var1;
String filename = var2.toString();
boolean compact = var3.intValue() == 1;
ByteArrayOutputStream cacheStream = new ByteArrayOutputStream();
PrintStream writer = LogStream.openStream( cacheStream, "UTF-8" );
map_variable.dump( writer, "", compact );
writer.close();
byte[] data = cacheStream.toByteArray();
return DataFileCache.printBytes( filename, data );
}
// Custom combat helper functions.
public static Value my_location( Interpreter interpreter )
{
String location = Preferences.getString( "nextAdventure" );
return DataTypes.parseLocationValue( location, true );
}
public static Value set_location( Interpreter interpreter, final Value location )
{
KoLAdventure adventure = (KoLAdventure) location.rawValue();
KoLAdventure.setNextAdventure( adventure );
return DataTypes.VOID_VALUE;
}
public static Value last_monster( Interpreter interpreter )
{
return DataTypes.makeMonsterValue( MonsterStatusTracker.getLastMonster() );
}
public static Value get_monsters( Interpreter interpreter, final Value location )
{
KoLAdventure adventure = (KoLAdventure) location.rawValue();
AreaCombatData data = adventure == null ? null : adventure.getAreaSummary();
int monsterCount = data == null ? 0 : data.getMonsterCount();
int superlikelyMonsterCount = data == null ? 0 : data.getSuperlikelyMonsterCount();
AggregateType type = new AggregateType( DataTypes.MONSTER_TYPE, monsterCount + superlikelyMonsterCount );
ArrayValue value = new ArrayValue( type );
for ( int i = 0; i < monsterCount; ++i )
{
value.aset( new Value( i ), DataTypes.makeMonsterValue( data.getMonster( i ) ) );
}
for ( int i = 0; i < superlikelyMonsterCount; ++i )
{
value.aset( new Value( i + monsterCount ), DataTypes.makeMonsterValue( data.getSuperlikelyMonster( i ) ) );
}
return value;
}
public static Value get_location_monsters( Interpreter interpreter, final Value location )
{
KoLAdventure adventure = (KoLAdventure) location.rawValue();
AreaCombatData data = adventure == null ? null : adventure.getAreaSummary();
AggregateType type = new AggregateType( DataTypes.BOOLEAN_TYPE, DataTypes.MONSTER_TYPE );
MapValue value = new MapValue( type );
int monsterCount = data == null ? 0 : data.getMonsterCount();
for ( int i = 0; i < monsterCount; ++i )
{
value.aset( DataTypes.makeMonsterValue( data.getMonster( i ) ), DataTypes.TRUE_VALUE );
}
int superlikelyMonsterCount = data == null ? 0 : data.getSuperlikelyMonsterCount();
for ( int i = 0; i < superlikelyMonsterCount; ++i )
{
value.aset( DataTypes.makeMonsterValue( data.getSuperlikelyMonster( i ) ), DataTypes.TRUE_VALUE );
}
return value;
}
public static Value appearance_rates( Interpreter interpreter, final Value location )
{
return appearance_rates( interpreter, location, DataTypes.makeBooleanValue( false ) );
}
public static Value appearance_rates( Interpreter interpreter, final Value location, final Value includeQueue )
{
KoLAdventure adventure = (KoLAdventure) location.rawValue();
AreaCombatData data = adventure == null ? null : adventure.getAreaSummary();
AggregateType type = new AggregateType( DataTypes.FLOAT_TYPE, DataTypes.MONSTER_TYPE );
MapValue value = new MapValue( type );
if ( data == null )
return value;
data.recalculate();
double combatFactor = data.areaCombatPercent();
value.aset( DataTypes.MONSTER_INIT, new Value( data.combats() < 0 ? -1.0F : 100.0f - combatFactor ) );
double total = data.totalWeighting();
double superlikelyChance = 0.0;
for ( int i = data.getSuperlikelyMonsterCount() - 1; i >= 0; --i )
{
MonsterData monster = data.getSuperlikelyMonster( i );
String name = monster.getName();
double chance = AreaCombatData.superlikelyChance( name );
superlikelyChance += chance;
Value toSet = new Value( chance );
value.aset( DataTypes.makeMonsterValue( monster ), toSet );
}
for ( int i = data.getMonsterCount() - 1; i >= 0; --i )
{
int weight = data.getWeighting( i );
double rejection = data.getRejection( i );
if ( weight == -2 )
continue; // impossible this ascension
Value toSet;
if ( weight == -4 )
{
// Temporarily set to 0% chance
toSet = new Value( 0 );
}
else if ( weight <= 0 )
{
// Ultrarares & Banished
toSet = new Value( weight );
}
else if ( includeQueue.intValue() == 1 )
{
toSet =
new Value( AdventureQueueDatabase.applyQueueEffects(
combatFactor * weight * ( 1 - superlikelyChance / 100 ) * ( 1 - rejection / 100 ), data.getMonster( i ), data ) );
}
else
{
toSet = new Value( combatFactor * ( 1 - superlikelyChance / 100 ) * ( 1 - rejection / 100 ) * weight / total );
}
value.aset( DataTypes.makeMonsterValue( data.getMonster( i ) ), toSet );
}
return value;
}
public static Value expected_damage( Interpreter interpreter )
{
return expected_damage( interpreter, MonsterStatusTracker.getLastMonster(), MonsterStatusTracker.getMonsterAttackModifier() );
}
public static Value expected_damage( Interpreter interpreter, final Value arg )
{
return expected_damage( interpreter, (MonsterData) arg.rawValue(), 0 );
}
private static Value expected_damage( Interpreter interpreter, MonsterData monster, int attackModifier )
{
if ( monster == null )
{
return DataTypes.ZERO_VALUE;
}
// http://kol.coldfront.net/thekolwiki/index.php/Damage
int attack = monster.getAttack() + attackModifier;
int defenseStat = KoLCharacter.getAdjustedMoxie();
if ( KoLCharacter.hasSkill(SkillDatabase.getSkillId("Hero of the Half-Shell" ) ) &&
EquipmentManager.usingShield() &&
KoLCharacter.getAdjustedMuscle() > defenseStat )
{
defenseStat = KoLCharacter.getAdjustedMuscle();
}
int baseValue =
Math.max( 0, attack - defenseStat ) + attack / 4 - KoLCharacter.getDamageReduction();
double damageAbsorb =
1.0 - ( Math.sqrt( Math.min( 1000, KoLCharacter.getDamageAbsorption() ) / 10.0 ) - 1.0 ) / 10.0;
double elementAbsorb = 1.0 - KoLCharacter.getElementalResistance( monster.getAttackElement() ) / 100.0;
return new Value( (int) Math.ceil( baseValue * damageAbsorb * elementAbsorb ) );
}
public static Value monster_level_adjustment( Interpreter interpreter )
{
return new Value( KoLCharacter.getMonsterLevelAdjustment() );
}
public static Value weight_adjustment( Interpreter interpreter )
{
return new Value( KoLCharacter.getFamiliarWeightAdjustment() );
}
public static Value mana_cost_modifier( Interpreter interpreter )
{
return new Value( KoLCharacter.getManaCostAdjustment() );
}
public static Value combat_mana_cost_modifier( Interpreter interpreter )
{
return new Value( KoLCharacter.getManaCostAdjustment( true ) );
}
public static Value raw_damage_absorption( Interpreter interpreter )
{
return new Value( KoLCharacter.getDamageAbsorption() );
}
public static Value damage_absorption_percent( Interpreter interpreter )
{
int raw = Math.min( 1000, KoLCharacter.getDamageAbsorption() );
if ( raw == 0 )
{
return DataTypes.ZERO_FLOAT_VALUE;
}
// http://forums.kingdomofloathing.com/viewtopic.php?p=2016073
// ( sqrt( raw / 10 ) - 1 ) / 10
double percent = ( Math.sqrt( raw / 10.0 ) - 1.0 ) * 10.0;
return new Value( percent );
}
public static Value damage_reduction( Interpreter interpreter )
{
return new Value( KoLCharacter.getDamageReduction() );
}
public static Value elemental_resistance( Interpreter interpreter )
{
return new Value( KoLCharacter.getElementalResistance( MonsterStatusTracker.getMonsterAttackElement() ) );
}
public static Value elemental_resistance( Interpreter interpreter, final Value arg )
{
if ( arg.getType().equals( DataTypes.TYPE_ELEMENT ) )
{
String elementName = arg.toString();
Element elem = Element.fromString( elementName );
return new Value( KoLCharacter.getElementalResistance( elem ) );
}
MonsterData monster = (MonsterData) arg.rawValue();
if ( monster == null )
{
return DataTypes.ZERO_VALUE;
}
return new Value( KoLCharacter.getElementalResistance( monster.getAttackElement() ) );
}
public static Value combat_rate_modifier( Interpreter interpreter )
{
return new Value( KoLCharacter.getCombatRateAdjustment() );
}
public static Value initiative_modifier( Interpreter interpreter )
{
return new Value( KoLCharacter.getInitiativeAdjustment() );
}
public static Value experience_bonus( Interpreter interpreter )
{
return new Value( KoLCharacter.getExperienceAdjustment() );
}
public static Value meat_drop_modifier( Interpreter interpreter )
{
return new Value( KoLCharacter.getMeatDropPercentAdjustment() );
}
public static Value item_drop_modifier( Interpreter interpreter )
{
return new Value( KoLCharacter.getItemDropPercentAdjustment() );
}
public static Value buffed_hit_stat( Interpreter interpreter )
{
int hitStat = EquipmentManager.getAdjustedHitStat();
return new Value( hitStat );
}
public static Value current_hit_stat( Interpreter interpreter )
{
return EquipmentManager.getHitStatType() == Stat.MOXIE ? DataTypes.MOXIE_VALUE : DataTypes.MUSCLE_VALUE;
}
public static Value monster_element( Interpreter interpreter )
{
Element element = MonsterStatusTracker.getMonsterDefenseElement();
return new Value( DataTypes.ELEMENT_TYPE, element.toString(), element );
}
public static Value monster_element( Interpreter interpreter, final Value arg )
{
MonsterData monster = (MonsterData) arg.rawValue();
if ( monster == null )
{
return DataTypes.ELEMENT_INIT;
}
Element element = monster.getDefenseElement();
return new Value( DataTypes.ELEMENT_TYPE, element.toString(), element );
}
public static Value monster_attack( Interpreter interpreter )
{
return new Value( MonsterStatusTracker.getMonsterAttack() );
}
public static Value monster_attack( Interpreter interpreter, final Value arg )
{
MonsterData monster = (MonsterData) arg.rawValue();
if ( monster == null )
{
return DataTypes.ZERO_VALUE;
}
return new Value( monster.getAttack() );
}
public static Value monster_defense( Interpreter interpreter )
{
return new Value( MonsterStatusTracker.getMonsterDefense() );
}
public static Value monster_defense( Interpreter interpreter, final Value arg )
{
MonsterData monster = (MonsterData) arg.rawValue();
if ( monster == null )
{
return DataTypes.ZERO_VALUE;
}
return new Value( monster.getDefense() );
}
public static Value monster_initiative( Interpreter interpreter )
{
return new Value( MonsterStatusTracker.getMonsterInitiative() );
}
public static Value monster_initiative( Interpreter interpreter, final Value arg )
{
MonsterData monster = (MonsterData) arg.rawValue();
if ( monster == null )
{
return DataTypes.ZERO_VALUE;
}
return new Value( monster.getInitiative() );
}
public static Value monster_hp( Interpreter interpreter )
{
return new Value( MonsterStatusTracker.getMonsterHealth() );
}
public static Value monster_hp( Interpreter interpreter, final Value arg )
{
MonsterData monster = (MonsterData) arg.rawValue();
if ( monster == null )
{
return DataTypes.ZERO_VALUE;
}
return new Value( monster.getHP() );
}
public static Value monster_phylum( Interpreter interpreter )
{
Phylum phylum = MonsterStatusTracker.getMonsterPhylum();
return new Value( DataTypes.PHYLUM_TYPE, phylum.toString(), phylum );
}
public static Value monster_phylum( Interpreter interpreter, final Value arg )
{
MonsterData monster = (MonsterData) arg.rawValue();
if ( monster == null )
{
return DataTypes.PHYLUM_INIT;
}
Phylum phylum = monster.getPhylum();
return new Value( DataTypes.PHYLUM_TYPE, phylum.toString(), phylum );
}
public static Value is_banished( Interpreter interpreter, final Value arg )
{
MonsterData monster = (MonsterData) arg.rawValue();
if ( monster == null )
{
return DataTypes.FALSE_VALUE;
}
return DataTypes.makeBooleanValue( BanishManager.isBanished( (String) monster.getName() ) );
}
public static Value jump_chance( Interpreter interpreter )
{
return new Value( MonsterStatusTracker.getJumpChance() );
}
public static Value jump_chance( Interpreter interpreter, final Value arg )
{
if ( arg.getType().equals( DataTypes.TYPE_MONSTER ) )
{
MonsterData monster = (MonsterData) arg.rawValue();
if ( monster == null )
{
return DataTypes.ZERO_VALUE;
}
return new Value( monster.getJumpChance() );
}
if ( arg.getType().equals( DataTypes.TYPE_LOCATION ) )
{
KoLAdventure adventure = (KoLAdventure) arg.rawValue();
AreaCombatData data = adventure == null ? null : adventure.getAreaSummary();
int monsterCount = data == null ? 0 : data.getMonsterCount();
int superlikelyMonsterCount = data == null ? 0 : data.getSuperlikelyMonsterCount();
int jumpChance = data == null ? 0 : 100;
for ( int i = 0; i < monsterCount; ++i )
{
int monsterJumpChance = data.getMonster( i ).getJumpChance();
if ( jumpChance > monsterJumpChance && data.getWeighting( i ) > 0 )
{
jumpChance = monsterJumpChance;
}
}
for ( int i = 0; i < superlikelyMonsterCount; ++i )
{
MonsterData monster = data.getSuperlikelyMonster( i );
int monsterJumpChance = monster.getJumpChance();
if ( jumpChance > monsterJumpChance && data.superlikelyChance( monster.getName() ) > 0 )
{
jumpChance = monsterJumpChance;
}
}
return new Value( jumpChance );
}
return DataTypes.ZERO_VALUE;
}
public static Value jump_chance( Interpreter interpreter, final Value arg, final Value init )
{
int initiative = (int) init.intValue();
if ( arg.getType().equals( DataTypes.TYPE_MONSTER ) )
{
MonsterData monster = (MonsterData) arg.rawValue();
if ( monster == null )
{
return DataTypes.ZERO_VALUE;
}
return new Value( monster.getJumpChance( initiative ) );
}
if ( arg.getType().equals( DataTypes.TYPE_LOCATION ) )
{
KoLAdventure adventure = (KoLAdventure) arg.rawValue();
AreaCombatData data = adventure == null ? null : adventure.getAreaSummary();
int monsterCount = data == null ? 0 : data.getMonsterCount();
int superlikelyMonsterCount = data == null ? 0 : data.getSuperlikelyMonsterCount();
int jumpChance = data == null ? 0 : 100;
for ( int i = 0; i < monsterCount; ++i )
{
int monsterJumpChance = data.getMonster( i ).getJumpChance( initiative );
if ( jumpChance > monsterJumpChance && data.getWeighting( i ) > 0 )
{
jumpChance = monsterJumpChance;
}
}
for ( int i = 0; i < superlikelyMonsterCount; ++i )
{
MonsterData monster = data.getSuperlikelyMonster( i );
int monsterJumpChance = monster.getJumpChance( initiative );
if ( jumpChance > monsterJumpChance && AreaCombatData.superlikelyChance( monster.getName() ) > 0 )
{
jumpChance = monsterJumpChance;
}
}
return new Value( jumpChance );
}
return DataTypes.ZERO_VALUE;
}
public static Value jump_chance( Interpreter interpreter, final Value arg, final Value init, final Value ml )
{
int initiative = (int) init.intValue();
int monsterLevel = (int) ml.intValue();
if ( arg.getType().equals( DataTypes.TYPE_MONSTER ) )
{
MonsterData monster = (MonsterData) arg.rawValue();
if ( monster == null )
{
return DataTypes.ZERO_VALUE;
}
return new Value( monster.getJumpChance( initiative, monsterLevel ) );
}
if ( arg.getType().equals( DataTypes.TYPE_LOCATION ) )
{
KoLAdventure adventure = (KoLAdventure) arg.rawValue();
AreaCombatData data = adventure == null ? null : adventure.getAreaSummary();
int monsterCount = data == null ? 0 : data.getMonsterCount();
int jumpChance = data == null ? 0 : 100;
for ( int i = 0; i < monsterCount; ++i )
{
int monsterJumpChance = data.getMonster( i ).getJumpChance( initiative, monsterLevel );
if ( jumpChance > monsterJumpChance && data.getWeighting( i ) > 0 )
{
jumpChance = monsterJumpChance;
}
}
return new Value( jumpChance );
}
return DataTypes.ZERO_VALUE;
}
public static Value item_drops( Interpreter interpreter )
{
MonsterData monster = MonsterStatusTracker.getLastMonster();
List data = monster == null ? new ArrayList() : monster.getItems();
MapValue value = new MapValue( DataTypes.ITEM_TO_INT_TYPE );
AdventureResult result;
for ( int i = 0; i < data.size(); ++i )
{
result = (AdventureResult) data.get( i );
value.aset(
DataTypes.makeItemValue( result.getItemId(), true ),
DataTypes.parseIntValue( String.valueOf( result.getCount() >> 16 ), true ) );
}
return value;
}
public static Value item_drops( Interpreter interpreter, final Value arg )
{
MonsterData monster = (MonsterData) arg.rawValue();
List data = monster == null ? new ArrayList() : monster.getItems();
MapValue value = new MapValue( DataTypes.ITEM_TO_INT_TYPE );
AdventureResult result;
for ( int i = 0; i < data.size(); ++i )
{
result = (AdventureResult) data.get( i );
value.aset(
DataTypes.makeItemValue( result.getItemId(), true ),
DataTypes.parseIntValue( String.valueOf( result.getCount() >> 16 ), true ) );
}
return value;
}
public static Value item_drops_array( Interpreter interpreter )
{
return item_drops_array( interpreter, MonsterStatusTracker.getLastMonster() );
}
public static Value item_drops_array( Interpreter interpreter, final Value arg )
{
return item_drops_array( interpreter, (MonsterData) arg.rawValue() );
}
public static Value item_drops_array( Interpreter interpreter, MonsterData monster )
{
List data = monster == null ? new ArrayList() : monster.getItems();
int dropCount = data.size();
AggregateType type = new AggregateType( RuntimeLibrary.itemDropRec, dropCount );
ArrayValue value = new ArrayValue( type );
for ( int i = 0; i < dropCount; ++i )
{
AdventureResult result = (AdventureResult) data.get( i );
int count = result.getCount();
char dropType = (char) (count & 0xFFFF);
RecordValue rec = (RecordValue) value.aref( new Value( i ) );
rec.aset( 0, DataTypes.makeItemValue( result.getItemId(), true ), null );
rec.aset( 1, new Value( count >> 16 ), null );
if ( dropType < '1' || dropType > '9' )
{ // leave as an empty string if no special type was given
rec.aset( 2, new Value( String.valueOf( dropType ) ), null );
}
}
return value;
}
public static Value svn_info( Interpreter interpreter, final Value script )
{
String[] projects = KoLConstants.SVN_LOCATION.list();
if ( projects == null )
return getRecInit();
ArrayList<String> matches = new ArrayList<String>();
for ( String s: projects )
{
if ( s.contains( script.toString() ) )
{
matches.add( s );
}
}
if ( matches.size() != 1 )
{
return getRecInit();
}
File projectFile = new File( KoLConstants.SVN_LOCATION, matches.get( 0 ) );
try
{
if ( !SVNWCUtil.isWorkingCopyRoot( projectFile ) )
{
return getRecInit();
}
}
catch ( SVNException e1 )
{
return getRecInit();
}
RecordType type = RuntimeLibrary.svnInfoRec;
RecordValue rec = new RecordValue( type );
// get info
SVNInfo info;
try
{
info = SVNManager.doInfo( projectFile );
}
catch ( SVNException e )
{
SVNManager.error( e, null );
return getRecInit();
}
// URL
rec.aset( 0, new Value( info.getURL().toString() ), null );
// revision
rec.aset( 1, DataTypes.makeIntValue( info.getRevision().getNumber() ), null );
// lastChangedAuthor
rec.aset( 2, new Value( info.getAuthor() ), null );
// lastChangedRev
rec.aset( 3, DataTypes.makeIntValue( info.getCommittedRevision().getNumber() ), null );
// lastChangedDate
// use format that is similar to what 'svn info' gives, ex:
// Last Changed Date: 2003-01-16 23:21:19 -0600 (Thu, 16 Jan 2003)
SimpleDateFormat SVN_FORMAT = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss z (EEE, dd MMM yyyy)", Locale.US );
rec.aset( 4, new Value( SVN_FORMAT.format( info.getCommittedDate() ) ), null );
return rec;
}
private static RecordValue getRecInit()
{
RecordType type = RuntimeLibrary.svnInfoRec;
RecordValue rec = new RecordValue( type );
rec.aset( 0, DataTypes.STRING_INIT, null );
// revision
rec.aset( 1, DataTypes.INT_INIT, null );
// lastChangedAuthor
rec.aset( 2, DataTypes.STRING_INIT, null );
// lastChangedRev
rec.aset( 3, DataTypes.INT_INIT, null );
// lastChangedDate
rec.aset( 4, DataTypes.STRING_INIT, null );
return rec;
}
public static Value meat_drop( Interpreter interpreter )
{
MonsterData monster = MonsterStatusTracker.getLastMonster();
if ( monster == null )
{
return new Value( -1 );
}
return new Value( monster.getBaseMeat() );
}
public static Value meat_drop( Interpreter interpreter, final Value arg )
{
MonsterData monster = (MonsterData) arg.rawValue();
if ( monster == null )
{
return new Value( -1 );
}
return new Value( monster.getBaseMeat() );
}
public static Value will_usually_dodge( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( MonsterStatusTracker.willUsuallyDodge() );
}
public static Value will_usually_miss( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( MonsterStatusTracker.willUsuallyMiss() );
}
public static Value dad_sea_monkee_weakness( Interpreter interpreter, final Value arg )
{
DadManager.Element element = DadManager.weakness( (int)arg.intValue() );
switch ( element )
{
case HOT:
return new Value( DataTypes.ELEMENT_TYPE, "hot", element );
case COLD:
return new Value( DataTypes.ELEMENT_TYPE, "cold", element );
case STENCH:
return new Value( DataTypes.ELEMENT_TYPE, "stench", element );
case SPOOKY:
return new Value( DataTypes.ELEMENT_TYPE, "spooky", element );
case SLEAZE:
return new Value( DataTypes.ELEMENT_TYPE, "sleaze", element );
}
return DataTypes.ELEMENT_INIT;
}
public static Value flush_monster_manuel_cache( Interpreter interpreter )
{
MonsterManuelManager.flushCache();
return DataTypes.TRUE_VALUE;
}
public static Value monster_manuel_text( Interpreter interpreter, final Value arg )
{
return new Value( MonsterManuelManager.getManuelText( (int) arg.intValue() ) );
}
public static Value monster_factoids_available( Interpreter interpreter, final Value arg1, final Value arg2 )
{
return new Value( MonsterManuelManager.getFactoidsAvailable( (int) arg1.intValue(), arg2.intValue() != 0 ) );
}
public static Value all_monsters_with_id( Interpreter interpreter )
{
AggregateType type = new AggregateType( DataTypes.BOOLEAN_TYPE, DataTypes.MONSTER_TYPE );
MapValue value = new MapValue( type );
for ( Integer id : MonsterDatabase.idKeySet() )
{
if ( id == 0 ) continue;
Value v = DataTypes.makeMonsterValue( id, false );
if ( v != null ) value.aset( v, DataTypes.TRUE_VALUE );
}
return value;
}
private static String getModifierType( final Value arg )
{
Type type = arg.getType();
String name = arg.toString();
int id = (int) arg.intValue();
if ( type.equals( DataTypes.ITEM_TYPE ) )
{
return "Item";
}
if ( type.equals( DataTypes.EFFECT_TYPE ) )
{
return "Effect";
}
if ( type.equals( DataTypes.SKILL_TYPE ) )
{
return "Skill";
}
if ( type.equals( DataTypes.THRALL_TYPE ) )
{
return "Thrall";
}
if ( name.contains( ":" ) )
{
return name.substring( 0, name.indexOf( ":" ) );
}
return "Item";
}
private static String getModifierName( final Value arg )
{
Type type = arg.getType();
String name = arg.toString();
int id = (int) arg.intValue();
if ( type.equals( DataTypes.ITEM_TYPE ) || type.equals( DataTypes.EFFECT_TYPE ) )
{
return "[" + id + "]";
}
int index = name.indexOf( ":" );
if ( index != -1 )
{
return name.substring( index + 1 );
}
return name;
}
public static Value numeric_modifier( Interpreter interpreter, final Value modifier )
{
String mod = modifier.toString();
return new Value( KoLCharacter.currentNumericModifier( mod ) );
}
public static Value numeric_modifier( Interpreter interpreter, final Value arg, final Value modifier )
{
String type = RuntimeLibrary.getModifierType( arg );
String name = RuntimeLibrary.getModifierName( arg );
String mod = modifier.toString();
return new Value( Modifiers.getNumericModifier( type, name, mod ) );
}
public static Value numeric_modifier( Interpreter interpreter, final Value familiar, final Value modifier, final Value weight, final Value item )
{
FamiliarData fam = new FamiliarData( (int) familiar.intValue() );
String mod = modifier.toString();
int w = Math.max( 1, (int) weight.intValue() );
AdventureResult it = ItemPool.get( (int) item.intValue() );
return new Value( Modifiers.getNumericModifier( fam, mod, w, it ) );
}
public static Value boolean_modifier( Interpreter interpreter, final Value modifier )
{
String mod = modifier.toString();
return DataTypes.makeBooleanValue( KoLCharacter.currentBooleanModifier( mod ) );
}
public static Value boolean_modifier( Interpreter interpreter, final Value arg, final Value modifier )
{
String type = RuntimeLibrary.getModifierType( arg );
String name = RuntimeLibrary.getModifierName( arg );
String mod = modifier.toString();
return DataTypes.makeBooleanValue( Modifiers.getBooleanModifier( type, name, mod ) );
}
public static Value string_modifier( Interpreter interpreter, final Value modifier )
{
String mod = modifier.toString();
return new Value( KoLCharacter.currentStringModifier( mod ) );
}
public static Value string_modifier( Interpreter interpreter, final Value arg, final Value modifier )
{
String type = RuntimeLibrary.getModifierType( arg );
String name = RuntimeLibrary.getModifierName( arg );
String mod = modifier.toString();
return new Value( Modifiers.getStringModifier( type, name, mod ) );
}
public static Value effect_modifier( Interpreter interpreter, final Value arg, final Value modifier )
{
String type = RuntimeLibrary.getModifierType( arg );
String name = RuntimeLibrary.getModifierName( arg );
String mod = modifier.toString();
return new Value( DataTypes.parseEffectValue( Modifiers.getStringModifier( type, name, mod ), true ) );
}
public static Value class_modifier( Interpreter interpreter, final Value arg, final Value modifier )
{
String type = RuntimeLibrary.getModifierType( arg );
String name = RuntimeLibrary.getModifierName( arg );
String mod = modifier.toString();
return new Value( DataTypes.parseClassValue( Modifiers.getStringModifier( type, name, mod ), true ) );
}
public static Value skill_modifier( Interpreter interpreter, final Value arg, final Value modifier )
{
String type = RuntimeLibrary.getModifierType( arg );
String name = RuntimeLibrary.getModifierName( arg );
String mod = modifier.toString();
return new Value( DataTypes.parseSkillValue( Modifiers.getStringModifier( type, name, mod ), true ) );
}
public static Value stat_modifier( Interpreter interpreter, final Value arg, final Value modifier )
{
String type = RuntimeLibrary.getModifierType( arg );
String name = RuntimeLibrary.getModifierName( arg );
String mod = modifier.toString();
return new Value( DataTypes.parseStatValue( Modifiers.getStringModifier( type, name, mod ), true ) );
}
public static Value white_citadel_available( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( QuestLogRequest.isWhiteCitadelAvailable() );
}
public static Value friars_available( Interpreter interpreter )
{
if ( QuestLogRequest.areFriarsAvailable() )
Preferences.setInteger( "lastFriarCeremonyAscension", Preferences.getInteger( "knownAscensions" ));
return DataTypes.makeBooleanValue( QuestLogRequest.areFriarsAvailable() );
}
public static Value black_market_available( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( QuestLogRequest.isBlackMarketAvailable() );
}
public static Value hippy_store_available( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( QuestLogRequest.isHippyStoreAvailable() );
}
public static Value dispensary_available( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.getDispensaryOpen() );
}
public static Value guild_store_available( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.getGuildStoreOpen() );
}
public static Value hidden_temple_unlocked( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.getTempleUnlocked() );
}
public static Value knoll_available( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.knollAvailable() );
}
public static Value canadia_available( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.canadiaAvailable() );
}
public static Value gnomads_available( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( KoLCharacter.gnomadsAvailable() );
}
public static Value florist_available( Interpreter interpreter )
{
return DataTypes.makeBooleanValue( FloristRequest.haveFlorist() );
}
public static Value is_trendy( Interpreter interpreter, final Value thing )
{
// Types: "Items", "Campground", Bookshelf", "Familiars", "Skills", "Clan Item".
String key = thing.toString();
Type type = thing.getType();
boolean result;
if ( type.equals( DataTypes.TYPE_STRING ) )
{
result = TrendyRequest.isTrendy( "Items", key ) &&
TrendyRequest.isTrendy( "Campground", key ) &&
TrendyRequest.isTrendy( "Bookshelf", key ) &&
TrendyRequest.isTrendy( "Familiars", key ) &&
TrendyRequest.isTrendy( "Skills", key ) &&
TrendyRequest.isTrendy( "Clan Item", key );
}
else if ( type.equals( DataTypes.TYPE_ITEM ) )
{
result = TrendyRequest.isTrendy( "Items", key );
}
else if ( type.equals( DataTypes.TYPE_FAMILIAR ) )
{
result = TrendyRequest.isTrendy( "Familiars", key );
}
else if ( type.equals( DataTypes.TYPE_SKILL ) )
{
if ( SkillDatabase.isBookshelfSkill( key ) )
{
int itemId = SkillDatabase.skillToBook( key );
key = ItemDatabase.getItemName( itemId );
result = TrendyRequest.isTrendy( "Bookshelf", key );
}
else
{
result = TrendyRequest.isTrendy( "Skills", key );
}
}
else
{
result = false;
}
return DataTypes.makeBooleanValue( result );
}
public static Value is_unrestricted( Interpreter interpreter, final Value thing )
{
// Types: "Items", Bookshelf Books", "Skills", "Familiars", "Clan Item".
String key = thing.toString();
Type type = thing.getType();
boolean result;
if ( type.equals( DataTypes.TYPE_STRING ) )
{
result =
StandardRequest.isNotRestricted( "Items", key ) &&
StandardRequest.isNotRestricted( "Bookshelf Books", key ) &&
StandardRequest.isNotRestricted( "Skills", key ) &&
StandardRequest.isNotRestricted( "Familiars", key ) &&
StandardRequest.isNotRestricted( "Clan Items", key );
}
else if ( type.equals( DataTypes.TYPE_ITEM ) )
{
result = StandardRequest.isNotRestricted( "Items", key );
}
else if ( type.equals( DataTypes.TYPE_FAMILIAR ) )
{
result = StandardRequest.isNotRestricted( "Familiars", key );
}
else if ( type.equals( DataTypes.TYPE_SKILL ) )
{
if ( SkillDatabase.isBookshelfSkill( key ) )
{
int itemId = SkillDatabase.skillToBook( key );
key = ItemDatabase.getItemName( itemId );
// Work around a KoL bug: most restricted books are
// listed both under Bookshelf Books and Items, but
// 3 are listed under only one or the other.
result = StandardRequest.isNotRestricted( "Bookshelf Books", key ) &&
StandardRequest.isNotRestricted( "Items", key );
}
else
{
result = StandardRequest.isNotRestricted( "Skills", key );
}
}
else
{
result = false;
}
return DataTypes.makeBooleanValue( result );
}
public static Value mmg_visit( Interpreter interpreter )
{
RequestThread.postRequest( new MoneyMakingGameRequest() );
return DataTypes.VOID_VALUE;
}
public static Value mmg_search( Interpreter interpreter, final Value arg1, final Value arg2 )
{
int lower = (int) arg1.intValue();
int higher = (int) arg2.intValue();
RequestThread.postRequest( new MoneyMakingGameRequest( MoneyMakingGameRequest.SEARCH, lower, higher ) );
return DataTypes.VOID_VALUE;
}
public static Value mmg_make_bet( Interpreter interpreter, final Value arg, final Value source )
{
int amount = (int) arg.intValue();
int storage = (int) source.intValue();
RequestThread.postRequest( new MoneyMakingGameRequest( MoneyMakingGameRequest.MAKE_BET, amount, storage ) );
return new Value( MoneyMakingGameManager.getLastBetId() );
}
public static Value mmg_retract_bet( Interpreter interpreter, final Value arg )
{
int id = (int) arg.intValue();
RequestThread.postRequest( new MoneyMakingGameRequest( MoneyMakingGameRequest.RETRACT_BET, id ) );
return RuntimeLibrary.continueValue();
}
public static Value mmg_take_bet( Interpreter interpreter, final Value arg, final Value source )
{
int betId = (int) arg.intValue();
int storage = (int) source.intValue();
RequestThread.postRequest( new MoneyMakingGameRequest( MoneyMakingGameRequest.TAKE_BET, betId, storage ) );
return new Value( MoneyMakingGameManager.getLastWinnings() );
}
public static Value mmg_my_bets( Interpreter interpreter )
{
int[] bets = MoneyMakingGameManager.getActiveBets();
AggregateType type = new AggregateType( DataTypes.INT_TYPE, bets.length );
ArrayValue value = new ArrayValue( type );
for ( int i = 0; i < bets.length; ++i )
{
value.aset( new Value( i ), new Value( bets[ i ] ) );
}
return value;
}
public static Value mmg_offered_bets( Interpreter interpreter )
{
int[] bets = MoneyMakingGameManager.getOfferedBets();
AggregateType type = new AggregateType( DataTypes.INT_TYPE, bets.length );
ArrayValue value = new ArrayValue( type );
for ( int i = 0; i < bets.length; ++i )
{
value.aset( new Value( i ), new Value( bets[ i ] ) );
}
return value;
}
public static Value mmg_bet_owner( Interpreter interpreter, final Value arg )
{
int id = (int) arg.intValue();
return new Value( MoneyMakingGameManager.betOwner( id ) );
}
public static Value mmg_bet_owner_id( Interpreter interpreter, final Value arg )
{
int id = (int) arg.intValue();
return new Value( MoneyMakingGameManager.betOwnerId( id ) );
}
public static Value mmg_bet_amount( Interpreter interpreter, final Value arg )
{
int id = (int) arg.intValue();
return new Value( MoneyMakingGameManager.betAmount( id ) );
}
public static Value mmg_wait_event( Interpreter interpreter, final Value arg )
{
int seconds = (int) arg.intValue();
return new Value( MoneyMakingGameManager.getNextEvent( seconds ) );
}
public static Value mmg_bet_taker( Interpreter interpreter )
{
return new Value( MoneyMakingGameManager.getLastEventPlayer() );
}
public static Value mmg_bet_taker_id( Interpreter interpreter )
{
return new Value( MoneyMakingGameManager.getLastEventPlayerId() );
}
public static Value mmg_bet_winnings( Interpreter interpreter )
{
return new Value( MoneyMakingGameManager.getLastEventWinnings() );
}
public static Value svn_exists( Interpreter interpreter, final Value project )
{
File f = new File( KoLConstants.SVN_LOCATION, project.toString() );
boolean isWCRoot = false;
try
{
isWCRoot = SVNWCUtil.isWorkingCopyRoot( f );
}
catch ( SVNException e )
{
StaticEntity.printStackTrace( e );
}
return DataTypes.makeBooleanValue( isWCRoot );
}
public static Value svn_at_head( Interpreter interpreter, final Value project )
{
File f = new File( KoLConstants.SVN_LOCATION, project.toString() );
if ( !f.exists() || !f.isDirectory() )
{
return DataTypes.FALSE_VALUE;
}
return DataTypes.makeBooleanValue( SVNManager.WCAtHead( f, true ) );
}
// Sweet Synthesis
public static Value candy_for_tier( Interpreter interpreter, final Value arg )
{
return RuntimeLibrary.candy_for_tier( interpreter, arg, DataTypes.makeIntValue( CandyDatabase.defaultFlags() ) );
}
public static Value candy_for_tier( Interpreter interpreter, final Value arg1, final Value arg2 )
{
int tier = (int) arg1.intValue();
int flags = (int) arg2.intValue();
Set<Integer> candies = CandyDatabase.candyForTier( tier, flags );
int count = ( candies == null ) ? 0 : candies.size();
AggregateType type = new AggregateType( DataTypes.ITEM_TYPE, count );
ArrayValue value = new ArrayValue( type );
if ( candies != null )
{
int index = 0;
for ( Integer itemId : candies )
{
Value key = new Value( index++ );
Value val = DataTypes.makeItemValue( itemId.intValue(), true );
value.aset( key, val );
}
}
return value;
}
public static Value sweet_synthesis_pairing( Interpreter interpreter, final Value arg1, final Value arg2 )
{
return RuntimeLibrary.sweet_synthesis_pairing( interpreter, arg1, arg2, DataTypes.makeIntValue( CandyDatabase.defaultFlags() ) );
}
public static Value sweet_synthesis_pairing( Interpreter interpreter, final Value arg1, final Value arg2, final Value arg3 )
{
int effectId = (int) arg1.intValue();
int itemId = (int) arg2.intValue();
int flags = (int) arg3.intValue();
Set<Integer> candies = CandyDatabase.sweetSynthesisPairing( effectId, itemId, flags );
int count = ( candies == null ) ? 0 : candies.size();
AggregateType type = new AggregateType( DataTypes.ITEM_TYPE, count );
ArrayValue value = new ArrayValue( type );
if ( candies != null )
{
int index = 0;
for ( Integer itemId2 : candies )
{
Value key = new Value( index++ );
Value val = DataTypes.makeItemValue( itemId2.intValue(), true );
value.aset( key, val );
}
}
return value;
}
public static Value sweet_synthesis_pair( Interpreter interpreter, final Value arg1 )
{
return RuntimeLibrary.sweet_synthesis_pair( interpreter, arg1, DataTypes.makeIntValue( CandyDatabase.defaultFlags() ) );
}
public static Value sweet_synthesis_pair( Interpreter interpreter, final Value arg1, final Value arg2 )
{
int effectId = (int) arg1.intValue();
int flags = (int) arg2.intValue();
AggregateType type = new AggregateType( DataTypes.ITEM_TYPE, 2 );
ArrayValue value = new ArrayValue( type );
Candy[] candies = CandyDatabase.synthesisPair( effectId, flags );
if ( candies.length == 2 )
{
value.aset( new Value( 0 ), DataTypes.makeItemValue( candies[0].getItemId(), true ) );
value.aset( new Value( 1 ), DataTypes.makeItemValue( candies[1].getItemId(), true ) );
}
return value;
}
public static Value sweet_synthesis_result( Interpreter interpreter, final Value item1, final Value item2 )
{
int itemId1 = (int) item1.intValue();
int itemId2 = (int) item2.intValue();
int effectId = CandyDatabase.synthesisResult( itemId1, itemId2 );
return effectId == -1 ? DataTypes.EFFECT_INIT : DataTypes.makeEffectValue( effectId, true );
}
public static Value sweet_synthesis( Interpreter interpreter, final Value effect )
{
int effectId = (int) effect.intValue();
Candy[] candies = CandyDatabase.synthesisPair( effectId );
if ( candies.length != 2 )
{
return DataTypes.FALSE_VALUE;
}
int itemId1 = candies[0].getItemId();
int itemId2 = candies[1].getItemId();
// SweetSynthesisRequest will retrieve the candies
SweetSynthesisRequest request = new SweetSynthesisRequest( itemId1, itemId2 );
RequestThread.postRequest( request );
return RuntimeLibrary.continueValue();
}
public static Value sweet_synthesis( Interpreter interpreter, final Value arg1, final Value arg2 )
{
Type type = arg1.getType();
int itemId1 = -1;
int itemId2 = -1;
if ( type.equals( DataTypes.TYPE_ITEM ) )
{
itemId1 = (int) arg1.intValue();
itemId2 = (int) arg2.intValue();
if ( !ItemDatabase.isCandyItem( itemId1 ) || !ItemDatabase.isCandyItem( itemId2 ) )
{
return DataTypes.FALSE_VALUE;
}
}
else
{
int effectId = (int) arg1.intValue();
int flags = (int) arg2.intValue() | CandyDatabase.defaultFlags();
Candy[] candies = CandyDatabase.synthesisPair( effectId, flags );
if ( candies.length != 2 )
{
return DataTypes.FALSE_VALUE;
}
itemId1 = candies[0].getItemId();
itemId2 = candies[1].getItemId();
}
// SweetSynthesisRequest will retrieve the candies
SweetSynthesisRequest request = new SweetSynthesisRequest( itemId1, itemId2 );
RequestThread.postRequest( request );
return RuntimeLibrary.continueValue();
}
}