summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Hintz <t@thintz.com>2020-08-28 15:24:08 -0700
committerThomas Hintz <t@thintz.com>2020-08-28 15:24:08 -0700
commit3a97c128b60b9fd9ab3c9e3b821510a828c09f14 (patch)
tree80cac13df8aa1d02df55ed843202ac023dfa8f85
parentb2d0dc32681e7b6d6028682f625e519ec7fac9a6 (diff)
downloadfarm-3a97c128b60b9fd9ab3c9e3b821510a828c09f14.tar.gz
Adding tabs and ROI to game over screen.
-rw-r--r--src/components/farm/Board.jsx204
-rw-r--r--src/style.scss8
2 files changed, 142 insertions, 70 deletions
diff --git a/src/components/farm/Board.jsx b/src/components/farm/Board.jsx
index 0bde4e6..d7b1459 100644
--- a/src/components/farm/Board.jsx
+++ b/src/components/farm/Board.jsx
@@ -27,7 +27,7 @@ import TractorFullImg from './../../../assets/img/tractor-with-spikes.svg'
import HarvesterImg from './../../../assets/img/harvester.svg'
import VolcanoImg from './../../../assets/img/volcano2.gif'
-import React, { Fragment } from 'react'
+import React, { Fragment, useState } from 'react'
import ReactDOM from 'react-dom'
import { connect } from 'react-redux'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
@@ -191,7 +191,13 @@ class PlayerResources extends React.Component {
// http://stackoverflow.com/questions/149055
function formatMoney(n) {
- return n.toFixed(1).replace(/(\d)(?=(\d{3})+\.)/g, '$1,').slice(0, -2); }
+ if (typeof n === 'number') {
+ return n.toFixed(1).replace(/(\d)(?=(\d{3})+\.)/g, '$1,').slice(0, -2);
+ } else {
+ console.trace(n);
+ return 'NaN';
+ }
+}
class MoneySummary extends React.Component {
render () {
@@ -1916,60 +1922,141 @@ class Board extends React.Component {
}
// handler, buttonText, children
-class AlertOverlay extends React.Component {
- constructor(props) {
- super(props);
- this.state = { visible: typeof this.props.visible !== 'undefined' ?
- this.props.visible : true };
- }
+const AlertOverlay = ({ visible, alertHandled, hideHandler, id, handler, cancelHandler, preventHiding,
+ children, disabled, buttonText, cancelButtonText, cancelDisabled }) => {
+ const [isVisible, setIsVisible] = useState(typeof visible !== 'undefined' ? visible : true);
- hide = e => {
+ const hide = (e) => {
e.preventDefault();
- this.setState({ visible: false });
- this.props.alertHandled(this.props.id);
- this.props.hideHandler();
+ setIsVisible(false);
+ alertHandled(id);
+ hideHandler();
}
- buttonClick = e => {
- this.hide(e);
- this.props.handler();
+ const buttonClick = (e) => {
+ hide(e);
+ handler();
}
- cancelButtonClick = e => {
+ const cancelButtonClick = (e) => {
e.preventDefault();
- this.props.cancelHandler();
+ cancelHandler();
}
// <label><input type='checkbox' onClick={this.hidePermanent} /> {`Don't show again`}</label>
- render() {
- return (
- <div className={'alert-overlay' + (this.state.visible ? '' : ' hidden') }>
- {!this.props.preventHiding ? (
- <div onClick={this.hide} className='alert-overlay-hide'>
- <FontAwesomeIcon icon={faTimes} />
- </div>
- ) : (<></>)}
- <div className='alert-container'>
- <div className='alert-overlay-contents'>
- {this.props.children}
- <br />
- <div>
- <Button onClick={this.buttonClick} disabled={!!this.props.disabled}>{this.props.buttonText}</Button>
- {this.props.cancelButtonText ? (
- <>
- {' '}
- <Button onClick={this.cancelButtonClick} disabled={!!this.props.cancelDisabled}>
- {this.props.cancelButtonText}
- </Button>
- </>
- ): (<></>)}
- </div>
- {!this.props.preventHiding ? (<a onClick={this.hide}>close</a>) : (<></>)}
+ return (
+ <div className={'alert-overlay' + (isVisible ? '' : ' hidden') }>
+ {!preventHiding ? (
+ <div onClick={hide} className='alert-overlay-hide'>
+ <FontAwesomeIcon icon={faTimes} />
+ </div>
+ ) : (<></>)}
+ <div className='alert-container'>
+ <div className='alert-overlay-contents'>
+ {children}
+ <br />
+ <div>
+ <Button onClick={buttonClick} disabled={!!disabled}>{buttonText}</Button>
+ {cancelButtonText ? (
+ <>
+ {' '}
+ <Button onClick={cancelButtonClick} disabled={!!cancelDisabled}>
+ {cancelButtonText}
+ </Button>
+ </>
+ ): (<></>)}
</div>
+ {!preventHiding ? (<a onClick={hide}>close</a>) : (<></>)}
</div>
</div>
- );
+ </div>
+ );
+}
+
+const gameOverTabs = { initial: 'Summary', harvest: 'Harvests', investments: 'Investments' };
+const GameOver = ({ id, alertHandled, contents, game, player}) => {
+ const [tab, setTab] = useState(gameOverTabs.initial);
+
+ const tabClass = (screen) =>
+ 'tab border-top' + (tab === screen ? ' show ' : '');
+
+ const iconClass = (screen) =>
+ tab === screen ? 'is-active' : ' ';
+
+ const iconOnClick = (icon) =>
+ (e) => {
+ e.preventDefault();
+ setTab(icon);
+ };
+
+ const playerRidgeValue = (player, otherPlayers) => {
+ const ridges = makeRidgeLookup(player, otherPlayers);
+ return (ridges.ridge1 ? 10 : 0) +
+ (ridges.ridge2 ? 15 : 0) +
+ (ridges.ridge3 ? 20 : 0) +
+ (ridges.ridge4 ? 25 : 0);
}
+
+ return (
+ <AlertOverlay visible={true}
+ id={id}
+ alertHandled={alertHandled}
+ buttonText='Close'
+ hideHandler={() => 'nothing'}
+ handler={() => { return false; }}>
+ <div className="game-over">
+ <h1>Game Over!</h1>
+ <ul className='menu icons icons-top'>
+ {[gameOverTabs.initial, gameOverTabs.harvest, gameOverTabs.investments]
+ .map((icon, i) =>
+ (<li key={i} className={iconClass(icon)}>
+ <div></div>
+ <a onClick={iconOnClick(icon)}>
+ {icon}
+ </a>
+ </li>))}
+ </ul>
+ <div className="">
+ <div className={tabClass(gameOverTabs.initial)}>
+ {contents.results.map((e, i) => (
+ <p key={i}>{e}</p>
+ ))}
+ <p>{contents.stats.pro}</p>
+ <p>{contents.stats.back}</p>
+ <p>{contents.stats.taxPerson}</p>
+ <p>{contents.stats.emergency}</p>
+ <p>{contents.stats.highRoller}</p>
+ <p>{contents.stats.lowRoller}</p>
+ </div>
+ <div className={tabClass(gameOverTabs.harvest)}>
+ {contents.stats.players.map(p => (
+ <div key={p.name}>
+ <p><b>{p.name} Harvests:</b></p>
+ <p>Total: ${formatMoney(p.harvestTotal)} Expenses: ${formatMoney(Math.abs(p.operatingExpenses))}</p>
+ <p>Avg ${formatMoney(p.harvestAverage)} rolling {p.harvestRoll} for {p.numHarvests} harvests</p>
+ <p>Hay: ${formatMoney(p.hay)} Grain: ${formatMoney(p.grain)} Fruit: ${formatMoney(p.fruit)} Cows: ${formatMoney(p.cows)}</p>
+ </div>))}
+ </div>
+ <div className={tabClass(gameOverTabs.investments)}>
+ {contents.stats.players.map(p => {
+ const pObj = findPlayer(game, p.name) || player;
+ return (
+ <div key={p.name}>
+ <p><b>{p.name} Investments:</b></p>
+ <p>Total: ${formatMoney(assetsValue(pObj))}</p>
+ <p>Hay: {(p.hay / ((pObj.assets.hay * 2000) || 0.001)).toFixed(2)} {' '}
+ Grain: {(p.grain / ((pObj.assets.grain * 2000) || 0.001)).toFixed(2)} {' '}
+ Fruit: {(p.fruit / ((pObj.assets.fruit * 5000) || 0.001)).toFixed(2)} {' '}
+ Cows: {(p.cows / (((pObj.assets.cows * 500) + (playerRidgeValue(pObj, game.otherPlayers))) || 0.001)).toFixed(2)}
+ </p>
+ </div>
+ );
+ })}
+ </div>
+ </div>
+ </div>
+ </AlertOverlay>
+ );
}
class InfoBar extends React.Component {
@@ -2255,34 +2342,11 @@ class BoardApp extends React.Component {
let alertOverlay;
const alert = this.props.ui.unhandledAlert;
if (alert && alert.type === ALERTS.endOfGame) {
- alertOverlay = (
- <AlertOverlay visible={true}
- id={alert.id}
- alertHandled={this.props.alertHandled}
- buttonText='Close'
- hideHandler={() => 'nothing'}
- handler={() => { return false; }}>
- <div className="game-over">
- <h1>Game Over!</h1>
- {alert.contents.results.map((e, i) => (
- <p key={i}>{e}</p>
- ))}
- <p>{alert.contents.stats.pro}</p>
- <p>{alert.contents.stats.back}</p>
- <p>{alert.contents.stats.taxPerson}</p>
- <p>{alert.contents.stats.emergency}</p>
- <p>{alert.contents.stats.highRoller}</p>
- <p>{alert.contents.stats.lowRoller}</p>
- {alert.contents.stats.players.map(p => (
- <div key={p.name}>
- <p><b>{p.name} Harvests:</b></p>
- <p>Total: ${formatMoney(p.harvestTotal)} Expenses: ${formatMoney(Math.abs(p.operatingExpenses))}</p>
- <p>Avg ${formatMoney(p.harvestAverage)} rolling {p.harvestRoll} for {p.numHarvests} harvests</p>
- <p>Hay: ${formatMoney(p.hay)} Grain: ${formatMoney(p.grain)} Fruit: ${formatMoney(p.fruit)} Cows: ${formatMoney(p.cows)}</p>
- </div>))}
- </div>
- </AlertOverlay>
- );
+ alertOverlay = (<GameOver id={alert.id}
+ game={this.props.game}
+ player={this.props.player}
+ alertHandled={this.props.alertHandled}
+ contents={alert.contents} />);
} else if (alert && alert.type === ALERTS.auditCalled) {
alertOverlay = (
<AlertOverlay visible={true}
diff --git a/src/style.scss b/src/style.scss
index 95dc634..6000835 100644
--- a/src/style.scss
+++ b/src/style.scss
@@ -806,6 +806,14 @@ $trade-margin: 3rem;
padding: 0.5rem;
display: none; }
+.tab.border-top {
+ $tab-border: 0.3rem solid $primary-color;
+ border-top: $tab-border;
+ border-bottom: none;
+ border-left: none;
+ border-right: none;
+}
+
.tab.show {
display: block; }