1
0

Settlement restriction on initial-placement for Volcano

Improved admin-command for roll

Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
James Ketrenos 2022-05-25 16:08:59 -07:00
parent 1c69cd23e9
commit 68e43fa3f7
2 changed files with 82 additions and 34 deletions

View File

@ -6,10 +6,17 @@ if [[ "${ADMIN}" == "" ]]; then
fi
id=$1
color=$2
shift
color=$1
shift
dice1=$1
shift
if [[ "$1" != "" ]]; then
dice2=",$1"
fi
if [[ "${id}" == "" ]] || [[ "${color}" == "" ]]; then
echo "Usage: roll GAME-ID (red|white|blue|orange)-DICE"
if [[ "${id}" == "" ]] || [[ "${color}" == "" ]] || [[ "$dice1" == "" ]]; then
echo "Usage: roll GAME-ID (red|white|blue|orange) DICE [DICE]"
exit 1
fi
@ -17,6 +24,6 @@ curl --noproxy '*' -s -L \
--request PUT \
--header "PRIVATE-TOKEN: ${ADMIN}" \
--header "Content-Type: application/json" \
http://localhost:8930/ketr.ketran/api/v1/games/${id}/roll/${color} |
jq -r .status
http://localhost:8930/ketr.ketran/api/v1/games/${id}/roll/${color}?dice=${dice1}${dice2}
# | jq -r .status

View File

@ -117,6 +117,7 @@ const processTies = (players) => {
});
let ties = false, position = 1;
const irstify = (position) => {
switch (position) {
case 1: return `1st`;
@ -126,7 +127,7 @@ const processTies = (players) => {
default: return position;
}
}
console.log(`Slots: `, slots);
/* Reverse from high to low */
slots.reverse().forEach((slot) => {
if (slot.length !== 1) {
@ -217,22 +218,24 @@ const processGameOrder = (game, player, dice) => {
});
}
const roll = (game, session) => {
const roll = (game, session, dice) => {
const player = session.player,
name = session.name ? session.name : "Unnamed";
if (!dice) {
dice = [ Math.ceil(Math.random() * 6), Math.ceil(Math.random() * 6) ];
}
switch (game.state) {
case "lobby": /* currently not available as roll is only after color is
* set for players */
addChatMessage(game, session, `${name} rolled ${Math.ceil(Math.random() * 6)}.`);
addChatMessage(game, session, `${name} rolled ${dice[0]}.`);
sendUpdateToPlayers(game, { chat: game.chat });
return;
case "game-order":
game.startTime = Date.now();
const dice = Math.ceil(Math.random() * 6);
addChatMessage(game, session, `${name} rolled ${dice}.`);
return processGameOrder(game, player, dice);
addChatMessage(game, session, `${name} rolled ${dice[0]}.`);
return processGameOrder(game, player, dice[0]);
case "normal":
if (game.turn.color !== session.color) {
@ -241,10 +244,21 @@ const roll = (game, session) => {
if (game.turn.roll) {
return `You already rolled this turn.`;
}
processRoll(game, session, [ Math.ceil(Math.random() * 6), Math.ceil(Math.random() * 6) ]);
processRoll(game, session, dice);
sendUpdateToPlayers(game, { chat: game.chat });
return;
case 'volcano-resource':
if (game.turn.color !== session.color) {
return `It is not your turn.`;
}
if (game.turn.volcano) {
return `You already rolled for the Volcano!`;
}
processVolcano(game, session, dice);
sendUpdateToPlayers(game, { chat: game.chat });
return;
default:
return `Invalid game state (${game.state}) in roll.`;
}
@ -621,7 +635,7 @@ const canGiveBuilding = (game) => {
}
}
const adminActions = (game, action, value) => {
const adminActions = (game, action, value, query) => {
let color, player, parts, session, corners, error;
switch (action) {
@ -745,32 +759,47 @@ const adminActions = (game, action, value) => {
return results;
case "roll":
parts = value.match(/^([1-6])(-([1-6]))?$/);
if (!parts) {
let dice = (query.dice || '').split(',');
dice = dice.map(die => parseInt(die));
if (!value) {
return `Unable to parse roll request.`;
}
let dice = [ parseInt(parts[1]) ];
if (parts[3]) {
dice.push(parseInt(parts[3]));
switch (value) {
case 'orange': color = 'O'; break;
case 'red': color = 'R'; break;
case 'blue': color = 'B'; break;
case 'white': color = 'W'; break;
}
for (let id in game.sessions) {
if (game.sessions[id].name === game.turn.name) {
session = game.sessions[id];
if (!color) {
return `Unable to find player ${value}`
}
const rollingPlayer = (color) => {
for (let id in game.sessions) {
if ((color
&& game.sessions[id].player
&& game.sessions[id].player.color === color)
|| (game.sessions[id].name === game.turn.name)) {
return game.sessions[id];
}
}
return undefined;
};
addChatMessage(game, null,
`Admin rolling ${dice.join(', ')} for ${value}.`);
if (game.state === 'game-order') {
session = rollingPlayer(color);
} else {
session = rollingPlayer();
}
if (!session) {
return `Unable to determine current player turn for admin roll.`;
}
console.log(dice, parts);
addChatMessage(game, null, `Admin rolling ${dice.join(', ')} for ${game.turn.name}.`);
switch (game.state) {
case 'game-order':
addActivity(game, session, `${game.turn.name} rolled ${dice[0]}.`);
processGameOrder(game, session.player, dice[0]);
break;
case 'normal':
processRoll(game, session, dice);
break;
let warning = roll(game, session, dice);
if (warning) {
sendWarning(session, warning);
}
break;
@ -1401,9 +1430,14 @@ const getValidCorners = (game, color, type) => {
*
* If we are limiting based on active player, a corner is only valid
* if it connects to a road that is owned by that player.
*
* If no color is set, walk each road that leaves that corner and
* check to see if there is a settlement placed at the end of that road
*
* If so, this location cannot have a settlement.
*
* If still valid, and we are in initial settlement placement, and if
* Volcano is enabled, verify the tile is not the Volcano.
*/
layout.corners.forEach((corner, cornerIndex) => {
const placement = game.placements.corners[cornerIndex];
@ -1431,7 +1465,8 @@ const getValidCorners = (game, color, type) => {
for (let r = 0; valid && r < corner.roads.length; r++) {
const road = layout.roads[corner.roads[r]];
for (let c = 0; valid && c < road.corners.length; c++) {
/* This side of the road is pointing to the corner being validated. Skip it. */
/* This side of the road is pointing to the corner being validated.
* Skip it. */
if (road.corners[c] === cornerIndex) {
continue;
}
@ -1443,7 +1478,11 @@ const getValidCorners = (game, color, type) => {
}
}
if (valid) {
limits.push(cornerIndex);
if (game.state !== 'initial-placement'
|| (isRuleEnabled(game, 'volcano')
&& layout.tiles[game.robber].corners.indexOf(cornerIndex) === -1)) {
limits.push(cornerIndex);
}
}
});
@ -1701,10 +1740,12 @@ router.put("/:id/:action/:value?", async (req, res) => {
if (req.headers['private-token'] !== req.app.get('admin')) {
error = `Invalid admin credentials.`;
} else {
error = adminActions(game, action, value);
error = adminActions(game, action, value, req.query);
}
if (!error) {
sendGameToPlayers(game);
} else {
console.log(`admin-action error: ${error}`);
}
}