@rpgjs/action-battle 5.0.0-beta.5 → 5.0.0-beta.6
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/README.md +115 -0
- package/dist/ai.server.d.ts +17 -2
- package/dist/client/index.js +13 -8
- package/dist/client/index10.js +54 -136
- package/dist/client/index11.js +52 -23
- package/dist/client/index12.js +101 -1217
- package/dist/client/index13.js +139 -42
- package/dist/client/index14.js +23 -8
- package/dist/client/index15.js +68 -444
- package/dist/client/index16.js +1281 -0
- package/dist/client/index17.js +13 -0
- package/dist/client/index18.js +60 -0
- package/dist/client/index19.js +10 -0
- package/dist/client/index2.js +25 -87
- package/dist/client/index20.js +504 -0
- package/dist/client/index3.js +45 -83
- package/dist/client/index4.js +98 -297
- package/dist/client/index5.js +81 -33
- package/dist/client/index6.js +284 -78
- package/dist/client/index7.js +33 -74
- package/dist/client/index8.js +95 -55
- package/dist/client/index9.js +75 -96
- package/dist/core/attack-profile.d.ts +9 -0
- package/dist/core/attack-runtime.d.ts +20 -0
- package/dist/core/enemy-attack-profiles.d.ts +6 -0
- package/dist/core/equipment.d.ts +2 -0
- package/dist/core/hit-reaction.d.ts +5 -0
- package/dist/index.d.ts +6 -1
- package/dist/server/index.js +12 -7
- package/dist/server/index10.js +1278 -8
- package/dist/server/index11.js +37 -0
- package/dist/server/index12.js +60 -0
- package/dist/server/index13.js +13 -0
- package/dist/server/index14.js +503 -0
- package/dist/server/index15.js +10 -0
- package/dist/server/index3.js +25 -87
- package/dist/server/index4.js +45 -141
- package/dist/server/index5.js +104 -21
- package/dist/server/index6.js +137 -1215
- package/dist/server/index7.js +22 -34
- package/dist/server/index8.js +70 -44
- package/dist/server/index9.js +44 -437
- package/dist/server.d.ts +7 -1
- package/package.json +5 -5
- package/src/ai.server.ts +172 -43
- package/src/client.ts +21 -12
- package/src/config.ts +17 -2
- package/src/core/attack-profile.spec.ts +118 -0
- package/src/core/attack-profile.ts +100 -0
- package/src/core/attack-runtime.spec.ts +103 -0
- package/src/core/attack-runtime.ts +83 -0
- package/src/core/contracts.ts +3 -0
- package/src/core/enemy-attack-profiles.spec.ts +35 -0
- package/src/core/enemy-attack-profiles.ts +103 -0
- package/src/core/equipment.spec.ts +37 -0
- package/src/core/equipment.ts +17 -0
- package/src/core/hit-reaction.spec.ts +43 -0
- package/src/core/hit-reaction.ts +70 -0
- package/src/core/hit.spec.ts +54 -1
- package/src/core/hit.ts +26 -0
- package/src/index.ts +36 -0
- package/src/server.ts +180 -33
- package/src/types.ts +62 -6
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/core/equipment.ts
|
|
2
|
+
var resolveItemId = (item) => item?.id?.() ?? item?.id;
|
|
3
|
+
function resolveActionBattleWeaponAttackProfile(entity) {
|
|
4
|
+
const equipments = entity?.equipments?.() || [];
|
|
5
|
+
for (const item of equipments) {
|
|
6
|
+
const itemId = resolveItemId(item);
|
|
7
|
+
const itemData = entity?.databaseById?.(itemId);
|
|
8
|
+
if (itemData?._type === "weapon" && itemData.attackProfile) return itemData.attackProfile;
|
|
9
|
+
}
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { resolveActionBattleWeaponAttackProfile };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { isActionBattleEntityInvincible, setActionBattleInvincibility } from "./index2.js";
|
|
2
|
+
//#region src/core/hit.ts
|
|
3
|
+
var applyActionBattleHit = (system, context) => {
|
|
4
|
+
let hitContext = { ...context };
|
|
5
|
+
const before = system.hooks?.beforeHit?.(hitContext);
|
|
6
|
+
if (before === false) return {
|
|
7
|
+
damage: 0,
|
|
8
|
+
knockbackForce: 0,
|
|
9
|
+
knockbackDuration: 0,
|
|
10
|
+
defeated: false,
|
|
11
|
+
attacker: hitContext.attacker,
|
|
12
|
+
target: hitContext.target,
|
|
13
|
+
cancelled: true,
|
|
14
|
+
metadata: hitContext.metadata
|
|
15
|
+
};
|
|
16
|
+
if (before) hitContext = before;
|
|
17
|
+
if (isActionBattleEntityInvincible(hitContext.target)) return {
|
|
18
|
+
damage: 0,
|
|
19
|
+
knockbackForce: 0,
|
|
20
|
+
knockbackDuration: 0,
|
|
21
|
+
defeated: false,
|
|
22
|
+
attacker: hitContext.attacker,
|
|
23
|
+
target: hitContext.target,
|
|
24
|
+
cancelled: true,
|
|
25
|
+
metadata: hitContext.metadata,
|
|
26
|
+
reaction: hitContext.reaction
|
|
27
|
+
};
|
|
28
|
+
const damage = hitContext.damage ?? system.resolveDamage({
|
|
29
|
+
attacker: hitContext.attacker,
|
|
30
|
+
target: hitContext.target,
|
|
31
|
+
skill: hitContext.skill,
|
|
32
|
+
pattern: hitContext.pattern
|
|
33
|
+
});
|
|
34
|
+
hitContext.damage = damage;
|
|
35
|
+
const afterDamage = system.hooks?.afterDamage?.(hitContext);
|
|
36
|
+
if (afterDamage) hitContext = afterDamage;
|
|
37
|
+
const knockback = hitContext.knockback ?? system.resolveKnockback({
|
|
38
|
+
attacker: hitContext.attacker,
|
|
39
|
+
target: hitContext.target,
|
|
40
|
+
damage
|
|
41
|
+
});
|
|
42
|
+
hitContext.knockback = knockback;
|
|
43
|
+
if (!damage.defeated && knockback.force > 0 && knockback.direction) hitContext.target.knockback?.(knockback.direction, knockback.force, knockback.duration);
|
|
44
|
+
if (!damage.defeated && hitContext.reaction?.invincibilityMs) setActionBattleInvincibility(hitContext.target, hitContext.reaction.invincibilityMs);
|
|
45
|
+
const result = {
|
|
46
|
+
damage: damage.damage,
|
|
47
|
+
knockbackForce: knockback.force,
|
|
48
|
+
knockbackDuration: knockback.duration,
|
|
49
|
+
defeated: damage.defeated,
|
|
50
|
+
attacker: hitContext.attacker,
|
|
51
|
+
target: hitContext.target,
|
|
52
|
+
rawDamage: damage.raw,
|
|
53
|
+
reaction: hitContext.reaction,
|
|
54
|
+
metadata: hitContext.metadata
|
|
55
|
+
};
|
|
56
|
+
system.hooks?.afterHit?.(result);
|
|
57
|
+
return result;
|
|
58
|
+
};
|
|
59
|
+
//#endregion
|
|
60
|
+
export { applyActionBattleHit };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/enemies/factory.ts
|
|
2
|
+
var BattleAi = null;
|
|
3
|
+
var createActionEnemy = (event, presetOrOptions, presets = {}) => {
|
|
4
|
+
const options = typeof presetOrOptions === "string" ? presets[presetOrOptions] : presetOrOptions;
|
|
5
|
+
if (!options) throw new Error(`Action battle enemy preset not found: ${presetOrOptions}`);
|
|
6
|
+
options.stats?.(event);
|
|
7
|
+
return new BattleAi(event, options);
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
export { createActionEnemy };
|
package/dist/client/index2.js
CHANGED
|
@@ -1,94 +1,32 @@
|
|
|
1
|
-
//#region src/
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
autoOpen: false,
|
|
7
|
-
mode: "both"
|
|
8
|
-
},
|
|
9
|
-
targeting: {
|
|
10
|
-
enabled: true,
|
|
11
|
-
showGrid: true,
|
|
12
|
-
colors: {
|
|
13
|
-
area: 3120887,
|
|
14
|
-
edge: 1796760,
|
|
15
|
-
cursor: 16765286
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
skills: { defaultAoeMask: ["#"] },
|
|
20
|
-
targeting: {
|
|
21
|
-
affects: "events",
|
|
22
|
-
allowEmptyTarget: true
|
|
23
|
-
},
|
|
24
|
-
attack: {
|
|
25
|
-
lockMovement: true,
|
|
26
|
-
lockDurationMs: 350,
|
|
27
|
-
showPreview: true,
|
|
28
|
-
previewDurationMs: 180,
|
|
29
|
-
previewColor: 16774064,
|
|
30
|
-
previewAccentColor: 16777215
|
|
31
|
-
},
|
|
32
|
-
animations: {}
|
|
1
|
+
//#region src/core/hit-reaction.ts
|
|
2
|
+
var DEFAULT_ACTION_BATTLE_HIT_REACTION = {
|
|
3
|
+
invincibilityMs: 250,
|
|
4
|
+
hitstunMs: 150,
|
|
5
|
+
staggerPower: 1
|
|
33
6
|
};
|
|
34
|
-
var
|
|
35
|
-
|
|
7
|
+
var STATE_KEY = "__actionBattleHitReaction";
|
|
8
|
+
var isFiniteNumber = (value) => typeof value === "number" && Number.isFinite(value);
|
|
9
|
+
var nonNegativeMs = (value, fallback) => isFiniteNumber(value) ? Math.max(0, value) : fallback;
|
|
10
|
+
var nonNegativeValue = (value, fallback) => isFiniteNumber(value) ? Math.max(0, value) : fallback;
|
|
11
|
+
var getRuntimeState = (entity) => {
|
|
12
|
+
if (!entity[STATE_KEY]) entity[STATE_KEY] = { invincibleUntil: 0 };
|
|
13
|
+
return entity[STATE_KEY];
|
|
14
|
+
};
|
|
15
|
+
function normalizeActionBattleHitReaction(reaction, defaults = DEFAULT_ACTION_BATTLE_HIT_REACTION) {
|
|
36
16
|
return {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
...options.ui?.actionBar
|
|
41
|
-
},
|
|
42
|
-
targeting: {
|
|
43
|
-
...DEFAULT_ACTION_BATTLE_OPTIONS.ui?.targeting,
|
|
44
|
-
...options.ui?.targeting,
|
|
45
|
-
colors: {
|
|
46
|
-
...DEFAULT_ACTION_BATTLE_OPTIONS.ui?.targeting?.colors,
|
|
47
|
-
...options.ui?.targeting?.colors
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
skills: {
|
|
52
|
-
...DEFAULT_ACTION_BATTLE_OPTIONS.skills,
|
|
53
|
-
...options.skills
|
|
54
|
-
},
|
|
55
|
-
targeting: {
|
|
56
|
-
...DEFAULT_ACTION_BATTLE_OPTIONS.targeting,
|
|
57
|
-
...options.targeting
|
|
58
|
-
},
|
|
59
|
-
attack: {
|
|
60
|
-
...DEFAULT_ACTION_BATTLE_OPTIONS.attack,
|
|
61
|
-
...options.attack
|
|
62
|
-
},
|
|
63
|
-
animations: {
|
|
64
|
-
...DEFAULT_ACTION_BATTLE_OPTIONS.animations,
|
|
65
|
-
...options.animations
|
|
66
|
-
},
|
|
67
|
-
systems: {
|
|
68
|
-
combat: {
|
|
69
|
-
...DEFAULT_ACTION_BATTLE_OPTIONS.systems?.combat,
|
|
70
|
-
...options.systems?.combat,
|
|
71
|
-
hooks: {
|
|
72
|
-
...DEFAULT_ACTION_BATTLE_OPTIONS.systems?.combat?.hooks,
|
|
73
|
-
...options.systems?.combat?.hooks
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
ai: {
|
|
77
|
-
...DEFAULT_ACTION_BATTLE_OPTIONS.systems?.ai,
|
|
78
|
-
...options.systems?.ai,
|
|
79
|
-
behaviors: {
|
|
80
|
-
...DEFAULT_ACTION_BATTLE_OPTIONS.systems?.ai?.behaviors,
|
|
81
|
-
...options.systems?.ai?.behaviors
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
17
|
+
invincibilityMs: nonNegativeMs(reaction?.invincibilityMs, defaults.invincibilityMs),
|
|
18
|
+
hitstunMs: nonNegativeMs(reaction?.hitstunMs, defaults.hitstunMs),
|
|
19
|
+
staggerPower: nonNegativeValue(reaction?.staggerPower, defaults.staggerPower)
|
|
85
20
|
};
|
|
86
21
|
}
|
|
87
|
-
function
|
|
88
|
-
|
|
22
|
+
function isActionBattleEntityInvincible(entity, now = Date.now()) {
|
|
23
|
+
if (!entity) return false;
|
|
24
|
+
return getRuntimeState(entity).invincibleUntil > now;
|
|
89
25
|
}
|
|
90
|
-
function
|
|
91
|
-
return
|
|
26
|
+
function setActionBattleInvincibility(entity, durationMs, now = Date.now()) {
|
|
27
|
+
if (!entity || durationMs <= 0) return;
|
|
28
|
+
const state = getRuntimeState(entity);
|
|
29
|
+
state.invincibleUntil = Math.max(state.invincibleUntil, now + durationMs);
|
|
92
30
|
}
|
|
93
31
|
//#endregion
|
|
94
|
-
export {
|
|
32
|
+
export { DEFAULT_ACTION_BATTLE_HIT_REACTION, isActionBattleEntityInvincible, normalizeActionBattleHitReaction, setActionBattleInvincibility };
|