Spaces:
Sleeping
Sleeping
| /** | |
| * @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); | |
| } | |
| } | |