feat: complete Phase 4 combat/hunting system
- Add content migration (003_content.sql): zones, monsters, items, loot tables - Add inventory migration (004_inventory.sql) and logs migration (006_logs.sql) - Add Mulberry32 PRNG (src/utils/rng.js) for deterministic combat - Add combat system (src/game/combat.js) with turn order, crit, mage bonus, 20-round cap - Add rewards/loot system (src/game/rewards.js) and leveling (src/game/leveling.js) - Add hunt endpoint (POST /api/hunt) with full combat flow in DB transaction - Add hunt integration tests and unit tests for rewards/leveling/combat - Fix session middleware to use memory store in tests (avoids cleanup hang) - Fix huntService transaction (db.transaction() returns wrapper, must call separately) - Add huntService to helpers.js cache invalidation for test isolation
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
// Hunt routes: POST /api/hunt (fight a monster in a zone).
|
||||
const zod = require('zod');
|
||||
const { AppError } = require('../utils/errors');
|
||||
const { requireAuth } = require('../middleware/session');
|
||||
const { hunt } = require('../services/huntService');
|
||||
|
||||
// Validation schema
|
||||
const huntSchema = zod.strictObject({
|
||||
zoneId: zod.number().int().positive(),
|
||||
});
|
||||
|
||||
function wrap(fn) {
|
||||
return (req, res, next) => Promise.resolve(fn(req, res, next)).catch(next);
|
||||
}
|
||||
|
||||
async function handleHunt(req, res) {
|
||||
const parsed = huntSchema.safeParse(req.body);
|
||||
if (!parsed.success) {
|
||||
throw new AppError('VALIDATION_ERROR', 'Request validation failed.', 400);
|
||||
}
|
||||
|
||||
const { zoneId } = parsed.data;
|
||||
const userId = req.session.userId;
|
||||
|
||||
// Get character ID for this user
|
||||
const db = require('../db').getDb();
|
||||
const character = db.prepare('SELECT id FROM characters WHERE user_id = ?').get(userId);
|
||||
if (!character) {
|
||||
throw new AppError('NO_CHARACTER', 'No character found.', 404);
|
||||
}
|
||||
|
||||
const result = hunt(character.id, zoneId);
|
||||
|
||||
res.json({
|
||||
ok: true,
|
||||
data: result,
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
routes: {
|
||||
postHunt: wrap(handleHunt),
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user