Merge pull request 'inventory-items' (#42) from inventory-items into main
All checks were successful
E2E Testing / test (push) Successful in 1m32s
All checks were successful
E2E Testing / test (push) Successful in 1m32s
Reviewed-on: #42
This commit is contained in:
commit
a3d5846ec1
@ -8,6 +8,7 @@ import {ModelComponentFileDirectory} from "./storage/ModelComponentFileDirectory
|
|||||||
import {GamesystemStorage} from "./storage/storing/GamesystemStorage";
|
import {GamesystemStorage} from "./storage/storing/GamesystemStorage";
|
||||||
import {Character} from "../src/app/project/game-model/characters/Character";
|
import {Character} from "../src/app/project/game-model/characters/Character";
|
||||||
import {CharacterStorage} from "./storage/storing/CharacterStorage";
|
import {CharacterStorage} from "./storage/storing/CharacterStorage";
|
||||||
|
import {ItemStorage} from "./storage/storing/ItemStorage";
|
||||||
|
|
||||||
let win: BrowserWindow | null = null;
|
let win: BrowserWindow | null = null;
|
||||||
const args = process.argv.slice(1),
|
const args = process.argv.slice(1),
|
||||||
@ -247,6 +248,9 @@ function recieveGameModelToStore(gameModel: StoredGameModel) {
|
|||||||
|
|
||||||
const characterStorage = new CharacterStorage(path.join(projectDirectory, ModelComponentFileDirectory.CHARACTER_DIR_NAME))
|
const characterStorage = new CharacterStorage(path.join(projectDirectory, ModelComponentFileDirectory.CHARACTER_DIR_NAME))
|
||||||
characterStorage.storeCharacters(gameModel.storedCharacters)
|
characterStorage.storeCharacters(gameModel.storedCharacters)
|
||||||
|
|
||||||
|
const itemStorage = new ItemStorage(path.join(projectDirectory, ModelComponentFileDirectory.ITEM_DIR_NAME))
|
||||||
|
itemStorage.storeItem(gameModel.storedItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*function deleteComponent(component: DeleteModel) {
|
/*function deleteComponent(component: DeleteModel) {
|
||||||
|
@ -7,4 +7,5 @@ exports.ModelComponentFileDirectory = ModelComponentFileDirectory;
|
|||||||
ModelComponentFileDirectory.SCRIPTACCOUNT_DIR_NAME = "script-accounts";
|
ModelComponentFileDirectory.SCRIPTACCOUNT_DIR_NAME = "script-accounts";
|
||||||
ModelComponentFileDirectory.GAMESYSTEM_DIR_NAME = "gamesystems";
|
ModelComponentFileDirectory.GAMESYSTEM_DIR_NAME = "gamesystems";
|
||||||
ModelComponentFileDirectory.CHARACTER_DIR_NAME = "characters";
|
ModelComponentFileDirectory.CHARACTER_DIR_NAME = "characters";
|
||||||
|
ModelComponentFileDirectory.ITEM_DIR_NAME = "items";
|
||||||
//# sourceMappingURL=ModelComponentFileDirectory.js.map
|
//# sourceMappingURL=ModelComponentFileDirectory.js.map
|
@ -2,4 +2,5 @@ export class ModelComponentFileDirectory {
|
|||||||
public static SCRIPTACCOUNT_DIR_NAME = "script-accounts"
|
public static SCRIPTACCOUNT_DIR_NAME = "script-accounts"
|
||||||
public static GAMESYSTEM_DIR_NAME = "gamesystems";
|
public static GAMESYSTEM_DIR_NAME = "gamesystems";
|
||||||
public static CHARACTER_DIR_NAME = "characters";
|
public static CHARACTER_DIR_NAME = "characters";
|
||||||
|
public static ITEM_DIR_NAME = "items";
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,12 @@
|
|||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.StoredGameModel = void 0;
|
exports.StoredGameModel = void 0;
|
||||||
class StoredGameModel {
|
class StoredGameModel {
|
||||||
constructor(gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters) {
|
constructor(gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters, storedItems) {
|
||||||
this.gameModelName = gameModelName;
|
this.gameModelName = gameModelName;
|
||||||
this.storedGamesystems = storedGamesystems;
|
this.storedGamesystems = storedGamesystems;
|
||||||
this.storedScriptAccounts = storedScriptAccounts;
|
this.storedScriptAccounts = storedScriptAccounts;
|
||||||
this.storedCharacters = storedCharacters;
|
this.storedCharacters = storedCharacters;
|
||||||
|
this.storedItems = storedItems;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.StoredGameModel = StoredGameModel;
|
exports.StoredGameModel = StoredGameModel;
|
||||||
|
@ -6,13 +6,15 @@ export class StoredGameModel {
|
|||||||
storedGamesystems: StoreComponent[]
|
storedGamesystems: StoreComponent[]
|
||||||
storedScriptAccounts: StoreComponent[]
|
storedScriptAccounts: StoreComponent[]
|
||||||
storedCharacters: StoreComponent[]
|
storedCharacters: StoreComponent[]
|
||||||
|
storedItems: StoreComponent[]
|
||||||
|
|
||||||
|
|
||||||
constructor(gameModelName: string, storedScriptAccounts: StoreComponent[], storedGamesystems: StoreComponent[],
|
constructor(gameModelName: string, storedScriptAccounts: StoreComponent[], storedGamesystems: StoreComponent[],
|
||||||
storedCharacters: StoreComponent[]) {
|
storedCharacters: StoreComponent[], storedItems: StoreComponent[]) {
|
||||||
this.gameModelName = gameModelName;
|
this.gameModelName = gameModelName;
|
||||||
this.storedGamesystems = storedGamesystems;
|
this.storedGamesystems = storedGamesystems;
|
||||||
this.storedScriptAccounts = storedScriptAccounts;
|
this.storedScriptAccounts = storedScriptAccounts;
|
||||||
this.storedCharacters = storedCharacters;
|
this.storedCharacters = storedCharacters;
|
||||||
|
this.storedItems = storedItems;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ const ModelComponentFileDirectory_1 = require("../ModelComponentFileDirectory");
|
|||||||
const ScriptAccountLoader_1 = require("./ScriptAccountLoader");
|
const ScriptAccountLoader_1 = require("./ScriptAccountLoader");
|
||||||
const GamesystemLoader_1 = require("./GamesystemLoader");
|
const GamesystemLoader_1 = require("./GamesystemLoader");
|
||||||
const CharacterLoader_1 = require("./CharacterLoader");
|
const CharacterLoader_1 = require("./CharacterLoader");
|
||||||
|
const ItemLoader_1 = require("./ItemLoader");
|
||||||
class GameModelLoader {
|
class GameModelLoader {
|
||||||
constructor(gameModelDir) {
|
constructor(gameModelDir) {
|
||||||
this.gameModelDir = gameModelDir;
|
this.gameModelDir = gameModelDir;
|
||||||
@ -16,7 +17,8 @@ class GameModelLoader {
|
|||||||
const storedScriptAccounts = this.loadScriptAccountComponents();
|
const storedScriptAccounts = this.loadScriptAccountComponents();
|
||||||
const storedGamesystems = this.loadGamesystems();
|
const storedGamesystems = this.loadGamesystems();
|
||||||
const storedCharacters = this.loadCharacters();
|
const storedCharacters = this.loadCharacters();
|
||||||
return new StoredGameModel_1.StoredGameModel(gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters);
|
const storedItems = this.loadItems();
|
||||||
|
return new StoredGameModel_1.StoredGameModel(gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters, storedItems);
|
||||||
}
|
}
|
||||||
loadScriptAccountComponents() {
|
loadScriptAccountComponents() {
|
||||||
const scriptAccountDir = path.join(this.gameModelDir, ModelComponentFileDirectory_1.ModelComponentFileDirectory.SCRIPTACCOUNT_DIR_NAME);
|
const scriptAccountDir = path.join(this.gameModelDir, ModelComponentFileDirectory_1.ModelComponentFileDirectory.SCRIPTACCOUNT_DIR_NAME);
|
||||||
@ -33,6 +35,11 @@ class GameModelLoader {
|
|||||||
const characterLoader = new CharacterLoader_1.CharacterLoader(characterDir);
|
const characterLoader = new CharacterLoader_1.CharacterLoader(characterDir);
|
||||||
return characterLoader.loadCharacters();
|
return characterLoader.loadCharacters();
|
||||||
}
|
}
|
||||||
|
loadItems() {
|
||||||
|
const itemDir = path.join(this.gameModelDir, ModelComponentFileDirectory_1.ModelComponentFileDirectory.ITEM_DIR_NAME);
|
||||||
|
const itemLoader = new ItemLoader_1.ItemLoader(itemDir);
|
||||||
|
return itemLoader.loadItems();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
exports.GameModelLoader = GameModelLoader;
|
exports.GameModelLoader = GameModelLoader;
|
||||||
//# sourceMappingURL=GameModelLoader.js.map
|
//# sourceMappingURL=GameModelLoader.js.map
|
@ -6,6 +6,7 @@ import {ModelComponentFileDirectory} from "../ModelComponentFileDirectory";
|
|||||||
import {ScriptAccountLoader} from "./ScriptAccountLoader";
|
import {ScriptAccountLoader} from "./ScriptAccountLoader";
|
||||||
import {GamesystemLoader} from "./GamesystemLoader";
|
import {GamesystemLoader} from "./GamesystemLoader";
|
||||||
import {CharacterLoader} from "./CharacterLoader";
|
import {CharacterLoader} from "./CharacterLoader";
|
||||||
|
import {ItemLoader} from "./ItemLoader";
|
||||||
|
|
||||||
export class GameModelLoader {
|
export class GameModelLoader {
|
||||||
gameModelDir: string
|
gameModelDir: string
|
||||||
@ -21,8 +22,9 @@ export class GameModelLoader {
|
|||||||
const storedScriptAccounts = this.loadScriptAccountComponents();
|
const storedScriptAccounts = this.loadScriptAccountComponents();
|
||||||
const storedGamesystems = this.loadGamesystems();
|
const storedGamesystems = this.loadGamesystems();
|
||||||
const storedCharacters = this.loadCharacters()
|
const storedCharacters = this.loadCharacters()
|
||||||
|
const storedItems = this.loadItems();
|
||||||
|
|
||||||
return new StoredGameModel(gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters);
|
return new StoredGameModel(gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters, storedItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadScriptAccountComponents() {
|
private loadScriptAccountComponents() {
|
||||||
@ -44,7 +46,9 @@ export class GameModelLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private loadItems(): StoreComponent[] {
|
||||||
|
const itemDir = path.join(this.gameModelDir, ModelComponentFileDirectory.ITEM_DIR_NAME);
|
||||||
|
const itemLoader = new ItemLoader(itemDir)
|
||||||
|
return itemLoader.loadItems();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
31
app/storage/loader/ItemLoader.js
Normal file
31
app/storage/loader/ItemLoader.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.ItemLoader = void 0;
|
||||||
|
const fs = require("node:fs");
|
||||||
|
const StoreComponent_1 = require("../StoreComponent");
|
||||||
|
const ModelComponentType_1 = require("../../../src/app/project/game-model/ModelComponentType");
|
||||||
|
const FileUtils_1 = require("../FileUtils");
|
||||||
|
class ItemLoader {
|
||||||
|
constructor(itemDir) {
|
||||||
|
this.itemDir = itemDir;
|
||||||
|
}
|
||||||
|
loadItems() {
|
||||||
|
const itemFiles = FileUtils_1.FileUtils.listFilesInDirectory(this.itemDir);
|
||||||
|
const loadedItems = [];
|
||||||
|
itemFiles.forEach(itemFile => {
|
||||||
|
const loadedItem = this.loadItem(itemFile);
|
||||||
|
if (loadedItem != undefined) {
|
||||||
|
loadedItems.push(loadedItem);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return loadedItems;
|
||||||
|
}
|
||||||
|
loadItem(itemFile) {
|
||||||
|
if (itemFile.endsWith(".json")) {
|
||||||
|
const itemData = fs.readFileSync(itemFile, 'utf-8');
|
||||||
|
return new StoreComponent_1.StoreComponent(itemData, itemFile, ModelComponentType_1.ModelComponentType.ITEM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ItemLoader = ItemLoader;
|
||||||
|
//# sourceMappingURL=ItemLoader.js.map
|
33
app/storage/loader/ItemLoader.ts
Normal file
33
app/storage/loader/ItemLoader.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import * as fs from "node:fs";
|
||||||
|
import {StoreComponent} from "../StoreComponent";
|
||||||
|
import {ModelComponentType} from "../../../src/app/project/game-model/ModelComponentType";
|
||||||
|
import {FileUtils} from "../FileUtils";
|
||||||
|
|
||||||
|
export class ItemLoader {
|
||||||
|
private itemDir: string
|
||||||
|
|
||||||
|
|
||||||
|
constructor(itemDir: string) {
|
||||||
|
this.itemDir = itemDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadItems() {
|
||||||
|
const itemFiles = FileUtils.listFilesInDirectory(this.itemDir);
|
||||||
|
const loadedItems :StoreComponent[] = []
|
||||||
|
itemFiles.forEach(itemFile => {
|
||||||
|
const loadedItem = this.loadItem(itemFile);
|
||||||
|
if(loadedItem != undefined) {
|
||||||
|
loadedItems.push(loadedItem);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return loadedItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadItem(itemFile: string) {
|
||||||
|
if(itemFile.endsWith(".json")) {
|
||||||
|
const itemData = fs.readFileSync(itemFile, 'utf-8');
|
||||||
|
return new StoreComponent(itemData, itemFile, ModelComponentType.ITEM)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
app/storage/storing/ItemStorage.js
Normal file
31
app/storage/storing/ItemStorage.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.ItemStorage = void 0;
|
||||||
|
const FileUtils_1 = require("../FileUtils");
|
||||||
|
const path = require("node:path");
|
||||||
|
const fs = require("node:fs");
|
||||||
|
class ItemStorage {
|
||||||
|
constructor(itemDir) {
|
||||||
|
this.itemDir = itemDir;
|
||||||
|
FileUtils_1.FileUtils.prepareDirectoryFroWriting(this.itemDir);
|
||||||
|
}
|
||||||
|
storeItem(storedItems) {
|
||||||
|
this.persistDeletedItems(storedItems);
|
||||||
|
storedItems.forEach(item => this.storeSingleItem(item));
|
||||||
|
}
|
||||||
|
persistDeletedItems(existingItems) {
|
||||||
|
const itemFiles = FileUtils_1.FileUtils.listFilesInDirectory(this.itemDir);
|
||||||
|
itemFiles.forEach(itemFile => {
|
||||||
|
const itemFileName = path.parse(path.basename(itemFile)).name;
|
||||||
|
if (existingItems.find(item => item.fileName === itemFileName) == undefined) {
|
||||||
|
fs.unlinkSync(itemFile);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
storeSingleItem(item) {
|
||||||
|
const completeItemFile = path.join(this.itemDir, item.fileName + ".json");
|
||||||
|
fs.writeFileSync(completeItemFile, item.jsonString, 'utf-8');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ItemStorage = ItemStorage;
|
||||||
|
//# sourceMappingURL=ItemStorage.js.map
|
33
app/storage/storing/ItemStorage.ts
Normal file
33
app/storage/storing/ItemStorage.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import {FileUtils} from "../FileUtils";
|
||||||
|
import {StoreComponent} from "../StoreComponent";
|
||||||
|
import * as path from "node:path";
|
||||||
|
import * as fs from "node:fs";
|
||||||
|
|
||||||
|
export class ItemStorage {
|
||||||
|
private itemDir: string
|
||||||
|
|
||||||
|
constructor(itemDir: string) {
|
||||||
|
this.itemDir = itemDir;
|
||||||
|
FileUtils.prepareDirectoryFroWriting(this.itemDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
storeItem(storedItems: StoreComponent[]) {
|
||||||
|
this.persistDeletedItems(storedItems);
|
||||||
|
storedItems.forEach(item => this.storeSingleItem(item))
|
||||||
|
}
|
||||||
|
|
||||||
|
private persistDeletedItems(existingItems: StoreComponent[]) {
|
||||||
|
const itemFiles = FileUtils.listFilesInDirectory(this.itemDir);
|
||||||
|
itemFiles.forEach(itemFile => {
|
||||||
|
const itemFileName = path.parse(path.basename(itemFile)).name
|
||||||
|
if(existingItems.find(item => item.fileName === itemFileName) == undefined) {
|
||||||
|
fs.unlinkSync(itemFile)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private storeSingleItem(item: StoreComponent) {
|
||||||
|
const completeItemFile = path.join(this.itemDir, item.fileName + ".json");
|
||||||
|
fs.writeFileSync(completeItemFile, item.jsonString, 'utf-8')
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,13 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="full-height-container" >
|
<div class="full-height-container" >
|
||||||
<button mat-icon-button class="small-icon-button" [ngClass]="openContent === ModelComponentType.SCRIPTACCOUNT ? 'selected':''"
|
<button mat-icon-button class="small-icon-button" [ngClass]="openContent === ModelComponentType.SCRIPTACCOUNT ? 'selected':''"
|
||||||
(click)="openScriptAccountsOverview()"><mat-icon>inventory_2</mat-icon></button>
|
(click)="openScriptAccountsOverview()"><mat-icon>analytics</mat-icon></button>
|
||||||
<button mat-icon-button class="small-icon-button" [ngClass]="openContent === ModelComponentType.GAMESYTEM ? 'selected':''"
|
<button mat-icon-button class="small-icon-button" [ngClass]="openContent === ModelComponentType.GAMESYTEM ? 'selected':''"
|
||||||
(click)="openGamesystemsOverview()"><mat-icon>code</mat-icon></button>
|
(click)="openGamesystemsOverview()"><mat-icon>code</mat-icon></button>
|
||||||
<button mat-icon-button class="small-icon-button" [ngClass]="openContent === ModelComponentType.CHARACTER ? 'selected':''"
|
<button mat-icon-button class="small-icon-button" [ngClass]="openContent === ModelComponentType.CHARACTER ? 'selected':''"
|
||||||
(click)="openCharactersOverview()"><mat-icon>person</mat-icon></button>
|
(click)="openCharactersOverview()"><mat-icon>person</mat-icon></button>
|
||||||
|
<button mat-icon-button class="small-icon-button" [ngClass]="openContent === ModelComponentType.ITEM ? 'selected':''"
|
||||||
|
(click)="openContentOverview(ModelComponentType.ITEM)"><mat-icon>inventory_2</mat-icon></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@ -23,11 +25,13 @@
|
|||||||
<button mat-menu-item (click)="openScriptAccountsOverview()">{{ModelComponentTypeUtillities.toString(ModelComponentType.SCRIPTACCOUNT)}}</button>
|
<button mat-menu-item (click)="openScriptAccountsOverview()">{{ModelComponentTypeUtillities.toString(ModelComponentType.SCRIPTACCOUNT)}}</button>
|
||||||
<button mat-menu-item (click)="openGamesystemsOverview()">{{ModelComponentTypeUtillities.toString(ModelComponentType.GAMESYTEM)}}</button>
|
<button mat-menu-item (click)="openGamesystemsOverview()">{{ModelComponentTypeUtillities.toString(ModelComponentType.GAMESYTEM)}}</button>
|
||||||
<button mat-menu-item (click)="openCharactersOverview()">{{ModelComponentTypeUtillities.toString(ModelComponentType.CHARACTER)}}</button>
|
<button mat-menu-item (click)="openCharactersOverview()">{{ModelComponentTypeUtillities.toString(ModelComponentType.CHARACTER)}}</button>
|
||||||
|
<button mat-menu-item (click)="openContentOverview(ModelComponentType.ITEM)">{{ModelComponentTypeUtillities.toString(ModelComponentType.ITEM)}}</button>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
</div>
|
</div>
|
||||||
<app-script-account-overview *ngIf="openContent == ModelComponentType.SCRIPTACCOUNT" #scriptAccountOverview [gameModel]="gameModel" (onOpenScriptAccount)="openModelComponent($event)"></app-script-account-overview>
|
<app-script-account-overview *ngIf="openContent == ModelComponentType.SCRIPTACCOUNT" #scriptAccountOverview [gameModel]="gameModel" (onOpenScriptAccount)="openModelComponent($event)"></app-script-account-overview>
|
||||||
<app-gamescript-overview *ngIf="openContent == ModelComponentType.GAMESYTEM" #gamesystemOverview [gameModel]="gameModel" (openGamesystemEditor)="openModelComponent($event)"></app-gamescript-overview>
|
<app-gamescript-overview *ngIf="openContent == ModelComponentType.GAMESYTEM" #gamesystemOverview [gameModel]="gameModel" (openGamesystemEditor)="openModelComponent($event)"></app-gamescript-overview>
|
||||||
<app-character-overview *ngIf="openContent == ModelComponentType.CHARACTER" #characterOverview [gameModel]="gameModel" (onOpenCharacterEditor)="openModelComponent($event)"></app-character-overview>
|
<app-character-overview *ngIf="openContent == ModelComponentType.CHARACTER" #characterOverview [gameModel]="gameModel" (onOpenCharacterEditor)="openModelComponent($event)"></app-character-overview>
|
||||||
|
<app-inventory-item-overview *ngIf="openContent === ModelComponentType.ITEM" #itemOverview [gameModel]="gameModel" (openItemEditor)="openModelComponent($event)"></app-inventory-item-overview>
|
||||||
</mat-drawer>
|
</mat-drawer>
|
||||||
|
|
||||||
<div class="example-sidenav-content">
|
<div class="example-sidenav-content">
|
||||||
|
@ -27,6 +27,8 @@ import {CharacterParser} from "./project/parser/characterParser/CharacterParser"
|
|||||||
import {TemplateType} from "./project/game-model/templates/TemplateType";
|
import {TemplateType} from "./project/game-model/templates/TemplateType";
|
||||||
import {TemplateTypeUtilities} from "./project/game-model/templates/TemplateTypeUtilities";
|
import {TemplateTypeUtilities} from "./project/game-model/templates/TemplateTypeUtilities";
|
||||||
import {SimpleTemplateGamesystem} from "./project/game-model/templates/simpleGamesystem/SimpleTemplateGamesystem";
|
import {SimpleTemplateGamesystem} from "./project/game-model/templates/simpleGamesystem/SimpleTemplateGamesystem";
|
||||||
|
import {ItemSerializer} from "./project/serializer/ItemSerializer";
|
||||||
|
import {ItemParser} from "./project/parser/ItemParser";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
@ -223,6 +225,8 @@ export class AppComponent implements OnInit{
|
|||||||
const characterParser = new CharacterParser(characterTemplateSystems, characterRelationTemplateSystems, gameModel.scriptAccounts);
|
const characterParser = new CharacterParser(characterTemplateSystems, characterRelationTemplateSystems, gameModel.scriptAccounts);
|
||||||
gameModel.characters = characterParser.parseCharacters(storedGameModel.storedCharacters)
|
gameModel.characters = characterParser.parseCharacters(storedGameModel.storedCharacters)
|
||||||
|
|
||||||
|
gameModel.inventoryItems = ItemParser.parseItems(storedGameModel.storedItems)
|
||||||
|
|
||||||
this.gameModel = gameModel;
|
this.gameModel = gameModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +235,11 @@ export class AppComponent implements OnInit{
|
|||||||
const storedScriptAccounts = ScriptAccountSerializer.serializeScriptAccounts(this.gameModel.scriptAccounts)
|
const storedScriptAccounts = ScriptAccountSerializer.serializeScriptAccounts(this.gameModel.scriptAccounts)
|
||||||
const storedGamesystems: StoreComponent[] = GamesystemSerializer.serializeGamesystems(this.gameModel.gamesystems)
|
const storedGamesystems: StoreComponent[] = GamesystemSerializer.serializeGamesystems(this.gameModel.gamesystems)
|
||||||
const storedCharacters: StoreComponent[] = CharacterSerializer.serializeCharacters(this.gameModel.characters)
|
const storedCharacters: StoreComponent[] = CharacterSerializer.serializeCharacters(this.gameModel.characters)
|
||||||
const storeModel = new StoredGameModel(this.gameModel.gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters)
|
const storedItems: StoreComponent[] = ItemSerializer.serializeItems(this.gameModel.inventoryItems);
|
||||||
|
|
||||||
|
console.log(this.gameModel.inventoryItems)
|
||||||
|
const storeModel = new StoredGameModel(this.gameModel.gameModelName, storedScriptAccounts,
|
||||||
|
storedGamesystems, storedCharacters, storedItems)
|
||||||
|
|
||||||
if(this.electronService.isElectron) {
|
if(this.electronService.isElectron) {
|
||||||
this.electronService.ipcRenderer.send('save-model', storeModel)
|
this.electronService.ipcRenderer.send('save-model', storeModel)
|
||||||
@ -254,6 +262,11 @@ export class AppComponent implements OnInit{
|
|||||||
this.drawer!.open()
|
this.drawer!.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openContentOverview(contentType: ModelComponentType) {
|
||||||
|
this.openContent = contentType;
|
||||||
|
this.drawer!.open();
|
||||||
|
}
|
||||||
|
|
||||||
protected readonly ModelComponentType = ModelComponentType;
|
protected readonly ModelComponentType = ModelComponentType;
|
||||||
|
|
||||||
closeContentOverview() {
|
closeContentOverview() {
|
||||||
|
@ -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";
|
||||||
@ -82,6 +82,13 @@ import {
|
|||||||
import {
|
import {
|
||||||
StateInitialCellComponent
|
StateInitialCellComponent
|
||||||
} from "./editor/gamesystem-editor/state-editor/simple-state-editor/state-initial-cell/state-initial-cell.component";
|
} from "./editor/gamesystem-editor/state-editor/simple-state-editor/state-initial-cell/state-initial-cell.component";
|
||||||
|
import {
|
||||||
|
InventoryItemOverviewComponent
|
||||||
|
} from "./side-overviews/inventory-item-overview/inventory-item-overview.component";
|
||||||
|
import {InventoryItemEditorComponent} from "./editor/inventory-item-editor/inventory-item-editor.component";
|
||||||
|
import {
|
||||||
|
ItemPropertyEditorComponent
|
||||||
|
} from "./editor/inventory-item-editor/item-property-editor/item-property-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');
|
||||||
@ -107,71 +114,75 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl
|
|||||||
CharacterOverviewComponent,
|
CharacterOverviewComponent,
|
||||||
CharacterEditorComponent,
|
CharacterEditorComponent,
|
||||||
TemplateSpecificatorComponent,
|
TemplateSpecificatorComponent,
|
||||||
StateInitialCellComponent
|
StateInitialCellComponent,
|
||||||
|
InventoryItemOverviewComponent,
|
||||||
|
InventoryItemEditorComponent,
|
||||||
|
ItemPropertyEditorComponent
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
BrowserModule,
|
||||||
|
FormsModule,
|
||||||
|
HttpClientModule,
|
||||||
|
CoreModule,
|
||||||
|
SharedModule,
|
||||||
|
TranslateModule.forRoot({
|
||||||
|
loader: {
|
||||||
|
provide: TranslateLoader,
|
||||||
|
useFactory: httpLoaderFactory,
|
||||||
|
deps: [HttpClient]
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
BrowserAnimationsModule,
|
||||||
|
MatIcon,
|
||||||
|
MatToolbar,
|
||||||
|
MatButton,
|
||||||
|
MatFormField,
|
||||||
|
MatInput,
|
||||||
|
MatDrawerContainer,
|
||||||
|
MatDrawer,
|
||||||
|
MatIconButton,
|
||||||
|
MatMenuTrigger,
|
||||||
|
MatMenu,
|
||||||
|
MatMenuItem,
|
||||||
|
MatListItem,
|
||||||
|
MatActionList,
|
||||||
|
MatTabGroup,
|
||||||
|
MatTab,
|
||||||
|
MatTabLabel,
|
||||||
|
MatLabel,
|
||||||
|
MatFormField,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
MatError,
|
||||||
|
MatDialogTitle,
|
||||||
|
MatDialogContent,
|
||||||
|
MatDialogActions,
|
||||||
|
MatMiniFabButton,
|
||||||
|
MatTreeModule,
|
||||||
|
MatTable,
|
||||||
|
MatColumnDef,
|
||||||
|
MatHeaderCell,
|
||||||
|
MatHeaderCellDef,
|
||||||
|
MatCellDef,
|
||||||
|
MatCell,
|
||||||
|
MatHeaderRow,
|
||||||
|
MatRow,
|
||||||
|
MatHeaderRowDef,
|
||||||
|
MatRowDef,
|
||||||
|
MatCheckbox,
|
||||||
|
MatSelect,
|
||||||
|
MatOption,
|
||||||
|
MatHint,
|
||||||
|
MatTooltip,
|
||||||
|
MatCard,
|
||||||
|
MatCardContent,
|
||||||
|
MatCardHeader,
|
||||||
|
MatAccordion,
|
||||||
|
MatExpansionPanel,
|
||||||
|
MatExpansionPanelTitle,
|
||||||
|
MatCardTitle,
|
||||||
|
MatExpansionPanelHeader,
|
||||||
|
MatCardActions,
|
||||||
],
|
],
|
||||||
imports: [
|
|
||||||
BrowserModule,
|
|
||||||
FormsModule,
|
|
||||||
HttpClientModule,
|
|
||||||
CoreModule,
|
|
||||||
SharedModule,
|
|
||||||
TranslateModule.forRoot({
|
|
||||||
loader: {
|
|
||||||
provide: TranslateLoader,
|
|
||||||
useFactory: httpLoaderFactory,
|
|
||||||
deps: [HttpClient]
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
BrowserAnimationsModule,
|
|
||||||
MatIcon,
|
|
||||||
MatToolbar,
|
|
||||||
MatButton,
|
|
||||||
MatFormField,
|
|
||||||
MatInput,
|
|
||||||
MatDrawerContainer,
|
|
||||||
MatDrawer,
|
|
||||||
MatIconButton,
|
|
||||||
MatMenuTrigger,
|
|
||||||
MatMenu,
|
|
||||||
MatMenuItem,
|
|
||||||
MatListItem,
|
|
||||||
MatActionList,
|
|
||||||
MatTabGroup,
|
|
||||||
MatTab,
|
|
||||||
MatTabLabel,
|
|
||||||
MatLabel,
|
|
||||||
MatFormField,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
MatError,
|
|
||||||
MatDialogTitle,
|
|
||||||
MatDialogContent,
|
|
||||||
MatDialogActions,
|
|
||||||
MatMiniFabButton,
|
|
||||||
MatTreeModule,
|
|
||||||
MatTable,
|
|
||||||
MatColumnDef,
|
|
||||||
MatHeaderCell,
|
|
||||||
MatHeaderCellDef,
|
|
||||||
MatCellDef,
|
|
||||||
MatCell,
|
|
||||||
MatHeaderRow,
|
|
||||||
MatRow,
|
|
||||||
MatHeaderRowDef,
|
|
||||||
MatRowDef,
|
|
||||||
MatCheckbox,
|
|
||||||
MatSelect,
|
|
||||||
MatOption,
|
|
||||||
MatHint,
|
|
||||||
MatTooltip,
|
|
||||||
MatCard,
|
|
||||||
MatCardContent,
|
|
||||||
MatCardHeader,
|
|
||||||
MatAccordion,
|
|
||||||
MatExpansionPanel,
|
|
||||||
MatExpansionPanelTitle,
|
|
||||||
MatCardTitle,
|
|
||||||
MatExpansionPanelHeader
|
|
||||||
],
|
|
||||||
providers: [],
|
providers: [],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {Component, Input} from '@angular/core';
|
import {Component, Input, OnInit} 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 {MatDialog} from "@angular/material/dialog";
|
import {MatDialog} from "@angular/material/dialog";
|
||||||
|
@ -16,9 +16,11 @@
|
|||||||
[scriptAccounts]="gameModel!.scriptAccounts"></app-gamesystem-editor>
|
[scriptAccounts]="gameModel!.scriptAccounts"></app-gamesystem-editor>
|
||||||
<app-character-editor *ngIf="modelComponent.type === ModelComponentType.CHARACTER"
|
<app-character-editor *ngIf="modelComponent.type === ModelComponentType.CHARACTER"
|
||||||
[character]="convertModelComponentToCharacter(modelComponent)"
|
[character]="convertModelComponentToCharacter(modelComponent)"
|
||||||
[gameModel]="gameModel!"
|
[gameModel]="gameModel!">
|
||||||
>
|
|
||||||
|
|
||||||
</app-character-editor>
|
</app-character-editor>
|
||||||
|
<app-inventory-item-editor *ngIf="modelComponent.type === ModelComponentType.ITEM"
|
||||||
|
[item]="convertModelComponentToItem(modelComponent)"
|
||||||
|
[gameModel]="gameModel!">
|
||||||
|
</app-inventory-item-editor>
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
</mat-tab-group>
|
</mat-tab-group>
|
||||||
|
@ -7,6 +7,7 @@ import {State} from "../project/game-model/gamesystems/states/State";
|
|||||||
import {Transition} from "../project/game-model/gamesystems/transitions/Transition";
|
import {Transition} from "../project/game-model/gamesystems/transitions/Transition";
|
||||||
import {ModelComponentType} from "../project/game-model/ModelComponentType";
|
import {ModelComponentType} from "../project/game-model/ModelComponentType";
|
||||||
import {Character} from "../project/game-model/characters/Character";
|
import {Character} from "../project/game-model/characters/Character";
|
||||||
|
import {Item} from "../project/game-model/inventory/Item";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -27,6 +28,7 @@ export class EditorComponent {
|
|||||||
} else {
|
} else {
|
||||||
this.activeTab = this.gameModelComponents.findIndex(component => component.componentName === gameModelComponent.componentName);
|
this.activeTab = this.gameModelComponents.findIndex(component => component.componentName === gameModelComponent.componentName);
|
||||||
}
|
}
|
||||||
|
console.log(gameModelComponent)
|
||||||
}
|
}
|
||||||
|
|
||||||
closeGameModelComponent(gameModelComponent: ModelComponent) {
|
closeGameModelComponent(gameModelComponent: ModelComponent) {
|
||||||
@ -57,4 +59,11 @@ export class EditorComponent {
|
|||||||
return modelComponent as Character
|
return modelComponent as Character
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
convertModelComponentToItem(modelComponent: ModelComponent) {
|
||||||
|
if(modelComponent instanceof Item) {
|
||||||
|
return modelComponent as Item
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,74 @@
|
|||||||
|
<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-header>
|
||||||
|
<mat-card-title>Item Characteristics</mat-card-title>
|
||||||
|
</mat-card-header>
|
||||||
|
<mat-card-content>
|
||||||
|
<app-item-property-editor [item]="item"></app-item-property-editor>
|
||||||
|
</mat-card-content>
|
||||||
|
</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>
|
@ -0,0 +1,7 @@
|
|||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-column-edit, .mat-column-delete {
|
||||||
|
width: 32px;
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { InventoryItemEditorComponent } from './inventory-item-editor.component';
|
||||||
|
|
||||||
|
describe('InventoryItemEditorComponent', () => {
|
||||||
|
let component: InventoryItemEditorComponent;
|
||||||
|
let fixture: ComponentFixture<InventoryItemEditorComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [InventoryItemEditorComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(InventoryItemEditorComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,58 @@
|
|||||||
|
import {Component, ElementRef, Input, OnInit, ViewChildren} from '@angular/core';
|
||||||
|
import {Character} from "../../project/game-model/characters/Character";
|
||||||
|
import {GameModel} from "../../project/game-model/GameModel";
|
||||||
|
import {Item} from "../../project/game-model/inventory/Item";
|
||||||
|
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({
|
||||||
|
selector: 'app-inventory-item-editor',
|
||||||
|
templateUrl: './inventory-item-editor.component.html',
|
||||||
|
styleUrl: './inventory-item-editor.component.scss'
|
||||||
|
})
|
||||||
|
export class InventoryItemEditorComponent implements OnInit{
|
||||||
|
|
||||||
|
@Input() item: Item | 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())
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
<table mat-table [dataSource]="datasource" class="mat-elevation-z8" multiTemplateDataRows>
|
||||||
|
<ng-container matColumnDef="name">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>Name</th>
|
||||||
|
<td mat-cell *matCellDef="let itemProperty">
|
||||||
|
<span *ngIf="editedItemProperty !== itemProperty || quality != undefined"> {{itemProperty.propertyName}}</span>
|
||||||
|
<mat-form-field appearance="fill" *ngIf="editedItemProperty === itemProperty && quality == undefined">
|
||||||
|
<mat-label>Name</mat-label>
|
||||||
|
<input matInput [(ngModel)]="itemProperty.propertyName">
|
||||||
|
</mat-form-field>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<!-- Expanded Content Column - The detail row is made up of this one column that spans across all columns -->
|
||||||
|
<ng-container matColumnDef="expandedDetail">
|
||||||
|
<td mat-cell *matCellDef="let element" [attr.colspan]="columnsToDisplayWithExpand.length">
|
||||||
|
<div class="example-element-detail" [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
|
||||||
|
<p *ngIf="editedItemProperty !== element || quality != undefined">{{element.propertyDescription}}</p>
|
||||||
|
<mat-form-field appearance="fill" class="long-form" *ngIf="editedItemProperty === element && quality == undefined">
|
||||||
|
<mat-label>Description</mat-label>
|
||||||
|
<textarea matInput [(ngModel)]="element.propertyDescription" rows="3"></textarea>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="property">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>Value</th>
|
||||||
|
<td mat-cell *matCellDef="let itemProperty">
|
||||||
|
<p *ngIf="itemProperty !== editedItemProperty">{{itemProperty.property}}</p>
|
||||||
|
<mat-form-field appearance="fill" *ngIf="itemProperty === editedItemProperty">
|
||||||
|
<mat-label>Value</mat-label>
|
||||||
|
<input matInput [(ngModel)]="itemProperty.property" type="number">
|
||||||
|
</mat-form-field>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="edit">
|
||||||
|
<th mat-header-cell *matHeaderCellDef></th>
|
||||||
|
<td mat-cell *matCellDef="let itemProperty">
|
||||||
|
<button mat-icon-button class="icon-btn-primary" *ngIf="editedItemProperty !== itemProperty"
|
||||||
|
(click)="editItemProperty(itemProperty)" [disabled]="editedItemProperty !== undefined"><mat-icon>edit</mat-icon></button>
|
||||||
|
<button mat-icon-button class="icon-btn-primary" (click)="finishEditing()" *ngIf="editedItemProperty === itemProperty"><mat-icon>done</mat-icon></button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="delete">
|
||||||
|
<th mat-header-cell *matHeaderCellDef></th>
|
||||||
|
<td mat-cell *matCellDef="let itemProperty">
|
||||||
|
<button *ngIf="quality == undefined" mat-icon-button color="warn" (click)="deleteItemProperty(itemProperty)"><mat-icon>delete</mat-icon></button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="expand">
|
||||||
|
<th mat-header-cell *matHeaderCellDef aria-label="row actions">
|
||||||
|
<button *ngIf="quality == undefined" mat-icon-button [disabled]="editedItemProperty !== undefined" (click)="addItemProperty()"><mat-icon>add</mat-icon></button>
|
||||||
|
</th>
|
||||||
|
<td mat-cell *matCellDef="let element">
|
||||||
|
<button mat-icon-button aria-label="expand row" (click)="(expandedElement = expandedElement === element ? null : element); $event.stopPropagation()">
|
||||||
|
@if (expandedElement === element) {
|
||||||
|
<mat-icon>keyboard_arrow_up</mat-icon>
|
||||||
|
} @else {
|
||||||
|
<mat-icon>keyboard_arrow_down</mat-icon>
|
||||||
|
}
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<tr mat-header-row *matHeaderRowDef="columnsToDisplayWithExpand"></tr>
|
||||||
|
<tr mat-row *matRowDef="let element; columns: columnsToDisplayWithExpand;"
|
||||||
|
class="example-element-row"
|
||||||
|
[class.example-expanded-row]="expandedElement === element"
|
||||||
|
(click)="expandedElement = expandedElement === element ? null : element">
|
||||||
|
</tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="example-detail-row"></tr>
|
||||||
|
</table>
|
@ -0,0 +1,57 @@
|
|||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.example-detail-row {
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.example-element-row:not(.example-expanded-row):hover {
|
||||||
|
background: #545456
|
||||||
|
}
|
||||||
|
|
||||||
|
tr.example-element-row:not(.example-expanded-row):active {
|
||||||
|
background: #545456;
|
||||||
|
}
|
||||||
|
|
||||||
|
.example-element-row td {
|
||||||
|
border-bottom-width: 0;
|
||||||
|
}
|
||||||
|
.example-element-diagram {
|
||||||
|
min-width: 80px;
|
||||||
|
border: 2px solid black;
|
||||||
|
padding: 8px;
|
||||||
|
font-weight: lighter;
|
||||||
|
margin: 8px 0;
|
||||||
|
height: 104px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.example-element-symbol {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 40px;
|
||||||
|
line-height: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.example-element-description {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.example-element-description-attribution {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-column-edit, .mat-column-delete, .mat-column-expand {
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.long-form {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-error {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning-icon {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ItemPropertyEditorComponent } from './item-property-editor.component';
|
||||||
|
|
||||||
|
describe('ItemPropertyEditorComponent', () => {
|
||||||
|
let component: ItemPropertyEditorComponent;
|
||||||
|
let fixture: ComponentFixture<ItemPropertyEditorComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [ItemPropertyEditorComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(ItemPropertyEditorComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,82 @@
|
|||||||
|
import {Component, Input, OnInit} from '@angular/core';
|
||||||
|
import {Item} from "../../../project/game-model/inventory/Item";
|
||||||
|
import {MatTableDataSource} from "@angular/material/table";
|
||||||
|
import {ItemProperty} from "../../../project/game-model/inventory/ItemProperty";
|
||||||
|
import {animate, state, style, transition, trigger} from "@angular/animations";
|
||||||
|
import {MatSnackBar} from "@angular/material/snack-bar";
|
||||||
|
import {ItemQuality} from "../../../project/game-model/inventory/ItemQuality";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-item-property-editor',
|
||||||
|
templateUrl: './item-property-editor.component.html',
|
||||||
|
styleUrl: './item-property-editor.component.scss',
|
||||||
|
animations: [
|
||||||
|
trigger('detailExpand', [
|
||||||
|
state('collapsed,void', style({height: '0px', minHeight: '0'})),
|
||||||
|
state('expanded', style({height: '*'})),
|
||||||
|
transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class ItemPropertyEditorComponent implements OnInit{
|
||||||
|
|
||||||
|
@Input() item: Item | undefined
|
||||||
|
@Input() quality: ItemQuality | undefined
|
||||||
|
editedItemProperty: ItemProperty | undefined
|
||||||
|
expandedElement: ItemProperty | undefined
|
||||||
|
|
||||||
|
displayedColumns: string[] = ['name', 'property', 'edit', 'delete']
|
||||||
|
columnsToDisplayWithExpand = [...this.displayedColumns, 'expand'];
|
||||||
|
|
||||||
|
datasource: MatTableDataSource<ItemProperty> = new MatTableDataSource<ItemProperty>();
|
||||||
|
|
||||||
|
constructor(private snackbar: MatSnackBar) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.updatedDisplayedData()
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteItemProperty(itemProperty: ItemProperty) {
|
||||||
|
if(this.quality == undefined) {
|
||||||
|
this.item!.itemProperties = this.item!.itemProperties.filter(property => property.propertyName !== itemProperty.propertyName)
|
||||||
|
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) {
|
||||||
|
this.editedItemProperty = itemProperty
|
||||||
|
}
|
||||||
|
|
||||||
|
finishEditing() {
|
||||||
|
if(this.editedItemProperty!.propertyName.length < 1) {
|
||||||
|
this.snackbar.open("PropertyName cannout be empty", "", {duration: 2000});
|
||||||
|
} else {
|
||||||
|
this.editedItemProperty = undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addItemProperty() {
|
||||||
|
if(this.quality == undefined) {
|
||||||
|
const itemProperty = new ItemProperty("New Property", "", 0);
|
||||||
|
this.item!.itemProperties.push(itemProperty);
|
||||||
|
this.datasource.data = this.item!.itemProperties;
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@ import {SimpleTemplateGamesystem} from "./templates/simpleGamesystem/SimpleTempl
|
|||||||
import {ProductTemplateSystem} from "./templates/productGamesystem/ProductTemplateSystem";
|
import {ProductTemplateSystem} from "./templates/productGamesystem/ProductTemplateSystem";
|
||||||
import {ProductTemplateCreator} from "./templates/productGamesystem/ProductTemplateCreator";
|
import {ProductTemplateCreator} from "./templates/productGamesystem/ProductTemplateCreator";
|
||||||
import {CharacterRelation} from "./characters/CharacterRelation";
|
import {CharacterRelation} from "./characters/CharacterRelation";
|
||||||
|
import {Item} from "./inventory/Item";
|
||||||
|
|
||||||
export class GameModel {
|
export class GameModel {
|
||||||
gameModelName: string
|
gameModelName: string
|
||||||
@ -18,6 +19,7 @@ export class GameModel {
|
|||||||
gamesystems: Gamesystem<any, any>[] = [];
|
gamesystems: Gamesystem<any, any>[] = [];
|
||||||
scriptAccounts: ScriptAccount[] = [];
|
scriptAccounts: ScriptAccount[] = [];
|
||||||
characters: Character[] = []
|
characters: Character[] = []
|
||||||
|
inventoryItems: Item[] = []
|
||||||
|
|
||||||
constructor(gameModelName: string) {
|
constructor(gameModelName: string) {
|
||||||
this.gameModelName = gameModelName;
|
this.gameModelName = gameModelName;
|
||||||
@ -101,7 +103,12 @@ export class GameModel {
|
|||||||
return simpleGamesystem;
|
return simpleGamesystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createInventoryItem(itemName: string) {
|
||||||
|
if(itemName != undefined) {
|
||||||
|
const item = new Item(itemName, "", ModelComponentType.ITEM);
|
||||||
|
this.inventoryItems.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
createGamesystem(gamesystemName: string, parentGamesystemName: string | undefined, templateType: TemplateType | undefined) {
|
createGamesystem(gamesystemName: string, parentGamesystemName: string | undefined, templateType: TemplateType | undefined) {
|
||||||
if(gamesystemName != undefined && this.findGamesystem(gamesystemName) == undefined) {
|
if(gamesystemName != undefined && this.findGamesystem(gamesystemName) == undefined) {
|
||||||
@ -156,6 +163,10 @@ export class GameModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeItem(item: Item) {
|
||||||
|
this.inventoryItems = this.inventoryItems.filter(i => i.componentName === item.componentName)
|
||||||
|
}
|
||||||
|
|
||||||
findGamesystem(gamesystemName: string) {
|
findGamesystem(gamesystemName: string) {
|
||||||
const gamesystemQueue : Gamesystem<State<any>, Transition<any>>[] = [];
|
const gamesystemQueue : Gamesystem<State<any>, Transition<any>>[] = [];
|
||||||
this.gamesystems.forEach(gamesystem => gamesystemQueue.push(gamesystem));
|
this.gamesystems.forEach(gamesystem => gamesystemQueue.push(gamesystem));
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
export enum ModelComponentType {
|
export enum ModelComponentType {
|
||||||
SCRIPTACCOUNT,
|
SCRIPTACCOUNT,
|
||||||
GAMESYTEM,
|
GAMESYTEM,
|
||||||
CHARACTER
|
CHARACTER,
|
||||||
|
ITEM
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,8 @@ export class ModelComponentTypeUtillities {
|
|||||||
switch (modelComponentType) {
|
switch (modelComponentType) {
|
||||||
case ModelComponentType.SCRIPTACCOUNT: return "ScriptAccounts";
|
case ModelComponentType.SCRIPTACCOUNT: return "ScriptAccounts";
|
||||||
case ModelComponentType.GAMESYTEM: return "Gamesystems";
|
case ModelComponentType.GAMESYTEM: return "Gamesystems";
|
||||||
case ModelComponentType.CHARACTER: return "Characters"
|
case ModelComponentType.CHARACTER: return "Characters";
|
||||||
|
case ModelComponentType.ITEM: return "Items";
|
||||||
default: return "Undefined";
|
default: return "Undefined";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -15,6 +16,7 @@ export class ModelComponentTypeUtillities {
|
|||||||
case ModelComponentType.SCRIPTACCOUNT: return "ScriptAccount";
|
case ModelComponentType.SCRIPTACCOUNT: return "ScriptAccount";
|
||||||
case ModelComponentType.GAMESYTEM: return "Gamesystem";
|
case ModelComponentType.GAMESYTEM: return "Gamesystem";
|
||||||
case ModelComponentType.CHARACTER: return "Character"
|
case ModelComponentType.CHARACTER: return "Character"
|
||||||
|
case ModelComponentType.ITEM: return "Item"
|
||||||
default: return "Undefined";
|
default: return "Undefined";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -24,6 +26,7 @@ export class ModelComponentTypeUtillities {
|
|||||||
case "gamesystem": return ModelComponentType.GAMESYTEM;
|
case "gamesystem": return ModelComponentType.GAMESYTEM;
|
||||||
case "scriptaccount": return ModelComponentType.SCRIPTACCOUNT;
|
case "scriptaccount": return ModelComponentType.SCRIPTACCOUNT;
|
||||||
case "character": return ModelComponentType.CHARACTER
|
case "character": return ModelComponentType.CHARACTER
|
||||||
|
case "item": return ModelComponentType.ITEM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
44
src/app/project/game-model/inventory/Item.ts
Normal file
44
src/app/project/game-model/inventory/Item.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import {ItemProperty} from "./ItemProperty";
|
||||||
|
import {ItemQuality} from "./ItemQuality";
|
||||||
|
import {ModelComponent} from "../ModelComponent";
|
||||||
|
import {ModelComponentType} from "../ModelComponentType";
|
||||||
|
import {ItemPropertyDescription} from "./ItemPropertyDescription";
|
||||||
|
|
||||||
|
export class Item extends ModelComponent {
|
||||||
|
|
||||||
|
possible_qualities: ItemQuality[] = []
|
||||||
|
itemProperties: ItemProperty[] = []
|
||||||
|
|
||||||
|
perQualityProperties: ItemPropertyDescription[] = []
|
||||||
|
|
||||||
|
constructor(componentName: string, componentDescription: string, type: ModelComponentType) {
|
||||||
|
super(componentName, componentDescription, type);
|
||||||
|
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))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
12
src/app/project/game-model/inventory/ItemProperty.ts
Normal file
12
src/app/project/game-model/inventory/ItemProperty.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
export class ItemProperty {
|
||||||
|
propertyName: string
|
||||||
|
propertyDescription: string
|
||||||
|
property: number
|
||||||
|
|
||||||
|
|
||||||
|
constructor(propertyName: string, propertyDescription: string, property: number) {
|
||||||
|
this.propertyName = propertyName;
|
||||||
|
this.propertyDescription = propertyDescription;
|
||||||
|
this.property = property;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
export class ItemPropertyDescription {
|
||||||
|
propertyName: string;
|
||||||
|
propertyDescription: string;
|
||||||
|
|
||||||
|
|
||||||
|
constructor(propertyName: string, propertyDescription: string) {
|
||||||
|
this.propertyName = propertyName;
|
||||||
|
this.propertyDescription = propertyDescription;
|
||||||
|
}
|
||||||
|
}
|
30
src/app/project/game-model/inventory/ItemQuality.ts
Normal file
30
src/app/project/game-model/inventory/ItemQuality.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import {ItemProperty} from "./ItemProperty";
|
||||||
|
import {ItemPropertyDescription} from "./ItemPropertyDescription";
|
||||||
|
|
||||||
|
export class ItemQuality {
|
||||||
|
quality_step: number
|
||||||
|
quality_propertes: ItemProperty[] = []
|
||||||
|
|
||||||
|
|
||||||
|
constructor(quality_step: number) {
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
85
src/app/project/parser/ItemParser.ts
Normal file
85
src/app/project/parser/ItemParser.ts
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import {StoreComponent} from "../../../../app/storage/StoreComponent";
|
||||||
|
import {Item} from "../game-model/inventory/Item";
|
||||||
|
import {ItemQuality} from "../game-model/inventory/ItemQuality";
|
||||||
|
import {ItemProperty} from "../game-model/inventory/ItemProperty";
|
||||||
|
import {ItemPropertyDescription} from "../game-model/inventory/ItemPropertyDescription";
|
||||||
|
import {ModelComponentType} from "../game-model/ModelComponentType";
|
||||||
|
|
||||||
|
export class ItemParser {
|
||||||
|
|
||||||
|
public static parseItems(items: StoreComponent[]): Item[] {
|
||||||
|
const parsedItems: Item[] = []
|
||||||
|
items.forEach(item => parsedItems.push(this.parseSingleItem(JSON.parse(item.jsonString))));
|
||||||
|
return parsedItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static parseSingleItem(itemData: any): Item {
|
||||||
|
const componentName = itemData.componentName;
|
||||||
|
const componentDescription = itemData.componentDescription;
|
||||||
|
|
||||||
|
const perQualityProperties = this.parseQualityPropertyReferences(itemData.perQualityProperties);
|
||||||
|
const qualties = this.parseQualities(itemData.possible_qualities, perQualityProperties)
|
||||||
|
const itemProperties = this.parseItemProperties(itemData.itemProperties)
|
||||||
|
|
||||||
|
const item = new Item(componentName, componentDescription, ModelComponentType.ITEM);
|
||||||
|
item.possible_qualities = qualties;
|
||||||
|
item.itemProperties = itemProperties;
|
||||||
|
item.perQualityProperties = perQualityProperties;
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static parseItemProperties(propertyData: any): ItemProperty[] {
|
||||||
|
const itemProperties : ItemProperty[] = []
|
||||||
|
for(let i=0; i<propertyData.length; i++) {
|
||||||
|
const propertyName = propertyData[i].propertyName;
|
||||||
|
const propertyDescription = propertyData[i].propertyDescription;
|
||||||
|
const property = propertyData[i].property;
|
||||||
|
|
||||||
|
itemProperties.push(new ItemProperty(propertyName, propertyDescription, property))
|
||||||
|
}
|
||||||
|
return itemProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static parseQualities(qualityData: any, perQualityProperties: ItemPropertyDescription[]): ItemQuality[] {
|
||||||
|
const qualities: ItemQuality[] = []
|
||||||
|
for(let i=0; i<qualityData.length; i++){
|
||||||
|
const qualityStep = qualityData[i].quality_step;
|
||||||
|
const qualityProperties = this.parseQualityProperty(qualityData[i].quality_propertes, perQualityProperties)
|
||||||
|
|
||||||
|
const itemQuality = new ItemQuality(qualityStep);
|
||||||
|
itemQuality.quality_propertes = qualityProperties;
|
||||||
|
qualities.push(itemQuality)
|
||||||
|
}
|
||||||
|
|
||||||
|
return qualities;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static parseQualityProperty(qualityPropertyData: any, propertyDescriptions: ItemPropertyDescription[]): ItemProperty[] {
|
||||||
|
const result: ItemProperty[] = []
|
||||||
|
for(let i=0; i<qualityPropertyData.length; i++){
|
||||||
|
const propertyName = qualityPropertyData[i].propertyName;
|
||||||
|
const propertyDescription = this.findMappingPropertyDescription(propertyDescriptions, propertyName)!.propertyDescription
|
||||||
|
const property = qualityPropertyData[i].property;
|
||||||
|
|
||||||
|
result.push(new ItemProperty(propertyName, propertyDescription, property))
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static findMappingPropertyDescription(propertyDescriptions: ItemPropertyDescription[], propertyName: string) {
|
||||||
|
return propertyDescriptions.find(property => property.propertyName === propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static parseQualityPropertyReferences(qualityPropertyData: any): ItemPropertyDescription[] {
|
||||||
|
const result: ItemPropertyDescription[] = []
|
||||||
|
for(let i=0; i<qualityPropertyData.length; i++){
|
||||||
|
const propertyName = qualityPropertyData[i].propertyName;
|
||||||
|
const propertyDescription = qualityPropertyData[i].propertyDescription;
|
||||||
|
result.push(new ItemPropertyDescription(propertyName, propertyDescription))
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
38
src/app/project/serializer/ItemSerializer.ts
Normal file
38
src/app/project/serializer/ItemSerializer.ts
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import {Item} from "../game-model/inventory/Item";
|
||||||
|
import {StoreComponent} from "../../../../app/storage/StoreComponent";
|
||||||
|
import {SerializeConstants} from "./SerializeConstants";
|
||||||
|
import {ItemQuality} from "../game-model/inventory/ItemQuality";
|
||||||
|
import {ItemPropertyDescription} from "../game-model/inventory/ItemPropertyDescription";
|
||||||
|
import {ItemProperty} from "../game-model/inventory/ItemProperty";
|
||||||
|
|
||||||
|
export class ItemSerializer {
|
||||||
|
|
||||||
|
public static serializeItems(items: Item[]): StoreComponent[] {
|
||||||
|
const storedItems: StoreComponent[] = []
|
||||||
|
items.forEach(item => storedItems.push(this.serializeSingleItem(item)))
|
||||||
|
return storedItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static serializeSingleItem(item: Item): StoreComponent {
|
||||||
|
const fileName = item.componentName;
|
||||||
|
const componentType = item.type;
|
||||||
|
const jsonString = JSON.stringify(item,(key, value) => {
|
||||||
|
if(key === 'perQualityProperties') {
|
||||||
|
return value;
|
||||||
|
} else if(key == 'quality_propertes') {
|
||||||
|
return value.map((prop: ItemProperty) => ({
|
||||||
|
...prop,
|
||||||
|
propertyDescription: undefined
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(key === 'unsaved' || key === 'type') {
|
||||||
|
return undefined;
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}, SerializeConstants.JSON_INDENT)
|
||||||
|
|
||||||
|
return new StoreComponent(jsonString, fileName, componentType);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
<mat-action-list>
|
||||||
|
<mat-list-item class="item" *ngFor="let item of gameModel!.inventoryItems"
|
||||||
|
(dblclick)="onOpenItemEditor(item)" (click)="selectItem(item)"
|
||||||
|
[ngClass]="selectedItem === item ?'selected-item':''"
|
||||||
|
(contextmenu)="selectItem(item)">
|
||||||
|
<mat-icon class="icon">inventory_2</mat-icon>{{item.componentName}}
|
||||||
|
</mat-list-item>
|
||||||
|
</mat-action-list>
|
@ -0,0 +1,14 @@
|
|||||||
|
.item {
|
||||||
|
min-height: 1.8em !important;
|
||||||
|
height: 1.8em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
margin-right: 10px;
|
||||||
|
color: #ccffff;
|
||||||
|
align-content: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-item {
|
||||||
|
background-color: #8696b6;
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { InventoryItemOverviewComponent } from './inventory-item-overview.component';
|
||||||
|
|
||||||
|
describe('InventoryItemOverviewComponent', () => {
|
||||||
|
let component: InventoryItemOverviewComponent;
|
||||||
|
let fixture: ComponentFixture<InventoryItemOverviewComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [InventoryItemOverviewComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(InventoryItemOverviewComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,34 @@
|
|||||||
|
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||||
|
import {GameModel} from "../../project/game-model/GameModel";
|
||||||
|
import {Item} from "../../project/game-model/inventory/Item";
|
||||||
|
import {MatActionList, MatListItem} from "@angular/material/list";
|
||||||
|
import {MatIcon} from "@angular/material/icon";
|
||||||
|
import {NgForOf} from "@angular/common";
|
||||||
|
import {ScriptAccount} from "../../project/game-model/scriptAccounts/ScriptAccount";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-inventory-item-overview',
|
||||||
|
templateUrl: './inventory-item-overview.component.html',
|
||||||
|
styleUrl: './inventory-item-overview.component.scss'
|
||||||
|
})
|
||||||
|
export class InventoryItemOverviewComponent {
|
||||||
|
|
||||||
|
@Input() gameModel: GameModel | undefined;
|
||||||
|
@Output() openItemEditor = new EventEmitter<Item>();
|
||||||
|
|
||||||
|
|
||||||
|
selectedItem: Item | undefined
|
||||||
|
|
||||||
|
onOpenItemEditor(item: Item) {
|
||||||
|
this.openItemEditor.emit(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
selectItem(item: Item) {
|
||||||
|
if(this.selectedItem != undefined && this.selectedItem!.componentName === item.componentName) {
|
||||||
|
this.selectedItem = undefined
|
||||||
|
} else {
|
||||||
|
this.selectedItem = item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,6 @@
|
|||||||
(dblclick)="onOpenScriptAccount(scriptAccount)" (click)="selectScriptAccount(scriptAccount)"
|
(dblclick)="onOpenScriptAccount(scriptAccount)" (click)="selectScriptAccount(scriptAccount)"
|
||||||
[ngClass]="selectedScriptAccount === scriptAccount ?'selected-item':''"
|
[ngClass]="selectedScriptAccount === scriptAccount ?'selected-item':''"
|
||||||
(contextmenu)="selectScriptAccount(scriptAccount)">
|
(contextmenu)="selectScriptAccount(scriptAccount)">
|
||||||
<mat-icon class="scriptAccount-icon">inventory_2</mat-icon>{{scriptAccount.componentName}}
|
<mat-icon class="scriptAccount-icon">analytics</mat-icon>{{scriptAccount.componentName}}
|
||||||
</mat-list-item>
|
</mat-list-item>
|
||||||
</mat-action-list>
|
</mat-action-list>
|
||||||
|
55
testModel/items/Item 1.json
Normal file
55
testModel/items/Item 1.json
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"componentName": "Item 1",
|
||||||
|
"componentDescription": "",
|
||||||
|
"possible_qualities": [
|
||||||
|
{
|
||||||
|
"quality_propertes": [
|
||||||
|
{
|
||||||
|
"propertyName": "Price",
|
||||||
|
"property": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quality_step": 0.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"quality_propertes": [
|
||||||
|
{
|
||||||
|
"propertyName": "Price",
|
||||||
|
"property": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quality_step": 0.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"quality_propertes": [
|
||||||
|
{
|
||||||
|
"propertyName": "Price",
|
||||||
|
"property": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quality_step": 0.75
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"quality_propertes": [
|
||||||
|
{
|
||||||
|
"propertyName": "Price",
|
||||||
|
"property": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quality_step": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"itemProperties": [
|
||||||
|
{
|
||||||
|
"propertyName": "Weight",
|
||||||
|
"propertyDescription": "Some Weights",
|
||||||
|
"property": 10
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"perQualityProperties": [
|
||||||
|
{
|
||||||
|
"propertyName": "Price",
|
||||||
|
"propertyDescription": "Price to buy item"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
55
testModel/items/Item 2.json
Normal file
55
testModel/items/Item 2.json
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"componentName": "Item 2",
|
||||||
|
"componentDescription": "",
|
||||||
|
"possible_qualities": [
|
||||||
|
{
|
||||||
|
"quality_propertes": [
|
||||||
|
{
|
||||||
|
"propertyName": "Price",
|
||||||
|
"property": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quality_step": 0.25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"quality_propertes": [
|
||||||
|
{
|
||||||
|
"propertyName": "Price",
|
||||||
|
"property": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quality_step": 0.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"quality_propertes": [
|
||||||
|
{
|
||||||
|
"propertyName": "Price",
|
||||||
|
"property": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quality_step": 0.75
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"quality_propertes": [
|
||||||
|
{
|
||||||
|
"propertyName": "Price",
|
||||||
|
"property": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quality_step": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"itemProperties": [
|
||||||
|
{
|
||||||
|
"propertyName": "Weight",
|
||||||
|
"propertyDescription": "Some Weights",
|
||||||
|
"property": 10
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"perQualityProperties": [
|
||||||
|
{
|
||||||
|
"propertyName": "Price",
|
||||||
|
"propertyDescription": "Price to buy item"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user