diff --git a/app/main.ts b/app/main.ts
index c4ffd82..e1bbffd 100644
--- a/app/main.ts
+++ b/app/main.ts
@@ -8,7 +8,7 @@ import {ModelComponentFileDirectory} from "./storage/ModelComponentFileDirectory
import {GamesystemStorage} from "./storage/storing/GamesystemStorage";
import {Character} from "../src/app/project/game-model/characters/Character";
import {CharacterStorage} from "./storage/storing/CharacterStorage";
-import {ItemStorage} from "./storage/storing/ItemStorage";
+import {ItemgroupStorage} from "./storage/storing/ItemgroupStorage";
let win: BrowserWindow | null = null;
const args = process.argv.slice(1),
@@ -97,6 +97,29 @@ function createWindow(): BrowserWindow {
click: () => {
win!.webContents.send('context-menu', "new-character");
}
+ },
+ {
+ label: "Itemgroup",
+ submenu: [
+ {
+ label: "Abstract Itemgroup",
+ click: () => {
+ win!.webContents.send('context-menu', "new-itemgroup-abstract")
+ }
+ },
+ {
+ label: "Concrete Itemgroup",
+ click: () => {
+ win!.webContents.send('context-menu', "new-itemgroup-concrete")
+ }
+ },
+ {
+ label: "Item",
+ click: () => {
+ win!.webContents.send("context-menu", "new-item")
+ }
+ }
+ ]
}
]
@@ -249,8 +272,9 @@ function recieveGameModelToStore(gameModel: StoredGameModel) {
const characterStorage = new CharacterStorage(path.join(projectDirectory, ModelComponentFileDirectory.CHARACTER_DIR_NAME))
characterStorage.storeCharacters(gameModel.storedCharacters)
- const itemStorage = new ItemStorage(path.join(projectDirectory, ModelComponentFileDirectory.ITEM_DIR_NAME))
- itemStorage.storeItem(gameModel.storedItems);
+ const itemgroupStorage = new ItemgroupStorage(path.join(projectDirectory, ModelComponentFileDirectory.ITEMGROUP_DIR_NAME))
+ itemgroupStorage.storeItemgroups(gameModel.storedItemgroups);
+ itemgroupStorage.storeItems(gameModel.storedItems)
}
/*function deleteComponent(component: DeleteModel) {
diff --git a/app/storage/ModelComponentFileDirectory.js b/app/storage/ModelComponentFileDirectory.js
index fa14422..eda48c4 100644
--- a/app/storage/ModelComponentFileDirectory.js
+++ b/app/storage/ModelComponentFileDirectory.js
@@ -7,5 +7,5 @@ exports.ModelComponentFileDirectory = ModelComponentFileDirectory;
ModelComponentFileDirectory.SCRIPTACCOUNT_DIR_NAME = "script-accounts";
ModelComponentFileDirectory.GAMESYSTEM_DIR_NAME = "gamesystems";
ModelComponentFileDirectory.CHARACTER_DIR_NAME = "characters";
-ModelComponentFileDirectory.ITEM_DIR_NAME = "items";
+ModelComponentFileDirectory.ITEMGROUP_DIR_NAME = "items";
//# sourceMappingURL=ModelComponentFileDirectory.js.map
\ No newline at end of file
diff --git a/app/storage/ModelComponentFileDirectory.ts b/app/storage/ModelComponentFileDirectory.ts
index 38e675a..c68a714 100644
--- a/app/storage/ModelComponentFileDirectory.ts
+++ b/app/storage/ModelComponentFileDirectory.ts
@@ -2,5 +2,5 @@ export class ModelComponentFileDirectory {
public static SCRIPTACCOUNT_DIR_NAME = "script-accounts"
public static GAMESYSTEM_DIR_NAME = "gamesystems";
public static CHARACTER_DIR_NAME = "characters";
- public static ITEM_DIR_NAME = "items";
+ static ITEMGROUP_DIR_NAME = "items";
}
diff --git a/app/storage/StoredGameModel.js b/app/storage/StoredGameModel.js
index 2ba280b..860b91d 100644
--- a/app/storage/StoredGameModel.js
+++ b/app/storage/StoredGameModel.js
@@ -2,11 +2,12 @@
Object.defineProperty(exports, "__esModule", { value: true });
exports.StoredGameModel = void 0;
class StoredGameModel {
- constructor(gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters, storedItems) {
+ constructor(gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters, storedItemgroups, storedItems) {
this.gameModelName = gameModelName;
this.storedGamesystems = storedGamesystems;
this.storedScriptAccounts = storedScriptAccounts;
this.storedCharacters = storedCharacters;
+ this.storedItemgroups = storedItemgroups;
this.storedItems = storedItems;
}
}
diff --git a/app/storage/StoredGameModel.ts b/app/storage/StoredGameModel.ts
index 5449edd..829b038 100644
--- a/app/storage/StoredGameModel.ts
+++ b/app/storage/StoredGameModel.ts
@@ -6,15 +6,17 @@ export class StoredGameModel {
storedGamesystems: StoreComponent[]
storedScriptAccounts: StoreComponent[]
storedCharacters: StoreComponent[]
+ storedItemgroups: StoreComponent[]
storedItems: StoreComponent[]
constructor(gameModelName: string, storedScriptAccounts: StoreComponent[], storedGamesystems: StoreComponent[],
- storedCharacters: StoreComponent[], storedItems: StoreComponent[]) {
+ storedCharacters: StoreComponent[], storedItemgroups: StoreComponent[], storedItems: StoreComponent[]) {
this.gameModelName = gameModelName;
this.storedGamesystems = storedGamesystems;
this.storedScriptAccounts = storedScriptAccounts;
this.storedCharacters = storedCharacters;
+ this.storedItemgroups = storedItemgroups;
this.storedItems = storedItems;
}
}
diff --git a/app/storage/loader/GameModelLoader.js b/app/storage/loader/GameModelLoader.js
index 5431d73..0b8447e 100644
--- a/app/storage/loader/GameModelLoader.js
+++ b/app/storage/loader/GameModelLoader.js
@@ -10,6 +10,8 @@ const CharacterLoader_1 = require("./CharacterLoader");
const ItemLoader_1 = require("./ItemLoader");
class GameModelLoader {
constructor(gameModelDir) {
+ this.loadedItemgroups = [];
+ this.loadedItems = [];
this.gameModelDir = gameModelDir;
}
loadGameModel() {
@@ -17,8 +19,8 @@ class GameModelLoader {
const storedScriptAccounts = this.loadScriptAccountComponents();
const storedGamesystems = this.loadGamesystems();
const storedCharacters = this.loadCharacters();
- const storedItems = this.loadItems();
- return new StoredGameModel_1.StoredGameModel(gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters, storedItems);
+ this.loadItemsAndItemgroups();
+ return new StoredGameModel_1.StoredGameModel(gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters, this.loadedItemgroups, this.loadedItems);
}
loadScriptAccountComponents() {
const scriptAccountDir = path.join(this.gameModelDir, ModelComponentFileDirectory_1.ModelComponentFileDirectory.SCRIPTACCOUNT_DIR_NAME);
@@ -35,10 +37,12 @@ class GameModelLoader {
const characterLoader = new CharacterLoader_1.CharacterLoader(characterDir);
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();
+ loadItemsAndItemgroups() {
+ const itemgroupDir = path.join(this.gameModelDir, ModelComponentFileDirectory_1.ModelComponentFileDirectory.ITEMGROUP_DIR_NAME);
+ const itemgroupLoader = new ItemLoader_1.ItemLoader(itemgroupDir);
+ itemgroupLoader.loadItemgroups();
+ this.loadedItems = itemgroupLoader.loadedItems;
+ this.loadedItemgroups = itemgroupLoader.loadedItemgroups;
}
}
exports.GameModelLoader = GameModelLoader;
diff --git a/app/storage/loader/GameModelLoader.ts b/app/storage/loader/GameModelLoader.ts
index 14dc146..9423d73 100644
--- a/app/storage/loader/GameModelLoader.ts
+++ b/app/storage/loader/GameModelLoader.ts
@@ -11,6 +11,9 @@ import {ItemLoader} from "./ItemLoader";
export class GameModelLoader {
gameModelDir: string
+ loadedItemgroups: StoreComponent[] = []
+ loadedItems: StoreComponent[] = []
+
constructor(gameModelDir: string) {
this.gameModelDir = gameModelDir;
@@ -22,9 +25,9 @@ export class GameModelLoader {
const storedScriptAccounts = this.loadScriptAccountComponents();
const storedGamesystems = this.loadGamesystems();
const storedCharacters = this.loadCharacters()
- const storedItems = this.loadItems();
+ this.loadItemsAndItemgroups();
- return new StoredGameModel(gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters, storedItems);
+ return new StoredGameModel(gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters, this.loadedItemgroups, this.loadedItems);
}
private loadScriptAccountComponents() {
@@ -46,9 +49,12 @@ export class GameModelLoader {
}
- private loadItems(): StoreComponent[] {
- const itemDir = path.join(this.gameModelDir, ModelComponentFileDirectory.ITEM_DIR_NAME);
- const itemLoader = new ItemLoader(itemDir)
- return itemLoader.loadItems();
+ private loadItemsAndItemgroups() {
+ const itemgroupDir = path.join(this.gameModelDir, ModelComponentFileDirectory.ITEMGROUP_DIR_NAME);
+ const itemgroupLoader = new ItemLoader(itemgroupDir);
+ itemgroupLoader.loadItemgroups();
+
+ this.loadedItems = itemgroupLoader.loadedItems;
+ this.loadedItemgroups = itemgroupLoader.loadedItemgroups;
}
}
diff --git a/app/storage/loader/ItemLoader.js b/app/storage/loader/ItemLoader.js
index 7536397..acb1bff 100644
--- a/app/storage/loader/ItemLoader.js
+++ b/app/storage/loader/ItemLoader.js
@@ -1,30 +1,58 @@
"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");
+const path = require("node:path");
+const ModelComponentType_1 = require("../../../src/app/project/game-model/ModelComponentType");
+const fs = require("node:fs");
class ItemLoader {
constructor(itemDir) {
+ this._loadedItemgroups = [];
+ this._loadedItems = [];
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);
+ loadItemgroups() {
+ this.loadItemgroupsRecursively(this.itemDir);
+ }
+ get loadedItemgroups() {
+ return this._loadedItemgroups;
+ }
+ get loadedItems() {
+ return this._loadedItems;
+ }
+ loadItemgroupsRecursively(currentDir) {
+ const itemgroupFiles = FileUtils_1.FileUtils.listFilesInDirectory(currentDir);
+ itemgroupFiles.forEach(itemgroupFile => {
+ if (fs.lstatSync(itemgroupFile).isDirectory()) {
+ this.loadItemgroupsRecursively(itemgroupFile);
+ }
+ else if (path.basename(itemgroupFile).endsWith(".json") && this.fileRepresentsItemgroup(itemgroupFile)) {
+ const loadedItemgroup = this.loadSingleItemgroup(itemgroupFile);
+ this._loadedItemgroups.push(loadedItemgroup);
+ }
+ else if (path.basename(itemgroupFile).endsWith(".json")) {
+ const loadedItem = this.loadSingleItem(itemgroupFile);
+ this._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);
+ loadSingleItemgroup(itemgroupFile) {
+ if (itemgroupFile.endsWith(".json")) {
+ const data = fs.readFileSync(itemgroupFile, "utf-8");
+ return new StoreComponent_1.StoreComponent(data, itemgroupFile, ModelComponentType_1.ModelComponentType.ITEMGROUP);
}
+ return undefined;
+ }
+ loadSingleItem(itemFile) {
+ if (itemFile.endsWith(".json")) {
+ const data = fs.readFileSync(itemFile, "utf-8");
+ return new StoreComponent_1.StoreComponent(data, itemFile, ModelComponentType_1.ModelComponentType.ITEM);
+ }
+ return undefined;
+ }
+ fileRepresentsItemgroup(file) {
+ return path.basename(path.dirname(file)) === path.parse(path.basename(file)).name;
}
}
exports.ItemLoader = ItemLoader;
diff --git a/app/storage/loader/ItemLoader.ts b/app/storage/loader/ItemLoader.ts
index aca7a9c..91b6a83 100644
--- a/app/storage/loader/ItemLoader.ts
+++ b/app/storage/loader/ItemLoader.ts
@@ -1,33 +1,65 @@
-import * as fs from "node:fs";
import {StoreComponent} from "../StoreComponent";
-import {ModelComponentType} from "../../../src/app/project/game-model/ModelComponentType";
import {FileUtils} from "../FileUtils";
+import * as path from "node:path";
+import {ModelComponentType} from "../../../src/app/project/game-model/ModelComponentType";
+import * as fs from "node:fs";
export class ItemLoader {
- private itemDir: string
+ itemDir: string
+ private _loadedItemgroups: StoreComponent[] = []
+ private _loadedItems: StoreComponent[] = []
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);
+ loadItemgroups(){
+ this.loadItemgroupsRecursively(this.itemDir);
+ }
+
+
+ get loadedItemgroups(): StoreComponent[] {
+ return this._loadedItemgroups;
+ }
+
+ get loadedItems(): StoreComponent[] {
+ return this._loadedItems;
+ }
+
+ private loadItemgroupsRecursively(currentDir: string) {
+ const itemgroupFiles = FileUtils.listFilesInDirectory(currentDir);
+
+ itemgroupFiles.forEach(itemgroupFile => {
+ if(fs.lstatSync(itemgroupFile).isDirectory()) {
+ this.loadItemgroupsRecursively(itemgroupFile);
+ } else if(path.basename(itemgroupFile).endsWith(".json") && this.fileRepresentsItemgroup(itemgroupFile)){
+ const loadedItemgroup = this.loadSingleItemgroup(itemgroupFile)!;
+ this._loadedItemgroups.push(loadedItemgroup)
+ } else if(path.basename(itemgroupFile).endsWith(".json")) {
+ const loadedItem = this.loadSingleItem(itemgroupFile)!;
+ this._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)
+ private loadSingleItemgroup(itemgroupFile: string): StoreComponent | undefined {
+ if(itemgroupFile.endsWith(".json")) {
+ const data = fs.readFileSync(itemgroupFile, "utf-8");
+ return new StoreComponent(data, itemgroupFile, ModelComponentType.ITEMGROUP);
}
+ return undefined
+ }
+
+ private loadSingleItem(itemFile: string) {
+ if(itemFile.endsWith(".json")) {
+ const data = fs.readFileSync(itemFile, "utf-8");
+ return new StoreComponent(data, itemFile, ModelComponentType.ITEM);
+ }
+ return undefined
+ }
+
+ private fileRepresentsItemgroup(file: string): boolean {
+ return path.basename(path.dirname(file)) === path.parse(path.basename(file)).name;
}
}
diff --git a/app/storage/storing/ItemgroupStorage.js b/app/storage/storing/ItemgroupStorage.js
new file mode 100644
index 0000000..2851c97
--- /dev/null
+++ b/app/storage/storing/ItemgroupStorage.js
@@ -0,0 +1,30 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ItemgroupStorage = void 0;
+const FileUtils_1 = require("../FileUtils");
+const path = require("node:path");
+const fs = require("node:fs");
+class ItemgroupStorage {
+ constructor(itemgroupDir) {
+ this.itemgroupDir = itemgroupDir;
+ FileUtils_1.FileUtils.prepareDirectoryFroWriting(this.itemgroupDir);
+ }
+ storeItemgroups(itemgroups) {
+ itemgroups.forEach(itemgroup => {
+ this.storeItemgroup(itemgroup);
+ });
+ }
+ storeItemgroup(itemgroup) {
+ const file = path.join(...itemgroup.fileName.split("/"));
+ const completeFileName = path.join(this.itemgroupDir, file);
+ const itemgroupDirectory = path.join(...itemgroup.fileName.split("/").slice(0, -1));
+ const completeItemgroupDirectory = path.join(this.itemgroupDir, itemgroupDirectory);
+ FileUtils_1.FileUtils.prepareDirectoryFroWriting(completeItemgroupDirectory);
+ fs.writeFileSync(completeFileName + ".json", itemgroup.jsonString, "utf-8");
+ }
+ storeItems(storedItems) {
+ storedItems.forEach(item => this.storeItemgroup(item));
+ }
+}
+exports.ItemgroupStorage = ItemgroupStorage;
+//# sourceMappingURL=ItemgroupStorage.js.map
\ No newline at end of file
diff --git a/app/storage/storing/ItemgroupStorage.ts b/app/storage/storing/ItemgroupStorage.ts
new file mode 100644
index 0000000..84f7fdd
--- /dev/null
+++ b/app/storage/storing/ItemgroupStorage.ts
@@ -0,0 +1,35 @@
+import {FileUtils} from "../FileUtils";
+import {StoreComponent} from "../StoreComponent";
+import * as path from "node:path";
+import * as fs from "node:fs";
+
+export class ItemgroupStorage {
+ private itemgroupDir: string
+
+
+ constructor(itemgroupDir: string) {
+ this.itemgroupDir = itemgroupDir;
+ FileUtils.prepareDirectoryFroWriting(this.itemgroupDir);
+ }
+
+ public storeItemgroups(itemgroups: StoreComponent[]) {
+ itemgroups.forEach(itemgroup => {
+ this.storeItemgroup(itemgroup)
+ })
+ }
+
+ private storeItemgroup(itemgroup: StoreComponent) {
+ const file = path.join(... itemgroup.fileName.split("/"));
+ const completeFileName = path.join(this.itemgroupDir, file);
+
+ const itemgroupDirectory = path.join(... itemgroup.fileName.split("/").slice(0, -1))
+ const completeItemgroupDirectory = path.join(this.itemgroupDir, itemgroupDirectory)
+ FileUtils.prepareDirectoryFroWriting(completeItemgroupDirectory);
+ fs.writeFileSync(completeFileName + ".json", itemgroup.jsonString, "utf-8")
+ }
+
+
+ storeItems(storedItems: StoreComponent[]) {
+ storedItems.forEach(item => this.storeItemgroup(item))
+ }
+}
diff --git a/e2e/game-model/gamesystems/CreateGamesystem.spec.ts b/e2e/game-model/gamesystems/CreateGamesystem.spec.ts
deleted file mode 100644
index fffea92..0000000
--- a/e2e/game-model/gamesystems/CreateGamesystem.spec.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { test, expect } from '@playwright/test';
-import {GamesystemTrainer} from "./GamesystemTrainer";
-import {ProductGamesystem} from "../../../src/app/project/game-model/gamesystems/ProductGamesystem";
-test.describe('Test Create Gamesystems', () => {
-
- test('Test creating gamesystem with invalid name', async => {
- const gameModel = GamesystemTrainer.givenEmptyGameModel();
- let result = gameModel.createGamesystem(undefined, undefined);
- expect(result).toBeUndefined();
-
- result = gameModel.createGamesystem(null, undefined);
- expect(result).toBeUndefined();
- })
-
- test("Test creating gamesystem with valid name but without parent", async => {
- const gameModel = GamesystemTrainer.givenEmptyGameModel();
- let result = gameModel.createGamesystem(GamesystemTrainer.SIMPLEGAMESYSTEMNAME, undefined);
- expect(result).toBeDefined();
- expect(gameModel.gamesystems.length).toEqual(1);
- expect(gameModel.findGamesystem(GamesystemTrainer.SIMPLEGAMESYSTEMNAME)).toBeDefined();
- })
-
- test("Test creating Gamesystem with valid name but with Product Parent", async => {
- const gameModel = GamesystemTrainer.givenGameModelWithProductGamesytemOnTopLayer();
- let result = gameModel.createGamesystem(GamesystemTrainer.SIMPLEGAMESYSTEM_LEAF_LEFT, GamesystemTrainer.TOP_PRODUCT_GAMESYSTEM_NAME);
- expect(result).toBeDefined();
- expect(result.parentGamesystem!.componentName).toEqual(GamesystemTrainer.TOP_PRODUCT_GAMESYSTEM_NAME);
- expect(result.parentGamesystem!.innerGamesystems.length).toEqual(3);
- expect(result.parentGamesystem!.innerGamesystems.includes(result)).toBeTruthy();
- })
-
- test("Test creating Gamesystem with valid name but with Simple Parent", async() => {
- const gameModel = GamesystemTrainer.givenGameModelWithSimpleGamesystemOnTopLayer();
- let result = gameModel.createGamesystem(GamesystemTrainer.SIMPLEGAMESYSTEM_LEAF_LEFT, GamesystemTrainer.SIMPLEGAMESYSTEMNAME);
- expect(result).toBeDefined();
- expect(gameModel.gamesystems.length).toEqual(1);
- expect(gameModel.gamesystems[0]).toBeInstanceOf(ProductGamesystem);
- expect(gameModel.gamesystems[0]).toEqual(result.parentGamesystem);
- expect((gameModel.gamesystems[0] as ProductGamesystem).innerGamesystems.length).toEqual(1);
- expect((gameModel.gamesystems[0] as ProductGamesystem).innerGamesystems.includes(result)).toBeTruthy();
- })
-
-
-});
diff --git a/e2e/game-model/scriptAccounts/ScriptAccountTest.spec.ts b/e2e/game-model/scriptAccounts/ScriptAccountTest.spec.ts
deleted file mode 100644
index 27aaed2..0000000
--- a/e2e/game-model/scriptAccounts/ScriptAccountTest.spec.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import { BrowserContext, ElectronApplication, Page, _electron as electron } from 'playwright';
-import { test, expect } from '@playwright/test';
-import * as PATH from 'path';
-import {GameModel} from "../../../src/app/project/game-model/GameModel";
-import {Gamesystem} from "../../src/app/project/game-model/gamesystems/Gamesystem";
-import {ScriptAccount} from "../../../src/app/project/game-model/scriptAccounts/ScriptAccount";
-import {ModelComponentType} from "../../../src/app/project/game-model/ModelComponentType";
-
-test.describe('Test ScriptAccounts', () => {
-
- test("Test ScriptAccount Creation", async () => {
- const scriptAccunt = new ScriptAccount("ScriptAccount", "Description");
-
- expect(scriptAccunt.componentName).toEqual("ScriptAccount");
- expect(scriptAccunt.componentDescription).toEqual("Description");
- expect(scriptAccunt.type).toEqual(ModelComponentType.SCRIPTACCOUNT);
- expect(scriptAccunt.minValue).toEqual(0);
- expect(scriptAccunt.maxValue).toEqual(100);
- })
-
- test("Test Adding ScriptAccounts", async () => {
- const gameModel: GameModel = new GameModel("GameModel");
-
- let scriptAccount =gameModel.createScriptAccount("ScriptAccount");
- expect(scriptAccount).toBeDefined();
- expect(gameModel.scriptAccounts.length).toEqual(1);
- expect(gameModel.scriptAccounts.includes(scriptAccount)).toBeTruthy();
-
- //Test adding scriptAccount with already existing name
- const scriptAccount2 = gameModel.createScriptAccount("ScriptAccount")
- expect(scriptAccount2).toBeUndefined();
- expect(gameModel.scriptAccounts.length).toEqual(1);
-
- //Test for adding invalid names as scriptaccount names (null/undefined/empty)
- let result = gameModel.createScriptAccount(null);
- expect(result).toBeUndefined();
- expect(gameModel.scriptAccounts.length).toEqual(1);
- result = gameModel.createScriptAccount(undefined);
- expect(result).toBeUndefined();
- expect(gameModel.scriptAccounts.length).toEqual(1);
- result = gameModel.createScriptAccount("");
- expect(result).toBeUndefined();
- expect(gameModel.scriptAccounts.length).toEqual(1);
- })
-
- test("test Removing ScriptAccounts", async () => {
- const gameModel: GameModel = new GameModel("GameModel");
- let scriptAccount = new ScriptAccount("test", "")
-
- gameModel.removeScriptAccount(scriptAccount);
- expect(gameModel.scriptAccounts.length).toEqual(0);
-
- scriptAccount = gameModel.createScriptAccount("ScriptAccount");
- gameModel.removeScriptAccount(scriptAccount);
- expect(gameModel.scriptAccounts.length).toEqual(0);
-
- gameModel.removeScriptAccount(undefined);
- expect(gameModel.scriptAccounts.length).toEqual(0);
-
- gameModel.removeScriptAccount(null);
- expect(gameModel.scriptAccounts.length).toEqual(0);
-
- scriptAccount = gameModel.createScriptAccount(scriptAccount);
- let scriptAccount2 = gameModel.createScriptAccount("ScriptAccount 2");
-
- gameModel.removeScriptAccount(scriptAccount);
- expect(gameModel.scriptAccounts.length).toEqual(1);
- expect(gameModel.scriptAccounts.includes(scriptAccount2)).toBeTruthy();
- })
-
-});
diff --git a/src/app/app.component.html b/src/app/app.component.html
index 83a3954..c8c374d 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1,13 +1,14 @@
+ (click)="openScriptAccountsOverview()">inventory_2
-
+
+
@@ -25,13 +26,15 @@
-
+
-
+
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 64992c3..4bfac7a 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -25,10 +25,17 @@ import {CharacterOverviewComponent} from "./side-overviews/character-overview/ch
import {CharacterSerializer} from "./project/serializer/CharacterSerializer";
import {CharacterParser} from "./project/parser/characterParser/CharacterParser";
import {TemplateType} from "./project/game-model/templates/TemplateType";
-import {TemplateTypeUtilities} from "./project/game-model/templates/TemplateTypeUtilities";
import {SimpleTemplateGamesystem} from "./project/game-model/templates/simpleGamesystem/SimpleTemplateGamesystem";
import {ItemSerializer} from "./project/serializer/ItemSerializer";
-import {ItemParser} from "./project/parser/ItemParser";
+import {ItemgroupParser} from "./project/parser/itemParser/ItemgroupParser";
+import {ItemParser} from "./project/parser/itemParser/ItemParser";
+import {ItemgroupCreator} from "./project/game-model/utils/creator/ItemgroupCreator";
+import {ItemOverviewComponent} from "./side-overviews/item-overview/item-overview.component";
+import {Overview} from "./side-overviews/Overview";
+import {ItemCreator} from "./project/game-model/utils/creator/ItemCreator";
+import {ScriptAccountCreator} from "./project/game-model/utils/creator/ScriptAccountCreator";
+import {CharacterCreator} from "./project/game-model/utils/creator/CharacterCreator";
+import {GamesystemCreator} from "./project/game-model/utils/creator/GamesystemCreator";
@Component({
selector: 'app-root',
@@ -43,6 +50,7 @@ export class AppComponent implements OnInit{
@ViewChild('scriptAccountOverview') scriptAccountOverview: ScriptAccountOverviewComponent | undefined
@ViewChild('gamesystemOverview') gamesystemOverview: GamescriptOverviewComponent | undefined
@ViewChild('characterOverview') characterOverview: CharacterOverviewComponent | undefined
+ @ViewChild('itemOverview') itemOverview: ItemOverviewComponent | undefined
gameModel: GameModel | undefined
@@ -81,12 +89,45 @@ export class AppComponent implements OnInit{
} else if(message.startsWith("new")) {
const splittedMessage = message.split("-");
const modelComponentType = ModelComponentTypeUtillities.fromString(splittedMessage[1]);
- const templateType = TemplateTypeUtilities.fromString(splittedMessage[2]);
- if(modelComponentType != undefined) {
- this.onCreateModelComponent(modelComponentType, templateType);
- } else {
- console.log("[ERROR] [App-Component] Unknown Context-Menu Command!")
+ if(modelComponentType !== undefined) {
+ let creationContext = "";
+ if(splittedMessage.length > 2) {
+ creationContext = splittedMessage[2];
+ }
+
+ let componentCreator;
+ switch (modelComponentType) {
+ case ModelComponentType.ITEMGROUP: {
+ componentCreator = new ItemgroupCreator(creationContext, this.gameModel!, this.selectedModelComponent);
+ } break
+ case ModelComponentType.ITEM: {
+ componentCreator = new ItemCreator(creationContext, this.gameModel!, this.selectedModelComponent);
+ } break
+ case ModelComponentType.SCRIPTACCOUNT: {
+ componentCreator = new ScriptAccountCreator(creationContext, this.gameModel!, this.selectedModelComponent);
+ } break
+ case ModelComponentType.CHARACTER: {
+ componentCreator = new CharacterCreator(creationContext, this.gameModel!, this.selectedModelComponent);
+ } break
+ case ModelComponentType.GAMESYTEM: {
+ componentCreator = new GamesystemCreator(creationContext, this.gameModel!, this.selectedModelComponent);
+ } break
+ }
+
+ if(componentCreator) {
+ const createdModel = componentCreator.createModelComponent();
+ this.openModelComponent(createdModel!)
+
+ const openedOverview = this.openedOverview;
+ if(openedOverview) {
+ openedOverview.refresh()
+ }
+
+ } else {
+ console.log("[ERROR] Unknown Creation Command: ", message)
+ }
}
+
}
}
@@ -109,6 +150,7 @@ export class AppComponent implements OnInit{
}
}break
+
}
}
@@ -133,53 +175,6 @@ export class AppComponent implements OnInit{
})
}
- private onCreateModelComponent(modelComponentType: ModelComponentType, templateType: TemplateType | undefined) {
- switch (modelComponentType) {
- case ModelComponentType.SCRIPTACCOUNT: this.onCreateNewScriptAccount(); break
- case ModelComponentType.GAMESYTEM: this.onCreateNewGamesystem(templateType); break
- case ModelComponentType.CHARACTER: this.onCreateNewCharacter(); break
- }
- }
-
- private onCreateNewScriptAccount() {
- const createdScriptAccount = this.gameModel!.createScriptAccount("New ScriptAccount");
- if(createdScriptAccount != undefined) {
- this.editor?.openGameModelComponent(createdScriptAccount);
- } else {
- console.log("[DEBUG] [App-Component] ScriptAccount could not be created (Name not unique)");
- }
- }
-
- private onCreateNewGamesystem(templateType: TemplateType | undefined) {
- let parentGamesystemName = undefined
- if(this.openContent != ModelComponentType.GAMESYTEM) {
- this.openGamesystemsOverview();
- } else {
- parentGamesystemName = this.gamesystemOverview!.selectedGamesystemName;
- }
-
-
- let createdGamesystem;
- if(parentGamesystemName == undefined) {
- createdGamesystem = this.gameModel?.createSimpleGamesystem("New Gamesystem", templateType);
- } else {
- createdGamesystem = this.gameModel!.createSimpleGamesystemWithParent("New Gamesystem", parentGamesystemName, templateType)
- }
-
- if(createdGamesystem != undefined) {
- this.gamesystemOverview!.refresh();
- this.editor?.openGameModelComponent(createdGamesystem);
- }
- }
-
- private onCreateNewCharacter() {
- const createdCharacter = this.gameModel!.createCharacter("New Character")
- if(createdCharacter != undefined) {
- this.editor?.openGameModelComponent(createdCharacter);
- } else {
- console.log("[DEBUG] [App-Component] ScriptAccount could not be created (Name not unique)");
- }
- }
private getSelectedModelComponent(): ModelComponent | undefined {
if(this.openContent == ModelComponentType.SCRIPTACCOUNT) {
@@ -225,7 +220,12 @@ export class AppComponent implements OnInit{
const characterParser = new CharacterParser(characterTemplateSystems, characterRelationTemplateSystems, gameModel.scriptAccounts);
gameModel.characters = characterParser.parseCharacters(storedGameModel.storedCharacters)
- gameModel.inventoryItems = ItemParser.parseItems(storedGameModel.storedItems)
+ const itemgroupParser = new ItemgroupParser();
+ itemgroupParser.parseItemgroups(storedGameModel.storedItemgroups);
+ gameModel.itemgroups = itemgroupParser.getParsedTopItemgroups();
+
+ const itemParser = new ItemParser(itemgroupParser.getParsedItemgroups())
+ itemParser.parseItems(storedGameModel.storedItems);
this.gameModel = gameModel;
}
@@ -235,11 +235,12 @@ export class AppComponent implements OnInit{
const storedScriptAccounts = ScriptAccountSerializer.serializeScriptAccounts(this.gameModel.scriptAccounts)
const storedGamesystems: StoreComponent[] = GamesystemSerializer.serializeGamesystems(this.gameModel.gamesystems)
const storedCharacters: StoreComponent[] = CharacterSerializer.serializeCharacters(this.gameModel.characters)
- const storedItems: StoreComponent[] = ItemSerializer.serializeItems(this.gameModel.inventoryItems);
- console.log(this.gameModel.inventoryItems)
- const storeModel = new StoredGameModel(this.gameModel.gameModelName, storedScriptAccounts,
- storedGamesystems, storedCharacters, storedItems)
+ const itemSerializer = new ItemSerializer();
+ const storedItemgroups: StoreComponent[] = itemSerializer.serializeItemgroups(this.gameModel!.itemgroups);
+ const storedItems: StoreComponent[] = itemSerializer.getSerializedItems()
+
+ const storeModel = new StoredGameModel(this.gameModel.gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters, storedItemgroups, storedItems)
if(this.electronService.isElectron) {
this.electronService.ipcRenderer.send('save-model', storeModel)
@@ -262,8 +263,8 @@ export class AppComponent implements OnInit{
this.drawer!.open()
}
- openContentOverview(contentType: ModelComponentType) {
- this.openContent = contentType;
+ openOverview(overviewType: ModelComponentType) {
+ this.openContent = overviewType;
this.drawer!.open();
}
@@ -296,5 +297,26 @@ export class AppComponent implements OnInit{
}
}
+ get selectedModelComponent(): ModelComponent | undefined {
+ switch (this.openContent) {
+ case ModelComponentType.GAMESYTEM: return this.gamesystemOverview!.getSelectedGamesystem();
+ case ModelComponentType.CHARACTER: return this.characterOverview!.selectedCharacter;
+ case ModelComponentType.SCRIPTACCOUNT: return this.scriptAccountOverview!.selectedScriptAccount;
+ case ModelComponentType.ITEMGROUP: return this.itemOverview!.selectedModelComponent;
+ case ModelComponentType.ITEM: return this.itemOverview!.selectedModelComponent;
+ default: return undefined
+ }
+ }
+ get openedOverview(): Overview | undefined {
+ if(this.openContent === ModelComponentType.ITEMGROUP || this.openContent === ModelComponentType.ITEM) {
+ return this.itemOverview;
+ } else if(this.openContent === ModelComponentType.SCRIPTACCOUNT) {
+ return this.scriptAccountOverview;
+ } else if(this.openContent === ModelComponentType.CHARACTER) {
+ return this.characterOverview;
+ } else if(this.openContent === ModelComponentType.GAMESYTEM) {
+ return this.gamesystemOverview;
+ }
+ }
}
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index a3bac22..152535a 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -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, MatCardActions, MatCardContent, MatCardHeader, MatCardTitle} 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";
@@ -72,7 +72,7 @@ import {CharacterOverviewComponent} from "./side-overviews/character-overview/ch
import {CharacterEditorComponent} from "./editor/character-editor/character-editor.component";
import {
MatAccordion,
- MatExpansionPanel,
+ MatExpansionPanel, MatExpansionPanelDescription,
MatExpansionPanelHeader,
MatExpansionPanelTitle
} from "@angular/material/expansion";
@@ -82,14 +82,15 @@ import {
import {
StateInitialCellComponent
} from "./editor/gamesystem-editor/state-editor/simple-state-editor/state-initial-cell/state-initial-cell.component";
+import {ItemOverviewComponent} from "./side-overviews/item-overview/item-overview.component";
+import {ItemGroupEditorComponent} from "./editor/items/item-group-editor/item-group-editor.component";
+import {ItemEditorComponent} from "./editor/items/item-editor/item-editor.component";
import {
- InventoryItemOverviewComponent
-} from "./side-overviews/inventory-item-overview/inventory-item-overview.component";
-import {InventoryItemEditorComponent} from "./editor/inventory-item-editor/inventory-item-editor.component";
+ ItemgroupInheritorComponent
+} from "./editor/items/item-editor/itemgroup-inheritor/itemgroup-inheritor.component";
import {
- ItemPropertyEditorComponent
-} from "./editor/inventory-item-editor/item-property-editor/item-property-editor.component";
-
+ InheritedItemCharacteristicEditorComponent
+} from "./editor/items/item-editor/inherited-item-characteristic-editor/inherited-item-characteristic-editor.component";
// AoT requires an exported function for factories
const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './assets/i18n/', '.json');
@@ -115,9 +116,11 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl
CharacterEditorComponent,
TemplateSpecificatorComponent,
StateInitialCellComponent,
- InventoryItemOverviewComponent,
- InventoryItemEditorComponent,
- ItemPropertyEditorComponent
+ ItemOverviewComponent,
+ ItemGroupEditorComponent,
+ ItemEditorComponent,
+ ItemgroupInheritorComponent,
+ InheritedItemCharacteristicEditorComponent
],
imports: [
BrowserModule,
@@ -181,7 +184,7 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl
MatExpansionPanelTitle,
MatCardTitle,
MatExpansionPanelHeader,
- MatCardActions,
+ MatExpansionPanelDescription
],
providers: [],
bootstrap: [AppComponent]
diff --git a/src/app/editor/editor.component.html b/src/app/editor/editor.component.html
index e856a70..ae86488 100644
--- a/src/app/editor/editor.component.html
+++ b/src/app/editor/editor.component.html
@@ -16,11 +16,11 @@
[scriptAccounts]="gameModel!.scriptAccounts">
+ [gameModel]="gameModel!"
+ >
+
-
-
+
+
diff --git a/src/app/editor/editor.component.ts b/src/app/editor/editor.component.ts
index b69cdbf..2b31b33 100644
--- a/src/app/editor/editor.component.ts
+++ b/src/app/editor/editor.component.ts
@@ -7,6 +7,7 @@ import {State} from "../project/game-model/gamesystems/states/State";
import {Transition} from "../project/game-model/gamesystems/transitions/Transition";
import {ModelComponentType} from "../project/game-model/ModelComponentType";
import {Character} from "../project/game-model/characters/Character";
+import {ItemGroup} from "../project/game-model/inventory/ItemGroup";
import {Item} from "../project/game-model/inventory/Item";
@@ -28,7 +29,6 @@ export class EditorComponent {
} else {
this.activeTab = this.gameModelComponents.findIndex(component => component.componentName === gameModelComponent.componentName);
}
- console.log(gameModelComponent)
}
closeGameModelComponent(gameModelComponent: ModelComponent) {
@@ -60,10 +60,17 @@ export class EditorComponent {
return undefined;
}
+ convertModelComponentToItemGroup(modelComponent: ModelComponent) {
+ if(modelComponent instanceof ItemGroup) {
+ return modelComponent as ItemGroup
+ }
+ return undefined;
+ }
+
convertModelComponentToItem(modelComponent: ModelComponent) {
if(modelComponent instanceof Item) {
- return modelComponent as Item
+ return modelComponent as Item;
}
- return undefined
+ return undefined;
}
}
diff --git a/src/app/editor/items/item-editor/inherited-item-characteristic-editor/inherited-item-characteristic-editor.component.html b/src/app/editor/items/item-editor/inherited-item-characteristic-editor/inherited-item-characteristic-editor.component.html
new file mode 100644
index 0000000..42bbb40
--- /dev/null
+++ b/src/app/editor/items/item-editor/inherited-item-characteristic-editor/inherited-item-characteristic-editor.component.html
@@ -0,0 +1,28 @@
+
diff --git a/src/app/editor/items/item-editor/inherited-item-characteristic-editor/inherited-item-characteristic-editor.component.scss b/src/app/editor/items/item-editor/inherited-item-characteristic-editor/inherited-item-characteristic-editor.component.scss
new file mode 100644
index 0000000..80c8212
--- /dev/null
+++ b/src/app/editor/items/item-editor/inherited-item-characteristic-editor/inherited-item-characteristic-editor.component.scss
@@ -0,0 +1,3 @@
+.mat-column-edit {
+ width: 32px;
+}
diff --git a/src/app/editor/items/item-editor/inherited-item-characteristic-editor/inherited-item-characteristic-editor.component.spec.ts b/src/app/editor/items/item-editor/inherited-item-characteristic-editor/inherited-item-characteristic-editor.component.spec.ts
new file mode 100644
index 0000000..437d097
--- /dev/null
+++ b/src/app/editor/items/item-editor/inherited-item-characteristic-editor/inherited-item-characteristic-editor.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { InheritedItemCharacteristicEditorComponent } from './inherited-item-characteristic-editor.component';
+
+describe('InheritedItemCharacteristicEditorComponent', () => {
+ let component: InheritedItemCharacteristicEditorComponent;
+ let fixture: ComponentFixture
;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [InheritedItemCharacteristicEditorComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(InheritedItemCharacteristicEditorComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/editor/items/item-editor/inherited-item-characteristic-editor/inherited-item-characteristic-editor.component.ts b/src/app/editor/items/item-editor/inherited-item-characteristic-editor/inherited-item-characteristic-editor.component.ts
new file mode 100644
index 0000000..167bd38
--- /dev/null
+++ b/src/app/editor/items/item-editor/inherited-item-characteristic-editor/inherited-item-characteristic-editor.component.ts
@@ -0,0 +1,42 @@
+import {Component, Input, OnInit} from '@angular/core';
+import {ItemGroup} from "../../../../project/game-model/inventory/ItemGroup";
+import {Item} from "../../../../project/game-model/inventory/Item";
+import {MatTableDataSource} from "@angular/material/table";
+import {ItemgroupCharacteristicValue} from "../../../../project/game-model/inventory/ItemgroupCharacteristicValue";
+
+@Component({
+ selector: 'app-inherited-item-characteristic-editor',
+ templateUrl: './inherited-item-characteristic-editor.component.html',
+ styleUrl: './inherited-item-characteristic-editor.component.scss'
+})
+export class InheritedItemCharacteristicEditorComponent implements OnInit{
+
+ @Input() inheritedItemgroup: ItemGroup | undefined
+ @Input() item: Item | undefined
+
+ datasource: MatTableDataSource = new MatTableDataSource();
+ displayedColumns: string[] = ['characteristic', 'value', 'edit']
+ editedItemgroupCharacteristicValue: ItemgroupCharacteristicValue | undefined
+
+ ngOnInit() {
+ this.item!.initializeItemCharacteristics();
+ this.datasource.data = this.findCharacteristicValuesByItemgroup(this.inheritedItemgroup!);
+ }
+
+
+ findCharacteristicValuesByItemgroup(itemGroup: ItemGroup): ItemgroupCharacteristicValue[] {
+ const result = this.item?.itemCharacteristicValues.filter(value => value.key.itemgroup.componentName === itemGroup.componentName);
+ if(result != undefined) {
+ return result;
+ }
+ return []
+ }
+
+ editCharacteristicValue(itemCharacteristicValue: ItemgroupCharacteristicValue): void {
+ this.editedItemgroupCharacteristicValue = itemCharacteristicValue;
+ }
+
+ finishEditing() {
+ this.editedItemgroupCharacteristicValue = undefined;
+ }
+}
diff --git a/src/app/editor/items/item-editor/item-editor.component.html b/src/app/editor/items/item-editor/item-editor.component.html
new file mode 100644
index 0000000..8ff7a5d
--- /dev/null
+++ b/src/app/editor/items/item-editor/item-editor.component.html
@@ -0,0 +1,20 @@
+
+
+ Inherited Itemgroups
+
+
+
+
+
+ {{itemgroup.componentName}}
+ {{itemgroup.componentDescription}}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/editor/items/item-editor/item-editor.component.scss b/src/app/editor/items/item-editor/item-editor.component.scss
new file mode 100644
index 0000000..6fd81c6
--- /dev/null
+++ b/src/app/editor/items/item-editor/item-editor.component.scss
@@ -0,0 +1,3 @@
+.panel-actions {
+ float: right;
+}
diff --git a/src/app/editor/items/item-editor/item-editor.component.spec.ts b/src/app/editor/items/item-editor/item-editor.component.spec.ts
new file mode 100644
index 0000000..a1e4546
--- /dev/null
+++ b/src/app/editor/items/item-editor/item-editor.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ItemEditorComponent } from './item-editor.component';
+
+describe('ItemEditorComponent', () => {
+ let component: ItemEditorComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [ItemEditorComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(ItemEditorComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/editor/items/item-editor/item-editor.component.ts b/src/app/editor/items/item-editor/item-editor.component.ts
new file mode 100644
index 0000000..05a673d
--- /dev/null
+++ b/src/app/editor/items/item-editor/item-editor.component.ts
@@ -0,0 +1,49 @@
+import {Component, Input} from '@angular/core';
+import {Item} from "../../../project/game-model/inventory/Item";
+import {ItemGroup} from "../../../project/game-model/inventory/ItemGroup";
+import {GameModel} from "../../../project/game-model/GameModel";
+import {MatDialog} from "@angular/material/dialog";
+import {ItemgroupInheritorComponent} from "./itemgroup-inheritor/itemgroup-inheritor.component";
+import {ItemgroupUtilities} from "../../../project/game-model/utils/ItemgroupUtilities";
+
+@Component({
+ selector: 'app-item-editor',
+ templateUrl: './item-editor.component.html',
+ styleUrl: './item-editor.component.scss'
+})
+export class ItemEditorComponent {
+
+ @Input() item: Item | undefined
+ @Input() gameModel: GameModel | undefined;
+
+
+ constructor(private dialog: MatDialog) {
+
+ }
+
+ onAddNewInheritedItemgroup() {
+ const itemgroups = this.item!.manuallyInheritedGroups.concat(this.item!.hierarchyInheritedGroups);
+ const dialogRef = this.dialog.open(ItemgroupInheritorComponent, {
+ data: this.gameModel!.itemgroupsAsList.filter(group => !itemgroups.includes(group)),
+ width: "400px"
+ })
+
+ dialogRef.afterClosed().subscribe(res => {
+ if(res != undefined) {
+ this.item!.addInheritedGroup(res);
+ }
+ })
+ }
+
+ deleteInheritedItemgroup(itemgroup: ItemGroup) {
+ this.item!.deleteInheritedGroup(itemgroup);
+ }
+
+ get automaticallyInheritedItemgroups() {
+ return ItemgroupUtilities.findItemgroupPathToItem(this.item!.componentName, this.gameModel!.itemgroups);
+ }
+
+ get manuallyAndHierarchyItemgroups() {
+ return this.item!.hierarchyInheritedGroups.concat(this.item!.manuallyInheritedGroups);
+ }
+}
diff --git a/src/app/editor/items/item-editor/itemgroup-inheritor/itemgroup-inheritor.component.html b/src/app/editor/items/item-editor/itemgroup-inheritor/itemgroup-inheritor.component.html
new file mode 100644
index 0000000..dc0ed23
--- /dev/null
+++ b/src/app/editor/items/item-editor/itemgroup-inheritor/itemgroup-inheritor.component.html
@@ -0,0 +1,13 @@
+Inherit Itemgroup
+
+
+ Select Itemgroup
+
+ {{itemgroup.componentName}}
+
+
+
+
+
+
+
diff --git a/src/app/editor/items/item-editor/itemgroup-inheritor/itemgroup-inheritor.component.scss b/src/app/editor/items/item-editor/itemgroup-inheritor/itemgroup-inheritor.component.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/editor/items/item-editor/itemgroup-inheritor/itemgroup-inheritor.component.spec.ts b/src/app/editor/items/item-editor/itemgroup-inheritor/itemgroup-inheritor.component.spec.ts
new file mode 100644
index 0000000..3bdf452
--- /dev/null
+++ b/src/app/editor/items/item-editor/itemgroup-inheritor/itemgroup-inheritor.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ItemgroupInheritorComponent } from './itemgroup-inheritor.component';
+
+describe('ItemgroupInheritorComponent', () => {
+ let component: ItemgroupInheritorComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [ItemgroupInheritorComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(ItemgroupInheritorComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/editor/items/item-editor/itemgroup-inheritor/itemgroup-inheritor.component.ts b/src/app/editor/items/item-editor/itemgroup-inheritor/itemgroup-inheritor.component.ts
new file mode 100644
index 0000000..c71a02e
--- /dev/null
+++ b/src/app/editor/items/item-editor/itemgroup-inheritor/itemgroup-inheritor.component.ts
@@ -0,0 +1,25 @@
+import {Component, Inject} from '@angular/core';
+import {MAT_DIALOG_DATA, MatDialogRef, MatDialogTitle} from "@angular/material/dialog";
+import {ItemGroup} from "../../../../project/game-model/inventory/ItemGroup";
+
+@Component({
+ selector: 'app-itemgroup-inheritor',
+ templateUrl: './itemgroup-inheritor.component.html',
+ styleUrl: './itemgroup-inheritor.component.scss'
+})
+export class ItemgroupInheritorComponent {
+
+ selectedItemgroup: ItemGroup | undefined
+
+ constructor(private dialogRef: MatDialogRef,
+ @Inject(MAT_DIALOG_DATA) public availableItemgroups: ItemGroup[]) {
+ }
+
+ cancel() {
+ this.dialogRef.close()
+ }
+
+ submit() {
+ this.dialogRef.close(this.selectedItemgroup);
+ }
+}
diff --git a/src/app/editor/items/item-group-editor/item-group-editor.component.html b/src/app/editor/items/item-group-editor/item-group-editor.component.html
new file mode 100644
index 0000000..caa4082
--- /dev/null
+++ b/src/app/editor/items/item-group-editor/item-group-editor.component.html
@@ -0,0 +1,36 @@
+
diff --git a/src/app/editor/items/item-group-editor/item-group-editor.component.scss b/src/app/editor/items/item-group-editor/item-group-editor.component.scss
new file mode 100644
index 0000000..9aa19ce
--- /dev/null
+++ b/src/app/editor/items/item-group-editor/item-group-editor.component.scss
@@ -0,0 +1,7 @@
+.mat-column-edit, .mat-column-delete {
+ width: 32px;
+}
+
+.mat-column-Characteristic, {
+ width: 25%;
+}
diff --git a/src/app/editor/items/item-group-editor/item-group-editor.component.spec.ts b/src/app/editor/items/item-group-editor/item-group-editor.component.spec.ts
new file mode 100644
index 0000000..a6bbd54
--- /dev/null
+++ b/src/app/editor/items/item-group-editor/item-group-editor.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ItemGroupEditorComponent } from './item-group-editor.component';
+
+describe('ItemGroupEditorComponent', () => {
+ let component: ItemGroupEditorComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [ItemGroupEditorComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(ItemGroupEditorComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/editor/items/item-group-editor/item-group-editor.component.ts b/src/app/editor/items/item-group-editor/item-group-editor.component.ts
new file mode 100644
index 0000000..2436e71
--- /dev/null
+++ b/src/app/editor/items/item-group-editor/item-group-editor.component.ts
@@ -0,0 +1,46 @@
+import {Component, Input, OnInit} from '@angular/core';
+import {ItemGroup} from "../../../project/game-model/inventory/ItemGroup";
+import {MatColumnDef, MatTable, MatTableDataSource} from "@angular/material/table";
+import {ItemGroupCharacteristic} from "../../../project/game-model/inventory/ItemgroupCharacteristic";
+import {Item} from "../../../project/game-model/inventory/Item";
+
+@Component({
+ selector: 'app-item-group-editor',
+ templateUrl: './item-group-editor.component.html',
+ styleUrl: './item-group-editor.component.scss'
+})
+export class ItemGroupEditorComponent implements OnInit{
+
+ @Input() itemgroup: ItemGroup | undefined
+
+ itemQualityDatasource: MatTableDataSource = new MatTableDataSource();
+ displayedColumns: string[] = ["Characteristic", "Description", 'edit', 'delete']
+
+ editedCharacteristic: ItemGroupCharacteristic | undefined;
+
+
+ ngOnInit(): void {
+ this.itemQualityDatasource.data = this.itemgroup!.itemGroupCharacteristics;
+ }
+
+ deleteItemgroupCharacteristic(characteristic: ItemGroupCharacteristic) {
+ this.itemgroup!.itemGroupCharacteristics = this.itemgroup!.itemGroupCharacteristics.filter(igc => igc.characteristicName !== characteristic.characteristicName);
+ this.itemQualityDatasource.data = this.itemgroup!.itemGroupCharacteristics;
+ }
+
+ editItemgroupCharacteristic(characteristic: ItemGroupCharacteristic) {
+ this.editedCharacteristic = characteristic;
+ }
+
+ finishEditing() {
+ this.editedCharacteristic = undefined;
+ }
+
+ addItemgroupCharacteristic() {
+ const itemgroupCharacteristic = new ItemGroupCharacteristic("", "", this.itemgroup!);
+ this.itemgroup!.addItemgroupCharacteristic(itemgroupCharacteristic);
+
+ this.itemQualityDatasource.data = this.itemgroup!.itemGroupCharacteristics;
+ this.editedCharacteristic = itemgroupCharacteristic;
+ }
+}
diff --git a/src/app/project/game-model/GameModel.ts b/src/app/project/game-model/GameModel.ts
index 4ba59a8..2a34fc9 100644
--- a/src/app/project/game-model/GameModel.ts
+++ b/src/app/project/game-model/GameModel.ts
@@ -11,7 +11,12 @@ import {SimpleTemplateGamesystem} from "./templates/simpleGamesystem/SimpleTempl
import {ProductTemplateSystem} from "./templates/productGamesystem/ProductTemplateSystem";
import {ProductTemplateCreator} from "./templates/productGamesystem/ProductTemplateCreator";
import {CharacterRelation} from "./characters/CharacterRelation";
+import {ItemGroup} from "./inventory/ItemGroup";
+import {AbstractItemGroup} from "./inventory/AbstractItemGroup";
+import {ConcreteItemGroup} from "./inventory/ConcreteItemGroup";
import {Item} from "./inventory/Item";
+import {ItemgroupUtilities} from "./utils/ItemgroupUtilities";
+import {ItemGroupCharacteristic} from "./inventory/ItemgroupCharacteristic";
export class GameModel {
gameModelName: string
@@ -19,12 +24,28 @@ export class GameModel {
gamesystems: Gamesystem[] = [];
scriptAccounts: ScriptAccount[] = [];
characters: Character[] = []
- inventoryItems: Item[] = []
+ itemgroups: ItemGroup[] = []
constructor(gameModelName: string) {
this.gameModelName = gameModelName;
}
+
+ public static findItemgroupByName(name: string, itemgroups: ItemGroup[]) {
+ const itemgroupQueue: ItemGroup[] = itemgroups.concat();
+ while(itemgroupQueue.length > 0 ) {
+ const currentItemgroup = itemgroupQueue.shift()!;
+
+ if(currentItemgroup.componentName === name) {
+ return currentItemgroup;
+ }
+
+ if(currentItemgroup instanceof AbstractItemGroup) {
+ currentItemgroup.children.forEach(itemgroup => itemgroupQueue.push(itemgroup));
+ }
+ }
+ }
+
addGamesystem(gamesystem: Gamesystem) {
if(this.findGamesystem(gamesystem.componentName) == undefined) {
this.gamesystems.push(gamesystem);
@@ -40,16 +61,12 @@ export class GameModel {
}
}
- createScriptAccount(scriptAccountName: string) {
- if(scriptAccountName != undefined && scriptAccountName.length > 0) {
- const scriptAccount = new ScriptAccount(scriptAccountName, "");
- const searchedScriptAccount = this.scriptAccounts.find(s => s.componentName === scriptAccount.componentName);
- if(searchedScriptAccount == undefined) {
- this.scriptAccounts.push(scriptAccount);
- return scriptAccount;
- }
+ addScriptAccount(scriptAccount: ScriptAccount) {
+ if(!this.scriptAccounts.find(sA => sA.componentName === scriptAccount.componentName)) {
+ this.scriptAccounts.push(scriptAccount)
+ return true;
}
- return undefined;
+ return false;
}
createSimpleGamesystem(gamesystemName: string, templateType: TemplateType | undefined, pushToTop: boolean = true) {
@@ -103,12 +120,7 @@ export class GameModel {
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) {
if(gamesystemName != undefined && this.findGamesystem(gamesystemName) == undefined) {
@@ -163,10 +175,6 @@ export class GameModel {
}
}
- removeItem(item: Item) {
- this.inventoryItems = this.inventoryItems.filter(i => i.componentName === item.componentName)
- }
-
findGamesystem(gamesystemName: string) {
const gamesystemQueue : Gamesystem, Transition>[] = [];
this.gamesystems.forEach(gamesystem => gamesystemQueue.push(gamesystem));
@@ -182,10 +190,6 @@ export class GameModel {
}
}
- addScriptAccount(scriptAccount: ScriptAccount) {
- this.scriptAccounts.push(scriptAccount);
- }
-
generateProductSystemContents() {
this.gamesystems.forEach(gamesystem => {
if(gamesystem instanceof ProductGamesystem) {
@@ -213,4 +217,27 @@ export class GameModel {
return requestedTemplates;
}
+
+ get itemgroupsAsList() {
+ let itemgroupQueue: ItemGroup[] = this.itemgroups.concat();
+ const result: ItemGroup[] = []
+ while(itemgroupQueue.length > 0) {
+ const currentGroup = itemgroupQueue.shift()!;
+
+ if(currentGroup instanceof AbstractItemGroup) {
+ itemgroupQueue = itemgroupQueue.concat(currentGroup.children);
+ }
+ result.push(currentGroup);
+ }
+
+ return result;
+ }
+
+ addCharacter(character: Character) {
+ if(this.characters.find(c => c.componentName === character.componentName) === undefined) {
+ this.characters.push(character)
+ return true;
+ }
+ return false;
+ }
}
diff --git a/src/app/project/game-model/ModelComponentType.ts b/src/app/project/game-model/ModelComponentType.ts
index 4baebb9..ffef110 100644
--- a/src/app/project/game-model/ModelComponentType.ts
+++ b/src/app/project/game-model/ModelComponentType.ts
@@ -2,5 +2,7 @@ export enum ModelComponentType {
SCRIPTACCOUNT,
GAMESYTEM,
CHARACTER,
+ ITEMGROUP,
ITEM
+
}
diff --git a/src/app/project/game-model/ModelComponentTypeUtillities.ts b/src/app/project/game-model/ModelComponentTypeUtillities.ts
index a2bdc40..984a7a2 100644
--- a/src/app/project/game-model/ModelComponentTypeUtillities.ts
+++ b/src/app/project/game-model/ModelComponentTypeUtillities.ts
@@ -5,8 +5,9 @@ export class ModelComponentTypeUtillities {
switch (modelComponentType) {
case ModelComponentType.SCRIPTACCOUNT: return "ScriptAccounts";
case ModelComponentType.GAMESYTEM: return "Gamesystems";
- case ModelComponentType.CHARACTER: return "Characters";
+ case ModelComponentType.CHARACTER: return "Characters"
case ModelComponentType.ITEM: return "Items";
+ case ModelComponentType.ITEMGROUP: return "Itemgroups";
default: return "Undefined";
}
}
@@ -16,7 +17,8 @@ export class ModelComponentTypeUtillities {
case ModelComponentType.SCRIPTACCOUNT: return "ScriptAccount";
case ModelComponentType.GAMESYTEM: return "Gamesystem";
case ModelComponentType.CHARACTER: return "Character"
- case ModelComponentType.ITEM: return "Item"
+ case ModelComponentType.ITEM: return "Item";
+ case ModelComponentType.ITEMGROUP: return "Itemgroup";
default: return "Undefined";
}
}
@@ -26,7 +28,8 @@ export class ModelComponentTypeUtillities {
case "gamesystem": return ModelComponentType.GAMESYTEM;
case "scriptaccount": return ModelComponentType.SCRIPTACCOUNT;
case "character": return ModelComponentType.CHARACTER
- case "item": return ModelComponentType.ITEM
+ case "item": return ModelComponentType.ITEM;
+ case "itemgroup": return ModelComponentType.ITEMGROUP;
}
}
}
diff --git a/src/app/project/game-model/gamesystems/Gamesystem.ts b/src/app/project/game-model/gamesystems/Gamesystem.ts
index 981590a..e50cf3f 100644
--- a/src/app/project/game-model/gamesystems/Gamesystem.ts
+++ b/src/app/project/game-model/gamesystems/Gamesystem.ts
@@ -27,5 +27,4 @@ export abstract class Gamesystem extends ModelComponent{
this.transitions = updatedTransitions;
return true;
}
-
}
diff --git a/src/app/project/game-model/gamesystems/ProductGamesystem.ts b/src/app/project/game-model/gamesystems/ProductGamesystem.ts
index 2b77cdc..eb2dc3e 100644
--- a/src/app/project/game-model/gamesystems/ProductGamesystem.ts
+++ b/src/app/project/game-model/gamesystems/ProductGamesystem.ts
@@ -32,14 +32,12 @@ export class ProductGamesystem extends Gamesystem {
+ item.addInheritedHierarchyGroup(itemgroup);
+ })
+ this.items.push(item);
+ }
+ }
+
+ findItemByName(itemName: string) {
+ return this.items.find(item => item.componentName === itemName);
+ }
+
+ protected addCharacteristicValue(characteristic: ItemGroupCharacteristic): void {
+ this.items.forEach(item => {
+ item.addCharacteristic(characteristic);
+ })
+ }
+
+
+}
diff --git a/src/app/project/game-model/inventory/Item.ts b/src/app/project/game-model/inventory/Item.ts
index 13f8a35..6d0978c 100644
--- a/src/app/project/game-model/inventory/Item.ts
+++ b/src/app/project/game-model/inventory/Item.ts
@@ -1,44 +1,59 @@
-import {ItemProperty} from "./ItemProperty";
-import {ItemQuality} from "./ItemQuality";
import {ModelComponent} from "../ModelComponent";
-import {ModelComponentType} from "../ModelComponentType";
-import {ItemPropertyDescription} from "./ItemPropertyDescription";
+import {ItemGroup} from "./ItemGroup";
+import {ItemgroupCharacteristicValue} from "./ItemgroupCharacteristicValue";
+import {ItemGroupCharacteristic} from "./ItemgroupCharacteristic";
export class Item extends ModelComponent {
- possible_qualities: ItemQuality[] = []
- itemProperties: ItemProperty[] = []
- perQualityProperties: ItemPropertyDescription[] = []
+ manuallyInheritedGroups: ItemGroup[] = []
+ hierarchyInheritedGroups: ItemGroup[] = []
+ itemCharacteristicValues: ItemgroupCharacteristicValue[] = []
- 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);
+ initializeItemCharacteristics() {
+ const inheritedGroups = this.manuallyInheritedGroups.concat(this.hierarchyInheritedGroups);
+ inheritedGroups.forEach(itemGroup => {
+ this.initializeItemCharacteristicsOfItemgroup(itemGroup);
})
}
- 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))
+ initializeItemCharacteristicsOfItemgroup(itemGroup: ItemGroup) {
+ itemGroup.itemGroupCharacteristics.forEach(characteristic => {
+ this.addCharacteristic(characteristic);
+ })
+ }
+
+ private isValueInitialized(characteristic: ItemGroupCharacteristic) {
+ return this.itemCharacteristicValues.find(value => value.key.characteristicName === characteristic.characteristicName) !== undefined
+ }
+
+ addInheritedGroup(itemgroup: ItemGroup) {
+ if(this.findItemgroupByName(itemgroup.componentName) == undefined) {
+ this.manuallyInheritedGroups.push(itemgroup);
+ itemgroup.manuallyInheritedItems.push(this);
+ this.initializeItemCharacteristicsOfItemgroup(itemgroup);
}
}
- editPerQualityProperty(qualityProperty: ItemPropertyDescription) {
- this.possible_qualities.forEach(quality => {
- quality.editQualityProperty(qualityProperty, this.perQualityProperties.map(property => property.propertyName))
- })
+ findItemgroupByName(groupName: string) {
+ const itemgroups = this.hierarchyInheritedGroups.concat(this.manuallyInheritedGroups);
+ return itemgroups.find(group => group.componentName === groupName);
+ }
+
+ addCharacteristic(characteristic: ItemGroupCharacteristic) {
+ const characteristicValue = new ItemgroupCharacteristicValue(characteristic, 0);
+ if(!this.isValueInitialized(characteristic)) {
+ this.itemCharacteristicValues.push(characteristicValue);
+ }
+ }
+
+ deleteInheritedGroup(itemgroup: ItemGroup) {
+ this.manuallyInheritedGroups = this.manuallyInheritedGroups.filter(manually => manually.componentName !== itemgroup.componentName);
+ }
+
+ addInheritedHierarchyGroup(itemgroup: ItemGroup) {
+ this.hierarchyInheritedGroups.push(itemgroup);
+ this.initializeItemCharacteristicsOfItemgroup(itemgroup);
+
}
}
diff --git a/src/app/project/game-model/inventory/ItemGroup.ts b/src/app/project/game-model/inventory/ItemGroup.ts
new file mode 100644
index 0000000..3096e7b
--- /dev/null
+++ b/src/app/project/game-model/inventory/ItemGroup.ts
@@ -0,0 +1,35 @@
+import {ModelComponent} from "../ModelComponent";
+import {ItemGroupCharacteristic} from "./ItemgroupCharacteristic";
+import {AbstractItemGroup} from "./AbstractItemGroup";
+import {Item} from "./Item";
+
+export abstract class ItemGroup extends ModelComponent {
+
+ itemGroupCharacteristics: ItemGroupCharacteristic[] = []
+ parentGroup: AbstractItemGroup | undefined
+ manuallyInheritedItems: Item[] = []
+
+ addItemgroupCharacteristic(itemgroupCharacteristic: ItemGroupCharacteristic) {
+ this.itemGroupCharacteristics.push(itemgroupCharacteristic);
+ this.addCharacteristicValueForManuallyItems(itemgroupCharacteristic);
+ this.addCharacteristicValue(itemgroupCharacteristic);
+ }
+
+ protected abstract addCharacteristicValue(characteristic: ItemGroupCharacteristic): void;
+
+ private addCharacteristicValueForManuallyItems(characteristic: ItemGroupCharacteristic) {
+ this.manuallyInheritedItems.forEach(item => {
+ item.addCharacteristic(characteristic);
+ })
+ }
+
+ inheritManualItem(item: Item) {
+ if(this.manuallyInheritedItems.find(inheritedItems => inheritedItems.componentName === item.componentName) == undefined) {
+ this.manuallyInheritedItems.push(item);
+ item.addInheritedGroup(this);
+ }
+ }
+
+
+
+}
diff --git a/src/app/project/game-model/inventory/ItemgroupCharacteristic.ts b/src/app/project/game-model/inventory/ItemgroupCharacteristic.ts
new file mode 100644
index 0000000..d28b9a1
--- /dev/null
+++ b/src/app/project/game-model/inventory/ItemgroupCharacteristic.ts
@@ -0,0 +1,14 @@
+import {ItemGroup} from "./ItemGroup";
+
+export class ItemGroupCharacteristic {
+ characteristicName: string;
+ characteristicDescription: string
+ itemgroup: ItemGroup
+
+
+ constructor(characteristicName: string, characteristicDescription: string, itemgroup: ItemGroup) {
+ this.characteristicName = characteristicName;
+ this.characteristicDescription = characteristicDescription;
+ this.itemgroup = itemgroup;
+ }
+}
diff --git a/src/app/project/game-model/inventory/ItemgroupCharacteristicValue.ts b/src/app/project/game-model/inventory/ItemgroupCharacteristicValue.ts
new file mode 100644
index 0000000..436d3b7
--- /dev/null
+++ b/src/app/project/game-model/inventory/ItemgroupCharacteristicValue.ts
@@ -0,0 +1,14 @@
+import {ItemGroupCharacteristic} from "./ItemgroupCharacteristic";
+
+export class ItemgroupCharacteristicValue {
+ key: ItemGroupCharacteristic
+ value: number
+
+
+ constructor(key: ItemGroupCharacteristic, value: number) {
+ this.key = key;
+ this.value = value;
+ }
+
+
+}
diff --git a/src/app/project/game-model/inventory/ItemgroupType.ts b/src/app/project/game-model/inventory/ItemgroupType.ts
new file mode 100644
index 0000000..f1ca933
--- /dev/null
+++ b/src/app/project/game-model/inventory/ItemgroupType.ts
@@ -0,0 +1,4 @@
+export enum ItemgroupType {
+ CONCRETE,
+ ABSTRACT
+}
diff --git a/src/app/project/game-model/utils/ItemgroupUtilities.ts b/src/app/project/game-model/utils/ItemgroupUtilities.ts
new file mode 100644
index 0000000..25c9533
--- /dev/null
+++ b/src/app/project/game-model/utils/ItemgroupUtilities.ts
@@ -0,0 +1,67 @@
+import {GameModel} from "../GameModel";
+import {ItemGroup} from "../inventory/ItemGroup";
+import {AbstractItemGroup} from "../inventory/AbstractItemGroup";
+import {ConcreteItemGroup} from "../inventory/ConcreteItemGroup";
+
+export class ItemgroupUtilities {
+
+ public static findItemgroupPathToItem(searchedItemName: string, itemgroups: ItemGroup[]): ItemGroup[] {
+ for(let i=0; i 0) {
+ return found_path;
+ }
+ }
+ return [];
+ }
+
+ public static findItemgroupPathToItemgroup(searchedItemgroupName: string, itemgroups: ItemGroup[]): ItemGroup[] {
+ for(let i=0; i 0) {
+ return found_path;
+ }
+ }
+ return [];
+ }
+
+ private static findItemgroupPathToItemgroupRecursive(root: ItemGroup, searchedItemgroupName: string, path: ItemGroup[]): ItemGroup[] {
+ path.push(root);
+
+ if(root.componentName === searchedItemgroupName) {
+ return path;
+ }
+
+ if(root instanceof AbstractItemGroup) {
+ for(let i=0; i 0) {
+ return found_path;
+ }
+ }
+ return [];
+ } else {
+ return [];
+ }
+ }
+
+ private static findItemgroupPathToItemRecursive(root: ItemGroup, searchedItemName: string, path: ItemGroup[]): ItemGroup[] {
+ path.push(root);
+
+ if(root instanceof ConcreteItemGroup) {
+ const searchedItem = root.items.find(item => item.componentName === searchedItemName)
+ if(searchedItem != undefined) {
+ return path;
+ }
+ } else if(root instanceof AbstractItemGroup) {
+ for(let i=0; i 0) {
+ return found_path;
+ }
+ }
+ }
+ return [];
+ }
+
+}
diff --git a/src/app/project/game-model/utils/creator/CharacterCreator.ts b/src/app/project/game-model/utils/creator/CharacterCreator.ts
new file mode 100644
index 0000000..03d19a6
--- /dev/null
+++ b/src/app/project/game-model/utils/creator/CharacterCreator.ts
@@ -0,0 +1,22 @@
+import {ModelComponentCreator} from "./ModelComponentCreator";
+import {GameModel} from "../../GameModel";
+import {ModelComponent} from "../../ModelComponent";
+import {Character} from "../../characters/Character";
+
+export class CharacterCreator extends ModelComponentCreator{
+
+
+ constructor(context: string, gameModel: GameModel, selectedComponent: ModelComponent | undefined) {
+ super(context, gameModel, selectedComponent);
+ }
+
+ createModelComponent(): ModelComponent | undefined {
+ const character = new Character("New Character", "");
+ if(this.gameModel.addCharacter(character)) {
+ return character;
+ }
+ return undefined;
+ }
+
+
+}
diff --git a/src/app/project/game-model/utils/creator/GamesystemCreator.ts b/src/app/project/game-model/utils/creator/GamesystemCreator.ts
new file mode 100644
index 0000000..6233ab4
--- /dev/null
+++ b/src/app/project/game-model/utils/creator/GamesystemCreator.ts
@@ -0,0 +1,86 @@
+import {ModelComponentCreator} from "./ModelComponentCreator";
+import {GameModel} from "../../GameModel";
+import {ModelComponent} from "../../ModelComponent";
+import {TemplateTypeUtilities} from "../../templates/TemplateTypeUtilities";
+import {Gamesystem} from "../../gamesystems/Gamesystem";
+import {SimpleGamesystem} from "../../gamesystems/SimpleGamesystem";
+import {ProductGamesystem} from "../../gamesystems/ProductGamesystem";
+import {SimpleTemplateGamesystem} from "../../templates/simpleGamesystem/SimpleTemplateGamesystem";
+import {ProductTemplateCreator} from "../../templates/productGamesystem/ProductTemplateCreator";
+import {ProductTemplateSystem} from "../../templates/productGamesystem/ProductTemplateSystem";
+import {TemplateType} from "../../templates/TemplateType";
+
+export class GamesystemCreator extends ModelComponentCreator{
+
+
+ constructor(context: string, gameModel: GameModel, selectedComponent: ModelComponent | undefined) {
+ super(context, gameModel, selectedComponent);
+ }
+
+ createModelComponent(): ModelComponent | undefined {
+ const templateType = TemplateTypeUtilities.fromString(this.context);
+ let simpleGamesystem;
+ if(templateType == undefined) /**Aka normal**/{
+ simpleGamesystem = new SimpleGamesystem("New Simple Gamesystem", "");
+ } else {
+ simpleGamesystem = new SimpleTemplateGamesystem("New Simple Gamesystem", "", templateType)
+ }
+
+ if(this.selectedComponent !== undefined && this.selectedComponent instanceof Gamesystem)/**Aka productGamesystem**/ {
+ const productParentsystem: ProductGamesystem = this.constructProductFromSimple(this.selectedComponent, undefined)!
+ productParentsystem.addChildGamesystem(simpleGamesystem);
+ } else {
+ this.gameModel!.gamesystems.push(simpleGamesystem);
+ }
+
+ return simpleGamesystem;
+ }
+
+ private constructProductFromSimple(simpleGamesystem: Gamesystem, producttemplateType: TemplateType | undefined): ProductGamesystem | undefined {
+ if(!(simpleGamesystem instanceof ProductTemplateSystem) && producttemplateType != undefined) {
+ console.log("Wierd, Debug")
+ return ProductTemplateCreator.convertProductToTemplate(simpleGamesystem as ProductGamesystem, this.gameModel, producttemplateType);
+ }
+
+ if(simpleGamesystem instanceof ProductGamesystem) {
+ console.log("Wierder Debug")
+ return simpleGamesystem;
+ }
+
+ let productGamesystem: ProductGamesystem
+ if(producttemplateType != undefined) {
+ productGamesystem = new ProductTemplateSystem(simpleGamesystem.componentName, simpleGamesystem.componentDescription, producttemplateType);
+ } else {
+ productGamesystem = new ProductGamesystem(simpleGamesystem.componentName, simpleGamesystem.componentDescription);
+ }
+
+ this.constructGamesystemHierarchy(productGamesystem, simpleGamesystem as SimpleGamesystem)
+ return productGamesystem;
+ }
+
+ private constructGamesystemHierarchy(productGamesystem: ProductGamesystem, simpleGamesystem: SimpleGamesystem) {
+ const simpleParentGamesystem = simpleGamesystem.parentGamesystem;
+
+ if(simpleGamesystem.states.length > 0) {
+ simpleGamesystem.componentName += "(Child)";
+ if(simpleParentGamesystem == undefined) {
+ this.gameModel.removeGamesystem(simpleGamesystem);
+ productGamesystem.addChildGamesystem(simpleGamesystem);
+ this.gameModel.addGamesystem(productGamesystem);
+ } else {
+ simpleParentGamesystem.removeChildGamesystem(simpleGamesystem);
+ productGamesystem.addChildGamesystem(simpleGamesystem);
+ simpleParentGamesystem.addChildGamesystem(productGamesystem);
+ }
+ } else {
+ if(simpleParentGamesystem == undefined) {
+ this.gameModel.removeGamesystem(simpleGamesystem);
+ this.gameModel.addGamesystem(productGamesystem);
+ } else {
+ simpleParentGamesystem.removeChildGamesystem(simpleGamesystem);
+ simpleParentGamesystem.addChildGamesystem(productGamesystem);
+ }
+ }
+ }
+
+}
diff --git a/src/app/project/game-model/utils/creator/ItemCreator.ts b/src/app/project/game-model/utils/creator/ItemCreator.ts
new file mode 100644
index 0000000..bc58902
--- /dev/null
+++ b/src/app/project/game-model/utils/creator/ItemCreator.ts
@@ -0,0 +1,37 @@
+import {ModelComponentCreator} from "./ModelComponentCreator";
+import {GameModel} from "../../GameModel";
+import {ModelComponent} from "../../ModelComponent";
+import {Item} from "../../inventory/Item";
+import {ModelComponentType} from "../../ModelComponentType";
+import {ConcreteItemGroup} from "../../inventory/ConcreteItemGroup";
+import {ItemGroup} from "../../inventory/ItemGroup";
+
+export class ItemCreator extends ModelComponentCreator {
+
+
+ constructor(context: string, gameModel: GameModel, selectedComponent: ModelComponent | undefined) {
+ super(context, gameModel, selectedComponent);
+ }
+
+ createModelComponent(): ModelComponent | undefined {
+ if(this.selectedComponent != undefined && this.selectedComponent instanceof ConcreteItemGroup) {
+ const item = new Item("New Item", "", ModelComponentType.ITEM);
+ this.selectedComponent.addItem(item, this.getInheritedGroups(this.selectedComponent))
+ return item;
+ } else {
+ return undefined
+ }
+ }
+
+ private getInheritedGroups(baseGroup: ItemGroup): ItemGroup[] {
+ const itemgroups: ItemGroup[] = []
+ let currentGroup: ItemGroup | undefined = baseGroup;
+ while(currentGroup != undefined) {
+ itemgroups.push(currentGroup);
+ currentGroup = currentGroup.parentGroup;
+ }
+ return itemgroups;
+ }
+
+
+}
diff --git a/src/app/project/game-model/utils/creator/ItemgroupCreator.ts b/src/app/project/game-model/utils/creator/ItemgroupCreator.ts
new file mode 100644
index 0000000..924ee6a
--- /dev/null
+++ b/src/app/project/game-model/utils/creator/ItemgroupCreator.ts
@@ -0,0 +1,36 @@
+import {ModelComponentCreator} from "./ModelComponentCreator";
+import {ModelComponent} from "../../ModelComponent";
+import {GameModel} from "../../GameModel";
+import {AbstractItemGroup} from "../../inventory/AbstractItemGroup";
+import {ModelComponentType} from "../../ModelComponentType";
+import {ConcreteItemGroup} from "../../inventory/ConcreteItemGroup";
+
+export class ItemgroupCreator extends ModelComponentCreator {
+
+
+
+ constructor(context: string, gameModel: GameModel, selectedComponent: ModelComponent | undefined) {
+ super(context, gameModel, selectedComponent);
+ }
+
+ createModelComponent(): ModelComponent | undefined{
+ let itemgroup;
+ if(this.context === 'abstract') {
+ itemgroup = new AbstractItemGroup("New Abstract Itemgroup", "", ModelComponentType.ITEMGROUP);
+ } else if(this.context === 'concrete') {
+ itemgroup = new ConcreteItemGroup("New Concrete Itemgroup", "", ModelComponentType.ITEMGROUP);
+ } else {
+ return undefined
+ }
+
+ if(this.selectedComponent != null && this.selectedComponent instanceof AbstractItemGroup) {
+ this.selectedComponent.addChildItemgroup(itemgroup);
+ } else {
+ this.gameModel.itemgroups.push(itemgroup);
+ }
+
+ return itemgroup;
+ }
+
+
+}
diff --git a/src/app/project/game-model/utils/creator/ModelComponentCreator.ts b/src/app/project/game-model/utils/creator/ModelComponentCreator.ts
new file mode 100644
index 0000000..68a90e2
--- /dev/null
+++ b/src/app/project/game-model/utils/creator/ModelComponentCreator.ts
@@ -0,0 +1,18 @@
+import {ModelComponent} from "../../ModelComponent";
+import {GameModel} from "../../GameModel";
+import {Overview} from "../../../../side-overviews/Overview";
+
+export abstract class ModelComponentCreator {
+ context: string;
+ gameModel: GameModel
+ selectedComponent: ModelComponent | undefined
+
+
+ protected constructor(context: string, gameModel: GameModel, selectedComponent: ModelComponent | undefined) {
+ this.context = context;
+ this.gameModel = gameModel;
+ this.selectedComponent = selectedComponent;
+ }
+
+ abstract createModelComponent(): ModelComponent | undefined;
+}
diff --git a/src/app/project/game-model/utils/creator/ScriptAccountCreator.ts b/src/app/project/game-model/utils/creator/ScriptAccountCreator.ts
new file mode 100644
index 0000000..cee9fc4
--- /dev/null
+++ b/src/app/project/game-model/utils/creator/ScriptAccountCreator.ts
@@ -0,0 +1,22 @@
+import {ModelComponentCreator} from "./ModelComponentCreator";
+import {GameModel} from "../../GameModel";
+import {ModelComponent} from "../../ModelComponent";
+import {ScriptAccount} from "../../scriptAccounts/ScriptAccount";
+
+export class ScriptAccountCreator extends ModelComponentCreator {
+
+ constructor(context: string, gameModel: GameModel, selectedComponent: ModelComponent | undefined) {
+ super(context, gameModel, selectedComponent);
+ }
+
+ createModelComponent(): ModelComponent | undefined {
+ const scriptAccount = new ScriptAccount("New ScriptAccount", "");
+ if(this.gameModel.addScriptAccount(scriptAccount)) {
+ return scriptAccount;
+ } else {
+ return undefined;
+ }
+ }
+
+
+}
diff --git a/src/app/project/parser/itemParser/ItemParser.ts b/src/app/project/parser/itemParser/ItemParser.ts
new file mode 100644
index 0000000..40da22f
--- /dev/null
+++ b/src/app/project/parser/itemParser/ItemParser.ts
@@ -0,0 +1,87 @@
+import {ItemGroup} from "../../game-model/inventory/ItemGroup";
+import {StoreComponent} from "../../../../../app/storage/StoreComponent";
+import {Item} from "../../game-model/inventory/Item";
+import {ModelComponentType} from "../../game-model/ModelComponentType";
+import {ConcreteItemGroup} from "../../game-model/inventory/ConcreteItemGroup";
+import {ItemgroupCharacteristicValue} from "../../game-model/inventory/ItemgroupCharacteristicValue";
+
+export class ItemParser {
+ parsedItemgroups: ItemGroup[] = []
+
+ constructor(itemgroups: ItemGroup[] = []) {
+ this.parsedItemgroups = itemgroups;
+ }
+
+ parseItems(storeComponents: StoreComponent[]): Item[] {
+ const parsedItems: Item[] = []
+ storeComponents.forEach(storeComponent => parsedItems.push(this.parseSingleItem(storeComponent)));
+ return parsedItems;
+ }
+
+ private parseSingleItem(storeComponent: StoreComponent) {
+ const parsedData = JSON.parse(storeComponent.jsonString);
+
+ const componentName = parsedData.componentName;
+ const componentDescription = parsedData.componentDescription;
+
+ const manuallyInheritedGroups = this.parseInheritedGroups(parsedData.manuallyInheritedGroups);
+ const hierarchyInheritedGroups = this.parseInheritedGroups(parsedData.hierarchyInheritedGroups);
+
+ const item = new Item(componentName, componentDescription, ModelComponentType.ITEM);
+ item.manuallyInheritedGroups = manuallyInheritedGroups;
+ item.hierarchyInheritedGroups = hierarchyInheritedGroups;
+
+ const owningGroup = hierarchyInheritedGroups.find(itemgroup => itemgroup instanceof ConcreteItemGroup);
+ if (owningGroup) {
+ (owningGroup as ConcreteItemGroup).items.push(item);
+ } else {
+ console.log("[ERROR] No group found for item: ", item.componentName)
+ }
+
+
+ item.itemCharacteristicValues = this.parseItemCharacteristicValues(parsedData.itemCharacteristicValues);
+ return item;
+ }
+
+ private parseInheritedGroups(inheritedGroupsData: any) {
+ const inheritedGroups: ItemGroup[] = []
+ for(let i=0; i group.componentName === inheritedGroupName);
+ if (matchedGroup) {
+ inheritedGroups.push(matchedGroup);
+ }
+ }
+
+ return inheritedGroups;
+ }
+
+ private parseItemCharacteristicValues(data: any): ItemgroupCharacteristicValue[] {
+ const values: ItemgroupCharacteristicValue[] = []
+ for(let i=0; i characteristic.characteristicName === itemCharacteristicName);
+
+ if(characteristic != undefined) {
+ return characteristic;
+ }
+ }
+ return undefined;
+ }
+
+
+}
diff --git a/src/app/project/parser/itemParser/ItemgroupParser.ts b/src/app/project/parser/itemParser/ItemgroupParser.ts
new file mode 100644
index 0000000..fb18e77
--- /dev/null
+++ b/src/app/project/parser/itemParser/ItemgroupParser.ts
@@ -0,0 +1,94 @@
+import {ItemGroup} from "../../game-model/inventory/ItemGroup";
+import {StoreComponent} from "../../../../../app/storage/StoreComponent";
+import {ItemGroupCharacteristic} from "../../game-model/inventory/ItemgroupCharacteristic";
+import {AbstractItemGroup} from "../../game-model/inventory/AbstractItemGroup";
+import {ModelComponentType} from "../../game-model/ModelComponentType";
+import {ConcreteItemGroup} from "../../game-model/inventory/ConcreteItemGroup";
+
+export class ItemgroupParser {
+
+ private parsedItemgroups: ItemGroup[] = []
+ private topParsedItemgroups: ItemGroup[] = []
+
+ parseItemgroups(storeComponents: StoreComponent[]) {
+ const topologicalSort = this.topologicalSort(storeComponents);
+ topologicalSort.forEach(storeComponent => this.parseSingleItemgroup(storeComponent));
+ return this.parsedItemgroups;
+ }
+
+ private topologicalSort(storeComponents: StoreComponent[]) {
+ const sortedObjects: StoreComponent[] = []
+ const visited: {[key: string]: boolean} = {};
+
+ const visit = (object: StoreComponent) => {
+ const jsonData = JSON.parse(object.jsonString)
+ if(visited[jsonData.componentName]) return;
+ visited[jsonData.componentName] = true;
+
+ if(jsonData.parent) {
+ const parentObject = storeComponents.find(obj => JSON.parse(obj.jsonString).componentName === jsonData.parent);
+ if(parentObject) {
+ visit(parentObject);
+ }
+ }
+ sortedObjects.push(object);
+ }
+
+ storeComponents.forEach(object => visit(object));
+
+ return sortedObjects;
+ }
+
+ parseSingleItemgroup(storeComponent: StoreComponent) {
+ const data = JSON.parse(storeComponent.jsonString);
+
+ const componentName = data.componentName;
+ const componentDescription = data.componentDescription;
+ const parentgroupName = data.parentgroup;
+
+ let itemgroup;
+ if(data.itemgroupType == 0) {
+ itemgroup = new ConcreteItemGroup(componentName, componentDescription, ModelComponentType.ITEMGROUP);
+ } else {
+ itemgroup = new AbstractItemGroup(componentName, componentDescription, ModelComponentType.ITEMGROUP);
+ }
+
+ const parentgroup = this.parsedItemgroups.find(parent => parent.componentName === parentgroupName);
+
+ if(parentgroup != undefined) {
+ const abstractParentgroup = parentgroup as AbstractItemGroup;
+ abstractParentgroup.addChildItemgroup(itemgroup)
+ this.parsedItemgroups.push(itemgroup)
+ } else {
+ this.parsedItemgroups.push(itemgroup);
+ this.topParsedItemgroups.push(itemgroup);
+ }
+
+ this.parseItemgroupCharacteristics(data.itemGroupCharacteristics, itemgroup);
+ }
+
+ parseItemgroupCharacteristics(itemgroupCharacteristicsData: any, itemgroup: ItemGroup): ItemGroupCharacteristic[] {
+ const itemgroupCharacteristics: ItemGroupCharacteristic[] = []
+ for(let i=0; i {
if(this.IGNORED_SIMPLE_ATTRIBUTES.includes(key)) {
diff --git a/src/app/project/serializer/ItemSerializer.ts b/src/app/project/serializer/ItemSerializer.ts
index 352f4b4..80d51bf 100644
--- a/src/app/project/serializer/ItemSerializer.ts
+++ b/src/app/project/serializer/ItemSerializer.ts
@@ -1,38 +1,135 @@
-import {Item} from "../game-model/inventory/Item";
+import {ItemGroup} from "../game-model/inventory/ItemGroup";
import {StoreComponent} from "../../../../app/storage/StoreComponent";
+import {AbstractItemGroup} from "../game-model/inventory/AbstractItemGroup";
+import {ConcreteItemGroup} from "../game-model/inventory/ConcreteItemGroup";
+import {ModelComponentType} from "../game-model/ModelComponentType";
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";
+import {Item} from "../game-model/inventory/Item";
+import {ItemgroupType} from "../game-model/inventory/ItemgroupType";
export class ItemSerializer {
- public static serializeItems(items: Item[]): StoreComponent[] {
- const storedItems: StoreComponent[] = []
- items.forEach(item => storedItems.push(this.serializeSingleItem(item)))
- return storedItems;
+ private serializedItemgroups: StoreComponent[] = []
+ private serializedItems: StoreComponent[] = []
+ private static ignoredGroupKeys: string[] = ['type', 'unsaved', "itemgroup", "manuallyInheritedGroups", "hierarchyInheritedGroups", "items"]
+ private static ignoredItemKeys: string[] = ['type', 'unsaved']
+
+ public serializeItemgroups(itemgroups: ItemGroup[]): StoreComponent[] {
+ itemgroups.forEach(itemgroup => {
+ this.serializeSingleItemgroupHierarchy(itemgroup)
+ })
+ return this.serializedItemgroups;
}
- 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
- }));
+ private serializeSingleItemgroupHierarchy(itemgroup: ItemGroup) {
+ if(itemgroup instanceof AbstractItemGroup) {
+ const storeComponent = this.serializeAbstractItemgroup(itemgroup)
+ this.serializedItemgroups.push(storeComponent)
+ itemgroup.children.forEach(child => this.serializeSingleItemgroupHierarchy(child));
+ } else {
+ const storeComponent = this.serializeConcreteItemgroup(itemgroup as ConcreteItemGroup);
+ this.serializedItemgroups.push(storeComponent)
+
+ this.serializeItemsOfItemgroup(itemgroup as ConcreteItemGroup);
+ }
+ }
+
+ private serializeAbstractItemgroup(itemgroup: AbstractItemGroup): StoreComponent {
+ const componentType = ModelComponentType.ITEMGROUP;
+ const fileName = ItemSerializer.computeItemgroupPath(itemgroup);
+
+ const jsonObject = {
+ componentName: itemgroup.componentName,
+ componentDescription: itemgroup.componentDescription,
+ itemGroupCharacteristics: itemgroup.itemGroupCharacteristics.map(characteristic => {
+ return {
+ characteristicName: characteristic.characteristicName,
+ characteristicDescription: characteristic.characteristicDescription
+ }
+ }),
+ parentgroup: itemgroup.parentGroup,
+ itemgroupType: ItemgroupType.ABSTRACT
+ };
+
+ const jsonString = JSON.stringify(jsonObject, (key, value) => {
+ return value;
+ }, SerializeConstants.JSON_INDENT);
+ return new StoreComponent(jsonString, fileName, componentType)
+ }
+
+ private serializeConcreteItemgroup(itemgroup: ConcreteItemGroup) {
+ const componentType = ModelComponentType.ITEMGROUP;
+ const fileName = ItemSerializer.computeItemgroupPath(itemgroup);
+
+ const jsonObject = {
+ componentName: itemgroup.componentName,
+ componentDescription: itemgroup.componentDescription,
+ itemGroupCharacteristics: itemgroup.itemGroupCharacteristics.map(characteristic => {
+ return {
+ characteristicName: characteristic.characteristicName,
+ characteristicDescription: characteristic.characteristicDescription
+ }
+ }),
+ itemgroupType: ItemgroupType.CONCRETE,
+ parentgroup: itemgroup.parentGroup?.componentName
+ };
+
+ const jsonString = JSON.stringify(jsonObject, (key, value) => {
+ return value;
+ }, SerializeConstants.JSON_INDENT);
+ return new StoreComponent(jsonString, fileName, componentType)
+ }
+
+ private static computeItemgroupPath(itemgroup: ItemGroup, itemPath: boolean = false): string {
+ const itemgroupPath: string[] = [];
+ itemgroupPath.push(itemgroup.componentName);
+
+ if(!itemPath) {
+ itemgroupPath.push(itemgroup.componentName);
+ }
+
+
+ while(itemgroup.parentGroup !== undefined) {
+ itemgroupPath.unshift(itemgroup.parentGroup.componentName);
+ itemgroup = itemgroup.parentGroup;
+ }
+
+ return itemgroupPath.join("/");
+ }
+
+ private serializeItemsOfItemgroup(itemgroup: ConcreteItemGroup) {
+ const fileName = ItemSerializer.computeItemgroupPath(itemgroup, true);
+ itemgroup.items.forEach(item => {
+ const storeComponent = this.serializeSingleItem(fileName, item);
+ this.serializedItems.push(storeComponent)
+ })
+
+
+ }
+
+ private serializeSingleItem(itemgroupPath: string, item: Item) {
+ const itemFile = itemgroupPath + "/" + item.componentName;
+
+ const jsonString = JSON.stringify(item, (key, value) => {
+ if(ItemSerializer.ignoredItemKeys.includes(key)) {
+ return undefined
}
- if(key === 'unsaved' || key === 'type') {
- return undefined;
- } else {
- return value;
+ if(value instanceof ItemGroup) {
+ return value.componentName
}
+
+ if(key == "key") {
+ return value.characteristicName
+ }
+
+ return value;
}, SerializeConstants.JSON_INDENT)
- return new StoreComponent(jsonString, fileName, componentType);
+ return new StoreComponent(jsonString, itemFile, ModelComponentType.ITEM)
+ }
+
+ getSerializedItems() {
+ return this.serializedItems;
}
}
diff --git a/src/app/shared/Tupel.ts b/src/app/shared/Tupel.ts
new file mode 100644
index 0000000..e05b237
--- /dev/null
+++ b/src/app/shared/Tupel.ts
@@ -0,0 +1,10 @@
+export class Tupel {
+ value00: A
+ value01: B
+
+
+ constructor(value00: A, value01: B) {
+ this.value00 = value00;
+ this.value01 = value01;
+ }
+}
diff --git a/src/app/side-overviews/Overview.ts b/src/app/side-overviews/Overview.ts
new file mode 100644
index 0000000..88dd18f
--- /dev/null
+++ b/src/app/side-overviews/Overview.ts
@@ -0,0 +1,3 @@
+export interface Overview {
+ refresh(): void
+}
diff --git a/src/app/side-overviews/character-overview/character-overview.component.ts b/src/app/side-overviews/character-overview/character-overview.component.ts
index c182485..50ad56a 100644
--- a/src/app/side-overviews/character-overview/character-overview.component.ts
+++ b/src/app/side-overviews/character-overview/character-overview.component.ts
@@ -5,13 +5,17 @@ import {MatIcon} from "@angular/material/icon";
import {NgClass, NgForOf} from "@angular/common";
import {ScriptAccount} from "../../project/game-model/scriptAccounts/ScriptAccount";
import {Character} from "../../project/game-model/characters/Character";
+import {Overview} from "../Overview";
@Component({
selector: 'app-character-overview',
templateUrl: './character-overview.component.html',
styleUrl: './character-overview.component.scss'
})
-export class CharacterOverviewComponent {
+export class CharacterOverviewComponent implements Overview{
+ refresh(): void {
+ //Nothing to-do
+ }
@Input() gameModel: GameModel | undefined
@Output("onOpenCharacterEditor") openCharacterEmitter: EventEmitter = new EventEmitter();
diff --git a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts
index 3194a5f..4c6fe9c 100644
--- a/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts
+++ b/src/app/side-overviews/gamescript-overview/gamescript-overview.component.ts
@@ -8,6 +8,7 @@ import {State} from "../../project/game-model/gamesystems/states/State";
import {Transition} from "../../project/game-model/gamesystems/transitions/Transition";
import {ProductGamesystem} from "../../project/game-model/gamesystems/ProductGamesystem";
import {SimpleGamesystem} from "../../project/game-model/gamesystems/SimpleGamesystem";
+import {Overview} from "../Overview";
interface FlatNode {
@@ -20,7 +21,7 @@ interface FlatNode {
templateUrl: './gamescript-overview.component.html',
styleUrl: './gamescript-overview.component.scss'
})
-export class GamescriptOverviewComponent implements OnInit {
+export class GamescriptOverviewComponent implements OnInit, Overview {
@Input('gameModel') gameModel: GameModel | undefined
@Output('openGamesystemEditor') openGamesystemEmitter : EventEmitter, Transition>> = new EventEmitter, Transition>>();
diff --git a/src/app/side-overviews/item-overview/item-overview.component.html b/src/app/side-overviews/item-overview/item-overview.component.html
new file mode 100644
index 0000000..2622561
--- /dev/null
+++ b/src/app/side-overviews/item-overview/item-overview.component.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+ folder
+ data_object
+ {{node.name}}
+
+
+
+
+ folder
+ data_object
+ {{node.name}}
+
+
diff --git a/src/app/side-overviews/item-overview/item-overview.component.scss b/src/app/side-overviews/item-overview/item-overview.component.scss
new file mode 100644
index 0000000..d799155
--- /dev/null
+++ b/src/app/side-overviews/item-overview/item-overview.component.scss
@@ -0,0 +1,41 @@
+.mat-tree-node {
+ min-height: 1.8em !important;
+ height: 1.8em;
+}
+
+
+.small-icon-button {
+ width: 26px !important;
+ height: 26px !important;
+ padding: 0px !important;
+ display: inline-flex !important;
+ align-items: center;
+ justify-content: center;
+ margin-left: 5px;
+ margin-right: 5px;
+ margin-bottom: 2px;
+
+ & > *[role=img] {
+ width: 18px;
+ height: 18px;
+ font-size: 18px;
+
+ svg {
+ width: 18px;
+ height: 18px;
+ }
+ }
+
+ .mat-mdc-button-touch-target {
+ width: 22px !important;
+ height: 22px !important;
+ }
+}
+
+.small-icon-button mat-icon {
+ color: whitesmoke;
+}
+
+.selected-node {
+ background-color: #545456
+}
diff --git a/src/app/side-overviews/item-overview/item-overview.component.spec.ts b/src/app/side-overviews/item-overview/item-overview.component.spec.ts
new file mode 100644
index 0000000..58c2547
--- /dev/null
+++ b/src/app/side-overviews/item-overview/item-overview.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ItemOverviewComponent } from './item-overview.component';
+
+describe('ItemOverviewComponent', () => {
+ let component: ItemOverviewComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [ItemOverviewComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(ItemOverviewComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/side-overviews/item-overview/item-overview.component.ts b/src/app/side-overviews/item-overview/item-overview.component.ts
new file mode 100644
index 0000000..a41020e
--- /dev/null
+++ b/src/app/side-overviews/item-overview/item-overview.component.ts
@@ -0,0 +1,153 @@
+import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
+import {GameModel} from "../../project/game-model/GameModel";
+import {FlatTreeControl} from "@angular/cdk/tree";
+import {MatTreeFlatDataSource, MatTreeFlattener} from "@angular/material/tree";
+import {AbstractItemGroup} from "../../project/game-model/inventory/AbstractItemGroup";
+import {ConcreteItemGroup} from "../../project/game-model/inventory/ConcreteItemGroup";
+import {ModelComponent} from "../../project/game-model/ModelComponent";
+import {ModelComponentType} from "../../project/game-model/ModelComponentType";
+import {ItemGroup} from "../../project/game-model/inventory/ItemGroup";
+import {Item} from "../../project/game-model/inventory/Item";
+import {Overview} from "../Overview";
+
+interface FlatNode {
+ expandable: boolean,
+ name: string,
+ level: number,
+ type: ModelComponentType
+}
+
+@Component({
+ selector: 'app-item-overview',
+ templateUrl: './item-overview.component.html',
+ styleUrl: './item-overview.component.scss'
+})
+export class ItemOverviewComponent implements OnInit, Overview{
+
+ @Input() gameModel: GameModel | undefined
+ @Output() openItemgroupEmitter: EventEmitter = new EventEmitter();
+ @Output() onOpenItemEditor: EventEmitter- = new EventEmitter();
+
+ private _transformer = (node: ModelComponent, level: number) => {
+ if(node instanceof AbstractItemGroup) {
+ return {
+ expandable: !!node.children && node.children.length > 0,
+ name: node.componentName,
+ level: level,
+ type: ModelComponentType.ITEMGROUP,
+ };
+ } else if(node instanceof ConcreteItemGroup) {
+ return {
+ expandable: !!node.items && node.items.length > 0,
+ name: node.componentName,
+ level: level,
+ type: ModelComponentType.ITEMGROUP,
+ }
+ } else {
+ return {
+ expandable: false,
+ name: node.componentName,
+ level: level,
+ type: ModelComponentType.ITEM
+ }
+ }
+ };
+
+
+ treeControl = new FlatTreeControl(
+ node => node.level,
+ node => node.expandable,
+ );
+
+ treeFlattener = new MatTreeFlattener(
+ this._transformer,
+ node => node.level,
+ node => node.expandable,
+ node => this.getNodeChildren(node)
+ );
+
+ dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
+ selectedItem: FlatNode | undefined
+
+ hasChild = (_: number, node: FlatNode) => node.expandable;
+
+ getNodeChildren(node: ModelComponent): ModelComponent[] {
+ if(node instanceof ConcreteItemGroup) {
+ return node.items;
+ } else if(node instanceof AbstractItemGroup) {
+ return node.children;
+ } else {
+ return [];
+ }
+ }
+
+ ngOnInit() {
+ this.dataSource.data = this.gameModel!.itemgroups;
+ }
+
+ protected readonly ModelComponentType = ModelComponentType;
+
+ onSelectItem(node: FlatNode) {
+ this.selectedItem = node;
+ }
+
+ openItemEditor(node: FlatNode) {
+ if(node.type == ModelComponentType.ITEMGROUP) {
+ const itemGroup = GameModel.findItemgroupByName(node.name, this.gameModel!.itemgroups);
+ if(itemGroup) {
+ this.openItemgroupEmitter.emit(itemGroup);
+ }
+ } else if(node.type == ModelComponentType.ITEM) {
+ const item = this.searchItemByName(node.name);
+ if(item !== undefined) {
+ this.onOpenItemEditor.emit(item);
+ }
+ }
+ }
+
+ private searchItemByName(itemName: string): Item | undefined {
+ let groupQueue: ItemGroup[] = this.gameModel!.itemgroups.concat();
+ while(groupQueue.length > 0) {
+ const currentGroup = groupQueue.shift()!;
+
+ if(currentGroup instanceof AbstractItemGroup) {
+ groupQueue = groupQueue.concat(currentGroup.children);
+ } else if(currentGroup instanceof ConcreteItemGroup) {
+ const searchResult = currentGroup.items.find(item => item.componentName === itemName);
+ if(searchResult != undefined) {
+ return searchResult;
+ }
+ }
+ }
+ return undefined;
+ }
+
+ get selectedModelComponent() {
+ if(this.selectedItem) {
+ if(this.selectedItem.type === ModelComponentType.ITEMGROUP) {
+ let groupQueue: ItemGroup[] = this.gameModel!.itemgroups.concat();
+ while(groupQueue.length > 0) {
+ const currentGroup = groupQueue.shift()!;
+
+ if(currentGroup.componentName === this.selectedItem.name) {
+ return currentGroup;
+ }
+
+ if(currentGroup instanceof AbstractItemGroup) {
+ groupQueue = groupQueue.concat(currentGroup.children);
+ }
+ }
+ } else {
+ return this.searchItemByName(this.selectedItem!.name)
+ }
+ } else {
+ return undefined
+ }
+ }
+
+ refresh(): void {
+ this.dataSource.data = this.gameModel!.itemgroups;
+ console.log("Opened Refreshed")
+ }
+
+}
diff --git a/src/app/side-overviews/script-account-overview/script-account-overview.component.ts b/src/app/side-overviews/script-account-overview/script-account-overview.component.ts
index 3643289..fce194e 100644
--- a/src/app/side-overviews/script-account-overview/script-account-overview.component.ts
+++ b/src/app/side-overviews/script-account-overview/script-account-overview.component.ts
@@ -2,13 +2,14 @@ import {Component, EventEmitter, Input, NgZone, Output} from '@angular/core';
import {ElectronService} from "../../core/services";
import {GameModel} from "../../project/game-model/GameModel";
import {ScriptAccount} from "../../project/game-model/scriptAccounts/ScriptAccount";
+import {Overview} from "../Overview";
@Component({
selector: 'app-script-account-overview',
templateUrl: './script-account-overview.component.html',
styleUrl: './script-account-overview.component.css'
})
-export class ScriptAccountOverviewComponent {
+export class ScriptAccountOverviewComponent implements Overview{
@Input("gameModel") gameModel: GameModel | undefined
@Output("onOpenScriptAccount") openScriptAccountEmitter: EventEmitter = new EventEmitter();
@@ -17,6 +18,10 @@ export class ScriptAccountOverviewComponent {
constructor() {
}
+ refresh(): void {
+ //Nothing to do
+ }
+
onOpenScriptAccount(scriptAccount: ScriptAccount) {
console.log("onOpenScriptAccount (overview)")
this.openScriptAccountEmitter.emit(scriptAccount);
diff --git a/testModel/gamesystems/Parentgamesystem.json b/testModel/gamesystems/Parentgamesystem.json
new file mode 100644
index 0000000..75902da
--- /dev/null
+++ b/testModel/gamesystems/Parentgamesystem.json
@@ -0,0 +1,7 @@
+{
+ "componentName": "Parentgamesystem",
+ "componentDescription": "",
+ "states": [],
+ "transitions": [],
+ "generateIsolatedStates": false
+}
\ No newline at end of file
diff --git a/testModel/items/Clothing/Clothing.json b/testModel/items/Clothing/Clothing.json
new file mode 100644
index 0000000..af1c0a1
--- /dev/null
+++ b/testModel/items/Clothing/Clothing.json
@@ -0,0 +1,11 @@
+{
+ "componentName": "Clothing",
+ "componentDescription": "",
+ "itemGroupCharacteristics": [
+ {
+ "characteristicName": "Test0",
+ "characteristicDescription": ""
+ }
+ ],
+ "itemgroupType": 1
+}
\ No newline at end of file
diff --git a/testModel/items/Clothing/Hose/Hose 1.json b/testModel/items/Clothing/Hose/Hose 1.json
new file mode 100644
index 0000000..e2f14c9
--- /dev/null
+++ b/testModel/items/Clothing/Hose/Hose 1.json
@@ -0,0 +1,17 @@
+{
+ "componentName": "Hose 1",
+ "componentDescription": "",
+ "manuallyInheritedGroups": [
+ "Inventory"
+ ],
+ "hierarchyInheritedGroups": [
+ "Clothing",
+ "Hose"
+ ],
+ "itemCharacteristicValues": [
+ {
+ "key": "Test0",
+ "value": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/testModel/items/Clothing/Hose/Hose 2.json b/testModel/items/Clothing/Hose/Hose 2.json
new file mode 100644
index 0000000..50ef84c
--- /dev/null
+++ b/testModel/items/Clothing/Hose/Hose 2.json
@@ -0,0 +1,15 @@
+{
+ "componentName": "Hose 2",
+ "componentDescription": "",
+ "manuallyInheritedGroups": [],
+ "hierarchyInheritedGroups": [
+ "Clothing",
+ "Hose"
+ ],
+ "itemCharacteristicValues": [
+ {
+ "key": "Test0",
+ "value": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/testModel/items/Clothing/Hose/Hose.json b/testModel/items/Clothing/Hose/Hose.json
new file mode 100644
index 0000000..241268e
--- /dev/null
+++ b/testModel/items/Clothing/Hose/Hose.json
@@ -0,0 +1,7 @@
+{
+ "componentName": "Hose",
+ "componentDescription": "",
+ "itemGroupCharacteristics": [],
+ "itemgroupType": 0,
+ "parentgroup": "Clothing"
+}
\ No newline at end of file
diff --git a/testModel/items/Clothing/Oberteil/Oberteil.json b/testModel/items/Clothing/Oberteil/Oberteil.json
new file mode 100644
index 0000000..1079ae4
--- /dev/null
+++ b/testModel/items/Clothing/Oberteil/Oberteil.json
@@ -0,0 +1,7 @@
+{
+ "componentName": "Oberteil",
+ "componentDescription": "",
+ "itemGroupCharacteristics": [],
+ "itemgroupType": 0,
+ "parentgroup": "Clothing"
+}
\ No newline at end of file
diff --git a/testModel/items/Inventory/Inventory.json b/testModel/items/Inventory/Inventory.json
new file mode 100644
index 0000000..76568dd
--- /dev/null
+++ b/testModel/items/Inventory/Inventory.json
@@ -0,0 +1,11 @@
+{
+ "componentName": "Inventory",
+ "componentDescription": "",
+ "itemGroupCharacteristics": [
+ {
+ "characteristicName": "Test0",
+ "characteristicDescription": ""
+ }
+ ],
+ "itemgroupType": 0
+}
\ No newline at end of file
diff --git a/testModel/items/Item 1.json b/testModel/items/Item 1.json
deleted file mode 100644
index 2316aa2..0000000
--- a/testModel/items/Item 1.json
+++ /dev/null
@@ -1,55 +0,0 @@
-{
- "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"
- }
- ]
-}
\ No newline at end of file
diff --git a/testModel/items/Item 2.json b/testModel/items/Item 2.json
deleted file mode 100644
index 1e3bc67..0000000
--- a/testModel/items/Item 2.json
+++ /dev/null
@@ -1,55 +0,0 @@
-{
- "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"
- }
- ]
-}
\ No newline at end of file