SES-147 throw dialogs - player #77
@ -44,6 +44,8 @@ import { SpellService } from '../services/spell.service';
|
|||||||
import { WeaponService } from '../services/weapon.service';
|
import { WeaponService } from '../services/weapon.service';
|
||||||
import { ArmorService } from '../services/armor.service';
|
import { ArmorService } from '../services/armor.service';
|
||||||
import { OtherEquipmentService } from '../services/other-equipment.service';
|
import { OtherEquipmentService } from '../services/other-equipment.service';
|
||||||
|
import { ThrowPrimaryAbilityComponent } from './components/throws/throw-primary-ability/throw-primary-ability.component';
|
||||||
|
import { MatRadioModule } from '@angular/material/radio';
|
||||||
import { GameMasterMonstersTableComponent } from './components/game-master-monsters-table/game-master-monsters-table.component';
|
import { GameMasterMonstersTableComponent } from './components/game-master-monsters-table/game-master-monsters-table.component';
|
||||||
import { MonsterService } from '../services/monster.service';
|
import { MonsterService } from '../services/monster.service';
|
||||||
import { SpellDetailsDialogComponent } from './components/spell-details-dialog/spell-details-dialog.component';
|
import { SpellDetailsDialogComponent } from './components/spell-details-dialog/spell-details-dialog.component';
|
||||||
@ -64,6 +66,7 @@ import { GameMasterShopkeepersTableComponent } from './components/game-master-sh
|
|||||||
GameMasterArmorsTableComponent,
|
GameMasterArmorsTableComponent,
|
||||||
GameMasterWeaponsTableComponent,
|
GameMasterWeaponsTableComponent,
|
||||||
GameMasterCharacterActionsDialogComponent,
|
GameMasterCharacterActionsDialogComponent,
|
||||||
|
ThrowPrimaryAbilityComponent,
|
||||||
GameMasterMonstersTableComponent,
|
GameMasterMonstersTableComponent,
|
||||||
SpellDetailsDialogComponent,
|
SpellDetailsDialogComponent,
|
||||||
GameMasterShopkeepersTableComponent,
|
GameMasterShopkeepersTableComponent,
|
||||||
@ -94,6 +97,7 @@ import { GameMasterShopkeepersTableComponent } from './components/game-master-sh
|
|||||||
MatTableModule,
|
MatTableModule,
|
||||||
MatSortModule,
|
MatSortModule,
|
||||||
MatTooltipModule,
|
MatTooltipModule,
|
||||||
|
MatRadioModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
UserService,
|
UserService,
|
||||||
@ -112,6 +116,7 @@ import { GameMasterShopkeepersTableComponent } from './components/game-master-sh
|
|||||||
GameMasterMonstersTableComponent,
|
GameMasterMonstersTableComponent,
|
||||||
AbilitiesComponent,
|
AbilitiesComponent,
|
||||||
GameMasterCharacterActionsDialogComponent,
|
GameMasterCharacterActionsDialogComponent,
|
||||||
|
ThrowPrimaryAbilityComponent,
|
||||||
SpellDetailsDialogComponent,
|
SpellDetailsDialogComponent,
|
||||||
GameMasterShopkeepersTableComponent,
|
GameMasterShopkeepersTableComponent,
|
||||||
],
|
],
|
||||||
|
@ -19,7 +19,13 @@
|
|||||||
padding-bottom: 15px;
|
padding-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 468px) {
|
@media (max-width: 365px) {
|
||||||
|
#main {
|
||||||
|
width: 315px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 365px) and (max-width: 468px) {
|
||||||
#main {
|
#main {
|
||||||
width: 340px;
|
width: 340px;
|
||||||
}
|
}
|
||||||
@ -27,7 +33,7 @@
|
|||||||
|
|
||||||
@media (min-width: 468px) and (max-width: 768px) {
|
@media (min-width: 468px) and (max-width: 768px) {
|
||||||
#main {
|
#main {
|
||||||
width: 420px;
|
width: 410px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
<div *ngIf="ability" id="main">
|
<div *ngIf="ability" id="main">
|
||||||
<mat-card [style.border-color]="headStyle.bgColor" [style.color]="headStyle.bgColor" class="cardContainerClass">
|
<mat-card [style.border-color]="headStyle.bgColor" [style.color]="headStyle.bgColor" class="cardContainerClass">
|
||||||
<mat-card-header id="ability-card-header" [style.background]="headStyle.bgColor" [style.color]="headStyle.textColor">
|
<mat-card-header id="ability-card-header" [style.background]="headStyle.bgColor" [style.color]="headStyle.textColor">
|
||||||
<div id="ability-value">{{ability.value}}</div>
|
<div matTooltip="Click to roll the {{ability.name}}" id="ability-value" (click)="OpenThrowDialog(ability.name, ability.value, ability.modification)">{{ability.value}}</div>
|
||||||
<div class="diagonal-line"></div>
|
<div class="diagonal-line"></div>
|
||||||
Mod: {{ability.modification > 0? '+' + ability.modification : + ability.modification}}
|
Mod: {{ability.modification > 0? '+' + ability.modification : + ability.modification}}
|
||||||
<div class="diagonal-line"></div>
|
<div class="diagonal-line"></div>
|
||||||
{{ability.name}}
|
{{ability.name}}
|
||||||
<div *ngIf="ability.canSaveThrows" class="diagonal-line" style="margin-left: auto"></div>
|
<div *ngIf="ability.canSaveThrows" class="diagonal-line" style="margin-left: auto"></div>
|
||||||
<div *ngIf="ability.canSaveThrows" style="margin-right: 10px">
|
<div *ngIf="ability.canSaveThrows" style="margin-right: 10px">
|
||||||
<div id="ability-saving-throws">ST: {{ability.savingThrows > 0? '+' + ability.savingThrows : ability.savingThrows}}</div>
|
<div (click)="OpenThrowDialog('Saving Throw', null, ability.savingThrows)" matTooltip="Click to do the Saving Throw" id="ability-saving-throws">ST: {{ability.savingThrows > 0? '+' + ability.savingThrows : ability.savingThrows}}</div>
|
||||||
</div>
|
</div>
|
||||||
</mat-card-header>
|
</mat-card-header>
|
||||||
<mat-divider [style.border-top-color]="'black'"></mat-divider>
|
<mat-divider [style.border-top-color]="'black'"></mat-divider>
|
||||||
<mat-card-content id="ability-card-content" [style.background]="contentStyle.bgColor" [style.color]="contentStyle.textColor">
|
<mat-card-content id="ability-card-content" [style.background]="contentStyle.bgColor" [style.color]="contentStyle.textColor">
|
||||||
<a [style.border-color]="headStyle.bgColor" mat-stroked-button *ngFor="let skill of ability.skills" id="skill-btn">
|
<a (click)="OpenThrowDialog(skill.name, null, skill.value)" matTooltip="Click to roll the {{skill.name}}" [style.border-color]="headStyle.bgColor" mat-stroked-button *ngFor="let skill of ability.skills" id="skill-btn">
|
||||||
{{skill.name}}
|
{{skill.name}}
|
||||||
|
|
||||||
<span [style.border-left-color]="headStyle.bgColor" id="skill-btn-divider"></span>
|
<span [style.border-left-color]="headStyle.bgColor" id="skill-btn-divider"></span>
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import {CharacterStatsViewModel} from '../../../types/viewmodels/character-viewmodels/CharacterStatsViewModel';
|
import { CharacterStatsViewModel } from '../../../types/viewmodels/character-viewmodels/CharacterStatsViewModel';
|
||||||
|
import { ThrowPrimaryAbilityComponent } from '../throws/throw-primary-ability/throw-primary-ability.component';
|
||||||
|
import { MatDialog } from '@angular/material';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-ability-card',
|
selector: 'app-ability-card',
|
||||||
@ -11,7 +13,8 @@ export class AbilityCardComponent implements OnInit {
|
|||||||
@Input() headStyle: { bgColor: string; textColor: string };
|
@Input() headStyle: { bgColor: string; textColor: string };
|
||||||
@Input() contentStyle: { bgColor: string; textColor: string };
|
@Input() contentStyle: { bgColor: string; textColor: string };
|
||||||
|
|
||||||
constructor() {}
|
constructor(public dialog: MatDialog) {
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (this.ability.skills != null) {
|
if (this.ability.skills != null) {
|
||||||
@ -42,4 +45,15 @@ export class AbilityCardComponent implements OnInit {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OpenThrowDialog(abilityName: string, abilityValue: number, abilityMod: number): void {
|
||||||
|
this.dialog.open(ThrowPrimaryAbilityComponent, {
|
||||||
|
data: {
|
||||||
|
abilityName: abilityName,
|
||||||
|
abilityValue: abilityValue,
|
||||||
|
abilityMod: abilityMod,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
@import "../../../styles.css";
|
@import "../../../styles.css";
|
||||||
|
|
||||||
|
.toggle-class{
|
||||||
|
margin: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.menu-spacer {
|
.menu-spacer {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
@ -37,7 +41,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ability_card_container {
|
.ability_card_container {
|
||||||
margin: 5%;
|
margin: 2%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -0,0 +1,167 @@
|
|||||||
|
.throw-container {
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-button {
|
||||||
|
padding: 3%;
|
||||||
|
border: 1px #e9cca7 solid;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-bottom: 5%;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-button:hover {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
::ng-deep.mat-dialog-container {
|
||||||
|
background-color: #102028;
|
||||||
|
color: whitesmoke;
|
||||||
|
box-shadow: -1px 3px 48px 23px rgba(0,0,0,0.82);
|
||||||
|
}
|
||||||
|
.header-throw-dialog {
|
||||||
|
color: orange;
|
||||||
|
background-color: #102028;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-throw-dialog {
|
||||||
|
background-color: #102028;
|
||||||
|
color: orange;
|
||||||
|
height: 400px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.throw-dialog-actions {
|
||||||
|
background-color: #102028;
|
||||||
|
color: orange;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-dialog:hover {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
#radio-group-label-class {
|
||||||
|
margin-bottom: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-divider--custom-style{
|
||||||
|
background-color: #9e8b6e;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
box-shadow: 0 1px 0 0 #d8d8d8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.score-result {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
height: 180px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
text-align: center;
|
||||||
|
align-items: center
|
||||||
|
}
|
||||||
|
|
||||||
|
.score-result>* {
|
||||||
|
flex: 1 1 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box {
|
||||||
|
padding: 2px;
|
||||||
|
width: 165px;
|
||||||
|
height: 85px;
|
||||||
|
world-wrap: break-word;
|
||||||
|
border: 1px #e9cca7 solid;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box--ability {
|
||||||
|
paddin-top: 25px;
|
||||||
|
padding-left: 2px;
|
||||||
|
padding-right: 2px;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
height: 170px;
|
||||||
|
width: 165px;
|
||||||
|
world-wrap: break-word;
|
||||||
|
border: 1px #e9cca7 solid;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box--ability > div {
|
||||||
|
padding-top: 40%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 365px) {
|
||||||
|
.content-throw-dialog {
|
||||||
|
height: 350px;
|
||||||
|
}
|
||||||
|
.radio-button {
|
||||||
|
padding: 5%;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
#main {
|
||||||
|
width: 320px;
|
||||||
|
}
|
||||||
|
.score-result {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.box {
|
||||||
|
width: 100px;
|
||||||
|
height: 85px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box--ability {
|
||||||
|
height: 170px;
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 365px) and (max-width: 468px) {
|
||||||
|
#main {
|
||||||
|
width: 340px;
|
||||||
|
}
|
||||||
|
.score-result {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
.box {
|
||||||
|
width: 110px;
|
||||||
|
height: 85px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box--ability {
|
||||||
|
height: 170px;
|
||||||
|
width: 110px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 468px) and (max-width: 768px) {
|
||||||
|
#main {
|
||||||
|
width: 410px;
|
||||||
|
}
|
||||||
|
.score-result {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
.box {
|
||||||
|
width: 120px;
|
||||||
|
height: 85px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box--ability {
|
||||||
|
height: 170px;
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
#main {
|
||||||
|
width: 480px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
|||||||
|
<div class="throw-container">
|
||||||
|
<div mat-dialog-title class="header-throw-dialog">
|
||||||
|
Click to roll the {{abilityName}}
|
||||||
|
</div>
|
||||||
|
<mat-divider class="mat-divider--custom-style"></mat-divider>
|
||||||
|
<div mat-dialog-content class="content-throw-dialog">
|
||||||
|
<label id="radio-group-label-class">Choose which type of throw you are interested in:</label>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
|
||||||
|
<mat-radio-group
|
||||||
|
aria-labelledby="radio-group-label-class"
|
||||||
|
class="radio-group"
|
||||||
|
[(ngModel)]="choosedThrow">
|
||||||
|
|
||||||
|
<mat-radio-button name="normal" type="submit" (click)="getResultOfRoll('normal')" class="radio-button">
|
||||||
|
Normal throw on ability
|
||||||
|
</mat-radio-button>
|
||||||
|
<mat-radio-button name="hidden" type="submit" (click)="getResultOfRoll('hidden')" class="radio-button">
|
||||||
|
Hidden throw for Game Master
|
||||||
|
</mat-radio-button>
|
||||||
|
</mat-radio-group>
|
||||||
|
|
||||||
|
<div *ngIf="showSendToGMMessage" class="score-result">
|
||||||
|
Your score has been send to Game Master
|
||||||
|
</div>
|
||||||
|
<div class="score-result">
|
||||||
|
<div class="box" *ngIf="score">Your roll result is: <p>{{score}}</p></div>
|
||||||
|
<div class="box" *ngIf="score" >Your roll with modification is: <p>{{score+abilityMod}}</p></div>
|
||||||
|
<div class="box--ability" *ngIf="score && abilityValue">
|
||||||
|
<div>
|
||||||
|
Ability value: <p>{{abilityValue}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<mat-divider class="mat-divider--custom-style"></mat-divider>
|
||||||
|
<div mat-dialog-actions class="throw-dialog-actions">
|
||||||
|
<button mat-button [mat-dialog-close] class="button-dialog">Close dialog</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ThrowPrimaryAbilityComponent } from './throw-primary-ability.component';
|
||||||
|
|
||||||
|
describe('ThrowPrimaryAbilityComponent', () => {
|
||||||
|
let component: ThrowPrimaryAbilityComponent;
|
||||||
|
let fixture: ComponentFixture<ThrowPrimaryAbilityComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ThrowPrimaryAbilityComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ThrowPrimaryAbilityComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,52 @@
|
|||||||
|
import {Component, Inject, Input, OnInit} from '@angular/core';
|
||||||
|
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
|
||||||
|
import { AbilitiesComponent } from '../../abilities/abilities.component';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-throw-primary-ability',
|
||||||
|
templateUrl: './throw-primary-ability.component.html',
|
||||||
|
styleUrls: ['./throw-primary-ability.component.css']
|
||||||
|
})
|
||||||
|
export class ThrowPrimaryAbilityComponent implements OnInit {
|
||||||
|
score: number;
|
||||||
|
checked = false;
|
||||||
|
choosedThrow: string;
|
||||||
|
throws: string[] = [`Normal throw on ability`, 'Hidden throw for Game Master'];
|
||||||
|
showSendToGMMessage: boolean;
|
||||||
|
|
||||||
|
@Input() abilityName: string;
|
||||||
|
@Input() abilityValue: number;
|
||||||
|
@Input() abilityMod: number;
|
||||||
|
@Input() message: string;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<AbilitiesComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any
|
||||||
|
) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.abilityName = this.data.abilityName;
|
||||||
|
this.abilityValue = this.data.abilityValue;
|
||||||
|
this.abilityMod = this.data.abilityMod;
|
||||||
|
}
|
||||||
|
|
||||||
|
getRandomNumberBetween(min, max) {
|
||||||
|
min = Math.ceil(min);
|
||||||
|
max = Math.floor(max);
|
||||||
|
return Math.floor(Math.random() * (max - min)) + min;
|
||||||
|
}
|
||||||
|
|
||||||
|
getResultOfRoll(choice: string) {
|
||||||
|
switch (choice) {
|
||||||
|
case 'normal':
|
||||||
|
this.score = this.getRandomNumberBetween(1, 20);
|
||||||
|
this.showSendToGMMessage = false;
|
||||||
|
break;
|
||||||
|
case 'hidden':
|
||||||
|
this.score = null;
|
||||||
|
this.showSendToGMMessage = true;
|
||||||
|
//TODO tutaj bedzie wyslanie rzutu do GM
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user