hedgewars/uGearsHandlersMess.pas
changeset 10354 56bd029245fc
parent 10352 2af2309207b0
child 10356 7d1044267b83
equal deleted inserted replaced
10352:2af2309207b0 10354:56bd029245fc
   257 
   257 
   258 
   258 
   259 ////////////////////////////////////////////////////////////////////////////////
   259 ////////////////////////////////////////////////////////////////////////////////
   260 procedure doStepDrowningGear(Gear: PGear);
   260 procedure doStepDrowningGear(Gear: PGear);
   261     begin
   261     begin
   262     AllInactive := false;
   262     if Gear^.Timer = 0 then
       
   263         begin
       
   264         if (FollowGear = Gear) and (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) then
       
   265             FollowGear:= CurrentHedgehog^.Gear;
       
   266         end
       
   267     else if Gear^.Timer > 0 then
       
   268         begin
       
   269         AllInactive := false;
       
   270         dec(Gear^.Timer);
       
   271         end;
       
   272 
   263     Gear^.Y := Gear^.Y + cDrownSpeed;
   273     Gear^.Y := Gear^.Y + cDrownSpeed;
   264     Gear^.X := Gear^.X + Gear^.dX * cDrownSpeed;
   274 
       
   275     if cWaterLine > hwRound(Gear^.Y) + Gear^.Radius then
       
   276         begin
       
   277         if leftX > hwRound(Gear^.X) - Gear^.Radius then
       
   278             Gear^.X := Gear^.X - cDrownSpeed
       
   279         else
       
   280             Gear^.X := Gear^.X + cDrownSpeed;
       
   281         end
       
   282     else
       
   283         Gear^.X := Gear^.X + Gear^.dX * cDrownSpeed;
       
   284 
       
   285     if cWaterLine < hwRound(Gear^.Y) + Gear^.Radius then
       
   286     else
       
   287         Gear^.Y := Gear^.Y + Gear^.dY * cDrownSpeed;
       
   288 
   265     // Create some bubbles (0.5% might be better but causes too few bubbles sometimes)
   289     // Create some bubbles (0.5% might be better but causes too few bubbles sometimes)
   266     if ((not SuddenDeathDmg and (WaterOpacity < $FF))
   290     if ((not SuddenDeathDmg and (WaterOpacity < $FF))
   267     or (SuddenDeathDmg and (SDWaterOpacity < $FF))) and ((GameTicks and $1F) = 0) then
   291     or (SuddenDeathDmg and (SDWaterOpacity < $FF))) and ((GameTicks and $1F) = 0) then
   268         if (Gear^.Kind = gtHedgehog) and (Random(4) = 0) then
   292         if (Gear^.Kind = gtHedgehog) and (Random(4) = 0) then
   269             AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, vgtBubble)
   293             AddVisualGear(hwRound(Gear^.X) - Gear^.Radius, hwRound(Gear^.Y) - Gear^.Radius, vgtBubble)
   299     if Gear^.dX.Round > 1 then
   323     if Gear^.dX.Round > 1 then
   300         Gear^.dX.QWordValue:= 8589934592;
   324         Gear^.dX.QWordValue:= 8589934592;
   301     if Gear^.dY.Round > 1 then
   325     if Gear^.dY.Round > 1 then
   302         Gear^.dY.QWordValue:= 8589934592;
   326         Gear^.dY.QWordValue:= 8589934592;
   303 
   327 
   304     if (Gear^.State and gstSubmersible <> 0) and (gY > cWaterLine) then
   328     if (Gear^.State and gstSubmersible <> 0) and CheckCoordInWater(gX, gY) then
   305         begin
   329         begin
   306         Gear^.dX:= Gear^.dX * _0_999;
   330         Gear^.dX:= Gear^.dX * _0_999;
   307         Gear^.dY:= Gear^.dY * _0_999
   331         Gear^.dY:= Gear^.dY * _0_999
   308         end;
   332         end;
   309 
   333 
   785             if Timer = vobFramesCount then
   809             if Timer = vobFramesCount then
   786                 Timer:= 0
   810                 Timer:= 0
   787             end;
   811             end;
   788 *)
   812 *)
   789     // move back to cloud layer
   813     // move back to cloud layer
   790         if yy > cWaterLine then
   814         if CheckCoordInWater(xx, yy) then
   791             move:= true
   815             move:= true
   792         else if (xx > snowRight) or (xx < snowLeft) then
   816         else if (xx > snowRight) or (xx < snowLeft) then
   793             move:=true
   817             move:=true
   794         // Solid pixel encountered
   818         // Solid pixel encountered
   795         else if ((yy and LAND_HEIGHT_MASK) = 0) and ((xx and LAND_WIDTH_MASK) = 0) and (Land[yy, xx] <> 0) then
   819         else if ((yy and LAND_HEIGHT_MASK) = 0) and ((xx and LAND_WIDTH_MASK) = 0) and (Land[yy, xx] <> 0) then
   954     WorldWrap(Gear);
   978     WorldWrap(Gear);
   955     AllInactive := false;
   979     AllInactive := false;
   956     gX := hwRound(Gear^.X);
   980     gX := hwRound(Gear^.X);
   957     gY := hwRound(Gear^.Y);
   981     gY := hwRound(Gear^.Y);
   958     uw := (Gear^.Tag <> 0); // was bee underwater last tick?
   982     uw := (Gear^.Tag <> 0); // was bee underwater last tick?
   959     nuw := (cWaterLine < gy + Gear^.Radius); // is bee underwater now?
   983     nuw := CheckCoordInWater(gx, gy + Gear^.Radius); // is bee underwater now?
   960 
   984 
   961     // if water entered or left
   985     // if water entered or left
   962     if nuw <> uw then
   986     if nuw <> uw then
   963         begin
   987         begin
   964         AddVisualGear(gX, cWaterLine, vgtSplash);
   988         if (gX > leftX) and (gY < rightX) then
   965         AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
   989             begin
   966         AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
   990             AddVisualGear(gX, cWaterLine, vgtSplash);
   967         AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
   991             AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
   968         AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
   992             AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
       
   993             AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
       
   994             AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
       
   995             end;
   969         StopSoundChan(Gear^.SoundChannel);
   996         StopSoundChan(Gear^.SoundChannel);
   970         if nuw then
   997         if nuw then
   971             begin
   998             begin
   972             Gear^.SoundChannel := LoopSound(sndBeeWater);
   999             Gear^.SoundChannel := LoopSound(sndBeeWater);
   973             Gear^.Tag := 1;
  1000             Gear^.Tag := 1;
  1176 
  1203 
  1177             // reached edge of land. assume infinite beam. Extend it way out past camera
  1204             // reached edge of land. assume infinite beam. Extend it way out past camera
  1178             if (hwRound(Bullet^.X) and LAND_WIDTH_MASK <> 0)
  1205             if (hwRound(Bullet^.X) and LAND_WIDTH_MASK <> 0)
  1179             or (hwRound(Bullet^.Y) and LAND_HEIGHT_MASK <> 0) then
  1206             or (hwRound(Bullet^.Y) and LAND_HEIGHT_MASK <> 0) then
  1180                     // only extend if not under water
  1207                     // only extend if not under water
  1181                     if hwRound(Bullet^.Y) < cWaterLine then
  1208                     if not CheckCoordInWater(hwRound(Bullet^.X), hwRound(Bullet^.Y)) then
  1182                         begin
  1209                         begin
  1183                         VGear^.dX := VGear^.dX + max(LAND_WIDTH,4096) * (VGear^.dX - VGear^.X);
  1210                         VGear^.dX := VGear^.dX + max(LAND_WIDTH,4096) * (VGear^.dX - VGear^.X);
  1184                         VGear^.dY := VGear^.dY + max(LAND_WIDTH,4096) * (VGear^.dY - VGear^.Y);
  1211                         VGear^.dY := VGear^.dY + max(LAND_WIDTH,4096) * (VGear^.dY - VGear^.Y);
  1185                         end;
  1212                         end;
  1186 
  1213 
  2151 
  2178 
  2152         //if sticky then Gear^.X := Gear^.X + Gear^.dX else
  2179         //if sticky then Gear^.X := Gear^.X + Gear^.dX else
  2153         Gear^.X := Gear^.X + Gear^.dX + cWindSpeed * 640;
  2180         Gear^.X := Gear^.X + Gear^.dX + cWindSpeed * 640;
  2154         Gear^.Y := Gear^.Y + Gear^.dY;
  2181         Gear^.Y := Gear^.Y + Gear^.dY;
  2155 
  2182 
  2156         if (hwRound(Gear^.Y) > cWaterLine) then
  2183         gX := hwRound(Gear^.X);
  2157             begin
  2184         gY := hwRound(Gear^.Y);
  2158             gX := hwRound(Gear^.X);
  2185 
       
  2186         if CheckCoordInWater(gX, gY) then
       
  2187             begin
  2159             for i:= 0 to 3 do
  2188             for i:= 0 to 3 do
  2160                 AddVisualGear(gX - 16 + Random(32), cWaterLine - 16 + Random(16), vgtSteam);
  2189                 AddVisualGear(gX - 8 + Random(16), gY - 8 + Random(16), vgtSteam);
  2161             PlaySound(sndVaporize);
  2190             PlaySound(sndVaporize);
  2162             DeleteGear(Gear);
  2191             DeleteGear(Gear);
  2163             exit
  2192             exit
  2164             end
  2193             end
  2165         end
  2194         end
  2168         if (Gear^.Timer = 1) and (GameTicks and $3 = 0) then
  2197         if (Gear^.Timer = 1) and (GameTicks and $3 = 0) then
  2169             begin
  2198             begin
  2170             Gear^.Y:= Gear^.Y+_6;
  2199             Gear^.Y:= Gear^.Y+_6;
  2171             if (landPixel and lfIce <> 0) or (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
  2200             if (landPixel and lfIce <> 0) or (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
  2172                 begin
  2201                 begin
  2173                 gX := hwRound(Gear^.X);
  2202                 gY := gy-6;
  2174                 gY := hwRound(Gear^.Y)-6;
       
  2175                 DrawExplosion(gX, gY, 4);
  2203                 DrawExplosion(gX, gY, 4);
  2176                 PlaySound(sndVaporize);
  2204                 PlaySound(sndVaporize);
  2177                 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSteam);
  2205                 AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSteam);
  2178                 DeleteGear(Gear);
  2206                 DeleteGear(Gear);
  2179                 exit
  2207                 exit
  2199             dec(Gear^.Timer);
  2227             dec(Gear^.Timer);
  2200             inc(Gear^.Damage)
  2228             inc(Gear^.Damage)
  2201             end
  2229             end
  2202         else
  2230         else
  2203             begin
  2231             begin
  2204             gX := hwRound(Gear^.X);
       
  2205             gY := hwRound(Gear^.Y);
       
  2206             // Standard fire
  2232             // Standard fire
  2207             if not sticky then
  2233             if not sticky then
  2208                 begin
  2234                 begin
  2209                 if ((GameTicks and $1) = 0) then
  2235                 if ((GameTicks and $1) = 0) then
  2210                     begin
  2236                     begin
  2250                 end
  2276                 end
  2251             end
  2277             end
  2252         end;
  2278         end;
  2253     if Gear^.Health = 0 then
  2279     if Gear^.Health = 0 then
  2254         begin
  2280         begin
  2255         gX := hwRound(Gear^.X);
       
  2256         gY := hwRound(Gear^.Y);
       
  2257         if not sticky then
  2281         if not sticky then
  2258             begin
  2282             begin
  2259             if ((GameTicks and $3) = 0) and (Random(1) = 0) then
  2283             if ((GameTicks and $3) = 0) and (Random(1) = 0) then
  2260                 for i:= Random(2) downto 0 do
  2284                 for i:= Random(2) downto 0 do
  2261                     AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
  2285                     AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke);
  2796 
  2820 
  2797         Gear^.X := Gear^.X + HHGear^.dX;
  2821         Gear^.X := Gear^.X + HHGear^.dX;
  2798         Gear^.Y := Gear^.Y + HHGear^.dY;
  2822         Gear^.Y := Gear^.Y + HHGear^.dY;
  2799         HHGear^.X := Gear^.X;
  2823         HHGear^.X := Gear^.X;
  2800         HHGear^.Y := Gear^.Y;
  2824         HHGear^.Y := Gear^.Y;
       
  2825 
       
  2826         // check for drowning
       
  2827         if CheckGearDrowning(HHGear) then
       
  2828             begin
       
  2829             AfterAttack;
       
  2830             DeleteGear(Gear);
       
  2831             exit;
       
  2832             end;
  2801 
  2833 
  2802         inc(Gear^.Damage, 2);
  2834         inc(Gear^.Damage, 2);
  2803 
  2835 
  2804         //  if TestCollisionXwithGear(HHGear, hwSign(Gear^.dX))
  2836         //  if TestCollisionXwithGear(HHGear, hwSign(Gear^.dX))
  2805         //      or TestCollisionYwithGear(HHGear, hwSign(Gear^.dY)) then inc(Gear^.Damage, 3);
  2837         //      or TestCollisionYwithGear(HHGear, hwSign(Gear^.dY)) then inc(Gear^.Damage, 3);
  3165     if Gear^.Timer = 17 then
  3197     if Gear^.Timer = 17 then
  3166         Gear^.Timer := 0
  3198         Gear^.Timer := 0
  3167     else
  3199     else
  3168         exit;
  3200         exit;
  3169 
  3201 
       
  3202     if playWidth > cMinPlayWidth then
       
  3203         begin
       
  3204         inc(leftX);
       
  3205         dec(rightX);
       
  3206         dec(playWidth, 2);
       
  3207         for i:= 0 to LAND_HEIGHT - 1 do
       
  3208             begin
       
  3209             Land[i, leftX] := 0;
       
  3210             Land[i, rightX] := 0;
       
  3211             end;
       
  3212         end;
       
  3213 
  3170     if cWaterLine > 0 then
  3214     if cWaterLine > 0 then
  3171         begin
  3215         begin
  3172         dec(cWaterLine);
  3216         dec(cWaterLine);
  3173         for i:= 0 to LAND_WIDTH - 1 do
  3217         for i:= 0 to LAND_WIDTH - 1 do
  3174             Land[cWaterLine, i] := 0;
  3218             Land[cWaterLine, i] := 0;
  3506     fuel, i: LongInt;
  3550     fuel, i: LongInt;
  3507     move: hwFloat;
  3551     move: hwFloat;
  3508     isUnderwater: Boolean;
  3552     isUnderwater: Boolean;
  3509     bubble: PVisualGear;
  3553     bubble: PVisualGear;
  3510 begin
  3554 begin
  3511     isUnderwater:= cWaterLine < hwRound(Gear^.Y) + Gear^.Radius;
  3555     isUnderwater:= CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y) + Gear^.Radius);
  3512     if Gear^.Pos > 0 then
  3556     if Gear^.Pos > 0 then
  3513         dec(Gear^.Pos);
  3557         dec(Gear^.Pos);
  3514     AllInactive := false;
  3558     AllInactive := false;
  3515     HHGear := Gear^.Hedgehog^.Gear;
  3559     HHGear := Gear^.Hedgehog^.Gear;
  3516     //dec(Gear^.Timer);
  3560     //dec(Gear^.Timer);
  3612         doStepHedgehogMoving(HHGear);
  3656         doStepHedgehogMoving(HHGear);
  3613 
  3657 
  3614     if // (Gear^.Health = 0)
  3658     if // (Gear^.Health = 0)
  3615         (HHGear^.Damage <> 0)
  3659         (HHGear^.Damage <> 0)
  3616         //or CheckGearDrowning(HHGear)
  3660         //or CheckGearDrowning(HHGear)
       
  3661         // drown if too deep under water
  3617         or (cWaterLine + cVisibleWater * 4 < hwRound(HHGear^.Y))
  3662         or (cWaterLine + cVisibleWater * 4 < hwRound(HHGear^.Y))
  3618         or (TurnTimeLeft = 0)
  3663         or (TurnTimeLeft = 0)
  3619         // allow brief ground touches - to be fair on this, might need another counter
  3664         // allow brief ground touches - to be fair on this, might need another counter
  3620         or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0))
  3665         or (((GameTicks and $1FF) = 0) and (not HHGear^.dY.isNegative) and (TestCollisionYwithGear(HHGear, 1) <> 0))
  3621         or ((Gear^.Message and gmAttack) <> 0) then
  3666         or ((Gear^.Message and gmAttack) <> 0) then
  3927 
  3972 
  3928     // destroy portal if ground it was attached too is gone
  3973     // destroy portal if ground it was attached too is gone
  3929     if (Land[hwRound(Gear^.Y), hwRound(Gear^.X)] <= lfAllObjMask)
  3974     if (Land[hwRound(Gear^.Y), hwRound(Gear^.X)] <= lfAllObjMask)
  3930     or (Gear^.Timer < 1)
  3975     or (Gear^.Timer < 1)
  3931     or (Gear^.Hedgehog^.Team <> CurrentHedgehog^.Team)
  3976     or (Gear^.Hedgehog^.Team <> CurrentHedgehog^.Team)
  3932     or (hwRound(Gear^.Y) > cWaterLine) then
  3977     or CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y)) then
  3933         begin
  3978         begin
  3934         deleteGear(Gear);
  3979         deleteGear(Gear);
  3935         EXIT;
  3980         EXIT;
  3936         end;
  3981         end;
  3937 
  3982 
  4316         end
  4361         end
  4317         else
  4362         else
  4318             loadNewPortalBall(Gear, true);
  4363             loadNewPortalBall(Gear, true);
  4319     end
  4364     end
  4320 
  4365 
  4321     else if (y > cWaterLine)
  4366     else if CheckCoordInWater(x, y)
  4322     or (y < -max(LAND_WIDTH,4096))
  4367     or (y < -max(LAND_WIDTH,4096))
  4323     or (x > 2*max(LAND_WIDTH,4096))
  4368     or (x > 2*max(LAND_WIDTH,4096))
  4324     or (x < -max(LAND_WIDTH,4096)) then
  4369     or (x < -max(LAND_WIDTH,4096)) then
  4325         loadNewPortalBall(Gear, true);
  4370         loadNewPortalBall(Gear, true);
  4326 end;
  4371 end;
  4556             Gear^.Damage := 0;
  4601             Gear^.Damage := 0;
  4557             Gear^.Health := 0;
  4602             Gear^.Health := 0;
  4558             end
  4603             end
  4559         else
  4604         else
  4560             begin
  4605             begin
  4561             if (rY <= cWaterLine) or (y <= cWaterLine) then
  4606             if CheckCoordInWater(rX, rY) or CheckCoordInWater(x, y) then
  4562                 begin
  4607                 begin
  4563                 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0)
  4608                 if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0)
  4564                     and (Land[y, x] <> 0) then
  4609                     and (Land[y, x] <> 0) then
  4565                         begin
  4610                         begin
  4566                         if ((GameFlags and gfSolidLand) <> 0) and (Land[y, x] > 255) then
  4611                         if ((GameFlags and gfSolidLand) <> 0) and (Land[y, x] > 255) then
  4943         end
  4988         end
  4944     else
  4989     else
  4945         begin
  4990         begin
  4946         //Gear^.dY := Gear^.dY + cGravity;
  4991         //Gear^.dY := Gear^.dY + cGravity;
  4947         //Gear^.Y := Gear^.Y + Gear^.dY;
  4992         //Gear^.Y := Gear^.Y + Gear^.dY;
  4948         if hwRound(Gear^.Y) > cWaterLine then
  4993         if CheckCoordInWater(hwRound(Gear^.X), hwRound(Gear^.Y)) then
  4949             Gear^.Timer := 1
  4994             Gear^.Timer := 1
  4950         end;
  4995         end;
  4951 
  4996 
  4952     //Gear^.X := Gear^.X + HitGear^.dX;
  4997     //Gear^.X := Gear^.X + HitGear^.dX;
  4953     HitGear^.X := Gear^.X;
  4998     HitGear^.X := Gear^.X;