This commit is contained in:
Chris Chen 2025-11-14 13:53:44 -08:00
parent 9ea2278dfb
commit 3a12b6a4ab
7 changed files with 193 additions and 3 deletions

View File

@ -54,6 +54,7 @@ import { MD2BossFightEditorComponent } from './massive-darkness2/md2-mob-info-ma
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';
import { GameInitDlgComponent } from './massive-darkness2/game-init-dlg/game-init-dlg.component';
@NgModule({
@ -92,7 +93,8 @@ import { MD2HeroProfileEditorComponent } from './massive-darkness2/md2-hero-prof
MD2BossFightEditorComponent,
MD2PhaseBuffEditorComponent,
MD2HeroProfileMaintenanceComponent,
MD2HeroProfileEditorComponent
MD2HeroProfileEditorComponent,
GameInitDlgComponent
],
imports: [
CommonModule,

View File

@ -0,0 +1,40 @@
<nb-card status="info" size="large">
<nb-card-header>
<img src="{{md2Service.imgUrl('HeroIcon.png')}}" width="40px">
<span class="ml-2 g-font-size-17">Initialize Game</span>
</nb-card-header>
<nb-card-body>
<div class="form-group">
<label class="label">Select Game Bundles:</label>
<div class="form-group" *ngFor="let bundle of bundleOptions">
<nb-checkbox [checked]="isBundleEnabled(bundle.value)" (checkedChange)="toggleBundle(bundle.value)">
{{ bundle.label }}
</nb-checkbox>
</div>
<small class="form-text text-muted" *ngIf="enabledBundles.length === 0">
At least one bundle must be selected.
</small>
</div>
<div class="form-group">
<nb-checkbox [(checked)]="enableMobSpecialRule">
Enable Mob Special Rules
</nb-checkbox>
</div>
<div class="form-group">
<nb-checkbox [(checked)]="enableHeroBetrayal">
Enable Hero Betrayal
</nb-checkbox>
</div>
</nb-card-body>
<nb-card-footer>
<button class="float-right" nbButton hero status="warning" size="small" (click)="cancel()">
Cancel
</button>
<button class="float-right mr-2" nbButton hero status="primary" size="small"
[disabled]="enabledBundles.length === 0" (click)="submit()">
Initialize
</button>
</nb-card-footer>
</nb-card>

View File

@ -0,0 +1,12 @@
nb-card {
min-width: 400px;
}
.form-group {
margin-bottom: 1rem;
}
nb-checkbox {
display: block;
margin-bottom: 0.5rem;
}

View File

@ -0,0 +1,73 @@
import { Component, OnInit, Input } from '@angular/core';
import { NbDialogRef } from '@nebular/theme';
import { GameBundle } from '../massive-darkness2.db.model';
import { MD2Service } from '../../../services/MD2/md2.service';
export interface GameInitConfig {
enabledBundles: GameBundle[];
enableMobSpecialRule: boolean;
enableHeroBetrayal: boolean;
}
@Component({
selector: 'ngx-game-init-dlg',
templateUrl: './game-init-dlg.component.html',
styleUrls: ['./game-init-dlg.component.scss']
})
export class GameInitDlgComponent implements OnInit {
GameBundle = GameBundle;
@Input() initialConfig: GameInitConfig;
enabledBundles: GameBundle[] = [GameBundle.CoreGame];
enableMobSpecialRule: boolean = false;
enableHeroBetrayal: boolean = false;
bundleOptions = [
{ value: GameBundle.CoreGame, label: 'Core Game' },
{ value: GameBundle.HeavenFallen, label: 'Heaven Fallen' },
{ value: GameBundle.Zombiecide, label: 'Zombiecide' },
{ value: GameBundle.ZombiecideWhiteDeath, label: 'Zombiecide White Death' }
];
constructor(
private dlgRef: NbDialogRef<GameInitDlgComponent>,
public md2Service: MD2Service
) { }
ngOnInit(): void {
// Initialize from context if provided
if (this.initialConfig) {
this.enabledBundles = [...this.initialConfig.enabledBundles];
this.enableMobSpecialRule = this.initialConfig.enableMobSpecialRule;
this.enableHeroBetrayal = this.initialConfig.enableHeroBetrayal;
}
}
toggleBundle(bundle: GameBundle): void {
const index = this.enabledBundles.indexOf(bundle);
if (index > -1) {
this.enabledBundles.splice(index, 1);
} else {
this.enabledBundles.push(bundle);
}
}
isBundleEnabled(bundle: GameBundle): boolean {
return this.enabledBundles.includes(bundle);
}
submit(): void {
const config: GameInitConfig = {
enabledBundles: this.enabledBundles,
enableMobSpecialRule: this.enableMobSpecialRule,
enableHeroBetrayal: this.enableHeroBetrayal
};
this.dlgRef.close(config);
}
cancel(): void {
this.dlgRef.close();
}
}

View File

@ -17,6 +17,8 @@ import { SpawnMobDlgComponent } from './mobs/spawn-mob-dlg/spawn-mob-dlg.compone
import { BossMicheal } from './massive-darkness2.model.boss';
import { MD2InitService } from '../../services/MD2/md2-init.service';
import { NumberUtils } from '../../utilities/number-utils';
import { GameInitDlgComponent, GameInitConfig } from './game-init-dlg/game-init-dlg.component';
import { GameBundle } from './massive-darkness2.db.model';
@Component({
selector: 'ngx-massive-darkness2',
@ -43,9 +45,62 @@ export class MassiveDarkness2Component extends MD2Base implements OnInit {
ngOnInit(): void {
super.ngOnInit();
this.md2Service.enemyPhaseSubject.pipe(takeUntil(this.destroy$)).subscribe(result => {
this.showEnemyPhaseAction(0);
});
this.showGameInitDialog();
}
private showGameInitDialog() {
// Only show dialog if game hasn't been initialized yet
if (!this.md2Service.initialized) {
const dialogRef = this.msgBoxService.dlgService.open(GameInitDlgComponent, {
closeOnBackdropClick: false,
closeOnEsc: false,
context: {
initialConfig: {
enabledBundles: this.md2Service.info.enabledBundles?.length > 0
? this.md2Service.info.enabledBundles
: [GameBundle.CoreGame],
enableMobSpecialRule: this.md2Service.info.enableMobSpecialRule || false,
enableHeroBetrayal: this.md2Service.info.enableHeroBetrayal || false
}
}
});
dialogRef.onClose.pipe(first()).subscribe((config: GameInitConfig) => {
if (config) {
this.initGameBundles(config);
} else {
// User cancelled, use defaults
this.initGameBundles({
enabledBundles: [GameBundle.CoreGame],
enableMobSpecialRule: false,
enableHeroBetrayal: false
});
}
});
} else {
// Game already initialized, just use current settings
this.initGameBundles({
enabledBundles: this.md2Service.info.enabledBundles,
enableMobSpecialRule: this.md2Service.info.enableMobSpecialRule,
enableHeroBetrayal: this.md2Service.info.enableHeroBetrayal
});
}
}
private initGameBundles(config: GameInitConfig) {
this.md2Service.info.enabledBundles = config.enabledBundles;
this.md2Service.info.enableMobSpecialRule = config.enableMobSpecialRule;
this.md2Service.info.enableHeroBetrayal = config.enableHeroBetrayal;
if (this.md2Service.initialized == false) {
this.gameRoomService.createGameRoom('MD2');
this.md2Service.initialized = true;
}
this.initService.initMobDecks();
this.initService.initTreasureBag();
}
@ -78,10 +133,12 @@ export class MassiveDarkness2Component extends MD2Base implements OnInit {
}
showQrCode() {
if (this.md2Service.initialized == false) {
this.gameRoomService.createGameRoom('MD2');
this.md2Service.initialized = true;
}
let initUrl = `${window.location.origin}/games/MD2_Hero/${this.gameRoomService.gameRoomId}`;
this.msgBoxService.show("Scan To Join", { text: `<img src='${this.qrCodeService.QRCodeUrl(initUrl, 5)}'><br><a href='${initUrl}' target='_blank'>Link</a>` });
}

View File

@ -88,7 +88,9 @@ export class MobsComponent extends MD2ComponentBase implements OnInit {
}
spawnSpecificMob() {
let mobOptions = this.isRoamingMonster ? this.md2Service.allRoamingMonsterInfos.map(f => new DropDownOption(f.name, f.name)) : this.md2Service.allMobInfos.map(f => new DropDownOption(f.name, f.name));
let mobOptions = this.isRoamingMonster ?
this.md2Service.allRoamingMonsterInfos.map(f => new DropDownOption(f.name, f.name)) :
this.md2Service.allMobInfos.map(f => new DropDownOption(f.name, f.name));
this.msgBoxService.showInputbox('Spawn', '',
{
inputType: 'dropdown', dropDownOptions: mobOptions,

View File

@ -274,7 +274,7 @@ export class MD2Service {
this.enemyPhaseMobs = this.roamingMonsters.concat(this.mobs);
if (this.mobs.length > 0 && triggerSpecialRule) {
if (this.info.enableMobSpecialRule && this.mobs.length > 0 && triggerSpecialRule) {
let specialRuleDrawingBag = new DrawingBag<MD2EnemyPhaseSpecialRule>(this.specialRule.specialRules);
let specialRule = specialRuleDrawingBag.Draw(1)[0];
this.specialRule.specialRule = specialRule;
@ -883,4 +883,8 @@ export class MD2GameInfo {
public roundPhase: RoundPhase = RoundPhase.HeroPhase;
public showAttackBtn: boolean = false;
public boss: MobInfo;
public enabledBundles: GameBundle[] = [GameBundle.CoreGame];
public enableMobSpecialRule: boolean = false;
public enableHeroBetrayal: boolean = false;
}