import { ChangeDetectorRef, Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { NbDialogRef } from '@nebular/theme'; import { concatMap, find, defaultIfEmpty, first, map, switchMap } from 'rxjs/operators'; import { FileService } from '../../../../services/file.service'; import { MD2Service } from '../../../../services/MD2/md2.service'; import { MsgBoxService } from '../../../../services/msg-box.service'; import { StateService } from '../../../../services/state.service'; import { StringUtils } from '../../../../utilities/string-utils'; import { AttackInfo, AttackTarget, AttackType, MD2HeroInfo, MD2Icon, MobDlgType, MobInfo, MobType } from '../../massive-darkness2.model'; import { MD2ComponentBase } from '../../MD2Base'; import { ADButtons, ADIcon } from '../../../../ui/alert-dlg/alert-dlg.model'; import { MobSkillType } from '../../massive-darkness2.model.boss'; import { Observable, from, of } from 'rxjs'; import { MD2MobSkill, MobSkillTarget } from '../../massive-darkness2.db.model'; import { MD2Logic } from '../../massive-darkness2.logic'; type SkillResolutionResult = { result: boolean; skill: MD2MobSkill | null }; @Component({ selector: 'ngx-spawn-mob-dlg', templateUrl: './spawn-mob-dlg.component.html', styleUrls: ['./spawn-mob-dlg.component.scss'] }) export class SpawnMobDlgComponent extends MD2ComponentBase implements OnInit { MobDlgType = MobDlgType; MobType = MobType; mode: MobDlgType; cardTitle: string; title: string; titleHtml: string; MD2Icon = MD2Icon; mob: MobInfo; actionInfoHtml: string; beenAttackedHero = null as MD2HeroInfo; attackTarget: string; otherAttackTarget: string; constructor( private dlgRef: NbDialogRef, private msgBoxService: MsgBoxService, public md2Service: MD2Service, protected stateService: StateService, protected route: ActivatedRoute, protected cdRef: ChangeDetectorRef, ) { super(md2Service, stateService, route, cdRef); } activeSkill: MD2MobSkill = null;; ngOnInit(): void { //this.mob = new MobInfo(this.mob); if (this.mode == MobDlgType.Spawn && this.mob.type == MobType.Mob) { this.mob.attackInfos = [new AttackInfo(MD2Icon.Melee), new AttackInfo(MD2Icon.Range), new AttackInfo(MD2Icon.Magic)]; } else if (this.mode == MobDlgType.Activating) { if (this.mob.skills) { //this.mobActivate(this.mob, this.md2Service.info.heros); //this.mob.activateFunction(this.mob, this.md2Service.msgBoxService, this.md2Service.info.heros); this.mobActivate(this.mob, this.md2Service.info.heros).pipe(first()).subscribe(result => { if (result && result.skill) { this.activeSkill = result.skill; //this.actionInfoHtml = `

${result.skill.name}

${result.skill.description}
`; } if (this.mob.type == MobType.Mob) { this.mob.actions = 2; } else { if (result && result.skill) { this.mob.actions = 1; } else { this.mob.actions = 2; this.activeSkill = { name: 'Normal Action', description: `${this.mob.name} Gains 2 Actions.` } as MD2MobSkill; //this.actionInfoHtml = `${this.mob.name} Gains 2 Actions.`; } } }); } } this.mob.uiWounds = 0; this.mob.uiFrozenTokens = 0; this.mob.uiFrozenTokens = 0; this.initTitleHtml(); } mobActivate(mob: MobInfo, heros: MD2HeroInfo[]): Observable { switch (mob.type) { case MobType.Mob: return of({ result: false, skill: null } as SkillResolutionResult); case MobType.RoamingMonster: if (!mob.skills || mob.skills.length === 0) { return of({ result: false, skill: null } as SkillResolutionResult); } const orderedSkills = mob.skills .filter(s => [MobSkillType.ConditionalSkill, MobSkillType.OtherWiseSkill].includes(s.type)) .sort((a, b) => (a.seq ?? Number.MAX_SAFE_INTEGER) - (b.seq ?? Number.MAX_SAFE_INTEGER)); if (orderedSkills.length === 0) { return of({ result: false, skill: null } as SkillResolutionResult); } return from(orderedSkills).pipe( concatMap(skill => this.resolveSkillPrompt(skill)), find(resolution => resolution.result === true), defaultIfEmpty({ result: false, skill: null } as SkillResolutionResult) ); case MobType.Boss: default: return of({ result: false, skill: null } as SkillResolutionResult); } } private resolveSkillPrompt(skill: MD2MobSkill): Observable { if (skill.type === MobSkillType.OtherWiseSkill) { return of({ result: true, skill } as SkillResolutionResult); } const title = 'Resolve Skill?'; const prompt = skill.skillCondition; return this.msgBoxService.show(title, { text: prompt, icon: ADIcon.QUESTION, buttons: ADButtons.YesNo }).pipe( map(answer => ({ result: !!answer, skill } as SkillResolutionResult)) ); } submit() { if (this.mode == MobDlgType.Spawn) { this.mob.attackInfos = this.mob.attackInfos.filter(a => a.yellow > 0 || a.orange > 0 || a.red > 0); } switch (this.mode) { case MobDlgType.Spawn: this.mob.attackInfos = this.mob.attackInfos.filter(a => a.yellow > 0 || a.orange > 0 || a.red > 0); break; case MobDlgType.Activating: break; case MobDlgType.BeenAttacked: break; case MobDlgType.PreView: default: break; } this.md2Service.info.showAttackBtn = false; this.md2Service.refreshUI$.next(); this.dlgRef.close(this.mob); } cancel() { this.dlgRef.close(); } initTitleHtml() { this.cardTitle = MobType[this.mob.type]; let htmlText = ''; if (this.mode == MobDlgType.Spawn) { htmlText = `${this.mob.description} Shows Up`; } else if (this.mode == MobDlgType.Activating) { let targetType = null as MobSkillTarget; let randomAttack = Math.random() * MobSkillTarget.HighestLevel; const values = Object.values(MobSkillTarget); const stringKeys = Object .keys(MobSkillTarget) .filter((v) => isNaN(Number(v))) for (let i = 0; i < stringKeys.length; i++) { const element = MobSkillTarget[stringKeys[i]]; if (element >= randomAttack) { targetType = element; break; } } this.beenAttackedHero = MD2Logic.getTargetHeroByFilter(this.md2Service.heros, targetType); switch (targetType) { case MobSkillTarget.LeastHp: this.otherAttackTarget = 'attacking the other Lowest HP hero.'; break; case MobSkillTarget.HighestHp: this.otherAttackTarget = 'attacking the other Highest HP hero.'; break; case MobSkillTarget.HighestMp: this.otherAttackTarget = 'attacking the other Highest Mana hero.'; break; case MobSkillTarget.LowestLevel: this.otherAttackTarget = 'attacking the other Lowest Level hero.'; break; case MobSkillTarget.HighestLevel: this.otherAttackTarget = 'attacking the other Highest Level hero.'; break; case MobSkillTarget.Random: default: this.otherAttackTarget = 'Just act like normal.'; break; } //let attackedHeros = StringUtils.makeCommaSeparatedString(this.beenAttackedHero.map(h => this.md2Service.heroFullName(h)), true, true); this.attackTarget = `Attacking ${this.beenAttackedHero.heroFullName} first if possible, otherwise ${this.otherAttackTarget}`; htmlText = `${this.title}`; } else { htmlText = `${this.mob.description}`; } this.titleHtml = htmlText; } public get headerStatus(): string { switch (this.mode) { case MobDlgType.Spawn: return 'warning'; break; case MobDlgType.Activating: return 'danger'; break; case MobDlgType.BeenAttacked: return 'info'; break; case MobDlgType.PreView: default: return ''; break; } } public get submitBtnText(): string { switch (this.mode) { case MobDlgType.Activating: return 'Next'; break; case MobDlgType.BeenAttacked: return 'Attack!!'; break; case MobDlgType.PreView: case MobDlgType.Spawn: default: return 'Close'; } } }