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) |
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; |