Skip to content

Commit

Permalink
dialog options, finish sphinx for now, add gear
Browse files Browse the repository at this point in the history
  • Loading branch information
amcolash committed Jul 14, 2024
1 parent 20eaaa8 commit a7b7421
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/classes/Item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { InteractResult, Interactive, ItemType } from './types';

export const ItemData = {
[ItemType.Wrench]: { x: 0, y: 0, image: 'wrench' },
[ItemType.Gear]: { x: 3500, y: 810, image: 'gear' },
[ItemType.Gear]: { x: 5120, y: 915, image: 'gear' },
};

export class Item extends Phaser.Physics.Arcade.Sprite implements Interactive {
Expand Down
84 changes: 80 additions & 4 deletions src/classes/UI/Message.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GameObjects, Scene } from 'phaser';
import { GameObjects, Math, Scene } from 'phaser';

import { Config } from '../../config';
import { Colors, getColorNumber } from '../../utils/colors';
Expand Down Expand Up @@ -26,6 +26,10 @@ export class Message extends GameObjects.Container {
box: GameObjects.Rectangle;
image: GameObjects.Image;

options?: string[];
optionsContainer: GameObjects.Container;
optionIndex: number;

dialog?: NPCDialog;
messageIndex: number;
interactionTimeout: number;
Expand All @@ -36,7 +40,7 @@ export class Message extends GameObjects.Container {

this.setScrollFactor(0);
this.setPosition(padding, height - padding - boxHeight);
this.setDepth(2);
this.setDepth(3);
this.setVisible(false);

this.player = player;
Expand Down Expand Up @@ -66,14 +70,32 @@ export class Message extends GameObjects.Container {
this.box.setStrokeStyle(2, getColorNumber(Colors.Tan), 1);
this.box.setOrigin(0, 0);

this.optionsContainer = scene.add.container().setScrollFactor(0);

this.add([this.box, this.npcName, this.text, this.image]);

this.scene.input.keyboard?.on('keydown-DOWN', () => {
this.setOptionIndex(1);
});

this.scene.input.keyboard?.on('keydown-UP', () => {
this.setOptionIndex(-1);
});

this.scene.input.keyboard?.on('keydown-ENTER', () => {
this.updateDialog();
if (this.options) {
this.onSelectOption(this.options[this.optionIndex]);
} else {
this.updateDialog();
}
});

this.scene.input.keyboard?.on('keydown-SPACE', () => {
this.updateDialog();
if (this.options) {
this.onSelectOption(this.options[this.optionIndex]);
} else {
this.updateDialog();
}
});
}

Expand Down Expand Up @@ -114,6 +136,52 @@ export class Message extends GameObjects.Container {
this.text.setText(message);
if (this.text.getWrappedText().length > 2) console.error('Message too long!', message);
}

this.updateOptions();
}

updateOptions() {
this.optionIndex = 0;
this.options = this.getOptions();
if (!this.options) return;

this.optionsContainer.removeAll(true);

this.options.forEach((option, index) => {
const text = new GameObjects.Text(this.scene, Config.width / 2, 120 + index * 74, option, {
...fontStyle,
backgroundColor: '#' + Colors.Black,
padding: { y: 10 },
align: 'center',
fixedWidth: 350,
}).setOrigin(0.5);

if (index === 0) text.setTint(getColorNumber(Colors.Tan));

text.setInteractive().on('pointerdown', () => {
this.onSelectOption(option);
});

this.optionsContainer.add(text);
});
}

setOptionIndex(delta: number) {
if (this.options) {
this.optionIndex = Math.Clamp(this.optionIndex + delta, 0, this.options.length - 1);

this.optionsContainer.getAll().forEach((option, index) => {
const text = option as GameObjects.Text;
text.setTint(index === this.optionIndex ? getColorNumber(Colors.Tan) : 0xffffff);
});
}
}

onSelectOption(option: string) {
if (this.dialog?.onSelected) {
this.dialog.onSelected(option, this.player, this.npc);
this.optionsContainer.removeAll(true);
}
}

updateDialog() {
Expand Down Expand Up @@ -145,4 +213,12 @@ export class Message extends GameObjects.Container {
}
return messages;
}

getOptions(): string[] | undefined {
let options = this.dialog?.options;
if (typeof options === 'function') {
options = options(this.player);
}
return options;
}
}
5 changes: 3 additions & 2 deletions src/scenes/Game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Player } from '../classes/Player';
import { DebugUI } from '../classes/UI/DebugUI';
import { Walls } from '../classes/Walls';
import { Warp } from '../classes/Warp';
import { NPCType, WarpType } from '../classes/types';
import { ItemType, NPCType, WarpType } from '../classes/types';
import { Config } from '../config';

