X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_panel.pas;h=7651b48a17326b5ea5efd06b208f55de3e2229f5;hb=e3862af724594e026b2eda52e284d21fc580aa71;hp=3c95a56ffe7f3b07724ad060b99a995f7fad3c26;hpb=d3ce22f70dfe266676a3fb95d5193238ff5b9e72;p=d2df-sdl.git diff --git a/src/game/g_panel.pas b/src/game/g_panel.pas index 3c95a56..7651b48 100644 --- a/src/game/g_panel.pas +++ b/src/game/g_panel.pas @@ -49,12 +49,34 @@ type mMovingStart: TDFPoint; mMovingEnd: TDFPoint; mMovingActive: Boolean; + mMoveOnce: Boolean; + + mSizeSpeed: TDFSize; + mSizeEnd: TDFSize; + + mEndPosTrig: Integer; + mEndSizeTrig: Integer; private function getx1 (): Integer; inline; function gety1 (): Integer; inline; function getvisvalid (): Boolean; inline; + function getMovingSpeedX (): Integer; inline; + procedure setMovingSpeedX (v: Integer); inline; + function getMovingSpeedY (): Integer; inline; + procedure setMovingSpeedY (v: Integer); inline; + + function getMovingStartX (): Integer; inline; + procedure setMovingStartX (v: Integer); inline; + function getMovingStartY (): Integer; inline; + procedure setMovingStartY (v: Integer); inline; + + function getMovingEndX (): Integer; inline; + procedure setMovingEndX (v: Integer); inline; + function getMovingEndY (): Integer; inline; + procedure setMovingEndY (v: Integer); inline; + public FCurTexture: Integer; // Íîìåð òåêóùåé òåêñòóðû FCurFrame: Integer; @@ -93,18 +115,17 @@ type procedure SaveState(var Mem: TBinMemoryWriter); procedure LoadState(var Mem: TBinMemoryReader); - procedure positionChanged (); - - function isGBack (): Boolean; inline; // gRenderBackgrounds - function isGStep (): Boolean; inline; // gSteps - function isGWall (): Boolean; inline; // gWalls - function isGAcid1 (): Boolean; inline; // gAcid1 - function isGAcid2 (): Boolean; inline; // gAcid2 - function isGWater (): Boolean; inline; // gWater - function isGFore (): Boolean; inline; // gRenderForegrounds - function isGLift (): Boolean; inline; // gLifts - function isGBlockMon (): Boolean; inline; // gBlockMon + procedure positionChanged (); inline; + function getIsGBack (): Boolean; inline; // gRenderBackgrounds + function getIsGStep (): Boolean; inline; // gSteps + function getIsGWall (): Boolean; inline; // gWalls + function getIsGAcid1 (): Boolean; inline; // gAcid1 + function getIsGAcid2 (): Boolean; inline; // gAcid2 + function getIsGWater (): Boolean; inline; // gWater + function getIsGFore (): Boolean; inline; // gRenderForegrounds + function getIsGLift (): Boolean; inline; // gLifts + function getIsGBlockMon (): Boolean; inline; // gBlockMon public property visvalid: Boolean read getvisvalid; // panel is "visvalid" when it's width and height are positive @@ -127,21 +148,46 @@ type property liftType: Byte read FLiftType write FLiftType; // Ñîõðàíÿòü ïðè SaveState? property lastAnimLoop: Byte read FLastAnimLoop write FLastAnimLoop; // Ñîõðàíÿòü ïðè SaveState? + property movingSpeedX: Integer read getMovingSpeedX write setMovingSpeedX; + property movingSpeedY: Integer read getMovingSpeedY write setMovingSpeedY; + property movingStartX: Integer read getMovingStartX write setMovingStartX; + property movingStartY: Integer read getMovingStartY write setMovingStartY; + property movingEndX: Integer read getMovingEndX write setMovingEndX; + property movingEndY: Integer read getMovingEndY write setMovingEndY; property movingActive: Boolean read mMovingActive write mMovingActive; + property moveOnce: Boolean read mMoveOnce write mMoveOnce; + + property isGBack: Boolean read getIsGBack; + property isGStep: Boolean read getIsGStep; + property isGWall: Boolean read getIsGWall; + property isGAcid1: Boolean read getIsGAcid1; + property isGAcid2: Boolean read getIsGAcid2; + property isGWater: Boolean read getIsGWater; + property isGFore: Boolean read getIsGFore; + property isGLift: Boolean read getIsGLift; + property isGBlockMon: Boolean read getIsGBlockMon; public property movingSpeed: TDFPoint read mMovingSpeed write mMovingSpeed; property movingStart: TDFPoint read mMovingStart write mMovingStart; property movingEnd: TDFPoint read mMovingEnd write mMovingEnd; + + property endPosTrigId: Integer read mEndPosTrig write mEndPosTrig; + property endSizeTrigId: Integer read mEndSizeTrig write mEndSizeTrig; end; TPanelArray = Array of TPanel; +var + g_dbgpan_mplat_active: Boolean = {$IF DEFINED(D2F_DEBUG)}true{$ELSE}true{$ENDIF}; + g_dbgpan_mplat_step: Boolean = false; // one step, and stop + + implementation uses - SysUtils, g_basic, g_map, g_game, g_gfx, e_graphics, - g_console, g_language, g_monsters, g_player, e_log, GL; + SysUtils, 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, GL, utils; const PANEL_SIGNATURE = $4C4E4150; // 'PANL' @@ -173,6 +219,13 @@ begin mMovingStart := PanelRec.moveStart; mMovingEnd := PanelRec.moveEnd; mMovingActive := PanelRec['move_active'].varvalue; + mMoveOnce := PanelRec.moveOnce; + + mSizeSpeed := PanelRec.sizeSpeed; + mSizeEnd := PanelRec.sizeEnd; + + mEndPosTrig := PanelRec.endPosTrig; + mEndSizeTrig := PanelRec.endSizeTrig; // Òèï ïàíåëè: PanelType := PanelRec.PanelType; @@ -318,15 +371,30 @@ function TPanel.getx1 (): Integer; inline; begin result := X+Width-1; end; function TPanel.gety1 (): Integer; inline; begin result := Y+Height-1; end; function TPanel.getvisvalid (): Boolean; inline; begin result := (Width > 0) and (Height > 0); end; -function TPanel.isGBack (): Boolean; inline; begin result := ((tag and GridTagBack) <> 0); end; -function TPanel.isGStep (): Boolean; inline; begin result := ((tag and GridTagStep) <> 0); end; -function TPanel.isGWall (): Boolean; inline; begin result := ((tag and (GridTagWall or GridTagDoor)) <> 0); end; -function TPanel.isGAcid1 (): Boolean; inline; begin result := ((tag and GridTagAcid1) <> 0); end; -function TPanel.isGAcid2 (): Boolean; inline; begin result := ((tag and GridTagAcid2) <> 0); end; -function TPanel.isGWater (): Boolean; inline; begin result := ((tag and GridTagWater) <> 0); end; -function TPanel.isGFore (): Boolean; inline; begin result := ((tag and GridTagFore) <> 0); end; -function TPanel.isGLift (): Boolean; inline; begin result := ((tag and GridTagLift) <> 0); end; -function TPanel.isGBlockMon (): Boolean; inline; begin result := ((tag and GridTagBlockMon) <> 0); end; +function TPanel.getMovingSpeedX (): Integer; inline; begin result := mMovingSpeed.X; end; +procedure TPanel.setMovingSpeedX (v: Integer); inline; begin mMovingSpeed.X := v; end; +function TPanel.getMovingSpeedY (): Integer; inline; begin result := mMovingSpeed.Y; end; +procedure TPanel.setMovingSpeedY (v: Integer); inline; begin mMovingSpeed.Y := v; end; + +function TPanel.getMovingStartX (): Integer; inline; begin result := mMovingStart.X; end; +procedure TPanel.setMovingStartX (v: Integer); inline; begin mMovingStart.X := v; end; +function TPanel.getMovingStartY (): Integer; inline; begin result := mMovingStart.Y; end; +procedure TPanel.setMovingStartY (v: Integer); inline; begin mMovingStart.Y := v; end; + +function TPanel.getMovingEndX (): Integer; inline; begin result := mMovingEnd.X; end; +procedure TPanel.setMovingEndX (v: Integer); inline; begin mMovingEnd.X := v; end; +function TPanel.getMovingEndY (): Integer; inline; begin result := mMovingEnd.Y; end; +procedure TPanel.setMovingEndY (v: Integer); inline; begin mMovingEnd.Y := v; end; + +function TPanel.getIsGBack (): Boolean; inline; begin result := ((tag and GridTagBack) <> 0); end; +function TPanel.getIsGStep (): Boolean; inline; begin result := ((tag and GridTagStep) <> 0); end; +function TPanel.getIsGWall (): Boolean; inline; begin result := ((tag and (GridTagWall or GridTagDoor)) <> 0); end; +function TPanel.getIsGAcid1 (): Boolean; inline; begin result := ((tag and GridTagAcid1) <> 0); end; +function TPanel.getIsGAcid2 (): Boolean; inline; begin result := ((tag and GridTagAcid2) <> 0); end; +function TPanel.getIsGWater (): Boolean; inline; begin result := ((tag and GridTagWater) <> 0); end; +function TPanel.getIsGFore (): Boolean; inline; begin result := ((tag and GridTagFore) <> 0); end; +function TPanel.getIsGLift (): Boolean; inline; begin result := ((tag and GridTagLift) <> 0); end; +function TPanel.getIsGBlockMon (): Boolean; inline; begin result := ((tag and GridTagBlockMon) <> 0); end; procedure TPanel.Draw(); var @@ -382,10 +450,10 @@ begin end; else - e_DrawFill(FTextureIDs[FCurTexture].Tex, X, Y, - Width div FTextureWidth, - Height div FTextureHeight, - FAlpha, True, FBlending); + if not mMovingActive then + e_DrawFill(FTextureIDs[FCurTexture].Tex, X, Y, Width div FTextureWidth, Height div FTextureHeight, FAlpha, True, FBlending) + else + e_DrawFillX(FTextureIDs[FCurTexture].Tex, X, Y, Width, Height, FAlpha, True, FBlending, g_dbg_scale); end; end; end; @@ -439,127 +507,360 @@ begin end; -procedure TPanel.positionChanged (); +procedure TPanel.positionChanged (); inline; +var + px, py, pw, ph: Integer; begin - if (proxyId >= 0) then mapGrid.moveBody(proxyId, X, Y); + if (proxyId >= 0) then + begin + mapGrid.getBodyDims(proxyId, px, py, pw, ph); + if (px <> x) or (py <> y) or (pw <> Width) or (ph <> Height) then + 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); + if (Width < 1) or (Height < 1) then + begin + mapGrid.proxyEnabled[proxyId] := false; + end + else + begin + mapGrid.proxyEnabled[proxyId] := Enabled; + if (pw <> Width) or (ph <> Height) then + begin + //writeln('panel resize!'); + mapGrid.moveResizeBody(proxyId, X, Y, Width, Height) + end + else + begin + mapGrid.moveBody(proxyId, X, Y); + end; + g_Mark(X, Y, Width, Height, MARK_WALL); + end; + end; + end; end; var - monMoveList: array of TMonster = nil; - monMoveListUsed: Integer = 0; + monCheckList: array of TMonster = nil; + monCheckListUsed: Integer = 0; procedure TPanel.Update(); var + ox, oy: Integer; nx, ny: Integer; - f: Integer; + ex, ey, nex, ney: Integer; + mpw, mph: Integer; - function doPush (px, py, pw, ph: Integer; out dx, dy: Integer): 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; + var + u0, u1: Single; + tex, tey: Integer; + pdx, pdy: Integer; + pan: TPanel; + trtag: Integer; + hedge: Integer; begin - result := g_Collide(px, py, pw, ph, nx, ny, Width, Height); - if result then + squash := false; + tex := px; + tey := py; + pdx := mMovingSpeed.X; + pdy := mMovingSpeed.Y; + // standing on the platform? + if (py+ph = oy) then begin - // need to push - if (mMovingSpeed.X < 0) then dx := nx-(px+pw) - else if (mMovingSpeed.X > 0) then dx := (nx+Width)-px - else dx := 0; - if (mMovingSpeed.Y < 0) then dy := ny-(py+ph) - else if (mMovingSpeed.Y > 0) then dy := (ny+Height)-py - else dy := 0; + if (ontop <> nil) then ontop^ := true; + // yes, move with it; but skip steps + pan := mapGrid.traceBox(tex, tey, px, py, pw, ph, pdx, pdy, nil, (GridTagWall or GridTagDoor)); + if (pan <> nil) then + begin + //e_LogWritefln('entity on the platform; tracing=(%s,%s); endpoint=(%s,%s); mustbe=(%s,%s)', [px, py, tex, tey, px+pdx, py+pdy]); + // if we cannot move, only walls should squash the entity + { + if ((tag and (GridTagWall or GridTagDoor)) <> 0) then + begin + if (tex = px) and (tey = py) then squash := true; + end; + } + end; end else begin - dx := 0; - dy := 0; + if (ontop <> nil) then ontop^ := false; + // 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, mpw, mph) 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+mpw-1, oy+mph-1]); + end; + } + if sweepAABB(ox, oy, mpw, mph, pdx, pdy, px, py, pw, ph, @u0, @hedge, @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, mpw, mph, 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 + trtag := (GridTagWall or GridTagDoor); + // if we're moving down, consider steps too + if (pdy > 0) then trtag := trtag or GridTagStep; + pan := mapGrid.traceBox(tex, tey, px, py, pw, ph, pdx, pdy, nil, trtag); + //e_LogWritefln(' tracebox: te=(%s,%s)', [tex, tey]); + // if we cannot move, only walls should squash the entity + { + if ((tag and (GridTagWall or GridTagDoor)) <> 0) then + begin + if (pan <> nil) and (tex = px) and (tey = py) then squash := true; + end; + } + end; + 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, mpw, mph, pdx, pdy, px-1, py-1, pw+2, ph+2]); + //squash := (u1 >= 0.0); + end; end; - end; - - function monMove (mon: TMonster): Boolean; - begin - result := false; // don't stop - mon.GameX := mon.GameX+mMovingSpeed.X; - mon.GameY := mon.GameY+mMovingSpeed.Y; - if (monMoveListUsed >= Length(monMoveList)) then SetLength(monMoveList, monMoveListUsed+64); - monMoveList[monMoveListUsed] := mon; - Inc(monMoveListUsed); - end; - - function monPush (mon: TMonster): Boolean; - var - px, py, pw, ph, dx, dy: Integer; - begin - result := false; // don't stop - mon.getMapBox(px, py, pw, ph); - if doPush(px, py, pw, ph, dx, dy) then + dx := tex-px; + dy := tey-py; + result := (dx <> 0) or (dy <> 0); + if (not squash) and ((tag and (GridTagWall or GridTagDoor)) <> 0) then begin - mon.GameX := mon.GameX+dx; - mon.GameY := mon.GameY+dy; - if (monMoveListUsed >= Length(monMoveList)) then SetLength(monMoveList, monMoveListUsed+64); - monMoveList[monMoveListUsed] := mon; - Inc(monMoveListUsed); + squash := g_Collide(tex, tey, pw, ph, nx, ny, mpw, mph); // still in platform? + //if not squash then squash := g_Map_CollidePanel(tex, tey, pw, ph, (PANEL_WALL or PANEL_OPENDOOR or PANEL_CLOSEDOOR)); end; end; - procedure plrMove (plr: TPlayer); - var - px, py, pw, ph, dx, dy: Integer; + function monCollect (mon: TMonster): Boolean; begin - if (plr = nil) then exit; - plr.getMapBox(px, py, pw, ph); - if (py+ph <> Y) then - begin - // push player - if doPush(px, py, pw, ph, dx, dy) then - begin - plr.GameX := plr.GameX+dx; - plr.GameY := plr.GameY+dy; - plr.positionChanged(); - end; - exit; - end; - if (px+pw <= X) then exit; - if (px >= X+Width) then exit; - plr.GameX := plr.GameX+mMovingSpeed.X; - plr.GameY := plr.GameY+mMovingSpeed.Y; - plr.positionChanged(); + result := false; // don't stop + if (monCheckListUsed >= Length(monCheckList)) then SetLength(monCheckList, monCheckListUsed+128); + monCheckList[monCheckListUsed] := mon; + Inc(monCheckListUsed); end; +var + cx0, cy0, cx1, cy1, cw, ch: Integer; + f: Integer; + px, py, pw, ph, pdx, pdy: Integer; + squash: Boolean; + plr: TPlayer; + gib: PGib; + cor: TCorpse; + mon: TMonster; + mpfrid: LongWord; + ontop: Boolean; + actMoveTrig: Boolean; + actSizeTrig: Boolean; 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; - if mMovingActive and (not mMovingSpeed.isZero) then + if not g_dbgpan_mplat_active then exit; + + if not mMovingActive then exit; + if mMovingSpeed.isZero and mSizeSpeed.isZero then exit; + + //TODO: write wall size change processing + + // moving platform? begin - monMoveListUsed := 0; - nx := X+mMovingSpeed.X; - ny := Y+mMovingSpeed.Y; - // move monsters on lifts - g_Mons_ForEachAt(X, Y-1, Width, 1, monMove); - // push monsters - g_Mons_ForEachAt(nx, ny, Width, Height, monPush); - // move and push players - for f := 0 to High(gPlayers) do plrMove(gPlayers[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; - // awake particles - g_Mark(X, Y, Width, Height, MARK_WALL, false); + (* + * 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 + *) + mpw := Width; + mph := Height; + + // old rect + ox := X; + oy := Y; + ex := ox+mpw-1; + ey := ox+mph-1; + // new rect + nx := ox+mMovingSpeed.X; + ny := oy+mMovingSpeed.Y; + nex := nx+mpw-1; + ney := ny+mph-1; + // full rect + cx0 := nmin(ox, nx); + cy0 := nmin(oy, ny); + cx1 := nmax(ex, nex); + cy1 := nmax(ey, ney); + // extrude + cx0 -= 1; + cy0 -= 1; + cx1 += 1; + cy1 += 1; + cw := cx1-cx0+1; + ch := cy1-cy0+1; + + // process "obstacle" panels + if ((tag and GridTagObstacle) <> 0) then + begin + // temporarily turn off this panel, so it won't interfere with collision checks + mapGrid.proxyEnabled[proxyId] := false; + + // process players + 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 not g_Collide(px, py, pw, ph, cx0, cy0, cw, ch) then continue; + if tryMPlatMove(px, py, pw, ph, pdx, pdy, squash) then + begin + // set new position + plr.moveBy(pdx, pdy); // this will call `positionChanged()` for us + end; + // squash player, if necessary + if 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 + begin + // set new position + gib.moveBy(pdx, pdy); // this will call `positionChanged()` for us + { + if ontop then + begin + gib.Obj.Vel.X += pdx; + gib.Obj.Vel.Y += pdy; + end; + } + end; + end; + + // move and push corpses + for f := 0 to High(gCorpses) do + begin + cor := gCorpses[f]; + if (cor = nil) then continue; + cor.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 + cor.moveBy(pdx, pdy); // this will call `positionChanged()` for us + { + if ontop then + begin + cor.ObjPtr.Vel.X += pdx; + cor.ObjPtr.Vel.Y += pdy; + end; + } + end; + end; + + // collect monsters + monCheckListUsed := 0; + g_Mons_ForEachAt(cx0, cy0, cw, ch, monCollect); + + // process collected monsters + if (monCheckListUsed > 0) then + begin + mpfrid := g_Mons_getNewMPlatFrameId(); + for f := 0 to monCheckListUsed do + begin + mon := monCheckList[f]; + if (mon = nil) or (not mon.alive) or (mon.mplatCheckFrameId = mpfrid) then continue; + mon.mplatCheckFrameId := mpfrid; + mon.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) then + begin + // set new position + mon.moveBy(pdx, pdy); // this will call `positionChanged()` for us + end; + // squash player, if necessary + if squash then mon.Damage(15000, 0, 0, 0, HIT_TRAP); + end; + end; + + // restore panel state + mapGrid.proxyEnabled[proxyId] := true; + end; + + // move panel X := nx; Y := ny; - g_Mark(nx, ny, Width, Height, MARK_WALL); - // fix grid + FWidth += mSizeSpeed.w; + FHeight += mSizeSpeed.h; positionChanged(); - // notify moved monsters about their movement - for f := 0 to monMoveListUsed-1 do monMoveList[f].positionChanged(); + + actMoveTrig := false; + actSizeTrig := false; + + { + if not mSizeSpeed.isZero then + begin + e_LogWritefln('ss: size_speed=(%s,%s); size=(%s,%s); move_speed=(%s,%s); oy=%s; ny=%s; etp:%s; ets:%s', [mSizeSpeed.w, mSizeSpeed.h, FWidth, FHeight, mMovingSpeed.X, mMovingSpeed.Y, oy, ny, mEndPosTrig, mEndSizeTrig]); + 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; + + // check "size stop" + if not mSizeSpeed.isZero and (Width = mSizeEnd.w) and (Height = mSizeEnd.h) then + begin + mSizeSpeed.w := 0; + mSizeSpeed.h := 0; + actSizeTrig := true; + if (Width < 1) or (Height < 1) then mMovingActive := false; //HACK! + //e_LogWritefln('FUUUUUUUUUUUUUU', []); + end; + + + if actMoveTrig then + begin + g_Triggers_Press(mEndPosTrig, ACTIVATE_CUSTOM); + end; + + if actSizeTrig then + begin + g_Triggers_Press(mEndSizeTrig, ACTIVATE_CUSTOM); + end; end; end; @@ -784,7 +1085,8 @@ begin Mem.ReadInt(mMovingEnd.Y); Mem.ReadBoolean(mMovingActive); - if (proxyId >= 0) then mapGrid.moveBody(proxyId, X, Y); + positionChanged(); + //mapGrid.proxyEnabled[proxyId] := FEnabled; // done in g_map.pas end; end.