
TrialChamberPro
Because Trial Chambers deserve better than being a "one and done" dungeon.
1.7K
20
Список изменений
This plugin version is compatible with Minecraft 26.X.X
1.3.0 - 2026-04-23
Added
- Custom Mob Provider API — new pluggable
TrialMobProviderinterface (providers/TrialMobProvider.kt) lets trial-spawner waves source mobs from external plugins instead of vanilla. Two built-in providers ship in this release:vanilla(default, unchanged behavior) andmythicmobs(reflection-based soft-dep on MythicMobs — no compile-time binding). - Replace-after-spawn strategy — when a chamber is configured with a non-vanilla provider,
SpawnerWaveListenerlets the vanilla trial spawner spawn its mob, then removes that entity the same tick and asks the provider to spawn its replacement at the same location. The vanilla spawner's state machine (tracked UUIDs, wave counter, cooldown) is preserved, so boss bars, glow outlines, and cooldown management all continue to work with custom mobs. - Plugin-driven Trial Key drops — vanilla's key-ejection path relies on tracked mob UUIDs that no longer exist when we replace the spawns, so
SpawnerWaveManager.maybeDropProviderKeysdropsTRIAL_KEY/OMINOUS_TRIAL_KEYitself: one per unique participant, above the spawner block, with a small upward velocity that approximates vanilla's pop. The key type is captured at wave start (WaveState.isOminousis aval) and cannot flip mid-wave. - Owner-only spawner-key pickup — new
SpawnerKeyDropOwnerListenersibling ofVaultDropOwnerListener(v1.2.28). Drops are PDC-tagged withtcp:spawner_key_owner+tcp:spawner_key_dropped_at; non-owner pickups are cancelled during the grace window. Config:reset.spawner-key-drop-owner-grace-seconds(default30,0= owner-locked until despawn). Sharedtcp.bypass.droplockpermission with vault drops. - Per-chamber provider configuration — new DB columns
custom_mob_provider,custom_mob_ids_normal,custom_mob_ids_ominous(JSON-encoded id lists) onchambersvia idempotent migration. Ominous waves fall back to the normal list if the ominous list is empty, matching the loot-table override pattern.ChamberManager.updateCustomMobProvider(id, provider, normalIds, ominousIds)is the single write path;Chamber.pickMobId(ominous)andChamber.hasCustomMobProvider(ominous)are the read-side helpers. CustomMobProviderViewGUI — new 6-row admin view reachable fromChamberSettingsView(spawner icon, row 2 centre). Cycle providers with left/right-click, shift-click to reset to vanilla; add mob ids via a one-shot chat input (MobIdInputListener) with 30-second timeout andcancelkeyword; click a mob-id icon to remove it. All writes go throughChamberManager.updateCustomMobProviderand the view refreshes on the player's region thread after each change./tcp mobscommand — CLI path for per-chamber provider config:/tcp mobs providers— list registered providers and their availability/tcp mobs <chamber> provider <id|vanilla|none>— set the provider/tcp mobs <chamber> add normal|ominous <mobId>— add a mob id to the pool/tcp mobs <chamber> remove normal|ominous <mobId>— remove a mob id/tcp mobs <chamber> list— show current config- Permission:
tcp.admin.mobs(default op)
- MythicMobs integration as a soft-dependency via
plugin.ymlsoftdepend.MythicMobsProviderresolvesio.lumine.mythic.bukkit.MythicBukkit+MobManager.spawnMob(String, Location, double)reflectively and degrades gracefully if the API shape changes. - Additional provider integrations — five more providers, all zero-compile-time-dependency reflection with cached availability and verbose-logging-gated warnings:
elitemobs— EliteMobs custom-boss spawning vianew CustomBossEntity(filename)+spawn(Location, 0, true)+getLivingEntity(). Mob id = boss filename (with or without.yml).ecomobs— Auxilor EcoMobs (hard-depends on Eco) viaEcoMobs[id].spawn(Location, SpawnReason.CUSTOM). Mob id = entry id fromplugins/EcoMobs/mobs/<id>.yml.levelledmobs— spawns a vanillaEntityTypeand applies a LevelledMobs level throughLevelInterface2.applyLevelToMob(LivingEntityWrapper, int, ...). Mob id formatENTITY_TYPE[:level|ominous](e.g.ZOMBIE:15,HUSK:ominous). The ominous keyword maps to tiered levels (20 for ominous waves, 10 otherwise).infernalmobs— spawns a vanillaEntityTypeand enriches it viainfernal_mobs.makeInfernal(Entity, false)(abilities are rolled by the plugin from config). Mob id formatENTITY_TYPE.citizens— clones a template NPC from the defaultNPCRegistry(by numeric id or exact name) and spawns the clone so template NPCs are never moved. Mob id = Citizens NPC id or name.
- Plugin.yml softdepends —
EliteMobs,Eco,EcoMobs,LevelledMobs,InfernalMobs,Citizensadded alongsideMythicMobsso load order guarantees the provider registry sees every backing plugin before seeding.
Changed
TrialChamberPro.onEnablenow constructs aTrialMobProviderRegistryafter manager init and conditionally registersMythicMobsProviderwhen MythicMobs is present on the server. Accessible viaplugin.trialMobProviderRegistry.
Added — GUI translatability
- Full GUI localization — every name, lore line, and button label across all 18 admin GUI views is now driven by
messages.ymlunder a nestedgui.*section (~330 new keys). No hard-codedComponent.text(...)calls left in any view file. See docs/configuration/localization.md for the key naming conventions and translator workflow. gui/components/GuiComponents.kt— reusable builders (infoItem,toggleItem,backButton,closeButton,prevPageButton,nextPageButton,playerHeadx2) plus a class-doc that codifies icon material conventions in 5 categories (Navigation, Action buttons, State indicators, Settings categories, Domain icons). All views now build through this layer; future GUI code uses the localization layer by default.TrialChamberProhelper additions —loadedMessages(),getMessageList(key, ...),getGuiText(key, ...)returning aComponent,getGuiLore(key, ...)returning aList<Component>.getMessage()auto-skips the chat prefix for any key starting withgui.so admin items don't get[TCP]prepended.- Empty-state placeholders added to 6 list/grid views (chamber list, chambers overview, loot table list, vault management, custom mob provider, loot editor) so admins always see a localized "no entries" card instead of a confusing blank pane.
Added — Public event API
- 6 events under
api/events/— Bukkit-style events that third-party plugins can hook without forking. See docs/api/events.md for field tables and integration examples.ChamberResetEvent(cancellable) withReasonenum (SCHEDULED / MANUAL / FORCED)ChamberResetCompleteEvent— post-reset with duration + blocks restoredVaultOpenedEvent— post-open with cloned item snapshotSpawnerWaveCompleteEvent— post-wave with participants setChamberDiscoveredEvent(cancellable) withMethodenum (CHUNK_LOAD / STARTUP_SWEEP)TrialKeyDropEvent(cancellable) — per-participant key drop for provider-driven waves
- All events use
Event(!Bukkit.isPrimaryThread())so they correctly identify as async when fired from coroutines or Folia region threads. - 5 fire sites wired:
ResetManager.resetChamber(pre + post;reasonparameter added withMANUALdefault — scheduled paths passSCHEDULED, GUI shift+right force-reset paths passFORCED);VaultInteractListener.openVault(post, with cloned items snapshot);SpawnerWaveManager.completeWave(post);SpawnerWaveManager.maybeDropProviderKeys(per-participant pre/cancellable);ChamberDiscoveryManager.registerChamber(pre/cancellable).
Added — Stability + reliability
MenuSessionCleanupListener— drops a player's GUI session onPlayerQuitEvent. Belt-and-braces soft-cap eviction at 500 sessions insideMenuServicecovers any future code paths that forget to clean up.config/ConfigValidator— startup sanity check that clamps ~12 numeric config values back into safe ranges with logged warnings (no hard-fail). Sentinel values (e.g.-1for "use vanilla cooldown") pass through untouched. Runs early inonEnableso the rest of the bootstrap sees corrected values./tcp mobstab completer — second/third/fourth-arg completion forproviders,provider,add,remove,listand thenormal/ominouswave keywords./tcp mobslocalization — ~23 newmobs-*keys inmessages.yml; the command no longer hard-codes any English strings.
Added — Test foundation
- 67 unit tests across 5 test classes (
./gradlew testruns in seconds; covers gzip roundtripping, Chamber bounds math, coordinate parsing, LootEditorDraft mutability/equality, and ConfigValidator clamp behavior). Paper API added totestImplementationso tests can mock Bukkit types via MockK without spinning up a server.
Changed — Internal structure
models/LootEditorDraft— extracted fromLootEditorView.Draftso amount/loot editors andMenuServiceno longer reach into the view class for a shared data type.commands/handlers/— three of the largest/tcpsubcommands extracted to dedicatedSubcommandHandlerclasses:GenerateCommand(548 → 432 lines, with allparse*/validate*/placeBoxFromPlayerhelpers andMIN_XZ/MIN_Yconstants moved out ofTCPCommand),MobsCommand, andLootCommand(with the four sub-actions — set, clear, info, list — as private methods on the class). The fourgeneratemode branches now share acreateChamberAsynchelper that deduplicated ~120 lines of identical scan/snapshot follow-up code.TCPCommand.kt: 1461 → 627 lines (57% reduction). The dispatcher is a thin when-chain that routes to size-appropriate cases — small handlers stay inline, big ones delegate.commands/handlers/CoordinateParser— pure parsing logic (parseTriple,parseHyphenated,isTripleString) extracted fromGenerateCommandto enable unit testing without mockingBukkit.getWorld().GenerateCommand.parseCoordsArgsnow delegates toCoordinateParserfor the pure parts and keeps only the world-aware composition logic.
Notes
- Not persisted across restart: in-progress waves still reset to vanilla on server stop (matches pre-1.3.0 behavior). Acceptable for this release; revisit if restart-mid-wave becomes a common report.
- All planned providers ship in 1.3.0: the six providers originally split between 1.3.0 (vanilla + MythicMobs) and 1.3.1+ (EliteMobs, EcoMobs, LevelledMobs, InfernalMobs, Citizens) are now all in the initial release. The
TrialMobProviderinterface is stable for third-party providers to register against — see docs/api/mob-providers.md for the developer guide. - Public API stability: the v1.3.0 event classes and
TrialMobProviderinterface are considered stable. Field names, enum constants, and method signatures will go through a deprecation cycle before any breaking change. - No config file format changes — existing
config.yml,loot.yml, andmessages.ymlfiles continue to work. Existing chambers, loot tables, and snapshots are unaffected. Translators who already customizedmessages.ymlwill see the new GUI translation keys auto-merged from the bundled defaults on first reload.
Файлы
TrialChamberPro-1.3.0-beta.1-mc26.jar(12.50 MiB)
ОсновнойМетаданные
Канал релиза
Beta
Номер версии
1.3.0-beta.1-mc26
Загрузчики
FoliaPaperPurpur
Версии игры
26.1–26.1.2
Загрузок
5
Дата публикации
1 нед. назад
