Skip to content

Commit

Permalink
Merge branch 'feature/stat_calculation' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
thesimonho committed Feb 9, 2020
2 parents 9cce512 + 877502a commit 34347de
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 103 deletions.
66 changes: 54 additions & 12 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Commanders from './data/commanders.json';
import {
sumArray,
getMaxTalentCount,
getTreeName,
setTitle,
isTouchDevice,
encode,
Expand All @@ -25,6 +26,7 @@ const TreePanel = React.lazy(() => import('./TreePanel'));
let treeData;

//FIXME: only updateurl/encode if that particular tree has changed
//TODO: move updateURL to utils

/**
* Main application component. Contains high level logic for managing application state
Expand Down Expand Up @@ -59,11 +61,10 @@ class App extends Component {
switch (urlParams.length) {
case 1: // blank url
this.state = this.getEmptyState();
treeData = loadTreeData(dataVersion);
this.updateURL('clear');
break;
case 5: // complete url
//FIXME: this loads treeData twice if url is valid
this.state = this.getEmptyState();
let [urlDataVersion, comID, red, yellow, blue] = urlParams;
urlDataVersion = parseInt(urlDataVersion);

Expand All @@ -79,6 +80,7 @@ class App extends Component {
this.invalidBuildMessage = 'Unknown commander ID';
this.invalidModalFlag = true;
} else {
this.state = this.getEmptyState();
treeData = loadTreeData(urlDataVersion);
this.state = {
...this.state,
Expand Down Expand Up @@ -118,7 +120,19 @@ class App extends Component {
this.invalidModalFlag = true;
break;
} else {
// Store color array in state
this.state[color[1]] = talents;

// Calculate stats for the color
const treeName = getTreeName(color[1], commanderName);
for (let i = 0; i < talents.length; i++) {
const talentData = treeData[treeName][i + 1];
const stat = talentData['stats'];
if (talents[i] > 0 && stat) {
this.state.stats[stat] +=
talentData['values'][talents[i] - 1];
}
}
}
}

Expand All @@ -131,6 +145,7 @@ class App extends Component {

if (this.invalidModalFlag) {
this.state = this.getEmptyState();
treeData = loadTreeData(dataVersion);
this.updateURL('clear');
} else {
this.updateURL('update');
Expand All @@ -141,6 +156,7 @@ class App extends Component {
this.invalidBuildMessage = `Incorrect number of build parameters (length: ${urlParams.length}, expected: 5)`;
this.invalidModalFlag = true;
this.state = this.getEmptyState();
treeData = loadTreeData(dataVersion);
this.updateURL('clear');
}
}
Expand All @@ -153,8 +169,6 @@ class App extends Component {
* @memberof App
*/
getEmptyState() {
treeData = loadTreeData(dataVersion);

const isShownInfoPanel = JSON.parse(
localStorage.getItem('isShownInfoPanel')
);
Expand All @@ -170,6 +184,7 @@ class App extends Component {
red: [],
yellow: [],
blue: [],
stats: this.getEmptyStats(),
nodeSize: localStorage.getItem('nodeSize') || 'M',
isShownInfoPanel: isShownInfoPanel === null ? true : isShownInfoPanel,
isShownValues: isShownValues === null ? true : isShownValues,
Expand All @@ -181,14 +196,13 @@ class App extends Component {
}

/**
* Set app state to empty and update the current URL
* Get object containing all minor stats and set them to 0
*
* @returns {object} Object containing stats with 0 values
* @memberof App
*/
setEmptyState() {
this.setState(this.getEmptyState(), () => {
this.updateURL('clear');
});
getEmptyStats() {
return { Attack: 0, Defense: 0, Health: 0, 'March Speed': 0 };
}

/**
Expand Down Expand Up @@ -243,7 +257,12 @@ class App extends Component {

const zeroTalents = this.createZeroTalents(commander);
this.setState(
{ dataVersion: dataVersion, commander: commander, ...zeroTalents },
{
dataVersion: dataVersion,
commander: commander,
...zeroTalents,
stats: this.getEmptyStats()
},
() => {
this.updateURL('update');
this.treePanelRef.drawLines();
Expand Down Expand Up @@ -302,18 +321,40 @@ class App extends Component {
*
* @param {string} color Color of the tree the node belongs to
* @param {number} idx Index of the node in the tree/color array.
* @param {number} valueIdx Index of the changed value.
* @param {string} how {increase | decrease} Should node value be increased
* or decreased?
* @memberof App
*/
changeTalentValue(color, idx, how) {
changeTalentValue(color, idx, valueIdx, how) {
let talent = treeData[Commanders[this.state.commander][color]][idx];
let stat = talent['stats'];
let newArr = this.state[color];
let newStats = { ...this.state.stats };

if (how === 'increase') {
newArr[idx - 1] += 1;
// increase stat value
if (valueIdx === 0) {
newStats[stat] += talent['values'][0];
} else {
newStats[stat] +=
talent['values'][valueIdx] - talent['values'][valueIdx - 1];
}
} else if (how === 'decrease') {
newArr[idx - 1] -= 1;
// decrease stat value
if (valueIdx <= 1) {
newStats[stat] -= talent['values'][0];
} else {
newStats[stat] -=
talent['values'][valueIdx - 1] - talent['values'][valueIdx - 2];
}
}
this.setState({ [color]: newArr }, () => this.updateURL('update'));

this.setState({ [color]: newArr, stats: newStats }, () =>
this.updateURL('update')
);
}

/**
Expand Down Expand Up @@ -565,6 +606,7 @@ class App extends Component {
red={this.state.red}
yellow={this.state.yellow}
blue={this.state.blue}
stats={this.state.stats}
isShownInfoPanel={this.state.isShownInfoPanel}
/>
</ErrorBoundary>
Expand Down
38 changes: 15 additions & 23 deletions src/InfoPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import SummaryPanel from './SummaryPanel';
import StatsPanel from './StatsPanel';
import StatsTalentsPanel from './StatsTalentsPanel';
import ErrorBoundary from './Error';
import { isTouchDevice } from './utils';

import './styles/InfoPanel.css';

Expand Down Expand Up @@ -31,37 +32,28 @@ class InfoPanel extends Component {
calcPointsSpent={this.props.calcPointsSpent}
/>
<MediaQuery orientation="portrait">
<StatsPanel
commander={this.props.commander}
treeData={this.props.treeData}
red={this.props.red}
yellow={this.props.yellow}
blue={this.props.blue}
/>
<StatsPanel stats={this.props.stats} />
</MediaQuery>
</div>
</ErrorBoundary>

<MediaQuery orientation="landscape">
<ErrorBoundary>
<StatsPanel
commander={this.props.commander}
treeData={this.props.treeData}
red={this.props.red}
yellow={this.props.yellow}
blue={this.props.blue}
/>
<StatsPanel stats={this.props.stats} />
</ErrorBoundary>

<ErrorBoundary>
<StatsTalentsPanel
commander={this.props.commander}
treeData={this.props.treeData}
red={this.props.red}
yellow={this.props.yellow}
blue={this.props.blue}
/>
</ErrorBoundary>
{!isTouchDevice() && (
<ErrorBoundary>
<StatsTalentsPanel
calcPointsSpent={this.props.calcPointsSpent}
commander={this.props.commander}
treeData={this.props.treeData}
red={this.props.red}
yellow={this.props.yellow}
blue={this.props.blue}
/>
</ErrorBoundary>
)}
</MediaQuery>
</div>
);
Expand Down
2 changes: 2 additions & 0 deletions src/Node.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ class Node extends Component {
this.props.changeTalentValue(
this.props.color,
this.props.idx,
this.props.value,
'increase'
);
jsPlumb
Expand Down Expand Up @@ -175,6 +176,7 @@ class Node extends Component {
this.props.changeTalentValue(
this.props.color,
this.props.idx,
this.props.value,
'decrease'
);

Expand Down
41 changes: 5 additions & 36 deletions src/StatsPanel.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React, { Component } from 'react';

import Commanders from './data/commanders.json';
import './styles/StatsPanel.css';

//FIXME: calcStats is inefficient. Iterate once over everything (instead of once for each stat)
//TODO: add main stats to small stats (e.g. march speed peacekeeping)

/**
* Stats panel component displaying stats about the current talent build
Expand All @@ -12,45 +11,15 @@ import './styles/StatsPanel.css';
* @extends {Component}
*/
class StatsPanel extends Component {
/**
* Calculate the total value of a given stat (e.g. attack, health)
*
* @param {string} stat Name of the stat to be calculated (e.g. Defense)
* @returns {number} Calculated value of the stat
* @memberof StatsPanel
*/
calcStats(stat) {
const commander = this.props.commander;
let statValue = 0;

['red', 'yellow', 'blue'].forEach(color => {
const nodes = this.props[color];

if (nodes.some(values => values !== 0)) {
nodes.forEach((value, idx) => {
const talentInfo = this.props.treeData[Commanders[commander][color]][
idx + 1
];

if (value > 0 && talentInfo.stats === stat) {
statValue += talentInfo.values[value - 1];
}
});
}
});

return statValue;
}

render() {
return (
<div id="stats-panel" className="info-box">
<h2>Stats</h2>
<div id="stats-panel-stats">
<p>Attack: {this.calcStats('Attack')}%</p>
<p>Defense: {this.calcStats('Defense')}%</p>
<p>Health: {this.calcStats('Health')}%</p>
<p>March Speed: {this.calcStats('March Speed')}%</p>
<p>Attack: {this.props.stats['Attack']}%</p>
<p>Defense: {this.props.stats['Defense']}%</p>
<p>Health: {this.props.stats['Health']}%</p>
<p>March Speed: {this.props.stats['March Speed']}%</p>
</div>
</div>
);
Expand Down
19 changes: 8 additions & 11 deletions src/StatsTalentsPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,10 @@ class StatsTalentsPanel extends Component {
}

/**
* Calculate an array of the bonus stats that don't belong in any of
* the base state categories
* Calculate an array of main talents that don't belong in any of
* the base stat categories
*
* @param {string} stat Name of the stat to be calculated (e.g. Defense)
* @returns {String[]} Array of all selected main talents
* @returns {DOMElement[]} Array of all selected main talents
* @memberof StatsTalentsPanel
*/
calcStatsTalents() {
Expand Down Expand Up @@ -91,19 +90,17 @@ class StatsTalentsPanel extends Component {
}

render() {
const mainTalents = this.calcStatsTalents();
return (
<div
id="stats-talents"
className="info-box"
onClick={this.toggleStatsTalents}
>
<h2>
Main Talents{' '}
<span className="stats-talents-expand">
{this.state.isShownStatsTalents ? '(collapse)' : '(expand)'}
</span>
</h2>
<div data-testid="stats-talents">{this.calcStatsTalents()}</div>
<h2 id="stats-talents-title">Main Talents</h2>
<div data-testid="stats-talents">
{mainTalents.length === 0 ? 'None' : mainTalents}
</div>
</div>
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/TreePanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ class TreePanel extends Component {

{this.props.dataVersion < dataVersion && (
<div data-testid="version-warning" id="version-warning">
(warning: this build uses an old <br /> version of the game data)
Warning: this build uses an old version <br /> of the game data
</div>
)}

Expand Down
15 changes: 15 additions & 0 deletions src/__tests__/InfoPanel.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,22 @@ import { render, cleanup } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import InfoPanel from '../InfoPanel';

Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation(query => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(),
removeListener: jest.fn(),
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn()
}))
});

let props;

beforeEach(() => {
props = {
calcPointsRemaining: jest.fn(),
Expand Down
4 changes: 1 addition & 3 deletions src/__tests__/StatsPanel.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import StatsPanel from '../StatsPanel';
let props;
beforeEach(() => {
props = {
red: [],
yellow: [],
blue: []
stats: { stats: { Attack: 0, Defense: 0, Health: 0, 'March Speed': 0 } }
};
});

Expand Down
Loading

0 comments on commit 34347de

Please sign in to comment.