Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
bf7e52138d | |||
683cf8d80c | |||
0a0075ce05 | |||
2d4f820f04 | |||
838eafcf56 | |||
ab97315910 | |||
c5c21d89b6 | |||
ddbe59a5ac | |||
0103a654c3 |
.gitignoreplugin.ymlterrain.png
.idea
build.gradlesettings.gradlesrc/main
java
eu
mhsl
minecraft
pixelpic
pixelpics
ImageMapRenderer.javaMain.java
commands
render
resources
colormap
models
block
acacia_button.jsonacacia_button_inventory.jsonacacia_button_pressed.jsonacacia_door_bottom_left.jsonacacia_door_bottom_left_open.jsonacacia_door_bottom_right.jsonacacia_door_bottom_right_open.jsonacacia_door_top_left.jsonacacia_door_top_left_open.jsonacacia_door_top_right.jsonacacia_door_top_right_open.jsonacacia_fence_gate.jsonacacia_fence_gate_open.jsonacacia_fence_gate_wall.jsonacacia_fence_gate_wall_open.jsonacacia_fence_inventory.jsonacacia_fence_post.jsonacacia_fence_side.jsonacacia_hanging_sign.jsonacacia_leaves.jsonacacia_log.jsonacacia_log_horizontal.jsonacacia_planks.jsonacacia_pressure_plate.jsonacacia_pressure_plate_down.jsonacacia_sapling.jsonacacia_sign.jsonacacia_slab.jsonacacia_slab_top.jsonacacia_stairs.jsonacacia_stairs_inner.jsonacacia_stairs_outer.jsonacacia_trapdoor_bottom.jsonacacia_trapdoor_open.jsonacacia_trapdoor_top.jsonacacia_wood.jsonactivator_rail.jsonactivator_rail_on.jsonactivator_rail_on_raised_ne.jsonactivator_rail_on_raised_sw.jsonactivator_rail_raised_ne.jsonactivator_rail_raised_sw.jsonair.jsonallium.jsonamethyst_block.jsonamethyst_cluster.jsonancient_debris.jsonandesite.jsonandesite_slab.jsonandesite_slab_top.jsonandesite_stairs.jsonandesite_stairs_inner.jsonandesite_stairs_outer.jsonandesite_wall_inventory.jsonandesite_wall_post.jsonandesite_wall_side.jsonandesite_wall_side_tall.jsonanvil.jsonattached_melon_stem.jsonattached_pumpkin_stem.jsonazalea.jsonazalea_leaves.jsonazure_bluet.jsonbamboo1_age0.jsonbamboo1_age1.jsonbamboo2_age0.jsonbamboo2_age1.jsonbamboo3_age0.jsonbamboo3_age1.jsonbamboo4_age0.jsonbamboo4_age1.jsonbamboo_block.jsonbamboo_block_x.jsonbamboo_block_y.jsonbamboo_block_z.jsonbamboo_button.jsonbamboo_button_inventory.jsonbamboo_button_pressed.jsonbamboo_door_bottom_left.jsonbamboo_door_bottom_left_open.jsonbamboo_door_bottom_right.jsonbamboo_door_bottom_right_open.jsonbamboo_door_top_left.jsonbamboo_door_top_left_open.jsonbamboo_door_top_right.jsonbamboo_door_top_right_open.jsonbamboo_fence_gate.jsonbamboo_fence_gate_open.jsonbamboo_fence_gate_wall.jsonbamboo_fence_gate_wall_open.jsonbamboo_fence_inventory.jsonbamboo_fence_post.jsonbamboo_fence_side_east.jsonbamboo_fence_side_north.jsonbamboo_fence_side_south.jsonbamboo_fence_side_west.jsonbamboo_hanging_sign.jsonbamboo_large_leaves.jsonbamboo_mosaic.jsonbamboo_mosaic_slab.jsonbamboo_mosaic_slab_top.jsonbamboo_mosaic_stairs.jsonbamboo_mosaic_stairs_inner.jsonbamboo_mosaic_stairs_outer.jsonbamboo_planks.jsonbamboo_pressure_plate.jsonbamboo_pressure_plate_down.jsonbamboo_sapling.jsonbamboo_sign.jsonbamboo_slab.jsonbamboo_slab_top.jsonbamboo_small_leaves.jsonbamboo_stairs.jsonbamboo_stairs_inner.jsonbamboo_stairs_outer.jsonbamboo_trapdoor_bottom.jsonbamboo_trapdoor_open.jsonbamboo_trapdoor_top.jsonbanner.jsonbarrel.jsonbarrel_open.jsonbarrier.jsonbasalt.jsonbeacon.jsonbed.jsonbedrock.jsonbedrock_mirrored.jsonbee_nest_empty.jsonbee_nest_honey.jsonbeehive_empty.jsonbeehive_honey.jsonbeetroots_stage0.jsonbeetroots_stage1.jsonbeetroots_stage2.jsonbeetroots_stage3.jsonbell_between_walls.jsonbell_ceiling.jsonbell_floor.jsonbell_wall.jsonbig_dripleaf.jsonbig_dripleaf_full_tilt.jsonbig_dripleaf_partial_tilt.jsonbig_dripleaf_stem.jsonbirch_button.jsonbirch_button_inventory.jsonbirch_button_pressed.jsonbirch_door_bottom_left.jsonbirch_door_bottom_left_open.jsonbirch_door_bottom_right.jsonbirch_door_bottom_right_open.jsonbirch_door_top_left.jsonbirch_door_top_left_open.jsonbirch_door_top_right.jsonbirch_door_top_right_open.jsonbirch_fence_gate.jsonbirch_fence_gate_open.jsonbirch_fence_gate_wall.jsonbirch_fence_gate_wall_open.jsonbirch_fence_inventory.jsonbirch_fence_post.jsonbirch_fence_side.jsonbirch_hanging_sign.jsonbirch_leaves.jsonbirch_log.jsonbirch_log_horizontal.jsonbirch_planks.jsonbirch_pressure_plate.jsonbirch_pressure_plate_down.jsonbirch_sapling.jsonbirch_sign.jsonbirch_slab.jsonbirch_slab_top.jsonbirch_stairs.jsonbirch_stairs_inner.jsonbirch_stairs_outer.jsonbirch_trapdoor_bottom.jsonbirch_trapdoor_open.jsonbirch_trapdoor_top.jsonbirch_wood.jsonblack_candle_cake.jsonblack_candle_cake_lit.jsonblack_candle_four_candles.jsonblack_candle_four_candles_lit.jsonblack_candle_one_candle.jsonblack_candle_one_candle_lit.jsonblack_candle_three_candles.jsonblack_candle_three_candles_lit.jsonblack_candle_two_candles.jsonblack_candle_two_candles_lit.jsonblack_carpet.jsonblack_concrete.jsonblack_concrete_powder.jsonblack_glazed_terracotta.jsonblack_shulker_box.jsonblack_stained_glass.jsonblack_stained_glass_pane_noside.jsonblack_stained_glass_pane_noside_alt.jsonblack_stained_glass_pane_post.jsonblack_stained_glass_pane_side.jsonblack_stained_glass_pane_side_alt.jsonblack_terracotta.jsonblack_wool.jsonblackstone.jsonblackstone_slab.jsonblackstone_slab_top.jsonblackstone_stairs.jsonblackstone_stairs_inner.jsonblackstone_stairs_outer.jsonblackstone_wall_inventory.jsonblackstone_wall_post.jsonblackstone_wall_side.jsonblackstone_wall_side_tall.jsonblast_furnace.jsonblast_furnace_on.jsonblock.jsonblue_candle_cake.jsonblue_candle_cake_lit.jsonblue_candle_four_candles.jsonblue_candle_four_candles_lit.jsonblue_candle_one_candle.jsonblue_candle_one_candle_lit.jsonblue_candle_three_candles.jsonblue_candle_three_candles_lit.jsonblue_candle_two_candles.jsonblue_candle_two_candles_lit.jsonblue_carpet.jsonblue_concrete.jsonblue_concrete_powder.jsonblue_glazed_terracotta.jsonblue_ice.jsonblue_orchid.jsonblue_shulker_box.jsonblue_stained_glass.jsonblue_stained_glass_pane_noside.jsonblue_stained_glass_pane_noside_alt.jsonblue_stained_glass_pane_post.jsonblue_stained_glass_pane_side.jsonblue_stained_glass_pane_side_alt.jsonblue_terracotta.jsonblue_wool.jsonbone_block.jsonbookshelf.jsonbrain_coral.jsonbrain_coral_block.jsonbrain_coral_fan.jsonbrain_coral_wall_fan.jsonbrewing_stand.jsonbrewing_stand_bottle0.jsonbrewing_stand_bottle1.jsonbrewing_stand_bottle2.jsonbrewing_stand_empty0.jsonbrewing_stand_empty1.jsonbrewing_stand_empty2.jsonbrick_slab.jsonbrick_slab_top.jsonbrick_stairs.jsonbrick_stairs_inner.jsonbrick_stairs_outer.jsonbrick_wall_inventory.jsonbrick_wall_post.jsonbrick_wall_side.jsonbrick_wall_side_tall.jsonbricks.jsonbrown_candle_cake.jsonbrown_candle_cake_lit.jsonbrown_candle_four_candles.jsonbrown_candle_four_candles_lit.jsonbrown_candle_one_candle.jsonbrown_candle_one_candle_lit.jsonbrown_candle_three_candles.jsonbrown_candle_three_candles_lit.jsonbrown_candle_two_candles.jsonbrown_candle_two_candles_lit.jsonbrown_carpet.jsonbrown_concrete.jsonbrown_concrete_powder.jsonbrown_glazed_terracotta.jsonbrown_mushroom.jsonbrown_mushroom_block.jsonbrown_mushroom_block_inventory.jsonbrown_shulker_box.jsonbrown_stained_glass.jsonbrown_stained_glass_pane_noside.jsonbrown_stained_glass_pane_noside_alt.jsonbrown_stained_glass_pane_post.jsonbrown_stained_glass_pane_side.jsonbrown_stained_glass_pane_side_alt.jsonbrown_terracotta.jsonbrown_wool.jsonbubble_coral.jsonbubble_coral_block.jsonbubble_coral_fan.jsonbubble_coral_wall_fan.jsonbudding_amethyst.jsonbutton.jsonbutton_inventory.jsonbutton_pressed.jsoncactus.jsoncake.jsoncake_slice1.jsoncake_slice2.jsoncake_slice3.jsoncake_slice4.jsoncake_slice5.jsoncake_slice6.jsoncalcite.jsoncalibrated_sculk_sensor.jsoncalibrated_sculk_sensor_active.jsoncalibrated_sculk_sensor_inactive.jsoncampfire.jsoncampfire_off.jsoncandle_cake.jsoncandle_cake_lit.jsoncandle_four_candles.jsoncandle_four_candles_lit.jsoncandle_one_candle.jsoncandle_one_candle_lit.jsoncandle_three_candles.jsoncandle_three_candles_lit.jsoncandle_two_candles.jsoncandle_two_candles_lit.jsoncarpet.jsoncarrots_stage0.jsoncarrots_stage1.jsoncarrots_stage2.jsoncarrots_stage3.jsoncartography_table.jsoncarved_pumpkin.jsoncauldron.jsoncave_vines.jsoncave_vines_lit.jsoncave_vines_plant.jsoncave_vines_plant_lit.jsonchain.jsonchain_command_block.jsonchain_command_block_conditional.jsoncherry_button.jsoncherry_button_inventory.jsoncherry_button_pressed.jsoncherry_door_bottom_left.jsoncherry_door_bottom_left_open.jsoncherry_door_bottom_right.jsoncherry_door_bottom_right_open.jsoncherry_door_top_left.jsoncherry_door_top_left_open.jsoncherry_door_top_right.jsoncherry_door_top_right_open.jsoncherry_fence_gate.jsoncherry_fence_gate_open.jsoncherry_fence_gate_wall.jsoncherry_fence_gate_wall_open.jsoncherry_fence_inventory.jsoncherry_fence_post.jsoncherry_fence_side.jsoncherry_hanging_sign.jsoncherry_leaves.jsoncherry_log.jsoncherry_log_x.jsoncherry_log_y.jsoncherry_log_z.jsoncherry_planks.jsoncherry_pressure_plate.jsoncherry_pressure_plate_down.jsoncherry_sapling.jsoncherry_sign.jsoncherry_slab.jsoncherry_slab_top.jsoncherry_stairs.jsoncherry_stairs_inner.jsoncherry_stairs_outer.jsoncherry_trapdoor_bottom.jsoncherry_trapdoor_open.jsoncherry_trapdoor_top.jsoncherry_wood.jsonchest.jsonchipped_anvil.jsonchiseled_bookshelf.jsonchiseled_bookshelf_empty_slot_bottom_left.jsonchiseled_bookshelf_empty_slot_bottom_mid.jsonchiseled_bookshelf_empty_slot_bottom_right.jsonchiseled_bookshelf_empty_slot_top_left.jsonchiseled_bookshelf_empty_slot_top_mid.jsonchiseled_bookshelf_empty_slot_top_right.jsonchiseled_bookshelf_inventory.jsonchiseled_bookshelf_occupied_slot_bottom_left.jsonchiseled_bookshelf_occupied_slot_bottom_mid.jsonchiseled_bookshelf_occupied_slot_bottom_right.jsonchiseled_bookshelf_occupied_slot_top_left.jsonchiseled_bookshelf_occupied_slot_top_mid.jsonchiseled_bookshelf_occupied_slot_top_right.jsonchiseled_copper.jsonchiseled_deepslate.jsonchiseled_nether_bricks.jsonchiseled_polished_blackstone.jsonchiseled_quartz_block.jsonchiseled_red_sandstone.jsonchiseled_resin_bricks.jsonchiseled_sandstone.jsonchiseled_stone_bricks.jsonchiseled_tuff.jsonchiseled_tuff_bricks.jsonchorus_flower.jsonchorus_flower_dead.jsonchorus_plant.jsonchorus_plant_noside.jsonchorus_plant_noside1.jsonchorus_plant_noside2.jsonchorus_plant_noside3.jsonchorus_plant_side.jsonclay.jsonclosed_eyeblossom.jsoncoal_block.jsoncoal_ore.jsoncoarse_dirt.jsoncobbled_deepslate.jsoncobbled_deepslate_slab.jsoncobbled_deepslate_slab_top.jsoncobbled_deepslate_stairs.jsoncobbled_deepslate_stairs_inner.jsoncobbled_deepslate_stairs_outer.jsoncobbled_deepslate_wall_inventory.jsoncobbled_deepslate_wall_post.jsoncobbled_deepslate_wall_side.jsoncobbled_deepslate_wall_side_tall.jsoncobblestone.jsoncobblestone_slab.jsoncobblestone_slab_top.jsoncobblestone_stairs.jsoncobblestone_stairs_inner.jsoncobblestone_stairs_outer.jsoncobblestone_wall_inventory.jsoncobblestone_wall_post.jsoncobblestone_wall_side.jsoncobblestone_wall_side_tall.jsoncobweb.jsoncocoa_stage0.jsoncocoa_stage1.jsoncocoa_stage2.jsoncommand_block.jsoncommand_block_conditional.jsoncomparator.jsoncomparator_on.jsoncomparator_on_subtract.jsoncomparator_subtract.jsoncomposter.jsoncomposter_contents1.jsoncomposter_contents2.jsoncomposter_contents3.jsoncomposter_contents4.jsoncomposter_contents5.jsoncomposter_contents6.jsoncomposter_contents7.jsoncomposter_contents_ready.jsonconduit.jsoncopper_block.jsoncopper_bulb.jsoncopper_bulb_lit.jsoncopper_bulb_lit_powered.jsoncopper_bulb_powered.jsoncopper_door_bottom_left.jsoncopper_door_bottom_left_open.jsoncopper_door_bottom_right.jsoncopper_door_bottom_right_open.jsoncopper_door_top_left.jsoncopper_door_top_left_open.jsoncopper_door_top_right.jsoncopper_door_top_right_open.jsoncopper_grate.jsoncopper_ore.jsoncopper_trapdoor_bottom.jsoncopper_trapdoor_open.jsoncopper_trapdoor_top.jsoncoral_fan.jsoncoral_wall_fan.jsoncornflower.jsoncracked_deepslate_bricks.jsoncracked_deepslate_tiles.jsoncracked_nether_bricks.jsoncracked_polished_blackstone_bricks.jsoncracked_stone_bricks.jsoncrafter.jsoncrafter_crafting.jsoncrafter_crafting_triggered.jsoncrafter_triggered.jsoncrafting_table.jsoncreaking_heart.jsoncreaking_heart_active.jsoncreaking_heart_active_horizontal.jsoncreaking_heart_horizontal.jsoncrimson_button.jsoncrimson_button_inventory.jsoncrimson_button_pressed.jsoncrimson_door_bottom_left.jsoncrimson_door_bottom_left_open.jsoncrimson_door_bottom_right.jsoncrimson_door_bottom_right_open.jsoncrimson_door_top_left.jsoncrimson_door_top_left_open.jsoncrimson_door_top_right.jsoncrimson_door_top_right_open.jsoncrimson_fence_gate.jsoncrimson_fence_gate_open.jsoncrimson_fence_gate_wall.jsoncrimson_fence_gate_wall_open.jsoncrimson_fence_inventory.jsoncrimson_fence_post.jsoncrimson_fence_side.jsoncrimson_fungus.jsoncrimson_hanging_sign.jsoncrimson_hyphae.jsoncrimson_nylium.jsoncrimson_planks.jsoncrimson_pressure_plate.jsoncrimson_pressure_plate_down.jsoncrimson_roots.jsoncrimson_sign.jsoncrimson_slab.jsoncrimson_slab_top.jsoncrimson_stairs.jsoncrimson_stairs_inner.jsoncrimson_stairs_outer.jsoncrimson_stem.jsoncrimson_trapdoor_bottom.jsoncrimson_trapdoor_open.jsoncrimson_trapdoor_top.jsoncrop.jsoncross.jsoncross_emissive.jsoncrying_obsidian.jsoncube.jsoncube_all.jsoncube_all_inner_faces.jsoncube_bottom_top.jsoncube_bottom_top_inner_faces.jsoncube_column.jsoncube_column_horizontal.jsoncube_column_mirrored.jsoncube_column_uv_locked_x.jsoncube_column_uv_locked_y.jsoncube_column_uv_locked_z.jsoncube_directional.jsoncube_mirrored.jsoncube_mirrored_all.jsoncube_north_west_mirrored.jsoncube_north_west_mirrored_all.jsoncube_top.jsoncustom_fence_inventory.jsoncustom_fence_post.jsoncustom_fence_side_east.jsoncustom_fence_side_north.jsoncustom_fence_side_south.jsoncustom_fence_side_west.jsoncut_copper.jsoncut_copper_slab.jsoncut_copper_slab_top.jsoncut_copper_stairs.jsoncut_copper_stairs_inner.jsoncut_copper_stairs_outer.jsoncut_red_sandstone.jsoncut_red_sandstone_slab.jsoncut_red_sandstone_slab_top.jsoncut_sandstone.jsoncut_sandstone_slab.jsoncut_sandstone_slab_top.jsoncyan_candle_cake.jsoncyan_candle_cake_lit.jsoncyan_candle_four_candles.jsoncyan_candle_four_candles_lit.jsoncyan_candle_one_candle.jsoncyan_candle_one_candle_lit.jsoncyan_candle_three_candles.jsoncyan_candle_three_candles_lit.jsoncyan_candle_two_candles.jsoncyan_candle_two_candles_lit.jsoncyan_carpet.jsoncyan_concrete.jsoncyan_concrete_powder.jsoncyan_glazed_terracotta.jsoncyan_shulker_box.jsoncyan_stained_glass.jsoncyan_stained_glass_pane_noside.jsoncyan_stained_glass_pane_noside_alt.jsoncyan_stained_glass_pane_post.jsoncyan_stained_glass_pane_side.jsoncyan_stained_glass_pane_side_alt.jsoncyan_terracotta.jsoncyan_wool.jsondamaged_anvil.jsondandelion.jsondark_oak_button.jsondark_oak_button_inventory.jsondark_oak_button_pressed.jsondark_oak_door_bottom_left.jsondark_oak_door_bottom_left_open.jsondark_oak_door_bottom_right.jsondark_oak_door_bottom_right_open.jsondark_oak_door_top_left.jsondark_oak_door_top_left_open.jsondark_oak_door_top_right.jsondark_oak_door_top_right_open.jsondark_oak_fence_gate.jsondark_oak_fence_gate_open.jsondark_oak_fence_gate_wall.jsondark_oak_fence_gate_wall_open.jsondark_oak_fence_inventory.jsondark_oak_fence_post.jsondark_oak_fence_side.jsondark_oak_hanging_sign.jsondark_oak_leaves.jsondark_oak_log.jsondark_oak_log_horizontal.jsondark_oak_planks.jsondark_oak_pressure_plate.jsondark_oak_pressure_plate_down.jsondark_oak_sapling.jsondark_oak_sign.jsondark_oak_slab.jsondark_oak_slab_top.jsondark_oak_stairs.jsondark_oak_stairs_inner.jsondark_oak_stairs_outer.jsondark_oak_trapdoor_bottom.jsondark_oak_trapdoor_open.jsondark_oak_trapdoor_top.jsondark_oak_wood.jsondark_prismarine.jsondark_prismarine_slab.jsondark_prismarine_slab_top.jsondark_prismarine_stairs.jsondark_prismarine_stairs_inner.jsondark_prismarine_stairs_outer.jsondaylight_detector.jsondaylight_detector_inverted.jsondead_brain_coral.jsondead_brain_coral_block.jsondead_brain_coral_fan.jsondead_brain_coral_wall_fan.jsondead_bubble_coral.jsondead_bubble_coral_block.jsondead_bubble_coral_fan.jsondead_bubble_coral_wall_fan.jsondead_bush.jsondead_fire_coral.jsondead_fire_coral_block.jsondead_fire_coral_fan.jsondead_fire_coral_wall_fan.jsondead_horn_coral.jsondead_horn_coral_block.jsondead_horn_coral_fan.jsondead_horn_coral_wall_fan.jsondead_sea_pickle.jsondead_tube_coral.jsondead_tube_coral_block.jsondead_tube_coral_fan.jsondead_tube_coral_wall_fan.jsondecorated_pot.jsondeepslate.jsondeepslate_brick_slab.jsondeepslate_brick_slab_top.jsondeepslate_brick_stairs.jsondeepslate_brick_stairs_inner.jsondeepslate_brick_stairs_outer.jsondeepslate_brick_wall_inventory.jsondeepslate_brick_wall_post.jsondeepslate_brick_wall_side.jsondeepslate_brick_wall_side_tall.jsondeepslate_bricks.jsondeepslate_coal_ore.jsondeepslate_copper_ore.jsondeepslate_diamond_ore.jsondeepslate_emerald_ore.jsondeepslate_gold_ore.jsondeepslate_iron_ore.jsondeepslate_lapis_ore.jsondeepslate_mirrored.jsondeepslate_redstone_ore.jsondeepslate_tile_slab.jsondeepslate_tile_slab_top.jsondeepslate_tile_stairs.jsondeepslate_tile_stairs_inner.jsondeepslate_tile_stairs_outer.jsondeepslate_tile_wall_inventory.jsondeepslate_tile_wall_post.jsondeepslate_tile_wall_side.jsondeepslate_tile_wall_side_tall.jsondeepslate_tiles.jsondetector_rail.jsondetector_rail_on.jsondetector_rail_on_raised_ne.jsondetector_rail_on_raised_sw.jsondetector_rail_raised_ne.jsondetector_rail_raised_sw.jsondiamond_block.jsondiamond_ore.jsondiorite.jsondiorite_slab.jsondiorite_slab_top.jsondiorite_stairs.jsondiorite_stairs_inner.jsondiorite_stairs_outer.jsondiorite_wall_inventory.jsondiorite_wall_post.jsondiorite_wall_side.jsondiorite_wall_side_tall.jsondirt.jsondirt_path.jsondispenser.jsondispenser_vertical.jsondoor_bottom_left.jsondoor_bottom_left_open.jsondoor_bottom_right.jsondoor_bottom_right_open.jsondoor_top_left.jsondoor_top_left_open.jsondoor_top_right.jsondoor_top_right_open.jsondragon_egg.jsondried_kelp_block.jsondripstone_block.jsondropper.jsondropper_vertical.jsonemerald_block.jsonemerald_ore.jsonenchanting_table.jsonend_gateway.jsonend_portal.jsonend_portal_frame.jsonend_portal_frame_filled.jsonend_rod.jsonend_stone.jsonend_stone_brick_slab.jsonend_stone_brick_slab_top.jsonend_stone_brick_stairs.jsonend_stone_brick_stairs_inner.jsonend_stone_brick_stairs_outer.jsonend_stone_brick_wall_inventory.jsonend_stone_brick_wall_post.jsonend_stone_brick_wall_side.jsonend_stone_brick_wall_side_tall.jsonend_stone_bricks.jsonender_chest.jsonexposed_chiseled_copper.jsonexposed_copper.jsonexposed_copper_bulb.jsonexposed_copper_bulb_lit.jsonexposed_copper_bulb_lit_powered.jsonexposed_copper_bulb_powered.jsonexposed_copper_door_bottom_left.jsonexposed_copper_door_bottom_left_open.jsonexposed_copper_door_bottom_right.jsonexposed_copper_door_bottom_right_open.jsonexposed_copper_door_top_left.jsonexposed_copper_door_top_left_open.jsonexposed_copper_door_top_right.jsonexposed_copper_door_top_right_open.jsonexposed_copper_grate.jsonexposed_copper_trapdoor_bottom.jsonexposed_copper_trapdoor_open.jsonexposed_copper_trapdoor_top.jsonexposed_cut_copper.jsonexposed_cut_copper_slab.jsonexposed_cut_copper_slab_top.jsonexposed_cut_copper_stairs.jsonexposed_cut_copper_stairs_inner.jsonexposed_cut_copper_stairs_outer.jsonfarmland.jsonfarmland_moist.jsonfence_inventory.jsonfence_post.jsonfence_side.jsonfern.jsonfire_coral.jsonfire_coral_block.jsonfire_coral_fan.jsonfire_coral_wall_fan.jsonfire_floor0.jsonfire_floor1.jsonfire_side0.jsonfire_side1.jsonfire_side_alt0.jsonfire_side_alt1.jsonfire_up0.jsonfire_up1.jsonfire_up_alt0.jsonfire_up_alt1.jsonfletching_table.jsonflower_pot.jsonflower_pot_cross.jsonflower_pot_cross_emissive.jsonflowerbed_1.jsonflowerbed_2.jsonflowerbed_3.jsonflowerbed_4.jsonflowering_azalea.jsonflowering_azalea_leaves.jsonfour_dead_sea_pickles.jsonfour_sea_pickles.jsonfour_slightly_cracked_turtle_eggs.jsonfour_turtle_eggs.jsonfour_very_cracked_turtle_eggs.jsonfrogspawn.jsonfrosted_ice_0.jsonfrosted_ice_1.jsonfrosted_ice_2.jsonfrosted_ice_3.jsonfurnace.jsonfurnace_on.jsongilded_blackstone.jsonglass.jsonglass_pane_noside.jsonglass_pane_noside_alt.jsonglass_pane_post.jsonglass_pane_side.jsonglass_pane_side_alt.jsonglow_item_frame.jsonglow_item_frame_map.jsonglow_lichen.jsonglowstone.jsongold_block.jsongold_ore.jsongranite.jsongranite_slab.jsongranite_slab_top.jsongranite_stairs.jsongranite_stairs_inner.jsongranite_stairs_outer.jsongranite_wall_inventory.jsongranite_wall_post.jsongranite_wall_side.jsongranite_wall_side_tall.jsongrass_block.jsongrass_block_snow.jsongravel.jsongray_candle_cake.jsongray_candle_cake_lit.jsongray_candle_four_candles.jsongray_candle_four_candles_lit.jsongray_candle_one_candle.jsongray_candle_one_candle_lit.jsongray_candle_three_candles.jsongray_candle_three_candles_lit.jsongray_candle_two_candles.jsongray_candle_two_candles_lit.jsongray_carpet.jsongray_concrete.jsongray_concrete_powder.jsongray_glazed_terracotta.jsongray_shulker_box.jsongray_stained_glass.jsongray_stained_glass_pane_noside.jsongray_stained_glass_pane_noside_alt.jsongray_stained_glass_pane_post.jsongray_stained_glass_pane_side.jsongray_stained_glass_pane_side_alt.jsongray_terracotta.jsongray_wool.jsongreen_candle_cake.jsongreen_candle_cake_lit.jsongreen_candle_four_candles.jsongreen_candle_four_candles_lit.jsongreen_candle_one_candle.jsongreen_candle_one_candle_lit.jsongreen_candle_three_candles.jsongreen_candle_three_candles_lit.jsongreen_candle_two_candles.jsongreen_candle_two_candles_lit.jsongreen_carpet.jsongreen_concrete.jsongreen_concrete_powder.jsongreen_glazed_terracotta.jsongreen_shulker_box.jsongreen_stained_glass.jsongreen_stained_glass_pane_noside.jsongreen_stained_glass_pane_noside_alt.jsongreen_stained_glass_pane_post.jsongreen_stained_glass_pane_side.jsongreen_stained_glass_pane_side_alt.jsongreen_terracotta.jsongreen_wool.jsongrindstone.jsonhanging_roots.jsonhay_block.jsonhay_block_horizontal.jsonheavy_core.jsonheavy_weighted_pressure_plate.jsonheavy_weighted_pressure_plate_down.jsonhoney_block.jsonhoneycomb_block.jsonhopper.jsonhopper_side.jsonhorn_coral.jsonhorn_coral_block.jsonhorn_coral_fan.jsonhorn_coral_wall_fan.jsonice.jsoninner_stairs.jsoniron_bars_cap.jsoniron_bars_cap_alt.jsoniron_bars_post.jsoniron_bars_post_ends.jsoniron_bars_side.jsoniron_bars_side_alt.jsoniron_block.jsoniron_door_bottom_left.jsoniron_door_bottom_left_open.jsoniron_door_bottom_right.jsoniron_door_bottom_right_open.jsoniron_door_top_left.jsoniron_door_top_left_open.jsoniron_door_top_right.jsoniron_door_top_right_open.jsoniron_ore.jsoniron_trapdoor_bottom.jsoniron_trapdoor_open.jsoniron_trapdoor_top.jsonitem_frame.jsonitem_frame_map.jsonjack_o_lantern.jsonjigsaw.jsonjukebox.jsonjungle_button.jsonjungle_button_inventory.jsonjungle_button_pressed.jsonjungle_door_bottom_left.jsonjungle_door_bottom_left_open.jsonjungle_door_bottom_right.jsonjungle_door_bottom_right_open.jsonjungle_door_top_left.jsonjungle_door_top_left_open.jsonjungle_door_top_right.jsonjungle_door_top_right_open.jsonjungle_fence_gate.jsonjungle_fence_gate_open.jsonjungle_fence_gate_wall.jsonjungle_fence_gate_wall_open.jsonjungle_fence_inventory.jsonjungle_fence_post.jsonjungle_fence_side.jsonjungle_hanging_sign.jsonjungle_leaves.jsonjungle_log.jsonjungle_log_horizontal.jsonjungle_planks.jsonjungle_pressure_plate.jsonjungle_pressure_plate_down.jsonjungle_sapling.jsonjungle_sign.jsonjungle_slab.jsonjungle_slab_top.jsonjungle_stairs.jsonjungle_stairs_inner.jsonjungle_stairs_outer.jsonjungle_trapdoor_bottom.jsonjungle_trapdoor_open.jsonjungle_trapdoor_top.jsonjungle_wood.jsonkelp.jsonkelp_plant.jsonladder.jsonlantern.jsonlantern_hanging.jsonlapis_block.jsonlapis_ore.jsonlarge_amethyst_bud.jsonlarge_fern_bottom.jsonlarge_fern_top.jsonlava.jsonlava_cauldron.jsonleaves.jsonlectern.jsonlever.jsonlever_on.jsonlight_00.jsonlight_01.jsonlight_02.jsonlight_03.jsonlight_04.jsonlight_05.jsonlight_06.jsonlight_07.jsonlight_08.jsonlight_09.jsonlight_10.jsonlight_11.jsonlight_12.jsonlight_13.jsonlight_14.jsonlight_15.jsonlight_blue_candle_cake.jsonlight_blue_candle_cake_lit.jsonlight_blue_candle_four_candles.jsonlight_blue_candle_four_candles_lit.jsonlight_blue_candle_one_candle.jsonlight_blue_candle_one_candle_lit.jsonlight_blue_candle_three_candles.jsonlight_blue_candle_three_candles_lit.jsonlight_blue_candle_two_candles.jsonlight_blue_candle_two_candles_lit.jsonlight_blue_carpet.jsonlight_blue_concrete.jsonlight_blue_concrete_powder.jsonlight_blue_glazed_terracotta.jsonlight_blue_shulker_box.jsonlight_blue_stained_glass.jsonlight_blue_stained_glass_pane_noside.jsonlight_blue_stained_glass_pane_noside_alt.jsonlight_blue_stained_glass_pane_post.jsonlight_blue_stained_glass_pane_side.jsonlight_blue_stained_glass_pane_side_alt.jsonlight_blue_terracotta.jsonlight_blue_wool.jsonlight_gray_candle_cake.jsonlight_gray_candle_cake_lit.jsonlight_gray_candle_four_candles.jsonlight_gray_candle_four_candles_lit.jsonlight_gray_candle_one_candle.jsonlight_gray_candle_one_candle_lit.jsonlight_gray_candle_three_candles.jsonlight_gray_candle_three_candles_lit.jsonlight_gray_candle_two_candles.jsonlight_gray_candle_two_candles_lit.jsonlight_gray_carpet.jsonlight_gray_concrete.jsonlight_gray_concrete_powder.jsonlight_gray_glazed_terracotta.jsonlight_gray_shulker_box.jsonlight_gray_stained_glass.jsonlight_gray_stained_glass_pane_noside.jsonlight_gray_stained_glass_pane_noside_alt.jsonlight_gray_stained_glass_pane_post.jsonlight_gray_stained_glass_pane_side.jsonlight_gray_stained_glass_pane_side_alt.jsonlight_gray_terracotta.jsonlight_gray_wool.jsonlight_weighted_pressure_plate.jsonlight_weighted_pressure_plate_down.jsonlightning_rod.jsonlightning_rod_on.jsonlilac_bottom.jsonlilac_top.jsonlily_of_the_valley.jsonlily_pad.jsonlime_candle_cake.jsonlime_candle_cake_lit.jsonlime_candle_four_candles.jsonlime_candle_four_candles_lit.jsonlime_candle_one_candle.jsonlime_candle_one_candle_lit.jsonlime_candle_three_candles.jsonlime_candle_three_candles_lit.jsonlime_candle_two_candles.jsonlime_candle_two_candles_lit.jsonlime_carpet.jsonlime_concrete.jsonlime_concrete_powder.jsonlime_glazed_terracotta.jsonlime_shulker_box.jsonlime_stained_glass.jsonlime_stained_glass_pane_noside.jsonlime_stained_glass_pane_noside_alt.jsonlime_stained_glass_pane_post.jsonlime_stained_glass_pane_side.jsonlime_stained_glass_pane_side_alt.jsonlime_terracotta.jsonlime_wool.jsonlodestone.jsonloom.jsonmagenta_candle_cake.jsonmagenta_candle_cake_lit.jsonmagenta_candle_four_candles.jsonmagenta_candle_four_candles_lit.jsonmagenta_candle_one_candle.jsonmagenta_candle_one_candle_lit.jsonmagenta_candle_three_candles.jsonmagenta_candle_three_candles_lit.jsonmagenta_candle_two_candles.jsonmagenta_candle_two_candles_lit.jsonmagenta_carpet.jsonmagenta_concrete.jsonmagenta_concrete_powder.jsonmagenta_glazed_terracotta.jsonmagenta_shulker_box.jsonmagenta_stained_glass.jsonmagenta_stained_glass_pane_noside.jsonmagenta_stained_glass_pane_noside_alt.jsonmagenta_stained_glass_pane_post.jsonmagenta_stained_glass_pane_side.jsonmagenta_stained_glass_pane_side_alt.jsonmagenta_terracotta.jsonmagenta_wool.jsonmagma_block.jsonmangrove_button.jsonmangrove_button_inventory.jsonmangrove_button_pressed.jsonmangrove_door_bottom_left.jsonmangrove_door_bottom_left_open.jsonmangrove_door_bottom_right.jsonmangrove_door_bottom_right_open.jsonmangrove_door_top_left.jsonmangrove_door_top_left_open.jsonmangrove_door_top_right.jsonmangrove_door_top_right_open.jsonmangrove_fence_gate.jsonmangrove_fence_gate_open.jsonmangrove_fence_gate_wall.jsonmangrove_fence_gate_wall_open.jsonmangrove_fence_inventory.jsonmangrove_fence_post.jsonmangrove_fence_side.jsonmangrove_hanging_sign.jsonmangrove_leaves.jsonmangrove_log.jsonmangrove_log_horizontal.jsonmangrove_planks.jsonmangrove_pressure_plate.jsonmangrove_pressure_plate_down.jsonmangrove_propagule.jsonmangrove_propagule_hanging_0.jsonmangrove_propagule_hanging_1.jsonmangrove_propagule_hanging_2.jsonmangrove_propagule_hanging_3.jsonmangrove_propagule_hanging_4.jsonmangrove_roots.jsonmangrove_sign.jsonmangrove_slab.jsonmangrove_slab_top.jsonmangrove_stairs.jsonmangrove_stairs_inner.jsonmangrove_stairs_outer.jsonmangrove_trapdoor_bottom.jsonmangrove_trapdoor_open.jsonmangrove_trapdoor_top.jsonmangrove_wood.jsonmedium_amethyst_bud.jsonmelon.jsonmelon_stem_stage0.jsonmelon_stem_stage1.jsonmelon_stem_stage2.jsonmelon_stem_stage3.jsonmelon_stem_stage4.jsonmelon_stem_stage5.jsonmelon_stem_stage6.jsonmelon_stem_stage7.jsonmoss_block.jsonmoss_carpet.jsonmossy_carpet_side.jsonmossy_cobblestone.jsonmossy_cobblestone_slab.jsonmossy_cobblestone_slab_top.jsonmossy_cobblestone_stairs.jsonmossy_cobblestone_stairs_inner.jsonmossy_cobblestone_stairs_outer.jsonmossy_cobblestone_wall_inventory.jsonmossy_cobblestone_wall_post.jsonmossy_cobblestone_wall_side.jsonmossy_cobblestone_wall_side_tall.jsonmossy_stone_brick_slab.jsonmossy_stone_brick_slab_top.jsonmossy_stone_brick_stairs.jsonmossy_stone_brick_stairs_inner.jsonmossy_stone_brick_stairs_outer.jsonmossy_stone_brick_wall_inventory.jsonmossy_stone_brick_wall_post.jsonmossy_stone_brick_wall_side.jsonmossy_stone_brick_wall_side_tall.jsonmossy_stone_bricks.jsonmoving_piston.jsonmud.jsonmud_brick_slab.jsonmud_brick_slab_top.jsonmud_brick_stairs.jsonmud_brick_stairs_inner.jsonmud_brick_stairs_outer.jsonmud_brick_wall_inventory.jsonmud_brick_wall_post.jsonmud_brick_wall_side.jsonmud_brick_wall_side_tall.jsonmud_bricks.jsonmud_bricks_north_west_mirrored.jsonmuddy_mangrove_roots.jsonmushroom_block_inside.jsonmushroom_stem.jsonmushroom_stem_inventory.jsonmycelium.jsonnether_brick_fence_inventory.jsonnether_brick_fence_post.jsonnether_brick_fence_side.jsonnether_brick_slab.jsonnether_brick_slab_top.jsonnether_brick_stairs.jsonnether_brick_stairs_inner.jsonnether_brick_stairs_outer.jsonnether_brick_wall_inventory.jsonnether_brick_wall_post.jsonnether_brick_wall_side.jsonnether_brick_wall_side_tall.jsonnether_bricks.jsonnether_gold_ore.jsonnether_portal_ew.jsonnether_portal_ns.jsonnether_quartz_ore.jsonnether_sprouts.jsonnether_wart_block.jsonnether_wart_stage0.jsonnether_wart_stage1.jsonnether_wart_stage2.jsonnetherite_block.jsonnetherrack.jsonnote_block.jsonoak_button.jsonoak_button_inventory.jsonoak_button_pressed.jsonoak_door_bottom_left.jsonoak_door_bottom_left_open.jsonoak_door_bottom_right.jsonoak_door_bottom_right_open.jsonoak_door_top_left.jsonoak_door_top_left_open.jsonoak_door_top_right.jsonoak_door_top_right_open.jsonoak_fence_gate.jsonoak_fence_gate_open.jsonoak_fence_gate_wall.jsonoak_fence_gate_wall_open.jsonoak_fence_inventory.jsonoak_fence_post.jsonoak_fence_side.jsonoak_hanging_sign.jsonoak_leaves.jsonoak_log.jsonoak_log_horizontal.jsonoak_planks.jsonoak_pressure_plate.jsonoak_pressure_plate_down.jsonoak_sapling.jsonoak_sign.jsonoak_slab.jsonoak_slab_top.jsonoak_stairs.jsonoak_stairs_inner.jsonoak_stairs_outer.jsonoak_trapdoor_bottom.jsonoak_trapdoor_open.jsonoak_trapdoor_top.jsonoak_wood.jsonobserver.jsonobserver_on.jsonobsidian.jsonochre_froglight.jsonochre_froglight_horizontal.jsonopen_eyeblossom.jsonorange_candle_cake.jsonorange_candle_cake_lit.jsonorange_candle_four_candles.jsonorange_candle_four_candles_lit.jsonorange_candle_one_candle.jsonorange_candle_one_candle_lit.jsonorange_candle_three_candles.jsonorange_candle_three_candles_lit.jsonorange_candle_two_candles.jsonorange_candle_two_candles_lit.jsonorange_carpet.jsonorange_concrete.jsonorange_concrete_powder.jsonorange_glazed_terracotta.jsonorange_shulker_box.jsonorange_stained_glass.jsonorange_stained_glass_pane_noside.jsonorange_stained_glass_pane_noside_alt.jsonorange_stained_glass_pane_post.jsonorange_stained_glass_pane_side.jsonorange_stained_glass_pane_side_alt.jsonorange_terracotta.jsonorange_tulip.jsonorange_wool.jsonorientable.jsonorientable_vertical.jsonorientable_with_bottom.jsonouter_stairs.jsonoxeye_daisy.jsonoxidized_chiseled_copper.jsonoxidized_copper.jsonoxidized_copper_bulb.jsonoxidized_copper_bulb_lit.jsonoxidized_copper_bulb_lit_powered.jsonoxidized_copper_bulb_powered.jsonoxidized_copper_door_bottom_left.jsonoxidized_copper_door_bottom_left_open.jsonoxidized_copper_door_bottom_right.jsonoxidized_copper_door_bottom_right_open.jsonoxidized_copper_door_top_left.jsonoxidized_copper_door_top_left_open.jsonoxidized_copper_door_top_right.jsonoxidized_copper_door_top_right_open.jsonoxidized_copper_grate.jsonoxidized_copper_trapdoor_bottom.jsonoxidized_copper_trapdoor_open.jsonoxidized_copper_trapdoor_top.jsonoxidized_cut_copper.jsonoxidized_cut_copper_slab.jsonoxidized_cut_copper_slab_top.jsonoxidized_cut_copper_stairs.jsonoxidized_cut_copper_stairs_inner.jsonoxidized_cut_copper_stairs_outer.jsonpacked_ice.jsonpacked_mud.jsonpale_hanging_moss.jsonpale_hanging_moss_tip.jsonpale_moss_block.jsonpale_moss_carpet.jsonpale_moss_carpet_side_small.jsonpale_moss_carpet_side_tall.jsonpale_oak_button.jsonpale_oak_button_inventory.jsonpale_oak_button_pressed.jsonpale_oak_door_bottom_left.jsonpale_oak_door_bottom_left_open.jsonpale_oak_door_bottom_right.jsonpale_oak_door_bottom_right_open.jsonpale_oak_door_top_left.jsonpale_oak_door_top_left_open.jsonpale_oak_door_top_right.jsonpale_oak_door_top_right_open.jsonpale_oak_fence_gate.jsonpale_oak_fence_gate_open.jsonpale_oak_fence_gate_wall.jsonpale_oak_fence_gate_wall_open.jsonpale_oak_fence_inventory.jsonpale_oak_fence_post.jsonpale_oak_fence_side.jsonpale_oak_hanging_sign.jsonpale_oak_leaves.jsonpale_oak_log.jsonpale_oak_log_horizontal.jsonpale_oak_planks.jsonpale_oak_pressure_plate.jsonpale_oak_pressure_plate_down.jsonpale_oak_sapling.jsonpale_oak_sign.jsonpale_oak_slab.jsonpale_oak_slab_top.jsonpale_oak_stairs.jsonpale_oak_stairs_inner.jsonpale_oak_stairs_outer.jsonpale_oak_trapdoor_bottom.jsonpale_oak_trapdoor_open.jsonpale_oak_trapdoor_top.jsonpale_oak_wood.jsonpearlescent_froglight.jsonpearlescent_froglight_horizontal.jsonpeony_bottom.jsonpeony_top.jsonpetrified_oak_slab.jsonpetrified_oak_slab_top.jsonpink_candle_cake.jsonpink_candle_cake_lit.jsonpink_candle_four_candles.jsonpink_candle_four_candles_lit.jsonpink_candle_one_candle.jsonpink_candle_one_candle_lit.jsonpink_candle_three_candles.jsonpink_candle_three_candles_lit.jsonpink_candle_two_candles.jsonpink_candle_two_candles_lit.jsonpink_carpet.jsonpink_concrete.jsonpink_concrete_powder.jsonpink_glazed_terracotta.jsonpink_petals_1.jsonpink_petals_2.jsonpink_petals_3.jsonpink_petals_4.jsonpink_shulker_box.jsonpink_stained_glass.jsonpink_stained_glass_pane_noside.jsonpink_stained_glass_pane_noside_alt.jsonpink_stained_glass_pane_post.jsonpink_stained_glass_pane_side.jsonpink_stained_glass_pane_side_alt.jsonpink_terracotta.jsonpink_tulip.jsonpink_wool.jsonpiston.jsonpiston_base.jsonpiston_extended.jsonpiston_head.jsonpiston_head_short.jsonpiston_head_short_sticky.jsonpiston_head_sticky.jsonpiston_inventory.jsonpitcher_crop_bottom_stage_0.jsonpitcher_crop_bottom_stage_1.jsonpitcher_crop_bottom_stage_2.jsonpitcher_crop_bottom_stage_3.jsonpitcher_crop_bottom_stage_4.jsonpitcher_crop_top_stage_0.jsonpitcher_crop_top_stage_1.jsonpitcher_crop_top_stage_2.jsonpitcher_crop_top_stage_3.jsonpitcher_crop_top_stage_4.jsonpitcher_plant_bottom.jsonpitcher_plant_top.jsonpodzol.jsonpointed_dripstone.jsonpointed_dripstone_down_base.jsonpointed_dripstone_down_frustum.jsonpointed_dripstone_down_middle.jsonpointed_dripstone_down_tip.jsonpointed_dripstone_down_tip_merge.jsonpointed_dripstone_up_base.jsonpointed_dripstone_up_frustum.jsonpointed_dripstone_up_middle.jsonpointed_dripstone_up_tip.jsonpointed_dripstone_up_tip_merge.jsonpolished_andesite.jsonpolished_andesite_slab.jsonpolished_andesite_slab_top.jsonpolished_andesite_stairs.jsonpolished_andesite_stairs_inner.jsonpolished_andesite_stairs_outer.jsonpolished_basalt.jsonpolished_blackstone.jsonpolished_blackstone_brick_slab.jsonpolished_blackstone_brick_slab_top.jsonpolished_blackstone_brick_stairs.jsonpolished_blackstone_brick_stairs_inner.jsonpolished_blackstone_brick_stairs_outer.jsonpolished_blackstone_brick_wall_inventory.jsonpolished_blackstone_brick_wall_post.jsonpolished_blackstone_brick_wall_side.jsonpolished_blackstone_brick_wall_side_tall.jsonpolished_blackstone_bricks.jsonpolished_blackstone_button.jsonpolished_blackstone_button_inventory.jsonpolished_blackstone_button_pressed.jsonpolished_blackstone_pressure_plate.jsonpolished_blackstone_pressure_plate_down.jsonpolished_blackstone_slab.jsonpolished_blackstone_slab_top.jsonpolished_blackstone_stairs.jsonpolished_blackstone_stairs_inner.jsonpolished_blackstone_stairs_outer.jsonpolished_blackstone_wall_inventory.jsonpolished_blackstone_wall_post.jsonpolished_blackstone_wall_side.jsonpolished_blackstone_wall_side_tall.jsonpolished_deepslate.jsonpolished_deepslate_slab.jsonpolished_deepslate_slab_top.jsonpolished_deepslate_stairs.jsonpolished_deepslate_stairs_inner.jsonpolished_deepslate_stairs_outer.jsonpolished_deepslate_wall_inventory.jsonpolished_deepslate_wall_post.jsonpolished_deepslate_wall_side.jsonpolished_deepslate_wall_side_tall.jsonpolished_diorite.jsonpolished_diorite_slab.jsonpolished_diorite_slab_top.jsonpolished_diorite_stairs.jsonpolished_diorite_stairs_inner.jsonpolished_diorite_stairs_outer.jsonpolished_granite.jsonpolished_granite_slab.jsonpolished_granite_slab_top.jsonpolished_granite_stairs.jsonpolished_granite_stairs_inner.jsonpolished_granite_stairs_outer.jsonpolished_tuff.jsonpolished_tuff_slab.jsonpolished_tuff_slab_top.jsonpolished_tuff_stairs.jsonpolished_tuff_stairs_inner.jsonpolished_tuff_stairs_outer.jsonpolished_tuff_wall_inventory.jsonpolished_tuff_wall_post.jsonpolished_tuff_wall_side.jsonpolished_tuff_wall_side_tall.jsonpoppy.jsonpotatoes_stage0.jsonpotatoes_stage1.jsonpotatoes_stage2.jsonpotatoes_stage3.jsonpotted_acacia_sapling.jsonpotted_allium.jsonpotted_azalea_bush.jsonpotted_azure_bluet.jsonpotted_bamboo.jsonpotted_birch_sapling.jsonpotted_blue_orchid.jsonpotted_brown_mushroom.jsonpotted_cactus.jsonpotted_cherry_sapling.jsonpotted_closed_eyeblossom.jsonpotted_cornflower.jsonpotted_crimson_fungus.jsonpotted_crimson_roots.jsonpotted_dandelion.jsonpotted_dark_oak_sapling.jsonpotted_dead_bush.jsonpotted_fern.jsonpotted_flowering_azalea_bush.jsonpotted_jungle_sapling.jsonpotted_lily_of_the_valley.jsonpotted_mangrove_propagule.jsonpotted_oak_sapling.jsonpotted_open_eyeblossom.jsonpotted_orange_tulip.jsonpotted_oxeye_daisy.jsonpotted_pale_oak_sapling.jsonpotted_pink_tulip.jsonpotted_poppy.jsonpotted_red_mushroom.jsonpotted_red_tulip.jsonpotted_spruce_sapling.jsonpotted_torchflower.jsonpotted_warped_fungus.jsonpotted_warped_roots.jsonpotted_white_tulip.jsonpotted_wither_rose.jsonpowder_snow.jsonpowder_snow_cauldron_full.jsonpowder_snow_cauldron_level1.jsonpowder_snow_cauldron_level2.jsonpowered_rail.jsonpowered_rail_on.jsonpowered_rail_on_raised_ne.jsonpowered_rail_on_raised_sw.jsonpowered_rail_raised_ne.jsonpowered_rail_raised_sw.jsonpressure_plate_down.jsonpressure_plate_up.jsonprismarine.jsonprismarine_brick_slab.jsonprismarine_brick_slab_top.jsonprismarine_brick_stairs.jsonprismarine_brick_stairs_inner.jsonprismarine_brick_stairs_outer.jsonprismarine_bricks.jsonprismarine_slab.jsonprismarine_slab_top.jsonprismarine_stairs.jsonprismarine_stairs_inner.jsonprismarine_stairs_outer.jsonprismarine_wall_inventory.jsonprismarine_wall_post.jsonprismarine_wall_side.jsonprismarine_wall_side_tall.jsonpumpkin.jsonpumpkin_stem_stage0.jsonpumpkin_stem_stage1.jsonpumpkin_stem_stage2.jsonpumpkin_stem_stage3.jsonpumpkin_stem_stage4.jsonpumpkin_stem_stage5.jsonpumpkin_stem_stage6.jsonpumpkin_stem_stage7.jsonpurple_candle_cake.jsonpurple_candle_cake_lit.jsonpurple_candle_four_candles.jsonpurple_candle_four_candles_lit.jsonpurple_candle_one_candle.jsonpurple_candle_one_candle_lit.jsonpurple_candle_three_candles.jsonpurple_candle_three_candles_lit.jsonpurple_candle_two_candles.jsonpurple_candle_two_candles_lit.jsonpurple_carpet.jsonpurple_concrete.jsonpurple_concrete_powder.jsonpurple_glazed_terracotta.jsonpurple_shulker_box.jsonpurple_stained_glass.jsonpurple_stained_glass_pane_noside.jsonpurple_stained_glass_pane_noside_alt.jsonpurple_stained_glass_pane_post.jsonpurple_stained_glass_pane_side.jsonpurple_stained_glass_pane_side_alt.jsonpurple_terracotta.jsonpurple_wool.jsonpurpur_block.jsonpurpur_pillar.jsonpurpur_pillar_horizontal.jsonpurpur_slab.jsonpurpur_slab_top.jsonpurpur_stairs.jsonpurpur_stairs_inner.jsonpurpur_stairs_outer.jsonquartz_block.jsonquartz_bricks.jsonquartz_pillar.jsonquartz_pillar_horizontal.jsonquartz_slab.jsonquartz_slab_top.jsonquartz_stairs.jsonquartz_stairs_inner.jsonquartz_stairs_outer.jsonrail.jsonrail_corner.jsonrail_curved.jsonrail_flat.jsonrail_raised_ne.jsonrail_raised_sw.jsonraw_copper_block.jsonraw_gold_block.jsonraw_iron_block.jsonred_candle_cake.jsonred_candle_cake_lit.jsonred_candle_four_candles.jsonred_candle_four_candles_lit.jsonred_candle_one_candle.jsonred_candle_one_candle_lit.jsonred_candle_three_candles.jsonred_candle_three_candles_lit.jsonred_candle_two_candles.jsonred_candle_two_candles_lit.jsonred_carpet.jsonred_concrete.jsonred_concrete_powder.jsonred_glazed_terracotta.jsonred_mushroom.jsonred_mushroom_block.jsonred_mushroom_block_inventory.jsonred_nether_brick_slab.jsonred_nether_brick_slab_top.jsonred_nether_brick_stairs.jsonred_nether_brick_stairs_inner.jsonred_nether_brick_stairs_outer.jsonred_nether_brick_wall_inventory.jsonred_nether_brick_wall_post.jsonred_nether_brick_wall_side.jsonred_nether_brick_wall_side_tall.jsonred_nether_bricks.jsonred_sand.jsonred_sandstone.jsonred_sandstone_slab.jsonred_sandstone_slab_top.jsonred_sandstone_stairs.jsonred_sandstone_stairs_inner.jsonred_sandstone_stairs_outer.jsonred_sandstone_wall_inventory.jsonred_sandstone_wall_post.jsonred_sandstone_wall_side.jsonred_sandstone_wall_side_tall.jsonred_shulker_box.jsonred_stained_glass.jsonred_stained_glass_pane_noside.jsonred_stained_glass_pane_noside_alt.jsonred_stained_glass_pane_post.jsonred_stained_glass_pane_side.jsonred_stained_glass_pane_side_alt.jsonred_terracotta.jsonred_tulip.jsonred_wool.jsonredstone_block.jsonredstone_dust_dot.jsonredstone_dust_side.jsonredstone_dust_side0.jsonredstone_dust_side1.jsonredstone_dust_side_alt.jsonredstone_dust_side_alt0.jsonredstone_dust_side_alt1.jsonredstone_dust_up.jsonredstone_lamp.jsonredstone_lamp_on.jsonredstone_ore.jsonredstone_torch.jsonredstone_torch_off.jsonredstone_wall_torch.jsonredstone_wall_torch_off.jsonreinforced_deepslate.jsonrepeater_1tick.jsonrepeater_1tick_locked.jsonrepeater_1tick_on.jsonrepeater_1tick_on_locked.jsonrepeater_2tick.jsonrepeater_2tick_locked.jsonrepeater_2tick_on.jsonrepeater_2tick_on_locked.jsonrepeater_3tick.jsonrepeater_3tick_locked.jsonrepeater_3tick_on.jsonrepeater_3tick_on_locked.jsonrepeater_4tick.jsonrepeater_4tick_locked.jsonrepeater_4tick_on.jsonrepeater_4tick_on_locked.jsonrepeating_command_block.jsonrepeating_command_block_conditional.jsonresin_block.jsonresin_brick_slab.jsonresin_brick_slab_top.jsonresin_brick_stairs.jsonresin_brick_stairs_inner.jsonresin_brick_stairs_outer.jsonresin_brick_wall_inventory.jsonresin_brick_wall_post.jsonresin_brick_wall_side.jsonresin_brick_wall_side_tall.jsonresin_bricks.jsonresin_clump.jsonrespawn_anchor_0.jsonrespawn_anchor_1.jsonrespawn_anchor_2.jsonrespawn_anchor_3.jsonrespawn_anchor_4.jsonrooted_dirt.jsonrose_bush_bottom.jsonrose_bush_top.jsonsand.jsonsandstone.jsonsandstone_slab.jsonsandstone_slab_top.jsonsandstone_stairs.jsonsandstone_stairs_inner.jsonsandstone_stairs_outer.jsonsandstone_wall_inventory.jsonsandstone_wall_post.jsonsandstone_wall_side.jsonsandstone_wall_side_tall.jsonscaffolding_stable.jsonscaffolding_unstable.jsonsculk.jsonsculk_catalyst.jsonsculk_catalyst_bloom.jsonsculk_mirrored.jsonsculk_sensor.jsonsculk_sensor_active.jsonsculk_sensor_inactive.jsonsculk_shrieker.jsonsculk_shrieker_can_summon.jsonsculk_vein.jsonsea_lantern.jsonsea_pickle.jsonseagrass.jsonshort_grass.jsonshroomlight.jsonshulker_box.jsonskull.jsonslab.jsonslab_top.jsonslightly_cracked_turtle_egg.jsonslime_block.jsonsmall_amethyst_bud.jsonsmall_dripleaf_bottom.jsonsmall_dripleaf_top.jsonsmithing_table.jsonsmoker.jsonsmoker_on.jsonsmooth_basalt.jsonsmooth_quartz.jsonsmooth_quartz_slab.jsonsmooth_quartz_slab_top.jsonsmooth_quartz_stairs.jsonsmooth_quartz_stairs_inner.jsonsmooth_quartz_stairs_outer.jsonsmooth_red_sandstone.jsonsmooth_red_sandstone_slab.jsonsmooth_red_sandstone_slab_top.jsonsmooth_red_sandstone_stairs.jsonsmooth_red_sandstone_stairs_inner.jsonsmooth_red_sandstone_stairs_outer.jsonsmooth_sandstone.jsonsmooth_sandstone_slab.jsonsmooth_sandstone_slab_top.jsonsmooth_sandstone_stairs.jsonsmooth_sandstone_stairs_inner.jsonsmooth_sandstone_stairs_outer.jsonsmooth_stone.jsonsmooth_stone_slab.jsonsmooth_stone_slab_double.jsonsmooth_stone_slab_top.jsonsniffer_egg.jsonsniffer_egg_not_cracked.jsonsniffer_egg_slightly_cracked.jsonsniffer_egg_very_cracked.jsonsnow_block.jsonsnow_height10.jsonsnow_height12.jsonsnow_height14.jsonsnow_height2.jsonsnow_height4.jsonsnow_height6.jsonsnow_height8.jsonsoul_campfire.jsonsoul_fire_floor0.jsonsoul_fire_floor1.jsonsoul_fire_side0.jsonsoul_fire_side1.jsonsoul_fire_side_alt0.jsonsoul_fire_side_alt1.jsonsoul_lantern.jsonsoul_lantern_hanging.jsonsoul_sand.jsonsoul_soil.jsonsoul_torch.jsonsoul_wall_torch.jsonspawner.jsonsponge.jsonspore_blossom.jsonspruce_button.jsonspruce_button_inventory.jsonspruce_button_pressed.jsonspruce_door_bottom_left.jsonspruce_door_bottom_left_open.jsonspruce_door_bottom_right.jsonspruce_door_bottom_right_open.jsonspruce_door_top_left.jsonspruce_door_top_left_open.jsonspruce_door_top_right.jsonspruce_door_top_right_open.jsonspruce_fence_gate.jsonspruce_fence_gate_open.jsonspruce_fence_gate_wall.jsonspruce_fence_gate_wall_open.jsonspruce_fence_inventory.jsonspruce_fence_post.jsonspruce_fence_side.jsonspruce_hanging_sign.jsonspruce_leaves.jsonspruce_log.jsonspruce_log_horizontal.jsonspruce_planks.jsonspruce_pressure_plate.jsonspruce_pressure_plate_down.jsonspruce_sapling.jsonspruce_sign.jsonspruce_slab.jsonspruce_slab_top.jsonspruce_stairs.jsonspruce_stairs_inner.jsonspruce_stairs_outer.jsonspruce_trapdoor_bottom.jsonspruce_trapdoor_open.jsonspruce_trapdoor_top.jsonspruce_wood.jsonstairs.jsonstem_fruit.jsonstem_growth0.jsonstem_growth1.jsonstem_growth2.jsonstem_growth3.jsonstem_growth4.jsonstem_growth5.jsonstem_growth6.jsonstem_growth7.jsonsticky_piston.jsonsticky_piston_inventory.jsonstone.jsonstone_brick_slab.jsonstone_brick_slab_top.jsonstone_brick_stairs.jsonstone_brick_stairs_inner.jsonstone_brick_stairs_outer.jsonstone_brick_wall_inventory.jsonstone_brick_wall_post.jsonstone_brick_wall_side.jsonstone_brick_wall_side_tall.jsonstone_bricks.jsonstone_button.jsonstone_button_inventory.jsonstone_button_pressed.jsonstone_mirrored.jsonstone_pressure_plate.jsonstone_pressure_plate_down.jsonstone_slab.jsonstone_slab_top.jsonstone_stairs.jsonstone_stairs_inner.jsonstone_stairs_outer.jsonstonecutter.jsonstripped_acacia_log.jsonstripped_acacia_log_horizontal.jsonstripped_acacia_wood.jsonstripped_bamboo_block.jsonstripped_bamboo_block_x.jsonstripped_bamboo_block_y.jsonstripped_bamboo_block_z.jsonstripped_birch_log.jsonstripped_birch_log_horizontal.jsonstripped_birch_wood.jsonstripped_cherry_log.jsonstripped_cherry_log_x.jsonstripped_cherry_log_y.jsonstripped_cherry_log_z.jsonstripped_cherry_wood.jsonstripped_crimson_hyphae.jsonstripped_crimson_stem.jsonstripped_dark_oak_log.jsonstripped_dark_oak_log_horizontal.jsonstripped_dark_oak_wood.jsonstripped_jungle_log.jsonstripped_jungle_log_horizontal.jsonstripped_jungle_wood.jsonstripped_mangrove_log.jsonstripped_mangrove_log_horizontal.jsonstripped_mangrove_wood.jsonstripped_oak_log.jsonstripped_oak_log_horizontal.jsonstripped_oak_wood.jsonstripped_pale_oak_log.jsonstripped_pale_oak_log_horizontal.jsonstripped_pale_oak_wood.jsonstripped_spruce_log.jsonstripped_spruce_log_horizontal.jsonstripped_spruce_wood.jsonstripped_warped_hyphae.jsonstripped_warped_stem.jsonstructure_block.jsonstructure_block_corner.jsonstructure_block_data.jsonstructure_block_load.jsonstructure_block_save.jsonstructure_void.jsonsugar_cane.jsonsunflower_bottom.jsonsunflower_top.jsonsuspicious_gravel_0.jsonsuspicious_gravel_1.jsonsuspicious_gravel_2.jsonsuspicious_gravel_3.jsonsuspicious_sand_0.jsonsuspicious_sand_1.jsonsuspicious_sand_2.jsonsuspicious_sand_3.jsonsweet_berry_bush_stage0.jsonsweet_berry_bush_stage1.jsonsweet_berry_bush_stage2.jsonsweet_berry_bush_stage3.jsontall_grass_bottom.jsontall_grass_top.jsontall_seagrass_bottom.jsontall_seagrass_top.jsontarget.jsontemplate_anvil.jsontemplate_azalea.jsontemplate_cake_with_candle.jsontemplate_campfire.jsontemplate_candle.jsontemplate_cauldron_full.jsontemplate_cauldron_level1.jsontemplate_cauldron_level2.jsontemplate_chiseled_bookshelf_slot_bottom_left.jsontemplate_chiseled_bookshelf_slot_bottom_mid.jsontemplate_chiseled_bookshelf_slot_bottom_right.jsontemplate_chiseled_bookshelf_slot_top_left.jsontemplate_chiseled_bookshelf_slot_top_mid.jsontemplate_chiseled_bookshelf_slot_top_right.jsontemplate_chorus_flower.jsontemplate_command_block.jsontemplate_custom_fence_gate.jsontemplate_custom_fence_gate_open.jsontemplate_custom_fence_gate_wall.jsontemplate_custom_fence_gate_wall_open.jsontemplate_daylight_detector.jsontemplate_farmland.jsontemplate_fence_gate.jsontemplate_fence_gate_open.jsontemplate_fence_gate_wall.jsontemplate_fence_gate_wall_open.jsontemplate_fire_floor.jsontemplate_fire_side.jsontemplate_fire_side_alt.jsontemplate_fire_up.jsontemplate_fire_up_alt.jsontemplate_four_candles.jsontemplate_four_turtle_eggs.jsontemplate_glass_pane_noside.jsontemplate_glass_pane_noside_alt.jsontemplate_glass_pane_post.jsontemplate_glass_pane_side.jsontemplate_glass_pane_side_alt.jsontemplate_glazed_terracotta.jsontemplate_hanging_lantern.jsontemplate_item_frame.jsontemplate_item_frame_map.jsontemplate_lantern.jsontemplate_orientable_trapdoor_bottom.jsontemplate_orientable_trapdoor_open.jsontemplate_orientable_trapdoor_top.jsontemplate_piston.jsontemplate_piston_head.jsontemplate_piston_head_short.jsontemplate_potted_azalea_bush.jsontemplate_rail_raised_ne.jsontemplate_rail_raised_sw.jsontemplate_redstone_torch.jsontemplate_redstone_torch_wall.jsontemplate_sculk_shrieker.jsontemplate_seagrass.jsontemplate_single_face.jsontemplate_three_candles.jsontemplate_three_turtle_eggs.jsontemplate_torch.jsontemplate_torch_unlit.jsontemplate_torch_wall.jsontemplate_torch_wall_unlit.jsontemplate_trapdoor_bottom.jsontemplate_trapdoor_open.jsontemplate_trapdoor_top.jsontemplate_turtle_egg.jsontemplate_two_candles.jsontemplate_two_turtle_eggs.jsontemplate_vault.jsontemplate_wall_post.jsontemplate_wall_side.jsontemplate_wall_side_tall.jsonterracotta.jsonthin_block.jsonthree_dead_sea_pickles.jsonthree_sea_pickles.jsonthree_slightly_cracked_turtle_eggs.jsonthree_turtle_eggs.jsonthree_very_cracked_turtle_eggs.jsontinted_cross.jsontinted_flower_pot_cross.jsontinted_glass.jsontnt.jsontorch.jsontorchflower.jsontorchflower_crop_stage0.jsontorchflower_crop_stage1.jsontrapped_chest.jsontrial_spawner.jsontrial_spawner_active.jsontrial_spawner_active_ominous.jsontrial_spawner_ejecting_reward.jsontrial_spawner_ejecting_reward_ominous.jsontrial_spawner_inactive_ominous.jsontripwire_attached_n.jsontripwire_attached_ne.jsontripwire_attached_ns.jsontripwire_attached_nse.jsontripwire_attached_nsew.jsontripwire_hook.jsontripwire_hook_attached.jsontripwire_hook_attached_on.jsontripwire_hook_on.jsontripwire_n.jsontripwire_ne.jsontripwire_ns.jsontripwire_nse.jsontripwire_nsew.jsontube_coral.jsontube_coral_block.jsontube_coral_fan.jsontube_coral_wall_fan.jsontuff.jsontuff_brick_slab.jsontuff_brick_slab_top.jsontuff_brick_stairs.jsontuff_brick_stairs_inner.jsontuff_brick_stairs_outer.jsontuff_brick_wall_inventory.jsontuff_brick_wall_post.jsontuff_brick_wall_side.jsontuff_brick_wall_side_tall.jsontuff_bricks.jsontuff_slab.jsontuff_slab_top.jsontuff_stairs.jsontuff_stairs_inner.jsontuff_stairs_outer.jsontuff_wall_inventory.jsontuff_wall_post.jsontuff_wall_side.jsontuff_wall_side_tall.jsonturtle_egg.jsontwisting_vines.jsontwisting_vines_plant.jsontwo_dead_sea_pickles.jsontwo_sea_pickles.jsontwo_slightly_cracked_turtle_eggs.jsontwo_turtle_eggs.jsontwo_very_cracked_turtle_eggs.jsonvault.jsonvault_active.jsonvault_active_ominous.jsonvault_ejecting_reward.jsonvault_ejecting_reward_ominous.jsonvault_ominous.jsonvault_unlocking.jsonvault_unlocking_ominous.jsonverdant_froglight.jsonverdant_froglight_horizontal.jsonvery_cracked_turtle_egg.jsonvine.jsonwall_inventory.jsonwall_torch.jsonwarped_button.jsonwarped_button_inventory.jsonwarped_button_pressed.jsonwarped_door_bottom_left.jsonwarped_door_bottom_left_open.jsonwarped_door_bottom_right.jsonwarped_door_bottom_right_open.jsonwarped_door_top_left.jsonwarped_door_top_left_open.jsonwarped_door_top_right.jsonwarped_door_top_right_open.jsonwarped_fence_gate.jsonwarped_fence_gate_open.jsonwarped_fence_gate_wall.jsonwarped_fence_gate_wall_open.jsonwarped_fence_inventory.jsonwarped_fence_post.jsonwarped_fence_side.jsonwarped_fungus.jsonwarped_hanging_sign.jsonwarped_hyphae.jsonwarped_nylium.jsonwarped_planks.jsonwarped_pressure_plate.jsonwarped_pressure_plate_down.jsonwarped_roots.jsonwarped_sign.jsonwarped_slab.jsonwarped_slab_top.jsonwarped_stairs.jsonwarped_stairs_inner.jsonwarped_stairs_outer.jsonwarped_stem.jsonwarped_trapdoor_bottom.jsonwarped_trapdoor_open.jsonwarped_trapdoor_top.jsonwarped_wart_block.jsonwater.jsonwater_cauldron_full.jsonwater_cauldron_level1.jsonwater_cauldron_level2.jsonweathered_chiseled_copper.jsonweathered_copper.jsonweathered_copper_bulb.jsonweathered_copper_bulb_lit.jsonweathered_copper_bulb_lit_powered.jsonweathered_copper_bulb_powered.jsonweathered_copper_door_bottom_left.jsonweathered_copper_door_bottom_left_open.jsonweathered_copper_door_bottom_right.jsonweathered_copper_door_bottom_right_open.jsonweathered_copper_door_top_left.jsonweathered_copper_door_top_left_open.jsonweathered_copper_door_top_right.jsonweathered_copper_door_top_right_open.jsonweathered_copper_grate.jsonweathered_copper_trapdoor_bottom.jsonweathered_copper_trapdoor_open.jsonweathered_copper_trapdoor_top.jsonweathered_cut_copper.jsonweathered_cut_copper_slab.jsonweathered_cut_copper_slab_top.jsonweathered_cut_copper_stairs.jsonweathered_cut_copper_stairs_inner.jsonweathered_cut_copper_stairs_outer.jsonweeping_vines.jsonweeping_vines_plant.jsonwet_sponge.jsonwheat_stage0.jsonwheat_stage1.jsonwheat_stage2.jsonwheat_stage3.jsonwheat_stage4.jsonwheat_stage5.jsonwheat_stage6.jsonwheat_stage7.jsonwhite_candle_cake.jsonwhite_candle_cake_lit.jsonwhite_candle_four_candles.jsonwhite_candle_four_candles_lit.jsonwhite_candle_one_candle.jsonwhite_candle_one_candle_lit.jsonwhite_candle_three_candles.jsonwhite_candle_three_candles_lit.jsonwhite_candle_two_candles.jsonwhite_candle_two_candles_lit.jsonwhite_carpet.jsonwhite_concrete.jsonwhite_concrete_powder.jsonwhite_glazed_terracotta.jsonwhite_shulker_box.jsonwhite_stained_glass.jsonwhite_stained_glass_pane_noside.jsonwhite_stained_glass_pane_noside_alt.jsonwhite_stained_glass_pane_post.jsonwhite_stained_glass_pane_side.jsonwhite_stained_glass_pane_side_alt.jsonwhite_terracotta.jsonwhite_tulip.jsonwhite_wool.jsonwither_rose.jsonyellow_candle_cake.jsonyellow_candle_cake_lit.jsonyellow_candle_four_candles.jsonyellow_candle_four_candles_lit.jsonyellow_candle_one_candle.jsonyellow_candle_one_candle_lit.jsonyellow_candle_three_candles.jsonyellow_candle_three_candles_lit.jsonyellow_candle_two_candles.jsonyellow_candle_two_candles_lit.jsonyellow_carpet.jsonyellow_concrete.jsonyellow_concrete_powder.jsonyellow_glazed_terracotta.jsonyellow_shulker_box.jsonyellow_stained_glass.jsonyellow_stained_glass_pane_noside.jsonyellow_stained_glass_pane_noside_alt.jsonyellow_stained_glass_pane_post.jsonyellow_stained_glass_pane_side.jsonyellow_stained_glass_pane_side_alt.jsonyellow_terracotta.jsonyellow_wool.json
textures
block
acacia_door_bottom.pngacacia_door_top.pngacacia_leaves.pngacacia_log.pngacacia_log_top.pngacacia_planks.pngacacia_sapling.pngacacia_trapdoor.pngactivator_rail.pngactivator_rail_on.pngallium.pngamethyst_block.pngamethyst_cluster.pngancient_debris_side.pngancient_debris_top.pngandesite.pnganvil.pnganvil_top.pngattached_melon_stem.pngattached_pumpkin_stem.pngazalea_leaves.pngazalea_plant.pngazalea_side.pngazalea_top.pngazure_bluet.pngbamboo_block.pngbamboo_block_top.pngbamboo_door_bottom.pngbamboo_door_top.pngbamboo_fence.pngbamboo_fence_gate.pngbamboo_fence_gate_particle.pngbamboo_fence_particle.pngbamboo_large_leaves.pngbamboo_mosaic.pngbamboo_planks.pngbamboo_singleleaf.pngbamboo_small_leaves.pngbamboo_stage0.pngbamboo_stalk.pngbamboo_trapdoor.pngbarrel_bottom.pngbarrel_side.pngbarrel_top.pngbarrel_top_open.pngbasalt_side.pngbasalt_top.pngbeacon.pngbedrock.pngbee_nest_bottom.pngbee_nest_front.pngbee_nest_front_honey.pngbee_nest_side.pngbee_nest_top.pngbeehive_end.pngbeehive_front.pngbeehive_front_honey.pngbeehive_side.pngbeetroots_stage0.pngbeetroots_stage1.pngbeetroots_stage2.pngbeetroots_stage3.pngbell_bottom.pngbell_side.pngbell_top.pngbig_dripleaf_side.pngbig_dripleaf_stem.pngbig_dripleaf_tip.pngbig_dripleaf_top.pngbirch_door_bottom.pngbirch_door_top.pngbirch_leaves.pngbirch_log.pngbirch_log_top.pngbirch_planks.pngbirch_sapling.pngbirch_trapdoor.pngblack_candle.pngblack_candle_lit.pngblack_concrete.pngblack_concrete_powder.pngblack_glazed_terracotta.pngblack_shulker_box.pngblack_stained_glass.pngblack_stained_glass_pane_top.pngblack_terracotta.pngblack_wool.pngblackstone.pngblackstone_top.pngblast_furnace_front.pngblast_furnace_front_on.pngblast_furnace_front_on.png.mcmetablast_furnace_side.pngblast_furnace_top.pngblue_candle.pngblue_candle_lit.pngblue_concrete.pngblue_concrete_powder.pngblue_glazed_terracotta.pngblue_ice.pngblue_orchid.pngblue_shulker_box.pngblue_stained_glass.pngblue_stained_glass_pane_top.pngblue_terracotta.pngblue_wool.pngbone_block_side.pngbone_block_top.pngbookshelf.pngbrain_coral.pngbrain_coral_block.pngbrain_coral_fan.pngbrewing_stand.pngbrewing_stand_base.pngbricks.pngbrown_candle.pngbrown_candle_lit.pngbrown_concrete.pngbrown_concrete_powder.pngbrown_glazed_terracotta.pngbrown_mushroom.pngbrown_mushroom_block.pngbrown_shulker_box.pngbrown_stained_glass.pngbrown_stained_glass_pane_top.pngbrown_terracotta.pngbrown_wool.pngbubble_coral.pngbubble_coral_block.pngbubble_coral_fan.pngbudding_amethyst.pngcactus_bottom.pngcactus_side.pngcactus_top.pngcake_bottom.pngcake_inner.pngcake_side.pngcake_top.pngcalcite.pngcalibrated_sculk_sensor_amethyst.pngcalibrated_sculk_sensor_input_side.pngcalibrated_sculk_sensor_top.pngcampfire_fire.pngcampfire_fire.png.mcmetacampfire_log.pngcampfire_log_lit.pngcampfire_log_lit.png.mcmetacandle.pngcandle_lit.pngcarrots_stage0.pngcarrots_stage1.pngcarrots_stage2.pngcarrots_stage3.pngcartography_table_side1.pngcartography_table_side2.pngcartography_table_side3.pngcartography_table_top.pngcarved_pumpkin.pngcauldron_bottom.pngcauldron_inner.pngcauldron_side.pngcauldron_top.pngcave_vines.pngcave_vines_lit.pngcave_vines_plant.pngcave_vines_plant_lit.pngchain.pngchain_command_block_back.pngchain_command_block_back.png.mcmetachain_command_block_conditional.pngchain_command_block_conditional.png.mcmetachain_command_block_front.pngchain_command_block_front.png.mcmetachain_command_block_side.pngchain_command_block_side.png.mcmetacherry_door_bottom.pngcherry_door_top.pngcherry_leaves.pngcherry_log.pngcherry_log_top.pngcherry_planks.pngcherry_sapling.pngcherry_trapdoor.pngchipped_anvil_top.pngchiseled_bookshelf_empty.pngchiseled_bookshelf_occupied.pngchiseled_bookshelf_side.pngchiseled_bookshelf_top.pngchiseled_copper.pngchiseled_deepslate.pngchiseled_nether_bricks.pngchiseled_polished_blackstone.pngchiseled_quartz_block.pngchiseled_quartz_block_top.pngchiseled_red_sandstone.pngchiseled_resin_bricks.pngchiseled_sandstone.pngchiseled_stone_bricks.pngchiseled_tuff.pngchiseled_tuff_bricks.pngchiseled_tuff_bricks_top.pngchiseled_tuff_top.pngchorus_flower.pngchorus_flower_dead.pngchorus_plant.pngclay.pngclosed_eyeblossom.pngcoal_block.pngcoal_ore.pngcoarse_dirt.pngcobbled_deepslate.pngcobblestone.pngcobweb.pngcocoa_stage0.pngcocoa_stage1.pngcocoa_stage2.pngcommand_block_back.pngcommand_block_back.png.mcmetacommand_block_conditional.pngcommand_block_conditional.png.mcmetacommand_block_front.pngcommand_block_front.png.mcmetacommand_block_side.pngcommand_block_side.png.mcmetacomparator.pngcomparator_on.pngcomposter_bottom.pngcomposter_compost.pngcomposter_ready.pngcomposter_side.pngcomposter_top.pngconduit.pngcopper_block.pngcopper_bulb.pngcopper_bulb_lit.pngcopper_bulb_lit_powered.pngcopper_bulb_powered.pngcopper_door_bottom.pngcopper_door_top.pngcopper_grate.pngcopper_ore.pngcopper_trapdoor.pngcornflower.pngcracked_deepslate_bricks.pngcracked_deepslate_tiles.pngcracked_nether_bricks.pngcracked_polished_blackstone_bricks.pngcracked_stone_bricks.pngcrafter_bottom.pngcrafter_east.pngcrafter_east_crafting.pngcrafter_east_triggered.pngcrafter_north.pngcrafter_north_crafting.pngcrafter_south.pngcrafter_south_triggered.pngcrafter_top.pngcrafter_top_crafting.pngcrafter_top_triggered.pngcrafter_west.pngcrafter_west_crafting.pngcrafter_west_triggered.pngcrafting_table_front.pngcrafting_table_side.pngcrafting_table_top.pngcreaking_heart.pngcreaking_heart_active.pngcreaking_heart_top.pngcreaking_heart_top_active.pngcrimson_door_bottom.pngcrimson_door_top.pngcrimson_fungus.pngcrimson_nylium.pngcrimson_nylium_side.pngcrimson_planks.pngcrimson_roots.pngcrimson_roots_pot.pngcrimson_stem.pngcrimson_stem.png.mcmetacrimson_stem_top.pngcrimson_trapdoor.pngcrying_obsidian.pngcut_copper.pngcut_red_sandstone.pngcut_sandstone.pngcyan_candle.pngcyan_candle_lit.pngcyan_concrete.pngcyan_concrete_powder.pngcyan_glazed_terracotta.pngcyan_shulker_box.pngcyan_stained_glass.pngcyan_stained_glass_pane_top.pngcyan_terracotta.pngcyan_wool.pngdamaged_anvil_top.pngdandelion.pngdark_oak_door_bottom.pngdark_oak_door_top.pngdark_oak_leaves.pngdark_oak_log.pngdark_oak_log_top.pngdark_oak_planks.pngdark_oak_sapling.pngdark_oak_trapdoor.pngdark_prismarine.pngdaylight_detector_inverted_top.pngdaylight_detector_side.pngdaylight_detector_top.pngdead_brain_coral.pngdead_brain_coral_block.pngdead_brain_coral_fan.pngdead_bubble_coral.pngdead_bubble_coral_block.pngdead_bubble_coral_fan.pngdead_bush.pngdead_fire_coral.pngdead_fire_coral_block.pngdead_fire_coral_fan.pngdead_horn_coral.pngdead_horn_coral_block.pngdead_horn_coral_fan.pngdead_tube_coral.pngdead_tube_coral_block.pngdead_tube_coral_fan.pngdebug.pngdebug2.pngdeepslate.pngdeepslate_bricks.pngdeepslate_coal_ore.pngdeepslate_copper_ore.pngdeepslate_diamond_ore.pngdeepslate_emerald_ore.pngdeepslate_gold_ore.pngdeepslate_iron_ore.pngdeepslate_lapis_ore.pngdeepslate_redstone_ore.pngdeepslate_tiles.pngdeepslate_top.pngdestroy_stage_0.pngdestroy_stage_1.pngdestroy_stage_2.pngdestroy_stage_3.pngdestroy_stage_4.pngdestroy_stage_5.pngdestroy_stage_6.pngdestroy_stage_7.pngdestroy_stage_8.pngdestroy_stage_9.pngdetector_rail.pngdetector_rail_on.pngdiamond_block.pngdiamond_ore.pngdiorite.pngdirt.pngdirt_path_side.pngdirt_path_top.pngdispenser_front.pngdispenser_front_vertical.pngdragon_egg.pngdried_kelp_bottom.pngdried_kelp_side.pngdried_kelp_top.pngdripstone_block.pngdropper_front.pngdropper_front_vertical.pngemerald_block.pngemerald_ore.pngenchanting_table_bottom.pngenchanting_table_side.pngenchanting_table_top.pngend_portal_frame_eye.pngend_portal_frame_side.pngend_portal_frame_top.pngend_rod.pngend_stone.pngend_stone_bricks.pngexposed_chiseled_copper.pngexposed_copper.pngexposed_copper_bulb.pngexposed_copper_bulb_lit.pngexposed_copper_bulb_lit_powered.pngexposed_copper_bulb_powered.pngexposed_copper_door_bottom.pngexposed_copper_door_top.pngexposed_copper_grate.pngexposed_copper_trapdoor.pngexposed_cut_copper.pngfarmland.pngfarmland_moist.pngfern.pngfire_0.pngfire_0.png.mcmetafire_1.pngfire_1.png.mcmetafire_coral.pngfire_coral_block.pngfire_coral_fan.pngfletching_table_front.pngfletching_table_side.pngfletching_table_top.pngflower_pot.pngflowering_azalea_leaves.pngflowering_azalea_side.pngflowering_azalea_top.pngfrogspawn.pngfrosted_ice_0.pngfrosted_ice_1.pngfrosted_ice_2.pngfrosted_ice_3.pngfurnace_front.pngfurnace_front_on.pngfurnace_side.pngfurnace_top.pnggilded_blackstone.pngglass.pngglass_pane_top.pngglow_item_frame.pngglow_lichen.pngglowstone.pnggold_block.pnggold_ore.pnggranite.pnggrass_block_side.pnggrass_block_side_overlay.pnggrass_block_snow.pnggrass_block_top.pnggravel.pnggray_candle.pnggray_candle_lit.pnggray_concrete.pnggray_concrete_powder.pnggray_glazed_terracotta.pnggray_shulker_box.pnggray_stained_glass.pnggray_stained_glass_pane_top.pnggray_terracotta.pnggray_wool.pnggreen_candle.pnggreen_candle_lit.pnggreen_concrete.pnggreen_concrete_powder.pnggreen_glazed_terracotta.pnggreen_shulker_box.pnggreen_stained_glass.pnggreen_stained_glass_pane_top.pnggreen_terracotta.pnggreen_wool.pnggrindstone_pivot.pnggrindstone_round.pnggrindstone_side.pnghanging_roots.pnghay_block_side.pnghay_block_top.pngheavy_core.pnghoney_block_bottom.pnghoney_block_side.pnghoney_block_top.pnghoneycomb_block.pnghopper_inside.pnghopper_outside.pnghopper_top.pnghorn_coral.pnghorn_coral_block.pnghorn_coral_fan.pngice.pngiron_bars.pngiron_block.pngiron_door_bottom.pngiron_door_top.pngiron_ore.pngiron_trapdoor.pngitem_frame.pngjack_o_lantern.pngjigsaw_bottom.pngjigsaw_lock.pngjigsaw_side.pngjigsaw_top.pngjukebox_side.pngjukebox_top.pngjungle_door_bottom.pngjungle_door_top.pngjungle_leaves.pngjungle_log.pngjungle_log_top.pngjungle_planks.pngjungle_sapling.pngjungle_trapdoor.pngkelp.pngkelp.png.mcmetakelp_plant.pngkelp_plant.png.mcmetaladder.pnglantern.pnglantern.png.mcmetalapis_block.pnglapis_ore.pnglarge_amethyst_bud.pnglarge_fern_bottom.pnglarge_fern_top.pnglava_flow.pnglava_flow.png.mcmetalava_still.pnglava_still.png.mcmetalectern_base.pnglectern_front.pnglectern_sides.pnglectern_top.pnglever.pnglight_blue_candle.pnglight_blue_candle_lit.pnglight_blue_concrete.pnglight_blue_concrete_powder.pnglight_blue_glazed_terracotta.pnglight_blue_shulker_box.pnglight_blue_stained_glass.pnglight_blue_stained_glass_pane_top.pnglight_blue_terracotta.pnglight_blue_wool.pnglight_gray_candle.pnglight_gray_candle_lit.pnglight_gray_concrete.pnglight_gray_concrete_powder.pnglight_gray_glazed_terracotta.pnglight_gray_shulker_box.pnglight_gray_stained_glass.pnglight_gray_stained_glass_pane_top.pnglight_gray_terracotta.pnglight_gray_wool.pnglightning_rod.pnglightning_rod_on.pnglilac_bottom.pnglilac_top.pnglily_of_the_valley.pnglily_pad.pnglime_candle.pnglime_candle_lit.pnglime_concrete.pnglime_concrete_powder.pnglime_glazed_terracotta.pnglime_shulker_box.pnglime_stained_glass.pnglime_stained_glass_pane_top.pnglime_terracotta.pnglime_wool.pnglodestone_side.pnglodestone_top.pngloom_bottom.pngloom_front.pngloom_side.pngloom_top.pngmagenta_candle.pngmagenta_candle_lit.pngmagenta_concrete.pngmagenta_concrete_powder.pngmagenta_glazed_terracotta.pngmagenta_shulker_box.pngmagenta_stained_glass.pngmagenta_stained_glass_pane_top.pngmagenta_terracotta.pngmagenta_wool.pngmagma.pngmagma.png.mcmetamangrove_door_bottom.pngmangrove_door_top.pngmangrove_leaves.pngmangrove_log.pngmangrove_log_top.pngmangrove_planks.pngmangrove_propagule.pngmangrove_propagule_hanging.pngmangrove_roots_side.pngmangrove_roots_top.pngmangrove_trapdoor.pngmedium_amethyst_bud.pngmelon_side.pngmelon_stem.pngmelon_top.pngmoss_block.pngmossy_cobblestone.pngmossy_stone_bricks.pngmud.pngmud_bricks.pngmuddy_mangrove_roots_side.pngmuddy_mangrove_roots_top.pngmushroom_block_inside.pngmushroom_stem.pngmycelium_side.pngmycelium_top.pngnether_bricks.pngnether_gold_ore.pngnether_portal.pngnether_portal.png.mcmetanether_quartz_ore.pngnether_sprouts.pngnether_wart_block.pngnether_wart_stage0.pngnether_wart_stage1.pngnether_wart_stage2.pngnetherite_block.pngnetherrack.pngnote_block.pngoak_door_bottom.pngoak_door_top.pngoak_leaves.pngoak_log.pngoak_log_top.pngoak_planks.pngoak_sapling.pngoak_trapdoor.pngobserver_back.pngobserver_back_on.pngobserver_front.pngobserver_side.pngobserver_top.pngobsidian.pngochre_froglight_side.pngochre_froglight_top.pngopen_eyeblossom.pngopen_eyeblossom_emissive.pngorange_candle.pngorange_candle_lit.pngorange_concrete.pngorange_concrete_powder.pngorange_glazed_terracotta.pngorange_shulker_box.pngorange_stained_glass.pngorange_stained_glass_pane_top.pngorange_terracotta.pngorange_tulip.pngorange_wool.pngoxeye_daisy.pngoxidized_chiseled_copper.pngoxidized_copper.pngoxidized_copper_bulb.pngoxidized_copper_bulb_lit.pngoxidized_copper_bulb_lit_powered.pngoxidized_copper_bulb_powered.pngoxidized_copper_door_bottom.pngoxidized_copper_door_top.pngoxidized_copper_grate.pngoxidized_copper_trapdoor.pngoxidized_cut_copper.pngpacked_ice.pngpacked_mud.pngpale_hanging_moss.pngpale_hanging_moss_tip.pngpale_moss_block.pngpale_moss_carpet.pngpale_moss_carpet_side_small.pngpale_moss_carpet_side_tall.pngpale_oak_door_bottom.pngpale_oak_door_top.pngpale_oak_leaves.pngpale_oak_log.pngpale_oak_log_top.pngpale_oak_planks.pngpale_oak_sapling.pngpale_oak_trapdoor.pngpearlescent_froglight_side.pngpearlescent_froglight_top.pngpeony_bottom.pngpeony_top.pngpink_candle.pngpink_candle_lit.pngpink_concrete.pngpink_concrete_powder.pngpink_glazed_terracotta.pngpink_petals.pngpink_petals_stem.pngpink_shulker_box.pngpink_stained_glass.pngpink_stained_glass_pane_top.pngpink_terracotta.pngpink_tulip.pngpink_wool.pngpiston_bottom.pngpiston_inner.pngpiston_side.pngpiston_top.pngpiston_top_sticky.pngpitcher_crop_bottom.pngpitcher_crop_bottom_stage_1.pngpitcher_crop_bottom_stage_2.pngpitcher_crop_bottom_stage_3.pngpitcher_crop_bottom_stage_4.pngpitcher_crop_side.pngpitcher_crop_top.pngpitcher_crop_top_stage_3.pngpitcher_crop_top_stage_4.pngpodzol_side.pngpodzol_top.pngpointed_dripstone_down_base.pngpointed_dripstone_down_frustum.pngpointed_dripstone_down_middle.pngpointed_dripstone_down_tip.pngpointed_dripstone_down_tip_merge.pngpointed_dripstone_up_base.pngpointed_dripstone_up_frustum.pngpointed_dripstone_up_middle.pngpointed_dripstone_up_tip.pngpointed_dripstone_up_tip_merge.pngpolished_andesite.pngpolished_basalt_side.pngpolished_basalt_top.pngpolished_blackstone.pngpolished_blackstone_bricks.pngpolished_deepslate.pngpolished_diorite.pngpolished_granite.pngpolished_tuff.pngpoppy.pngpotatoes_stage0.pngpotatoes_stage1.pngpotatoes_stage2.pngpotatoes_stage3.pngpotted_azalea_bush_plant.pngpotted_azalea_bush_side.pngpotted_azalea_bush_top.pngpotted_flowering_azalea_bush_plant.pngpotted_flowering_azalea_bush_side.pngpotted_flowering_azalea_bush_top.pngpowder_snow.pngpowered_rail.pngpowered_rail_on.pngprismarine.pngprismarine.png.mcmetaprismarine_bricks.pngpumpkin_side.pngpumpkin_stem.pngpumpkin_top.pngpurple_candle.pngpurple_candle_lit.pngpurple_concrete.pngpurple_concrete_powder.pngpurple_glazed_terracotta.pngpurple_shulker_box.pngpurple_stained_glass.pngpurple_stained_glass_pane_top.pngpurple_terracotta.pngpurple_wool.pngpurpur_block.pngpurpur_pillar.pngpurpur_pillar_top.pngquartz_block_bottom.pngquartz_block_side.pngquartz_block_top.pngquartz_bricks.pngquartz_pillar.pngquartz_pillar_top.pngrail.pngrail_corner.pngraw_copper_block.pngraw_gold_block.pngraw_iron_block.pngred_candle.pngred_candle_lit.pngred_concrete.pngred_concrete_powder.pngred_glazed_terracotta.pngred_mushroom.pngred_mushroom_block.pngred_nether_bricks.pngred_sand.pngred_sandstone.pngred_sandstone_bottom.pngred_sandstone_top.pngred_shulker_box.pngred_stained_glass.pngred_stained_glass_pane_top.pngred_terracotta.pngred_tulip.pngred_wool.pngredstone_block.pngredstone_dust_dot.pngredstone_dust_line0.pngredstone_dust_line1.pngredstone_dust_overlay.pngredstone_lamp.pngredstone_lamp_on.pngredstone_ore.pngredstone_torch.pngredstone_torch_off.pngreinforced_deepslate_bottom.pngreinforced_deepslate_side.pngreinforced_deepslate_top.pngrepeater.pngrepeater_on.pngrepeating_command_block_back.pngrepeating_command_block_back.png.mcmetarepeating_command_block_conditional.pngrepeating_command_block_conditional.png.mcmetarepeating_command_block_front.pngrepeating_command_block_front.png.mcmetarepeating_command_block_side.pngrepeating_command_block_side.png.mcmetaresin_block.pngresin_bricks.pngresin_clump.pngrespawn_anchor_bottom.pngrespawn_anchor_side0.pngrespawn_anchor_side1.pngrespawn_anchor_side2.pngrespawn_anchor_side3.pngrespawn_anchor_side4.pngrespawn_anchor_top.pngrespawn_anchor_top.png.mcmetarespawn_anchor_top_off.pngrooted_dirt.pngrose_bush_bottom.pngrose_bush_top.pngsand.pngsandstone.pngsandstone_bottom.pngsandstone_top.pngscaffolding_bottom.pngscaffolding_side.pngscaffolding_top.pngsculk.pngsculk.png.mcmetasculk_catalyst_bottom.pngsculk_catalyst_side.pngsculk_catalyst_side_bloom.pngsculk_catalyst_side_bloom.png.mcmetasculk_catalyst_top.pngsculk_catalyst_top_bloom.pngsculk_catalyst_top_bloom.png.mcmetasculk_sensor_bottom.pngsculk_sensor_side.pngsculk_sensor_tendril_active.pngsculk_sensor_tendril_active.png.mcmetasculk_sensor_tendril_inactive.pngsculk_sensor_tendril_inactive.png.mcmetasculk_sensor_top.pngsculk_shrieker_bottom.pngsculk_shrieker_can_summon_inner_top.pngsculk_shrieker_can_summon_inner_top.png.mcmetasculk_shrieker_inner_top.pngsculk_shrieker_inner_top.png.mcmetasculk_shrieker_side.pngsculk_shrieker_top.pngsculk_vein.pngsculk_vein.png.mcmetasea_lantern.pngsea_lantern.png.mcmetasea_pickle.pngseagrass.pngseagrass.png.mcmetashort_grass.pngshroomlight.pngshulker_box.pngslime_block.pngsmall_amethyst_bud.pngsmall_dripleaf_side.pngsmall_dripleaf_stem_bottom.pngsmall_dripleaf_stem_top.pngsmall_dripleaf_top.pngsmithing_table_bottom.pngsmithing_table_front.pngsmithing_table_side.pngsmithing_table_top.pngsmoker_bottom.pngsmoker_front.pngsmoker_front_on.pngsmoker_front_on.png.mcmetasmoker_side.pngsmoker_top.pngsmooth_basalt.pngsmooth_stone.pngsmooth_stone_slab_side.pngsniffer_egg_not_cracked_bottom.pngsniffer_egg_not_cracked_east.pngsniffer_egg_not_cracked_north.pngsniffer_egg_not_cracked_south.pngsniffer_egg_not_cracked_top.pngsniffer_egg_not_cracked_west.pngsniffer_egg_slightly_cracked_bottom.pngsniffer_egg_slightly_cracked_east.pngsniffer_egg_slightly_cracked_north.pngsniffer_egg_slightly_cracked_south.pngsniffer_egg_slightly_cracked_top.pngsniffer_egg_slightly_cracked_west.pngsniffer_egg_very_cracked_bottom.pngsniffer_egg_very_cracked_east.pngsniffer_egg_very_cracked_north.pngsniffer_egg_very_cracked_south.pngsniffer_egg_very_cracked_top.pngsniffer_egg_very_cracked_west.pngsnow.pngsoul_campfire_fire.pngsoul_campfire_fire.png.mcmetasoul_campfire_log_lit.pngsoul_campfire_log_lit.png.mcmetasoul_fire_0.pngsoul_fire_0.png.mcmetasoul_fire_1.pngsoul_fire_1.png.mcmetasoul_lantern.pngsoul_lantern.png.mcmetasoul_sand.pngsoul_soil.pngsoul_torch.pngspawner.pngsponge.pngspore_blossom.pngspore_blossom_base.pngspruce_door_bottom.pngspruce_door_top.pngspruce_leaves.pngspruce_log.pngspruce_log_top.pngspruce_planks.pngspruce_sapling.pngspruce_trapdoor.pngstone.pngstone_bricks.pngstonecutter_bottom.pngstonecutter_saw.pngstonecutter_saw.png.mcmetastonecutter_side.pngstonecutter_top.pngstripped_acacia_log.pngstripped_acacia_log_top.pngstripped_bamboo_block.pngstripped_bamboo_block_top.pngstripped_birch_log.pngstripped_birch_log_top.pngstripped_cherry_log.pngstripped_cherry_log_top.pngstripped_crimson_stem.pngstripped_crimson_stem_top.pngstripped_dark_oak_log.pngstripped_dark_oak_log_top.pngstripped_jungle_log.pngstripped_jungle_log_top.pngstripped_mangrove_log.pngstripped_mangrove_log_top.pngstripped_oak_log.pngstripped_oak_log_top.pngstripped_pale_oak_log.pngstripped_pale_oak_log_top.pngstripped_spruce_log.pngstripped_spruce_log_top.pngstripped_warped_stem.pngstripped_warped_stem_top.pngstructure_block.pngstructure_block_corner.pngstructure_block_data.pngstructure_block_load.pngstructure_block_save.pngsugar_cane.pngsunflower_back.pngsunflower_bottom.pngsunflower_front.pngsunflower_top.pngsuspicious_gravel_0.pngsuspicious_gravel_1.pngsuspicious_gravel_2.pngsuspicious_gravel_3.pngsuspicious_sand_0.pngsuspicious_sand_1.pngsuspicious_sand_2.pngsuspicious_sand_3.pngsweet_berry_bush_stage0.pngsweet_berry_bush_stage1.pngsweet_berry_bush_stage2.pngsweet_berry_bush_stage3.pngtall_grass_bottom.pngtall_grass_top.pngtall_seagrass_bottom.pngtall_seagrass_bottom.png.mcmetatall_seagrass_top.pngtall_seagrass_top.png.mcmetatarget_side.pngtarget_top.pngterracotta.pngtinted_glass.pngtnt_bottom.pngtnt_side.pngtnt_top.pngtorch.pngtorchflower.pngtorchflower_crop_stage0.pngtorchflower_crop_stage1.pngtrial_spawner_bottom.pngtrial_spawner_side_active.pngtrial_spawner_side_active_ominous.pngtrial_spawner_side_inactive.pngtrial_spawner_side_inactive_ominous.pngtrial_spawner_top_active.pngtrial_spawner_top_active_ominous.pngtrial_spawner_top_ejecting_reward.pngtrial_spawner_top_ejecting_reward_ominous.pngtrial_spawner_top_inactive.pngtrial_spawner_top_inactive_ominous.pngtripwire.pngtripwire_hook.pngtube_coral.pngtube_coral_block.pngtube_coral_fan.pngtuff.pngtuff_bricks.pngturtle_egg.pngturtle_egg_slightly_cracked.pngturtle_egg_very_cracked.pngtwisting_vines.pngtwisting_vines_plant.pngvault_bottom.pngvault_bottom_ominous.pngvault_front_ejecting.pngvault_front_ejecting_ominous.pngvault_front_off.pngvault_front_off_ominous.pngvault_front_on.pngvault_front_on_ominous.pngvault_side_off.pngvault_side_off_ominous.pngvault_side_on.pngvault_side_on_ominous.pngvault_top.pngvault_top_ejecting.pngvault_top_ejecting_ominous.pngvault_top_ominous.pngverdant_froglight_side.pngverdant_froglight_top.pngvine.pngwarped_door_bottom.pngwarped_door_top.pngwarped_fungus.pngwarped_nylium.pngwarped_nylium_side.pngwarped_planks.pngwarped_roots.pngwarped_roots_pot.pngwarped_stem.pngwarped_stem.png.mcmetawarped_stem_top.pngwarped_trapdoor.pngwarped_wart_block.pngwater_flow.pngwater_flow.png.mcmetawater_overlay.pngwater_still.pngwater_still.png.mcmetaweathered_chiseled_copper.pngweathered_copper.pngweathered_copper_bulb.pngweathered_copper_bulb_lit.pngweathered_copper_bulb_lit_powered.pngweathered_copper_bulb_powered.pngweathered_copper_door_bottom.pngweathered_copper_door_top.pngweathered_copper_grate.pngweathered_copper_trapdoor.pngweathered_cut_copper.pngweeping_vines.pngweeping_vines_plant.pngwet_sponge.pngwheat_stage0.pngwheat_stage1.pngwheat_stage2.pngwheat_stage3.pngwheat_stage4.pngwheat_stage5.pngwheat_stage6.pngwheat_stage7.pngwhite_candle.pngwhite_candle_lit.pngwhite_concrete.pngwhite_concrete_powder.pngwhite_glazed_terracotta.pngwhite_shulker_box.pngwhite_stained_glass.pngwhite_stained_glass_pane_top.pngwhite_terracotta.pngwhite_tulip.pngwhite_wool.pngwither_rose.pngyellow_candle.pngyellow_candle_lit.pngyellow_concrete.pngyellow_concrete_powder.pngyellow_glazed_terracotta.pngyellow_shulker_box.pngyellow_stained_glass.pngyellow_stained_glass_pane_top.pngyellow_terracotta.pngyellow_wool.png
2
.gitignore
vendored
2
.gitignore
vendored
@ -168,3 +168,5 @@ gradle-app.setting
|
||||
*.hprof
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/java,intellij,gradle
|
||||
|
||||
/local.gradle
|
2
.idea/modules.xml
generated
2
.idea/modules.xml
generated
@ -3,6 +3,8 @@
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/PixelPic.main.iml" filepath="$PROJECT_DIR$/.idea/modules/PixelPic.main.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/PixelPics.PixelPic.main.iml" filepath="$PROJECT_DIR$/.idea/modules/PixelPics.PixelPic.main.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/eu.mhsl.minecraft.pixelpic.PixelPic.main.iml" filepath="$PROJECT_DIR$/.idea/modules/eu.mhsl.minecraft.pixelpic.PixelPic.main.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
4
.idea/modules/PixelPic.main.iml
generated
4
.idea/modules/PixelPic.main.iml
generated
@ -11,4 +11,8 @@
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
14
.idea/modules/PixelPics.main.iml
generated
Normal file
14
.idea/modules/PixelPics.main.iml
generated
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="minecraft" name="Minecraft">
|
||||
<configuration>
|
||||
<autoDetectTypes>
|
||||
<platformType>PAPER</platformType>
|
||||
<platformType>ADVENTURE</platformType>
|
||||
</autoDetectTypes>
|
||||
<projectReimportVersion>1</projectReimportVersion>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
</module>
|
14
.idea/modules/eu.mhsl.minecraft.pixelpic.PixelPic.main.iml
generated
Normal file
14
.idea/modules/eu.mhsl.minecraft.pixelpic.PixelPic.main.iml
generated
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="minecraft" name="Minecraft">
|
||||
<configuration>
|
||||
<autoDetectTypes>
|
||||
<platformType>PAPER</platformType>
|
||||
<platformType>ADVENTURE</platformType>
|
||||
</autoDetectTypes>
|
||||
<projectReimportVersion>1</projectReimportVersion>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
</module>
|
@ -2,7 +2,7 @@ plugins {
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group = 'eu.mhsl.minecraft.pixelpic'
|
||||
group = 'eu.mhsl.minecraft.pixelpics'
|
||||
version = '1.0-SNAPSHOT'
|
||||
|
||||
repositories {
|
||||
@ -18,7 +18,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("io.papermc.paper:paper-api:1.21.4-R0.1-SNAPSHOT")
|
||||
compileOnly("io.papermc.paper:paper-api:1.21.7-R0.1-SNAPSHOT")
|
||||
}
|
||||
|
||||
def targetJavaVersion = 21
|
||||
@ -47,3 +47,7 @@ processResources {
|
||||
expand props
|
||||
}
|
||||
}
|
||||
|
||||
if (file("local.gradle").exists()) {
|
||||
apply from: "local.gradle"
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
rootProject.name = 'PixelPic'
|
||||
rootProject.name = 'PixelPics'
|
||||
|
@ -1,17 +0,0 @@
|
||||
package eu.mhsl.minecraft.pixelpic;
|
||||
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public final class Main extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
// Plugin startup logic
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
// Plugin shutdown logic
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package eu.mhsl.minecraft.pixelpics;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.map.MapCanvas;
|
||||
import org.bukkit.map.MapRenderer;
|
||||
import org.bukkit.map.MapView;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class ImageMapRenderer extends MapRenderer {
|
||||
public static final int IMAGE_SIZE = 128;
|
||||
private final BufferedImage image;
|
||||
private boolean alreadyRendered = false;
|
||||
|
||||
public ImageMapRenderer(BufferedImage image) {
|
||||
this(image, 0, 0);
|
||||
}
|
||||
|
||||
public ImageMapRenderer(BufferedImage image, int x, int y) {
|
||||
this.image = recalculateInput(image, x, y);
|
||||
}
|
||||
|
||||
public static BufferedImage recalculateInput(BufferedImage input, int x, int y) {
|
||||
if (x * IMAGE_SIZE > input.getWidth() || y * IMAGE_SIZE > input.getHeight())
|
||||
throw new RuntimeException(String.format("Input image mus match a multiple of x and y with %d", IMAGE_SIZE));
|
||||
|
||||
int x1 = (int) (double) (x * IMAGE_SIZE);
|
||||
int y1 = (int) (double) (y * IMAGE_SIZE);
|
||||
|
||||
int x2 = (int) (double) Math.min(input.getWidth(), ((x + 1) * IMAGE_SIZE));
|
||||
int y2 = (int) (double) Math.min(input.getHeight(), ((y + 1) * IMAGE_SIZE));
|
||||
|
||||
if (x2 - x1 <= 0 || y2 - y1 <= 0)
|
||||
throw new RuntimeException("Invalid Image dimensions!");
|
||||
|
||||
return input.getSubimage(x1, y1, x2 - x1, y2 - y1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(@NotNull MapView map, @NotNull MapCanvas canvas, @NotNull Player player) {
|
||||
if(this.alreadyRendered) return;
|
||||
canvas.drawImage(0, 0, this.image);
|
||||
this.alreadyRendered = true;
|
||||
}
|
||||
}
|
106
src/main/java/eu/mhsl/minecraft/pixelpics/Main.java
Normal file
106
src/main/java/eu/mhsl/minecraft/pixelpics/Main.java
Normal file
@ -0,0 +1,106 @@
|
||||
package eu.mhsl.minecraft.pixelpics;
|
||||
|
||||
import eu.mhsl.minecraft.pixelpics.commands.PixelPicsCommand;
|
||||
import eu.mhsl.minecraft.pixelpics.render.render.DefaultScreenRenderer;
|
||||
import eu.mhsl.minecraft.pixelpics.render.render.Renderer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
public final class Main extends JavaPlugin {
|
||||
private static Main instance;
|
||||
private Renderer screenRenderer;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
extractJsonResources();
|
||||
|
||||
Bukkit.getPluginCommand("pixelPic").setExecutor(new PixelPicsCommand());
|
||||
|
||||
Bukkit.getPluginCommand("test").setExecutor((sender, command, label, args) -> {
|
||||
Material.getMaterial("acacia_button");
|
||||
Bukkit.broadcast(Component.text(Material.STONE.getBlockTranslationKey().replace("block.minecraft.", "")));
|
||||
|
||||
if(!(sender instanceof Player player))
|
||||
throw new IllegalStateException("Dieser Command kann nur von einem Spieler ausgeführt werden!");
|
||||
|
||||
File blockDir = new File(getDataFolder(), "models/block");
|
||||
for (File file : blockDir.listFiles()) {
|
||||
String blockName = file.getName().substring(0, file.getName().lastIndexOf('.'));
|
||||
Material material = Material.getMaterial(blockName.toUpperCase());
|
||||
System.out.println(material);
|
||||
if(material == null) {
|
||||
System.out.println(blockName);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
}
|
||||
|
||||
public void extractJsonResources() {
|
||||
String resourcePath = "models/block/"; // Pfad im JAR
|
||||
File outputDir = new File(getDataFolder(), resourcePath);
|
||||
if (outputDir.exists()) return;
|
||||
outputDir.mkdirs();
|
||||
|
||||
try {
|
||||
URL jarUrl = getClass().getProtectionDomain().getCodeSource().getLocation();
|
||||
File jarFile = new File(jarUrl.toURI());
|
||||
|
||||
try (JarFile jar = new JarFile(jarFile)) {
|
||||
Enumeration<JarEntry> entries = jar.entries();
|
||||
|
||||
while (entries.hasMoreElements()) {
|
||||
JarEntry entry = entries.nextElement();
|
||||
String entryName = entry.getName();
|
||||
|
||||
// Nur JSON-Dateien im gewünschten Ordner
|
||||
if (entryName.startsWith(resourcePath) && entryName.endsWith(".json")) {
|
||||
InputStream in = getResource(entryName);
|
||||
if (in == null) continue;
|
||||
|
||||
File outFile = new File(getDataFolder(), entryName);
|
||||
outFile.getParentFile().mkdirs(); // Ordnerstruktur sicherstellen
|
||||
|
||||
try (OutputStream out = new FileOutputStream(outFile)) {
|
||||
byte[] buffer = new byte[1024];
|
||||
int len;
|
||||
while ((len = in.read(buffer)) != -1) {
|
||||
out.write(buffer, 0, len);
|
||||
}
|
||||
System.out.println("Extrahiert: " + entryName);
|
||||
}
|
||||
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Renderer getScreenRenderer() {
|
||||
if(this.screenRenderer == null) this.screenRenderer = new DefaultScreenRenderer();
|
||||
return this.screenRenderer;
|
||||
}
|
||||
|
||||
public static Main getInstance() {
|
||||
return instance;
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package eu.mhsl.minecraft.pixelpics.commands;
|
||||
|
||||
import eu.mhsl.minecraft.pixelpics.ImageMapRenderer;
|
||||
import eu.mhsl.minecraft.pixelpics.Main;
|
||||
import eu.mhsl.minecraft.pixelpics.render.render.Resolution;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.MapMeta;
|
||||
import org.bukkit.map.MapView;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
|
||||
public class PixelPicsCommand implements CommandExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String @NotNull [] args) {
|
||||
if(!(sender instanceof Player player))
|
||||
throw new IllegalStateException("Dieser Command kann nur von einem Spieler ausgeführt werden!");
|
||||
|
||||
Resolution.Pixels pixels = Resolution.Pixels._128P;
|
||||
Resolution.AspectRatio aspectRatio = Resolution.AspectRatio._1_1;
|
||||
Resolution resolution = new Resolution(pixels, aspectRatio);
|
||||
|
||||
BufferedImage image = Main.getInstance().getScreenRenderer().render(player, resolution);
|
||||
|
||||
File file = new File(Main.getInstance().getDataFolder(), "Bild" + ".png");
|
||||
try {
|
||||
Main.getInstance().getDataFolder().mkdir();
|
||||
ImageIO.write(image, "png", file);
|
||||
} catch (Exception e) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ItemStack map = new ItemStack(Material.FILLED_MAP, 1);
|
||||
MapMeta meta = (MapMeta) map.getItemMeta();
|
||||
|
||||
MapView mapView = Bukkit.createMap(Bukkit.getWorlds().getFirst());
|
||||
mapView.getRenderers().forEach(mapView::removeRenderer);
|
||||
mapView.addRenderer(new ImageMapRenderer(image));
|
||||
|
||||
meta.setMapView(mapView);
|
||||
map.setItemMeta(meta);
|
||||
|
||||
player.getInventory().addItem(map);
|
||||
player.updateInventory();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.model;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import eu.mhsl.minecraft.pixelpics.render.model.MultiModel.MultiModelBuilder;
|
||||
import eu.mhsl.minecraft.pixelpics.render.model.CrossModel.CrossModelBuilder;
|
||||
import eu.mhsl.minecraft.pixelpics.render.model.StaticModel.StaticModelBuilder;
|
||||
import eu.mhsl.minecraft.pixelpics.render.model.OctahedronModel.OctahedronModelBuilder;
|
||||
import eu.mhsl.minecraft.pixelpics.render.model.SphereModel.SphereModelBuilder;
|
||||
|
||||
|
||||
public abstract class AbstractModel implements Model {
|
||||
|
||||
final int textureSize;
|
||||
final int[][] texture;
|
||||
|
||||
private final double transparencyFactor;
|
||||
private final double reflectionFactor;
|
||||
private final boolean occluding;
|
||||
|
||||
AbstractModel(int[][] texture, double transparencyFactor, double reflectionFactor,
|
||||
boolean occluding) {
|
||||
Preconditions.checkNotNull(texture);
|
||||
Preconditions.checkArgument(texture.length > 0, "texture cannot be empty");
|
||||
Preconditions.checkArgument(texture.length == texture[0].length, "texture must be a square array");
|
||||
|
||||
this.textureSize = texture.length;
|
||||
this.texture = texture;
|
||||
|
||||
this.transparencyFactor = transparencyFactor;
|
||||
this.reflectionFactor = reflectionFactor;
|
||||
this.occluding = occluding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTransparencyFactor() {
|
||||
return transparencyFactor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getReflectionFactor() {
|
||||
return reflectionFactor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOccluding() {
|
||||
return occluding;
|
||||
}
|
||||
|
||||
public static abstract class Builder {
|
||||
|
||||
final int[][] texture;
|
||||
|
||||
double transparencyFactor;
|
||||
double reflectionFactor;
|
||||
boolean occluding;
|
||||
|
||||
Builder(int[][] texture) {
|
||||
this.texture = texture;
|
||||
|
||||
this.transparencyFactor = 0;
|
||||
this.reflectionFactor = 0;
|
||||
this.occluding = false;
|
||||
}
|
||||
|
||||
public static SimpleModel.SimpleModelBuilder createSimple(int[][] texture) {
|
||||
return new SimpleModel.SimpleModelBuilder(texture);
|
||||
}
|
||||
|
||||
public static MultiModelBuilder createMulti(int[][] topTexture, int[][] sideTexture,
|
||||
int[][] bottomTexture) {
|
||||
return new MultiModelBuilder(topTexture, sideTexture, bottomTexture);
|
||||
}
|
||||
|
||||
public static StaticModelBuilder createStatic(int color) {
|
||||
return new StaticModelBuilder(color);
|
||||
}
|
||||
|
||||
public static CrossModelBuilder createCross(int[][] texture) {
|
||||
return new CrossModelBuilder(texture);
|
||||
}
|
||||
|
||||
public static SphereModelBuilder createSphere(int[][] texture) {
|
||||
return new SphereModelBuilder(texture);
|
||||
}
|
||||
|
||||
public static OctahedronModelBuilder createOctahedron(int[][] texture) {
|
||||
return new OctahedronModelBuilder(texture);
|
||||
}
|
||||
|
||||
public Builder transparency(double transparencyFactor) {
|
||||
this.transparencyFactor = transparencyFactor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder reflection(double reflectionFactor) {
|
||||
this.reflectionFactor = reflectionFactor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder occlusion() {
|
||||
this.occluding = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public abstract Model build();
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.model;
|
||||
|
||||
import eu.mhsl.minecraft.pixelpics.render.util.Intersection;
|
||||
import eu.mhsl.minecraft.pixelpics.render.util.MathUtil;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class CrossModel extends AbstractModel {
|
||||
|
||||
private static final Vector NORMAL_ONE = new Vector(1, 0, 1).normalize();
|
||||
private static final Vector NORMAL_TWO = new Vector(-1, 0, 1).normalize();
|
||||
|
||||
private static final Vector POINT_ONE = new Vector(1, 0, 0);
|
||||
private static final Vector POINT_TWO = new Vector(1, 0, 1);
|
||||
|
||||
private CrossModel(int[][] texture, double transparencyFactor, double reflectionFactor,
|
||||
boolean occluding) {
|
||||
super(texture, transparencyFactor, reflectionFactor, occluding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intersection intersect(Block block, Intersection currentIntersection) {
|
||||
Vector linePoint = currentIntersection.getPoint();
|
||||
Vector lineDirection = currentIntersection.getDirection();
|
||||
|
||||
Vector blockPoint = block.getLocation().toVector();
|
||||
Vector planePoint = block.getLocation().add(0.5, 0, 0.5).toVector();
|
||||
|
||||
double distance = Double.POSITIVE_INFINITY;
|
||||
int color = 0;
|
||||
Vector target = null;
|
||||
|
||||
Vector intersectionOne = MathUtil.getLinePlaneIntersection(linePoint, lineDirection, planePoint, NORMAL_ONE,
|
||||
true);
|
||||
if (intersectionOne != null) {
|
||||
intersectionOne.subtract(blockPoint);
|
||||
if (isInsideBlock(intersectionOne)) {
|
||||
color = getColor(intersectionOne, POINT_ONE);
|
||||
distance = linePoint.distanceSquared(intersectionOne.add(blockPoint));
|
||||
target = intersectionOne;
|
||||
}
|
||||
}
|
||||
|
||||
Vector intersectionTwo = MathUtil.getLinePlaneIntersection(linePoint, lineDirection, planePoint, NORMAL_TWO,
|
||||
true);
|
||||
if (intersectionTwo != null) {
|
||||
intersectionTwo.subtract(blockPoint);
|
||||
if (isInsideBlock(intersectionTwo)) {
|
||||
int colorTwo = getColor(intersectionTwo, POINT_TWO);
|
||||
double distanceTwo = linePoint.distanceSquared(intersectionTwo.add(blockPoint));
|
||||
if ((distanceTwo < distance && (colorTwo >> 24) != 0) || (color >> 24) == 0) {
|
||||
target = intersectionTwo;
|
||||
color = colorTwo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (target == null) {
|
||||
target = linePoint;
|
||||
}
|
||||
|
||||
return Intersection.of(currentIntersection.getNormal(), target, lineDirection, color);
|
||||
}
|
||||
|
||||
private boolean isInsideBlock(Vector vec) {
|
||||
return vec.getX() >= 0 && vec.getZ() < 1 && vec.getY() >= 0 && vec.getY() < 1 && vec.getZ() >= 0
|
||||
&& vec.getZ() < 1;
|
||||
}
|
||||
|
||||
private int getColor(Vector vec, Vector base) {
|
||||
double xOffset = Math.sqrt(Math.pow(vec.getX() - base.getX(), 2) + Math.pow(vec.getZ() - base.getZ(), 2));
|
||||
double yOffset = vec.getY();
|
||||
|
||||
int pixelY = (int) Math.floor(yOffset * textureSize);
|
||||
int pixelX = (int) Math.floor(xOffset / Math.sqrt(2) * textureSize);
|
||||
|
||||
return texture[pixelY][pixelX];
|
||||
}
|
||||
|
||||
public static class CrossModelBuilder extends Builder {
|
||||
|
||||
CrossModelBuilder(int[][] texture) {
|
||||
super(texture);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CrossModel build() {
|
||||
return new CrossModel(texture, transparencyFactor, reflectionFactor, occluding);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.model;
|
||||
|
||||
import eu.mhsl.minecraft.pixelpics.render.util.Intersection;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
public interface Model {
|
||||
|
||||
Intersection intersect(Block block, Intersection currentIntersection);
|
||||
|
||||
double getTransparencyFactor();
|
||||
|
||||
double getReflectionFactor();
|
||||
|
||||
boolean isOccluding();
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.model;
|
||||
|
||||
import eu.mhsl.minecraft.pixelpics.render.util.Intersection;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class MultiModel extends SimpleModel {
|
||||
|
||||
private final int[][] topTexture;
|
||||
private final int[][] bottomTexture;
|
||||
|
||||
private MultiModel(int[][] topTexture, int[][] sideTexture, int[][] bottomTexture,
|
||||
double transparencyFactor, double reflectionFactor, boolean occluding) {
|
||||
super(sideTexture, transparencyFactor, reflectionFactor, occluding);
|
||||
|
||||
this.topTexture = topTexture;
|
||||
this.bottomTexture = bottomTexture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intersection intersect(Block block, Intersection currentIntersection) {
|
||||
if (!currentIntersection.getNormal().equals(UP) && !currentIntersection.getNormal().equals(DOWN)) {
|
||||
return super.intersect(block, currentIntersection);
|
||||
}
|
||||
|
||||
Vector normal = currentIntersection.getNormal();
|
||||
Vector point = currentIntersection.getPoint();
|
||||
Vector direction = currentIntersection.getDirection();
|
||||
|
||||
double yOffset = point.getX() - (int) point.getX();
|
||||
double xOffset = point.getZ() - (int) point.getZ();
|
||||
|
||||
int pixelY = (int) Math.floor((yOffset < 0 ? yOffset + 1 : yOffset) * textureSize);
|
||||
int pixelX = (int) Math.floor((xOffset < 0 ? xOffset + 1 : xOffset) * textureSize);
|
||||
|
||||
if (normal.equals(UP)) {
|
||||
return Intersection.of(normal, point, direction, topTexture[pixelY][pixelX]);
|
||||
} else {
|
||||
return Intersection.of(normal, point, direction, bottomTexture[pixelY][pixelX]);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MultiModelBuilder extends SimpleModelBuilder {
|
||||
|
||||
private final int[][] topTexture;
|
||||
private final int[][] bottomTexture;
|
||||
|
||||
MultiModelBuilder(int[][] topTexture, int[][] sideTexture, int[][] bottomTexture) {
|
||||
super(sideTexture);
|
||||
|
||||
this.topTexture = topTexture;
|
||||
this.bottomTexture = bottomTexture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiModel build() {
|
||||
return new MultiModel(topTexture, texture, bottomTexture, transparencyFactor,
|
||||
reflectionFactor, occluding);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.model;
|
||||
|
||||
import eu.mhsl.minecraft.pixelpics.render.util.Intersection;
|
||||
import eu.mhsl.minecraft.pixelpics.render.util.MathUtil;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class OctahedronModel extends AbstractModel {
|
||||
|
||||
private static final double RADIUS = 0.5;
|
||||
|
||||
private static final Vector[] NORMALS = new Vector[]{new Vector(-1, -1, -1), new Vector(-1, -1, 1),
|
||||
new Vector(-1, 1, -1), new Vector(-1, 1, 1), new Vector(1, -1, -1), new Vector(1, -1, 1),
|
||||
new Vector(1, 1, -1), new Vector(1, 1, 1)};
|
||||
|
||||
private OctahedronModel(int[][] texture, double transparencyFactor, double reflectionFactor,
|
||||
boolean occluding) {
|
||||
super(texture, transparencyFactor, reflectionFactor, occluding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intersection intersect(Block block, Intersection currentIntersection) {
|
||||
Vector linePoint = currentIntersection.getPoint();
|
||||
Vector lineDirection = currentIntersection.getDirection();
|
||||
Vector blockPoint = block.getLocation().toVector();
|
||||
Vector centerPoint = blockPoint.clone().add(new Vector(0.5, 0.5, 0.5));
|
||||
|
||||
Vector lastIntersection = null;
|
||||
double lastDistance = Double.POSITIVE_INFINITY;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
Vector planePoint = new Vector(i < 4 ? -0.5 : 0.5, 0, 0).add(centerPoint);
|
||||
Vector planeNormal = NORMALS[i];
|
||||
|
||||
Vector intersection = MathUtil.getLinePlaneIntersection(linePoint, lineDirection, planePoint, planeNormal,
|
||||
false);
|
||||
if (intersection == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isInsideBlock(blockPoint, planeNormal, intersection)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
double distance = intersection.distance(linePoint);
|
||||
if (distance < lastDistance) {
|
||||
lastIntersection = intersection;
|
||||
lastDistance = distance;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastIntersection == null) {
|
||||
return currentIntersection;
|
||||
}
|
||||
|
||||
double dist = linePoint.distance(centerPoint);
|
||||
double minDist = dist - RADIUS;
|
||||
double maxDist = dist + RADIUS;
|
||||
double factor = (lastDistance - minDist) / (maxDist - minDist);
|
||||
|
||||
double yOffset = lastIntersection.getX() - (int) lastIntersection.getX();
|
||||
double xOffset = lastIntersection.getZ() - (int) lastIntersection.getZ();
|
||||
|
||||
int pixelY = (int) Math.floor((yOffset < 0 ? yOffset + 1 : yOffset) * textureSize);
|
||||
int pixelX = (int) Math.floor((xOffset < 0 ? xOffset + 1 : xOffset) * textureSize);
|
||||
|
||||
return Intersection.of(currentIntersection.getNormal(), lastIntersection, lineDirection,
|
||||
0xFF000000 | MathUtil.weightedColorSum(texture[pixelY][pixelX], 0, 1 - factor, factor));
|
||||
}
|
||||
|
||||
private boolean isInsideBlock(Vector blockPoint, Vector planeNormal, Vector intersection) {
|
||||
intersection = intersection.clone().subtract(blockPoint);
|
||||
|
||||
if (intersection.getX() < 0 || intersection.getX() >= 1 || intersection.getY() < 0 || intersection.getY() >= 1
|
||||
|| intersection.getZ() < 0 || intersection.getZ() >= 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean posX = planeNormal.getX() >= 0;
|
||||
boolean posY = planeNormal.getY() >= 0;
|
||||
boolean posZ = planeNormal.getZ() >= 0;
|
||||
|
||||
boolean blockX = intersection.getX() >= 0.5;
|
||||
boolean blockY = intersection.getY() >= 0.5;
|
||||
boolean blockZ = intersection.getZ() >= 0.5;
|
||||
|
||||
return posX == blockX && posY == blockY && posZ == blockZ;
|
||||
}
|
||||
|
||||
public static class OctahedronModelBuilder extends Builder {
|
||||
|
||||
OctahedronModelBuilder(int[][] texture) {
|
||||
super(texture);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model build() {
|
||||
return new OctahedronModel(texture, transparencyFactor, reflectionFactor, occluding);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.model;
|
||||
|
||||
import eu.mhsl.minecraft.pixelpics.render.util.Intersection;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class SimpleModel extends AbstractModel {
|
||||
|
||||
static final Vector UP = new Vector(0, 1, 0);
|
||||
static final Vector DOWN = new Vector(0, -1, 0);
|
||||
private static final Vector NORTH = new Vector(0, 0, -1);
|
||||
private static final Vector SOUTH = new Vector(0, 0, 1);
|
||||
private static final Vector EAST = new Vector(1, 0, 0);
|
||||
private static final Vector WEST = new Vector(-1, 0, 0);
|
||||
|
||||
SimpleModel(int[][] texture, double transparencyFactor, double reflectionFactor,
|
||||
boolean occluding) {
|
||||
super(texture, transparencyFactor, reflectionFactor, occluding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intersection intersect(Block block, Intersection currentIntersection) {
|
||||
double yOffset;
|
||||
double xOffset;
|
||||
|
||||
Vector normal = currentIntersection.getNormal();
|
||||
Vector point = currentIntersection.getPoint();
|
||||
Vector direction = currentIntersection.getDirection();
|
||||
|
||||
if (normal.equals(NORTH) || normal.equals(SOUTH)) {
|
||||
yOffset = point.getY() - (int) point.getY();
|
||||
xOffset = point.getX() - (int) point.getX();
|
||||
} else if (normal.equals(EAST) || normal.equals(WEST)) {
|
||||
yOffset = point.getY() - (int) point.getY();
|
||||
xOffset = point.getZ() - (int) point.getZ();
|
||||
} else {
|
||||
yOffset = point.getX() - (int) point.getX();
|
||||
xOffset = point.getZ() - (int) point.getZ();
|
||||
}
|
||||
|
||||
int pixelY = (int) Math.floor((yOffset < 0 ? yOffset + 1 : yOffset) * textureSize);
|
||||
int pixelX = (int) Math.floor((xOffset < 0 ? xOffset + 1 : xOffset) * textureSize);
|
||||
|
||||
return Intersection.of(normal, point, direction, texture[pixelY][pixelX]);
|
||||
}
|
||||
|
||||
public static class SimpleModelBuilder extends Builder {
|
||||
|
||||
protected SimpleModelBuilder(int[][] texture) {
|
||||
super(texture);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model build() {
|
||||
return new SimpleModel(texture, transparencyFactor, reflectionFactor, occluding);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.model;
|
||||
|
||||
import eu.mhsl.minecraft.pixelpics.render.util.Intersection;
|
||||
import eu.mhsl.minecraft.pixelpics.render.util.MathUtil;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class SphereModel extends AbstractModel {
|
||||
|
||||
private final double radius;
|
||||
private final Vector offset;
|
||||
|
||||
private SphereModel(int[][] texture, double transparencyFactor, double reflectionFactor,
|
||||
boolean occluding, double radius, Vector offset) {
|
||||
super(texture, transparencyFactor, reflectionFactor, occluding);
|
||||
|
||||
this.radius = radius;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intersection intersect(Block block, Intersection currentIntersection) {
|
||||
Vector linePoint = currentIntersection.getPoint();
|
||||
Vector lineDirection = currentIntersection.getDirection();
|
||||
Vector blockPoint = block.getLocation().toVector();
|
||||
Vector centerPoint = block.getLocation().add(0.5, 0.5, 0.5).add(offset).toVector();
|
||||
|
||||
double a = lineDirection.dot(lineDirection);
|
||||
double b = 2 * (linePoint.dot(lineDirection) - centerPoint.dot(lineDirection));
|
||||
double c = linePoint.dot(linePoint) - 2 * centerPoint.dot(linePoint) + centerPoint.dot(centerPoint)
|
||||
- Math.pow(radius, 2);
|
||||
|
||||
double delta = Math.pow(b, 2) - 4 * a * c;
|
||||
if (delta < 0) {
|
||||
return Intersection.of(currentIntersection.getNormal(), linePoint, lineDirection);
|
||||
}
|
||||
|
||||
double dist = linePoint.distance(centerPoint);
|
||||
double minDist = dist - radius;
|
||||
double maxDist = dist + radius;
|
||||
|
||||
if (delta == 0) {
|
||||
double t = -b / (2 * a);
|
||||
Vector intersection = lineDirection.clone().add(lineDirection.clone().multiply(t));
|
||||
if (!isInsideBlock(blockPoint, intersection)) {
|
||||
return currentIntersection;
|
||||
}
|
||||
double currentDist = intersection.distance(linePoint);
|
||||
double factor = (currentDist - minDist) / (maxDist - minDist);
|
||||
Vector normal = intersection.clone().subtract(centerPoint).normalize();
|
||||
return Intersection.of(normal, intersection, lineDirection, getColor(centerPoint, intersection, factor));
|
||||
}
|
||||
|
||||
double deltaSqrt = Math.sqrt(delta);
|
||||
|
||||
double tOne = (-b + deltaSqrt) / (2 * a);
|
||||
double tTwo = (-b - deltaSqrt) / (2 * a);
|
||||
|
||||
Vector intersectionOne = linePoint.clone().add(lineDirection.clone().multiply(tOne));
|
||||
Vector intersectionTwo = linePoint.clone().add(lineDirection.clone().multiply(tTwo));
|
||||
|
||||
boolean first = intersectionOne.distanceSquared(linePoint) < intersectionTwo.distanceSquared(linePoint);
|
||||
double currentDist = (first ? intersectionOne : intersectionTwo).distance(linePoint);
|
||||
double factor = (currentDist - minDist) / (maxDist - minDist);
|
||||
if (first && isInsideBlock(blockPoint, intersectionOne)) {
|
||||
Vector normal = intersectionOne.clone().subtract(centerPoint).normalize();
|
||||
return Intersection.of(normal, intersectionOne, lineDirection,
|
||||
getColor(centerPoint, intersectionOne, factor));
|
||||
} else if (isInsideBlock(blockPoint, intersectionTwo)) {
|
||||
Vector normal = intersectionTwo.clone().subtract(centerPoint).normalize();
|
||||
return Intersection.of(normal, intersectionTwo, lineDirection,
|
||||
getColor(centerPoint, intersectionTwo, factor));
|
||||
} else {
|
||||
return currentIntersection;
|
||||
}
|
||||
}
|
||||
|
||||
private int getColor(Vector base, Vector intersection, double factor) {
|
||||
Location loc = base.toLocation(null);
|
||||
loc.setDirection(intersection.clone().subtract(base).normalize());
|
||||
|
||||
double perimeter = Math.round(2 * Math.PI * radius);
|
||||
double yawDiv = 360 / perimeter;
|
||||
double pitchDiv = 180 / perimeter;
|
||||
|
||||
int pixelX = (int) ((loc.getYaw() % yawDiv) / (yawDiv / textureSize));
|
||||
int pixelY = (int) (((loc.getPitch() + 90) % pitchDiv) / (pitchDiv / textureSize));
|
||||
|
||||
return 0xFF000000 | MathUtil.weightedColorSum(texture[pixelY][pixelX], 0, 1 - factor, factor);
|
||||
}
|
||||
|
||||
private boolean isInsideBlock(Vector blockPoint, Vector intersection) {
|
||||
intersection = intersection.clone().subtract(blockPoint);
|
||||
|
||||
return intersection.getX() >= 0 && intersection.getX() < 1 && intersection.getY() >= 0
|
||||
&& intersection.getY() < 1 && intersection.getZ() >= 0 && intersection.getZ() < 1;
|
||||
}
|
||||
|
||||
public static class SphereModelBuilder extends Builder {
|
||||
|
||||
private double radius;
|
||||
private Vector offset;
|
||||
|
||||
SphereModelBuilder(int[][] texture) {
|
||||
super(texture);
|
||||
|
||||
this.radius = 0.5;
|
||||
this.offset = new Vector();
|
||||
}
|
||||
|
||||
public SphereModelBuilder radius(double radius) {
|
||||
this.radius = radius;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SphereModelBuilder offset(Vector offset) {
|
||||
this.offset = offset.clone();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model build() {
|
||||
return new SphereModel(texture, transparencyFactor, reflectionFactor, occluding, radius,
|
||||
offset);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.model;
|
||||
|
||||
import eu.mhsl.minecraft.pixelpics.render.model.AbstractModel.Builder;
|
||||
import eu.mhsl.minecraft.pixelpics.render.util.Intersection;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
public class StaticModel implements Model {
|
||||
|
||||
private final int color;
|
||||
private final double transparencyFactor;
|
||||
private final double reflectionFactor;
|
||||
private final boolean occluding;
|
||||
|
||||
private StaticModel(int color, double transparencyFactor, double reflectionFactor, boolean occluding) {
|
||||
this.color = color;
|
||||
this.transparencyFactor = transparencyFactor;
|
||||
this.reflectionFactor = reflectionFactor;
|
||||
this.occluding = occluding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intersection intersect(Block block, Intersection currentIntersection) {
|
||||
return Intersection.of(currentIntersection.getNormal(), currentIntersection.getPoint(),
|
||||
currentIntersection.getDirection(), color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTransparencyFactor() {
|
||||
return transparencyFactor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getReflectionFactor() {
|
||||
return reflectionFactor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOccluding() {
|
||||
return occluding;
|
||||
}
|
||||
|
||||
public static class StaticModelBuilder extends Builder {
|
||||
|
||||
private final int color;
|
||||
|
||||
StaticModelBuilder(int color) {
|
||||
super(new int[1][1]);
|
||||
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StaticModel build() {
|
||||
return new StaticModel(color, transparencyFactor, reflectionFactor, occluding);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.raytrace;
|
||||
|
||||
import eu.mhsl.minecraft.pixelpics.render.model.Model;
|
||||
import eu.mhsl.minecraft.pixelpics.render.registry.AdvancedModelRegistry;
|
||||
import eu.mhsl.minecraft.pixelpics.render.util.BlockRaytracer;
|
||||
import eu.mhsl.minecraft.pixelpics.render.util.Intersection;
|
||||
import eu.mhsl.minecraft.pixelpics.render.util.MathUtil;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class AdvancedRaytracer implements Raytracer {
|
||||
private final int maxDistance;
|
||||
private final int reflectionDepth;
|
||||
|
||||
private final AdvancedModelRegistry textureRegistry;
|
||||
private Block reflectedBlock;
|
||||
|
||||
public AdvancedRaytracer() {
|
||||
this(300, 10);
|
||||
}
|
||||
|
||||
public AdvancedRaytracer(int maxDistance, int reflectionDepth) {
|
||||
this.maxDistance = maxDistance;
|
||||
this.reflectionDepth = reflectionDepth;
|
||||
|
||||
this.textureRegistry = new AdvancedModelRegistry();
|
||||
this.textureRegistry.initialize();
|
||||
|
||||
this.reflectedBlock = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int trace(World world, Vector point, Vector direction) {
|
||||
return trace(world, point, direction, reflectionDepth);
|
||||
}
|
||||
|
||||
private int trace(World world, Vector point, Vector direction, int reflectionDepth) {
|
||||
Location loc = point.toLocation(world);
|
||||
loc.setDirection(direction);
|
||||
BlockRaytracer iterator = new BlockRaytracer(loc);
|
||||
int baseColor = Color.fromRGB(65, 89, 252).asRGB();
|
||||
Vector finalIntersection = null;
|
||||
|
||||
int reflectionColor = 0;
|
||||
double reflectionFactor = 0;
|
||||
boolean reflected = false;
|
||||
|
||||
Vector transparencyStart = null;
|
||||
int transparencyColor = 0;
|
||||
double transparencyFactor = 0;
|
||||
|
||||
Material occlusionMaterial = null;
|
||||
BlockData occlusionData = null;
|
||||
|
||||
for (int i = 0; i < maxDistance; i++) {
|
||||
if (!iterator.hasNext()) break;
|
||||
Block block = iterator.next();
|
||||
if (reflectedBlock != null && reflectedBlock.equals(block)) continue;
|
||||
reflectedBlock = null;
|
||||
|
||||
Material material = block.getType();
|
||||
if (material == Material.AIR) {
|
||||
occlusionMaterial = null;
|
||||
occlusionData = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
Model textureModel = textureRegistry.getModel(block.getType(), block.getBlockData(), block.getTemperature(), block.getHumidity());
|
||||
Intersection currentIntersection = Intersection.of(
|
||||
MathUtil.toVector(iterator.getIntersectionFace()),
|
||||
i == 0 ? point : iterator.getIntersectionPoint(),
|
||||
direction
|
||||
);
|
||||
Intersection newIntersection = textureModel.intersect(block, currentIntersection);
|
||||
|
||||
if (newIntersection == null) continue;
|
||||
|
||||
int color = newIntersection.getColor();
|
||||
|
||||
if (!reflected && textureModel.getReflectionFactor() > 0 && reflectionDepth > 0 && (color >> 24) != 0) {
|
||||
reflectedBlock = block;
|
||||
reflectionColor = trace(
|
||||
world,
|
||||
newIntersection.getPoint(),
|
||||
MathUtil.reflectVector(
|
||||
point,
|
||||
direction,
|
||||
newIntersection.getPoint(),
|
||||
newIntersection.getNormal()
|
||||
),
|
||||
reflectionDepth - 1
|
||||
);
|
||||
reflectionFactor = textureModel.getReflectionFactor();
|
||||
reflected = true;
|
||||
}
|
||||
|
||||
if (transparencyStart == null && textureModel.getTransparencyFactor() > 0) {
|
||||
transparencyStart = newIntersection.getPoint();
|
||||
transparencyColor = newIntersection.getColor();
|
||||
transparencyFactor = textureModel.getTransparencyFactor();
|
||||
}
|
||||
|
||||
if (textureModel.isOccluding()) {
|
||||
BlockData data = block.getBlockData();
|
||||
|
||||
if (material == occlusionMaterial && data.equals(occlusionData)) continue;
|
||||
|
||||
occlusionMaterial = material;
|
||||
occlusionData = data;
|
||||
} else {
|
||||
occlusionMaterial = null;
|
||||
occlusionData = null;
|
||||
}
|
||||
|
||||
if (transparencyStart != null && textureModel.getTransparencyFactor() > 0) continue;
|
||||
if ((color >> 24) == 0) continue;
|
||||
|
||||
baseColor = color;
|
||||
finalIntersection = newIntersection.getPoint();
|
||||
break;
|
||||
}
|
||||
|
||||
if (transparencyStart != null) {
|
||||
baseColor = MathUtil.weightedColorSum(
|
||||
baseColor,
|
||||
transparencyColor,
|
||||
transparencyFactor,
|
||||
(1
|
||||
- transparencyFactor)
|
||||
* (1 + transparencyStart.distance(finalIntersection == null ? transparencyStart : finalIntersection)
|
||||
/ 5.0));
|
||||
}
|
||||
if (reflected) {
|
||||
baseColor = MathUtil.weightedColorSum(
|
||||
baseColor,
|
||||
reflectionColor,
|
||||
1 - reflectionFactor,
|
||||
reflectionFactor
|
||||
);
|
||||
}
|
||||
|
||||
return baseColor & 0xFFFFFF;
|
||||
}
|
||||
}
|
@ -0,0 +1,152 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.raytrace;
|
||||
|
||||
import eu.mhsl.minecraft.pixelpics.render.model.Model;
|
||||
import eu.mhsl.minecraft.pixelpics.render.registry.AdvancedModelRegistry;
|
||||
import eu.mhsl.minecraft.pixelpics.render.registry.ModelRegistry;
|
||||
import eu.mhsl.minecraft.pixelpics.render.util.BlockRaytracer;
|
||||
import eu.mhsl.minecraft.pixelpics.render.util.Intersection;
|
||||
import eu.mhsl.minecraft.pixelpics.render.util.MathUtil;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class DefaultRaytracer implements Raytracer {
|
||||
private final int maxDistance;
|
||||
private final int reflectionDepth;
|
||||
|
||||
private final ModelRegistry textureRegistry;
|
||||
private Block reflectedBlock;
|
||||
|
||||
public DefaultRaytracer() {
|
||||
this(300, 10);
|
||||
}
|
||||
|
||||
public DefaultRaytracer(int maxDistance, int reflectionDepth) {
|
||||
this.maxDistance = maxDistance;
|
||||
this.reflectionDepth = reflectionDepth;
|
||||
|
||||
this.textureRegistry = new AdvancedModelRegistry();
|
||||
this.textureRegistry.initialize();
|
||||
|
||||
this.reflectedBlock = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int trace(World world, Vector point, Vector direction) {
|
||||
return trace(world, point, direction, reflectionDepth);
|
||||
}
|
||||
|
||||
private int trace(World world, Vector point, Vector direction, int reflectionDepth) {
|
||||
Location loc = point.toLocation(world);
|
||||
loc.setDirection(direction);
|
||||
BlockRaytracer iterator = new BlockRaytracer(loc);
|
||||
int baseColor = Color.fromRGB(65, 89, 252).asRGB();
|
||||
Vector finalIntersection = null;
|
||||
|
||||
int reflectionColor = 0;
|
||||
double reflectionFactor = 0;
|
||||
boolean reflected = false;
|
||||
|
||||
Vector transparencyStart = null;
|
||||
int transparencyColor = 0;
|
||||
double transparencyFactor = 0;
|
||||
|
||||
Material occlusionMaterial = null;
|
||||
BlockData occlusionData = null;
|
||||
|
||||
for (int i = 0; i < maxDistance; i++) {
|
||||
if (!iterator.hasNext()) break;
|
||||
Block block = iterator.next();
|
||||
if (reflectedBlock != null && reflectedBlock.equals(block)) continue;
|
||||
reflectedBlock = null;
|
||||
|
||||
Material material = block.getType();
|
||||
if (material == Material.AIR) {
|
||||
occlusionMaterial = null;
|
||||
occlusionData = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
Biome biome = block.getBiome();
|
||||
Model textureModel = textureRegistry.getModel(block);
|
||||
Intersection currentIntersection = Intersection.of(
|
||||
MathUtil.toVector(iterator.getIntersectionFace()),
|
||||
i == 0 ? point : iterator.getIntersectionPoint(),
|
||||
direction
|
||||
);
|
||||
Intersection newIntersection = textureModel.intersect(block, currentIntersection);
|
||||
|
||||
if (newIntersection == null) continue;
|
||||
|
||||
int color = newIntersection.getColor();
|
||||
|
||||
if (!reflected && textureModel.getReflectionFactor() > 0 && reflectionDepth > 0 && (color >> 24) != 0) {
|
||||
reflectedBlock = block;
|
||||
reflectionColor = trace(
|
||||
world,
|
||||
newIntersection.getPoint(),
|
||||
MathUtil.reflectVector(
|
||||
point,
|
||||
direction,
|
||||
newIntersection.getPoint(),
|
||||
newIntersection.getNormal()
|
||||
),
|
||||
reflectionDepth - 1
|
||||
);
|
||||
reflectionFactor = textureModel.getReflectionFactor();
|
||||
reflected = true;
|
||||
}
|
||||
|
||||
if (transparencyStart == null && textureModel.getTransparencyFactor() > 0) {
|
||||
transparencyStart = newIntersection.getPoint();
|
||||
transparencyColor = newIntersection.getColor();
|
||||
transparencyFactor = textureModel.getTransparencyFactor();
|
||||
}
|
||||
|
||||
if (textureModel.isOccluding()) {
|
||||
BlockData data = block.getBlockData();
|
||||
|
||||
if (material == occlusionMaterial && data.equals(occlusionData)) continue;
|
||||
|
||||
occlusionMaterial = material;
|
||||
occlusionData = data;
|
||||
} else {
|
||||
occlusionMaterial = null;
|
||||
occlusionData = null;
|
||||
}
|
||||
|
||||
if (transparencyStart != null && textureModel.getTransparencyFactor() > 0) continue;
|
||||
if ((color >> 24) == 0) continue;
|
||||
|
||||
baseColor = color;
|
||||
finalIntersection = newIntersection.getPoint();
|
||||
break;
|
||||
}
|
||||
|
||||
if (transparencyStart != null) {
|
||||
baseColor = MathUtil.weightedColorSum(
|
||||
baseColor,
|
||||
transparencyColor,
|
||||
transparencyFactor,
|
||||
(1
|
||||
- transparencyFactor)
|
||||
* (1 + transparencyStart.distance(finalIntersection == null ? transparencyStart : finalIntersection)
|
||||
/ 5.0));
|
||||
}
|
||||
if (reflected) {
|
||||
baseColor = MathUtil.weightedColorSum(
|
||||
baseColor,
|
||||
reflectionColor,
|
||||
1 - reflectionFactor,
|
||||
reflectionFactor
|
||||
);
|
||||
}
|
||||
|
||||
return baseColor & 0xFFFFFF;
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.raytrace;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public interface Raytracer {
|
||||
|
||||
int trace(World world, Vector point, Vector direction);
|
||||
}
|
157
src/main/java/eu/mhsl/minecraft/pixelpics/render/registry/AdvancedModelRegistry.java
Normal file
157
src/main/java/eu/mhsl/minecraft/pixelpics/render/registry/AdvancedModelRegistry.java
Normal file
@ -0,0 +1,157 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.registry;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import eu.mhsl.minecraft.pixelpics.Main;
|
||||
import eu.mhsl.minecraft.pixelpics.render.model.AbstractModel;
|
||||
import eu.mhsl.minecraft.pixelpics.render.model.Model;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
|
||||
import static eu.mhsl.minecraft.pixelpics.render.registry.DefaultModelRegistry.TEXTURE_SIZE;
|
||||
|
||||
public class AdvancedModelRegistry implements ModelRegistry {
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
private final Map<Material, Map<BlockData, Model>> modelMap = new HashMap<>();
|
||||
private final Set<String> tintedBlocks = Set.of("grass", "grass_block", "leaves", "oak_leaves", "water", "vine", "sugar_cane");
|
||||
|
||||
public record BlockInfo(String parent, BlockTextures textures){}
|
||||
public record BlockTextures(
|
||||
String texture,
|
||||
String bottom,
|
||||
String top,
|
||||
String all,
|
||||
String particle,
|
||||
String end,
|
||||
String side,
|
||||
String cross,
|
||||
String rail,
|
||||
String overlay
|
||||
){}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
System.out.println(modelMap);
|
||||
|
||||
File blockDir = new File(Main.getInstance().getDataFolder(), "models/block");
|
||||
for (File file : Objects.requireNonNull(blockDir.listFiles())) {
|
||||
addModelFromFile(file);
|
||||
}
|
||||
|
||||
try {
|
||||
registerModel(Material.LAVA, AbstractModel.Builder.createSimple(getTextureArray("lava_still"))
|
||||
.transparency(0.15).reflection(0.05).occlusion().build());
|
||||
registerModel(Material.WATER, AbstractModel.Builder.createSimple(getTextureArray("water_still"))
|
||||
.transparency(0.60).reflection(0.1).occlusion().build());
|
||||
} catch (Exception ignored) { }
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model getModel(Block block) {
|
||||
return ModelRegistry.super.getModel(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model getModel(Material material, BlockData blockData) {
|
||||
return getModel(material, blockData, 0.8, 0.4);
|
||||
}
|
||||
|
||||
public Model getModel(Material material, BlockData blockData, double temperature, double humidity) {
|
||||
return modelMap.computeIfAbsent(material, key -> new HashMap<>()).getOrDefault(blockData,
|
||||
blockData == null ? getDefaultModel()
|
||||
: modelMap.get(material).getOrDefault(null, getDefaultModel()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model getDefaultModel() {
|
||||
return AbstractModel.Builder.createStatic(Color.PURPLE.asRGB()).build();
|
||||
}
|
||||
|
||||
private void registerModel(Material material, Model blockModel) {
|
||||
modelMap.computeIfAbsent(material, key -> new HashMap<>())
|
||||
.put(null, blockModel);
|
||||
}
|
||||
|
||||
private void addModelFromFile(File file) {
|
||||
String blockName = file.getName().substring(0, file.getName().lastIndexOf('.'));
|
||||
Material material = Material.getMaterial(blockName.toUpperCase());
|
||||
if(material == null) return;
|
||||
|
||||
Model model = getModelFromFile(file);
|
||||
if(model == null) return;
|
||||
|
||||
registerModel(material, model);
|
||||
}
|
||||
|
||||
private Model getModelFromFile(File file) {
|
||||
try (Reader reader = new FileReader(file)) {
|
||||
BlockInfo blockInfo = gson.fromJson(reader, BlockInfo.class);
|
||||
|
||||
if(blockInfo.textures.all != null) {
|
||||
return AbstractModel.Builder.createSimple(
|
||||
getTextureArray(blockInfo.textures.all.substring(blockInfo.textures.all.lastIndexOf('/') + 1))
|
||||
).build();
|
||||
}
|
||||
if(blockInfo.textures.cross != null) {
|
||||
return AbstractModel.Builder.createCross(
|
||||
getTextureArray(blockInfo.textures.cross.substring(blockInfo.textures.cross.lastIndexOf('/') + 1))
|
||||
).build();
|
||||
}
|
||||
if(blockInfo.textures.side != null && blockInfo.textures.bottom != null && blockInfo.textures.top != null) {
|
||||
return AbstractModel.Builder.createMulti(
|
||||
getTextureArray(blockInfo.textures.top.substring(blockInfo.textures.top.lastIndexOf('/') + 1)),
|
||||
getTextureArray(blockInfo.textures.side.substring(blockInfo.textures.side.lastIndexOf('/') + 1)),
|
||||
getTextureArray(blockInfo.textures.bottom.substring(blockInfo.textures.bottom.lastIndexOf('/') + 1))
|
||||
).build();
|
||||
}
|
||||
if(blockInfo.textures.side != null && blockInfo.textures.end != null) {
|
||||
return AbstractModel.Builder.createMulti(
|
||||
getTextureArray(blockInfo.textures.end.substring(blockInfo.textures.end.lastIndexOf('/') + 1)),
|
||||
getTextureArray(blockInfo.textures.side.substring(blockInfo.textures.side.lastIndexOf('/') + 1)),
|
||||
getTextureArray(blockInfo.textures.end.substring(blockInfo.textures.end.lastIndexOf('/') + 1))
|
||||
).build();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int[][] getTextureArray(String textureName) {
|
||||
int[][] texture = new int[TEXTURE_SIZE][TEXTURE_SIZE];
|
||||
BufferedImage img;
|
||||
URL url = this.getClass().getClassLoader().getResource(String.format("textures/block/%s.png", textureName));
|
||||
if (url == null) {
|
||||
throw new RuntimeException("Block Texture Resource not found.");
|
||||
}
|
||||
try (InputStream input = url.openConnection().getInputStream()) {
|
||||
img = ImageIO.read(input);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
for (int pixelY = 0; pixelY < TEXTURE_SIZE; pixelY++) {
|
||||
for (int pixelX = 0; pixelX < TEXTURE_SIZE; pixelX++) {
|
||||
texture[TEXTURE_SIZE - 1 - pixelY][TEXTURE_SIZE - 1 - pixelX] = img.getRGB(pixelX, pixelY);
|
||||
}
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
private int tintPixel(int baseColor, int tintColor) {
|
||||
int a = (baseColor >> 24) & 0xFF;
|
||||
int r = ((baseColor >> 16) & 0xFF) * ((tintColor >> 16) & 0xFF) / 255;
|
||||
int g = ((baseColor >> 8) & 0xFF) * ((tintColor >> 8) & 0xFF) / 255;
|
||||
int b = (baseColor & 0xFF) * (tintColor & 0xFF) / 255;
|
||||
return (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
@ -0,0 +1,169 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.registry;
|
||||
|
||||
import eu.mhsl.minecraft.pixelpics.render.model.AbstractModel.Builder;
|
||||
import eu.mhsl.minecraft.pixelpics.render.model.Model;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class DefaultModelRegistry implements ModelRegistry {
|
||||
|
||||
private static final String IMAGE_RESOURCE = "terrain.png";
|
||||
static final int TEXTURE_SIZE = 16;
|
||||
|
||||
private final Map<Material, Map<BlockData, Model>> modelMap;
|
||||
private BufferedImage textures;
|
||||
|
||||
public DefaultModelRegistry() {
|
||||
this.modelMap = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
URL url = this.getClass().getClassLoader().getResource(IMAGE_RESOURCE);
|
||||
if (url == null) {
|
||||
throw new RuntimeException("Default resource \"terrain.png\" is missing");
|
||||
}
|
||||
try (InputStream input = url.openConnection().getInputStream()) {
|
||||
this.textures = ImageIO.read(input);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
registerModel(Material.GRASS_BLOCK, Builder.createMulti(textureIndex(0, 0), textureIndex(0, 3), textureIndex(0, 2)).build());
|
||||
registerModel(Material.STONE, Builder.createSimple(textureIndex(0, 1)).build());
|
||||
registerModel(Material.DIRT, Builder.createSimple(textureIndex(0, 2)).build());
|
||||
registerModel(Material.OAK_PLANKS, Builder.createSimple(textureIndex(0, 4)).build());
|
||||
registerModel(Material.SPRUCE_PLANKS,
|
||||
Builder.createSimple(textureIndex(0, 4)).build());
|
||||
registerModel(Material.BIRCH_PLANKS,
|
||||
Builder.createSimple(textureIndex(0, 4)).build());
|
||||
registerModel(Material.JUNGLE_PLANKS,
|
||||
Builder.createSimple(textureIndex(0, 4)).build());
|
||||
registerModel(Material.ACACIA_PLANKS,
|
||||
Builder.createSimple(textureIndex(0, 4)).build());
|
||||
registerModel(Material.DARK_OAK_PLANKS,
|
||||
Builder.createSimple(textureIndex(0, 4)).build());
|
||||
registerModel(Material.BRICK, Builder.createSimple(textureIndex(0, 7)).build());
|
||||
registerModel(Material.TNT, Builder.createMulti(textureIndex(0, 9),
|
||||
textureIndex(0, 8), textureIndex(0, 10)).build());
|
||||
registerModel(Material.WATER, Builder.createStatic(0xFF000000 | Color.fromRGB(0, 5, 60).asRGB())
|
||||
.transparency(0.60).reflection(0.1).occlusion().build());
|
||||
registerModel(Material.DIAMOND_BLOCK,
|
||||
Builder.createSimple(textureIndex(3, 3)).reflection(0.75).build());
|
||||
registerModel(Material.POPPY, Builder.createCross(textureIndex(0, 12)).build());
|
||||
registerModel(Material.DANDELION, Builder.createCross(textureIndex(0, 13)).build());
|
||||
registerModel(Material.OAK_SAPLING,
|
||||
Builder.createCross(textureIndex(0, 15)).build());
|
||||
registerModel(Material.SPRUCE_SAPLING,
|
||||
Builder.createCross(textureIndex(0, 15)).build());
|
||||
registerModel(Material.BIRCH_SAPLING,
|
||||
Builder.createCross(textureIndex(0, 15)).build());
|
||||
registerModel(Material.JUNGLE_SAPLING,
|
||||
Builder.createCross(textureIndex(0, 15)).build());
|
||||
registerModel(Material.ACACIA_SAPLING,
|
||||
Builder.createCross(textureIndex(0, 15)).build());
|
||||
registerModel(Material.DARK_OAK_SAPLING,
|
||||
Builder.createCross(textureIndex(0, 15)).build());
|
||||
|
||||
registerModel(Material.COBBLESTONE,
|
||||
Builder.createSimple(textureIndex(1, 0)).build());
|
||||
registerModel(Material.BEDROCK, Builder.createSimple(textureIndex(1, 1)).build());
|
||||
registerModel(Material.SAND, Builder.createSimple(textureIndex(1, 2)).build());
|
||||
registerModel(Material.GRAVEL, Builder.createSimple(textureIndex(1, 3)).build());
|
||||
registerModel(Material.OAK_LOG, Builder.createMulti(textureIndex(1, 5),
|
||||
textureIndex(1, 4), textureIndex(1, 5)).build());
|
||||
registerModel(Material.SPRUCE_LOG, Builder.createMulti(textureIndex(1, 5),
|
||||
textureIndex(1, 4), textureIndex(1, 5)).build());
|
||||
registerModel(Material.BIRCH_LOG, Builder.createMulti(textureIndex(1, 5),
|
||||
textureIndex(1, 4), textureIndex(1, 5)).build());
|
||||
registerModel(Material.JUNGLE_LOG, Builder.createMulti(textureIndex(1, 5),
|
||||
textureIndex(1, 4), textureIndex(1, 5)).build());
|
||||
registerModel(Material.ACACIA_LOG, Builder.createMulti(textureIndex(1, 5),
|
||||
textureIndex(1, 4), textureIndex(1, 5)).build());
|
||||
registerModel(Material.DARK_OAK_LOG, Builder.createMulti(textureIndex(1, 5),
|
||||
textureIndex(1, 4), textureIndex(1, 5)).build());
|
||||
registerModel(Material.OAK_WOOD, Builder.createSimple(textureIndex(1, 4)).build());
|
||||
registerModel(Material.SPRUCE_WOOD,
|
||||
Builder.createSimple(textureIndex(1, 4)).build());
|
||||
registerModel(Material.BIRCH_WOOD, Builder.createSimple(textureIndex(1, 4)).build());
|
||||
registerModel(Material.JUNGLE_WOOD,
|
||||
Builder.createSimple(textureIndex(1, 4)).build());
|
||||
registerModel(Material.ACACIA_WOOD,
|
||||
Builder.createSimple(textureIndex(1, 4)).build());
|
||||
registerModel(Material.DARK_OAK_WOOD,
|
||||
Builder.createSimple(textureIndex(1, 4)).build());
|
||||
registerModel(Material.OAK_LEAVES, Builder.createSimple(textureIndex(1, 6)).build());
|
||||
registerModel(Material.SPRUCE_LEAVES,
|
||||
Builder.createSimple(textureIndex(1, 6)).build());
|
||||
registerModel(Material.BIRCH_LEAVES,
|
||||
Builder.createSimple(textureIndex(1, 6)).build());
|
||||
registerModel(Material.JUNGLE_LEAVES,
|
||||
Builder.createSimple(textureIndex(1, 6)).build());
|
||||
registerModel(Material.ACACIA_LEAVES,
|
||||
Builder.createSimple(textureIndex(1, 6)).build());
|
||||
registerModel(Material.DARK_OAK_LEAVES,
|
||||
Builder.createSimple(textureIndex(1, 6)).build());
|
||||
registerModel(Material.IRON_BLOCK,
|
||||
Builder.createMulti(textureIndex(1, 7),
|
||||
textureIndex(2, 7), textureIndex(3, 7)).build());
|
||||
registerModel(Material.GOLD_BLOCK, Builder.createMulti(textureIndex(1, 8),
|
||||
textureIndex(2, 8), textureIndex(3, 8)).build());
|
||||
registerModel(Material.RED_MUSHROOM,
|
||||
Builder.createCross(textureIndex(1, 12)).build());
|
||||
registerModel(Material.BROWN_MUSHROOM,
|
||||
Builder.createCross(textureIndex(1, 13)).build());
|
||||
registerModel(Material.LAVA, Builder.createSimple(textureIndex(2, 14))
|
||||
.transparency(0.15).reflection(0.05).occlusion().build());
|
||||
|
||||
registerModel(Material.GOLD_ORE, Builder.createSimple(textureIndex(2, 0)).build());
|
||||
registerModel(Material.IRON_ORE, Builder.createSimple(textureIndex(2, 1)).build());
|
||||
registerModel(Material.COAL_ORE, Builder.createSimple(textureIndex(2, 2)).build());
|
||||
|
||||
registerModel(Material.GLASS,
|
||||
Builder.createSimple(textureIndex(3, 1)).occlusion().build());
|
||||
|
||||
registerModel(Material.SHORT_GRASS, Builder.createCross(textureIndex(5, 6)).build());
|
||||
registerModel(Material.SUGAR_CANE, Builder.createCross(textureIndex(5, 5)).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model getModel(Material material, BlockData blockData) {
|
||||
return modelMap.computeIfAbsent(material, key -> new HashMap<>()).getOrDefault(blockData,
|
||||
blockData == null ? getDefaultModel()
|
||||
: modelMap.get(material).getOrDefault(null, getDefaultModel()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Model getDefaultModel() {
|
||||
return Builder.createStatic(Color.PURPLE.asRGB()).build();
|
||||
}
|
||||
|
||||
private void registerModel(Material material, Model blockModel) {
|
||||
modelMap.computeIfAbsent(material, key -> new HashMap<>())
|
||||
.put(null, blockModel);
|
||||
}
|
||||
|
||||
private int[][] textureIndex(int verticalIndex, int horizontalIndex) {
|
||||
int[][] texture = new int[TEXTURE_SIZE][TEXTURE_SIZE];
|
||||
|
||||
int offsetY = verticalIndex * TEXTURE_SIZE + (TEXTURE_SIZE - 1);
|
||||
int offsetX = horizontalIndex * TEXTURE_SIZE;
|
||||
|
||||
for (int pixelY = 0; pixelY < TEXTURE_SIZE; pixelY++) {
|
||||
for (int pixelX = 0; pixelX < TEXTURE_SIZE; pixelX++) {
|
||||
texture[pixelY][pixelX] = textures.getRGB(offsetX + pixelX, offsetY - pixelY);
|
||||
}
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.registry;
|
||||
|
||||
import eu.mhsl.minecraft.pixelpics.render.model.Model;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
public interface ModelRegistry {
|
||||
|
||||
void initialize();
|
||||
|
||||
default Model getModel(Block block) {
|
||||
return getModel(block.getType(), block.getBlockData());
|
||||
}
|
||||
|
||||
default Model getModel(Material material) {
|
||||
return getModel(material, null);
|
||||
}
|
||||
|
||||
Model getModel(Material material, BlockData blockData);
|
||||
|
||||
Model getDefaultModel();
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.render;
|
||||
|
||||
import eu.mhsl.minecraft.pixelpics.render.raytrace.DefaultRaytracer;
|
||||
import eu.mhsl.minecraft.pixelpics.render.raytrace.Raytracer;
|
||||
import eu.mhsl.minecraft.pixelpics.render.util.MathUtil;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DefaultScreenRenderer implements Renderer {
|
||||
|
||||
private static final double FOV_YAW_DEG = 53;
|
||||
private static final double FOV_PITCH_DEG = 23;
|
||||
|
||||
private static final double FOV_YAW_RAD = Math.toRadians(FOV_YAW_DEG);
|
||||
private static final double FOV_PITCH_RAD = Math.toRadians(FOV_PITCH_DEG);
|
||||
|
||||
private static final Vector BASE_VEC = new Vector(1, 0, 0);
|
||||
|
||||
private final Raytracer raytracer;
|
||||
|
||||
public DefaultScreenRenderer() {
|
||||
this.raytracer = new DefaultRaytracer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedImage render(Player player, Resolution resolution) {
|
||||
int width = resolution.getWidth();
|
||||
int height = resolution.getHeight();
|
||||
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
int[] imageData = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
|
||||
|
||||
World world = player.getWorld();
|
||||
Vector linePoint = player.getEyeLocation().toVector();
|
||||
List<Vector> rayMap = buildRayMap(player, resolution);
|
||||
for (int i = 0; i < rayMap.size(); i++) {
|
||||
imageData[i] = raytracer.trace(world, linePoint, rayMap.get(i));
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
private List<Vector> buildRayMap(Player p, Resolution resolution) {
|
||||
Location eyeLocation = p.getEyeLocation();
|
||||
Vector lineDirection = eyeLocation.getDirection();
|
||||
|
||||
double x = lineDirection.getX();
|
||||
double y = lineDirection.getY();
|
||||
double z = lineDirection.getZ();
|
||||
|
||||
double angleYaw = Math.atan2(z, x);
|
||||
double anglePitch = Math.atan2(y, Math.sqrt(x * x + z * z));
|
||||
|
||||
Vector lowerLeftCorner = MathUtil.doubleYawPitchRotation(BASE_VEC, -FOV_YAW_RAD, -FOV_PITCH_RAD, angleYaw, anglePitch);
|
||||
Vector upperLeftCorner = MathUtil.doubleYawPitchRotation(BASE_VEC, -FOV_YAW_RAD, FOV_PITCH_RAD, angleYaw, anglePitch);
|
||||
Vector lowerRightCorner = MathUtil.doubleYawPitchRotation(BASE_VEC, FOV_YAW_RAD, -FOV_PITCH_RAD, angleYaw, anglePitch);
|
||||
Vector upperRightCorner = MathUtil.doubleYawPitchRotation(BASE_VEC, FOV_YAW_RAD, FOV_PITCH_RAD, angleYaw, anglePitch);
|
||||
|
||||
int width = resolution.getWidth();
|
||||
int height = resolution.getHeight();
|
||||
List<Vector> rayMap = new ArrayList<>(width * height);
|
||||
|
||||
Vector leftFraction = upperLeftCorner.clone().subtract(lowerLeftCorner).multiply(1.0 / (height - 1));
|
||||
Vector rightFraction = upperRightCorner.clone().subtract(lowerRightCorner).multiply(1.0 / (height - 1));
|
||||
|
||||
for (int pitch = 0; pitch < height; pitch++) {
|
||||
|
||||
Vector leftPitch = upperLeftCorner.clone().subtract(leftFraction.clone().multiply(pitch));
|
||||
Vector rightPitch = upperRightCorner.clone().subtract(rightFraction.clone().multiply(pitch));
|
||||
Vector yawFraction = rightPitch.clone().subtract(leftPitch).multiply(1.0 / (width - 1));
|
||||
|
||||
for (int yaw = 0; yaw < width; yaw++) {
|
||||
Vector ray = leftPitch.clone().add(yawFraction.clone().multiply(yaw)).normalize();
|
||||
rayMap.add(ray);
|
||||
}
|
||||
}
|
||||
|
||||
return rayMap;
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.render;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public interface Renderer {
|
||||
|
||||
BufferedImage render(Player player, Resolution resolution);
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.render;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public final class Resolution {
|
||||
|
||||
private final int width;
|
||||
private final int height;
|
||||
|
||||
public Resolution(Pixels pixels, AspectRatio aspectRatio) {
|
||||
Preconditions.checkNotNull(pixels);
|
||||
Preconditions.checkNotNull(aspectRatio);
|
||||
|
||||
this.height = pixels.height;
|
||||
this.width = (int) Math.round(pixels.height * aspectRatio.ratio);
|
||||
}
|
||||
|
||||
public Resolution(int width, int height) {
|
||||
Preconditions.checkArgument(width > 0);
|
||||
Preconditions.checkArgument(height > 0);
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public enum Pixels {
|
||||
_128P(128, "128p"),
|
||||
_256P(256, "256p");
|
||||
|
||||
private final int height;
|
||||
private final List<String> aliases;
|
||||
|
||||
Pixels(int height, String... aliases) {
|
||||
this.height = height;
|
||||
this.aliases = Collections.unmodifiableList(Arrays.asList(aliases));
|
||||
}
|
||||
}
|
||||
|
||||
public enum AspectRatio {
|
||||
_1_1(1, "1:1"),
|
||||
_2_1(2, "2:1"),
|
||||
_3_2(3 / 2.0, "3:2");
|
||||
|
||||
private final double ratio;
|
||||
private final List<String> aliases;
|
||||
|
||||
AspectRatio(double ratio, String... aliases) {
|
||||
this.ratio = ratio;
|
||||
this.aliases = Collections.unmodifiableList(Arrays.asList(aliases));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.util;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.util.BlockIterator;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BlockRaytracer extends BlockIterator {
|
||||
|
||||
private final Vector position;
|
||||
private final Vector direction;
|
||||
|
||||
private Block lastBlock;
|
||||
private BlockFace currentFace;
|
||||
|
||||
public BlockRaytracer(Location loc) {
|
||||
super(loc);
|
||||
|
||||
this.position = loc.toVector();
|
||||
this.direction = loc.getDirection();
|
||||
}
|
||||
|
||||
public BlockFace getIntersectionFace() {
|
||||
if (currentFace == null) {
|
||||
throw new IllegalStateException("Called before next()");
|
||||
}
|
||||
|
||||
return currentFace;
|
||||
}
|
||||
|
||||
public Vector getIntersectionPoint() {
|
||||
BlockFace lastFace = getIntersectionFace();
|
||||
Vector planeNormal = new Vector(lastFace.getModX(), lastFace.getModY(), lastFace.getModZ());
|
||||
Vector planePoint = lastBlock.getLocation()
|
||||
.add(0.5, 0.5, 0.5)
|
||||
.toVector()
|
||||
.add(planeNormal.clone().multiply(0.5));
|
||||
|
||||
return MathUtil.getLinePlaneIntersection(position, direction, planePoint, planeNormal, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Block next() {
|
||||
Block currentBlock = super.next();
|
||||
currentFace = lastBlock == null ? BlockFace.SELF : currentBlock.getFace(lastBlock);
|
||||
|
||||
return (lastBlock = currentBlock);
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.util;
|
||||
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public final class Intersection {
|
||||
|
||||
private final Vector normal;
|
||||
private final Vector point;
|
||||
private final Vector direction;
|
||||
private final int color;
|
||||
|
||||
private Intersection(Vector normal, Vector point, Vector direction, int color) {
|
||||
this.normal = normal;
|
||||
this.point = point;
|
||||
this.direction = direction;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public Vector getNormal() {
|
||||
return normal;
|
||||
}
|
||||
|
||||
public Vector getPoint() {
|
||||
return point;
|
||||
}
|
||||
|
||||
public Vector getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public static Intersection of(Vector normal, Vector point, Vector direction) {
|
||||
return of(normal, point, direction, 0);
|
||||
}
|
||||
|
||||
public static Intersection of(Vector normal, Vector point, Vector direction, int color) {
|
||||
return new Intersection(normal, point, direction, color);
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package eu.mhsl.minecraft.pixelpics.render.util;
|
||||
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class MathUtil {
|
||||
|
||||
private MathUtil() {}
|
||||
|
||||
public static Vector yawPitchRotation(Vector base, double angleYaw, double anglePitch) {
|
||||
double oldX = base.getX();
|
||||
double oldY = base.getY();
|
||||
double oldZ = base.getZ();
|
||||
|
||||
double sinOne = Math.sin(angleYaw);
|
||||
double sinTwo = Math.sin(anglePitch);
|
||||
double cosOne = Math.cos(angleYaw);
|
||||
double cosTwo = Math.cos(anglePitch);
|
||||
|
||||
double newX = oldX * cosOne * cosTwo - oldY * cosOne * sinTwo - oldZ * sinOne;
|
||||
double newY = oldX * sinTwo + oldY * cosTwo;
|
||||
double newZ = oldX * sinOne * cosTwo - oldY * sinOne * sinTwo + oldZ * cosOne;
|
||||
|
||||
return new Vector(newX, newY, newZ);
|
||||
}
|
||||
|
||||
public static Vector doubleYawPitchRotation(Vector base, double firstYaw, double firstPitch, double secondYaw,
|
||||
double secondPitch) {
|
||||
return yawPitchRotation(yawPitchRotation(base, firstYaw, firstPitch), secondYaw, secondPitch);
|
||||
}
|
||||
|
||||
public static Vector reflectVector(Vector linePoint, Vector lineDirection, Vector planePoint, Vector planeNormal) {
|
||||
return lineDirection.clone().subtract(planeNormal.clone().multiply(2 * lineDirection.dot(planeNormal)));
|
||||
}
|
||||
|
||||
public static Vector toVector(BlockFace face) {
|
||||
return new Vector(face.getModX(), face.getModY(), face.getModZ());
|
||||
}
|
||||
|
||||
public static int weightedColorSum(int rgbOne, int rgbTwo, double weightOne, double weightTwo) {
|
||||
Color colorOne = Color.fromRGB(rgbOne & 0xFFFFFF);
|
||||
Color colorTwo = Color.fromRGB(rgbTwo & 0xFFFFFF);
|
||||
|
||||
double total = weightOne + weightTwo;
|
||||
int newRed = (int) ((colorOne.getRed() * weightOne + colorTwo.getRed() * weightTwo) / total);
|
||||
int newGreen = (int) ((colorOne.getGreen() * weightOne + colorTwo.getGreen() * weightTwo) / total);
|
||||
int newBlue = (int) ((colorOne.getBlue() * weightOne + colorTwo.getBlue() * weightTwo) / total);
|
||||
|
||||
return Color.fromRGB(newRed, newGreen, newBlue).asRGB();
|
||||
}
|
||||
|
||||
public static Vector getLinePlaneIntersection(Vector linePoint, Vector lineDirection, Vector planePoint,
|
||||
Vector planeNormal, boolean allowBackwards) {
|
||||
double d = planePoint.dot(planeNormal);
|
||||
double t = (d - planeNormal.dot(linePoint)) / planeNormal.dot(lineDirection);
|
||||
|
||||
if (t < 0 && !allowBackwards) {
|
||||
return null;
|
||||
}
|
||||
|
||||
double x = linePoint.getX() + lineDirection.getX() * t;
|
||||
double y = linePoint.getY() + lineDirection.getY() * t;
|
||||
double z = linePoint.getZ() + lineDirection.getZ() * t;
|
||||
|
||||
return new Vector(x, y, z);
|
||||
}
|
||||
}
|
BIN
src/main/resources/colormap/foliage.png
Normal file
BIN
src/main/resources/colormap/foliage.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 14 KiB |
BIN
src/main/resources/colormap/grass.png
Normal file
BIN
src/main/resources/colormap/grass.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 5.8 KiB |
6
src/main/resources/models/block/acacia_button.json
Normal file
6
src/main/resources/models/block/acacia_button.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/button",
|
||||
"textures": {
|
||||
"texture": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/button_inventory",
|
||||
"textures": {
|
||||
"texture": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/button_pressed",
|
||||
"textures": {
|
||||
"texture": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"parent": "minecraft:block/door_bottom_left",
|
||||
"textures": {
|
||||
"bottom": "minecraft:block/acacia_door_bottom",
|
||||
"top": "minecraft:block/acacia_door_top"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"parent": "minecraft:block/door_bottom_left_open",
|
||||
"textures": {
|
||||
"bottom": "minecraft:block/acacia_door_bottom",
|
||||
"top": "minecraft:block/acacia_door_top"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"parent": "minecraft:block/door_bottom_right",
|
||||
"textures": {
|
||||
"bottom": "minecraft:block/acacia_door_bottom",
|
||||
"top": "minecraft:block/acacia_door_top"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"parent": "minecraft:block/door_bottom_right_open",
|
||||
"textures": {
|
||||
"bottom": "minecraft:block/acacia_door_bottom",
|
||||
"top": "minecraft:block/acacia_door_top"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"parent": "minecraft:block/door_top_left",
|
||||
"textures": {
|
||||
"bottom": "minecraft:block/acacia_door_bottom",
|
||||
"top": "minecraft:block/acacia_door_top"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"parent": "minecraft:block/door_top_left_open",
|
||||
"textures": {
|
||||
"bottom": "minecraft:block/acacia_door_bottom",
|
||||
"top": "minecraft:block/acacia_door_top"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"parent": "minecraft:block/door_top_right",
|
||||
"textures": {
|
||||
"bottom": "minecraft:block/acacia_door_bottom",
|
||||
"top": "minecraft:block/acacia_door_top"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"parent": "minecraft:block/door_top_right_open",
|
||||
"textures": {
|
||||
"bottom": "minecraft:block/acacia_door_bottom",
|
||||
"top": "minecraft:block/acacia_door_top"
|
||||
}
|
||||
}
|
6
src/main/resources/models/block/acacia_fence_gate.json
Normal file
6
src/main/resources/models/block/acacia_fence_gate.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/template_fence_gate",
|
||||
"textures": {
|
||||
"texture": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/template_fence_gate_open",
|
||||
"textures": {
|
||||
"texture": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/template_fence_gate_wall",
|
||||
"textures": {
|
||||
"texture": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/template_fence_gate_wall_open",
|
||||
"textures": {
|
||||
"texture": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/fence_inventory",
|
||||
"textures": {
|
||||
"texture": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
6
src/main/resources/models/block/acacia_fence_post.json
Normal file
6
src/main/resources/models/block/acacia_fence_post.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/fence_post",
|
||||
"textures": {
|
||||
"texture": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
6
src/main/resources/models/block/acacia_fence_side.json
Normal file
6
src/main/resources/models/block/acacia_fence_side.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/fence_side",
|
||||
"textures": {
|
||||
"texture": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
5
src/main/resources/models/block/acacia_hanging_sign.json
Normal file
5
src/main/resources/models/block/acacia_hanging_sign.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"textures": {
|
||||
"particle": "minecraft:block/stripped_acacia_log"
|
||||
}
|
||||
}
|
6
src/main/resources/models/block/acacia_leaves.json
Normal file
6
src/main/resources/models/block/acacia_leaves.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/leaves",
|
||||
"textures": {
|
||||
"all": "minecraft:block/acacia_leaves"
|
||||
}
|
||||
}
|
7
src/main/resources/models/block/acacia_log.json
Normal file
7
src/main/resources/models/block/acacia_log.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_column",
|
||||
"textures": {
|
||||
"end": "minecraft:block/acacia_log_top",
|
||||
"side": "minecraft:block/acacia_log"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_column_horizontal",
|
||||
"textures": {
|
||||
"end": "minecraft:block/acacia_log_top",
|
||||
"side": "minecraft:block/acacia_log"
|
||||
}
|
||||
}
|
6
src/main/resources/models/block/acacia_planks.json
Normal file
6
src/main/resources/models/block/acacia_planks.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/pressure_plate_up",
|
||||
"textures": {
|
||||
"texture": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/pressure_plate_down",
|
||||
"textures": {
|
||||
"texture": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
6
src/main/resources/models/block/acacia_sapling.json
Normal file
6
src/main/resources/models/block/acacia_sapling.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/cross",
|
||||
"textures": {
|
||||
"cross": "minecraft:block/acacia_sapling"
|
||||
}
|
||||
}
|
5
src/main/resources/models/block/acacia_sign.json
Normal file
5
src/main/resources/models/block/acacia_sign.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"textures": {
|
||||
"particle": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
8
src/main/resources/models/block/acacia_slab.json
Normal file
8
src/main/resources/models/block/acacia_slab.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"parent": "minecraft:block/slab",
|
||||
"textures": {
|
||||
"bottom": "minecraft:block/acacia_planks",
|
||||
"side": "minecraft:block/acacia_planks",
|
||||
"top": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
8
src/main/resources/models/block/acacia_slab_top.json
Normal file
8
src/main/resources/models/block/acacia_slab_top.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"parent": "minecraft:block/slab_top",
|
||||
"textures": {
|
||||
"bottom": "minecraft:block/acacia_planks",
|
||||
"side": "minecraft:block/acacia_planks",
|
||||
"top": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
8
src/main/resources/models/block/acacia_stairs.json
Normal file
8
src/main/resources/models/block/acacia_stairs.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"parent": "minecraft:block/stairs",
|
||||
"textures": {
|
||||
"bottom": "minecraft:block/acacia_planks",
|
||||
"side": "minecraft:block/acacia_planks",
|
||||
"top": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
8
src/main/resources/models/block/acacia_stairs_inner.json
Normal file
8
src/main/resources/models/block/acacia_stairs_inner.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"parent": "minecraft:block/inner_stairs",
|
||||
"textures": {
|
||||
"bottom": "minecraft:block/acacia_planks",
|
||||
"side": "minecraft:block/acacia_planks",
|
||||
"top": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
8
src/main/resources/models/block/acacia_stairs_outer.json
Normal file
8
src/main/resources/models/block/acacia_stairs_outer.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"parent": "minecraft:block/outer_stairs",
|
||||
"textures": {
|
||||
"bottom": "minecraft:block/acacia_planks",
|
||||
"side": "minecraft:block/acacia_planks",
|
||||
"top": "minecraft:block/acacia_planks"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/template_orientable_trapdoor_bottom",
|
||||
"textures": {
|
||||
"texture": "minecraft:block/acacia_trapdoor"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/template_orientable_trapdoor_open",
|
||||
"textures": {
|
||||
"texture": "minecraft:block/acacia_trapdoor"
|
||||
}
|
||||
}
|
6
src/main/resources/models/block/acacia_trapdoor_top.json
Normal file
6
src/main/resources/models/block/acacia_trapdoor_top.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/template_orientable_trapdoor_top",
|
||||
"textures": {
|
||||
"texture": "minecraft:block/acacia_trapdoor"
|
||||
}
|
||||
}
|
7
src/main/resources/models/block/acacia_wood.json
Normal file
7
src/main/resources/models/block/acacia_wood.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_column",
|
||||
"textures": {
|
||||
"end": "minecraft:block/acacia_log",
|
||||
"side": "minecraft:block/acacia_log"
|
||||
}
|
||||
}
|
6
src/main/resources/models/block/activator_rail.json
Normal file
6
src/main/resources/models/block/activator_rail.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/rail_flat",
|
||||
"textures": {
|
||||
"rail": "minecraft:block/activator_rail"
|
||||
}
|
||||
}
|
6
src/main/resources/models/block/activator_rail_on.json
Normal file
6
src/main/resources/models/block/activator_rail_on.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/rail_flat",
|
||||
"textures": {
|
||||
"rail": "minecraft:block/activator_rail_on"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/template_rail_raised_ne",
|
||||
"textures": {
|
||||
"rail": "minecraft:block/activator_rail_on"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/template_rail_raised_sw",
|
||||
"textures": {
|
||||
"rail": "minecraft:block/activator_rail_on"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/template_rail_raised_ne",
|
||||
"textures": {
|
||||
"rail": "minecraft:block/activator_rail"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/template_rail_raised_sw",
|
||||
"textures": {
|
||||
"rail": "minecraft:block/activator_rail"
|
||||
}
|
||||
}
|
5
src/main/resources/models/block/air.json
Normal file
5
src/main/resources/models/block/air.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"textures": {
|
||||
"particle": "minecraft:missingno"
|
||||
}
|
||||
}
|
6
src/main/resources/models/block/allium.json
Normal file
6
src/main/resources/models/block/allium.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/cross",
|
||||
"textures": {
|
||||
"cross": "minecraft:block/allium"
|
||||
}
|
||||
}
|
6
src/main/resources/models/block/amethyst_block.json
Normal file
6
src/main/resources/models/block/amethyst_block.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "minecraft:block/amethyst_block"
|
||||
}
|
||||
}
|
6
src/main/resources/models/block/amethyst_cluster.json
Normal file
6
src/main/resources/models/block/amethyst_cluster.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/cross",
|
||||
"textures": {
|
||||
"cross": "minecraft:block/amethyst_cluster"
|
||||
}
|
||||
}
|
7
src/main/resources/models/block/ancient_debris.json
Normal file
7
src/main/resources/models/block/ancient_debris.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_column",
|
||||
"textures": {
|
||||
"end": "minecraft:block/ancient_debris_top",
|
||||
"side": "minecraft:block/ancient_debris_side"
|
||||
}
|
||||
}
|
6
src/main/resources/models/block/andesite.json
Normal file
6
src/main/resources/models/block/andesite.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "minecraft:block/andesite"
|
||||
}
|
||||
}
|
8
src/main/resources/models/block/andesite_slab.json
Normal file
8
src/main/resources/models/block/andesite_slab.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"parent": "minecraft:block/slab",
|
||||
"textures": {
|
||||
"bottom": "minecraft:block/andesite",
|
||||
"side": "minecraft:block/andesite",
|
||||
"top": "minecraft:block/andesite"
|
||||
}
|
||||
}
|
8
src/main/resources/models/block/andesite_slab_top.json
Normal file
8
src/main/resources/models/block/andesite_slab_top.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"parent": "minecraft:block/slab_top",
|
||||
"textures": {
|
||||
"bottom": "minecraft:block/andesite",
|
||||
"side": "minecraft:block/andesite",
|
||||
"top": "minecraft:block/andesite"
|
||||
}
|
||||
}
|
8
src/main/resources/models/block/andesite_stairs.json
Normal file
8
src/main/resources/models/block/andesite_stairs.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"parent": "minecraft:block/stairs",
|
||||
"textures": {
|
||||
"bottom": "minecraft:block/andesite",
|
||||
"side": "minecraft:block/andesite",
|
||||
"top": "minecraft:block/andesite"
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"parent": "minecraft:block/inner_stairs",
|
||||
"textures": {
|
||||
"bottom": "minecraft:block/andesite",
|
||||
"side": "minecraft:block/andesite",
|
||||
"top": "minecraft:block/andesite"
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"parent": "minecraft:block/outer_stairs",
|
||||
"textures": {
|
||||
"bottom": "minecraft:block/andesite",
|
||||
"side": "minecraft:block/andesite",
|
||||
"top": "minecraft:block/andesite"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/wall_inventory",
|
||||
"textures": {
|
||||
"wall": "minecraft:block/andesite"
|
||||
}
|
||||
}
|
6
src/main/resources/models/block/andesite_wall_post.json
Normal file
6
src/main/resources/models/block/andesite_wall_post.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/template_wall_post",
|
||||
"textures": {
|
||||
"wall": "minecraft:block/andesite"
|
||||
}
|
||||
}
|
6
src/main/resources/models/block/andesite_wall_side.json
Normal file
6
src/main/resources/models/block/andesite_wall_side.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/template_wall_side",
|
||||
"textures": {
|
||||
"wall": "minecraft:block/andesite"
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/template_wall_side_tall",
|
||||
"textures": {
|
||||
"wall": "minecraft:block/andesite"
|
||||
}
|
||||
}
|
6
src/main/resources/models/block/anvil.json
Normal file
6
src/main/resources/models/block/anvil.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/template_anvil",
|
||||
"textures": {
|
||||
"top": "minecraft:block/anvil_top"
|
||||
}
|
||||
}
|
7
src/main/resources/models/block/attached_melon_stem.json
Normal file
7
src/main/resources/models/block/attached_melon_stem.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"parent": "minecraft:block/stem_fruit",
|
||||
"textures": {
|
||||
"stem": "minecraft:block/melon_stem",
|
||||
"upperstem": "minecraft:block/attached_melon_stem"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"parent": "minecraft:block/stem_fruit",
|
||||
"textures": {
|
||||
"stem": "minecraft:block/pumpkin_stem",
|
||||
"upperstem": "minecraft:block/attached_pumpkin_stem"
|
||||
}
|
||||
}
|
7
src/main/resources/models/block/azalea.json
Normal file
7
src/main/resources/models/block/azalea.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"parent": "minecraft:block/template_azalea",
|
||||
"textures": {
|
||||
"side": "minecraft:block/azalea_side",
|
||||
"top": "minecraft:block/azalea_top"
|
||||
}
|
||||
}
|
6
src/main/resources/models/block/azalea_leaves.json
Normal file
6
src/main/resources/models/block/azalea_leaves.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/cube_all",
|
||||
"textures": {
|
||||
"all": "minecraft:block/azalea_leaves"
|
||||
}
|
||||
}
|
6
src/main/resources/models/block/azure_bluet.json
Normal file
6
src/main/resources/models/block/azure_bluet.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:block/cross",
|
||||
"textures": {
|
||||
"cross": "minecraft:block/azure_bluet"
|
||||
}
|
||||
}
|
19
src/main/resources/models/block/bamboo1_age0.json
Normal file
19
src/main/resources/models/block/bamboo1_age0.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"textures": {
|
||||
"all": "block/bamboo_stalk",
|
||||
"particle": "block/bamboo_stalk"
|
||||
},
|
||||
"elements": [
|
||||
{ "from": [ 7, 0, 7 ],
|
||||
"to": [ 9, 16, 9 ],
|
||||
"faces": {
|
||||
"down": { "uv": [ 13, 4, 15, 6 ], "texture": "#all", "cullface": "down" },
|
||||
"up": { "uv": [ 13, 0, 15, 2], "texture": "#all", "cullface": "up" },
|
||||
"north": { "uv": [ 0, 0, 2, 16 ], "texture": "#all" },
|
||||
"south": { "uv": [ 0, 0, 2, 16 ], "texture": "#all" },
|
||||
"west": { "uv": [ 0, 0, 2, 16 ], "texture": "#all" },
|
||||
"east": { "uv": [ 0, 0, 2, 16 ], "texture": "#all" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
19
src/main/resources/models/block/bamboo1_age1.json
Normal file
19
src/main/resources/models/block/bamboo1_age1.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"textures": {
|
||||
"all": "block/bamboo_stalk",
|
||||
"particle": "block/bamboo_stalk"
|
||||
},
|
||||
"elements": [
|
||||
{ "from": [ 6.5, 0, 6.5 ],
|
||||
"to": [ 9.5, 16, 9.5 ],
|
||||
"faces": {
|
||||
"down": { "uv": [ 13, 4, 16, 7 ], "texture": "#all", "cullface": "down" },
|
||||
"up": { "uv": [ 13, 0, 16, 3 ], "texture": "#all", "cullface": "up" },
|
||||
"north": { "uv": [ 0, 0, 3, 16 ], "texture": "#all" },
|
||||
"south": { "uv": [ 0, 0, 3, 16 ], "texture": "#all" },
|
||||
"west": { "uv": [ 0, 0, 3, 16 ], "texture": "#all" },
|
||||
"east": { "uv": [ 0, 0, 3, 16 ], "texture": "#all" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
19
src/main/resources/models/block/bamboo2_age0.json
Normal file
19
src/main/resources/models/block/bamboo2_age0.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"textures": {
|
||||
"all": "block/bamboo_stalk",
|
||||
"particle": "block/bamboo_stalk"
|
||||
},
|
||||
"elements": [
|
||||
{ "from": [ 7, 0, 7 ],
|
||||
"to": [ 9, 16, 9 ],
|
||||
"faces": {
|
||||
"down": { "uv": [ 13, 4, 15, 6 ], "texture": "#all", "cullface": "down" },
|
||||
"up": { "uv": [ 13, 0, 15, 2], "texture": "#all", "cullface": "up" },
|
||||
"north": { "uv": [ 3, 0, 5, 16 ], "texture": "#all" },
|
||||
"south": { "uv": [ 3, 0, 5, 16 ], "texture": "#all" },
|
||||
"west": { "uv": [ 3, 0, 5, 16 ], "texture": "#all" },
|
||||
"east": { "uv": [ 3, 0, 5, 16 ], "texture": "#all" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
19
src/main/resources/models/block/bamboo2_age1.json
Normal file
19
src/main/resources/models/block/bamboo2_age1.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"textures": {
|
||||
"all": "block/bamboo_stalk",
|
||||
"particle": "block/bamboo_stalk"
|
||||
},
|
||||
"elements": [
|
||||
{ "from": [ 6.5, 0, 6.5 ],
|
||||
"to": [ 9.5, 16, 9.5 ],
|
||||
"faces": {
|
||||
"down": { "uv": [ 13, 4, 16, 7 ], "texture": "#all", "cullface": "down" },
|
||||
"up": { "uv": [ 13, 0, 16, 3 ], "texture": "#all", "cullface": "up" },
|
||||
"north": { "uv": [ 3, 0, 6, 16 ], "texture": "#all" },
|
||||
"south": { "uv": [ 3, 0, 6, 16 ], "texture": "#all" },
|
||||
"west": { "uv": [ 3, 0, 6, 16 ], "texture": "#all" },
|
||||
"east": { "uv": [ 3, 0, 6, 16 ], "texture": "#all" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user