airframe.io / src /game /multiplayer /RoomLifecycle.ts
LATTICEWORKS's picture
feat: integrate Google Earth 3D Tiles and optimize engine hooks
565f6e7
Raw
History Blame Contribute Delete
4.67 kB
import { Client } from "@colyseus/core";
import { Pilot } from "../../types";
import { DEFAULT_AIRCRAFT } from "../aircraftData";
import { getVoxelDef } from "../content/aircraft/voxelRegistry";
import { buildVoxelGrid } from "../voxelMesh";
import { NetworkPlayer } from "./MatchState";
import { getAirSpawnPosition, getSpawnYaw, createEmptyDamage, initAmmo } from "./RoomUtils";
import { Quaternion, Euler } from "three";
import RAPIER from "@dimforge/rapier3d-compat";
import { getPlaneHitRadius } from "../math";
import { AmmoBelt } from "../../types";
export class RoomLifecycle {
public onJoin(
client: Client,
options: any,
authData: any,
assignedTeam: number,
mapId: string,
pilots: Map<string, Pilot>,
statePlayers: any,
serverTick: number,
broadcast: (type: string, msg: any) => void,
rapierWorld: RAPIER.World,
rigidBodies: Map<string, RAPIER.RigidBody>,
colliders: Map<string, RAPIER.Collider>,
playerVoxelGrids: Map<string, any>,
evictBot: (team: number) => void
) {
const planeId = options.aircraftId || authData.selectedPlaneId || "falcon-mk2";
const skin = options.skin || authData.customizations?.skin || "default";
evictBot(assignedTeam);
const specs = DEFAULT_AIRCRAFT.find(a => a.id === planeId) || DEFAULT_AIRCRAFT[0];
const spawnPos = getAirSpawnPosition(assignedTeam as 1 | 2, mapId);
const q = new Quaternion().setFromEuler(new Euler(0, getSpawnYaw(assignedTeam), 0, "YXZ"));
const player = new Pilot({
id: client.sessionId,
name: authData.nickname || "Maverick",
isBot: false,
team: assignedTeam as 1 | 2,
aircraftId: planeId,
specs,
x: spawnPos.x, y: spawnPos.y, z: spawnPos.z,
vx: spawnPos.vx, vy: spawnPos.vy, vz: spawnPos.vz,
qx: q.x, qy: q.y, qz: q.z, qw: q.w,
throttle: 0.8,
engineTemperature: 75,
damage: createEmptyDamage(),
ammo: initAmmo(specs),
ammoBelt: authData.selectedBelt || AmmoBelt.Universal,
modifications: authData.equippedMods?.[planeId] || [],
score: 0, kills: 0, deaths: 0,
weaponCooldowns: {},
invulnerableTimer: 2.0
});
pilots.set(client.sessionId, player);
const bodyDesc = RAPIER.RigidBodyDesc.kinematicPositionBased()
.setTranslation(spawnPos.x, spawnPos.y, spawnPos.z)
.setUserData({ playerId: client.sessionId });
const body = rapierWorld.createRigidBody(bodyDesc);
const colliderDesc = RAPIER.ColliderDesc.ball(getPlaneHitRadius(specs) + 3.2);
const collider = rapierWorld.createCollider(colliderDesc, body);
rigidBodies.set(client.sessionId, body);
colliders.set(client.sessionId, collider);
const voxDef = getVoxelDef(planeId);
if (voxDef) playerVoxelGrids.set(client.sessionId, buildVoxelGrid(voxDef));
const netPlayer = new NetworkPlayer();
netPlayer.id = client.sessionId;
netPlayer.name = player.name;
netPlayer.team = assignedTeam;
netPlayer.aircraftId = planeId;
netPlayer.skin = skin;
netPlayer.score = 0;
netPlayer.kills = 0;
netPlayer.deaths = 0;
netPlayer.isBot = false;
statePlayers.set(client.sessionId, netPlayer);
client.send("welcome", { assignedId: client.sessionId, assignedTeam, tick: serverTick });
broadcast("player_joined", { id: client.sessionId, name: player.name, team: assignedTeam });
}
public respawnPilot(
pilotId: string,
pilots: Map<string, Pilot>,
mapId: string,
playerVoxelGrids: Map<string, any>,
broadcast: (type: string, msg: any) => void
) {
const pilot = pilots.get(pilotId);
if (!pilot) return;
const spawnPos = getAirSpawnPosition(pilot.team as 1 | 2, mapId);
pilot.x = spawnPos.x; pilot.y = spawnPos.y; pilot.z = spawnPos.z;
pilot.vx = spawnPos.vx; pilot.vy = spawnPos.vy; pilot.vz = spawnPos.vz;
const q = new Quaternion().setFromEuler(new Euler(0, getSpawnYaw(pilot.team), 0, "YXZ"));
pilot.qx = q.x; pilot.qy = q.y; pilot.qz = q.z; pilot.qw = q.w;
pilot.throttle = 0.8;
const destrComp = pilot.entity.components.get("destructible") as any;
destrComp.hp = 100;
destrComp.isDead = false;
destrComp.damageModel = createEmptyDamage();
const wepComp = pilot.entity.components.get("weaponized") as any;
wepComp.ammo = initAmmo(pilot.specs);
wepComp.cooldowns = {};
pilot.invulnerableTimer = 2.0;
const voxDef = getVoxelDef(pilot.aircraftId);
if (voxDef) playerVoxelGrids.set(pilotId, buildVoxelGrid(voxDef));
broadcast("pilot_respawned", { id: pilotId, x: spawnPos.x, y: spawnPos.y, z: spawnPos.z, yaw: getSpawnYaw(pilot.team) });
}
}