2025-11-14 07:37:48 -08:00

150 lines
5.0 KiB
TypeScript

import { Component, Input, OnInit, ViewChild, ChangeDetectorRef } from '@angular/core';
import { DialogRef, DialogContentBase } from '@progress/kendo-angular-dialog';
import { NgForm } from '@angular/forms';
import { first } from 'rxjs/operators';
import { MD2MobInfo, GameBundle, BossFightProfile } from '../../massive-darkness2.db.model';
import { MobType } from '../../massive-darkness2.model';
import { MD2MobInfoService } from '../../service/massive-darkness2.service';
@Component({
selector: 'ngx-md2-mob-info-editor',
templateUrl: './md2-mob-info-editor.component.html',
styleUrls: ['./md2-mob-info-editor.component.scss']
})
export class MD2MobInfoEditorComponent extends DialogContentBase implements OnInit {
@Input() public data: MD2MobInfo;
@Input() public isAdding: boolean = false;
@ViewChild('form') form: NgForm;
public model: MD2MobInfo;
public processing: boolean = false;
public mobTypes: Array<{ value: MobType; text: string }> = [];
public gameBundles: Array<{ value: GameBundle; text: string }> = [];
public selectedMobType: { value: MobType; text: string } | null = null;
public selectedGameBundle: { value: GameBundle; text: string } | null = null;
constructor(
public dialog: DialogRef,
private mobInfoService: MD2MobInfoService,
private cdr: ChangeDetectorRef
) {
super(dialog);
this.initializeEnums();
}
ngOnInit(): void {
this.initializeModel();
}
public initializeModel(): void {
const typeValue = this.data?.type !== undefined && this.data?.type !== null ? this.data.type : MobType.Mob;
const fromValue = this.data?.from !== undefined && this.data?.from !== null ? this.data.from : GameBundle.CoreGame;
this.model = {
id: this.data?.id || '',
name: this.data?.name || '',
type: typeValue,
from: fromValue,
leaderImgUrl: this.data?.leaderImgUrl || '',
minionImgUrl: this.data?.minionImgUrl || '',
mobLevelInfos: this.data?.mobLevelInfos || [],
skills: this.data?.skills || [],
bossFightProfile: this.data?.bossFightProfile
};
// Initialize bossFightProfile for Boss type mobs if not already set
if (typeValue === MobType.Boss && !this.model.bossFightProfile) {
this.model.bossFightProfile = this.createDefaultBossFightProfile(this.model.id);
}
// Set selected objects for dropdowns
this.selectedMobType = this.mobTypes.find(t => t.value === typeValue) || this.mobTypes[0] || null;
this.selectedGameBundle = this.gameBundles.find(b => b.value === fromValue) || this.gameBundles[0] || null;
this.cdr.detectChanges();
}
private createDefaultBossFightProfile(mobInfoId: string): BossFightProfile {
return {
id: 'bossfight_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9),
mobInfoId: mobInfoId || '',
prerequisite: '',
objective: '',
specialRules: '',
extraTokenName: '',
extraTokenHtml: '',
extraTokenName2: '',
extraTokenHtml2: '',
phaseBuffs: []
};
}
private initializeEnums(): void {
// Initialize MobType options
Object.keys(MobType).filter(key => isNaN(Number(key))).forEach(key => {
this.mobTypes.push({
value: MobType[key] as MobType,
text: key
});
});
// Initialize GameBundle options
Object.keys(GameBundle).filter(key => isNaN(Number(key))).forEach(key => {
this.gameBundles.push({
value: GameBundle[key] as GameBundle,
text: key
});
});
}
public close(): void {
this.dialog.close();
}
public save(): void {
if (this.model.name && !this.processing) {
this.processing = true;
const mobType = this.selectedMobType?.value ?? MobType.Mob;
// Ensure bossFightProfile is initialized for Boss type
let bossFightProfile = this.model.bossFightProfile;
if (mobType === MobType.Boss && !bossFightProfile) {
bossFightProfile = this.createDefaultBossFightProfile(this.model.id);
} else if (mobType !== MobType.Boss) {
bossFightProfile = undefined;
}
// Extract enum values from selected objects
const mobInfo: MD2MobInfo = {
...this.model,
type: mobType,
from: this.selectedGameBundle?.value ?? GameBundle.CoreGame,
mobLevelInfos: this.data?.mobLevelInfos || [],
skills: this.data?.skills || [],
bossFightProfile: bossFightProfile
};
this.mobInfoService.createOrUpdate(mobInfo).pipe(first()).subscribe(result => {
this.processing = false;
this.dialog.close(result);
}, error => {
this.processing = false;
console.error('Error saving mob info:', error);
});
}
}
public get isValid(): boolean {
if (!this.model) {
return false;
}
const nameValid = this.model.name && this.model.name.trim().length > 0;
const typeValid = this.selectedMobType !== null && this.selectedMobType !== undefined;
const fromValid = this.selectedGameBundle !== null && this.selectedGameBundle !== undefined;
return nameValid && typeValid && fromValid;
}
}