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