File size: 2,371 Bytes
e4ffbe5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/**
 * @license
 * SPDX-License-Identifier: Apache-2.0
 */

import { Vector3 } from "three";
import { Pilot, GroundTarget, Projectile, WeaponType, AmmoBelt } from "../types";
import { generateId } from "./math";

export class GroundDefenseSystem {
  public static updateGroundDefense(
    dt: number,
    groundTargets: GroundTarget[],
    pilots: Pilot[],
    projectiles: Projectile[],
    isMultiplayer: boolean,
    isHost: boolean
  ) {
    if (isMultiplayer && !isHost) {
      return;
    }

    groundTargets.forEach(t => {
      if (t.isDead || t.type !== "anti-air") return;

      if (t.fireCooldown !== undefined) {
        t.fireCooldown = Math.max(0, t.fireCooldown - dt);

        if (t.fireCooldown <= 0) {
          const opposingTeam = t.team === 1 ? 2 : 1;
          const targetsInSky = pilots.filter(
            p => p.team === opposingTeam && p.damage.fuselage > 0
          );

          let lockedPlane: Pilot | null = null;
          let minDist = 1300;

          targetsInSky.forEach(p => {
            const d = new Vector3(t.x, t.y, t.z).distanceTo(
              new Vector3(p.x, p.y, p.z)
            );

            if (d < minDist) {
              minDist = d;
              lockedPlane = p;
            }
          });

          if (lockedPlane) {
            this.spawnAABullet(t, lockedPlane, projectiles);
            t.fireCooldown = 1.0 + Math.random() * 1.5;
          }
        }
      }
    });

    groundTargets.forEach(t => {
      if (t.isDead || t.type !== "convoy") return;

      const spd = t.team === 1 ? 4.5 : -4.5;
      t.x += spd * dt;
    });
  }

  private static spawnAABullet(aa: GroundTarget, target: Pilot, projectiles: Projectile[]) {
    const startPos = new Vector3(aa.x, aa.y + 6, aa.z);
    const tarPos = new Vector3(
      target.x,
      target.y + (Math.random() - 0.5) * 50,
      target.z
    );

    const dir = tarPos.clone().sub(startPos).normalize();
    const bulletSpeed = 550;

    const projectile: Projectile = {
      id: generateId(),
      ownerId: aa.id,
      ownerTeam: aa.team,
      type: WeaponType.MG_7_7,
      belt: AmmoBelt.Tracer,
      x: startPos.x,
      y: startPos.y,
      z: startPos.z,
      vx: dir.x * bulletSpeed,
      vy: dir.y * bulletSpeed,
      vz: dir.z * bulletSpeed,
      life: 2.5,
      isRocket: false
    };

    projectiles.push(projectile);
  }
}