More work on compile errors, New system for ToolClasses, using a ToolType class instead to de-stringify things.
This commit is contained in:
parent
0cd21ebe7e
commit
cdfa7caaeb
33 changed files with 1668 additions and 519 deletions
24
build.gradle
24
build.gradle
|
@ -10,6 +10,9 @@ buildscript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id 'net.minecrell.licenser' version '0.4'
|
||||||
|
}
|
||||||
apply plugin: 'eclipse'
|
apply plugin: 'eclipse'
|
||||||
|
|
||||||
group = 'net.minecraftforge'
|
group = 'net.minecraftforge'
|
||||||
|
@ -52,6 +55,7 @@ project(':forge') {
|
||||||
apply plugin: 'java-library'
|
apply plugin: 'java-library'
|
||||||
apply plugin: 'eclipse'
|
apply plugin: 'eclipse'
|
||||||
apply plugin: 'net.minecraftforge.gradle.forgedev.patcher'
|
apply plugin: 'net.minecraftforge.gradle.forgedev.patcher'
|
||||||
|
apply plugin: 'net.minecrell.licenser'
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main {
|
main {
|
||||||
java {
|
java {
|
||||||
|
@ -161,6 +165,26 @@ project(':forge') {
|
||||||
environment target:'fmldevserver'
|
environment target:'fmldevserver'
|
||||||
workingDir 'runserver'
|
workingDir 'runserver'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
license {
|
||||||
|
header = file("$rootDir/LICENSE-header.txt")
|
||||||
|
|
||||||
|
include 'net/minecraftforge/'
|
||||||
|
exclude 'net/minecraftforge/server/terminalconsole/'
|
||||||
|
exclude 'net/minecraftforge/fml/common/versioning/ComparableVersion.java'
|
||||||
|
exclude 'net/minecraftforge/fml/common/versioning/InvalidVersionSpecificationException.java'
|
||||||
|
exclude 'net/minecraftforge/fml/common/versioning/Restriction.java'
|
||||||
|
exclude 'net/minecraftforge/fml/common/versioning/VersionRange.java'
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
main {
|
||||||
|
files = files("$rootDir/src/main/java")
|
||||||
|
}
|
||||||
|
test {
|
||||||
|
files = files("$rootDir/src/test/java")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//evaluationDependsOnChildren()
|
//evaluationDependsOnChildren()
|
||||||
|
|
|
@ -9,66 +9,79 @@
|
||||||
protected static final Logger field_196273_d = LogManager.getLogger();
|
protected static final Logger field_196273_d = LogManager.getLogger();
|
||||||
private static final ResourceLocation AIR_ID = new ResourceLocation("air");
|
private static final ResourceLocation AIR_ID = new ResourceLocation("air");
|
||||||
public static final RegistryNamespacedDefaultedByKey<ResourceLocation, Block> REGISTRY = new RegistryNamespacedDefaultedByKey<ResourceLocation, Block>(AIR_ID);
|
public static final RegistryNamespacedDefaultedByKey<ResourceLocation, Block> REGISTRY = new RegistryNamespacedDefaultedByKey<ResourceLocation, Block>(AIR_ID);
|
||||||
@@ -1604,4 +1604,62 @@
|
@@ -502,8 +502,8 @@
|
||||||
|
if (f == -1.0F) {
|
||||||
|
return 0.0F;
|
||||||
|
} else {
|
||||||
|
- int i = player.canHarvestBlock(state) ? 30 : 100;
|
||||||
|
- return player.getDigSpeed(state) / f / (float)i;
|
||||||
|
+ int i = net.minecraftforge.common.ForgeHooks.canHarvestBlock(state, player, worldIn, pos) ? 30 : 100;
|
||||||
|
+ return player.getDigSpeed(state, pos) / f / (float)i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -625,6 +625,7 @@
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
+ @Deprecated //Use state sensitive version
|
||||||
|
protected boolean canSilkHarvest() {
|
||||||
|
return this.getDefaultState().isFullCube() && !this.hasTileEntity();
|
||||||
|
}
|
||||||
|
@@ -1604,4 +1605,56 @@
|
||||||
return Objects.hash(this.field_212164_a, this.field_212165_b, this.field_212166_c);
|
return Objects.hash(this.field_212164_a, this.field_212165_b, this.field_212166_c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+ /* ======================================== FORGE START =====================================*/
|
+ /* ======================================== FORGE START =====================================*/
|
||||||
+
|
|
||||||
+ private ThreadLocal<IBlockState> silkCheck = new ThreadLocal<>();
|
+ private ThreadLocal<IBlockState> silkCheck = new ThreadLocal<>();
|
||||||
+ private String[] harvestTool = new String[16];
|
+ private net.minecraftforge.common.ToolType harvestTool;
|
||||||
+ private int[] harvestLevel = new int[]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
|
+ private int harvestLevel;
|
||||||
+ protected static ThreadLocal<Boolean> captureDrops = ThreadLocal.withInitial(() -> false);
|
+ protected static ThreadLocal<Boolean> captureDrops = ThreadLocal.withInitial(() -> false);
|
||||||
+ protected static ThreadLocal<NonNullList<ItemStack>> capturedDrops = ThreadLocal.withInitial(NonNullList::create);
|
+ protected static ThreadLocal<NonNullList<ItemStack>> capturedDrops = ThreadLocal.withInitial(NonNullList::create);
|
||||||
+ protected NonNullList<ItemStack> captureDrops(boolean start)
|
+ protected NonNullList<ItemStack> captureDrops(boolean start)
|
||||||
+ {
|
+ {
|
||||||
+ if (start)
|
+ if (start) {
|
||||||
+ {
|
|
||||||
+ captureDrops.set(true);
|
+ captureDrops.set(true);
|
||||||
+ capturedDrops.get().clear();
|
+ capturedDrops.get().clear();
|
||||||
+ return NonNullList.create();
|
+ return NonNullList.create();
|
||||||
+ }
|
+ } else {
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ captureDrops.set(false);
|
+ captureDrops.set(false);
|
||||||
+ return capturedDrops.get();
|
+ return capturedDrops.get();
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ @Override
|
+ @Override
|
||||||
+ public float getSlipperiness(IBlockState state, IWorldReader world, BlockPos pos, @Nullable Entity entity)
|
+ public float getSlipperiness(IBlockState state, IWorldReader world, BlockPos pos, @Nullable Entity entity) {
|
||||||
+ {
|
|
||||||
+ return this.slipperiness;
|
+ return this.slipperiness;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ @Override
|
+ @Override
|
||||||
+ public boolean canSilkHarvest(IWorldReader world, BlockPos pos, IBlockState state, EntityPlayer player)
|
+ public boolean canSilkHarvest(IBlockState state, IWorldReader world, BlockPos pos, EntityPlayer player) {
|
||||||
+ {
|
+ return this.canSilkHarvest() && !state.hasTileEntity();
|
||||||
+ silkCheck.set(state);
|
|
||||||
+ boolean ret = this.canSilkHarvest();
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ @Override
|
+ @Override
|
||||||
+ public void onBlockExploded(World world, BlockPos pos, Explosion explosion)
|
+ public void onBlockExploded(IBlockState state, World world, BlockPos pos, Explosion explosion) {
|
||||||
+ {
|
|
||||||
+ world.setBlockToAir(pos);
|
+ world.setBlockToAir(pos);
|
||||||
+ onExplosionDestroy(world, pos, explosion);
|
+ onExplosionDestroy(world, pos, explosion);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ @Nullable
|
+ @Nullable
|
||||||
+ @Override
|
+ @Override
|
||||||
+ public String getHarvestTool(IBlockState state)
|
+ public net.minecraftforge.common.ToolType getHarvestTool(IBlockState state) {
|
||||||
+ {
|
+ return harvestTool; //TODO: RE-Evaluate
|
||||||
+ return harvestTool[0]; //TODO: RE-Evaluate
|
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ @Override
|
+ @Override
|
||||||
+ public int getHarvestLevel(IBlockState state)
|
+ public int getHarvestLevel(IBlockState state) {
|
||||||
+ {
|
+ return harvestLevel; //TODO: RE-Evaluate
|
||||||
+
|
|
||||||
+ return harvestLevel[0]; //TODO: RE-Evaluate
|
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
|
+ static {
|
||||||
|
+ net.minecraftforge.common.ForgeHooks.setBlockToolSetter((block, tool, level) -> {
|
||||||
|
+ block.harvestTool = tool;
|
||||||
|
+ block.harvestLevel = level;
|
||||||
|
+ });
|
||||||
|
+ }
|
||||||
+ /* ========================================= FORGE END ======================================*/
|
+ /* ========================================= FORGE END ======================================*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
--- a/net/minecraft/block/state/IBlockState.java
|
||||||
|
+++ b/net/minecraft/block/state/IBlockState.java
|
||||||
|
@@ -30,7 +30,7 @@
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
-public interface IBlockState extends IStateHolder<IBlockState> {
|
||||||
|
+public interface IBlockState extends IStateHolder<IBlockState>, net.minecraftforge.common.extensions.IForgeBlockState {
|
||||||
|
ThreadLocal<Object2ByteMap<IBlockState>> field_208776_a = ThreadLocal.<Object2ByteMap<IBlockState>>withInitial(() -> {
|
||||||
|
Object2ByteOpenHashMap<IBlockState> object2byteopenhashmap = new Object2ByteOpenHashMap<IBlockState>();
|
||||||
|
object2byteopenhashmap.defaultReturnValue((byte)127);
|
|
@ -0,0 +1,21 @@
|
||||||
|
--- a/net/minecraft/client/gui/GuiBossOverlay.java
|
||||||
|
+++ b/net/minecraft/client/gui/GuiBossOverlay.java
|
||||||
|
@@ -28,12 +28,17 @@
|
||||||
|
|
||||||
|
for(BossInfoClient bossinfoclient : this.mapBossInfos.values()) {
|
||||||
|
int k = i / 2 - 91;
|
||||||
|
+ net.minecraftforge.client.event.RenderGameOverlayEvent.BossInfo event =
|
||||||
|
+ net.minecraftforge.client.ForgeHooksClient.bossBarRenderPre(this.client.field_195558_d, bossinfoclient, k, j, 10 + this.client.fontRenderer.FONT_HEIGHT);
|
||||||
|
+ if (!event.isCanceled()) {
|
||||||
|
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
|
||||||
|
this.client.getTextureManager().bindTexture(GUI_BARS_TEXTURES);
|
||||||
|
this.render(k, j, bossinfoclient);
|
||||||
|
String s = bossinfoclient.getName().getFormattedText();
|
||||||
|
this.client.fontRenderer.drawStringWithShadow(s, (float)(i / 2 - this.client.fontRenderer.getStringWidth(s) / 2), (float)(j - 9), 16777215);
|
||||||
|
- j += 10 + this.client.fontRenderer.FONT_HEIGHT;
|
||||||
|
+ }
|
||||||
|
+ j += event.getIncrement();
|
||||||
|
+ net.minecraftforge.client.ForgeHooksClient.bossBarRenderPost(this.client.field_195558_d);
|
||||||
|
if (j >= this.client.field_195558_d.func_198087_p() / 3) {
|
||||||
|
break;
|
||||||
|
}
|
|
@ -9,3 +9,24 @@
|
||||||
private static final DataParameter<Float> ABSORPTION = EntityDataManager.<Float>createKey(EntityPlayer.class, DataSerializers.FLOAT);
|
private static final DataParameter<Float> ABSORPTION = EntityDataManager.<Float>createKey(EntityPlayer.class, DataSerializers.FLOAT);
|
||||||
private static final DataParameter<Integer> PLAYER_SCORE = EntityDataManager.<Integer>createKey(EntityPlayer.class, DataSerializers.VARINT);
|
private static final DataParameter<Integer> PLAYER_SCORE = EntityDataManager.<Integer>createKey(EntityPlayer.class, DataSerializers.VARINT);
|
||||||
protected static final DataParameter<Byte> PLAYER_MODEL_FLAG = EntityDataManager.<Byte>createKey(EntityPlayer.class, DataSerializers.BYTE);
|
protected static final DataParameter<Byte> PLAYER_MODEL_FLAG = EntityDataManager.<Byte>createKey(EntityPlayer.class, DataSerializers.BYTE);
|
||||||
|
@@ -663,7 +665,12 @@
|
||||||
|
return p_184816_1_.getItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
+ @Deprecated //Use location sensitive version below
|
||||||
|
public float getDigSpeed(IBlockState state) {
|
||||||
|
+ return getDigSpeed(state, null);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public float getDigSpeed(IBlockState state, @Nullable BlockPos pos) {
|
||||||
|
float f = this.inventory.getDestroySpeed(state);
|
||||||
|
if (f > 1.0F) {
|
||||||
|
int i = EnchantmentHelper.getEfficiencyModifier(this);
|
||||||
|
@@ -705,6 +712,7 @@
|
||||||
|
f /= 5.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ f = net.minecraftforge.event.ForgeEventFactory.getBreakSpeed(this, state, f, pos);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@
|
||||||
ItemGroup itemgroup = this.getCreativeTab();
|
ItemGroup itemgroup = this.getCreativeTab();
|
||||||
return itemgroup != null && (targetTab == ItemGroup.SEARCH || targetTab == itemgroup);
|
return itemgroup != null && (targetTab == ItemGroup.SEARCH || targetTab == itemgroup);
|
||||||
}
|
}
|
||||||
@@ -310,10 +318,49 @@
|
@@ -310,10 +318,48 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@
|
||||||
+ @Nullable
|
+ @Nullable
|
||||||
+ private final java.util.function.Supplier<net.minecraft.client.renderer.tileentity.TileEntityItemStackRenderer> teisr;
|
+ private final java.util.function.Supplier<net.minecraft.client.renderer.tileentity.TileEntityItemStackRenderer> teisr;
|
||||||
+
|
+
|
||||||
+ private final java.util.Map<String, Integer> toolClasses = new java.util.HashMap<String, Integer>();
|
+ private final java.util.Map<net.minecraftforge.common.ToolType, Integer> toolClasses = Maps.newHashMap();
|
||||||
+
|
+
|
||||||
+ protected final boolean canRepair;
|
+ protected final boolean canRepair;
|
||||||
+
|
+
|
||||||
|
@ -98,16 +98,15 @@
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ @Override
|
+ @Override
|
||||||
+ public java.util.Set<String> getToolClasses(ItemStack stack)
|
+ public java.util.Set<net.minecraftforge.common.ToolType> getToolTypes(ItemStack stack)
|
||||||
+ {
|
+ {
|
||||||
+ return toolClasses.keySet();
|
+ return toolClasses.keySet();
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ @Override
|
+ @Override
|
||||||
+ public int getHarvestLevel(ItemStack stack, String toolClass, @Nullable EntityPlayer player, @Nullable IBlockState blockState)
|
+ public int getHarvestLevel(ItemStack stack, net.minecraftforge.common.ToolType tool, @Nullable EntityPlayer player, @Nullable IBlockState blockState)
|
||||||
+ {
|
+ {
|
||||||
+ Integer ret = toolClasses.get(toolClass);
|
+ return toolClasses.getOrDefault(tool, -1);
|
||||||
+ return ret == null ? -1 : ret;
|
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ @OnlyIn(Dist.CLIENT)
|
+ @OnlyIn(Dist.CLIENT)
|
||||||
|
@ -123,24 +122,34 @@
|
||||||
public static void registerItems() {
|
public static void registerItems() {
|
||||||
registerItemBlock(Blocks.AIR, new ItemAir(Blocks.AIR, new Item.Builder()));
|
registerItemBlock(Blocks.AIR, new ItemAir(Blocks.AIR, new Item.Builder()));
|
||||||
func_200879_a(Blocks.STONE, ItemGroup.BUILDING_BLOCKS);
|
func_200879_a(Blocks.STONE, ItemGroup.BUILDING_BLOCKS);
|
||||||
@@ -1147,6 +1194,9 @@
|
@@ -1147,6 +1193,9 @@
|
||||||
private Item field_200922_c;
|
private Item field_200922_c;
|
||||||
private ItemGroup field_200923_d;
|
private ItemGroup field_200923_d;
|
||||||
private EnumRarity field_208104_e = EnumRarity.COMMON;
|
private EnumRarity field_208104_e = EnumRarity.COMMON;
|
||||||
+ private boolean canRepair = true;
|
+ private boolean canRepair = true;
|
||||||
+ private java.util.Map<String, Integer> toolClasses = new java.util.HashMap<String, Integer>();
|
+ private java.util.Map<net.minecraftforge.common.ToolType, Integer> toolClasses = Maps.newHashMap();
|
||||||
+ private java.util.function.Supplier<java.util.concurrent.Callable<net.minecraft.client.renderer.tileentity.TileEntityItemStackRenderer>> teisr;
|
+ private java.util.function.Supplier<java.util.concurrent.Callable<net.minecraft.client.renderer.tileentity.TileEntityItemStackRenderer>> teisr;
|
||||||
|
|
||||||
public Item.Builder func_200917_a(int p_200917_1_) {
|
public Item.Builder func_200917_a(int p_200917_1_) {
|
||||||
if (this.field_200921_b > 0) {
|
if (this.field_200921_b > 0) {
|
||||||
@@ -1181,5 +1231,10 @@
|
@@ -1181,5 +1230,20 @@
|
||||||
this.field_208104_e = p_208103_1_;
|
this.field_208104_e = p_208103_1_;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
+
|
+
|
||||||
+ public Item.Builder setNoRepair() {
|
+ public Item.Builder setNoRepair() {
|
||||||
+ canRepair = false;
|
+ canRepair = false;
|
||||||
+ return this;
|
+ return this;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public Item.Builder addToolType(net.minecraftforge.common.ToolType type, int level) {
|
||||||
|
+ toolClasses.put(type, level);
|
||||||
|
+ return this;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public Item.Builder setTEISR(java.util.function.Supplier<java.util.concurrent.Callable<net.minecraft.client.renderer.tileentity.TileEntityItemStackRenderer>> teisr) {
|
||||||
|
+ this.teisr = teisr;
|
||||||
|
+ return this;
|
||||||
+ }
|
+ }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
25
patches/minecraft/net/minecraft/item/ItemPickaxe.java.patch
Normal file
25
patches/minecraft/net/minecraft/item/ItemPickaxe.java.patch
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
--- a/net/minecraft/item/ItemPickaxe.java
|
||||||
|
+++ b/net/minecraft/item/ItemPickaxe.java
|
||||||
|
@@ -17,18 +17,11 @@
|
||||||
|
public boolean canHarvestBlock(IBlockState blockIn) {
|
||||||
|
Block block = blockIn.getBlock();
|
||||||
|
int i = this.func_200891_e().func_200925_d();
|
||||||
|
- if (block == Blocks.OBSIDIAN) {
|
||||||
|
- return i == 3;
|
||||||
|
- } else if (block != Blocks.DIAMOND_BLOCK && block != Blocks.DIAMOND_ORE && block != Blocks.EMERALD_ORE && block != Blocks.EMERALD_BLOCK && block != Blocks.GOLD_BLOCK && block != Blocks.GOLD_ORE && block != Blocks.REDSTONE_ORE) {
|
||||||
|
- if (block != Blocks.IRON_BLOCK && block != Blocks.IRON_ORE && block != Blocks.LAPIS_BLOCK && block != Blocks.LAPIS_ORE) {
|
||||||
|
- Material material = blockIn.getMaterial();
|
||||||
|
- return material == Material.ROCK || material == Material.IRON || material == Material.ANVIL;
|
||||||
|
- } else {
|
||||||
|
- return i >= 1;
|
||||||
|
- }
|
||||||
|
- } else {
|
||||||
|
- return i >= 2;
|
||||||
|
+ if (blockIn.getHarvestTool() == net.minecraftforge.common.ToolType.PICKAXE) {
|
||||||
|
+ return i >= blockIn.getHarvestLevel();
|
||||||
|
}
|
||||||
|
+ Material material = blockIn.getMaterial();
|
||||||
|
+ return material == Material.ROCK || material == Material.IRON || material == Material.ANVIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getDestroySpeed(ItemStack stack, IBlockState state) {
|
|
@ -5,7 +5,7 @@
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
-public final class ItemStack {
|
-public final class ItemStack {
|
||||||
+public final class ItemStack extends net.minecraftforge.common.capabilities.CapabilityProvider implements net.minecraftforge.common.capabilities.ICapabilitySerializable<NBTTagCompound>, net.minecraftforge.common.extensions.IForgeItemStack {
|
+public final class ItemStack extends net.minecraftforge.common.capabilities.CapabilityProvider implements net.minecraftforge.common.extensions.IForgeItemStack {
|
||||||
private static final Logger field_199558_c = LogManager.getLogger();
|
private static final Logger field_199558_c = LogManager.getLogger();
|
||||||
public static final ItemStack EMPTY = new ItemStack((Item)null);
|
public static final ItemStack EMPTY = new ItemStack((Item)null);
|
||||||
public static final DecimalFormat DECIMALFORMAT = func_208306_D();
|
public static final DecimalFormat DECIMALFORMAT = func_208306_D();
|
||||||
|
@ -68,7 +68,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public EnumActionResult func_196084_a(ItemUseContext p_196084_1_) {
|
public EnumActionResult func_196084_a(ItemUseContext p_196084_1_) {
|
||||||
+ if (!p_196084_1_.field_196006_g.isRemote) return net.minecraftforge.common.ForgeHooks.onPlaceItemIntoWorld(p_196084_1_);
|
+ //if (!p_196084_1_.field_196006_g.isRemote) return net.minecraftforge.common.ForgeHooks.onPlaceItemIntoWorld(p_196084_1_);
|
||||||
EntityPlayer entityplayer = p_196084_1_.func_195999_j();
|
EntityPlayer entityplayer = p_196084_1_.func_195999_j();
|
||||||
BlockPos blockpos = p_196084_1_.func_195995_a();
|
BlockPos blockpos = p_196084_1_.func_195995_a();
|
||||||
BlockWorldState blockworldstate = new BlockWorldState(p_196084_1_.func_195991_k(), blockpos, false);
|
BlockWorldState blockworldstate = new BlockWorldState(p_196084_1_.func_195991_k(), blockpos, false);
|
||||||
|
@ -153,7 +153,7 @@
|
||||||
|
|
||||||
public boolean canHarvestBlock(IBlockState blockIn) {
|
public boolean canHarvestBlock(IBlockState blockIn) {
|
||||||
- return this.getItem().canHarvestBlock(blockIn);
|
- return this.getItem().canHarvestBlock(blockIn);
|
||||||
+ return this.getItem().canHarvestBlock(blockIn, this);
|
+ return this.getItem().canHarvestBlock(this, blockIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean interactWithEntity(EntityPlayer playerIn, EntityLivingBase entityIn, EnumHand hand) {
|
public boolean interactWithEntity(EntityPlayer playerIn, EntityLivingBase entityIn, EnumHand hand) {
|
||||||
|
|
|
@ -9,6 +9,17 @@
|
||||||
|
|
||||||
public class BannerDuplicateRecipe extends IRecipeHidden {
|
public class BannerDuplicateRecipe extends IRecipeHidden {
|
||||||
public BannerDuplicateRecipe(ResourceLocation p_i48171_1_) {
|
public BannerDuplicateRecipe(ResourceLocation p_i48171_1_) {
|
||||||
|
@@ -77,8 +75,8 @@
|
||||||
|
for(int i = 0; i < nonnulllist.size(); ++i) {
|
||||||
|
ItemStack itemstack = inv.getStackInSlot(i);
|
||||||
|
if (!itemstack.isEmpty()) {
|
||||||
|
- if (itemstack.getItem().hasContainerItem()) {
|
||||||
|
- nonnulllist.set(i, new ItemStack(itemstack.getItem().getContainerItem()));
|
||||||
|
+ if (itemstack.hasContainerItem()) {
|
||||||
|
+ nonnulllist.set(i, itemstack.getContainerItem());
|
||||||
|
} else if (itemstack.hasTagCompound() && TileEntityBanner.getPatterns(itemstack) > 0) {
|
||||||
|
ItemStack itemstack1 = itemstack.copy();
|
||||||
|
itemstack1.setCount(1);
|
||||||
@@ -94,7 +92,6 @@
|
@@ -94,7 +92,6 @@
|
||||||
return RecipeSerializers.field_199586_l;
|
return RecipeSerializers.field_199586_l;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
--- a/net/minecraft/network/ServerStatusResponse.java
|
||||||
|
+++ b/net/minecraft/network/ServerStatusResponse.java
|
||||||
|
@@ -26,6 +26,7 @@
|
||||||
|
|
||||||
|
public void setServerDescription(ITextComponent descriptionIn) {
|
||||||
|
this.description = descriptionIn;
|
||||||
|
+ invalidateJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerStatusResponse.Players getPlayers() {
|
||||||
|
@@ -34,6 +35,7 @@
|
||||||
|
|
||||||
|
public void setPlayers(ServerStatusResponse.Players playersIn) {
|
||||||
|
this.players = playersIn;
|
||||||
|
+ invalidateJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerStatusResponse.Version getVersion() {
|
||||||
|
@@ -42,16 +44,51 @@
|
||||||
|
|
||||||
|
public void setVersion(ServerStatusResponse.Version versionIn) {
|
||||||
|
this.version = versionIn;
|
||||||
|
+ invalidateJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFavicon(String faviconBlob) {
|
||||||
|
this.favicon = faviconBlob;
|
||||||
|
+ invalidateJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFavicon() {
|
||||||
|
return this.favicon;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ private java.util.concurrent.Semaphore mutex = new java.util.concurrent.Semaphore(1);
|
||||||
|
+ private String json = null;
|
||||||
|
+ /**
|
||||||
|
+ * Returns this object as a Json string.
|
||||||
|
+ * Converting to JSON if a cached version is not available.
|
||||||
|
+ *
|
||||||
|
+ * Also to prevent potentially large memory allocations on the server
|
||||||
|
+ * this is moved from the SPacketServerInfo writePacket function
|
||||||
|
+ *
|
||||||
|
+ * As this method is called from the network threads so thread safety is important!
|
||||||
|
+ */
|
||||||
|
+ public String getJson() {
|
||||||
|
+ String ret = this.json;
|
||||||
|
+ if (ret == null) {
|
||||||
|
+ mutex.acquireUninterruptibly();
|
||||||
|
+ ret = this.json;
|
||||||
|
+ if (ret == null) {
|
||||||
|
+ ret = net.minecraft.network.status.server.SPacketServerInfo.GSON.toJson(this);
|
||||||
|
+ this.json = ret;
|
||||||
|
+ }
|
||||||
|
+ mutex.release();
|
||||||
|
+ }
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Invalidates the cached json, causing the next call to getJson to rebuild it.
|
||||||
|
+ * This is needed externally because PlayerCountData.setPlayer's is public.
|
||||||
|
+ */
|
||||||
|
+ public void invalidateJson() {
|
||||||
|
+ this.json = null;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
public static class Players {
|
||||||
|
private final int maxPlayers;
|
||||||
|
private final int onlinePlayerCount;
|
|
@ -0,0 +1,11 @@
|
||||||
|
--- a/net/minecraft/network/status/server/SPacketServerInfo.java
|
||||||
|
+++ b/net/minecraft/network/status/server/SPacketServerInfo.java
|
||||||
|
@@ -30,7 +30,7 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writePacketData(PacketBuffer buf) throws IOException {
|
||||||
|
- buf.writeString(GSON.toJson(this.response));
|
||||||
|
+ buf.writeString(this.response.getJson()); //Forge: Let the response cache the JSON
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processPacket(INetHandlerStatusClient handler) {
|
|
@ -1,34 +1,67 @@
|
||||||
--- a/net/minecraft/server/MinecraftServer.java
|
--- a/net/minecraft/server/MinecraftServer.java
|
||||||
+++ b/net/minecraft/server/MinecraftServer.java
|
+++ b/net/minecraft/server/MinecraftServer.java
|
||||||
@@ -130,7 +130,7 @@
|
@@ -148,7 +148,6 @@
|
||||||
private final DataFixer dataFixer;
|
|
||||||
private String hostname;
|
|
||||||
private int serverPort = -1;
|
|
||||||
- public WorldServer[] worlds;
|
|
||||||
+ public WorldServer[] worlds = new WorldServer[0];
|
|
||||||
private PlayerList playerList;
|
|
||||||
private boolean serverRunning = true;
|
|
||||||
private boolean serverStopped;
|
|
||||||
@@ -148,7 +148,8 @@
|
|
||||||
private int buildLimit;
|
private int buildLimit;
|
||||||
private int maxPlayerIdleMinutes;
|
private int maxPlayerIdleMinutes;
|
||||||
public final long[] tickTimeArray = new long[100];
|
public final long[] tickTimeArray = new long[100];
|
||||||
- public long[][] timeOfLastDimensionTick;
|
- public long[][] timeOfLastDimensionTick;
|
||||||
+ //public long[][] timeOfLastDimensionTick;
|
|
||||||
+ public java.util.Hashtable<Integer, long[]> worldTickTimes = new java.util.Hashtable<Integer, long[]>();
|
|
||||||
private KeyPair serverKeyPair;
|
private KeyPair serverKeyPair;
|
||||||
private String serverOwner;
|
private String serverOwner;
|
||||||
private String folderName;
|
private String folderName;
|
||||||
@@ -287,8 +288,6 @@
|
@@ -287,8 +286,7 @@
|
||||||
public void loadAllWorlds(String saveName, String worldNameIn, long seed, WorldType type, JsonElement generatorOptions) {
|
public void loadAllWorlds(String saveName, String worldNameIn, long seed, WorldType type, JsonElement generatorOptions) {
|
||||||
this.convertMapIfNeeded(saveName);
|
this.convertMapIfNeeded(saveName);
|
||||||
this.func_200245_b(new TextComponentTranslation("menu.loadingLevel", new Object[0]));
|
this.func_200245_b(new TextComponentTranslation("menu.loadingLevel", new Object[0]));
|
||||||
- this.worlds = new WorldServer[3];
|
- this.worlds = new WorldServer[3];
|
||||||
- this.timeOfLastDimensionTick = new long[this.worlds.length][100];
|
- this.timeOfLastDimensionTick = new long[this.worlds.length][100];
|
||||||
|
+ this.worlds = new WorldServer[1]; //Forge only initialize overworld, we will do the rest.
|
||||||
ISaveHandler isavehandler = this.anvilConverterForAnvilFile.func_197715_a(saveName, this);
|
ISaveHandler isavehandler = this.anvilConverterForAnvilFile.func_197715_a(saveName, this);
|
||||||
this.setResourcePackFromWorld(this.getFolderName(), isavehandler);
|
this.setResourcePackFromWorld(this.getFolderName(), isavehandler);
|
||||||
WorldInfo worldinfo = isavehandler.loadWorldInfo();
|
WorldInfo worldinfo = isavehandler.loadWorldInfo();
|
||||||
@@ -523,6 +522,7 @@
|
@@ -340,6 +338,18 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ for (int dim : net.minecraftforge.common.DimensionManager.getStaticDimensionIDs()) {
|
||||||
|
+ WorldServer world = this.worlds[0];
|
||||||
|
+ if (dim != 0) {
|
||||||
|
+ world = (WorldServer)(new WorldServerMulti(this, isavehandler, dim, this.worlds[0], this.profiler).init());
|
||||||
|
+ world.addEventListener(new ServerWorldEventHandler(this, world));
|
||||||
|
+ if (!this.isSinglePlayer()) {
|
||||||
|
+ world.getWorldInfo().setGameType(getGameType());
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Load(world));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
this.playerList.setPlayerManager(this.worlds);
|
||||||
|
if (worldinfo.func_201357_P() != null) {
|
||||||
|
this.func_201300_aS().func_201381_a(worldinfo.func_201357_P());
|
||||||
|
@@ -378,7 +388,7 @@
|
||||||
|
this.func_200245_b(new TextComponentTranslation("menu.generatingTerrain", new Object[0]));
|
||||||
|
int j1 = 0;
|
||||||
|
LOGGER.info("Preparing start region for level 0");
|
||||||
|
- WorldServer worldserver = this.worlds[0];
|
||||||
|
+ WorldServer worldserver = getWorld(0);
|
||||||
|
BlockPos blockpos = worldserver.getSpawnPoint();
|
||||||
|
List<ChunkPos> list = Lists.<ChunkPos>newArrayList();
|
||||||
|
Set<ChunkPos> set = Sets.<ChunkPos>newConcurrentHashSet();
|
||||||
|
@@ -493,9 +503,14 @@
|
||||||
|
|
||||||
|
for(WorldServer worldserver1 : this.worlds) {
|
||||||
|
if (worldserver1 != null) {
|
||||||
|
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Unload(worldserver1));
|
||||||
|
worldserver1.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ WorldServer[] tmp = this.worlds;
|
||||||
|
+ for (WorldServer world : tmp)
|
||||||
|
+ net.minecraftforge.common.DimensionManager.setWorld(world.provider.getId(), null, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.usageSnooper.isSnooperRunning()) {
|
||||||
|
@@ -523,6 +538,7 @@
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
if (this.init()) {
|
if (this.init()) {
|
||||||
|
@ -36,7 +69,7 @@
|
||||||
this.field_211151_aa = Util.func_211177_b();
|
this.field_211151_aa = Util.func_211177_b();
|
||||||
this.statusResponse.setServerDescription(new TextComponentString(this.motd));
|
this.statusResponse.setServerDescription(new TextComponentString(this.motd));
|
||||||
this.statusResponse.setVersion(new ServerStatusResponse.Version("1.13", 393));
|
this.statusResponse.setVersion(new ServerStatusResponse.Version("1.13", 393));
|
||||||
@@ -546,7 +546,10 @@
|
@@ -546,7 +562,10 @@
|
||||||
|
|
||||||
this.serverIsRunning = true;
|
this.serverIsRunning = true;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +80,7 @@
|
||||||
this.finalTick((CrashReport)null);
|
this.finalTick((CrashReport)null);
|
||||||
}
|
}
|
||||||
} catch (Throwable throwable1) {
|
} catch (Throwable throwable1) {
|
||||||
@@ -565,6 +568,7 @@
|
@@ -565,6 +584,7 @@
|
||||||
LOGGER.error("We were unable to save this crash report to disk.");
|
LOGGER.error("We were unable to save this crash report to disk.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +88,7 @@
|
||||||
this.finalTick(crashreport);
|
this.finalTick(crashreport);
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
@@ -573,6 +577,7 @@
|
@@ -573,6 +593,7 @@
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
LOGGER.error("Exception stopping the server", throwable);
|
LOGGER.error("Exception stopping the server", throwable);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -63,7 +96,15 @@
|
||||||
this.systemExitNow();
|
this.systemExitNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -686,10 +691,12 @@
|
@@ -648,6 +669,7 @@
|
||||||
|
|
||||||
|
Collections.shuffle(Arrays.asList(agameprofile));
|
||||||
|
this.statusResponse.getPlayers().setPlayers(agameprofile);
|
||||||
|
+ this.statusResponse.invalidateJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.tickCounter % 900 == 0) {
|
||||||
|
@@ -686,16 +708,18 @@
|
||||||
this.getFunctionManager().update();
|
this.getFunctionManager().update();
|
||||||
this.profiler.endStartSection("levels");
|
this.profiler.endStartSection("levels");
|
||||||
|
|
||||||
|
@ -74,17 +115,74 @@
|
||||||
long j = Util.func_211178_c();
|
long j = Util.func_211178_c();
|
||||||
- if (i == 0 || this.getAllowNether()) {
|
- if (i == 0 || this.getAllowNether()) {
|
||||||
- WorldServer worldserver = this.worlds[i];
|
- WorldServer worldserver = this.worlds[i];
|
||||||
|
+ WorldServer worldserver = getWorld(id);
|
||||||
+ if (id == 0 || this.getAllowNether()) {
|
+ if (id == 0 || this.getAllowNether()) {
|
||||||
+ WorldServer worldserver = net.minecraftforge.common.DimensionManager.getWorld(id);
|
|
||||||
this.profiler.func_194340_a(() -> {
|
this.profiler.func_194340_a(() -> {
|
||||||
return worldserver.getWorldInfo().getWorldName();
|
return worldserver.getWorldInfo().getWorldName();
|
||||||
});
|
});
|
||||||
@@ -724,7 +731,7 @@
|
if (this.tickCounter % 20 == 0) {
|
||||||
|
this.profiler.startSection("timeSync");
|
||||||
|
- this.playerList.sendPacketToAllPlayersInDimension(new SPacketTimeUpdate(worldserver.getTotalWorldTime(), worldserver.getWorldTime(), worldserver.getGameRules().getBoolean("doDaylightCycle")), worldserver.provider.getDimensionType().getId());
|
||||||
|
+ this.playerList.sendPacketToAllPlayersInDimension(new SPacketTimeUpdate(worldserver.getTotalWorldTime(), worldserver.getWorldTime(), worldserver.getGameRules().getBoolean("doDaylightCycle")), worldserver.provider.getId());
|
||||||
|
this.profiler.endSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -724,9 +748,11 @@
|
||||||
this.profiler.endSection();
|
this.profiler.endSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
- this.timeOfLastDimensionTick[i][this.tickCounter % 100] = Util.func_211178_c() - j;
|
- this.timeOfLastDimensionTick[i][this.tickCounter % 100] = Util.func_211178_c() - j;
|
||||||
+ worldTickTimes.get(id)[this.tickCounter % 100] = Util.func_211178_c() - j;
|
+ worldserver.setTickTime(this.tickCounter, Util.func_211178_c() - j);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ this.profiler.endStartSection("dim_unloading");
|
||||||
|
+ net.minecraftforge.common.DimensionManager.unloadWorlds();
|
||||||
this.profiler.endStartSection("connection");
|
this.profiler.endStartSection("connection");
|
||||||
|
this.getNetworkSystem().networkTick();
|
||||||
|
this.profiler.endStartSection("players");
|
||||||
|
@@ -749,6 +775,14 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] p_main_0_) {
|
||||||
|
+ //Forge: Copied from DedicatedServer.init as to run as early as possible, Old code left in place intentionally.
|
||||||
|
+ //Done in good faith with permission: https://github.com/MinecraftForge/MinecraftForge/issues/3659#issuecomment-390467028
|
||||||
|
+ ServerEula eula = new ServerEula(new File("eula.txt"));
|
||||||
|
+ if (!eula.hasAcceptedEULA()) {
|
||||||
|
+ LOGGER.info("You need to agree to the EULA in order to run the server. Go to eula.txt for more info.");
|
||||||
|
+ eula.createEULAFile();
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
Bootstrap.register();
|
||||||
|
|
||||||
|
try {
|
||||||
|
@@ -851,7 +885,7 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startServerThread() {
|
||||||
|
- this.serverThread = new Thread(this, "Server thread");
|
||||||
|
+ this.serverThread = new Thread(net.minecraftforge.fml.common.thread.SidedThreadGroups.SERVER, this, "Server thread");
|
||||||
|
this.serverThread.setUncaughtExceptionHandler((p_195574_0_, p_195574_1_) -> {
|
||||||
|
LOGGER.error(p_195574_1_);
|
||||||
|
});
|
||||||
|
@@ -871,11 +905,7 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
public WorldServer getWorld(int dimension) {
|
||||||
|
- if (dimension == -1) {
|
||||||
|
- return this.worlds[1];
|
||||||
|
- } else {
|
||||||
|
- return dimension == 1 ? this.worlds[2] : this.worlds[0];
|
||||||
|
- }
|
||||||
|
+ return net.minecraftforge.common.DimensionManager.getWorld(dimension, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WorldServer func_200667_a(DimensionType p_200667_1_) {
|
||||||
|
@@ -918,7 +948,7 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerModName() {
|
||||||
|
- return "vanilla";
|
||||||
|
+ return net.minecraftforge.common.ForgeHooks.getServerModName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CrashReport addServerInfoToCrashReport(CrashReport report) {
|
||||||
|
|
|
@ -1,6 +1,35 @@
|
||||||
--- a/net/minecraft/server/integrated/IntegratedServer.java
|
--- a/net/minecraft/server/integrated/IntegratedServer.java
|
||||||
+++ b/net/minecraft/server/integrated/IntegratedServer.java
|
+++ b/net/minecraft/server/integrated/IntegratedServer.java
|
||||||
@@ -121,9 +121,10 @@
|
@@ -62,8 +62,7 @@
|
||||||
|
|
||||||
|
public void loadAllWorlds(String saveName, String worldNameIn, long seed, WorldType type, JsonElement generatorOptions) {
|
||||||
|
this.convertMapIfNeeded(saveName);
|
||||||
|
- this.worlds = new WorldServer[3];
|
||||||
|
- this.timeOfLastDimensionTick = new long[this.worlds.length][100];
|
||||||
|
+ this.worlds = new WorldServer[1]; //Forge only initialize overworld, we will do the rest.
|
||||||
|
ISaveHandler isavehandler = this.getActiveAnvilConverter().func_197715_a(saveName, this);
|
||||||
|
this.setResourcePackFromWorld(this.getFolderName(), isavehandler);
|
||||||
|
WorldInfo worldinfo = isavehandler.loadWorldInfo();
|
||||||
|
@@ -100,6 +99,18 @@
|
||||||
|
this.worlds[i].addEventListener(new ServerWorldEventHandler(this, this.worlds[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
+ for (int dim : net.minecraftforge.common.DimensionManager.getStaticDimensionIDs()) {
|
||||||
|
+ WorldServer world = this.worlds[0];
|
||||||
|
+ if (dim != 0) {
|
||||||
|
+ world = (WorldServer)(new WorldServerMulti(this, isavehandler, dim, this.worlds[0], this.profiler).init());
|
||||||
|
+ world.addEventListener(new ServerWorldEventHandler(this, world));
|
||||||
|
+ if (!this.isSinglePlayer()) {
|
||||||
|
+ world.getWorldInfo().setGameType(getGameType());
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Load(world));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
this.getPlayerList().setPlayerManager(this.worlds);
|
||||||
|
if (worldinfo.func_201357_P() != null) {
|
||||||
|
this.func_201300_aS().func_201381_a(worldinfo.func_201357_P());
|
||||||
|
@@ -121,9 +132,10 @@
|
||||||
this.setAllowFlight(true);
|
this.setAllowFlight(true);
|
||||||
LOGGER.info("Generating keypair");
|
LOGGER.info("Generating keypair");
|
||||||
this.setKeyPair(CryptManager.generateKeyPair());
|
this.setKeyPair(CryptManager.generateKeyPair());
|
||||||
|
@ -12,3 +41,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void tick() {
|
public void tick() {
|
||||||
|
@@ -176,6 +188,7 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
public EnumDifficulty getDifficulty() {
|
||||||
|
+ if (this.mc.world == null) return this.mc.gameSettings.difficulty; // Fix NPE just in case.
|
||||||
|
return this.mc.world.getWorldInfo().getDifficulty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -275,6 +288,7 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initiateShutdown() {
|
||||||
|
+ if (isServerRunning())
|
||||||
|
Futures.getUnchecked(this.addScheduledTask(() -> {
|
||||||
|
for(EntityPlayerMP entityplayermp : Lists.newArrayList(this.getPlayerList().getPlayers())) {
|
||||||
|
if (!entityplayermp.getUniqueID().equals(this.field_211528_n)) {
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
--- a/net/minecraft/tileentity/TileEntityFurnace.java
|
||||||
|
+++ b/net/minecraft/tileentity/TileEntityFurnace.java
|
||||||
|
@@ -185,9 +185,9 @@
|
||||||
|
super.readFromNBT(compound);
|
||||||
|
this.furnaceItemStacks = NonNullList.<ItemStack>withSize(this.getSizeInventory(), ItemStack.EMPTY);
|
||||||
|
ItemStackHelper.loadAllItems(compound, this.furnaceItemStacks);
|
||||||
|
- this.furnaceBurnTime = compound.getShort("BurnTime");
|
||||||
|
- this.cookTime = compound.getShort("CookTime");
|
||||||
|
- this.totalCookTime = compound.getShort("CookTimeTotal");
|
||||||
|
+ this.furnaceBurnTime = compound.getInteger("BurnTime");
|
||||||
|
+ this.cookTime = compound.getInteger("CookTime");
|
||||||
|
+ this.totalCookTime = compound.getInteger("CookTimeTotal");
|
||||||
|
this.currentItemBurnTime = getItemBurnTime(this.furnaceItemStacks.get(1));
|
||||||
|
int i = compound.getShort("RecipesUsedSize");
|
||||||
|
|
||||||
|
@@ -205,9 +205,9 @@
|
||||||
|
|
||||||
|
public NBTTagCompound writeToNBT(NBTTagCompound compound) {
|
||||||
|
super.writeToNBT(compound);
|
||||||
|
- compound.setShort("BurnTime", (short)this.furnaceBurnTime);
|
||||||
|
- compound.setShort("CookTime", (short)this.cookTime);
|
||||||
|
- compound.setShort("CookTimeTotal", (short)this.totalCookTime);
|
||||||
|
+ compound.setInteger("BurnTime", this.furnaceBurnTime);
|
||||||
|
+ compound.setInteger("CookTime", this.cookTime);
|
||||||
|
+ compound.setInteger("CookTimeTotal", this.totalCookTime);
|
||||||
|
ItemStackHelper.saveAllItems(compound, this.furnaceItemStacks);
|
||||||
|
compound.setShort("RecipesUsedSize", (short)this.field_203901_m.size());
|
||||||
|
int i = 0;
|
||||||
|
@@ -254,6 +254,10 @@
|
||||||
|
this.currentItemBurnTime = this.furnaceBurnTime;
|
||||||
|
if (this.isBurning()) {
|
||||||
|
flag1 = true;
|
||||||
|
+ if (itemstack.hasContainerItem()) {
|
||||||
|
+ this.furnaceItemStacks.set(1, itemstack.getContainerItem());
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
if (!itemstack.isEmpty()) {
|
||||||
|
Item item = itemstack.getItem();
|
||||||
|
itemstack.shrink(1);
|
||||||
|
@@ -308,10 +312,10 @@
|
||||||
|
return true;
|
||||||
|
} else if (!itemstack1.isItemEqual(itemstack)) {
|
||||||
|
return false;
|
||||||
|
- } else if (itemstack1.getCount() < this.getInventoryStackLimit() && itemstack1.getCount() < itemstack1.getMaxStackSize()) {
|
||||||
|
+ } else if (itemstack1.getCount() + itemstack.getCount() <= this.getInventoryStackLimit() && itemstack1.getCount() < itemstack1.getMaxStackSize()) { // Forge fix: make furnace respect stack sizes in furnace recipes
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
- return itemstack1.getCount() < itemstack.getMaxStackSize();
|
||||||
|
+ return itemstack1.getCount() + itemstack.getCount() <= itemstack.getMaxStackSize(); // Forge fix: make furnace respect stack sizes in furnace recipes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
@@ -327,7 +331,7 @@
|
||||||
|
if (itemstack2.isEmpty()) {
|
||||||
|
this.furnaceItemStacks.set(2, itemstack1.copy());
|
||||||
|
} else if (itemstack2.getItem() == itemstack1.getItem()) {
|
||||||
|
- itemstack2.grow(1);
|
||||||
|
+ itemstack2.grow(itemstack1.getCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.world.isRemote) {
|
||||||
|
@@ -347,12 +351,13 @@
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
Item item = stack.getItem();
|
||||||
|
- return func_201564_p().getOrDefault(item, 0);
|
||||||
|
+ int ret = stack.getBurnTime();
|
||||||
|
+ return net.minecraftforge.event.ForgeEventFactory.getItemBurnTime(stack, ret == -1 ? func_201564_p().getOrDefault(item, 0) : ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isItemFuel(ItemStack stack) {
|
||||||
|
- return func_201564_p().containsKey(stack.getItem());
|
||||||
|
+ return getItemBurnTime(stack) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUsableByPlayer(EntityPlayer player) {
|
||||||
|
@@ -501,4 +506,27 @@
|
||||||
|
|
||||||
|
this.field_203901_m.clear();
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ net.minecraftforge.common.capabilities.OptionalCapabilityInstance<? extends net.minecraftforge.items.IItemHandler>[] handlers =
|
||||||
|
+ net.minecraftforge.items.wrapper.SidedInvWrapper.create(this, EnumFacing.UP, EnumFacing.DOWN, EnumFacing.NORTH);
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public <T> net.minecraftforge.common.capabilities.OptionalCapabilityInstance<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable EnumFacing facing) {
|
||||||
|
+ if (facing != null && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
|
||||||
|
+ if (facing == EnumFacing.UP)
|
||||||
|
+ return handlers[0].cast();
|
||||||
|
+ else if (facing == EnumFacing.UP)
|
||||||
|
+ return handlers[1].cast();
|
||||||
|
+ else
|
||||||
|
+ return handlers[2].cast();
|
||||||
|
+ }
|
||||||
|
+ return super.getCapability(capability, facing);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void invalidate() {
|
||||||
|
+ super.invalidate();
|
||||||
|
+ for (int x = 0; x < handlers.length; x++)
|
||||||
|
+ handlers[x].invalidate();
|
||||||
|
+ }
|
||||||
|
}
|
|
@ -17,3 +17,16 @@
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -957,4 +958,12 @@
|
||||||
|
public NetworkTagManager func_205772_D() {
|
||||||
|
return this.server.func_199731_aO();
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ private long[] tickTime = new long[100];
|
||||||
|
+ public void setTickTime(int tick, long time) {
|
||||||
|
+ this.tickTime[tick % 100] = time;
|
||||||
|
+ }
|
||||||
|
+ public long[] getTickTimes() {
|
||||||
|
+ return this.tickTime;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
|
@ -40,9 +40,9 @@ import javax.vecmath.Matrix4f;
|
||||||
import javax.vecmath.Vector3f;
|
import javax.vecmath.Vector3f;
|
||||||
import javax.vecmath.Vector4f;
|
import javax.vecmath.Vector4f;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.GameSettings;
|
import net.minecraft.client.GameSettings;
|
||||||
|
import net.minecraft.client.MainWindow;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.audio.ISound;
|
import net.minecraft.client.audio.ISound;
|
||||||
import net.minecraft.client.audio.SoundHandler;
|
import net.minecraft.client.audio.SoundHandler;
|
||||||
|
@ -138,14 +138,13 @@ import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
import org.lwjgl.opengl.GL11;
|
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
public class ForgeHooksClient
|
public class ForgeHooksClient
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = LogManager.getLogger();
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
|
||||||
//private static final ResourceLocation ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png");
|
//private static final ResourceLocation ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png");
|
||||||
|
|
||||||
public static String getArmorTexture(Entity entity, ItemStack armor, String _default, EntityEquipmentSlot slot, String type)
|
public static String getArmorTexture(Entity entity, ItemStack armor, String _default, EntityEquipmentSlot slot, String type)
|
||||||
|
@ -154,19 +153,6 @@ public class ForgeHooksClient
|
||||||
return result != null ? result : _default;
|
return result != null ? result : _default;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Optifine Helper Functions u.u, these are here specifically for Optifine
|
|
||||||
//Note: When using Optifine, these methods are invoked using reflection, which
|
|
||||||
//incurs a major performance penalty.
|
|
||||||
public static void orientBedCamera(IWorldReader world, BlockPos pos, IBlockState state, Entity entity)
|
|
||||||
{
|
|
||||||
Block block = state.getBlock();
|
|
||||||
|
|
||||||
if (block != null && block.isBed(state, world, pos, entity))
|
|
||||||
{
|
|
||||||
glRotatef((float)(block.getBedDirection(state, world, pos).getHorizontalIndex() * 90), 0.0F, 1.0F, 0.0F);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean onDrawBlockHighlight(RenderGlobal context, EntityPlayer player, RayTraceResult target, int subID, float partialTicks)
|
public static boolean onDrawBlockHighlight(RenderGlobal context, EntityPlayer player, RayTraceResult target, int subID, float partialTicks)
|
||||||
{
|
{
|
||||||
return MinecraftForge.EVENT_BUS.post(new DrawBlockHighlightEvent(context, player, target, subID, partialTicks));
|
return MinecraftForge.EVENT_BUS.post(new DrawBlockHighlightEvent(context, player, target, subID, partialTicks));
|
||||||
|
@ -729,7 +715,7 @@ public class ForgeHooksClient
|
||||||
return new BlockFaceUV(new float[]{ uMin, vMin, uMax, vMax }, angle);
|
return new BlockFaceUV(new float[]{ uMin, vMin, uMax, vMax }, angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RenderGameOverlayEvent.BossInfo bossBarRenderPre(ScaledResolution res, BossInfoClient bossInfo, int x, int y, int increment)
|
public static RenderGameOverlayEvent.BossInfo bossBarRenderPre(MainWindow res, BossInfoClient bossInfo, int x, int y, int increment)
|
||||||
{
|
{
|
||||||
RenderGameOverlayEvent.BossInfo evt = new RenderGameOverlayEvent.BossInfo(new RenderGameOverlayEvent(Animation.getPartialTickTime(), res),
|
RenderGameOverlayEvent.BossInfo evt = new RenderGameOverlayEvent.BossInfo(new RenderGameOverlayEvent(Animation.getPartialTickTime(), res),
|
||||||
BOSSINFO, bossInfo, x, y, increment);
|
BOSSINFO, bossInfo, x, y, increment);
|
||||||
|
@ -737,7 +723,7 @@ public class ForgeHooksClient
|
||||||
return evt;
|
return evt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void bossBarRenderPost(ScaledResolution res)
|
public static void bossBarRenderPost(MainWindow res)
|
||||||
{
|
{
|
||||||
MinecraftForge.EVENT_BUS.post(new RenderGameOverlayEvent.Post(new RenderGameOverlayEvent(Animation.getPartialTickTime(), res), BOSSINFO));
|
MinecraftForge.EVENT_BUS.post(new RenderGameOverlayEvent.Post(new RenderGameOverlayEvent(Animation.getPartialTickTime(), res), BOSSINFO));
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ package net.minecraftforge.client.model.pipeline;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.renderer.BlockModelRenderer;
|
import net.minecraft.client.renderer.BlockModelRenderer;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
@ -113,7 +114,7 @@ public class ForgeBlockModelRenderer extends BlockModelRenderer
|
||||||
quads = model.func_200117_a(state, side, rand);
|
quads = model.func_200117_a(state, side, rand);
|
||||||
if(!quads.isEmpty())
|
if(!quads.isEmpty())
|
||||||
{
|
{
|
||||||
if(!checkSides || state.shouldSideBeRendered(world, pos, side))
|
if(!checkSides || Block.shouldSideBeRendered(state, world, pos, side))
|
||||||
{
|
{
|
||||||
if(empty) lighter.updateBlockInfo();
|
if(empty) lighter.updateBlockInfo();
|
||||||
empty = false;
|
empty = false;
|
||||||
|
|
|
@ -219,13 +219,11 @@ public class DimensionManager
|
||||||
{
|
{
|
||||||
worlds.put(id, world);
|
worlds.put(id, world);
|
||||||
weakWorldMap.put(world, world);
|
weakWorldMap.put(world, world);
|
||||||
server.worldTickTimes.put(id, new long[100]);
|
|
||||||
LOGGER.info(DIMMGR,"Loading dimension {} ({}) ({})", id, world.getWorldInfo().getWorldName(), world.getMinecraftServer());
|
LOGGER.info(DIMMGR,"Loading dimension {} ({}) ({})", id, world.getWorldInfo().getWorldName(), world.getMinecraftServer());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
worlds.remove(id);
|
worlds.remove(id);
|
||||||
server.worldTickTimes.remove(id);
|
|
||||||
LOGGER.info(DIMMGR,"Unloading dimension {}", id);
|
LOGGER.info(DIMMGR,"Unloading dimension {}", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,12 +285,23 @@ public class DimensionManager
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WorldServer getWorld(int id, boolean resetUnloadDelay)
|
public static WorldServer getWorld(int id, boolean resetUnloadDelay)
|
||||||
|
{
|
||||||
|
return getWorld(id, resetUnloadDelay, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static WorldServer getWorld(int id, boolean resetUnloadDelay, boolean forceLoad)
|
||||||
{
|
{
|
||||||
if (resetUnloadDelay && unloadQueue.contains(id))
|
if (resetUnloadDelay && unloadQueue.contains(id))
|
||||||
{
|
{
|
||||||
dimensions.get(id).ticksWaited = 0;
|
dimensions.get(id).ticksWaited = 0;
|
||||||
}
|
}
|
||||||
return worlds.get(id);
|
WorldServer ret = worlds.get(id);
|
||||||
|
if (ret != null && forceLoad)
|
||||||
|
{
|
||||||
|
initDimension(id);
|
||||||
|
ret = worlds.get(id);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WorldServer[] getWorlds()
|
public static WorldServer[] getWorlds()
|
||||||
|
@ -379,7 +388,7 @@ public class DimensionManager
|
||||||
/*
|
/*
|
||||||
* To be called by the server at the appropriate time, do not call from mod code.
|
* To be called by the server at the appropriate time, do not call from mod code.
|
||||||
*/
|
*/
|
||||||
public static void unloadWorlds(Hashtable<Integer, long[]> worldTickTimes)
|
public static void unloadWorlds()
|
||||||
{
|
{
|
||||||
IntIterator queueIterator = unloadQueue.iterator();
|
IntIterator queueIterator = unloadQueue.iterator();
|
||||||
while (queueIterator.hasNext())
|
while (queueIterator.hasNext())
|
||||||
|
|
|
@ -21,8 +21,10 @@ package net.minecraftforge.common;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -38,6 +40,7 @@ import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Queues;
|
import com.google.common.collect.Queues;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
@ -49,7 +52,6 @@ import net.minecraft.advancements.Advancement;
|
||||||
import net.minecraft.advancements.AdvancementManager;
|
import net.minecraft.advancements.AdvancementManager;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockFarmland;
|
import net.minecraft.block.BlockFarmland;
|
||||||
import net.minecraft.block.BlockLiquid;
|
|
||||||
import net.minecraft.block.material.Material;
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
@ -64,7 +66,9 @@ import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
import net.minecraft.entity.player.InventoryPlayer;
|
import net.minecraft.entity.player.InventoryPlayer;
|
||||||
import net.minecraft.entity.projectile.EntityThrowable;
|
import net.minecraft.entity.projectile.EntityThrowable;
|
||||||
|
import net.minecraft.fluid.IFluidState;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
|
import net.minecraft.init.Fluids;
|
||||||
import net.minecraft.init.Items;
|
import net.minecraft.init.Items;
|
||||||
import net.minecraft.inventory.ContainerRepair;
|
import net.minecraft.inventory.ContainerRepair;
|
||||||
import net.minecraft.inventory.IInventory;
|
import net.minecraft.inventory.IInventory;
|
||||||
|
@ -73,7 +77,6 @@ import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemAxe;
|
import net.minecraft.item.ItemAxe;
|
||||||
import net.minecraft.item.ItemBucket;
|
import net.minecraft.item.ItemBucket;
|
||||||
import net.minecraft.item.ItemEnchantedBook;
|
import net.minecraft.item.ItemEnchantedBook;
|
||||||
import net.minecraft.item.ItemMonsterPlacer;
|
|
||||||
import net.minecraft.item.ItemPickaxe;
|
import net.minecraft.item.ItemPickaxe;
|
||||||
import net.minecraft.item.ItemPotion;
|
import net.minecraft.item.ItemPotion;
|
||||||
import net.minecraft.item.ItemSpade;
|
import net.minecraft.item.ItemSpade;
|
||||||
|
@ -91,11 +94,12 @@ import net.minecraft.network.play.server.SPacketRecipeBook;
|
||||||
import net.minecraft.network.play.server.SPacketRecipeBook.State;
|
import net.minecraft.network.play.server.SPacketRecipeBook.State;
|
||||||
import net.minecraft.potion.PotionType;
|
import net.minecraft.potion.PotionType;
|
||||||
import net.minecraft.potion.PotionUtils;
|
import net.minecraft.potion.PotionUtils;
|
||||||
|
import net.minecraft.resources.IResource;
|
||||||
|
import net.minecraft.resources.IResourceManager;
|
||||||
import net.minecraft.stats.StatList;
|
import net.minecraft.stats.StatList;
|
||||||
import net.minecraft.tags.ItemTags;
|
import net.minecraft.tags.ItemTags;
|
||||||
import net.minecraft.tags.Tag;
|
import net.minecraft.tags.Tag;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.tileentity.TileEntityNote;
|
|
||||||
import net.minecraft.util.DamageSource;
|
import net.minecraft.util.DamageSource;
|
||||||
import net.minecraft.util.EnumActionResult;
|
import net.minecraft.util.EnumActionResult;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
|
@ -117,6 +121,7 @@ import net.minecraft.world.IWorldReader;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.EnumDifficulty;
|
import net.minecraft.world.EnumDifficulty;
|
||||||
import net.minecraft.world.GameType;
|
import net.minecraft.world.GameType;
|
||||||
|
import net.minecraft.world.IBlockReader;
|
||||||
import net.minecraft.world.storage.loot.LootEntry;
|
import net.minecraft.world.storage.loot.LootEntry;
|
||||||
import net.minecraft.world.storage.loot.LootTable;
|
import net.minecraft.world.storage.loot.LootTable;
|
||||||
import net.minecraft.world.storage.loot.LootTableManager;
|
import net.minecraft.world.storage.loot.LootTableManager;
|
||||||
|
@ -149,17 +154,12 @@ import net.minecraftforge.event.entity.player.AdvancementEvent;
|
||||||
import net.minecraftforge.event.world.BlockEvent;
|
import net.minecraftforge.event.world.BlockEvent;
|
||||||
import net.minecraftforge.event.world.NoteBlockEvent;
|
import net.minecraftforge.event.world.NoteBlockEvent;
|
||||||
import net.minecraftforge.fluids.IFluidBlock;
|
import net.minecraftforge.fluids.IFluidBlock;
|
||||||
import net.minecraftforge.fml.common.Loader;
|
|
||||||
import net.minecraftforge.fml.common.LoaderState;
|
|
||||||
import net.minecraftforge.fml.ModContainer;
|
import net.minecraftforge.fml.ModContainer;
|
||||||
import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher;
|
|
||||||
import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.ConnectionType;
|
|
||||||
import net.minecraftforge.fml.ModList;
|
import net.minecraftforge.fml.ModList;
|
||||||
import net.minecraftforge.fml.network.ConnectionType;
|
import net.minecraftforge.fml.network.ConnectionType;
|
||||||
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
||||||
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
|
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
|
||||||
import net.minecraftforge.fml.network.NetworkHooks;
|
import net.minecraftforge.fml.network.NetworkHooks;
|
||||||
import net.minecraftforge.fml.relauncher.ReflectionHelper;
|
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
import net.minecraftforge.registries.IForgeRegistry;
|
import net.minecraftforge.registries.IForgeRegistry;
|
||||||
import net.minecraftforge.registries.RegistryManager;
|
import net.minecraftforge.registries.RegistryManager;
|
||||||
|
@ -168,10 +168,12 @@ import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.apache.commons.io.FilenameUtils;
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.Marker;
|
import org.apache.logging.log4j.Marker;
|
||||||
import org.apache.logging.log4j.MarkerManager;
|
import org.apache.logging.log4j.MarkerManager;
|
||||||
|
import org.apache.logging.log4j.util.TriConsumer;
|
||||||
|
|
||||||
public class ForgeHooks
|
public class ForgeHooks
|
||||||
{
|
{
|
||||||
|
@ -210,20 +212,16 @@ public class ForgeHooks
|
||||||
return entry.getStack(rand, fortune);
|
return entry.getStack(rand, fortune);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean toolInit = false;
|
public static boolean canHarvestBlock(@Nonnull IBlockState state, @Nonnull EntityPlayer player, @Nonnull IBlockReader world, @Nonnull BlockPos pos)
|
||||||
//static HashSet<List> toolEffectiveness = new HashSet<List>();
|
|
||||||
|
|
||||||
public static boolean canHarvestBlock(@Nonnull Block block, @Nonnull EntityPlayer player, @Nonnull IWorldReader world, @Nonnull BlockPos pos)
|
|
||||||
{
|
{
|
||||||
IBlockState state = world.getBlockState(pos);
|
//state = state.getActualState(world, pos);
|
||||||
state = state.getBlock().getActualState(state, world, pos);
|
|
||||||
if (state.getMaterial().isToolNotRequired())
|
if (state.getMaterial().isToolNotRequired())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack stack = player.getHeldItemMainhand();
|
ItemStack stack = player.getHeldItemMainhand();
|
||||||
String tool = block.getHarvestTool(state);
|
ToolType tool = state.getHarvestTool();
|
||||||
if (stack.isEmpty() || tool == null)
|
if (stack.isEmpty() || tool == null)
|
||||||
{
|
{
|
||||||
return player.canHarvestBlock(state);
|
return player.canHarvestBlock(state);
|
||||||
|
@ -235,89 +233,50 @@ public class ForgeHooks
|
||||||
return player.canHarvestBlock(state);
|
return player.canHarvestBlock(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
return toolLevel >= block.getHarvestLevel(state);
|
return toolLevel >= state.getHarvestLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean canToolHarvestBlock(IWorldReader world, BlockPos pos, @Nonnull ItemStack stack)
|
public static boolean canToolHarvestBlock(IWorldReader world, BlockPos pos, @Nonnull ItemStack stack)
|
||||||
{
|
{
|
||||||
IBlockState state = world.getBlockState(pos);
|
IBlockState state = world.getBlockState(pos);
|
||||||
state = state.getBlock().getActualState(state, world, pos);
|
//state = state.getActualState(world, pos);
|
||||||
String tool = state.getBlock().getHarvestTool(state);
|
ToolType tool = state.getHarvestTool();
|
||||||
if (stack.isEmpty() || tool == null) return false;
|
if (stack.isEmpty() || tool == null) return false;
|
||||||
return stack.getItem().getHarvestLevel(stack, tool, null, null) >= state.getBlock().getHarvestLevel(state);
|
return stack.getHarvestLevel(tool, null, null) >= state.getHarvestLevel();
|
||||||
}
|
|
||||||
|
|
||||||
public static float blockStrength(@Nonnull IBlockState state, @Nonnull EntityPlayer player, @Nonnull World world, @Nonnull BlockPos pos)
|
|
||||||
{
|
|
||||||
float hardness = state.getBlockHardness(world, pos);
|
|
||||||
if (hardness < 0.0F)
|
|
||||||
{
|
|
||||||
return 0.0F;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!canHarvestBlock(state.getBlock(), player, world, pos))
|
|
||||||
{
|
|
||||||
return player.getDigSpeed(state, pos) / hardness / 100F;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return player.getDigSpeed(state, pos) / hardness / 30F;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isToolEffective(IWorldReader world, BlockPos pos, @Nonnull ItemStack stack)
|
public static boolean isToolEffective(IWorldReader world, BlockPos pos, @Nonnull ItemStack stack)
|
||||||
{
|
{
|
||||||
IBlockState state = world.getBlockState(pos);
|
IBlockState state = world.getBlockState(pos);
|
||||||
state = state.getBlock().getActualState(state, world, pos);
|
//state = state.getActualState(world, pos);
|
||||||
for (String type : stack.getItem().getToolClasses(stack))
|
for (ToolType type : stack.getToolTypes())
|
||||||
{
|
{
|
||||||
if (state.getBlock().isToolEffective(type, state))
|
if (state.isToolEffective(type))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean toolInit = false;
|
||||||
static void initTools()
|
static void initTools()
|
||||||
{
|
{
|
||||||
if (toolInit)
|
if (toolInit)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
toolInit = true;
|
toolInit = true;
|
||||||
|
|
||||||
Set<Block> blocks = ReflectionHelper.getPrivateValue(ItemPickaxe.class, null, 0);
|
Set<Block> blocks = getPrivateValue(ItemPickaxe.class, null, 0);
|
||||||
for (Block block : blocks)
|
blocks.forEach(block -> blockToolSetter.accept(block, ToolType.PICKAXE, 0));
|
||||||
{
|
blocks = getPrivateValue(ItemSpade.class, null, 0);
|
||||||
block.setHarvestLevel("pickaxe", 0);
|
blocks.forEach(block -> blockToolSetter.accept(block, ToolType.SHOVEL, 0));
|
||||||
}
|
blocks = getPrivateValue(ItemAxe.class, null, 0);
|
||||||
|
blocks.forEach(block -> blockToolSetter.accept(block, ToolType.AXE, 0));
|
||||||
|
|
||||||
blocks = ReflectionHelper.getPrivateValue(ItemSpade.class, null, 0);
|
//This is taken from ItemAxe, if that changes update here.
|
||||||
for (Block block : blocks)
|
blockToolSetter.accept(Blocks.OBSIDIAN, ToolType.PICKAXE, 3);
|
||||||
{
|
for (Block block : new Block[]{Blocks.DIAMOND_BLOCK, Blocks.DIAMOND_ORE, Blocks.EMERALD_ORE, Blocks.EMERALD_BLOCK, Blocks.GOLD_BLOCK, Blocks.GOLD_ORE, Blocks.REDSTONE_ORE})
|
||||||
block.setHarvestLevel("shovel", 0);
|
blockToolSetter.accept(block, ToolType.PICKAXE, 2);
|
||||||
}
|
for (Block block : new Block[]{Blocks.IRON_BLOCK, Blocks.IRON_ORE, Blocks.LAPIS_BLOCK, Blocks.LAPIS_ORE})
|
||||||
|
blockToolSetter.accept(block, ToolType.PICKAXE, 1);
|
||||||
blocks = ReflectionHelper.getPrivateValue(ItemAxe.class, null, 0);
|
|
||||||
for (Block block : blocks)
|
|
||||||
{
|
|
||||||
block.setHarvestLevel("axe", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Blocks.OBSIDIAN.setHarvestLevel("pickaxe", 3);
|
|
||||||
Blocks.ENCHANTING_TABLE.setHarvestLevel("pickaxe", 0);
|
|
||||||
Block[] oreBlocks = new Block[] {
|
|
||||||
Blocks.EMERALD_ORE, Blocks.EMERALD_BLOCK, Blocks.DIAMOND_ORE, Blocks.DIAMOND_BLOCK,
|
|
||||||
Blocks.GOLD_ORE, Blocks.GOLD_BLOCK, Blocks.REDSTONE_ORE, Blocks.LIT_REDSTONE_ORE
|
|
||||||
};
|
|
||||||
for (Block block : oreBlocks)
|
|
||||||
{
|
|
||||||
block.setHarvestLevel("pickaxe", 2);
|
|
||||||
}
|
|
||||||
Blocks.IRON_ORE.setHarvestLevel("pickaxe", 1);
|
|
||||||
Blocks.IRON_BLOCK.setHarvestLevel("pickaxe", 1);
|
|
||||||
Blocks.LAPIS_ORE.setHarvestLevel("pickaxe", 1);
|
|
||||||
Blocks.LAPIS_BLOCK.setHarvestLevel("pickaxe", 1);
|
|
||||||
Blocks.QUARTZ_ORE.setHarvestLevel("pickaxe", 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getTotalArmorValue(EntityPlayer player)
|
public static int getTotalArmorValue(EntityPlayer player)
|
||||||
|
@ -723,7 +682,7 @@ public class ForgeHooks
|
||||||
|
|
||||||
public static float getEnchantPower(@Nonnull World world, @Nonnull BlockPos pos)
|
public static float getEnchantPower(@Nonnull World world, @Nonnull BlockPos pos)
|
||||||
{
|
{
|
||||||
return world.getBlockState(pos).getBlock().getEnchantPowerBonus(world, pos);
|
return world.getBlockState(pos).getEnchantPowerBonus(world, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -841,9 +800,7 @@ public class ForgeHooks
|
||||||
// Tell client the block is gone immediately then process events
|
// Tell client the block is gone immediately then process events
|
||||||
if (world.getTileEntity(pos) == null)
|
if (world.getTileEntity(pos) == null)
|
||||||
{
|
{
|
||||||
SPacketBlockChange packet = new SPacketBlockChange(world, pos);
|
entityPlayer.connection.sendPacket(new SPacketBlockChange(DUMMY_WORLD, pos));
|
||||||
packet.blockState = Blocks.AIR.getDefaultState();
|
|
||||||
entityPlayer.connection.sendPacket(packet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post the block break event
|
// Post the block break event
|
||||||
|
@ -872,6 +829,7 @@ public class ForgeHooks
|
||||||
return event.isCanceled() ? -1 : event.getExpToDrop();
|
return event.isCanceled() ? -1 : event.getExpToDrop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: Talk to Sponge folk about World rollbacks.
|
||||||
public static EnumActionResult onPlaceItemIntoWorld(@Nonnull ItemUseContext context)
|
public static EnumActionResult onPlaceItemIntoWorld(@Nonnull ItemUseContext context)
|
||||||
{
|
{
|
||||||
ItemStack itemstack = context.func_195996_i();
|
ItemStack itemstack = context.func_195996_i();
|
||||||
|
@ -969,6 +927,7 @@ public class ForgeHooks
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
public static boolean onAnvilChange(ContainerRepair container, @Nonnull ItemStack left, @Nonnull ItemStack right, IInventory outputSlot, String name, int baseCost)
|
public static boolean onAnvilChange(ContainerRepair container, @Nonnull ItemStack left, @Nonnull ItemStack right, IInventory outputSlot, String name, int baseCost)
|
||||||
{
|
{
|
||||||
|
@ -989,18 +948,6 @@ public class ForgeHooks
|
||||||
return e.getBreakChance();
|
return e.getBreakChance();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean onNoteChange(TileEntityNote te, byte old)
|
|
||||||
{
|
|
||||||
NoteBlockEvent.Change e = new NoteBlockEvent.Change(te.getWorld(), te.getPos(), te.getWorld().getBlockState(te.getPos()), old, te.note);
|
|
||||||
if (MinecraftForge.EVENT_BUS.post(e))
|
|
||||||
{
|
|
||||||
te.note = old;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
te.note = (byte)e.getVanillaNoteId();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ThreadLocal<EntityPlayer> craftingPlayer = new ThreadLocal<EntityPlayer>();
|
private static ThreadLocal<EntityPlayer> craftingPlayer = new ThreadLocal<EntityPlayer>();
|
||||||
public static void setCraftingPlayer(EntityPlayer player)
|
public static void setCraftingPlayer(EntityPlayer player)
|
||||||
{
|
{
|
||||||
|
@ -1285,16 +1232,6 @@ public class ForgeHooks
|
||||||
MinecraftForge.EVENT_BUS.post(new BlockEvent.CropGrowEvent.Post(worldIn, pos, state, worldIn.getBlockState(pos)));
|
MinecraftForge.EVENT_BUS.post(new BlockEvent.CropGrowEvent.Post(worldIn, pos, state, worldIn.getBlockState(pos)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean loadAdvancements(Map<ResourceLocation, Advancement.Builder> map)
|
|
||||||
{
|
|
||||||
boolean errored = false;
|
|
||||||
for (ModFileInfo mod : ModList.get().getModFiles())
|
|
||||||
{
|
|
||||||
errored |= !loadAdvancements(map, mod.getFile());
|
|
||||||
}
|
|
||||||
return errored;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static CriticalHitEvent getCriticalHit(EntityPlayer player, Entity target, boolean vanillaCritical, float damageModifier)
|
public static CriticalHitEvent getCriticalHit(EntityPlayer player, Entity target, boolean vanillaCritical, float damageModifier)
|
||||||
{
|
{
|
||||||
|
@ -1307,56 +1244,6 @@ public class ForgeHooks
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean loadAdvancements(Map<ResourceLocation, Advancement.Builder> map, ModFile mod)
|
|
||||||
{
|
|
||||||
if (Loader.instance().getLoaderState() != LoaderState.NOINIT) //Unit Tests..
|
|
||||||
Loader.instance().setActiveModContainer(mod);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean loadAdvancements(Map<ResourceLocation, Advancement.Builder> map, ModContainer mod)
|
|
||||||
{
|
|
||||||
return CraftingHelper.findFiles(mod, "assets/" + mod.getModId() + "/advancements", null,
|
|
||||||
(root, file) ->
|
|
||||||
{
|
|
||||||
|
|
||||||
String relative = root.relativize(file).toString();
|
|
||||||
if (!"json".equals(FilenameUtils.getExtension(file.toString())) || relative.startsWith("_"))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
String name = FilenameUtils.removeExtension(relative).replaceAll("\\\\", "/");
|
|
||||||
ResourceLocation key = new ResourceLocation(mod.getModId(), name);
|
|
||||||
|
|
||||||
if (!map.containsKey(key))
|
|
||||||
{
|
|
||||||
BufferedReader reader = null;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
reader = Files.newBufferedReader(file);
|
|
||||||
Advancement.Builder builder = JsonUtils.fromJson(AdvancementManager.GSON, reader, Advancement.Builder.class);
|
|
||||||
map.put(key, builder);
|
|
||||||
}
|
|
||||||
catch (JsonParseException jsonparseexception)
|
|
||||||
{
|
|
||||||
LOGGER.error("Parsing error loading built-in advancement " + key, (Throwable)jsonparseexception);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch (IOException ioexception)
|
|
||||||
{
|
|
||||||
LOGGER.error("Couldn't read advancement " + key + " from " + file, (Throwable)ioexception);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
IOUtils.closeQuietly(reader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
true, true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
/* TODO this should be unnecessary now?
|
/* TODO this should be unnecessary now?
|
||||||
public static void sendRecipeBook(NetHandlerPlayServer connection, State state, List<IRecipe> recipes, List<IRecipe> display, boolean isGuiOpen, boolean isFilteringCraftable)
|
public static void sendRecipeBook(NetHandlerPlayServer connection, State state, List<IRecipe> recipes, List<IRecipe> display, boolean isGuiOpen, boolean isFilteringCraftable)
|
||||||
{
|
{
|
||||||
|
@ -1439,4 +1326,52 @@ public class ForgeHooks
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getServerModName()
|
||||||
|
{
|
||||||
|
//TODO: Branding Properties: snooperbranding
|
||||||
|
return "forge";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TriConsumer<Block, ToolType, Integer> blockToolSetter;
|
||||||
|
//Internal use only Modders, this is specifically hidden from you, as you shouldn't be editing other people's blocks.
|
||||||
|
public static void setBlockToolSetter(TriConsumer<Block, ToolType, Integer> setter)
|
||||||
|
{
|
||||||
|
blockToolSetter = setter;
|
||||||
|
}
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static <T, E> T getPrivateValue(Class <? super E > classToAccess, @Nullable E instance, int fieldIndex)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Field f = classToAccess.getDeclaredFields()[fieldIndex];
|
||||||
|
f.setAccessible(true);
|
||||||
|
return (T) f.get(instance);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Throwables.throwIfUnchecked(e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final DummyBlockReader DUMMY_WORLD = new DummyBlockReader();
|
||||||
|
private static class DummyBlockReader implements IBlockReader {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TileEntity getTileEntity(BlockPos pos) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBlockState getBlockState(BlockPos pos) {
|
||||||
|
return Blocks.AIR.getDefaultState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IFluidState func_204610_c(BlockPos p_204610_1_) {
|
||||||
|
return Fluids.field_204541_a.func_207188_f();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
53
src/main/java/net/minecraftforge/common/ToolType.java
Normal file
53
src/main/java/net/minecraftforge/common/ToolType.java
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 2016-2018.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package net.minecraftforge.common;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
public final class ToolType
|
||||||
|
{
|
||||||
|
public static final ToolType AXE = get("axe");
|
||||||
|
public static final ToolType PICKAXE = get("pickaxe");
|
||||||
|
public static final ToolType SHOVEL = get("shovel");
|
||||||
|
|
||||||
|
private static final Map<String, ToolType> values = Maps.newHashMap();
|
||||||
|
private static final Pattern VALID_NAME = Pattern.compile("[^a-z_]"); //Only a-z and _ are allowed, meaning names must be lower case. And use _ to separate words.
|
||||||
|
|
||||||
|
public static ToolType get(String name)
|
||||||
|
{
|
||||||
|
if (VALID_NAME.matcher(name).find())
|
||||||
|
throw new IllegalArgumentException("ToolType.create() called with invalid name: " + name);
|
||||||
|
return values.putIfAbsent(name, new ToolType(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
private ToolType(String name)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,7 +40,6 @@ import net.minecraft.item.EnumDyeColor;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.pathfinding.PathNodeType;
|
import net.minecraft.pathfinding.PathNodeType;
|
||||||
import net.minecraft.state.EnumProperty;
|
|
||||||
import net.minecraft.state.IProperty;
|
import net.minecraft.state.IProperty;
|
||||||
import net.minecraft.state.properties.BedPart;
|
import net.minecraft.state.properties.BedPart;
|
||||||
import net.minecraft.util.*;
|
import net.minecraft.util.*;
|
||||||
|
@ -52,19 +51,20 @@ import net.minecraft.world.Explosion;
|
||||||
import net.minecraft.world.IBlockReader;
|
import net.minecraft.world.IBlockReader;
|
||||||
import net.minecraft.world.IWorld;
|
import net.minecraft.world.IWorld;
|
||||||
import net.minecraft.world.IWorldReader;
|
import net.minecraft.world.IWorldReader;
|
||||||
|
import net.minecraft.world.IWorldWriter;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.WorldServer;
|
import net.minecraft.world.WorldServer;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.common.EnumPlantType;
|
import net.minecraftforge.common.EnumPlantType;
|
||||||
import net.minecraftforge.common.IPlantable;
|
import net.minecraftforge.common.IPlantable;
|
||||||
|
import net.minecraftforge.common.ToolType;
|
||||||
|
|
||||||
public interface IForgeBlock
|
public interface IForgeBlock
|
||||||
{
|
{
|
||||||
default Block getBlock()
|
default Block getBlock()
|
||||||
{
|
{
|
||||||
return (Block) this;
|
return (Block) this;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -170,7 +170,7 @@ public interface IForgeBlock
|
||||||
return this.getBlock().hasTileEntity();
|
return this.getBlock().hasTileEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean canSilkHarvest(IWorldReader world, BlockPos pos, IBlockState state, EntityPlayer player);
|
boolean canSilkHarvest(IBlockState state, IWorldReader world, BlockPos pos, EntityPlayer player);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if this block is classified as a Bed, Allowing
|
* Determines if this block is classified as a Bed, Allowing
|
||||||
|
@ -198,6 +198,7 @@ public interface IForgeBlock
|
||||||
* @param type The Mob Category Type
|
* @param type The Mob Category Type
|
||||||
* @return True to allow a mob of the specified category to spawn, false to prevent it.
|
* @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)
|
default boolean canCreatureSpawn(IBlockState state, IWorldReader world, BlockPos pos, EntitySpawnPlacementRegistry.SpawnPlacementType type)
|
||||||
{
|
{
|
||||||
return this.getBlock().isTopSolid(state);
|
return this.getBlock().isTopSolid(state);
|
||||||
|
@ -225,19 +226,18 @@ public interface IForgeBlock
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a user either starts or stops sleeping in the bed.
|
* Called when a user either starts or stops sleeping in the bed.
|
||||||
|
* @param state
|
||||||
*
|
*
|
||||||
* @param world The current world
|
* @param world The current world
|
||||||
* @param pos Block position in world
|
* @param pos Block position in world
|
||||||
* @param player The player or camera entity, null in some cases.
|
* @param player The player or camera entity, null in some cases.
|
||||||
* @param occupied True if we are occupying the bed, or false if they are stopping use of the bed
|
* @param occupied True if we are occupying the bed, or false if they are stopping use of the bed
|
||||||
*/
|
*/
|
||||||
default void setBedOccupied(IWorldReader world, BlockPos pos, EntityPlayer player, boolean occupied)
|
default void setBedOccupied(IBlockState state, IWorldReader world, BlockPos pos, EntityPlayer player, boolean occupied)
|
||||||
{
|
{
|
||||||
if (world instanceof World)
|
if (world instanceof IWorldWriter)
|
||||||
{
|
{
|
||||||
IBlockState state = world.getBlockState(pos);
|
((IWorldWriter)world).setBlockState(pos, state.func_206870_a(BlockBed.OCCUPIED,occupied), 4);
|
||||||
state.func_206870_a(BlockBed.OCCUPIED,occupied);
|
|
||||||
((World) world).setBlockState(pos, state, 4);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +336,7 @@ public interface IForgeBlock
|
||||||
* @param pos Block position in world
|
* @param pos Block position in world
|
||||||
* @return true if the block is wood (logs)
|
* @return true if the block is wood (logs)
|
||||||
*/
|
*/
|
||||||
default boolean isWood(IWorldReader world, BlockPos pos)
|
default boolean isWood(IBlockState state, IWorldReader world, BlockPos pos)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -365,7 +365,7 @@ public interface IForgeBlock
|
||||||
* @param explosion The explosion
|
* @param explosion The explosion
|
||||||
* @return The amount of the explosion absorbed.
|
* @return The amount of the explosion absorbed.
|
||||||
*/
|
*/
|
||||||
default float getExplosionResistance(IWorld world, BlockPos pos, @Nullable Entity exploder, Explosion explosion)
|
default float getExplosionResistance(IBlockState state, IWorldReader world, BlockPos pos, @Nullable Entity exploder, Explosion explosion)
|
||||||
{
|
{
|
||||||
return this.getBlock().getExplosionResistance();
|
return this.getBlock().getExplosionResistance();
|
||||||
}
|
}
|
||||||
|
@ -379,7 +379,7 @@ public interface IForgeBlock
|
||||||
* @param pos Block position in world
|
* @param pos Block position in world
|
||||||
* @param explosion The explosion instance affecting the block
|
* @param explosion The explosion instance affecting the block
|
||||||
*/
|
*/
|
||||||
void onBlockExploded(World world, BlockPos pos, Explosion explosion);
|
void onBlockExploded(IBlockState state, World world, BlockPos pos, Explosion explosion);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if this block can make a redstone connection on the side provided,
|
* Determine if this block can make a redstone connection on the side provided,
|
||||||
|
@ -395,7 +395,7 @@ public interface IForgeBlock
|
||||||
{
|
{
|
||||||
return state.canProvidePower() && side != null;
|
return state.canProvidePower() && side != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if a torch can be placed on the top surface of this block.
|
* Determines if a torch can be placed on the top surface of this block.
|
||||||
* Useful for creating your own block that torches can be on, such as fences.
|
* Useful for creating your own block that torches can be on, such as fences.
|
||||||
|
@ -408,44 +408,39 @@ public interface IForgeBlock
|
||||||
default boolean canPlaceTorchOnTop(IBlockState state, IWorldReader world, BlockPos pos)
|
default boolean canPlaceTorchOnTop(IBlockState state, IWorldReader world, BlockPos pos)
|
||||||
{
|
{
|
||||||
if (state.isTopSolid() || state.getBlockFaceShape(world, pos, EnumFacing.UP) == BlockFaceShape.SOLID)
|
if (state.isTopSolid() || state.getBlockFaceShape(world, pos, EnumFacing.UP) == BlockFaceShape.SOLID)
|
||||||
{
|
|
||||||
return this.getBlock() != Blocks.END_GATEWAY && this.getBlock() != Blocks.field_196628_cT;
|
return this.getBlock() != Blocks.END_GATEWAY && this.getBlock() != Blocks.field_196628_cT;
|
||||||
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
return this.getBlock() instanceof BlockFence || this.getBlock() == Blocks.COBBLESTONE_WALL || this.getBlock() instanceof BlockGlass;
|
return this.getBlock() instanceof BlockFence || this.getBlock() == Blocks.COBBLESTONE_WALL || this.getBlock() instanceof BlockGlass;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Called when A user uses the creative pick block button on this block
|
* Called when A user uses the creative pick block button on this block
|
||||||
*
|
*
|
||||||
* @param target The full target the player is looking at
|
* @param target The full target the player is looking at
|
||||||
* @return A ItemStack to add to the player's inventory, empty itemstack if nothing should be added.
|
* @return A ItemStack to add to the player's inventory, empty itemstack if nothing should be added.
|
||||||
*/
|
*/
|
||||||
default ItemStack getPickBlock(IBlockState state, RayTraceResult target, IBlockReader world, BlockPos pos, EntityPlayer player)
|
default ItemStack getPickBlock(IBlockState state, RayTraceResult target, IBlockReader world, BlockPos pos, EntityPlayer player)
|
||||||
{
|
{
|
||||||
return this.getBlock().getItem(world, pos, state);
|
return this.getBlock().getItem(world, pos, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by getTopSoilidOrLiquidBlock while placing biome decorations, villages, etc
|
* Used by getTopSoilidOrLiquidBlock while placing biome decorations, villages, etc
|
||||||
* Also used to determine if the player can spawn in this block.
|
* Also used to determine if the player can spawn in this block.
|
||||||
*
|
*
|
||||||
* @return False to disallow spawning.
|
* @return False to disallow spawning.
|
||||||
*/
|
*/
|
||||||
default boolean isFoilage(IWorldReader world, BlockPos pos)
|
default boolean isFoliage(IBlockState state, IWorldReader world, BlockPos pos)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows a block to override the standard EntityLivingBase.updateFallState
|
* Allows a block to override the standard EntityLivingBase.updateFallState
|
||||||
* particles, this is a server side method that spawns particles with
|
* particles, this is a server side method that spawns particles with
|
||||||
* WorldServer.spawnParticle.
|
* WorldServer.spawnParticle.
|
||||||
*
|
*
|
||||||
* @param worldserver The current Server World
|
* @param worldserver The current Server World
|
||||||
* @param pos The position of the block.
|
* @param pos The position of the block.
|
||||||
* @param state2 The state at the specific world/pos
|
* @param state2 The state at the specific world/pos
|
||||||
|
@ -453,9 +448,9 @@ public interface IForgeBlock
|
||||||
* @param numberOfParticles That vanilla world have spawned
|
* @param numberOfParticles That vanilla world have spawned
|
||||||
* @return True to prevent vanilla landing particles from spawning
|
* @return True to prevent vanilla landing particles from spawning
|
||||||
*/
|
*/
|
||||||
default boolean addLandingEffects(IBlockState state1, WorldServer worldserver, BlockPos pos, IBlockState state2, EntityLivingBase entity, int numberOfParticles)
|
default boolean addLandingEffects(IBlockState state1, WorldServer worldserver, BlockPos pos, IBlockState state2, EntityLivingBase entity, int numberOfParticles)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Allows a block to override the standard vanilla running particles.
|
* Allows a block to override the standard vanilla running particles.
|
||||||
|
@ -486,7 +481,7 @@ public interface IForgeBlock
|
||||||
* @return True to prevent vanilla break particles from spawning.
|
* @return True to prevent vanilla break particles from spawning.
|
||||||
*/
|
*/
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
default boolean addDestroyEffects(World world, BlockPos pos, ParticleManager manager)
|
default boolean addDestroyEffects(IBlockState state, World world, BlockPos pos, ParticleManager manager)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -568,9 +563,7 @@ public interface IForgeBlock
|
||||||
default void onPlantGrow(IBlockState state, World world, BlockPos pos, BlockPos source)
|
default void onPlantGrow(IBlockState state, World world, BlockPos pos, BlockPos source)
|
||||||
{
|
{
|
||||||
if (this.getBlock() == Blocks.GRASS || this.getBlock() == Blocks.FARMLAND)
|
if (this.getBlock() == Blocks.GRASS || this.getBlock() == Blocks.FARMLAND)
|
||||||
{
|
|
||||||
world.setBlockState(pos, Blocks.DIRT.getDefaultState(), 2);
|
world.setBlockState(pos, Blocks.DIRT.getDefaultState(), 2);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -582,12 +575,10 @@ public interface IForgeBlock
|
||||||
* @param pos Block position in world
|
* @param pos Block position in world
|
||||||
* @return True if the soil should be considered fertile.
|
* @return True if the soil should be considered fertile.
|
||||||
*/
|
*/
|
||||||
default boolean isFertile(World world, BlockPos pos)
|
default boolean isFertile(IBlockState state, IWorldReader world, BlockPos pos)
|
||||||
{
|
{
|
||||||
if (this.getBlock() == Blocks.FARMLAND)
|
if (this.getBlock() == Blocks.FARMLAND)
|
||||||
{
|
return state.getValue(BlockFarmland.MOISTURE) > 0;
|
||||||
return world.getBlockState(pos).getValue(BlockFarmland.MOISTURE) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -618,7 +609,7 @@ public interface IForgeBlock
|
||||||
* @param beacon Beacon position in world
|
* @param beacon Beacon position in world
|
||||||
* @return True, to support the beacon, and make it active with this block.
|
* @return True, to support the beacon, and make it active with this block.
|
||||||
*/
|
*/
|
||||||
default boolean isBeaconBase(IWorldReader world, BlockPos pos, BlockPos beacon)
|
default boolean isBeaconBase(IBlockState state, IWorldReader world, BlockPos pos, BlockPos beacon)
|
||||||
{
|
{
|
||||||
return this.getBlock() == Blocks.EMERALD_BLOCK || this.getBlock() == Blocks.GOLD_BLOCK ||
|
return this.getBlock() == Blocks.EMERALD_BLOCK || this.getBlock() == Blocks.GOLD_BLOCK ||
|
||||||
this.getBlock() == Blocks.DIAMOND_BLOCK || this.getBlock() == Blocks.IRON_BLOCK;
|
this.getBlock() == Blocks.DIAMOND_BLOCK || this.getBlock() == Blocks.IRON_BLOCK;
|
||||||
|
@ -637,10 +628,8 @@ public interface IForgeBlock
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean rotateBlock(World world, BlockPos pos, EnumFacing axis)
|
default boolean rotateBlock(IBlockState state, IWorld world, BlockPos pos, EnumFacing axis)
|
||||||
{
|
{
|
||||||
IBlockState state = world.getBlockState(pos);
|
|
||||||
|
|
||||||
state.func_206871_b().keySet().forEach(prop ->
|
state.func_206871_b().keySet().forEach(prop ->
|
||||||
{
|
{
|
||||||
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)
|
||||||
|
@ -673,7 +662,7 @@ public interface IForgeBlock
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
world.setBlockState(pos, newState);
|
world.setBlockState(pos, newState, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -688,7 +677,7 @@ public interface IForgeBlock
|
||||||
* @param pos Block position in world
|
* @param pos Block position in world
|
||||||
* @return The amount of enchanting power this block produces.
|
* @return The amount of enchanting power this block produces.
|
||||||
*/
|
*/
|
||||||
default float getEnchantPowerBouns(World world, BlockPos pos)
|
default float getEnchantPowerBonus(IBlockState state, IWorldReader world, BlockPos pos)
|
||||||
{
|
{
|
||||||
return this.getBlock() == Blocks.BOOKSHELF ? 1: 0;
|
return this.getBlock() == Blocks.BOOKSHELF ? 1: 0;
|
||||||
}
|
}
|
||||||
|
@ -703,7 +692,7 @@ public interface IForgeBlock
|
||||||
* @param fortune
|
* @param fortune
|
||||||
* @return Amount of XP from breaking this block.
|
* @return Amount of XP from breaking this block.
|
||||||
*/
|
*/
|
||||||
default boolean recolorBlock(World world, BlockPos pos, EnumFacing facing, EnumDyeColor color)
|
default boolean recolorBlock(IBlockState state, IWorld world, BlockPos pos, EnumFacing facing, EnumDyeColor color)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -714,7 +703,7 @@ public interface IForgeBlock
|
||||||
* @param pos Block position in world
|
* @param pos Block position in world
|
||||||
* @param neighbor Block position of neighbor
|
* @param neighbor Block position of neighbor
|
||||||
*/
|
*/
|
||||||
default void onNeighborChange(IWorldReader world, BlockPos pos, BlockPos neighbor){}
|
default void onNeighborChange(IBlockState state, IWorldReader world, BlockPos pos, BlockPos neighbor){}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called on an Observer block whenever an update for an Observer is received.
|
* Called on an Observer block whenever an update for an Observer is received.
|
||||||
|
@ -748,7 +737,7 @@ public interface IForgeBlock
|
||||||
* @param pos Block position in world
|
* @param pos Block position in world
|
||||||
* @return true To be notified of changes
|
* @return true To be notified of changes
|
||||||
*/
|
*/
|
||||||
default boolean getWeakChanges(IWorldReader world, BlockPos pos)
|
default boolean getWeakChanges(IBlockState state, IWorldReader world, BlockPos pos)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -756,7 +745,7 @@ public interface IForgeBlock
|
||||||
* Queries the class of tool required to harvest this block, if null is returned
|
* Queries the class of tool required to harvest this block, if null is returned
|
||||||
* we assume that anything can harvest this block.
|
* we assume that anything can harvest this block.
|
||||||
*/
|
*/
|
||||||
String getHarvestTool(IBlockState state);
|
ToolType getHarvestTool(IBlockState state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queries the harvest level of this item stack for the specified tool class,
|
* Queries the harvest level of this item stack for the specified tool class,
|
||||||
|
@ -770,14 +759,11 @@ public interface IForgeBlock
|
||||||
* Checks if the specified tool type is efficient on this block,
|
* Checks if the specified tool type is efficient on this block,
|
||||||
* meaning that it digs at full speed.
|
* meaning that it digs at full speed.
|
||||||
*/
|
*/
|
||||||
default boolean isToolEffective(String type, IBlockState state)
|
default boolean isToolEffective(IBlockState state, ToolType tool)
|
||||||
{
|
{
|
||||||
if ("pickaxe".equals(type) && (this.getBlock() == Blocks.REDSTONE_ORE || this.getBlock() == Blocks.REDSTONE_LAMP
|
if (tool == ToolType.PICKAXE && (this.getBlock() == Blocks.REDSTONE_ORE || this.getBlock() == Blocks.REDSTONE_LAMP || this.getBlock() == Blocks.OBSIDIAN))
|
||||||
|| this.getBlock() == Blocks.OBSIDIAN))
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
return tool == getHarvestTool(state);
|
||||||
return type != null && type.equals(getHarvestTool(state));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -794,7 +780,6 @@ public interface IForgeBlock
|
||||||
*
|
*
|
||||||
* @param world that is being tested.
|
* @param world that is being tested.
|
||||||
* @param blockpos position thats being tested.
|
* @param blockpos position thats being tested.
|
||||||
* @param iblockstate state at world/blockpos
|
|
||||||
* @param entity that is being tested.
|
* @param entity that is being tested.
|
||||||
* @param yToTest, primarily for testingHead, which sends the the eye level of the entity, other wise it sends a y that can be tested vs liquid height.
|
* @param yToTest, primarily for testingHead, which sends the the eye level of the entity, other wise it sends a y that can be tested vs liquid height.
|
||||||
* @param materialIn to test for.
|
* @param materialIn to test for.
|
||||||
|
@ -802,7 +787,7 @@ public interface IForgeBlock
|
||||||
* @return null for default behavior, true if the entity is within the material, false if it was not.
|
* @return null for default behavior, true if the entity is within the material, false if it was not.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
default Boolean isEntityInsideMaterial(IWorldReader world, BlockPos blockpos, IBlockState iblockstate, Entity entity, double yToTest, Material materialIn, boolean testingHead)
|
default Boolean isEntityInsideMaterial(IBlockState state, IWorldReader world, BlockPos blockpos, Entity entity, double yToTest, Material materialIn, boolean testingHead)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -818,7 +803,7 @@ public interface IForgeBlock
|
||||||
* @return null for default behavior, true if the box is within the material, false if it was not.
|
* @return null for default behavior, true if the box is within the material, false if it was not.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
default Boolean isAABBInsideMaterial(World world, BlockPos pos, AxisAlignedBB boundingBox, Material materialIn)
|
default Boolean isAABBInsideMaterial(IBlockState state, IWorldReader world, BlockPos pos, AxisAlignedBB boundingBox, Material materialIn)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -832,7 +817,7 @@ public interface IForgeBlock
|
||||||
* @return null for default behavior, true if the box is within the material, false if it was not.
|
* @return null for default behavior, true if the box is within the material, false if it was not.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
default Boolean isAABBInsideLiquid(World world, BlockPos pos, AxisAlignedBB boundingBox)
|
default Boolean isAABBInsideLiquid(IBlockState state, IWorldReader world, BlockPos pos, AxisAlignedBB boundingBox)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -855,7 +840,7 @@ public interface IForgeBlock
|
||||||
* @param entity The entity that is breaking/stepping on/placing/hitting/falling on this block, or null if no entity is in this context
|
* @param entity The entity that is breaking/stepping on/placing/hitting/falling on this block, or null if no entity is in this context
|
||||||
* @return A SoundType to use
|
* @return A SoundType to use
|
||||||
*/
|
*/
|
||||||
default SoundType getSoundType(IBlockState state, World world, BlockPos pos, @Nullable Entity entity)
|
default SoundType getSoundType(IBlockState state, IWorldReader world, BlockPos pos, @Nullable Entity entity)
|
||||||
{
|
{
|
||||||
return this.getBlock().getSoundType();
|
return this.getBlock().getSoundType();
|
||||||
}
|
}
|
||||||
|
@ -868,7 +853,7 @@ public interface IForgeBlock
|
||||||
* @return A float RGB [0.0, 1.0] array to be averaged with a beacon's existing beam color, or null to do nothing to the beam
|
* @return A float RGB [0.0, 1.0] array to be averaged with a beacon's existing beam color, or null to do nothing to the beam
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
default float[] getBeaconColorMultiplier(IBlockState state, World world, BlockPos pos, BlockPos beaconPos)
|
default float[] getBeaconColorMultiplier(IBlockState state, IWorldReader world, BlockPos pos, BlockPos beaconPos)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -885,7 +870,7 @@ public interface IForgeBlock
|
||||||
* @return The new fog color.
|
* @return The new fog color.
|
||||||
*/
|
*/
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
default Vec3d getFogColor(World world, BlockPos pos, IBlockState state, Entity entity, Vec3d originalColor, float partialTicks)
|
default Vec3d getFogColor(IBlockState state, IWorldReader world, BlockPos pos, Entity entity, Vec3d originalColor, float partialTicks)
|
||||||
{
|
{
|
||||||
if (state.getMaterial() == Material.WATER)
|
if (state.getMaterial() == Material.WATER)
|
||||||
{
|
{
|
||||||
|
@ -939,6 +924,7 @@ public interface IForgeBlock
|
||||||
* @param hand The player hand used to place this block
|
* @param hand The player hand used to place this block
|
||||||
* @return The state to be placed in the world
|
* @return The state to be placed in the world
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
default IBlockState getStateForPlacement(IBlockState state, EnumFacing facing, IBlockState state2, IWorld world, BlockPos pos1, BlockPos pos2, EnumHand hand)
|
default IBlockState getStateForPlacement(IBlockState state, EnumFacing facing, IBlockState state2, IWorld world, BlockPos pos1, BlockPos pos2, EnumHand hand)
|
||||||
{
|
{
|
||||||
return this.getBlock().func_196271_a(state, facing, state2, world, pos1, pos2);
|
return this.getBlock().func_196271_a(state, facing, state2, world, pos1, pos2);
|
||||||
|
@ -953,7 +939,7 @@ public interface IForgeBlock
|
||||||
* @param facing The side the connecting block is on
|
* @param facing The side the connecting block is on
|
||||||
* @return True to allow another block to connect to this block
|
* @return True to allow another block to connect to this block
|
||||||
*/
|
*/
|
||||||
default boolean canBeConnectedTo(IWorldReader world, BlockPos pos, EnumFacing facing)
|
default boolean canBeConnectedTo(IBlockState state, IWorldReader world, BlockPos pos, EnumFacing facing)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -976,6 +962,7 @@ public interface IForgeBlock
|
||||||
* @param side The side of this block that the chest lid is trying to open into
|
* @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
|
* @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, IWorldReader world, BlockPos pos, EnumFacing side)
|
||||||
{
|
{
|
||||||
ResourceLocation registryName = this.getBlock().getRegistryName();
|
ResourceLocation registryName = this.getBlock().getRegistryName();
|
||||||
|
|
|
@ -0,0 +1,820 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 2016-2018.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.minecraftforge.common.extensions;
|
||||||
|
|
||||||
|
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;
|
||||||
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
|
import net.minecraft.entity.EntitySpawnPlacementRegistry.SpawnPlacementType;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.item.EnumDyeColor;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.pathfinding.PathNodeType;
|
||||||
|
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;
|
||||||
|
import net.minecraft.world.Explosion;
|
||||||
|
import net.minecraft.world.IBlockReader;
|
||||||
|
import net.minecraft.world.IWorld;
|
||||||
|
import net.minecraft.world.IWorldReader;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.WorldServer;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.common.IPlantable;
|
||||||
|
import net.minecraftforge.common.ToolType;
|
||||||
|
|
||||||
|
public interface IForgeBlockState
|
||||||
|
{
|
||||||
|
default IBlockState getBlockState()
|
||||||
|
{
|
||||||
|
return (IBlockState)this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the slipperiness at the given location at the given state. Normally
|
||||||
|
* between 0 and 1.
|
||||||
|
* <p>
|
||||||
|
* Note that entities may reduce slipperiness by a certain factor of their own;
|
||||||
|
* for {@link net.minecraft.entity.EntityLivingBase}, this is {@code .91}.
|
||||||
|
* {@link net.minecraft.entity.item.EntityItem} uses {@code .98}, and
|
||||||
|
* {@link net.minecraft.entity.projectile.EntityFishHook} uses {@code .92}.
|
||||||
|
*
|
||||||
|
* @param world the world
|
||||||
|
* @param pos the position in the world
|
||||||
|
* @param entity the entity in question
|
||||||
|
* @return the factor by which the entity's motion should be multiplied
|
||||||
|
*/
|
||||||
|
default float getSlipperiness(IWorldReader world, BlockPos pos, @Nullable Entity entity)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().getSlipperiness(getBlockState(), world, pos, entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a light value for this block, taking into account the given state and coordinates, normal ranges are between 0 and 15
|
||||||
|
*/
|
||||||
|
default int getLightValue(IWorldReader world, BlockPos pos)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().getLightValue(getBlockState(), world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a player or entity can use this block to 'climb' like a ladder.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @param entity The entity trying to use the ladder, CAN be null.
|
||||||
|
* @return True if the block should act like a ladder
|
||||||
|
*/
|
||||||
|
default boolean isLadder(IWorldReader world, BlockPos pos, EntityLivingBase entity)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().isLadder(getBlockState(), world, pos, entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the block is a normal, solid cube. This
|
||||||
|
* determines indirect power state, entity ejection from blocks, and a few
|
||||||
|
* others.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @return True if the block is a full cube
|
||||||
|
*/
|
||||||
|
default boolean isNormalCube(IWorldReader world, BlockPos pos)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().isNormalCube(getBlockState(), world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the face of a block should block rendering.
|
||||||
|
*
|
||||||
|
* Faces which are fully opaque should return true, faces with transparency
|
||||||
|
* or faces which do not span the full size of the block should return false.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @param face The side to check
|
||||||
|
* @return True if the block is opaque on the specified side.
|
||||||
|
*/
|
||||||
|
default boolean doesSideBlockRendering(IWorldReader world, BlockPos pos, EnumFacing face)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().doesSideBlockRendering(getBlockState(), world, pos, face);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called throughout the code as a replacement for block instanceof BlockContainer
|
||||||
|
* Moving this to the Block base class allows for mods that wish to extend vanilla
|
||||||
|
* blocks, and also want to have a tile entity on that block, may.
|
||||||
|
*
|
||||||
|
* Return true from this function to specify this block has a tile entity.
|
||||||
|
*
|
||||||
|
* @return True if block has a tile entity, false otherwise
|
||||||
|
*/
|
||||||
|
default boolean hasTileEntity()
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().hasTileEntity(getBlockState());
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean canSilkHarvest(IWorldReader world, BlockPos pos, EntityPlayer player)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().canSilkHarvest(getBlockState(), world, pos, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if this block is classified as a Bed, Allowing
|
||||||
|
* players to sleep in it, though the block has to specifically
|
||||||
|
* perform the sleeping functionality in it's activated event.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @param player The player or camera entity, null in some cases.
|
||||||
|
* @return True to treat this as a bed
|
||||||
|
*/
|
||||||
|
default boolean isBed(IWorldReader world, BlockPos pos, @Nullable EntityPlayer player)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().isBed(getBlockState(), world, pos, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a specified mob type can spawn on this block, returning false will
|
||||||
|
* prevent any mob from spawning on the block.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @param type The Mob Category Type
|
||||||
|
* @return True to allow a mob of the specified category to spawn, false to prevent it.
|
||||||
|
*/
|
||||||
|
default boolean canCreatureSpawn(IWorldReader world, BlockPos pos, SpawnPlacementType type)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().canCreatureSpawn(getBlockState(), world, pos, type);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the position that the player is moved to upon
|
||||||
|
* waking up, or respawning at the bed.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @param player The player or camera entity, null in some cases.
|
||||||
|
* @return The spawn position
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default BlockPos getBedSpawnPosition(IWorldReader world, BlockPos pos, @Nullable EntityPlayer player)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().getBedSpawnPosition(getBlockState(), world, pos, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a user either starts or stops sleeping in the bed.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @param player The player or camera entity, null in some cases.
|
||||||
|
* @param occupied True if we are occupying the bed, or false if they are stopping use of the bed
|
||||||
|
*/
|
||||||
|
default void setBedOccupied(IWorldReader world, BlockPos pos, EntityPlayer player, boolean occupied)
|
||||||
|
{
|
||||||
|
getBlockState().getBlock().setBedOccupied(getBlockState(), world, pos, player, occupied);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the direction of the block. Same values that
|
||||||
|
* are returned by BlockDirectional
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @return Bed direction
|
||||||
|
*/
|
||||||
|
default EnumFacing getBedDirection(IWorldReader world, BlockPos pos)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().getBedDirection(getBlockState(), world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the current block is the foot half of the bed.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @return True if the current block is the foot side of a bed.
|
||||||
|
*/
|
||||||
|
default boolean isBedFoot(IWorldReader world, BlockPos pos)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().isBedFoot(getBlockState(), world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a leaf should start its decay process.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
*/
|
||||||
|
default void beginLeaveDecay(IWorldReader world, BlockPos pos)
|
||||||
|
{
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @return true if this block is considered leaves.
|
||||||
|
*/
|
||||||
|
default boolean isLeaves(IWorldReader world, BlockPos pos)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().isLeaves(getBlockState(), world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines this block should be treated as an air block
|
||||||
|
* by the rest of the code. This method is primarily
|
||||||
|
* useful for creating pure logic-blocks that will be invisible
|
||||||
|
* to the player and otherwise interact as air would.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @return True if the block considered air
|
||||||
|
*/
|
||||||
|
default boolean isAir(IWorldReader world, BlockPos pos)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().isAir(getBlockState(), world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used during tree growth to determine if newly generated leaves can replace this block.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @return true if this block can be replaced by growing leaves.
|
||||||
|
*/
|
||||||
|
default boolean canBeReplacedByLeaves(IWorldReader world, BlockPos pos)
|
||||||
|
{
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @param target The generic target block the gen is looking for, Standards define stone
|
||||||
|
* for overworld generation, and neatherack for the nether.
|
||||||
|
* @return True to allow this block to be replaced by a ore
|
||||||
|
*/
|
||||||
|
default boolean isReplaceableOreGen(IWorldReader world, BlockPos pos, Predicate<IBlockState> target)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().isReplaceableOreGen(getBlockState(), world, pos, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location sensitive version of getExplosionResistance
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @param exploder The entity that caused the explosion, can be null
|
||||||
|
* @param explosion The explosion
|
||||||
|
* @return The amount of the explosion absorbed.
|
||||||
|
*/
|
||||||
|
default float getExplosionResistance(IWorldReader world, BlockPos pos, @Nullable Entity exploder, Explosion explosion)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().getExplosionResistance(getBlockState(), world, pos, exploder, explosion);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the block is destroyed by an explosion.
|
||||||
|
* Useful for allowing the block to take into account tile entities,
|
||||||
|
* state, etc. when exploded, before it is removed.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @param explosion The explosion instance affecting the block
|
||||||
|
*/
|
||||||
|
default void onBlockExploded(World world, BlockPos pos, Explosion explosion)
|
||||||
|
{
|
||||||
|
getBlockState().getBlock().onBlockExploded(getBlockState(), world, pos, explosion);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if this block can make a redstone connection on the side provided,
|
||||||
|
* Useful to control which sides are inputs and outputs for redstone wires.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @param side The side that is trying to make the connection, CAN BE NULL
|
||||||
|
* @return True to make the connection
|
||||||
|
*/
|
||||||
|
default boolean canConnectRedstone(IWorldReader world, BlockPos pos, @Nullable EnumFacing side)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().canConnectRedstone(getBlockState(), world, pos, side);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a torch can be placed on the top surface of this block.
|
||||||
|
* Useful for creating your own block that torches can be on, such as fences.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @return True to allow the torch to be placed
|
||||||
|
*/
|
||||||
|
default boolean canPlaceTorchOnTop(IWorldReader world, BlockPos pos)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().canPlaceTorchOnTop(getBlockState(), world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Called when A user uses the creative pick block button on this block
|
||||||
|
*
|
||||||
|
* @param target The full target the player is looking at
|
||||||
|
* @return A ItemStack to add to the player's inventory, empty itemstack if nothing should be added.
|
||||||
|
*/
|
||||||
|
default ItemStack getPickBlock(RayTraceResult target, IBlockReader world, BlockPos pos, EntityPlayer player)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().getPickBlock(getBlockState(), target, world, pos, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by getTopSoilidOrLiquidBlock while placing biome decorations, villages, etc
|
||||||
|
* Also used to determine if the player can spawn in this block.
|
||||||
|
*
|
||||||
|
* @return False to disallow spawning.
|
||||||
|
*/
|
||||||
|
default boolean isFoliage(IWorldReader world, BlockPos pos)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().isFoliage(getBlockState(), world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows a block to override the standard EntityLivingBase.updateFallState
|
||||||
|
* particles, this is a server side method that spawns particles with
|
||||||
|
* WorldServer.spawnParticle.
|
||||||
|
*
|
||||||
|
* @param worldserver The current Server World
|
||||||
|
* @param pos The position of the block.
|
||||||
|
* @param state2 The state at the specific world/pos
|
||||||
|
* @param entity The entity that hit landed on the block
|
||||||
|
* @param numberOfParticles That vanilla world have spawned
|
||||||
|
* @return True to prevent vanilla landing particles from spawning
|
||||||
|
*/
|
||||||
|
default boolean addLandingEffects(WorldServer worldserver, BlockPos pos, IBlockState state2, EntityLivingBase entity, int numberOfParticles)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().addLandingEffects(getBlockState(), worldserver, pos, state2, entity, numberOfParticles);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Allows a block to override the standard vanilla running particles.
|
||||||
|
* This is called from {@link Entity#spawnRunningParticles} and is called both,
|
||||||
|
* Client and server side, it's up to the implementor to client check / server check.
|
||||||
|
* By default vanilla spawns particles only on the client and the server methods no-op.
|
||||||
|
*
|
||||||
|
* @param world The world.
|
||||||
|
* @param pos The position at the entities feet.
|
||||||
|
* @param entity The entity running on the block.
|
||||||
|
* @return True to prevent vanilla running particles from spawning.
|
||||||
|
*/
|
||||||
|
default boolean addRunningEffects(World world, BlockPos pos, Entity entity)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().addRunningEffects(getBlockState(), world, pos, entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spawn particles for when the block is destroyed. Due to the nature
|
||||||
|
* of how this is invoked, the x/y/z locations are not always guaranteed
|
||||||
|
* to host your block. So be sure to do proper sanity checks before assuming
|
||||||
|
* that the location is this block.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Position to spawn the particle
|
||||||
|
* @param manager A reference to the current particle manager.
|
||||||
|
* @return True to prevent vanilla break particles from spawning.
|
||||||
|
*/
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
default boolean addDestroyEffects(World world, BlockPos pos, ParticleManager manager)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().addDestroyEffects(getBlockState(), world, pos, manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if this block can support the passed in plant, allowing it to be planted and grow.
|
||||||
|
* Some examples:
|
||||||
|
* Reeds check if its a reed, or if its sand/dirt/grass and adjacent to water
|
||||||
|
* Cacti checks if its a cacti, or if its sand
|
||||||
|
* Nether types check for soul sand
|
||||||
|
* Crops check for tilled soil
|
||||||
|
* Caves check if it's a solid surface
|
||||||
|
* Plains check if its grass or dirt
|
||||||
|
* Water check if its still water
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param facing The direction relative to the given position the plant wants to be, typically its UP
|
||||||
|
* @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)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().canSustainPlant(getBlockState(), world, pos, facing, plantable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a plant grows on this block, only implemented for saplings using the WorldGen*Trees classes right now.
|
||||||
|
* Modder may implement this for custom plants.
|
||||||
|
* This does not use ForgeDirection, because large/huge trees can be located in non-representable direction,
|
||||||
|
* so the source location is specified.
|
||||||
|
* Currently this just changes the block to dirt if it was grass.
|
||||||
|
*
|
||||||
|
* Note: This happens DURING the generation, the generation may not be complete when this is called.
|
||||||
|
*
|
||||||
|
* @param world Current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @param source Source plant's position in world
|
||||||
|
*/
|
||||||
|
default void onPlantGrow(World world, BlockPos pos, BlockPos source)
|
||||||
|
{
|
||||||
|
getBlockState().getBlock().onPlantGrow(getBlockState(), world, pos, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this soil is fertile, typically this means that growth rates
|
||||||
|
* of plants on this soil will be slightly sped up.
|
||||||
|
* Only vanilla case is tilledField when it is within range of water.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @return True if the soil should be considered fertile.
|
||||||
|
*/
|
||||||
|
default boolean isFertile(IWorldReader 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.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @param beacon Beacon position in world
|
||||||
|
* @return True, to support the beacon, and make it active with this block.
|
||||||
|
*/
|
||||||
|
default boolean isBeaconBase(IWorldReader world, BlockPos pos, BlockPos beacon)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().isBeaconBase(getBlockState(), world, pos, beacon);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Gathers how much experience this block drops when broken.
|
||||||
|
*
|
||||||
|
* @param world The world
|
||||||
|
* @param pos Block position
|
||||||
|
* @param fortune
|
||||||
|
* @return Amount of XP from breaking this block.
|
||||||
|
*/
|
||||||
|
default int getExpDrop(IWorldReader world, BlockPos pos, int fortune)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().getExpDrop(getBlockState(), world, pos, fortune);
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean rotateBlock(IWorld world, BlockPos pos, EnumFacing axis)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().rotateBlock(getBlockState(), world, pos, axis);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the amount of enchanting power this block can provide to an enchanting table.
|
||||||
|
* @param world The World
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @return The amount of enchanting power this block produces.
|
||||||
|
*/
|
||||||
|
default float getEnchantPowerBonus(IWorldReader world, BlockPos pos)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().getEnchantPowerBonus(getBlockState(), world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean recolorBlock(IWorld world, BlockPos pos, EnumFacing facing, EnumDyeColor color)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().recolorBlock(getBlockState(), world, pos, facing, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a tile entity on a side of this block changes is created or is destroyed.
|
||||||
|
* @param world The world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @param neighbor Block position of neighbor
|
||||||
|
*/
|
||||||
|
default void onNeighborChange(IWorldReader world, BlockPos pos, BlockPos neighbor)
|
||||||
|
{
|
||||||
|
getBlockState().getBlock().onNeighborChange(getBlockState(), world, pos, neighbor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called on an Observer block whenever an update for an Observer is received.
|
||||||
|
*
|
||||||
|
* @param observerState The Observer block's state.
|
||||||
|
* @param world The current world.
|
||||||
|
* @param pos The Observer block's position.
|
||||||
|
* @param changed The updated block.
|
||||||
|
* @param changedPos The updated block's position.
|
||||||
|
*/
|
||||||
|
default void observedNeighborChange(World world, BlockPos pos, Block changed, BlockPos changedPos)
|
||||||
|
{
|
||||||
|
getBlockState().getBlock().observedNeighborChange(getBlockState(), world, pos, changed, changedPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to determine whether to allow the a block to handle its own indirect power rather than using the default rules.
|
||||||
|
* @param world The world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @param side The INPUT side of the block to be powered - ie the opposite of this block's output side
|
||||||
|
* @return Whether Block#isProvidingWeakPower should be called when determining indirect power
|
||||||
|
*/
|
||||||
|
default boolean shouldCheckWeakPower(IWorldReader world, BlockPos pos, EnumFacing side)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().shouldCheckWeakPower(getBlockState(), world, pos, side);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this block should be notified of weak changes.
|
||||||
|
* Weak changes are changes 1 block away through a solid block.
|
||||||
|
* Similar to comparators.
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos Block position in world
|
||||||
|
* @return true To be notified of changes
|
||||||
|
*/
|
||||||
|
default boolean getWeakChanges(IWorldReader world, BlockPos pos)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().getWeakChanges(getBlockState(), world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries the class of tool required to harvest this block, if null is returned
|
||||||
|
* we assume that anything can harvest this block.
|
||||||
|
*/
|
||||||
|
default ToolType getHarvestTool()
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().getHarvestTool(getBlockState());
|
||||||
|
}
|
||||||
|
|
||||||
|
default int getHarvestLevel()
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().getHarvestLevel(getBlockState());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the specified tool type is efficient on this block,
|
||||||
|
* meaning that it digs at full speed.
|
||||||
|
*/
|
||||||
|
default boolean isToolEffective(ToolType tool)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().isToolEffective(getBlockState(), tool);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can return IExtendedBlockState
|
||||||
|
*/
|
||||||
|
default IBlockState getExtendedState(IBlockReader world, BlockPos pos)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().getExtendedState(getBlockState(), world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the entity is inside this block, may be used to determined if the entity can breathing,
|
||||||
|
* display material overlays, or if the entity can swim inside a block.
|
||||||
|
*
|
||||||
|
* @param world that is being tested.
|
||||||
|
* @param pos position thats being tested.
|
||||||
|
* @param entity that is being tested.
|
||||||
|
* @param yToTest, primarily for testingHead, which sends the the eye level of the entity, other wise it sends a y that can be tested vs liquid height.
|
||||||
|
* @param material to test for.
|
||||||
|
* @param testingHead when true, its testing the entities head for vision, breathing ect... otherwise its testing the body, for swimming and movement adjustment.
|
||||||
|
* @return null for default behavior, true if the entity is within the material, false if it was not.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default Boolean isEntityInsideMaterial(IWorldReader world, BlockPos pos, Entity entity, double yToTest, Material material, boolean testingHead)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().isEntityInsideMaterial(getBlockState(), world, pos, entity, yToTest, material, testingHead);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when boats or fishing hooks are inside the block to check if they are inside
|
||||||
|
* the material requested.
|
||||||
|
*
|
||||||
|
* @param world world that is being tested.
|
||||||
|
* @param pos block thats being tested.
|
||||||
|
* @param boundingBox box to test, generally the bounds of an entity that are besting tested.
|
||||||
|
* @param material to check for.
|
||||||
|
* @return null for default behavior, true if the box is within the material, false if it was not.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default Boolean isAABBInsideMaterial(IWorldReader world, BlockPos pos, AxisAlignedBB boundingBox, Material material)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().isAABBInsideMaterial(getBlockState(), world, pos, boundingBox, material);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when entities are moving to check if they are inside a liquid
|
||||||
|
*
|
||||||
|
* @param world world that is being tested.
|
||||||
|
* @param pos block thats being tested.
|
||||||
|
* @param boundingBox box to test, generally the bounds of an entity that are besting tested.
|
||||||
|
* @return null for default behavior, true if the box is within the material, false if it was not.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default Boolean isAABBInsideLiquid(IWorldReader world, BlockPos pos, AxisAlignedBB boundingBox)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().isAABBInsideLiquid(getBlockState(), world, pos, boundingBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries if this block should render in a given layer.
|
||||||
|
* ISmartBlockModel can use {@link net.minecraftforge.client.MinecraftForgeClient#getRenderLayer()} to alter their model based on layer.
|
||||||
|
*/
|
||||||
|
default boolean canRenderInLayer(BlockRenderLayer layer)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().canRenderInLayer(getBlockState(), layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sensitive version of getSoundType
|
||||||
|
* @param world The world
|
||||||
|
* @param pos The position. Note that the world may not necessarily have {@code state} here!
|
||||||
|
* @param entity The entity that is breaking/stepping on/placing/hitting/falling on this block, or null if no entity is in this context
|
||||||
|
* @return A SoundType to use
|
||||||
|
*/
|
||||||
|
default SoundType getSoundType(IWorldReader world, BlockPos pos, @Nullable Entity entity)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().getSoundType(getBlockState(), world, pos, entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param world The world
|
||||||
|
* @param pos The position of this state
|
||||||
|
* @param beaconPos The position of the beacon
|
||||||
|
* @return A float RGB [0.0, 1.0] array to be averaged with a beacon's existing beam color, or null to do nothing to the beam
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default float[] getBeaconColorMultiplier(IWorldReader world, BlockPos pos, BlockPos beacon)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().getBeaconColorMultiplier(getBlockState(), world, pos, beacon);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this to change the fog color used when the entity is "inside" a material.
|
||||||
|
* Vec3d is used here as "r/g/b" 0 - 1 values.
|
||||||
|
*
|
||||||
|
* @param world The world.
|
||||||
|
* @param pos The position at the entity viewport.
|
||||||
|
* @param entity the entity
|
||||||
|
* @param originalColor The current fog color, You are not expected to use this, Return as the default if applicable.
|
||||||
|
* @return The new fog color.
|
||||||
|
*/
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
default Vec3d getFogColor(IWorldReader world, BlockPos pos, Entity entity, Vec3d originalColor, float partialTicks)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().getFogColor(getBlockState(), world, pos, entity, originalColor, partialTicks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to determine the state 'viewed' by an entity (see
|
||||||
|
* {@link ActiveRenderInfo#getBlockStateAtEntityViewpoint(World, Entity, float)}).
|
||||||
|
* Can be used by fluid blocks to determine if the viewpoint is within the fluid or not.
|
||||||
|
*
|
||||||
|
* @param world the world
|
||||||
|
* @param pos the position
|
||||||
|
* @param viewpoint the viewpoint
|
||||||
|
* @return the block state that should be 'seen'
|
||||||
|
*/
|
||||||
|
default IBlockState getStateAtViewpoint(IWorldReader world, BlockPos pos, Vec3d viewpoint)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().getStateAtViewpoint(getBlockState(), world, pos, viewpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** //TODO: Re-Evaluate
|
||||||
|
* Gets the {@link IBlockState} to place
|
||||||
|
* @param world The world the block is being placed in
|
||||||
|
* @param pos The position the block is being placed at
|
||||||
|
* @param facing The side the block is being placed on
|
||||||
|
* @param hitX The X coordinate of the hit vector
|
||||||
|
* @param hitY The Y coordinate of the hit vector
|
||||||
|
* @param hitZ The Z coordinate of the hit vector
|
||||||
|
* @param meta The metadata of {@link ItemStack} as processed by {@link Item#getMetadata(int)}
|
||||||
|
* @param placer The entity placing the block
|
||||||
|
* @param hand The player hand used to place this block
|
||||||
|
* @return The state to be placed in the world
|
||||||
|
*/
|
||||||
|
default IBlockState getStateForPlacement(EnumFacing facing, IBlockState state2, IWorld world, BlockPos pos1, BlockPos pos2, EnumHand hand)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().getStateForPlacement(getBlockState(), facing, state2, world, pos1, pos2, hand);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if another block can connect to this block
|
||||||
|
*
|
||||||
|
* @param world The current world
|
||||||
|
* @param pos The position of this block
|
||||||
|
* @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)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().canBeConnectedTo(getBlockState(), world, pos, facing);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the {@code PathNodeType} for this block. Return {@code null} for vanilla behavior.
|
||||||
|
*
|
||||||
|
* @return the PathNodeType
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default PathNodeType getAiPathNodeType(IWorldReader world, BlockPos pos)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().getAiPathNodeType(getBlockState(), world, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param blockState The state for this block
|
||||||
|
* @param world The world this block is in
|
||||||
|
* @param pos The position of this block
|
||||||
|
* @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)
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().doesSideBlockChestOpening(getBlockState(), world, pos, side);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param state The state
|
||||||
|
* @return true if the block is sticky block which used for pull or push adjacent blocks (use by piston)
|
||||||
|
*/
|
||||||
|
default boolean isStickyBlock()
|
||||||
|
{
|
||||||
|
return getBlockState().getBlock().isStickyBlock(getBlockState());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,14 +1,18 @@
|
||||||
package net.minecraftforge.common.extensions;
|
package net.minecraftforge.common.extensions;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityLiving;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.ai.attributes.AttributeModifier;
|
import net.minecraft.entity.ai.attributes.AttributeModifier;
|
||||||
import net.minecraft.entity.passive.EntityHorse;
|
import net.minecraft.entity.passive.EntityHorse;
|
||||||
|
import net.minecraft.entity.passive.HorseArmorType;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
import net.minecraft.init.Items;
|
import net.minecraft.init.Items;
|
||||||
|
@ -30,6 +34,7 @@ import net.minecraft.world.GameType;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.common.ToolType;
|
||||||
|
|
||||||
// TODO review most of the methods in this "patch"
|
// TODO review most of the methods in this "patch"
|
||||||
public interface IForgeItem
|
public interface IForgeItem
|
||||||
|
@ -43,6 +48,7 @@ public interface IForgeItem
|
||||||
/**
|
/**
|
||||||
* ItemStack sensitive version of getItemAttributeModifiers
|
* ItemStack sensitive version of getItemAttributeModifiers
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
default Multimap<String, AttributeModifier> getAttributeModifiers(EntityEquipmentSlot slot, ItemStack stack)
|
default Multimap<String, AttributeModifier> getAttributeModifiers(EntityEquipmentSlot slot, ItemStack stack)
|
||||||
{
|
{
|
||||||
return getItem().getItemAttributeModifiers(slot);
|
return getItem().getItemAttributeModifiers(slot);
|
||||||
|
@ -87,7 +93,7 @@ public interface IForgeItem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by CraftingManager to determine if an item is reparable.
|
* Called by CraftingManager to determine if an item is reparable.
|
||||||
*
|
*
|
||||||
* @return True if reparable
|
* @return True if reparable
|
||||||
*/
|
*/
|
||||||
boolean isRepairable();
|
boolean isRepairable();
|
||||||
|
@ -114,7 +120,7 @@ public interface IForgeItem
|
||||||
/**
|
/**
|
||||||
* Override this method to decide what to do with the NBT data received from
|
* Override this method to decide what to do with the NBT data received from
|
||||||
* getNBTShareTag().
|
* getNBTShareTag().
|
||||||
*
|
*
|
||||||
* @param stack The stack that received NBT
|
* @param stack The stack that received NBT
|
||||||
* @param nbt Received NBT, can be null
|
* @param nbt Received NBT, can be null
|
||||||
*/
|
*/
|
||||||
|
@ -141,7 +147,7 @@ public interface IForgeItem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called each tick while using an item.
|
* Called each tick while using an item.
|
||||||
*
|
*
|
||||||
* @param stack The Item being used
|
* @param stack The Item being used
|
||||||
* @param player The Player using the item
|
* @param player The Player using the item
|
||||||
* @param count The amount of time in tick the item has been used for
|
* @param count The amount of time in tick the item has been used for
|
||||||
|
@ -184,10 +190,11 @@ public interface IForgeItem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ItemStack sensitive version of hasContainerItem
|
* ItemStack sensitive version of hasContainerItem
|
||||||
*
|
*
|
||||||
* @param stack The current item stack
|
* @param stack The current item stack
|
||||||
* @return True if this item has a 'container'
|
* @return True if this item has a 'container'
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
default boolean hasContainerItem(ItemStack stack)
|
default boolean hasContainerItem(ItemStack stack)
|
||||||
{
|
{
|
||||||
return getItem().hasContainerItem();
|
return getItem().hasContainerItem();
|
||||||
|
@ -220,7 +227,7 @@ public interface IForgeItem
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function should return a new entity to replace the dropped item.
|
* This function should return a new entity to replace the dropped item.
|
||||||
* Returning null here will not kill the EntityItem and will leave it to
|
* Returning null here will not kill the EntityItem and will leave it to
|
||||||
|
@ -476,6 +483,7 @@ public interface IForgeItem
|
||||||
* @param stack The itemstack that is damaged
|
* @param stack The itemstack that is damaged
|
||||||
* @return the damage value
|
* @return the damage value
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
default int getMaxDamage(ItemStack stack)
|
default int getMaxDamage(ItemStack stack)
|
||||||
{
|
{
|
||||||
return getItem().getMaxDamage();
|
return getItem().getMaxDamage();
|
||||||
|
@ -484,7 +492,7 @@ public interface IForgeItem
|
||||||
/**
|
/**
|
||||||
* Return if this itemstack is damaged. Note only called if
|
* Return if this itemstack is damaged. Note only called if
|
||||||
* {@link #isDamageable()} is true.
|
* {@link #isDamageable()} is true.
|
||||||
*
|
*
|
||||||
* @param stack the stack
|
* @param stack the stack
|
||||||
* @return if the stack is damaged
|
* @return if the stack is damaged
|
||||||
*/
|
*/
|
||||||
|
@ -496,7 +504,7 @@ public interface IForgeItem
|
||||||
/**
|
/**
|
||||||
* Set the damage for this itemstack. Note, this method is responsible for zero
|
* Set the damage for this itemstack. Note, this method is responsible for zero
|
||||||
* checking.
|
* checking.
|
||||||
*
|
*
|
||||||
* @param stack the stack
|
* @param stack the stack
|
||||||
* @param damage the new damage value
|
* @param damage the new damage value
|
||||||
*/
|
*/
|
||||||
|
@ -512,7 +520,7 @@ public interface IForgeItem
|
||||||
* a block with this item. Also checked from
|
* a block with this item. Also checked from
|
||||||
* {@link net.minecraftforge.common.ForgeHooks#onBlockBreakEvent(World, GameType, EntityPlayerMP, BlockPos)
|
* {@link net.minecraftforge.common.ForgeHooks#onBlockBreakEvent(World, GameType, EntityPlayerMP, BlockPos)
|
||||||
* ForgeHooks.onBlockBreakEvent()} to prevent sending an event.
|
* ForgeHooks.onBlockBreakEvent()} to prevent sending an event.
|
||||||
*
|
*
|
||||||
* @return true if the given player can destroy specified block in creative mode
|
* @return true if the given player can destroy specified block in creative mode
|
||||||
* with this item
|
* with this item
|
||||||
*/
|
*/
|
||||||
|
@ -523,12 +531,12 @@ public interface IForgeItem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ItemStack sensitive version of {@link #canHarvestBlock(IBlockState)}
|
* ItemStack sensitive version of {@link #canHarvestBlock(IBlockState)}
|
||||||
*
|
*
|
||||||
* @param state The block trying to harvest
|
|
||||||
* @param stack The itemstack used to harvest the block
|
* @param stack The itemstack used to harvest the block
|
||||||
|
* @param state The block trying to harvest
|
||||||
* @return true if can harvest the block
|
* @return true if can harvest the block
|
||||||
*/
|
*/
|
||||||
default boolean canHarvestBlock(IBlockState state, ItemStack stack)
|
default boolean canHarvestBlock(ItemStack stack, IBlockState state)
|
||||||
{
|
{
|
||||||
return getItem().canHarvestBlock(state);
|
return getItem().canHarvestBlock(state);
|
||||||
}
|
}
|
||||||
|
@ -540,12 +548,13 @@ public interface IForgeItem
|
||||||
* @param stack The ItemStack
|
* @param stack The ItemStack
|
||||||
* @return The maximum number this item can be stacked to
|
* @return The maximum number this item can be stacked to
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
default int getItemStackLimit(ItemStack stack)
|
default int getItemStackLimit(ItemStack stack)
|
||||||
{
|
{
|
||||||
return getItem().getItemStackLimit();
|
return getItem().getItemStackLimit();
|
||||||
}
|
}
|
||||||
|
|
||||||
java.util.Set<String> getToolClasses(ItemStack stack);
|
Set<ToolType> getToolTypes(ItemStack stack);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queries the harvest level of this item stack for the specified tool class,
|
* Queries the harvest level of this item stack for the specified tool class,
|
||||||
|
@ -557,7 +566,7 @@ public interface IForgeItem
|
||||||
* @param blockState The block to harvest
|
* @param blockState The block to harvest
|
||||||
* @return Harvest level, or -1 if not the specified tool type.
|
* @return Harvest level, or -1 if not the specified tool type.
|
||||||
*/
|
*/
|
||||||
int getHarvestLevel(ItemStack stack, String toolClass, @Nullable EntityPlayer player, @Nullable IBlockState blockState);
|
int getHarvestLevel(ItemStack stack, ToolType tool, @Nullable EntityPlayer player, @Nullable IBlockState blockState);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ItemStack sensitive version of getItemEnchantability
|
* ItemStack sensitive version of getItemEnchantability
|
||||||
|
@ -578,7 +587,7 @@ public interface IForgeItem
|
||||||
* {@link net.minecraft.enchantment.Enchantment#canApplyAtEnchantingTable(ItemStack)};
|
* {@link net.minecraft.enchantment.Enchantment#canApplyAtEnchantingTable(ItemStack)};
|
||||||
* check the individual implementation for reference. By default this will check
|
* check the individual implementation for reference. By default this will check
|
||||||
* if the enchantment type is valid for this item type.
|
* if the enchantment type is valid for this item type.
|
||||||
*
|
*
|
||||||
* @param stack the item stack to be enchanted
|
* @param stack the item stack to be enchanted
|
||||||
* @param enchantment the enchantment to be applied
|
* @param enchantment the enchantment to be applied
|
||||||
* @return true if the enchantment can be applied to this item
|
* @return true if the enchantment can be applied to this item
|
||||||
|
@ -590,7 +599,7 @@ public interface IForgeItem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this Item can be used as a payment to activate the vanilla beacon.
|
* Whether this Item can be used as a payment to activate the vanilla beacon.
|
||||||
*
|
*
|
||||||
* @param stack the ItemStack
|
* @param stack the ItemStack
|
||||||
* @return true if this Item can be used
|
* @return true if this Item can be used
|
||||||
*/
|
*/
|
||||||
|
@ -601,7 +610,7 @@ public interface IForgeItem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the player switching between these two item stacks
|
* Determine if the player switching between these two item stacks
|
||||||
*
|
*
|
||||||
* @param oldStack The old stack that was equipped
|
* @param oldStack The old stack that was equipped
|
||||||
* @param newStack The new stack
|
* @param newStack The new stack
|
||||||
* @param slotChanged If the current equipped slot was changed, Vanilla does not
|
* @param slotChanged If the current equipped slot was changed, Vanilla does not
|
||||||
|
@ -617,7 +626,7 @@ public interface IForgeItem
|
||||||
/**
|
/**
|
||||||
* Called when the player is mining a block and the item in his hand changes.
|
* Called when the player is mining a block and the item in his hand changes.
|
||||||
* Allows to not reset blockbreaking if only NBT or similar changes.
|
* Allows to not reset blockbreaking if only NBT or similar changes.
|
||||||
*
|
*
|
||||||
* @param oldStack The old stack that was used for mining. Item in players main
|
* @param oldStack The old stack that was used for mining. Item in players main
|
||||||
* hand
|
* hand
|
||||||
* @param newStack The new stack
|
* @param newStack The new stack
|
||||||
|
@ -684,7 +693,7 @@ public interface IForgeItem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can this Item disable a shield
|
* Can this Item disable a shield
|
||||||
*
|
*
|
||||||
* @param stack The ItemStack
|
* @param stack The ItemStack
|
||||||
* @param shield The shield in question
|
* @param shield The shield in question
|
||||||
* @param entity The EntityLivingBase holding the shield
|
* @param entity The EntityLivingBase holding the shield
|
||||||
|
@ -698,7 +707,7 @@ public interface IForgeItem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this Item a shield
|
* Is this Item a shield
|
||||||
*
|
*
|
||||||
* @param stack The ItemStack
|
* @param stack The ItemStack
|
||||||
* @param entity The Entity holding the ItemStack
|
* @param entity The Entity holding the ItemStack
|
||||||
* @return True if the ItemStack is considered a shield
|
* @return True if the ItemStack is considered a shield
|
||||||
|
@ -713,7 +722,7 @@ public interface IForgeItem
|
||||||
* it not act as a fuel. Return -1 to let the default vanilla logic
|
* it not act as a fuel. Return -1 to let the default vanilla logic
|
||||||
* decide.
|
* decide.
|
||||||
*/
|
*/
|
||||||
default int getItemBurnTime(ItemStack itemStack)
|
default int getBurnTime(ItemStack itemStack)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -722,17 +731,17 @@ public interface IForgeItem
|
||||||
* Returns an enum constant of type {@code HorseArmorType}. The returned enum
|
* Returns an enum constant of type {@code HorseArmorType}. The returned enum
|
||||||
* constant will be used to determine the armor value and texture of this item
|
* constant will be used to determine the armor value and texture of this item
|
||||||
* when equipped.
|
* when equipped.
|
||||||
*
|
*
|
||||||
* @param stack the armor stack
|
* @param stack the armor stack
|
||||||
* @return an enum constant of type {@code HorseArmorType}. Return
|
* @return an enum constant of type {@code HorseArmorType}. Return
|
||||||
* HorseArmorType.NONE if this is not horse armor
|
* HorseArmorType.NONE if this is not horse armor
|
||||||
*/
|
*/
|
||||||
default net.minecraft.entity.passive.HorseArmorType getHorseArmorType(ItemStack stack)
|
default HorseArmorType getHorseArmorType(ItemStack stack)
|
||||||
{
|
{
|
||||||
return net.minecraft.entity.passive.HorseArmorType.getByItem(stack.getItem());
|
return HorseArmorType.getByItem(stack.getItem());
|
||||||
}
|
}
|
||||||
|
|
||||||
default String getHorseArmorTexture(net.minecraft.entity.EntityLiving wearer, ItemStack stack)
|
default String getHorseArmorTexture(EntityLiving wearer, ItemStack stack)
|
||||||
{
|
{
|
||||||
return getHorseArmorType(stack).getTextureName();
|
return getHorseArmorType(stack).getTextureName();
|
||||||
}
|
}
|
||||||
|
@ -740,12 +749,12 @@ public interface IForgeItem
|
||||||
/**
|
/**
|
||||||
* Called every tick from {@link EntityHorse#onUpdate()} on the item in the
|
* Called every tick from {@link EntityHorse#onUpdate()} on the item in the
|
||||||
* armor slot.
|
* armor slot.
|
||||||
*
|
*
|
||||||
* @param world the world the horse is in
|
* @param world the world the horse is in
|
||||||
* @param horse the horse wearing this armor
|
* @param horse the horse wearing this armor
|
||||||
* @param armor the armor itemstack
|
* @param armor the armor itemstack
|
||||||
*/
|
*/
|
||||||
default void onHorseArmorTick(World world, net.minecraft.entity.EntityLiving horse, ItemStack armor)
|
default void onHorseArmorTick(World world, EntityLiving horse, ItemStack armor)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,20 @@
|
||||||
package net.minecraftforge.common.extensions;
|
package net.minecraftforge.common.extensions;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraftforge.common.ToolType;
|
||||||
|
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Extension added to ItemStack that bounces to ItemSack sensitive Item methods. Typically this is just for convince.
|
* Extension added to ItemStack that bounces to ItemSack sensitive Item methods. Typically this is just for convince.
|
||||||
*/
|
*/
|
||||||
public interface IForgeItemStack
|
public interface IForgeItemStack extends ICapabilitySerializable<NBTTagCompound>
|
||||||
{
|
{
|
||||||
// Helpers for accessing Item data
|
// Helpers for accessing Item data
|
||||||
default ItemStack getStack()
|
default ItemStack getStack()
|
||||||
|
@ -36,4 +45,33 @@ public interface IForgeItemStack
|
||||||
return getStack().getItem().hasContainerItem(getStack());
|
return getStack().getItem().hasContainerItem(getStack());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the fuel burn time for this itemStack in a furnace. Return 0 to make
|
||||||
|
* it not act as a fuel. Return -1 to let the default vanilla logic
|
||||||
|
* decide.
|
||||||
|
*/
|
||||||
|
default int getBurnTime()
|
||||||
|
{
|
||||||
|
return getStack().getItem().getBurnTime(getStack());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries the harvest level of this item stack for the specified tool class,
|
||||||
|
* Returns -1 if this tool is not of the specified type
|
||||||
|
*
|
||||||
|
* @param stack This item stack instance
|
||||||
|
* @param toolClass Tool Class
|
||||||
|
* @param player The player trying to harvest the given blockstate
|
||||||
|
* @param state The block to harvest
|
||||||
|
* @return Harvest level, or -1 if not the specified tool type.
|
||||||
|
*/
|
||||||
|
default int getHarvestLevel(ToolType tool, @Nullable EntityPlayer player, @Nullable IBlockState state)
|
||||||
|
{
|
||||||
|
return getStack().getItem().getHarvestLevel(getStack(), tool, player, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
default Set<ToolType> getToolTypes() {
|
||||||
|
return getStack().getItem().getToolTypes(getStack());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ public class FakePlayer extends EntityPlayerMP
|
||||||
@Override public void sendStatusMessage(ITextComponent chatComponent, boolean actionBar){}
|
@Override public void sendStatusMessage(ITextComponent chatComponent, boolean actionBar){}
|
||||||
@Override public void sendMessage(ITextComponent component) {}
|
@Override public void sendMessage(ITextComponent component) {}
|
||||||
@Override public void addStat(StatBase par1StatBase, int par2){}
|
@Override public void addStat(StatBase par1StatBase, int par2){}
|
||||||
@Override public void openGui(Object mod, int modGuiId, World world, int x, int y, int z){}
|
//@Override public void openGui(Object mod, int modGuiId, World world, int x, int y, int z){}
|
||||||
@Override public boolean isEntityInvulnerable(DamageSource source){ return true; }
|
@Override public boolean isEntityInvulnerable(DamageSource source){ return true; }
|
||||||
@Override public boolean canAttackPlayer(EntityPlayer player){ return false; }
|
@Override public boolean canAttackPlayer(EntityPlayer player){ return false; }
|
||||||
@Override public void onDeath(DamageSource source){ return; }
|
@Override public void onDeath(DamageSource source){ return; }
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
/*
|
|
||||||
* Minecraft Forge
|
|
||||||
* Copyright (c) 2016-2018.
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation version 2.1
|
|
||||||
* of the License.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
package net.minecraftforge.event;
|
|
||||||
|
|
||||||
import net.minecraft.command.CommandHandler;
|
|
||||||
import net.minecraftforge.client.ClientCommandHandler;
|
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
|
||||||
import net.minecraftforge.eventbus.api.Cancelable;
|
|
||||||
import net.minecraftforge.eventbus.api.Event;
|
|
||||||
import net.minecraft.command.ICommand;
|
|
||||||
import net.minecraft.command.ICommandSender;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CommandEvent is fired whenever a command is scheduled to be executed.
|
|
||||||
* This event is fired during the invocation of {@link CommandHandler#executeCommand(ICommandSender, String)}
|
|
||||||
* and {@link ClientCommandHandler#executeCommand(ICommandSender, String)}. <br>
|
|
||||||
* <br>
|
|
||||||
* {@link #command} contains the instance of ICommand which is representative of the currently executing command.<br>
|
|
||||||
* {@link #sender} contains the instance of ICommandSender for the given command sender.<br>
|
|
||||||
* {@link #parameters} contains the arguments passed for the command execution.<br>
|
|
||||||
* {@link #exception} begins null, but can be populated with an exception to be thrown within the command.<br>
|
|
||||||
* <br>
|
|
||||||
* This event is {@link Cancelable}. <br>
|
|
||||||
* If the event is canceled, the execution of the command does not occur.<br>
|
|
||||||
* <br>
|
|
||||||
* This event does not have a result. {@link HasResult}<br>
|
|
||||||
* <br>
|
|
||||||
* This event is fired on the {@link MinecraftForge#EVENT_BUS}.<br>
|
|
||||||
**/
|
|
||||||
@Cancelable
|
|
||||||
public class CommandEvent extends net.minecraftforge.eventbus.api.Event
|
|
||||||
{
|
|
||||||
|
|
||||||
private final ICommand command;
|
|
||||||
private final ICommandSender sender;
|
|
||||||
private String[] parameters;
|
|
||||||
private Throwable exception;
|
|
||||||
|
|
||||||
public CommandEvent(ICommand command, ICommandSender sender, String[] parameters)
|
|
||||||
{
|
|
||||||
this.command = command;
|
|
||||||
this.sender = sender;
|
|
||||||
this.setParameters(parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ICommand getCommand() { return command; }
|
|
||||||
public ICommandSender getSender() { return sender; }
|
|
||||||
public String[] getParameters() { return parameters; }
|
|
||||||
public void setParameters(String[] parameters) { this.parameters = parameters; }
|
|
||||||
public Throwable getException() { return exception; }
|
|
||||||
public void setException(Throwable exception) { this.exception = exception; }
|
|
||||||
}
|
|
|
@ -89,7 +89,6 @@ import net.minecraftforge.event.entity.EntityMountEvent;
|
||||||
import net.minecraftforge.event.entity.EntityStruckByLightningEvent;
|
import net.minecraftforge.event.entity.EntityStruckByLightningEvent;
|
||||||
import net.minecraftforge.event.entity.PlaySoundAtEntityEvent;
|
import net.minecraftforge.event.entity.PlaySoundAtEntityEvent;
|
||||||
import net.minecraftforge.event.entity.ProjectileImpactEvent;
|
import net.minecraftforge.event.entity.ProjectileImpactEvent;
|
||||||
import net.minecraftforge.event.entity.ThrowableImpactEvent;
|
|
||||||
import net.minecraftforge.event.entity.item.ItemExpireEvent;
|
import net.minecraftforge.event.entity.item.ItemExpireEvent;
|
||||||
import net.minecraftforge.event.entity.living.AnimalTameEvent;
|
import net.minecraftforge.event.entity.living.AnimalTameEvent;
|
||||||
import net.minecraftforge.event.entity.living.LivingDestroyBlockEvent;
|
import net.minecraftforge.event.entity.living.LivingDestroyBlockEvent;
|
||||||
|
@ -127,7 +126,6 @@ import net.minecraftforge.event.world.BlockEvent.PlaceEvent;
|
||||||
import net.minecraftforge.event.world.ExplosionEvent;
|
import net.minecraftforge.event.world.ExplosionEvent;
|
||||||
import net.minecraftforge.event.world.GetCollisionBoxesEvent;
|
import net.minecraftforge.event.world.GetCollisionBoxesEvent;
|
||||||
import net.minecraftforge.event.world.WorldEvent;
|
import net.minecraftforge.event.world.WorldEvent;
|
||||||
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
|
|
||||||
import net.minecraftforge.eventbus.api.Event;
|
import net.minecraftforge.eventbus.api.Event;
|
||||||
import net.minecraftforge.eventbus.api.Event.Result;
|
import net.minecraftforge.eventbus.api.Event.Result;
|
||||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||||
|
@ -180,27 +178,6 @@ public class ForgeEventFactory
|
||||||
MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(player, stack, hand));
|
MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(player, stack, hand));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated use {@link #canEntitySpawn(EntityLiving, World, float, float, float, MobSpawnerBaseLogic)} instead
|
|
||||||
*/
|
|
||||||
@Deprecated // TODO remove in 1.13
|
|
||||||
public static Result canEntitySpawn(EntityLiving entity, World world, float x, float y, float z)
|
|
||||||
{
|
|
||||||
return canEntitySpawn(entity, world, x, y, z, true);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @deprecated use {@link #canEntitySpawn(EntityLiving, World, float, float, float, MobSpawnerBaseLogic)} instead
|
|
||||||
*/
|
|
||||||
@Deprecated // Still used in base game for non-spawner spawns, which is safe
|
|
||||||
public static Result canEntitySpawn(EntityLiving entity, World world, float x, float y, float z, boolean isSpawner)
|
|
||||||
{
|
|
||||||
if (entity == null)
|
|
||||||
return Result.DEFAULT;
|
|
||||||
LivingSpawnEvent.CheckSpawn event = new LivingSpawnEvent.CheckSpawn(entity, world, x, y, z, isSpawner); // TODO: replace isSpawner with null in 1.13
|
|
||||||
MinecraftForge.EVENT_BUS.post(event);
|
|
||||||
return event.getResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Result canEntitySpawn(EntityLiving entity, World world, float x, float y, float z, MobSpawnerBaseLogic spawner)
|
public static Result canEntitySpawn(EntityLiving entity, World world, float x, float y, float z, MobSpawnerBaseLogic spawner)
|
||||||
{
|
{
|
||||||
if (entity == null)
|
if (entity == null)
|
||||||
|
@ -223,32 +200,6 @@ public class ForgeEventFactory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use {@link #canEntitySpawnSpawner(EntityLiving, World, float, float, float, MobSpawnerBaseLogic)}
|
|
||||||
*/
|
|
||||||
@Deprecated // TODO remove in 1.13
|
|
||||||
public static boolean canEntitySpawnSpawner(EntityLiving entity, World world, float x, float y, float z)
|
|
||||||
{
|
|
||||||
Result result = canEntitySpawn(entity, world, x, y, z, true);
|
|
||||||
if (result == Result.DEFAULT)
|
|
||||||
{
|
|
||||||
return entity.getCanSpawnHere() && entity.isNotColliding(); // vanilla logic
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return result == Result.ALLOW;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use {@link #canEntitySpawnSpawner(EntityLiving, World, float, float, float, MobSpawnerBaseLogic)}
|
|
||||||
*/
|
|
||||||
@Deprecated // Still used in base game for non-spawner spawns, which is safe
|
|
||||||
public static boolean doSpecialSpawn(EntityLiving entity, World world, float x, float y, float z)
|
|
||||||
{
|
|
||||||
return MinecraftForge.EVENT_BUS.post(new LivingSpawnEvent.SpecialSpawn(entity, world, x, y, z, null));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean doSpecialSpawn(EntityLiving entity, World world, float x, float y, float z, MobSpawnerBaseLogic spawner)
|
public static boolean doSpecialSpawn(EntityLiving entity, World world, float x, float y, float z, MobSpawnerBaseLogic spawner)
|
||||||
{
|
{
|
||||||
return MinecraftForge.EVENT_BUS.post(new LivingSpawnEvent.SpecialSpawn(entity, world, x, y, z, spawner));
|
return MinecraftForge.EVENT_BUS.post(new LivingSpawnEvent.SpecialSpawn(entity, world, x, y, z, spawner));
|
||||||
|
@ -261,21 +212,10 @@ public class ForgeEventFactory
|
||||||
return event.getResult();
|
return event.getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getItemBurnTime(@Nonnull ItemStack itemStack)
|
public static int getItemBurnTime(@Nonnull ItemStack itemStack, int burnTime)
|
||||||
{
|
{
|
||||||
Item item = itemStack.getItem();
|
|
||||||
int burnTime = item.getItemBurnTime(itemStack);
|
|
||||||
FurnaceFuelBurnTimeEvent event = new FurnaceFuelBurnTimeEvent(itemStack, burnTime);
|
FurnaceFuelBurnTimeEvent event = new FurnaceFuelBurnTimeEvent(itemStack, burnTime);
|
||||||
MinecraftForge.EVENT_BUS.post(event);
|
MinecraftForge.EVENT_BUS.post(event);
|
||||||
if (event.getBurnTime() < 0)
|
|
||||||
{
|
|
||||||
// legacy handling
|
|
||||||
int fuelValue = GameRegistry.getFuelValueLegacy(itemStack);
|
|
||||||
if (fuelValue > 0)
|
|
||||||
{
|
|
||||||
return fuelValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return event.getBurnTime();
|
return event.getBurnTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,9 +333,7 @@ public class ForgeEventFactory
|
||||||
|
|
||||||
public static void firePlayerLoadingEvent(EntityPlayer player, IPlayerFileData playerFileData, String uuidString)
|
public static void firePlayerLoadingEvent(EntityPlayer player, IPlayerFileData playerFileData, String uuidString)
|
||||||
{
|
{
|
||||||
SaveHandler sh = (SaveHandler) playerFileData;
|
MinecraftForge.EVENT_BUS.post(new PlayerEvent.LoadFromFile(player, ((SaveHandler)playerFileData).playersDirectory, uuidString));
|
||||||
File dir = sh.getPlayersDirectory();
|
|
||||||
MinecraftForge.EVENT_BUS.post(new PlayerEvent.LoadFromFile(player, dir, uuidString));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -624,13 +562,13 @@ public class ForgeEventFactory
|
||||||
{
|
{
|
||||||
return MinecraftForge.EVENT_BUS.post(new RenderBlockOverlayEvent(player, renderPartialTicks, type, block, pos));
|
return MinecraftForge.EVENT_BUS.post(new RenderBlockOverlayEvent(player, renderPartialTicks, type, block, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static <T extends ICapabilityProvider> CapabilityDispatcher gatherCapabilities(Class<? extends T> type, T provider)
|
public static <T extends ICapabilityProvider> CapabilityDispatcher gatherCapabilities(Class<? extends T> type, T provider)
|
||||||
{
|
{
|
||||||
return gatherCapabilities(type, provider, null);
|
return gatherCapabilities(type, provider, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Nullable
|
@Nullable
|
||||||
public static <T extends ICapabilityProvider> CapabilityDispatcher gatherCapabilities(Class<? extends T> type, T provider, @Nullable ICapabilityProvider parent)
|
public static <T extends ICapabilityProvider> CapabilityDispatcher gatherCapabilities(Class<? extends T> type, T provider, @Nullable ICapabilityProvider parent)
|
||||||
|
@ -705,9 +643,7 @@ public class ForgeEventFactory
|
||||||
|
|
||||||
public static boolean onProjectileImpact(EntityThrowable throwable, RayTraceResult ray)
|
public static boolean onProjectileImpact(EntityThrowable throwable, RayTraceResult ray)
|
||||||
{
|
{
|
||||||
boolean oldEvent = MinecraftForge.EVENT_BUS.post(new ThrowableImpactEvent(throwable, ray));
|
return MinecraftForge.EVENT_BUS.post(new ProjectileImpactEvent.Throwable(throwable, ray));
|
||||||
boolean newEvent = MinecraftForge.EVENT_BUS.post(new ProjectileImpactEvent.Throwable(throwable, ray));
|
|
||||||
return oldEvent || newEvent; // TODO: clean up when old event is removed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean onReplaceBiomeBlocks(IChunkGenerator gen, int x, int z, ChunkPrimer primer, World world)
|
public static boolean onReplaceBiomeBlocks(IChunkGenerator gen, int x, int z, ChunkPrimer primer, World world)
|
||||||
|
|
|
@ -23,13 +23,12 @@ import javax.annotation.Nullable;
|
||||||
import net.minecraft.tileentity.MobSpawnerBaseLogic;
|
import net.minecraft.tileentity.MobSpawnerBaseLogic;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.event.ForgeEventFactory;
|
import net.minecraftforge.event.ForgeEventFactory;
|
||||||
import net.minecraftforge.eventbus.api.Cancelable;
|
|
||||||
import net.minecraftforge.eventbus.api.Event;
|
import net.minecraftforge.eventbus.api.Event;
|
||||||
import net.minecraft.entity.EntityLiving;
|
import net.minecraft.entity.EntityLiving;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LivingSpawnEvent is fired for any events associated with Living Enttnies spawn status. <br>
|
* LivingSpawnEvent is fired for any events associated with Living Entities spawn status. <br>
|
||||||
* If a method utilizes this {@link Event} as its parameter, the method will
|
* If a method utilizes this {@link Event} as its parameter, the method will
|
||||||
* receive every child event of this class.<br>
|
* receive every child event of this class.<br>
|
||||||
* <br>
|
* <br>
|
||||||
|
@ -72,7 +71,6 @@ public class LivingSpawnEvent extends LivingEvent
|
||||||
@HasResult
|
@HasResult
|
||||||
public static class CheckSpawn extends LivingSpawnEvent
|
public static class CheckSpawn extends LivingSpawnEvent
|
||||||
{
|
{
|
||||||
private final boolean isSpawner; // TODO: remove in 1.13
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final MobSpawnerBaseLogic spawner;
|
private final MobSpawnerBaseLogic spawner;
|
||||||
|
|
||||||
|
@ -90,42 +88,12 @@ public class LivingSpawnEvent extends LivingEvent
|
||||||
public CheckSpawn(EntityLiving entity, World world, float x, float y, float z, @Nullable MobSpawnerBaseLogic spawner)
|
public CheckSpawn(EntityLiving entity, World world, float x, float y, float z, @Nullable MobSpawnerBaseLogic spawner)
|
||||||
{
|
{
|
||||||
super(entity, world, x, y, z);
|
super(entity, world, x, y, z);
|
||||||
this.isSpawner = spawner != null;
|
|
||||||
this.spawner = spawner;
|
this.spawner = spawner;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use {@link CheckSpawn##CheckSpawn(EntityLiving, World, float, float, float, MobSpawnerBaseLogic)}
|
|
||||||
* with a spawner instance, or null if not a spawner
|
|
||||||
* CheckSpawn is fired when an Entity is about to be spawned.
|
|
||||||
* @param entity the spawning entity
|
|
||||||
* @param world the world to spawn in
|
|
||||||
* @param x x coordinate
|
|
||||||
* @param y y coordinate
|
|
||||||
* @param z z coordinate
|
|
||||||
* @param isSpawner true if this spawn is done by a MobSpawner,
|
|
||||||
* false if it this spawn is coming from a WorldSpawner
|
|
||||||
*/
|
|
||||||
@Deprecated // TODO: Remove in 1.13
|
|
||||||
public CheckSpawn(EntityLiving entity, World world, float x, float y, float z, boolean isSpawner)
|
|
||||||
{
|
|
||||||
super(entity, world, x, y, z);
|
|
||||||
this.isSpawner = isSpawner;
|
|
||||||
spawner = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use {@link CheckSpawn#CheckSpawn(EntityLiving, World, float, float, float, MobSpawnerBaseLogic)} instead
|
|
||||||
*/
|
|
||||||
@Deprecated // TODO: Remove in 1.13
|
|
||||||
public CheckSpawn(EntityLiving entity, World world, float x, float y, float z)
|
|
||||||
{
|
|
||||||
this(entity, world, x, y, z, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSpawner()
|
public boolean isSpawner()
|
||||||
{
|
{
|
||||||
return isSpawner; // TODO: replace with spawner null check in 1.13
|
return spawner != null; // TODO: replace with spawner null check in 1.13
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -154,17 +122,6 @@ public class LivingSpawnEvent extends LivingEvent
|
||||||
@Nullable
|
@Nullable
|
||||||
private final MobSpawnerBaseLogic spawner;
|
private final MobSpawnerBaseLogic spawner;
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use {@link SpecialSpawn#SpecialSpawn(EntityLiving, World, float, float, float, MobSpawnerBaseLogic)}
|
|
||||||
* with originating spawner instance or null
|
|
||||||
*/
|
|
||||||
@Deprecated // TODO: remove in 1.13
|
|
||||||
public SpecialSpawn(EntityLiving entity, World world, float x, float y, float z)
|
|
||||||
{
|
|
||||||
super(entity, world, x, y, z);
|
|
||||||
spawner = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param spawner the position of a tileentity or approximate position of an entity that initiated the spawn if any
|
* @param spawner the position of a tileentity or approximate position of an entity that initiated the spawn if any
|
||||||
*/
|
*/
|
||||||
|
@ -203,4 +160,4 @@ public class LivingSpawnEvent extends LivingEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ import net.minecraftforge.eventbus.api.Event;
|
||||||
/**
|
/**
|
||||||
* {@link FurnaceFuelBurnTimeEvent} is fired when determining the fuel value for an ItemStack. <br>
|
* {@link FurnaceFuelBurnTimeEvent} is fired when determining the fuel value for an ItemStack. <br>
|
||||||
* <br>
|
* <br>
|
||||||
* To set the burn time of your own item, use {@link Item#getItemBurnTime(ItemStack)} instead.<br>
|
* To set the burn time of your own item, use {@link Item#getBurnTime(ItemStack)} instead.<br>
|
||||||
* <br>
|
* <br>
|
||||||
* This event is fired from {@link ForgeEventFactory#getItemBurnTime(ItemStack)}.<br>
|
* This event is fired from {@link ForgeEventFactory#getItemBurnTime(ItemStack)}.<br>
|
||||||
* <br>
|
* <br>
|
||||||
|
@ -66,18 +66,19 @@ public class FurnaceFuelBurnTimeEvent extends Event
|
||||||
/**
|
/**
|
||||||
* Set the burn time for the given ItemStack.
|
* Set the burn time for the given ItemStack.
|
||||||
* Setting it to 0 will prevent the item from being used as fuel, overriding vanilla's decision.
|
* Setting it to 0 will prevent the item from being used as fuel, overriding vanilla's decision.
|
||||||
* Setting it to -1 will let vanilla decide on the fuel value, this is the default.
|
|
||||||
*/
|
*/
|
||||||
public void setBurnTime(int burnTime)
|
public void setBurnTime(int burnTime)
|
||||||
{
|
{
|
||||||
this.burnTime = burnTime;
|
if (burnTime >= 0)
|
||||||
setCanceled(true);
|
{
|
||||||
|
this.burnTime = burnTime;
|
||||||
|
setCanceled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The resulting value of this event, the burn time for the ItemStack.
|
* The resulting value of this event, the burn time for the ItemStack.
|
||||||
* A value of 0 will prevent the item from being used as fuel, overriding vanilla's decision.
|
* A value of 0 will prevent the item from being used as fuel, overriding vanilla's decision.
|
||||||
* A value of -1 will let vanilla decide on the fuel value, this is the default for {@link Item#getItemBurnTime(ItemStack)}.
|
|
||||||
*/
|
*/
|
||||||
public int getBurnTime()
|
public int getBurnTime()
|
||||||
{
|
{
|
||||||
|
|
|
@ -127,8 +127,8 @@ public class BlockEvent extends Event
|
||||||
super(world, pos, state);
|
super(world, pos, state);
|
||||||
this.player = player;
|
this.player = player;
|
||||||
|
|
||||||
if (state == null || !ForgeHooks.canHarvestBlock(state.getBlock(), player, world, pos) || // Handle empty block or player unable to break block scenario
|
if (state == null || !ForgeHooks.canHarvestBlock(state, player, world, pos) || // Handle empty block or player unable to break block scenario
|
||||||
(state.getBlock().canSilkHarvest(world, pos, world.getBlockState(pos), player) && EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, player.getHeldItemMainhand()) > 0)) // If the block is being silk harvested, the exp dropped is 0
|
(state.canSilkHarvest(world, pos, player) && EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, player.getHeldItemMainhand()) > 0)) // If the block is being silk harvested, the exp dropped is 0
|
||||||
{
|
{
|
||||||
this.exp = 0;
|
this.exp = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class WorldEvent extends Event
|
||||||
* This event is fired when a world is unloaded in
|
* This event is fired when a world is unloaded in
|
||||||
* {@link Minecraft#loadWorld(WorldClient, String)},
|
* {@link Minecraft#loadWorld(WorldClient, String)},
|
||||||
* {@link MinecraftServer#stopServer()},
|
* {@link MinecraftServer#stopServer()},
|
||||||
* {@link DimensionManager#unloadWorlds(Hashtable)},
|
* {@link DimensionManager#unloadWorlds()},
|
||||||
* {@link ForgeInternalHandler#onDimensionUnload(Unload)}. <br>
|
* {@link ForgeInternalHandler#onDimensionUnload(Unload)}. <br>
|
||||||
* <br>
|
* <br>
|
||||||
* This event is not {@link Cancelable}.<br>
|
* This event is not {@link Cancelable}.<br>
|
||||||
|
|
|
@ -27,6 +27,7 @@ import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.material.Material;
|
import net.minecraft.block.material.Material;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.item.BlockItemUseContext;
|
||||||
import net.minecraft.item.ItemBucket;
|
import net.minecraft.item.ItemBucket;
|
||||||
import net.minecraft.init.Items;
|
import net.minecraft.init.Items;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
@ -98,13 +99,13 @@ public class FluidUtil
|
||||||
{
|
{
|
||||||
return player.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
return player.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
||||||
.map(playerInventory -> {
|
.map(playerInventory -> {
|
||||||
|
|
||||||
FluidActionResult fluidActionResult = tryFillContainerAndStow(heldItem, handler, playerInventory, Integer.MAX_VALUE, player, true);
|
FluidActionResult fluidActionResult = tryFillContainerAndStow(heldItem, handler, playerInventory, Integer.MAX_VALUE, player, true);
|
||||||
if (!fluidActionResult.isSuccess())
|
if (!fluidActionResult.isSuccess())
|
||||||
{
|
{
|
||||||
fluidActionResult = tryEmptyContainerAndStow(heldItem, handler, playerInventory, Integer.MAX_VALUE, player, true);
|
fluidActionResult = tryEmptyContainerAndStow(heldItem, handler, playerInventory, Integer.MAX_VALUE, player, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fluidActionResult.isSuccess())
|
if (fluidActionResult.isSuccess())
|
||||||
{
|
{
|
||||||
player.setHeldItem(hand, fluidActionResult.getResult());
|
player.setHeldItem(hand, fluidActionResult.getResult());
|
||||||
|
@ -151,7 +152,7 @@ public class FluidUtil
|
||||||
{
|
{
|
||||||
containerFluidHandler.fill(simulatedTransfer, true);
|
containerFluidHandler.fill(simulatedTransfer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack resultContainer = containerFluidHandler.getContainer();
|
ItemStack resultContainer = containerFluidHandler.getContainer();
|
||||||
return new FluidActionResult(resultContainer);
|
return new FluidActionResult(resultContainer);
|
||||||
}
|
}
|
||||||
|
@ -615,11 +616,13 @@ public class FluidUtil
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BlockItemUseContext context = new BlockItemUseContext(world, player, ItemStack.EMPTY, pos, EnumFacing.UP, 0, 0, 0); //TODO: This neds proper context...
|
||||||
|
|
||||||
// check that we can place the fluid at the destination
|
// check that we can place the fluid at the destination
|
||||||
IBlockState destBlockState = world.getBlockState(pos);
|
IBlockState destBlockState = world.getBlockState(pos);
|
||||||
Material destMaterial = destBlockState.getMaterial();
|
Material destMaterial = destBlockState.getMaterial();
|
||||||
boolean isDestNonSolid = !destMaterial.isSolid();
|
boolean isDestNonSolid = !destMaterial.isSolid();
|
||||||
boolean isDestReplaceable = destBlockState.getBlock().isReplaceable(world, pos);
|
boolean isDestReplaceable = destBlockState.func_196953_a(context);
|
||||||
if (!world.isAirBlock(pos) && !isDestNonSolid && !isDestReplaceable)
|
if (!world.isAirBlock(pos) && !isDestNonSolid && !isDestReplaceable)
|
||||||
{
|
{
|
||||||
return false; // Non-air, solid, unreplacable block. We can't put fluid here.
|
return false; // Non-air, solid, unreplacable block. We can't put fluid here.
|
||||||
|
@ -688,7 +691,7 @@ public class FluidUtil
|
||||||
IBlockState destBlockState = world.getBlockState(pos);
|
IBlockState destBlockState = world.getBlockState(pos);
|
||||||
Material destMaterial = destBlockState.getMaterial();
|
Material destMaterial = destBlockState.getMaterial();
|
||||||
boolean isDestNonSolid = !destMaterial.isSolid();
|
boolean isDestNonSolid = !destMaterial.isSolid();
|
||||||
boolean isDestReplaceable = destBlockState.getBlock().isReplaceable(world, pos);
|
boolean isDestReplaceable = false; //TODO: Needs BlockItemUseContext destBlockState.getBlock().isReplaceable(world, pos);
|
||||||
if ((isDestNonSolid || isDestReplaceable) && !destMaterial.isLiquid())
|
if ((isDestNonSolid || isDestReplaceable) && !destMaterial.isLiquid())
|
||||||
{
|
{
|
||||||
world.destroyBlock(pos, true);
|
world.destroyBlock(pos, true);
|
||||||
|
|
|
@ -359,7 +359,7 @@ public net.minecraft.item.crafting.Ingredient$TagList <init>(Lnet/minecraft/tags
|
||||||
public net.minecraft.client.Minecraft func_193986_ar()V # populateSearchTreeManager
|
public net.minecraft.client.Minecraft func_193986_ar()V # populateSearchTreeManager
|
||||||
|
|
||||||
# Advancements
|
# Advancements
|
||||||
public net.minecraft.advancements.AdvancementManager field_192783_b # GSON
|
public net.minecraft.advancements.AdvancementManager func_195439_b(Lnet/minecraft/resources/IResourceManager;)Ljava/util/Map; # loadCustomAdvancements
|
||||||
public net.minecraft.advancements.CriteriaTriggers func_192118_a(Lnet/minecraft/advancements/ICriterionTrigger;)Lnet/minecraft/advancements/ICriterionTrigger; # register
|
public net.minecraft.advancements.CriteriaTriggers func_192118_a(Lnet/minecraft/advancements/ICriterionTrigger;)Lnet/minecraft/advancements/ICriterionTrigger; # register
|
||||||
|
|
||||||
# BiomeProvider
|
# BiomeProvider
|
||||||
|
@ -367,3 +367,9 @@ public net.minecraft.world.biome.provider.BiomeProvider field_201540_a # BIOMES_
|
||||||
|
|
||||||
# BlockTags.Wrapper
|
# BlockTags.Wrapper
|
||||||
public net.minecraft.tags.BlockTags$Wrapper
|
public net.minecraft.tags.BlockTags$Wrapper
|
||||||
|
|
||||||
|
#SaveHandler
|
||||||
|
public net.minecraft.world.storage.SaveHandler field_75771_c # playersDirectory
|
||||||
|
|
||||||
|
#BlockItemUseContext
|
||||||
|
public net.minecraft.item.BlockItemUseContext <init>(Lnet/minecraft/world/World;Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/item/ItemStack;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/EnumFacing;FFF)V
|
||||||
|
|
Loading…
Reference in a new issue