aboutsummaryrefslogtreecommitdiff
path: root/engines/dm/dungeonman.h
blob: f5943cd6be91b798f81a33da8bd31ceafbfaa0f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
#ifndef DUNGEONMAN_H
#define DUNGEONMAN_H

#include "dm.h"
#include "dungeonman.h"
#include "gfx.h"


namespace DM {

				
enum ArmourAttribute {
	kArmourAttributeIsAShield = 0x0080, // @ MASK0x0080_IS_A_SHIELD
	kArmourAttributeSharpDefense = 0x0007, // @ MASK0x0007_SHARP_DEFENSE
};

class ArmourInfo {
public:
	uint16 _weight;
	uint16 _defense;
private:
	uint16 _attributes;
public:
	ArmourInfo(uint16 weight, uint16 defense)
		:_weight(weight), _defense(defense) {}

	uint16 getAttribute(ArmourAttribute attribute) { return _attributes & attribute; }
	void setAttribute(ArmourAttribute attribute) { _attributes |= attribute; }
}; // @ ARMOUR_INFO

enum WeaponClass {
/* Class 0: SWING weapons */
	kWeaponClassSwingWeapon = 0, // @ C000_CLASS_SWING_WEAPON 
	/* Class 1 to 15: THROW weapons */
	kWeaponClassDaggerAndAxes = 2, // @ C002_CLASS_DAGGER_AND_AXES 
	kWeaponClassBowAmmunition = 10, // @ C010_CLASS_BOW_AMMUNITION
	kWeaponClassSlingAmmunition = 11, // @ C011_CLASS_SLING_AMMUNITION
	kWeaponClassPoisinDart = 12, // @ C012_CLASS_POISON_DART
	/* Class 16 to 111: SHOOT weapons */
	kWeaponClassFirstBow = 16, // @ C016_CLASS_FIRST_BOW 
	kWeaponClassLastBow = 31, // @ C031_CLASS_LAST_BOW
	kWeaponClassFirstSling = 32, // @ C032_CLASS_FIRST_SLING
	kWeaponClassLastSling = 47, // @ C047_CLASS_LAST_SLING
	/* Class 112 to 255: Magic and special weapons */
	kWeaponClassFirstMagicWeapon = 112 // @ C112_CLASS_FIRST_MAGIC_WEAPON
};

class WeaponInfo {

public:
        uint16 _weight;
        WeaponClass _class;
        uint16 _strength;
        uint16 _kineticEnergy;
private:
	uint16 _attributes; /* Bits 15-13 Unreferenced */
public:
        WeaponInfo(uint16 weight, WeaponClass wClass, uint16 strength, uint16 kineticEnergy, uint16 attributes)
        	: _weight(weight), _class(wClass), _strength(strength), _kineticEnergy(kineticEnergy), _attributes(attributes) {}

