DEADSOFTWARE

some new code for moving platforms: only for players yet
authorKetmar Dark <ketmar@ketmar.no-ip.org>
Mon, 4 Sep 2017 17:34:29 +0000 (20:34 +0300)
committerKetmar Dark <ketmar@ketmar.no-ip.org>
Mon, 4 Sep 2017 18:01:07 +0000 (21:01 +0300)
src/game/g_game.pas
src/game/g_holmes.pas
src/game/g_holmes_cmd.inc
src/game/g_monsters.pas
src/game/g_panel.pas
src/game/g_player.pas

index a85ad9af2ab7362961e28449b46f8dc125f6467e..58abd6ef2ef281d0b7ee2b0d471708ff8ced7143 100644 (file)
@@ -5106,12 +5106,12 @@ begin
           g_Console_Add(cmd + ' [ID | Name] [behaviour]');
           g_Console_Add('ID | Name');
           for b := MONSTER_DEMON to MONSTER_MAN do
-            g_Console_Add(Format('%2d | %s', [b, g_Monsters_GetNameByID(b)]));
+            g_Console_Add(Format('%2d | %s', [b, g_Mons_NameByTypeId(b)]));
         end else
         begin
           a := StrToIntDef(P[1], 0);
           if (a < MONSTER_DEMON) or (a > MONSTER_MAN) then
-            a := g_Monsters_GetIDByName(P[1]);
+            a := g_Mons_TypeIdByName(P[1]);
 
           if (a < MONSTER_DEMON) or (a > MONSTER_MAN) then
             g_Console_Add(Format(_lc[I_MSG_NO_MONSTER], [P[1]]))
index a1248f00155a5218285e177273ba6ad5d6795595..1f548e4c2058b560b06054513333e175df7ee7bc 100644 (file)
@@ -21,7 +21,7 @@ interface
 uses
   e_log, e_input,
   g_textures, g_basic, e_graphics, g_phys, g_grid, g_player, g_monsters,
-  g_window, g_map, g_triggers, g_items, g_game, g_panel, g_console,
+  g_window, g_map, g_triggers, g_items, g_game, g_panel, g_console, g_gfx,
   xprofiler;
 
 
@@ -908,6 +908,22 @@ procedure plrDebugDraw ();
     end;
   end;
 
+  procedure drawAwakeCells ();
+  var
+    x, y: Integer;
+  begin
+    for y := 0 to (mapGrid.gridHeight div mapGrid.tileSize) do
+    begin
+      for x := 0 to (mapGrid.gridWidth div mapGrid.tileSize) do
+      begin
+        if awmIsSetHolmes(x*mapGrid.tileSize+mapGrid.gridX0+1, y*mapGrid.tileSize++mapGrid.gridY0+1) then
+        begin
+          fillRect(x*mapGrid.tileSize++mapGrid.gridX0, y*mapGrid.tileSize++mapGrid.gridY0, monsGrid.tileSize, monsGrid.tileSize, 128, 0, 128, 64);
+        end;
+      end;
+    end;
+  end;
+
   procedure hilightCell (cx, cy: Integer);
   begin
     fillRect(cx, cy, monsGrid.tileSize, monsGrid.tileSize, 0, 128, 0, 64);
@@ -1184,6 +1200,8 @@ begin
   if showTriggers then drawTriggers();
   if showGrid then drawSelectedPlatformCells();
 
+  drawAwakeCells();
+
   //drawGibsBoxes();
 
   glPopMatrix();
@@ -1323,6 +1341,20 @@ procedure bcToggleDrawTriggers (arg: Integer=-1); begin if (arg < 0) then showTr
 procedure bcToggleCurPos (arg: Integer=-1); begin if (arg < 0) then showMapCurPos := not showMapCurPos else showMapCurPos := (arg > 0); end;
 procedure bcToggleGrid (arg: Integer=-1); begin if (arg < 0) then showGrid := not showGrid else showGrid := (arg > 0); end;
 
