Add tests for canLearnTalent and canUnlearnTalent
This commit is contained in:
+1
-1
@@ -55,7 +55,7 @@ body {
|
|||||||
|
|
||||||
&__class {
|
&__class {
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
opacity: .8;
|
opacity: 1;
|
||||||
transition: all .1s ease-out;
|
transition: all .1s ease-out;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
|||||||
+2
-1
@@ -5,7 +5,8 @@ import { BrowserRouter as Router, Route } from 'react-router-dom'
|
|||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<Router basename={process.env.NODE_ENV !== 'development' ? '%PUBLIC_URL%' : ''}>
|
<Router basename={process.env.NODE_ENV === 'production' ? '/wow-talent-calculator' : ''}>
|
||||||
|
{/* <Router basename={process.env.NODE_ENV !== 'development' ? '%PUBLIC_URL%' : ''}> */}
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<Route path="/:selectedClass?/:pointString?" component={IndexRoute} />
|
<Route path="/:selectedClass?/:pointString?" component={IndexRoute} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+47
-11
@@ -1,5 +1,21 @@
|
|||||||
@import "../sass/config";
|
@import "../sass/config";
|
||||||
|
|
||||||
|
@function baseRowTopOffset($row) {
|
||||||
|
@return $row-offset + ($row * $row-distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@function calcLeftOffset($col) {
|
||||||
|
@return $col-offset + ($col-gutter * ($col - 1)) + $icon-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@function calcRightOffset($col) {
|
||||||
|
@return $col-offset + ($col-distance * $col) + $icon-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@function calcArrowHeight($length) {
|
||||||
|
@return 2px + ($row-offset * $length) + ($icon-size * ($length - 1))
|
||||||
|
}
|
||||||
|
|
||||||
.arrow {
|
.arrow {
|
||||||
$arrow-width: 15px;
|
$arrow-width: 15px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -11,7 +27,7 @@
|
|||||||
// Rows
|
// Rows
|
||||||
@for $i from 0 through 6 {
|
@for $i from 0 through 6 {
|
||||||
&[data-row="#{$i}"] {
|
&[data-row="#{$i}"] {
|
||||||
top: 12px + $row-offset + (($i) * $row-distance);
|
top: 12px + baseRowTopOffset($i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,50 +40,50 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&--right {
|
&--right {
|
||||||
background-image: url('/images/arrows/right.png');
|
background-image: url('../images/arrows/right.png');
|
||||||
background-position: center right;
|
background-position: center right;
|
||||||
|
|
||||||
&.arrow--active {
|
&.arrow--active {
|
||||||
background-image: url('/images/arrows/right-active.png');
|
background-image: url('../images/arrows/right-active.png');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cols
|
// Cols
|
||||||
@for $i from 0 through 3 {
|
@for $i from 0 through 3 {
|
||||||
&[data-col="#{$i}"] {
|
&[data-col="#{$i}"] {
|
||||||
left: 3px + $col-offset + ($col-distance * $i) + $icon-size;
|
left: 3px + calcRightOffset($i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&--left {
|
&--left {
|
||||||
background-image: url('/images/arrows/left.png');
|
background-image: url('../images/arrows/left.png');
|
||||||
background-position: center left;
|
background-position: center left;
|
||||||
|
|
||||||
&.arrow--active {
|
&.arrow--active {
|
||||||
background-image: url('/images/arrows/left-active.png');
|
background-image: url('../images/arrows/left-active.png');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cols
|
// Cols
|
||||||
@for $i from 0 through 3 {
|
@for $i from 0 through 3 {
|
||||||
&[data-col="#{$i}"] {
|
&[data-col="#{$i}"] {
|
||||||
left: -3px + $col-offset + ($col-gutter * ($i - 1)) + $icon-size;
|
left: -3px + calcLeftOffset($i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&--down {
|
&--down {
|
||||||
width: $arrow-width;
|
width: $arrow-width;
|
||||||
background-image: url('/images/arrows/down.png');
|
background-image: url('../images/arrows/down.png');
|
||||||
background-position: center bottom;
|
background-position: center bottom;
|
||||||
|
|
||||||
&.arrow--active {
|
&.arrow--active {
|
||||||
background-image: url('/images/arrows/down-active.png');
|
background-image: url('../images/arrows/down-active.png');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rows
|
// Rows
|
||||||
@for $i from 0 through 6 {
|
@for $i from 0 through 6 {
|
||||||
&[data-row="#{$i}"] {
|
&[data-row="#{$i}"] {
|
||||||
top: $row-offset + (($i) * $row-distance) + 40px;
|
top: 40px + baseRowTopOffset($i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,8 +97,28 @@
|
|||||||
// Lengths
|
// Lengths
|
||||||
@for $i from 0 through 3 {
|
@for $i from 0 through 3 {
|
||||||
&[data-length="#{$i}"] {
|
&[data-length="#{$i}"] {
|
||||||
height: 2px + ($row-offset * $i) + ($icon-size * ($i - 1));
|
height: calcArrowHeight($i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&--right-down {
|
||||||
|
// Horizontal
|
||||||
|
::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
height: $arrow-width;
|
||||||
|
background-image: url('../images/arrows/rightdown.png');
|
||||||
|
background-position: center right;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vertical
|
||||||
|
::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
width: $arrow-width;
|
||||||
|
background-image: url('../images/arrows/down.png');
|
||||||
|
background-position: center bottom;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,11 +4,14 @@ import { TalentTree } from './TalentTree'
|
|||||||
import {
|
import {
|
||||||
modifyTalentPoint,
|
modifyTalentPoint,
|
||||||
calcAvailablePoints,
|
calcAvailablePoints,
|
||||||
encodeKnownTalents
|
encodeKnownTalents,
|
||||||
|
SORT_TALENTS_BY_SPEC
|
||||||
} from '../lib/tree'
|
} from '../lib/tree'
|
||||||
import { talentsBySpec } from '../data/talents'
|
import { talentsBySpec, talentsById } from '../data/talents'
|
||||||
import { classByName } from '../data/classes'
|
import { classByName } from '../data/classes'
|
||||||
import { History } from 'history'
|
import { History } from 'history'
|
||||||
|
import { spells } from '../data/spells'
|
||||||
|
import { debugPrintKnown } from '../lib/debug'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
selectedClass: string
|
selectedClass: string
|
||||||
@@ -56,13 +59,16 @@ export class Calculator extends React.PureComponent<Props> {
|
|||||||
|
|
||||||
handleTalentPress = (specId: number, talentId: number, modifier: 1 | -1) => {
|
handleTalentPress = (specId: number, talentId: number, modifier: 1 | -1) => {
|
||||||
const talent = talentsBySpec[specId][talentId]
|
const talent = talentsBySpec[specId][talentId]
|
||||||
console.log('Clicked talent: ' + talentId)
|
console.log('Clicked talent: ', talentId)
|
||||||
|
|
||||||
const newKnownTalents = modifyTalentPoint(this.state.knownTalents, talent, modifier)
|
const newKnownTalents = modifyTalentPoint(this.state.knownTalents, talent, modifier)
|
||||||
if (newKnownTalents !== this.state.knownTalents) {
|
if (newKnownTalents !== this.state.knownTalents) {
|
||||||
this.updateURL(newKnownTalents)
|
this.updateURL(newKnownTalents)
|
||||||
}
|
}
|
||||||
this.setState({ knownTalents: newKnownTalents })
|
this.setState({ knownTalents: newKnownTalents })
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
debugPrintKnown(newKnownTalents)
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -93,7 +99,8 @@ export class Calculator extends React.PureComponent<Props> {
|
|||||||
<ul>
|
<ul>
|
||||||
<li><a href="/shaman/-5505000055523051-55">Shaman test</a></li>
|
<li><a href="/shaman/-5505000055523051-55">Shaman test</a></li>
|
||||||
<li><a href="/shaman/-5595000055523051-55">Shaman test broken</a></li>
|
<li><a href="/shaman/-5595000055523051-55">Shaman test broken</a></li>
|
||||||
<li><a href="/rogue/-005055-50205302332212051">Rogue can unlearn first row</a></li>
|
<li><a href="/rogue/-005055-50205302332212051">Rogue (should break, does not meet requirement)</a></li>
|
||||||
|
<li><a href="/rogue/-005055-50205302333212041">Rogue can unlearn first row AND dependency</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import './Tooltip.scss'
|
||||||
|
import React, { FC } from 'react'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Tooltip: FC<Props> = (props) => {
|
||||||
|
return <div className="tooltip">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { Map } from 'immutable'
|
||||||
|
import { SORT_TALENTS_BY_SPEC } from './tree'
|
||||||
|
import { talentsById } from '../data/talents'
|
||||||
|
|
||||||
|
export const debugPrintKnown = (known: Map<number, number>) => {
|
||||||
|
const obj = {}
|
||||||
|
known.toArray()
|
||||||
|
.map(([talentId]) => talentsById[talentId])
|
||||||
|
.sort(SORT_TALENTS_BY_SPEC)
|
||||||
|
.forEach(talent => { obj[talent.id] = known.get(talent.id) })
|
||||||
|
|
||||||
|
console.log(JSON.stringify(obj, null, 2))
|
||||||
|
}
|
||||||
+85
-31
@@ -1,40 +1,94 @@
|
|||||||
import im from 'immutable'
|
import im, {
|
||||||
|
Map
|
||||||
|
} from 'immutable'
|
||||||
import {
|
import {
|
||||||
// setTalentPointsInTree,
|
canUnlearnTalent, canLearnTalent
|
||||||
getPointsInSpec
|
|
||||||
} from './tree'
|
} from './tree'
|
||||||
|
import {
|
||||||
|
talentsById
|
||||||
|
} from '../data/talents'
|
||||||
|
|
||||||
|
const createKnownTalents = (obj: object): Map <number, number> => {
|
||||||
|
let m = Map<number, number>()
|
||||||
|
Object.keys(obj).forEach((key) => {
|
||||||
|
m = m.set(parseInt(key, 10), obj[key])
|
||||||
|
})
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
// describe('setTalentPointsInTree', () => {
|
const ROGUE_TALENTS = createKnownTalents({
|
||||||
// it('sets points on an empty tree', () => {
|
241: 5, // Master of Deception
|
||||||
// const tree = im.List()
|
181: 5,
|
||||||
// expect(setTalentPointsInTree(tree, 2, 5).toJS()).toEqual([0, 0, 5])
|
186: 5,
|
||||||
// })
|
187: 5,
|
||||||
|
244: 5,
|
||||||
|
245: 3,
|
||||||
|
246: 3,
|
||||||
|
262: 3,
|
||||||
|
263: 2,
|
||||||
|
265: 2,
|
||||||
|
284: 1,
|
||||||
|
381: 1,
|
||||||
|
1123: 3,
|
||||||
|
1700: 2,
|
||||||
|
1701: 2,
|
||||||
|
1702: 5
|
||||||
|
})
|
||||||
|
|
||||||
// it('sets points in the end of the current range', () => {
|
describe('canUnlearnTalent', () => {
|
||||||
// const tree = im.List([0, 1])
|
it('returns false for the incorrect Rogue talent case', () => {
|
||||||
// expect(setTalentPointsInTree(tree, 2, 5).toJS()).toEqual([0, 1, 5])
|
const result = canUnlearnTalent(ROGUE_TALENTS, talentsById[241])
|
||||||
// })
|
expect(result).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
// it('sets points in the middle of the current range', () => {
|
it('returns false if no points are spent for the talent', () => {
|
||||||
// const tree = im.List([0, 0, 0, 0, 0, 0, 5])
|
const result = canUnlearnTalent(Map(), talentsById[241])
|
||||||
// expect(setTalentPointsInTree(tree, 2, 5).toJS()).toEqual([0, 0, 5, 0, 0, 0, 5])
|
expect(result).toBe(false)
|
||||||
// })
|
})
|
||||||
|
|
||||||
// it('does not mutate the tree for points already set', () => {
|
it('returns false if the talent is a dependency for another learnt talent', () => {
|
||||||
// const tree = im.List([0, 3, 2, 0, 5])
|
// http://localhost:3000/rogue/-00505001
|
||||||
// expect(setTalentPointsInTree(tree, 1, 3)).toStrictEqual(tree)
|
const known = createKnownTalents({
|
||||||
// })
|
186: 5, // Row 1
|
||||||
// })
|
187: 5, // Row 2
|
||||||
|
301: 1, // Row 3
|
||||||
|
})
|
||||||
|
const result = canUnlearnTalent(known, talentsById[187])
|
||||||
|
expect(result).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
// describe('getTreePointCount', () => {
|
it('returns true with points only spent in the first row', () => {
|
||||||
// it('returns proper count', () => {
|
const known = createKnownTalents({
|
||||||
// const result = getPointsInSpec(im.List([0, 0, 4, 5, 3, 0, 0]))
|
241: 5
|
||||||
// expect(result).toBe(12)
|
})
|
||||||
// })
|
const result = canUnlearnTalent(known, talentsById[241])
|
||||||
|
expect(result).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
// it('returns 0 for empty list', () => {
|
describe('canLearnTalent', () => {
|
||||||
// const result = getPointsInSpec(im.List())
|
it('returns false if 51 points are already spent', () => {
|
||||||
// expect(result).toBe(0)
|
// http://localhost:3000/rogue/-005055010055505-55005
|
||||||
// })
|
const known = createKnownTalents({
|
||||||
// })
|
"181": 5,
|
||||||
|
"182": 5,
|
||||||
|
"184": 5,
|
||||||
|
"186": 5,
|
||||||
|
"187": 5,
|
||||||
|
"221": 5,
|
||||||
|
"222": 1,
|
||||||
|
"241": 5,
|
||||||
|
"242": 4,
|
||||||
|
"244": 5,
|
||||||
|
"261": 5,
|
||||||
|
"301": 1
|
||||||
|
})
|
||||||
|
const result = canLearnTalent(known, talentsById[222])
|
||||||
|
expect(result).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns true for talent in the first row', () => {
|
||||||
|
const result = canLearnTalent(Map(), talentsById[186])
|
||||||
|
expect(result).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
+60
-57
@@ -16,6 +16,15 @@ export const SORT_TALENTS = (a: TalentData, b: TalentData) => {
|
|||||||
return a.row - b.row
|
return a.row - b.row
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const SORT_TALENTS_BY_SPEC = (a: TalentData, b: TalentData) => {
|
||||||
|
const aSpec = talentToSpec[a.id]
|
||||||
|
const bSpec = talentToSpec[b.id]
|
||||||
|
if (aSpec === bSpec) {
|
||||||
|
return SORT_TALENTS(a, b)
|
||||||
|
}
|
||||||
|
return aSpec - bSpec
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the overall points spent in the tree.
|
* Returns the overall points spent in the tree.
|
||||||
*/
|
*/
|
||||||
@@ -69,6 +78,56 @@ export const canLearnTalent = (known: Map<number, number>, talent: TalentData):
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getCumulativePointsPerRow = (known: Map<number, number>, specId: number): number[] => {
|
||||||
|
return known.reduce((reduction, points, talentId) => {
|
||||||
|
const t = talentsBySpec[specId][talentId]
|
||||||
|
if (t && points > 0) {
|
||||||
|
for (let row = t.row; row < MAX_ROWS; row++) {
|
||||||
|
reduction[row] = (reduction[row] || 0) + points
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return reduction
|
||||||
|
}, [])
|
||||||
|
}
|
||||||
|
|
||||||
|
export const canUnlearnTalent = (known: Map<number, number>, talent: TalentData): boolean => {
|
||||||
|
const currentPoints = known.get(talent.id, 0)
|
||||||
|
const specId = talentToSpec[talent.id]
|
||||||
|
|
||||||
|
// No points to reduce for this talent
|
||||||
|
if (currentPoints === 0) {
|
||||||
|
console.warn('no points to reduce')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent if another talent depends on this
|
||||||
|
const isDependency = known.some((points, talentId) => {
|
||||||
|
const t = talentsBySpec[specId][talentId]
|
||||||
|
return t && points > 0 && t.requires.some((req) => req.id === talent.id)
|
||||||
|
})
|
||||||
|
if (isDependency) {
|
||||||
|
console.warn('is dependency')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Walk through every talent and ensure no requirements are breached
|
||||||
|
let cumulativePointsPerRow = getCumulativePointsPerRow(known, specId)
|
||||||
|
for (let r = talent.row; r < cumulativePointsPerRow.length; r++) {
|
||||||
|
// Calculate what the points would look like when this one is removed
|
||||||
|
cumulativePointsPerRow[r] = cumulativePointsPerRow[r] - 1
|
||||||
|
}
|
||||||
|
const wouldBreach = known.some((points, talentId) => {
|
||||||
|
const t = talentsBySpec[specId][talentId]
|
||||||
|
return t && points > 0 && t.row > 0 && cumulativePointsPerRow[t.row - 1] < t.row * 5
|
||||||
|
})
|
||||||
|
if (wouldBreach) {
|
||||||
|
console.warn('point requirements would be breached')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a single talent point to the Map, if possible.
|
* Adds a single talent point to the Map, if possible.
|
||||||
*/
|
*/
|
||||||
@@ -87,48 +146,8 @@ export const addTalentPoint = (known: Map<number, number>, talent: TalentData):
|
|||||||
*/
|
*/
|
||||||
export const removeTalentPoint = (known: Map<number, number>, talent: TalentData): Map<number, number> => {
|
export const removeTalentPoint = (known: Map<number, number>, talent: TalentData): Map<number, number> => {
|
||||||
const currentPoints = known.get(talent.id, 0)
|
const currentPoints = known.get(talent.id, 0)
|
||||||
const specId = talentToSpec[talent.id]
|
|
||||||
|
|
||||||
// No points to reduce for this talent
|
if (!canUnlearnTalent(known, talent)) {
|
||||||
if (currentPoints === 0) {
|
|
||||||
console.warn('no points to reduce')
|
|
||||||
return known
|
|
||||||
}
|
|
||||||
|
|
||||||
let isDependency = false
|
|
||||||
let highestRow = 0
|
|
||||||
let cumulativePointsPerRow = {}
|
|
||||||
|
|
||||||
known.forEach((points, talentId) => {
|
|
||||||
const t = talentsBySpec[specId][talentId]
|
|
||||||
if (t && points > 0) {
|
|
||||||
isDependency = isDependency || t.requires.some((req) => req.id === talent.id)
|
|
||||||
if (t.row > highestRow) {
|
|
||||||
console.info('new highest row:', t)
|
|
||||||
}
|
|
||||||
highestRow = t.row > highestRow ? t.row : highestRow
|
|
||||||
for (let row = t.row; row < MAX_ROWS; row++) {
|
|
||||||
cumulativePointsPerRow[row] = (cumulativePointsPerRow[row] || 0) + points
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Check if removing this talent would not break the requirements for talents spent in later rows
|
|
||||||
const pointsUntilHighestRow = cumulativePointsPerRow[highestRow - 1]
|
|
||||||
const targetPointsHighestRow = highestRow * 5
|
|
||||||
if (talent.row < highestRow && pointsUntilHighestRow - 1 < targetPointsHighestRow) {
|
|
||||||
console.warn('would not break the requirements for talents spent in later rows', {
|
|
||||||
talent,
|
|
||||||
highestRow,
|
|
||||||
pointsUntilHighestRow,
|
|
||||||
targetPointsHighestRow
|
|
||||||
})
|
|
||||||
return known
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prevent if another talent depends on this
|
|
||||||
if (isDependency) {
|
|
||||||
console.warn('is dependency')
|
|
||||||
return known
|
return known
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,19 +167,6 @@ export const modifyTalentPoint = (known: Map<number, number>, talent: TalentData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
|
||||||
export function parsePointString(str: string): List<List<number>> {
|
|
||||||
const list: Array<number[]> = []
|
|
||||||
const trees = str.split('-')
|
|
||||||
|
|
||||||
trees.forEach((stringForTree, index) => {
|
|
||||||
const points = stringForTree.split('').map(a => parseInt(a, 10))
|
|
||||||
list[index] = points
|
|
||||||
})
|
|
||||||
|
|
||||||
return fromJS(list)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encodes a Map of known talents into a URL-friendly string.
|
* Encodes a Map of known talents into a URL-friendly string.
|
||||||
*/
|
*/
|
||||||
@@ -183,8 +189,6 @@ export function encodeKnownTalents(known: Map<number, number>, className: string
|
|||||||
* Decodes a string of points into a Map of talents.
|
* Decodes a string of points into a Map of talents.
|
||||||
*/
|
*/
|
||||||
export function decodeKnownTalents(pointString: string, className: string): Map<number, number> {
|
export function decodeKnownTalents(pointString: string, className: string): Map<number, number> {
|
||||||
console.log(pointString, className)
|
|
||||||
|
|
||||||
const { specs } = classByName[className]
|
const { specs } = classByName[className]
|
||||||
let known = Map<number, number>()
|
let known = Map<number, number>()
|
||||||
|
|
||||||
@@ -206,7 +210,6 @@ export function decodeKnownTalents(pointString: string, className: string): Map<
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (points > 0) {
|
if (points > 0) {
|
||||||
console.log(`Spent ${points} in ${talent.id}`)
|
|
||||||
known = known.set(talent.id, points)
|
known = known.set(talent.id, points)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user