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,
interactScript: `
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(),
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 [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(() => {

View File

@ -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(

View File

@ -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}) {
)}
<Entities
filters={filters}
monopolizers={monopolizers}
/>
{projected?.length > 0 && layers[0] && (
<TargetingGhost

View File

@ -9,7 +9,7 @@ import {useMainEntity} from '@/context/main-entity.js';
import Entity from './entity.jsx';
export default function Entities({filters}) {
export default function Entities({filters, monopolizers}) {
const [ecs] = useEcs();
const [entities, setEntities] = useState({});
const [mainEntity] = useMainEntity();
@ -75,7 +75,7 @@ export default function Entities({filters}) {
}, []);
const renderables = [];
for (const id in entities) {
const isHighlightedInteraction = id == willInteractWith;
const isHighlightedInteraction = 0 === monopolizers.length && id == willInteractWith;
renderables.push(
<Entity
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 (
<Stage
className={styles.stage}
@ -58,6 +58,7 @@ export default function Pixi({applyFilters, camera, scale}) {
<Ecs
applyFilters={applyFilters}
camera={camera}
monopolizers={monopolizers}
scale={scale}
/>
</Stage>

View File

@ -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}) {
<Pixi
applyFilters={applyFilters}
camera={camera}
monopolizers={monopolizers}
scale={scale}
/>
<Dom>
@ -399,6 +411,7 @@ export default function Ui({disconnected}) {
<Entities
camera={camera}
scale={scale}
setMonopolizers={setMonopolizers}
/>
{showDisconnected && (
<Disconnected />