From 848b2469aea3dc1a9d29d6abe8d86bf4b1d9eda2 Mon Sep 17 00:00:00 2001 From: Denis Molony Date: Sat, 11 Jun 2022 15:52:58 +1000 Subject: [PATCH] refactoring Character --- .../diskbrowser/wizardry/Character.java | 46 +++++ .../diskbrowser/wizardry/CharacterV1.java | 193 ++++++++---------- .../diskbrowser/wizardry/CharacterV4.java | 51 +---- .../wizardry/WizardryScenarioDisk.java | 10 +- 4 files changed, 141 insertions(+), 159 deletions(-) diff --git a/src/com/bytezone/diskbrowser/wizardry/Character.java b/src/com/bytezone/diskbrowser/wizardry/Character.java index a37b8c2..61680bb 100644 --- a/src/com/bytezone/diskbrowser/wizardry/Character.java +++ b/src/com/bytezone/diskbrowser/wizardry/Character.java @@ -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 () // ---------------------------------------------------------------------------------// diff --git a/src/com/bytezone/diskbrowser/wizardry/CharacterV1.java b/src/com/bytezone/diskbrowser/wizardry/CharacterV1.java index 5f1bb2f..f47d807 100755 --- a/src/com/bytezone/diskbrowser/wizardry/CharacterV1.java +++ b/src/com/bytezone/diskbrowser/wizardry/CharacterV1.java @@ -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 spellBook = new ArrayList<> (); - private final List baggageList = new ArrayList<> (); + private final List 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 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 getBaggage () // ---------------------------------------------------------------------------------// { - return stats; - } - - // ---------------------------------------------------------------------------------// - public Iterator 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; - } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/wizardry/CharacterV4.java b/src/com/bytezone/diskbrowser/wizardry/CharacterV4.java index c7fdbdd..b58eba1 100644 --- a/src/com/bytezone/diskbrowser/wizardry/CharacterV4.java +++ b/src/com/bytezone/diskbrowser/wizardry/CharacterV4.java @@ -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 possessionIds = new ArrayList<> (MAX_POSSESSIONS); public final List 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 ())); diff --git a/src/com/bytezone/diskbrowser/wizardry/WizardryScenarioDisk.java b/src/com/bytezone/diskbrowser/wizardry/WizardryScenarioDisk.java index 12ec92b..b26b856 100755 --- a/src/com/bytezone/diskbrowser/wizardry/WizardryScenarioDisk.java +++ b/src/com/bytezone/diskbrowser/wizardry/WizardryScenarioDisk.java @@ -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 ();