Syncing multi-player actions.
This commit is contained in:
@@ -43,7 +43,7 @@ import { setSelectedCard, setMessagePanelSpace, setMPDims, movePlayer,
|
||||
nextUIAction, alert } from './actions.js'
|
||||
import { buy, roll, endTurn, loan, trade, submitTradeAccept,
|
||||
submitTradeDeny, submitTradeCancel, audit,
|
||||
buyUncleBert } from './interface.js'
|
||||
buyUncleBert, skip } from './interface.js'
|
||||
|
||||
function netWorth(player) {
|
||||
return ((player.assets.hay + player.assets.grain) * 2000) +
|
||||
@@ -594,7 +594,9 @@ class Die extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { num: props.roll ? this.roll() : props.num,
|
||||
finalFace: false }
|
||||
finalFace: false,
|
||||
autoSkip: typeof props.autoSkip === 'undefined' ? false :
|
||||
props.autoSkip };
|
||||
this.trigger = 1000 * this.speed[props.speed ? props.speed : 'fast']
|
||||
if (props.ms) {
|
||||
this.maxTicks = Math.floor(props.ms / this.trigger);
|
||||
@@ -657,7 +659,10 @@ class Die extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
skip() {
|
||||
skip(preventAutoSkip) {
|
||||
if (!preventAutoSkip) {
|
||||
skip('die');
|
||||
}
|
||||
clearInterval(this.timerId);
|
||||
this.timerId = false;
|
||||
this.setState({ num: this.props.num, finalFace: true });
|
||||
@@ -670,6 +675,16 @@ class Die extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
if (this.state.autoSkip !== this.props.autoSkip) {
|
||||
if (this.state.autoSkip === false &&
|
||||
this.props.autoSkip) {
|
||||
this.skip(true);
|
||||
}
|
||||
this.setState({ autoSkip: this.props.autoSkip });
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
let face;
|
||||
switch (this.state.num) {
|
||||
@@ -751,6 +766,7 @@ class Rolling extends React.Component {
|
||||
<Die decay={true} num={this.props.num} ms={2000} roll={true}
|
||||
showScreen={this.props.showScreen}
|
||||
skip={this.props.skip}
|
||||
autoSkip={this.props.autoSkip}
|
||||
showScreenDelay={this.props.showScreenDelay} />
|
||||
</GroupBox>
|
||||
);
|
||||
@@ -765,21 +781,43 @@ class Harvest extends React.Component {
|
||||
fruit: FruitImg,
|
||||
corn: CornImg }
|
||||
|
||||
viewOrder = ['roll', 'income', 'operating-expense', 'expense-value', false]
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { view: 'ready' }
|
||||
this.state = { view: 'ready',
|
||||
autoSkip: typeof props.autoSkip === 'undefined' ? false :
|
||||
props.autoSkip,
|
||||
autoSkipView: false };
|
||||
}
|
||||
|
||||
nextView = view => {
|
||||
this.setState({ view });
|
||||
nextView = (view, preventAutoSkip) => {
|
||||
const newView = view ? view :
|
||||
this.viewOrder[this.viewOrder.indexOf(this.state.view) + 1];
|
||||
this.setState({ view: newView });
|
||||
if (!preventAutoSkip) {
|
||||
skip('harvest|' + newView);
|
||||
}
|
||||
}
|
||||
|
||||
cropToImg = crop => {
|
||||
return this.cropsToImg[crop];
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
if (this.props.autoSkip &&
|
||||
typeof this.props.autoSkip === 'string' &&
|
||||
this.props.autoSkip.indexOf('harvest|') === 0 &&
|
||||
this.state.autoSkipView !== this.props.autoSkip.split('|')[1]) {
|
||||
this.nextView(this.props.autoSkip.split('|')[1], true);
|
||||
this.setState({ autoSkipView: this.props.autoSkip.split('|')[1] });
|
||||
}
|
||||
}
|
||||
|
||||
// this.props.player.name === this.props.game.currentPlayer TODO
|
||||
render() {
|
||||
let view;
|
||||
const isCurrentPlayer = this.props.player.name === this.props.game.currentPlayer;
|
||||
switch (this.state.view) {
|
||||
case 'ready':
|
||||
view = (
|
||||
@@ -791,7 +829,7 @@ class Harvest extends React.Component {
|
||||
Get ready to harvest <b>{this.props.acres}
|
||||
{this.props.crop === 'cows' ? ' head of cow' : ' acres'}</b>!
|
||||
</div>
|
||||
{this.props.player.name === this.props.game.currentPlayer ? (
|
||||
{isCurrentPlayer ? (
|
||||
<Button onClick={() => this.nextView('roll')}>
|
||||
Roll for harvest!
|
||||
</Button>
|
||||
@@ -804,6 +842,7 @@ class Harvest extends React.Component {
|
||||
view = (<Die decay={true} num={this.props.rolled} ms={2000} roll={true}
|
||||
showScreen={() => this.nextView('income')}
|
||||
skip={true}
|
||||
autoSkip={this.props.autoSkip === 'die'}
|
||||
showScreenDelay={2000} />);
|
||||
break;
|
||||
case 'income':
|
||||
@@ -813,14 +852,16 @@ class Harvest extends React.Component {
|
||||
<div className={'flex green'}>
|
||||
<FontAwesomeIcon icon={faDollarSign} size='6x' />
|
||||
<div>
|
||||
{this.props.player.name === this.props.game.currentPlayer ? 'You' :
|
||||
{isCurrentPlayer ? 'You' :
|
||||
this.props.game.currentPlayer} rolled a <b>{this.props.rolled}</b> and earned <b>${formatMoney(this.props.income)}</b>!
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='center spacer'>
|
||||
<Button onClick={() => this.nextView('operating-expense')}>Draw Operating Expense</Button>
|
||||
</div>
|
||||
</div>
|
||||
{isCurrentPlayer ? (
|
||||
<div className='center spacer'>
|
||||
<Button onClick={() => this.nextView('operating-expense')}>Draw Operating Expense</Button>
|
||||
</div>
|
||||
) : (<Fragment />)}
|
||||
</div>
|
||||
);
|
||||
break;
|
||||
@@ -833,9 +874,11 @@ class Harvest extends React.Component {
|
||||
dangerouslySetInnerHTML={{__html: this.props.contents}} />
|
||||
</GroupBox>
|
||||
</div>
|
||||
<div className='center spacer'>
|
||||
<Button onClick={() => this.nextView('expense-value')}>Continue</Button>
|
||||
</div>
|
||||
{isCurrentPlayer ? (
|
||||
<div className='center spacer'>
|
||||
<Button onClick={() => this.nextView('expense-value')}>Continue</Button>
|
||||
</div>
|
||||
) : (<Fragment />)}
|
||||
</Fragment>
|
||||
);
|
||||
break;
|
||||
@@ -846,16 +889,18 @@ class Harvest extends React.Component {
|
||||
<div className={'flex ' + (this.props.expenseValue < 0 ? 'red' : 'green')}>
|
||||
<FontAwesomeIcon icon={faDollarSign} size='6x' />
|
||||
<div>
|
||||
{this.props.player.name === this.props.game.currentPlayer ? 'You' :
|
||||
{isCurrentPlayer ? 'You' :
|
||||
this.props.game.currentPlayer} {this.props.expenseValue < 0 ? 'lost ' : 'gained '}
|
||||
${Math.abs(this.props.expenseValue)}!
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{isCurrentPlayer ? (
|
||||
<div className='center spacer'>
|
||||
<Button onClick={this.props.nextAction}>Continue</Button>
|
||||
</div>
|
||||
</div>
|
||||
) : (<Fragment />)}
|
||||
</div>
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -879,7 +924,9 @@ class Moving extends React.Component {
|
||||
this.props.player : this.props.game.otherPlayers
|
||||
.find(p => p.player.name === this.props.game.currentPlayer).player;
|
||||
const currentPos = from;
|
||||
this.state = { currentPos: currentPos < 0 ? currentPos + 49 : currentPos };
|
||||
this.state = { currentPos: currentPos < 0 ? currentPos + 49 : currentPos,
|
||||
autoSkip: typeof props.autoSkip === 'undefined' ? false :
|
||||
props.autoSkip };
|
||||
this.endPos = to;
|
||||
this.color = currentPlayer.color;
|
||||
// only for hurt back do we go backwards
|
||||
@@ -923,13 +970,26 @@ class Moving extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
skip() {
|
||||
skip(preventAutoSkip) {
|
||||
if (!preventAutoSkip) {
|
||||
skip('moving');
|
||||
}
|
||||
clearInterval(this.timerId);
|
||||
this.timerId = false;
|
||||
this.props.movePlayer(this.endPos, this.state.currentPos, this.color);
|
||||
this.setState({ currentPos: this.endPos });
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
if (this.state.autoSkip !== this.props.autoSkip) {
|
||||
if (this.state.autoSkip === false &&
|
||||
this.props.autoSkip) {
|
||||
this.skip(true);
|
||||
}
|
||||
this.setState({ autoSkip: this.props.autoSkip });
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
let buttons;
|
||||
if (this.props.player.name !== this.props.game.currentPlayer) {
|
||||
@@ -1036,6 +1096,7 @@ class Action extends React.Component {
|
||||
break;
|
||||
case 'harvest':
|
||||
view = (<Harvest rolled={this.props.ui.actionValue.rolled}
|
||||
autoSkip={this.props.ui.autoSkip}
|
||||
player={this.props.player}
|
||||
game={this.props.game}
|
||||
income={this.props.ui.actionValue.income}
|
||||
@@ -1043,6 +1104,7 @@ class Action extends React.Component {
|
||||
expenseValue={this.props.ui.actionValue.operatingExpenseValue}
|
||||
crop={this.props.ui.actionValue.crop}
|
||||
acres={this.props.ui.actionValue.acres}
|
||||
autoSkip={this.props.ui.autoSkip}
|
||||
nextAction={() => this.props.showNextAction()} />);
|
||||
buttons = (<Fragment />);
|
||||
break;
|
||||
@@ -1053,6 +1115,7 @@ class Action extends React.Component {
|
||||
game={this.props.game}
|
||||
spaces={this.props.spaces}
|
||||
movePlayer={this.props.movePlayer}
|
||||
autoSkip={this.props.ui.autoSkip}
|
||||
ui={this.props.ui}/>);
|
||||
buttons = (<Fragment />);
|
||||
break;
|
||||
@@ -1063,6 +1126,7 @@ class Action extends React.Component {
|
||||
game={this.props.game}
|
||||
spaces={this.props.spaces}
|
||||
movePlayer={this.props.movePlayer}
|
||||
autoSkip={this.props.ui.autoSkip}
|
||||
ui={this.props.ui} />);
|
||||
buttons = (<Fragment />);
|
||||
break;
|
||||
@@ -1079,6 +1143,7 @@ class Action extends React.Component {
|
||||
showScreen={this.props.player.name === this.props.game.currentPlayer
|
||||
? () => this.props.showNextAction()
|
||||
: false}
|
||||
autoSkip={this.props.ui.autoSkip}
|
||||
skip={this.props.player.name === this.props.game.currentPlayer}
|
||||
showScreenDelay={2000} />);
|
||||
buttons = (<Fragment />);
|
||||
|
||||
@@ -34,3 +34,4 @@ export const NEXT_UI_ACTION_SILENT = 'next-ui-action-silent'
|
||||
export const MARK_ACTION_CHANGE_HANDLED = 'mark-action-change-handled'
|
||||
export const ALERT = 'alert'
|
||||
export const ALERT_HANDLED = 'alert-handled'
|
||||
export const AUTO_SKIP = 'auto-skip'
|
||||
|
||||
@@ -19,13 +19,14 @@
|
||||
import { UPDATE_GAME, UPDATE_PLAYER, GAME_STATE, SET_SELECTED_CARD, SET_CARDS,
|
||||
SPACE_PUSH_PLAYER, SPACE_CLEAR_PLAYERS, SET_OLD_MESSAGES, MESSAGE_PANEL_SPACE,
|
||||
MP_MOUSE, SET_MP_DIMS, MARK_ACTION_CHANGE_HANDLED, SET_NEXT_ACTION,
|
||||
MOVE_PLAYER, NEXT_UI_ACTION, NEXT_UI_ACTION_SILENT, ALERT, ALERT_HANDLED
|
||||
} from './actionTypes.js'
|
||||
MOVE_PLAYER, NEXT_UI_ACTION, NEXT_UI_ACTION_SILENT, ALERT, ALERT_HANDLED,
|
||||
AUTO_SKIP } from './actionTypes.js'
|
||||
|
||||
export { updateGame, updatePlayer, gameState, setSelectedCard, setCards,
|
||||
spacePushPlayer, spaceClearPlayers, setOldMessages, setMessagePanelSpace,
|
||||
mpMouse, setMPDims, movePlayer, setNextAction, nextUIAction,
|
||||
markActionChangeHandled, nextUIActionSilent, alert, alertHandled }
|
||||
markActionChangeHandled, nextUIActionSilent, alert, alertHandled,
|
||||
autoSkip }
|
||||
|
||||
function updateGame(update) {
|
||||
return { type: UPDATE_GAME,
|
||||
@@ -113,3 +114,7 @@ function alert(value) {
|
||||
function alertHandled() {
|
||||
return { type: ALERT_HANDLED };
|
||||
}
|
||||
|
||||
function autoSkip(component) {
|
||||
return { type: AUTO_SKIP, component };
|
||||
}
|
||||
|
||||
@@ -23,12 +23,12 @@ import * as websocket from '../../websocket.js'
|
||||
|
||||
import { updateGame, updatePlayer, gameState, setSelectedCard, setCards,
|
||||
movePlayer, setOldMessages, markActionChangeHandled,
|
||||
mpMouse, rolled, setNextAction, nextUIAction, nextUIActionSilent, alert
|
||||
} from './actions.js'
|
||||
mpMouse, rolled, setNextAction, nextUIAction, nextUIActionSilent, alert,
|
||||
autoSkip } from './actions.js'
|
||||
|
||||
export { initialize, buy, roll, endTurn, loan, trade, submitTradeAccept,
|
||||
submitTradeDeny, submitTradeCancel, audit, handleMessage,
|
||||
nextAction, buyUncleBert, actionsFinished }
|
||||
nextAction, buyUncleBert, actionsFinished, skip }
|
||||
|
||||
let store;
|
||||
|
||||
@@ -94,6 +94,9 @@ function handleMessage(evt) {
|
||||
!store.getState().farm.ui.nextAction) {
|
||||
store.dispatch(alert(ALERTS.raiseMoney));
|
||||
}
|
||||
if (data.event === 'auto-skip') {
|
||||
store.dispatch(autoSkip(data.component));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -151,6 +154,10 @@ function actionsFinished() {
|
||||
sendCommand({ type: 'actions-finished' });
|
||||
}
|
||||
|
||||
function skip(component) {
|
||||
sendCommand({ type: 'skip', component });
|
||||
}
|
||||
|
||||
function initialize(st, sc) {
|
||||
store = st;
|
||||
sendCommand = sc;
|
||||
|
||||
@@ -20,8 +20,8 @@ import { UPDATE_GAME, UPDATE_PLAYER, GAME_STATE, SET_SELECTED_CARD, SET_CARDS,
|
||||
SPACE_PUSH_PLAYER, SPACE_CLEAR_PLAYERS,
|
||||
SET_OLD_MESSAGES, MESSAGE_PANEL_SPACE, MP_MOUSE,
|
||||
SET_MP_DIMS, MOVE_PLAYER, SET_NEXT_ACTION, NEXT_UI_ACTION,
|
||||
MARK_ACTION_CHANGE_HANDLED, NEXT_UI_ACTION_SILENT, ALERT, ALERT_HANDLED
|
||||
} from './actionTypes.js'
|
||||
MARK_ACTION_CHANGE_HANDLED, NEXT_UI_ACTION_SILENT, ALERT, ALERT_HANDLED,
|
||||
AUTO_SKIP } from './actionTypes.js'
|
||||
import { GAME_STATES } from '../../constants.js'
|
||||
import { spaceContent, corners } from 'game.js'
|
||||
|
||||
@@ -108,6 +108,7 @@ const initialState = {
|
||||
nextActionValue: null,
|
||||
actionChangeHandled: true,
|
||||
alert: false,
|
||||
autoSkip: false,
|
||||
alertHandled: false },
|
||||
spaces: spaces,
|
||||
space: null,
|
||||
@@ -164,6 +165,7 @@ export default function(state = initialState, action) {
|
||||
case NEXT_UI_ACTION:
|
||||
return { ...state, ui: { ...state.ui, action: state.ui.nextAction,
|
||||
actionValue: state.ui.nextActionValue,
|
||||
autoSkip: false,
|
||||
actionChangeHandled: !state.ui.nextAction }};
|
||||
case NEXT_UI_ACTION_SILENT: // don't set actionChangeHandled
|
||||
return { ...state, ui: { ...state.ui, action: state.ui.nextAction,
|
||||
@@ -176,6 +178,8 @@ export default function(state = initialState, action) {
|
||||
alertHandled: action.value === false ? true : false }};
|
||||
case ALERT_HANDLED:
|
||||
return { ...state, ui: { ...state.ui, alertHandled: true }};
|
||||
case AUTO_SKIP:
|
||||
return { ...state, ui: { ...state.ui, autoSkip: action.component }};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user