        uint16 getShootAttack() {return _attributes & 0xFF;} // @ M65_SHOOT_ATTACK
        uint16 getProjectileAspectOrdinal() {return (_attributes >> 8) & 0x1F;} // @ M66_PROJECTILE_ASPECT_ORDINAL
}; // @ WEAPON_INFO


int16 ordinalToIndex(int16 val); // @ M01_ORDINAL_TO_INDEX
int16 indexToOrdinal(int16 val); // @ M00_INDEX_TO_ORDINAL


enum TextType {
	/* Used for text on walls */
	kTextTypeInscription = 0, // @ C0_TEXT_TYPE_INSCRIPTION 
	/* Used for messages displayed when the party walks on a square */
	kTextTypeMessage = 1, // @ C1_TEXT_TYPE_MESSAGE 
	/* Used for text on scrolls and champion information */
	kTextTypeScroll = 2 // @ C2_TEXT_TYPE_SCROLL 
};

enum SquareAspectIndice {
	kElemAspect = 0,
	kFirstGroupOrObjectAspect = 1,
	kRightWallOrnOrdAspect = 2,
	kFrontWallOrnOrdAspect = 3,
	kLeftWallOrnOrdAspect = 4,
	kPitInvisibleAspect = 2,
	kTeleporterVisibleAspect = 2,
	kStairsUpAspect = 2,
	kDoorStateAspect = 2,
	kDoorThingIndexAspect = 3,
	kFloorOrnOrdAspect = 4,
	kFootprintsAspect = 0x8000 // @ MASK0x8000_FOOTPRINTS          
};


struct CreatureInfo {
	byte creatureAspectIndex;
	byte attackSoundOrdinal;
	uint16 attributes; /* Bits 15-14 Unreferenced */
	uint16 graphicInfo; /* Bits 11 and 6 Unreferenced */
	byte movementTicks; /* Value 255 means the creature cannot move */
	byte attackTicks; /* Minimum ticks between attacks */
	byte defense;
	byte baseHealth;
	byte attack;
	byte poisonAttack;
	byte dexterity;
	uint16 Ranges; /* Bits 7-4 Unreferenced */
	uint16 Properties;
	uint16 Resistances; /* Bits 15-12 and 3-0 Unreferenced */
	uint16 AnimationTicks; /* Bits 15-12 Unreferenced */
	uint16 WoundProbabilities; /* Contains 4 probabilities to wound a champion's Head (Bits 15-12), Legs (Bits 11-8), Torso (Bits 7-4) and Feet (Bits 3-0) */
	byte AttackType;
}; // @ CREATURE_INFO


extern CreatureInfo gCreatureInfo[kCreatureTypeCount];

class Door {
	Thing nextThing;
	uint16 attributes;
public:
	Door(uint16 *rawDat) : nextThing(rawDat[0]), attributes(rawDat[1]) {}
	Thing getNextThing() { return nextThing; }
	bool isMeleeDestructible() { return (attributes >> 8) & 1; }
	bool isMagicDestructible() { return (attributes >> 7) & 1; }
	bool hasButton() { return (attributes >> 6) & 1; }
	bool opensVertically() { return (attributes >> 5) & 1; }
	byte getOrnOrdinal() { return (attributes >> 1) & 0xF; }
	byte getType() { return attributes & 1; }
}; // @ DOOR

enum TeleporterScope {
	kTelepScopeCreatures = 1, // @ MASK0x0001_SCOPE_CREATURES
	kTelepScopeObjOrParty = 2 // @ MASK0x0002_SCOPE_OBJECTS_OR_PARTY
};


class Teleporter {
	Thing nextThing;
	uint16 attributes;
	uint16 destMapIndex;
public:
	Teleporter(uint16 *rawDat) : nextThing(rawDat[0]), attributes(rawDat[1]), destMapIndex(rawDat[2]) {}
	Thing getNextThing() { return nextThing; }
	bool makesSound() { return (attributes >> 15) & 1; }
	TeleporterScope getScope() { return (TeleporterScope)((attributes >> 13) & 1); }
	bool absRotation() { return (attributes >> 12) & 1; }
	direction getRotationDir() { return (direction)((attributes >> 10) & 1); }
	byte getDestY() { return (attributes >> 5) & 0xF; }
	byte getDestX() { return attributes & 0xF; }
	uint16 getDestMapIndex() { return destMapIndex >> 8; }
}; // @ TELEPORTER



class TextString {
	Thing nextThing;
	uint16 textDataRef;
public:
	TextString(uint16 *rawDat) : nextThing(rawDat[0]), textDataRef(rawDat[1]) {}

