Specify Gamesystems for Characters

This commit is contained in:
Sebastian Böckelmann 2024-04-11 14:21:50 +02:00
parent 9d530e48f9
commit bf757c2069
11 changed files with 155 additions and 10 deletions

View File

@ -61,7 +61,7 @@ import {
ProductStateEditorComponent
} from "./editor/gamesystem-editor/state-editor/product-state-editor/product-state-editor.component";
import {MatTooltip} from "@angular/material/tooltip";
import {MatCard, MatCardContent, MatCardHeader} from "@angular/material/card";
import {MatCard, MatCardContent, MatCardHeader, MatCardTitle} from "@angular/material/card";
import {
ScriptaccountActionEditorComponent
} from "./editor/gamesystem-editor/transition-editor/scriptaccount-action-editor/scriptaccount-action-editor.component";
@ -70,7 +70,8 @@ import {
} from "./editor/gamesystem-editor/scriptaccount-condition-editor/scriptaccount-condition-editor.component";
import {CharacterOverviewComponent} from "./side-overviews/character-overview/character-overview.component";
import {CharacterEditorComponent} from "./editor/character-editor/character-editor.component";
import {MatAccordion, MatExpansionPanel} from "@angular/material/expansion";
import {MatAccordion, MatExpansionPanel, MatExpansionPanelHeader} from "@angular/material/expansion";
import {TemplateCreatorComponent} from "./editor/gamesystem-editor/template-creator/template-creator.component";
// AoT requires an exported function for factories
const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './assets/i18n/', '.json');
@ -94,7 +95,8 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl
ScriptaccountActionEditorComponent,
ScriptaccountConditionEditorComponent,
CharacterOverviewComponent,
CharacterEditorComponent
CharacterEditorComponent,
TemplateCreatorComponent
],
imports: [
BrowserModule,
@ -154,7 +156,9 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl
MatCardContent,
MatCardHeader,
MatAccordion,
MatExpansionPanel
MatExpansionPanel,
MatCardTitle,
MatExpansionPanelHeader
],
providers: [],
bootstrap: [AppComponent]

View File

@ -8,5 +8,6 @@
<mat-expansion-panel-header>{{gamesystem.componentName}}</mat-expansion-panel-header>
</mat-expansion-panel>
</mat-accordion>
<button mat-stroked-button style="width: 100%; margin-top: 10px" (click)="onOpenTemplateCreator()">Add Gamesystem</button>
</mat-card-content>
</mat-card>

View File

@ -1,6 +1,9 @@
import {Component, Input} from '@angular/core';
import {Character} from "../../project/game-model/characters/Character";
import {GameModel} from "../../project/game-model/GameModel";
import {MatDialog} from "@angular/material/dialog";
import {TemplateCreatorComponent} from "../gamesystem-editor/template-creator/template-creator.component";
import {TemplateType} from "../../project/game-model/TemplateType";
@Component({
selector: 'app-character-editor',
@ -11,4 +14,20 @@ export class CharacterEditorComponent {
@Input() character: Character | undefined
@Input() gameModel: GameModel | undefined
constructor(private dialog: MatDialog) {
}
onOpenTemplateCreator() {
const dialogRef = this.dialog.open(TemplateCreatorComponent, {
data: this.gameModel!.listGamesystems(TemplateType.CHARACTER),
minWidth: "400px"
})
dialogRef.afterClosed().subscribe(res => {
if(res != undefined) {
this.character!.addCharacterSpecificGamesystem(res)
}
})
}
}

View File

@ -0,0 +1,13 @@
<h1 mat-dialog-title>Specify Gamesystem</h1>
<div matDialogContent>
<mat-form-field appearance="outline" style="width: 100%">
<mat-label>Referencesystem</mat-label>
<mat-select [formControl]="templateCtrl">
<mat-option *ngFor="let gamesystem of templateGamesystems" [value]="gamesystem">{{gamesystem.componentName}}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div matDialogActions align="end">
<button mat-stroked-button (click)="cancel()">Cancel</button>
<button mat-raised-button color="accent" (click)="save()">Specify</button>
</div>

View File

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

View File

@ -0,0 +1,26 @@
import {Component, Inject} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef, MatDialogTitle} from "@angular/material/dialog";
import {SimpleTemplateGamesystem} from "../../../project/game-model/gamesystems/SimpleTemplateGamesystem";
import {FormControl, Validators} from "@angular/forms";
@Component({
selector: 'app-template-creator',
templateUrl: './template-creator.component.html',
styleUrl: './template-creator.component.scss'
})
export class TemplateCreatorComponent {
templateCtrl = new FormControl('', [Validators.required]);
constructor(@Inject(MAT_DIALOG_DATA) public templateGamesystems: SimpleTemplateGamesystem<any>[],
private dialogRef: MatDialogRef<TemplateCreatorComponent>) {
}
cancel() {
this.dialogRef.close();
}
save() {
this.dialogRef.close(this.templateCtrl.value)
}
}

View File

@ -9,6 +9,7 @@ import {TemplateType} from "./TemplateType";
import {SimpleTemplateGamesystem} from "./gamesystems/SimpleTemplateGamesystem";
export class GameModel {
gameModelName: string
gamesystems: Gamesystem<any, any>[] = [];
@ -121,4 +122,25 @@ export class GameModel {
}
})
}
listGamesystems(templateType: TemplateType): SimpleTemplateGamesystem<any>[] {
const gamesystemList: SimpleTemplateGamesystem<any>[] = []
const gamesystemQueue: Gamesystem<any, any>[] = this.gamesystems.concat()
while(gamesystemQueue.length > 0) {
const currentGamesystem = gamesystemQueue.shift()!;
if(currentGamesystem.templateType === templateType) {
gamesystemList.push(currentGamesystem as SimpleTemplateGamesystem<any>)
}
if(currentGamesystem instanceof ProductGamesystem) {
currentGamesystem.innerGamesystems.forEach(innerGamesystem => {
gamesystemQueue.push(innerGamesystem)
})
}
}
console.log(gamesystemList)
return gamesystemList;
}
}

