# HG changeset patch # User sheepluva # Date 1277597491 -7200 # Node ID 3836fa355f9696384fdca06d6b013f1f00bfdf0c # Parent 27b0ec6835726a45f3ba0232438e00d2fda45d8e portal: entry angle is now affecting exit angle diff -r 27b0ec683572 -r 3836fa355f96 hedgewars/GSHandlers.inc --- a/hedgewars/GSHandlers.inc Sat Jun 26 19:30:16 2010 +0200 +++ b/hedgewars/GSHandlers.inc Sun Jun 27 02:11:31 2010 +0200 @@ -3205,7 +3205,7 @@ procedure doStepPortal(Gear: PGear); var iterator, conPortal: PGear; - s, acptRadius, cdxy: hwFloat; + s, acptRadius, itdist, nx, ny, pspeed, nspeed: hwFloat; noTrap, hasdxy: Boolean; begin doPortalColorSwitch(); @@ -3281,7 +3281,8 @@ // won't port stuff that moves away from me! // wow! good candidate there, let's see if the distance really is small enough! - if (Distance(Gear^.X-iterator^.X,Gear^.Y-iterator^.Y) > acptRadius) then + itdist := Distance(Gear^.X-iterator^.X,Gear^.Y-iterator^.Y); + if (itdist > acptRadius) then continue; (* noTrap := ((not Gear^.dY.isNegative or (Gear^.dY.QWordValue = 0)) @@ -3300,36 +3301,50 @@ // Until loops are reliably broken inc(iterator^.PortalCounter); - // TODO: more accurate porting - cdxy := Distance(conPortal^.dX, conPortal^.dY); - s := (Int2hwFloat(Gear^.Radius)) / cdxy; - - if iterator^.Kind = gtCake then + // find out how much speed parallel to the portal vector + // the gear has + pspeed:= (Gear^.dX * iterator^.dX + Gear^.dY * iterator^.dY ); + // create a normal of the portal vector + nx := - Gear^.dY; + ny := Gear^.dX; + // pick the normal vector that's pointing skywards + if (not ny.isNegative) then begin - iterator^.X := conPortal^.X ; - iterator^.Y := conPortal^.Y ; - end - else + nx.isNegative := not nx.isNegative; + ny.isNegative := not ny.isNegative; + end; + // now let's find out how much speed the gear has in the + // direction of that normal + nspeed:= (nx * iterator^.dX + ny * iterator^.dY); + + // now let's project those back to the connected portal's vectors + nx := - conPortal^.dY; + ny := conPortal^.dX; + if ny.isNegative then begin - iterator^.X := conPortal^.X + s * conPortal^.dX; - iterator^.Y := conPortal^.Y + s * conPortal^.dY; - - s := Distance(iterator^.dX, iterator^.dY) / cdxy; - - iterator^.dX := s * conPortal^.dX; - iterator^.dY := s * conPortal^.dY + nx.isNegative := not nx.isNegative; + ny.isNegative := not ny.isNegative; end; + iterator^.dX := -pspeed * conPortal^.dX + -nspeed * nx; + iterator^.dY := -pspeed * conPortal^.dY + -nspeed * ny; + if iterator^.Kind = gtCake then + itdist := int2hwFloat(iterator^.Radius) - _0_1; + s := itdist / Distance(iterator^.dX, iterator^.dY); + iterator^.X := conPortal^.X + s * iterator^.dX; + iterator^.Y := conPortal^.Y + s * iterator^.dY; + end; FollowGear := iterator; +{ s := _0_2 + _0_008 * Gear^.Health; iterator^.dX := s * iterator^.dX; iterator^.dY := s * iterator^.dY; +} if Gear^.Health > 1 then dec(Gear^.Health); - //dec(iterator^.Health);?? - - // breaks (some) loops + +{ // breaks (some) loops if Distance(iterator^.dX, iterator^.dY) > _0_96 then begin iterator^.dX := iterator^.dX + signAs(cGravity * getRandom(1000),iterator^.dX); @@ -3338,7 +3353,7 @@ iterator^.dX := s * iterator^.dX; iterator^.dY := s * iterator^.dX; end; - end; +} end; procedure doStepMovingPortal_real(Gear: PGear);