|
|
@ -31,7 +31,8 @@ import { connect } from 'react-redux'
|
|
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
|
|
import { faUser, faUsers, faTractor, faWindowRestore,
|
|
|
|
import { faUser, faUsers, faTractor, faWindowRestore,
|
|
|
|
faDollarSign, faTimes, faAsterisk, faExchangeAlt,
|
|
|
|
faDollarSign, faTimes, faAsterisk, faExchangeAlt,
|
|
|
|
faInfoCircle, faArrowUp, faAward } from '@fortawesome/free-solid-svg-icons'
|
|
|
|
faInfoCircle, faArrowUp, faArrowDown, faAward,
|
|
|
|
|
|
|
|
faTimesCircle } from '@fortawesome/free-solid-svg-icons'
|
|
|
|
|
|
|
|
|
|
|
|
import { GroupBox, Row, Col, Button } from '../widgets.jsx'
|
|
|
|
import { GroupBox, Row, Col, Button } from '../widgets.jsx'
|
|
|
|
import SpaceNode from './SpaceNode.jsx'
|
|
|
|
import SpaceNode from './SpaceNode.jsx'
|
|
|
@ -40,7 +41,8 @@ import Tractor from '../tractor/Tractor.jsx'
|
|
|
|
import { GAME_STATES, ALERTS } from '../../constants.js'
|
|
|
|
import { GAME_STATES, ALERTS } from '../../constants.js'
|
|
|
|
import { itemCard, itemCardShort, fateCard, ridgeNames } from 'game.js'
|
|
|
|
import { itemCard, itemCardShort, fateCard, ridgeNames } from 'game.js'
|
|
|
|
import { setSelectedCard, setMessagePanelSpace, setMPDims, movePlayer,
|
|
|
|
import { setSelectedCard, setMessagePanelSpace, setMPDims, movePlayer,
|
|
|
|
nextUIAction, alert, alertHandled, setCardError } from './actions.js'
|
|
|
|
nextUIAction, alert, alertHandled, setCardError,
|
|
|
|
|
|
|
|
setMovingSkip } from './actions.js'
|
|
|
|
import { buy, roll, endTurn, loan, trade, submitTradeAccept,
|
|
|
|
import { buy, roll, endTurn, loan, trade, submitTradeAccept,
|
|
|
|
submitTradeDeny, submitTradeCancel, audit,
|
|
|
|
submitTradeDeny, submitTradeCancel, audit,
|
|
|
|
buyUncleBert, skip } from './interface.js'
|
|
|
|
buyUncleBert, skip } from './interface.js'
|
|
|
@ -174,7 +176,7 @@ class ResourceUnit extends React.Component {
|
|
|
|
render () {
|
|
|
|
render () {
|
|
|
|
const hslString = 'hsl(' + this.props.h + ', ' + this.props.s;
|
|
|
|
const hslString = 'hsl(' + this.props.h + ', ' + this.props.s;
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div className='resource-unit'
|
|
|
|
<div className={'resource-unit ' + (this.props.className ? this.props.className : '')}
|
|
|
|
title={this.props.amount + ' ' + this.props.label}
|
|
|
|
title={this.props.amount + ' ' + this.props.label}
|
|
|
|
style={{backgroundColor: hslString + '%, 85%)',
|
|
|
|
style={{backgroundColor: hslString + '%, 85%)',
|
|
|
|
borderTop: '3px solid ' + hslString + '%, 55%)'}}>
|
|
|
|
borderTop: '3px solid ' + hslString + '%, 55%)'}}>
|
|
|
@ -448,6 +450,363 @@ class TradeContainer extends React.Component {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const findPlayer = (game, name) => {
|
|
|
|
|
|
|
|
const ret = game.otherPlayers.find(p => p.player.name === name) || false;
|
|
|
|
|
|
|
|
return ret ? ret.player : ret;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const playerRidgeCows = player => {
|
|
|
|
|
|
|
|
return Object.values(player.ridges).reduce((a, b) => a + b, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const makeDefaultToTrade = () => {
|
|
|
|
|
|
|
|
return { hay: 0,
|
|
|
|
|
|
|
|
grain: 0,
|
|
|
|
|
|
|
|
fruit: 0,
|
|
|
|
|
|
|
|
cows: 0,
|
|
|
|
|
|
|
|
harvester: 0,
|
|
|
|
|
|
|
|
tractor: 0,
|
|
|
|
|
|
|
|
money: 0,
|
|
|
|
|
|
|
|
ridge1: false,
|
|
|
|
|
|
|
|
ridge2: false,
|
|
|
|
|
|
|
|
ridge3: false,
|
|
|
|
|
|
|
|
ridge4: false,
|
|
|
|
|
|
|
|
cards: ''
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TradeContainer2 extends React.Component {
|
|
|
|
|
|
|
|
resources = [{ img: HayImg,
|
|
|
|
|
|
|
|
h: '120',
|
|
|
|
|
|
|
|
s: '100',
|
|
|
|
|
|
|
|
label: 'acres of Hay',
|
|
|
|
|
|
|
|
key: 'hay',
|
|
|
|
|
|
|
|
amount: 10
|
|
|
|
|
|
|
|
}, {
|
|
|
|
|
|
|
|
img: WheatImg,
|
|
|
|
|
|
|
|
h: '41',
|
|
|
|
|
|
|
|
s: '100',
|
|
|
|
|
|
|
|
label: 'acres of Grain',
|
|
|
|
|
|
|
|
key: 'grain',
|
|
|
|
|
|
|
|
amount: 10
|
|
|
|
|
|
|
|
}, {
|
|
|
|
|
|
|
|
img: FruitImg,
|
|
|
|
|
|
|
|
h: '0',
|
|
|
|
|
|
|
|
s: '100',
|
|
|
|
|
|
|
|
label: 'acres of Fruit',
|
|
|
|
|
|
|
|
key: 'fruit',
|
|
|
|
|
|
|
|
amount: 5
|
|
|
|
|
|
|
|
}, {
|
|
|
|
|
|
|
|
img: CowImg,
|
|
|
|
|
|
|
|
h: '0',
|
|
|
|
|
|
|
|
s: '59',
|
|
|
|
|
|
|
|
label: 'head of Cows',
|
|
|
|
|
|
|
|
key: 'cows',
|
|
|
|
|
|
|
|
amount: 10
|
|
|
|
|
|
|
|
}, {
|
|
|
|
|
|
|
|
img: HarvesterImg,
|
|
|
|
|
|
|
|
h: '240',
|
|
|
|
|
|
|
|
s: '100',
|
|
|
|
|
|
|
|
label: 'Harvesters',
|
|
|
|
|
|
|
|
key: 'harvester',
|
|
|
|
|
|
|
|
amount: 1
|
|
|
|
|
|
|
|
}, {
|
|
|
|
|
|
|
|
img: TractorImg,
|
|
|
|
|
|
|
|
h: '240',
|
|
|
|
|
|
|
|
s: '100',
|
|
|
|
|
|
|
|
label: 'Tractors',
|
|
|
|
|
|
|
|
key: 'tractor',
|
|
|
|
|
|
|
|
amount: 1
|
|
|
|
|
|
|
|
}, {
|
|
|
|
|
|
|
|
icon: faDollarSign,
|
|
|
|
|
|
|
|
h: '100',
|
|
|
|
|
|
|
|
s: '83',
|
|
|
|
|
|
|
|
label: 'Cash',
|
|
|
|
|
|
|
|
key: 'money',
|
|
|
|
|
|
|
|
amount: 1
|
|
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
state = {
|
|
|
|
|
|
|
|
otherPlayer: findPlayer(this.props.game, this.props.game.otherPlayers.length > 0 ? this.props.game.otherPlayers[0].player.name : ''),
|
|
|
|
|
|
|
|
toTrade: makeDefaultToTrade()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
selectPlayer = e => {
|
|
|
|
|
|
|
|
this.setState({ otherPlayer: findPlayer(this.props.game, e.target.value) });
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
componentDidUpdate(prevProps) {
|
|
|
|
|
|
|
|
if (!this.state.otherPlayer &&
|
|
|
|
|
|
|
|
prevProps.game.otherPlayers.length !== this.props.game.otherPlayers.length) {
|
|
|
|
|
|
|
|
this.setState({ otherPlayer: findPlayer(this.props.game,
|
|
|
|
|
|
|
|
this.props.game.otherPlayers.length > 0 ? this.props.game.otherPlayers[0].player.name : '') });
|
|
|
|
|
|
|
|
} else if (this.state.otherPlayer && this.state.otherPlayer !== findPlayer(this.props.game, this.state.otherPlayer.name)) {
|
|
|
|
|
|
|
|
this.setState({ otherPlayer: findPlayer(this.props.game, this.state.otherPlayer.name) });
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (prevProps.player.trade.originator && !this.props.player.trade.originator) {
|
|
|
|
|
|
|
|
this.setState({ otherPlayer: findPlayer(this.props.game,
|
|
|
|
|
|
|
|
this.props.game.otherPlayers.length > 0 ? this.props.game.otherPlayers[0].player.name : ''),
|
|
|
|
|
|
|
|
toTrade: makeDefaultToTrade()
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
} else if (prevProps.player.trade.originator !== this.props.player.trade.originator) {
|
|
|
|
|
|
|
|
const isOriginator = this.props.player.trade.originator === this.props.player.name;
|
|
|
|
|
|
|
|
let tradeObj = {};
|
|
|
|
|
|
|
|
if (!isOriginator) {
|
|
|
|
|
|
|
|
Object.keys(this.props.player.trade).forEach(key => {
|
|
|
|
|
|
|
|
const value = this.props.player.trade[key];
|
|
|
|
|
|
|
|
switch (typeof value) {
|
|
|
|
|
|
|
|
case 'number':
|
|
|
|
|
|
|
|
tradeObj[key] = value * -1;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'boolean':
|
|
|
|
|
|
|
|
tradeObj[key] = value;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
tradeObj[key] = value;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
tradeObj = this.props.player.trade;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
|
|
|
|
toTrade: {
|
|
|
|
|
|
|
|
...makeDefaultToTrade(),
|
|
|
|
|
|
|
|
...tradeObj,
|
|
|
|
|
|
|
|
money: tradeObj.money ? tradeObj.money / 1000 : 0
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
otherPlayer: findPlayer(this.props.game, isOriginator ?
|
|
|
|
|
|
|
|
this.props.player.trade.player : this.props.player.trade.originator)
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tradeClass(amount) {
|
|
|
|
|
|
|
|
if (amount > 0) {
|
|
|
|
|
|
|
|
return 'trade-to';
|
|
|
|
|
|
|
|
} else if (amount < 0) {
|
|
|
|
|
|
|
|
return 'trade-from';
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
return '';
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tradeAsset = (asset, amount, verbatim) => {
|
|
|
|
|
|
|
|
this.setState(state => {
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
toTrade: {
|
|
|
|
|
|
|
|
...state.toTrade,
|
|
|
|
|
|
|
|
[asset]: (typeof amount === 'number') && !verbatim ? (state.toTrade[asset] + amount) : amount
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
propose = () => {
|
|
|
|
|
|
|
|
trade({ ...this.state.toTrade,
|
|
|
|
|
|
|
|
money: this.state.toTrade.money * 1000,
|
|
|
|
|
|
|
|
player: this.state.otherPlayer.name
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
render() {
|
|
|
|
|
|
|
|
const player = this.props.player,
|
|
|
|
|
|
|
|
otherPlayer = this.state.otherPlayer,
|
|
|
|
|
|
|
|
toTrade = this.state.toTrade,
|
|
|
|
|
|
|
|
tradeProposed = !!player.trade.originator;
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<GroupBox title='Trade'>
|
|
|
|
|
|
|
|
<Row>
|
|
|
|
|
|
|
|
<Col width="12">
|
|
|
|
|
|
|
|
<div className="trade-player-container">
|
|
|
|
|
|
|
|
<h4>{player.name}</h4>
|
|
|
|
|
|
|
|
{Object.keys(player.ridges).map((ridge, idx) => (
|
|
|
|
|
|
|
|
<Fragment key={'player-trade' + ridge}>
|
|
|
|
|
|
|
|
{!tradeProposed && (player.ridges[ridge] > 0) && !toTrade[ridge] ? (
|
|
|
|
|
|
|
|
<Button className="tiny"
|
|
|
|
|
|
|
|
onClick={() => this.tradeAsset(ridge, player.ridges[ridge], true)}>
|
|
|
|
|
|
|
|
<FontAwesomeIcon icon={faArrowDown} /> {ridgeNames[idx]} {'('}{player.ridges[ridge]} cows{')'}
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
) : (<></>)}
|
|
|
|
|
|
|
|
{' '}
|
|
|
|
|
|
|
|
</Fragment>
|
|
|
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
<div className='resource-unit-container'>
|
|
|
|
|
|
|
|
{this.resources.map((o, i) => {
|
|
|
|
|
|
|
|
let amount = o.key === 'money' ? Math.floor(player.cash / 1000) : player.assets[o.key];
|
|
|
|
|
|
|
|
if (o.key === 'cows') { amount = player.assets.cows - playerRidgeCows(player); }
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<ResourceUnit img={o.img ? o.img : false} h={o.h} s={o.s} label={o.label}
|
|
|
|
|
|
|
|
key={i}
|
|
|
|
|
|
|
|
className={o.key === 'money' ? 'double-width' : false}
|
|
|
|
|
|
|
|
amount={amount + Math.min(0, toTrade[o.key])}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
{o.icon ? (
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
|
|
|
<FontAwesomeIcon icon={o.icon} />(K)
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
) : ''}
|
|
|
|
|
|
|
|
{amount + Math.min(0, toTrade[o.key])}
|
|
|
|
|
|
|
|
{o.icon ? (<br />) : ''}
|
|
|
|
|
|
|
|
{!tradeProposed && ((amount + Math.min(0, toTrade[o.key])) > 0 || toTrade[o.key] > 0) ? (
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
|
|
|
<Button className="tiny"
|
|
|
|
|
|
|
|
onClick={() => this.tradeAsset(o.key, o.amount * -1)}>
|
|
|
|
|
|
|
|
<FontAwesomeIcon icon={faArrowDown} />
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
{o.key === 'money' && (amount + Math.min(0, toTrade[o.key])) >= 10 ? (
|
|
|
|
|
|
|
|
<Button className="tiny"
|
|
|
|
|
|
|
|
onClick={() => this.tradeAsset(o.key, o.amount * -10)}>
|
|
|
|
|
|
|
|
<FontAwesomeIcon icon={faArrowDown} />
|
|
|
|
|
|
|
|
<FontAwesomeIcon icon={faArrowDown} />
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
) : ''}
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
) : (<></>)}
|
|
|
|
|
|
|
|
</ResourceUnit>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
})}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
<Row>
|
|
|
|
|
|
|
|
<Col width="12">
|
|
|
|
|
|
|
|
{Object.keys(otherPlayer ? otherPlayer.ridges : []).map((ridge, idx) => (
|
|
|
|
|
|
|
|
<Fragment key={'to-trade' + ridge}>
|
|
|
|
|
|
|
|
{(otherPlayer.ridges[ridge] > 0) && toTrade[ridge] ? (
|
|
|
|
|
|
|
|
<Button className="tiny"
|
|
|
|
|
|
|
|
onClick={() => this.tradeAsset(ridge, false)}>
|
|
|
|
|
|
|
|
<FontAwesomeIcon icon={faArrowDown} /> {ridgeNames[idx]} {'('}{otherPlayer.ridges[ridge]} cows{')'}
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
) : (<></>)}
|
|
|
|
|
|
|
|
{' '}
|
|
|
|
|
|
|
|
</Fragment>
|
|
|
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
<Row>
|
|
|
|
|
|
|
|
<Col width="12">
|
|
|
|
|
|
|
|
<div className='resource-unit-container resources-to-trade'>
|
|
|
|
|
|
|
|
{this.resources.map((o, i) => (
|
|
|
|
|
|
|
|
<ResourceUnit h={o.h} s={o.s} label={o.label}
|
|
|
|
|
|
|
|
key={i}
|
|
|
|
|
|
|
|
className={(this.tradeClass(toTrade[o.key])) + (o.key === 'money' ? ' double-width' : '')}
|
|
|
|
|
|
|
|
amount={toTrade[o.key]}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
{Math.abs(toTrade[o.key])}
|
|
|
|
|
|
|
|
</ResourceUnit>
|
|
|
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
<Row>
|
|
|
|
|
|
|
|
<Col width="12">
|
|
|
|
|
|
|
|
{Object.keys(player.ridges).map((ridge, idx) => (
|
|
|
|
|
|
|
|
<Fragment key={'to-trade' + ridge}>
|
|
|
|
|
|
|
|
{(player.ridges[ridge] > 0) && toTrade[ridge] ? (
|
|
|
|
|
|
|
|
<Button className="tiny"
|
|
|
|
|
|
|
|
onClick={() => this.tradeAsset(ridge, false)}>
|
|
|
|
|
|
|
|
<FontAwesomeIcon icon={faArrowUp} /> {ridgeNames[idx]} {'('}{player.ridges[ridge]} cows{')'}
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
) : (<></>)}
|
|
|
|
|
|
|
|
{' '}
|
|
|
|
|
|
|
|
</Fragment>
|
|
|
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
<Row>
|
|
|
|
|
|
|
|
<Col width="12">
|
|
|
|
|
|
|
|
<div className="trade-player-container">
|
|
|
|
|
|
|
|
{otherPlayer ? (
|
|
|
|
|
|
|
|
<div className='resource-unit-container'>
|
|
|
|
|
|
|
|
{this.resources.map((o, i) => {
|
|
|
|
|
|
|
|
let amount = o.key === 'money' ? 99 : otherPlayer.assets[o.key];
|
|
|
|
|
|
|
|
if (o.key === 'cows') { amount = otherPlayer.assets.cows - playerRidgeCows(otherPlayer); }
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<ResourceUnit img={o.img ? o.img : false} h={o.h} s={o.s} label={o.label}
|
|
|
|
|
|
|
|
key={i}
|
|
|
|
|
|
|
|
className={o.key === 'money' ? 'double-width' : false}
|
|
|
|
|
|
|
|
amount={amount - Math.max(0, toTrade[o.key])}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
{o.icon ? (
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
|
|
|
<FontAwesomeIcon icon={o.icon} />(K)
|
|
|
|
|
|
|
|
<br />
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
) : ''}
|
|
|
|
|
|
|
|
{amount - Math.max(0, toTrade[o.key])}
|
|
|
|
|
|
|
|
{o.icon ? (<br />) : ''}
|
|
|
|
|
|
|
|
{!tradeProposed && ((amount - Math.max(0, toTrade[o.key])) > 0 || toTrade[o.key] < 0) ? (
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
|
|
|
<Button className="tiny"
|
|
|
|
|
|
|
|
onClick={() => this.tradeAsset(o.key, o.amount)}>
|
|
|
|
|
|
|
|
<FontAwesomeIcon icon={faArrowUp} />
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
{o.key === 'money' && (amount - Math.min(0, toTrade[o.key])) >= 10 ? (
|
|
|
|
|
|
|
|
<Button className="tiny"
|
|
|
|
|
|
|
|
onClick={() => this.tradeAsset(o.key, o.amount * 10)}>
|
|
|
|
|
|
|
|
<FontAwesomeIcon icon={faArrowUp} />
|
|
|
|
|
|
|
|
<FontAwesomeIcon icon={faArrowUp} />
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
) : ''}
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
) : (<></>)}
|
|
|
|
|
|
|
|
</ResourceUnit>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
})}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
) : (<></>)}
|
|
|
|
|
|
|
|
{Object.keys(otherPlayer ? otherPlayer.ridges : []).map((ridge, idx) => (
|
|
|
|
|
|
|
|
<Fragment key={'other-player-trade' + ridge}>
|
|
|
|
|
|
|
|
{!tradeProposed && ((otherPlayer.ridges[ridge] > 0) && !toTrade[ridge]) ? (
|
|
|
|
|
|
|
|
<Button className="tiny"
|
|
|
|
|
|
|
|
onClick={() => this.tradeAsset(ridge, otherPlayer.ridges[ridge], verbatim)}>
|
|
|
|
|
|
|
|
<FontAwesomeIcon icon={faArrowUp} /> {ridgeNames[idx]} {'('}{otherPlayer.ridges[ridge]} cows{')'}
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
) : (<></>)}
|
|
|
|
|
|
|
|
{' '}
|
|
|
|
|
|
|
|
</Fragment>
|
|
|
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
<select onChange={this.selectPlayer}>
|
|
|
|
|
|
|
|
{this.props.game.otherPlayers.map(p => (
|
|
|
|
|
|
|
|
<option key={p.player.name} value={p.player.name}>{p.player.name}</option>
|
|
|
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
<Row>
|
|
|
|
|
|
|
|
<Col width="12">
|
|
|
|
|
|
|
|
<input type="text" placeholder="Cards"
|
|
|
|
|
|
|
|
defaultValue={toTrade.cards}
|
|
|
|
|
|
|
|
onChange={e => this.tradeAsset('cards', e.target.value)} />
|
|
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
<Row>
|
|
|
|
|
|
|
|
<Col width="12">
|
|
|
|
|
|
|
|
{player.trade.error ? (
|
|
|
|
|
|
|
|
<p><b>ERROR:</b> {player.trade.error}</p>
|
|
|
|
|
|
|
|
) : (<></>)}
|
|
|
|
|
|
|
|
{tradeProposed && player.trade.originator === player.name ? (
|
|
|
|
|
|
|
|
<Button onClick={submitTradeCancel}>Cancel trade</Button>
|
|
|
|
|
|
|
|
) : (<></>)}
|
|
|
|
|
|
|
|
{tradeProposed && player.trade.originator !== player.name ? (
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
|
|
|
<Button onClick={submitTradeAccept}>Accept trade</Button>{' '}
|
|
|
|
|
|
|
|
<Button onClick={submitTradeCancel}>Deny trade</Button>
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
) : (<></>)}
|
|
|
|
|
|
|
|
{!tradeProposed ? (
|
|
|
|
|
|
|
|
<Button onClick={this.propose}>Propose Trade</Button>
|
|
|
|
|
|
|
|
) : (<></>)}
|
|
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
</GroupBox>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class CCBY extends React.Component {
|
|
|
|
class CCBY extends React.Component {
|
|
|
|
render() {
|
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
return (
|
|
|
@ -1012,105 +1371,32 @@ class Harvest extends React.Component {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// props: currentPos, moveTo, color
|
|
|
|
|
|
|
|
// actions: movePlayer
|
|
|
|
|
|
|
|
class Moving extends React.Component {
|
|
|
|
class Moving extends React.Component {
|
|
|
|
endPos = 0
|
|
|
|
|
|
|
|
color = ''
|
|
|
|
|
|
|
|
hurtBack = false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
const to = this.props.ui.actionValue.to,
|
|
|
|
|
|
|
|
from = this.props.ui.actionValue.from;
|
|
|
|
|
|
|
|
const currentPlayer = this.props.player.name === this.props.game.currentPlayer ?
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
|
|
|
autoSkip: typeof props.autoSkip === 'undefined' ? false :
|
|
|
|
|
|
|
|
props.autoSkip };
|
|
|
|
|
|
|
|
this.endPos = to;
|
|
|
|
|
|
|
|
this.color = currentPlayer.color;
|
|
|
|
|
|
|
|
// only for hurt back do we go backwards
|
|
|
|
|
|
|
|
this.hurtBack = to === 2 && from === 11 ? true : false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
componentDidMount() {
|
|
|
|
|
|
|
|
// TODO combine with tick
|
|
|
|
|
|
|
|
const delta = this.state.currentPos === 48 ? -48 : this.hurtBack ? -1 : 1;
|
|
|
|
|
|
|
|
this.props.movePlayer(this.state.currentPos + delta,
|
|
|
|
|
|
|
|
this.state.currentPos,
|
|
|
|
|
|
|
|
this.color);
|
|
|
|
|
|
|
|
this.setState(state => ({ currentPos: state.currentPos + delta}));
|
|
|
|
|
|
|
|
if (this.state.currentPos + delta !== this.endPos) {
|
|
|
|
|
|
|
|
if (this.props.timerId) {
|
|
|
|
|
|
|
|
clearInterval(this.props.timerId);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
this.props.setTimerId(setInterval(() => this.tick(), 500));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
componentWillUnmount() {
|
|
|
|
|
|
|
|
if (this.props.timerId) {
|
|
|
|
|
|
|
|
clearInterval(this.props.timerId);
|
|
|
|
|
|
|
|
this.props.setTimerId(false);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// if another player skips movement
|
|
|
|
|
|
|
|
if (this.state.currentPos !== this.endPos) {
|
|
|
|
|
|
|
|
this.props.movePlayer(this.endPos,
|
|
|
|
|
|
|
|
this.state.currentPos,
|
|
|
|
|
|
|
|
this.color);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tick() {
|
|
|
|
|
|
|
|
const delta = this.state.currentPos === 48 ? -48 : this.hurtBack ? -1 : 1;
|
|
|
|
|
|
|
|
this.props.movePlayer(this.state.currentPos + delta,
|
|
|
|
|
|
|
|
this.state.currentPos,
|
|
|
|
|
|
|
|
this.color);
|
|
|
|
|
|
|
|
this.setState(state => ({ currentPos: state.currentPos + delta}));
|
|
|
|
|
|
|
|
if (this.state.currentPos === this.endPos) {
|
|
|
|
|
|
|
|
if (this.props.timerId) { clearInterval(this.props.timerId); }
|
|
|
|
|
|
|
|
this.props.setTimerId(false);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
skip(preventAutoSkip) {
|
|
|
|
skip(preventAutoSkip) {
|
|
|
|
if (!preventAutoSkip) {
|
|
|
|
if (!preventAutoSkip) {
|
|
|
|
skip('moving');
|
|
|
|
skip('moving');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
clearInterval(this.props.timerId);
|
|
|
|
this.props.setMovingSkip(true);
|
|
|
|
this.props.setTimerId(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() {
|
|
|
|
render() {
|
|
|
|
let buttons;
|
|
|
|
let buttons;
|
|
|
|
if (this.props.player.name !== this.props.game.currentPlayer) {
|
|
|
|
if (this.props.player.name !== this.props.game.currentPlayer) {
|
|
|
|
buttons = (<Fragment />);
|
|
|
|
buttons = (<Fragment />);
|
|
|
|
} else if (this.state.currentPos === this.endPos) {
|
|
|
|
} else if (this.props.ui.playerSpaces[this.props.player.color] === this.props.ui.actionValue.to) {
|
|
|
|
buttons = (<Button onClick={() => this.props.showNextAction()}>Continue</Button>);
|
|
|
|
buttons = (<Button onClick={() => this.props.showNextAction()}>Continue</Button>);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
buttons = (<Button onClick={() => this.skip()}>Skip</Button>);
|
|
|
|
buttons = (<Button onClick={() => this.skip()}>Skip</Button>);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const currentPlayer = this.props.player.name === this.props.game.currentPlayer ?
|
|
|
|
|
|
|
|
this.props.player : this.props.game.otherPlayers
|
|
|
|
|
|
|
|
.find(p => p.player.name === this.props.game.currentPlayer).player;
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<Row>
|
|
|
|
<Row>
|
|
|
|
<Col width={'12'}>
|
|
|
|
<Col width={'12'}>
|
|
|
|
<div className='moving'>
|
|
|
|
<div className='moving'>
|
|
|
|
<div className={'action clear-background'}>
|
|
|
|
<div className={'action clear-background'}>
|
|
|
|
<SpaceNode space={this.props.spaces[this.state.currentPos]}
|
|
|
|
<SpaceNode space={this.props.spaces[this.props.ui.playerSpaces[currentPlayer.color]]}
|
|
|
|
height={'170px'} showtitle={true} />
|
|
|
|
height={'170px'} showtitle={true} />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
@ -1242,6 +1528,7 @@ class Action extends React.Component {
|
|
|
|
autoSkip={this.props.ui.autoSkip}
|
|
|
|
autoSkip={this.props.ui.autoSkip}
|
|
|
|
timerId={this.props.timerId}
|
|
|
|
timerId={this.props.timerId}
|
|
|
|
setTimerId={this.props.setTimerId}
|
|
|
|
setTimerId={this.props.setTimerId}
|
|
|
|
|
|
|
|
setMovingSkip={this.props.setMovingSkip}
|
|
|
|
ui={this.props.ui} />);
|
|
|
|
ui={this.props.ui} />);
|
|
|
|
buttons = (<Fragment />);
|
|
|
|
buttons = (<Fragment />);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
@ -1251,6 +1538,7 @@ class Action extends React.Component {
|
|
|
|
setTimerId={this.props.setTimerId}
|
|
|
|
setTimerId={this.props.setTimerId}
|
|
|
|
player={this.props.player}
|
|
|
|
player={this.props.player}
|
|
|
|
game={this.props.game}
|
|
|
|
game={this.props.game}
|
|
|
|
|
|
|
|
setMovingSkip={this.props.setMovingSkip}
|
|
|
|
spaces={this.props.spaces}
|
|
|
|
spaces={this.props.spaces}
|
|
|
|
movePlayer={this.props.movePlayer}
|
|
|
|
movePlayer={this.props.movePlayer}
|
|
|
|
autoSkip={this.props.ui.autoSkip}
|
|
|
|
autoSkip={this.props.ui.autoSkip}
|
|
|
@ -1311,7 +1599,7 @@ class Board extends React.Component {
|
|
|
|
(<SpaceNode showIcons={true} space={s} key={s.key} orientation={o} />);
|
|
|
|
(<SpaceNode showIcons={true} space={s} key={s.key} orientation={o} />);
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<Fragment>
|
|
|
|
<Fragment>
|
|
|
|
<Row collapse='true' className='row-spaces'>
|
|
|
|
<Row collapse='true' className='row-spaces'>
|
|
|
|
<Col width='1'>{renderSpace(this.props.spaces[0], rh, 'corner-tl')}</Col>
|
|
|
|
<Col width='1'>{renderSpace(this.props.spaces[0], rh, 'corner-tl')}</Col>
|
|
|
|
<Col width='10'>
|
|
|
|
<Col width='10'>
|
|
|
@ -1705,6 +1993,7 @@ class BoardApp extends React.Component {
|
|
|
|
otherPlayersTurn={this.props.player.name !== this.props.game.currentPlayer}
|
|
|
|
otherPlayersTurn={this.props.player.name !== this.props.game.currentPlayer}
|
|
|
|
screen={this.state.screen}
|
|
|
|
screen={this.state.screen}
|
|
|
|
showScreen={screen => this.showScreen(screen)}
|
|
|
|
showScreen={screen => this.showScreen(screen)}
|
|
|
|
|
|
|
|
setMovingSkip={this.props.setMovingSkip}
|
|
|
|
ui={this.props.ui} />);
|
|
|
|
ui={this.props.ui} />);
|
|
|
|
// faExchangeAlt -> trade icon, hidden for now
|
|
|
|
// faExchangeAlt -> trade icon, hidden for now
|
|
|
|
return (
|
|
|
|
return (
|
|
|
@ -1768,8 +2057,8 @@ class BoardApp extends React.Component {
|
|
|
|
<FarmsContainer player={this.props.player}
|
|
|
|
<FarmsContainer player={this.props.player}
|
|
|
|
otherPlayers={this.props.game.otherPlayers} />
|
|
|
|
otherPlayers={this.props.game.otherPlayers} />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className={this.tabClass(SCREENS.trade)}>
|
|
|
|
<div className={this.tabClass(SCREENS.trade) + ' trade-tab'}>
|
|
|
|
<TradeContainer player={this.props.player} game={this.props.game} />
|
|
|
|
<TradeContainer2 player={this.props.player} game={this.props.game} />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className={this.tabClass(SCREENS.misc)}>
|
|
|
|
<div className={this.tabClass(SCREENS.misc)}>
|
|
|
|
<Misc />
|
|
|
|
<Misc />
|
|
|
@ -1792,7 +2081,8 @@ class BoardApp extends React.Component {
|
|
|
|
|
|
|
|
|
|
|
|
export default connect(
|
|
|
|
export default connect(
|
|
|
|
state => state.farm,
|
|
|
|
state => state.farm,
|
|
|
|
{ setMessagePanelSpace, setMPDims, nextUIAction, movePlayer, alert, alertHandled, setCardError }
|
|
|
|
{ setMessagePanelSpace, setMPDims, nextUIAction, movePlayer, alert, alertHandled,
|
|
|
|
|
|
|
|
setCardError, setMovingSkip }
|
|
|
|
)(BoardApp)
|
|
|
|
)(BoardApp)
|
|
|
|
|
|
|
|
|
|
|
|
class Card extends React.Component {
|
|
|
|
class Card extends React.Component {
|
|
|
|