# HG changeset patch # User sheepluva # Date 1277573416 -7200 # Node ID 27b0ec6835726a45f3ba0232438e00d2fda45d8e # Parent 28e90e4541ce6e20e50f90bfc1a268e824ceee83 portal / slope detection: * make portal shot collision work regardless of portal projectile velocity * small hax so that hogs can open portals below their feet * killing some whitespaces for my personal entertainment diff -r 28e90e4541ce -r 27b0ec683572 hedgewars/GSHandlers.inc --- a/hedgewars/GSHandlers.inc Sat Jun 26 16:00:40 2010 +0200 +++ b/hedgewars/GSHandlers.inc Sat Jun 26 19:30:16 2010 +0200 @@ -16,6 +16,54 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) +procedure doStepPerPixel(Gear: PGear; step: TGearStepProcedure; onlyCheckIfChanged: boolean); +var + dX, dY, sX, sY: hwFloat; + i, steps: LongWord; + caller: TGearStepProcedure; +begin + dX:= Gear^.dX; + dY:= Gear^.dY; + steps:= max(abs(hwRound(Gear^.X+dX)-hwRound(Gear^.X)), abs(hwRound(Gear^.Y+dY)-hwRound(Gear^.Y))); + + // Gear is still on the same Pixel it was before + if steps < 1 then + begin + if onlyCheckIfChanged then + begin + Gear^.X := Gear^.X + dX; + Gear^.Y := Gear^.Y + dY; + EXIT; + end + else + steps := 1; + end; + + if steps > 1 then + begin + sX:= dX / steps; + sY:= dY / steps; + end + else + begin + sX:= dX; + sY:= dY; + end; + + caller:= Gear^.doStep; + + for i:= 1 to steps do + begin + Gear^.X := Gear^.X + sX; + Gear^.Y := Gear^.Y + sY; + step(Gear); + if (Gear^.doStep <> caller) + or ((Gear^.State and gstCollision) <> 0) + or ((Gear^.State and gstMoving) = 0) then + break; + end; +end; + procedure makeHogsWorry(x, y: hwFloat; r: LongInt); var gi: PGear; @@ -3293,10 +3341,9 @@ end; end; -procedure doStepMovingPortal(Gear: PGear); +procedure doStepMovingPortal_real(Gear: PGear); var x, y, tx, ty: LongInt; - //, bx, by, tangle: LongInt; s: hwFloat; procedure loadNewPortalBall(oldPortal: PGear; destroyGear: Boolean); @@ -3322,17 +3369,6 @@ end; begin - if (Gear^.Timer < 1) - or (PHedgehog(Gear^.Hedgehog) <> CurrentHedgehog) then - begin - deleteGear(Gear); - EXIT; - end; - - doPortalColorSwitch(); - - Gear^.X := Gear^.X + Gear^.dX; - Gear^.Y := Gear^.Y + Gear^.dY; x := hwRound(Gear^.X); y := hwRound(Gear^.Y); tx := 0; @@ -3341,6 +3377,8 @@ if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > 255) then begin + Gear^.State := Gear^.State or gstCollision; + Gear^.State := Gear^.State and not gstMoving; if not calcSlopeTangent(Gear, x, y, tx, ty, 255) or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain begin @@ -3373,6 +3411,15 @@ loadNewPortalBall(Gear, true); end; +procedure doStepMovingPortal(Gear: PGear); +begin + doPortalColorSwitch(); + doStepPerPixel(Gear, @doStepMovingPortal_real, true); + if (Gear^.Timer < 1) + or (PHedgehog(Gear^.Hedgehog) <> CurrentHedgehog) then + deleteGear(Gear); +end; + procedure doStepPortalShot(newPortal: PGear); var iterator: PGear; @@ -3422,6 +3469,8 @@ iterator := iterator^.NextGear end; end; + newPortal^.State := newPortal^.State and not gstCollision; + newPortal^.State := newPortal^.State or gstMoving; newPortal^.doStep := @doStepMovingPortal; end; diff -r 28e90e4541ce -r 27b0ec683572 hedgewars/uCollisions.pas --- a/hedgewars/uCollisions.pas Sat Jun 26 16:00:40 2010 +0200 +++ b/hedgewars/uCollisions.pas Sat Jun 26 19:30:16 2010 +0200 @@ -321,31 +321,39 @@ var ldx, ldy, rdx, rdy: LongInt; i, j, mx, my, li, ri, jfr, jto, tmpo : ShortInt; tmpx, tmpy: LongWord; - dx, dy: hwFloat; + dx, dy, s: hwFloat; offset: Array[0..7,0..1] of ShortInt; begin dx:= Gear^.dX; dy:= Gear^.dY; - // we start searching from the direction the gear center is at + // we start searching from the direction the gear came from + if (dx.QWordValue > _0_995.QWordValue ) + or (dy.QWordValue > _0_995.QWordValue ) then + begin // scale + s := _1 / Distance(dx,dy); + dx := s * dx; + dy := s * dy; + end; + mx:= hwRound(Gear^.X-dx) - hwRound(Gear^.X); my:= hwRound(Gear^.Y-dy) - hwRound(Gear^.Y); li:= -1; ri:= -1; - + // go around collision pixel, checking for first/last collisions // this will determinate what angles will be tried to crawl along for i:= 0 to 7 do begin offset[i,0]:= mx; offset[i,1]:= my; - + tmpx:= collisionX + mx; tmpy:= collisionY + my; - if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) then + if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) then if (Land[tmpy,tmpx] > TestWord) then begin // remember the index belonging to the first and last collision (if in 1st half) diff -r 28e90e4541ce -r 27b0ec683572 hedgewars/uConsts.pas --- a/hedgewars/uConsts.pas Sat Jun 26 16:00:40 2010 +0200 +++ b/hedgewars/uConsts.pas Sat Jun 26 19:30:16 2010 +0200 @@ -2015,7 +2015,7 @@ SkipTurns: 0; PosCount: 1; PosSprite: sprWater; - ejectX: 0; //29; + ejectX: -5; //29; ejectY: -7), // Piano