Reverts to the state of cbfacdf (split app.js into 21 modules, <1000 lines each).
Removes: nostr.js, nostr-panel.js, SovOS.js, RESEARCH_DROP_456.md, core/, data/
Historical archive preserved in .historical/ and branch archive/manus-damage-2026-03-24
Refs #418, #452, #454
66 lines
2.1 KiB
JavaScript
66 lines
2.1 KiB
JavaScript
// === PORTALS ===
|
|
import * as THREE from 'three';
|
|
import { scene } from './scene-setup.js';
|
|
import { rebuildRuneRing, setPortalsRef } from './effects.js';
|
|
import { setPortalsRefAudio, startPortalHums } from './audio.js';
|
|
import { S } from './state.js';
|
|
|
|
export const portalGroup = new THREE.Group();
|
|
scene.add(portalGroup);
|
|
|
|
export let portals = [];
|
|
|
|
function createPortals() {
|
|
const portalGeo = new THREE.TorusGeometry(3.0, 0.2, 16, 100);
|
|
|
|
portals.forEach(portal => {
|
|
const isOnline = portal.status === 'online';
|
|
|
|
const portalMat = new THREE.MeshBasicMaterial({
|
|
color: new THREE.Color(portal.color).convertSRGBToLinear(),
|
|
transparent: true,
|
|
opacity: isOnline ? 0.7 : 0.15,
|
|
blending: THREE.AdditiveBlending,
|
|
side: THREE.DoubleSide,
|
|
});
|
|
|
|
const portalMesh = new THREE.Mesh(portalGeo, portalMat);
|
|
|
|
portalMesh.position.set(portal.position.x, portal.position.y + 0.5, portal.position.z);
|
|
portalMesh.rotation.y = portal.rotation.y;
|
|
portalMesh.rotation.x = Math.PI / 2;
|
|
|
|
portalMesh.name = `portal-${portal.id}`;
|
|
portalMesh.userData.destinationUrl = portal.destination?.url || null;
|
|
portalMesh.userData.portalColor = new THREE.Color(portal.color).convertSRGBToLinear();
|
|
|
|
portalGroup.add(portalMesh);
|
|
});
|
|
}
|
|
|
|
// rebuildGravityZones forward ref
|
|
let _rebuildGravityZonesFn = null;
|
|
export function setRebuildGravityZonesFn(fn) { _rebuildGravityZonesFn = fn; }
|
|
|
|
// runPortalHealthChecks forward ref
|
|
let _runPortalHealthChecksFn = null;
|
|
export function setRunPortalHealthChecksFn(fn) { _runPortalHealthChecksFn = fn; }
|
|
|
|
export async function loadPortals() {
|
|
try {
|
|
const res = await fetch('./portals.json');
|
|
if (!res.ok) throw new Error('Portals not found');
|
|
portals = await res.json();
|
|
console.log('Loaded portals:', portals);
|
|
setPortalsRef(portals);
|
|
setPortalsRefAudio(portals);
|
|
createPortals();
|
|
rebuildRuneRing();
|
|
if (_rebuildGravityZonesFn) _rebuildGravityZonesFn();
|
|
startPortalHums();
|
|
if (_runPortalHealthChecksFn) _runPortalHealthChecksFn();
|
|
} catch (error) {
|
|
console.error('Failed to load portals:', error);
|
|
}
|
|
}
|