DEADSOFTWARE

game: disable gibs for server
[d2df-sdl.git] / src / game / g_panel.pas
index c95c271c289aff596bbc6b0b5b9f33750b09e7be..f9b7371f213c2f8b4b380e02ec61bd7b03b6672f 100644 (file)
@@ -2,8 +2,7 @@
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation, version 3 of the License ONLY.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -24,11 +23,16 @@ uses
   MAPDEF, g_textures, xdynrec;
 
 type
-  TAddTextureArray = Array of
-    record
-      Texture: Cardinal;
-      Anim: Boolean;
-    end;
+  TAddTextureArray = array of record
+    Texture: Cardinal; // Textures[Texture]
+  end;
+
+  ATextureID = array of record
+    Texture: Cardinal; // Textures[Texture]
+    case Anim: Boolean of
+      False: ();
+      True:  (AnTex: TAnimationState);
+  end;
 
   PPanel = ^TPanel;
   TPanel = Class (TObject)
@@ -36,17 +40,9 @@ type
     const
   private
     mGUID: Integer; // will be assigned in "g_map.pas"
-    FTextureWidth:    Word;
-    FTextureHeight:   Word;
     FAlpha:           Byte;
     FBlending:        Boolean;
-    FTextureIDs:      Array of
-                        record
-                          case Anim: Boolean of
-                            False: (Tex: Cardinal);
-                            True:  (AnTex: TAnimation);
-                        end;
-
+    FTextureIDs:      ATextureID;
     mMovingSpeed: TDFPoint;
     mMovingStart: TDFPoint;
     mMovingEnd: TDFPoint;
@@ -118,8 +114,6 @@ type
                        var Textures: TLevelTextureArray; aguid: Integer);
     destructor  Destroy(); override;
 
-    procedure   Draw (hasAmbient: Boolean; constref ambColor: TDFColor);
-    procedure   DrawShadowVolume(lightX: Integer; lightY: Integer; radius: Integer);
     procedure   Update();
     procedure   SetFrame(Frame: Integer; Count: Byte);
     procedure   NextTexture(AnimLoop: Byte = 0);
@@ -190,6 +184,11 @@ type
     property isGLift: Boolean read getIsGLift;
     property isGBlockMon: Boolean read getIsGBlockMon;
 
+    (* private state *)
+    property Alpha: Byte read FAlpha;
+    property Blending: Boolean read FBlending;
+    property TextureIDs: ATextureID read FTextureIDs;
+
   public
     property movingSpeed: TDFPoint read mMovingSpeed write mMovingSpeed;
     property movingStart: TDFPoint read mMovingStart write mMovingStart;
@@ -204,6 +203,12 @@ type
 
   TPanelArray = Array of TPanel;
 
+const
+  LIFTTYPE_UP = 0;
+  LIFTTYPE_DOWN = 1;
+  LIFTTYPE_LEFT = 2;
+  LIFTTYPE_RIGHT = 3;
+
 var
   g_dbgpan_mplat_active: Boolean = {$IF DEFINED(D2F_DEBUG)}true{$ELSE}true{$ENDIF};
   g_dbgpan_mplat_step: Boolean = false; // one step, and stop
@@ -211,20 +216,39 @@ var
 
 implementation
 
-uses
-{$IFDEF USE_NANOGL}
-  nanoGL,
-{$ELSE}
-  GL,
-{$ENDIF}
-  e_texture, g_basic, g_map, g_game, g_gfx, e_graphics, g_weapons, g_triggers,
-  g_console, g_language, g_monsters, g_player, g_grid, e_log, geom, utils, xstreams;
+  uses
+    {$IFDEF ENABLE_GFX}
+      g_gfx,
+    {$ENDIF}
+    {$IFDEF ENABLE_GIBS}
+      g_gibs,
+    {$ENDIF}
+    g_basic, g_map, g_game, g_weapons, g_triggers,
+    g_console, g_language, g_monsters, g_player, g_grid, e_log, geom, utils, xstreams
+  ;
 
 const
   PANEL_SIGNATURE = $4C4E4150; // 'PANL'
 
 { T P a n e l : }
 
