diff --git a/src/game/g_map.pas b/src/game/g_map.pas
index f3e15a21ef10847f71df7a34d342ff75b3dece9b..52713fd8785e114aee27e6386f688f3ac52467e9 100644 (file)
--- a/src/game/g_map.pas
+++ b/src/game/g_map.pas
FLAG_SIGNATURE = $47414C46; // 'FLAG'
+type
+ TPanelGrid = specialize TBodyGridBase<TPanel>;
+
+ TDynAABBTreePanelBase = specialize TDynAABBTreeBase<TPanel>;
+
+ TDynAABBTreeMap = class(TDynAABBTreePanelBase)
+ function getFleshAABB (out aabb: AABB2D; pan: TPanel; tag: Integer): Boolean; override;
+ end;
+
+function TDynAABBTreeMap.getFleshAABB (out aabb: AABB2D; pan: TPanel; tag: Integer): Boolean;
+begin
+ result := false;
+ if (pan = nil) then begin aabb := AABB2D.Create(0, 0, 0, 0); exit; end;
+ aabb := AABB2D.Create(pan.X, pan.Y, pan.X+pan.Width-1, pan.Y+pan.Height-1);
+ if (pan.Width < 1) or (pan.Height < 1) then exit;
+ if not aabb.valid then raise Exception.Create('wutafuuuuuuu?!');
+ result := true;
+end;
+
function panelTypeToTag (panelType: Word): Integer;
begin
PArrID: Integer;
end;
-type
- TDynAABBTreeMap = class(TDynAABBTree)
- function getFleshAABB (var aabb: AABB2D; flesh: TTreeFlesh): Boolean; override;
- end;
-
-function TDynAABBTreeMap.getFleshAABB (var aabb: AABB2D; flesh: TTreeFlesh): Boolean;
-var
- pan: TPanel;
-begin
- result := false;
- if (flesh = nil) then begin aabb := AABB2D.Create(0, 0, 0, 0); exit; end;
- //pan := (flesh as TPanel);
- pan := TPanel(flesh);
- aabb := AABB2D.Create(pan.X, pan.Y, pan.X+pan.Width, pan.Y+pan.Height);
- if (pan.Width < 1) or (pan.Height < 1) then exit;
- //if (pan.Width = 1) then aabb.maxX += 1;
- //if (pan.Height = 1) then aabb.maxY += 1;
- //if (pan.Width < 3) or (pan.Height < 3) then exit;
- //aabb := AABB2D.Create(pan.X, pan.Y, pan.X+pan.Width-2, pan.Y+pan.Height-2);
- if not aabb.valid then raise Exception.Create('wutafuuuuuuu?!');
- result := aabb.valid;
-end;
-
var
PanelById: array of TPanelID;
Textures: TLevelTextureArray;
RespawnPoints: Array of TRespawnPoint;
FlagPoints: Array [FLAG_RED..FLAG_BLUE] of PFlagPoint;
//DOMFlagPoints: Array of TFlagPoint;
- gMapGrid: TBodyGrid = nil;
- mapTree: TDynAABBTree = nil;
+ gMapGrid: TPanelGrid = nil;
+ mapTree: TDynAABBTreeMap = nil;
procedure g_Map_ProfilersBegin ();
procedure CreateMonster(monster: TMonsterRec_1);
var
- a, i: Integer;
+ a: Integer;
+ mon: TMonster;
begin
if g_Game_IsClient then Exit;
if (gGameSettings.GameType = GT_SINGLE)
or LongBool(gGameSettings.Options and GAME_OPTION_MONSTERS) then
begin
- i := g_Monsters_Create(monster.MonsterType, monster.X, monster.Y,
- TDirection(monster.Direction));
+ mon := g_Monsters_Create(monster.MonsterType, monster.X, monster.Y, TDirection(monster.Direction));
if gTriggers <> nil then
+ begin
for a := 0 to High(gTriggers) do
- if gTriggers[a].TriggerType in [TRIGGER_PRESS,
- TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then
- if (gTriggers[a].Data.MonsterID-1) = gMonsters[i].StartID then
- gMonsters[i].AddTrigger(a);
+ 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);
+ end;
+ end;
+ end;
- if monster.MonsterType <> MONSTER_BARREL then
- Inc(gTotalMonsters);
+ if monster.MonsterType <> MONSTER_BARREL then Inc(gTotalMonsters);
end;
end;
procedure g_Map_ReAdd_DieTriggers();
-var
- i, a: Integer;
-begin
- if g_Game_IsClient then Exit;
- for i := 0 to High(gMonsters) do
- if gMonsters[i] <> nil then
+ function monsDieTrig (mon: TMonster): Boolean;
+ var
+ a: Integer;
+ begin
+ result := false; // don't stop
+ mon.ClearTriggers();
+ for a := 0 to High(gTriggers) do
+ begin
+ if gTriggers[a].TriggerType in [TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then
begin
- gMonsters[i].ClearTriggers();
-
- for a := 0 to High(gTriggers) do
- if gTriggers[a].TriggerType in [TRIGGER_PRESS,
- TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then
- if (gTriggers[a].Data.MonsterID-1) = gMonsters[i].StartID then
- gMonsters[i].AddTrigger(a);
+ if (gTriggers[a].Data.MonsterID-1) = mon.StartID then mon.AddTrigger(a);
end;
+ end;
+ end;
+
+begin
+ if g_Game_IsClient then Exit;
+
+ g_Mons_ForEach(monsDieTrig);
end;
function extractWadName(resourceName: string): string;
mapX1: Integer = -$3fffffff;
mapY1: Integer = -$3fffffff;
- procedure calcBoundingBox (var panels: TPanelArray);
+ procedure calcBoundingBox (constref panels: TPanelArray);
var
idx: Integer;
pan: TPanel;
end;
end;
- procedure addPanelsToGrid (var panels: TPanelArray; tag: Integer);
+ procedure addPanelsToGrid (constref panels: TPanelArray; tag: Integer);
var
idx: Integer;
pan: TPanel;
e_WriteLog(Format('map dimensions: (%d,%d)-(%d,%d)', [mapX0, mapY0, mapX1, mapY1]), MSG_WARNING);
- gMapGrid := TBodyGrid.Create(mapX0, mapY0, mapX1-mapX0+1, mapY1-mapY0+1);
+ gMapGrid := TPanelGrid.Create(mapX0, mapY0, mapX1-mapX0+1, mapY1-mapY0+1);
mapTree := TDynAABBTreeMap.Create();
addPanelsToGrid(gWalls, PANEL_WALL);
// old algo
procedure g_Map_DrawPanels (PanelType: Word);
- procedure DrawPanels (var panels: TPanelArray; drawDoors: Boolean=False);
+ procedure DrawPanels (constref panels: TPanelArray; drawDoors: Boolean=False);
var
idx: Integer;
begin
// new algo
procedure g_Map_CollectDrawPanels (x0, y0, wdt, hgt: Integer);
- function checker (obj: TObject; tag: Integer): Boolean;
- var
- pan: TPanel;
+ function checker (pan: TPanel; tag: Integer): Boolean;
begin
result := false; // don't stop, ever
- //pan := (obj as TPanel);
- pan := TPanel(obj);
- //if (PanelType = PANEL_CLOSEDOOR) then begin if not pan.Door then exit; end else begin if pan.Door then exit; end;
if ((tag and GridTagDoor) <> 0) <> pan.Door then exit;
- //dplAddPanel(pan);
gDrawPanelList.insert(pan);
end;
gMapGrid.forEachInAABB(x0, y0, wdt, hgt, checker, (GridTagBack or GridTagStep or GridTagWall or GridTagDoor or GridTagAcid1 or GridTagAcid2 or GridTagWater or GridTagFore));
end;
// list will be rendered in `g_game.DrawPlayer()`
- (*
- while (gDrawPanelList.count > 0) do
- begin
- //(gDrawPanelList.front() as TPanel).Draw();
- TPanel(gDrawPanelList.front()).Draw();
- gDrawPanelList.popFront();
- end;
- *)
end;
procedure g_Map_DrawPanelShadowVolumes(lightX: Integer; lightY: Integer; radius: Integer);
- function checker (obj: TObject; tag: Integer): Boolean;
- var
- pan: TPanel;
+ function checker (pan: TPanel; tag: Integer): Boolean;
begin
result := false; // don't stop, ever
- //if (tag <> GridTagWall) and (tag <> GridTagDoor) then exit; // only walls
- //pan := (obj as TPanel);
- pan := TPanel(obj);
pan.DrawShadowVolume(lightX, lightY, radius);
end;
@@ -2117,7 +2101,7 @@ function g_Map_CollideLiquid_TextureOld(X, Y: Integer; Width, Height: Word): DWO
var
texid: DWORD;
- function checkPanels (var panels: TPanelArray): Boolean;
+ function checkPanels (constref panels: TPanelArray): Boolean;
var
a: Integer;
begin
function g_Map_CollidePanel(X, Y: Integer; Width, Height: Word; PanelType: Word; b1x3: Boolean): Boolean;
- function checker (obj: TObject; tag: Integer): Boolean;
- var
- pan: TPanel;
+ function checker (pan: TPanel; tag: Integer): Boolean;
begin
result := false; // don't stop, ever
- pan := TPanel(obj);
if ((tag and (GridTagWall or GridTagDoor)) <> 0) then
begin
texid: DWORD;
// slightly different from the old code, but meh...
- function checker (obj: TObject; tag: Integer): Boolean;
- var
- pan: TPanel;
+ function checker (pan: TPanel; tag: Integer): Boolean;
begin
result := false; // don't stop, ever
//if ((tag and (GridTagWater or GridTagAcid1 or GridTagAcid2)) = 0) then exit;
//2: if ((tag and (GridTagWater or GridTagAcid1 or GridTagAcid2) = 0) then exit; // allowed: water, acid1, acid2
end;
// collision?
- pan := (obj as TPanel);
if not g_Collide(X, Y, Width, Height, pan.X, pan.Y, pan.Width, pan.Height) then exit;
// yeah
- texid := TPanel(obj).GetTextureID();
+ texid := pan.GetTextureID();
// water? water has the highest priority, so stop right here
if ((tag and GridTagWater) <> 0) then begin cctype := 0; result := true; exit; end;
// acid2?