/*
* 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;
}
}