hedgewars/GSHandlers.inc
branchhedgeroid
changeset 5644 4ad07103cfae
parent 5628 a9a0c67f9656
child 5638 e35ba2a400d8
equal deleted inserted replaced
5641:06558ee35f51 5644:4ad07103cfae
   356         Gear^.State := Gear^.State or      gstMoving;
   356         Gear^.State := Gear^.State or      gstMoving;
   357 
   357 
   358     if (Gear^.nImpactSounds > 0) and 
   358     if (Gear^.nImpactSounds > 0) and 
   359        ((Gear^.Damage <> 0) or 
   359        ((Gear^.Damage <> 0) or 
   360           ((Gear^.State and (gstCollision or gstMoving)) = (gstCollision or gstMoving))) and
   360           ((Gear^.State and (gstCollision or gstMoving)) = (gstCollision or gstMoving))) and
   361        ((Gear^.dX.QWordValue > _0_1.QWordValue) or 
   361        (((Gear^.Radius < 3) and (Gear^.dY < -_0_1)) or
   362           (Gear^.dY.QWordValue > _0_1.QWordValue)) then
   362         ((Gear^.Radius >= 3) and ((Gear^.dX.QWordValue > _0_1.QWordValue) or 
       
   363           (Gear^.dY.QWordValue > _0_1.QWordValue)))) then
   363         PlaySound(TSound(ord(Gear^.ImpactSound) + LongInt(GetRandom(Gear^.nImpactSounds))), true);
   364         PlaySound(TSound(ord(Gear^.ImpactSound) + LongInt(GetRandom(Gear^.nImpactSounds))), true);
   364 end;
   365 end;
   365 
   366 
   366 ////////////////////////////////////////////////////////////////////////////////
   367 ////////////////////////////////////////////////////////////////////////////////
   367 procedure doStepBomb(Gear: PGear);
   368 procedure doStepBomb(Gear: PGear);
   792 
   793 
   793     if (GameTicks and $F) = 0 then
   794     if (GameTicks and $F) = 0 then
   794     begin
   795     begin
   795         if (GameTicks and $30) = 0 then
   796         if (GameTicks and $30) = 0 then
   796             AddVisualGear(gX, gY, vgtBeeTrace);
   797             AddVisualGear(gX, gY, vgtBeeTrace);
   797         Gear^.dX := Gear^.Elasticity * (Gear^.dX + _0_000064 * (Gear^.TargetX - gX));
   798         Gear^.dX := Gear^.Elasticity * (Gear^.dX + _0_000064 * (Gear^.Target.X - gX));
   798         Gear^.dY := Gear^.Elasticity * (Gear^.dY + _0_000064 * (Gear^.TargetY - gY));
   799         Gear^.dY := Gear^.Elasticity * (Gear^.dY + _0_000064 * (Gear^.Target.Y - gY));
   799         // make sure new speed isn't higher than original one (which we stored in Friction variable)
   800         // make sure new speed isn't higher than original one (which we stored in Friction variable)
   800         t := Gear^.Friction / Distance(Gear^.dX, Gear^.dY);
   801         t := Gear^.Friction / Distance(Gear^.dX, Gear^.dY);
   801         Gear^.dX := Gear^.dX * t;
   802         Gear^.dX := Gear^.dX * t;
   802         Gear^.dY := Gear^.dY * t;
   803         Gear^.dY := Gear^.dY * t;
   803     end;
   804     end;
  2370 begin
  2371 begin
  2371     AllInactive := false;
  2372     AllInactive := false;
  2372     Gear^.X := Gear^.X + cAirPlaneSpeed * Gear^.Tag;
  2373     Gear^.X := Gear^.X + cAirPlaneSpeed * Gear^.Tag;
  2373 
  2374 
  2374     if (Gear^.Health > 0)and(not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then
  2375     if (Gear^.Health > 0)and(not (Gear^.X < Gear^.dX))and(Gear^.X < Gear^.dX + cAirPlaneSpeed) then
  2375     begin
  2376         begin
  2376         dec(Gear^.Health);
  2377         dec(Gear^.Health);
  2377         case Gear^.State of 
  2378         case Gear^.State of 
  2378             0: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed *
  2379             0: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtAirBomb, 0, cBombsSpeed *
  2379                              Gear^.Tag, _0, 0);
  2380                              Gear^.Tag, _0, 0);
  2380             1: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine,    0, cBombsSpeed *
  2381             1: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtMine,    0, cBombsSpeed *
  2383                              Gear^.Tag, _0, 0);
  2384                              Gear^.Tag, _0, 0);
  2384             3: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtDrill, gsttmpFlag, cBombsSpeed *
  2385             3: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtDrill, gsttmpFlag, cBombsSpeed *
  2385                              Gear^.Tag, _0, Gear^.Timer + 1);
  2386                              Gear^.Tag, _0, Gear^.Timer + 1);
  2386             //4: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtWaterMelon, 0, cBombsSpeed *
  2387             //4: FollowGear := AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtWaterMelon, 0, cBombsSpeed *
  2387             //                 Gear^.Tag, _0, 5000);
  2388             //                 Gear^.Tag, _0, 5000);
  2388         end;
  2389             end;
  2389         Gear^.dX := Gear^.dX + int2hwFloat(30 * Gear^.Tag);
  2390         Gear^.dX := Gear^.dX + int2hwFloat(30 * Gear^.Tag);
  2390         StopSound(Gear^.SoundChannel, 4000);
  2391         StopSound(Gear^.SoundChannel, 4000);
  2391     end;
  2392         end;
  2392 
  2393 
  2393     if (GameTicks and $3F) = 0 then
  2394     if (GameTicks and $3F) = 0 then
  2394         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace);
  2395         AddVisualGear(hwRound(Gear^.X), hwRound(Gear^.Y), vgtSmokeTrace);
  2395 
  2396 
  2396     if (hwRound(Gear^.X) > (LAND_WIDTH+2048)) or (hwRound(Gear^.X) < -2048) then
  2397     if (hwRound(Gear^.X) > (LAND_WIDTH+2048)) or (hwRound(Gear^.X) < -2048) then
  2415         Gear^.Tag := -1;
  2416         Gear^.Tag := -1;
  2416         Gear^.X := int2hwFloat(LAND_WIDTH + 2048);
  2417         Gear^.X := int2hwFloat(LAND_WIDTH + 2048);
  2417     end;
  2418     end;
  2418 
  2419 
  2419     Gear^.Y := int2hwFloat(topY-300);
  2420     Gear^.Y := int2hwFloat(topY-300);
  2420     Gear^.dX := int2hwFloat(Gear^.TargetX - 5 * Gear^.Tag * 15);
  2421     Gear^.dX := int2hwFloat(Gear^.Target.X - 5 * Gear^.Tag * 15);
  2421 
  2422 
  2422     // calcs for Napalm Strike, so that it will hit the target (without wind at least :P)
  2423     // calcs for Napalm Strike, so that it will hit the target (without wind at least :P)
  2423     if (Gear^.State = 2) then
  2424     if (Gear^.State = 2) then
  2424         Gear^.dX := Gear^.dX - cBombsSpeed * Gear^.Tag * 900 
  2425         Gear^.dX := Gear^.dX - cBombsSpeed * Gear^.Tag * 900 
  2425     // calcs for regular falling gears
  2426     // calcs for regular falling gears
  2426     else if (int2hwFloat(Gear^.TargetY) - Gear^.Y > _0) then
  2427     else if (int2hwFloat(Gear^.Target.Y) - Gear^.Y > _0) then
  2427             Gear^.dX := Gear^.dX - cBombsSpeed * hwSqrt((int2hwFloat(Gear^.TargetY) - Gear^.Y) * 2 /
  2428             Gear^.dX := Gear^.dX - cBombsSpeed * hwSqrt((int2hwFloat(Gear^.Target.Y) - Gear^.Y) * 2 /
  2428                 cGravity) * Gear^.Tag;
  2429                 cGravity) * Gear^.Tag;
  2429 
  2430 
  2430     Gear^.Health := 6;
  2431     Gear^.Health := 6;
  2431     Gear^.doStep := @doStepAirAttackWork;
  2432     Gear^.doStep := @doStepAirAttackWork;
  2432     Gear^.SoundChannel := LoopSound(sndPlane, 4000);
  2433     Gear^.SoundChannel := LoopSound(sndPlane, 4000);
  2458     x, y, tx, ty: hwFloat;
  2459     x, y, tx, ty: hwFloat;
  2459 begin
  2460 begin
  2460     AllInactive := false;
  2461     AllInactive := false;
  2461 
  2462 
  2462     HHGear := Gear^.Hedgehog^.Gear;
  2463     HHGear := Gear^.Hedgehog^.Gear;
  2463     tx := int2hwFloat(Gear^.TargetX);
  2464     tx := int2hwFloat(Gear^.Target.X);
  2464     ty := int2hwFloat(Gear^.TargetY);
  2465     ty := int2hwFloat(Gear^.Target.Y);
  2465     x := HHGear^.X;
  2466     x := HHGear^.X;
  2466     y := HHGear^.Y;
  2467     y := HHGear^.Y;
  2467 
  2468 
  2468     if (Distance(tx - x, ty - y) > _256) or
  2469     if (Distance(tx - x, ty - y) > _256) or
  2469        not TryPlaceOnLand(Gear^.TargetX - SpritesData[sprAmGirder].Width div 2,
  2470        not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprAmGirder].Width div 2,
  2470        Gear^.TargetY - SpritesData[sprAmGirder].Height div 2,
  2471        Gear^.Target.Y - SpritesData[sprAmGirder].Height div 2,
  2471        sprAmGirder, Gear^.State, true, false) then
  2472        sprAmGirder, Gear^.State, true, false) then
  2472     begin
  2473     begin
  2473         PlaySound(sndDenied);
  2474         PlaySound(sndDenied);
  2474         HHGear^.Message := HHGear^.Message and not gmAttack;
  2475         HHGear^.Message := HHGear^.Message and not gmAttack;
  2475         HHGear^.State := HHGear^.State and not gstAttacking;
  2476         HHGear^.State := HHGear^.State and not gstAttacking;
  2524     HHGear: PGear;
  2525     HHGear: PGear;
  2525 begin
  2526 begin
  2526     AllInactive := false;
  2527     AllInactive := false;
  2527 
  2528 
  2528     HHGear := Gear^.Hedgehog^.Gear;
  2529     HHGear := Gear^.Hedgehog^.Gear;
  2529     if not TryPlaceOnLand(Gear^.TargetX - SpritesData[sprHHTelepMask].Width div 2,
  2530     if not TryPlaceOnLand(Gear^.Target.X - SpritesData[sprHHTelepMask].Width div 2,
  2530        Gear^.TargetY - SpritesData[sprHHTelepMask].Height div 2,
  2531        Gear^.Target.Y - SpritesData[sprHHTelepMask].Height div 2,
  2531        sprHHTelepMask, 0, false, false) then
  2532        sprHHTelepMask, 0, false, false) then
  2532     begin
  2533     begin
  2533         HHGear^.Message := HHGear^.Message and not gmAttack;
  2534         HHGear^.Message := HHGear^.Message and not gmAttack;
  2534         HHGear^.State := HHGear^.State and not gstAttacking;
  2535         HHGear^.State := HHGear^.State and not gstAttacking;
  2535         HHGear^.State := HHGear^.State or gstHHChooseTarget;
  2536         HHGear^.State := HHGear^.State or gstHHChooseTarget;
  2547         Gear^.dX := HHGear^.dX;
  2548         Gear^.dX := HHGear^.dX;
  2548         // retrieve the cursor direction (it was previously copied to X so it doesn't get lost)
  2549         // retrieve the cursor direction (it was previously copied to X so it doesn't get lost)
  2549         HHGear^.dX.isNegative := (Gear^.X.QWordValue <> 0);
  2550         HHGear^.dX.isNegative := (Gear^.X.QWordValue <> 0);
  2550         Gear^.X := HHGear^.X;
  2551         Gear^.X := HHGear^.X;
  2551         Gear^.Y := HHGear^.Y;
  2552         Gear^.Y := HHGear^.Y;
  2552         HHGear^.X := int2hwFloat(Gear^.TargetX);
  2553         HHGear^.X := int2hwFloat(Gear^.Target.X);
  2553         HHGear^.Y := int2hwFloat(Gear^.TargetY);
  2554         HHGear^.Y := int2hwFloat(Gear^.Target.Y);
  2554         HHGear^.State := HHGear^.State or gstMoving;
  2555         HHGear^.State := HHGear^.State or gstMoving;
  2555         playSound(sndWarp)
  2556         playSound(sndWarp)
  2556     end;
  2557     end;
  2557     Gear^.TargetX:= NoPointX
  2558     Gear^.Target.X:= NoPointX
  2558 end;
  2559 end;
  2559 
  2560 
  2560 ////////////////////////////////////////////////////////////////////////////////
  2561 ////////////////////////////////////////////////////////////////////////////////
  2561 procedure doStepSwitcherWork(Gear: PGear);
  2562 procedure doStepSwitcherWork(Gear: PGear);
  2562 var 
  2563 var 
  4579 while i > 0 do
  4580 while i > 0 do
  4580     begin
  4581     begin
  4581     dec(i);
  4582     dec(i);
  4582     tmp:= t^.ar[i];
  4583     tmp:= t^.ar[i];
  4583     if (tmp^.State and gstNoDamage) = 0 then
  4584     if (tmp^.State and gstNoDamage) = 0 then
  4584         if (tmp^.Kind = gtHedgehog) then
  4585         if (tmp^.Kind = gtHedgehog) or (tmp^.Kind = gtMine) or (tmp^.Kind = gtExplosives) then
  4585             begin
  4586             begin
  4586             //tmp^.State:= tmp^.State or gstFlatened;
  4587             //tmp^.State:= tmp^.State or gstFlatened;
  4587             ApplyDamage(tmp, CurrentHedgehog, tmp^.Health div 3, dsUnknown);
  4588             ApplyDamage(tmp, CurrentHedgehog, tmp^.Health div 3, dsUnknown);
  4588             //DrawTunnel(tmp^.X, tmp^.Y - _1, _0, _0_5, cHHRadius * 6, cHHRadius * 3);
  4589             //DrawTunnel(tmp^.X, tmp^.Y - _1, _0, _0_5, cHHRadius * 6, cHHRadius * 3);
  4589             tmp2:= AddGear(hwRound(tmp^.X), hwRound(tmp^.Y), gtHammerHit, 0, _0, _0, 0);
  4590             tmp2:= AddGear(hwRound(tmp^.X), hwRound(tmp^.Y), gtHammerHit, 0, _0, _0, 0);
  4590             tmp2^.Hedgehog:= tmp^.Hedgehog;
  4591             tmp2^.IntersectGear:= tmp;
  4591             SetAllToActive
  4592             SetAllToActive
  4592             end
  4593             end
  4593         else
  4594         else
  4594             begin
  4595             begin
  4595             end
  4596             end
  4600 Gear^.doStep:= @doStepIdle
  4601 Gear^.doStep:= @doStepIdle
  4601 end;
  4602 end;
  4602 
  4603 
  4603 procedure doStepHammerHitWork(Gear: PGear);
  4604 procedure doStepHammerHitWork(Gear: PGear);
  4604 var 
  4605 var 
  4605     i, ei: LongInt;
  4606     i, j, ei: LongInt;
  4606     HHGear: PGear;
  4607     HitGear: PGear;
  4607 begin
  4608 begin
  4608     AllInactive := false;
  4609     AllInactive := false;
  4609     HHGear := Gear^.Hedgehog^.Gear;
  4610     HitGear := Gear^.IntersectGear;
  4610     dec(Gear^.Timer);
  4611     dec(Gear^.Timer);
  4611     if (HHGear = nil) or (Gear^.Timer = 0) or ((Gear^.Message and gmDestroy) <> 0) then
  4612     if (HitGear = nil) or (Gear^.Timer = 0) or ((Gear^.Message and gmDestroy) <> 0) then
  4612     begin
  4613         begin
  4613         DeleteGear(Gear);
  4614         DeleteGear(Gear);
  4614         exit
  4615         exit
  4615     end;
  4616         end;
  4616 
  4617 
  4617     if (Gear^.Timer mod 5) = 0 then
  4618     if (Gear^.Timer mod 5) = 0 then
  4618     begin
  4619         begin
  4619         AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
  4620         AddVisualGear(hwRound(Gear^.X) - 5 + Random(10), hwRound(Gear^.Y) + 12, vgtDust);
  4620 
  4621 
  4621         i := hwRound(Gear^.X) - Gear^.Radius - LongInt(GetRandom(2));
  4622         i := hwRound(Gear^.X) - HitGear^.Radius + 2;
  4622         ei := hwRound(Gear^.X) + Gear^.Radius + LongInt(GetRandom(2));
  4623         ei := hwRound(Gear^.X) + HitGear^.Radius - 2;
       
  4624         for j := 1 to 4 do DrawExplosion(i - GetRandom(5), hwRound(Gear^.Y) + 6*j, 3);
       
  4625         for j := 1 to 4 do DrawExplosion(ei + GetRandom(5), hwRound(Gear^.Y) + 6*j, 3);
  4623         while i <= ei do
  4626         while i <= ei do
  4624         begin
  4627             begin
  4625             DrawExplosion(i, hwRound(Gear^.Y) + 3, 3);
  4628             for j := 1 to 11 do DrawExplosion(i, hwRound(Gear^.Y) + 3*j, 3);
  4626             inc(i, 1)
  4629             inc(i, 1)
  4627         end;
  4630             end;
  4628 
  4631 
  4629         if CheckLandValue(hwRound(Gear^.X + Gear^.dX + SignAs(_6,Gear^.dX)), hwRound(Gear^.Y + _1_9)
  4632         if CheckLandValue(hwRound(Gear^.X + Gear^.dX + SignAs(_6,Gear^.dX)), hwRound(Gear^.Y + _1_9)
  4630            , lfIndestructible) then
  4633            , lfIndestructible) then
  4631         begin
  4634             begin
  4632             Gear^.X := Gear^.X + Gear^.dX;
  4635             Gear^.X := Gear^.X + Gear^.dX;
  4633             Gear^.Y := Gear^.Y + _1_9;
  4636             Gear^.Y := Gear^.Y + _1_9;
  4634         end;
  4637             end;
  4635         SetAllHHToActive;
  4638         end;
  4636     end;
       
  4637     if TestCollisionYwithGear(Gear, 1) then
  4639     if TestCollisionYwithGear(Gear, 1) then
  4638     begin
  4640         begin
  4639         Gear^.dY := _0;
  4641         Gear^.dY := _0;
  4640         SetLittle(HHGear^.dX);
  4642         SetLittle(HitGear^.dX);
  4641         HHGear^.dY := _0;
  4643         HitGear^.dY := _0;
  4642     end
  4644         end
  4643     else
  4645     else
  4644     begin
  4646         begin
  4645         Gear^.dY := Gear^.dY + cGravity;
  4647         Gear^.dY := Gear^.dY + cGravity;
  4646         Gear^.Y := Gear^.Y + Gear^.dY;
  4648         Gear^.Y := Gear^.Y + Gear^.dY;
  4647         if hwRound(Gear^.Y) > cWaterLine then Gear^.Timer := 1
  4649         if hwRound(Gear^.Y) > cWaterLine then Gear^.Timer := 1
  4648     end;
  4650         end;
  4649 
  4651 
  4650     Gear^.X := Gear^.X + HHGear^.dX;
  4652     Gear^.X := Gear^.X + HitGear^.dX;
  4651     HHGear^.X := Gear^.X;
  4653     HitGear^.X := Gear^.X;
  4652     HHGear^.Y := Gear^.Y - int2hwFloat(cHHRadius);
  4654     SetLittle(HitGear^.dY);
       
  4655     HitGear^.Active:= true;
  4653 end;
  4656 end;
  4654 
  4657 
  4655 procedure doStepHammerHit(Gear: PGear);
  4658 procedure doStepHammerHit(Gear: PGear);
  4656 var 
  4659 var 
  4657     i, y: LongInt;
  4660     i, y: LongInt;