feat: monopolizers

This commit is contained in:
cha0s 2024-07-13 17:08:23 -05:00
parent 8fb37dd2ba
commit 387e36613f
7 changed files with 65 additions and 11 deletions

View File

@ -77,7 +77,10 @@ export default async function createHomestead(id) {
interacting: 1, interacting: 1,
interactScript: ` interactScript: `
subject.Interlocutor.dialogue({ subject.Interlocutor.dialogue({
body: '<strong>Hey</strong><rate frequency={1}> </rate><rate frequency={0}><shake>what</shake></rate> <em>is</em> <wave frequency={0.5}>uu<rainbow frequency={2}>uu<blink>uu</blink><fade frequency={5}>uu<shake magnitude={4}>uu</shake>uuu</fade></rainbow>uup</wave>? ^_^', // body: '<strong>Hey</strong><rate frequency={1}> </rate><rate frequency={0}><shake>what</shake></rate> <em>is</em> <wave frequency={0.5}>uu<rainbow frequency={2}>uu<blink>uu</blink><fade frequency={5}>uu<shake magnitude={4}>uu</shake>uuu</fade></rainbow>uup</wave>? ^_^',
body: 'This is a fairly decently long amount of text that will be used to show just how the box grows when there is a kinda l<wave>oooooooooooooooo</wave>ng ass bunch of text here',
linger: 5,
monopolizer: true,
origin: subject.Position.toJSON(), origin: subject.Position.toJSON(),
position: {x: subject.Position.x, y: subject.Position.y - 32}, position: {x: subject.Position.x, y: subject.Position.y - 32},
}) })

View File

@ -18,6 +18,16 @@ export default function Dialogue({
const [dimensions, setDimensions] = useState({h: 0, w: 0}); const [dimensions, setDimensions] = useState({h: 0, w: 0});
const [caret, setCaret] = useState(0); const [caret, setCaret] = useState(0);
const [radians, setRadians] = useState(0); const [radians, setRadians] = useState(0);
useEffect(() => {
return dialogue.addSkipListener(() => {
if (caret >= dialogue.letters.length - 1) {
dialogue.onClose();
}
else {
setCaret(dialogue.letters.length - 1);
}
});
}, [caret, dialogue]);
useEffect(() => { useEffect(() => {
setRadians(0); setRadians(0);
let handle; let handle;
@ -40,9 +50,8 @@ export default function Dialogue({
const {params} = dialogue.letters[caret]; const {params} = dialogue.letters[caret];
let handle; let handle;
if (caret >= dialogue.letters.length - 1) { if (caret >= dialogue.letters.length - 1) {
const {linger = 5} = dialogue; const {linger} = dialogue;
if (!linger) { if (!linger) {
dialogue.onClose();
return; return;
} }
handle = setTimeout(() => { handle = setTimeout(() => {

View File

@ -5,7 +5,7 @@ import {parseLetters} from '@/dialogue.js';
import Entity from './entity.jsx'; import Entity from './entity.jsx';
export default function Entities({camera, scale}) { export default function Entities({camera, scale, setMonopolizers}) {
const [ecs] = useEcs(); const [ecs] = useEcs();
const [entities, setEntities] = useState({}); const [entities, setEntities] = useState({});
useEcsTick((payload) => { useEcsTick((payload) => {
@ -30,12 +30,39 @@ export default function Entities({camera, scale}) {
for (const key in dialogue) { for (const key in dialogue) {
dialogues[key] = dialogue[key]; dialogues[key] = dialogue[key];
dialogues[key].letters = parseLetters(dialogues[key].body); dialogues[key].letters = parseLetters(dialogues[key].body);
const skipListeners = new Set();
dialogues[key].addSkipListener = (listener) => {
skipListeners.add(listener);
return () => {
skipListeners.delete(listener);
}
}
const monopolizer = {
trigger: () => {
for (const listener of skipListeners) {
listener();
}
},
};
if (dialogues[key].monopolizer) {
setMonopolizers((monopolizers) => [...monopolizers, monopolizer]);
}
dialogues[key].onClose = () => { dialogues[key].onClose = () => {
delete dialogues[key];
setEntities((entities) => ({ setEntities((entities) => ({
...entities, ...entities,
[id]: ecs.rebuild(id), [id]: ecs.rebuild(id),
})); }));
if (dialogues[key].monopolizer) {
setMonopolizers((monopolizers) => {
const index = monopolizers.indexOf(monopolizer);
if (-1 === index) {
return monopolizers;
}
monopolizers.splice(index, 1);
return [...monopolizers];
});
}
delete dialogues[key];
}; };
} }
} }
@ -49,7 +76,7 @@ export default function Entities({camera, scale}) {
...updating, ...updating,
}; };
}); });
}, [ecs]); }, [ecs, setMonopolizers]);
const renderables = []; const renderables = [];
for (const id in entities) { for (const id in entities) {
renderables.push( renderables.push(

View File

@ -26,7 +26,7 @@ function calculateDarkness(hour) {
return Math.floor(darkness * 1000) / 1000; return Math.floor(darkness * 1000) / 1000;
} }
export default function Ecs({applyFilters, camera, scale}) { export default function Ecs({applyFilters, camera, monopolizers, scale}) {
const [ecs] = useEcs(); const [ecs] = useEcs();
const [filters, setFilters] = useState([]); const [filters, setFilters] = useState([]);
const [mainEntity] = useMainEntity(); const [mainEntity] = useMainEntity();
@ -130,6 +130,7 @@ export default function Ecs({applyFilters, camera, scale}) {
)} )}
<Entities <Entities
filters={filters} filters={filters}
monopolizers={monopolizers}
/> />
{projected?.length > 0 && layers[0] && ( {projected?.length > 0 && layers[0] && (
<TargetingGhost <TargetingGhost

View File

@ -9,7 +9,7 @@ import {useMainEntity} from '@/context/main-entity.js';
import Entity from './entity.jsx'; import Entity from './entity.jsx';
export default function Entities({filters}) { export default function Entities({filters, monopolizers}) {
const [ecs] = useEcs(); const [ecs] = useEcs();
const [entities, setEntities] = useState({}); const [entities, setEntities] = useState({});
const [mainEntity] = useMainEntity(); const [mainEntity] = useMainEntity();
@ -75,7 +75,7 @@ export default function Entities({filters}) {
}, []); }, []);
const renderables = []; const renderables = [];
for (const id in entities) { for (const id in entities) {
const isHighlightedInteraction = id == willInteractWith; const isHighlightedInteraction = 0 === monopolizers.length && id == willInteractWith;
renderables.push( renderables.push(
<Entity <Entity
filters={isHighlightedInteraction ? interactionFilters : null} filters={isHighlightedInteraction ? interactionFilters : null}

View File

@ -45,7 +45,7 @@ export const Stage = ({children, ...props}) => {
); );
}; };
export default function Pixi({applyFilters, camera, scale}) { export default function Pixi({applyFilters, camera, monopolizers, scale}) {
return ( return (
<Stage <Stage
className={styles.stage} className={styles.stage}
@ -58,6 +58,7 @@ export default function Pixi({applyFilters, camera, scale}) {
<Ecs <Ecs
applyFilters={applyFilters} applyFilters={applyFilters}
camera={camera} camera={camera}
monopolizers={monopolizers}
scale={scale} scale={scale}
/> />
</Stage> </Stage>

View File

@ -64,6 +64,7 @@ export default function Ui({disconnected}) {
const [Components, setComponents] = useState(); const [Components, setComponents] = useState();
const [Systems, setSystems] = useState(); const [Systems, setSystems] = useState();
const [applyFilters, setApplyFilters] = useState(true); const [applyFilters, setApplyFilters] = useState(true);
const [monopolizers, setMonopolizers] = useState([]);
useEffect(() => { useEffect(() => {
async function setEcsStuff() { async function setEcsStuff() {
const {default: Components} = await import('@/ecs-components/index.js'); const {default: Components} = await import('@/ecs-components/index.js');
@ -148,6 +149,12 @@ export default function Ui({disconnected}) {
break; break;
} }
case 'e': { case 'e': {
if (KEY_MAP[type]) {
if (monopolizers.length > 0) {
monopolizers[0].trigger();
break;
}
}
actionPayload = {type: 'interact', value: KEY_MAP[type]}; actionPayload = {type: 'interact', value: KEY_MAP[type]};
break; break;
} }
@ -219,7 +226,7 @@ export default function Ui({disconnected}) {
}); });
} }
}); });
}, [client, debug, devtoolsIsOpen, setDebug, setScale]); }, [client, debug, devtoolsIsOpen, monopolizers, setDebug, setScale]);
usePacket('EcsChange', async () => { usePacket('EcsChange', async () => {
setMainEntity(undefined); setMainEntity(undefined);
setEcs(new ClientEcs({Components, Systems})); setEcs(new ClientEcs({Components, Systems}));
@ -339,6 +346,10 @@ export default function Ui({disconnected}) {
} }
break; break;
case 2: case 2:
if (monopolizers.length > 0) {
monopolizers[0].trigger();
break;
}
client.send({ client.send({
type: 'Action', type: 'Action',
payload: {type: 'interact', value: 1}, payload: {type: 'interact', value: 1},
@ -383,6 +394,7 @@ export default function Ui({disconnected}) {
<Pixi <Pixi
applyFilters={applyFilters} applyFilters={applyFilters}
camera={camera} camera={camera}
monopolizers={monopolizers}
scale={scale} scale={scale}
/> />
<Dom> <Dom>
@ -399,6 +411,7 @@ export default function Ui({disconnected}) {
<Entities <Entities
camera={camera} camera={camera}
scale={scale} scale={scale}
setMonopolizers={setMonopolizers}
/> />
{showDisconnected && ( {showDisconnected && (
<Disconnected /> <Disconnected />