Skip to content

Make crafted items follow their template's required class - #53

Merged
XxFran10xX merged 2 commits into
mainfrom
fix/refresh-required-class
Nov 14, 2026
Merged

XxFran10xX merged 2 commits into
mainfrom
fix/refresh-required-class

Conversation

@XxFran10xX

@XxFran10xX XxFran10xX commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

Status record

  • Reviewed: Fable 5.2 APPROVE at 834cf16 (4 minor; class-sync failure guard and case-insensitive match fixed in 0688629, no re-review: no saved-data change)
  • Second opinion: CodeRabbit APPROVE at 834cf16 (no findings)
  • Dev-tested: passed at 0688629 on TFMCDev01 (DEV-20261114-0010, 2026-11-14 00:24-00:26 UTC, bot ACTierBot). CUSTOM_WARHAMMER without Warden: crafted warhammer (Masterwork, Sapphire socketed, durability 463/500) has the 4-class list and a Warden is refused ("You don't have the right class!", 0 damage); a baseline relog changes nothing. Warden restored + mi reload + relog: exactly one [AC][ClassSync] WARHAMMERS.CUSTOM_WARHAMMER: [Crusader, Templar, Cleric, Juggernaut] -> [Crusader, Templar, Cleric, Juggernaut, Warden]. Full NBT diff: only MMOITEMS_REQUIRED_CLASS, MMOITEMS_DYNAMIC_LORE and the lore class line changed; gem, durability, name, stats, quality and tier lines identical. The Warden then hits for damage. A second relog: no ClassSync line, all items identical. The non-AC mi give warhammer (old list), a vanilla sword and an already-matching warhammer are untouched. No AC warnings or errors. Template restored byte-identical; bot cleaned.
  • Local tests: passed at 0688629 (191 tests; only the 4 known Windows-only station persistence failures, which also fail on origin/main; Linux CI runs the coverage gate)

What

AdvancedCrafting's item refresh now makes a crafted MMOItems item's required class follow its current MMOItems template.

Why

MMOItems stamps MMOITEMS_REQUIRED_CLASS on an item when it is built. AC rebuilds crafted items from the item's own NBT (LiveMMOItem), not from the template, so a later template change never reaches existing pieces. On Main, CUSTOM_WARHAMMER gained Warden on 2026-11-07, but a pre-11-07 Parsusite Warhammer still carries Crusader, Templar, Cleric, Juggernaut, so a Warden can't use it. Bumping the MMOItems revision-id isn't an option because it would wipe AC's crafted stats.

How

  • New utils/RequiredClassSync.sync(ItemStack), called from AcItemRefresher.refreshIfOutdated after the stat/lore refresh and before the look migration. It runs on every existing refresh trigger: join and character session (every inventory, armour, off-hand and ender chest slot), opened chests/barrels/storage entities, clicks, hotbar, armour equip and drops.
  • It only handles AdvancedCrafting crafts (items with the craft recipe tag) that are MMOItems items with a known template. Anything else, including an unknown or removed template, is returned unchanged.
  • Cheap check: it reads the NBT class string, splits it, and compares it with the template's required-class as sets (trimmed, so order, spacing and repeats don't count). If they match, it returns the same item: no LiveMMOItem, no rebuild, no write.
  • On a mismatch: it sets REQUIRED_CLASS to the template list in template order, or removes the stat when the template has no required-class. Then it rebuilds through mmo.newBuilder().build(), so MMOItems regenerates the class lore line. The rebuild keeps what the stat refresh keeps: wear (RefreshKeeper.keepWear); skin/model, display name and all PDC (keepAppearance); and amount. It reapplies the stored tier line. No other stat is touched.
  • If the item has a HSTRY_REQUIRED_CLASS stat history, only the history's original layer is compared and replaced, so gem and external layers stay.
  • Each change is logged as [AC][ClassSync] <TYPE>.<ID>: [old] -> [new].
  • The same code works for any future class change on any AC weapon or armour template.

Tests

