Merge pull request 'SES-146 Added spells dialog' (#75) from SES-146 into dev
Reviewed-on: #75
This commit is contained in:
commit
f3c1edbc2c
@ -46,6 +46,7 @@ import { ArmorService } from '../services/armor.service';
|
||||
import { OtherEquipmentService } from '../services/other-equipment.service';
|
||||
import { GameMasterMonstersTableComponent } from './components/game-master-monsters-table/game-master-monsters-table.component';
|
||||
import { MonsterService } from '../services/monster.service';
|
||||
import { SpellDetailsDialogComponent } from './components/spell-details-dialog/spell-details-dialog.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@ -63,6 +64,7 @@ import { MonsterService } from '../services/monster.service';
|
||||
GameMasterWeaponsTableComponent,
|
||||
GameMasterCharacterActionsDialogComponent,
|
||||
GameMasterMonstersTableComponent,
|
||||
SpellDetailsDialogComponent,
|
||||
],
|
||||
imports: [
|
||||
BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
|
||||
@ -108,6 +110,7 @@ import { MonsterService } from '../services/monster.service';
|
||||
GameMasterMonstersTableComponent,
|
||||
AbilitiesComponent,
|
||||
GameMasterCharacterActionsDialogComponent,
|
||||
SpellDetailsDialogComponent,
|
||||
],
|
||||
})
|
||||
export class AppModule {}
|
||||
|
@ -27,7 +27,7 @@
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;" (click)="ShowSpellDetailsDialog(row.id)"></tr>
|
||||
|
||||
<tr class="mat-row" *matNoDataRow>
|
||||
<td class="mat-cell" colspan="4">No data matching the filter "{{input.value}}"</td>
|
||||
|
@ -7,6 +7,8 @@ import { SpellService } from '../../../services/spell.service';
|
||||
import { first } from 'rxjs/operators';
|
||||
import { ErrorResponse } from '../../../types/ErrorResponse';
|
||||
import { HttpErrorResponse } from '@angular/common/http';
|
||||
import { MatDialog } from '@angular/material';
|
||||
import { SpellDetailsDialogComponent } from '../spell-details-dialog/spell-details-dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-game-master-spells-table',
|
||||
@ -20,7 +22,7 @@ export class GameMasterSpellsTableComponent implements OnInit {
|
||||
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
||||
@ViewChild(MatSort, { static: true }) sort: MatSort;
|
||||
|
||||
constructor(private spellService: SpellService) {
|
||||
constructor(private spellService: SpellService, public dialog: MatDialog) {
|
||||
spellService
|
||||
.GetAllSpells()
|
||||
.pipe(first())
|
||||
@ -49,4 +51,9 @@ export class GameMasterSpellsTableComponent implements OnInit {
|
||||
this.dataSource.paginator.firstPage();
|
||||
}
|
||||
}
|
||||
|
||||
ShowSpellDetailsDialog(spellId: number) {
|
||||
let spell = this.dataSource.data.find((e) => e.id == spellId);
|
||||
this.dialog.open(SpellDetailsDialogComponent, { data: { spell: spell } });
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
.spell-card-flag {
|
||||
clip-path: polygon(100% 0, 100% 80%, 50% 100%, 0 80%, 0 0);
|
||||
width: 70px;
|
||||
height: 150px;
|
||||
}
|
||||
.shadow-for-flag {
|
||||
right: 5%;
|
||||
position: absolute;
|
||||
filter: drop-shadow(0px 0px 3px white);
|
||||
}
|
||||
.names-on-flag {
|
||||
height: 18px;
|
||||
font-size: 15px !important;
|
||||
text-align: center;
|
||||
}
|
||||
::ng-deep mat-dialog-container {
|
||||
padding: 0 !important;
|
||||
}
|
||||
::ng-deep mat-card {
|
||||
padding: 0 !important;
|
||||
}
|
||||
mat-icon {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.spell-details-card {
|
||||
color: whitesmoke;
|
||||
background-color: lightgray;
|
||||
max-width: 600px;
|
||||
}
|
||||
.spell-details-card > mat-card-header {
|
||||
background-color: #3d4751;
|
||||
}
|
||||
.spell-details-card > mat-card-content {
|
||||
background-color: #4f5c69;
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
<mat-card class="spell-details-card">
|
||||
<mat-card-header>
|
||||
<div style="margin-top: 10px">
|
||||
<mat-card-title>{{spell.name}}</mat-card-title>
|
||||
</div>
|
||||
<div class="shadow-for-flag">
|
||||
<div class="spell-card-flag" [ngStyle]="{backgroundColor: spellFlagBackgroundColor}">
|
||||
<div *ngFor="let elem of spell.classes" class="names-on-flag">{{elem}}</div>
|
||||
<div *ngFor="let elem of spell.subclasses" class="names-on-flag">{{elem}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-header>
|
||||
<mat-card-content style="padding-left: 10px; padding-right: 10px;overflow-y: auto; max-height: 600px;-ms-overflow-style: none; scrollbar-width: none;">
|
||||
<br/>
|
||||
<div style="font-style: italic;">{{GetSpellLevelAndSchool()}}</div>
|
||||
<hr />
|
||||
<div>
|
||||
<mat-icon inline style="font-size: 16px;" color="white">history_toggle_off</mat-icon> Casting Time: {{spellDictionary.GetCastingTime(spell.castingTime)}}
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon inline style="font-size: 16px;" color="white"><i class="ra ra-archery-target"></i></mat-icon> Range: {{spellDictionary.GetRange(spell.range)}}
|
||||
</div>
|
||||
<div>
|
||||
<mat-icon inline style="font-size: 16px;" color="white">hourglass_bottom</mat-icon> Duration: {{spellDictionary.GetDuration(spell.duration)}}
|
||||
</div>
|
||||
<hr />
|
||||
<b>Description:</b>
|
||||
<p style="text-align: justify;">{{GetSpellDescription()}}</p>
|
||||
<div *ngIf="spell.higherLevel.length > 0">
|
||||
<b>At Higher Levels:</b>
|
||||
<p style="text-align: justify;">{{GetSpellAtHigherLevels()}}</p>
|
||||
</div>
|
||||
<hr />
|
||||
<div *ngIf="spell.components.length > 0">
|
||||
<table style="border-spacing: 10px 0; border-collapse: unset">
|
||||
<tr>
|
||||
<td *ngIf="spell.components.includes('V')" style="text-align: center;"><mat-icon style="font-size: 34px; width: 34px; height: 34px">volume_up</mat-icon></td>
|
||||
<td *ngIf="spell.components.includes('S')" style="text-align: center;"><mat-icon style="font-size: 34px; width: 34px; height: 34px">gesture</mat-icon></td>
|
||||
<td *ngIf="spell.components.includes('M')" style="text-align: center;" [matTooltip]="spell.material"><mat-icon style="font-size: 34px; width: 34px; height: 34px">extension</mat-icon></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td *ngIf="spell.components.includes('V')">Verbal</td>
|
||||
<td *ngIf="spell.components.includes('S')">Somatic</td>
|
||||
<td *ngIf="spell.components.includes('M')">Material</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
@ -0,0 +1,96 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
|
||||
import { SpellViewModel } from '../../../types/viewmodels/spell-viewmodels/SpellViewModel';
|
||||
import SpellDictionary from '../../shared/dictionaries/SpellDictionary';
|
||||
|
||||
@Component({
|
||||
selector: 'app-spell-details-dialog',
|
||||
templateUrl: './spell-details-dialog.component.html',
|
||||
styleUrls: ['./spell-details-dialog.component.css'],
|
||||
})
|
||||
export class SpellDetailsDialogComponent implements OnInit {
|
||||
spell: SpellViewModel;
|
||||
spellFlagBackgroundColor: string;
|
||||
spellDictionary = SpellDictionary;
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<SpellDetailsDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.spell = this.data.spell;
|
||||
this.ChangeFlagColor();
|
||||
}
|
||||
|
||||
GetSpellDescription() {
|
||||
let result = '';
|
||||
for (let elem of this.spell.descriptions) {
|
||||
result += elem;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
GetSpellAtHigherLevels() {
|
||||
let result = '';
|
||||
for (let elem of this.spell.higherLevel) {
|
||||
result += elem;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
GetSpellLevelAndSchool() {
|
||||
let result = '';
|
||||
if (this.spell.level == -1) {
|
||||
result += this.spell.school + ' Cantrip';
|
||||
} else {
|
||||
result += this.spell.level + ' st level ' + this.spell.school;
|
||||
}
|
||||
|
||||
if (this.spell.ritual) {
|
||||
result += ' (ritual)';
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ChangeFlagColor() {
|
||||
switch (this.spell.school) {
|
||||
case 'Evocation': {
|
||||
this.spellFlagBackgroundColor = '#7c081e';
|
||||
break;
|
||||
}
|
||||
case 'Conjuration': {
|
||||
this.spellFlagBackgroundColor = '#335f96';
|
||||
break;
|
||||
}
|
||||
case 'Abjuration': {
|
||||
this.spellFlagBackgroundColor = '#bab725';
|
||||
break;
|
||||
}
|
||||
case 'Transmutation': {
|
||||
this.spellFlagBackgroundColor = '#875a2d';
|
||||
break;
|
||||
}
|
||||
case 'Enchantment': {
|
||||
this.spellFlagBackgroundColor = '#479636';
|
||||
break;
|
||||
}
|
||||
case 'Necromancy': {
|
||||
this.spellFlagBackgroundColor = '#444444';
|
||||
break;
|
||||
}
|
||||
case 'Divination': {
|
||||
this.spellFlagBackgroundColor = '#a1a3a3';
|
||||
break;
|
||||
}
|
||||
case 'Illusion': {
|
||||
this.spellFlagBackgroundColor = '#652d84';
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
this.spellFlagBackgroundColor = '#212b87';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
const Ranges: { [key: string]: string } = {
|
||||
Self: 'Self',
|
||||
Touch: 'Touch',
|
||||
Special: 'Special',
|
||||
Sight: 'Slight',
|
||||
Unlimited: 'Unlimited',
|
||||
Feet_5: '5 Feet',
|
||||
Feet_10: '10 Feet',
|
||||
Feet_30: '30 Feet',
|
||||
Feet_60: '60 Feet',
|
||||
Feet_90: '90 Feet',
|
||||
Feet_100: '100 Feet',
|
||||
Feet_120: '120 Feet',
|
||||
Feet_150: '150 Feet',
|
||||
Feet_300: '300 Feet',
|
||||
Feet_500: '500 Feet',
|
||||
Miles_1: '1 Mile',
|
||||
Miles_500: '500 Miles',
|
||||
};
|
||||
|
||||
const Durations: { [key: string]: string } = {
|
||||
Instantaneous: 'Instantaneous',
|
||||
Until_dispelled: 'Until dispeled',
|
||||
Special: 'Special',
|
||||
Minutes_1: '1 Minute',
|
||||
Minutes_10: '10 Minutes',
|
||||
Hours_1: '1 Hour',
|
||||
Hours_2: '2 Hours',
|
||||
Hours_8: '8 Hours',
|
||||
Hours_24: '24 Hours',
|
||||
Days_7: '7 Days',
|
||||
Days_10: '10 Days',
|
||||
Days_30: '30 Days',
|
||||
Round_1: '1 Round',
|
||||
};
|
||||
|
||||
const CastingTimes: { [key: string]: string } = {
|
||||
Minutes_1: '1 Minute',
|
||||
Minutes_10: '10 Minutes',
|
||||
Hours_1: '1 Hour',
|
||||
Hours_8: '8 Hours',
|
||||
Hours_12: '12 Hours',
|
||||
Hours_24: '24 Hours',
|
||||
Action_1: '1 Action',
|
||||
Reaction_1: '1 Reaction',
|
||||
Bonus_Action_1: '1 Bonus Action',
|
||||
};
|
||||
|
||||
export default new (class SpellDictionary {
|
||||
GetRange(name: string) {
|
||||
return Ranges[name];
|
||||
}
|
||||
GetDuration(name: string) {
|
||||
return Durations[name];
|
||||
}
|
||||
GetCastingTime(name: string) {
|
||||
return CastingTimes[name];
|
||||
}
|
||||
})();
|
Loading…
Reference in New Issue
Block a user