/
PanItem.java
195 lines (173 loc) · 6.5 KB
/
PanItem.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
package skelyvelocirap.panning.items;
import java.util.List;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.monster.EndermanEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluid;
import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tags.ITag;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.RayTraceContext.FluidMode;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import skelyvelocirap.panning.setup.PanningAction;
import skelyvelocirap.panning.setup.registries.Pannable;
public class PanItem extends Item {
public static int itemUseTicks = 200;
public PanItem(Properties properties) {
super(properties);
}
@Override
public int getUseDuration(ItemStack stack) {
return itemUseTicks;
}
@Override
public int getMaxDamage(ItemStack stack) {
return getUseDuration(stack);
}
@Override
public boolean canEquip(ItemStack stack, EquipmentSlotType armorType, Entity entity) {
return armorType == EquipmentSlotType.HEAD;
}
@Override
public boolean isEnderMask(ItemStack stack, PlayerEntity player, EndermanEntity endermanEntity) {
return true;
}
@Override
public void appendHoverText(ItemStack stack, World world, List<ITextComponent> tooltip, ITooltipFlag flag) {
super.appendHoverText(stack, world, tooltip, flag);
}
@Override
public boolean onEntitySwing(ItemStack stack, LivingEntity entity) {
CompoundNBT compound = getNBTTagCompound(stack);
ItemStack inventoryStack = getItemInPan(stack);
if(inventoryStack.isEmpty()) {
World world = entity.level;
if(!world.isClientSide) {
if(entity instanceof PlayerEntity) {
PlayerEntity player = (PlayerEntity)entity;
RayTraceResult traceResult = getPlayerPOVHitResult(world, (PlayerEntity)player, FluidMode.NONE);
if(traceResult.getType() == RayTraceResult.Type.BLOCK) {
BlockRayTraceResult blockTraceResult = (BlockRayTraceResult)traceResult;
BlockPos pos = blockTraceResult.getBlockPos();
if(player.distanceToSqr(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D) < 64.0D) {
Pannable result = PanningAction.blockHasResultForBiome(world, pos);
if(result != null) {
if(touchesLiquid(world, pos, result.getFluidType())) {
saveNBTtoStack(stack, new ItemStack(world.getBlockState(pos).getBlock(), 1), compound);
compound.putLong("pos", pos.asLong());
world.setBlockAndUpdate(pos, Blocks.AIR.defaultBlockState());
}
}
}
}
}
}
}
return super.onEntitySwing(stack, entity);
}
@Override
public ItemStack finishUsingItem(ItemStack stack, World world, LivingEntity entity) {
stack.setDamageValue(0);
CompoundNBT compound = getNBTTagCompound(stack);
ItemStack inventoryStack = getItemInPan(stack);
if(entity instanceof PlayerEntity) {
PlayerEntity player = (PlayerEntity)entity;
if(!world.isClientSide) {
if(!inventoryStack.isEmpty()){
if(PanningAction.inFluidForDrops(player)) {
if(inventoryStack.getItem() instanceof BlockItem) {
List<ItemStack> results = PanningAction.getDrops(player, BlockPos.of(compound.getLong("pos")), ((BlockItem)inventoryStack.getItem()).getBlock(), 1);
for(int i = 0; i < results.size(); i++) {
ItemEntity itemEntity = new ItemEntity(world, player.position().x, player.position().y, player.position().z, results.get(i));
itemEntity.setInvulnerable(true);
itemEntity.fireImmune();
world.addFreshEntity(itemEntity);
player.giveExperiencePoints(Math.round(PanningAction.getExperience(i)));
}
saveNBTtoStack(stack, ItemStack.EMPTY, compound);
} else {
saveNBTtoStack(stack, ItemStack.EMPTY, compound);
return stack;
}
}
}
}
}
return super.finishUsingItem(stack, world, entity);
}
public static void saveNBTtoStack(ItemStack stack, ItemStack newStack, CompoundNBT compound) {
stack = newStack;
stack.save(compound);
}
@Override
public void onUseTick(World world, LivingEntity entity, ItemStack stack, int ticks) {
if(ticks % 3 == 0) {
stack.setDamageValue(stack.getMaxDamage() - ticks);
}
}
@Override
public ActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand) {
ItemStack stack = player.getItemInHand(hand);
if(PanningAction.inFluidForDrops(player)) {
if(!getItemInPan(stack).isEmpty()) {
player.startUsingItem(hand);
if(player.getUseItemRemainingTicks() > 0) {
return ActionResult.pass(stack);
}
return ActionResult.success(stack);
}
}
return ActionResult.pass(stack);
}
@Override
public int getItemStackLimit(ItemStack stack) {
return 1;
}
public CompoundNBT getNBTTagCompound(ItemStack stack) {
CompoundNBT compound = stack.getOrCreateTag();
return compound;
}
@Override
public boolean showDurabilityBar(ItemStack stack) {
return getItemInPan(stack).isEmpty() ? false : true;
}
public ItemStack getItemInPan(ItemStack stack) {
CompoundNBT compound = getNBTTagCompound(stack);
return compound.contains("id") ? ItemStack.of(compound) : ItemStack.EMPTY;
}
public static boolean touchesLiquid(IBlockReader reader, BlockPos pos, ITag<Fluid> fluid) {
boolean flag = false;
BlockPos.Mutable blockpos$mutable = pos.mutable();
for(Direction direction : Direction.values()) {
BlockState blockstate = reader.getBlockState(blockpos$mutable);
if (direction != Direction.DOWN || isFluidType(blockstate, fluid)) {
blockpos$mutable.setWithOffset(pos, direction);
blockstate = reader.getBlockState(blockpos$mutable);
if (isFluidType(blockstate, fluid) && !blockstate.isFaceSturdy(reader, pos, direction.getOpposite())) {
flag = true;
break;
}
}
}
return flag;
}
public static boolean isFluidType(BlockState blockState, ITag<Fluid> fluid) {
return blockState.getFluidState().is(fluid);
}
}