Optmize
This commit is contained in:
parent
2ef9968920
commit
f30c41afba
@ -20,7 +20,7 @@ export interface LoginTokenViewModel {
|
|||||||
avatarImage: string;
|
avatarImage: string;
|
||||||
role: Role;
|
role: Role;
|
||||||
cellGroup: PastoralDomain;
|
cellGroup: PastoralDomain;
|
||||||
signalRSessionId;
|
signalRConnectionId;
|
||||||
sessionTabId: string;
|
sessionTabId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@ export interface IGamePlayer {
|
|||||||
isPlayer: boolean;
|
isPlayer: boolean;
|
||||||
signalRClientId: string;
|
signalRClientId: string;
|
||||||
tabId: string;
|
tabId: string;
|
||||||
|
isDisconnected: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GamePlayer implements IGamePlayer {
|
export class GamePlayer implements IGamePlayer {
|
||||||
@ -14,4 +15,5 @@ export class GamePlayer implements IGamePlayer {
|
|||||||
isPlayer: boolean;
|
isPlayer: boolean;
|
||||||
signalRClientId: string;
|
signalRClientId: string;
|
||||||
tabId: string;
|
tabId: string;
|
||||||
|
isDisconnected: boolean;
|
||||||
}
|
}
|
||||||
@ -8,6 +8,7 @@ import { StateService } from "../../services/state.service";
|
|||||||
import { ADIcon, MessageBoxConfig } from "../../ui/alert-dlg/alert-dlg.model";
|
import { ADIcon, MessageBoxConfig } from "../../ui/alert-dlg/alert-dlg.model";
|
||||||
import { MD2HeroInfo, MD2Icon, MobInfo, RoundPhase } from "./massive-darkness2.model";
|
import { MD2HeroInfo, MD2Icon, MobInfo, RoundPhase } from "./massive-darkness2.model";
|
||||||
import { LoginUserService } from "../../services/login-user.service";
|
import { LoginUserService } from "../../services/login-user.service";
|
||||||
|
import { GamePlayer } from "../games.model";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export abstract class MD2Base {
|
export abstract class MD2Base {
|
||||||
@ -59,14 +60,14 @@ export abstract class MD2Base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
imgUrl(imgPath: string) {
|
imgUrl(imgPath: string) {
|
||||||
return this.md2Service.stateService.imgUrl(imgPath);
|
return this.md2Service.imgUrl(imgPath);
|
||||||
}
|
}
|
||||||
fileList(folderPath: string) {
|
fileList(folderPath: string) {
|
||||||
return this.md2Service.fileList(folderPath);
|
return this.md2Service.fileList(folderPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
iconHtml(icon: MD2Icon, cssClass = '') {
|
iconHtml(icon: MD2Icon, cssClass = '') {
|
||||||
return this.md2Service.stateService.iconHtml(icon, cssClass);
|
return this.md2Service.iconHtml(icon, cssClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
imgHtml(imgFile: string, cssClass = '') {
|
imgHtml(imgFile: string, cssClass = '') {
|
||||||
@ -82,12 +83,17 @@ export abstract class MD2Base {
|
|||||||
}
|
}
|
||||||
abstract refreshUI();
|
abstract refreshUI();
|
||||||
handleSignalRCallback(message: SignalRMessage): void {
|
handleSignalRCallback(message: SignalRMessage): void {
|
||||||
// if (message.from.isGroup) {
|
if (message.from) {
|
||||||
// if (!this.isHeroDashboard) return;
|
if (message.from.isGroup) {
|
||||||
// } else {
|
if (!this.isHeroDashboard) return;
|
||||||
// if (this.isHeroDashboard && this.md2Service.playerHero.playerInfo.signalRClientId == message.from.sessionId) return;
|
} else {
|
||||||
// }
|
if (this.isHeroDashboard && this.md2Service.playerHero?.playerInfo?.signalRClientId == message.from.connectionId) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.isHeroDashboard) {
|
||||||
|
|
||||||
|
}
|
||||||
switch (message.actionType) {
|
switch (message.actionType) {
|
||||||
case 'hero':
|
case 'hero':
|
||||||
let heroInfo = new MD2HeroInfo(JSON.parse(message.parameters['hero']));
|
let heroInfo = new MD2HeroInfo(JSON.parse(message.parameters['hero']));
|
||||||
@ -101,7 +107,7 @@ export abstract class MD2Base {
|
|||||||
break;
|
break;
|
||||||
case 'updateMyHero':
|
case 'updateMyHero':
|
||||||
if (this.isHeroDashboard) {
|
if (this.isHeroDashboard) {
|
||||||
this.md2Service.stateService.playerHero = heroInfo;
|
this.md2Service.playerHero = heroInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -113,24 +119,42 @@ export abstract class MD2Base {
|
|||||||
case 'heroes':
|
case 'heroes':
|
||||||
switch (message.actionName) {
|
switch (message.actionName) {
|
||||||
case 'updateAll':
|
case 'updateAll':
|
||||||
|
if (this.isHeroDashboard) {
|
||||||
let allHeroes = (JSON.parse(message.parameters['heros']) as MD2HeroInfo[]).map(h => new MD2HeroInfo(h));
|
let allHeroes = (JSON.parse(message.parameters['heros']) as MD2HeroInfo[]).map(h => new MD2HeroInfo(h));
|
||||||
//Remove heroes that are not in the list
|
//Remove heroes that are not in the list
|
||||||
this.md2Service.info.heros = this.md2Service.heros.filter(h => !allHeroes.some(h2 => h2.playerInfo.tabId == h.playerInfo.tabId));
|
this.md2Service.info.heros = this.md2Service.heros.filter(h => allHeroes.some(h2 => h2.playerInfo.tabId == h.playerInfo.tabId));
|
||||||
allHeroes.forEach(heroInfo => {
|
allHeroes.forEach(heroInfo => {
|
||||||
this.updateHeroInfo(heroInfo);
|
this.updateHeroInfo(heroInfo);
|
||||||
});
|
});
|
||||||
|
this.detectChanges();
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'GameRoom':
|
case 'GameRoom':
|
||||||
switch (message.actionName) {
|
switch (message.actionName) {
|
||||||
case 'Leaving':
|
case 'Leaving':
|
||||||
this.md2Service.heros.splice(this.md2Service.heros.findIndex(h => h.playerInfo.tabId == message.from.sessionId));
|
let leavingPlayerInfo = message.value as GamePlayer;
|
||||||
|
let leavingHero = this.md2Service.heros.find(h => h.playerInfo.tabId == leavingPlayerInfo.tabId);
|
||||||
|
if (leavingHero) {
|
||||||
|
leavingHero.playerInfo.isDisconnected = true;
|
||||||
|
}
|
||||||
|
//var disconnectHero = this.md2Service.heros.splice(this.md2Service.heros.findIndex(h => h.playerInfo.signalRClientId == leavingPlayerInfo.signalRClientId));
|
||||||
|
//this.md2Service.info.disconnectedHeroes.push(...disconnectHero);
|
||||||
this.detectChanges();
|
this.detectChanges();
|
||||||
break;
|
break;
|
||||||
case 'update':
|
case 'update':
|
||||||
if (this.isHeroDashboard) {
|
if (this.isHeroDashboard) {
|
||||||
this.md2Service.info = new MD2GameInfo(JSON.parse(message.parameters['gameInfo']) as MD2GameInfo);
|
this.md2Service.info = new MD2GameInfo(JSON.parse(message.parameters['gameInfo']) as MD2GameInfo);
|
||||||
|
let playerHero = this.md2Service.heros.find(h => h.playerInfo.tabId == this.stateService.loginUserService.sessionTabId);
|
||||||
|
if (playerHero) {
|
||||||
|
|
||||||
|
playerHero.playerInfo = this.md2Service.gameRoomService.currentPlayer();
|
||||||
|
playerHero.playerInfo.isDisconnected = false;
|
||||||
|
this.md2Service.playerHero = playerHero;
|
||||||
|
this.md2Service.broadcastMyHeroInfo();
|
||||||
|
}
|
||||||
this.detectChanges();
|
this.detectChanges();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -140,10 +164,17 @@ export abstract class MD2Base {
|
|||||||
this.detectChanges();
|
this.detectChanges();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'getGameInfo':
|
||||||
|
|
||||||
|
if (!this.isHeroDashboard) {
|
||||||
|
|
||||||
|
this.md2Service.broadcastGameInfo();
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'sendJoinInfo':
|
case 'sendJoinInfo':
|
||||||
if (this.isHeroDashboard && this.md2Service.playerHero) {
|
if (this.isHeroDashboard && this.md2Service.playerHero) {
|
||||||
this.md2Service.playerHero.playerInfo.signalRClientId = message.parameters['signalrconnid'];
|
this.md2Service.playerHero.playerInfo.signalRClientId = message.parameters['signalrconnid'];
|
||||||
this.md2Service.broadcastService.broadcastMyHeroInfo();
|
this.md2Service.broadcastMyHeroInfo();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -212,14 +243,15 @@ export abstract class MD2Base {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateHeroInfo(heroInfo: MD2HeroInfo) {
|
updateHeroInfo(heroInfo: MD2HeroInfo) {
|
||||||
let exitingHero = this.md2Service.heros.find(h => h.playerInfo.signalRClientId == heroInfo.playerInfo.signalRClientId);
|
let exitingHero = this.md2Service.heros.find(h => h.playerInfo.tabId == heroInfo.playerInfo.tabId);
|
||||||
if (exitingHero) {
|
if (exitingHero) {
|
||||||
|
//For boss fight, if the hero finished activating, activate the boss
|
||||||
let activateBoss = exitingHero.uiActivating && !heroInfo.uiActivating;
|
let activateBoss = exitingHero.uiActivating && !heroInfo.uiActivating;
|
||||||
|
|
||||||
this.md2Service.heros[this.md2Service.heros.indexOf(exitingHero)] = heroInfo;
|
this.md2Service.heros[this.md2Service.heros.indexOf(exitingHero)] = heroInfo;
|
||||||
//My hero update
|
//My hero update
|
||||||
if (this.isHeroDashboard && this.md2Service.loginUserService.sessionTabId == heroInfo.playerInfo.tabId) {
|
if (this.isHeroDashboard && this.md2Service.loginUserService.sessionTabId == heroInfo.playerInfo.tabId) {
|
||||||
this.md2Service.stateService.playerHero = heroInfo;
|
this.md2Service.playerHero = heroInfo;
|
||||||
}
|
}
|
||||||
if (!this.isHeroDashboard && this.md2Service.info.isBossFight && activateBoss) {
|
if (!this.isHeroDashboard && this.md2Service.info.isBossFight && activateBoss) {
|
||||||
this.md2Service.activateBoss();
|
this.md2Service.activateBoss();
|
||||||
@ -276,14 +308,14 @@ export abstract class MD2ComponentBase {
|
|||||||
this.destroy$.complete();
|
this.destroy$.complete();
|
||||||
}
|
}
|
||||||
imgUrl(imgPath: string) {
|
imgUrl(imgPath: string) {
|
||||||
return this.md2Service.stateService.imgUrl(imgPath);
|
return this.md2Service.imgUrl(imgPath);
|
||||||
}
|
}
|
||||||
fileList(folderPath: string) {
|
fileList(folderPath: string) {
|
||||||
return this.md2Service.fileList(folderPath);
|
return this.md2Service.fileList(folderPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
iconHtml(icon: MD2Icon, cssClass = '') {
|
iconHtml(icon: MD2Icon, cssClass = '') {
|
||||||
return this.md2Service.stateService.iconHtml(icon, cssClass);
|
return this.md2Service.iconHtml(icon, cssClass);
|
||||||
}
|
}
|
||||||
detectChanges() {
|
detectChanges() {
|
||||||
if (!this.cdRef['destroyed']) {
|
if (!this.cdRef['destroyed']) {
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
<div class="col-md-7">
|
<div class="col-md-7">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md">
|
<div class="col-md">
|
||||||
<adj-number-input name="mob{{boss.info.name}}" [(ngModel)]="boss.info.unitRemainHp" minimum="0"
|
<adj-number-input name="mob{{boss.info.name}}" [(ngModel)]="boss.info.hp" minimum="0"
|
||||||
class="mb-3" title="Boss HP" (hitMinimum)="WIN()">
|
class="mb-3" title="Boss HP" (hitMinimum)="WIN()">
|
||||||
</adj-number-input>
|
</adj-number-input>
|
||||||
<md2-mob-attack-info [mob]="boss.info">
|
<md2-mob-attack-info [mob]="boss.info">
|
||||||
|
|||||||
@ -52,7 +52,11 @@ export class BossFightComponent extends MD2ComponentBase {
|
|||||||
this.boss.activating();
|
this.boss.activating();
|
||||||
}
|
}
|
||||||
WIN() {
|
WIN() {
|
||||||
|
this.msgBoxService.show('Win', { text: 'You Win the Boss Fight', icon: ADIcon.INFO });
|
||||||
|
this.md2Service.info.isBossFight = false;
|
||||||
|
this.md2Service.info.boss = undefined;
|
||||||
|
this.md2Service.heros.forEach(h => h.uiBossFight = false);
|
||||||
|
this.md2Service.broadcastGameInfo();
|
||||||
}
|
}
|
||||||
attack(mob: MobInfo) {
|
attack(mob: MobInfo) {
|
||||||
|
|
||||||
@ -62,6 +66,9 @@ export class BossFightComponent extends MD2ComponentBase {
|
|||||||
let attackDamage = mobResult.uiWounds;
|
let attackDamage = mobResult.uiWounds;
|
||||||
if (attackDamage) {
|
if (attackDamage) {
|
||||||
this.boss.info.hp -= attackDamage;
|
this.boss.info.hp -= attackDamage;
|
||||||
|
if (this.boss.info.hp <= 0) {
|
||||||
|
this.WIN();
|
||||||
|
}
|
||||||
this.cdRef.detectChanges();
|
this.cdRef.detectChanges();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -139,7 +139,7 @@
|
|||||||
<!-- <img class="MD2HeroCard " src="{{imgUrl('Heros/'+className+'.jpg')}}" (click)="toggleFlip()"> -->
|
<!-- <img class="MD2HeroCard " src="{{imgUrl('Heros/'+className+'.jpg')}}" (click)="toggleFlip()"> -->
|
||||||
|
|
||||||
<!-- Action Buttons (Desktop/Landscape) -->
|
<!-- Action Buttons (Desktop/Landscape) -->
|
||||||
<div class="hero-actions d-none d-sm-block">
|
<div class="hero-actions d-block">
|
||||||
<div class="action-buttons-group" *ngIf="hero.uiActivating && hero.remainActions > 0">
|
<div class="action-buttons-group" *ngIf="hero.uiActivating && hero.remainActions > 0">
|
||||||
<button nbButton hero class="action-btn" status="info" (click)="moveAction()"
|
<button nbButton hero class="action-btn" status="info" (click)="moveAction()"
|
||||||
*ngIf="!showMoveAction">
|
*ngIf="!showMoveAction">
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import { DebounceTimer } from '../../../utilities/timer-utils';
|
|||||||
import { HeroClass, MD2HeroInfo, MD2HeroProfile, MD2Icon } from '../massive-darkness2.model';
|
import { HeroClass, MD2HeroInfo, MD2HeroProfile, MD2Icon } from '../massive-darkness2.model';
|
||||||
import { MD2Base } from '../MD2Base';
|
import { MD2Base } from '../MD2Base';
|
||||||
import { MD2HeroProfileService } from '../service/massive-darkness2.service';
|
import { MD2HeroProfileService } from '../service/massive-darkness2.service';
|
||||||
|
import { SignalRService } from '../../../services/signal-r.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ngx-hero-dashboard',
|
selector: 'ngx-hero-dashboard',
|
||||||
@ -70,6 +71,15 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
|||||||
return this.md2Service.playerHero;
|
return this.md2Service.playerHero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get className() {
|
||||||
|
if (this.md2Service.playerHero) {
|
||||||
|
return HeroClass[this.md2Service.playerHero.class];
|
||||||
|
}
|
||||||
|
if (this.selectedHeroClass) {
|
||||||
|
return HeroClass[this.selectedHeroClass];
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
public get currentSelectingHero(): MD2HeroInfo {
|
public get currentSelectingHero(): MD2HeroInfo {
|
||||||
return this.heros[this.currentHeroIndex];
|
return this.heros[this.currentHeroIndex];
|
||||||
}
|
}
|
||||||
@ -82,6 +92,7 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
|||||||
protected route: ActivatedRoute,
|
protected route: ActivatedRoute,
|
||||||
protected cdRef: ChangeDetectorRef,
|
protected cdRef: ChangeDetectorRef,
|
||||||
private msgBoxService: MsgBoxService,
|
private msgBoxService: MsgBoxService,
|
||||||
|
private signalRService: SignalRService
|
||||||
) {
|
) {
|
||||||
super(md2Service, stateService, route, cdRef);
|
super(md2Service, stateService, route, cdRef);
|
||||||
this.isHeroDashboard = true;
|
this.isHeroDashboard = true;
|
||||||
@ -93,6 +104,15 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
|||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
super.ngOnInit();
|
super.ngOnInit();
|
||||||
|
|
||||||
|
this.gameRoomService.gameRoomId = this.roomId;
|
||||||
|
this.gameRoomService.joinGameRoom(this.roomId);
|
||||||
|
//this.fetchGameInfo();
|
||||||
|
this.signalRService.signalRMessageConnSubject.subscribe(state => {
|
||||||
|
if (state.status == 'connected') {
|
||||||
|
this.fetchGameInfo();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override signalRInitialized() {
|
override signalRInitialized() {
|
||||||
@ -103,9 +123,7 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
initHero() {
|
initHero() {
|
||||||
this.gameRoomService.gameRoomId = this.roomId;
|
if (!this.md2Service.heros.some(h => h.playerInfo.signalRClientId == this.stateService.loginUserService.userAccess.signalRConnectionId)) {
|
||||||
this.gameRoomService.joinGameRoom(this.roomId);
|
|
||||||
if (!this.md2Service.heros.some(h => h.playerInfo.signalRClientId == this.stateService.loginUserService.userAccess.signalRSessionId)) {
|
|
||||||
|
|
||||||
this.msgBoxService.showInputbox('Select Hero Class', '', { dropDownOptions: this.classOptions, inputType: 'dropdown' })
|
this.msgBoxService.showInputbox('Select Hero Class', '', { dropDownOptions: this.classOptions, inputType: 'dropdown' })
|
||||||
.pipe(first()).subscribe(heroClass => {
|
.pipe(first()).subscribe(heroClass => {
|
||||||
@ -127,10 +145,11 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
className: string;
|
|
||||||
|
|
||||||
|
|
||||||
initClassHeroList(heroClass: HeroClass) {
|
initClassHeroList(heroClass: HeroClass) {
|
||||||
this.heros = [];
|
this.heros = [];
|
||||||
this.className = HeroClass[heroClass];
|
|
||||||
this.selectedHeroClass = heroClass;
|
this.selectedHeroClass = heroClass;
|
||||||
this.heroProfileService.getAll().pipe(first()).subscribe(result => {
|
this.heroProfileService.getAll().pipe(first()).subscribe(result => {
|
||||||
|
|
||||||
@ -161,7 +180,7 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
|||||||
selectCurrentHero() {
|
selectCurrentHero() {
|
||||||
if (this.currentSelectingHero) {
|
if (this.currentSelectingHero) {
|
||||||
this.md2Service.playerJoin(this.currentSelectingHero);
|
this.md2Service.playerJoin(this.currentSelectingHero);
|
||||||
this.md2Service.broadcastService.broadcastMyHeroInfo();
|
this.md2Service.broadcastMyHeroInfo();
|
||||||
this.isSelectingHero = false;
|
this.isSelectingHero = false;
|
||||||
this.detectChanges();
|
this.detectChanges();
|
||||||
}
|
}
|
||||||
@ -189,8 +208,12 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
|||||||
this.detectChanges();
|
this.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fetchGameInfo() {
|
||||||
|
this.md2Service.broadcastFetchGameInfo();
|
||||||
|
}
|
||||||
|
|
||||||
broadcastHeroInfo() {
|
broadcastHeroInfo() {
|
||||||
this.md2Service.broadcastService.broadcastMyHeroInfo();
|
this.md2Service.broadcastMyHeroInfo();
|
||||||
this.heroUpdateDebounceTimer.clearOut();
|
this.heroUpdateDebounceTimer.clearOut();
|
||||||
}
|
}
|
||||||
increaseRage() {
|
increaseRage() {
|
||||||
@ -199,7 +222,7 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
openDoor() {
|
openDoor() {
|
||||||
this.md2Service.broadcastService.broadcastHeroAction('openDoor');
|
this.md2Service.broadcastHeroAction('openDoor');
|
||||||
//this.showMoveAction = false;
|
//this.showMoveAction = false;
|
||||||
this.detectChanges();
|
this.detectChanges();
|
||||||
}
|
}
|
||||||
@ -224,7 +247,7 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.md2Service.broadcastService.broadcastHeroAction(action);
|
this.md2Service.broadcastHeroAction(action);
|
||||||
this.reduceAction();
|
this.reduceAction();
|
||||||
}
|
}
|
||||||
reduceAction() {
|
reduceAction() {
|
||||||
|
|||||||
@ -59,20 +59,28 @@
|
|||||||
<div class="col-12" *ngFor="let hero of md2Service.heros">
|
<div class="col-12" *ngFor="let hero of md2Service.heros">
|
||||||
<label class='label mr-1'>{{hero.playerInfo.name}} ({{heroClassName(hero)}} -
|
<label class='label mr-1'>{{hero.playerInfo.name}} ({{heroClassName(hero)}} -
|
||||||
{{hero.name}})</label>
|
{{hero.name}})</label>
|
||||||
<span class="badge badge-primary mr-1">Lv.:{{hero.level}}</span>
|
<span class="badge badge-primary mr-1"
|
||||||
<span class="badge badge-primary mr-1">HP: {{hero.hp}}/{{hero.hpMaximum}}</span>
|
(click)="adjustHeroValue(hero,'level')">Lv.:{{hero.level}}</span>
|
||||||
<span class="badge badge-primary mr-1">Mana: {{hero.mp}}/{{hero.mpMaximum}}</span>
|
<span class="badge badge-primary mr-1" (click)="adjustHeroValue(hero,'hp')">HP:
|
||||||
<span class="badge badge-success mr-1">Exp: {{hero.exp}}</span>
|
{{hero.hp}}/{{hero.hpMaximum}}</span>
|
||||||
|
<span class="badge badge-primary mr-1" (click)="adjustHeroValue(hero,'mp')">Mana:
|
||||||
|
{{hero.mp}}/{{hero.mpMaximum}}</span>
|
||||||
|
<span class="badge badge-success mr-1" (click)="adjustHeroValue(hero,'exp')">Exp:
|
||||||
|
{{hero.exp}}</span>
|
||||||
<span class="badge mr-1" *ngIf="hero.fireToken">
|
<span class="badge mr-1" *ngIf="hero.fireToken">
|
||||||
<md2-icon [icon]="MD2Icon.FireToken" size="sm"></md2-icon> {{hero.fireToken}}
|
<md2-icon [icon]="MD2Icon.FireToken" size="sm"></md2-icon> {{hero.fireToken}}
|
||||||
</span>
|
</span>
|
||||||
<span class="badge mr-1" *ngIf="hero.frozenToken">
|
<span class="badge mr-1" *ngIf="hero.frozenToken">
|
||||||
<md2-icon [icon]="MD2Icon.FrozenToken" size="sm"></md2-icon>{{hero.frozenToken}}
|
<md2-icon [icon]="MD2Icon.FrozenToken" size="sm"></md2-icon>{{hero.frozenToken}}
|
||||||
</span>
|
</span>
|
||||||
<span class="badge badge-success mr-1" *ngIf="hero.remainActions>0">Actions:
|
<span class="badge badge-success mr-1" *ngIf="hero.remainActions>0"
|
||||||
|
(click)="adjustHeroValue(hero,'remainActions')">Actions:
|
||||||
{{hero.remainActions}}</span>
|
{{hero.remainActions}}</span>
|
||||||
<span class="badge badge-light mr-1" *ngIf=" !hero.uiActivating">Inactive</span>
|
<span class="badge badge-light mr-1" *ngIf=" !hero.uiActivating"
|
||||||
|
(click)="activatingHero(hero)">Inactive</span>
|
||||||
<span class="badge badge-primary mr-1" *ngIf="hero.uiActivating">Activating</span>
|
<span class="badge badge-primary mr-1" *ngIf="hero.uiActivating">Activating</span>
|
||||||
|
<span class="badge badge-warning mr-1"
|
||||||
|
*ngIf="hero.playerInfo.isDisconnected">Disconnected</span>
|
||||||
<!-- <span class="badge badge-success mr-1">{{hero.playerInfo.signalRClientId}}</span> -->
|
<!-- <span class="badge badge-success mr-1">{{hero.playerInfo.signalRClientId}}</span> -->
|
||||||
|
|
||||||
<span class="badge badge-danger mr-1" (click)="removeHero(hero)">X
|
<span class="badge badge-danger mr-1" (click)="removeHero(hero)">X
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
.badge {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
@ -51,6 +51,31 @@ export class MassiveDarkness2Component extends MD2Base implements OnInit {
|
|||||||
}
|
}
|
||||||
override signalRInitialized() {
|
override signalRInitialized() {
|
||||||
|
|
||||||
|
}
|
||||||
|
adjustHeroValue(hero: MD2HeroInfo, value: string) {
|
||||||
|
this.msgBoxService.showInputbox(`Adjust ${value} for ${hero.playerInfo.name}`, `Enter the new value for ${value}`, {
|
||||||
|
inputType: 'number',
|
||||||
|
inputValue: hero[value].toString()
|
||||||
|
}).pipe(first()).subscribe(result => {
|
||||||
|
if (result) {
|
||||||
|
hero[value] = Number.parseInt(result);
|
||||||
|
this.md2Service.broadcastHeroInfoToAll(hero, true);
|
||||||
|
this.detectChanges();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
activatingHero(hero: MD2HeroInfo) {
|
||||||
|
if (hero.remainActions > 0) {
|
||||||
|
this.msgBoxService.show('Activating', { text: `Are you sure you want to activate ${hero.playerInfo.name}?` }).pipe(first()).subscribe(result => {
|
||||||
|
if (result) {
|
||||||
|
this.md2Service.heros.forEach(h => h.uiActivating = false);
|
||||||
|
hero.uiActivating = true;
|
||||||
|
this.md2Service.broadcastAllHeroInfoToAll();
|
||||||
|
this.detectChanges();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
showQrCode() {
|
showQrCode() {
|
||||||
if (this.md2Service.initialized == false) {
|
if (this.md2Service.initialized == false) {
|
||||||
@ -146,7 +171,7 @@ export class MassiveDarkness2Component extends MD2Base implements OnInit {
|
|||||||
this.md2Service.heros.forEach(hero => {
|
this.md2Service.heros.forEach(hero => {
|
||||||
hero.uiShowAttackBtn = this.md2Service.mobs.length > 0 || this.md2Service.roamingMonsters.length > 0 || this.md2Service.info.isBossFight;
|
hero.uiShowAttackBtn = this.md2Service.mobs.length > 0 || this.md2Service.roamingMonsters.length > 0 || this.md2Service.info.isBossFight;
|
||||||
});
|
});
|
||||||
this.md2Service.broadcastService.broadcastAllHeroInfoToAll();
|
this.md2Service.broadcastAllHeroInfoToAll();
|
||||||
}
|
}
|
||||||
removeHero(hero) {
|
removeHero(hero) {
|
||||||
this.msgBoxService.showConfirmDeleteBox().pipe(first()).subscribe(result => {
|
this.msgBoxService.showConfirmDeleteBox().pipe(first()).subscribe(result => {
|
||||||
|
|||||||
@ -53,6 +53,7 @@ export interface IBossFight {
|
|||||||
imgUrl: string
|
imgUrl: string
|
||||||
standUrl: string
|
standUrl: string
|
||||||
extraRules: string
|
extraRules: string
|
||||||
|
md2Service: MD2Service
|
||||||
activating(): boolean
|
activating(): boolean
|
||||||
prepareForBossFight(): void
|
prepareForBossFight(): void
|
||||||
darknessPhase(): void
|
darknessPhase(): void
|
||||||
@ -73,7 +74,7 @@ export abstract class BossFight implements IBossFight {
|
|||||||
extraRules: string
|
extraRules: string
|
||||||
protected subscription: Subscription
|
protected subscription: Subscription
|
||||||
|
|
||||||
constructor(protected md2Service: MD2Service) {
|
constructor(public md2Service: MD2Service) {
|
||||||
this.rounds = 1;
|
this.rounds = 1;
|
||||||
}
|
}
|
||||||
activating(): boolean {
|
activating(): boolean {
|
||||||
@ -105,26 +106,26 @@ export abstract class BossFight implements IBossFight {
|
|||||||
|
|
||||||
}
|
}
|
||||||
export class BossMicheal extends BossFight {
|
export class BossMicheal extends BossFight {
|
||||||
constructor(protected md2Service: MD2Service) {
|
constructor(public md2Service: MD2Service) {
|
||||||
super(md2Service);
|
super(md2Service);
|
||||||
this.corruptionTokenHtml = this.md2Service.stateService.imgHtml('Tokens/CorruptToken.png');
|
this.corruptionTokenHtml = this.md2Service.imgHtml('Tokens/CorruptToken.png');
|
||||||
|
|
||||||
this.name = 'Michael - The Corrupted Archangel';
|
this.name = 'Michael - The Corrupted Archangel';
|
||||||
this.imgUrl = md2Service.stateService.imgUrl('/Boss/Michael - The Corrupted Archangel.jpg');
|
this.imgUrl = md2Service.imgUrl('/Boss/Michael - The Corrupted Archangel.jpg');
|
||||||
this.standUrl = md2Service.stateService.imgUrl('/Boss/Michael.png');
|
this.standUrl = md2Service.imgUrl('/Boss/Michael.png');
|
||||||
|
|
||||||
this.info = new MobInfo({
|
this.info = new MobInfo({
|
||||||
description: this.name,
|
description: this.name,
|
||||||
type: MobType.Boss,
|
type: MobType.Boss,
|
||||||
hpPerHero: 15,
|
hpPerHero: 15,
|
||||||
level: 10,
|
level: 10,
|
||||||
imageUrl: md2Service.stateService.imgUrl('/Boss/Michael.png')
|
imageUrl: md2Service.imgUrl('/Boss/Michael.png')
|
||||||
});
|
});
|
||||||
if (!this.info.skills) {
|
if (!this.info.skills) {
|
||||||
this.info.skills = [];
|
this.info.skills = [];
|
||||||
}
|
}
|
||||||
this.info.skills.push({
|
this.info.skills.push({
|
||||||
name: `Combat 1 ${this.md2Service.stateService.iconHtml(MD2Icon.EnemySkill)}`,
|
name: `Combat 1 ${this.md2Service.iconHtml(MD2Icon.EnemySkill)}`,
|
||||||
description: `Deal 1 Wound for each ${this.corruptionTokenHtml} on the attacking or defending Hero. Discard the tokens afterwards(once per combat).`,
|
description: `Deal 1 Wound for each ${this.corruptionTokenHtml} on the attacking or defending Hero. Discard the tokens afterwards(once per combat).`,
|
||||||
type: MobSkillType.Combat,
|
type: MobSkillType.Combat,
|
||||||
skillRoll: 1
|
skillRoll: 1
|
||||||
@ -135,9 +136,9 @@ export class BossMicheal extends BossFight {
|
|||||||
this.actionBlackDice = 2;
|
this.actionBlackDice = 2;
|
||||||
|
|
||||||
this.extraRules = `Archangel Michael can’t be the target of any attack, skill, ability or take Wounds until there are no Corruption tokens in the whole Tile.<br><br>` +
|
this.extraRules = `Archangel Michael can’t be the target of any attack, skill, ability or take Wounds until there are no Corruption tokens in the whole Tile.<br><br>` +
|
||||||
`Any Hero on a Zone with a ${this.corruptionTokenHtml} may spend 1 action to remove it. Each time a Hero removes a ${this.corruptionTokenHtml} from a Zone they must roll 1 ${this.md2Service.stateService.iconHtml(MD2Icon.BlackDice)}.` +
|
`Any Hero on a Zone with a ${this.corruptionTokenHtml} may spend 1 action to remove it. Each time a Hero removes a ${this.corruptionTokenHtml} from a Zone they must roll 1 ${this.md2Service.iconHtml(MD2Icon.BlackDice)}.` +
|
||||||
`If ${this.md2Service.stateService.iconHtml(MD2Icon.EnemyClaw)} the Hero takes 1 Wound.<br>If ${this.md2Service.stateService.iconHtml(MD2Icon.EnemySkill)} place 1 ${this.corruptionTokenHtml} on their Dashboard.<br>` +
|
`If ${this.md2Service.iconHtml(MD2Icon.EnemyClaw)} the Hero takes 1 Wound.<br>If ${this.md2Service.iconHtml(MD2Icon.EnemySkill)} place 1 ${this.corruptionTokenHtml} on their Dashboard.<br>` +
|
||||||
`If ${this.md2Service.stateService.iconHtml(MD2Icon.EnemyClaw)}/${this.md2Service.stateService.iconHtml(MD2Icon.EnemySkill)} the Hero takes 1 Wound and places 1 ${this.corruptionTokenHtml} on their Dashboard.`
|
`If ${this.md2Service.iconHtml(MD2Icon.EnemyClaw)}/${this.md2Service.iconHtml(MD2Icon.EnemySkill)} the Hero takes 1 Wound and places 1 ${this.corruptionTokenHtml} on their Dashboard.`
|
||||||
}
|
}
|
||||||
activatedTimes: number
|
activatedTimes: number
|
||||||
acted: number
|
acted: number
|
||||||
@ -232,26 +233,26 @@ export class BossMicheal extends BossFight {
|
|||||||
|
|
||||||
export class BossReaper extends BossFight {
|
export class BossReaper extends BossFight {
|
||||||
|
|
||||||
constructor(protected md2Service: MD2Service) {
|
constructor(public md2Service: MD2Service) {
|
||||||
super(md2Service);
|
super(md2Service);
|
||||||
this.timeTokenHtml = this.md2Service.stateService.imgHtml('Tokens/TimeToken.png');
|
this.timeTokenHtml = this.md2Service.imgHtml('Tokens/TimeToken.png');
|
||||||
|
|
||||||
this.name = 'The Reaper';
|
this.name = 'The Reaper';
|
||||||
this.imgUrl = md2Service.stateService.imgUrl('/Boss/The Reaper.jpg');
|
this.imgUrl = md2Service.imgUrl('/Boss/The Reaper.jpg');
|
||||||
this.standUrl = md2Service.stateService.imgUrl('/Boss/The Reaper-Stand.png');
|
this.standUrl = md2Service.imgUrl('/Boss/The Reaper-Stand.png');
|
||||||
|
|
||||||
this.info = new MobInfo({
|
this.info = new MobInfo({
|
||||||
description: this.name,
|
description: this.name,
|
||||||
type: MobType.Boss,
|
type: MobType.Boss,
|
||||||
hpPerHero: 25,
|
hpPerHero: 25,
|
||||||
level: 10,
|
level: 10,
|
||||||
imageUrl: md2Service.stateService.imgUrl('/Boss/The Reaper-Stand.png')
|
imageUrl: md2Service.imgUrl('/Boss/The Reaper-Stand.png')
|
||||||
});
|
});
|
||||||
if (!this.info.skills) {
|
if (!this.info.skills) {
|
||||||
this.info.skills = [];
|
this.info.skills = [];
|
||||||
}
|
}
|
||||||
this.info.skills.push({
|
this.info.skills.push({
|
||||||
description: `If the Hero has no ${this.md2Service.stateService.iconHtml(MD2Icon.Mana_Color)}, they take 1 ${this.md2Service.stateService.iconHtml(MD2Icon.FrozenToken)}`,
|
description: `If the Hero has no ${this.md2Service.iconHtml(MD2Icon.Mana_Color)}, they take 1 ${this.md2Service.iconHtml(MD2Icon.FrozenToken)}`,
|
||||||
type: MobSkillType.Attack,
|
type: MobSkillType.Attack,
|
||||||
skillRoll: 1
|
skillRoll: 1
|
||||||
} as MD2MobSkill);
|
} as MD2MobSkill);
|
||||||
@ -304,8 +305,8 @@ export class BossReaper extends BossFight {
|
|||||||
name: 'Death Is Coming',
|
name: 'Death Is Coming',
|
||||||
description:
|
description:
|
||||||
`Place The Reaper in the central Zone.<br>` +
|
`Place The Reaper in the central Zone.<br>` +
|
||||||
`Roll 1 ${this.md2Service.stateService.iconHtml(MD2Icon.YellowDice)}. Remove ${this.timeTokenHtml} equal to ${this.md2Service.stateService.iconHtml(MD2Icon.Melee)} rolled from both <b>Hourglass Zone</b>.<br>` +
|
`Roll 1 ${this.md2Service.iconHtml(MD2Icon.YellowDice)}. Remove ${this.timeTokenHtml} equal to ${this.md2Service.iconHtml(MD2Icon.Melee)} rolled from both <b>Hourglass Zone</b>.<br>` +
|
||||||
`Each Hero discards ${this.md2Service.stateService.iconHtml(MD2Icon.MP)} equal to ${this.md2Service.stateService.iconHtml(MD2Icon.Melee)} rolled.`
|
`Each Hero discards ${this.md2Service.iconHtml(MD2Icon.MP)} equal to ${this.md2Service.iconHtml(MD2Icon.Melee)} rolled.`
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import { MsgBoxService } from '../../../services/msg-box.service';
|
|||||||
import { DropDownOption } from '../../../entity/dropDownOption';
|
import { DropDownOption } from '../../../entity/dropDownOption';
|
||||||
import { MD2Icon } from '../massive-darkness2.model';
|
import { MD2Icon } from '../massive-darkness2.model';
|
||||||
import { first } from 'rxjs/operators';
|
import { first } from 'rxjs/operators';
|
||||||
import { MD2StateService } from '../../../services/MD2/md2-state.service';
|
|
||||||
import { MD2IconPickerDlgComponent } from './md2-icon-picker-dlg.component';
|
import { MD2IconPickerDlgComponent } from './md2-icon-picker-dlg.component';
|
||||||
import { NbDialogService } from '@nebular/theme';
|
import { NbDialogService } from '@nebular/theme';
|
||||||
import { DOMParser as ProseMirrorDOMParser } from 'prosemirror-model';
|
import { DOMParser as ProseMirrorDOMParser } from 'prosemirror-model';
|
||||||
@ -59,7 +58,6 @@ export class MD2HtmlEditorComponent implements ControlValueAccessor, AfterViewIn
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private msgBoxService: MsgBoxService,
|
private msgBoxService: MsgBoxService,
|
||||||
private md2StateService: MD2StateService,
|
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
private cdr: ChangeDetectorRef,
|
private cdr: ChangeDetectorRef,
|
||||||
elementRef: ElementRef, ngZone: NgZone, @Inject(PLATFORM_ID) platformId: Object) {
|
elementRef: ElementRef, ngZone: NgZone, @Inject(PLATFORM_ID) platformId: Object) {
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { NbDialogRef } from '@nebular/theme';
|
import { NbDialogRef } from '@nebular/theme';
|
||||||
import { MD2Icon } from '../massive-darkness2.model';
|
import { MD2Icon } from '../massive-darkness2.model';
|
||||||
import { MD2StateService } from '../../../services/MD2/md2-state.service';
|
|
||||||
import { DialogRef } from '@progress/kendo-angular-dialog';
|
import { DialogRef } from '@progress/kendo-angular-dialog';
|
||||||
|
import { MD2Service } from '../../../services/MD2/md2.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'md2-icon-picker-dlg',
|
selector: 'md2-icon-picker-dlg',
|
||||||
@ -63,7 +63,7 @@ export class MD2IconPickerDlgComponent implements OnInit {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private dlgRef: DialogRef,
|
private dlgRef: DialogRef,
|
||||||
private md2StateService: MD2StateService
|
private md2Service: MD2Service
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
@ -72,7 +72,7 @@ export class MD2IconPickerDlgComponent implements OnInit {
|
|||||||
this.iconList.push({
|
this.iconList.push({
|
||||||
icon: icon,
|
icon: icon,
|
||||||
name: MD2Icon[icon],
|
name: MD2Icon[icon],
|
||||||
html: this.md2StateService.iconHtml(icon)
|
html: this.md2Service.iconHtml(icon)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import { MD2Icon, TreasureType } from '../massive-darkness2.model';
|
import { MD2Icon, TreasureType } from '../massive-darkness2.model';
|
||||||
import { MD2StateService } from '../../../services/MD2/md2-state.service';
|
import { MD2Service } from '../../../services/MD2/md2.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'md2-icon',
|
selector: 'md2-icon',
|
||||||
@ -44,7 +44,7 @@ export class MD2IconComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
@Input() size: string = 'sm';
|
@Input() size: string = 'sm';
|
||||||
iconName: string;
|
iconName: string;
|
||||||
constructor(private md2StateService: MD2StateService) { }
|
constructor(private md2Service: MD2Service) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
}
|
}
|
||||||
@ -52,10 +52,10 @@ export class MD2IconComponent implements OnInit {
|
|||||||
private initIcon(icon: MD2Icon): void {
|
private initIcon(icon: MD2Icon): void {
|
||||||
if (icon < MD2Icon.TreasureToken) {
|
if (icon < MD2Icon.TreasureToken) {
|
||||||
this.isImageIcon = false;
|
this.isImageIcon = false;
|
||||||
this.iconHtml = this.md2StateService.iconHtml(icon);
|
this.iconHtml = this.md2Service.iconHtml(icon);
|
||||||
} else {
|
} else {
|
||||||
this.isImageIcon = true;
|
this.isImageIcon = true;
|
||||||
this.imgUrl = this.md2StateService.iconHtml(icon);
|
this.imgUrl = this.md2Service.iconHtml(icon);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { MD2MobLevelInfo } from '../../massive-darkness2.db.model';
|
|||||||
import { MobSkillType } from '../../massive-darkness2.model.boss';
|
import { MobSkillType } from '../../massive-darkness2.model.boss';
|
||||||
import { MD2MobLevelInfoService } from '../../service/massive-darkness2.service';
|
import { MD2MobLevelInfoService } from '../../service/massive-darkness2.service';
|
||||||
import { MD2Icon, MobType } from '../../massive-darkness2.model';
|
import { MD2Icon, MobType } from '../../massive-darkness2.model';
|
||||||
import { MD2StateService } from '../../../../services/MD2/md2-state.service';
|
import { MD2Service } from '../../../../services/MD2/md2.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ngx-md2-mob-level-editor',
|
selector: 'ngx-md2-mob-level-editor',
|
||||||
@ -30,7 +30,7 @@ export class MD2MobLevelEditorComponent extends DialogContentBase implements OnI
|
|||||||
public dialog: DialogRef,
|
public dialog: DialogRef,
|
||||||
private mobLevelInfoService: MD2MobLevelInfoService,
|
private mobLevelInfoService: MD2MobLevelInfoService,
|
||||||
private cdr: ChangeDetectorRef,
|
private cdr: ChangeDetectorRef,
|
||||||
private md2StateService: MD2StateService
|
private md2Service: MD2Service
|
||||||
) {
|
) {
|
||||||
super(dialog);
|
super(dialog);
|
||||||
}
|
}
|
||||||
@ -43,9 +43,9 @@ export class MD2MobLevelEditorComponent extends DialogContentBase implements OnI
|
|||||||
public initializeEnums(): void {
|
public initializeEnums(): void {
|
||||||
this.attackTypes = [
|
this.attackTypes = [
|
||||||
{ value: MobSkillType.Attack, text: 'None' },
|
{ value: MobSkillType.Attack, text: 'None' },
|
||||||
{ value: MobSkillType.MeleeAttack, text: this.md2StateService.iconHtml(MD2Icon.Melee) + ' Melee Attack' },
|
{ value: MobSkillType.MeleeAttack, text: this.md2Service.iconHtml(MD2Icon.Melee) + ' Melee Attack' },
|
||||||
{ value: MobSkillType.RangeAttack, text: this.md2StateService.iconHtml(MD2Icon.Range) + ' Range Attack' },
|
{ value: MobSkillType.RangeAttack, text: this.md2Service.iconHtml(MD2Icon.Range) + ' Range Attack' },
|
||||||
{ value: MobSkillType.MagicAttack, text: this.md2StateService.iconHtml(MD2Icon.Magic) + ' Magic Attack' },
|
{ value: MobSkillType.MagicAttack, text: this.md2Service.iconHtml(MD2Icon.Magic) + ' Magic Attack' },
|
||||||
];
|
];
|
||||||
this.selectedAttackType = this.attackTypes.find(t => t.value === this.model.attackInfo.type) || this.attackTypes[0] || null;
|
this.selectedAttackType = this.attackTypes.find(t => t.value === this.model.attackInfo.type) || this.attackTypes[0] || null;
|
||||||
this.selectedAlterAttackType = this.attackTypes.find(t => t.value === this.model.alterAttackInfo?.type) || this.attackTypes[0] || null;
|
this.selectedAlterAttackType = this.attackTypes.find(t => t.value === this.model.alterAttackInfo?.type) || this.attackTypes[0] || null;
|
||||||
|
|||||||
@ -8,8 +8,8 @@
|
|||||||
<div class="pl-2 col-md-6" *ngIf="mob.mobAmount">
|
<div class="pl-2 col-md-6" *ngIf="mob.mobAmount">
|
||||||
|
|
||||||
<ng-container>
|
<ng-container>
|
||||||
<label class='label g-text-nowrap'>Alive Units <b
|
<label class='label g-text-nowrap'>Minions <b
|
||||||
class="MD2text g-font-size-18">{{mob.mobAmount}}</b></label><br>
|
class="MD2text g-font-size-18">{{mob.mobAmount-1}}</b></label><br>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
<img class="g-width-95x img-thumbnail mobBg" src="{{imgUrl('/Mobs/BG.png')}}" />
|
<img class="g-width-95x img-thumbnail mobBg" src="{{imgUrl('/Mobs/BG.png')}}" />
|
||||||
<img class="mobImg roamingMonster" src="{{getMobImageUrl(mob)}}" (click)="showMobImage(mob)" *ngIf="!isMob" />
|
<img class="mobImg roamingMonster" src="{{getMobImageUrl(mob)}}" (click)="showMobImage(mob)" *ngIf="!isMob" />
|
||||||
<div *ngIf="isMob">
|
<div *ngIf="isMob">
|
||||||
<img class="mobImg mobLeader" src="{{mob.leaderImgUrl}}" (click)="showMobImage(mob)" />
|
<img class="mobImg mobLeader" src="{{mob.leaderImgUrl}}" (click)="showMobImage(mob)"
|
||||||
<img class="mobImg mobMinion" src="{{mob.minionImgUrl}}" (click)="showMobImage(mob)" />
|
[ngClass]="{'noMinions': mob.mobAmount==1}" />
|
||||||
|
<img class="mobImg mobMinion" src="{{mob.minionImgUrl}}" (click)="showMobImage(mob)" *ngIf="mob.mobAmount>1" />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -1,6 +1,7 @@
|
|||||||
.mobImg {
|
.mobImg {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
object-fit: contain;
|
||||||
&.roamingMonster {
|
&.roamingMonster {
|
||||||
width: 95%;
|
width: 95%;
|
||||||
max-height: 80%;
|
max-height: 80%;
|
||||||
@ -12,6 +13,10 @@
|
|||||||
max-height: 80%;
|
max-height: 80%;
|
||||||
top: 40px;
|
top: 40px;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
&.noMinions {
|
||||||
|
width: 95%;
|
||||||
|
max-height: 90%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&.mobMinion {
|
&.mobMinion {
|
||||||
width: 60%;
|
width: 60%;
|
||||||
|
|||||||
@ -119,7 +119,7 @@ export class MobsComponent extends MD2ComponentBase implements OnInit {
|
|||||||
|
|
||||||
afterSpawn() {
|
afterSpawn() {
|
||||||
this.cdRef.detectChanges();
|
this.cdRef.detectChanges();
|
||||||
this.md2Service.broadcastService.broadcastMobsInfo();
|
this.md2Service.broadcastMobsInfo();
|
||||||
if (this.showRoundMessage) {
|
if (this.showRoundMessage) {
|
||||||
this.msgBoxService.show(`${NumberUtils.Ordinal(this.md2Service.info.round)} Hero Phase`, { icon: ADIcon.INFO });
|
this.msgBoxService.show(`${NumberUtils.Ordinal(this.md2Service.info.round)} Hero Phase`, { icon: ADIcon.INFO });
|
||||||
}
|
}
|
||||||
@ -150,7 +150,7 @@ export class MobsComponent extends MD2ComponentBase implements OnInit {
|
|||||||
if (attacker) {
|
if (attacker) {
|
||||||
attacker.exp += 1;
|
attacker.exp += 1;
|
||||||
this.msgBoxService.show(`${attacker.heroFullName} Gain 1 Exp`, { icon: ADIcon.INFO }).pipe(first()).subscribe(result => {
|
this.msgBoxService.show(`${attacker.heroFullName} Gain 1 Exp`, { icon: ADIcon.INFO }).pipe(first()).subscribe(result => {
|
||||||
this.md2Service.broadcastService.broadcastHeroInfoToOwner(attacker);
|
this.md2Service.broadcastHeroInfoToOwner(attacker);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +0,0 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { MD2BroadcastService } from './md2-broadcast.service';
|
|
||||||
|
|
||||||
describe('MD2BroadcastService', () => {
|
|
||||||
let service: MD2BroadcastService;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
TestBed.configureTestingModule({});
|
|
||||||
service = TestBed.inject(MD2BroadcastService);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be created', () => {
|
|
||||||
expect(service).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,116 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { NbDialogService } from '@nebular/theme';
|
|
||||||
import { first } from 'rxjs/operators';
|
|
||||||
import { MD2HeroInfo } from '../../games/massive-darkness2/massive-darkness2.model';
|
|
||||||
import { FileService } from '../file.service';
|
|
||||||
import { GameRoomService } from '../game-room.service';
|
|
||||||
import { LoginUserService } from '../login-user.service';
|
|
||||||
import { SignalRService, SignalRSession, SignalRMessage } from '../signal-r.service';
|
|
||||||
import { MD2StateService } from './md2-state.service';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class MD2BroadcastService {
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
public fileService: FileService,
|
|
||||||
private gameRoomService: GameRoomService,
|
|
||||||
private loginUserService: LoginUserService,
|
|
||||||
public stateService: MD2StateService,
|
|
||||||
public signalRService: SignalRService,
|
|
||||||
public dlgService: NbDialogService
|
|
||||||
) { }
|
|
||||||
|
|
||||||
public get playerHero(): MD2HeroInfo {
|
|
||||||
return this.stateService.playerHero;
|
|
||||||
}
|
|
||||||
public broadcastAllHeroInfoToAll() {
|
|
||||||
let message = {
|
|
||||||
receiver: { isGroup: true, sessionId: this.gameRoomService.gameRoomId } as SignalRSession,
|
|
||||||
from: { isGroup: false, sessionId: this.loginUserService.userAccess.signalRSessionId },
|
|
||||||
actionType: 'heroes',
|
|
||||||
actionName: 'updateAll',
|
|
||||||
} as SignalRMessage;
|
|
||||||
message.parameters = { heros: JSON.stringify(this.stateService.info.heros) };
|
|
||||||
this.gameRoomService.sendMessage(message).pipe(first()).subscribe(result => {
|
|
||||||
});
|
|
||||||
this.broadcastMobsInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
public broadcastHeroAction(action: string, extraValue: any = null) {
|
|
||||||
let parameters = {};
|
|
||||||
parameters['tabId'] = this.loginUserService.sessionTabId;
|
|
||||||
parameters['extraValue'] = JSON.stringify(extraValue);
|
|
||||||
this.broadcastMessage('heroAction', action, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
public broadcastHeroInfoToAll(hero: MD2HeroInfo) {
|
|
||||||
let message = {
|
|
||||||
receiver: { isGroup: true, sessionId: this.gameRoomService.gameRoomId } as SignalRSession,
|
|
||||||
from: { isGroup: false, sessionId: hero.playerInfo.signalRClientId },
|
|
||||||
actionType: 'hero',
|
|
||||||
actionName: 'update',
|
|
||||||
} as SignalRMessage;
|
|
||||||
message.parameters = { hero: JSON.stringify(hero) };
|
|
||||||
this.gameRoomService.sendMessage(message).pipe(first()).subscribe(result => {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public broadcastHeroInfoToOwner(hero: MD2HeroInfo) {
|
|
||||||
let message = {
|
|
||||||
receiver: { isGroup: false, sessionId: hero.playerInfo.signalRClientId } as SignalRSession,
|
|
||||||
from: { isGroup: true, sessionId: this.gameRoomService.gameRoomId },
|
|
||||||
actionType: 'hero',
|
|
||||||
actionName: 'updateMyHero',
|
|
||||||
} as SignalRMessage;
|
|
||||||
message.parameters = { hero: JSON.stringify(hero) };
|
|
||||||
this.gameRoomService.sendMessage(message).pipe(first()).subscribe(result => {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `sessionId` = null means broadcast to all
|
|
||||||
*/
|
|
||||||
public broadcastMessage(actionType: string,
|
|
||||||
actionName: string,
|
|
||||||
parameters: { [key: string]: string; } = {},
|
|
||||||
sessionId: string = null) {
|
|
||||||
let message = {
|
|
||||||
receiver: { isGroup: !sessionId, sessionId: sessionId } as SignalRSession,
|
|
||||||
from: { isGroup: false, sessionId: this.loginUserService.userAccess.signalRSessionId },
|
|
||||||
actionType: actionType,
|
|
||||||
actionName: actionName,
|
|
||||||
parameters: parameters
|
|
||||||
} as SignalRMessage;
|
|
||||||
|
|
||||||
if (sessionId == null) {
|
|
||||||
message.receiver = { isGroup: true, sessionId: this.gameRoomService.gameRoomId } as SignalRSession
|
|
||||||
} else {
|
|
||||||
message.receiver = { isGroup: false, sessionId: this.gameRoomService.gameRoomId } as SignalRSession
|
|
||||||
}
|
|
||||||
this.gameRoomService.sendMessage(message).pipe(first()).subscribe(result => {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
public broadcastGameInfo() {
|
|
||||||
let parameters = {};
|
|
||||||
parameters['gameInfo'] = JSON.stringify(this.stateService.info);
|
|
||||||
this.broadcastMessage('GameRoom', 'update', parameters);
|
|
||||||
}
|
|
||||||
public broadcastRoundPhase() {
|
|
||||||
let parameters = {};
|
|
||||||
parameters['phase'] = JSON.stringify(this.stateService.info.roundPhase);
|
|
||||||
this.broadcastMessage('GameRoom', 'phase', parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
public broadcastMobsInfo() {
|
|
||||||
let parameters = {};
|
|
||||||
parameters['roamingMonsters'] = JSON.stringify(this.stateService.info.roamingMonsters);
|
|
||||||
parameters['mobs'] = JSON.stringify(this.stateService.info.mobs);
|
|
||||||
this.broadcastMessage('mobs', 'update', parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
public broadcastMyHeroInfo() {
|
|
||||||
this.broadcastHeroInfoToAll(this.playerHero);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,8 +1,8 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { DrawingBag, MobInfo, MobType, TreasureItem, TreasureType } from '../../games/massive-darkness2/massive-darkness2.model';
|
import { DrawingBag, MobInfo, MobType, TreasureItem, TreasureType } from '../../games/massive-darkness2/massive-darkness2.model';
|
||||||
import { MD2StateService } from './md2-state.service';
|
|
||||||
import { MD2MobInfoService } from '../../games/massive-darkness2/service/massive-darkness2.service';
|
import { MD2MobInfoService } from '../../games/massive-darkness2/service/massive-darkness2.service';
|
||||||
import { first } from 'rxjs/operators';
|
import { first } from 'rxjs/operators';
|
||||||
|
import { MD2Service } from './md2.service';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -10,13 +10,13 @@ import { first } from 'rxjs/operators';
|
|||||||
export class MD2InitService {
|
export class MD2InitService {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private stateService: MD2StateService,
|
private md2Service: MD2Service,
|
||||||
private mobInfoService: MD2MobInfoService,
|
private mobInfoService: MD2MobInfoService,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
public initMobDecks() {
|
public initMobDecks() {
|
||||||
this.stateService.mobDeck = new DrawingBag();
|
this.md2Service.mobDeck = new DrawingBag();
|
||||||
this.stateService.roamingMobDeck = new DrawingBag();
|
this.md2Service.roamingMobDeck = new DrawingBag();
|
||||||
|
|
||||||
this.initCoreGameMobAndRoamingMonsters();
|
this.initCoreGameMobAndRoamingMonsters();
|
||||||
}
|
}
|
||||||
@ -29,18 +29,18 @@ export class MD2InitService {
|
|||||||
// }
|
// }
|
||||||
// });
|
// });
|
||||||
this.mobInfoService.getAll().pipe(first()).subscribe(result => {
|
this.mobInfoService.getAll().pipe(first()).subscribe(result => {
|
||||||
this.stateService.mobInfos = result.filter(m => m.type == MobType.Mob);
|
this.md2Service.mobInfos = result.filter(m => m.type == MobType.Mob);
|
||||||
this.stateService.roamingMobInfos = result.filter(m => m.type == MobType.RoamingMonster);
|
this.md2Service.roamingMobInfos = result.filter(m => m.type == MobType.RoamingMonster);
|
||||||
for (let i = 0; i < result.length; i++) {
|
for (let i = 0; i < result.length; i++) {
|
||||||
const mobInfo = result[i];
|
const mobInfo = result[i];
|
||||||
for (let j = 0; j < mobInfo.mobLevelInfos.length; j++) {
|
for (let j = 0; j < mobInfo.mobLevelInfos.length; j++) {
|
||||||
const levelInfo = mobInfo.mobLevelInfos[j];
|
const levelInfo = mobInfo.mobLevelInfos[j];
|
||||||
switch (mobInfo.type) {
|
switch (mobInfo.type) {
|
||||||
case MobType.Mob:
|
case MobType.Mob:
|
||||||
this.stateService.mobDeck.AddItem(new MobInfo({ name: mobInfo.name, level: levelInfo.level, drawingWeight: 1 }));
|
this.md2Service.mobDeck.AddItem(new MobInfo({ name: mobInfo.name, level: levelInfo.level, drawingWeight: 1 }));
|
||||||
break;
|
break;
|
||||||
case MobType.RoamingMonster:
|
case MobType.RoamingMonster:
|
||||||
this.stateService.roamingMobDeck.AddItem(new MobInfo({ name: mobInfo.name, level: levelInfo.level, drawingWeight: 1 }));
|
this.md2Service.roamingMobDeck.AddItem(new MobInfo({ name: mobInfo.name, level: levelInfo.level, drawingWeight: 1 }));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,12 +53,12 @@ export class MD2InitService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public initTreasureBag() {
|
public initTreasureBag() {
|
||||||
this.stateService.treasureBag.ClearAllItems();
|
this.md2Service.treasureBag.ClearAllItems();
|
||||||
this.addTreasure(TreasureType.Common, 15);
|
this.addTreasure(TreasureType.Common, 15);
|
||||||
this.addTreasure(TreasureType.Rare, 5);
|
this.addTreasure(TreasureType.Rare, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public addTreasure(type: TreasureType, amount: number = 1) {
|
public addTreasure(type: TreasureType, amount: number = 1) {
|
||||||
this.stateService.treasureBag.AddItem(new TreasureItem(type, amount));
|
this.md2Service.treasureBag.AddItem(new TreasureItem(type, amount));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { first } from 'rxjs/operators';
|
|||||||
import { MobInfo, MobType } from '../../games/massive-darkness2/massive-darkness2.model';
|
import { MobInfo, MobType } from '../../games/massive-darkness2/massive-darkness2.model';
|
||||||
import { ADIcon } from '../../ui/alert-dlg/alert-dlg.model';
|
import { ADIcon } from '../../ui/alert-dlg/alert-dlg.model';
|
||||||
import { MsgBoxService } from '../msg-box.service';
|
import { MsgBoxService } from '../msg-box.service';
|
||||||
import { MD2StateService } from './md2-state.service';
|
|
||||||
import { MD2Service } from './md2.service';
|
import { MD2Service } from './md2.service';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
@ -16,14 +15,13 @@ export class MD2MobService {
|
|||||||
attackingAttackerReward: string = '';
|
attackingAttackerReward: string = '';
|
||||||
constructor(
|
constructor(
|
||||||
private md2Service: MD2Service,
|
private md2Service: MD2Service,
|
||||||
private stateService: MD2StateService,
|
|
||||||
private msgBoxService: MsgBoxService
|
private msgBoxService: MsgBoxService
|
||||||
) { }
|
) { }
|
||||||
public get roamingMonsters() {
|
public get roamingMonsters() {
|
||||||
return this.stateService.info.roamingMonsters;
|
return this.md2Service.info.roamingMonsters;
|
||||||
}
|
}
|
||||||
public get mobs() {
|
public get mobs() {
|
||||||
return this.stateService.info.mobs;
|
return this.md2Service.info.mobs;
|
||||||
}
|
}
|
||||||
|
|
||||||
addOneUnit(mob: MobInfo) {
|
addOneUnit(mob: MobInfo) {
|
||||||
@ -120,14 +118,14 @@ export class MD2MobService {
|
|||||||
}
|
}
|
||||||
this.attackingAllExp = 0;
|
this.attackingAllExp = 0;
|
||||||
this.attackingAttackerExp = 0;
|
this.attackingAttackerExp = 0;
|
||||||
this.md2Service.broadcastService.broadcastAllHeroInfoToAll();
|
this.md2Service.broadcastAllHeroInfoToAll();
|
||||||
this.md2Service.refreshUI$.next();
|
this.md2Service.refreshUI$.next();
|
||||||
});
|
});
|
||||||
} else if (this.attackingAttackerExp > 0 && attacker) {
|
} else if (this.attackingAttackerExp > 0 && attacker) {
|
||||||
this.msgBoxService.show(`<b>${attackerTitle}</b> Gains ${this.attackingAttackerExp} Exp`, { icon: ADIcon.INFO }).pipe(first()).subscribe(result => {
|
this.msgBoxService.show(`<b>${attackerTitle}</b> Gains ${this.attackingAttackerExp} Exp`, { icon: ADIcon.INFO }).pipe(first()).subscribe(result => {
|
||||||
attacker.exp += this.attackingAttackerExp;
|
attacker.exp += this.attackingAttackerExp;
|
||||||
this.attackingAttackerExp = 0;
|
this.attackingAttackerExp = 0;
|
||||||
this.md2Service.broadcastService.broadcastHeroInfoToOwner(attacker);
|
this.md2Service.broadcastHeroInfoToOwner(attacker);
|
||||||
this.md2Service.refreshUI$.next();
|
this.md2Service.refreshUI$.next();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +0,0 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { MD2StateService } from './md2-state.service';
|
|
||||||
|
|
||||||
describe('MD2StateService', () => {
|
|
||||||
let service: MD2StateService;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
TestBed.configureTestingModule({});
|
|
||||||
service = TestBed.inject(MD2StateService);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be created', () => {
|
|
||||||
expect(service).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,87 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { DrawingBag, MD2HeroInfo, MD2Icon, MobInfo, TreasureItem, TreasureType } from '../../games/massive-darkness2/massive-darkness2.model';
|
|
||||||
import { FileService } from '../file.service';
|
|
||||||
import { MD2GameInfo } from './md2.service';
|
|
||||||
import { MD2MobInfo } from '../../games/massive-darkness2/massive-darkness2.db.model';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class MD2StateService {
|
|
||||||
|
|
||||||
private _highestPlayerLevel: number = 1;
|
|
||||||
private _playerAmount: number = 2;
|
|
||||||
|
|
||||||
public info: MD2GameInfo;
|
|
||||||
public playerHero: MD2HeroInfo;
|
|
||||||
public mobInfos: MD2MobInfo[] = [];
|
|
||||||
public roamingMobInfos: MD2MobInfo[] = [];
|
|
||||||
public mobDeck: DrawingBag<MobInfo>;
|
|
||||||
public roamingMobDeck: DrawingBag<MobInfo>;
|
|
||||||
public treasureBag: DrawingBag<TreasureItem> = new DrawingBag<TreasureItem>();
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
public fileService: FileService,
|
|
||||||
) { }
|
|
||||||
|
|
||||||
public iconHtml(icon: MD2Icon, cssClass = '') {
|
|
||||||
|
|
||||||
|
|
||||||
if (icon == MD2Icon.Fire) {
|
|
||||||
cssClass += ' g-color-google-plus ';
|
|
||||||
}
|
|
||||||
if (icon == MD2Icon.Frost || icon == MD2Icon.Mana) {
|
|
||||||
cssClass += ' g-color-aqua ';
|
|
||||||
}
|
|
||||||
if (icon < MD2Icon.RedDice) {
|
|
||||||
return `<span md2-icon='${String.fromCharCode(65 + icon)}' class='MD2Icon ${cssClass}'>${String.fromCharCode(65 + icon)}</span>`
|
|
||||||
} else if (icon < MD2Icon.TreasureToken) {
|
|
||||||
return `<span md2-icon='${String.fromCharCode(65 + icon)}' class='MD2Icon dice ${MD2Icon[icon].replace('Dice', '')} ${cssClass}'></span>`;
|
|
||||||
} else {
|
|
||||||
if (!cssClass) {
|
|
||||||
cssClass = 'g-height-25 mr-1';
|
|
||||||
}
|
|
||||||
//image based icons
|
|
||||||
switch (icon) {
|
|
||||||
|
|
||||||
case MD2Icon.HP_Color:
|
|
||||||
return this.imgHtml('HeartIcon.png', cssClass);
|
|
||||||
case MD2Icon.Mana_Color:
|
|
||||||
return this.imgHtml('ManaIcon.png', cssClass);
|
|
||||||
case MD2Icon.CorruptToken:
|
|
||||||
return this.imgHtml('Tokens/CorruptToken.png', cssClass);
|
|
||||||
case MD2Icon.TimeToken:
|
|
||||||
return this.imgHtml('Tokens/TimeToken.png', cssClass);
|
|
||||||
case MD2Icon.FireToken:
|
|
||||||
return this.imgHtml('Tokens/FireToken.png', cssClass);
|
|
||||||
case MD2Icon.FrozenToken:
|
|
||||||
return this.imgHtml('Tokens/FrozenToken.png', cssClass);
|
|
||||||
case MD2Icon.TreasureToken:
|
|
||||||
return this.imgHtml('TreasureToken/Cover.png', cssClass);
|
|
||||||
case MD2Icon.TreasureToken_Common:
|
|
||||||
return this.imgHtml('TreasureToken/Common.png', cssClass);
|
|
||||||
case MD2Icon.TreasureToken_Rare:
|
|
||||||
return this.imgHtml('TreasureToken/Rare.png', cssClass);
|
|
||||||
case MD2Icon.TreasureToken_Epic:
|
|
||||||
return this.imgHtml('TreasureToken/Epic.png', cssClass);
|
|
||||||
case MD2Icon.TreasureToken_Legendary:
|
|
||||||
return this.imgHtml('TreasureToken/Legendary.png', cssClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public imgHtml(imgPath: string, cssClass = 'g-height-25 mr-1') {
|
|
||||||
return `<img src='${this.imgUrl(imgPath)}' class='${cssClass}'>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
public imgUrl(imgPath: string) {
|
|
||||||
return this.fileService.ImageUrl('MD2/' + imgPath);
|
|
||||||
}
|
|
||||||
public treasureImage(type: TreasureType) {
|
|
||||||
return this.imgUrl(`TreasureToken/${TreasureType[type]}.png`);
|
|
||||||
}
|
|
||||||
public treasureImageHtml(type: TreasureType) {
|
|
||||||
return this.imgHtml(`TreasureToken/${TreasureType[type]}.png`, 'g-height-40 mr-1');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -11,9 +11,7 @@ import { FileService } from '../file.service';
|
|||||||
import { GameRoomService } from '../game-room.service';
|
import { GameRoomService } from '../game-room.service';
|
||||||
import { LoginUserService } from '../login-user.service';
|
import { LoginUserService } from '../login-user.service';
|
||||||
import { MsgBoxService } from '../msg-box.service';
|
import { MsgBoxService } from '../msg-box.service';
|
||||||
import { SignalRService, SignalRSession, SignalRMessage } from '../signal-r.service';
|
import { SignalRService, SignalRClient, SignalRMessage } from '../signal-r.service';
|
||||||
import { MD2StateService } from './md2-state.service';
|
|
||||||
import { MD2BroadcastService } from './md2-broadcast.service';
|
|
||||||
import { MD2Logic } from '../../games/massive-darkness2/massive-darkness2.logic';
|
import { MD2Logic } from '../../games/massive-darkness2/massive-darkness2.logic';
|
||||||
import { MD2InitService } from './md2-init.service';
|
import { MD2InitService } from './md2-init.service';
|
||||||
import { ArrayUtils } from '../../utilities/array-utils';
|
import { ArrayUtils } from '../../utilities/array-utils';
|
||||||
@ -29,6 +27,17 @@ const MD2_IMG_URL = (id: string = null) => { return `${environment.apiUrl}/Files
|
|||||||
export class MD2Service {
|
export class MD2Service {
|
||||||
// #region Properties (24)
|
// #region Properties (24)
|
||||||
|
|
||||||
|
private _highestPlayerLevel: number = 1;
|
||||||
|
private _playerAmount: number = 2;
|
||||||
|
|
||||||
|
public info: MD2GameInfo;
|
||||||
|
public playerHero: MD2HeroInfo;
|
||||||
|
public mobInfos: MD2MobInfo[] = [];
|
||||||
|
public roamingMobInfos: MD2MobInfo[] = [];
|
||||||
|
public mobDeck: DrawingBag<MobInfo>;
|
||||||
|
public roamingMobDeck: DrawingBag<MobInfo>;
|
||||||
|
public treasureBag: DrawingBag<TreasureItem> = new DrawingBag<TreasureItem>();
|
||||||
|
|
||||||
public darknessPhaseRule: IDarknessPhaseRule;
|
public darknessPhaseRule: IDarknessPhaseRule;
|
||||||
public enemyPhaseMobs: MobInfo[];
|
public enemyPhaseMobs: MobInfo[];
|
||||||
public enemyPhaseSubject = new Subject<MobInfo>();
|
public enemyPhaseSubject = new Subject<MobInfo>();
|
||||||
@ -42,45 +51,34 @@ export class MD2Service {
|
|||||||
|
|
||||||
|
|
||||||
public get heros() {
|
public get heros() {
|
||||||
return this.stateService.info.heros;
|
return this.info.heros;
|
||||||
}
|
}
|
||||||
public get roamingMonsters() {
|
public get roamingMonsters() {
|
||||||
return this.stateService.info.roamingMonsters;
|
return this.info.roamingMonsters;
|
||||||
}
|
}
|
||||||
public get mobs() {
|
public get mobs() {
|
||||||
return this.stateService.info.mobs;
|
return this.info.mobs;
|
||||||
}
|
}
|
||||||
public get allRoamingMonsterInfos() {
|
public get allRoamingMonsterInfos() {
|
||||||
return this.stateService.roamingMobInfos;
|
return this.roamingMobInfos;
|
||||||
}
|
}
|
||||||
public get allMobInfos() {
|
public get allMobInfos() {
|
||||||
return this.stateService.mobInfos;
|
return this.mobInfos;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public get info(): MD2GameInfo {
|
|
||||||
return this.stateService.info;
|
|
||||||
}
|
|
||||||
public set info(v: MD2GameInfo) {
|
|
||||||
this.stateService.info = v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// #endregion Properties (24)
|
// #endregion Properties (24)
|
||||||
|
|
||||||
// #region Constructors (1)
|
// #region Constructors (1)
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public fileService: FileService,
|
public fileService: FileService,
|
||||||
public msgBoxService: MsgBoxService,
|
public msgBoxService: MsgBoxService,
|
||||||
private gameRoomService: GameRoomService,
|
public gameRoomService: GameRoomService,
|
||||||
public loginUserService: LoginUserService,
|
public loginUserService: LoginUserService,
|
||||||
public stateService: MD2StateService,
|
|
||||||
public signalRService: SignalRService,
|
public signalRService: SignalRService,
|
||||||
public dlgService: NbDialogService,
|
public dlgService: NbDialogService
|
||||||
public broadcastService: MD2BroadcastService
|
|
||||||
) {
|
) {
|
||||||
this.darknessPhaseRule = new CoreGameDarknessPhaseRule();
|
this.darknessPhaseRule = new CoreGameDarknessPhaseRule();
|
||||||
this.stateService.info = new MD2GameInfo();
|
this.info = new MD2GameInfo();
|
||||||
this.darknessPhaseRule.addTreasureToken.subscribe(treasureType => {
|
this.darknessPhaseRule.addTreasureToken.subscribe(treasureType => {
|
||||||
this.addTreasure(treasureType, 1);
|
this.addTreasure(treasureType, 1);
|
||||||
});
|
});
|
||||||
@ -105,11 +103,8 @@ export class MD2Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public get playerHero(): MD2HeroInfo {
|
|
||||||
return this.stateService.playerHero;
|
|
||||||
}
|
|
||||||
public get currentActivateHero(): MD2HeroInfo {
|
public get currentActivateHero(): MD2HeroInfo {
|
||||||
return this.stateService.info.heros.find(h => h.uiActivating);
|
return this.info.heros.find(h => h.uiActivating);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -119,9 +114,6 @@ export class MD2Service {
|
|||||||
|
|
||||||
// #region Public Methods (27)
|
// #region Public Methods (27)
|
||||||
|
|
||||||
public get treasureBag() {
|
|
||||||
return this.stateService.treasureBag
|
|
||||||
}
|
|
||||||
|
|
||||||
public addTreasure(type: TreasureType, amount: number = 1) {
|
public addTreasure(type: TreasureType, amount: number = 1) {
|
||||||
this.treasureBag.AddItem(new TreasureItem(type, amount));
|
this.treasureBag.AddItem(new TreasureItem(type, amount));
|
||||||
@ -131,17 +123,17 @@ export class MD2Service {
|
|||||||
public darknessPhase() {
|
public darknessPhase() {
|
||||||
this.heros.forEach(hero => {
|
this.heros.forEach(hero => {
|
||||||
hero.remainActions = 3;
|
hero.remainActions = 3;
|
||||||
this.broadcastService.broadcastHeroInfoToOwner(hero);
|
this.broadcastHeroInfoToOwner(hero);
|
||||||
});
|
});
|
||||||
this.stateService.info.roundPhase = RoundPhase.HeroPhase;
|
this.info.roundPhase = RoundPhase.HeroPhase;
|
||||||
if (!this.stateService.info.isBossFight) {
|
if (!this.info.isBossFight) {
|
||||||
this.stateService.info.round++;
|
this.info.round++;
|
||||||
if (this.darknessPhaseRule.runDarknessPhase()) {
|
if (this.darknessPhaseRule.runDarknessPhase()) {
|
||||||
this.msgBoxService.show(`${NumberUtils.Ordinal(this.stateService.info.round)} Hero Phase`, { icon: ADIcon.INFO });
|
this.msgBoxService.show(`${NumberUtils.Ordinal(this.info.round)} Hero Phase`, { icon: ADIcon.INFO });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.stateService.info.boss.darknessPhase();
|
this.info.boss.darknessPhase();
|
||||||
this.msgBoxService.show(`Boss Fight - ${NumberUtils.Ordinal(this.stateService.info.boss.rounds)} Hero Phase`, { icon: ADIcon.INFO });
|
this.msgBoxService.show(`Boss Fight - ${NumberUtils.Ordinal(this.info.boss.rounds)} Hero Phase`, { icon: ADIcon.INFO });
|
||||||
}
|
}
|
||||||
|
|
||||||
//this.runNextPhase();
|
//this.runNextPhase();
|
||||||
@ -157,9 +149,9 @@ export class MD2Service {
|
|||||||
level = 5;
|
level = 5;
|
||||||
}
|
}
|
||||||
if (isRoamingMonster) {
|
if (isRoamingMonster) {
|
||||||
mobDeck = this.stateService.roamingMobDeck;
|
mobDeck = this.roamingMobDeck;
|
||||||
} else {
|
} else {
|
||||||
mobDeck = this.stateService.mobDeck;
|
mobDeck = this.mobDeck;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mobDeck.drawingItems.filter(m => (m as MobInfo).level == level)
|
if (mobDeck.drawingItems.filter(m => (m as MobInfo).level == level)
|
||||||
@ -298,9 +290,9 @@ export class MD2Service {
|
|||||||
} else {
|
} else {
|
||||||
this.info.boss = new BossMicheal(this);
|
this.info.boss = new BossMicheal(this);
|
||||||
}
|
}
|
||||||
this.stateService.info.roamingMonsters = [];
|
this.info.roamingMonsters = [];
|
||||||
this.stateService.info.mobs = [];
|
this.info.mobs = [];
|
||||||
this.stateService.info.isBossFight = true;
|
this.info.isBossFight = true;
|
||||||
this.info.isBossFight = true;
|
this.info.isBossFight = true;
|
||||||
this.info.boss.info.hp = this.info.boss.info.hpPerHero * this.info.heros.length;
|
this.info.boss.info.hp = this.info.boss.info.hpPerHero * this.info.heros.length;
|
||||||
this.info.boss.info.unitRemainHp = this.info.boss.info.hp;
|
this.info.boss.info.unitRemainHp = this.info.boss.info.hp;
|
||||||
@ -314,14 +306,14 @@ export class MD2Service {
|
|||||||
hero.uiActivating = false;
|
hero.uiActivating = false;
|
||||||
hero.uiBossFight = true;
|
hero.uiBossFight = true;
|
||||||
});
|
});
|
||||||
this.broadcastService.broadcastAllHeroInfoToAll();
|
this.broadcastGameInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
//this.sendMsgboxMsg
|
//this.sendMsgboxMsg
|
||||||
}
|
}
|
||||||
public activateBoss() {
|
public activateBoss() {
|
||||||
this.stateService.info.boss.activating();
|
this.info.boss.activating();
|
||||||
}
|
}
|
||||||
public fileList(folderPath: string) {
|
public fileList(folderPath: string) {
|
||||||
return this.fileService.FileList('Images/MD2/' + folderPath);
|
return this.fileService.FileList('Images/MD2/' + folderPath);
|
||||||
@ -342,8 +334,8 @@ export class MD2Service {
|
|||||||
hero.mp += levelUpInfo.extraMp;
|
hero.mp += levelUpInfo.extraMp;
|
||||||
hero.mpMaximum += levelUpInfo.extraMp;
|
hero.mpMaximum += levelUpInfo.extraMp;
|
||||||
hero.exp = levelUpInfo.currentExp;
|
hero.exp = levelUpInfo.currentExp;
|
||||||
this.broadcastService.broadcastHeroInfoToOwner(hero);
|
this.broadcastHeroInfoToOwner(hero);
|
||||||
this.sendMsgboxMsg(hero.playerInfo.signalRClientId, { title: 'Level Up', text: 'Please do a skill level up!', icon: ADIcon.INFO });
|
this.sendMsgboxMsg(hero.playerInfo.signalRClientId, { title: `Level Up Lv.${hero.level}`, text: 'Please do a skill level up!', icon: ADIcon.INFO });
|
||||||
levelUpInfo = MD2Rules.checkCoreGameLevelup(hero.level, hero.exp);
|
levelUpInfo = MD2Rules.checkCoreGameLevelup(hero.level, hero.exp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -362,9 +354,9 @@ export class MD2Service {
|
|||||||
level = 3;
|
level = 3;
|
||||||
}
|
}
|
||||||
if (isRoamingMonsters) {
|
if (isRoamingMonsters) {
|
||||||
return this.stateService.imgUrl(`Mobs/CoreGame/RoamingMonsters/${name}/${level}.png`);
|
return this.imgUrl(`Mobs/CoreGame/RoamingMonsters/${name}/${level}.png`);
|
||||||
} else {
|
} else {
|
||||||
return this.stateService.imgUrl(`Mobs/CoreGame/Mobs/${name}/${level}.png`);
|
return this.imgUrl(`Mobs/CoreGame/Mobs/${name}/${level}.png`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,7 +366,7 @@ export class MD2Service {
|
|||||||
hero.hp = hero.hpMaximum;
|
hero.hp = hero.hpMaximum;
|
||||||
hero.mp = hero.mpMaximum;
|
hero.mp = hero.mpMaximum;
|
||||||
hero.exp = 0;
|
hero.exp = 0;
|
||||||
this.stateService.playerHero = hero;
|
this.playerHero = hero;
|
||||||
// let message = {
|
// let message = {
|
||||||
// receiver: { isGroup: true, sessionId: this.gameRoomService.gameRoomId } as SignalRSession,
|
// receiver: { isGroup: true, sessionId: this.gameRoomService.gameRoomId } as SignalRSession,
|
||||||
// from: { isGroup: false, sessionId: this.loginUserService.userAccess.signalRSessionId },
|
// from: { isGroup: false, sessionId: this.loginUserService.userAccess.signalRSessionId },
|
||||||
@ -389,12 +381,12 @@ export class MD2Service {
|
|||||||
|
|
||||||
|
|
||||||
public runNextPhase() {
|
public runNextPhase() {
|
||||||
this.stateService.info.roundPhase++;
|
this.info.roundPhase++;
|
||||||
switch (this.stateService.info.roundPhase) {
|
switch (this.info.roundPhase) {
|
||||||
case RoundPhase.HeroPhase:
|
case RoundPhase.HeroPhase:
|
||||||
this.heros.forEach(hero => {
|
this.heros.forEach(hero => {
|
||||||
hero.remainActions = 3;
|
hero.remainActions = 3;
|
||||||
this.broadcastService.broadcastHeroInfoToOwner(hero);
|
this.broadcastHeroInfoToOwner(hero);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case RoundPhase.EnemyPhase:
|
case RoundPhase.EnemyPhase:
|
||||||
@ -409,14 +401,14 @@ export class MD2Service {
|
|||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
let parameters = {};
|
let parameters = {};
|
||||||
parameters['phase'] = this.stateService.info.roundPhase;
|
parameters['phase'] = this.info.roundPhase;
|
||||||
this.broadcastService.broadcastMessage('roundPhase', '', parameters);
|
this.broadcastMessage('roundPhase', '', parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sendMsgboxMsg(playerSessionId: string, msg: Partial<MessageBoxConfig>) {
|
public sendMsgboxMsg(playerSessionId: string, msg: Partial<MessageBoxConfig>) {
|
||||||
let message = {
|
let message = {
|
||||||
receiver: { isGroup: false, sessionId: playerSessionId } as SignalRSession,
|
receiver: { isGroup: false, connectionId: playerSessionId } as SignalRClient,
|
||||||
from: { isGroup: false, sessionId: this.loginUserService.userAccess.signalRSessionId },
|
from: { isGroup: false, connectionId: this.loginUserService.userAccess.signalRConnectionId },
|
||||||
actionType: 'message',
|
actionType: 'message',
|
||||||
actionName: 'popup',
|
actionName: 'popup',
|
||||||
} as SignalRMessage;
|
} as SignalRMessage;
|
||||||
@ -426,7 +418,7 @@ export class MD2Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getTargetHerosByFilter(targetType: AttackTarget, onlyOne: boolean = false) {
|
public getTargetHerosByFilter(targetType: AttackTarget, onlyOne: boolean = false) {
|
||||||
return MD2Logic.getTargetHerosByFilter(this.stateService.info.heros, targetType, onlyOne);
|
return MD2Logic.getTargetHerosByFilter(this.info.heros, targetType, onlyOne);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTargetHerosHtml(beenAttackedHero: MD2HeroInfo[]) {
|
public getTargetHerosHtml(beenAttackedHero: MD2HeroInfo[]) {
|
||||||
@ -449,32 +441,193 @@ export class MD2Service {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.broadcastService.broadcastHeroInfoToAll(this.currentActivateHero);
|
this.broadcastHeroInfoToAll(this.currentActivateHero, true);
|
||||||
this.broadcastService.broadcastHeroInfoToOwner(this.currentActivateHero);
|
//this.broadcastHeroInfoToOwner(this.currentActivateHero);
|
||||||
this.msgBoxService.show(
|
this.msgBoxService.show(
|
||||||
this.stateService.imgHtml('/Fountain/Cover.png', '')
|
this.imgHtml('/Fountain/Cover.png', '')
|
||||||
, { text: `${this.currentActivateHero.heroFullName} Recovered ${result.description}.` });
|
, { text: `${this.currentActivateHero.heroFullName} Recovered ${result.description}.` });
|
||||||
}
|
}
|
||||||
|
|
||||||
public openTreasureChest() {
|
public openTreasureChest() {
|
||||||
let result = new DrawingBag<DrawingItem>([
|
let result = new DrawingBag<DrawingItem>([
|
||||||
new DrawingItem('Common', `${this.stateService.treasureImageHtml(TreasureType.Common)} x 2`, '', 10),
|
new DrawingItem('Common', `${this.treasureImageHtml(TreasureType.Common)} x 2`, '', 10),
|
||||||
new DrawingItem('Open Treasure Chest', `${this.stateService.treasureImageHtml(TreasureType.Rare)} x 2`, '', 5),
|
new DrawingItem('Open Treasure Chest', `${this.treasureImageHtml(TreasureType.Rare)} x 2`, '', 5),
|
||||||
])
|
])
|
||||||
.Draw(1)[0];
|
.Draw(1)[0];
|
||||||
|
|
||||||
this.msgBoxService.show(
|
this.msgBoxService.show(
|
||||||
this.stateService.imgHtml('/TreasureChest/SmallTresureChest.jpg', ''), { text: `${this.currentActivateHero.heroFullName} gets ${result.description}.` });
|
this.imgHtml('/TreasureChest/SmallTresureChest.jpg', ''), { text: `${this.currentActivateHero.heroFullName} gets ${result.description}.` });
|
||||||
}
|
}
|
||||||
public openGreatTreasureChest() {
|
public openGreatTreasureChest() {
|
||||||
let result = new DrawingBag<DrawingItem>([
|
let result = new DrawingBag<DrawingItem>([
|
||||||
new DrawingItem('Common', `${this.stateService.treasureImageHtml(TreasureType.Rare)} x 3`, '', 3),
|
new DrawingItem('Common', `${this.treasureImageHtml(TreasureType.Rare)} x 3`, '', 3),
|
||||||
new DrawingItem('Open Treasure Chest', `${this.stateService.treasureImageHtml(TreasureType.Epic)} x 3`, '', 1),
|
new DrawingItem('Open Treasure Chest', `${this.treasureImageHtml(TreasureType.Epic)} x 3`, '', 1),
|
||||||
]).Draw(1)[0];
|
]).Draw(1)[0];
|
||||||
|
|
||||||
this.msgBoxService.show(
|
this.msgBoxService.show(
|
||||||
this.stateService.imgHtml('/TreasureChest/BigTresureChest.png', ''), { text: `${this.currentActivateHero.heroFullName} gets ${result.description}.` });
|
this.imgHtml('/TreasureChest/BigTresureChest.png', ''), { text: `${this.currentActivateHero.heroFullName} gets ${result.description}.` });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public iconHtml(icon: MD2Icon, cssClass = '') {
|
||||||
|
|
||||||
|
|
||||||
|
if (icon == MD2Icon.Fire) {
|
||||||
|
cssClass += ' g-color-google-plus ';
|
||||||
|
}
|
||||||
|
if (icon == MD2Icon.Frost || icon == MD2Icon.Mana) {
|
||||||
|
cssClass += ' g-color-aqua ';
|
||||||
|
}
|
||||||
|
if (icon < MD2Icon.RedDice) {
|
||||||
|
return `<span md2-icon='${String.fromCharCode(65 + icon)}' class='MD2Icon ${cssClass}'>${String.fromCharCode(65 + icon)}</span>`
|
||||||
|
} else if (icon < MD2Icon.TreasureToken) {
|
||||||
|
return `<span md2-icon='${String.fromCharCode(65 + icon)}' class='MD2Icon dice ${MD2Icon[icon].replace('Dice', '')} ${cssClass}'></span>`;
|
||||||
|
} else {
|
||||||
|
if (!cssClass) {
|
||||||
|
cssClass = 'g-height-25 mr-1';
|
||||||
|
}
|
||||||
|
//image based icons
|
||||||
|
switch (icon) {
|
||||||
|
|
||||||
|
case MD2Icon.HP_Color:
|
||||||
|
return this.imgHtml('HeartIcon.png', cssClass);
|
||||||
|
case MD2Icon.Mana_Color:
|
||||||
|
return this.imgHtml('ManaIcon.png', cssClass);
|
||||||
|
case MD2Icon.CorruptToken:
|
||||||
|
return this.imgHtml('Tokens/CorruptToken.png', cssClass);
|
||||||
|
case MD2Icon.TimeToken:
|
||||||
|
return this.imgHtml('Tokens/TimeToken.png', cssClass);
|
||||||
|
case MD2Icon.FireToken:
|
||||||
|
return this.imgHtml('Tokens/FireToken.png', cssClass);
|
||||||
|
case MD2Icon.FrozenToken:
|
||||||
|
return this.imgHtml('Tokens/FrozenToken.png', cssClass);
|
||||||
|
case MD2Icon.TreasureToken:
|
||||||
|
return this.imgHtml('TreasureToken/Cover.png', cssClass);
|
||||||
|
case MD2Icon.TreasureToken_Common:
|
||||||
|
return this.imgHtml('TreasureToken/Common.png', cssClass);
|
||||||
|
case MD2Icon.TreasureToken_Rare:
|
||||||
|
return this.imgHtml('TreasureToken/Rare.png', cssClass);
|
||||||
|
case MD2Icon.TreasureToken_Epic:
|
||||||
|
return this.imgHtml('TreasureToken/Epic.png', cssClass);
|
||||||
|
case MD2Icon.TreasureToken_Legendary:
|
||||||
|
return this.imgHtml('TreasureToken/Legendary.png', cssClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public imgHtml(imgPath: string, cssClass = 'g-height-25 mr-1') {
|
||||||
|
return `<img src='${this.imgUrl(imgPath)}' class='${cssClass}'>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
public imgUrl(imgPath: string) {
|
||||||
|
return this.fileService.ImageUrl('MD2/' + imgPath);
|
||||||
|
}
|
||||||
|
public treasureImage(type: TreasureType) {
|
||||||
|
return this.imgUrl(`TreasureToken/${TreasureType[type]}.png`);
|
||||||
|
}
|
||||||
|
public treasureImageHtml(type: TreasureType) {
|
||||||
|
return this.imgHtml(`TreasureToken/${TreasureType[type]}.png`, 'g-height-40 mr-1');
|
||||||
|
}
|
||||||
|
|
||||||
|
public broadcastAllHeroInfoToAll() {
|
||||||
|
let message = {
|
||||||
|
receiver: { isGroup: true, connectionId: this.gameRoomService.gameRoomId } as SignalRClient,
|
||||||
|
from: { isGroup: false, connectionId: this.loginUserService.userAccess.signalRConnectionId },
|
||||||
|
actionType: 'heroes',
|
||||||
|
actionName: 'updateAll',
|
||||||
|
} as SignalRMessage;
|
||||||
|
message.parameters = { heros: JSON.stringify(this.info.heros) };
|
||||||
|
this.gameRoomService.sendMessage(message).pipe(first()).subscribe(result => {
|
||||||
|
});
|
||||||
|
this.broadcastMobsInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public broadcastHeroAction(action: string, extraValue: any = null) {
|
||||||
|
let parameters = {};
|
||||||
|
parameters['tabId'] = this.loginUserService.sessionTabId;
|
||||||
|
parameters['extraValue'] = JSON.stringify(extraValue);
|
||||||
|
this.broadcastMessage('heroAction', action, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public broadcastHeroInfoToAll(hero: MD2HeroInfo, fromDashboard: boolean = false) {
|
||||||
|
let message = {
|
||||||
|
receiver: { isGroup: true, connectionId: this.gameRoomService.gameRoomId } as SignalRClient,
|
||||||
|
from: { isGroup: fromDashboard, connectionId: fromDashboard ? this.gameRoomService.gameRoomId : hero.playerInfo.signalRClientId },
|
||||||
|
actionType: 'hero',
|
||||||
|
actionName: 'update',
|
||||||
|
} as SignalRMessage;
|
||||||
|
message.parameters = { hero: JSON.stringify(hero) };
|
||||||
|
this.gameRoomService.sendMessage(message).pipe(first()).subscribe(result => {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public broadcastHeroInfoToOwner(hero: MD2HeroInfo) {
|
||||||
|
let message = {
|
||||||
|
receiver: { isGroup: false, connectionId: hero.playerInfo.signalRClientId } as SignalRClient,
|
||||||
|
from: { isGroup: true, connectionId: this.gameRoomService.gameRoomId },
|
||||||
|
actionType: 'hero',
|
||||||
|
actionName: 'updateMyHero',
|
||||||
|
} as SignalRMessage;
|
||||||
|
message.parameters = { hero: JSON.stringify(hero) };
|
||||||
|
this.gameRoomService.sendMessage(message).pipe(first()).subscribe(result => {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `sessionId` = null means broadcast to all
|
||||||
|
*/
|
||||||
|
public broadcastMessage(actionType: string,
|
||||||
|
actionName: string,
|
||||||
|
parameters: { [key: string]: string; } = {},
|
||||||
|
sessionId: string = null) {
|
||||||
|
let message = {
|
||||||
|
receiver: { isGroup: !sessionId, connectionId: sessionId } as SignalRClient,
|
||||||
|
from: { isGroup: false, connectionId: this.loginUserService.userAccess.signalRConnectionId },
|
||||||
|
actionType: actionType,
|
||||||
|
actionName: actionName,
|
||||||
|
parameters: parameters
|
||||||
|
} as SignalRMessage;
|
||||||
|
|
||||||
|
if (sessionId == null) {
|
||||||
|
message.receiver = { isGroup: true, connectionId: this.gameRoomService.gameRoomId } as SignalRClient
|
||||||
|
} else {
|
||||||
|
message.receiver = { isGroup: false, connectionId: this.gameRoomService.gameRoomId } as SignalRClient
|
||||||
|
}
|
||||||
|
this.gameRoomService.sendMessage(message).pipe(first()).subscribe(result => {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public broadcastGameInfo() {
|
||||||
|
let parameters = {};
|
||||||
|
if (this.info.boss) {
|
||||||
|
this.info.boss.md2Service = undefined;
|
||||||
|
}
|
||||||
|
parameters['gameInfo'] = JSON.stringify(this.info);
|
||||||
|
|
||||||
|
if (this.info.boss) {
|
||||||
|
this.info.boss.md2Service = this;
|
||||||
|
}
|
||||||
|
this.broadcastMessage('GameRoom', 'update', parameters);
|
||||||
|
}
|
||||||
|
broadcastFetchGameInfo() {
|
||||||
|
this.broadcastMessage('GameRoom', 'getGameInfo', {});
|
||||||
|
}
|
||||||
|
public broadcastRoundPhase() {
|
||||||
|
let parameters = {};
|
||||||
|
parameters['phase'] = JSON.stringify(this.info.roundPhase);
|
||||||
|
this.broadcastMessage('GameRoom', 'phase', parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public broadcastMobsInfo() {
|
||||||
|
let parameters = {};
|
||||||
|
parameters['roamingMonsters'] = JSON.stringify(this.info.roamingMonsters);
|
||||||
|
parameters['mobs'] = JSON.stringify(this.info.mobs);
|
||||||
|
this.broadcastMessage('mobs', 'update', parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public broadcastMyHeroInfo() {
|
||||||
|
this.broadcastHeroInfoToAll(this.playerHero);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #endregion Public Methods (27)
|
// #endregion Public Methods (27)
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -491,7 +644,7 @@ export class MD2GameInfo {
|
|||||||
|
|
||||||
this.mobs = this.mobs.map(m => new MobInfo(m));
|
this.mobs = this.mobs.map(m => new MobInfo(m));
|
||||||
this.roamingMonsters = this.roamingMonsters.map(m => new MobInfo(m));
|
this.roamingMonsters = this.roamingMonsters.map(m => new MobInfo(m));
|
||||||
if (this.boss.info) {
|
if (this.boss && this.boss.info) {
|
||||||
this.boss.info = new MobInfo(this.boss.info);
|
this.boss.info = new MobInfo(this.boss.info);
|
||||||
}
|
}
|
||||||
this.heros = this.heros.map(h => new MD2HeroInfo(h));
|
this.heros = this.heros.map(h => new MD2HeroInfo(h));
|
||||||
@ -502,6 +655,7 @@ export class MD2GameInfo {
|
|||||||
public mobs: MobInfo[] = [];
|
public mobs: MobInfo[] = [];
|
||||||
public roamingMonsters: MobInfo[] = [];
|
public roamingMonsters: MobInfo[] = [];
|
||||||
public heros: MD2HeroInfo[] = [];
|
public heros: MD2HeroInfo[] = [];
|
||||||
|
public disconnectedHeroes: MD2HeroInfo[] = [];
|
||||||
public round = 1;
|
public round = 1;
|
||||||
public roundPhase: RoundPhase = RoundPhase.HeroPhase;
|
public roundPhase: RoundPhase = RoundPhase.HeroPhase;
|
||||||
public showAttackBtn: boolean = false;
|
public showAttackBtn: boolean = false;
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
import { Injectable } from "@angular/core";
|
|
||||||
import { MD2StateService } from "./md2-state.service";
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class MD2SpawnMobService {
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
constructor(
|
|
||||||
public stateService: MD2StateService,) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -23,18 +23,19 @@ export class GameRoomService {
|
|||||||
return {
|
return {
|
||||||
name: this.loginUserService.userAccess.firstName,
|
name: this.loginUserService.userAccess.firstName,
|
||||||
id: this.loginUserService.userAccess.memberId,
|
id: this.loginUserService.userAccess.memberId,
|
||||||
signalRClientId: this.loginUserService.userAccess.signalRSessionId,
|
signalRClientId: this.loginUserService.userAccess.signalRConnectionId,
|
||||||
isPlayer: true,
|
isPlayer: true,
|
||||||
gameRoomId: this.gameRoomId,
|
gameRoomId: this.gameRoomId,
|
||||||
tabId: this.loginUserService.sessionTabId
|
tabId: this.loginUserService.sessionTabId
|
||||||
} as IGamePlayer;
|
} as IGamePlayer;
|
||||||
}
|
}
|
||||||
createGameRoom(name: string) {
|
createGameRoom(name: string) {
|
||||||
let gameRoom = this.currentPlayer();
|
//Using current player to create game room
|
||||||
gameRoom.gameRoomId = gameRoom.id;
|
let currentPlayer = this.currentPlayer();
|
||||||
this.gameRoomId = gameRoom.id;
|
currentPlayer.gameRoomId = currentPlayer.id;
|
||||||
|
this.gameRoomId = currentPlayer.id;
|
||||||
this.http.post<boolean>(GAME_ROOM_URL,
|
this.http.post<boolean>(GAME_ROOM_URL,
|
||||||
JSON.stringify(gameRoom), {
|
JSON.stringify(currentPlayer), {
|
||||||
headers: {
|
headers: {
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|||||||
@ -14,7 +14,7 @@ export class LoginUserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setSignalRConnectionId(id: string) {
|
setSignalRConnectionId(id: string) {
|
||||||
this.userAccess.signalRSessionId = id;
|
this.userAccess.signalRConnectionId = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get sessionTabId(): string {
|
public get sessionTabId(): string {
|
||||||
|
|||||||
@ -15,7 +15,7 @@ const SIGNAL_R_URL = (id: string = null) => { return `${environment.apiUrl}/${id
|
|||||||
})
|
})
|
||||||
export class SignalRService {
|
export class SignalRService {
|
||||||
ReceivedSignalRMessageSubject = new Subject<SignalRMessage>();
|
ReceivedSignalRMessageSubject = new Subject<SignalRMessage>();
|
||||||
signalRMessageConnSubject = new Subject<any>();
|
signalRMessageConnSubject = new Subject<SignalRConnectionState>();
|
||||||
private hubConnection: signalR.HubConnection
|
private hubConnection: signalR.HubConnection
|
||||||
constructor(
|
constructor(
|
||||||
private loginUserService: LoginUserService,
|
private loginUserService: LoginUserService,
|
||||||
@ -42,6 +42,7 @@ export class SignalRService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
public startSignalRConnection(gameRoomId: string = '') {
|
public startSignalRConnection(gameRoomId: string = '') {
|
||||||
|
this.signalRMessageConnSubject.next({ status: 'connecting' });
|
||||||
if (!this.loginUserService.sessionTabId) {
|
if (!this.loginUserService.sessionTabId) {
|
||||||
this.loginUserService.sessionTabId = UuidUtils.generate();
|
this.loginUserService.sessionTabId = UuidUtils.generate();
|
||||||
}
|
}
|
||||||
@ -65,13 +66,21 @@ export class SignalRService {
|
|||||||
.withUrl(`${SIGNAL_R_URL('GameRoomHub')}?${params.toString()}`)
|
.withUrl(`${SIGNAL_R_URL('GameRoomHub')}?${params.toString()}`)
|
||||||
.withAutomaticReconnect()
|
.withAutomaticReconnect()
|
||||||
.build();
|
.build();
|
||||||
|
this.registerHubConnectionLifecycleHandlers();
|
||||||
let me = this
|
let me = this
|
||||||
this.hubConnection
|
this.hubConnection
|
||||||
.start()
|
.start()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
me.setSignalRConnectionId(this.hubConnection.connectionId);
|
me.setSignalRConnectionId(this.hubConnection.connectionId);
|
||||||
|
this.signalRMessageConnSubject.next({
|
||||||
|
status: 'connected',
|
||||||
|
connectionId: this.hubConnection.connectionId
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log('Error while starting connection: ' + err);
|
||||||
|
this.signalRMessageConnSubject.next({ status: 'error', error: err });
|
||||||
})
|
})
|
||||||
.catch(err => console.log('Error while starting connection: ' + err))
|
|
||||||
this.hubConnection.on("ReceivedMessage", (jsonString) => {
|
this.hubConnection.on("ReceivedMessage", (jsonString) => {
|
||||||
this.BroadcastAPIMessageReceive(JSON.parse(jsonString));
|
this.BroadcastAPIMessageReceive(JSON.parse(jsonString));
|
||||||
});
|
});
|
||||||
@ -79,12 +88,37 @@ export class SignalRService {
|
|||||||
}
|
}
|
||||||
public setSignalRConnectionId(connectionId: string) {
|
public setSignalRConnectionId(connectionId: string) {
|
||||||
|
|
||||||
this.loginUserService.userAccess.signalRSessionId = connectionId;
|
this.loginUserService.userAccess.signalRConnectionId = connectionId;
|
||||||
this.loginUserService.signalRInitialized.next(connectionId);
|
this.loginUserService.signalRInitialized.next(connectionId);
|
||||||
console.log('GameRoomHub start connection: ' + this.hubConnection.connectionId)
|
console.log('GameRoomHub start connection: ' + this.hubConnection.connectionId)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private registerHubConnectionLifecycleHandlers() {
|
||||||
|
this.hubConnection.onreconnecting(error => {
|
||||||
|
console.warn('SignalR reconnecting...', error);
|
||||||
|
this.signalRMessageConnSubject.next({ status: 'reconnecting', error });
|
||||||
|
});
|
||||||
|
|
||||||
|
this.hubConnection.onreconnected(connectionId => {
|
||||||
|
console.log('SignalR reconnected with new connectionId', connectionId);
|
||||||
|
this.setSignalRConnectionId(connectionId);
|
||||||
|
this.signalRMessageConnSubject.next({ status: 'reconnected', connectionId });
|
||||||
|
});
|
||||||
|
|
||||||
|
this.hubConnection.onclose(error => {
|
||||||
|
console.warn('SignalR connection closed', error);
|
||||||
|
this.clearSignalRConnectionId();
|
||||||
|
this.signalRMessageConnSubject.next({ status: 'closed', error });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private clearSignalRConnectionId() {
|
||||||
|
if (this.loginUserService?.userAccess) {
|
||||||
|
this.loginUserService.userAccess.signalRConnectionId = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BroadcastAPIMessageReceive(msg: SignalRMessage) {
|
BroadcastAPIMessageReceive(msg: SignalRMessage) {
|
||||||
@ -102,16 +136,23 @@ export class SignalRService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
export interface SignalRMessage {
|
export interface SignalRMessage {
|
||||||
from: SignalRSession;
|
from: SignalRClient;
|
||||||
receiver: SignalRSession;
|
receiver: SignalRClient;
|
||||||
actionType: string;
|
actionType: string;
|
||||||
actionName: string;
|
actionName: string;
|
||||||
parameters: { [key: string]: string; };
|
parameters: { [key: string]: string; };
|
||||||
|
value: any;
|
||||||
jsonValue: string;
|
jsonValue: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SignalRSession {
|
export interface SignalRClient {
|
||||||
sessionId: string;
|
connectionId: string;
|
||||||
name: string;
|
name: string;
|
||||||
isGroup: boolean;
|
isGroup: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SignalRConnectionState {
|
||||||
|
status: 'connecting' | 'connected' | 'reconnecting' | 'reconnected' | 'closed' | 'error';
|
||||||
|
connectionId?: string;
|
||||||
|
error?: any;
|
||||||
|
}
|
||||||
@ -24,3 +24,9 @@ p {
|
|||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
a,
|
||||||
|
input {
|
||||||
|
touch-action: manipulation;
|
||||||
|
}
|
||||||
|
|||||||
@ -6,8 +6,9 @@
|
|||||||
<title>真幸福的幸福小組</title>
|
<title>真幸福的幸福小組</title>
|
||||||
|
|
||||||
<base href="/">
|
<base href="/">
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
|
||||||
<link rel="icon" type="image/png" href="favicon.png">
|
<link rel="icon" type="image/png" href="favicon.png">
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
<script defer
|
<script defer
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user