241 lines
8.4 KiB
TypeScript
241 lines
8.4 KiB
TypeScript
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<SpawnMobDlgComponent>,
|
|
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 = `<h4>${result.skill.name}</h4><div>${result.skill.description}</div>`;
|
|
}
|
|
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<SkillResolutionResult> {
|
|
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<SkillResolutionResult> {
|
|
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 <b>Lowest HP</b> hero.';
|
|
break;
|
|
case MobSkillTarget.HighestHp:
|
|
this.otherAttackTarget = 'attacking the other <b>Highest HP</b> hero.';
|
|
break;
|
|
case MobSkillTarget.HighestMp:
|
|
this.otherAttackTarget = 'attacking the other <b>Highest Mana</b> hero.';
|
|
break;
|
|
case MobSkillTarget.LowestLevel:
|
|
this.otherAttackTarget = 'attacking the other <b>Lowest Level</b> hero.';
|
|
break;
|
|
case MobSkillTarget.HighestLevel:
|
|
this.otherAttackTarget = 'attacking the other <b>Highest Level</b> 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 <b>${this.beenAttackedHero.heroFullName}</b> 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';
|
|
}
|
|
}
|
|
}
|