Introduce ItemQualities and PerQualitiyProperties
All checks were successful
E2E Testing / test (push) Successful in 1m32s

This commit is contained in:
Sebastian Böckelmann 2024-04-20 09:37:40 +02:00
parent 9dc5418d64
commit 69dce0b4f7
9 changed files with 212 additions and 17 deletions

View File

@ -61,7 +61,7 @@ import {
ProductStateEditorComponent ProductStateEditorComponent
} from "./editor/gamesystem-editor/state-editor/product-state-editor/product-state-editor.component"; } from "./editor/gamesystem-editor/state-editor/product-state-editor/product-state-editor.component";
import {MatTooltip} from "@angular/material/tooltip"; import {MatTooltip} from "@angular/material/tooltip";
import {MatCard, MatCardContent, MatCardHeader, MatCardTitle} from "@angular/material/card"; import {MatCard, MatCardActions, MatCardContent, MatCardHeader, MatCardTitle} from "@angular/material/card";
import { import {
ScriptaccountActionEditorComponent ScriptaccountActionEditorComponent
} from "./editor/gamesystem-editor/transition-editor/scriptaccount-action-editor/scriptaccount-action-editor.component"; } from "./editor/gamesystem-editor/transition-editor/scriptaccount-action-editor/scriptaccount-action-editor.component";
@ -181,6 +181,7 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl
MatExpansionPanelTitle, MatExpansionPanelTitle,
MatCardTitle, MatCardTitle,
MatExpansionPanelHeader, MatExpansionPanelHeader,
MatCardActions,
], ],
providers: [], providers: [],
bootstrap: [AppComponent] bootstrap: [AppComponent]

View File

@ -1,3 +1,19 @@
<mat-card>
<mat-card-header>
<mat-card-title>Item Qualtities</mat-card-title>
</mat-card-header>
<mat-card-content>
<mat-accordion>
<mat-expansion-panel *ngFor="let quality of item!.possible_qualities">
<mat-expansion-panel-header>
<mat-panel-title>{{quality.quality_step}}</mat-panel-title>
</mat-expansion-panel-header>
<app-item-property-editor #perQualityPropertyEditors [item]="item" [quality]="quality"></app-item-property-editor>
</mat-expansion-panel>
</mat-accordion>
</mat-card-content>
</mat-card>
<mat-card> <mat-card>
<mat-card-header> <mat-card-header>
<mat-card-title>Item Characteristics</mat-card-title> <mat-card-title>Item Characteristics</mat-card-title>
@ -6,3 +22,53 @@
<app-item-property-editor [item]="item"></app-item-property-editor> <app-item-property-editor [item]="item"></app-item-property-editor>
</mat-card-content> </mat-card-content>
</mat-card> </mat-card>
<mat-card>
<mat-card-header>
<mat-card-title>Item Quality Characteristics</mat-card-title>
</mat-card-header>
<mat-card-content>
<table mat-table [dataSource]="datasource" class="mat-elevation-z8">
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>Name</th>
<td mat-cell *matCellDef="let itemProperty">
<span *ngIf="itemProperty !== editedProperty">{{itemProperty.propertyName}}</span>
<mat-form-field appearance="fill" *ngIf="itemProperty === editedProperty">
<mat-label>Name</mat-label>
<input matInput [(ngModel)]="itemProperty.propertyName">
</mat-form-field>
</td>
</ng-container>
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef>Description</th>
<td mat-cell *matCellDef="let itemProperty">
<span *ngIf="itemProperty !== editedProperty">{{itemProperty.propertyDescription}}</span>
<mat-form-field appearance="fill" *ngIf="itemProperty === editedProperty">
<mat-label>Name</mat-label>
<input matInput [(ngModel)]="itemProperty.propertyDescription">
</mat-form-field>
</td>
</ng-container>
<ng-container matColumnDef="edit">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let itemProperty">
<button *ngIf="editedProperty == undefined" mat-icon-button (click)="editPerQualityProperty(itemProperty)"><mat-icon>edit</mat-icon></button>
<button *ngIf="editedProperty !== undefined" mat-icon-button (click)="finishEditing()"><mat-icon>done</mat-icon></button>
</td>
</ng-container>
<ng-container matColumnDef="delete">
<th mat-header-cell *matHeaderCellDef>
<button mat-icon-button (click)="addQualityProperty()"><mat-icon>add</mat-icon></button>
</th>
<td mat-cell *matCellDef="let itemProperty">
<button mat-icon-button color="warn" (click)="deletePerQualityProperty(itemProperty)"><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>
</mat-card-content>
</mat-card>

