Skip to content

Commit e6cceaf

Browse files
committed
Store gacha targets into local storage
1 parent 31bf04f commit e6cceaf

File tree

1 file changed

+96
-43
lines changed

1 file changed

+96
-43
lines changed

pages/tools/gachacalc.tsx

Lines changed: 96 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ type ReducedSim = {
181181

182182
type GachaTarget = {
183183
id: string
184+
enabled: boolean
184185
banner: Banner
185186
current: number
186187
target: number
@@ -194,6 +195,7 @@ let gtCounter = 0
194195
function createDefaultTarget(banner: Banner): GachaTarget {
195196
return {
196197
id: gtCounter++ + Math.random().toString(36).substring(2, 15),
198+
enabled: true,
197199
banner,
198200
current: banner.minConst,
199201
target: banner.maxConst,
@@ -208,11 +210,33 @@ export default function GachaCalc({ location }: { location: string }) {
208210
const [gachaTargets, setGachaTargets] = useState<GachaTarget[]>([createDefaultTarget(gachas.char)])
209211
const [pulls, setPulls] = useState(gachaTargets[0].banner.maxPity)
210212

211-
const calculated = useMemo(() => calcSimsRegular(pulls, gachaTargets), [gachaTargets, pulls])
213+
useEffect(() => {
214+
const items = JSON.parse(localStorage.getItem("gachaTargets") ?? "[]")
215+
if (items.length > 0) {
216+
// Force low amount as calculations could have exploded
217+
if (items.filter((x: any) => x.enabled).length > 5) setPulls(1)
218+
else if (items.filter((x: any) => x.enabled).length > 2) setPulls(10)
219+
220+
setGachaTargets(items.map((gt: any) => ({
221+
...gt,
222+
banner: gachas[gt.banner] ?? Object.values(gachas)[0],
223+
})))
224+
}
225+
}, [])
226+
227+
useEffect(() => {
228+
localStorage.setItem("gachaTargets", JSON.stringify(gachaTargets.map(gt => ({
229+
...gt,
230+
banner: Object.entries(gachas).find(([_, v]) => v.bannerName == gt.banner.bannerName)?.[0],
231+
}))))
232+
}, [gachaTargets])
233+
234+
const enabledTargets = useMemo(() => gachaTargets.filter(gt => gt.enabled), [gachaTargets])
235+
const calculated = useMemo(() => calcSimsRegular(pulls, enabledTargets), [enabledTargets, pulls])
212236

213237
const consts = []
214-
for (let index = 0; index < gachaTargets.length; index++) {
215-
const gachaTarget = gachaTargets[index]
238+
for (let index = 0; index < enabledTargets.length; index++) {
239+
const gachaTarget = enabledTargets[index]
216240
for (let i = gachaTarget.current + 1; i <= gachaTarget.target; i++)
217241
consts.push({
218242
gachaTargetIndex: index,
@@ -221,8 +245,8 @@ export default function GachaCalc({ location }: { location: string }) {
221245
})
222246
}
223247

224-
const constName = gachaTargets.map(gt => gt.banner.constName).filter((x, i, a) => a.indexOf(x) == i).join("/")
225-
const constFormat = gachaTargets.map(gt => gt.banner.constFormat).filter((x, i, a) => a.indexOf(x) == i).join("/")
248+
const constName = enabledTargets.map(gt => gt.banner.constName).filter((x, i, a) => a.indexOf(x) == i).join("/")
249+
const constFormat = enabledTargets.map(gt => gt.banner.constFormat).filter((x, i, a) => a.indexOf(x) == i).join("/")
226250

227251
const desc = "Gacha rate calculator for Genshin Impact."
228252
return (
@@ -244,15 +268,42 @@ export default function GachaCalc({ location }: { location: string }) {
244268
<h1 className="text-5xl font-bold pb-2">Gacha rate calculator</h1>
245269

246270
<NumberInput label="Pulls" set={setPulls} value={pulls} min={0} max={1260 * gachaTargets.length}/>
247-
{gachaTargets.map((gachaTarget, index) => <div key={gachaTarget.id} className="bg-blend-multiply bg-slate-600 rounded-xl p-1 my-2">
248-
{gachaTargets.length > 1 &&
249-
<button className="bg-red-700 text-slate-50 cursor-pointer text-center rounded-lg px-2 py-1 my-2 float-right"
250-
onClick={() =>
251-
setGachaTargets(gachaTargets.filter((_, i) => i != index))
252-
}>
253-
Remove gacha target
254-
</button>
255-
}
271+
{gachaTargets.map((gachaTarget, index) => <div key={gachaTarget.id} className={`bg-slate-600 ${gachaTarget.enabled ? "" : "bg-opacity-25 bg-red-800"} rounded-xl p-1 my-2 flex flex-row gap-2`}>
272+
<div className="flex flex-col items-center justify-center gap-2">
273+
<div>
274+
<button className="bg-slate-900 text-slate-50 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed text-center rounded-lg px-2 py-1"
275+
disabled={!(gachaTargets.length > 1 && index > 0)}
276+
onClick={() => {
277+
// Move index up
278+
const newGachaTargets = [...gachaTargets]
279+
newGachaTargets[index] = gachaTargets[index - 1]
280+
newGachaTargets[index - 1] = gachaTargets[index]
281+
setGachaTargets(newGachaTargets)
282+
}}>
283+
&uarr;
284+
</button>
285+
</div>
286+
<div>
287+
<button className="bg-red-700 text-slate-50 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed text-center rounded-lg px-2 py-1"
288+
disabled={!(gachaTargets.length > 1)}
289+
onClick={() => setGachaTargets(gachaTargets.filter((_, i) => i != index))}>
290+
&times;
291+
</button>
292+
</div>
293+
<div>
294+
<button className="bg-slate-900 text-slate-50 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed text-center rounded-lg px-2 py-1"
295+
disabled={!(gachaTargets.length > 1 && index < gachaTargets.length - 1)}
296+
onClick={() => {
297+
// Move index down
298+
const newGachaTargets = [...gachaTargets]
299+
newGachaTargets[index] = gachaTargets[index + 1]
300+
newGachaTargets[index + 1] = gachaTargets[index]
301+
setGachaTargets(newGachaTargets)
302+
}}>
303+
&darr;
304+
</button>
305+
</div>
306+
</div>
256307
<GachaTargetInput value={gachaTarget} set={newGachaTarget => setGachaTargets(gachaTargets.map((gt, i) => i == index ? newGachaTarget : gt))} />
257308
</div>)}
258309

@@ -341,11 +392,11 @@ export default function GachaCalc({ location }: { location: string }) {
341392
datasets: consts
342393
.map((gtc, x, arr) => ({
343394
label: getName(gtc),
344-
backgroundColor: getColor(gtc, gachaTargets, 1),
345-
borderColor: getColor(gtc, gachaTargets, 1),
395+
backgroundColor: getColor(gtc, enabledTargets, 1),
396+
borderColor: getColor(gtc, enabledTargets, 1),
346397
fill: {
347-
above: getColor(gtc, gachaTargets, 0.15),
348-
below: getColor(gtc, gachaTargets, 0.1),
398+
above: getColor(gtc, enabledTargets, 0.15),
399+
below: getColor(gtc, enabledTargets, 0.1),
349400
target: arr.indexOf(gtc) == arr.length - 1 ? "start" : x + 1,
350401
},
351402
data: calculated.map(c => c
@@ -477,6 +528,7 @@ function GachaTargetInput({
477528
value: GachaTarget;
478529
set: (newValue: GachaTarget) => unknown;
479530
}) {
531+
const [enabled, setEnabled] = useState(value.enabled)
480532
const [current, setCurrent] = useState(value.current)
481533
const [target, setTarget] = useState(value.target)
482534
const [pity, setPity] = useState(value.pity)
@@ -498,6 +550,7 @@ function GachaTargetInput({
498550

499551
useEffect(() => {
500552
if (banner.bannerName != value.banner.bannerName) {}
553+
else if (enabled != value.enabled) {}
501554
else if (current != value.current) {}
502555
else if (target != value.target) {}
503556
else if (pity != value.pity) {}
@@ -508,6 +561,7 @@ function GachaTargetInput({
508561

509562
set({
510563
id: value.id,
564+
enabled,
511565
banner,
512566
current,
513567
target,
@@ -516,31 +570,30 @@ function GachaTargetInput({
516570
guaranteedPity,
517571
lostPity,
518572
})
519-
}, [set, value, banner, current, target, pity, guaranteed, guaranteedPity, lostPity])
520-
return (
521-
<>
522-
<SelectInput label="Banner type" set={(g) => {
523-
if (current == banner.minConst)
524-
setCurrent((Object.values(gachas).find((x) => x.bannerName == g) ?? Object.values(gachas)[0]).minConst)
525-
if (target == banner.maxConst)
526-
setTarget((Object.values(gachas).find((x) => x.bannerName == g) ?? Object.values(gachas)[0]).maxConst)
527-
setGacha(g)
528-
}}
529-
value={gachaName}
530-
options={Object.values(gachas).map((g) => g.bannerName)}
531-
/>
532-
<NumberInput label={`Current ${banner.constName.toLowerCase()}`} set={setCurrent} value={current} min={banner.minConst} max={target - 1}/>
533-
<NumberInput label={`Target ${banner.constName.toLowerCase()}`} set={setTarget} value={target} min={current + 1} max={banner.maxConst}/>
534-
<NumberInput label="Current pity" set={setPity} value={pity} min={0} max={banner.maxPity - 1}/>
535-
<CheckboxInput label="Next is guaranteed" set={setGuaranteed} value={guaranteed}/>
536-
{banner.guaranteedPity && (
537-
<NumberInput label="Epitomized Path" set={setGuaranteedPity} value={guaranteedPity} min={0} max={banner.guaranteedPity - 1}/>
538-
)}
539-
{Array.isArray(banner.banner) && (
540-
<NumberInput label="Lost pity (Capturing Radiance)" set={setLostPity} value={lostPity} min={0} max={banner.banner.length - 1}/>
541-
)}
542-
</>
543-
)
573+
}, [set, value, enabled, banner, current, target, pity, guaranteed, guaranteedPity, lostPity])
574+
return <div>
575+
<CheckboxInput label="Enabled" set={setEnabled} value={enabled} />
576+
<SelectInput label="Banner type" set={(g) => {
577+
if (current == banner.minConst)
578+
setCurrent((Object.values(gachas).find((x) => x.bannerName == g) ?? Object.values(gachas)[0]).minConst)
579+
if (target == banner.maxConst)
580+
setTarget((Object.values(gachas).find((x) => x.bannerName == g) ?? Object.values(gachas)[0]).maxConst)
581+
setGacha(g)
582+
}}
583+
value={gachaName}
584+
options={Object.values(gachas).map((g) => g.bannerName)}
585+
/>
586+
<NumberInput label={`Current ${banner.constName.toLowerCase()}`} set={setCurrent} value={current} min={banner.minConst} max={target - 1}/>
587+
<NumberInput label={`Target ${banner.constName.toLowerCase()}`} set={setTarget} value={target} min={current + 1} max={banner.maxConst}/>
588+
<NumberInput label="Current pity" set={setPity} value={pity} min={0} max={banner.maxPity - 1}/>
589+
<CheckboxInput label="Next is guaranteed" set={setGuaranteed} value={guaranteed}/>
590+
{banner.guaranteedPity && (
591+
<NumberInput label="Epitomized Path" set={setGuaranteedPity} value={guaranteedPity} min={0} max={banner.guaranteedPity - 1}/>
592+
)}
593+
{Array.isArray(banner.banner) && (
594+
<NumberInput label="Lost pity (Capturing Radiance)" set={setLostPity} value={lostPity} min={0} max={banner.banner.length - 1}/>
595+
)}
596+
</div>
544597
}
545598

546599
function NumberInput({ value, set, label, min, max }: {

0 commit comments

Comments
 (0)