From e5933104cc150d49beafd44586da978eb25fe61a Mon Sep 17 00:00:00 2001 From: Chris Chen Date: Tue, 4 Nov 2025 18:13:43 -0800 Subject: [PATCH] WIP --- .hintrc | 13 + .../factorys/mobs/CoreGame.ts | 222 ------------------ .../factorys/roamingMonsters/CoreGame.ts | 76 +++--- .../massive-darkness2.component.html | 1 - .../massive-darkness2.db.model.ts | 1 + .../massive-darkness2.model.boss.ts | 35 +-- .../massive-darkness2.model.ts | 15 +- .../md2-icon/md2-icon.component.html | 2 +- .../md2-icon/md2-icon.component.ts | 30 ++- .../md2-mob-info-detail.component.ts | 75 ++++-- .../mob-combat-info.component.html | 16 +- .../mob-combat-info.component.scss | 7 +- .../mob-combat-info.component.ts | 36 +-- .../massive-darkness2/mobs/mobs.component.ts | 3 +- src/app/services/MD2/md2-init.service.ts | 29 ++- src/app/services/MD2/md2-state.service.ts | 2 + src/app/services/MD2/md2.service.ts | 38 ++- .../styles/form-controls/_scrollbars.scss | 18 +- 18 files changed, 262 insertions(+), 357 deletions(-) create mode 100644 .hintrc delete mode 100644 src/app/games/massive-darkness2/factorys/mobs/CoreGame.ts diff --git a/.hintrc b/.hintrc new file mode 100644 index 0000000..ae62a1a --- /dev/null +++ b/.hintrc @@ -0,0 +1,13 @@ +{ + "extends": [ + "development" + ], + "hints": { + "axe/text-alternatives": [ + "default", + { + "image-alt": "off" + } + ] + } +} \ No newline at end of file diff --git a/src/app/games/massive-darkness2/factorys/mobs/CoreGame.ts b/src/app/games/massive-darkness2/factorys/mobs/CoreGame.ts deleted file mode 100644 index 7f7ca0a..0000000 --- a/src/app/games/massive-darkness2/factorys/mobs/CoreGame.ts +++ /dev/null @@ -1,222 +0,0 @@ -import { environment } from "../../../../../environments/environment"; -import { DefenseInfo, IMobFactory, MD2Icon, MobInfo } from "../../massive-darkness2.model"; -import { MobSkill, MobSkillType } from "../../massive-darkness2.model.boss"; - -const MD2_IMG_URL = (id: string = null) => { return `${environment.apiUrl}/Files/Images/MD2/Mobs${(id ? `${encodeURI(id)}` : '')}` } -const CORE_GAME_MOB_LEVEL = [ - { name: 'Gargoyles', level: 1, hp: 2, rewardTokens: 1, defBlue: 1 }, - { name: 'Gargoyles', level: 3, hp: 3, rewardTokens: 1, defBlue: 2 }, - { name: 'Gargoyles', level: 5, hp: 6, rewardTokens: 2, defBlue: 3 }, - - { name: 'Demons', level: 1, hp: 3, rewardTokens: 1, defBlue: 1 }, - { name: 'Demons', level: 3, hp: 4, rewardTokens: 1, defBlue: 2 }, - { name: 'Demons', level: 5, hp: 6, rewardTokens: 2, defBlue: 4 }, - - { name: 'Undead', level: 1, hp: 4, rewardTokens: 1, defBlue: 1 }, - { name: 'Undead', level: 3, hp: 5, rewardTokens: 1, defBlue: 1 }, - { name: 'Undead', level: 5, hp: 8, rewardTokens: 2, defBlue: 1 }, - - { name: 'Fire Entities', level: 1, hp: 3, rewardTokens: 1, defBlue: 1 }, - { name: 'Fire Entities', level: 3, hp: 4, rewardTokens: 1, defBlue: 2 }, - { name: 'Fire Entities', level: 5, hp: 7, rewardTokens: 2, defBlue: 3 }, - - { name: 'Fallen Angels', level: 1, hp: 2, rewardTokens: 1, defBlue: 2 }, - { name: 'Fallen Angels', level: 3, hp: 3, rewardTokens: 1, defBlue: 3 }, - { name: 'Fallen Angels', level: 5, hp: 5, rewardTokens: 2, defBlue: 5 }, - - { name: 'Infernal Imps', level: 1, hp: 3, rewardTokens: 1, defBlue: 1 }, - { name: 'Infernal Imps', level: 3, hp: 4, rewardTokens: 1, defBlue: 1 }, - { name: 'Infernal Imps', level: 5, hp: 5, rewardTokens: 2, defBlue: 3 }, - - { name: 'Skeletons', level: 1, hp: 2, rewardTokens: 1, defBlue: 1 }, - { name: 'Skeletons', level: 3, hp: 3, rewardTokens: 1, defBlue: 2 }, - { name: 'Skeletons', level: 5, hp: 5, rewardTokens: 2, defBlue: 4 }, - - { name: 'Satyrs', level: 1, hp: 3, rewardTokens: 1, defBlue: 1 }, - { name: 'Satyrs', level: 3, hp: 4, rewardTokens: 1, defBlue: 2 }, - { name: 'Satyrs', level: 5, hp: 6, rewardTokens: 2, defBlue: 4 }] - -export abstract class MobFactory implements IMobFactory { - abstract mobName: string; - abstract generate(level: number): MobInfo - protected mob: MobInfo; - protected loadLevelInfo(mobName: string, level: number) { - let levelInfo = CORE_GAME_MOB_LEVEL.find(m => m.name == mobName && level >= m.level); - - this.mob = new MobInfo({ - name: mobName, hp: levelInfo.hp, level: level, rewardTokens: levelInfo.rewardTokens, - defenseInfo: new DefenseInfo(levelInfo.defBlue) - }); - this.mob.leaderImgUrl = MD2_IMG_URL(`/CoreGame/Mobs/${this.mob.name}/Leader.png`); - this.mob.minionImgUrl = MD2_IMG_URL(`/CoreGame/Mobs/${this.mob.name}/Minion.png`); - - } - iconHtml(icon: MD2Icon, cssClass = 'g-font-size-24') { - if (icon == MD2Icon.Fire) { - cssClass += ' g-color-google-plus '; - } - if (icon == MD2Icon.Frost || icon == MD2Icon.Mana) { - cssClass += ' g-color-aqua '; - } - - if (icon < MD2Icon.RedDice) { - return `${String.fromCharCode(65 + icon)}` - - } - else { - return ``; - } - } -} -export class MobDemonsFactory extends MobFactory { - mobName: string = 'Demons'; - generate(level: number): MobInfo { - this.loadLevelInfo('Demons', level); - this.mob.combatSkill = new MobSkill( - { - description: `Attacking or defending Hero discards 1 ${this.iconHtml(MD2Icon.Mana)}` - } - ) - return this.mob; - } - -} -export class MobFallenAngelFactory extends MobFactory { - mobName: string = 'Fallen Angels'; - generate(level: number): MobInfo { - this.loadLevelInfo('Fallen Angels', level); - this.mob.combatSkill = new MobSkill( - { - description: `Defender -${level == 1 ? 1 : 2} ${this.iconHtml(MD2Icon.Defense)}`, - type: MobSkillType.Attack - } - ) - return this.mob; - } -} - -export class MobFireEntitiesFactory extends MobFactory { - mobName: string = 'Fire Entities'; - generate(level: number): MobInfo { - this.loadLevelInfo('Fire Entities', level); - this.mob.combatSkill = new MobSkill( - { - description: `Add 1 ${this.iconHtml(MD2Icon.Fire)} to the attacking or defending Hero.`, - type: MobSkillType.Combat - } - ) - return this.mob; - } -} - -export class MobGargoylesFactory extends MobFactory { - mobName: string = 'Gargoyles'; - generate(level: number): MobInfo { - this.loadLevelInfo('Gargoyles', level); - this.mob.combatSkill = new MobSkill( - { - description: `+ ${level < 5 ? 1 : 2} ${this.iconHtml(MD2Icon.Defense)}`, - type: MobSkillType.Defense - } - ) - return this.mob; - } -} -export class MobInfernalImpsFactory extends MobFactory { - mobName: string = 'Infernal Imps'; - generate(level: number): MobInfo { - this.loadLevelInfo('Infernal Imps', level); - let damage = 1; - switch (level) { - case 1: - case 2: - damage = 1; - break; - case 3: - case 4: - damage = 2; - break; - case 5: - damage = 3; - break; - - default: - damage = 1; - break; - } - this.mob.combatSkill = new MobSkill( - { - description: `Kill 1 Imp, then deal ${damage} Wound to each Hero in the attacker's Zone(once per roll).`, - type: MobSkillType.Defense - } - ) - return this.mob; - } -} -export class MobSatyrsFactory extends MobFactory { - mobName: string = 'Satyrs'; - generate(level: number): MobInfo { - this.loadLevelInfo('Satyrs', level); - this.mob.combatSkill = new MobSkill( - { - description: `+ ${level < 3 ? 1 : 2} ${this.iconHtml(MD2Icon.Attack)}`, - type: MobSkillType.Attack - } - ) - return this.mob; - } -} - -export class MobSkeletonsFactory extends MobFactory { - mobName: string = 'Skeletons'; - generate(level: number): MobInfo { - this.loadLevelInfo('Skeletons', level); - this.mob.combatSkill = new MobSkill( - { - description: `Add 1 minion to this Mob(if possible) unless the Hero discards ${level < 5 ? 1 : 2} ${this.iconHtml(MD2Icon.Mana)}.`, - type: MobSkillType.Defense, - skillRoll: 2 - } - ) - return this.mob; - } -} - -export class MobUndeadFactory extends MobFactory { - mobName: string = 'Undead'; - generate(level: number): MobInfo { - this.loadLevelInfo('Undead', level); - - let skillDesc = ''; - if (level < 3) { - skillDesc = `+1 ${this.iconHtml(MD2Icon.YellowDice)}`; - } else if (level < 5) { - skillDesc = `+2 ${this.iconHtml(MD2Icon.YellowDice)}`; - - } else { - skillDesc = `+1 ${this.iconHtml(MD2Icon.YellowDice)} 1 ${this.iconHtml(MD2Icon.OrangeDice)}`; - - } - skillDesc += ' and this Mob takes 2 wounds'; - this.mob.combatSkill = new MobSkill( - { - description: skillDesc, - type: MobSkillType.Attack - } - ) - this.mob.drawingWeight = 1; - return this.mob; - } -} - - -export const CoreGameMobFactories = [ - new MobDemonsFactory(), - new MobFallenAngelFactory(), - new MobFireEntitiesFactory(), - new MobGargoylesFactory(), - new MobInfernalImpsFactory(), - new MobSatyrsFactory(), - new MobSkeletonsFactory(), - new MobUndeadFactory(), -]; \ No newline at end of file diff --git a/src/app/games/massive-darkness2/factorys/roamingMonsters/CoreGame.ts b/src/app/games/massive-darkness2/factorys/roamingMonsters/CoreGame.ts index b3adc40..54dd76e 100644 --- a/src/app/games/massive-darkness2/factorys/roamingMonsters/CoreGame.ts +++ b/src/app/games/massive-darkness2/factorys/roamingMonsters/CoreGame.ts @@ -3,8 +3,9 @@ import { first, map } from "rxjs/operators"; import { environment } from "../../../../../environments/environment"; import { ADButtons, ADIcon } from "../../../../ui/alert-dlg/alert-dlg.model"; import { MD2Logic } from "../../massive-darkness2.logic"; -import { AttackInfo, AttackTarget, DefenseInfo, IMobFactory, MD2Icon, MobInfo, MobType, TreasureItem, TreasureType } from "../../massive-darkness2.model"; -import { MobSkill, MobSkillType } from "../../massive-darkness2.model.boss"; +import { AttackInfo, AttackTarget, IMobFactory, MD2Icon, MobInfo, MobType, TreasureItem, TreasureType } from "../../massive-darkness2.model"; +import { MobSkillType } from "../../massive-darkness2.model.boss"; +import { MD2DiceSet, MD2MobSkill } from "../../massive-darkness2.db.model"; const MD2_IMG_URL = (id: string = null) => { return `${environment.apiUrl}/Files/Images/MD2/Mobs${(id ? `${encodeURI(id)}` : '')}` } const CORE_GAME_MOB_LEVEL = [ @@ -13,68 +14,68 @@ const CORE_GAME_MOB_LEVEL = [ name: 'Andra', level: 1, hp: 5, attackInfos: [new AttackInfo(MD2Icon.Melee, 1, 0, 0, 1), new AttackInfo(MD2Icon.Range, 1, 0, 0, 1)], - defenseInfo: new DefenseInfo(2, 1), + defenseInfo: { blue: 2, black: 1 } as MD2DiceSet, }), new MobInfo({ name: 'Andra', level: 3, hp: 7, attackInfos: [new AttackInfo(MD2Icon.Melee, 1, 1, 0, 1), new AttackInfo(MD2Icon.Range, 1, 1, 0, 1)], - defenseInfo: new DefenseInfo(3, 1), + defenseInfo: { blue: 3, black: 1 } as MD2DiceSet, }), new MobInfo({ name: 'Andra', level: 5, hp: 5, attackInfos: [new AttackInfo(MD2Icon.Melee, 1, 2, 0, 1), new AttackInfo(MD2Icon.Range, 1, 2, 0, 1)], - defenseInfo: new DefenseInfo(5, 1), + defenseInfo: { blue: 5, black: 1 } as MD2DiceSet, }), new MobInfo({ name: 'Ytheria, Undead Queen', level: 1, hp: 4, attackInfos: [new AttackInfo(MD2Icon.Melee, 1), new AttackInfo(MD2Icon.Range, 2, 0, 0, 1)], - defenseInfo: new DefenseInfo(1, 1), + defenseInfo: { blue: 1, black: 1 } as MD2DiceSet, }), new MobInfo({ name: 'Ytheria, Undead Queen', level: 3, hp: 6, attackInfos: [new AttackInfo(MD2Icon.Melee, 0, 1), new AttackInfo(MD2Icon.Range, 1, 1, 0, 1)], - defenseInfo: new DefenseInfo(2, 1), + defenseInfo: { blue: 2, black: 1 } as MD2DiceSet, }), new MobInfo({ name: 'Ytheria, Undead Queen', level: 5, hp: 8, attackInfos: [new AttackInfo(MD2Icon.Melee, 2, 1), new AttackInfo(MD2Icon.Range, 2, 1, 0, 1)], - defenseInfo: new DefenseInfo(4, 1), + defenseInfo: { blue: 4, black: 1 } as MD2DiceSet, }), new MobInfo({ name: 'Lyidan, Incubus Lord', level: 1, hp: 7, attackInfos: [new AttackInfo(MD2Icon.Melee, 0, 1, 0, 2)], - defenseInfo: new DefenseInfo(2, 1), + defenseInfo: { blue: 2, black: 1 } as MD2DiceSet, }), new MobInfo({ name: 'Lyidan, Incubus Lord', level: 3, hp: 10, attackInfos: [new AttackInfo(MD2Icon.Melee, 0, 2, 0, 1)], - defenseInfo: new DefenseInfo(2, 1), + defenseInfo: { blue: 2, black: 1 } as MD2DiceSet, }), new MobInfo({ name: 'Lyidan, Incubus Lord', level: 5, hp: 12, attackInfos: [new AttackInfo(MD2Icon.Melee, 2, 2, 0, 1)], - defenseInfo: new DefenseInfo(4, 1), + defenseInfo: { blue: 4, black: 1 } as MD2DiceSet, }), new MobInfo({ name: 'The Ghoul', level: 1, hp: 5, attackInfos: [new AttackInfo(MD2Icon.Melee, 0, 1, 0, 1)], - defenseInfo: new DefenseInfo(2, 1), + defenseInfo: { blue: 2, black: 1 } as MD2DiceSet, }), new MobInfo({ name: 'The Ghoul', level: 3, hp: 8, attackInfos: [new AttackInfo(MD2Icon.Melee, 0, 2, 0, 2)], - defenseInfo: new DefenseInfo(3, 1), + defenseInfo: { blue: 3, black: 1 } as MD2DiceSet, }), new MobInfo({ name: 'The Ghoul', level: 5, hp: 10, attackInfos: [new AttackInfo(MD2Icon.Melee, 0, 3, 0, 3)], - defenseInfo: new DefenseInfo(4, 1), + defenseInfo: { blue: 4, black: 1 } as MD2DiceSet, }), @@ -83,21 +84,21 @@ const CORE_GAME_MOB_LEVEL = [ attackInfos: [ new AttackInfo(MD2Icon.Magic, 0, 1, 0, 2), ], - defenseInfo: new DefenseInfo(2, 1), + defenseInfo: { blue: 2, black: 1 } as MD2DiceSet, }), new MobInfo({ name: 'Balrog', level: 3, hp: 8, attackInfos: [ new AttackInfo(MD2Icon.Magic, 0, 2, 0, 2), ], - defenseInfo: new DefenseInfo(3, 1), + defenseInfo: { blue: 3, black: 1 } as MD2DiceSet, }), new MobInfo({ name: 'Balrog', level: 5, hp: 10, attackInfos: [ new AttackInfo(MD2Icon.Magic, 0, 3, 0, 2), ], - defenseInfo: new DefenseInfo(4, 1), + defenseInfo: { blue: 4, black: 1 } as MD2DiceSet, }), ] @@ -194,12 +195,13 @@ export class RMUndeadQueenFactory extends CoreGameRMFactory { });; } - this.mob.combatSkill = new MobSkill( + this.mob.skills = [ { description: `Add 1 Minion to each Mob in the Dungeon, if possible.`, - type: MobSkillType.Attack - } - ) + type: MobSkillType.Attack, + + skillRoll: 1 + } as MD2MobSkill]; return this.mob; } } @@ -249,12 +251,12 @@ export class RMAndraFactory extends CoreGameRMFactory { }); } - this.mob.combatSkill = new MobSkill( + this.mob.skills = [ { description: `Deal ${damage} wound to another Hero with the lowest HP in LoS`, - type: MobSkillType.Combat - } - ) + type: MobSkillType.Combat, + skillRoll: 1 + } as MD2MobSkill]; return this.mob; } } @@ -293,12 +295,12 @@ export class RMTheGhoulFactory extends CoreGameRMFactory { }); } - this.mob.combatSkill = new MobSkill( + this.mob.skills = [ { description: `Move the closest Mob with minion 1 Zone toward The Ghoul.`, - type: MobSkillType.Combat - } - ) + type: MobSkillType.Combat, + skillRoll: 1 + } as MD2MobSkill]; return this.mob; } } @@ -340,12 +342,12 @@ export class RMLyidanIncubusLordFactory extends CoreGameRMFactory { }); } - this.mob.combatSkill = new MobSkill( + this.mob.skills = [ { description: `After combat, resolve all ${this.iconHtml(MD2Icon.Fire)} on the defending Hero(once per combat).`, - type: MobSkillType.Attack - } - ) + type: MobSkillType.Attack, + skillRoll: 1 + } as MD2MobSkill]; return this.mob; } } @@ -376,12 +378,12 @@ export class RMBalrogFactory extends CoreGameRMFactory { } } - this.mob.combatSkill = new MobSkill( + this.mob.skills = [ { description: `The Hero takes 1 ${this.iconHtml(MD2Icon.Fire)}`, - type: MobSkillType.Combat - } - ) + type: MobSkillType.Combat, + skillRoll: 1 + } as MD2MobSkill]; return this.mob; } } diff --git a/src/app/games/massive-darkness2/massive-darkness2.component.html b/src/app/games/massive-darkness2/massive-darkness2.component.html index 09e01bf..9f92ff7 100644 --- a/src/app/games/massive-darkness2/massive-darkness2.component.html +++ b/src/app/games/massive-darkness2/massive-darkness2.component.html @@ -15,7 +15,6 @@ --> -
diff --git a/src/app/games/massive-darkness2/massive-darkness2.db.model.ts b/src/app/games/massive-darkness2/massive-darkness2.db.model.ts index 68a5966..da596a7 100644 --- a/src/app/games/massive-darkness2/massive-darkness2.db.model.ts +++ b/src/app/games/massive-darkness2/massive-darkness2.db.model.ts @@ -52,6 +52,7 @@ export interface MD2MobSkill { skillRoll: number; name: string; description: string; + uiDisplay?: boolean; } export interface MD2DiceSet { diff --git a/src/app/games/massive-darkness2/massive-darkness2.model.boss.ts b/src/app/games/massive-darkness2/massive-darkness2.model.boss.ts index 836de74..4fcd850 100644 --- a/src/app/games/massive-darkness2/massive-darkness2.model.boss.ts +++ b/src/app/games/massive-darkness2/massive-darkness2.model.boss.ts @@ -4,8 +4,9 @@ import { first } from "rxjs/operators" import { MD2Service } from "../../services/MD2/md2.service" import { StringUtils } from "../../utilities/string-utils" import { BossActivationComponent } from "./boss-fight/boss-activation/boss-activation.component" -import { TreasureType, AttackInfo, DefenseInfo, AttackType, MD2Icon, MD2HeroInfo, AttackTarget, MobInfo, MobType } from "./massive-darkness2.model" +import { TreasureType, AttackInfo, AttackType, MD2Icon, MD2HeroInfo, AttackTarget, MobInfo, MobType } from "./massive-darkness2.model" import { RollingBlackDice } from "./massive-darkness2.model.dice" +import { MD2DiceSet, MD2MobSkill } from "./massive-darkness2.db.model" export enum MobSkillType { @@ -110,14 +111,18 @@ export class BossMicheal extends BossFight { type: MobType.Boss, hpPerHero: 15, level: 10, - combatSkill: new MobSkill( - { - name: `Combat 1 ${this.md2Service.stateService.iconHtml(MD2Icon.EnemySkill)}`, - description: `Deal 1 Wound for each ${this.corruptionTokenHtml} on the attacking or defending Hero. Discard the tokens afterwards(once per combat).` - }), imageUrl: md2Service.stateService.imgUrl('/Boss/Michael.png') }); - this.info.defenseInfo = new DefenseInfo(5, 1); + if (!this.info.skills) { + this.info.skills = []; + } + this.info.skills.push({ + name: `Combat 1 ${this.md2Service.stateService.iconHtml(MD2Icon.EnemySkill)}`, + description: `Deal 1 Wound for each ${this.corruptionTokenHtml} on the attacking or defending Hero. Discard the tokens afterwards(once per combat).`, + type: MobSkillType.Combat, + skillRoll: 1 + } as MD2MobSkill); + this.info.defenseInfo = { blue: 5, black: 1 } as MD2DiceSet; this.info.attackInfos = [new AttackInfo(MD2Icon.Melee, 2, 2, 0, 1)]; this.actions = 1; this.actionBlackDice = 2; @@ -233,15 +238,17 @@ export class BossReaper extends BossFight { type: MobType.Boss, hpPerHero: 25, level: 10, - combatSkill: new MobSkill( - { - description: `If the Hero has no ${this.md2Service.stateService.iconHtml(MD2Icon.Mana)}, they take 1 ${this.md2Service.stateService.iconHtml(MD2Icon.Frost)}`, - type: MobSkillType.Attack, - - }), imageUrl: md2Service.stateService.imgUrl('/Boss/The Reaper-Stand.png') }); - this.info.defenseInfo = new DefenseInfo(4, 3); + if (!this.info.skills) { + this.info.skills = []; + } + this.info.skills.push({ + description: `If the Hero has no ${this.md2Service.stateService.iconHtml(MD2Icon.Mana)}, they take 1 ${this.md2Service.stateService.iconHtml(MD2Icon.Frost)}`, + type: MobSkillType.Attack, + skillRoll: 1 + } as MD2MobSkill); + this.info.defenseInfo = { blue: 4, black: 3 } as MD2DiceSet; this.info.attackInfos = [new AttackInfo(MD2Icon.Melee, 1, 2, 0, 3)]; this.actions = 1; this.actionBlackDice = 2; diff --git a/src/app/games/massive-darkness2/massive-darkness2.model.ts b/src/app/games/massive-darkness2/massive-darkness2.model.ts index 3a1a169..d837c19 100644 --- a/src/app/games/massive-darkness2/massive-darkness2.model.ts +++ b/src/app/games/massive-darkness2/massive-darkness2.model.ts @@ -5,6 +5,7 @@ import { ObjectUtils } from "../../utilities/object-utils"; import { GamePlayer } from "../games.model"; import { MD2Clone } from "./factorys/md2-clone"; import { MobSkill } from "./massive-darkness2.model.boss"; +import { MD2DiceSet, MD2MobSkill } from "./massive-darkness2.db.model"; const MD2_IMG_URL = (id: string = null) => { return `${environment.apiUrl}/Files/Images/MD2/${(id ? `${encodeURI(id)}` : '')}` } export enum MobDlgType { @@ -110,14 +111,7 @@ export class AttackInfo { yellow: number black: number } -export class DefenseInfo { - constructor(blue: number, black: number = 0) { - this.blue = blue - this.black = black - } - blue: number - black: number -} + export class MD2LevelUpReward { constructor(config: Partial) { Object.assign(this, config); @@ -311,10 +305,11 @@ export class MobInfo implements IDrawingItem { fixedCarriedTreasure: TreasureItem[]; unitRemainHp: number; attackInfos: AttackInfo[]; - defenseInfo: DefenseInfo; + defenseInfo: MD2DiceSet; + + skills: MD2MobSkill[]; actions: number = 0; activateDescription: string; - combatSkill: MobSkill fireToken: number = 0; frozenToken: number = 0; diff --git a/src/app/games/massive-darkness2/md2-icon/md2-icon.component.html b/src/app/games/massive-darkness2/md2-icon/md2-icon.component.html index dc32e52..c1521d9 100644 --- a/src/app/games/massive-darkness2/md2-icon/md2-icon.component.html +++ b/src/app/games/massive-darkness2/md2-icon/md2-icon.component.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/app/games/massive-darkness2/md2-icon/md2-icon.component.ts b/src/app/games/massive-darkness2/md2-icon/md2-icon.component.ts index fa4ff36..3f9819d 100644 --- a/src/app/games/massive-darkness2/md2-icon/md2-icon.component.ts +++ b/src/app/games/massive-darkness2/md2-icon/md2-icon.component.ts @@ -15,19 +15,27 @@ export class MD2IconComponent implements OnInit { private _icon: string | MD2Icon; @Input() public set icon(v: string | MD2Icon) { - if (this._icon != v) { - this._icon = v; - //if it's string, convert it to MD2Icon - if (typeof v === 'string') { - v = MD2Icon[v]; + if (v !== undefined) { + if (this._icon != v) { + this._icon = v; + //if it's string, convert it to MD2Icon + if (typeof v === 'string') { + const key = Object.keys(MD2Icon).find( + k => k.toLowerCase() === v.toString().toLowerCase() + ); + if (key) { + v = MD2Icon[key as keyof typeof MD2Icon]; + } + } + this.iconHtml = this.md2StateService.iconHtml(v as MD2Icon); + } + if (this.isMD2Icon(v)) { + this.iconName = MD2Icon[v].toLowerCase(); + } else { + this.iconName = v; } - this.iconHtml = this.md2StateService.iconHtml(v as MD2Icon); - } - if (this.isMD2Icon(v)) { - this.iconName = MD2Icon[v].toLowerCase(); - } else { - this.iconName = v; } + } isMD2Icon(icon: MD2Icon | string): icon is MD2Icon { 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 d2d323e..d60c33d 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 @@ -111,21 +111,66 @@ export class MD2MobInfoDetailComponent extends DialogContentBase implements OnIn public addLevelHandler(): void { if (!this.mobInfo || !this.levelsGrid) return; - const newLevel: MD2MobLevelInfo = { - id: this.generateLevelId(), - level: this.mobLevelInfos.length + 1, - mobInfoId: this.mobInfo.id, - rewardTokens: 0, - fixedRareTreasure: 0, - fixedEpicTreasure: 0, - fixedLegendTreasure: 0, - fixedHp: 1, - hpPerHero: 0, - actions: 1, - attackInfo: { yellow: null, orange: null, red: null, blue: null, green: null, black: null }, - defenceInfo: { yellow: null, orange: null, red: null, blue: null, green: null, black: null }, - skills: [] - }; + // Get the last level info (highest level) if any exists + const lastLevel = this.mobLevelInfos.length > 0 + ? this.mobLevelInfos.reduce((prev, current) => (prev.level > current.level) ? prev : current) + : null; + + // Calculate the next level number + const nextLevel = lastLevel ? lastLevel.level + 2 : 1; + let rewardTokens = 0; + + switch (nextLevel) { + case 1: + case 3: + rewardTokens = 1; + break; + case 5: + rewardTokens = 2; + break; + } + + let newLevel: MD2MobLevelInfo; + + if (lastLevel) { + // Copy the last level's info as initial values + newLevel = { + id: this.generateLevelId(), + level: nextLevel, + mobInfoId: this.mobInfo.id, + rewardTokens: rewardTokens, + fixedRareTreasure: lastLevel.fixedRareTreasure ?? 0, + fixedEpicTreasure: lastLevel.fixedEpicTreasure ?? 0, + fixedLegendTreasure: lastLevel.fixedLegendTreasure ?? 0, + fixedHp: lastLevel.fixedHp ?? 1, + hpPerHero: lastLevel.hpPerHero ?? 0, + actions: lastLevel.actions ?? 1, + attackInfo: lastLevel.attackInfo + ? { ...lastLevel.attackInfo } + : { yellow: null, orange: null, red: null, blue: null, green: null, black: null }, + defenceInfo: lastLevel.defenceInfo + ? { ...lastLevel.defenceInfo } + : { yellow: null, orange: null, red: null, blue: null, green: null, black: null }, + skills: [] // Don't copy skills, start with empty array + }; + } else { + // Default values if no levels exist + newLevel = { + id: this.generateLevelId(), + level: nextLevel, + mobInfoId: this.mobInfo.id, + rewardTokens: rewardTokens, + fixedRareTreasure: 0, + fixedEpicTreasure: 0, + fixedLegendTreasure: 0, + fixedHp: 1, + hpPerHero: 0, + actions: 1, + attackInfo: { yellow: null, orange: null, red: null, blue: null, green: null, black: null }, + defenceInfo: { yellow: null, orange: null, red: null, blue: null, green: null, black: null }, + skills: [] + }; + } // Use grid's addRow method to properly add a new row in edit mode this.levelsGrid.addRow(newLevel); diff --git a/src/app/games/massive-darkness2/mobs/mob-detail-info/mob-combat-info/mob-combat-info.component.html b/src/app/games/massive-darkness2/mobs/mob-detail-info/mob-combat-info/mob-combat-info.component.html index c0fe413..64da57e 100644 --- a/src/app/games/massive-darkness2/mobs/mob-detail-info/mob-combat-info/mob-combat-info.component.html +++ b/src/app/games/massive-darkness2/mobs/mob-detail-info/mob-combat-info/mob-combat-info.component.html @@ -15,10 +15,18 @@
-
-