foundryvtt-mcp 0.11.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/LICENSE +21 -0
- package/README.md +142 -0
- package/dist/character/manager.d.ts +92 -0
- package/dist/character/manager.d.ts.map +1 -0
- package/dist/character/manager.js +208 -0
- package/dist/character/manager.js.map +1 -0
- package/dist/combat/manager.d.ts +94 -0
- package/dist/combat/manager.d.ts.map +1 -0
- package/dist/combat/manager.js +373 -0
- package/dist/combat/manager.js.map +1 -0
- package/dist/config/index.d.ts +114 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +177 -0
- package/dist/config/index.js.map +1 -0
- package/dist/diagnostics/client.d.ts +193 -0
- package/dist/diagnostics/client.d.ts.map +1 -0
- package/dist/diagnostics/client.js +314 -0
- package/dist/diagnostics/client.js.map +1 -0
- package/dist/diagnostics/types.d.ts +414 -0
- package/dist/diagnostics/types.d.ts.map +1 -0
- package/dist/diagnostics/types.js +94 -0
- package/dist/diagnostics/types.js.map +1 -0
- package/dist/foundry/auth.d.ts +19 -0
- package/dist/foundry/auth.d.ts.map +1 -0
- package/dist/foundry/auth.js +135 -0
- package/dist/foundry/auth.js.map +1 -0
- package/dist/foundry/client.d.ts +95 -0
- package/dist/foundry/client.d.ts.map +1 -0
- package/dist/foundry/client.js +692 -0
- package/dist/foundry/client.js.map +1 -0
- package/dist/foundry/types.d.ts +805 -0
- package/dist/foundry/types.d.ts.map +1 -0
- package/dist/foundry/types.js +13 -0
- package/dist/foundry/types.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +199 -0
- package/dist/index.js.map +1 -0
- package/dist/resources/index.d.ts +3 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +93 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/tools/base.d.ts +80 -0
- package/dist/tools/base.d.ts.map +1 -0
- package/dist/tools/base.js +73 -0
- package/dist/tools/base.js.map +1 -0
- package/dist/tools/definitions.d.ts +414 -0
- package/dist/tools/definitions.d.ts.map +1 -0
- package/dist/tools/definitions.js +429 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/handlers/actors.d.ts +31 -0
- package/dist/tools/handlers/actors.d.ts.map +1 -0
- package/dist/tools/handlers/actors.js +76 -0
- package/dist/tools/handlers/actors.js.map +1 -0
- package/dist/tools/handlers/chat.d.ts +13 -0
- package/dist/tools/handlers/chat.d.ts.map +1 -0
- package/dist/tools/handlers/chat.js +38 -0
- package/dist/tools/handlers/chat.js.map +1 -0
- package/dist/tools/handlers/combat.d.ts +11 -0
- package/dist/tools/handlers/combat.d.ts.map +1 -0
- package/dist/tools/handlers/combat.js +48 -0
- package/dist/tools/handlers/combat.js.map +1 -0
- package/dist/tools/handlers/diagnostics.d.ts +64 -0
- package/dist/tools/handlers/diagnostics.d.ts.map +1 -0
- package/dist/tools/handlers/diagnostics.js +182 -0
- package/dist/tools/handlers/diagnostics.js.map +1 -0
- package/dist/tools/handlers/dice.d.ts +39 -0
- package/dist/tools/handlers/dice.d.ts.map +1 -0
- package/dist/tools/handlers/dice.js +53 -0
- package/dist/tools/handlers/dice.js.map +1 -0
- package/dist/tools/handlers/generation.d.ts +44 -0
- package/dist/tools/handlers/generation.d.ts.map +1 -0
- package/dist/tools/handlers/generation.js +205 -0
- package/dist/tools/handlers/generation.js.map +1 -0
- package/dist/tools/handlers/items.d.ts +21 -0
- package/dist/tools/handlers/items.d.ts.map +1 -0
- package/dist/tools/handlers/items.js +50 -0
- package/dist/tools/handlers/items.js.map +1 -0
- package/dist/tools/handlers/journals.d.ts +22 -0
- package/dist/tools/handlers/journals.d.ts.map +1 -0
- package/dist/tools/handlers/journals.js +62 -0
- package/dist/tools/handlers/journals.js.map +1 -0
- package/dist/tools/handlers/resources.d.ts +13 -0
- package/dist/tools/handlers/resources.d.ts.map +1 -0
- package/dist/tools/handlers/resources.js +188 -0
- package/dist/tools/handlers/resources.js.map +1 -0
- package/dist/tools/handlers/scenes.d.ts +18 -0
- package/dist/tools/handlers/scenes.d.ts.map +1 -0
- package/dist/tools/handlers/scenes.js +34 -0
- package/dist/tools/handlers/scenes.js.map +1 -0
- package/dist/tools/handlers/users.d.ts +11 -0
- package/dist/tools/handlers/users.d.ts.map +1 -0
- package/dist/tools/handlers/users.js +34 -0
- package/dist/tools/handlers/users.js.map +1 -0
- package/dist/tools/handlers/utils.d.ts +11 -0
- package/dist/tools/handlers/utils.d.ts.map +1 -0
- package/dist/tools/handlers/utils.js +24 -0
- package/dist/tools/handlers/utils.js.map +1 -0
- package/dist/tools/handlers/world.d.ts +26 -0
- package/dist/tools/handlers/world.d.ts.map +1 -0
- package/dist/tools/handlers/world.js +92 -0
- package/dist/tools/handlers/world.js.map +1 -0
- package/dist/tools/index.d.ts +19 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +22 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/new-router.d.ts +29 -0
- package/dist/tools/new-router.d.ts.map +1 -0
- package/dist/tools/new-router.js +97 -0
- package/dist/tools/new-router.js.map +1 -0
- package/dist/tools/registry.d.ts +51 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +79 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/resources.d.ts +16 -0
- package/dist/tools/resources.d.ts.map +1 -0
- package/dist/tools/resources.js +63 -0
- package/dist/tools/resources.js.map +1 -0
- package/dist/tools/router.d.ts +22 -0
- package/dist/tools/router.d.ts.map +1 -0
- package/dist/tools/router.js +128 -0
- package/dist/tools/router.js.map +1 -0
- package/dist/utils/cache-instance.d.ts +25 -0
- package/dist/utils/cache-instance.d.ts.map +1 -0
- package/dist/utils/cache-instance.js +30 -0
- package/dist/utils/cache-instance.js.map +1 -0
- package/dist/utils/cache.d.ts +80 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +205 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/diagnostics.d.ts +114 -0
- package/dist/utils/diagnostics.d.ts.map +1 -0
- package/dist/utils/diagnostics.js +330 -0
- package/dist/utils/diagnostics.js.map +1 -0
- package/dist/utils/logger.d.ts +137 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +158 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +98 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Lauri Gates
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# FoundryVTT MCP Server
|
|
2
|
+
|
|
3
|
+
A Model Context Protocol (MCP) server that integrates with FoundryVTT, allowing AI assistants to interact with your tabletop gaming sessions through natural language.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Dice Rolling** — standard RPG notation with any formula
|
|
8
|
+
- **Data Querying** — search and inspect actors, items, scenes, journals
|
|
9
|
+
- **Game State** — combat tracking, chat messages, user presence
|
|
10
|
+
- **Content Generation** — NPCs, loot tables, rule lookups
|
|
11
|
+
- **World Search** — full-text search across all game entities
|
|
12
|
+
- **Live Connection** — Socket.IO loads complete world state on connect
|
|
13
|
+
- **MCP Resources** — `foundry://` URIs for direct data access
|
|
14
|
+
- **Diagnostics** — optional server health monitoring (requires REST API module)
|
|
15
|
+
|
|
16
|
+
## Quick Start
|
|
17
|
+
|
|
18
|
+
### Prerequisites
|
|
19
|
+
|
|
20
|
+
- Node.js 18+
|
|
21
|
+
- FoundryVTT server running with an active world
|
|
22
|
+
- MCP-compatible AI client (Claude Desktop, etc.)
|
|
23
|
+
|
|
24
|
+
### Setup
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
git clone <repository-url>
|
|
28
|
+
cd foundryvtt-mcp
|
|
29
|
+
npm install
|
|
30
|
+
npm run setup-wizard
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The setup wizard will detect your FoundryVTT server, test connectivity, and generate your `.env` configuration.
|
|
34
|
+
|
|
35
|
+
To configure manually, see the [Configuration Guide](docs/guides/configuration.md).
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
Ask your AI assistant things like:
|
|
40
|
+
|
|
41
|
+
- "Roll 1d20+5 for an attack roll"
|
|
42
|
+
- "Show me all the NPCs in this scene"
|
|
43
|
+
- "What's the current combat initiative order?"
|
|
44
|
+
- "Search the world for anything related to dragons"
|
|
45
|
+
- "Generate a random NPC merchant"
|
|
46
|
+
|
|
47
|
+
## Available Tools
|
|
48
|
+
|
|
49
|
+
### Data Access
|
|
50
|
+
|
|
51
|
+
- `search_actors` — find characters, NPCs, monsters
|
|
52
|
+
- `get_actor_details` — detailed character information
|
|
53
|
+
- `search_items` — find equipment, spells, consumables
|
|
54
|
+
- `get_scene_info` — current scene details
|
|
55
|
+
- `search_journals` — search notes and handouts
|
|
56
|
+
- `get_journal` — retrieve a specific journal entry
|
|
57
|
+
- `get_users` — list online users and their status
|
|
58
|
+
- `get_combat_state` — combat state and initiative order
|
|
59
|
+
- `get_chat_messages` — recent chat history
|
|
60
|
+
|
|
61
|
+
### World
|
|
62
|
+
|
|
63
|
+
- `search_world` — full-text search across all game entities
|
|
64
|
+
- `get_world_summary` — overview of the current world state
|
|
65
|
+
- `refresh_world_data` — reload world data from FoundryVTT
|
|
66
|
+
|
|
67
|
+
### Game Mechanics
|
|
68
|
+
|
|
69
|
+
- `roll_dice` — roll dice with any formula
|
|
70
|
+
- `lookup_rule` — game rules and spell descriptions
|
|
71
|
+
|
|
72
|
+
### Content Generation
|
|
73
|
+
|
|
74
|
+
- `generate_npc` — create random NPCs
|
|
75
|
+
- `generate_loot` — create treasure appropriate for level
|
|
76
|
+
|
|
77
|
+
### Diagnostics (requires REST API module)
|
|
78
|
+
|
|
79
|
+
- `get_recent_logs` — retrieve filtered FoundryVTT logs
|
|
80
|
+
- `search_logs` — search logs with regex patterns
|
|
81
|
+
- `get_system_health` — server performance and health metrics
|
|
82
|
+
- `diagnose_errors` — analyze errors with troubleshooting suggestions
|
|
83
|
+
- `get_health_status` — comprehensive health diagnostics
|
|
84
|
+
|
|
85
|
+
## Available Resources
|
|
86
|
+
|
|
87
|
+
- `foundry://actors` — all actors in the world
|
|
88
|
+
- `foundry://items` — all items in the world
|
|
89
|
+
- `foundry://scenes` — all scenes
|
|
90
|
+
- `foundry://scenes/current` — current active scene
|
|
91
|
+
- `foundry://journals` — all journal entries
|
|
92
|
+
- `foundry://users` — online users
|
|
93
|
+
- `foundry://combat` — active combat state
|
|
94
|
+
- `foundry://world/settings` — world and campaign settings
|
|
95
|
+
- `foundry://system/diagnostics` — system diagnostics (requires REST API module)
|
|
96
|
+
|
|
97
|
+
## Configuration
|
|
98
|
+
|
|
99
|
+
Copy `.env.example`, set `FOUNDRY_URL`, `FOUNDRY_USERNAME`, and `FOUNDRY_PASSWORD`, then run `npm run build && npm start`.
|
|
100
|
+
|
|
101
|
+
Full environment variable reference: [Configuration Guide](docs/guides/configuration.md)
|
|
102
|
+
|
|
103
|
+
## Troubleshooting
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
npm run test-connection # Test FoundryVTT connectivity
|
|
107
|
+
npm run setup-wizard # Re-run interactive setup
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Detailed guide: [TROUBLESHOOTING.md](TROUBLESHOOTING.md)
|
|
111
|
+
|
|
112
|
+
## Development
|
|
113
|
+
|
|
114
|
+
See [Development Guide](docs/guides/development.md) for project structure, adding tools, testing, and building.
|
|
115
|
+
|
|
116
|
+
## Roadmap
|
|
117
|
+
|
|
118
|
+
See [Feature Tracker](docs/blueprint/feature-tracker.md) for completed and planned features.
|
|
119
|
+
|
|
120
|
+
## Contributing
|
|
121
|
+
|
|
122
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
123
|
+
|
|
124
|
+
## Integration
|
|
125
|
+
|
|
126
|
+
See [Integration Guide](docs/guides/integration.md) for Claude Desktop config and custom MCP client examples.
|
|
127
|
+
|
|
128
|
+
## License
|
|
129
|
+
|
|
130
|
+
MIT License — see [LICENSE](LICENSE) for details.
|
|
131
|
+
|
|
132
|
+
## Support
|
|
133
|
+
|
|
134
|
+
- **Issues**: [GitHub Issues](https://github.com/laurigates/foundryvtt-mcp/issues)
|
|
135
|
+
- **Discord**: [FoundryVTT Discord](https://discord.gg/foundryvtt) #api-development
|
|
136
|
+
- **Docs**: [FoundryVTT API](https://foundryvtt.com/api/)
|
|
137
|
+
|
|
138
|
+
## Acknowledgments
|
|
139
|
+
|
|
140
|
+
- FoundryVTT team for the excellent VTT platform
|
|
141
|
+
- Anthropic for the Model Context Protocol
|
|
142
|
+
- The tabletop gaming community for inspiration and feedback
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import type { FoundryClient } from '../foundry/client.js';
|
|
3
|
+
export interface CharacterAdvancement {
|
|
4
|
+
actorId: string;
|
|
5
|
+
fromLevel: number;
|
|
6
|
+
toLevel: number;
|
|
7
|
+
hitPointsGained: number;
|
|
8
|
+
abilityScoreImprovements: Array<{
|
|
9
|
+
ability: string;
|
|
10
|
+
increase: number;
|
|
11
|
+
}>;
|
|
12
|
+
newSpellsLearned: string[];
|
|
13
|
+
newFeatures: string[];
|
|
14
|
+
skillProficiencies: string[];
|
|
15
|
+
timestamp: Date;
|
|
16
|
+
}
|
|
17
|
+
export interface EquipmentTransaction {
|
|
18
|
+
actorId: string;
|
|
19
|
+
action: 'add' | 'remove' | 'equip' | 'unequip' | 'transfer';
|
|
20
|
+
itemId: string;
|
|
21
|
+
itemName: string;
|
|
22
|
+
quantity?: number;
|
|
23
|
+
targetActorId?: string;
|
|
24
|
+
timestamp: Date;
|
|
25
|
+
}
|
|
26
|
+
export interface ResourceManagement {
|
|
27
|
+
actorId: string;
|
|
28
|
+
resource: string;
|
|
29
|
+
maxValue: number;
|
|
30
|
+
currentValue: number;
|
|
31
|
+
resetType: 'short_rest' | 'long_rest' | 'daily' | 'manual';
|
|
32
|
+
lastReset?: Date;
|
|
33
|
+
}
|
|
34
|
+
export interface PartyComposition {
|
|
35
|
+
actors: string[];
|
|
36
|
+
averageLevel: number;
|
|
37
|
+
encounterRating: string;
|
|
38
|
+
roleBalance: {
|
|
39
|
+
tank: number;
|
|
40
|
+
healer: number;
|
|
41
|
+
damage: number;
|
|
42
|
+
support: number;
|
|
43
|
+
control: number;
|
|
44
|
+
};
|
|
45
|
+
recommendations: string[];
|
|
46
|
+
}
|
|
47
|
+
export declare class CharacterManager extends EventEmitter {
|
|
48
|
+
private foundryClient;
|
|
49
|
+
private advancementHistory;
|
|
50
|
+
private equipmentHistory;
|
|
51
|
+
private resourceTracking;
|
|
52
|
+
constructor(foundryClient: FoundryClient);
|
|
53
|
+
levelUpCharacter(actorId: string, options?: {
|
|
54
|
+
hitPointMethod?: 'roll' | 'average' | 'max';
|
|
55
|
+
abilityScoreImprovements?: Array<{
|
|
56
|
+
ability: string;
|
|
57
|
+
increase: number;
|
|
58
|
+
}>;
|
|
59
|
+
newSpells?: string[];
|
|
60
|
+
newFeatures?: string[];
|
|
61
|
+
newSkills?: string[];
|
|
62
|
+
}): Promise<CharacterAdvancement>;
|
|
63
|
+
calculateExperienceRequired(currentLevel: number, targetLevel?: number): Promise<{
|
|
64
|
+
current: number;
|
|
65
|
+
required: number;
|
|
66
|
+
remaining: number;
|
|
67
|
+
nextMilestone: number;
|
|
68
|
+
}>;
|
|
69
|
+
addItemToCharacter(actorId: string, itemData: {
|
|
70
|
+
name: string;
|
|
71
|
+
type: string;
|
|
72
|
+
quantity?: number;
|
|
73
|
+
properties?: Record<string, unknown>;
|
|
74
|
+
equipped?: boolean;
|
|
75
|
+
}): Promise<EquipmentTransaction>;
|
|
76
|
+
equipItem(actorId: string, itemId: string): Promise<EquipmentTransaction>;
|
|
77
|
+
transferItem(fromActorId: string, toActorId: string, itemId: string, quantity?: number): Promise<EquipmentTransaction>;
|
|
78
|
+
trackResource(actorId: string, resourceName: string, config: {
|
|
79
|
+
maxValue: number;
|
|
80
|
+
currentValue?: number;
|
|
81
|
+
resetType: 'short_rest' | 'long_rest' | 'daily' | 'manual';
|
|
82
|
+
}): Promise<ResourceManagement>;
|
|
83
|
+
useResource(actorId: string, resourceName: string, amount?: number): Promise<ResourceManagement | null>;
|
|
84
|
+
restoreResources(actorId: string, restType: 'short_rest' | 'long_rest'): Promise<ResourceManagement[]>;
|
|
85
|
+
private calculateHitPointGain;
|
|
86
|
+
private suggestAbilityImprovements;
|
|
87
|
+
private determineNewSpells;
|
|
88
|
+
private determineNewFeatures;
|
|
89
|
+
private determineNewSkills;
|
|
90
|
+
private generateItemId;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/character/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import { logger } from '../utils/logger.js';
|
|
3
|
+
export class CharacterManager extends EventEmitter {
|
|
4
|
+
foundryClient;
|
|
5
|
+
advancementHistory = [];
|
|
6
|
+
equipmentHistory = [];
|
|
7
|
+
resourceTracking = new Map();
|
|
8
|
+
constructor(foundryClient) {
|
|
9
|
+
super();
|
|
10
|
+
this.foundryClient = foundryClient;
|
|
11
|
+
}
|
|
12
|
+
// Character Advancement
|
|
13
|
+
async levelUpCharacter(actorId, options = {}) {
|
|
14
|
+
logger.info(`Starting level up process for actor ${actorId}`);
|
|
15
|
+
const actor = await this.foundryClient.getActor(actorId);
|
|
16
|
+
const currentLevel = actor.level || 1;
|
|
17
|
+
const newLevel = currentLevel + 1;
|
|
18
|
+
// Calculate HP gain
|
|
19
|
+
const hitPointsGained = this.calculateHitPointGain(actor, options.hitPointMethod || 'average');
|
|
20
|
+
// Process ability score improvements (every 4 levels in D&D 5e)
|
|
21
|
+
const abilityImprovements = options.abilityScoreImprovements || [];
|
|
22
|
+
if (newLevel % 4 === 0 && abilityImprovements.length === 0) {
|
|
23
|
+
// Suggest ability score improvements
|
|
24
|
+
abilityImprovements.push(...this.suggestAbilityImprovements(actor));
|
|
25
|
+
}
|
|
26
|
+
// Determine new spells and features based on class and level
|
|
27
|
+
const newSpells = options.newSpells || this.determineNewSpells(actor, newLevel);
|
|
28
|
+
const newFeatures = options.newFeatures || this.determineNewFeatures(actor, newLevel);
|
|
29
|
+
const newSkills = options.newSkills || this.determineNewSkills(actor, newLevel);
|
|
30
|
+
const advancement = {
|
|
31
|
+
actorId,
|
|
32
|
+
fromLevel: currentLevel,
|
|
33
|
+
toLevel: newLevel,
|
|
34
|
+
hitPointsGained,
|
|
35
|
+
abilityScoreImprovements: abilityImprovements,
|
|
36
|
+
newSpellsLearned: newSpells,
|
|
37
|
+
newFeatures,
|
|
38
|
+
skillProficiencies: newSkills,
|
|
39
|
+
timestamp: new Date(),
|
|
40
|
+
};
|
|
41
|
+
this.advancementHistory.push(advancement);
|
|
42
|
+
this.emit('character_level_up', advancement);
|
|
43
|
+
logger.info(`${actor.name} leveled up from ${currentLevel} to ${newLevel}`);
|
|
44
|
+
return advancement;
|
|
45
|
+
}
|
|
46
|
+
async calculateExperienceRequired(currentLevel, targetLevel) {
|
|
47
|
+
// D&D 5e experience table
|
|
48
|
+
const xpTable = [
|
|
49
|
+
0, 300, 900, 2700, 6500, 14000, 23000, 34000, 48000, 64000, 85000, 100000, 120000, 140000,
|
|
50
|
+
165000, 195000, 225000, 265000, 305000, 355000,
|
|
51
|
+
];
|
|
52
|
+
const currentXP = xpTable[Math.min(currentLevel - 1, xpTable.length - 1)] || 0;
|
|
53
|
+
const target = targetLevel || currentLevel + 1;
|
|
54
|
+
const requiredXP = xpTable[Math.min(target - 1, xpTable.length - 1)] || xpTable[xpTable.length - 1];
|
|
55
|
+
const nextLevelXP = xpTable[Math.min(currentLevel, xpTable.length - 1)] || xpTable[xpTable.length - 1];
|
|
56
|
+
return {
|
|
57
|
+
current: currentXP,
|
|
58
|
+
required: requiredXP || 0,
|
|
59
|
+
remaining: (requiredXP || 0) - currentXP,
|
|
60
|
+
nextMilestone: nextLevelXP || 0,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// Equipment Management
|
|
64
|
+
async addItemToCharacter(actorId, itemData) {
|
|
65
|
+
logger.info(`Adding ${itemData.name} to actor ${actorId}`);
|
|
66
|
+
const transaction = {
|
|
67
|
+
actorId,
|
|
68
|
+
action: 'add',
|
|
69
|
+
itemId: this.generateItemId(),
|
|
70
|
+
itemName: itemData.name,
|
|
71
|
+
quantity: itemData.quantity || 1,
|
|
72
|
+
timestamp: new Date(),
|
|
73
|
+
};
|
|
74
|
+
this.equipmentHistory.push(transaction);
|
|
75
|
+
this.emit('equipment_changed', transaction);
|
|
76
|
+
return transaction;
|
|
77
|
+
}
|
|
78
|
+
async equipItem(actorId, itemId) {
|
|
79
|
+
const transaction = {
|
|
80
|
+
actorId,
|
|
81
|
+
action: 'equip',
|
|
82
|
+
itemId,
|
|
83
|
+
itemName: 'Unknown Item', // Would be retrieved from actual item data
|
|
84
|
+
timestamp: new Date(),
|
|
85
|
+
};
|
|
86
|
+
this.equipmentHistory.push(transaction);
|
|
87
|
+
this.emit('equipment_changed', transaction);
|
|
88
|
+
logger.info(`Equipped item ${itemId} on actor ${actorId}`);
|
|
89
|
+
return transaction;
|
|
90
|
+
}
|
|
91
|
+
async transferItem(fromActorId, toActorId, itemId, quantity) {
|
|
92
|
+
const transaction = {
|
|
93
|
+
actorId: fromActorId,
|
|
94
|
+
action: 'transfer',
|
|
95
|
+
itemId,
|
|
96
|
+
itemName: 'Unknown Item',
|
|
97
|
+
quantity: quantity || 1,
|
|
98
|
+
targetActorId: toActorId,
|
|
99
|
+
timestamp: new Date(),
|
|
100
|
+
};
|
|
101
|
+
this.equipmentHistory.push(transaction);
|
|
102
|
+
this.emit('equipment_changed', transaction);
|
|
103
|
+
logger.info(`Transferred item ${itemId} from ${fromActorId} to ${toActorId}`);
|
|
104
|
+
return transaction;
|
|
105
|
+
}
|
|
106
|
+
// Resource Management
|
|
107
|
+
async trackResource(actorId, resourceName, config) {
|
|
108
|
+
const resource = {
|
|
109
|
+
actorId,
|
|
110
|
+
resource: resourceName,
|
|
111
|
+
maxValue: config.maxValue,
|
|
112
|
+
currentValue: config.currentValue ?? config.maxValue,
|
|
113
|
+
resetType: config.resetType,
|
|
114
|
+
lastReset: new Date(),
|
|
115
|
+
};
|
|
116
|
+
if (!this.resourceTracking.has(actorId)) {
|
|
117
|
+
this.resourceTracking.set(actorId, []);
|
|
118
|
+
}
|
|
119
|
+
const resources = this.resourceTracking.get(actorId);
|
|
120
|
+
if (!resources) {
|
|
121
|
+
throw new Error(`Resources not found for actor ${actorId}`);
|
|
122
|
+
}
|
|
123
|
+
const existingIndex = resources.findIndex((r) => r.resource === resourceName);
|
|
124
|
+
if (existingIndex >= 0) {
|
|
125
|
+
resources[existingIndex] = resource;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
resources.push(resource);
|
|
129
|
+
}
|
|
130
|
+
this.emit('resource_tracked', resource);
|
|
131
|
+
return resource;
|
|
132
|
+
}
|
|
133
|
+
async useResource(actorId, resourceName, amount = 1) {
|
|
134
|
+
const resources = this.resourceTracking.get(actorId);
|
|
135
|
+
if (!resources) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
const resource = resources.find((r) => r.resource === resourceName);
|
|
139
|
+
if (!resource) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
if (resource.currentValue >= amount) {
|
|
143
|
+
resource.currentValue -= amount;
|
|
144
|
+
this.emit('resource_used', { resource, amountUsed: amount });
|
|
145
|
+
logger.info(`${actorId} used ${amount} ${resourceName} (${resource.currentValue}/${resource.maxValue} remaining)`);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
logger.warn(`${actorId} attempted to use ${amount} ${resourceName} but only has ${resource.currentValue}`);
|
|
149
|
+
}
|
|
150
|
+
return resource;
|
|
151
|
+
}
|
|
152
|
+
async restoreResources(actorId, restType) {
|
|
153
|
+
const resources = this.resourceTracking.get(actorId) || [];
|
|
154
|
+
const restoredResources = [];
|
|
155
|
+
// Process resource restoration
|
|
156
|
+
for (const resource of resources) {
|
|
157
|
+
if ((restType === 'short_rest' && resource.resetType === 'short_rest') ||
|
|
158
|
+
(restType === 'long_rest' &&
|
|
159
|
+
(resource.resetType === 'long_rest' || resource.resetType === 'short_rest'))) {
|
|
160
|
+
resource.currentValue = resource.maxValue;
|
|
161
|
+
resource.lastReset = new Date();
|
|
162
|
+
restoredResources.push(resource);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (restoredResources.length > 0) {
|
|
166
|
+
this.emit('resources_restored', { actorId, restType, resources: restoredResources });
|
|
167
|
+
logger.info(`Restored ${restoredResources.length} resources for ${actorId} after ${restType} rest`);
|
|
168
|
+
}
|
|
169
|
+
return restoredResources;
|
|
170
|
+
}
|
|
171
|
+
// Helper methods for the character advancement system
|
|
172
|
+
calculateHitPointGain(_actor, method) {
|
|
173
|
+
const hitDie = 8; // Default d8, would be determined by class
|
|
174
|
+
switch (method) {
|
|
175
|
+
case 'roll':
|
|
176
|
+
return Math.floor(Math.random() * hitDie) + 1;
|
|
177
|
+
case 'average':
|
|
178
|
+
return Math.floor(hitDie / 2) + 1;
|
|
179
|
+
case 'max':
|
|
180
|
+
return hitDie;
|
|
181
|
+
default:
|
|
182
|
+
return Math.floor(hitDie / 2) + 1;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
suggestAbilityImprovements(_actor) {
|
|
186
|
+
// Simple suggestion logic - would be more sophisticated in practice
|
|
187
|
+
return [
|
|
188
|
+
{ ability: 'strength', increase: 1 },
|
|
189
|
+
{ ability: 'constitution', increase: 1 },
|
|
190
|
+
];
|
|
191
|
+
}
|
|
192
|
+
determineNewSpells(_actor, _level) {
|
|
193
|
+
// Would integrate with spell system
|
|
194
|
+
return [];
|
|
195
|
+
}
|
|
196
|
+
determineNewFeatures(_actor, _level) {
|
|
197
|
+
// Would integrate with class feature system
|
|
198
|
+
return [];
|
|
199
|
+
}
|
|
200
|
+
determineNewSkills(_actor, _level) {
|
|
201
|
+
// Would integrate with skill system
|
|
202
|
+
return [];
|
|
203
|
+
}
|
|
204
|
+
generateItemId() {
|
|
205
|
+
return `item_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/character/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import type { FoundryClient } from '../foundry/client.js';
|
|
3
|
+
export interface CombatState {
|
|
4
|
+
id: string;
|
|
5
|
+
round: number;
|
|
6
|
+
turn: number;
|
|
7
|
+
active: boolean;
|
|
8
|
+
started: boolean;
|
|
9
|
+
scene?: string;
|
|
10
|
+
combatants: CombatantState[];
|
|
11
|
+
currentCombatant?: CombatantState;
|
|
12
|
+
turnStartTime?: Date;
|
|
13
|
+
roundStartTime?: Date;
|
|
14
|
+
}
|
|
15
|
+
export interface CombatantState {
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
initiative?: number;
|
|
19
|
+
hp: {
|
|
20
|
+
current: number;
|
|
21
|
+
max: number;
|
|
22
|
+
temp?: number;
|
|
23
|
+
};
|
|
24
|
+
ac?: number;
|
|
25
|
+
conditions: string[];
|
|
26
|
+
defeated: boolean;
|
|
27
|
+
hidden: boolean;
|
|
28
|
+
actorId?: string;
|
|
29
|
+
tokenId?: string;
|
|
30
|
+
turnTaken: boolean;
|
|
31
|
+
actions: {
|
|
32
|
+
action: boolean;
|
|
33
|
+
bonus: boolean;
|
|
34
|
+
movement: number;
|
|
35
|
+
reaction: boolean;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export interface CombatEvent {
|
|
39
|
+
type: 'combat_start' | 'combat_end' | 'turn_start' | 'turn_end' | 'round_start' | 'round_end' | 'damage_dealt' | 'condition_applied' | 'initiative_changed';
|
|
40
|
+
timestamp: Date;
|
|
41
|
+
combat: CombatState;
|
|
42
|
+
data?: unknown;
|
|
43
|
+
}
|
|
44
|
+
export declare class CombatManager extends EventEmitter {
|
|
45
|
+
private readonly foundryClient;
|
|
46
|
+
private currentCombat;
|
|
47
|
+
private combatHistory;
|
|
48
|
+
private turnTimer;
|
|
49
|
+
private readonly TURN_WARNING_TIME;
|
|
50
|
+
constructor(foundryClient: FoundryClient);
|
|
51
|
+
private setupEventHandlers;
|
|
52
|
+
/**
|
|
53
|
+
* Destroy the combat manager and release resources
|
|
54
|
+
*/
|
|
55
|
+
destroy(): void;
|
|
56
|
+
getCurrentCombat(): CombatState | null;
|
|
57
|
+
getCombatHistory(limit?: number): CombatEvent[];
|
|
58
|
+
startCombat(combatants: Partial<CombatantState>[]): Promise<CombatState>;
|
|
59
|
+
rollInitiative(combatantId?: string): Promise<{
|
|
60
|
+
[key: string]: number;
|
|
61
|
+
}>;
|
|
62
|
+
nextTurn(): Promise<CombatantState | null>;
|
|
63
|
+
applyDamage(combatantId: string, damage: number, damageType?: string): Promise<CombatantState>;
|
|
64
|
+
healCombatant(combatantId: string, healing: number): Promise<CombatantState>;
|
|
65
|
+
applyCondition(combatantId: string, condition: string, duration?: number): Promise<CombatantState>;
|
|
66
|
+
removeCondition(combatantId: string, condition: string): Promise<CombatantState>;
|
|
67
|
+
endCombat(): Promise<CombatState>;
|
|
68
|
+
private handleCombatStart;
|
|
69
|
+
private handleTurnStart;
|
|
70
|
+
private handleTurnEnd;
|
|
71
|
+
private handleRoundEnd;
|
|
72
|
+
private initializeCombatants;
|
|
73
|
+
private getInitiativeModifier;
|
|
74
|
+
private generateCombatId;
|
|
75
|
+
private generateCombatantId;
|
|
76
|
+
private emitCombatEvent;
|
|
77
|
+
getCombatStatistics(): {
|
|
78
|
+
totalRounds: number;
|
|
79
|
+
totalTurns: number;
|
|
80
|
+
averageTurnTime: number;
|
|
81
|
+
combatants: Array<{
|
|
82
|
+
name: string;
|
|
83
|
+
initiative: number;
|
|
84
|
+
hp: {
|
|
85
|
+
current: number;
|
|
86
|
+
max: number;
|
|
87
|
+
};
|
|
88
|
+
status: string[];
|
|
89
|
+
}>;
|
|
90
|
+
} | null;
|
|
91
|
+
private calculateAverageTurnTime;
|
|
92
|
+
suggestTacticalActions(combatantId: string): string[];
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/combat/manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAG1D,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,gBAAgB,CAAC,EAAE,cAAc,CAAC;IAClC,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB,cAAc,CAAC,EAAE,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE;QACF,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE;QACP,MAAM,EAAE,OAAO,CAAC;QAChB,KAAK,EAAE,OAAO,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EACA,cAAc,GACd,YAAY,GACZ,YAAY,GACZ,UAAU,GACV,aAAa,GACb,WAAW,GACX,cAAc,GACd,mBAAmB,GACnB,oBAAoB,CAAC;IACzB,SAAS,EAAE,IAAI,CAAC;IAChB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,qBAAa,aAAc,SAAQ,YAAY;IAC7C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;gBAE/B,aAAa,EAAE,aAAa;IAMxC,OAAO,CAAC,kBAAkB;IAO1B;;OAEG;IACH,OAAO,IAAI,IAAI;IAYf,gBAAgB,IAAI,WAAW,GAAG,IAAI;IAItC,gBAAgB,CAAC,KAAK,GAAE,MAAW,GAAG,WAAW,EAAE;IAI7C,WAAW,CAAC,UAAU,EAAE,OAAO,CAAC,cAAc,CAAC,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAuBxE,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IA8BxE,QAAQ,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAoD1C,WAAW,CACf,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,cAAc,CAAC;IAwCpB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAuB5E,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC;IAyBpB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAmBhF,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC;IAqBvC,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,cAAc;YAKR,oBAAoB;IAgClC,OAAO,CAAC,qBAAqB;IAM7B,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,eAAe;IAoBvB,mBAAmB,IAAI;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,eAAe,EAAE,MAAM,CAAC;QACxB,UAAU,EAAE,KAAK,CAAC;YAChB,IAAI,EAAE,MAAM,CAAC;YACb,UAAU,EAAE,MAAM,CAAC;YACnB,EAAE,EAAE;gBAAE,OAAO,EAAE,MAAM,CAAC;gBAAC,GAAG,EAAE,MAAM,CAAA;aAAE,CAAC;YACrC,MAAM,EAAE,MAAM,EAAE,CAAC;SAClB,CAAC,CAAC;KACJ,GAAG,IAAI;IAsBR,OAAO,CAAC,wBAAwB;IAkBhC,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE;CAyDtD"}
|