Compare commits

...
62 Commits
Author SHA1 Message Date
mezz 0ebced9609 Fix #1845 API has references to internal classes 2017-09-07 19:23:59 -07:00
mezz b9924ea98b Fix #1843 Improve performance of worldgen hives 2017-09-06 00:35:54 -07:00
mezz 5707d27598 Fix #1577 Hives load new chunks when retrogen is active 2017-09-04 14:46:56 -07:00
mezz 42bde9e576 Fix #1836 Update minimum required JEI version 2017-09-04 14:10:55 -07:00
mezz 76f09be39d Close #1838 Make IHiveFrame's getBeeModifier() ItemStack aware 2017-09-04 13:52:32 -07:00
LachimHeigrim e6cb758e0e Fix #1827 Allow Natura nether saplings to be autofarmed in arboreal farm (#1829) 2017-09-01 19:58:46 -07:00
mezz b3549edf51 Fix #1833 Item in players hand get deleted by farm planting 2017-08-29 22:14:47 -07:00
mezz e09d159935 Fix breeding data desync after changing dimensions 2017-08-29 20:55:31 -07:00
Nedelosk 4cb2610b1c Fix #1830 Carpenter removes the wrong item 2017-08-28 16:03:12 +02:00
mezz c44f11cf09 Update dependencies 2017-08-27 14:56:59 -07:00
mezz b69c31ed8a Clean up generics for Forestry ItemBlocks 2017-08-25 21:14:13 -07:00
mezz 6a2231f8fb Fix a crash when escritoire loads with a specimen already in it 2017-08-22 23:00:27 -07:00
mezz a3a6c71c42 Fix #1762 Swapping specimens in the escritoire has strange effects 2017-08-22 22:46:13 -07:00
mezz 8d5c0c6f8b Fix #1806 Allow sapling's products to work as hint items in escritoire 2017-08-22 22:37:35 -07:00
mezz 56603fd00c Fix #1813 Saplings do not drop when removed by water of piston 2017-08-22 22:10:47 -07:00
mezz ed69411d2e Fix #1815 Stop MultiFarm from converting vanilla saplings 2017-08-22 21:45:55 -07:00
mezz e1d017f077 Fix #1819 Crash when growing short Sipiri trees 2017-08-20 22:24:53 -07:00
mezz 9269af7a13 Update to 1.12.1 2017-08-18 20:17:18 -07:00
Nedelosk 8ffdba5021 Fix build script 2017-08-17 13:59:39 +02:00
Nedelosk e00aecd886 Fix #1807 Honeycomb block uncraftable 2017-08-16 19:26:15 +02:00
Nedelosk 98f859f2fb Add a log message to the Create Model 2017-08-16 14:48:11 +02:00
mezz 55a15d23b2 Fix Pam's harvestcraft integration 2017-08-14 21:19:29 -07:00
mezz 307580aed8 Mark as working on 1.12.1 on CurseForge 2017-08-13 22:06:46 -07:00
Nedelosk d2d93004e0 Merge pull request #1801 from asiekierka/mc-1.12
Reduce SimpleModel memory usage
2017-08-13 18:21:02 +02:00
Adrian Siekierka e1df424bfd reduce SimpleModel memory usage 2017-08-13 16:35:26 +02:00
Robert Obermeier 6a75347b05 Add Red Orchid support to farm (#1800) 2017-08-12 17:09:00 -07:00
Robert Obermeier cfd513ea80 Fix Natura support (#1794) 2017-08-12 15:50:31 -07:00
Robert Obermeier edcc47a6b3 Fix #1753 Add generalized sapling support (#1798) 2017-08-12 14:44:16 -07:00
mezz 6593118f3d Fix #1787 Wood logs drop the wrong item when harvested with silk touch 2017-08-12 12:39:59 -07:00
Robert Obermeier fd724d147a Fix #1789 The End has no hives. (#1795) 2017-08-11 20:56:12 -07:00
mezz b2e1b2dc9b Fix tree generation with Mystcraft 2017-07-29 15:42:34 -07:00
mezz defc47000b Fix client visual glitch with worktable 2017-07-29 00:56:34 -07:00
mezz 0a37ad0666 First beta version 2017-07-28 23:31:04 -07:00
mezz 13d4907bff #1687 Fix crash when genetics items are missing nbt 2017-07-28 23:28:43 -07:00
mezz 78725009c1 Fix #1777 crash on load from backpacks 2017-07-28 23:13:51 -07:00
mezz a1bc9144bd Fix #1768 fix serious issues with the worktable 2017-07-27 22:39:49 -07:00
Nedelosk b897056824 Fix #1772 crash if forestry.factory=false 2017-07-28 00:11:03 +02:00
Nedelosk 87563b6c97 Merge remote-tracking branch 'origin/mc-1.12' into mc-1.12 2017-07-25 16:01:11 +02:00
Nedelosk 62d6294da2 Fix Fertilizer Config from 1.10 to 1.11 / 1.12 2017-07-25 16:01:01 +02:00
Robert Obermeier b4d71543db Move hives into biome decoration generation
fixes #1760
2017-07-24 22:33:21 -07:00
mezz 73db1a608a Fix #1741 Fix recipes for farm blocks only allow quartz 2017-07-17 23:41:18 -07:00
Brennan Ward 1c6b60122e Update to AA r115 2017-07-15 17:51:15 -07:00
mezz 1e7a042b53 Fix missing item/block event handling 2017-07-12 22:47:26 -07:00
mezz bf08336bc5 Fix JEI dependency info 2017-07-09 21:02:15 -07:00
mezz 62cbf31ac2 Version 5.4.3 2017-07-03 17:22:56 -07:00
mezz a2eac214b4 Minor cleanup 2017-07-03 17:22:39 -07:00
Nedelosk 32933ce90b Merge remote-tracking branch 'origin/mc-1.12' into mc-1.12 2017-07-04 02:15:42 +02:00
Nedelosk 44cdc191fc Fix #1732 Forestry - Blocks all look the same when placed 2017-07-04 02:15:30 +02:00
mezz e4f77e42d3 Fix #1237 Fireproof blocks work as fuel 2017-07-03 16:52:45 -07:00
mezz 9f91832c7e Experiment updating Gradle Wrapper to 4.0 2017-07-03 15:26:50 -07:00
mezz 6d4af0fb5d Version 5.4.2 2017-07-03 00:17:10 -07:00
mezz 4345739a87 Merge remote-tracking branch 'origin/mc-1.11' into mc-1.12 2017-07-03 00:15:34 -07:00
mezz 0a881a81f8 Fix worktable crafting (#1728) 2017-07-03 00:12:58 -07:00
mezz b066f7ad4c Create proper recipe registry names 2017-07-03 00:06:31 -07:00
mezz a19380347a Fix missing textures on butterfly items (#1730) 2017-07-02 21:31:49 -07:00
mezz 9bc1211e57 Fix missing textures on machine tabs (#1730) 2017-07-02 21:31:29 -07:00
mezz cbce5d0fc0 Cleanup 2017-07-02 21:31:03 -07:00
mezz b20b56c5d4 Update Forge 2017-07-02 21:30:40 -07:00
mezz 27041c205c Fix #1723 Items show in the wrong creative tabs 2017-07-02 01:00:28 -07:00
Nedelosk 09ea20729d Improve Wood Model Loader 2017-06-26 14:00:41 +02:00
Nedelosk 736e6c5fa2 Change wood texture json file name 2017-06-25 15:33:00 +02:00
Nedelosk e96f4fc8a0 Fix Fence Gate Model 2017-06-25 11:55:25 +02:00
149 changed files with 2456 additions and 1664 deletions

No files matched your search

Executable → Regular
+10 -17
View File
@@ -5,15 +5,17 @@ buildscript {
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
classpath "gradle.plugin.se.bjurr.gitchangelog:git-changelog-gradle-plugin:1.47"
}
}
plugins {
id "com.matthewprenger.cursegradle" version "1.0.9"
id "se.bjurr.gitchangelog.git-changelog-gradle-plugin" version "1.32"
}
apply plugin: 'net.minecraftforge.gradle.forge'
apply plugin: 'idea'
apply plugin: 'maven'
apply plugin: "se.bjurr.gitchangelog.git-changelog-gradle-plugin"
version = version_major + '.' + version_minor + '.' + version_patch + '.' + getBuildNumber()
if (project.hasProperty('buildQualifier')) {
@@ -60,9 +62,9 @@ repositories {
}
dependencies {
deobfCompile "net.darkhax.tesla:Tesla-${mcversion}:${tesla_version}"
deobfCompile "mezz.jei:jei_${mcversion}:${jei_version}:api"
runtime "mezz.jei:jei_${mcversion}:${jei_version}"
deobfCompile "net.darkhax.tesla:Tesla-${tesla_mcversion}:${tesla_version}"
deobfCompile "mezz.jei:jei_${jei_mcversion}:${jei_version}:api"
runtime "mezz.jei:jei_${jei_mcversion}:${jei_version}"
deobfCompile "net.industrial-craft:industrialcraft-2:${ic2_version}:api"
}
@@ -149,26 +151,17 @@ task makeChangelog(type: se.bjurr.gitchangelog.plugin.gradle.GitChangelogTask) {
untaggedName = "Current release ${project.version}"
fromCommit = "5a3850c2642e535656d090d1473054d5fa8d3331"
toRef = "HEAD"
templateContent = """
Please help the Forestry project by <a href="https://github.com/ForestryMC/ForestryMC/issues">reporting issues here.</a><br/>
{{#tags}}
<h3>{{name}}</h3>
<ul>
{{#commits}}
<li>{{{message}}} - {{authorName}}</li>
{{/commits}}
</ul>
{{/tags}}
"""
templateContent = file('changelog.mustache').getText('UTF-8')
}
curseforge {
apiKey = project.hasProperty('curseforge_apikey') ? project.curseforge_apikey : '0'
project {
id = '59751'
id = curse_project_id
changelog = file('changelog.html')
changelogType = 'html'
releaseType = 'alpha'
releaseType = 'beta'
addGameVersion '1.12'
}
}
+9
View File
@@ -0,0 +1,9 @@
Please help the Forestry project by <a href="https://github.com/ForestryMC/ForestryMC/issues">reporting issues here.</a><br/>
{{#tags}}
<h3>{{name}}</h3>
<ul>
{{#commits}}
<li>{{{message}}} - {{authorName}}</li>
{{/commits}}
</ul>
{{/tags}}
+10 -7
View File
@@ -1,11 +1,14 @@
mcversion=1.12
forgeversion=14.21.1.2387
mcp_mappings=snapshot_20170702
mcversion=1.12.1
forgeversion=14.22.0.2469
mcp_mappings=snapshot_20170904
curse_project_id=59751
tesla_version=1.0.60
jei_version=4.7.0.67
ic2_version=2.7.30-ex111
tesla_mcversion=1.12
jei_version=4.7.8.92
jei_mcversion=1.12.1
ic2_version=2.8.24-ex112
version_major=5
version_minor=4
version_patch=1
version_minor=5
version_patch=3
Binary file not shown.
+2 -2
View File
@@ -1,6 +1,6 @@
#Sat Jun 24 19:47:39 PDT 2017
#Mon Jul 03 15:24:47 PDT 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.7-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-all.zip
Vendored
+1 -5
View File
@@ -42,11 +42,6 @@ case "`uname`" in
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@@ -114,6 +109,7 @@ fi
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+1 -1
Submodule lang updated: f5300f059b...192d6f8584.
+15 -19
View File
@@ -15,12 +15,11 @@ import com.google.common.base.Preconditions;
import javax.annotation.Nullable;
import java.io.File;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import forestry.plugins.compat.PluginNatura;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
@@ -29,6 +28,7 @@ import net.minecraftforge.fml.common.event.FMLInterModComms.IMCEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry;
@@ -44,7 +44,6 @@ import forestry.core.gui.GuiHandler;
import forestry.core.multiblock.MultiblockEventHandler;
import forestry.core.network.PacketHandler;
import forestry.core.proxy.Proxies;
import forestry.core.utils.MigrationHelper;
import forestry.core.worldgen.WorldGenerator;
import forestry.plugins.PluginManager;
import forestry.plugins.compat.PluginIC2;
@@ -59,10 +58,11 @@ import forestry.plugins.compat.PluginIC2;
name = Constants.MOD_NAME,
version = Constants.VERSION,
guiFactory = "forestry.core.config.ForestryGuiConfigFactory",
acceptedMinecraftVersions = "[1.12]",
dependencies = "required-after:forge@[14.21.0.2363,);"
+ "after:JEI@[4.7.0,);"
+ "after:" + PluginIC2.modId + ";")
acceptedMinecraftVersions = "[1.12, 1.12.1]",
dependencies = "required-after:forge@[14.21.1.2395,);"
+ "after:jei@[4.7.8.91,);"
+ "after:" + PluginIC2.modId + ";"
+ "after:" + PluginNatura.modId + ";")
public class Forestry {
@SuppressWarnings("NullableProblems")
@@ -77,6 +77,7 @@ public class Forestry {
ForestryAPI.errorStateRegistry = new ErrorStateRegistry();
EnumErrorCode.init();
FluidRegistry.enableUniversalBucket();
MinecraftForge.EVENT_BUS.register(this);
}
@Nullable
@@ -109,6 +110,11 @@ public class Forestry {
PluginManager.runPreInit(event.getSide());
}
@SubscribeEvent
public void registerModels(ModelRegistryEvent event) {
PluginManager.runRegisterBackpacksAndCrates();
Proxies.render.registerModels();
}
@@ -151,14 +157,4 @@ public class Forestry {
public void processIMCMessages(IMCEvent event) {
PluginManager.processIMCMessages(event.getMessages());
}
@EventHandler
public void onMissingBlockMappings(RegistryEvent.MissingMappings<Block> event) {
MigrationHelper.onMissingBlockMappings(event);
}
@EventHandler
public void onMissingItemMappings(RegistryEvent.MissingMappings<Item> event) {
MigrationHelper.onMissingItemMappings(event);
}
}
@@ -5,12 +5,14 @@
******************************************************************************/
package forestry.api.apiculture;
import java.io.IOException;
import java.util.List;
import forestry.api.core.INbtReadable;
import forestry.api.core.INbtWritable;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.PacketBuffer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.fml.relauncher.Side;
@@ -79,4 +81,12 @@ public interface IBeekeepingLogic extends INbtWritable, INbtReadable {
* These positions are synced to the client from the server.
*/
List<BlockPos> getFlowerPositions();
default void readData(PacketBuffer data) throws IOException {
}
default void writeData(PacketBuffer data) {
}
}
@@ -20,5 +20,18 @@ public interface IHiveFrame {
*/
ItemStack frameUsed(IBeeHousing housing, ItemStack frame, IBee queen, int wear);
/**
* @param frame ItemStack containing the actual frame.
* @return the {@link IBeeModifier} for this frame.
* @since Forestry 5.5.1
*/
default IBeeModifier getBeeModifier(ItemStack frame) {
return getBeeModifier();
}
/**
* @deprecated since Forestry 5.5.1. Use {@link #getBeeModifier(ItemStack)}
*/
@Deprecated
IBeeModifier getBeeModifier();
}
@@ -12,6 +12,7 @@ import java.util.List;
import com.mojang.authlib.GameProfile;
import forestry.api.genetics.IAllele;
import forestry.api.genetics.IChromosome;
import forestry.api.genetics.IFruitFamily;
import forestry.api.genetics.ISpeciesRootPollinatable;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -101,4 +102,6 @@ public interface ITreeRoot extends ISpeciesRootPollinatable {
/* MUTATIONS */
@Override
List<ITreeMutation> getMutations(boolean shuffle);
Collection<IFruitProvider> getFruitProvidersForFruitFamily(IFruitFamily fruitFamily);
}
@@ -57,6 +57,6 @@ public enum WoodBlockKind {
break;
}
textures.putAll(customTextures);
return model.retexture(new ImmutableMap.Builder<String, String>().putAll(textures).build());
return model.retexture(ImmutableMap.copyOf(textures));
}
}
@@ -0,0 +1,13 @@
/*******************************************************************************
* Copyright 2011-2014 SirSengir
*
* This work (the API) is licensed under the "MIT" License, see LICENSE.txt for details.
******************************************************************************/
package forestry.api.core;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public interface IBlockPosPredicate {
boolean test(World world, BlockPos blockPos);
}
@@ -7,6 +7,7 @@ package forestry.api.farming;
import java.util.Collection;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
@@ -33,6 +34,8 @@ public interface IFarmLogic {
IFarmLogic setManual(boolean manual);
void addSoil(ItemStack resource, IBlockState soilState, boolean hasMetaData);
@SideOnly(Side.CLIENT)
ResourceLocation getTextureMap();
@@ -11,6 +11,13 @@ import net.minecraft.item.ItemStack;
public interface IFarmRegistry {
/**
* Registers farming logic in registry under given identifier
* @param identifier Valid identifiers: farmArboreal farmWheat farmGourd farmInfernal farmPoales farmSucculentes farmVegetables farmShroom
* @param logic corresponding instance of logic
*/
void registerFarmLogic(String identifier, IFarmLogic logic);
/**
* Can be used to add IFarmables to some of the vanilla farm logics.
* <p>
@@ -1,7 +1,5 @@
package forestry.api.genetics;
import net.minecraftforge.fml.common.eventhandler.Event;
/**
* Called after Forestry has registered all his species alleles of a individual.
*/
@@ -5,10 +5,12 @@
******************************************************************************/
package forestry.api.genetics;
import java.util.Iterator;
import java.util.List;
import forestry.api.apiculture.IBee;
import forestry.api.apiculture.IBeeHousing;
import forestry.api.core.IBlockPosPredicate;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.BlockPos;
@@ -60,17 +62,38 @@ public interface IFlowerRegistry {
*/
boolean growFlower(String flowerType, World world, IIndividual individual, BlockPos pos);
/**
* Gets an iterator over the area a bee can travel from its beeHousing.
* Starts at the bee housing and spirals outward.
*
* @param beeHousing The bee housing that will help determine the size of the area to check.
* @param bee The bee that will help determine the size of the area to check.
* @return an iterator over the area a bee can travel from its beeHousing.
* @since Forestry 5.5.2
*/
Iterator<BlockPos.MutableBlockPos> getAreaIterator(IBeeHousing beeHousing, IBee bee);
/**
* Checks a single coordinate to see if it is an accepted flower.
* @since Forestry 5.5.2
*/
IBlockPosPredicate createAcceptedFlowerPredicate(String flowerType);
/**
* @param beeHousing The bee housing that will help determine the size of the area to check.
* @param bee The bee that will help determine the size of the area to check.
* @param flowerType See {@link forestry.api.apiculture.FlowerManager}.FlowerTypeXXX
* @param maxFlowers the largest number of flowers to check for before returning. Use 1 if you only need 1.
* @return the coordinates of nearby accepted flowers, with size from 0 to maxFlowers.
* @deprecated since Forestry 5.5.2. Use {@link #getAreaIterator(IBeeHousing, IBee)} and {@link #createAcceptedFlowerPredicate(String)}.
*/
@Deprecated
List<BlockPos> getAcceptedFlowerCoordinates(IBeeHousing beeHousing, IBee bee, String flowerType, int maxFlowers);
/**
* Checks a single coordinate to see if it is an accepted flower.
* @deprecated since Forestry 5.5.2. Use {@link #createAcceptedFlowerPredicate(String)}.
*/
@Deprecated
boolean isAcceptedFlower(String flowerType, World world, BlockPos pos);
}
@@ -38,8 +38,6 @@ import forestry.apiculture.network.packets.PacketBeeLogicActive;
import forestry.apiculture.network.packets.PacketBeeLogicActiveEntity;
import forestry.core.config.Constants;
import forestry.core.errors.EnumErrorCode;
import forestry.core.network.IStreamable;
import forestry.core.network.PacketBufferForestry;
import forestry.core.utils.Log;
import forestry.core.utils.NetworkUtil;
import net.minecraft.client.Minecraft;
@@ -48,13 +46,14 @@ import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.PacketBuffer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class BeekeepingLogic implements IBeekeepingLogic, IStreamable {
public class BeekeepingLogic implements IBeekeepingLogic {
private static final int totalBreedingTime = Constants.APIARY_BREEDING_TIME;
@@ -136,7 +135,7 @@ public class BeekeepingLogic implements IBeekeepingLogic, IStreamable {
}
@Override
public void writeData(PacketBufferForestry data) {
public void writeData(PacketBuffer data) {
data.writeBoolean(active);
if (active) {
data.writeItemStack(queenStack);
@@ -145,7 +144,7 @@ public class BeekeepingLogic implements IBeekeepingLogic, IStreamable {
}
@Override
public void readData(PacketBufferForestry data) throws IOException {
public void readData(PacketBuffer data) throws IOException {
boolean active = data.readBoolean();
setActive(active);
if (active) {
@@ -222,7 +221,8 @@ public class BeekeepingLogic implements IBeekeepingLogic, IStreamable {
errorLogic.setCondition(true, errorState);
}
boolean hasFlowers = hasFlowersCache.hasFlowers(queen, housing);
hasFlowersCache.update(queen, housing);
boolean hasFlowers = hasFlowersCache.hasFlowers();
boolean flowerCacheNeedsSync = hasFlowersCache.needsSync();
errorLogic.setCondition(!hasFlowers, EnumErrorCode.NO_FLOWER);
@@ -10,80 +10,92 @@
******************************************************************************/
package forestry.apiculture;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import forestry.api.apiculture.BeeManager;
import forestry.api.apiculture.FlowerManager;
import forestry.api.apiculture.IBee;
import forestry.api.apiculture.IBeeHousing;
import forestry.api.apiculture.IBeeModifier;
import forestry.api.core.INbtReadable;
import forestry.api.core.INbtWritable;
import forestry.api.core.IBlockPosPredicate;
import forestry.api.genetics.IFlowerProvider;
import forestry.core.network.IStreamable;
import forestry.core.network.PacketBufferForestry;
import forestry.core.utils.VectUtil;
import forestry.core.utils.TickHelper;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.World;
public class HasFlowersCache implements INbtWritable, INbtReadable, IStreamable {
private static final String nbtKey = "hasFlowerCache";
private static final String nbtKeyFlowers = "flowers";
private static final String nbtKeyCooldown = "cooldown";
public class HasFlowersCache implements INbtWritable, INbtReadable {
private static final String NBT_KEY = "hasFlowerCache";
private static final String NBT_KEY_FLOWERS = "flowers";
private static final int FLOWER_CHECK_INTERVAL = 200;
private static final Random random = new Random();
private static final int flowerCheckInterval = 128;
private final TickHelper tickHelper = new TickHelper();
private final int flowerCheckTime = random.nextInt(flowerCheckInterval);
private List<BlockPos> flowerCoords = new ArrayList<>();
private int cooldown = 0;
@Nullable
private FlowerData flowerData;
private final List<BlockPos> flowerCoords = new ArrayList<>();
private boolean needsSync = false;
public boolean hasFlowers(IBee queen, IBeeHousing beeHousing) {
IFlowerProvider flowerProvider = queen.getGenome().getFlowerProvider();
String flowerType = flowerProvider.getFlowerType();
private static class FlowerData {
public final String flowerType;
public final IBlockPosPredicate flowerPredicate;
public Iterator<BlockPos.MutableBlockPos> areaIterator;
public FlowerData(IBee queen, IBeeHousing beeHousing) {
IFlowerProvider flowerProvider = queen.getGenome().getFlowerProvider();
this.flowerType = flowerProvider.getFlowerType();
this.flowerPredicate = FlowerManager.flowerRegistry.createAcceptedFlowerPredicate(flowerType);
this.areaIterator = FlowerManager.flowerRegistry.getAreaIterator(beeHousing, queen);
}
public void resetIterator(IBee queen, IBeeHousing beeHousing) {
this.areaIterator = FlowerManager.flowerRegistry.getAreaIterator(beeHousing, queen);
}
}
public void update(IBee queen, IBeeHousing beeHousing) {
if (flowerData == null) {
this.flowerData = new FlowerData(queen, beeHousing);
this.flowerCoords.clear();
}
World world = beeHousing.getWorldObj();
tickHelper.onTick();
if (!flowerCoords.isEmpty()) {
if (world.getTotalWorldTime() % flowerCheckInterval != flowerCheckTime) {
return true;
}
IBeeModifier beeModifier = BeeManager.beeRoot.createBeeHousingModifier(beeHousing);
BlockPos housingCoords = beeHousing.getCoordinates();
Vec3i genomeTerritory = queen.getGenome().getTerritory();
float housingModifier = beeModifier.getTerritoryModifier(queen.getGenome(), 1f);
Vec3i area = VectUtil.scale(genomeTerritory, housingModifier * 3.0f);
BlockPos min = VectUtil.scale(area, -0.5f).add(housingCoords);
BlockPos max = VectUtil.scale(area, 0.5f).add(housingCoords);
for (BlockPos flowerPos : flowerCoords) {
if (!isFlowerValid(world, flowerPos, flowerType, min, max)) {
cooldown = 0;
break;
if (!flowerCoords.isEmpty() && tickHelper.updateOnInterval(FLOWER_CHECK_INTERVAL)) {
Iterator<BlockPos> iterator = flowerCoords.iterator();
while (iterator.hasNext()) {
BlockPos flowerPos = iterator.next();
if (!flowerData.flowerPredicate.test(world, flowerPos) && world.isBlockLoaded(flowerPos)) {
iterator.remove();
needsSync = true;
}
}
}
if (cooldown <= 0) {
List<BlockPos> newFlowerCoords = FlowerManager.flowerRegistry.getAcceptedFlowerCoordinates(beeHousing, queen, flowerType, 5);
cooldown = PluginApiculture.ticksPerBeeWorkCycle;
if (!flowerCoords.equals(newFlowerCoords)) {
flowerCoords = newFlowerCoords;
needsSync = true;
}
} else {
cooldown--;
}
final int flowerCount = flowerCoords.size();
final int ticksPerCheck = 1 + (flowerCount * flowerCount);
if (tickHelper.updateOnInterval(ticksPerCheck)) {
if (flowerData.areaIterator.hasNext()) {
BlockPos.MutableBlockPos blockPos = flowerData.areaIterator.next();
if (flowerData.flowerPredicate.test(world, blockPos)) {
flowerCoords.add(blockPos.toImmutable());
needsSync = true;
}
} else {
flowerData.resetIterator(queen, beeHousing);
}
}
}
public boolean hasFlowers() {
return !flowerCoords.isEmpty();
}
@@ -95,35 +107,23 @@ public class HasFlowersCache implements INbtWritable, INbtReadable, IStreamable
public void clear() {
flowerCoords.clear();
cooldown = 0;
flowerData = null;
}
public List<BlockPos> getFlowerCoords() {
return Collections.unmodifiableList(flowerCoords);
}
private static boolean isFlowerValid(World world, BlockPos flowerCoords, String flowerType, BlockPos min, BlockPos max) {
if (!isFlowerCoordInRange(flowerCoords, min, max)) {
return false;
}
return FlowerManager.flowerRegistry.isAcceptedFlower(flowerType, world, flowerCoords);
}
private static boolean isFlowerCoordInRange(BlockPos flowerCoords, BlockPos min, BlockPos max) {
return flowerCoords.getX() >= min.getX() && flowerCoords.getX() <= max.getX() && flowerCoords.getY() >= min.getY() && flowerCoords.getY() <= max.getY() && flowerCoords.getZ() >= min.getZ() && flowerCoords.getZ() <= max.getZ();
}
@Override
public void readFromNBT(NBTTagCompound nbttagcompound) {
if (!nbttagcompound.hasKey(nbtKey)) {
if (!nbttagcompound.hasKey(NBT_KEY)) {
return;
}
NBTTagCompound hasFlowerCacheNBT = nbttagcompound.getCompoundTag(nbtKey);
NBTTagCompound hasFlowerCacheNBT = nbttagcompound.getCompoundTag(NBT_KEY);
if (hasFlowerCacheNBT.hasKey(nbtKeyFlowers)) {
int[] flowersList = hasFlowerCacheNBT.getIntArray(nbtKeyFlowers);
if (hasFlowerCacheNBT.hasKey(NBT_KEY_FLOWERS)) {
int[] flowersList = hasFlowerCacheNBT.getIntArray(NBT_KEY_FLOWERS);
if (flowersList.length % 3 == 0) {
int flowerCount = flowersList.length / 3;
for (int i = 0; i < flowerCount; i++) {
@@ -133,8 +133,6 @@ public class HasFlowersCache implements INbtWritable, INbtReadable, IStreamable
needsSync = true;
}
}
cooldown = hasFlowerCacheNBT.getInteger(nbtKeyCooldown);
}
@Override
@@ -151,17 +149,14 @@ public class HasFlowersCache implements INbtWritable, INbtReadable, IStreamable
i++;
}
hasFlowerCacheNBT.setIntArray(nbtKeyFlowers, flowersList);
hasFlowerCacheNBT.setIntArray(NBT_KEY_FLOWERS, flowersList);
}
hasFlowerCacheNBT.setInteger(nbtKeyCooldown, cooldown);
nbttagcompound.setTag(nbtKey, hasFlowerCacheNBT);
nbttagcompound.setTag(NBT_KEY, hasFlowerCacheNBT);
return nbttagcompound;
}
@Override
public void writeData(PacketBufferForestry data) {
public void writeData(PacketBuffer data) {
int size = flowerCoords.size();
data.writeVarInt(size);
if (size > 0) {
@@ -173,8 +168,7 @@ public class HasFlowersCache implements INbtWritable, INbtReadable, IStreamable
}
}
@Override
public void readData(PacketBufferForestry data) throws IOException {
public void readData(PacketBuffer data) throws IOException {
flowerCoords.clear();
int size = data.readVarInt();
@@ -33,6 +33,7 @@ import net.minecraft.potion.PotionUtils;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.DimensionType;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.IChunkGenerator;
@@ -45,6 +46,8 @@ import net.minecraftforge.common.brewing.BrewingRecipeRegistry;
import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.registries.IForgeRegistry;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.event.FMLInterModComms.IMCMessage;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@@ -53,7 +56,6 @@ import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.common.registry.VillagerRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.registries.IForgeRegistry;
import forestry.Forestry;
import forestry.api.apiculture.BeeManager;
@@ -437,87 +439,88 @@ public class PluginApiculture extends BlankForestryPlugin {
// / APIARIST'S ARMOR
ItemStack wovenSilk = coreItems.craftingMaterial.getWovenSilk();
RecipeUtil.addRecipe(items.apiaristHat,
RecipeUtil.addRecipe("apiarist_hat", items.apiaristHat,
"###", "# #",
'#', wovenSilk);
RecipeUtil.addRecipe(items.apiaristChest,
RecipeUtil.addRecipe("apiarist_chest", items.apiaristChest,
"# #", "###", "###",
'#', wovenSilk);
RecipeUtil.addRecipe(items.apiaristLegs,
RecipeUtil.addRecipe("apiarist_legs", items.apiaristLegs,
"###", "# #", "# #",
'#', wovenSilk);
RecipeUtil.addRecipe(items.apiaristBoots,
RecipeUtil.addRecipe("apiarist_boots", items.apiaristBoots,
"# #", "# #",
'#', wovenSilk);
// / HABITAT LOCATOR
RecipeUtil.addRecipe(items.habitatLocator,
RecipeUtil.addRecipe("habitat_locator", items.habitatLocator,
" X ",
"X#X",
" X ",
'#', OreDictUtil.DUST_REDSTONE, 'X', OreDictUtil.INGOT_BRONZE);
// Bees
RecipeUtil.addRecipe(items.scoop,
RecipeUtil.addRecipe("scoop", items.scoop,
"#X#", "###", " # ",
'#', OreDictUtil.STICK_WOOD,
'X', Blocks.WOOL);
RecipeUtil.addRecipe(items.smoker,
RecipeUtil.addRecipe("smoker", items.smoker,
"LS#",
"LF#",
"###",
'#', "ingotTin", 'S', OreDictUtil.STICK_WOOD, 'F', Items.FLINT_AND_STEEL, 'L', OreDictUtil.LEATHER);
RecipeUtil.addRecipe(new ItemStack(Items.SLIME_BALL),
RecipeUtil.addRecipe("propolis_to_slime", new ItemStack(Items.SLIME_BALL),
"#X#", "#X#", "#X#",
'#', items.propolis,
'X', items.pollenCluster.get(EnumPollenCluster.NORMAL, 1));
RecipeUtil.addRecipe(new ItemStack(Items.SPECKLED_MELON),
RecipeUtil.addRecipe("honey_melon", new ItemStack(Items.SPECKLED_MELON),
"#X#", "#Y#", "#X#",
'#', items.honeyDrop,
'X', items.honeydew,
'Y', Items.MELON);
RecipeUtil.addRecipe(items.frameUntreated,
RecipeUtil.addRecipe("frame_untreated", items.frameUntreated,
"###", "#S#", "###",
'#', OreDictUtil.STICK_WOOD,
'S', Items.STRING);
RecipeUtil.addRecipe(items.frameImpregnated,
RecipeUtil.addRecipe("frame_impregnated", items.frameImpregnated,
"###", "#S#", "###",
'#', coreItems.stickImpregnated,
'S', Items.STRING);
RecipeUtil.addRecipe(items.minecartBeehouse.getBeeHouseMinecart(),
RecipeUtil.addRecipe("bee_house_minecart", items.minecartBeehouse.getBeeHouseMinecart(),
"B",
"C",
'B', new ItemStack(blocks.beeHouse),
'C', Items.MINECART);
RecipeUtil.addRecipe(items.minecartBeehouse.getApiaryMinecart(),
RecipeUtil.addRecipe("apiary_minecart", items.minecartBeehouse.getApiaryMinecart(),
"B",
"C",
'B', new ItemStack(blocks.apiary),
'C', Items.MINECART);
for(int i = 0;i < blocks.beeCombs.length;i++){
BlockHoneyComb block = blocks.beeCombs[i];
for(int m = 0;m < EnumHoneyComb.VALUES.length - i * 16;m++){
RecipeUtil.addRecipe(new ItemStack(block, 1, m),
for(int blockCount = 0;blockCount < blocks.beeCombs.length;blockCount++){
BlockHoneyComb block = blocks.beeCombs[blockCount];
for(int blockMeta = 0;blockMeta < EnumHoneyComb.VALUES.length - blockCount * 16;blockMeta++){
int itemMeta = blockMeta + blockCount * 16;
RecipeUtil.addRecipe("comb." + itemMeta, new ItemStack(block, 1, blockMeta),
"###",
"###",
"###", '#', items.beeComb.get(EnumHoneyComb.get(i * 16 + m), 1));
"###", '#', items.beeComb.get(EnumHoneyComb.get(itemMeta), 1));
}
}
// FOOD STUFF
if (ForestryAPI.enabledPlugins.contains(ForestryPluginUids.FOOD)) {
ItemRegistryFood foodItems = PluginFood.getItems();
RecipeUtil.addRecipe(new ItemStack(foodItems.honeyedSlice, 4),
RecipeUtil.addRecipe("honeyed_slice", new ItemStack(foodItems.honeyedSlice, 4),
"###", "#X#", "###",
'#', items.honeyDrop,
'X', Items.BREAD);
RecipeUtil.addRecipe(foodItems.honeyPot,
RecipeUtil.addRecipe("honey_pot", foodItems.honeyPot,
"# #", " X ", "# #",
'#', items.honeyDrop,
'X', fluidItems.waxCapsuleEmpty);
RecipeUtil.addRecipe(foodItems.ambrosia,
RecipeUtil.addRecipe("ambrosia", foodItems.ambrosia,
"#Y#", "XXX", "###",
'#', items.honeydew,
'X', items.royalJelly,
@@ -529,33 +532,33 @@ public class PluginApiculture extends BlankForestryPlugin {
int outputCapsuleAmount = ForestryAPI.activeMode.getIntegerSetting("recipe.output.capsule");
if (outputCapsuleAmount > 0) {
ItemStack capsule = fluidItems.waxCapsuleEmpty.getItemStack(outputCapsuleAmount);
RecipeUtil.addRecipe(capsule, "###", '#', coreItems.beeswax);
RecipeUtil.addRecipe("wax_capsule", capsule, "###", '#', coreItems.beeswax);
}
int outputRefractoryAmount = ForestryAPI.activeMode.getIntegerSetting("recipe.output.refractory");
if (outputRefractoryAmount > 0) {
ItemStack capsule = fluidItems.refractoryEmpty.getItemStack(outputRefractoryAmount);
RecipeUtil.addRecipe(capsule, "###", '#', coreItems.refractoryWax);
RecipeUtil.addRecipe("refractory_capsule", capsule, "###", '#', coreItems.refractoryWax);
}
// / BITUMINOUS PEAT
RecipeUtil.addRecipe(coreItems.bituminousPeat.getItemStack(),
RecipeUtil.addRecipe("bituminous_peat", coreItems.bituminousPeat.getItemStack(),
" # ", "XYX", " # ",
'#', OreDictUtil.DUST_ASH,
'X', coreItems.peat,
'Y', items.propolis);
// / TORCHES
RecipeUtil.addRecipe(new ItemStack(Blocks.TORCH, 3),
RecipeUtil.addRecipe("beeswax_worth", new ItemStack(Blocks.TORCH, 3),
" # ", " # ", " Y ",
'#', coreItems.beeswax,
'Y', OreDictUtil.STICK_WOOD);
RecipeUtil.addRecipe(coreItems.craftingMaterial.getPulsatingMesh(),
RecipeUtil.addRecipe("pulsating_mesh", coreItems.craftingMaterial.getPulsatingMesh(),
"# #", " # ", "# #",
'#', items.propolis.get(EnumPropolis.PULSATING, 1));
// / WAX CAST
RecipeUtil.addRecipe(items.waxCast,
RecipeUtil.addRecipe("wax_cast", items.waxCast,
"###",
"# #",
"###",
@@ -563,14 +566,14 @@ public class PluginApiculture extends BlankForestryPlugin {
// / ALVEARY
ItemStack alvearyPlainBlock = blocks.getAlvearyBlock(BlockAlvearyType.PLAIN);
RecipeUtil.addRecipe(alvearyPlainBlock,
RecipeUtil.addRecipe("alveary_plain", alvearyPlainBlock,
"###",
"#X#",
"###",
'X', coreItems.impregnatedCasing,
'#', coreItems.craftingMaterial.getScentedPaneling());
// SWARMER
RecipeUtil.addRecipe(blocks.getAlvearyBlock(BlockAlvearyType.SWARMER),
RecipeUtil.addRecipe("alveary_swarmer", blocks.getAlvearyBlock(BlockAlvearyType.SWARMER),
"#G#",
" X ",
"#G#",
@@ -578,7 +581,7 @@ public class PluginApiculture extends BlankForestryPlugin {
'X', alvearyPlainBlock,
'G', OreDictUtil.INGOT_GOLD);
// FAN
RecipeUtil.addRecipe(blocks.getAlvearyBlock(BlockAlvearyType.FAN),
RecipeUtil.addRecipe("alveary_fan", blocks.getAlvearyBlock(BlockAlvearyType.FAN),
"I I",
" X ",
"I#I",
@@ -586,7 +589,7 @@ public class PluginApiculture extends BlankForestryPlugin {
'X', alvearyPlainBlock,
'I', OreDictUtil.INGOT_IRON);
// HEATER
RecipeUtil.addRecipe(blocks.getAlvearyBlock(BlockAlvearyType.HEATER),
RecipeUtil.addRecipe("alveary_heater", blocks.getAlvearyBlock(BlockAlvearyType.HEATER),
"#I#",
" X ",
"YYY",
@@ -594,7 +597,7 @@ public class PluginApiculture extends BlankForestryPlugin {
'X', alvearyPlainBlock,
'I', OreDictUtil.INGOT_IRON, 'Y', OreDictUtil.STONE);
// HYGROREGULATOR
RecipeUtil.addRecipe(blocks.getAlvearyBlock(BlockAlvearyType.HYGRO),
RecipeUtil.addRecipe("alveary_hygro", blocks.getAlvearyBlock(BlockAlvearyType.HYGRO),
"GIG",
"GXG",
"GIG",
@@ -602,14 +605,14 @@ public class PluginApiculture extends BlankForestryPlugin {
'I', OreDictUtil.INGOT_IRON,
'G', OreDictUtil.BLOCK_GLASS);
// STABILISER
RecipeUtil.addRecipe(blocks.getAlvearyBlock(BlockAlvearyType.STABILISER),
RecipeUtil.addRecipe("alveary_stabiliser", blocks.getAlvearyBlock(BlockAlvearyType.STABILISER),
"G G",
"GXG",
"G G",
'X', alvearyPlainBlock,
'G', OreDictUtil.GEM_QUARTZ);
// SIEVE
RecipeUtil.addRecipe(blocks.getAlvearyBlock(BlockAlvearyType.SIEVE),
RecipeUtil.addRecipe("alveary_sieve", blocks.getAlvearyBlock(BlockAlvearyType.SIEVE),
"III",
" X ",
"WWW",
@@ -657,8 +660,8 @@ public class PluginApiculture extends BlankForestryPlugin {
"#X#",
'#', coreItems.beeswax,
'X', coreItems.craftingMaterial.getSilkWisp());
RecipeUtil.addShapelessRecipe(blocks.candle.getUnlitCandle(1), blocks.candle.getUnlitCandle(1));
RecipeUtil.addShapelessRecipe(blocks.candle.getLitCandle(1), blocks.candle.getLitCandle(1));
RecipeUtil.addShapelessRecipe("candle_unlit_reset", blocks.candle.getUnlitCandle(1), blocks.candle.getUnlitCandle(1));
RecipeUtil.addShapelessRecipe("candle_lit_reset", blocks.candle.getLitCandle(1), blocks.candle.getLitCandle(1));
// / CENTRIFUGE
// Honey combs
@@ -758,7 +761,7 @@ public class PluginApiculture extends BlankForestryPlugin {
RecipeManagers.fermenterManager.addRecipe(items.honeydew.getItemStack(), 500, 1.0f, Fluids.SHORT_MEAD.getFluid(1), Fluids.FOR_HONEY.getFluid(1));
}
RecipeUtil.addRecipe(blocks.apiary,
RecipeUtil.addRecipe("apiary", blocks.apiary,
"XXX",
"#C#",
"###",
@@ -766,7 +769,7 @@ public class PluginApiculture extends BlankForestryPlugin {
'#', OreDictUtil.PLANK_WOOD,
'C', coreItems.impregnatedCasing);
RecipeUtil.addRecipe(blocks.beeChest,
RecipeUtil.addRecipe("bee_chest", blocks.beeChest,
" # ",
"XYX",
"XXX",
@@ -774,7 +777,7 @@ public class PluginApiculture extends BlankForestryPlugin {
'X', OreDictUtil.BEE_COMB,
'Y', OreDictUtil.CHEST_WOOD);
RecipeUtil.addRecipe(blocks.beeHouse,
RecipeUtil.addRecipe("bee_house", blocks.beeHouse,
"XXX",
"#C#",
"###",
@@ -899,8 +902,18 @@ public class PluginApiculture extends BlankForestryPlugin {
@Override
public void populateChunk(IChunkGenerator chunkGenerator, World world, Random rand, int chunkX, int chunkZ, boolean hasVillageGenerated) {
if(!world.provider.getDimensionType().equals(DimensionType.THE_END)) return;
if (Config.getBeehivesAmount() > 0.0) {
HiveDecorator.decorateHives(chunkGenerator, world, rand, chunkX, chunkZ, hasVillageGenerated);
HiveDecorator.decorateHives(world, rand, chunkX, chunkZ);
}
}
@Override
public void decorateBiome(World world, Random rand, BlockPos pos) {
if (Config.getBeehivesAmount() > 0.0) {
int chunkX = pos.getX() >> 4;
int chunkZ = pos.getZ() >> 4;
HiveDecorator.decorateHives(world, rand, chunkX, chunkZ);
}
}
@@ -0,0 +1,166 @@
/*******************************************************************************
* Copyright (c) 2011-2014 SirSengir.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License v3
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl-3.0.txt
*
* Various Contributors including, but not limited to:
* SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges
******************************************************************************/
package forestry.apiculture;
import java.io.IOException;
import java.util.List;
import forestry.api.apiculture.IBee;
import forestry.api.apiculture.IBeekeepingLogic;
import forestry.api.genetics.IEffectData;
import forestry.apiculture.network.packets.PacketBeeLogicActive;
import forestry.apiculture.tiles.TileHive;
import forestry.core.utils.NetworkUtil;
import forestry.core.utils.TickHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class WorldgenBeekeepingLogic implements IBeekeepingLogic {
private final TileHive housing;
private IEffectData effectData[] = new IEffectData[2];
private final HasFlowersCache hasFlowersCache = new HasFlowersCache();
private final TickHelper tickHelper = new TickHelper();
// Client
private boolean active;
public WorldgenBeekeepingLogic(TileHive housing) {
this.housing = housing;
}
// / SAVING & LOADING
@Override
public void readFromNBT(NBTTagCompound nbttagcompound) {
setActive(nbttagcompound.getBoolean("Active"));
hasFlowersCache.readFromNBT(nbttagcompound);
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbttagcompound) {
nbttagcompound.setBoolean("Active", active);
hasFlowersCache.writeToNBT(nbttagcompound);
return nbttagcompound;
}
@Override
public void writeData(PacketBuffer data) {
data.writeBoolean(active);
if (active) {
hasFlowersCache.writeData(data);
}
}
@Override
public void readData(PacketBuffer data) throws IOException {
boolean active = data.readBoolean();
setActive(active);
if (active) {
hasFlowersCache.readData(data);
}
}
/* Activatable */
private void setActive(boolean active) {
if (this.active == active) {
return;
}
this.active = active;
syncToClient();
}
/* UPDATING */
@Override
public boolean canWork() {
tickHelper.onTick();
IBee queen = housing.getContainedBee();
hasFlowersCache.update(queen, housing);
if (tickHelper.updateOnInterval(200)) {
World world = housing.getWorldObj();
boolean canWork = (world.isDaytime() || queen.getGenome().getNeverSleeps()) &&
(!housing.isRaining() || queen.getGenome().getToleratesRain());
boolean flowerCacheNeedsSync = hasFlowersCache.needsSync();
if (active != canWork) {
setActive(canWork);
} else if (flowerCacheNeedsSync) {
syncToClient();
}
}
return active;
}
@Override
public void doWork() {
}
@Override
public void clearCachedValues() {
if (!housing.getWorldObj().isRemote) {
hasFlowersCache.clear();
canWork();
}
}
/* CLIENT */
@Override
public void syncToClient() {
World world = housing.getWorldObj();
if (world != null && !world.isRemote) {
NetworkUtil.sendNetworkPacket(new PacketBeeLogicActive(housing), housing.getCoordinates(), world);
}
}
@Override
public void syncToClient(EntityPlayerMP player) {
World world = housing.getWorldObj();
if (world != null && !world.isRemote) {
NetworkUtil.sendToPlayer(new PacketBeeLogicActive(housing), player);
}
}
@Override
public int getBeeProgressPercent() {
return 0;
}
@Override
@SideOnly(Side.CLIENT)
public boolean canDoBeeFX() {
return !Minecraft.getMinecraft().isGamePaused() && active;
}
@Override
@SideOnly(Side.CLIENT)
public void doBeeFX() {
IBee queen = housing.getContainedBee();
queen.doFX(effectData, housing);
}
@Override
public List<BlockPos> getFlowerPositions() {
return hasFlowersCache.getFlowerCoords();
}
}
@@ -13,8 +13,8 @@ package forestry.apiculture.blocks;
import java.util.Map;
import forestry.api.core.Tabs;
import forestry.apiculture.items.ItemBlockHoneyComb;
import forestry.apiculture.items.ItemBlockCandle;
import forestry.apiculture.items.ItemBlockHoneyComb;
import forestry.core.blocks.BlockBase;
import forestry.core.blocks.BlockRegistry;
import forestry.core.items.ItemBlockForestry;
@@ -33,23 +33,23 @@ public class BlockRegistryApiculture extends BlockRegistry {
public BlockRegistryApiculture() {
apiary = new BlockApiculture(BlockTypeApiculture.APIARY);
registerBlock(apiary, new ItemBlockForestry(apiary), "apiary");
registerBlock(apiary, new ItemBlockForestry<>(apiary), "apiary");
beeHouse = new BlockApiculture(BlockTypeApiculture.BEE_HOUSE);
registerBlock(beeHouse, new ItemBlockForestry(beeHouse), "bee_house");
registerBlock(beeHouse, new ItemBlockForestry<>(beeHouse), "bee_house");
beeChest = new BlockBase<>(BlockTypeApicultureTesr.APIARIST_CHEST, Material.WOOD);
registerBlock(beeChest, new ItemBlockForestry(beeChest), "bee_chest");
registerBlock(beeChest, new ItemBlockForestry<>(beeChest), "bee_chest");
beeChest.setCreativeTab(Tabs.tabApiculture);
beeChest.setHarvestLevel("axe", 0);
beehives = new BlockBeeHives();
registerBlock(beehives, new ItemBlockForestry(beehives), "beehives");
registerBlock(beehives, new ItemBlockForestry<>(beehives), "beehives");
candle = new BlockCandle();
registerBlock(candle, new ItemBlockCandle(candle), "candle");
stump = new BlockStump();
registerBlock(stump, new ItemBlockForestry(stump), "stump");
registerBlock(stump, new ItemBlockForestry<>(stump), "stump");
beeCombs = BlockHoneyComb.create();
for(int i = 0;i < beeCombs.length;i++){
@@ -59,7 +59,7 @@ public class BlockRegistryApiculture extends BlockRegistry {
alvearyBlockMap = BlockAlveary.create();
for (BlockAlveary block : alvearyBlockMap.values()) {
registerBlock(block, new ItemBlockForestry(block), "alveary." + block.getAlvearyType());
registerBlock(block, new ItemBlockForestry<>(block), "alveary." + block.getAlvearyType());
}
}
@@ -21,7 +21,7 @@ public class ApicultureJeiPlugin implements IModPlugin {
ISubtypeRegistry.ISubtypeInterpreter beeSubtypeInterpreter = itemStack -> {
IAlleleSpecies species = Genome.getSpeciesDirectly(BeeManager.beeRoot, itemStack);
return species == null ? null : species.getUID();
return species == null ? ISubtypeRegistry.ISubtypeInterpreter.NONE : species.getUID();
};
subtypeRegistry.registerSubtypeInterpreter(items.beeDroneGE, beeSubtypeInterpreter);
@@ -33,6 +33,7 @@ import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Tuple;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@@ -89,8 +90,11 @@ public class EntityMinecartApiary extends EntityMinecartBeeHousingBase implement
beeModifiers.add(beeModifier);
for (IHiveFrame frame : inventory.getFrames()) {
beeModifiers.add(frame.getBeeModifier());
for (Tuple<IHiveFrame, ItemStack> frame : inventory.getFrames()) {
IHiveFrame hiveFrame = frame.getFirst();
ItemStack stack = frame.getSecond();
IBeeModifier beeModifier = hiveFrame.getBeeModifier(stack);
beeModifiers.add(beeModifier);
}
return beeModifiers;
@@ -36,6 +36,7 @@ import forestry.core.owner.OwnerHandler;
import forestry.core.tiles.IClimatised;
import forestry.core.utils.ClimateUtil;
import forestry.core.utils.NetworkUtil;
import forestry.core.utils.TickHelper;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.EntityDataManager;
@@ -47,12 +48,10 @@ import net.minecraft.world.biome.Biome;
public abstract class EntityMinecartBeeHousingBase extends EntityMinecartContainerForestry implements IBeeHousing, IOwnedTile, IGuiBeeHousingDelegate, IClimatised, IStreamableGui {
private static final DataParameter<Optional<GameProfile>> OWNER = EntityDataManager.createKey(EntityMinecartBeeHousingBase.class, GameProfileDataSerializer.INSTANCE);
private static final Random random = new Random();
private static final int beeFXInterval = 4;
private static final int pollenFXInterval = 50;
private final int beeFXTime = random.nextInt(beeFXInterval);
private final int pollenFXTime = random.nextInt(pollenFXInterval);
private final TickHelper tickHelper = new TickHelper();
private final IBeekeepingLogic beeLogic = BeeManager.beeRoot.createBeekeepingLogic(this);
private final IErrorLogic errorLogic = ForestryAPI.errorStateRegistry.createErrorLogic();
@@ -184,6 +183,7 @@ public abstract class EntityMinecartBeeHousingBase extends EntityMinecartContain
@Override
public void onUpdate() {
super.onUpdate();
tickHelper.onTick();
if (!world.isRemote) {
if (beeLogic.canWork()) {
beeLogic.doWork();
@@ -196,11 +196,11 @@ public abstract class EntityMinecartBeeHousingBase extends EntityMinecartContain
}
if (beeLogic.canDoBeeFX()) {
if (world.getTotalWorldTime() % beeFXInterval == beeFXTime) {
if (tickHelper.updateOnInterval(beeFXInterval)) {
beeLogic.doBeeFX();
}
if (world.getTotalWorldTime() % pollenFXInterval == pollenFXTime) {
if (tickHelper.updateOnInterval(pollenFXInterval)) {
TileBeeHousingBase.doPollenFX(world, posX - 0.5, posY - 0.1, posZ - 0.5);
}
}
@@ -12,6 +12,7 @@ package forestry.apiculture.flowers;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
@@ -27,11 +28,13 @@ import forestry.api.apiculture.IBee;
import forestry.api.apiculture.IBeeGenome;
import forestry.api.apiculture.IBeeHousing;
import forestry.api.apiculture.IBeeModifier;
import forestry.api.core.IBlockPosPredicate;
import forestry.api.genetics.IFlowerAcceptableRule;
import forestry.api.genetics.IFlowerGrowthHelper;
import forestry.api.genetics.IFlowerGrowthRule;
import forestry.api.genetics.IFlowerRegistry;
import forestry.api.genetics.IIndividual;
import forestry.core.utils.BlockStateSet;
import forestry.core.utils.VectUtil;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
@@ -43,7 +46,7 @@ import net.minecraft.world.World;
public final class FlowerRegistry implements IFlowerRegistry, IFlowerGrowthHelper {
private final HashMultimap<String, IFlowerAcceptableRule> registeredRules;
private final HashMultimap<String, Block> acceptableBlocks;
private final HashMultimap<String, IBlockState> acceptableBlockStates;
private final Map<String, BlockStateSet> acceptableBlockStates;
private final HashMultimap<String, Flower> plantableFlowers;
private final ArrayListMultimap<String, IFlowerGrowthRule> growthRules;
@@ -52,7 +55,7 @@ public final class FlowerRegistry implements IFlowerRegistry, IFlowerGrowthHelpe
public FlowerRegistry() {
this.registeredRules = HashMultimap.create();
this.acceptableBlocks = HashMultimap.create();
this.acceptableBlockStates = HashMultimap.create();
this.acceptableBlockStates = new HashMap<>();
this.plantableFlowers = HashMultimap.create();
this.growthRules = ArrayListMultimap.create();
this.chances = new HashMap<>();
@@ -78,7 +81,7 @@ public final class FlowerRegistry implements IFlowerRegistry, IFlowerGrowthHelpe
throw new NullPointerException("Tried to register flower with null type. " + blockState);
}
this.acceptableBlockStates.get(flowerType).add(blockState);
this.getAcceptedBlockStates(flowerType).add(blockState);
}
}
@@ -113,7 +116,7 @@ public final class FlowerRegistry implements IFlowerRegistry, IFlowerGrowthHelpe
Set<Flower> flowers = this.plantableFlowers.get(flowerType);
flowers.add(newFlower);
Set<IBlockState> blocks = this.acceptableBlockStates.get(flowerType);
Set<IBlockState> blocks = this.getAcceptedBlockStates(flowerType);
blocks.add(blockState);
if (this.chances.containsKey(flowerType)) {
@@ -129,43 +132,16 @@ public final class FlowerRegistry implements IFlowerRegistry, IFlowerGrowthHelpe
}
@Override
public List<BlockPos> getAcceptedFlowerCoordinates(IBeeHousing beeHousing, IBee bee, String flowerType, int maxFlowers) {
Set<IFlowerAcceptableRule> acceptableRules = this.registeredRules.get(flowerType);
Set<IBlockState> acceptedBlockStates = this.acceptableBlockStates.get(flowerType);
Set<Block> acceptedBlocks = this.acceptableBlocks.get(flowerType);
World world = beeHousing.getWorldObj();
IBeeModifier beeModifier = BeeManager.beeRoot.createBeeHousingModifier(beeHousing);
Vec3i area = getArea(bee.getGenome(), beeModifier);
BlockPos minPos = beeHousing.getCoordinates().add(-area.getX() / 2, -area.getY() / 2, -area.getZ() / 2);
BlockPos maxPos = minPos.add(area);
List<BlockPos> flowerCoords = new ArrayList<>();
for (BlockPos.MutableBlockPos posBlock : VectUtil.getAllInBoxFromCenterMutable(world, minPos, beeHousing.getCoordinates(), maxPos)) {
if (!world.isBlockLoaded(posBlock)) {
continue;
}
IBlockState blockState = world.getBlockState(posBlock);
if (blockState.getBlock().isAir(blockState, world, posBlock)) {
continue;
}
for (IFlowerAcceptableRule acceptableRule : acceptableRules) {
if (acceptableRule.isAcceptableFlower(blockState, world, posBlock, flowerType)) {
flowerCoords.add(posBlock.toImmutable());
if (flowerCoords.size() >= maxFlowers) {
return flowerCoords;
}
}
}
if (isAcceptedFlower(blockState, acceptedBlocks, acceptedBlockStates)) {
flowerCoords.add(posBlock.toImmutable());
if (flowerCoords.size() >= maxFlowers) {
return flowerCoords;
}
World world = beeHousing.getWorldObj();
IBlockPosPredicate acceptedFlowerPredicate = createAcceptedFlowerPredicate(flowerType);
Iterator<BlockPos.MutableBlockPos> areaIterator = getAreaIterator(beeHousing, bee);
while (areaIterator.hasNext() && flowerCoords.size() < maxFlowers) {
BlockPos.MutableBlockPos pos = areaIterator.next();
if (acceptedFlowerPredicate.test(world, pos)) {
flowerCoords.add(pos.toImmutable());
}
}
@@ -173,6 +149,17 @@ public final class FlowerRegistry implements IFlowerRegistry, IFlowerGrowthHelpe
}
@Override
public Iterator<BlockPos.MutableBlockPos> getAreaIterator(IBeeHousing beeHousing, IBee bee) {
IBeeModifier beeModifier = BeeManager.beeRoot.createBeeHousingModifier(beeHousing);
Vec3i area = getArea(bee.getGenome(), beeModifier);
BlockPos minPos = beeHousing.getCoordinates().add(-area.getX() / 2, -area.getY() / 2, -area.getZ() / 2);
BlockPos maxPos = minPos.add(area);
World world = beeHousing.getWorldObj();
return VectUtil.getAllInBoxFromCenterMutable(world, minPos, beeHousing.getCoordinates(), maxPos);
}
@Override
@Deprecated
public boolean isAcceptedFlower(String flowerType, World world, BlockPos pos) {
if (!world.isBlockLoaded(pos)) {
return true; // Avoid actually checking until the flower's position is loaded.
@@ -185,12 +172,25 @@ public final class FlowerRegistry implements IFlowerRegistry, IFlowerGrowthHelpe
}
}
Set<IBlockState> acceptedBlockStates = this.acceptableBlockStates.get(flowerType);
Set<IBlockState> acceptedBlockStates = this.getAcceptedBlockStates(flowerType);
Set<Block> acceptedBlocks = this.acceptableBlocks.get(flowerType);
return isAcceptedFlower(blockState, acceptedBlocks, acceptedBlockStates);
}
private Set<IBlockState> getAcceptedBlockStates(String flowerType) {
return this.acceptableBlockStates.computeIfAbsent(flowerType, k -> new BlockStateSet());
}
@Override
public IBlockPosPredicate createAcceptedFlowerPredicate(String flowerType) {
Set<IFlowerAcceptableRule> acceptableRules = this.registeredRules.get(flowerType);
Set<IBlockState> acceptedBlockStates = this.getAcceptedBlockStates(flowerType);
Set<Block> acceptedBlocks = this.acceptableBlocks.get(flowerType);
return new AcceptedFlowerPredicate(flowerType, acceptableRules, acceptedBlocks, acceptedBlockStates);
}
private static boolean isAcceptedFlower(IBlockState blockState, Set<Block> acceptedBlocks, Set<IBlockState> acceptedBlockStates) {
Block block = blockState.getBlock();
return acceptedBlocks.contains(block) || acceptedBlockStates.contains(blockState);
@@ -255,4 +255,37 @@ public final class FlowerRegistry implements IFlowerRegistry, IFlowerGrowthHelpe
Flower flower = getRandomPlantableFlower(flowerType, world.rand);
return world.setBlockState(pos, flower.getBlockState());
}
private static class AcceptedFlowerPredicate implements IBlockPosPredicate {
private final String flowerType;
private final Set<IFlowerAcceptableRule> acceptableRules;
private final Set<Block> acceptedBlocks;
private final Set<IBlockState> acceptedBlockStates;
public AcceptedFlowerPredicate(String flowerType, Set<IFlowerAcceptableRule> acceptableRules, Set<Block> acceptedBlocks, Set<IBlockState> acceptedBlockStates) {
this.flowerType = flowerType;
this.acceptableRules = acceptableRules;
this.acceptedBlocks = acceptedBlocks;
this.acceptedBlockStates = acceptedBlockStates;
}
@Override
public boolean test(World world, BlockPos blockPos) {
if (world.isBlockLoaded(blockPos)) {
IBlockState blockState = world.getBlockState(blockPos);
if (!blockState.getBlock().isAir(blockState, world, blockPos)) {
for (IFlowerAcceptableRule acceptableRule : acceptableRules) {
if (acceptableRule.isAcceptableFlower(blockState, world, blockPos, flowerType)) {
return true;
}
}
if (isAcceptedFlower(blockState, acceptedBlocks, acceptedBlockStates)) {
return true;
}
}
}
return false;
}
}
}
@@ -1024,7 +1024,7 @@ public enum BeeDefinition implements IBeeDefinition {
}
public static void preInit() {
MinecraftForge.EVENT_BUS.post(new AlleleSpeciesRegisterEvent(BeeManager.beeRoot, IAlleleBeeSpecies.class));
MinecraftForge.EVENT_BUS.post(new AlleleSpeciesRegisterEvent<>(BeeManager.beeRoot, IAlleleBeeSpecies.class));
}
private void init() {
@@ -22,6 +22,7 @@ import forestry.apiculture.InventoryBeeHousing;
import forestry.core.utils.SlotUtil;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Tuple;
public class InventoryApiary extends InventoryBeeHousing implements IApiaryInventory {
public static final int SLOT_FRAMES_1 = 9;
@@ -47,14 +48,15 @@ public class InventoryApiary extends InventoryBeeHousing implements IApiaryInven
super.isItemValidForSlot(slotIndex, itemStack);
}
public Collection<IHiveFrame> getFrames() {
Collection<IHiveFrame> hiveFrames = new ArrayList<>(SLOT_FRAMES_COUNT);
public Collection<Tuple<IHiveFrame, ItemStack>> getFrames() {
Collection<Tuple<IHiveFrame, ItemStack>> hiveFrames = new ArrayList<>(SLOT_FRAMES_COUNT);
for (int i = SLOT_FRAMES_1; i < SLOT_FRAMES_1 + SLOT_FRAMES_COUNT; i++) {
ItemStack stackInSlot = getStackInSlot(i);
Item itemInSlot = stackInSlot.getItem();
if (itemInSlot instanceof IHiveFrame) {
hiveFrames.add((IHiveFrame) itemInSlot);
IHiveFrame frame = (IHiveFrame) itemInSlot;
hiveFrames.add(new Tuple<>(frame, stackInSlot.copy()));
}
}
@@ -103,7 +103,9 @@ public class ItemBeeGE extends ItemGE implements IColoredItem {
@Override
public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> subItems) {
addCreativeItems(subItems, true);
if (this.isInCreativeTab(tab)) {
addCreativeItems(subItems, true);
}
}
public void addCreativeItems(NonNullList<ItemStack> subItems, boolean hideSecrets) {
@@ -13,7 +13,6 @@ package forestry.apiculture.items;
import forestry.apiculture.blocks.BlockCandle;
import forestry.core.items.IColoredItem;
import forestry.core.items.ItemBlockForestry;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fml.relauncher.Side;
@@ -21,7 +20,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
public class ItemBlockCandle extends ItemBlockForestry<BlockCandle> implements IColoredItem {
public ItemBlockCandle(Block block) {
public ItemBlockCandle(BlockCandle block) {
super(block);
}
@@ -3,14 +3,13 @@ package forestry.apiculture.items;
import forestry.apiculture.blocks.BlockHoneyComb;
import forestry.core.items.IColoredItem;
import forestry.core.items.ItemBlockForestry;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class ItemBlockHoneyComb extends ItemBlockForestry<BlockHoneyComb> implements IColoredItem {
public ItemBlockHoneyComb(Block block) {
public ItemBlockHoneyComb(BlockHoneyComb block) {
super(block);
}
@@ -52,6 +52,11 @@ public class ItemHiveFrame extends ItemForestry implements IHiveFrame {
}
}
@Override
public IBeeModifier getBeeModifier(ItemStack frame) {
return beeModifier;
}
@Override
public IBeeModifier getBeeModifier() {
return beeModifier;
@@ -62,10 +62,12 @@ public class ItemHoneyComb extends ItemForestry implements IColoredItem {
@Override
public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> subItems) {
for (int i = 0; i < EnumHoneyComb.VALUES.length; i++) {
EnumHoneyComb honeyComb = EnumHoneyComb.get(i);
if (!honeyComb.isSecret() || Config.isDebug) {
subItems.add(new ItemStack(this, 1, i));
if (this.isInCreativeTab(tab)) {
for (int i = 0; i < EnumHoneyComb.VALUES.length; i++) {
EnumHoneyComb honeyComb = EnumHoneyComb.get(i);
if (!honeyComb.isSecret() || Config.isDebug) {
subItems.add(new ItemStack(this, 1, i));
}
}
}
}
@@ -97,8 +97,10 @@ public class ItemMinecartBeehouse extends ItemMinecart implements IItemModelRegi
@Override
public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> subItems) {
for (int i = 0; i < definition.length; i++) {
subItems.add(new ItemStack(this, 1, i));
if (this.isInCreativeTab(tab)) {
for (int i = 0; i < definition.length; i++) {
subItems.add(new ItemStack(this, 1, i));
}
}
}
@@ -14,7 +14,6 @@ import java.io.IOException;
import forestry.api.apiculture.IBeeHousing;
import forestry.api.apiculture.IBeekeepingLogic;
import forestry.apiculture.BeekeepingLogic;
import forestry.core.network.ForestryPacket;
import forestry.core.network.IForestryPacketClient;
import forestry.core.network.IForestryPacketHandlerClient;
@@ -28,11 +27,11 @@ import net.minecraftforge.fml.relauncher.SideOnly;
public class PacketBeeLogicActive extends ForestryPacket implements IForestryPacketClient {
private final BlockPos tilePos;
private final BeekeepingLogic beekeepingLogic;
private final IBeekeepingLogic beekeepingLogic;
public PacketBeeLogicActive(IBeeHousing tile) {
this.tilePos = tile.getCoordinates();
this.beekeepingLogic = (BeekeepingLogic) tile.getBeekeepingLogic();
this.beekeepingLogic = tile.getBeekeepingLogic();
}
@Override
@@ -55,9 +54,7 @@ public class PacketBeeLogicActive extends ForestryPacket implements IForestryPac
IBeeHousing beeHousing = TileUtil.getTile(player.world, tilePos, IBeeHousing.class);
if (beeHousing != null) {
IBeekeepingLogic beekeepingLogic = beeHousing.getBeekeepingLogic();
if (beekeepingLogic instanceof BeekeepingLogic) {
((BeekeepingLogic) beekeepingLogic).readData(data);
}
beekeepingLogic.readData(data);
}
}
}
@@ -29,6 +29,8 @@ import forestry.apiculture.inventory.InventoryApiary;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Tuple;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@@ -58,8 +60,11 @@ public class TileApiary extends TileBeeHousingBase implements IApiary {
beeModifiers.add(beeModifier);
for (IHiveFrame frame : inventory.getFrames()) {
beeModifiers.add(frame.getBeeModifier());
for (Tuple<IHiveFrame, ItemStack> frame : inventory.getFrames()) {
IHiveFrame hiveFrame = frame.getFirst();
ItemStack stack = frame.getSecond();
IBeeModifier beeModifier = hiveFrame.getBeeModifier(stack);
beeModifiers.add(beeModifier);
}
return beeModifiers;
@@ -16,6 +16,8 @@ import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
import forestry.apiculture.WorldgenBeekeepingLogic;
import forestry.core.utils.TickHelper;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityLivingBase;
@@ -59,7 +61,6 @@ import forestry.api.core.EnumTemperature;
import forestry.api.core.ForestryAPI;
import forestry.api.core.IErrorLogic;
import forestry.api.genetics.IAllele;
import forestry.apiculture.BeekeepingLogic;
import forestry.apiculture.blocks.BlockBeeHives;
import forestry.apiculture.genetics.BeeDefinition;
import forestry.apiculture.genetics.alleles.AlleleEffect;
@@ -78,9 +79,10 @@ public class TileHive extends TileEntity implements ITickable, IHiveTile, IActiv
private final InventoryAdapter contained = new InventoryAdapter(2, "Contained");
private final HiveBeeHousingInventory inventory;
private final BeekeepingLogic beeLogic;
private final WorldgenBeekeepingLogic beeLogic;
private final IErrorLogic errorLogic;
private final Predicate<EntityLivingBase> beeTargetPredicate;
private final TickHelper tickHelper = new TickHelper();
@Nullable
private IBee containedBee = null;
@@ -96,7 +98,7 @@ public class TileHive extends TileEntity implements ITickable, IHiveTile, IActiv
public TileHive() {
inventory = new HiveBeeHousingInventory(this);
beeLogic = new BeekeepingLogic(this);
beeLogic = new WorldgenBeekeepingLogic(this);
errorLogic = ForestryAPI.errorStateRegistry.createErrorLogic();
beeTargetPredicate = new BeeTargetPredicate(this);
}
@@ -106,12 +108,13 @@ public class TileHive extends TileEntity implements ITickable, IHiveTile, IActiv
if (Config.generateBeehivesDebug) {
return;
}
tickHelper.onTick();
if (world.isRemote) {
if (!updatedLight && world.getWorldTime() % 100 == 0) {
if (!updatedLight && tickHelper.updateOnInterval(100)) {
updatedLight = world.checkLightFor(EnumSkyBlock.BLOCK, getPos());
}
if (active && world.rand.nextInt(4) == 0) {
if (active && tickHelper.updateOnInterval(4)) {
if (beeLogic.canDoBeeFX()) {
beeLogic.doBeeFX();
}
@@ -119,7 +122,7 @@ public class TileHive extends TileEntity implements ITickable, IHiveTile, IActiv
} else {
boolean canWork = beeLogic.canWork(); // must be called every tick to stay updated
if (world.rand.nextInt(angry ? 10 : 200) == 0) {
if (tickHelper.updateOnInterval(angry ? 10 : 200)) {
if (calmTime == 0) {
if (canWork) {
if(world.getWorldInfo().getDifficulty() != EnumDifficulty.PEACEFUL) {
@@ -26,7 +26,6 @@ import net.minecraft.block.BlockLeaves;
import net.minecraft.block.BlockNewLeaf;
import net.minecraft.block.BlockOldLeaf;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.passive.EntityVillager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
@@ -42,7 +41,8 @@ import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fml.common.IFuelHandler;
import net.minecraftforge.oredict.OreDictionary;
import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.fml.common.event.FMLInterModComms.IMCMessage;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@@ -51,7 +51,6 @@ import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.common.registry.VillagerRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.oredict.OreDictionary;
import forestry.api.arboriculture.EnumForestryWoodType;
import forestry.api.arboriculture.EnumGermlingType;
@@ -72,7 +71,6 @@ import forestry.api.recipes.RecipeManagers;
import forestry.api.storage.ICrateRegistry;
import forestry.api.storage.StorageManager;
import forestry.arboriculture.blocks.BlockArbLog;
import forestry.arboriculture.blocks.BlockArbSlab;
import forestry.arboriculture.blocks.BlockDefaultLeaves;
import forestry.arboriculture.blocks.BlockForestryLeaves;
import forestry.arboriculture.blocks.BlockRegistryArboriculture;
@@ -87,7 +85,6 @@ import forestry.arboriculture.genetics.TreeRoot;
import forestry.arboriculture.genetics.TreekeepingMode;
import forestry.arboriculture.genetics.alleles.AlleleFruits;
import forestry.arboriculture.genetics.alleles.AlleleLeafEffects;
import forestry.arboriculture.items.ItemGermlingGE;
import forestry.arboriculture.items.ItemGrafter;
import forestry.arboriculture.items.ItemRegistryArboriculture;
import forestry.arboriculture.models.TextureLeaves;
@@ -327,29 +324,29 @@ public class PluginArboriculture extends BlankForestryPlugin {
if (woodType instanceof EnumForestryWoodType) {
planks.setCount(4);
logs.setCount(1);
RecipeUtil.addShapelessRecipe(planks.copy(), logs.copy());
RecipeUtil.addShapelessRecipe("planks_" + woodType.getName(), planks.copy(), logs.copy());
slabs.setCount(6);
planks.setCount(1);
RecipeUtil.addRecipe(slabs.copy(), "###", '#', planks.copy());
RecipeUtil.addRecipe("slabs_" + woodType.getName(), slabs.copy(), "###", '#', planks.copy());
fences.setCount(3);
planks.setCount(1);
RecipeUtil.addRecipe(fences.copy(),
RecipeUtil.addRecipe("fences_" + woodType.getName(), fences.copy(),
"#X#",
"#X#",
'#', planks.copy(), 'X', "stickWood");
fenceGates.setCount(1);
planks.setCount(1);
RecipeUtil.addRecipe(fenceGates.copy(),
RecipeUtil.addRecipe("fence_gates_" + woodType.getName(), fenceGates.copy(),
"X#X",
"X#X",
'#', planks.copy(), 'X', "stickWood");
stairs.setCount(4);
planks.setCount(1);
RecipeUtil.addRecipe(stairs.copy(),
RecipeUtil.addRecipe("stairs_" + woodType.getName(), stairs.copy(),
"# ",
"## ",
"###",
@@ -357,7 +354,7 @@ public class PluginArboriculture extends BlankForestryPlugin {
doors.setCount(3);
planks.setCount(1);
RecipeUtil.addRecipe(doors.copy(),
RecipeUtil.addRecipe("doors_" + woodType.getName(), doors.copy(),
"## ",
"## ",
"## ",
@@ -366,31 +363,31 @@ public class PluginArboriculture extends BlankForestryPlugin {
fireproofPlanks.setCount(4);
fireproofLogs.setCount(1);
RecipeUtil.addShapelessRecipe(fireproofPlanks.copy(), fireproofLogs.copy());
RecipeUtil.addShapelessRecipe("fireproof_planks_" + woodType.getName(), fireproofPlanks.copy(), fireproofLogs.copy());
fireproofSlabs.setCount(6);
fireproofPlanks.setCount(1);
RecipeUtil.addRecipe(fireproofSlabs.copy(),
RecipeUtil.addRecipe("fireproof_slabs_" + woodType.getName(), fireproofSlabs.copy(),
"###",
'#', fireproofPlanks.copy());
fireproofFences.setCount(3);
fireproofPlanks.setCount(1);
RecipeUtil.addRecipe(fireproofFences.copy(),
RecipeUtil.addRecipe("fireproof_fences_" + woodType.getName(), fireproofFences.copy(),
"#X#",
"#X#",
'#', fireproofPlanks.copy(), 'X', "stickWood");
fireproofFenceGates.setCount(1);
fireproofPlanks.setCount(1);
RecipeUtil.addRecipe(fireproofFenceGates.copy(),
RecipeUtil.addRecipe("fireproof_fence_gates_" + woodType.getName(), fireproofFenceGates.copy(),
"X#X",
"X#X",
'#', fireproofPlanks.copy(), 'X', "stickWood");
fireproofStairs.setCount(4);
fireproofPlanks.setCount(1);
RecipeUtil.addRecipe(fireproofStairs.copy(),
RecipeUtil.addRecipe("fireproof_stairs_" + woodType.getName(), fireproofStairs.copy(),
"# ",
"## ",
"###",
@@ -398,7 +395,7 @@ public class PluginArboriculture extends BlankForestryPlugin {
doors.setCount(3);
fireproofPlanks.setCount(1);
RecipeUtil.addRecipe(doors.copy(),
RecipeUtil.addRecipe("fireproof_doors_" + woodType.getName(), doors.copy(),
"## ",
"## ",
"## ",
@@ -445,14 +442,14 @@ public class PluginArboriculture extends BlankForestryPlugin {
}
// Grafter
RecipeUtil.addRecipe(items.grafter.getItemStack(),
RecipeUtil.addRecipe("grafter", items.grafter.getItemStack(),
" B",
" # ",
"# ",
'B', "ingotBronze",
'#', "stickWood");
RecipeUtil.addRecipe(blocks.treeChest,
RecipeUtil.addRecipe("tree_chest", blocks.treeChest,
" # ",
"XYX",
"XXX",
@@ -461,10 +458,10 @@ public class PluginArboriculture extends BlankForestryPlugin {
'Y', "chestWood");
//Wood Pile
RecipeUtil.addShapelessRecipe(new ItemStack(blocks.woodPile), OreDictUtil.LOG_WOOD, OreDictUtil.LOG_WOOD, OreDictUtil.LOG_WOOD, OreDictUtil.LOG_WOOD);
RecipeUtil.addShapelessRecipe("wood_pile", new ItemStack(blocks.woodPile), OreDictUtil.LOG_WOOD, OreDictUtil.LOG_WOOD, OreDictUtil.LOG_WOOD, OreDictUtil.LOG_WOOD);
//Dirt Pile Block
RecipeUtil.addShapelessRecipe(new ItemStack(blocks.loam, 4), Items.CLAY_BALL, coreItems.fertilizerBio, Items.CLAY_BALL, OreDictUtil.SAND, Items.CLAY_BALL, OreDictUtil.SAND, Items.CLAY_BALL, coreItems.fertilizerBio, Items.CLAY_BALL);
RecipeUtil.addShapelessRecipe("loam", new ItemStack(blocks.loam, 4), Items.CLAY_BALL, coreItems.compost, Items.CLAY_BALL, OreDictUtil.SAND, Items.CLAY_BALL, OreDictUtil.SAND, Items.CLAY_BALL, coreItems.compost, Items.CLAY_BALL);
}
private static void registerAlleles() {
@@ -544,11 +541,6 @@ public class PluginArboriculture extends BlankForestryPlugin {
}
}
@Override
public IFuelHandler getFuelHandler() {
return new FuelHandler(getItems().sapling);
}
@Override
public IPacketRegistry getPacketRegistry() {
return new PacketRegistryArboriculture();
@@ -575,49 +567,11 @@ public class PluginArboriculture extends BlankForestryPlugin {
hiddenItems.add(new ItemStack(getBlocks().saplingGE));
}
private static class FuelHandler implements IFuelHandler {
private final ItemGermlingGE sapling;
public FuelHandler(ItemGermlingGE sapling) {
this.sapling = sapling;
}
@Override
public int getBurnTime(ItemStack fuel) {
Item item = fuel.getItem();
if (sapling == item) {
return 100;
}
if(Item.getItemFromBlock(blocks.charcoal) == item){
return 16000;
}
if(Item.getItemFromBlock(blocks.woodPile) == item){
return 1200;
}
Block block = Block.getBlockFromItem(item);
if (block instanceof IWoodTyped) {
IWoodTyped woodTypedBlock = (IWoodTyped) block;
if (woodTypedBlock.isFireproof()) {
return 0;
} else if (block instanceof BlockArbSlab) {
return 150;
} else {
return 300;
}
}
return 0;
}
}
@SubscribeEvent
@SideOnly(Side.CLIENT)
public void registerSprites(TextureStitchEvent.Pre event) {
TextureLeaves.registerAllSprites();
WoodTextureManager.parseFile(Minecraft.getMinecraft().getResourceManager());
WoodTextureManager.parseFile();
for (IAlleleFruit alleleFruit : AlleleFruits.getFruitAlleles()) {
alleleFruit.getProvider().registerSprites();
}
@@ -3,21 +3,22 @@ package forestry.arboriculture;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import forestry.api.arboriculture.EnumForestryWoodType;
import forestry.api.arboriculture.EnumVanillaWoodType;
import forestry.api.arboriculture.IWoodItemMeshDefinition;
import forestry.api.arboriculture.IWoodType;
import forestry.api.arboriculture.TreeManager;
import forestry.api.arboriculture.WoodBlockKind;
import forestry.arboriculture.models.WoodModelLoader;
import forestry.core.config.Constants;
import forestry.core.models.ModelManager;
import forestry.core.utils.Translator;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class WoodHelper {
@@ -77,16 +78,18 @@ public class WoodHelper {
@Override
public ModelResourceLocation getModelLocation(ItemStack stack) {
if (!WoodModelLoader.INSTANCE.isEnabled) {
return new ModelResourceLocation(getDefaultModelLocation(stack), "inventory");
}
int meta = stack.getMetadata();
IWoodType woodType = wood.getWoodType(meta);
WoodBlockKind blockKind = wood.getBlockKind();
if (woodType instanceof EnumVanillaWoodType) {
return new ModelResourceLocation("minecraft:" + woodType + "_" + blockKind, "inventory");
} else {
return ModelManager.getInstance().getModelLocation(blockKind + "/" + woodType);
String modID = Constants.MOD_ID;
Block block = Block.getBlockFromItem(stack.getItem());
if(block != null){
modID = block.getRegistryName().getResourceDomain();
}
return new ModelResourceLocation(modID + ":" + blockKind + "/" + woodType, "inventory");
}
}
@@ -142,6 +142,14 @@ public abstract class BlockForestryLog<T extends Enum<T> & IWoodType> extends Bl
return woodType.getHardness();
}
@Override
protected ItemStack getSilkTouchDrop(IBlockState state) {
ItemStack silkTouchDrop = super.getSilkTouchDrop(state);
int damage = this.damageDropped(state);
silkTouchDrop.setItemDamage(damage);
return silkTouchDrop;
}
/* PROPERTIES */
@Override
public final int getFireSpreadSpeed(IBlockAccess world, BlockPos pos, EnumFacing face) {
@@ -32,7 +32,6 @@ import forestry.core.blocks.BlockRegistry;
import forestry.core.items.ItemBlockForestry;
import forestry.core.utils.OreDictUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockLeaves;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.MinecraftForge;
@@ -79,37 +78,37 @@ public class BlockRegistryArboriculture extends BlockRegistry {
// Wood blocks
logs = BlockArbLog.create(false);
for (BlockArbLog block : logs) {
registerBlock(block, new ItemBlockWood(block), "logs." + block.getBlockNumber());
registerBlock(block, new ItemBlockWood<>(block), "logs." + block.getBlockNumber());
registerOreDictWildcard(OreDictUtil.LOG_WOOD, block);
}
logsFireproof = BlockArbLog.create(true);
for (BlockArbLog block : logsFireproof) {
registerBlock(block, new ItemBlockWood(block), "logs.fireproof." + block.getBlockNumber());
registerBlock(block, new ItemBlockWood<>(block), "logs.fireproof." + block.getBlockNumber());
registerOreDictWildcard(OreDictUtil.LOG_WOOD, block);
}
logsVanillaFireproof = BlockFireproofVanillaLog.create();
for (BlockFireproofVanillaLog block : logsVanillaFireproof) {
registerBlock(block, new ItemBlockWood(block), "logs.vanilla.fireproof." + block.getBlockNumber());
registerBlock(block, new ItemBlockWood<>(block), "logs.vanilla.fireproof." + block.getBlockNumber());
registerOreDictWildcard(OreDictUtil.LOG_WOOD, block);
}
planks = BlockArbPlanks.create(false);
for (BlockArbPlanks block : planks) {
registerBlock(block, new ItemBlockWood(block), "planks." + block.getBlockNumber());
registerBlock(block, new ItemBlockWood<>(block), "planks." + block.getBlockNumber());
registerOreDictWildcard(OreDictUtil.PLANK_WOOD, block);
}
planksFireproof = BlockArbPlanks.create(true);
for (BlockArbPlanks block : planksFireproof) {
registerBlock(block, new ItemBlockWood(block), "planks.fireproof." + block.getBlockNumber());
registerBlock(block, new ItemBlockWood<>(block), "planks.fireproof." + block.getBlockNumber());
registerOreDictWildcard(OreDictUtil.PLANK_WOOD, block);
}
planksVanillaFireproof = BlockFireproofVanillaPlanks.create();
for (BlockFireproofVanillaPlanks block : planksVanillaFireproof) {
registerBlock(block, new ItemBlockWood(block), "planks.vanilla.fireproof." + block.getBlockNumber());
registerBlock(block, new ItemBlockWood<>(block), "planks.vanilla.fireproof." + block.getBlockNumber());
registerOreDictWildcard(OreDictUtil.PLANK_WOOD, block);
}
@@ -145,19 +144,19 @@ public class BlockRegistryArboriculture extends BlockRegistry {
fences = BlockArbFence.create(false);
for (BlockArbFence block : fences) {
registerBlock(block, new ItemBlockWood(block), "fences." + block.getBlockNumber());
registerBlock(block, new ItemBlockWood<>(block), "fences." + block.getBlockNumber());
registerOreDictWildcard(OreDictUtil.FENCE_WOOD, block);
}
fencesFireproof = BlockArbFence.create(true);
for (BlockArbFence block : fencesFireproof) {
registerBlock(block, new ItemBlockWood(block), "fences.fireproof." + block.getBlockNumber());
registerBlock(block, new ItemBlockWood<>(block), "fences.fireproof." + block.getBlockNumber());
registerOreDictWildcard(OreDictUtil.FENCE_WOOD, block);
}
fencesVanillaFireproof = BlockFireproofVanillaFence.create();
for (BlockFireproofVanillaFence block : fencesVanillaFireproof) {
registerBlock(block, new ItemBlockWood(block), "fences.vanilla.fireproof." + block.getBlockNumber());
registerBlock(block, new ItemBlockWood<>(block), "fences.vanilla.fireproof." + block.getBlockNumber());
registerOreDictWildcard(OreDictUtil.FENCE_WOOD, block);
}
@@ -165,12 +164,12 @@ public class BlockRegistryArboriculture extends BlockRegistry {
fenceGatesFireproof = new ArrayList<>();
for (EnumForestryWoodType woodType : EnumForestryWoodType.VALUES) {
BlockForestryFenceGate fenceGate = new BlockForestryFenceGate<>(false, woodType);
registerBlock(fenceGate, new ItemBlockWood(fenceGate), "fence.gates." + woodType);
registerBlock(fenceGate, new ItemBlockWood<>(fenceGate), "fence.gates." + woodType);
registerOreDictWildcard(OreDictUtil.FENCE_GATE_WOOD, fenceGate);
fenceGates.add(fenceGate);
BlockForestryFenceGate fenceGateFireproof = new BlockForestryFenceGate<>(true, woodType);
registerBlock(fenceGateFireproof, new ItemBlockWood(fenceGateFireproof), "fence.gates.fireproof." + woodType);
registerBlock(fenceGateFireproof, new ItemBlockWood<>(fenceGateFireproof), "fence.gates.fireproof." + woodType);
registerOreDictWildcard(OreDictUtil.FENCE_GATE_WOOD, fenceGateFireproof);
fenceGatesFireproof.add(fenceGateFireproof);
}
@@ -178,7 +177,7 @@ public class BlockRegistryArboriculture extends BlockRegistry {
fenceGatesVanillaFireproof = new ArrayList<>();
for (EnumVanillaWoodType woodType : EnumVanillaWoodType.VALUES) {
BlockForestryFenceGate fenceGateFireproof = new BlockForestryFenceGate<>(true, woodType);
registerBlock(fenceGateFireproof, new ItemBlockWood(fenceGateFireproof), "fence.gates.vanilla.fireproof." + woodType);
registerBlock(fenceGateFireproof, new ItemBlockWood<>(fenceGateFireproof), "fence.gates.vanilla.fireproof." + woodType);
registerOreDictWildcard(OreDictUtil.FENCE_GATE_WOOD, fenceGateFireproof);
fenceGatesFireproof.add(fenceGateFireproof);
}
@@ -190,7 +189,7 @@ public class BlockRegistryArboriculture extends BlockRegistry {
EnumForestryWoodType woodType = plank.getWoodType(meta);
BlockForestryStairs stair = new BlockForestryStairs<>(false, blockState, woodType);
registerBlock(stair, new ItemBlockWood(stair), "stairs." + woodType);
registerBlock(stair, new ItemBlockWood<>(stair), "stairs." + woodType);
registerOreDictWildcard(OreDictUtil.STAIR_WOOD, stair);
stairs.add(stair);
}
@@ -203,7 +202,7 @@ public class BlockRegistryArboriculture extends BlockRegistry {
EnumForestryWoodType woodType = plank.getWoodType(meta);
BlockForestryStairs stair = new BlockForestryStairs<>(true, blockState, woodType);
registerBlock(stair, new ItemBlockWood(stair), "stairs.fireproof." + woodType);
registerBlock(stair, new ItemBlockWood<>(stair), "stairs.fireproof." + woodType);
registerOreDictWildcard(OreDictUtil.STAIR_WOOD, stair);
stairsFireproof.add(stair);
}
@@ -216,7 +215,7 @@ public class BlockRegistryArboriculture extends BlockRegistry {
EnumVanillaWoodType woodType = plank.getWoodType(meta);
BlockForestryStairs stair = new BlockForestryStairs<>(true, blockState, woodType);
registerBlock(stair, new ItemBlockWood(stair), "stairs.vanilla.fireproof." + woodType);
registerBlock(stair, new ItemBlockWood<>(stair), "stairs.vanilla.fireproof." + woodType);
registerOreDictWildcard(OreDictUtil.STAIR_WOOD, stair);
stairsVanillaFireproof.add(stair);
}
@@ -233,7 +232,7 @@ public class BlockRegistryArboriculture extends BlockRegistry {
// Saplings
TreeDefinition.preInit();
saplingGE = new BlockSapling();
registerBlock(saplingGE, new ItemBlockForestry(saplingGE), "sapling_ge");
registerBlock(saplingGE, new ItemBlockForestry<>(saplingGE), "sapling_ge");
registerOreDictWildcard(OreDictUtil.TREE_SAPLING, saplingGE);
// Leaves
@@ -271,17 +270,29 @@ public class BlockRegistryArboriculture extends BlockRegistry {
}
charcoal = new BlockCharcoal();
registerBlock(charcoal, new ItemBlockForestry(charcoal), "charcoal");
ItemBlockForestry itemBlockCharcoal = new ItemBlockForestry<BlockCharcoal>(charcoal) {
@Override
public int getItemBurnTime(ItemStack itemStack) {
return 16000;
}
};
registerBlock(charcoal, itemBlockCharcoal, "charcoal");
woodPile = new BlockWoodPile();
registerBlock(woodPile, new ItemBlockForestry(woodPile), "wood_pile");
ItemBlockForestry itemBlockWoodPile = new ItemBlockForestry<BlockWoodPile>(woodPile) {
@Override
public int getItemBurnTime(ItemStack itemStack) {
return 1200;
}
};
registerBlock(woodPile, itemBlockWoodPile, "wood_pile");
loam = new BlockLoam();
registerBlock(loam, new ItemBlockForestry(loam), "loam");
registerBlock(loam, new ItemBlockForestry<>(loam), "loam");
// Pods
AlleleFruits.registerAlleles();
MinecraftForge.EVENT_BUS.post(new AlleleRegisterEvent(IAlleleFruit.class));
MinecraftForge.EVENT_BUS.post(new AlleleRegisterEvent<>(IAlleleFruit.class));
podsMap = new HashMap<>();
for (BlockFruitPod pod : BlockFruitPod.create()) {
IAlleleFruit fruit = pod.getFruit();
@@ -291,7 +302,7 @@ public class BlockRegistryArboriculture extends BlockRegistry {
// Machines
treeChest = new BlockArboriculture(BlockTypeArboricultureTesr.ARB_CHEST);
registerBlock(treeChest, new ItemBlockForestry(treeChest), "tree_chest");
registerBlock(treeChest, new ItemBlockForestry<>(treeChest), "tree_chest");
}
public ItemStack getDecorativeLeaves(String speciesUid) {
@@ -152,7 +152,10 @@ public class BlockSapling extends BlockTreeContainer implements IGrowable, IStat
/* REMOVING */
@Override
public void getDrops(NonNullList<ItemStack> drops, IBlockAccess world, BlockPos pos, IBlockState state, int fortune) {
ItemStack drop = getDrop(world, pos);
if (!drop.isEmpty()) {
drops.add(drop);
}
}
@Override
@@ -179,13 +182,21 @@ public class BlockSapling extends BlockTreeContainer implements IGrowable, IStat
if (world.isRemote) {
return;
}
TileSapling sapling = TileUtil.getTile(world, pos, TileSapling.class);
if (sapling != null && sapling.getTree() != null) {
ItemStack saplingStack = TreeManager.treeRoot.getMemberStack(sapling.getTree(), EnumGermlingType.SAPLING);
ItemStackUtil.dropItemStackAsEntity(saplingStack, world, pos);
ItemStack drop = getDrop(world, pos);
if (!drop.isEmpty()) {
ItemStackUtil.dropItemStackAsEntity(drop, world, pos);
}
}
private static ItemStack getDrop(IBlockAccess world, BlockPos pos) {
TileSapling sapling = TileUtil.getTile(world, pos, TileSapling.class);
if (sapling != null) {
ITree tree = sapling.getTree();
if (tree != null) {
return TreeManager.treeRoot.getMemberStack(tree, EnumGermlingType.SAPLING);
}
}
return ItemStack.EMPTY;
}
/* GROWNING */
@@ -1,18 +1,12 @@
package forestry.arboriculture.blocks;
import com.google.common.collect.Maps;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.google.common.collect.Maps;
import forestry.api.arboriculture.EnumForestryWoodType;
import forestry.api.arboriculture.EnumVanillaWoodType;
import forestry.api.arboriculture.IWoodStateMapper;
import forestry.api.arboriculture.IWoodType;
import forestry.arboriculture.IWoodTyped;
import forestry.arboriculture.models.WoodModelLoader;
import forestry.core.config.Constants;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFence;
import net.minecraft.block.BlockFenceGate;
@@ -20,9 +14,16 @@ import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.block.statemap.StateMapperBase;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import forestry.api.arboriculture.EnumVanillaWoodType;
import forestry.api.arboriculture.IWoodStateMapper;
import forestry.api.arboriculture.IWoodType;
import forestry.arboriculture.IWoodTyped;
import forestry.core.config.Constants;
@SideOnly(Side.CLIENT)
public class WoodTypeStateMapper extends StateMapperBase implements IWoodStateMapper {
private final IWoodTyped woodTyped;
@@ -70,14 +71,10 @@ public class WoodTypeStateMapper extends StateMapperBase implements IWoodStateMa
Block block = state.getBlock();
int meta = block.getMetaFromState(state);
IWoodType woodType = woodTyped.getWoodType(meta);
if (woodType instanceof EnumForestryWoodType) {
if (WoodModelLoader.INSTANCE.isEnabled) {
return getForestryModelResourceLocation(woodType, properties);
} else {
return getDefaultModelResourceLocation(state);
}
} else {
if (woodType instanceof EnumVanillaWoodType) {
return getVanillaModelResourceLocation(block, woodType, properties);
} else {
return getModelResourceLocation(woodType, properties, block.getRegistryName().getResourceDomain());
}
}
@@ -100,10 +97,10 @@ public class WoodTypeStateMapper extends StateMapperBase implements IWoodStateMa
return new ModelResourceLocation(Constants.MOD_ID + ':' + resourceLocation, propertyString);
}
private ModelResourceLocation getForestryModelResourceLocation(IWoodType woodType, Map<IProperty<?>, Comparable<?>> properties) {
private ModelResourceLocation getModelResourceLocation(IWoodType woodType, Map<IProperty<?>, Comparable<?>> properties, String modID) {
String resourceLocation = "arboriculture/" + blockPath + '/' + woodType;
String propertyString = this.getPropertyString(properties);
return new ModelResourceLocation(Constants.MOD_ID + ':' + resourceLocation, propertyString);
return new ModelResourceLocation(modID + ':' + resourceLocation, propertyString);
}
private ModelResourceLocation getVanillaModelResourceLocation(Block block, IWoodType woodType, Map<IProperty<?>, Comparable<?>> properties) {
@@ -14,9 +14,11 @@ import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.base.Preconditions;
@@ -26,6 +28,7 @@ import forestry.api.arboriculture.EnumTreeChromosome;
import forestry.api.arboriculture.IAlleleFruit;
import forestry.api.arboriculture.IAlleleTreeSpecies;
import forestry.api.arboriculture.IArboristTracker;
import forestry.api.arboriculture.IFruitProvider;
import forestry.api.arboriculture.ILeafTickHandler;
import forestry.api.arboriculture.ITree;
import forestry.api.arboriculture.ITreeGenome;
@@ -38,6 +41,7 @@ import forestry.api.genetics.IAllele;
import forestry.api.genetics.IAlyzerPlugin;
import forestry.api.genetics.ICheckPollinatable;
import forestry.api.genetics.IChromosomeType;
import forestry.api.genetics.IFruitFamily;
import forestry.api.genetics.IIndividual;
import forestry.api.genetics.IMutation;
import forestry.api.genetics.IPollinatable;
@@ -75,6 +79,7 @@ public class TreeRoot extends SpeciesRoot implements ITreeRoot {
private static ITreekeepingMode activeTreekeepingMode;
public static final List<ITree> treeTemplates = new ArrayList<>();
private final Map<IFruitFamily, Collection<IFruitProvider>> providersForFamilies = new HashMap<>();
private final List<ITreekeepingMode> treekeepingModes = new ArrayList<>();
public TreeRoot() {
@@ -154,7 +159,6 @@ public class TreeRoot extends SpeciesRoot implements ITreeRoot {
@Override
@Nullable
public ITree getMember(ItemStack itemstack) {
itemstack = GeneticsUtil.convertToGeneticEquivalent(itemstack);
if (!isMember(itemstack) || itemstack.getTagCompound() == null) {
return null;
}
@@ -440,4 +444,18 @@ public class TreeRoot extends SpeciesRoot implements ITreeRoot {
}
}
@Override
public Collection<IFruitProvider> getFruitProvidersForFruitFamily(IFruitFamily fruitFamily) {
if (providersForFamilies.isEmpty()) {
@SuppressWarnings("unchecked")
Collection<IAlleleFruit> fruitAlleles = (Collection<IAlleleFruit>) (Object) AlleleManager.alleleRegistry.getRegisteredAlleles(EnumTreeChromosome.FRUITS);
for (IAlleleFruit alleleFruit : fruitAlleles) {
IFruitProvider fruitProvider = alleleFruit.getProvider();
Collection<IFruitProvider> fruitProviders = providersForFamilies.computeIfAbsent(fruitProvider.getFamily(), k -> new ArrayList<>());
fruitProviders.add(fruitProvider);
}
}
return providersForFamilies.computeIfAbsent(fruitFamily, k -> new ArrayList<>());
}
}
@@ -11,12 +11,16 @@
package forestry.arboriculture.genetics.alleles;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import forestry.api.arboriculture.EnumGermlingType;
import forestry.api.arboriculture.EnumTreeChromosome;
import forestry.api.arboriculture.IAlleleFruit;
import forestry.api.arboriculture.IAlleleTreeSpecies;
import forestry.api.arboriculture.IAlleleTreeSpeciesBuilder;
import forestry.api.arboriculture.IFruitProvider;
import forestry.api.arboriculture.IGermlingModelProvider;
import forestry.api.arboriculture.IGrowthProvider;
import forestry.api.arboriculture.ILeafProvider;
@@ -27,6 +31,7 @@ import forestry.api.arboriculture.IWoodProvider;
import forestry.api.arboriculture.TreeManager;
import forestry.api.core.IModelManager;
import forestry.api.genetics.AlleleManager;
import forestry.api.genetics.IAllele;
import forestry.api.genetics.IClassification;
import forestry.api.genetics.IFruitFamily;
import forestry.arboriculture.genetics.ClimateGrowthProvider;
@@ -34,6 +39,7 @@ import forestry.arboriculture.genetics.LeafProvider;
import forestry.core.genetics.alleles.AlleleSpecies;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.EnumPlantType;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@@ -196,6 +202,34 @@ public class AlleleTreeSpecies extends AlleleSpecies implements IAlleleTreeSpeci
return modID;
}
@Override
public float getResearchSuitability(ItemStack itemstack) {
if (itemstack.isEmpty()) {
return 0f;
}
List<IFruitFamily> suitableFruit = getSuitableFruit();
for (IFruitFamily fruitFamily : suitableFruit) {
Collection<IFruitProvider> fruitProviders = TreeManager.treeRoot.getFruitProvidersForFruitFamily(fruitFamily);
for (IFruitProvider fruitProvider : fruitProviders) {
Map<ItemStack, Float> products = fruitProvider.getProducts();
for (ItemStack stack : products.keySet()) {
if (stack.isItemEqual(itemstack)) {
return 1.0f;
}
}
Map<ItemStack, Float> specialtyChances = fruitProvider.getSpecialty();
for (ItemStack stack : specialtyChances.keySet()) {
if (stack.isItemEqual(itemstack)) {
return 1.0f;
}
}
}
}
return super.getResearchSuitability(itemstack);
}
@Override
public int compareTo(IAlleleTreeSpecies o) {
return 0;
@@ -1,20 +1,17 @@
package forestry.arboriculture.items;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import forestry.api.arboriculture.IFruitProvider;
import forestry.api.arboriculture.ITreeGenome;
import forestry.arboriculture.blocks.BlockDecorativeLeaves;
import forestry.arboriculture.genetics.TreeDefinition;
import forestry.core.items.IColoredItem;
import forestry.core.items.ItemBlockForestry;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class ItemBlockDecorativeLeaves extends ItemBlockForestry<BlockDecorativeLeaves> implements IColoredItem {
public ItemBlockDecorativeLeaves(Block block) {
public ItemBlockDecorativeLeaves(BlockDecorativeLeaves block) {
super(block);
}
@@ -12,12 +12,10 @@ package forestry.arboriculture.items;
import forestry.arboriculture.PluginArboriculture;
import forestry.arboriculture.blocks.BlockAbstractLeaves;
import forestry.arboriculture.blocks.BlockForestryLeaves;
import forestry.arboriculture.tiles.TileLeaves;
import forestry.core.items.IColoredItem;
import forestry.core.items.ItemBlockForestry;
import forestry.core.utils.Translator;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
@@ -30,7 +28,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
public class ItemBlockLeaves extends ItemBlockForestry<BlockAbstractLeaves> implements IColoredItem {
public ItemBlockLeaves(Block block) {
public ItemBlockLeaves(BlockAbstractLeaves block) {
super(block);
}
@@ -18,7 +18,7 @@ import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
public class ItemBlockWood<B extends Block & IWoodTyped> extends ItemBlockForestry<B> {
public ItemBlockWood(Block block) {
public ItemBlockWood(B block) {
super(block);
}
@@ -29,5 +29,14 @@ public class ItemBlockWood<B extends Block & IWoodTyped> extends ItemBlockForest
IWoodType woodType = wood.getWoodType(meta);
return WoodHelper.getDisplayName(wood, woodType);
}
@Override
public int getItemBurnTime(ItemStack itemStack) {
B block = getBlock();
if (block.isFireproof()) {
return 0;
} else {
return 300;
}
}
}
@@ -16,7 +16,7 @@ import net.minecraft.world.World;
public class ItemBlockWoodDoor extends ItemBlockWood<BlockArbDoor> {
public ItemBlockWoodDoor(Block block) {
public ItemBlockWoodDoor(BlockArbDoor block) {
super(block);
}
@@ -52,4 +52,13 @@ public class ItemBlockWoodDoor extends ItemBlockWood<BlockArbDoor> {
}
}
}
@Override
public int getItemBurnTime(ItemStack itemStack) {
if (getBlock().isFireproof()) {
return 0;
} else {
return 200;
}
}
}
@@ -2,6 +2,7 @@ package forestry.arboriculture.items;
import forestry.api.arboriculture.IWoodType;
import forestry.arboriculture.WoodHelper;
import forestry.arboriculture.blocks.BlockArbSlab;
import forestry.arboriculture.blocks.BlockForestrySlab;
import net.minecraft.item.ItemSlab;
import net.minecraft.item.ItemStack;
@@ -18,4 +19,14 @@ public class ItemBlockWoodSlab extends ItemSlab {
IWoodType woodType = wood.getWoodType(meta);
return WoodHelper.getDisplayName(wood, woodType);
}
@Override
public int getItemBurnTime(ItemStack itemStack) {
BlockForestrySlab forestrySlab = (BlockForestrySlab) this.block;
if (forestrySlab.isFireproof()) {
return 0;
} else {
return 150;
}
}
}
@@ -90,7 +90,9 @@ public class ItemGermlingGE extends ItemGE implements IVariableFermentable, ICol
@Override
public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> subItems) {
addCreativeItems(subItems, true);
if (this.isInCreativeTab(tab)) {
addCreativeItems(subItems, true);
}
}
public void addCreativeItems(NonNullList<ItemStack> subItems, boolean hideSecrets) {
@@ -216,4 +218,9 @@ public class ItemGermlingGE extends ItemGE implements IVariableFermentable, ICol
}
return tree.getGenome().getSappiness() * 10;
}
@Override
public int getItemBurnTime(ItemStack itemStack) {
return 100;
}
}
@@ -47,28 +47,35 @@ public class SimpleModel implements IModel {
private static final ModelResourceLocation MISSING = new ModelResourceLocation("builtin/missing", "missing");
private final List<Variant> variants;
private final List<ResourceLocation> locations = new ArrayList<>();
private final Set<ResourceLocation> textures = Sets.newHashSet();
private final List<IModel> models = new ArrayList<>();
private final ImmutableList<ResourceLocation> locations;
private final ImmutableSet<ResourceLocation> textures;
private final ImmutableList<IModel> models;
private final IModelState defaultState;
public SimpleModel(List<ResourceLocation> locations, List<IModel> models, List<Variant> variants,
IModelState defaultState) {
this.locations.addAll(locations);
this.models.addAll(models);
this.variants = variants;
this.locations = ImmutableList.copyOf(locations);
this.models = ImmutableList.copyOf(models);
this.defaultState = defaultState;
ImmutableSet.Builder<ResourceLocation> texturesBuilder = ImmutableSet.builder();
for (IModel model : models) {
textures.addAll(model.getTextures());
texturesBuilder.addAll(model.getTextures());
}
textures = texturesBuilder.build();
}
public SimpleModel(ResourceLocation parent, VariantList variants) throws Exception {
this.variants = variants.getVariantList();
ImmutableList.Builder<Pair<IModel, IModelState>> builder = ImmutableList.builder();
ImmutableList.Builder<IModel> modelsBuilder = ImmutableList.builder();
ImmutableList.Builder<ResourceLocation> locationsBuilder = ImmutableList.builder();
ImmutableSet.Builder<ResourceLocation> texturesBuilder = ImmutableSet.builder();
for (Variant variant : this.variants) {
ResourceLocation loc = variant.getModelLocation();
locations.add(loc);
locationsBuilder.add(loc);
IModel model;
if (loc.equals(MISSING)) {
@@ -81,19 +88,23 @@ public class SimpleModel implements IModel {
for (ResourceLocation location : model.getDependencies()) {
ModelLoaderRegistry.getModelOrMissing(location);
}
textures.addAll(model.getTextures());
texturesBuilder.addAll(model.getTextures());
models.add(model);
modelsBuilder.add(model);
builder.add(Pair.of(model, variant.getState()));
}
if (models.size() == 0) {
if (this.variants.size() == 0) {
IModel missing = ModelLoaderRegistry.getMissingModel();
models.add(missing);
modelsBuilder.add(missing);
builder.add(Pair.of(missing, TRSRTransformation.identity()));
}
defaultState = new MultiModelState(builder.build());
locations = locationsBuilder.build();
models = modelsBuilder.build();
textures = texturesBuilder.build();
}
@Override
@@ -129,6 +140,7 @@ public class SimpleModel implements IModel {
@Override
public IModel retexture(ImmutableMap<String, String> textures) {
List<ResourceLocation> locations = new ArrayList<>();
List<IModel> models = new ArrayList<>();
ImmutableList.Builder<Pair<IModel, IModelState>> builder = ImmutableList.builder();
for (Variant variant : this.variants) {
@@ -13,25 +13,27 @@ package forestry.arboriculture.models;
import java.util.ArrayList;
import java.util.List;
import forestry.core.config.Constants;
import forestry.core.utils.ModelUtil;
import net.minecraft.client.renderer.block.model.ModelBlockDefinition;
import net.minecraft.client.renderer.block.model.ModelBlockDefinition.MissingVariantException;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.block.model.VariantList;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.ICustomModelLoader;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import forestry.core.config.Constants;
import forestry.core.utils.ModelUtil;
@SideOnly(Side.CLIENT)
public enum WoodModelLoader implements ICustomModelLoader {
INSTANCE;
public static final List<String> validFiles = new ArrayList<>();
public boolean isEnabled = false;
static {
validFiles.add("door");
@@ -51,7 +53,7 @@ public enum WoodModelLoader implements ICustomModelLoader {
@Override
public boolean accepts(ResourceLocation modelLocation) {
if (!isEnabled || !(modelLocation instanceof ModelResourceLocation)
if (!(modelLocation instanceof ModelResourceLocation)
|| !modelLocation.getResourceDomain().equals(Constants.MOD_ID)
|| !modelLocation.getResourcePath().contains("arboriculture")) {
return false;
@@ -10,6 +10,15 @@
******************************************************************************/
package forestry.arboriculture.models;
import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.internal.Streams;
import com.google.gson.stream.JsonReader;
import javax.annotation.Nullable;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -19,37 +28,28 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import javax.annotation.Nullable;
import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.internal.Streams;
import com.google.gson.stream.JsonReader;
import forestry.api.arboriculture.IWoodType;
import forestry.api.arboriculture.WoodBlockKind;
import forestry.arboriculture.models.WoodTexture;
import forestry.arboriculture.models.WoodTexture.SimpleTexture;
import forestry.arboriculture.models.WoodTexture.TextureMap;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import forestry.api.arboriculture.IWoodType;
import forestry.api.arboriculture.WoodBlockKind;
import forestry.arboriculture.models.WoodTexture.SimpleTexture;
import forestry.arboriculture.models.WoodTexture.TextureMap;
import forestry.core.utils.Log;
@SideOnly(Side.CLIENT)
public class WoodTextureManager {
protected static final Map<String, WoodTexture> WOOD_TEXTURES = new HashMap<>();
public static final String KIND_KEY = "kind";
public static final ResourceLocation LOCATION = new ResourceLocation("forestry:textures/woodTextures.json");
public static final String LOCATION = "/assets/forestry/textures/wood_textures.json";
public static void parseFile(IResourceManager resourceManager) {
try {
InputStream stream = resourceManager.getResource(LOCATION).getInputStream();
JsonReader reader = null;
try {
reader = new JsonReader(new BufferedReader(new InputStreamReader(stream)));
public static void parseFile() {
try (InputStream stream = WoodTextureManager.class.getResourceAsStream(LOCATION)) {
if (stream == null){
return;
}
try (JsonReader reader = new JsonReader(new BufferedReader(new InputStreamReader(stream)))){
JsonElement json = Streams.parse(reader);
if (json.isJsonObject()) {
JsonObject jsonObject = json.getAsJsonObject();
@@ -62,14 +62,10 @@ public class WoodTextureManager {
}
}
}
} finally {
if (reader != null) {
reader.close();
}
}
} catch (IOException e) {
if (!(e instanceof FileNotFoundException)) {
e.printStackTrace();
Log.error("Error finding wood textures.", e);
}
}
}
@@ -78,9 +74,9 @@ public class WoodTextureManager {
WOOD_TEXTURES.put(key, createSimpleTexture(object));
}
private static void addTextureMap(String key, JsonArray jaonArray){
private static void addTextureMap(String key, JsonArray jsonArray){
ImmutableMap.Builder<String, SimpleTexture> textures = new ImmutableMap.Builder<>();
for (JsonElement elementEntry : jaonArray) {
for (JsonElement elementEntry : jsonArray) {
if (elementEntry.isJsonObject()) {
JsonObject obj = elementEntry.getAsJsonObject();
String kind = getKind(obj);
@@ -122,11 +118,13 @@ public class WoodTextureManager {
return new SimpleTexture(locations.build());
}
@Nullable
private static WoodTexture getKindTexture(WoodBlockKind blockKind){
String kindName = blockKind.getName();
return WOOD_TEXTURES.get(kindName);
}
@Nullable
private static WoodTexture getTexture(IWoodType woodType){
String woodName = woodType.getName();
woodName = woodName.toLowerCase(Locale.ENGLISH);
@@ -10,12 +10,33 @@
******************************************************************************/
package forestry.arboriculture.proxy;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.block.model.multipart.Multipart;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.IRegistry;
import net.minecraft.world.ColorizerFoliage;
import net.minecraftforge.client.event.ModelBakeEvent;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import forestry.api.arboriculture.IWoodItemMeshDefinition;
import forestry.api.arboriculture.IWoodStateMapper;
import forestry.api.arboriculture.IWoodType;
@@ -35,22 +56,6 @@ import forestry.core.models.BlockModelEntry;
import forestry.core.models.ModelManager;
import forestry.core.models.SimpleRetexturedModel;
import forestry.core.models.WoodModelEntry;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.block.model.multipart.Multipart;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.registry.IRegistry;
import net.minecraft.world.ColorizerFoliage;
import net.minecraftforge.client.event.ModelBakeEvent;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ProxyArboricultureClient extends ProxyArboriculture {
@@ -110,7 +115,6 @@ public class ProxyArboricultureClient extends ProxyArboriculture {
@SubscribeEvent
public <T extends Block & IWoodTyped> void onModelBake(ModelBakeEvent event) {
WoodModelLoader.INSTANCE.isEnabled = true;
IRegistry<ModelResourceLocation, IBakedModel> registry = event.getModelRegistry();
for (WoodModelEntry<T> entry : woodModelEntrys) {
@@ -145,28 +149,27 @@ public class ProxyArboricultureClient extends ProxyArboriculture {
ImmutableMap<String, String> textures, IWoodType woodType, WoodBlockKind woodKind, ItemStack itemStack,
IWoodItemMeshDefinition woodDefinition) {
if (woodKind != WoodBlockKind.DOOR) {
IModel basicItemModel = ModelLoaderRegistry
.getModelOrMissing(woodDefinition.getDefaultModelLocation(itemStack));
ResourceLocation defaultModelLocation = woodDefinition.getDefaultModelLocation(itemStack);
IModel basicItemModel = ModelLoaderRegistry.getModelOrMissing(defaultModelLocation);
ModelResourceLocation basicItemLocation = woodDefinition.getModelLocation(itemStack);
registry.putObject(basicItemLocation,
new SimpleRetexturedModel(woodKind.retextureModel(basicItemModel, woodType, textures)));
IModel retextureModel = woodKind.retextureModel(basicItemModel, woodType, textures);
registry.putObject(basicItemLocation, new SimpleRetexturedModel(retextureModel));
}
}
private void retexturBlockModel(IRegistry<ModelResourceLocation, IBakedModel> registry,
ImmutableMap<String, String> textures, IWoodType woodType, WoodBlockKind woodKind, IBlockState blockState,
IWoodStateMapper woodMapper) {
IModel basicModel = ModelLoaderRegistry
.getModelOrMissing(woodMapper.getDefaultModelResourceLocation(blockState));
ModelResourceLocation defaultModelResourceLocation = woodMapper.getDefaultModelResourceLocation(blockState);
IModel basicModel = ModelLoaderRegistry.getModelOrMissing(defaultModelResourceLocation);
if (basicModel instanceof MultipartModel) {
MultipartModel multipartModel = (MultipartModel) basicModel;
Multipart multipart = multipartModel.getMultipart();
multipart.setStateContainer(blockState.getBlock().getBlockState());
}
ModelResourceLocation basicLocation = woodMapper.getModelLocation(blockState);
registry.putObject(basicLocation,
new SimpleRetexturedModel(woodKind.retextureModel(basicModel, woodType, textures)));
IModel retextureModel = woodKind.retextureModel(basicModel, woodType, textures);
registry.putObject(basicLocation, new SimpleRetexturedModel(retextureModel));
}
@@ -10,6 +10,7 @@
******************************************************************************/
package forestry.arboriculture.worldgen;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -18,6 +19,18 @@ import java.util.Map;
import java.util.Random;
import java.util.Set;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraftforge.common.IPlantable;
import net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import forestry.api.arboriculture.EnumTreeChromosome;
import forestry.api.arboriculture.IAlleleTreeSpecies;
import forestry.api.arboriculture.IGrowthProvider;
@@ -28,22 +41,10 @@ import forestry.api.genetics.AlleleManager;
import forestry.api.genetics.IAllele;
import forestry.arboriculture.commands.TreeGenHelper;
import forestry.core.utils.BlockUtil;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraftforge.common.IPlantable;
import net.minecraftforge.common.util.EnumHelper;
import net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate;
public class TreeDecorator {
private static final EventType EVENT_TYPE = EnumHelper.addEnum(EventType.class, "FORESTRY_TREES", new Class[0]);
private static final List<IAlleleTreeSpecies> SPECIES = new ArrayList<>();
private static final Map<Biome, Set<ITree>> biomeCache = new HashMap<>();
private static final Map<ResourceLocation, Set<ITree>> biomeCache = new HashMap<>();
@SubscribeEvent
public void decorateTrees(Decorate event) {
@@ -53,7 +54,7 @@ public class TreeDecorator {
}
public static void decorateTrees(World world, Random rand, int worldX, int worldZ) {
if(biomeCache.isEmpty()){
if (biomeCache.isEmpty()) {
generateBiomeCache(world, rand);
}
for (int tries = 0; tries < 4 + rand.nextInt(2); tries++) {
@@ -62,9 +63,9 @@ public class TreeDecorator {
BlockPos pos = new BlockPos(x, 0, z);
Biome biome = world.getBiome(pos);
Set<ITree> trees = biomeCache.get(biome);
for(ITree tree : trees){
Set<ITree> trees = biomeCache.computeIfAbsent(biome.getRegistryName(), k -> new HashSet<>());
for (ITree tree : trees) {
IAlleleTreeSpecies species = tree.getGenome().getPrimary();
if (species.getRarity() >= rand.nextFloat()) {
pos = getValidPos(world, x, z, tree);
@@ -83,15 +84,16 @@ public class TreeDecorator {
}
}
@Nullable
private static BlockPos getValidPos(World world, int x, int z, ITree tree){
// get to the ground
final BlockPos topPos = world.getHeight(new BlockPos(x, 0, z));
if (topPos.getY() == 0) {
return null;
}
final BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(topPos);
IBlockState blockState = world.getBlockState(pos);
IBlockState downState = world.getBlockState(pos.down());
while (BlockUtil.canReplace(blockState, world, pos)) {
@@ -124,14 +126,14 @@ public class TreeDecorator {
}
private static void generateBiomeCache(World world, Random rand){
for(IAlleleTreeSpecies species : getSpecies()){
for (IAlleleTreeSpecies species : getSpecies()) {
IAllele[] template = TreeManager.treeRoot.getTemplate(species);
ITreeGenome genome = TreeManager.treeRoot.templateAsGenome(template);
ITree tree = TreeManager.treeRoot.getTree(world, genome);
IGrowthProvider growthProvider = species.getGrowthProvider();
for(Biome biome : Biome.REGISTRY){
Set<ITree> trees = biomeCache.computeIfAbsent(biome, k -> new HashSet<>());
if(growthProvider.isBiomeValid(tree, biome)){
for (Biome biome : Biome.REGISTRY) {
Set<ITree> trees = biomeCache.computeIfAbsent(biome.getRegistryName(), k -> new HashSet<>());
if (growthProvider.isBiomeValid(tree, biome)) {
trees.add(tree);
}
}
@@ -49,15 +49,17 @@ public class WorldGenGreenheart extends WorldGenTree {
WorldGenHelper.generateCylinderFromTreeStartPos(world, leaf, startPos.add(0, leafSpawn--, 0), girth, 1.5f + girth, 1, WorldGenHelper.EnumReplaceMode.SOFT);
WorldGenHelper.generateCylinderFromTreeStartPos(world, leaf, startPos.add(0, leafSpawn, 0), girth, 0.5f + girth, 1, WorldGenHelper.EnumReplaceMode.SOFT);
// Add some smaller twigs below for flavour
for (int times = 0; times < height / 4; times++) {
int h = 10 + rand.nextInt(height - 10);
if (rand.nextBoolean() && h < height / 2) {
h = height / 2 + rand.nextInt(height / 2);
if (height > 10) {
// Add some smaller twigs below for flavour
for (int times = 0; times < height / 4; times++) {
int h = 10 + rand.nextInt(height - 10);
if (rand.nextBoolean() && h < height / 2) {
h = height / 2 + rand.nextInt(height / 2);
}
int x_off = -1 + rand.nextInt(3);
int y_off = -1 + rand.nextInt(3);
WorldGenHelper.generateSphere(world, startPos.add(x_off, h, y_off), 1 + rand.nextInt(1), leaf, WorldGenHelper.EnumReplaceMode.AIR);
}
int x_off = -1 + rand.nextInt(3);
int y_off = -1 + rand.nextInt(3);
WorldGenHelper.generateSphere(world, startPos.add(x_off, h, y_off), 1 + rand.nextInt(1), leaf, WorldGenHelper.EnumReplaceMode.AIR);
}
}
}
@@ -62,7 +62,16 @@ public class EventHandlerCore {
@SubscribeEvent
public void handlePlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) {
EntityPlayer player = event.player;
syncBreedingTrackers(player);
}
@SubscribeEvent
public void handlePlayerChangedDimension(PlayerEvent.PlayerChangedDimensionEvent event) {
EntityPlayer player = event.player;
syncBreedingTrackers(player);
}
private static void syncBreedingTrackers(EntityPlayer player) {
IAlleleRegistry alleleRegistry = AlleleManager.alleleRegistry;
Collection<ISpeciesRoot> speciesRoots = alleleRegistry.getSpeciesRoot().values();
for (ISpeciesRoot speciesRoot : speciesRoots) {
+60 -87
View File
@@ -10,13 +10,32 @@
******************************************************************************/
package forestry.core;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.command.ICommand;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.world.storage.loot.functions.LootFunctionManager;
import net.minecraftforge.client.event.ModelBakeEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.oredict.OreDictionary;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import forestry.api.circuits.ChipsetManager;
import forestry.api.core.CamouflageManager;
import forestry.api.core.ForestryAPI;
@@ -52,7 +71,6 @@ import forestry.core.network.PacketRegistryCore;
import forestry.core.owner.GameProfileDataSerializer;
import forestry.core.proxy.Proxies;
import forestry.core.recipes.RecipeUtil;
import forestry.core.recipes.ShapedRecipeCustom;
import forestry.core.render.TextureManagerForestry;
import forestry.core.utils.ClimateUtil;
import forestry.core.utils.ForestryModEnvWarningCallable;
@@ -60,23 +78,6 @@ import forestry.core.utils.OreDictUtil;
import forestry.plugins.BlankForestryPlugin;
import forestry.plugins.ForestryPlugin;
import forestry.plugins.ForestryPluginUids;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.command.ICommand;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.world.storage.loot.functions.LootFunctionManager;
import net.minecraftforge.client.event.ModelBakeEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fml.common.IFuelHandler;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.oredict.OreDictionary;
import net.minecraftforge.oredict.RecipeSorter;
@ForestryPlugin(pluginID = ForestryPluginUids.CORE, name = "Core", author = "SirSengir", url = Constants.URL, unlocalizedDescription = "for.plugin.core.description")
public class PluginCore extends BlankForestryPlugin {
@@ -162,8 +163,6 @@ public class PluginCore extends BlankForestryPlugin {
alleleHelper.init();
Proxies.render.initRendering();
RecipeSorter.register("forestry:shaped", ShapedRecipeCustom.class, RecipeSorter.Category.SHAPED, "");
}
@Override
@@ -260,16 +259,16 @@ public class PluginCore extends BlankForestryPlugin {
if (Config.isCraftingBronzeEnabled()) {
ItemStack ingotBronze = items.ingotBronze.copy();
ingotBronze.setCount(4);
RecipeUtil.addShapelessRecipe(ingotBronze, OreDictUtil.INGOT_TIN, OreDictUtil.INGOT_COPPER, OreDictUtil.INGOT_COPPER, OreDictUtil.INGOT_COPPER);
RecipeUtil.addShapelessRecipe("bronze_ingot", ingotBronze, OreDictUtil.INGOT_TIN, OreDictUtil.INGOT_COPPER, OreDictUtil.INGOT_COPPER, OreDictUtil.INGOT_COPPER);
}
/* STURDY MACHINE */
RecipeUtil.addRecipe(items.sturdyCasing, "###", "# #", "###", '#', OreDictUtil.INGOT_BRONZE);
RecipeUtil.addRecipe("sturdy_casing", items.sturdyCasing, "###", "# #", "###", '#', OreDictUtil.INGOT_BRONZE);
// / EMPTY CANS
int canAmount = ForestryAPI.activeMode.getIntegerSetting("recipe.output.can");
ItemStack canOutput = fluidItems.canEmpty.getItemStack(canAmount);
RecipeUtil.addRecipe(canOutput, " # ", "# #", '#', OreDictUtil.INGOT_TIN);
RecipeUtil.addRecipe("tin_can", canOutput, " # ", "# #", '#', OreDictUtil.INGOT_TIN);
// / GEARS
List<ItemStack> stoneGear = OreDictionary.getOres(OreDictUtil.GEAR_STONE);
@@ -279,27 +278,27 @@ public class PluginCore extends BlankForestryPlugin {
} else {
gearCenter = OreDictUtil.INGOT_COPPER;
}
RecipeUtil.addRecipe(items.gearBronze, " # ", "#X#", " # ", '#', OreDictUtil.INGOT_BRONZE, 'X', gearCenter);
RecipeUtil.addRecipe(items.gearCopper, " # ", "#X#", " # ", '#', OreDictUtil.INGOT_COPPER, 'X', gearCenter);
RecipeUtil.addRecipe(items.gearTin, " # ", "#X#", " # ", '#', OreDictUtil.INGOT_TIN, 'X', gearCenter);
RecipeUtil.addRecipe("gear_bronze", items.gearBronze, " # ", "#X#", " # ", '#', OreDictUtil.INGOT_BRONZE, 'X', gearCenter);
RecipeUtil.addRecipe("gear_copper", items.gearCopper, " # ", "#X#", " # ", '#', OreDictUtil.INGOT_COPPER, 'X', gearCenter);
RecipeUtil.addRecipe("gear_tin", items.gearTin, " # ", "#X#", " # ", '#', OreDictUtil.INGOT_TIN, 'X', gearCenter);
// / SURVIVALIST TOOLS
RecipeUtil.addRecipe(items.bronzePickaxe, " X ", " X ", "###", '#', OreDictUtil.INGOT_BRONZE, 'X', OreDictUtil.STICK_WOOD);
RecipeUtil.addRecipe(items.bronzeShovel, " X ", " X ", " # ", '#', OreDictUtil.INGOT_BRONZE, 'X', OreDictUtil.STICK_WOOD);
RecipeUtil.addShapelessRecipe(items.kitPickaxe, items.bronzePickaxe, items.carton);
RecipeUtil.addShapelessRecipe(items.kitShovel, items.bronzeShovel, items.carton);
RecipeUtil.addRecipe("bronze_pickaxe", items.bronzePickaxe, " X ", " X ", "###", '#', OreDictUtil.INGOT_BRONZE, 'X', OreDictUtil.STICK_WOOD);
RecipeUtil.addRecipe("bronze_shovel", items.bronzeShovel, " X ", " X ", " # ", '#', OreDictUtil.INGOT_BRONZE, 'X', OreDictUtil.STICK_WOOD);
RecipeUtil.addShapelessRecipe("pickaxe_kit", items.kitPickaxe, items.bronzePickaxe, items.carton);
RecipeUtil.addShapelessRecipe("shovel_kit", items.kitShovel, items.bronzeShovel, items.carton);
/* NATURALIST'S ARMOR */
RecipeUtil.addRecipe(items.spectacles, " X ", "Y Y", 'X', OreDictUtil.INGOT_BRONZE, 'Y', OreDictUtil.PANE_GLASS);
RecipeUtil.addRecipe("spectacles", items.spectacles, " X ", "Y Y", 'X', OreDictUtil.INGOT_BRONZE, 'Y', OreDictUtil.PANE_GLASS);
// / WRENCH
RecipeUtil.addRecipe(items.wrench, "# #", " # ", " # ", '#', OreDictUtil.INGOT_BRONZE);
RecipeUtil.addRecipe("wrench", items.wrench, "# #", " # ", " # ", '#', OreDictUtil.INGOT_BRONZE);
// / CAMOUFLAGE SPRAY CAN
RecipeUtil.addRecipe(items.camouflageSprayCan, "TTT", "TCT", "TCT", 'T', OreDictUtil.INGOT_TIN, 'C', items.craftingMaterial.getCamouflagedPaneling());
RecipeUtil.addRecipe("camoflage_spray_can", items.camouflageSprayCan, "TTT", "TCT", "TCT", 'T', OreDictUtil.INGOT_TIN, 'C', items.craftingMaterial.getCamouflagedPaneling());
// / WEB
RecipeUtil.addRecipe(new ItemStack(Blocks.WEB, 4), "# #", " # ", "# #", '#', items.craftingMaterial.getSilkWisp());
RecipeUtil.addRecipe("silk_wisp_to_web", new ItemStack(Blocks.WEB, 4), "# #", " # ", "# #", '#', items.craftingMaterial.getSilkWisp());
if (ForestryAPI.enabledPlugins.contains(ForestryPluginUids.FACTORY)) {
// / CARPENTER
@@ -321,7 +320,7 @@ public class PluginCore extends BlankForestryPlugin {
'Y', OreDictUtil.DYE_YELLOW);
} else {
// Portable ANALYZER
RecipeUtil.addRecipe(items.portableAlyzer.getItemStack(),
RecipeUtil.addRecipe("portable_alyzer", items.portableAlyzer.getItemStack(),
"X#X",
"X#X",
"RDR",
@@ -330,19 +329,18 @@ public class PluginCore extends BlankForestryPlugin {
'R', OreDictUtil.DUST_REDSTONE,
'D', OreDictUtil.GEM_DIAMOND);
// Camouflaged Paneling
RecipeUtil.addRecipe(items.craftingMaterial.getCamouflagedPaneling(8),
RecipeUtil.addRecipe("camoflaged_paneling", items.craftingMaterial.getCamouflagedPaneling(8),
"WWW",
"YBR",
"WWW",
'W', OreDictUtil.PLANK_WOOD,
'D', OreDictUtil.DUST_REDSTONE,
'Y', OreDictUtil.DYE_YELLOW,
'B', OreDictUtil.DYE_BLUE,
'R', OreDictUtil.DYE_RED);
}
// ANALYZER
RecipeUtil.addRecipe(blocks.analyzer,
RecipeUtil.addRecipe("alyzer", blocks.analyzer,
"XTX",
" Y ",
"X X",
@@ -353,46 +351,46 @@ public class PluginCore extends BlankForestryPlugin {
// Manure and Fertilizer
int compostWheatAmount = ForestryAPI.activeMode.getIntegerSetting("recipe.output.compost.wheat");
if (compostWheatAmount > 0) {
ItemStack compost = items.fertilizerBio.getItemStack(compostWheatAmount);
RecipeUtil.addRecipe(compost, " X ", "X#X", " X ", '#', Blocks.DIRT, 'X', OreDictUtil.CROP_WHEAT);
ItemStack compost = items.compost.getItemStack(compostWheatAmount);
RecipeUtil.addRecipe("wheat_to_compost", compost, " X ", "X#X", " X ", '#', Blocks.DIRT, 'X', OreDictUtil.CROP_WHEAT);
}
int compostAshAmount = ForestryAPI.activeMode.getIntegerSetting("recipe.output.compost.ash");
if (compostAshAmount > 0) {
ItemStack compost = items.fertilizerBio.getItemStack(compostAshAmount);
RecipeUtil.addRecipe(compost, " X ", "X#X", " X ", '#', Blocks.DIRT, 'X', OreDictUtil.DUST_ASH);
ItemStack compost = items.compost.getItemStack(compostAshAmount);
RecipeUtil.addRecipe("ash_to_compost", compost, " X ", "X#X", " X ", '#', Blocks.DIRT, 'X', OreDictUtil.DUST_ASH);
}
int fertilizerApatiteAmount = ForestryAPI.activeMode.getIntegerSetting("recipe.output.fertilizer.apatite");
if (fertilizerApatiteAmount > 0) {
ItemStack fertilizer = items.fertilizerCompound.getItemStack(fertilizerApatiteAmount);
RecipeUtil.addRecipe(fertilizer, " # ", " X ", " # ", '#', OreDictUtil.SAND, 'X', OreDictUtil.GEM_APATITE);
RecipeUtil.addRecipe("sand_to_fertilizer", fertilizer, " # ", " X ", " # ", '#', OreDictUtil.SAND, 'X', OreDictUtil.GEM_APATITE);
}
int fertilizerAshAmount = ForestryAPI.activeMode.getIntegerSetting("recipe.output.fertilizer.ash");
if (fertilizerAshAmount > 0) {
ItemStack fertilizer = items.fertilizerCompound.getItemStack(fertilizerAshAmount);
RecipeUtil.addRecipe(fertilizer, "###", "#X#", "###", '#', OreDictUtil.DUST_ASH, 'X', OreDictUtil.GEM_APATITE);
RecipeUtil.addRecipe("ash_to_fertilizer", fertilizer, "###", "#X#", "###", '#', OreDictUtil.DUST_ASH, 'X', OreDictUtil.GEM_APATITE);
}
// Humus
int humusCompostAmount = ForestryAPI.activeMode.getIntegerSetting("recipe.output.humus.compost");
if (humusCompostAmount > 0) {
ItemStack humus = new ItemStack(blocks.humus, humusCompostAmount);
RecipeUtil.addRecipe(humus, "###", "#X#", "###", '#', Blocks.DIRT, 'X', items.fertilizerBio);
RecipeUtil.addRecipe("compost_humus", humus, "###", "#X#", "###", '#', Blocks.DIRT, 'X', items.compost);
}
int humusFertilizerAmount = ForestryAPI.activeMode.getIntegerSetting("recipe.output.humus.fertilizer");
if (humusFertilizerAmount > 0) {
ItemStack humus = new ItemStack(blocks.humus, humusFertilizerAmount);
RecipeUtil.addRecipe(humus, "###", "#X#", "###", '#', Blocks.DIRT, 'X', items.fertilizerCompound);
RecipeUtil.addRecipe("fertilizer_humus", humus, "###", "#X#", "###", '#', Blocks.DIRT, 'X', items.fertilizerCompound);
}
// Bog earth
int bogEarthOutputBucket = ForestryAPI.activeMode.getIntegerSetting("recipe.output.bogearth.bucket");
if (bogEarthOutputBucket > 0) {
ItemStack bogEarth = blocks.bogEarth.get(BlockBogEarth.SoilType.BOG_EARTH, bogEarthOutputBucket);
RecipeUtil.addRecipe(bogEarth, "#Y#", "YXY", "#Y#", '#', Blocks.DIRT, 'X', Items.WATER_BUCKET, 'Y', OreDictUtil.SAND);
RecipeUtil.addRecipe("bucket_bog_earth", bogEarth, "#Y#", "YXY", "#Y#", '#', Blocks.DIRT, 'X', Items.WATER_BUCKET, 'Y', OreDictUtil.SAND);
}
int bogEarthOutputCan = ForestryAPI.activeMode.getIntegerSetting("recipe.output.bogearth.can");
@@ -401,46 +399,46 @@ public class PluginCore extends BlankForestryPlugin {
ItemStack canWater = fluidItems.getContainer(EnumContainerType.CAN, FluidRegistry.WATER);
ItemStack waxCapsuleWater = fluidItems.getContainer(EnumContainerType.CAPSULE, FluidRegistry.WATER);
ItemStack refractoryWater = fluidItems.getContainer(EnumContainerType.REFRACTORY, FluidRegistry.WATER);
RecipeUtil.addRecipe(bogEarth, "#Y#", "YXY", "#Y#", '#', Blocks.DIRT, 'X', canWater, 'Y', OreDictUtil.SAND);
RecipeUtil.addRecipe(bogEarth, "#Y#", "YXY", "#Y#", '#', Blocks.DIRT, 'X', waxCapsuleWater, 'Y', OreDictUtil.SAND);
RecipeUtil.addRecipe(bogEarth, "#Y#", "YXY", "#Y#", '#', Blocks.DIRT, 'X', refractoryWater, 'Y', OreDictUtil.SAND);
RecipeUtil.addRecipe("can_bog_earth", bogEarth, "#Y#", "YXY", "#Y#", '#', Blocks.DIRT, 'X', canWater, 'Y', OreDictUtil.SAND);
RecipeUtil.addRecipe("capsule_bog_earth", bogEarth, "#Y#", "YXY", "#Y#", '#', Blocks.DIRT, 'X', waxCapsuleWater, 'Y', OreDictUtil.SAND);
RecipeUtil.addRecipe("refractory_capsule_bog_earth", bogEarth, "#Y#", "YXY", "#Y#", '#', Blocks.DIRT, 'X', refractoryWater, 'Y', OreDictUtil.SAND);
}
// Crafting Material
RecipeUtil.addRecipe(new ItemStack(Items.STRING), "#", "#", "#", '#', items.craftingMaterial.getSilkWisp());
RecipeUtil.addRecipe("silk_to_string", new ItemStack(Items.STRING), "#", "#", "#", '#', items.craftingMaterial.getSilkWisp());
// / Pipette
RecipeUtil.addRecipe(items.pipette, " #", " X ", "X ", 'X', OreDictUtil.PANE_GLASS, '#', new ItemStack(Blocks.WOOL, 1, OreDictionary.WILDCARD_VALUE));
RecipeUtil.addRecipe("pipette", items.pipette, " #", " X ", "X ", 'X', OreDictUtil.PANE_GLASS, '#', new ItemStack(Blocks.WOOL, 1, OreDictionary.WILDCARD_VALUE));
// Storage Blocks
{
RecipeUtil.addRecipe(blocks.resourceStorageApatite, "###", "###", "###", '#', OreDictUtil.GEM_APATITE);
RecipeUtil.addRecipe("apatite_block", blocks.resourceStorageApatite, "###", "###", "###", '#', OreDictUtil.GEM_APATITE);
RecipeUtil.addShapelessRecipe(new ItemStack(items.apatite, 9), OreDictUtil.BLOCK_APATITE);
RecipeUtil.addShapelessRecipe("block_to_apatite", new ItemStack(items.apatite, 9), OreDictUtil.BLOCK_APATITE);
}
{
RecipeUtil.addRecipe(blocks.resourceStorageCopper, "###", "###", "###", '#', OreDictUtil.INGOT_COPPER);
RecipeUtil.addRecipe("copper_block", blocks.resourceStorageCopper, "###", "###", "###", '#', OreDictUtil.INGOT_COPPER);
ItemStack ingotCopper = items.ingotCopper.copy();
ingotCopper.setCount(9);
RecipeUtil.addShapelessRecipe(ingotCopper, OreDictUtil.BLOCK_COPPER);
RecipeUtil.addShapelessRecipe("block_to_copper", ingotCopper, OreDictUtil.BLOCK_COPPER);
}
{
RecipeUtil.addRecipe(blocks.resourceStorageTin, "###", "###", "###", '#', OreDictUtil.INGOT_TIN);
RecipeUtil.addRecipe("tin_block", blocks.resourceStorageTin, "###", "###", "###", '#', OreDictUtil.INGOT_TIN);
ItemStack ingotTin = items.ingotTin.copy();
ingotTin.setCount(9);
RecipeUtil.addShapelessRecipe(ingotTin, OreDictUtil.BLOCK_TIN);
RecipeUtil.addShapelessRecipe("block_to_tin", ingotTin, OreDictUtil.BLOCK_TIN);
}
{
RecipeUtil.addRecipe(blocks.resourceStorageBronze, "###", "###", "###", '#', OreDictUtil.INGOT_BRONZE);
RecipeUtil.addRecipe("bronze_block", blocks.resourceStorageBronze, "###", "###", "###", '#', OreDictUtil.INGOT_BRONZE);
ItemStack ingotBronze = items.ingotBronze.copy();
ingotBronze.setCount(9);
RecipeUtil.addShapelessRecipe(ingotBronze, OreDictUtil.BLOCK_BRONZE);
RecipeUtil.addShapelessRecipe("block_to_bronze", ingotBronze, OreDictUtil.BLOCK_BRONZE);
}
// alternate recipes
@@ -466,37 +464,12 @@ public class PluginCore extends BlankForestryPlugin {
return new ICommand[]{rootCommand};
}
@Override
public IFuelHandler getFuelHandler() {
return new FuelHandler(getItems());
}
@Override
public void getHiddenItems(List<ItemStack> hiddenItems) {
// research note items are not useful without actually having completed research
hiddenItems.add(new ItemStack(getItems().researchNote));
}
private static class FuelHandler implements IFuelHandler {
private final ItemRegistryCore items;
public FuelHandler(ItemRegistryCore items) {
this.items = items;
}
@Override
public int getBurnTime(ItemStack fuel) {
if (fuel != null && fuel.getItem() == items.peat) {
return 2000;
}
if (fuel != null && fuel.getItem() == items.bituminousPeat) {
return 4200;
}
return 0;
}
}
@SubscribeEvent
@SideOnly(Side.CLIENT)
public void onBakeModels(ModelBakeEvent event) {
@@ -12,18 +12,26 @@ package forestry.core;
import com.google.common.collect.LinkedListMultimap;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import it.unimi.dsi.fastutil.ints.IntArraySet;
import it.unimi.dsi.fastutil.ints.IntSet;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.gen.ChunkProviderServer;
import net.minecraft.world.gen.IChunkGenerator;
import net.minecraftforge.event.world.ChunkDataEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent.Phase;
import net.minecraftforge.fml.common.gameevent.TickEvent.WorldTickEvent;
import net.minecraftforge.fml.common.registry.GameRegistry;
import forestry.core.config.Config;
import forestry.core.config.Constants;
@@ -34,6 +42,7 @@ public class TickHandlerCoreServer {
private final WorldGenerator worldGenerator;
private final LinkedListMultimap<Integer, ChunkCoords> chunkRegenList = LinkedListMultimap.create();
private final IntSet checkForRetrogen = new IntArraySet();
public TickHandlerCoreServer(WorldGenerator worldGenerator) {
this.worldGenerator = worldGenerator;
@@ -54,27 +63,49 @@ public class TickHandlerCoreServer {
}
}
if (Config.doRetrogen) {
World world = event.world;
if (Config.doRetrogen && event.world instanceof WorldServer) {
WorldServer world = (WorldServer) event.world;
int dimensionID = world.provider.getDimension();
List<ChunkCoords> chunkList = chunkRegenList.get(dimensionID);
if (!chunkList.isEmpty()) {
ChunkCoords coords = chunkList.get(0);
chunkList.remove(0);
// This bit is from FML's GameRegistry.generateWorld where the seed is constructed.
long worldSeed = world.getSeed();
Random random = new Random(worldSeed);
long xSeed = random.nextLong() >> 2 + 1L;
long zSeed = random.nextLong() >> 2 + 1L;
random.setSeed(xSeed * coords.x + zSeed * coords.z ^ worldSeed);
worldGenerator.retroGen(random, coords.x, coords.z, world);
if (checkForRetrogen.contains(dimensionID)) {
List<ChunkCoords> chunkList = chunkRegenList.get(dimensionID);
Iterator<ChunkCoords> iterator = chunkList.iterator();
while (iterator.hasNext()) {
ChunkCoords coords = iterator.next();
if (canDecorate(world, coords)) {
iterator.remove();
Random random = getRetrogenRandom(world, coords);
worldGenerator.retroGen(random, coords.x, coords.z, world);
}
}
checkForRetrogen.remove(dimensionID);
}
}
}
/**
* This is from {@link GameRegistry#generateWorld(int, int, World, IChunkGenerator, IChunkProvider)} where the seed is constructed.
*/
private static Random getRetrogenRandom(World world, ChunkCoords coords) {
long worldSeed = world.getSeed();
Random random = new Random(worldSeed);
long xSeed = random.nextLong() >> 2 + 1L;
long zSeed = random.nextLong() >> 2 + 1L;
random.setSeed(xSeed * coords.x + zSeed * coords.z ^ worldSeed);
return random;
}
private static boolean canDecorate(WorldServer server, ChunkCoords chunkCoords) {
ChunkProviderServer chunkProvider = server.getChunkProvider();
for (int x = 0; x <= 1; x++) {
for (int z = 0; z <= 1; z++) {
if (!chunkProvider.chunkExists(chunkCoords.x + x, chunkCoords.z + z)) {
return false;
}
}
}
return true;
}
@SubscribeEvent
public void chunkSaveEventHandler(ChunkDataEvent.Save event) {
NBTTagCompound tag = new NBTTagCompound();
@@ -94,6 +125,7 @@ public class TickHandlerCoreServer {
if (!tag.hasKey("retrogen") || Config.forceRetrogen) {
ChunkCoords coords = new ChunkCoords(event.getChunk());
chunkRegenList.put(coords.dimension, coords);
checkForRetrogen.add(coords.dimension);
}
}
}
@@ -29,7 +29,7 @@ public class BlockRegistryCore extends BlockRegistry {
public BlockRegistryCore() {
analyzer = new BlockCore(BlockTypeCoreTesr.ANALYZER);
registerBlock(analyzer, new ItemBlockForestry(analyzer), "analyzer");
registerBlock(analyzer, new ItemBlockForestry<>(analyzer), "analyzer");
escritoire = new BlockCore(BlockTypeCoreTesr.ESCRITOIRE);
registerBlock(escritoire, new ItemBlockForestry<>(escritoire), "escritoire");
@@ -43,14 +43,14 @@ public class BlockRegistryCore extends BlockRegistry {
humus.setHarvestLevel("shovel", 0);
resources = new BlockResourceOre();
registerBlock(resources, new ItemBlockForestry(resources), "resources");
registerBlock(resources, new ItemBlockForestry<>(resources), "resources");
resources.setHarvestLevel("pickaxe", 1);
OreDictionary.registerOre(OreDictUtil.ORE_APATITE, resources.get(EnumResourceType.APATITE, 1));
OreDictionary.registerOre(OreDictUtil.ORE_COPPER, resources.get(EnumResourceType.COPPER, 1));
OreDictionary.registerOre(OreDictUtil.ORE_TIN, resources.get(EnumResourceType.TIN, 1));
BlockResourceStorage resourceStorage = new BlockResourceStorage();
registerBlock(resourceStorage, new ItemBlockForestry(resourceStorage), "resource_storage");
registerBlock(resourceStorage, new ItemBlockForestry<>(resourceStorage), "resource_storage");
resourceStorage.setHarvestLevel("pickaxe", 0);
resourceStorageApatite = resourceStorage.get(EnumResourceType.APATITE);
@@ -29,6 +29,7 @@ public class Circuits {
public static ICircuit farmOrchardManual;
public static ICircuit farmRubberManual;
public static ICircuit farmEnderManaged;
public static ICircuit farmOrchidManaged;
public static ICircuit machineSpeedUpgrade1;
public static ICircuit machineSpeedUpgrade2;
public static ICircuit machineEfficiencyUpgrade1;
@@ -42,10 +42,12 @@ public class ItemCircuitBoard extends ItemForestry implements IColoredItem {
@Override
public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> subItems) {
subItems.add(createCircuitboard(EnumCircuitBoardType.BASIC, null, new ICircuit[]{}));
subItems.add(createCircuitboard(EnumCircuitBoardType.ENHANCED, null, new ICircuit[]{}));
subItems.add(createCircuitboard(EnumCircuitBoardType.REFINED, null, new ICircuit[]{}));
subItems.add(createCircuitboard(EnumCircuitBoardType.INTRICATE, null, new ICircuit[]{}));
if (this.isInCreativeTab(tab)) {
subItems.add(createCircuitboard(EnumCircuitBoardType.BASIC, null, new ICircuit[]{}));
subItems.add(createCircuitboard(EnumCircuitBoardType.ENHANCED, null, new ICircuit[]{}));
subItems.add(createCircuitboard(EnumCircuitBoardType.REFINED, null, new ICircuit[]{}));
subItems.add(createCircuitboard(EnumCircuitBoardType.INTRICATE, null, new ICircuit[]{}));
}
}
/* MODELS*/
@@ -92,6 +92,7 @@ public class Config {
public static int farmSize = 2;
public static boolean squareFarms = false;
private static boolean enableExUtilEnderLily = true;
private static boolean enableExUtilRedOrchid = true;
private static boolean enableMagicalCropsSupport = true;
// Mail
@@ -131,6 +132,8 @@ public class Config {
return enableExUtilEnderLily;
}
public static boolean isExUtilRedOrchidEnabled() { return enableExUtilRedOrchid; }
public static boolean isMagicalCropsSupportEnabled() {
return enableMagicalCropsSupport;
}
@@ -241,6 +244,7 @@ public class Config {
farmSize = configCommon.getIntLocalized("tweaks.farms", "size", farmSize, 1, 3);
squareFarms = configCommon.getBooleanLocalized("tweaks.farms", "square", squareFarms);
enableExUtilEnderLily = configCommon.getBooleanLocalized("tweaks.farms", "enderlily", enableExUtilEnderLily);
enableExUtilRedOrchid = configCommon.getBooleanLocalized("tweaks.farms", "redorchid", enableExUtilRedOrchid);
enableMagicalCropsSupport = configCommon.getBooleanLocalized("tweaks.farms", "magicalcrops", enableMagicalCropsSupport);
String[] availableStructures = new String[]{"alveary3x3", "farm3x3", "farm3x4", "farm3x5", "farm4x4", "farm5x5"};
@@ -12,7 +12,6 @@ package forestry.core.fluids;
import javax.annotation.Nullable;
import forestry.core.utils.InventoryUtil;
import forestry.core.utils.ItemStackUtil;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
@@ -107,7 +106,7 @@ public final class FluidHelper {
boolean moveToOutput = fluidInContainer.amount >= containerCapacity;
if (moveToOutput) {
if (!output.isEmpty() && (output.getCount() >= output.getMaxStackSize() || !InventoryUtil.isItemEqual(filled, output))) {
if (!output.isEmpty() && (output.getCount() >= output.getMaxStackSize() || !ItemStackUtil.areItemStacksEqualIgnoreCount(filled, output))) {
return FillStatus.NO_SPACE;
}
} else {
@@ -11,7 +11,6 @@
package forestry.core.genetics;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import javax.annotation.Nullable;
import java.util.Arrays;
@@ -26,6 +25,7 @@ import forestry.api.genetics.IChromosome;
import forestry.api.genetics.IChromosomeType;
import forestry.api.genetics.IGenome;
import forestry.api.genetics.ISpeciesRoot;
import forestry.core.utils.Log;
public abstract class Genome implements IGenome {
private static final String SLOT_TAG = "Slot";
@@ -138,12 +138,23 @@ public abstract class Genome implements IGenome {
private static IChromosome getChromosome(ItemStack itemStack, IChromosomeType chromosomeType, ISpeciesRoot speciesRoot) {
NBTTagCompound nbtTagCompound = itemStack.getTagCompound();
Preconditions.checkArgument(nbtTagCompound != null, "itemStack must have nbt");
if (nbtTagCompound == null) {
nbtTagCompound = new NBTTagCompound();
itemStack.setTagCompound(nbtTagCompound);
}
NBTTagCompound genome = nbtTagCompound.getCompoundTag("Genome");
Preconditions.checkArgument(!genome.hasNoTags(), "itemStack nbt must have a genome tag");
NBTTagCompound genomeNbt = nbtTagCompound.getCompoundTag("Genome");
if (genomeNbt.hasNoTags()) {
Log.error("Got a genetic item with no genome, setting it to a default value.");
genomeNbt = new NBTTagCompound();
IAllele[] defaultTemplate = speciesRoot.getDefaultTemplate();
IGenome genome = speciesRoot.templateAsGenome(defaultTemplate);
genome.writeToNBT(genomeNbt);
nbtTagCompound.setTag("Genome", genomeNbt);
}
IChromosome[] chromosomes = getChromosomes(genome, speciesRoot);
IChromosome[] chromosomes = getChromosomes(genomeNbt, speciesRoot);
return chromosomes[chromosomeType.ordinal()];
}
@@ -14,12 +14,12 @@ import com.google.common.collect.Lists;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryCraftResult;
import net.minecraft.inventory.Slot;
import net.minecraft.inventory.SlotCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import forestry.factory.inventory.InventoryCraftingForestry;
import forestry.factory.tiles.ICrafterWorktable;
public class SlotCrafter extends Slot {
@@ -27,7 +27,7 @@ public class SlotCrafter extends Slot {
/**
* The craft matrix inventory linked to this result slot.
*/
private final IInventory craftMatrix;
private final InventoryCraftingForestry craftMatrix;
private final ICrafterWorktable crafter;
/**
@@ -38,9 +38,9 @@ public class SlotCrafter extends Slot {
* The number of items that have been crafted so far. Gets passed to ItemStack.onCrafting before being reset.
*/
private int amountCrafted;
public SlotCrafter(EntityPlayer player, IInventory craftMatrix, ICrafterWorktable crafter, int slot, int xPos, int yPos) {
super(craftMatrix, slot, xPos, yPos);
public SlotCrafter(EntityPlayer player, InventoryCraftingForestry craftMatrix, IInventory craftingDisplay, ICrafterWorktable crafter, int slot, int xPos, int yPos) {
super(craftingDisplay, slot, xPos, yPos);
this.craftMatrix = craftMatrix;
this.crafter = crafter;
this.player = player;
@@ -75,12 +75,9 @@ public class SlotCrafter extends Slot {
}
this.amountCrafted = 0;
InventoryCraftResult inventorycraftresult = (InventoryCraftResult) this.inventory;
IRecipe irecipe = inventorycraftresult.getRecipeUsed();
IRecipe irecipe = crafter.getRecipeUsed();
if (irecipe != null && !irecipe.isHidden()) {
this.player.unlockRecipes(Lists.newArrayList(irecipe));
inventorycraftresult.setRecipeUsed(null);
}
}
@@ -100,7 +97,7 @@ public class SlotCrafter extends Slot {
@Override
public ItemStack getStack() {
return crafter.getResult();
return crafter.getResult(craftMatrix, player.world);
}
@Override
@@ -12,11 +12,13 @@ package forestry.core.inventory;
import forestry.api.genetics.AlleleManager;
import forestry.api.genetics.IIndividual;
import forestry.core.tiles.EscritoireGame;
import forestry.core.tiles.TileEscritoire;
import forestry.core.utils.GeneticsUtil;
import forestry.core.utils.SlotUtil;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
public class InventoryEscritoire extends InventoryAdapterTile<TileEscritoire> {
public static final short SLOT_ANALYZE = 0;
@@ -79,8 +81,10 @@ public class InventoryEscritoire extends InventoryAdapterTile<TileEscritoire> {
super.setInventorySlotContents(SLOT_ANALYZE, ersatz);
}
}
if (!tile.getWorld().isRemote) {
tile.getGame().initialize(getStackInSlot(SLOT_ANALYZE));
World world = tile.getWorld();
if (world != null && !world.isRemote) {
EscritoireGame game = tile.getGame();
game.initialize(getStackInSlot(SLOT_ANALYZE));
}
}
}
@@ -26,7 +26,8 @@ public enum EnumElectronTube implements ItemOverlay.IOverlayInfo {
EMERALD(new Color(0x00CC41)),
APATITE(new Color(0x579CD9)),
LAPIS(new Color(0x1c57c6)),
ENDER(new Color(0x33adad), new Color(0x255661));
ENDER(new Color(0x33adad), new Color(0x255661)),
ORCHID(new Color(0x820208), new Color(0xc64f3f));
public static final EnumElectronTube[] VALUES = values();
@@ -13,6 +13,11 @@ package forestry.core.items;
import javax.annotation.Nullable;
import java.util.List;
import forestry.core.blocks.IBlockRotatable;
import forestry.core.blocks.IBlockWithMeta;
import forestry.core.tiles.TileForestry;
import forestry.core.tiles.TileUtil;
import forestry.core.utils.ItemTooltipUtil;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.util.ITooltipFlag;
@@ -22,19 +27,12 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import forestry.core.blocks.IBlockRotatable;
import forestry.core.blocks.IBlockWithMeta;
import forestry.core.tiles.TileForestry;
import forestry.core.tiles.TileUtil;
import forestry.core.utils.ItemTooltipUtil;
public class ItemBlockForestry<B extends Block> extends ItemBlock {
public ItemBlockForestry(Block block) {
public ItemBlockForestry(B block) {
super(block);
setMaxDamage(0);
setHasSubtypes(true);
@@ -59,8 +59,10 @@ public class ItemCraftingMaterial extends ItemForestry {
@Override
public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> subItems) {
for (int i = 0; i < definition.length; i++) {
subItems.add(new ItemStack(this, 1, i));
if (this.isInCreativeTab(tab)) {
for (int i = 0; i < definition.length; i++) {
subItems.add(new ItemStack(this, 1, i));
}
}
}
@@ -25,6 +25,7 @@ import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@@ -66,11 +66,13 @@ public class ItemElectronTube extends ItemOverlay {
@Override
public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> subItems) {
for (int i = 0; i < overlays.length; i++) {
if (Config.isDebug || !overlays[i].isSecret()) {
ItemStack itemStack = new ItemStack(this, 1, i);
if (Config.isDebug || !getCircuits(itemStack).isEmpty()) {
subItems.add(itemStack);
if (this.isInCreativeTab(tab)) {
for (int i = 0; i < overlays.length; i++) {
if (Config.isDebug || !overlays[i].isSecret()) {
ItemStack itemStack = new ItemStack(this, 1, i);
if (Config.isDebug || !getCircuits(itemStack).isEmpty()) {
subItems.add(itemStack);
}
}
}
}
@@ -68,16 +68,18 @@ public class ItemFluidContainerForestry extends ItemForestry {
@SideOnly(Side.CLIENT)
@Override
public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> subItems) {
// empty
subItems.add(new ItemStack(this));
// filled
for (Fluid fluid : FluidRegistry.getRegisteredFluids().values()) {
ItemStack itemStack = new ItemStack(this);
IFluidHandlerItem fluidHandler = new FluidHandlerItemForestry(itemStack, type);
if (fluidHandler.fill(new FluidStack(fluid, Fluid.BUCKET_VOLUME), true) == Fluid.BUCKET_VOLUME) {
ItemStack filled = fluidHandler.getContainer();
subItems.add(filled);
if (this.isInCreativeTab(tab)) {
// empty
subItems.add(new ItemStack(this));
// filled
for (Fluid fluid : FluidRegistry.getRegisteredFluids().values()) {
ItemStack itemStack = new ItemStack(this);
IFluidHandlerItem fluidHandler = new FluidHandlerItemForestry(itemStack, type);
if (fluidHandler.fill(new FluidStack(fluid, Fluid.BUCKET_VOLUME), true) == Fluid.BUCKET_VOLUME) {
ItemStack filled = fluidHandler.getContainer();
subItems.add(filled);
}
}
}
}
@@ -89,8 +89,10 @@ public class ItemFruit extends ItemForestryFood {
@Override
public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> subItems) {
for (int i = 0; i < EnumFruit.values().length; i++) {
subItems.add(new ItemStack(this, 1, i));
if (this.isInCreativeTab(tab)) {
for (int i = 0; i < EnumFruit.values().length; i++) {
subItems.add(new ItemStack(this, 1, i));
}
}
}
@@ -55,9 +55,11 @@ public class ItemOverlay extends ItemForestry implements IColoredItem {
@Override
public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> subItems) {
for (int i = 0; i < overlays.length; i++) {
if (Config.isDebug || !overlays[i].isSecret()) {
subItems.add(new ItemStack(this, 1, i));
if (this.isInCreativeTab(tab)) {
for (int i = 0; i < overlays.length; i++) {
if (Config.isDebug || !overlays[i].isSecret()) {
subItems.add(new ItemStack(this, 1, i));
}
}
}
}
@@ -19,7 +19,7 @@ import net.minecraftforge.oredict.OreDictionary;
public class ItemRegistryCore extends ItemRegistry {
/* Fertilizer */
public final ItemForestry fertilizerBio;
public final ItemForestry compost;
public final ItemFertilizer fertilizerCompound;
/* Gems */
@@ -91,7 +91,7 @@ public class ItemRegistryCore extends ItemRegistry {
public final ItemCamouflageSprayCan camouflageSprayCan;
public ItemRegistryCore() {
fertilizerBio = registerItem(new ItemForestry(), "fertilizer_bio");
compost = registerItem(new ItemForestry(), "fertilizer_bio");
fertilizerCompound = registerItem(new ItemFertilizer(), "fertilizer_compound");
apatite = registerItem(new ItemForestry(), "apatite");
@@ -116,13 +116,25 @@ public class ItemRegistryCore extends ItemRegistry {
spectacles = registerItem(new ItemArmorNaturalist(), "naturalist_helmet");
peat = registerItem(new ItemForestry(), "peat");
peat = new ItemForestry() {
@Override
public int getItemBurnTime(ItemStack itemStack) {
return 2000;
}
};
registerItem(peat, "peat");
OreDictionary.registerOre(OreDictUtil.BRICK_PEAT, peat);
ash = registerItem(new ItemForestry(), "ash");
OreDictionary.registerOre(OreDictUtil.DUST_ASH, ash);
bituminousPeat = registerItem(new ItemForestry(), "bituminous_peat");
bituminousPeat = new ItemForestry() {
@Override
public int getItemBurnTime(ItemStack itemStack) {
return 4200;
}
};
registerItem(bituminousPeat, "bituminous_peat");
gearBronze = createItemForOreName(OreDictUtil.GEAR_BRONZE, "gear_bronze");
gearCopper = createItemForOreName(OreDictUtil.GEAR_COPPER, "gear_copper");
@@ -10,8 +10,6 @@
******************************************************************************/
package forestry.core.models;
import com.google.common.base.Preconditions;
import javax.annotation.Nullable;
import javax.vecmath.Matrix4f;
import java.util.ArrayList;
@@ -39,11 +37,12 @@ import net.minecraftforge.client.event.ModelBakeEvent;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.model.PerspectiveMapWrapper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import forestry.core.items.ItemCrated;
import forestry.core.utils.ItemStackUtil;
import forestry.core.utils.Log;
import forestry.core.utils.ModelUtil;
import forestry.storage.PluginStorage;
@@ -107,8 +106,16 @@ public class ModelCrate extends BlankModel {
@Override
public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, @Nullable World world, @Nullable EntityLivingBase entity) {
ItemCrated crated = (ItemCrated) stack.getItem();
ResourceLocation itemName = ItemStackUtil.getItemNameFromRegistry(crated);
Preconditions.checkNotNull(itemName);
ResourceLocation itemName = crated.getRegistryName();
if(itemName == null){
IBakedModel baseCrateModel = cache.get("base");
if(baseCrateModel == null){
baseCrateModel = ModelUtil.getModel(new ItemStack(PluginStorage.getItems().crate, 1, 1));
baseCrateModel = ForgeHooksClient.handleCameraTransforms(baseCrateModel, TransformType.GROUND, false);
}
Log.error("Failed to load the model of the create item: {}, please report this to the authors of forestry.", itemName);
return baseCrateModel;
}
String crateUID = itemName.getResourcePath();
IBakedModel model = cache.get(crateUID);
if (model == null) {
@@ -12,6 +12,7 @@ package forestry.core.recipes;
import javax.annotation.Nullable;
import java.util.List;
import java.util.stream.Collectors;
import net.minecraft.block.Block;
import net.minecraft.inventory.IInventory;
@@ -37,9 +38,7 @@ import forestry.factory.inventory.InventoryCraftingForestry;
public abstract class RecipeUtil {
// hack to make unique recipe names.
// TODO use json recipes
private static int recipeIndex;
public static void addFermenterRecipes(ItemStack resource, int fermentationValue, Fluids output) {
if (RecipeManagers.fermenterManager == null) {
@@ -58,140 +57,85 @@ public abstract class RecipeUtil {
}
@Nullable
public static InventoryCraftingForestry getCraftRecipe(NonNullList<ItemStack> recipeItems, NonNullList<ItemStack> availableItems, World world, ItemStack recipeOutput) {
// Need at least one matched set
if (ItemStackUtil.containsSets(recipeItems, availableItems, true, true) == 0) {
public static InventoryCraftingForestry getCraftRecipe(InventoryCrafting originalCrafting, NonNullList<ItemStack> availableItems, World world, IRecipe recipe) {
if (!recipe.matches(originalCrafting, world)) {
return null;
}
// Check that it doesn't make a different recipe.
// For example:
// Wood Logs are all ore dictionary equivalent with each other,
// but an Oak Log shouldn't be able to make Ebony Wood Planks
// because it makes Oak Wood Planks using the same recipe.
// Strategy:
// Create a fake crafting inventory using items we have in availableItems
// in place of the ones in the saved crafting inventory.
// Check that the recipe it makes is the same as the currentRecipe.
ItemStack expectedOutput = recipe.getCraftingResult(originalCrafting);
if (expectedOutput.isEmpty()) {
return null;
}
InventoryCraftingForestry crafting = new InventoryCraftingForestry();
NonNullList<ItemStack> stockCopy = ItemStackUtil.condenseStacks(availableItems);
for (int slot = 0; slot < recipeItems.size(); slot++) {
ItemStack recipeStack = recipeItems.get(slot);
if (recipeStack.isEmpty()) {
continue;
}
// Use crafting equivalent (not oredict) items first
for (ItemStack stockStack : stockCopy) {
if (stockStack.getCount() > 0 && ItemStackUtil.isCraftingEquivalent(recipeStack, stockStack, false, false)) {
ItemStack stack = ItemStackUtil.createCopyWithCount(stockStack, 1);
stockStack.shrink(1);
crafting.setInventorySlotContents(slot, stack);
break;
for (int slot = 0; slot < originalCrafting.getSizeInventory(); slot++) {
ItemStack stackInSlot = originalCrafting.getStackInSlot(slot);
if (!stackInSlot.isEmpty()) {
ItemStack equivalent = getCraftingEquivalent(stockCopy, originalCrafting, slot, world, recipe, expectedOutput);
if (equivalent.isEmpty()) {
return null;
} else {
crafting.setInventorySlotContents(slot, equivalent);
}
}
}
if (recipe.matches(crafting, world)) {
ItemStack output = recipe.getCraftingResult(crafting);
if (ItemStack.areItemStacksEqual(output, expectedOutput)) {
return crafting;
}
}
// Use oredict items if crafting equivalent items aren't available
if (crafting.getStackInSlot(slot).isEmpty()) {
for (ItemStack stockStack : stockCopy) {
if (stockStack.getCount() > 0 && ItemStackUtil.isCraftingEquivalent(recipeStack, stockStack, true, true)) {
ItemStack stack = ItemStackUtil.createCopyWithCount(stockStack, 1);
stockStack.shrink(1);
crafting.setInventorySlotContents(slot, stack);
break;
return null;
}
private static ItemStack getCraftingEquivalent(NonNullList<ItemStack> stockCopy, InventoryCrafting crafting, int slot, World world, IRecipe recipe, ItemStack expectedOutput) {
ItemStack originalStack = crafting.getStackInSlot(slot);
for (ItemStack stockStack : stockCopy) {
if (!stockStack.isEmpty()) {
ItemStack singleStockStack = ItemStackUtil.createCopyWithCount(stockStack, 1);
crafting.setInventorySlotContents(slot, singleStockStack);
if (recipe.matches(crafting, world)) {
ItemStack output = recipe.getCraftingResult(crafting);
if (ItemStack.areItemStacksEqual(output, expectedOutput)) {
crafting.setInventorySlotContents(slot, originalStack);
return stockStack.splitStack(1);
}
}
}
}
List<ItemStack> outputs = findMatchingRecipes(crafting, world);
if (!ItemStackUtil.containsItemStack(outputs, recipeOutput)) {
return null;
}
return crafting;
}
public static NonNullList<ItemStack> findMatchingRecipes(InventoryCrafting inventory, World world) {
NonNullList<ItemStack> matchingRecipes = NonNullList.create();
ItemStack repairRecipe = findRepairRecipe(inventory);
if (!repairRecipe.isEmpty()) {
matchingRecipes.add(repairRecipe);
return matchingRecipes;
}
for (Object recipe : ForgeRegistries.RECIPES.getValues()) {
IRecipe irecipe = (IRecipe) recipe;
if (irecipe.matches(inventory, world)) {
ItemStack result = irecipe.getCraftingResult(inventory);
if (!ItemStackUtil.containsItemStack(matchingRecipes, result)) {
matchingRecipes.add(result);
}
}
}
return matchingRecipes;
}
private static ItemStack findRepairRecipe(InventoryCrafting inventory) {
int craftIngredientCount = 0;
ItemStack itemstack0 = ItemStack.EMPTY;
ItemStack itemstack1 = ItemStack.EMPTY;
for (int j = 0; j < inventory.getSizeInventory(); j++) {
ItemStack itemstack = inventory.getStackInSlot(j);
if (!itemstack.isEmpty()) {
if (craftIngredientCount == 0) {
itemstack0 = itemstack;
}
if (craftIngredientCount == 1) {
itemstack1 = itemstack;
}
++craftIngredientCount;
}
}
if (craftIngredientCount == 2 && itemstack0.getItem() == itemstack1.getItem() && itemstack0.getCount() == 1 && itemstack1.getCount() == 1 && itemstack0.getItem().isRepairable()) {
int damage0 = itemstack0.getMaxDamage() - itemstack0.getItemDamage();
int damage1 = itemstack0.getMaxDamage() - itemstack1.getItemDamage();
int repairAmount = damage0 + damage1 + itemstack0.getMaxDamage() * 5 / 100;
int repairedDamage = itemstack0.getMaxDamage() - repairAmount;
if (repairedDamage < 0) {
repairedDamage = 0;
}
return new ItemStack(itemstack0.getItem(), 1, repairedDamage);
}
crafting.setInventorySlotContents(slot, originalStack);
return ItemStack.EMPTY;
}
public static void addRecipe(Block block, Object... obj) {
addRecipe(new ItemStack(block), obj);
public static List<IRecipe> findMatchingRecipes(InventoryCrafting inventory, World world) {
return ForgeRegistries.RECIPES.getValues().stream().filter(recipe -> recipe.matches(inventory, world)).collect(Collectors.toList());
}
public static void addRecipe(Item item, Object... obj) {
addRecipe(new ItemStack(item), obj);
public static void addRecipe(String recipeName, Block block, Object... obj) {
addRecipe(recipeName, new ItemStack(block), obj);
}
public static void addRecipe(ItemStack itemstack, Object... obj) {
public static void addRecipe(String recipeName, Item item, Object... obj) {
addRecipe(recipeName, new ItemStack(item), obj);
}
public static void addRecipe(String recipeName, ItemStack itemstack, Object... obj) {
ShapedRecipeCustom recipe = new ShapedRecipeCustom(itemstack, obj);
recipe.setRegistryName(Constants.MOD_ID, "Recipe" + recipeIndex++);
recipe.setRegistryName(Constants.MOD_ID, recipeName);
ForgeRegistries.RECIPES.register(recipe);
}
public static void addShapelessRecipe(Item item, Object... obj) {
addShapelessRecipe(new ItemStack(item), obj);
public static void addShapelessRecipe(String recipeName, Item item, Object... obj) {
addShapelessRecipe(recipeName, new ItemStack(item), obj);
}
public static void addShapelessRecipe(ItemStack itemstack, Object... obj) {
public static void addShapelessRecipe(String recipeName, ItemStack itemstack, Object... obj) {
ShapelessOreRecipe recipe = new ShapelessOreRecipe(null, itemstack, obj);
recipe.setRegistryName(Constants.MOD_ID, "Recipe" + recipeIndex++);
recipe.setRegistryName(Constants.MOD_ID, recipeName);
ForgeRegistries.RECIPES.register(recipe);
}
@@ -203,6 +147,7 @@ public abstract class RecipeUtil {
GameRegistry.addSmelting(res, prod, xp);
}
@Nullable
public static String[][] matches(IDescriptiveRecipe recipe, IInventory inventoryCrafting) {
NonNullList<NonNullList<ItemStack>> recipeIngredients = recipe.getRawIngredients();
NonNullList<String> oreDicts = recipe.getOreDicts();
@@ -211,6 +156,7 @@ public abstract class RecipeUtil {
return matches(recipeIngredients, oreDicts, width, height, inventoryCrafting);
}
@Nullable
public static String[][] matches(NonNullList<NonNullList<ItemStack>> recipeIngredients, NonNullList<String> oreDicts, int width, int height, IInventory inventoryCrafting) {
ItemStack[][] resources = getResources(inventoryCrafting);
return matches(recipeIngredients, oreDicts, width, height, resources);
@@ -68,32 +68,30 @@ public class ParticleRender {
int color = genome.getPrimary().getSpriteColour(0);
if (!flowerPositions.isEmpty()) {
int randomInt = world.rand.nextInt(100);
int randomInt = world.rand.nextInt(100);
if (housing instanceof IHiveTile) {
if (((IHiveTile) housing).isAngry() || randomInt >= 85) {
List<EntityLivingBase> entitiesInRange = AlleleEffect.getEntitiesInRange(genome, housing, EntityLivingBase.class);
if (!entitiesInRange.isEmpty()) {
EntityLivingBase entity = entitiesInRange.get(world.rand.nextInt(entitiesInRange.size()));
Particle particle = new ParticleBeeTargetEntity(world, particleStart, entity, color);
effectRenderer.addEffect(particle);
return;
}
if (housing instanceof IHiveTile) {
if (((IHiveTile) housing).isAngry() || randomInt >= 85) {
List<EntityLivingBase> entitiesInRange = AlleleEffect.getEntitiesInRange(genome, housing, EntityLivingBase.class);
if (!entitiesInRange.isEmpty()) {
EntityLivingBase entity = entitiesInRange.get(world.rand.nextInt(entitiesInRange.size()));
Particle particle = new ParticleBeeTargetEntity(world, particleStart, entity, color);
effectRenderer.addEffect(particle);
return;
}
}
}
if (randomInt < 75) {
BlockPos destination = flowerPositions.get(world.rand.nextInt(flowerPositions.size()));
Particle particle = new ParticleBeeRoundTrip(world, particleStart, destination, color);
effectRenderer.addEffect(particle);
} else {
Vec3i area = AlleleEffect.getModifiedArea(genome, housing);
Vec3i offset = housing.getCoordinates().add(-area.getX() / 2, -area.getY() / 4, -area.getZ() / 2);
BlockPos destination = VectUtil.getRandomPositionInArea(world.rand, area).add(offset);
Particle particle = new ParticleBeeExplore(world, particleStart, destination, color);
effectRenderer.addEffect(particle);
}
if (randomInt < 75 && !flowerPositions.isEmpty()) {
BlockPos destination = flowerPositions.get(world.rand.nextInt(flowerPositions.size()));
Particle particle = new ParticleBeeRoundTrip(world, particleStart, destination, color);
effectRenderer.addEffect(particle);
} else {
Vec3i area = AlleleEffect.getModifiedArea(genome, housing);
Vec3i offset = housing.getCoordinates().add(-area.getX() / 2, -area.getY() / 4, -area.getZ() / 2);
BlockPos destination = VectUtil.getRandomPositionInArea(world.rand, area).add(offset);
Particle particle = new ParticleBeeExplore(world, particleStart, destination, color);
effectRenderer.addEffect(particle);
}
}
@@ -29,8 +29,6 @@ import forestry.core.utils.Log;
@SideOnly(Side.CLIENT)
public class TextureMapForestry extends TextureMap {
private boolean skipFirst = true;
public TextureMapForestry(String basePathIn) {
super(basePathIn, null, true);
}
@@ -49,44 +47,41 @@ public class TextureMapForestry extends TextureMap {
this.mapUploadedSprites.clear();
this.listAnimatedSprites.clear();
ProgressManager.ProgressBar bar = ProgressManager.push("Texture stitching", skipFirst ? 0 : this.mapRegisteredSprites.size());
ProgressManager.ProgressBar bar = ProgressManager.push("Texture stitching", this.mapRegisteredSprites.size());
for (Map.Entry<String, TextureAtlasSprite> entry : this.mapRegisteredSprites.entrySet()) {
TextureAtlasSprite textureatlassprite = entry.getValue();
ResourceLocation resourcelocation = this.getResourceLocation(textureatlassprite);
bar.step(resourcelocation.getResourcePath());
IResource iresource = null;
if (!skipFirst) {
for (Map.Entry<String, TextureAtlasSprite> entry : this.mapRegisteredSprites.entrySet()) {
TextureAtlasSprite textureatlassprite = entry.getValue();
ResourceLocation resourcelocation = this.getResourceLocation(textureatlassprite);
bar.step(resourcelocation.getResourcePath());
IResource iresource = null;
if (textureatlassprite.hasCustomLoader(resourceManager, resourcelocation)) {
if (textureatlassprite.load(resourceManager, resourcelocation, l -> mapRegisteredSprites.get(l.toString()))) {
continue;
}
} else
try {
PngSizeInfo pngsizeinfo = PngSizeInfo.makeFromResource(resourceManager.getResource(resourcelocation));
iresource = resourceManager.getResource(resourcelocation);
boolean flag = iresource.getMetadata("animation") != null;
textureatlassprite.loadSprite(pngsizeinfo, flag);
} catch (RuntimeException runtimeexception) {
FMLClientHandler.instance().trackBrokenTexture(resourcelocation, runtimeexception.getMessage());
continue;
} catch (IOException ioexception) {
FMLClientHandler.instance().trackMissingTexture(resourcelocation);
continue;
} finally {
IOUtils.closeQuietly(iresource);
}
if (textureatlassprite.hasCustomLoader(resourceManager, resourcelocation)) {
if (textureatlassprite.load(resourceManager, resourcelocation, l -> mapRegisteredSprites.get(l.toString()))) {
continue;
}
} else
try {
PngSizeInfo pngsizeinfo = PngSizeInfo.makeFromResource(resourceManager.getResource(resourcelocation));
iresource = resourceManager.getResource(resourcelocation);
boolean flag = iresource.getMetadata("animation") != null;
textureatlassprite.loadSprite(pngsizeinfo, flag);
} catch (RuntimeException runtimeexception) {
FMLClientHandler.instance().trackBrokenTexture(resourcelocation, runtimeexception.getMessage());
continue;
} catch (IOException ioexception) {
FMLClientHandler.instance().trackMissingTexture(resourcelocation);
continue;
} finally {
IOUtils.closeQuietly(iresource);
}
stitcher.addSprite(textureatlassprite);
}
stitcher.addSprite(textureatlassprite);
}
ProgressManager.pop(bar);
this.missingImage.generateMipmaps(0);
stitcher.addSprite(this.missingImage);
skipFirst = false;
bar = ProgressManager.push("Texture creation", 2);
bar.step("Stitching");
@@ -97,6 +97,7 @@ public class EscritoireGame implements INbtWritable, INbtReadable, IStreamable {
/* INTERACTION */
public void initialize(ItemStack specimen) {
reset();
if (gameBoard.initialize(specimen)) {
status = Status.PLAYING;
bountyLevel = BOUNTY_MAX;
@@ -27,6 +27,7 @@ import forestry.core.network.PacketBufferForestry;
import forestry.core.network.packets.PacketTileStream;
import forestry.core.utils.NBTUtilForestry;
import forestry.core.utils.NetworkUtil;
import forestry.core.utils.TickHelper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.ItemStack;
@@ -48,14 +49,12 @@ import net.minecraftforge.items.wrapper.SidedInvWrapper;
//@Optional.Interface(iface = "buildcraft.api.statements.ITriggerProvider", modid = "BuildCraftAPI|statements")
public abstract class TileForestry extends TileEntity implements IStreamable, IErrorLogicSource, ISidedInventory, IFilterSlotDelegate, ITitled, ILocatable, IGuiHandlerTile, ITickable {
private static final Random rand = new Random();
private final ErrorLogic errorHandler = new ErrorLogic();
private final AdjacentTileCache tileCache = new AdjacentTileCache(this);
private IInventoryAdapter inventory = FakeInventoryAdapter.instance();
private int tickCount = rand.nextInt(256);
private final TickHelper tickHelper = new TickHelper();
private boolean needsNetworkUpdate = false;
protected AdjacentTileCache getTileCache() {
@@ -81,7 +80,7 @@ public abstract class TileForestry extends TileEntity implements IStreamable, IE
// / UPDATING
@Override
public final void update() {
tickCount++;
tickHelper.onTick();
if (!world.isRemote) {
updateServerSide();
@@ -103,7 +102,7 @@ public abstract class TileForestry extends TileEntity implements IStreamable, IE
}
protected final boolean updateOnInterval(int tickInterval) {
return tickCount % tickInterval == 0;
return tickHelper.updateOnInterval(tickInterval);
}
// / SAVING & LOADING
@@ -0,0 +1,63 @@
package forestry.core.utils;
import java.util.AbstractSet;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
/**
* A set with fast {@link #contains(Object)} for IBlockState
*/
public class BlockStateSet extends AbstractSet<IBlockState> {
private final Set<IBlockState> blockStates = new HashSet<>();
private final Map<Block, Integer> blocks = new IdentityHashMap<>();
@Override
public boolean add(IBlockState blockState) {
Block block = blockState.getBlock();
Integer count = blocks.getOrDefault(block, 0);
blocks.put(block, count + 1);
return blockStates.add(blockState);
}
@Override
public boolean remove(Object o) {
IBlockState blockState = (IBlockState) o;
Block block = blockState.getBlock();
Integer count = blocks.getOrDefault(block, 0);
if (count > 0) {
blocks.put(block, count - 1);
} else {
blocks.remove(block);
}
return blockStates.remove(blockState);
}
@Override
public boolean contains(Object o) {
IBlockState blockState = (IBlockState) o;
Block block = blockState.getBlock();
return blocks.containsKey(block) && blockStates.contains(blockState);
}
@Override
public void clear() {
blockStates.clear();
blocks.clear();
}
@Override
public Iterator<IBlockState> iterator() {
return blockStates.iterator();
}
@Override
public int size() {
return blockStates.size();
}
}
@@ -11,14 +11,7 @@
package forestry.core.utils;
import javax.annotation.Nullable;
import java.util.Collection;
import forestry.api.core.ForestryAPI;
import forestry.core.circuits.ISocketable;
import forestry.core.inventory.ItemHandlerInventoryManipulator;
import forestry.core.inventory.StandardStackFilters;
import forestry.core.tiles.AdjacentTileCache;
import forestry.plugins.ForestryPluginUids;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
@@ -29,78 +22,20 @@ import net.minecraft.util.EnumFacing;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.fml.common.Optional;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.oredict.OreDictionary;
import net.minecraftforge.fml.common.Optional;
import forestry.api.core.ForestryAPI;
import forestry.core.circuits.ISocketable;
import forestry.core.inventory.ItemHandlerInventoryManipulator;
import forestry.core.inventory.StandardStackFilters;
import forestry.core.tiles.AdjacentTileCache;
import forestry.plugins.ForestryPluginUids;
public abstract class InventoryUtil {
public static boolean isWildcard(ItemStack stack) {
return stack.getItemDamage() == OreDictionary.WILDCARD_VALUE;
}
/**
* A more robust item comparison function. Supports items with damage = -1
* matching any sub-type.
*
* @param a An ItemStack
* @param b An ItemStack
* @return True if equal
*/
public static boolean isItemEqual(ItemStack a, ItemStack b) {
return isItemEqual(a, b, true, true);
}
public static boolean isItemEqual(final ItemStack a, final ItemStack b, final boolean matchDamage, final boolean matchNBT) {
if (a.isEmpty() || b.isEmpty()) {
return false;
}
if (a.getItem() != b.getItem()) {
return false;
}
if (matchNBT && !ItemStack.areItemStackTagsEqual(a, b)) {
return false;
}
if (matchDamage && a.getHasSubtypes()) {
if (isWildcard(a) || isWildcard(b)) {
return true;
}
if (a.getItemDamage() != b.getItemDamage()) {
return false;
}
}
return true;
}
/**
* Returns true if the item is equal to any one of several possible matches.
*/
public static boolean isItemEqual(ItemStack stack, ItemStack... matches) {
for (ItemStack match : matches) {
if (isItemEqual(stack, match)) {
return true;
}
}
return false;
}
/**
* Returns true if the item is equal to any one of several possible matches.
*
* @param stack the ItemStack to test
* @param matches the ItemStacks to test against
* @return true if a match is found
*/
public static boolean isItemEqual(ItemStack stack, Collection<ItemStack> matches) {
for (ItemStack match : matches) {
if (isItemEqual(stack, match)) {
return true;
}
}
return false;
}
/**
* Attempts to move an ItemStack from one inventory to another.
*
@@ -218,6 +153,48 @@ public abstract class InventoryUtil {
return ItemStackUtil.containsSets(set, stock, oreDicts, craftingTools) >= count;
}
}
public static boolean deleteExactSet(IInventory inventory, NonNullList<ItemStack> required) {
NonNullList<ItemStack> offered = getStacks(inventory);
NonNullList<ItemStack> condensedRequired = ItemStackUtil.condenseStacks(required);
NonNullList<ItemStack> condensedOffered = ItemStackUtil.condenseStacks(offered);
for (ItemStack req : condensedRequired) {
if (!containsExactStack(req, condensedOffered)) {
return false;
}
}
for (ItemStack itemStack : condensedRequired) {
deleteExactStack(inventory, itemStack);
}
return true;
}
private static boolean containsExactStack(ItemStack req, NonNullList<ItemStack> condensedOffered) {
for (ItemStack offer : condensedOffered) {
if (offer.getCount() >= req.getCount() && ItemStackUtil.areItemStacksEqualIgnoreCount(req, offer)) {
return true;
}
}
return false;
}
private static void deleteExactStack(IInventory inventory, ItemStack itemStack) {
int count = itemStack.getCount();
for (int j = 0; j < inventory.getSizeInventory(); j++) {
ItemStack stackInSlot = inventory.getStackInSlot(j);
if (!stackInSlot.isEmpty()) {
if (ItemStackUtil.areItemStacksEqualIgnoreCount(itemStack, stackInSlot)) {
ItemStack removed = inventory.decrStackSize(j, count);
count -= removed.getCount();
if (count == 0) {
return;
}
}
}
}
}
@Nullable
public static NonNullList<ItemStack> removeSets(IInventory inventory, int count, NonNullList<ItemStack> set, @Nullable EntityPlayer player, boolean stowContainer, boolean oreDictionary, boolean craftingTools) {
@@ -303,7 +280,7 @@ public abstract class InventoryUtil {
for (int j = 0; j < inventory.getSizeInventory(); j++) {
ItemStack stackInSlot = inventory.getStackInSlot(j);
if (!stackInSlot.isEmpty()) {
if (ItemStackUtil.isCraftingEquivalent(stackInSlot, stackToRemove, oreDictOfStack, craftingTools)) {
if (ItemStackUtil.isCraftingEquivalent(stackToRemove, stackInSlot, oreDictOfStack, craftingTools)) {
ItemStack removed = inventory.decrStackSize(j, stackToRemove.getCount());
stackToRemove.shrink(removed.getCount());
@@ -394,7 +371,7 @@ public abstract class InventoryUtil {
public static boolean tryAddStacksCopy(IInventory inventory, NonNullList<ItemStack> stacks, int startSlot, int slots, boolean all) {
for (ItemStack stack : stacks) {
if (stack == null) {
if (stack == null || stack.isEmpty()) {
continue;
}
@@ -594,5 +594,24 @@ public abstract class ItemStackUtil {
}
return null;
}
/**
* Checks like {@link ItemStack#areItemStacksEqual(ItemStack, ItemStack)}
* but ignores stack size (count).
*/
public static boolean areItemStacksEqualIgnoreCount(ItemStack a, ItemStack b) {
if (a.isEmpty() && b.isEmpty()) {
return true;
} else if (a.isEmpty() || b.isEmpty()) {
return false;
} else if (a.getItem() != b.getItem()) {
return false;
} else if (a.getItemDamage() != b.getItemDamage()) {
return false;
} else if (a.getTagCompound() == null && b.getTagCompound() != null) {
return false;
} else {
return (a.getTagCompound() == null || a.getTagCompound().equals(b.getTagCompound())) && a.areCapsCompatible(b);
}
}
}
@@ -13,8 +13,12 @@ import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.registry.ForgeRegistries;
@Mod.EventBusSubscriber
public class MigrationHelper {
private static Map<String, String> blockRemappings = new HashMap<>();
private static Map<String, String> itemRemappings = new HashMap<>();
@@ -51,6 +55,7 @@ public class MigrationHelper {
}
}
@SubscribeEvent
public static void onMissingBlockMappings(RegistryEvent.MissingMappings<Block> event) {
for (RegistryEvent.MissingMappings.Mapping<Block> missingMapping : event.getMappings()) {
ResourceLocation resourceLocation = missingMapping.key;
@@ -70,6 +75,7 @@ public class MigrationHelper {
}
}
@SubscribeEvent
public static void onMissingItemMappings(RegistryEvent.MissingMappings<Item> event) {
for (RegistryEvent.MissingMappings.Mapping<Item> missingMapping : event.getMappings()) {
ResourceLocation resourceLocation = missingMapping.key;
@@ -67,6 +67,26 @@ public abstract class PlayerUtil {
return player;
}
/**
* Get a fake player for a given World and GameProfile.
* Do not store references to the return value, to prevent worlds staying in memory.
*/
@Nullable
public static EntityPlayer getFakePlayer(World world, @Nullable GameProfile profile) {
if (profile == null || profile.getName() == null) {
if (world instanceof WorldServer) {
return FakePlayerFactory.getMinecraft((WorldServer) world);
} else {
return null;
}
}
if (world instanceof WorldServer) {
return FakePlayerFactory.get((WorldServer) world, profile);
}
return null;
}
public static void writeGameProfile(NBTTagCompound tagCompound, GameProfile profile) {
if (!StringUtils.isNullOrEmpty(profile.getName())) {
tagCompound.setString("Name", profile.getName());
@@ -12,6 +12,7 @@ package forestry.core.utils;
import java.util.List;
import forestry.core.gui.slots.SlotCrafter;
import forestry.core.gui.slots.SlotForestry;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
@@ -70,7 +71,7 @@ public abstract class SlotUtil {
return ItemStack.EMPTY;
}
boolean fromCraftingSlot = slot instanceof SlotCrafting;
boolean fromCraftingSlot = slot instanceof SlotCrafting || slot instanceof SlotCrafter;
int numSlots = inventorySlots.size();
ItemStack stackInSlot = slot.getStack();
@@ -82,7 +83,7 @@ public abstract class SlotUtil {
slot.onSlotChange(stackInSlot, originalStack);
if (stackInSlot.isEmpty()) {
slot.putStack(stackInSlot);
slot.putStack(ItemStack.EMPTY);
} else {
slot.onSlotChanged();
}
@@ -0,0 +1,16 @@
package forestry.core.utils;
import java.util.Random;
public final class TickHelper {
private static final Random rand = new Random();
private int tickCount = rand.nextInt(2048);
public void onTick() {
tickCount++;
}
public boolean updateOnInterval(int tickInterval) {
return tickCount % tickInterval == 0;
}
}
@@ -11,6 +11,7 @@
package forestry.core.utils;
import javax.annotation.Nullable;
import java.util.Iterator;
import java.util.Random;
import com.google.common.collect.AbstractIterator;
@@ -57,11 +58,11 @@ public final class VectUtil {
}
}
public static Iterable<BlockPos.MutableBlockPos> getAllInBoxFromCenterMutable(World world, final BlockPos from, final BlockPos center, final BlockPos to) {
public static Iterator<BlockPos.MutableBlockPos> getAllInBoxFromCenterMutable(World world, final BlockPos from, final BlockPos center, final BlockPos to) {
final BlockPos minPos = new BlockPos(Math.min(from.getX(), to.getX()), Math.min(from.getY(), to.getY()), Math.min(from.getZ(), to.getZ()));
final BlockPos maxPos = new BlockPos(Math.max(from.getX(), to.getX()), Math.max(from.getY(), to.getY()), Math.max(from.getZ(), to.getZ()));
return () -> new MutableBlockPosSpiralIterator(world, center, maxPos, minPos);
return new MutableBlockPosSpiralIterator(world, center, maxPos, minPos);
}
private static class MutableBlockPosSpiralIterator extends AbstractIterator<BlockPos.MutableBlockPos> {
@@ -21,6 +21,7 @@ import net.minecraft.world.gen.IChunkGenerator;
import net.minecraft.world.gen.feature.WorldGenMinable;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.terraingen.DecorateBiomeEvent;
import net.minecraftforge.event.terraingen.PopulateChunkEvent;
import net.minecraftforge.fml.common.IWorldGenerator;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@@ -54,6 +55,11 @@ public class WorldGenerator implements IWorldGenerator {
PluginManager.populateChunk(event.getGen(), event.getWorld(), event.getRand(), event.getChunkX(), event.getChunkZ(), event.isHasVillageGenerated());
}
@SubscribeEvent
public void decorateBiome(DecorateBiomeEvent.Post event) {
PluginManager.decorateBiome(event.getWorld(), event.getRand(), event.getPos());
}
public void retroGen(Random random, int chunkX, int chunkZ, World world) {
generateWorld(random, chunkX, chunkZ, world);
PluginManager.populateChunkRetroGen(world, random, chunkX, chunkZ);
@@ -57,7 +57,7 @@ public class PluginEnergy extends BlankForestryPlugin {
super.registerRecipes();
Preconditions.checkState(blocks != null);
RecipeUtil.addRecipe(new ItemStack(blocks.peatEngine),
RecipeUtil.addRecipe("peat_engine", new ItemStack(blocks.peatEngine),
"###",
" X ",
"YVY",
@@ -66,7 +66,7 @@ public class PluginEnergy extends BlankForestryPlugin {
'Y', "gearCopper",
'V', Blocks.PISTON);
RecipeUtil.addRecipe(new ItemStack(blocks.biogasEngine),
RecipeUtil.addRecipe("biogas_engine", new ItemStack(blocks.biogasEngine),
"###",
" X ",
"YVY",
@@ -76,7 +76,7 @@ public class PluginEnergy extends BlankForestryPlugin {
'V', Blocks.PISTON);
if (ForestryAPI.activeMode.getBooleanSetting("energy.engine.clockwork")) {
RecipeUtil.addRecipe(new ItemStack(blocks.clockworkEngine),
RecipeUtil.addRecipe("clockwork_engine", new ItemStack(blocks.clockworkEngine),
"###",
" X ",
"ZVY",
@@ -144,7 +144,7 @@ public class PluginFactory extends BlankForestryPlugin {
int cyclesCompost = ForestryAPI.activeMode.getIntegerSetting("fermenter.cycles.compost");
int valueCompost = ForestryAPI.activeMode.getIntegerSetting("fermenter.value.compost");
ItemStack fertilizerBio = coreItems.fertilizerBio.getItemStack();
ItemStack fertilizerBio = coreItems.compost.getItemStack();
ItemStack mulch = coreItems.mulch.getItemStack();
FuelManager.fermenterFuel.put(fertilizerBio, new FermenterFuel(fertilizerBio, valueCompost, cyclesCompost));
FuelManager.fermenterFuel.put(mulch, new FermenterFuel(mulch, valueCompost, cyclesCompost));
@@ -325,6 +325,12 @@ public class PluginFactory extends BlankForestryPlugin {
"XXX",
'#', new ItemStack(Items.ENDER_EYE, 1, 0),
'X', new ItemStack(Blocks.END_STONE, 1, 0)});
RecipeManagers.fabricatorManager.addRecipe(ItemStack.EMPTY, Fluids.GLASS.getFluid(500), electronTube.get(EnumElectronTube.ORCHID, 4), new Object[]{
" X ",
"#X#",
"XXX",
'#', new ItemStack(Items.REPEATER, 1, 0),
'X', new ItemStack(Blocks.REDSTONE_ORE, 1, 0)});
String[] dyes = {"dyeBlack", "dyeRed", "dyeGreen", "dyeBrown", "dyeBlue", "dyePurple", "dyeCyan", "dyeLightGray", "dyeGray", "dyePink", "dyeLime",
"dyeYellow", "dyeLightBlue", "dyeMagenta", "dyeOrange", "dyeWhite"};
@@ -542,7 +548,7 @@ public class PluginFactory extends BlankForestryPlugin {
ChipsetManager.solderManager.addRecipe(layout, coreItems.tubes.get(EnumElectronTube.BLAZE, 1), Circuits.machineSpeedUpgrade2);
ChipsetManager.solderManager.addRecipe(layout, coreItems.tubes.get(EnumElectronTube.GOLD, 1), Circuits.machineEfficiencyUpgrade1);
RecipeUtil.addRecipe(blocks.bottler,
RecipeUtil.addRecipe("bottler", blocks.bottler,
"X#X",
"#Y#",
"X#X",
@@ -550,7 +556,7 @@ public class PluginFactory extends BlankForestryPlugin {
'X', fluidItems.canEmpty,
'Y', coreItems.sturdyCasing);
RecipeUtil.addRecipe(blocks.carpenter,
RecipeUtil.addRecipe("carpenter", blocks.carpenter,
"X#X",
"XYX",
"X#X",
@@ -558,7 +564,7 @@ public class PluginFactory extends BlankForestryPlugin {
'X', "ingotBronze",
'Y', coreItems.sturdyCasing);
RecipeUtil.addRecipe(blocks.centrifuge,
RecipeUtil.addRecipe("centrifuge", blocks.centrifuge,
"X#X",
"XYX",
"X#X",
@@ -566,7 +572,7 @@ public class PluginFactory extends BlankForestryPlugin {
'X', "ingotCopper",
'Y', coreItems.sturdyCasing);
RecipeUtil.addRecipe(blocks.fermenter,
RecipeUtil.addRecipe("fermenter", blocks.fermenter,
"X#X",
"#Y#",
"X#X",
@@ -574,7 +580,7 @@ public class PluginFactory extends BlankForestryPlugin {
'X', "gearBronze",
'Y', coreItems.sturdyCasing);
RecipeUtil.addRecipe(blocks.moistener,
RecipeUtil.addRecipe("moistener", blocks.moistener,
"X#X",
"#Y#",
"X#X",
@@ -582,7 +588,7 @@ public class PluginFactory extends BlankForestryPlugin {
'X', "gearCopper",
'Y', coreItems.sturdyCasing);
RecipeUtil.addRecipe(blocks.squeezer,
RecipeUtil.addRecipe("squeezer", blocks.squeezer,
"X#X",
"XYX",
"X#X",
@@ -590,7 +596,7 @@ public class PluginFactory extends BlankForestryPlugin {
'X', "ingotTin",
'Y', coreItems.sturdyCasing);
RecipeUtil.addRecipe(blocks.still,
RecipeUtil.addRecipe("still", blocks.still,
"X#X",
"#Y#",
"X#X",
@@ -598,7 +604,7 @@ public class PluginFactory extends BlankForestryPlugin {
'X', "dustRedstone",
'Y', coreItems.sturdyCasing);
RecipeUtil.addRecipe(blocks.rainmaker,
RecipeUtil.addRecipe("rainmaker", blocks.rainmaker,
"X#X",
"#Y#",
"X#X",
@@ -606,7 +612,7 @@ public class PluginFactory extends BlankForestryPlugin {
'X', "gearTin",
'Y', coreItems.hardenedCasing);
RecipeUtil.addRecipe(blocks.fabricator,
RecipeUtil.addRecipe("fabricator", blocks.fabricator,
"X#X",
"#Y#",
"XZX",
@@ -615,7 +621,7 @@ public class PluginFactory extends BlankForestryPlugin {
'Y', coreItems.sturdyCasing,
'Z', "chestWood");
RecipeUtil.addRecipe(blocks.raintank,
RecipeUtil.addRecipe("raintank", blocks.raintank,
"X#X",
"XYX",
"X#X",
@@ -623,7 +629,7 @@ public class PluginFactory extends BlankForestryPlugin {
'X', "ingotIron",
'Y', coreItems.sturdyCasing);
RecipeUtil.addRecipe(blocks.worktable,
RecipeUtil.addRecipe("worktable", blocks.worktable,
"B",
"W",
"C",
@@ -30,28 +30,28 @@ public class BlockRegistryFactory extends BlockRegistry {
public BlockRegistryFactory() {
bottler = new BlockFactoryTESR(BlockTypeFactoryTesr.BOTTLER);
registerBlock(bottler, new ItemBlockForestry(bottler), "bottler");
registerBlock(bottler, new ItemBlockForestry<>(bottler), "bottler");
carpenter = new BlockFactoryTESR(BlockTypeFactoryTesr.CARPENTER);
registerBlock(carpenter, new ItemBlockForestry(carpenter), "carpenter");
registerBlock(carpenter, new ItemBlockForestry<>(carpenter), "carpenter");
centrifuge = new BlockFactoryTESR(BlockTypeFactoryTesr.CENTRIFUGE);
registerBlock(centrifuge, new ItemBlockForestry(centrifuge), "centrifuge");
registerBlock(centrifuge, new ItemBlockForestry<>(centrifuge), "centrifuge");
fermenter = new BlockFactoryTESR(BlockTypeFactoryTesr.FERMENTER);
registerBlock(fermenter, new ItemBlockForestry(fermenter), "fermenter");
registerBlock(fermenter, new ItemBlockForestry<>(fermenter), "fermenter");
moistener = new BlockFactoryTESR(BlockTypeFactoryTesr.MOISTENER);
registerBlock(moistener, new ItemBlockForestry(moistener), "moistener");
registerBlock(moistener, new ItemBlockForestry<>(moistener), "moistener");
squeezer = new BlockFactoryTESR(BlockTypeFactoryTesr.SQUEEZER);
registerBlock(squeezer, new ItemBlockForestry(squeezer), "squeezer");
registerBlock(squeezer, new ItemBlockForestry<>(squeezer), "squeezer");
still = new BlockFactoryTESR(BlockTypeFactoryTesr.STILL);
registerBlock(still, new ItemBlockForestry(still), "still");
registerBlock(still, new ItemBlockForestry<>(still), "still");
rainmaker = new BlockFactoryTESR(BlockTypeFactoryTesr.RAINMAKER);
registerBlock(rainmaker, new ItemBlockForestry(rainmaker), "rainmaker");
registerBlock(rainmaker, new ItemBlockForestry<>(rainmaker), "rainmaker");
fabricator = new BlockFactoryPlain(BlockTypeFactoryPlain.FABRICATOR);
registerBlock(fabricator, new ItemBlockNBT(fabricator), "fabricator");
@@ -63,7 +63,7 @@ public class ContainerWorktable extends ContainerTile<TileWorktable> implements
}
// CraftResult display
addSlotToContainer(new SlotCrafter(player, craftingDisplay, tile, InventoryGhostCrafting.SLOT_CRAFTING_RESULT, 77, 38));
addSlotToContainer(new SlotCrafter(player, craftMatrix, craftingDisplay, tile, InventoryGhostCrafting.SLOT_CRAFTING_RESULT, 77, 38));
for (int i = 0; i < craftMatrix.getSizeInventory(); i++) {
onCraftMatrixChanged(tile.getCraftingDisplay(), i);
@@ -12,14 +12,31 @@ package forestry.factory.inventory;
import forestry.core.gui.ContainerDummy;
import forestry.factory.gui.ContainerWorktable;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.InventoryCrafting;
public class InventoryCraftingForestry extends InventoryCrafting {
private final Container eventHandlerIn;
public InventoryCraftingForestry(ContainerWorktable containerWorktable) {
super(containerWorktable, 3, 3);
this(containerWorktable, 3, 3);
}
public InventoryCraftingForestry() {
super(ContainerDummy.instance, 3, 3);
this(ContainerDummy.instance, 3, 3);
}
private InventoryCraftingForestry(Container eventHandlerIn, int width, int height) {
super(eventHandlerIn, width, height);
this.eventHandlerIn = eventHandlerIn;
}
public InventoryCraftingForestry copy() {
InventoryCraftingForestry copy = new InventoryCraftingForestry(this.eventHandlerIn, getWidth(), getHeight());
for (int slot = 0; slot < getSizeInventory(); slot++) {
copy.setInventorySlotContents(slot, getStackInSlot(slot).copy());
}
return copy;
}
}
@@ -10,24 +10,33 @@
******************************************************************************/
package forestry.factory.recipes;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagString;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.registry.ForgeRegistries;
import forestry.api.core.INbtReadable;
import forestry.api.core.INbtWritable;
import forestry.core.network.IStreamable;
import forestry.core.network.PacketBufferForestry;
import forestry.core.recipes.RecipeUtil;
import forestry.core.utils.InventoryUtil;
import forestry.core.utils.ItemStackUtil;
import forestry.core.utils.NBTUtilForestry;
import forestry.factory.inventory.InventoryCraftingForestry;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.NonNullList;
import net.minecraft.world.World;
public final class MemorizedRecipe implements INbtWritable, INbtReadable, IStreamable {
private final InventoryCraftingForestry craftMatrix = new InventoryCraftingForestry();
private NonNullList<ItemStack> recipeOutputs = NonNullList.create();
private InventoryCraftingForestry craftMatrix = new InventoryCraftingForestry();
private List<IRecipe> recipes = new ArrayList<>();
private int selectedRecipe;
private long lastUsed;
private boolean locked;
@@ -39,29 +48,23 @@ public final class MemorizedRecipe implements INbtWritable, INbtReadable, IStrea
public MemorizedRecipe(NBTTagCompound nbt) {
readFromNBT(nbt);
}
public MemorizedRecipe(InventoryCraftingForestry craftMatrix, NonNullList<ItemStack> recipeOutputs) {
public MemorizedRecipe(InventoryCraftingForestry craftMatrix, List<IRecipe> recipes) {
InventoryUtil.deepCopyInventoryContents(craftMatrix, this.craftMatrix);
this.recipeOutputs = recipeOutputs;
this.recipes = recipes;
}
public InventoryCraftingForestry getCraftMatrix() {
return craftMatrix;
}
public void calculateRecipeOutput(World world) {
recipeOutputs = RecipeUtil.findMatchingRecipes(craftMatrix, world);
if (selectedRecipe >= recipeOutputs.size()) {
selectedRecipe = 0;
}
if (hasRecipeConflict()) {
removeRecipeConflicts();
}
public void setCraftMatrix(InventoryCraftingForestry craftMatrix) {
this.craftMatrix = craftMatrix;
}
public void incrementRecipe() {
selectedRecipe++;
if (selectedRecipe >= recipeOutputs.size()) {
if (selectedRecipe >= recipes.size()) {
selectedRecipe = 0;
}
}
@@ -69,31 +72,54 @@ public final class MemorizedRecipe implements INbtWritable, INbtReadable, IStrea
public void decrementRecipe() {
selectedRecipe--;
if (selectedRecipe < 0) {
selectedRecipe = recipeOutputs.size() - 1;
selectedRecipe = recipes.size() - 1;
}
}
public boolean hasRecipeConflict() {
return recipeOutputs.size() > 1;
return recipes.size() > 1;
}
public void removeRecipeConflicts() {
ItemStack recipeOutput = getRecipeOutput();
recipeOutputs.clear();
recipeOutputs.add(recipeOutput);
IRecipe recipe = getSelectedRecipe();
recipes.clear();
recipes.add(recipe);
selectedRecipe = 0;
}
public ItemStack getRecipeOutput() {
if (recipeOutputs.isEmpty()) {
return ItemStack.EMPTY;
public ItemStack getOutputIcon() {
IRecipe selectedRecipe = getSelectedRecipe();
if (selectedRecipe != null) {
ItemStack recipeOutput = selectedRecipe.getCraftingResult(craftMatrix);
if (!recipeOutput.isEmpty()) {
return recipeOutput;
}
}
return ItemStack.EMPTY;
}
public ItemStack getCraftingResult(InventoryCrafting inventoryCrafting, World world) {
IRecipe selectedRecipe = getSelectedRecipe();
if (selectedRecipe != null && selectedRecipe.matches(inventoryCrafting, world)) {
ItemStack recipeOutput = selectedRecipe.getCraftingResult(inventoryCrafting);
if (!recipeOutput.isEmpty()) {
return recipeOutput;
}
}
return ItemStack.EMPTY;
}
@Nullable
public IRecipe getSelectedRecipe() {
if (recipes.isEmpty()) {
return null;
} else {
return recipeOutputs.get(selectedRecipe);
return recipes.get(selectedRecipe);
}
}
public boolean hasRecipeOutput(ItemStack output) {
return ItemStackUtil.containsItemStack(recipeOutputs, output);
public boolean hasRecipe(@Nullable IRecipe recipe) {
return this.recipes.contains(recipe);
}
public void updateLastUse(long lastUsed) {
@@ -122,6 +148,21 @@ public final class MemorizedRecipe implements INbtWritable, INbtReadable, IStrea
if (nbttagcompound.hasKey("SelectedRecipe")) {
selectedRecipe = nbttagcompound.getInteger("SelectedRecipe");
}
recipes.clear();
NBTTagList recipesNbt = nbttagcompound.getTagList("Recipes", NBTUtilForestry.EnumNBTType.STRING.ordinal());
for (int i = 0; i < recipesNbt.tagCount(); i++) {
String recipeKey = recipesNbt.getStringTagAt(i);
ResourceLocation key = new ResourceLocation(recipeKey);
IRecipe recipe = ForgeRegistries.RECIPES.getValue(key);
if (recipe != null) {
recipes.add(recipe);
}
}
if (selectedRecipe > recipes.size()) {
selectedRecipe = 0;
}
}
@Override
@@ -130,6 +171,16 @@ public final class MemorizedRecipe implements INbtWritable, INbtReadable, IStrea
nbttagcompound.setLong("LastUsed", lastUsed);
nbttagcompound.setBoolean("Locked", locked);
nbttagcompound.setInteger("SelectedRecipe", selectedRecipe);
NBTTagList recipesNbt = new NBTTagList();
for (IRecipe recipe : recipes) {
ResourceLocation recipeKey = ForgeRegistries.RECIPES.getKey(recipe);
if (recipeKey != null) {
recipesNbt.appendTag(new NBTTagString(recipeKey.toString()));
}
}
nbttagcompound.setTag("Recipes", recipesNbt);
return nbttagcompound;
}
@@ -138,15 +189,31 @@ public final class MemorizedRecipe implements INbtWritable, INbtReadable, IStrea
public void writeData(PacketBufferForestry data) {
data.writeInventory(craftMatrix);
data.writeBoolean(locked);
data.writeItemStacks(recipeOutputs);
data.writeVarInt(selectedRecipe);
data.writeVarInt(recipes.size());
for (IRecipe recipe: recipes) {
ResourceLocation recipeId = ForgeRegistries.RECIPES.getKey(recipe);
if (recipeId != null) {
data.writeString(recipeId.toString());
}
}
}
@Override
public void readData(PacketBufferForestry data) throws IOException {
data.readInventory(craftMatrix);
locked = data.readBoolean();
recipeOutputs = data.readItemStacks();
selectedRecipe = data.readVarInt();
recipes.clear();
int recipeCount = data.readVarInt();
for (int i = 0; i < recipeCount; i++) {
String recipeId = data.readString();
IRecipe recipe = ForgeRegistries.RECIPES.getValue(new ResourceLocation(recipeId));
if (recipe != null) {
recipes.add(recipe);
}
}
}
}
@@ -12,20 +12,17 @@ package forestry.factory.recipes;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import forestry.api.core.INbtWritable;
import forestry.core.network.IStreamable;
import forestry.core.network.PacketBufferForestry;
import net.minecraft.item.Item;
import net.minecraft.item.ItemMap;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@@ -33,12 +30,6 @@ public class RecipeMemory implements INbtWritable, IStreamable {
private static final int capacity = 9;
private static final List<Class<? extends Item>> memoryBlacklist = new ArrayList<>();
static {
memoryBlacklist.add(ItemMap.class); // almost every ItemMap is unique
}
private final LinkedList<MemorizedRecipe> memorizedRecipes;
private long lastUpdate;
@@ -56,31 +47,8 @@ public class RecipeMemory implements INbtWritable, IStreamable {
for (int j = 0; j < nbttaglist.tagCount(); ++j) {
NBTTagCompound recipeNbt = nbttaglist.getCompoundTagAt(j);
MemorizedRecipe recipe = new MemorizedRecipe(recipeNbt);
memorizedRecipes.add(recipe);
}
}
private static boolean isValid(@Nullable MemorizedRecipe recipe) {
if (recipe == null) {
return false;
}
ItemStack recipeOutput = recipe.getRecipeOutput();
if (recipeOutput.isEmpty()) {
return false;
}
Item item = recipeOutput.getItem();
return !memoryBlacklist.contains(item.getClass());
}
public void validate(World world) {
Iterator<MemorizedRecipe> iterator = memorizedRecipes.iterator();
while (iterator.hasNext()) {
MemorizedRecipe recipe = iterator.next();
if (recipe != null) {
recipe.calculateRecipeOutput(world);
if (!isValid(recipe)) {
iterator.remove();
}
if (recipe.getSelectedRecipe() != null) {
memorizedRecipes.add(recipe);
}
}
}
@@ -90,7 +58,7 @@ public class RecipeMemory implements INbtWritable, IStreamable {
}
public void memorizeRecipe(long worldTime, MemorizedRecipe recipe) {
if (!isValid(recipe)) {
if (recipe.getSelectedRecipe() == null) {
return;
}
@@ -102,7 +70,7 @@ public class RecipeMemory implements INbtWritable, IStreamable {
}
// update existing matching recipes
MemorizedRecipe memory = getExistingMemorizedRecipe(recipe.getRecipeOutput());
MemorizedRecipe memory = getExistingMemorizedRecipe(recipe.getSelectedRecipe());
if (memory != null) {
updateExistingRecipe(memory, recipe);
return;
@@ -156,7 +124,7 @@ public class RecipeMemory implements INbtWritable, IStreamable {
if (recipe == null) {
return ItemStack.EMPTY;
}
return recipe.getRecipeOutput();
return recipe.getOutputIcon();
}
public boolean isLocked(int recipeIndex) {
@@ -172,10 +140,12 @@ public class RecipeMemory implements INbtWritable, IStreamable {
}
@Nullable
private MemorizedRecipe getExistingMemorizedRecipe(ItemStack craftingRecipeOutput) {
for (MemorizedRecipe memorizedRecipe : memorizedRecipes) {
if (memorizedRecipe.hasRecipeOutput(craftingRecipeOutput)) {
return memorizedRecipe;
private MemorizedRecipe getExistingMemorizedRecipe(@Nullable IRecipe recipe) {
if (recipe != null) {
for (MemorizedRecipe memorizedRecipe : memorizedRecipes) {
if (memorizedRecipe.hasRecipe(recipe)) {
return memorizedRecipe;
}
}
}
@@ -186,7 +156,7 @@ public class RecipeMemory implements INbtWritable, IStreamable {
public NBTTagCompound writeToNBT(NBTTagCompound nbttagcompound) {
NBTTagList nbttaglist = new NBTTagList();
for (MemorizedRecipe recipe : memorizedRecipes) {
if (recipe != null) {
if (recipe != null && recipe.getSelectedRecipe() != null) {
NBTTagCompound recipeNbt = new NBTTagCompound();
recipe.writeToNBT(recipeNbt);
nbttaglist.appendTag(recipeNbt);
@@ -4,6 +4,7 @@ import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;
import forestry.core.recipes.RecipeUtil;
import forestry.factory.gui.ContainerWorktable;
import forestry.factory.inventory.InventoryCraftingForestry;
import forestry.factory.recipes.MemorizedRecipe;
@@ -13,6 +14,7 @@ import mezz.jei.api.recipe.transfer.IRecipeTransferError;
import mezz.jei.api.recipe.transfer.IRecipeTransferHandler;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.util.NonNullList;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@@ -27,27 +29,27 @@ class WorktableRecipeTransferHandler implements IRecipeTransferHandler<Container
@Nullable
@Override
public IRecipeTransferError transferRecipe(ContainerWorktable container, IRecipeLayout recipeLayout, EntityPlayer player, boolean maxTransfer, boolean doTransfer) {
Map<Integer, ? extends IGuiIngredient<ItemStack>> guiIngredients = recipeLayout.getItemStacks().getGuiIngredients();
InventoryCraftingForestry inventory = new InventoryCraftingForestry(container);
NonNullList<ItemStack> recipeOutputs = NonNullList.create();
for (Map.Entry<Integer, ? extends IGuiIngredient<ItemStack>> entry : guiIngredients.entrySet()) {
int recipeSlot = entry.getKey();
List<ItemStack> allIngredients = entry.getValue().getAllIngredients();
if (!allIngredients.isEmpty()) {
if (recipeSlot == 0) {
recipeOutputs.addAll(allIngredients);
} else {
ItemStack firstIngredient = allIngredients.get(0);
inventory.setInventorySlotContents(recipeSlot - 1, firstIngredient);
if (doTransfer) {
Map<Integer, ? extends IGuiIngredient<ItemStack>> guiIngredients = recipeLayout.getItemStacks().getGuiIngredients();
InventoryCraftingForestry inventory = new InventoryCraftingForestry(container);
for (Map.Entry<Integer, ? extends IGuiIngredient<ItemStack>> entry : guiIngredients.entrySet()) {
int recipeSlot = entry.getKey();
List<ItemStack> allIngredients = entry.getValue().getAllIngredients();
if (!allIngredients.isEmpty()) {
if (recipeSlot != 0) { // skip the output slot
ItemStack firstIngredient = allIngredients.get(0);
inventory.setInventorySlotContents(recipeSlot - 1, firstIngredient);
}
}
}
}
if (!recipeOutputs.isEmpty() && doTransfer) {
MemorizedRecipe recipe = new MemorizedRecipe(inventory, recipeOutputs);
container.sendWorktableRecipeRequest(recipe);
List<IRecipe> matchingRecipes = RecipeUtil.findMatchingRecipes(inventory, player.world);
if (!matchingRecipes.isEmpty()) {
MemorizedRecipe recipe = new MemorizedRecipe(inventory, matchingRecipes);
container.sendWorktableRecipeRequest(recipe);
}
}
return null;
Loaded 100 of 149 files, more files were not shown because too many files have changed in this diff. Show more