add choice mechanic
This commit is contained in:
@@ -22,12 +22,23 @@ define_sprite Player shock "https://placehold.co/400x600/4d79ff/ffffff?text=Play
|
||||
sprite Agnieszka happy at pos2
|
||||
sprite Player normal at pos7
|
||||
say Agnieszka "To jest najprostszy tekst w tekstboxie!"
|
||||
say Agnieszka "Chcesz zobaczyć specjalny efekt?"
|
||||
|
||||
choice "Tak, pokaż mi!" jump:special_effect
|
||||
choice "Nie, przejdźmy dalej" jump:continue_scene
|
||||
|
||||
label special_effect
|
||||
sprite Agnieszka wave at pos3
|
||||
say Agnieszka "Oto on! Pogrubiony tekst: " b"BUM!"
|
||||
say Agnieszka "I teraz wracamy do głównej sceny."
|
||||
|
||||
label continue_scene
|
||||
say Agnieszka "Kontynuujemy naszą rozmowę."
|
||||
say Agnieszka "To jest najprostszy tekst w tekstboxie!" "Tu jest dużo tekstu."
|
||||
say "To by było trochę niekomfortowe trzymać w jednej linii." "Ale wszyscy wiedzą."
|
||||
say "Że to nadal Agnieszka."
|
||||
say "To jest tekst bez osoby podanej!"
|
||||
sprite Agnieszka wave at pos3
|
||||
say Agnieszka "Look, I defined this 'wave' sprite right in the script!"
|
||||
say Agnieszka b"To jest pogrubione" "A to nie!" b"P""ierwsza litera tylko"
|
||||
say Agnieszka i"Hello! This is italicized" "And this isn't"
|
||||
say Agnieszka u"This is underlined" "And this isn't."
|
||||
@@ -67,8 +78,13 @@ export interface Segment {
|
||||
modifiers: Modifier;
|
||||
}
|
||||
|
||||
export interface ChoiceOption {
|
||||
text: string;
|
||||
jumpLabel: string;
|
||||
}
|
||||
|
||||
export interface Statement {
|
||||
type: 'say' | 'wait' | 'sprite' | 'set' | 'fire' | 'nextfile' | 'comment';
|
||||
type: 'say' | 'wait' | 'sprite' | 'set' | 'fire' | 'nextfile' | 'comment' | 'choice' | 'label';
|
||||
character?: string | null;
|
||||
segments?: Segment[];
|
||||
continuations?: Segment[];
|
||||
@@ -82,6 +98,8 @@ export interface Statement {
|
||||
filename?: string;
|
||||
text?: string;
|
||||
lineNumber: number;
|
||||
label?: string;
|
||||
choices?: ChoiceOption[];
|
||||
}
|
||||
|
||||
// --- PARSER ---
|
||||
@@ -95,7 +113,23 @@ export function parseScript(text: string): Statement[] {
|
||||
const segments: Segment[] = [];
|
||||
const segmentRegex = /([biuswcftn]|click|clicknoskip)?"([^"]*)"(\(([^)]+)\))?/g;
|
||||
let match;
|
||||
let lastIndex = 0;
|
||||
|
||||
while ((match = segmentRegex.exec(lineText)) !== null) {
|
||||
// Add any text between matches (like spaces) as a plain segment
|
||||
const gap = lineText.substring(lastIndex, match.index);
|
||||
if (gap) {
|
||||
segments.push({
|
||||
text: gap,
|
||||
modifiers: {
|
||||
bold: false, italic: false, underline: false, strikethrough: false,
|
||||
wait: false, waitDuration: null, color: null, font: null,
|
||||
speed: null, clickLock: null, click: false, clicknoskip: false,
|
||||
inlineBranch: []
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const [full, mod, textValue, fullParens, params] = match;
|
||||
const modifiers: Modifier = {
|
||||
bold: mod === 'b',
|
||||
@@ -113,7 +147,23 @@ export function parseScript(text: string): Statement[] {
|
||||
inlineBranch: []
|
||||
};
|
||||
segments.push({ text: textValue, modifiers });
|
||||
lastIndex = segmentRegex.lastIndex;
|
||||
}
|
||||
|
||||
// Add remaining text after the last match
|
||||
const remaining = lineText.substring(lastIndex);
|
||||
if (remaining) {
|
||||
segments.push({
|
||||
text: remaining,
|
||||
modifiers: {
|
||||
bold: false, italic: false, underline: false, strikethrough: false,
|
||||
wait: false, waitDuration: null, color: null, font: null,
|
||||
speed: null, clickLock: null, click: false, clicknoskip: false,
|
||||
inlineBranch: []
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return segments;
|
||||
};
|
||||
|
||||
@@ -135,10 +185,12 @@ export function parseScript(text: string): Statement[] {
|
||||
if (afterSay.startsWith('"')) {
|
||||
character = null;
|
||||
} else {
|
||||
const firstQuoteIndex = afterSay.indexOf('"');
|
||||
if (firstQuoteIndex !== -1) {
|
||||
character = afterSay.substring(0, firstQuoteIndex).trim();
|
||||
segmentPart = afterSay.substring(firstQuoteIndex);
|
||||
// Find the start of the first segment.
|
||||
// A segment starts with a quote, or a modifier followed by a quote.
|
||||
const segmentMatch = afterSay.match(/([biuswcftn]|click|clicknoskip)?"/);
|
||||
if (segmentMatch && segmentMatch.index !== undefined) {
|
||||
character = afterSay.substring(0, segmentMatch.index).trim();
|
||||
segmentPart = afterSay.substring(segmentMatch.index);
|
||||
} else {
|
||||
character = afterSay;
|
||||
segmentPart = "";
|
||||
@@ -159,10 +211,31 @@ export function parseScript(text: string): Statement[] {
|
||||
continue;
|
||||
}
|
||||
|
||||
const words = line.split(/\s+/);
|
||||
const words = line.match(/(?:[^\s"]+|"[^"]*")+/g) || [];
|
||||
let cmd = words[0];
|
||||
|
||||
if (cmd === 'wait') {
|
||||
if (cmd === 'label') {
|
||||
statements.push({
|
||||
type: 'label',
|
||||
label: words[1],
|
||||
lineNumber: originalLineNumber
|
||||
});
|
||||
} else if (cmd === 'choice') {
|
||||
const text = words[1]?.replace(/^"(.*)"$/, '$1');
|
||||
const jumpPart = words[2];
|
||||
const jumpLabel = jumpPart?.startsWith('jump:') ? jumpPart.slice(5) : '';
|
||||
|
||||
const lastStatement = statements[statements.length - 1];
|
||||
if (lastStatement?.type === 'choice') {
|
||||
lastStatement.choices?.push({ text, jumpLabel });
|
||||
} else {
|
||||
statements.push({
|
||||
type: 'choice',
|
||||
choices: [{ text, jumpLabel }],
|
||||
lineNumber: originalLineNumber
|
||||
});
|
||||
}
|
||||
} else if (cmd === 'wait') {
|
||||
statements.push({
|
||||
type: 'wait',
|
||||
duration: words[1],
|
||||
|
||||
Reference in New Issue
Block a user