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