+procedure bcMonsterSpawn (s: AnsiString);
+var
+  mon: TMonster;
+begin
+  if not gGameOn or g_Game_IsClient then
+  begin
+    conwriteln('cannot spawn monster in this mode');
+    exit;
+  end;
+  mon := g_Mons_SpawnAt(s, pmsCurMapX, pmsCurMapY);
+  if (mon = nil) then begin conwritefln('unknown monster id: ''%s''', [s]); exit; end;
+  monMarkedUID := mon.UID;
+end;
+
 procedure bcMonsterWakeup ();
 var
   mon: TMonster;
@@ -1449,6 +1481,8 @@ begin
   cmdAdd('mon_cells', bcToggleMonsterCells, 'toggle "show all cells occupied by monsters" (SLOW!)', 'monster control');
   cmdAdd('mon_wakeup', bcMonsterWakeup, 'toggle "show all cells occupied by monsters" (SLOW!)', 'monster control');
 
+  cmdAdd('mon_spawn', bcMonsterSpawn, 'spawn monster', 'monster control');
+
   cmdAdd('mplat_step', bcOneMPlatThinkStep, 'one mplat think step', 'mplat control');
   cmdAdd('mplat_toggle', bcMPlatToggle, 'activate/deactivate moving platforms', 'mplat control');
 
@@ -1497,6 +1531,8 @@ begin
     keybindAdd('C-G', 'dbg_grid');
     keybindAdd('C-X', 'dbg_triggers');
 
+    keybindAdd('C-1', 'mon_spawn zombie');
+
     // mouse
     msbindAdd('LMB', 'atcur_select_monster');
     msbindAdd('M-LMB', 'atcur_dump_monsters');
index 60e72b4f1f712390a0fabfe00d5b3c4b8a9c65ec..63b0ae55a83587d0e1118b97633e2053ed3185d2 100644 (file)
 type
   TBindArgLessCB = procedure ();
   TBindToggleCB = procedure (arg: Integer); // -1: no arg
+  TBindStringCB = procedure (s: AnsiString);
 
   PHolmesCommand = ^THolmesCommand;
   THolmesCommand = record
   public
-    type TType = (TArgLess, TToggle);
+    type TType = (TArgLess, TToggle, TString);
 
   public
     name: AnsiString;
@@ -69,21 +70,40 @@ end;
 procedure THolmesCommand.execute (pr: TTextParser);
 var
   a: Integer = -1;
+  s: AnsiString = '';
 begin
   if not assigned(cb) then exit;
-  if (ctype = TType.TToggle) then
-  begin
-    if pr.skipBlanks() then
-    begin
-           if pr.eatId('true') or pr.eatId('tan') or pr.eatId('yes') then a := 1
-      else if pr.eatId('false') or pr.eatId('ona') or pr.eatId('no') then a := 0
-      else begin conwritefln('%s: invalid argument', [name]); exit; end;
-    end;
-  end;
-  if pr.skipBlanks() then begin conwritefln('%s: too many arguments', [name]); exit; end;
   case ctype of
-    TType.TArgLess: TBindArgLessCB(cb)();
-    TType.TToggle: TBindToggleCB(cb)(a);
+    TType.TToggle:
+      begin
+        if (pr.tokType <> pr.TTEOF) then
+        begin
+               if pr.eatId('true') or pr.eatId('tan') or pr.eatId('yes') then a := 1
+          else if pr.eatId('false') or pr.eatId('ona') or pr.eatId('no') then a := 0
+          else begin conwritefln('%s: invalid argument', [name]); exit; end;
+          if (pr.tokType <> pr.TTEOF) then begin conwritefln('%s: too many arguments', [name]); exit; end;
+        end;
+        TBindToggleCB(cb)(a);
+      end;
+    TType.TArgLess:
+      begin
+        if (pr.tokType <> pr.TTEOF) then begin conwritefln('%s: too many arguments', [name]); exit; end;
+        TBindArgLessCB(cb)();
+      end;
+    TType.TString:
+      begin
+        if (pr.tokType <> pr.TTEOF) then
+        begin
+          if (pr.tokType = pr.TTStr) then s := pr.expectStr(false) else s := pr.expectId;
+          if (pr.tokType <> pr.TTEOF) then begin conwritefln('%s: too many arguments', [name]); exit; end;
+        end
+        else
+        begin
+          conwritefln('%s: string argument expected', [name]);
+          exit;
+        end;
+        TBindStringCB(cb)(s);
+      end;
     else assert(false);
   end;
 end;
