Skip to content

Let an attuned mage weapon be re-attuned from scratch for a fee - #64

Merged
XxFran10xX merged 3 commits into
mainfrom
reattune-mage-weapons
Oct 21, 2026
Merged

XxFran10xX merged 3 commits into
mainfrom
reattune-mage-weapons

Conversation

@XxFran10xX

Copy link
Copy Markdown
Contributor

What

fran asked for already-crafted mage weapons to be attunable again, at a higher cost. A recharge (setting the weapon back on a station and applying another charge) already worked, but it can only raise a weapon's requirements: an element can never be removed or swapped. This adds a paid reset that wipes the old attunement and lets the weapon be attuned from scratch.

How it works

  1. Sneak + right-click an empty Magic station while holding an attuned weapon the station can create. Chat lists the fee and asks for a second sneak-right-click within gear.confirm_seconds.

  2. The second click pays the fee and rests one weapon on the station as a pending reset (rested: true, reattune: true, with the fee kept in charged). The weapon itself isn't changed yet.

  3. Apply a charge as usual. When a run catches something:

    • the weapon's requirements are replaced by what it caught, instead of the highest-only merge;
    • its Rift becomes this run's bad hits, and the old Rift is dropped;
    • sockets and runes are left alone, because rewriteSockets would wipe applied runes, and with socket_rarity_prefix: false the colours wouldn't change anyway.

    The row then becomes a plain rested weapon, its charged set to {}.

  4. A run that catches nothing leaves the old attunement untouched. The reset stays paid and pending for another charge.

While a reset is pending:

  • Empty-hand pickup is blocked.
  • Only the owning character or magic.admin can apply a charge, since whoever charges it picks the new attunement.
  • Between runs, the owner's shift-left-click calls it off and returns the unchanged weapon and the whole fee. A running charge can't be called off, so the fee can't be refunded after seeing how a run is going.
  • A station that loses its furniture drops the fee with the weapon.
  • An unreadable fee record or an unbuildable material leaves the station for staff review, with a message to the owner and a log warning.

Plain right-click recharging is unchanged.

Fee

gear.reattune.cost_fraction in config.yml, default 0.5. It is that share of the weapon's current part costs in gear/parts.yml, rounded up per material, and at least 1 of each material when the share is above 0. 0 makes the reset free, and magic.bypass_crafting_cost skips the fee as it does for crafting. For example, Main's iron staff with basic parts pays 2 iron, 1 stick, 3 books and 12 enchanted dust.

The jar doesn't add the new key to an existing config.yml, so a live config without it gets the 0.5 default. New gear.reattune.* messages fall back to the bundled messages.yml until they're added to a live copy.

Tests

  • New GearReattuneCoverageTest, plus reset cases in GearStationListenerCoverageTest, GearOrbServiceCoverageTest, GearChargeCoverageTest and ConfigurationTest.
  • Full mvn verify on Linux: 683 tests pass and the 100% coverage gate is met. The station persistence suites need Linux directory fsync, so they can't run on Windows.
  • Dev (DEV-20261021-reattune, mineflayer bot TestChar2 on a real character):
    • The fee is listed and paid (3 dust, 2 iron, 1 stick for an iron wand). Server-side inventory confirms the exact fee is taken and refunded, twice over.
    • Empty-hand pickup is refused. The abort returns the unchanged Mitlan 70 weapon plus the fee.
    • A missed run gives "The charge scatters" and "The old attunement holds", and keeps Mitlan III.
    • A caught run gives "settles at III, 100%" and "The old attunement is gone". The weapon now holds only Seithr 75, with Rift 15% from 3 bad hits.
    • No Magic warnings and no held gear rows.

Docs: TF-Minecraft/Docs MAGE_GEAR.md "Re-attuning from scratch" (separate PR).

🤖 Generated with Claude Code

XxFran10xX and others added 3 commits October 21, 2026 13:49
Sneak-right-clicking an empty station with an attuned weapon names a
fee (gear.reattune.cost_fraction of the weapon's part costs, 0.5 by
default, rounded up per material). A second sneak-click within the
confirm window pays it and rests the weapon as a pending reset.

The next charge's run replaces the weapon's elements and Rift with
what it catches. A run that catches nothing leaves the old attunement
and keeps the reset pending. Only the owner can charge a pending
reset, and empty-hand pickup is blocked; the owner's shift-left-click
returns the unchanged weapon with the whole fee. A station that loses
its furniture drops the fee with the weapon.

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

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3cd53f8d-4948-4309-9a0b-83f0acdd2035
📥 Commits

Reviewing files that changed from the base of the PR and between cabd8b4 and 0eeb4a2.

