1
0

House settlement is now shaped during selection

Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
James Ketrenos 2022-02-11 17:40:22 -08:00
parent 872cf41404
commit 3fe70fa739
4 changed files with 166 additions and 3 deletions

View File

@ -40,6 +40,10 @@
filter: drop-shadow(0px 0px 5px rgba(255, 255, 0, 0.9)); filter: drop-shadow(0px 0px 5px rgba(255, 255, 0, 0.9));
} }
.Pip.Active.Option {
filter: brightness(150%) drop-shadow(0px 0px 5px rgba(255, 255, 0, 0.9));
}
.Pips[disabled], .Pips[disabled],
.Tiles[disabled], .Tiles[disabled],
.Roads[disabled], .Roads[disabled],
@ -71,6 +75,7 @@
bottom: 0px; bottom: 0px;
} }
.Corner:not([data-type]) .Corner-Shape,
.Corner[data-type="settlement"] .Corner-Shape { .Corner[data-type="settlement"] .Corner-Shape {
clip-path: polygon(50% 0%,70% 15%,70% 2%,90% 2%,90% 30%,100% 40%,100% 100%,65% 100%,65% 65%,35% 65%,35% 100%,0% 100%,0% 40%); clip-path: polygon(50% 0%,70% 15%,70% 2%,90% 2%,90% 30%,100% 40%,100% 100%,65% 100%,65% 65%,35% 65%,35% 100%,0% 100%,0% 40%);
} }
@ -128,6 +133,13 @@
filter: brightness(150%); filter: brightness(150%);
} }
.Option .Pip-Shape,
.Option .Tile-Shape,
.Option .Corner-Shape,
.Option .Road-Shape {
background-color: rgba(255, 255, 255, 0.5);
}
.Robber .Pip-Shape, .Robber .Pip-Shape,
.Pip-Shape:hover { .Pip-Shape:hover {
clip-path: circle(45%); /* show through the border */ clip-path: circle(45%); /* show through the border */
@ -140,7 +152,7 @@
.Tile-Shape:hover, .Tile-Shape:hover,
.Corner-Shape:hover, .Corner-Shape:hover,
.Road-Shape:hover { .Road-Shape:hover {
/* background-color: white;*/ background-color: white;
filter: brightness(150%); filter: brightness(150%);
} }

View File

@ -12,6 +12,7 @@
display: flex; display: flex;
margin-right: 40vw; margin-right: 40vw;
justify-content: space-between; justify-content: space-between;
align-items: flex-end;
} }
.WaitingForPlayer { .WaitingForPlayer {
@ -81,6 +82,60 @@
margin: 0 0.25em; margin: 0 0.25em;
} }
.SelectPlayer {
display: flex;
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
justify-content: center;
align-items: center;
background: rgba(0,0,0,0.5);
z-index: 1000;
}
.SelectPlayer .Title {
align-self: center;
padding: 2px;
font-weight: bold;
}
.SelectPlayer .SelectPlayerList {
display: flex;
flex-direction: column;
justify-content: flex-start;
padding: 0.5em;
background-color:rgba(224, 224, 224);
margin: 0.5em 0;
}
.SelectPlayer > * {
width: 20em;
display: inline-flex;
padding: 0.5em;
flex-direction: column;
}
.SelectPlayer .PlayerColor {
width: 1em;
height: 1em;
}
.SelectPlayer .SelectPlayerItem {
display: flex;
flex-direction: row;
width: 100%;
align-items: center;
padding: 2px 0;
cursor: pointer;
}
.SelectPlayer > * {
margin: 0 0.25em;
}
.Display { .Display {
display: inline-block; display: inline-block;
position: absolute; position: absolute;

View File

@ -336,6 +336,41 @@ const GameOrder = ({table}) => {
); );
}; };
const SelectPlayer = ({table, players}) => {
const playerClick = (event) => {
table.stealResource(event.currentTarget.getAttribute('data-color'));
}
if (!table.game) {
return (<></>);
}
let list = players.map(color => {
let item = {
color: color,
name: getPlayerName(table.game.sessions, color)
};
return <div className="SelectPlayerItem"
onClick={playerClick}
data-color={color}
key={`player-${item.color}`}>
<PlayerColor color={item.color}/>
<div>{item.name}</div>
</div>;
});
return (
<div className="SelectPlayer">
{ table.game && <Paper>
<div className="Title">Select Player to Steal From</div>
<div className="SelectPlayerList">
{ list }
</div>
</Paper> }
</div>
);
};
const Action = ({ table }) => { const Action = ({ table }) => {
const discardClick = (event) => { const discardClick = (event) => {
const nodes = document.querySelectorAll('.Hand .Selected'), const nodes = document.querySelectorAll('.Hand .Selected'),
@ -695,6 +730,10 @@ class Table extends React.Component {
return this.sendAction('place-road', road); return this.sendAction('place-road', road);
} }
stealResource(color) {
return this.sendAction('steal-resource', color);
}
throwDice() { throwDice() {
return this.rollDice(); return this.rollDice();
@ -856,7 +895,7 @@ class Table extends React.Component {
message = <>{message}<PlayerColor color={color}/> {name} needs to discard {discard} resources.</>; message = <>{message}<PlayerColor color={color}/> {name} needs to discard {discard} resources.</>;
} }
} }
if (move) { if (move && (this.game.turn && !this.game.turn.placedRobber)) {
message = <>{message}<PlayerColor color={this.game.turn.color}/> {this.game.turn.name} needs to move the robber.</> message = <>{message}<PlayerColor color={this.game.turn.color}/> {this.game.turn.name} needs to move the robber.</>
} }
} }
@ -992,6 +1031,13 @@ class Table extends React.Component {
<GameOrder table={this}/> <GameOrder table={this}/>
} }
{ game && game.state === 'normal' &&
game.turn &&
game.turn.color == game.color &&
game.turn.actions && game.turn.actions.indexOf('steal-resource') !== -1 &&
<SelectPlayer table={this} players={game.turn.limits.players}/>
}
{ game && game.turn && game.turn.color !== game.color && { game && game.turn && game.turn.color !== game.color &&
(game.state === 'initial-placement' || game.state === 'normal') && (game.state === 'initial-placement' || game.state === 'normal') &&
(!game.player || !game.player.mustDiscard) && <WaitingForPlayer table={this}/> (!game.player || !game.player.mustDiscard) && <WaitingForPlayer table={this}/>

View File

@ -354,6 +354,7 @@ const processRoll = (game, dice) => {
game.turn.roll = game.dice[0] + game.dice[1]; game.turn.roll = game.dice[0] + game.dice[1];
if (game.turn.roll === 7) { if (game.turn.roll === 7) {
addChatMessage(game, null, `ROBBER! ROBBER! ROBBER!`); addChatMessage(game, null, `ROBBER! ROBBER! ROBBER!`);
delete game.turn.placedRobber;
for (let id in game.sessions) { for (let id in game.sessions) {
const player = game.sessions[id].player; const player = game.sessions[id].player;
if (player) { if (player) {
@ -906,7 +907,54 @@ router.put("/:id/:action/:value?", async (req, res) => {
game.robber = robber; game.robber = robber;
game.turn.placedRobber = true; game.turn.placedRobber = true;
addChatMessage(game, session, `Robber has been moved!`); addChatMessage(game, session, `Robber has been moved!`);
addChatMessage(game, null, 'TODO: Look up which players are on tile, then allow robber-roller to select which player to steal from.');
let colors = [];
layout.tiles[robber].corners.forEach(cornerIndex => {
const active = game.placements.corners[cornerIndex];
if (active && active.color && active.color !== game.turn.color && colors.indexOf(active.color) == -1) {
colors.push(active.color);
}
});
if (colors.length) {
game.turn.actions = [ 'steal-resource' ],
game.turn.limits = { players: colors };
addChatMessage(game, session, `${session.name} must select player to steal resource from.`);
} else {
game.turn.actions = [];
delete game.turn.limits;
addChatMessage(game, session, `The Robber was moved to a terrain with no other players.`);
}
break;
case 'steal-resource':
if (game.turn.actions.indexOf('steal-resource') === -1) {
error = `You can only steal a resource when it is valid to do so!`;
break;
}
if (game.turn.limits.players.indexOf(value) === -1) {
error = `You can only steal a resource from a player on this terrain!`;
break;
}
let victim = game.players[value];
const cards = [];
[ 'wheat', 'brick', 'sheep', 'stone', 'wood' ].forEach(field => {
for (let i = 0; i < victim[field]; i++) {
cards.push(field);
}
});
if (cards.length === 0) {
addChatMessage(game, session, `Victim did not have any cards to steal.`);
} else {
let index = Math.floor(Math.random() * cards.length),
type = cards[index];
victim[type]--;
session.player[type]++
game.turn.actions = [];
game.turn.limits = {};
addChatMessage(game, session,
`${session.name} randomly stole ${type} from ${playerNameFromColor(game, value)}.`);
}
break; break;
case 'place-settlement': case 'place-settlement':
if (game.state !== 'initial-placement' && game.state !== 'normal') { if (game.state !== 'initial-placement' && game.state !== 'normal') {
@ -1157,8 +1205,10 @@ const sendGame = async (req, res, game, error) => {
game.turn.limits.pips.push(i); game.turn.limits.pips.push(i);
} }
} else { } else {
/*
game.turn.limits = {}; game.turn.limits = {};
game.turn.actions = []; game.turn.actions = [];
*/
} }
} }