@@ -135,6 +155,7 @@ begin
 end;
 
 
+// ////////////////////////////////////////////////////////////////////////// //
 procedure cmdAdd (const aname: AnsiString; cb: TBindArgLessCB; const ahelp: AnsiString; const asection: AnsiString); overload;
 var
   cmd: PHolmesCommand;
@@ -157,6 +178,18 @@ begin
 end;
 
 
+procedure cmdAdd (const aname: AnsiString; cb: TBindStringCB; const ahelp: AnsiString; const asection: AnsiString); overload;
+var
+  cmd: PHolmesCommand;
+begin
+  if (Length(aname) = 0) or not assigned(cb) then exit;
+  cmd := cmdNewInternal(aname, ahelp, asection);
+  cmd.cb := Pointer(@cb);
+  cmd.ctype := cmd.TType.TString;
+end;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
 function getCommandHelp (const aname: AnsiString): AnsiString;
 var
   cmd: PHolmesCommand = nil;
index 5719ca4ff300322779f697deeb1bbb08510a196b..62686cd4409d24785029888d2809c4feba7e467b 100644 (file)
@@ -192,9 +192,16 @@ function  g_Monsters_ByUID (UID: Word): TMonster;
 procedure g_Monsters_killedp ();
 procedure g_Monsters_SaveState (var Mem: TBinMemoryWriter);
 procedure g_Monsters_LoadState (var Mem: TBinMemoryReader);
-function  g_Monsters_GetIDByName (name: String): Integer;
-function  g_Monsters_GetNameByID (MonsterType: Byte): String;
-function  g_Monsters_GetKilledBy (MonsterType: Byte): String;
+
+function g_Mons_SpawnAt (monType: Integer; x, y: Integer; dir: TDirection=D_LEFT): TMonster; overload;
+function g_Mons_SpawnAt (const typeName: AnsiString; x, y: Integer; dir: TDirection=D_LEFT): TMonster; overload;
+
+function g_Mons_TypeLo (): Integer; inline;
+function g_Mons_TypeHi (): Integer; inline;
+
+function g_Mons_TypeIdByName (const name: AnsiString): Integer;
+function g_Mons_NameByTypeId (monType: Integer): AnsiString;
+function g_Mons_GetKilledByTypeId (monType: Integer): AnsiString;
 
 
 type
@@ -549,6 +556,7 @@ const
   MAX_SOUL = 512; // Îãðàíè÷åíèå Lost_Soul'îâ
 
 
+// ////////////////////////////////////////////////////////////////////////// //
 var
   gMonsters: array of TMonster;
   uidMap: array [0..65535] of TMonster; // monster knows it's index
@@ -1460,41 +1468,69 @@ begin
   end;
 end;
 
-function g_Monsters_GetIDByName(name: String): Integer;
+
+// ////////////////////////////////////////////////////////////////////////// //
+function g_Mons_SpawnAt (monType: Integer; x, y: Integer; dir: TDirection=D_LEFT): TMonster; overload;
+begin
+  result := nil;
+  if (monType >= MONSTER_DEMON) and (monType <= MONSTER_MAN) then
+  begin
+    result := g_Monsters_Create(monType, x, y, dir);
+  end;
+end;
+
+
+function g_Mons_SpawnAt (const typeName: AnsiString; x, y: Integer; dir: TDirection=D_LEFT): TMonster; overload;
+begin
+  result := g_Mons_SpawnAt(g_Mons_TypeIdByName(typeName), x, y, dir);
+end;
+
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+function g_Mons_TypeLo (): Integer; inline; begin result := Low(MONSTERTABLE); end;
+function g_Mons_TypeHi (): Integer; inline; begin result := High(MONSTERTABLE); end;
+
+
+function g_Mons_TypeIdByName (const name: String): Integer;
 var
   i: Integer;
 begin
