Optmize
This commit is contained in:
parent
2ef9968920
commit
f30c41afba
@ -20,7 +20,7 @@ export interface LoginTokenViewModel {
|
||||
avatarImage: string;
|
||||
role: Role;
|
||||
cellGroup: PastoralDomain;
|
||||
signalRSessionId;
|
||||
signalRConnectionId;
|
||||
sessionTabId: string;
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ export interface IGamePlayer {
|
||||
isPlayer: boolean;
|
||||
signalRClientId: string;
|
||||
tabId: string;
|
||||
isDisconnected: boolean;
|
||||
}
|
||||
|
||||
export class GamePlayer implements IGamePlayer {
|
||||
@ -14,4 +15,5 @@ export class GamePlayer implements IGamePlayer {
|
||||
isPlayer: boolean;
|
||||
signalRClientId: 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 { MD2HeroInfo, MD2Icon, MobInfo, RoundPhase } from "./massive-darkness2.model";
|
||||
import { LoginUserService } from "../../services/login-user.service";
|
||||
import { GamePlayer } from "../games.model";
|
||||
|
||||
@Injectable()
|
||||
export abstract class MD2Base {
|
||||
@ -59,14 +60,14 @@ export abstract class MD2Base {
|
||||
}
|
||||
|
||||
imgUrl(imgPath: string) {
|
||||
return this.md2Service.stateService.imgUrl(imgPath);
|
||||
return this.md2Service.imgUrl(imgPath);
|
||||
}
|
||||
fileList(folderPath: string) {
|
||||
return this.md2Service.fileList(folderPath);
|
||||
}
|
||||
|
||||
iconHtml(icon: MD2Icon, cssClass = '') {
|
||||
return this.md2Service.stateService.iconHtml(icon, cssClass);
|
||||
return this.md2Service.iconHtml(icon, cssClass);
|
||||
}
|
||||
|
||||
imgHtml(imgFile: string, cssClass = '') {
|
||||
@ -82,12 +83,17 @@ export abstract class MD2Base {
|
||||
}
|
||||
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;
|
||||
// }
|
||||
if (message.from) {
|
||||
if (message.from.isGroup) {
|
||||
if (!this.isHeroDashboard) return;
|
||||
} else {
|
||||
if (this.isHeroDashboard && this.md2Service.playerHero?.playerInfo?.signalRClientId == message.from.connectionId) return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.isHeroDashboard) {
|
||||
|
||||
}
|
||||
switch (message.actionType) {
|
||||
case 'hero':
|
||||
let heroInfo = new MD2HeroInfo(JSON.parse(message.parameters['hero']));
|
||||
@ -101,7 +107,7 @@ export abstract class MD2Base {
|
||||
break;
|
||||
case 'updateMyHero':
|
||||
if (this.isHeroDashboard) {
|
||||
this.md2Service.stateService.playerHero = heroInfo;
|
||||
this.md2Service.playerHero = heroInfo;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -113,24 +119,42 @@ export abstract class MD2Base {
|
||||
case 'heroes':
|
||||
switch (message.actionName) {
|
||||
case 'updateAll':
|
||||
let allHeroes = (JSON.parse(message.parameters['heros']) as MD2HeroInfo[]).map(h => new MD2HeroInfo(h));
|
||||
//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));
|
||||
allHeroes.forEach(heroInfo => {
|
||||
this.updateHeroInfo(heroInfo);
|
||||
});
|
||||
if (this.isHeroDashboard) {
|
||||
let allHeroes = (JSON.parse(message.parameters['heros']) as MD2HeroInfo[]).map(h => new MD2HeroInfo(h));
|
||||
//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));
|
||||
allHeroes.forEach(heroInfo => {
|
||||
this.updateHeroInfo(heroInfo);
|
||||
});
|
||||
this.detectChanges();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'GameRoom':
|
||||
switch (message.actionName) {
|
||||
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();
|
||||
break;
|
||||
case 'update':
|
||||
if (this.isHeroDashboard) {
|
||||
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();
|
||||
}
|
||||
break;
|
||||
@ -140,10 +164,17 @@ export abstract class MD2Base {
|
||||
this.detectChanges();
|
||||
}
|
||||
break;
|
||||
case 'getGameInfo':
|
||||
|
||||
if (!this.isHeroDashboard) {
|
||||
|
||||
this.md2Service.broadcastGameInfo();
|
||||
}
|
||||
break;
|
||||
case 'sendJoinInfo':
|
||||
if (this.isHeroDashboard && this.md2Service.playerHero) {
|
||||
this.md2Service.playerHero.playerInfo.signalRClientId = message.parameters['signalrconnid'];
|
||||
this.md2Service.broadcastService.broadcastMyHeroInfo();
|
||||
this.md2Service.broadcastMyHeroInfo();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -212,14 +243,15 @@ export abstract class MD2Base {
|
||||
}
|
||||
}
|
||||
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) {
|
||||
//For boss fight, if the hero finished activating, activate the boss
|
||||
let activateBoss = exitingHero.uiActivating && !heroInfo.uiActivating;
|
||||
|
||||
this.md2Service.heros[this.md2Service.heros.indexOf(exitingHero)] = heroInfo;
|
||||
//My hero update
|
||||
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) {
|
||||
this.md2Service.activateBoss();
|
||||
@ -276,14 +308,14 @@ export abstract class MD2ComponentBase {
|
||||
this.destroy$.complete();
|
||||
}
|
||||
imgUrl(imgPath: string) {
|
||||
return this.md2Service.stateService.imgUrl(imgPath);
|
||||
return this.md2Service.imgUrl(imgPath);
|
||||
}
|
||||
fileList(folderPath: string) {
|
||||
return this.md2Service.fileList(folderPath);
|
||||
}
|
||||
|
||||
iconHtml(icon: MD2Icon, cssClass = '') {
|
||||
return this.md2Service.stateService.iconHtml(icon, cssClass);
|
||||
return this.md2Service.iconHtml(icon, cssClass);
|
||||
}
|
||||
detectChanges() {
|
||||
if (!this.cdRef['destroyed']) {
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
<div class="col-md-7">
|
||||
<div class="row">
|
||||
<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()">
|
||||
</adj-number-input>
|
||||
<md2-mob-attack-info [mob]="boss.info">
|
||||
|
||||
@ -52,7 +52,11 @@ export class BossFightComponent extends MD2ComponentBase {
|
||||
this.boss.activating();
|
||||
}
|
||||
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) {
|
||||
|
||||
@ -62,6 +66,9 @@ export class BossFightComponent extends MD2ComponentBase {
|
||||
let attackDamage = mobResult.uiWounds;
|
||||
if (attackDamage) {
|
||||
this.boss.info.hp -= attackDamage;
|
||||
if (this.boss.info.hp <= 0) {
|
||||
this.WIN();
|
||||
}
|
||||
this.cdRef.detectChanges();
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,7 +139,7 @@
|
||||
<!-- <img class="MD2HeroCard " src="{{imgUrl('Heros/'+className+'.jpg')}}" (click)="toggleFlip()"> -->
|
||||
|
||||
<!-- 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">
|
||||
<button nbButton hero class="action-btn" status="info" (click)="moveAction()"
|
||||
*ngIf="!showMoveAction">
|
||||
|
||||
@ -14,6 +14,7 @@ import { DebounceTimer } from '../../../utilities/timer-utils';
|
||||
import { HeroClass, MD2HeroInfo, MD2HeroProfile, MD2Icon } from '../massive-darkness2.model';
|
||||
import { MD2Base } from '../MD2Base';
|
||||
import { MD2HeroProfileService } from '../service/massive-darkness2.service';
|
||||
import { SignalRService } from '../../../services/signal-r.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-hero-dashboard',
|
||||
@ -70,6 +71,15 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
||||
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 {
|
||||
return this.heros[this.currentHeroIndex];
|
||||
}
|
||||
@ -82,6 +92,7 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
||||
protected route: ActivatedRoute,
|
||||
protected cdRef: ChangeDetectorRef,
|
||||
private msgBoxService: MsgBoxService,
|
||||
private signalRService: SignalRService
|
||||
) {
|
||||
super(md2Service, stateService, route, cdRef);
|
||||
this.isHeroDashboard = true;
|
||||
@ -93,6 +104,15 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
||||
|
||||
ngOnInit(): void {
|
||||
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() {
|
||||
@ -103,9 +123,7 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
||||
// }
|
||||
}
|
||||
initHero() {
|
||||
this.gameRoomService.gameRoomId = this.roomId;
|
||||
this.gameRoomService.joinGameRoom(this.roomId);
|
||||
if (!this.md2Service.heros.some(h => h.playerInfo.signalRClientId == this.stateService.loginUserService.userAccess.signalRSessionId)) {
|
||||
if (!this.md2Service.heros.some(h => h.playerInfo.signalRClientId == this.stateService.loginUserService.userAccess.signalRConnectionId)) {
|
||||
|
||||
this.msgBoxService.showInputbox('Select Hero Class', '', { dropDownOptions: this.classOptions, inputType: 'dropdown' })
|
||||
.pipe(first()).subscribe(heroClass => {
|
||||
@ -127,10 +145,11 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
||||
});
|
||||
}
|
||||
}
|
||||
className: string;
|
||||
|
||||
|
||||
|
||||
initClassHeroList(heroClass: HeroClass) {
|
||||
this.heros = [];
|
||||
this.className = HeroClass[heroClass];
|
||||
this.selectedHeroClass = heroClass;
|
||||
this.heroProfileService.getAll().pipe(first()).subscribe(result => {
|
||||
|
||||
@ -161,7 +180,7 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
||||
selectCurrentHero() {
|
||||
if (this.currentSelectingHero) {
|
||||
this.md2Service.playerJoin(this.currentSelectingHero);
|
||||
this.md2Service.broadcastService.broadcastMyHeroInfo();
|
||||
this.md2Service.broadcastMyHeroInfo();
|
||||
this.isSelectingHero = false;
|
||||
this.detectChanges();
|
||||
}
|
||||
@ -189,8 +208,12 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
||||
this.detectChanges();
|
||||
}
|
||||
|
||||
fetchGameInfo() {
|
||||
this.md2Service.broadcastFetchGameInfo();
|
||||
}
|
||||
|
||||
broadcastHeroInfo() {
|
||||
this.md2Service.broadcastService.broadcastMyHeroInfo();
|
||||
this.md2Service.broadcastMyHeroInfo();
|
||||
this.heroUpdateDebounceTimer.clearOut();
|
||||
}
|
||||
increaseRage() {
|
||||
@ -199,7 +222,7 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
||||
}
|
||||
}
|
||||
openDoor() {
|
||||
this.md2Service.broadcastService.broadcastHeroAction('openDoor');
|
||||
this.md2Service.broadcastHeroAction('openDoor');
|
||||
//this.showMoveAction = false;
|
||||
this.detectChanges();
|
||||
}
|
||||
@ -224,7 +247,7 @@ export class HeroDashboardComponent extends MD2Base implements OnInit {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this.md2Service.broadcastService.broadcastHeroAction(action);
|
||||
this.md2Service.broadcastHeroAction(action);
|
||||
this.reduceAction();
|
||||
}
|
||||
reduceAction() {
|
||||
|
||||
@ -59,20 +59,28 @@
|
||||
<div class="col-12" *ngFor="let hero of md2Service.heros">
|
||||
<label class='label mr-1'>{{hero.playerInfo.name}} ({{heroClassName(hero)}} -
|
||||
{{hero.name}})</label>
|
||||
<span class="badge badge-primary mr-1">Lv.:{{hero.level}}</span>
|
||||
<span class="badge badge-primary mr-1">HP: {{hero.hp}}/{{hero.hpMaximum}}</span>
|
||||
<span class="badge badge-primary mr-1">Mana: {{hero.mp}}/{{hero.mpMaximum}}</span>
|
||||
<span class="badge badge-success mr-1">Exp: {{hero.exp}}</span>
|
||||
<span class="badge badge-primary mr-1"
|
||||
(click)="adjustHeroValue(hero,'level')">Lv.:{{hero.level}}</span>
|
||||
<span class="badge badge-primary mr-1" (click)="adjustHeroValue(hero,'hp')">HP:
|
||||
{{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">
|
||||
<md2-icon [icon]="MD2Icon.FireToken" size="sm"></md2-icon> {{hero.fireToken}}
|
||||
</span>
|
||||
<span class="badge mr-1" *ngIf="hero.frozenToken">
|
||||
<md2-icon [icon]="MD2Icon.FrozenToken" size="sm"></md2-icon>{{hero.frozenToken}}
|
||||
</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>
|
||||
<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-warning mr-1"
|
||||
*ngIf="hero.playerInfo.isDisconnected">Disconnected</span>
|
||||
<!-- <span class="badge badge-success mr-1">{{hero.playerInfo.signalRClientId}}</span> -->
|
||||
|
||||
<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() {
|
||||
|
||||
}
|
||||
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() {
|
||||
if (this.md2Service.initialized == false) {
|
||||
@ -146,7 +171,7 @@ export class MassiveDarkness2Component extends MD2Base implements OnInit {
|
||||
this.md2Service.heros.forEach(hero => {
|
||||
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) {
|
||||
this.msgBoxService.showConfirmDeleteBox().pipe(first()).subscribe(result => {
|
||||
|
||||
@ -53,6 +53,7 @@ export interface IBossFight {
|
||||
imgUrl: string
|
||||
standUrl: string
|
||||
extraRules: string
|
||||
md2Service: MD2Service
|
||||
activating(): boolean
|
||||
prepareForBossFight(): void
|
||||
darknessPhase(): void
|
||||
@ -73,7 +74,7 @@ export abstract class BossFight implements IBossFight {
|
||||
extraRules: string
|
||||
protected subscription: Subscription
|
||||
|
||||
constructor(protected md2Service: MD2Service) {
|
||||
constructor(public md2Service: MD2Service) {
|
||||
this.rounds = 1;
|
||||
}
|
||||
activating(): boolean {
|
||||
@ -105,26 +106,26 @@ export abstract class BossFight implements IBossFight {
|
||||
|
||||
}
|
||||
export class BossMicheal extends BossFight {
|
||||
constructor(protected md2Service: MD2Service) {
|
||||
constructor(public md2Service: 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.imgUrl = md2Service.stateService.imgUrl('/Boss/Michael - The Corrupted Archangel.jpg');
|
||||
this.standUrl = md2Service.stateService.imgUrl('/Boss/Michael.png');
|
||||
this.imgUrl = md2Service.imgUrl('/Boss/Michael - The Corrupted Archangel.jpg');
|
||||
this.standUrl = md2Service.imgUrl('/Boss/Michael.png');
|
||||
|
||||
this.info = new MobInfo({
|
||||
description: this.name,
|
||||
type: MobType.Boss,
|
||||
hpPerHero: 15,
|
||||
level: 10,
|
||||
imageUrl: md2Service.stateService.imgUrl('/Boss/Michael.png')
|
||||
imageUrl: md2Service.imgUrl('/Boss/Michael.png')
|
||||
});
|
||||
if (!this.info.skills) {
|
||||
this.info.skills = [];
|
||||
}
|
||||
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).`,
|
||||
type: MobSkillType.Combat,
|
||||
skillRoll: 1
|
||||
@ -135,9 +136,9 @@ export class BossMicheal extends BossFight {
|
||||
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>` +
|
||||
`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)}.` +
|
||||
`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.stateService.iconHtml(MD2Icon.EnemyClaw)}/${this.md2Service.stateService.iconHtml(MD2Icon.EnemySkill)} the Hero takes 1 Wound and places 1 ${this.corruptionTokenHtml} on their Dashboard.`
|
||||
`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.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.iconHtml(MD2Icon.EnemyClaw)}/${this.md2Service.iconHtml(MD2Icon.EnemySkill)} the Hero takes 1 Wound and places 1 ${this.corruptionTokenHtml} on their Dashboard.`
|
||||
}
|
||||
activatedTimes: number
|
||||
acted: number
|
||||
@ -232,26 +233,26 @@ export class BossMicheal extends BossFight {
|
||||
|
||||
export class BossReaper extends BossFight {
|
||||
|
||||
constructor(protected md2Service: MD2Service) {
|
||||
constructor(public md2Service: 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.imgUrl = md2Service.stateService.imgUrl('/Boss/The Reaper.jpg');
|
||||
this.standUrl = md2Service.stateService.imgUrl('/Boss/The Reaper-Stand.png');
|
||||
this.imgUrl = md2Service.imgUrl('/Boss/The Reaper.jpg');
|
||||
this.standUrl = md2Service.imgUrl('/Boss/The Reaper-Stand.png');
|
||||
|
||||
this.info = new MobInfo({
|
||||
description: this.name,
|
||||
type: MobType.Boss,
|
||||
hpPerHero: 25,
|
||||
level: 10,
|
||||
imageUrl: md2Service.stateService.imgUrl('/Boss/The Reaper-Stand.png')
|
||||
imageUrl: md2Service.imgUrl('/Boss/The Reaper-Stand.png')
|
||||
});
|
||||
if (!this.info.skills) {
|
||||
this.info.skills = [];
|
||||
}
|
||||
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,
|
||||
skillRoll: 1
|
||||
} as MD2MobSkill);
|
||||
@ -304,8 +305,8 @@ export class BossReaper extends BossFight {
|
||||
name: 'Death Is Coming',
|
||||
description:
|
||||
`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>` +
|
||||
`Each Hero discards ${this.md2Service.stateService.iconHtml(MD2Icon.MP)} equal to ${this.md2Service.stateService.iconHtml(MD2Icon.Melee)} rolled.`
|
||||
`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.iconHtml(MD2Icon.MP)} equal to ${this.md2Service.iconHtml(MD2Icon.Melee)} rolled.`
|
||||
});
|
||||
break;
|
||||
|
||||
|
||||
@ -6,7 +6,6 @@ import { MsgBoxService } from '../../../services/msg-box.service';
|
||||
import { DropDownOption } from '../../../entity/dropDownOption';
|
||||
import { MD2Icon } from '../massive-darkness2.model';
|
||||
import { first } from 'rxjs/operators';
|
||||
import { MD2StateService } from '../../../services/MD2/md2-state.service';
|
||||
import { MD2IconPickerDlgComponent } from './md2-icon-picker-dlg.component';
|
||||
import { NbDialogService } from '@nebular/theme';
|
||||
import { DOMParser as ProseMirrorDOMParser } from 'prosemirror-model';
|
||||
@ -59,7 +58,6 @@ export class MD2HtmlEditorComponent implements ControlValueAccessor, AfterViewIn
|
||||
|
||||
constructor(
|
||||
private msgBoxService: MsgBoxService,
|
||||
private md2StateService: MD2StateService,
|
||||
private dialogService: DialogService,
|
||||
private cdr: ChangeDetectorRef,
|
||||
elementRef: ElementRef, ngZone: NgZone, @Inject(PLATFORM_ID) platformId: Object) {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { NbDialogRef } from '@nebular/theme';
|
||||
import { MD2Icon } from '../massive-darkness2.model';
|
||||
import { MD2StateService } from '../../../services/MD2/md2-state.service';
|
||||
import { DialogRef } from '@progress/kendo-angular-dialog';
|
||||
import { MD2Service } from '../../../services/MD2/md2.service';
|
||||
|
||||
@Component({
|
||||
selector: 'md2-icon-picker-dlg',
|
||||
@ -63,7 +63,7 @@ export class MD2IconPickerDlgComponent implements OnInit {
|
||||
|
||||
constructor(
|
||||
private dlgRef: DialogRef,
|
||||
private md2StateService: MD2StateService
|
||||
private md2Service: MD2Service
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
@ -72,7 +72,7 @@ export class MD2IconPickerDlgComponent implements OnInit {
|
||||
this.iconList.push({
|
||||
icon: 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 { MD2Icon, TreasureType } from '../massive-darkness2.model';
|
||||
import { MD2StateService } from '../../../services/MD2/md2-state.service';
|
||||
import { MD2Service } from '../../../services/MD2/md2.service';
|
||||
|
||||
@Component({
|
||||
selector: 'md2-icon',
|
||||
@ -44,7 +44,7 @@ export class MD2IconComponent implements OnInit {
|
||||
}
|
||||
@Input() size: string = 'sm';
|
||||
iconName: string;
|
||||
constructor(private md2StateService: MD2StateService) { }
|
||||
constructor(private md2Service: MD2Service) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
@ -52,10 +52,10 @@ export class MD2IconComponent implements OnInit {
|
||||
private initIcon(icon: MD2Icon): void {
|
||||
if (icon < MD2Icon.TreasureToken) {
|
||||
this.isImageIcon = false;
|
||||
this.iconHtml = this.md2StateService.iconHtml(icon);
|
||||
this.iconHtml = this.md2Service.iconHtml(icon);
|
||||
} else {
|
||||
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 { MD2MobLevelInfoService } from '../../service/massive-darkness2.service';
|
||||
import { MD2Icon, MobType } from '../../massive-darkness2.model';
|
||||
import { MD2StateService } from '../../../../services/MD2/md2-state.service';
|
||||
import { MD2Service } from '../../../../services/MD2/md2.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-md2-mob-level-editor',
|
||||
@ -30,7 +30,7 @@ export class MD2MobLevelEditorComponent extends DialogContentBase implements OnI
|
||||
public dialog: DialogRef,
|
||||
private mobLevelInfoService: MD2MobLevelInfoService,
|
||||
private cdr: ChangeDetectorRef,
|
||||
private md2StateService: MD2StateService
|
||||
private md2Service: MD2Service
|
||||
) {
|
||||
super(dialog);
|
||||
}
|
||||
@ -43,9 +43,9 @@ export class MD2MobLevelEditorComponent extends DialogContentBase implements OnI
|
||||
public initializeEnums(): void {
|
||||
this.attackTypes = [
|
||||
{ value: MobSkillType.Attack, text: 'None' },
|
||||
{ value: MobSkillType.MeleeAttack, text: this.md2StateService.iconHtml(MD2Icon.Melee) + ' Melee Attack' },
|
||||
{ value: MobSkillType.RangeAttack, text: this.md2StateService.iconHtml(MD2Icon.Range) + ' Range Attack' },
|
||||
{ value: MobSkillType.MagicAttack, text: this.md2StateService.iconHtml(MD2Icon.Magic) + ' Magic Attack' },
|
||||
{ value: MobSkillType.MeleeAttack, text: this.md2Service.iconHtml(MD2Icon.Melee) + ' Melee Attack' },
|
||||
{ value: MobSkillType.RangeAttack, text: this.md2Service.iconHtml(MD2Icon.Range) + ' Range 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.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">
|
||||
|
||||
<ng-container>
|
||||
<label class='label g-text-nowrap'>Alive Units <b
|
||||
class="MD2text g-font-size-18">{{mob.mobAmount}}</b></label><br>
|
||||
<label class='label g-text-nowrap'>Minions <b
|
||||
class="MD2text g-font-size-18">{{mob.mobAmount-1}}</b></label><br>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
<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" />
|
||||
<div *ngIf="isMob">
|
||||
<img class="mobImg mobLeader" src="{{mob.leaderImgUrl}}" (click)="showMobImage(mob)" />
|
||||
<img class="mobImg mobMinion" src="{{mob.minionImgUrl}}" (click)="showMobImage(mob)" />
|
||||
<img class="mobImg mobLeader" src="{{mob.leaderImgUrl}}" (click)="showMobImage(mob)"
|
||||
[ngClass]="{'noMinions': mob.mobAmount==1}" />
|
||||
<img class="mobImg mobMinion" src="{{mob.minionImgUrl}}" (click)="showMobImage(mob)" *ngIf="mob.mobAmount>1" />
|
||||
|
||||
</div>
|
||||
@ -1,6 +1,7 @@
|
||||
.mobImg {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
object-fit: contain;
|
||||
&.roamingMonster {
|
||||
width: 95%;
|
||||
max-height: 80%;
|
||||
@ -12,6 +13,10 @@
|
||||
max-height: 80%;
|
||||
top: 40px;
|
||||
left: 0;
|
||||
&.noMinions {
|
||||
width: 95%;
|
||||
max-height: 90%;
|
||||
}
|
||||
}
|
||||
&.mobMinion {
|
||||
width: 60%;
|
||||
|
||||
@ -119,7 +119,7 @@ export class MobsComponent extends MD2ComponentBase implements OnInit {
|
||||
|
||||
afterSpawn() {
|
||||
this.cdRef.detectChanges();
|
||||
this.md2Service.broadcastService.broadcastMobsInfo();
|
||||
this.md2Service.broadcastMobsInfo();
|
||||
if (this.showRoundMessage) {
|
||||
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) {
|
||||
attacker.exp += 1;
|
||||
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 { 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 { first } from 'rxjs/operators';
|
||||
import { MD2Service } from './md2.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@ -10,13 +10,13 @@ import { first } from 'rxjs/operators';
|
||||
export class MD2InitService {
|
||||
|
||||
constructor(
|
||||
private stateService: MD2StateService,
|
||||
private md2Service: MD2Service,
|
||||
private mobInfoService: MD2MobInfoService,
|
||||
) { }
|
||||
|
||||
public initMobDecks() {
|
||||
this.stateService.mobDeck = new DrawingBag();
|
||||
this.stateService.roamingMobDeck = new DrawingBag();
|
||||
this.md2Service.mobDeck = new DrawingBag();
|
||||
this.md2Service.roamingMobDeck = new DrawingBag();
|
||||
|
||||
this.initCoreGameMobAndRoamingMonsters();
|
||||
}
|
||||
@ -29,18 +29,18 @@ export class MD2InitService {
|
||||
// }
|
||||
// });
|
||||
this.mobInfoService.getAll().pipe(first()).subscribe(result => {
|
||||
this.stateService.mobInfos = result.filter(m => m.type == MobType.Mob);
|
||||
this.stateService.roamingMobInfos = result.filter(m => m.type == MobType.RoamingMonster);
|
||||
this.md2Service.mobInfos = result.filter(m => m.type == MobType.Mob);
|
||||
this.md2Service.roamingMobInfos = result.filter(m => m.type == MobType.RoamingMonster);
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
const mobInfo = result[i];
|
||||
for (let j = 0; j < mobInfo.mobLevelInfos.length; j++) {
|
||||
const levelInfo = mobInfo.mobLevelInfos[j];
|
||||
switch (mobInfo.type) {
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -53,12 +53,12 @@ export class MD2InitService {
|
||||
}
|
||||
|
||||
public initTreasureBag() {
|
||||
this.stateService.treasureBag.ClearAllItems();
|
||||
this.md2Service.treasureBag.ClearAllItems();
|
||||
this.addTreasure(TreasureType.Common, 15);
|
||||
this.addTreasure(TreasureType.Rare, 5);
|
||||
}
|
||||
|
||||
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 { ADIcon } from '../../ui/alert-dlg/alert-dlg.model';
|
||||
import { MsgBoxService } from '../msg-box.service';
|
||||
import { MD2StateService } from './md2-state.service';
|
||||
import { MD2Service } from './md2.service';
|
||||
|
||||
@Injectable({
|
||||
@ -16,14 +15,13 @@ export class MD2MobService {
|
||||
attackingAttackerReward: string = '';
|
||||
constructor(
|
||||
private md2Service: MD2Service,
|
||||
private stateService: MD2StateService,
|
||||
private msgBoxService: MsgBoxService
|
||||
) { }
|
||||
public get roamingMonsters() {
|
||||
return this.stateService.info.roamingMonsters;
|
||||
return this.md2Service.info.roamingMonsters;
|
||||
}
|
||||
public get mobs() {
|
||||
return this.stateService.info.mobs;
|
||||
return this.md2Service.info.mobs;
|
||||
}
|
||||
|
||||
addOneUnit(mob: MobInfo) {
|
||||
@ -120,14 +118,14 @@ export class MD2MobService {
|
||||
}
|
||||
this.attackingAllExp = 0;
|
||||
this.attackingAttackerExp = 0;
|
||||
this.md2Service.broadcastService.broadcastAllHeroInfoToAll();
|
||||
this.md2Service.broadcastAllHeroInfoToAll();
|
||||
this.md2Service.refreshUI$.next();
|
||||
});
|
||||
} else if (this.attackingAttackerExp > 0 && attacker) {
|
||||
this.msgBoxService.show(`<b>${attackerTitle}</b> Gains ${this.attackingAttackerExp} Exp`, { icon: ADIcon.INFO }).pipe(first()).subscribe(result => {
|
||||
attacker.exp += this.attackingAttackerExp;
|
||||
this.attackingAttackerExp = 0;
|
||||
this.md2Service.broadcastService.broadcastHeroInfoToOwner(attacker);
|
||||
this.md2Service.broadcastHeroInfoToOwner(attacker);
|
||||
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 { LoginUserService } from '../login-user.service';
|
||||
import { MsgBoxService } from '../msg-box.service';
|
||||
import { SignalRService, SignalRSession, SignalRMessage } from '../signal-r.service';
|
||||
import { MD2StateService } from './md2-state.service';
|
||||
import { MD2BroadcastService } from './md2-broadcast.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';
|
||||
@ -29,6 +27,17 @@ const MD2_IMG_URL = (id: string = null) => { return `${environment.apiUrl}/Files
|
||||
export class MD2Service {
|
||||
// #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 enemyPhaseMobs: MobInfo[];
|
||||
public enemyPhaseSubject = new Subject<MobInfo>();
|
||||
@ -42,45 +51,34 @@ export class MD2Service {
|
||||
|
||||
|
||||
public get heros() {
|
||||
return this.stateService.info.heros;
|
||||
return this.info.heros;
|
||||
}
|
||||
public get roamingMonsters() {
|
||||
return this.stateService.info.roamingMonsters;
|
||||
return this.info.roamingMonsters;
|
||||
}
|
||||
public get mobs() {
|
||||
return this.stateService.info.mobs;
|
||||
return this.info.mobs;
|
||||
}
|
||||
public get allRoamingMonsterInfos() {
|
||||
return this.stateService.roamingMobInfos;
|
||||
return this.roamingMobInfos;
|
||||
}
|
||||
public get allMobInfos() {
|
||||
return this.stateService.mobInfos;
|
||||
}
|
||||
|
||||
|
||||
public get info(): MD2GameInfo {
|
||||
return this.stateService.info;
|
||||
}
|
||||
public set info(v: MD2GameInfo) {
|
||||
this.stateService.info = v;
|
||||
return this.mobInfos;
|
||||
}
|
||||
|
||||
// #endregion Properties (24)
|
||||
|
||||
// #region Constructors (1)
|
||||
|
||||
constructor(
|
||||
public fileService: FileService,
|
||||
public msgBoxService: MsgBoxService,
|
||||
private gameRoomService: GameRoomService,
|
||||
public gameRoomService: GameRoomService,
|
||||
public loginUserService: LoginUserService,
|
||||
public stateService: MD2StateService,
|
||||
public signalRService: SignalRService,
|
||||
public dlgService: NbDialogService,
|
||||
public broadcastService: MD2BroadcastService
|
||||
public dlgService: NbDialogService
|
||||
) {
|
||||
this.darknessPhaseRule = new CoreGameDarknessPhaseRule();
|
||||
this.stateService.info = new MD2GameInfo();
|
||||
this.info = new MD2GameInfo();
|
||||
this.darknessPhaseRule.addTreasureToken.subscribe(treasureType => {
|
||||
this.addTreasure(treasureType, 1);
|
||||
});
|
||||
@ -105,11 +103,8 @@ export class MD2Service {
|
||||
}
|
||||
}
|
||||
|
||||
public get playerHero(): MD2HeroInfo {
|
||||
return this.stateService.playerHero;
|
||||
}
|
||||
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)
|
||||
|
||||
public get treasureBag() {
|
||||
return this.stateService.treasureBag
|
||||
}
|
||||
|
||||
public addTreasure(type: TreasureType, amount: number = 1) {
|
||||
this.treasureBag.AddItem(new TreasureItem(type, amount));
|
||||
@ -131,17 +123,17 @@ export class MD2Service {
|
||||
public darknessPhase() {
|
||||
this.heros.forEach(hero => {
|
||||
hero.remainActions = 3;
|
||||
this.broadcastService.broadcastHeroInfoToOwner(hero);
|
||||
this.broadcastHeroInfoToOwner(hero);
|
||||
});
|
||||
this.stateService.info.roundPhase = RoundPhase.HeroPhase;
|
||||
if (!this.stateService.info.isBossFight) {
|
||||
this.stateService.info.round++;
|
||||
this.info.roundPhase = RoundPhase.HeroPhase;
|
||||
if (!this.info.isBossFight) {
|
||||
this.info.round++;
|
||||
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 {
|
||||
this.stateService.info.boss.darknessPhase();
|
||||
this.msgBoxService.show(`Boss Fight - ${NumberUtils.Ordinal(this.stateService.info.boss.rounds)} Hero Phase`, { icon: ADIcon.INFO });
|
||||
this.info.boss.darknessPhase();
|
||||
this.msgBoxService.show(`Boss Fight - ${NumberUtils.Ordinal(this.info.boss.rounds)} Hero Phase`, { icon: ADIcon.INFO });
|
||||
}
|
||||
|
||||
//this.runNextPhase();
|
||||
@ -157,9 +149,9 @@ export class MD2Service {
|
||||
level = 5;
|
||||
}
|
||||
if (isRoamingMonster) {
|
||||
mobDeck = this.stateService.roamingMobDeck;
|
||||
mobDeck = this.roamingMobDeck;
|
||||
} else {
|
||||
mobDeck = this.stateService.mobDeck;
|
||||
mobDeck = this.mobDeck;
|
||||
}
|
||||
|
||||
if (mobDeck.drawingItems.filter(m => (m as MobInfo).level == level)
|
||||
@ -298,9 +290,9 @@ export class MD2Service {
|
||||
} else {
|
||||
this.info.boss = new BossMicheal(this);
|
||||
}
|
||||
this.stateService.info.roamingMonsters = [];
|
||||
this.stateService.info.mobs = [];
|
||||
this.stateService.info.isBossFight = true;
|
||||
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;
|
||||
@ -314,14 +306,14 @@ export class MD2Service {
|
||||
hero.uiActivating = false;
|
||||
hero.uiBossFight = true;
|
||||
});
|
||||
this.broadcastService.broadcastAllHeroInfoToAll();
|
||||
this.broadcastGameInfo();
|
||||
}
|
||||
|
||||
});
|
||||
//this.sendMsgboxMsg
|
||||
}
|
||||
public activateBoss() {
|
||||
this.stateService.info.boss.activating();
|
||||
this.info.boss.activating();
|
||||
}
|
||||
public fileList(folderPath: string) {
|
||||
return this.fileService.FileList('Images/MD2/' + folderPath);
|
||||
@ -342,8 +334,8 @@ export class MD2Service {
|
||||
hero.mp += levelUpInfo.extraMp;
|
||||
hero.mpMaximum += levelUpInfo.extraMp;
|
||||
hero.exp = levelUpInfo.currentExp;
|
||||
this.broadcastService.broadcastHeroInfoToOwner(hero);
|
||||
this.sendMsgboxMsg(hero.playerInfo.signalRClientId, { title: 'Level Up', text: 'Please do a skill level up!', icon: ADIcon.INFO });
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -362,9 +354,9 @@ export class MD2Service {
|
||||
level = 3;
|
||||
}
|
||||
if (isRoamingMonsters) {
|
||||
return this.stateService.imgUrl(`Mobs/CoreGame/RoamingMonsters/${name}/${level}.png`);
|
||||
return this.imgUrl(`Mobs/CoreGame/RoamingMonsters/${name}/${level}.png`);
|
||||
} 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.mp = hero.mpMaximum;
|
||||
hero.exp = 0;
|
||||
this.stateService.playerHero = hero;
|
||||
this.playerHero = hero;
|
||||
// let message = {
|
||||
// receiver: { isGroup: true, sessionId: this.gameRoomService.gameRoomId } as SignalRSession,
|
||||
// from: { isGroup: false, sessionId: this.loginUserService.userAccess.signalRSessionId },
|
||||
@ -389,12 +381,12 @@ export class MD2Service {
|
||||
|
||||
|
||||
public runNextPhase() {
|
||||
this.stateService.info.roundPhase++;
|
||||
switch (this.stateService.info.roundPhase) {
|
||||
this.info.roundPhase++;
|
||||
switch (this.info.roundPhase) {
|
||||
case RoundPhase.HeroPhase:
|
||||
this.heros.forEach(hero => {
|
||||
hero.remainActions = 3;
|
||||
this.broadcastService.broadcastHeroInfoToOwner(hero);
|
||||
this.broadcastHeroInfoToOwner(hero);
|
||||
});
|
||||
break;
|
||||
case RoundPhase.EnemyPhase:
|
||||
@ -409,14 +401,14 @@ export class MD2Service {
|
||||
default: break;
|
||||
}
|
||||
let parameters = {};
|
||||
parameters['phase'] = this.stateService.info.roundPhase;
|
||||
this.broadcastService.broadcastMessage('roundPhase', '', parameters);
|
||||
parameters['phase'] = this.info.roundPhase;
|
||||
this.broadcastMessage('roundPhase', '', parameters);
|
||||
}
|
||||
|
||||
public sendMsgboxMsg(playerSessionId: string, msg: Partial<MessageBoxConfig>) {
|
||||
let message = {
|
||||
receiver: { isGroup: false, sessionId: playerSessionId } as SignalRSession,
|
||||
from: { isGroup: false, sessionId: this.loginUserService.userAccess.signalRSessionId },
|
||||
receiver: { isGroup: false, connectionId: playerSessionId } as SignalRClient,
|
||||
from: { isGroup: false, connectionId: this.loginUserService.userAccess.signalRConnectionId },
|
||||
actionType: 'message',
|
||||
actionName: 'popup',
|
||||
} as SignalRMessage;
|
||||
@ -426,7 +418,7 @@ export class MD2Service {
|
||||
}
|
||||
|
||||
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[]) {
|
||||
@ -449,32 +441,193 @@ export class MD2Service {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this.broadcastService.broadcastHeroInfoToAll(this.currentActivateHero);
|
||||
this.broadcastService.broadcastHeroInfoToOwner(this.currentActivateHero);
|
||||
this.broadcastHeroInfoToAll(this.currentActivateHero, true);
|
||||
//this.broadcastHeroInfoToOwner(this.currentActivateHero);
|
||||
this.msgBoxService.show(
|
||||
this.stateService.imgHtml('/Fountain/Cover.png', '')
|
||||
this.imgHtml('/Fountain/Cover.png', '')
|
||||
, { text: `${this.currentActivateHero.heroFullName} Recovered ${result.description}.` });
|
||||
}
|
||||
|
||||
public openTreasureChest() {
|
||||
let result = new DrawingBag<DrawingItem>([
|
||||
new DrawingItem('Common', `${this.stateService.treasureImageHtml(TreasureType.Common)} x 2`, '', 10),
|
||||
new DrawingItem('Open Treasure Chest', `${this.stateService.treasureImageHtml(TreasureType.Rare)} x 2`, '', 5),
|
||||
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.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() {
|
||||
let result = new DrawingBag<DrawingItem>([
|
||||
new DrawingItem('Common', `${this.stateService.treasureImageHtml(TreasureType.Rare)} x 3`, '', 3),
|
||||
new DrawingItem('Open Treasure Chest', `${this.stateService.treasureImageHtml(TreasureType.Epic)} x 3`, '', 1),
|
||||
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.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)
|
||||
|
||||
}
|
||||
@ -491,7 +644,7 @@ export class MD2GameInfo {
|
||||
|
||||
this.mobs = this.mobs.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.heros = this.heros.map(h => new MD2HeroInfo(h));
|
||||
@ -502,6 +655,7 @@ export class MD2GameInfo {
|
||||
public mobs: MobInfo[] = [];
|
||||
public roamingMonsters: MobInfo[] = [];
|
||||
public heros: MD2HeroInfo[] = [];
|
||||
public disconnectedHeroes: MD2HeroInfo[] = [];
|
||||
public round = 1;
|
||||
public roundPhase: RoundPhase = RoundPhase.HeroPhase;
|
||||
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 {
|
||||
name: this.loginUserService.userAccess.firstName,
|
||||
id: this.loginUserService.userAccess.memberId,
|
||||
signalRClientId: this.loginUserService.userAccess.signalRSessionId,
|
||||
signalRClientId: this.loginUserService.userAccess.signalRConnectionId,
|
||||
isPlayer: true,
|
||||
gameRoomId: this.gameRoomId,
|
||||
tabId: this.loginUserService.sessionTabId
|
||||
} as IGamePlayer;
|
||||
}
|
||||
createGameRoom(name: string) {
|
||||
let gameRoom = this.currentPlayer();
|
||||
gameRoom.gameRoomId = gameRoom.id;
|
||||
this.gameRoomId = gameRoom.id;
|
||||
//Using current player to create game room
|
||||
let currentPlayer = this.currentPlayer();
|
||||
currentPlayer.gameRoomId = currentPlayer.id;
|
||||
this.gameRoomId = currentPlayer.id;
|
||||
this.http.post<boolean>(GAME_ROOM_URL,
|
||||
JSON.stringify(gameRoom), {
|
||||
JSON.stringify(currentPlayer), {
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
|
||||
@ -14,7 +14,7 @@ export class LoginUserService {
|
||||
}
|
||||
|
||||
setSignalRConnectionId(id: string) {
|
||||
this.userAccess.signalRSessionId = id;
|
||||
this.userAccess.signalRConnectionId = id;
|
||||
}
|
||||
|
||||
public get sessionTabId(): string {
|
||||
|
||||
@ -15,7 +15,7 @@ const SIGNAL_R_URL = (id: string = null) => { return `${environment.apiUrl}/${id
|
||||
})
|
||||
export class SignalRService {
|
||||
ReceivedSignalRMessageSubject = new Subject<SignalRMessage>();
|
||||
signalRMessageConnSubject = new Subject<any>();
|
||||
signalRMessageConnSubject = new Subject<SignalRConnectionState>();
|
||||
private hubConnection: signalR.HubConnection
|
||||
constructor(
|
||||
private loginUserService: LoginUserService,
|
||||
@ -42,6 +42,7 @@ export class SignalRService {
|
||||
|
||||
}
|
||||
public startSignalRConnection(gameRoomId: string = '') {
|
||||
this.signalRMessageConnSubject.next({ status: 'connecting' });
|
||||
if (!this.loginUserService.sessionTabId) {
|
||||
this.loginUserService.sessionTabId = UuidUtils.generate();
|
||||
}
|
||||
@ -65,13 +66,21 @@ export class SignalRService {
|
||||
.withUrl(`${SIGNAL_R_URL('GameRoomHub')}?${params.toString()}`)
|
||||
.withAutomaticReconnect()
|
||||
.build();
|
||||
this.registerHubConnectionLifecycleHandlers();
|
||||
let me = this
|
||||
this.hubConnection
|
||||
.start()
|
||||
.then(() => {
|
||||
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.BroadcastAPIMessageReceive(JSON.parse(jsonString));
|
||||
});
|
||||
@ -79,12 +88,37 @@ export class SignalRService {
|
||||
}
|
||||
public setSignalRConnectionId(connectionId: string) {
|
||||
|
||||
this.loginUserService.userAccess.signalRSessionId = connectionId;
|
||||
this.loginUserService.userAccess.signalRConnectionId = connectionId;
|
||||
this.loginUserService.signalRInitialized.next(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) {
|
||||
@ -102,16 +136,23 @@ export class SignalRService {
|
||||
|
||||
}
|
||||
export interface SignalRMessage {
|
||||
from: SignalRSession;
|
||||
receiver: SignalRSession;
|
||||
from: SignalRClient;
|
||||
receiver: SignalRClient;
|
||||
actionType: string;
|
||||
actionName: string;
|
||||
parameters: { [key: string]: string; };
|
||||
value: any;
|
||||
jsonValue: string;
|
||||
}
|
||||
|
||||
export interface SignalRSession {
|
||||
sessionId: string;
|
||||
export interface SignalRClient {
|
||||
connectionId: string;
|
||||
name: string;
|
||||
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-bottom: 0;
|
||||
}
|
||||
|
||||
button,
|
||||
a,
|
||||
input {
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
@ -6,8 +6,9 @@
|
||||
<title>真幸福的幸福小組</title>
|
||||
|
||||
<base href="/">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
|
||||
<link rel="icon" type="image/png" href="favicon.png">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<script defer
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user