mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-13 06:36:49 -05:00
Object damage hitpoints initial
This commit is contained in:
@@ -5,6 +5,7 @@ export type {
|
||||
Stat,
|
||||
AnalyzedBuild,
|
||||
SpecialEffectType,
|
||||
HitPoints,
|
||||
} from "./types";
|
||||
|
||||
export { useAnalyzeBuild } from "./useAnalyzeBuild";
|
||||
|
||||
53
app/modules/analyzer/objectHitPoints.ts
Normal file
53
app/modules/analyzer/objectHitPoints.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import invariant from "tiny-invariant";
|
||||
import { BIG_BUBBLER_ID, CRAB_TANK_ID, SPLASH_WALL_ID } from "../in-game-lists";
|
||||
import { specialDeviceHp, specialFieldHp, subStats } from "./stats";
|
||||
import type {
|
||||
AbilityPoints,
|
||||
HitPoints,
|
||||
SpecialWeaponParams,
|
||||
SubWeaponParams,
|
||||
} from "./types";
|
||||
import weaponParams from "./weapon-params.json";
|
||||
|
||||
const PLACEHOLDER_HP = 1000;
|
||||
|
||||
export const objectHitPoints = (abilityPoints: AbilityPoints): HitPoints => {
|
||||
const Wsb_Shield = subStats({
|
||||
abilityPoints,
|
||||
subWeaponParams: weaponParams.subWeapons[SPLASH_WALL_ID] as SubWeaponParams,
|
||||
}).subHp?.value;
|
||||
const GreatBarrier_Barrier = specialFieldHp({
|
||||
abilityPoints,
|
||||
specialWeaponParams: weaponParams.specialWeapons[
|
||||
BIG_BUBBLER_ID
|
||||
] as SpecialWeaponParams,
|
||||
})?.value;
|
||||
const GreatBarrier_WeakPoint = specialDeviceHp({
|
||||
abilityPoints,
|
||||
specialWeaponParams: weaponParams.specialWeapons[
|
||||
BIG_BUBBLER_ID
|
||||
] as SpecialWeaponParams,
|
||||
})?.value;
|
||||
|
||||
invariant(Wsb_Shield);
|
||||
invariant(GreatBarrier_Barrier);
|
||||
invariant(GreatBarrier_WeakPoint);
|
||||
|
||||
return {
|
||||
BulletUmbrellaCanopyNormal: PLACEHOLDER_HP, // ?? needs defaults
|
||||
BulletUmbrellaCanopyWide: weaponParams.mainWeapons[6010].CanopyHP,
|
||||
BulletUmbrellaCanopyCompact: weaponParams.mainWeapons[6020].CanopyHP,
|
||||
Wsb_Shield,
|
||||
Bomb_TorpedoBullet: PLACEHOLDER_HP, // ??
|
||||
Chariot: weaponParams.specialWeapons[CRAB_TANK_ID].ArmorHP,
|
||||
Gachihoko_Barrier: PLACEHOLDER_HP, // ??
|
||||
GreatBarrier_Barrier,
|
||||
GreatBarrier_WeakPoint,
|
||||
InkRail: PLACEHOLDER_HP, // ??
|
||||
NiceBall_Armor: PLACEHOLDER_HP, // ??
|
||||
ShockSonar: PLACEHOLDER_HP, // ??
|
||||
Sponge_Versus: PLACEHOLDER_HP, // ??
|
||||
Wsb_Flag: PLACEHOLDER_HP, // ??
|
||||
Wsb_Sprinkler: PLACEHOLDER_HP, // ??
|
||||
};
|
||||
};
|
||||
@@ -765,7 +765,9 @@ const SUB_WEAPON_STATS = [
|
||||
},
|
||||
{ analyzedBuildKey: "subHp", abilityValuesKey: "MaxHP", type: "HP" },
|
||||
] as const;
|
||||
function subStats(args: StatFunctionInput) {
|
||||
export function subStats(
|
||||
args: Pick<StatFunctionInput, "subWeaponParams" | "abilityPoints">
|
||||
) {
|
||||
const result: Partial<AnalyzedBuild["stats"]> = {};
|
||||
const SUB_STATS_KEY = "BRU";
|
||||
|
||||
@@ -1126,8 +1128,8 @@ function specialPaintRadius(
|
||||
};
|
||||
}
|
||||
|
||||
function specialFieldHp(
|
||||
args: StatFunctionInput
|
||||
export function specialFieldHp(
|
||||
args: Pick<StatFunctionInput, "specialWeaponParams" | "abilityPoints">
|
||||
): AnalyzedBuild["stats"]["specialFieldHp"] {
|
||||
if (!hasEffect({ key: "MaxFieldHP", weapon: args.specialWeaponParams })) {
|
||||
return;
|
||||
@@ -1150,8 +1152,8 @@ function specialFieldHp(
|
||||
};
|
||||
}
|
||||
|
||||
function specialDeviceHp(
|
||||
args: StatFunctionInput
|
||||
export function specialDeviceHp(
|
||||
args: Pick<StatFunctionInput, "specialWeaponParams" | "abilityPoints">
|
||||
): AnalyzedBuild["stats"]["specialDeviceHp"] {
|
||||
if (!hasEffect({ key: "MaxHP", weapon: args.specialWeaponParams })) {
|
||||
return;
|
||||
|
||||
@@ -164,6 +164,8 @@ export type DamageType = typeof DAMAGE_TYPE[number];
|
||||
|
||||
export type DamageReceiver = typeof DAMAGE_RECEIVERS[number];
|
||||
|
||||
export type HitPoints = Record<DamageReceiver, number>;
|
||||
|
||||
export interface Damage {
|
||||
value: number;
|
||||
type: DamageType;
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useSearchParams } from "@remix-run/react";
|
||||
import { type MainWeaponId } from "../in-game-lists";
|
||||
import { damageTypeToWeaponType } from "./constants";
|
||||
import { damageTypeToMultipliers, fallbackRates } from "./damageMultipliers";
|
||||
import { objectHitPoints } from "./objectHitPoints";
|
||||
import { buildStats } from "./stats";
|
||||
import { validatedWeaponIdFromSearchParams } from "./utils";
|
||||
|
||||
@@ -53,5 +54,7 @@ export function useObjectDamage() {
|
||||
mainWeaponId,
|
||||
handleChange,
|
||||
multipliers,
|
||||
damages: analyzed.stats.damages,
|
||||
hitPoints: objectHitPoints(new Map()),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1246,6 +1246,7 @@
|
||||
}
|
||||
},
|
||||
"12": {
|
||||
"ArmorHP": 5000,
|
||||
"overwrites": {
|
||||
"SpecialDurationFrame": {
|
||||
"High": 660,
|
||||
|
||||
@@ -1,22 +1,54 @@
|
||||
import { WeaponCombobox } from "~/components/Combobox";
|
||||
import { Image } from "~/components/Image";
|
||||
import { Main } from "~/components/Main";
|
||||
import { useObjectDamage } from "~/modules/analyzer";
|
||||
import type { MainWeaponId } from "~/modules/in-game-lists";
|
||||
import { type SendouRouteHandle } from "~/utils/remix";
|
||||
import {
|
||||
DAMAGE_RECEIVERS,
|
||||
useObjectDamage,
|
||||
type HitPoints,
|
||||
} from "~/modules/analyzer";
|
||||
import {
|
||||
type MainWeaponId,
|
||||
BIG_BUBBLER_ID,
|
||||
BOOYAH_BOMB_ID,
|
||||
CRAB_TANK_ID,
|
||||
SPLASH_WALL_ID,
|
||||
SQUID_BEAKON_ID,
|
||||
TORPEDO_ID,
|
||||
WAVE_BREAKER_ID,
|
||||
SPRINKLER_ID,
|
||||
} from "~/modules/in-game-lists";
|
||||
import {
|
||||
mainWeaponImageUrl,
|
||||
modeImageUrl,
|
||||
specialWeaponImageUrl,
|
||||
subWeaponImageUrl,
|
||||
} from "~/utils/urls";
|
||||
import styles from "~/styles/object-damage.css";
|
||||
import type { LinksFunction } from "@remix-run/node";
|
||||
import type { SendouRouteHandle } from "~/utils/remix";
|
||||
import type { DamageReceiver } from "~/modules/analyzer/types";
|
||||
|
||||
export const links: LinksFunction = () => {
|
||||
return [{ rel: "stylesheet", href: styles }];
|
||||
};
|
||||
|
||||
export const handle: SendouRouteHandle = {
|
||||
i18n: ["weapons"],
|
||||
};
|
||||
|
||||
export default function ObjectDamagePage() {
|
||||
const { mainWeaponId, handleChange, multipliers } = useObjectDamage();
|
||||
const { mainWeaponId, handleChange, multipliers, damages, hitPoints } =
|
||||
useObjectDamage();
|
||||
|
||||
if (process.env.NODE_ENV !== "development") {
|
||||
return <Main>WIP :)</Main>;
|
||||
}
|
||||
|
||||
console.log(JSON.stringify(multipliers, null, 2));
|
||||
console.log(JSON.stringify(damages, null, 2));
|
||||
|
||||
return (
|
||||
<Main>
|
||||
<Main className="stack lg">
|
||||
<WeaponCombobox
|
||||
inputName="weapon"
|
||||
initialWeaponId={mainWeaponId}
|
||||
@@ -29,7 +61,48 @@ export default function ObjectDamagePage() {
|
||||
className="w-full-important"
|
||||
clearsInputOnFocus
|
||||
/>
|
||||
<pre>{JSON.stringify(multipliers, null, 2)}</pre>
|
||||
<div
|
||||
className="object-damage__grid"
|
||||
style={{ "--columns-count": "2" } as any}
|
||||
>
|
||||
<DamageReceiversHeader hitPoints={hitPoints} />
|
||||
</div>
|
||||
</Main>
|
||||
);
|
||||
}
|
||||
|
||||
const damageReceiverImages: Record<DamageReceiver, string> = {
|
||||
Bomb_TorpedoBullet: subWeaponImageUrl(TORPEDO_ID),
|
||||
Chariot: specialWeaponImageUrl(CRAB_TANK_ID),
|
||||
Gachihoko_Barrier: modeImageUrl("RM"),
|
||||
GreatBarrier_Barrier: specialWeaponImageUrl(BIG_BUBBLER_ID),
|
||||
GreatBarrier_WeakPoint: specialWeaponImageUrl(BIG_BUBBLER_ID),
|
||||
InkRail: modeImageUrl("CB"),
|
||||
NiceBall_Armor: specialWeaponImageUrl(BOOYAH_BOMB_ID),
|
||||
ShockSonar: specialWeaponImageUrl(WAVE_BREAKER_ID),
|
||||
Sponge_Versus: modeImageUrl("CB"),
|
||||
Wsb_Flag: subWeaponImageUrl(SQUID_BEAKON_ID),
|
||||
Wsb_Shield: subWeaponImageUrl(SPLASH_WALL_ID),
|
||||
Wsb_Sprinkler: subWeaponImageUrl(SPRINKLER_ID),
|
||||
BulletUmbrellaCanopyNormal: mainWeaponImageUrl(6000),
|
||||
BulletUmbrellaCanopyWide: mainWeaponImageUrl(6010),
|
||||
BulletUmbrellaCanopyCompact: mainWeaponImageUrl(6020),
|
||||
};
|
||||
function DamageReceiversHeader({ hitPoints }: { hitPoints: HitPoints }) {
|
||||
return (
|
||||
<>
|
||||
{DAMAGE_RECEIVERS.map((receiver, i) => (
|
||||
<>
|
||||
<Image
|
||||
key={i}
|
||||
alt=""
|
||||
path={damageReceiverImages[receiver]}
|
||||
width={40}
|
||||
height={40}
|
||||
/>
|
||||
<div>{hitPoints[receiver]}</div>
|
||||
</>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
6
app/styles/object-damage.css
Normal file
6
app/styles/object-damage.css
Normal file
@@ -0,0 +1,6 @@
|
||||
.object-damage__grid {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
gap: var(--s-3);
|
||||
grid-template-columns: repeat(var(--columns-count), 1fr);
|
||||
}
|
||||
@@ -314,7 +314,10 @@ function parametersToSpecialWeaponResult(params: any) {
|
||||
resultUnwrapped["SplashAroundPaintRadius"] = undefined;
|
||||
}
|
||||
|
||||
return { overwrites: resultUnwrapped };
|
||||
return {
|
||||
ArmorHP: params["WeaponSpChariotParam"]?.["ArmorHP"],
|
||||
overwrites: resultUnwrapped,
|
||||
};
|
||||
}
|
||||
|
||||
function unwrapSubSpecialSpecUpList(result: any) {
|
||||
|
||||
Reference in New Issue
Block a user