Made jars placeable
BIN
assets/models/body.png
Normal file
After Width: | Height: | Size: 220 B |
BIN
assets/models/cork.png
Normal file
After Width: | Height: | Size: 136 B |
1
assets/models/jar.bbmodel
Normal file
|
@ -0,0 +1 @@
|
|||
{"meta":{"format_version":"4.9","model_format":"java_block","box_uv":false},"name":"jar","parent":"","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"unhandled_root_fields":{},"resolution":{"width":16,"height":16},"elements":[{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[4,0,4],"to":[12,12,12],"autouv":0,"color":3,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,8,12],"texture":0},"east":{"uv":[0,0,8,12],"texture":0},"south":{"uv":[0,0,8,12],"texture":0},"west":{"uv":[0,0,8,12],"texture":0},"up":{"uv":[8,0,16,8],"texture":0},"down":{"uv":[8,0,16,8],"texture":0}},"type":"cube","uuid":"c02d32c0-74ac-27ba-627e-83de2a9500f7"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[6,13,6],"to":[10,16,10],"autouv":0,"color":3,"origin":[0,0,0],"faces":{"north":{"uv":[0,4,4,7],"texture":1},"east":{"uv":[0,4,4,7],"texture":1},"south":{"uv":[0,4,4,7],"texture":1},"west":{"uv":[0,4,4,7],"texture":1},"up":{"uv":[0,0,4,4],"texture":1},"down":{"uv":[4,0,8,4],"texture":1}},"type":"cube","uuid":"147c96d5-ae15-7e40-dcb7-c635e6e80eed"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[5,13,5],"to":[11,14,11],"autouv":0,"color":3,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,8,1],"texture":0},"east":{"uv":[0,0,8,1],"texture":0},"south":{"uv":[0,0,8,1],"texture":0},"west":{"uv":[0,0,8,1],"texture":0},"up":{"uv":[8,0,16,8],"texture":0},"down":{"uv":[8,0,16,8],"texture":0}},"type":"cube","uuid":"7642fef8-ce7e-d79f-f450-01de2526fca5"},{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[6,12,6],"to":[10,13,10],"autouv":0,"color":3,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,8,1],"texture":0},"east":{"uv":[0,0,8,1],"texture":0},"south":{"uv":[0,0,8,1],"texture":0},"west":{"uv":[0,0,8,1],"texture":0},"up":{"uv":[8,0,16,8],"texture":0},"down":{"uv":[8,0,16,8],"texture":0}},"type":"cube","uuid":"e1e878a3-7fdb-79f6-e2c8-b591a94cec41"}],"outliner":["c02d32c0-74ac-27ba-627e-83de2a9500f7","7642fef8-ce7e-d79f-f450-01de2526fca5","e1e878a3-7fdb-79f6-e2c8-b591a94cec41","147c96d5-ae15-7e40-dcb7-c635e6e80eed"],"textures":[{"path":"","name":"body","folder":"block","namespace":"","id":"0","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":true,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":false,"uuid":"c3fc3ff5-2bb6-a5d1-88ff-7d0d48a4200c","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAKxJREFUOE/Nk70NxCAMhe0qiCKCCRiA/UdhAFgARIGg8sknJbpI/CS6K47Sz/54fggkIoLJCSHAvu+glLp0pZQg5wwYYyStNfYYrHGdhxHx0sMXM+QEHIVPGAN6w8dlPHMCek4eAUYrLB1478kYM8zga8AyxJkD1hgwfcYVYLTekRk658ha281gpv0WUEqBWiu01t7gbdtACAFSShi5Ox3M/sEdrbv7ncH/cfACoGWX3cV5e7AAAAAASUVORK5CYII="},{"path":"","name":"cork","folder":"block","namespace":"","id":"1","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":false,"uuid":"1faf1369-230e-ed4a-f210-037c1820f194","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAFJJREFUOE9jXDwj8z8DHhCbMZ0RnzwjyABRYW6wmtdvv4JpZD59DKDICztWl6CEgUdoD14/o1sGDgNkQUJ+pr4B+PxPjBxJ/sVm4KgBDAzDIAwAlBIoEQohE0IAAAAASUVORK5CYII="}]}
|
BIN
assets/models/jar_body.png
Normal file
After Width: | Height: | Size: 220 B |
1
assets/models/jar_cloud.bbmodel
Normal file
BIN
assets/models/jar_cork.png
Normal file
After Width: | Height: | Size: 136 B |
1
assets/models/jar_lightning.bbmodel
Normal file
|
@ -0,0 +1 @@
|
|||
{"meta":{"format_version":"4.9","model_format":"java_block","box_uv":false},"name":"jar","parent":"","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"unhandled_root_fields":{},"resolution":{"width":16,"height":16},"elements":[{"name":"cube","box_uv":false,"rescale":true,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[6,1,7.5],"to":[11,11,7.5],"autouv":0,"color":5,"rotation":[0,-45,0],"origin":[8,5,7],"faces":{"north":{"uv":[3,0,13,16],"texture":0},"east":{"uv":[0,0,0,8],"texture":0},"south":{"uv":[3,0,13,16],"texture":0},"west":{"uv":[0,0,0,8],"texture":0},"up":{"uv":[0,0,6,0],"texture":0},"down":{"uv":[0,0,6,0],"texture":0}},"type":"cube","uuid":"52fdb109-7055-1f3c-d1a1-788daf976643"},{"name":"cube","box_uv":false,"rescale":true,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[5,1,7.5],"to":[10,11,7.5],"autouv":0,"color":5,"rotation":[0,45,0],"origin":[8,5,7],"faces":{"north":{"uv":[3,0,13,16],"texture":0},"east":{"uv":[0,0,0,8],"texture":0},"south":{"uv":[3,0,13,16],"texture":0},"west":{"uv":[0,0,0,8],"texture":0},"up":{"uv":[0,0,6,0],"rotation":180,"texture":0},"down":{"uv":[0,0,6,0],"rotation":180,"texture":0}},"type":"cube","uuid":"67ba2407-52e4-4b13-579c-0e7675265bb9"}],"outliner":["52fdb109-7055-1f3c-d1a1-788daf976643","67ba2407-52e4-4b13-579c-0e7675265bb9"],"textures":[{"path":"/home/sollace/Documents/GitRepos/minecraft_mods/Unicopia/src/main/resources/assets/unicopia/textures/block/lightning_jar_filling.png","name":"lightning_jar_filling.png","folder":"block","namespace":"unicopia","id":"2","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"2c8fdd18-9bd4-2276-cdc1-d86d0605d22d","relative_path":"../../../src/main/resources/assets/unicopia/textures/block/lightning_jar_filling.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAN9JREFUOE9jZCASOH7T/L+f6zojunIMAWzmObxR/c/IxcJAlgE+3/X+f/j7l4GV6R/pBnh/0vv/59d/hl9cf7BqBrkWrxdABnxj+Y1TM14DQJq//vrOwMfLz7CJ/QxOi7BKgEKc5wcLw3u2fwxHeK6C1YDEuP6wMqC7CKcB2GIDZMBWvksoejAMANmErBnkEhD4zP6bgZGRESM88BoA1/zvBzi8D4jcwp+QkG0HJRrfd7pg14DCgqh0ADMApBnEZvsGcT5Z6QBXqBOVF9C9gi+/4Y1GbJmHoAuQw4GYnA4AMBBxEZobGUEAAAAASUVORK5CYII="}]}
|
1
assets/models/jar_storm.bbmodel
Normal file
1
assets/models/jar_zap.bbmodel
Normal file
|
@ -0,0 +1 @@
|
|||
{"meta":{"format_version":"4.9","model_format":"java_block","box_uv":false},"name":"jar","parent":"","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"unhandled_root_fields":{},"resolution":{"width":16,"height":16},"elements":[{"name":"cube","box_uv":false,"rescale":false,"locked":false,"render_order":"default","allow_mirror_modeling":true,"from":[4,0,4],"to":[12,10,12],"autouv":0,"color":4,"inflate":-0.09999999999999964,"origin":[0,0,0],"faces":{"north":{"uv":[0,2,8,12],"texture":2},"east":{"uv":[0,6,8,16],"texture":2},"south":{"uv":[8,6,16,16],"texture":2},"west":{"uv":[8,0,16,10],"texture":2},"up":{"uv":[4,3,12,11],"texture":2},"down":{"uv":[8,4,16,12],"texture":2}},"type":"cube","uuid":"e15b3907-6195-1f3b-0c48-23c6b4642fc6"}],"outliner":["e15b3907-6195-1f3b-0c48-23c6b4642fc6"],"textures":[{"path":"/home/sollace/Documents/GitRepos/minecraft_mods/Unicopia/assets/models/body.png","name":"body.png","folder":"","namespace":"","id":"0","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":true,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"c3fc3ff5-2bb6-a5d1-88ff-7d0d48a4200c","relative_path":"../body.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAKxJREFUOE/Nk70NxCAMhe0qiCKCCRiA/UdhAFgARIGg8sknJbpI/CS6K47Sz/54fggkIoLJCSHAvu+glLp0pZQg5wwYYyStNfYYrHGdhxHx0sMXM+QEHIVPGAN6w8dlPHMCek4eAUYrLB1478kYM8zga8AyxJkD1hgwfcYVYLTekRk658ha281gpv0WUEqBWiu01t7gbdtACAFSShi5Ox3M/sEdrbv7ncH/cfACoGWX3cV5e7AAAAAASUVORK5CYII="},{"path":"/home/sollace/Documents/GitRepos/minecraft_mods/Unicopia/assets/models/cork.png","name":"cork.png","folder":"","namespace":"","id":"1","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"1faf1369-230e-ed4a-f210-037c1820f194","relative_path":"../cork.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAFJJREFUOE9jXDwj8z8DHhCbMZ0RnzwjyABRYW6wmtdvv4JpZD59DKDICztWl6CEgUdoD14/o1sGDgNkQUJ+pr4B+PxPjBxJ/sVm4KgBDAzDIAwAlBIoEQohE0IAAAAASUVORK5CYII="},{"path":"/home/sollace/Documents/GitRepos/minecraft_mods/Unicopia/src/main/resources/assets/unicopia/textures/item/jar_filling_zap.png","name":"jar_filling_zap.png","folder":"item","namespace":"unicopia","id":"2","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":false,"uuid":"62c06d20-77c5-befb-bb95-8e5da5394d9c","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAudJREFUOE8dkUlrXWUYgJ/3G849J7dJSxZuG2s6aMDaUsWWNjVpBS2luHDtyp1UcOhfEKTZ1LYIURQXjQYkEkwduhVd6S8oxUXAJpCBeO/NGb7hlfgPnkHOmvfUiMepBwJ3ph0ej3YRPew5+9UnSN9CY4gnL0FpcBo5vzjCeEHOmA9UJaBJuTftKHAUGeoqc/7BPTgUyPsgJ+boTEEkU6rj3OJTysIiZ/37moPly5mSnjEgBYN2n5d/+RSXgAQ5QDw5R2GFQWOZ/WIL6Ql2lJFz9iNdfM4zsg3jFAy6louP7kMRyZ2AgfqZWXAlRlsuLw7wpdDEQH10Ffnj+C31PY+2LT4Lp79fgBIkQZICfeEyQSsYNlxZ3mX4b83EkYqm6Rge/wn569SHqjZRq+fC6gK66Vgff5ep9A3MzLLTBY5UgVcXa1KKRBImQH5xDVGH/Pn8LTUkXvr5M1I0uKbj73yTZ48/IfmEsZFXvt6jGAniDYOwTz72A9rvQzbI76c+1gs/3icMa/wERAE3dYOailwPmFvbxu5kJBz0F0ZnVkl1S9Xr0wWD6GOUCCogCvnYWxjfgkZeX27Y3tzDO0cMGTPzkNh3tHVNUULvtbtIfoKKeNLUVYwYJEW6kePGbyM2Hm9RVI5oDGlqhewMgsWKoXd1gUiH1GFeSyvQjJGrhjeWO/55uoVTh+9bjGTs9K80YmhDTRk69PodnPW0MSIarimu4NrKiO31baJP9IqCHJV4Yol8gC8lsR5Qjo1Tzt2mIRNjwHhF3vzuinaaECvs7uxgjaE6+pCNPGRsYpxcJ9QbNAYmr37Org7pmTFaavyB8vzSrDpbsbe5RVNF3NEVovXQtPjeIVpa3t7cYO2dbzHqyKYhqSekfUpXIReXLqlJke3JB7geqHdIryDWSmkjxlYcnr/NXmhIVrCq/H/NZBwVcvrRunYSKLGkImOi4LynDcrk9bsMm33koIFrKUIP1Y7sWqz0ydLyH7DGczPZHbGfAAAAAElFTkSuQmCC","relative_path":"../../../src/main/resources/assets/unicopia/textures/item/jar_filling_zap.png"}]}
|
|
@ -43,6 +43,7 @@ public interface UTags {
|
|||
TagKey<Block> FRAGILE = block("fragile");
|
||||
TagKey<Block> INTERESTING = block("interesting");
|
||||
TagKey<Block> CATAPULT_IMMUNE = block("catapult_immune");
|
||||
TagKey<Block> JARS = block("jars");
|
||||
|
||||
TagKey<Block> CRYSTAL_HEART_BASE = block("crystal_heart_base");
|
||||
TagKey<Block> CRYSTAL_HEART_ORNAMENT = block("crystal_heart_ornament");
|
||||
|
|
|
@ -0,0 +1,216 @@
|
|||
package com.minelittlepony.unicopia.block;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import net.minecraft.block.BlockEntityProvider;
|
||||
import net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.InventoryProvider;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.SidedInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldAccess;
|
||||
|
||||
public class ItemJarBlock extends JarBlock implements BlockEntityProvider, InventoryProvider {
|
||||
|
||||
public ItemJarBlock(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockRenderType getRenderType(BlockState state) {
|
||||
return BlockRenderType.MODEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||
if (hand == Hand.OFF_HAND) {
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).map(data -> {
|
||||
ItemStack stack = player.getStackInHand(hand);
|
||||
if (stack.isEmpty()) {
|
||||
return data.removeItem(world, pos);
|
||||
}
|
||||
|
||||
return data.insertItem(world, pos, player.isCreative() ? stack.copyWithCount(1) : stack.split(1));
|
||||
}).orElse(ActionResult.PASS);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||
if (!moved && !state.isOf(newState.getBlock())) {
|
||||
world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).ifPresent(data -> {
|
||||
data.getStacks().forEach(stack -> {
|
||||
dropStack(world, pos, stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
super.onStateReplaced(state, world, pos, newState, moved);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasComparatorOutput(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getComparatorOutput(BlockState state, World world, BlockPos pos) {
|
||||
return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).map(data -> Math.min(16, data.getStacks().size())).orElse(0);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public boolean onSyncedBlockEvent(BlockState state, World world, BlockPos pos, int type, int data) {
|
||||
super.onSyncedBlockEvent(state, world, pos, type, data);
|
||||
BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||
return blockEntity != null && blockEntity.onSyncedBlockEvent(type, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
|
||||
return new TileData(pos, state);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SidedInventory getInventory(BlockState state, WorldAccess world, BlockPos pos) {
|
||||
return world.getBlockEntity(pos, UBlockEntities.ITEM_JAR).orElse(null);
|
||||
}
|
||||
|
||||
public static class TileData extends BlockEntity implements SidedInventory {
|
||||
private static final int[] SLOTS = IntStream.range(0, 16).toArray();
|
||||
private final List<ItemStack> stacks = new ArrayList<>();
|
||||
|
||||
public TileData(BlockPos pos, BlockState state) {
|
||||
super(UBlockEntities.ITEM_JAR, pos, state);
|
||||
}
|
||||
|
||||
public ActionResult insertItem(World world, BlockPos pos, ItemStack stack) {
|
||||
if (stacks.size() >= size()) {
|
||||
return ActionResult.FAIL;
|
||||
}
|
||||
stacks.add(stack);
|
||||
markDirty();
|
||||
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
public ActionResult removeItem(World world, BlockPos pos) {
|
||||
if (stacks.isEmpty()) {
|
||||
return ActionResult.FAIL;
|
||||
}
|
||||
dropStack(world, pos, stacks.remove(0));
|
||||
markDirty();
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
public List<ItemStack> getStacks() {
|
||||
return stacks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 15;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return stacks.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStack(int slot) {
|
||||
return slot < 0 || slot >= stacks.size() ? ItemStack.EMPTY : stacks.get(slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeStack(int slot, int amount) {
|
||||
if (slot < 0 || slot >= stacks.size()) {
|
||||
try {
|
||||
ItemStack stack = stacks.get(slot);
|
||||
ItemStack removed = stack.split(1);
|
||||
if (stack.isEmpty()) {
|
||||
stacks.remove(slot);
|
||||
}
|
||||
return removed;
|
||||
} finally {
|
||||
markDirty();
|
||||
}
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack removeStack(int slot) {
|
||||
if (slot < 0 || slot >= stacks.size()) {
|
||||
try {
|
||||
return stacks.remove(slot);
|
||||
} finally {
|
||||
markDirty();
|
||||
}
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStack(int slot, ItemStack stack) {
|
||||
if (slot >= stacks.size()) {
|
||||
if (stacks.size() >= size()) {
|
||||
dropStack(getWorld(), getPos(), stack);
|
||||
} else {
|
||||
stacks.add(stack);
|
||||
}
|
||||
} else {
|
||||
ItemStack existing = stacks.get(slot);
|
||||
if (!ItemStack.canCombine(existing, stack)) {
|
||||
dropStack(getWorld(), getPos(), stack);
|
||||
} else {
|
||||
existing.setCount(existing.getCount() + stack.split(Math.max(0, existing.getMaxCount() - existing.getCount())).getCount());
|
||||
if (!stack.isEmpty()) {
|
||||
dropStack(getWorld(), getPos(), stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlayerUse(PlayerEntity player) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
stacks.clear();
|
||||
markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getAvailableSlots(Direction side) {
|
||||
return SLOTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInsert(int slot, ItemStack stack, Direction dir) {
|
||||
return (slot >= 0 && slot < size()) && (slot >= stacks.size() || (
|
||||
ItemStack.canCombine(stacks.get(slot), stack)
|
||||
&& (stacks.get(slot).getCount() + stack.getCount()) <= Math.min(stacks.get(slot).getMaxCount(), stack.getMaxCount())
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canExtract(int slot, ItemStack stack, Direction dir) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package com.minelittlepony.unicopia.block;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.item.WeatherJarItem;
|
||||
import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect;
|
||||
|
||||
import net.minecraft.block.AbstractGlassBlock;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.ShapeContext;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.util.shape.VoxelShape;
|
||||
import net.minecraft.util.shape.VoxelShapes;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.explosion.Explosion;
|
||||
|
||||
public class JarBlock extends AbstractGlassBlock {
|
||||
private static final VoxelShape SHAPE = VoxelShapes.union(
|
||||
Block.createCuboidShape(4, 0, 4, 12, 12, 12),
|
||||
Block.createCuboidShape(6, 12, 6, 10, 16, 10),
|
||||
Block.createCuboidShape(5, 13, 5, 11, 14, 11)
|
||||
);
|
||||
|
||||
public JarBlock(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
|
||||
return SHAPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSideInvisible(BlockState state, BlockState stateFrom, Direction direction) {
|
||||
return super.isSideInvisible(state, stateFrom, direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void randomDisplayTick(BlockState state, World world, BlockPos pos, Random random) {
|
||||
if (this == UBlocks.LIGHTNING_JAR) {
|
||||
world.addParticle(new LightningBoltParticleEffect(true, 10, 1, 0.6F, Optional.empty()), pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
|
||||
super.onStateReplaced(state, world, pos, newState, moved);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBreak(World world, BlockPos pos, BlockState state, PlayerEntity player) {
|
||||
super.onBreak(world, pos, state, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyedByExplosion(World world, BlockPos pos, Explosion explosion) {
|
||||
if (asItem() instanceof WeatherJarItem jar) {
|
||||
jar.releaseContents(world, pos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterBreak(World world, PlayerEntity player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) {
|
||||
super.afterBreak(world, player, pos, state, blockEntity, tool);
|
||||
if (!EnchantmentHelper.hasSilkTouch(tool) && !player.shouldCancelInteraction()) {
|
||||
if (asItem() instanceof WeatherJarItem jar) {
|
||||
jar.releaseContents(world, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ public interface UBlockEntities {
|
|||
BlockEntityType<CloudBedBlock.Tile> FANCY_BED = create("fancy_bed", BlockEntityType.Builder.create(CloudBedBlock.Tile::new, UBlocks.CLOTH_BED, UBlocks.CLOUD_BED));
|
||||
BlockEntityType<ChestBlockEntity> CLOUD_CHEST = create("cloud_chest", BlockEntityType.Builder.create(CloudChestBlock.TileData::new, UBlocks.CLOUD_CHEST));
|
||||
BlockEntityType<HiveBlock.TileData> HIVE_STORAGE = create("hive_storage", BlockEntityType.Builder.create(HiveBlock.TileData::new, UBlocks.HIVE));
|
||||
BlockEntityType<ItemJarBlock.TileData> ITEM_JAR = create("item_jar", BlockEntityType.Builder.create(ItemJarBlock.TileData::new, UBlocks.JAR));
|
||||
|
||||
static <T extends BlockEntity> BlockEntityType<T> create(String id, Builder<T> builder) {
|
||||
return Registry.register(Registries.BLOCK_ENTITY_TYPE, id, builder.build(null));
|
||||
|
|
|
@ -253,6 +253,11 @@ public interface UBlocks {
|
|||
Block CLOUD_DOOR = register("cloud_door", new CloudDoorBlock(Settings.copy(CLOUD), CLOUD.getDefaultState(), UWoodTypes.CLOUD), ItemGroups.FUNCTIONAL);
|
||||
|
||||
Block SPECTRAL_FIRE = register("spectral_fire", new SpectralFireBlock(Settings.copy(Blocks.SOUL_FIRE)));
|
||||
Block JAR = register("jar", new ItemJarBlock(Settings.copy(Blocks.GLASS)));
|
||||
Block CLOUD_JAR = register("cloud_jar", new JarBlock(Settings.copy(Blocks.GLASS)));
|
||||
Block STORM_JAR = register("storm_jar", new JarBlock(Settings.copy(Blocks.GLASS)));
|
||||
Block LIGHTNING_JAR = register("lightning_jar", new JarBlock(Settings.copy(Blocks.GLASS)));
|
||||
Block ZAP_JAR = register("zap_jar", new JarBlock(Settings.copy(Blocks.GLASS)));
|
||||
|
||||
Block WORM_BLOCK = register("worm_block", new FallingBlock(Settings.create().hardness(0.1F).resistance(0).requiresTool().sounds(BlockSoundGroup.MUD)), ItemGroups.NATURAL);
|
||||
EdibleBlock HAY_BLOCK = register("hay_block", new EdibleBlock(new Identifier("hay_block"), new Identifier("wheat"), true));
|
||||
|
@ -305,7 +310,10 @@ public interface UBlocks {
|
|||
OxidizableBlocksRegistry.registerWaxableBlockPair(ZAP_SLAB, WAXED_ZAP_SLAB);
|
||||
OxidizableBlocksRegistry.registerWaxableBlockPair(ZAP_FENCE, WAXED_ZAP_FENCE);
|
||||
OxidizableBlocksRegistry.registerWaxableBlockPair(ZAP_FENCE_GATE, WAXED_ZAP_FENCE_GATE);
|
||||
Collections.addAll(TRANSLUCENT_BLOCKS, WEATHER_VANE, CHITIN_SPIKES, PLUNDER_VINE, PLUNDER_VINE_BUD, CLAM_SHELL, SCALLOP_SHELL, TURRET_SHELL, CURING_JOKE, SPECTRAL_FIRE);
|
||||
Collections.addAll(TRANSLUCENT_BLOCKS,
|
||||
WEATHER_VANE, CHITIN_SPIKES, PLUNDER_VINE, PLUNDER_VINE_BUD, CLAM_SHELL, SCALLOP_SHELL, TURRET_SHELL, CURING_JOKE, SPECTRAL_FIRE,
|
||||
JAR, CLOUD_JAR, STORM_JAR, LIGHTNING_JAR, ZAP_JAR
|
||||
);
|
||||
TintedBlock.REGISTRY.add(PALM_LEAVES);
|
||||
|
||||
FlammableBlockRegistry.getDefaultInstance().add(GREEN_APPLE_LEAVES, 30, 60);
|
||||
|
|
|
@ -116,6 +116,7 @@ public interface URenderers {
|
|||
BlockEntityRendererFactories.register(UBlockEntities.WEATHER_VANE, WeatherVaneBlockEntityRenderer::new);
|
||||
BlockEntityRendererFactories.register(UBlockEntities.FANCY_BED, CloudBedBlockEntityRenderer::new);
|
||||
BlockEntityRendererFactories.register(UBlockEntities.CLOUD_CHEST, CloudChestBlockEntityRenderer::new);
|
||||
BlockEntityRendererFactories.register(UBlockEntities.ITEM_JAR, ItemJarBlockEntityRenderer::new);
|
||||
|
||||
register(URenderers::renderJarItem, UItems.FILLED_JAR);
|
||||
register(URenderers::renderBedItem, UItems.CLOTH_BED, UItems.CLOUD_BED);
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package com.minelittlepony.unicopia.client.render.entity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.minelittlepony.unicopia.block.ItemJarBlock;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRendererFactory;
|
||||
import net.minecraft.client.render.model.json.ModelTransformationMode;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.RotationAxis;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
|
||||
public class ItemJarBlockEntityRenderer implements BlockEntityRenderer<ItemJarBlock.TileData> {
|
||||
|
||||
public ItemJarBlockEntityRenderer(BlockEntityRendererFactory.Context ctx) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(ItemJarBlock.TileData entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertices, int light, int overlay) {
|
||||
|
||||
List<ItemStack> stacks = entity.getStacks();
|
||||
|
||||
float itemScale = 0.35F;
|
||||
|
||||
matrices.push();
|
||||
matrices.translate(0.5, 0, 0.5);
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90));
|
||||
matrices.scale(itemScale, itemScale, itemScale);
|
||||
|
||||
Random rng = Random.create(entity.getPos().asLong());
|
||||
|
||||
float y = 0;
|
||||
for (ItemStack stack : stacks) {
|
||||
matrices.push();
|
||||
|
||||
matrices.translate((rng.nextFloat() - 0.5F) * 0.5F, (rng.nextFloat() - 0.5F) * 0.8F, -0.05 + y);
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees((rng.nextFloat() * 360) - 180));
|
||||
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees((rng.nextFloat() * 360) - 180));
|
||||
y -= 0.1F;
|
||||
MinecraftClient.getInstance().getItemRenderer().renderItem(stack, ModelTransformationMode.FIXED, light, overlay, matrices, vertices, entity.getWorld(), 0);
|
||||
matrices.pop();
|
||||
}
|
||||
matrices.pop();
|
||||
}
|
||||
}
|
|
@ -34,6 +34,7 @@ public interface BlockModels {
|
|||
Model DOOR_RIGHT = block("door_right", TextureKey.BOTTOM, TextureKey.TOP);
|
||||
Model TEMPLATE_PILLAR = block("template_pillar", TextureKey.SIDE);
|
||||
Model TEMPLATE_PILLAR_END = block("template_pillar_end", "_end", TextureKey.BOTTOM, TextureKey.TOP, TextureKey.END);
|
||||
Identifier TEMPLATE_JAR = Unicopia.id("block/template_jar");
|
||||
|
||||
Factory CROP = Factory.of(TextureMap::crop, Models.CROP);
|
||||
Factory CUBE_ALL = Factory.of(TextureMap::all, Models.CUBE_ALL);
|
||||
|
|
|
@ -35,6 +35,7 @@ import net.minecraft.data.client.Models;
|
|||
import net.minecraft.data.client.MultipartBlockStateSupplier;
|
||||
import net.minecraft.data.client.TextureMap;
|
||||
import net.minecraft.data.client.TexturedModel;
|
||||
import net.minecraft.data.client.VariantSettings;
|
||||
import net.minecraft.data.client.VariantsBlockStateSupplier;
|
||||
import net.minecraft.data.client.When;
|
||||
import net.minecraft.item.Item;
|
||||
|
@ -177,6 +178,18 @@ public class UBlockStateModelGenerator extends BlockStateModelGenerator {
|
|||
registerWithStagesBuiltinModels(UBlocks.MYSTERIOUS_EGG, PileBlock.COUNT, 1, 2, 3);
|
||||
excludeFromSimpleItemModelGeneration(UBlocks.MYSTERIOUS_EGG);
|
||||
FireModels.registerSoulFire(this, UBlocks.SPECTRAL_FIRE, Blocks.SOUL_FIRE);
|
||||
|
||||
blockStateCollector.accept(createSingletonBlockState(UBlocks.JAR, BlockModels.TEMPLATE_JAR));
|
||||
registerWeatherJar(UBlocks.CLOUD_JAR);
|
||||
registerWeatherJar(UBlocks.STORM_JAR);
|
||||
registerWeatherJar(UBlocks.ZAP_JAR);
|
||||
registerWeatherJar(UBlocks.LIGHTNING_JAR);
|
||||
}
|
||||
|
||||
public void registerWeatherJar(Block jar) {
|
||||
blockStateCollector.accept(MultipartBlockStateSupplier.create(jar)
|
||||
.with(BlockStateVariant.create().put(VariantSettings.MODEL, BlockModels.TEMPLATE_JAR))
|
||||
.with(BlockStateVariant.create().put(VariantSettings.MODEL, ModelIds.getBlockSubModelId(jar, "_filling"))));
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
|
|
|
@ -40,11 +40,12 @@ public class UBlockTagProvider extends FabricTagProvider.BlockTagProvider {
|
|||
};
|
||||
|
||||
getOrCreateTagBuilder(UTags.CATAPULT_IMMUNE).add(Blocks.BEDROCK).forceAddTag(BlockTags.DOORS).forceAddTag(BlockTags.TRAPDOORS);
|
||||
getOrCreateTagBuilder(UTags.JARS).add(UBlocks.JAR, UBlocks.CLOUD_JAR, UBlocks.STORM_JAR, UBlocks.LIGHTNING_JAR, UBlocks.ZAP_JAR);
|
||||
getOrCreateTagBuilder(BlockTags.CROPS).add(crops);
|
||||
getOrCreateTagBuilder(BlockTags.BEE_GROWABLES).add(crops);
|
||||
getOrCreateTagBuilder(BlockTags.MAINTAINS_FARMLAND).add(crops);
|
||||
getOrCreateTagBuilder(BlockTags.NEEDS_DIAMOND_TOOL).add(UBlocks.FROSTED_OBSIDIAN);
|
||||
getOrCreateTagBuilder(BlockTags.PICKAXE_MINEABLE).add(UBlocks.ROCKS, UBlocks.FROSTED_OBSIDIAN, UBlocks.WEATHER_VANE);
|
||||
getOrCreateTagBuilder(BlockTags.PICKAXE_MINEABLE).add(UBlocks.ROCKS, UBlocks.FROSTED_OBSIDIAN, UBlocks.WEATHER_VANE).forceAddTag(UTags.JARS);
|
||||
getOrCreateTagBuilder(BlockTags.DRAGON_IMMUNE).add(UBlocks.FROSTED_OBSIDIAN, UBlocks.GOLDEN_OAK_LOG, UBlocks.GOLDEN_OAK_LEAVES);
|
||||
getOrCreateTagBuilder(BlockTags.FIRE).add(UBlocks.SPECTRAL_FIRE);
|
||||
getOrCreateTagBuilder(BlockTags.HOE_MINEABLE).add(UBlocks.HAY_BLOCK).addOptional(Unicopia.id("rice_block")).addOptional(Unicopia.id("straw_block"));
|
||||
|
@ -67,6 +68,7 @@ public class UBlockTagProvider extends FabricTagProvider.BlockTagProvider {
|
|||
getOrCreateTagBuilder(UTags.FRAGILE)
|
||||
.forceAddTag(ConventionalBlockTags.GLASS_BLOCKS)
|
||||
.forceAddTag(ConventionalBlockTags.GLASS_PANES)
|
||||
.forceAddTag(UTags.JARS)
|
||||
.add(Blocks.VINE, Blocks.LILY_PAD);
|
||||
|
||||
getOrCreateTagBuilder(UTags.INTERESTING).add(
|
||||
|
|
|
@ -81,6 +81,11 @@ public class UBlockLootTableProvider extends FabricBlockLootTableProvider {
|
|||
tree.pot().ifPresent(this::addPottedPlantDrops);
|
||||
});
|
||||
|
||||
// jars
|
||||
List.of(
|
||||
UBlocks.JAR, UBlocks.CLOUD_JAR, UBlocks.STORM_JAR, UBlocks.LIGHTNING_JAR, UBlocks.STORM_JAR
|
||||
).forEach(jar -> addDrop(jar, UBlockLootTableProvider::dropsWithSilkTouch));
|
||||
|
||||
// doors
|
||||
List.of(
|
||||
UBlocks.CLOUD_DOOR, UBlocks.CRYSTAL_DOOR,
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
package com.minelittlepony.unicopia.item;
|
||||
|
||||
import com.minelittlepony.unicopia.block.UBlocks;
|
||||
import com.minelittlepony.unicopia.entity.IItemEntity;
|
||||
import com.minelittlepony.unicopia.entity.ItemImpl;
|
||||
|
||||
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.ItemEntity;
|
||||
import net.minecraft.entity.LightningEntity;
|
||||
import net.minecraft.entity.Entity.RemovalReason;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ActionResult;
|
||||
|
||||
public class EmptyJarItem extends BlockItem implements ItemImpl.GroundTickCallback {
|
||||
public EmptyJarItem(Block block, Settings settings) {
|
||||
super(block, settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult onGroundTick(IItemEntity item) {
|
||||
ItemEntity entity = item.get().asEntity();
|
||||
|
||||
BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), UBlocks.CLOUD_JAR, UBlocks.STORM_JAR, UBlocks.LIGHTNING_JAR, UBlocks.ZAP_JAR);
|
||||
|
||||
entity.setInvulnerable(true);
|
||||
|
||||
if (!entity.getWorld().isClient
|
||||
&& !entity.isRemoved()
|
||||
&& entity.getItemAge() > 100
|
||||
&& entity.getWorld().isThundering()
|
||||
&& entity.getWorld().isSkyVisible(entity.getBlockPos())
|
||||
&& entity.getWorld().random.nextInt(130) == 0) {
|
||||
LightningEntity lightning = EntityType.LIGHTNING_BOLT.create(entity.getWorld());
|
||||
lightning.refreshPositionAfterTeleport(entity.getX(), entity.getY(), entity.getZ());
|
||||
|
||||
entity.remove(RemovalReason.DISCARDED);
|
||||
entity.getWorld().spawnEntity(lightning);
|
||||
|
||||
ItemEntity neu = EntityType.ITEM.create(entity.getWorld());
|
||||
neu.copyPositionAndRotation(entity);
|
||||
neu.setStack(new ItemStack(this == UItems.RAIN_CLOUD_JAR ? UItems.STORM_CLOUD_JAR : UItems.LIGHTNING_JAR));
|
||||
neu.setInvulnerable(true);
|
||||
|
||||
entity.getWorld().spawnEntity(neu);
|
||||
|
||||
ItemEntity copy = EntityType.ITEM.create(entity.getWorld());
|
||||
copy.copyPositionAndRotation(entity);
|
||||
copy.setInvulnerable(true);
|
||||
copy.setStack(entity.getStack());
|
||||
copy.getStack().decrement(1);
|
||||
|
||||
entity.getWorld().spawnEntity(copy);
|
||||
}
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
package com.minelittlepony.unicopia.item;
|
||||
|
||||
import com.minelittlepony.unicopia.entity.IItemEntity;
|
||||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.entity.Living;
|
||||
import com.minelittlepony.unicopia.entity.mob.ButterflyEntity;
|
||||
import com.minelittlepony.unicopia.entity.mob.UEntities;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileDelegate;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
|
@ -20,16 +21,20 @@ import net.minecraft.entity.attribute.EntityAttributes;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.particle.ParticleTypes;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.hit.EntityHitResult;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.WorldEvents;
|
||||
|
||||
public class FilledJarItem extends JarItem implements ChameleonItem {
|
||||
|
||||
public class FilledJarItem extends ProjectileItem implements ProjectileDelegate.HitListener, ChameleonItem {
|
||||
public FilledJarItem(Settings settings) {
|
||||
super(settings, false, false, false);
|
||||
super(settings, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundEvent getThrowSound(ItemStack stack) {
|
||||
return USounds.ENTITY_JAR_THROW;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -42,20 +47,8 @@ public class FilledJarItem extends JarItem implements ChameleonItem {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult onGroundTick(IItemEntity item) {
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getProjectileDamage(ItemStack stack) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile, EntityHitResult hit) {
|
||||
super.onImpact(projectile, hit);
|
||||
|
||||
Entity entity = hit.getEntity();
|
||||
|
||||
if (!entity.isAttackable() || !(projectile instanceof FlyingItemEntity)) {
|
||||
|
|
|
@ -5,37 +5,19 @@ import org.jetbrains.annotations.Nullable;
|
|||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.projectile.PhysicsBodyProjectileEntity;
|
||||
|
||||
import net.minecraft.block.DispenserBlock;
|
||||
import net.minecraft.block.dispenser.ProjectileDispenserBehavior;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.PersistentProjectileEntity;
|
||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.util.math.Position;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class HeavyProjectileItem extends ProjectileItem {
|
||||
|
||||
public HeavyProjectileItem(Settings settings, float projectileDamage) {
|
||||
super(settings, projectileDamage);
|
||||
DispenserBlock.registerBehavior(this, new ProjectileDispenserBehavior(){
|
||||
@Override
|
||||
protected ProjectileEntity createProjectile(World world, Position position, ItemStack stack) {
|
||||
ProjectileEntity projectile = HeavyProjectileItem.this.createProjectile(stack, world, null);
|
||||
projectile.setPosition(position.getX(), position.getY(), position.getZ());
|
||||
return projectile;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getVariation() {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PhysicsBodyProjectileEntity createProjectile(ItemStack stack, World world, @Nullable PlayerEntity player) {
|
||||
public PhysicsBodyProjectileEntity createProjectile(ItemStack stack, World world, @Nullable PlayerEntity player) {
|
||||
PhysicsBodyProjectileEntity projectile = player == null ? new PhysicsBodyProjectileEntity(world) : new PhysicsBodyProjectileEntity(world, player);
|
||||
if (player != null) {
|
||||
projectile.setVelocity(player, player.getPitch(), player.getYaw(), 0, 1.5F, 1);
|
||||
|
@ -46,7 +28,7 @@ public class HeavyProjectileItem extends ProjectileItem {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected SoundEvent getThrowSound(ItemStack stack) {
|
||||
public SoundEvent getThrowSound(ItemStack stack) {
|
||||
return USounds.ENTITY_JAR_THROW;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ public class HorseShoeItem extends HeavyProjectileItem {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected PhysicsBodyProjectileEntity createProjectile(ItemStack stack, World world, @Nullable PlayerEntity player) {
|
||||
public PhysicsBodyProjectileEntity createProjectile(ItemStack stack, World world, @Nullable PlayerEntity player) {
|
||||
PhysicsBodyProjectileEntity projectile = super.createProjectile(stack, world, player);
|
||||
projectile.setDamageType(UDamageTypes.HORSESHOE);
|
||||
|
||||
|
@ -99,7 +99,7 @@ public class HorseShoeItem extends HeavyProjectileItem {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected SoundEvent getThrowSound(ItemStack stack) {
|
||||
public SoundEvent getThrowSound(ItemStack stack) {
|
||||
return USounds.Vanilla.ITEM_TRIDENT_THROW;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ public class JarInsertRecipe extends ItemCombinationRecipe {
|
|||
|
||||
@Override
|
||||
protected boolean isInsertItem(ItemStack stack) {
|
||||
return !(stack.getItem() instanceof JarItem);
|
||||
return !(stack.getItem() instanceof EmptyJarItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,150 +0,0 @@
|
|||
package com.minelittlepony.unicopia.item;
|
||||
|
||||
import com.minelittlepony.unicopia.AwaitTickQueue;
|
||||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.entity.IItemEntity;
|
||||
import com.minelittlepony.unicopia.entity.ItemImpl;
|
||||
import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||
import com.minelittlepony.unicopia.particle.UParticles;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileDelegate;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.ItemEntity;
|
||||
import net.minecraft.entity.LightningEntity;
|
||||
import net.minecraft.entity.Entity.RemovalReason;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.math.ChunkSectionPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.Heightmap;
|
||||
import net.minecraft.world.WorldEvents;
|
||||
|
||||
public class JarItem extends ProjectileItem implements ItemImpl.GroundTickCallback, ProjectileDelegate.HitListener {
|
||||
|
||||
private final boolean rain;
|
||||
private final boolean thunder;
|
||||
private final boolean lightning;
|
||||
|
||||
public JarItem(Settings settings, boolean rain, boolean thunder, boolean lightning) {
|
||||
super(settings, 0.5F);
|
||||
this.rain = rain;
|
||||
this.thunder = thunder;
|
||||
this.lightning = lightning;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult onGroundTick(IItemEntity item) {
|
||||
ItemEntity entity = item.get().asEntity();
|
||||
|
||||
entity.setInvulnerable(true);
|
||||
|
||||
if (!lightning
|
||||
&& !entity.getWorld().isClient
|
||||
&& !entity.isRemoved()
|
||||
&& entity.getItemAge() > 100
|
||||
&& entity.getWorld().isThundering()
|
||||
&& entity.getWorld().isSkyVisible(entity.getBlockPos())
|
||||
&& entity.getWorld().random.nextInt(130) == 0) {
|
||||
LightningEntity lightning = EntityType.LIGHTNING_BOLT.create(entity.getWorld());
|
||||
lightning.refreshPositionAfterTeleport(entity.getX(), entity.getY(), entity.getZ());
|
||||
|
||||
entity.remove(RemovalReason.DISCARDED);
|
||||
entity.getWorld().spawnEntity(lightning);
|
||||
|
||||
ItemEntity neu = EntityType.ITEM.create(entity.getWorld());
|
||||
neu.copyPositionAndRotation(entity);
|
||||
neu.setStack(new ItemStack(this == UItems.RAIN_CLOUD_JAR ? UItems.STORM_CLOUD_JAR : UItems.LIGHTNING_JAR));
|
||||
neu.setInvulnerable(true);
|
||||
|
||||
entity.getWorld().spawnEntity(neu);
|
||||
|
||||
ItemEntity copy = EntityType.ITEM.create(entity.getWorld());
|
||||
copy.copyPositionAndRotation(entity);
|
||||
copy.setInvulnerable(true);
|
||||
copy.setStack(entity.getStack());
|
||||
copy.getStack().decrement(1);
|
||||
|
||||
entity.getWorld().spawnEntity(copy);
|
||||
}
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SoundEvent getThrowSound(ItemStack stack) {
|
||||
return USounds.ENTITY_JAR_THROW;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile) {
|
||||
if (!projectile.getWorld().isClient()) {
|
||||
ServerWorld world = (ServerWorld)projectile.getWorld();
|
||||
|
||||
if (rain || thunder) {
|
||||
// clear weather time = number of ticks for which the weather is clear
|
||||
// rain time = ticks until rain gets toggled (reset the tick after toggling)
|
||||
// thunder time = ticks until thundering gets toggled (reset the tick after toggling)
|
||||
|
||||
// clear weather time
|
||||
// Number of ticks weather must stay clear.
|
||||
// Raining and thundering, and raining/thundering times are kept to false and 0
|
||||
// when clear weather time is <= 0
|
||||
// - wait for thunder time to reach zero then toggle thundering
|
||||
// - wait for rain time to reach zero then toggle raining
|
||||
// when thunder time is <= 0
|
||||
// - randomly pick a new value for thunder time
|
||||
// when rain time is <= 0
|
||||
// - randomly pick a new value for rain time
|
||||
|
||||
world.setWeather(0, 0, rain, thunder);
|
||||
|
||||
if (thunder) {
|
||||
for (int i = world.random.nextInt(7); i > 0; i--) {
|
||||
AwaitTickQueue.scheduleTask(world, w -> {
|
||||
LightningEntity bolt = EntityType.LIGHTNING_BOLT.create(world);
|
||||
bolt.setCosmetic(true);
|
||||
bolt.refreshPositionAfterTeleport(Vec3d.ofBottomCenter(world.getTopPosition(Heightmap.Type.MOTION_BLOCKING, world.getRandomPosInChunk(
|
||||
ChunkSectionPos.getBlockCoord(ChunkSectionPos.getSectionCoord(projectile.getX())),
|
||||
0,
|
||||
ChunkSectionPos.getBlockCoord(ChunkSectionPos.getSectionCoord(projectile.getZ())),
|
||||
15
|
||||
)).up(32)));
|
||||
world.spawnEntity(bolt);
|
||||
}, 15 + world.random.nextInt(12));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lightning) {
|
||||
LightningEntity lightning = EntityType.LIGHTNING_BOLT.create(world);
|
||||
lightning.refreshPositionAfterTeleport(projectile.getX(), projectile.getY(), projectile.getZ());
|
||||
|
||||
world.spawnEntity(lightning);
|
||||
}
|
||||
}
|
||||
|
||||
if (lightning) {
|
||||
ParticleUtils.spawnParticle(projectile.getWorld(), LightningBoltParticleEffect.DEFAULT, projectile.getPos(), Vec3d.ZERO);
|
||||
}
|
||||
|
||||
if (rain || thunder) {
|
||||
projectile.getWorld().syncWorldEvent(WorldEvents.SPLASH_POTION_SPLASHED, projectile.getBlockPos(), thunder ? 0x888888 : 0xF8F8F8);
|
||||
|
||||
for (int i = projectile.getWorld().random.nextInt(3) + 1; i >= 0; i--) {
|
||||
ParticleUtils.spawnParticle(projectile.getWorld(), UParticles.CLOUDS_ESCAPING,
|
||||
projectile.getX(), projectile.getY(), projectile.getZ(),
|
||||
projectile.getWorld().random.nextFloat() - 0.5,
|
||||
0,
|
||||
projectile.getWorld().random.nextFloat() - 0.5
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
projectile.getWorld().syncWorldEvent(WorldEvents.BLOCK_BROKEN, projectile.getBlockPos(), Block.getRawIdFromState(Blocks.GLASS.getDefaultState()));
|
||||
}
|
||||
}
|
|
@ -10,13 +10,12 @@ import net.minecraft.item.ItemStack;
|
|||
import net.minecraft.world.World;
|
||||
|
||||
public class MuffinItem extends HeavyProjectileItem {
|
||||
|
||||
public MuffinItem(Settings settings, float projectileDamage) {
|
||||
super(settings, projectileDamage);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PhysicsBodyProjectileEntity createProjectile(ItemStack stack, World world, @Nullable PlayerEntity player) {
|
||||
public PhysicsBodyProjectileEntity createProjectile(ItemStack stack, World world, @Nullable PlayerEntity player) {
|
||||
PhysicsBodyProjectileEntity projectile = super.createProjectile(stack, world, player);
|
||||
projectile.setBouncy();
|
||||
projectile.setDamage(0);
|
||||
|
|
|
@ -1,72 +1,34 @@
|
|||
package com.minelittlepony.unicopia.item;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.util.SoundEmitter;
|
||||
|
||||
import com.minelittlepony.unicopia.projectile.Projectile;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.stat.Stats;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
abstract class ProjectileItem extends Item {
|
||||
abstract class ProjectileItem extends Item implements Projectile {
|
||||
|
||||
private final float projectileDamage;
|
||||
|
||||
public ProjectileItem(Settings settings, float projectileDamage) {
|
||||
super(settings);
|
||||
this.projectileDamage = projectileDamage;
|
||||
Projectile.makeDispensable(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypedActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand) {
|
||||
|
||||
if (isFood() && !player.isSneaking()) {
|
||||
if (isFood() && !player.shouldCancelInteraction()) {
|
||||
return super.use(world, player, hand);
|
||||
}
|
||||
|
||||
ItemStack stack = player.getStackInHand(hand);
|
||||
|
||||
SoundEmitter.playSoundAt(player,
|
||||
getThrowSound(stack), SoundCategory.NEUTRAL,
|
||||
0.5F,
|
||||
0.4F / (world.random.nextFloat() * 0.4F + 0.8F));
|
||||
|
||||
if (!world.isClient) {
|
||||
world.spawnEntity(createProjectile(stack.copyWithCount(1), world, player));
|
||||
}
|
||||
|
||||
player.incrementStat(Stats.USED.getOrCreateStat(this));
|
||||
|
||||
if (!player.isCreative()) {
|
||||
stack.decrement(1);
|
||||
}
|
||||
|
||||
return TypedActionResult.success(stack, world.isClient());
|
||||
return triggerThrow(world, player, hand);
|
||||
}
|
||||
|
||||
protected ProjectileEntity createProjectile(ItemStack stack, World world, @Nullable PlayerEntity player) {
|
||||
MagicProjectileEntity projectile = player == null ? new MagicProjectileEntity(world) : new MagicProjectileEntity(world, player);
|
||||
projectile.setItem(stack);
|
||||
projectile.setThrowDamage(getProjectileDamage(stack));
|
||||
projectile.setMaxAge(-1);
|
||||
if (player != null) {
|
||||
projectile.setVelocity(player, player.getPitch(), player.getYaw(), 0, 1.5F, 1);
|
||||
}
|
||||
return projectile;
|
||||
}
|
||||
|
||||
protected abstract SoundEvent getThrowSound(ItemStack stack);
|
||||
|
||||
protected float getProjectileDamage(ItemStack stack) {
|
||||
@Override
|
||||
public float getProjectileDamage(ItemStack stack) {
|
||||
return projectileDamage;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -50,12 +50,12 @@ public interface UItems {
|
|||
FriendshipBraceletItem FRIENDSHIP_BRACELET = register("friendship_bracelet", new FriendshipBraceletItem(new FabricItemSettings().rarity(Rarity.UNCOMMON)), ItemGroups.TOOLS);
|
||||
|
||||
Item PLUNDER_VINE = register("plunder_vine", new BlockItem(UBlocks.PLUNDER_VINE_BUD, new Item.Settings()));
|
||||
Item EMPTY_JAR = register("empty_jar", new JarItem(new Item.Settings().fireproof(), false, false, false), ItemGroups.FUNCTIONAL);
|
||||
Item EMPTY_JAR = register("empty_jar", new EmptyJarItem(UBlocks.JAR, new Item.Settings().fireproof()), ItemGroups.FUNCTIONAL);
|
||||
FilledJarItem FILLED_JAR = register("filled_jar", new FilledJarItem(new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR)));
|
||||
Item RAIN_CLOUD_JAR = register("rain_cloud_jar", new JarItem(new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), true, false, false), ItemGroups.FUNCTIONAL);
|
||||
Item STORM_CLOUD_JAR = register("storm_cloud_jar", new JarItem(new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), true, true, false), ItemGroups.FUNCTIONAL);
|
||||
Item LIGHTNING_JAR = register("lightning_jar", new JarItem(new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), false, false, true), ItemGroups.FUNCTIONAL);
|
||||
Item ZAP_APPLE_JAM_JAR = register("zap_apple_jam_jar", new JarItem(new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), false, false, true), ItemGroups.FUNCTIONAL);
|
||||
Item RAIN_CLOUD_JAR = register("rain_cloud_jar", new WeatherJarItem(UBlocks.CLOUD_JAR, new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), WeatherJarItem.Type.RAIN), ItemGroups.FUNCTIONAL);
|
||||
Item STORM_CLOUD_JAR = register("storm_cloud_jar", new WeatherJarItem(UBlocks.STORM_JAR, new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), WeatherJarItem.Type.THUNDER), ItemGroups.FUNCTIONAL);
|
||||
Item LIGHTNING_JAR = register("lightning_jar", new WeatherJarItem(UBlocks.LIGHTNING_JAR, new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), WeatherJarItem.Type.LIGHTNING), ItemGroups.FUNCTIONAL);
|
||||
Item ZAP_APPLE_JAM_JAR = register("zap_apple_jam_jar", new WeatherJarItem(UBlocks.ZAP_JAR, new Item.Settings().maxCount(16).fireproof().recipeRemainder(EMPTY_JAR), WeatherJarItem.Type.LIGHTNING), ItemGroups.FUNCTIONAL);
|
||||
|
||||
Item TOAST = register("toast", new Item(new Item.Settings().maxCount(16).food(UFoodComponents.TOAST)), ItemGroups.FOOD_AND_DRINK);
|
||||
Item BURNED_TOAST = register("burned_toast", new Item(new Item.Settings().maxCount(16).food(UFoodComponents.BURNED_TOAST)), ItemGroups.FOOD_AND_DRINK);
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
package com.minelittlepony.unicopia.item;
|
||||
|
||||
import com.minelittlepony.unicopia.AwaitTickQueue;
|
||||
import com.minelittlepony.unicopia.USounds;
|
||||
import com.minelittlepony.unicopia.particle.LightningBoltParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.ParticleUtils;
|
||||
import com.minelittlepony.unicopia.particle.UParticles;
|
||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||
import com.minelittlepony.unicopia.projectile.Projectile;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileDelegate;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LightningEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.AliasedBlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkSectionPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.Heightmap;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldEvents;
|
||||
|
||||
public class WeatherJarItem extends AliasedBlockItem implements Projectile, ProjectileDelegate.HitListener {
|
||||
private final Type type;
|
||||
|
||||
public WeatherJarItem(Block block, Settings settings, Type type) {
|
||||
super(block, settings);
|
||||
this.type = type;
|
||||
Projectile.makeDispensable(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundEvent getThrowSound(ItemStack stack) {
|
||||
return USounds.ENTITY_JAR_THROW;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getProjectileDamage(ItemStack stack) {
|
||||
return 0.5F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypedActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand) {
|
||||
if (player.shouldCancelInteraction()) {
|
||||
return super.use(world, player, hand);
|
||||
}
|
||||
return triggerThrow(world, player, hand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImpact(MagicProjectileEntity projectile) {
|
||||
releaseContents(projectile.getWorld(), projectile.getBlockPos());
|
||||
}
|
||||
|
||||
public void releaseContents(World world, BlockPos pos) {
|
||||
if (!world.isClient()) {
|
||||
ServerWorld sw = (ServerWorld)world;
|
||||
|
||||
if (type == Type.RAIN || type == Type.THUNDER) {
|
||||
// clear weather time = number of ticks for which the weather is clear
|
||||
// rain time = ticks until rain gets toggled (reset the tick after toggling)
|
||||
// thunder time = ticks until thundering gets toggled (reset the tick after toggling)
|
||||
|
||||
// clear weather time
|
||||
// Number of ticks weather must stay clear.
|
||||
// Raining and thundering, and raining/thundering times are kept to false and 0
|
||||
// when clear weather time is <= 0
|
||||
// - wait for thunder time to reach zero then toggle thundering
|
||||
// - wait for rain time to reach zero then toggle raining
|
||||
// when thunder time is <= 0
|
||||
// - randomly pick a new value for thunder time
|
||||
// when rain time is <= 0
|
||||
// - randomly pick a new value for rain time
|
||||
|
||||
sw.setWeather(0, 0, type == Type.RAIN, type == Type.THUNDER);
|
||||
|
||||
if (type == Type.THUNDER) {
|
||||
for (int i = world.random.nextInt(7); i > 0; i--) {
|
||||
AwaitTickQueue.scheduleTask(world, w -> {
|
||||
LightningEntity bolt = EntityType.LIGHTNING_BOLT.create(world);
|
||||
bolt.setCosmetic(true);
|
||||
bolt.refreshPositionAfterTeleport(Vec3d.ofBottomCenter(world.getTopPosition(Heightmap.Type.MOTION_BLOCKING, world.getRandomPosInChunk(
|
||||
ChunkSectionPos.getBlockCoord(ChunkSectionPos.getSectionCoord(pos.getX())),
|
||||
0,
|
||||
ChunkSectionPos.getBlockCoord(ChunkSectionPos.getSectionCoord(pos.getZ())),
|
||||
15
|
||||
)).up(32)));
|
||||
world.spawnEntity(bolt);
|
||||
}, 15 + world.random.nextInt(12));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type == Type.LIGHTNING) {
|
||||
LightningEntity lightning = EntityType.LIGHTNING_BOLT.create(world);
|
||||
lightning.refreshPositionAfterTeleport(pos.getX(), pos.getY(), pos.getZ());
|
||||
|
||||
world.spawnEntity(lightning);
|
||||
}
|
||||
}
|
||||
|
||||
Vec3d centerPos = pos.toCenterPos();
|
||||
|
||||
if (type == Type.LIGHTNING) {
|
||||
ParticleUtils.spawnParticle(world, LightningBoltParticleEffect.DEFAULT, centerPos, Vec3d.ZERO);
|
||||
}
|
||||
|
||||
if (type == Type.RAIN || type == Type.THUNDER) {
|
||||
world.syncWorldEvent(WorldEvents.SPLASH_POTION_SPLASHED, pos, type == Type.THUNDER ? 0x888888 : 0xF8F8F8);
|
||||
|
||||
for (int i = world.random.nextInt(3) + 1; i >= 0; i--) {
|
||||
ParticleUtils.spawnParticle(world, UParticles.CLOUDS_ESCAPING,
|
||||
centerPos.getX(), centerPos.getY(), centerPos.getZ(),
|
||||
world.random.nextFloat() - 0.5,
|
||||
0,
|
||||
world.random.nextFloat() - 0.5
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
world.syncWorldEvent(WorldEvents.BLOCK_BROKEN, pos, Block.getRawIdFromState(Blocks.GLASS.getDefaultState()));
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
RAIN,
|
||||
THUNDER,
|
||||
LIGHTNING
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package com.minelittlepony.unicopia.projectile;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.util.SoundEmitter;
|
||||
|
||||
import net.minecraft.block.DispenserBlock;
|
||||
import net.minecraft.block.dispenser.ProjectileDispenserBehavior;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
import net.minecraft.item.ItemConvertible;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.stat.Stats;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
import net.minecraft.util.math.Position;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface Projectile extends ItemConvertible {
|
||||
static void makeDispensable(Projectile projectile) {
|
||||
DispenserBlock.registerBehavior(projectile.asItem(), new ProjectileDispenserBehavior(){
|
||||
@Override
|
||||
protected ProjectileEntity createProjectile(World world, Position position, ItemStack stack) {
|
||||
ProjectileEntity p = projectile.createProjectile(stack, world, null);
|
||||
p.setPosition(position.getX(), position.getY(), position.getZ());
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getVariation() {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
default TypedActionResult<ItemStack> triggerThrow(World world, PlayerEntity player, Hand hand) {
|
||||
ItemStack stack = player.getStackInHand(hand);
|
||||
|
||||
SoundEmitter.playSoundAt(player,
|
||||
getThrowSound(stack), SoundCategory.NEUTRAL,
|
||||
0.5F,
|
||||
0.4F / (world.random.nextFloat() * 0.4F + 0.8F));
|
||||
|
||||
if (!world.isClient) {
|
||||
world.spawnEntity(createProjectile(stack.copyWithCount(1), world, player));
|
||||
}
|
||||
|
||||
player.incrementStat(Stats.USED.getOrCreateStat(asItem()));
|
||||
|
||||
if (!player.isCreative()) {
|
||||
stack.decrement(1);
|
||||
}
|
||||
|
||||
return TypedActionResult.success(stack, world.isClient());
|
||||
}
|
||||
|
||||
default ProjectileEntity createProjectile(ItemStack stack, World world, @Nullable PlayerEntity player) {
|
||||
MagicProjectileEntity projectile = player == null ? new MagicProjectileEntity(world) : new MagicProjectileEntity(world, player);
|
||||
projectile.setItem(stack);
|
||||
projectile.setThrowDamage(getProjectileDamage(stack));
|
||||
projectile.setMaxAge(-1);
|
||||
if (player != null) {
|
||||
projectile.setVelocity(player, player.getPitch(), player.getYaw(), 0, 1.5F, 1);
|
||||
}
|
||||
return projectile;
|
||||
}
|
||||
|
||||
SoundEvent getThrowSound(ItemStack stack);
|
||||
|
||||
float getProjectileDamage(ItemStack stack);
|
||||
}
|
|
@ -81,11 +81,16 @@
|
|||
|
||||
"item.unicopia.plunder_vine": "Plunder Vine",
|
||||
"item.unicopia.empty_jar": "Glass Jar",
|
||||
"block.unicopia.jar": "Glass Jar",
|
||||
"item.unicopia.filled_jar": "%s in a Jar",
|
||||
"item.unicopia.rain_cloud_jar": "Rain in a Jar",
|
||||
"item.unicopia.cloud_jar": "Rain in a Jar",
|
||||
"item.unicopia.storm_cloud_jar": "Storm in a Jar",
|
||||
"block.unicopia.storm_jar": "Storm in a Jar",
|
||||
"item.unicopia.lightning_jar": "Lightning in a Jar",
|
||||
"block.unicopia.lightning_jar": "Lightning in a Jar",
|
||||
"item.unicopia.zap_apple_jam_jar": "Zap Apple Jam",
|
||||
"block.unicopia.zap_jar": "Jar of Zap Apple Jam",
|
||||
|
||||
"item.unicopia.toast": "Toast",
|
||||
"item.unicopia.burned_toast": "Burned Toast",
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
"textures": {
|
||||
"cloud": "unicopia:block/cloud",
|
||||
"particle": "#cloud"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [5.1, 6.1, 5.1],
|
||||
"to": [9.9, 8.9, 8.9],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 2, 8, 12], "texture": "#cloud"},
|
||||
"east": {"uv": [0, 6, 8, 16], "texture": "#cloud"},
|
||||
"south": {"uv": [8, 6, 16, 16], "texture": "#cloud"},
|
||||
"west": {"uv": [8, 0, 16, 10], "texture": "#cloud"},
|
||||
"up": {"uv": [4, 3, 12, 11], "texture": "#cloud"},
|
||||
"down": {"uv": [8, 4, 16, 12], "texture": "#cloud"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [6.1, 4.1, 7.1],
|
||||
"to": [11.9, 6.9, 10.9],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 2, 8, 12], "texture": "#cloud"},
|
||||
"east": {"uv": [0, 6, 8, 16], "texture": "#cloud"},
|
||||
"south": {"uv": [8, 6, 16, 16], "texture": "#cloud"},
|
||||
"west": {"uv": [8, 0, 16, 10], "texture": "#cloud"},
|
||||
"up": {"uv": [4, 3, 12, 11], "texture": "#cloud"},
|
||||
"down": {"uv": [8, 4, 16, 12], "texture": "#cloud"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [6.1, 8.1, 7.1],
|
||||
"to": [9.9, 9.9, 9.9],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 2, 8, 12], "texture": "#cloud"},
|
||||
"east": {"uv": [0, 6, 8, 16], "texture": "#cloud"},
|
||||
"south": {"uv": [8, 6, 16, 16], "texture": "#cloud"},
|
||||
"west": {"uv": [8, 0, 16, 10], "texture": "#cloud"},
|
||||
"up": {"uv": [4, 3, 12, 11], "texture": "#cloud"},
|
||||
"down": {"uv": [8, 4, 16, 12], "texture": "#cloud"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [6.1, 7.1, 8.1],
|
||||
"to": [10.9, 8.9, 10.9],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 2, 8, 12], "texture": "#cloud"},
|
||||
"east": {"uv": [0, 6, 8, 16], "texture": "#cloud"},
|
||||
"south": {"uv": [8, 6, 16, 16], "texture": "#cloud"},
|
||||
"west": {"uv": [8, 0, 16, 10], "texture": "#cloud"},
|
||||
"up": {"uv": [4, 3, 12, 11], "texture": "#cloud"},
|
||||
"down": {"uv": [8, 4, 16, 12], "texture": "#cloud"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"textures": {
|
||||
"filling": "unicopia:block/lightning_jar_filling",
|
||||
"particle": "#filling"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [6, 1, 7.5],
|
||||
"to": [11, 11, 7.5],
|
||||
"rotation": {"angle": -45, "axis": "y", "origin": [8, 5, 7], "rescale": true},
|
||||
"faces": {
|
||||
"north": {"uv": [3, 0, 13, 16], "texture": "#filling"},
|
||||
"east": {"uv": [0, 0, 0, 8], "texture": "#filling"},
|
||||
"south": {"uv": [3, 0, 13, 16], "texture": "#filling"},
|
||||
"west": {"uv": [0, 0, 0, 8], "texture": "#filling"},
|
||||
"up": {"uv": [0, 0, 6, 0], "texture": "#filling"},
|
||||
"down": {"uv": [0, 0, 6, 0], "texture": "#filling"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [5, 1, 7.5],
|
||||
"to": [10, 11, 7.5],
|
||||
"rotation": {"angle": 45, "axis": "y", "origin": [8, 5, 7], "rescale": true},
|
||||
"faces": {
|
||||
"north": {"uv": [3, 0, 13, 16], "texture": "#filling"},
|
||||
"east": {"uv": [0, 0, 0, 8], "texture": "#filling"},
|
||||
"south": {"uv": [3, 0, 13, 16], "texture": "#filling"},
|
||||
"west": {"uv": [0, 0, 0, 8], "texture": "#filling"},
|
||||
"up": {"uv": [0, 0, 6, 0], "rotation": 180, "texture": "#filling"},
|
||||
"down": {"uv": [0, 0, 6, 0], "rotation": 180, "texture": "#filling"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
{
|
||||
"textures": {
|
||||
"cloud": "unicopia:block/cloud",
|
||||
"particle": "#cloud"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [4.1, 3.1, 4.1],
|
||||
"to": [11.9, 11.9, 11.9],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 2, 8, 12], "texture": "#cloud"},
|
||||
"east": {"uv": [0, 6, 8, 16], "texture": "#cloud"},
|
||||
"south": {"uv": [8, 6, 16, 16], "texture": "#cloud"},
|
||||
"west": {"uv": [8, 0, 16, 10], "texture": "#cloud"},
|
||||
"up": {"uv": [4, 3, 12, 11], "texture": "#cloud"},
|
||||
"down": {"uv": [8, 4, 16, 12], "texture": "#cloud"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [6.1, 2.1, 5.1],
|
||||
"to": [10.9, 2.9, 10.9],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 2, 8, 12], "texture": "#cloud"},
|
||||
"east": {"uv": [0, 6, 8, 16], "texture": "#cloud"},
|
||||
"south": {"uv": [8, 6, 16, 16], "texture": "#cloud"},
|
||||
"west": {"uv": [8, 0, 16, 10], "texture": "#cloud"},
|
||||
"up": {"uv": [4, 3, 12, 11], "texture": "#cloud"},
|
||||
"down": {"uv": [8, 4, 16, 12], "texture": "#cloud"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [7.1, 11.1, 6.1],
|
||||
"to": [12.9, 13.9, 9.9],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 2, 8, 12], "texture": "#cloud"},
|
||||
"east": {"uv": [0, 6, 8, 16], "texture": "#cloud"},
|
||||
"south": {"uv": [8, 6, 16, 16], "texture": "#cloud"},
|
||||
"west": {"uv": [8, 0, 16, 10], "texture": "#cloud"},
|
||||
"up": {"uv": [4, 3, 12, 11], "texture": "#cloud"},
|
||||
"down": {"uv": [8, 4, 16, 12], "texture": "#cloud"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [3, 9, 10],
|
||||
"to": [5, 11, 12],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 2, 8, 12], "texture": "#cloud"},
|
||||
"east": {"uv": [0, 6, 8, 16], "texture": "#cloud"},
|
||||
"south": {"uv": [8, 6, 16, 16], "texture": "#cloud"},
|
||||
"west": {"uv": [8, 0, 16, 10], "texture": "#cloud"},
|
||||
"up": {"uv": [4, 3, 12, 11], "texture": "#cloud"},
|
||||
"down": {"uv": [8, 4, 16, 12], "texture": "#cloud"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [3.1, 10.1, 7.1],
|
||||
"to": [8.9, 12.9, 10.9],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 2, 8, 12], "texture": "#cloud"},
|
||||
"east": {"uv": [0, 6, 8, 16], "texture": "#cloud"},
|
||||
"south": {"uv": [8, 6, 16, 16], "texture": "#cloud"},
|
||||
"west": {"uv": [8, 0, 16, 10], "texture": "#cloud"},
|
||||
"up": {"uv": [4, 3, 12, 11], "texture": "#cloud"},
|
||||
"down": {"uv": [8, 4, 16, 12], "texture": "#cloud"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [11, 10, 9],
|
||||
"to": [13, 12, 11],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 2, 8, 12], "texture": "#cloud"},
|
||||
"east": {"uv": [0, 6, 8, 16], "texture": "#cloud"},
|
||||
"south": {"uv": [8, 6, 16, 16], "texture": "#cloud"},
|
||||
"west": {"uv": [8, 0, 16, 10], "texture": "#cloud"},
|
||||
"up": {"uv": [4, 3, 12, 11], "texture": "#cloud"},
|
||||
"down": {"uv": [8, 4, 16, 12], "texture": "#cloud"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [9, 13, 7],
|
||||
"to": [11, 15, 9],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 2, 8, 12], "texture": "#cloud"},
|
||||
"east": {"uv": [0, 6, 8, 16], "texture": "#cloud"},
|
||||
"south": {"uv": [8, 6, 16, 16], "texture": "#cloud"},
|
||||
"west": {"uv": [8, 0, 16, 10], "texture": "#cloud"},
|
||||
"up": {"uv": [4, 3, 12, 11], "texture": "#cloud"},
|
||||
"down": {"uv": [8, 4, 16, 12], "texture": "#cloud"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [5, 13, 7],
|
||||
"to": [7, 15, 9],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 2, 8, 12], "texture": "#cloud"},
|
||||
"east": {"uv": [0, 6, 8, 16], "texture": "#cloud"},
|
||||
"south": {"uv": [8, 6, 16, 16], "texture": "#cloud"},
|
||||
"west": {"uv": [8, 0, 16, 10], "texture": "#cloud"},
|
||||
"up": {"uv": [4, 3, 12, 11], "texture": "#cloud"},
|
||||
"down": {"uv": [8, 4, 16, 12], "texture": "#cloud"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [3, 8, 5],
|
||||
"to": [5, 10, 7],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 2, 8, 12], "texture": "#cloud"},
|
||||
"east": {"uv": [0, 6, 8, 16], "texture": "#cloud"},
|
||||
"south": {"uv": [8, 6, 16, 16], "texture": "#cloud"},
|
||||
"west": {"uv": [8, 0, 16, 10], "texture": "#cloud"},
|
||||
"up": {"uv": [4, 3, 12, 11], "texture": "#cloud"},
|
||||
"down": {"uv": [8, 4, 16, 12], "texture": "#cloud"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [6.1, 10.1, 7.1],
|
||||
"to": [9.9, 11.9, 9.9],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 2, 8, 12], "texture": "#cloud"},
|
||||
"east": {"uv": [0, 6, 8, 16], "texture": "#cloud"},
|
||||
"south": {"uv": [8, 6, 16, 16], "texture": "#cloud"},
|
||||
"west": {"uv": [8, 0, 16, 10], "texture": "#cloud"},
|
||||
"up": {"uv": [4, 3, 12, 11], "texture": "#cloud"},
|
||||
"down": {"uv": [8, 4, 16, 12], "texture": "#cloud"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [6.1, 11.1, 9.1],
|
||||
"to": [10.9, 12.9, 11.9],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 2, 8, 12], "texture": "#cloud"},
|
||||
"east": {"uv": [0, 6, 8, 16], "texture": "#cloud"},
|
||||
"south": {"uv": [8, 6, 16, 16], "texture": "#cloud"},
|
||||
"west": {"uv": [8, 0, 16, 10], "texture": "#cloud"},
|
||||
"up": {"uv": [4, 3, 12, 11], "texture": "#cloud"},
|
||||
"down": {"uv": [8, 4, 16, 12], "texture": "#cloud"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"textures": {
|
||||
"body": "unicopia:block/jar_body",
|
||||
"cork": "unicopia:block/jar_cork",
|
||||
"particle": "#body"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [4, 0, 4],
|
||||
"to": [12, 12, 12],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 8, 12], "texture": "#body"},
|
||||
"east": {"uv": [0, 0, 8, 12], "texture": "#body"},
|
||||
"south": {"uv": [0, 0, 8, 12], "texture": "#body"},
|
||||
"west": {"uv": [0, 0, 8, 12], "texture": "#body"},
|
||||
"up": {"uv": [8, 0, 16, 8], "texture": "#body"},
|
||||
"down": {"uv": [8, 0, 16, 8], "texture": "#body"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [5, 13, 5],
|
||||
"to": [11, 14, 11],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 8, 1], "texture": "#body"},
|
||||
"east": {"uv": [0, 0, 8, 1], "texture": "#body"},
|
||||
"south": {"uv": [0, 0, 8, 1], "texture": "#body"},
|
||||
"west": {"uv": [0, 0, 8, 1], "texture": "#body"},
|
||||
"up": {"uv": [8, 0, 16, 8], "texture": "#body"},
|
||||
"down": {"uv": [8, 0, 16, 8], "texture": "#body"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [6, 12, 6],
|
||||
"to": [10, 13, 10],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 8, 1], "texture": "#body"},
|
||||
"east": {"uv": [0, 0, 8, 1], "texture": "#body"},
|
||||
"south": {"uv": [0, 0, 8, 1], "texture": "#body"},
|
||||
"west": {"uv": [0, 0, 8, 1], "texture": "#body"},
|
||||
"up": {"uv": [8, 0, 16, 8], "texture": "#body"},
|
||||
"down": {"uv": [8, 0, 16, 8], "texture": "#body"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [6, 13, 6],
|
||||
"to": [10, 16, 10],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 4, 4, 7], "texture": "#cork"},
|
||||
"east": {"uv": [0, 4, 4, 7], "texture": "#cork"},
|
||||
"south": {"uv": [0, 4, 4, 7], "texture": "#cork"},
|
||||
"west": {"uv": [0, 4, 4, 7], "texture": "#cork"},
|
||||
"up": {"uv": [0, 0, 4, 4], "texture": "#cork"},
|
||||
"down": {"uv": [4, 0, 8, 4], "texture": "#cork"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"textures": {
|
||||
"filling": "unicopia:block/zap_jar_filling",
|
||||
"particle": "#filling"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [4.1, 0.1, 4.1],
|
||||
"to": [11.9, 9.9, 11.9],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 2, 8, 12], "texture": "#filling"},
|
||||
"east": {"uv": [0, 6, 8, 16], "texture": "#filling"},
|
||||
"south": {"uv": [8, 6, 16, 16], "texture": "#filling"},
|
||||
"west": {"uv": [8, 0, 16, 10], "texture": "#filling"},
|
||||
"up": {"uv": [4, 3, 12, 11], "texture": "#filling"},
|
||||
"down": {"uv": [8, 4, 16, 12], "texture": "#filling"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
BIN
src/main/resources/assets/unicopia/textures/block/jar_body.png
Normal file
After Width: | Height: | Size: 220 B |
BIN
src/main/resources/assets/unicopia/textures/block/jar_cork.png
Normal file
After Width: | Height: | Size: 136 B |
After Width: | Height: | Size: 8.7 KiB |
After Width: | Height: | Size: 9.3 KiB |