RequiredClassSyncTest:

  • old list → template list with Warden added, in template order
  • an already-matching item is not read or rebuilt
  • a template without required-class removes the restriction
  • an unknown template, a non-crafted item, a non-MMOItems item, null and air are all left untouched
  • other stats and gem histories stay identical (real MMOItem and StatHistory objects)
  • order, spacing and repeats count as equal
  • a matching stat history is not rebuilt
  • a full refresh keeps amount, PDC, provenance and the tier line

Dev test notes

  • Hold or carry a warhammer crafted before 2026-11-07 as a Warden and rejoin. It should become usable, its lore should list Warden, and the log should show one [AC][ClassSync] line.
  • A second rejoin should log nothing.
  • Name, quality line, gems, stats and durability should be unchanged.

🤖 Generated with Claude Code

Crafted pieces keep the MMOITEMS_REQUIRED_CLASS list stamped at craft
time, and the refresh rebuilds them from their own NBT, so a class added
to a template (Warden on CUSTOM_WARHAMMER) never reached old pieces.

The item refresh (join, character session, opened storage, clicks) now
compares a crafted MMOItems item's class list with its current template
as a set (order, spacing and repeats ignored). On a mismatch it sets the
REQUIRED_CLASS stat to the template list in template order, or removes it
when the template has none, and rebuilds through MMOItems' builder so the
lore line follows; wear, look, name, PDC and the tier line are kept like
the stat refresh does. With a class stat history only its original layer
changes. Matching items, unknown templates and non-crafted items are left
untouched without a rebuild.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Explain Change →

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 780438e1-eef3-455f-b427-f5f7428315e4

No actionable comments were generated in the recent review.

Summary

Summary by CodeRabbit

  • Bug Fixes
    • Crafted items now synchronise their required classes with the current item template during refresh, including when no other refresh is needed.
    • Updates preserve item wear, appearance, quantity, craft tier and other existing item data.

The change adds a utility to synchronise a crafted item’s required classes with its MMOItems template. Item refresh now runs this synchronisation before armour-look migration.

Changes: Required class synchronisation

Layer / File(s) Summary
Synchronise required classes
src/main/java/net/tfminecraft/advancedcrafting/utils/RequiredClassSync.java, src/test/java/net/tfminecraft/advancedcrafting/RequiredClassSyncTest.java
The utility compares class sets without regard to order, spacing or duplicates. It updates or removes the required-class stat when needed, and tests cover item rebuilding, history and metadata preservation, and unchanged inputs.
Apply synchronisation during refresh
src/main/java/net/tfminecraft/advancedcrafting/utils/AcItemRefresher.java
Item refresh passes the selected item through required-class synchronisation before armour-look migration.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Merge Risk: Minimal · previous review 834cf

Crafted items now pick up their template's required class on refresh, and matching or unsupported items are left alone. No concrete defect was established. One narrow case is unconfirmed: a template with no classes on an item that also carries gem-contributed class history. Merge risk is minimal.

- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Recent review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 93b36917-2d40-449b-89bb-7a0897c88782
Commits

Reviewing files that changed from the base of the PR and between 98246a8 and 834cf16.

Files selected for processing: 3

  • src/main/java/net/tfminecraft/advancedcrafting/utils/AcItemRefresher.java
  • src/main/java/net/tfminecraft/advancedcrafting/utils/RequiredClassSync.java
  • src/test/java/net/tfminecraft/advancedcrafting/RequiredClassSyncTest.java

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

@github-actions github-actions Bot added the size:L 100-499 effective changed lines (tests excluded in mixed PRs). label Nov 13, 2026
@XxFran10xX

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Nov 14, 2026 •

Copy link
Copy Markdown
Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Nov 14, 2026
…s ignoring case

Review follow-ups: a class sync error no longer throws away the stat refresh done before it (it is logged
and the item kept), and a case-only template change (warden -> Warden) is no change, as MMOItems matches
class names ignoring case. The update() javadoc now says a template without classes drops the whole stat.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@XxFran10xX
XxFran10xX merged commit ccfae5f into main Nov 14, 2026
3 checks passed
@XxFran10xX
XxFran10xX deleted the fix/refresh-required-class branch November 14, 2026 00:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 effective changed lines (tests excluded in mixed PRs).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant