refactoring Character

This commit is contained in:
Denis Molony 2022-06-11 15:52:58 +10:00
parent 989b1d5ab9
commit 848b2469ae
4 changed files with 141 additions and 159 deletions

View File

@ -17,6 +17,35 @@ public abstract class Character extends AbstractFile
int scenario;
public boolean inMaze;
public int hpLeft;
public int hpMax;
public int armourClass;
public final int[] attributes = new int[6]; // 0:18
public final int[] saveVs = new int[5]; // 0:31
public int characterLevel;
public int possessionsCount;
public enum Race
{
NORACE, HUMAN, ELF, DWARF, GNOME, HOBBIT
}
public enum Alignment
{
UNALIGN, GOOD, NEUTRAL, EVIL
}
public enum CharacterStatus
{
OK, AFRAID, ASLEEP, PLYZE, STONED, DEAD, ASHES, LOST
}
public enum CharacterClass
{
FIGHTER, MAGE, PRIEST, THIEF, BISHOP, SAMURAI, LORD, NINJA
}
// ---------------------------------------------------------------------------------//
Character (String name, byte[] buffer)
// ---------------------------------------------------------------------------------//
@ -24,6 +53,23 @@ public abstract class Character extends AbstractFile
super (name, buffer);
}
// ---------------------------------------------------------------------------------//
void get3x5Bits (int[] attributes, int ptr, int value)
// ---------------------------------------------------------------------------------//
{
attributes[ptr] = value & 0x001F;
attributes[ptr + 1] = (value & 0x03E0) >>> 5;
attributes[ptr + 2] = (value & 0x7C00) >>> 10;
}
// ---------------------------------------------------------------------------------//
void get2x5Bits (int[] attributes, int ptr, int value)
// ---------------------------------------------------------------------------------//
{
attributes[ptr] = value & 0x001F;
attributes[ptr + 1] = (value & 0x03E0) >>> 5;
}
// ---------------------------------------------------------------------------------//
public String getAwardString ()
// ---------------------------------------------------------------------------------//

View File

