mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-08 04:05:54 -05:00
Objective damage table change SPU/BRU
This commit is contained in:
@@ -13,6 +13,7 @@ type LabelProps = Pick<
|
||||
};
|
||||
required?: boolean;
|
||||
className?: string;
|
||||
labelClassName?: string;
|
||||
};
|
||||
|
||||
export function Label({
|
||||
@@ -21,10 +22,11 @@ export function Label({
|
||||
children,
|
||||
htmlFor,
|
||||
className,
|
||||
labelClassName,
|
||||
}: LabelProps) {
|
||||
return (
|
||||
<div className={clsx("label__container", className)}>
|
||||
<label htmlFor={htmlFor}>
|
||||
<label htmlFor={htmlFor} className={labelClassName}>
|
||||
{children} {required && <span className="text-error">*</span>}
|
||||
</label>
|
||||
{valueLimits ? (
|
||||
|
||||
@@ -15,3 +15,5 @@ export { useObjectDamage } from "./useObjectDamage";
|
||||
export { MAX_LDE_INTENSITY, DAMAGE_RECEIVERS, DAMAGE_TYPE } from "./constants";
|
||||
|
||||
export { lastDitchEffortIntensityToAp } from "./specialEffects";
|
||||
|
||||
export { possibleApValues } from "./utils";
|
||||
|
||||
@@ -2,21 +2,27 @@ import { useSearchParams } from "@remix-run/react";
|
||||
import { type MainWeaponId } from "../in-game-lists";
|
||||
import { calculateDamage } from "./objectDamage";
|
||||
import { buildStats } from "./stats";
|
||||
import { validatedWeaponIdFromSearchParams } from "./utils";
|
||||
import { possibleApValues, validatedWeaponIdFromSearchParams } from "./utils";
|
||||
|
||||
const ABILITY_POINTS_SP_KEY = "ap";
|
||||
|
||||
export function useObjectDamage() {
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
|
||||
const mainWeaponId = validatedWeaponIdFromSearchParams(searchParams);
|
||||
const abilityPoints = validatedAbilityPointsFromSearchParams(searchParams);
|
||||
|
||||
const handleChange = ({
|
||||
newMainWeaponId = mainWeaponId,
|
||||
abilityPoints = 0,
|
||||
}: {
|
||||
newMainWeaponId?: MainWeaponId;
|
||||
abilityPoints?: number;
|
||||
}) => {
|
||||
setSearchParams(
|
||||
{
|
||||
weapon: String(newMainWeaponId),
|
||||
[ABILITY_POINTS_SP_KEY]: String(abilityPoints),
|
||||
},
|
||||
{ replace: true, state: { scroll: false } }
|
||||
);
|
||||
@@ -31,9 +37,23 @@ export function useObjectDamage() {
|
||||
subWeaponId: analyzed.weapon.subWeaponSplId,
|
||||
handleChange,
|
||||
damagesToReceivers: calculateDamage({
|
||||
abilityPoints: new Map(),
|
||||
abilityPoints: new Map([
|
||||
["BRU", { ap: abilityPoints, apBeforeTacticooler: abilityPoints }],
|
||||
["SPU", { ap: abilityPoints, apBeforeTacticooler: abilityPoints }],
|
||||
]),
|
||||
analyzed,
|
||||
mainWeaponId,
|
||||
}),
|
||||
abilityPoints: String(abilityPoints),
|
||||
};
|
||||
}
|
||||
|
||||
export function validatedAbilityPointsFromSearchParams(
|
||||
searchParams: URLSearchParams
|
||||
) {
|
||||
const abilityPoints = Number(searchParams.get(ABILITY_POINTS_SP_KEY));
|
||||
|
||||
return (
|
||||
possibleApValues().find((possibleAp) => possibleAp === abilityPoints) ?? 0
|
||||
);
|
||||
}
|
||||
|
||||
@@ -167,3 +167,15 @@ export function validatedWeaponIdFromSearchParams(
|
||||
}
|
||||
|
||||
export const hpDivided = (hp: number) => hp / 10;
|
||||
|
||||
export function possibleApValues() {
|
||||
const uniqueValues = new Set<number>();
|
||||
|
||||
for (let i = 0; i < 4; i++) {
|
||||
for (let j = 0; j < 10; j++) {
|
||||
uniqueValues.add(i * 10 + j * 3);
|
||||
}
|
||||
}
|
||||
|
||||
return Array.from(uniqueValues).sort((a, b) => a - b);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { WeaponCombobox } from "~/components/Combobox";
|
||||
import { Image } from "~/components/Image";
|
||||
import { Main } from "~/components/Main";
|
||||
import { useObjectDamage } from "~/modules/analyzer";
|
||||
import { possibleApValues, useObjectDamage } from "~/modules/analyzer";
|
||||
import {
|
||||
type MainWeaponId,
|
||||
BIG_BUBBLER_ID,
|
||||
@@ -26,6 +26,8 @@ import type { DamageReceiver } from "~/modules/analyzer/types";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import clsx from "clsx";
|
||||
import { Label } from "~/components/Label";
|
||||
import { Ability } from "~/components/Ability";
|
||||
|
||||
export const links: LinksFunction = () => {
|
||||
return [{ rel: "stylesheet", href: styles }];
|
||||
@@ -36,8 +38,14 @@ export const handle: SendouRouteHandle = {
|
||||
};
|
||||
|
||||
export default function ObjectDamagePage() {
|
||||
const { mainWeaponId, subWeaponId, handleChange, damagesToReceivers } =
|
||||
useObjectDamage();
|
||||
const { t } = useTranslation(["analyzer"]);
|
||||
const {
|
||||
mainWeaponId,
|
||||
subWeaponId,
|
||||
handleChange,
|
||||
damagesToReceivers,
|
||||
abilityPoints,
|
||||
} = useObjectDamage();
|
||||
|
||||
if (process.env.NODE_ENV !== "development") {
|
||||
return <Main>WIP :)</Main>;
|
||||
@@ -45,18 +53,50 @@ export default function ObjectDamagePage() {
|
||||
|
||||
return (
|
||||
<Main className="stack lg">
|
||||
<WeaponCombobox
|
||||
inputName="weapon"
|
||||
initialWeaponId={mainWeaponId}
|
||||
onChange={(opt) =>
|
||||
opt &&
|
||||
handleChange({
|
||||
newMainWeaponId: Number(opt.value) as MainWeaponId,
|
||||
})
|
||||
}
|
||||
className="w-full-important"
|
||||
clearsInputOnFocus
|
||||
/>
|
||||
<div className="object-damage__controls">
|
||||
<div>
|
||||
<Label htmlFor="weapon">Weapon</Label>
|
||||
<WeaponCombobox
|
||||
id="weapon"
|
||||
inputName="weapon"
|
||||
initialWeaponId={mainWeaponId}
|
||||
onChange={(opt) =>
|
||||
opt &&
|
||||
handleChange({
|
||||
newMainWeaponId: Number(opt.value) as MainWeaponId,
|
||||
})
|
||||
}
|
||||
className="w-full-important"
|
||||
clearsInputOnFocus
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="damage">Damage type</Label>
|
||||
<select id="damage">
|
||||
<option value="0">0</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="ap" labelClassName="object-damage__ap-label">
|
||||
Amount of <Ability ability="BRU" size="TINY" />{" "}
|
||||
<Ability ability="SPU" size="TINY" />
|
||||
</Label>
|
||||
<select
|
||||
id="ap"
|
||||
value={abilityPoints}
|
||||
onChange={(e) =>
|
||||
handleChange({ abilityPoints: Number(e.target.value) })
|
||||
}
|
||||
>
|
||||
{possibleApValues().map((ap) => (
|
||||
<option key={ap} value={ap}>
|
||||
{ap}
|
||||
{t("analyzer:abilityPoints.short")}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<DamageReceiversGrid
|
||||
subWeaponId={subWeaponId}
|
||||
damagesToReceivers={damagesToReceivers}
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
.object-damage__controls {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.object-damage__ap-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--s-1-5);
|
||||
}
|
||||
|
||||
.object-damage__grid {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
|
||||
Reference in New Issue
Block a user