2 std/typetraits, std/macros, std/tables,
3 ../serialization, ../utils, ../gfx,
7 MapDirection* {.size: sizeof(uint8).} = enum
10 dirUnspecified = "DIR_SOMETHING2" # ???
12 MapKey* {.size: sizeof(uint8), bitsetNullValue: "KEY_NONE".} = enum
14 keyGreen = "KEY_GREEN"
16 keyRedTeam = "KEY_REDTEAM"
17 keyBlueTeam = "KEY_BLUETEAM"
19 MapSpawnEffect* {.size: sizeof(uint8).} = enum
20 effNone = "EFFECT_NONE"
21 effTeleport = "EFFECT_TELEPORT"
22 effRespawn = "EFFECT_RESPAWN"
23 effFire = "EFFECT_FIRE"
25 MapHitType* {.size: sizeof(uint8).} = enum
27 hitRocket = "HIT_ROCKET"
31 hitWater = "HIT_WATER"
33 hitElectro = "HIT_ELECTRO"
34 hitFlame = "HIT_FLAME"
36 hitDiscon = "HIT_DISCON"
38 MapObject* = ref object of Serializable
40 MapSpecialTexture* {.size: sizeof(int32).} = enum
41 texSpecialNone = (-4, "TEXTURE_SPECIAL_NONE")
42 texSpecialAcid2 = (-3, "TEXTURE_SPECIAL_ACID2")
43 texSpecialAcid1 = (-2, "TEXTURE_SPECIAL_ACID1")
44 texSpecialWater = (-1, "TEXTURE_SPECIAL_WATER")
46 MapTexture* = ref object of Serializable
47 path* {.writeDefault, resPath, maxSize: 64.}: string
48 animated* {.nonEditable.}: bool
49 # editor-specific fields
50 id* {.serializeNever, nonEditable, invisible.}: uint16
51 tex* {.serializeNever, nonEditable, invisible.}: Texture
53 # this is defined as if it was a bitfield, but it actually isn't
54 MapPanelType* {.size: sizeof(uint16).} = enum
55 panNone = (0, "PANEL_NONE")
56 panWall = (1, "PANEL_WALL")
57 panBack = (2, "PANEL_BACK")
58 panFore = (4, "PANEL_FORE")
59 panWater = (8, "PANEL_WATER")
60 panAcid1 = (16, "PANEL_ACID1")
61 panAcid2 = (32, "PANEL_ACID2")
62 panStep = (64, "PANEL_STEP")
63 panLiftUp = (128, "PANEL_LIFTUP")
64 panLiftDown = (256, "PANEL_LIFTDOWN")
65 panOpenDoor = (512, "PANEL_OPENDOOR")
66 panClosedDoor = (1024, "PANEL_CLOSEDOOR")
67 panBlockMon = (2048, "PANEL_BLOCKMON")
68 panLiftLeft = (4096, "PANEL_LIFTLEFT")
69 panLiftRight = (8192, "PANEL_LIFTRIGHT")
71 MapPanelFlags* {.size: sizeof(uint8), bitsetNullValue: "PANEL_FLAG_NONE".} = enum
72 pfBlending = "PANEL_FLAG_BLENDING"
73 pfHide = "PANEL_FLAG_HIDE"
74 pfWaterTexture = "PANEL_FLAG_WATERTEXTURES"
76 MapPanel* = ref object of MapObject
77 position* {.writeDefault.}: DFPoint
78 size* {.writeDefault.}: DFSize
79 texture* {.writeDefault.}: MapTexture
80 kind* {.writeDefault.}: MapPanelType
82 flags*: set[MapPanelFlags]
83 moveSpeed* {.serializeTextOnly.}: DFPoint
84 sizeSpeed* {.serializeTextOnly.}: DFPoint
85 moveStart* {.serializeTextOnly.}: DFPoint
86 moveEnd* {.serializeTextOnly.}: DFPoint
87 sizeEnd* {.serializeTextOnly.}: DFSize
88 moveActive* {.serializeTextOnly.}: bool
89 moveOnce* {.serializeTextOnly.}: bool
90 endPosTrigger* {.serializeTextOnly.}: MapTrigger
91 endSizeTrigger* {.serializeTextOnly.}: MapTrigger
92 # editor-specific fields
93 id* {.serializeNever, nonEditable, invisible.}: int32
95 MapItemType* {.size: sizeof(uint8).} = enum
96 itemNone = "ITEM_NONE"
97 itemMedkitSmall = "ITEM_MEDKIT_SMALL"
98 itemMedkitLarge = "ITEM_MEDKIT_LARGE"
99 itemMedkitBlack = "ITEM_MEDKIT_BLACK"
100 itemArmorGreen = "ITEM_ARMOR_GREEN"
101 itemArmorBlue = "ITEM_ARMOR_BLUE"
102 itemSphereBlue = "ITEM_SPHERE_BLUE"
103 itemSphereWhite = "ITEM_SPHERE_WHITE"
104 itemSuit = "ITEM_SUIT"
105 itemOxygen = "ITEM_OXYGEN"
106 itemInvul = "ITEM_INVUL"
107 itemWeaponSaw = "ITEM_WEAPON_SAW"
108 itemWeaponShotgun1 = "ITEM_WEAPON_SHOTGUN"
109 itemWeaponShotgun2 = "ITEM_WEAPON_SHOTGUN2"
110 itemWeaponChaingun = "ITEM_WEAPON_CHAINGUN"
111 itemWeaponRocketLauncher = "ITEM_WEAPON_ROCKETLAUNCHER"
112 itemWeaponPlasma = "ITEM_WEAPON_PLASMA"
113 itemWeaponBfg = "ITEM_WEAPON_BFG"
114 itemWeaponSuperChaingun = "ITEM_WEAPON_SUPERPULEMET"
115 itemAmmoBullets = "ITEM_AMMO_BULLETS"
116 itemAmmoBulletsBox = "ITEM_AMMO_BULLETS_BOX"
117 itemAmmoShells = "ITEM_AMMO_SHELLS"
118 itemAmmoShellsBox = "ITEM_AMMO_SHELLS_BOX"
119 itemAmmoRocket = "ITEM_AMMO_ROCKET"
120 itemAmmoRocketBox = "ITEM_AMMO_ROCKET_BOX"
121 itemAmmoCell = "ITEM_AMMO_CELL"
122 itemAmmoCellBig = "ITEM_AMMO_CELL_BIG"
123 itemAmmoBackpack = "ITEM_AMMO_BACKPACK"
124 itemKeyRed = "ITEM_KEY_RED"
125 itemKeyGreen = "ITEM_KEY_GREEN"
126 itemKeyBlue = "ITEM_KEY_BLUE"
127 itemWeaponFist = "ITEM_WEAPON_KASTET"
128 itemWeaponPistol = "ITEM_WEAPON_PISTOL"
129 itemHealthBonus = "ITEM_BOTTLE"
130 itemArmorBonus = "ITEM_HELMET"
131 itemJetpack = "ITEM_JETPACK"
132 itemInvis = "ITEM_INVIS"
133 itemWeaponFlamethrower = "ITEM_WEAPON_FLAMETHROWER"
134 itemAmmoFuelCan = "ITEM_AMMO_FUELCAN"
136 MapItemFlags* {.size: sizeof(uint8), bitsetNullValue: "ITEM_OPTION_NONE".} = enum
137 ifOnlyDM = "ITEM_OPTION_ONLYDM"
138 ifFall = "ITEM_OPTION_FALL"
140 MapItem* = ref object of MapObject
141 position* {.writeDefault.}: DFPoint
142 kind* {.writeDefault.}: MapItemType
143 options*: set[MapItemFlags]
144 # editor-specific fields
145 id* {.serializeNever, nonEditable, invisible.}: int32
146 size* {.serializeNever, nonEditable.}: DFSize
147 tex* {.serializeNever, nonEditable, invisible.}: Texture
149 MapMonsterType* {.size: sizeof(uint8).} = enum
150 monNone = "MONSTER_NONE"
151 monDemon = "MONSTER_DEMON"
152 monImp = "MONSTER_IMP"
153 monZombie = "MONSTER_ZOMBIE"
154 monSergeant = "MONSTER_SERG"
155 monCyber = "MONSTER_CYBER"
156 monChaingunner = "MONSTER_CGUN"
157 monBaron = "MONSTER_BARON"
158 monKnight = "MONSTER_KNIGHT"
159 monCaco = "MONSTER_CACO"
160 monLostSoul = "MONSTER_SOUL"
161 monPain = "MONSTER_PAIN"
162 monSpider = "MONSTER_SPIDER"
163 monBigSpider = "MONSTER_BSP"
164 monMancubus = "MONSTER_MANCUB"
165 monRevenant = "MONSTER_SKEL"
166 monArchVile = "MONSTER_VILE"
167 monFish = "MONSTER_FISH"
168 monBarrel = "MONSTER_BARREL"
169 monRobo = "MONSTER_ROBO"
170 monPrikolist = "MONSTER_MAN"
172 MapMonsterBehaviour* {.size: sizeof(uint8).} = enum
173 behNormal = "BH_NORMAL"
174 behKiller = "BH_KILLER"
175 behManiac = "BH_MANIAC"
176 behInsane = "BH_INSANE"
177 behCannibal = "BH_CANNIBAL"
180 MapMonster* = ref object of MapObject
181 position* {.writeDefault.}: DFPoint
182 kind* {.writeDefault.}: MapMonsterType
183 direction*: MapDirection
184 # editor-specific fields
185 id* {.serializeNever, nonEditable, invisible.}: int32
186 size* {.serializeNever, nonEditable.}: DFSize
187 center* {.serializeNever, nonEditable, invisible.}: DFPoint
188 delta* {.serializeNever, nonEditable, invisible.}: DFPoint
189 tex* {.serializeNever, nonEditable, invisible.}: Texture
191 MapAreaType* {.size: sizeof(uint8).} = enum
192 areaNone = "AREA_NONE"
193 areaP1Spawn = "AREA_PLAYERPOINT1"
194 areaP2Spawn = "AREA_PLAYERPOINT2"
195 areaDMSpawn = "AREA_DMPOINT"
196 areaRedFlag = "AREA_REDFLAG"
197 areaBlueFlag = "AREA_BLUEFLAG"
198 areaDomFlag = "AREA_DOMFLAG"
199 areaRedSpawn = "AREA_REDTEAMPOINT"
200 areaBlueSpawn = "AREA_BLUETEAMPOINT"
202 MapArea* = ref object of MapObject
203 position* {.writeDefault.}: DFPoint
204 kind* {.writeDefault.}: MapAreaType
205 direction*: MapDirection
206 # editor-specific fields
207 id* {.serializeNever, nonEditable, invisible.}: int32
208 size* {.serializeNever, nonEditable.}: DFSize
209 center* {.serializeNever, nonEditable, invisible.}: DFPoint
210 tex* {.serializeNever, nonEditable, invisible.}: Texture
212 MapActivationType* {.size: sizeof(uint8), bitsetNullValue: "ACTIVATE_NONE".} = enum
213 actPlayerCollide = "ACTIVATE_PLAYERCOLLIDE"
214 actMonsterCollide = "ACTIVATE_MONSTERCOLLIDE"
215 actPlayerPress = "ACTIVATE_PLAYERPRESS"
216 actMonsterPress = "ACTIVATE_MONSTERPRESS"
217 actShot = "ACTIVATE_SHOT"
218 actNoMonster = "ACTIVATE_NOMONSTER"
220 MapTriggerData* {.triggerData.} = ref object of Serializable
222 MapTriggerType* {.size: sizeof(uint8).} = enum
223 trigNone = "TRIGGER_NONE"
224 trigExit = "TRIGGER_EXIT"
225 trigTeleport = "TRIGGER_TELEPORT"
226 trigOpenDoor = "TRIGGER_OPENDOOR"
227 trigCloseDoor = "TRIGGER_CLOSEDOOR"
228 trigDoor = "TRIGGER_DOOR"
229 trigDoor5 = "TRIGGER_DOOR5"
230 trigCloseTrap = "TRIGGER_CLOSETRAP"
231 trigTrap = "TRIGGER_TRAP"
232 trigPress = "TRIGGER_PRESS"
233 trigSecret = "TRIGGER_SECRET"
234 trigLiftUp = "TRIGGER_LIFTUP"
235 trigLiftDown = "TRIGGER_LIFTDOWN"
236 trigLift = "TRIGGER_LIFT"
237 trigTexture = "TRIGGER_TEXTURE"
238 trigOn = "TRIGGER_ON"
239 trigOff = "TRIGGER_OFF"
240 trigOnOff = "TRIGGER_ONOFF"
241 trigSound = "TRIGGER_SOUND"
242 trigSpawnMonster = "TRIGGER_SPAWNMONSTER"
243 trigSpawnItem = "TRIGGER_SPAWNITEM"
244 trigMusic = "TRIGGER_MUSIC"
245 trigPush = "TRIGGER_PUSH"
246 trigScore = "TRIGGER_SCORE"
247 trigMessage = "TRIGGER_MESSAGE"
248 trigDamage = "TRIGGER_DAMAGE"
249 trigHealth = "TRIGGER_HEALTH"
250 trigShot = "TRIGGER_SHOT"
251 trigEffect = "TRIGGER_EFFECT"
252 trigScript = "TRIGGER_SCRIPT"
254 MapTrigger* = ref object of MapObject
255 position* {.writeDefault.}: DFPoint
256 size* {.writeDefault.}: DFSize
257 enabled* {.defaultValue: true.}: bool
258 texturePanel*: MapPanel
259 kind* {.writeDefault.}: MapTriggerType
260 activateType* {.writeDefault.}: set[MapActivationType]
262 triggerData* {.writeDefault, serializedBlockName: "triggerdata", triggerData.}: MapTriggerData # must always be last
263 # editor-specific fields
264 id* {.serializeNever, nonEditable.}: int32
266 MapHeader* = ref object of Serializable
267 mapName* {.writeDefault, serializedFieldName: "name", maxSize: 32.}: string
268 author* {.writeDefault, maxSize: 32.}: string
269 description* {.writeDefault, maxSize: 256.}: string
270 music* {.writeDefault, resPath, maxSize: 64.}: string
271 sky* {.writeDefault, resPath, maxSize: 64.}: string
272 size* {.writeDefault.}: DFSize
274 Map* = ref object of Serializable
275 header* {.writeDefault, serializedBlockId: 7.}: MapHeader
276 textures* {.writeDefault, serializedBlockId: 1, serializedBlockName: "texture".}: ref seq[MapTexture]
277 panels* {.writeDefault, serializedBlockId: 2, serializedBlockName: "panel".}: ref seq[MapPanel]
278 items* {.writeDefault, serializedBlockId: 3, serializedBlockName: "item".}: ref seq[MapItem]
279 monsters* {.writeDefault, serializedBlockId: 5, serializedBlockName: "monster".}: ref seq[MapMonster]
280 areas* {.writeDefault, serializedBlockId: 4, serializedBlockName: "area".}: ref seq[MapArea]
281 triggers* {.writeDefault, serializedBlockId: 6, serializedBlockName: "trigger".}: ref seq[MapTrigger]
283 SomeMapObject* = MapPanel | MapItem | MapMonster | MapArea | MapTrigger
284 SomeMapRecord* = SomeMapObject | MapTexture
287 lrBackground = "Background"
289 lrForeground = "Foreground"
291 lrLiquids = "Liquids"
293 lrMonsters = "Monsters"
295 lrTriggers = "Triggers"
299 # TRIGGER DATA TYPES START #
302 triggerDataType({ trigExit }):
303 type MapTriggerDataExit* = ref object of MapTriggerData
304 map* {.writeDefault, maxSize: 16.}: string
306 triggerDataType({ trigTeleport }):
307 type MapTriggerDataTeleport* = ref object of MapTriggerData
308 target* {.writeDefault.}: DFPoint
311 direction*: MapDirection
313 triggerDataType({ trigOpenDoor..trigTrap, trigLiftUp..trigLift }):
314 type MapTriggerDataPanel* = ref object of MapTriggerData
315 panel* {.writeDefault, serializedFieldName: "panelid".}: MapPanel
319 triggerDataType({ trigPress, trigOn..trigOnOff }):
320 type MapTriggerDataPress* = ref object of MapTriggerData
325 monster* {.serializedFieldName: "monsterid".}: MapMonster
328 movePanel* {.serializeTextOnly, serializedFieldName: "panelid".}: MapPanel
329 silent* {.serializeTextOnly, defaultValue: true.}: bool
330 sound* {.serializeTextOnly.}: string
332 triggerDataType({ trigTexture }):
333 type MapTriggerDataTexture* = ref object of MapTriggerData
334 activateOnce* {.writeDefault.}: bool
335 animateOnce* {.writeDefault.}: bool
337 triggerDataType({ trigSound }):
338 type MapTriggerDataSound* = ref object of MapTriggerData
339 soundName* {.writeDefault, resPath, maxSize: 64.}: string
340 volume* {.writeDefault.}: uint8
342 local* {.defaultValue: true.}: bool
346 triggerDataType({ trigSpawnMonster }):
347 type MapTriggerDataSpawnMonster* = ref object of MapTriggerData
348 position* {.writeDefault.}: DFPoint
349 kind* {.writeDefault, overrideSize: sizeof(uint32).}: MapMonsterType
350 health* {.writeDefault.}: int32
351 direction* {.writeDefault.}: MapDirection
352 active* {.writeDefault, overrideSize: 3, defaultValue: true.}: bool
353 count* {.writeDefault, defaultValue: 1.}: int32
354 effect* {.writeDefault.}: MapSpawnEffect
355 max* {.writeDefault, defaultValue: 1.}: uint16
356 delay* {.writeDefault, defaultValue: 1000.}: uint16
357 behaviour*: MapMonsterBehaviour
359 triggerDataType({ trigSpawnItem }):
360 type MapTriggerDataSpawnItem* = ref object of MapTriggerData
361 position* {.writeDefault.}: DFPoint
362 kind* {.writeDefault.}: MapItemType
363 gravity* {.defaultValue: true.}: bool
364 dmonly* {.overrideSize: 2.}: bool
365 count* {.defaultValue: 1.}: int32
366 effect* {.overrideSize: 2.}: MapSpawnEffect
367 max* {.defaultValue: 1.}: uint16
368 delay* {.defaultValue: 1.}: uint16
371 MapTriggerMusicAction* {.size: sizeof(uint8).} = enum
372 musActionStop = "TRIGGER_MUSIC_ACTION_STOP"
373 musActionPlay = "TRIGGER_MUSIC_ACTION_PLAY"
375 triggerDataType({ trigMusic }):
376 type MapTriggerDataMusic* = ref object of MapTriggerData
377 musicName* {.writeDefault, serializedFieldName: "name", resPath, maxSize: 64.}: string
378 action* {.writeDefault.}: MapTriggerMusicAction
380 triggerDataType({ trigPush }):
381 type MapTriggerDataPush* = ref object of MapTriggerData
382 angle* {.writeDefault.}: uint16
383 force* {.writeDefault.}: uint8
384 resetVelocity* {.writeDefault.}: bool
387 MapTriggerScoreAction* {.size: sizeof(uint8).} = enum
388 scoreActionAdd = "TRIGGER_SCORE_ACTION_ADD"
389 scoreActionSub = "TRIGGER_SCORE_ACTION_SUB"
390 scoreActionWin = "TRIGGER_SCORE_ACTION_WIN"
391 scoreActionLose = "TRIGGER_SCORE_ACTION_LOOSE" # sic
393 MapTriggerScoreTeam* {.size: sizeof(uint8).} = enum
394 scoreTeamMineRed = "TRIGGER_SCORE_TEAM_MINE_RED"
395 scoreTeamMineBlue = "TRIGGER_SCORE_TEAM_MINE_BLUE"
396 scoreTeamForceRed = "TRIGGER_SCORE_TEAM_FORCE_RED"
397 scoreTeamForceBlue = "TRIGGER_SCORE_TEAM_FORCE_BLUE"
399 triggerDataType({ trigScore }):
400 type MapTriggerDataScore* = ref object of MapTriggerData
401 action* {.writeDefault.}: MapTriggerScoreAction
402 count* {.writeDefault, defaultValue: 1.}: uint8
403 team* {.writeDefault.}: MapTriggerScoreTeam
404 console* {.writeDefault.}: bool
405 message* {.writeDefault, defaultValue: true.}: bool
408 MapTriggerMessageKind* {.size: sizeof(uint8).} = enum
409 msgKindChat = "TRIGGER_MESSAGE_KIND_CHAT"
410 msgKindGame = "TRIGGER_MESSAGE_KIND_GAME"
412 MapTriggerMessageDest* {.size: sizeof(uint8).} = enum
413 msgDestMe = "TRIGGER_MESSAGE_DEST_ME"
414 msgDestMyTeam = "TRIGGER_MESSAGE_DEST_MY_TEAM"
415 msgDestEnemyTeam = "TRIGGER_MESSAGE_DEST_ENEMY_TEAM"
416 msgDestRedTeam = "TRIGGER_MESSAGE_DEST_RED_TEAM"
417 msgDestBlueTeam = "TRIGGER_MESSAGE_DEST_BLUE_TEAM"
418 msgDestEveryone = "TRIGGER_MESSAGE_DEST_EVERYONE"
420 triggerDataType({ trigMessage }):
421 type MapTriggerDataMessage* = ref object of MapTriggerData
422 kind* {.writeDefault, serializedFieldName: "kind".}: MapTriggerMessageKind
423 dest* {.writeDefault.}: MapTriggerMessageDest
424 text* {.writeDefault, maxSize: 100.}: string
425 time* {.writeDefault.}: uint16
427 triggerDataType({ trigDamage }):
428 type MapTriggerDataDamage* = ref object of MapTriggerData
429 amount* {.writeDefault.}: uint16
430 interval* {.writeDefault.}: uint16
431 kind* {.writeDefault, serializedFieldName: "kind".}: MapHitType
433 triggerDataType({ trigHealth }):
434 type MapTriggerDataHealth* = ref object of MapTriggerData
435 amount* {.writeDefault.}: uint16
436 interval* {.writeDefault.}: uint16
437 max* {.writeDefault.}: bool
438 silent* {.writeDefault.}: bool
441 MapTriggerShotKind* {.size: sizeof(uint8).} = enum
442 shotKindPistol = "TRIGGER_SHOT_PISTOL"
443 shotKindBullet = "TRIGGER_SHOT_BULLET"
444 shotKindShotgun = "TRIGGER_SHOT_SHOTGUN"
445 shotKindSSG = "TRIGGER_SHOT_SSG"
446 shotKindImp = "TRIGGER_SHOT_IMP"
447 shotKindPlasma = "TRIGGER_SHOT_PLASMA"
448 shotKindSpider = "TRIGGER_SHOT_SPIDER"
449 shotKindCaco = "TRIGGER_SHOT_CACO"
450 shotKindBaron = "TRIGGER_SHOT_BARON"
451 shotKindMancub = "TRIGGER_SHOT_MANCUB"
452 shotKindRev = "TRIGGER_SHOT_REV"
453 shotKindRocket = "TRIGGER_SHOT_ROCKET"
454 shotKindBFG = "TRIGGER_SHOT_BFG"
455 shotKindExpl = "TRIGGER_SHOT_EXPL"
456 shotKindBFGExpl = "TRIGGER_SHOT_BFGEXPL"
457 shotKindFlame = "TRIGGER_SHOT_FLAME"
458 MapTriggerShotTarget* {.size: sizeof(uint8).} = enum
459 shotTargetNone = "TRIGGER_SHOT_TARGET_NONE"
460 shotTargetMon = "TRIGGER_SHOT_TARGET_MON"
461 shotTargetPlr = "TRIGGER_SHOT_TARGET_PLR"
462 shotTargetRed = "TRIGGER_SHOT_TARGET_RED"
463 shotTargetBlue = "TRIGGER_SHOT_TARGET_BLUE"
464 shotTargetMonPlr = "TRIGGER_SHOT_TARGET_MONPLR"
465 shotTargetPlrMon = "TRIGGER_SHOT_TARGET_PLRMON"
466 MapTriggerShotAim* {.size: sizeof(uint8).} = enum
467 shotAimDefault = "TRIGGER_SHOT_AIM_DEFAULT"
468 shotAimAllMap = "TRIGGER_SHOT_AIM_ALLMAP"
469 shotAimTrace = "TRIGGER_SHOT_AIM_TRACE"
470 shotAimTraceAll = "TRIGGER_SHOT_AIM_TRACEALL"
472 triggerDataType({ trigShot }):
473 type MapTriggerDataShot* = ref object of MapTriggerData
474 position* {.writeDefault.}: DFPoint
475 kind* {.writeDefault.}: MapTriggerShotKind
476 target* {.writeDefault.}: MapTriggerShotTarget
477 sound*: bool # negbool?
478 aim*: MapTriggerShotAim
479 panel* {.writeDefault, serializedFieldName: "panelid".}: MapPanel
488 MapTriggerEffectType* {.size: sizeof(uint8).} = enum
489 effectTypeParticle = "TRIGGER_EFFECT_PARTICLE"
490 effectTypeAnimation = "TRIGGER_EFFECT_ANIMATION"
491 MapTriggerEffectSubType* {.size: sizeof(uint8).} = enum
492 effectSubTypeSLiquid = "TRIGGER_EFFECT_SLIQUID"
493 effectSubTypeLLiquid = "TRIGGER_EFFECT_LLIQUID"
494 effectSubTypeDLiquid = "TRIGGER_EFFECT_DLIQUID"
495 effectSubTypeBlood = "TRIGGER_EFFECT_BLOOD"
496 effectSubTypeSpark = "TRIGGER_EFFECT_SPARK"
497 effectSubTypeBubble = "TRIGGER_EFFECT_BUBBLE"
498 MapTriggerEffectPos* {.size: sizeof(uint8).} = enum
499 effectPosCenter = "TRIGGER_EFFECT_POS_CENTER"
500 effectPosArea = "TRIGGER_EFFECT_POS_AREA"
502 triggerDataType({ trigEffect }):
503 type MapTriggerDataEffect* = ref object of MapTriggerData
504 count* {.writeDefault.}: uint8
505 kind* {.writeDefault.}: MapTriggerEffectType
506 subType* {.writeDefault.}: MapTriggerEffectSubType
507 red* {.writeDefault.}: uint8
508 green* {.writeDefault.}: uint8
509 blue* {.writeDefault.}: uint8
510 pos* {.writeDefault.}: MapTriggerEffectPos
511 wait* {.writeDefault.}: uint16
512 velX* {.writeDefault.}: int8
513 velY* {.writeDefault.}: int8
514 spreadL* {.writeDefault.}: uint8
515 spreadR* {.writeDefault.}: uint8
516 spreadU* {.writeDefault.}: uint8
517 spreadD* {.writeDefault.}: uint8
519 triggerDataType({ trigSecret }):
520 type MapTriggerDataSecret* = ref object of MapTriggerData
522 # TRIGGER DATA TYPES END #
525 currentMap*: Map = nil
527 # intiializers for map structs, executed after loading
529 proc init*(self: MapPanel) =
532 proc init*(self: MapTrigger) =
535 proc init*(self: MapTexture) =
536 self.tex = gfx.getTexture(self.path)
538 self.tex = gfx.getTexture("$$ERROR")
540 proc init*(self: MapItem) =
541 let typeStr = $self.kind
542 if typeStr in mapEntInfo:
543 let (_, _, size, _, _) = mapEntInfo[typeStr]
544 self.tex = gfx.getTexture("$$" & typeStr)
547 proc init*(self: MapArea) =
548 let typeStr = $self.kind
549 if typeStr in mapEntInfo:
550 let (center, _, size, _, _) = mapEntInfo[typeStr]
551 self.tex = gfx.getTexture("$$" & typeStr)
555 proc init*(self: MapMonster) =
556 let typeStr = $self.kind
557 if typeStr in mapEntInfo:
558 let (center, delta, size, _, _) = mapEntInfo[typeStr]
559 self.tex = gfx.getTexture("$$" & typeStr)
566 iterator mapAllOfType*[T: SomeMapRecord](): var T =
568 when T is MapTexture:
569 for x in currentMap.textures[].mitems(): yield x
571 for x in currentMap.panels[].mitems(): yield x
573 for x in currentMap.items[].mitems(): yield x
574 elif T is MapMonster:
575 for x in currentMap.monsters[].mitems(): yield x
577 for x in currentMap.areas[].mitems(): yield x
578 elif T is MapTrigger:
579 for x in currentMap.triggers[].mitems(): yield x
581 error("this shouldn't happen")
583 proc mapGetAllOfType*[T: SomeMapRecord](): seq[T] =
585 when T is MapTexture:
586 return currentMap.textures
588 return currentMap.panels
590 return currentMap.items
591 elif T is MapMonster:
592 return currentMap.monsters
594 return currentMap.areas
595 elif T is MapTrigger:
596 return currentMap.triggers
598 error("this shouldn't happen")
600 template mapForAllRecords*(obj, blk: untyped): untyped =
602 for obj in mapAllOfType[MapTexture](): blk
603 for obj in mapAllOfType[MapPanel](): blk
604 for obj in mapAllOfType[MapItem](): blk
605 for obj in mapAllOfType[MapMonster](): blk
606 for obj in mapAllOfType[MapArea](): blk
607 for obj in mapAllOfType[MapTrigger](): blk
609 template mapForAllObjects*(obj, blk: untyped): untyped =
611 for obj in mapAllOfType[MapPanel](): blk
612 for obj in mapAllOfType[MapItem](): blk
613 for obj in mapAllOfType[MapMonster](): blk
614 for obj in mapAllOfType[MapArea](): blk
615 for obj in mapAllOfType[MapTrigger](): blk
617 proc mapGetByName*[T: SomeMapRecord](name: string): T =
619 for x in mapAllOfType[T]():
624 proc mapGetById*[T: SomeMapRecord](id: int): T =
625 if id >= 0 and id != 0xFFFF:
626 for x in mapAllOfType[T]():
631 proc newMapHeader*(name: string, w, h: int): MapHeader =
632 result = new(MapHeader)
633 result.mapName = name
634 result.size = initDFSize(w, h)
636 proc newMap*(): Map =
638 result.header = newMapHeader("Unnamed Map", 1600, 1600)
646 proc newMap*(stream: SomeSerializer): Map =
647 assert(not stream.isWriting, "can't create map from writer stream")
649 stream.serialize(result)
652 proc save*(self: Map, stream: SomeSerializer) =
653 assert(stream.isWriting, "can't save map to reader stream")
654 stream.serialize(self)
657 proc destroy*(self: Map) =
658 for mtex in self.textures[].mitems():
659 if mtex.path notin waterTextureNames:
661 self.textures[].setLen(0)
662 self.panels[].setLen(0)
663 self.items[].setLen(0)
664 self.monsters[].setLen(0)
665 self.areas[].setLen(0)
666 self.triggers[].setLen(0)
668 proc referenceScan[T: Serializable](self: Map, x: T) =
669 for fieldName, fieldSym in fieldPairs(x[]):
670 when fieldSym is SomeMapRecord:
672 when T is MapPanel and fieldSym is MapTexture:
673 if pfHide in x.flags:
674 fieldSym = nil # hidden panel, no texture
676 let searchName = fieldSym.name
677 let searchId = fieldSym.id
678 fieldSym = mapGetById[type(fieldSym)](searchId.int)
680 fieldSym = mapGetByName[type(fieldSym)](searchName)
681 elif fieldSym is MapTriggerData:
682 fieldSym.fixupReferences(self)
684 proc fixupReferences*(self: Map) =
686 self.referenceScan(x)