View File

@ -47,10 +47,11 @@ export class GamesystemParser {
let simpleGamesystem = new SimpleGamesystem(gamesystemData.componentName, gamesystemData.componentDescription)
if(templateType == TemplateType.CHARACTER) {
simpleGamesystem = new SimpleTemplateGamesystem<Character>(gamesystemData.componentName, gamesystemData.componentDescription)
simpleGamesystem.templateType = TemplateType.CHARACTER
}
const stateParser = new StateParser(this.scriptAccounts);
simpleGamesystem.states = stateParser.parseStates(gamesystemData.states)
simpleGamesystem.states = stateParser.parseStates(gamesystemData.states, templateType)
const transitionParser = new TransitionParser(simpleGamesystem.states, this.scriptAccounts)
simpleGamesystem.transitions = transitionParser.parseTransitions(gamesystemData.transitions)

View File

@ -2,6 +2,9 @@ import {SimpleState} from "../../game-model/gamesystems/states/SimpleState";
import {ScriptAccount} from "../../game-model/scriptAccounts/ScriptAccount";
import {ScriptAccountCondition} from "../../game-model/gamesystems/conditions/ScriptAccountCondition";
import {ScriptAccountConditionParser} from "./ScriptAccountConditionParser";
import {TemplateType} from "../../game-model/TemplateType";
import {SimpleTemplateState} from "../../game-model/gamesystems/states/SimpleTemplateState";
import {Character} from "../../game-model/characters/Character";
export class StateParser {
@ -12,23 +15,29 @@ export class StateParser {
this.conditionParser = new ScriptAccountConditionParser(scriptAccounts)
}
public parseStates(stateData: any): SimpleState[] {
public parseStates(stateData: any, templateType: TemplateType): SimpleState[] {
const parsedStates: SimpleState[] = []
for(let i=0; i<stateData.length; i++) {
parsedStates.push(this.parseState(stateData[i]))
parsedStates.push(this.parseState(stateData[i], templateType))
}
return parsedStates;
}
private parseState(stateData: any): SimpleState {
private parseState(stateData: any, templateType: TemplateType): SimpleState {
const initial = stateData.initial
const stateLabel = stateData.stateLabel
const stateDescription = stateData.stateDescription
const conditions = this.conditionParser.parseStoredConditions(stateData.conditions)
const simpleState = new SimpleState(stateLabel, stateDescription);
let simpleState;
if(templateType === TemplateType.NORMAL) {
simpleState = new SimpleState(stateLabel, stateDescription);
} else {
simpleState = new SimpleTemplateState<Character>(stateLabel, stateDescription);
}
simpleState.initial = initial;
simpleState.conditions = conditions;

View File

@ -1,5 +1,32 @@
{
"componentName": "Hicks Haddock",
"componentDescription": "",
"characterSpecificGamesystems": []
"characterSpecificGamesystems": [
{
"componentName": "Characterstimmung",
"componentDescription": "",
"states": [
{
"incomingTransitions": [],
"outgoingTransitions": [],
"initial": true,
"conditions": [],
"stateLabel": "Fröhlich",
"stateDescription": "",
"conditionMap": {}
},
{
"incomingTransitions": [],
"outgoingTransitions": [],
"initial": false,
"conditions": [],
"stateLabel": "Wütend",
"stateDescription": "",
"conditionMap": {}
}
],
"transitions": [],
"templateType": 1
}
]
}