From 06723fec6dfd19eb2357c4bbbb3ae689f3786b6a Mon Sep 17 00:00:00 2001 From: Melvin Valster Date: Sun, 21 Jul 2019 23:11:50 +0200 Subject: [PATCH] Proof of concept for encoding known talents into URL --- TODO.md | 4 ++- src/components/Calculator.tsx | 25 ++++++++++++++++--- src/components/IndexRoute.tsx | 7 ++++-- src/lib/tree.ts | 47 ++++++++++++++++++++++++++++++++++- 4 files changed, 75 insertions(+), 8 deletions(-) diff --git a/TODO.md b/TODO.md index 9180373..05442f3 100644 --- a/TODO.md +++ b/TODO.md @@ -4,7 +4,9 @@ - [ ] Talent tooltips - [ ] Generate URL for chosen talents - [ ] Responsive on mobile -- [ ] Pretty ClassPicker +- [ ] Prettier talent frames +- [ ] Prettier icon frames & coloring +- [x] Pretty ClassPicker - [x] Add react-router - [x] Prevent reducing talent points on a row when it is a dependency for points already spent in the next row - [x] Prevent reducing talent points on a talent that is a requirement for another talent with points in it diff --git a/src/components/Calculator.tsx b/src/components/Calculator.tsx index cdef45f..c26c8d0 100644 --- a/src/components/Calculator.tsx +++ b/src/components/Calculator.tsx @@ -3,16 +3,28 @@ import { Map } from 'immutable' import { TalentTree } from './TalentTree' import { modifyTalentPoint, - calcAvailablePoints + calcAvailablePoints, + encodeKnownTalents } from '../lib/tree' import { talentsBySpec } from '../data/talents' import { classByName } from '../data/classes' +import { History } from 'history' interface Props { selectedClass: string + history: History } +// const EMPTY_TALENTS = Map() const EMPTY_TALENTS = Map() + // .set(30, 5) + // .set(26, 5) + // .set(34, 5) + // .set(28, 2) + // .set(27, 3) + // .set(33, 1) + // .set(29, 1) + // .set(32, 1) export class Calculator extends React.PureComponent { static whyDidYouRender = true @@ -30,10 +42,15 @@ export class Calculator extends React.PureComponent { } handleTalentPress = (specId: number, talentId: number, modifier: 1 | -1) => { + const { selectedClass } = this.props const talent = talentsBySpec[specId][talentId] - this.setState({ - knownTalents: modifyTalentPoint(this.state.knownTalents, talent, modifier) - }) + console.log('Clicked talent: ' + talentId) + + const newKnownTalents = modifyTalentPoint(this.state.knownTalents, talent, modifier) + this.setState({ knownTalents: newKnownTalents }) + + const pointString = encodeKnownTalents(newKnownTalents, selectedClass) + this.props.history.replace(`/${selectedClass}/${pointString}`) } render() { diff --git a/src/components/IndexRoute.tsx b/src/components/IndexRoute.tsx index 65b2c3d..765aaa7 100644 --- a/src/components/IndexRoute.tsx +++ b/src/components/IndexRoute.tsx @@ -15,7 +15,7 @@ export class IndexRoute extends React.PureComponent { static whyDidYouRender = true render() { - const { match } = this.props + const { match, history } = this.props const { selectedClass, pointString } = match.params return ( @@ -23,7 +23,10 @@ export class IndexRoute extends React.PureComponent { {selectedClass && - + } ) diff --git a/src/lib/tree.ts b/src/lib/tree.ts index 75b9881..51ab682 100644 --- a/src/lib/tree.ts +++ b/src/lib/tree.ts @@ -1,5 +1,10 @@ import { List, Map, fromJS } from 'immutable' -import { talentsBySpec, talentToSpec, talentsById } from '../data/talents'; +import { + talentsBySpec, + talentToSpec, + talentsBySpecArray +} from '../data/talents'; +import { classByName } from '../data/classes' export const MAX_POINTS = 51 export const MAX_ROWS = 7 @@ -128,4 +133,44 @@ export function parsePointString(str: string): List> { }) return fromJS(list) +} + +/** + * Encodes a Map of known talents into a URL-friendly string. + */ +export function encodeKnownTalents(known: Map, className: string): string { + let string = '' + const { specs } = classByName[className] + for (let i = 0; i < specs.length; i++) { + const specId = specs[i] + const talents = talentsBySpecArray[specId].sort((a, b) => { + if (a.row === b.row) { + return a.col - b.col + } + return a.row - b.row + }) + string += i > 0 ? '-' : '' + string += removeTrailingCharacters( + talents.map((talent) => known.get(talent.id, 0)).join(''), + '0' + ) + } + return removeTrailingCharacters(string, '-') +} + +/** + * Decodes a string of points into a Map of talents. + */ +export function decodeKnownTalents(pointString: string, className: string): Map { + return Map() +} + +/** + * Removes repeated characters from the end of a string. + */ +function removeTrailingCharacters(str: string, char: string): string { + while (str[str.length - 1] === char) { + str = str.slice(0, -1) + } + return str } \ No newline at end of file