zork-ts 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/engine/cyclops.js +1 -1
- package/dist/engine/executor.js +1 -1
- package/dist/engine/thief.js +2 -1
- package/dist/game/actions.js +8 -4
- package/dist/game/data/flags.d.ts +1 -0
- package/dist/game/data/flags.js +2 -0
- package/dist/game/data/rooms-complete.js +0 -12
- package/dist/game/death.js +3 -3
- package/dist/game/factories/verifyContent.js +13 -14
- package/dist/game/objects.d.ts +11 -4
- package/dist/game/rooms.d.ts +3 -0
- package/dist/game/rooms.js +2 -0
- package/dist/game/sceneryActions.js +3 -3
- package/dist/game/specialBehaviors.js +2 -2
- package/dist/game/state.d.ts +15 -0
- package/dist/game/state.js +45 -0
- package/dist/parity/ObjectInteractionManager.js +17 -8
- package/dist/parity/ParityEnhancementEngine.js +2 -1
- package/dist/parity/interfaces.d.ts +3 -0
- package/dist/persistence/serializer.js +1 -1
- package/package.json +4 -4
package/dist/engine/cyclops.js
CHANGED
|
@@ -55,7 +55,7 @@ export class CyclopsBehavior extends BaseActorBehavior {
|
|
|
55
55
|
this.wrathLevel = this.wrathLevel + 1;
|
|
56
56
|
}
|
|
57
57
|
const messageIndex = Math.min(absWrath - 1, CYCLOPS_MAD_MESSAGES.length - 1);
|
|
58
|
-
if (messageIndex >= 0
|
|
58
|
+
if (messageIndex >= 0) {
|
|
59
59
|
console.log(CYCLOPS_MAD_MESSAGES[messageIndex]);
|
|
60
60
|
return true;
|
|
61
61
|
}
|
package/dist/engine/executor.js
CHANGED
|
@@ -395,7 +395,7 @@ export class CommandExecutor {
|
|
|
395
395
|
}
|
|
396
396
|
// SAY command needs raw input
|
|
397
397
|
if (verb === 'SAY') {
|
|
398
|
-
return handler.execute(state, command.directObject?.id, command.indirectObject?.id, command.preposition,
|
|
398
|
+
return handler.execute(state, command.directObject?.id, command.indirectObject?.id, command.preposition, command.rawInput);
|
|
399
399
|
}
|
|
400
400
|
// Intransitive verbs (no object required)
|
|
401
401
|
if (['XYZZY', 'PLUGH', 'PLOVER', 'JUMP', 'LEAP', 'PRAY', 'CURSE', 'SING', 'LISTEN', 'SMELL', 'SNIFF', 'WAIT', 'Z', 'CLIMB', 'ECHO', 'DANCE', 'SWIM', 'DIG', 'SLEEP', 'WAKE', 'YELL', 'SCREAM', 'HELLO', 'HI', 'GOODBYE', 'THANK', 'YES', 'Y', 'NO'].includes(verb)) {
|
package/dist/engine/thief.js
CHANGED
|
@@ -96,7 +96,8 @@ export class ThiefBehavior extends BaseActorBehavior {
|
|
|
96
96
|
const room = state.getCurrentRoom();
|
|
97
97
|
if (!room)
|
|
98
98
|
return false;
|
|
99
|
-
|
|
99
|
+
// Check if room has ONBIT flag (rooms use string flags)
|
|
100
|
+
return room.flags.has('ONBIT');
|
|
100
101
|
}
|
|
101
102
|
/**
|
|
102
103
|
* Check if troll is present in current room
|
package/dist/game/actions.js
CHANGED
|
@@ -1106,8 +1106,8 @@ export class ReadAction {
|
|
|
1106
1106
|
stateChanges: takenMessage ? [{
|
|
1107
1107
|
type: 'OBJECT_MOVED',
|
|
1108
1108
|
objectId: objectId,
|
|
1109
|
-
|
|
1110
|
-
|
|
1109
|
+
oldValue: obj.location,
|
|
1110
|
+
newValue: 'PLAYER'
|
|
1111
1111
|
}] : []
|
|
1112
1112
|
};
|
|
1113
1113
|
}
|
|
@@ -2215,7 +2215,7 @@ export class ClimbAction {
|
|
|
2215
2215
|
if (upExit && upExit.destination) {
|
|
2216
2216
|
// Track if room was visited before
|
|
2217
2217
|
const newRoom = state.rooms.get(upExit.destination);
|
|
2218
|
-
const wasVisited = newRoom?.hasFlag(
|
|
2218
|
+
const wasVisited = newRoom?.hasFlag(RoomFlag.TOUCHBIT) || false;
|
|
2219
2219
|
// Move up
|
|
2220
2220
|
state.setCurrentRoom(upExit.destination);
|
|
2221
2221
|
// Get the new room and display its description
|
|
@@ -3729,7 +3729,11 @@ export class DropAllAction {
|
|
|
3729
3729
|
// Use ObjectInteractionManager for context-aware empty-handed message
|
|
3730
3730
|
const objectManager = new ZMachineObjectInteraction();
|
|
3731
3731
|
const result = objectManager.handleDropAllCommand(state);
|
|
3732
|
-
return
|
|
3732
|
+
return {
|
|
3733
|
+
success: result.success,
|
|
3734
|
+
message: result.message,
|
|
3735
|
+
stateChanges: []
|
|
3736
|
+
};
|
|
3733
3737
|
}
|
|
3734
3738
|
const messages = [];
|
|
3735
3739
|
const stateChanges = [];
|
package/dist/game/data/flags.js
CHANGED
|
@@ -131,6 +131,7 @@ export const FLAG_DESCRIPTIONS = {
|
|
|
131
131
|
NONLANDBIT: 'Room is not on land (water/boat required)',
|
|
132
132
|
// Global Flags
|
|
133
133
|
CYCLOPS_FLAG: 'Cyclops has been dealt with',
|
|
134
|
+
DAM_LIGHTS: 'Dam control panel lights are on',
|
|
134
135
|
DEFLATE: 'Boat has been deflated',
|
|
135
136
|
DOME_FLAG: 'Dome rope has been tied',
|
|
136
137
|
EMPTY_HANDED: 'Player is carrying nothing',
|
|
@@ -147,6 +148,7 @@ export const FLAG_DESCRIPTIONS = {
|
|
|
147
148
|
*/
|
|
148
149
|
export const INITIAL_GLOBAL_FLAGS = {
|
|
149
150
|
CYCLOPS_FLAG: false,
|
|
151
|
+
DAM_LIGHTS: false,
|
|
150
152
|
DEFLATE: false,
|
|
151
153
|
DOME_FLAG: false,
|
|
152
154
|
EMPTY_HANDED: false,
|
|
@@ -195,18 +195,6 @@ export const ALL_ROOMS = {
|
|
|
195
195
|
flags: ['RLANDBIT', 'ONBIT', 'SACREDBIT'],
|
|
196
196
|
globalObjects: ['TREE', 'SONGBIRD', 'WHITE-HOUSE', 'FOREST']
|
|
197
197
|
},
|
|
198
|
-
'CANYON-VIEW': {
|
|
199
|
-
id: 'CANYON-VIEW',
|
|
200
|
-
name: 'Canyon View',
|
|
201
|
-
description: 'Canyon View',
|
|
202
|
-
longDescription: 'You are at the top of the Great Canyon on its west wall. From here there is a marvelous view of the canyon and parts of the Frigid River upstream. Across the canyon, the walls of the White Cliffs join the mighty ramparts of the Flathead Mountains to the east. Following the Canyon upstream to the north, Aragain Falls may be seen, complete with rainbow. The mighty Frigid River flows out from a great dark cavern. To the west and south can be seen an immense forest, stretching for miles around. A path leads northwest. It is possible to climb down into the canyon from here.',
|
|
203
|
-
exits: [
|
|
204
|
-
{ direction: 'WEST', destination: 'CLEARING' },
|
|
205
|
-
{ direction: 'NW', destination: 'GRATING-CLEARING' },
|
|
206
|
-
{ direction: 'DOWN', destination: 'ROCKY-LEDGE' }
|
|
207
|
-
],
|
|
208
|
-
flags: ['RLANDBIT', 'ONBIT', 'SACREDBIT']
|
|
209
|
-
},
|
|
210
198
|
'MOUNTAINS': {
|
|
211
199
|
id: 'MOUNTAINS',
|
|
212
200
|
name: 'Forest',
|
package/dist/game/death.js
CHANGED
|
@@ -196,7 +196,7 @@ function randomizeObjects(state) {
|
|
|
196
196
|
// Reset SWORD treasure value to 0
|
|
197
197
|
const sword = state.getObject('SWORD');
|
|
198
198
|
if (sword) {
|
|
199
|
-
sword.
|
|
199
|
+
sword.value = 0;
|
|
200
200
|
}
|
|
201
201
|
// Get all objects in inventory
|
|
202
202
|
const inventoryObjects = state.getInventoryObjects();
|
|
@@ -209,8 +209,8 @@ function randomizeObjects(state) {
|
|
|
209
209
|
if (obj.id === 'LAMP' || obj.id === 'COFFIN') {
|
|
210
210
|
continue;
|
|
211
211
|
}
|
|
212
|
-
// Treasures (
|
|
213
|
-
if (obj.
|
|
212
|
+
// Treasures (value > 0) go to random RLANDBIT rooms
|
|
213
|
+
if (obj.value && obj.value > 0) {
|
|
214
214
|
// Pick a random RLANDBIT room using 50% probability per room
|
|
215
215
|
if (rlandRooms.length > 0) {
|
|
216
216
|
let placed = false;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { createInitialGameState, validateRoomConnections, validateObjectLocations } from './gameFactory.js';
|
|
6
6
|
import { ALL_ROOMS } from '../data/rooms-complete.js';
|
|
7
7
|
import { ALL_OBJECTS } from '../data/objects-complete.js';
|
|
8
|
+
import { Direction } from '../rooms.js';
|
|
8
9
|
/**
|
|
9
10
|
* Verify content completeness
|
|
10
11
|
*/
|
|
@@ -187,10 +188,8 @@ export function verifyContent() {
|
|
|
187
188
|
for (const [direction, exit] of room.exits.entries()) {
|
|
188
189
|
if (exit.condition) {
|
|
189
190
|
conditionalExitCount++;
|
|
190
|
-
//
|
|
191
|
-
|
|
192
|
-
warnings.push(`Room ${roomId} exit ${direction} has condition ${exit.condition} which is not a known flag`);
|
|
193
|
-
}
|
|
191
|
+
// Note: exit.condition is a function, not a flag name
|
|
192
|
+
// We can't easily validate the condition without executing it
|
|
194
193
|
}
|
|
195
194
|
}
|
|
196
195
|
}
|
|
@@ -198,16 +197,16 @@ export function verifyContent() {
|
|
|
198
197
|
// Check bidirectional connections
|
|
199
198
|
console.log(`\n=== Checking Bidirectional Connections ===`);
|
|
200
199
|
const oppositeDirections = {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
200
|
+
[Direction.NORTH]: Direction.SOUTH,
|
|
201
|
+
[Direction.SOUTH]: Direction.NORTH,
|
|
202
|
+
[Direction.EAST]: Direction.WEST,
|
|
203
|
+
[Direction.WEST]: Direction.EAST,
|
|
204
|
+
[Direction.NE]: Direction.SW,
|
|
205
|
+
[Direction.SW]: Direction.NE,
|
|
206
|
+
[Direction.NW]: Direction.SE,
|
|
207
|
+
[Direction.SE]: Direction.NW,
|
|
208
|
+
[Direction.UP]: Direction.DOWN,
|
|
209
|
+
[Direction.DOWN]: Direction.UP,
|
|
211
210
|
};
|
|
212
211
|
let bidirectionalCount = 0;
|
|
213
212
|
let unidirectionalCount = 0;
|
package/dist/game/objects.d.ts
CHANGED
|
@@ -31,8 +31,15 @@ export interface GameObject {
|
|
|
31
31
|
capacity?: number;
|
|
32
32
|
size?: number;
|
|
33
33
|
value?: number;
|
|
34
|
-
hasFlag(flag: ObjectFlag): boolean;
|
|
34
|
+
hasFlag(flag: ObjectFlag | string): boolean;
|
|
35
|
+
addFlag(flag: ObjectFlag | string): void;
|
|
36
|
+
removeFlag(flag: ObjectFlag | string): void;
|
|
37
|
+
getProperty(key: string): any;
|
|
38
|
+
setProperty(key: string, value: any): void;
|
|
35
39
|
isOpen(): boolean;
|
|
40
|
+
isContainer(): boolean;
|
|
41
|
+
isTakeable(): boolean;
|
|
42
|
+
providesLight(): boolean;
|
|
36
43
|
}
|
|
37
44
|
/**
|
|
38
45
|
* GameObjectImpl provides a concrete implementation of GameObject
|
|
@@ -74,15 +81,15 @@ export declare class GameObjectImpl implements GameObject {
|
|
|
74
81
|
/**
|
|
75
82
|
* Check if object has a specific flag
|
|
76
83
|
*/
|
|
77
|
-
hasFlag(flag: ObjectFlag): boolean;
|
|
84
|
+
hasFlag(flag: ObjectFlag | string): boolean;
|
|
78
85
|
/**
|
|
79
86
|
* Add a flag to the object
|
|
80
87
|
*/
|
|
81
|
-
addFlag(flag: ObjectFlag): void;
|
|
88
|
+
addFlag(flag: ObjectFlag | string): void;
|
|
82
89
|
/**
|
|
83
90
|
* Remove a flag from the object
|
|
84
91
|
*/
|
|
85
|
-
removeFlag(flag: ObjectFlag): void;
|
|
92
|
+
removeFlag(flag: ObjectFlag | string): void;
|
|
86
93
|
/**
|
|
87
94
|
* Toggle a flag on the object
|
|
88
95
|
*/
|
package/dist/game/rooms.d.ts
CHANGED
|
@@ -40,6 +40,7 @@ export interface Room {
|
|
|
40
40
|
exits: Map<Direction, Exit>;
|
|
41
41
|
objects: string[];
|
|
42
42
|
globalObjects?: string[];
|
|
43
|
+
scenery?: string[];
|
|
43
44
|
visited: boolean;
|
|
44
45
|
flags: Set<RoomFlag>;
|
|
45
46
|
hasFlag(flag: RoomFlag): boolean;
|
|
@@ -66,6 +67,7 @@ export declare class RoomImpl implements Room {
|
|
|
66
67
|
exits: Map<Direction, Exit>;
|
|
67
68
|
objects: string[];
|
|
68
69
|
globalObjects?: string[];
|
|
70
|
+
scenery?: string[];
|
|
69
71
|
visited: boolean;
|
|
70
72
|
flags: Set<RoomFlag>;
|
|
71
73
|
constructor(data: {
|
|
@@ -75,6 +77,7 @@ export declare class RoomImpl implements Room {
|
|
|
75
77
|
exits?: Map<Direction, Exit>;
|
|
76
78
|
objects?: string[];
|
|
77
79
|
globalObjects?: string[];
|
|
80
|
+
scenery?: string[];
|
|
78
81
|
visited?: boolean;
|
|
79
82
|
flags?: RoomFlag[];
|
|
80
83
|
});
|
package/dist/game/rooms.js
CHANGED
|
@@ -32,6 +32,7 @@ export class RoomImpl {
|
|
|
32
32
|
exits;
|
|
33
33
|
objects;
|
|
34
34
|
globalObjects;
|
|
35
|
+
scenery;
|
|
35
36
|
visited;
|
|
36
37
|
flags;
|
|
37
38
|
constructor(data) {
|
|
@@ -41,6 +42,7 @@ export class RoomImpl {
|
|
|
41
42
|
this.exits = data.exits || new Map();
|
|
42
43
|
this.objects = data.objects || [];
|
|
43
44
|
this.globalObjects = data.globalObjects;
|
|
45
|
+
this.scenery = data.scenery;
|
|
44
46
|
this.visited = data.visited || false;
|
|
45
47
|
this.flags = new Set(data.flags || []);
|
|
46
48
|
}
|
|
@@ -474,8 +474,8 @@ const rainbowHandler = {
|
|
|
474
474
|
if (state.currentRoom === 'CANYON-VIEW') {
|
|
475
475
|
return 'From here?!?';
|
|
476
476
|
}
|
|
477
|
-
// Check if rainbow is solid (
|
|
478
|
-
const rainbowSolid = state.getFlag('
|
|
477
|
+
// Check if rainbow is solid (RAINBOW_FLAG)
|
|
478
|
+
const rainbowSolid = state.getFlag('RAINBOW_FLAG');
|
|
479
479
|
if (rainbowSolid) {
|
|
480
480
|
// This would trigger movement logic
|
|
481
481
|
return "You'll have to say which way...";
|
|
@@ -486,7 +486,7 @@ const rainbowHandler = {
|
|
|
486
486
|
if (state.currentRoom === 'CANYON-VIEW') {
|
|
487
487
|
return 'From here?!?';
|
|
488
488
|
}
|
|
489
|
-
const rainbowSolid = state.getFlag('
|
|
489
|
+
const rainbowSolid = state.getFlag('RAINBOW_FLAG');
|
|
490
490
|
if (rainbowSolid) {
|
|
491
491
|
return "You'll have to say which way...";
|
|
492
492
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Special Behavior Handlers
|
|
3
3
|
* Handles complex state-dependent behaviors for special objects
|
|
4
4
|
*/
|
|
5
|
-
import { ObjectFlag } from './data/flags.js';
|
|
5
|
+
import { ObjectFlag, RoomFlag } from './data/flags.js';
|
|
6
6
|
import { initializeCandleTimer } from '../engine/daemons.js';
|
|
7
7
|
/**
|
|
8
8
|
* Registry of all special behaviors
|
|
@@ -700,7 +700,7 @@ const buttonBehavior = {
|
|
|
700
700
|
}
|
|
701
701
|
if (directObject === 'YELLOW-BUTTON' && yellowButton) {
|
|
702
702
|
const room = state.getCurrentRoom();
|
|
703
|
-
if (room?.hasFlag(
|
|
703
|
+
if (room?.hasFlag(RoomFlag.ONBIT)) {
|
|
704
704
|
return 'The chests are already open.';
|
|
705
705
|
}
|
|
706
706
|
}
|
package/dist/game/state.d.ts
CHANGED
|
@@ -226,5 +226,20 @@ export declare class GameState {
|
|
|
226
226
|
* @returns true if testing mode is enabled
|
|
227
227
|
*/
|
|
228
228
|
isTestingMode(): boolean;
|
|
229
|
+
/**
|
|
230
|
+
* Get the current turn number (alias for moves)
|
|
231
|
+
* Used for compatibility with parity modules
|
|
232
|
+
*/
|
|
233
|
+
get turn(): number;
|
|
234
|
+
/**
|
|
235
|
+
* Check if the current room is lit
|
|
236
|
+
* Wrapper for lighting system's isRoomLit function
|
|
237
|
+
*/
|
|
238
|
+
hasLight(): boolean;
|
|
239
|
+
/**
|
|
240
|
+
* Check if player has an active light source
|
|
241
|
+
* Wrapper for checking inventory light sources
|
|
242
|
+
*/
|
|
243
|
+
hasLightSource(): boolean;
|
|
229
244
|
}
|
|
230
245
|
//# sourceMappingURL=state.d.ts.map
|
package/dist/game/state.js
CHANGED
|
@@ -407,5 +407,50 @@ export class GameState {
|
|
|
407
407
|
isTestingMode() {
|
|
408
408
|
return this.testingMode;
|
|
409
409
|
}
|
|
410
|
+
/**
|
|
411
|
+
* Get the current turn number (alias for moves)
|
|
412
|
+
* Used for compatibility with parity modules
|
|
413
|
+
*/
|
|
414
|
+
get turn() {
|
|
415
|
+
return this.moves;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Check if the current room is lit
|
|
419
|
+
* Wrapper for lighting system's isRoomLit function
|
|
420
|
+
*/
|
|
421
|
+
hasLight() {
|
|
422
|
+
const room = this.getCurrentRoom();
|
|
423
|
+
if (!room)
|
|
424
|
+
return false;
|
|
425
|
+
// Check if room is inherently lit
|
|
426
|
+
if (room.hasFlag('ONBIT'))
|
|
427
|
+
return true;
|
|
428
|
+
// Check for light sources in inventory
|
|
429
|
+
for (const obj of this.getInventoryObjects()) {
|
|
430
|
+
if (obj.hasFlag('LIGHTBIT') && obj.hasFlag('ONBIT')) {
|
|
431
|
+
return true;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
// Check for light sources in room
|
|
435
|
+
for (const objId of room.objects) {
|
|
436
|
+
const obj = this.getObject(objId);
|
|
437
|
+
if (obj && obj.hasFlag('LIGHTBIT') && obj.hasFlag('ONBIT')) {
|
|
438
|
+
return true;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Check if player has an active light source
|
|
445
|
+
* Wrapper for checking inventory light sources
|
|
446
|
+
*/
|
|
447
|
+
hasLightSource() {
|
|
448
|
+
for (const obj of this.getInventoryObjects()) {
|
|
449
|
+
if (obj.hasFlag('LIGHTBIT') && obj.hasFlag('ONBIT')) {
|
|
450
|
+
return true;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
410
455
|
}
|
|
411
456
|
//# sourceMappingURL=state.js.map
|
|
@@ -74,14 +74,20 @@ export class ZMachineObjectInteraction {
|
|
|
74
74
|
return false;
|
|
75
75
|
}
|
|
76
76
|
// Check if object is in current room
|
|
77
|
-
const currentRoom = gameState.
|
|
78
|
-
if (currentRoom?.objects?.some(
|
|
79
|
-
obj
|
|
77
|
+
const currentRoom = gameState.getCurrentRoom();
|
|
78
|
+
if (currentRoom?.objects?.some(objId => {
|
|
79
|
+
const obj = gameState.getObject(objId);
|
|
80
|
+
return obj && (obj.name.toLowerCase() === object.toLowerCase() ||
|
|
81
|
+
obj.synonyms?.some(syn => syn.toLowerCase() === object.toLowerCase()));
|
|
82
|
+
})) {
|
|
80
83
|
return true;
|
|
81
84
|
}
|
|
82
85
|
// Check if object is in inventory
|
|
83
|
-
if (gameState.inventory?.some(
|
|
84
|
-
obj
|
|
86
|
+
if (gameState.inventory?.some(objId => {
|
|
87
|
+
const obj = gameState.getObject(objId);
|
|
88
|
+
return obj && (obj.name.toLowerCase() === object.toLowerCase() ||
|
|
89
|
+
obj.synonyms?.some(syn => syn.toLowerCase() === object.toLowerCase()));
|
|
90
|
+
})) {
|
|
85
91
|
return true;
|
|
86
92
|
}
|
|
87
93
|
// Check if it's a room feature or scenery
|
|
@@ -105,14 +111,17 @@ export class ZMachineObjectInteraction {
|
|
|
105
111
|
// Check visibility
|
|
106
112
|
context.isVisible = this.checkObjectVisibility(object, gameState);
|
|
107
113
|
// Check possession
|
|
108
|
-
context.isPossessed = gameState.inventory?.some(
|
|
109
|
-
obj
|
|
114
|
+
context.isPossessed = gameState.inventory?.some(objId => {
|
|
115
|
+
const obj = gameState.getObject(objId);
|
|
116
|
+
return obj && (obj.name.toLowerCase() === object.toLowerCase() ||
|
|
117
|
+
obj.synonyms?.some(syn => syn.toLowerCase() === object.toLowerCase()));
|
|
118
|
+
}) || false;
|
|
110
119
|
// Set location context
|
|
111
120
|
if (context.isPossessed) {
|
|
112
121
|
context.location = 'inventory';
|
|
113
122
|
}
|
|
114
123
|
else if (context.isVisible) {
|
|
115
|
-
context.location = gameState.
|
|
124
|
+
context.location = gameState.getCurrentRoom()?.name || 'unknown';
|
|
116
125
|
}
|
|
117
126
|
else {
|
|
118
127
|
context.location = 'unknown';
|
|
@@ -171,10 +171,11 @@ export class ParityEnhancementEngine {
|
|
|
171
171
|
*/
|
|
172
172
|
createMessageContext(command, gameState) {
|
|
173
173
|
const context = this.parseCommand(command);
|
|
174
|
+
const currentRoom = gameState.getCurrentRoom();
|
|
174
175
|
return {
|
|
175
176
|
verb: context.verb,
|
|
176
177
|
object: context.directObject,
|
|
177
|
-
location:
|
|
178
|
+
location: currentRoom?.name,
|
|
178
179
|
command: command
|
|
179
180
|
};
|
|
180
181
|
}
|
|
@@ -84,6 +84,7 @@ export interface ParserErrorHandler {
|
|
|
84
84
|
handleIncompleteCommand(verb: string, context: ParseContext): string;
|
|
85
85
|
handleUnknownVerb(input: string): string;
|
|
86
86
|
handleMalformedCommand(input: string): string;
|
|
87
|
+
verbRequiresObject(verb: string): boolean;
|
|
87
88
|
}
|
|
88
89
|
/**
|
|
89
90
|
* ObjectInteractionManager interface for managing object interactions
|
|
@@ -100,6 +101,7 @@ export interface MessageConsistencyManager {
|
|
|
100
101
|
standardizeMessage(messageType: MessageType, context: MessageContext): string;
|
|
101
102
|
validateMessageFormat(message: string): boolean;
|
|
102
103
|
getCanonicalMessage(messageType: MessageType, context: MessageContext): string;
|
|
104
|
+
formatErrorMessage(message: string): string;
|
|
103
105
|
}
|
|
104
106
|
/**
|
|
105
107
|
* StateSynchronizationManager interface for game state validation
|
|
@@ -109,5 +111,6 @@ export interface StateSynchronizationManager {
|
|
|
109
111
|
synchronizeObjectLocations(state: GameState): void;
|
|
110
112
|
ensureInventoryConsistency(state: GameState): void;
|
|
111
113
|
validateObjectAction?(action: string, objectId: string, gameState: GameState): any;
|
|
114
|
+
repairStateInconsistencies(state: GameState): ValidationResult;
|
|
112
115
|
}
|
|
113
116
|
//# sourceMappingURL=interfaces.d.ts.map
|
|
@@ -176,7 +176,7 @@ export class Serializer {
|
|
|
176
176
|
location: obj.location,
|
|
177
177
|
locationRelation: obj.locationRelation,
|
|
178
178
|
properties: new Map(obj.properties),
|
|
179
|
-
flags:
|
|
179
|
+
flags: obj.flags,
|
|
180
180
|
capacity: obj.capacity,
|
|
181
181
|
size: obj.size,
|
|
182
182
|
value: obj.value
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zork-ts",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Zork I: The Great Underground Empire - TypeScript Edition",
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"bin": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"_securityNote": "pkg has GHSA-22r3-9w55-cj54 (moderate, local privilege escalation). Risk accepted: dev-only, local access required, no fix available. See dev-artifacts/docs/PACKAGING.md"
|
|
48
48
|
},
|
|
49
49
|
"engines": {
|
|
50
|
-
"node": ">=
|
|
50
|
+
"node": ">=25.0.3"
|
|
51
51
|
},
|
|
52
52
|
"repository": {
|
|
53
53
|
"type": "git",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"author": "",
|
|
70
70
|
"license": "MIT",
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"@types/node": "^
|
|
72
|
+
"@types/node": "^25.0.3",
|
|
73
73
|
"pkg": "^5.8.1",
|
|
74
74
|
"tsx": "^4.7.0",
|
|
75
75
|
"typescript": "^5.3.0",
|
|
@@ -77,6 +77,6 @@
|
|
|
77
77
|
},
|
|
78
78
|
"dependencies": {
|
|
79
79
|
"fast-check": "^4.5.3",
|
|
80
|
-
"zod": "^4.
|
|
80
|
+
"zod": "^4.3.4"
|
|
81
81
|
}
|
|
82
82
|
}
|