interaction map type

This commit is contained in:
2026-03-15 13:10:13 +01:00
parent 621659a352
commit 57b753a6b5
7 changed files with 2854 additions and 9 deletions

2780
bun.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,16 @@
import { Chibi } from "../../types/chibi/chibi";
import { EChibiInteraction } from "../../types/chibi/chibi-interaction";
import { Food } from "../../types/food";
import { RandomService } from "../random.service";
export interface IBrain {
init(chibi: Chibi): void;
// function to set up the initial state
init(chibi: Chibi, randomService: RandomService): void;
// function for time passegs + autonomous state changes
exist(): void;
// function which resolves all interactions
resolveInteraction(interaction: EChibiInteraction, item?: Food): void
}

View File

@@ -3,17 +3,46 @@ import { EChibiInteraction } from "../../../types/chibi/chibi-interaction";
import { ChibiState, isState, STATE_AWAKE, STATE_EATING, STATE_IDLE, STATE_SLEEPING, STATES } from "../../../types/chibi/chibi-state";
import { EChibiStateName } from "../../../types/chibi/chibi-state-name";
import { Food } from "../../../types/food";
import { RandomService } from "../../random.service";
import { IBrain } from "../brain";
type InteractionRecord = Partial<Record<EChibiInteraction, ((interaction: EChibiInteraction) => ChibiState)>>;
const MAX_TIME_AWAKE: number = 3;
export class Aperio implements IBrain {
private randomService!: RandomService;
private chibi!: Chibi;
private hasBeenAwakeFor: number = 0;
private state!: ChibiState;
init(chibi: Chibi): void {
public readonly defaultState: EChibiStateName = EChibiStateName.Sleeping;
public readonly interactionMap: { [key in EChibiStateName]: InteractionRecord | undefined } = {
[EChibiStateName.Sleeping]: {
[EChibiInteraction.WakeUp]: this.resolveSleepingInteraction,
},
[EChibiStateName.Awake]: undefined,
[EChibiStateName.Snoring]: undefined,
[EChibiStateName.Nightmare]: undefined,
[EChibiStateName.Grumbling]: undefined,
[EChibiStateName.Bored]: undefined,
[EChibiStateName.Idle]: undefined,
[EChibiStateName.Exited]: undefined,
[EChibiStateName.Fighting]: undefined,
[EChibiStateName.Eating]: undefined,
[EChibiStateName.Hungry]: undefined,
[EChibiStateName.Depressed]: undefined,
[EChibiStateName.Tired]: undefined
}
//needed: some sort of legal interactions map
//uses stateNames as keys
//then submap the interactions
//behind every interaction is a dedicated function
init(chibi: Chibi, randomService: RandomService): void {
this.randomService = randomService;
this.chibi = chibi;
this.state = STATES[chibi.state];
}
@@ -43,8 +72,7 @@ export class Aperio implements IBrain {
/*
pear mostly sleeps
1/128 chance of waking her
12/128 chance of her doing a grumble and going back to sleep
visiting caethya will wake her up and go into lovey-dovey mode
she has a 1/2048 chance of waking up on her own
pears happyness goes up when she sleeps
@@ -65,8 +93,14 @@ export class Aperio implements IBrain {
*/
private resolveSleepingInteraction(interaction: EChibiInteraction): ChibiState {
if (EChibiInteraction.WakeUp) {
return STATE_AWAKE;
const willwakeUp = this.randomService.matchesChance(1, 128);
/*
1/128 chance of waking her
12/128 chance of her doing a grumble and going back to sleep
*/
console.log('will wake up', willwakeUp);
if (EChibiInteraction.WakeUp && willwakeUp) {
return STATE_IDLE;
}
return STATE_SLEEPING;
}

View File

@@ -0,0 +1,18 @@
import { Injectable } from "@angular/core";
@Injectable({ providedIn: 'root' })
export class RandomService {
private rollRandom(min: number, max: number): number {
return Math.floor(Math.random() * (max - min) + min);
}
public matchesChance(chance: number, max: number): boolean {
const random = this.rollRandom(0, max);
console.log(random, chance);
if (random < chance) {
return true;
}
return false;
}
}

View File

@@ -14,6 +14,7 @@ import { TranslateableComponent } from '../../components/translateable.component
import { Food } from '../../types/food';
import { interval } from 'rxjs';
import { ChibiState, STATES } from '../../types/chibi/chibi-state';
import { RandomService } from '../../logic/random.service';
enum EInteractionMenuState {
Neutral,
@@ -32,6 +33,7 @@ export class InteractionsComponent extends TranslateableComponent {
public readonly chibiId: InputSignal<ChibiId> = input.required<ChibiId>();
private readonly chibiStore: ChibiStore = inject(ChibiStore);
private readonly randomService: RandomService = inject(RandomService);
protected readonly chibi: Signal<Chibi> = computed(() => {
return this.chibiStore.chibis().find((chibi: Chibi) => chibi.id === this.chibiId()) as Chibi;
@@ -49,7 +51,7 @@ export class InteractionsComponent extends TranslateableComponent {
effect(() => {
if (this.chibi()) {
this.brain = BRAIN_MAP[this.chibi().name]!;
this.brain.init(this.chibi());
this.brain.init(this.chibi(), this.randomService);
}
})
interval(THINKING_INTERVAL).subscribe(() => {

View File

@@ -11,4 +11,5 @@ export enum EChibiStateName {
Eating = 'Eating',
Hungry = 'Hunry',
Depressed = 'Depressed',
Tired = 'Tired',
}

View File

@@ -40,6 +40,11 @@ export const STATE_EATING: ChibiState = {
parent: STATE_AWAKE
}
export const STATE_TIRED: ChibiState = {
name: EChibiStateName.Tired,
parent: STATE_AWAKE
}
export const STATE_BORED: ChibiState = {
name: EChibiStateName.Bored,
parent: STATE_AWAKE
@@ -86,5 +91,6 @@ export const STATES: Record<EChibiStateName, ChibiState> = {
[EChibiStateName.Fighting]: STATE_FIGHTING,
[EChibiStateName.Eating]: STATE_EATING,
[EChibiStateName.Hungry]: STATE_HUNGRY,
[EChibiStateName.Depressed]: STATE_DEPRESSED
[EChibiStateName.Depressed]: STATE_DEPRESSED,
[EChibiStateName.Tired]: STATE_TIRED
}