	Thing getNextThing() { return nextThing; }
	uint16 getWordOffset() { return textDataRef >> 3; }
	bool isVisible() { return textDataRef & 1; }
}; // @ TEXTSTRING

enum SensorActionType {
	kSensorEffNone = -1, // @ CM1_EFFECT_NONE
	kSensorEffSet = 0, // @ C00_EFFECT_SET
	kSensorEffClear = 1, // @ C01_EFFECT_CLEAR
	kSensorEffToggle = 2, // @ C02_EFFECT_TOGGLE
	kSensorEffHold = 3, // @ C03_EFFECT_HOLD
	kSensorEffAddExp = 10 // @ C10_EFFECT_ADD_EXPERIENCE
};

enum SensorType {
	kSensorDisabled = 0, // @ C000_SENSOR_DISABLED    /* Never triggered, may be used for a floor or wall ornament */
	kSensorFloorTheronPartyCreatureObj = 1, // @ C001_SENSOR_FLOOR_THERON_PARTY_CREATURE_OBJECT    /* Triggered by party/thing F0276_SENSOR_ProcessThingAdditionOrRemoval */
	kSensorFloorTheronPartyCreature = 2, // @ C002_SENSOR_FLOOR_THERON_PARTY_CREATURE    /* Triggered by party/thing F0276_SENSOR_ProcessThingAdditionOrRemoval */
	kSensorFloorParty = 3, // @ C003_SENSOR_FLOOR_PARTY    /* Triggered by party/thing F0276_SENSOR_ProcessThingAdditionOrRemoval */
	kSensorFloorObj = 4, // @ C004_SENSOR_FLOOR_OBJECT    /* Triggered by party/thing F0276_SENSOR_ProcessThingAdditionOrRemoval */
	kSensorFloorPartyOnStairs = 5, // @ C005_SENSOR_FLOOR_PARTY_ON_STAIRS    /* Triggered by party/thing F0276_SENSOR_ProcessThingAdditionOrRemoval */
	kSensorFloorGroupGenerator = 6, // @ C006_SENSOR_FLOOR_GROUP_GENERATOR    /* Triggered by event F0245_TIMELINE_ProcessEvent5_Square_Corridor */
	kSensorFloorCreature = 7, // @ C007_SENSOR_FLOOR_CREATURE    /* Triggered by party/thing F0276_SENSOR_ProcessThingAdditionOrRemoval */
	kSensorFloorPartyPossession = 8, // @ C008_SENSOR_FLOOR_PARTY_POSSESSION    /* Triggered by party/thing F0276_SENSOR_ProcessThingAdditionOrRemoval */
	kSensorFloorVersionChecker = 9, // @ C009_SENSOR_FLOOR_VERSION_CHECKER    /* Triggered by party/thing F0276_SENSOR_ProcessThingAdditionOrRemoval */
	kSensorWallOrnClick = 1, // @ C001_SENSOR_WALL_ORNAMENT_CLICK    /* Triggered by player click F0275_SENSOR_IsTriggeredByClickOnWall */
	kSensorWallOrnClickWithAnyObj = 2, // @ C002_SENSOR_WALL_ORNAMENT_CLICK_WITH_ANY_OBJECT    /* Triggered by player click F0275_SENSOR_IsTriggeredByClickOnWall */
	kSensorWallOrnClickWithSpecObj = 3, // @ C003_SENSOR_WALL_ORNAMENT_CLICK_WITH_SPECIFIC_OBJECT    /* Triggered by player click F0275_SENSOR_IsTriggeredByClickOnWall */
	kSensorWallOrnClickWithSpecObjRemoved = 4, // @ C004_SENSOR_WALL_ORNAMENT_CLICK_WITH_SPECIFIC_OBJECT_REMOVED    /* Triggered by player click F0275_SENSOR_IsTriggeredByClickOnWall */
	kSensorWallAndOrGate = 5, // @ C005_SENSOR_WALL_AND_OR_GATE    /* Triggered by event F0248_TIMELINE_ProcessEvent6_Square_Wall */
	kSensorWallCountdown = 6, // @ C006_SENSOR_WALL_COUNTDOWN    /* Triggered by event F0248_TIMELINE_ProcessEvent6_Square_Wall */
	kSensorWallSingleProjLauncherNewObj = 7, // @ C007_SENSOR_WALL_SINGLE_PROJECTILE_LAUNCHER_NEW_OBJECT    /* Triggered by event F0248_TIMELINE_ProcessEvent6_Square_Wall */
	kSensorWallSingleProjLauncherExplosion = 8, // @ C008_SENSOR_WALL_SINGLE_PROJECTILE_LAUNCHER_EXPLOSION    /* Triggered by event F0248_TIMELINE_ProcessEvent6_Square_Wall */
	kSensorWallDoubleProjLauncherNewObj = 9, // @ C009_SENSOR_WALL_DOUBLE_PROJECTILE_LAUNCHER_NEW_OBJECT    /* Triggered by event F0248_TIMELINE_ProcessEvent6_Square_Wall */
	kSensorWallDoubleProjLauncherExplosion = 10, // @ C010_SENSOR_WALL_DOUBLE_PROJECTILE_LAUNCHER_EXPLOSION    /* Triggered by event F0248_TIMELINE_ProcessEvent6_Square_Wall */
	kSensorWallOrnClickWithSpecObjRemovedRotateSensors = 11, // @ C011_SENSOR_WALL_ORNAMENT_CLICK_WITH_SPECIFIC_OBJECT_REMOVED_ROTATE_SENSORS   /* Triggered by player click F0275_SENSOR_IsTriggeredByClickOnWall */
	kSensorWallObjGeneratorRotateSensors = 12, // @ C012_SENSOR_WALL_OBJECT_GENERATOR_ROTATE_SENSORS    /* Triggered by player click F0275_SENSOR_IsTriggeredByClickOnWall */
	kSensorWallSingleObjStorageRotateSensors = 13, // @ C013_SENSOR_WALL_SINGLE_OBJECT_STORAGE_ROTATE_SENSORS    /* Triggered by player click F0275_SENSOR_IsTriggeredByClickOnWall */
	kSensorWallSingleProjLauncherSquareObj = 14, // @ C014_SENSOR_WALL_SINGLE_PROJECTILE_LAUNCHER_SQUARE_OBJECT    /* Triggered by event F0248_TIMELINE_ProcessEvent6_Square_Wall */
	kSensorWallDoubleProjLauncherSquareObj = 15, // @ C015_SENSOR_WALL_DOUBLE_PROJECTILE_LAUNCHER_SQUARE_OBJECT    /* Triggered by event F0248_TIMELINE_ProcessEvent6_Square_Wall */
	kSensorWallObjExchanger = 16, // @ C016_SENSOR_WALL_OBJECT_EXCHANGER    /* Triggered by player click F0275_SENSOR_IsTriggeredByClickOnWall */
	kSensorWallOrnClickWithSpecObjRemovedSensor = 17, // @ C017_SENSOR_WALL_ORNAMENT_CLICK_WITH_SPECIFIC_OBJECT_REMOVED_REMOVE_SENSOR    /* Triggered by player click F0275_SENSOR_IsTriggeredByClickOnWall */
	kSensorWallEndGame = 18, // @ C018_SENSOR_WALL_END_GAME    /* Triggered by event F0248_TIMELINE_ProcessEvent6_Square_Wall */
	kSensorWallChampionPortrait = 127 // @ C127_SENSOR_WALL_CHAMPION_PORTRAIT    /* Triggered by player click F0275_SENSOR_IsTriggeredByClickOnWall */
};

class Sensor {
	Thing nextThing;
	uint16 datAndType;
	uint16 attributes;
	uint16 action;
public:
	Sensor(uint16 *rawDat) : nextThing(rawDat[0]), datAndType(rawDat[1]), attributes(rawDat[2]), action(rawDat[3]) {}

	Thing getNextThing() { return nextThing; }
	SensorType getType() { return (SensorType)(datAndType & 0x7F); } // @ M39_TYPE
	uint16 getData() { return datAndType >> 7; } // @ M40_DATA
	uint16 getDataMask1() { return (datAndType >> 7) & 0xF; } // @ M42_MASK1
	uint16 getDataMask2() { return (datAndType >> 11) & 0xF; } // @ M43_MASK2
	void setData(int16 dat) { datAndType = (datAndType & 0x7F) | (dat << 7); } // @ M41_SET_DATA
	void setTypeDisabled() { datAndType &= 0xFF80; } // @ M44_SET_TYPE_DISABLED
	uint16 getOrnOrdinal() { return attributes >> 12; }
	bool isLocalAction() { return (attributes >> 11) & 1; }
	uint16 getDelay() { return (attributes >> 7) & 0xF; }
	bool hasSound() { return (attributes >> 6) & 1; }
	bool shouldRevert() { return (attributes >> 5) & 1; }
	SensorActionType getActionType() { return (SensorActionType)((attributes >> 3) & 3); }
	bool isSingleUse() { return (attributes >> 2) & 1; }
	uint16 getRemoteMapY() { return (action >> 11); }
	uint16 getRemoteMapX() { return (action >> 6) & 0x1F; }
	direction getRemoteDir() { return (direction)((action >> 4) & 3); }
	uint16 getLocalAction() { return (action >> 4); }
	// some macros missing, i got bored
}; // @ SENSOR

class Group {
	Thing nextThing;
	Thing possessionID;
	byte type;
	byte position;
	uint16 health[4];
	uint16 attributes;
public:
	Group(uint16 *rawDat) : nextThing(rawDat[0]), possessionID(rawDat[1]), type(rawDat[2]),
		position(rawDat[3]), attributes(rawDat[8]) {
		health[0] = rawDat[4];
		health[1] = rawDat[5];
		health[2] = rawDat[6];
		health[3] = rawDat[7];
	}
	Thing getNextThing() { return nextThing; }
}; // @ GROUP

class Weapon {
	Thing nextThing;
	uint16 desc;
public:
	Weapon(uint16 *rawDat) : nextThing(rawDat[0]), desc(rawDat[1]) {}

