GamesystemConditionEditor
All checks were successful
E2E Testing / test (push) Successful in 1m20s

This commit is contained in:
sebastian 2024-06-02 17:05:52 +02:00
parent 1c60504565
commit 1ffc5c1ecf
11 changed files with 221 additions and 5 deletions

View File

@ -110,6 +110,9 @@ import {
import { import {
CharacterInteractionEditorComponent CharacterInteractionEditorComponent
} from "./editor/character-editor/character-interaction-editor/character-interaction-editor.component"; } from "./editor/character-editor/character-interaction-editor/character-interaction-editor.component";
import {
GamesystemConditionEditorComponent
} from "./editor/interaction-editor/conditions/gamesystem-condition-editor/gamesystem-condition-editor.component";
// AoT requires an exported function for factories // AoT requires an exported function for factories
const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './assets/i18n/', '.json'); const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './assets/i18n/', '.json');
@ -145,7 +148,8 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl
CharacteristicSelectorComponent, CharacteristicSelectorComponent,
RequieredInheritancesEditorComponent, RequieredInheritancesEditorComponent,
RequieredInheritancesCreatorComponent, RequieredInheritancesCreatorComponent,
CharacterInteractionEditorComponent CharacterInteractionEditorComponent,
GamesystemConditionEditorComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,

View File

@ -107,7 +107,8 @@
<p>Inventory Conditions</p> <p>Inventory Conditions</p>
</mat-tab> </mat-tab>
<mat-tab label="Gamesystem Conditions"> <mat-tab label="Gamesystem Conditions">
<p>Gamesystem Conditions</p> <app-gamesystem-condition-editor [gamesystemConditions]="element.gamesystemConditions" [gamesystems]="gameModel!.gamesystemsAsList"
></app-gamesystem-condition-editor>
</mat-tab> </mat-tab>
</mat-tab-group> </mat-tab-group>
</mat-expansion-panel> </mat-expansion-panel>

View File

@ -0,0 +1,77 @@
<table mat-table [dataSource]="datasource" class="mat-elevation-z8">
<ng-container matColumnDef="characterDependency">
<th mat-header-cell *matHeaderCellDef>Dependency</th>
<td mat-cell *matCellDef="let condition">
@if(condition === editedCondition) {
<mat-form-field class="long-form" appearance="fill">
<mat-label>Character Dependency</mat-label>
<mat-select [(ngModel)]="editedCondition!.characterDependency">
<mat-option [value]="CharacterDependency.NONE">None</mat-option>
<mat-option [value]="CharacterDependency.SRC">Source</mat-option>
<mat-option [value]="CharacterDependency.TARGET">Target</mat-option>
</mat-select>
</mat-form-field>
} @else {
{{condition.characterDependency}}
}
</td>
</ng-container>
<ng-container matColumnDef="targetGamesystem">
<th mat-header-cell *matHeaderCellDef>Gamesystem</th>
<td mat-cell *matCellDef="let condition">
@if(condition === editedCondition) {
<mat-form-field class="long-form" appearance="fill">
<mat-label>Character Dependency</mat-label>
<mat-select [(ngModel)]="editedCondition!.targetGamesystem">
<mat-option *ngFor="let gamesystem of gamesystems" [value]="gamesystem">{{gamesystem.componentName}}</mat-option>
</mat-select>
</mat-form-field>
} @else {
@if(condition.targetGamesystem != undefined) {
{{condition.targetGamesystem.componentName}}
} @else {
<p>UNKNOWN GAMESYSTEM</p>
}
}
</td>
</ng-container>
<ng-container matColumnDef="requieredState">
<th mat-header-cell *matHeaderCellDef>State</th>
<td mat-cell *matCellDef="let condition">
@if(condition === editedCondition && editedCondition!.targetGamesystem != undefined) {
<mat-form-field appearance="fill" class="long-form">
<mat-select [(ngModel)]="editedCondition!.requieredState">
<mat-option *ngFor="let state of editedCondition!.targetGamesystem.states" [value]="state">{{state.computeStateLabel()}}</mat-option>
</mat-select>
</mat-form-field>
} @else {
@if(condition.requieredState != undefined) {
{{condition.requieredState.computeStateLabel()}}
} @else {
<p>UNKNOWN STATE</p>
}
}
</td>
</ng-container>
<ng-container matColumnDef="edit">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let condition">
<button mat-icon-button *ngIf="editedCondition === condition" (click)="finishEditingCondition()"><mat-icon>done</mat-icon></button>
<button mat-icon-button *ngIf="editedCondition != condition" [disabled]="editedCondition != undefined" (click)="editCondition(condition)"><mat-icon>edit</mat-icon></button>
</td>
</ng-container>
<ng-container matColumnDef="delete">
<th mat-header-cell *matHeaderCellDef>
<button mat-icon-button (click)="addCondition()"><mat-icon>addd</mat-icon></button>
</th>
<td mat-cell *matCellDef="let condition">
<button mat-icon-button color="warn" (click)="deleteCondition(condition)"><mat-icon>delete</mat-icon></button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

View File

