/
EnhancedCauldronBlock.java
163 lines (142 loc) · 5.32 KB
/
EnhancedCauldronBlock.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
package knightminer.inspirations.recipes.block;
import knightminer.inspirations.common.Config;
import knightminer.inspirations.library.recipe.cauldron.util.CauldronTemperature;
import knightminer.inspirations.recipes.InspirationsRecipes;
import knightminer.inspirations.recipes.tileentity.CauldronTileEntity;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.CauldronBlock;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.particles.IParticleData;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType;
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.world.IBlockReader;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import slimeknights.mantle.util.TileEntityHelper;
import java.util.Random;
/**
* Cauldron block exteneded to have a tile entity
*/
@SuppressWarnings("WeakerAccess")
public class EnhancedCauldronBlock extends CauldronBlock {
public EnhancedCauldronBlock(Block.Properties props) {
super(props);
}
/**
* Gets the level of fluid in the cauldron
* @param state State to check
* @return Water level of state
*/
public int getLevel(BlockState state) {
return state.get(LEVEL);
}
@Override
public void setWaterLevel(World world, BlockPos pos, BlockState state, int level) {
if (level != getLevel(state)) {
super.setWaterLevel(world, pos, state, level);
}
}
@Override
public void fillWithRain(World world, BlockPos pos) {
TileEntity te = world.getTileEntity(pos);
// do not fill unless the current contents are water
if (te instanceof CauldronTileEntity && !((CauldronTileEntity)te).getContents().isSimple()) {
return;
}
// allow disabling the random 1/20 chance
if ((Config.fasterCauldronRain.get() || world.rand.nextInt(20) == 0) && world.getBiome(pos).getTemperature(pos) >= 0.15F) {
BlockState state = world.getBlockState(pos);
int level = getLevel(state);
if (level < 3) {
setWaterLevel(world, pos, state, level + 1);
}
}
}
/* TE behavior */
@Override
public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult ray) {
// all moved to the cauldron registry
return ActionResultType.SUCCESS;
}
@Override
public boolean hasTileEntity(BlockState state) {
return true;
}
@Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return new CauldronTileEntity(this);
}
@Override
public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
if (world.isRemote) {
return;
}
// check if an entity hit within the water
int level = getLevel(state);
if (entity.getBoundingBox().minY <= (pos.getY() + (5.5F + (3 * Math.max(level, 1))) / 16.0F)) {
// if so, have the TE handle it
TileEntityHelper.getTile(CauldronTileEntity.class, world, pos).ifPresent(te -> {
int newLevel = te.onEntityCollide(entity, level, state);
// if the level changed, update it
if (level != newLevel) {
this.setWaterLevel(world, pos, state, newLevel);
}
});
}
}
@SuppressWarnings("deprecation")
@Override
@Deprecated
public BlockState updatePostPlacement(BlockState state, Direction facing, BlockState facingState, IWorld world, BlockPos currentPos, BlockPos facingPos) {
// need a method called on both sides, neighborChanged is server only
TileEntityHelper.getTile(CauldronTileEntity.class, world, currentPos).ifPresent(te -> te.neighborChanged(facingPos));
return state;
}
/* Particles */
@Deprecated
@Override
@OnlyIn(Dist.CLIENT)
public void animateTick(BlockState state, World world, BlockPos pos, Random rand) {
int level = getLevel(state);
if (level == 0) {
return;
}
// transform particles
TileEntity te = world.getTileEntity(pos);
if (te instanceof CauldronTileEntity) {
CauldronTileEntity cauldron = (CauldronTileEntity)te;
// boiling particles if boiling
if (cauldron.getTemperature() == CauldronTemperature.BOILING) {
addParticles(InspirationsRecipes.boilingParticle, world, pos, 2, level, rand);
}
// transform particles if performing a recipe
int count = cauldron.getTransformParticles();
addParticles(ParticleTypes.HAPPY_VILLAGER, world, pos, count, level, rand);
}
}
/**
* Adds particles
* @param type Particle type
* @param world World instance
* @param pos Block position
* @param level Fluid level
* @param rand Random instance
*/
private static void addParticles(IParticleData type, World world, BlockPos pos, int count, int level, Random rand) {
for (int i = 0; i < count; i++) {
double x = pos.getX() + 0.1875D + (rand.nextFloat() * 0.625D);
double y = pos.getY() + 0.375D + (level * 0.1875D);
double z = pos.getZ() + 0.1875D + (rand.nextFloat() * 0.625D);
world.addParticle(type, x, y, z, 0, 0, 0);
}
}
}