diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..449691b --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +save-exact=true \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 421f443..d4b1256 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8821,12 +8821,14 @@ "version": "1.0.0", "dependencies": { "@rpg-village/core": "1.0.0", + "ramda": "0.28.0", "ts-node": "10.9.1", "typescript": "4.9.4" }, "devDependencies": { "@types/chance": "1.1.3", "@types/node": "18.11.18", + "@types/ramda": "0.28.21", "ava": "4.3.0", "chance": "1.1.9" } @@ -9835,8 +9837,10 @@ "@rpg-village/core": "1.0.0", "@types/chance": "1.1.3", "@types/node": "18.11.18", + "@types/ramda": "0.28.21", "ava": "4.3.0", "chance": "1.1.9", + "ramda": "0.28.0", "ts-node": "10.9.1", "typescript": "4.9.4" } diff --git a/packages/core-test/package.json b/packages/core-test/package.json index a8fdd54..040ccba 100644 --- a/packages/core-test/package.json +++ b/packages/core-test/package.json @@ -9,11 +9,13 @@ "prepare": "true" }, "dependencies": { + "ramda": "0.28.0", "@rpg-village/core": "1.0.0", "typescript": "4.9.4", "ts-node": "10.9.1" }, "devDependencies": { + "@types/ramda": "0.28.21", "@types/chance": "1.1.3", "@types/node": "18.11.18", "ava": "4.3.0", diff --git a/packages/core-test/tests/activities/battle.test.ts b/packages/core-test/tests/activities/battle.test.ts index aa89157..e620096 100644 --- a/packages/core-test/tests/activities/battle.test.ts +++ b/packages/core-test/tests/activities/battle.test.ts @@ -12,8 +12,7 @@ import { createState, test } from "../utils"; import { equipmentFactory, runeFactory } from "../utils/factories"; test("should finish correctly", { - initState: createState(({ activity, party, unit, battle, map }) => [ - map({ mapLocationIds: ["locationId"] }), + initState: createState(({ activity, party, unit, battle }) => [ activity({ id: "battleActivity", name: BattleActivityType.Battle, @@ -24,11 +23,10 @@ test("should finish correctly", { battleId: battle({ partyId: party({ id: "random-id", - locationId: "locationId", + unitIds: [unit({ dmg: 100, hp: 100 })], }), defenderPartyId: party({ - locationId: "locationId", unitIds: [unit({ dmg: 1, hp: 1, armor: 0 })], }), }), @@ -40,15 +38,13 @@ test("should finish correctly", { }); test("should gain xp for winner heroes", { - initState: createState(({ activity, party, unit, battle, map }) => [ - map({ mapLocationIds: ["locationId"] }), + initState: createState(({ activity, party, unit, battle }) => [ activity({ name: BattleActivityType.Battle, state: { battleId: battle({ partyId: party({ id: "party-id", - locationId: "locationId", unitIds: [ unit({ id: "winner-unit", @@ -61,7 +57,6 @@ test("should gain xp for winner heroes", { ], }), defenderPartyId: party({ - locationId: "locationId", unitIds: [unit({ dmg: 1, hp: 1, level: 1, armor: 0 })], }), }), @@ -73,20 +68,17 @@ test("should gain xp for winner heroes", { }); test("should gain gold", { - initState: createState(({ activity, party, unit, battle, map }) => [ - map({ mapLocationIds: ["locationId"] }), + initState: createState(({ activity, party, unit, battle }) => [ activity({ name: BattleActivityType.Battle, state: { battleId: battle({ partyId: party({ id: "party-id", - locationId: "locationId", unitIds: [unit({ dmg: 100, hp: 100 })], stash: { resource: { gold: 0 } }, }), defenderPartyId: party({ - locationId: "locationId", unitIds: [unit({ dmg: 1, hp: 1, level: 1, armor: 0 })], }), }), @@ -98,8 +90,7 @@ test("should gain gold", { }); test("should gain soul", { - initState: createState(({ activity, party, unit, battle, map }) => [ - map({ mapLocationIds: ["locationId"] }), + initState: createState(({ activity, party, unit, battle }) => [ activity({ name: BattleActivityType.Battle, state: { @@ -111,7 +102,6 @@ test("should gain soul", { stash: { resource: { soul: 5 } }, }), defenderPartyId: party({ - locationId: "locationId", unitIds: [unit({ dmg: 1, hp: 1, level: 1, armor: 0 })], }), }), @@ -122,23 +112,20 @@ test("should gain soul", { expectedState: { parties: { "party-id": { stash: { resource: { soul: 6 } } } } }, }); -test("should gain resource in village when enabled VillageConfig.DirectLootToVillage config", { - config: { [VillageConfig.DirectLootToVillage]: true }, - initState: createState(({ activity, party, unit, battle, map, village }) => [ - map({ mapLocationIds: ["locationId"] }), +test("should gain resource into village when enabled VillageConfig.DirectLootToVillage config", { + gameConfig: { [VillageConfig.DirectLootToVillage]: true }, + initState: createState(({ activity, party, unit, battle, village }) => [ village({ stash: { resource: { gold: 0 } } }), activity({ name: BattleActivityType.Battle, state: { battleId: battle({ partyId: party({ - locationId: "locationId", id: "winner-party", unitIds: [unit({ dmg: 10, hp: 10 })], stash: { resource: { gold: 0 } }, }), defenderPartyId: party({ - locationId: "locationId", unitIds: [unit({ dmg: 1, hp: 1, level: 1, armor: 0 })], }), }), @@ -153,14 +140,12 @@ test("should gain resource in village when enabled VillageConfig.DirectLootToVil }); test("should apply item dmg effect", { - initState: createState(({ activity, party, unit, battle, map }) => [ - map({ mapLocationIds: ["locationId"] }), + initState: createState(({ activity, party, unit, battle }) => [ activity({ name: BattleActivityType.Battle, state: { battleId: battle({ partyId: party({ - locationId: "locationId", unitIds: [ unit({ dmg: 10, @@ -175,7 +160,6 @@ test("should apply item dmg effect", { ], }), defenderPartyId: party({ - locationId: "locationId", unitIds: [unit({ id: "defender-unit", dmg: 1, hp: 25, armor: 0, maxhp: 25 })], }), }), @@ -186,15 +170,46 @@ test("should apply item dmg effect", { expectedState: { units: { "defender-unit": { hp: 5 } } }, }); +test("should apply percentage item dmg effect", { + initState: createState(({ activity, party, unit, battle }) => [ + activity({ + name: BattleActivityType.Battle, + state: { + battleId: battle({ + partyId: party({ + unitIds: [ + unit({ + dmg: 10, + hp: 100, + equipment: { + rightHand: equipmentFactory({ + itemType: ItemType.Weapon, + effects: [ + { value: 10, type: EffectType.Static, isPercentage: true, effectType: AttackEffectType.Dmg }, + ], + }), + }, + }), + ], + }), + defenderPartyId: party({ + unitIds: [unit({ id: "defender-unit", dmg: 1, hp: 25, armor: 0, maxhp: 25 })], + }), + }), + }, + }), + ]), + turn: true, + expectedState: { units: { "defender-unit": { hp: 14 } } }, +}); + test("should apply dynamic item effects", { - initState: createState(({ activity, party, unit, battle, map }) => [ - map({ mapLocationIds: ["locationId"] }), + initState: createState(({ activity, party, unit, battle }) => [ activity({ name: BattleActivityType.Battle, state: { battleId: battle({ partyId: party({ - locationId: "locationId", unitIds: [ unit({ dmg: 10, @@ -210,7 +225,6 @@ test("should apply dynamic item effects", { ], }), defenderPartyId: party({ - locationId: "locationId", unitIds: [unit({ id: "defender-unit", dmg: 1, hp: 200, armor: 0, maxhp: 200 })], }), }), diff --git a/packages/core-test/tests/commands/buildings/portals/open-portal.test.ts b/packages/core-test/tests/commands/buildings/portals/open-portal.test.ts index e77bc95..350549c 100644 --- a/packages/core-test/tests/commands/buildings/portals/open-portal.test.ts +++ b/packages/core-test/tests/commands/buildings/portals/open-portal.test.ts @@ -1,4 +1,6 @@ -import { ItemType, PortalsCommand } from "@rpg-village/core"; +import { values } from "ramda"; + +import { AttackEffectType, EffectType, ItemType, PortalsCommand } from "@rpg-village/core"; import { createState, test } from "../../../utils"; @@ -19,6 +21,34 @@ test("should create portal", { expectedState: (state, t) => t.length(state.maps, 2), }); +test("should apply effects to the portal", { + initState: createState(({ village, map }) => [ + map({ id: "global-map", mapLocationIds: ["village-location"] }), + village({ + locationId: "village-location", + stash: { + items: [ + { + itemType: ItemType.DungeonKey, + id: "dungeon-key", + effects: [{ type: EffectType.Static, effectType: AttackEffectType.Dmg, value: 10 }], + }, + ], + }, + }), + ]), + commands: [ + { + command: PortalsCommand.OpenPortal, + args: { dungeonKeyId: "dungeon-key" }, + }, + ], + expectedState: (state, t) => + t.deepEqual(values(state.maps).find(x => x.id !== "global-map").modifiers, [ + { type: EffectType.Static, effectType: AttackEffectType.Dmg, value: 10 }, + ]), +}); + test("should consume dungeon key", { initState: createState(({ village }) => [ village({ stash: { items: [{ itemType: ItemType.DungeonKey, id: "dungeon-key" }] } }), diff --git a/packages/core-test/tests/commands/map/battle.test.ts b/packages/core-test/tests/commands/map/battle.test.ts index c27a392..411c5a7 100644 --- a/packages/core-test/tests/commands/map/battle.test.ts +++ b/packages/core-test/tests/commands/map/battle.test.ts @@ -3,7 +3,8 @@ import { BattleActivityType, MapCommand, PartyOwner } from "@rpg-village/core"; import { createState, test } from "../../utils"; test("should start Battle activity", { - initState: createState(({ party, unit, location }) => [ + initState: createState(({ party, unit, location, map }) => [ + map({ mapLocationIds: ["battle-location"], modifiers: [] }), party({ id: "party-x", locationId: location({ id: "battle-location" }), diff --git a/packages/core-test/tests/event-handlers/map/new-location.ts b/packages/core-test/tests/event-handlers/map/new-location.ts new file mode 100644 index 0000000..327f747 --- /dev/null +++ b/packages/core-test/tests/event-handlers/map/new-location.ts @@ -0,0 +1,28 @@ +import { EffectType, MapEvent, MiscEffectType } from "@rpg-village/core"; + +import { createState, test } from "../../utils"; + +test("should apply map difficulty to new enemies", { + event: { event: MapEvent.NewLocation, args: { locationId: "location-id", mapId: "map-id" } }, + initState: createState(({ location, map }) => [ + map({ + id: "map-id", + difficulty: 10, + mapLocationIds: [location({ id: "location-id" })], + }), + ]), + expectedState: (state, t) => t.withRandomId(state.units, { hp: 30 }), +}); + +test("should apply misc map modifiers to new units", { + event: { event: MapEvent.NewLocation, args: { locationId: "location-id", mapId: "map-id" } }, + initState: createState(({ location, map }) => [ + map({ + id: "map-id", + difficulty: 1, + mapLocationIds: [location({ id: "location-id" })], + modifiers: [{ effectType: MiscEffectType.Hp, type: EffectType.Static, value: 100 }], + }), + ]), + expectedState: (state, t) => t.withRandomId(state.units, { hp: 112 }), +}); diff --git a/packages/core-test/tests/utils/test.ts b/packages/core-test/tests/utils/test.ts index 2165cd0..8c310ce 100644 --- a/packages/core-test/tests/utils/test.ts +++ b/packages/core-test/tests/utils/test.ts @@ -3,7 +3,7 @@ import * as ava from "ava"; import { argv } from "process"; import * as util from "util"; -import { Command, GameConfig, GameState } from "@rpg-village/core"; +import { Command, Event, GameConfig, GameState } from "@rpg-village/core"; import { ExecutionTestContext, lengthAssertionFactory, withRandomIDAssertionFactory } from "./custom-assertions"; import { gameFactory } from "./game-factory"; @@ -17,15 +17,16 @@ type ExpectedState = TestGameState | ExpectedStateMatcher; type Test = { initState: TestGameState; - config?: GameConfig["config"]; + gameConfig?: GameConfig["config"]; commands?: (Command | string)[]; + event?: Event; turn?: boolean | number; expectedState: ExpectedState | ExpectedState[]; }; const project_dir = argv[1].replace(/node_modules.*/, ""); -export function test(testName: string, { config, initState, commands, expectedState, turn = 0 }: Test) { +export function test(testName: string, { gameConfig, initState, commands, event, expectedState, turn = 0 }: Test) { const testFilePath = new Error().stack .split("\n")[2] .replace("at Object. ", "") @@ -33,7 +34,7 @@ export function test(testName: string, { config, initState, commands, expectedSt .replace(project_dir, ""); ava.default(testName, t => { - const game = gameFactory({ state: initState, config } as any); + const game = gameFactory({ state: initState, config: gameConfig } as any); if (commands) { commands.forEach(command => { @@ -45,6 +46,10 @@ export function test(testName: string, { config, initState, commands, expectedSt }); } + if (event) { + game.emitEvent(event); + } + for (let i = 0; i < +turn; i++) { game.gameTurn(); } diff --git a/packages/core/src/core/event/event.ts b/packages/core/src/core/event/event.ts new file mode 100644 index 0000000..e28c9fd --- /dev/null +++ b/packages/core/src/core/event/event.ts @@ -0,0 +1,9 @@ +import { EventType } from "../global-type/event-type"; + +type EventBase = T extends string + ? EventType[T] extends undefined + ? { event: T } + : { event: T; args: EventType[T] } + : never; + +export type Event = EventBase; diff --git a/packages/core/src/core/event/index.ts b/packages/core/src/core/event/index.ts index c92eb30..8050d66 100644 --- a/packages/core/src/core/event/index.ts +++ b/packages/core/src/core/event/index.ts @@ -1,3 +1,4 @@ export * from "../global-type/event-type"; export * from "./event-system"; export * from "./event-handler-decorator"; +export * from "./event"; diff --git a/packages/core/src/models/effect/unit-effect-property-map.ts b/packages/core/src/models/effect/unit-effect-property-map.ts index 55ffb45..86ef66d 100644 --- a/packages/core/src/models/effect/unit-effect-property-map.ts +++ b/packages/core/src/models/effect/unit-effect-property-map.ts @@ -3,10 +3,10 @@ import { Unit } from "@modules/unit"; import { AttackEffectType, DefenseEffectType, MiscEffectType } from "./battle-effect"; import { EffectBaseType } from "./effect"; -export const unitEffectBasePropertiesMap: Record = { +export const unitEffectBasePropertiesMap: Record = { [AttackEffectType.Dmg]: "dmg", [AttackEffectType.CriticalChance]: "criticalChance", [DefenseEffectType.Evasion]: "evasion", [DefenseEffectType.Armor]: "armor", - [MiscEffectType.Hp]: "maxhp", + [MiscEffectType.Hp]: null, }; diff --git a/packages/core/src/models/effect/utils/calculate-unit-stats-with-effects.ts b/packages/core/src/models/effect/utils/calculate-unit-stats-with-effects.ts index 4e5783e..4618e70 100644 --- a/packages/core/src/models/effect/utils/calculate-unit-stats-with-effects.ts +++ b/packages/core/src/models/effect/utils/calculate-unit-stats-with-effects.ts @@ -13,7 +13,7 @@ export function calculateUnitStatsWithEffects(unit: Unit): Unit { return reduce(applyEffect, unitWithEffects, effectsToApply); } -function getEffectBaseProperty(effect: EffectStatic): keyof Unit { +function getEffectBaseProperty(effect: EffectStatic): keyof Unit | null { return unitEffectBasePropertiesMap[effect.effectType]; } @@ -30,3 +30,17 @@ function applyEffect(unit: Unit, effect: EffectStatic): Unit { return unit; } + +function calculateEffectValue(value: number, effect: EffectStatic): number { + if (effect.isPercentage) { + return (value * effect.value) / 100 + 1; + } else { + return value + effect.value; + } +} + +export function calculateEffectsValue(value: number, effects: EffectStatic[]): number { + const applyEffectsOrder = sortBy(propOr(false, "isPercentage"), effects); + + return applyEffectsOrder.reduce(calculateEffectValue, value); +} diff --git a/packages/core/src/modules/activity/activity-manager.ts b/packages/core/src/modules/activity/activity-manager.ts index e618aba..bc7417c 100644 --- a/packages/core/src/modules/activity/activity-manager.ts +++ b/packages/core/src/modules/activity/activity-manager.ts @@ -30,7 +30,10 @@ export class ActivityManager { } } - startPartyActivity(activityName: string, startingArgs: PartyActivityStartArgs) { + startPartyActivity( + activityName: string, + startingArgs: ActivityStartArgs, + ) { if (this.partyStore.get(startingArgs.partyId).activityId) return; const activityHandler = this.getActivityHandler(activityName); @@ -64,7 +67,7 @@ export class ActivityManager { activityHandler.resolve(updatedActivity); this.activityStore.remove(activity.id); - if(activity.type === ActivityType.Party) { + if (activity.type === ActivityType.Party) { this.partyStore.clearActivity(activity.startArgs.partyId); if (activity.startArgs.involvedPartyId) { this.partyStore.clearActivity(activity.startArgs.involvedPartyId); diff --git a/packages/core/src/modules/battle/battle-service.ts b/packages/core/src/modules/battle/battle-service.ts index d7d3d49..f3509c4 100644 --- a/packages/core/src/modules/battle/battle-service.ts +++ b/packages/core/src/modules/battle/battle-service.ts @@ -1,8 +1,7 @@ import { injectable } from "inversify"; import { forEach } from "ramda"; -import { MapLocationID } from "@modules/map"; -import { PartyID, PartyService, PartyStore } from "@modules/party"; +import { PartyID, PartyService } from "@modules/party"; import { UnitStore } from "@modules/unit"; import { Battle } from "./battle"; @@ -13,23 +12,12 @@ import { BattleID, BattleStoreState } from "./interfaces"; export class BattleService { private battleInstances: Record = {}; - constructor( - private battleStore: BattleStore, - private partyService: PartyService, - private unitStore: UnitStore, - private partyStore: PartyStore, - ) {} + constructor(private battleStore: BattleStore, private partyService: PartyService, private unitStore: UnitStore) {} getBattle(battleId: BattleID): BattleStoreState { return this.battleStore.get(battleId); } - getBattleLocation(battleId: BattleID): MapLocationID { - const partyId = this.battleStore.get(battleId).partyId; - const party = this.partyStore.get(partyId); - return party.locationId; - } - startBattle(partyId: PartyID, defenderPartyId: PartyID): BattleID { return this.battleStore.add({ partyId, defenderPartyId }).id; } @@ -54,6 +42,7 @@ export class BattleService { private getBattleInstance(battleId: BattleID): Battle { if (!this.battleInstances[battleId]) { const battleState = this.battleStore.get(battleId); + this.battleInstances[battleId] = new Battle( this.partyService.getPartyUnits(battleState.partyId), this.partyService.getPartyUnits(battleState.defenderPartyId), diff --git a/packages/core/src/modules/battle/battle.ts b/packages/core/src/modules/battle/battle.ts index 3375b0d..6c57edc 100644 --- a/packages/core/src/modules/battle/battle.ts +++ b/packages/core/src/modules/battle/battle.ts @@ -11,7 +11,7 @@ export class Battle { private battleState: BattleState; constructor(attackerParty: Unit[], defenderParty: Unit[]) { - this.battleState = this.createStartBattleState(clone(attackerParty), clone(defenderParty)); + this.battleState = this.initBattleState(clone(attackerParty), clone(defenderParty)); } turn(): BattleState { @@ -30,10 +30,10 @@ export class Battle { return areAllDead(this.battleState.attackerParty) || areAllDead(this.battleState.defenderParty); } - private createStartBattleState(attackerPartyUnits: Unit[], defenderPartyUnits: Unit[]): BattleState { + private initBattleState(attackerPartyUnits: Unit[], defenderPartyUnits: Unit[]): BattleState { return { - attackerParty: attackerPartyUnits, - defenderParty: defenderPartyUnits, + attackerParty: attackerPartyUnits.map(calculateUnitStatsWithEffects), + defenderParty: defenderPartyUnits.map(calculateUnitStatsWithEffects), }; } @@ -41,12 +41,7 @@ export class Battle { forEach(attackerUnit => { const defenderUnit = sample(defenderParty.filter(isAlive)); - const [attackerUnitStats, defenderUnitStats] = [ - calculateUnitStatsWithEffects(attackerUnit), - calculateUnitStatsWithEffects(defenderUnit), - ]; - - defenderUnit.hp = Math.max(0, defenderUnit.hp - Math.max(attackerUnitStats.dmg - defenderUnitStats.armor, 0)); + defenderUnit.hp = Math.max(0, defenderUnit.hp - Math.max(attackerUnit.dmg - defenderUnit.armor, 0)); }, attackerParty.filter(isAlive)); } } diff --git a/packages/core/src/modules/game/game-controller.ts b/packages/core/src/modules/game/game-controller.ts index 3bef1e1..68e068d 100644 --- a/packages/core/src/modules/game/game-controller.ts +++ b/packages/core/src/modules/game/game-controller.ts @@ -1,14 +1,18 @@ import { injectable } from "inversify"; import { Command, CommandSystem } from "@core/command"; -import { EventSystem } from "@core/event"; +import { Event, EventSystem } from "@core/event"; import { GameStore } from "./game-store"; import { GameCommand, GameState } from "./interfaces"; @injectable() export class GameController { - constructor(private gameStore: GameStore, private commandSystem: CommandSystem, eventSystem: EventSystem) { + constructor( + private gameStore: GameStore, + private commandSystem: CommandSystem, + private eventSystem: EventSystem, + ) { commandSystem.hookCommandHandlers(); eventSystem.hookEventHandlers(); } @@ -33,6 +37,11 @@ export class GameController { return this.gameStore.getState(); } + /** For Internal Test Helper Interface */ + emitEvent(event: Event) { + this.eventSystem.fire(event.event, event.args); + } + executeCommand(command: Command): State { if ("args" in command) { this.commandSystem.execute(command.command, command.args); diff --git a/packages/core/src/modules/game/interfaces/game-instance.ts b/packages/core/src/modules/game/interfaces/game-instance.ts index d3ac453..b39cb54 100644 --- a/packages/core/src/modules/game/interfaces/game-instance.ts +++ b/packages/core/src/modules/game/interfaces/game-instance.ts @@ -1,4 +1,5 @@ import { Command } from "@core/command"; +import { Event } from "@core/event"; import { GameState } from "./game-state"; @@ -7,5 +8,6 @@ export interface GameInstance { getState(): S; loadGame(gameState: S): S; startNewGame(): S; + emitEvent(event: Event): void; executeCommand(command: Command): S; } diff --git a/packages/core/src/modules/map/lib/generate-enemy.ts b/packages/core/src/modules/map/lib/generate-enemy.ts index 76672a2..cd28e19 100644 --- a/packages/core/src/modules/map/lib/generate-enemy.ts +++ b/packages/core/src/modules/map/lib/generate-enemy.ts @@ -1,4 +1,4 @@ -import { EffectStatic } from "@models/effect"; +import { EffectStatic, MiscEffectType, calculateEffectsValue } from "@models/effect"; import { PartyStash } from "@modules/party"; import { Unit, UnitType } from "@modules/unit"; @@ -14,17 +14,19 @@ export function generateEnemyParty(difficulty: number, effects: EffectStatic[]): }; } -function generateEnemy(point: number, effects: EffectStatic[]): Omit { - const level = ~~(point / 10) + 1; +function generateEnemy(difficulty: number, effects: EffectStatic[]): Omit { + const level = ~~(difficulty / 10) + 1; + + const hpModifiers = effects.filter(x => x.effectType === MiscEffectType.Hp); return { name: "Skeleton", armor: 0, - dmg: 8 + ~~(point / 10), + dmg: 8 + ~~(difficulty / 10), equipment: {}, - hp: 10 + point * 2, + hp: calculateEffectsValue(10 + difficulty * 2, hpModifiers), level, - maxhp: 10 + point * 2, + maxhp: calculateEffectsValue(10 + difficulty * 2, hpModifiers), stash: { resource: { gold: 0 }, items: [] }, xp: 0, effects, diff --git a/packages/core/src/modules/map/map-command-handler.ts b/packages/core/src/modules/map/map-command-handler.ts index 3ed5291..faa513d 100644 --- a/packages/core/src/modules/map/map-command-handler.ts +++ b/packages/core/src/modules/map/map-command-handler.ts @@ -6,19 +6,25 @@ import { ActivityManager } from "@modules/activity"; import { BattleActivityType } from "@modules/battle"; import { PartyOwner, PartyService } from "@modules/party"; -import { MapActivity, MapCommand, MapCommandBattleArgs } from "./interfaces"; +import { + MapActivity, + MapCommand, + MapCommandBattleArgs, + MapCommandExploreArgs, + MapCommandTravelArgs, +} from "./interfaces"; @injectable() export class MapCommandHandler { constructor(private activityManager: ActivityManager, private partyService: PartyService) {} @commandHandler(MapCommand.Travel) - travelCommand(travelArgs: any) { + travelCommand(travelArgs: MapCommandTravelArgs) { this.activityManager.startPartyActivity(MapActivity.Travel, travelArgs); } @commandHandler(MapCommand.Explore) - exploreCommand(exploreArgs: any) { + exploreCommand(exploreArgs: MapCommandExploreArgs) { this.activityManager.startPartyActivity(MapActivity.Explore, exploreArgs); } diff --git a/packages/core/src/modules/map/map-event-handler.ts b/packages/core/src/modules/map/map-event-handler.ts index 230969d..020f0fe 100644 --- a/packages/core/src/modules/map/map-event-handler.ts +++ b/packages/core/src/modules/map/map-event-handler.ts @@ -28,9 +28,9 @@ export class MapEventHandler { if (location.type === MapLocationType.Empty) return; if (location.type === MapLocationType.Boss) { - this.addEnemyUnitToMap(args.mapId, args.locationId, map.modifiers); + this.addEnemyUnitToMap(args.mapId, args.locationId, map.modifiers || []); } else { - this.addEnemyUnitToMap(args.mapId, args.locationId, map.modifiers); + this.addEnemyUnitToMap(args.mapId, args.locationId, map.modifiers || []); } }