📒 Files selected for processing: 18
  • src/main/java/net/tfminecraft/magic/gear/GearCache.java
  • src/main/java/net/tfminecraft/magic/gear/GearChargeService.java
  • src/main/java/net/tfminecraft/magic/gear/GearCosts.java
  • src/main/java/net/tfminecraft/magic/gear/GearReattuneService.java
  • src/main/java/net/tfminecraft/magic/gear/GearStationListener.java
  • src/main/java/net/tfminecraft/magic/gear/GearStationStore.java
  • src/main/java/net/tfminecraft/magic/gear/WeaponRequirement.java
  • src/main/java/net/tfminecraft/magic/gear/orb/GearOrbService.java
  • src/main/java/net/tfminecraft/magic/gear/ownership/GearEffects.java
  • src/main/java/net/tfminecraft/magic/listener/MagicSessionListener.java
  • src/main/java/net/tfminecraft/magic/loader/ConfigLoader.java
  • src/main/resources/config.yml
  • src/main/resources/messages.yml
  • src/test/java/net/tfminecraft/magic/ConfigurationTest.java
  • src/test/java/net/tfminecraft/magic/GearChargeCoverageTest.java
  • src/test/java/net/tfminecraft/magic/GearOrbServiceCoverageTest.java
  • src/test/java/net/tfminecraft/magic/GearReattuneCoverageTest.java
  • src/test/java/net/tfminecraft/magic/GearStationListenerCoverageTest.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.

📝 Summary

Summary by CodeRabbit

  • New Features
    • Added weapon re-attunement at empty gear stations via sneak-right-click.
    • Re-attunement now supports confirmation, material costs, ownership checks, and expiry protection.
    • Successful re-attunement resets the weapon’s attunement while preserving applicable gear details.
    • Configurable fees default to 50% of component costs, rounded up; bypass permissions and zero-cost settings are supported.
  • Bug Fixes
    • Prevented unauthorised players from charging or re-attuning weapons.
    • Cancelled operations refund applicable materials, and pending fees drop safely if a station is removed.
    • Added clearer messages for warnings, requirements, completion, cancellation, and failures.

The change adds a configurable fee and confirmation flow for reattuning weapons at empty stations. Pending reattunements retain their fee and station state through orb completion, cancellation, and station removal. Successful orb runs can replace the weapon’s attunement.

Changes: Weapon reattunement

Layer / File(s) Summary
Fee configuration and reattunement request
src/main/java/net/tfminecraft/magic/gear/GearCache.java, src/main/java/net/tfminecraft/magic/gear/GearCosts.java, src/main/java/net/tfminecraft/magic/gear/GearReattuneService.java, src/main/java/net/tfminecraft/magic/loader/ConfigLoader.java, src/main/resources/config.yml, src/main/resources/messages.yml, src/test/java/net/tfminecraft/magic/ConfigurationTest.java, src/test/java/net/tfminecraft/magic/GearReattuneCoverageTest.java
The configured fee defaults to half of each weapon-part cost, rounded up per material. The request flow checks confirmation, available materials, held-item integrity, and cost-bypass permission before depositing a weapon for reattunement.
Pending station state and fee return
src/main/java/net/tfminecraft/magic/gear/GearChargeService.java, src/main/java/net/tfminecraft/magic/gear/GearStationListener.java, src/main/java/net/tfminecraft/magic/gear/GearStationStore.java, src/main/java/net/tfminecraft/magic/gear/ownership/GearEffects.java, src/main/java/net/tfminecraft/magic/listener/MagicSessionListener.java, src/test/java/net/tfminecraft/magic/GearChargeCoverageTest.java, src/test/java/net/tfminecraft/magic/GearReattuneCoverageTest.java, src/test/java/net/tfminecraft/magic/GearStationListenerCoverageTest.java
Stations persist pending reattunement state and charged materials. Reattunement stations block ordinary ejection and require owner authorisation. Cancellation returns the weapon and fee; station removal drops the fee with the weapon.
Reattunement orb completion
src/main/java/net/tfminecraft/magic/gear/WeaponRequirement.java, src/main/java/net/tfminecraft/magic/gear/orb/GearOrbService.java, src/test/java/net/tfminecraft/magic/GearOrbServiceCoverageTest.java
Reattunement completion starts with empty requirements. A valid captured band replaces the attunement while preserving sockets; otherwise, the original weapon remains. Successful reattunement uses a dedicated station completion path.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant Player
  participant GearStationListener
  participant GearReattuneService
  participant GearCosts
  participant GearEffects
  Player->>GearStationListener: Sneak-right-click empty station
  GearStationListener->>GearReattuneService: Request reattunement
  GearReattuneService->>GearCosts: Calculate and plan fee
  GearReattuneService->>Player: Show fee and request confirmation
  Player->>GearReattuneService: Confirm request
  GearReattuneService->>GearEffects: Deposit weapon with fee and reattune flag
Loading

Suggested reviewers: ryanbarlow97

Merge Risk: ⚪ Minimal · up to 0eeb4

The reviewed reset, fee-return, and completion paths have no identified issue requiring a fix before merge. Proceed with normal checks.

- [ ] 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

Comment @coderabbitai help to get the list of available commands.

@XxFran10xX

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 21, 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.

@XxFran10xX
XxFran10xX merged commit 464c85c into main Oct 21, 2026
3 checks passed
@XxFran10xX
XxFran10xX deleted the reattune-mage-weapons branch October 21, 2026 12:15
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