+  function FindTextureByName (const name: String): Integer;
+    var i: Integer;
+  begin
+    Result := -1;
+    if Textures <> nil then
+    begin
+      for i := 0 to High(Textures) do
+      begin
+        if Textures[i].TextureName = name then
+        begin
+          Result := i;
+          break;
+        end
+      end
+    end
+  end;
+
 constructor TPanel.Create(PanelRec: TDynRecord;
                           AddTextures: TAddTextureArray;
                           CurTex: Integer;
@@ -265,16 +289,16 @@ begin
   PanelType := PanelRec.PanelType;
   Enabled := True;
   Door := False;
-  LiftType := 0;
+  LiftType := LIFTTYPE_UP;
   hasTexTrigger := False;
 
   case PanelType of
     PANEL_OPENDOOR: begin Enabled := False; Door := True; end;
     PANEL_CLOSEDOOR: Door := True;
-    PANEL_LIFTUP: LiftType := 0; //???
-    PANEL_LIFTDOWN: LiftType := 1;
-    PANEL_LIFTLEFT: LiftType := 2;
-    PANEL_LIFTRIGHT: LiftType := 3;
+    PANEL_LIFTUP: LiftType := LIFTTYPE_UP; //???
+    PANEL_LIFTDOWN: LiftType := LIFTTYPE_DOWN;
+    PANEL_LIFTLEFT: LiftType := LIFTTYPE_LEFT;
+    PANEL_LIFTRIGHT: LiftType := LIFTTYPE_RIGHT;
   end;
 
 // Íåâèäèìàÿ:
@@ -303,16 +327,11 @@ begin
   begin
     SetLength(FTextureIDs, 1);
     FTextureIDs[0].Anim := False;
-
     case PanelRec.PanelType of
-      PANEL_WATER:
-        FTextureIDs[0].Tex := LongWord(TEXTURE_SPECIAL_WATER);
-      PANEL_ACID1:
-        FTextureIDs[0].Tex := LongWord(TEXTURE_SPECIAL_ACID1);
-      PANEL_ACID2:
-        FTextureIDs[0].Tex := LongWord(TEXTURE_SPECIAL_ACID2);
+      PANEL_WATER: FTextureIDs[0].Texture := FindTextureByName(TEXTURE_NAME_WATER);
+      PANEL_ACID1: FTextureIDs[0].Texture := FindTextureByName(TEXTURE_NAME_ACID1);
+      PANEL_ACID2: FTextureIDs[0].Texture := FindTextureByName(TEXTURE_NAME_ACID2);
     end;
-
     FCurTexture := 0;
     Exit;
   end;
@@ -329,19 +348,12 @@ begin
 
   for i := 0 to Length(FTextureIDs)-1 do
   begin
-    FTextureIDs[i].Anim := AddTextures[i].Anim;
+    FTextureIDs[i].Texture := AddTextures[i].Texture;
+    FTextureIDs[i].Anim := Textures[AddTextures[i].Texture].FramesCount > 0;
     if FTextureIDs[i].Anim then
-      begin // Àíèìèðîâàííàÿ òåêñòóðà
-        FTextureIDs[i].AnTex :=
-           TAnimation.Create(Textures[AddTextures[i].Texture].FramesID,
-                             True, Textures[AddTextures[i].Texture].Speed);
-        FTextureIDs[i].AnTex.Blending := ByteBool(PanelRec.Flags and PANEL_FLAG_BLENDING);
-        FTextureIDs[i].AnTex.Alpha := PanelRec.Alpha;
-      end
-    else
-      begin // Îáû÷íàÿ òåêñòóðà
-        FTextureIDs[i].Tex := Textures[AddTextures[i].Texture].TextureID;
-      end;
+    begin // Àíèìèðîâàííàÿ òåêñòóðà
+      FTextureIDs[i].AnTex := TAnimationState.Create(True, Textures[AddTextures[i].Texture].Speed, Textures[AddTextures[i].Texture].FramesCount);
+    end
   end;
 
 // Òåêñòóð íåñêîëüêî - íóæíî ñîõðàíÿòü òåêóùóþ:
@@ -354,15 +366,11 @@ begin
   if ({PanelRec.TextureNum}tnum > High(Textures)) then
   begin
     e_WriteLog(Format('WTF?! tnum is out of limits! (%d : %d)', [tnum, High(Textures)]), TMsgType.Warning);
-    FTextureWidth := 2;
-    FTextureHeight := 2;
     FAlpha := 0;
     FBlending := ByteBool(0);
   end
   else if not g_Map_IsSpecialTexture(Textures[{PanelRec.TextureNum}tnum].TextureName) then
   begin
-    FTextureWidth := Textures[{PanelRec.TextureNum}tnum].Width;
-    FTextureHeight := Textures[{PanelRec.TextureNum}tnum].Height;
     FAlpha := PanelRec.Alpha;
     FBlending := ByteBool(PanelRec.Flags and PANEL_FLAG_BLENDING);
   end;
@@ -422,111 +430,6 @@ function TPanel.getIsGBlockMon (): Boolean; inline; begin result := ((tag and Gr
 function TPanel.gncNeedSend (): Boolean; inline; begin result := mNeedSend; mNeedSend := false; end;
 procedure TPanel.setDirty (); inline; begin mNeedSend := true; end;
 
-
-procedure TPanel.Draw (hasAmbient: Boolean; constref ambColor: TDFColor);
-var
-  xx, yy: Integer;
-  NoTextureID: DWORD;
-  NW, NH: Word;
-begin
-  if {Enabled and} (FCurTexture >= 0) and
-     (Width > 0) and (Height > 0) and (FAlpha < 255) {and
-     g_Collide(X, Y, Width, Height, sX, sY, sWidth, sHeight)} then
-  begin
-    if FTextureIDs[FCurTexture].Anim then
-      begin // Àíèìèðîâàííàÿ òåêñòóðà
-        if FTextureIDs[FCurTexture].AnTex = nil then
-          Exit;
-
-        for xx := 0 to (Width div FTextureWidth)-1 do
-          for yy := 0 to (Height div FTextureHeight)-1 do
-            FTextureIDs[FCurTexture].AnTex.Draw(
-              X + xx*FTextureWidth,
-              Y + yy*FTextureHeight, TMirrorType.None);
-      end
-    else
-      begin // Îáû÷íàÿ òåêñòóðà
-        case FTextureIDs[FCurTexture].Tex of
-          LongWord(TEXTURE_SPECIAL_WATER): e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1, 0, 0, 255, 0, TBlending.Filter);
-          LongWord(TEXTURE_SPECIAL_ACID1): e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1, 0, 128, 0, 0, TBlending.Filter);
-          LongWord(TEXTURE_SPECIAL_ACID2): e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1, 128, 0, 0, 0, TBlending.Filter);
-          LongWord(TEXTURE_NONE):
-            if g_Texture_Get('NOTEXTURE', NoTextureID) then
-            begin
-              e_GetTextureSize(NoTextureID, @NW, @NH);
-              e_DrawFill(NoTextureID, X, Y, Width div NW, Height div NH, 0, False, False);
-            end
-            else
-            begin
-              xx := X + (Width div 2);
-              yy := Y + (Height div 2);
-              e_DrawFillQuad(X, Y, xx, yy, 255, 0, 255, 0);
-              e_DrawFillQuad(xx, Y, X+Width-1, yy, 255, 255, 0, 0);
-              e_DrawFillQuad(X, yy, xx, Y+Height-1, 255, 255, 0, 0);
-              e_DrawFillQuad(xx, yy, X+Width-1, Y+Height-1, 255, 0, 255, 0);
-            end;
-          else
-          begin
-            if not mMovingActive then
-              e_DrawFill(FTextureIDs[FCurTexture].Tex, X, Y, Width div FTextureWidth, Height div FTextureHeight, FAlpha, True, FBlending, hasAmbient)
-            else
-              e_DrawFillX(FTextureIDs[FCurTexture].Tex, X, Y, Width, Height, FAlpha, True, FBlending, g_dbg_scale, hasAmbient);
-            if hasAmbient then e_AmbientQuad(X, Y, Width, Height, ambColor.r, ambColor.g, ambColor.b, ambColor.a);
-          end;
-        end;
-      end;
-  end;
-end;
-
-procedure TPanel.DrawShadowVolume(lightX: Integer; lightY: Integer; radius: Integer);
-  procedure extrude (x: Integer; y: Integer);
-  begin
-    glVertex2i(x+(x-lightX)*500, y+(y-lightY)*500);
-    //e_WriteLog(Format('  : (%d,%d)', [x+(x-lightX)*300, y+(y-lightY)*300]), MSG_WARNING);
-  end;
-
-  procedure drawLine (x0: Integer; y0: Integer; x1: Integer; y1: Integer);
-  begin
-    // does this side facing the light?
-    if ((x1-x0)*(lightY-y0)-(lightX-x0)*(y1-y0) >= 0) then exit;
-    //e_WriteLog(Format('lightpan: (%d,%d)-(%d,%d)', [x0, y0, x1, y1]), MSG_WARNING);
-    // this edge is facing the light, extrude and draw it
-    glVertex2i(x0, y0);
-    glVertex2i(x1, y1);
-    extrude(x1, y1);
-    extrude(x0, y0);
-  end;
-
-begin
-  if radius < 4 then exit;
-  if Enabled and (FCurTexture >= 0) and (Width > 0) and (Height > 0) and (FAlpha < 255) {and
-     g_Collide(X, Y, Width, Height, sX, sY, sWidth, sHeight)} then
-  begin
-    if not FTextureIDs[FCurTexture].Anim then
-    begin
-      case FTextureIDs[FCurTexture].Tex of
-        LongWord(TEXTURE_SPECIAL_WATER): exit;
-        LongWord(TEXTURE_SPECIAL_ACID1): exit;
-        LongWord(TEXTURE_SPECIAL_ACID2): exit;
-        LongWord(TEXTURE_NONE): exit;
-      end;
-    end;
-    if (X+Width < lightX-radius) then exit;
-    if (Y+Height < lightY-radius) then exit;
-    if (X > lightX+radius) then exit;
-    if (Y > lightY+radius) then exit;
-    //e_DrawFill(FTextureIDs[FCurTexture].Tex, X, Y, Width div FTextureWidth, Height div FTextureHeight, FAlpha, True, FBlending);
-
-    glBegin(GL_QUADS);
-      drawLine(x,       y,        x+width, y); // top
-      drawLine(x+width, y,        x+width, y+height); // right
-      drawLine(x+width, y+height, x,       y+height); // bottom
-      drawLine(x,       y+height, x,       y); // left
-    glEnd();
-  end;
-end;
-
-
 procedure TPanel.positionChanged (); inline;
 var
   px, py, pw, ph: Integer;