@ -0,0 +1,3 @@
.mat-column-edit, .mat-column-delete {
width: 32px;
}

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { GamesystemConditionEditorComponent } from './gamesystem-condition-editor.component';
describe('GamesystemConditionEditorComponent', () => {
let component: GamesystemConditionEditorComponent;
let fixture: ComponentFixture<GamesystemConditionEditorComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [GamesystemConditionEditorComponent]
})
.compileComponents();
fixture = TestBed.createComponent(GamesystemConditionEditorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,68 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {GamesystemCondition} from "../../../../project/game-model/interactions/condition/GamesystemCondition";
import {MatSnackBar} from "@angular/material/snack-bar";
import {MatTableDataSource} from "@angular/material/table";
import {CharacterDependency} from "../../../../project/game-model/interactions/CharacterDependency";
import {Gamesystem} from "../../../../project/game-model/gamesystems/Gamesystem";
@Component({
selector: 'app-gamesystem-condition-editor',
templateUrl: './gamesystem-condition-editor.component.html',
styleUrl: './gamesystem-condition-editor.component.scss'
})
export class GamesystemConditionEditorComponent implements OnInit{
@Input() gamesystemConditions: GamesystemCondition[] = []
@Input() gamesystems: Gamesystem<any, any>[] = []
@Output("onConditionUpdate") gamesytemConditionChangeEmitter: EventEmitter<GamesystemCondition> = new EventEmitter();
@Output("onConditionDelete") gamesystemConditionDeleteEmitter: EventEmitter<GamesystemCondition> = new EventEmitter();
editedCondition: GamesystemCondition | undefined
addedCondition: GamesystemCondition | undefined
datasource: MatTableDataSource<GamesystemCondition> = new MatTableDataSource<GamesystemCondition>();
displayedColumns: string[] = ["characterDependency", "targetGamesystem", "requieredState", "edit", "delete"]
constructor(private snackbar: MatSnackBar) {
}
ngOnInit() {
this.datasource.data = this.gamesystemConditions;
}
editCondition(condition: GamesystemCondition) {
this.editedCondition = condition;
}
finishEditingCondition() {
if(this.editedCondition == undefined) {
return;
}
if(this.editedCondition!.validate()) {
if(this.editedCondition === this.addedCondition) {
this.gamesytemConditionChangeEmitter.emit(this.editedCondition);
this.addedCondition = undefined
}
this.editedCondition = undefined;
} else {
this.snackbar.open("Invalid Condition", "", {duration: 2000});
}
}
deleteCondition(condition: GamesystemCondition) {
this.gamesystemConditions = this.gamesystemConditions.filter(c => c !== condition);
this.datasource.data = this.gamesystemConditions;
this.gamesystemConditionDeleteEmitter.emit(condition);
}
addCondition() {
const condition = new GamesystemCondition(CharacterDependency.NONE, undefined, undefined);
this.gamesystemConditions.push(condition);
this.editedCondition = condition;
this.addedCondition = condition;
this.datasource.data = this.gamesystemConditions;
}
protected readonly CharacterDependency = CharacterDependency;
}

View File

@ -235,6 +235,21 @@ export class GameModel {
return result; return result;
} }
get gamesystemsAsList() {
let gamesystemQueue: Gamesystem<any, any>[] = this.gamesystems.concat();
const result: Gamesystem<any, any>[] = []
while(gamesystemQueue.length > 0) {
const currentGamesystem = gamesystemQueue.shift()!;
if(currentGamesystem instanceof ProductGamesystem) {
gamesystemQueue = gamesystemQueue.concat(currentGamesystem.innerGamesystems);
}
result.push(currentGamesystem);
}
return result;
}
addCharacter(character: Character) { addCharacter(character: Character) {
if(this.characters.find(c => c.componentName === character.componentName) === undefined) { if(this.characters.find(c => c.componentName === character.componentName) === undefined) {
this.characters.push(character) this.characters.push(character)

View File

@ -2,6 +2,7 @@ import {ProductTransition} from "../transitions/ProductTransition";
import {State} from "./State"; import {State} from "./State";
import {SimpleState} from "./SimpleState"; import {SimpleState} from "./SimpleState";
import {Transition} from "../transitions/Transition"; import {Transition} from "../transitions/Transition";
import {state} from "@angular/animations";
export class ProductState extends State<ProductTransition> { export class ProductState extends State<ProductTransition> {
innerStates: State<any>[] = []; innerStates: State<any>[] = [];
@ -50,4 +51,17 @@ export class ProductState extends State<ProductTransition> {
return false; return false;
} }
computeStateLabel(): string {
let stateLabel = "("
for(let i=0; i<this.innerStates.length; i++) {
stateLabel += this.innerStates[i].computeStateLabel();
if(i+1 < this.innerStates.length) {
stateLabel += ", ";
}
}
return stateLabel += ")";
}
} }

View File

@ -20,5 +20,10 @@ export class SimpleState extends State<SimpleTransition> {
return this.stateLabel === (state as SimpleState).stateLabel; return this.stateLabel === (state as SimpleState).stateLabel;
} }
computeStateLabel(): string {
return this.stateLabel
}
} }

View File

@ -47,4 +47,6 @@ export abstract class State<T extends Transition<any>> {
} }
abstract equals(state: State<Transition<any>>): boolean; abstract equals(state: State<Transition<any>>): boolean;
abstract computeStateLabel(): string
} }

View File

@ -4,13 +4,17 @@ import {Condition} from "./Condition";
import {CharacterDependency} from "../CharacterDependency"; import {CharacterDependency} from "../CharacterDependency";
export class GamesystemCondition extends Condition { export class GamesystemCondition extends Condition {
targetGamesystem: Gamesystem<any, any> targetGamesystem: Gamesystem<any, any> | undefined
requieredState: State<any>; requieredState: State<any> | undefined;
constructor(characterDependency: CharacterDependency, targetGamesystem: Gamesystem<any, any>, requieredState: State<any>) { constructor(characterDependency: CharacterDependency, targetGamesystem: Gamesystem<any, any> | undefined, requieredState: State<any> | undefined) {
super(characterDependency); super(characterDependency);
this.targetGamesystem = targetGamesystem; this.targetGamesystem = targetGamesystem;
this.requieredState = requieredState; this.requieredState = requieredState;
} }
validate(): boolean {
return this.targetGamesystem != undefined && this.requieredState != undefined;
}
} }