mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2024-09-29 07:55:13 +00:00
216 lines
5.7 KiB
Java
216 lines
5.7 KiB
Java
|
package com.bytezone.diskbrowser.wizardry;
|
||
|
|
||
|
import java.awt.Dimension;
|
||
|
import java.awt.Graphics2D;
|
||
|
import java.awt.RenderingHints;
|
||
|
import java.awt.image.BufferedImage;
|
||
|
import java.util.List;
|
||
|
|
||
|
import com.bytezone.diskbrowser.HexFormatter;
|
||
|
import com.bytezone.diskbrowser.applefile.AbstractFile;
|
||
|
|
||
|
class MazeLevel extends AbstractFile
|
||
|
{
|
||
|
public int level;
|
||
|
private List<Message> messages;
|
||
|
private List<Monster> monsters;
|
||
|
private List<Item> items;
|
||
|
|
||
|
public MazeLevel (byte[] buffer, int level)
|
||
|
{
|
||
|
super ("Level " + level, buffer);
|
||
|
this.level = level;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public BufferedImage getImage ()
|
||
|
{
|
||
|
Dimension cellSize = new Dimension (22, 22);
|
||
|
image =
|
||
|
new BufferedImage (20 * cellSize.width + 1, 20 * cellSize.height + 1,
|
||
|
BufferedImage.TYPE_USHORT_555_RGB);
|
||
|
Graphics2D g = image.createGraphics ();
|
||
|
g.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||
|
|
||
|
for (int row = 0; row < 20; row++)
|
||
|
for (int column = 0; column < 20; column++)
|
||
|
{
|
||
|
MazeCell cell = getLocation ((row) % 20, (column) % 20);
|
||
|
int x = column * cellSize.width;
|
||
|
int y = image.getHeight () - (row + 1) * cellSize.height - 1;
|
||
|
cell.draw (g, x, y);
|
||
|
}
|
||
|
return image;
|
||
|
}
|
||
|
|
||
|
public void setMessages (List<Message> messages)
|
||
|
{
|
||
|
this.messages = messages;
|
||
|
}
|
||
|
|
||
|
public void setMonsters (List<Monster> monsters)
|
||
|
{
|
||
|
this.monsters = monsters;
|
||
|
}
|
||
|
|
||
|
public void setItems (List<Item> items)
|
||
|
{
|
||
|
this.items = items;
|
||
|
}
|
||
|
|
||
|
public MazeCell getLocation (int row, int column)
|
||
|
{
|
||
|
MazeAddress address = new MazeAddress (level, row, column);
|
||
|
MazeCell cell = new MazeCell (address);
|
||
|
|
||
|
// doors and walls
|
||
|
|
||
|
int offset = column * 6 + row / 4; // 6 bytes/column
|
||
|
|
||
|
int value = HexFormatter.intValue (buffer[offset]);
|
||
|
value >>>= (row % 4) * 2;
|
||
|
cell.westWall = ((value & 1) == 1);
|
||
|
value >>>= 1;
|
||
|
cell.westDoor = ((value & 1) == 1);
|
||
|
|
||
|
value = HexFormatter.intValue (buffer[offset + 120]);
|
||
|
value >>>= (row % 4) * 2;
|
||
|
cell.southWall = ((value & 1) == 1);
|
||
|
value >>>= 1;
|
||
|
cell.southDoor = ((value & 1) == 1);
|
||
|
|
||
|
value = HexFormatter.intValue (buffer[offset + 240]);
|
||
|
value >>>= (row % 4) * 2;
|
||
|
cell.eastWall = ((value & 1) == 1);
|
||
|
value >>>= 1;
|
||
|
cell.eastDoor = ((value & 1) == 1);
|
||
|
|
||
|
value = HexFormatter.intValue (buffer[offset + 360]);
|
||
|
value >>>= (row % 4) * 2;
|
||
|
cell.northWall = ((value & 1) == 1);
|
||
|
value >>>= 1;
|
||
|
cell.northDoor = ((value & 1) == 1);
|
||
|
|
||
|
// monster table
|
||
|
|
||
|
offset = column * 4 + row / 8; // 4 bytes/column, 1 bit/row
|
||
|
value = HexFormatter.intValue (buffer[offset + 480]);
|
||
|
value >>>= row % 8;
|
||
|
cell.monsterLair = ((value & 1) == 1);
|
||
|
|
||
|
// stairs, pits, darkness etc.
|
||
|
|
||
|
offset = column * 10 + row / 2; // 10 bytes/column, 4 bits/row
|
||
|
value = HexFormatter.intValue (buffer[offset + 560]);
|
||
|
int b = (row % 2 == 0) ? value % 16 : value / 16;
|
||
|
int c = HexFormatter.intValue (buffer[760 + b / 2]);
|
||
|
int d = (b % 2 == 0) ? c % 16 : c / 16;
|
||
|
|
||
|
switch (d)
|
||
|
{
|
||
|
case 1:
|
||
|
cell.stairs = true;
|
||
|
cell.addressTo = getAddress (b);
|
||
|
break;
|
||
|
case 2:
|
||
|
cell.pit = true;
|
||
|
break;
|
||
|
case 3:
|
||
|
cell.chute = true;
|
||
|
cell.addressTo = getAddress (b);
|
||
|
break;
|
||
|
case 4:
|
||
|
cell.spinner = true;
|
||
|
break;
|
||
|
case 5:
|
||
|
cell.darkness = true;
|
||
|
break;
|
||
|
case 6:
|
||
|
cell.teleport = true;
|
||
|
cell.addressTo = getAddress (b);
|
||
|
break;
|
||
|
case 8:
|
||
|
cell.elevator = true;
|
||
|
cell.elevatorTo = HexFormatter.intValue (buffer[800 + b * 2], buffer[801 + b * 2]);
|
||
|
cell.elevatorFrom = HexFormatter.intValue (buffer[832 + b * 2], buffer[833 + b * 2]);
|
||
|
break;
|
||
|
case 9:
|
||
|
cell.rock = true;
|
||
|
break;
|
||
|
case 10:
|
||
|
cell.spellsBlocked = true;
|
||
|
break;
|
||
|
case 11:
|
||
|
int messageNum = HexFormatter.intValue (buffer[800 + b * 2], buffer[801 + b * 2]);
|
||
|
for (Message m : messages)
|
||
|
if (m.match (messageNum))
|
||
|
{
|
||
|
cell.message = m;
|
||
|
break;
|
||
|
}
|
||
|
if (cell.message == null)
|
||
|
System.out.println ("message not found : " + messageNum);
|
||
|
cell.messageType = HexFormatter.intValue (buffer[832 + b * 2], buffer[833 + b * 2]);
|
||
|
|
||
|
int itemID = -1;
|
||
|
|
||
|
if (cell.messageType == 2) // obtain Item
|
||
|
{
|
||
|
itemID = HexFormatter.intValue (buffer[768 + b * 2], buffer[769 + b * 2]);
|
||
|
cell.itemObtained = items.get (itemID);
|
||
|
}
|
||
|
if (cell.messageType == 5) // requires Item
|
||
|
{
|
||
|
itemID = HexFormatter.intValue (buffer[768 + b * 2], buffer[769 + b * 2]);
|
||
|
cell.itemRequired = items.get (itemID);
|
||
|
}
|
||
|
if (cell.messageType == 4)
|
||
|
{
|
||
|
value = HexFormatter.intValue (buffer[768 + b * 2], buffer[769 + b * 2]);
|
||
|
if (value <= 100)
|
||
|
{
|
||
|
cell.monsterID = value;
|
||
|
cell.monsters = monsters;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
int val = (value - 64536) * -1;
|
||
|
System.out.println ("Value : " + val);
|
||
|
// this gives Index error: 20410, Size 104 in Wizardry_III/legacy2.dsk
|
||
|
if (val < items.size ())
|
||
|
cell.itemObtained = items.get (val); // check this
|
||
|
if (cell.itemObtained == null)
|
||
|
System.out.printf ("Item %d not found%n", val);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case 12:
|
||
|
cell.monsterID = HexFormatter.intValue (buffer[832 + b * 2], buffer[833 + b * 2]);
|
||
|
cell.monsters = monsters;
|
||
|
break;
|
||
|
default:
|
||
|
cell.unknown = d;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return cell;
|
||
|
}
|
||
|
|
||
|
private MazeAddress getAddress (int a)
|
||
|
{
|
||
|
int b = a * 2;
|
||
|
return new MazeAddress (HexFormatter.intValue (buffer[768 + b], buffer[769 + b]), HexFormatter
|
||
|
.intValue (buffer[800 + b], buffer[801 + b]), HexFormatter.intValue (buffer[832 + b],
|
||
|
buffer[833 + b]));
|
||
|
}
|
||
|
|
||
|
public int getRows ()
|
||
|
{
|
||
|
return 20;
|
||
|
}
|
||
|
|
||
|
public int getColumns ()
|
||
|
{
|
||
|
return 20;
|
||
|
}
|
||
|
}
|