	Thing getNextThing() { return nextThing; }
}; // @ WEAPON

class Armour {
	Thing nextThing;
	uint16 attributes;
public:
	Armour(uint16 *rawDat) : nextThing(rawDat[0]), attributes(rawDat[1]) {}

	Thing getNextThing() { return nextThing; }
}; // @ ARMOUR

class Scroll {
	Thing nextThing;
	uint16 attributes;
public:
	Scroll(uint16 *rawDat) : nextThing(rawDat[0]), attributes(rawDat[1]) {}
	void set(Thing next, uint16 attribs) {
		nextThing = next;
		attributes = attribs;
	}
	Thing getNextThing() { return nextThing; }
}; // @ SCROLL

class Potion {
	Thing nextThing;
	uint16 attributes;
public:
	Potion(uint16 *rawDat) : nextThing(rawDat[0]), attributes(rawDat[1]) {}

	Thing getNextThing() { return nextThing; }
}; // @ POTION

class Container {
	Thing nextThing;
	Thing nextContainedThing;
	uint16 type;
public:
	Container(uint16 *rawDat) : nextThing(rawDat[0]), nextContainedThing(rawDat[1]), type(rawDat[2]) {}

	Thing getNextThing() { return nextThing; }
}; // @ CONTAINER

class Junk {
	Thing nextThing;
	uint16 attributes;
public:
	Junk(uint16 *rawDat) : nextThing(rawDat[0]), attributes(rawDat[1]) {}

	Thing getNextThing() { return nextThing; }
}; // @ JUNK

class Projectile {
	Thing nextThing;
	Thing object;
	byte kineticEnergy;
	byte damageEnergy;
	uint16 timerIndex;
public:
	Projectile(uint16 *rawDat) : nextThing(rawDat[0]), object(rawDat[1]), kineticEnergy(rawDat[2]),
		damageEnergy(rawDat[3]), timerIndex(rawDat[4]) {}

	Thing getNextThing() { return nextThing; }
}; // @ PROJECTILE

class Explosion {
	Thing nextThing;
	uint16 attributes;
public:
	Explosion(uint16 *rawDat) : nextThing(rawDat[0]), attributes(rawDat[1]) {}

