# HG changeset patch # User Wuzzy # Date 1508631927 -7200 # Node ID d08afea02908666569ba147c5e49ae8822b079e3 # Parent 7cbb0241d31c9fdefdb5f9ab84373060038da02f Fix bee homing incorrectly when target is across wrap world edge diff -r 7cbb0241d31c -r d08afea02908 ChangeLog.txt --- a/ChangeLog.txt Sun Oct 22 00:48:38 2017 +0200 +++ b/ChangeLog.txt Sun Oct 22 02:25:27 2017 +0200 @@ -37,6 +37,7 @@ * Fixed screenshots being too bright if taken in quick succession * Video recording functionality is restored * Fixed bee not being affected by wrap world edge while still being thrown + * Fixed bee homing incorrectly when target is across wrap world edge * Rope is now destroyed when attempting to shoot it through wrap or bouncy world edge * Fixed turn not ending when sticky mine was trapped on rubberband * Fixed molotov cocktails bouncing off vertically off rubber diff -r 7cbb0241d31c -r d08afea02908 hedgewars/uGearsHandlersMess.pas --- a/hedgewars/uGearsHandlersMess.pas Sun Oct 22 00:48:38 2017 +0200 +++ b/hedgewars/uGearsHandlersMess.pas Sun Oct 22 02:25:27 2017 +0200 @@ -994,11 +994,14 @@ var t: hwFloat; gX,gY,i: LongInt; - uw, nuw: boolean; + uw, nuw, wrapped: boolean; flower: PVisualGear; begin - WorldWrap(Gear); + wrapped:= WorldWrap(Gear); + if wrapped then + HomingWrap(Gear); + AllInactive := false; gX := hwRound(Gear^.X); gY := hwRound(Gear^.Y); @@ -1116,6 +1119,9 @@ Gear^.SoundChannel := LoopSound(sndBee); Gear^.Timer := 5000; + + HomingWrap(Gear); + // save initial speed in otherwise unused Friction variable Gear^.Friction := Distance(Gear^.dX, Gear^.dY); Gear^.doStep := @doStepBeeWork diff -r 7cbb0241d31c -r d08afea02908 hedgewars/uGearsUtils.pas --- a/hedgewars/uGearsUtils.pas Sun Oct 22 00:48:38 2017 +0200 +++ b/hedgewars/uGearsUtils.pas Sun Oct 22 02:25:27 2017 +0200 @@ -57,6 +57,7 @@ function GetUtility(Hedgehog: PHedgehog): TAmmoType; function WorldWrap(var Gear: PGear): boolean; +function HomingWrap(var Gear: PGear): boolean; function IsHogLocal(HH: PHedgehog): boolean; @@ -1628,6 +1629,47 @@ end; end; +(* +Applies wrap-around logic for the target of homing gears. + +In wrap-around world edge, the shortest way may to the target might +be across the border, so the X value of the target would lead the +gear to the wrong direction across the whole map. This procedure +changes the target X in this case. +This function must be called in the gear set-up routine and whenever +the gear passed through the wrap-around world edge. + +No-op for other world edges. + +Returns true if target has been changed. +*) +function HomingWrap(var Gear: PGear): boolean; +var dist_center, dist_right, dist_left: hwFloat; +begin + if WorldEdge = weWrap then + begin + HomingWrap:= false; + // We just need check the same target 3 times: + // 1) in current section (no change) + // 2) clone in the right section + // 3) clone in the left section + // The gear will go for the target with the shortest distance to the gear + dist_center:= Distance(Gear^.X - int2hwFloat(Gear^.Target.X), Gear^.Y - int2hwFloat(Gear^.Target.Y)); + dist_right:= Distance(Gear^.X - int2hwFloat(Gear^.Target.X + (RightX-LeftX)), Gear^.Y - int2hwFloat(Gear^.Target.Y)); + dist_left:= Distance(Gear^.X - int2hwFloat(Gear^.Target.X - (RightX-LeftX)), Gear^.Y - int2hwFloat(Gear^.Target.Y)); + if (dist_left < dist_right) and (dist_left < dist_center) then + begin + dec(Gear^.Target.X, RightX-LeftX); + HomingWrap:= true; + end + else if (dist_right < dist_left) and (dist_right < dist_center) then + begin + inc(Gear^.Target.X, RightX-LeftX); + HomingWrap:= true; + end; + end; +end; + procedure AddBounceEffectForGear(Gear: PGear); var boing: PVisualGear; begin