Skip to content

Universal 175-slot animation support in UOFiddler (anim_custom.mul/idx) — edit, preview, import/export, and convert - #1

Open
Tald0r wants to merge 1 commit into
masterfrom
universal-anim_custom
Open

Universal 175-slot animation support in UOFiddler (anim_custom.mul/idx) — edit, preview, import/export, and convert#1
Tald0r wants to merge 1 commit into
masterfrom
universal-anim_custom

Conversation

@Tald0r

@Tald0r Tald0r commented Aug 16, 2025

Copy link
Copy Markdown
Owner

✨ Universal 175-slot animation support in UOFiddler (anim_custom.mul/idx) — edit, preview, import/export, and convert

Summary

This PR adds first-class support in UOFiddler for a single, universal animation file pair, anim_custom.mul + anim_custom.idx (file type 6), that uses a fixed 175-slot-per-body layout (35 actions × 5 directions). Unlike legacy anim files, anim_custom can mix different animation types per body (High/Low/People). The UI and editor logic were updated to recognize, display, and persist the correct action sets dynamically based on the type stored in the .idx “extra” field.

The classic anim loaders (anim.mul, anim2.mul, …) remain fully supported. anim_custom is simply an additional option that simplifies authoring, import/export workflows, and tool-chain interoperability with modern packs.

Motivation

  • Modern workflows benefit from a single, flat 175-slot layout per body.
  • Legacy anim files split bodies across files and slot sizes (110/65/175) and infer type from body ranges.
  • UOFiddler can now:
    • Open/edit a universal file with mixed types per body.
    • Persist body type in the .idx extra field.
    • Reflect the correct action list in the UI per stored type.
    • Import/export VD with correct type semantics.
    • Convert empty bodies to a desired type directly from the UI.

Key changes

Core format and addressing

  • Introduced “file type 6” for anim_custom.mul/idx.
  • Fixed 175-slot addressing per body:
    • Slot = body * 175 + action * 5 + mirroredDir
    • Direction mirroring: mirroredDir = dir <= 4 ? dir : dir - ((dir - 4) * 2)
  • The .idx extra field stores the body type: 0 = High (Monsters), 1 = Low (Animals), 2 = People/Equipment.
    • This value determines the action set length (22/13/35) and which action names to display in the UI.
    • Empty/new slots default to People (2), but can be converted.

Animations runtime updates

  • New optional file index for anim_custom alongside the existing anim1..5.
  • Body/action/direction addressing for file type 6 uses the universal 175-slot formula.
  • Animation count for file type 6 is derived from .idx length divided by 175 * 12.
  • For file type 6, action length is resolved from the .idx extra field (not body ranges).

Editing pipeline (AnimationEdit)

  • Added cache and file index for anim_custom.
  • Read/write of the .idx “extra” field persists BodyType per entry in file type 6.
  • VD import:
    • Reads the type from the source VD header.
    • For file type 6, the imported type is accepted and stored; action table is sized accordingly (13/22/35).
  • VD export:
    • For file type 6, the exported header type matches the cached BodyType, ensuring fidelity with downstream tools.
  • “SetBodyType” API:
    • Allows programmatic conversion of an empty body block to High/Low/People by materializing minimal entries and persisting the new type in .idx on Save.

UI/UX (AnimationEditForm)

  • File dropdown now includes “anim_custom”.
  • TreeView population:
    • For file type 6, resolves BodyType from .idx extra (or cached AnimIdx) and builds the correct action list and labels (H/L/P) per body.
    • For legacy files, original inference logic unchanged.
  • New “Convert” context menu on the body node:
    • L : Low (Animals), H : High (Monsters), P : People (Equipment).
    • Converts empty slots to a chosen type by persisting the selection in .idx and reloading the node.
  • “Import VD”:
    • For file type 6: accepts the VD’s stored type, loads frames accordingly, updates body node and action list live.
    • For legacy files: preserves existing behavior and type validation.
  • Palette panel, frames list, preview/edit pane, and all add/replace/remove operations work with anim_custom identically to legacy files.

Behaviour

  • If anim_custom.mul/idx is present:
    • Selecting “anim_custom” in the file dropdown enables editing and preview of universal 175-slot bodies.
    • The UI displays the correct number of actions and labels for each body based on its stored type.
    • Conversions (H/L/P) on empty bodies persist to .idx and immediately refresh the TreeView/action labels.
    • VD import honors the source file’s type for file type 6, enabling straightforward round‑trips with other tools.
  • If anim_custom.mul/idx is not present:
    • Nothing changes for legacy anim files 1..5; original behavior is intact.

Files changed (high-level)

  • Animations
    • Added optional support for file type 6 with universal 175-slot addressing and count/length calculations driven by the .idx extra field.
  • AnimationEdit
    • Added cache/index for file type 6, BodyType persistence via .idx extra.
    • VD import/export updated to respect stored type for 6.
    • Save() writes BodyType to .idx extra for 6; legacy files remain unchanged.
  • AnimationEditForm (+ Designer)
    • UI includes “anim_custom” in the file selector.
    • TreeView population reads BodyType for 6 and renders the right action names set (13/22/35).
    • Added “Convert..” context menu for body-type selection on empty slots.
    • VD import flow updated as described above.

175-slot addressing reference (for contributors)

  • Constants:
    • Actions per body: 35
    • Directions per action: 5
    • Slots per body: 175
  • Direction mirroring:
    • mirroredDir = dir <= 4 ? dir : dir - ((dir - 4) * 2)
  • Slot formula:
    • slot = body * 175 + action * 5 + mirroredDir
  • Block starts:
    • Body block: body * 175
    • Action block in body: body * 175 + action * 5

Migration / Usage

  1. Add anim_custom.mul and anim_custom.idx to the data folder.
  2. Choose “anim_custom” in UOFiddler’s file selector to work with the universal layout.
  3. For each body:
    • If frames already exist, the UI reads the stored type from .idx and shows the correct action names.
    • If empty, the “Convert..” menu can set a desired type (H/L/P), which is persisted on Save.
  4. Import/export VD as usual:
    • File type 6 accepts the VD’s stored type on import and exports the cached BodyType on write.

Notes for reviewers

  • Legacy anim1..5 logic is preserved; changes are additive for file type 6.
  • The .idx extra field is the single source of truth for BodyType in anim_custom.
  • Internal memory caches materialize minimal entries for empty bodies upon conversion to ensure type persistence on Save.
  • All palette/center/frames editing logic is unchanged and compatible with the universal layout.

TL;DR

UOFiddler now supports a modern, single-file universal animation pack (anim_custom.mul/idx, file type 6) with a fixed 175-slot layout per body, mixed body types, and seamless UI/VD import/export integration — without disrupting legacy anim workflows.

This commit introduces a new, flexible animation file format, `anim_custom.idx` and `anim_custom.mul`, identified as file type 6. This allows for mixing different animation types (High Detail Monster, Low Detail Animal, People/Equipment) within a single file, overcoming the rigid structure of the original anim files.

Key changes include:
- A universal 175-slot block structure is used for each body in `anim_custom`.
- The `extra` field in the `.idx` file is repurposed to store the body type (0=H, 1=L, 2=P), which determines the animation set and length.
- The AnimationEdit UI now dynamically loads and displays the correct actions based on the stored body type when viewing `anim_custom`.
- A "Convert" context menu option has been added, allowing users to change the type of empty body slots.
- VD file import logic is updated to respect the animation type from the source file when importing into an `anim_custom` slot.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant