Init Boss Fight
This commit is contained in:
parent
ee6dc58a21
commit
a4391c84d0
@ -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 { 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 { 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 { 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 { 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';
|
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,
|
MD2MobInfoDetailComponent,
|
||||||
MD2MobSkillEditorComponent,
|
MD2MobSkillEditorComponent,
|
||||||
MD2MobLevelEditorComponent,
|
MD2MobLevelEditorComponent,
|
||||||
|
MD2BossFightEditorComponent,
|
||||||
|
MD2PhaseBuffEditorComponent,
|
||||||
MD2HeroProfileMaintenanceComponent,
|
MD2HeroProfileMaintenanceComponent,
|
||||||
MD2HeroProfileEditorComponent
|
MD2HeroProfileEditorComponent
|
||||||
],
|
],
|
||||||
|
|||||||
@ -0,0 +1,144 @@
|
|||||||
|
<div class="k-dialog-content">
|
||||||
|
<kendo-tabstrip tabPosition="top">
|
||||||
|
<kendo-tabstrip-tab title="Boss Fight Info" [selected]="true">
|
||||||
|
<ng-template kendoTabContent>
|
||||||
|
<form class="k-form" style="padding: 20px;">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">Prerequisite</label>
|
||||||
|
<md2-html-editor [(ngModel)]="model.prerequisite" name="prerequisite"
|
||||||
|
class="htmlEditor"></md2-html-editor>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">Objective</label>
|
||||||
|
<md2-html-editor [(ngModel)]="model.objective" name="objective"
|
||||||
|
class="htmlEditor"></md2-html-editor>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">Special Rules</label>
|
||||||
|
<md2-html-editor [(ngModel)]="model.specialRules" name="specialRules"
|
||||||
|
class="htmlEditor"></md2-html-editor>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">Extra Token Name</label>
|
||||||
|
<input kendoTextBox [(ngModel)]="model.extraTokenName" name="extraTokenName"
|
||||||
|
class="k-input" placeholder="Enter extra token name" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">Extra Token HTML</label>
|
||||||
|
<md2-html-editor [(ngModel)]="model.extraTokenHtml" name="extraTokenHtml"
|
||||||
|
class="htmlEditor"></md2-html-editor>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">Extra Token Name 2</label>
|
||||||
|
<input kendoTextBox [(ngModel)]="model.extraTokenName2" name="extraTokenName2"
|
||||||
|
class="k-input" placeholder="Enter extra token name 2" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">Extra Token HTML 2</label>
|
||||||
|
<md2-html-editor [(ngModel)]="model.extraTokenHtml2" name="extraTokenHtml2"
|
||||||
|
class="htmlEditor"></md2-html-editor>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</ng-template>
|
||||||
|
</kendo-tabstrip-tab>
|
||||||
|
|
||||||
|
<kendo-tabstrip-tab title="Phase Buffs">
|
||||||
|
<ng-template kendoTabContent>
|
||||||
|
<div style="padding: 20px;">
|
||||||
|
<div class="phase-buffs-toolbar" style="margin-bottom: 10px;">
|
||||||
|
<button kendoButton (click)="addPhaseBuffHandler()" [primary]="true">
|
||||||
|
<span class="k-icon k-i-plus"></span> Add Phase Buff
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<kendo-grid #phaseBuffsGrid [data]="phaseBuffsData" [loading]="isLoading"
|
||||||
|
[pageSize]="phaseBuffsState.take" [skip]="phaseBuffsState.skip" [sortable]="true"
|
||||||
|
[filterable]="true" [pageable]="true" [height]="400"
|
||||||
|
(remove)="removePhaseBuffHandler($event)" (dataStateChange)="phaseBuffsState = $event; loadPhaseBuffs()">
|
||||||
|
|
||||||
|
<kendo-grid-column field="phase" title="Phase" [width]="80">
|
||||||
|
<ng-template kendoGridCellTemplate let-dataItem>
|
||||||
|
{{ dataItem.phase }}
|
||||||
|
</ng-template>
|
||||||
|
</kendo-grid-column>
|
||||||
|
|
||||||
|
<kendo-grid-column field="extraAction" title="Extra Action" [width]="100">
|
||||||
|
<ng-template kendoGridCellTemplate let-dataItem>
|
||||||
|
{{ dataItem.extraAction }}
|
||||||
|
</ng-template>
|
||||||
|
</kendo-grid-column>
|
||||||
|
|
||||||
|
<kendo-grid-column field="extraHp" title="Extra HP" [width]="80">
|
||||||
|
<ng-template kendoGridCellTemplate let-dataItem>
|
||||||
|
{{ dataItem.extraHp }}
|
||||||
|
</ng-template>
|
||||||
|
</kendo-grid-column>
|
||||||
|
|
||||||
|
<kendo-grid-column field="extraTokenCount" title="Extra Token Count" [width]="120">
|
||||||
|
<ng-template kendoGridCellTemplate let-dataItem>
|
||||||
|
{{ dataItem.extraTokenCount }}
|
||||||
|
</ng-template>
|
||||||
|
</kendo-grid-column>
|
||||||
|
|
||||||
|
<kendo-grid-column field="extraTokenCount2" title="Extra Token Count 2" [width]="140">
|
||||||
|
<ng-template kendoGridCellTemplate let-dataItem>
|
||||||
|
{{ dataItem.extraTokenCount2 }}
|
||||||
|
</ng-template>
|
||||||
|
</kendo-grid-column>
|
||||||
|
|
||||||
|
<kendo-grid-column field="extraBuffDescription" title="Extra Buff Description" [width]="300">
|
||||||
|
<ng-template kendoGridCellTemplate let-dataItem>
|
||||||
|
<div *ngIf="dataItem.enableExtraBuffDescription" [innerHTML]="dataItem.extraBuffDescription">
|
||||||
|
</div>
|
||||||
|
<span *ngIf="!dataItem.enableExtraBuffDescription">-</span>
|
||||||
|
</ng-template>
|
||||||
|
</kendo-grid-column>
|
||||||
|
|
||||||
|
<kendo-grid-command-column title="Actions" [width]="133">
|
||||||
|
<ng-template kendoGridCellTemplate let-isNew="isNew" let-dataItem="dataItem"
|
||||||
|
let-rowIndex="rowIndex">
|
||||||
|
<button kendoButton [primary]="true" (click)="editPhaseBuffHandler(dataItem)">Edit</button>
|
||||||
|
<button kendoGridRemoveCommand>Remove</button>
|
||||||
|
</ng-template>
|
||||||
|
</kendo-grid-command-column>
|
||||||
|
</kendo-grid>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</kendo-tabstrip-tab>
|
||||||
|
</kendo-tabstrip>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<kendo-dialog-actions>
|
||||||
|
<button kendoButton (click)="close()">Cancel</button>
|
||||||
|
<button kendoButton [primary]="true" (click)="save()" [disabled]="!isValid || processing">
|
||||||
|
{{ processing ? 'Saving...' : 'Save' }}
|
||||||
|
</button>
|
||||||
|
</kendo-dialog-actions>
|
||||||
@ -0,0 +1 @@
|
|||||||
|
// Boss Fight Editor styles
|
||||||
@ -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 !== '';
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -183,5 +183,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<kendo-dialog-actions>
|
<kendo-dialog-actions>
|
||||||
|
<button kendoButton *ngIf="mobInfo?.type === MobType.Boss" (click)="editBossFightHandler()">Edit Boss Fight</button>
|
||||||
<button kendoButton [primary]="true" (click)="close()">Close</button>
|
<button kendoButton [primary]="true" (click)="close()">Close</button>
|
||||||
</kendo-dialog-actions>
|
</kendo-dialog-actions>
|
||||||
@ -3,13 +3,15 @@ import { DialogRef, DialogContentBase, DialogService } from '@progress/kendo-ang
|
|||||||
import { GridComponent, GridDataResult } from '@progress/kendo-angular-grid';
|
import { GridComponent, GridDataResult } from '@progress/kendo-angular-grid';
|
||||||
import { State } from '@progress/kendo-data-query';
|
import { State } from '@progress/kendo-data-query';
|
||||||
import { first } from 'rxjs/operators';
|
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 { MobType } from '../../massive-darkness2.model';
|
||||||
import { MobSkillType } from '../../massive-darkness2.model.boss';
|
import { MobSkillType } from '../../massive-darkness2.model.boss';
|
||||||
import { MD2MobLevelInfoService, MD2MobSkillService } from '../../service/massive-darkness2.service';
|
import { MD2MobLevelInfoService, MD2MobSkillService } from '../../service/massive-darkness2.service';
|
||||||
import { MsgBoxService } from '../../../../services/msg-box.service';
|
import { MsgBoxService } from '../../../../services/msg-box.service';
|
||||||
import { MD2MobSkillEditorComponent } from '../md2-mob-skill-editor/md2-mob-skill-editor.component';
|
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 { 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({
|
@Component({
|
||||||
selector: 'ngx-md2-mob-info-detail',
|
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 {
|
export class MD2MobInfoDetailComponent extends DialogContentBase implements OnInit {
|
||||||
MobSkillType = MobSkillType;
|
MobSkillType = MobSkillType;
|
||||||
|
MobType = MobType;
|
||||||
@Input() public mobInfo: MD2MobInfo;
|
@Input() public mobInfo: MD2MobInfo;
|
||||||
@ViewChild('levelsGrid') levelsGrid: GridComponent;
|
@ViewChild('levelsGrid') levelsGrid: GridComponent;
|
||||||
@ViewChild('skillsGrid') skillsGrid: GridComponent;
|
@ViewChild('skillsGrid') skillsGrid: GridComponent;
|
||||||
@ -54,6 +57,7 @@ export class MD2MobInfoDetailComponent extends DialogContentBase implements OnIn
|
|||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
private mobLevelInfoService: MD2MobLevelInfoService,
|
private mobLevelInfoService: MD2MobLevelInfoService,
|
||||||
private mobSkillService: MD2MobSkillService,
|
private mobSkillService: MD2MobSkillService,
|
||||||
|
private mobInfoService: MD2MobInfoService,
|
||||||
private msgBoxService: MsgBoxService
|
private msgBoxService: MsgBoxService
|
||||||
) {
|
) {
|
||||||
super(dialog);
|
super(dialog);
|
||||||
@ -434,6 +438,53 @@ export class MD2MobInfoDetailComponent extends DialogContentBase implements OnIn
|
|||||||
return GameBundle[bundle] || '';
|
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 {
|
public close(): void {
|
||||||
this.dialog.close(true);
|
this.dialog.close(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { Component, Input, OnInit, ViewChild, ChangeDetectorRef } from '@angular
|
|||||||
import { DialogRef, DialogContentBase } from '@progress/kendo-angular-dialog';
|
import { DialogRef, DialogContentBase } from '@progress/kendo-angular-dialog';
|
||||||
import { NgForm } from '@angular/forms';
|
import { NgForm } from '@angular/forms';
|
||||||
import { first } from 'rxjs/operators';
|
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 { MobType } from '../../massive-darkness2.model';
|
||||||
import { MD2MobInfoService } from '../../service/massive-darkness2.service';
|
import { MD2MobInfoService } from '../../service/massive-darkness2.service';
|
||||||
|
|
||||||
@ -48,9 +48,15 @@ export class MD2MobInfoEditorComponent extends DialogContentBase implements OnIn
|
|||||||
leaderImgUrl: this.data?.leaderImgUrl || '',
|
leaderImgUrl: this.data?.leaderImgUrl || '',
|
||||||
minionImgUrl: this.data?.minionImgUrl || '',
|
minionImgUrl: this.data?.minionImgUrl || '',
|
||||||
mobLevelInfos: this.data?.mobLevelInfos || [],
|
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
|
// Set selected objects for dropdowns
|
||||||
this.selectedMobType = this.mobTypes.find(t => t.value === typeValue) || this.mobTypes[0] || null;
|
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.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();
|
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 {
|
private initializeEnums(): void {
|
||||||
// Initialize MobType options
|
// Initialize MobType options
|
||||||
@ -85,13 +106,24 @@ export class MD2MobInfoEditorComponent extends DialogContentBase implements OnIn
|
|||||||
if (this.model.name && !this.processing) {
|
if (this.model.name && !this.processing) {
|
||||||
this.processing = true;
|
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
|
// Extract enum values from selected objects
|
||||||
const mobInfo: MD2MobInfo = {
|
const mobInfo: MD2MobInfo = {
|
||||||
...this.model,
|
...this.model,
|
||||||
type: this.selectedMobType?.value ?? MobType.Mob,
|
type: mobType,
|
||||||
from: this.selectedGameBundle?.value ?? GameBundle.CoreGame,
|
from: this.selectedGameBundle?.value ?? GameBundle.CoreGame,
|
||||||
mobLevelInfos: this.data?.mobLevelInfos || [],
|
mobLevelInfos: this.data?.mobLevelInfos || [],
|
||||||
skills: this.data?.skills || []
|
skills: this.data?.skills || [],
|
||||||
|
bossFightProfile: bossFightProfile
|
||||||
};
|
};
|
||||||
|
|
||||||
this.mobInfoService.createOrUpdate(mobInfo).pipe(first()).subscribe(result => {
|
this.mobInfoService.createOrUpdate(mobInfo).pipe(first()).subscribe(result => {
|
||||||
|
|||||||
@ -0,0 +1,180 @@
|
|||||||
|
<div class="k-dialog-content">
|
||||||
|
<form #form="ngForm" class="k-form">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">Phase *</label>
|
||||||
|
<kendo-numerictextbox [(ngModel)]="model.phase" name="phase" [min]="1" [decimals]="0"
|
||||||
|
[format]="'n0'">
|
||||||
|
</kendo-numerictextbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">Extra Action</label>
|
||||||
|
<kendo-numerictextbox [(ngModel)]="model.extraAction" name="extraAction" [min]="0" [decimals]="0"
|
||||||
|
[format]="'n0'">
|
||||||
|
</kendo-numerictextbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">
|
||||||
|
<md2-icon [icon]="MD2Icon.HP"></md2-icon>Extra HP</label>
|
||||||
|
<kendo-numerictextbox [(ngModel)]="model.extraHp" name="extraHp" [min]="0" [decimals]="0"
|
||||||
|
[format]="'n0'">
|
||||||
|
</kendo-numerictextbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">Extra Token Count</label>
|
||||||
|
<kendo-numerictextbox [(ngModel)]="model.extraTokenCount" name="extraTokenCount" [min]="0"
|
||||||
|
[decimals]="0" [format]="'n0'">
|
||||||
|
</kendo-numerictextbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">Extra Token Count 2</label>
|
||||||
|
<kendo-numerictextbox [(ngModel)]="model.extraTokenCount2" name="extraTokenCount2" [min]="0"
|
||||||
|
[decimals]="0" [format]="'n0'">
|
||||||
|
</kendo-numerictextbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">Enable Extra Buff Description</label>
|
||||||
|
<input type="checkbox" [(ngModel)]="model.enableExtraBuffDescription" name="enableExtraBuffDescription" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row" *ngIf="model.enableExtraBuffDescription">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">Extra Buff Description</label>
|
||||||
|
<textarea [(ngModel)]="model.extraBuffDescription" name="extraBuffDescription" rows="4" class="k-input" style="width: 100%;"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h5>Extra Attack Dice</h5>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">
|
||||||
|
<md2-icon [icon]="MD2Icon.Attack"></md2-icon>Attack Type</label>
|
||||||
|
<kendo-dropdownlist [(ngModel)]="selectedAttackType" name="extraAttackDice.type"
|
||||||
|
[data]="attackTypes" [textField]="'text'" [valueField]="'value'">
|
||||||
|
<ng-template kendoDropDownListItemTemplate let-dataItem>
|
||||||
|
<span [innerHTML]="dataItem.text"></span>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template kendoDropDownListValueTemplate let-dataItem>
|
||||||
|
<span [innerHTML]="dataItem?.text || ''"></span>
|
||||||
|
</ng-template>
|
||||||
|
</kendo-dropdownlist>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">
|
||||||
|
<md2-icon [icon]="MD2Icon.YellowDice"></md2-icon>Yellow Dice</label>
|
||||||
|
<kendo-numerictextbox [(ngModel)]="model.extraAttackDice.yellow" name="extraAttackDice.yellow"
|
||||||
|
[min]="0" [decimals]="0" [format]="'n0'">
|
||||||
|
</kendo-numerictextbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">
|
||||||
|
<md2-icon [icon]="MD2Icon.OrangeDice"></md2-icon>Orange Dice</label>
|
||||||
|
<kendo-numerictextbox [(ngModel)]="model.extraAttackDice.orange" name="extraAttackDice.orange"
|
||||||
|
[min]="0" [decimals]="0" [format]="'n0'">
|
||||||
|
</kendo-numerictextbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">
|
||||||
|
<md2-icon [icon]="MD2Icon.RedDice"></md2-icon>Red Dice</label>
|
||||||
|
<kendo-numerictextbox [(ngModel)]="model.extraAttackDice.red" name="extraAttackDice.red" [min]="0"
|
||||||
|
[decimals]="0" [format]="'n0'">
|
||||||
|
</kendo-numerictextbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">
|
||||||
|
<md2-icon [icon]="MD2Icon.BlackDice"></md2-icon>Black Dice</label>
|
||||||
|
<kendo-numerictextbox [(ngModel)]="model.extraAttackDice.black" name="extraAttackDice.black"
|
||||||
|
[min]="0" [decimals]="0" [format]="'n0'">
|
||||||
|
</kendo-numerictextbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h5>Extra Defence Dice</h5>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">
|
||||||
|
<md2-icon [icon]="MD2Icon.Defense"></md2-icon>Defence Type</label>
|
||||||
|
<kendo-dropdownlist [(ngModel)]="selectedDefenceType" name="extraDefenceDice.type"
|
||||||
|
[data]="attackTypes" [textField]="'text'" [valueField]="'value'">
|
||||||
|
<ng-template kendoDropDownListItemTemplate let-dataItem>
|
||||||
|
<span [innerHTML]="dataItem.text"></span>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template kendoDropDownListValueTemplate let-dataItem>
|
||||||
|
<span [innerHTML]="dataItem?.text || ''"></span>
|
||||||
|
</ng-template>
|
||||||
|
</kendo-dropdownlist>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">
|
||||||
|
<md2-icon [icon]="MD2Icon.BlueDice"></md2-icon>Blue Dice</label>
|
||||||
|
<kendo-numerictextbox [(ngModel)]="model.extraDefenceDice.blue" name="extraDefenceDice.blue"
|
||||||
|
[min]="0" [decimals]="0" [format]="'n0'">
|
||||||
|
</kendo-numerictextbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">
|
||||||
|
<md2-icon [icon]="MD2Icon.GreenDice"></md2-icon>Green Dice</label>
|
||||||
|
<kendo-numerictextbox [(ngModel)]="model.extraDefenceDice.green" name="extraDefenceDice.green"
|
||||||
|
[min]="0" [decimals]="0" [format]="'n0'">
|
||||||
|
</kendo-numerictextbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="k-label">
|
||||||
|
<md2-icon [icon]="MD2Icon.BlackDice"></md2-icon>Black Dice</label>
|
||||||
|
<kendo-numerictextbox [(ngModel)]="model.extraDefenceDice.black" name="extraDefenceDice.black"
|
||||||
|
[min]="0" [decimals]="0" [format]="'n0'">
|
||||||
|
</kendo-numerictextbox>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<kendo-dialog-actions>
|
||||||
|
<button kendoButton (click)="close()">Cancel</button>
|
||||||
|
<button kendoButton [primary]="true" (click)="save()" [disabled]="!isValid || processing">
|
||||||
|
{{ processing ? 'Saving...' : 'Save' }}
|
||||||
|
</button>
|
||||||
|
</kendo-dialog-actions>
|
||||||
@ -0,0 +1 @@
|
|||||||
|
// Phase Buff Editor styles
|
||||||
@ -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 !== '';
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { CrudService } from '../../../services/crudServices/crud.service';
|
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 { HttpClient } from '@angular/common/http';
|
||||||
import { MD2HeroProfile } from '../massive-darkness2.model';
|
import { MD2HeroProfile } from '../massive-darkness2.model';
|
||||||
|
|
||||||
@ -47,4 +47,26 @@ export class MD2HeroProfileService extends CrudService<MD2HeroProfile> {
|
|||||||
super(http, (action: string = null) => { return `MD2HeroProfile${(action ? `/${action}` : '')}` });
|
super(http, (action: string = null) => { return `MD2HeroProfile${(action ? `/${action}` : '')}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class MD2BossFightProfileService extends CrudService<BossFightProfile> {
|
||||||
|
|
||||||
|
constructor(http: HttpClient) {
|
||||||
|
super(http, (action: string = null) => { return `MD2BossFightProfile${(action ? `/${action}` : '')}` });
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class MD2PhaseBuffService extends CrudService<BossFightPhaseBuff> {
|
||||||
|
|
||||||
|
constructor(http: HttpClient) {
|
||||||
|
super(http, (action: string = null) => { return `MD2BossFightPhaseBuff${(action ? `/${action}` : '')}` });
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user