# HG changeset patch # User Wuzzy # Date 1532949601 -7200 # Node ID a71e6856ffab7fa7f0e7adcd0b0df788e3c414b7 # Parent fb81633f17fa8aa03b1f63d4e01783174c800ffc Fix freeze ray not working through wrap world edge; add DrawLineWrapped diff -r fb81633f17fa -r a71e6856ffab ChangeLog.txt --- a/ChangeLog.txt Sun Jul 29 11:39:48 2018 -0400 +++ b/ChangeLog.txt Mon Jul 30 13:20:01 2018 +0200 @@ -10,6 +10,8 @@ * Functionality of controllers restored * Fix crash when 2 or more controllers were connected * Fix hammer and pickhammer not digging correctly at wrap world edge + * Fix freezer ray not working through wrap world edge + * Fix freezer ray going through bounce world edge * Fix extreme amounts of droplets when shooting with minigun into ocean world edge * Fix hog being unable to walk after using sniper rifle without firing both shots * Fix video recorder not working when game audio was disabled diff -r fb81633f17fa -r a71e6856ffab hedgewars/uGearsHandlersMess.pas --- a/hedgewars/uGearsHandlersMess.pas Sun Jul 29 11:39:48 2018 -0400 +++ b/hedgewars/uGearsHandlersMess.pas Mon Jul 30 13:20:01 2018 +0200 @@ -6227,6 +6227,9 @@ exit end; updateFuel(Gear); + if WorldWrap(Gear) and (WorldEdge = weWrap) and (Gear^.Target.X = NoPointX) then + // Use FlightTime to count number of times the gear has world-wrapped + inc(Gear^.FlightTime); with Gear^ do begin @@ -6240,6 +6243,7 @@ begin updateTarget(Gear, ndX, ndY); Timer := iceWaitCollision; + FlightTime := 0; end else begin diff -r fb81633f17fa -r a71e6856ffab hedgewars/uGearsList.pas --- a/hedgewars/uGearsList.pas Sun Jul 29 11:39:48 2018 -0400 +++ b/hedgewars/uGearsList.pas Mon Jul 30 13:20:01 2018 +0200 @@ -727,6 +727,7 @@ gtIceGun: begin gear^.Health:= 1000; gear^.Radius:= 8; + gear^.Density:= _0; end; gtDuck: begin gear^.Pos:= 0; // 0: in air, 1-4: on water, 5-8: underwater diff -r fb81633f17fa -r a71e6856ffab hedgewars/uGearsRender.pas --- a/hedgewars/uGearsRender.pas Sun Jul 29 11:39:48 2018 -0400 +++ b/hedgewars/uGearsRender.pas Mon Jul 30 13:20:01 2018 +0200 @@ -1568,11 +1568,11 @@ i:= random(100)+100; if Gear^.Target.X <> NoPointX then begin - DrawLine(Gear^.Target.X, Gear^.Target.Y, hwRound(HHGear^.X), hwRound(HHGear^.Y), 4.0, i, i, $FF, $40); + DrawLineWrapped(hwRound(HHGear^.X), hwRound(HHGear^.Y), Gear^.Target.X, Gear^.Target.Y, 4.0, hwSign(HHGear^.dX) < 0, Gear^.FlightTime, i, i, $FF, $40); end else begin - DrawLine(hwRound(HHGear^.X), hwRound(HHGear^.Y), hwRound(Gear^.X), hwRound(Gear^.Y), 4.0, i, i, $FF, $40); + DrawLineWrapped(hwRound(HHGear^.X), hwRound(HHGear^.Y), hwRound(Gear^.X), hwRound(Gear^.Y), 4.0, hwSign(HHGear^.dX) < 0, Gear^.FlightTime, i, i, $FF, $40); end; end end diff -r fb81633f17fa -r a71e6856ffab hedgewars/uGearsUtils.pas --- a/hedgewars/uGearsUtils.pas Sun Jul 29 11:39:48 2018 -0400 +++ b/hedgewars/uGearsUtils.pas Mon Jul 30 13:20:01 2018 +0200 @@ -1723,6 +1723,8 @@ procedure AddBounceEffectForGear(Gear: PGear); var boing: PVisualGear; begin + if Gear^.Density < _0_01 then + exit; boing:= AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtStraightShot, 0, false, 1); if boing <> nil then with boing^ do diff -r fb81633f17fa -r a71e6856ffab hedgewars/uRender.pas --- a/hedgewars/uRender.pas Sun Jul 29 11:39:48 2018 -0400 +++ b/hedgewars/uRender.pas Mon Jul 30 13:20:01 2018 +0200 @@ -53,6 +53,8 @@ procedure DrawLine (X0, Y0, X1, Y1, Width: Single; color: LongWord); inline; procedure DrawLine (X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); +procedure DrawLineWrapped (X0, Y0, X1, Y1, Width: Single; goesLeft: boolean; Wraps: LongWord; color: LongWord); inline; +procedure DrawLineWrapped (X0, Y0, X1, Y1, Width: Single; goesLeft: boolean; Wraps: LongWord; r, g, b, a: Byte); procedure DrawLineOnScreen (X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); procedure DrawRect (rect: TSDL_Rect; r, g, b, a: Byte; Fill: boolean); procedure DrawHedgehog (X, Y: LongInt; Dir: LongInt; Pos, Step: LongWord; Angle: real); @@ -1337,11 +1339,17 @@ end; end; +// Same as below, but with color as LongWord procedure DrawLine(X0, Y0, X1, Y1, Width: Single; color: LongWord); inline; begin DrawLine(X0, Y0, X1, Y1, Width, (color shr 24) and $FF, (color shr 16) and $FF, (color shr 8) and $FF, color and $FF) end; +// Draw line between 2 points +// X0, Y0: Start point +// X0, Y1: End point +// Width: Visual line width +// r, g, b, a: Color procedure DrawLine(X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); begin openglPushMatrix(); @@ -1356,6 +1364,106 @@ UpdateModelviewProjection; end; +// Same as below, but with color as a longword +procedure DrawLineWrapped(X0, Y0, X1, Y1, Width: Single; goesLeft: boolean; Wraps: LongWord; color: LongWord); inline; +begin +DrawLineWrapped(X0, Y0, X1, Y1, Width, goesLeft, Wraps, (color shr 24) and $FF, (color shr 16) and $FF, (color shr 8) and $FF, color and $FF); +end; + +// Draw a line between 2 points, but it wraps around the +// world edge for a given number of times. +// goesLeft: true if the line direction from the start point is left +// Wraps: Number of times the line intersects the wrapping world edge +// r, g, b, a: color +procedure DrawLineWrapped(X0, Y0, X1, Y1, Width: Single; goesLeft: boolean; Wraps: LongWord; r, g, b, a: Byte); +var w: LongWord; + startX, startY, endX, endY: Single; + // total X and Y distance the line travels if you would unwrap it + // with this we know the slope of the line. + totalX, totalY: Single; + // x variable for the line formula + x: Single; +begin + openglPushMatrix(); + openglTranslatef(WorldDx, WorldDy, 0); + + UpdateModelviewProjection; + + startX:= X0; + startY:= Y0; + if (Wraps = 0) then + begin + // Wraps=0 is trivial: Just draw one direct connection + endX:= X1; + endY:= Y1; + DrawLineOnScreen(startX, startY, endX, endY, Width, r, g, b, a); + end + else + begin + // A wrapping line is drawn using multiple line segments + // which stop at the left and right border. We + // calculate the points at which the line intersects with the border. + // Then we draws all line segments. + + // Calculate position of first wrap point + if goesLeft then + begin + endX:= LeftX; + totalX:= (RightX - X1) + (X0 - LeftX); + x:= X0 - LeftX; + end + else + begin + endX:= RightX; + totalX:= (RightX - X0) + (X1 - LeftX); + x:= RightX - X0; + end; + if (Wraps >= 2) then + totalX:= totalX + ((RightX - LeftX) * (Wraps-1)); + totalY:= Y1 - Y0; + // Calculate Y of first wrap point using the line formula + endY:= Y0 + (totalY / totalX) * x; + // Draw line segment between starting point and first wrap point + DrawLineOnScreen(startX, startY, endX, endY, Width, r, g, b, a); + + // Calculate and draw all remaining line segments + for w:=1 to Wraps do + begin + startY:= endY; + if goesLeft then + begin + startX:= RightX; + if w < Wraps then + endX:= LeftX + else + endX:= X1; + end + else + begin + startX:= LeftX; + if w < Wraps then + endX:= RightX + else + endX:= X1; + end; + if w < Wraps then + begin + x:= x + (RightX - LeftX); + endY:= Y0 + (totalY / totalX) * x; + end + else + endY:= Y1; + + DrawLineOnScreen(startX, startY, endX, endY, Width, r, g, b, a); + end; + + end; + + openglPopMatrix(); + + UpdateModelviewProjection; +end; + procedure DrawLineOnScreen(X0, Y0, X1, Y1, Width: Single; r, g, b, a: Byte); begin glEnable(GL_LINE_SMOOTH);