Split up more scss and fix so arrow starts from under the icon
This commit is contained in:
@@ -6,8 +6,8 @@
|
|||||||
- [ ] General: Responsive on mobile
|
- [ ] General: Responsive on mobile
|
||||||
- [ ] Talent tree: Reset button per tree (?)
|
- [ ] Talent tree: Reset button per tree (?)
|
||||||
- [ ] Fix: Initial load `pointString` validation (make sure all talents are valid and their deps are met)
|
- [ ] Fix: Initial load `pointString` validation (make sure all talents are valid and their deps are met)
|
||||||
- [ ] Fix: Arrow should start underneath the icon
|
|
||||||
- [ ] Fix: Navigating between talent links for same class does not trigger re-render
|
- [ ] Fix: Navigating between talent links for same class does not trigger re-render
|
||||||
|
- [x] Fix: Arrow should start underneath the icon
|
||||||
- [x] Talent tree: Arrows for dependencies
|
- [x] Talent tree: Arrows for dependencies
|
||||||
- [x] System: Generate URL for chosen talents
|
- [x] System: Generate URL for chosen talents
|
||||||
- [x] Talent tree: Prettier talent frames
|
- [x] Talent tree: Prettier talent frames
|
||||||
|
|||||||
@@ -52,58 +52,6 @@ a {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.trees {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tree {
|
|
||||||
position: relative;
|
|
||||||
min-width: 300px;
|
|
||||||
color: white;
|
|
||||||
margin-right: 1em;
|
|
||||||
background-color: #111;
|
|
||||||
|
|
||||||
.talent {
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
// Rows
|
|
||||||
@for $i from 0 through 6 {
|
|
||||||
&[data-row="#{$i}"] {
|
|
||||||
top: $row-offset + (($i) * $row-distance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Columns
|
|
||||||
@for $i from 0 through 3 {
|
|
||||||
&[data-col="#{$i}"] {
|
|
||||||
left: $col-offset + ($col-distance * $i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__header {
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
margin-top: .75em;
|
|
||||||
margin-bottom: .75em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__body {
|
|
||||||
position: relative;
|
|
||||||
height: 520px;
|
|
||||||
border: 1px solid black;
|
|
||||||
background-size: cover;
|
|
||||||
background-position: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.index {
|
.index {
|
||||||
min-height: 85vh;
|
min-height: 85vh;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,14 +19,6 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const EMPTY_TALENTS = Map<number, number>()
|
const EMPTY_TALENTS = Map<number, number>()
|
||||||
// .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<Props> {
|
export class Calculator extends React.PureComponent<Props> {
|
||||||
static whyDidYouRender = true
|
static whyDidYouRender = true
|
||||||
|
|||||||
@@ -63,4 +63,4 @@ export const Talent: FC<Props> = (props) => {
|
|||||||
|
|
||||||
Talent.defaultProps = defaultProps
|
Talent.defaultProps = defaultProps
|
||||||
|
|
||||||
// ;(Talent as any).whyDidYouRender = true
|
;(Talent as any).whyDidYouRender = true
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
@import "../sass/config";
|
||||||
|
|
||||||
|
.trees {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree {
|
||||||
|
position: relative;
|
||||||
|
min-width: 300px;
|
||||||
|
color: white;
|
||||||
|
margin-right: 1em;
|
||||||
|
background-color: #111;
|
||||||
|
|
||||||
|
.talent {
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
// Rows
|
||||||
|
@for $i from 0 through 6 {
|
||||||
|
&[data-row="#{$i}"] {
|
||||||
|
top: $row-offset + (($i) * $row-distance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Columns
|
||||||
|
@for $i from 0 through 3 {
|
||||||
|
&[data-col="#{$i}"] {
|
||||||
|
left: $col-offset + ($col-distance * $i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__header {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin-top: .75em;
|
||||||
|
margin-bottom: .75em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__body {
|
||||||
|
position: relative;
|
||||||
|
height: 520px;
|
||||||
|
border: 1px solid black;
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
|
import './TalentTree.scss'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback } from 'react'
|
||||||
import { Map } from 'immutable'
|
import { Map } from 'immutable'
|
||||||
import { Talent } from './Talent';
|
import { Talent } from './Talent';
|
||||||
import { getPointsInSpec, canLearnTalent, calcMeetsRequirements } from '../lib/tree';
|
import { getPointsInSpec, canLearnTalent, calcMeetsRequirements, SORT_TALENTS_DESC } from '../lib/tree';
|
||||||
import { talentsBySpec, specNames, talentsById, talentToSpec } from '../data/talents'
|
import { talentsBySpec, specNames, talentsById, talentToSpec } from '../data/talents'
|
||||||
import { Arrow } from './Arrow'
|
import { Arrow } from './Arrow'
|
||||||
|
|
||||||
@@ -13,8 +14,7 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const TalentTree: React.FC<Props> = ({ specId, knownTalents, availablePoints, onTalentPress }) => {
|
export const TalentTree: React.FC<Props> = ({ specId, knownTalents, availablePoints, onTalentPress }) => {
|
||||||
const talents = Object.values(talentsBySpec[specId])
|
const talents = Object.values(talentsBySpec[specId]).sort(SORT_TALENTS_DESC)
|
||||||
const bgImg = require(`../images/specs/${specId}.jpg`)
|
|
||||||
|
|
||||||
const handleClick = useCallback(
|
const handleClick = useCallback(
|
||||||
(talentId) => onTalentPress(specId, talentId, 1),
|
(talentId) => onTalentPress(specId, talentId, 1),
|
||||||
@@ -25,50 +25,40 @@ export const TalentTree: React.FC<Props> = ({ specId, knownTalents, availablePoi
|
|||||||
[specId, onTalentPress]
|
[specId, onTalentPress]
|
||||||
)
|
)
|
||||||
|
|
||||||
const arrows = talents
|
|
||||||
.filter((talent) => talent.requires.length)
|
|
||||||
.map((talent) => {
|
|
||||||
return <Arrow
|
|
||||||
key={talent.id}
|
|
||||||
from={talentsById[talent.requires[0].id]}
|
|
||||||
to={talent}
|
|
||||||
active={knownTalents.get(talent.id, 0) > 0 || canLearnTalent(knownTalents, talent)}
|
|
||||||
/>
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="tree">
|
<div className="tree">
|
||||||
<div className="tree__header">
|
<div className="tree__header">
|
||||||
<h3>{specNames[specId]} ({getPointsInSpec(specId, knownTalents)})</h3>
|
<h3>{specNames[specId]} ({getPointsInSpec(specId, knownTalents)})</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="tree__body" style={{ backgroundImage: `url(${bgImg})` }}>
|
<div className="tree__body" style={{ backgroundImage: `url(${require(`../images/specs/${specId}.jpg`)})` }}>
|
||||||
{talents.map((talent) =>
|
{talents.map((talent) => {
|
||||||
<Talent
|
const points = knownTalents.get(talent.id, 0)
|
||||||
key={talent.id}
|
const canLearn = canLearnTalent(knownTalents, talent)
|
||||||
talent={talent}
|
|
||||||
points={knownTalents.get(talent.id, 0)}
|
|
||||||
onClick={handleClick}
|
|
||||||
onRightClick={handleRightClick}
|
|
||||||
disabled={availablePoints === 0 || !isAvailable(talent, knownTalents)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{arrows}
|
return <React.Fragment>
|
||||||
|
<Talent
|
||||||
|
key={talent.id}
|
||||||
|
talent={talent}
|
||||||
|
points={points}
|
||||||
|
onClick={handleClick}
|
||||||
|
onRightClick={handleRightClick}
|
||||||
|
disabled={availablePoints === 0 || !canLearn}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{!!talent.requires.length &&
|
||||||
|
<Arrow
|
||||||
|
key={`arrow-${talent.id}`}
|
||||||
|
from={talentsById[talent.requires[0].id]}
|
||||||
|
to={talent}
|
||||||
|
active={points > 0 || canLearn}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</React.Fragment>
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// move this somewhere else/revise this
|
|
||||||
export const isAvailable = (talent: TalentData, knownTalents: Map<number, number>): boolean => {
|
|
||||||
// Dependent on other talents?
|
|
||||||
if (!calcMeetsRequirements(talent, knownTalents)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
const specId = talentToSpec[talent.id]
|
|
||||||
const pointsInSpec = getPointsInSpec(specId, knownTalents)
|
|
||||||
return talent.row * 5 <= pointsInSpec
|
|
||||||
}
|
|
||||||
|
|
||||||
;(TalentTree as any).whyDidYouRender = true
|
;(TalentTree as any).whyDidYouRender = true
|
||||||
@@ -16,6 +16,13 @@ export const SORT_TALENTS = (a: TalentData, b: TalentData) => {
|
|||||||
return a.row - b.row
|
return a.row - b.row
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const SORT_TALENTS_DESC = (a: TalentData, b: TalentData) => {
|
||||||
|
if (a.row === b.row) {
|
||||||
|
return b.col - a.col
|
||||||
|
}
|
||||||
|
return b.row - a.row
|
||||||
|
}
|
||||||
|
|
||||||
export const SORT_TALENTS_BY_SPEC = (a: TalentData, b: TalentData) => {
|
export const SORT_TALENTS_BY_SPEC = (a: TalentData, b: TalentData) => {
|
||||||
const aSpec = talentToSpec[a.id]
|
const aSpec = talentToSpec[a.id]
|
||||||
const bSpec = talentToSpec[b.id]
|
const bSpec = talentToSpec[b.id]
|
||||||
|
|||||||
Reference in New Issue
Block a user