@ -10,13 +10,22 @@ import com.bytezone.diskbrowser.utilities.Utility;
class CharacterV1 extends Character
// -----------------------------------------------------------------------------------//
{
public final int[] attributes = new int[6]; // 0:18
public final int[] saveVs = new int[5]; // 0:31
private String race;
private String type;
private String alignment;
private String status;
private final Statistics stats;
public int typeInt;
public int statusInt;
public long gold;
public int experience;
public long nextLevel;
public int ageInWeeks;
public int assetValue;
private final List<Spell> spellBook = new ArrayList<> ();
private final List<Baggage> baggageList = new ArrayList<> ();
private final List<Possession> possessions = new ArrayList<> ();
// ---------------------------------------------------------------------------------//
CharacterV1 (String name, byte[] buffer, int scenario)
@ -26,71 +35,57 @@ class CharacterV1 extends Character
this.scenario = scenario;
stats = new Statistics ();
inMaze = Utility.getShort (buffer, 32) != 0;
race = races[buffer[34] & 0xFF];
stats.race = races[buffer[34] & 0xFF];
stats.typeInt = buffer[36] & 0xFF;
stats.type = types[stats.typeInt];
stats.ageInWeeks = Utility.getShort (buffer, 38);
stats.statusValue = buffer[40];
stats.status = statuses[stats.statusValue];
stats.alignment = alignments[buffer[42] & 0xFF];
typeInt = buffer[36] & 0xFF;
type = types[typeInt];
int attr1 = Utility.getShort (buffer, 44);
int attr2 = Utility.getShort (buffer, 46);
ageInWeeks = Utility.getShort (buffer, 38);
attributes[0] = attr1 & 0x001F;
attributes[1] = (attr1 & 0x03E0) >>> 5;
attributes[2] = (attr1 & 0x7C00) >>> 10;
attributes[3] = attr2 & 0x001F;
attributes[4] = (attr2 & 0x03E0) >>> 5;
attributes[5] = (attr2 & 0x7C00) >>> 10;
statusInt = buffer[40];
status = statuses[statusInt];
stats.gold = Utility.getWizLong (buffer, 52);
stats.experience = Utility.getWizLong (buffer, 124);
stats.level = Utility.getShort (buffer, 132);
alignment = alignments[buffer[42] & 0xFF];
stats.hitsLeft = Utility.getShort (buffer, 134);
stats.hitsMax = Utility.getShort (buffer, 136);
get3x5Bits (attributes, 0, Utility.getShort (buffer, 44));
get3x5Bits (attributes, 3, Utility.getShort (buffer, 46));
get3x5Bits (saveVs, 0, Utility.getShort (buffer, 48));
get2x5Bits (saveVs, 3, Utility.getShort (buffer, 50));
stats.armourClass = buffer[176];
gold = Utility.getWizLong (buffer, 52);
// saving throws
attr1 = Utility.getShort (buffer, 48);
attr2 = Utility.getShort (buffer, 50);
possessionsCount = Utility.getShort (buffer, 58);
for (int i = 0; i < possessionsCount; i++)
{
boolean equipped = Utility.getShort (buffer, 60 + i * 8) == 1;
boolean cursed = Utility.getShort (buffer, 62 + i * 8) == 1;
boolean identified = Utility.getShort (buffer, 64 + i * 8) == 1;
saveVs[0] = attr1 & 0x001F;
saveVs[1] = (attr1 & 0x03E0) >>> 5;
saveVs[2] = (attr1 & 0x7C00) >>> 10;
saveVs[3] = attr2 & 0x001F;
saveVs[4] = (attr2 & 0x03E0) >>> 5;
int itemId = Utility.getShort (buffer, 66 + i * 8);
if (scenario == 3 && itemId >= 1000)
itemId -= 1000; // why?
possessions.add (new Possession (itemId, equipped, cursed, identified));
}
experience = Utility.getWizLong (buffer, 124);
characterLevel = Utility.getShort (buffer, 132);
hpLeft = Utility.getShort (buffer, 134);
hpMax = Utility.getShort (buffer, 136);
armourClass = buffer[176];
}
// ---------------------------------------------------------------------------------//
public void linkItems (List<ItemV1> itemList)
// ---------------------------------------------------------------------------------//
{
boolean equipped;
boolean identified;
int totItems = buffer[58];
stats.assetValue = 0;
for (int ptr = 60; totItems > 0; ptr += 8, totItems--)
for (Possession baggage : possessions)
{
int itemID = buffer[ptr + 6] & 0xFF;
if (scenario == 3)
itemID = (itemID + 24) % 256;
if (itemID >= 0 && itemID < itemList.size ())
{
ItemV1 item = itemList.get (itemID);
equipped = (buffer[ptr] == 1);
identified = (buffer[ptr + 4] == 1);
baggageList.add (new Baggage (item, equipped, identified));
stats.assetValue += item.getCost ();
}
else
System.out.println (
getName () + " ItemID : " + itemID + " is outside range 0:" + (itemList.size () - 1));
baggage.item = itemList.get (baggage.itemId);
assetValue += baggage.item.getCost ();
}
}
@ -118,20 +113,20 @@ class CharacterV1 extends Character
StringBuilder text = new StringBuilder ();
text.append ("Character name ..... " + getName ());
text.append ("\n\nRace ............... " + stats.race);
text.append ("\nType ............... " + stats.type);
text.append ("\nAlignment .......... " + stats.alignment);
text.append ("\nStatus ............. " + stats.status);
text.append ("\nGold ............... " + String.format ("%,d", stats.gold));
text.append ("\nExperience ......... " + String.format ("%,d", stats.experience));
text.append ("\nNext level ......... " + String.format ("%,d", stats.nextLevel));
text.append ("\nLevel .............. " + stats.level);
text.append ("\nAge in weeks ....... "
+ String.format ("%,d (%d)", stats.ageInWeeks, (stats.ageInWeeks / 52)));
text.append ("\nHit points left .... " + stats.hitsLeft);
text.append ("\nMaximum hits ....... " + stats.hitsMax);
text.append ("\nArmour class ....... " + stats.armourClass);
text.append ("\nAsset value ........ " + String.format ("%,d", stats.assetValue));
text.append ("\n\nRace ............... " + race);
text.append ("\nType ............... " + type);
text.append ("\nAlignment .......... " + alignment);
text.append ("\nStatus ............. " + status);
text.append ("\nGold ............... " + String.format ("%,d", gold));
text.append ("\nExperience ......... " + String.format ("%,d", experience));
text.append ("\nNext level ......... " + String.format ("%,d", nextLevel));
text.append ("\nLevel .............. " + characterLevel);
text.append (
"\nAge in weeks ....... " + String.format ("%,d (%d)", ageInWeeks, (ageInWeeks / 52)));
text.append ("\nHit points left .... " + hpLeft);
text.append ("\nMaximum hits ....... " + hpMax);
text.append ("\nArmour class ....... " + armourClass);
text.append ("\nAsset value ........ " + String.format ("%,d", assetValue));
text.append ("\nAwards ............. " + getAwardString ());
text.append ("\nOut ................ " + isOut ());
@ -158,7 +153,7 @@ class CharacterV1 extends Character
text.append ("\n" + s);
text.append ("\n\nItems :");
for (Baggage b : baggageList)
for (Possession b : possessions)
text.append ("\n" + b);
return text.toString ();
@ -168,7 +163,7 @@ class CharacterV1 extends Character
public void linkExperience (ExperienceLevel exp)
// ---------------------------------------------------------------------------------//
{
stats.nextLevel = exp.getExperiencePoints (stats.level);
nextLevel = exp.getExperiencePoints (characterLevel);
}
// ---------------------------------------------------------------------------------//
@ -199,35 +194,42 @@ class CharacterV1 extends Character
public Long getNextLevel ()
// ---------------------------------------------------------------------------------//
{
return stats.nextLevel;
return nextLevel;
}
// ---------------------------------------------------------------------------------//
public boolean isOut ()
// ---------------------------------------------------------------------------------//
{
return (buffer[32] == 1);
return inMaze;
}
// ---------------------------------------------------------------------------------//
public String getType ()
// ---------------------------------------------------------------------------------//
{
return stats.type;
return type;
}
// ---------------------------------------------------------------------------------//
public String getStatus ()
// ---------------------------------------------------------------------------------//
{
return status;
}
// ---------------------------------------------------------------------------------//
public String getRace ()
// ---------------------------------------------------------------------------------//
{
return stats.race;
return race;
}
// ---------------------------------------------------------------------------------//
public String getAlignment ()
// ---------------------------------------------------------------------------------//
{
return stats.alignment;
return alignment;
}
// ---------------------------------------------------------------------------------//
@ -238,17 +240,10 @@ class CharacterV1 extends Character
}
// ---------------------------------------------------------------------------------//
public Statistics getStatistics ()
public Iterator<Possession> getBaggage ()
// ---------------------------------------------------------------------------------//
{
return stats;
}
// ---------------------------------------------------------------------------------//
public Iterator<Baggage> getBaggage ()
// ---------------------------------------------------------------------------------//
{
return baggageList.iterator ();
return possessions.iterator ();
}
// ---------------------------------------------------------------------------------//
@ -267,18 +262,21 @@ class CharacterV1 extends Character
}
// ---------------------------------------------------------------------------------//
public class Baggage
public class Possession
// ---------------------------------------------------------------------------------//
{
public ItemV1 item;
int itemId;
public boolean cursed;
public boolean equipped;
public boolean identified;
public Baggage (ItemV1 item, boolean equipped, boolean identified)
public Possession (int itemId, boolean equipped, boolean cursed, boolean identified)
{
this.item = item;
this.itemId = itemId;
this.equipped = equipped;
this.identified = identified;
this.cursed = cursed;
}
@Override
@ -288,25 +286,4 @@ class CharacterV1 extends Character
item.getCost ());
}
}
// ---------------------------------------------------------------------------------//
public class Statistics implements Cloneable
// ---------------------------------------------------------------------------------//
{
public String race;
public String type;
public String alignment;
public String status;
public int typeInt;
public int statusValue;
public long gold;
public int experience;
public long nextLevel;
public int level;
public int ageInWeeks;
public int hitsLeft;
public int hitsMax;
public int armourClass;
public int assetValue;
}
}

