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
--- 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;
--- 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)
--- 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