View File

@ -0,0 +1,7 @@
table {
width: 100%;
}
.mat-column-edit, .mat-column-delete {
width: 32px;
}

View File

@ -1,17 +1,58 @@
import {Component, Input} from '@angular/core'; import {Component, ElementRef, Input, OnInit, ViewChildren} from '@angular/core';
import {Character} from "../../project/game-model/characters/Character"; import {Character} from "../../project/game-model/characters/Character";
import {GameModel} from "../../project/game-model/GameModel"; import {GameModel} from "../../project/game-model/GameModel";
import {Item} from "../../project/game-model/inventory/Item"; import {Item} from "../../project/game-model/inventory/Item";
import {MatCard, MatCardContent, MatCardHeader} from "@angular/material/card"; import {MatCard, MatCardContent, MatCardHeader} from "@angular/material/card";
import {ItemPropertyDescription} from "../../project/game-model/inventory/ItemPropertyDescription";
import {ItemPropertyEditorComponent} from "./item-property-editor/item-property-editor.component";
import {MatTableDataSource} from "@angular/material/table";
@Component({ @Component({
selector: 'app-inventory-item-editor', selector: 'app-inventory-item-editor',
templateUrl: './inventory-item-editor.component.html', templateUrl: './inventory-item-editor.component.html',
styleUrl: './inventory-item-editor.component.scss' styleUrl: './inventory-item-editor.component.scss'
}) })
export class InventoryItemEditorComponent { export class InventoryItemEditorComponent implements OnInit{
@Input() item: Item | undefined; @Input() item: Item | undefined;
@Input() gameModel: GameModel | undefined; @Input() gameModel: GameModel | undefined;
@ViewChildren('perQualityPropertyEditors') perQualityPropertyEditors: ItemPropertyEditorComponent[] = [];
displayedColumns: string[] = ['name', 'description', 'edit', 'delete']
editedProperty: ItemPropertyDescription | undefined
datasource: MatTableDataSource<ItemPropertyDescription> = new MatTableDataSource<ItemPropertyDescription>()
ngOnInit() {
this.datasource.data = this.item!.perQualityProperties
}
deletePerQualityProperty(itemProperty: ItemPropertyDescription) {
this.item!.removePerQualityProperty(itemProperty);
this.datasource.data = this.item!.perQualityProperties
this.perQualityPropertyEditors.forEach(component => component.updatedDisplayedData())
}
editPerQualityProperty(itemProperty: ItemPropertyDescription) {
this.editedProperty = itemProperty
}
finishEditing() {
if(this.editedProperty!.propertyName.length > 0) {
this.item!.editPerQualityProperty(this.editedProperty!);
this.editedProperty = undefined;
this.perQualityPropertyEditors.forEach(component => component.updatedDisplayedData())
}
}
addQualityProperty() {
const qualityDescription = new ItemPropertyDescription("New Property", "")
this.item!.addPerQualityProperty(qualityDescription);
this.datasource.data = this.item!.perQualityProperties
this.editedProperty = qualityDescription;
this.perQualityPropertyEditors.forEach(component => component.updatedDisplayedData())
}
} }

View File

