DEADSOFTWARE

removed "monidx" argument from monster spatial query callback (each monster has UIDs...
[d2df-sdl.git] / src / game / g_map.pas
index cd2aff9951cc4908138407a965ef2acb17d5b77d..52713fd8785e114aee27e6386f688f3ac52467e9 100644 (file)
@@ -189,6 +189,26 @@ const
   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
   case panelType of
@@ -231,37 +251,14 @@ type
     PArrID: Integer;
   end;
 
-type
-  TDynAABBTreeMap = class(TDynAABBTree)
-    function getFleshAABB (var aabb: AABB2D; flesh: TTreeFlesh; tag: Integer): Boolean; override;
-  end;
-
-function TDynAABBTreeMap.getFleshAABB (var aabb: AABB2D; flesh: TTreeFlesh; tag: Integer): 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 ();
@@ -938,45 +935,52 @@ end;
 
 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;
@@ -1029,7 +1033,7 @@ var
   mapX1: Integer = -$3fffffff;
   mapY1: Integer = -$3fffffff;
 
-  procedure calcBoundingBox (var panels: TPanelArray);
+  procedure calcBoundingBox (constref panels: TPanelArray);
   var
     idx: Integer;
     pan: TPanel;
@@ -1046,7 +1050,7 @@ var
     end;
   end;
 
-  procedure addPanelsToGrid (var panels: TPanelArray; tag: Integer);
+  procedure addPanelsToGrid (constref panels: TPanelArray; tag: Integer);
   var
     idx: Integer;
     pan: TPanel;
@@ -1080,7 +1084,7 @@ begin
 
   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);
@@ -1893,7 +1897,7 @@ end;
 // 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
@@ -1923,16 +1927,10 @@ end;
 
 // 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;
 
@@ -1949,26 +1947,13 @@ begin
     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;
 
@@ -2116,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
@@ -2144,12 +2129,9 @@ end;
 
 
 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
@@ -2222,9 +2204,7 @@ var
   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;
@@ -2235,10 +2215,9 @@ var
       //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?