summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 5af7337)
raw | patch | inline | side by side (parent: 5af7337)
author | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Thu, 31 Aug 2017 19:28:08 +0000 (22:28 +0300) | ||
committer | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Fri, 1 Sep 2017 00:33:55 +0000 (03:33 +0300) |
13 files changed:
src/game/g_game.pas | patch | blob | history | |
src/game/g_gui.pas | patch | blob | history | |
src/game/g_main.pas | patch | blob | history | |
src/game/g_map.pas | patch | blob | history | |
src/game/g_netmsg.pas | patch | blob | history | |
src/game/g_panel.pas | patch | blob | history | |
src/game/g_triggers.pas | patch | blob | history | |
src/shared/MAPDEF.pas | patch | blob | history | |
src/shared/mapdef.inc | patch | blob | history | |
src/shared/mapdef_help.inc | [new file with mode: 0644] | patch | blob |
src/shared/mapdef_impl.inc | [new file with mode: 0644] | patch | blob |
src/shared/xdynrec.pas | patch | blob | history | |
src/tools/mapgen.dpr | patch | blob | history |
diff --git a/src/game/g_game.pas b/src/game/g_game.pas
index 03be57d86ec5c43e9f3007c5f3548dfeaa20e7ed..302b952af4b10f88b81c89e2537faf706921b2b9 100644 (file)
--- a/src/game/g_game.pas
+++ b/src/game/g_game.pas
begin
g_Console_Add('player left the map');
gExitByTrigger := True;
- g_Game_ExitLevel(gTriggers[a].Data.MapName);
+ //g_Game_ExitLevel(gTriggers[a].Data.MapName);
+ g_Game_ExitLevel(gTriggers[a].trigData.trigMapName);
break;
end;
end;
if gTriggers[a].TriggerType = TRIGGER_EXIT then
begin
gExitByTrigger := True;
- gNextMap := gTriggers[a].Data.MapName;
+ //gNextMap := gTriggers[a].Data.MapName;
+ gNextMap := gTriggers[a].trigData.trigMapName;
Break;
end;
// Èùåì ñëåäóþùóþ êàðòó â WAD ôàéëå
with gTriggers[i] do
if (TriggerType = TRIGGER_SOUND) and
(Sound <> nil) and
- (Data.Local) and
+ (trigData.trigLocal) and
Sound.IsPlaying() then
begin
if ((gPlayer1 <> nil) and g_CollidePoint(gPlayer1.GameX, gPlayer1.GameY, X, Y, Width, Height)) or
((gPlayer2 <> nil) and g_CollidePoint(gPlayer2.GameX, gPlayer2.GameY, X, Y, Width, Height)) then
begin
- Sound.SetPan(0.5 - Data.Pan/255.0);
- Sound.SetVolume(Data.Volume/255.0);
+ Sound.SetPan(0.5 - trigData.trigPan/255.0);
+ Sound.SetVolume(trigData.trigVolume/255.0);
end
else
- Sound.SetCoords(X+(Width div 2), Y+(Height div 2), Data.Volume/255.0);
+ Sound.SetCoords(X+(Width div 2), Y+(Height div 2), trigData.trigVolume/255.0);
end;
end;
diff --git a/src/game/g_gui.pas b/src/game/g_gui.pas
index 45b2364f8adba30e40aa89565fc3648bfd26e24a..d7735ab374d568a4e51cf47c543f1a2c458d7522 100644 (file)
--- a/src/game/g_gui.pas
+++ b/src/game/g_gui.pas
procedure TGUIMapPreview.SetMap(Res: string);
var
WAD: TWADFile;
- //MapReader: TMapReader_1;
- panels: TPanelsRec1Array;
- header: TMapHeaderRec_1;
- a: Integer;
+ panlist: TDynField;
+ pan: TDynRecord;
+ //header: TMapHeaderRec_1;
FileName: string;
Data: Pointer;
Len: Integer;
raise;
end;
- {
- MapReader := TMapReader_1.Create();
- if not MapReader.LoadMap(Data) then
- begin
- FreeMem(Data);
- MapReader.Free();
- FMapSize.X := 0;
- FMapSize.Y := 0;
- FScale := 0.0;
- FMapData := nil;
- Exit;
- end;
- }
-
FreeMem(Data);
- panels := GetPanels(map);
- header := GetMapHeader(map);
+ panlist := map.field['panel'];
+ //header := GetMapHeader(map);
- FMapSize.X := header.Width div 16;
- FMapSize.Y := header.Height div 16;
+ FMapSize.X := map.Width div 16;
+ FMapSize.Y := map.Height div 16;
- rX := Ceil(header.Width / (MAPPREVIEW_WIDTH*256.0));
- rY := Ceil(header.Height / (MAPPREVIEW_HEIGHT*256.0));
+ rX := Ceil(map.Width / (MAPPREVIEW_WIDTH*256.0));
+ rY := Ceil(map.Height / (MAPPREVIEW_HEIGHT*256.0));
FScale := max(rX, rY);
FMapData := nil;
- if panels <> nil then
- for a := 0 to High(panels) do
- if WordBool(panels[a].PanelType and (PANEL_WALL or PANEL_CLOSEDOOR or
+ if (panlist <> nil) then
+ begin
+ for pan in panlist do
+ begin
+ if (pan.PanelType and (PANEL_WALL or PANEL_CLOSEDOOR or
PANEL_STEP or PANEL_WATER or
- PANEL_ACID1 or PANEL_ACID2)) then
+ PANEL_ACID1 or PANEL_ACID2)) <> 0 then
begin
SetLength(FMapData, Length(FMapData)+1);
with FMapData[High(FMapData)] do
begin
- X1 := panels[a].X div 16;
- Y1 := panels[a].Y div 16;
+ X1 := pan.X div 16;
+ Y1 := pan.Y div 16;
- X2 := (panels[a].X + panels[a].Width) div 16;
- Y2 := (panels[a].Y + panels[a].Height) div 16;
+ X2 := (pan.X + pan.Width) div 16;
+ Y2 := (pan.Y + pan.Height) div 16;
X1 := Trunc(X1/FScale + 0.5);
Y1 := Trunc(Y1/FScale + 0.5);
Y2 := Y2 + 1;
end;
- PanelType := panels[a].PanelType;
+ PanelType := pan.PanelType;
+ end;
end;
- end;
-
- panels := nil;
+ end;
+ end;
- //MapReader.Free();
map.Free();
end;
diff --git a/src/game/g_main.pas b/src/game/g_main.pas
index 1b131f14e7bec2d12111b4487525f4a7232c5916..06e5ace8c04ede683e71ac4445ba8e019cc8df49 100644 (file)
--- a/src/game/g_main.pas
+++ b/src/game/g_main.pas
if gTriggers[a].TriggerType = TRIGGER_EXIT then
begin
gExitByTrigger := True;
- g_Game_ExitLevel(gTriggers[a].Data.MapName);
+ //g_Game_ExitLevel(gTriggers[a].Data.MapName);
+ g_Game_ExitLevel(gTriggers[a].trigData.trigMapName);
Break;
end;
goto Cheated;
diff --git a/src/game/g_map.pas b/src/game/g_map.pas
index 66d4e5696cbd19a3df29ab2d413d5f044bab1a0b..1695460c162e06e3b8b36e9c0f3b6b629390cc4a 100644 (file)
--- a/src/game/g_map.pas
+++ b/src/game/g_map.pas
profMapCollision: TProfiler = nil; //WARNING: FOR DEBUGGING ONLY!
gDrawPanelList: TBinaryHeapObj = nil; // binary heap of all walls we have to render, populated by `g_Map_CollectDrawPanels()`
+ gCurrentMap: TDynRecord = nil;
+
function panelTypeToTag (panelType: Word): Integer; // returns GridTagXXX
GL, GLExt, g_weapons, g_game, g_sound, e_sound, CONFIG,
g_options, g_triggers, g_player,
Math, g_monsters, g_saveload, g_language, g_netmsg,
- utils, sfs, xstreams,
+ utils, sfs, xstreams, hashtable,
ImagingTypes, Imaging, ImagingUtility,
ImagingGif, ImagingNetworkGraphics;
var
dfmapdef: TDynMapDef = nil;
-
procedure loadMapDefinition ();
var
pr: TTextParser = nil;
PanelArray := nil;
end;
-function CreatePanel(PanelRec: TPanelRec_1; AddTextures: TAddTextureArray;
+function CreatePanel(PanelRec: TDynRecord; AddTextures: TAddTextureArray;
CurTex: Integer; sav: Boolean): Integer;
var
len: Integer;
end;
end;
-procedure CreateItem(Item: TItemRec_1);
+procedure CreateItem(Item: TDynRecord);
begin
if g_Game_IsClient then Exit;
gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF, GM_COOP]);
end;
-procedure CreateArea(Area: TAreaRec_1);
+procedure CreateArea(Area: TDynRecord);
var
a: Integer;
id: DWORD = 0;
end;
end;
-procedure CreateTrigger(Trigger: TTriggerRec_1; fTexturePanel1Type, fTexturePanel2Type: Word);
+procedure CreateTrigger(Trigger: TDynRecord; atpanid, ashotpanid: Integer; fTexturePanel1Type, fTexturePanel2Type: Word);
var
_trigger: TTrigger;
begin
TriggerType := Trigger.TriggerType;
ActivateType := Trigger.ActivateType;
Keys := Trigger.Keys;
- Data.Default := Trigger.DATA;
+ trigPanelId := atpanid;
+ trigShotPanelId := ashotpanid;
+ //Data.Default := Trigger.DATA;
+ trigData := Trigger.trigRec.clone();
end;
g_Triggers_Create(_trigger);
end;
-procedure CreateMonster(monster: TMonsterRec_1);
+procedure CreateMonster(monster: TDynRecord);
var
a: Integer;
mon: TMonster;
begin
if gTriggers[a].TriggerType in [TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then
begin
- if (gTriggers[a].Data.MonsterID-1) = mon.StartID then mon.AddTrigger(a);
+ //if (gTriggers[a].Data.MonsterID-1) = Integer(mon.StartID) then mon.AddTrigger(a);
+ if (gTriggers[a].trigData.trigMonsterId) = Integer(mon.StartID) then mon.AddTrigger(a);
end;
end;
end;
begin
if gTriggers[a].TriggerType in [TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then
begin
- if (gTriggers[a].Data.MonsterID-1) = mon.StartID then mon.AddTrigger(a);
+ //if (gTriggers[a].Data.MonsterID-1) = Integer(mon.StartID) then mon.AddTrigger(a);
+ if (gTriggers[a].trigData.trigMonsterId) = Integer(mon.StartID) then mon.AddTrigger(a);
end;
end;
end;
end;
procedure generateExternalResourcesList({mapReader: TMapReader_1}map: TDynRecord);
-var
- textures: TTexturesRec1Array;
- mapHeader: TMapHeaderRec_1;
- i: integer;
- resFile: String = '';
+//var
+ //textures: TTexturesRec1Array;
+ //textures: TDynField;
+ //trec: TDynRecord;
+ //mapHeader: TMapHeaderRec_1;
+ //i: integer;
+ //resFile: String = '';
begin
if gExternalResources = nil then
gExternalResources := TStringList.Create;
gExternalResources.Clear;
+
+ (*
+ {
textures := GetTextures(map);
for i := 0 to High(textures) do
begin
addResToExternalResList(resFile);
end;
+ }
+
+ textures := map['texture'];
+ if (textures <> nil) then
+ begin
+ for trec in textures do
+ begin
+ addResToExternalResList(resFile);
+ end;
+ end;
textures := nil;
+ *)
- mapHeader := GetMapHeader(map);
+ //mapHeader := GetMapHeader(map);
- addResToExternalResList(mapHeader.MusicName);
- addResToExternalResList(mapHeader.SkyName);
+ addResToExternalResList(map.MusicName);
+ addResToExternalResList(map.SkyName);
end;
const
DefaultMusRes = 'Standart.wad:STDMUS\MUS1';
DefaultSkyRes = 'Standart.wad:STDSKY\SKY0';
+type
+ PTRec = ^TTRec;
+ TTRec = record
+ //TexturePanel: Integer;
+ texPanIdx: Integer;
+ LiftPanelIdx: Integer;
+ DoorPanelIdx: Integer;
+ ShotPanelIdx: Integer;
+ trigrec: TDynRecord;
+ texPan: TDynRecord;
+ liftPan: TDynRecord;
+ doorPan: TDynRecord;
+ shotPan: TDynRecord;
+ end;
var
WAD: TWADFile;
//MapReader: TMapReader_1;
mapReader: TDynRecord = nil;
- Header: TMapHeaderRec_1;
- _textures: TTexturesRec1Array;
- _texnummap: array of Integer; // `_textures` -> `Textures`
- panels: TPanelsRec1Array;
- items: TItemsRec1Array;
- monsters: TMonsterRec1Array;
- areas: TAreasRec1Array;
- triggers: TTriggersRec1Array;
- a, b, c, k: Integer;
+ //Header: TMapHeaderRec_1;
+ _textures: TDynField = nil; //TTexturesRec1Array; tagInt: texture index
+ //_texnummap: array of Integer = nil; // `_textures` -> `Textures`
+ panels: TDynField = nil; //TPanelsRec1Array;
+ items: TDynField = nil; //TItemsRec1Array;
+ monsters: TDynField = nil; //TMonsterRec1Array;
+ areas: TDynField = nil; //TAreasRec1Array;
+ triggers: TDynField = nil; //TTriggersRec1Array;
+ b, c, k: Integer;
PanelID: DWORD;
AddTextures: TAddTextureArray;
- texture: TTextureRec_1;
- TriggersTable: Array of record
- TexturePanel: Integer;
- LiftPanel: Integer;
- DoorPanel: Integer;
- ShotPanel: Integer;
- end;
+ //texture: TTextureRec_1;
+ TriggersTable: array of TTRec;
FileName, mapResName, s, TexName: String;
Data: Pointer;
Len: Integer;
ok, isAnim, trigRef: Boolean;
CurTex, ntn: Integer;
+ rec, texrec: TDynRecord;
+ pttit: PTRec;
+ pannum, trignum, cnt: Integer;
+ // key: panel index; value: `TriggersTable` index
+ hashTextPan: THashIntInt = nil;
+ hashLiftPan: THashIntInt = nil;
+ hashDoorPan: THashIntInt = nil;
+ hashShotPan: THashIntInt = nil;
begin
mapGrid.Free();
mapGrid := nil;
+ gCurrentMap.Free();
+ gCurrentMap := nil;
+
Result := False;
gMapInfo.Map := Res;
TriggersTable := nil;
- FillChar(texture, SizeOf(texture), 0);
+ mapReader := nil;
+ //FillChar(texture, SizeOf(texture), 0);
sfsGCDisable(); // temporary disable removing of temporary volumes
try
- // Çàãðóçêà WAD:
+ // Çàãðóçêà WAD:
FileName := g_ExtractWadName(Res);
e_WriteLog('Loading map WAD: '+FileName, MSG_NOTIFY);
g_Game_SetLoadingText(_lc[I_LOAD_WAD_FILE], 0, False);
e_LogWritefln('Loading map: %s', [mapResName], MSG_NOTIFY);
g_Game_SetLoadingText(_lc[I_LOAD_MAP], 0, False);
- {
- if (PChar(Data)[0] = 'M') and (PChar(Data)[1] = 'A') and (PChar(Data)[2] = 'P') and (PByte(Data)[3] = 1) then
- begin
- // nothing
- end
- else
- begin
- e_LogWritefln('Loading text map: %s', [mapResName]);
- loadMapDefinition();
- if (dfmapdef = nil) then raise Exception.Create('internal map loader error');
- //e_LogWritefln('***'#10'%s'#10'***', [dfmapdef.headerType.definition]);
- wst := TSFSMemoryChunkStream.Create(Data, Len);
- try
- pr := TFileTextParser.Create(wst);
- e_LogWritefln('parsing text map: %s', [mapResName]);
- rec := dfmapdef.parseMap(pr);
- except on e: Exception do
- begin
- if (pr <> nil) then e_LogWritefln('ERROR at (%s,%s): %s', [pr.line, pr.col, e.message])
- else e_LogWritefln('ERROR: %s', [e.message]);
- pr.Free();
- wst.Free();
- FreeMem(Data);
- exit;
- end;
- end;
- pr.Free();
- //wst.Free(); // pr will do it
- e_LogWritefln('writing text map to temporary bin storage...', []);
- st := TMemoryStream.Create();
- try
- rec.writeBinTo(st);
- Len := Integer(st.position);
- st.position := 0;
- FreeMem(Data);
- GetMem(Data, Len);
- st.ReadBuffer(Data^, Len);
- except on e: Exception do
- begin
- rec.Free();
- st.Free();
- e_LogWritefln('ERROR: %s', [e.message]);
- FreeMem(Data);
- exit;
- end;
- end;
- st.Free();
- end;
- }
try
mapReader := g_Map_ParseMap(Data, Len);
except
mapReader.Free();
g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Res]));
FreeMem(Data);
- MapReader.Free();
- Exit;
- end;
-
- {
- MapReader := TMapReader_1.Create();
- if not MapReader.LoadMap(Data) then
- begin
- g_FatalError(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Res]));
- FreeMem(Data);
- MapReader.Free();
Exit;
end;
- }
FreeMem(Data);
- generateExternalResourcesList(MapReader);
- // Çàãðóçêà òåêñòóð:
- g_Game_SetLoadingText(_lc[I_LOAD_TEXTURES], 0, False);
- _textures := GetTextures(mapReader);
- _texnummap := nil;
- // Çàãðóçêà îïèñàíèÿ êàðòû:
+ hashTextPan := hashNewIntInt();
+ hashLiftPan := hashNewIntInt();
+ hashDoorPan := hashNewIntInt();
+ hashShotPan := hashNewIntInt();
+
+ generateExternalResourcesList(MapReader);
+ //_textures := GetTextures(mapReader);
+ _textures := mapReader['texture'];
+ //_texnummap := nil;
+ // get all other lists here too
+ //panels := GetPanels(mapReader);
+ panels := mapReader['panel'];
+ //triggers := GetTriggers(mapReader);
+ triggers := mapReader['trigger'];
+ //items := GetItems(mapReader);
+ items := mapReader['item'];
+ //areas := GetAreas(mapReader);
+ areas := mapReader['area'];
+ //monsters := GetMonsters(mapReader);
+ monsters := mapReader['monster'];
+
+ // Çàãðóçêà îïèñàíèÿ êàðòû:
e_WriteLog(' Reading map info...', MSG_NOTIFY);
g_Game_SetLoadingText(_lc[I_LOAD_MAP_HEADER], 0, False);
- Header := GetMapHeader(mapReader);
+ //Header := GetMapHeader(mapReader);
with gMapInfo do
begin
- Name := Header.MapName;
- Description := Header.MapDescription;
- Author := Header.MapAuthor;
- MusicName := Header.MusicName;
- SkyName := Header.SkyName;
- Height := Header.Height;
- Width := Header.Width;
+ Name := mapReader.MapName;
+ Description := mapReader.MapDesc;
+ Author := mapReader.MapAuthor;
+ MusicName := mapReader.MusicName;
+ SkyName := mapReader.SkyName;
+ Height := mapReader.Height;
+ Width := mapReader.Width;
end;
- // Äîáàâëåíèå òåêñòóð â Textures[]:
- if _textures <> nil then
+ // Çàãðóçêà òåêñòóð:
+ g_Game_SetLoadingText(_lc[I_LOAD_TEXTURES], 0, False);
+ // Äîáàâëåíèå òåêñòóð â Textures[]:
+ if (_textures <> nil) and (_textures.count > 0) then
begin
e_WriteLog(' Loading textures:', MSG_NOTIFY);
- g_Game_SetLoadingText(_lc[I_LOAD_TEXTURES], High(_textures), False);
- SetLength(_texnummap, length(_textures));
+ g_Game_SetLoadingText(_lc[I_LOAD_TEXTURES], _textures.count-1, False);
+ //SetLength(_texnummap, _textures.count);
- for a := 0 to High(_textures) do
+ cnt := -1;
+ for rec in _textures do
begin
- SetLength(s, 64);
- CopyMemory(@s[1], @_textures[a].Resource[0], 64);
- for b := 1 to Length(s) do
- begin
- if s[b] = #0 then
- begin
- SetLength(s, b-1);
- Break;
- end;
- end;
+ Inc(cnt);
+ s := rec.Resource;
{$IF DEFINED(D2F_DEBUG_TXLOAD)}
- e_WriteLog(Format(' Loading texture #%d: %s', [a, s]), MSG_NOTIFY);
+ e_WriteLog(Format(' Loading texture #%d: %s', [cnt, s]), MSG_NOTIFY);
{$ENDIF}
//if g_Map_IsSpecialTexture(s) then e_WriteLog(' SPECIAL!', MSG_NOTIFY);
- // Àíèìèðîâàííàÿ òåêñòóðà:
- if ByteBool(_textures[a].Anim) then
- begin
- ntn := CreateAnimTexture(_textures[a].Resource, FileName, True);
- if ntn < 0 then
- begin
- g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_ANIM], [s]));
- ntn := CreateNullTexture(_textures[a].Resource);
- end;
- end
- else // Îáû÷íàÿ òåêñòóðà:
- ntn := CreateTexture(_textures[a].Resource, FileName, True);
- if ntn < 0 then
- begin
- g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_SIMPLE], [s]));
- ntn := CreateNullTexture(_textures[a].Resource);
- end;
+ if rec.Anim then
+ begin
+ // Àíèìèðîâàííàÿ òåêñòóðà
+ ntn := CreateAnimTexture(rec.Resource, FileName, True);
+ if (ntn < 0) then g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_ANIM], [s]));
+ end
+ else
+ begin
+ // Îáû÷íàÿ òåêñòóðà
+ ntn := CreateTexture(rec.Resource, FileName, True);
+ if (ntn < 0) then g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_SIMPLE], [s]));
+ end;
+ if (ntn < 0) then ntn := CreateNullTexture(rec.Resource);
- _texnummap[a] := ntn; // fix texture number
+ //_texnummap[a] := ntn; // fix texture number
+ rec.tagInt := ntn;
g_Game_StepLoading();
end;
+
+ // set panel tagInt to texture index
+ if (panels <> nil) then
+ begin
+ for rec in panels do
+ begin
+ texrec := rec.TextureRec;
+ if (texrec = nil) then rec.tagInt := -1 else rec.tagInt := texrec.tagInt;
+ end;
+ end;
end;
- // Çàãðóçêà òðèããåðîâ:
+ // Çàãðóçêà òðèããåðîâ
gTriggerClientID := 0;
e_WriteLog(' Loading triggers...', MSG_NOTIFY);
g_Game_SetLoadingText(_lc[I_LOAD_TRIGGERS], 0, False);
- triggers := GetTriggers(mapReader);
- // Çàãðóçêà ïàíåëåé:
+ // Çàãðóçêà ïàíåëåé
e_WriteLog(' Loading panels...', MSG_NOTIFY);
g_Game_SetLoadingText(_lc[I_LOAD_PANELS], 0, False);
- panels := GetPanels(mapReader);
// check texture numbers for panels
- for a := 0 to High(panels) do
+ if (panels <> nil) and (panels.count > 0) then
begin
- if panels[a].TextureNum > High(_textures) then
+ for rec in panels do
begin
- e_WriteLog('error loading map: invalid texture index for panel', MSG_FATALERROR);
- result := false;
- exit;
+ if (rec.tagInt < 0) then
+ begin
+ e_WriteLog('error loading map: invalid texture index for panel', MSG_FATALERROR);
+ result := false;
+ exit;
+ end;
end;
- panels[a].TextureNum := _texnummap[panels[a].TextureNum];
end;
- // Ñîçäàíèå òàáëèöû òðèããåðîâ (ñîîòâåòñòâèå ïàíåëåé òðèããåðàì):
- if triggers <> nil then
+ // Ñîçäàíèå òàáëèöû òðèããåðîâ (ñîîòâåòñòâèå ïàíåëåé òðèããåðàì)
+ if (triggers <> nil) and (triggers.count > 0) then
begin
e_WriteLog(' Setting up trigger table...', MSG_NOTIFY);
- SetLength(TriggersTable, Length(triggers));
- g_Game_SetLoadingText(_lc[I_LOAD_TRIGGERS_TABLE], High(TriggersTable), False);
+ //SetLength(TriggersTable, triggers.count);
+ g_Game_SetLoadingText(_lc[I_LOAD_TRIGGERS_TABLE], triggers.count-1, False);
- for a := 0 to High(TriggersTable) do
+ for rec in triggers do
begin
- // Ñìåíà òåêñòóðû (âîçìîæíî, êíîïêè):
- TriggersTable[a].TexturePanel := triggers[a].TexturePanel;
- // Ëèôòû:
- if triggers[a].TriggerType in [TRIGGER_LIFTUP, TRIGGER_LIFTDOWN, TRIGGER_LIFT] then
- TriggersTable[a].LiftPanel := TTriggerData(triggers[a].DATA).PanelID
- else
- TriggersTable[a].LiftPanel := -1;
- // Äâåðè:
- if triggers[a].TriggerType in [TRIGGER_OPENDOOR,
- TRIGGER_CLOSEDOOR, TRIGGER_DOOR, TRIGGER_DOOR5,
- TRIGGER_CLOSETRAP, TRIGGER_TRAP] then
- TriggersTable[a].DoorPanel := TTriggerData(triggers[a].DATA).PanelID
- else
- TriggersTable[a].DoorPanel := -1;
- // Òóðåëü:
- if triggers[a].TriggerType = TRIGGER_SHOT then
- TriggersTable[a].ShotPanel := TTriggerData(triggers[a].DATA).ShotPanelID
- else
- TriggersTable[a].ShotPanel := -1;
+ SetLength(TriggersTable, Length(TriggersTable)+1);
+ pttit := @TriggersTable[High(TriggersTable)];
+ pttit.trigrec := rec;
+ pttit.texPan := mapReader.panel[rec.TexturePanel];
+ pttit.liftPan := nil;
+ pttit.doorPan := nil;
+ pttit.shotPan := nil;
+ pttit.texPanIdx := -1;
+ pttit.LiftPanelIdx := -1;
+ pttit.DoorPanelIdx := -1;
+ pttit.ShotPanelIdx := -1;
+ // Ñìåíà òåêñòóðû (âîçìîæíî, êíîïêè)
+ //if (rec.TexturePanel >= 0) and (pttit.texPan = nil) then e_WriteLog('error loading map: invalid texture panel index for trigger', MSG_WARNING);
+ // Ëèôòû
+ if rec.TriggerType in [TRIGGER_LIFTUP, TRIGGER_LIFTDOWN, TRIGGER_LIFT] then
+ begin
+ //pttit.LiftPanel := TTriggerData(rec.DATA).PanelID
+ pttit.liftPan := mapReader.panel[rec.trigRec.tgPanelID];
+ //if (rec.trigRec.trigPanelID >= 0) and (pttit.liftPan = nil) then e_WriteLog('error loading map: invalid lift panel index for trigger', MSG_WARNING);
+ end;
+ // Äâåðè
+ if rec.TriggerType in [TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR, TRIGGER_DOOR, TRIGGER_DOOR5, TRIGGER_CLOSETRAP, TRIGGER_TRAP] then
+ begin
+ //pttit.DoorPanel := TTriggerData(rec.DATA).PanelID
+ pttit.doorPan := mapReader.panel[rec.trigRec.tgPanelID];
+ end;
+ // Òóðåëü
+ if (rec.TriggerType = TRIGGER_SHOT) then
+ begin
+ //pttit.ShotPanel := TTriggerData(rec.DATA).ShotPanelID
+ pttit.shotPan := mapReader.panel[rec.trigRec.tgShotPanelID];
+ end;
+
+ // update hashes
+ if (pttit.texPan <> nil) then hashTextPan.put(rec.TexturePanel, High(TriggersTable));
+ if (pttit.liftPan <> nil) then hashLiftPan.put(rec.trigRec.tgPanelID, High(TriggersTable));
+ if (pttit.doorPan <> nil) then hashDoorPan.put(rec.trigRec.tgPanelID, High(TriggersTable));
+ if (pttit.shotPan <> nil) then hashShotPan.put(rec.trigRec.tgShotPanelID, High(TriggersTable));
g_Game_StepLoading();
end;
end;
- // Ñîçäàåì ïàíåëè:
- if panels <> nil then
+ // Ñîçäàåì ïàíåëè
+ if (panels <> nil) and (panels.count > 0) then
begin
e_WriteLog(' Setting up trigger links...', MSG_NOTIFY);
- g_Game_SetLoadingText(_lc[I_LOAD_LINK_TRIGGERS], High(panels), False);
+ g_Game_SetLoadingText(_lc[I_LOAD_LINK_TRIGGERS], panels.count-1, False);
- for a := 0 to High(panels) do
+ pannum := -1;
+ for rec in panels do
begin
+ Inc(pannum);
+ texrec := nil;
SetLength(AddTextures, 0);
trigRef := False;
CurTex := -1;
- if _textures <> nil then
- begin
- texture := _textures[panels[a].TextureNum];
- ok := True;
- end
- else
- ok := False;
+ ok := false;
+
+ if (_textures <> nil) then
+ begin
+ texrec := rec.TextureRec;
+ ok := (texrec <> nil);
+ end;
if ok then
begin
- // Ñìîòðèì, ññûëàþòñÿ ëè íà ýòó ïàíåëü òðèããåðû.
- // Åñëè äà - òî íàäî ñîçäàòü åùå òåêñòóð:
- ok := False;
+ // Ñìîòðèì, ññûëàþòñÿ ëè íà ýòó ïàíåëü òðèããåðû.
+ // Åñëè äà - òî íàäî ñîçäàòü åùå òåêñòóð
+ ok := false;
if (TriggersTable <> nil) and (_textures <> nil) then
+ begin
for b := 0 to High(TriggersTable) do
- if (TriggersTable[b].TexturePanel = a)
- or (TriggersTable[b].ShotPanel = a) then
+ begin
+ if (TriggersTable[b].texPan = rec) or (TriggersTable[b].shotPan = rec) then
begin
trigRef := True;
ok := True;
- Break;
+ break;
end;
+ end;
+ end;
end;
if ok then
- begin // Åñòü ññûëêè òðèããåðîâ íà ýòó ïàíåëü
- SetLength(s, 64);
- CopyMemory(@s[1], @texture.Resource[0], 64);
- // Èçìåðÿåì äëèíó:
- Len := Length(s);
- for c := Len downto 1 do
- if s[c] <> #0 then
- begin
- Len := c;
- Break;
- end;
- SetLength(s, Len);
+ begin
+ // Åñòü ññûëêè òðèããåðîâ íà ýòó ïàíåëü
+ s := texrec.Resource;
- // Ñïåö-òåêñòóðû çàïðåùåíû:
+ // Ñïåö-òåêñòóðû çàïðåùåíû
if g_Map_IsSpecialTexture(s) then
- ok := False
+ begin
+ ok := false
+ end
else
- // Îïðåäåëÿåì íàëè÷èå è ïîëîæåíèå öèôð â êîíöå ñòðîêè:
+ begin
+ // Îïðåäåëÿåì íàëè÷èå è ïîëîæåíèå öèôð â êîíöå ñòðîêè
ok := g_Texture_NumNameFindStart(s);
+ end;
- // Åñëè ok, çíà÷èò åñòü öèôðû â êîíöå.
- // Çàãðóæàåì òåêñòóðû ñ îñòàëüíûìè #:
+ // Åñëè ok, çíà÷èò åñòü öèôðû â êîíöå.
+ // Çàãðóæàåì òåêñòóðû ñ îñòàëüíûìè #
if ok then
begin
k := NNF_NAME_BEFORE;
- // Öèêë ïî èçìåíåíèþ èìåíè òåêñòóðû:
- while ok or (k = NNF_NAME_BEFORE) or
- (k = NNF_NAME_EQUALS) do
+ // Öèêë ïî èçìåíåíèþ èìåíè òåêñòóðû
+ while ok or (k = NNF_NAME_BEFORE) or (k = NNF_NAME_EQUALS) do
begin
k := g_Texture_NumNameFindNext(TexName);
- if (k = NNF_NAME_BEFORE) or
- (k = NNF_NAME_AFTER) then
+ if (k = NNF_NAME_BEFORE) or (k = NNF_NAME_AFTER) then
+ begin
+ // Ïðîáóåì äîáàâèòü íîâóþ òåêñòóðó
+ if texrec.Anim then
begin
- // Ïðîáóåì äîáàâèòü íîâóþ òåêñòóðó:
- if ByteBool(texture.Anim) then
- begin // Íà÷àëüíàÿ - àíèìèðîâàííàÿ, èùåì àíèìèðîâàííóþ
- isAnim := True;
- ok := CreateAnimTexture(TexName, FileName, False) >= 0;
- if not ok then
- begin // Íåò àíèìèðîâàííîé, èùåì îáû÷íóþ
- isAnim := False;
- ok := CreateTexture(TexName, FileName, False) >= 0;
- end;
- end
- else
- begin // Íà÷àëüíàÿ - îáû÷íàÿ, èùåì îáû÷íóþ
- isAnim := False;
- ok := CreateTexture(TexName, FileName, False) >= 0;
- if not ok then
- begin // Íåò îáû÷íîé, èùåì àíèìèðîâàííóþ
- isAnim := True;
- ok := CreateAnimTexture(TexName, FileName, False) >= 0;
- end;
- end;
-
- // Îíà ñóùåñòâóåò. Çàíîñèì åå ID â ñïèñîê ïàíåëè:
- if ok then
+ // Íà÷àëüíàÿ - àíèìèðîâàííàÿ, èùåì àíèìèðîâàííóþ
+ isAnim := True;
+ ok := CreateAnimTexture(TexName, FileName, False) >= 0;
+ if not ok then
begin
- for c := 0 to High(Textures) do
- if Textures[c].TextureName = TexName then
- begin
- SetLength(AddTextures, Length(AddTextures)+1);
- AddTextures[High(AddTextures)].Texture := c;
- AddTextures[High(AddTextures)].Anim := isAnim;
- Break;
- end;
+ // Íåò àíèìèðîâàííîé, èùåì îáû÷íóþ
+ isAnim := False;
+ ok := CreateTexture(TexName, FileName, False) >= 0;
end;
end
+ else
+ begin
+ // Íà÷àëüíàÿ - îáû÷íàÿ, èùåì îáû÷íóþ
+ isAnim := False;
+ ok := CreateTexture(TexName, FileName, False) >= 0;
+ if not ok then
+ begin
+ // Íåò îáû÷íîé, èùåì àíèìèðîâàííóþ
+ isAnim := True;
+ ok := CreateAnimTexture(TexName, FileName, False) >= 0;
+ end;
+ end;
+
+ // Îíà ñóùåñòâóåò. Çàíîñèì åå ID â ñïèñîê ïàíåëè
+ if ok then
+ begin
+ for c := 0 to High(Textures) do
+ begin
+ if (Textures[c].TextureName = TexName) then
+ begin
+ SetLength(AddTextures, Length(AddTextures)+1);
+ AddTextures[High(AddTextures)].Texture := c;
+ AddTextures[High(AddTextures)].Anim := isAnim;
+ break;
+ end;
+ end;
+ end;
+ end
else
+ begin
if k = NNF_NAME_EQUALS then
- begin
- // Çàíîñèì òåêóùóþ òåêñòóðó íà ñâîå ìåñòî:
- SetLength(AddTextures, Length(AddTextures)+1);
- AddTextures[High(AddTextures)].Texture := panels[a].TextureNum;
- AddTextures[High(AddTextures)].Anim := ByteBool(texture.Anim);
- CurTex := High(AddTextures);
- ok := True;
- end
+ begin
+ // Çàíîñèì òåêóùóþ òåêñòóðó íà ñâîå ìåñòî
+ SetLength(AddTextures, Length(AddTextures)+1);
+ //AddTextures[High(AddTextures)].Texture := _texnummap[rec.TextureNum]; //panels[a].TextureNum;
+ AddTextures[High(AddTextures)].Texture := rec.tagInt; //panels[a].TextureNum;
+ AddTextures[High(AddTextures)].Anim := texrec.Anim;
+ CurTex := High(AddTextures);
+ ok := true;
+ end
else // NNF_NO_NAME
- ok := False;
+ begin
+ ok := false;
+ end;
+ end;
end; // while ok...
- ok := True;
+ ok := true;
end; // if ok - åñòü ñìåæíûå òåêñòóðû
end; // if ok - ññûëàþòñÿ òðèããåðû
if not ok then
begin
- // Çàíîñèì òîëüêî òåêóùóþ òåêñòóðó:
+ // Çàíîñèì òîëüêî òåêóùóþ òåêñòóðó
SetLength(AddTextures, 1);
- AddTextures[0].Texture := panels[a].TextureNum;
- AddTextures[0].Anim := ByteBool(texture.Anim);
+ AddTextures[0].Texture := rec.tagInt; //panels[a].TextureNum;
+ AddTextures[0].Anim := false;
+ if (texrec <> nil) then AddTextures[0].Anim := texrec.Anim;
CurTex := 0;
end;
//e_WriteLog(Format('panel #%d: TextureNum=%d; ht=%d; ht1=%d; atl=%d', [a, panels[a].TextureNum, High(_textures), High(Textures), High(AddTextures)]), MSG_NOTIFY);
- // Ñîçäàåì ïàíåëü è çàïîìèíàåì åå íîìåð:
- PanelID := CreatePanel(panels[a], AddTextures, CurTex, trigRef);
+ // Ñîçäàåì ïàíåëü è çàïîìèíàåì åå íîìåð
+ PanelID := CreatePanel(rec, AddTextures, CurTex, trigRef);
+ //e_LogWritefln('panel #%s of type %s got id #%s', [pannum, rec.PanelType, PanelID]);
- // Åñëè èñïîëüçóåòñÿ â òðèããåðàõ, òî ñòàâèì òî÷íûé ID:
- if TriggersTable <> nil then
+ // Åñëè èñïîëüçóåòñÿ â òðèããåðàõ, òî ñòàâèì òî÷íûé ID
+ if hashTextPan.get(pannum, b) then TriggersTable[b].texPanIdx := PanelID;
+ if hashLiftPan.get(pannum, b) then TriggersTable[b].LiftPanelIdx := PanelID;
+ if hashDoorPan.get(pannum, b) then TriggersTable[b].DoorPanelIdx := PanelID;
+ if hashShotPan.get(pannum, b) then TriggersTable[b].ShotPanelIdx := PanelID;
+
+ (*
+ if (TriggersTable <> nil) then
+ begin
for b := 0 to High(TriggersTable) do
begin
- // Òðèããåð äâåðè/ëèôòà:
- if (TriggersTable[b].LiftPanel = a) or
- (TriggersTable[b].DoorPanel = a) then
- TTriggerData(triggers[b].DATA).PanelID := PanelID;
- // Òðèããåð ñìåíû òåêñòóðû:
- if TriggersTable[b].TexturePanel = a then
- triggers[b].TexturePanel := PanelID;
- // Òðèããåð "Òóðåëü":
- if TriggersTable[b].ShotPanel = a then
- TTriggerData(triggers[b].DATA).ShotPanelID := PanelID;
+ if (TriggersTable[b].texPan = rec) then TriggersTable[b].texPanIdx := PanelID;
+ if (TriggersTable[b].liftPan = rec) then TriggersTable[b].LiftPanelIdx := PanelID;
+ if (TriggersTable[b].doorPan = rec) then TriggersTable[b].DoorPanelIdx := PanelID;
+ if (TriggersTable[b].shotPan = rec) then TriggersTable[b].ShotPanelIdx := PanelID;
+ {
+ // Òðèããåð äâåðè/ëèôòà
+ if (TriggersTable[b].LiftPanel = pannum) or
+ (TriggersTable[b].DoorPanel = pannum) then
+ //TTriggerData(TriggersTable[b].trigrec.DATA).PanelID := PanelID;
+ TriggersTable[b].trigrec.trigRec.trigPanelID := PanelID;
+ // Òðèããåð ñìåíû òåêñòóðû
+ if TriggersTable[b].texPanIdx = pannum then
+ TriggersTable[b].trigrec.TexturePanel := PanelID;
+ // Òðèããåð "Òóðåëü"
+ if TriggersTable[b].ShotPanel = pannum then
+ TriggersTable[b].trigrec.trigRec.trigShotPanelID := PanelID;
+ }
end;
+ end;
+ *)
g_Game_StepLoading();
end;
end;
+ (*
+ begin
+ for b := 0 to High(TriggersTable) do
+ begin
+ // Òðèããåð äâåðè/ëèôòà
+ if (TriggersTable[b].texPan <> nil) then e_LogWritefln('trigger #%s: textPan=%s; panidx=%s', [b, TriggersTable[b].texPanIdx, mapReader.panelIndex[TriggersTable[b].texPan]]);
+ if (TriggersTable[b].liftPan <> nil) then e_LogWritefln('trigger #%s: liftPan=%s; panidx=%s', [b, TriggersTable[b].LiftPanelIdx, mapReader.panelIndex[TriggersTable[b].liftPan]]);
+ if (TriggersTable[b].doorPan <> nil) then e_LogWritefln('trigger #%s: doorPan=%s; panidx=%s', [b, TriggersTable[b].DoorPanelIdx, mapReader.panelIndex[TriggersTable[b].doorPan]]);
+ if (TriggersTable[b].shotPan <> nil) then e_LogWritefln('trigger #%s: shotPan=%s; panidx=%s', [b, TriggersTable[b].ShotPanelIdx, mapReader.panelIndex[TriggersTable[b].shotPan]]);
+ end;
+ end;
+ *)
+
// create map grid, init other grids (for monsters, for example)
e_WriteLog('Creating map grid', MSG_NOTIFY);
mapCreateGrid();
- // Åñëè íå LoadState, òî ñîçäàåì òðèããåðû:
- if (triggers <> nil) and not gLoadGameMode then
+ // Åñëè íå LoadState, òî ñîçäàåì òðèããåðû
+ if (triggers <> nil) and (panels <> nil) and (not gLoadGameMode) then
begin
- e_LogWritefln(' Creating triggers (%d)...', [Length(triggers)]);
+ e_LogWritefln(' Creating triggers (%d)...', [triggers.count]);
g_Game_SetLoadingText(_lc[I_LOAD_CREATE_TRIGGERS], 0, False);
- // Óêàçûâàåì òèï ïàíåëè, åñëè åñòü:
- for a := 0 to High(triggers) do
+ // Óêàçûâàåì òèï ïàíåëè, åñëè åñòü
+ trignum := -1;
+ for rec in triggers do
begin
- if (triggers[a].TexturePanel <> -1) then
+ Inc(trignum);
+ if (TriggersTable[trignum].texPan <> nil) then b := TriggersTable[trignum].texPan.PanelType else b := 0;
+ if (TriggersTable[trignum].shotPan <> nil) then c := TriggersTable[trignum].shotPan.PanelType else c := 0;
+ (*
+ if (rec.TexturePanel <> -1) then
begin
- if (TriggersTable[a].TexturePanel < 0) or (TriggersTable[a].TexturePanel > High(panels)) then
+ {
+ if (TriggersTable[trignum].TexturePanel < 0) or (TriggersTable[trignum].TexturePanel >= panels.count) then
begin
e_WriteLog('error loading map: invalid panel index for trigger', MSG_FATALERROR);
result := false;
exit;
end;
- b := panels[TriggersTable[a].TexturePanel].PanelType;
+ }
+ //b := panels[TriggersTable[a].TexturePanel].PanelType;
+ //b := mapReader.panel[TriggersTable[trignum].texPanIdx].PanelType;
+ assert(TriggersTable[trignum].texPanIdx >= 0);
+ b := TriggersTable[trignum].texPanIdx;
end
else
begin
b := 0;
end;
- if (triggers[a].TriggerType = TRIGGER_SHOT) and (TTriggerData(triggers[a].DATA).ShotPanelID <> -1) then
+ e_LogWritefln('trigger #%s: type=%s; texPanIdx=%s; b=%s', [trignum, rec.TriggerType, TriggersTable[trignum].texPanIdx, b]);
+ if (rec.TriggerType = TRIGGER_SHOT) then e_LogWritefln(' SHOT: shotpanidx=%s', [rec.trigRec.trigShotPanelID]);
+ if (rec.TriggerType = TRIGGER_SHOT) and {(rec.trigRec.trigShotPanelID <> -1)} (TriggersTable[trignum].shotPan <> nil) then
begin
- c := panels[TriggersTable[a].ShotPanel].PanelType
+ //c := panels[TriggersTable[a].ShotPanel].PanelType;
+ //c := mapReader.panel[TriggersTable[trignum].ShotPanel].PanelType;
+ assert(TriggersTable[trignum].ShotPanelIdx >= 0);
+ c := TriggersTable[trignum].ShotPanelIdx;
end
else
begin
c := 0;
end;
- CreateTrigger(triggers[a], b, c);
+ *)
+ //e_LogWritefln('creating trigger #%s; texpantype=%s; shotpantype=%s (%d,%d)', [trignum, b, c, TriggersTable[trignum].texPanIdx, TriggersTable[trignum].ShotPanelIdx]);
+ CreateTrigger(rec, TriggersTable[trignum].texPanIdx, TriggersTable[trignum].ShotPanelIdx, Word(b), Word(c));
end;
end;
- // Çàãðóçêà ïðåäìåòîâ:
+ // Çàãðóçêà ïðåäìåòîâ
e_WriteLog(' Loading items...', MSG_NOTIFY);
g_Game_SetLoadingText(_lc[I_LOAD_ITEMS], 0, False);
- items := GetItems(mapReader);
- // Åñëè íå LoadState, òî ñîçäàåì ïðåäìåòû:
+ // Åñëè íå LoadState, òî ñîçäàåì ïðåäìåòû
if (items <> nil) and not gLoadGameMode then
begin
e_WriteLog(' Spawning items...', MSG_NOTIFY);
g_Game_SetLoadingText(_lc[I_LOAD_CREATE_ITEMS], 0, False);
- for a := 0 to High(items) do
- CreateItem(Items[a]);
+ for rec in items do CreateItem(rec);
end;
- // Çàãðóçêà îáëàñòåé:
+ // Çàãðóçêà îáëàñòåé
e_WriteLog(' Loading areas...', MSG_NOTIFY);
g_Game_SetLoadingText(_lc[I_LOAD_AREAS], 0, False);
- areas := GetAreas(mapReader);
- // Åñëè íå LoadState, òî ñîçäàåì îáëàñòè:
+ // Åñëè íå LoadState, òî ñîçäàåì îáëàñòè
if areas <> nil then
begin
e_WriteLog(' Creating areas...', MSG_NOTIFY);
g_Game_SetLoadingText(_lc[I_LOAD_CREATE_AREAS], 0, False);
- for a := 0 to High(areas) do
- CreateArea(areas[a]);
+ for rec in areas do CreateArea(rec);
end;
- // Çàãðóçêà ìîíñòðîâ:
+ // Çàãðóçêà ìîíñòðîâ
e_WriteLog(' Loading monsters...', MSG_NOTIFY);
g_Game_SetLoadingText(_lc[I_LOAD_MONSTERS], 0, False);
- monsters := GetMonsters(mapReader);
gTotalMonsters := 0;
- // Åñëè íå LoadState, òî ñîçäàåì ìîíñòðîâ:
+ // Åñëè íå LoadState, òî ñîçäàåì ìîíñòðîâ
if (monsters <> nil) and not gLoadGameMode then
begin
e_WriteLog(' Spawning monsters...', MSG_NOTIFY);
g_Game_SetLoadingText(_lc[I_LOAD_CREATE_MONSTERS], 0, False);
- for a := 0 to High(monsters) do
- CreateMonster(monsters[a]);
+ for rec in monsters do CreateMonster(rec);
end;
- MapReader.Free();
+ //MapReader.Free();
+ gCurrentMap := mapReader;
+ mapReader := nil;
- // Çàãðóçêà íåáà:
+ // Çàãðóçêà íåáà
if gMapInfo.SkyName <> '' then
begin
e_WriteLog(' Loading sky: ' + gMapInfo.SkyName, MSG_NOTIFY);
g_FatalError(Format(_lc[I_GAME_ERROR_SKY], [s]));
end;
- // Çàãðóçêà ìóçûêè:
+ // Çàãðóçêà ìóçûêè
ok := False;
if gMapInfo.MusicName <> '' then
begin
g_FatalError(Format(_lc[I_GAME_ERROR_MUSIC], [s]));
end;
- // Îñòàëüíûå óñòàíâêè:
+ // Îñòàëüíûå óñòàíâêè
CreateDoorMap();
CreateLiftMap();
g_Weapon_Init();
g_Monsters_Init();
- // Åñëè íå LoadState, òî ñîçäàåì êàðòó ñòîëêíîâåíèé:
- if not gLoadGameMode then
- g_GFX_Init();
+ // Åñëè íå LoadState, òî ñîçäàåì êàðòó ñòîëêíîâåíèé:
+ if not gLoadGameMode then g_GFX_Init();
- // Ñáðîñ ëîêàëüíûõ ìàññèâîâ:
+ // Ñáðîñ ëîêàëüíûõ ìàññèâîâ:
_textures := nil;
panels := nil;
items := nil;
TriggersTable := nil;
AddTextures := nil;
- // Âêëþ÷àåì ìóçûêó, åñëè ýòî íå çàãðóçêà:
+ // Âêëþ÷àåì ìóçûêó, åñëè ýòî íå çàãðóçêà:
if ok and (not gLoadGameMode) then
- begin
- gMusic.SetByName(gMapInfo.MusicName);
- gMusic.Play();
- end
+ begin
+ gMusic.SetByName(gMapInfo.MusicName);
+ gMusic.Play();
+ end
else
+ begin
gMusic.SetByName('');
+ end;
finally
sfsGCEnable(); // enable releasing unused volumes
+ mapReader.Free();
+ hashTextPan.Free();
+ hashLiftPan.Free();
+ hashDoorPan.Free();
+ hashShotPan.Free();
end;
e_WriteLog('Done loading map.', MSG_NOTIFY);
var
WAD: TWADFile;
MapReader: TDynRecord;
- Header: TMapHeaderRec_1;
+ //Header: TMapHeaderRec_1;
FileName: String;
Data: Pointer;
Len: Integer;
FreeMem(Data);
//MapReader.Free();
- if (mapReader <> nil) then Header := GetMapHeader(mapReader) else FillChar(Header, sizeof(Header), 0);
- MapReader.Free();
+ //if (mapReader <> nil) then Header := GetMapHeader(mapReader) else FillChar(Header, sizeof(Header), 0);
+ //MapReader.Free();
- if (Header.Width > 0) and (Header.Height > 0) then
+ if (mapReader.Width > 0) and (mapReader.Height > 0) then
begin
- Result.Name := Header.MapName;
- Result.Description := Header.MapDescription;
+ Result.Name := mapReader.MapName;
+ Result.Description := mapReader.MapDesc;
+ Result.Map := Res;
+ Result.Author := mapReader.MapAuthor;
+ Result.Height := mapReader.Height;
+ Result.Width := mapReader.Width;
end
else
begin
g_Console_Add(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Res]), True);
- ZeroMemory(@Header, SizeOf(Header));
+ //ZeroMemory(@Header, SizeOf(Header));
Result.Name := _lc[I_GAME_ERROR_MAP_SELECT];
Result.Description := _lc[I_GAME_ERROR_MAP_SELECT];
+ Result.Map := Res;
+ Result.Author := '';
+ Result.Height := 0;
+ Result.Width := 0;
end;
- Result.Map := Res;
- Result.Author := Header.MapAuthor;
- Result.Height := Header.Height;
- Result.Width := Header.Width;
+ mapReader.Free();
end;
function g_Map_GetMapsList(WADName: string): SArray;
diff --git a/src/game/g_netmsg.pas b/src/game/g_netmsg.pas
index 936141adbc58ee1d33acae7c7708b42ef064dcfe..f77bdcadd97dbafa8ea20c15c44e4f473ce80806 100644 (file)
--- a/src/game/g_netmsg.pas
+++ b/src/game/g_netmsg.pas
begin
if SPlaying then
begin
- if Data.Local then
- Sound.PlayVolumeAt(X+(Width div 2), Y+(Height div 2), Data.Volume/255.0)
+ if trigData.trigLocal then
+ Sound.PlayVolumeAt(X+(Width div 2), Y+(Height div 2), trigData.trigVolume/255.0)
else
- Sound.PlayPanVolume((Data.Pan-127.0)/128.0, Data.Volume/255.0);
+ Sound.PlayPanVolume((trigData.trigPan-127.0)/128.0, trigData.trigVolume/255.0);
Sound.SetPosition(SPos);
end
else
diff --git a/src/game/g_panel.pas b/src/game/g_panel.pas
index c46cf8c456d1f591698f72dc96593132c17680e0..5eec8e780a546456cf85a75a25c04b6160b08b62 100644 (file)
--- a/src/game/g_panel.pas
+++ b/src/game/g_panel.pas
interface
uses
- MAPDEF, BinEditor, g_textures;
+ MAPDEF, BinEditor, g_textures, xdynrec;
type
TAddTextureArray = Array of
tag: Integer; // used in coldets and such; sorry
proxyId: Integer; // proxy id in map grid (DO NOT USE!)
- constructor Create(PanelRec: TPanelRec_1;
+ constructor Create(PanelRec: TDynRecord;
AddTextures: TAddTextureArray;
CurTex: Integer;
var Textures: TLevelTextureArray);
{ T P a n e l : }
-constructor TPanel.Create(PanelRec: TPanelRec_1;
+constructor TPanel.Create(PanelRec: TDynRecord;
AddTextures: TAddTextureArray;
CurTex: Integer;
var Textures: TLevelTextureArray);
index c327fdb55c2afcd0257ec015562191cdcc0aade1..be680ecb8e9f7e4698e3d0648b135d4b737c3d54 100644 (file)
--- a/src/game/g_triggers.pas
+++ b/src/game/g_triggers.pas
uses
MAPDEF, e_graphics, g_basic, g_sound,
- BinEditor;
+ BinEditor, xdynrec;
type
TActivator = record
ShotAmmoCount: Word;
ShotReloadTime: Integer;
- Data: TTriggerData;
+ trigShotPanelId: Integer;
+ trigPanelId: Integer;
+
+ //TrigData: TTriggerData;
+ trigData: TDynRecord; // triggerdata; owned by trigger
end;
function g_Triggers_Create(Trigger: TTrigger): DWORD;
procedure MakeShot(var Trigger: TTrigger; wx, wy, dx, dy: Integer; TargetUID: Word);
begin
with Trigger do
- if (Data.ShotAmmo = 0) or
- ((Data.ShotAmmo > 0) and (ShotAmmoCount > 0)) then
+ if (trigData.trigShotAmmo = 0) or
+ ((trigData.trigShotAmmo > 0) and (ShotAmmoCount > 0)) then
begin
- if (Data.ShotPanelID <> -1) and (ShotPanelTime = 0) then
+ if (trigShotPanelID <> -1) and (ShotPanelTime = 0) then
begin
- g_Map_SwitchTexture(ShotPanelType, Data.ShotPanelID);
+ g_Map_SwitchTexture(ShotPanelType, trigShotPanelID);
ShotPanelTime := 4; // òèêîâ íà âñïûøêó âûñòðåëà
end;
- if Data.ShotIntSight > 0 then
+ if trigData.trigShotIntSight > 0 then
ShotSightTimeout := 180; // ~= 5 ñåêóíä
if ShotAmmoCount > 0 then Dec(ShotAmmoCount);
- dx := dx + Random(Data.ShotAccuracy) - Random(Data.ShotAccuracy);
- dy := dy + Random(Data.ShotAccuracy) - Random(Data.ShotAccuracy);
+ dx := dx + Random(trigData.trigShotAccuracy) - Random(trigData.trigShotAccuracy);
+ dy := dy + Random(trigData.trigShotAccuracy) - Random(trigData.trigShotAccuracy);
- tr_SpawnShot(Data.ShotType, wx, wy, dx, dy, Data.ShotSound, TargetUID);
+ tr_SpawnShot(trigData.trigShotType, wx, wy, dx, dy, trigData.trigShotSound, TargetUID);
end
else
- if (Data.ShotIntReload > 0) and (ShotReloadTime = 0) then
- ShotReloadTime := Data.ShotIntReload; // òèêîâ íà ïåðåçàðÿäêó ïóøêè
+ if (trigData.trigShotIntReload > 0) and (ShotReloadTime = 0) then
+ ShotReloadTime := trigData.trigShotIntReload; // òèêîâ íà ïåðåçàðÿäêó ïóøêè
end;
procedure tr_MakeEffect(X, Y, VX, VY: Integer; T, ST, CR, CG, CB: Byte; Silent, Send: Boolean);
begin
if TriggerType <> TRIGGER_SHOT then
Exit;
- Result := (Data.ShotAim and TRIGGER_SHOT_AIM_ALLMAP > 0)
+ Result := (trigData.trigShotAim and TRIGGER_SHOT_AIM_ALLMAP > 0)
or g_Obj_Collide(X, Y, Width, Height, Obj);
- if Result and (Data.ShotAim and TRIGGER_SHOT_AIM_TRACE > 0) then
- Result := g_TraceVector(Data.ShotPos.X,
- Data.ShotPos.Y,
+ if Result and (trigData.trigShotAim and TRIGGER_SHOT_AIM_TRACE > 0) then
+ Result := g_TraceVector(trigData.trigShotPos.X,
+ trigData.trigShotPos.Y,
Obj^.X + Obj^.Rect.X + (Obj^.Rect.Width div 2),
Obj^.Y + Obj^.Rect.Y + (Obj^.Rect.Height div 2));
end;
g_Sound_PlayEx('SOUND_GAME_SWITCH0');
if g_Game_IsNet then MH_SEND_Sound(X, Y, 'SOUND_GAME_SWITCH0');
gExitByTrigger := True;
- g_Game_ExitLevel(Data.MapName);
+ g_Game_ExitLevel(trigData.trigMapName);
TimeOut := 18;
Result := True;
TRIGGER_TELEPORT:
begin
Result := tr_Teleport(ActivateUID,
- Data.TargetPoint.X, Data.TargetPoint.Y,
- Data.TlpDir, Data.silent_teleport,
- Data.d2d_teleport);
+ trigData.trigTargetPoint.X, trigData.trigTargetPoint.Y,
+ trigData.trigTlpDir, trigData.trigsilent_teleport,
+ trigData.trigd2d_teleport);
TimeOut := 0;
end;
TRIGGER_OPENDOOR:
begin
- Result := tr_OpenDoor(Data.PanelID, Data.NoSound, Data.d2d_doors);
+ Result := tr_OpenDoor(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors);
TimeOut := 0;
end;
TRIGGER_CLOSEDOOR:
begin
- Result := tr_CloseDoor(Data.PanelID, Data.NoSound, Data.d2d_doors);
+ Result := tr_CloseDoor(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors);
TimeOut := 0;
end;
TRIGGER_DOOR, TRIGGER_DOOR5:
begin
- if Data.PanelID <> -1 then
+ if trigPanelID <> -1 then
begin
- if gWalls[Data.PanelID].Enabled then
+ if gWalls[trigPanelID].Enabled then
begin
- Result := tr_OpenDoor(Data.PanelID, Data.NoSound, Data.d2d_doors);
+ Result := tr_OpenDoor(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors);
if TriggerType = TRIGGER_DOOR5 then
DoorTime := 180;
end
else
- Result := tr_CloseDoor(Data.PanelID, Data.NoSound, Data.d2d_doors);
+ Result := tr_CloseDoor(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors);
if Result then
TimeOut := 18;
TRIGGER_CLOSETRAP, TRIGGER_TRAP:
begin
- tr_CloseTrap(Data.PanelID, Data.NoSound, Data.d2d_doors);
+ tr_CloseTrap(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors);
if TriggerType = TRIGGER_TRAP then
begin
PressCount := PressCount + 1;
if PressTime = -1 then
- PressTime := Data.Wait;
+ PressTime := trigData.trigWait;
if coolDown then
TimeOut := 18
TRIGGER_LIFTUP:
begin
- Result := tr_SetLift(Data.PanelID, 0, Data.NoSound, Data.d2d_doors);
+ Result := tr_SetLift(trigPanelID, 0, trigData.trigNoSound, trigData.trigd2d_doors);
TimeOut := 0;
- if (not Data.NoSound) and Result then begin
+ if (not trigData.trigNoSound) and Result then begin
g_Sound_PlayExAt('SOUND_GAME_SWITCH0',
X + (Width div 2),
Y + (Height div 2));
TRIGGER_LIFTDOWN:
begin
- Result := tr_SetLift(Data.PanelID, 1, Data.NoSound, Data.d2d_doors);
+ Result := tr_SetLift(trigPanelID, 1, trigData.trigNoSound, trigData.trigd2d_doors);
TimeOut := 0;
- if (not Data.NoSound) and Result then begin
+ if (not trigData.trigNoSound) and Result then begin
g_Sound_PlayExAt('SOUND_GAME_SWITCH0',
X + (Width div 2),
Y + (Height div 2));
TRIGGER_LIFT:
begin
- Result := tr_SetLift(Data.PanelID, 3, Data.NoSound, Data.d2d_doors);
+ Result := tr_SetLift(trigPanelID, 3, trigData.trigNoSound, trigData.trigd2d_doors);
if Result then
begin
TimeOut := 18;
- if (not Data.NoSound) and Result then begin
+ if (not trigData.trigNoSound) and Result then begin
g_Sound_PlayExAt('SOUND_GAME_SWITCH0',
X + (Width div 2),
Y + (Height div 2));
TRIGGER_TEXTURE:
begin
- if ByteBool(Data.ActivateOnce) then
+ if ByteBool(trigData.trigActivateOnce) then
begin
Enabled := False;
TriggerType := TRIGGER_NONE;
else
TimeOut := 0;
- animonce := Data.AnimOnce;
+ animonce := trigData.trigAnimOnce;
Result := True;
end;
begin
if Sound <> nil then
begin
- if Data.SoundSwitch and Sound.IsPlaying() then
+ if trigData.trigSoundSwitch and Sound.IsPlaying() then
begin // Íóæíî âûêëþ÷èòü, åñëè èãðàë
Sound.Stop();
SoundPlayCount := 0;
Result := True;
end
else // (not Data.SoundSwitch) or (not Sound.IsPlaying())
- if (Data.PlayCount > 0) or (not Sound.IsPlaying()) then
+ if (trigData.trigPlayCount > 0) or (not Sound.IsPlaying()) then
begin
- if Data.PlayCount > 0 then
- SoundPlayCount := Data.PlayCount
+ if trigData.trigPlayCount > 0 then
+ SoundPlayCount := trigData.trigPlayCount
else // 0 - èãðàåì áåñêîíå÷íî
SoundPlayCount := 1;
Result := True;
end;
TRIGGER_SPAWNMONSTER:
- if (Data.MonType in [MONSTER_DEMON..MONSTER_MAN]) then
+ if (trigData.trigMonType in [MONSTER_DEMON..MONSTER_MAN]) then
begin
Result := False;
- if (Data.MonDelay > 0) and (actType <> ACTIVATE_CUSTOM) then
+ if (trigData.trigMonDelay > 0) and (actType <> ACTIVATE_CUSTOM) then
begin
AutoSpawn := not AutoSpawn;
SpawnCooldown := 0;
Result := True;
end;
- if ((Data.MonDelay = 0) and (actType <> ACTIVATE_CUSTOM))
- or ((Data.MonDelay > 0) and (actType = ACTIVATE_CUSTOM)) then
- for k := 1 to Data.MonCount do
+ if ((trigData.trigMonDelay = 0) and (actType <> ACTIVATE_CUSTOM))
+ or ((trigData.trigMonDelay > 0) and (actType = ACTIVATE_CUSTOM)) then
+ for k := 1 to trigData.trigMonCount do
begin
- if (actType = ACTIVATE_CUSTOM) and (Data.MonDelay > 0) then
- SpawnCooldown := Data.MonDelay;
- if (Data.MonMax > 0) and (SpawnedCount >= Data.MonMax) then
+ if (actType = ACTIVATE_CUSTOM) and (trigData.trigMonDelay > 0) then
+ SpawnCooldown := trigData.trigMonDelay;
+ if (trigData.trigMonMax > 0) and (SpawnedCount >= trigData.trigMonMax) then
Break;
- mon := g_Monsters_Create(Data.MonType,
- Data.MonPos.X, Data.MonPos.Y,
- TDirection(Data.MonDir), True);
+ mon := g_Monsters_Create(trigData.trigMonType,
+ trigData.trigMonPos.X, trigData.trigMonPos.Y,
+ TDirection(trigData.trigMonDir), True);
Result := True;
// Çäîðîâüå:
- if (Data.MonHealth > 0) then
- mon.SetHealth(Data.MonHealth);
+ if (trigData.trigMonHealth > 0) then
+ mon.SetHealth(trigData.trigMonHealth);
// Óñòàíàâëèâàåì ïîâåäåíèå:
- mon.MonsterBehaviour := Data.MonBehav;
+ mon.MonsterBehaviour := trigData.trigMonBehav;
mon.FNoRespawn := True;
if g_Game_IsNet then
MH_SEND_MonsterSpawn(mon.UID);
// Èäåì èñêàòü öåëü, åñëè íàäî:
- if Data.MonActive then
+ if trigData.trigMonActive then
mon.WakeUp();
- if Data.MonType <> MONSTER_BARREL then Inc(gTotalMonsters);
+ if trigData.trigMonType <> MONSTER_BARREL then Inc(gTotalMonsters);
if g_Game_IsNet then
begin
gMonstersSpawned[High(gMonstersSpawned)] := mon.UID;
end;
- if Data.MonMax > 0 then
+ if trigData.trigMonMax > 0 then
begin
mon.SpawnTrigger := ID;
Inc(SpawnedCount);
end;
- case Data.MonEffect of
+ case trigData.trigMonEffect of
EFFECT_TELEPORT: begin
if g_Frames_Get(FramesID, 'FRAMES_TELEPORT') then
begin
Anim := TAnimation.Create(FramesID, False, 3);
- g_Sound_PlayExAt('SOUND_GAME_TELEPORT', Data.MonPos.X, Data.MonPos.Y);
+ g_Sound_PlayExAt('SOUND_GAME_TELEPORT', trigData.trigMonPos.X, trigData.trigMonPos.Y);
g_GFX_OnceAnim(mon.Obj.X+mon.Obj.Rect.X+(mon.Obj.Rect.Width div 2)-32,
mon.Obj.Y+mon.Obj.Rect.Y+(mon.Obj.Rect.Height div 2)-32, Anim);
Anim.Free();
if g_Frames_Get(FramesID, 'FRAMES_ITEM_RESPAWN') then
begin
Anim := TAnimation.Create(FramesID, False, 4);
- g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', Data.MonPos.X, Data.MonPos.Y);
+ g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', trigData.trigMonPos.X, trigData.trigMonPos.Y);
g_GFX_OnceAnim(mon.Obj.X+mon.Obj.Rect.X+(mon.Obj.Rect.Width div 2)-16,
mon.Obj.Y+mon.Obj.Rect.Y+(mon.Obj.Rect.Height div 2)-16, Anim);
Anim.Free();
if g_Frames_Get(FramesID, 'FRAMES_FIRE') then
begin
Anim := TAnimation.Create(FramesID, False, 4);
- g_Sound_PlayExAt('SOUND_FIRE', Data.MonPos.X, Data.MonPos.Y);
+ g_Sound_PlayExAt('SOUND_FIRE', trigData.trigMonPos.X, trigData.trigMonPos.Y);
g_GFX_OnceAnim(mon.Obj.X+mon.Obj.Rect.X+(mon.Obj.Rect.Width div 2)-32,
mon.Obj.Y+mon.Obj.Rect.Y+mon.Obj.Rect.Height-128, Anim);
Anim.Free();
end;
TRIGGER_SPAWNITEM:
- if (Data.ItemType in [ITEM_MEDKIT_SMALL..ITEM_MAX]) then
+ if (trigData.trigItemType in [ITEM_MEDKIT_SMALL..ITEM_MAX]) then
begin
Result := False;
- if (Data.ItemDelay > 0) and (actType <> ACTIVATE_CUSTOM) then
+ if (trigData.trigItemDelay > 0) and (actType <> ACTIVATE_CUSTOM) then
begin
AutoSpawn := not AutoSpawn;
SpawnCooldown := 0;
Result := True;
end;
- if ((Data.ItemDelay = 0) and (actType <> ACTIVATE_CUSTOM))
- or ((Data.ItemDelay > 0) and (actType = ACTIVATE_CUSTOM)) then
- if (not Data.ItemOnlyDM) or
+ if ((trigData.trigItemDelay = 0) and (actType <> ACTIVATE_CUSTOM))
+ or ((trigData.trigItemDelay > 0) and (actType = ACTIVATE_CUSTOM)) then
+ if (not trigData.trigItemOnlyDM) or
(gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF]) then
- for k := 1 to Data.ItemCount do
+ for k := 1 to trigData.trigItemCount do
begin
- if (actType = ACTIVATE_CUSTOM) and (Data.ItemDelay > 0) then
- SpawnCooldown := Data.ItemDelay;
- if (Data.ItemMax > 0) and (SpawnedCount >= Data.ItemMax) then
+ if (actType = ACTIVATE_CUSTOM) and (trigData.trigItemDelay > 0) then
+ SpawnCooldown := trigData.trigItemDelay;
+ if (trigData.trigItemMax > 0) and (SpawnedCount >= trigData.trigItemMax) then
Break;
- iid := g_Items_Create(Data.ItemPos.X, Data.ItemPos.Y,
- Data.ItemType, Data.ItemFalls, False, True);
+ iid := g_Items_Create(trigData.trigItemPos.X, trigData.trigItemPos.Y,
+ trigData.trigItemType, trigData.trigItemFalls, False, True);
Result := True;
- if Data.ItemMax > 0 then
+ if trigData.trigItemMax > 0 then
begin
it := g_Items_ByIdx(iid);
it.SpawnTrigger := ID;
Inc(SpawnedCount);
end;
- case Data.ItemEffect of
+ case trigData.trigItemEffect of
EFFECT_TELEPORT: begin
it := g_Items_ByIdx(iid);
if g_Frames_Get(FramesID, 'FRAMES_TELEPORT') then
begin
Anim := TAnimation.Create(FramesID, False, 3);
- g_Sound_PlayExAt('SOUND_GAME_TELEPORT', Data.ItemPos.X, Data.ItemPos.Y);
+ g_Sound_PlayExAt('SOUND_GAME_TELEPORT', trigData.trigItemPos.X, trigData.trigItemPos.Y);
g_GFX_OnceAnim(it.Obj.X+it.Obj.Rect.X+(it.Obj.Rect.Width div 2)-32,
it.Obj.Y+it.Obj.Rect.Y+(it.Obj.Rect.Height div 2)-32, Anim);
Anim.Free();
if g_Frames_Get(FramesID, 'FRAMES_ITEM_RESPAWN') then
begin
Anim := TAnimation.Create(FramesID, False, 4);
- g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', Data.ItemPos.X, Data.ItemPos.Y);
+ g_Sound_PlayExAt('SOUND_ITEM_RESPAWNITEM', trigData.trigItemPos.X, trigData.trigItemPos.Y);
g_GFX_OnceAnim(it.Obj.X+it.Obj.Rect.X+(it.Obj.Rect.Width div 2)-16,
it.Obj.Y+it.Obj.Rect.Y+(it.Obj.Rect.Height div 2)-16, Anim);
Anim.Free();
if g_Frames_Get(FramesID, 'FRAMES_FIRE') then
begin
Anim := TAnimation.Create(FramesID, False, 4);
- g_Sound_PlayExAt('SOUND_FIRE', Data.ItemPos.X, Data.ItemPos.Y);
+ g_Sound_PlayExAt('SOUND_FIRE', trigData.trigItemPos.X, trigData.trigItemPos.Y);
g_GFX_OnceAnim(it.Obj.X+it.Obj.Rect.X+(it.Obj.Rect.Width div 2)-32,
it.Obj.Y+it.Obj.Rect.Y+it.Obj.Rect.Height-128, Anim);
Anim.Free();
TRIGGER_MUSIC:
begin
// Ìåíÿåì ìóçûêó, åñëè åñòü íà ÷òî:
- if (Trigger.Data.MusicName <> '') then
+ if (Trigger.trigData.trigMusicName <> '') then
begin
- gMusic.SetByName(Trigger.Data.MusicName);
+ gMusic.SetByName(Trigger.trigData.trigMusicName);
gMusic.SpecPause := True;
gMusic.Play();
end;
- if Trigger.Data.MusicAction = 1 then
+ if Trigger.trigData.trigMusicAction = 1 then
begin // Âêëþ÷èòü
if gMusic.SpecPause then // Áûëà íà ïàóçå => èãðàòü
gMusic.SpecPause := False
TRIGGER_PUSH:
begin
- pAngle := -DegToRad(Data.PushAngle);
+ pAngle := -DegToRad(trigData.trigPushAngle);
Result := tr_Push(ActivateUID,
- Floor(Cos(pAngle)*Data.PushForce),
- Floor(Sin(pAngle)*Data.PushForce),
- Data.ResetVel);
+ Floor(Cos(pAngle)*trigData.trigPushForce),
+ Floor(Sin(pAngle)*trigData.trigPushForce),
+ trigData.trigResetVel);
TimeOut := 0;
end;
begin
Result := False;
// Ïðèáàâèòü èëè îòíÿòü î÷êî
- if (Data.ScoreAction in [0..1]) and (Data.ScoreCount > 0) then
+ if (trigData.trigScoreAction in [0..1]) and (trigData.trigScoreCount > 0) then
begin
// Ñâîåé èëè ÷óæîé êîìàíäå
- if (Data.ScoreTeam in [0..1]) and (g_GetUIDType(ActivateUID) = UID_PLAYER) then
+ if (trigData.trigScoreTeam in [0..1]) and (g_GetUIDType(ActivateUID) = UID_PLAYER) then
begin
p := g_Player_Get(ActivateUID);
- if ((Data.ScoreAction = 0) and (Data.ScoreTeam = 0) and (p.Team = TEAM_RED))
- or ((Data.ScoreAction = 0) and (Data.ScoreTeam = 1) and (p.Team = TEAM_BLUE)) then
+ if ((trigData.trigScoreAction = 0) and (trigData.trigScoreTeam = 0) and (p.Team = TEAM_RED))
+ or ((trigData.trigScoreAction = 0) and (trigData.trigScoreTeam = 1) and (p.Team = TEAM_BLUE)) then
begin
- Inc(gTeamStat[TEAM_RED].Goals, Data.ScoreCount); // Red Scores
+ Inc(gTeamStat[TEAM_RED].Goals, trigData.trigScoreCount); // Red Scores
- if Data.ScoreCon then
- if Data.ScoreTeam = 0 then
+ if trigData.trigScoreCon then
+ if trigData.trigScoreTeam = 0 then
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_OWN], [p.Name, Data.ScoreCount, _lc[I_PLAYER_SCORE_TO_RED]]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_OWN], [p.Name, trigData.trigScoreCount, _lc[I_PLAYER_SCORE_TO_RED]]), True);
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (Data.ScoreCount shl 16), '+r');
+ MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (trigData.trigScoreCount shl 16), '+r');
end else
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_ENEMY], [p.Name, Data.ScoreCount, _lc[I_PLAYER_SCORE_TO_RED]]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_ENEMY], [p.Name, trigData.trigScoreCount, _lc[I_PLAYER_SCORE_TO_RED]]), True);
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (Data.ScoreCount shl 16), '+re');
+ MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (trigData.trigScoreCount shl 16), '+re');
end;
- if Data.ScoreMsg then
+ if trigData.trigScoreMsg then
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_ADD], [AnsiUpperCase(_lc[I_GAME_TEAM_RED])]), 108);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE_MSG, TEAM_RED);
end;
end;
- if ((Data.ScoreAction = 1) and (Data.ScoreTeam = 0) and (p.Team = TEAM_RED))
- or ((Data.ScoreAction = 1) and (Data.ScoreTeam = 1) and (p.Team = TEAM_BLUE)) then
+ if ((trigData.trigScoreAction = 1) and (trigData.trigScoreTeam = 0) and (p.Team = TEAM_RED))
+ or ((trigData.trigScoreAction = 1) and (trigData.trigScoreTeam = 1) and (p.Team = TEAM_BLUE)) then
begin
- Dec(gTeamStat[TEAM_RED].Goals, Data.ScoreCount); // Red Fouls
+ Dec(gTeamStat[TEAM_RED].Goals, trigData.trigScoreCount); // Red Fouls
- if Data.ScoreCon then
- if Data.ScoreTeam = 0 then
+ if trigData.trigScoreCon then
+ if trigData.trigScoreTeam = 0 then
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_OWN], [p.Name, Data.ScoreCount, _lc[I_PLAYER_SCORE_TO_RED]]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_OWN], [p.Name, trigData.trigScoreCount, _lc[I_PLAYER_SCORE_TO_RED]]), True);
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (Data.ScoreCount shl 16), '-r');
+ MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (trigData.trigScoreCount shl 16), '-r');
end else
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_ENEMY], [p.Name, Data.ScoreCount, _lc[I_PLAYER_SCORE_TO_RED]]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_ENEMY], [p.Name, trigData.trigScoreCount, _lc[I_PLAYER_SCORE_TO_RED]]), True);
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (Data.ScoreCount shl 16), '-re');
+ MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (trigData.trigScoreCount shl 16), '-re');
end;
- if Data.ScoreMsg then
+ if trigData.trigScoreMsg then
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_SUB], [AnsiUpperCase(_lc[I_GAME_TEAM_RED])]), 108);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE_MSG, -TEAM_RED);
end;
end;
- if ((Data.ScoreAction = 0) and (Data.ScoreTeam = 0) and (p.Team = TEAM_BLUE))
- or ((Data.ScoreAction = 0) and (Data.ScoreTeam = 1) and (p.Team = TEAM_RED)) then
+ if ((trigData.trigScoreAction = 0) and (trigData.trigScoreTeam = 0) and (p.Team = TEAM_BLUE))
+ or ((trigData.trigScoreAction = 0) and (trigData.trigScoreTeam = 1) and (p.Team = TEAM_RED)) then
begin
- Inc(gTeamStat[TEAM_BLUE].Goals, Data.ScoreCount); // Blue Scores
+ Inc(gTeamStat[TEAM_BLUE].Goals, trigData.trigScoreCount); // Blue Scores
- if Data.ScoreCon then
- if Data.ScoreTeam = 0 then
+ if trigData.trigScoreCon then
+ if trigData.trigScoreTeam = 0 then
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_OWN], [p.Name, Data.ScoreCount, _lc[I_PLAYER_SCORE_TO_BLUE]]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_OWN], [p.Name, trigData.trigScoreCount, _lc[I_PLAYER_SCORE_TO_BLUE]]), True);
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (Data.ScoreCount shl 16), '+b');
+ MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (trigData.trigScoreCount shl 16), '+b');
end else
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_ENEMY], [p.Name, Data.ScoreCount, _lc[I_PLAYER_SCORE_TO_BLUE]]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_ENEMY], [p.Name, trigData.trigScoreCount, _lc[I_PLAYER_SCORE_TO_BLUE]]), True);
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (Data.ScoreCount shl 16), '+be');
+ MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (trigData.trigScoreCount shl 16), '+be');
end;
- if Data.ScoreMsg then
+ if trigData.trigScoreMsg then
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_ADD], [AnsiUpperCase(_lc[I_GAME_TEAM_BLUE])]), 108);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE_MSG, TEAM_BLUE);
end;
end;
- if ((Data.ScoreAction = 1) and (Data.ScoreTeam = 0) and (p.Team = TEAM_BLUE))
- or ((Data.ScoreAction = 1) and (Data.ScoreTeam = 1) and (p.Team = TEAM_RED)) then
+ if ((trigData.trigScoreAction = 1) and (trigData.trigScoreTeam = 0) and (p.Team = TEAM_BLUE))
+ or ((trigData.trigScoreAction = 1) and (trigData.trigScoreTeam = 1) and (p.Team = TEAM_RED)) then
begin
- Dec(gTeamStat[TEAM_BLUE].Goals, Data.ScoreCount); // Blue Fouls
+ Dec(gTeamStat[TEAM_BLUE].Goals, trigData.trigScoreCount); // Blue Fouls
- if Data.ScoreCon then
- if Data.ScoreTeam = 0 then
+ if trigData.trigScoreCon then
+ if trigData.trigScoreTeam = 0 then
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_OWN], [p.Name, Data.ScoreCount, _lc[I_PLAYER_SCORE_TO_BLUE]]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_OWN], [p.Name, trigData.trigScoreCount, _lc[I_PLAYER_SCORE_TO_BLUE]]), True);
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (Data.ScoreCount shl 16), '-b');
+ MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (trigData.trigScoreCount shl 16), '-b');
end else
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_ENEMY], [p.Name, Data.ScoreCount, _lc[I_PLAYER_SCORE_TO_BLUE]]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_ENEMY], [p.Name, trigData.trigScoreCount, _lc[I_PLAYER_SCORE_TO_BLUE]]), True);
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (Data.ScoreCount shl 16), '-be');
+ MH_SEND_GameEvent(NET_EV_SCORE, p.UID or (trigData.trigScoreCount shl 16), '-be');
end;
- if Data.ScoreMsg then
+ if trigData.trigScoreMsg then
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_SUB], [AnsiUpperCase(_lc[I_GAME_TEAM_BLUE])]), 108);
if g_Game_IsServer and g_Game_IsNet then
Result := (p.Team = TEAM_RED) or (p.Team = TEAM_BLUE);
end;
// Êàêîé-òî êîíêðåòíîé êîìàíäå
- if Data.ScoreTeam in [2..3] then
+ if trigData.trigScoreTeam in [2..3] then
begin
- if (Data.ScoreAction = 0) and (Data.ScoreTeam = 2) then
+ if (trigData.trigScoreAction = 0) and (trigData.trigScoreTeam = 2) then
begin
- Inc(gTeamStat[TEAM_RED].Goals, Data.ScoreCount); // Red Scores
+ Inc(gTeamStat[TEAM_RED].Goals, trigData.trigScoreCount); // Red Scores
- if Data.ScoreCon then
+ if trigData.trigScoreCon then
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_TEAM], [_lc[I_PLAYER_SCORE_RED], Data.ScoreCount]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_TEAM], [_lc[I_PLAYER_SCORE_RED], trigData.trigScoreCount]), True);
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, Data.ScoreCount shl 16, '+tr');
+ MH_SEND_GameEvent(NET_EV_SCORE, trigData.trigScoreCount shl 16, '+tr');
end;
- if Data.ScoreMsg then
+ if trigData.trigScoreMsg then
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_ADD], [AnsiUpperCase(_lc[I_GAME_TEAM_RED])]), 108);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE_MSG, TEAM_RED);
end;
end;
- if (Data.ScoreAction = 1) and (Data.ScoreTeam = 2) then
+ if (trigData.trigScoreAction = 1) and (trigData.trigScoreTeam = 2) then
begin
- Dec(gTeamStat[TEAM_RED].Goals, Data.ScoreCount); // Red Fouls
+ Dec(gTeamStat[TEAM_RED].Goals, trigData.trigScoreCount); // Red Fouls
- if Data.ScoreCon then
+ if trigData.trigScoreCon then
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_TEAM], [_lc[I_PLAYER_SCORE_RED], Data.ScoreCount]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_TEAM], [_lc[I_PLAYER_SCORE_RED], trigData.trigScoreCount]), True);
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, Data.ScoreCount shl 16, '-tr');
+ MH_SEND_GameEvent(NET_EV_SCORE, trigData.trigScoreCount shl 16, '-tr');
end;
- if Data.ScoreMsg then
+ if trigData.trigScoreMsg then
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_SUB], [AnsiUpperCase(_lc[I_GAME_TEAM_RED])]), 108);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE_MSG, -TEAM_RED);
end;
end;
- if (Data.ScoreAction = 0) and (Data.ScoreTeam = 3) then
+ if (trigData.trigScoreAction = 0) and (trigData.trigScoreTeam = 3) then
begin
- Inc(gTeamStat[TEAM_BLUE].Goals, Data.ScoreCount); // Blue Scores
+ Inc(gTeamStat[TEAM_BLUE].Goals, trigData.trigScoreCount); // Blue Scores
- if Data.ScoreCon then
+ if trigData.trigScoreCon then
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_TEAM], [_lc[I_PLAYER_SCORE_BLUE], Data.ScoreCount]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_ADD_TEAM], [_lc[I_PLAYER_SCORE_BLUE], trigData.trigScoreCount]), True);
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, Data.ScoreCount shl 16, '+tb');
+ MH_SEND_GameEvent(NET_EV_SCORE, trigData.trigScoreCount shl 16, '+tb');
end;
- if Data.ScoreMsg then
+ if trigData.trigScoreMsg then
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_ADD], [AnsiUpperCase(_lc[I_GAME_TEAM_BLUE])]), 108);
if g_Game_IsServer and g_Game_IsNet then
MH_SEND_GameEvent(NET_EV_SCORE_MSG, TEAM_BLUE);
end;
end;
- if (Data.ScoreAction = 1) and (Data.ScoreTeam = 3) then
+ if (trigData.trigScoreAction = 1) and (trigData.trigScoreTeam = 3) then
begin
- Dec(gTeamStat[TEAM_BLUE].Goals, Data.ScoreCount); // Blue Fouls
+ Dec(gTeamStat[TEAM_BLUE].Goals, trigData.trigScoreCount); // Blue Fouls
- if Data.ScoreCon then
+ if trigData.trigScoreCon then
begin
- g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_TEAM], [_lc[I_PLAYER_SCORE_BLUE], Data.ScoreCount]), True);
+ g_Console_Add(Format(_lc[I_PLAYER_SCORE_SUB_TEAM], [_lc[I_PLAYER_SCORE_BLUE], trigData.trigScoreCount]), True);
if g_Game_IsServer and g_Game_IsNet then
- MH_SEND_GameEvent(NET_EV_SCORE, Data.ScoreCount shl 16, '-tb');
+ MH_SEND_GameEvent(NET_EV_SCORE, trigData.trigScoreCount shl 16, '-tb');
end;
- if Data.ScoreMsg then
+ if trigData.trigScoreMsg then
begin
g_Game_Message(Format(_lc[I_MESSAGE_SCORE_SUB], [AnsiUpperCase(_lc[I_GAME_TEAM_BLUE])]), 108);
if g_Game_IsServer and g_Game_IsNet then
end;
end;
// Âûèãðûø
- if (Data.ScoreAction = 2) and (gGameSettings.GoalLimit > 0) then
+ if (trigData.trigScoreAction = 2) and (gGameSettings.GoalLimit > 0) then
begin
// Ñâîåé èëè ÷óæîé êîìàíäû
- if (Data.ScoreTeam in [0..1]) and (g_GetUIDType(ActivateUID) = UID_PLAYER) then
+ if (trigData.trigScoreTeam in [0..1]) and (g_GetUIDType(ActivateUID) = UID_PLAYER) then
begin
p := g_Player_Get(ActivateUID);
- if ((Data.ScoreTeam = 0) and (p.Team = TEAM_RED)) // Red Wins
- or ((Data.ScoreTeam = 1) and (p.Team = TEAM_BLUE)) then
+ if ((trigData.trigScoreTeam = 0) and (p.Team = TEAM_RED)) // Red Wins
+ or ((trigData.trigScoreTeam = 1) and (p.Team = TEAM_BLUE)) then
if gTeamStat[TEAM_RED].Goals < SmallInt(gGameSettings.GoalLimit) then
begin
gTeamStat[TEAM_RED].Goals := gGameSettings.GoalLimit;
- if Data.ScoreCon then
- if Data.ScoreTeam = 0 then
+ if trigData.trigScoreCon then
+ if trigData.trigScoreTeam = 0 then
begin
g_Console_Add(Format(_lc[I_PLAYER_SCORE_WIN_OWN], [p.Name, _lc[I_PLAYER_SCORE_TO_RED]]), True);
if g_Game_IsServer and g_Game_IsNet then
Result := True;
end;
- if ((Data.ScoreTeam = 0) and (p.Team = TEAM_BLUE)) // Blue Wins
- or ((Data.ScoreTeam = 1) and (p.Team = TEAM_RED)) then
+ if ((trigData.trigScoreTeam = 0) and (p.Team = TEAM_BLUE)) // Blue Wins
+ or ((trigData.trigScoreTeam = 1) and (p.Team = TEAM_RED)) then
if gTeamStat[TEAM_BLUE].Goals < SmallInt(gGameSettings.GoalLimit) then
begin
gTeamStat[TEAM_BLUE].Goals := gGameSettings.GoalLimit;
- if Data.ScoreCon then
- if Data.ScoreTeam = 0 then
+ if trigData.trigScoreCon then
+ if trigData.trigScoreTeam = 0 then
begin
g_Console_Add(Format(_lc[I_PLAYER_SCORE_WIN_OWN], [p.Name, _lc[I_PLAYER_SCORE_TO_BLUE]]), True);
if g_Game_IsServer and g_Game_IsNet then
end;
end;
// Êàêîé-òî êîíêðåòíîé êîìàíäû
- if Data.ScoreTeam in [2..3] then
+ if trigData.trigScoreTeam in [2..3] then
begin
- if Data.ScoreTeam = 2 then // Red Wins
+ if trigData.trigScoreTeam = 2 then // Red Wins
if gTeamStat[TEAM_RED].Goals < SmallInt(gGameSettings.GoalLimit) then
begin
gTeamStat[TEAM_RED].Goals := gGameSettings.GoalLimit;
Result := True;
end;
- if Data.ScoreTeam = 3 then // Blue Wins
+ if trigData.trigScoreTeam = 3 then // Blue Wins
if gTeamStat[TEAM_BLUE].Goals < SmallInt(gGameSettings.GoalLimit) then
begin
gTeamStat[TEAM_BLUE].Goals := gGameSettings.GoalLimit;
end;
end;
// Ïðîèãðûø
- if (Data.ScoreAction = 3) and (gGameSettings.GoalLimit > 0) then
+ if (trigData.trigScoreAction = 3) and (gGameSettings.GoalLimit > 0) then
begin
// Ñâîåé èëè ÷óæîé êîìàíäû
- if (Data.ScoreTeam in [0..1]) and (g_GetUIDType(ActivateUID) = UID_PLAYER) then
+ if (trigData.trigScoreTeam in [0..1]) and (g_GetUIDType(ActivateUID) = UID_PLAYER) then
begin
p := g_Player_Get(ActivateUID);
- if ((Data.ScoreTeam = 0) and (p.Team = TEAM_BLUE)) // Red Wins
- or ((Data.ScoreTeam = 1) and (p.Team = TEAM_RED)) then
+ if ((trigData.trigScoreTeam = 0) and (p.Team = TEAM_BLUE)) // Red Wins
+ or ((trigData.trigScoreTeam = 1) and (p.Team = TEAM_RED)) then
if gTeamStat[TEAM_RED].Goals < SmallInt(gGameSettings.GoalLimit) then
begin
gTeamStat[TEAM_RED].Goals := gGameSettings.GoalLimit;
- if Data.ScoreCon then
- if Data.ScoreTeam = 0 then
+ if trigData.trigScoreCon then
+ if trigData.trigScoreTeam = 0 then
begin
g_Console_Add(Format(_lc[I_PLAYER_SCORE_WIN_ENEMY], [p.Name, _lc[I_PLAYER_SCORE_TO_RED]]), True);
if g_Game_IsServer and g_Game_IsNet then
Result := True;
end;
- if ((Data.ScoreTeam = 0) and (p.Team = TEAM_RED)) // Blue Wins
- or ((Data.ScoreTeam = 1) and (p.Team = TEAM_BLUE)) then
+ if ((trigData.trigScoreTeam = 0) and (p.Team = TEAM_RED)) // Blue Wins
+ or ((trigData.trigScoreTeam = 1) and (p.Team = TEAM_BLUE)) then
if gTeamStat[TEAM_BLUE].Goals < SmallInt(gGameSettings.GoalLimit) then
begin
gTeamStat[TEAM_BLUE].Goals := gGameSettings.GoalLimit;
- if Data.ScoreCon then
- if Data.ScoreTeam = 0 then
+ if trigData.trigScoreCon then
+ if trigData.trigScoreTeam = 0 then
begin
g_Console_Add(Format(_lc[I_PLAYER_SCORE_WIN_ENEMY], [p.Name, _lc[I_PLAYER_SCORE_TO_BLUE]]), True);
if g_Game_IsServer and g_Game_IsNet then
end;
end;
// Êàêîé-òî êîíêðåòíîé êîìàíäû
- if Data.ScoreTeam in [2..3] then
+ if trigData.trigScoreTeam in [2..3] then
begin
- if Data.ScoreTeam = 3 then // Red Wins
+ if trigData.trigScoreTeam = 3 then // Red Wins
if gTeamStat[TEAM_RED].Goals < SmallInt(gGameSettings.GoalLimit) then
begin
gTeamStat[TEAM_RED].Goals := gGameSettings.GoalLimit;
Result := True;
end;
- if Data.ScoreTeam = 2 then // Blue Wins
+ if trigData.trigScoreTeam = 2 then // Blue Wins
if gTeamStat[TEAM_BLUE].Goals < SmallInt(gGameSettings.GoalLimit) then
begin
gTeamStat[TEAM_BLUE].Goals := gGameSettings.GoalLimit;
TRIGGER_MESSAGE:
begin
- Result := tr_Message(Data.MessageKind, Data.MessageText,
- Data.MessageSendTo, Data.MessageTime,
+ Result := tr_Message(trigData.trigMessageKind, trigData.trigMessageText,
+ trigData.trigMessageSendTo, trigData.trigMessageTime,
ActivateUID);
TimeOut := 18;
end;
end else
begin // Óæå âèäåëè åãî
// Åñëè èíòåðâàë îòêëþ÷¸í, íî îí âñ¸ åù¸ â çîíå ïîðàæåíèÿ, äà¸ì åìó âðåìÿ
- if (Data.DamageInterval = 0) and (Activators[k].TimeOut > 0) then
+ if (trigData.trigDamageInterval = 0) and (Activators[k].TimeOut > 0) then
Activators[k].TimeOut := 65535;
// Òàéìàóò ïðîø¸ë - ðàáîòàåì
Result := Activators[k].TimeOut = 0;
Exit;
// Íàíîñèì óðîí èãðîêó
- if (TriggerType = TRIGGER_DAMAGE) and (Data.DamageValue > 0) then
- p.Damage(Data.DamageValue, 0, 0, 0, HIT_SOME);
+ if (TriggerType = TRIGGER_DAMAGE) and (trigData.trigDamageValue > 0) then
+ p.Damage(trigData.trigDamageValue, 0, 0, 0, HIT_SOME);
// Ëå÷èì èãðîêà
- if (TriggerType = TRIGGER_HEALTH) and (Data.HealValue > 0) then
- if p.Heal(Data.HealValue, not Data.HealMax) and (not Data.HealSilent) then
+ if (TriggerType = TRIGGER_HEALTH) and (trigData.trigHealValue > 0) then
+ if p.Heal(trigData.trigHealValue, not trigData.trigHealMax) and (not trigData.trigHealSilent) then
begin
g_Sound_PlayExAt('SOUND_ITEM_GETITEM', p.Obj.X, p.Obj.Y);
if g_Game_IsServer and g_Game_IsNet then
Exit;
// Íàíîñèì óðîí ìîíñòðó
- if (TriggerType = TRIGGER_DAMAGE) and (Data.DamageValue > 0) then
- m.Damage(Data.DamageValue, 0, 0, 0, HIT_SOME);
+ if (TriggerType = TRIGGER_DAMAGE) and (trigData.trigDamageValue > 0) then
+ m.Damage(trigData.trigDamageValue, 0, 0, 0, HIT_SOME);
// Ëå÷èì ìîíñòðà
- if (TriggerType = TRIGGER_HEALTH) and (Data.HealValue > 0) then
- if m.Heal(Data.HealValue) and (not Data.HealSilent) then
+ if (TriggerType = TRIGGER_HEALTH) and (trigData.trigHealValue > 0) then
+ if m.Heal(trigData.trigHealValue) and (not trigData.trigHealSilent) then
begin
g_Sound_PlayExAt('SOUND_ITEM_GETITEM', m.Obj.X, m.Obj.Y);
if g_Game_IsServer and g_Game_IsNet then
end;
// Íàçíà÷àåì âðåìÿ ñëåäóþùåãî âîçäåéñòâèÿ
if TriggerType = TRIGGER_DAMAGE then
- idx := Data.DamageInterval
+ idx := trigData.trigDamageInterval
else
- idx := Data.HealInterval;
+ idx := trigData.trigHealInterval;
if coolDown then
if idx > 0 then
Activators[k].TimeOut := idx
Exit;
// put this at the beginning so it doesn't trigger itself
- TimeOut := Data.ShotWait + 1;
+ TimeOut := trigData.trigShotWait + 1;
- wx := Data.ShotPos.X;
- wy := Data.ShotPos.Y;
- pAngle := -DegToRad(Data.ShotAngle);
+ wx := trigData.trigShotPos.X;
+ wy := trigData.trigShotPos.Y;
+ pAngle := -DegToRad(trigData.trigShotAngle);
xd := wx + Round(Cos(pAngle) * 32.0);
yd := wy + Round(Sin(pAngle) * 32.0);
TargetUID := 0;
- case Data.ShotTarget of
+ case trigData.trigShotTarget of
TRIGGER_SHOT_TARGET_MON: // monsters
//TODO: accelerate this!
g_Mons_ForEachAlive(monsShotTarget);
end;
else begin
- if (Data.ShotTarget <> TRIGGER_SHOT_TARGET_NONE) or
- (Data.ShotType <> TRIGGER_SHOT_REV) then
+ if (trigData.trigShotTarget <> TRIGGER_SHOT_TARGET_NONE) or
+ (trigData.trigShotType <> TRIGGER_SHOT_REV) then
TargetUID := ActivateUID;
end;
end;
- if (Data.ShotTarget = TRIGGER_SHOT_TARGET_NONE) or (TargetUID > 0) or
- ((Data.ShotTarget > TRIGGER_SHOT_TARGET_NONE) and (TargetUID = 0)) then
+ if (trigData.trigShotTarget = TRIGGER_SHOT_TARGET_NONE) or (TargetUID > 0) or
+ ((trigData.trigShotTarget > TRIGGER_SHOT_TARGET_NONE) and (TargetUID = 0)) then
begin
Result := True;
- if (Data.ShotIntSight = 0) or
- (Data.ShotTarget = TRIGGER_SHOT_TARGET_NONE) or
+ if (trigData.trigShotIntSight = 0) or
+ (trigData.trigShotTarget = TRIGGER_SHOT_TARGET_NONE) or
(TargetUID = ShotSightTarget) then
MakeShot(Trigger, wx, wy, xd, yd, TargetUID)
else
begin
- ShotSightTime := Data.ShotIntSight;
+ ShotSightTime := trigData.trigShotIntSight;
ShotSightTargetN := TargetUID;
- if Data.ShotType = TRIGGER_SHOT_BFG then
+ if trigData.trigShotType = TRIGGER_SHOT_BFG then
begin
g_Sound_PlayExAt('SOUND_WEAPON_STARTFIREBFG', wx, wy);
if g_Game_IsNet and g_Game_IsServer then
TRIGGER_EFFECT:
begin
- idx := Data.FXCount;
+ idx := trigData.trigFXCount;
while idx > 0 do
begin
- case Data.FXPos of
+ case trigData.trigFXPos of
TRIGGER_EFFECT_POS_CENTER:
begin
wx := X + Width div 2;
wy := Y + Height div 2;
end;
end;
- xd := Data.FXVelX;
- yd := Data.FXVelY;
- if Data.FXSpreadL > 0 then xd := xd - Random(Data.FXSpreadL + 1);
- if Data.FXSpreadR > 0 then xd := xd + Random(Data.FXSpreadR + 1);
- if Data.FXSpreadU > 0 then yd := yd - Random(Data.FXSpreadU + 1);
- if Data.FXSpreadD > 0 then yd := yd + Random(Data.FXSpreadD + 1);
+ xd := trigData.trigFXVelX;
+ yd := trigData.trigFXVelY;
+ if trigData.trigFXSpreadL > 0 then xd := xd - Random(trigData.trigFXSpreadL + 1);
+ if trigData.trigFXSpreadR > 0 then xd := xd + Random(trigData.trigFXSpreadR + 1);
+ if trigData.trigFXSpreadU > 0 then yd := yd - Random(trigData.trigFXSpreadU + 1);
+ if trigData.trigFXSpreadD > 0 then yd := yd + Random(trigData.trigFXSpreadD + 1);
tr_MakeEffect(wx, wy, xd, yd,
- Data.FXType, Data.FXSubType,
- Data.FXColorR, Data.FXColorG, Data.FXColorB, True, False);
+ trigData.trigFXType, trigData.trigFXSubType,
+ trigData.trigFXColorR, trigData.trigFXColorG, trigData.trigFXColorB, True, False);
Dec(idx);
end;
- TimeOut := Data.FXWait;
+ TimeOut := trigData.trigFXWait;
end;
end;
end;
// Çàãðóæàåì çâóê, åñëè ýòî òðèããåð "Çâóê":
if (Trigger.TriggerType = TRIGGER_SOUND) and
- (Trigger.Data.SoundName <> '') then
+ (Trigger.trigData.trigSoundName <> '') then
begin
// Åùå íåò òàêîãî çâóêà:
- if not g_Sound_Exists(Trigger.Data.SoundName) then
+ if not g_Sound_Exists(Trigger.trigData.trigSoundName) then
begin
- fn := g_ExtractWadName(Trigger.Data.SoundName);
+ fn := g_ExtractWadName(Trigger.trigData.trigSoundName);
if fn = '' then
begin // Çâóê â ôàéëå ñ êàðòîé
mapw := g_ExtractWadName(gMapInfo.Map);
- fn := mapw+':'+g_ExtractFilePathName(Trigger.Data.SoundName);
+ fn := mapw+':'+g_ExtractFilePathName(Trigger.trigData.trigSoundName);
end
else // Çâóê â îòäåëüíîì ôàéëå
- fn := GameDir + '/wads/' + Trigger.Data.SoundName;
+ fn := GameDir + '/wads/' + Trigger.trigData.trigSoundName;
- if not g_Sound_CreateWADEx(Trigger.Data.SoundName, fn) then
- g_FatalError(Format(_lc[I_GAME_ERROR_TR_SOUND], [fn, Trigger.Data.SoundName]));
+ if not g_Sound_CreateWADEx(Trigger.trigData.trigSoundName, fn) then
+ g_FatalError(Format(_lc[I_GAME_ERROR_TR_SOUND], [fn, Trigger.trigData.trigSoundName]));
end;
// Ñîçäàåì îáúåêò çâóêà:
with gTriggers[find_id] do
begin
Sound := TPlayableSound.Create();
- if not Sound.SetByName(Trigger.Data.SoundName) then
+ if not Sound.SetByName(Trigger.trigData.trigSoundName) then
begin
Sound.Free();
Sound := nil;
// Çàãðóæàåì ìóçûêó, åñëè ýòî òðèããåð "Ìóçûêà":
if (Trigger.TriggerType = TRIGGER_MUSIC) and
- (Trigger.Data.MusicName <> '') then
+ (Trigger.trigData.trigMusicName <> '') then
begin
// Åùå íåò òàêîé ìóçûêè:
- if not g_Sound_Exists(Trigger.Data.MusicName) then
+ if not g_Sound_Exists(Trigger.trigData.trigMusicName) then
begin
- fn := g_ExtractWadName(Trigger.Data.MusicName);
+ fn := g_ExtractWadName(Trigger.trigData.trigMusicName);
if fn = '' then
begin // Ìóçûêà â ôàéëå ñ êàðòîé
mapw := g_ExtractWadName(gMapInfo.Map);
- fn := mapw+':'+g_ExtractFilePathName(Trigger.Data.MusicName);
+ fn := mapw+':'+g_ExtractFilePathName(Trigger.trigData.trigMusicName);
end
else // Ìóçûêà â ôàéëå ñ êàðòîé
- fn := GameDir+'/wads/'+Trigger.Data.MusicName;
+ fn := GameDir+'/wads/'+Trigger.trigData.trigMusicName;
- if not g_Sound_CreateWADEx(Trigger.Data.MusicName, fn, True) then
- g_FatalError(Format(_lc[I_GAME_ERROR_TR_SOUND], [fn, Trigger.Data.MusicName]));
+ if not g_Sound_CreateWADEx(Trigger.trigData.trigMusicName, fn, True) then
+ g_FatalError(Format(_lc[I_GAME_ERROR_TR_SOUND], [fn, Trigger.trigData.trigMusicName]));
end;
end;
ShotSightTimeout := 0;
ShotSightTarget := 0;
ShotSightTargetN := 0;
- ShotAmmoCount := Trigger.Data.ShotAmmo;
+ ShotAmmoCount := Trigger.trigData.trigShotAmmo;
ShotReloadTime := 0;
end;
else
Continue;
// Ñ÷èòàåì, ÷òî îáúåêò ïîêèíóë çîíó äåéñòâèÿ òðèããåðà
- if (Data.DamageInterval = 0) and (Activators[b].TimeOut < 65530) then
+ if (trigData.trigDamageInterval = 0) and (Activators[b].TimeOut < 65530) then
Activators[b].TimeOut := 0;
end;
if SpawnCooldown = 0 then
begin
// Åñëè ïðèøëî âðåìÿ, ñïàâíèì ìîíñòðà:
- if (TriggerType = TRIGGER_SPAWNMONSTER) and (Data.MonDelay > 0) then
+ if (TriggerType = TRIGGER_SPAWNMONSTER) and (trigData.trigMonDelay > 0) then
begin
ActivateUID := 0;
ActivateTrigger(gTriggers[a], ACTIVATE_CUSTOM);
end;
// Åñëè ïðèøëî âðåìÿ, ñïàâíèì ïðåäìåò:
- if (TriggerType = TRIGGER_SPAWNITEM) and (Data.ItemDelay > 0) then
+ if (TriggerType = TRIGGER_SPAWNITEM) and (trigData.trigItemDelay > 0) then
begin
ActivateUID := 0;
ActivateTrigger(gTriggers[a], ACTIVATE_CUSTOM);
begin
Dec(ShotPanelTime);
if ShotPanelTime = 0 then
- g_Map_SwitchTexture(ShotPanelType, Data.ShotPanelID);
+ g_Map_SwitchTexture(ShotPanelType, trigShotPanelID);
end;
if ShotSightTime > 0 then
begin
begin
Dec(ShotReloadTime);
if ShotReloadTime = 0 then
- ShotAmmoCount := Data.ShotAmmo;
+ ShotAmmoCount := trigData.trigShotAmmo;
end;
end;
if Enabled and (TriggerType = TRIGGER_SOUND) and (Sound <> nil) then
if (SoundPlayCount > 0) and (not Sound.IsPlaying()) then
begin
- if Data.PlayCount > 0 then // Åñëè 0 - èãðàåì çâóê áåñêîíå÷íî
+ if trigData.trigPlayCount > 0 then // Åñëè 0 - èãðàåì çâóê áåñêîíå÷íî
SoundPlayCount := SoundPlayCount - 1;
- if Data.Local then
- Sound.PlayVolumeAt(X+(Width div 2), Y+(Height div 2), Data.Volume/255.0)
+ if trigData.trigLocal then
+ Sound.PlayVolumeAt(X+(Width div 2), Y+(Height div 2), trigData.trigVolume/255.0)
else
- Sound.PlayPanVolume((Data.Pan-127.0)/128.0, Data.Volume/255.0);
+ Sound.PlayPanVolume((trigData.trigPan-127.0)/128.0, trigData.trigVolume/255.0);
if Sound.IsPlaying() and g_Game_IsNet and g_Game_IsServer then
MH_SEND_TriggerSound(gTriggers[a]);
end;
// Òðèããåð "Ëîâóøêà" - ïîðà îòêðûâàòü:
- if (TriggerType = TRIGGER_TRAP) and (DoorTime = 0) and (Data.PanelID <> -1) then
+ if (TriggerType = TRIGGER_TRAP) and (DoorTime = 0) and (trigPanelID <> -1) then
begin
- tr_OpenDoor(Data.PanelID, Data.NoSound, Data.d2d_doors);
+ tr_OpenDoor(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors);
DoorTime := -1;
end;
// Òðèããåð "Äâåðü 5 ñåê" - ïîðà çàêðûâàòü:
- if (TriggerType = TRIGGER_DOOR5) and (DoorTime = 0) and (Data.PanelID <> -1) then
+ if (TriggerType = TRIGGER_DOOR5) and (DoorTime = 0) and (trigPanelID <> -1) then
begin
// Óæå çàêðûòà:
- if gWalls[Data.PanelID].Enabled then
+ if gWalls[trigPanelID].Enabled then
DoorTime := -1
else // Ïîêà îòêðûòà - çàêðûâàåì
- if tr_CloseDoor(Data.PanelID, Data.NoSound, Data.d2d_doors) then
+ if tr_CloseDoor(trigPanelID, trigData.trigNoSound, trigData.trigd2d_doors) then
DoorTime := -1;
end;
// Òðèããåð - ðàñøèðèòåëü èëè ïåðåêëþ÷àòåëü, è ïðîøëà çàäåðæêà, è íàæàëè íóæíîå ÷èñëî ðàç:
if (TriggerType in [TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF]) and
- (PressTime = 0) and (PressCount >= Data.Count) then
+ (PressTime = 0) and (PressCount >= trigData.trigCount) then
begin
// Ñáðàñûâàåì çàäåðæêó àêòèâàöèè:
PressTime := -1;
// Ñáðàñûâàåì ñ÷åò÷èê íàæàòèé:
- if Data.Count > 0 then
- PressCount := PressCount - Data.Count
+ if trigData.trigCount > 0 then
+ PressCount := PressCount - trigData.trigCount
else
PressCount := 0;
// Îïðåäåëÿåì èçìåíÿåìûå èì òðèããåðû:
for b := 0 to High(gTriggers) do
- if g_Collide(Data.tX, Data.tY, Data.tWidth, Data.tHeight, gTriggers[b].X, gTriggers[b].Y,
+ if g_Collide(trigData.trigtX, trigData.trigtY, trigData.trigtWidth, trigData.trigtHeight, gTriggers[b].X, gTriggers[b].Y,
gTriggers[b].Width, gTriggers[b].Height) and
- ((b <> a) or (Data.Wait > 0)) then
+ ((b <> a) or (trigData.trigWait > 0)) then
begin // Can be self-activated, if there is Data.Wait
- if (not Data.ExtRandom) or gTriggers[b].Enabled then
+ if (not trigData.trigExtRandom) or gTriggers[b].Enabled then
begin
SetLength(Affected, Length(Affected) + 1);
Affected[High(Affected)] := b;
end;
end;
// Âûáèðàåì îäèí èç òðèããåðîâ äëÿ ðàñøèðèòåëÿ, åñëè âêëþ÷åí ðàíäîì:
- if (TriggerType = TRIGGER_PRESS) and Data.ExtRandom then
+ if (TriggerType = TRIGGER_PRESS) and trigData.trigExtRandom then
begin
if (Length(Affected) > 0) then
begin
(TriggerType = TRIGGER_DOOR5) or
(TriggerType = TRIGGER_DOOR) then
begin
- tr_OpenDoor(Data.PanelID, True, Data.d2d_doors);
+ tr_OpenDoor(trigPanelID, True, trigData.trigd2d_doors);
if TriggerType = TRIGGER_DOOR5 then DoorTime := 180;
b := True;
end;
var
a: Integer;
begin
- if gTriggers <> nil then
- for a := 0 to High(gTriggers) do
+ for a := 0 to High(gTriggers) do
+ begin
+ gTriggers[a].trigData.Free();
+ if (gTriggers[a].TriggerType = TRIGGER_SOUND) then
begin
- if gTriggers[a].TriggerType = TRIGGER_SOUND then
+ if g_Sound_Exists(gTriggers[a].trigData.trigSoundName) then
begin
- if g_Sound_Exists(gTriggers[a].Data.SoundName) then
- g_Sound_Delete(gTriggers[a].Data.SoundName);
-
- gTriggers[a].Sound.Free();
+ g_Sound_Delete(gTriggers[a].trigData.trigSoundName);
end;
- if gTriggers[a].Activators <> nil then
- SetLength(gTriggers[a].Activators, 0);
+ gTriggers[a].Sound.Free();
end;
+ if (gTriggers[a].Activators <> nil) then
+ begin
+ SetLength(gTriggers[a].Activators, 0);
+ end;
+ end;
gTriggers := nil;
gSecretsCount := 0;
dw: DWORD;
sg: Single;
b: Boolean;
- p: Pointer;
+ //p: Pointer;
begin
// Ñ÷èòàåì êîëè÷åñòâî ñóùåñòâóþùèõ òðèããåðîâ:
count := 0;
// Òèï òðèããåðà:
Mem.WriteByte(gTriggers[i].TriggerType);
// Ñïåöèàëüíûå äàííûå òðèããåðà:
- p := @gTriggers[i].Data;
- Mem.WriteMemory(p, SizeOf(TTriggerData));
+ //!!!FIXME!!!
+ //p := @gTriggers[i].Data;
+ //Mem.WriteMemory(p, SizeOf(TTriggerData));
// Êîîðäèíàòû ëåâîãî âåðõíåãî óãëà:
Mem.WriteInt(gTriggers[i].X);
Mem.WriteInt(gTriggers[i].Y);
dw: DWORD;
vol, pan: Single;
b: Boolean;
- p: Pointer;
+ //p: Pointer;
Trig: TTrigger;
begin
if Mem = nil then
// Òèï òðèããåðà:
Mem.ReadByte(Trig.TriggerType);
// Ñïåöèàëüíûå äàííûå òðèããåðà:
+ //!!!FIXME!!!
+ {
Mem.ReadMemory(p, dw);
if dw <> SizeOf(TTriggerData) then
begin
raise EBinSizeError.Create('g_Triggers_LoadState: Wrong TriggerData Size');
end;
Trig.Data := TTriggerData(p^);
+ }
// Ñîçäàåì òðèããåð:
i := g_Triggers_Create(Trig);
// Êîîðäèíàòû ëåâîãî âåðõíåãî óãëà:
diff --git a/src/shared/MAPDEF.pas b/src/shared/MAPDEF.pas
index 37f9f0091ced2a3c9f117838fa1fceb42ebd3849..a7137162c81c5be25db278bc34b11462913c11a9 100644 (file)
--- a/src/shared/MAPDEF.pas
+++ b/src/shared/MAPDEF.pas
{$M+}
unit MAPDEF;
-{
------------------------------------
-MAPDEF.PAS ÂÅÐÑÈß ÎÒ 22.03.09
-
-Ïîääåðæêà êàðò âåðñèè 1
------------------------------------
-}
-
interface
uses
type
TDFPoint = packed record
+ public
X, Y: LongInt;
+
+ public
+ constructor Create (ax, ay: LongInt);
end;
Char16 = packed array[0..15] of Char;
{$INCLUDE mapdef.inc}
+// various helpers to access map structures
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;
+ TDynRecordHelper = class helper for TDynRecord
+ private
+ function getFieldWithType (const aname: AnsiString; atype: TDynField.TType): TDynField; inline;
+
+ function getPanelByIdx (idx: Integer): TDynRecord; inline;
+
+ function getPanelId (): Integer; inline;
+ //procedure setPanelId (v: Integer); inline;
+
+ function getTexturePanel (): Integer; inline;
+ //procedure setTexturePanel (v: Integer); inline;
+
+ function getPanelIndex (pan: TDynRecord): Integer;
+
+ function getPointField (const aname: AnsiString): TDFPoint; inline;
+
+ public
+ function panelCount (): Integer; inline;
+
+ // header
+ function mapName (): AnsiString; inline;
+ function mapAuthor (): AnsiString; inline;
+ function mapDesc (): AnsiString; inline;
+ function musicName (): AnsiString; inline;
+ function skyName (): AnsiString; inline;
+
+ // panel
+ function X (): Integer; inline;
+ function Y (): Integer; inline;
+ function Width (): Word; inline;
+ function Height (): Word; inline;
+ function TextureNum (): Word; inline;
+ function TextureRec (): TDynRecord; inline;
+ function PanelType (): Word; inline;
+ function Alpha (): Byte; inline;
+ function Flags (): Byte; inline;
+
+ // texture
+ function Resource (): AnsiString; inline;
+ function Anim (): Boolean; inline;
+
+ // item
+ function ItemType (): Byte; inline;
+ function Options (): Byte; inline;
+
+ // monster
+ function MonsterType (): Byte; inline; // type, ubyte
+ function Direction (): Byte; inline; // direction, ubyte
+
+ // area
+ function AreaType (): Byte; inline; // type, ubyte
+ //function Direction (): Byte; inline; // direction, ubyte
+
+ // trigger
+ function trigRec (): TDynRecord; inline;
+ function Enabled (): Boolean; inline; // enabled, bool
+ function TriggerType (): Byte; inline; // type, ubyte
+ function ActivateType (): Byte; inline; // activatetype, ubyte
+ function Keys (): Byte; inline; // keys, ubyte
+ //function DATA (): Byte128; inline; // triggerdata, trigdata[128]; // the only special nested structure
+
+ {$INCLUDE mapdef_help.inc}
+ function trigMonsterId (): Integer; inline;
+
+ public
+ property panel[idx: Integer]: TDynRecord read getPanelByIdx;
+ property panelIndex[pan: TDynRecord]: Integer read getPanelIndex;
+ // triggers
+ property tgPanelID: Integer read getPanelId {write setPanelId};
+ property tgShotPanelID: Integer read getPanelId {write setPanelId};
+ property TexturePanel: Integer read getTexturePanel {write setTexturePanel}; // texturepanel, int
+ end;
+implementation
-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;
+uses
+ SysUtils, {e_log,} utils, xparser, xstreams;
-implementation
+// ////////////////////////////////////////////////////////////////////////// //
+constructor TDFPoint.Create (ax, ay: LongInt); begin X := ax; Y := ay; end;
-uses
- {e_log,} xparser, xstreams;
+
+// ////////////////////////////////////////////////////////////////////////// //
+function TDynRecordHelper.getFieldWithType (const aname: AnsiString; atype: TDynField.TType): TDynField; inline;
+begin
+ result := field[aname];
+ if (result = nil) then raise Exception.Create(Format('field ''%s'' not found in record ''%s'' of type ''%s''', [aname, name, id]));
+ if (result.baseType <> atype) then raise Exception.Create(Format('field ''%s'' in record ''%s'' of type ''%s'' has invalid data type', [aname, name, id]));
+end;
-function GetMapHeader (rec: TDynRecord): TMapHeaderRec_1;
+function TDynRecordHelper.getPointField (const aname: AnsiString): TDFPoint; inline;
var
- ws: TSFSMemoryChunkStream = nil;
+ fld: TDynField;
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();
+ fld := field[aname];
+ if (fld = nil) then raise Exception.Create(Format('field ''%s'' not found in record ''%s'' of type ''%s''', [aname, name, id]));
+ if (fld.baseType <> TPoint) then raise Exception.Create(Format('field ''%s'' in record ''%s'' of type ''%s'' has invalid data type', [aname, name, id]));
+ result := TDFPoint.Create(fld.ival, fld.ival2);
end;
-function GetTextures (rec: TDynRecord): TTexturesRec1Array;
+function TDynRecordHelper.getPanelByIdx (idx: Integer): TDynRecord; inline;
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.count = 0) then exit;
- ws := TSFSMemoryChunkStream.Create(nil, 0);
- try
- SetLength(result, fld.count);
- for f := 0 to fld.count-1 do
- begin
- FillChar(result[f], sizeof(result[f]), 0);
- ws.setup(@result[f], sizeof(result[f]));
- fld.item[f].writeBinTo(ws, -1, true); // only fields
- end;
- except
- result := nil;
- end;
- ws.Free();
+ fld := headerRec['panel'];
+ if (fld <> nil) then result := fld.item[idx] else result := nil;
end;
-function GetPanels (rec: TDynRecord): TPanelsRec1Array;
+function TDynRecordHelper.getPanelIndex (pan: TDynRecord): Integer;
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.count = 0) then exit;
- ws := TSFSMemoryChunkStream.Create(nil, 0);
- try
- SetLength(result, fld.count);
- for f := 0 to fld.count-1 do
+ result := -1;
+ if (pan <> nil) then
+ begin
+ fld := headerRec['panel'];
+ if (fld <> nil) then
begin
- FillChar(result[f], sizeof(result[f]), 0);
- ws.setup(@result[f], sizeof(result[f]));
- fld.item[f].writeBinTo(ws, -1, true); // only fields
+ for f := 0 to fld.count-1 do if (fld.item[f] = pan) then begin result := f; exit; end;
end;
- except
- result := nil;
end;
- ws.Free();
end;
-function GetItems (rec: TDynRecord): TItemsRec1Array;
+function TDynRecordHelper.panelCount (): Integer; inline;
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.count = 0) then exit;
- ws := TSFSMemoryChunkStream.Create(nil, 0);
- try
- SetLength(result, fld.count);
- for f := 0 to fld.count-1 do
- begin
- FillChar(result[f], sizeof(result[f]), 0);
- ws.setup(@result[f], sizeof(result[f]));
- fld.item[f].writeBinTo(ws, -1, true); // only fields
- end;
- except
- result := nil;
- end;
- ws.Free();
+ fld := headerRec['panel'];
+ if (fld <> nil) then result := fld.count else result := 0;
end;
-function GetAreas (rec: TDynRecord): TAreasRec1Array;
+function TDynRecordHelper.TextureNum (): Word; inline;
var
- ws: TSFSMemoryChunkStream = nil;
+ idx: Integer;
fld: TDynField;
- f: Integer;
begin
- result := nil;
- fld := rec.field['area'];
- if (fld = nil) or (fld.baseType <> fld.TType.TList) or (fld.count = 0) then exit;
- ws := TSFSMemoryChunkStream.Create(nil, 0);
- try
- SetLength(result, fld.count);
- for f := 0 to fld.count-1 do
- begin
- FillChar(result[f], sizeof(result[f]), 0);
- ws.setup(@result[f], sizeof(result[f]));
- fld.item[f].writeBinTo(ws, -1, true); // only fields
- end;
- except
- result := nil;
- end;
- ws.Free();
+ fld := getFieldWithType('texture', TDynField.TType.TUShort);
+ idx := fld.recrefIndex;
+ if (idx < 0) then result := Word(TEXTURE_NONE) else result := Word(idx);
end;
-function GetMonsters (rec: TDynRecord): TMonsterRec1Array;
+// ////////////////////////////////////////////////////////////////////////// //
+// trigger
+function TDynRecordHelper.trigRec (): TDynRecord; inline;
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.count = 0) then exit;
- ws := TSFSMemoryChunkStream.Create(nil, 0);
- try
- SetLength(result, fld.count);
- for f := 0 to fld.count-1 do
- begin
- FillChar(result[f], sizeof(result[f]), 0);
- ws.setup(@result[f], sizeof(result[f]));
- fld.item[f].writeBinTo(ws, -1, true); // only fields
- end;
- except
- result := nil;
- end;
- ws.Free();
+ fld := getFieldWithType('triggerdata', TDynField.TType.TTrigData);
+ if (fld <> nil) then result := fld.recref else result := nil;
end;
-function GetTriggers (rec: TDynRecord): TTriggersRec1Array;
+function TDynRecordHelper.trigMonsterId (): Integer; inline;
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.count = 0) then exit;
- ws := TSFSMemoryChunkStream.Create(nil, 0);
- try
- //wr := TFileTextWriter.Create('z00.txt');
- SetLength(result, fld.count);
- for f := 0 to fld.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.item[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.item[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();
+ fld := getFieldWithType('monsterid', TDynField.TType.TInt);
+ result := fld.recrefIndex;
end;
+// ////////////////////////////////////////////////////////////////////////// //
+function TDynRecordHelper.mapName (): AnsiString; inline; begin result := utf2win(getFieldWithType('name', TDynField.TType.TChar).sval); end;
+function TDynRecordHelper.mapAuthor (): AnsiString; inline; begin result := utf2win(getFieldWithType('author', TDynField.TType.TChar).sval); end;
+function TDynRecordHelper.mapDesc (): AnsiString; inline; begin result := utf2win(getFieldWithType('description', TDynField.TType.TChar).sval); end;
+function TDynRecordHelper.musicName (): AnsiString; inline; begin result := utf2win(getFieldWithType('music', TDynField.TType.TChar).sval); end;
+function TDynRecordHelper.skyName (): AnsiString; inline; begin result := utf2win(getFieldWithType('sky', TDynField.TType.TChar).sval); end;
+function TDynRecordHelper.X (): Integer; inline; begin result := getFieldWithType('position', TDynField.TType.TPoint).ival; end;
+function TDynRecordHelper.Y (): Integer; inline; begin result := getFieldWithType('position', TDynField.TType.TPoint).ival2; end;
+function TDynRecordHelper.Width (): Word; inline; begin result := Word(getFieldWithType('size', TDynField.TType.TSize).ival); end;
+function TDynRecordHelper.Height (): Word; inline; begin result := Word(getFieldWithType('size', TDynField.TType.TSize).ival2); end;
+function TDynRecordHelper.PanelType (): Word; inline; begin result := Word(getFieldWithType('type', TDynField.TType.TUShort).ival); end;
+function TDynRecordHelper.TextureRec (): TDynRecord; inline; begin result := getFieldWithType('texture', TDynField.TType.TUShort).recref; end;
+function TDynRecordHelper.Alpha (): Byte; inline; begin result := Byte(getFieldWithType('alpha', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.Flags (): Byte; inline; begin result := Byte(getFieldWithType('flags', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.Resource (): AnsiString; inline; begin result := utf2win(getFieldWithType('path', TDynField.TType.TChar).sval); end;
+function TDynRecordHelper.Anim (): Boolean; inline; begin result := (getFieldWithType('animated', TDynField.TType.TBool).ival <> 0); end;
+function TDynRecordHelper.ItemType (): Byte; inline; begin result := Byte(getFieldWithType('type', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.Options (): Byte; inline; begin result := Byte(getFieldWithType('options', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.MonsterType (): Byte; inline; begin result := Byte(getFieldWithType('type', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.Direction (): Byte; inline; begin result := Byte(getFieldWithType('direction', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.AreaType (): Byte; inline; begin result := Byte(getFieldWithType('type', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.Enabled (): Boolean; inline; begin result := (getFieldWithType('enabled', TDynField.TType.TBool).ival <> 0); end;
+function TDynRecordHelper.TriggerType (): Byte; inline; begin result := Byte(getFieldWithType('type', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.ActivateType (): Byte; inline; begin result := Byte(getFieldWithType('activatetype', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.Keys (): Byte; inline; begin result := Byte(getFieldWithType('keys', TDynField.TType.TUByte).ival); end;
+
+function TDynRecordHelper.getPanelId (): Integer; inline; begin result := getFieldWithType('panelid', TDynField.TType.TInt).recrefIndex; end;
+function TDynRecordHelper.getTexturePanel (): Integer; begin result := getFieldWithType('texturepanel', TDynField.TType.TInt).recrefIndex; end;
+
+{$INCLUDE mapdef_impl.inc}
+
+
end.
diff --git a/src/shared/mapdef.inc b/src/shared/mapdef.inc
index 3ebc917df62bd7c01617fe03fc7932d17c409995..d744d9394d7e6ba0ea5cfeb9a0f14bb58ad24049 100644 (file)
--- a/src/shared/mapdef.inc
+++ b/src/shared/mapdef.inc
KEY_BLUETEAM = 16;
-// ////////////////////////////////////////////////////////////////////////// //
-// records
-type
- TMapHeaderRec_1 = packed record
- MapName: Char32;
- MapAuthor: Char32;
- MapDescription: Char256;
- MusicName: Char64;
- SkyName: Char64;
- Width, Height: Word;
- end;
-
- TTextureRec_1 = packed record
- Resource: Char64;
- Anim: Boolean;
- end;
-
- TPanelRec_1 = packed record
- X, Y: Integer;
- Width, Height: Word;
- TextureNum: Word;
- PanelType: Word;
- Alpha: Byte;
- Flags: Byte;
- end;
-
- TItemRec_1 = packed record
- X, Y: Integer;
- ItemType: Byte;
- Options: Byte;
- end;
-
- TMonsterRec_1 = packed record
- X, Y: Integer;
- MonsterType: Byte;
- Direction: Byte;
- end;
-
- TAreaRec_1 = packed record
- X, Y: Integer;
- AreaType: Byte;
- Direction: Byte;
- end;
-
- TTriggerRec_1 = packed record
- X, Y: Integer;
- Width, Height: Word;
- Enabled: Boolean;
- TexturePanel: LongInt;
- TriggerType: Byte;
- ActivateType: Byte;
- Keys: Byte;
- DATA: Byte128;
- end;
-
-
-
-// ////////////////////////////////////////////////////////////////////////// //
-// triggerdata
-type
- TTriggerData = record
- case Byte of
- 0: (Default: Byte128);
- TRIGGER_EXIT: (
- MapName: Char16;
- );
- TRIGGER_TELEPORT: (
- TargetPoint: TDFPoint;
- 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: LongInt;
- NoSound: Boolean;
- d2d_doors: Boolean;
- );
- TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF: (
- tX, tY: Integer;
- tWidth, tHeight: Word;
- Wait: Word;
- Count: Word;
- MonsterID: LongInt;
- 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: TDFPoint;
- MonType: Byte;
- MonHealth: LongInt;
- MonDir: Byte;
- MonActive: Boolean;
- MonCount: LongInt;
- MonEffect: Byte;
- MonMax: Word;
- MonDelay: Word;
- MonBehav: Byte;
- );
- TRIGGER_SPAWNITEM: (
- ItemPos: TDFPoint;
- ItemType: Byte;
- ItemFalls: Boolean;
- ItemOnlyDM: Boolean;
- ItemCount: LongInt;
- 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: Boolean;
- 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: (
- ShotPos: TDFPoint;
- ShotType: Byte;
- ShotTarget: Byte;
- ShotSound: Boolean;
- ShotAim: ShortInt;
- ShotPanelID: LongInt;
- ShotIntSight: Word;
- 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;
-
-
const defaultMapDef: AnsiString = ''+
#47#47#32#121#101#115#44#32#116#104#105#115#32#102#105#108#101#32#115#101+
#114#118#101#115#32#98#111#116#104#32#97#115#32#102#111#114#109#97#116#32+
diff --git a/src/shared/mapdef_help.inc b/src/shared/mapdef_help.inc
--- /dev/null
@@ -0,0 +1,88 @@
+// *** WARNING! ***
+// regenerate this part directly from "mapdef.txt" with 'mapgen', NEVER manually change anything here!
+
+function trigMapName (): AnsiString; inline;
+function trigTargetPoint (): TDFPoint; inline;
+function trigd2d_teleport (): Boolean; inline;
+function trigsilent_teleport (): Boolean; inline;
+function trigTlpDir (): Byte; inline;
+function trigNoSound (): Boolean; inline;
+function trigd2d_doors (): Boolean; inline;
+function trigTX (): LongInt; inline;
+function trigTY (): LongInt; inline;
+function trigTWidth (): Word; inline;
+function trigTHeight (): Word; inline;
+function trigWait (): Word; inline;
+function trigCount (): Word; inline;
+function trigExtRandom (): Boolean; inline;
+function trigActivateOnce (): Boolean; inline;
+function trigAnimOnce (): Boolean; inline;
+function trigSoundName (): AnsiString; inline;
+function trigVolume (): Byte; inline;
+function trigPan (): Byte; inline;
+function trigLocal (): Boolean; inline;
+function trigPlayCount (): Byte; inline;
+function trigSoundSwitch (): Boolean; inline;
+function trigMonPos (): TDFPoint; inline;
+function trigMonType (): Byte; inline;
+function trigMonHealth (): LongInt; inline;
+function trigMonDir (): Byte; inline;
+function trigMonActive (): Boolean; inline;
+function trigMonCount (): LongInt; inline;
+function trigMonEffect (): Byte; inline;
+function trigMonMax (): Word; inline;
+function trigMonDelay (): Word; inline;
+function trigMonBehav (): Byte; inline;
+function trigItemPos (): TDFPoint; inline;
+function trigItemType (): Byte; inline;
+function trigItemFalls (): Boolean; inline;
+function trigItemOnlyDM (): Boolean; inline;
+function trigItemCount (): LongInt; inline;
+function trigItemEffect (): Byte; inline;
+function trigItemMax (): Word; inline;
+function trigItemDelay (): Word; inline;
+function trigMusicName (): AnsiString; inline;
+function trigMusicAction (): Byte; inline;
+function trigPushAngle (): Word; inline;
+function trigPushForce (): Byte; inline;
+function trigResetVel (): Boolean; inline;
+function trigScoreAction (): Byte; inline;
+function trigScoreCount (): Byte; inline;
+function trigScoreTeam (): Byte; inline;
+function trigScoreCon (): Boolean; inline;
+function trigScoreMsg (): Boolean; inline;
+function trigMessageKind (): Byte; inline;
+function trigMessageSendTo (): Byte; inline;
+function trigMessageText (): AnsiString; inline;
+function trigMessageTime (): Word; inline;
+function trigDamageValue (): Word; inline;
+function trigDamageInterval (): Word; inline;
+function trigHealValue (): Word; inline;
+function trigHealInterval (): Word; inline;
+function trigHealMax (): Boolean; inline;
+function trigHealSilent (): Boolean; inline;
+function trigShotPos (): TDFPoint; inline;
+function trigShotType (): Byte; inline;
+function trigShotTarget (): Byte; inline;
+function trigShotSound (): Boolean; inline;
+function trigShotAim (): SmallInt; inline;
+function trigShotIntSight (): Word; inline;
+function trigShotAngle (): Word; inline;
+function trigShotWait (): Word; inline;
+function trigShotAccuracy (): Word; inline;
+function trigShotAmmo (): Word; inline;
+function trigShotIntReload (): Word; inline;
+function trigFXCount (): Byte; inline;
+function trigFXType (): Byte; inline;
+function trigFXSubType (): Byte; inline;
+function trigFXColorR (): Byte; inline;
+function trigFXColorG (): Byte; inline;
+function trigFXColorB (): Byte; inline;
+function trigFXPos (): Byte; inline;
+function trigFXWait (): Word; inline;
+function trigFXVelX (): SmallInt; inline;
+function trigFXVelY (): SmallInt; inline;
+function trigFXSpreadL (): Byte; inline;
+function trigFXSpreadR (): Byte; inline;
+function trigFXSpreadU (): Byte; inline;
+function trigFXSpreadD (): Byte; inline;
diff --git a/src/shared/mapdef_impl.inc b/src/shared/mapdef_impl.inc
--- /dev/null
@@ -0,0 +1,123 @@
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+// trigger helpers
+
+// TRIGGER_EXIT
+function TDynRecordHelper.trigMapName (): AnsiString; inline; begin result := utf2win(getFieldWithType('map', TDynField.TType.TChar).sval); end;
+
+// TRIGGER_TELEPORT
+function TDynRecordHelper.trigTargetPoint (): TDFPoint; inline; begin result := getPointField('target'); end;
+function TDynRecordHelper.trigd2d_teleport (): Boolean; inline; begin result := (getFieldWithType('d2d', TDynField.TType.TBool).ival <> 0); end;
+function TDynRecordHelper.trigsilent_teleport (): Boolean; inline; begin result := (getFieldWithType('silent', TDynField.TType.TBool).ival <> 0); end;
+function TDynRecordHelper.trigTlpDir (): Byte; inline; begin result := Byte(getFieldWithType('direction', TDynField.TType.TUByte).ival); end;
+
+// TRIGGER_OPENDOOR, TRIGGER_CLOSEDOOR, TRIGGER_DOOR, TRIGGER_DOOR5, TRIGGER_CLOSETRAP, TRIGGER_TRAP, TRIGGER_LIFTUP, TRIGGER_LIFTDOWN, TRIGGER_LIFT
+function TDynRecordHelper.trigNoSound (): Boolean; inline; begin result := (getFieldWithType('silent', TDynField.TType.TBool).ival <> 0); end;
+function TDynRecordHelper.trigd2d_doors (): Boolean; inline; begin result := (getFieldWithType('d2d', TDynField.TType.TBool).ival <> 0); end;
+
+// TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF
+function TDynRecordHelper.trigTX (): LongInt; inline; begin result := LongInt(getFieldWithType('position', TDynField.TType.TPoint).ival); end;
+function TDynRecordHelper.trigTY (): LongInt; inline; begin result := LongInt(getFieldWithType('position', TDynField.TType.TPoint).ival2); end;
+function TDynRecordHelper.trigTWidth (): Word; inline; begin result := Word(getFieldWithType('size', TDynField.TType.TSize).ival); end;
+function TDynRecordHelper.trigTHeight (): Word; inline; begin result := Word(getFieldWithType('size', TDynField.TType.TSize).ival2); end;
+function TDynRecordHelper.trigWait (): Word; inline; begin result := Word(getFieldWithType('wait', TDynField.TType.TUShort).ival); end;
+function TDynRecordHelper.trigCount (): Word; inline; begin result := Word(getFieldWithType('count', TDynField.TType.TUShort).ival); end;
+function TDynRecordHelper.trigExtRandom (): Boolean; inline; begin result := (getFieldWithType('extrandom', TDynField.TType.TBool).ival <> 0); end;
+
+// TRIGGER_SECRET
+
+// TRIGGER_TEXTURE
+function TDynRecordHelper.trigActivateOnce (): Boolean; inline; begin result := (getFieldWithType('activateonce', TDynField.TType.TBool).ival <> 0); end;
+function TDynRecordHelper.trigAnimOnce (): Boolean; inline; begin result := (getFieldWithType('animateonce', TDynField.TType.TBool).ival <> 0); end;
+
+// TRIGGER_SOUND
+function TDynRecordHelper.trigSoundName (): AnsiString; inline; begin result := utf2win(getFieldWithType('soundname', TDynField.TType.TChar).sval); end;
+function TDynRecordHelper.trigVolume (): Byte; inline; begin result := Byte(getFieldWithType('volume', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigPan (): Byte; inline; begin result := Byte(getFieldWithType('pan', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigLocal (): Boolean; inline; begin result := (getFieldWithType('local', TDynField.TType.TBool).ival <> 0); end;
+function TDynRecordHelper.trigPlayCount (): Byte; inline; begin result := Byte(getFieldWithType('playcount', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigSoundSwitch (): Boolean; inline; begin result := (getFieldWithType('soundswitch', TDynField.TType.TBool).ival <> 0); end;
+
+// TRIGGER_SPAWNMONSTER
+function TDynRecordHelper.trigMonPos (): TDFPoint; inline; begin result := getPointField('position'); end;
+function TDynRecordHelper.trigMonType (): Byte; inline; begin result := Byte(getFieldWithType('type', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigMonHealth (): LongInt; inline; begin result := LongInt(getFieldWithType('health', TDynField.TType.TInt).ival); end;
+function TDynRecordHelper.trigMonDir (): Byte; inline; begin result := Byte(getFieldWithType('direction', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigMonActive (): Boolean; inline; begin result := (getFieldWithType('active', TDynField.TType.TBool).ival <> 0); end;
+function TDynRecordHelper.trigMonCount (): LongInt; inline; begin result := LongInt(getFieldWithType('count', TDynField.TType.TInt).ival); end;
+function TDynRecordHelper.trigMonEffect (): Byte; inline; begin result := Byte(getFieldWithType('effect', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigMonMax (): Word; inline; begin result := Word(getFieldWithType('max', TDynField.TType.TUShort).ival); end;
+function TDynRecordHelper.trigMonDelay (): Word; inline; begin result := Word(getFieldWithType('delay', TDynField.TType.TUShort).ival); end;
+function TDynRecordHelper.trigMonBehav (): Byte; inline; begin result := Byte(getFieldWithType('behaviour', TDynField.TType.TUByte).ival); end;
+
+// TRIGGER_SPAWNITEM
+function TDynRecordHelper.trigItemPos (): TDFPoint; inline; begin result := getPointField('position'); end;
+function TDynRecordHelper.trigItemType (): Byte; inline; begin result := Byte(getFieldWithType('type', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigItemFalls (): Boolean; inline; begin result := (getFieldWithType('gravity', TDynField.TType.TBool).ival <> 0); end;
+function TDynRecordHelper.trigItemOnlyDM (): Boolean; inline; begin result := (getFieldWithType('dmonly', TDynField.TType.TBool).ival <> 0); end;
+function TDynRecordHelper.trigItemCount (): LongInt; inline; begin result := LongInt(getFieldWithType('count', TDynField.TType.TInt).ival); end;
+function TDynRecordHelper.trigItemEffect (): Byte; inline; begin result := Byte(getFieldWithType('effect', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigItemMax (): Word; inline; begin result := Word(getFieldWithType('max', TDynField.TType.TUShort).ival); end;
+function TDynRecordHelper.trigItemDelay (): Word; inline; begin result := Word(getFieldWithType('delay', TDynField.TType.TUShort).ival); end;
+
+// TRIGGER_MUSIC
+function TDynRecordHelper.trigMusicName (): AnsiString; inline; begin result := utf2win(getFieldWithType('name', TDynField.TType.TChar).sval); end;
+function TDynRecordHelper.trigMusicAction (): Byte; inline; begin result := Byte(getFieldWithType('action', TDynField.TType.TUByte).ival); end;
+
+// TRIGGER_PUSH
+function TDynRecordHelper.trigPushAngle (): Word; inline; begin result := Word(getFieldWithType('angle', TDynField.TType.TUShort).ival); end;
+function TDynRecordHelper.trigPushForce (): Byte; inline; begin result := Byte(getFieldWithType('force', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigResetVel (): Boolean; inline; begin result := (getFieldWithType('resetvelocity', TDynField.TType.TBool).ival <> 0); end;
+
+// TRIGGER_SCORE
+function TDynRecordHelper.trigScoreAction (): Byte; inline; begin result := Byte(getFieldWithType('action', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigScoreCount (): Byte; inline; begin result := Byte(getFieldWithType('count', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigScoreTeam (): Byte; inline; begin result := Byte(getFieldWithType('team', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigScoreCon (): Boolean; inline; begin result := (getFieldWithType('console', TDynField.TType.TBool).ival <> 0); end;
+function TDynRecordHelper.trigScoreMsg (): Boolean; inline; begin result := (getFieldWithType('message', TDynField.TType.TBool).ival <> 0); end;
+
+// TRIGGER_MESSAGE
+function TDynRecordHelper.trigMessageKind (): Byte; inline; begin result := Byte(getFieldWithType('kind', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigMessageSendTo (): Byte; inline; begin result := Byte(getFieldWithType('sendto', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigMessageText (): AnsiString; inline; begin result := utf2win(getFieldWithType('text', TDynField.TType.TChar).sval); end;
+function TDynRecordHelper.trigMessageTime (): Word; inline; begin result := Word(getFieldWithType('time', TDynField.TType.TUShort).ival); end;
+
+// TRIGGER_DAMAGE
+function TDynRecordHelper.trigDamageValue (): Word; inline; begin result := Word(getFieldWithType('amount', TDynField.TType.TUShort).ival); end;
+function TDynRecordHelper.trigDamageInterval (): Word; inline; begin result := Word(getFieldWithType('interval', TDynField.TType.TUShort).ival); end;
+
+// TRIGGER_HEALTH
+function TDynRecordHelper.trigHealValue (): Word; inline; begin result := Word(getFieldWithType('amount', TDynField.TType.TUShort).ival); end;
+function TDynRecordHelper.trigHealInterval (): Word; inline; begin result := Word(getFieldWithType('interval', TDynField.TType.TUShort).ival); end;
+function TDynRecordHelper.trigHealMax (): Boolean; inline; begin result := (getFieldWithType('max', TDynField.TType.TBool).ival <> 0); end;
+function TDynRecordHelper.trigHealSilent (): Boolean; inline; begin result := (getFieldWithType('silent', TDynField.TType.TBool).ival <> 0); end;
+
+// TRIGGER_SHOT
+function TDynRecordHelper.trigShotPos (): TDFPoint; inline; begin result := getPointField('position'); end;
+function TDynRecordHelper.trigShotType (): Byte; inline; begin result := Byte(getFieldWithType('type', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigShotTarget (): Byte; inline; begin result := Byte(getFieldWithType('target', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigShotSound (): Boolean; inline; begin result := (getFieldWithType('silent', TDynField.TType.TBool).ival = 0); end;
+function TDynRecordHelper.trigShotAim (): SmallInt; inline; begin result := ShortInt(getFieldWithType('aim', TDynField.TType.TByte).ival); end;
+function TDynRecordHelper.trigShotIntSight (): Word; inline; begin result := Word(getFieldWithType('sight', TDynField.TType.TUShort).ival); end;
+function TDynRecordHelper.trigShotAngle (): Word; inline; begin result := Word(getFieldWithType('angle', TDynField.TType.TUShort).ival); end;
+function TDynRecordHelper.trigShotWait (): Word; inline; begin result := Word(getFieldWithType('wait', TDynField.TType.TUShort).ival); end;
+function TDynRecordHelper.trigShotAccuracy (): Word; inline; begin result := Word(getFieldWithType('accuracy', TDynField.TType.TUShort).ival); end;
+function TDynRecordHelper.trigShotAmmo (): Word; inline; begin result := Word(getFieldWithType('ammo', TDynField.TType.TUShort).ival); end;
+function TDynRecordHelper.trigShotIntReload (): Word; inline; begin result := Word(getFieldWithType('reload', TDynField.TType.TUShort).ival); end;
+
+// TRIGGER_EFFECT
+function TDynRecordHelper.trigFXCount (): Byte; inline; begin result := Byte(getFieldWithType('count', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigFXType (): Byte; inline; begin result := Byte(getFieldWithType('type', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigFXSubType (): Byte; inline; begin result := Byte(getFieldWithType('subtype', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigFXColorR (): Byte; inline; begin result := Byte(getFieldWithType('colorr', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigFXColorG (): Byte; inline; begin result := Byte(getFieldWithType('colorg', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigFXColorB (): Byte; inline; begin result := Byte(getFieldWithType('colorb', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigFXPos (): Byte; inline; begin result := Byte(getFieldWithType('position', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigFXWait (): Word; inline; begin result := Word(getFieldWithType('wait', TDynField.TType.TUShort).ival); end;
+function TDynRecordHelper.trigFXVelX (): SmallInt; inline; begin result := ShortInt(getFieldWithType('velx', TDynField.TType.TByte).ival); end;
+function TDynRecordHelper.trigFXVelY (): SmallInt; inline; begin result := ShortInt(getFieldWithType('vely', TDynField.TType.TByte).ival); end;
+function TDynRecordHelper.trigFXSpreadL (): Byte; inline; begin result := Byte(getFieldWithType('spreadl', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigFXSpreadR (): Byte; inline; begin result := Byte(getFieldWithType('spreadr', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigFXSpreadU (): Byte; inline; begin result := Byte(getFieldWithType('spreadu', TDynField.TType.TUByte).ival); end;
+function TDynRecordHelper.trigFXSpreadD (): Byte; inline; begin result := Byte(getFieldWithType('spreadd', TDynField.TType.TUByte).ival); end;
diff --git a/src/shared/xdynrec.pas b/src/shared/xdynrec.pas
index 37d27dfca414f09c812edf9af38aa0ed6c9a31be..8ebac36188754ef6349bbb7bbc5147a1a0ccfe7a 100644 (file)
--- a/src/shared/xdynrec.pas
+++ b/src/shared/xdynrec.pas
mRecRef: TDynRecord; // for TEBS.TRec
mMaxDim: Integer; // for byte and char arrays; <0: not an array; 0: impossible value
mBinOfs: Integer; // offset in binary; <0 - none
- mRecOfs: Integer; // offset in record; <0 - none
mSepPosSize: Boolean; // for points and sizes, use separate fields
mAsT: Boolean; // for points and sizes, use separate fields, names starts with `t`
mDefined: Boolean;
// for binary parser
mRecRefId: AnsiString;
+ // for userdata
+ mTagInt: Integer;
+ mTagPtr: Pointer;
+
private
procedure cleanup ();
function getListItem (idx: Integer): TDynRecord; inline; overload;
function getListItem (const aname: AnsiString): TDynRecord; inline; overload;
+ function getRecRefIndex (): Integer;
+
+ procedure setIVal (v: Integer); inline;
+
protected
// returns `true` for duplicate record id
function addListItem (rec: TDynRecord): Boolean; inline;
+ public
+ type
+ TListEnumerator = record
+ private
+ mList: TDynRecList;
+ mCurIdx: Integer;
+ public
+ constructor Create (alist: TDynRecList);
+ function MoveNext (): Boolean; inline;
+ function getCurrent (): TDynRecord; inline;
+ property Current: TDynRecord read getCurrent;
+ end;
+
public
constructor Create (const aname: AnsiString; atype: TType);
constructor Create (pr: TTextParser);
procedure setValue (const s: AnsiString);
+ function GetEnumerator (): TListEnumerator;
+
public
property pasname: AnsiString read mPasName;
property name: AnsiString read mName;
property baseType: TType read mType;
+ property negbool: Boolean read mNegBool;
property defined: Boolean read mDefined write mDefined;
property internal: Boolean read mInternal write mInternal;
- property ival: Integer read mIVal;
+ property hasTPrefix: Boolean read mAsT;
+ property separatePasFields: Boolean read mSepPosSize;
+ property binOfs: Integer read mBinOfs;
+ property ival: Integer read mIVal write setIVal;
+ property ival2: Integer read mIVal2;
property sval: AnsiString read mSVal;
property hasDefault: Boolean read mHasDefault;
property defsval: AnsiString read mDefSVal;
property ebs: TEBS read mEBS;
property ebstype: TObject read mEBSType;
property ebstypename: AnsiString read mEBSTypeName; // enum/bitset name
+ property recref: TDynRecord read mRecRef write mRecRef; //FIXME: writing is a hack!
+ property recrefIndex: Integer read getRecRefIndex; // search for this record in header; -1: not found
// for lists
property count: Integer read getListCount;
property item[idx: Integer]: TDynRecord read getListItem;
property items[const aname: AnsiString]: TDynRecord read getListItem; default; // alas, FPC 3+ lost property overloading feature
-
- property x: Integer read mIVal;
- property w: Integer read mIVal;
- property y: Integer read mIVal2;
- property h: Integer read mIVal2;
+ // userdata
+ property tagInt: Integer read mTagInt write mTagInt;
+ property tagPtr: Pointer read mTagPtr write mTagPtr;
end;
mBinBlock: Integer; // -1: none
mHeaderRec: TDynRecord; // for "value" records this is header record with data, for "type" records this is header type record
+ // for userdata
+ mTagInt: Integer;
+ mTagPtr: Pointer;
+
private
procedure parseDef (pr: TTextParser); // parse definition
function findByName (const aname: AnsiString): Integer; inline;
function hasByName (const aname: AnsiString): Boolean; inline;
function getFieldByName (const aname: AnsiString): TDynField; inline;
+ function getFieldAt (idx: Integer): TDynField; inline;
+ function getCount (): Integer; inline;
function getIsTrigData (): Boolean; inline;
function getIsForTrig (const aname: AnsiString): Boolean; inline;
+ function getForTrigCount (): Integer; inline;
+ function getForTrigAt (idx: Integer): AnsiString; inline;
+
protected
function findRecordByTypeId (const atypename, aid: AnsiString): TDynRecord;
function findRecordNumByType (const atypename: AnsiString; rc: TDynRecord): Integer;
property size: Integer read mSize; // size in bytes
//property fields: TDynFieldList read mFields;
property has[const aname: AnsiString]: Boolean read hasByName;
- property field[const aname: AnsiString]: TDynField read getFieldByName;
+ property count: Integer read getCount;
+ property field[const aname: AnsiString]: TDynField read getFieldByName; default;
+ property fieldAt[idx: Integer]: TDynField read getFieldAt;
property isTrigData: Boolean read getIsTrigData;
property isForTrig[const aname: AnsiString]: Boolean read getIsForTrig;
- property headerType: TDynRecord read mHeaderRec;
+ property forTrigCount: Integer read getForTrigCount;
+ property forTrigAt[idx: Integer]: AnsiString read getForTrigAt;
+ property headerRec: TDynRecord read mHeaderRec;
property isHeader: Boolean read mHeader;
+ // userdata
+ property tagInt: Integer read mTagInt write mTagInt;
+ property tagPtr: Pointer read mTagPtr write mTagPtr;
end;
TDynEBS = class
function getHeaderRecType (): TDynRecord; inline;
+ function getTrigTypeCount (): Integer; inline;
+ function getTrigTypeAt (idx: Integer): TDynRecord; inline;
+
public
constructor Create (pr: TTextParser); // parses data definition
destructor Destroy (); override;
function findEBSType (const aname: AnsiString): TDynEBS;
function pasdef (): AnsiString;
+ function pasdefconst (): AnsiString;
// creates new header record
function parseMap (pr: TTextParser): TDynRecord;
public
property headerType: TDynRecord read getHeaderRecType;
+ property trigTypeCount: Integer read getTrigTypeCount;
+ property trigType[idx: Integer]: TDynRecord read getTrigTypeAt;
end;
function StrEqu (const a, b: AnsiString): Boolean; inline; begin result := (a = b); end;
+// ////////////////////////////////////////////////////////////////////////// //
+constructor TDynField.TListEnumerator.Create (alist: TDynRecList);
+begin
+ mList := alist;
+ mCurIdx := -1;
+end;
+
+
+function TDynField.TListEnumerator.MoveNext (): Boolean; inline;
+begin
+ Inc(mCurIdx);
+ result := (mList <> nil) and (mCurIdx < mList.count);
+end;
+
+
+function TDynField.TListEnumerator.getCurrent (): TDynRecord; inline;
+begin
+ result := mList[mCurIdx];
+end;
+
+
+function TDynField.GetEnumerator (): TListEnumerator;
+begin
+ result := TListEnumerator.Create(mRVal);
+end;
+
+
// ////////////////////////////////////////////////////////////////////////// //
constructor TDynField.Create (const aname: AnsiString; atype: TType);
begin
mRecRef := nil;
mMaxDim := -1;
mBinOfs := -1;
- mRecOfs := -1;
mSepPosSize := false;
mAsT := false;
mHasDefault := false;
mAsMonsterId := false;
mNegBool := false;
mRecRefId := '';
+ mTagInt := 0;
+ mTagPtr := nil;
end;
result.mRecRef := mRecRef;
result.mMaxDim := mMaxDim;
result.mBinOfs := mBinOfs;
- result.mRecOfs := mRecOfs;
result.mSepPosSize := mSepPosSize;
result.mAsT := mAsT;
result.mDefined := mDefined;
result.mEBSTypeName := mEBSTypeName;
result.mEBSType := mEBSType;
result.mRecRefId := mRecRefId;
+ result.mTagInt := mTagInt;
+ result.mTagPtr := mTagPtr;
+end;
+
+
+procedure TDynField.setIVal (v: Integer); inline;
+begin
+ //FIXME: check type
+ mIVal := v;
+ mDefined := true;
end;
result := mPasName+' is '+quoteStr(mName)+' type ';
result += getTypeName(mType);
if (mMaxDim >= 0) then result += Format('[%d]', [mMaxDim]);
- if (mRecOfs >= 0) then result += Format(' offset %d', [mRecOfs]);
+ if (mBinOfs >= 0) then result += Format(' offset %d', [mBinOfs]);
case mEBS of
TEBS.TNone: begin end;
TEBS.TRec: result += ' '+mEBSTypeName;
self.mAsMonsterId := asmonid;
self.mMaxDim := lmaxdim;
self.mBinOfs := fldofs;
- self.mRecOfs := fldofs;
self.mSepPosSize := (asxy or aswh);
self.mAsT := ast;
self.mOmitDef := omitdef;
end;
+function TDynField.getRecRefIndex (): Integer;
+begin
+ if (mRecRef = nil) then begin result := -1; exit; end;
+ result := mOwner.findRecordNumByType(mEBSTypeName, mRecRef);
+end;
+
+
procedure TDynField.writeBinTo (st: TStream);
var
s: AnsiString;
raise Exception.Create(Format('cannot parse field ''%s'' yet', [mName]));
end;
+
procedure TDynField.parseBinValue (st: TStream);
var
rec, rc: TDynRecord;
mHeader := false;
mHeaderRec := nil;
mBinBlock := -1;
+ mTagInt := 0;
+ mTagPtr := nil;
parseDef(pr);
end;
mTrigTypes := nil;
mHeader := false;
mHeaderRec := nil;
+ mTagInt := 0;
+ mTagPtr := nil;
end;
{$ENDIF}
mTrigTypes := nil;
mHeaderRec := nil;
+ mTagInt := 0;
+ mTagPtr := nil;
inherited;
end;
end;
+function TDynRecord.getFieldAt (idx: Integer): TDynField; inline;
+begin
+ if (idx >= 0) and (idx < mFields.count) then result := mFields[idx] else result := nil;
+end;
+
+
+function TDynRecord.getCount (): Integer; inline;
+begin
+ result := mFields.count;
+end;
+
+
function TDynRecord.getIsTrigData (): Boolean; inline;
begin
result := (Length(mTrigTypes) > 0);
end;
+function TDynRecord.getForTrigCount (): Integer; inline;
+begin
+ result := Length(mTrigTypes);
+end;
+
+
+function TDynRecord.getForTrigAt (idx: Integer): AnsiString; inline;
+begin
+ if (idx >= 0) and (idx < Length(mTrigTypes)) then result := mTrigTypes[idx] else result := '';
+end;
+
+
function TDynRecord.clone (): TDynRecord;
var
fld: TDynField;
result.mHeader := mHeader;
result.mBinBlock := mBinBlock;
result.mHeaderRec := mHeaderRec;
+ result.mTagInt := mTagInt;
+ result.mTagPtr := mTagPtr;
end;
end;
+function TDynMapDef.pasdefconst (): AnsiString;
+var
+ ebs: TDynEBS;
+begin
+ result := '';
+ result += '// ////////////////////////////////////////////////////////////////////////// //'#10;
+ result += '// enums and bitsets'#10;
+ for ebs in ebsTypes do result += #10+ebs.pasdef();
+end;
+
+
+function TDynMapDef.getTrigTypeCount (): Integer; inline; begin result := trigTypes.count; end;
+function TDynMapDef.getTrigTypeAt (idx: Integer): TDynRecord; inline; begin if (idx >= 0) and (idx < trigTypes.count) then result := trigTypes[idx] else result := nil; end;
+
+
end.
diff --git a/src/tools/mapgen.dpr b/src/tools/mapgen.dpr
index 9a98f712be4e676662a34514530cdf60997f14ff..c53aa4eb9ee22b74608b8e0d873f53c3d7df9db3 100644 (file)
--- a/src/tools/mapgen.dpr
+++ b/src/tools/mapgen.dpr
var
pr: TTextParser;
dfmapdef: TDynMapDef;
- fo: TextFile;
+ fo, fohlp, foimpl: TextFile;
st: TStream = nil;
ch: AnsiChar;
wdt: Integer;
s: AnsiString;
+ tidx, nidx, fidx: Integer;
+ needComma: Boolean;
+ trec: TDynRecord;
+ fld: TDynField;
begin
//writeln(getFilenamePath(ParamStr(0)), '|');
writeln('writing "mapdef.inc"...');
AssignFile(fo, 'mapdef.inc');
Rewrite(fo);
+
+ AssignFile(fohlp, 'mapdef_help.inc');
+ Rewrite(fohlp);
+
+ AssignFile(foimpl, 'mapdef_impl.inc');
+ Rewrite(foimpl);
+
write(fo, '// *** WARNING! ***'#10);
write(fo, '// regenerate this part directly from "mapdef.txt" with ''mapgen'', NEVER manually change anything here!'#10#10#10);
- write(fo, dfmapdef.pasdef);
+ write(fo, dfmapdef.pasdefconst);
+
+ write(fohlp, '// *** WARNING! ***'#10);
+ write(fohlp, '// regenerate this part directly from "mapdef.txt" with ''mapgen'', NEVER manually change anything here!'#10#10);
+
+ // generate trigger helpers
+{
+function TDynRecordHelper.trigTargetPoint (): TDFPoint; inline; begin result := getPointField('target'); end;
+function TDynRecordHelper.trigD2DTeleport (): Boolean; inline; begin result := (getFieldWithType('d2d', TDynField.TType.TBool).ival <> 0); end;
+function TDynRecordHelper.trigSilentTeleport (): Boolean; inline; begin result := (getFieldWithType('silent', TDynField.TType.TBool).ival <> 0); end;
+function TDynRecordHelper.trigTlpDir (): Byte; inline; begin result := Byte(getFieldWithType('direction', TDynField.TType.TUByte).ival); end;
+}
+
+ write(foimpl, #10#10'// ////////////////////////////////////////////////////////////////////////// //'#10);
+ write(foimpl, '// trigger helpers'#10);
+ for tidx := 0 to dfmapdef.trigTypeCount-1 do
+ begin
+ // header comment
+ write(foimpl, #10'// ');
+ needComma := false;
+ trec := dfmapdef.trigType[tidx];
+ for nidx := 0 to trec.forTrigCount-1 do
+ begin
+ if needComma then write(foimpl, ', ') else needComma := true;
+ write(foimpl, trec.forTrigAt[nidx]);
+ end;
+ write(foimpl, #10);
+ // fields
+ for fidx := 0 to trec.count-1 do
+ begin
+ fld := trec.fieldAt[fidx];
+ if fld.internal then continue;
+ if (fld.binOfs < 0) then continue;
+ // HACK!
+ if (fld.name = 'panelid') or (fld.name = 'monsterid') then
+ begin
+ writeln('skipping ', fld.pasname, ' <', fld.name, '>');
+ continue;
+ end;
+ if (fld.baseType <> TDynField.TType.TPoint) and (fld.baseType <> TDynField.TType.TSize) then
+ begin
+ write(foimpl, 'function TDynRecordHelper.trig', fld.pasname, ' (): ');
+ write(fohlp, 'function trig', fld.pasname, ' (): ');
+ end;
+ case fld.baseType of
+ TDynField.TType.TBool:
+ begin
+ write(fohlp, 'Boolean; inline;'#10);
+ write(foimpl, 'Boolean; inline; begin result := (getFieldWithType(''', fld.name, ''', TDynField.TType.TBool).ival ');
+ if fld.negbool then write(foimpl, '=') else write(foimpl, '<>');
+ write(foimpl, ' 0); end;'#10);
+ end;
+ TDynField.TType.TChar:
+ begin
+ write(fohlp, 'AnsiString; inline;'#10);
+ write(foimpl, 'AnsiString; inline; begin result := utf2win(getFieldWithType(''', fld.name, ''', TDynField.TType.TChar).sval); end;'#10);
+ end;
+ TDynField.TType.TByte:
+ begin
+ write(fohlp, 'SmallInt; inline;'#10);
+ write(foimpl, 'SmallInt; inline; begin result := ShortInt(getFieldWithType(''', fld.name, ''', TDynField.TType.TByte).ival); end;'#10);
+ end;
+ TDynField.TType.TUByte:
+ begin
+ write(fohlp, 'Byte; inline;'#10);
+ write(foimpl, 'Byte; inline; begin result := Byte(getFieldWithType(''', fld.name, ''', TDynField.TType.TUByte).ival); end;'#10);
+ end;
+ TDynField.TType.TShort:
+ begin
+ write(fohlp, 'ShortInt; inline;'#10);
+ write(foimpl, 'ShortInt; inline; begin result := SmallInt(getFieldWithType(''', fld.name, ''', TDynField.TType.TShort).ival); end;'#10);
+ end;
+ TDynField.TType.TUShort:
+ begin
+ write(fohlp, 'Word; inline;'#10);
+ write(foimpl, 'Word; inline; begin result := Word(getFieldWithType(''', fld.name, ''', TDynField.TType.TUShort).ival); end;'#10);
+ end;
+ TDynField.TType.TInt:
+ begin
+ write(fohlp, 'LongInt; inline;'#10);
+ write(foimpl, 'LongInt; inline; begin result := LongInt(getFieldWithType(''', fld.name, ''', TDynField.TType.TInt).ival); end;'#10);
+ end;
+ TDynField.TType.TUInt:
+ begin
+ write(fohlp, 'LongWord; inline;'#10);
+ write(foimpl, 'LongWord; inline; begin result := LongWord(getFieldWithType(''', fld.name, ''', TDynField.TType.TUInt).ival); end;'#10);
+ end;
+ TDynField.TType.TString:
+ begin
+ write(fohlp, 'AnsiString; inline;'#10);
+ write(foimpl, 'AnsiString; inline; begin result := utf2win(getFieldWithType(''', fld.name, ''', TDynField.TType.TChar).sval); end;'#10);
+ end;
+ TDynField.TType.TPoint:
+ begin
+ if fld.hasTPrefix or fld.separatePasFields then
+ begin
+ write(fohlp, 'function trig'); if fld.hasTPrefix then write(fohlp, 'T'); write(fohlp, 'X (): LongInt; inline;'#10);
+ write(fohlp, 'function trig'); if fld.hasTPrefix then write(fohlp, 'T'); write(fohlp, 'Y (): LongInt; inline;'#10);
+ // [T]X
+ write(foimpl, 'function TDynRecordHelper.trig');
+ if fld.hasTPrefix then write(foimpl, 'T');
+ write(foimpl, 'X (): LongInt; inline; begin result := LongInt(getFieldWithType(''', fld.name, ''', TDynField.TType.TPoint).ival); end;'#10);
+ // [T]Y
+ write(foimpl, 'function TDynRecordHelper.trig');
+ if fld.hasTPrefix then write(foimpl, 'T');
+ write(foimpl, 'Y (): LongInt; inline; begin result := LongInt(getFieldWithType(''', fld.name, ''', TDynField.TType.TPoint).ival2); end;'#10);
+ end
+ else
+ begin
+ write(fohlp, 'function trig', fld.pasname, ' (): TDFPoint; inline;'#10);
+ write(foimpl, 'function TDynRecordHelper.trig', fld.pasname, ' (): TDFPoint; inline; begin result := getPointField(''', fld.name, '''); end;'#10);
+ end;
+ end;
+ TDynField.TType.TSize:
+ begin
+ if fld.hasTPrefix or fld.separatePasFields then
+ begin
+ write(fohlp, 'function trig'); if fld.hasTPrefix then write(fohlp, 'T'); write(fohlp, 'Width (): Word; inline;'#10);
+ write(fohlp, 'function trig'); if fld.hasTPrefix then write(fohlp, 'T'); write(fohlp, 'Height (): Word; inline;'#10);
+ // [T]X
+ write(foimpl, 'function TDynRecordHelper.trig');
+ if fld.hasTPrefix then write(foimpl, 'T');
+ write(foimpl, 'Width (): Word; inline; begin result := Word(getFieldWithType(''', fld.name, ''', TDynField.TType.TSize).ival); end;'#10);
+ // [T]Y
+ write(foimpl, 'function TDynRecordHelper.trig');
+ if fld.hasTPrefix then write(foimpl, 'T');
+ write(foimpl, 'Height (): Word; inline; begin result := Word(getFieldWithType(''', fld.name, ''', TDynField.TType.TSize).ival2); end;'#10);
+ end
+ else
+ begin
+ raise Exception.Create('no non-separate sizes in triggers, pelase');
+ end;
+ end;
+ TDynField.TType.TList:
+ raise Exception.Create('no lists in triggers, pelase');
+ TDynField.TType.TTrigData:
+ raise Exception.Create('no triggers in triggers, pelase');
+ end;
+ end;
+ end;
+
//st := openDiskFileRO('mapdef.txt');
st.position := 0;
write(fo, #10';');
CloseFile(fo);
+ CloseFile(fohlp);
+ CloseFile(foimpl);
end.