	Thing getNextThing() { return nextThing; }
}; // @ EXPLOSION


enum SquareMask {
	kWallWestRandOrnAllowed = 0x1,
	kWallSouthRandOrnAllowed = 0x2,
	kWallEastRandOrnAllowed = 0x4,
	kWallNorthRandOrnAllowed = 0x8,
	kCorridorRandOrnAllowed = 0x8,
	kPitImaginary = 0x1,
	kPitInvisible = 0x4,
	kPitOpen = 0x8,
	kStairsUp = 0x4,
	kStairsNorthSouthOrient = 0x8,
	kDoorNorthSouthOrient = 0x8,
	kTeleporterVisible = 0x4,
	kTeleporterOpen = 0x8,
	kFakeWallImaginary = 0x1,
	kFakeWallOpen = 0x4,
	kFakeWallRandOrnOrFootPAllowed = 0x8,
	kThingListPresent = 0x10,
	kDecodeEvenIfInvisible = 0x8000
};

enum SquareType {
	kChampionElemType = -2,
	kCreatureElemType = -1,
	kWallElemType = 0,
	kCorridorElemType = 1,
	kPitElemType = 2,
	kStairsElemType = 3,
	kDoorElemType = 4,
	kTeleporterElemType = 5,
	kFakeWallElemType = 6,
	kDoorSideElemType = 16,
	kDoorFrontElemType = 17,
	kStairsSideElemType = 18,
	kStairsFrontElemType = 19
}; // @ C[-2..19]_ELEMENT_...

class Square {
	byte data;
public:
	Square(byte dat = 0) : data(dat) {}
	Square(SquareType type) { setType(type); }
	Square &set(byte dat) { this->data = dat; return *this; }
	Square &set(SquareMask mask) { data |= mask; return *this; }
	byte get(SquareMask mask) { return data & mask; }
	byte getDoorState() { return data & 0x7; } // @ M36_DOOR_STATE
	Square &setDoorState(byte state) { data = ((data & ~0x7) | state); } // @ M37_SET_DOOR_STATE
	SquareType getType() { return (SquareType)(data >> 5); } // @ M34_SQUARE_TYPE
	Square &setType(SquareType type) { data = (data & 0x1F) | type << 5; return *this; }
	byte toByte() { return data; } // I don't like 'em casts
};

struct DungeonFileHeader {
	uint16 dungeonId; // @ G0526_ui_DungeonID
	// equal to dungeonId
	uint16 ornamentRandomSeed;
	uint32 rawMapDataSize;
	uint8 mapCount;
	uint16 textDataWordCount;
	direction partyStartDir; // @ InitialPartyLocation
	uint16 partyStartPosX, partyStartPosY;
	uint16 squareFirstThingCount; // @ SquareFirstThingCount
	uint16 thingCounts[16]; // @ ThingCount[16]
}; // @ DUNGEON_HEADER

struct Map {
	uint32 rawDunDataOffset;
	uint8 offsetMapX, offsetMapY;

	uint8 level; // only used in DMII
	uint8 width, height; // !!! THESRE ARE INCLUSIVE BOUNDARIES
	// orn short for Ornament
	uint8 wallOrnCount; /* May be used in a Sensor on a Wall or closed Fake Wall square */
	uint8 randWallOrnCount; /* Used only on some Wall squares and some closed Fake Wall squares */
	uint8 floorOrnCount; /* May be used in a Sensor on a Pit, open Fake Wall, Corridor or Teleporter square */
	uint8 randFloorOrnCount; /* Used only on some Corridor squares and some open Fake Wall squares */

	uint8 doorOrnCount;
	uint8 creatureTypeCount;
	uint8 difficulty;

	FloorSet floorSet;
	WallSet wallSet;
	uint8 doorSet0, doorSet1;
}; // @ MAP

struct DungeonData {
	// I have no idea the heck is this
	uint16 *mapsFirstColumnIndex; // @ G0281_pui_DungeonMapsFirstColumnIndex
	uint16 columCount; // @ G0282_ui_DungeonColumnCount

	// I have no idea the heck is this
	uint16 *columnsCumulativeSquareThingCount; // @ G0280_pui_DungeonColumnsCumulativeSquareThingCount
	Thing *squareFirstThings; // @ G0283_pT_SquareFirstThings
	uint16 *textData; // @ G0260_pui_DungeonTextData

	uint16 **thingsData[16]; // @ G0284_apuc_ThingData

	byte ***mapData; // @ G0279_pppuc_DungeonMapData

	// TODO: ??? is this doing here
	uint16 eventMaximumCount; // @ G0369_ui_EventMaximumCount
}; // @ AGGREGATE

struct CurrMapData {
	direction partyDir; // @ G0308_i_PartyDirection
	int16 partyPosX; // @ G0306_i_PartyMapX
	int16 partyPosY; // @ G0307_i_PartyMapY
	uint8 currPartyMapIndex; // @ G0309_i_PartyMapIndex

	uint8 index; // @ G0272_i_CurrentMapIndex
	byte **data; // @ G0271_ppuc_CurrentMapData
	Map *map; // @ G0269_ps_CurrentMap
	uint16 width; // @ G0273_i_CurrentMapWidth
	uint16 height; // @ G0274_i_CurrentMapHeight
	uint16 *colCumulativeSquareFirstThingCount; // @G0270_pui_CurrentMapColumnsCumulativeSquareFirstThingCount
}; // @ AGGREGATE

struct Messages {
	bool newGame; // @ G0298_B_NewGame
	bool restartGameRequest; // @ G0523_B_RestartGameRequested
}; // @ AGGREGATE

class DungeonMan {
	DMEngine *_vm;

	DungeonMan(const DungeonMan &other); // no implementation on purpose
	void operator=(const DungeonMan &rhs); // no implementation on purpose

	Square getSquare(int16 mapX, int16 mapY); // @ F0151_DUNGEON_GetSquare
	Square getRelSquare(direction dir, int16 stepsForward, int16 stepsRight, int16 posX, int16 posY); // @ F0152_DUNGEON_GetRelativeSquare

	void decompressDungeonFile(); // @ F0455_FLOPPY_DecompressDungeon

	int16 getSquareFirstThingIndex(int16 mapX, int16 mapY); // @ F0160_DUNGEON_GetSquareFirstThingIndex
	Thing getSquareFirstThing(int16 mapX, int16 mapY); // @ F0161_DUNGEON_GetSquareFirstThing

	int16 getRandomOrnOrdinal(bool allowed, int16 count, int16 mapX, int16 mapY, int16 modulo); // @ F0170_DUNGEON_GetRandomOrnamentOrdinal
	void setSquareAspectOrnOrdinals(uint16 *aspectArray, bool leftAllowed, bool frontAllowed, bool rightAllowed, direction dir,
									int16 mapX, int16 mapY, bool isFakeWall); // @ F0171_DUNGEON_SetSquareAspectRandomWallOrnamentOrdinals


	void setCurrentMap(uint16 mapIndex); // @ F0173_DUNGEON_SetCurrentMap

	Thing getNextThing(Thing thing); // @ F0159_DUNGEON_GetNextThing(THING P0280_T_Thing)
	uint16 *getThingData(Thing thing); // @ unsigned char* F0156_DUNGEON_GetThingData(register THING P0276_T_Thing)
public:
	DungeonMan(DMEngine *dmEngine);
	~DungeonMan();
	// TODO: this does stuff other than load the file!
	void loadDungeonFile();	// @ F0434_STARTEND_IsLoadDungeonSuccessful_CPSC
	void setCurrentMapAndPartyMap(uint16 mapIndex); // @ F0174_DUNGEON_SetCurrentMapAndPartyMap

	bool isWallOrnAnAlcove(int16 wallOrnIndex); // @ F0149_DUNGEON_IsWallOrnamentAnAlcove
	void mapCoordsAfterRelMovement(direction dir, int16 stepsForward, int16 stepsRight, int16 &posX, int16 &posY); // @ F0150_DUNGEON_UpdateMapCoordinatesAfterRelativeMovement
	SquareType getRelSquareType(direction dir, int16 stepsForward, int16 stepsRight, int16 posX, int16 posY) {
		return Square(getRelSquare(dir, stepsForward, stepsRight, posX, posY)).getType();
	} // @ F0153_DUNGEON_GetRelativeSquareType
	void setSquareAspect(uint16 *aspectArray, direction dir, int16 mapX, int16 mapY); // @ F0172_DUNGEON_SetSquareAspect
	void decodeText(char *destString, Thing thing, TextType type); // F0168_DUNGEON_DecodeText

	uint32 _rawDunFileDataSize;	 // @ probably NONE
	byte *_rawDunFileData; // @ ???
	DungeonFileHeader _fileHeader; // @ G0278_ps_DungeonHeader

	DungeonData _dunData; // @ NONE
	CurrMapData _currMap; // @ NONE
	Map *_maps; // @ G0277_ps_DungeonMaps
	// does not have to be freed
	byte *_rawMapData; // @ G0276_puc_DungeonRawMapData
	Messages _messages; // @ NONE;

	int16 _currMapInscriptionWallOrnIndex; // @ G0265_i_CurrentMapInscriptionWallOrnamentIndex
	uint16 _dungeonViewClickableBoxes[6][4]; // G0291_aauc_DungeonViewClickableBoxes
	bool _isFacingAlcove; // @ G0286_B_FacingAlcove
	bool _isFacingViAltar; // @ G0287_B_FacingViAltar
	bool _isFacingFountain; // @ G0288_B_FacingFountain
};

};


#endif