weapon-table.component.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import { Component, EventEmitter, Output } from '@angular/core';
  2. import { DataService } from 'src/services/data/data.service';
  3. import { Attribute, Weapon } from 'src/interfaces/interfaces';
  4. import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
  5. import { DetailsService } from 'src/services/details/details.service';
  6. import { WeaponDetailsComponent } from './weapon-details/weapon-details.component';
  7. import { ModalService } from 'src/services/modal/modal.service';
  8. import { WeaponModalComponent } from './weapon-modal/weapon-modal.component';
  9. @Component({
  10. selector: 'weapon-table',
  11. templateUrl: './weapon-table.component.html',
  12. styleUrls: ['./weapon-table.component.scss'],
  13. })
  14. export class WeaponTableComponent {
  15. @Output() public createNewWeapon: EventEmitter<void> =
  16. new EventEmitter<void>();
  17. @Output() public updateWeaponEvent: EventEmitter<any> =
  18. new EventEmitter<any>();
  19. public weapons!: Weapon[];
  20. public damageModifiers: string[] = [
  21. '0',
  22. '0',
  23. '0',
  24. '0',
  25. '0',
  26. '0',
  27. '0',
  28. '0',
  29. '0',
  30. '0',
  31. ];
  32. public isMonk: boolean = false;
  33. public strengthValue: number = 0;
  34. public dexterityValue: number = 0;
  35. public constructor(
  36. public dataAccessor: DataService,
  37. public detailsAccessor: DetailsService,
  38. private modalAccessor: ModalService,
  39. ) {}
  40. public ngOnInit(): void {
  41. this.dataAccessor.strength$.subscribe((newValue: Attribute) => {
  42. this.strengthValue = newValue.value;
  43. if (this.weapons) {
  44. this.calculateDamageModifierArray();
  45. }
  46. });
  47. this.dataAccessor.dexterity$.subscribe((newValue: Attribute) => {
  48. this.dexterityValue = newValue.value;
  49. if (this.weapons) {
  50. this.calculateDamageModifierArray();
  51. }
  52. });
  53. this.weapons = this.dataAccessor.favoriteWeapons;
  54. this.calculateDamageModifierArray();
  55. }
  56. /**
  57. * Calculates the whole damage modifier array.
  58. * Calls the single damage modifier calculation for each weapon.
  59. */
  60. private calculateDamageModifierArray(): void {
  61. this.weapons.forEach((_, index) => {
  62. this.calculateSingleDamageModifier(index);
  63. });
  64. }
  65. private calculateSingleDamageModifier(index: number): void {
  66. let value: number = 0;
  67. let bonus: number = 0;
  68. const weapon: Weapon = this.weapons[index];
  69. if (weapon.useAttributeModifier) {
  70. if (this.isMonk || weapon.isFinesse) {
  71. value = Math.max(this.strengthValue, this.dexterityValue);
  72. } else if (weapon.isRanged) {
  73. value = this.dexterityValue;
  74. } else {
  75. value = this.strengthValue;
  76. }
  77. } else {
  78. value = 10;
  79. }
  80. if (weapon.isMagical) {
  81. bonus = weapon.magicBonus!;
  82. }
  83. if (weapon.hasAdditionalDamage) {
  84. bonus += weapon.additionalDamage!;
  85. }
  86. this.damageModifiers[index] = this.calculateModifier(value, bonus);
  87. }
  88. public dropWeapons(event: CdkDragDrop<string[]>): void {
  89. moveItemInArray(this.weapons, event.previousIndex, event.currentIndex);
  90. moveItemInArray(
  91. this.damageModifiers,
  92. event.previousIndex,
  93. event.currentIndex,
  94. );
  95. this.updateWeaponInDatabase();
  96. }
  97. public updateWeaponInDatabase(): void {
  98. this.dataAccessor.favoriteWeapons = this.weapons;
  99. }
  100. public addWeapon(weapon: Weapon) {
  101. this.weapons.push(weapon);
  102. this.calculateDamageModifierArray();
  103. this.updateWeaponInDatabase();
  104. }
  105. public openDetailsPanel(index: number): void {
  106. this.detailsAccessor.openPanel(WeaponDetailsComponent, {
  107. weapon: this.weapons[index],
  108. damageModifier: this.damageModifiers[index],
  109. });
  110. const resultSubscription = this.detailsAccessor.result$.subscribe(
  111. (result) => {
  112. if (result.state === 'delete') {
  113. this.deleteWeapon(index);
  114. } else if (result.state === 'update') {
  115. this.openModal(true, index);
  116. }
  117. resultSubscription.unsubscribe();
  118. },
  119. );
  120. }
  121. public openModal(isUpdate: boolean, index?: number): void {
  122. this.modalAccessor.openModal(WeaponModalComponent, {
  123. item:
  124. index !== undefined
  125. ? JSON.parse(JSON.stringify(this.weapons[index]))
  126. : undefined,
  127. isUpdate: isUpdate,
  128. });
  129. const resultSubscription = this.modalAccessor.result$.subscribe(
  130. (result) => {
  131. if (result.state === 'update') {
  132. this.updateWeapon(result.data, index!);
  133. } else if (result.state === 'add') {
  134. this.addWeapon(result.data);
  135. }
  136. resultSubscription.unsubscribe();
  137. },
  138. );
  139. }
  140. public updateWeapon(weapon: Weapon, index: number): void {
  141. this.weapons[index] = weapon;
  142. this.calculateSingleDamageModifier(index);
  143. this.updateWeaponInDatabase();
  144. }
  145. public deleteWeapon(index: number): void {
  146. this.weapons.splice(index, 1);
  147. this.calculateDamageModifierArray();
  148. this.updateWeaponInDatabase();
  149. }
  150. ////// Calculation Helpers
  151. private calculateModifier(attributeValue: number, bonus: number): string {
  152. let mod: number = Math.floor((attributeValue - 10) / 2) + bonus;
  153. if (mod > 0) {
  154. return '+' + mod;
  155. } else {
  156. return mod.toString();
  157. }
  158. }
  159. }