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'
|
||||
|
||||
group = 'net.minecraftforge'
|
||||
|
@ -52,6 +55,7 @@ project(':forge') {
|
|||
apply plugin: 'java-library'
|
||||
apply plugin: 'eclipse'
|
||||
apply plugin: 'net.minecraftforge.gradle.forgedev.patcher'
|
||||
apply plugin: 'net.minecrell.licenser'
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
|
@ -161,6 +165,26 @@ project(':forge') {
|
|||
environment target:'fmldevserver'
|
||||
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()
|
||||
|
|
|
@ -9,66 +9,79 @@
|
|||
protected static final Logger field_196273_d = LogManager.getLogger();
|
||||
private static final ResourceLocation AIR_ID = new ResourceLocation("air");
|
||||
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);
|
||||
}
|
||||
}
|
||||
+ /* ======================================== FORGE START =====================================*/
|
||||
+
|
||||
+ private ThreadLocal<IBlockState> silkCheck = new ThreadLocal<>();
|
||||
+ private String[] harvestTool = new String[16];
|
||||
+ private int[] harvestLevel = new int[]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
|
||||
+ private net.minecraftforge.common.ToolType harvestTool;
|
||||
+ private int harvestLevel;
|
||||
+ protected static ThreadLocal<Boolean> captureDrops = ThreadLocal.withInitial(() -> false);
|
||||
+ protected static ThreadLocal<NonNullList<ItemStack>> capturedDrops = ThreadLocal.withInitial(NonNullList::create);
|
||||
+ protected NonNullList<ItemStack> captureDrops(boolean start)
|
||||
+ {
|
||||
+ if (start)
|
||||
+ {
|
||||
+ if (start) {
|
||||
+ captureDrops.set(true);
|
||||
+ capturedDrops.get().clear();
|
||||
+ return NonNullList.create();
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ } else {
|
||||
+ captureDrops.set(false);
|
||||
+ return capturedDrops.get();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @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;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean canSilkHarvest(IWorldReader world, BlockPos pos, IBlockState state, EntityPlayer player)
|
||||
+ {
|
||||
+ silkCheck.set(state);
|
||||
+ boolean ret = this.canSilkHarvest();
|
||||
+ return ret;
|
||||
+ public boolean canSilkHarvest(IBlockState state, IWorldReader world, BlockPos pos, EntityPlayer player) {
|
||||
+ return this.canSilkHarvest() && !state.hasTileEntity();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onBlockExploded(World world, BlockPos pos, Explosion explosion)
|
||||
+ {
|
||||
+ public void onBlockExploded(IBlockState state, World world, BlockPos pos, Explosion explosion) {
|
||||
+ world.setBlockToAir(pos);
|
||||
+ onExplosionDestroy(world, pos, explosion);
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public String getHarvestTool(IBlockState state)
|
||||
+ {
|
||||
+ return harvestTool[0]; //TODO: RE-Evaluate
|
||||
+ public net.minecraftforge.common.ToolType getHarvestTool(IBlockState state) {
|
||||
+ return harvestTool; //TODO: RE-Evaluate
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getHarvestLevel(IBlockState state)
|
||||
+ {
|
||||
+
|
||||
+ return harvestLevel[0]; //TODO: RE-Evaluate
|
||||
+ public int getHarvestLevel(IBlockState state) {
|
||||
+ return harvestLevel; //TODO: RE-Evaluate
|
||||
+ }
|
||||
+
|
||||
+ static {
|
||||
+ net.minecraftforge.common.ForgeHooks.setBlockToolSetter((block, tool, level) -> {
|
||||
+ block.harvestTool = tool;
|
||||
+ block.harvestLevel = level;
|
||||
+ });
|
||||
+ }
|
||||
+ /* ========================================= 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<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);
|
||||
@@ -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();
|
||||
return itemgroup != null && (targetTab == ItemGroup.SEARCH || targetTab == itemgroup);
|
||||
}
|
||||
@@ -310,10 +318,49 @@
|
||||
@@ -310,10 +318,48 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@
|
|||
+ @Nullable
|
||||
+ 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;
|
||||
+
|
||||
|
@ -98,16 +98,15 @@
|
|||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.Set<String> getToolClasses(ItemStack stack)
|
||||
+ public java.util.Set<net.minecraftforge.common.ToolType> getToolTypes(ItemStack stack)
|
||||
+ {
|
||||
+ return toolClasses.keySet();
|
||||
+ }
|
||||
+
|
||||
+ @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 ret == null ? -1 : ret;
|
||||
+ return toolClasses.getOrDefault(tool, -1);
|
||||
+ }
|
||||
+
|
||||
+ @OnlyIn(Dist.CLIENT)
|
||||
|
@ -123,17 +122,17 @@
|
|||
public static void registerItems() {
|
||||
registerItemBlock(Blocks.AIR, new ItemAir(Blocks.AIR, new Item.Builder()));
|
||||
func_200879_a(Blocks.STONE, ItemGroup.BUILDING_BLOCKS);
|
||||
@@ -1147,6 +1194,9 @@
|
||||
@@ -1147,6 +1193,9 @@
|
||||
private Item field_200922_c;
|
||||
private ItemGroup field_200923_d;
|
||||
private EnumRarity field_208104_e = EnumRarity.COMMON;
|
||||
+ 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;
|
||||
|
||||
public Item.Builder func_200917_a(int p_200917_1_) {
|
||||
if (this.field_200921_b > 0) {
|
||||
@@ -1181,5 +1231,10 @@
|
||||
@@ -1181,5 +1230,20 @@
|
||||
this.field_208104_e = p_208103_1_;
|
||||
return this;
|
||||
}
|
||||
|
@ -141,6 +140,16 @@
|
|||
+ public Item.Builder setNoRepair() {
|
||||
+ canRepair = false;
|
||||
+ 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;
|
||||
|
||||
-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();
|
||||
public static final ItemStack EMPTY = new ItemStack((Item)null);
|
||||
public static final DecimalFormat DECIMALFORMAT = func_208306_D();
|
||||
|
@ -68,7 +68,7 @@
|
|||
}
|
||||
|
||||
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();
|
||||
BlockPos blockpos = p_196084_1_.func_195995_a();
|
||||
BlockWorldState blockworldstate = new BlockWorldState(p_196084_1_.func_195991_k(), blockpos, false);
|
||||
|
@ -153,7 +153,7 @@
|
|||
|
||||
public boolean canHarvestBlock(IBlockState 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) {
|
||||
|
|
|
@ -9,6 +9,17 @@
|
|||
|
||||
public class BannerDuplicateRecipe extends IRecipeHidden {
|
||||
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 @@
|
||||
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
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -130,7 +130,7 @@
|
||||
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 @@
|
||||
@@ -148,7 +148,6 @@
|
||||
private int buildLimit;
|
||||
private int maxPlayerIdleMinutes;
|
||||
public final long[] tickTimeArray = new long[100];
|
||||
- public long[][] timeOfLastDimensionTick;
|
||||
+ //public long[][] timeOfLastDimensionTick;
|
||||
+ public java.util.Hashtable<Integer, long[]> worldTickTimes = new java.util.Hashtable<Integer, long[]>();
|
||||
private KeyPair serverKeyPair;
|
||||
private String serverOwner;
|
||||
private String folderName;
|
||||
@@ -287,8 +288,6 @@
|
||||
@@ -287,8 +286,7 @@
|
||||
public void loadAllWorlds(String saveName, String worldNameIn, long seed, WorldType type, JsonElement generatorOptions) {
|
||||
this.convertMapIfNeeded(saveName);
|
||||
this.func_200245_b(new TextComponentTranslation("menu.loadingLevel", new Object[0]));
|
||||
- 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.anvilConverterForAnvilFile.func_197715_a(saveName, this);
|
||||
this.setResourcePackFromWorld(this.getFolderName(), isavehandler);
|
||||
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() {
|
||||
try {
|
||||
if (this.init()) {
|
||||
|
@ -36,7 +69,7 @@
|
|||
this.field_211151_aa = Util.func_211177_b();
|
||||
this.statusResponse.setServerDescription(new TextComponentString(this.motd));
|
||||
this.statusResponse.setVersion(new ServerStatusResponse.Version("1.13", 393));
|
||||
@@ -546,7 +546,10 @@
|
||||
@@ -546,7 +562,10 @@
|
||||
|
||||
this.serverIsRunning = true;
|
||||
}
|
||||
|
@ -47,7 +80,7 @@
|
|||
this.finalTick((CrashReport)null);
|
||||
}
|
||||
} catch (Throwable throwable1) {
|
||||
@@ -565,6 +568,7 @@
|
||||
@@ -565,6 +584,7 @@
|
||||
LOGGER.error("We were unable to save this crash report to disk.");
|
||||
}
|
||||
|
||||
|
@ -55,7 +88,7 @@
|
|||
this.finalTick(crashreport);
|
||||
} finally {
|
||||
try {
|
||||
@@ -573,6 +577,7 @@
|
||||
@@ -573,6 +593,7 @@
|
||||
} catch (Throwable throwable) {
|
||||
LOGGER.error("Exception stopping the server", throwable);
|
||||
} finally {
|
||||
|
@ -63,7 +96,15 @@
|
|||
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.profiler.endStartSection("levels");
|
||||
|
||||
|
@ -74,17 +115,74 @@
|
|||
long j = Util.func_211178_c();
|
||||
- if (i == 0 || this.getAllowNether()) {
|
||||
- WorldServer worldserver = this.worlds[i];
|
||||
+ WorldServer worldserver = getWorld(id);
|
||||
+ if (id == 0 || this.getAllowNether()) {
|
||||
+ WorldServer worldserver = net.minecraftforge.common.DimensionManager.getWorld(id);
|
||||
this.profiler.func_194340_a(() -> {
|
||||
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.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.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
|
||||
+++ 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);
|
||||
LOGGER.info("Generating keypair");
|
||||
this.setKeyPair(CryptManager.generateKeyPair());
|
||||
|
@ -12,3 +41,19 @@
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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.Vector4f;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.GameSettings;
|
||||
import net.minecraft.client.MainWindow;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.audio.ISound;
|
||||
import net.minecraft.client.audio.SoundHandler;
|
||||
|
@ -138,7 +138,6 @@ import org.apache.commons.lang3.tuple.Pair;
|
|||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
|
@ -154,19 +153,6 @@ public class ForgeHooksClient
|
|||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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),
|
||||
BOSSINFO, bossInfo, x, y, increment);
|
||||
|
@ -737,7 +723,7 @@ public class ForgeHooksClient
|
|||
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));
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ package net.minecraftforge.client.model.pipeline;
|
|||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.renderer.BlockModelRenderer;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
|
@ -113,7 +114,7 @@ public class ForgeBlockModelRenderer extends BlockModelRenderer
|
|||
quads = model.func_200117_a(state, side, rand);
|
||||
if(!quads.isEmpty())
|
||||
{
|
||||
if(!checkSides || state.shouldSideBeRendered(world, pos, side))
|
||||
if(!checkSides || Block.shouldSideBeRendered(state, world, pos, side))
|
||||
{
|
||||
if(empty) lighter.updateBlockInfo();
|
||||
empty = false;
|
||||
|
|
|
@ -219,13 +219,11 @@ public class DimensionManager
|
|||
{
|
||||
worlds.put(id, world);
|
||||
weakWorldMap.put(world, world);
|
||||
server.worldTickTimes.put(id, new long[100]);
|
||||
LOGGER.info(DIMMGR,"Loading dimension {} ({}) ({})", id, world.getWorldInfo().getWorldName(), world.getMinecraftServer());
|
||||
}
|
||||
else
|
||||
{
|
||||
worlds.remove(id);
|
||||
server.worldTickTimes.remove(id);
|
||||
LOGGER.info(DIMMGR,"Unloading dimension {}", id);
|
||||
}
|
||||
|
||||
|
@ -287,12 +285,23 @@ public class DimensionManager
|
|||
}
|
||||
|
||||
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))
|
||||
{
|
||||
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()
|
||||
|
@ -379,7 +388,7 @@ public class DimensionManager
|
|||
/*
|
||||
* 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();
|
||||
while (queueIterator.hasNext())
|
||||
|
|
|
@ -21,8 +21,10 @@ package net.minecraftforge.common;
|
|||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
|
@ -38,6 +40,7 @@ import java.util.regex.Matcher;
|
|||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Queues;
|
||||
import com.google.common.collect.Sets;
|
||||
|
@ -49,7 +52,6 @@ import net.minecraft.advancements.Advancement;
|
|||
import net.minecraft.advancements.AdvancementManager;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockFarmland;
|
||||
import net.minecraft.block.BlockLiquid;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
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.InventoryPlayer;
|
||||
import net.minecraft.entity.projectile.EntityThrowable;
|
||||
import net.minecraft.fluid.IFluidState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Fluids;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.inventory.ContainerRepair;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
|
@ -73,7 +77,6 @@ import net.minecraft.item.Item;
|
|||
import net.minecraft.item.ItemAxe;
|
||||
import net.minecraft.item.ItemBucket;
|
||||
import net.minecraft.item.ItemEnchantedBook;
|
||||
import net.minecraft.item.ItemMonsterPlacer;
|
||||
import net.minecraft.item.ItemPickaxe;
|
||||
import net.minecraft.item.ItemPotion;
|
||||
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.potion.PotionType;
|
||||
import net.minecraft.potion.PotionUtils;
|
||||
import net.minecraft.resources.IResource;
|
||||
import net.minecraft.resources.IResourceManager;
|
||||
import net.minecraft.stats.StatList;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityNote;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
@ -117,6 +121,7 @@ import net.minecraft.world.IWorldReader;
|
|||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.EnumDifficulty;
|
||||
import net.minecraft.world.GameType;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.storage.loot.LootEntry;
|
||||
import net.minecraft.world.storage.loot.LootTable;
|
||||
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.NoteBlockEvent;
|
||||
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.common.network.handshake.NetworkDispatcher;
|
||||
import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.ConnectionType;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.network.ConnectionType;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
|
||||
import net.minecraftforge.fml.network.NetworkHooks;
|
||||
import net.minecraftforge.fml.relauncher.ReflectionHelper;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
import net.minecraftforge.registries.RegistryManager;
|
||||
|
@ -168,10 +168,12 @@ import javax.annotation.Nonnull;
|
|||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.Marker;
|
||||
import org.apache.logging.log4j.MarkerManager;
|
||||
import org.apache.logging.log4j.util.TriConsumer;
|
||||
|
||||
public class ForgeHooks
|
||||
{
|
||||
|
@ -210,20 +212,16 @@ public class ForgeHooks
|
|||
return entry.getStack(rand, fortune);
|
||||
}
|
||||
|
||||
private static boolean toolInit = false;
|
||||
//static HashSet<List> toolEffectiveness = new HashSet<List>();
|
||||
|
||||
public static boolean canHarvestBlock(@Nonnull Block block, @Nonnull EntityPlayer player, @Nonnull IWorldReader world, @Nonnull BlockPos pos)
|
||||
public static boolean canHarvestBlock(@Nonnull IBlockState state, @Nonnull EntityPlayer player, @Nonnull IBlockReader world, @Nonnull BlockPos pos)
|
||||
{
|
||||
IBlockState state = world.getBlockState(pos);
|
||||
state = state.getBlock().getActualState(state, world, pos);
|
||||
//state = state.getActualState(world, pos);
|
||||
if (state.getMaterial().isToolNotRequired())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ItemStack stack = player.getHeldItemMainhand();
|
||||
String tool = block.getHarvestTool(state);
|
||||
ToolType tool = state.getHarvestTool();
|
||||
if (stack.isEmpty() || tool == null)
|
||||
{
|
||||
return player.canHarvestBlock(state);
|
||||
|
@ -235,89 +233,50 @@ public class ForgeHooks
|
|||
return player.canHarvestBlock(state);
|
||||
}
|
||||
|
||||
return toolLevel >= block.getHarvestLevel(state);
|
||||
return toolLevel >= state.getHarvestLevel();
|
||||
}
|
||||
|
||||
public static boolean canToolHarvestBlock(IWorldReader world, BlockPos pos, @Nonnull ItemStack stack)
|
||||
{
|
||||
IBlockState state = world.getBlockState(pos);
|
||||
state = state.getBlock().getActualState(state, world, pos);
|
||||
String tool = state.getBlock().getHarvestTool(state);
|
||||
//state = state.getActualState(world, pos);
|
||||
ToolType tool = state.getHarvestTool();
|
||||
if (stack.isEmpty() || tool == null) return false;
|
||||
return stack.getItem().getHarvestLevel(stack, tool, null, null) >= state.getBlock().getHarvestLevel(state);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
return stack.getHarvestLevel(tool, null, null) >= state.getHarvestLevel();
|
||||
}
|
||||
|
||||
public static boolean isToolEffective(IWorldReader world, BlockPos pos, @Nonnull ItemStack stack)
|
||||
{
|
||||
IBlockState state = world.getBlockState(pos);
|
||||
state = state.getBlock().getActualState(state, world, pos);
|
||||
for (String type : stack.getItem().getToolClasses(stack))
|
||||
//state = state.getActualState(world, pos);
|
||||
for (ToolType type : stack.getToolTypes())
|
||||
{
|
||||
if (state.getBlock().isToolEffective(type, state))
|
||||
if (state.isToolEffective(type))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean toolInit = false;
|
||||
static void initTools()
|
||||
{
|
||||
if (toolInit)
|
||||
{
|
||||
return;
|
||||
}
|
||||
toolInit = true;
|
||||
|
||||
Set<Block> blocks = ReflectionHelper.getPrivateValue(ItemPickaxe.class, null, 0);
|
||||
for (Block block : blocks)
|
||||
{
|
||||
block.setHarvestLevel("pickaxe", 0);
|
||||
}
|
||||
Set<Block> blocks = getPrivateValue(ItemPickaxe.class, null, 0);
|
||||
blocks.forEach(block -> blockToolSetter.accept(block, ToolType.PICKAXE, 0));
|
||||
blocks = getPrivateValue(ItemSpade.class, null, 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);
|
||||
for (Block block : blocks)
|
||||
{
|
||||
block.setHarvestLevel("shovel", 0);
|
||||
}
|
||||
|
||||
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);
|
||||
//This is taken from ItemAxe, if that changes update here.
|
||||
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})
|
||||
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);
|
||||
}
|
||||
|
||||
public static int getTotalArmorValue(EntityPlayer player)
|
||||
|
@ -723,7 +682,7 @@ public class ForgeHooks
|
|||
|
||||
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
|
||||
|
@ -841,9 +800,7 @@ public class ForgeHooks
|
|||
// Tell client the block is gone immediately then process events
|
||||
if (world.getTileEntity(pos) == null)
|
||||
{
|
||||
SPacketBlockChange packet = new SPacketBlockChange(world, pos);
|
||||
packet.blockState = Blocks.AIR.getDefaultState();
|
||||
entityPlayer.connection.sendPacket(packet);
|
||||
entityPlayer.connection.sendPacket(new SPacketBlockChange(DUMMY_WORLD, pos));
|
||||
}
|
||||
|
||||
// Post the block break event
|
||||
|
@ -872,6 +829,7 @@ public class ForgeHooks
|
|||
return event.isCanceled() ? -1 : event.getExpToDrop();
|
||||
}
|
||||
|
||||
/* TODO: Talk to Sponge folk about World rollbacks.
|
||||
public static EnumActionResult onPlaceItemIntoWorld(@Nonnull ItemUseContext context)
|
||||
{
|
||||
ItemStack itemstack = context.func_195996_i();
|
||||
|
@ -969,6 +927,7 @@ public class ForgeHooks
|
|||
|
||||
return ret;
|
||||
}
|
||||
*/
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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>();
|
||||
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)));
|
||||
}
|
||||
|
||||
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
|
||||
public static CriticalHitEvent getCriticalHit(EntityPlayer player, Entity target, boolean vanillaCritical, float damageModifier)
|
||||
{
|
||||
|
@ -1307,56 +1244,6 @@ public class ForgeHooks
|
|||
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?
|
||||
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;
|
||||
}
|
||||
|
||||
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.ItemStack;
|
||||
import net.minecraft.pathfinding.PathNodeType;
|
||||
import net.minecraft.state.EnumProperty;
|
||||
import net.minecraft.state.IProperty;
|
||||
import net.minecraft.state.properties.BedPart;
|
||||
import net.minecraft.util.*;
|
||||
|
@ -52,19 +51,20 @@ import net.minecraft.world.Explosion;
|
|||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.IWorldWriter;
|
||||
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.EnumPlantType;
|
||||
import net.minecraftforge.common.IPlantable;
|
||||
import net.minecraftforge.common.ToolType;
|
||||
|
||||
public interface IForgeBlock
|
||||
{
|
||||
default Block getBlock()
|
||||
{
|
||||
return (Block) this;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -170,7 +170,7 @@ public interface IForgeBlock
|
|||
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
|
||||
|
@ -198,6 +198,7 @@ public interface IForgeBlock
|
|||
* @param type The Mob Category Type
|
||||
* @return True to allow a mob of the specified category to spawn, false to prevent it.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
default boolean canCreatureSpawn(IBlockState state, IWorldReader world, BlockPos pos, EntitySpawnPlacementRegistry.SpawnPlacementType type)
|
||||
{
|
||||
return this.getBlock().isTopSolid(state);
|
||||
|
@ -225,19 +226,18 @@ public interface IForgeBlock
|
|||
|
||||
/**
|
||||
* Called when a user either starts or stops sleeping in the bed.
|
||||
* @param state
|
||||
*
|
||||
* @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)
|
||||
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);
|
||||
state.func_206870_a(BlockBed.OCCUPIED,occupied);
|
||||
((World) world).setBlockState(pos, state, 4);
|
||||
((IWorldWriter)world).setBlockState(pos, state.func_206870_a(BlockBed.OCCUPIED,occupied), 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,7 +336,7 @@ public interface IForgeBlock
|
|||
* @param pos Block position in world
|
||||
* @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;
|
||||
}
|
||||
|
@ -365,7 +365,7 @@ public interface IForgeBlock
|
|||
* @param explosion The explosion
|
||||
* @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();
|
||||
}
|
||||
|
@ -379,7 +379,7 @@ public interface IForgeBlock
|
|||
* @param pos Block position in world
|
||||
* @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,
|
||||
|
@ -408,15 +408,10 @@ public interface IForgeBlock
|
|||
default boolean canPlaceTorchOnTop(IBlockState state, IWorldReader world, BlockPos pos)
|
||||
{
|
||||
if (state.isTopSolid() || state.getBlockFaceShape(world, pos, EnumFacing.UP) == BlockFaceShape.SOLID)
|
||||
{
|
||||
return this.getBlock() != Blocks.END_GATEWAY && this.getBlock() != Blocks.field_196628_cT;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.getBlock() instanceof BlockFence || this.getBlock() == Blocks.COBBLESTONE_WALL || this.getBlock() instanceof BlockGlass;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -436,7 +431,7 @@ public interface IForgeBlock
|
|||
*
|
||||
* @return False to disallow spawning.
|
||||
*/
|
||||
default boolean isFoilage(IWorldReader world, BlockPos pos)
|
||||
default boolean isFoliage(IBlockState state, IWorldReader world, BlockPos pos)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -486,7 +481,7 @@ public interface IForgeBlock
|
|||
* @return True to prevent vanilla break particles from spawning.
|
||||
*/
|
||||
@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;
|
||||
}
|
||||
|
@ -568,10 +563,8 @@ public interface IForgeBlock
|
|||
default void onPlantGrow(IBlockState state, World world, BlockPos pos, BlockPos source)
|
||||
{
|
||||
if (this.getBlock() == Blocks.GRASS || this.getBlock() == Blocks.FARMLAND)
|
||||
{
|
||||
world.setBlockState(pos, Blocks.DIRT.getDefaultState(), 2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this soil is fertile, typically this means that growth rates
|
||||
|
@ -582,12 +575,10 @@ public interface IForgeBlock
|
|||
* @param pos Block position in world
|
||||
* @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)
|
||||
{
|
||||
return world.getBlockState(pos).getValue(BlockFarmland.MOISTURE) > 0;
|
||||
}
|
||||
return state.getValue(BlockFarmland.MOISTURE) > 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -618,7 +609,7 @@ public interface IForgeBlock
|
|||
* @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)
|
||||
default boolean isBeaconBase(IBlockState state, IWorldReader world, BlockPos pos, BlockPos beacon)
|
||||
{
|
||||
return this.getBlock() == Blocks.EMERALD_BLOCK || this.getBlock() == Blocks.GOLD_BLOCK ||
|
||||
this.getBlock() == Blocks.DIAMOND_BLOCK || this.getBlock() == Blocks.IRON_BLOCK;
|
||||
|
@ -637,10 +628,8 @@ public interface IForgeBlock
|
|||
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 ->
|
||||
{
|
||||
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
|
||||
* @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;
|
||||
}
|
||||
|
@ -703,7 +692,7 @@ public interface IForgeBlock
|
|||
* @param fortune
|
||||
* @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;
|
||||
}
|
||||
|
@ -714,7 +703,7 @@ public interface IForgeBlock
|
|||
* @param pos Block position in world
|
||||
* @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.
|
||||
|
@ -748,7 +737,7 @@ public interface IForgeBlock
|
|||
* @param pos Block position in world
|
||||
* @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;
|
||||
}
|
||||
|
@ -756,7 +745,7 @@ public interface IForgeBlock
|
|||
* Queries the class of tool required to harvest this block, if null is returned
|
||||
* 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,
|
||||
|
@ -770,14 +759,11 @@ public interface IForgeBlock
|
|||
* Checks if the specified tool type is efficient on this block,
|
||||
* meaning that it digs at full speed.
|
||||
*/
|
||||
default boolean isToolEffective(String type, IBlockState state)
|
||||
{
|
||||
if ("pickaxe".equals(type) && (this.getBlock() == Blocks.REDSTONE_ORE || this.getBlock() == Blocks.REDSTONE_LAMP
|
||||
|| this.getBlock() == Blocks.OBSIDIAN))
|
||||
default boolean isToolEffective(IBlockState state, ToolType tool)
|
||||
{
|
||||
if (tool == ToolType.PICKAXE && (this.getBlock() == Blocks.REDSTONE_ORE || this.getBlock() == Blocks.REDSTONE_LAMP || this.getBlock() == Blocks.OBSIDIAN))
|
||||
return false;
|
||||
}
|
||||
return type != null && type.equals(getHarvestTool(state));
|
||||
return tool == getHarvestTool(state);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -794,7 +780,6 @@ public interface IForgeBlock
|
|||
*
|
||||
* @param world that is being tested.
|
||||
* @param blockpos position thats being tested.
|
||||
* @param iblockstate state at world/blockpos
|
||||
* @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 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.
|
||||
*/
|
||||
@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;
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
@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;
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
@Nullable
|
||||
default Boolean isAABBInsideLiquid(World world, BlockPos pos, AxisAlignedBB boundingBox)
|
||||
default Boolean isAABBInsideLiquid(IBlockState state, IWorldReader world, BlockPos pos, AxisAlignedBB boundingBox)
|
||||
{
|
||||
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
|
||||
* @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();
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
@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;
|
||||
}
|
||||
|
@ -885,7 +870,7 @@ public interface IForgeBlock
|
|||
* @return The new fog color.
|
||||
*/
|
||||
@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)
|
||||
{
|
||||
|
@ -939,6 +924,7 @@ public interface IForgeBlock
|
|||
* @param hand The player hand used to place this block
|
||||
* @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)
|
||||
{
|
||||
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
|
||||
* @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;
|
||||
}
|
||||
|
@ -976,6 +962,7 @@ public interface IForgeBlock
|
|||
* @param side The side of this block that the chest lid is trying to open into
|
||||
* @return true if the chest should be prevented from opening by this block
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
default boolean doesSideBlockChestOpening(IBlockState blockState, IWorldReader world, BlockPos pos, EnumFacing side)
|
||||
{
|
||||
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;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.ai.attributes.AttributeModifier;
|
||||
import net.minecraft.entity.passive.EntityHorse;
|
||||
import net.minecraft.entity.passive.HorseArmorType;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.init.Items;
|
||||
|
@ -30,6 +34,7 @@ import net.minecraft.world.GameType;
|
|||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.ToolType;
|
||||
|
||||
// TODO review most of the methods in this "patch"
|
||||
public interface IForgeItem
|
||||
|
@ -43,6 +48,7 @@ public interface IForgeItem
|
|||
/**
|
||||
* ItemStack sensitive version of getItemAttributeModifiers
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
default Multimap<String, AttributeModifier> getAttributeModifiers(EntityEquipmentSlot slot, ItemStack stack)
|
||||
{
|
||||
return getItem().getItemAttributeModifiers(slot);
|
||||
|
@ -188,6 +194,7 @@ public interface IForgeItem
|
|||
* @param stack The current item stack
|
||||
* @return True if this item has a 'container'
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
default boolean hasContainerItem(ItemStack stack)
|
||||
{
|
||||
return getItem().hasContainerItem();
|
||||
|
@ -476,6 +483,7 @@ public interface IForgeItem
|
|||
* @param stack The itemstack that is damaged
|
||||
* @return the damage value
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
default int getMaxDamage(ItemStack stack)
|
||||
{
|
||||
return getItem().getMaxDamage();
|
||||
|
@ -524,11 +532,11 @@ public interface IForgeItem
|
|||
/**
|
||||
* ItemStack sensitive version of {@link #canHarvestBlock(IBlockState)}
|
||||
*
|
||||
* @param state The block trying to harvest
|
||||
* @param stack The itemstack used to harvest the block
|
||||
* @param state The block trying to harvest
|
||||
* @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);
|
||||
}
|
||||
|
@ -540,12 +548,13 @@ public interface IForgeItem
|
|||
* @param stack The ItemStack
|
||||
* @return The maximum number this item can be stacked to
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
default int getItemStackLimit(ItemStack stack)
|
||||
{
|
||||
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,
|
||||
|
@ -557,7 +566,7 @@ public interface IForgeItem
|
|||
* @param blockState The block to harvest
|
||||
* @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
|
||||
|
@ -713,7 +722,7 @@ public interface IForgeItem
|
|||
* it not act as a fuel. Return -1 to let the default vanilla logic
|
||||
* decide.
|
||||
*/
|
||||
default int getItemBurnTime(ItemStack itemStack)
|
||||
default int getBurnTime(ItemStack itemStack)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
@ -727,12 +736,12 @@ public interface IForgeItem
|
|||
* @return an enum constant of type {@code HorseArmorType}. Return
|
||||
* 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();
|
||||
}
|
||||
|
@ -745,7 +754,7 @@ public interface IForgeItem
|
|||
* @param horse the horse wearing this armor
|
||||
* @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;
|
||||
|
||||
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.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.
|
||||
*/
|
||||
public interface IForgeItemStack
|
||||
public interface IForgeItemStack extends ICapabilitySerializable<NBTTagCompound>
|
||||
{
|
||||
// Helpers for accessing Item data
|
||||
default ItemStack getStack()
|
||||
|
@ -36,4 +45,33 @@ public interface IForgeItemStack
|
|||
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 sendMessage(ITextComponent component) {}
|
||||
@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 canAttackPlayer(EntityPlayer player){ return false; }
|
||||
@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.PlaySoundAtEntityEvent;
|
||||
import net.minecraftforge.event.entity.ProjectileImpactEvent;
|
||||
import net.minecraftforge.event.entity.ThrowableImpactEvent;
|
||||
import net.minecraftforge.event.entity.item.ItemExpireEvent;
|
||||
import net.minecraftforge.event.entity.living.AnimalTameEvent;
|
||||
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.GetCollisionBoxesEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
import net.minecraftforge.eventbus.api.Event.Result;
|
||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
|
@ -180,27 +178,6 @@ public class ForgeEventFactory
|
|||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return MinecraftForge.EVENT_BUS.post(new LivingSpawnEvent.SpecialSpawn(entity, world, x, y, z, spawner));
|
||||
|
@ -261,21 +212,10 @@ public class ForgeEventFactory
|
|||
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);
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
if (event.getBurnTime() < 0)
|
||||
{
|
||||
// legacy handling
|
||||
int fuelValue = GameRegistry.getFuelValueLegacy(itemStack);
|
||||
if (fuelValue > 0)
|
||||
{
|
||||
return fuelValue;
|
||||
}
|
||||
}
|
||||
return event.getBurnTime();
|
||||
}
|
||||
|
||||
|
@ -393,9 +333,7 @@ public class ForgeEventFactory
|
|||
|
||||
public static void firePlayerLoadingEvent(EntityPlayer player, IPlayerFileData playerFileData, String uuidString)
|
||||
{
|
||||
SaveHandler sh = (SaveHandler) playerFileData;
|
||||
File dir = sh.getPlayersDirectory();
|
||||
MinecraftForge.EVENT_BUS.post(new PlayerEvent.LoadFromFile(player, dir, uuidString));
|
||||
MinecraftForge.EVENT_BUS.post(new PlayerEvent.LoadFromFile(player, ((SaveHandler)playerFileData).playersDirectory, uuidString));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -705,9 +643,7 @@ public class ForgeEventFactory
|
|||
|
||||
public static boolean onProjectileImpact(EntityThrowable throwable, RayTraceResult ray)
|
||||
{
|
||||
boolean oldEvent = MinecraftForge.EVENT_BUS.post(new ThrowableImpactEvent(throwable, ray));
|
||||
boolean newEvent = MinecraftForge.EVENT_BUS.post(new ProjectileImpactEvent.Throwable(throwable, ray));
|
||||
return oldEvent || newEvent; // TODO: clean up when old event is removed
|
||||
return MinecraftForge.EVENT_BUS.post(new ProjectileImpactEvent.Throwable(throwable, ray));
|
||||
}
|
||||
|
||||
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.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.ForgeEventFactory;
|
||||
import net.minecraftforge.eventbus.api.Cancelable;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
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
|
||||
* receive every child event of this class.<br>
|
||||
* <br>
|
||||
|
@ -72,7 +71,6 @@ public class LivingSpawnEvent extends LivingEvent
|
|||
@HasResult
|
||||
public static class CheckSpawn extends LivingSpawnEvent
|
||||
{
|
||||
private final boolean isSpawner; // TODO: remove in 1.13
|
||||
@Nullable
|
||||
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)
|
||||
{
|
||||
super(entity, world, x, y, z);
|
||||
this.isSpawner = spawner != null;
|
||||
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()
|
||||
{
|
||||
return isSpawner; // TODO: replace with spawner null check in 1.13
|
||||
return spawner != null; // TODO: replace with spawner null check in 1.13
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -154,17 +122,6 @@ public class LivingSpawnEvent extends LivingEvent
|
|||
@Nullable
|
||||
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
|
||||
*/
|
||||
|
|
|
@ -31,7 +31,7 @@ import net.minecraftforge.eventbus.api.Event;
|
|||
/**
|
||||
* {@link FurnaceFuelBurnTimeEvent} is fired when determining the fuel value for an ItemStack. <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>
|
||||
* This event is fired from {@link ForgeEventFactory#getItemBurnTime(ItemStack)}.<br>
|
||||
* <br>
|
||||
|
@ -66,18 +66,19 @@ public class FurnaceFuelBurnTimeEvent extends Event
|
|||
/**
|
||||
* 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 -1 will let vanilla decide on the fuel value, this is the default.
|
||||
*/
|
||||
public void setBurnTime(int burnTime)
|
||||
{
|
||||
if (burnTime >= 0)
|
||||
{
|
||||
this.burnTime = burnTime;
|
||||
setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 -1 will let vanilla decide on the fuel value, this is the default for {@link Item#getItemBurnTime(ItemStack)}.
|
||||
*/
|
||||
public int getBurnTime()
|
||||
{
|
||||
|
|
|
@ -127,8 +127,8 @@ public class BlockEvent extends Event
|
|||
super(world, pos, state);
|
||||
this.player = player;
|
||||
|
||||
if (state == null || !ForgeHooks.canHarvestBlock(state.getBlock(), 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
|
||||
if (state == null || !ForgeHooks.canHarvestBlock(state, player, world, pos) || // Handle empty block or player unable to break block scenario
|
||||
(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;
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ public class WorldEvent extends Event
|
|||
* This event is fired when a world is unloaded in
|
||||
* {@link Minecraft#loadWorld(WorldClient, String)},
|
||||
* {@link MinecraftServer#stopServer()},
|
||||
* {@link DimensionManager#unloadWorlds(Hashtable)},
|
||||
* {@link DimensionManager#unloadWorlds()},
|
||||
* {@link ForgeInternalHandler#onDimensionUnload(Unload)}. <br>
|
||||
* <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.state.IBlockState;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemBucket;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -615,11 +616,13 @@ public class FluidUtil
|
|||
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
|
||||
IBlockState destBlockState = world.getBlockState(pos);
|
||||
Material destMaterial = destBlockState.getMaterial();
|
||||
boolean isDestNonSolid = !destMaterial.isSolid();
|
||||
boolean isDestReplaceable = destBlockState.getBlock().isReplaceable(world, pos);
|
||||
boolean isDestReplaceable = destBlockState.func_196953_a(context);
|
||||
if (!world.isAirBlock(pos) && !isDestNonSolid && !isDestReplaceable)
|
||||
{
|
||||
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);
|
||||
Material destMaterial = destBlockState.getMaterial();
|
||||
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())
|
||||
{
|
||||
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
|
||||
|
||||
# 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
|
||||
|
||||
# BiomeProvider
|
||||
|
@ -367,3 +367,9 @@ public net.minecraft.world.biome.provider.BiomeProvider field_201540_a # BIOMES_
|
|||
|
||||
# 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