diff --git a/resources/werdna.png b/resources/werdna.png new file mode 100644 index 0000000..de22c2c Binary files /dev/null and b/resources/werdna.png differ diff --git a/src/com/bytezone/diskbrowser/wizardry/Monster.java b/src/com/bytezone/diskbrowser/wizardry/Monster.java index a404628..eb0a818 100755 --- a/src/com/bytezone/diskbrowser/wizardry/Monster.java +++ b/src/com/bytezone/diskbrowser/wizardry/Monster.java @@ -6,11 +6,14 @@ import java.util.List; import com.bytezone.diskbrowser.applefile.AbstractFile; import com.bytezone.diskbrowser.utilities.HexFormatter; +import com.bytezone.diskbrowser.utilities.Utility; // -----------------------------------------------------------------------------------// class Monster extends AbstractFile // -----------------------------------------------------------------------------------// { + int scenarioId; + public final String genericName; public final String realName; public final int monsterID; @@ -19,10 +22,8 @@ class Monster extends AbstractFile Reward goldReward; Reward chestReward; - public final int type; - public final int imageID; - int rewardTable1; - int rewardTable2; + final int type; + final int imageID; public final int partnerID; public final int partnerOdds; @@ -31,6 +32,7 @@ class Monster extends AbstractFile public final int mageSpellLevel; public final int priestSpellLevel; + int experiencePoints; int levelDrain; int healPts; int breathe; @@ -38,6 +40,7 @@ class Monster extends AbstractFile int unique; int resistance; int abilities; + public final Dice groupSize, hitPoints; List damage = new ArrayList<> (); @@ -46,6 +49,7 @@ class Monster extends AbstractFile public static String[] monsterClass = { "Fighter", "Mage", "Priest", "Thief", "Midget", "Giant", "Mythical", "Dragon", "Animal", "Were", "Undead", "Demon", "Insect", "Enchanted" }; + // Scenario #1 values private static int[] experience = { // 55, 235, 415, 230, 380, 620, 840, 520, 550, 350, // 00-09 475, 515, 920, 600, 735, 520, 795, 780, 990, 795, // 10-19 @@ -61,21 +65,18 @@ class Monster extends AbstractFile }; // ---------------------------------------------------------------------------------// - Monster (String name, byte[] buffer, List rewards, List monsters) + Monster (String name, byte[] buffer, List rewards, List monsters, int scenarioId) // ---------------------------------------------------------------------------------// { super (name, buffer); + this.scenarioId = scenarioId; + realName = name; genericName = HexFormatter.getPascalString (buffer, 0); this.monsterID = counter++; this.monsters = monsters; - goldReward = rewards.get (buffer[136]); - chestReward = rewards.get (buffer[138]); - goldReward.addMonster (this, 0); - chestReward.addMonster (this, 1); - imageID = buffer[64]; groupSize = new Dice (buffer, 66); hitPoints = new Dice (buffer, 72); @@ -83,17 +84,18 @@ class Monster extends AbstractFile armourClass = buffer[80]; recsn = buffer[82]; // number of dice - for (int i = 0, ptr = 84; i < 8; i++, ptr += 6) + for (int i = 0, ptr = 84; i < 7; i++, ptr += 6) { if (buffer[ptr] == 0) break; damage.add (new Dice (buffer, ptr)); } + experiencePoints = Utility.readTriple (buffer, 126); levelDrain = buffer[132]; healPts = buffer[134]; - rewardTable1 = buffer[136]; - rewardTable2 = buffer[138]; + goldReward = rewards.get (buffer[136]); + chestReward = rewards.get (buffer[138]); partnerID = buffer[140]; partnerOdds = buffer[142]; mageSpellLevel = buffer[144]; @@ -105,6 +107,9 @@ class Monster extends AbstractFile resistance = buffer[154]; // bit flags abilities = buffer[156]; // bit flags + + goldReward.addMonster (this, 0); + chestReward.addMonster (this, 1); } // ---------------------------------------------------------------------------------// @@ -114,7 +119,7 @@ class Monster extends AbstractFile { StringBuilder text = new StringBuilder (); - int totalExperience = getExperience (); + int totalExperience = scenarioId == 1 ? getExperience () : experiencePoints; text.append ("ID .............. " + monsterID); text.append ("\nMonster name .... " + realName); @@ -151,10 +156,10 @@ class Monster extends AbstractFile text.append (String.format ("%n%nExperience ...... %-,7d", totalExperience)); - text.append ("\n\n===== Gold reward ======"); + text.append (String.format ("%n%n===== Gold reward %2d ======", goldReward.id)); // text.append ("\nTable ........... " + rewardTable1); text.append ("\n" + goldReward.getText (false)); - text.append ("===== Chest reward ====="); + text.append (String.format ("===== Chest reward %2d =====", chestReward.id)); // text.append ("\nTable ........... " + rewardTable2); text.append ("\n" + chestReward.getText (false)); @@ -179,8 +184,8 @@ class Monster extends AbstractFile int expDamage = recsn <= 1 ? 0 : getBonus (30, recsn); int expUnaffect = unaffect == 0 ? 0 : getBonus (40, (unaffect / 10 + 1)); - int expFlags1 = getBonus (35, Integer.bitCount (resistance & 0x7E)); - int expFlags2 = getBonus (40, Integer.bitCount (abilities & 0x7F)); + int expFlags1 = getBonus (35, Integer.bitCount (resistance & 0x7E)); // 6 bits + int expFlags2 = getBonus (40, Integer.bitCount (abilities & 0x7F)); // 7 bits return expHitPoints + expAc + expMage + expPriest + expDrain + expHeal + expDamage + expUnaffect + expFlags1 + expFlags2; @@ -196,11 +201,16 @@ class Monster extends AbstractFile int total = base; while (multiplier > 1) { + int part = total % 10000; // get the last 4 digits + multiplier--; - total += total; // double the value + total += total; // double the value + + if (part >= 5000) // mimics the wizardry bug + total += 10000; // yay, free points } - return total + total / 10000 * 10000; // mimics the Wizardry bug + return total; } // ---------------------------------------------------------------------------------// @@ -234,8 +244,11 @@ class Monster extends AbstractFile for (Dice d : damage) text.append (d + ", "); - text.deleteCharAt (text.length () - 1); - text.deleteCharAt (text.length () - 1); + if (text.length () > 0) + { + text.deleteCharAt (text.length () - 1); + text.deleteCharAt (text.length () - 1); + } return text.toString (); } @@ -254,7 +267,7 @@ class Monster extends AbstractFile for (int i = lo; i < hi; i++) line.append (String.format ("%02X ", buffer[i])); - if (block == 3) + if (block == 3 && scenarioId == 1) { int exp = getExperience (); line.append (String.format (" %,6d %,6d", exp, exp - experience[monsterID])); diff --git a/src/com/bytezone/diskbrowser/wizardry/WizLong.java b/src/com/bytezone/diskbrowser/wizardry/WizLong.java index 80d4dfb..757f350 100644 --- a/src/com/bytezone/diskbrowser/wizardry/WizLong.java +++ b/src/com/bytezone/diskbrowser/wizardry/WizLong.java @@ -165,7 +165,9 @@ public class WizLong return high > other.high ? 1 : -1; } + // ---------------------------------------------------------------------------------// public int value () + // ---------------------------------------------------------------------------------// { return high * 10000 * 10000 + mid * 10000 + low; } @@ -229,7 +231,7 @@ public class WizLong int heal = 0; int breathe = 0; int unaffect = 85; - int wepsty = 0x40; + int wepsty = 64; int sppc = 0; // Werdna @@ -243,8 +245,8 @@ public class WizLong // int heal = 5; // int breathe = 0; // int unaffect = 70; - // int wepsty = 0x0E; - // int sppc = 0x0F; + // int wepsty = 14; + // int sppc = 15; // Will O Wisp // int hpSides = 10; @@ -272,6 +274,7 @@ public class WizLong multAddKX (killExp, priestSpells, 35); multAddKX (killExp, drain, 200); multAddKX (killExp, heal, 90); + killExp.printLong (); killExpx = new WizLong (40 * (11 - ac)); @@ -280,16 +283,41 @@ public class WizLong if (recsn > 1) multAddKX (killExp, recsn, 30); + killExp.printLong (); if (unaffect > 0) multAddKX (killExp, (unaffect / 10 + 1), 40); + killExp.printLong (); multAddKX (killExp, Integer.bitCount (wepsty & 0x7E), 35); // 6 bits - // System.out.println (Integer.bitCount (wepsty)); multAddKX (killExp, Integer.bitCount (sppc & 0x7F), 40); // 7 bits killExp.printLong (); + + System.out.println (); + + WizLong a = new WizLong (1000); + a.multLong (54); + a.printLong (); + a.addLong (a); + a.printLong (); + + System.out.println (); + + a = new WizLong (1000); + a.multLong (500); + a.printLong (); + a.addLong (a); + a.printLong (); + + System.out.println (); + + a = new WizLong (1000); + a.multLong (505); + a.printLong (); + a.addLong (a); + a.printLong (); } } diff --git a/src/com/bytezone/diskbrowser/wizardry/WizardryScenarioDisk.java b/src/com/bytezone/diskbrowser/wizardry/WizardryScenarioDisk.java index 0191461..45281ca 100755 --- a/src/com/bytezone/diskbrowser/wizardry/WizardryScenarioDisk.java +++ b/src/com/bytezone/diskbrowser/wizardry/WizardryScenarioDisk.java @@ -277,9 +277,10 @@ public class WizardryScenarioDisk extends PascalDisk { int nameLength = buffer[ptr] & 0xFF; if (nameLength == 0xC3) - continue; + return; + String name = HexFormatter.getString (buffer, ptr + 1, nameLength); - if ("UNSET".equals (name) && buffer[ptr + 40] == 0x07) // 7 = LOST + if (name.isEmpty () || ("UNSET".equals (name) && buffer[ptr + 40] == 0x07)) // 7 = LOST continue; byte[] data2 = new byte[recLen]; @@ -341,7 +342,7 @@ public class WizardryScenarioDisk extends PascalDisk byte[] data2 = new byte[recLen]; System.arraycopy (buffer, ptr, data2, 0, recLen); - Monster m = new Monster (itemName, data2, rewards, monsters); + Monster m = new Monster (itemName, data2, rewards, monsters, scenarioHeader.scenarioID); monsters.add (m); addToNode (m, node, blocks, monsterSector); }