X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_panel.pas;h=52722d38b5b033d3275382c9f29490215c3d9306;hb=176b2c983b32841d4d93dd322f3b3a5d1f1549b2;hp=084f64db416a805fc917215dcf74c7c898994715;hpb=0f3ace5126eeb6ef6c5dbdee5226e36dffe712d6;p=d2df-sdl.git diff --git a/src/game/g_panel.pas b/src/game/g_panel.pas index 084f64d..52722d3 100644 --- a/src/game/g_panel.pas +++ b/src/game/g_panel.pas @@ -222,7 +222,7 @@ implementation uses {$INCLUDE ../nogl/noGLuses.inc} - e_texture, g_basic, g_map, g_game, g_gfx, e_graphics, g_weapons, g_triggers, + e_texture, g_basic, g_map, g_game, g_gfx, e_graphics, g_weapons, g_triggers, g_items, g_console, g_language, g_monsters, g_player, g_grid, e_log, geom, utils, xstreams; const @@ -607,6 +607,7 @@ var nx, ny, nw, nh: Integer; ex, ey, nex, ney: Integer; mpw, mph: Integer; + conveyor: Boolean; // return `true` if we should move by dx,dy function tryMPlatMove (px, py, pw, ph: Integer; out dx, dy: Integer; out squash: Boolean; ontop: PBoolean=nil): Boolean; @@ -682,7 +683,7 @@ var dx := tex-px; dy := tey-py; result := (dx <> 0) or (dy <> 0); - if ((tag and (GridTagWall or GridTagDoor)) <> 0) then + if not conveyor and ((tag and (GridTagWall or GridTagDoor)) <> 0) then begin // check for squashing; as entity cannot be pushed into a wall, check only collision with the platform itself squash := g_Collide(tex, tey, pw, ph, nx, ny, nw, nh); // squash, if still in platform @@ -706,6 +707,8 @@ var gib: PGib; cor: TCorpse; mon: TMonster; + flg: PFlag; + itm: PItem; mpfrid: LongWord; ontop: Boolean; actMoveTrig: Boolean; @@ -748,10 +751,19 @@ begin mpw := Width; mph := Height; + // the mplat acts as a stationary conveyor belt when it's locked within a movement rect of zero area + conveyor := (mMovingEnd.X = mMovingStart.X) and (mMovingEnd.Y = mMovingStart.Y) + and (mMovingEnd.X = X) and (mMovingEnd.Y = Y); + nw := mpw+mSizeSpeed.w; nh := mph+mSizeSpeed.h; - nx := ox+mMovingSpeed.X; - ny := oy+mMovingSpeed.Y; + nx := ox; + ny := oy; + if not conveyor then + begin + nx += mMovingSpeed.X; + ny += mMovingSpeed.Y; + end; // force network updates only if some sudden change happened // set the flag here, so we can sync affected monsters @@ -840,6 +852,40 @@ begin end; end; + // move and push flags + if gGameSettings.GameMode = GM_CTF then + for f := FLAG_RED to FLAG_BLUE do + begin + flg := @gFlags[f]; + if (flg.State in [FLAG_STATE_NONE, FLAG_STATE_CAPTURED]) then continue; + px := flg.Obj.X+flg.Obj.Rect.X; + py := flg.Obj.Y+flg.Obj.Rect.Y; + pw := flg.Obj.Rect.Width; + ph := flg.Obj.Rect.Height; + 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 + if (pdx <> 0) or (pdy <> 0) then + begin + flg.Obj.X := flg.Obj.X + pdx; + flg.Obj.Y := flg.Obj.Y + pdy; + flg.NeedSend := true; + end; + end; + + // move and push items + itm := g_Items_NextAlive(-1); + while itm <> nil do + begin + if itm.Fall then + begin + itm.getMapBox(px, py, pw, ph); + if g_Collide(px, py, pw, ph, cx0, cy0, cw, ch) then + if tryMPlatMove(px, py, pw, ph, pdx, pdy, squash, @ontop) then + itm.moveBy(pdx, pdy); // this will call `positionChanged()` for us + end; + itm := g_Items_NextAlive(itm.myId); + end; + // collect monsters monCheckListUsed := 0; g_Mons_ForEachAt(cx0, cy0, cw, ch, monCollect); @@ -899,21 +945,24 @@ begin if (nw < 1) or (nh < 1) then mMovingActive := false; //HACK! end; - // reverse moving direction, if necessary - if ((mMovingSpeed.X < 0) and (nx <= mMovingStart.X)) or ((mMovingSpeed.X > 0) and (nx >= mMovingEnd.X)) then + if not conveyor then begin - if mMoveOnce then mMovingActive := false else mMovingSpeed.X := -mMovingSpeed.X; - actMoveTrig := true; - end; + // reverse moving direction, if necessary + if ((mMovingSpeed.X < 0) and (nx <= mMovingStart.X)) or ((mMovingSpeed.X > 0) and (nx >= mMovingEnd.X)) then + begin + if mMoveOnce then mMovingActive := false else mMovingSpeed.X := -mMovingSpeed.X; + actMoveTrig := true; + end; - if ((mMovingSpeed.Y < 0) and (ny <= mMovingStart.Y)) or ((mMovingSpeed.Y > 0) and (ny >= mMovingEnd.Y)) then - begin - if mMoveOnce then mMovingActive := false else mMovingSpeed.Y := -mMovingSpeed.Y; - actMoveTrig := true; - end; + if ((mMovingSpeed.Y < 0) and (ny <= mMovingStart.Y)) or ((mMovingSpeed.Y > 0) and (ny >= mMovingEnd.Y)) then + begin + if mMoveOnce then mMovingActive := false else mMovingSpeed.Y := -mMovingSpeed.Y; + actMoveTrig := true; + end; - if (mOldMovingActive <> mMovingActive) then mNeedSend := true; - mOldMovingActive := mMovingActive; + if (mOldMovingActive <> mMovingActive) then mNeedSend := true; + mOldMovingActive := mMovingActive; + end; if not g_Game_IsClient then begin