Chris Chen dfc1f269a0 Stable
2024-04-06 07:26:12 -07:00

283 lines
11 KiB
TypeScript

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<void> = new Subject<void>();
/**
*
*/
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 `<img src="${this.imgUrl(imgFile)}" class='${cssClass}'>`
}
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 <b>same zone with ${this.md2Service.heroFullName(this.md2Service.currentActivateHero)}</b> 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<void> = new Subject<void>();
/**
*
*/
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() {
}
}