ChurchAngular/src/app/services/MD2/md2.service.ts
Chris Chen ee6dc58a21 WIP
2025-11-14 07:28:22 -08:00

685 lines
25 KiB
TypeScript

import { Injectable } from '@angular/core';
import { AttackInfo, AttackTarget, CoreGameDarknessPhaseRule, DrawingBag, DrawingItem, HeroClass, IDarknessPhaseRule, MD2EnemyPhaseSpecialInfo, MD2EnemyPhaseSpecialRule, MD2HeroInfo, MD2Icon, MD2Rules, MobInfo, MobType, RoundPhase, TreasureItem, TreasureType } from '../../games/massive-darkness2/massive-darkness2.model';
import { first, map, reduce } from "rxjs/operators";
import { NbDialogService, NbThemeService } from '@nebular/theme';
import { Subject } from 'rxjs';
import { BossMicheal, BossReaper, IBossFight } from '../../games/massive-darkness2/massive-darkness2.model.boss';
import { ADIcon, MessageBoxConfig } from '../../ui/alert-dlg/alert-dlg.model';
import { NumberUtils } from '../../utilities/number-utils';
import { StringUtils } from '../../utilities/string-utils';
import { FileService } from '../file.service';
import { GameRoomService } from '../game-room.service';
import { LoginUserService } from '../login-user.service';
import { MsgBoxService } from '../msg-box.service';
import { SignalRService, SignalRClient, SignalRMessage } from '../signal-r.service';
import { MD2Logic } from '../../games/massive-darkness2/massive-darkness2.logic';
import { MD2InitService } from './md2-init.service';
import { ArrayUtils } from '../../utilities/array-utils';
import { DropDownOption } from '../../entity/dropDownOption';
import { GameBundle, MD2DiceSet, MD2MobInfo } from '../../games/massive-darkness2/massive-darkness2.db.model';
import { environment } from '../../../environments/environment';
const MD2_IMG_URL = (id: string = null) => { return `${environment.apiUrl}/Files/Images/MD2/Mobs${(id ? `${encodeURI(id)}` : '')}` };
@Injectable({
providedIn: 'root'
})
export class MD2Service {
// #region Properties (24)
private _highestPlayerLevel: number = 1;
private _playerAmount: number = 2;
public specialRule: MD2EnemyPhaseSpecialInfo;
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 enemyPhaseMobs: MobInfo[];
public enemyPhaseSubject = new Subject<MobInfo>();
public initialized = false;
public mobBeenKilledSubject = new Subject<MobInfo>();
public refreshUI$: Subject<void> = new Subject<void>();
public refreshTreasureBagSubject = new Subject<DrawingBag<TreasureItem>>();
public heroAttackingSubject = new Subject<MD2HeroInfo>();
public get heros() {
return this.info.heros;
}
public get roamingMonsters() {
return this.info.roamingMonsters;
}
public get mobs() {
return this.info.mobs;
}
public get allRoamingMonsterInfos() {
return this.roamingMobInfos;
}
public get allMobInfos() {
return this.mobInfos;
}
// #endregion Properties (24)
// #region Constructors (1)
constructor(
public fileService: FileService,
public msgBoxService: MsgBoxService,
public gameRoomService: GameRoomService,
public loginUserService: LoginUserService,
public signalRService: SignalRService,
public dlgService: NbDialogService,
public themeService: NbThemeService
) {
this.darknessPhaseRule = new CoreGameDarknessPhaseRule();
this.info = new MD2GameInfo();
this.darknessPhaseRule.addTreasureToken.subscribe(treasureType => {
this.addTreasure(treasureType, 1);
});
this.specialRule = new MD2EnemyPhaseSpecialInfo();
}
// #endregion Constructors (1)
// #region Public Getters And Setters (5)
public get highestPlayerLevel(): number {
if (this.heros.length > 0) {
return Math.max(...this.heros.map(h => h.level));
} else {
return 1;
}
}
public get playerAmount(): number {
if (this.heros.length > 0) {
return this.heros.length;
} else {
return 1;
}
}
public get currentActivateHero(): MD2HeroInfo {
return this.info.heros.find(h => h.uiActivating);
}
// #endregion Public Getters And Setters (5)
// #region Public Methods (27)
public addTreasure(type: TreasureType, amount: number = 1) {
this.treasureBag.AddItem(new TreasureItem(type, amount));
this.refreshTreasureBagSubject.next(this.treasureBag);
}
public darknessPhase() {
this.heros.forEach(hero => {
hero.remainActions = 3;
this.broadcastHeroInfoToOwner(hero);
});
this.info.roundPhase = RoundPhase.HeroPhase;
if (!this.info.isBossFight) {
this.info.round++;
if (this.darknessPhaseRule.runDarknessPhase()) {
this.msgBoxService.show(`${NumberUtils.Ordinal(this.info.round)} Hero Phase`, { icon: ADIcon.INFO });
}
} else {
this.info.boss.darknessPhase();
this.msgBoxService.show(`Boss Fight - ${NumberUtils.Ordinal(this.info.boss.rounds)} Hero Phase`, { icon: ADIcon.INFO });
}
//this.runNextPhase();
}
public spawnMob(isRoamingMonster: boolean, mobName: string = null) {
let mobDeck = null as DrawingBag<MobInfo>;
let level = 1;
if (this.highestPlayerLevel < 3) {
} else if (this.highestPlayerLevel < 5) {
level = 3;
} else {
level = 5;
}
if (isRoamingMonster) {
mobDeck = this.roamingMobDeck;
} else {
mobDeck = this.mobDeck;
}
if (mobDeck.drawingItems.filter(m => (m as MobInfo).level == level)
.map(d => d.drawingWeight).reduce((a, b) => a + b, 0) == 0) {
mobDeck.RestoreRemoveItems();
}
let newSpawnMob = null as MobInfo;
if (mobName) {
newSpawnMob = new MobInfo(mobDeck.DrawAndRemove(1, m => m.level == level && m.name == mobName)[0]);
} else {
newSpawnMob = new MobInfo(mobDeck.DrawAndRemove(1, m => m.level == level)[0]);
}
let exitingMob = isRoamingMonster ? this.roamingMonsters.find(m => m.name == newSpawnMob.name) : this.mobs.find(m => m.name == newSpawnMob.name);
if (exitingMob) {
exitingMob.level = newSpawnMob.level;
exitingMob.hp = newSpawnMob.hp;
exitingMob.imageUrl = newSpawnMob.imageUrl;
exitingMob.attackInfos = newSpawnMob.attackInfos;
exitingMob.defenseInfo = newSpawnMob.defenseInfo;
exitingMob.skills = newSpawnMob.skills;
} else {
if (isRoamingMonster) {
newSpawnMob = this.generateMob(isRoamingMonster, newSpawnMob.name, level);
this.roamingMonsters.push(newSpawnMob);
} else {
newSpawnMob = this.generateMob(isRoamingMonster, newSpawnMob.name, level);
this.mobs.push(newSpawnMob);
}
newSpawnMob.carriedTreasure = this.treasureBag.DrawAndRemove(newSpawnMob.rewardTokens);
this.refreshTreasureBagSubject.next(this.treasureBag);
}
newSpawnMob.imageUrl = this.mobImage(newSpawnMob.name, newSpawnMob.level, isRoamingMonster);
return { exitingMob, mob: newSpawnMob };
}
private generateMob(isRoamingMonster: boolean, mobName: string, level: number) {
let dbMobInfo = isRoamingMonster ? this.allRoamingMonsterInfos.find(m => m.name == mobName) : this.allMobInfos.find(m => m.name == mobName);
let levelInfo = dbMobInfo.mobLevelInfos.find(l => l.level <= level);
let skills = dbMobInfo.skills.filter(s => s.level <= level).sort((a, b) => b.seq - a.seq);
//Distinct by SkillType and Skill Name, take the one with the highest level
let mobInfo = new MobInfo({
name: dbMobInfo.name,
hp: levelInfo.hpPerHero,
hpPerHero: levelInfo.hpPerHero,
level: level,
rewardTokens: levelInfo.rewardTokens,
defenseInfo: levelInfo.defenceInfo,
type: dbMobInfo.type,
skills: []
});
for (let i = 0; i < skills.length; i++) {
const skill = skills[i];
if (!mobInfo.skills.find(s => s.type == skill.type && s.name == skill.name)) {
mobInfo.skills.push(skill);
}
}
mobInfo.skills = mobInfo.skills.sort((a, b) => b.seq - a.seq);
switch (dbMobInfo.type) {
case MobType.Mob:
mobInfo.leaderImgUrl = mobInfo.leaderImgUrl || MD2_IMG_URL(`/${GameBundle[dbMobInfo.from]}/Mobs/${mobInfo.name}/Leader.png`);
mobInfo.minionImgUrl = mobInfo.minionImgUrl || MD2_IMG_URL(`/${GameBundle[dbMobInfo.from]}/Mobs/${mobInfo.name}/Minion.png`);
break;
case MobType.RoamingMonster:
mobInfo.leaderImgUrl = mobInfo.leaderImgUrl || MD2_IMG_URL(`/${GameBundle[dbMobInfo.from]}/RoamingMonsters/${mobInfo.name}/Stand.png`);
mobInfo.minionImgUrl = null;
break;
case MobType.Boss:
mobInfo.leaderImgUrl = mobInfo.leaderImgUrl || MD2_IMG_URL(`/Boss/${mobInfo.name}-Stand.png`);
mobInfo.minionImgUrl = null;
break;
default:
break;
}
mobInfo.fixedCarriedTreasure = [];
levelInfo.fixedRareTreasure > 0 && mobInfo.fixedCarriedTreasure.push(new TreasureItem(TreasureType.Rare, levelInfo.fixedRareTreasure));
levelInfo.fixedEpicTreasure > 0 && mobInfo.fixedCarriedTreasure.push(new TreasureItem(TreasureType.Epic, levelInfo.fixedEpicTreasure));
levelInfo.fixedLegendTreasure > 0 && mobInfo.fixedCarriedTreasure.push(new TreasureItem(TreasureType.Legendary, levelInfo.fixedLegendTreasure));
switch (dbMobInfo.type) {
case MobType.Mob:
//Maybe add more mobs later
mobInfo.mobAmount = this.playerAmount + 1;
break;
case MobType.RoamingMonster:
case MobType.Boss:
mobInfo.hp = levelInfo.hpPerHero * this.playerAmount;
mobInfo.unitRemainHp = mobInfo.hp;
mobInfo.mobAmount = 0;
mobInfo.attackInfos = [this.getAttackInfo(levelInfo.attackInfo)];
let altAttackInfo = levelInfo.alterAttackInfo;
if (altAttackInfo
&& (altAttackInfo.black > 0 || altAttackInfo.blue > 0 || altAttackInfo.green > 0 || altAttackInfo.orange > 0 || altAttackInfo.red > 0 || altAttackInfo.yellow > 0)
) {
mobInfo.attackInfos.push(this.getAttackInfo(altAttackInfo));
}
break;
}
return mobInfo;
}
private getAttackInfo(attackInfo: MD2DiceSet): AttackInfo {
return new AttackInfo(attackInfo.type as unknown as MD2Icon, attackInfo.yellow, attackInfo.orange, attackInfo.red, attackInfo.black);
}
public enemyPhase(triggerSpecialRule: boolean = true) {
//this.msgBoxService
//Draw a special rule
this.enemyPhaseMobs = this.roamingMonsters.concat(this.mobs);
if (this.mobs.length > 0 && triggerSpecialRule) {
let specialRuleDrawingBag = new DrawingBag<MD2EnemyPhaseSpecialRule>(this.specialRule.specialRules);
let specialRule = specialRuleDrawingBag.Draw(1)[0];
this.specialRule.specialRule = specialRule;
if (specialRule.description) {
this.themeService.changeTheme('dark');
this.msgBoxService.show(specialRule.title, { text: specialRule.description, icon: ADIcon.WARNING })
.pipe(first()).subscribe(result => {
this.enemyPhase(false);
});
return;
} else {
this.specialRule.specialRule = null;
}
}
if (this.enemyPhaseMobs.length > 0) {
this.enemyPhaseMobs = ArrayUtils.Shuffle(this.enemyPhaseMobs);
//this.showEnemyPhaseAction();
this.enemyPhaseSubject.next(this.enemyPhaseMobs[0]);
} else {
this.runNextPhase();
}
}
public enterBossFight() {
this.msgBoxService.showInputbox('Boss Fight', 'Choose the boss', {
inputType: 'dropdown',
dropDownOptions: [new DropDownOption('The Reaper', 'The Reaper'), new DropDownOption('Michael - The Corrupted Archangel', 'Michael - The Corrupted Archangel')]
}).pipe(first()).subscribe(result => {
if (result) {
this.info.mobs = [];
this.info.roamingMonsters = [];
if (result == 'The Reaper') {
this.info.boss = new BossReaper(this);
} else {
this.info.boss = new BossMicheal(this);
}
this.info.roamingMonsters = [];
this.info.mobs = [];
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.unitRemainHp = this.info.boss.info.hp;
this.refreshUI$.next();
this.info.boss.prepareForBossFight();
this.levelUpPhase(false);
this.heros.forEach(hero => {
hero.hp = hero.hpMaximum;
hero.mp = hero.mpMaximum;
hero.remainActions = 3;
hero.uiActivating = false;
hero.uiBossFight = true;
});
this.broadcastGameInfo();
}
});
//this.sendMsgboxMsg
}
public activateBoss() {
this.info.boss.activating();
}
public fileList(folderPath: string) {
return this.fileService.FileList('Images/MD2/' + folderPath);
}
public heroFullName(hero: MD2HeroInfo) {
return MD2Logic.heroFullName(hero);
}
public levelUpPhase(runNextPhase: boolean = true) {
for (let i = 0; i < this.heros.length; i++) {
const hero = this.heros[i];
let levelUpInfo = MD2Rules.checkCoreGameLevelup(hero.level, hero.exp);
while (levelUpInfo != null) {
hero.level = levelUpInfo.level;
hero.hp += levelUpInfo.extraHp;
hero.hpMaximum += levelUpInfo.extraHp;
hero.mp += levelUpInfo.extraMp;
hero.mpMaximum += levelUpInfo.extraMp;
hero.exp = levelUpInfo.currentExp;
this.broadcastHeroInfoToOwner(hero);
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);
}
}
this.refreshUI$.next();
if (runNextPhase) {
this.runNextPhase();
}
}
public mobImage(name: string, level: number, isRoamingMonsters: boolean) {
if (level < 3) {
level = 1;
} else if (level < 5) {
level = 2;
} else {
level = 3;
}
if (isRoamingMonsters) {
return this.imgUrl(`Mobs/CoreGame/RoamingMonsters/${name}/${level}.png`);
} else {
return this.imgUrl(`Mobs/CoreGame/Mobs/${name}/${level}.png`);
}
}
public playerJoin(hero: MD2HeroInfo) {
hero.playerInfo = this.gameRoomService.currentPlayer();
hero.level = 1;
hero.hp = hero.hpMaximum;
hero.mp = hero.mpMaximum;
hero.exp = 0;
this.playerHero = hero;
// let message = {
// receiver: { isGroup: true, sessionId: this.gameRoomService.gameRoomId } as SignalRSession,
// from: { isGroup: false, sessionId: this.loginUserService.userAccess.signalRSessionId },
// actionType: 'hero',
// actionName: 'join',
// } as SignalRMessage;
// message.parameters = { hero: JSON.stringify(hero) };
// this.gameRoomService.sendMessage(message).pipe(first()).subscribe(result => {
// });
}
public runNextPhase() {
this.info.roundPhase++;
switch (this.info.roundPhase) {
case RoundPhase.HeroPhase:
//HeroPhase will be handled in the darkness phase
// this.heros.forEach(hero => {
// hero.remainActions = 3;
// this.broadcastHeroInfoToOwner(hero);
// });
break;
case RoundPhase.EnemyPhase:
this.enemyPhase();
break;
case RoundPhase.LevelUpPhase:
this.levelUpPhase();
break;
case RoundPhase.DarknessPhase:
this.darknessPhase();
this.themeService.changeTheme('default');
break;
default: break;
}
let parameters = {};
parameters['phase'] = this.info.roundPhase;
this.broadcastMessage('roundPhase', '', parameters);
}
public sendMsgboxMsg(playerSessionId: string, msg: Partial<MessageBoxConfig>) {
let message = {
receiver: { isGroup: false, connectionId: playerSessionId } as SignalRClient,
from: { isGroup: false, connectionId: this.loginUserService.userAccess.signalRConnectionId },
actionType: 'message',
actionName: 'popup',
} as SignalRMessage;
message.parameters = { msg: JSON.stringify(msg) };
this.gameRoomService.sendMessage(message).pipe(first()).subscribe(result => {
});
}
public getTargetHerosByFilter(targetType: AttackTarget, onlyOne: boolean = false) {
return MD2Logic.getTargetHerosByFilter(this.info.heros, targetType, onlyOne);
}
public getTargetHerosHtml(beenAttackedHero: MD2HeroInfo[]) {
return MD2Logic.getTargetHerosHtml(beenAttackedHero);
}
public drawingHealFountain() {
let result = new DrawingBag<DrawingItem>([new DrawingItem('Heal Fountain', '3 HP', '', 2), new DrawingItem('Heal Fountain', '4 HP', '', 1), new DrawingItem('Heal Fountain', 'Full HP', '', 1)])
.Draw(1)[0];
switch (result.description) {
case '3 HP':
this.currentActivateHero.hp = Math.min(this.currentActivateHero.hp + 3, this.currentActivateHero.hpMaximum);
break;
case '4 HP':
this.currentActivateHero.hp = Math.min(this.currentActivateHero.hp + 4, this.currentActivateHero.hpMaximum);
break;
case 'Full HP':
this.currentActivateHero.hp = this.currentActivateHero.hpMaximum;
break;
default:
break;
}
this.broadcastHeroInfoToAll(this.currentActivateHero, true);
//this.broadcastHeroInfoToOwner(this.currentActivateHero);
this.msgBoxService.show(
this.imgHtml('/Fountain/Cover.png', '')
, { text: `${this.currentActivateHero.heroFullName} Recovered ${result.description}.` });
}
public openTreasureChest() {
let result = new DrawingBag<DrawingItem>([
new DrawingItem('Common', `${this.treasureImageHtml(TreasureType.Common)} x 2`, '', 10),
new DrawingItem('Open Treasure Chest', `${this.treasureImageHtml(TreasureType.Rare)} x 2`, '', 5),
])
.Draw(1)[0];
this.msgBoxService.show(
this.imgHtml('/TreasureChest/SmallTresureChest.jpg', ''), { text: `${this.currentActivateHero.heroFullName} gets ${result.description}.` });
}
public openGreatTreasureChest() {
let result = new DrawingBag<DrawingItem>([
new DrawingItem('Common', `${this.treasureImageHtml(TreasureType.Rare)} x 3`, '', 3),
new DrawingItem('Open Treasure Chest', `${this.treasureImageHtml(TreasureType.Epic)} x 3`, '', 1),
]).Draw(1)[0];
this.msgBoxService.show(
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)
}
export class MD2GameInfo {
/**
*
*/
constructor(
config: Partial<MD2GameInfo> = undefined
) {
if (config) {
Object.assign(this, config);
this.mobs = this.mobs.map(m => new MobInfo(m));
this.roamingMonsters = this.roamingMonsters.map(m => new MobInfo(m));
if (this.boss && this.boss.info) {
this.boss.info = new MobInfo(this.boss.info);
}
this.heros = this.heros.map(h => new MD2HeroInfo(h));
}
}
public isBossFight: boolean = false;
public mobs: MobInfo[] = [];
public roamingMonsters: MobInfo[] = [];
public heros: MD2HeroInfo[] = [];
public disconnectedHeroes: MD2HeroInfo[] = [];
public round = 1;
public roundPhase: RoundPhase = RoundPhase.HeroPhase;
public showAttackBtn: boolean = false;
public boss: IBossFight;
}