From 6e3fe01df5df5ce6bab50f7ac61870c80b8e29f9 Mon Sep 17 00:00:00 2001 From: James Ketrenos Date: Sun, 27 Mar 2022 01:59:25 -0700 Subject: [PATCH] Implemented Robin Hood Robber Signed-off-by: James Ketrenos --- client/src/App.css | 2 +- client/src/HouseRules.css | 11 +++++++--- client/src/HouseRules.js | 26 +++++++++++++---------- server/package.json | 2 +- server/routes/games.js | 43 ++++++++++++++++++++++++++++++--------- 5 files changed, 58 insertions(+), 26 deletions(-) diff --git a/client/src/App.css b/client/src/App.css index a7cadc0..fe6b011 100755 --- a/client/src/App.css +++ b/client/src/App.css @@ -168,6 +168,7 @@ body { right: 0; bottom: 0; } + .Table .ChooseCard { display: flex; position: relative; @@ -187,7 +188,6 @@ body { padding: 0.25rem 0.55rem; } - .Table button:disabled { opacity: 0.5; border: 1px solid #ccc; /* why !important */ diff --git a/client/src/HouseRules.css b/client/src/HouseRules.css index 35ecc17..4faa90f 100644 --- a/client/src/HouseRules.css +++ b/client/src/HouseRules.css @@ -19,7 +19,6 @@ margin: 0.5em; width: 40em; display: inline-flex; - padding: 0.5em; flex-direction: column; } @@ -34,16 +33,22 @@ .HouseRules .HouseRule { display: flex; flex-direction: column; - align-items: center; + align-items: flex-start; + padding: 0 0.5rem; } .HouseRules .Title { + padding-bottom: 0.5rem; align-self: center; - padding: 2px; + padding: 0.5rem; font-weight: bold; margin-bottom: 0.5em; } +.HouseRules .HouseRule[data-enabled="true"] { + background-color: rgb(255, 254, 206); +} + .HouseRules .HouseRule b { margin: 0;/* 0.25rem;*/ } diff --git a/client/src/HouseRules.js b/client/src/HouseRules.js index f6b3610..6efc3d2 100644 --- a/client/src/HouseRules.js +++ b/client/src/HouseRules.js @@ -108,13 +108,14 @@ const HouseRules = ({ houseRulesActive, setHouseRulesActive }) => { const setRule = useCallback((event, key) => { const rules = houseRules ? Object.assign({}, houseRules) : {}; if (!(key in rules)) { - rules[key] = { enabled: true }; + rules[key] = { enabled: false }; } rules[key].enabled = !rules[key].enabled; + console.log(`house-rules - set ${key} - ${rules[key].enabled}`); setHouseRules(rules); ws.send(JSON.stringify({ type: 'rules', - houseRules + houseRules: rules })); }, [ws, houseRules]); @@ -185,11 +186,8 @@ const HouseRules = ({ houseRulesActive, setHouseRulesActive }) => { }, { title: `Robin Hood robber`, key: `robin-hood-robber`, - description: `Robbers can't steal from players with fewer than two victory points.`, - element: , + description: `Robbers can't steal from players with two or less victory points.`, + element: <> }, { title: `Crime and Punishment`, key: `crime-and-punishment`, @@ -206,7 +204,8 @@ const HouseRules = ({ houseRulesActive, setHouseRulesActive }) => { ws, houseRules, field: `credit` }} />, - } ].map(item => { + } ] + .map(item => { const disabled = (state !== 'lobby'), defaultChecked = houseRules && (item.key in houseRules) @@ -214,19 +213,24 @@ const HouseRules = ({ houseRulesActive, setHouseRulesActive }) => { : false; console.log(`house-rules - ${item.key} - `, { houseRules, defaultChecked, disabled }); - return
+ return
{item.title}: {item.description}
setRule(e, item.key)} {...{ disabled }} />
{ defaultChecked && item.element }
})); - }, [houseRules, setRules ]); + }, [houseRules, setRules, setRule ]); if (!houseRulesActive) { return <>; diff --git a/server/package.json b/server/package.json index f3933cf..3a4daab 100644 --- a/server/package.json +++ b/server/package.json @@ -2,7 +2,6 @@ "name": "peddlers-of-ketran-server", "version": "1.0.0", "main": "app.js", - "devDependencies": {}, "scripts": { "start": "export $(cat ../.env | xargs) && node app.js" }, @@ -19,6 +18,7 @@ "express": "^4.17.3", "express-session": "^1.17.1", "express-ws": "^5.0.2", + "fast-deep-equal": "^3.1.3", "handlebars": "^4.7.6", "moment": "^2.24.0", "morgan": "^1.9.1", diff --git a/server/routes/games.js b/server/routes/games.js index 7005f32..f75de8a 100755 --- a/server/routes/games.js +++ b/server/routes/games.js @@ -6,8 +6,8 @@ const express = require("express"), { readFile, writeFile } = require("fs").promises, fs = require("fs"), accessSync = fs.accessSync, - randomWords = require("random-words"); - + randomWords = require("random-words"), + equal = require("fast-deep-equal"); const layout = require('./layout.js'); const MAX_SETTLEMENTS = 5; @@ -292,8 +292,19 @@ const distributeResources = (game, roll) => { if (!tile.robber) { receives[active.color][resource.type] += count; } else { - trackTheft(game, active.color, 'robber', resource.type, count); - receives.robber[resource.type] += count; + if (`robin-hood-robber` in game.houseRules + && game.houseRules[`robin-hood-robber`].enabled + && game.players[active.color].points <= 2) { + addChatMessage(game, null, `Robber does not steal ${count} + ${resource.type} from ${game.players[active.color].name} ` + + `due to Robin Hood Robber house rule.`); + console.log(`robin-hood-robber`, game.players[active.color], + active.color); + receives[active.color][resource.type] += count; + } else { + trackTheft(game, active.color, 'robber', resource.type, count); + receives.robber[resource.type] += count; + } } } }) @@ -1277,7 +1288,8 @@ const calculateRoadLengths = (game, session) => { if (debug.road) console.log('Graphs B:', graphs); - if (debug.road) console.log('Pre update:', game.placements.roads.filter(road => road.color)); + if (debug.road) console.log('Pre update:', + game.placements.roads.filter(road => road.color)); for (let color in game.players) { if (game.players[color] === 'Not active') { @@ -1299,7 +1311,8 @@ const calculateRoadLengths = (game, session) => { game.placements.roads.forEach(road => delete road.walking); - if (debug.road) console.log('Post update:', game.placements.roads.filter(road => road.color)); + if (debug.road) console.log('Post update:', + game.placements.roads.filter(road => road.color)); let checkForTies = false; @@ -2566,8 +2579,12 @@ const setHouseRules = (game, session, houseRules) => { if (game.state !== 'lobby') { return `You can not modify House Rules once the game has started.`; } - + for (let rule in houseRules) { + if (equal(game.houseRules[rule], houseRules[rule])) { + continue; + } + switch (rule) { case 'victory-points': if (!('points' in houseRules[rule])) { @@ -2584,10 +2601,16 @@ const setHouseRules = (game, session, houseRules) => { } game.houseRules[rule] = houseRules[rule]; break; + case 'robin-hood-robber': + addChatMessage(game, null, + `${getName(session)} has ${houseRules[rule].enabled ? 'en' : 'dis'}abled the Robin Hood Robber house rule.`); + game.houseRules[rule] = houseRules[rule]; + break; default: return `Rule ${rule} not recognized.`; } } + sendUpdateToPlayers(game, { rules: game.houseRules, chat: game.chat @@ -3275,7 +3298,8 @@ const sendUpdateToPlayer = async (game, session, update) => { }); if (!session.ws) { - console.log(`${session.id}: -> sendUpdateToPlayer: Currently no connection.`); + console.log(`${session.id}: -> sendUpdateToPlayer: ` + + `Currently no connection.`); } else { session.ws.send(message); } @@ -3379,9 +3403,8 @@ const calculatePoints = (game, update) => { } }); - if (player.points === currentPoints) { - return; + continue; } if (player.points < getVictoryPointRule(game)) {