diff --git a/app/create-homestead.js b/app/create-homestead.js index c8728fb..8d5ec55 100644 --- a/app/create-homestead.js +++ b/app/create-homestead.js @@ -77,7 +77,10 @@ export default async function createHomestead(id) { interacting: 1, interactScript: ` subject.Interlocutor.dialogue({ - body: 'Hey what is uuuuuuuuuuuuuuup? ^_^', + // body: 'Hey what is uuuuuuuuuuuuuuup? ^_^', + 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 loooooooooooooooong ass bunch of text here', + linger: 5, + monopolizer: true, origin: subject.Position.toJSON(), position: {x: subject.Position.x, y: subject.Position.y - 32}, }) diff --git a/app/react-components/dom/dialogue.jsx b/app/react-components/dom/dialogue.jsx index d86ceb8..852732f 100644 --- a/app/react-components/dom/dialogue.jsx +++ b/app/react-components/dom/dialogue.jsx @@ -18,6 +18,16 @@ export default function Dialogue({ const [dimensions, setDimensions] = useState({h: 0, w: 0}); const [caret, setCaret] = 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(() => { setRadians(0); let handle; @@ -40,9 +50,8 @@ export default function Dialogue({ const {params} = dialogue.letters[caret]; let handle; if (caret >= dialogue.letters.length - 1) { - const {linger = 5} = dialogue; + const {linger} = dialogue; if (!linger) { - dialogue.onClose(); return; } handle = setTimeout(() => { diff --git a/app/react-components/dom/entities.jsx b/app/react-components/dom/entities.jsx index dfaee8b..afa9a7e 100644 --- a/app/react-components/dom/entities.jsx +++ b/app/react-components/dom/entities.jsx @@ -5,7 +5,7 @@ import {parseLetters} from '@/dialogue.js'; import Entity from './entity.jsx'; -export default function Entities({camera, scale}) { +export default function Entities({camera, scale, setMonopolizers}) { const [ecs] = useEcs(); const [entities, setEntities] = useState({}); useEcsTick((payload) => { @@ -30,12 +30,39 @@ export default function Entities({camera, scale}) { for (const key in dialogue) { dialogues[key] = dialogue[key]; 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 = () => { - delete dialogues[key]; setEntities((entities) => ({ ...entities, [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, }; }); - }, [ecs]); + }, [ecs, setMonopolizers]); const renderables = []; for (const id in entities) { renderables.push( diff --git a/app/react-components/pixi/ecs.jsx b/app/react-components/pixi/ecs.jsx index 9045f1f..c9fd919 100644 --- a/app/react-components/pixi/ecs.jsx +++ b/app/react-components/pixi/ecs.jsx @@ -26,7 +26,7 @@ function calculateDarkness(hour) { 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 [filters, setFilters] = useState([]); const [mainEntity] = useMainEntity(); @@ -130,6 +130,7 @@ export default function Ecs({applyFilters, camera, scale}) { )} {projected?.length > 0 && layers[0] && ( { ); }; -export default function Pixi({applyFilters, camera, scale}) { +export default function Pixi({applyFilters, camera, monopolizers, scale}) { return ( diff --git a/app/react-components/ui.jsx b/app/react-components/ui.jsx index b2c9ab8..7c0b7e9 100644 --- a/app/react-components/ui.jsx +++ b/app/react-components/ui.jsx @@ -64,6 +64,7 @@ export default function Ui({disconnected}) { const [Components, setComponents] = useState(); const [Systems, setSystems] = useState(); const [applyFilters, setApplyFilters] = useState(true); + const [monopolizers, setMonopolizers] = useState([]); useEffect(() => { async function setEcsStuff() { const {default: Components} = await import('@/ecs-components/index.js'); @@ -148,6 +149,12 @@ export default function Ui({disconnected}) { break; } case 'e': { + if (KEY_MAP[type]) { + if (monopolizers.length > 0) { + monopolizers[0].trigger(); + break; + } + } actionPayload = {type: 'interact', value: KEY_MAP[type]}; break; } @@ -219,7 +226,7 @@ export default function Ui({disconnected}) { }); } }); - }, [client, debug, devtoolsIsOpen, setDebug, setScale]); + }, [client, debug, devtoolsIsOpen, monopolizers, setDebug, setScale]); usePacket('EcsChange', async () => { setMainEntity(undefined); setEcs(new ClientEcs({Components, Systems})); @@ -339,6 +346,10 @@ export default function Ui({disconnected}) { } break; case 2: + if (monopolizers.length > 0) { + monopolizers[0].trigger(); + break; + } client.send({ type: 'Action', payload: {type: 'interact', value: 1}, @@ -383,6 +394,7 @@ export default function Ui({disconnected}) { @@ -399,6 +411,7 @@ export default function Ui({disconnected}) { {showDisconnected && (