# HG changeset patch # User sheepluva # Date 1272817471 0 # Node ID d5d31d16eccc374441f333c9a6e8f0153ef45bda # Parent 4003bf74588a0b1aefb0ed54981cdb2be400e73e add a part of my landslide vector collision and use if for the portal gun DirAngle, not flawless yet diff -r 4003bf74588a -r d5d31d16eccc hedgewars/GSHandlers.inc --- a/hedgewars/GSHandlers.inc Sun May 02 16:16:00 2010 +0000 +++ b/hedgewars/GSHandlers.inc Sun May 02 16:24:31 2010 +0000 @@ -3039,6 +3039,7 @@ end; end; +//////////////////////////////////////////////////////////////////////////////// procedure doStepPortal(Gear: PGear); var tmpGear, iterator: PGear; begin @@ -3071,7 +3072,7 @@ end; procedure doStepMovingPortal(Gear: PGear); -var x, y: LongInt;//, tx, ty, bx, by, tangle: LongInt; +var x, y, tx, ty: LongInt;//, bx, by, tangle: LongInt; begin Gear^.X:= Gear^.X + Gear^.dX; Gear^.Y:= Gear^.Y + Gear^.dY; @@ -3080,6 +3081,14 @@ if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and ((Land[y, x] and $FF00) <> 0) then begin + if not calcSlopeNormal(Gear, x, y, tx, ty, 255) then + begin + DeleteGear(Gear); + EXIT; + end; + //AddFileLog(IntToStr(tx)+' '+IntToStr(ty)); + if Gear^.dX.isNegative then ty:= -ty; + Gear^.DirAngle:= DxDy2Angle(Int2hwFloat(ty),Int2hwFloat(tx)); (* This is not quite doing what I want, but basically hoping to avoid portals just sitting out in midair Works ok for right angles, aaaand that's about it. @@ -3091,6 +3100,9 @@ bx:= hwRound(Gear^.X-SignAs(AngleSin(tangle), Gear^.dX)*_6); by:= hwRound(Gear^.Y+AngleCos(tangle)*_6); *) + + + if ((Gear^.IntersectGear <> nil) and (hwRound(Distance(Gear^.X - Gear^.IntersectGear^.X,Gear^.Y-Gear^.IntersectGear^.Y)) < Gear^.Radius*2)) (*or (((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and ((Land[ty, tx] and $FF00) = 0)) or diff -r 4003bf74588a -r d5d31d16eccc hedgewars/uCollisions.pas --- a/hedgewars/uCollisions.pas Sun May 02 16:16:00 2010 +0000 +++ b/hedgewars/uCollisions.pas Sun May 02 16:24:31 2010 +0000 @@ -49,6 +49,8 @@ function TestCollisionXwithXYShift(Gear: PGear; ShiftX: hwFloat; ShiftY: LongInt; Dir: LongInt): boolean; function TestCollisionYwithXYShift(Gear: PGear; ShiftX, ShiftY: LongInt; Dir: LongInt): boolean; +function calcSlopeNormal(Gear: PGear; collisionX, collisionY: LongInt; var deltaX, deltaY: LongInt; TestWord: LongWord): Boolean; + implementation uses uMisc, uConsts, uLand, uLandGraphics, uConsole; @@ -312,6 +314,187 @@ Gear^.Y:= Gear^.Y - int2hwFloat(ShiftY) end; + +function calcSlopeNormal(Gear: PGear; collisionX, collisionY: LongInt; var deltaX, deltaY: LongInt; TestWord: LongWord): boolean; +var sx, sy, ldx, ldy, rdx, rdy: LongInt; + i, j, mx, my : ShortInt; + tmpx, tmpy: LongWord; + dx, dy, rx, ry: hwFloat; + leftsteps: Array[0..4,0..1] of ShortInt; + rightsteps: Array[0..4,0..1] of ShortInt; + +begin + dx:= Gear^.dX; + dy:= Gear^.dY; + + if Gear^.AdvBounce > 0 then + begin + rx:= _0_5 + Int2hwFloat(collisionX) - Gear^.X; + ry:= _0_5 + Int2hwFloat(collisionY) - Gear^.Y; + end + else + begin + rx:= dx; + ry:= dy; + end; + + sx:= hwSign(rx); + sy:= hwSign(ry); + + if rx.QWordValue > ry.QWordValue then + begin + if (ry/rx).QWordValue < _0_5.QWordValue then sy:= 0; + end + else + begin + if (rx/ry).QWordValue < _0_5.QWordValue then sx:= 0; + end; + + mx:= -sx; + my:= -sy; + + for i:= 0 to 4 do + begin + if (mx = -1) and (my <> 1) then my:= my + 1 + else if (my = 1) and (mx <> 1) then mx:= mx + 1 + else if (mx = 1) and (my <> -1) then my:= my - 1 + else mx:= mx - 1; + + leftsteps[i,0]:= mx; + leftsteps[i,1]:= my; + end; + + mx:= -sx; + my:= -sy; + + for i:= 0 to 4 do + begin + if (mx = -1) and (my <> -1) then my:= my - 1 + else if (my = -1) and (mx <> 1) then mx:= mx + 1 + else if (mx = 1) and (my <> 1) then my:= my + 1 + else mx:= mx - 1; + + rightsteps[i,0]:= mx; + rightsteps[i,1]:= my; + end; + + ldx:= collisionX; + ldy:= collisionY; + rdx:= collisionX; + rdy:= collisionY; + + for i:= 0 to 4 do + begin + tmpx:= collisionX + leftsteps[i,0]; + tmpy:= collisionY + leftsteps[i,1]; + if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) then + if (Land[tmpy,tmpx] > TestWord) then + begin + if i <> 0 then + for j:= 0 to 2 do + begin + leftsteps[j,0]:= leftsteps[i+j,0]; + leftsteps[j,1]:= leftsteps[i+j,1]; + end; + ldx:= tmpx; + ldy:= tmpy; + break; + end; + end; + + for i:= 0 to 4 do + begin + tmpx:= collisionX + rightsteps[i,0]; + tmpy:= collisionY + rightsteps[i,1]; + if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) then + if (Land[tmpy,tmpx] > TestWord) then + begin + if i <> 0 then + for j:= 0 to 2 do + begin + rightsteps[j,0]:= rightsteps[i+j-1,0]; + rightsteps[j,1]:= rightsteps[i+j-1,1]; + end; + rdx:= tmpx; + rdy:= tmpy; + break; + end; + end; + + // TODO: avoid redundant checks + for i:= 0 to 4 do + begin + for j:= 0 to 2 do + begin + tmpx:= ldx + leftsteps[j,0]; + tmpy:= ldy + leftsteps[j,1]; + if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) then + if (Land[tmpy,tmpx] > TestWord) then + begin + ldx:= tmpx; + ldy:= tmpy; + break; + end; + end; + end; + + for i:= 0 to 4 do + begin + for j:= 0 to 2 do + begin + tmpx:= rdx + rightsteps[j,0]; + tmpy:= rdy + rightsteps[j,1]; + if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) then + if (Land[tmpy,tmpx] > TestWord) then + begin + rdx:= tmpx; + rdy:= tmpy; + break; + end; + end; + end; + + ldx:= rdx - ldx; + ldy:= rdy - ldy; + + // rotate vector by 90° + rdx:= -ldy; + ldy:= ldx; + ldx:= rdx; + + if (ldy <> 0) then tmpy := collisionY + ldy div abs(ldy) else tmpy:= collisionY; + if (ldx <> 0) then tmpx := collisionX + ldx div abs(ldx) else tmpx:= collisionX; + if ((ldx = 0) and (ldy = 0)) then EXIT(false); + + if ((((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) + and (Land[tmpy,tmpx] > TestWord)) then + begin + if (ldy <> 0) then + begin + ldy:= -ldy; + tmpy := collisionY + ldy div abs(ldy); + end; + if (ldx <> 0) then + begin + ldx:= -ldx; + tmpx := collisionX + ldx div abs(ldx); + end; + + if ((((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) + and (Land[tmpy,tmpx] > TestWord)) then + EXIT(false); + end; + + + if (dx*ldx + dy*ldy).isNegative then + begin + deltaX:= ldx; + deltaY:= ldy; + EXIT(true); + end; +exit(false); +end; + procedure initModule; begin Count:= 0;