DEADSOFTWARE

render monster drop after monsters, so monster corpses will not obscure ammo clips...
authorKetmar Dark <ketmar@ketmar.no-ip.org>
Mon, 11 Sep 2017 19:30:44 +0000 (22:30 +0300)
committerKetmar Dark <ketmar@ketmar.no-ip.org>
Mon, 11 Sep 2017 19:31:25 +0000 (22:31 +0300)
src/game/g_game.pas
src/game/g_items.pas
src/game/g_monsters.pas
src/game/g_netmsg.pas

index d1ffd7ade5d35568897b3a5b825e0ec55a682da4..89d46d59b584d5c8c139d4feef8eb6abd1b82b8d 100644 (file)
@@ -2939,6 +2939,7 @@ begin
   drawOther('corpses', @g_Player_DrawCorpses);
   drawPanelType('*wall', PANEL_WALL, g_rlayer_wall);
   drawOther('monsters', @g_Monsters_Draw);
+  drawOther('itemdrop', @g_Items_DrawDrop);
   drawPanelType('*door', PANEL_CLOSEDOOR, g_rlayer_door);
   drawOther('gfx', @g_GFX_Draw);
   drawOther('flags', @g_Map_DrawFlags);
index 6365d7bbe2bee8fe88233355921860a0dec509fa..ef2e925b659be7ab89c696789a67be165e09273d 100644 (file)
@@ -30,16 +30,17 @@ Type
     arrIdx: Integer; // in ggItems
 
   public
-    ItemType:      Byte;
-    Respawnable:   Boolean;
-    InitX, InitY:  Integer;
-    RespawnTime:   Word;
-    alive:         Boolean;
-    Fall:          Boolean;
-    QuietRespawn:  Boolean;
-    SpawnTrigger:  Integer;
-    Obj:           TObj;
-    Animation:     TAnimation;
+    ItemType: Byte;
+    Respawnable: Boolean;
+    InitX, InitY: Integer;
+    RespawnTime: Word;
+    alive: Boolean;
+    Fall: Boolean;
+    QuietRespawn: Boolean;
+    SpawnTrigger: Integer;
+    Obj: TObj;
+    Animation: TAnimation;
+    dropped: Boolean; // dropped from the monster? drops should be rendered after corpses, so zombie corpse will not obscure ammo container, for example
 
     procedure positionChanged (); //WARNING! call this after monster position was changed, or coldet will not work right!
 
@@ -52,8 +53,10 @@ procedure g_Items_Init();
 procedure g_Items_Free();
 function g_Items_Create(X, Y: Integer; ItemType: Byte;
            Fall, Respawnable: Boolean; AdjCoord: Boolean = False; ForcedID: Integer = -1): DWORD;
+procedure g_Items_SetDrop (ID: DWORD);
 procedure g_Items_Update();
 procedure g_Items_Draw();
+procedure g_Items_DrawDrop();
 procedure g_Items_Pick(ID: DWORD);
 procedure g_Items_Remove(ID: DWORD);
 procedure g_Items_SaveState(var Mem: TBinMemoryWriter);
@@ -458,6 +461,7 @@ begin
   it.Fall := Fall;
   it.alive := True;
   it.QuietRespawn := False;
+  it.dropped := false;
 
   g_Obj_Init(@it.Obj);
   it.Obj.X := X;
@@ -618,17 +622,20 @@ begin
 end;
 
 
-procedure g_Items_Draw ();
+procedure itemsDrawInternal (dropflag: Boolean);
 var
   i: Integer;
+  it: PItem;
 begin
   if (ggItems = nil) then exit;
 
   for i := 0 to High(ggItems) do
   begin
-    if not ggItems[i].alive then continue;
+    it := @ggItems[i];
+    if not it.alive then continue;
+    if (it.dropped <> dropflag) then continue;
 
-    with ggItems[i] do
+    with it^ do
     begin
       if g_Collide(Obj.X, Obj.Y, Obj.Rect.Width, Obj.Rect.Height, sX, sY, sWidth, sHeight) then
       begin
@@ -655,10 +662,33 @@ begin
 end;
 
 
+procedure g_Items_Draw ();
+begin
+  itemsDrawInternal(false);
+end;
+
+procedure g_Items_DrawDrop ();
+begin
+  itemsDrawInternal(true);
+end;
+
+
+procedure g_Items_SetDrop (ID: DWORD);
+begin
+  if (ID < Length(ggItems)) then
+  begin
+    ggItems[ID].dropped := true;
+  end;
+end;
+
+
 procedure g_Items_Pick (ID: DWORD);
 begin
