silphius/app/react-components/pixi/entities.jsx
2024-07-14 21:44:15 -05:00

90 lines
2.3 KiB
JavaScript

import {AdjustmentFilter} from '@pixi/filter-adjustment';
import {GlowFilter} from '@pixi/filter-glow';
import {Container} from '@pixi/react';
import {useState} from 'react';
import {usePacket} from '@/context/client.js';
import {useEcs, useEcsTick} from '@/context/ecs.js';
import {useMainEntity} from '@/context/main-entity.js';
import {useRadians} from '@/context/radians.js';
import Entity from './entity.jsx';
export default function Entities({filters, monopolizers}) {
const [ecs] = useEcs();
const [entities, setEntities] = useState({});
const [mainEntity] = useMainEntity();
const radians = useRadians();
const [willInteractWith, setWillInteractWith] = useState(0);
const [interactionFilters] = useState([
new AdjustmentFilter(),
new GlowFilter({color: 0x0}),
]);
const pulse = (Math.cos(radians / 4) + 1) * 0.5;
interactionFilters[0].brightness = (pulse * 0.75) + 1;
interactionFilters[1].outerStrength = pulse * 0.5;
usePacket('EcsChange', async () => {
setEntities({});
}, [setEntities]);
useEcsTick((payload) => {
if (!ecs) {
return;
}
const deleting = {};
const updating = {};
for (const id in payload) {
if ('1' === id) {
continue;
}
const update = payload[id];
if (false === update) {
deleting[id] = true;
continue;
}
updating[id] = ecs.get(id);
if (update.Emitter?.emit) {
updating[id].Emitter.emitting = {
...updating[id].Emitter.emitting,
...update.Emitter.emit,
};
}
}
setEntities((entities) => {
for (const id in deleting) {
delete entities[id];
}
return {
...entities,
...updating,
};
});
}, [ecs]);
useEcsTick(() => {
if (!ecs) {
return;
}
const main = ecs.get(mainEntity);
if (main) {
setWillInteractWith(main.Interacts.willInteractWith);
}
}, [ecs, mainEntity]);
const renderables = [];
for (const id in entities) {
const isHighlightedInteraction = 0 === monopolizers.length && id == willInteractWith;
renderables.push(
<Entity
filters={isHighlightedInteraction ? interactionFilters : null}
entity={entities[id]}
key={id}
/>
);
}
return (
<Container
filters={filters}
sortableChildren
>
{renderables}
</Container>
);
}