about summary refs log tree commit diff stats
path: root/html/text-world/js/game.js
diff options
context:
space:
mode:
Diffstat (limited to 'html/text-world/js/game.js')
-rw-r--r--html/text-world/js/game.js239
1 files changed, 239 insertions, 0 deletions
diff --git a/html/text-world/js/game.js b/html/text-world/js/game.js
new file mode 100644
index 0000000..8f2d4d6
--- /dev/null
+++ b/html/text-world/js/game.js
@@ -0,0 +1,239 @@
+class Game {
+    constructor() {
+        const generated = WorldGenerator.generate();
+        this.state = {
+            world: generated.world,
+            playerId: generated.playerId
+        };
+        
+        this.setupUI();
+        this.print("Welcome to the Text Adventure!");
+        this.describeCurrentLocation();
+    }
+
+    setState(newState) {
+        this.state = newState;
+    }
+
+    setupUI() {
+        this.output = document.getElementById('output');
+        this.input = document.getElementById('input');
+        
+        this.input.addEventListener('keypress', (e) => {
+            if (e.key === 'Enter') {
+                const command = this.input.value.toLowerCase();
+                this.input.value = '';
+                this.handleCommand(command);
+            }
+        });
+    }
+
+    print(text) {
+        const line = document.createElement('div');
+        line.textContent = text;
+        this.output.appendChild(line);
+        this.output.scrollTop = this.output.scrollHeight;
+    }
+
+    handleCommand(command) {
+        this.print(`> ${command}`);
+
+        if (command.match(/^(where am i|look around)$/)) {
+            this.describeCurrentLocation();
+        }
+        else if (command.startsWith('move ')) {
+            const newState = this.handleMove(command.split(' ')[1]);
+            if (newState) {
+                this.setState(newState);
+                this.describeCurrentLocation();
+            }
+        }
+        else if (command.startsWith('explore ') || command.startsWith('look at ')) {
+            const target = command.replace(/^(explore|look at) /, '');
+            this.exploreTarget(target);
+        }
+        else if (command === 'phone') {
+            this.checkMessages();
+        }
+        else if (command === 'inventory') {
+            this.checkInventory();
+        }
+        else if (command.startsWith('get ') || command.startsWith('take ')) {
+            const itemName = command.replace(/^(get|take) /, '');
+            const newState = this.collectItem(itemName);
+            if (newState) {
+                this.setState(newState);
+            }
+        }
+        else {
+            this.print("I don't understand that command.");
+        }
+    }
+
+    getCurrentLocation() {
+        const playerPos = World.getComponent(this.state.world, this.state.playerId, 'Position');
+        
+        if (!playerPos) {
+            console.error('Player position not found');
+            return null;
+        }
+        
+        // Find the environment at the player's position
+        const locationEntity = Array.from(this.state.world.entities.entries()).find(([entityId, _]) => {
+            if (entityId === this.state.playerId) return false;
+            
+            const pos = World.getComponent(this.state.world, entityId, 'Position');
+            return pos && pos.x === playerPos.x && pos.y === playerPos.y;
+        });
+
+        if (!locationEntity) return null;
+
+        const [entityId, _] = locationEntity;
+        const desc = World.getComponent(this.state.world, entityId, 'Description');
+        
+        // Add items to the location description
+        const items = this.getItemsAtLocation(playerPos);
+        return { entityId, desc, items };
+    }
+
+    getItemsAtLocation(pos) {
+        return Array.from(this.state.world.entities.entries())
+            .filter(([entityId, _]) => {
+                const itemPos = World.getComponent(this.state.world, entityId, 'Position');
+                const item = World.getComponent(this.state.world, entityId, 'Item');
+                return itemPos && item && 
+                       itemPos.x === pos.x && 
+                       itemPos.y === pos.y;
+            })
+            .map(([entityId, _]) => ({
+                entityId,
+                item: World.getComponent(this.state.world, entityId, 'Item')
+            }));
+    }
+
+    describeCurrentLocation() {
+        const location = this.getCurrentLocation();
+        if (location) {
+            this.print(`You are in: ${location.desc.short}`);
+            this.print(location.desc.long);
+            
+            if (location.items.length > 0) {
+                this.print("\nYou can see:");
+                location.items.forEach(({ item }) => {
+                    this.print(`- ${item.name}`);
+                });
+            }
+        }
+    }
+
+    handleMove(direction) {
+        const playerPos = World.getComponent(this.state.world, this.state.playerId, 'Position');
+        
+        if (!playerPos) {
+            console.error('Player position not found');
+            return null;
+        }
+
+        const moves = {
+            'north': { x: 0, y: -1 },
+            'south': { x: 0, y: 1 },
+            'east': { x: 1, y: 0 },
+            'west': { x: -1, y: 0 }
+        };
+
+        if (!moves[direction]) {
+            this.print("Invalid direction. Use north, south, east, or west.");
+            return null;
+        }
+
+        const newX = playerPos.x + moves[direction].x;
+        const newY = playerPos.y + moves[direction].y;
+
+        if (newX < 0 || newX >= 10 || newY < 0 || newY >= 10) {
+            this.print("You can't go that way - you've reached the edge of the world.");
+            return null;
+        }
+
+        const newWorld = World.addComponent(
+            this.state.world,
+            this.state.playerId,
+            new Position(newX, newY)
+        );
+
+        this.print(`You move ${direction}.`);
+        
+        return {
+            ...this.state,
+            world: newWorld
+        };
+    }
+
+    exploreTarget(target) {
+        const location = this.getCurrentLocation();
+        if (location && location.desc.explorable[target]) {
+            this.print(location.desc.explorable[target]);
+        } else {
+            this.print("There's nothing special about that.");
+        }
+    }
+
+    checkMessages() {
+        const messages = World.getComponent(this.state.world, this.state.playerId, 'Messages');
+        if (messages.messages.length === 0) {
+            this.print("You have no messages.");
+        } else {
+            this.print("Your messages:");
+            messages.messages.forEach(msg => this.print(`- ${msg}`));
+        }
+    }
+
+    collectItem(itemName) {
+        const playerPos = World.getComponent(this.state.world, this.state.playerId, 'Position');
+        const items = this.getItemsAtLocation(playerPos);
+        
+        const itemEntry = items.find(({ item }) => 
+            item.name.toLowerCase() === itemName.toLowerCase()
+        );
+
+        if (!itemEntry) {
+            this.print(`There is no ${itemName} here.`);
+            return null;
+        }
+
+        if (!itemEntry.item.collectable) {
+            this.print(`You can't take the ${itemName}.`);
+            return null;
+        }
+
+        // Add to inventory
+        const inventory = World.getComponent(this.state.world, this.state.playerId, 'Inventory');
+        const updatedInventory = new Inventory([...inventory.items, itemEntry.item]);
+        
+        // Remove from world and update inventory
+        let newWorld = World.removeComponent(this.state.world, itemEntry.entityId, 'Position');
+        newWorld = World.addComponent(newWorld, this.state.playerId, updatedInventory);
+
+        this.print(`You take the ${itemName}.`);
+        return {
+            ...this.state,
+            world: newWorld
+        };
+    }
+
+    checkInventory() {
+        const inventory = World.getComponent(this.state.world, this.state.playerId, 'Inventory');
+        if (inventory.items.length === 0) {
+            this.print("Your inventory is empty.");
+        } else {
+            this.print("Your inventory contains:");
+            inventory.items.forEach(item => {
+                this.print(`- ${item.name}`);
+            });
+        }
+    }
+}
+
+// Start the game when the page loads
+window.addEventListener('load', () => {
+    window.game = new Game();
+});