-  ggItems[ID].alive := false;
-  ggItems[ID].RespawnTime := ITEM_RESPAWNTIME;
+  if (ID < Length(ggItems)) then
+  begin
+    ggItems[ID].alive := false;
+    ggItems[ID].RespawnTime := ITEM_RESPAWNTIME;
+  end;
 end;
 
 
@@ -684,6 +714,7 @@ procedure g_Items_SaveState (var Mem: TBinMemoryWriter);
 var
   count, i: Integer;
   sig: DWORD;
+  tt: Byte;
 begin
   // Ñ÷èòàåì êîëè÷åñòâî ñóùåñòâóþùèõ ïðåäìåòîâ
   count := 0;
@@ -707,7 +738,9 @@ begin
       sig := ITEM_SIGNATURE; // 'ITEM'
       Mem.WriteDWORD(sig);
       // Òèï ïðåäìåòà
-      Mem.WriteByte(ggItems[i].ItemType);
+      tt := ggItems[i].ItemType;
+      if ggItems[i].dropped then tt := tt or $80;
+      Mem.WriteByte(tt);
       // Åñòü ëè ðåñïàóí
       Mem.WriteBoolean(ggItems[i].Respawnable);
       // Êîîðäèíàòû ðåñïóíà
@@ -749,9 +782,10 @@ begin
     Mem.ReadDWORD(sig);
     if (sig <> ITEM_SIGNATURE) then raise EBinSizeError.Create('g_Items_LoadState: Wrong Item Signature'); // 'ITEM'
     // Òèï ïðåäìåòà
-    Mem.ReadByte(b);
+    Mem.ReadByte(b); // bit7=1: monster drop
     // Ñîçäàåì ïðåäìåò
-    i := g_Items_Create(0, 0, b, False, False);
+    i := g_Items_Create(0, 0, b and $7F, False, False);
+    if ((b and $80) <> 0) then g_Items_SetDrop(i);
     // Åñòü ëè ðåñïàóí
     Mem.ReadBoolean(ggItems[i].Respawnable);
     // Êîîðäèíàòû ðåñïóíà
index 8629bc954ae6143ed88e380cd3bc76795289b448..1b39ee849607715154823fed3b6caf519667c925 100644 (file)
@@ -2077,9 +2077,10 @@ begin
         it := g_Items_Create(FObj.X + (FObj.Rect.Width div 2),
                              FObj.Y + (FObj.Rect.Height div 2),
                              c, True, False);
+        g_Items_SetDrop(it); // mark it as monster drop
         g_Obj_Push(g_Items_ObjByIdx(it), (FObj.Vel.X div 2)-3+Random(7),
                                         (FObj.Vel.Y div 2)-Random(4));
-        positionChanged(); // this updates spatial accelerators
+        //positionChanged(); // this updates spatial accelerators
         if g_Game_IsServer and g_Game_IsNet then
           MH_SEND_ItemSpawn(True, it);
       end;
index 3a2304bb005bca95012c7b85563ee780dddef21e..98ef65484d75106458c50cf94f86679e52d992ca 100644 (file)
@@ -1148,13 +1148,16 @@ end;
 procedure MH_SEND_ItemSpawn(Quiet: Boolean; IID: Word; ID: Integer = NET_EVERYONE);
 var
   it: PItem;
+  tt: Byte;
 begin
   it := g_Items_ByIdx(IID);
 
   NetOut.Write(Byte(NET_MSG_ISPAWN));
   NetOut.Write(IID);
   NetOut.Write(Byte(Quiet));
-  NetOut.Write(it.ItemType);
+  tt := it.ItemType;
+  if it.dropped then tt := tt or $80;
+  NetOut.Write(tt);
   NetOut.Write(Byte(it.Fall));
   NetOut.Write(Byte(it.Respawnable));
   NetOut.Write(it.Obj.X);
@@ -2306,7 +2309,8 @@ begin
   VX := M.ReadLongInt();
   VY := M.ReadLongInt();
 
-  g_Items_Create(X, Y, T, Fall, False, False, ID);
+  g_Items_Create(X, Y, T and $7F, Fall, False, False, ID);
+  if ((T and $80) <> 0) then g_Items_SetDrop(ID);
 
   it := g_Items_ByIdx(ID);
   it.Obj.Vel.X := VX;