diff --git a/client/public/assets/gfx/tiles-jungle.png b/client/public/assets/gfx/tiles-jungle.png
new file mode 100755
index 0000000..3752abc
Binary files /dev/null and b/client/public/assets/gfx/tiles-jungle.png differ
diff --git a/client/src/Board.js b/client/src/Board.js
index 1edbd99..ece2c23 100644
--- a/client/src/Board.js
+++ b/client/src/Board.js
@@ -47,11 +47,13 @@ const Board = () => {
const [ turn, setTurn ] = useState({});
const [ state, setState ] = useState("");
const [ color, setColor ] = useState("");
+ const [ rules, setRules ] = useState({});
const [ longestRoadLength, setLongestRoadLength ] = useState(0);
const fields = useMemo(() => [
'signature', 'robber', 'robberName',
'pips', 'pipOrder', 'borders', 'borderOrder', 'tiles', 'tileOrder',
- 'placements', 'turn', 'state', 'color', 'longestRoadLength'
+ 'placements', 'turn', 'state', 'color', 'longestRoadLength',
+ 'rules'
], []);
console.log(`board - ws`, ws);
@@ -68,7 +70,8 @@ const Board = () => {
setRobber(data.update.robber);
}
- if ('robberName' in data.update && data.update.robberName !== robberName) {
+ if ('robberName' in data.update
+ && data.update.robberName !== robberName) {
setRobberName(data.update.robberName);
}
@@ -76,6 +79,11 @@ const Board = () => {
setState(data.update.state);
}
+ if ('rules' in data.update
+ && !equal(data.update.rules, rules)) {
+ setRules(data.update.rules);
+ }
+
if ('color' in data.update && data.update.color !== color) {
setColor(data.update.color);
}
@@ -485,8 +493,15 @@ const Board = () => {
const tile = Object.assign({},
tiles[order],
{ index: index++, left: x, top: y});
+ if ('tiles-start-facing-down' in rules
+ && rules[`tiles-start-facing-down`].enabled
+ && state !== 'normal'
+ && state !== 'winner') {
+ tile.type = 'jungle';
+ tile.card = 0;
+ }
let div = ;
if (++rowCount === rows[row]) {
@@ -550,7 +565,7 @@ const Board = () => {
}, [
signature, generated,
pips, pipOrder, borders, borderOrder, tiles, tileOrder,
- ws
+ ws, state, rules
]);
/* Re-render turn info after every render */
diff --git a/client/src/HouseRules.js b/client/src/HouseRules.js
index 8f914e3..da005c5 100644
--- a/client/src/HouseRules.js
+++ b/client/src/HouseRules.js
@@ -9,32 +9,32 @@ import "./HouseRules.css";
import { GlobalContext } from "./GlobalContext.js";
-const VictoryPoints = ({ ws, houseRules, field }) => {
+const VictoryPoints = ({ ws, rules, field }) => {
const minVP = 10;
- const [points, setPoints] = useState(houseRules[field].points || minVP);
- console.log(`house-rules - ${field} - `, houseRules[field]);
+ const [points, setPoints] = useState(rules[field].points || minVP);
+ console.log(`house-rules - ${field} - `, rules[field]);
- if (!(field in houseRules)) {
- houseRules[field] = {
+ if (!(field in rules)) {
+ rules[field] = {
points: minVP
}
};
- if (houseRules[field].points && houseRules[field].points !== points) {
- setPoints(houseRules[field].points);
+ if (rules[field].points && rules[field].points !== points) {
+ setPoints(rules[field].points);
}
const update = (value) => {
- let points = (houseRules[field].points || minVP) + value;
+ let points = (rules[field].points || minVP) + value;
if (points < minVP) {
return;
}
- if (points !== houseRules[field].points) {
+ if (points !== rules[field].points) {
setPoints(points);
- houseRules[field].points = points;
+ rules[field].points = points;
ws.send(JSON.stringify({
type: 'rules',
- houseRules
+ rules: rules
}));
}
};
@@ -52,9 +52,8 @@ const NotImplemented = () => {
const HouseRules = ({ houseRulesActive, setHouseRulesActive }) => {
const { ws } = useContext(GlobalContext);
- const [houseRules, setHouseRules] = useState(undefined);
+ const [rules, setRules] = useState(undefined);
const [state, setState] = useState(undefined);
- const [rules, setRules] = useState([]);
const [ruleElements, setRuleElements] = useState([]);
const fields = useMemo(() => [
'state', 'rules'
@@ -67,10 +66,11 @@ const HouseRules = ({ houseRulesActive, setHouseRulesActive }) => {
if ('state' in data.update && data.update.state !== state) {
setState(data.update.state);
}
- if ('rules' in data.update && !equal(data.update.rules, houseRules)) {
+ if ('rules' in data.update
+ && !equal(data.update.rules, rules)) {
console.log(`house-rules - setting house rules to `,
data.update.rules);
- setHouseRules(data.update.rules);
+ setRules(data.update.rules);
}
break;
default:
@@ -104,45 +104,43 @@ const HouseRules = ({ houseRulesActive, setHouseRulesActive }) => {
}*/
}, [setHouseRulesActive]);//ws, HouseRulesDismissed, setHouseRulesDismissed]);
- console.log(`house-rules - render - `, { houseRules });
+ console.log(`house-rules - render - `, { rules });
const setRule = useCallback((event, key) => {
- const rules = houseRules ? Object.assign({}, houseRules) : {};
if (!(key in rules)) {
rules[key] = { enabled: false };
}
rules[key].enabled = !rules[key].enabled;
console.log(`house-rules - set ${key} - ${rules[key].enabled}`);
- setHouseRules(rules);
+ setRules(Object.assign({}, rules));
ws.send(JSON.stringify({
type: 'rules',
- houseRules: rules
+ rules
}));
- }, [ws, houseRules]);
+ }, [ws, rules]);
useEffect(() => {
- const _rules = [ {
+ setRuleElements([ {
title: `More victory points`,
key: `victory-points`,
- description: `Customize how many Victory Points are required to win. ` +
- `The minimum number of Victory Points is 10.`,
- element: ,
implemented: true
}, {
title: `Tiles start facing down`,
key: `tiles-start-facing-down`,
- description: `Flip resource tiles upside - down while placing starting settlements.`,
- element: ,
+ description: `Resource tiles start upside-down while placing starting settlements.`,
+ element:
Once all players have placed their initial settlements
+ and roads, the tiles are flipped and you discover what the
+ resources are.
,
+ implemented: true
}, {
title: `Bribery`,
key: `bribery`,
description: `Dissuade enemies from robbing you by offering resources voluntarily.`,
element: ,
}, {
@@ -150,7 +148,7 @@ const HouseRules = ({ houseRulesActive, setHouseRulesActive }) => {
key: `king-of-the-hill`,
description: `Keep your lead for one full turn after you reach max victory points.`,
element: ,
}, {
@@ -158,7 +156,7 @@ const HouseRules = ({ houseRulesActive, setHouseRulesActive }) => {
key: `everyone-gets-one-reroll`,
description: `Each player gets one chance re - roll at any point.`,
element: ,
}, {
@@ -166,7 +164,7 @@ const HouseRules = ({ houseRulesActive, setHouseRulesActive }) => {
key: `the-bridge`,
description: `Build a super-bridge across one resource tile.`,
element: ,
}, {
@@ -174,7 +172,7 @@ const HouseRules = ({ houseRulesActive, setHouseRulesActive }) => {
key: `discard-desert`,
description: `Scrap the desert in favour of an additional resource tile.`,
element: ,
}, {
@@ -182,7 +180,7 @@ const HouseRules = ({ houseRulesActive, setHouseRulesActive }) => {
key: `roll-double-roll-again`,
description: `Roll again if you roll two of the same number.`,
element: ,
}, {
@@ -196,7 +194,7 @@ const HouseRules = ({ houseRulesActive, setHouseRulesActive }) => {
key: `crime-and-punishment`,
description: `Change how the robber works to make Catan more or less competitive.`,
element: ,
}, {
@@ -204,7 +202,7 @@ const HouseRules = ({ houseRulesActive, setHouseRulesActive }) => {
key: `credit`,
description: `Trade with resources you don't have.`,
element: ,
} ]
@@ -220,24 +218,20 @@ const HouseRules = ({ houseRulesActive, setHouseRulesActive }) => {
return +1;
}
return A.title.localeCompare();
- });
-
- setRules(_rules);
-
- setRuleElements(_rules
+ })
.map(item => {
const disabled = (state !== 'lobby' || !item.implemented),
- defaultChecked = houseRules
- && (item.key in houseRules)
- ? houseRules[item.key].enabled
+ defaultChecked = rules
+ && (item.key in rules)
+ ? rules[item.key].enabled
: false;
console.log(`house-rules - ${item.key} - `,
- { houseRules, defaultChecked, disabled });
+ { rules, defaultChecked, disabled });
return
@@ -254,7 +248,7 @@ const HouseRules = ({ houseRulesActive, setHouseRulesActive }) => {
{ defaultChecked && item.element }
}));
- }, [houseRules, setRules, setRule ]);
+ }, [rules, setRules, setRuleElements, state, ws ]);
if (!houseRulesActive) {
return <>>;
diff --git a/server/routes/games.js b/server/routes/games.js
index f75de8a..7b0dc87 100755
--- a/server/routes/games.js
+++ b/server/routes/games.js
@@ -292,8 +292,8 @@ const distributeResources = (game, roll) => {
if (!tile.robber) {
receives[active.color][resource.type] += count;
} else {
- if (`robin-hood-robber` in game.houseRules
- && game.houseRules[`robin-hood-robber`].enabled
+ if (`robin-hood-robber` in game.rules
+ && game.rules[`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} ` +
@@ -2568,43 +2568,51 @@ const placeRoad = (game, session, index) => {
const getVictoryPointRule = (game) => {
const minVP = 10;
- if (!('victory-points' in game.houseRules)
- || !game.houseRules['victory-points'].enabled) {
+ if (!('victory-points' in game.rules)
+ || !game.rules['victory-points'].enabled) {
return minVP;
}
- return game.houseRules['victory-pionts'].points;
+ return game.rules['victory-pionts'].points;
}
-const setHouseRules = (game, session, houseRules) => {
+const setRules = (game, session, rules) => {
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])) {
+ for (let rule in rules) {
+ if (equal(game.rules[rule], rules[rule])) {
continue;
}
switch (rule) {
case 'victory-points':
- if (!('points' in houseRules[rule])) {
+ if (!('points' in rules[rule])) {
return `No points specified for victory-points`;
}
- if (!houseRules[rule].enabled) {
+ if (!rules[rule].enabled) {
addChatMessage(game, null,
`${getName(session)} has disabled the Victory Point ` +
`house rule.`);
} else {
addChatMessage(game, null,
`${getName(session)} set the minimum Victory Points to ` +
- `${houseRules[rule].points}`);
+ `${rules[rule].points}`);
}
- game.houseRules[rule] = houseRules[rule];
+ game.rules[rule] = rules[rule];
+ break;
+ case 'tiles-start-facing-down':
+ addChatMessage(game, null,
+ `${getName(session)} has ${rules[rule].enabled ? 'en' : 'dis'}abled the Tiles Start Facing Down house rule.`);
+ if (rules[rule].enabled) {
+ shuffle(game, session);
+ }
+ game.rules[rule] = rules[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];
+ `${getName(session)} has ${rules[rule].enabled ? 'en' : 'dis'}abled the Robin Hood Robber house rule.`);
+ game.rules[rule] = rules[rule];
break;
default:
return `Rule ${rule} not recognized.`;
@@ -2612,7 +2620,7 @@ const setHouseRules = (game, session, houseRules) => {
}
sendUpdateToPlayers(game, {
- rules: game.houseRules,
+ rules: game.rules,
chat: game.chat
});
};
@@ -3725,7 +3733,7 @@ router.ws("/ws/:id", async (ws, req) => {
update[field] = game[field];
break;
case 'rules':
- update[field] = game.houseRules ? game.houseRules : {};
+ update[field] = game.rules ? game.rules : {};
break;
case 'name':
update.name = session.name;
@@ -3949,8 +3957,8 @@ router.ws("/ws/:id", async (ws, req) => {
break;
case 'rules':
console.log(`${short} - <- rules:${getName(session)} - `,
- data.houseRules);
- warning = setHouseRules(game, session, data.houseRules);
+ data.rules);
+ warning = setRules(game, session, data.rules);
if (warning) {
sendWarning(session, warning);
}
@@ -4303,7 +4311,7 @@ const createGame = (id) => {
sessions: {},
unselected: [],
active: 0,
- houseRules: {
+ rules: {
'victory-points': {
points: 10
}