Good stuff - I found that drone Summon in the Serpent Tower last night, as I was playing through. Haven't played Bloodwych in so many years it's good to relive the old memories. And my map generator is definitely helping!
I guess that limitation on the number of teams you mention explains why you often see "couples", so they can't team up with other "couples".
I'll start posting the rest of my investigations here... a lot of this is based on your posts anyway, so probably nothing new.
ATARI ST Floor and object data -
[$0EE3C] The Keep
[$1023E] The Serpent Tower
[$11640] The Moon Tower
[$12A42] The Dragon Tower
[$13E44] The Chaos Tower
[$15246] Zendik's Tower
/*
* FLOOR DATA
($1402 total bytes per block)
[$00000] - (8 bytes) Width values of the respective Floors of the the Tower, starting with the lowest floor.
[$00008] - (8 bytes) height of each of the floors, starting with the lowest floor.
[$00010] - ($28 bytes) ?other header? not sure what this is for
[$00038] - ($FC8 bytes) Map Data
[$01000] - ($402 bytes) Object data - first 2 bytes signify amount of data used for object data
*/
Getting item stacks for a tower - assume we are parsing the $400 bytes of object data (from $01002)
where objectDataSize = the value parse from the first 2 bytes
int objOffset = 0;
ItemStacks = new List<ItemStack>();
while (objOffset < objectDataSize)
{
//what we care about here is how many bytes are used for this ItemStack
//This is a minimum of 5 bytes, with an additional 2 bytes added for each extra item in this location.
//Format: AB CD EF GH IJ .. KL MN .. OP QR .. etc..
int ef = DataObjects[objOffset + 2];
//EF = The number of items in the given location, minus 1.
int bytesToTake = (2*ef) + 5;
List<byte> bytesForThisItemStack = DataObjects.Skip(objOffset).Take(bytesToTake).ToList();
ItemStack itemStack = new ItemStack(bytesForThisItemStack);
ItemStacks.Add(itemStack);
//increment to the next ItemStack
objOffset += bytesToTake;
}
public ItemStack(List<byte> data)
{
Position = EnumPositon.None;
//this should be a new object
//This is a minimum of 5 bytes, with an additional 2 bytes added for each extra item in this location.
//Format: AB CD EF GH IJ .. KL MN .. OP QR .. etc..
int ab = data[0];
int cd = data[1];
int ef = data[2];
//A = The position of the items in the location (4 positions for a standard floor, and 2 positions for a shelf)
//00 - Position 1 - North West Space, North Facing Bottom Shelf, West Facing Top Shelf
//04 - Position 2 - North East Space, East Facing Bottom Shelf, North Facing Top Shelf
//08 - Position 3 - South West Space, West Facing Bottom Shelf, South Facing Top Shelf
//0C - Position 4 - South East Space, South Facing Bottom Shelf, East Facing Top Shelf
int a = ab >> 4;
switch(a)
{
case 0x00:
Position = EnumPositon.NorthWest;
break;
case 0x04:
Position = EnumPositon.NorthEast;
break;
case 0x08:
Position = EnumPositon.SouthWest;
break;
case 0x0C:
Position = EnumPositon.SouthEast;
break;
}
//BCD = The index number for the location.
int b = ab % 0x10;
int bcd = (b <<
+ cd;
IndexNumber = bcd;
//EF = The number of items in the given location, minus 1.
//go through each this count to extract object data
Items = new List<Item>();
for (int oi = 0; oi <= ef; oi++)
{
//lets call each pair GH IJ for simplicity
//GH - object code for the item in the location. based on the object lookup table
int gh = data[3 + (2 * oi)];
//IJ - This is the number of item GH to be "stacked" at this point.
int ij = data[4 + (2 * oi)];
Item item = new Item(gh, ij);
Items.Add(item);
}
}
and an example of a map generated for the keep is attached... as you can see I have yet to ingest the champion data, only objects and monsters.