192 lines
4.7 KiB
TypeScript
192 lines
4.7 KiB
TypeScript
import { DrawPile } from "./drawpile.ts";
|
|
import { CheckData, CheckDataOption, ChoiceOption } from "./newmap.ts";
|
|
import { getPartLocation, withCamera } from "./layout.ts";
|
|
import { AlignX, AlignY, Point, Rect, Size } from "./engine/datatypes.ts";
|
|
import { D } from "./engine/public.ts";
|
|
import { addButton } from "./button.ts";
|
|
import { getSkills } from "./skills.ts";
|
|
import { getPlayerProgress } from "./playerprogress.ts";
|
|
import { C } from "./colors.ts";
|
|
|
|
export class CheckModal {
|
|
#drawpile: DrawPile;
|
|
#activeCheck: CheckData | null;
|
|
#callback: (() => void) | null;
|
|
#success: string | null;
|
|
|
|
constructor() {
|
|
this.#drawpile = new DrawPile();
|
|
this.#activeCheck = null;
|
|
this.#callback = null;
|
|
this.#success = null;
|
|
}
|
|
|
|
get isShown() {
|
|
return this.#activeCheck != null;
|
|
}
|
|
|
|
get #size(): Size {
|
|
return getPartLocation("BottomModal").size;
|
|
}
|
|
|
|
update() {
|
|
withCamera("BottomModal", () => this.#update());
|
|
this.#drawpile.executeOnClick();
|
|
}
|
|
|
|
draw() {
|
|
withCamera("BottomModal", () => this.#draw());
|
|
}
|
|
|
|
show(checkData: CheckData | null, callback: (() => void) | null) {
|
|
this.#activeCheck = checkData;
|
|
this.#callback = callback;
|
|
this.#success = null;
|
|
}
|
|
|
|
#update() {
|
|
this.#drawpile.clear();
|
|
|
|
let check = this.#activeCheck;
|
|
if (!check) {
|
|
return;
|
|
}
|
|
|
|
let size = this.#size;
|
|
this.#drawpile.add(0, () => {
|
|
D.fillRect(new Point(-4, -4), size.add(new Size(8, 8)), C.BG_UI);
|
|
});
|
|
|
|
let success = this.#success;
|
|
if (success) {
|
|
this.#drawpile.add(0, () => {
|
|
D.drawText(
|
|
success,
|
|
new Point(size.w / 2, (size.h - 64) / 2),
|
|
C.FG_BOLD,
|
|
{
|
|
forceWidth: size.w,
|
|
alignX: AlignX.Center,
|
|
alignY: AlignY.Middle,
|
|
},
|
|
);
|
|
});
|
|
addButton(
|
|
this.#drawpile,
|
|
"OK!",
|
|
new Rect(new Point(0, size.h - 64), new Size(size.w, 64)),
|
|
true,
|
|
() => {
|
|
this.show(null, null);
|
|
},
|
|
);
|
|
return;
|
|
}
|
|
|
|
let labelText = check.label;
|
|
this.#drawpile.add(0, () => {
|
|
D.drawText(
|
|
labelText,
|
|
new Point(size.w / 2, (size.h - 64) / 2),
|
|
C.FG_BOLD,
|
|
{
|
|
forceWidth: size.w,
|
|
alignX: AlignX.Center,
|
|
alignY: AlignY.Middle,
|
|
},
|
|
);
|
|
});
|
|
|
|
let options = check.options;
|
|
|
|
let addOptionButton = (
|
|
option: CheckDataOption | ChoiceOption,
|
|
rect: Rect,
|
|
) => {
|
|
let accomplished: boolean;
|
|
let optionLabel: string;
|
|
let resultMessage: string | null;
|
|
let endorse = false;
|
|
if ((option as ChoiceOption).isChoice) {
|
|
// TODO: Use OOP here
|
|
option = option as ChoiceOption;
|
|
accomplished = option.countsAsSuccess;
|
|
optionLabel = option.unlockable;
|
|
resultMessage = option.success;
|
|
} else {
|
|
option = option as CheckDataOption;
|
|
let skill = option.skill();
|
|
let skillName = getSkills().get(skill).profile.name;
|
|
let hasSkill = getPlayerProgress().hasLearned(skill);
|
|
// hasSkill ||= true;
|
|
if (hasSkill) {
|
|
optionLabel = `[${skillName}] ${option.unlockable}`;
|
|
endorse = true;
|
|
} else {
|
|
optionLabel = `[Needs ${skillName}] ${option.locked}`;
|
|
}
|
|
resultMessage = hasSkill ? option.success : option.failure;
|
|
accomplished = hasSkill;
|
|
}
|
|
addButton(
|
|
this.#drawpile,
|
|
optionLabel,
|
|
rect,
|
|
true,
|
|
() => {
|
|
this.#success = resultMessage;
|
|
|
|
if (accomplished) {
|
|
let cb = this.#callback;
|
|
if (cb) {
|
|
cb();
|
|
}
|
|
}
|
|
|
|
if (resultMessage == null) {
|
|
this.show(null, null);
|
|
}
|
|
},
|
|
{ endorse },
|
|
);
|
|
};
|
|
|
|
if (options.length == 0) {
|
|
addButton(
|
|
this.#drawpile,
|
|
"OK!",
|
|
new Rect(new Point(0, size.h - 64), new Size(size.w, 64)),
|
|
true,
|
|
() => {
|
|
this.show(null, null);
|
|
},
|
|
);
|
|
} else if (options.length == 1) {
|
|
addOptionButton(
|
|
options[0],
|
|
new Rect(new Point(0, size.h - 64), new Size(size.w, 64)),
|
|
);
|
|
} else if (options.length == 2) {
|
|
addOptionButton(
|
|
options[0],
|
|
new Rect(new Point(0, size.h - 64), new Size(size.w, 32)),
|
|
);
|
|
addOptionButton(
|
|
options[1],
|
|
new Rect(new Point(0, size.h - 32), new Size(size.w, 32)),
|
|
);
|
|
} else {
|
|
throw new Error(`unexpected number of options ${options.length}`);
|
|
}
|
|
}
|
|
|
|
#draw() {
|
|
this.#drawpile.draw();
|
|
}
|
|
}
|
|
|
|
let active: CheckModal = new CheckModal();
|
|
export function getCheckModal() {
|
|
return active;
|
|
}
|