Patch work, most of block classes, and fix eclipse run configs.

This commit is contained in:
LexManos 2018-11-16 23:15:39 -08:00
parent 763b3e806e
commit 7c0d94ce9c
51 changed files with 1865 additions and 276 deletions

View file

@ -119,11 +119,17 @@ project(':forge') {
clientRun {
main = 'net.minecraftforge.fml.LaunchTesting'
environment = [
target: 'fmldevclient'
target: 'fmldevclient',
assetDirectory: downloadAssets.output,
nativesDirectory: extractNatives.output
]
properties = [
target: 'fmldevclient',
assetDirectory: downloadAssets.output
'org.lwjgl.util.Debug': 'true',
'org.lwjgl.util.DebugLoader': 'true',
'mc.version': MC_VERSION,
'mcp.version': MCP_VERSION,
'forge.version': "${project.version.substring(MC_VERSION.length() + 1)}".toString(),
'forge.spec': SPEC_VERSION
]
}
serverRun {
@ -131,6 +137,12 @@ project(':forge') {
environment = [
target: 'fmldevserver'
]
properties = [
'mc.version': MC_VERSION,
'mcp.version': MCP_VERSION,
'forge.version': "${project.version.substring(MC_VERSION.length() + 1)}".toString(),
'forge.spec': SPEC_VERSION
]
}
}
@ -207,7 +219,7 @@ project(':forge') {
]
environment += [
target:'fmldevclient',
assetDirectory: file("${gradle.getGradleUserHomeDir()}/caches/forge_gradle/assets/"),
assetDirectory: downloadAssets.output,
nativesDirectory: extractNatives.output
]
workingDir 'runclient'

View file

@ -0,0 +1,19 @@
--- a/net/minecraft/advancements/PlayerAdvancements.java
+++ b/net/minecraft/advancements/PlayerAdvancements.java
@@ -174,6 +174,8 @@
}
public boolean func_192750_a(Advancement p_192750_1_, String p_192750_2_) {
+ // Forge: don't grant advancements for fake players
+ if (this.field_192762_j instanceof net.minecraftforge.common.util.FakePlayer) return false;
boolean flag = false;
AdvancementProgress advancementprogress = this.func_192747_a(p_192750_1_);
boolean flag1 = advancementprogress.func_192105_a();
@@ -186,6 +188,7 @@
if (p_192750_1_.func_192068_c() != null && p_192750_1_.func_192068_c().func_193220_i() && this.field_192762_j.field_70170_p.func_82736_K().func_82766_b("announceAdvancements")) {
this.field_192756_d.func_184103_al().func_148539_a(new TextComponentTranslation("chat.type.advancement." + p_192750_1_.func_192068_c().func_192291_d().func_192307_a(), new Object[]{this.field_192762_j.func_145748_c_(), p_192750_1_.func_193123_j()}));
}
+ net.minecraftforge.common.ForgeHooks.onAdvancement(this.field_192762_j, p_192750_1_);
}
}

View file

