hrbattle 1.1.2 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/battle/config/jsonConfigLoader.d.ts +0 -1
- package/dist/battle/config/jsonConfigLoader.js +0 -14
- package/dist/cocos-adapter/ReusableBattleFacade.d.ts +2 -2
- package/dist/cocos-adapter/ReusableBattleFacade.js +4 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +3 -6
- package/src/battle/config/jsonConfigLoader.ts +123 -139
- package/src/cocos-adapter/ReusableBattleFacade.ts +3 -4
- package/src/index.ts +1 -2
- package/src/battle/config/json/designed-buffs.json +0 -611
- package/src/battle/config/json/designed-hero-skill-books.json +0 -146
- package/src/battle/config/json/designed-monster-skill-books.json +0 -310
- package/src/battle/config/json/designed-roster.json +0 -438
- package/src/battle/config/json/designed-skill-templates.json +0 -87
- package/src/battle/config/sampleData.ts +0 -85
- package/tests/battle.spec.ts +0 -786
- package/tests/battleResultOutput.test.ts +0 -124
- package/tests/config.spec.ts +0 -41
- package/tests/json-loader.spec.ts +0 -28
- package/tests/reusable-battle-facade.spec.ts +0 -41
- package/tests/roster.spec.ts +0 -35
- package/tests/skill-level-upgrade.spec.ts +0 -198
- package/tests/targeting.spec.ts +0 -101
|
@@ -20,7 +20,6 @@ export interface BattleJsonConfigBundle {
|
|
|
20
20
|
monsterSkillBooks: JsonHeroSkillBook[];
|
|
21
21
|
roster: JsonRoster;
|
|
22
22
|
}
|
|
23
|
-
export declare function loadBattleJsonConfigBundle(): BattleJsonConfigBundle;
|
|
24
23
|
export declare function validateBattleJsonConfigBundle(bundle: BattleJsonConfigBundle): void;
|
|
25
24
|
/** 英雄入参:可以是纯 heroId 字符串,也可以带技能等级覆盖 */
|
|
26
25
|
export type HeroInput = string | {
|
|
@@ -45,20 +45,6 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
45
45
|
}
|
|
46
46
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
47
47
|
};
|
|
48
|
-
import designedBuffs from "./json/designed-buffs.json" with { type: "json" };
|
|
49
|
-
import designedHeroSkillBooks from "./json/designed-hero-skill-books.json" with { type: "json" };
|
|
50
|
-
import designedMonsterSkillBooks from "./json/designed-monster-skill-books.json" with { type: "json" };
|
|
51
|
-
import designedRoster from "./json/designed-roster.json" with { type: "json" };
|
|
52
|
-
import designedSkillTemplates from "./json/designed-skill-templates.json" with { type: "json" };
|
|
53
|
-
export function loadBattleJsonConfigBundle() {
|
|
54
|
-
return {
|
|
55
|
-
buffs: designedBuffs,
|
|
56
|
-
skillTemplates: designedSkillTemplates,
|
|
57
|
-
heroSkillBooks: designedHeroSkillBooks,
|
|
58
|
-
monsterSkillBooks: designedMonsterSkillBooks,
|
|
59
|
-
roster: designedRoster
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
48
|
export function validateBattleJsonConfigBundle(bundle) {
|
|
63
49
|
var e_1, _a, e_2, _b, e_3, _c, e_4, _d, e_5, _e, e_6, _f;
|
|
64
50
|
var buffIds = new Set(bundle.buffs.map(function (item) { return item.id; }));
|
|
@@ -2,7 +2,7 @@ import type { BattleResult } from "../battle/battleCore.js";
|
|
|
2
2
|
import { type BattleJsonConfigBundle, type HeroInput } from "../battle/config/jsonConfigLoader.js";
|
|
3
3
|
import type { BattleConfig, BattleInitUnit, ISkillScript } from "../battle/types.js";
|
|
4
4
|
export interface ReusableBattleFacadeOptions {
|
|
5
|
-
bundle
|
|
5
|
+
bundle: BattleJsonConfigBundle;
|
|
6
6
|
scripts?: Record<string, ISkillScript>;
|
|
7
7
|
defaultConfig?: BattleConfig;
|
|
8
8
|
validateBundle?: boolean;
|
|
@@ -12,7 +12,7 @@ export declare class ReusableBattleFacade {
|
|
|
12
12
|
private readonly bundle;
|
|
13
13
|
private readonly scripts;
|
|
14
14
|
private defaultConfig?;
|
|
15
|
-
constructor(options
|
|
15
|
+
constructor(options: ReusableBattleFacadeOptions);
|
|
16
16
|
getBundle(): BattleJsonConfigBundle;
|
|
17
17
|
setDefaultConfig(config: BattleConfig): void;
|
|
18
18
|
buildUnits(team1?: HeroInput[], team2?: HeroInput[]): BattleInitUnit[];
|
|
@@ -36,16 +36,15 @@ var __read = (this && this.__read) || function (o, n) {
|
|
|
36
36
|
}
|
|
37
37
|
return ar;
|
|
38
38
|
};
|
|
39
|
-
import { buildBattleUnitsFromJsonBundle,
|
|
39
|
+
import { buildBattleUnitsFromJsonBundle, validateBattleJsonConfigBundle } from "../battle/config/jsonConfigLoader.js";
|
|
40
40
|
import { designedScripts } from "../battle/script/designedScripts.js";
|
|
41
41
|
import { BattleFacade } from "./BattleFacade.js";
|
|
42
42
|
var ReusableBattleFacade = /** @class */ (function () {
|
|
43
43
|
function ReusableBattleFacade(options) {
|
|
44
|
-
|
|
45
|
-
var _a, _b;
|
|
44
|
+
var _a;
|
|
46
45
|
this.facade = new BattleFacade();
|
|
47
|
-
this.bundle =
|
|
48
|
-
this.scripts = (
|
|
46
|
+
this.bundle = options.bundle;
|
|
47
|
+
this.scripts = (_a = options.scripts) !== null && _a !== void 0 ? _a : designedScripts;
|
|
49
48
|
this.defaultConfig = options.defaultConfig;
|
|
50
49
|
if (options.validateBundle !== false) {
|
|
51
50
|
validateBattleJsonConfigBundle(this.bundle);
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export { EffectSystem } from "./battle/effectSystem.js";
|
|
|
8
8
|
export { calcDamage, calcEffectProbability, calcHealOrShield } from "./battle/formula.js";
|
|
9
9
|
export { ConfigSkillEngine, ScriptSkillEngine, SkillExecutor } from "./battle/skillEngine.js";
|
|
10
10
|
export { designedScripts } from "./battle/script/designedScripts.js";
|
|
11
|
-
export {
|
|
11
|
+
export { validateBattleJsonConfigBundle, buildBattleUnitsFromJsonBundle } from "./battle/config/jsonConfigLoader.js";
|
|
12
12
|
export type { BattleJsonConfigBundle, HeroInput } from "./battle/config/jsonConfigLoader.js";
|
|
13
13
|
export type { BattleScriptApi, BattleConfig, BattleInitUnit, BuffConfig, ElementType, ISkillScript, SkillDefinition, SkillExecMode, SkillTemplate, SkillType, TargetRule, UnitModel, UnitStats } from "./battle/types.js";
|
|
14
14
|
export type { BattleResult } from "./battle/battleCore.js";
|
package/dist/index.js
CHANGED
|
@@ -7,4 +7,4 @@ export { EffectSystem } from "./battle/effectSystem.js";
|
|
|
7
7
|
export { calcDamage, calcEffectProbability, calcHealOrShield } from "./battle/formula.js";
|
|
8
8
|
export { ConfigSkillEngine, ScriptSkillEngine, SkillExecutor } from "./battle/skillEngine.js";
|
|
9
9
|
export { designedScripts } from "./battle/script/designedScripts.js";
|
|
10
|
-
export {
|
|
10
|
+
export { validateBattleJsonConfigBundle, buildBattleUnitsFromJsonBundle } from "./battle/config/jsonConfigLoader.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hrbattle",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "一个基于回合制战斗引擎,支持技能脚本、buff系统和效果解析。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -13,13 +13,11 @@
|
|
|
13
13
|
},
|
|
14
14
|
"files": [
|
|
15
15
|
"dist",
|
|
16
|
-
"src"
|
|
17
|
-
"tests"
|
|
16
|
+
"src"
|
|
18
17
|
],
|
|
19
18
|
"scripts": {
|
|
20
19
|
"build": "tsc",
|
|
21
|
-
"prepublishOnly": "npm run build"
|
|
22
|
-
"battle:result": "vitest run tests/battleResultOutput.test.ts"
|
|
20
|
+
"prepublishOnly": "npm run build"
|
|
23
21
|
},
|
|
24
22
|
"keywords": [
|
|
25
23
|
"battle",
|
|
@@ -34,7 +32,6 @@
|
|
|
34
32
|
"@types/node": "^22.15.3",
|
|
35
33
|
"tsx": "^4.19.4",
|
|
36
34
|
"typescript": "^5.8.3",
|
|
37
|
-
"vitest": "^3.1.2",
|
|
38
35
|
"xlsx": "^0.18.5"
|
|
39
36
|
}
|
|
40
37
|
}
|
|
@@ -1,139 +1,123 @@
|
|
|
1
|
-
import type { BattleInitUnit, BuffConfig, SkillDefinition, SkillTemplate, UnitStats } from "../types.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
for (const
|
|
52
|
-
if (
|
|
53
|
-
throw new Error(`missing-
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
position,
|
|
125
|
-
element: heroBook.element,
|
|
126
|
-
stats: cloneStats(stats),
|
|
127
|
-
skills: heroBook.skills.map((skill) => {
|
|
128
|
-
const cloned = { ...skill };
|
|
129
|
-
if (skillLevels && skillLevels[skill.id] !== undefined) {
|
|
130
|
-
cloned.level = skillLevels[skill.id];
|
|
131
|
-
}
|
|
132
|
-
return cloned;
|
|
133
|
-
})
|
|
134
|
-
};
|
|
135
|
-
});
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
return [...buildTeam(1, team1Inputs), ...buildTeam(2, team2Inputs)];
|
|
139
|
-
}
|
|
1
|
+
import type { BattleInitUnit, BuffConfig, SkillDefinition, SkillTemplate, UnitStats } from "../types.js";
|
|
2
|
+
|
|
3
|
+
type JsonHeroSkillBook = {
|
|
4
|
+
heroId: string;
|
|
5
|
+
heroName: string;
|
|
6
|
+
element: BattleInitUnit["element"];
|
|
7
|
+
role: string;
|
|
8
|
+
skills: SkillDefinition[];
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
type JsonRoster = {
|
|
12
|
+
heroStatProfiles: Record<string, UnitStats>;
|
|
13
|
+
defaultLineup: {
|
|
14
|
+
team1: string[];
|
|
15
|
+
team2: string[];
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export interface BattleJsonConfigBundle {
|
|
20
|
+
buffs: BuffConfig[];
|
|
21
|
+
skillTemplates: SkillTemplate[];
|
|
22
|
+
heroSkillBooks: JsonHeroSkillBook[];
|
|
23
|
+
monsterSkillBooks: JsonHeroSkillBook[];
|
|
24
|
+
roster: JsonRoster;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function validateBattleJsonConfigBundle(bundle: BattleJsonConfigBundle): void {
|
|
28
|
+
const buffIds = new Set(bundle.buffs.map((item) => item.id));
|
|
29
|
+
const templateIds = new Set(bundle.skillTemplates.map((item) => item.id));
|
|
30
|
+
|
|
31
|
+
for (const hero of bundle.heroSkillBooks) {
|
|
32
|
+
if (!bundle.roster.heroStatProfiles[hero.heroId]) {
|
|
33
|
+
throw new Error(`missing-stat-profile:${hero.heroId}`);
|
|
34
|
+
}
|
|
35
|
+
for (const skill of hero.skills) {
|
|
36
|
+
if (skill.configTemplateId && !templateIds.has(skill.configTemplateId)) {
|
|
37
|
+
throw new Error(`missing-skill-template:${hero.heroId}:${skill.id}:${skill.configTemplateId}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
for (const monster of bundle.monsterSkillBooks) {
|
|
43
|
+
for (const skill of monster.skills) {
|
|
44
|
+
if (skill.configTemplateId && !templateIds.has(skill.configTemplateId)) {
|
|
45
|
+
throw new Error(`missing-skill-template:${monster.heroId}:${skill.id}:${skill.configTemplateId}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
for (const template of bundle.skillTemplates) {
|
|
51
|
+
for (const step of template.steps) {
|
|
52
|
+
if (step.buffId && !buffIds.has(step.buffId)) {
|
|
53
|
+
throw new Error(`missing-buff-config:${template.id}:${step.buffId}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function cloneStats(stats: UnitStats): UnitStats {
|
|
60
|
+
return { ...stats };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function buildUnitInstanceId(teamId: 1 | 2, position: 1 | 2 | 3 | 4, heroId: string): string {
|
|
64
|
+
return `t${teamId}_p${position}_${heroId}`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** 英雄入参:可以是纯 heroId 字符串,也可以带技能等级覆盖 */
|
|
68
|
+
export type HeroInput = string | {
|
|
69
|
+
heroId: string;
|
|
70
|
+
/** 技能等级覆盖,key 为 skillId,value 为等级数值 */
|
|
71
|
+
skillLevels?: Record<string, number>;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
function normalizeHeroInput(input: HeroInput): { heroId: string; skillLevels?: Record<string, number> } {
|
|
75
|
+
if (typeof input === "string") return { heroId: input };
|
|
76
|
+
return input;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function buildBattleUnitsFromJsonBundle(
|
|
80
|
+
bundle: BattleJsonConfigBundle,
|
|
81
|
+
team1?: HeroInput[],
|
|
82
|
+
team2?: HeroInput[]
|
|
83
|
+
): BattleInitUnit[] {
|
|
84
|
+
const team1Inputs = team1 ?? bundle.roster.defaultLineup.team1;
|
|
85
|
+
const team2Inputs = team2 ?? bundle.roster.defaultLineup.team2;
|
|
86
|
+
|
|
87
|
+
const heroBookMap = new Map([
|
|
88
|
+
...bundle.heroSkillBooks.map((item) => [item.heroId, item] as const),
|
|
89
|
+
...bundle.monsterSkillBooks.map((item) => [item.heroId, item] as const),
|
|
90
|
+
]);
|
|
91
|
+
|
|
92
|
+
const buildTeam = (teamId: 1 | 2, inputs: HeroInput[]): BattleInitUnit[] => {
|
|
93
|
+
return inputs.map((input, index) => {
|
|
94
|
+
const { heroId, skillLevels } = normalizeHeroInput(input);
|
|
95
|
+
const heroBook = heroBookMap.get(heroId);
|
|
96
|
+
if (!heroBook) {
|
|
97
|
+
throw new Error(`missing-hero-skill-book:${heroId}`);
|
|
98
|
+
}
|
|
99
|
+
const position = (index + 1) as 1 | 2 | 3 | 4;
|
|
100
|
+
const stats = bundle.roster.heroStatProfiles[heroId];
|
|
101
|
+
if (!stats) {
|
|
102
|
+
throw new Error(`missing-hero-stat-profile:${heroId}`);
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
id: buildUnitInstanceId(teamId, position, heroId),
|
|
106
|
+
name: heroBook.heroName,
|
|
107
|
+
teamId,
|
|
108
|
+
position,
|
|
109
|
+
element: heroBook.element,
|
|
110
|
+
stats: cloneStats(stats),
|
|
111
|
+
skills: heroBook.skills.map((skill) => {
|
|
112
|
+
const cloned = { ...skill };
|
|
113
|
+
if (skillLevels && skillLevels[skill.id] !== undefined) {
|
|
114
|
+
cloned.level = skillLevels[skill.id];
|
|
115
|
+
}
|
|
116
|
+
return cloned;
|
|
117
|
+
})
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
return [...buildTeam(1, team1Inputs), ...buildTeam(2, team2Inputs)];
|
|
123
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { BattleResult } from "../battle/battleCore.js";
|
|
2
2
|
import {
|
|
3
3
|
buildBattleUnitsFromJsonBundle,
|
|
4
|
-
loadBattleJsonConfigBundle,
|
|
5
4
|
validateBattleJsonConfigBundle,
|
|
6
5
|
type BattleJsonConfigBundle,
|
|
7
6
|
type HeroInput
|
|
@@ -11,7 +10,7 @@ import type { BattleConfig, BattleInitUnit, ISkillScript } from "../battle/types
|
|
|
11
10
|
import { BattleFacade } from "./BattleFacade.js";
|
|
12
11
|
|
|
13
12
|
export interface ReusableBattleFacadeOptions {
|
|
14
|
-
bundle
|
|
13
|
+
bundle: BattleJsonConfigBundle;
|
|
15
14
|
scripts?: Record<string, ISkillScript>;
|
|
16
15
|
defaultConfig?: BattleConfig;
|
|
17
16
|
validateBundle?: boolean;
|
|
@@ -23,8 +22,8 @@ export class ReusableBattleFacade {
|
|
|
23
22
|
private readonly scripts: Record<string, ISkillScript>;
|
|
24
23
|
private defaultConfig?: BattleConfig;
|
|
25
24
|
|
|
26
|
-
constructor(options: ReusableBattleFacadeOptions
|
|
27
|
-
this.bundle = options.bundle
|
|
25
|
+
constructor(options: ReusableBattleFacadeOptions) {
|
|
26
|
+
this.bundle = options.bundle;
|
|
28
27
|
this.scripts = options.scripts ?? designedScripts;
|
|
29
28
|
this.defaultConfig = options.defaultConfig;
|
|
30
29
|
if (options.validateBundle !== false) {
|
package/src/index.ts
CHANGED
|
@@ -20,7 +20,6 @@ export { calcDamage, calcEffectProbability, calcHealOrShield } from "./battle/fo
|
|
|
20
20
|
export { ConfigSkillEngine, ScriptSkillEngine, SkillExecutor } from "./battle/skillEngine.js";
|
|
21
21
|
export { designedScripts } from "./battle/script/designedScripts.js";
|
|
22
22
|
export {
|
|
23
|
-
loadBattleJsonConfigBundle,
|
|
24
23
|
validateBattleJsonConfigBundle,
|
|
25
24
|
buildBattleUnitsFromJsonBundle
|
|
26
25
|
} from "./battle/config/jsonConfigLoader.js";
|
|
@@ -43,4 +42,4 @@ export type {
|
|
|
43
42
|
UnitModel,
|
|
44
43
|
UnitStats
|
|
45
44
|
} from "./battle/types.js";
|
|
46
|
-
export type { BattleResult } from "./battle/battleCore.js";
|
|
45
|
+
export type { BattleResult } from "./battle/battleCore.js";
|