inventory-items-2 #44
28
app/main.ts
28
app/main.ts
@ -8,6 +8,7 @@ import {ModelComponentFileDirectory} from "./storage/ModelComponentFileDirectory
|
|||||||
import {GamesystemStorage} from "./storage/storing/GamesystemStorage";
|
import {GamesystemStorage} from "./storage/storing/GamesystemStorage";
|
||||||
import {Character} from "../src/app/project/game-model/characters/Character";
|
import {Character} from "../src/app/project/game-model/characters/Character";
|
||||||
import {CharacterStorage} from "./storage/storing/CharacterStorage";
|
import {CharacterStorage} from "./storage/storing/CharacterStorage";
|
||||||
|
import {ItemgroupStorage} from "./storage/storing/ItemgroupStorage";
|
||||||
|
|
||||||
let win: BrowserWindow | null = null;
|
let win: BrowserWindow | null = null;
|
||||||
const args = process.argv.slice(1),
|
const args = process.argv.slice(1),
|
||||||
@ -96,6 +97,29 @@ function createWindow(): BrowserWindow {
|
|||||||
click: () => {
|
click: () => {
|
||||||
win!.webContents.send('context-menu', "new-character");
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -247,6 +271,10 @@ function recieveGameModelToStore(gameModel: StoredGameModel) {
|
|||||||
|
|
||||||
const characterStorage = new CharacterStorage(path.join(projectDirectory, ModelComponentFileDirectory.CHARACTER_DIR_NAME))
|
const characterStorage = new CharacterStorage(path.join(projectDirectory, ModelComponentFileDirectory.CHARACTER_DIR_NAME))
|
||||||
characterStorage.storeCharacters(gameModel.storedCharacters)
|
characterStorage.storeCharacters(gameModel.storedCharacters)
|
||||||
|
|
||||||
|
const itemgroupStorage = new ItemgroupStorage(path.join(projectDirectory, ModelComponentFileDirectory.ITEMGROUP_DIR_NAME))
|
||||||
|
itemgroupStorage.storeItemgroups(gameModel.storedItemgroups);
|
||||||
|
itemgroupStorage.storeItems(gameModel.storedItems)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*function deleteComponent(component: DeleteModel) {
|
/*function deleteComponent(component: DeleteModel) {
|
||||||
|
@ -7,4 +7,5 @@ exports.ModelComponentFileDirectory = ModelComponentFileDirectory;
|
|||||||
ModelComponentFileDirectory.SCRIPTACCOUNT_DIR_NAME = "script-accounts";
|
ModelComponentFileDirectory.SCRIPTACCOUNT_DIR_NAME = "script-accounts";
|
||||||
ModelComponentFileDirectory.GAMESYSTEM_DIR_NAME = "gamesystems";
|
ModelComponentFileDirectory.GAMESYSTEM_DIR_NAME = "gamesystems";
|
||||||
ModelComponentFileDirectory.CHARACTER_DIR_NAME = "characters";
|
ModelComponentFileDirectory.CHARACTER_DIR_NAME = "characters";
|
||||||
|
ModelComponentFileDirectory.ITEMGROUP_DIR_NAME = "items";
|
||||||
//# sourceMappingURL=ModelComponentFileDirectory.js.map
|
//# sourceMappingURL=ModelComponentFileDirectory.js.map
|
@ -2,4 +2,5 @@ export class ModelComponentFileDirectory {
|
|||||||
public static SCRIPTACCOUNT_DIR_NAME = "script-accounts"
|
public static SCRIPTACCOUNT_DIR_NAME = "script-accounts"
|
||||||
public static GAMESYSTEM_DIR_NAME = "gamesystems";
|
public static GAMESYSTEM_DIR_NAME = "gamesystems";
|
||||||
public static CHARACTER_DIR_NAME = "characters";
|
public static CHARACTER_DIR_NAME = "characters";
|
||||||
|
static ITEMGROUP_DIR_NAME = "items";
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.StoredGameModel = void 0;
|
exports.StoredGameModel = void 0;
|
||||||
class StoredGameModel {
|
class StoredGameModel {
|
||||||
constructor(gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters) {
|
constructor(gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters, storedItemgroups, storedItems) {
|
||||||
this.gameModelName = gameModelName;
|
this.gameModelName = gameModelName;
|
||||||
this.storedGamesystems = storedGamesystems;
|
this.storedGamesystems = storedGamesystems;
|
||||||
this.storedScriptAccounts = storedScriptAccounts;
|
this.storedScriptAccounts = storedScriptAccounts;
|
||||||
this.storedCharacters = storedCharacters;
|
this.storedCharacters = storedCharacters;
|
||||||
|
this.storedItemgroups = storedItemgroups;
|
||||||
|
this.storedItems = storedItems;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.StoredGameModel = StoredGameModel;
|
exports.StoredGameModel = StoredGameModel;
|
||||||
|
@ -6,13 +6,17 @@ export class StoredGameModel {
|
|||||||
storedGamesystems: StoreComponent[]
|
storedGamesystems: StoreComponent[]
|
||||||
storedScriptAccounts: StoreComponent[]
|
storedScriptAccounts: StoreComponent[]
|
||||||
storedCharacters: StoreComponent[]
|
storedCharacters: StoreComponent[]
|
||||||
|
storedItemgroups: StoreComponent[]
|
||||||
|
storedItems: StoreComponent[]
|
||||||
|
|
||||||
|
|
||||||
constructor(gameModelName: string, storedScriptAccounts: StoreComponent[], storedGamesystems: StoreComponent[],
|
constructor(gameModelName: string, storedScriptAccounts: StoreComponent[], storedGamesystems: StoreComponent[],
|
||||||
storedCharacters: StoreComponent[]) {
|
storedCharacters: StoreComponent[], storedItemgroups: StoreComponent[], storedItems: StoreComponent[]) {
|
||||||
this.gameModelName = gameModelName;
|
this.gameModelName = gameModelName;
|
||||||
this.storedGamesystems = storedGamesystems;
|
this.storedGamesystems = storedGamesystems;
|
||||||
this.storedScriptAccounts = storedScriptAccounts;
|
this.storedScriptAccounts = storedScriptAccounts;
|
||||||
this.storedCharacters = storedCharacters;
|
this.storedCharacters = storedCharacters;
|
||||||
|
this.storedItemgroups = storedItemgroups;
|
||||||
|
this.storedItems = storedItems;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,11 @@ const ModelComponentFileDirectory_1 = require("../ModelComponentFileDirectory");
|
|||||||
const ScriptAccountLoader_1 = require("./ScriptAccountLoader");
|
const ScriptAccountLoader_1 = require("./ScriptAccountLoader");
|
||||||
const GamesystemLoader_1 = require("./GamesystemLoader");
|
const GamesystemLoader_1 = require("./GamesystemLoader");
|
||||||
const CharacterLoader_1 = require("./CharacterLoader");
|
const CharacterLoader_1 = require("./CharacterLoader");
|
||||||
|
const ItemLoader_1 = require("./ItemLoader");
|
||||||
class GameModelLoader {
|
class GameModelLoader {
|
||||||
constructor(gameModelDir) {
|
constructor(gameModelDir) {
|
||||||
|
this.loadedItemgroups = [];
|
||||||
|
this.loadedItems = [];
|
||||||
this.gameModelDir = gameModelDir;
|
this.gameModelDir = gameModelDir;
|
||||||
}
|
}
|
||||||
loadGameModel() {
|
loadGameModel() {
|
||||||
@ -16,7 +19,8 @@ class GameModelLoader {
|
|||||||
const storedScriptAccounts = this.loadScriptAccountComponents();
|
const storedScriptAccounts = this.loadScriptAccountComponents();
|
||||||
const storedGamesystems = this.loadGamesystems();
|
const storedGamesystems = this.loadGamesystems();
|
||||||
const storedCharacters = this.loadCharacters();
|
const storedCharacters = this.loadCharacters();
|
||||||
return new StoredGameModel_1.StoredGameModel(gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters);
|
this.loadItemsAndItemgroups();
|
||||||
|
return new StoredGameModel_1.StoredGameModel(gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters, this.loadedItemgroups, this.loadedItems);
|
||||||
}
|
}
|
||||||
loadScriptAccountComponents() {
|
loadScriptAccountComponents() {
|
||||||
const scriptAccountDir = path.join(this.gameModelDir, ModelComponentFileDirectory_1.ModelComponentFileDirectory.SCRIPTACCOUNT_DIR_NAME);
|
const scriptAccountDir = path.join(this.gameModelDir, ModelComponentFileDirectory_1.ModelComponentFileDirectory.SCRIPTACCOUNT_DIR_NAME);
|
||||||
@ -33,6 +37,13 @@ class GameModelLoader {
|
|||||||
const characterLoader = new CharacterLoader_1.CharacterLoader(characterDir);
|
const characterLoader = new CharacterLoader_1.CharacterLoader(characterDir);
|
||||||
return characterLoader.loadCharacters();
|
return characterLoader.loadCharacters();
|
||||||
}
|
}
|
||||||
|
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;
|
exports.GameModelLoader = GameModelLoader;
|
||||||
//# sourceMappingURL=GameModelLoader.js.map
|
//# sourceMappingURL=GameModelLoader.js.map
|
@ -6,10 +6,14 @@ import {ModelComponentFileDirectory} from "../ModelComponentFileDirectory";
|
|||||||
import {ScriptAccountLoader} from "./ScriptAccountLoader";
|
import {ScriptAccountLoader} from "./ScriptAccountLoader";
|
||||||
import {GamesystemLoader} from "./GamesystemLoader";
|
import {GamesystemLoader} from "./GamesystemLoader";
|
||||||
import {CharacterLoader} from "./CharacterLoader";
|
import {CharacterLoader} from "./CharacterLoader";
|
||||||
|
import {ItemLoader} from "./ItemLoader";
|
||||||
|
|
||||||
export class GameModelLoader {
|
export class GameModelLoader {
|
||||||
gameModelDir: string
|
gameModelDir: string
|
||||||
|
|
||||||
|
loadedItemgroups: StoreComponent[] = []
|
||||||
|
loadedItems: StoreComponent[] = []
|
||||||
|
|
||||||
|
|
||||||
constructor(gameModelDir: string) {
|
constructor(gameModelDir: string) {
|
||||||
this.gameModelDir = gameModelDir;
|
this.gameModelDir = gameModelDir;
|
||||||
@ -21,8 +25,9 @@ export class GameModelLoader {
|
|||||||
const storedScriptAccounts = this.loadScriptAccountComponents();
|
const storedScriptAccounts = this.loadScriptAccountComponents();
|
||||||
const storedGamesystems = this.loadGamesystems();
|
const storedGamesystems = this.loadGamesystems();
|
||||||
const storedCharacters = this.loadCharacters()
|
const storedCharacters = this.loadCharacters()
|
||||||
|
this.loadItemsAndItemgroups();
|
||||||
|
|
||||||
return new StoredGameModel(gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters);
|
return new StoredGameModel(gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters, this.loadedItemgroups, this.loadedItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadScriptAccountComponents() {
|
private loadScriptAccountComponents() {
|
||||||
@ -44,7 +49,12 @@ export class GameModelLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
59
app/storage/loader/ItemLoader.js
Normal file
59
app/storage/loader/ItemLoader.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.ItemLoader = void 0;
|
||||||
|
const StoreComponent_1 = require("../StoreComponent");
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
//# sourceMappingURL=ItemLoader.js.map
|
65
app/storage/loader/ItemLoader.ts
Normal file
65
app/storage/loader/ItemLoader.ts
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import {StoreComponent} from "../StoreComponent";
|
||||||
|
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 {
|
||||||
|
|
||||||
|
itemDir: string
|
||||||
|
private _loadedItemgroups: StoreComponent[] = []
|
||||||
|
private _loadedItems: StoreComponent[] = []
|
||||||
|
|
||||||
|
constructor(itemDir: string) {
|
||||||
|
this.itemDir = itemDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
30
app/storage/storing/ItemgroupStorage.js
Normal file
30
app/storage/storing/ItemgroupStorage.js
Normal file
@ -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
|
35
app/storage/storing/ItemgroupStorage.ts
Normal file
35
app/storage/storing/ItemgroupStorage.ts
Normal file
@ -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))
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,9 @@
|
|||||||
(click)="openGamesystemsOverview()"><mat-icon>code</mat-icon></button>
|
(click)="openGamesystemsOverview()"><mat-icon>code</mat-icon></button>
|
||||||
<button mat-icon-button class="small-icon-button" [ngClass]="openContent === ModelComponentType.CHARACTER ? 'selected':''"
|
<button mat-icon-button class="small-icon-button" [ngClass]="openContent === ModelComponentType.CHARACTER ? 'selected':''"
|
||||||
(click)="openCharactersOverview()"><mat-icon>person</mat-icon></button>
|
(click)="openCharactersOverview()"><mat-icon>person</mat-icon></button>
|
||||||
|
|
||||||
|
<button mat-icon-button class="small-icon-button" [ngClass]="openContent === ModelComponentType.ITEM || openContent === ModelComponentType.ITEMGROUP ? 'selected':''"
|
||||||
|
(click)="openOverview(ModelComponentType.ITEM)"><mat-icon>inventory_2</mat-icon></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@ -23,11 +26,15 @@
|
|||||||
<button mat-menu-item (click)="openScriptAccountsOverview()">{{ModelComponentTypeUtillities.toString(ModelComponentType.SCRIPTACCOUNT)}}</button>
|
<button mat-menu-item (click)="openScriptAccountsOverview()">{{ModelComponentTypeUtillities.toString(ModelComponentType.SCRIPTACCOUNT)}}</button>
|
||||||
<button mat-menu-item (click)="openGamesystemsOverview()">{{ModelComponentTypeUtillities.toString(ModelComponentType.GAMESYTEM)}}</button>
|
<button mat-menu-item (click)="openGamesystemsOverview()">{{ModelComponentTypeUtillities.toString(ModelComponentType.GAMESYTEM)}}</button>
|
||||||
<button mat-menu-item (click)="openCharactersOverview()">{{ModelComponentTypeUtillities.toString(ModelComponentType.CHARACTER)}}</button>
|
<button mat-menu-item (click)="openCharactersOverview()">{{ModelComponentTypeUtillities.toString(ModelComponentType.CHARACTER)}}</button>
|
||||||
|
<button mat-menu-item (click)="openOverview(ModelComponentType.ITEMGROUP)">{{ModelComponentTypeUtillities.toString(ModelComponentType.ITEM)}}</button>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
</div>
|
</div>
|
||||||
<app-script-account-overview *ngIf="openContent == ModelComponentType.SCRIPTACCOUNT" #scriptAccountOverview [gameModel]="gameModel" (onOpenScriptAccount)="openModelComponent($event)"></app-script-account-overview>
|
<app-script-account-overview *ngIf="openContent == ModelComponentType.SCRIPTACCOUNT" #scriptAccountOverview [gameModel]="gameModel" (onOpenScriptAccount)="openModelComponent($event)"></app-script-account-overview>
|
||||||
<app-gamescript-overview *ngIf="openContent == ModelComponentType.GAMESYTEM" #gamesystemOverview [gameModel]="gameModel" (openGamesystemEditor)="openModelComponent($event)"></app-gamescript-overview>
|
<app-gamescript-overview *ngIf="openContent == ModelComponentType.GAMESYTEM" #gamesystemOverview [gameModel]="gameModel" (openGamesystemEditor)="openModelComponent($event)"></app-gamescript-overview>
|
||||||
<app-character-overview *ngIf="openContent == ModelComponentType.CHARACTER" #characterOverview [gameModel]="gameModel" (onOpenCharacterEditor)="openModelComponent($event)"></app-character-overview>
|
<app-character-overview *ngIf="openContent == ModelComponentType.CHARACTER" #characterOverview [gameModel]="gameModel" (onOpenCharacterEditor)="openModelComponent($event)"></app-character-overview>
|
||||||
|
<app-item-overview *ngIf="openContent == ModelComponentType.ITEMGROUP || openContent == ModelComponentType.ITEM"
|
||||||
|
#itemOverview [gameModel]="gameModel" (openItemgroupEmitter)="openModelComponent($event)"
|
||||||
|
(onOpenItemEditor)="openModelComponent($event)"></app-item-overview>
|
||||||
</mat-drawer>
|
</mat-drawer>
|
||||||
|
|
||||||
<div class="example-sidenav-content">
|
<div class="example-sidenav-content">
|
||||||
|
@ -27,6 +27,9 @@ import {CharacterParser} from "./project/parser/characterParser/CharacterParser"
|
|||||||
import {TemplateType} from "./project/game-model/templates/TemplateType";
|
import {TemplateType} from "./project/game-model/templates/TemplateType";
|
||||||
import {TemplateTypeUtilities} from "./project/game-model/templates/TemplateTypeUtilities";
|
import {TemplateTypeUtilities} from "./project/game-model/templates/TemplateTypeUtilities";
|
||||||
import {SimpleTemplateGamesystem} from "./project/game-model/templates/simpleGamesystem/SimpleTemplateGamesystem";
|
import {SimpleTemplateGamesystem} from "./project/game-model/templates/simpleGamesystem/SimpleTemplateGamesystem";
|
||||||
|
import {ItemSerializer} from "./project/serializer/ItemSerializer";
|
||||||
|
import {ItemgroupParser} from "./project/parser/itemParser/ItemgroupParser";
|
||||||
|
import {ItemParser} from "./project/parser/itemParser/ItemParser";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
@ -223,6 +226,13 @@ export class AppComponent implements OnInit{
|
|||||||
const characterParser = new CharacterParser(characterTemplateSystems, characterRelationTemplateSystems, gameModel.scriptAccounts);
|
const characterParser = new CharacterParser(characterTemplateSystems, characterRelationTemplateSystems, gameModel.scriptAccounts);
|
||||||
gameModel.characters = characterParser.parseCharacters(storedGameModel.storedCharacters)
|
gameModel.characters = characterParser.parseCharacters(storedGameModel.storedCharacters)
|
||||||
|
|
||||||
|
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;
|
this.gameModel = gameModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +241,12 @@ export class AppComponent implements OnInit{
|
|||||||
const storedScriptAccounts = ScriptAccountSerializer.serializeScriptAccounts(this.gameModel.scriptAccounts)
|
const storedScriptAccounts = ScriptAccountSerializer.serializeScriptAccounts(this.gameModel.scriptAccounts)
|
||||||
const storedGamesystems: StoreComponent[] = GamesystemSerializer.serializeGamesystems(this.gameModel.gamesystems)
|
const storedGamesystems: StoreComponent[] = GamesystemSerializer.serializeGamesystems(this.gameModel.gamesystems)
|
||||||
const storedCharacters: StoreComponent[] = CharacterSerializer.serializeCharacters(this.gameModel.characters)
|
const storedCharacters: StoreComponent[] = CharacterSerializer.serializeCharacters(this.gameModel.characters)
|
||||||
const storeModel = new StoredGameModel(this.gameModel.gameModelName, storedScriptAccounts, storedGamesystems, storedCharacters)
|
|
||||||
|
const 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) {
|
if(this.electronService.isElectron) {
|
||||||
this.electronService.ipcRenderer.send('save-model', storeModel)
|
this.electronService.ipcRenderer.send('save-model', storeModel)
|
||||||
@ -254,6 +269,11 @@ export class AppComponent implements OnInit{
|
|||||||
this.drawer!.open()
|
this.drawer!.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openOverview(overviewType: ModelComponentType) {
|
||||||
|
this.openContent = overviewType;
|
||||||
|
this.drawer!.open();
|
||||||
|
}
|
||||||
|
|
||||||
protected readonly ModelComponentType = ModelComponentType;
|
protected readonly ModelComponentType = ModelComponentType;
|
||||||
|
|
||||||
closeContentOverview() {
|
closeContentOverview() {
|
||||||
@ -284,4 +304,5 @@ export class AppComponent implements OnInit{
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected readonly open = open;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ import {CharacterOverviewComponent} from "./side-overviews/character-overview/ch
|
|||||||
import {CharacterEditorComponent} from "./editor/character-editor/character-editor.component";
|
import {CharacterEditorComponent} from "./editor/character-editor/character-editor.component";
|
||||||
import {
|
import {
|
||||||
MatAccordion,
|
MatAccordion,
|
||||||
MatExpansionPanel,
|
MatExpansionPanel, MatExpansionPanelDescription,
|
||||||
MatExpansionPanelHeader,
|
MatExpansionPanelHeader,
|
||||||
MatExpansionPanelTitle
|
MatExpansionPanelTitle
|
||||||
} from "@angular/material/expansion";
|
} from "@angular/material/expansion";
|
||||||
@ -82,7 +82,15 @@ import {
|
|||||||
import {
|
import {
|
||||||
StateInitialCellComponent
|
StateInitialCellComponent
|
||||||
} from "./editor/gamesystem-editor/state-editor/simple-state-editor/state-initial-cell/state-initial-cell.component";
|
} from "./editor/gamesystem-editor/state-editor/simple-state-editor/state-initial-cell/state-initial-cell.component";
|
||||||
|
import {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 {
|
||||||
|
ItemgroupInheritorComponent
|
||||||
|
} from "./editor/items/item-editor/itemgroup-inheritor/itemgroup-inheritor.component";
|
||||||
|
import {
|
||||||
|
InheritedItemCharacteristicEditorComponent
|
||||||
|
} from "./editor/items/item-editor/inherited-item-characteristic-editor/inherited-item-characteristic-editor.component";
|
||||||
// AoT requires an exported function for factories
|
// AoT requires an exported function for factories
|
||||||
const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './assets/i18n/', '.json');
|
const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './assets/i18n/', '.json');
|
||||||
|
|
||||||
@ -107,71 +115,77 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new Transl
|
|||||||
CharacterOverviewComponent,
|
CharacterOverviewComponent,
|
||||||
CharacterEditorComponent,
|
CharacterEditorComponent,
|
||||||
TemplateSpecificatorComponent,
|
TemplateSpecificatorComponent,
|
||||||
StateInitialCellComponent
|
StateInitialCellComponent,
|
||||||
|
ItemOverviewComponent,
|
||||||
|
ItemGroupEditorComponent,
|
||||||
|
ItemEditorComponent,
|
||||||
|
ItemgroupInheritorComponent,
|
||||||
|
InheritedItemCharacteristicEditorComponent
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
BrowserModule,
|
||||||
|
FormsModule,
|
||||||
|
HttpClientModule,
|
||||||
|
CoreModule,
|
||||||
|
SharedModule,
|
||||||
|
TranslateModule.forRoot({
|
||||||
|
loader: {
|
||||||
|
provide: TranslateLoader,
|
||||||
|
useFactory: httpLoaderFactory,
|
||||||
|
deps: [HttpClient]
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
BrowserAnimationsModule,
|
||||||
|
MatIcon,
|
||||||
|
MatToolbar,
|
||||||
|
MatButton,
|
||||||
|
MatFormField,
|
||||||
|
MatInput,
|
||||||
|
MatDrawerContainer,
|
||||||
|
MatDrawer,
|
||||||
|
MatIconButton,
|
||||||
|
MatMenuTrigger,
|
||||||
|
MatMenu,
|
||||||
|
MatMenuItem,
|
||||||
|
MatListItem,
|
||||||
|
MatActionList,
|
||||||
|
MatTabGroup,
|
||||||
|
MatTab,
|
||||||
|
MatTabLabel,
|
||||||
|
MatLabel,
|
||||||
|
MatFormField,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
MatError,
|
||||||
|
MatDialogTitle,
|
||||||
|
MatDialogContent,
|
||||||
|
MatDialogActions,
|
||||||
|
MatMiniFabButton,
|
||||||
|
MatTreeModule,
|
||||||
|
MatTable,
|
||||||
|
MatColumnDef,
|
||||||
|
MatHeaderCell,
|
||||||
|
MatHeaderCellDef,
|
||||||
|
MatCellDef,
|
||||||
|
MatCell,
|
||||||
|
MatHeaderRow,
|
||||||
|
MatRow,
|
||||||
|
MatHeaderRowDef,
|
||||||
|
MatRowDef,
|
||||||
|
MatCheckbox,
|
||||||
|
MatSelect,
|
||||||
|
MatOption,
|
||||||
|
MatHint,
|
||||||
|
MatTooltip,
|
||||||
|
MatCard,
|
||||||
|
MatCardContent,
|
||||||
|
MatCardHeader,
|
||||||
|
MatAccordion,
|
||||||
|
MatExpansionPanel,
|
||||||
|
MatExpansionPanelTitle,
|
||||||
|
MatCardTitle,
|
||||||
|
MatExpansionPanelHeader,
|
||||||
|
MatExpansionPanelDescription
|
||||||
],
|
],
|
||||||
imports: [
|
|
||||||
BrowserModule,
|
|
||||||
FormsModule,
|
|
||||||
HttpClientModule,
|
|
||||||
CoreModule,
|
|
||||||
SharedModule,
|
|
||||||
TranslateModule.forRoot({
|
|
||||||
loader: {
|
|
||||||
provide: TranslateLoader,
|
|
||||||
useFactory: httpLoaderFactory,
|
|
||||||
deps: [HttpClient]
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
BrowserAnimationsModule,
|
|
||||||
MatIcon,
|
|
||||||
MatToolbar,
|
|
||||||
MatButton,
|
|
||||||
MatFormField,
|
|
||||||
MatInput,
|
|
||||||
MatDrawerContainer,
|
|
||||||
MatDrawer,
|
|
||||||
MatIconButton,
|
|
||||||
MatMenuTrigger,
|
|
||||||
MatMenu,
|
|
||||||
MatMenuItem,
|
|
||||||
MatListItem,
|
|
||||||
MatActionList,
|
|
||||||
MatTabGroup,
|
|
||||||
MatTab,
|
|
||||||
MatTabLabel,
|
|
||||||
MatLabel,
|
|
||||||
MatFormField,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
MatError,
|
|
||||||
MatDialogTitle,
|
|
||||||
MatDialogContent,
|
|
||||||
MatDialogActions,
|
|
||||||
MatMiniFabButton,
|
|
||||||
MatTreeModule,
|
|
||||||
MatTable,
|
|
||||||
MatColumnDef,
|
|
||||||
MatHeaderCell,
|
|
||||||
MatHeaderCellDef,
|
|
||||||
MatCellDef,
|
|
||||||
MatCell,
|
|
||||||
MatHeaderRow,
|
|
||||||
MatRow,
|
|
||||||
MatHeaderRowDef,
|
|
||||||
MatRowDef,
|
|
||||||
MatCheckbox,
|
|
||||||
MatSelect,
|
|
||||||
MatOption,
|
|
||||||
MatHint,
|
|
||||||
MatTooltip,
|
|
||||||
MatCard,
|
|
||||||
MatCardContent,
|
|
||||||
MatCardHeader,
|
|
||||||
MatAccordion,
|
|
||||||
MatExpansionPanel,
|
|
||||||
MatExpansionPanelTitle,
|
|
||||||
MatCardTitle,
|
|
||||||
MatExpansionPanelHeader
|
|
||||||
],
|
|
||||||
providers: [],
|
providers: [],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
|
@ -20,5 +20,7 @@
|
|||||||
>
|
>
|
||||||
|
|
||||||
</app-character-editor>
|
</app-character-editor>
|
||||||
|
<app-item-group-editor *ngIf="modelComponent.type === ModelComponentType.ITEMGROUP" [itemgroup]="convertModelComponentToItemGroup(modelComponent)"></app-item-group-editor>
|
||||||
|
<app-item-editor *ngIf="modelComponent.type === ModelComponentType.ITEM" [item]="convertModelComponentToItem(modelComponent)" [gameModel]="gameModel!"></app-item-editor>
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
</mat-tab-group>
|
</mat-tab-group>
|
||||||
|
@ -7,6 +7,8 @@ import {State} from "../project/game-model/gamesystems/states/State";
|
|||||||
import {Transition} from "../project/game-model/gamesystems/transitions/Transition";
|
import {Transition} from "../project/game-model/gamesystems/transitions/Transition";
|
||||||
import {ModelComponentType} from "../project/game-model/ModelComponentType";
|
import {ModelComponentType} from "../project/game-model/ModelComponentType";
|
||||||
import {Character} from "../project/game-model/characters/Character";
|
import {Character} from "../project/game-model/characters/Character";
|
||||||
|
import {ItemGroup} from "../project/game-model/inventory/ItemGroup";
|
||||||
|
import {Item} from "../project/game-model/inventory/Item";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -57,4 +59,18 @@ export class EditorComponent {
|
|||||||
return modelComponent as Character
|
return modelComponent as Character
|
||||||
return undefined;
|
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 undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
<table mat-table [dataSource]="findCharacteristicValuesByItemgroup(inheritedItemgroup!)" class="mat-elevation-z8">
|
||||||
|
<ng-container matColumnDef="characteristic">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>Characteristic</th>
|
||||||
|
<td mat-cell *matCellDef="let characteristicValue">{{characteristicValue.key.characteristicName}}</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="value">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>Value</th>
|
||||||
|
<td mat-cell *matCellDef="let characteristicValue">
|
||||||
|
<span *ngIf="characteristicValue !== editedItemgroupCharacteristicValue">{{characteristicValue.value}}</span>
|
||||||
|
<mat-form-field appearance="outline" style="width: 100%;" *ngIf="characteristicValue === editedItemgroupCharacteristicValue">
|
||||||
|
<mat-label>Value</mat-label>
|
||||||
|
<input matInput [(ngModel)]="characteristicValue.value">
|
||||||
|
</mat-form-field>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="edit">
|
||||||
|
<th mat-header-cell *matHeaderCellDef></th>
|
||||||
|
<td mat-cell *matCellDef="let characteristicValue">
|
||||||
|
<button mat-icon-button *ngIf="editedItemgroupCharacteristicValue == undefined" (click)="editCharacteristicValue(characteristicValue)"><mat-icon>edit</mat-icon></button>
|
||||||
|
<button mat-icon-button *ngIf="editedItemgroupCharacteristicValue != undefined" (click)="finishEditing()" [disabled]="characteristicValue !== editedItemgroupCharacteristicValue"><mat-icon>done</mat-icon></button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||||
|
</table>
|
@ -0,0 +1,3 @@
|
|||||||
|
.mat-column-edit {
|
||||||
|
width: 32px;
|
||||||
|
}
|
@ -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<InheritedItemCharacteristicEditorComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [InheritedItemCharacteristicEditorComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(InheritedItemCharacteristicEditorComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -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<ItemgroupCharacteristicValue> = new MatTableDataSource<ItemgroupCharacteristicValue>();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
20
src/app/editor/items/item-editor/item-editor.component.html
Normal file
20
src/app/editor/items/item-editor/item-editor.component.html
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<mat-card>
|
||||||
|
<mat-card-header>
|
||||||
|
<mat-card-title>Inherited Itemgroups</mat-card-title>
|
||||||
|
</mat-card-header>
|
||||||
|
<mat-card-content>
|
||||||
|
<mat-accordion>
|
||||||
|
<mat-expansion-panel *ngFor="let itemgroup of manuallyAndHierarchyItemgroups">
|
||||||
|
<mat-expansion-panel-header>
|
||||||
|
<mat-panel-title>{{itemgroup.componentName}}</mat-panel-title>
|
||||||
|
<mat-panel-description>{{itemgroup.componentDescription}}</mat-panel-description>
|
||||||
|
</mat-expansion-panel-header>
|
||||||
|
<app-inherited-item-characteristic-editor [inheritedItemgroup]="itemgroup" [item]="item"></app-inherited-item-characteristic-editor>
|
||||||
|
<div class="panel-actions">
|
||||||
|
<button mat-raised-button color="warn" [disabled]="automaticallyInheritedItemgroups.includes(itemgroup)" (click)="deleteInheritedItemgroup(itemgroup)">Delete</button>
|
||||||
|
</div>
|
||||||
|
</mat-expansion-panel>
|
||||||
|
</mat-accordion>
|
||||||
|
<button mat-stroked-button style="width: 100%" (click)="onAddNewInheritedItemgroup()">Add Itemgroup</button>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
@ -0,0 +1,3 @@
|
|||||||
|
.panel-actions {
|
||||||
|
float: right;
|
||||||
|
}
|
@ -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<ItemEditorComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [ItemEditorComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(ItemEditorComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
49
src/app/editor/items/item-editor/item-editor.component.ts
Normal file
49
src/app/editor/items/item-editor/item-editor.component.ts
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
<h1 mat-dialog-title>Inherit Itemgroup</h1>
|
||||||
|
<mat-dialog-content>
|
||||||
|
<mat-form-field appearance="outline" style="width: 100%;">
|
||||||
|
<mat-label>Select Itemgroup</mat-label>
|
||||||
|
<mat-select [(ngModel)]="selectedItemgroup">
|
||||||
|
<mat-option *ngFor="let itemgroup of availableItemgroups" [value]="itemgroup">{{itemgroup.componentName}}</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</mat-dialog-content>
|
||||||
|
<mat-dialog-actions align="end">
|
||||||
|
<button mat-stroked-button (click)="cancel()">Cancel</button>
|
||||||
|
<button mat-raised-button color="primary" (click)="submit()">Confim</button>
|
||||||
|
</mat-dialog-actions>
|
@ -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<ItemgroupInheritorComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [ItemgroupInheritorComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(ItemgroupInheritorComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -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<ItemgroupInheritorComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public availableItemgroups: ItemGroup[]) {
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel() {
|
||||||
|
this.dialogRef.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
submit() {
|
||||||
|
this.dialogRef.close(this.selectedItemgroup);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
<table mat-table [dataSource]="itemQualityDatasource" class="mat-elevation-z8">
|
||||||
|
<ng-container matColumnDef="Characteristic">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> Characteristic </th>
|
||||||
|
<td mat-cell *matCellDef="let element">
|
||||||
|
<span *ngIf="editedCharacteristic !== element">{{element.characteristicName}}</span>
|
||||||
|
<mat-form-field appearance="outline" *ngIf="editedCharacteristic === element" style="width: 100%">
|
||||||
|
<mat-label>Name</mat-label>
|
||||||
|
<input matInput [(ngModel)]="element.characteristicName">
|
||||||
|
</mat-form-field>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="Description">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> Description </th>
|
||||||
|
<td mat-cell *matCellDef="let element">
|
||||||
|
<span *ngIf="editedCharacteristic !== element">{{element.characteristicDescription}}</span>
|
||||||
|
<mat-form-field appearance="outline" *ngIf="editedCharacteristic === element" style="width: 100%">
|
||||||
|
<mat-label>Name</mat-label>
|
||||||
|
<textarea matInput [(ngModel)]="element.characteristicDescription" rows="3"></textarea>
|
||||||
|
</mat-form-field>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="edit">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> </th>
|
||||||
|
<td mat-cell *matCellDef="let element">
|
||||||
|
<button mat-icon-button *ngIf="editedCharacteristic !== element" [disabled]="editedCharacteristic" (click)="editItemgroupCharacteristic(element)"><mat-icon>edit</mat-icon></button>
|
||||||
|
<button mat-icon-button *ngIf="editedCharacteristic === element" (click)="finishEditing()"><mat-icon>done</mat-icon></button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="delete">
|
||||||
|
<th mat-header-cell *matHeaderCellDef> <button mat-icon-button (click)="addItemgroupCharacteristic()"><mat-icon>add</mat-icon></button> </th>
|
||||||
|
<td mat-cell *matCellDef="let element"><button mat-icon-button color="warn" (click)="deleteItemgroupCharacteristic(element)"><mat-icon>delete</mat-icon></button></td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||||
|
</table>
|
@ -0,0 +1,7 @@
|
|||||||
|
.mat-column-edit, .mat-column-delete {
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-column-Characteristic, {
|
||||||
|
width: 25%;
|
||||||
|
}
|
@ -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<ItemGroupEditorComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [ItemGroupEditorComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(ItemGroupEditorComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -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<ItemGroupCharacteristic> = new MatTableDataSource<ItemGroupCharacteristic>();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,12 @@ import {SimpleTemplateGamesystem} from "./templates/simpleGamesystem/SimpleTempl
|
|||||||
import {ProductTemplateSystem} from "./templates/productGamesystem/ProductTemplateSystem";
|
import {ProductTemplateSystem} from "./templates/productGamesystem/ProductTemplateSystem";
|
||||||
import {ProductTemplateCreator} from "./templates/productGamesystem/ProductTemplateCreator";
|
import {ProductTemplateCreator} from "./templates/productGamesystem/ProductTemplateCreator";
|
||||||
import {CharacterRelation} from "./characters/CharacterRelation";
|
import {CharacterRelation} from "./characters/CharacterRelation";
|
||||||
|
import {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 {
|
export class GameModel {
|
||||||
gameModelName: string
|
gameModelName: string
|
||||||
@ -18,11 +24,69 @@ export class GameModel {
|
|||||||
gamesystems: Gamesystem<any, any>[] = [];
|
gamesystems: Gamesystem<any, any>[] = [];
|
||||||
scriptAccounts: ScriptAccount[] = [];
|
scriptAccounts: ScriptAccount[] = [];
|
||||||
characters: Character[] = []
|
characters: Character[] = []
|
||||||
|
itemgroups: ItemGroup[] = []
|
||||||
|
|
||||||
constructor(gameModelName: string) {
|
constructor(gameModelName: string) {
|
||||||
this.gameModelName = gameModelName;
|
this.gameModelName = gameModelName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addAbstractItemgroup(groupName: string, parentgroup: AbstractItemGroup | undefined) {
|
||||||
|
//Ensure that Itemgroup does not exist
|
||||||
|
if(parentgroup == undefined) {
|
||||||
|
if(GameModel.findItemgroupByName(groupName, this.itemgroups) == undefined) {
|
||||||
|
const itemgroup = new AbstractItemGroup(groupName, "", ModelComponentType.ITEMGROUP)
|
||||||
|
this.itemgroups.push(itemgroup);
|
||||||
|
itemgroup.addItemgroupCharacteristic(new ItemGroupCharacteristic("Test0", "", itemgroup));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(GameModel.findItemgroupByName(groupName, parentgroup.children) == undefined) {
|
||||||
|
parentgroup.addChildItemgroup(new AbstractItemGroup(groupName, "", ModelComponentType.ITEMGROUP));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addConcreteItemgroup(groupName: string, parentgroup: AbstractItemGroup | undefined) {
|
||||||
|
//Ensure that Itemgroup does not exist
|
||||||
|
if(parentgroup == undefined) {
|
||||||
|
if(GameModel.findItemgroupByName(groupName, this.itemgroups) == undefined) {
|
||||||
|
this.itemgroups.push(new ConcreteItemGroup(groupName, "", ModelComponentType.ITEMGROUP));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(GameModel.findItemgroupByName(groupName, parentgroup.children) == undefined) {
|
||||||
|
parentgroup.addChildItemgroup(new ConcreteItemGroup(groupName, "", ModelComponentType.ITEMGROUP));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addItem(itemName: string, conceteItemgroupName: string) {
|
||||||
|
const itemgroup = GameModel.findItemgroupByName(conceteItemgroupName, this.itemgroups);
|
||||||
|
if(itemgroup instanceof ConcreteItemGroup) {
|
||||||
|
const itemgroups: ItemGroup[] = ItemgroupUtilities.findItemgroupPathToItemgroup(conceteItemgroupName, this.itemgroups);
|
||||||
|
|
||||||
|
if(itemgroups.length > 0) {
|
||||||
|
const item = new Item(itemName, "", ModelComponentType.ITEM )
|
||||||
|
itemgroup.addItem(item, itemgroups)
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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<any, any>) {
|
addGamesystem(gamesystem: Gamesystem<any, any>) {
|
||||||
if(this.findGamesystem(gamesystem.componentName) == undefined) {
|
if(this.findGamesystem(gamesystem.componentName) == undefined) {
|
||||||
this.gamesystems.push(gamesystem);
|
this.gamesystems.push(gamesystem);
|
||||||
@ -202,4 +266,19 @@ export class GameModel {
|
|||||||
|
|
||||||
return requestedTemplates;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
export enum ModelComponentType {
|
export enum ModelComponentType {
|
||||||
SCRIPTACCOUNT,
|
SCRIPTACCOUNT,
|
||||||
GAMESYTEM,
|
GAMESYTEM,
|
||||||
CHARACTER
|
CHARACTER,
|
||||||
|
ITEMGROUP,
|
||||||
|
ITEM
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ export class ModelComponentTypeUtillities {
|
|||||||
case ModelComponentType.SCRIPTACCOUNT: return "ScriptAccounts";
|
case ModelComponentType.SCRIPTACCOUNT: return "ScriptAccounts";
|
||||||
case ModelComponentType.GAMESYTEM: return "Gamesystems";
|
case ModelComponentType.GAMESYTEM: return "Gamesystems";
|
||||||
case ModelComponentType.CHARACTER: return "Characters"
|
case ModelComponentType.CHARACTER: return "Characters"
|
||||||
|
case ModelComponentType.ITEM: return "Items";
|
||||||
|
case ModelComponentType.ITEMGROUP: return "Itemgroups";
|
||||||
default: return "Undefined";
|
default: return "Undefined";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -15,6 +17,8 @@ export class ModelComponentTypeUtillities {
|
|||||||
case ModelComponentType.SCRIPTACCOUNT: return "ScriptAccount";
|
case ModelComponentType.SCRIPTACCOUNT: return "ScriptAccount";
|
||||||
case ModelComponentType.GAMESYTEM: return "Gamesystem";
|
case ModelComponentType.GAMESYTEM: return "Gamesystem";
|
||||||
case ModelComponentType.CHARACTER: return "Character"
|
case ModelComponentType.CHARACTER: return "Character"
|
||||||
|
case ModelComponentType.ITEM: return "Item";
|
||||||
|
case ModelComponentType.ITEMGROUP: return "Itemgroup";
|
||||||
default: return "Undefined";
|
default: return "Undefined";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -24,6 +28,8 @@ export class ModelComponentTypeUtillities {
|
|||||||
case "gamesystem": return ModelComponentType.GAMESYTEM;
|
case "gamesystem": return ModelComponentType.GAMESYTEM;
|
||||||
case "scriptaccount": return ModelComponentType.SCRIPTACCOUNT;
|
case "scriptaccount": return ModelComponentType.SCRIPTACCOUNT;
|
||||||
case "character": return ModelComponentType.CHARACTER
|
case "character": return ModelComponentType.CHARACTER
|
||||||
|
case "item": return ModelComponentType.ITEM;
|
||||||
|
case "itemgroup": return ModelComponentType.ITEMGROUP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
20
src/app/project/game-model/inventory/AbstractItemGroup.ts
Normal file
20
src/app/project/game-model/inventory/AbstractItemGroup.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import {ItemGroup} from "./ItemGroup";
|
||||||
|
import {ItemGroupCharacteristic} from "./ItemgroupCharacteristic";
|
||||||
|
import {ItemgroupType} from "./ItemgroupType";
|
||||||
|
|
||||||
|
export class AbstractItemGroup extends ItemGroup {
|
||||||
|
|
||||||
|
children: ItemGroup[] = [];
|
||||||
|
itemgroupType = ItemgroupType.ABSTRACT
|
||||||
|
|
||||||
|
addChildItemgroup(itemGroup: ItemGroup) {
|
||||||
|
this.children.push(itemGroup)
|
||||||
|
itemGroup.parentGroup = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected addCharacteristicValue(characteristic: ItemGroupCharacteristic): void {
|
||||||
|
//Do Nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
31
src/app/project/game-model/inventory/ConcreteItemGroup.ts
Normal file
31
src/app/project/game-model/inventory/ConcreteItemGroup.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import {ItemGroup} from "./ItemGroup";
|
||||||
|
import {Item} from "./Item";
|
||||||
|
import {ItemGroupCharacteristic} from "./ItemgroupCharacteristic";
|
||||||
|
import {ItemgroupType} from "./ItemgroupType";
|
||||||
|
|
||||||
|
export class ConcreteItemGroup extends ItemGroup {
|
||||||
|
|
||||||
|
items: Item[] = [];
|
||||||
|
itemgroupType = ItemgroupType.CONCRETE
|
||||||
|
|
||||||
|
addItem(item: Item, parentItemgroups: ItemGroup[]) {
|
||||||
|
if(this.findItemByName(item.componentName) == undefined) {
|
||||||
|
parentItemgroups.forEach(itemgroup => {
|
||||||
|
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);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
59
src/app/project/game-model/inventory/Item.ts
Normal file
59
src/app/project/game-model/inventory/Item.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import {ModelComponent} from "../ModelComponent";
|
||||||
|
import {ItemGroup} from "./ItemGroup";
|
||||||
|
import {ItemgroupCharacteristicValue} from "./ItemgroupCharacteristicValue";
|
||||||
|
import {ItemGroupCharacteristic} from "./ItemgroupCharacteristic";
|
||||||
|
|
||||||
|
export class Item extends ModelComponent {
|
||||||
|
|
||||||
|
|
||||||
|
manuallyInheritedGroups: ItemGroup[] = []
|
||||||
|
hierarchyInheritedGroups: ItemGroup[] = []
|
||||||
|
itemCharacteristicValues: ItemgroupCharacteristicValue[] = []
|
||||||
|
|
||||||
|
initializeItemCharacteristics() {
|
||||||
|
const inheritedGroups = this.manuallyInheritedGroups.concat(this.hierarchyInheritedGroups);
|
||||||
|
inheritedGroups.forEach(itemGroup => {
|
||||||
|
this.initializeItemCharacteristicsOfItemgroup(itemGroup);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
35
src/app/project/game-model/inventory/ItemGroup.ts
Normal file
35
src/app/project/game-model/inventory/ItemGroup.ts
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
4
src/app/project/game-model/inventory/ItemgroupType.ts
Normal file
4
src/app/project/game-model/inventory/ItemgroupType.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export enum ItemgroupType {
|
||||||
|
CONCRETE,
|
||||||
|
ABSTRACT
|
||||||
|
}
|
67
src/app/project/game-model/utils/ItemgroupUtilities.ts
Normal file
67
src/app/project/game-model/utils/ItemgroupUtilities.ts
Normal file
@ -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<itemgroups.length; i++) {
|
||||||
|
const found_path = this.findItemgroupPathToItemRecursive(itemgroups[i], searchedItemName, []);
|
||||||
|
if(found_path.length > 0) {
|
||||||
|
return found_path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static findItemgroupPathToItemgroup(searchedItemgroupName: string, itemgroups: ItemGroup[]): ItemGroup[] {
|
||||||
|
for(let i=0; i<itemgroups.length; i++) {
|
||||||
|
const found_path = this.findItemgroupPathToItemgroupRecursive(itemgroups[i], searchedItemgroupName, []);
|
||||||
|
if(found_path.length > 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<root.children.length; i++) {
|
||||||
|
const found_path = this.findItemgroupPathToItemgroupRecursive(root.children[i], searchedItemgroupName, path.concat())
|
||||||
|
if(found_path != undefined && found_path.length > 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<root.children.length; i++) {
|
||||||
|
const found_path = this.findItemgroupPathToItemRecursive(root.children[i], searchedItemName, path.concat());
|
||||||
|
if(found_path.length > 0) {
|
||||||
|
return found_path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
87
src/app/project/parser/itemParser/ItemParser.ts
Normal file
87
src/app/project/parser/itemParser/ItemParser.ts
Normal file
@ -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<inheritedGroupsData.length; i++) {
|
||||||
|
const inheritedGroupName = inheritedGroupsData[i];
|
||||||
|
|
||||||
|
const matchedGroup = this.parsedItemgroups.find(group => group.componentName === inheritedGroupName);
|
||||||
|
if (matchedGroup) {
|
||||||
|
inheritedGroups.push(matchedGroup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return inheritedGroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
private parseItemCharacteristicValues(data: any): ItemgroupCharacteristicValue[] {
|
||||||
|
const values: ItemgroupCharacteristicValue[] = []
|
||||||
|
for(let i=0; i<data.length; i++) {
|
||||||
|
const key = this.findItemCharacteristic(data[i].key);
|
||||||
|
if (key) {
|
||||||
|
const characteristicValue = new ItemgroupCharacteristicValue(key!, data[i].value)
|
||||||
|
values.push(characteristicValue)
|
||||||
|
} else {
|
||||||
|
console.log("[ERROR] Characteristic not found: ", data[i].key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
private findItemCharacteristic(itemCharacteristicName: string) {
|
||||||
|
for(let i=0; i<this.parsedItemgroups.length; i++) {
|
||||||
|
const characteristic = this.parsedItemgroups[i].itemGroupCharacteristics
|
||||||
|
.find(characteristic=> characteristic.characteristicName === itemCharacteristicName);
|
||||||
|
|
||||||
|
if(characteristic != undefined) {
|
||||||
|
return characteristic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
94
src/app/project/parser/itemParser/ItemgroupParser.ts
Normal file
94
src/app/project/parser/itemParser/ItemgroupParser.ts
Normal file
@ -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<itemgroupCharacteristicsData.length; i++) {
|
||||||
|
this.parseSingleItemgroupCharacteristic(itemgroupCharacteristicsData[i], itemgroup)
|
||||||
|
}
|
||||||
|
return itemgroupCharacteristics;
|
||||||
|
}
|
||||||
|
|
||||||
|
private parseSingleItemgroupCharacteristic(itemgroupCharacteristicData: any, itemgroup: ItemGroup) {
|
||||||
|
const name = itemgroupCharacteristicData.characteristicName;
|
||||||
|
const description = itemgroupCharacteristicData.characteristicDescription;
|
||||||
|
|
||||||
|
const characteristic = new ItemGroupCharacteristic(name, description, itemgroup);
|
||||||
|
characteristic.itemgroup.addItemgroupCharacteristic(characteristic);
|
||||||
|
return characteristic;
|
||||||
|
}
|
||||||
|
|
||||||
|
getParsedTopItemgroups() {
|
||||||
|
return this.topParsedItemgroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
getParsedItemgroups() {
|
||||||
|
return this.parsedItemgroups;
|
||||||
|
}
|
||||||
|
}
|
@ -27,9 +27,7 @@ export class GamesystemSerializer {
|
|||||||
|
|
||||||
private static serializeSimpleGamesystem(simpleGamesystem: SimpleGamesystem): StoreComponent {
|
private static serializeSimpleGamesystem(simpleGamesystem: SimpleGamesystem): StoreComponent {
|
||||||
const fileName = this.computeSimpleGamesystemPath(simpleGamesystem);
|
const fileName = this.computeSimpleGamesystemPath(simpleGamesystem);
|
||||||
if(simpleGamesystem.componentName === "Weather(Child)") {
|
console.log(fileName)
|
||||||
console.log(fileName)
|
|
||||||
}
|
|
||||||
const jsonString = JSON.stringify(simpleGamesystem, (key, value) => {
|
const jsonString = JSON.stringify(simpleGamesystem, (key, value) => {
|
||||||
|
|
||||||
if(this.IGNORED_SIMPLE_ATTRIBUTES.includes(key)) {
|
if(this.IGNORED_SIMPLE_ATTRIBUTES.includes(key)) {
|
||||||
|
135
src/app/project/serializer/ItemSerializer.ts
Normal file
135
src/app/project/serializer/ItemSerializer.ts
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
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 {Item} from "../game-model/inventory/Item";
|
||||||
|
import {ItemgroupType} from "../game-model/inventory/ItemgroupType";
|
||||||
|
|
||||||
|
export class ItemSerializer {
|
||||||
|
|
||||||
|
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 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(value instanceof ItemGroup) {
|
||||||
|
return value.componentName
|
||||||
|
}
|
||||||
|
|
||||||
|
if(key == "key") {
|
||||||
|
return value.characteristicName
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}, SerializeConstants.JSON_INDENT)
|
||||||
|
|
||||||
|
return new StoreComponent(jsonString, itemFile, ModelComponentType.ITEM)
|
||||||
|
}
|
||||||
|
|
||||||
|
getSerializedItems() {
|
||||||
|
return this.serializedItems;
|
||||||
|
}
|
||||||
|
}
|
10
src/app/shared/Tupel.ts
Normal file
10
src/app/shared/Tupel.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export class Tupel<A, B> {
|
||||||
|
value00: A
|
||||||
|
value01: B
|
||||||
|
|
||||||
|
|
||||||
|
constructor(value00: A, value01: B) {
|
||||||
|
this.value00 = value00;
|
||||||
|
this.value01 = value01;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
|
||||||
|
<!-- This is the tree node template for leaf nodes -->
|
||||||
|
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding matTreeNodePaddingIndent="10" (click)="onSelectItem(node)" (contextmenu)="onSelectItem(node)" (dblclick)="openItemEditor(node)">
|
||||||
|
<!-- use a disabled button to provide padding for tree leaf -->
|
||||||
|
<button class="small-icon-button" mat-icon-button disabled></button>
|
||||||
|
<mat-icon class="small-icon-button" *ngIf="node.type == ModelComponentType.ITEMGROUP">folder</mat-icon>
|
||||||
|
<mat-icon class="small-icon-button" *ngIf="node.type == ModelComponentType.ITEM">data_object</mat-icon>
|
||||||
|
{{node.name}}
|
||||||
|
</mat-tree-node>
|
||||||
|
<!-- This is the tree node template for expandable nodes -->
|
||||||
|
<mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding matTreeNodePaddingIndent="10" (click)="onSelectItem(node)" (contextmenu)="onSelectItem(node)" (dblclick)="openItemEditor(node)">
|
||||||
|
<button class="small-icon-button" mat-icon-button matTreeNodeToggle
|
||||||
|
[attr.aria-label]="'Toggle ' + node.name">
|
||||||
|
<mat-icon class="mat-icon-rtl-mirror">
|
||||||
|
{{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
|
||||||
|
</mat-icon>
|
||||||
|
</button>
|
||||||
|
<mat-icon class="small-icon-button" *ngIf="node.type == ModelComponentType.ITEMGROUP">folder</mat-icon>
|
||||||
|
<mat-icon class="small-icon-button" *ngIf="node.type == ModelComponentType.ITEM">data_object</mat-icon>
|
||||||
|
{{node.name}}
|
||||||
|
</mat-tree-node>
|
||||||
|
</mat-tree>
|
@ -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
|
||||||
|
}
|
@ -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<ItemOverviewComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [ItemOverviewComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(ItemOverviewComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
123
src/app/side-overviews/item-overview/item-overview.component.ts
Normal file
123
src/app/side-overviews/item-overview/item-overview.component.ts
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
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";
|
||||||
|
|
||||||
|
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{
|
||||||
|
|
||||||
|
@Input() gameModel: GameModel | undefined
|
||||||
|
@Output() openItemgroupEmitter: EventEmitter<ItemGroup> = new EventEmitter();
|
||||||
|
@Output() onOpenItemEditor: EventEmitter<Item> = 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<FlatNode>(
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
11
testModel/items/Clothing/Clothing.json
Normal file
11
testModel/items/Clothing/Clothing.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"componentName": "Clothing",
|
||||||
|
"componentDescription": "",
|
||||||
|
"itemGroupCharacteristics": [
|
||||||
|
{
|
||||||
|
"characteristicName": "Test0",
|
||||||
|
"characteristicDescription": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"itemgroupType": 1
|
||||||
|
}
|
17
testModel/items/Clothing/Hose/Hose 1.json
Normal file
17
testModel/items/Clothing/Hose/Hose 1.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"componentName": "Hose 1",
|
||||||
|
"componentDescription": "",
|
||||||
|
"manuallyInheritedGroups": [
|
||||||
|
"Inventory"
|
||||||
|
],
|
||||||
|
"hierarchyInheritedGroups": [
|
||||||
|
"Clothing",
|
||||||
|
"Hose"
|
||||||
|
],
|
||||||
|
"itemCharacteristicValues": [
|
||||||
|
{
|
||||||
|
"key": "Test0",
|
||||||
|
"value": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
15
testModel/items/Clothing/Hose/Hose 2.json
Normal file
15
testModel/items/Clothing/Hose/Hose 2.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"componentName": "Hose 2",
|
||||||
|
"componentDescription": "",
|
||||||
|
"manuallyInheritedGroups": [],
|
||||||
|
"hierarchyInheritedGroups": [
|
||||||
|
"Clothing",
|
||||||
|
"Hose"
|
||||||
|
],
|
||||||
|
"itemCharacteristicValues": [
|
||||||
|
{
|
||||||
|
"key": "Test0",
|
||||||
|
"value": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
7
testModel/items/Clothing/Hose/Hose.json
Normal file
7
testModel/items/Clothing/Hose/Hose.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"componentName": "Hose",
|
||||||
|
"componentDescription": "",
|
||||||
|
"itemGroupCharacteristics": [],
|
||||||
|
"itemgroupType": 0,
|
||||||
|
"parentgroup": "Clothing"
|
||||||
|
}
|
7
testModel/items/Clothing/Oberteil/Oberteil.json
Normal file
7
testModel/items/Clothing/Oberteil/Oberteil.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"componentName": "Oberteil",
|
||||||
|
"componentDescription": "",
|
||||||
|
"itemGroupCharacteristics": [],
|
||||||
|
"itemgroupType": 0,
|
||||||
|
"parentgroup": "Clothing"
|
||||||
|
}
|
11
testModel/items/Inventory/Inventory.json
Normal file
11
testModel/items/Inventory/Inventory.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"componentName": "Inventory",
|
||||||
|
"componentDescription": "",
|
||||||
|
"itemGroupCharacteristics": [
|
||||||
|
{
|
||||||
|
"characteristicName": "Test0",
|
||||||
|
"characteristicDescription": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"itemgroupType": 1
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user