-  name := UpperCase(name);
   i := MONSTER_DEMON;
   while (i <= MONSTER_MAN) do
   begin
-    if name = MONSTERTABLE[i].Name then
+    if (CompareText(name, MONSTERTABLE[i].Name) = 0) then
     begin
-      Result := i;
-      Exit;
+      result := i;
+      exit;
     end;
     Inc(i);
   end;
-
-  Result := -1;
+  result := -1;
+  // HACK!
+  if (CompareText(name, 'zombie') = 0) then result := MONSTER_ZOMBY;
 end;
 
-function g_Monsters_GetNameByID(MonsterType: Byte): String;
+
+function g_Mons_NameByTypeId (monType: Integer): AnsiString;
 begin
-  if MonsterType in [MONSTER_DEMON..MONSTER_MAN] then
-    Result := MONSTERTABLE[MonsterType].Name
+  if (monType >= MONSTER_DEMON) and (monType <= MONSTER_MAN) then
+    result := MONSTERTABLE[monType].Name
   else
-    Result := '?';
+    result := '?';
 end;
 
-function g_Monsters_GetKilledBy(MonsterType: Byte): String;
+
+function g_Mons_GetKilledByTypeId (monType: Integer): AnsiString;
 begin
-  if MonsterType in [MONSTER_DEMON..MONSTER_MAN] then
-    Result := KilledByMonster[MonsterType]
+  if (monType >= MONSTER_DEMON) and (monType <= MONSTER_MAN) then
+    Result := KilledByMonster[monType]
   else
     Result := '?';
 end;
 
+
+// ////////////////////////////////////////////////////////////////////////// //
 { T M o n s t e r : }
 
 procedure TMonster.setGameX (v: Integer); inline; begin FObj.X := v; positionChanged(); end;
index bcd1c4c1d4040d2dc820e8c2747a663dd237b82b..56e3db77948c1582f02ec4462818045feeed63a7 100644 (file)
@@ -176,7 +176,7 @@ implementation
 
 uses
   SysUtils, g_basic, g_map, g_game, g_gfx, e_graphics, g_weapons,
-  g_console, g_language, g_monsters, g_player, e_log, GL;
+  g_console, g_language, g_monsters, g_player, g_grid, e_log, GL, utils;
 
 const
   PANEL_SIGNATURE = $4C4E4150; // 'PANL'
@@ -511,13 +511,95 @@ begin
 end;
 
 
+{
 var
   monMoveList: array of TMonster = nil;
   monMoveListUsed: Integer = 0;
+}
 
 procedure TPanel.Update();
 var
+  ox, oy: Integer;
   nx, ny: Integer;
