diff --git a/src/app/components/interaction-canvas/interaction-canvas.component.html b/src/app/components/interaction-canvas/interaction-canvas.component.html
index d0490da..897a351 100644
--- a/src/app/components/interaction-canvas/interaction-canvas.component.html
+++ b/src/app/components/interaction-canvas/interaction-canvas.component.html
@@ -1,4 +1,4 @@
-
{{ chibi().state }}
+
{{ chibi().currentStateName }}
diff --git a/src/app/dexie/entities/chibis.ts b/src/app/dexie/entities/chibis.ts
index 1034dba..a0b33d2 100644
--- a/src/app/dexie/entities/chibis.ts
+++ b/src/app/dexie/entities/chibis.ts
@@ -29,7 +29,7 @@ export const CHIBIS: Chibi[] = [
constitution: 1000,
power: 1000,
maintenanceCals: 0,
- state: EChibiStateName.Sleeping
+ currentStateName: EChibiStateName.Sleeping
},
{
id: '238df3e7-3003-4471-91f5-a7ecf3151e18' as ChibiId,
@@ -48,6 +48,6 @@ export const CHIBIS: Chibi[] = [
constitution: 1000,
power: 1000,
maintenanceCals: 0,
- state: EChibiStateName.Idle
+ currentStateName: EChibiStateName.Idle
},
];
\ No newline at end of file
diff --git a/src/app/logic/chibi-behaviour/brains/aperio.brain.ts b/src/app/logic/chibi-behaviour/brains/aperio.brain.ts
index b6b5349..575a78a 100644
--- a/src/app/logic/chibi-behaviour/brains/aperio.brain.ts
+++ b/src/app/logic/chibi-behaviour/brains/aperio.brain.ts
@@ -13,8 +13,11 @@ export type ChibiInteraction = {
payload: T;
}
-type ResolutionFunction = (interaction: ChibiInteraction) => ChibiState;
-type InteractionRecord = Partial>;
+type InteractionResolutionFunction = (interaction: ChibiInteraction) => ChibiState;
+type InteractionRecord = Partial>;
+
+type ResolutionFunction = () => ChibiState | undefined;
+type ResolutionMap = { [key in EChibiStateName]: ResolutionFunction | undefined }
const MAX_TIME_AWAKE: number = 10;
@@ -38,7 +41,6 @@ export class Aperio implements IBrain {
private lastConsumedFoods: string[] = [];
private preferredFoods: string[] = [];
- private state: ChibiState = STATES[this.defaultState];
private interactionMap: InteractionMap = {
[EChibiStateName.Sleeping]: {
[EChibiInteraction.WakeUp]: (interaction: ChibiInteraction): ChibiState => this.wakeUp(interaction),
@@ -58,27 +60,45 @@ export class Aperio implements IBrain {
[EChibiStateName.Depressed]: undefined,
[EChibiStateName.Tired]: undefined
}
+ private resolutionMap: ResolutionMap = {
+ [EChibiStateName.Sleeping]: (): ChibiState | undefined => this.resolveSleeping(),
+ [EChibiStateName.Awake]: (): ChibiState | undefined => this.resolveAwake(),
+ [EChibiStateName.Snoring]: undefined,
+ [EChibiStateName.Nightmare]: undefined,
+ [EChibiStateName.Grumbling]: (): ChibiState | undefined => this.resolveGrumbling(),
+ [EChibiStateName.Bored]: undefined,
+ [EChibiStateName.Idle]: undefined,
+ [EChibiStateName.Exited]: undefined,
+ [EChibiStateName.Fighting]: undefined,
+ [EChibiStateName.Eating]: (): ChibiState | undefined => this.resolveEating(),
+ [EChibiStateName.Hungry]: undefined,
+ [EChibiStateName.Depressed]: undefined,
+ [EChibiStateName.Tired]: undefined
+ }
+
+ get state(): ChibiState {
+ return STATES[this.chibi.currentStateName];
+ }
init(chibi: Chibi, randomService: RandomService): void {
this.randomService = randomService;
this.chibi = chibi;
- this.state = STATES[chibi.state];
}
exist(): void {
this.timeInCurrentState++;
- //this sucks, resolve should be generic
- //stuff into an existMap which contains the resolve functions
- //then find correct function to execute the same way we do for interactions
- this.resolveAwake();
- this.resolveSleeping();
- this.resolveGrumbling();
- this.resolveEating();
+ const resolution = this.matchResolution(this.resolutionMap, STATES[this.chibi.currentStateName]);
+ if (resolution) {
+ const newState = resolution();
+ if (newState && newState != STATES[this.chibi.currentStateName]) {
+ this.changeState(newState);
+ }
+ }
}
resolveInteraction(interaction: ChibiInteraction): void {
this.timeSinceLastInteraction = 0;
- const resolution = this.matchInteraction(this.interactionMap, interaction.name, STATES[this.chibi.state]);
+ const resolution = this.matchInteraction(this.interactionMap, interaction.name, STATES[this.chibi.currentStateName]);
console.log('resolution', resolution);
console.log(`${this.chibi.name} should ${interaction.name} with payload: ${interaction.payload}`);
if (resolution) {
@@ -90,7 +110,7 @@ export class Aperio implements IBrain {
return isState(this.state, EChibiStateName.Awake);
}
- matchInteraction(map: InteractionMap, interaction: EChibiInteraction, state: ChibiState): ResolutionFunction | undefined {
+ matchInteraction(map: InteractionMap, interaction: EChibiInteraction, state: ChibiState): InteractionResolutionFunction | undefined {
const directMatch = map?.[state.name]?.[interaction];
if (directMatch) {
return directMatch;
@@ -101,53 +121,61 @@ export class Aperio implements IBrain {
return undefined;
}
+ matchResolution(map: ResolutionMap, state: ChibiState): ResolutionFunction | undefined {
+ const directMatch = map?.[state.name];
+ if (directMatch) {
+ return directMatch;
+ }
+ if (state.parent) {
+ return this.matchResolution(map, state.parent);
+ }
+ return undefined;
+ }
+
// resolvers
- // functions which auitomatically resolve based on the existence cycle
+ // functions which automatically resolve based on the existence cycle
- resolveAwake(): void {
- if (this.isAwake()) {
- console.log(`${this.chibi.name} is awake.`);
- this.timeSinceLastInteraction++;
- this.hasBeenAwakeFor++;
+ resolveAwake(): ChibiState | undefined {
+ console.log(`${this.chibi.name} is awake.`);
+ this.timeSinceLastInteraction++;
+ this.hasBeenAwakeFor++;
- if (this.timeInCurrentState % 10 === 0) {
- this.saddenedByNeglect(this.timeSinceLastInteraction, SADNESS_FROM_NEGLECT);
- }
-
- if (this.hasBeenAwakeFor > MAX_TIME_AWAKE) {
- this.changeState(STATE_SLEEPING);
- }
+ if (this.timeInCurrentState % 10 === 0) {
+ this.saddenedByNeglect(this.timeSinceLastInteraction, SADNESS_FROM_NEGLECT);
}
+
+ if (this.hasBeenAwakeFor > MAX_TIME_AWAKE) {
+ return STATE_SLEEPING;
+ }
+ return undefined;
}
- resolveSleeping(): void {
- if (isState(this.state, EChibiStateName.Sleeping)) {
- console.log(`${this.chibi.name} is sleeping.`);
- this.hasBeenAwakeFor = 0;
- this.increaseHappyness(HAPPINESS_FROM_SLEEP);
- const awakeChance = this.randomService.obtainRandom(2048);
- if (awakeChance.matchesChance(1)) {
- this.changeState(STATE_AWAKE);
- }
+ resolveSleeping(): ChibiState | undefined {
+ console.log(`${this.chibi.name} is sleeping.`);
+ this.hasBeenAwakeFor = 0;
+ this.increaseHappyness(HAPPINESS_FROM_SLEEP);
+ const awakeChance = this.randomService.obtainRandom(2048);
+ if (awakeChance.matchesChance(1)) {
+ return STATE_AWAKE;
}
+ return undefined;
}
- resolveGrumbling(): void {
- if (isState(this.state, EChibiStateName.Grumbling)) {
- console.log(`${this.chibi.name} is grumbling.`);
- if (this.timeInCurrentState > MAX_DURATION_GRUMBLE) {
- this.changeState(STATE_SLEEPING);
- }
+ resolveGrumbling(): ChibiState | undefined {
+ console.log(`${this.chibi.name} is grumbling. ${this.timeInCurrentState}`);
+ if (this.timeInCurrentState > MAX_DURATION_GRUMBLE) {
+ return STATE_SLEEPING;
}
+
+ return undefined;
}
- resolveEating(): void {
- if (isState(this.state, EChibiStateName.Eating)) {
- console.log(`${this.chibi.name} is eating.`);
- if (this.timeInCurrentState > MAX_DURATION_EATING) {
- this.changeState(STATES[this.previousState]);
- }
+ resolveEating(): ChibiState | undefined {
+ console.log(`${this.chibi.name} is eating. ${this.timeInCurrentState}`);
+ if (this.timeInCurrentState > MAX_DURATION_EATING) {
+ return STATE_IDLE;
}
+ return undefined;
}
@@ -163,8 +191,7 @@ export class Aperio implements IBrain {
private changeState(state: ChibiState): void {
this.previousState = this.state.name;
- this.state = state;
- this.chibi.state = this.state.name;
+ this.chibi.currentStateName = state.name;
this.timeInCurrentState = 0;
}
diff --git a/src/app/pages/interactions/interactions.component.ts b/src/app/pages/interactions/interactions.component.ts
index 99d17de..938fbdd 100644
--- a/src/app/pages/interactions/interactions.component.ts
+++ b/src/app/pages/interactions/interactions.component.ts
@@ -70,7 +70,7 @@ export class InteractionsComponent extends TranslateableComponent implements OnD
}
public isAwake(): boolean {
- return isState(STATES[this.chibi().state], EChibiStateName.Awake);
+ return isState(STATES[this.chibi().currentStateName], EChibiStateName.Awake);
}
public interact(interaction: EChibiInteraction, item?: Food): void {
@@ -78,7 +78,7 @@ export class InteractionsComponent extends TranslateableComponent implements OnD
this.brain.resolveInteraction({ name: interaction, payload: item } as ChibiInteraction);
}
-
+
public openFoodPantry(): void {
this.interactionMenuState.set(EInteractionMenuState.Pantry);
}
diff --git a/src/app/types/chibi/chibi.ts b/src/app/types/chibi/chibi.ts
index a237bb4..e3568e9 100644
--- a/src/app/types/chibi/chibi.ts
+++ b/src/app/types/chibi/chibi.ts
@@ -19,7 +19,7 @@ export type Chibi = {
spritePath: string;
experience: number;
unlocked: boolean;
- state: EChibiStateName;
+ currentStateName: EChibiStateName;
} & ChibiWellnessStats & ChibiTraits;
export type ChibiWellnessStats = {