Just wondering if anyone has any information on their structure. I wrote a basic DMap reader (took about 30 minutes, DMap/ani structure is quite simple.) and I'm trying to parse the PUL files to get the tiles for the map. It's not hard at all to get it to work if you get the offsets right, but some PUL files are half the size of the arena map (the map I worked with first) and the offsets are not absolute at all. Is there something I'm missing about calculating the offset of the tile amounts (x and y)? Of course the tile information is after them, so there's no need for those offsets to be exact.
Edit: And I know that I can calculate the number of tiles by using the tile size and coordinate width/height of the map (given a simple calculation to convert the size to isometric format), but that would still leave the offset for the tile data unknown. So I'd rather just read the data from the file the right way.
Here's an example:
As you can see, the highlighted byte (4) is the amount of tiles for the x axis, while the 4th byte to the right of it (3) is the amount of tiles for the y axis. So, 4x3 tiles, pretty simple. And the data follows immediately after that. The problem is the garbage before the tile amounts, it doesn't seem to be a consistent size, so skipping over it can be a pain. That's the only thing I need a nudge about.
Edit: Scratch that, it does seem to have some uniformity to it. Tile amount for the X axis has been at 263 for 4 maps now, and the amount for the y axis is at 267. They're both UInt16 (ushort).
Yahh it's a very simple file as already shown. Now you just need a full dmap structure as well as displaying scene objects and then converting between screen and game space based on zoom/camera location and mouse offset.
Are you planning on turning this into a map editor? Mine is basically just missing scene objects right now as well as the FULL dmap structure (just access info right now).
Yep, haven't even touched scene files yet. And thanks for the link to the EO source, I missed having it as a reference.
Quote:
Originally Posted by pro4never
Yahh it's a very simple file as already shown. Now you just need a full dmap structure as well as displaying scene objects and then converting between screen and game space based on zoom/camera location and mouse offset.
Are you planning on turning this into a map editor? Mine is basically just missing scene objects right now as well as the FULL dmap structure (just access info right now).
Hmm, possibly. I just did it to get the coordinates of certain spots in maps in real-time, but being able to make/edit maps would definitely be a plus...
Quote:
Originally Posted by unknownone
Full dmap structure for anyone who wants it.
Code:
internal enum MapObjectType
{
Scene = 0x01,
TerrainObject = 0x04,
Backdrop = 0x08,
Effect = 0x0A,
Sound = 0x0F
}
public static MapData Load(Stream file)
{
MapData dmap = new MapData() {
TerrainObjects = new List<MapTerrainObject>(),
Scenes = new List<MapScene>(),
Sounds = new List<MapSound>(),
Effects = new List<Map3DEffect>()
};
using (BinaryReader br = new BinaryReader(file))
{
string dmapheader = br.ReadASCIIString(8);
dmap.PuzzlePath = br.ReadASCIIString(260);
dmap.Bounds = br.ReadSize();
dmap.Cells = new MapCellCollection(dmap.Bounds) { CollectionSize = dmap.Bounds };
for (int j = 0 ; j < dmap.Bounds.Height ; j++) {
for (int i = 0 ; i < dmap.Bounds.Width ; i++) {
dmap.Cells[i, j] = new MapCell() {
Access = br.ReadInt16(),
Surface = br.ReadInt16(),
Height = br.ReadInt16()
};
}
dmap.Cells.OffsetArray.Add(br.ReadInt32());
}
Int32 portalcount = br.ReadInt32();
dmap.Portals = new List<MapPortal>();
for (int i = 0 ; i < portalcount ; i++) {
dmap.Portals.Add(new MapPortal() {
Location = br.ReadPoint(),
PortalType = br.ReadInt32()
});
}
Int32 objCount = br.ReadInt32();
for (int i = 0 ; i < objCount ; i++) {
MapObjectType type;
try {
type = (MapObjectType)br.ReadInt32();
}
catch (EndOfStreamException ex) {
throw ex;
}
switch (type) {
case MapObjectType.Scene:
dmap.Scenes.Add(new MapScene() {
ScenePath = br.ReadASCIIString(260),
Location = br.ReadPoint()
});
break;
case MapObjectType.TerrainObject:
dmap.TerrainObjects.Add(new MapTerrainObject() {
AniPath = br.ReadASCIIString(260),
AniName = br.ReadASCIIString(128),
Location = br.ReadPoint(),
Size = br.ReadSize(),
ImageOffset = br.ReadPoint(),
Interval = br.ReadInt32()
});
break;
case MapObjectType.Effect:
dmap.Effects.Add(new Map3DEffect() {
Effect = br.ReadASCIIString(64),
Location = br.ReadPoint()
});
break;
case MapObjectType.Sound:
dmap.Sounds.Add(new MapSound() {
SoundPath = br.ReadASCIIString(260),
Location = br.ReadPoint(),
Volume = br.ReadInt32(),
Range = br.ReadInt32()
});
break;
default:
throw new UnknownMapDataException();
}
}
Int32 nLayers = br.ReadInt32();
dmap.Layers = new List<MapLayer>(nLayers);
for (int i = 0 ; i < nLayers ; i++) {
MapLayer layer = new MapLayer() {
Backdrops = new List<MapBackdrop>(),
TerrainObjects = new List<MapTerrainObject>(),
index = br.ReadInt32(),
layertype = br.ReadInt32(),
xInt = br.ReadInt32(),
yInt = br.ReadInt32()
};
Int32 nItems = br.ReadInt32();
for (int j = 0 ; j < nItems ; j++) {
MapObjectType nType = (MapObjectType)br.ReadInt32();
switch (nType)
{
case MapObjectType.Backdrop:
layer.Backdrops.Add(new MapBackdrop() {
PuzzlePath = br.ReadASCIIString(260)
});
break;
case MapObjectType.TerrainObject:
layer.TerrainObjects.Add(new MapTerrainObject() {
AniPath = br.ReadASCIIString(260),
AniName = br.ReadASCIIString(128),
Location = br.ReadPoint(),
Size = br.ReadSize(),
ImageOffset = br.ReadPoint(),
Interval = br.ReadInt32()
});
break;
default:
throw new UnknownMapDataException();
}
}
dmap.Layers.Add(layer);
}
}
return dmap;
}
Ahh thank you, references are always great to have.
Just a few corrections on Sparkie's code for the structure.
The value that Sparkie stores is actually a checksum for that row.
Code:
for (int j = 0 ; j < dmap.Bounds.Height ; j++) {
for (int i = 0 ; i < dmap.Bounds.Width ; i++) {
dmap.Cells[i, j] = new MapCell() {
Access = br.ReadInt16(),
Surface = br.ReadInt16(),
Height = br.ReadInt16()
};
}
[B]dmap.Cells.OffsetArray.Add(br.ReadInt32());[/B]
}
So here is TQ's checksum calculation in C++.
Code:
for (int j = 0 ; j < dmap.Bounds.Height ; j++) {
for (int i = 0 ; i < dmap.Bounds.Width ; i++) {
dmap.Cells[i, j] = new MapCell() {
Access = br.ReadInt16(),
Surface = br.ReadInt16(),
Height = br.ReadInt16()
};
[B]//dwCheckData += pLayerInfo->usMask * (pLayerInfo->usTerrain+j+1) + (pLayerInfo->sAltitude+2)*(i+1+pLayerInfo->usTerrain);
}
int ActualCheckSum = br.ReadInt32();
if (RowCheckSum != ActualCheckSum)
return;[/B]
}
The value labelled PortalType, is actually the PortalsID within that map.
Code:
Int32 portalcount = br.ReadInt32();
dmap.Portals = new List<MapPortal>();
for (int i = 0 ; i < portalcount ; i++) {
dmap.Portals.Add(new MapPortal() {
Location = br.ReadPoint(),
[B]PortalType = br.ReadInt32()[/B]
});
}
This change is necessary if you want to actually use the correct method for linking up portals, so if your using an official database for example, otherwise its possible you will become confused about what values mean what with relation to the database.
Code:
Int32 portalcount = br.ReadInt32();
dmap.Portals = new List<MapPortal>();
for (int i = 0 ; i < portalcount ; i++) {
dmap.Portals.Add(new MapPortal() {
Location = br.ReadPoint(),
[B]PortalID = br.ReadInt32()[/B]
});
}
Just a few corrections on Sparkie's code for the structure.
The value that Sparkie stores is actually a checksum for that row.
Code:
for (int j = 0 ; j < dmap.Bounds.Height ; j++) {
for (int i = 0 ; i < dmap.Bounds.Width ; i++) {
dmap.Cells[i, j] = new MapCell() {
Access = br.ReadInt16(),
Surface = br.ReadInt16(),
Height = br.ReadInt16()
};
}
[B]dmap.Cells.OffsetArray.Add(br.ReadInt32());[/B]
}
So here is TQ's checksum calculation in C++.
Code:
for (int j = 0 ; j < dmap.Bounds.Height ; j++) {
for (int i = 0 ; i < dmap.Bounds.Width ; i++) {
dmap.Cells[i, j] = new MapCell() {
Access = br.ReadInt16(),
Surface = br.ReadInt16(),
Height = br.ReadInt16()
};
[B]//dwCheckData += pLayerInfo->usMask * (pLayerInfo->usTerrain+j+1) + (pLayerInfo->sAltitude+2)*(i+1+pLayerInfo->usTerrain);
}
int ActualCheckSum = br.ReadInt32();
if (RowCheckSum != ActualCheckSum)
return;[/B]
}
The value labelled PortalType, is actually the PortalsID within that map.
Code:
Int32 portalcount = br.ReadInt32();
dmap.Portals = new List<MapPortal>();
for (int i = 0 ; i < portalcount ; i++) {
dmap.Portals.Add(new MapPortal() {
Location = br.ReadPoint(),
[B]PortalType = br.ReadInt32()[/B]
});
}
This change is necessary if you want to actually use the correct method for linking up portals, so if your using an official database for example, otherwise its possible you will become confused about what values mean what with relation to the database.
Code:
Int32 portalcount = br.ReadInt32();
dmap.Portals = new List<MapPortal>();
for (int i = 0 ; i < portalcount ; i++) {
dmap.Portals.Add(new MapPortal() {
Location = br.ReadPoint(),
[B]PortalID = br.ReadInt32()[/B]
});
}
Thanks I kinda figured it had something to do with verification, didn't expect a checksum though.
There is also an implementation in my CO2_CORE_DLL which is entirely based on the one in the EO server source. But with Sparkie's implementation and Korvacs rectification, it's pretty much the full format.
There is also an implementation in my CO2_CORE_DLL which is entirely based on the one in the EO server source. But with Sparkie's implementation and Korvacs rectification, it's pretty much the full format.
Yeah, I've been considering using your DLL for some of my projects lately, as it does look to be quite useful.
[MAP][PUZZLE] Brainbuster I v1.0 (neue Action / Puzzle Map) 09/09/2011 - Minecraft - 2 Replies Brainbuster I v1.0
Hey Leute,
Achtung: Die Map ist auf Englisch, wir arbeiten allerdings momentan an einer deutschen Version.
hier mein erster Thread und erste Map, die von mir, Telithanor, und einem Kollegen, FW_Bluti, erstellt wurde. Ich wusste nicht recht, wo ich den Thread posten sollte; falls das hier falsch ist, bitte ich den Thread zu verschieben, danke ;) .
Orginial-Thread(Englisch): click
Puzzle Piraten 01/25/2011 - General Gaming Discussion - 16 Replies Bin Neu hier auf dem Board also erstmal hi an alle!
ich Suche Cheats Für das Online game Puzzle Piraten!
gibts da was?
Grüße
super123
Getting valid coordinates on dmaps using scene and puzzle files? 01/16/2011 - CO2 Private Server - 0 Replies So I've successfully gotten the dmap file to fit a specific format, although the number of invalid coordinates is too great. Apparently I need to add in the object accessibility. Any information at all on objects and their structures would be appreciated.
Puzzle Pirates 03/03/2009 - General Gaming Discussion - 3 Replies Is there a hack for puzzle pirates?
www.puzzlepirates.com
(like a dubloons hack or moneyhack?)