spellslots.component.ts 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. import { Component } from '@angular/core';
  2. import { DataService } from 'src/services/data/data.service';
  3. import { ModalService } from 'src/services/modal/modal.service';
  4. import { SpellslotsModalComponent } from './spellslots-modal/spellslots-modal.component';
  5. @Component({
  6. selector: 'spellslots-table',
  7. templateUrl: './spellslots.component.html',
  8. styleUrls: ['./spellslots.component.scss'],
  9. })
  10. export class SpellslotsComponent {
  11. public spellslots: any[] = [];
  12. public showSpellslots: boolean = false;
  13. public kiPoints: any;
  14. public spellcastingAttribute: string = '';
  15. public proficiencyBonus: number = 2;
  16. public attributeValue: number = 0;
  17. public isMonk: boolean = true;
  18. public spellAttackModifier: number = 0;
  19. public spellSaveDC: number = 0;
  20. public slotNumber: number = 1;
  21. public constructor(
  22. public dataAccessor: DataService,
  23. public modalAccessor: ModalService,
  24. ) {
  25. this.isMonk = this.dataAccessor.characterData.class === 'Monk';
  26. }
  27. public ngOnInit(): void {
  28. const spells = this.dataAccessor.spellslots;
  29. const kiPoints = this.dataAccessor.kiPoints;
  30. this.spellslots = spells.spellslots;
  31. this.showSpellslots = spells.showSpellslots;
  32. this.spellcastingAttribute = spells.spellcastingAttribute;
  33. this.kiPoints = kiPoints;
  34. // this.calculateModifiers();
  35. this.subscribeToProficiency();
  36. this.subscribeToAttribute();
  37. }
  38. public ngAfterViewInit(): void {
  39. setTimeout(() => {
  40. this.spellslots.forEach((_, levelIndex) => {
  41. this.correctSpellslotsView(levelIndex);
  42. });
  43. this.correctKiPointsView();
  44. }, 10);
  45. }
  46. // FUNCTIONS
  47. public openModal(): void {
  48. this.modalAccessor.openModal(SpellslotsModalComponent, {
  49. kiPoints: JSON.parse(JSON.stringify(this.kiPoints)),
  50. spellslots: JSON.parse(JSON.stringify(this.spellslots)),
  51. showSpellslots: this.showSpellslots,
  52. isMonk: this.isMonk,
  53. });
  54. const resultSubscription = this.modalAccessor.result$.subscribe(
  55. (result) => {
  56. if (result.state === 'update') {
  57. this.updateSlotsAndPoints(result.data);
  58. }
  59. resultSubscription.unsubscribe();
  60. },
  61. );
  62. }
  63. private calculateModifiers(): void {
  64. const spellcastingAttribute = this.spellcastingAttribute;
  65. if (spellcastingAttribute !== undefined) {
  66. const modifier = Math.floor((this.attributeValue - 10) / 2);
  67. this.spellAttackModifier = modifier + this.proficiencyBonus;
  68. this.spellSaveDC = 8 + modifier + this.proficiencyBonus;
  69. }
  70. }
  71. private subscribeToAttribute(): void {
  72. if (this.spellcastingAttribute !== undefined) {
  73. const command =
  74. 'this.dataAccessor.' +
  75. this.spellcastingAttribute.toLowerCase() +
  76. '$.subscribe((attribute) => {this.attributeValue = attribute.value; this.calculateModifiers();});';
  77. eval(command);
  78. }
  79. }
  80. private subscribeToProficiency(): void {
  81. this.dataAccessor.proficiency$.subscribe((value) => {
  82. this.proficiencyBonus = value;
  83. this.calculateModifiers();
  84. });
  85. }
  86. // ki points
  87. public handleUsedKiPoints(pointIndex: number, eventTarget: any): void {
  88. if (eventTarget.checked) {
  89. this.kiPoints.usedPoints++;
  90. if (pointIndex + 1 !== this.kiPoints.usedPoints) {
  91. this.correctKiPointsView();
  92. }
  93. } else {
  94. this.kiPoints.usedPoints--;
  95. if (pointIndex !== this.kiPoints.usedPoints) {
  96. this.correctKiPointsView();
  97. }
  98. }
  99. this.updateKiPointsDatabase();
  100. }
  101. private correctKiPointsView(): void {
  102. const totalKiPoints = this.kiPoints.totalPoints;
  103. const usedKiPoints = this.kiPoints.usedPoints;
  104. for (let kiIndex = 0; kiIndex < usedKiPoints; kiIndex++) {
  105. setTimeout(() => {
  106. (
  107. document.getElementById('checkbox' + kiIndex) as HTMLInputElement
  108. ).checked = true;
  109. });
  110. }
  111. for (let kiIndex = usedKiPoints; kiIndex < totalKiPoints; kiIndex++) {
  112. setTimeout(() => {
  113. (
  114. document.getElementById('checkbox' + kiIndex) as HTMLInputElement
  115. ).checked = false;
  116. });
  117. }
  118. }
  119. // spellslots
  120. public handleUsedSlots(
  121. levelIndex: number,
  122. slotIndex: number,
  123. eventTarget: any,
  124. ) {
  125. // if now checked, it means the slot was just used.
  126. if (eventTarget.checked) {
  127. this.spellslots[levelIndex].usedSlots++;
  128. if (slotIndex + 1 !== this.spellslots[levelIndex].usedSlots) {
  129. this.correctSpellslotsView(levelIndex);
  130. }
  131. } else {
  132. this.spellslots[levelIndex].usedSlots--;
  133. if (slotIndex !== this.spellslots[levelIndex].usedSlots) {
  134. this.correctSpellslotsView(levelIndex);
  135. }
  136. }
  137. this.updateSpellslotDatabase();
  138. }
  139. public correctSpellslotsView(levelIndex: number): void {
  140. const totalSlots = this.spellslots[levelIndex].totalSlots;
  141. const usedSlots = this.spellslots[levelIndex].usedSlots;
  142. for (let slotIndex = 0; slotIndex < usedSlots; slotIndex++) {
  143. setTimeout(() => {
  144. (
  145. document.getElementById(
  146. 'checkbox' + levelIndex + '-' + slotIndex,
  147. ) as HTMLInputElement
  148. ).checked = true;
  149. });
  150. }
  151. for (let slotIndex = usedSlots; slotIndex < totalSlots; slotIndex++) {
  152. setTimeout(() => {
  153. (
  154. document.getElementById(
  155. 'checkbox' + levelIndex + '-' + slotIndex,
  156. ) as HTMLInputElement
  157. ).checked = false;
  158. });
  159. }
  160. }
  161. // general
  162. public getArray(length: number): any[] {
  163. return Array.from({ length: length });
  164. }
  165. public isNotEmptyObject(obj: object): boolean {
  166. return Object.keys(obj).length !== 0;
  167. }
  168. public updateSpellslotDatabase(): void {
  169. this.dataAccessor.spellslots = {
  170. spellslots: this.spellslots,
  171. showSpellslots: this.showSpellslots,
  172. spellcastingAttribute: this.spellcastingAttribute,
  173. };
  174. }
  175. public updateKiPointsDatabase(): void {
  176. this.dataAccessor.kiPoints = this.kiPoints;
  177. }
  178. public updateSlotsAndPoints(data: any): void {
  179. this.spellslots = data.spellslots.spellslots;
  180. this.showSpellslots = data.spellslots.showSpellslots;
  181. this.kiPoints = data.kiPoints;
  182. setTimeout(() => {
  183. this.spellslots.forEach((_, levelIndex) => {
  184. this.correctSpellslotsView(levelIndex);
  185. });
  186. this.correctKiPointsView();
  187. }, 200);
  188. this.updateSpellslotDatabase();
  189. this.updateKiPointsDatabase();
  190. }
  191. }