@sharpee/world-model 3.0.0 → 3.1.0
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/behaviors/index.d.ts +1 -0
- package/behaviors/index.d.ts.map +1 -1
- package/behaviors/index.js +4 -1
- package/behaviors/index.js.map +1 -1
- package/capabilities/action-interceptor.d.ts +93 -6
- package/capabilities/action-interceptor.d.ts.map +1 -1
- package/capabilities/action-interceptor.js +59 -2
- package/capabilities/action-interceptor.js.map +1 -1
- package/capabilities/index.d.ts +1 -1
- package/capabilities/index.d.ts.map +1 -1
- package/capabilities/index.js +2 -1
- package/capabilities/index.js.map +1 -1
- package/index.d.ts +13 -0
- package/index.d.ts.map +1 -1
- package/index.js +23 -0
- package/index.js.map +1 -1
- package/package.json +3 -3
- package/traits/combatant/combatantBehavior.d.ts +23 -18
- package/traits/combatant/combatantBehavior.d.ts.map +1 -1
- package/traits/combatant/combatantBehavior.js +47 -45
- package/traits/combatant/combatantBehavior.js.map +1 -1
- package/traits/combatant/combatantTrait.d.ts +14 -48
- package/traits/combatant/combatantTrait.d.ts.map +1 -1
- package/traits/combatant/combatantTrait.js +13 -80
- package/traits/combatant/combatantTrait.js.map +1 -1
- package/traits/cuttable/cuttableBehavior.d.ts +23 -0
- package/traits/cuttable/cuttableBehavior.d.ts.map +1 -0
- package/traits/cuttable/cuttableBehavior.js +39 -0
- package/traits/cuttable/cuttableBehavior.js.map +1 -0
- package/traits/cuttable/cuttableTrait.d.ts +37 -0
- package/traits/cuttable/cuttableTrait.d.ts.map +1 -0
- package/traits/cuttable/cuttableTrait.js +30 -0
- package/traits/cuttable/cuttableTrait.js.map +1 -0
- package/traits/cuttable/index.d.ts +3 -0
- package/traits/cuttable/index.d.ts.map +1 -0
- package/traits/cuttable/index.js +20 -0
- package/traits/cuttable/index.js.map +1 -0
- package/traits/deadly-room/deadlyRoomBehavior.d.ts +48 -0
- package/traits/deadly-room/deadlyRoomBehavior.d.ts.map +1 -0
- package/traits/deadly-room/deadlyRoomBehavior.js +59 -0
- package/traits/deadly-room/deadlyRoomBehavior.js.map +1 -0
- package/traits/deadly-room/deadlyRoomTrait.d.ts +51 -0
- package/traits/deadly-room/deadlyRoomTrait.d.ts.map +1 -0
- package/traits/deadly-room/deadlyRoomTrait.js +37 -0
- package/traits/deadly-room/deadlyRoomTrait.js.map +1 -0
- package/traits/deadly-room/index.d.ts +3 -0
- package/traits/deadly-room/index.d.ts.map +1 -0
- package/traits/deadly-room/index.js +8 -0
- package/traits/deadly-room/index.js.map +1 -0
- package/traits/diggable/diggableBehavior.d.ts +23 -0
- package/traits/diggable/diggableBehavior.d.ts.map +1 -0
- package/traits/diggable/diggableBehavior.js +39 -0
- package/traits/diggable/diggableBehavior.js.map +1 -0
- package/traits/diggable/diggableTrait.d.ts +37 -0
- package/traits/diggable/diggableTrait.d.ts.map +1 -0
- package/traits/diggable/diggableTrait.js +30 -0
- package/traits/diggable/diggableTrait.js.map +1 -0
- package/traits/diggable/index.d.ts +3 -0
- package/traits/diggable/index.d.ts.map +1 -0
- package/traits/diggable/index.js +20 -0
- package/traits/diggable/index.js.map +1 -0
- package/traits/health/healthBehavior.d.ts +66 -0
- package/traits/health/healthBehavior.d.ts.map +1 -0
- package/traits/health/healthBehavior.js +98 -0
- package/traits/health/healthBehavior.js.map +1 -0
- package/traits/health/healthTrait.d.ts +60 -0
- package/traits/health/healthTrait.d.ts.map +1 -0
- package/traits/health/healthTrait.js +49 -0
- package/traits/health/healthTrait.js.map +1 -0
- package/traits/health/index.d.ts +3 -0
- package/traits/health/index.d.ts.map +1 -0
- package/traits/health/index.js +8 -0
- package/traits/health/index.js.map +1 -0
- package/traits/implementations.d.ts +5 -1
- package/traits/implementations.d.ts.map +1 -1
- package/traits/implementations.js +15 -1
- package/traits/implementations.js.map +1 -1
- package/traits/index.d.ts +4 -0
- package/traits/index.d.ts.map +1 -1
- package/traits/index.js +5 -0
- package/traits/index.js.map +1 -1
- package/traits/npc/npcTrait.d.ts +5 -27
- package/traits/npc/npcTrait.d.ts.map +1 -1
- package/traits/npc/npcTrait.js +0 -38
- package/traits/npc/npcTrait.js.map +1 -1
- package/traits/openable/openableBehavior.d.ts +10 -0
- package/traits/openable/openableBehavior.d.ts.map +1 -1
- package/traits/openable/openableBehavior.js +21 -0
- package/traits/openable/openableBehavior.js.map +1 -1
- package/traits/openable/openableTrait.d.ts +7 -0
- package/traits/openable/openableTrait.d.ts.map +1 -1
- package/traits/openable/openableTrait.js +4 -0
- package/traits/openable/openableTrait.js.map +1 -1
- package/traits/room/roomTrait.d.ts +8 -3
- package/traits/room/roomTrait.d.ts.map +1 -1
- package/traits/room/roomTrait.js +2 -2
- package/traits/room/roomTrait.js.map +1 -1
- package/traits/trait-types.d.ts +4 -0
- package/traits/trait-types.d.ts.map +1 -1
- package/traits/trait-types.js +12 -0
- package/traits/trait-types.js.map +1 -1
- package/world/VisibilityBehavior.d.ts +1 -1
- package/world/VisibilityBehavior.js +4 -4
- package/world/VisibilityBehavior.js.map +1 -1
- package/world/WorldModel.js +1 -1
- package/world/WorldModel.js.map +1 -1
|
@@ -1,33 +1,38 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Behavior for combatant entities
|
|
3
|
+
* Behavior for combatant entities.
|
|
4
|
+
*
|
|
5
|
+
* Combat orchestration — armor reduction, inventory-drop on death, combat messages —
|
|
6
|
+
* over the entity's combat *stats* (`CombatantTrait`). Health itself lives on the
|
|
7
|
+
* required {@link HealthTrait}; all health reads/writes route through
|
|
8
|
+
* {@link HealthBehavior} (ADR-226 / ADR-223 child A). A combatant is guaranteed a
|
|
9
|
+
* `HealthTrait` by the load-time AC-7 check.
|
|
10
|
+
*
|
|
11
|
+
* Public interface: `canAttack` / `attack` / `heal` / `resurrect` / `isAlive` /
|
|
12
|
+
* `getHealth` / `getHealthPercentage` / `isHostile` / `setHostile`.
|
|
13
|
+
* Owner context: `@sharpee/world-model` — combat (requires the HEALTH layer).
|
|
4
14
|
*/
|
|
5
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
16
|
exports.CombatBehavior = void 0;
|
|
7
17
|
const behavior_1 = require("../../behaviors/behavior");
|
|
8
18
|
const trait_types_1 = require("../trait-types");
|
|
9
|
-
|
|
10
|
-
* Behavior for combatant entities.
|
|
11
|
-
*
|
|
12
|
-
* Handles combat with health, armor, and death.
|
|
13
|
-
* This is a world-aware behavior because it handles inventory dropping on death.
|
|
14
|
-
*/
|
|
19
|
+
const healthBehavior_1 = require("../health/healthBehavior");
|
|
15
20
|
class CombatBehavior extends behavior_1.Behavior {
|
|
16
|
-
static requiredTraits = [trait_types_1.TraitType.COMBATANT];
|
|
21
|
+
static requiredTraits = [trait_types_1.TraitType.COMBATANT, trait_types_1.TraitType.HEALTH];
|
|
17
22
|
/**
|
|
18
|
-
* Check if a combatant can be attacked
|
|
23
|
+
* Check if a combatant can be attacked (present, and alive per its health).
|
|
19
24
|
*/
|
|
20
25
|
static canAttack(entity) {
|
|
21
26
|
if (!entity.has(trait_types_1.TraitType.COMBATANT)) {
|
|
22
27
|
return false;
|
|
23
28
|
}
|
|
24
|
-
const
|
|
25
|
-
return
|
|
29
|
+
const health = CombatBehavior.optional(entity, trait_types_1.TraitType.HEALTH);
|
|
30
|
+
return health ? healthBehavior_1.HealthBehavior.isAlive(health) : true;
|
|
26
31
|
}
|
|
27
32
|
/**
|
|
28
|
-
* Attack a combatant
|
|
33
|
+
* Attack a combatant.
|
|
29
34
|
* @param entity The combatant to attack
|
|
30
|
-
* @param damage Base damage amount
|
|
35
|
+
* @param damage Base damage amount (pre-armor)
|
|
31
36
|
* @param world The world model (needed for dropping inventory)
|
|
32
37
|
* @returns Result describing what happened
|
|
33
38
|
*/
|
|
@@ -42,7 +47,8 @@ class CombatBehavior extends behavior_1.Behavior {
|
|
|
42
47
|
};
|
|
43
48
|
}
|
|
44
49
|
const combatant = entity.get(trait_types_1.TraitType.COMBATANT);
|
|
45
|
-
|
|
50
|
+
const health = CombatBehavior.require(entity, trait_types_1.TraitType.HEALTH);
|
|
51
|
+
if (!healthBehavior_1.HealthBehavior.isAlive(health)) {
|
|
46
52
|
return {
|
|
47
53
|
success: false,
|
|
48
54
|
damage: 0,
|
|
@@ -50,21 +56,19 @@ class CombatBehavior extends behavior_1.Behavior {
|
|
|
50
56
|
remainingHealth: 0
|
|
51
57
|
};
|
|
52
58
|
}
|
|
53
|
-
// Apply armor reduction
|
|
59
|
+
// Apply armor reduction (always at least 1 damage), then route through health.
|
|
54
60
|
const actualDamage = Math.max(1, damage - combatant.armor);
|
|
55
|
-
|
|
56
|
-
combatant.health = Math.max(0, combatant.health - actualDamage);
|
|
61
|
+
const killed = healthBehavior_1.HealthBehavior.takeDamage(health, actualDamage, 'combat');
|
|
57
62
|
const result = {
|
|
58
63
|
success: true,
|
|
59
64
|
damage: actualDamage,
|
|
60
|
-
killed
|
|
61
|
-
remainingHealth:
|
|
65
|
+
killed,
|
|
66
|
+
remainingHealth: health.health,
|
|
62
67
|
message: combatant.hitMessage,
|
|
63
|
-
retaliated: combatant.canRetaliate &&
|
|
68
|
+
retaliated: combatant.canRetaliate && !killed
|
|
64
69
|
};
|
|
65
70
|
// Handle death
|
|
66
|
-
if (
|
|
67
|
-
combatant.isAlive = false;
|
|
71
|
+
if (killed) {
|
|
68
72
|
result.deathMessage = combatant.deathMessage;
|
|
69
73
|
// Drop inventory if specified
|
|
70
74
|
if (combatant.dropsInventory) {
|
|
@@ -85,66 +89,64 @@ class CombatBehavior extends behavior_1.Behavior {
|
|
|
85
89
|
return result;
|
|
86
90
|
}
|
|
87
91
|
/**
|
|
88
|
-
* Heal a combatant
|
|
92
|
+
* Heal a combatant. Returns the amount actually healed.
|
|
89
93
|
*/
|
|
90
94
|
static heal(entity, amount) {
|
|
91
95
|
if (!entity.has(trait_types_1.TraitType.COMBATANT)) {
|
|
92
96
|
return 0;
|
|
93
97
|
}
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
return 0;
|
|
97
|
-
const oldHealth = combatant.health;
|
|
98
|
-
combatant.health = Math.min(combatant.maxHealth, combatant.health + amount);
|
|
99
|
-
return combatant.health - oldHealth;
|
|
98
|
+
const health = CombatBehavior.require(entity, trait_types_1.TraitType.HEALTH);
|
|
99
|
+
return healthBehavior_1.HealthBehavior.heal(health, amount);
|
|
100
100
|
}
|
|
101
101
|
/**
|
|
102
|
-
* Resurrect a dead combatant
|
|
102
|
+
* Resurrect a dead combatant — clears the terminal state and restores full health.
|
|
103
|
+
* @returns true if a dead combatant was resurrected, false if it was already alive
|
|
103
104
|
*/
|
|
104
105
|
static resurrect(entity) {
|
|
105
106
|
if (!entity.has(trait_types_1.TraitType.COMBATANT)) {
|
|
106
107
|
return false;
|
|
107
108
|
}
|
|
108
|
-
const
|
|
109
|
-
if (
|
|
109
|
+
const health = CombatBehavior.require(entity, trait_types_1.TraitType.HEALTH);
|
|
110
|
+
if (healthBehavior_1.HealthBehavior.isAlive(health))
|
|
110
111
|
return false;
|
|
111
|
-
|
|
112
|
-
|
|
112
|
+
health.dead = false;
|
|
113
|
+
health.causeOfDeath = undefined;
|
|
114
|
+
health.health = health.maxHealth;
|
|
113
115
|
return true;
|
|
114
116
|
}
|
|
115
117
|
/**
|
|
116
|
-
* Check if combatant is alive
|
|
118
|
+
* Check if combatant is alive (via its health). Non-combatants are alive by default.
|
|
117
119
|
*/
|
|
118
120
|
static isAlive(entity) {
|
|
119
121
|
if (!entity.has(trait_types_1.TraitType.COMBATANT)) {
|
|
120
122
|
return true; // Non-combatants are considered 'alive' by default
|
|
121
123
|
}
|
|
122
|
-
const
|
|
123
|
-
return
|
|
124
|
+
const health = CombatBehavior.optional(entity, trait_types_1.TraitType.HEALTH);
|
|
125
|
+
return health ? healthBehavior_1.HealthBehavior.isAlive(health) : true;
|
|
124
126
|
}
|
|
125
127
|
/**
|
|
126
|
-
* Get current health
|
|
128
|
+
* Get current health.
|
|
127
129
|
*/
|
|
128
130
|
static getHealth(entity) {
|
|
129
|
-
const
|
|
130
|
-
return
|
|
131
|
+
const health = CombatBehavior.require(entity, trait_types_1.TraitType.HEALTH);
|
|
132
|
+
return health.health;
|
|
131
133
|
}
|
|
132
134
|
/**
|
|
133
|
-
* Get health percentage
|
|
135
|
+
* Get health percentage.
|
|
134
136
|
*/
|
|
135
137
|
static getHealthPercentage(entity) {
|
|
136
|
-
const
|
|
137
|
-
return (
|
|
138
|
+
const health = CombatBehavior.require(entity, trait_types_1.TraitType.HEALTH);
|
|
139
|
+
return (health.health / health.maxHealth) * 100;
|
|
138
140
|
}
|
|
139
141
|
/**
|
|
140
|
-
* Check if combatant is hostile
|
|
142
|
+
* Check if combatant is hostile.
|
|
141
143
|
*/
|
|
142
144
|
static isHostile(entity) {
|
|
143
145
|
const combatant = CombatBehavior.require(entity, trait_types_1.TraitType.COMBATANT);
|
|
144
146
|
return combatant.hostile;
|
|
145
147
|
}
|
|
146
148
|
/**
|
|
147
|
-
* Set hostility
|
|
149
|
+
* Set hostility.
|
|
148
150
|
*/
|
|
149
151
|
static setHostile(entity, hostile) {
|
|
150
152
|
const combatant = CombatBehavior.require(entity, trait_types_1.TraitType.COMBATANT);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combatantBehavior.js","sourceRoot":"","sources":["../../../../../../../../repos/sharpee_v2/packages/world-model/src/traits/combatant/combatantBehavior.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"combatantBehavior.js","sourceRoot":"","sources":["../../../../../../../../repos/sharpee_v2/packages/world-model/src/traits/combatant/combatantBehavior.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Combatant trait for entities that can engage in combat
|
|
2
|
+
* Combatant trait for entities that can engage in combat.
|
|
3
|
+
*
|
|
4
|
+
* Combat STATS only (ADR-226 / ADR-223 child A): a combatant's health, alive/
|
|
5
|
+
* conscious state, and recovery live on the entity's {@link HealthTrait} — the single
|
|
6
|
+
* life-state source — not here. `CombatantTrait` *requires* a `HealthTrait`
|
|
7
|
+
* (enforced at load; ADR-226 §2 / AC-7). Hostility stays here for now (moves to
|
|
8
|
+
* disposition in ADR-223 child C).
|
|
9
|
+
*
|
|
10
|
+
* Data only — all combat logic is in `CombatBehavior`, which reads/writes health
|
|
11
|
+
* through `HealthBehavior`.
|
|
12
|
+
* Owner context: `@sharpee/world-model` — combat stats (requires the HEALTH layer).
|
|
3
13
|
*/
|
|
4
14
|
import { ITrait } from '../trait';
|
|
5
15
|
export interface ICombatantData {
|
|
6
|
-
/** Current health points */
|
|
7
|
-
health?: number;
|
|
8
|
-
/** Maximum health points */
|
|
9
|
-
maxHealth?: number;
|
|
10
16
|
/** Combat skill (0-100, affects hit/dodge chance) - ADR-072 */
|
|
11
17
|
skill?: number;
|
|
12
18
|
/** Natural damage (if no weapon) - ADR-072 */
|
|
13
19
|
baseDamage?: number;
|
|
14
|
-
/** Whether this combatant is conscious (false = knocked out) - ADR-072 */
|
|
15
|
-
isConscious?: boolean;
|
|
16
|
-
/** Turns until consciousness recovery - ADR-072 */
|
|
17
|
-
recoveryTurns?: number;
|
|
18
20
|
/** Armor value that reduces damage */
|
|
19
21
|
armor?: number;
|
|
20
22
|
/** Attack power modifier (legacy, use baseDamage) */
|
|
21
23
|
attackPower?: number;
|
|
22
24
|
/** Defense modifier */
|
|
23
25
|
defense?: number;
|
|
24
|
-
/** Whether this combatant is alive */
|
|
25
|
-
isAlive?: boolean;
|
|
26
26
|
/** Custom message when hit */
|
|
27
27
|
hitMessage?: string;
|
|
28
28
|
/** Custom message when killed */
|
|
29
29
|
deathMessage?: string;
|
|
30
30
|
/** Custom message when attacking */
|
|
31
31
|
attackMessage?: string;
|
|
32
|
-
/** Whether this combatant is hostile by default */
|
|
32
|
+
/** Whether this combatant is hostile by default (moves to disposition, ADR-223 child C) */
|
|
33
33
|
hostile?: boolean;
|
|
34
34
|
/** Whether this combatant can retaliate */
|
|
35
35
|
canRetaliate?: boolean;
|
|
@@ -43,22 +43,17 @@ export interface ICombatantData {
|
|
|
43
43
|
/**
|
|
44
44
|
* Combatant trait indicates an entity can engage in combat.
|
|
45
45
|
*
|
|
46
|
-
* This trait contains only
|
|
47
|
-
* is in CombatBehavior
|
|
46
|
+
* This trait contains only combat *stats* — health and life-state are on the
|
|
47
|
+
* required {@link HealthTrait}. All combat logic is in `CombatBehavior`.
|
|
48
48
|
*/
|
|
49
49
|
export declare class CombatantTrait implements ITrait, ICombatantData {
|
|
50
50
|
static readonly type: "combatant";
|
|
51
51
|
readonly type: "combatant";
|
|
52
|
-
health: number;
|
|
53
|
-
maxHealth: number;
|
|
54
52
|
skill: number;
|
|
55
53
|
baseDamage: number;
|
|
56
|
-
isConscious: boolean;
|
|
57
|
-
recoveryTurns?: number;
|
|
58
54
|
armor: number;
|
|
59
55
|
attackPower: number;
|
|
60
56
|
defense: number;
|
|
61
|
-
isAlive: boolean;
|
|
62
57
|
hitMessage?: string;
|
|
63
58
|
deathMessage?: string;
|
|
64
59
|
attackMessage?: string;
|
|
@@ -68,34 +63,5 @@ export declare class CombatantTrait implements ITrait, ICombatantData {
|
|
|
68
63
|
experienceValue: number;
|
|
69
64
|
isUndead: boolean;
|
|
70
65
|
constructor(data?: ICombatantData);
|
|
71
|
-
/**
|
|
72
|
-
* Computed property to check if combatant is alive based on health
|
|
73
|
-
*/
|
|
74
|
-
get alive(): boolean;
|
|
75
|
-
/**
|
|
76
|
-
* Check if combatant can act (alive and conscious)
|
|
77
|
-
*/
|
|
78
|
-
get canAct(): boolean;
|
|
79
|
-
/**
|
|
80
|
-
* Knock out this combatant (unconscious but alive)
|
|
81
|
-
*/
|
|
82
|
-
knockOut(recoveryTurns?: number): void;
|
|
83
|
-
/**
|
|
84
|
-
* Wake up this combatant
|
|
85
|
-
*/
|
|
86
|
-
wakeUp(): void;
|
|
87
|
-
/**
|
|
88
|
-
* Kill this combatant
|
|
89
|
-
*/
|
|
90
|
-
kill(): void;
|
|
91
|
-
/**
|
|
92
|
-
* Take damage
|
|
93
|
-
* @returns true if combatant was killed
|
|
94
|
-
*/
|
|
95
|
-
takeDamage(amount: number): boolean;
|
|
96
|
-
/**
|
|
97
|
-
* Heal this combatant
|
|
98
|
-
*/
|
|
99
|
-
heal(amount: number): void;
|
|
100
66
|
}
|
|
101
67
|
//# sourceMappingURL=combatantTrait.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combatantTrait.d.ts","sourceRoot":"","sources":["../../../../../../../../repos/sharpee_v2/packages/world-model/src/traits/combatant/combatantTrait.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"combatantTrait.d.ts","sourceRoot":"","sources":["../../../../../../../../repos/sharpee_v2/packages/world-model/src/traits/combatant/combatantTrait.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,WAAW,cAAc;IAC7B,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,uBAAuB;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,8BAA8B;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,iCAAiC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,oCAAoC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,0CAA0C;IAC1C,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB,8CAA8C;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;GAKG;AACH,qBAAa,cAAe,YAAW,MAAM,EAAE,cAAc;IAC3D,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAG,WAAW,CAAU;IAC5C,QAAQ,CAAC,IAAI,EAAG,WAAW,CAAU;IAErC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;gBAEN,IAAI,GAAE,cAAmB;CAgBtC"}
|
|
@@ -1,29 +1,33 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Combatant trait for entities that can engage in combat
|
|
3
|
+
* Combatant trait for entities that can engage in combat.
|
|
4
|
+
*
|
|
5
|
+
* Combat STATS only (ADR-226 / ADR-223 child A): a combatant's health, alive/
|
|
6
|
+
* conscious state, and recovery live on the entity's {@link HealthTrait} — the single
|
|
7
|
+
* life-state source — not here. `CombatantTrait` *requires* a `HealthTrait`
|
|
8
|
+
* (enforced at load; ADR-226 §2 / AC-7). Hostility stays here for now (moves to
|
|
9
|
+
* disposition in ADR-223 child C).
|
|
10
|
+
*
|
|
11
|
+
* Data only — all combat logic is in `CombatBehavior`, which reads/writes health
|
|
12
|
+
* through `HealthBehavior`.
|
|
13
|
+
* Owner context: `@sharpee/world-model` — combat stats (requires the HEALTH layer).
|
|
4
14
|
*/
|
|
5
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
16
|
exports.CombatantTrait = void 0;
|
|
7
17
|
/**
|
|
8
18
|
* Combatant trait indicates an entity can engage in combat.
|
|
9
19
|
*
|
|
10
|
-
* This trait contains only
|
|
11
|
-
* is in CombatBehavior
|
|
20
|
+
* This trait contains only combat *stats* — health and life-state are on the
|
|
21
|
+
* required {@link HealthTrait}. All combat logic is in `CombatBehavior`.
|
|
12
22
|
*/
|
|
13
23
|
class CombatantTrait {
|
|
14
24
|
static type = 'combatant';
|
|
15
25
|
type = 'combatant';
|
|
16
|
-
// CombatantData properties
|
|
17
|
-
health;
|
|
18
|
-
maxHealth;
|
|
19
26
|
skill;
|
|
20
27
|
baseDamage;
|
|
21
|
-
isConscious;
|
|
22
|
-
recoveryTurns;
|
|
23
28
|
armor;
|
|
24
29
|
attackPower;
|
|
25
30
|
defense;
|
|
26
|
-
isAlive;
|
|
27
31
|
hitMessage;
|
|
28
32
|
deathMessage;
|
|
29
33
|
attackMessage;
|
|
@@ -34,16 +38,11 @@ class CombatantTrait {
|
|
|
34
38
|
isUndead;
|
|
35
39
|
constructor(data = {}) {
|
|
36
40
|
// Set defaults and merge with provided data
|
|
37
|
-
this.health = data.health ?? data.maxHealth ?? 10;
|
|
38
|
-
this.maxHealth = data.maxHealth ?? 10;
|
|
39
41
|
this.skill = data.skill ?? 30; // Default skill level (ADR-072)
|
|
40
42
|
this.baseDamage = data.baseDamage ?? data.attackPower ?? 1; // ADR-072
|
|
41
|
-
this.isConscious = data.isConscious ?? true; // ADR-072
|
|
42
|
-
this.recoveryTurns = data.recoveryTurns; // ADR-072
|
|
43
43
|
this.armor = data.armor ?? 0;
|
|
44
44
|
this.attackPower = data.attackPower ?? 1;
|
|
45
45
|
this.defense = data.defense ?? 0;
|
|
46
|
-
this.isAlive = data.isAlive ?? true;
|
|
47
46
|
this.hitMessage = data.hitMessage;
|
|
48
47
|
this.deathMessage = data.deathMessage;
|
|
49
48
|
this.attackMessage = data.attackMessage;
|
|
@@ -53,72 +52,6 @@ class CombatantTrait {
|
|
|
53
52
|
this.experienceValue = data.experienceValue ?? 0;
|
|
54
53
|
this.isUndead = data.isUndead ?? false;
|
|
55
54
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Computed property to check if combatant is alive based on health
|
|
58
|
-
*/
|
|
59
|
-
get alive() {
|
|
60
|
-
return this.health > 0;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Check if combatant can act (alive and conscious)
|
|
64
|
-
*/
|
|
65
|
-
get canAct() {
|
|
66
|
-
return this.isAlive && this.isConscious;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Knock out this combatant (unconscious but alive)
|
|
70
|
-
*/
|
|
71
|
-
knockOut(recoveryTurns) {
|
|
72
|
-
this.isConscious = false;
|
|
73
|
-
if (recoveryTurns !== undefined) {
|
|
74
|
-
this.recoveryTurns = recoveryTurns;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Wake up this combatant
|
|
79
|
-
*/
|
|
80
|
-
wakeUp() {
|
|
81
|
-
if (this.isAlive) {
|
|
82
|
-
this.isConscious = true;
|
|
83
|
-
this.recoveryTurns = undefined;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Kill this combatant
|
|
88
|
-
*/
|
|
89
|
-
kill() {
|
|
90
|
-
this.health = 0;
|
|
91
|
-
this.isAlive = false;
|
|
92
|
-
this.isConscious = false;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Take damage
|
|
96
|
-
* @returns true if combatant was killed
|
|
97
|
-
*/
|
|
98
|
-
takeDamage(amount) {
|
|
99
|
-
const effectiveDamage = Math.max(0, amount - this.armor);
|
|
100
|
-
this.health = Math.max(0, this.health - effectiveDamage);
|
|
101
|
-
if (this.health <= 0) {
|
|
102
|
-
this.kill();
|
|
103
|
-
return true;
|
|
104
|
-
}
|
|
105
|
-
// Check for knockout (20% health threshold per ADR-072)
|
|
106
|
-
if (this.health <= this.maxHealth * 0.2) {
|
|
107
|
-
this.knockOut();
|
|
108
|
-
}
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Heal this combatant
|
|
113
|
-
*/
|
|
114
|
-
heal(amount) {
|
|
115
|
-
if (this.isAlive) {
|
|
116
|
-
this.health = Math.min(this.maxHealth, this.health + amount);
|
|
117
|
-
if (this.health > this.maxHealth * 0.2) {
|
|
118
|
-
this.wakeUp();
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
55
|
}
|
|
123
56
|
exports.CombatantTrait = CombatantTrait;
|
|
124
57
|
//# sourceMappingURL=combatantTrait.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combatantTrait.js","sourceRoot":"","sources":["../../../../../../../../repos/sharpee_v2/packages/world-model/src/traits/combatant/combatantTrait.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"combatantTrait.js","sourceRoot":"","sources":["../../../../../../../../repos/sharpee_v2/packages/world-model/src/traits/combatant/combatantTrait.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;AA6CH;;;;;GAKG;AACH,MAAa,cAAc;IACzB,MAAM,CAAU,IAAI,GAAG,WAAoB,CAAC;IACnC,IAAI,GAAG,WAAoB,CAAC;IAErC,KAAK,CAAS;IACd,UAAU,CAAS;IACnB,KAAK,CAAS;IACd,WAAW,CAAS;IACpB,OAAO,CAAS;IAChB,UAAU,CAAU;IACpB,YAAY,CAAU;IACtB,aAAa,CAAU;IACvB,OAAO,CAAU;IACjB,YAAY,CAAU;IACtB,cAAc,CAAU;IACxB,eAAe,CAAS;IACxB,QAAQ,CAAU;IAElB,YAAY,OAAuB,EAAE;QACnC,4CAA4C;QAC5C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,gCAAgC;QAC/D,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,UAAU;QACtE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;QACtC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;QACxC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC;QACrC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC;QAC9C,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC;QAClD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC;IACzC,CAAC;;AAjCH,wCAkCC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { EntityId } from '@sharpee/core';
|
|
2
|
+
import { Behavior } from '../../behaviors/behavior';
|
|
3
|
+
import { IFEntity } from '../../entities/if-entity';
|
|
4
|
+
/**
|
|
5
|
+
* Behavior for cuttable entities (ADR-230 D3c).
|
|
6
|
+
*
|
|
7
|
+
* Pure predicates only — the cutting action's validate() consults these;
|
|
8
|
+
* the cut mutation itself belongs to the entity's registered
|
|
9
|
+
* implementation, never here.
|
|
10
|
+
*/
|
|
11
|
+
export declare class CuttableBehavior extends Behavior {
|
|
12
|
+
static requiredTraits: "cuttable"[];
|
|
13
|
+
/**
|
|
14
|
+
* Check if this entity requires a tool to cut (mirrors
|
|
15
|
+
* LockableBehavior.requiresKey / OpenableBehavior.requiresTool)
|
|
16
|
+
*/
|
|
17
|
+
static requiresTool(entity: IFEntity): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Check if a tool can cut this entity (mirrors LockableBehavior.canUnlockWith)
|
|
20
|
+
*/
|
|
21
|
+
static canCutWith(entity: IFEntity, toolId: EntityId): boolean;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=cuttableBehavior.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cuttableBehavior.d.ts","sourceRoot":"","sources":["../../../../../../../../repos/sharpee_v2/packages/world-model/src/traits/cuttable/cuttableBehavior.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAIpD;;;;;;GAMG;AACH,qBAAa,gBAAiB,SAAQ,QAAQ;IAC5C,MAAM,CAAC,cAAc,eAAwB;IAE7C;;;OAGG;IACH,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO;IAK9C;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO;CAa/D"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// packages/world-model/src/traits/cuttable/cuttableBehavior.ts
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.CuttableBehavior = void 0;
|
|
5
|
+
const behavior_1 = require("../../behaviors/behavior");
|
|
6
|
+
const trait_types_1 = require("../trait-types");
|
|
7
|
+
/**
|
|
8
|
+
* Behavior for cuttable entities (ADR-230 D3c).
|
|
9
|
+
*
|
|
10
|
+
* Pure predicates only — the cutting action's validate() consults these;
|
|
11
|
+
* the cut mutation itself belongs to the entity's registered
|
|
12
|
+
* implementation, never here.
|
|
13
|
+
*/
|
|
14
|
+
class CuttableBehavior extends behavior_1.Behavior {
|
|
15
|
+
static requiredTraits = [trait_types_1.TraitType.CUTTABLE];
|
|
16
|
+
/**
|
|
17
|
+
* Check if this entity requires a tool to cut (mirrors
|
|
18
|
+
* LockableBehavior.requiresKey / OpenableBehavior.requiresTool)
|
|
19
|
+
*/
|
|
20
|
+
static requiresTool(entity) {
|
|
21
|
+
const cuttable = CuttableBehavior.require(entity, trait_types_1.TraitType.CUTTABLE);
|
|
22
|
+
return !!(cuttable.toolId || cuttable.toolIds?.length);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Check if a tool can cut this entity (mirrors LockableBehavior.canUnlockWith)
|
|
26
|
+
*/
|
|
27
|
+
static canCutWith(entity, toolId) {
|
|
28
|
+
const cuttable = CuttableBehavior.require(entity, trait_types_1.TraitType.CUTTABLE);
|
|
29
|
+
if (cuttable.toolId === toolId) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
if (cuttable.toolIds && cuttable.toolIds.includes(toolId)) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.CuttableBehavior = CuttableBehavior;
|
|
39
|
+
//# sourceMappingURL=cuttableBehavior.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cuttableBehavior.js","sourceRoot":"","sources":["../../../../../../../../repos/sharpee_v2/packages/world-model/src/traits/cuttable/cuttableBehavior.ts"],"names":[],"mappings":";AAAA,+DAA+D;;;AAG/D,uDAAoD;AAEpD,gDAA2C;AAG3C;;;;;;GAMG;AACH,MAAa,gBAAiB,SAAQ,mBAAQ;IAC5C,MAAM,CAAC,cAAc,GAAG,CAAC,uBAAS,CAAC,QAAQ,CAAC,CAAC;IAE7C;;;OAGG;IACH,MAAM,CAAC,YAAY,CAAC,MAAgB;QAClC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAgB,MAAM,EAAE,uBAAS,CAAC,QAAQ,CAAC,CAAC;QACrF,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,MAAgB,EAAE,MAAgB;QAClD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAgB,MAAM,EAAE,uBAAS,CAAC,QAAQ,CAAC,CAAC;QAErF,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1D,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;;AA3BH,4CA4BC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { EntityId } from '@sharpee/core';
|
|
2
|
+
import { ITrait } from '../trait';
|
|
3
|
+
/**
|
|
4
|
+
* Data for the cuttable trait (ADR-230 D3c).
|
|
5
|
+
*
|
|
6
|
+
* Tool fields mirror ILockableData's key config (PIN 2 shared shape with
|
|
7
|
+
* OpenableTrait's tool fields): a declared requirement makes the cutting
|
|
8
|
+
* action refuse wrong/missing tools; no requirement means any explicit
|
|
9
|
+
* tool (or none) passes validation.
|
|
10
|
+
*/
|
|
11
|
+
export interface ICuttableData {
|
|
12
|
+
/** Single tool entity required to cut this (mirrors ILockableData.keyId) */
|
|
13
|
+
toolId?: EntityId;
|
|
14
|
+
/** Multiple tool entities that can cut this (mirrors ILockableData.keyIds) */
|
|
15
|
+
toolIds?: EntityId[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Cuttable trait — marks an entity the cutting action may target.
|
|
19
|
+
*
|
|
20
|
+
* The trait gates eligibility only. The cut OUTCOME is the entity's own
|
|
21
|
+
* registered implementation (ADR-090 capability behavior from TS, or a
|
|
22
|
+
* Chord `on cutting it` interceptor) — the standard cutting action never
|
|
23
|
+
* mutates state itself. An entity with this trait and no registered
|
|
24
|
+
* implementation is an authoring error (load-time in Chord; runtime
|
|
25
|
+
* safety-net refusal otherwise).
|
|
26
|
+
*
|
|
27
|
+
* This trait contains only data - eligibility/tool logic is in
|
|
28
|
+
* CuttableBehavior.
|
|
29
|
+
*/
|
|
30
|
+
export declare class CuttableTrait implements ITrait, ICuttableData {
|
|
31
|
+
static readonly type: "cuttable";
|
|
32
|
+
readonly type: "cuttable";
|
|
33
|
+
toolId?: EntityId;
|
|
34
|
+
toolIds?: EntityId[];
|
|
35
|
+
constructor(data?: ICuttableData);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=cuttableTrait.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cuttableTrait.d.ts","sourceRoot":"","sources":["../../../../../../../../repos/sharpee_v2/packages/world-model/src/traits/cuttable/cuttableTrait.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGlC;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,MAAM,CAAC,EAAE,QAAQ,CAAC;IAElB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC;CACtB;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAc,YAAW,MAAM,EAAE,aAAa;IACzD,MAAM,CAAC,QAAQ,CAAC,IAAI,aAAsB;IAC1C,QAAQ,CAAC,IAAI,aAAsB;IAEnC,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC;gBAET,IAAI,GAAE,aAAkB;CAIrC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// packages/world-model/src/traits/cuttable/cuttableTrait.ts
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.CuttableTrait = void 0;
|
|
5
|
+
const trait_types_1 = require("../trait-types");
|
|
6
|
+
/**
|
|
7
|
+
* Cuttable trait — marks an entity the cutting action may target.
|
|
8
|
+
*
|
|
9
|
+
* The trait gates eligibility only. The cut OUTCOME is the entity's own
|
|
10
|
+
* registered implementation (ADR-090 capability behavior from TS, or a
|
|
11
|
+
* Chord `on cutting it` interceptor) — the standard cutting action never
|
|
12
|
+
* mutates state itself. An entity with this trait and no registered
|
|
13
|
+
* implementation is an authoring error (load-time in Chord; runtime
|
|
14
|
+
* safety-net refusal otherwise).
|
|
15
|
+
*
|
|
16
|
+
* This trait contains only data - eligibility/tool logic is in
|
|
17
|
+
* CuttableBehavior.
|
|
18
|
+
*/
|
|
19
|
+
class CuttableTrait {
|
|
20
|
+
static type = trait_types_1.TraitType.CUTTABLE;
|
|
21
|
+
type = trait_types_1.TraitType.CUTTABLE;
|
|
22
|
+
toolId;
|
|
23
|
+
toolIds;
|
|
24
|
+
constructor(data = {}) {
|
|
25
|
+
this.toolId = data.toolId;
|
|
26
|
+
this.toolIds = data.toolIds;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.CuttableTrait = CuttableTrait;
|
|
30
|
+
//# sourceMappingURL=cuttableTrait.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cuttableTrait.js","sourceRoot":"","sources":["../../../../../../../../repos/sharpee_v2/packages/world-model/src/traits/cuttable/cuttableTrait.ts"],"names":[],"mappings":";AAAA,4DAA4D;;;AAI5D,gDAA2C;AAkB3C;;;;;;;;;;;;GAYG;AACH,MAAa,aAAa;IACxB,MAAM,CAAU,IAAI,GAAG,uBAAS,CAAC,QAAQ,CAAC;IACjC,IAAI,GAAG,uBAAS,CAAC,QAAQ,CAAC;IAEnC,MAAM,CAAY;IAClB,OAAO,CAAc;IAErB,YAAY,OAAsB,EAAE;QAClC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAC9B,CAAC;;AAVH,sCAWC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../repos/sharpee_v2/packages/world-model/src/traits/cuttable/index.ts"],"names":[],"mappings":"AAEA,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// packages/world-model/src/traits/cuttable/index.ts
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
15
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
16
|
+
};
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
__exportStar(require("./cuttableTrait"), exports);
|
|
19
|
+
__exportStar(require("./cuttableBehavior"), exports);
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../repos/sharpee_v2/packages/world-model/src/traits/cuttable/index.ts"],"names":[],"mappings":";AAAA,oDAAoD;;;;;;;;;;;;;;;;AAEpD,kDAAgC;AAChC,qDAAmC"}
|