/**
* 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.persistence;
import java.io.BufferedReader;
import java.io.File;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.ImageIcon;
import net.java.dev.spellcast.utilities.JComponentUtilities;
import net.sourceforge.kolmafia.FamiliarData;
import net.sourceforge.kolmafia.KoLConstants;
import net.sourceforge.kolmafia.KoLCharacter;
import net.sourceforge.kolmafia.KoLmafia;
import net.sourceforge.kolmafia.RequestLogger;
import net.sourceforge.kolmafia.StaticEntity;
import net.sourceforge.kolmafia.objectpool.FamiliarPool;
import net.sourceforge.kolmafia.objectpool.IntegerPool;
import net.sourceforge.kolmafia.utilities.BooleanArray;
import net.sourceforge.kolmafia.utilities.FileUtilities;
import net.sourceforge.kolmafia.utilities.LogStream;
import net.sourceforge.kolmafia.utilities.StringUtilities;
public class FamiliarDatabase
{
private static final Map<Integer,String> familiarById = new TreeMap<Integer,String>();
private static final Map<String,Integer> familiarByName = new TreeMap<String,Integer>();
private static final Map<Integer, String> familiarItemById = new HashMap<Integer,String>();
private static final Map<String, Integer> familiarByItem = new HashMap<String,Integer>();
private static final Map<Integer, Integer> familiarLarvaById = new HashMap<Integer,Integer>();
private static final Map<Integer, Integer> familiarByLarva = new HashMap<Integer,Integer>();
private static final Map<Integer,String> familiarImageById = new HashMap<Integer,String>();
private static final Map<String,Integer> familiarByImage = new HashMap<String,Integer>();
private static final BooleanArray volleyById = new BooleanArray();
private static final BooleanArray sombreroById = new BooleanArray();
private static final BooleanArray meatDropById = new BooleanArray();
private static final BooleanArray fairyById = new BooleanArray();
private static final BooleanArray combat0ById = new BooleanArray();
private static final BooleanArray combat1ById = new BooleanArray();
private static final BooleanArray blockById = new BooleanArray();
private static final BooleanArray delevelById = new BooleanArray();
private static final BooleanArray meat1ById = new BooleanArray();
private static final BooleanArray stat2ById = new BooleanArray();
private static final BooleanArray hp0ById = new BooleanArray();
private static final BooleanArray mp0ById = new BooleanArray();
private static final BooleanArray other0ById = new BooleanArray();
private static final BooleanArray hp1ById = new BooleanArray();
private static final BooleanArray mp1ById = new BooleanArray();
private static final BooleanArray stat3ById = new BooleanArray();
private static final BooleanArray other1ById = new BooleanArray();
private static final BooleanArray passiveById = new BooleanArray();
private static final BooleanArray dropById = new BooleanArray();
private static final BooleanArray underwaterById = new BooleanArray();
private static final BooleanArray noneById = new BooleanArray();
private static final BooleanArray variableById = new BooleanArray();
private static final Map<String,Integer>[] eventSkillByName = new HashMap[ 4 ];
public static boolean newFamiliars = false;
public static int maxFamiliarId = 0;
static
{
FamiliarDatabase.newFamiliars = false;
for ( int i = 0; i < 4; ++i )
{
FamiliarDatabase.eventSkillByName[ i ] = new HashMap<String,Integer>();
}
// This begins by opening up the data file and preparing
// a buffered reader; once this is done, every line is
// examined and float-referenced: once in the name-lookup,
// and again in the Id lookup.
BufferedReader reader = FileUtilities.getVersionedReader( "familiars.txt", KoLConstants.FAMILIARS_VERSION );
String[] data;
while ( ( data = FileUtilities.readData( reader ) ) != null )
{
if ( data.length != 10 )
{
continue;
}
try
{
int id = StringUtilities.parseInt( data[ 0 ] );
if ( id > FamiliarDatabase.maxFamiliarId )
{
FamiliarDatabase.maxFamiliarId = id;
}
Integer familiarId = IntegerPool.get( id );
String familiarName = new String( data[ 1 ] );
String familiarImage = new String( data[ 2 ] );
String familiarType = new String( data[ 3 ] );
String familiarLarvaName = new String( data[ 4 ] );
Integer familiarLarva = Integer.valueOf( ItemDatabase.getItemId( familiarLarvaName ) );
String familiarItemName = new String( data[ 5 ] );
FamiliarDatabase.familiarById.put( familiarId, StringUtilities.getDisplayName( familiarName ) );
FamiliarDatabase.familiarByName.put( StringUtilities.getCanonicalName( familiarName ), familiarId );
FamiliarDatabase.familiarImageById.put( familiarId, familiarImage );
FamiliarDatabase.familiarByImage.put( familiarImage, familiarId );
// Kludge: Happy Medium has 4 different images
if ( id == FamiliarPool.HAPPY_MEDIUM )
{
FamiliarDatabase.familiarByImage.put( "medium_1.gif", familiarId );
FamiliarDatabase.familiarByImage.put( "medium_2.gif", familiarId );
FamiliarDatabase.familiarByImage.put( "medium_3.gif", familiarId );
}
FamiliarDatabase.familiarLarvaById.put( familiarId, familiarLarva );
FamiliarDatabase.familiarByLarva.put( familiarLarva, familiarId );
FamiliarDatabase.familiarItemById.put( familiarId, familiarItemName );
FamiliarDatabase.familiarByItem.put( familiarItemName, familiarId );
FamiliarDatabase.volleyById.set( familiarId.intValue(), familiarType.contains( "stat0" ) );
FamiliarDatabase.sombreroById.set( familiarId.intValue(), familiarType.contains( "stat1" ) );
FamiliarDatabase.fairyById.set( familiarId.intValue(), familiarType.contains( "item0" ) );
FamiliarDatabase.meatDropById.set( familiarId.intValue(), familiarType.contains( "meat0" ) );
// The following are "combat" abilities
FamiliarDatabase.combat0ById.set( familiarId.intValue(), familiarType.contains( "combat0" ) );
FamiliarDatabase.combat1ById.set( familiarId.intValue(), familiarType.contains( "combat1" ) );
FamiliarDatabase.blockById.set( familiarId.intValue(), familiarType.contains( "block" ) );
FamiliarDatabase.delevelById.set( familiarId.intValue(), familiarType.contains( "delevel" ) );
FamiliarDatabase.hp0ById.set( familiarId.intValue(), familiarType.contains( "hp0" ) );
FamiliarDatabase.mp0ById.set( familiarId.intValue(), familiarType.contains( "mp0" ) );
FamiliarDatabase.meat1ById.set( familiarId.intValue(), familiarType.contains( "meat1" ) );
FamiliarDatabase.stat2ById.set( familiarId.intValue(), familiarType.contains( "stat2" ) );
FamiliarDatabase.other0ById.set( familiarId.intValue(), familiarType.contains( "other0" ) );
// The following are "after combat" abilities
FamiliarDatabase.hp1ById.set( familiarId.intValue(), familiarType.contains( "hp1" ) );
FamiliarDatabase.mp1ById.set( familiarId.intValue(), familiarType.contains( "mp1" ) );
FamiliarDatabase.stat3ById.set( familiarId.intValue(), familiarType.contains( "stat3" ) );
FamiliarDatabase.other1ById.set( familiarId.intValue(), familiarType.contains( "other1" ) );
// The following are other abilities that deserve their own category
FamiliarDatabase.passiveById.set( familiarId.intValue(), familiarType.contains( "passive" ) );
FamiliarDatabase.dropById.set( familiarId.intValue(), familiarType.contains( "drop" ) );
FamiliarDatabase.underwaterById.set( familiarId.intValue(), familiarType.contains( "underwater" ) );
FamiliarDatabase.noneById.set( familiarId.intValue(), familiarType.contains( "none" ) );
FamiliarDatabase.variableById.set( familiarId.intValue(), familiarType.contains( "variable" ) );
String canonical = StringUtilities.getCanonicalName( data[ 1 ] );
for ( int i = 0; i < 4; ++i )
{
FamiliarDatabase.eventSkillByName[ i ].put( canonical, Integer.valueOf( data[ i + 6 ] ) );
}
}
catch ( Exception e )
{
// This should not happen. Therefore, print
// a stack trace for debug purposes.
StaticEntity.printStackTrace( e );
}
}
try
{
reader.close();
}
catch ( Exception e )
{
// This should not happen. Therefore, print
// a stack trace for debug purposes.
StaticEntity.printStackTrace( e );
}
}
/**
* Temporarily adds a familiar to the familiar database. This is used
* whenever KoLmafia encounters an unknown familiar on login
*/
private static final Integer ZERO = IntegerPool.get( 0 );
public static final void registerFamiliar( final int familiarId, final String familiarName, final String image )
{
FamiliarDatabase.registerFamiliar( familiarId, familiarName, image, FamiliarDatabase.ZERO );
}
// Hatches into:</b><br><table cellpadding=5 style='border: 1px solid black;'><tr><td align=center><a class=nounder href=desc_familiar.php?which=154><img border=0 src=http://images.kingdomofloathing.com/itemimages/groose.gif width=30 height=30><br><b>Bloovian Groose</b></a></td></tr></table>
private static final Pattern FAMILIAR_PATTERN = Pattern.compile( "Hatches into:.*?<table.*?which=(\\d*).*?itemimages/(.*?) .*?<b>(.*?)</b>");
public static final void registerFamiliar( final Integer larvaId, final String text )
{
Matcher matcher = FAMILIAR_PATTERN.matcher( text );
if ( matcher.find() )
{
int familiarId = StringUtilities.parseInt( matcher.group( 1 ) );
String image = matcher.group( 2 );
String familiarName = matcher.group( 3 );
FamiliarDatabase.registerFamiliar( familiarId, familiarName, image, larvaId );
}
}
public static final void registerFamiliar( final int familiarId, final String familiarName, final String image, final Integer larvaId )
{
String canon = StringUtilities.getCanonicalName( familiarName );
if ( FamiliarDatabase.familiarByName.containsKey( canon ) )
{
return;
}
RequestLogger.printLine( "New familiar: \"" + familiarName + "\" (" + familiarId + ") @ " + image );
if ( familiarId > FamiliarDatabase.maxFamiliarId )
{
FamiliarDatabase.maxFamiliarId = familiarId;
}
Integer dummyId = IntegerPool.get( familiarId );
FamiliarDatabase.familiarById.put( dummyId, familiarName );
FamiliarDatabase.familiarByName.put( canon, dummyId );
FamiliarDatabase.familiarImageById.put( dummyId, image );
FamiliarDatabase.familiarByImage.put( image, dummyId );
FamiliarDatabase.familiarLarvaById.put( dummyId, larvaId );
FamiliarDatabase.familiarByLarva.put( larvaId, dummyId );
FamiliarDatabase.familiarItemById.put( dummyId, "" );
for ( int i = 0; i < 4; ++i )
{
FamiliarDatabase.eventSkillByName[ i ].put( canon, FamiliarDatabase.ZERO );
}
FamiliarDatabase.newFamiliars = true;
}
/**
* Returns the name for an familiar, given its Id.
*
* @param familiarId The Id of the familiar to lookup
* @return The name of the corresponding familiar
*/
public static final String getFamiliarName( final int familiarId )
{
return FamiliarDatabase.getFamiliarName( IntegerPool.get( familiarId ) );
}
public static final String getFamiliarName( final Integer familiarId )
{
return (String) FamiliarDatabase.familiarById.get( familiarId );
}
/**
* Returns the Id number for an familiar, given its larval stage.
*
* @param larvaId The larva stage of the familiar to lookup
* @return The Id number of the corresponding familiar
*/
public static final FamiliarData growFamiliarLarva( final int larvaId )
{
Integer familiarId = FamiliarDatabase.familiarByLarva.get( IntegerPool.get( larvaId ) );
return familiarId == null ? null : new FamiliarData( familiarId.intValue() );
}
/**
* Returns the Id number for an familiar, given its name.
*
* @param substring The name of the familiar to lookup
* @return The Id number of the corresponding familiar
*/
public static final int getFamiliarId( final String substring )
{
String searchString = substring.toLowerCase();
Object familiarId = FamiliarDatabase.familiarByName.get( searchString );
if ( familiarId != null )
{
return ( (Integer) familiarId ).intValue();
}
String[] familiarNames = new String[ FamiliarDatabase.familiarByName.size() ];
FamiliarDatabase.familiarByName.keySet().toArray( familiarNames );
for ( int i = 0; i < familiarNames.length; ++i )
{
if ( familiarNames[ i ].indexOf( searchString ) != -1 )
{
familiarId = FamiliarDatabase.familiarByName.get( familiarNames[ i ] );
return familiarId == null ? -1 : ( (Integer) familiarId ).intValue();
}
}
return -1;
}
public static final boolean isVolleyType( final int familiarId )
{
return FamiliarDatabase.volleyById.get( familiarId );
}
public static final boolean isSombreroType( final int familiarId )
{
return FamiliarDatabase.sombreroById.get( familiarId );
}
public static final boolean isFairyType( final int familiarId )
{
return FamiliarDatabase.fairyById.get( familiarId );
}
public static final boolean isMeatDropType( final int familiarId )
{
return FamiliarDatabase.meatDropById.get( familiarId );
}
public static final boolean isCombatType( final int familiarId )
{
return FamiliarDatabase.combat0ById.get( familiarId ) ||
FamiliarDatabase.combat1ById.get( familiarId ) ||
FamiliarDatabase.blockById.get( familiarId ) ||
FamiliarDatabase.delevelById.get( familiarId ) ||
FamiliarDatabase.hp0ById.get( familiarId ) ||
FamiliarDatabase.mp0ById.get( familiarId ) ||
FamiliarDatabase.other0ById.get( familiarId );
}
public static final boolean isCombat0Type( final int familiarId )
{
return FamiliarDatabase.combat0ById.get( familiarId );
}
public static final boolean isCombat1Type( final int familiarId )
{
return FamiliarDatabase.combat1ById.get( familiarId );
}
public static final boolean isDropType( final int familiarId )
{
return FamiliarDatabase.dropById.get( familiarId );
}
public static final boolean isBlockType( final int familiarId )
{
return FamiliarDatabase.blockById.get( familiarId );
}
public static final boolean isDelevelType( final int familiarId )
{
return FamiliarDatabase.delevelById.get( familiarId );
}
public static final boolean isHp0Type( final int familiarId )
{
return FamiliarDatabase.hp0ById.get( familiarId );
}
public static final boolean isMp0Type( final int familiarId )
{
return FamiliarDatabase.mp0ById.get( familiarId );
}
public static final boolean isMeat1Type( final int familiarId )
{
return FamiliarDatabase.meat1ById.get( familiarId );
}
public static final boolean isStat2Type( final int familiarId )
{
return FamiliarDatabase.stat2ById.get( familiarId );
}
public static final boolean isOther0Type( final int familiarId )
{
return FamiliarDatabase.other0ById.get( familiarId );
}
public static final boolean isHp1Type( final int familiarId )
{
return FamiliarDatabase.hp1ById.get( familiarId );
}
public static final boolean isMp1Type( final int familiarId )
{
return FamiliarDatabase.mp1ById.get( familiarId );
}
public static final boolean isStat3Type( final int familiarId )
{
return FamiliarDatabase.stat3ById.get( familiarId );
}
public static final boolean isNoneType( final int familiarId )
{
return FamiliarDatabase.noneById.get( familiarId );
}
public static final boolean isOther1Type( final int familiarId )
{
return FamiliarDatabase.other1ById.get( familiarId );
}
public static final boolean isPassiveType( final int familiarId )
{
return FamiliarDatabase.passiveById.get( familiarId );
}
public static final boolean isUnderwaterType( final int familiarId )
{
return FamiliarDatabase.underwaterById.get( familiarId );
}
public static final boolean isVariableType( final int familiarId )
{
return FamiliarDatabase.variableById.get( familiarId );
}
public static final String getFamiliarItem( final int familiarId )
{
return FamiliarDatabase.getFamiliarItem( IntegerPool.get( familiarId ) );
}
public static final String getFamiliarItem( final Integer familiarId )
{
return FamiliarDatabase.familiarItemById.get( familiarId );
}
public static final int getFamiliarItemId( final int familiarId )
{
return FamiliarDatabase.getFamiliarItemId( IntegerPool.get( familiarId ) );
}
public static final int getFamiliarItemId( final Integer familiarId )
{
String name = FamiliarDatabase.getFamiliarItem( familiarId );
return name == null ? -1 : ItemDatabase.getItemId( name );
}
public static final int getFamiliarByItem( final String item )
{
Integer familiarId = FamiliarDatabase.familiarByItem.get( StringUtilities.getCanonicalName( item ) );
return familiarId == null ? -1 : familiarId.intValue();
}
public static final int getFamiliarLarva( final int familiarId )
{
return FamiliarDatabase.getFamiliarLarva( IntegerPool.get( familiarId ) );
}
public static final int getFamiliarLarva( final Integer familiarId )
{
Integer id = FamiliarDatabase.familiarLarvaById.get( familiarId );
return id == null ? 0 : id.intValue();
}
public static final String getFamiliarType( final int familiarId )
{
StringBuilder buffer = new StringBuilder();
String sep = "";
// Base types: Leprechaun, Fairy, Volleyball, Sombrero
if ( FamiliarDatabase.meatDropById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "meat0" );
}
if ( FamiliarDatabase.fairyById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "item0" );
}
if ( FamiliarDatabase.volleyById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "stat0" );
}
if ( FamiliarDatabase.sombreroById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "stat1" );
}
// Combat abilities
if ( FamiliarDatabase.combat0ById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "combat0" );
}
if ( FamiliarDatabase.combat1ById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "combat1" );
}
if ( FamiliarDatabase.blockById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "block" );
}
if ( FamiliarDatabase.delevelById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "delevel" );
}
if ( FamiliarDatabase.hp0ById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "hp0" );
}
if ( FamiliarDatabase.mp0ById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "mp0" );
}
if ( FamiliarDatabase.other0ById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "other0" );
}
if ( FamiliarDatabase.meat1ById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "meat1" );
}
if ( FamiliarDatabase.stat2ById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "stat2" );
}
// After Combat abilities
if ( FamiliarDatabase.hp1ById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "hp1" );
}
if ( FamiliarDatabase.mp1ById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "mp1" );
}
if ( FamiliarDatabase.other1ById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "other1" );
}
if ( FamiliarDatabase.passiveById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "passive" );
}
if ( FamiliarDatabase.underwaterById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "underwater" );
}
if ( FamiliarDatabase.variableById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "variable" );
}
// Special items
if ( FamiliarDatabase.dropById.get( familiarId ) )
{
buffer.append( sep );
sep = ",";
buffer.append( "drop" );
}
if ( sep.equals( "" ) )
{
buffer.append( "none" );
}
return buffer.toString();
}
public static final void setFamiliarImageLocation( final int familiarId, final String location )
{
FamiliarDatabase.familiarImageById.put( IntegerPool.get( familiarId ), location );
}
public static final String getFamiliarImageLocation( final int familiarId )
{
String location = (String) FamiliarDatabase.familiarImageById.get( IntegerPool.get( familiarId ) );
return ( location != null ) ? location : "debug.gif";
}
public static final int getFamiliarByImageLocation( final String image )
{
Object familiarId = FamiliarDatabase.familiarByImage.get( image );
return familiarId == null ? -1 : ( (Integer) familiarId ).intValue();
}
private static final ImageIcon getFamiliarIcon( final String location )
{
if ( location == null || location.equals( "debug.gif" ) )
{
return FamiliarDatabase.getNoFamiliarImage();
}
String url = KoLmafia.imageServerPath() + "itemimages/" + location;
File file = FileUtilities.downloadImage( url );
if ( file == null )
{
return FamiliarDatabase.getNoFamiliarImage();
}
ImageIcon icon = JComponentUtilities.getImage( "itemimages/" + location );
return icon != null ? icon : FamiliarDatabase.getNoFamiliarImage();
}
public static final ImageIcon getNoFamiliarImage()
{
return JComponentUtilities.getImage( "debug.gif" );
}
public static final ImageIcon getFamiliarImage( final String name )
{
return FamiliarDatabase.getFamiliarImage( FamiliarDatabase.getFamiliarId( name ) );
}
public static final ImageIcon getFamiliarImage( final int familiarId )
{
String location = FamiliarDatabase.getFamiliarImageLocation( familiarId );
return FamiliarDatabase.getFamiliarIcon( location );
}
public static final ImageIcon getCurrentFamiliarImage()
{
String location = KoLCharacter.getFamiliarImage();
return FamiliarDatabase.getFamiliarIcon( location );
}
/**
* Returns whether or not an item with a given name exists in the database; this is useful in the event that an item
* is encountered which is not tradeable (and hence, should not be displayed).
*
* @return <code>true</code> if the item is in the database
*/
public static final boolean contains( final String familiarName )
{
return FamiliarDatabase.familiarByName.containsKey( StringUtilities.getCanonicalName( familiarName ) );
}
public static final Integer getFamiliarSkill( final String name, final int event )
{
return (Integer) FamiliarDatabase.eventSkillByName[ event - 1 ].get( StringUtilities.getCanonicalName( name ) );
}
public static final int[] getFamiliarSkills( final int id )
{
return FamiliarDatabase.getFamiliarSkills( IntegerPool.get( id ) );
}
public static final int[] getFamiliarSkills( final Integer id )
{
String name = StringUtilities.getCanonicalName( FamiliarDatabase.getFamiliarName( id ) );
int skills[] = new int[ 4 ];
for ( int i = 0; i < 4; ++i )
{
skills[ i ] = ( (Integer) FamiliarDatabase.eventSkillByName[ i ].get( name ) ).intValue();
}
return skills;
}
public static final void setFamiliarSkills( final String name, final int[] skills )
{
String canon = StringUtilities.getCanonicalName( name );
for ( int i = 0; i < 4; ++i )
{
FamiliarDatabase.eventSkillByName[ i ].put( canon, IntegerPool.get( skills[ i ] ) );
}
FamiliarDatabase.newFamiliars = true;
FamiliarDatabase.saveDataOverride();
}
/**
* Returns the set of familiars keyed by name
*
* @return The set of familiars keyed by name
*/
public static final Set entrySet()
{
return FamiliarDatabase.familiarById.entrySet();
}
public static final void saveDataOverride()
{
FamiliarDatabase.writeFamiliars( new File( KoLConstants.DATA_LOCATION, "familiars.txt" ) );
FamiliarDatabase.newFamiliars = false;
}
public static void writeFamiliars( final File output )
{
RequestLogger.printLine( "Writing data override: " + output );
PrintStream writer = LogStream.openStream( output, true );
writer.println( KoLConstants.FAMILIARS_VERSION );
writer.println( "# Original familiar arena stats from Vladjimir's arena data" );
writer.println( "# http://www.therye.org/familiars/" );
writer.println();
writer.println( "# no. name image type larva item CM SH OC H&S" );
writer.println();
Integer[] familiarIds = new Integer[ FamiliarDatabase.familiarById.size() ];
FamiliarDatabase.familiarById.keySet().toArray( familiarIds );
int lastInteger = 1;
for ( int i = 0; i < familiarIds.length; ++i )
{
Integer nextInteger = familiarIds[ i ];
int familiarId = nextInteger.intValue();
for ( int j = lastInteger; j < familiarId; ++j )
{
writer.println( j );
}
lastInteger = familiarId + 1;
String name = FamiliarDatabase.getFamiliarName( nextInteger );
String image = FamiliarDatabase.getFamiliarImageLocation( familiarId );
String type = FamiliarDatabase.getFamiliarType( familiarId );
int larvaId = FamiliarDatabase.getFamiliarLarva( nextInteger ) ;
int itemId = FamiliarDatabase.getFamiliarItemId( nextInteger );
int[] skills = FamiliarDatabase.getFamiliarSkills( nextInteger );
FamiliarDatabase.writeFamiliar( writer, familiarId, name, image, type, larvaId, itemId, skills );
}
}
public static void writeFamiliar( final PrintStream writer,
final int familiarId, final String name, final String image,
final String type, final int larvaId, final int itemId, final int [] skills )
{
writer.println( FamiliarDatabase.familiarString( familiarId, name, image, type, larvaId, itemId, skills ) );
}
public static String familiarString( final int familiarId, final String name, final String image,
final String type, final int larvaId, final int itemId, final int [] skills )
{
String larva = larvaId == -1 ? "" : ItemDatabase.getItemDataName( larvaId );
String item = itemId == -1 ? "" : ItemDatabase.getItemDataName( itemId );
return familiarId + "\t" +
name + "\t" +
image + "\t" +
type + "\t" +
larva + "\t" +
item + "\t" +
skills[0] + "\t" +
skills[1] + "\t" +
skills[2] + "\t" +
skills[3];
}
}