From 3a12b6a4ab0ae7fff2401fdb8a6f7d53bac33471 Mon Sep 17 00:00:00 2001 From: Chris Chen Date: Fri, 14 Nov 2025 13:53:44 -0800 Subject: [PATCH] WIP --- src/app/games/games.module.ts | 4 +- .../game-init-dlg.component.html | 40 ++++++++++ .../game-init-dlg.component.scss | 12 +++ .../game-init-dlg/game-init-dlg.component.ts | 73 +++++++++++++++++++ .../massive-darkness2.component.ts | 57 +++++++++++++++ .../massive-darkness2/mobs/mobs.component.ts | 4 +- src/app/services/MD2/md2.service.ts | 6 +- 7 files changed, 193 insertions(+), 3 deletions(-) create mode 100644 src/app/games/massive-darkness2/game-init-dlg/game-init-dlg.component.html create mode 100644 src/app/games/massive-darkness2/game-init-dlg/game-init-dlg.component.scss create mode 100644 src/app/games/massive-darkness2/game-init-dlg/game-init-dlg.component.ts diff --git a/src/app/games/games.module.ts b/src/app/games/games.module.ts index 215ed5f..9b80a04 100644 --- a/src/app/games/games.module.ts +++ b/src/app/games/games.module.ts @@ -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, diff --git a/src/app/games/massive-darkness2/game-init-dlg/game-init-dlg.component.html b/src/app/games/massive-darkness2/game-init-dlg/game-init-dlg.component.html new file mode 100644 index 0000000..050f5a7 --- /dev/null +++ b/src/app/games/massive-darkness2/game-init-dlg/game-init-dlg.component.html @@ -0,0 +1,40 @@ + + + + Initialize Game + + +
+ +
+ + {{ bundle.label }} + +
+ + At least one bundle must be selected. + +
+ +
+ + Enable Mob Special Rules + +
+ +
+ + Enable Hero Betrayal + +
+
+ + + + +
\ No newline at end of file diff --git a/src/app/games/massive-darkness2/game-init-dlg/game-init-dlg.component.scss b/src/app/games/massive-darkness2/game-init-dlg/game-init-dlg.component.scss new file mode 100644 index 0000000..f7cfd87 --- /dev/null +++ b/src/app/games/massive-darkness2/game-init-dlg/game-init-dlg.component.scss @@ -0,0 +1,12 @@ +nb-card { + min-width: 400px; +} + +.form-group { + margin-bottom: 1rem; +} + +nb-checkbox { + display: block; + margin-bottom: 0.5rem; +} diff --git a/src/app/games/massive-darkness2/game-init-dlg/game-init-dlg.component.ts b/src/app/games/massive-darkness2/game-init-dlg/game-init-dlg.component.ts new file mode 100644 index 0000000..6efba2a --- /dev/null +++ b/src/app/games/massive-darkness2/game-init-dlg/game-init-dlg.component.ts @@ -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, + 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(); + } +} + diff --git a/src/app/games/massive-darkness2/massive-darkness2.component.ts b/src/app/games/massive-darkness2/massive-darkness2.component.ts index f779c9c..18716f7 100644 --- a/src/app/games/massive-darkness2/massive-darkness2.component.ts +++ b/src/app/games/massive-darkness2/massive-darkness2.component.ts @@ -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: `
Link` }); } diff --git a/src/app/games/massive-darkness2/mobs/mobs.component.ts b/src/app/games/massive-darkness2/mobs/mobs.component.ts index 960ee62..1b0eec3 100644 --- a/src/app/games/massive-darkness2/mobs/mobs.component.ts +++ b/src/app/games/massive-darkness2/mobs/mobs.component.ts @@ -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, diff --git a/src/app/services/MD2/md2.service.ts b/src/app/services/MD2/md2.service.ts index 2d840ef..bbbedca 100644 --- a/src/app/services/MD2/md2.service.ts +++ b/src/app/services/MD2/md2.service.ts @@ -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(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; } \ No newline at end of file