diff -r fad3408fdcc1 -r a1476c09403f hedgewars/GSHandlers.inc --- 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;