frontispiece / packages / ink-processor / src / data / story-section.ts
story-section.ts
Raw
/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

import {
	VisualInkSection,
	VisualInkLineOrCommand,
	VisualInkAllLineTypes,
	GetVisibleLinesInSectionOptions,
} from "../types"

// getters
////////////

export const getLatestVisibleLineInSection = (
	section: VisualInkSection
): VisualInkLineOrCommand => {
	if (!section) {
		return undefined
	}
	if (isSectionComplete(section)) {
		return section.lines[section.lines.length - 1]
	}
	if (section.activeLine < 0) {
		return undefined
	}
	return section.lines[section.activeLine]
}

export const isSectionComplete = (section: VisualInkSection): boolean => {
	if (!section) {
		return false
	}
	if (section.activeLine === undefined) {
		return true
	}
	return section.activeLine >= section.lines.length - 1
}

/**
 * Retrieves all visible lines in section. Commands may be a part of the visualState, but aren't shown here.
 * @param section
 * @param options
 * @returns
 */
export const getVisibleLinesInSection = (
	section: VisualInkSection,
	options: GetVisibleLinesInSectionOptions
) => {
	const activeLine = isSectionComplete(section) ? section.lines.length - 1 : section.activeLine
	const lines: VisualInkAllLineTypes[] = []
	for (let i = 0; i <= activeLine; i++) {
		const scopeLine = section.lines[i]
		if (scopeLine.type === "command" && !options.showCommands) {
			continue
		}
		if (scopeLine.isHidden && !options.showHidden) {
			continue
		}

		let line = scopeLine
		if (section.isHidden && !scopeLine.isHidden) {
			line = {...scopeLine, isHidden: true}
		}
		lines.push(line)
	}

	if (
		isSectionComplete(section) &&
		section.activeChoiceIndex !== undefined &&
		section.activeChoiceIndex !== -1 &&
		options.showChosenChoice
	) {
		const choice = section.choices[section.activeChoiceIndex]
		if (!choice.isHidden || options.showHidden) {
			let choiceCopy = choice
			if (section.isHidden) {
				choiceCopy = {...choice, isHidden: true}
			}
			lines.push(choiceCopy)
		}
	}

	return lines
}

export const getNumberOfLinesLeftToShow = (section: VisualInkSection): number => {
	if (isSectionComplete(section)) {
		return 0
	}
	return section.lines.length - (section.activeLine + 1)
}

// reducers
//////////////

export const advanceSectionLine = (section: VisualInkSection): VisualInkSection => {
	if (section.activeLine === undefined) {
		return section
	}

	return {...section, activeLine: section.activeLine + 1}
}