hedgewars/GSHandlers.inc
changeset 7733 a1476c09403f
parent 7730 2013733f9ca9
child 7734 b0d8a595875b
--- a/hedgewars/GSHandlers.inc	Tue Oct 09 00:38:17 2012 +0400
+++ b/hedgewars/GSHandlers.inc	Mon Oct 08 21:07:18 2012 -0400
@@ -5247,84 +5247,128 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Make the knife initial angle based on the hog attack angle, or is that too hard?
 procedure doStepKnife(Gear: PGear);
-var t, ox, oy, w, h, cx, cy, tx, ty, hx, hy : LongInt;
+var t, 
+    gx, gy, ga,  // gear x,y,angle
+    lx, ly, la, // land x,y,angle
+    ox, oy, // x,y offset
+    w, h,   // wXh of clip area
+    tx, ty  // tip position in sprite
+    : LongInt;
+    surf: PSDL_Surface;
+    s: hwFloat;
+
 begin
-    doStepFallingGear(Gear);
+    Gear^.dY := Gear^.dY + cGravity;
+    if (GameFlags and gfMoreWind) <> 0 then
+        Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density;
+    Gear^.X := Gear^.X + Gear^.dX;
+    Gear^.Y := Gear^.Y + Gear^.dY;
+    CheckGearDrowning(Gear);
+    gx:= hwRound(Gear^.X);
+    gy:= hwRound(Gear^.Y);
+    if Gear^.State and gstDrowning <> 0 then exit;
     with Gear^ do
         begin
-        if State and gstCollision <> 0 then
+        if CheckLandValue(gx, gy, $FF00) then
+            begin
+            t:= Angle + hwRound((hwAbs(dX)+hwAbs(dY)) * _10); 
+
+            if t < 0 then inc(t, 4096)
+            else if 4095 < t then dec(t, 4096);
+            Angle:= t;
+
+            DirAngle:= Angle / 4096 * 360
+            end
+        else
             begin
-(* Yay. More incomplete code.
-This is the set of postions for the knife.
-Using FlipSurface and copyToXY the knife can be written to the LandPixels at 32 positions, and an appropriate line drawn in Land.
-0deg
-2,5   (x,y offset)
-25,5  (wXh of clip area)
-13,2  (centre of mass, relative to the clip)
--13,0 (tip relative to centre of mass)
-11,0  (handle relative to centre of mass)
-
-11.25deg
-2,15
-24,8
-13,4
--13,3
-10,-3
-
-22.5deg
-2,27
-23,12
-12,6
--12,5
-10,-5
-
-33.75deg
-2,43
-21,15
-11,7
--11,7
-9,-6
-
-45deg
-29,8
-19,19
-9,9
--9,8
-8,-9
-
-56.25deg
-29,32
-15,21
-7,10
--7,10
-7,-10
-
-67.5deg
-51,3
-11,23
-5,11
--5,11
-5,-11
-
-78.75deg
-51,34
-7,24
-2,11
--2,12
-4,-11
-*)
+//This is the set of postions for the knife.
+//Using FlipSurface and copyToXY the knife can be written to the LandPixels at 32 positions, and an appropriate line drawn in Land.
+            t:= Angle mod 1024;
+            case t div 128 of
+                0:  begin
+                    ox:=   2; oy:= 5;
+                    w :=  25;  h:= 5;
+                    tx:=   0; ty:= 2
+                    end;
+                1:  begin
+                    ox:=   2; oy:= 15;
+                     w:=  24;  h:=  8;
+                    tx:=   0; ty:=  7
+                    end;
+                2:  begin
+                    ox:=   2; oy:= 27;
+                     w:=  23;  h:= 12;
+                    tx:= -12; ty:= -5
+                    end;
+                3:  begin
+                    ox:=   2; oy:= 43;
+                     w:=  21;  h:= 15;
+                    tx:=   0; ty:= 14
+                    end;
+                4:  begin
+                    ox:= 29; oy:=  8;
+                     w:= 19;  h:= 19;
+                    tx:=  0; ty:= 17 
+                    end;
+                5:  begin
+                    ox:= 29; oy:=  32;
+                     w:= 15;  h:=  21;
+                    tx:=  0; ty:=  20
+                    end;
+                6:  begin
+                    ox:= 51; oy:=   3;
+                     w:= 11;  h:=  23;
+                    tx:=  0; ty:=  22 
+                    end;
+                7:  begin
+                    ox:= 51; oy:=  34;
+                     w:=  7;  h:=  24;
+                    tx:=  0; ty:=  23
+                    end
+                end;
+                
+            surf:= SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RMask, GMask, BMask, AMask);
+            copyToXYFromRect(SpritesData[sprKnife].Surface, surf, ox, oy, w, h, 0, 0);
+            // try to make the knife hit point first
+            lx := 0;
+            ly := 0;
+            if CalcSlopeTangent(Gear, gx, gy, lx, ly, 255) then
+                begin
+                la:= vector2Angle(int2hwFloat(lx), int2hwFloat(ly));
+                ga:= vector2Angle(dX, dY);
+                // change  to 0 to 4096 forced by LongWord in Gear
+                if la < 0 then la:= 4096+la;
+                if ga < 0 then ga:= 4096+ga;
+                if ((Angle < ga) and (Angle < la)) or ((Angle > ga) and (Angle > la)) then
+                    begin
+                    if Angle >= 2048 then dec(Angle, 2048)
+                    else if Angle < 2048 then inc(Angle, 2048)
+                    end
+                end;
+            case Angle div 1024 of
+                0:  begin 
+                    flipSurface(surf, true);
+                    flipSurface(surf, true);
+                    BlitImageAndGenerateCollisionInfo(hwRound(X)-(w-tx), hwRound(Y)+(w-ty), w, surf)
+                    end;
+                1:  begin
+                    flipSurface(surf, false);
+                    BlitImageAndGenerateCollisionInfo(hwRound(X)-(w-tx), hwRound(Y)-ty, w, surf)
+                    end;
+                2:  begin // knife was actually drawn facing this way...
+                    BlitImageAndGenerateCollisionInfo(hwRound(X)-tx, hwRound(Y)-ty, w, surf)
+                    end;
+                3:  begin
+                    flipSurface(surf, true);
+                    BlitImageAndGenerateCollisionInfo(hwRound(X)-tx, hwRound(Y)+(w-ty), w, surf)
+                    end
+                end;
+            SDL_FreeSurface(surf);
+            // this needs to calculate actual width/height + land clipping since update texture doesn't.
+            // i.e. this will crash if you fire near sides of map, but until I get the blit right, not going to put real values
+            UpdateLandTexture(hwRound(X)-32, 64, hwRound(Y)-32, 64, true);
             DeleteGear(Gear);
             exit
             end
-        else
-            begin
-            t := hwRound((dX + dY) * _10);
-            if not dX.isNegative then inc(Angle, t)
-            else dec(Angle,t);
-
-            if Angle < -2048 then inc(Angle, 4096)
-            else if 2048 < Angle then dec(Angle, 4096);
-            DirAngle:= (Angle+2048) / 4096 * 360;
-            end
         end;
 end;