/* * UFO Saved Game Editor * Copyright (C) 2010 Christopher Davoren * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package net.rubikscomplex.ufosge.data; import java.io.EOFException; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import net.rubikscomplex.ufosge.util.UFOInputStream; import net.rubikscomplex.ufosge.util.UFOOutputStream; /** * * @author Chris Davoren */ public class Soldier { public static final short RANK_DEAD = -1; public static final short RANK_ROOKIE = 0; public static final short RANK_SQUADDIE = 1; public static final short RANK_SERGEANT = 2; public static final short RANK_CAPTAIN = 3; public static final short RANK_COLONEL = 4; public static final short RANK_COMMANDER = 5; public static final short ARMOR_NONE = 0; public static final short ARMOR_PERSONAL = 1; public static final short ARMOR_POWER = 2; public static final short ARMOR_FLYING = 3; public static final short GENDER_MALE = 0; public static final short GENDER_FEMALE = 1; public static final short APPEARANCE_BLONDE = 0; public static final short APPEARANCE_BROWN = 1; public static final short APPEARANCE_ORIENTAL = 2; public static final short APPEARANCE_AFRICAN = 3; public static final short HOST_BASE_TRANSFERRING = -1; public static final short ASSIGNED_CRAFT_NONE = -1; public static final int NAME_LEN = 25; // This soldier's position in SOLDIER.DAT public int index; public short rank; public short hostBase; public short assignedCraft; public short previousCraft; public short missionsCompleted; public short kills; public short recoveryDaysLeft; public short victoryValue; public String name; public short transferDestination; public short timeUnits; public short health; public short energy; public short reactions; public short strength; public short firingAccuracy; public short throwingAccuracy; public short meleeAccuracy; public short psionicStrength; public short psionicSkill; public short bravery; public short timeUnitsImp; public short healthImp; public short energyImp; public short reactionsImp; public short strengthImp; public short firingAccuracyImp; public short throwingAccuracyImp; public short meleeAccuracyImp; public short braveryImp; public short armor; public short psiTrainingIncrease; public boolean inPsiTraining; public boolean promoted; public short gender; public short appearance; public Soldier() { } public static String rankToString(short rank) { switch(rank) { case RANK_DEAD: return "Dead"; case RANK_ROOKIE: return "Rookie"; case RANK_SQUADDIE: return "Squaddie"; case RANK_SERGEANT: return "Sergeant"; case RANK_CAPTAIN: return "Captain"; case RANK_COLONEL: return "Colonel"; case RANK_COMMANDER: return "Commander"; default: return "Unknown"; } } public static String rankToAbbrString(short rank) { switch(rank) { case RANK_DEAD: return "DED"; case RANK_ROOKIE: return "RKE"; case RANK_SQUADDIE: return "SQD"; case RANK_SERGEANT: return "SGT"; case RANK_CAPTAIN: return "CPT"; case RANK_COLONEL: return "COL"; case RANK_COMMANDER: return "CDR"; default: return "UKN"; } } public static short stringToRank(String str) { if (str.equalsIgnoreCase("Dead")) { return RANK_DEAD; } else if (str.equalsIgnoreCase("Rookie")) { return RANK_ROOKIE; } else if (str.equalsIgnoreCase("Sergeant")) { return RANK_SERGEANT; } else if (str.equalsIgnoreCase("Captain")) { return RANK_CAPTAIN; } else if (str.equalsIgnoreCase("Colonel")) { return RANK_COLONEL; } else if (str.equalsIgnoreCase("Commander")) { return RANK_COMMANDER; } else { return RANK_DEAD; } } public static Map<Short, String> getRankMap() { HashMap<Short, String> map = new HashMap<Short, String>(); map.put(RANK_DEAD, rankToString(RANK_DEAD)); map.put(RANK_ROOKIE, rankToString(RANK_ROOKIE)); map.put(RANK_SERGEANT, rankToString(RANK_SERGEANT)); map.put(RANK_CAPTAIN, rankToString(RANK_CAPTAIN)); map.put(RANK_COLONEL, rankToString(RANK_COLONEL)); map.put(RANK_COMMANDER, rankToString(RANK_COMMANDER)); return map; } public static String armorToString(short armor) { switch(armor) { case ARMOR_NONE: return "None"; case ARMOR_PERSONAL: return "Personal Armor"; case ARMOR_POWER: return "Power Suit"; case ARMOR_FLYING: return "Flying Suit"; default: return "Unknown"; } } public static short stringToArmor(String armorName) { if (armorName.equalsIgnoreCase("None")) { return ARMOR_NONE; } else if (armorName.equalsIgnoreCase("Personal Armor")) { return ARMOR_PERSONAL; } else if (armorName.equalsIgnoreCase("Power Suit")) { return ARMOR_POWER; } else if (armorName.equalsIgnoreCase("Flying Suit")) { return ARMOR_FLYING; } else { return ARMOR_NONE; } } public static Map<Short, String> getArmorMap() { HashMap<Short, String> map = new HashMap<Short, String>(); map.put(ARMOR_NONE, armorToString(ARMOR_NONE)); map.put(ARMOR_PERSONAL, armorToString(ARMOR_PERSONAL)); map.put(ARMOR_POWER, armorToString(ARMOR_POWER)); map.put(ARMOR_FLYING, armorToString(ARMOR_FLYING)); return map; } public static String genderToString(short gender) { switch(gender) { case GENDER_MALE: return "Male"; case GENDER_FEMALE: return "Female"; default: return "Unknown"; } } public static short stringToGender(String str) { if (str.equalsIgnoreCase("MALE")) { return GENDER_MALE; } else if (str.equalsIgnoreCase("Female")) { return GENDER_FEMALE; } else { return GENDER_MALE; } } public static Map<Short, String> getGenderMap() { HashMap<Short, String> map = new HashMap<Short, String>(); map.put(GENDER_MALE, genderToString(GENDER_MALE)); map.put(GENDER_FEMALE, genderToString(GENDER_FEMALE)); return map; } public static String appearanceToString(short appearance) { switch(appearance) { case APPEARANCE_BLONDE: return "Blonde Hair"; case APPEARANCE_BROWN: return "Brown Hair"; case APPEARANCE_ORIENTAL: return "Oriental"; case APPEARANCE_AFRICAN: return "African"; default: return "Unknown"; } } public static short stringToAppearance(String str) { if (str.equalsIgnoreCase("Blonde Hair")) { return APPEARANCE_BLONDE; } else if(str.equalsIgnoreCase("Brown Hair")) { return APPEARANCE_BROWN; } else if (str.equalsIgnoreCase("Oriental")) { return APPEARANCE_ORIENTAL; } else if (str.equalsIgnoreCase("African")) { return APPEARANCE_AFRICAN; } else { return APPEARANCE_BLONDE; } } public static Map<Short, String> getAppearanceMap() { HashMap<Short, String> map = new HashMap<Short, String>(); map.put(APPEARANCE_BLONDE, appearanceToString(APPEARANCE_BLONDE)); map.put(APPEARANCE_BROWN, appearanceToString(APPEARANCE_BROWN)); map.put(APPEARANCE_ORIENTAL, appearanceToString(APPEARANCE_ORIENTAL)); map.put(APPEARANCE_AFRICAN, appearanceToString(APPEARANCE_AFRICAN)); return map; } public boolean readFromFile(UFOInputStream stream, int index) throws IOException { try { rank = stream.readUFOShort(); hostBase = stream.readUFOShort(); assignedCraft = stream.readUFOShort(); previousCraft = stream.readUFOShort(); missionsCompleted = stream.readUFOShort(); kills = stream.readUFOShort(); recoveryDaysLeft = stream.readUFOShort(); victoryValue = stream.readUFOShort(); name = stream.readUFOString(NAME_LEN); transferDestination = stream.readUFOByte(); timeUnits = stream.readUFOByte(); health = stream.readUFOByte(); energy = stream.readUFOByte(); reactions = stream.readUFOByte(); strength = stream.readUFOByte(); firingAccuracy = stream.readUFOByte(); throwingAccuracy = stream.readUFOByte(); meleeAccuracy = stream.readUFOByte(); psionicStrength = stream.readUFOByte(); psionicSkill = stream.readUFOByte(); bravery = stream.readUFOByte(); timeUnitsImp = stream.readUFOByte(); healthImp = stream.readUFOByte(); energyImp = stream.readUFOByte(); reactionsImp = stream.readUFOByte(); strengthImp = stream.readUFOByte(); firingAccuracyImp = stream.readUFOByte(); throwingAccuracyImp = stream.readUFOByte(); meleeAccuracyImp = stream.readUFOByte(); braveryImp = stream.readUFOByte(); armor = stream.readUFOByte(); psiTrainingIncrease = stream.readUFOByte(); inPsiTraining = stream.readUFOByte() == 1; promoted = stream.readUFOByte() == 1; gender = stream.readUFOByte(); appearance = stream.readUFOByte(); this.index = index; return true; } catch (EOFException e) { return false; } } public void writeToFile(UFOOutputStream out) throws IOException { out.writeUFOShort(rank); out.writeUFOShort(hostBase); out.writeUFOShort(assignedCraft); out.writeUFOShort(previousCraft); out.writeUFOShort(missionsCompleted); out.writeUFOShort(kills); out.writeUFOShort(recoveryDaysLeft); out.writeUFOShort(victoryValue); out.writeUFOString(name, NAME_LEN); out.writeUFOByte(transferDestination); out.writeUFOByte(timeUnits); out.writeUFOByte(health); out.writeUFOByte(energy); out.writeUFOByte(reactions); out.writeUFOByte(strength); out.writeUFOByte(firingAccuracy); out.writeUFOByte(throwingAccuracy); out.writeUFOByte(meleeAccuracy); out.writeUFOByte(psionicStrength); out.writeUFOByte(psionicSkill); out.writeUFOByte(bravery); out.writeUFOByte(timeUnitsImp); out.writeUFOByte(healthImp); out.writeUFOByte(energyImp); out.writeUFOByte(reactionsImp); out.writeUFOByte(strengthImp); out.writeUFOByte(firingAccuracyImp); out.writeUFOByte(throwingAccuracyImp); out.writeUFOByte(meleeAccuracyImp); out.writeUFOByte(braveryImp); out.writeUFOByte(armor); out.writeUFOByte(psiTrainingIncrease); out.writeByte(inPsiTraining ? 1 : 0); out.writeByte(promoted ? 1 : 0); out.writeUFOByte(gender); out.writeUFOByte(appearance); } public static ArrayList<Soldier> readList(UFOInputStream in) throws IOException { ArrayList<Soldier> list = new ArrayList<Soldier>(); while (true) { Soldier soldier = new Soldier(); if (soldier.readFromFile(in, list.size())) { list.add(soldier); } else { break; } } return list; } public static void writeList(UFOOutputStream out, ArrayList<Soldier> list) throws IOException { Iterator<Soldier> si = list.iterator(); while(si.hasNext()) { si.next().writeToFile(out); } } public boolean isUsed() { return rank != RANK_DEAD || name.length() > 0; } }