@@ -540,7 +443,9 @@ begin
       e_LogWritefln('panel moved: arridx=%s; guid=%s; proxyid=%s; old:(%s,%s)-(%sx%s); new:(%s,%s)-(%sx%s)',
         [arrIdx, mGUID, proxyId, px, py, pw, ph, x, y, width, height]);
       }
-      g_Mark(px, py, pw, ph, MARK_WALL, false);
+      {$IFDEF ENABLE_GFX}
+        g_Mark(px, py, pw, ph, MARK_WALL, false);
+      {$ENDIF}
       if (Width < 1) or (Height < 1) then
       begin
         mapGrid.proxyEnabled[proxyId] := false;
@@ -557,7 +462,9 @@ begin
         begin
           mapGrid.moveBody(proxyId, X, Y);
         end;
-        g_Mark(X, Y, Width, Height, MARK_WALL);
+        {$IFDEF ENABLE_GFX}
+          g_Mark(X, Y, Width, Height, MARK_WALL);
+        {$ENDIF}
       end;
     end;
   end;
@@ -670,7 +577,9 @@ var
   px, py, pw, ph, pdx, pdy: Integer;
   squash: Boolean;
   plr: TPlayer;
-  gib: PGib;
+  {$IFDEF ENABLE_GIBS}
+    gib: PGib;
+  {$ENDIF}
   cor: TCorpse;
   mon: TMonster;
   mpfrid: LongWord;
