hedgewars/GSHandlers.inc
branchhedgeroid
changeset 6328 d14adf1c7721
parent 6325 cdd3d8c723ec
child 6368 cd819d9df6f6
equal deleted inserted replaced
6236:1998ff75321a 6328:d14adf1c7721
   383         if (GameFlags and gfMoreWind) <> 0 then Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density
   383         if (GameFlags and gfMoreWind) <> 0 then Gear^.dX := Gear^.dX + cWindSpeed / Gear^.Density
   384         end;
   384         end;
   385 
   385 
   386     Gear^.X := Gear^.X + Gear^.dX;
   386     Gear^.X := Gear^.X + Gear^.dX;
   387     Gear^.Y := Gear^.Y + Gear^.dY;
   387     Gear^.Y := Gear^.Y + Gear^.dY;
   388     CheckGearDrowning(Gear);
   388     if Gear^.Kind <> gtBee then
       
   389         CheckGearDrowning(Gear);
   389     //if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_0002) and
   390     //if (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) < _0_0002) and
   390     if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_02.QWordValue) and
   391     if ((Gear^.dX.QWordValue + Gear^.dY.QWordValue) < _0_02.QWordValue) and
   391        (not isFalling) then
   392        (not isFalling) then
   392         Gear^.State := Gear^.State and not gstMoving
   393         Gear^.State := Gear^.State and not gstMoving
   393     else
   394     else
   839 ////////////////////////////////////////////////////////////////////////////////
   840 ////////////////////////////////////////////////////////////////////////////////
   840 procedure doStepBeeWork(Gear: PGear);
   841 procedure doStepBeeWork(Gear: PGear);
   841 var 
   842 var 
   842     t: hwFloat;
   843     t: hwFloat;
   843     gX,gY,i: LongInt;
   844     gX,gY,i: LongInt;
   844     nuw: boolean;
   845     uw, nuw: boolean;
   845     flower: PVisualGear;
   846     flower: PVisualGear;
   846 
   847 
   847 const uw: boolean =   false;
       
   848 begin
   848 begin
   849     AllInactive := false;
   849     AllInactive := false;
   850     gX := hwRound(Gear^.X);
   850     gX := hwRound(Gear^.X);
   851     gY := hwRound(Gear^.Y);
   851     gY := hwRound(Gear^.Y);
   852     nuw := (cWaterLine < gy + Gear^.Radius);
   852     uw := (Gear^.Tag <> 0); // was bee underwater last tick?
   853     if nuw and not uw then
   853     nuw := (cWaterLine < gy + Gear^.Radius); // is bee underwater now?
       
   854 
       
   855     // if water entered or left
       
   856     if nuw <> uw then
   854     begin
   857     begin
   855         AddVisualGear(gX, cWaterLine, vgtSplash);
   858         AddVisualGear(gX, cWaterLine, vgtSplash);
   856         AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
   859         AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
   857         AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
   860         AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
   858         AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
   861         AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
   859         AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
   862         AddVisualGear(gX - 3 + Random(6), cWaterLine, vgtDroplet);
   860         StopSound(Gear^.SoundChannel);
   863         StopSound(Gear^.SoundChannel);
   861         Gear^.SoundChannel := LoopSound(sndBeeWater);
   864         if nuw then
   862         uw := nuw
   865         begin
   863     end
   866             Gear^.SoundChannel := LoopSound(sndBeeWater);
   864     else if not nuw and uw then
   867             Gear^.Tag := 1;
   865         begin
   868         end
   866             AddVisualGear(gX, cWaterLine, vgtSplash);
   869         else
   867             StopSound(Gear^.SoundChannel);
   870         begin
   868             Gear^.SoundChannel := LoopSound(sndBee);
   871             Gear^.SoundChannel := LoopSound(sndBee);
   869             uw := nuw
   872             Gear^.Tag := 0;
   870         end;
   873         end;
   871 
   874     end;
   872 
   875 
   873     if (GameTicks and $F) = 0 then
   876 
   874     begin
   877     if Gear^.Timer = 0 then
   875         if (GameTicks and $30) = 0 then
   878         Gear^.RenderTimer:= false
   876             AddVisualGear(gX, gY, vgtBeeTrace);
   879     else
   877         Gear^.dX := Gear^.Elasticity * (Gear^.dX + _0_000064 * (Gear^.Target.X - gX));
   880     begin
   878         Gear^.dY := Gear^.Elasticity * (Gear^.dY + _0_000064 * (Gear^.Target.Y - gY));
   881         if (GameTicks and $F) = 0 then
   879         // make sure new speed isn't higher than original one (which we stored in Friction variable)
   882         begin
   880         t := Gear^.Friction / Distance(Gear^.dX, Gear^.dY);
   883             if (GameTicks and $30) = 0 then
   881         Gear^.dX := Gear^.dX * t;
   884                 AddVisualGear(gX, gY, vgtBeeTrace);
   882         Gear^.dY := Gear^.dY * t;
   885             Gear^.dX := Gear^.Elasticity * (Gear^.dX + _0_000064 * (Gear^.Target.X - gX));
   883     end;
   886             Gear^.dY := Gear^.Elasticity * (Gear^.dY + _0_000064 * (Gear^.Target.Y - gY));
   884 
   887             // make sure new speed isn't higher than original one (which we stored in Friction variable)
   885     Gear^.X := Gear^.X + Gear^.dX;
   888             t := Gear^.Friction / Distance(Gear^.dX, Gear^.dY);
   886     Gear^.Y := Gear^.Y + Gear^.dY;
   889             Gear^.dX := Gear^.dX * t;
       
   890             Gear^.dY := Gear^.dY * t;
       
   891         end;
       
   892 
       
   893         Gear^.X := Gear^.X + Gear^.dX;
       
   894         Gear^.Y := Gear^.Y + Gear^.dY;
       
   895 
       
   896     end;
       
   897 
   887 
   898 
   888     CheckCollision(Gear);
   899     CheckCollision(Gear);
   889     dec(Gear^.Timer);
   900     if ((Gear^.State and gstCollision) <> 0) then
   890     if ((Gear^.State and gstCollision) <> 0) or (Gear^.Timer = 0) then
       
   891     begin
   901     begin
   892         StopSound(Gear^.SoundChannel);
   902         StopSound(Gear^.SoundChannel);
   893         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
   903         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 50, Gear^.Hedgehog, EXPLAutoSound);
   894         for i:= 0 to 31 do
   904         for i:= 0 to 31 do
   895             begin
   905             begin
   905                     FrameTicks:= random(250) + 250;
   915                     FrameTicks:= random(250) + 250;
   906                     State:= ord(sprTargetBee);
   916                     State:= ord(sprTargetBee);
   907                     end;
   917                     end;
   908             end;
   918             end;
   909         DeleteGear(Gear);
   919         DeleteGear(Gear);
       
   920     end;
       
   921 
       
   922     if (Gear^.Timer > 0) then
       
   923         dec(Gear^.Timer)
       
   924     else
       
   925     begin
       
   926         if nuw then
       
   927         begin
       
   928             StopSound(Gear^.SoundChannel);
       
   929             CheckGearDrowning(Gear);
       
   930         end
       
   931         else
       
   932             doStepFallingGear(Gear);
   910     end;
   933     end;
   911 end;
   934 end;
   912 
   935 
   913 procedure doStepBee(Gear: PGear);
   936 procedure doStepBee(Gear: PGear);
   914 begin
   937 begin
  1260             begin
  1283             begin
  1261             DrawExplosion(i, y + 3, 3);
  1284             DrawExplosion(i, y + 3, 3);
  1262             inc(i, 1)
  1285             inc(i, 1)
  1263             end;
  1286             end;
  1264 
  1287 
  1265         if CheckLandValue(hwRound(Gear^.X + Gear^.dX + SignAs(_6,Gear^.dX)), hwRound(Gear^.Y + _1_9)
  1288         if CheckLandValue(hwRound(Gear^.X + Gear^.dX + SignAs(_6,Gear^.dX)), hwRound(Gear^.Y + _1_9), lfIndestructible) then
  1266            , lfIndestructible) then
       
  1267             begin
  1289             begin
  1268             Gear^.X := Gear^.X + Gear^.dX;
  1290             Gear^.X := Gear^.X + Gear^.dX;
  1269             Gear^.Y := Gear^.Y + _1_9;
  1291             Gear^.Y := Gear^.Y + _1_9;
  1270             end;
  1292             end;
  1271         SetAllHHToActive;
  1293         SetAllHHToActive;
  1276         SetLittle(HHGear^.dX);
  1298         SetLittle(HHGear^.dX);
  1277         HHGear^.dY := _0;
  1299         HHGear^.dY := _0;
  1278         end
  1300         end
  1279     else
  1301     else
  1280         begin
  1302         begin
  1281         Gear^.dY := Gear^.dY + cGravity;
  1303         if CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y + Gear^.dY + cGravity), lfIndestructible) then
  1282         Gear^.Y := Gear^.Y + Gear^.dY;
  1304             begin
       
  1305             Gear^.dY := Gear^.dY + cGravity;
       
  1306             Gear^.Y := Gear^.Y + Gear^.dY
       
  1307             end;
  1283         if hwRound(Gear^.Y) > cWaterLine then Gear^.Timer := 1
  1308         if hwRound(Gear^.Y) > cWaterLine then Gear^.Timer := 1
  1284         end;
  1309         end;
  1285 
  1310 
  1286     Gear^.X := Gear^.X + HHGear^.dX;
  1311     Gear^.X := Gear^.X + HHGear^.dX;
  1287     HHGear^.X := Gear^.X;
  1312     if CheckLandValue(hwRound(Gear^.X), hwRound(Gear^.Y)-cHHRadius, lfIndestructible) then
  1288     HHGear^.Y := Gear^.Y - int2hwFloat(cHHRadius);
  1313         begin
       
  1314         HHGear^.X := Gear^.X;
       
  1315         HHGear^.Y := Gear^.Y - int2hwFloat(cHHRadius)
       
  1316         end;
  1289 
  1317 
  1290     if (Gear^.Message and gmAttack) <> 0 then
  1318     if (Gear^.Message and gmAttack) <> 0 then
  1291         if (Gear^.State and gsttmpFlag) <> 0 then Gear^.Timer := 1
  1319         if (Gear^.State and gsttmpFlag) <> 0 then Gear^.Timer := 1
  1292     else
  1320     else
  1293     else
  1321     else
  1399             HHGear^.State := HHGear^.State and not gstNoDamage
  1427             HHGear^.State := HHGear^.State and not gstNoDamage
  1400             end;
  1428             end;
  1401         end;
  1429         end;
  1402 
  1430 
  1403     if b then
  1431     if b then
  1404         DrawTunnel(HHGear^.X - Gear^.dX * cHHRadius, HHGear^.Y - _4 - Gear^.dY * cHHRadius + hwAbs(
  1432     begin
  1405                    Gear^.dY) * 7,
  1433         DrawTunnel(HHGear^.X + Gear^.dX * cHHRadius,
       
  1434         HHGear^.Y + Gear^.dY * cHHRadius - _1 -
       
  1435         ((hwAbs(Gear^.dX) / (hwAbs(Gear^.dX) + hwAbs(Gear^.dY))) * _0_5 * 7),
  1406         Gear^.dX, Gear^.dY,
  1436         Gear^.dX, Gear^.dY,
  1407         cHHRadius * 5, cHHRadius * 2 + 7);
  1437         cHHStepTicks, cHHRadius * 2 + 7);
       
  1438     end;
  1408 
  1439 
  1409     if (TurnTimeLeft = 0) or (Gear^.Timer = 0) or ((HHGear^.Message and gmAttack) <> 0) then
  1440     if (TurnTimeLeft = 0) or (Gear^.Timer = 0) or ((HHGear^.Message and gmAttack) <> 0) then
  1410         begin
  1441         begin
  1411         HHGear^.Message := 0;
  1442         HHGear^.Message := 0;
  1412         HHGear^.State := HHGear^.State and (not gstNotKickable);
  1443         HHGear^.State := HHGear^.State and (not gstNotKickable);
  3621     HHGear^.State := HHGear^.State or gstMoving;
  3652     HHGear^.State := HHGear^.State or gstMoving;
  3622 
  3653 
  3623     Gear^.X := HHGear^.X;
  3654     Gear^.X := HHGear^.X;
  3624     Gear^.Y := HHGear^.Y;
  3655     Gear^.Y := HHGear^.Y;
  3625     // For some reason I need to reapply followgear here, something else grabs it otherwise.
  3656     // For some reason I need to reapply followgear here, something else grabs it otherwise.
  3626     if not bShowAmmoMenu and not CurrentTeam^.ExtDriven then FollowGear := HHGear;
  3657     // This is probably not needed anymore
       
  3658     if not CurrentTeam^.ExtDriven then FollowGear := HHGear;
  3627 
  3659 
  3628     if not isUnderWater and hasBorder and ((HHGear^.X < _0) or (hwRound(HHGear^.X) > LAND_WIDTH)) then HHGear^.dY.isNegative:= false;
  3660     if not isUnderWater and hasBorder and ((HHGear^.X < _0) or (hwRound(HHGear^.X) > LAND_WIDTH)) then HHGear^.dY.isNegative:= false;
  3629     if ((Gear^.State and gsttmpFlag) = 0) or (HHGear^.dY < _0) then doStepHedgehogMoving(HHGear);
  3661     if ((Gear^.State and gsttmpFlag) = 0) or (HHGear^.dY < _0) then doStepHedgehogMoving(HHGear);
  3630 
  3662 
  3631     if // (Gear^.Health = 0)
  3663     if // (Gear^.Health = 0)
  3752     HHGear^.State := HHGear^.State or gstMoving;
  3784     HHGear^.State := HHGear^.State or gstMoving;
  3753 
  3785 
  3754     Gear^.X := HHGear^.X;
  3786     Gear^.X := HHGear^.X;
  3755     Gear^.Y := HHGear^.Y - int2hwFloat(32);
  3787     Gear^.Y := HHGear^.Y - int2hwFloat(32);
  3756     // For some reason I need to reapply followgear here, something else grabs it otherwise.
  3788     // For some reason I need to reapply followgear here, something else grabs it otherwise.
  3757     if not bShowAmmoMenu then FollowGear := HHGear;
  3789     // this is probably not needed anymore
       
  3790     if not CurrentTeam^.ExtDriven then FollowGear := HHGear;
  3758 
  3791 
  3759     if ((Gear^.State and gsttmpFlag) = 0) or (HHGear^.dY < _0) then doStepHedgehogMoving(HHGear);
  3792     if ((Gear^.State and gsttmpFlag) = 0) or (HHGear^.dY < _0) then doStepHedgehogMoving(HHGear);
  3760 
  3793 
  3761     if  (Gear^.Health = 0)
  3794     if  (Gear^.Health = 0)
  3762        or (HHGear^.Damage <> 0)
  3795        or (HHGear^.Damage <> 0)
  4375 var 
  4408 var 
  4376     r0, r1: LongInt;
  4409     r0, r1: LongInt;
  4377     odY: hwFloat;
  4410     odY: hwFloat;
  4378 begin
  4411 begin
  4379     AllInactive := false;
  4412     AllInactive := false;
  4380     if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and ((CurrentHedgehog^.Gear^.
  4413     if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) and 
  4381        Message and gmSlot) <> 0) then
  4414        ((CurrentHedgehog^.Gear^.Message and gmSlot) <> 0) then
  4382     begin
  4415         begin
  4383         case CurrentHedgehog^.Gear^.MsgParam of 
  4416         case CurrentHedgehog^.Gear^.MsgParam of 
  4384             0: PlaySound(sndPiano0);
  4417             0: PlaySound(sndPiano0);
  4385             1: PlaySound(sndPiano1);
  4418             1: PlaySound(sndPiano1);
  4386             2: PlaySound(sndPiano2);
  4419             2: PlaySound(sndPiano2);
  4387             3: PlaySound(sndPiano3);
  4420             3: PlaySound(sndPiano3);
  4392             else PlaySound(sndPiano8);
  4425             else PlaySound(sndPiano8);
  4393         end;
  4426         end;
  4394         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtNote);
  4427         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtNote);
  4395         CurrentHedgehog^.Gear^.MsgParam := 0;
  4428         CurrentHedgehog^.Gear^.MsgParam := 0;
  4396         CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and not gmSlot;
  4429         CurrentHedgehog^.Gear^.Message := CurrentHedgehog^.Gear^.Message and not gmSlot;
  4397     end;
  4430         end;
  4398 
  4431 
  4399     if (*((Gear^.Pos = 3) and ((GameFlags and gfSolidLand) <> 0)) or*) (Gear^.Pos = 5) then
  4432     if (*((Gear^.Pos = 3) and ((GameFlags and gfSolidLand) <> 0)) or*) (Gear^.Pos = 5) then
  4400         // bounce up to 10 times (3 times on gameflagged solid land) before dropping past landscape
  4433         begin
  4401     begin
       
  4402         Gear^.dY := Gear^.dY + cGravity * 2;
  4434         Gear^.dY := Gear^.dY + cGravity * 2;
  4403         Gear^.Y := Gear^.Y + Gear^.dY;
  4435         Gear^.Y := Gear^.Y + Gear^.dY;
  4404         CheckGearDrowning(Gear);
  4436         CheckGearDrowning(Gear);
  4405         if (Gear^.State and gstDrowning) <> 0 then
  4437         if (Gear^.State and gstDrowning) <> 0 then
  4406         begin
  4438             begin
       
  4439             OnUsedAmmo(CurrentHedgehog^);
  4407             if CurrentHedgehog^.Gear <> nil then
  4440             if CurrentHedgehog^.Gear <> nil then
  4408             begin
  4441                 begin
  4409                 // Drown the hedgehog.  Could also just delete it, but hey, this gets a caption
  4442                 // Drown the hedgehog.  Could also just delete it, but hey, this gets a caption
  4410                 CurrentHedgehog^.Gear^.Active := true;
  4443                 CurrentHedgehog^.Gear^.Active := true;
  4411                 CurrentHedgehog^.Gear^.X := Gear^.X;
  4444                 CurrentHedgehog^.Gear^.X := Gear^.X;
  4412                 CurrentHedgehog^.Gear^.Y := int2hwFloat(cWaterLine+cVisibleWater)+_128;
  4445                 CurrentHedgehog^.Gear^.Y := int2hwFloat(cWaterLine+cVisibleWater)+_128;
  4413                 CurrentHedgehog^.Unplaced := false;
  4446                 CurrentHedgehog^.Unplaced := false;
  4414                 if TagTurnTimeLeft = 0 then TagTurnTimeLeft:= TurnTimeLeft;
  4447                 if TagTurnTimeLeft = 0 then TagTurnTimeLeft:= TurnTimeLeft;
  4415                 TurnTimeLeft:= 0
  4448                 TurnTimeLeft:= 0
  4416             end;
  4449                 end;
  4417             ResumeMusic
  4450             ResumeMusic
  4418         end;
  4451             end;
  4419         exit
  4452         exit
  4420     end;
  4453         end;
  4421 
  4454 
  4422     odY:= Gear^.dY;
  4455     odY:= Gear^.dY;
  4423     doStepFallingGear(Gear);
  4456     doStepFallingGear(Gear);
  4424 
  4457 
  4425     if (Gear^.State and gstDrowning) <> 0 then
  4458     if (Gear^.State and gstDrowning) <> 0 then
  4426     begin
  4459         begin
       
  4460         OnUsedAmmo(CurrentHedgehog^);
  4427         if CurrentHedgehog^.Gear <> nil then
  4461         if CurrentHedgehog^.Gear <> nil then
  4428         begin
  4462             begin
  4429             // Drown the hedgehog.  Could also just delete it, but hey, this gets a caption
  4463             // Drown the hedgehog.  Could also just delete it, but hey, this gets a caption
  4430             CurrentHedgehog^.Gear^.Active := true;
  4464             CurrentHedgehog^.Gear^.Active := true;
  4431             CurrentHedgehog^.Gear^.X := Gear^.X;
  4465             CurrentHedgehog^.Gear^.X := Gear^.X;
  4432             CurrentHedgehog^.Gear^.Y := int2hwFloat(cWaterLine+cVisibleWater)+_128;
  4466             CurrentHedgehog^.Gear^.Y := int2hwFloat(cWaterLine+cVisibleWater)+_128;
  4433             CurrentHedgehog^.Unplaced := false;
  4467             CurrentHedgehog^.Unplaced := false;
  4434             if TagTurnTimeLeft = 0 then TagTurnTimeLeft:= TurnTimeLeft;
  4468             if TagTurnTimeLeft = 0 then TagTurnTimeLeft:= TurnTimeLeft;
  4435             TurnTimeLeft:= 0
  4469             TurnTimeLeft:= 0
  4436         end;
  4470             end;
  4437         ResumeMusic
  4471         ResumeMusic
  4438     end
  4472         end
  4439     else if (Gear^.State and gstCollision) <> 0 then
  4473     else if (Gear^.State and gstCollision) <> 0 then
  4440         begin
  4474         begin
  4441             r0 := GetRandom(21);
  4475         r0 := GetRandom(21);
  4442             r1 := GetRandom(21);
  4476         r1 := GetRandom(21);
  4443             doMakeExplosion(hwRound(Gear^.X) - 30 - r0, hwRound(Gear^.Y) + 40, 40 + r1, Gear^.Hedgehog, 0);
  4477         doMakeExplosion(hwRound(Gear^.X) - 30 - r0, hwRound(Gear^.Y) + 40, 40 + r1, Gear^.Hedgehog, 0);
  4444             doMakeExplosion(hwRound(Gear^.X) + 30 + r1, hwRound(Gear^.Y) + 40, 40 + r0, Gear^.Hedgehog, 0);
  4478         doMakeExplosion(hwRound(Gear^.X) + 30 + r1, hwRound(Gear^.Y) + 40, 40 + r0, Gear^.Hedgehog, 0);
  4445             doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 80 + r0, Gear^.Hedgehog, EXPLAutoSound);
  4479         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 80 + r0, Gear^.Hedgehog, EXPLAutoSound);
  4446             for r0:= 0 to 4 do
  4480         for r0:= 0 to 4 do
  4447                 AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtNote);
  4481             AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtNote);
  4448             Gear^.dY := odY * -1 + cGravity * 2;
  4482         Gear^.dY := odY * -1 + cGravity * 2;
  4449             Gear^.Pos := Gear^.Pos + 1;
  4483         Gear^.Pos := Gear^.Pos + 1;
  4450         end
  4484         end
  4451     else
  4485     else
  4452         Gear^.dY := Gear^.dY + cGravity * 2;
  4486         Gear^.dY := Gear^.dY + cGravity * 2;
  4453     // let it fall faster so itdoesn't take too long for the whole attack
  4487     // let it fall faster so itdoesn't take too long for the whole attack
  4454 end;
  4488 end;