DRY questLog
This commit is contained in:
parent
b75dc078f9
commit
9a44605469
|
|
@ -19,19 +19,47 @@ export class QuestLog extends Component {
|
||||||
readonly #quests = new Map<string, QuestEntry>();
|
readonly #quests = new Map<string, QuestEntry>();
|
||||||
|
|
||||||
addQuest(quest: Quest): void {
|
addQuest(quest: Quest): void {
|
||||||
if (!this.#quests.has(quest.id)) {
|
if (this.#quests.has(quest.id)) {
|
||||||
|
console.warn(`[QuestLog] quest '${quest.id}' is already registered, ignoring duplicate`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.#quests.set(quest.id, { quest, state: { status: 'inactive', stageIndex: 0 } });
|
this.#quests.set(quest.id, { quest, state: { status: 'inactive', stageIndex: 0 } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#transition(op: string, questId: string, from: QuestStatus, to: QuestStatus, event: string): boolean {
|
||||||
|
const entry = this.#quests.get(questId);
|
||||||
|
if (!entry) {
|
||||||
|
console.warn(`[QuestLog] ${op}: quest '${questId}' is not registered`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (entry.state.status !== from) {
|
||||||
|
console.warn(`[QuestLog] ${op}: quest '${questId}' cannot transition from status '${entry.state.status}'`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
entry.state.status = to;
|
||||||
|
if (to === 'active' || to === 'inactive') entry.state.stageIndex = 0;
|
||||||
|
this.emit(event, { questId });
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
start(questId: string): boolean {
|
start(questId: string): boolean {
|
||||||
const entry = this.#quests.get(questId);
|
return this.#transition('start', questId, 'inactive', 'active', 'started');
|
||||||
if (!entry || entry.state.status !== 'inactive') return false;
|
}
|
||||||
entry.state.status = 'active';
|
|
||||||
entry.state.stageIndex = 0;
|
@action
|
||||||
this.emit('started', { questId });
|
complete(questId: string): boolean {
|
||||||
return true;
|
return this.#transition('complete', questId, 'active', 'completed', 'completed');
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
fail(questId: string): boolean {
|
||||||
|
return this.#transition('fail', questId, 'active', 'failed', 'failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
abandon(questId: string): boolean {
|
||||||
|
return this.#transition('abandon', questId, 'active', 'inactive', 'abandoned');
|
||||||
}
|
}
|
||||||
|
|
||||||
getState(questId: string): QuestRuntimeState | undefined {
|
getState(questId: string): QuestRuntimeState | undefined {
|
||||||
|
|
@ -46,25 +74,6 @@ export class QuestLog extends Component {
|
||||||
return quest.conditions.every(c => evaluateCondition(parseCondition(c), ctx));
|
return quest.conditions.every(c => evaluateCondition(parseCondition(c), ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
|
||||||
fail(questId: string): boolean {
|
|
||||||
const entry = this.#quests.get(questId);
|
|
||||||
if (!entry || entry.state.status !== 'active') return false;
|
|
||||||
entry.state.status = 'failed';
|
|
||||||
this.emit('failed', { questId });
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
|
||||||
abandon(questId: string): boolean {
|
|
||||||
const entry = this.#quests.get(questId);
|
|
||||||
if (!entry || entry.state.status !== 'active') return false;
|
|
||||||
entry.state.status = 'inactive';
|
|
||||||
entry.state.stageIndex = 0;
|
|
||||||
this.emit('abandoned', { questId });
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
getStage(questId: string): QuestStage | undefined {
|
getStage(questId: string): QuestStage | undefined {
|
||||||
const entry = this.#quests.get(questId);
|
const entry = this.#quests.get(questId);
|
||||||
if (!entry || entry.state.status !== 'active') return undefined;
|
if (!entry || entry.state.status !== 'active') return undefined;
|
||||||
|
|
@ -91,10 +100,7 @@ export class QuestLog extends Component {
|
||||||
|
|
||||||
/** @internal called by QuestSystem when a fail condition is met */
|
/** @internal called by QuestSystem when a fail condition is met */
|
||||||
_fail(questId: string): void {
|
_fail(questId: string): void {
|
||||||
const entry = this.#quests.get(questId);
|
this.#transition('_fail', questId, 'active', 'failed', 'failed');
|
||||||
if (!entry) return;
|
|
||||||
entry.state.status = 'failed';
|
|
||||||
this.emit('failed', { questId });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal called by QuestSystem after stage actions complete */
|
/** @internal called by QuestSystem after stage actions complete */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue