Skip to content

Commit

Permalink
add map effects propagation to new units
Browse files Browse the repository at this point in the history
  • Loading branch information
Greegko committed May 7, 2023
1 parent 7d4e7ea commit d11e41c
Show file tree
Hide file tree
Showing 20 changed files with 192 additions and 77 deletions.
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
save-exact=true
4 changes: 4 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/core-test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
72 changes: 43 additions & 29 deletions packages/core-test/tests/activities/battle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 })],
}),
}),
Expand All @@ -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",
Expand All @@ -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 })],
}),
}),
Expand All @@ -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 })],
}),
}),
Expand All @@ -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: {
Expand All @@ -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 })],
}),
}),
Expand All @@ -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 })],
}),
}),
Expand All @@ -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,
Expand All @@ -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 })],
}),
}),
Expand All @@ -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,
Expand All @@ -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 })],
}),
}),
Expand Down
Original file line number Diff line number Diff line change
@@ -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";

Expand All @@ -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" }] } }),
Expand Down
3 changes: 2 additions & 1 deletion packages/core-test/tests/commands/map/battle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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" }),
Expand Down
28 changes: 28 additions & 0 deletions packages/core-test/tests/event-handlers/map/new-location.ts
Original file line number Diff line number Diff line change
@@ -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 }),
});
13 changes: 9 additions & 4 deletions packages/core-test/tests/utils/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -17,23 +17,24 @@ 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.<anonymous> ", "")
.slice(5, -1)
.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 => {
Expand All @@ -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();
}
Expand Down
9 changes: 9 additions & 0 deletions packages/core/src/core/event/event.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { EventType } from "../global-type/event-type";

type EventBase<T extends keyof EventType> = T extends string
? EventType[T] extends undefined
? { event: T }
: { event: T; args: EventType[T] }
: never;

export type Event = EventBase<keyof EventType>;
1 change: 1 addition & 0 deletions packages/core/src/core/event/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "../global-type/event-type";
export * from "./event-system";
export * from "./event-handler-decorator";
export * from "./event";
4 changes: 2 additions & 2 deletions packages/core/src/models/effect/unit-effect-property-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { Unit } from "@modules/unit";
import { AttackEffectType, DefenseEffectType, MiscEffectType } from "./battle-effect";
import { EffectBaseType } from "./effect";

export const unitEffectBasePropertiesMap: Record<EffectBaseType, keyof Unit> = {
export const unitEffectBasePropertiesMap: Record<EffectBaseType, keyof Unit | null> = {
[AttackEffectType.Dmg]: "dmg",
[AttackEffectType.CriticalChance]: "criticalChance",
[DefenseEffectType.Evasion]: "evasion",
[DefenseEffectType.Armor]: "armor",
[MiscEffectType.Hp]: "maxhp",
[MiscEffectType.Hp]: null,
};
Loading

0 comments on commit d11e41c

Please sign in to comment.