summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server.js35
-rw-r--r--tools/sql/schema.txt8
-rw-r--r--views/create.ejs5
-rw-r--r--views/join.ejs14
4 files changed, 49 insertions, 13 deletions
diff --git a/server.js b/server.js
index 0f694a1..2ac4725 100644
--- a/server.js
+++ b/server.js
@@ -362,6 +362,8 @@ const QUERY_LIST_ONE_GAME = db.prepare(`
games.mtime,
games.description,
games.status,
+ games.private,
+ games.random,
games.result,
games.active
FROM games
@@ -433,7 +435,6 @@ const QUERY_LIST_ALL_GAMES = db.prepare(`
const QUERY_PLAYERS = db.prepare(`
SELECT
- players.game_id,
players.user_id,
players.role,
users.name
@@ -452,21 +453,22 @@ const QUERY_PLAYER_NAMES = db.prepare(`
`).pluck();
const QUERY_TITLE = db.prepare("SELECT * FROM titles WHERE title_id = ?");
-const QUERY_ROLES = db.prepare("SELECT * FROM roles WHERE title_id = ?");
+const QUERY_ROLES = db.prepare("SELECT role FROM roles WHERE title_id = ?").pluck();
const QUERY_GAME_OWNER = db.prepare("SELECT * FROM games WHERE game_id = ? AND owner = ?");
const QUERY_TITLE_FROM_GAME = db.prepare("SELECT title_id FROM games WHERE game_id = ?");
const QUERY_ROLE_FROM_GAME_AND_USER = db.prepare("SELECT role FROM players WHERE game_id = ? AND user_id = ?");
const QUERY_JOIN_GAME = db.prepare("INSERT INTO players (user_id, game_id, role) VALUES (?,?,?)");
const QUERY_PART_GAME = db.prepare("DELETE FROM players WHERE game_id = ? AND user_id = ? AND role = ?");
-const QUERY_START_GAME = db.prepare("UPDATE games SET status = 1, state = ?, active = ? WHERE game_id = ?");
+const QUERY_START_GAME = db.prepare("UPDATE games SET random = 0, status = 1, state = ?, active = ? WHERE game_id = ?");
const QUERY_CREATE_GAME = db.prepare(`
INSERT INTO games
- (owner,title_id,scenario,private,ctime,mtime,description,status,state,chat)
+ (owner,title_id,scenario,private,random,ctime,mtime,description,status,state,chat)
VALUES
- (?,?,?,?,datetime('now'),datetime('now'),?,0,NULL,'[]')
+ (?,?,?,?,?,datetime('now'),datetime('now'),?,0,NULL,'[]')
`);
const QUERY_UPDATE_GAME_SET_PRIVATE = db.prepare("UPDATE games SET private = 1 WHERE game_id = ?");
+const QUERY_ASSIGN_ROLE = db.prepare("UPDATE players SET role = ? WHERE game_id = ? AND user_id = ? AND role = ?");
const QUERY_IS_PLAYER = db.prepare("SELECT COUNT(*) FROM players WHERE game_id = ? AND user_id = ?").pluck();
const QUERY_IS_ACTIVE = db.prepare("SELECT COUNT(*) FROM players WHERE game_id = ? AND role = ? AND user_id = ?").pluck();
@@ -559,6 +561,7 @@ app.post('/create/:title_id', must_be_logged_in, function (req, res) {
let title_id = req.params.title_id;
let descr = req.body.description;
let priv = req.body.private == 'private';
+ let rand = req.body.random == 'random';
let scenario = req.body.scenario;
let user_id = req.user.user_id;
LOG(req, "POST /create/" + req.params.title_id, scenario, priv, JSON.stringify(descr));
@@ -576,7 +579,7 @@ app.post('/create/:title_id', must_be_logged_in, function (req, res) {
req.flash('message', "That scenario doesn't exist.");
return res.redirect('/create/'+title_id);
}
- let info = QUERY_CREATE_GAME.run(user_id, title_id, scenario, priv ? 1 : 0, descr);
+ let info = QUERY_CREATE_GAME.run(user_id, title_id, scenario, priv ? 1 : 0, rand ? 1 : 0, descr);
res.redirect('/join/'+info.lastInsertRowid);
} catch (err) {
req.flash('message', err.toString());
@@ -610,6 +613,9 @@ app.get('/join/:game_id', must_be_logged_in, function (req, res) {
return res.redirect('/');
}
let roles = QUERY_ROLES.all(game.title_id);
+ if (game.random)
+ for (let i = 0; i < roles.length; ++i)
+ roles[i] = "Random " + (i+1);
let players = QUERY_PLAYERS.all(game_id);
res.set("Cache-Control", "no-store");
res.render('join.ejs', {
@@ -649,6 +655,21 @@ app.get('/part/:game_id/:part_id/:role', must_be_logged_in, function (req, res)
}
});
+function assign_random_roles(game, players) {
+ function pick_random_item(list) {
+ let k = Math.floor(Math.random() * list.length);
+ let r = list[k];
+ list.splice(k, 1);
+ return r;
+ }
+ let roles = QUERY_ROLES.all(game.title_id);
+ for (let p of players) {
+ let old_role = p.role;
+ p.role = pick_random_item(roles);
+ QUERY_ASSIGN_ROLE.run(p.role, game.game_id, p.user_id, old_role);
+ }
+}
+
app.get('/start/:game_id', must_be_logged_in, function (req, res) {
LOG(req, "GET /start/" + req.params.game_id);
let game_id = req.params.game_id | 0;
@@ -663,6 +684,8 @@ app.get('/start/:game_id', must_be_logged_in, function (req, res) {
return res.redirect('/join/'+game_id);
}
let players = QUERY_PLAYERS.all(game_id);
+ if (game.random)
+ assign_random_roles(game, players);
let state = RULES[game.title_id].setup(game.scenario, players);
QUERY_START_GAME.run(JSON.stringify(state), state.active, game_id);
let is_solo = players.every(p => p.user_id == players[0].user_id);
diff --git a/tools/sql/schema.txt b/tools/sql/schema.txt
index 97e8b25..d9502c2 100644
--- a/tools/sql/schema.txt
+++ b/tools/sql/schema.txt
@@ -31,6 +31,7 @@ CREATE TABLE IF NOT EXISTS games (
scenario TEXT,
owner INTEGER,
private BOOLEAN,
+ random BOOLEAN,
ctime TIMESTAMP,
mtime TIMESTAMP,
description TEXT,
@@ -45,7 +46,6 @@ CREATE TABLE IF NOT EXISTS players (
user_id INTEGER,
game_id INTEGER,
role TEXT,
- UNIQUE ( game_id, user_id, role ),
UNIQUE ( game_id, role )
);
@@ -75,6 +75,12 @@ BEGIN
roles.title_id = games.title_id AND
games.game_id = new.game_id AND
roles.role = new.role ) <> 1
+ AND new.role <> 'Random 1'
+ AND new.role <> 'Random 2'
+ AND new.role <> 'Random 3'
+ AND new.role <> 'Random 4'
+ AND new.role <> 'Random 5'
+ AND new.role <> 'Random 6'
THEN RAISE(ABORT, "Invalid role for that title.")
END;
END;
diff --git a/views/create.ejs b/views/create.ejs
index ed9ae9e..5db8fe6 100644
--- a/views/create.ejs
+++ b/views/create.ejs
@@ -15,6 +15,11 @@ Description:<br>
<input type="text" autocomplete="off" id="description" name="description" size="50">
<p>
<label>
+<input type="checkbox" id="random" name="random" value="random">
+<span>Random player roles</span>
+</label>
+<p>
+<label>
<input type="checkbox" id="private" name="private" value="private">
<span>Private</span>
</label>
diff --git a/views/join.ejs b/views/join.ejs
index 810e0f4..42feaaf 100644
--- a/views/join.ejs
+++ b/views/join.ejs
@@ -11,9 +11,11 @@ function confirm_delete(status) {
<p>
Owner: <%= game.owner_name %>
-<p>
+<br>
+Private: <%= game.private ? "yes" : "no" %>
+<br>
Scenario: <%= game.scenario %>
-<p>
+<br>
Description: <%= game.description || "No description." %>
<br clear=left>
@@ -23,18 +25,18 @@ Description: <%= game.description || "No description." %>
<tr>
<%
roles.forEach((role) => {
- %><th><%= role.role %><%
+ %><th><%= role %><%
});
%>
<tr>
<%
roles.forEach((role) => {
- if (game.active == role.role || game.active == "Both" || game.active == "All") {
+ if (game.active == role || game.active == "Both" || game.active == "All") {
%><td style="min-width:9em" class="your_turn"><%
} else {
%><td style="min-width:9em"><%
}
- let p = players.find(p => p.role == role.role);
+ let p = players.find(p => p.role == role);
if (game.status == 0) {
if (p) {
if ((p.user_id == user.user_id) || (game.owner_id == user.user_id)) {
@@ -44,7 +46,7 @@ Description: <%= game.description || "No description." %>
%><%= p.name %><%
}
} else {
- %><a href="/join/<%= game.game_id %>/<%= role.role %>">Join</a><%
+ %><a href="/join/<%= game.game_id %>/<%= role %>">Join</a><%
}
} else {
if (p) {