mirror of
https://github.com/exogen/t2-mapper.git
synced 2026-03-13 17:30:56 +00:00
begin live server support
This commit is contained in:
parent
0c9ddb476a
commit
e4ae265184
368 changed files with 17756 additions and 7738 deletions
185
src/stream/entityBridge.ts
Normal file
185
src/stream/entityBridge.ts
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
import type { StreamEntity } from "./types";
|
||||
import type {
|
||||
GameEntity,
|
||||
ShapeEntity,
|
||||
PlayerEntity,
|
||||
ForceFieldBareEntity,
|
||||
ExplosionEntity,
|
||||
TracerEntity,
|
||||
SpriteEntity,
|
||||
AudioEmitterEntity,
|
||||
CameraEntity,
|
||||
WayPointEntity,
|
||||
} from "../state/gameEntityTypes";
|
||||
import type { SceneTSStatic } from "../scene/types";
|
||||
|
||||
/** Common fields extracted from a StreamEntity for positioned game entities. */
|
||||
function positionedBase(entity: StreamEntity, spawnTime?: number) {
|
||||
return {
|
||||
id: entity.id,
|
||||
className: entity.className ?? entity.type,
|
||||
ghostIndex: entity.ghostIndex,
|
||||
dataBlockId: entity.dataBlockId,
|
||||
shapeHint: entity.shapeHint,
|
||||
spawnTime,
|
||||
position: entity.position,
|
||||
rotation: entity.rotation,
|
||||
velocity: entity.velocity,
|
||||
keyframes: [
|
||||
{
|
||||
time: spawnTime ?? 0,
|
||||
position: entity.position ?? [0, 0, 0] as [number, number, number],
|
||||
rotation: entity.rotation ?? [0, 0, 0, 1] as [number, number, number, number],
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
/** Convert a StreamEntity to a GameEntity for the entity store. */
|
||||
export function streamEntityToGameEntity(
|
||||
entity: StreamEntity,
|
||||
spawnTime?: number,
|
||||
): GameEntity {
|
||||
// Scene infrastructure — routed from sceneData
|
||||
if (entity.sceneData) {
|
||||
const base = {
|
||||
id: entity.id,
|
||||
className: entity.className ?? entity.type,
|
||||
ghostIndex: entity.ghostIndex,
|
||||
dataBlockId: entity.dataBlockId,
|
||||
shapeHint: entity.shapeHint,
|
||||
spawnTime,
|
||||
};
|
||||
switch (entity.sceneData.className) {
|
||||
case "TerrainBlock":
|
||||
return { ...base, renderType: "TerrainBlock", terrainData: entity.sceneData };
|
||||
case "InteriorInstance":
|
||||
return { ...base, renderType: "InteriorInstance", interiorData: entity.sceneData };
|
||||
case "Sky":
|
||||
return { ...base, renderType: "Sky", skyData: entity.sceneData };
|
||||
case "Sun":
|
||||
return { ...base, renderType: "Sun", sunData: entity.sceneData };
|
||||
case "WaterBlock":
|
||||
return { ...base, renderType: "WaterBlock", waterData: entity.sceneData };
|
||||
case "MissionArea":
|
||||
return { ...base, renderType: "MissionArea", missionAreaData: entity.sceneData };
|
||||
case "TSStatic":
|
||||
// TSStatic is rendered as a shape — extract shapeName from scene data.
|
||||
return {
|
||||
...positionedBase(entity, spawnTime),
|
||||
renderType: "Shape",
|
||||
shapeName: (entity.sceneData as SceneTSStatic).shapeName,
|
||||
shapeType: "TSStatic",
|
||||
dataBlock: entity.dataBlock,
|
||||
} satisfies ShapeEntity;
|
||||
}
|
||||
}
|
||||
|
||||
// Projectile visuals
|
||||
if (entity.visual?.kind === "tracer") {
|
||||
return {
|
||||
...positionedBase(entity, spawnTime),
|
||||
renderType: "Tracer",
|
||||
visual: entity.visual,
|
||||
dataBlock: entity.dataBlock,
|
||||
direction: entity.direction,
|
||||
} satisfies TracerEntity;
|
||||
}
|
||||
if (entity.visual?.kind === "sprite") {
|
||||
return {
|
||||
...positionedBase(entity, spawnTime),
|
||||
renderType: "Sprite",
|
||||
visual: entity.visual,
|
||||
} satisfies SpriteEntity;
|
||||
}
|
||||
|
||||
// Player
|
||||
if (entity.type === "Player") {
|
||||
return {
|
||||
...positionedBase(entity, spawnTime),
|
||||
renderType: "Player",
|
||||
shapeName: entity.dataBlock,
|
||||
dataBlock: entity.dataBlock,
|
||||
weaponShape: entity.weaponShape,
|
||||
playerName: entity.playerName,
|
||||
iffColor: entity.iffColor,
|
||||
threads: entity.threads,
|
||||
weaponImageState: entity.weaponImageState,
|
||||
weaponImageStates: entity.weaponImageStates,
|
||||
headPitch: entity.headPitch,
|
||||
headYaw: entity.headYaw,
|
||||
targetRenderFlags: entity.targetRenderFlags,
|
||||
} satisfies PlayerEntity;
|
||||
}
|
||||
|
||||
// Explosion
|
||||
if (entity.type === "Explosion") {
|
||||
return {
|
||||
...positionedBase(entity, spawnTime),
|
||||
renderType: "Explosion",
|
||||
shapeName: entity.dataBlock,
|
||||
dataBlock: entity.dataBlock,
|
||||
explosionDataBlockId: entity.explosionDataBlockId,
|
||||
faceViewer: entity.faceViewer,
|
||||
} satisfies ExplosionEntity;
|
||||
}
|
||||
|
||||
// Force field
|
||||
if (entity.className === "ForceFieldBare") {
|
||||
return {
|
||||
...positionedBase(entity, spawnTime),
|
||||
renderType: "ForceFieldBare",
|
||||
} satisfies ForceFieldBareEntity;
|
||||
}
|
||||
|
||||
// Audio emitter
|
||||
if (entity.className === "AudioEmitter") {
|
||||
return {
|
||||
...positionedBase(entity, spawnTime),
|
||||
renderType: "AudioEmitter",
|
||||
audioFileName: entity.audioFileName,
|
||||
audioVolume: entity.audioVolume,
|
||||
audioIs3D: entity.audioIs3D,
|
||||
audioIsLooping: entity.audioIsLooping ?? true,
|
||||
audioMinDistance: entity.audioMinDistance,
|
||||
audioMaxDistance: entity.audioMaxDistance,
|
||||
audioMinLoopGap: entity.audioMinLoopGap,
|
||||
audioMaxLoopGap: entity.audioMaxLoopGap,
|
||||
} satisfies AudioEmitterEntity;
|
||||
}
|
||||
|
||||
// WayPoint
|
||||
if (entity.className === "WayPoint") {
|
||||
return {
|
||||
...positionedBase(entity, spawnTime),
|
||||
renderType: "WayPoint",
|
||||
label: entity.label,
|
||||
} satisfies WayPointEntity;
|
||||
}
|
||||
|
||||
// Camera
|
||||
if (entity.className === "Camera") {
|
||||
return {
|
||||
...positionedBase(entity, spawnTime),
|
||||
renderType: "Camera",
|
||||
} satisfies CameraEntity;
|
||||
}
|
||||
|
||||
// Default: generic DTS shape
|
||||
return {
|
||||
...positionedBase(entity, spawnTime),
|
||||
renderType: "Shape",
|
||||
shapeName: entity.dataBlock,
|
||||
shapeType:
|
||||
entity.className === "Turret"
|
||||
? "Turret"
|
||||
: entity.className === "Item"
|
||||
? "Item"
|
||||
: "StaticShape",
|
||||
dataBlock: entity.dataBlock,
|
||||
weaponShape: entity.weaponShape,
|
||||
threads: entity.threads,
|
||||
targetRenderFlags: entity.targetRenderFlags,
|
||||
iffColor: entity.iffColor,
|
||||
} satisfies ShapeEntity;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue