# HG changeset patch # User Wuzzy # Date 1546541208 -3600 # Node ID 5ac181cb2396e2eb50fc6be195ba28f8b78f9563 # Parent 5230c063214a6c66dcd796fbe5d58ce27e1ee72f Fix bee targeting fail across wrap world edge Previously, the bee always aimed for the light area, no matter where you actually put the target. It also got confused whenever it flew across the wrap world edge. How the bee works now: 1) The placed bee target is *not* recalculated when it was placed in the "gray" part of the wrap world edge. This allows for more fine-tuning. 1a) Place target in light area: bee aims for target light area 1b) Place target in gray area: bee aims for target, but flies to gray area first 2) Bee target is recalculated whenever bee passes the wrap world edge. diff -r 5230c063214a -r 5ac181cb2396 ChangeLog.txt --- a/ChangeLog.txt Thu Jan 03 17:57:31 2019 +0100 +++ b/ChangeLog.txt Thu Jan 03 19:46:48 2019 +0100 @@ -13,6 +13,7 @@ + Don't show crate spawn message for initial crates in missions * Use player-chosen team identity in campaigns and singleplayer missions * Fix last 2 characters in demo chat being missing + * Fix homing bee flying weird if passing wrap world edge or target was placed beyond it * King Mode: Fix team sometimes not being killed properly if king drowned * King Mode: Kill resurrected minions if king is not alive * Fix poison damage not working in first round diff -r 5230c063214a -r 5ac181cb2396 hedgewars/uConsts.pas --- a/hedgewars/uConsts.pas Thu Jan 03 17:57:31 2019 +0100 +++ b/hedgewars/uConsts.pas Thu Jan 03 19:46:48 2019 +0100 @@ -336,6 +336,7 @@ = $00100000; // doesn't stop timer while Attacking gear msg is set and inf. attack mode is on ammoprop_ForceTurnEnd = $00200000; // always ends turn after usage, ignoring inf. attack ammoprop_NoTargetAfter= $00400000; // disable target selection after attack + ammoprop_NoWrapTarget = $00800000; // allow to select target beyond wrap world edge limits ammoprop_NoRoundEnd = $10000000; // ammo doesn't end turn AMMO_INFINITE = 100; // internal representation of infinite ammo count diff -r 5230c063214a -r 5ac181cb2396 hedgewars/uGearsHandlersMess.pas --- a/hedgewars/uGearsHandlersMess.pas Thu Jan 03 17:57:31 2019 +0100 +++ b/hedgewars/uGearsHandlersMess.pas Thu Jan 03 19:46:48 2019 +0100 @@ -1046,11 +1046,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); diff -r 5230c063214a -r 5ac181cb2396 hedgewars/uGearsUtils.pas --- a/hedgewars/uGearsUtils.pas Thu Jan 03 17:57:31 2019 +0100 +++ b/hedgewars/uGearsUtils.pas Thu Jan 03 19:46:48 2019 +0100 @@ -64,6 +64,7 @@ function GetUtility(Hedgehog: PHedgehog): TAmmoType; function WorldWrap(var Gear: PGear): boolean; +function HomingWrap(var Gear: PGear): boolean; function IsHogLocal(HH: PHedgehog): boolean; @@ -1809,6 +1810,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 after the gear passed through +the wrap-around world edge (WorldWrap returned true). + +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 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. + // For simplicity, we only check distance on the X axis. + dist_center:= hwAbs(Gear^.X - int2hwFloat(Gear^.Target.X)); + dist_right:= hwAbs(Gear^.X - int2hwFloat(Gear^.Target.X + (RightX-LeftX))); + dist_left:= hwAbs(Gear^.X - int2hwFloat(Gear^.Target.X - (RightX-LeftX))); + 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; // Add an audiovisual bounce effect for gear after it bounced from bouncy material. // Graphical effect is based on speed. diff -r 5230c063214a -r 5ac181cb2396 hedgewars/uIO.pas --- a/hedgewars/uIO.pas Thu Jan 03 17:57:31 2019 +0100 +++ b/hedgewars/uIO.pas Thu Jan 03 19:46:48 2019 +0100 @@ -527,13 +527,14 @@ TargetPoint.X:= CursorPoint.X - WorldDx; TargetPoint.Y:= cScreenHeight - CursorPoint.Y - WorldDy; end; - if (WorldEdge <> weBounce) then + if (WorldEdge <> weBounce) and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoWrapTarget) = 0) then TargetPoint.X:= CalcWorldWrap(TargetPoint.X, 0); SendIPCXY('p', TargetPoint.X, TargetPoint.Y); end else begin - TargetPoint.X:= CalcWorldWrap(TargetPoint.X, 0); + if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoWrapTarget) = 0 then + TargetPoint.X:= CalcWorldWrap(TargetPoint.X, 0); TargetPoint.X:= putX; TargetPoint.Y:= putY end; diff -r 5230c063214a -r 5ac181cb2396 hedgewars/uVariables.pas --- a/hedgewars/uVariables.pas Thu Jan 03 17:57:31 2019 +0100 +++ b/hedgewars/uVariables.pas Thu Jan 03 19:46:48 2019 +0100 @@ -951,6 +951,7 @@ Ammo: (Propz: ammoprop_Power or ammoprop_NeedTarget or ammoprop_NoTargetAfter or + ammoprop_NoWrapTarget or ammoprop_DontHold or ammoprop_NeedUpDown; Count: 2;