@@ -779,19 +688,21 @@ begin
           if not g_Game_IsClient and squash then plr.Damage(15000, 0, 0, 0, HIT_TRAP);
         end;
 
-        // process gibs
-        for f := 0 to High(gGibs) do
-        begin
-          gib := @gGibs[f];
-          if not gib.alive then continue;
-          gib.getMapBox(px, py, pw, ph);
-          if not g_Collide(px, py, pw, ph, cx0, cy0, cw, ch) then continue;
-          if tryMPlatMove(px, py, pw, ph, pdx, pdy, squash, @ontop) then
+        {$IFDEF ENABLE_GIBS}
+          // process gibs
+          for f := 0 to High(gGibs) do
           begin
-            // set new position
-            gib.moveBy(pdx, pdy); // this will call `positionChanged()` for us
+            gib := @gGibs[f];
+            if not gib.alive then continue;
+            gib.getMapBox(px, py, pw, ph);
+            if not g_Collide(px, py, pw, ph, cx0, cy0, cw, ch) then continue;
+            if tryMPlatMove(px, py, pw, ph, pdx, pdy, squash, @ontop) then
+            begin
+              // set new position
+              gib.moveBy(pdx, pdy); // this will call `positionChanged()` for us
+            end;
           end;
-        end;
+        {$ENDIF}
 
         // move and push corpses
         for f := 0 to High(gCorpses) do
