/
BlockTallWaterPlantTFC.java
199 lines (171 loc) · 7.54 KB
/
BlockTallWaterPlantTFC.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
196
197
198
199
/*
* Work under Copyright. Licensed under the EUPL.
* See the project README.md and LICENSE.txt for more information.
*/
package net.dries007.tfc.objects.blocks.plants;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import net.minecraft.block.Block;
import net.minecraft.block.IGrowable;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.EnumSkyBlock;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.dries007.tfc.api.types.Plant;
import net.dries007.tfc.objects.blocks.BlocksTFC;
import net.dries007.tfc.util.ITallPlant;
import net.dries007.tfc.world.classic.CalendarTFC;
import net.dries007.tfc.world.classic.ClimateTFC;
import net.dries007.tfc.world.classic.chunkdata.ChunkDataTFC;
import static net.dries007.tfc.world.classic.ChunkGenTFC.SALT_WATER;
@ParametersAreNonnullByDefault
public class BlockTallWaterPlantTFC extends BlockWaterPlantTFC implements IGrowable, ITallPlant
{
private static final PropertyEnum<EnumBlockPart> PART = PropertyEnum.create("part", EnumBlockPart.class);
private static final Map<Plant, BlockTallWaterPlantTFC> MAP = new HashMap<>();
public static BlockTallWaterPlantTFC get(Plant plant)
{
return BlockTallWaterPlantTFC.MAP.get(plant);
}
public BlockTallWaterPlantTFC(Plant plant)
{
super(plant);
if (MAP.put(plant, this) != null) throw new IllegalStateException("There can only be one.");
}
@Override
public boolean canGrow(World worldIn, BlockPos pos, IBlockState state, boolean isClient)
{
IBlockState water = plant.getWaterType();
int i;
//noinspection StatementWithEmptyBody
for (i = 1; worldIn.getBlockState(pos.down(i)).getBlock() == this; ++i) ;
if (water == SALT_WATER)
return i < plant.getMaxHeight() && BlocksTFC.isSaltWater(worldIn.getBlockState(pos.up())) && canBlockStay(worldIn, pos.up(), state);
else
return i < plant.getMaxHeight() && BlocksTFC.isFreshWater(worldIn.getBlockState(pos.up())) && canBlockStay(worldIn, pos.up(), state);
}
@Override
public boolean canUseBonemeal(World worldIn, Random rand, BlockPos pos, IBlockState state)
{
return false;
}
@Override
public void grow(World worldIn, Random rand, BlockPos pos, IBlockState state)
{
worldIn.setBlockState(pos.up(), this.getDefaultState());
IBlockState iblockstate = state.withProperty(AGE, 0).withProperty(growthStageProperty, plant.getStages()[CalendarTFC.getMonthOfYear().id()]).withProperty(PART, getPlantPart(worldIn, pos));
worldIn.setBlockState(pos, iblockstate);
iblockstate.neighborChanged(worldIn, pos.up(), this, pos);
}
public void shrink(World worldIn, BlockPos pos)
{
worldIn.setBlockState(pos, plant.getWaterType());
worldIn.getBlockState(pos).neighborChanged(worldIn, pos.down(), this, pos);
}
@Override
public void onBlockHarvested(World worldIn, BlockPos pos, IBlockState state, EntityPlayer player)
{
super.onBlockHarvested(worldIn, pos, state, player);
}
@Override
public boolean canSustainPlant(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing direction, net.minecraftforge.common.IPlantable plantable)
{
IBlockState plant = plantable.getPlant(world, pos.offset(direction));
if (plant.getBlock() == this)
{
return true;
}
return super.canSustainPlant(state, world, pos, direction, plantable);
}
@Override
@Nonnull
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos)
{
return super.getActualState(state, worldIn, pos).withProperty(PART, getPlantPart(worldIn, pos));
}
@Override
@Nonnull
public Block.EnumOffsetType getOffsetType()
{
return EnumOffsetType.XYZ;
}
@Override
public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand)
{
if (!worldIn.isAreaLoaded(pos, 1)) return;
if (plant.isValidGrowthTemp(ClimateTFC.getHeightAdjustedTemp(worldIn, pos)) && plant.isValidSunlight(Math.subtractExact(worldIn.getLightFor(EnumSkyBlock.SKY, pos), worldIn.getSkylightSubtracted())))
{
int j = state.getValue(AGE);
if (rand.nextDouble() < getGrowthRate(worldIn, pos) && net.minecraftforge.common.ForgeHooks.onCropsGrowPre(worldIn, pos.up(), state, true))
{
if (j == 3 && canGrow(worldIn, pos, state, worldIn.isRemote))
{
grow(worldIn, rand, pos, state);
}
else if (j < 3)
{
worldIn.setBlockState(pos, state.withProperty(AGE, j + 1).withProperty(PART, getPlantPart(worldIn, pos)));
}
net.minecraftforge.common.ForgeHooks.onCropsGrowPost(worldIn, pos, state, worldIn.getBlockState(pos));
}
}
else if (!plant.isValidGrowthTemp(ClimateTFC.getHeightAdjustedTemp(worldIn, pos)) || !plant.isValidSunlight(worldIn.getLightFor(EnumSkyBlock.SKY, pos)))
{
int j = state.getValue(AGE);
if (rand.nextDouble() < getGrowthRate(worldIn, pos) && net.minecraftforge.common.ForgeHooks.onCropsGrowPre(worldIn, pos, state, true))
{
if (j == 0 && canShrink(worldIn, pos))
{
shrink(worldIn, pos);
}
else if (j > 0)
{
worldIn.setBlockState(pos, state.withProperty(AGE, j - 1).withProperty(PART, getPlantPart(worldIn, pos)));
}
net.minecraftforge.common.ForgeHooks.onCropsGrowPost(worldIn, pos, state, worldIn.getBlockState(pos));
}
}
checkAndDropBlock(worldIn, pos, state);
}
@Override
public boolean canBlockStay(World worldIn, BlockPos pos, IBlockState state)
{
IBlockState soil = worldIn.getBlockState(pos.down());
if (worldIn.getBlockState(pos.down(plant.getMaxHeight())).getBlock() == this) return false;
if (state.getBlock() == this)
{
return soil.getBlock().canSustainPlant(soil, worldIn, pos.down(), net.minecraft.util.EnumFacing.UP, this) && plant.isValidTemp(ClimateTFC.getHeightAdjustedTemp(worldIn, pos)) && plant.isValidRain(ChunkDataTFC.getRainfall(worldIn, pos));
}
return this.canSustainBush(soil);
}
@Override
@Nonnull
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos)
{
return getTallBoundingBax(state.getValue(AGE), state, source, pos);
}
@Override
@Nonnull
protected BlockStateContainer createPlantBlockState()
{
return new BlockStateContainer(this, AGE, growthStageProperty, PART, DAYPERIOD);
}
@Override
public boolean canPlaceBlockAt(World worldIn, BlockPos pos)
{
return super.canPlaceBlockAt(worldIn, pos) && this.canBlockStay(worldIn, pos, worldIn.getBlockState(pos));
}
private boolean canShrink(World worldIn, BlockPos pos)
{
return worldIn.getBlockState(pos.down()).getBlock() == this && worldIn.getBlockState(pos.up()).getBlock() != this;
}
}