import {Container} from '@pixi/react'; import {useEffect, useState} from 'react'; import {useEcs, useEcsTick} from '@/react/context/ecs.js'; import {useMainEntity} from '@/react/context/main-entity.js'; // import {useRadians} from '@/react/context/radians.js'; // import {TAU} from '@/util/math.js'; import Entities from './entities.jsx'; import TargetingGhost from './targeting-ghost.jsx'; import TargetingGrid from './targeting-grid.jsx'; import TileLayer from './tile-layer.jsx'; import Water from './water.jsx'; const NIGHTNESS = 0.1; function calculateDarkness(hour) { let darkness = 0; if (hour >= 21 || hour < 4) { darkness = 0.8; } if (hour >= 4 && hour < 7) { darkness = 0.8 * ((7 - hour) / 3); } if (hour >= 18 && hour < 21) { darkness = 0.8 * ((3 - (21 - hour)) / 3); } return Math.floor(darkness * 1000) / 1000; } export default function Ecs({applyFilters, camera, monopolizers, scale}) { const [ecs] = useEcs(); const [filters, setFilters] = useState([]); const [mainEntity] = useMainEntity(); const [layers, setLayers] = useState([]); const [hour, setHour] = useState(10); const [night, setNight] = useState(); const [projected, setProjected] = useState([]); const [position, setPosition] = useState({x: 0, y: 0}); const [water, setWater] = useState(); // const radians = useRadians(); // const [sine, setSine] = useState(); // useEffect(() => { // async function buildSineFilter() { // const {default: SineFilter} = await import('./filters/horizontal-sine.js'); // const sine = new SineFilter(); // sine.frequency = 1; // sine.magnitude = 3; // setSine(sine); // } // buildSineFilter(); // }, []); // useEffect(() => { // if (!sine) { // return; // } // const r = (radians / 8) % TAU; // sine.offset = 6 * (camera.y + r); // sine.magnitude = 2 * (r > Math.PI ? TAU - r : r); // }, [camera, radians, scale, sine]); useEffect(() => { async function buildNightFilter() { const {ColorMatrixFilter} = await import('@pixi/filter-color-matrix'); class NightFilter extends ColorMatrixFilter { setIntensity(intensity) { const double = NIGHTNESS * 2; const half = NIGHTNESS / 2; const redDown = 1 - (intensity * (1 + double)); const blueUp = 1 - (intensity * (1 - half)); const scale = intensity * NIGHTNESS; this.uniforms.m = [ redDown, -scale, 0, 0, 0, -scale, (1 - intensity), scale, 0, 0, 0, scale, blueUp, 0, 0, 0, 0, 0, 1, 0, ]; } } setNight(new NightFilter()); } buildNightFilter(); }, []); useEffect(() => { if (night) { night.setIntensity(calculateDarkness(hour)); } }, [hour, night]); useEcsTick((payload) => { const entity = ecs.get(mainEntity); for (const id in payload) { const update = payload[id]; switch (id) { case '1': { const master = ecs.get(1); if (update.TileLayers) { setLayers(Object.values(master.TileLayers.$$layersProxies)); } if (update.Time) { setHour(Math.round(ecs.get(1).Time.hour * 60) / 60); } if (update.Water) { setWater(master.Water.water); } break; } } } if (entity) { const {Direction, Position, Wielder} = entity; setPosition(Position.toJSON()); setProjected(Wielder.activeItem()?.project(Position.tile, Direction.quantize(4))); } }, [ecs, mainEntity, scale]); useEffect(() => { setFilters( applyFilters ? [ ...(false && night ? [night] : []), // ...(sine ? [sine] : []), ] : [], ); }, [applyFilters, night]) return ( {layers.map((layer, i) => ( ))} {water && layers[0] && ( )} {projected && layers[0] && ( )} {projected?.length > 0 && layers[0] && ( )} ) }