X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fshared%2FMAPDEF.pas;h=e3bdddc085c1d4caf412770bbedec55ea438dfa8;hb=2b04301f4303668096c37c21e06af70930f55b7f;hp=697d25339a9477b41b41cd7963b2830e2d4b6d1f;hpb=88ce644db1b40111bdb380f4357fa59bdb5173be;p=d2df-sdl.git diff --git a/src/shared/MAPDEF.pas b/src/shared/MAPDEF.pas index 697d253..e3bdddc 100644 --- a/src/shared/MAPDEF.pas +++ b/src/shared/MAPDEF.pas @@ -1,3 +1,20 @@ +(* Copyright (C) DooM 2D:Forever Developers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *) +{$INCLUDE a_modes.inc} +{$M+} unit MAPDEF; { @@ -11,311 +28,248 @@ MAPDEF.PAS interface uses - MAPSTRUCT; + xdynrec; + const - PANEL_NONE = 0; - PANEL_WALL = 1; - PANEL_BACK = 2; - PANEL_FORE = 4; - PANEL_WATER = 8; - PANEL_ACID1 = 16; - PANEL_ACID2 = 32; - PANEL_STEP = 64; - PANEL_LIFTUP = 128; - PANEL_LIFTDOWN = 256; - PANEL_OPENDOOR = 512; - PANEL_CLOSEDOOR = 1024; - PANEL_BLOCKMON = 2048; - PANEL_LIFTLEFT = 4096; - PANEL_LIFTRIGHT = 8192; - - PANEL_FLAG_BLENDING = 1; - PANEL_FLAG_HIDE = 2; - PANEL_FLAG_WATERTEXTURES = 4; - - EFFECT_NONE = 0; - EFFECT_TELEPORT = 1; - EFFECT_RESPAWN = 2; - EFFECT_FIRE = 3; - - ITEM_NONE = 0; - ITEM_MEDKIT_SMALL = 1; - ITEM_MEDKIT_LARGE = 2; - ITEM_MEDKIT_BLACK = 3; - ITEM_ARMOR_GREEN = 4; - ITEM_ARMOR_BLUE = 5; - ITEM_SPHERE_BLUE = 6; - ITEM_SPHERE_WHITE = 7; - ITEM_SUIT = 8; - ITEM_OXYGEN = 9; - ITEM_INVUL = 10; - ITEM_WEAPON_SAW = 11; - ITEM_WEAPON_SHOTGUN1 = 12; - ITEM_WEAPON_SHOTGUN2 = 13; - ITEM_WEAPON_CHAINGUN = 14; - ITEM_WEAPON_ROCKETLAUNCHER = 15; - ITEM_WEAPON_PLASMA = 16; - ITEM_WEAPON_BFG = 17; - ITEM_WEAPON_SUPERPULEMET = 18; - ITEM_AMMO_BULLETS = 19; - ITEM_AMMO_BULLETS_BOX = 20; - ITEM_AMMO_SHELLS = 21; - ITEM_AMMO_SHELLS_BOX = 22; - ITEM_AMMO_ROCKET = 23; - ITEM_AMMO_ROCKET_BOX = 24; - ITEM_AMMO_CELL = 25; - ITEM_AMMO_CELL_BIG = 26; - ITEM_AMMO_BACKPACK = 27; - ITEM_KEY_RED = 28; - ITEM_KEY_GREEN = 29; - ITEM_KEY_BLUE = 30; - ITEM_WEAPON_KASTET = 31; - ITEM_WEAPON_PISTOL = 32; - ITEM_BOTTLE = 33; - ITEM_HELMET = 34; - ITEM_JETPACK = 35; - ITEM_INVIS = 36; - - ITEM_MAX = 36; // store the last item's id in here - // use this in for loops - - ITEM_OPTION_ONLYDM = 1; - ITEM_OPTION_FALL = 2; - - AREA_NONE = 0; - AREA_PLAYERPOINT1 = 1; - AREA_PLAYERPOINT2 = 2; - AREA_DMPOINT = 3; - AREA_REDFLAG = 4; - AREA_BLUEFLAG = 5; - AREA_DOMFLAG = 6; - AREA_REDTEAMPOINT = 7; - AREA_BLUETEAMPOINT = 8; - - MONSTER_NONE = 0; - MONSTER_DEMON = 1; - MONSTER_IMP = 2; - MONSTER_ZOMBY = 3; - MONSTER_SERG = 4; - MONSTER_CYBER = 5; - MONSTER_CGUN = 6; - MONSTER_BARON = 7; - MONSTER_KNIGHT = 8; - MONSTER_CACO = 9; - MONSTER_SOUL = 10; - MONSTER_PAIN = 11; - MONSTER_SPIDER = 12; - MONSTER_BSP = 13; - MONSTER_MANCUB = 14; - MONSTER_SKEL = 15; - MONSTER_VILE = 16; - MONSTER_FISH = 17; - MONSTER_BARREL = 18; - MONSTER_ROBO = 19; - MONSTER_MAN = 20; - - TRIGGER_NONE = 0; - TRIGGER_EXIT = 1; - TRIGGER_TELEPORT = 2; - TRIGGER_OPENDOOR = 3; - TRIGGER_CLOSEDOOR = 4; - TRIGGER_DOOR = 5; - TRIGGER_DOOR5 = 6; - TRIGGER_CLOSETRAP = 7; - TRIGGER_TRAP = 8; - TRIGGER_PRESS = 9; - TRIGGER_SECRET = 10; - TRIGGER_LIFTUP = 11; - TRIGGER_LIFTDOWN = 12; - TRIGGER_LIFT = 13; - TRIGGER_TEXTURE = 14; - TRIGGER_ON = 15; - TRIGGER_OFF = 16; - TRIGGER_ONOFF = 17; - TRIGGER_SOUND = 18; - TRIGGER_SPAWNMONSTER = 19; - TRIGGER_SPAWNITEM = 20; - TRIGGER_MUSIC = 21; - TRIGGER_PUSH = 22; - TRIGGER_SCORE = 23; - TRIGGER_MESSAGE = 24; - TRIGGER_DAMAGE = 25; - TRIGGER_HEALTH = 26; - TRIGGER_SHOT = 27; - TRIGGER_EFFECT = 28; - TRIGGER_MAX = 28; - - TRIGGER_SHOT_PISTOL = 0; - TRIGGER_SHOT_BULLET = 1; - TRIGGER_SHOT_SHOTGUN = 2; - TRIGGER_SHOT_SSG = 3; - TRIGGER_SHOT_IMP = 4; - TRIGGER_SHOT_PLASMA = 5; - TRIGGER_SHOT_SPIDER = 6; - TRIGGER_SHOT_CACO = 7; - TRIGGER_SHOT_BARON = 8; - TRIGGER_SHOT_MANCUB = 9; - TRIGGER_SHOT_REV = 10; - TRIGGER_SHOT_ROCKET = 11; - TRIGGER_SHOT_BFG = 12; - TRIGGER_SHOT_EXPL = 13; - TRIGGER_SHOT_BFGEXPL = 14; - TRIGGER_SHOT_MAX = 14; - - TRIGGER_SHOT_TARGET_NONE = 0; - TRIGGER_SHOT_TARGET_MON = 1; - TRIGGER_SHOT_TARGET_PLR = 2; - TRIGGER_SHOT_TARGET_RED = 3; - TRIGGER_SHOT_TARGET_BLUE = 4; - TRIGGER_SHOT_TARGET_MONPLR = 5; - TRIGGER_SHOT_TARGET_PLRMON = 6; - - TRIGGER_EFFECT_PARTICLE = 0; - TRIGGER_EFFECT_ANIMATION = 1; - - TRIGGER_EFFECT_SLIQUID = 0; - TRIGGER_EFFECT_LLIQUID = 1; - TRIGGER_EFFECT_DLIQUID = 2; - TRIGGER_EFFECT_BLOOD = 3; - TRIGGER_EFFECT_SPARK = 4; - TRIGGER_EFFECT_BUBBLE = 5; - TRIGGER_EFFECT_MAX = 5; - - TRIGGER_EFFECT_POS_CENTER = 0; - TRIGGER_EFFECT_POS_AREA = 1; - - ACTIVATE_PLAYERCOLLIDE = 1; - ACTIVATE_MONSTERCOLLIDE = 2; - ACTIVATE_PLAYERPRESS = 4; - ACTIVATE_MONSTERPRESS = 8; - ACTIVATE_SHOT = 16; - ACTIVATE_NOMONSTER = 32; - ACTIVATE_CUSTOM = 255; - - KEY_RED = 1; - KEY_GREEN = 2; - KEY_BLUE = 4; - KEY_REDTEAM = 8; - KEY_BLUETEAM = 16; + MAP_SIGNATURE = 'MAP'; + +const TEXTURE_NAME_WATER = '_water_0'; TEXTURE_NAME_ACID1 = '_water_1'; TEXTURE_NAME_ACID2 = '_water_2'; - TEXTURE_SPECIAL_WATER = DWORD(-1); - TEXTURE_SPECIAL_ACID1 = DWORD(-2); - TEXTURE_SPECIAL_ACID2 = DWORD(-3); - TEXTURE_NONE = DWORD(-4); -Type - TPoint = packed record +type + TDFPoint = packed record X, Y: LongInt; end; - TTriggerData = record - case Byte of - 0: (Default: Byte128); - TRIGGER_EXIT: (MapName: Char16); - TRIGGER_TELEPORT: (TargetPoint: TPoint; - d2d_teleport: Boolean; - silent_teleport: Boolean; - TlpDir: Byte); - TRIGGER_OPENDOOR, - TRIGGER_CLOSEDOOR, - TRIGGER_DOOR, - TRIGGER_DOOR5, - TRIGGER_CLOSETRAP, - TRIGGER_TRAP, - TRIGGER_LIFTUP, - TRIGGER_LIFTDOWN, - TRIGGER_LIFT: (PanelID: Integer; - NoSound: Boolean; - d2d_doors: Boolean); - TRIGGER_PRESS, - TRIGGER_ON, - TRIGGER_OFF, - TRIGGER_ONOFF: (tX, tY: Integer; - tWidth, tHeight: Word; - Wait: Word; - Count: Word; - MonsterID: Integer; - ExtRandom: Boolean); - TRIGGER_SECRET: (); - TRIGGER_TEXTURE: (ActivateOnce: Boolean; - AnimOnce: Boolean); - TRIGGER_SOUND: (SoundName: Char64; - Volume: Byte; - Pan: Byte; - Local: Boolean; - PlayCount: Byte; - SoundSwitch: Boolean); - TRIGGER_SPAWNMONSTER: (MonPos: TPoint; - MonType: Byte; - MonHealth: Integer; - MonDir: Byte; - MonActive: Boolean; - MonCount: Integer; - MonEffect: Byte; - MonMax: Word; - MonDelay: Word; - MonBehav: Byte); - TRIGGER_SPAWNITEM: (ItemPos: TPoint; - ItemType: Byte; - ItemFalls: Boolean; - ItemOnlyDM: Boolean; - ItemCount: Integer; - ItemEffect: Byte; - ItemMax: Word; - ItemDelay: Word); - TRIGGER_MUSIC: (MusicName: Char64; - MusicAction: Byte); - TRIGGER_PUSH: (PushAngle: Word; - PushForce: Byte; - ResetVel: Boolean); - TRIGGER_SCORE: (ScoreAction: Byte; - ScoreCount: Byte; - ScoreTeam: Byte; - ScoreCon, - ScoreMsg: Boolean); - TRIGGER_MESSAGE: (MessageKind: Byte; - MessageSendTo: Byte; - MessageText: Char100; - MessageTime: Word); - TRIGGER_DAMAGE: (DamageValue: Word; - DamageInterval: Word); - TRIGGER_HEALTH: (HealValue: Word; - HealInterval: Word; - HealMax: Boolean; - HealSilent: Boolean); - TRIGGER_SHOT: (ShotType: Byte; - ShotSound: Boolean; - ShotPanelID: Integer; - ShotTarget: Byte; - ShotIntSight: Word; - ShotAllMap: Boolean; - ShotPos: TPoint; - ShotAngle: Word; - ShotWait: Word; - ShotAccuracy: Word; - ShotAmmo: Word; - ShotIntReload: Word); - TRIGGER_EFFECT: (FXCount: Byte; - FXType: Byte; - FXSubType: Byte; - FXColorR: Byte; - FXColorG: Byte; - FXColorB: Byte; - FXPos: Byte; - FXWait: Word; - FXVelX: ShortInt; - FXVelY: ShortInt; - FXSpreadL: Byte; - FXSpreadR: Byte; - FXSpreadU: Byte; - FXSpreadD: Byte); - end; + Char16 = packed array[0..15] of Char; + Char32 = packed array[0..31] of Char; + Char64 = packed array[0..63] of Char; + Char100 = packed array[0..99] of Char; + Char256 = packed array[0..255] of Char; + Byte128 = packed array[0..127] of Byte; + +{$INCLUDE mapdef.inc} + +type + TTexturesRec1Array = array of TTextureRec_1; + TPanelsRec1Array = array of TPanelRec_1; + TItemsRec1Array = array of TItemRec_1; + TMonsterRec1Array = array of TMonsterRec_1; + TAreasRec1Array = array of TAreaRec_1; + TTriggersRec1Array = array of TTriggerRec_1; + + +function GetMapHeader (rec: TDynRecord): TMapHeaderRec_1; +function GetTextures (rec: TDynRecord): TTexturesRec1Array; +function GetPanels (rec: TDynRecord): TPanelsRec1Array; +function GetItems (rec: TDynRecord): TItemsRec1Array; +function GetAreas (rec: TDynRecord): TAreasRec1Array; +function GetMonsters (rec: TDynRecord): TMonsterRec1Array; +function GetTriggers (rec: TDynRecord): TTriggersRec1Array; + implementation +uses + {e_log,} xparser, xstreams; + + +function GetMapHeader (rec: TDynRecord): TMapHeaderRec_1; +var + ws: TSFSMemoryChunkStream = nil; +begin + FillChar(result, sizeof(result), 0); + if (rec = nil) then exit; + try + ws := TSFSMemoryChunkStream.Create(@result, sizeof(result)); + rec.writeBinTo(ws, -1, true); // only fields + except // sorry + FillChar(result, sizeof(result), 0); + end; + ws.Free(); +end; + + +function GetTextures (rec: TDynRecord): TTexturesRec1Array; +var + ws: TSFSMemoryChunkStream = nil; + fld: TDynField; + f: Integer; +begin + result := nil; + fld := rec.field['texture']; + if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.list.count = 0) then exit; + ws := TSFSMemoryChunkStream.Create(nil, 0); + try + SetLength(result, fld.list.count); + for f := 0 to fld.list.count-1 do + begin + FillChar(result[f], sizeof(result[f]), 0); + ws.setup(@result[f], sizeof(result[f])); + fld.list[f].writeBinTo(ws, -1, true); // only fields + end; + except + result := nil; + end; + ws.Free(); +end; + + +function GetPanels (rec: TDynRecord): TPanelsRec1Array; +var + ws: TSFSMemoryChunkStream = nil; + fld: TDynField; + f: Integer; +begin + result := nil; + fld := rec.field['panel']; + if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.list.count = 0) then exit; + ws := TSFSMemoryChunkStream.Create(nil, 0); + try + SetLength(result, fld.list.count); + for f := 0 to fld.list.count-1 do + begin + FillChar(result[f], sizeof(result[f]), 0); + ws.setup(@result[f], sizeof(result[f])); + fld.list[f].writeBinTo(ws, -1, true); // only fields + end; + except + result := nil; + end; + ws.Free(); +end; + + +function GetItems (rec: TDynRecord): TItemsRec1Array; +var + ws: TSFSMemoryChunkStream = nil; + fld: TDynField; + f: Integer; +begin + result := nil; + fld := rec.field['item']; + if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.list.count = 0) then exit; + ws := TSFSMemoryChunkStream.Create(nil, 0); + try + SetLength(result, fld.list.count); + for f := 0 to fld.list.count-1 do + begin + FillChar(result[f], sizeof(result[f]), 0); + ws.setup(@result[f], sizeof(result[f])); + fld.list[f].writeBinTo(ws, -1, true); // only fields + end; + except + result := nil; + end; + ws.Free(); +end; + + +function GetAreas (rec: TDynRecord): TAreasRec1Array; +var + ws: TSFSMemoryChunkStream = nil; + fld: TDynField; + f: Integer; +begin + result := nil; + fld := rec.field['area']; + if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.list.count = 0) then exit; + ws := TSFSMemoryChunkStream.Create(nil, 0); + try + SetLength(result, fld.list.count); + for f := 0 to fld.list.count-1 do + begin + FillChar(result[f], sizeof(result[f]), 0); + ws.setup(@result[f], sizeof(result[f])); + fld.list[f].writeBinTo(ws, -1, true); // only fields + end; + except + result := nil; + end; + ws.Free(); +end; + + +function GetMonsters (rec: TDynRecord): TMonsterRec1Array; +var + ws: TSFSMemoryChunkStream = nil; + fld: TDynField; + f: Integer; +begin + result := nil; + fld := rec.field['monster']; + if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.list.count = 0) then exit; + ws := TSFSMemoryChunkStream.Create(nil, 0); + try + SetLength(result, fld.list.count); + for f := 0 to fld.list.count-1 do + begin + FillChar(result[f], sizeof(result[f]), 0); + ws.setup(@result[f], sizeof(result[f])); + fld.list[f].writeBinTo(ws, -1, true); // only fields + end; + except + result := nil; + end; + ws.Free(); +end; + + +function GetTriggers (rec: TDynRecord): TTriggersRec1Array; +var + ws: TSFSMemoryChunkStream = nil; + fld: TDynField; + f: Integer; + //wr: TTextWriter; + //fo: File; +begin + result := nil; + fld := rec.field['trigger']; + if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.list.count = 0) then exit; + ws := TSFSMemoryChunkStream.Create(nil, 0); + try + //wr := TFileTextWriter.Create('z00.txt'); + SetLength(result, fld.list.count); + for f := 0 to fld.list.count-1 do + begin + FillChar(result[f], sizeof(result[f]), 0); + //e_LogWritefln(': trigger #%s; TexturePanel=%s', [f, result[f].TexturePanel]); + ws.setup(@result[f], sizeof(result[f])); + fld.list[f].writeBinTo(ws, -1, true); // only fields + { + e_LogWritefln(': trigger #%s; X=%s; Y=%s; Width=%s; Height=%s; Enabled=%s; TexturePanel=%s; TriggerType=%s; ActivateType=%s; Keys=%s', [f, + result[f].X, + result[f].Y, + result[f].Width, + result[f].Height, + result[f].Enabled, + result[f].TexturePanel, + result[f].TriggerType, + result[f].ActivateType, + result[f].Keys + ]); + //e_LogWritefln('***'#10'%s'#10'***', [); + fld.list[f].writeTo(wr); + if (f = 0) then + begin + AssignFile(fo, 'z00.bin'); + Rewrite(fo, 1); + BlockWrite(fo, result[f], sizeof(result[f])); + CloseFile(fo); + end; + } + end; + //wr.Free(); + except + result := nil; + end; + ws.Free(); +end; + + end.