@sharpee/ext-basic-combat 0.9.86
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/basic-combat-interceptor.d.ts +17 -0
- package/basic-combat-interceptor.d.ts.map +1 -0
- package/basic-combat-interceptor.js +62 -0
- package/basic-combat-interceptor.js.map +1 -0
- package/basic-npc-resolver.d.ts +15 -0
- package/basic-npc-resolver.d.ts.map +1 -0
- package/basic-npc-resolver.js +87 -0
- package/basic-npc-resolver.js.map +1 -0
- package/combat-messages.d.ts +52 -0
- package/combat-messages.d.ts.map +1 -0
- package/combat-messages.js +69 -0
- package/combat-messages.js.map +1 -0
- package/combat-service.d.ts +107 -0
- package/combat-service.d.ts.map +1 -0
- package/combat-service.js +210 -0
- package/combat-service.js.map +1 -0
- package/index.d.ts +37 -0
- package/index.d.ts.map +1 -0
- package/index.js +58 -0
- package/index.js.map +1 -0
- package/package.json +23 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Basic Combat Interceptor
|
|
3
|
+
*
|
|
4
|
+
* Wraps CombatService as an ActionInterceptor for PC→NPC attacks.
|
|
5
|
+
* Registered on CombatantTrait for if.action.attacking.
|
|
6
|
+
*/
|
|
7
|
+
import { ActionInterceptor } from "./src/index";
|
|
8
|
+
/**
|
|
9
|
+
* ActionInterceptor that uses CombatService for PC→NPC combat resolution.
|
|
10
|
+
*
|
|
11
|
+
* postExecute populates sharedData with:
|
|
12
|
+
* - attackResult: AttackResult-shaped object
|
|
13
|
+
* - combatResult: CombatResult from CombatService
|
|
14
|
+
* - usedCombatService: true
|
|
15
|
+
*/
|
|
16
|
+
export declare const BasicCombatInterceptor: ActionInterceptor;
|
|
17
|
+
//# sourceMappingURL=basic-combat-interceptor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"basic-combat-interceptor.d.ts","sourceRoot":"","sources":["../../../../../mnt/c/repotemp/sharpee/packages/extensions/basic-combat/src/basic-combat-interceptor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,iBAAiB,EAMlB,MAAM,sBAAsB,CAAC;AAS9B;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,iBA4CpC,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Basic Combat Interceptor
|
|
4
|
+
*
|
|
5
|
+
* Wraps CombatService as an ActionInterceptor for PC→NPC attacks.
|
|
6
|
+
* Registered on CombatantTrait for if.action.attacking.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.BasicCombatInterceptor = void 0;
|
|
10
|
+
const core_1 = require("./src/index.js");
|
|
11
|
+
const stdlib_1 = require("./src/index.js");
|
|
12
|
+
const combat_service_js_1 = require("./combat-service.js");
|
|
13
|
+
/**
|
|
14
|
+
* Module-level random instance for consistent combat rolls.
|
|
15
|
+
*/
|
|
16
|
+
const combatRandom = (0, core_1.createSeededRandom)();
|
|
17
|
+
/**
|
|
18
|
+
* ActionInterceptor that uses CombatService for PC→NPC combat resolution.
|
|
19
|
+
*
|
|
20
|
+
* postExecute populates sharedData with:
|
|
21
|
+
* - attackResult: AttackResult-shaped object
|
|
22
|
+
* - combatResult: CombatResult from CombatService
|
|
23
|
+
* - usedCombatService: true
|
|
24
|
+
*/
|
|
25
|
+
exports.BasicCombatInterceptor = {
|
|
26
|
+
postExecute(target, world, actorId, sharedData) {
|
|
27
|
+
const attacker = world.getEntity(actorId);
|
|
28
|
+
if (!attacker)
|
|
29
|
+
return;
|
|
30
|
+
// Use weapon from sharedData (attacking.ts passes it) or find one
|
|
31
|
+
const weaponId = sharedData.weaponId;
|
|
32
|
+
const weapon = weaponId
|
|
33
|
+
? world.getEntity(weaponId)
|
|
34
|
+
: (0, stdlib_1.findWieldedWeapon)(attacker, world);
|
|
35
|
+
const combatService = new combat_service_js_1.CombatService();
|
|
36
|
+
const combatResult = combatService.resolveAttack({
|
|
37
|
+
attacker,
|
|
38
|
+
target,
|
|
39
|
+
weapon: weapon || undefined,
|
|
40
|
+
world,
|
|
41
|
+
random: combatRandom,
|
|
42
|
+
});
|
|
43
|
+
// Apply combat result to target (handles health, death, inventory dropping)
|
|
44
|
+
const combatApplyResult = (0, combat_service_js_1.applyCombatResult)(target, combatResult, world);
|
|
45
|
+
// Populate sharedData for the report phase
|
|
46
|
+
sharedData.attackResult = {
|
|
47
|
+
success: true,
|
|
48
|
+
type: combatResult.targetKilled ? 'killed' :
|
|
49
|
+
combatResult.targetKnockedOut ? 'knocked_out' :
|
|
50
|
+
combatResult.hit ? 'hit' : 'missed',
|
|
51
|
+
damage: combatResult.damage,
|
|
52
|
+
remainingHitPoints: combatResult.targetNewHealth,
|
|
53
|
+
targetDestroyed: false,
|
|
54
|
+
targetKilled: combatResult.targetKilled,
|
|
55
|
+
targetKnockedOut: combatResult.targetKnockedOut,
|
|
56
|
+
itemsDropped: combatApplyResult.droppedItems,
|
|
57
|
+
};
|
|
58
|
+
sharedData.combatResult = combatResult;
|
|
59
|
+
sharedData.usedCombatService = true;
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=basic-combat-interceptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"basic-combat-interceptor.js","sourceRoot":"","sources":["../../../../../mnt/c/repotemp/sharpee/packages/extensions/basic-combat/src/basic-combat-interceptor.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,wCAAiE;AASjE,4CAAoD;AACpD,2DAAqF;AAErF;;GAEG;AACH,MAAM,YAAY,GAAiB,IAAA,yBAAkB,GAAE,CAAC;AAExD;;;;;;;GAOG;AACU,QAAA,sBAAsB,GAAsB;IACvD,WAAW,CACT,MAAgB,EAChB,KAAiB,EACjB,OAAe,EACf,UAAiC;QAEjC,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEtB,kEAAkE;QAClE,MAAM,QAAQ,GAAG,UAAU,CAAC,QAA8B,CAAC;QAC3D,MAAM,MAAM,GAAG,QAAQ;YACrB,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC;YAC3B,CAAC,CAAC,IAAA,0BAAiB,EAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAEvC,MAAM,aAAa,GAAG,IAAI,iCAAa,EAAE,CAAC;QAC1C,MAAM,YAAY,GAAG,aAAa,CAAC,aAAa,CAAC;YAC/C,QAAQ;YACR,MAAM;YACN,MAAM,EAAE,MAAM,IAAI,SAAS;YAC3B,KAAK;YACL,MAAM,EAAE,YAAY;SACrB,CAAC,CAAC;QAEH,4EAA4E;QAC5E,MAAM,iBAAiB,GAAG,IAAA,qCAAiB,EAAC,MAAM,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;QAEzE,2CAA2C;QAC3C,UAAU,CAAC,YAAY,GAAG;YACxB,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;gBACtC,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;oBAC/C,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ;YACzC,MAAM,EAAE,YAAY,CAAC,MAAM;YAC3B,kBAAkB,EAAE,YAAY,CAAC,eAAe;YAChD,eAAe,EAAE,KAAK;YACtB,YAAY,EAAE,YAAY,CAAC,YAAY;YACvC,gBAAgB,EAAE,YAAY,CAAC,gBAAgB;YAC/C,YAAY,EAAE,iBAAiB,CAAC,YAAY;SAC7C,CAAC;QACF,UAAU,CAAC,YAAY,GAAG,YAAY,CAAC;QACvC,UAAU,CAAC,iBAAiB,GAAG,IAAI,CAAC;IACtC,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Basic NPC Combat Resolver
|
|
3
|
+
*
|
|
4
|
+
* Wraps CombatService as an NpcCombatResolver for NPC→PC (and NPC→NPC) attacks.
|
|
5
|
+
* Used by npc-service.ts executeAttack() when registered.
|
|
6
|
+
*/
|
|
7
|
+
import type { NpcCombatResolver } from "./src/index";
|
|
8
|
+
/**
|
|
9
|
+
* Basic NPC combat resolver using CombatService.
|
|
10
|
+
*
|
|
11
|
+
* Resolves NPC attacks using the skill-based probability system.
|
|
12
|
+
* Returns semantic events for the attack result and optional death.
|
|
13
|
+
*/
|
|
14
|
+
export declare const basicNpcResolver: NpcCombatResolver;
|
|
15
|
+
//# sourceMappingURL=basic-npc-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"basic-npc-resolver.d.ts","sourceRoot":"","sources":["../../../../../mnt/c/repotemp/sharpee/packages/extensions/basic-combat/src/basic-npc-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AA8BzD;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,iBAuE9B,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Basic NPC Combat Resolver
|
|
4
|
+
*
|
|
5
|
+
* Wraps CombatService as an NpcCombatResolver for NPC→PC (and NPC→NPC) attacks.
|
|
6
|
+
* Used by npc-service.ts executeAttack() when registered.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.basicNpcResolver = void 0;
|
|
10
|
+
const core_1 = require("./src/index.js");
|
|
11
|
+
const world_model_1 = require("./src/index.js");
|
|
12
|
+
const stdlib_1 = require("./src/index.js");
|
|
13
|
+
const combat_service_js_1 = require("./combat-service.js");
|
|
14
|
+
/**
|
|
15
|
+
* Module-level random instance for NPC combat rolls.
|
|
16
|
+
*/
|
|
17
|
+
const npcCombatRandom = (0, core_1.createSeededRandom)();
|
|
18
|
+
let eventCounter = 0;
|
|
19
|
+
/**
|
|
20
|
+
* Create a semantic event (mirrors npc-service's createEvent pattern).
|
|
21
|
+
*/
|
|
22
|
+
function createEvent(type, data, sourceId) {
|
|
23
|
+
return {
|
|
24
|
+
id: `npc-combat-${Date.now()}-${++eventCounter}`,
|
|
25
|
+
type,
|
|
26
|
+
data,
|
|
27
|
+
entities: {
|
|
28
|
+
actor: sourceId,
|
|
29
|
+
},
|
|
30
|
+
timestamp: Date.now(),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Basic NPC combat resolver using CombatService.
|
|
35
|
+
*
|
|
36
|
+
* Resolves NPC attacks using the skill-based probability system.
|
|
37
|
+
* Returns semantic events for the attack result and optional death.
|
|
38
|
+
*/
|
|
39
|
+
const basicNpcResolver = (npc, target, world, random) => {
|
|
40
|
+
const events = [];
|
|
41
|
+
// Only resolve for combatant targets
|
|
42
|
+
if (!target.has(world_model_1.TraitType.COMBATANT)) {
|
|
43
|
+
events.push(createEvent('npc.attacked', {
|
|
44
|
+
npc: npc.id,
|
|
45
|
+
target: target.id,
|
|
46
|
+
}, npc.id));
|
|
47
|
+
return events;
|
|
48
|
+
}
|
|
49
|
+
const combatService = new combat_service_js_1.CombatService();
|
|
50
|
+
// Find NPC's weapon
|
|
51
|
+
const npcInventory = world.getContents(npc.id);
|
|
52
|
+
const weapon = (0, stdlib_1.findWieldedWeapon)(npc, world) ||
|
|
53
|
+
npcInventory.find(item => item.isWeapon);
|
|
54
|
+
const combatResult = combatService.resolveAttack({
|
|
55
|
+
attacker: npc,
|
|
56
|
+
target,
|
|
57
|
+
weapon: weapon || undefined,
|
|
58
|
+
world,
|
|
59
|
+
random,
|
|
60
|
+
});
|
|
61
|
+
// Apply combat result to target
|
|
62
|
+
(0, combat_service_js_1.applyCombatResult)(target, combatResult, world);
|
|
63
|
+
// Emit attack event with combat result
|
|
64
|
+
const npcMessageId = combatResult.messageId.replace('combat.attack.', 'npc.combat.attack.');
|
|
65
|
+
events.push(createEvent('npc.attacked', {
|
|
66
|
+
npc: npc.id,
|
|
67
|
+
npcName: npc.name,
|
|
68
|
+
target: target.id,
|
|
69
|
+
targetName: target.name,
|
|
70
|
+
hit: combatResult.hit,
|
|
71
|
+
damage: combatResult.damage,
|
|
72
|
+
messageId: npcMessageId,
|
|
73
|
+
targetKilled: combatResult.targetKilled,
|
|
74
|
+
targetKnockedOut: combatResult.targetKnockedOut,
|
|
75
|
+
}, npc.id));
|
|
76
|
+
// If target was killed, emit death event
|
|
77
|
+
if (combatResult.targetKilled) {
|
|
78
|
+
events.push(createEvent('if.event.death', {
|
|
79
|
+
target: target.id,
|
|
80
|
+
targetName: target.name,
|
|
81
|
+
killedBy: npc.id,
|
|
82
|
+
}, npc.id));
|
|
83
|
+
}
|
|
84
|
+
return events;
|
|
85
|
+
};
|
|
86
|
+
exports.basicNpcResolver = basicNpcResolver;
|
|
87
|
+
//# sourceMappingURL=basic-npc-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"basic-npc-resolver.js","sourceRoot":"","sources":["../../../../../mnt/c/repotemp/sharpee/packages/extensions/basic-combat/src/basic-npc-resolver.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,wCAAiF;AACjF,sDAI8B;AAC9B,4CAAoD;AAEpD,2DAAuE;AAGvE;;GAEG;AACH,MAAM,eAAe,GAAiB,IAAA,yBAAkB,GAAE,CAAC;AAE3D,IAAI,YAAY,GAAG,CAAC,CAAC;AAErB;;GAEG;AACH,SAAS,WAAW,CAClB,IAAY,EACZ,IAA6B,EAC7B,QAAiB;IAEjB,OAAO;QACL,EAAE,EAAE,cAAc,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,YAAY,EAAE;QAChD,IAAI;QACJ,IAAI;QACJ,QAAQ,EAAE;YACR,KAAK,EAAE,QAAQ;SAChB;QACD,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACtB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACI,MAAM,gBAAgB,GAAsB,CACjD,GAAa,EACb,MAAgB,EAChB,KAAiB,EACjB,MAAoB,EACF,EAAE;IACpB,MAAM,MAAM,GAAqB,EAAE,CAAC;IAEpC,qCAAqC;IACrC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,uBAAS,CAAC,SAAS,CAAC,EAAE,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,WAAW,CACrB,cAAc,EACd;YACE,GAAG,EAAE,GAAG,CAAC,EAAE;YACX,MAAM,EAAE,MAAM,CAAC,EAAE;SAClB,EACD,GAAG,CAAC,EAAE,CACP,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,iCAAa,EAAE,CAAC;IAE1C,oBAAoB;IACpB,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,IAAA,0BAAiB,EAAC,GAAG,EAAE,KAAK,CAAC;QAC1C,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAE,IAAY,CAAC,QAAQ,CAAC,CAAC;IAEpD,MAAM,YAAY,GAAG,aAAa,CAAC,aAAa,CAAC;QAC/C,QAAQ,EAAE,GAAG;QACb,MAAM;QACN,MAAM,EAAE,MAAM,IAAI,SAAS;QAC3B,KAAK;QACL,MAAM;KACP,CAAC,CAAC;IAEH,gCAAgC;IAChC,IAAA,qCAAiB,EAAC,MAAM,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;IAE/C,uCAAuC;IACvC,MAAM,YAAY,GAAG,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,gBAAgB,EAAE,oBAAoB,CAAC,CAAC;IAC5F,MAAM,CAAC,IAAI,CAAC,WAAW,CACrB,cAAc,EACd;QACE,GAAG,EAAE,GAAG,CAAC,EAAE;QACX,OAAO,EAAE,GAAG,CAAC,IAAI;QACjB,MAAM,EAAE,MAAM,CAAC,EAAE;QACjB,UAAU,EAAE,MAAM,CAAC,IAAI;QACvB,GAAG,EAAE,YAAY,CAAC,GAAG;QACrB,MAAM,EAAE,YAAY,CAAC,MAAM;QAC3B,SAAS,EAAE,YAAY;QACvB,YAAY,EAAE,YAAY,CAAC,YAAY;QACvC,gBAAgB,EAAE,YAAY,CAAC,gBAAgB;KAChD,EACD,GAAG,CAAC,EAAE,CACP,CAAC,CAAC;IAEH,yCAAyC;IACzC,IAAI,YAAY,CAAC,YAAY,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,WAAW,CACrB,gBAAgB,EAChB;YACE,MAAM,EAAE,MAAM,CAAC,EAAE;YACjB,UAAU,EAAE,MAAM,CAAC,IAAI;YACvB,QAAQ,EAAE,GAAG,CAAC,EAAE;SACjB,EACD,GAAG,CAAC,EAAE,CACP,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAvEW,QAAA,gBAAgB,oBAuE3B"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Combat Message IDs (ADR-072)
|
|
3
|
+
*
|
|
4
|
+
* Semantic message IDs for combat-related events.
|
|
5
|
+
* Actual text is provided by the language layer.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Message IDs for combat events
|
|
9
|
+
*/
|
|
10
|
+
export declare const CombatMessages: {
|
|
11
|
+
readonly ATTACK_MISSED: "combat.attack.missed";
|
|
12
|
+
readonly ATTACK_HIT: "combat.attack.hit";
|
|
13
|
+
readonly ATTACK_HIT_LIGHT: "combat.attack.hit_light";
|
|
14
|
+
readonly ATTACK_HIT_HEAVY: "combat.attack.hit_heavy";
|
|
15
|
+
readonly ATTACK_KNOCKED_OUT: "combat.attack.knocked_out";
|
|
16
|
+
readonly ATTACK_KILLED: "combat.attack.killed";
|
|
17
|
+
readonly DEFEND_BLOCKED: "combat.defend.blocked";
|
|
18
|
+
readonly DEFEND_PARRIED: "combat.defend.parried";
|
|
19
|
+
readonly DEFEND_DODGED: "combat.defend.dodged";
|
|
20
|
+
readonly HEALTH_HEALTHY: "combat.health.healthy";
|
|
21
|
+
readonly HEALTH_WOUNDED: "combat.health.wounded";
|
|
22
|
+
readonly HEALTH_BADLY_WOUNDED: "combat.health.badly_wounded";
|
|
23
|
+
readonly HEALTH_NEAR_DEATH: "combat.health.near_death";
|
|
24
|
+
readonly HEALTH_UNCONSCIOUS: "combat.health.unconscious";
|
|
25
|
+
readonly HEALTH_DEAD: "combat.health.dead";
|
|
26
|
+
readonly SWORD_GLOWS: "combat.special.sword_glows";
|
|
27
|
+
readonly SWORD_STOPS_GLOWING: "combat.special.sword_stops_glowing";
|
|
28
|
+
readonly BLESSED_WEAPON_EFFECT: "combat.special.blessed_weapon";
|
|
29
|
+
readonly CANNOT_ATTACK: "combat.cannot_attack";
|
|
30
|
+
readonly ALREADY_DEAD: "combat.already_dead";
|
|
31
|
+
readonly NOT_HOSTILE: "combat.not_hostile";
|
|
32
|
+
readonly NO_TARGET: "combat.no_target";
|
|
33
|
+
readonly TARGET_UNCONSCIOUS: "combat.target_unconscious";
|
|
34
|
+
readonly NEED_WEAPON: "combat.need_weapon";
|
|
35
|
+
readonly COMBAT_STARTED: "combat.started";
|
|
36
|
+
readonly COMBAT_ENDED: "combat.ended";
|
|
37
|
+
readonly PLAYER_DIED: "combat.player_died";
|
|
38
|
+
readonly PLAYER_RESURRECTED: "combat.player_resurrected";
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Type for combat message IDs
|
|
42
|
+
*/
|
|
43
|
+
export type CombatMessageId = (typeof CombatMessages)[keyof typeof CombatMessages];
|
|
44
|
+
/**
|
|
45
|
+
* Health status levels
|
|
46
|
+
*/
|
|
47
|
+
export type HealthStatus = 'healthy' | 'wounded' | 'badly_wounded' | 'near_death' | 'unconscious' | 'dead';
|
|
48
|
+
/**
|
|
49
|
+
* Get message ID for a health status
|
|
50
|
+
*/
|
|
51
|
+
export declare function getHealthStatusMessageId(status: HealthStatus): CombatMessageId;
|
|
52
|
+
//# sourceMappingURL=combat-messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"combat-messages.d.ts","sourceRoot":"","sources":["../../../../../mnt/c/repotemp/sharpee/packages/extensions/basic-combat/src/combat-messages.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCjB,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,OAAO,cAAc,CAAC,CAAC;AAEnF;;GAEG;AACH,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,SAAS,GACT,eAAe,GACf,YAAY,GACZ,aAAa,GACb,MAAM,CAAC;AAEX;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,YAAY,GAAG,eAAe,CAe9E"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Combat Message IDs (ADR-072)
|
|
4
|
+
*
|
|
5
|
+
* Semantic message IDs for combat-related events.
|
|
6
|
+
* Actual text is provided by the language layer.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.CombatMessages = void 0;
|
|
10
|
+
exports.getHealthStatusMessageId = getHealthStatusMessageId;
|
|
11
|
+
/**
|
|
12
|
+
* Message IDs for combat events
|
|
13
|
+
*/
|
|
14
|
+
exports.CombatMessages = {
|
|
15
|
+
// Attack outcomes
|
|
16
|
+
ATTACK_MISSED: 'combat.attack.missed',
|
|
17
|
+
ATTACK_HIT: 'combat.attack.hit',
|
|
18
|
+
ATTACK_HIT_LIGHT: 'combat.attack.hit_light',
|
|
19
|
+
ATTACK_HIT_HEAVY: 'combat.attack.hit_heavy',
|
|
20
|
+
ATTACK_KNOCKED_OUT: 'combat.attack.knocked_out',
|
|
21
|
+
ATTACK_KILLED: 'combat.attack.killed',
|
|
22
|
+
// Defense outcomes
|
|
23
|
+
DEFEND_BLOCKED: 'combat.defend.blocked',
|
|
24
|
+
DEFEND_PARRIED: 'combat.defend.parried',
|
|
25
|
+
DEFEND_DODGED: 'combat.defend.dodged',
|
|
26
|
+
// Health status descriptions
|
|
27
|
+
HEALTH_HEALTHY: 'combat.health.healthy',
|
|
28
|
+
HEALTH_WOUNDED: 'combat.health.wounded',
|
|
29
|
+
HEALTH_BADLY_WOUNDED: 'combat.health.badly_wounded',
|
|
30
|
+
HEALTH_NEAR_DEATH: 'combat.health.near_death',
|
|
31
|
+
HEALTH_UNCONSCIOUS: 'combat.health.unconscious',
|
|
32
|
+
HEALTH_DEAD: 'combat.health.dead',
|
|
33
|
+
// Special weapon messages
|
|
34
|
+
SWORD_GLOWS: 'combat.special.sword_glows',
|
|
35
|
+
SWORD_STOPS_GLOWING: 'combat.special.sword_stops_glowing',
|
|
36
|
+
BLESSED_WEAPON_EFFECT: 'combat.special.blessed_weapon',
|
|
37
|
+
// Error/validation messages
|
|
38
|
+
CANNOT_ATTACK: 'combat.cannot_attack',
|
|
39
|
+
ALREADY_DEAD: 'combat.already_dead',
|
|
40
|
+
NOT_HOSTILE: 'combat.not_hostile',
|
|
41
|
+
NO_TARGET: 'combat.no_target',
|
|
42
|
+
TARGET_UNCONSCIOUS: 'combat.target_unconscious',
|
|
43
|
+
NEED_WEAPON: 'combat.need_weapon',
|
|
44
|
+
// Combat state messages
|
|
45
|
+
COMBAT_STARTED: 'combat.started',
|
|
46
|
+
COMBAT_ENDED: 'combat.ended',
|
|
47
|
+
PLAYER_DIED: 'combat.player_died',
|
|
48
|
+
PLAYER_RESURRECTED: 'combat.player_resurrected',
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Get message ID for a health status
|
|
52
|
+
*/
|
|
53
|
+
function getHealthStatusMessageId(status) {
|
|
54
|
+
switch (status) {
|
|
55
|
+
case 'healthy':
|
|
56
|
+
return exports.CombatMessages.HEALTH_HEALTHY;
|
|
57
|
+
case 'wounded':
|
|
58
|
+
return exports.CombatMessages.HEALTH_WOUNDED;
|
|
59
|
+
case 'badly_wounded':
|
|
60
|
+
return exports.CombatMessages.HEALTH_BADLY_WOUNDED;
|
|
61
|
+
case 'near_death':
|
|
62
|
+
return exports.CombatMessages.HEALTH_NEAR_DEATH;
|
|
63
|
+
case 'unconscious':
|
|
64
|
+
return exports.CombatMessages.HEALTH_UNCONSCIOUS;
|
|
65
|
+
case 'dead':
|
|
66
|
+
return exports.CombatMessages.HEALTH_DEAD;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=combat-messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"combat-messages.js","sourceRoot":"","sources":["../../../../../mnt/c/repotemp/sharpee/packages/extensions/basic-combat/src/combat-messages.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAkEH,4DAeC;AA/ED;;GAEG;AACU,QAAA,cAAc,GAAG;IAC5B,kBAAkB;IAClB,aAAa,EAAE,sBAAsB;IACrC,UAAU,EAAE,mBAAmB;IAC/B,gBAAgB,EAAE,yBAAyB;IAC3C,gBAAgB,EAAE,yBAAyB;IAC3C,kBAAkB,EAAE,2BAA2B;IAC/C,aAAa,EAAE,sBAAsB;IAErC,mBAAmB;IACnB,cAAc,EAAE,uBAAuB;IACvC,cAAc,EAAE,uBAAuB;IACvC,aAAa,EAAE,sBAAsB;IAErC,6BAA6B;IAC7B,cAAc,EAAE,uBAAuB;IACvC,cAAc,EAAE,uBAAuB;IACvC,oBAAoB,EAAE,6BAA6B;IACnD,iBAAiB,EAAE,0BAA0B;IAC7C,kBAAkB,EAAE,2BAA2B;IAC/C,WAAW,EAAE,oBAAoB;IAEjC,0BAA0B;IAC1B,WAAW,EAAE,4BAA4B;IACzC,mBAAmB,EAAE,oCAAoC;IACzD,qBAAqB,EAAE,+BAA+B;IAEtD,4BAA4B;IAC5B,aAAa,EAAE,sBAAsB;IACrC,YAAY,EAAE,qBAAqB;IACnC,WAAW,EAAE,oBAAoB;IACjC,SAAS,EAAE,kBAAkB;IAC7B,kBAAkB,EAAE,2BAA2B;IAC/C,WAAW,EAAE,oBAAoB;IAEjC,wBAAwB;IACxB,cAAc,EAAE,gBAAgB;IAChC,YAAY,EAAE,cAAc;IAC5B,WAAW,EAAE,oBAAoB;IACjC,kBAAkB,EAAE,2BAA2B;CACvC,CAAC;AAkBX;;GAEG;AACH,SAAgB,wBAAwB,CAAC,MAAoB;IAC3D,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,SAAS;YACZ,OAAO,sBAAc,CAAC,cAAc,CAAC;QACvC,KAAK,SAAS;YACZ,OAAO,sBAAc,CAAC,cAAc,CAAC;QACvC,KAAK,eAAe;YAClB,OAAO,sBAAc,CAAC,oBAAoB,CAAC;QAC7C,KAAK,YAAY;YACf,OAAO,sBAAc,CAAC,iBAAiB,CAAC;QAC1C,KAAK,aAAa;YAChB,OAAO,sBAAc,CAAC,kBAAkB,CAAC;QAC3C,KAAK,MAAM;YACT,OAAO,sBAAc,CAAC,WAAW,CAAC;IACtC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Combat Service (ADR-072)
|
|
3
|
+
*
|
|
4
|
+
* Handles combat resolution using a skill-based probability system.
|
|
5
|
+
* Moved from stdlib to basic-combat extension — stories opt in by
|
|
6
|
+
* calling registerBasicCombat().
|
|
7
|
+
*/
|
|
8
|
+
import { EntityId, SeededRandom } from "./src/index";
|
|
9
|
+
import { IFEntity, WorldModel } from "./src/index";
|
|
10
|
+
import { HealthStatus } from './combat-messages.js';
|
|
11
|
+
/**
|
|
12
|
+
* Context for combat resolution
|
|
13
|
+
*/
|
|
14
|
+
export interface CombatContext {
|
|
15
|
+
/** The attacker entity */
|
|
16
|
+
attacker: IFEntity;
|
|
17
|
+
/** The target entity */
|
|
18
|
+
target: IFEntity;
|
|
19
|
+
/** Weapon being used (if any) */
|
|
20
|
+
weapon?: IFEntity;
|
|
21
|
+
/** The world model */
|
|
22
|
+
world: WorldModel;
|
|
23
|
+
/** Seeded random number generator */
|
|
24
|
+
random: SeededRandom;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Result of combat resolution
|
|
28
|
+
*/
|
|
29
|
+
export interface CombatResult {
|
|
30
|
+
/** Whether the attack hit */
|
|
31
|
+
hit: boolean;
|
|
32
|
+
/** Damage dealt (0 if missed) */
|
|
33
|
+
damage: number;
|
|
34
|
+
/** Target's new health after damage */
|
|
35
|
+
targetNewHealth: number;
|
|
36
|
+
/** Whether target was knocked out (unconscious) */
|
|
37
|
+
targetKnockedOut: boolean;
|
|
38
|
+
/** Whether target was killed */
|
|
39
|
+
targetKilled: boolean;
|
|
40
|
+
/** Message ID for the result */
|
|
41
|
+
messageId: string;
|
|
42
|
+
/** Data for the message */
|
|
43
|
+
messageData: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Validation result for combat
|
|
47
|
+
*/
|
|
48
|
+
export interface CombatValidation {
|
|
49
|
+
valid: boolean;
|
|
50
|
+
messageId?: string;
|
|
51
|
+
messageData?: Record<string, unknown>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Combat Service interface
|
|
55
|
+
*/
|
|
56
|
+
export interface ICombatService {
|
|
57
|
+
/** Resolve a single attack */
|
|
58
|
+
resolveAttack(context: CombatContext): CombatResult;
|
|
59
|
+
/** Check if attacker can attack target */
|
|
60
|
+
canAttack(attacker: IFEntity, target: IFEntity): CombatValidation;
|
|
61
|
+
/** Get descriptive health status */
|
|
62
|
+
getHealthStatus(entity: IFEntity): HealthStatus;
|
|
63
|
+
/** Calculate hit chance */
|
|
64
|
+
calculateHitChance(attackerSkill: number, defenderSkill: number, weaponBonus: number): number;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Combat Service implementation
|
|
68
|
+
*/
|
|
69
|
+
export declare class CombatService implements ICombatService {
|
|
70
|
+
/**
|
|
71
|
+
* Calculate hit chance based on skills
|
|
72
|
+
*
|
|
73
|
+
* Base chance starts at 50%.
|
|
74
|
+
* Each point of skill advantage = +1%.
|
|
75
|
+
* Clamped to 10%-95% (always some chance either way).
|
|
76
|
+
*/
|
|
77
|
+
calculateHitChance(attackerSkill: number, defenderSkill: number, weaponBonus: number): number;
|
|
78
|
+
/**
|
|
79
|
+
* Resolve an attack
|
|
80
|
+
*/
|
|
81
|
+
resolveAttack(context: CombatContext): CombatResult;
|
|
82
|
+
/**
|
|
83
|
+
* Check if an entity can attack another
|
|
84
|
+
*/
|
|
85
|
+
canAttack(attacker: IFEntity, target: IFEntity): CombatValidation;
|
|
86
|
+
/**
|
|
87
|
+
* Get health status for an entity
|
|
88
|
+
*/
|
|
89
|
+
getHealthStatus(entity: IFEntity): HealthStatus;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Create a new Combat Service instance
|
|
93
|
+
*/
|
|
94
|
+
export declare function createCombatService(): ICombatService;
|
|
95
|
+
/**
|
|
96
|
+
* Result of applying combat damage
|
|
97
|
+
*/
|
|
98
|
+
export interface ApplyCombatResultInfo {
|
|
99
|
+
/** IDs of items dropped from target's inventory */
|
|
100
|
+
droppedItems: EntityId[];
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Apply combat result to the target entity
|
|
104
|
+
* Handles health updates, consciousness changes, death, and inventory dropping
|
|
105
|
+
*/
|
|
106
|
+
export declare function applyCombatResult(target: IFEntity, result: CombatResult, world: WorldModel): ApplyCombatResultInfo;
|
|
107
|
+
//# sourceMappingURL=combat-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"combat-service.d.ts","sourceRoot":"","sources":["../../../../../mnt/c/repotemp/sharpee/packages/extensions/basic-combat/src/combat-service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EACL,QAAQ,EACR,UAAU,EAIX,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAkB,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpE;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,0BAA0B;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IAEnB,wBAAwB;IACxB,MAAM,EAAE,QAAQ,CAAC;IAEjB,iCAAiC;IACjC,MAAM,CAAC,EAAE,QAAQ,CAAC;IAElB,sBAAsB;IACtB,KAAK,EAAE,UAAU,CAAC;IAElB,qCAAqC;IACrC,MAAM,EAAE,YAAY,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,6BAA6B;IAC7B,GAAG,EAAE,OAAO,CAAC;IAEb,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;IAEf,uCAAuC;IACvC,eAAe,EAAE,MAAM,CAAC;IAExB,mDAAmD;IACnD,gBAAgB,EAAE,OAAO,CAAC;IAE1B,gCAAgC;IAChC,YAAY,EAAE,OAAO,CAAC;IAEtB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAElB,2BAA2B;IAC3B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,8BAA8B;IAC9B,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,YAAY,CAAC;IAEpD,0CAA0C;IAC1C,SAAS,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAG,gBAAgB,CAAC;IAElE,oCAAoC;IACpC,eAAe,CAAC,MAAM,EAAE,QAAQ,GAAG,YAAY,CAAC;IAEhD,2BAA2B;IAC3B,kBAAkB,CAChB,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,GAClB,MAAM,CAAC;CACX;AAED;;GAEG;AACH,qBAAa,aAAc,YAAW,cAAc;IAClD;;;;;;OAMG;IACH,kBAAkB,CAChB,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,GAClB,MAAM;IAMT;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,YAAY;IA8FnD;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAG,gBAAgB;IAuBjE;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,QAAQ,GAAG,YAAY;CA0BhD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,CAEpD;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,mDAAmD;IACnD,YAAY,EAAE,QAAQ,EAAE,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,QAAQ,EAChB,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,UAAU,GAChB,qBAAqB,CAkCvB"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Combat Service (ADR-072)
|
|
4
|
+
*
|
|
5
|
+
* Handles combat resolution using a skill-based probability system.
|
|
6
|
+
* Moved from stdlib to basic-combat extension — stories opt in by
|
|
7
|
+
* calling registerBasicCombat().
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.CombatService = void 0;
|
|
11
|
+
exports.createCombatService = createCombatService;
|
|
12
|
+
exports.applyCombatResult = applyCombatResult;
|
|
13
|
+
const world_model_1 = require("./src/index.js");
|
|
14
|
+
const combat_messages_js_1 = require("./combat-messages.js");
|
|
15
|
+
/**
|
|
16
|
+
* Combat Service implementation
|
|
17
|
+
*/
|
|
18
|
+
class CombatService {
|
|
19
|
+
/**
|
|
20
|
+
* Calculate hit chance based on skills
|
|
21
|
+
*
|
|
22
|
+
* Base chance starts at 50%.
|
|
23
|
+
* Each point of skill advantage = +1%.
|
|
24
|
+
* Clamped to 10%-95% (always some chance either way).
|
|
25
|
+
*/
|
|
26
|
+
calculateHitChance(attackerSkill, defenderSkill, weaponBonus) {
|
|
27
|
+
const baseChance = 50;
|
|
28
|
+
const skillDiff = attackerSkill + weaponBonus - defenderSkill;
|
|
29
|
+
return Math.max(10, Math.min(95, baseChance + skillDiff));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Resolve an attack
|
|
33
|
+
*/
|
|
34
|
+
resolveAttack(context) {
|
|
35
|
+
const { attacker, target, weapon, random } = context;
|
|
36
|
+
// Get combatant traits
|
|
37
|
+
const attackerCombat = attacker.get(world_model_1.TraitType.COMBATANT);
|
|
38
|
+
const targetCombat = target.get(world_model_1.TraitType.COMBATANT);
|
|
39
|
+
const weaponTrait = weapon?.get(world_model_1.TraitType.WEAPON);
|
|
40
|
+
// Get skill values
|
|
41
|
+
const attackerSkill = attackerCombat?.skill ?? 30;
|
|
42
|
+
const defenderSkill = targetCombat?.skill ?? 30;
|
|
43
|
+
const weaponBonus = weaponTrait?.skillBonus ?? 0;
|
|
44
|
+
// Calculate hit chance
|
|
45
|
+
const hitChance = this.calculateHitChance(attackerSkill, defenderSkill, weaponBonus);
|
|
46
|
+
// Roll to hit
|
|
47
|
+
const roll = random.int(1, 100);
|
|
48
|
+
const hit = roll <= hitChance;
|
|
49
|
+
// Base message data
|
|
50
|
+
const messageData = {
|
|
51
|
+
attackerName: attacker.name,
|
|
52
|
+
targetName: target.name,
|
|
53
|
+
weaponName: weapon?.name,
|
|
54
|
+
};
|
|
55
|
+
if (!hit) {
|
|
56
|
+
return {
|
|
57
|
+
hit: false,
|
|
58
|
+
damage: 0,
|
|
59
|
+
targetNewHealth: targetCombat?.health ?? 0,
|
|
60
|
+
targetKnockedOut: false,
|
|
61
|
+
targetKilled: false,
|
|
62
|
+
messageId: combat_messages_js_1.CombatMessages.ATTACK_MISSED,
|
|
63
|
+
messageData,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// Calculate damage
|
|
67
|
+
const baseDamage = attackerCombat?.baseDamage ?? 1;
|
|
68
|
+
const weaponDamage = weaponTrait?.damage ?? 0;
|
|
69
|
+
let totalDamage = baseDamage + weaponDamage;
|
|
70
|
+
// Blessed weapon bonus against undead (if applicable)
|
|
71
|
+
if (weaponTrait?.isBlessed) {
|
|
72
|
+
// Check if target is undead (story would define this trait)
|
|
73
|
+
const targetIdentity = target.get(world_model_1.TraitType.IDENTITY);
|
|
74
|
+
if (targetIdentity?.isUndead) {
|
|
75
|
+
totalDamage = Math.floor(totalDamage * 1.5);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Apply armor reduction
|
|
79
|
+
const armor = targetCombat?.armor ?? 0;
|
|
80
|
+
const effectiveDamage = Math.max(1, totalDamage - armor); // Always do at least 1 damage
|
|
81
|
+
// Calculate new health
|
|
82
|
+
const currentHealth = targetCombat?.health ?? 10;
|
|
83
|
+
const newHealth = Math.max(0, currentHealth - effectiveDamage);
|
|
84
|
+
// Determine outcome
|
|
85
|
+
const killed = newHealth <= 0;
|
|
86
|
+
const maxHealth = targetCombat?.maxHealth ?? 10;
|
|
87
|
+
const knockedOut = !killed && newHealth <= maxHealth * 0.2;
|
|
88
|
+
// Add damage to message data
|
|
89
|
+
messageData.damage = effectiveDamage;
|
|
90
|
+
// Determine message based on outcome
|
|
91
|
+
let messageId;
|
|
92
|
+
if (killed) {
|
|
93
|
+
messageId = combat_messages_js_1.CombatMessages.ATTACK_KILLED;
|
|
94
|
+
}
|
|
95
|
+
else if (knockedOut) {
|
|
96
|
+
messageId = combat_messages_js_1.CombatMessages.ATTACK_KNOCKED_OUT;
|
|
97
|
+
}
|
|
98
|
+
else if (effectiveDamage >= maxHealth * 0.3) {
|
|
99
|
+
messageId = combat_messages_js_1.CombatMessages.ATTACK_HIT_HEAVY;
|
|
100
|
+
}
|
|
101
|
+
else if (effectiveDamage <= maxHealth * 0.1) {
|
|
102
|
+
messageId = combat_messages_js_1.CombatMessages.ATTACK_HIT_LIGHT;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
messageId = combat_messages_js_1.CombatMessages.ATTACK_HIT;
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
hit: true,
|
|
109
|
+
damage: effectiveDamage,
|
|
110
|
+
targetNewHealth: newHealth,
|
|
111
|
+
targetKnockedOut: knockedOut,
|
|
112
|
+
targetKilled: killed,
|
|
113
|
+
messageId,
|
|
114
|
+
messageData,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Check if an entity can attack another
|
|
119
|
+
*/
|
|
120
|
+
canAttack(attacker, target) {
|
|
121
|
+
// Check if target has combatant trait
|
|
122
|
+
const targetCombat = target.get(world_model_1.TraitType.COMBATANT);
|
|
123
|
+
if (!targetCombat) {
|
|
124
|
+
return {
|
|
125
|
+
valid: false,
|
|
126
|
+
messageId: combat_messages_js_1.CombatMessages.CANNOT_ATTACK,
|
|
127
|
+
messageData: { targetName: target.name },
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// Check if target is alive
|
|
131
|
+
if (!targetCombat.isAlive) {
|
|
132
|
+
return {
|
|
133
|
+
valid: false,
|
|
134
|
+
messageId: combat_messages_js_1.CombatMessages.ALREADY_DEAD,
|
|
135
|
+
messageData: { targetName: target.name },
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
return { valid: true };
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Get health status for an entity
|
|
142
|
+
*/
|
|
143
|
+
getHealthStatus(entity) {
|
|
144
|
+
const combatant = entity.get(world_model_1.TraitType.COMBATANT);
|
|
145
|
+
if (!combatant) {
|
|
146
|
+
return 'healthy'; // Non-combatants are "healthy"
|
|
147
|
+
}
|
|
148
|
+
if (!combatant.isAlive) {
|
|
149
|
+
return 'dead';
|
|
150
|
+
}
|
|
151
|
+
if (!combatant.isConscious) {
|
|
152
|
+
return 'unconscious';
|
|
153
|
+
}
|
|
154
|
+
const healthPercent = combatant.health / combatant.maxHealth;
|
|
155
|
+
if (healthPercent <= 0.1) {
|
|
156
|
+
return 'near_death';
|
|
157
|
+
}
|
|
158
|
+
else if (healthPercent <= 0.3) {
|
|
159
|
+
return 'badly_wounded';
|
|
160
|
+
}
|
|
161
|
+
else if (healthPercent <= 0.7) {
|
|
162
|
+
return 'wounded';
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
return 'healthy';
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
exports.CombatService = CombatService;
|
|
170
|
+
/**
|
|
171
|
+
* Create a new Combat Service instance
|
|
172
|
+
*/
|
|
173
|
+
function createCombatService() {
|
|
174
|
+
return new CombatService();
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Apply combat result to the target entity
|
|
178
|
+
* Handles health updates, consciousness changes, death, and inventory dropping
|
|
179
|
+
*/
|
|
180
|
+
function applyCombatResult(target, result, world) {
|
|
181
|
+
const info = { droppedItems: [] };
|
|
182
|
+
if (!result.hit)
|
|
183
|
+
return info;
|
|
184
|
+
const combatant = target.get(world_model_1.TraitType.COMBATANT);
|
|
185
|
+
if (!combatant)
|
|
186
|
+
return info;
|
|
187
|
+
// Update health
|
|
188
|
+
combatant.health = result.targetNewHealth;
|
|
189
|
+
// Update consciousness
|
|
190
|
+
if (result.targetKnockedOut) {
|
|
191
|
+
combatant.knockOut();
|
|
192
|
+
}
|
|
193
|
+
// Update alive status and handle death
|
|
194
|
+
if (result.targetKilled) {
|
|
195
|
+
combatant.kill();
|
|
196
|
+
// Drop inventory if configured
|
|
197
|
+
if (combatant.dropsInventory) {
|
|
198
|
+
const location = world.getLocation(target.id);
|
|
199
|
+
if (location) {
|
|
200
|
+
const inventory = world.getContents(target.id);
|
|
201
|
+
for (const item of inventory) {
|
|
202
|
+
world.moveEntity(item.id, location);
|
|
203
|
+
info.droppedItems.push(item.id);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return info;
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=combat-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"combat-service.js","sourceRoot":"","sources":["../../../../../mnt/c/repotemp/sharpee/packages/extensions/basic-combat/src/combat-service.ts"],"names":[],"mappings":"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"}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sharpee/ext-basic-combat
|
|
3
|
+
*
|
|
4
|
+
* Generic skill-based combat extension for Sharpee IF engine.
|
|
5
|
+
*
|
|
6
|
+
* Provides opt-in combat resolution for both attack directions:
|
|
7
|
+
* - PC→NPC: BasicCombatInterceptor (registered on CombatantTrait + if.action.attacking)
|
|
8
|
+
* - NPC→PC: basicNpcResolver (registered as NpcCombatResolver)
|
|
9
|
+
*
|
|
10
|
+
* Stories with custom combat (e.g., Dungeo's melee system) register their
|
|
11
|
+
* own interceptor and resolver instead of calling registerBasicCombat().
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { registerBasicCombat } from "./src/index";
|
|
16
|
+
*
|
|
17
|
+
* // In story's initializeWorld():
|
|
18
|
+
* registerBasicCombat();
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Register the basic combat system for both attack directions.
|
|
23
|
+
*
|
|
24
|
+
* Call this in your story's initializeWorld() to enable generic
|
|
25
|
+
* skill-based combat. Do NOT call this if your story registers
|
|
26
|
+
* its own combat interceptor/resolver.
|
|
27
|
+
*
|
|
28
|
+
* Registers:
|
|
29
|
+
* 1. BasicCombatInterceptor on CombatantTrait + if.action.attacking (PC→NPC)
|
|
30
|
+
* 2. basicNpcResolver as the NPC combat resolver (NPC→PC)
|
|
31
|
+
*/
|
|
32
|
+
export declare function registerBasicCombat(): void;
|
|
33
|
+
export { CombatService, createCombatService, applyCombatResult, type ICombatService, type CombatContext, type CombatResult, type CombatValidation, type ApplyCombatResultInfo, } from './combat-service.js';
|
|
34
|
+
export { CombatMessages, getHealthStatusMessageId, type CombatMessageId, type HealthStatus, } from './combat-messages.js';
|
|
35
|
+
export { BasicCombatInterceptor } from './basic-combat-interceptor.js';
|
|
36
|
+
export { basicNpcResolver } from './basic-npc-resolver.js';
|
|
37
|
+
//# sourceMappingURL=index.d.ts.map
|
package/index.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../mnt/c/repotemp/sharpee/packages/extensions/basic-combat/src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAUH;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAO1C;AAGD,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,KAAK,eAAe,EACpB,KAAK,YAAY,GAClB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
|
package/index.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @sharpee/ext-basic-combat
|
|
4
|
+
*
|
|
5
|
+
* Generic skill-based combat extension for Sharpee IF engine.
|
|
6
|
+
*
|
|
7
|
+
* Provides opt-in combat resolution for both attack directions:
|
|
8
|
+
* - PC→NPC: BasicCombatInterceptor (registered on CombatantTrait + if.action.attacking)
|
|
9
|
+
* - NPC→PC: basicNpcResolver (registered as NpcCombatResolver)
|
|
10
|
+
*
|
|
11
|
+
* Stories with custom combat (e.g., Dungeo's melee system) register their
|
|
12
|
+
* own interceptor and resolver instead of calling registerBasicCombat().
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { registerBasicCombat } from "./src/index.js";
|
|
17
|
+
*
|
|
18
|
+
* // In story's initializeWorld():
|
|
19
|
+
* registerBasicCombat();
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.basicNpcResolver = exports.BasicCombatInterceptor = exports.getHealthStatusMessageId = exports.CombatMessages = exports.applyCombatResult = exports.createCombatService = exports.CombatService = void 0;
|
|
24
|
+
exports.registerBasicCombat = registerBasicCombat;
|
|
25
|
+
const world_model_1 = require("./src/index.js");
|
|
26
|
+
const stdlib_1 = require("./src/index.js");
|
|
27
|
+
const basic_combat_interceptor_js_1 = require("./basic-combat-interceptor.js");
|
|
28
|
+
const basic_npc_resolver_js_1 = require("./basic-npc-resolver.js");
|
|
29
|
+
/**
|
|
30
|
+
* Register the basic combat system for both attack directions.
|
|
31
|
+
*
|
|
32
|
+
* Call this in your story's initializeWorld() to enable generic
|
|
33
|
+
* skill-based combat. Do NOT call this if your story registers
|
|
34
|
+
* its own combat interceptor/resolver.
|
|
35
|
+
*
|
|
36
|
+
* Registers:
|
|
37
|
+
* 1. BasicCombatInterceptor on CombatantTrait + if.action.attacking (PC→NPC)
|
|
38
|
+
* 2. basicNpcResolver as the NPC combat resolver (NPC→PC)
|
|
39
|
+
*/
|
|
40
|
+
function registerBasicCombat() {
|
|
41
|
+
(0, world_model_1.registerActionInterceptor)(world_model_1.TraitType.COMBATANT, 'if.action.attacking', basic_combat_interceptor_js_1.BasicCombatInterceptor);
|
|
42
|
+
(0, stdlib_1.registerNpcCombatResolver)(basic_npc_resolver_js_1.basicNpcResolver);
|
|
43
|
+
}
|
|
44
|
+
// Combat service and types
|
|
45
|
+
var combat_service_js_1 = require("./combat-service.js");
|
|
46
|
+
Object.defineProperty(exports, "CombatService", { enumerable: true, get: function () { return combat_service_js_1.CombatService; } });
|
|
47
|
+
Object.defineProperty(exports, "createCombatService", { enumerable: true, get: function () { return combat_service_js_1.createCombatService; } });
|
|
48
|
+
Object.defineProperty(exports, "applyCombatResult", { enumerable: true, get: function () { return combat_service_js_1.applyCombatResult; } });
|
|
49
|
+
// Combat messages
|
|
50
|
+
var combat_messages_js_1 = require("./combat-messages.js");
|
|
51
|
+
Object.defineProperty(exports, "CombatMessages", { enumerable: true, get: function () { return combat_messages_js_1.CombatMessages; } });
|
|
52
|
+
Object.defineProperty(exports, "getHealthStatusMessageId", { enumerable: true, get: function () { return combat_messages_js_1.getHealthStatusMessageId; } });
|
|
53
|
+
// Individual components (for stories that want to register only one direction)
|
|
54
|
+
var basic_combat_interceptor_js_2 = require("./basic-combat-interceptor.js");
|
|
55
|
+
Object.defineProperty(exports, "BasicCombatInterceptor", { enumerable: true, get: function () { return basic_combat_interceptor_js_2.BasicCombatInterceptor; } });
|
|
56
|
+
var basic_npc_resolver_js_2 = require("./basic-npc-resolver.js");
|
|
57
|
+
Object.defineProperty(exports, "basicNpcResolver", { enumerable: true, get: function () { return basic_npc_resolver_js_2.basicNpcResolver; } });
|
|
58
|
+
//# sourceMappingURL=index.js.map
|
package/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../mnt/c/repotemp/sharpee/packages/extensions/basic-combat/src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;AAqBH,kDAOC;AA1BD,sDAG8B;AAC9B,4CAA4D;AAC5D,+EAAuE;AACvE,mEAA2D;AAE3D;;;;;;;;;;GAUG;AACH,SAAgB,mBAAmB;IACjC,IAAA,uCAAyB,EACvB,uBAAS,CAAC,SAAS,EACnB,qBAAqB,EACrB,oDAAsB,CACvB,CAAC;IACF,IAAA,kCAAyB,EAAC,wCAAgB,CAAC,CAAC;AAC9C,CAAC;AAED,2BAA2B;AAC3B,yDAS6B;AAR3B,kHAAA,aAAa,OAAA;AACb,wHAAA,mBAAmB,OAAA;AACnB,sHAAA,iBAAiB,OAAA;AAQnB,kBAAkB;AAClB,2DAK8B;AAJ5B,oHAAA,cAAc,OAAA;AACd,8HAAA,wBAAwB,OAAA;AAK1B,+EAA+E;AAC/E,6EAAuE;AAA9D,qIAAA,sBAAsB,OAAA;AAC/B,iEAA2D;AAAlD,yHAAA,gBAAgB,OAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sharpee/ext-basic-combat",
|
|
3
|
+
"version": "0.9.86",
|
|
4
|
+
"description": "Generic skill-based combat extension for Sharpee IF engine",
|
|
5
|
+
"main": "./index.js",
|
|
6
|
+
"types": "./index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./index.d.ts",
|
|
10
|
+
"require": "./index.js",
|
|
11
|
+
"default": "./index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"sharpee",
|
|
19
|
+
"interactive-fiction",
|
|
20
|
+
"combat"
|
|
21
|
+
],
|
|
22
|
+
"license": "MIT"
|
|
23
|
+
}
|