View File

@ -19,32 +19,24 @@ public class CharacterV4 extends Character
int nextCharacterId;
CharacterParty party;
public final boolean inMaze;
public final Race race;
public final CharacterClass characterClass;
public final int age;
public final CharacterStatus status;
public final Alignment alignment;
public final int[] attributes = new int[6]; // 0:18
public final int[] saveVs = new int[5]; // 0:31
public final long gold;
public final int possessionsCount;
public final List<Integer> possessionIds = new ArrayList<> (MAX_POSSESSIONS);
public final List<ItemV4> possessions = new ArrayList<> (MAX_POSSESSIONS);
public final long experience;
public final int maxlevac; // max level armour class?
public final int charlev; // character level?
public final int hpLeft;
public final int hpMax;
public final boolean mysteryBit; // first bit in spellsKnown
public final boolean[] spellsKnown = new boolean[50];
public final int[][] spellAllowance = new int[2][7];
public final int hpCalCmd;
public final int armourClass;
public final int healPts;
public final boolean crithitm;
@ -57,31 +49,6 @@ public class CharacterV4 extends Character
int unknown4;
int unknown5;
public enum Race
{
NORACE, HUMAN, ELF, DWARF, GNOME, HOBBIT
}
public enum Alignment
{
UNALIGN, GOOD, NEUTRAL, EVIL
}
public enum CharacterStatus
{
OK, AFRAID, ASLEEP, PLYZE, STONED, DEAD, ASHES, LOST
}
public enum CharacterClass
{
FIGHTER, MAGE, PRIEST, THIEF, BISHOP, SAMURAI, LORD, NINJA
}
public enum Status
{
OK, AFRAID, ASLEEP, PLYZE, STONED, DEAD, ASHES, LOST
}
// ---------------------------------------------------------------------------------//
CharacterV4 (String name, byte[] buffer, int id)
// ---------------------------------------------------------------------------------//
@ -100,19 +67,12 @@ public class CharacterV4 extends Character
status = CharacterStatus.values ()[Utility.getShort (buffer, 41)];
alignment = Alignment.values ()[Utility.getShort (buffer, 43)];
int attr1 = Utility.getShort (buffer, 45);
int attr2 = Utility.getShort (buffer, 47);
attributes[0] = attr1 & 0x001F;
attributes[1] = (attr1 & 0x03E0) >>> 5;
attributes[2] = attr1 & (0x7C00) >>> 10;
attributes[3] = attr2 & 0x001F;
attributes[4] = attr2 & (0x03E0) >>> 5;
attributes[5] = attr2 & (0x7C00) >>> 10;
get3x5Bits (attributes, 0, Utility.getShort (buffer, 45));
get3x5Bits (attributes, 3, Utility.getShort (buffer, 47));
gold = 0;
unknown1 = Utility.getShort (buffer, 49); // was luck/skill (4 bytes)
unknown1 = Utility.getShort (buffer, 49); // was saveVs (4 bytes)
unknown2 = Utility.getShort (buffer, 51);
unknown3 = Utility.getShort (buffer, 53); // was gold (6 bytes)
unknown4 = Utility.getShort (buffer, 55);
@ -133,7 +93,8 @@ public class CharacterV4 extends Character
experience = 0;
nextCharacterId = Utility.getShort (buffer, 125);
maxlevac = Utility.getShort (buffer, 131);
charlev = Utility.getShort (buffer, 133);
characterLevel = Utility.getShort (buffer, 133);
hpLeft = Utility.getShort (buffer, 135);
hpMax = Utility.getShort (buffer, 137);
@ -250,7 +211,7 @@ public class CharacterV4 extends Character
text.append (String.format ("Character class ... %s%n", characterClass));
text.append (String.format ("Alignment ......... %s%n", alignment));
text.append (String.format ("Status ............ %s%n", status));
text.append (String.format ("Level ? ........... %d%n", charlev));
text.append (String.format ("Level ? ........... %d%n", characterLevel));
text.append (String.format ("Hit points ........ %d/%d%n", hpLeft, hpMax));
text.append (String.format ("Armour class ...... %d%n", armourClass));
text.append (String.format ("Attributes ........ %s%n", getAttributeString ()));