@ -2,8 +2,8 @@
<ng-container matColumnDef="name"> <ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>Name</th> <th mat-header-cell *matHeaderCellDef>Name</th>
<td mat-cell *matCellDef="let itemProperty"> <td mat-cell *matCellDef="let itemProperty">
<span *ngIf="editedItemProperty !== itemProperty"> {{itemProperty.propertyName}}</span> <span *ngIf="editedItemProperty !== itemProperty || quality != undefined"> {{itemProperty.propertyName}}</span>
<mat-form-field appearance="fill" *ngIf="editedItemProperty === itemProperty"> <mat-form-field appearance="fill" *ngIf="editedItemProperty === itemProperty && quality == undefined">
<mat-label>Name</mat-label> <mat-label>Name</mat-label>
<input matInput [(ngModel)]="itemProperty.propertyName"> <input matInput [(ngModel)]="itemProperty.propertyName">
</mat-form-field> </mat-form-field>
@ -14,8 +14,8 @@
<ng-container matColumnDef="expandedDetail"> <ng-container matColumnDef="expandedDetail">
<td mat-cell *matCellDef="let element" [attr.colspan]="columnsToDisplayWithExpand.length"> <td mat-cell *matCellDef="let element" [attr.colspan]="columnsToDisplayWithExpand.length">
<div class="example-element-detail" [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'"> <div class="example-element-detail" [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
<p *ngIf="editedItemProperty !== element">{{element.propertyDescription}}</p> <p *ngIf="editedItemProperty !== element || quality != undefined">{{element.propertyDescription}}</p>
<mat-form-field appearance="fill" class="long-form" *ngIf="editedItemProperty === element"> <mat-form-field appearance="fill" class="long-form" *ngIf="editedItemProperty === element && quality == undefined">
<mat-label>Description</mat-label> <mat-label>Description</mat-label>
<textarea matInput [(ngModel)]="element.propertyDescription" rows="3"></textarea> <textarea matInput [(ngModel)]="element.propertyDescription" rows="3"></textarea>
</mat-form-field> </mat-form-field>
@ -46,13 +46,13 @@
<ng-container matColumnDef="delete"> <ng-container matColumnDef="delete">
<th mat-header-cell *matHeaderCellDef></th> <th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let itemProperty"> <td mat-cell *matCellDef="let itemProperty">
<button mat-icon-button color="warn" (click)="deleteItemProperty(itemProperty)"><mat-icon>delete</mat-icon></button> <button *ngIf="quality == undefined" mat-icon-button color="warn" (click)="deleteItemProperty(itemProperty)"><mat-icon>delete</mat-icon></button>
</td> </td>
</ng-container> </ng-container>
<ng-container matColumnDef="expand"> <ng-container matColumnDef="expand">
<th mat-header-cell *matHeaderCellDef aria-label="row actions"> <th mat-header-cell *matHeaderCellDef aria-label="row actions">
<button mat-icon-button [disabled]="editedItemProperty !== undefined" (click)="addItemProperty()"><mat-icon>add</mat-icon></button> <button *ngIf="quality == undefined" mat-icon-button [disabled]="editedItemProperty !== undefined" (click)="addItemProperty()"><mat-icon>add</mat-icon></button>
</th> </th>
<td mat-cell *matCellDef="let element"> <td mat-cell *matCellDef="let element">
<button mat-icon-button aria-label="expand row" (click)="(expandedElement = expandedElement === element ? null : element); $event.stopPropagation()"> <button mat-icon-button aria-label="expand row" (click)="(expandedElement = expandedElement === element ? null : element); $event.stopPropagation()">

View File

@ -4,6 +4,7 @@ import {MatTableDataSource} from "@angular/material/table";
import {ItemProperty} from "../../../project/game-model/inventory/ItemProperty"; import {ItemProperty} from "../../../project/game-model/inventory/ItemProperty";
import {animate, state, style, transition, trigger} from "@angular/animations"; import {animate, state, style, transition, trigger} from "@angular/animations";
import {MatSnackBar} from "@angular/material/snack-bar"; import {MatSnackBar} from "@angular/material/snack-bar";
import {ItemQuality} from "../../../project/game-model/inventory/ItemQuality";
@Component({ @Component({
selector: 'app-item-property-editor', selector: 'app-item-property-editor',
@ -20,6 +21,7 @@ import {MatSnackBar} from "@angular/material/snack-bar";
export class ItemPropertyEditorComponent implements OnInit{ export class ItemPropertyEditorComponent implements OnInit{
@Input() item: Item | undefined @Input() item: Item | undefined
@Input() quality: ItemQuality | undefined
editedItemProperty: ItemProperty | undefined editedItemProperty: ItemProperty | undefined
expandedElement: ItemProperty | undefined expandedElement: ItemProperty | undefined
@ -32,12 +34,19 @@ export class ItemPropertyEditorComponent implements OnInit{
} }
ngOnInit() { ngOnInit() {
this.datasource.data = this.item!.itemProperties this.updatedDisplayedData()
} }
deleteItemProperty(itemProperty: ItemProperty) { deleteItemProperty(itemProperty: ItemProperty) {
if(this.quality == undefined) {
this.item!.itemProperties = this.item!.itemProperties.filter(property => property.propertyName !== itemProperty.propertyName) this.item!.itemProperties = this.item!.itemProperties.filter(property => property.propertyName !== itemProperty.propertyName)
this.datasource.data = this.item!.itemProperties this.datasource.data = this.item!.itemProperties
} else {
this.quality.quality_propertes = this.quality.quality_propertes.filter(property => property.propertyName !== itemProperty.propertyName)
this.datasource.data = this.quality.quality_propertes;
}
} }
editItemProperty(itemProperty: ItemProperty) { editItemProperty(itemProperty: ItemProperty) {
@ -53,9 +62,21 @@ export class ItemPropertyEditorComponent implements OnInit{
} }
addItemProperty() { addItemProperty() {
if(this.quality == undefined) {
const itemProperty = new ItemProperty("New Property", "", 0); const itemProperty = new ItemProperty("New Property", "", 0);
this.item!.itemProperties.push(itemProperty); this.item!.itemProperties.push(itemProperty);
this.datasource.data = this.item!.itemProperties; this.datasource.data = this.item!.itemProperties;
this.editedItemProperty = itemProperty; this.editedItemProperty = itemProperty;
} }
}
updatedDisplayedData() {
if(this.quality != undefined) {
this.datasource.data = this.quality!.quality_propertes
this.displayedColumns = ['name', 'property', 'edit']
this.columnsToDisplayWithExpand = [...this.displayedColumns, 'expand'];
} else {
this.datasource.data = this.item!.itemProperties
}
}
} }

View File

@ -2,15 +2,43 @@ import {ItemProperty} from "./ItemProperty";
import {ItemQuality} from "./ItemQuality"; import {ItemQuality} from "./ItemQuality";
import {ModelComponent} from "../ModelComponent"; import {ModelComponent} from "../ModelComponent";
import {ModelComponentType} from "../ModelComponentType"; import {ModelComponentType} from "../ModelComponentType";
import {ItemPropertyDescription} from "./ItemPropertyDescription";
export class Item extends ModelComponent { export class Item extends ModelComponent {
possible_qualities: ItemQuality[] = [] possible_qualities: ItemQuality[] = []
itemProperties: ItemProperty[] = [] itemProperties: ItemProperty[] = []
perQualityProperties: ItemPropertyDescription[] = []
constructor(componentName: string, componentDescription: string, type: ModelComponentType) { constructor(componentName: string, componentDescription: string, type: ModelComponentType) {
super(componentName, componentDescription, type); super(componentName, componentDescription, type);
this.itemProperties.push(new ItemProperty("Weight", "Some Weights", 10)) this.itemProperties.push(new ItemProperty("Weight", "Some Weights", 10))
this.possible_qualities.push(new ItemQuality(0.25))
this.possible_qualities.push(new ItemQuality(0.50))
this.possible_qualities.push(new ItemQuality(0.75))
this.possible_qualities.push(new ItemQuality(1.00))
this.addPerQualityProperty(new ItemPropertyDescription("Price", "Price to buy item"))
}
removePerQualityProperty(qualityProperty: ItemPropertyDescription) {
this.perQualityProperties = this.perQualityProperties.filter(perQualityProperty => perQualityProperty !== qualityProperty);
this.possible_qualities.forEach(quality => {
quality.removeQualityProperty(qualityProperty.propertyName);
})
}
addPerQualityProperty(qualityProperty: ItemPropertyDescription) {
if(this.perQualityProperties.find(property => property.propertyName === qualityProperty.propertyName) == undefined) {
this.perQualityProperties.push(qualityProperty);
this.possible_qualities.forEach(quality => quality.addQualityProperty(qualityProperty))
}
}
editPerQualityProperty(qualityProperty: ItemPropertyDescription) {
this.possible_qualities.forEach(quality => {
quality.editQualityProperty(qualityProperty, this.perQualityProperties.map(property => property.propertyName))
})
} }
} }

View File

@ -0,0 +1,10 @@
export class ItemPropertyDescription {
propertyName: string;
propertyDescription: string;
constructor(propertyName: string, propertyDescription: string) {
this.propertyName = propertyName;
this.propertyDescription = propertyDescription;
}
}

View File

@ -1,9 +1,30 @@
import {ItemProperty} from "./ItemProperty";
import {ItemPropertyDescription} from "./ItemPropertyDescription";
export class ItemQuality { export class ItemQuality {
quality_step: number quality_step: number
quality_propertes: ItemQuality[] = [] quality_propertes: ItemProperty[] = []
constructor(quality_step: number) { constructor(quality_step: number) {
this.quality_step = quality_step; this.quality_step = quality_step;
} }
removeQualityProperty(propertyName: string) {
this.quality_propertes = this.quality_propertes.filter(qualityProperty => qualityProperty.propertyName !== propertyName);
}
addQualityProperty(qualityProperty: ItemPropertyDescription) {
this.quality_propertes.push(new ItemProperty(qualityProperty.propertyName, qualityProperty.propertyDescription, 0));
}
editQualityProperty(qualityProperty: ItemPropertyDescription, knownProperties: string[]) {
const affectedProperty = this.quality_propertes.find(property => !knownProperties.includes(property.propertyName) )
if(affectedProperty != undefined) {
affectedProperty!.propertyName = qualityProperty.propertyName;
affectedProperty!.propertyDescription = qualityProperty.propertyDescription;
} else {
console.log("Property was not found")
}
}
} }