diff --git a/src/app/games/games.module.ts b/src/app/games/games.module.ts
index 2440fb3..215ed5f 100644
--- a/src/app/games/games.module.ts
+++ b/src/app/games/games.module.ts
@@ -50,6 +50,8 @@ import { MD2MobInfoEditorComponent } from './massive-darkness2/md2-mob-info-main
import { MD2MobInfoDetailComponent } from './massive-darkness2/md2-mob-info-maintenance/md2-mob-info-detail/md2-mob-info-detail.component';
import { MD2MobSkillEditorComponent } from './massive-darkness2/md2-mob-info-maintenance/md2-mob-skill-editor/md2-mob-skill-editor.component';
import { MD2MobLevelEditorComponent } from './massive-darkness2/md2-mob-info-maintenance/md2-mob-level-editor/md2-mob-level-editor.component';
+import { MD2BossFightEditorComponent } from './massive-darkness2/md2-mob-info-maintenance/md2-boss-fight-editor/md2-boss-fight-editor.component';
+import { MD2PhaseBuffEditorComponent } from './massive-darkness2/md2-mob-info-maintenance/md2-phase-buff-editor/md2-phase-buff-editor.component';
import { MD2HeroProfileMaintenanceComponent } from './massive-darkness2/md2-hero-profile-maintenance/md2-hero-profile-maintenance.component';
import { MD2HeroProfileEditorComponent } from './massive-darkness2/md2-hero-profile-maintenance/md2-hero-profile-editor/md2-hero-profile-editor.component';
@@ -87,6 +89,8 @@ import { MD2HeroProfileEditorComponent } from './massive-darkness2/md2-hero-prof
MD2MobInfoDetailComponent,
MD2MobSkillEditorComponent,
MD2MobLevelEditorComponent,
+ MD2BossFightEditorComponent,
+ MD2PhaseBuffEditorComponent,
MD2HeroProfileMaintenanceComponent,
MD2HeroProfileEditorComponent
],
diff --git a/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-boss-fight-editor/md2-boss-fight-editor.component.html b/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-boss-fight-editor/md2-boss-fight-editor.component.html
new file mode 100644
index 0000000..38963c5
--- /dev/null
+++ b/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-boss-fight-editor/md2-boss-fight-editor.component.html
@@ -0,0 +1,144 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dataItem.phase }}
+
+
+
+
+
+ {{ dataItem.extraAction }}
+
+
+
+
+
+ {{ dataItem.extraHp }}
+
+
+
+
+
+ {{ dataItem.extraTokenCount }}
+
+
+
+
+
+ {{ dataItem.extraTokenCount2 }}
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-boss-fight-editor/md2-boss-fight-editor.component.scss b/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-boss-fight-editor/md2-boss-fight-editor.component.scss
new file mode 100644
index 0000000..f67848d
--- /dev/null
+++ b/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-boss-fight-editor/md2-boss-fight-editor.component.scss
@@ -0,0 +1 @@
+// Boss Fight Editor styles
diff --git a/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-boss-fight-editor/md2-boss-fight-editor.component.ts b/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-boss-fight-editor/md2-boss-fight-editor.component.ts
new file mode 100644
index 0000000..e596fe1
--- /dev/null
+++ b/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-boss-fight-editor/md2-boss-fight-editor.component.ts
@@ -0,0 +1,202 @@
+import { Component, Input, OnInit, ViewChild } from '@angular/core';
+import { DialogRef, DialogContentBase, DialogService } from '@progress/kendo-angular-dialog';
+import { GridComponent, GridDataResult } from '@progress/kendo-angular-grid';
+import { State } from '@progress/kendo-data-query';
+import { first } from 'rxjs/operators';
+import { BossFightProfile, BossFightPhaseBuff } from '../../massive-darkness2.db.model';
+import { MobSkillType } from '../../massive-darkness2.model.boss';
+import { MD2BossFightProfileService, MD2PhaseBuffService } from '../../service/massive-darkness2.service';
+import { MsgBoxService } from '../../../../services/msg-box.service';
+import { MD2PhaseBuffEditorComponent } from '../md2-phase-buff-editor/md2-phase-buff-editor.component';
+
+@Component({
+ selector: 'ngx-md2-boss-fight-editor',
+ templateUrl: './md2-boss-fight-editor.component.html',
+ styleUrls: ['./md2-boss-fight-editor.component.scss']
+})
+export class MD2BossFightEditorComponent extends DialogContentBase implements OnInit {
+ @Input() public data: BossFightProfile;
+ @Input() public mobInfoId: string;
+ @ViewChild('phaseBuffsGrid') phaseBuffsGrid: GridComponent;
+
+ public model: BossFightProfile;
+ public phaseBuffs: BossFightPhaseBuff[] = [];
+ public phaseBuffsData: GridDataResult = { data: [], total: 0 };
+ public phaseBuffsState: State = {
+ skip: 0,
+ take: 10,
+ sort: [],
+ filter: {
+ logic: 'and',
+ filters: []
+ }
+ };
+ public isLoading: boolean = false;
+ public processing: boolean = false;
+
+ constructor(
+ public dialog: DialogRef,
+ private dialogService: DialogService,
+ private bossFightProfileService: MD2BossFightProfileService,
+ private phaseBuffService: MD2PhaseBuffService,
+ private msgBoxService: MsgBoxService
+ ) {
+ super(dialog);
+ }
+
+ ngOnInit(): void {
+ this.initializeModel();
+ }
+
+ public initializeModel(): void {
+ this.model = {
+ id: this.data?.id || '',
+ mobInfoId: this.mobInfoId || this.data?.mobInfoId || '',
+ prerequisite: this.data?.prerequisite || '',
+ objective: this.data?.objective || '',
+ specialRules: this.data?.specialRules || '',
+ extraTokenName: this.data?.extraTokenName || '',
+ extraTokenHtml: this.data?.extraTokenHtml || '',
+ extraTokenName2: this.data?.extraTokenName2 || '',
+ extraTokenHtml2: this.data?.extraTokenHtml2 || '',
+ phaseBuffs: this.data?.phaseBuffs || []
+ };
+
+ this.phaseBuffs = this.model.phaseBuffs || [];
+ this.loadPhaseBuffs();
+ }
+
+ public loadPhaseBuffs(): void {
+ this.phaseBuffsData = {
+ data: this.phaseBuffs.sort((a, b) => a.phase - b.phase),
+ total: this.phaseBuffs.length
+ };
+ }
+
+ public addPhaseBuffHandler(): void {
+ if (!this.model) return;
+
+ const lastPhaseBuff = this.phaseBuffs.length > 0
+ ? this.phaseBuffs.reduce((prev, current) => (prev.phase > current.phase) ? prev : current)
+ : null;
+
+ const nextPhase = lastPhaseBuff ? lastPhaseBuff.phase + 1 : 1;
+
+ const newPhaseBuff: BossFightPhaseBuff = {
+ id: this.generatePhaseBuffId(),
+ bossFightProfileId: this.model.id,
+ phase: nextPhase,
+ extraAction: 0,
+ extraAttackDice: { type: MobSkillType.Attack, yellow: null, orange: null, red: null, blue: null, green: null, black: null },
+ extraDefenceDice: { type: MobSkillType.Defense, yellow: null, orange: null, red: null, blue: null, green: null, black: null },
+ extraHp: 0,
+ extraTokenCount: 0,
+ extraTokenCount2: 0,
+ enableExtraBuffDescription: false,
+ extraBuffDescription: ''
+ };
+
+ this.openPhaseBuffEditor(newPhaseBuff, true);
+ }
+
+ public editPhaseBuffHandler(dataItem: BossFightPhaseBuff): void {
+ if (!this.model) return;
+
+ const phaseBuffCopy: BossFightPhaseBuff = JSON.parse(JSON.stringify(dataItem));
+ this.openPhaseBuffEditor(phaseBuffCopy, false);
+ }
+
+ private openPhaseBuffEditor(phaseBuff: BossFightPhaseBuff, isNew: boolean): void {
+ if (!this.model) return;
+
+ const dialogRef = this.dialogService.open({
+ title: isNew ? 'Add New Phase Buff' : 'Edit Phase Buff',
+ content: MD2PhaseBuffEditorComponent,
+ width: '80vw',
+ height: 700
+ });
+
+ const editor = dialogRef.content.instance as MD2PhaseBuffEditorComponent;
+ editor.isAdding = isNew;
+ editor.data = phaseBuff;
+ editor.bossFightProfileId = this.model.id;
+
+ setTimeout(() => {
+ editor.initializeModel();
+ }, 0);
+
+ dialogRef.result.subscribe(result => {
+ if (result && typeof result === 'object' && 'id' in result) {
+ this.handlePhaseBuffSaved(result as BossFightPhaseBuff, isNew);
+ }
+ });
+ }
+
+ private handlePhaseBuffSaved(result: BossFightPhaseBuff, isNew: boolean): void {
+ if (!this.model) return;
+
+ if (isNew) {
+ if (!this.phaseBuffs) {
+ this.phaseBuffs = [];
+ }
+ this.phaseBuffs.push(result);
+ } else {
+ const index = this.phaseBuffs.findIndex(p => p.id === result.id);
+ if (index !== -1) {
+ this.phaseBuffs[index] = result;
+ }
+ }
+
+ this.model.phaseBuffs = this.phaseBuffs;
+ this.loadPhaseBuffs();
+ }
+
+ public removePhaseBuffHandler({ dataItem }: { dataItem: BossFightPhaseBuff }): void {
+ this.msgBoxService.showConfirmDeleteBox().pipe(first()).subscribe(answer => {
+ if (answer === true) {
+ this.isLoading = true;
+ this.phaseBuffService.delete(dataItem.id).pipe(first()).subscribe(result => {
+ const index = this.phaseBuffs.findIndex(p => p.id === dataItem.id);
+ if (index !== -1) {
+ this.phaseBuffs.splice(index, 1);
+ this.model.phaseBuffs = this.phaseBuffs;
+ this.loadPhaseBuffs();
+ }
+ this.isLoading = false;
+ });
+ }
+ });
+ }
+
+ private generatePhaseBuffId(): string {
+ return 'phasebuff_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
+ }
+
+ public close(): void {
+ this.dialog.close();
+ }
+
+ public save(): void {
+ if (!this.processing && this.model) {
+ this.processing = true;
+
+ this.model.phaseBuffs = this.phaseBuffs;
+ this.model.mobInfoId = this.mobInfoId || this.model.mobInfoId;
+
+ this.bossFightProfileService.createOrUpdate(this.model).pipe(first()).subscribe(result => {
+ this.processing = false;
+ this.dialog.close(result);
+ }, error => {
+ this.processing = false;
+ console.error('Error saving boss fight profile:', error);
+ });
+ }
+ }
+
+ public get isValid(): boolean {
+ if (!this.model) {
+ return false;
+ }
+ return this.model.mobInfoId !== '';
+ }
+}
diff --git a/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-mob-info-detail/md2-mob-info-detail.component.html b/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-mob-info-detail/md2-mob-info-detail.component.html
index dea2269..6721714 100644
--- a/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-mob-info-detail/md2-mob-info-detail.component.html
+++ b/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-mob-info-detail/md2-mob-info-detail.component.html
@@ -183,5 +183,6 @@
+
\ No newline at end of file
diff --git a/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-mob-info-detail/md2-mob-info-detail.component.ts b/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-mob-info-detail/md2-mob-info-detail.component.ts
index 038d914..1f30029 100644
--- a/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-mob-info-detail/md2-mob-info-detail.component.ts
+++ b/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-mob-info-detail/md2-mob-info-detail.component.ts
@@ -3,13 +3,15 @@ import { DialogRef, DialogContentBase, DialogService } from '@progress/kendo-ang
import { GridComponent, GridDataResult } from '@progress/kendo-angular-grid';
import { State } from '@progress/kendo-data-query';
import { first } from 'rxjs/operators';
-import { MD2MobInfo, MD2MobLevelInfo, MD2MobSkill, MobSkillTarget, GameBundle } from '../../massive-darkness2.db.model';
+import { MD2MobInfo, MD2MobLevelInfo, MD2MobSkill, MobSkillTarget, GameBundle, BossFightProfile } from '../../massive-darkness2.db.model';
import { MobType } from '../../massive-darkness2.model';
import { MobSkillType } from '../../massive-darkness2.model.boss';
import { MD2MobLevelInfoService, MD2MobSkillService } from '../../service/massive-darkness2.service';
import { MsgBoxService } from '../../../../services/msg-box.service';
import { MD2MobSkillEditorComponent } from '../md2-mob-skill-editor/md2-mob-skill-editor.component';
import { MD2MobLevelEditorComponent } from '../md2-mob-level-editor/md2-mob-level-editor.component';
+import { MD2BossFightEditorComponent } from '../md2-boss-fight-editor/md2-boss-fight-editor.component';
+import { MD2MobInfoService } from '../../service/massive-darkness2.service';
@Component({
selector: 'ngx-md2-mob-info-detail',
@@ -18,6 +20,7 @@ import { MD2MobLevelEditorComponent } from '../md2-mob-level-editor/md2-mob-leve
})
export class MD2MobInfoDetailComponent extends DialogContentBase implements OnInit {
MobSkillType = MobSkillType;
+ MobType = MobType;
@Input() public mobInfo: MD2MobInfo;
@ViewChild('levelsGrid') levelsGrid: GridComponent;
@ViewChild('skillsGrid') skillsGrid: GridComponent;
@@ -54,6 +57,7 @@ export class MD2MobInfoDetailComponent extends DialogContentBase implements OnIn
private dialogService: DialogService,
private mobLevelInfoService: MD2MobLevelInfoService,
private mobSkillService: MD2MobSkillService,
+ private mobInfoService: MD2MobInfoService,
private msgBoxService: MsgBoxService
) {
super(dialog);
@@ -434,6 +438,53 @@ export class MD2MobInfoDetailComponent extends DialogContentBase implements OnIn
return GameBundle[bundle] || '';
}
+ public editBossFightHandler(): void {
+ if (!this.mobInfo || this.mobInfo.type !== MobType.Boss) return;
+
+ // Ensure bossFightProfile is initialized
+ if (!this.mobInfo.bossFightProfile) {
+ this.mobInfo.bossFightProfile = {
+ id: 'bossfight_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9),
+ mobInfoId: this.mobInfo.id,
+ prerequisite: '',
+ objective: '',
+ specialRules: '',
+ extraTokenName: '',
+ extraTokenHtml: '',
+ extraTokenName2: '',
+ extraTokenHtml2: '',
+ phaseBuffs: []
+ };
+ }
+
+ // Create a copy of the boss fight profile for editing
+ const bossFightProfileCopy: BossFightProfile = JSON.parse(JSON.stringify(this.mobInfo.bossFightProfile));
+
+ const dialogRef = this.dialogService.open({
+ title: `Edit Boss Fight: ${this.mobInfo.name}`,
+ content: MD2BossFightEditorComponent,
+ width: '90vw',
+ height: '90vh'
+ });
+
+ const editor = dialogRef.content.instance as MD2BossFightEditorComponent;
+ editor.data = bossFightProfileCopy;
+ editor.mobInfoId = this.mobInfo.id;
+
+ setTimeout(() => {
+ editor.initializeModel();
+ }, 0);
+
+ dialogRef.result.subscribe(result => {
+ if (result && typeof result === 'object' && 'id' in result) {
+ // Reload mob info to get updated boss fight profile
+ this.mobInfoService.getById(this.mobInfo.id).pipe(first()).subscribe(mobInfo => {
+ this.mobInfo = mobInfo;
+ });
+ }
+ });
+ }
+
public close(): void {
this.dialog.close(true);
}
diff --git a/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-mob-info-editor/md2-mob-info-editor.component.ts b/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-mob-info-editor/md2-mob-info-editor.component.ts
index d0ad810..50cd28f 100644
--- a/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-mob-info-editor/md2-mob-info-editor.component.ts
+++ b/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-mob-info-editor/md2-mob-info-editor.component.ts
@@ -2,7 +2,7 @@ import { Component, Input, OnInit, ViewChild, ChangeDetectorRef } from '@angular
import { DialogRef, DialogContentBase } from '@progress/kendo-angular-dialog';
import { NgForm } from '@angular/forms';
import { first } from 'rxjs/operators';
-import { MD2MobInfo, GameBundle } from '../../massive-darkness2.db.model';
+import { MD2MobInfo, GameBundle, BossFightProfile } from '../../massive-darkness2.db.model';
import { MobType } from '../../massive-darkness2.model';
import { MD2MobInfoService } from '../../service/massive-darkness2.service';
@@ -48,9 +48,15 @@ export class MD2MobInfoEditorComponent extends DialogContentBase implements OnIn
leaderImgUrl: this.data?.leaderImgUrl || '',
minionImgUrl: this.data?.minionImgUrl || '',
mobLevelInfos: this.data?.mobLevelInfos || [],
- skills: this.data?.skills || []
+ 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;
@@ -58,6 +64,21 @@ export class MD2MobInfoEditorComponent extends DialogContentBase implements OnIn
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
@@ -85,13 +106,24 @@ export class MD2MobInfoEditorComponent extends DialogContentBase implements OnIn
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: this.selectedMobType?.value ?? MobType.Mob,
+ type: mobType,
from: this.selectedGameBundle?.value ?? GameBundle.CoreGame,
mobLevelInfos: this.data?.mobLevelInfos || [],
- skills: this.data?.skills || []
+ skills: this.data?.skills || [],
+ bossFightProfile: bossFightProfile
};
this.mobInfoService.createOrUpdate(mobInfo).pipe(first()).subscribe(result => {
diff --git a/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-phase-buff-editor/md2-phase-buff-editor.component.html b/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-phase-buff-editor/md2-phase-buff-editor.component.html
new file mode 100644
index 0000000..1f8eeba
--- /dev/null
+++ b/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-phase-buff-editor/md2-phase-buff-editor.component.html
@@ -0,0 +1,180 @@
+
+
+
+
+
+
diff --git a/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-phase-buff-editor/md2-phase-buff-editor.component.scss b/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-phase-buff-editor/md2-phase-buff-editor.component.scss
new file mode 100644
index 0000000..4a987b3
--- /dev/null
+++ b/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-phase-buff-editor/md2-phase-buff-editor.component.scss
@@ -0,0 +1 @@
+// Phase Buff Editor styles
diff --git a/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-phase-buff-editor/md2-phase-buff-editor.component.ts b/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-phase-buff-editor/md2-phase-buff-editor.component.ts
new file mode 100644
index 0000000..090e6ec
--- /dev/null
+++ b/src/app/games/massive-darkness2/md2-mob-info-maintenance/md2-phase-buff-editor/md2-phase-buff-editor.component.ts
@@ -0,0 +1,114 @@
+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 { BossFightPhaseBuff, MD2DiceSet } from '../../massive-darkness2.db.model';
+import { MobSkillType } from '../../massive-darkness2.model.boss';
+import { MD2PhaseBuffService } from '../../service/massive-darkness2.service';
+import { MD2Icon } from '../../massive-darkness2.model';
+import { MD2Service } from '../../../../services/MD2/md2.service';
+
+@Component({
+ selector: 'ngx-md2-phase-buff-editor',
+ templateUrl: './md2-phase-buff-editor.component.html',
+ styleUrls: ['./md2-phase-buff-editor.component.scss']
+})
+export class MD2PhaseBuffEditorComponent extends DialogContentBase implements OnInit {
+ MD2Icon = MD2Icon;
+ MobSkillType = MobSkillType;
+ @Input() public data: BossFightPhaseBuff;
+ @Input() public bossFightProfileId: string;
+ @Input() public isAdding: boolean = false;
+ @ViewChild('form') form: NgForm;
+
+ public model: BossFightPhaseBuff;
+ public processing: boolean = false;
+ public attackTypes: Array<{ value: MobSkillType; text: string }> = [];
+ public selectedAttackType: { value: MobSkillType; text: string } | null = null;
+ public selectedDefenceType: { value: MobSkillType; text: string } | null = null;
+
+ constructor(
+ public dialog: DialogRef,
+ private phaseBuffService: MD2PhaseBuffService,
+ private cdr: ChangeDetectorRef,
+ private md2Service: MD2Service
+ ) {
+ super(dialog);
+ }
+
+ ngOnInit(): void {
+ this.initializeModel();
+ this.initializeEnums();
+ }
+
+ public initializeEnums(): void {
+ this.attackTypes = [
+ { value: MobSkillType.Attack, text: 'None' },
+ { 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' },
+ { value: MobSkillType.Defense, text: this.md2Service.iconHtml(MD2Icon.Defense) + ' Defense' }
+ ];
+ this.selectedAttackType = this.attackTypes.find(t => t.value === this.model.extraAttackDice?.type) || this.attackTypes[0] || null;
+ this.selectedDefenceType = this.attackTypes.find(t => t.value === this.model.extraDefenceDice?.type) || this.attackTypes[4] || null;
+ }
+
+ public initializeModel(): void {
+ this.model = {
+ id: this.data?.id || '',
+ bossFightProfileId: this.bossFightProfileId || this.data?.bossFightProfileId || '',
+ phase: this.data?.phase ?? 1,
+ extraAction: this.data?.extraAction ?? 0,
+ extraAttackDice: this.data?.extraAttackDice
+ ? { ...this.data.extraAttackDice }
+ : { type: MobSkillType.Attack, yellow: null, orange: null, red: null, blue: null, green: null, black: null },
+ extraDefenceDice: this.data?.extraDefenceDice
+ ? { ...this.data.extraDefenceDice }
+ : { type: MobSkillType.Defense, yellow: null, orange: null, red: null, blue: null, green: null, black: null },
+ extraHp: this.data?.extraHp ?? 0,
+ extraTokenCount: this.data?.extraTokenCount ?? 0,
+ extraTokenCount2: this.data?.extraTokenCount2 ?? 0,
+ enableExtraBuffDescription: this.data?.enableExtraBuffDescription ?? false,
+ extraBuffDescription: this.data?.extraBuffDescription || ''
+ };
+
+ this.cdr.detectChanges();
+ }
+
+ public close(): void {
+ this.dialog.close();
+ }
+
+ public save(): void {
+ if (!this.processing) {
+ this.processing = true;
+
+ // Ensure required objects exist
+ if (!this.model.extraAttackDice) {
+ this.model.extraAttackDice = { type: MobSkillType.Attack, yellow: null, orange: null, red: null, blue: null, green: null, black: null };
+ }
+ if (!this.model.extraDefenceDice) {
+ this.model.extraDefenceDice = { type: MobSkillType.Defense, yellow: null, orange: null, red: null, blue: null, green: null, black: null };
+ }
+
+ this.model.extraAttackDice.type = this.selectedAttackType?.value ?? MobSkillType.Attack;
+ this.model.extraDefenceDice.type = this.selectedDefenceType?.value ?? MobSkillType.Defense;
+ this.model.bossFightProfileId = this.bossFightProfileId || this.model.bossFightProfileId;
+
+ this.phaseBuffService.createOrUpdate(this.model).pipe(first()).subscribe(result => {
+ this.processing = false;
+ this.dialog.close(result);
+ }, error => {
+ this.processing = false;
+ console.error('Error saving phase buff:', error);
+ });
+ }
+ }
+
+ public get isValid(): boolean {
+ if (!this.model) {
+ return false;
+ }
+ return this.model.phase > 0 && this.model.bossFightProfileId !== '';
+ }
+}
diff --git a/src/app/games/massive-darkness2/service/massive-darkness2.service.ts b/src/app/games/massive-darkness2/service/massive-darkness2.service.ts
index efc3519..279be6c 100644
--- a/src/app/games/massive-darkness2/service/massive-darkness2.service.ts
+++ b/src/app/games/massive-darkness2/service/massive-darkness2.service.ts
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { CrudService } from '../../../services/crudServices/crud.service';
-import { MD2MobInfo, MD2MobLevelInfo, MD2MobSkill } from '../massive-darkness2.db.model';
+import { MD2MobInfo, MD2MobLevelInfo, MD2MobSkill, BossFightProfile, BossFightPhaseBuff } from '../massive-darkness2.db.model';
import { HttpClient } from '@angular/common/http';
import { MD2HeroProfile } from '../massive-darkness2.model';
@@ -47,4 +47,26 @@ export class MD2HeroProfileService extends CrudService {
super(http, (action: string = null) => { return `MD2HeroProfile${(action ? `/${action}` : '')}` });
}
+}
+
+@Injectable({
+ providedIn: 'root'
+})
+export class MD2BossFightProfileService extends CrudService {
+
+ constructor(http: HttpClient) {
+ super(http, (action: string = null) => { return `MD2BossFightProfile${(action ? `/${action}` : '')}` });
+ }
+
+}
+
+@Injectable({
+ providedIn: 'root'
+})
+export class MD2PhaseBuffService extends CrudService {
+
+ constructor(http: HttpClient) {
+ super(http, (action: string = null) => { return `MD2BossFightPhaseBuff${(action ? `/${action}` : '')}` });
+ }
+
}
\ No newline at end of file