export class Game extends Scene {
Expand Down Expand Up @@ -118,7 +118,8 @@ export class Game extends Scene {
}

createItems(): Item[] {
return [];
const gear = new Item(this, ItemType.Gear, this.player);
return [gear];
}

createEventListeners() {
Expand Down
28 changes: 20 additions & 8 deletions src/utils/dialog.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { NPC } from '../classes/NPC';
import { Player } from '../classes/Player';
import { ItemType, JournalEntry, NPCType, Quest, QuestType, WarpType } from '../classes/types';
import { updateWarpVisibility } from './interactionUtils';
import { updateSphinx, updateWarpVisibility } from './interactionUtils';
import { getSphinxAnswer, getSphinxHint, getSphinxOptions, getSphinxRiddle } from './riddles';

export interface NPCDialog {
Expand Down Expand Up @@ -56,7 +56,7 @@ const npcDialogs: Record<NPCType, NPCDialog[]> = {
{
messages: [
'I’ve heard rumors of a gear hidden deep in the Enchanted Forest. Beware of the forest’s',
'creatures and traps. I sometimes get lost myself.',
'creatures and traps. One time I thought I saw an ancient being, but it ran away.',
],
conditions: {
hasItem: ItemType.Wrench,
Expand All @@ -81,18 +81,30 @@ const npcDialogs: Record<NPCType, NPCDialog[]> = {
conditions: {
activeQuest: QuestType.SphinxRiddle,
},
onSelected: (option, player) => {
onSelected: (option, player, npc) => {
const answer = getSphinxAnswer(player.scene);
if (option === answer) {
player.quests.updateExistingQuest(QuestType.SphinxRiddle, true);
player.journal.addEntry(JournalEntry.SphinxRiddleSolved);
player.message.setDialog(
{
messages: [`That is correct. Well done, you may pass.`],
onCompleted: (player, npc) => {
player.quests.updateExistingQuest(QuestType.SphinxRiddle, true);
player.journal.addEntry(JournalEntry.SphinxRiddleSolved);
if (npc) updateSphinx(npc, true);
},
},
npc
);
} else if (option === 'I don’t know') {
player.message.setDialog({ messages: ['Come back when you have an answer for me.'] }, npc);
} else {
// TODO: Add back talking points so we can hide dialog in a different system that is reset
player.message.setDialog({ messages: ['That is not correct. Do not return.'] }, npc);
}
},
},
{
messages: [
'Welcome, brave soul. To pass, you must answer my riddle correctly. You may only answer once. Choose wisely."',
],
messages: ['Welcome, brave soul. To pass, you must answer my riddle. You may only answer once. Choose wisely.'],
onCompleted: (player) => {
player.quests.addQuest({ name: 'Solve the sphinx riddle', id: QuestType.SphinxRiddle, completed: false });
},
Expand Down
3 changes: 2 additions & 1 deletion src/utils/interactionUtils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { GameObjects, Physics, Scene } from 'phaser';

import { NPC, NPCData } from '../classes/NPC';
import { WallData } from '../classes/Walls';
import { Warp } from '../classes/Warp';
import { NPCType, WallType, WarpType } from '../classes/types';
import { Game } from '../scenes/Game';
Expand All @@ -12,7 +13,7 @@ export function updateSphinx(npc: NPC, complete?: boolean) {
const wall = getWall(scene, WallType.Sphinx);
if (wall) {
if (complete) {
wall.setX(wall.x);
wall.setX(WallData.find((data) => data.id === WallType.Sphinx)?.x || 0);
} else {
wall.setX(wall.x - 150);
}
Expand Down
6 changes: 5 additions & 1 deletion src/utils/riddles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ export function getSphinxRiddle(scene: Phaser.Scene): string[] {

export function getSphinxOptions(scene: Phaser.Scene): string[] {
const index = getRiddleIndex(scene);
return riddles[index].options;
const options = [...riddles[index].options];
const shuffled = options.sort(() => Math.random() - 0.5);
shuffled.push('I don’t know');

return shuffled;
}

export function getSphinxAnswer(scene: Phaser.Scene): string {
Expand Down

0 comments on commit a7b7421

Please sign in to comment.