From 73efb513d21bfbb1fd33769e5f40dfa3e25b72ec Mon Sep 17 00:00:00 2001 From: gunshiz Date: Sun, 13 Sep 2026 15:22:31 +0700 Subject: [PATCH] feat : add import from gcsim and roation translater --- README.md | 20 +++ components/import-gcsim-dialog.tsx | 37 +++++ components/translator.tsx | 87 ++++++++--- components/ui/toggle.tsx | 44 ++++++ lib/translator/build.ts | 9 ++ lib/translator/final-stats.ts | 10 +- lib/translator/gcsim-text.ts | 38 +++++ lib/translator/generate.ts | 18 ++- lib/translator/import.test.ts | 235 +++++++++++++++++++++++++++++ lib/translator/import.ts | 149 ++++++++++++++++++ lib/translator/keys.ts | 40 +++++ lib/translator/rotation.test.ts | 75 +++++++++ lib/translator/rotation.ts | 137 +++++++++++++++++ lib/translator/types.ts | 15 ++ 14 files changed, 888 insertions(+), 26 deletions(-) create mode 100644 components/import-gcsim-dialog.tsx create mode 100644 components/ui/toggle.tsx create mode 100644 lib/translator/build.ts create mode 100644 lib/translator/gcsim-text.ts create mode 100644 lib/translator/import.test.ts create mode 100644 lib/translator/import.ts create mode 100644 lib/translator/rotation.test.ts create mode 100644 lib/translator/rotation.ts diff --git a/README.md b/README.md index 64e4741..1dca292 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,26 @@ bun run typecheck bun run lint ``` +## Optional rotations + +Enable **Include rotation** for a team to append actions to its character blocks: + +```text +Mavuika E > Xilonen E N2 +``` + +Use character names or keys from that team, separated by `>` or newlines. Supported shorthand: `E` (skill), `Q` (burst), `N2` (two normals), `C` (charged attack), `D` (dash), `J` (jump), `tE` / `hE` (tap / hold skill), and `W(60)` (wait 60 frames). Combine actions with `N2CD` or repeat groups with `3(N2CD)`; nested groups are supported. Compact repeats such as `2N2D` mean `2(N2D)`: perform two normals and a dash twice. A following spaced action runs once, so `2N2D Q` repeats `N2D` twice, then uses burst. **Repeat rotation** loops the actions until the simulation ends. + +Both toggles default to off. Rotation text and settings save with each team in this browser; turning rotation off preserves the text and outputs only builds. Invalid enabled rotations show an error and disable copying. The translator checks shorthand, not combat legality or energy requirements. Output contains build blocks and optional actions; add simulation settings and targets in gcsim. + +## Import from gcsim + +Click **Import from gcsim**, paste a config, review the preview, and click **Import team**. Import creates a new team with character levels, constellations, talents, weapons, artifact sets, and exact artifact stat totals. Multiple `add stats` lines are summed without converting their values into roll estimates. Imported stats and artifact piece counts can be edited directly, and numeric character, weapon, and set `+params` are preserved. + +Imported rotations remain editable gcsim script, retaining loops, conditionals, waits, and action parameters. **Include rotation** controls whether that script is copied. Use **Clear script and use shorthand** to start a new shorthand rotation instead. + +Imports support up to four characters from the current catalog, common character aliases, and Favonius aliases such as `favsword`, `favgs`, `favbow`, `favspear`, and `favcodex`. Unknown catalog entries, malformed build settings, and invalid values show errors before any team is added. Simulation options, targets, and energy settings are omitted with a notice in the import preview; full script validation happens in gcsim. + ## Production The `gcsim-secrets` Kubernetes secret only needs `DATABASE_URL`. Use a dedicated PostgreSQL role with read-only access to the Buzz Sheet `catalog` schema. diff --git a/components/import-gcsim-dialog.tsx b/components/import-gcsim-dialog.tsx new file mode 100644 index 0000000..9cd4a91 --- /dev/null +++ b/components/import-gcsim-dialog.tsx @@ -0,0 +1,37 @@ +"use client"; + +import { useMemo, useState } from "react"; +import { ImportIcon } from "lucide-react"; +import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; +import { Button } from "@/components/ui/button"; +import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; +import { Field, FieldDescription, FieldError, FieldGroup, FieldLabel } from "@/components/ui/field"; +import { Input } from "@/components/ui/input"; +import { Textarea } from "@/components/ui/textarea"; +import { importGcsimConfig } from "@/lib/translator/import"; +import type { Catalog, Team } from "@/lib/translator/types"; + +export function ImportGcsimDialog({ catalog, disabled, onImport }: { catalog: Catalog; disabled: boolean; onImport: (team: Team) => void }) { + const [open, setOpen] = useState(false); + const [input, setInput] = useState(""); + const [name, setName] = useState("Imported team"); + const preview = useMemo(() => input.trim() ? importGcsimConfig(input, catalog, name) : undefined, [input, catalog, name]); + const error = preview?.error; + return + }>Import from gcsim + + Import from gcsimPaste character settings, artifact stats, and rotation script. Import creates a new team. + + Team name setName(event.target.value)} /> + Gcsim config