+  ex, ey, nex, ney: Integer;
+  cx0, cy0, cx1, cy1: Integer;
+
+  // return `true` if we should move by dx,dy
+  function tryMPlatMove (px, py, pw, ph: Integer; out dx, dy: Integer; out squash: Boolean): Boolean;
+  var
+    u0, u1: Single;
+    tex, tey: Integer;
+    pdx, pdy: Integer;
+  begin
+    squash := false;
+    dx := 0;
+    dy := 0;
+    pdx := mMovingSpeed.X;
+    pdy := mMovingSpeed.Y;
+    // standing on the platform?
+    if (py+ph = oy) then
+    begin
+      // yes, move with it
+      mapGrid.traceBox(tex, tey, px, py, pw, ph, pdx, pdy, nil, GridTagObstacle);
+      //e_LogWritefln('entity on the platform; tracing=(%s,%s); endpoint=(%s,%s); mustbe=(%s,%s)', [px, py, tex, tey, px+pdx, py+pdy]);
+      // still in platform?
+      squash := g_Collide(tex, tey, pw, ph, nx, ny, Width, Height);
+      dx := tex-px;
+      dy := tey-py;
+    end
+    else
+    begin
+      // not standing on the platform: trace platform to see if it hits the entity
+      // hitedge (for `it`): 0: top; 1: right; 2: bottom; 3: left
+      {
+      if g_Collide(px, py, pw, ph, ox, oy, Width, Height) then
+      begin
+        e_LogWritefln('entity is embedded: plr=(%s,%s)-(%s,%s); mpl=(%s,%s)-(%s,%s)', [px, py, px+pw-1, py+ph-1, ox, oy, ox+Width-1, oy+Height-1]);
+      end;
+      }
+      if sweepAABB(ox, oy, Width, Height, pdx, pdy, px, py, pw, ph, @u0, nil, @u1) then
+      begin
+        //e_LogWritefln('T: platsweep; u0=%s; u1=%s; hedge=%s; sweepAABB(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)', [u0, u1, hedge, ox, oy, Width, Height, pdx, pdy, px-1, py-1, pw+2, ph+2]);
+        // yes, platform hits the entity, push the entity in the direction of the platform
+        u0 := 1.0-u0; // how much path left?
+        pdx := trunc(pdx*u0);
+        pdy := trunc(pdy*u0);
+        //e_LogWritefln(' platsweep; uleft=%s; pd=(%s,%s)', [u0, pdx, pdy]);
+        if (pdx <> 0) or (pdy <> 0) then
+        begin
+          // has some path to go, trace the entity
+          mapGrid.traceBox(tex, tey, px, py, pw, ph, pdx, pdy, nil, GridTagObstacle);
+          //e_LogWritefln('  tracebox: te=(%s,%s)', [tex, tey]);
+        end
+        else
+        begin
+          // no movement
+          tex := px;
+          tey := py;
+        end;
+        // free to push along the whole path, or path was corrected
+        // still in platform?
+        squash := g_Collide(tex, tey, pw, ph, nx, ny, Width, Height);
+        dx := tex-px;
+        dy := tey-py;
+      end
+      else
+      begin
+        // no collistion, but may be embedded
+        //e_LogWritefln('F: platsweep; u0=%s; u1=%s; sweepAABB(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)', [u0, u1, ox, oy, Width, Height, pdx, pdy, px-1, py-1, pw+2, ph+2]);
+        squash := (u1 >= 0.0);
+      end;
+    end;
+    result := (dx <> 0) or (dy <> 0);
+  end;
+
+(*
+  function monCollect (mon: TMonster): Boolean;
+  begin
+    result := false; // don't stop
+    monMoveList[monMoveListUsed] := mon;
+    Inc(monMoveListUsed);
+  end;
 
   function doPush (px, py, pw, ph: Integer; out dx, dy: Integer): Boolean;
   begin
@@ -574,7 +656,7 @@ var
     // dead players leaves separate body entities, so don't move 'em
     if (plr = nil) or not plr.alive then exit;
     plr.getMapBox(px, py, pw, ph);
-    if (py+ph <> Y) then
+    if (py+ph <> oy) then
     begin
       // push player
       if doPush(px, py, pw, ph, dx, dy) then
@@ -594,8 +676,8 @@ var
       end;
       exit;
     end;
-    if (px+pw <= X) then exit;
-    if (px >= X+Width) then exit;
+    if (px+pw <= ox) then exit;
+    if (px >= ox+Width) then exit;
     plr.GameX := plr.GameX+mMovingSpeed.X;
     plr.GameY := plr.GameY+mMovingSpeed.Y;
     plr.positionChanged();
@@ -612,7 +694,7 @@ var
     px := gib.Obj.X;
     py := gib.Obj.Y;
     }
-    if (py+ph <> Y) then
+    if (py+ph <> oy) then
     begin
       // push gib
       if doPush(px, py, pw, ph, dx, dy) then
