mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-04-24 23:19:39 -05:00
LDE and OG
This commit is contained in:
parent
1b80e5022b
commit
ac7a2d6f58
|
|
@ -3,7 +3,7 @@ import { RouteComponentProps } from "@reach/router"
|
|||
import React, { useState, useContext } from "react"
|
||||
import { Helmet } from "react-helmet-async"
|
||||
import useAbilityEffects from "../../hooks/useAbilityEffects"
|
||||
import { Build } from "../../types"
|
||||
import { Build, Ability } from "../../types"
|
||||
import PageHeader from "../common/PageHeader"
|
||||
import WeaponSelector from "../common/WeaponSelector"
|
||||
import BuildStats from "./BuildStats"
|
||||
|
|
@ -13,6 +13,7 @@ import { FaWrench } from "react-icons/fa"
|
|||
import Button from "../elements/Button"
|
||||
|
||||
const defaultBuild: Partial<Build> = {
|
||||
weapon: ".96 Gal",
|
||||
headgear: ["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
|
||||
clothing: ["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
|
||||
shoes: ["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
|
||||
|
|
@ -28,9 +29,13 @@ const BuildAnalyzerPage: React.FC<RouteComponentProps> = () => {
|
|||
const [otherFocused, setOtherFocused] = useState(false)
|
||||
const [hideExtra, setHideExtra] = useState(true)
|
||||
const [showSettings, setShowSettings] = useState(false)
|
||||
const [bonusAp, setBonusAp] = useState<Partial<Record<Ability, boolean>>>({})
|
||||
const [otherBonusAp, setOtherBonusAp] = useState<
|
||||
Partial<Record<Ability, boolean>>
|
||||
>({})
|
||||
|
||||
const explanations = useAbilityEffects(build)
|
||||
const otherExplanations = useAbilityEffects(otherBuild)
|
||||
const explanations = useAbilityEffects(build, bonusAp)
|
||||
const otherExplanations = useAbilityEffects(otherBuild, otherBonusAp)
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -67,6 +72,10 @@ const BuildAnalyzerPage: React.FC<RouteComponentProps> = () => {
|
|||
setOtherFocused(!otherFocused)
|
||||
}}
|
||||
otherFocused={otherFocused}
|
||||
bonusAp={bonusAp}
|
||||
setBonusAp={setBonusAp}
|
||||
otherBonusAp={otherBonusAp}
|
||||
setOtherBonusAp={setOtherBonusAp}
|
||||
/>
|
||||
)}
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import {
|
|||
} from "../../utils/lists"
|
||||
import Button from "../elements/Button"
|
||||
import { FaPlus, FaMinus } from "react-icons/fa"
|
||||
import HeadOnlyToggle from "./HeadOnlyToggle"
|
||||
|
||||
interface EditableBuildsProps {
|
||||
build: Partial<Build>
|
||||
|
|
@ -26,6 +27,14 @@ interface EditableBuildsProps {
|
|||
setShowOther: React.Dispatch<React.SetStateAction<boolean>>
|
||||
otherFocused: boolean
|
||||
changeFocus: () => void
|
||||
bonusAp: Partial<Record<Ability, boolean>>
|
||||
setBonusAp: React.Dispatch<
|
||||
React.SetStateAction<Partial<Record<Ability, boolean>>>
|
||||
>
|
||||
otherBonusAp: Partial<Record<Ability, boolean>>
|
||||
setOtherBonusAp: React.Dispatch<
|
||||
React.SetStateAction<Partial<Record<Ability, boolean>>>
|
||||
>
|
||||
}
|
||||
|
||||
const EditableBuilds: React.FC<EditableBuildsProps> = ({
|
||||
|
|
@ -36,6 +45,10 @@ const EditableBuilds: React.FC<EditableBuildsProps> = ({
|
|||
setShowOther,
|
||||
otherFocused,
|
||||
changeFocus,
|
||||
bonusAp,
|
||||
setBonusAp,
|
||||
otherBonusAp,
|
||||
setOtherBonusAp,
|
||||
}) => {
|
||||
const buildToEdit = otherFocused ? otherBuild : build
|
||||
const handleChange = (value: Object) => setBuild({ ...buildToEdit, ...value })
|
||||
|
|
@ -130,6 +143,10 @@ const EditableBuilds: React.FC<EditableBuildsProps> = ({
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
const headAbility = build.headgear ? build.headgear[0] : "SSU"
|
||||
const otherHeadAbility = otherBuild.headgear ? otherBuild.headgear[0] : "SSU"
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
|
|
@ -157,6 +174,18 @@ const EditableBuilds: React.FC<EditableBuildsProps> = ({
|
|||
m="1em"
|
||||
cursor={!otherFocused ? undefined : "not-allowed"}
|
||||
/>
|
||||
{["OG", "CB"].includes(headAbility) && (
|
||||
<HeadOnlyToggle
|
||||
ability={headAbility as any}
|
||||
active={bonusAp[headAbility] ?? false}
|
||||
setActive={() =>
|
||||
setBonusAp({
|
||||
...bonusAp,
|
||||
[headAbility]: !bonusAp[headAbility],
|
||||
})
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
{showOther && (
|
||||
<Flex flexDirection="column">
|
||||
|
|
@ -175,6 +204,18 @@ const EditableBuilds: React.FC<EditableBuildsProps> = ({
|
|||
m="1em"
|
||||
cursor={otherFocused ? undefined : "not-allowed"}
|
||||
/>
|
||||
{["OG", "CB"].includes(otherHeadAbility) && (
|
||||
<HeadOnlyToggle
|
||||
ability={otherHeadAbility as any}
|
||||
active={otherBonusAp[otherHeadAbility] ?? false}
|
||||
setActive={() =>
|
||||
setOtherBonusAp({
|
||||
...otherBonusAp,
|
||||
[otherHeadAbility]: !otherBonusAp[otherHeadAbility],
|
||||
})
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
)}
|
||||
</Flex>
|
||||
|
|
|
|||
61
frontend-react/src/components/analyzer/HeadOnlyToggle.tsx
Normal file
61
frontend-react/src/components/analyzer/HeadOnlyToggle.tsx
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
import React, { useContext } from "react"
|
||||
import { Box, Switch, FormLabel, Flex } from "@chakra-ui/core"
|
||||
import MyThemeContext from "../../themeContext"
|
||||
import AbilityIcon from "../builds/AbilityIcon"
|
||||
|
||||
interface HeadOnlyToggleProps {
|
||||
ability: "OG" | "CB"
|
||||
active: boolean
|
||||
setActive: () => void
|
||||
}
|
||||
|
||||
const HeadOnlyToggle: React.FC<HeadOnlyToggleProps> = ({
|
||||
ability,
|
||||
active,
|
||||
setActive,
|
||||
}) => {
|
||||
const { themeColor, themeColorWithShade } = useContext(MyThemeContext)
|
||||
return (
|
||||
<Flex
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
flexDirection="column"
|
||||
mb="1em"
|
||||
>
|
||||
<Box>
|
||||
<Switch
|
||||
id="show-all"
|
||||
color={themeColor}
|
||||
isChecked={active}
|
||||
onChange={() => setActive()}
|
||||
mr="0.5em"
|
||||
/>
|
||||
<FormLabel htmlFor="show-all">
|
||||
<AbilityIcon ability={ability} size="TINY" />
|
||||
</FormLabel>
|
||||
</Box>
|
||||
{active && ability === "OG" && (
|
||||
<Box color={themeColorWithShade} fontWeight="bold" mt="1em">
|
||||
+15AP{" "}
|
||||
{["SSU", "RSU", "RES"].map((ability) => (
|
||||
<Box as="span" mx="0.2em" key={ability}>
|
||||
<AbilityIcon ability={ability as any} size="SUBTINY" />
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
)}
|
||||
{active && ability === "CB" && (
|
||||
<Box color={themeColorWithShade} fontWeight="bold" mt="1em">
|
||||
+10AP{" "}
|
||||
{["ISM", "ISS", "REC", "RSU", "SSU", "SCU"].map((ability) => (
|
||||
<Box as="span" mx="0.2em" key={ability}>
|
||||
<AbilityIcon ability={ability as any} size="SUBTINY" />
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
)}
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
|
||||
export default HeadOnlyToggle
|
||||
|
|
@ -17,12 +17,29 @@ export interface Explanation {
|
|||
|
||||
const MAX_AP = 57
|
||||
|
||||
function buildToAP(build: Partial<Build>) {
|
||||
function buildToAP(
|
||||
build: Partial<Build>,
|
||||
bonusAp: Partial<Record<Ability, boolean>>
|
||||
) {
|
||||
const AP: Partial<Record<Ability, number>> = {}
|
||||
|
||||
if (build.headgear) {
|
||||
build.headgear.forEach((ability, index) => {
|
||||
if (ability !== "UNKNOWN") {
|
||||
if (ability === "OG" && bonusAp["OG"]) {
|
||||
for (const ability of ["SSU", "RSU", "RES"]) {
|
||||
const a = ability as Ability
|
||||
const existing = AP[a] ?? 0
|
||||
AP[a] = existing + 15
|
||||
}
|
||||
}
|
||||
if (ability === "CB" && bonusAp["CB"]) {
|
||||
for (const ability of ["ISM", "ISS", "REC", "RSU", "SSU", "SCU"]) {
|
||||
const a = ability as Ability
|
||||
const existing = AP[a] ?? 0
|
||||
AP[a] = existing + 10
|
||||
}
|
||||
}
|
||||
const existing = AP[ability] ?? 0
|
||||
const toAdd = index === 0 ? 10 : 3
|
||||
AP[ability] = existing + toAdd
|
||||
|
|
@ -56,7 +73,10 @@ function buildToAP(build: Partial<Build>) {
|
|||
return AP
|
||||
}
|
||||
|
||||
export default function useAbilityEffects(build: Partial<Build>) {
|
||||
export default function useAbilityEffects(
|
||||
build: Partial<Build>,
|
||||
bonusAp: Partial<Record<Ability, boolean>>
|
||||
) {
|
||||
const [explanations, setExplanations] = useState<Explanation[]>([])
|
||||
const weaponData: Record<Weapon | SubWeapon | SpecialWeapon, any> = weaponJson
|
||||
|
||||
|
|
@ -2116,7 +2136,7 @@ export default function useAbilityEffects(build: Partial<Build>) {
|
|||
|
||||
useEffect(() => {
|
||||
if (!build.weapon) return
|
||||
const AP = buildToAP(build)
|
||||
const AP = buildToAP(build, bonusAp)
|
||||
|
||||
let newExplanations: Explanation[] = []
|
||||
Object.keys(abilityFunctions).forEach((ability) => {
|
||||
|
|
@ -2128,7 +2148,7 @@ export default function useAbilityEffects(build: Partial<Build>) {
|
|||
|
||||
setExplanations(newExplanations)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [build])
|
||||
}, [build, bonusAp])
|
||||
|
||||
return explanations
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user