hedgewars/uGearsHandlersMess.pas
changeset 15717 9060532c25f7
parent 15716 d5fce8a02092
child 15718 83c950393d7a
equal deleted inserted replaced
15716:d5fce8a02092 15717:9060532c25f7
  7284         ClearGlobalHitOrderLeq(Gear^.Karma);
  7284         ClearGlobalHitOrderLeq(Gear^.Karma);
  7285         Gear^.Karma := 0;
  7285         Gear^.Karma := 0;
  7286     end;
  7286     end;
  7287 end;
  7287 end;
  7288 
  7288 
       
  7289 function CheckSentryDestroyed(Sentry: PGear; damagedState: LongInt): Boolean;
       
  7290 begin
       
  7291     CheckSentryDestroyed := false;
       
  7292     if Sentry^.Damage > 0 then
       
  7293     begin
       
  7294         dec(Sentry^.Health, Sentry^.Damage);
       
  7295         Sentry^.Damage := 0;
       
  7296         if Sentry^.Health <= 0 then
       
  7297         begin
       
  7298             doMakeExplosion(hwRound(Sentry^.X), hwRound(Sentry^.Y), Sentry^.Boom, Sentry^.Hedgehog, EXPLAutoSound);
       
  7299             DeleteGear(Sentry);
       
  7300             CheckSentryDestroyed := true;
       
  7301             exit;
       
  7302         end
       
  7303         else
       
  7304             ResetSentryState(Sentry, damagedState, 10000)
       
  7305     end;
       
  7306 
       
  7307     if ((Sentry^.Health * 100) < random(cSentryHealth * 90)) and ((GameTicks and $FF) = 0) then
       
  7308         if Sentry^.Health * 2 < cSentryHealth then
       
  7309             AddVisualGear(hwRound(Sentry^.X) - 8 + Random(16), hwRound(Sentry^.Y) - 2, vgtSmoke)
       
  7310         else
       
  7311             AddVisualGear(hwRound(Sentry^.X) - 8 + Random(16), hwRound(Sentry^.Y) - 2, vgtSmokeWhite);
       
  7312 end;
       
  7313 
       
  7314 procedure AimSentry(Sentry: PGear);
       
  7315 var HHGear: PGear;
       
  7316 begin
       
  7317     if CurrentHedgehog <> nil then
       
  7318     begin
       
  7319         HHGear := CurrentHedgehog^.Gear;
       
  7320         if HHGear <> nil then
       
  7321         begin
       
  7322             Sentry^.Target.X := Sentry^.Target.X + hwSign(HHGear^.X - int2hwFloat(Sentry^.Target.X));
       
  7323             Sentry^.Target.Y := Sentry^.Target.Y + hwSign(HHGear^.Y - int2hwFloat(Sentry^.Target.Y));
       
  7324         end;
       
  7325     end;
       
  7326 end;
       
  7327 
       
  7328 procedure MakeSentryShot(Sentry: PGear);
       
  7329 var bullet: PGear;
       
  7330     distX, distY, invDistance: HwFloat;
       
  7331 begin
       
  7332     distX := int2hwFloat(Sentry^.Target.X) - Sentry^.X;
       
  7333     distY := int2hwFloat(Sentry^.Target.Y) - Sentry^.Y;
       
  7334     invDistance := _1 / Distance(distX, distY);
       
  7335     distX := distX * invDistance;
       
  7336     distY := distY * invDistance;
       
  7337 
       
  7338     bullet := AddGear(
       
  7339         hwRound(Sentry^.X), hwRound(Sentry^.Y),
       
  7340         gtMinigunBullet, 0,
       
  7341         distX * _0_9 + rndSign(getRandomf * _0_1),
       
  7342         distY * _0_9 + rndSign(getRandomf * _0_1),
       
  7343         0);
       
  7344 
       
  7345     bullet^.Karma := 12;
       
  7346     bullet^.Pos := 1;
       
  7347     bullet^.WDTimer := GameTicks;
       
  7348     bullet^.PortalCounter := 1;
       
  7349     bullet^.Elasticity := Sentry^.X;
       
  7350     bullet^.Friction := Sentry^.Y;
       
  7351     bullet^.Data := Pointer(Sentry);
       
  7352 
       
  7353     CreateShellForGear(Sentry, Sentry^.WDTimer and 1);
       
  7354     PlaySound(sndGun);
       
  7355 end;
       
  7356 
  7289 procedure doStepSentryLand(Gear: PGear);
  7357 procedure doStepSentryLand(Gear: PGear);
  7290 var HHGear, bullet: PGear;
  7358 var HHGear: PGear;
  7291     distX, distY, invDistance: HwFloat;
       
  7292 const sentry_Idle = 0;
  7359 const sentry_Idle = 0;
  7293     sentry_Walking = 1;
  7360     sentry_Walking = 1;
  7294     sentry_Aiming = 2;
  7361     sentry_Aiming = 2;
  7295     sentry_Attacking = 3;
  7362     sentry_Attacking = 3;
  7296     sentry_Reloading = 4;
  7363     sentry_Reloading = 4;
  7298     HHGear:= nil;
  7365     HHGear:= nil;
  7299 
  7366 
  7300     if CheckGearDrowning(Gear) then
  7367     if CheckGearDrowning(Gear) then
  7301         exit;
  7368         exit;
  7302 
  7369 
  7303     if Gear^.Damage > 0 then
  7370     if CheckSentryDestroyed(Gear, sentry_Reloading) then
  7304     begin
  7371         exit;
  7305         dec(Gear^.Health, Gear^.Damage);
       
  7306         Gear^.Damage := 0;
       
  7307         if Gear^.Health <= 0 then
       
  7308         begin
       
  7309             doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), Gear^.Boom, Gear^.Hedgehog, EXPLAutoSound);
       
  7310             DeleteGear(Gear);
       
  7311             exit;
       
  7312         end;
       
  7313 
       
  7314         ResetSentryState(Gear, sentry_Reloading, 10000)
       
  7315     end;
       
  7316 
       
  7317     if ((Gear^.Health * 100) < random(cSentryHealth * 90)) and ((GameTicks and $FF) = 0) then
       
  7318         if Gear^.Health * 2 < cSentryHealth then
       
  7319             AddVisualGear(hwRound(Gear^.X) - 8 + Random(16), hwRound(Gear^.Y) - 2, vgtSmoke)
       
  7320         else
       
  7321             AddVisualGear(hwRound(Gear^.X) - 8 + Random(16), hwRound(Gear^.Y) - 2, vgtSmokeWhite);
       
  7322 
  7372 
  7323     if Gear^.dY.isNegative or (TestCollisionYwithGear(Gear, 1) = 0) then
  7373     if Gear^.dY.isNegative or (TestCollisionYwithGear(Gear, 1) = 0) then
  7324     begin
  7374     begin
  7325         doStepFallingGear(Gear);
  7375         doStepFallingGear(Gear);
  7326         if not (Gear^.Tag in [sentry_Idle, sentry_Reloading]) then
  7376         if not (Gear^.Tag in [sentry_Idle, sentry_Reloading]) then
  7394                 Gear^.Timer := 5000;
  7444                 Gear^.Timer := 5000;
  7395             end
  7445             end
  7396         end
  7446         end
  7397         else if Gear^.Tag = sentry_Attacking then
  7447         else if Gear^.Tag = sentry_Attacking then
  7398         begin
  7448         begin
  7399             distX := int2hwFloat(Gear^.Target.X) - Gear^.X;
  7449             MakeSentryShot(Gear);
  7400             distY := int2hwFloat(Gear^.Target.Y) - Gear^.Y;
       
  7401             invDistance := _1 / Distance(distX, distY);
       
  7402             distX := distX * invDistance;
       
  7403             distY := distY * invDistance;
       
  7404 
       
  7405             bullet := AddGear(
       
  7406                 hwRound(Gear^.X), hwRound(Gear^.Y),
       
  7407                 gtMinigunBullet, 0,
       
  7408                 distX * _0_9 + rndSign(getRandomf * _0_1),
       
  7409                 distY * _0_9 + rndSign(getRandomf * _0_1),
       
  7410                 0);
       
  7411 
       
  7412             bullet^.Karma := 12;
       
  7413             bullet^.Pos := 1;
       
  7414             bullet^.WDTimer := GameTicks;
       
  7415             bullet^.PortalCounter := 1;
       
  7416             bullet^.Elasticity := Gear^.X;
       
  7417             bullet^.Friction := Gear^.Y;
       
  7418             bullet^.Data := Pointer(Gear);
       
  7419 
       
  7420             CreateShellForGear(Gear, Gear^.WDTimer and 1);
       
  7421             PlaySound(sndGun);
       
  7422 
  7450 
  7423             if Gear^.WDTimer = 0 then
  7451             if Gear^.WDTimer = 0 then
  7424             begin
  7452                 ResetSentryState(Gear, sentry_Reloading, 6000 + GetRandom(2000))
  7425                 Gear^.Target.X := 0;
       
  7426                 Gear^.Target.Y := 0;
       
  7427                 ClearGlobalHitOrderLeq(Gear^.Karma);
       
  7428                 Gear^.Karma := 0;
       
  7429                 Gear^.Tag := sentry_Reloading;
       
  7430                 Gear^.Timer := 6000 + GetRandom(2000);
       
  7431             end
       
  7432             else
  7453             else
  7433             begin
  7454             begin
  7434                 dec(Gear^.WDTimer);
  7455                 dec(Gear^.WDTimer);
  7435                 Gear^.Timer := 100;
  7456                 Gear^.Timer := 100;
  7436             end
  7457             end
  7441     begin
  7462     begin
  7442         if not MakeSentryStep(Gear, 6, false) then
  7463         if not MakeSentryStep(Gear, 6, false) then
  7443             Gear^.Timer := 0
  7464             Gear^.Timer := 0
  7444     end;
  7465     end;
  7445 
  7466 
  7446     if ((GameTicks and $1F) = 0)
  7467     if ((GameTicks and $1F) = 0) and (Gear^.Tag = sentry_Aiming) then
  7447         and (Gear^.Tag = sentry_Aiming)
  7468         AimSentry(Gear);
  7448         and (CurrentHedgehog <> nil)
       
  7449         and (CurrentHedgehog^.Gear <> nil) then
       
  7450     begin
       
  7451         HHGear := CurrentHedgehog^.Gear;
       
  7452         Gear^.Target.X := Gear^.Target.X + hwSign(HHGear^.X - int2hwFloat(Gear^.Target.X));
       
  7453         Gear^.Target.Y := Gear^.Target.Y + hwSign(HHGear^.Y - int2hwFloat(Gear^.Target.Y));
       
  7454     end;
       
  7455 
  7469 
  7456     if ((GameTicks and $FF) = 0)
  7470     if ((GameTicks and $FF) = 0)
  7457         and (Gear^.Tag in [sentry_Idle, sentry_Walking])
  7471         and (Gear^.Tag in [sentry_Idle, sentry_Walking])
  7458         and (CurrentHedgehog <> nil)
  7472         and (CurrentHedgehog <> nil)
  7459         and (CurrentHedgehog^.Gear <> nil)
  7473         and (CurrentHedgehog^.Gear <> nil)
  7470         end
  7484         end
  7471     end
  7485     end
  7472 end;
  7486 end;
  7473 
  7487 
  7474 procedure doStepSentryWater(Gear: PGear);
  7488 procedure doStepSentryWater(Gear: PGear);
       
  7489 var HHGear: PGear;
       
  7490 const sentry_Idle = 0;
       
  7491     sentry_Walking = 1;
       
  7492     sentry_Aiming = 2;
       
  7493     sentry_Attacking = 3;
       
  7494     sentry_Reloading = 4;
  7475 begin
  7495 begin
  7476     if Gear^.Tag < 0 then
  7496     if Gear^.Tag < 0 then
  7477     begin
  7497     begin
  7478         CheckGearDrowning(Gear);
  7498         CheckGearDrowning(Gear);
  7479         exit;
  7499         exit;
  7483     if TestCollisionYwithGear(Gear, -1) <> 0 then
  7503     if TestCollisionYwithGear(Gear, -1) <> 0 then
  7484     begin
  7504     begin
  7485         Gear^.Tag := -1;
  7505         Gear^.Tag := -1;
  7486         exit;
  7506         exit;
  7487     end;
  7507     end;
       
  7508 
       
  7509     if CheckSentryDestroyed(Gear, sentry_Reloading) then
       
  7510         exit;
       
  7511 
       
  7512     if Gear^.Timer > 0 then dec(Gear^.Timer);
       
  7513 
       
  7514     if Gear^.Timer = 0 then
       
  7515     begin
       
  7516         if Gear^.Tag = sentry_Idle then
       
  7517         begin
       
  7518             Gear^.Tag := sentry_Walking;
       
  7519             Gear^.Timer := 3000 + GetRandom(3000);
       
  7520             Gear^.dX.isNegative := GetRandom(2) = 1;
       
  7521             if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) <> 0 then
       
  7522                 Gear^.dX.isNegative := not Gear^.dX.isNegative;
       
  7523         end
       
  7524         else if Gear^.Tag in [sentry_Walking, sentry_Reloading] then
       
  7525         begin
       
  7526             Gear^.Tag := sentry_Idle;
       
  7527             Gear^.Timer := 1000 + GetRandom(1000);
       
  7528         end
       
  7529         else if Gear^.Tag = sentry_Aiming then
       
  7530         begin
       
  7531             if CheckSentryAttackRange(Gear, int2hwFloat(Gear^.Target.X), int2hwFloat(Gear^.Target.Y)) then
       
  7532             begin
       
  7533                 Gear^.WDTimer := 5 + GetRandom(3);
       
  7534                 Gear^.Tag := sentry_Attacking;
       
  7535                 Gear^.Timer := 100;
       
  7536             end
       
  7537             else
       
  7538             begin
       
  7539                 Gear^.Target.X := 0;
       
  7540                 Gear^.Target.Y := 0;
       
  7541                 Gear^.Tag := sentry_Idle;
       
  7542                 Gear^.Timer := 5000;
       
  7543             end
       
  7544         end
       
  7545         else if Gear^.Tag = sentry_Attacking then
       
  7546         begin
       
  7547             MakeSentryShot(Gear);
       
  7548 
       
  7549             if Gear^.WDTimer = 0 then
       
  7550                 ResetSentryState(Gear, sentry_Reloading, 6000 + GetRandom(2000))
       
  7551             else
       
  7552             begin
       
  7553                 dec(Gear^.WDTimer);
       
  7554                 Gear^.Timer := 100;
       
  7555             end
       
  7556         end;
       
  7557     end;
       
  7558 
       
  7559     if (Gear^.Tag = sentry_Walking) and ((GameTicks and $1F) = 0) then
       
  7560     begin
       
  7561         if TestCollisionXwithGear(Gear, hwSign(Gear^.dX)) = 0 then
       
  7562             Gear^.X := Gear^.X + SignAs(_1, Gear^.dX)
       
  7563         else
       
  7564             Gear^.Timer := 0
       
  7565     end;
       
  7566 
       
  7567     if ((GameTicks and $1F) = 0) and (Gear^.Tag = sentry_Aiming) then
       
  7568         AimSentry(Gear);
       
  7569 
       
  7570     if ((GameTicks and $FF) = 0)
       
  7571         and (Gear^.Tag in [sentry_Idle, sentry_Walking])
       
  7572         and (CurrentHedgehog <> nil)
       
  7573         and (CurrentHedgehog^.Gear <> nil)
       
  7574         and ((CurrentHedgehog^.Gear^.State and (gstMoving or gstHHDriven)) = (gstMoving or gstHHDriven)) then
       
  7575     begin
       
  7576         HHGear := CurrentHedgehog^.Gear;
       
  7577         if CheckSentryAttackRange(Gear, HHGear^.X, HHGear^.Y) then
       
  7578         begin
       
  7579             Gear^.Target.X := hwRound(HHGear^.X);
       
  7580             Gear^.Target.Y := hwRound(HHGear^.Y);
       
  7581             Gear^.Karma := GameTicks;
       
  7582             Gear^.Tag := sentry_Aiming;
       
  7583             Gear^.Timer := 1800 + GetRandom(400);
       
  7584         end
       
  7585     end
  7488 end;
  7586 end;
  7489 
  7587 
  7490 procedure doStepSentryDeploy(Gear: PGear);
  7588 procedure doStepSentryDeploy(Gear: PGear);
  7491 begin
  7589 begin
  7492     Gear^.Tag := -1;
  7590     Gear^.Tag := -1;