@ -0,0 +1,38 @@
--- a/net/minecraft/advancements/criterion/ItemPredicate.java
+++ b/net/minecraft/advancements/criterion/ItemPredicate.java
@@ -23,6 +23,8 @@
import net.minecraft.util.ResourceLocation;
public class ItemPredicate {
+ private static final Map<ResourceLocation, java.util.function.Function<JsonObject, ItemPredicate>> custom_predicates = new java.util.HashMap<>();
+ private static final Map<ResourceLocation, java.util.function.Function<JsonObject, ItemPredicate>> unmod_predicates = java.util.Collections.unmodifiableMap(custom_predicates);
public static final ItemPredicate field_192495_a = new ItemPredicate();
@Nullable
private final Tag<Item> field_200018_b;
@@ -89,6 +91,11 @@
public static ItemPredicate func_192492_a(@Nullable JsonElement p_192492_0_) {
if (p_192492_0_ != null && !p_192492_0_.isJsonNull()) {
JsonObject jsonobject = JsonUtils.func_151210_l(p_192492_0_, "item");
+ if (jsonobject.has("type")) {
+ final ResourceLocation rl = new ResourceLocation(JsonUtils.func_151200_h(jsonobject, "type"));
+ if (custom_predicates.containsKey(rl)) return custom_predicates.get(rl).apply(jsonobject);
+ else throw new JsonSyntaxException("There is no ItemPredicate of type "+rl);
+ }
MinMaxBounds.IntBound minmaxbounds$intbound = MinMaxBounds.IntBound.func_211344_a(jsonobject.get("count"));
MinMaxBounds.IntBound minmaxbounds$intbound1 = MinMaxBounds.IntBound.func_211344_a(jsonobject.get("durability"));
if (jsonobject.has("data")) {
@@ -180,6 +187,14 @@
}
}
+ public static void register(ResourceLocation name, java.util.function.Function<JsonObject, ItemPredicate> deserializer) {
+ custom_predicates.put(name, deserializer);
+ }
+
+ public static Map<ResourceLocation, java.util.function.Function<JsonObject, ItemPredicate>> getPredicates() {
+ return unmod_predicates;
+ }
+
public static class Builder {
private final List<EnchantmentPredicate> field_200312_a = Lists.<EnchantmentPredicate>newArrayList();
@Nullable

View file

@ -1,6 +1,12 @@
--- a/net/minecraft/block/Block.java
+++ b/net/minecraft/block/Block.java
@@ -74,7 +74,7 @@
@@ -71,14 +71,19 @@
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
+import net.minecraftforge.common.EnumPlantType;
+import net.minecraftforge.common.IPlantable;
+
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -8,8 +14,63 @@
+public class Block extends net.minecraftforge.registries.ForgeRegistryEntry<Block> implements IItemProvider, net.minecraftforge.common.extensions.IForgeBlock {
protected static final Logger field_196273_d = LogManager.getLogger();
private static final ResourceLocation field_176230_a = new ResourceLocation("air");
public static final RegistryNamespacedDefaultedByKey<ResourceLocation, Block> field_149771_c = new RegistryNamespacedDefaultedByKey<ResourceLocation, Block>(field_176230_a);
@@ -502,8 +502,8 @@
- public static final RegistryNamespacedDefaultedByKey<ResourceLocation, Block> field_149771_c = new RegistryNamespacedDefaultedByKey<ResourceLocation, Block>(field_176230_a);
- public static final ObjectIntIdentityMap<IBlockState> field_176229_d = new ObjectIntIdentityMap<IBlockState>();
+ @Deprecated //Forge: Do not use, use ForgeRegistries
+ public static final RegistryNamespacedDefaultedByKey<ResourceLocation, Block> field_149771_c = net.minecraftforge.registries.GameData.getWrapperDefaulted(Block.class);
+ @Deprecated //Forge: Do not use, use GameRegistry
+ public static final ObjectIntIdentityMap<IBlockState> field_176229_d = net.minecraftforge.registries.GameData.getBlockStateIDMap();
protected final int field_149784_t;
protected final float field_149782_v;
protected final float field_149781_w;
@@ -316,7 +321,7 @@
@Deprecated
public boolean func_196253_a(IBlockState p_196253_1_, BlockItemUseContext p_196253_2_) {
- return this.field_149764_J.func_76222_j() && p_196253_2_.func_195996_i().func_77973_b() != this.func_199767_j();
+ return p_196253_1_.func_185904_a().func_76222_j() && p_196253_2_.func_195996_i().func_77973_b() != this.func_199767_j();
}
@Deprecated
@@ -328,8 +333,9 @@
return this.field_149789_z;
}
+ @Deprecated //Forge: New State sensitive version.
public boolean func_149716_u() {
- return this instanceof ITileEntityProvider;
+ return hasTileEntity(func_176223_P());
}
@Deprecated
@@ -340,11 +346,11 @@
@Deprecated
@OnlyIn(Dist.CLIENT)
public int func_185484_c(IBlockState p_185484_1_, IWorldReader p_185484_2_, BlockPos p_185484_3_) {
- int i = p_185484_2_.func_175626_b(p_185484_3_, p_185484_1_.func_185906_d());
+ int i = p_185484_2_.func_175626_b(p_185484_3_, p_185484_1_.getLightValue(p_185484_2_, p_185484_3_));
if (i == 0 && p_185484_1_.func_177230_c() instanceof BlockSlab) {
p_185484_3_ = p_185484_3_.func_177977_b();
p_185484_1_ = p_185484_2_.func_180495_p(p_185484_3_);
- return p_185484_2_.func_175626_b(p_185484_3_, p_185484_1_.func_185906_d());
+ return p_185484_2_.func_175626_b(p_185484_3_, p_185484_1_.getLightValue(p_185484_2_, p_185484_3_));
} else {
return i;
}
@@ -486,8 +492,12 @@
@Deprecated
public void func_196243_a(IBlockState p_196243_1_, World p_196243_2_, BlockPos p_196243_3_, IBlockState p_196243_4_, boolean p_196243_5_) {
+ if (hasTileEntity(p_196243_1_) && !(this instanceof BlockContainer)) {
+ p_196243_2_.func_175713_t(p_196243_3_);
+ }
}
+ @Deprecated //Forge: Use fortune/location sensitive version
public int func_196264_a(IBlockState p_196264_1_, Random p_196264_2_) {
return 1;
}
@@ -502,30 +512,27 @@
if (f == -1.0F) {
return 0.0F;
} else {
@ -20,7 +81,64 @@
}
}
@@ -625,6 +625,7 @@
@Deprecated
public void func_196255_a(IBlockState p_196255_1_, World p_196255_2_, BlockPos p_196255_3_, float p_196255_4_, int p_196255_5_) {
- if (!p_196255_2_.field_72995_K) {
- int i = this.func_196251_a(p_196255_1_, p_196255_5_, p_196255_2_, p_196255_3_, p_196255_2_.field_73012_v);
-
- for(int j = 0; j < i; ++j) {
- if (!(p_196255_4_ < 1.0F) || !(p_196255_2_.field_73012_v.nextFloat() > p_196255_4_)) {
- Item item = this.func_199769_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_5_).func_199767_j();
- if (item != Items.field_190931_a) {
- func_180635_a(p_196255_2_, p_196255_3_, new ItemStack(item));
- }
- }
- }
-
+ if (!p_196255_2_.field_72995_K && !p_196255_2_.restoringBlockSnapshots) { // do not drop items while restoring blockstates, prevents item dupe
+ NonNullList<ItemStack> drops = NonNullList.func_191196_a();
+ getDrops(p_196255_1_, drops, p_196255_2_, p_196255_3_, p_196255_5_); // use the old method until it gets removed, for backward compatibility
+ p_196255_4_ = net.minecraftforge.event.ForgeEventFactory.fireBlockHarvesting(drops, p_196255_2_, p_196255_3_, p_196255_1_, p_196255_5_, p_196255_4_, false, harvesters.get());
+ drops.forEach(stack -> func_180635_a(p_196255_2_, p_196255_3_, stack));
}
}
public static void func_180635_a(World p_180635_0_, BlockPos p_180635_1_, ItemStack p_180635_2_) {
- if (!p_180635_0_.field_72995_K && !p_180635_2_.func_190926_b() && p_180635_0_.func_82736_K().func_82766_b("doTileDrops")) {
+ if (!p_180635_0_.field_72995_K && !p_180635_2_.func_190926_b() && p_180635_0_.func_82736_K().func_82766_b("doTileDrops") && !p_180635_0_.restoringBlockSnapshots) {// do not drop items while restoring blockstates, prevents item dupe
+ if (captureDrops.get()) {
+ capturedDrops.get().add(p_180635_2_);
+ return;
+ }
float f = 0.5F;
double d0 = (double)(p_180635_0_.field_73012_v.nextFloat() * 0.5F) + 0.25D;
double d1 = (double)(p_180635_0_.field_73012_v.nextFloat() * 0.5F) + 0.25D;
@@ -547,6 +554,7 @@
}
+ @Deprecated //Forge: State sensitive version
public float func_149638_a() {
return this.field_149781_w;
}
@@ -615,16 +623,22 @@
public void func_180657_a(World p_180657_1_, EntityPlayer p_180657_2_, BlockPos p_180657_3_, IBlockState p_180657_4_, @Nullable TileEntity p_180657_5_, ItemStack p_180657_6_) {
p_180657_2_.func_71029_a(StatList.field_188065_ae.func_199076_b(this));
p_180657_2_.func_71020_j(0.005F);
- if (this.func_149700_E() && EnchantmentHelper.func_77506_a(Enchantments.field_185306_r, p_180657_6_) > 0) {
+ if (this.canSilkHarvest(p_180657_4_, p_180657_1_, p_180657_3_, p_180657_2_) && EnchantmentHelper.func_77506_a(Enchantments.field_185306_r, p_180657_6_) > 0) {
+ NonNullList<ItemStack> items = NonNullList.func_191196_a();
ItemStack itemstack = this.func_180643_i(p_180657_4_);
- func_180635_a(p_180657_1_, p_180657_3_, itemstack);
+ if (!itemstack.func_190926_b()) items.add(itemstack);
+ net.minecraftforge.event.ForgeEventFactory.fireBlockHarvesting(items, p_180657_1_, p_180657_3_, p_180657_4_, 0, 1.0f, true, p_180657_2_);
+ items.forEach(e -> func_180635_a(p_180657_1_, p_180657_3_, e));
} else {
+ harvesters.set(p_180657_2_);
int i = EnchantmentHelper.func_77506_a(Enchantments.field_185308_t, p_180657_6_);
p_180657_4_.func_196949_c(p_180657_1_, p_180657_3_, i);
+ harvesters.set(null);
}
}
@ -28,7 +146,15 @@
protected boolean func_149700_E() {
return this.func_176223_P().func_185917_h() && !this.func_149716_u();
}
@@ -755,6 +756,7 @@
@@ -681,6 +695,7 @@
p_176216_2_.field_70181_x = 0.0D;
}
+ @Deprecated // Forge: Use more sensitive version below: getPickBlock
public ItemStack func_185473_a(IBlockReader p_185473_1_, BlockPos p_185473_2_, IBlockState p_185473_3_) {
return new ItemStack(this);
}
@@ -755,6 +770,7 @@
}
}
@ -36,12 +162,22 @@
public SoundType func_185467_w() {
return this.field_149762_H;
}
@@ -1604,4 +1606,56 @@
@@ -1147,7 +1163,7 @@
func_196254_a("chiseled_quartz_block", new Block(Block.Builder.func_200949_a(Material.field_151576_e, MapColor.field_151677_p).func_200943_b(0.8F)));
func_196254_a("quartz_pillar", new BlockRotatedPillar(Block.Builder.func_200949_a(Material.field_151576_e, MapColor.field_151677_p).func_200943_b(0.8F)));
func_196254_a("quartz_stairs", new BlockStairs(block42.func_176223_P(), Block.Builder.func_200950_a(block42)));
- func_196254_a("activator_rail", new BlockRailPowered(Block.Builder.func_200945_a(Material.field_151594_q).func_200942_a().func_200943_b(0.7F).func_200947_a(SoundType.field_185852_e)));
+ func_196254_a("activator_rail", new BlockRailPowered(Block.Builder.func_200945_a(Material.field_151594_q).func_200942_a().func_200943_b(0.7F).func_200947_a(SoundType.field_185852_e), true));
func_196254_a("dropper", new BlockDropper(Block.Builder.func_200945_a(Material.field_151576_e).func_200943_b(3.5F)));
func_196254_a("white_terracotta", new Block(Block.Builder.func_200949_a(Material.field_151576_e, MapColor.field_193561_M).func_200948_a(1.25F, 4.2F)));
func_196254_a("orange_terracotta", new Block(Block.Builder.func_200949_a(Material.field_151576_e, MapColor.field_193562_N).func_200948_a(1.25F, 4.2F)));
@@ -1604,4 +1620,83 @@
return Objects.hash(this.field_212164_a, this.field_212165_b, this.field_212166_c);
}
}
+ /* ======================================== FORGE START =====================================*/
+ private ThreadLocal<IBlockState> silkCheck = new ThreadLocal<>();
+ protected Random RANDOM = new Random();
+ protected ThreadLocal<EntityPlayer> harvesters = new ThreadLocal<>();
+ private net.minecraftforge.common.ToolType harvestTool;
+ private int harvestLevel;
+ protected static ThreadLocal<Boolean> captureDrops = ThreadLocal.withInitial(() -> false);
@ -68,12 +204,6 @@
+ return this.func_149700_E() && !state.hasTileEntity();
+ }
+
+ @Override
+ public void onBlockExploded(IBlockState state, World world, BlockPos pos, Explosion explosion) {
+ world.func_175698_g(pos);
+ func_180652_a(world, pos, explosion);
+ }
+
+ @Nullable
+ @Override
+ public net.minecraftforge.common.ToolType getHarvestTool(IBlockState state) {
@ -85,6 +215,38 @@
+ return harvestLevel; //TODO: RE-Evaluate
+ }
+
+ @Override
+ public boolean canSustainPlant(IBlockState state, IBlockReader world, BlockPos pos, EnumFacing facing, IPlantable plantable) {
+ IBlockState plant = plantable.getPlant(world, pos.func_177972_a(facing));
+ EnumPlantType type = plantable.getPlantType(world, pos.func_177972_a(facing));
+
+ if (plant.func_177230_c() == Blocks.field_150434_aF)
+ return this.getBlock() == Blocks.field_150434_aF || this.getBlock() == Blocks.field_150354_m || this.getBlock() == Blocks.field_196611_F;
+
+ if (plant.func_177230_c() == Blocks.field_196608_cF)
+ return true;
+
+ if (plantable instanceof BlockBush && ((BlockBush)plantable).func_200014_a_(state, world, pos))
+ return true;
+
+ switch (type) {
+ case Desert: return this.getBlock() == Blocks.field_150354_m || this.getBlock() == Blocks.field_150405_ch || this.getBlock() instanceof BlockGlazedTerracotta;
+ case Nether: return this.getBlock() == Blocks.field_150425_aM;
+ case Crop: return this.getBlock() == Blocks.field_150458_ak;
+ case Cave: return state.func_185896_q();
+ case Plains: return this.getBlock() == Blocks.field_150349_c || this.getBlock() == Blocks.field_150346_d || this.getBlock() == Blocks.field_150458_ak;
+ case Water: return state.func_185904_a() == Material.field_151586_h; //&& state.getValue(BlockLiquidWrapper)
+ case Beach:
+ boolean isBeach = this.getBlock() == Blocks.field_150349_c || this.getBlock() == Blocks.field_150346_d || this.getBlock() == Blocks.field_150354_m;
+ boolean hasWater = (world.func_180495_p(pos.func_177974_f()).func_185904_a() == Material.field_151586_h ||
+ world.func_180495_p(pos.func_177976_e()).func_185904_a() == Material.field_151586_h ||
+ world.func_180495_p(pos.func_177978_c()).func_185904_a() == Material.field_151586_h ||
+ world.func_180495_p(pos.func_177968_d()).func_185904_a() == Material.field_151586_h);
+ return isBeach && hasWater;
+ }
+ return false;
+ }
+
+ static {
+ net.minecraftforge.common.ForgeHooks.setBlockToolSetter((block, tool, level) -> {
+ block.harvestTool = tool;

View file

@ -0,0 +1,22 @@
--- a/net/minecraft/block/BlockAbstractBanner.java
+++ b/net/minecraft/block/BlockAbstractBanner.java
@@ -50,7 +50,7 @@
}
public void func_196255_a(IBlockState p_196255_1_, World p_196255_2_, BlockPos p_196255_3_, float p_196255_4_, int p_196255_5_) {
- func_180635_a(p_196255_2_, p_196255_3_, this.func_185473_a(p_196255_2_, p_196255_3_, p_196255_1_));
+ super.func_196255_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_4_, p_196255_5_);
}
public void func_180657_a(World p_180657_1_, EntityPlayer p_180657_2_, BlockPos p_180657_3_, IBlockState p_180657_4_, @Nullable TileEntity p_180657_5_, ItemStack p_180657_6_) {
@@ -73,4 +73,10 @@
public EnumDyeColor func_196285_M_() {
return this.field_196286_a;
}
+
+ @Override
+ public void getDrops(IBlockState state, net.minecraft.util.NonNullList<ItemStack> drops, World world, BlockPos pos, int fortune) {
+ TileEntity te = world.func_175625_s(pos);
+ drops.add((te instanceof TileEntityBanner) ? ((TileEntityBanner)te).func_190615_l(state) : func_185473_a(world, pos, state));
+ }
}

View file

@ -0,0 +1,13 @@
--- a/net/minecraft/block/BlockBed.java
+++ b/net/minecraft/block/BlockBed.java
@@ -66,7 +66,9 @@
}
}
- if (p_196250_2_.field_73011_w.func_76567_e() && p_196250_2_.func_180494_b(p_196250_3_) != Biomes.field_76778_j) {
+ net.minecraft.world.dimension.Dimension.SleepResult sleepResult = p_196250_2_.field_73011_w.canSleepAt(p_196250_4_, p_196250_3_);
+ if (sleepResult != net.minecraft.world.dimension.Dimension.SleepResult.BED_EXPLODES) {
+ if (sleepResult == net.minecraft.world.dimension.Dimension.SleepResult.DENY) return true;
if (p_196250_1_.func_177229_b(field_176471_b)) {
EntityPlayer entityplayer = this.func_176470_e(p_196250_2_, p_196250_3_);
if (entityplayer != null) {

View file

@ -0,0 +1,32 @@
--- a/net/minecraft/block/BlockBush.java
+++ b/net/minecraft/block/BlockBush.java
@@ -10,7 +10,7 @@
import net.minecraft.world.IWorld;
import net.minecraft.world.IWorldReaderBase;
-public class BlockBush extends Block {
+public class BlockBush extends Block implements net.minecraftforge.common.IPlantable {
protected BlockBush(Block.Builder p_i48437_1_) {
super(p_i48437_1_);
}
@@ -26,6 +26,8 @@
public boolean func_196260_a(IBlockState p_196260_1_, IWorldReaderBase p_196260_2_, BlockPos p_196260_3_) {
BlockPos blockpos = p_196260_3_.func_177977_b();
+ if (p_196260_1_.func_177230_c() == this) //Forge: This function is called during world gen and placement, before this block is set, so if we are not 'here' then assume it's the pre-check.
+ return p_196260_2_.func_180495_p(blockpos).canSustainPlant(p_196260_2_, blockpos, EnumFacing.UP, this);
return this.func_200014_a_(p_196260_2_.func_180495_p(blockpos), p_196260_2_, blockpos);
}
@@ -44,4 +46,11 @@
public int func_200011_d(IBlockState p_200011_1_, IBlockReader p_200011_2_, BlockPos p_200011_3_) {
return 0;
}
+
+ @Override
+ public IBlockState getPlant(IBlockReader world, BlockPos pos) {
+ IBlockState state = world.func_180495_p(pos);
+ if (state.func_177230_c() != this) return func_176223_P();
+ return state;
+ }
}

View file

@ -0,0 +1,63 @@
--- a/net/minecraft/block/BlockCactus.java
+++ b/net/minecraft/block/BlockCactus.java
@@ -21,7 +21,7 @@
import net.minecraft.world.IWorldReaderBase;
import net.minecraft.world.World;
-public class BlockCactus extends Block {
+public class BlockCactus extends Block implements net.minecraftforge.common.IPlantable {
public static final IntegerProperty field_176587_a = BlockStateProperties.field_208171_X;
protected static final VoxelShape field_196400_b = Block.func_208617_a(1.0D, 0.0D, 1.0D, 15.0D, 15.0D, 15.0D);
protected static final VoxelShape field_196401_c = Block.func_208617_a(1.0D, 0.0D, 1.0D, 15.0D, 16.0D, 15.0D);
@@ -32,6 +32,7 @@
}
public void func_196267_b(IBlockState p_196267_1_, World p_196267_2_, BlockPos p_196267_3_, Random p_196267_4_) {
+ if (!p_196267_2_.func_205050_e(p_196267_3_, 1)) return; // Forge: prevent growing cactus from loading unloaded chunks with block update
if (!p_196267_1_.func_196955_c(p_196267_2_, p_196267_3_)) {
p_196267_2_.func_175655_b(p_196267_3_, true);
} else {
@@ -44,6 +45,7 @@
if (i < 3) {
int j = p_196267_1_.func_177229_b(field_176587_a);
+ if(net.minecraftforge.common.ForgeHooks.onCropsGrowPre(p_196267_2_, blockpos, p_196267_1_, true)) {
if (j == 15) {
p_196267_2_.func_175656_a(blockpos, this.func_176223_P());
IBlockState iblockstate = (IBlockState)p_196267_1_.func_206870_a(field_176587_a, Integer.valueOf(0));
@@ -52,7 +54,8 @@
} else {
p_196267_2_.func_180501_a(p_196267_3_, (IBlockState)p_196267_1_.func_206870_a(field_176587_a, Integer.valueOf(j + 1)), 4);
}
-
+ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(p_196267_2_, p_196267_3_, p_196267_1_);
+ }
}
}
}
@@ -91,8 +94,8 @@
}
}
- Block block = p_196260_2_.func_180495_p(p_196260_3_.func_177977_b()).func_177230_c();
- return (block == Blocks.field_150434_aF || block == Blocks.field_150354_m || block == Blocks.field_196611_F) && !p_196260_2_.func_180495_p(p_196260_3_.func_177984_a()).func_185904_a().func_76224_d();
+ IBlockState soil = p_196260_2_.func_180495_p(p_196260_3_.func_177977_b());
+ return soil.canSustainPlant(p_196260_2_, p_196260_3_.func_177977_b(), EnumFacing.UP, this) && !p_196260_2_.func_180495_p(p_196260_3_.func_177984_a()).func_185904_a().func_76224_d();
}
public void func_196262_a(IBlockState p_196262_1_, World p_196262_2_, BlockPos p_196262_3_, Entity p_196262_4_) {
@@ -114,4 +117,14 @@
public boolean func_196266_a(IBlockState p_196266_1_, IBlockReader p_196266_2_, BlockPos p_196266_3_, PathType p_196266_4_) {
return false;
}
+
+ @Override
+ public net.minecraftforge.common.EnumPlantType getPlantType(IBlockReader world, BlockPos pos) {
+ return net.minecraftforge.common.EnumPlantType.Desert;
+ }
+
+ @Override
+ public IBlockState getPlant(IBlockReader world, BlockPos pos) {
+ return func_176223_P();
+ }
}

View file

@ -0,0 +1,11 @@
--- a/net/minecraft/block/BlockChest.java
+++ b/net/minecraft/block/BlockChest.java
@@ -258,7 +258,7 @@
}
private boolean func_176456_n(IBlockReader p_176456_1_, BlockPos p_176456_2_) {
- return p_176456_1_.func_180495_p(p_176456_2_.func_177984_a()).func_185915_l();
+ return p_176456_1_.func_180495_p(p_176456_2_.func_177984_a()).doesSideBlockChestOpening(p_176456_1_, p_176456_2_.func_177984_a(), EnumFacing.DOWN);
}
private boolean func_176453_o(World p_176453_1_, BlockPos p_176453_2_) {

View file

@ -0,0 +1,20 @@
--- a/net/minecraft/block/BlockChorusFlower.java
+++ b/net/minecraft/block/BlockChorusFlower.java
@@ -42,7 +42,7 @@
BlockPos blockpos = p_196267_3_.func_177984_a();
if (p_196267_2_.func_175623_d(blockpos) && blockpos.func_177956_o() < 256) {
int i = p_196267_1_.func_177229_b(field_185607_a);
- if (i < 5) {
+ if (i < 5 && net.minecraftforge.common.ForgeHooks.onCropsGrowPre(p_196267_2_, blockpos, p_196267_1_, true)) {
boolean flag = false;
boolean flag1 = false;
IBlockState iblockstate = p_196267_2_.func_180495_p(p_196267_3_.func_177977_b());
@@ -99,7 +99,7 @@
} else {
this.func_185605_c(p_196267_2_, p_196267_3_);
}
-
+ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(p_196267_2_, p_196267_3_, p_196267_1_);
}
}
}

View file

@ -0,0 +1,39 @@
--- a/net/minecraft/block/BlockCocoa.java
+++ b/net/minecraft/block/BlockCocoa.java
@@ -34,10 +34,11 @@
}
public void func_196267_b(IBlockState p_196267_1_, World p_196267_2_, BlockPos p_196267_3_, Random p_196267_4_) {
- if (p_196267_2_.field_73012_v.nextInt(5) == 0) {
+ if (true) {
int i = p_196267_1_.func_177229_b(field_176501_a);
- if (i < 2) {
+ if (i < 2 && net.minecraftforge.common.ForgeHooks.onCropsGrowPre(p_196267_2_, p_196267_3_, p_196267_1_, p_196267_2_.field_73012_v.nextInt(5) == 0)) {
p_196267_2_.func_180501_a(p_196267_3_, (IBlockState)p_196267_1_.func_206870_a(field_176501_a, Integer.valueOf(i + 1)), 2);
+ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(p_196267_2_, p_196267_3_, p_196267_1_);
}
}
@@ -90,14 +91,20 @@
}
public void func_196255_a(IBlockState p_196255_1_, World p_196255_2_, BlockPos p_196255_3_, float p_196255_4_, int p_196255_5_) {
- int i = p_196255_1_.func_177229_b(field_176501_a);
+ super.func_196255_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_4_, p_196255_5_);
+ }
+
+ @Override
+ public void getDrops(IBlockState state, net.minecraft.util.NonNullList<ItemStack> drops, World world, BlockPos pos, int fortune) {
+ super.getDrops(state, drops, world, pos, fortune);
+ int i = state.func_177229_b(field_176501_a);
int j = 1;
if (i >= 2) {
j = 3;
}
for(int k = 0; k < j; ++k) {
- func_180635_a(p_196255_2_, p_196255_3_, new ItemStack(Items.field_196130_bo));
+ drops.add(new ItemStack(Items.field_196130_bo));
}
}

View file

@ -0,0 +1,64 @@
--- a/net/minecraft/block/BlockCrops.java
+++ b/net/minecraft/block/BlockCrops.java
@@ -9,6 +9,7 @@
import net.minecraft.state.StateContainer;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.IItemProvider;
+import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.shapes.VoxelShape;
@@ -55,12 +56,14 @@
public void func_196267_b(IBlockState p_196267_1_, World p_196267_2_, BlockPos p_196267_3_, Random p_196267_4_) {
super.func_196267_b(p_196267_1_, p_196267_2_, p_196267_3_, p_196267_4_);
+ if (!p_196267_2_.func_205050_e(p_196267_3_, 1)) return; // Forge: prevent loading unloaded chunks when checking neighbor's light
if (p_196267_2_.func_201669_a(p_196267_3_.func_177984_a(), 0) >= 9) {
int i = this.func_185527_x(p_196267_1_);
if (i < this.func_185526_g()) {
float f = func_180672_a(this, p_196267_2_, p_196267_3_);
- if (p_196267_4_.nextInt((int)(25.0F / f) + 1) == 0) {
+ if (net.minecraftforge.common.ForgeHooks.onCropsGrowPre(p_196267_2_, p_196267_3_, p_196267_1_, p_196267_4_.nextInt((int)(25.0F / f) + 1) == 0)) {
p_196267_2_.func_180501_a(p_196267_3_, this.func_185528_e(i + 1), 2);
+ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(p_196267_2_, p_196267_3_, p_196267_1_);
}
}
}
@@ -89,9 +92,9 @@
for(int j = -1; j <= 1; ++j) {
float f1 = 0.0F;
IBlockState iblockstate = p_180672_1_.func_180495_p(blockpos.func_177982_a(i, 0, j));
- if (iblockstate.func_177230_c() == Blocks.field_150458_ak) {
+ if (iblockstate.canSustainPlant(p_180672_1_, blockpos.func_177982_a(i, 0, j), net.minecraft.util.EnumFacing.UP, (net.minecraftforge.common.IPlantable)p_180672_0_)) {
f1 = 1.0F;
- if (iblockstate.func_177229_b(BlockFarmland.field_176531_a) > 0) {
+ if (iblockstate.isFertile(p_180672_1_, blockpos.func_177982_a(i, 0, j))) {
f1 = 3.0F;
}
}
@@ -135,15 +138,19 @@
}
public void func_196255_a(IBlockState p_196255_1_, World p_196255_2_, BlockPos p_196255_3_, float p_196255_4_, int p_196255_5_) {
- super.func_196255_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_4_, 0);
- if (!p_196255_2_.field_72995_K) {
- int i = this.func_185527_x(p_196255_1_);
+ super.func_196255_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_4_, p_196255_5_);
+ }
+
+ @Override
+ public void getDrops(IBlockState state, NonNullList<ItemStack> drops, World world, BlockPos pos, int fortune) {
+ {
+ int i = this.func_185527_x(state);
if (i >= this.func_185526_g()) {
- int j = 3 + p_196255_5_;
+ int j = 3 + fortune;
for(int k = 0; k < j; ++k) {
- if (p_196255_2_.field_73012_v.nextInt(2 * this.func_185526_g()) <= i) {
- func_180635_a(p_196255_2_, p_196255_3_, new ItemStack(this.func_199772_f()));
+ if (world.field_73012_v.nextInt(2 * this.func_185526_g()) <= i) {
+ drops.add(new ItemStack(this.func_199772_f()));
}
}
}

View file

@ -0,0 +1,26 @@
--- a/net/minecraft/block/BlockDeadBush.java
+++ b/net/minecraft/block/BlockDeadBush.java
@@ -14,7 +14,7 @@
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
-public class BlockDeadBush extends BlockBush {
+public class BlockDeadBush extends BlockBush implements net.minecraftforge.common.IShearable {
protected static final VoxelShape field_196397_a = Block.func_208617_a(2.0D, 0.0D, 2.0D, 14.0D, 13.0D, 14.0D);
protected BlockDeadBush(Block.Builder p_i48418_1_) {
@@ -46,4 +46,14 @@
super.func_180657_a(p_180657_1_, p_180657_2_, p_180657_3_, flag ? Blocks.field_150350_a.func_176223_P() : p_180657_4_, p_180657_5_, p_180657_6_);
}
+
+ @Override
+ public boolean isShearable(ItemStack item, net.minecraft.world.IWorldReader world, BlockPos pos) {
+ return false;
+ }
+
+ @Override
+ public java.util.List<ItemStack> onSheared(ItemStack item, net.minecraft.world.IWorldReader world, BlockPos pos, int fortune) {
+ return java.util.Arrays.asList(new ItemStack(Blocks.field_196555_aI));
+ }
}

View file

@ -0,0 +1,10 @@
--- a/net/minecraft/block/BlockDirtSnowySpreadable.java
+++ b/net/minecraft/block/BlockDirtSnowySpreadable.java
@@ -25,6 +25,7 @@
public void func_196267_b(IBlockState p_196267_1_, World p_196267_2_, BlockPos p_196267_3_, Random p_196267_4_) {
if (!p_196267_2_.field_72995_K) {
+ if (!p_196267_2_.func_205050_e(p_196267_3_, 3)) return; // Forge: prevent loading unloaded chunks when checking neighbor's light and spreading
if (!func_196383_a(p_196267_2_, p_196267_3_)) {
p_196267_2_.func_175656_a(p_196267_3_, Blocks.field_150346_d.func_176223_P());
} else {

View file

@ -0,0 +1,19 @@
--- a/net/minecraft/block/BlockDoublePlant.java
+++ b/net/minecraft/block/BlockDoublePlant.java
@@ -43,7 +43,7 @@
@Nullable
public IBlockState func_196258_a(BlockItemUseContext p_196258_1_) {
BlockPos blockpos = p_196258_1_.func_195995_a();
- return blockpos.func_177956_o() < 255 && p_196258_1_.func_195991_k().func_180495_p(blockpos.func_177984_a()).func_196953_a(p_196258_1_) ? super.func_196258_a(p_196258_1_) : null;
+ return blockpos.func_177956_o() < p_196258_1_.func_195991_k().func_72800_K() - 1 && p_196258_1_.func_195991_k().func_180495_p(blockpos.func_177984_a()).func_196953_a(p_196258_1_) ? super.func_196258_a(p_196258_1_) : null;
}
public void func_180633_a(World p_180633_1_, BlockPos p_180633_2_, IBlockState p_180633_3_, EntityLivingBase p_180633_4_, ItemStack p_180633_5_) {
@@ -51,6 +51,7 @@
}
public boolean func_196260_a(IBlockState p_196260_1_, IWorldReaderBase p_196260_2_, BlockPos p_196260_3_) {
+ if (p_196260_1_.func_177230_c() != this) return super.func_196260_a(p_196260_1_, p_196260_2_, p_196260_3_); //Forge: This function is called during world gen and placement, before this block is set, so if we are not 'here' then assume it's the pre-check.
if (p_196260_1_.func_177229_b(field_176492_b) != DoubleBlockHalf.UPPER) {
return super.func_196260_a(p_196260_1_, p_196260_2_, p_196260_3_);
} else {

View file

@ -0,0 +1,11 @@
--- a/net/minecraft/block/BlockDropper.java
+++ b/net/minecraft/block/BlockDropper.java
@@ -37,7 +37,7 @@
p_176439_1_.func_175718_b(1001, p_176439_2_, 0);
} else {
ItemStack itemstack = tileentitydispenser.func_70301_a(i);
- if (!itemstack.func_190926_b()) {
+ if (!itemstack.func_190926_b() && net.minecraftforge.items.VanillaInventoryCodeHooks.dropperInsertHook(p_176439_1_, p_176439_2_, tileentitydispenser, i, itemstack)) {
EnumFacing enumfacing = (EnumFacing)p_176439_1_.func_180495_p(p_176439_2_).func_177229_b(field_176441_a);
IInventory iinventory = TileEntityHopper.func_195484_a(p_176439_1_, p_176439_2_.func_177972_a(enumfacing));
ItemStack itemstack1;

View file

@ -0,0 +1,11 @@
--- a/net/minecraft/block/BlockEnchantmentTable.java
+++ b/net/minecraft/block/BlockEnchantmentTable.java
@@ -49,7 +49,7 @@
if (p_180655_4_.nextInt(16) == 0) {
for(int k = 0; k <= 1; ++k) {
BlockPos blockpos = p_180655_3_.func_177982_a(i, k, j);
- if (p_180655_2_.func_180495_p(blockpos).func_177230_c() == Blocks.field_150342_X) {
+ if (p_180655_2_.func_180495_p(blockpos).getEnchantPowerBonus(p_180655_2_, p_180655_3_) > 0) {
if (!p_180655_2_.func_175623_d(p_180655_3_.func_177982_a(i / 2, 0, j / 2))) {
break;
}

View file

@ -0,0 +1,11 @@
--- a/net/minecraft/block/BlockEnderChest.java
+++ b/net/minecraft/block/BlockEnderChest.java
@@ -81,7 +81,7 @@
InventoryEnderChest inventoryenderchest = p_196250_4_.func_71005_bN();
TileEntity tileentity = p_196250_2_.func_175625_s(p_196250_3_);
if (inventoryenderchest != null && tileentity instanceof TileEntityEnderChest) {
- if (p_196250_2_.func_180495_p(p_196250_3_.func_177984_a()).func_185915_l()) {
+ if (p_196250_2_.func_180495_p(p_196250_3_.func_177984_a()).doesSideBlockChestOpening(p_196250_2_, p_196250_3_.func_177984_a(), EnumFacing.DOWN)) {
return true;
} else if (p_196250_2_.field_72995_K) {
return true;

View file

@ -0,0 +1,21 @@
--- a/net/minecraft/block/BlockFalling.java
+++ b/net/minecraft/block/BlockFalling.java
@@ -48,7 +48,9 @@
p_176503_1_.func_72838_d(entityfallingblock);
}
} else {
+ IBlockState state = func_176223_P();
if (p_176503_1_.func_180495_p(p_176503_2_).func_177230_c() == this) {
+ state = p_176503_1_.func_180495_p(p_176503_2_);
p_176503_1_.func_175698_g(p_176503_2_);
}
@@ -58,7 +60,7 @@
}
if (blockpos.func_177956_o() > 0) {
- p_176503_1_.func_175656_a(blockpos.func_177984_a(), this.func_176223_P());
+ p_176503_1_.func_175656_a(blockpos.func_177984_a(), state); //Forge: Fix loss of state information during world gen.
}
}

View file

@ -0,0 +1,24 @@
--- a/net/minecraft/block/BlockFarmland.java
+++ b/net/minecraft/block/BlockFarmland.java
@@ -79,7 +79,7 @@
}
public void func_180658_a(World p_180658_1_, BlockPos p_180658_2_, Entity p_180658_3_, float p_180658_4_) {
- if (!p_180658_1_.field_72995_K && p_180658_1_.field_73012_v.nextFloat() < p_180658_4_ - 0.5F && p_180658_3_ instanceof EntityLivingBase && (p_180658_3_ instanceof EntityPlayer || p_180658_1_.func_82736_K().func_82766_b("mobGriefing")) && p_180658_3_.field_70130_N * p_180658_3_.field_70130_N * p_180658_3_.field_70131_O > 0.512F) {
+ if (!p_180658_1_.field_72995_K && net.minecraftforge.common.ForgeHooks.onFarmlandTrample(p_180658_1_, p_180658_2_, Blocks.field_150346_d.func_176223_P(), p_180658_4_, p_180658_3_)) { // Forge: Move logic to Entity#canTrample
func_199610_d(p_180658_1_.func_180495_p(p_180658_2_), p_180658_1_, p_180658_2_);
}
@@ -90,9 +90,9 @@
p_199610_1_.func_175656_a(p_199610_2_, func_199601_a(p_199610_0_, Blocks.field_150346_d.func_176223_P(), p_199610_1_, p_199610_2_));
}
- private static boolean func_176529_d(IBlockReader p_176529_0_, BlockPos p_176529_1_) {
- Block block = p_176529_0_.func_180495_p(p_176529_1_.func_177984_a()).func_177230_c();
- return block instanceof BlockCrops || block instanceof BlockStem || block instanceof BlockAttachedStem;
+ private boolean func_176529_d(IBlockReader p_176529_0_, BlockPos p_176529_1_) {
+ IBlockState state = p_176529_0_.func_180495_p(p_176529_1_.func_177984_a());
+ return state.func_177230_c() instanceof net.minecraftforge.common.IPlantable && canSustainPlant(state, p_176529_0_, p_176529_1_, EnumFacing.UP, (net.minecraftforge.common.IPlantable)state.func_177230_c());
}
private static boolean func_176530_e(IWorldReaderBase p_176530_0_, BlockPos p_176530_1_) {

View file

@ -0,0 +1,41 @@
--- a/net/minecraft/block/BlockFence.java
+++ b/net/minecraft/block/BlockFence.java
@@ -64,15 +64,12 @@
IBlockReader iblockreader = p_196258_1_.func_195991_k();
BlockPos blockpos = p_196258_1_.func_195995_a();
IFluidState ifluidstate = p_196258_1_.func_195991_k().func_204610_c(p_196258_1_.func_195995_a());
- BlockPos blockpos1 = blockpos.func_177978_c();
- BlockPos blockpos2 = blockpos.func_177974_f();
- BlockPos blockpos3 = blockpos.func_177968_d();
- BlockPos blockpos4 = blockpos.func_177976_e();
- IBlockState iblockstate = iblockreader.func_180495_p(blockpos1);
- IBlockState iblockstate1 = iblockreader.func_180495_p(blockpos2);
- IBlockState iblockstate2 = iblockreader.func_180495_p(blockpos3);
- IBlockState iblockstate3 = iblockreader.func_180495_p(blockpos4);
- return (IBlockState)((IBlockState)((IBlockState)((IBlockState)((IBlockState)super.func_196258_a(p_196258_1_).func_206870_a(field_196409_a, Boolean.valueOf(this.func_196416_a(iblockstate, iblockstate.func_193401_d(iblockreader, blockpos1, EnumFacing.SOUTH))))).func_206870_a(field_196411_b, Boolean.valueOf(this.func_196416_a(iblockstate1, iblockstate1.func_193401_d(iblockreader, blockpos2, EnumFacing.WEST))))).func_206870_a(field_196413_c, Boolean.valueOf(this.func_196416_a(iblockstate2, iblockstate2.func_193401_d(iblockreader, blockpos3, EnumFacing.NORTH))))).func_206870_a(field_196414_y, Boolean.valueOf(this.func_196416_a(iblockstate3, iblockstate3.func_193401_d(iblockreader, blockpos4, EnumFacing.EAST))))).func_206870_a(field_204514_u, Boolean.valueOf(ifluidstate.func_206886_c() == Fluids.field_204546_a));
+ return super.func_196258_a(p_196258_1_)
+ .func_206870_a(field_196409_a, canFenceConnectTo(iblockreader, blockpos, EnumFacing.NORTH))
+ .func_206870_a(field_196411_b, canFenceConnectTo(iblockreader, blockpos, EnumFacing.EAST))
+ .func_206870_a(field_196413_c, canFenceConnectTo(iblockreader, blockpos, EnumFacing.SOUTH))
+ .func_206870_a(field_196414_y, canFenceConnectTo(iblockreader, blockpos, EnumFacing.WEST))
+ .func_206870_a(field_204514_u, Boolean.valueOf(ifluidstate.func_206886_c() == Fluids.field_204546_a));
}
public IBlockState func_196271_a(IBlockState p_196271_1_, EnumFacing p_196271_2_, IBlockState p_196271_3_, IWorld p_196271_4_, BlockPos p_196271_5_, BlockPos p_196271_6_) {
@@ -90,4 +87,16 @@
public BlockFaceShape func_193383_a(IBlockReader p_193383_1_, IBlockState p_193383_2_, BlockPos p_193383_3_, EnumFacing p_193383_4_) {
return p_193383_4_ != EnumFacing.UP && p_193383_4_ != EnumFacing.DOWN ? BlockFaceShape.MIDDLE_POLE : BlockFaceShape.CENTER;
}
+
+ @Override
+ public boolean canBeConnectedTo(IBlockState state, IBlockReader world, BlockPos pos, EnumFacing facing) {
+ IBlockState other = world.func_180495_p(pos.func_177972_a(facing));
+ return func_196416_a(other, other.func_193401_d(world, pos.func_177972_a(facing), facing.func_176734_d()));
+ }
+
+ private boolean canFenceConnectTo(IBlockReader world, BlockPos pos, EnumFacing facing) {
+ BlockPos offset = pos.func_177972_a(facing);
+ IBlockState other = world.func_180495_p(offset);
+ return other.canBeConnectedTo(world, offset, facing.func_176734_d()) || func_176223_P().canBeConnectedTo(world, pos, facing.func_176734_d());
+ }
}

View file

@ -0,0 +1,26 @@
--- a/net/minecraft/block/BlockFenceGate.java
+++ b/net/minecraft/block/BlockFenceGate.java
@@ -100,7 +100,7 @@
}
private boolean func_196380_i(IBlockState p_196380_1_) {
- return p_196380_1_.func_177230_c() == Blocks.field_150463_bK || p_196380_1_.func_177230_c() == Blocks.field_196723_eg;
+ return p_196380_1_.func_177230_c() == Blocks.field_150463_bK || p_196380_1_.func_177230_c() == Blocks.field_196723_eg || p_196380_1_.func_177230_c() instanceof BlockWall;
}
public boolean func_196250_a(IBlockState p_196250_1_, World p_196250_2_, BlockPos p_196250_3_, EntityPlayer p_196250_4_, EnumHand p_196250_5_, EnumFacing p_196250_6_, float p_196250_7_, float p_196250_8_, float p_196250_9_) {
@@ -145,4 +145,14 @@
return BlockFaceShape.UNDEFINED;
}
}
+
+ @Override
+ public boolean canBeConnectedTo(IBlockState state, IBlockReader world, BlockPos pos, EnumFacing facing) {
+ if (state.func_193401_d(world, pos, facing) == BlockFaceShape.MIDDLE_POLE) {
+ Block other = world.func_180495_p(pos.func_177972_a(facing)).func_177230_c();
+ return other instanceof BlockFence || other instanceof BlockWall;
+ }
+ return false;
+ }
+
}

View file

@ -0,0 +1,208 @@
--- a/net/minecraft/block/BlockFire.java
+++ b/net/minecraft/block/BlockFire.java
@@ -63,13 +63,13 @@
public IBlockState func_196448_a(IBlockReader p_196448_1_, BlockPos p_196448_2_) {
IBlockState iblockstate = p_196448_1_.func_180495_p(p_196448_2_.func_177977_b());
- if (!iblockstate.func_185896_q() && !this.func_196446_i(iblockstate)) {
+ if (!iblockstate.func_185896_q() && !this.canCatchFire(p_196448_1_, p_196448_2_, EnumFacing.UP)) {
IBlockState iblockstate1 = this.func_176223_P();
for(EnumFacing enumfacing : EnumFacing.values()) {
BooleanProperty booleanproperty = field_196449_B.get(enumfacing);
if (booleanproperty != null) {
- iblockstate1 = (IBlockState)iblockstate1.func_206870_a(booleanproperty, Boolean.valueOf(this.func_196446_i(p_196448_1_.func_180495_p(p_196448_2_.func_177972_a(enumfacing)))));
+ iblockstate1 = iblockstate1.func_206870_a(booleanproperty, this.canCatchFire(p_196448_1_, p_196448_2_.func_177972_a(enumfacing), enumfacing.func_176734_d()));
}
}
@@ -97,12 +97,13 @@
public void func_196267_b(IBlockState p_196267_1_, World p_196267_2_, BlockPos p_196267_3_, Random p_196267_4_) {
if (p_196267_2_.func_82736_K().func_82766_b("doFireTick")) {
+ if (!p_196267_2_.func_205050_e(p_196267_3_, 2)) return; // Forge: prevent loading unloaded chunks when spreading fire
if (!p_196267_1_.func_196955_c(p_196267_2_, p_196267_3_)) {
p_196267_2_.func_175698_g(p_196267_3_);
}
- Block block = p_196267_2_.func_180495_p(p_196267_3_.func_177977_b()).func_177230_c();
- boolean flag = p_196267_2_.field_73011_w instanceof EndDimension && block == Blocks.field_150357_h || block == Blocks.field_150424_aL || block == Blocks.field_196814_hQ;
+ IBlockState other = p_196267_2_.func_180495_p(p_196267_3_.func_177977_b());
+ boolean flag = other.isFireSource(p_196267_2_, p_196267_3_.func_177977_b(), EnumFacing.UP);
int i = p_196267_1_.func_177229_b(field_176543_a);
if (!flag && p_196267_2_.func_72896_J() && this.func_176537_d(p_196267_2_, p_196267_3_) && p_196267_4_.nextFloat() < 0.2F + (float)i * 0.03F) {
p_196267_2_.func_175698_g(p_196267_3_);
@@ -116,14 +117,14 @@
if (!flag) {
p_196267_2_.func_205220_G_().func_205360_a(p_196267_3_, this, this.func_149738_a(p_196267_2_) + p_196267_4_.nextInt(10));
if (!this.func_196447_a(p_196267_2_, p_196267_3_)) {
- if (!p_196267_2_.func_180495_p(p_196267_3_.func_177977_b()).func_185896_q() || i > 3) {
+ if (p_196267_2_.func_180495_p(p_196267_3_.func_177977_b()).func_193401_d(p_196267_2_, p_196267_3_.func_177977_b(), EnumFacing.UP) != BlockFaceShape.SOLID || i > 3) {
p_196267_2_.func_175698_g(p_196267_3_);
}
return;
}
- if (i == 15 && p_196267_4_.nextInt(4) == 0 && !this.func_196446_i(p_196267_2_.func_180495_p(p_196267_3_.func_177977_b()))) {
+ if (i == 15 && p_196267_4_.nextInt(4) == 0 && !this.canCatchFire(p_196267_2_, p_196267_3_.func_177977_b(), EnumFacing.UP)) {
p_196267_2_.func_175698_g(p_196267_3_);
return;
}
@@ -131,12 +132,12 @@
boolean flag1 = p_196267_2_.func_180502_D(p_196267_3_);
int k = flag1 ? -50 : 0;
- this.func_176536_a(p_196267_2_, p_196267_3_.func_177974_f(), 300 + k, p_196267_4_, i);
- this.func_176536_a(p_196267_2_, p_196267_3_.func_177976_e(), 300 + k, p_196267_4_, i);
- this.func_176536_a(p_196267_2_, p_196267_3_.func_177977_b(), 250 + k, p_196267_4_, i);
- this.func_176536_a(p_196267_2_, p_196267_3_.func_177984_a(), 250 + k, p_196267_4_, i);
- this.func_176536_a(p_196267_2_, p_196267_3_.func_177978_c(), 300 + k, p_196267_4_, i);
- this.func_176536_a(p_196267_2_, p_196267_3_.func_177968_d(), 300 + k, p_196267_4_, i);
+ this.tryCatchFire(p_196267_2_, p_196267_3_.func_177974_f(), 300 + k, p_196267_4_, i, EnumFacing.WEST);
+ this.tryCatchFire(p_196267_2_, p_196267_3_.func_177976_e(), 300 + k, p_196267_4_, i, EnumFacing.EAST);
+ this.tryCatchFire(p_196267_2_, p_196267_3_.func_177977_b(), 250 + k, p_196267_4_, i, EnumFacing.UP);
+ this.tryCatchFire(p_196267_2_, p_196267_3_.func_177984_a(), 250 + k, p_196267_4_, i, EnumFacing.DOWN);
+ this.tryCatchFire(p_196267_2_, p_196267_3_.func_177978_c(), 300 + k, p_196267_4_, i, EnumFacing.SOUTH);
+ this.tryCatchFire(p_196267_2_, p_196267_3_.func_177968_d(), 300 + k, p_196267_4_, i, EnumFacing.NORTH);
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
for(int l = -1; l <= 1; ++l) {
@@ -174,28 +175,31 @@
return p_176537_1_.func_175727_C(p_176537_2_) || p_176537_1_.func_175727_C(p_176537_2_.func_177976_e()) || p_176537_1_.func_175727_C(p_176537_2_.func_177974_f()) || p_176537_1_.func_175727_C(p_176537_2_.func_177978_c()) || p_176537_1_.func_175727_C(p_176537_2_.func_177968_d());
}
+ @Deprecated //Forge: Use IForgeBlockState.getFlammability
public int func_176532_c(Block p_176532_1_) {
return this.field_149848_b.getInt(p_176532_1_);
}
+ @Deprecated //Forge: Use IForgeBlockState.getFireSpreadSpeed
public int func_176534_d(Block p_176534_1_) {
return this.field_149849_a.getInt(p_176534_1_);
}
- private void func_176536_a(World p_176536_1_, BlockPos p_176536_2_, int p_176536_3_, Random p_176536_4_, int p_176536_5_) {
- int i = this.func_176532_c(p_176536_1_.func_180495_p(p_176536_2_).func_177230_c());
- if (p_176536_4_.nextInt(p_176536_3_) < i) {
- IBlockState iblockstate = p_176536_1_.func_180495_p(p_176536_2_);
- if (p_176536_4_.nextInt(p_176536_5_ + 10) < 5 && !p_176536_1_.func_175727_C(p_176536_2_)) {
- int j = Math.min(p_176536_5_ + p_176536_4_.nextInt(5) / 4, 15);
- p_176536_1_.func_180501_a(p_176536_2_, (IBlockState)this.func_196448_a(p_176536_1_, p_176536_2_).func_206870_a(field_176543_a, Integer.valueOf(j)), 3);
+ private void tryCatchFire(World worldIn, BlockPos pos, int chance, Random random, int age, EnumFacing face) {
+ IBlockState other = worldIn.func_180495_p(pos);
+ int i = other.getFlammability(worldIn, pos, face);
+ if (random.nextInt(chance) < i) {
+ IBlockState iblockstate = worldIn.func_180495_p(pos);
+ if (random.nextInt(age + 10) < 5 && !worldIn.func_175727_C(pos)) {
+ int j = Math.min(age + random.nextInt(5) / 4, 15);
+ worldIn.func_180501_a(pos, (IBlockState)this.func_196448_a(worldIn, pos).func_206870_a(field_176543_a, Integer.valueOf(j)), 3);
} else {
- p_176536_1_.func_175698_g(p_176536_2_);
+ worldIn.func_175698_g(pos);
}
Block block = iblockstate.func_177230_c();
if (block instanceof BlockTNT) {
- ((BlockTNT)block).func_196534_a(p_176536_1_, p_176536_2_);
+ ((BlockTNT)block).func_196534_a(worldIn, pos);
}
}
@@ -203,7 +207,7 @@
private boolean func_196447_a(IBlockReader p_196447_1_, BlockPos p_196447_2_) {
for(EnumFacing enumfacing : EnumFacing.values()) {
- if (this.func_196446_i(p_196447_1_.func_180495_p(p_196447_2_.func_177972_a(enumfacing)))) {
+ if (this.canCatchFire(p_196447_1_, p_196447_2_.func_177972_a(enumfacing), enumfacing.func_176734_d())) {
return true;
}
}
@@ -218,7 +222,7 @@
int i = 0;
for(EnumFacing enumfacing : EnumFacing.values()) {
- i = Math.max(this.func_176534_d(p_176538_1_.func_180495_p(p_176538_2_.func_177972_a(enumfacing)).func_177230_c()), i);
+ i = Math.max(p_176538_1_.func_180495_p(p_176538_2_.func_177972_a(enumfacing)).getFlammability(p_176538_1_, p_176538_2_.func_177972_a(enumfacing), enumfacing.func_176734_d()), i);
}
return i;
@@ -229,6 +233,7 @@
return false;
}
+ @Deprecated //Forge: Use canCatchFire with more context
public boolean func_196446_i(IBlockState p_196446_1_) {
return this.func_176534_d(p_196446_1_.func_177230_c()) > 0;
}
@@ -251,8 +256,8 @@
p_180655_2_.func_184134_a((double)((float)p_180655_3_.func_177958_n() + 0.5F), (double)((float)p_180655_3_.func_177956_o() + 0.5F), (double)((float)p_180655_3_.func_177952_p() + 0.5F), SoundEvents.field_187643_bs, SoundCategory.BLOCKS, 1.0F + p_180655_4_.nextFloat(), p_180655_4_.nextFloat() * 0.7F + 0.3F, false);
}
- if (!p_180655_2_.func_180495_p(p_180655_3_.func_177977_b()).func_185896_q() && !this.func_196446_i(p_180655_2_.func_180495_p(p_180655_3_.func_177977_b()))) {
- if (this.func_196446_i(p_180655_2_.func_180495_p(p_180655_3_.func_177976_e()))) {
+ if (p_180655_2_.func_180495_p(p_180655_3_.func_177977_b()).func_193401_d(p_180655_2_, p_180655_3_.func_177977_b(), EnumFacing.UP) != BlockFaceShape.SOLID && !this.canCatchFire(p_180655_2_, p_180655_3_.func_177977_b(), EnumFacing.UP)) {
+ if (this.canCatchFire(p_180655_2_, p_180655_3_.func_177976_e(), EnumFacing.EAST)) {
for(int j = 0; j < 2; ++j) {
double d3 = (double)p_180655_3_.func_177958_n() + p_180655_4_.nextDouble() * (double)0.1F;
double d8 = (double)p_180655_3_.func_177956_o() + p_180655_4_.nextDouble();
@@ -261,7 +266,7 @@
}
}
- if (this.func_196446_i(p_180655_2_.func_180495_p(p_180655_3_.func_177974_f()))) {
+ if (this.canCatchFire(p_180655_2_, p_180655_3_.func_177974_f(), EnumFacing.WEST)) {
for(int k = 0; k < 2; ++k) {
double d4 = (double)(p_180655_3_.func_177958_n() + 1) - p_180655_4_.nextDouble() * (double)0.1F;
double d9 = (double)p_180655_3_.func_177956_o() + p_180655_4_.nextDouble();
@@ -270,7 +275,7 @@
}
}
- if (this.func_196446_i(p_180655_2_.func_180495_p(p_180655_3_.func_177978_c()))) {
+ if (this.canCatchFire(p_180655_2_, p_180655_3_.func_177978_c(), EnumFacing.SOUTH)) {
for(int l = 0; l < 2; ++l) {
double d5 = (double)p_180655_3_.func_177958_n() + p_180655_4_.nextDouble();
double d10 = (double)p_180655_3_.func_177956_o() + p_180655_4_.nextDouble();
@@ -279,7 +284,7 @@
}
}
- if (this.func_196446_i(p_180655_2_.func_180495_p(p_180655_3_.func_177968_d()))) {
+ if (this.canCatchFire(p_180655_2_, p_180655_3_.func_177968_d(), EnumFacing.NORTH)) {
for(int i1 = 0; i1 < 2; ++i1) {
double d6 = (double)p_180655_3_.func_177958_n() + p_180655_4_.nextDouble();
double d11 = (double)p_180655_3_.func_177956_o() + p_180655_4_.nextDouble();
@@ -288,7 +293,7 @@
}
}
- if (this.func_196446_i(p_180655_2_.func_180495_p(p_180655_3_.func_177984_a()))) {
+ if (this.canCatchFire(p_180655_2_, p_180655_3_.func_177984_a(), EnumFacing.DOWN)) {
for(int j1 = 0; j1 < 2; ++j1) {
double d7 = (double)p_180655_3_.func_177958_n() + p_180655_4_.nextDouble();
double d12 = (double)(p_180655_3_.func_177956_o() + 1) - p_180655_4_.nextDouble() * (double)0.1F;
@@ -320,10 +325,23 @@
}
public void func_180686_a(Block p_180686_1_, int p_180686_2_, int p_180686_3_) {
+ if (p_180686_1_ == Blocks.field_150350_a) throw new IllegalArgumentException("Tried to set air on fire... This is bad.");
this.field_149849_a.put(p_180686_1_, p_180686_2_);
this.field_149848_b.put(p_180686_1_, p_180686_3_);
}
+ /**
+ * Side sensitive version that calls the block function.
+ *
+ * @param world The current world
+ * @param pos Block position
+ * @param face The side the fire is coming from
+ * @return True if the face can catch fire.
+ */
+ public boolean canCatchFire(IBlockReader world, BlockPos pos, EnumFacing face) {
+ return world.func_180495_p(pos).isFlammable(world, pos, face);
+ }
+
public static void func_149843_e() {
BlockFire blockfire = (BlockFire)Blocks.field_150480_ab;
blockfire.func_180686_a(Blocks.field_196662_n, 5, 20);

View file

@ -0,0 +1,11 @@
--- a/net/minecraft/block/BlockFlowerPot.java
+++ b/net/minecraft/block/BlockFlowerPot.java
@@ -22,7 +22,7 @@
import net.minecraft.world.World;
public class BlockFlowerPot extends Block {
- private static final Map<Block, Block> field_196451_b = Maps.<Block, Block>newHashMap();
+ private static final Map<Block, Block> field_196451_b = Maps.<Block, Block>newHashMap(); //TODO: Delegates
protected static final VoxelShape field_196450_a = Block.func_208617_a(5.0D, 0.0D, 5.0D, 11.0D, 6.0D, 11.0D);
private final Block field_196452_c;

View file

@ -0,0 +1,25 @@
--- a/net/minecraft/block/BlockIce.java
+++ b/net/minecraft/block/BlockIce.java
@@ -34,8 +34,10 @@
public void func_180657_a(World p_180657_1_, EntityPlayer p_180657_2_, BlockPos p_180657_3_, IBlockState p_180657_4_, @Nullable TileEntity p_180657_5_, ItemStack p_180657_6_) {
p_180657_2_.func_71029_a(StatList.field_188065_ae.func_199076_b(this));
p_180657_2_.func_71020_j(0.005F);
- if (this.func_149700_E() && EnchantmentHelper.func_77506_a(Enchantments.field_185306_r, p_180657_6_) > 0) {
- func_180635_a(p_180657_1_, p_180657_3_, this.func_180643_i(p_180657_4_));
+ if (this.canSilkHarvest(p_180657_4_, p_180657_1_, p_180657_3_, p_180657_2_) && EnchantmentHelper.func_77506_a(Enchantments.field_185306_r, p_180657_6_) > 0) {
+ net.minecraft.util.NonNullList<ItemStack> items = net.minecraft.util.NonNullList.func_193580_a(ItemStack.field_190927_a, func_180643_i(p_180657_4_));
+ net.minecraftforge.event.ForgeEventFactory.fireBlockHarvesting(items, p_180657_1_, p_180657_3_, p_180657_4_, 0, 1.0f, true, p_180657_2_);
+ items.stream().filter(e -> !e.func_190926_b()).forEach(e -> func_180635_a(p_180657_1_, p_180657_3_, e));
} else {
if (p_180657_1_.field_73011_w.func_177500_n()) {
p_180657_1_.func_175698_g(p_180657_3_);
@@ -43,7 +45,9 @@
}
int i = EnchantmentHelper.func_77506_a(Enchantments.field_185308_t, p_180657_6_);
+ harvesters.set(p_180657_2_);
p_180657_4_.func_196949_c(p_180657_1_, p_180657_3_, i);
+ harvesters.set(null);
Material material = p_180657_1_.func_180495_p(p_180657_3_.func_177977_b()).func_185904_a();
if (material.func_76230_c() || material.func_76224_d()) {
p_180657_1_.func_175656_a(p_180657_3_, Blocks.field_150355_j.func_176223_P());

View file

@ -0,0 +1,28 @@
--- a/net/minecraft/block/BlockLadder.java
+++ b/net/minecraft/block/BlockLadder.java
@@ -3,6 +3,7 @@
import javax.annotation.Nullable;
import net.minecraft.block.state.BlockFaceShape;
import net.minecraft.block.state.IBlockState;
+import net.minecraft.entity.EntityLivingBase;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.IFluidState;
import net.minecraft.init.Blocks;
@@ -20,6 +21,7 @@
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
import net.minecraft.world.IWorldReaderBase;
public class BlockLadder extends Block implements IBucketPickupHandler, ILiquidContainer {
@@ -151,4 +153,9 @@
return false;
}
}
+
+ @Override
+ public boolean isLadder(IBlockState state, IWorldReader world, BlockPos pos, EntityLivingBase entity) {
+ return true;
+ }
}

View file

@ -0,0 +1,97 @@
--- a/net/minecraft/block/BlockLeaves.java
+++ b/net/minecraft/block/BlockLeaves.java
@@ -1,6 +1,9 @@
package net.minecraft.block;
+import java.util.List;
import java.util.Random;
+
+import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
@@ -22,11 +25,12 @@
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld;
+import net.minecraft.world.IWorldReader;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
-public class BlockLeaves extends Block {
+public class BlockLeaves extends Block implements net.minecraftforge.common.IShearable {
public static final IntegerProperty field_208494_a = BlockStateProperties.field_208514_aa;
public static final BooleanProperty field_208495_b = BlockStateProperties.field_208515_s;
protected static boolean field_196478_c;
@@ -122,28 +126,37 @@
}
public void func_196255_a(IBlockState p_196255_1_, World p_196255_2_, BlockPos p_196255_3_, float p_196255_4_, int p_196255_5_) {
- if (!p_196255_2_.field_72995_K) {
- int i = this.func_196472_i(p_196255_1_);
- if (p_196255_5_ > 0) {
- i -= 2 << p_196255_5_;
+ super.func_196255_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_4_, p_196255_5_);
+ }
+
+ @Override
+ public void getDrops(IBlockState state, net.minecraft.util.NonNullList<ItemStack> drops, World worldIn, BlockPos pos, int fortune) {
+ {
+ int i = this.func_196472_i(state);
+ if (fortune > 0) {
+ i -= 2 << fortune;
if (i < 10) {
i = 10;
}
}
- if (p_196255_2_.field_73012_v.nextInt(i) == 0) {
- func_180635_a(p_196255_2_, p_196255_3_, new ItemStack(this.func_199769_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_5_)));
+ if (worldIn.field_73012_v.nextInt(i) == 0) {
+ ItemStack drop = new ItemStack(this.func_199769_a(state, worldIn, pos, fortune));
+ if (!drop.func_190926_b())
+ drops.add(drop);
}
i = 200;
- if (p_196255_5_ > 0) {
- i -= 10 << p_196255_5_;
+ if (fortune > 0) {
+ i -= 10 << fortune;
if (i < 40) {
i = 40;
}
}
- this.func_196474_a(p_196255_2_, p_196255_3_, p_196255_1_, i);
+ captureDrops(true);
+ this.func_196474_a(worldIn, pos, state, i);
+ drops.addAll(captureDrops(false));
}
}
@@ -173,13 +186,7 @@
}
public void func_180657_a(World p_180657_1_, EntityPlayer p_180657_2_, BlockPos p_180657_3_, IBlockState p_180657_4_, @Nullable TileEntity p_180657_5_, ItemStack p_180657_6_) {
- if (!p_180657_1_.field_72995_K && p_180657_6_.func_77973_b() == Items.field_151097_aZ) {
- p_180657_2_.func_71029_a(StatList.field_188065_ae.func_199076_b(this));
- p_180657_2_.func_71020_j(0.005F);
- func_180635_a(p_180657_1_, p_180657_3_, new ItemStack(this));
- } else {
super.func_180657_a(p_180657_1_, p_180657_2_, p_180657_3_, p_180657_4_, p_180657_5_, p_180657_6_);
- }
}
protected void func_206840_a(StateContainer.Builder<Block, IBlockState> p_206840_1_) {
@@ -189,4 +196,9 @@
public IBlockState func_196258_a(BlockItemUseContext p_196258_1_) {
return func_208493_b((IBlockState)this.func_176223_P().func_206870_a(field_208495_b, Boolean.valueOf(true)), p_196258_1_.func_195991_k(), p_196258_1_.func_195995_a());
}
+
+ @Override
+ public List<ItemStack> onSheared(@Nonnull ItemStack item, IWorldReader world, BlockPos pos, int fortune) {
+ return java.util.Arrays.asList(new ItemStack(this));
+ }
}

View file

@ -0,0 +1,31 @@
--- a/net/minecraft/block/BlockMobSpawner.java
+++ b/net/minecraft/block/BlockMobSpawner.java
@@ -10,9 +10,12 @@
import net.minecraft.util.IItemProvider;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
+import net.minecraft.world.IWorldReader;
import net.minecraft.world.World;
public class BlockMobSpawner extends BlockContainer {
+ private static final java.util.Random RAND = new java.util.Random();
+
protected BlockMobSpawner(Block.Builder p_i48364_1_) {
super(p_i48364_1_);
}
@@ -27,10 +30,13 @@
public void func_196255_a(IBlockState p_196255_1_, World p_196255_2_, BlockPos p_196255_3_, float p_196255_4_, int p_196255_5_) {
super.func_196255_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_4_, p_196255_5_);
- int i = 15 + p_196255_2_.field_73012_v.nextInt(15) + p_196255_2_.field_73012_v.nextInt(15);
- this.func_180637_b(p_196255_2_, p_196255_3_, i);
}
+ @Override
+ public int getExpDrop(IBlockState state, IWorldReader world, BlockPos pos, int fortune) {
+ return 15 + RAND.nextInt(15) + RAND.nextInt(15);
+ }
+
public EnumBlockRenderType func_149645_b(IBlockState p_149645_1_) {
return EnumBlockRenderType.MODEL;
}

View file

@ -0,0 +1,11 @@
--- a/net/minecraft/block/BlockMushroom.java
+++ b/net/minecraft/block/BlockMushroom.java
@@ -64,7 +64,7 @@
IBlockState iblockstate = p_196260_2_.func_180495_p(blockpos);
Block block = iblockstate.func_177230_c();
if (block != Blocks.field_150391_bh && block != Blocks.field_196661_l) {
- return p_196260_2_.func_201669_a(p_196260_3_, 0) < 13 && this.func_200014_a_(iblockstate, p_196260_2_, blockpos);
+ return p_196260_2_.func_201669_a(p_196260_3_, 0) < 13 && iblockstate.canSustainPlant(p_196260_2_, blockpos, net.minecraft.util.EnumFacing.UP, this);
} else {
return true;
}

View file

@ -0,0 +1,45 @@
--- a/net/minecraft/block/BlockNetherWart.java
+++ b/net/minecraft/block/BlockNetherWart.java
@@ -33,26 +33,33 @@
public void func_196267_b(IBlockState p_196267_1_, World p_196267_2_, BlockPos p_196267_3_, Random p_196267_4_) {
int i = p_196267_1_.func_177229_b(field_176486_a);
- if (i < 3 && p_196267_4_.nextInt(10) == 0) {
- p_196267_1_ = (IBlockState)p_196267_1_.func_206870_a(field_176486_a, Integer.valueOf(i + 1));
- p_196267_2_.func_180501_a(p_196267_3_, p_196267_1_, 2);
+ if (i < 3 && net.minecraftforge.common.ForgeHooks.onCropsGrowPre(p_196267_2_, p_196267_3_, p_196267_1_, p_196267_4_.nextInt(10) == 0)) {
+ IBlockState newState = (IBlockState)p_196267_1_.func_206870_a(field_176486_a, Integer.valueOf(i + 1));
+ p_196267_2_.func_180501_a(p_196267_3_, newState, 2);
+ net.minecraftforge.common.ForgeHooks.onCropsGrowPost(p_196267_2_, p_196267_3_, p_196267_1_);
+ p_196267_1_ = newState;
}
super.func_196267_b(p_196267_1_, p_196267_2_, p_196267_3_, p_196267_4_);
}
public void func_196255_a(IBlockState p_196255_1_, World p_196255_2_, BlockPos p_196255_3_, float p_196255_4_, int p_196255_5_) {
- if (!p_196255_2_.field_72995_K) {
+ super.func_196255_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_4_, p_196255_5_);
+ }
+
+ @Override
+ public void getDrops(IBlockState state, net.minecraft.util.NonNullList<ItemStack> drops, World worldIn, BlockPos pos, int fortune) {
+ {
int i = 1;
- if (p_196255_1_.func_177229_b(field_176486_a) >= 3) {
- i = 2 + p_196255_2_.field_73012_v.nextInt(3);
- if (p_196255_5_ > 0) {
- i += p_196255_2_.field_73012_v.nextInt(p_196255_5_ + 1);
+ if (state.func_177229_b(field_176486_a) >= 3) {
+ i = 2 + worldIn.field_73012_v.nextInt(3);
+ if (fortune > 0) {
+ i += worldIn.field_73012_v.nextInt(fortune + 1);
}
}
for(int j = 0; j < i; ++j) {
- func_180635_a(p_196255_2_, p_196255_3_, new ItemStack(Items.field_151075_bm));
+ drops.add(new ItemStack(Items.field_151075_bm));
}
}

View file

@ -0,0 +1,23 @@
--- a/net/minecraft/block/BlockNote.java
+++ b/net/minecraft/block/BlockNote.java
@@ -59,7 +59,9 @@
if (p_196250_2_.field_72995_K) {
return true;
} else {
- p_196250_1_ = (IBlockState)p_196250_1_.func_177231_a(field_196485_c);
+ int _new = net.minecraftforge.common.ForgeHooks.onNoteChange(p_196250_2_, p_196250_3_, p_196250_1_, p_196250_1_.func_177229_b(field_196485_c), p_196250_1_.func_177231_a(field_196485_c).func_177229_b(field_196485_c));
+ if (_new == -1) return false;
+ p_196250_1_ = (IBlockState)p_196250_1_.func_206870_a(field_196485_c, _new);
p_196250_2_.func_180501_a(p_196250_3_, p_196250_1_, 3);
this.func_196482_a(p_196250_2_, p_196250_3_);
p_196250_4_.func_195066_a(StatList.field_188087_U);
@@ -75,6 +77,9 @@
}
public boolean func_189539_a(IBlockState p_189539_1_, World p_189539_2_, BlockPos p_189539_3_, int p_189539_4_, int p_189539_5_) {
+ net.minecraftforge.event.world.NoteBlockEvent.Play e = new net.minecraftforge.event.world.NoteBlockEvent.Play(p_189539_2_, p_189539_3_, p_189539_1_, p_189539_1_.func_177229_b(field_196485_c), p_189539_1_.func_177229_b(field_196483_a));
+ if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(e)) return false;
+ p_189539_1_ = p_189539_1_.func_206870_a(field_196485_c, e.getVanillaNoteId()).func_206870_a(field_196483_a, e.getInstrument());
int i = p_189539_1_.func_177229_b(field_196485_c);
float f = (float)Math.pow(2.0D, (double)(i - 12) / 12.0D);
p_189539_2_.func_184133_a((EntityPlayer)null, p_189539_3_, ((NoteBlockInstrument)p_189539_1_.func_177229_b(field_196483_a)).func_208088_a(), SoundCategory.RECORDS, 3.0F, f);

View file

@ -0,0 +1,39 @@
--- a/net/minecraft/block/BlockOre.java
+++ b/net/minecraft/block/BlockOre.java
@@ -49,23 +49,27 @@
public void func_196255_a(IBlockState p_196255_1_, World p_196255_2_, BlockPos p_196255_3_, float p_196255_4_, int p_196255_5_) {
super.func_196255_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_4_, p_196255_5_);
- if (this.func_199769_a(p_196255_1_, p_196255_2_, p_196255_3_, p_196255_5_) != this) {
+ }
+
+ @Override
+ public int getExpDrop(IBlockState state, net.minecraft.world.IWorldReader reader, BlockPos pos, int fortune) {
+ World world = reader instanceof World ? (World)reader : null;
+ if (world == null || this.func_199769_a(state, world, pos, fortune) != this) {
int i = 0;
if (this == Blocks.field_150365_q) {
- i = MathHelper.func_76136_a(p_196255_2_.field_73012_v, 0, 2);
+ i = MathHelper.func_76136_a(RANDOM, 0, 2);
} else if (this == Blocks.field_150482_ag) {
- i = MathHelper.func_76136_a(p_196255_2_.field_73012_v, 3, 7);
+ i = MathHelper.func_76136_a(RANDOM, 3, 7);
} else if (this == Blocks.field_150412_bA) {
- i = MathHelper.func_76136_a(p_196255_2_.field_73012_v, 3, 7);
+ i = MathHelper.func_76136_a(RANDOM, 3, 7);
} else if (this == Blocks.field_150369_x) {
- i = MathHelper.func_76136_a(p_196255_2_.field_73012_v, 2, 5);
+ i = MathHelper.func_76136_a(RANDOM, 2, 5);
} else if (this == Blocks.field_196766_fg) {
- i = MathHelper.func_76136_a(p_196255_2_.field_73012_v, 2, 5);
+ i = MathHelper.func_76136_a(RANDOM, 2, 5);
}
-
- this.func_180637_b(p_196255_2_, p_196255_3_, i);
+ return i;
}
-
+ return 0;
}
public ItemStack func_185473_a(IBlockReader p_185473_1_, BlockPos p_185473_2_, IBlockState p_185473_3_) {

View file

@ -0,0 +1,29 @@
--- a/net/minecraft/block/BlockRailPowered.java
+++ b/net/minecraft/block/BlockRailPowered.java
@@ -15,10 +15,16 @@
public class BlockRailPowered extends BlockRailBase {
public static final EnumProperty<RailShape> field_176568_b = BlockStateProperties.field_208166_S;
public static final BooleanProperty field_176569_M = BlockStateProperties.field_208194_u;
+ private final boolean isActivator;
protected BlockRailPowered(Block.Builder p_i48349_1_) {
- super(true, p_i48349_1_);
+ this(p_i48349_1_, false);
+ }
+
+ protected BlockRailPowered(Block.Builder builder, boolean isActivator) {
+ super(true, builder);
this.func_180632_j((IBlockState)((IBlockState)(this.field_176227_L.func_177621_b()).func_206870_a(field_176568_b, RailShape.NORTH_SOUTH)).func_206870_a(field_176569_M, Boolean.valueOf(false)));
+ this.isActivator = isActivator;
}
protected boolean func_176566_a(World p_176566_1_, BlockPos p_176566_2_, IBlockState p_176566_3_, boolean p_176566_4_, int p_176566_5_) {
@@ -100,7 +106,7 @@
protected boolean func_208071_a(World p_208071_1_, BlockPos p_208071_2_, boolean p_208071_3_, int p_208071_4_, RailShape p_208071_5_) {
IBlockState iblockstate = p_208071_1_.func_180495_p(p_208071_2_);
- if (iblockstate.func_177230_c() != this) {
+ if (!(iblockstate.func_177230_c() instanceof BlockRailPowered) || isActivator != ((BlockRailPowered)iblockstate.func_177230_c()).isActivator) {
return false;
} else {
RailShape railshape = (RailShape)iblockstate.func_177229_b(field_176568_b);

View file

@ -0,0 +1,45 @@
--- a/net/minecraft/block/BlockShearableDoublePlant.java
+++ b/net/minecraft/block/BlockShearableDoublePlant.java
@@ -1,5 +1,7 @@
package net.minecraft.block;
+import java.util.List;
+
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
@@ -11,7 +13,7 @@
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
-public class BlockShearableDoublePlant extends BlockDoublePlant {
+public class BlockShearableDoublePlant extends BlockDoublePlant implements net.minecraftforge.common.IShearable {
public static final EnumProperty<DoubleBlockHalf> field_208063_b = BlockDoublePlant.field_176492_b;
private final Block field_196392_b;
@@ -26,9 +28,7 @@
}
protected void func_196391_a(IBlockState p_196391_1_, World p_196391_2_, BlockPos p_196391_3_, ItemStack p_196391_4_) {
- if (p_196391_4_.func_77973_b() == Items.field_151097_aZ) {
- func_180635_a(p_196391_2_, p_196391_3_, new ItemStack(this.field_196392_b, 2));
- } else {
+ {
super.func_196391_a(p_196391_1_, p_196391_2_, p_196391_3_, p_196391_4_);
}
@@ -37,4 +37,14 @@
public IItemProvider func_199769_a(IBlockState p_199769_1_, World p_199769_2_, BlockPos p_199769_3_, int p_199769_4_) {
return p_199769_1_.func_177229_b(field_208063_b) == DoubleBlockHalf.LOWER && this == Blocks.field_196804_gh && p_199769_2_.field_73012_v.nextInt(8) == 0 ? Items.field_151014_N : Items.field_190931_a;
}
+
+ @Override
+ public boolean isShearable(ItemStack item, net.minecraft.world.IWorldReader world, BlockPos pos) {
+ return false;
+ }
+
+ @Override
+ public List<ItemStack> onSheared(ItemStack item, net.minecraft.world.IWorldReader world, BlockPos pos, int fortune) {
+ return java.util.Arrays.asList(new ItemStack(this.field_196392_b, 2));
+ }
}

View file

@ -0,0 +1,53 @@
--- a/net/minecraft/block/state/BlockPistonStructureHelper.java
+++ b/net/minecraft/block/state/BlockPistonStructureHelper.java
@@ -51,7 +51,7 @@
} else {
for(int i = 0; i < this.field_177258_e.size(); ++i) {
BlockPos blockpos = this.field_177258_e.get(i);
- if (this.field_177261_a.func_180495_p(blockpos).func_177230_c() == Blocks.field_180399_cE && !this.func_177250_b(blockpos)) {
+ if (this.field_177261_a.func_180495_p(blockpos).isStickyBlock() && !this.func_177250_b(blockpos)) {
return false;
}
}
@@ -62,8 +62,7 @@
private boolean func_177251_a(BlockPos p_177251_1_, EnumFacing p_177251_2_) {
IBlockState iblockstate = this.field_177261_a.func_180495_p(p_177251_1_);
- Block block = iblockstate.func_177230_c();
- if (iblockstate.func_196958_f()) {
+ if (iblockstate.isAir(field_177261_a, p_177251_1_)) {
return true;
} else if (!BlockPistonBase.func_185646_a(iblockstate, this.field_177261_a, p_177251_1_, this.field_177257_d, false, p_177251_2_)) {
return true;
@@ -76,11 +75,10 @@
if (i + this.field_177258_e.size() > 12) {
return false;
} else {
- while(block == Blocks.field_180399_cE) {
+ while(iblockstate.isStickyBlock()) {
BlockPos blockpos = p_177251_1_.func_177967_a(this.field_177257_d.func_176734_d(), i);
iblockstate = this.field_177261_a.func_180495_p(blockpos);
- block = iblockstate.func_177230_c();
- if (iblockstate.func_196958_f() || !BlockPistonBase.func_185646_a(iblockstate, this.field_177261_a, blockpos, this.field_177257_d, false, this.field_177257_d.func_176734_d()) || blockpos.equals(this.field_177259_b)) {
+ if (iblockstate.isAir(field_177261_a, blockpos) || !BlockPistonBase.func_185646_a(iblockstate, this.field_177261_a, blockpos, this.field_177257_d, false, this.field_177257_d.func_176734_d()) || blockpos.equals(this.field_177259_b)) {
break;
}
@@ -107,7 +105,7 @@
for(int l = 0; l <= k + i1; ++l) {
BlockPos blockpos2 = this.field_177258_e.get(l);
- if (this.field_177261_a.func_180495_p(blockpos2).func_177230_c() == Blocks.field_180399_cE && !this.func_177250_b(blockpos2)) {
+ if (this.field_177261_a.func_180495_p(blockpos2).isStickyBlock() && !this.func_177250_b(blockpos2)) {
return false;
}
}
@@ -116,7 +114,7 @@
}
iblockstate = this.field_177261_a.func_180495_p(blockpos1);
- if (iblockstate.func_196958_f()) {
+ if (iblockstate.isAir(field_177261_a, blockpos1)) {
return true;
}

View file

@ -9,3 +9,11 @@
ThreadLocal<Object2ByteMap<IBlockState>> field_208776_a = ThreadLocal.<Object2ByteMap<IBlockState>>withInitial(() -> {
Object2ByteOpenHashMap<IBlockState> object2byteopenhashmap = new Object2ByteOpenHashMap<IBlockState>();
object2byteopenhashmap.defaultReturnValue((byte)127);
@@ -109,6 +109,7 @@
return this.func_177230_c().func_180659_g(this, p_185909_1_, p_185909_2_);
}
+ @Deprecated//Forge: Use position sensitive version
default IBlockState func_185907_a(Rotation p_185907_1_) {
return this.func_177230_c().func_185499_a(this, p_185907_1_);
}

View file

@ -1,10 +1,6 @@
--- a/net/minecraft/world/World.java
+++ b/net/minecraft/world/World.java
@@ -68,10 +68,11 @@
import net.minecraft.world.storage.WorldSavedDataStorage;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
+
@@ -71,7 +71,7 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -13,7 +9,16 @@
protected static final Logger field_195596_d = LogManager.getLogger();
private static final EnumFacing[] field_200007_a = EnumFacing.values();
private int field_181546_a = 63;
@@ -121,6 +122,7 @@
@@ -110,6 +110,8 @@
private final WorldBorder field_175728_M;
int[] field_72994_J;
+ public boolean restoringBlockSnapshots = false;
+
protected World(ISaveHandler p_i45749_1_, WorldInfo p_i45749_2_, Dimension p_i45749_3_, Profiler p_i45749_4_, boolean p_i45749_5_) {
this.field_73021_x = Lists.newArrayList(this.field_184152_t);
this.field_72985_G = true;
@@ -121,6 +123,7 @@
this.field_73011_w = p_i45749_3_;
this.field_72995_K = p_i45749_5_;
this.field_175728_M = p_i45749_3_.func_177501_r();
@ -21,7 +26,7 @@
}
public IWorld func_175643_b() {
@@ -2397,4 +2399,31 @@
@@ -2397,4 +2400,31 @@
public abstract RecipeManager func_199532_z();
public abstract NetworkTagManager func_205772_D();
@ -29,7 +34,7 @@
+ /* ======================================== FORGE START =====================================*/
+
+ private net.minecraftforge.common.util.WorldCapabilityData capabilityData;
+
+
+ protected void initCapabilities()
+ {
+ net.minecraftforge.common.capabilities.ICapabilityProvider parent = field_73011_w.initCapabilities();
@ -46,7 +51,7 @@
+ capabilityData.setCapabilities(field_73011_w, getCapabilities());
+ }
+ }
+
+
+ protected WorldSavedDataStorage perWorldStorage; //Moved to a getter to simulate final without being final so we can load in subclasses.
+ public WorldSavedDataStorage getPerWorldStorage()
+ {

View file

@ -9,11 +9,11 @@
public static final float[] field_111203_a = new float[]{1.0F, 0.75F, 0.5F, 0.25F, 0.0F, 0.25F, 0.5F, 0.75F};
protected World field_76579_a;
protected boolean field_76575_d;
@@ -141,4 +141,76 @@
@@ -141,4 +141,91 @@
public abstract boolean func_76568_b(int p_76568_1_, int p_76568_2_);
public abstract DimensionType func_186058_p();
+
+
+ /*======================================= Forge Start =========================================*/
+ private net.minecraftforge.client.IRenderHandler skyRenderer = null;
+ private net.minecraftforge.client.IRenderHandler cloudRenderer = null;
@ -39,14 +39,14 @@
+ {
+ return this.skyRenderer;
+ }
+
+
+ @OnlyIn(Dist.CLIENT)
+ @Override
+ public void setSkyRenderer(net.minecraftforge.client.IRenderHandler skyRenderer)
+ {
+ this.skyRenderer = skyRenderer;
+ }
+
+
+ @Nullable
+ @OnlyIn(Dist.CLIENT)
+ @Override
@ -54,14 +54,14 @@
+ {
+ return cloudRenderer;
+ }
+
+
+ @OnlyIn(Dist.CLIENT)
+ @Override
+ public void setCloudRenderer(net.minecraftforge.client.IRenderHandler renderer)
+ {
+ cloudRenderer = renderer;
+ }
+
+
+ @Nullable
+ @OnlyIn(Dist.CLIENT)
+ @Override
@ -69,14 +69,14 @@
+ {
+ return weatherRenderer;
+ }
+
+
+ @OnlyIn(Dist.CLIENT)
+ @Override
+ public void setWeatherRenderer(net.minecraftforge.client.IRenderHandler renderer)
+ {
+ weatherRenderer = renderer;
+ }
+
+
+ @Override
+ public void resetRainAndThunder()
+ {
@ -84,5 +84,20 @@
+ field_76579_a.func_72912_H().func_76084_b(false);
+ field_76579_a.func_72912_H().func_76090_f(0);
+ field_76579_a.func_72912_H().func_76069_a(false);
+ }
+
+ /**
+ * Determines if the player can sleep in this world (or if the bed should explode for example).
+ *
+ * @param player The player that is attempting to sleep
+ * @param pos The location where the player tries to sleep at (the position of the clicked on bed for example)
+ * @return the result of a player trying to sleep at the given location
+ */
+ public SleepResult canSleepAt(net.minecraft.entity.player.EntityPlayer player, BlockPos pos) {
+ return (this.func_76567_e() && this.field_76579_a.func_180494_b(pos) != net.minecraft.init.Biomes.field_76778_j) ? SleepResult.ALLOW : SleepResult.BED_EXPLODES;
+ }
+
+ public enum SleepResult {
+ ALLOW, DENY, BED_EXPLODES
+ }
}

View file

@ -123,7 +123,7 @@ public class BlockInfo
{
BlockPos pos = blockPos.add(x - 1, y - 1, z - 1);
IBlockState state = world.getBlockState(pos);
t[x][y][z] = state.getLightOpacity(world, pos) < 15;
t[x][y][z] = state.getOpacity(world, pos) < 15;
int brightness = state.getPackedLightmapCoords(world, pos);
s[x][y][z] = (brightness >> 0x14) & 0xF;
b[x][y][z] = (brightness >> 0x04) & 0xF;

View file

@ -47,5 +47,5 @@ public enum EnumPlantType
* @param name the name of the type of plant, you had better follow the style above
* @return the acquired {@link EnumPlantType}, a new one if not found.
*/
public static EnumPlantType create(String name, int test, long bar, String foo){ return null; }
public static EnumPlantType create(String name){ return null; }
}

View file

@ -657,11 +657,6 @@ public class ForgeHooks
return event.getEntityItem();
}
public static float getEnchantPower(@Nonnull World world, @Nonnull BlockPos pos)
{
return world.getBlockState(pos).getEnchantPowerBonus(world, pos);
}
@Nullable
public static ITextComponent onServerChatEvent(NetHandlerPlayServer net, String raw, ITextComponent comp)
{
@ -1177,7 +1172,7 @@ public class ForgeHooks
return (ev.getResult() == net.minecraftforge.eventbus.api.Event.Result.ALLOW || (ev.getResult() == net.minecraftforge.eventbus.api.Event.Result.DEFAULT && def));
}
public static void onCropsGrowPost(World worldIn, BlockPos pos, IBlockState state, IBlockState blockState)
public static void onCropsGrowPost(World worldIn, BlockPos pos, IBlockState state)
{
MinecraftForge.EVENT_BUS.post(new BlockEvent.CropGrowEvent.Post(worldIn, pos, state, worldIn.getBlockState(pos)));
}
@ -1267,7 +1262,6 @@ public class ForgeHooks
public static boolean onFarmlandTrample(World world, BlockPos pos, IBlockState state, float fallDistance, Entity entity)
{
if (entity.canTrample(state, pos, fallDistance))
{
BlockEvent.FarmlandTrampleEvent event = new BlockEvent.FarmlandTrampleEvent(world, pos, state, fallDistance, entity);
@ -1318,4 +1312,11 @@ public class ForgeHooks
}
}
public static int onNoteChange(World world, BlockPos pos, IBlockState state, int old, int _new) {
NoteBlockEvent.Change event = new NoteBlockEvent.Change(world, pos, state, old, _new);
if (MinecraftForge.EVENT_BUS.post(event))
return -1;
return event.getVanillaNoteId();
}
}

View file

@ -19,12 +19,28 @@
package net.minecraftforge.common;
import net.minecraft.block.BlockCrops;
import net.minecraft.block.BlockFlower;
import net.minecraft.block.BlockSapling;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.IBlockReader;
public interface IPlantable
{
EnumPlantType getPlantType(IWorldReader world, BlockPos pos);
IBlockState getPlant(IWorldReader world, BlockPos pos);
default EnumPlantType getPlantType(IBlockReader world, BlockPos pos) {
if (this instanceof BlockCrops) return EnumPlantType.Crop;
if (this instanceof BlockSapling) return EnumPlantType.Plains;
if (this instanceof BlockFlower) return EnumPlantType.Plains;
if (this == Blocks.DEAD_BUSH) return EnumPlantType.Desert;
if (this == Blocks.LILY_PAD) return EnumPlantType.Water;
if (this == Blocks.RED_MUSHROOM) return EnumPlantType.Cave;
if (this == Blocks.BROWN_MUSHROOM) return EnumPlantType.Cave;
if (this == Blocks.NETHER_WART) return EnumPlantType.Nether;
if (this == Blocks.TALL_GRASS) return EnumPlantType.Plains;
return net.minecraftforge.common.EnumPlantType.Plains;
}
IBlockState getPlant(IBlockReader world, BlockPos pos);
}

View file

@ -48,7 +48,9 @@ public interface IShearable
* @param pos Block's position in world.
* @return If this is shearable, and onSheared should be called.
*/
boolean isShearable(@Nonnull ItemStack item, IWorldReader world, BlockPos pos);
default boolean isShearable(@Nonnull ItemStack item, IWorldReader world, BlockPos pos) {
return true;
}
/**
* Performs the shear function on this object.

View file

@ -95,8 +95,9 @@ public class RuntimeEnumExtender implements ILaunchPluginService {
{
LOGGER.error(()->new AdvancedLogMessageAdapter(sb-> {
sb.append("Enum has create method with no matching constructor:\n");
sb.append(" Enum: " + classType.getDescriptor()).append("\n");
sb.append(" Target: ").append(desc).append("\n");
classNode.methods.stream().filter(m -> m.name.equals("<init>")).forEach(m -> sb.append(" :").append(m.desc).append("\n"));
classNode.methods.stream().filter(m -> m.name.equals("<init>")).forEach(m -> sb.append(" : ").append(m.desc).append("\n"));
}));
throw new IllegalStateException("Enum has create method with no matching constructor: " + desc);
}

View file

@ -33,8 +33,12 @@ import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.EntitySpawnPlacementRegistry;
import net.minecraft.entity.boss.EntityDragon;
import net.minecraft.entity.boss.EntityWither;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityWitherSkull;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.init.MobEffects;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.Item;
@ -42,6 +46,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.pathfinding.PathNodeType;
import net.minecraft.state.IProperty;
import net.minecraft.state.properties.BedPart;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.*;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
@ -51,9 +56,11 @@ import net.minecraft.world.Explosion;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.IWorldReaderBase;
import net.minecraft.world.IWorldWriter;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraft.world.dimension.EndDimension;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.EnumPlantType;
@ -121,7 +128,7 @@ public interface IForgeBlock
* @param pos Block position in world
* @return True if the block is a full cube
*/
default boolean isNormalCube(IBlockState state, IWorldReader world, BlockPos pos)
default boolean isNormalCube(IBlockState state, IBlockReader world, BlockPos pos)
{
return state.isNormalCube();
}
@ -167,11 +174,75 @@ public interface IForgeBlock
*/
default boolean hasTileEntity(IBlockState state)
{
return this.getBlock().hasTileEntity();
return this instanceof ITileEntityProvider;
}
/**
* Called throughout the code as a replacement for ITileEntityProvider.createNewTileEntity
* Return the same thing you would from that function.
* This will fall back to ITileEntityProvider.createNewTileEntity(World) if this block is a ITileEntityProvider
*
* @param state The state of the current block
* @param world The world to create the TE in
* @return A instance of a class extending TileEntity
*/
@Nullable
default TileEntity createTileEntity(IBlockState state, IBlockReader world)
{
if (getBlock() instanceof ITileEntityProvider)
return ((ITileEntityProvider)getBlock()).createNewTileEntity(world);
return null;
}
/**
* Return true from this function if the player with silk touch can harvest this block directly, and not it's normal drops.
*
* @param state current block state
* @param world The world
* @param pos Block position in world
* @param player The player doing the harvesting
* @return True if the block can be directly harvested using silk touch
*/
boolean canSilkHarvest(IBlockState state, IWorldReader world, BlockPos pos, EntityPlayer player);
/**
* Determines if the player can harvest this block, obtaining it's drops when the block is destroyed.
*
* @param world The current world
* @param pos The block's current position
* @param player The player damaging the block
* @return True to spawn the drops
*/
default public boolean canHarvestBlock(IBlockState state, IBlockReader world, BlockPos pos, EntityPlayer player)
{
return net.minecraftforge.common.ForgeHooks.canHarvestBlock(state, player, world, pos);
}
/**
* Called when a player removes a block. This is responsible for
* actually destroying the block, and the block is intact at time of call.
* This is called regardless of whether the player can harvest the block or
* not.
*
* Return true if the block is actually destroyed.
*
* Note: When used in multiplayer, this is called on both client and
* server sides!
*
* @param state The current state.
* @param world The current world
* @param player The player damaging the block, may be null
* @param pos Block position in world
* @param willHarvest True if Block.harvestBlock will be called after this, if the return in true.
* Can be useful to delay the destruction of tile entities till after harvestBlock
* @return True if the block is actually destroyed.
*/
default boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest)
{
getBlock().onBlockHarvested(world, pos, state, player);
return world.setBlockState(pos, net.minecraft.init.Blocks.AIR.getDefaultState(), world.isRemote ? 11 : 3);
}
/**
* Determines if this block is classified as a Bed, Allowing
* players to sleep in it, though the block has to specifically
@ -198,10 +269,9 @@ public interface IForgeBlock
* @param type The Mob Category Type
* @return True to allow a mob of the specified category to spawn, false to prevent it.
*/
@SuppressWarnings("deprecation")
default boolean canCreatureSpawn(IBlockState state, IWorldReader world, BlockPos pos, EntitySpawnPlacementRegistry.SpawnPlacementType type)
{
return this.getBlock().isTopSolid(state);
return state.isTopSolid();
}
/**
* Returns the position that the player is moved to upon
@ -276,18 +346,6 @@ public interface IForgeBlock
*/
default void beginLeaveDecay(IBlockState state, IWorldReader world, BlockPos pos) {}
/**
* Determines if this block can prevent leaves connected to it from decaying.
* @param state The current state
* @param world The current world
* @param pos Block position in world
* @return true if the presence this block can prevent leaves from decaying.
*/
default boolean canSustainLeaves(IBlockState state, IWorldReader world, BlockPos pos)
{
return false;
}
/**
* Determines if this block is considered a leaf block, used to apply the leaf decay and generation system.
*
@ -330,17 +388,6 @@ public interface IForgeBlock
return isAir(state, world, pos) || isLeaves(state, world, pos);
}
/**
*
* @param world The current world
* @param pos Block position in world
* @return true if the block is wood (logs)
*/
default boolean isWood(IBlockState state, IWorldReader world, BlockPos pos)
{
return false;
}
/**
* Determines if the current block is replaceable by Ore veins during world generation.
*
@ -352,7 +399,7 @@ public interface IForgeBlock
* @return True to allow this block to be replaced by a ore
*/
default boolean isReplaceableOreGen(IBlockState state, IWorldReader world, BlockPos pos, Predicate<IBlockState> target)
{
{ //TODO: Re-evaluate with new world gen
return target.test(state);
}
@ -379,7 +426,10 @@ public interface IForgeBlock
* @param pos Block position in world
* @param explosion The explosion instance affecting the block
*/
void onBlockExploded(IBlockState state, World world, BlockPos pos, Explosion explosion);
default void onBlockExploded(IBlockState state, World world, BlockPos pos, Explosion explosion) {
world.removeBlock(pos);
getBlock().onExplosionDestroy(world, pos, explosion);
}
/**
* Determine if this block can make a redstone connection on the side provided,
@ -452,6 +502,7 @@ public interface IForgeBlock
{
return false;
}
/**
* Allows a block to override the standard vanilla running particles.
* This is called from {@link Entity#spawnRunningParticles} and is called both,
@ -504,47 +555,7 @@ public interface IForgeBlock
* @param plantable The plant that wants to check
* @return True to allow the plant to be planted/stay.
*/
default boolean canSustainPlant(IBlockState state, IWorldReader world, BlockPos pos, EnumFacing facing, IPlantable plantable)
{
IBlockState plant = plantable.getPlant(world, pos.offset(facing));
EnumPlantType type = plantable.getPlantType(world, pos.offset(facing));
if (plant.getBlock() == Blocks.CACTUS)
{
return this.getBlock() == Blocks.CACTUS && this.getBlock() == Blocks.SAND;
}
if (plant.getBlock() == Blocks.SUGAR_CANE)
{
return true;
}
if (plantable instanceof BlockBush && ((BlockBush)plantable).isValidPosition(state, world, pos))
{
return true;
}
switch (type)
{
case Desert: return this.getBlock() == Blocks.SAND || this.getBlock() == Blocks.TERRACOTTA ||
this.getBlock() instanceof BlockGlazedTerracotta;
case Nether: return this.getBlock() == Blocks.SOUL_SAND;
case Crop: return this.getBlock() == Blocks.FARMLAND;
case Cave: return state.isTopSolid();
case Plains: return this.getBlock() == Blocks.GRASS || this.getBlock() == Blocks.DIRT ||
this.getBlock() == Blocks.FARMLAND;
case Water: return state.getMaterial() == Material.WATER; //&& state.getValue(BlockLiquidWrapper)
case Beach:
boolean isBeach = this.getBlock() == Blocks.GRASS || this.getBlock() == Blocks.DIRT ||
this.getBlock() == Blocks.SAND;
boolean hasWater = (world.getBlockState(pos.east()).getMaterial() == Material.WATER ||
world.getBlockState(pos.west()).getMaterial() == Material.WATER ||
world.getBlockState(pos.north()).getMaterial() == Material.WATER ||
world.getBlockState(pos.south()).getMaterial() == Material.WATER);
return isBeach && hasWater;
}
return false;
}
boolean canSustainPlant(IBlockState state, IBlockReader world, BlockPos pos, EnumFacing facing, IPlantable plantable);
/**
* Called when a plant grows on this block, only implemented for saplings using the WorldGen*Trees classes right now.
@ -575,7 +586,7 @@ public interface IForgeBlock
* @param pos Block position in world
* @return True if the soil should be considered fertile.
*/
default boolean isFertile(IBlockState state, IWorldReader world, BlockPos pos)
default boolean isFertile(IBlockState state, IBlockReader world, BlockPos pos)
{
if (this.getBlock() == Blocks.FARMLAND)
return state.get(BlockFarmland.MOISTURE) > 0;
@ -583,24 +594,6 @@ public interface IForgeBlock
return false;
}
/**
* Location aware and overrideable version of the lightOpacity array,
* return the number to subtract from the light value when it passes through this block.
*
* This is not guaranteed to have the tile entity in place before this is called, so it is
* Recommended that you have your tile entity call relight after being placed if you
* rely on it for light info.
*
* @param state The Block state
* @param world The current world
* @param pos Block position in world
* @return The amount of light to block, 0 for air, 255 for fully opaque.
*/
default int getLightOpacity(IBlockState state, IWorldReader world, BlockPos pos)
{
return state.getOpacity(world, pos);
}
/**
* Determines if this block can be used as the base of a beacon.
*
@ -628,46 +621,33 @@ public interface IForgeBlock
return 0;
}
default boolean rotateBlock(IBlockState state, IWorld world, BlockPos pos, EnumFacing axis)
@SuppressWarnings("deprecation")
default IBlockState rotate(IBlockState state, IWorld world, BlockPos pos, Rotation direction)
{
state.getValues().keySet().forEach(prop ->
return state.rotate(direction);
}
/**
* Get the rotations that can apply to the block at the specified coordinates. Null means no rotations are possible.
* Note, this is up to the block to decide. It may not be accurate or representative.
* @param state The current state
* @param world The world
* @param pos Block position in world
* @return An array of valid axes to rotate around, or null for none or unknown
*/
@Nullable
default EnumFacing[] getValidRotations(IBlockState state, IBlockReader world, BlockPos pos)
{
for (IProperty<?> prop : state.getProperties())
{
if (prop.getName().equals("facing") || prop.getName().equals("rotation") && prop.getValueClass() == EnumFacing.class)
if ((prop.getName().equals("facing") || prop.getName().equals("rotation")) && prop.getValueClass() == EnumFacing.class)
{
Block block = state.getBlock();
if (!(block instanceof BlockBed) && !(block instanceof BlockPistonExtension))
{
IBlockState newState;
@SuppressWarnings("unchecked")
IProperty<EnumFacing> facingIProperty = (IProperty<EnumFacing>) prop;
EnumFacing facing = state.get(facingIProperty);
Collection<EnumFacing> validFacing = facingIProperty.getAllowedValues();
// rotate horizontal facings clockwise
if (validFacing.size() == 4 && !validFacing.contains(EnumFacing.UP) && !validFacing.contains(EnumFacing.DOWN))
{
newState = state.with(facingIProperty, facing.rotateY());
}
else
{
// rotate other facings about the axis
EnumFacing rotatedFacing = facing.rotateAround(axis.getAxis());
if (validFacing.contains(rotatedFacing))
{
newState = state.with(facingIProperty, rotatedFacing);
}
else // abnormal facing property, just cycle it
{
newState = state.cycle(facingIProperty);
}
}
world.setBlockState(pos, newState, 3);
}
@SuppressWarnings("unchecked")
Collection<EnumFacing> values = ((Collection<EnumFacing>)prop.getAllowedValues());
return values.toArray(new EnumFacing[values.size()]);
}
});
return false;
}
return null;
}
/**
@ -691,8 +671,21 @@ public interface IForgeBlock
* @param fortune
* @return Amount of XP from breaking this block.
*/
@SuppressWarnings("unchecked")
default boolean recolorBlock(IBlockState state, IWorld world, BlockPos pos, EnumFacing facing, EnumDyeColor color)
{
for (IProperty<?> prop : state.getProperties())
{
if (prop.getName().equals("color") && prop.getValueClass() == EnumDyeColor.class)
{
EnumDyeColor current = (EnumDyeColor)state.get(prop);
if (current != color && prop.getAllowedValues().contains(color))
{
world.setBlockState(pos, state.with(((IProperty<EnumDyeColor>)prop), color), 3);
return true;
}
}
}
return false;
}
@ -782,7 +775,6 @@ public interface IForgeBlock
{
return this.getBlock().getRenderLayer() == layer;
}
// For Internal use only to capture droped items inside getDrops
/**
* Sensitive version of getSoundType
@ -891,7 +883,7 @@ public interface IForgeBlock
* @param facing The side the connecting block is on
* @return True to allow another block to connect to this block
*/
default boolean canBeConnectedTo(IBlockState state, IWorldReader world, BlockPos pos, EnumFacing facing)
default boolean canBeConnectedTo(IBlockState state, IBlockReader world, BlockPos pos, EnumFacing facing)
{
return false;
}
@ -914,16 +906,15 @@ public interface IForgeBlock
* @param side The side of this block that the chest lid is trying to open into
* @return true if the chest should be prevented from opening by this block
*/
@SuppressWarnings("deprecation")
default boolean doesSideBlockChestOpening(IBlockState blockState, IWorldReader world, BlockPos pos, EnumFacing side)
default boolean doesSideBlockChestOpening(IBlockState blockState, IBlockReader world, BlockPos pos, EnumFacing side)
{
ResourceLocation registryName = this.getBlock().getRegistryName();
if (registryName != null && "minecraft".equals(registryName.getNamespace()))
{
// maintain the vanilla behavior of https://bugs.mojang.com/browse/MC-378
return isNormalCube(blockState, world, pos);
return blockState.isNormalCube(world, pos);
}
return this.getBlock().isTopSolid(blockState);
return blockState.isTopSolid();
}
/**
@ -935,4 +926,123 @@ public interface IForgeBlock
return state.getBlock() == Blocks.SLIME_BLOCK;
}
/**
* This gets a complete list of items dropped from this block.
*
* @param state Current state
* @param drops add all items this block drops to this drops list
* @param world The current world, Currently hard 'World' and not 'IBlockReder' because vanilla needs it.
* @param pos Block position in world
* @param fortune Breakers fortune level
*/
default void getDrops(IBlockState state, NonNullList<ItemStack> drops, World world, BlockPos pos, int fortune)
{
int count = getBlock().getItemsToDropCount(state, fortune, world, pos, world.rand);
for (int i = 0; i < count; i++)
{
Item item = getBlock().getItemDropped(state, world, pos, fortune).asItem();
if (item != Items.AIR)
drops.add(new ItemStack(item));
}
}
/**
* Chance that fire will spread and consume this block.
* 300 being a 100% chance, 0, being a 0% chance.
*
* @param state The current state
* @param world The current world
* @param pos Block position in world
* @param face The face that the fire is coming from
* @return A number ranging from 0 to 300 relating used to determine if the block will be consumed by fire
*/
default int getFlammability(IBlockState state, IBlockReader world, BlockPos pos, EnumFacing face)
{
return ((BlockFire)Blocks.FIRE).getFlammability(getBlock());
}
/**
* Called when fire is updating, checks if a block face can catch fire.
*
*
* @param state The current state
* @param world The current world
* @param pos Block position in world
* @param face The face that the fire is coming from
* @return True if the face can be on fire, false otherwise.
*/
default boolean isFlammable(IBlockState state, IBlockReader world, BlockPos pos, EnumFacing face)
{
return state.getFlammability(world, pos, face) > 0;
}
/**
* Called when fire is updating on a neighbor block.
* The higher the number returned, the faster fire will spread around this block.
*
* @param state The current state
* @param world The current world
* @param pos Block position in world
* @param face The face that the fire is coming from
* @return A number that is used to determine the speed of fire growth around the block
*/
default int getFireSpreadSpeed(IBlockState state, IBlockReader world, BlockPos pos, EnumFacing face)
{
return ((BlockFire)Blocks.FIRE).getEncouragement(getBlock());
}
/**
* Currently only called by fire when it is on top of this block.
* Returning true will prevent the fire from naturally dying during updating.
* Also prevents firing from dying from rain.
*
* @param state The current state
* @param world The current world
* @param pos Block position in world
* @param side The face that the fire is coming from
* @return True if this block sustains fire, meaning it will never go out.
*/
default boolean isFireSource(IBlockState state, IBlockReader world, BlockPos pos, EnumFacing side)
{
if (side != EnumFacing.UP)
return false;
if (getBlock() == Blocks.NETHERRACK || getBlock() == Blocks.MAGMA_BLOCK)
return true;
if (world instanceof World && ((World)world).dimension instanceof EndDimension && getBlock() == Blocks.BEDROCK)
return true;
return false;
}
/**
* Determines if this block is can be destroyed by the specified entities normal behavior.
*
* @param state The current state
* @param world The current world
* @param pos Block position in world
* @return True to allow the ender dragon to destroy this block
*/
default boolean canEntityDestroy(IBlockState state, IBlockReader world, BlockPos pos, Entity entity)
{
if (entity instanceof EntityDragon)
{
return this != Blocks.BARRIER &&
this != Blocks.OBSIDIAN &&
this != Blocks.END_STONE &&
this != Blocks.BEDROCK &&
this != Blocks.END_PORTAL &&
this != Blocks.END_PORTAL_FRAME &&
this != Blocks.COMMAND_BLOCK &&
this != Blocks.REPEATING_COMMAND_BLOCK &&
this != Blocks.CHAIN_COMMAND_BLOCK &&
this != Blocks.IRON_BARS &&
this != Blocks.END_GATEWAY;
}
else if ((entity instanceof EntityWither) ||
(entity instanceof EntityWitherSkull))
{
return EntityWither.canDestroyBlock(getBlock());
}
return true;
}
}

View file

@ -24,7 +24,6 @@ import java.util.function.Predicate;
import javax.annotation.Nullable;
import net.minecraft.block.*;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.particle.ParticleManager;
import net.minecraft.entity.Entity;
@ -35,8 +34,8 @@ import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.pathfinding.PathNodeType;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.*;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
@ -107,7 +106,7 @@ public interface IForgeBlockState
* @param pos Block position in world
* @return True if the block is a full cube
*/
default boolean isNormalCube(IWorldReader world, BlockPos pos)
default boolean isNormalCube(IBlockReader world, BlockPos pos)
{
return getBlockState().getBlock().isNormalCube(getBlockState(), world, pos);
}
@ -142,11 +141,70 @@ public interface IForgeBlockState
return getBlockState().getBlock().hasTileEntity(getBlockState());
}
/**
* Called throughout the code as a replacement for ITileEntityProvider.createNewTileEntity
* Return the same thing you would from that function.
* This will fall back to ITileEntityProvider.createNewTileEntity(World) if this block is a ITileEntityProvider
*
* @param world The world to create the TE in
* @return A instance of a class extending TileEntity
*/
@Nullable
default TileEntity createTileEntity(IBlockReader world)
{
return getBlockState().getBlock().createTileEntity(getBlockState(), world);
}
/**
* Return true from this function if the player with silk touch can harvest this block directly, and not it's normal drops.
*
* @param world The world
* @param pos Block position in world
* @param player The player doing the harvesting
* @return True if the block can be directly harvested using silk touch
*/
default boolean canSilkHarvest(IWorldReader world, BlockPos pos, EntityPlayer player)
{
return getBlockState().getBlock().canSilkHarvest(getBlockState(), world, pos, player);
}
/**
* Determines if the player can harvest this block, obtaining it's drops when the block is destroyed.
*
* @param world The current world
* @param pos The block's current position
* @param player The player damaging the block
* @return True to spawn the drops
*/
default boolean canHarvestBlock(IBlockReader world, BlockPos pos, EntityPlayer player)
{
return getBlockState().getBlock().canHarvestBlock(getBlockState(), world, pos, player);
}
/**
* Called when a player removes a block. This is responsible for
* actually destroying the block, and the block is intact at time of call.
* This is called regardless of whether the player can harvest the block or
* not.
*
* Return true if the block is actually destroyed.
*
* Note: When used in multiplayer, this is called on both client and
* server sides!
*
* @param world The current world
* @param player The player damaging the block, may be null
* @param pos Block position in world
* @param willHarvest True if Block.harvestBlock will be called after this, if the return in true.
* Can be useful to delay the destruction of tile entities till after harvestBlock
* @return True if the block is actually destroyed.
*/
default boolean removedByPlayer(World world, BlockPos pos, EntityPlayer player, boolean willHarvest)
{
return getBlockState().getBlock().removedByPlayer(getBlockState(), world, pos, player, willHarvest);
}
/**
* Determines if this block is classified as a Bed, Allowing
* players to sleep in it, though the block has to specifically
@ -239,17 +297,6 @@ public interface IForgeBlockState
getBlockState().getBlock().beginLeaveDecay(getBlockState(), world, pos);
}
/**
* Determines if this block can prevent leaves connected to it from decaying.
* @param world The current world
* @param pos Block position in world
* @return true if the presence this block can prevent leaves from decaying.
*/
default boolean canSustainLeaves(IWorldReader world, BlockPos pos)
{
return getBlockState().getBlock().canSustainLeaves(getBlockState(), world, pos);
}
/**
* Determines if this block is considered a leaf block, used to apply the leaf decay and generation system.
*
@ -289,17 +336,6 @@ public interface IForgeBlockState
return getBlockState().getBlock().canBeReplacedByLeaves(getBlockState(), world, pos);
}
/**
*
* @param world The current world
* @param pos Block position in world
* @return true if the block is wood (logs)
*/
default boolean isWood(IWorldReader world, BlockPos pos)
{
return getBlockState().getBlock().isWood(getBlockState(), world, pos);
}
/**
* Determines if the current block is replaceable by Ore veins during world generation.
*
@ -457,7 +493,7 @@ public interface IForgeBlockState
* @param plantable The plant that wants to check
* @return True to allow the plant to be planted/stay.
*/
default boolean canSustainPlant(IWorldReader world, BlockPos pos, EnumFacing facing, IPlantable plantable)
default boolean canSustainPlant(IBlockReader world, BlockPos pos, EnumFacing facing, IPlantable plantable)
{
return getBlockState().getBlock().canSustainPlant(getBlockState(), world, pos, facing, plantable);
}
@ -489,29 +525,11 @@ public interface IForgeBlockState
* @param pos Block position in world
* @return True if the soil should be considered fertile.
*/
default boolean isFertile(IWorldReader world, BlockPos pos)
default boolean isFertile(IBlockReader world, BlockPos pos)
{
return getBlockState().getBlock().isFertile(getBlockState(), world, pos);
}
/**
* Location aware and overrideable version of the lightOpacity array,
* return the number to subtract from the light value when it passes through this block.
*
* This is not guaranteed to have the tile entity in place before this is called, so it is
* Recommended that you have your tile entity call relight after being placed if you
* rely on it for light info.
*
* @param state The Block state
* @param world The current world
* @param pos Block position in world
* @return The amount of light to block, 0 for air, 255 for fully opaque.
*/
default int getLightOpacity(IWorldReader world, BlockPos pos)
{
return getBlockState().getBlock().getLightOpacity(getBlockState(), world, pos);
}
/**
* Determines if this block can be used as the base of a beacon.
*
@ -524,6 +542,7 @@ public interface IForgeBlockState
{
return getBlockState().getBlock().isBeaconBase(getBlockState(), world, pos, beacon);
}
/**
* Gathers how much experience this block drops when broken.
*
@ -537,9 +556,9 @@ public interface IForgeBlockState
return getBlockState().getBlock().getExpDrop(getBlockState(), world, pos, fortune);
}
default boolean rotateBlock(IWorld world, BlockPos pos, EnumFacing axis)
default IBlockState rotate(IWorld world, BlockPos pos, Rotation direction)
{
return getBlockState().getBlock().rotateBlock(getBlockState(), world, pos, axis);
return getBlockState().getBlock().rotate(getBlockState(), world, pos, direction);
}
@ -554,6 +573,16 @@ public interface IForgeBlockState
return getBlockState().getBlock().getEnchantPowerBonus(getBlockState(), world, pos);
}
/**
* //TODO: Re-Evaluate
* Gathers how much experience this block drops when broken.
*
* @param state The current state
* @param world The world
* @param pos Block position
* @param fortune
* @return Amount of XP from breaking this block.
*/
default boolean recolorBlock(IWorld world, BlockPos pos, EnumFacing facing, EnumDyeColor color)
{
return getBlockState().getBlock().recolorBlock(getBlockState(), world, pos, facing, color);
@ -723,7 +752,6 @@ public interface IForgeBlockState
return getBlockState().getBlock().getStateForPlacement(getBlockState(), facing, state2, world, pos1, pos2, hand);
}
/**
* Determines if another block can connect to this block
*
@ -732,7 +760,7 @@ public interface IForgeBlockState
* @param facing The side the connecting block is on
* @return True to allow another block to connect to this block
*/
default boolean canBeConnectedTo(IWorldReader world, BlockPos pos, EnumFacing facing)
default boolean canBeConnectedTo(IBlockReader world, BlockPos pos, EnumFacing facing)
{
return getBlockState().getBlock().canBeConnectedTo(getBlockState(), world, pos, facing);
}
@ -755,7 +783,7 @@ public interface IForgeBlockState
* @param side The side of this block that the chest lid is trying to open into
* @return true if the chest should be prevented from opening by this block
*/
default boolean doesSideBlockChestOpening(IWorldReader world, BlockPos pos, EnumFacing side)
default boolean doesSideBlockChestOpening(IBlockReader world, BlockPos pos, EnumFacing side)
{
return getBlockState().getBlock().doesSideBlockChestOpening(getBlockState(), world, pos, side);
}
@ -769,4 +797,97 @@ public interface IForgeBlockState
return getBlockState().getBlock().isStickyBlock(getBlockState());
}
/**
* This gets a complete list of items dropped from this block.
*
* @param drops add all items this block drops to this drops list
* @param world The current world
* @param pos Block position in world
* @param fortune Breakers fortune level
*/
default void getDrops(NonNullList<ItemStack> drops, World world, BlockPos pos, int fortune)
{
getBlockState().getBlock().getDrops(getBlockState(), drops, world, pos, fortune);
}
/**
* Chance that fire will spread and consume this block.
* 300 being a 100% chance, 0, being a 0% chance.
*
* @param world The current world
* @param pos Block position in world
* @param face The face that the fire is coming from
* @return A number ranging from 0 to 300 relating used to determine if the block will be consumed by fire
*/
default int getFlammability(IBlockReader world, BlockPos pos, EnumFacing face)
{
return getBlockState().getBlock().getFlammability(getBlockState(), world, pos, face);
}
/**
* Called when fire is updating, checks if a block face can catch fire.
*
* @param world The current world
* @param pos Block position in world
* @param face The face that the fire is coming from
* @return True if the face can be on fire, false otherwise.
*/
default boolean isFlammable(IBlockReader world, BlockPos pos, EnumFacing face)
{
return getBlockState().getBlock().isFlammable(getBlockState(), world, pos, face);
}
/**
* Called when fire is updating on a neighbor block.
* The higher the number returned, the faster fire will spread around this block.
*
* @param world The current world
* @param pos Block position in world
* @param face The face that the fire is coming from
* @return A number that is used to determine the speed of fire growth around the block
*/
default int getFireSpreadSpeed(IBlockReader world, BlockPos pos, EnumFacing face)
{
return getBlockState().getBlock().getFireSpreadSpeed(getBlockState(), world, pos, face);
}
/**
* Currently only called by fire when it is on top of this block.
* Returning true will prevent the fire from naturally dying during updating.
* Also prevents firing from dying from rain.
*
* @param world The current world
* @param pos Block position in world
* @param side The face that the fire is coming from
* @return True if this block sustains fire, meaning it will never go out.
*/
default boolean isFireSource(IBlockReader world, BlockPos pos, EnumFacing side)
{
return getBlockState().getBlock().isFireSource(getBlockState(), world, pos, side);
}
/**
* Determines if this block is can be destroyed by the specified entities normal behavior.
*
* @param world The current world
* @param pos Block position in world
* @return True to allow the ender dragon to destroy this block
*/
default boolean canEntityDestroy(IBlockReader world, BlockPos pos, Entity entity)
{
return getBlockState().getBlock().canEntityDestroy(getBlockState(), world, pos, entity);
}
/**
* Get the rotations that can apply to the block at the specified coordinates. Null means no rotations are possible.
* Note, this is up to the block to decide. It may not be accurate or representative.
* @param world The world
* @param pos Block position in world
* @return An array of valid axes to rotate around, or null for none or unknown
*/
@Nullable
default EnumFacing[] getValidRotations(IBlockReader world, BlockPos pos)
{
return getBlockState().getBlock().getValidRotations(getBlockState(), world, pos);
}
}

View file

@ -254,7 +254,7 @@ public class ForgeEventFactory
return event.getDisplayname();
}
public static float fireBlockHarvesting(List<ItemStack> drops, World world, BlockPos pos, IBlockState state, int fortune, float dropChance, boolean silkTouch, EntityPlayer player)
public static float fireBlockHarvesting(NonNullList<ItemStack> drops, World world, BlockPos pos, IBlockState state, int fortune, float dropChance, boolean silkTouch, EntityPlayer player)
{
BlockEvent.HarvestDropsEvent event = new BlockEvent.HarvestDropsEvent(world, pos, state, fortune, dropChance, drops, player, silkTouch);
MinecraftForge.EVENT_BUS.post(event);

View file

@ -22,17 +22,15 @@ package net.minecraftforge.event.world;
import java.util.EnumSet;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.BlockPortal;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Enchantments;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
@ -90,12 +88,12 @@ public class BlockEvent extends Event
public static class HarvestDropsEvent extends BlockEvent
{
private final int fortuneLevel;
private final List<ItemStack> drops;
private final NonNullList<ItemStack> drops;
private final boolean isSilkTouching;
private float dropChance; // Change to e.g. 1.0f, if you manipulate the list and want to guarantee it always drops
private final EntityPlayer harvester; // May be null for non-player harvesting such as explosions or machines
public HarvestDropsEvent(World world, BlockPos pos, IBlockState state, int fortuneLevel, float dropChance, List<ItemStack> drops, EntityPlayer harvester, boolean isSilkTouching)
public HarvestDropsEvent(World world, BlockPos pos, IBlockState state, int fortuneLevel, float dropChance, NonNullList<ItemStack> drops, EntityPlayer harvester, boolean isSilkTouching)
{
super(world, pos, state);
this.fortuneLevel = fortuneLevel;

View file

@ -20,6 +20,7 @@
package net.minecraftforge.event.world;
import net.minecraft.block.state.IBlockState;
import net.minecraft.state.properties.NoteBlockInstrument;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.eventbus.api.Cancelable;
@ -86,20 +87,20 @@ public class NoteBlockEvent extends BlockEvent
@Cancelable
public static class Play extends NoteBlockEvent
{
private Instrument instrument;
private NoteBlockInstrument instrument;
public Play(World world, BlockPos pos, IBlockState state, int note, int instrument)
public Play(World world, BlockPos pos, IBlockState state, int note, NoteBlockInstrument instrument)
{
super(world, pos, state, note);
this.setInstrument(Instrument.fromId(instrument));
this.instrument = instrument;
}
public Instrument getInstrument()
public NoteBlockInstrument getInstrument()
{
return instrument;
}
public void setInstrument(Instrument instrument)
public void setInstrument(NoteBlockInstrument instrument)
{
this.instrument = instrument;
}
@ -133,32 +134,6 @@ public class NoteBlockEvent extends BlockEvent
}
}
/**
* Describes the types of musical Instruments that can be played by a Noteblock.
* The Instrument being played can be overridden with {@link NoteBlockEvent.Play#setInstrument(Instrument)}
*/
public static enum Instrument
{
PIANO,
BASSDRUM,
SNARE,
CLICKS,
BASSGUITAR,
FLUTE,
BELL,
GUITAR,
CHIME,
XYLOPHONE;
// cache to avoid creating a new array every time
private static final Instrument[] values = values();
static Instrument fromId(int id)
{
return id < 0 || id >= values.length ? PIANO : values[id];
}
}
/**
* Information about the pitch of a Noteblock note.
* For altered notes such as G-Sharp / A-Flat the Sharp variant is used here.

View file

@ -19,9 +19,6 @@
package net.minecraftforge.fml;
import net.minecraft.network.Packet;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.fml.network.ICustomPacket;
import sun.misc.Unsafe;
import java.lang.reflect.Field;

View file

@ -281,12 +281,15 @@ public class GameData
{
static final BlockCallbacks INSTANCE = new BlockCallbacks();
@SuppressWarnings("deprecation")
@Override
public void onAdd(IForgeRegistryInternal<Block> owner, RegistryManager stage, int id, Block block, @Nullable Block oldBlock)
{
@SuppressWarnings("unchecked")
ClearableObjectIntIdentityMap<IBlockState> blockstateMap = owner.getSlaveMap(BLOCKSTATE_TO_ID, ClearableObjectIntIdentityMap.class);
int offset = 0;
for (IBlockState state : block.getStateContainer().getValidStates())
blockstateMap.put(state, id + offset++);
/*
if ("minecraft:tripwire".equals(block.getRegistryName().toString())) //Tripwire is crap so we have to special case whee!
@ -329,29 +332,26 @@ public class GameData
@Override
public void onClear(IForgeRegistryInternal<Block> owner, RegistryManager stage)
{
// owner.getSlaveMap(BLOCKSTATE_TO_ID, ClearableObjectIntIdentityMap.class).clear();
owner.getSlaveMap(BLOCKSTATE_TO_ID, ClearableObjectIntIdentityMap.class).clear();
}
@Override
public void onCreate(IForgeRegistryInternal<Block> owner, RegistryManager stage)
{
/*
final ClearableObjectIntIdentityMap<IBlockState> idMap = new ClearableObjectIntIdentityMap<IBlockState>()
{
@SuppressWarnings("deprecation")
@Override
public int get(IBlockState key)
{
Integer integer = (Integer)this.identityMap.get(key);
// There are some cases where this map is queried to serialize a state that is valid,
//but somehow not in this list, so attempt to get real metadata. Doing this hear saves us 7 patches
if (integer == null && key != null)
integer = this.identityMap.get(key.getBlock().getStateFromMeta(key.getBlock().getMetaFromState(key)));
//if (integer == null && key != null)
// integer = this.identityMap.get(key.getBlock().getStateFromMeta(key.getBlock().getMetaFromState(key)));
return integer == null ? -1 : integer.intValue();
}
};
owner.setSlaveMap(BLOCKSTATE_TO_ID, idMap);
*/
owner.setSlaveMap(BLOCK_TO_ITEM, Maps.newHashMap());
}