import { ChangeDetectorRef, Injectable } from "@angular/core"; import { ActivatedRoute } from "@angular/router"; import { Subject } from "rxjs"; import { first, takeUntil } from "rxjs/operators"; import { MD2GameInfo, MD2Service } from "../../services/MD2/md2.service"; import { SignalRMessage } from "../../services/signal-r.service"; import { StateService } from "../../services/state.service"; import { ADIcon, MessageBoxConfig } from "../../ui/alert-dlg/alert-dlg.model"; import { MD2HeroInfo, MD2Icon, MobInfo, RoundPhase } from "./massive-darkness2.model"; @Injectable() export abstract class MD2Base { MD2Icon = MD2Icon; public get gameInfo() { return this.md2Service.info; } protected isHeroDashboard: boolean = false; protected roomId: string; protected destroy$: Subject = new Subject(); /** * */ constructor( protected md2Service: MD2Service, protected stateService: StateService, protected route: ActivatedRoute, protected cdRef: ChangeDetectorRef, ) { } ngOnInit(): void { this.route.paramMap.pipe(first()).subscribe(params => { if (params.get('roomId')) { this.roomId = params.get('roomId'); } }); this.md2Service.refreshUI$.pipe(takeUntil(this.destroy$)).subscribe(result => { this.cdRef.detectChanges(); }); this.stateService.loginUserService.signalRInitialized.pipe(first()).subscribe(result => { console.log('signalRInitialized'); this.signalRInitialized(); }); this.md2Service.signalRService.ReceivedSignalRMessageSubject.pipe(takeUntil(this.destroy$)).subscribe(result => this.handleSignalRCallback(result)); } ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); } signalRInitialized() { } imgUrl(imgPath: string) { return this.md2Service.stateService.imgUrl(imgPath); } fileList(folderPath: string) { return this.md2Service.fileList(folderPath); } iconHtml(icon: MD2Icon, cssClass = '') { return this.md2Service.stateService.iconHtml(icon, cssClass); } imgHtml(imgFile: string, cssClass = '') { return `` } detectChanges() { if (!this.cdRef['destroyed']) { this.cdRef.detectChanges(); this.refreshUI(); this.md2Service.refreshUI$.next(); } } abstract refreshUI(); handleSignalRCallback(message: SignalRMessage): void { // if (message.from.isGroup) { // if (!this.isHeroDashboard) return; // } else { // if (this.isHeroDashboard && this.md2Service.playerHero.playerInfo.signalRClientId == message.from.sessionId) return; // } switch (message.actionType) { case 'hero': let heroInfo = new MD2HeroInfo(JSON.parse(message.parameters['hero'])); switch (message.actionName) { case 'join': this.md2Service.heros.push(heroInfo); break; case 'update': let exitingHero = this.md2Service.heros.find(h => h.playerInfo.signalRClientId == heroInfo.playerInfo.signalRClientId); if (exitingHero) { let activateBoss = exitingHero.uiActivating && !heroInfo.uiActivating; this.md2Service.heros[this.md2Service.heros.indexOf(exitingHero)] = heroInfo; if (this.isHeroDashboard && this.md2Service.stateService.playerHero.playerInfo.tabId == heroInfo.playerInfo.tabId) { this.md2Service.stateService.playerHero = heroInfo; } if (!this.isHeroDashboard && this.md2Service.info.isBossFight && activateBoss) { this.md2Service.activateBoss(); } } else { this.md2Service.heros.push(heroInfo); } if (!this.isHeroDashboard) { if (this.gameInfo.roundPhase == RoundPhase.HeroPhase) { if (!this.md2Service.heros.some(h => h.remainActions > 0) && !this.md2Service.heros.some(h => h.uiActivating)) { if (!this.md2Service.info.isBossFight) { if (this.md2Service.mobs.length > 0 || this.md2Service.roamingMonsters.length > 0) { this.md2Service.msgBoxService.show('Enemy Phase', { icon: ADIcon.WARNING }).pipe(first()).subscribe(result => { this.md2Service.runNextPhase(); }); } else { this.md2Service.runNextPhase(); } } } } } //Object.assign(heroInfo, exitingHero); break; case 'updateMyHero': if (this.isHeroDashboard) { this.md2Service.stateService.playerHero = heroInfo; } break; default: break; } this.detectChanges(); break; case 'GameRoom': switch (message.actionName) { case 'Leaving': this.md2Service.heros.splice(this.md2Service.heros.findIndex(h => h.playerInfo.tabId == message.from.sessionId)); this.detectChanges(); break; case 'update': if (this.isHeroDashboard) { this.md2Service.info = new MD2GameInfo(JSON.parse(message.parameters['gameInfo']) as MD2GameInfo); this.detectChanges(); } break; case 'phase': if (this.isHeroDashboard) { this.md2Service.info.roundPhase = JSON.parse(message.parameters['phase']); this.detectChanges(); } break; case 'sendJoinInfo': if (this.isHeroDashboard && this.md2Service.playerHero) { this.md2Service.playerHero.playerInfo.signalRClientId = message.parameters['signalrconnid']; this.md2Service.broadcastService.broadcastMyHeroInfo(); } break; default: break; } break; case 'message': switch (message.actionName) { case 'popup': let msg = JSON.parse(message.parameters['msg']) as MessageBoxConfig; this.md2Service.msgBoxService.show(msg.title, msg); break; default: break; } break; case 'roundPhase': switch (message.actionName) { case 'bossFight': this.gameInfo.isBossFight = true; break; default: this.gameInfo.roundPhase = Number.parseInt(message.parameters['phase']); break; } this.detectChanges(); break; case 'mobs': if (this.isHeroDashboard) { this.gameInfo.roamingMonsters = JSON.parse(message.parameters['roamingMonsters']); this.gameInfo.mobs = JSON.parse(message.parameters['mobs']); this.detectChanges(); } break; case 'heroAction': if (!this.isHeroDashboard) { //this.md2Service.currentActivateHero = this.md2Service.heros.find(h => h.playerInfo.tabId == message.parameters['tabId']); switch (message.actionName) { case 'attackAction': if (this.gameInfo.isBossFight) { this.md2Service.heroAttackingSubject.next(this.md2Service.currentActivateHero); } else { this.gameInfo.showAttackBtn = true; } break; case 'openDoor': //Door component listen for it break; case 'tradeAction': this.md2Service.msgBoxService.show('Trade and Equip', { text: `every one in the same zone with ${this.md2Service.heroFullName(this.md2Service.currentActivateHero)} may freely trade and equip items!`, icon: ADIcon.INFO }); break; default: //this.md2Service.roundPhase = Number.parseInt(message.parameters['phase']); break; } this.heroAction(this.md2Service.currentActivateHero, message.actionName); this.detectChanges(); } break; default: break; } } abstract heroAction(hero: MD2HeroInfo, action: string); } @Injectable() export abstract class MD2ComponentBase { protected roomId: string; protected destroy$: Subject = new Subject(); /** * */ constructor( protected md2Service: MD2Service, protected stateService: StateService, protected route: ActivatedRoute, protected cdRef: ChangeDetectorRef, ) { } ngOnInit(): void { this.md2Service.refreshUI$.pipe(takeUntil(this.destroy$)).subscribe(result => { this.cdRef.detectChanges(); }); } ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); } imgUrl(imgPath: string) { return this.md2Service.stateService.imgUrl(imgPath); } fileList(folderPath: string) { return this.md2Service.fileList(folderPath); } iconHtml(icon: MD2Icon, cssClass = '') { return this.md2Service.stateService.iconHtml(icon, cssClass); } detectChanges() { if (!this.cdRef['destroyed']) { this.cdRef.detectChanges(); this.refreshUI(); this.md2Service.refreshUI$.next(); } } refreshUI() { } }