@@ -623,8 +705,8 @@ var
       end;
       exit;
     end;
-    if (px+pw <= X) then exit;
-    if (px >= X+Width) then exit;
+    if (px+pw <= ox) then exit;
+    if (px >= ox+Width) then exit;
     gib.Obj.X += mMovingSpeed.X;
     gib.Obj.Y += mMovingSpeed.Y;
     gib.positionChanged();
@@ -636,7 +718,7 @@ var
   begin
     if (cor = nil) then exit;
     cor.getMapBox(px, py, pw, ph);
-    if (py+ph <> Y) then
+    if (py+ph <> oy) then
     begin
       // push gib
       if doPush(px, py, pw, ph, dx, dy) then
@@ -645,33 +727,101 @@ var
       end;
       exit;
     end;
-    if (px+pw <= X) then exit;
-    if (px >= X+Width) then exit;
+    if (px+pw <= ox) then exit;
+    if (px >= ox+Width) then exit;
     cor.moveBy(mMovingSpeed.X, mMovingSpeed.Y); // will call `positionChanged()` for us
   end;
+*)
 
 var
   f: Integer;
+  plr: TPlayer;
+  px, py, pw, ph, pdx, pdy: Integer;
+  squash: Boolean;
+{
   mon: TMonster;
-  px, py, pw, ph: Integer;
+  sdx, sdy, he: Integer;
+  u0, u1: Single;
+}
 begin
-  if Enabled and (FCurTexture >= 0) and
+  if (not Enabled) or (Width < 1) or (Height < 1) then exit;
+
+  if (FCurTexture >= 0) and
     (FTextureIDs[FCurTexture].Anim) and
     (FTextureIDs[FCurTexture].AnTex <> nil) and
-    (Width > 0) and (Height > 0) and (FAlpha < 255) then
+    (FAlpha < 255) then
   begin
     FTextureIDs[FCurTexture].AnTex.Update();
     FCurFrame := FTextureIDs[FCurTexture].AnTex.CurrentFrame;
     FCurFrameCount := FTextureIDs[FCurTexture].AnTex.CurrentCounter;
   end;
 
+  // moving platform?
   if mMovingActive and (not mMovingSpeed.isZero) and g_dbgpan_mplat_active then
   begin
