Item::CROSSBOW ships a ChargedProjectiles component by default, carrying an empty
projectile list (crates/pumpkin-data/src/generated/item.rs, the CROSSBOW components
table). normal_use tested only for the presence of that component, which is therefore
true for every crossbow including a freshly crafted one.
The result is that the first right-click on an uncharged crossbow takes the fire branch,
fire_projectiles iterates an empty list and does nothing, and charging never starts, so
the crossbow cannot be used at all until something else happens to write a non-empty
patch.
Vanilla gates on the list being present AND non-empty:
ChargedProjectiles chargedProjectiles = itemStack.get(DataComponents.CHARGED_PROJECTILES);
if (chargedProjectiles != null && !chargedProjectiles.isEmpty()) {
(CrossbowItem.java:67-68, 26.2.) Matching that here restores the charge-then-fire cycle.
Test plan:
- cargo fmt --all
- RUSTFLAGS="-D warnings" cargo clippy -p pumpkin --all-targets
`ProtoChunk::new` took its height from the noise settings while
`Chunk::build_level_sections` builds and reads back `dimension.height / 16`
sections. The End and the Nether are the two dimensions taller than their noise
settings (256 vs 128), so their proto chunks held 8 sections for the 16 the
level chunk asks for and `get_block_state_raw` indexed past the end of
`flat_block_map`, panicking on every generation thread. The same mismatch left
light data covering half the column and dropped features placed above y = 128.
A chunk spans its dimension, as in vanilla's `LevelHeightAccessor`; the noise
settings only bound the vertical window the generator writes into. `ProtoChunk`
now carries both, storage sized by the dimension plus a generation window built
with `GenerationShapeConfig::trim_height`, so surface rules, carver height
providers and feature placement keep resolving against y < 128 there.
The panic quoted in the issue (`chunk_density_function.rs`, len 99 index 129)
was the same conflation in `populate_noise` and is already fixed by 3c43f971.
`AnvilLevelInfo::read_world_info` validated the version tags and then returned
`LevelData::default(Seed(0))`, so level name, difficulty, spawn, world border
and data packs were discarded on every start, and the writer emitted only
`DataVersion`, `version` and `LastPlayed`, truncating the rest on save. A world
whose seed lives in level.dat's legacy `Data.WorldGenSettings` compound, as
converters such as Chunker emit, therefore loaded with seed 0 and generated
foreign terrain into its existing region files.
level.dat is now read and written tag by tag through pumpkin-nbt, every field
falling back to its vanilla default, so a missing optional tag such as
`Version.Series` no longer costs the whole file. Saving merges into the existing
`Data` compound, so tags Pumpkin does not model survive. A world with no seed
in either file aborts startup instead of silently regenerating, and the seed is
mirrored into level.dat, the only world file that is backed up. Version tags are
re-stamped with the current constants on save so level.dat stays consistent with
the chunks Pumpkin writes.
* fix(protocol): accept BungeeCord-forwarded handshake addresses
`SHandShake::read` bounded `server_address` at 255 characters, the limit a
vanilla client observes. `bungeecord_login`, however, expects that same field
to carry the host, the client's IP, its UUID and its signed profile properties
separated by NUL bytes, exactly as documented on that function. With
`ip_forward` enabled the signed properties alone run past a thousand
characters, so the read failed with "too large: string" before
`handle_handshake` ever ran: the connection state never advanced,
`server_address` stayed empty and the proxy login path could not be reached.
The same struct already writes this field with `write_string`, which bounds it
at `i16::MAX`, so the reader was stricter than the writer. Read it with that
same bound, as Spigot does.
Closes#1293
* test(proxy): cover a BungeeCord login from the wire up
Encodes a handshake the way BungeeCord puts it on the wire with
`ip_forward` enabled, decodes it with the real packet reader, and hands
the resulting address to `bungeecord_login`, asserting the forwarded IP,
the forwarded UUID and the signed skin all survive the trip.
Without the widened bound on `server_address` this fails inside
`SHandShake::read`, so `bungeecord_login` is never reached at all.
Implements the missing redstone half of the lectern:
- page turns pulse the powered state for 2 game ticks (vanilla parity),
strongly powering the block below and playing the page-turn event
- placing/taking a book resets the pulse and notifies neighbors
- comparator output now uses the vanilla formula
floor(page / (pageCount - 1) * 14) + 1 instead of a scaled variant
- adds the lectern screen handler (page buttons, jump-to-page and
take-book) so the pulse can actually be triggered by players; the
current page is synced as container property 0
- using a lectern with a book now opens the reading screen instead of
silently deleting the book
Co-authored-by: Mcxiaocaibug <Mcxiaocaibug@users.noreply.github.com>
* feat: Add Mineshaft Generation
* fix(structures): remove redundant mineshaft probability gate
The MINESHAFTS structure_set already gates generation via its
frequency reduction (0.004, LegacyType3) in placement, so the extra
0.01 roll in the generator was double-gating and made mineshafts far
too rare. No other Pumpkin structure generator rolls its own
probability, so the gate has been removed to match vanilla frequency.
* feat(structures): faithful port of vanilla mineshaft generation
Rewrites all mineshaft pieces to match vanilla MineshaftPieces
(decompiled from server.jar):
- Corridor: 3-wide tunnel with fence posts + plank beams every 5
blocks, floor planks below the box at y=-1, cobwebs, rails (with
correct NORTH_SOUTH / EAST_WEST shape per corridor axis), cave-spider
spawner (spider corridors), chest (1%), wood support pillars
- Room: carved dome chamber at Y=50, vanilla dims (8-13 wide)
- Crossing: 5x5 with corner pillars, optional two-floored
- Stairs: vanilla descending staircase (air-only, no planks)
- Assembly: vanilla piece weights (70% corridor / 10% stairs / 20%
crossing), depth <= 8, bounds = 80 blocks from start
- Liquid check (isInInvalidLocation): aborts pieces in water/lava
- Mesa variant: dark oak wood throughout
* feat(world): support generated loot minecarts
* Minecart Vanila Parity
* Rebased And Added Furnace, Hopper, TNT Minecarts
* Refactor minecarts and fix off-rail gravity
Split minecart variants into focused modules, correct airborne minecart physics, and remove the test-only entity chunk-loading rework.
* Fix mineshaft vanilla parity
---------
Co-authored-by: Zoltán Virágh <zoltan.viragh@cloudtalk.io>
* refactor: enchant command
Removes the only_one var and nested logic
* chore: removed TODO since it is now patched
In commit 938a627 (fix(item): prevent stacking items with different components (#2624)) this is patched since if a item is enchanted it will always have a extra data component which will now be detected and synced