View File

@ -18,7 +18,6 @@ import com.bytezone.diskbrowser.gui.DataSource;
import com.bytezone.diskbrowser.pascal.PascalDisk;
import com.bytezone.diskbrowser.utilities.HexFormatter;
import com.bytezone.diskbrowser.utilities.Utility;
import com.bytezone.diskbrowser.wizardry.CharacterV1.Statistics;
import com.bytezone.diskbrowser.wizardry.Header.ScenarioData;
import com.bytezone.diskbrowser.wizardry.Spell.SpellType;
@ -112,7 +111,7 @@ public class WizardryScenarioDisk extends PascalDisk
{
character.linkItems (items);
character.linkSpells (spells);
int type = character.getStatistics ().typeInt;
int type = character.typeInt;
character.linkExperience (experiences.get (type));
}
@ -256,13 +255,12 @@ public class WizardryScenarioDisk extends PascalDisk
+ "-- -- -- -- -- -- -- ------\n");
for (CharacterV1 ch : characters)
{
Statistics stats = ch.getStatistics ();
int[] att = ch.getAttributes ();
text.append (String.format ("%-15s %2d %-8s %-8s %-8s %3d", ch, (stats.ageInWeeks / 52),
stats.alignment, stats.race, stats.type, stats.hitsMax));
text.append (String.format ("%-15s %2d %-8s %-8s %-8s %3d", ch, (ch.ageInWeeks / 52),
ch.getAlignment (), ch.getRace (), ch.getType (), ch.hpMax));
text.append (String.format (" %2d %2d %2d %2d %2d %2d", att[0], att[1], att[2], att[3],
att[4], att[5]));
text.append (String.format (" %5s %s%n", stats.status, ch.isOut () ? "* OUT *" : ""));
text.append (String.format (" %5s %s%n", ch.getStatus (), ch.isOut () ? "* OUT *" : ""));
}
DefaultAppleFileSource afs = (DefaultAppleFileSource) node.getUserObject ();