feat: dialogue pages
This commit is contained in:
parent
de8ff49270
commit
336ec04f66
|
@ -18,36 +18,63 @@ export default function Dialogue({
|
|||
const ref = useRef();
|
||||
const [dimensions, setDimensions] = useState({h: 0, w: 0});
|
||||
const [caret, setCaret] = useState(0);
|
||||
const [page, setPage] = useState(0);
|
||||
const radians = useRadians();
|
||||
const [pageLetters, setPageLetters] = useState([]);
|
||||
useEffect(() => {
|
||||
setCaret(0);
|
||||
setPageLetters(dialogue.letters.filter((letter) => letter.page === page));
|
||||
}, [dialogue, page]);
|
||||
useEffect(() => {
|
||||
if (0 === pageLetters.length) {
|
||||
return;
|
||||
}
|
||||
return dialogue.addSkipListener(() => {
|
||||
if (caret >= dialogue.letters.length - 1) {
|
||||
dialogue.onClose();
|
||||
// at end
|
||||
if (caret >= pageLetters.length - 1) {
|
||||
if (page < dialogue.pages - 1) {
|
||||
setPage((page) => page + 1);
|
||||
}
|
||||
else {
|
||||
setCaret(dialogue.letters.length - 1);
|
||||
dialogue.onClose();
|
||||
}
|
||||
}
|
||||
// skip to end
|
||||
else {
|
||||
setCaret(pageLetters.length - 1);
|
||||
}
|
||||
});
|
||||
}, [caret, dialogue]);
|
||||
}, [caret, dialogue, page, pageLetters]);
|
||||
useEffect(() => {
|
||||
const {params} = dialogue.letters[caret];
|
||||
if (0 === pageLetters.length) {
|
||||
return;
|
||||
}
|
||||
const {params} = pageLetters[caret];
|
||||
let handle;
|
||||
if (caret >= dialogue.letters.length - 1) {
|
||||
// start lingering timeout
|
||||
if (caret >= pageLetters.length - 1) {
|
||||
const {linger} = dialogue;
|
||||
if (!linger) {
|
||||
return;
|
||||
}
|
||||
handle = setTimeout(() => {
|
||||
if (page < dialogue.pages - 1) {
|
||||
setPage((page) => page + 1);
|
||||
}
|
||||
else {
|
||||
dialogue.onClose();
|
||||
}
|
||||
}, linger * 1000);
|
||||
}
|
||||
else {
|
||||
// jump to next caret spot
|
||||
let jump = caret;
|
||||
while (0 === dialogue.letters[jump].params.rate.frequency && jump < dialogue.letters.length - 1) {
|
||||
while (0 === pageLetters[jump].params.rate.frequency && jump < pageLetters.length - 1) {
|
||||
jump += 1;
|
||||
}
|
||||
setCaret(jump);
|
||||
if (jump < dialogue.letters.length - 1) {
|
||||
if (jump < pageLetters.length - 1) {
|
||||
// wait for next jump
|
||||
handle = setTimeout(() => {
|
||||
setCaret(caret + 1);
|
||||
}, params.rate.frequency * 1000)
|
||||
|
@ -56,7 +83,7 @@ export default function Dialogue({
|
|||
return () => {
|
||||
clearTimeout(handle);
|
||||
}
|
||||
}, [caret, dialogue]);
|
||||
}, [caret, dialogue, page, pageLetters]);
|
||||
const updateDimensions = useCallback(() => {
|
||||
if (ref.current) {
|
||||
const {height, width} = ref.current.getBoundingClientRect();
|
||||
|
@ -65,8 +92,8 @@ export default function Dialogue({
|
|||
}, [domScale]);
|
||||
useAnimationFrame(updateDimensions);
|
||||
const localRender = useMemo(
|
||||
() => render(dialogue.letters, styles.letter),
|
||||
[dialogue.letters],
|
||||
() => render(pageLetters, styles.letter),
|
||||
[pageLetters],
|
||||
);
|
||||
let position = 'function' === typeof dialogue.position
|
||||
? dialogue.position()
|
||||
|
|
|
@ -45,6 +45,7 @@ export default function Entities({
|
|||
dialogues[key].position = () => updating[id].Position;
|
||||
}
|
||||
dialogues[key].letters = parseLetters(dialogues[key].body);
|
||||
dialogues[key].pages = 1 + dialogues[key].letters.at(-1).page;
|
||||
setChatMessages((chatMessages) => ({
|
||||
[[id, key].join('-')]: dialogues[key].letters,
|
||||
...chatMessages,
|
||||
|
|
|
@ -289,11 +289,7 @@ export default async function createHomestead(id) {
|
|||
interacting: 1,
|
||||
interactScript: `
|
||||
const lines = [
|
||||
'mrowwr',
|
||||
'p<shake>rrr</shake>o<wave>wwwww</wave>',
|
||||
'mew<rate frequency={0.5}> </rate>mew!',
|
||||
'me<wave>wwwww</wave>',
|
||||
'\\\\*pu<shake>rrrrr</shake>\\\\*',
|
||||
'Mind your own business, buddy.\\n\\ner, I mean, <shake>MEEHHHHHH</shake>',
|
||||
];
|
||||
const line = lines[Math.floor(Math.random() * lines.length)];
|
||||
subject.Interlocutor.dialogue({
|
||||
|
|
|
@ -27,6 +27,7 @@ function computeParams(ancestors) {
|
|||
|
||||
export function parseLetters(source) {
|
||||
let letters = [];
|
||||
let page = 0;
|
||||
try {
|
||||
const tree = parser.parse(source);
|
||||
tree.dialogue = {
|
||||
|
@ -43,6 +44,10 @@ export function parseLetters(source) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case 'paragraph': {
|
||||
page += 1;
|
||||
break;
|
||||
}
|
||||
case 'text': {
|
||||
const params = computeParams(ancestors);
|
||||
const split = node.value.split('');
|
||||
|
@ -51,7 +56,12 @@ export function parseLetters(source) {
|
|||
for (const name in params) {
|
||||
indices[name] = i + params[name].length;
|
||||
}
|
||||
letters.push({character: split[i], indices, params});
|
||||
letters.push({
|
||||
character: split[i],
|
||||
indices,
|
||||
page: page - 1,
|
||||
params,
|
||||
});
|
||||
}
|
||||
for (const name in params) {
|
||||
params[name].length += split.length;
|
||||
|
|
Loading…
Reference in New Issue
Block a user