inetraction stuff
This commit is contained in:
@@ -1 +1,12 @@
|
|||||||
|
<div class="h-full w-full absolute bg-red-300">
|
||||||
|
<div class="py-4 container mx-auto">
|
||||||
|
<div class="flex flex-row justify-between">
|
||||||
<p>food-pantry works!</p>
|
<p>food-pantry works!</p>
|
||||||
|
<ff-button (click)="onClose.emit(true)">X</ff-button>
|
||||||
|
</div>
|
||||||
|
<ff-grid
|
||||||
|
[gridItems]="foods()"
|
||||||
|
(onSelect)="onFoodChosen.emit($event)"
|
||||||
|
></ff-grid>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -1,10 +1,19 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component, inject, output, OutputEmitterRef, Signal } from '@angular/core';
|
||||||
|
import { ButtonComponent } from "../ui-elements/button/button.component";
|
||||||
|
import { Food } from '../../types/food';
|
||||||
|
import { FoodStore } from '../../api/food.store';
|
||||||
|
import { GridComponent } from "../grid/grid.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ff-food-pantry',
|
selector: 'ff-food-pantry',
|
||||||
imports: [],
|
imports: [ButtonComponent, GridComponent],
|
||||||
templateUrl: './food-pantry.component.html',
|
templateUrl: './food-pantry.component.html',
|
||||||
})
|
})
|
||||||
export class FoodPantryComponent {
|
export class FoodPantryComponent {
|
||||||
|
public readonly onClose: OutputEmitterRef<true> = output<true>();
|
||||||
|
public readonly onFoodChosen: OutputEmitterRef<Food> = output<Food>();
|
||||||
|
|
||||||
|
private readonly foodStore: FoodStore = inject(FoodStore);
|
||||||
|
|
||||||
|
protected readonly foods: Signal<Food[]> = this.foodStore.foods;
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/app/components/grid/grid.component.html
Normal file
12
src/app/components/grid/grid.component.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<div class="w-full flex flex-row flex-wrap gap-3">
|
||||||
|
@for (item of gridItems(); track $index) {
|
||||||
|
<div
|
||||||
|
(click)="onSelect.emit(item)"
|
||||||
|
class="rounded-lg bg-primary-400 cursor-pointer"
|
||||||
|
[ngStyle]="{
|
||||||
|
width: size() + 'rem',
|
||||||
|
height: size() + 'rem',
|
||||||
|
}"
|
||||||
|
></div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
23
src/app/components/grid/grid.component.spec.ts
Normal file
23
src/app/components/grid/grid.component.spec.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { GridComponent } from './grid.component';
|
||||||
|
|
||||||
|
describe('GridComponent', () => {
|
||||||
|
let component: GridComponent<any>;
|
||||||
|
let fixture: ComponentFixture<GridComponent<any>>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [GridComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(GridComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
14
src/app/components/grid/grid.component.ts
Normal file
14
src/app/components/grid/grid.component.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { NgStyle } from '@angular/common';
|
||||||
|
import { Component, input, InputSignal, output, OutputEmitterRef } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ff-grid',
|
||||||
|
imports: [NgStyle],
|
||||||
|
templateUrl: './grid.component.html',
|
||||||
|
})
|
||||||
|
export class GridComponent<T> {
|
||||||
|
public readonly gridItems: InputSignal<T[]> = input.required();
|
||||||
|
public readonly size: InputSignal<number> = input<number>(5);
|
||||||
|
|
||||||
|
public readonly onSelect: OutputEmitterRef<T> = output<T>();
|
||||||
|
}
|
||||||
@@ -1 +1,8 @@
|
|||||||
|
<div class="h-full w-full absolute bg-blue-300">
|
||||||
|
<div class="py-4 container mx-auto">
|
||||||
|
<div class="flex flex-row justify-between">
|
||||||
<p>inventory works!</p>
|
<p>inventory works!</p>
|
||||||
|
<ff-button (click)="onClose.emit()">X</ff-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component, output, OutputEmitterRef } from '@angular/core';
|
||||||
|
import { ButtonComponent } from "../ui-elements/button/button.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ff-inventory',
|
selector: 'ff-inventory',
|
||||||
imports: [],
|
imports: [ButtonComponent],
|
||||||
templateUrl: './inventory.component.html',
|
templateUrl: './inventory.component.html',
|
||||||
})
|
})
|
||||||
export class InventoryComponent {
|
export class InventoryComponent {
|
||||||
|
public readonly onClose: OutputEmitterRef<void> = output<void>();
|
||||||
|
public readonly onItemChosen: OutputEmitterRef<any> = output<any>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="rounded-lg bg-primary-500 hover:bg-primary-700 cursor-pointer text-white px-4 py-2"
|
class="rounded-lg bg-primary-500 hover:bg-primary-700 cursor-pointer text-white px-4 py-2 flex flex-row items-center justify-center"
|
||||||
>
|
>
|
||||||
<ng-content></ng-content>
|
<ng-content></ng-content>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
|
import { Chibi } from "../../types/chibi/chibi";
|
||||||
import { EChibiInteraction } from "../../types/chibi/chibi-interaction";
|
import { EChibiInteraction } from "../../types/chibi/chibi-interaction";
|
||||||
import { EChibiStateName } from "../../types/chibi/chibi-state-name";
|
import { Food } from "../../types/food";
|
||||||
|
|
||||||
export interface IBrain {
|
export interface IBrain {
|
||||||
|
|
||||||
//function for time passegs + autonomous state changes
|
//function for time passegs + autonomous state changes
|
||||||
|
exist(chibi: Chibi): void;
|
||||||
|
|
||||||
resolveInteraction(state: EChibiStateName, interaction: EChibiInteraction): EChibiStateName
|
resolveInteraction(chibi: Chibi, interaction: EChibiInteraction, item?: Food): void
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,29 @@
|
|||||||
|
import { Chibi } from "../../../types/chibi/chibi";
|
||||||
import { EChibiInteraction } from "../../../types/chibi/chibi-interaction";
|
import { EChibiInteraction } from "../../../types/chibi/chibi-interaction";
|
||||||
import { EChibiStateName } from "../../../types/chibi/chibi-state-name";
|
import { EChibiStateName } from "../../../types/chibi/chibi-state-name";
|
||||||
|
import { Food } from "../../../types/food";
|
||||||
import { IBrain } from "../brain";
|
import { IBrain } from "../brain";
|
||||||
|
|
||||||
export class Aperio implements IBrain {
|
export class Aperio implements IBrain {
|
||||||
resolveInteraction(state: EChibiStateName, interaction: EChibiInteraction): EChibiStateName {
|
|
||||||
switch (state) {
|
private hasBeenAwakeFor: number = 0;
|
||||||
case EChibiStateName.Sleeping: return this.resolveSleepingInteraction(interaction);
|
|
||||||
default: return EChibiStateName.Sleeping;
|
exist(chibi: Chibi): void {
|
||||||
|
console.log('Brain is braining');
|
||||||
|
if (!EChibiStateName.Sleeping) {
|
||||||
|
this.hasBeenAwakeFor++;
|
||||||
|
if (this.hasBeenAwakeFor > 60) {
|
||||||
|
chibi.state = EChibiStateName.Sleeping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resolveInteraction(chibi: Chibi, interaction: EChibiInteraction, item?: Food): void {
|
||||||
|
switch (chibi.state) {
|
||||||
|
case EChibiStateName.Sleeping: chibi.state = this.resolveSleepingInteraction(interaction); break;
|
||||||
|
case EChibiStateName.Awake: chibi.state = this.resolveAwakeInteraction(interaction, item); break;
|
||||||
|
default:
|
||||||
|
chibi.state = EChibiStateName.Sleeping; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,4 +56,11 @@ export class Aperio implements IBrain {
|
|||||||
}
|
}
|
||||||
return EChibiStateName.Sleeping;
|
return EChibiStateName.Sleeping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private resolveAwakeInteraction(interaction: EChibiInteraction, item?: Food): EChibiStateName {
|
||||||
|
if (EChibiInteraction.Feed) {
|
||||||
|
return EChibiStateName.Eating;
|
||||||
|
}
|
||||||
|
return EChibiStateName.Idle;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import { RouterLink } from "@angular/router";
|
import { RouterLink } from "@angular/router";
|
||||||
|
import { TranslateableComponent } from '../../components/translateable.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ff-home',
|
selector: 'ff-home',
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
@let shownMenu = interactionMenuState();
|
||||||
<div class="flex flex-col h-[100vh]">
|
<div class="flex flex-col h-[100vh]">
|
||||||
<div class="min-h-56 h-2/3 max-h-2/3">
|
<div class="min-h-56 h-2/3 max-h-2/3">
|
||||||
@if (chibi()) {
|
@if (chibi()) {
|
||||||
@@ -12,11 +13,26 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="h-1/3 min-h-20 bg-primary-300">
|
<div class="h-1/3 min-h-20 bg-primary-300 relative">
|
||||||
<ff-food-pantry></ff-food-pantry>
|
@if (shownMenu == EInteractionMenuState.Pantry) {
|
||||||
<ff-inventory></ff-inventory>
|
<ff-food-pantry
|
||||||
|
(onClose)="closeMenu()"
|
||||||
|
(onFoodChosen)="interact(EChibiInteraction.Feed, $event)"
|
||||||
|
></ff-food-pantry>
|
||||||
|
}
|
||||||
|
@if (shownMenu == EInteractionMenuState.Inventory) {
|
||||||
|
<ff-inventory (onClose)="closeMenu()"></ff-inventory>
|
||||||
|
}
|
||||||
|
<div class="flex flex-row gap-5 py-4 container mx-auto">
|
||||||
|
<ff-button (click)="openInventory()">{{
|
||||||
|
lang.game.actions.giveItem
|
||||||
|
}}</ff-button>
|
||||||
|
<ff-button (click)="openFoodPantry()">{{
|
||||||
|
lang.game.actions.feed
|
||||||
|
}}</ff-button>
|
||||||
<ff-button (click)="interact(EChibiInteraction.WakeUp)">{{
|
<ff-button (click)="interact(EChibiInteraction.WakeUp)">{{
|
||||||
lang.game.actions.wakeUp
|
lang.game.actions.wakeUp
|
||||||
}}</ff-button>
|
}}</ff-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Component, computed, effect, inject, input, InputSignal, Signal } from '@angular/core';
|
import { Component, computed, effect, inject, input, InputSignal, signal, Signal, WritableSignal } from '@angular/core';
|
||||||
import { HeaderComponent } from "../../components/ui-elements/header/header.component";
|
import { HeaderComponent } from "../../components/ui-elements/header/header.component";
|
||||||
import { ERouteKey } from '../../types/route-key';
|
import { ERouteKey } from '../../types/route-key';
|
||||||
import { Chibi, ChibiId } from '../../types/chibi/chibi';
|
import { Chibi, ChibiId } from '../../types/chibi/chibi';
|
||||||
@@ -11,6 +11,14 @@ import { EChibiInteraction } from '../../types/chibi/chibi-interaction';
|
|||||||
import { IBrain } from '../../logic/chibi-behaviour/brain';
|
import { IBrain } from '../../logic/chibi-behaviour/brain';
|
||||||
import { BRAIN_MAP } from '../../logic/chibi-behaviour/brain-map';
|
import { BRAIN_MAP } from '../../logic/chibi-behaviour/brain-map';
|
||||||
import { TranslateableComponent } from '../../components/translateable.component';
|
import { TranslateableComponent } from '../../components/translateable.component';
|
||||||
|
import { Food } from '../../types/food';
|
||||||
|
import { interval } from 'rxjs';
|
||||||
|
|
||||||
|
enum EInteractionMenuState {
|
||||||
|
Neutral,
|
||||||
|
Pantry,
|
||||||
|
Inventory
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ff-interactions',
|
selector: 'ff-interactions',
|
||||||
@@ -25,23 +33,41 @@ export class InteractionsComponent extends TranslateableComponent {
|
|||||||
protected readonly chibi: Signal<Chibi> = computed(() => {
|
protected readonly chibi: Signal<Chibi> = computed(() => {
|
||||||
return this.chibiStore.chibis().find((chibi: Chibi) => chibi.id === this.chibiId()) as Chibi;
|
return this.chibiStore.chibis().find((chibi: Chibi) => chibi.id === this.chibiId()) as Chibi;
|
||||||
});
|
});
|
||||||
|
protected readonly interactionMenuState: WritableSignal<EInteractionMenuState> = signal(EInteractionMenuState.Neutral);
|
||||||
|
|
||||||
|
protected readonly EInteractionMenuState: typeof EInteractionMenuState = EInteractionMenuState;
|
||||||
protected readonly ERouteKey: typeof ERouteKey = ERouteKey;
|
protected readonly ERouteKey: typeof ERouteKey = ERouteKey;
|
||||||
protected readonly EChibiInteraction: typeof EChibiInteraction = EChibiInteraction;
|
protected readonly EChibiInteraction: typeof EChibiInteraction = EChibiInteraction;
|
||||||
|
|
||||||
private brain!: IBrain;
|
private brain!: IBrain;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
super();
|
||||||
effect(() => {
|
effect(() => {
|
||||||
if (this.chibi()) {
|
if (this.chibi()) {
|
||||||
this.brain = BRAIN_MAP[this.chibi().name]!;
|
this.brain = BRAIN_MAP[this.chibi().name]!;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
interval(1000).subscribe(() => {
|
||||||
|
this.brain.exist(this.chibi());
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public interact(interaction: EChibiInteraction): void {
|
public interact(interaction: EChibiInteraction, item?: Food): void {
|
||||||
console.log(`${interaction} ${this.chibi().name}`);
|
console.log(`${interaction} ${this.chibi().name} and item ${item}`);
|
||||||
this.chibi().state = this.brain.resolveInteraction(this.chibi().state, interaction);
|
this.brain.resolveInteraction(this.chibi(), interaction, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openFoodPantry(): void {
|
||||||
|
this.interactionMenuState.set(EInteractionMenuState.Pantry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openInventory(): void {
|
||||||
|
this.interactionMenuState.set(EInteractionMenuState.Inventory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public closeMenu(): void {
|
||||||
|
this.interactionMenuState.set(EInteractionMenuState.Neutral);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ export const ENG_TRANSLATIONS: Translation = {
|
|||||||
foodPantry: {},
|
foodPantry: {},
|
||||||
inventory: {},
|
inventory: {},
|
||||||
actions: {
|
actions: {
|
||||||
wakeUp: 'Wake up!'
|
wakeUp: 'Wake up!',
|
||||||
|
feed: 'Feed',
|
||||||
|
giveItem: 'Give Item'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,6 +18,8 @@ export type Translation = {
|
|||||||
inventory: {},
|
inventory: {},
|
||||||
actions: {
|
actions: {
|
||||||
wakeUp: string;
|
wakeUp: string;
|
||||||
|
feed: string;
|
||||||
|
giveItem: string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user