diff --git a/src/game/g_map.pas b/src/game/g_map.pas
index 50b0d2669ae576f4647c599664b6d7c38dc094d2..33571b8bcd182fb5b61cbae55bfabfcd3c9f4a33 100644 (file)
--- a/src/game/g_map.pas
+++ b/src/game/g_map.pas
function g_Map_traceToNearest (x0, y0, x1, y1: Integer; tag: Integer; hitx: PInteger=nil; hity: PInteger=nil): TPanel;
type
- TForEachPanelCB = function (pan: TPanel): Boolean; // return `true` to stop
+ TForEachPanelCB = function (pan: TPanel): Boolean is nested; // return `true` to stop
function g_Map_HasAnyPanelAtPoint (x, y: Integer; panelType: Word): Boolean;
function g_Map_PanelAtPoint (x, y: Integer; tagmask: Integer=-1): TPanel;
function g_Map_TraceLiquidNonPrecise (x, y, dx, dy: Integer; out topx, topy: Integer): Boolean;
+// return `true` from `cb` to stop
+function g_Map_ForEachPanel (cb: TForEachPanelCB): TPanel;
+
+procedure g_Map_NetSendInterestingPanels (); // yay!
+
+
procedure g_Map_ProfilersBegin ();
procedure g_Map_ProfilersEnd ();
end;
+// return `true` from `cb` to stop
+function g_Map_ForEachPanel (cb: TForEachPanelCB): TPanel;
+var
+ pan: TPanel;
+begin
+ result := nil;
+ if not assigned(cb) then exit;
+ for pan in panByGUID do
+ begin
+ if cb(pan) then begin result := pan; exit; end;
+ end;
+end;
+
+
+procedure g_Map_NetSendInterestingPanels ();
+var
+ pan: TPanel;
+begin
+ if g_Game_IsServer and g_Game_IsNet then
+ begin
+ for pan in panByGUID do
+ begin
+ if pan.gncNeedSend then MH_SEND_PanelState(pan.guid);
+ end;
+ end;
+end;
+
+
// ////////////////////////////////////////////////////////////////////////// //
function g_Map_MinX (): Integer; inline; begin if (mapGrid <> nil) then result := mapGrid.gridX0 else result := 0; end;
function g_Map_MinY (): Integer; inline; begin if (mapGrid <> nil) then result := mapGrid.gridY0 else result := 0; end;
result := 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])
+ if (pr <> nil) then e_LogWritefln('ERROR at (%s,%s): %s', [pr.tokLine, pr.tokCol, e.message])
else e_LogWritefln('ERROR: %s', [e.message]);
pr.Free(); // will free `wst`
result := nil;
PanelArray := nil;
end;
-function CreatePanel (PanelRec: TDynRecord; AddTextures: TAddTextureArray; CurTex: Integer; sav: Boolean): Integer;
+function CreatePanel (PanelRec: TDynRecord; AddTextures: TAddTextureArray; CurTex: Integer): Integer;
var
len: Integer;
panels: ^TPanelArray;
pan.arrIdx := len;
pan.proxyId := -1;
pan.tag := panelTypeToTag(PanelRec.PanelType);
- if sav then pan.SaveIt := True;
PanelRec.user['panel_guid'] := pguid;
end;
end;
-procedure CreateTrigger (amapIdx: Integer; Trigger: TDynRecord; atpanid, atrigpanid: Integer; fTexturePanel1Type, fTexturePanel2Type: Word);
+function CreateTrigger (amapIdx: Integer; Trigger: TDynRecord; atpanid, atrigpanid: Integer; fTexturePanel1Type, fTexturePanel2Type: Word): Integer;
var
_trigger: TTrigger;
begin
+ result := -1;
if g_Game_IsClient and not (Trigger.TriggerType in [TRIGGER_SOUND, TRIGGER_MUSIC]) then Exit;
with _trigger do
end;
end;
- g_Triggers_Create(_trigger);
+ result := Integer(g_Triggers_Create(_trigger));
end;
procedure CreateMonster(monster: TDynRecord);
PTRec = ^TTRec;
TTRec = record
//TexturePanel: Integer;
+ tnum: Integer;
+ id: Integer;
texPanIdx: Integer;
LiftPanelIdx: Integer;
DoorPanelIdx: Integer;
FileName, mapResName, s, TexName: String;
Data: Pointer;
Len: Integer;
- ok, isAnim, trigRef: Boolean;
+ ok, isAnim: Boolean;
CurTex, ntn: Integer;
rec, texrec: TDynRecord;
pttit: PTRec;
stt: UInt64;
moveSpeed{, moveStart, moveEnd}: TDFPoint;
//moveActive: Boolean;
+ pan: TPanel;
begin
mapGrid.Free();
mapGrid := nil;
FreeMem(Data);
+ if (mapReader = nil) then
+ begin
+ e_LogWritefln('invalid map file: ''%s''', [mapResName]);
+ exit;
+ end;
+
generateExternalResourcesList(mapReader);
mapTextureList := mapReader['texture'];
// get all other lists here too
//e_LogWritefln('PANSTART: pannum=%s', [pannum]);
texrec := nil;
SetLength(AddTextures, 0);
- trigRef := False;
CurTex := -1;
ok := false;
ok := false;
if (TriggersTable <> nil) and (mapTextureList <> nil) then
begin
- {
- for b := 0 to High(TriggersTable) do
- begin
- if (TriggersTable[b].texPan = rec) or (TriggersTable[b].shotPan = rec) then
- begin
- trigRef := True;
- ok := True;
- break;
- end;
- end;
- }
if rec.userPanelTrigRef then
begin
// e_LogWritefln('trigref for panel %s', [pannum]);
- trigRef := True;
ok := True;
end;
end;
//e_LogWritefln('PANADD: pannum=%s', [pannum]);
// Ñîçäàåì ïàíåëü è çàïîìèíàåì åå GUID
- PanelID := CreatePanel(rec, AddTextures, CurTex, trigRef);
+ PanelID := CreatePanel(rec, AddTextures, CurTex);
//e_LogWritefln('panel #%s of type %s got guid #%s', [pannum, rec.PanelType, PanelID]);
rec.userPanelId := PanelID; // remember game panel id, we'll fix triggers later
else if (TriggersTable[trignum].MPlatPanelIdx <> -1) then tgpid := TriggersTable[trignum].MPlatPanelIdx
else tgpid := -1;
//e_LogWritefln('creating trigger #%s; texpantype=%s; shotpantype=%s (%d,%d)', [trignum, b, c, TriggersTable[trignum].texPanIdx, TriggersTable[trignum].ShotPanelIdx]);
- CreateTrigger(trignum, rec, TriggersTable[trignum].texPanIdx, tgpid, Word(b), Word(c));
+ TriggersTable[trignum].tnum := trignum;
+ TriggersTable[trignum].id := CreateTrigger(trignum, rec, TriggersTable[trignum].texPanIdx, tgpid, Word(b), Word(c));
+ end;
+ end;
+
+ //FIXME: use hashtable!
+ for pan in panByGUID do
+ begin
+ if (pan.endPosTrigId >= 0) and (pan.endPosTrigId < Length(TriggersTable)) then
+ begin
+ pan.endPosTrigId := TriggersTable[pan.endPosTrigId].id;
+ end;
+ if (pan.endSizeTrigId >= 0) and (pan.endSizeTrigId < Length(TriggersTable)) then
+ begin
+ pan.endSizeTrigId := TriggersTable[pan.endSizeTrigId].id;
end;
end;
FreeMem(Data);
+ if (mapReader = nil) then exit;
+
if (mapReader.Width > 0) and (mapReader.Height > 0) then
begin
Result.Name := mapReader.MapName;
//pan := gWalls[ID];
pan := g_Map_PanelByGUID(pguid);
if (pan = nil) then exit;
+ if pan.Enabled and mapGrid.proxyEnabled[pan.proxyId] then exit;
+
pan.Enabled := True;
g_Mark(pan.X, pan.Y, pan.Width, pan.Height, MARK_DOOR, true);
//if (pan.proxyId >= 0) then mapGrid.proxyEnabled[pan.proxyId] := true
//else pan.proxyId := mapGrid.insertBody(pan, pan.X, pan.Y, pan.Width, pan.Height, GridTagDoor);
- if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState({gWalls[ID]}pan.PanelType, pguid);
+ //if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState(pguid);
+ // mark platform as interesting
+ pan.setDirty();
{$IFDEF MAP_DEBUG_ENABLED_FLAG}
//e_WriteLog(Format('ENABLE: wall #%d(%d) enabled (%d) (%d,%d)-(%d,%d)', [Integer(ID), Integer(pan.proxyId), Integer(mapGrid.proxyEnabled[pan.proxyId]), pan.x, pan.y, pan.width, pan.height]), MSG_NOTIFY);
//pan := gWalls[ID];
pan := g_Map_PanelByGUID(pguid);
if (pan = nil) then exit;
+ if (not pan.Enabled) and (not mapGrid.proxyEnabled[pan.proxyId]) then exit;
+
pan.Enabled := False;
g_Mark(pan.X, pan.Y, pan.Width, pan.Height, MARK_DOOR, false);
mapGrid.proxyEnabled[pan.proxyId] := false;
//if (pan.proxyId >= 0) then begin mapGrid.removeBody(pan.proxyId); pan.proxyId := -1; end;
- if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState(pan.PanelType, pguid);
+ //if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState(pguid);
+ // mark platform as interesting
+ pan.setDirty();
{$IFDEF MAP_DEBUG_ENABLED_FLAG}
//e_WriteLog(Format('DISABLE: wall #%d(%d) disabled (%d) (%d,%d)-(%d,%d)', [Integer(ID), Integer(pan.proxyId), Integer(mapGrid.proxyEnabled[pan.proxyId]), pan.x, pan.y, pan.width, pan.height]), MSG_NOTIFY);
}
tp.NextTexture(AnimLoop);
- if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelTexture(PanelType, pguid, AnimLoop);
+ if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelTexture(pguid, AnimLoop);
end;
3: g_Mark(X, Y, Width, Height, MARK_LIFTRIGHT);
end;
- if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState(PanelType, pguid);
+ //if g_Game_IsServer and g_Game_IsNet then MH_SEND_PanelState(pguid);
+ // mark platform as interesting
+ pan.setDirty();
end;
end;
var
PAMem: TBinMemoryWriter;
pan: TPanel;
+ count: Integer;
begin
// Ñîçäàåì íîâûé ñïèñîê ñîõðàíÿåìûõ ïàíåëåé
PAMem := TBinMemoryWriter.Create((Length(panByGUID)+1) * 40);
- for pan in panByGUID do
- begin
- if true{pan.SaveIt} then
- begin
- // ID ïàíåëè
- //PAMem.WriteInt(i);
- // Ñîõðàíÿåì ïàíåëü
- pan.SaveState(PAMem);
- end;
- end;
+ // Ñîõðàíÿåì ïàíåëè
+ count := Length(panByGUID);
+ Mem.WriteInt(count);
+ for pan in panByGUID do pan.SaveState(PAMem);
// Ñîõðàíÿåì ýòîò ñïèñîê ïàíåëåé
PAMem.SaveToMemory(Mem);
var
PAMem: TBinMemoryReader;
pan: TPanel;
+ count: LongInt;
begin
// Çàãðóæàåì òåêóùèé ñïèñîê ïàíåëåé
PAMem := TBinMemoryReader.Create();
PAMem.LoadFromMemory(Mem);
+ // Çàãðóæàåì ïàíåëè
+ PAMem.ReadInt(count);
+ if (count <> Length(panByGUID)) then raise EBinSizeError.Create('g_Map_LoadState: LoadPanelArray: invalid number of panels');
for pan in panByGUID do
begin
- if true{pan.SaveIt} then
- begin
- // ID ïàíåëè:
- //PAMem.ReadInt(id);
- {
- if id <> i then raise EBinSizeError.Create('g_Map_LoadState: LoadPanelArray: Wrong Panel ID');
- }
- // Çàãðóæàåì ïàíåëü
- pan.LoadState(PAMem);
- //if (panels[i].arrIdx <> i) then raise Exception.Create('g_Map_LoadState: LoadPanelArray: Wrong Panel arrIdx');
- if (pan.proxyId >= 0) then mapGrid.proxyEnabled[pan.proxyId] := pan.Enabled;
- end;
+ pan.LoadState(PAMem);
+ if (pan.proxyId >= 0) then mapGrid.proxyEnabled[pan.proxyId] := pan.Enabled;
end;
// Ýòîò ñïèñîê ïàíåëåé çàãðóæåí