Переглянути джерело

added atriibutes and skills and almost done

Christopher Giese 1 рік тому
батько
коміт
0de1cac1a0

+ 2 - 3
src/app/character/character-creator/character-creator.component.ts

@@ -1,8 +1,6 @@
-import { BrowserModule } from '@angular/platform-browser';
 import { Component } from '@angular/core';
 import { DataService } from 'src/services/data/data.service';
 import { Router } from '@angular/router';
-import { Character } from 'src/interfaces/character';
 
 @Component({
   selector: 'app-character-creator',
@@ -15,6 +13,7 @@ export class CharacterCreatorComponent {
   public characterName: string = '';
 
   public async createCharacter(): Promise<void> {
+    // Creates a new entry in the character collection
     this.dataService.addData('characters', { name: this.characterName });
     // TODO: Animation, dass der Character erstellt wurde
     await this.createNewCharacterInDatabase();
@@ -80,7 +79,7 @@ export class CharacterCreatorComponent {
           stealth: ['', false],
           survival: ['', false],
         },
-        'skill'
+        'skills'
       ),
       // Character Combat Stats
       this.dataService.addData(

+ 1 - 0
src/app/journal/journal-home/journal-home.component.ts

@@ -13,6 +13,7 @@ export class JournalHomeComponent {
   public openNavigation(): void {
     this.offcanvasNavigation?.openNavigation();
   }
+
   // public ngAfterViewInit(): void {
   //   // Hier können funktionen aufgerufen werden, die in der child component definiert sind
   //   this.offcanvasNavigation?.openNavigation();

+ 15 - 0
src/app/journal/journal-stats/attribute-field/attribute-field.component.html

@@ -0,0 +1,15 @@
+<div class="attribute-box">
+  <div>
+    <label class="attribute-name">{{ attributeNames[attributeName] }}</label>
+  </div>
+  <div>
+    <input
+      class="attribute-value"
+      [(ngModel)]="attribute.value"
+      (change)="updateValue()"
+    />
+  </div>
+  <div>
+    <label class="attribute-modifier">{{ attributeModifier }}</label>
+  </div>
+</div>

+ 15 - 0
src/app/journal/journal-stats/attribute-field/attribute-field.component.scss

@@ -0,0 +1,15 @@
+.attribute-box{
+    border: solid 1px black;
+
+    input{
+        border: none;
+        outline: none;
+        box-shadow: none;
+        text-align: center;
+        background-color: transparent;
+        width: 100%;
+        font-size: 1.5rem;
+        font-weight: 600;
+    }
+}
+        

+ 21 - 0
src/app/journal/journal-stats/attribute-field/attribute-field.component.spec.ts

@@ -0,0 +1,21 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AttributeFieldComponent } from './attribute-field.component';
+
+describe('AttributeFieldComponent', () => {
+  let component: AttributeFieldComponent;
+  let fixture: ComponentFixture<AttributeFieldComponent>;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({
+      declarations: [AttributeFieldComponent]
+    });
+    fixture = TestBed.createComponent(AttributeFieldComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 84 - 0
src/app/journal/journal-stats/attribute-field/attribute-field.component.ts

@@ -0,0 +1,84 @@
+import { Component, Input } from '@angular/core';
+import { Attribute } from 'src/interfaces/attribute';
+import { DataService } from 'src/services/data/data.service';
+import { Observable } from 'rxjs';
+
+@Component({
+  selector: 'app-attribute-field',
+  templateUrl: './attribute-field.component.html',
+  styleUrls: ['./attribute-field.component.scss'],
+})
+export class AttributeFieldComponent {
+  @Input() attributeName: string = '';
+  public attribute: Attribute = { name: '', value: 0 };
+  public attributeModifier: string = '0';
+
+  public attributeNames: any = {
+    strength: 'Stärke',
+    dexterity: 'Geschicklichkeit',
+    constitution: 'Konstitution',
+    intelligence: 'Intelligenz',
+    wisdom: 'Weisheit',
+    charisma: 'Charisma',
+  };
+
+  public constructor(public dataAccessor: DataService) {}
+
+  ngOnInit(): void {
+    this.initAttributeSubscription();
+  }
+
+  public ngAfterViewInit(): void {
+    // this.mockChanges();
+  }
+
+  private initAttributeSubscription(): void {
+    const observable: Observable<Attribute> = eval(
+      `this.dataAccessor.${this.attributeName}$`
+    );
+    observable.subscribe((newValue: Attribute) => {
+      this.attribute = newValue;
+      this.attributeModifier = this.calculateModifier(); //needs to be fixed, is not being reflected in the DOM
+    });
+  }
+
+  // Wenn das hier auskommentiert ist, kommt cannot read properties of undefined reading 'next'
+
+  // private mockChanges(): void {
+  //   if (this.attributeName === 'strength') {
+  //     setTimeout(() => {
+  //       this.dataAccessor.updateAttribute({
+  //         name: 'strength',
+  //         value: 18,
+  //         proficiency: false,
+  //       });
+  //       console.log('updated data');
+  //       console.log(this.attributeModifier);
+  //     }, 3000);
+  //   }
+  // }
+
+  public updateValue(): void {
+    // attribute.name is strengt
+    console.log(this.attribute.name);
+    console.log(this.attribute.value);
+    console.log(this.attribute.proficiency);
+    this.dataAccessor.updateAttribute({
+      name: this.attribute.name,
+      value: this.attribute.value,
+      proficiency: this.attribute.proficiency,
+      // name: 'strength',
+      // value: 18,
+      // proficiency: false,
+    });
+  }
+
+  public calculateModifier(): string {
+    const mod: number = Math.floor((this.attribute.value - 10) / 2);
+    if (mod > 0) {
+      return '+' + mod;
+    } else {
+      return mod.toString();
+    }
+  }
+}

+ 20 - 1
src/app/journal/journal-stats/journal-stats.component.html

@@ -1 +1,20 @@
-<p style="height: 100%">journal-stats works!</p>
+<div class="stats-page-container">
+  <div class="name-container">Eliane Langwasser</div>
+
+  <div class="stats-container">
+    <div class="attribute-container">
+      <ng-container *ngFor="let attribute of attributeArray">
+        <app-attribute-field [attributeName]="attribute"></app-attribute-field>
+      </ng-container>
+    </div>
+
+    <div class="skill-proficiency-container">
+      <div>+2 Proficiency</div>
+      <ng-container *ngFor="let skill of skillArray">
+        <app-skill-field [skillName]="skill"></app-skill-field>
+      </ng-container>
+    </div>
+    <div class="life-weapon-container">life and weapon container</div>
+    <div class="platzhalter">platzhalter</div>
+  </div>
+</div>

+ 65 - 0
src/app/journal/journal-stats/journal-stats.component.scss

@@ -0,0 +1,65 @@
+.stats-page-container{
+    display: flex;
+    flex-direction: column;
+    width: 100vw;
+    gap: 2rem;
+
+    .name-container{
+        display: flex;
+        flex-direction: column;
+        width: 100vw;
+        height: 5vh;
+        // margin: 5rem 0 0 2rem;
+        padding: 10px;
+        border: 1px solid #8d8c8c;
+        border-radius: 5px;
+        text-align: center;
+    }
+}
+
+
+.stats-container{
+    display: flex;
+    flex-direction: row;
+    width: 100vw;
+    gap: 2rem;
+    border: 1px solid #882121;
+    border-radius: 5px;
+
+    .attribute-container{
+        display: flex;
+        flex-direction: column;
+        gap: 2rem;
+        width: 10%;
+        padding: 10px;
+        border: 1px solid #8d8c8c;
+        border-radius: 5px;
+        text-align: center;
+    }
+
+    .skill-proficiency-container{
+        display: flex;
+        flex-direction: column;
+        gap: 2rem;
+        width: 20%;
+        border: 1px solid #8d8c8c;
+        border-radius: 5px;
+    }
+    
+    .life-weapon-container{
+        display:flex;
+        flex-direction: column;
+        width: 30vw;
+        border: 1px solid #8d8c8c;
+        border-radius: 5px;
+    }
+
+    .platzhalter{
+        width: 30vw;
+        height: 80vh;
+        border: 1px solid #8d8c8c;
+        border-radius: 5px;
+    }
+}
+
+

+ 37 - 1
src/app/journal/journal-stats/journal-stats.component.ts

@@ -1,10 +1,46 @@
 import { Component } from '@angular/core';
+import { DataService } from 'src/services/data/data.service';
+import { DatabaseService } from 'src/services/database/database.service';
+import { Attribute } from 'src/interfaces/attribute';
 
 @Component({
   selector: 'app-journal-stats',
   templateUrl: './journal-stats.component.html',
-  styleUrls: ['./journal-stats.component.scss']
+  styleUrls: ['./journal-stats.component.scss'],
 })
 export class JournalStatsComponent {
+  public constructor(
+    public dataAccessor: DataService,
+    public database: DatabaseService
+  ) {}
 
+  public attributeArray: string[] = [
+    'strength',
+    'dexterity',
+    'constitution',
+    'intelligence',
+    'wisdom',
+    'charisma',
+  ];
+
+  public skillArray: string[] = [
+    'acrobatics',
+    'animalHandling',
+    'arcana',
+    'athletics',
+    'deception',
+    'history',
+    'insight',
+    'intimidation',
+    'investigation',
+    'medicine',
+    'nature',
+    'perception',
+    'performance',
+    'persuasion',
+    'religion',
+    'sleightOfHand',
+    'stealth',
+    'survival',
+  ];
 }

+ 5 - 0
src/app/journal/journal-stats/skill-field/skill-field.component.html

@@ -0,0 +1,5 @@
+<div class="skill-box">
+  <input class="attribute-value" [(ngModel)]="skill.value" />
+  <label class="attribute-name">{{ skillNames[skillName].attribute }}</label>
+  <label class="attribute-name">{{ skillNames[skillName].skill }}</label>
+</div>

+ 18 - 0
src/app/journal/journal-stats/skill-field/skill-field.component.scss

@@ -0,0 +1,18 @@
+.skill-box{
+    border: solid 1px black;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    gap:1rem;
+
+    input{
+        border: none;
+        outline: none;
+        box-shadow: none;
+        text-align: center;
+        background-color: transparent;
+        width: 30%;
+        font-size: 1.5rem;
+        font-weight: 600;
+    }
+}

+ 21 - 0
src/app/journal/journal-stats/skill-field/skill-field.component.spec.ts

@@ -0,0 +1,21 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SkillFieldComponent } from './skill-field.component';
+
+describe('SkillFieldComponent', () => {
+  let component: SkillFieldComponent;
+  let fixture: ComponentFixture<SkillFieldComponent>;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({
+      declarations: [SkillFieldComponent]
+    });
+    fixture = TestBed.createComponent(SkillFieldComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 78 - 0
src/app/journal/journal-stats/skill-field/skill-field.component.ts

@@ -0,0 +1,78 @@
+import { Component, Input } from '@angular/core';
+import { Skill } from 'src/interfaces/skill';
+import { DataService } from 'src/services/data/data.service';
+import { Observable } from 'rxjs';
+import { Attribute } from 'src/interfaces/attribute';
+
+@Component({
+  selector: 'app-skill-field',
+  templateUrl: './skill-field.component.html',
+  styleUrls: ['./skill-field.component.scss'],
+})
+export class SkillFieldComponent {
+  @Input() skillName: string = '';
+  public skill: Skill = { name: '', value: 0 };
+  private attribute: Attribute = { name: '', value: 0 };
+  public skillModifier: string = '0';
+
+  public constructor(public dataAccessor: DataService) {}
+
+  public skillNames: any = {
+    acrobatics: { skill: 'Akrobatik', attribute: 'GES', long: 'dexterity' },
+    animalHandling: { skill: 'Tierkunde', attribute: 'WIS', long: 'wisdom' },
+    arcana: { skill: 'Arkanes Wissen', attribute: 'INT', long: 'intelligence' },
+    athletics: { skill: 'Athletik', attribute: 'STR', long: 'strength' },
+    deception: { skill: 'Täuschung', attribute: 'CHA', long: 'charisma' },
+    history: { skill: 'Geschichte', attribute: 'INT', long: 'intelligence' },
+    insight: { skill: 'Einsicht', attribute: 'WIS', long: 'wisdom' },
+    intimidation: {
+      skill: 'Einschüchterung',
+      attribute: 'CHA',
+      long: 'charisma',
+    },
+    investigation: {
+      skill: 'Ermittlung',
+      attribute: 'INT',
+      long: 'intelligence',
+    },
+    medicine: { skill: 'Medizin', attribute: 'WIS', long: 'wisdom' },
+    nature: { skill: 'Natur', attribute: 'INT', long: 'intelligence' },
+    perception: { skill: 'Wahrnehmung', attribute: 'WIS', long: 'wisdom' },
+    performance: { skill: 'Performance', attribute: 'CHA', long: 'charisma' },
+    persuasion: { skill: 'Überredung', attribute: 'CHA', long: 'charisma' },
+    religion: { skill: 'Religion', attribute: 'INT', long: 'intelligence' },
+    sleightOfHand: {
+      skill: 'Fingerfertigkeit',
+      attribute: 'GES',
+      long: 'dexterity',
+    },
+    stealth: { skill: 'Heimlichkeit', attribute: 'GES', long: 'dexterity' },
+    survival: { skill: 'Überleben', attribute: 'WIS', long: 'wisdom' },
+  };
+
+  ngOnInit(): void {
+    // console.log('init');
+    this.initAttributeSubscription();
+  }
+
+  private initAttributeSubscription(): void {
+    const observable: Observable<Attribute> = eval(
+      `this.dataAccessor.${this.skillNames[this.skillName].long}$`
+    );
+    observable.subscribe((newValue: Attribute) => {
+      this.attribute = newValue;
+      this.skillModifier = this.calculateModifier();
+    });
+  }
+
+  private calculateModifier(): string {
+    const mod: number = Math.floor((this.attribute.value - 10) / 2);
+    if (mod > 0) {
+      // console.log('mod: +', mod);
+      return '+' + mod;
+    } else {
+      // console.log(mod.toString());
+      return mod.toString();
+    }
+  }
+}

+ 6 - 2
src/app/journal/journal.module.ts

@@ -1,7 +1,7 @@
 import { NgModule } from '@angular/core';
 import { CommonModule } from '@angular/common';
 import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
-
+import { FormsModule } from '@angular/forms';
 import { JournalRoutingModule } from './journal-routing.module';
 import { JournalHomeComponent } from './journal-home/journal-home.component';
 import { JournalStatsComponent } from './journal-stats/journal-stats.component';
@@ -12,6 +12,8 @@ import { JournalCharacterComponent } from './journal-character/journal-character
 import { TabbarComponent } from './journal-home/tabbar/tabbar.component';
 import { OffcanvasComponent } from './journal-home/offcanvas/offcanvas.component';
 import { InfopanelComponent } from './journal-home/infopanel/infopanel.component';
+import { AttributeFieldComponent } from './journal-stats/attribute-field/attribute-field.component';
+import { SkillFieldComponent } from './journal-stats/skill-field/skill-field.component';
 
 @NgModule({
   declarations: [
@@ -24,7 +26,9 @@ import { InfopanelComponent } from './journal-home/infopanel/infopanel.component
     TabbarComponent,
     OffcanvasComponent,
     InfopanelComponent,
+    AttributeFieldComponent,
+    SkillFieldComponent,
   ],
-  imports: [CommonModule, JournalRoutingModule, NgbModule],
+  imports: [CommonModule, JournalRoutingModule, NgbModule, FormsModule],
 })
 export class JournalModule {}

+ 5 - 0
src/interfaces/attribute.ts

@@ -0,0 +1,5 @@
+export interface Attribute {
+  name: string;
+  value: number;
+  proficiency?: boolean;
+}

+ 6 - 0
src/interfaces/skill.ts

@@ -0,0 +1,6 @@
+export interface Skill {
+  name: string;
+  value: number;
+  proficiency?: boolean;
+  bardicExpertise?: boolean;
+}

+ 288 - 6
src/services/data/data.service.ts

@@ -2,6 +2,9 @@ import { Injectable } from '@angular/core';
 import Localbase from 'localbase';
 import { Character } from 'src/interfaces/character';
 import { Router } from '@angular/router';
+import { BehaviorSubject } from 'rxjs';
+import { Attribute } from 'src/interfaces/attribute';
+import { Skill } from 'src/interfaces/skill';
 
 @Injectable({
   providedIn: 'root',
@@ -11,9 +14,279 @@ export class DataService {
 
   constructor(private Router: Router) {
     this.db = new Localbase('myDatabase');
+    // this.test();
   }
 
-  public character: any;
+  // public test(): void {
+  //   let char: Character = {
+  //     characterData: {
+  //       name: 'Eliane',
+  //       class: '',
+  //       race: '',
+  //       level: '',
+  //       subclass: '',
+  //       background: '',
+  //       experience: '',
+  //       inspiration: '',
+  //       proficiencyBonus: '2',
+  //     },
+  //     attributes: {
+  //       strength: ['12', false],
+  //       dexterity: ['14', false],
+  //       constitution: ['16', false],
+  //       intelligence: ['10', false],
+  //       wisdom: ['16', false],
+  //       charisma: ['10', false],
+  //     },
+  //     skills: {
+  //       acrobatics: ['12', false],
+  //       animalHandling: ['11', false],
+  //       arcana: ['11', false],
+  //       athletics: ['11', false],
+  //       deception: ['11', false],
+  //       history: ['12', false],
+  //       insight: ['13', false],
+  //       intimidation: ['14', false],
+  //       investigation: ['16', false],
+  //       medicine: ['15', false],
+  //       nature: ['17', false],
+  //       perception: ['18', false],
+  //       performance: ['19', false],
+  //       persuasion: ['20', false],
+  //       religion: ['9', false],
+  //       sleightOfHand: ['8', false],
+  //       stealth: ['7', false],
+  //       survival: ['6', false],
+  //     },
+  //     combatStats: {
+  //       armorClass: '18',
+  //       initiative: '+2',
+  //       speed: '30',
+  //       hitPointMaximum: '12',
+  //       currentHitPoints: '12',
+  //       temporaryHitPoints: '0',
+  //       hitDice: '',
+  //       deathSaveSuccesses: '0',
+  //       deathSaveFailures: '0',
+  //     },
+  //     appearance: {
+  //       age: '',
+  //       height: '',
+  //       weight: '',
+  //       eyes: '',
+  //       skin: '',
+  //       hair: '',
+  //     },
+  //     personality: {
+  //       personalityTraits: '',
+  //       ideals: '',
+  //       bonds: '',
+  //       flaws: '',
+  //     },
+  //     weapons: {
+  //       name: '',
+  //       attackBonus: '',
+  //       damage: '',
+  //       damageType: '',
+  //       range: '',
+  //       description: '',
+  //     },
+  //   };
+  //   this.character = char;
+  //   // console.log('character: ', this.character);
+  // }
+
+  public character: any = {};
+
+  // #region character data retrieval
+
+  public getCompleteCharacter(): Character {
+    return this.character;
+  }
+
+  public getCharacterData(): any {
+    return this.character.characterData;
+  }
+
+  public getAppearance(): any {
+    return this.character.appearance;
+  }
+
+  public getAttributes(): any {
+    return this.character.attributes;
+  }
+
+  public getSkills(): any {
+    return this.character.skills;
+  }
+
+  public getCombatStats(): any {
+    return this.character.combatStats;
+  }
+
+  public getPersonality(): any {
+    return this.character.personality;
+  }
+
+  public getWeapons(): any {
+    return this.character.weapons;
+  }
+
+  // #endregion
+
+  // #region Attribute observables
+
+  // Atrributes
+
+  /**
+   *
+   * @param newValue The new value of the Attribute
+   */
+  updateAttribute(newValue: Attribute) {
+    const functionCall: string = newValue.name + 'Subject.next(newValue)';
+    eval(`this.${functionCall}`);
+    console.log('updateAttribute: ', newValue.name);
+    // Datenbank updaten
+  }
+
+  private strengthSubject = new BehaviorSubject<Attribute>(
+    { name: 'strengt', value: 10, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public strength$ = this.strengthSubject.asObservable();
+
+  private dexteritySubject = new BehaviorSubject<Attribute>(
+    { name: 'dexterity', value: 10, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public dexterity$ = this.dexteritySubject.asObservable();
+
+  private constitutionSubject = new BehaviorSubject<Attribute>(
+    { name: 'constitution', value: 10, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public constitution$ = this.constitutionSubject.asObservable();
+
+  private intelligenceSubject = new BehaviorSubject<Attribute>(
+    { name: 'intelligence', value: 10, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public intelligence$ = this.intelligenceSubject.asObservable();
+
+  private wisdomSubject = new BehaviorSubject<Attribute>(
+    { name: 'wisdom', value: 10, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public wisdom$ = this.wisdomSubject.asObservable();
+
+  private charismaSubject = new BehaviorSubject<Attribute>(
+    { name: 'charisma', value: 10, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public charisma$ = this.charismaSubject.asObservable();
+
+  // #endregion
+
+  // #region Skill observables
+
+  /**
+   *
+   * @param newValue The new value of the skill
+   */
+  updateSkills(newValue: Skill) {
+    const functionCall: string = newValue.name + 'Subject.next(newValue)';
+    eval(`this.${functionCall}`);
+    console.log('updateSkill: ', newValue.name);
+    // Datenbank updaten
+  }
+
+  private acrobaticsSubject = new BehaviorSubject<Skill>(
+    { name: 'acrobatics', value: 1, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public acrobatics$ = this.acrobaticsSubject.asObservable();
+
+  private animalHandlingSubject = new BehaviorSubject<Skill>(
+    { name: 'animalHandling', value: 1, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public animalHandling$ = this.animalHandlingSubject.asObservable();
+
+  private arcanaSubject = new BehaviorSubject<Skill>(
+    { name: 'arcana', value: 1, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public arcana$ = this.arcanaSubject.asObservable();
+
+  private athleticsSubject = new BehaviorSubject<Skill>(
+    { name: 'athletics', value: 1, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public athletics$ = this.athleticsSubject.asObservable();
+
+  private deceptionSubject = new BehaviorSubject<Skill>(
+    { name: 'deception', value: 1, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public deception$ = this.deceptionSubject.asObservable();
+
+  private historySubject = new BehaviorSubject<Skill>(
+    { name: 'history', value: 1, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public history$ = this.historySubject.asObservable();
+
+  private insightSubject = new BehaviorSubject<Skill>(
+    { name: 'insight', value: 1, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public insight$ = this.insightSubject.asObservable();
+
+  private intimidationSubject = new BehaviorSubject<Skill>(
+    { name: 'intimidation', value: 1, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public intimidation$ = this.intimidationSubject.asObservable();
+
+  private investigationSubject = new BehaviorSubject<Skill>(
+    { name: 'investigation', value: 1, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public investigation$ = this.investigationSubject.asObservable();
+
+  private medicineSubject = new BehaviorSubject<Skill>(
+    { name: 'medicine', value: 1, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public medicine$ = this.medicineSubject.asObservable();
+
+  private natureSubject = new BehaviorSubject<Skill>(
+    { name: 'nature', value: 1, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public nature$ = this.natureSubject.asObservable();
+
+  private perceptionSubject = new BehaviorSubject<Skill>(
+    { name: 'perception', value: 1, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public perception$ = this.perceptionSubject.asObservable();
+
+  private performanceSubject = new BehaviorSubject<Skill>(
+    { name: 'performance', value: 1, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public performance$ = this.performanceSubject.asObservable();
+
+  private persuasionSubject = new BehaviorSubject<Skill>(
+    { name: 'persuasion', value: 1, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public persuasion$ = this.persuasionSubject.asObservable();
+
+  private religionSubject = new BehaviorSubject<Skill>(
+    { name: 'religion', value: 1, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public religion$ = this.religionSubject.asObservable();
+
+  private sleightOfHandSubject = new BehaviorSubject<Skill>(
+    { name: 'sleightOfHand', value: 1, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public sleightOfHand$ = this.sleightOfHandSubject.asObservable();
+
+  private stealthSubject = new BehaviorSubject<Skill>(
+    { name: 'stealth', value: 1, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public stealth$ = this.stealthSubject.asObservable();
+
+  private survivalSubject = new BehaviorSubject<Skill>(
+    { name: 'survival', value: 1, proficiency: false } //erstmal nur gemockt, später muss der Wert aus der Datenbank kommen
+  );
+  public survival$ = this.survivalSubject.asObservable();
+
+  // #endregion
+
+  // #region database calls
 
   public async addData(
     collection: string,
@@ -49,15 +322,23 @@ export class DataService {
     this.db.collection(collection).delete();
   }
 
+  // #endregion
+
+  // #region character selection and construction
+
+  /**
+   *
+   * @param character The name of the character that was selected
+   */
   public async selectCharacter(character: string) {
     console.log('selectCharacter ausgewählt');
     const characterData = await this.getCollectionWithKeys(character);
-    this.character = this.getcurrentCharacterData(characterData);
+    this.character = this.buildCurrentCharacter(characterData);
+    console.log('character: ', this.character);
     this.Router.navigate(['journal']);
   }
 
-  private getcurrentCharacterData(currentCharacterData: any) {
-    console.log(currentCharacterData);
+  private buildCurrentCharacter(currentCharacterData: any): Character {
     const [
       appearanceData,
       attributesData,
@@ -68,7 +349,6 @@ export class DataService {
       weaponsData,
     ] = currentCharacterData.map((entry: any) => entry.data);
 
-    console.log(appearanceData);
     const appearance = {
       age: appearanceData.age,
       height: appearanceData.height,
@@ -155,6 +435,8 @@ export class DataService {
       skills: skills,
       weapons: weapons,
     };
-    this.character = newCharacter;
+    console.log('newCharacter: ', newCharacter);
+    return newCharacter;
   }
+  // #endregion
 }

+ 16 - 0
src/services/database/database.service.spec.ts

@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { DatabaseService } from './database.service';
+
+describe('DatabaseService', () => {
+  let service: DatabaseService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(DatabaseService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});

+ 21 - 0
src/services/database/database.service.ts

@@ -0,0 +1,21 @@
+import { Injectable } from '@angular/core';
+import { BehaviorSubject } from 'rxjs';
+
+@Injectable({
+  providedIn: 'root',
+})
+export class DatabaseService {
+  private dataSubject = new BehaviorSubject<string>('Initial Value');
+  public data$ = this.dataSubject.asObservable();
+
+  updateData(newValue: string) {
+    this.dataSubject.next(newValue);
+  }
+
+  ngOnInit(): void {
+    setTimeout(() => {
+      this.updateData('New Value');
+      console.log('updated data');
+    }, 5000);
+  }
+}