@@ -906,7 +817,7 @@ begin
     (FTextureIDs[FCurTexture].AnTex <> nil) and
     (Width > 0) and (Height > 0) and (FAlpha < 255) then
   begin
-    FCurFrame := ClampInt(Frame, 0, FTextureIDs[FCurTexture].AnTex.TotalFrames);
+    FCurFrame := ClampInt(Frame, 0, FTextureIDs[FCurTexture].AnTex.TotalFrames - 1);
     FCurFrameCount := Count;
     FTextureIDs[FCurTexture].AnTex.CurrentFrame := FCurFrame;
     FTextureIDs[FCurTexture].AnTex.CurrentCounter := FCurFrameCount;
@@ -986,18 +897,20 @@ begin
   LastAnimLoop := AnimLoop;
 end;
 
-function TPanel.GetTextureID(): DWORD;
-begin
-  Result := LongWord(TEXTURE_NONE);
-
-  if (FCurTexture >= 0) then
+  function TPanel.GetTextureID(): DWORD;
+    var Texture: Integer;
   begin
-    if FTextureIDs[FCurTexture].Anim then
-      Result := FTextureIDs[FCurTexture].AnTex.FramesID
-    else
-      Result := FTextureIDs[FCurTexture].Tex;
+    Result := LongWord(TEXTURE_NONE);
+    if (FCurTexture >= 0) then
+    begin
+      Texture := FTextureIDs[FCurTexture].Texture;
+      case Textures[Texture].TextureName of
+        TEXTURE_NAME_WATER: Result := DWORD(TEXTURE_SPECIAL_WATER);
+        TEXTURE_NAME_ACID1: Result := DWORD(TEXTURE_SPECIAL_ACID1);
+        TEXTURE_NAME_ACID2: Result := DWORD(TEXTURE_SPECIAL_ACID2);
+      end
+    end
   end;
-end;
 
 function TPanel.GetTextureCount(): Integer;
 begin
@@ -1049,7 +962,7 @@ begin
   end;
   utils.writeBool(st, anim);
   // Åñëè äà - ñîõðàíÿåì àíèìàöèþ
-  if anim then FTextureIDs[FCurTexture].AnTex.SaveState(st);
+  if anim then FTextureIDs[FCurTexture].AnTex.SaveState(st, FAlpha, FBlending);
 
   // moving platform state
   utils.writeInt(st, Integer(mMovingSpeed.X));
@@ -1098,7 +1011,7 @@ begin
            (FTextureIDs[FCurTexture].Anim) and
            (FTextureIDs[FCurTexture].AnTex <> nil),
            'TPanel.LoadState: No animation object');
-    FTextureIDs[FCurTexture].AnTex.LoadState(st);
+    FTextureIDs[FCurTexture].AnTex.LoadState(st, FAlpha, FBlending);
   end;
 
   // moving platform state