package org.pokenet.server.battle;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;
import java.util.StringTokenizer;
import org.ini4j.Ini;
import org.ini4j.Ini.Section;
import org.pokenet.server.backend.item.DropData;
import org.pokenet.server.battle.Pokemon.ExpTypes;
import org.pokenet.server.battle.PokemonEvolution.EvolutionTypes;
import org.pokenet.server.battle.mechanics.JewelMechanics;
import org.pokenet.server.battle.mechanics.PokemonType;
import org.pokenet.server.battle.mechanics.moves.MoveList;
import org.pokenet.server.battle.mechanics.moves.MoveSetData;
import org.pokenet.server.feature.FishDatabase;
import org.simpleframework.xml.core.Persister;
/**
* Provides a data service for accessing various databases used by the server
* @author shadowkanji
*
*/
public class DataService {
private PokemonSpeciesData m_speciesData;
private static JewelMechanics m_mechanics;
private static MoveList m_moveList;
private static MoveSetData m_moveSetData;
private static FishDatabase m_fishingData;
private static ArrayList<String> m_nonTrades;
/**
* Default constructor. Loads data immediately.
*/
public DataService() {
try {
Persister stream = new Persister();
/*
* Load all of shoddy's databases
*/
m_moveList = new MoveList(true);
m_moveSetData = new MoveSetData();
m_speciesData = new PokemonSpeciesData();
m_mechanics = new JewelMechanics(5);
m_fishingData = new FishDatabase();
m_fishingData.reinitialise();
JewelMechanics.loadMoveTypes("res/movetypes.txt");
File f = new File(".");
m_moveSetData = stream.read(MoveSetData.class, new File(f.getCanonicalPath() + "/res/movesets.xml"));
initialiseSpecies();
PokemonSpecies.setDefaultData(m_speciesData);
System.out.println("INFO: Pokemon Databases loaded.");
/*
* List of non-tradeable Pokemon
*/
m_nonTrades = new ArrayList<String>();
m_nonTrades.add("Bulbasaur");
m_nonTrades.add("Ivysaur");
m_nonTrades.add("Venusaur");
m_nonTrades.add("Squirtle");
m_nonTrades.add("Wartortle");
m_nonTrades.add("Blastoise");
m_nonTrades.add("Charmander");
m_nonTrades.add("Charmeleon");
m_nonTrades.add("Charizard");
m_nonTrades.add("Chikorita");
m_nonTrades.add("Bayleef");
m_nonTrades.add("Meganium");
m_nonTrades.add("Cyndaquil");
m_nonTrades.add("Quilava");
m_nonTrades.add("Typhlosion");
m_nonTrades.add("Totodile");
m_nonTrades.add("Croconaw");
m_nonTrades.add("Feraligatr");
m_nonTrades.add("Treecko");
m_nonTrades.add("Grovyle");
m_nonTrades.add("Sceptile");
m_nonTrades.add("Torchic");
m_nonTrades.add("Combusken");
m_nonTrades.add("Blaziken");
m_nonTrades.add("Mudkip");
m_nonTrades.add("Marshtomp");
m_nonTrades.add("Swampert");
m_nonTrades.add("Turtwig");
m_nonTrades.add("Grotle");
m_nonTrades.add("Torterra");
m_nonTrades.add("Chimchar");
m_nonTrades.add("Monferno");
m_nonTrades.add("Infernape");
m_nonTrades.add("Piplup");
m_nonTrades.add("Prinplup");
m_nonTrades.add("Empoleon");
System.out.println("INFO: Trade Block List established.");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Returns true if the pokemon is tradeable
* @param pokemon
* @return
*/
public static boolean canTrade(String pokemon) {
for(int i = 0; i < m_nonTrades.size(); i++) {
if(m_nonTrades.get(i).equalsIgnoreCase(pokemon))
return false;
}
return true;
}
/**
* Initializes the species database
*/
public void initialiseSpecies() {
/* Load shoddy database */
try {
m_speciesData.loadSpeciesDatabase(new File("./res/dpspecies.db"));
} catch (Exception e1) {
e1.printStackTrace();
return;
}
Ini ini = null;
/* Load updated POLR db */
try {
ini = new Ini(new FileInputStream("./res/pokemon.ini"));
} catch (Exception e) {
e.printStackTrace();
return;
}
for (int i = 0; i < 493; i++) {
Ini.Section s = ini.get(String.valueOf(i+1));
PokemonSpecies species = null;
String name = s.get("InternalName");
if(name.equalsIgnoreCase("NIDORANfE")) {
name = "Nidoran-f";
species = m_speciesData.getPokemonByName(name);
initialisePokemon(species, s);
} else if(name.equalsIgnoreCase("NIDORANmA")) {
name = "Nidoran-m";
species = m_speciesData.getPokemonByName(name);
initialisePokemon(species, s);
} else if(name.equalsIgnoreCase("DEOXYS")) {
species = m_speciesData.getPokemonByName(name);
initialisePokemon(species, s);
species = m_speciesData.getPokemonByName("Deoxys-f");
initialisePokemon(species, s);
species = m_speciesData.getPokemonByName("Deoxys-l");
initialisePokemon(species, s);
species = m_speciesData.getPokemonByName("Deoxys-e");
initialisePokemon(species, s);
} else if(name.equalsIgnoreCase("WORMADAM")) {
species = m_speciesData.getPokemonByName(name);
initialisePokemon(species, s);
species = m_speciesData.getPokemonByName("Wormadam-g");
initialisePokemon(species, s);
species = m_speciesData.getPokemonByName("Wormadam-s");
initialisePokemon(species, s);
} else if(name.equalsIgnoreCase("Porygonz")) {
name = "Porygonz";
species = m_speciesData.getPokemonByName(name);
initialisePokemon(species, s);
} else {
name = s.get("Name");
species = m_speciesData.getPokemonByName(name);
initialisePokemon(species, s);
}
}
/* Load TM info */
try {
ini = new Ini(new FileInputStream("./res/tms.ini"));
} catch (Exception e) {
e.printStackTrace();
return;
}
Iterator<String> iterator = ini.keySet().iterator();
while(iterator.hasNext()) {
String tm = (String) iterator.next();
Ini.Section s = ini.get(tm);
String [] pokemons = s.get("POKEMON").split(",");
for(int i = 0; i < pokemons.length; i++) {
PokemonSpecies species = m_speciesData.getPokemonByName(pokemons[i]);
if(species != null) {
for(int j = 0; j < species.getTMMoves().length; j++) {
if(species.getTMMoves()[j] == null) {
species.getTMMoves()[j] = tm;
break;
}
}
}
}
}
/* We originally gave 92 possible TMs for every Pokemon, lets trim that down */
for(int i = 0; i < m_speciesData.getSpeciesCount(); i++) {
int a = 0;
PokemonSpecies s = m_speciesData.getSpecies()[i];
for(int j = 0; j < s.getTMMoves().length; j++) {
if(s.getTMMoves()[j] != null) {
a++;
} else {
break;
}
}
String [] newTMList = new String[a];
for(int j = 0; j < newTMList.length; j++) {
if(s.getTMMoves()[j] != null) {
newTMList[j] = s.getTMMoves()[j];
}
}
s.setTMMoves(newTMList);
}
/* Load Drop Data */
try {
Scanner s = new Scanner(new File("./res/itemdrops.txt"));
String pokemon = "";
while(s.hasNextLine()) {
pokemon = s.nextLine();
DropData [] drops = new DropData[10];
/* Parse the data in the form ITEM, PROBABILITY */
StringTokenizer st = new StringTokenizer(pokemon);
String pokeName = st.nextToken().toUpperCase();
if(pokeName.equalsIgnoreCase("ARCEUS")) {
drops = new DropData[17];
}
int dp = 0;
while(st.hasMoreTokens()) {
int item = Integer.parseInt(st.nextToken());
int p = Integer.parseInt(st.nextToken());
DropData d = new DropData(item, p);
if(dp < drops.length) {
drops[dp] = d;
dp++;
}
}
if(pokeName.equalsIgnoreCase("Mr.Mime")) {
pokeName = "Mr. Mime";
} else if(pokeName.equalsIgnoreCase("MIMEJR.")) {
pokeName = "Mime Jr.";
}
m_speciesData.getPokemonByName(pokeName).setDropData(drops);
}
s.close();
} catch (Exception e) {
e.printStackTrace();
return;
}
}
/**
* Initialises a pokemon from an ini section
* @param species
* @param s
*/
private void initialisePokemon(PokemonSpecies species, Section s) {
if(species != null) {
species.setInternalName(s.get("InternalName"));
species.setKind(s.get("Kind"));
species.setPokedexInfo(s.get("Pokedex"));
species.setType1(s.get("Type1"));
species.setType2(s.get("Type2"));
if (species.getType2() == null)
species.setType2("");
PokemonType [] types;
if(species.getType2() != null && !species.getType2().equalsIgnoreCase("")) {
types = new PokemonType[2];
types[0] = PokemonType.getType(species.getType1().toUpperCase());
types[1] = PokemonType.getType(species.getType2().toUpperCase());
} else {
types = new PokemonType[1];
types[0] = PokemonType.getType(species.getType1().toUpperCase());
}
species.setType(types);
String[] stringBaseStats = s.get("BaseStats").split(",");
for (int j = 0; j < stringBaseStats.length; j++)
species.getBaseStats()[j] =
Integer.parseInt(stringBaseStats[j]);
species.setRareness(Integer.parseInt(s.get("Rareness")));
species.setBaseEXP(Integer.parseInt(s.get("BaseEXP")));
species.setHappiness(Integer.parseInt(s.get("Happiness")));
species.setGrowthRate(ExpTypes.valueOf(s.get("GrowthRate").toUpperCase()));
species.setStepsToHatch(Integer.parseInt(s.get("StepsToHatch")));
species.setColor(s.get("Color"));
species.setHabitat(s.get("Habitat"));
if (species.getHabitat() == null)
species.setHabitat("");
String[] stringEffortPoints = s.get("EffortPoints").split(",");
for (int j = 0; j < stringEffortPoints.length; j++)
species.getEffortPoints()[j] =
Integer.parseInt(stringEffortPoints[j]);
String [] abilities = new String[2];
if(s.get("Abilities").contains(",")) {
String [] temp = s.get("Abilities").split(",");
abilities[0] = temp[0].trim();
abilities[1] = temp[1].trim();
} else {
abilities = new String[1];
abilities[0] = s.get("Abilities").trim();
}
species.setAbilities(abilities);
String[] stringCompatibility = s.get("Compatibility").split(",");
for (int j = 0; j < stringCompatibility.length; j++)
species.getCompatibility()[j] =
Integer.parseInt(stringCompatibility[j]);
species.setHeight(Float.parseFloat(s.get("Height")));
species.setWeight(Float.parseFloat(s.get("Weight")));
String gender = s.get("GenderRate");
if(gender.equalsIgnoreCase("Female50Percent")) {
species.setFemalePercentage(50);
species.setGenders(PokemonSpecies.GENDER_BOTH);
} else if(gender.equalsIgnoreCase("Female75Percent")) {
species.setFemalePercentage(75);
species.setGenders(PokemonSpecies.GENDER_BOTH);
} else if(gender.equalsIgnoreCase("Genderless")) {
species.setFemalePercentage(-1);
species.setGenders(PokemonSpecies.GENDER_NONE);
} else if(gender.equalsIgnoreCase("AlwaysMale")) {
species.setFemalePercentage(0);
species.setGenders(PokemonSpecies.GENDER_MALE);
} else if(gender.equalsIgnoreCase("AlwaysFemale")) {
species.setFemalePercentage(100);
species.setGenders(PokemonSpecies.GENDER_FEMALE);
} else if(gender.equalsIgnoreCase("Female25Percent")) {
species.setFemalePercentage(25);
species.setGenders(PokemonSpecies.GENDER_BOTH);
} else {
/* Female one eighth */
species.setFemalePercentage(12);
species.setGenders(PokemonSpecies.GENDER_BOTH);
}
String[] stringMoves = s.get("Moves").split(",");
species.setLevelMoves(new HashMap<Integer, String>());
String [] startMoves = new String [4];
int sp = 0;
for (int j = 0; j < stringMoves.length; j++) {
if (j % 2 == 0) {
int level = Integer.parseInt(stringMoves[j]);
String move = stringMoves[j + 1].charAt(0) +
stringMoves[j + 1].substring(1).toLowerCase();
if(move.contains(" ")) {
//Capitalise words correctly
String tmp = "";
for(int i = 1; i <= move.length(); i++) {
if(i < move.length() && move.substring(i - 1, i).compareTo(" ") == 0) {
tmp = tmp + " " + move.substring(i, i + 1).toUpperCase();
i++;
} else {
tmp = tmp + move.charAt(i - 1);
}
}
move = tmp;
}
if(level < 2) {
if(sp <= 3) {
startMoves[sp] = move;
sp++;
}
} else {
species.getLevelMoves().put(level, move);
}
}
}
species.setStarterMoves(startMoves);
species.setEggMoves(s.get("EggMoves").split(","));
String[] stringEvolutions = s.get("Evolutions").split(",");
PokemonEvolution [] evos = new PokemonEvolution[(int) Math.ceil(stringEvolutions.length / 3.0)];
int ep = 0;
for (int j = 0; j < stringEvolutions.length; j = j + 3) {
PokemonEvolution evo = new PokemonEvolution();
if(stringEvolutions[j] != null && !stringEvolutions[j].equalsIgnoreCase("")) {
evo.setEvolveTo(stringEvolutions[j]);
evo.setType(EvolutionTypes.valueOf(stringEvolutions[j + 1]));
if(evo.getType() == EvolutionTypes.Level)
evo.setLevel(Integer.parseInt(stringEvolutions[j + 2]));
else if(evo.getType() != EvolutionTypes.Happiness &&
evo.getType() != EvolutionTypes.HappinessDay &&
evo.getType() != EvolutionTypes.HappinessNight &&
evo.getType() != EvolutionTypes.Trade)
evo.setAttribute(stringEvolutions[j + 2]);
if(ep < evos.length) {
evos[ep] = evo;
}
}
}
species.setEvolutions(evos);
species.setTMMoves(new String [92]);
}
}
/**
* Returns the fish database
* @return
*/
public static FishDatabase getFishDatabase() {
return m_fishingData;
}
/**
* Returns shoddybattle battle mechanics
* @return
*/
public static JewelMechanics getBattleMechanics() {
return m_mechanics;
}
/**
* Returns the move list
* @return
*/
public static MoveList getMovesList() {
return m_moveList;
}
/**
* Returns move set data
* @return
*/
public static MoveSetData getMoveSetData() {
return m_moveSetData;
}
}