+    (*
+     * collect all monsters and players (aka entities) along the possible platform path
+     *   if entity is standing on a platform:
+     *     try to move it along the platform path, checking wall collisions
+     *   if entity is NOT standing on a platform, but hit with sweeped platform aabb:
+     *     try to push entity
+     *     if we can't push entity all the way, squash it
+     *)
+    // old rect
+    ox := X;
+    oy := Y;
+    ex := ox+Width-1;
+    ey := ox+Height-1;
+    // new rect
+    nx := ox+mMovingSpeed.X;
+    ny := oy+mMovingSpeed.Y;
+    nex := nx+Width-1;
+    ney := ny+Height-1;
+    // full rect
+    cx0 := nmin(ox, nx);
+    cy0 := nmin(oy, ny);
+    cx1 := nmax(ex, nex);
+    cy1 := nmax(ey, ney);
+
+    // temporarily turn off this panel, so it won't interfere with collision checks
+    mapGrid.proxyEnabled[proxyId] := false;
+
+    for f := 0 to High(gPlayers) do
+    begin
+      plr := gPlayers[f];
+      if (plr = nil) or (not plr.alive) then continue;
+      plr.getMapBox(px, py, pw, ph);
+      if tryMPlatMove(px, py, pw, ph, pdx, pdy, squash) then
+      begin
+        // set new position
+        plr.moveBy(pdx, pdy); // this will call `positionChanged()` for us
+        // squash player, if necessary
+        if squash then plr.Damage(15000, 0, 0, 0, HIT_TRAP);
+      end;
+    end;
+
+    // restore panel state
+    mapGrid.proxyEnabled[proxyId] := true;
+    // and really move it
+    X := nx;
+    Y := ny;
+    positionChanged();
+
+    // reverse moving direction, if necessary
+         if (mMovingSpeed.X < 0) and (nx <= mMovingStart.X) then mMovingSpeed.X := -mMovingSpeed.X
+    else if (mMovingSpeed.X > 0) and (nx >= mMovingEnd.X) then mMovingSpeed.X := -mMovingSpeed.X;
+         if (mMovingSpeed.Y < 0) and (ny <= mMovingStart.Y) then mMovingSpeed.Y := -mMovingSpeed.Y
+    else if (mMovingSpeed.Y > 0) and (ny >= mMovingEnd.Y) then mMovingSpeed.Y := -mMovingSpeed.Y;
+
+    (*
+    // collect monsters
     monMoveListUsed := 0;
-    nx := X+mMovingSpeed.X;
-    ny := Y+mMovingSpeed.Y;
+    g_Mons_ForEachAt(cx0, cy0, cx1-cx0+1, cy1-cy0+1, monCollect);
+    // process collected monsters
+
+
     // move monsters on lifts
-    g_Mons_ForEachAt(X, Y-1, Width, 1, monMove);
+    g_Mons_ForEachAt(ox, oy-1, Width, 1, monMove);
     X := nx;
     Y := ny;
     // fix grid
@@ -679,16 +829,30 @@ begin
     // push monsters
     g_Mons_ForEachAt(nx, ny, Width, Height, monPush);
     // move and push players
-    for f := 0 to High(gPlayers) do plrMove(gPlayers[f]);
+    for f := 0 to High(gPlayers) do
+    begin
+      gPlayers[f].getMapBox(px, py, pw, ph);
+      //if sweepAABB(ox, oy, Width, Height, mMovingSpeed.X, mMovingSpeed.Y, px, py, pw, ph, @u0, @u1) then
+      //if sweepAABB(ox, oy, Width, Height, mMovingSpeed.X, mMovingSpeed.Y, px, py, pw, ph, @u0, @u1) then
+      sdx := -mMovingSpeed.X;
+      sdy := -mMovingSpeed.Y;
+      if sweepAABB(ox, oy, Width, Height, mMovingSpeed.X, mMovingSpeed.Y, px, py, pw, ph, @u0, @he, @u1) then
+      begin
+        e_LogWritefln('player #%s sweep with platform %s: u0=%s; u1=%s; phe=%s', [f, mGUID, u0, u1, he]);
+        if (u1 > 0.0) then
+        begin
+          e_LogWritefln('  collide: %s', [g_Collide(px, py, pw, ph, nx, ny, Width, Height)]);
+          //gPlayers[f].GameX := gPlayers[f].GameX+trunc(sdx*(1.0-u0));
+          //gPlayers[f].GameY := gPlayers[f].GameY+trunc(mMovingSpeed.Y*(1.0-u0));
+          //gPlayers[f].positionChanged();
+        end;
+      end;
+      //plrMove(gPlayers[f]);
+    end;
     // move and push gibs
     for f := 0 to High(gGibs) do gibMove(@gGibs[f]);
     // move and push corpses
     for f := 0 to High(gCorpses) do corpseMove(gCorpses[f]);
-    // reverse moving direction, if necessary
-         if (mMovingSpeed.X < 0) and (nx <= mMovingStart.X) then mMovingSpeed.X := -mMovingSpeed.X
-    else if (mMovingSpeed.X > 0) and (nx >= mMovingEnd.X) then mMovingSpeed.X := -mMovingSpeed.X;
-         if (mMovingSpeed.Y < 0) and (ny <= mMovingStart.Y) then mMovingSpeed.Y := -mMovingSpeed.Y
-    else if (mMovingSpeed.Y > 0) and (ny >= mMovingEnd.Y) then mMovingSpeed.Y := -mMovingSpeed.Y;
     // notify moved monsters about their movement
     for f := 0 to monMoveListUsed-1 do
     begin
@@ -707,6 +871,7 @@ begin
         end;
       end;
     end;
+    *)
   end;
 end;
 
