New trading interface and moving bug fixes.
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
@@ -38,3 +38,4 @@ export const ALERT_HANDLED = 'alert-handled'
|
|||||||
export const AUTO_SKIP = 'auto-skip'
|
export const AUTO_SKIP = 'auto-skip'
|
||||||
export const MESSAGE = 'message'
|
export const MESSAGE = 'message'
|
||||||
export const SET_HARVEST_TABLE = 'set-harvest-table'
|
export const SET_HARVEST_TABLE = 'set-harvest-table'
|
||||||
|
export const SET_MOVING_SKIP = 'set-moving-skip'
|
||||||
|
|||||||
@@ -20,13 +20,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,
|
SPACE_PUSH_PLAYER, SPACE_CLEAR_PLAYERS, SET_OLD_MESSAGES, MESSAGE_PANEL_SPACE,
|
||||||
MP_MOUSE, SET_MP_DIMS, MARK_ACTION_CHANGE_HANDLED, SET_NEXT_ACTION,
|
MP_MOUSE, SET_MP_DIMS, MARK_ACTION_CHANGE_HANDLED, SET_NEXT_ACTION,
|
||||||
MOVE_PLAYER, NEXT_UI_ACTION, NEXT_UI_ACTION_SILENT, ALERT, ALERT_HANDLED,
|
MOVE_PLAYER, NEXT_UI_ACTION, NEXT_UI_ACTION_SILENT, ALERT, ALERT_HANDLED,
|
||||||
AUTO_SKIP, MESSAGE, SET_HARVEST_TABLE, SET_CARD_ERROR } from './actionTypes.js'
|
AUTO_SKIP, MESSAGE, SET_HARVEST_TABLE, SET_CARD_ERROR,
|
||||||
|
SET_MOVING_SKIP } from './actionTypes.js'
|
||||||
|
|
||||||
export { updateGame, updatePlayer, gameState, setSelectedCard, setCards,
|
export { updateGame, updatePlayer, gameState, setSelectedCard, setCards,
|
||||||
spacePushPlayer, spaceClearPlayers, setOldMessages, setMessagePanelSpace,
|
spacePushPlayer, spaceClearPlayers, setOldMessages, setMessagePanelSpace,
|
||||||
mpMouse, setMPDims, movePlayer, setNextAction, nextUIAction,
|
mpMouse, setMPDims, movePlayer, setNextAction, nextUIAction,
|
||||||
markActionChangeHandled, nextUIActionSilent, alert, alertHandled,
|
markActionChangeHandled, nextUIActionSilent, alert, alertHandled,
|
||||||
autoSkip, message, setHarvestTable, setCardError }
|
autoSkip, message, setHarvestTable, setCardError, setMovingSkip }
|
||||||
|
|
||||||
function updateGame(update) {
|
function updateGame(update) {
|
||||||
return { type: UPDATE_GAME,
|
return { type: UPDATE_GAME,
|
||||||
@@ -130,3 +131,7 @@ function message(message) {
|
|||||||
function setHarvestTable(table) {
|
function setHarvestTable(table) {
|
||||||
return { type: SET_HARVEST_TABLE, table };
|
return { type: SET_HARVEST_TABLE, table };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setMovingSkip(skip) {
|
||||||
|
return { type: SET_MOVING_SKIP, skip };
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ import * as websocket from '../../websocket.js'
|
|||||||
import { updateGame, updatePlayer, gameState, setSelectedCard, setCards,
|
import { updateGame, updatePlayer, gameState, setSelectedCard, setCards,
|
||||||
movePlayer, setOldMessages, markActionChangeHandled,
|
movePlayer, setOldMessages, markActionChangeHandled,
|
||||||
mpMouse, rolled, setNextAction, nextUIAction, nextUIActionSilent, alert,
|
mpMouse, rolled, setNextAction, nextUIAction, nextUIActionSilent, alert,
|
||||||
autoSkip, message, alertHandled, setHarvestTable, setCardError } from './actions.js'
|
autoSkip, message, alertHandled, setHarvestTable,
|
||||||
|
setCardError, setMovingSkip } from './actions.js'
|
||||||
import { itemCard, fateCard } from 'game.js'
|
import { itemCard, fateCard } from 'game.js'
|
||||||
|
|
||||||
export { initialize, buy, roll, endTurn, loan, trade, submitTradeAccept,
|
export { initialize, buy, roll, endTurn, loan, trade, submitTradeAccept,
|
||||||
@@ -189,7 +190,9 @@ function initialize(st, sc) {
|
|||||||
let lastAction = false,
|
let lastAction = false,
|
||||||
lastAutoSkip = false,
|
lastAutoSkip = false,
|
||||||
rollMessage = '',
|
rollMessage = '',
|
||||||
rollTimer = false;
|
rollTimer = false,
|
||||||
|
movingAction = { from: 99, to: 99 },
|
||||||
|
movingTimer = 0;
|
||||||
const unsubscribe = store.subscribe(
|
const unsubscribe = store.subscribe(
|
||||||
() => {
|
() => {
|
||||||
const state = store.getState();
|
const state = store.getState();
|
||||||
@@ -265,6 +268,50 @@ function initialize(st, sc) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((state.farm.ui.action === 'move' || state.farm.ui.action === 'goto') &&
|
||||||
|
movingAction.from !== state.farm.ui.actionValue.from &&
|
||||||
|
movingAction.to !== state.farm.ui.actionValue.to) {
|
||||||
|
movingAction = state.farm.ui.actionValue;
|
||||||
|
const movingProc = (player, from, to) => {
|
||||||
|
let currentPos = from < 0 ? from + 49 : from;
|
||||||
|
const color = player.color;
|
||||||
|
const hurtBack = to === 2 && from === 11 ? true : false;
|
||||||
|
const delta = currentPos === 48 ? -48 : hurtBack ? -1 : 1;
|
||||||
|
store.dispatch(movePlayer(currentPos + delta, currentPos, color));
|
||||||
|
currentPos += delta;
|
||||||
|
|
||||||
|
const tick = () => {
|
||||||
|
if (store.getState().farm.ui.movingSkip ||
|
||||||
|
store.getState().farm.ui.autoSkip === 'moving') {
|
||||||
|
store.dispatch(setMovingSkip(false));
|
||||||
|
store.dispatch(movePlayer(to, currentPos, color));
|
||||||
|
currentPos = to;
|
||||||
|
} else {
|
||||||
|
const delta = currentPos === 48 ? -48 : hurtBack ? -1 : 1;
|
||||||
|
store.dispatch(movePlayer(currentPos + delta, currentPos, color));
|
||||||
|
currentPos += delta;
|
||||||
|
}
|
||||||
|
if (currentPos === to) {
|
||||||
|
clearInterval(movingTimer);
|
||||||
|
movingTimer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentPos !== to) {
|
||||||
|
movingTimer = setInterval(tick, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
movingProc(state.farm.player.name === state.farm.game.currentPlayer ?
|
||||||
|
state.farm.player : state.farm.game.otherPlayers
|
||||||
|
.find(p => p.player.name === state.farm.game.currentPlayer).player,
|
||||||
|
movingAction.from, movingAction.to);
|
||||||
|
} else if (state.farm.ui.action !== 'move' && state.farm.ui.action !== 'goto') {
|
||||||
|
if (movingTimer) {
|
||||||
|
clearInterval(movingTimer);
|
||||||
|
movingTimer = 0;
|
||||||
|
movingAction = { from: 99, to: 99 };
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// mpDims.mouseX = e.clientX
|
// mpDims.mouseX = e.clientX
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ import { UPDATE_GAME, UPDATE_PLAYER, GAME_STATE, SET_SELECTED_CARD, SET_CARDS,
|
|||||||
SET_OLD_MESSAGES, MESSAGE_PANEL_SPACE, MP_MOUSE,
|
SET_OLD_MESSAGES, MESSAGE_PANEL_SPACE, MP_MOUSE,
|
||||||
SET_MP_DIMS, MOVE_PLAYER, SET_NEXT_ACTION, NEXT_UI_ACTION,
|
SET_MP_DIMS, MOVE_PLAYER, SET_NEXT_ACTION, NEXT_UI_ACTION,
|
||||||
MARK_ACTION_CHANGE_HANDLED, NEXT_UI_ACTION_SILENT, ALERT, ALERT_HANDLED,
|
MARK_ACTION_CHANGE_HANDLED, NEXT_UI_ACTION_SILENT, ALERT, ALERT_HANDLED,
|
||||||
AUTO_SKIP, MESSAGE, SET_HARVEST_TABLE, SET_CARD_ERROR } from './actionTypes.js'
|
AUTO_SKIP, MESSAGE, SET_HARVEST_TABLE, SET_CARD_ERROR,
|
||||||
|
SET_MOVING_SKIP } from './actionTypes.js'
|
||||||
import { GAME_STATES } from '../../constants.js'
|
import { GAME_STATES } from '../../constants.js'
|
||||||
import { spaceContent, corners } from 'game.js'
|
import { spaceContent, corners } from 'game.js'
|
||||||
|
|
||||||
@@ -121,6 +122,7 @@ const initialState = {
|
|||||||
unhandledAlert: false,
|
unhandledAlert: false,
|
||||||
autoSkip: false,
|
autoSkip: false,
|
||||||
playerSpaces: {},
|
playerSpaces: {},
|
||||||
|
movingSkip: false,
|
||||||
harvestTable: false },
|
harvestTable: false },
|
||||||
spaces: spaces,
|
spaces: spaces,
|
||||||
space: null,
|
space: null,
|
||||||
@@ -219,6 +221,8 @@ export default function(state = initialState, action) {
|
|||||||
return { ...state, ui: { ...state.ui, message: action.message }};
|
return { ...state, ui: { ...state.ui, message: action.message }};
|
||||||
case SET_HARVEST_TABLE:
|
case SET_HARVEST_TABLE:
|
||||||
return { ...state, ui: { ...state.ui, harvestTable: action.table }};
|
return { ...state, ui: { ...state.ui, harvestTable: action.table }};
|
||||||
|
case SET_MOVING_SKIP:
|
||||||
|
return { ...state, ui: { ...state.ui, movingSkip: action.skip }};
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -584,6 +584,16 @@
|
|||||||
(when (alist-ref ridge params)
|
(when (alist-ref ridge params)
|
||||||
(if (> (player-ridge player ridge) 0)
|
(if (> (player-ridge player ridge) 0)
|
||||||
(begin
|
(begin
|
||||||
|
(safe-set!
|
||||||
|
(player-assets originator)
|
||||||
|
(alist-update 'cows (+ (alist-ref 'cows (player-assets originator))
|
||||||
|
(alist-ref ridge (player-ridges player)))
|
||||||
|
(player-assets originator)))
|
||||||
|
(safe-set!
|
||||||
|
(player-assets player)
|
||||||
|
(alist-update 'cows (- (alist-ref 'cows (player-assets player))
|
||||||
|
(alist-ref ridge (player-ridges player)))
|
||||||
|
(player-assets player)))
|
||||||
(safe-set! (player-ridges originator)
|
(safe-set! (player-ridges originator)
|
||||||
(alist-update ridge
|
(alist-update ridge
|
||||||
(alist-ref ridge (player-ridges player))
|
(alist-ref ridge (player-ridges player))
|
||||||
@@ -591,6 +601,16 @@
|
|||||||
(safe-set! (player-ridges player)
|
(safe-set! (player-ridges player)
|
||||||
(alist-update ridge 0 (player-ridges player))))
|
(alist-update ridge 0 (player-ridges player))))
|
||||||
(begin
|
(begin
|
||||||
|
(safe-set!
|
||||||
|
(player-assets originator)
|
||||||
|
(alist-update 'cows (- (alist-ref 'cows (player-assets originator))
|
||||||
|
(alist-ref ridge (player-ridges originator)))
|
||||||
|
(player-assets originator)))
|
||||||
|
(safe-set!
|
||||||
|
(player-assets player)
|
||||||
|
(alist-update 'cows (+ (alist-ref 'cows (player-assets player))
|
||||||
|
(alist-ref ridge (player-ridges originator)))
|
||||||
|
(player-assets player)))
|
||||||
(safe-set! (player-ridges player)
|
(safe-set! (player-ridges player)
|
||||||
(alist-update ridge
|
(alist-update ridge
|
||||||
(alist-ref ridge (player-ridges originator))
|
(alist-ref ridge (player-ridges originator))
|
||||||
@@ -1903,17 +1923,11 @@
|
|||||||
;; TODO
|
;; TODO
|
||||||
;; make sure two players can't have the same name
|
;; make sure two players can't have the same name
|
||||||
;; info actions should look better
|
;; info actions should look better
|
||||||
;; you can get $50 from harvest
|
;; you can get $50 from operating expense
|
||||||
;; moving bug 5 from oct 2 saw by player 2
|
|
||||||
;; from harvest moon rolled 5
|
|
||||||
;; finished
|
|
||||||
;; infinite loop ((?action . end-game) (?value . #<procedure (a10302)>))
|
|
||||||
|
|
||||||
;; auto-skip loop
|
;; auto-skip loop
|
||||||
;; harvester / tractor don't say total price
|
;; harvester / tractor don't say total price
|
||||||
|
|
||||||
;; mark spaces
|
;; mark spaces
|
||||||
|
|
||||||
;; trade notification keeps popping up
|
;; can't trade other player's ridge
|
||||||
|
|
||||||
;; show harvest multiplier
|
|
||||||
|
|||||||
@@ -268,8 +268,77 @@ $tab-margin: 0.3rem;
|
|||||||
|
|
||||||
.player-trade-resources .resource-unit {
|
.player-trade-resources .resource-unit {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
margin-bottom: 0.3rem;
|
||||||
width: 4rem; }
|
width: 4rem; }
|
||||||
|
|
||||||
|
.resource-unit.double-width {
|
||||||
|
width: 84px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resource-unit.double-width .button:last-child {
|
||||||
|
margin-left: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player-trade-resources img {
|
||||||
|
margin-top: 0.2rem;
|
||||||
|
margin-bottom: 0.2rem; }
|
||||||
|
|
||||||
|
.trade-player-container {
|
||||||
|
border: 0.2rem solid $dark-color;
|
||||||
|
border-radius: 0.2rem;
|
||||||
|
background: #ccc;
|
||||||
|
padding: 0.3rem;
|
||||||
|
.button {
|
||||||
|
margin: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
$trade-margin: 3rem;
|
||||||
|
.resources-to-trade {
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
visibility: hidden;
|
||||||
|
.resource-unit {
|
||||||
|
position: relative;
|
||||||
|
margin-top: $trade-margin / 2;
|
||||||
|
margin-bottom: $trade-margin / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trade-asset-cancel {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
color: red;
|
||||||
|
padding: 0.2rem;
|
||||||
|
display: none;
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0.7;
|
||||||
|
svg {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.trade-to {
|
||||||
|
margin-top: ($trade-margin / 2) - 1.2;
|
||||||
|
margin-bottom: ($trade-margin / 2) + 1.2;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trade-to:hover .trade-asset-cancel {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.trade-from:hover .trade-asset-cancel {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trade-from {
|
||||||
|
margin-bottom: ($trade-margin / 2) - 1.2;
|
||||||
|
margin-top: ($trade-margin / 2) + 1.2;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.card-id {
|
.card-id {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
@@ -305,6 +374,7 @@ $tab-margin: 0.3rem;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.resource-unit {
|
.resource-unit {
|
||||||
|
position: relative;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-right: 0.5rem;
|
margin-right: 0.5rem;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
@@ -313,6 +383,19 @@ $tab-margin: 0.3rem;
|
|||||||
height: 34px; }
|
height: 34px; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.resource-doubled {
|
||||||
|
position: absolute;
|
||||||
|
top: -0.7rem;
|
||||||
|
right: -0.2rem;
|
||||||
|
color: blue;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
padding: 0.1rem;
|
||||||
|
transform: rotate(17deg);
|
||||||
|
svg {
|
||||||
|
filter: drop-shadow( 1px 1px 1px rgba(0, 0, 0, .7));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.resource-unit-container {
|
.resource-unit-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row; }
|
flex-direction: row; }
|
||||||
@@ -556,12 +639,17 @@ $tab-margin: 0.3rem;
|
|||||||
max-height: 80vh;
|
max-height: 80vh;
|
||||||
@include breakpoint(medium down) {
|
@include breakpoint(medium down) {
|
||||||
flex-grow: 2;
|
flex-grow: 2;
|
||||||
|
max-width: 82vw;
|
||||||
}
|
}
|
||||||
@include breakpoint(large) {
|
@include breakpoint(large) {
|
||||||
width: 26rem;
|
width: 26rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.trade-tab {
|
||||||
|
min-width: 26rem;
|
||||||
|
}
|
||||||
|
|
||||||
.static-tab-container {
|
.static-tab-container {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
max-height: 80vh;
|
max-height: 80vh;
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ module.exports = {
|
|||||||
chunkFilename: '[id].css',
|
chunkFilename: '[id].css',
|
||||||
}),
|
}),
|
||||||
new CopyPlugin([
|
new CopyPlugin([
|
||||||
{ from: './src/server/', to: './' },
|
{ from: './src/server/farm.scm', to: './[name].[ext]' },
|
||||||
|
{ from: './src/server/farm', to: './[name]' },
|
||||||
{ from: './assets/game/', to: './assets/game/' }
|
{ from: './assets/game/', to: './assets/game/' }
|
||||||
]),
|
]),
|
||||||
new webpack.LoaderOptionsPlugin({
|
new webpack.LoaderOptionsPlugin({
|
||||||
|
|||||||
Reference in New Issue
Block a user