* fix(protocol): remap item/block state IDs and entity metadata for older Java clients
The server was using reversed ViaVersion mappings (designed for old→new)
to downgrade packets for older clients, which produced ID collisions and
incorrect fallbacks for 26.1-exclusive items and block states.
Changes:
- Replace ViaVersion with ViaBackwards mapping files for item ID and
block state remapping, which provide the correct new→old direction
with proper closest-item fallbacks for 26.1-exclusive content
- Fix CSetEntityMetadata to remap ItemStack item IDs per client version,
matching the version-aware handling already done for inventory packets
and block state metadata
- Fix TrackedData codegen to resolve Java JSON keys correctly by trying
both bare names and DATA_-prefixed names, and iterate the union of all
version keys instead of only the latest (Bedrock) version
- Fix LootCondition::MatchTool to default to false instead of true,
preventing silk-touch loot table branches from always winning and
causing ores to drop themselves instead of their correct items
Fixes: block drops invisible on older Java clients
Fixes: leather showing as milk bucket on 1.21.11
Fixes: coal ore dropping coal ore instead of coal
Fixes: 26.1-exclusive blocks showing as wrong blocks on older clients
* fix(codegen): remove #[must_use] from trait impl methods in generated code
* fix(codegen): switch entity, sound and block state remapping to ViaBackwards mappings
---------
Co-authored-by: Missing_Love <42416195+Q2297045667@users.noreply.github.com>
* fix(entity): derive hurt sound parity from generated mapping
Keep slime hurt sounds in runtime because they depend on entity size.\n\nMove enderman and undead-family hurt sound mappings into generated data so living.rs dispatches through a shared lookup instead of owning a hardcoded table.
* refactor(entity): derive hurt sound lookup from entities data
The Extractor companion now emits hurt_sound through entities.json. Keep Pumpkin's hurt_sound_for_entity_type helper narrow and generated while moving its source of truth to entity data.
Slime remains a runtime special case because its hurt sound depends on size rather than static entity metadata.
* refactor(entity): fold hurt sound helper into entity codegen
Move hurt-sound helper generation into the existing entity codegen path.
Remove the standalone helper builder and generated file now that hurt_sound is sourced from entities.json. Runtime dispatch stays unchanged and slime remains a runtime size-based exception.
* refactor(entity): inline hurt sound into EntityType
Remove the standalone entity_hurt_sound feature and helper path.
Hurt sounds now live directly on generated EntityType values, while runtime behavior stays the same and slime remains the size-based runtime exception.
* feat: implement boat placement
- add boat item handler for all boat/raft types
- raycast with fluid handling to place on water or blocks
- filter entities with can_hit predicate (vanilla parity)
- check space is empty before spawning
- decrement item unless creative mode
* feat: add boat entity with damage handling
- create BoatEntity struct implementing EntityBase
- implement can_hit() and is_collidable() for boats
- implement damage handling that drops boat item on destroy
- update boat item to spawn BoatEntity instead of generic Entity
* fix: boat damage wobble and attack sounds match vanilla
Boats now accumulate damage with wobble animation that decays over time.
Attack sounds play for all hittable entities, not just living entities.
* feat: add boat riding and vehicle movement packets
* feat: complete boat implementation matching vanilla
- add underwater check (60 ticks) and max 2 passengers limit
- add paddle animation metadata and handler
- implement proper land dismount with offset calculation
- add riding_cooldown field to entity
* fix: clippy warnings for boat implementation
* refactor: use loot tables for boat item drops
* fix: collapse nested if to satisfy clippy
* style: fix cargo fmt formatting for collapsible if
* fix: boat dismount places player correctly beside vehicle
- implement vanilla's dismount position calculation with
getDismountHeight, canDismountInBlock, and pose fallback
(standing → crouching → swimming)
- fix packet ordering race: use enqueue_packet for teleport so it
arrives after CSetPassengers (send_packet_now bypassed the queue)
- pre-set awaiting_teleport before CSetPassengers to block stale
movement packets during async dismount calculation
- send CSetPassengers directly to dismounting player, broadcast to
others (matching vanilla's targeted packet behavior)
- use DELTA|ROT position flags for teleport (vanilla preserves
current look direction with relative rotation)
- add riding cooldown (60 ticks) to prevent immediate re-mount
- reset sneaking state after player dismount
- fix water detection to check specifically for water/flowing_water
fluids (Fluid::from_state_id returns EMPTY for air blocks)
- revert broken loot table refactor for boat item drops (boats use
hardcoded entity-to-item mapping, not loot tables)
- add get_dismount_height helper on World matching vanilla's
BlockView.getDismountHeight()
- ignore movement packets while awaiting teleport confirmation in
handle_position and handle_position_rotation
* style: fix cargo fmt formatting
* refactor: use loot tables for boat item drops
add loot table entries to entities.json for all 20 boat/raft types
and use the existing loot table system instead of hardcoded mapping.
* fix: resolve rebase conflicts and clippy warnings
* fix: regenerate codegen to include boat loot tables
Its works, but block state ids are currently not mapped, meaning that when using the current default world gen the client mostly will disconnect due to a not found block state id, vanilla version compatible worlds should work