index afd5b7af33fbbf7a596800a70fa1e721ee957c3d..06ae6e50340317cda52f96b1b34228d50c48f18c 100644 (file)
@@ -321,6 +321,7 @@ type
     procedure positionChanged (); //WARNING! call this after entity position was changed, or coldet will not work right!
 
     procedure getMapBox (out x, y, w, h: Integer); inline;
+    procedure moveBy (dx, dy: Integer); inline;
 
   public
     property    Vel: TPoint2i read FObj.Vel;
@@ -423,6 +424,7 @@ type
     Obj:      TObj;
 
     procedure getMapBox (out x, y, w, h: Integer); inline;
+    procedure moveBy (dx, dy: Integer); inline;
 
     procedure positionChanged (); inline; //WARNING! call this after entity position was changed, or coldet will not work right!
   end;
@@ -439,6 +441,7 @@ type
     Obj:      TObj;
 
     procedure getMapBox (out x, y, w, h: Integer); inline;
+    procedure moveBy (dx, dy: Integer); inline;
 
     procedure positionChanged ();  inline; //WARNING! call this after entity position was changed, or coldet will not work right!
   end;
@@ -464,7 +467,6 @@ type
     procedure   LoadState(var Mem: TBinMemoryReader);
 
     procedure getMapBox (out x, y, w, h: Integer); inline;
-
     procedure moveBy (dx, dy: Integer); inline;
 
     procedure positionChanged ();  inline; //WARNING! call this after entity position was changed, or coldet will not work right!
@@ -1727,6 +1729,17 @@ begin
   h := Obj.Rect.Height;
 end;
 
+procedure TGib.moveBy (dx, dy: Integer); inline;
+begin
+  if (dx <> 0) or (dy <> 0) then
+  begin
+    Obj.X += dx;
+    Obj.Y += dy;
+    positionChanged();
+  end;
+end;
+
+
 procedure TShell.getMapBox (out x, y, w, h: Integer); inline;
 begin
   x := Obj.X;
@@ -1735,10 +1748,21 @@ begin
   h := Obj.Rect.Height;
 end;
 
+procedure TShell.moveBy (dx, dy: Integer); inline;
+begin
+  if (dx <> 0) or (dy <> 0) then
+  begin
+    Obj.X += dx;
+    Obj.Y += dy;
+    positionChanged();
+  end;
+end;
+
 
 procedure TGib.positionChanged (); inline; begin end;
 procedure TShell.positionChanged (); inline; begin end;
 
+
 procedure g_Player_DrawCorpses();
 var
   i: Integer;
@@ -3196,7 +3220,7 @@ begin
         if mon = nil then
           s := '?'
         else
-          s := g_Monsters_GetKilledBy(mon.MonsterType);
+          s := g_Mons_GetKilledByTypeId(mon.MonsterType);
 
         case KillType of
           K_HARDKILL:
@@ -5069,6 +5093,7 @@ begin
     if FKeys[b].Time = 0 then FKeys[b].Pressed := False else Dec(FKeys[b].Time);
 end;
 
+
 procedure TPlayer.getMapBox (out x, y, w, h: Integer); inline;
 begin
   x := FObj.X+PLAYER_RECT.X;
@@ -5077,6 +5102,18 @@ begin
   h := PLAYER_RECT.Height;
 end;
 
+
+procedure TPlayer.moveBy (dx, dy: Integer); inline;
+begin
+  if (dx <> 0) or (dy <> 0) then
+  begin
+    FObj.X += dx;
+    FObj.Y += dy;
+    positionChanged();
+  end;
+end;
+
+
 function TPlayer.Collide(X, Y: Integer; Width, Height: Word): Boolean;
 begin
   Result := g_Collide(FObj.X+PLAYER_RECT.X,
@@ -6143,6 +6180,7 @@ begin
   h := PLAYER_CORPSERECT.Height;
 end;
 
+
 procedure TCorpse.Damage(Value: Word; vx, vy: Integer);
 var
   pm: TPlayerModel;