Compare commits

..
21 Commits
Author SHA1 Message Date
mezz 806ca2cf7b Bump version 2016-08-16 16:50:19 -07:00
mezz 9f171977bb Add some more tooltips and JEI description pages 2016-08-16 16:50:00 -07:00
mezz 2031f7fe02 Unify the way item and itemBlock tooltips are added 2016-08-16 16:49:28 -07:00
mezz 4259a55e7a Close #955 Automatically output water from the bottom of the Rain Tank 2016-08-15 00:12:47 -07:00
mezz 065344ba5e Clean up Rain Tank implementation 2016-08-14 22:52:53 -07:00
mezz d0c9a77528 Update dependencies 2016-08-14 21:40:39 -07:00
Nedelosk 604429f267 Fix #1388 Rendering Crash in Inventory and a climate crash 2016-08-14 13:27:12 +02:00
Nedelosk f5a9dcccb8 Fix #1387 Crash when creating a new world 2016-08-14 00:42:20 +02:00
Nedelosk b056cce707 Fix the woodTextures 2016-08-13 17:47:23 +02:00
Nedelosk 1497aada57 Improve the woodtextures class. 2016-08-13 17:24:26 +02:00
Nedelosk fb8ddf54b7 Adding a way to add costum wood models 2016-08-13 17:16:38 +02:00
Nedelosk 9a05322d45 Fix a mistake 2016-08-12 21:57:47 +02:00
Nedelosk 8c2008b06c Bump version 2016-08-12 21:54:08 +02:00
Nedelosk e3cc08a624 Fix #1382 Crash on load wood models and clean up 2016-08-12 21:46:41 +02:00
Nedelosk 36cd4663d9 Fix a cocoon bug and add a default cocoon loot 2016-08-12 13:59:05 +02:00
Nedelosk a014ef6d14 Fix #1381 Greenhouse climate switches between normal and very high levels and fix a cocoon bug 2016-08-12 13:48:19 +02:00
Nedelosk 34fa218c38 Try to fix the greengouse climate ledget and fix the greenhouse sprinklers 2016-08-12 13:18:08 +02:00
Nedelosk f422b577fe Fix model baker models 2016-08-12 12:42:52 +02:00
Nedelosk e379465227 Fix #1380 Forestry camoflaged blocks do not render the same as regular blocks 2016-08-12 12:36:10 +02:00
Nedelosk eb63e75200 Add new Wood Model Loader (#1367) 2016-08-11 21:22:02 -07:00
Nedelosk b5faab51c3 Update greenhouse climate system and improve camouflage system (#1334) 2016-08-11 20:53:04 -07:00
1171 changed files with 3789 additions and 11434 deletions

No files matched your search

+5 -5
View File
@@ -1,11 +1,11 @@
mcversion=1.10.2
forgeversion=12.18.1.2050
forgeversion=12.18.1.2060
mcp_mappings=snapshot_20160525
tesla_version=1.10.2-1.2.1.41
jei_version=3.8.0.240
ic2_version=2.6.15-ex110
tesla_version=1.10.2-1.2.1.42
jei_version=3.8.1.242
ic2_version=2.6.38-ex110
version_major=5
version_minor=2
version_patch=8
version_patch=9
+1 -1
Submodule lang updated: 0d52088d32...4c93562cb9.
+2
View File
@@ -28,6 +28,7 @@ import net.minecraftforge.fml.common.registry.GameRegistry;
import forestry.api.core.ForestryAPI;
import forestry.core.EventHandlerCore;
import forestry.core.climate.ClimateEventHandler;
import forestry.core.config.Config;
import forestry.core.config.Constants;
import forestry.core.config.GameMode;
@@ -78,6 +79,7 @@ public class Forestry {
EventHandlerCore eventHandlerCore = new EventHandlerCore();
MinecraftForge.EVENT_BUS.register(eventHandlerCore);
MinecraftForge.EVENT_BUS.register(new MultiblockEventHandler());
MinecraftForge.EVENT_BUS.register(new ClimateEventHandler());
configFolder = new File(event.getModConfigurationDirectory(), Constants.MOD_ID);
Config.load();
@@ -10,12 +10,8 @@ import javax.annotation.Nonnull;
import forestry.api.core.IClimateProvider;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import com.mojang.authlib.GameProfile;
import forestry.api.core.EnumHumidity;
import forestry.api.core.EnumTemperature;
import forestry.api.core.IErrorLogicSource;
import forestry.api.genetics.IHousing;
@@ -92,11 +92,38 @@ public enum EnumForestryWoodType implements IWoodType {
return VALUES[meta];
}
@Override
public int getCarbonization() {
return carbonization;
}
@Override
public int getCombustability() {
return combustability;
}
@Override
public String getPlankTexture() {
return "forestry:blocks/wood/planks." + getName();
}
@Override
public String getDoorLowerTexture() {
return "forestry:blocks/doors/" + getName() + "_lower";
}
@Override
public String getDoorUpperTexture() {
return "forestry:blocks/doors/" + getName() + "_upper";
}
@Override
public String getBarkTexture() {
return "forestry:blocks/wood/bark." + getName();
}
@Override
public String getHeartTexture() {
return "forestry:blocks/wood/heart." + getName();
}
}
@@ -71,4 +71,44 @@ public enum EnumVanillaWoodType implements IWoodType {
public int getCombustability() {
return combustability;
}
@Override
public String getPlankTexture() {
if(this == DARK_OAK){
return "blocks/planks_big_oak";
}
return "blocks/planks_" + getName();
}
@Override
public String getDoorLowerTexture() {
if(this == OAK){
return "blocks/door_wood_lower";
}
return "blocks/door_wood_lower";
}
@Override
public String getDoorUpperTexture() {
if(this == OAK){
return "blocks/door_wood_upper";
}
return "blocks/door_" + getName() + "_upper";
}
@Override
public String getBarkTexture() {
if(this == DARK_OAK){
return "blocks/log_big_oak";
}
return "blocks/log_" + getName();
}
@Override
public String getHeartTexture() {
if(this == DARK_OAK){
return "blocks/log_big_oak_top";
}
return "blocks/log_" + getName() + "_top";
}
}
@@ -5,6 +5,8 @@
******************************************************************************/
package forestry.api.arboriculture;
import java.util.List;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.ItemStack;
@@ -22,5 +24,7 @@ public interface IWoodAccess {
ItemStack getStack(IWoodType woodType, WoodBlockKind kind, boolean fireproof);
IBlockState getBlock(IWoodType woodType, WoodBlockKind kind, boolean fireproof);
List<IWoodType> getRegisteredWoodTypes();
}
@@ -0,0 +1,19 @@
/*******************************************************************************
* Copyright 2011-2014 SirSengir
*
* This work (the API) is licensed under the "MIT" License, see LICENSE.txt for details.
******************************************************************************/
package forestry.api.arboriculture;
import net.minecraft.client.renderer.ItemMeshDefinition;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public interface IWoodItemMeshDefinition extends ItemMeshDefinition {
ResourceLocation getDefaultModelLocation(ItemStack stack);
}
@@ -0,0 +1,21 @@
/*******************************************************************************
* Copyright 2011-2014 SirSengir
*
* This work (the API) is licensed under the "MIT" License, see LICENSE.txt for details.
******************************************************************************/
package forestry.api.arboriculture;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.block.statemap.IStateMapper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public interface IWoodStateMapper extends IStateMapper {
ModelResourceLocation getModelLocation(IBlockState state);
ModelResourceLocation getDefaultModelResourceLocation(IBlockState state);
}
@@ -14,4 +14,14 @@ public interface IWoodType extends IStringSerializable {
int getCarbonization();
int getCombustability();
String getPlankTexture();
String getDoorLowerTexture();
String getDoorUpperTexture();
String getBarkTexture();
String getHeartTexture();
}
@@ -1,12 +1,68 @@
package forestry.api.arboriculture;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.ModelProcessingHelper;
public enum WoodBlockKind {
LOG, PLANKS, SLAB, FENCE, FENCE_GATE, STAIRS, DOOR;
LOG, PLANKS, SLAB, FENCE, FENCE_GATE, STAIRS, DOOR(false);
public final boolean retextureItem;
private WoodBlockKind() {
this(true);
}
private WoodBlockKind(boolean retextureItem) {
this.retextureItem = retextureItem;
}
@Override
public String toString() {
return super.toString().toLowerCase(Locale.ENGLISH);
}
public IModel retextureModel(IModel model, IWoodType type, ImmutableMap<String, String> customTextures){
Map<String, String> textures = new HashMap<>();
switch (this) {
case SLAB:
case STAIRS:
String textureLocation = type.getPlankTexture();
textures.put("particle", textureLocation);
textures.put("side", textureLocation);
textures.put("top", textureLocation);
textures.put("bottom", textureLocation);
textures.put("all", textureLocation);
break;
case PLANKS:
textures.put("particle", type.getPlankTexture());
textures.put("all", type.getPlankTexture());
break;
case FENCE_GATE:
case FENCE:
textures.put("particle", type.getPlankTexture());
textures.put("side", type.getPlankTexture());
textures.put("texture", type.getPlankTexture());
break;
case DOOR:
textures.put("particle", type.getDoorLowerTexture());
textures.put("bottom", type.getDoorLowerTexture());
textures.put("top", type.getDoorUpperTexture());
break;
case LOG:
textures.put("particle", type.getBarkTexture());
textures.put("side", type.getBarkTexture());
textures.put("all", type.getBarkTexture());
textures.put("end", type.getHeartTexture());
break;
default:
break;
}
textures.putAll(customTextures);
return ModelProcessingHelper.retexture(model, new ImmutableMap.Builder<String, String>().putAll(textures).build());
}
}
@@ -5,8 +5,14 @@
******************************************************************************/
package forestry.api.core;
public enum EnumCamouflageType {
DEFAULT, GLASS, DOOR;
public class CamouflageManager {
public static final EnumCamouflageType[] VALUES = values();
public static ICamouflageAccess camouflageAccess;
public static final String DEFAULT = "default";
public static final String GLASS = "glass";
public static final String DOOR = "door";
}
@@ -7,6 +7,7 @@ package forestry.api.core;
import java.util.Set;
import forestry.api.core.climate.IClimateManager;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@@ -0,0 +1,33 @@
/*******************************************************************************
* Copyright 2011-2014 SirSengir
*
* This work (the API) is licensed under the "MIT" License, see LICENSE.txt for details.
******************************************************************************/
package forestry.api.core;
import java.util.List;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
public interface ICamouflageAccess {
/**
* Register a item camouflage handler for a type.
*
* @param type The camouflage type for of handler.
* @param itemHandler The handler that is to register.
*/
void registerCamouflageItemHandler(@Nonnull ICamouflageItemHandler itemHandler);
/**
* @return A list of all item camouflage handler's that are registered for that camouflage type.
*/
List<ICamouflageItemHandler> getCamouflageItemHandler(@Nonnull String type);
void addItemToBlackList(@Nonnull String type, @Nonnull ItemStack camouflageBlock);
boolean isItemBlackListed(@Nonnull String type, @Nonnull ItemStack camouflageBlock);
}
@@ -7,27 +7,34 @@ package forestry.api.core;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public interface ICamouflageHandler{
/**
* @return The item of the block that is the camouflage of this handler for the EnumCamouflageType.
* @return The item of the block that is the camouflage of this handler for the type.
*/
ItemStack getCamouflageBlock(EnumCamouflageType type);
ItemStack getCamouflageBlock(String type);
/**
* @return The default camouflage block item for the EnumCamouflageType.
* @return The default camouflage block item for the type.
*/
ItemStack getDefaultCamouflageBlock(EnumCamouflageType type);
ItemStack getDefaultCamouflageBlock(String type);
/**
* @return True if the handler can handle this type of camouflage.
*/
boolean canHandleType(String type);
/**
* Set the camouflage block item for the EnumCamouflageType.
* Set the camouflage block item for the type.
*/
void setCamouflageBlock(EnumCamouflageType type, ItemStack camouflageBlock);
void setCamouflageBlock(String type, ItemStack camouflageBlock);
/**
* @return The coordinates of the handler as a BlockPos.
*/
BlockPos getCoordinates();
World getWorld();
}
@@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright 2011-2014 SirSengir
*
* This work (the API) is licensed under the "MIT" License, see LICENSE.txt for details.
******************************************************************************/
package forestry.api.core;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public interface ICamouflageItemHandler {
boolean canHandle(ItemStack stack, ICamouflageHandler camouflageHandler);
String getType();
float getLightTransmittance(ItemStack stack, ICamouflageHandler camouflageHandler);
@SideOnly(Side.CLIENT)
Pair<IBlockState, IBakedModel> getModel(ItemStack stack, ICamouflageHandler camouflageHandler, ICamouflagedTile camouflageTile);
}
@@ -9,7 +9,7 @@ import net.minecraft.util.math.BlockPos;
public interface ICamouflagedTile {
EnumCamouflageType getCamouflageType();
String getCamouflageType();
BlockPos getCoordinates();
@@ -1,19 +0,0 @@
/*******************************************************************************
* 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 IClimateManager {
float getTemperature(World world, BlockPos pos);
float getHumidity(World world, BlockPos pos);
IClimateProvider getDefaultClimate(World world, BlockPos pos);
}
@@ -8,8 +8,6 @@ package forestry.api.core;
import net.minecraft.client.renderer.ItemMeshDefinition;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@@ -0,0 +1,18 @@
/*******************************************************************************
* Copyright 2011-2014 SirSengir
*
* This work (the API) is licensed under the "MIT" License, see LICENSE.txt for details.
******************************************************************************/
package forestry.api.core.climate;
public interface IClimateControlled {
/**
* Change the temperature, but not lower than boundaryDown or higher than boundaryUp.
*/
void addTemperatureChange(float change, float boundaryDown, float boundaryUp);
/**
* Change the humidity, but not lower than boundaryDown or higher than boundaryUp.
*/
void addHumidityChange(float change, float boundaryDown, float boundaryUp);
}
@@ -0,0 +1,43 @@
/*******************************************************************************
* Copyright 2011-2014 SirSengir
*
* This work (the API) is licensed under the "MIT" License, see LICENSE.txt for details.
******************************************************************************/
package forestry.api.core.climate;
import java.util.List;
import java.util.Map;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import forestry.api.core.IClimateProvider;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public interface IClimateManager {
float getTemperature(World world, BlockPos pos);
float getHumidity(World world, BlockPos pos);
IClimateProvider getDefaultClimate(World world, BlockPos pos);
void addRegion(IClimateRegion region);
void removeRegion(IClimateRegion region);
void addSource(IClimateSource source);
void removeSource(IClimateSource source);
@Nullable
IClimateRegion getRegionForPos(World world, BlockPos pos);
@Nonnull
Map<Integer, List<IClimateRegion>> getRegions();
@Nonnull
Map<Integer, Map<BlockPos, IClimateSource>> getSources();
}
@@ -0,0 +1,34 @@
/*******************************************************************************
* Copyright 2011-2014 SirSengir
*
* This work (the API) is licensed under the "MIT" License, see LICENSE.txt for details.
******************************************************************************/
package forestry.api.core.climate;
import javax.annotation.Nonnull;
import forestry.api.core.INbtReadable;
import forestry.api.core.INbtWritable;
import net.minecraft.util.math.BlockPos;
public interface IClimatePosition extends INbtReadable, INbtWritable {
@Nonnull
IClimateRegion getClimateRegion();
@Nonnull
BlockPos getPos();
void setTemperature(float temperature);
void addTemperature(float temperature);
float getTemperature();
void setHumidity(float humidity);
void addHumidity(float humidity);
float getHumidity();
}
@@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright 2011-2014 SirSengir
*
* This work (the API) is licensed under the "MIT" License, see LICENSE.txt for details.
******************************************************************************/
package forestry.api.core.climate;
import java.util.List;
import java.util.Map;
import javax.annotation.Nonnull;
import forestry.api.core.INbtReadable;
import forestry.api.core.INbtWritable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public interface IClimateRegion extends INbtReadable, INbtWritable {
@Nonnull
World getWorld();
/**
* Update the climate in a region, all 20 world ticks.
*/
void updateClimate();
@Nonnull
Map<BlockPos, IClimatePosition> getPositions();
int getTicksPerUpdate();
List<BlockPos> getOtherPositions();
}
@@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright 2011-2014 SirSengir
*
* This work (the API) is licensed under the "MIT" License, see LICENSE.txt for details.
******************************************************************************/
package forestry.api.core.climate;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
/**
* A climate source is used to change the climate in a region.
*/
public interface IClimateSource {
/**
* @param tickCount The current tick count.
* @param region The climate region, in that the source stands.
*/
void changeClimate(int tickCount, IClimateRegion region);
/**
* @return The ticks that are required for one change.
*/
int getTicksForChange(IClimateRegion region);
World getWorld();
BlockPos getPos();
}
@@ -5,10 +5,12 @@
******************************************************************************/
package forestry.api.genetics;
import net.minecraft.block.state.IBlockState;
import net.minecraftforge.common.BiomeDictionary;
import forestry.api.core.EnumHumidity;
import forestry.api.core.EnumTemperature;
import net.minecraft.block.state.IBlockState;
import net.minecraftforge.common.BiomeDictionary;
/** Set custom mutation requirements */
public interface IMutationBuilder {
@@ -10,7 +10,7 @@ import forestry.api.multiblock.IGreenhouseController;
public class DefaultGreenhouseListener implements IGreenhouseListener {
@Override
public <G extends IGreenhouseController & IGreenhouseHousing> boolean canWork(G greenhouse, boolean canWork) {
public boolean canWork(IGreenhouseController greenhouse, boolean canWork) {
return true;
}
@@ -1,12 +1,7 @@
/*******************************************************************************
* 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
* Copyright 2011-2014 SirSengir
*
* Various Contributors including, but not limited to:
* SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges
* This work (the API) is licensed under the "MIT" License, see LICENSE.txt for details.
******************************************************************************/
package forestry.api.greenhouse;
@@ -15,17 +10,17 @@ import javax.annotation.Nullable;
import net.minecraftforge.fml.common.eventhandler.Event;
import forestry.api.core.EnumCamouflageType;
import forestry.api.core.ICamouflageHandler;
import forestry.api.core.ICamouflagedTile;
import forestry.api.multiblock.IGreenhouseController;
public class GreenhouseEvents extends Event {
@Nullable
public final IGreenhouseState state;
public final IGreenhouseController controller;
public GreenhouseEvents(@Nullable IGreenhouseState state) {
this.state = state;
public GreenhouseEvents(@Nullable IGreenhouseController state) {
this.controller = state;
}
public static class CamouflageChangeEvent extends GreenhouseEvents{
@@ -35,10 +30,10 @@ public class GreenhouseEvents extends Event {
@Nonnull
public ICamouflageHandler camouflageHandler;
@Nonnull
public final EnumCamouflageType camouflageType;
public final String camouflageType;
public CamouflageChangeEvent(IGreenhouseState state, @Nullable ICamouflagedTile camouflagedBlock, @Nonnull ICamouflageHandler camouflageHandler, @Nonnull EnumCamouflageType camouflageType) {
super(state);
public CamouflageChangeEvent(IGreenhouseController controller, @Nullable ICamouflagedTile camouflagedBlock, @Nonnull ICamouflageHandler camouflageHandler, @Nonnull String camouflageType) {
super(controller);
this.camouflagedBlock = camouflagedBlock;
this.camouflageHandler = camouflageHandler;
@@ -51,8 +46,8 @@ public class GreenhouseEvents extends Event {
@Nonnull
public IInternalBlock internalBlock;
public InternalBlockEvent(IGreenhouseState state, @Nonnull IInternalBlock internalBlock) {
super(state);
public InternalBlockEvent(IGreenhouseController controller, @Nonnull IInternalBlock internalBlock) {
super(controller);
this.internalBlock = internalBlock;
}
@@ -60,8 +55,8 @@ public class GreenhouseEvents extends Event {
public static class CreateInternalBlockEvent extends InternalBlockEvent{
public CreateInternalBlockEvent(IGreenhouseState state, IInternalBlock internalBlock) {
super(state, internalBlock);
public CreateInternalBlockEvent(IGreenhouseController controller, IInternalBlock internalBlock) {
super(controller, internalBlock);
}
}
@@ -70,8 +65,8 @@ public class GreenhouseEvents extends Event {
@Nonnull
public final IInternalBlockFace face;
public CheckInternalBlockFaceEvent(IGreenhouseState state, IInternalBlock internalBlock, @Nonnull IInternalBlockFace face) {
super(state, internalBlock);
public CheckInternalBlockFaceEvent(IGreenhouseController controller, IInternalBlock internalBlock, @Nonnull IInternalBlockFace face) {
super(controller, internalBlock);
this.face = face;
}
@@ -5,15 +5,8 @@
******************************************************************************/
package forestry.api.greenhouse;
import java.util.ArrayList;
import java.util.List;
public class GreenhouseManager {
public static IGreenhouseAccess greenhouseAccess;
public static IGreenhouseHelper greenhouseHelper;
public static List<Class<? extends IGreenhouseLogic>> greenhouseLogics = new ArrayList<>();
}
@@ -1,25 +0,0 @@
/*******************************************************************************
* Copyright 2011-2014 SirSengir
*
* This work (the API) is licensed under the "MIT" License, see LICENSE.txt for details.
******************************************************************************/
package forestry.api.greenhouse;
import javax.annotation.Nonnull;
import forestry.api.core.EnumCamouflageType;
import net.minecraft.item.ItemStack;
public interface IGreenhouseAccess {
void registerGreenhouseGlass(@Nonnull ItemStack glass, float lightTransmittance);
boolean isGreenhouseGlass(@Nonnull ItemStack glass);
float getGreenhouseGlassLightTransmittance(@Nonnull ItemStack glass);
void addToCamouflageBlockBlackList(@Nonnull EnumCamouflageType type, @Nonnull ItemStack camouflageBlock);
boolean isOnCamouflageBlockBlackList(@Nonnull EnumCamouflageType type, @Nonnull ItemStack camouflageBlock);
}
@@ -5,14 +5,21 @@
******************************************************************************/
package forestry.api.greenhouse;
import java.util.List;
import forestry.api.multiblock.IGreenhouseController;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public interface IGreenhouseHelper {
/**
* @return A {@link IGreenhouseState} of a greenhouse, when the pos is a greenhouse
* @return A {@link IGreenhouseController} of a greenhouse, when the pos is a greenhouse
*/
IGreenhouseState getGreenhouseState(World world, BlockPos pos);
IGreenhouseController getGreenhouseController(World world, BlockPos pos);
void addGreenhouseLogic(Class<? extends IGreenhouseLogic> logic);
List<Class<? extends IGreenhouseLogic>> getGreenhouseLogics();
}
@@ -10,12 +10,12 @@ import forestry.api.multiblock.IGreenhouseController;
public interface IGreenhouseListener {
/**
* Called before the greenhouse work.
* Called before the greenhouse update the climate system.
*
* @param greenhouse The greenhouse multiblock.
* @param greenhouse The greenhouse of the listener.
* @param canWork The actual {@link Boolean} value.
* @return True if the greenhouse can work.
* @return True if the greenhouse can update the climate.
*/
<G extends IGreenhouseController & IGreenhouseHousing> boolean canWork(G greenhouse, boolean canWork);
boolean canWork(IGreenhouseController greenhouse, boolean canWork);
}
@@ -1,29 +0,0 @@
/*******************************************************************************
* Copyright 2011-2014 SirSengir
*
* This work (the API) is licensed under the "MIT" License, see LICENSE.txt for details.
******************************************************************************/
package forestry.api.greenhouse;
import java.util.Collection;
import java.util.Set;
import forestry.api.core.EnumHumidity;
import forestry.api.core.EnumTemperature;
import forestry.api.multiblock.IMultiblockComponent;
public interface IGreenhouseState {
EnumTemperature getTemperature();
EnumHumidity getHumidity();
float getExactTemperature();
float getExactHumidity();
Set<IInternalBlock> getInternalBlocks();
Collection<IMultiblockComponent> getGreenhouseComponents();
}
@@ -7,6 +7,7 @@ package forestry.api.greenhouse;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import net.minecraft.util.math.BlockPos;
@@ -7,7 +7,7 @@ package forestry.api.multiblock;
import forestry.api.apiculture.IBeeListener;
import forestry.api.apiculture.IBeeModifier;
import forestry.api.core.IClimateControlled;
import forestry.api.core.climate.IClimateControlled;
/**
* Needs to be implemented by TileEntities that want to be part of an alveary.
@@ -5,8 +5,7 @@
******************************************************************************/
package forestry.api.multiblock;
import forestry.api.core.IClimateControlled;
import forestry.api.greenhouse.IGreenhouseHousing;
import forestry.api.core.climate.IClimateSource;
import forestry.api.greenhouse.IGreenhouseListener;
import forestry.api.lepidopterology.IButterflyCocoon;
import net.minecraft.item.ItemStack;
@@ -22,8 +21,7 @@ public interface IGreenhouseComponent<T extends IMultiblockLogicGreenhouse> exte
interface Door extends IGreenhouseComponent {
}
interface Climatiser extends IGreenhouseComponent {
<G extends IGreenhouseController & IGreenhouseHousing & IClimateControlled> void changeClimate(int tickCount, G greenhouse);
interface Climatiser extends IGreenhouseComponent, IClimateSource {
}
interface ButterflyHatch extends IGreenhouseComponent {
@@ -7,13 +7,15 @@ package forestry.api.multiblock;
import java.util.List;
import javax.annotation.Nullable;
import forestry.api.core.ICamouflageHandler;
import forestry.api.core.IClimateControlled;
import forestry.api.core.climate.IClimateRegion;
import forestry.api.greenhouse.EnumGreenhouseEventType;
import forestry.api.greenhouse.IGreenhouseHousing;
import forestry.api.greenhouse.IGreenhouseLogic;
public interface IGreenhouseController extends IMultiblockController, IGreenhouseHousing, ICamouflageHandler, IClimateControlled {
public interface IGreenhouseController extends IMultiblockController, IGreenhouseHousing, ICamouflageHandler {
/**
* Handle change events.
@@ -24,5 +26,8 @@ public interface IGreenhouseController extends IMultiblockController, IGreenhous
* @return The logics of the greenhouse.
*/
List<IGreenhouseLogic> getLogics();
@Nullable
IClimateRegion getRegion();
}
@@ -15,4 +15,6 @@ public interface IMultiblockLogicFactory {
IMultiblockLogicFarm createFarmLogic();
IMultiblockLogicGreenhouse createGreenhouseLogic();
IMultiblockLogicCharcoalPile createCharcoalPileLogic();
}
@@ -2,13 +2,13 @@ package forestry.apiculture.compat;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.List;
import forestry.api.apiculture.BeeManager;
import forestry.api.genetics.IAlleleSpecies;
import forestry.apiculture.PluginApiculture;
import forestry.apiculture.items.ItemRegistryApiculture;
import forestry.core.genetics.Genome;
import forestry.core.utils.JeiUtil;
import mezz.jei.api.BlankModPlugin;
import mezz.jei.api.IModRegistry;
import mezz.jei.api.ISubtypeRegistry;
@@ -19,29 +19,31 @@ import net.minecraft.item.ItemStack;
public class ApicultureJeiPlugin extends BlankModPlugin {
@Override
public void register(@Nonnull IModRegistry registry) {
List<ItemStack> frames = Arrays.asList(
new ItemStack(PluginApiculture.items.frameImpregnated),
new ItemStack(PluginApiculture.items.frameProven),
new ItemStack(PluginApiculture.items.frameUntreated)
ItemRegistryApiculture items = PluginApiculture.items;
JeiUtil.addDescription(registry, "frames",
items.frameImpregnated,
items.frameProven,
items.frameUntreated
);
registry.addDescription(frames, "for.jei.description.frames");
List<ItemStack> apiaristSuit = Arrays.asList(
new ItemStack(PluginApiculture.items.apiaristBoots),
new ItemStack(PluginApiculture.items.apiaristChest),
new ItemStack(PluginApiculture.items.apiaristHat),
new ItemStack(PluginApiculture.items.apiaristLegs)
JeiUtil.addDescription(registry, "apiarist.suit",
items.apiaristBoots,
items.apiaristChest,
items.apiaristHat,
items.apiaristLegs
);
registry.addDescription(apiaristSuit, "for.jei.description.apiarist.suit");
registry.addDescription(new ItemStack(PluginApiculture.items.habitatLocator), "for.jei.description.habitat.locator");
registry.addDescription(new ItemStack(PluginApiculture.items.scoop), "for.jei.description.scoop");
JeiUtil.addDescription(registry,
items.habitatLocator,
items.scoop,
items.imprinter
);
ISubtypeRegistry subtypeRegistry = registry.getJeiHelpers().getSubtypeRegistry();
subtypeRegistry.registerNbtInterpreter(PluginApiculture.items.beeDroneGE, BeeSubtypeInterpreter.INSTANCE);
subtypeRegistry.registerNbtInterpreter(PluginApiculture.items.beePrincessGE, BeeSubtypeInterpreter.INSTANCE);
subtypeRegistry.registerNbtInterpreter(PluginApiculture.items.beeQueenGE, BeeSubtypeInterpreter.INSTANCE);
subtypeRegistry.registerNbtInterpreter(items.beeDroneGE, BeeSubtypeInterpreter.INSTANCE);
subtypeRegistry.registerNbtInterpreter(items.beePrincessGE, BeeSubtypeInterpreter.INSTANCE);
subtypeRegistry.registerNbtInterpreter(items.beeQueenGE, BeeSubtypeInterpreter.INSTANCE);
}
private static class BeeSubtypeInterpreter implements ISubtypeRegistry.ISubtypeInterpreter {
@@ -12,17 +12,6 @@ package forestry.apiculture.items;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import forestry.api.core.EnumHumidity;
import forestry.api.core.EnumTemperature;
import forestry.api.core.ForestryAPI;
@@ -36,6 +25,15 @@ import forestry.apiculture.inventory.ItemInventoryHabitatLocator;
import forestry.apiculture.render.TextureHabitatLocator;
import forestry.core.items.ItemWithGui;
import forestry.core.utils.Translator;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class ItemHabitatLocator extends ItemWithGui implements ISpriteRegister {
private static final String iconName = "forestry:items/biomefinder";
@@ -69,6 +67,8 @@ public class ItemHabitatLocator extends ItemWithGui implements ISpriteRegister {
@Override
public void addInformation(ItemStack itemstack, EntityPlayer player, List<String> list, boolean flag) {
super.addInformation(itemstack, player, list, flag);
Biome currentBiome = player.worldObj.getBiome(player.getPosition());
float temperatureValue = ForestryAPI.climateManager.getTemperature(player.worldObj, player.getPosition());
@@ -1,7 +1,10 @@
package forestry.apiculture.items;
import java.util.List;
import forestry.api.apiculture.IArmorApiarist;
import forestry.api.apiculture.IHiveTile;
import forestry.api.core.Tabs;
import forestry.core.items.ItemForestry;
import forestry.core.proxy.Proxies;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
@@ -9,20 +12,13 @@ import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumHandSide;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import forestry.api.apiculture.IArmorApiarist;
import forestry.api.apiculture.IHiveTile;
import forestry.api.core.Tabs;
import forestry.core.items.ItemForestry;
import forestry.core.proxy.Proxies;
import forestry.core.utils.Translator;
public class ItemSmoker extends ItemForestry implements IArmorApiarist {
public ItemSmoker() {
super(Tabs.tabApiculture);
@@ -106,12 +102,6 @@ public class ItemSmoker extends ItemForestry implements IArmorApiarist {
return 32;
}
@Override
public void addInformation(ItemStack stack, EntityPlayer playerIn, List<String> tooltip, boolean advanced) {
super.addInformation(stack, playerIn, tooltip, advanced);
tooltip.add(Translator.translateToLocal("item.for.smoker.description"));
}
@Override
public boolean protectEntity(EntityLivingBase entity, ItemStack armor, String cause, boolean doProtect) {
return true;
@@ -25,7 +25,7 @@ import forestry.api.core.BiomeHelper;
import forestry.api.core.EnumHumidity;
import forestry.api.core.EnumTemperature;
import forestry.api.core.ForestryAPI;
import forestry.api.core.IClimateControlled;
import forestry.api.core.climate.IClimateControlled;
import forestry.api.multiblock.IAlvearyComponent;
import forestry.api.multiblock.IMultiblockComponent;
import forestry.apiculture.AlvearyBeeModifier;
@@ -15,8 +15,7 @@ import javax.annotation.Nullable;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import forestry.api.core.IClimateControlled;
import forestry.api.core.climate.IClimateControlled;
import forestry.api.multiblock.IAlvearyComponent;
import forestry.apiculture.network.packets.PacketActiveUpdate;
import forestry.core.proxy.Proxies;
@@ -22,8 +22,7 @@ import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import forestry.api.core.IClimateControlled;
import forestry.api.core.climate.IClimateControlled;
import forestry.api.multiblock.IAlvearyComponent;
import forestry.apiculture.blocks.BlockAlvearyType;
import forestry.apiculture.gui.ContainerAlvearyHygroregulator;
@@ -17,7 +17,7 @@ import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.BlockFenceGate;
import net.minecraft.block.BlockHorizontal;
import net.minecraft.block.BlockLog;
import net.minecraft.block.BlockSlab;
import net.minecraft.block.BlockStairs;
@@ -57,9 +57,8 @@ import forestry.apiculture.flowers.Flower;
import forestry.apiculture.flowers.FlowerRegistry;
import forestry.apiculture.tiles.TileBeeHouse;
import forestry.arboriculture.PluginArboriculture;
import forestry.arboriculture.blocks.log.BlockArbLog;
import forestry.core.PluginCore;
import forestry.core.blocks.BlockCore;
import forestry.core.blocks.BlockBase;
import forestry.core.config.Constants;
import forestry.core.tiles.TileUtil;
import forestry.plugins.ForestryPluginUids;
@@ -140,9 +139,9 @@ public class VillageApiaristHouse extends StructureVillagePieces.House1 {
fillWithBlocks(world, structBoundingBox, 8, 1, 6, 8, 1, 10, fence, fence, false);
fillWithBlocks(world, structBoundingBox, 2, 1, 10, 7, 1, 10, fence, fence, false);
setBlockState(world, fenceGate.withProperty(BlockFenceGate.FACING, EnumFacing.EAST), 8, 1, 8, structBoundingBox);
setBlockState(world, fenceGate.withProperty(BlockFenceGate.FACING, EnumFacing.EAST), 1, 1, 8, structBoundingBox);
setBlockState(world, fenceGate.withProperty(BlockFenceGate.FACING, EnumFacing.NORTH), 4, 1, 10, structBoundingBox);
setBlockState(world, fenceGate.withProperty(BlockHorizontal.FACING, EnumFacing.EAST), 8, 1, 8, structBoundingBox);
setBlockState(world, fenceGate.withProperty(BlockHorizontal.FACING, EnumFacing.EAST), 1, 1, 8, structBoundingBox);
setBlockState(world, fenceGate.withProperty(BlockHorizontal.FACING, EnumFacing.NORTH), 4, 1, 10, structBoundingBox);
// Flowers
plantFlowerGarden(world, structBoundingBox, 2, 1, 5, 7, 1, 9);
@@ -171,7 +170,7 @@ public class VillageApiaristHouse extends StructureVillagePieces.House1 {
IBlockState slabCeiling = slabs.withProperty(BlockSlab.HALF, BlockSlab.EnumBlockHalf.TOP);
fillWithBlocks(world, structBoundingBox, 1, 4, 1, 7, 4, 4, slabCeiling, slabCeiling, false);
IBlockState logBracing = logs.withProperty(BlockArbLog.LOG_AXIS, BlockLog.EnumAxis.X);
IBlockState logBracing = logs.withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.X);
fillWithBlocks(world, structBoundingBox, 0, 4, 1, 8, 4, 1, logBracing, logBracing, false);
fillWithBlocks(world, structBoundingBox, 0, 4, 4, 8, 4, 4, logBracing, logBracing, false);
@@ -219,7 +218,7 @@ public class VillageApiaristHouse extends StructureVillagePieces.House1 {
// Escritoire
if (random.nextInt(2) == 0) {
IBlockState escritoireBlock = PluginCore.blocks.escritoire.getDefaultState().withProperty(BlockCore.FACING, EnumFacing.EAST);
IBlockState escritoireBlock = PluginCore.blocks.escritoire.getDefaultState().withProperty(BlockBase.FACING, EnumFacing.EAST);
setBlockState(world, escritoireBlock, 1, 1, 3, structBoundingBox);
}
@@ -0,0 +1,78 @@
/*******************************************************************************
* 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.arboriculture;
import forestry.api.core.CamouflageManager;
import forestry.api.core.ICamouflageHandler;
import forestry.api.core.ICamouflageItemHandler;
import forestry.api.core.ICamouflagedTile;
import forestry.arboriculture.items.ItemBlockWoodDoor;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockModelShapes;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.apache.commons.lang3.tuple.Pair;
public class CamouflageHandlerArbDoor implements ICamouflageItemHandler {
@Override
public boolean canHandle(ItemStack stack, ICamouflageHandler camouflageHandler) {
if(camouflageHandler == null || stack == null || stack.getItem() == null || stack.stackSize <= 0){
return false;
}
if(stack.getItem() instanceof ItemBlockWoodDoor){
return true;
}
return false;
}
@Override
public String getType() {
return CamouflageManager.DOOR;
}
@Override
public float getLightTransmittance(ItemStack stack, ICamouflageHandler camouflageHandler) {
return 0F;
}
@SideOnly(Side.CLIENT)
@Override
public Pair<IBlockState, IBakedModel> getModel(ItemStack stack, ICamouflageHandler camouflageHandler, ICamouflagedTile camouflageTile) {
if(camouflageHandler == null || stack == null || stack.getItem() == null || stack.stackSize <= 0 || !(stack.getItem() instanceof ItemBlockWoodDoor)){
return null;
}
World world = camouflageHandler.getWorld();
BlockPos pos = camouflageTile.getCoordinates();
IBlockState blockState = world.getBlockState(pos);
IBlockState currentState = blockState.getActualState(world, pos);
ItemBlockWoodDoor itemDoor = (ItemBlockWoodDoor) stack.getItem();
IBlockState doorState = itemDoor.block.getDefaultState()
.withProperty(BlockDoor.FACING, currentState.getValue(BlockDoor.FACING))
.withProperty(BlockDoor.HINGE, currentState.getValue(BlockDoor.HINGE))
.withProperty(BlockDoor.OPEN, currentState.getValue(BlockDoor.OPEN))
.withProperty(BlockDoor.POWERED, currentState.getValue(BlockDoor.POWERED))
.withProperty(BlockDoor.HALF, currentState.getValue(BlockDoor.HALF));
BlockModelShapes modelShapes = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes();
return Pair.of(doorState, modelShapes.getModelForState(doorState));
}
}
@@ -11,8 +11,8 @@
package forestry.arboriculture;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Collection;
import forestry.api.arboriculture.IWoodType;
import forestry.api.arboriculture.WoodBlockKind;
@@ -16,6 +16,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;
import forestry.api.arboriculture.EnumForestryWoodType;
import forestry.api.arboriculture.EnumGermlingType;
@@ -27,6 +28,7 @@ import forestry.api.arboriculture.ITree;
import forestry.api.arboriculture.IWoodType;
import forestry.api.arboriculture.TreeManager;
import forestry.api.arboriculture.WoodBlockKind;
import forestry.api.core.CamouflageManager;
import forestry.api.core.ForestryAPI;
import forestry.api.genetics.AlleleManager;
import forestry.api.genetics.ILeafTranslator;
@@ -53,8 +55,10 @@ import forestry.arboriculture.items.ItemCharcoal;
import forestry.arboriculture.items.ItemGrafter;
import forestry.arboriculture.items.ItemRegistryArboriculture;
import forestry.arboriculture.models.TextureLeaves;
import forestry.arboriculture.models.WoodTextures;
import forestry.arboriculture.network.PacketRegistryArboriculture;
import forestry.arboriculture.proxy.ProxyArboriculture;
import forestry.arboriculture.proxy.ProxyArboricultureClient;
import forestry.arboriculture.tiles.TileFruitPod;
import forestry.arboriculture.tiles.TileLeaves;
import forestry.arboriculture.tiles.TilePile;
@@ -66,7 +70,9 @@ import forestry.core.fluids.Fluids;
import forestry.core.genetics.alleles.AllelePlantType;
import forestry.core.items.ItemFruit.EnumFruit;
import forestry.core.network.IPacketRegistry;
import forestry.core.proxy.Proxies;
import forestry.core.recipes.RecipeUtil;
import forestry.core.render.TextureManager;
import forestry.core.utils.IMCUtil;
import forestry.core.utils.ItemStackUtil;
import forestry.core.utils.OreDictUtil;
@@ -87,7 +93,9 @@ import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.client.event.ModelBakeEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.world.BlockEvent;
@@ -173,6 +181,8 @@ public class PluginArboriculture extends BlankForestryPlugin {
// Commands
PluginCore.rootCommand.addChildCommand(new CommandTree());
CamouflageManager.camouflageAccess.registerCamouflageItemHandler(new CamouflageHandlerArbDoor());
}
@Override
@@ -548,9 +558,33 @@ public class PluginArboriculture extends BlankForestryPlugin {
@SideOnly(Side.CLIENT)
public void registerSprites(TextureStitchEvent.Pre event) {
TextureLeaves.registerAllSprites();
WoodTextures.deserializeFile(Proxies.render.getSelectedTexturePack());
for (IAlleleFruit alleleFruit : AlleleFruit.getFruitAlleles()) {
alleleFruit.getProvider().registerSprites();
}
List<ResourceLocation> textures = new ArrayList<>();
for(IWoodType type : TreeManager.woodAccess.getRegisteredWoodTypes()){
textures.add(new ResourceLocation(type.getHeartTexture()));
textures.add(new ResourceLocation(type.getBarkTexture()));
textures.add(new ResourceLocation(type.getDoorLowerTexture()));
textures.add(new ResourceLocation(type.getDoorUpperTexture()));
textures.add(new ResourceLocation(type.getPlankTexture()));
for(WoodBlockKind kind : WoodBlockKind.values()){
for(Entry<String, String> loc : WoodTextures.getLocations(type, kind).entrySet()){
textures.add(new ResourceLocation(loc.getValue()));
}
}
}
for(ResourceLocation loc : textures){
TextureManager.getInstance();
TextureManager.registerSprite(loc);
}
}
@SubscribeEvent
@SideOnly(Side.CLIENT)
public void onModelBake(ModelBakeEvent event) {
((ProxyArboricultureClient)proxy).onModelBake(event);
}
@SubscribeEvent
@@ -11,6 +11,8 @@
package forestry.arboriculture;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.HashMap;
@@ -43,6 +45,7 @@ import forestry.core.utils.Log;
public class WoodAccess implements IWoodAccess {
private static final Map<WoodBlockKind, WoodMap> woodMaps = new EnumMap<>(WoodBlockKind.class);
private static final List<IWoodType> registeredWoodTypes = new ArrayList<>();
static {
for (WoodBlockKind woodBlockKind : WoodBlockKind.values()) {
@@ -195,6 +198,9 @@ public class WoodAccess implements IWoodAccess {
int meta = woodTyped.getMetaFromState(blockState);
IWoodType woodType = woodTyped.getWoodType(meta);
ItemStack itemStack = new ItemStack(woodTyped, 1, meta);
if(!(woodType instanceof EnumVanillaWoodType)){
PluginArboriculture.proxy.registerWoodModel(woodTyped, true);
}
register(woodType, woodBlockKind, fireproof, blockState, itemStack);
}
}
@@ -207,6 +213,9 @@ public class WoodAccess implements IWoodAccess {
IBlockState blockState = woodTyped.getDefaultState();
IWoodType woodType = woodTyped.getWoodType(0);
ItemStack itemStack = new ItemStack(woodTyped);
if(!(woodType instanceof EnumVanillaWoodType)){
PluginArboriculture.proxy.registerWoodModel(woodTyped, false);
}
register(woodType, woodBlockKind, fireproof, blockState, itemStack);
}
@@ -218,6 +227,9 @@ public class WoodAccess implements IWoodAccess {
throw new NullPointerException("Invalid itemStack: " + itemStack);
}
WoodMap woodMap = woodMaps.get(woodBlockKind);
if(!registeredWoodTypes.contains(woodType)){
registeredWoodTypes.add(woodType);
}
woodMap.getItem(fireproof).put(woodType, itemStack);
woodMap.getBlock(fireproof).put(woodType, blockState);
}
@@ -249,4 +261,9 @@ public class WoodAccess implements IWoodAccess {
}
return blockState;
}
@Override
public List<IWoodType> getRegisteredWoodTypes() {
return registeredWoodTypes;
}
}
@@ -4,7 +4,6 @@ import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.client.renderer.ItemMeshDefinition;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
@@ -14,10 +13,12 @@ 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.api.core.ForestryAPI;
import forestry.arboriculture.models.WoodModelLoader;
import forestry.core.config.Constants;
import forestry.core.utils.Translator;
@@ -50,6 +51,10 @@ public class WoodHelper {
return displayName;
}
public static ResourceLocation getDefaultResourceLocations(IWoodTyped typed) {
return new ResourceLocation(Constants.MOD_ID, typed.getBlockKind().toString());
}
public static ResourceLocation[] getResourceLocations(IWoodTyped typed) {
List<ResourceLocation> resourceLocations = new ArrayList<>();
@@ -65,7 +70,7 @@ public class WoodHelper {
}
@SideOnly(Side.CLIENT)
public static class WoodMeshDefinition implements ItemMeshDefinition {
public static class WoodMeshDefinition implements IWoodItemMeshDefinition {
@Nonnull
public IWoodTyped wood;
@@ -75,6 +80,9 @@ public class WoodHelper {
@Override
public ModelResourceLocation getModelLocation(ItemStack stack) {
if(!WoodModelLoader.INSTANCE.isRegistered){
return new ModelResourceLocation(getDefaultModelLocation(stack), "inventory");
}
int meta = stack.getMetadata();
IWoodType woodType = wood.getWoodType(meta);
WoodBlockKind blockKind = wood.getBlockKind();
@@ -86,6 +94,12 @@ public class WoodHelper {
throw new IllegalArgumentException("Unknown wood type: " + woodType);
}
}
@Override
public ResourceLocation getDefaultModelLocation(ItemStack stack) {
WoodBlockKind blockKind = wood.getBlockKind();
return new ResourceLocation("forestry:item/" + blockKind.toString());
}
}
}
@@ -18,7 +18,6 @@ import java.util.List;
import net.minecraft.block.BlockFenceGate;
import net.minecraft.block.BlockPlanks.EnumType;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.ModelBakery;
import net.minecraft.creativetab.CreativeTabs;
@@ -120,7 +119,7 @@ public class BlockForestryFenceGate<T extends Enum<T> & IWoodType> extends Block
@SideOnly(Side.CLIENT)
@Override
public void registerModel(Item item, IModelManager manager) {
ModelBakery.registerItemVariants(item, WoodHelper.getResourceLocations(this));
ModelBakery.registerItemVariants(item, WoodHelper.getDefaultResourceLocations(this));
manager.registerItemModel(item, new WoodMeshDefinition(this));
}
}
@@ -5,7 +5,6 @@ import java.util.Collection;
import java.util.Collections;
import net.minecraft.block.BlockStairs;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.ModelBakery;
import net.minecraft.item.Item;
@@ -43,7 +42,7 @@ public class BlockForestryStairs<T extends Enum<T> & IWoodType> extends BlockSta
@SideOnly(Side.CLIENT)
@Override
public void registerModel(Item item, IModelManager manager) {
ModelBakery.registerItemVariants(item, WoodHelper.getResourceLocations(this));
ModelBakery.registerItemVariants(item, WoodHelper.getDefaultResourceLocations(this));
manager.registerItemModel(item, new WoodHelper.WoodMeshDefinition(this));
}
@@ -15,19 +15,19 @@ 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.EnumForestryWoodType;
import forestry.api.arboriculture.EnumVanillaWoodType;
import forestry.api.arboriculture.IWoodStateMapper;
import forestry.api.arboriculture.IWoodType;
import forestry.arboriculture.IWoodTyped;
import forestry.arboriculture.blocks.property.PropertyWoodType;
import forestry.arboriculture.models.WoodModelLoader;
import forestry.core.config.Constants;
@SideOnly(Side.CLIENT)
public class WoodTypeStateMapper extends StateMapperBase {
public class WoodTypeStateMapper extends StateMapperBase implements IWoodStateMapper {
@Nonnull
private final IWoodTyped woodTyped;
@@ -54,6 +54,11 @@ public class WoodTypeStateMapper extends StateMapperBase {
this.propertiesToRemove.add(property);
return this;
}
@Override
public ModelResourceLocation getModelLocation(IBlockState state) {
return getModelResourceLocation(state);
}
@Override
protected ModelResourceLocation getModelResourceLocation(IBlockState state) {
@@ -73,11 +78,34 @@ public class WoodTypeStateMapper extends StateMapperBase {
int meta = block.getMetaFromState(state);
IWoodType woodType = woodTyped.getWoodType(meta);
if (woodType instanceof EnumForestryWoodType) {
return getForestryModelResourceLocation(woodType, properties);
if(WoodModelLoader.INSTANCE.isRegistered){
return getForestryModelResourceLocation(woodType, properties);
}else{
return getDefaultModelResourceLocation(state);
}
} else {
return getVanillaModelResourceLocation(block, woodType, properties);
}
}
@Override
public ModelResourceLocation getDefaultModelResourceLocation(IBlockState state) {
final Map<IProperty<?>, Comparable<?>> properties;
if (propertyWoodType != null) {
properties = Maps.newLinkedHashMap(state.getProperties());
properties.remove(propertyWoodType);
} else {
properties = Maps.newLinkedHashMap(state.getProperties());
}
for (IProperty property : propertiesToRemove) {
properties.remove(property);
}
String resourceLocation = "arboriculture/" + blockPath;
String propertyString = this.getPropertyString(properties);
return new ModelResourceLocation(Constants.MOD_ID + ':' + resourceLocation, propertyString);
}
private ModelResourceLocation getForestryModelResourceLocation(IWoodType woodType, Map<IProperty<?>, Comparable<?>> properties) {
String resourceLocation = "arboriculture/" + blockPath + '/' + woodType;
@@ -104,7 +104,7 @@ public abstract class BlockForestryFence<T extends Enum<T> & IWoodType> extends
@SideOnly(Side.CLIENT)
@Override
public void registerModel(Item item, IModelManager manager) {
ModelBakery.registerItemVariants(item, WoodHelper.getResourceLocations(this));
ModelBakery.registerItemVariants(item, WoodHelper.getDefaultResourceLocations(this));
manager.registerItemModel(item, new WoodHelper.WoodMeshDefinition(this));
}
@@ -5,7 +5,6 @@ import java.util.Collection;
import java.util.List;
import net.minecraft.block.BlockLog;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.ModelBakery;
@@ -182,7 +181,7 @@ public abstract class BlockForestryLog<T extends Enum<T> & IWoodType> extends Bl
@SideOnly(Side.CLIENT)
@Override
public final void registerModel(Item item, IModelManager manager) {
ModelBakery.registerItemVariants(item, WoodHelper.getResourceLocations(this));
ModelBakery.registerItemVariants(item, WoodHelper.getDefaultResourceLocations(this));
manager.registerItemModel(item, new WoodHelper.WoodMeshDefinition(this));
}
@@ -121,7 +121,7 @@ public abstract class BlockForestryPlanks<T extends Enum<T> & IWoodType> extends
@SideOnly(Side.CLIENT)
@Override
public void registerModel(Item item, IModelManager manager) {
ModelBakery.registerItemVariants(item, WoodHelper.getResourceLocations(this));
ModelBakery.registerItemVariants(item, WoodHelper.getDefaultResourceLocations(this));
manager.registerItemModel(item, new WoodHelper.WoodMeshDefinition(this));
}
@@ -133,7 +133,7 @@ public abstract class BlockForestrySlab<T extends Enum<T> & IWoodType> extends B
@SideOnly(Side.CLIENT)
@Override
public void registerModel(Item item, IModelManager manager) {
ModelBakery.registerItemVariants(item, WoodHelper.getResourceLocations(this));
ModelBakery.registerItemVariants(item, WoodHelper.getDefaultResourceLocations(this));
manager.registerItemModel(item, new WoodHelper.WoodMeshDefinition(this));
}
@@ -0,0 +1,23 @@
package forestry.arboriculture.compat;
import javax.annotation.Nonnull;
import forestry.arboriculture.PluginArboriculture;
import forestry.arboriculture.items.ItemRegistryArboriculture;
import forestry.core.utils.JeiUtil;
import mezz.jei.api.BlankModPlugin;
import mezz.jei.api.IModRegistry;
import mezz.jei.api.JEIPlugin;
@JEIPlugin
public class ArboricultureJeiPlugin extends BlankModPlugin {
@Override
public void register(@Nonnull IModRegistry registry) {
ItemRegistryArboriculture items = PluginArboriculture.items;
JeiUtil.addDescription(registry,
items.grafter,
items.grafterProven
);
}
}
@@ -11,7 +11,6 @@
package forestry.arboriculture.genetics;
import forestry.api.core.ForestryAPI;
import forestry.core.DefaultClimateProvider;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@@ -14,7 +14,7 @@ import forestry.arboriculture.genetics.TreeDefinition;
import forestry.arboriculture.tiles.TilePile;
import forestry.core.blocks.propertys.UnlistedBlockAccess;
import forestry.core.blocks.propertys.UnlistedBlockPos;
import forestry.core.models.BlankItemModel;
import forestry.core.models.BlankModel;
import forestry.core.models.DefaultTextureGetter;
import forestry.core.tiles.TileUtil;
import net.minecraft.block.state.IBlockState;
@@ -38,7 +38,7 @@ import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class ModelWoodPile extends BlankItemModel{
public class ModelWoodPile extends BlankModel{
private final Function<ResourceLocation, TextureAtlasSprite> textureGetter = new DefaultTextureGetter();
@SideOnly(Side.CLIENT)
@@ -0,0 +1,296 @@
package forestry.arboriculture.models;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.tuple.Pair;
import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import forestry.core.config.Constants;
import forestry.core.utils.Log;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ModelBlockDefinition;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.block.model.Variant;
import net.minecraft.client.renderer.block.model.VariantList;
import net.minecraft.client.renderer.block.model.WeightedBakedModel;
import net.minecraft.client.renderer.block.model.ModelBlockDefinition.MissingVariantException;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.resources.IResource;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.Attributes;
import net.minecraftforge.client.model.ICustomModelLoader;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.IRetexturableModel;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.model.ModelProcessingHelper;
import net.minecraftforge.client.model.MultiModel;
import net.minecraftforge.client.model.MultiModelState;
import net.minecraftforge.common.model.IModelState;
import net.minecraftforge.common.model.TRSRTransformation;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
public enum WoodModelLoader implements ICustomModelLoader{
INSTANCE;
public static Map<ResourceLocation, Exception> loadingExceptions = Maps.newHashMap();
private final Map<ResourceLocation, ModelBlockDefinition> blockDefinitions = Maps.newHashMap();
public static final List<String> validFiles = new ArrayList<>();
public boolean isRegistered = false;
static{
validFiles.add("door");
validFiles.add("double_slab");
validFiles.add("fence");
validFiles.add("fence_gate");
validFiles.add("log");
validFiles.add("planks");
validFiles.add("slab");
validFiles.add("stairs");
}
// NOOP, handled in loader
@Override
public void onResourceManagerReload(IResourceManager resourceManager) {}
@Override
public boolean accepts(ResourceLocation modelLocation){
if(!(modelLocation instanceof ModelResourceLocation) || !modelLocation.getResourceDomain().equals(Constants.MOD_ID) || !modelLocation.getResourcePath().contains("arboriculture")){
return false;
}
String path = modelLocation.getResourcePath();
for(String validFile : validFiles){
if(path.endsWith(validFile)){
return true;
}
}
return false;
}
@Override
public IModel loadModel(ResourceLocation modelLocation) throws Exception{
ModelResourceLocation variant = (ModelResourceLocation) modelLocation;
ModelBlockDefinition definition = getModelBlockDefinition(variant);
try{
VariantList variants = definition.getVariant(variant.getVariant());
return new WeightedRandomModel(variant, variants);
}catch(MissingVariantException e){
if(definition.hasMultipartData()){
Log.error("The forestry model loader can't load the model with the location: %s, because it dons't support multipart models.", modelLocation.toString());
}
throw e;
}
}
/* MODEL LOADER PRIVATE METHODS */
private ModelBlockDefinition getModelBlockDefinition(ResourceLocation location){
try{
ResourceLocation resourcelocation = this.getBlockstateLocation(location);
ModelBlockDefinition modelblockdefinition = this.blockDefinitions.get(resourcelocation);
if (modelblockdefinition == null){
modelblockdefinition = this.loadMultipartMBD(location, resourcelocation);
this.blockDefinitions.put(resourcelocation, modelblockdefinition);
}
return modelblockdefinition;
}
catch (Exception exception){
loadingExceptions.put(location, new Exception("Could not load model definition for variant " + location, exception));
}
return new ModelBlockDefinition(new ArrayList<ModelBlockDefinition>());
}
private ResourceLocation getBlockstateLocation(ResourceLocation location){
return new ResourceLocation(location.getResourceDomain(), "blockstates/" + location.getResourcePath() + ".json");
}
private ModelBlockDefinition loadMultipartMBD(ResourceLocation location, ResourceLocation fileIn){
List<ModelBlockDefinition> list = Lists.<ModelBlockDefinition>newArrayList();
try{
for (IResource iresource : Minecraft.getMinecraft().getResourceManager().getAllResources(fileIn)){
list.add(this.loadModelBlockDefinition(location, iresource));
}
}catch (IOException ioexception){
throw new RuntimeException("Encountered an exception when loading model definition of model " + fileIn, ioexception);
}
return new ModelBlockDefinition(list);
}
private ModelBlockDefinition loadModelBlockDefinition(ResourceLocation location, IResource iresource){
InputStream inputstream = null;
ModelBlockDefinition definition;
try{
inputstream = iresource.getInputStream();
definition = ModelBlockDefinition.parseFromReader(new InputStreamReader(inputstream, Charsets.UTF_8));
}catch (Exception exception){
throw new RuntimeException("Encountered an exception when loading model definition of \'" + location + "\' from: \'" + iresource.getResourceLocation() + "\' in resourcepack: \'" + iresource.getResourcePackName() + "\'", exception);
}finally{
IOUtils.closeQuietly(inputstream);
}
return definition;
}
private class WeightedRandomModel implements IRetexturableModel {
private final List<Variant> variants;
private final List<ResourceLocation> locations = new ArrayList<ResourceLocation>();
private final Set<ResourceLocation> textures = Sets.newHashSet();
private final List<IModel> models = new ArrayList<IModel>();
private final IModelState defaultState;
public WeightedRandomModel(List<ResourceLocation> locations, List<IModel> models, List<Variant> variants, IModelState defaultState){
this.locations.addAll(locations);
this.models.addAll(models);
this.variants = variants;
this.defaultState = defaultState;
for(IModel model : models){
textures.addAll(model.getTextures());
}
}
public WeightedRandomModel(ResourceLocation parent, VariantList variants) throws Exception{
this.variants = variants.getVariantList();
ImmutableList.Builder<Pair<IModel, IModelState>> builder = ImmutableList.builder();
for (Variant v : this.variants){
ResourceLocation loc = v.getModelLocation();
locations.add(loc);
/*
* Vanilla eats this, which makes it only show variants that have models.
* But that doesn't help debugging, so throw the exception
*/
IModel model;
if(loc.equals(new ModelResourceLocation("builtin/missing", "missing"))){
// explicit missing location, happens if blockstate has "model"=null
model = ModelLoaderRegistry.getMissingModel();
}else{
model = ModelLoaderRegistry.getModel(loc);
}
// FIXME: is this the place? messes up dependency and texture resolution
model = v.process(model);
for(ResourceLocation location : model.getDependencies()){
ModelLoaderRegistry.getModelOrMissing(location);
}
//FMLLog.getLogger().error("Exception resolving indirect dependencies for model" + loc, e);
textures.addAll(model.getTextures()); // Kick this, just in case.
models.add(model);
builder.add(Pair.of(model, v.getState()));
}
if (models.size() == 0){ //If all variants are missing, add one with the missing model and default rotation.
// FIXME: log this?
IModel missing = ModelLoaderRegistry.getMissingModel();
models.add(missing);
builder.add(Pair.<IModel, IModelState>of(missing, TRSRTransformation.identity()));
}
defaultState = new MultiModelState(builder.build());
}
@Override
public Collection<ResourceLocation> getDependencies(){
return ImmutableList.copyOf(locations);
}
@Override
public Collection<ResourceLocation> getTextures(){
return ImmutableSet.copyOf(textures);
}
@Override
public IBakedModel bake(IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter){
if(!Attributes.moreSpecific(format, Attributes.DEFAULT_BAKED_FORMAT)){
throw new IllegalArgumentException("can't bake vanilla weighted models to the format that doesn't fit into the default one: " + format);
}
if(variants.size() == 1){
IModel model = models.get(0);
return model.bake(MultiModelState.getPartState(state, model, 0), format, bakedTextureGetter);
}
WeightedBakedModel.Builder builder = new WeightedBakedModel.Builder();
for(int i = 0; i < variants.size(); i++){
IModel model = models.get(i);
builder.add(model.bake(MultiModelState.getPartState(state, model, i), format, bakedTextureGetter), variants.get(i).getWeight());
}
return builder.build();
}
@Override
public IModelState getDefaultState(){
return defaultState;
}
@Override
public IModel retexture(ImmutableMap<String, String> textures) {
List<IModel> models = new ArrayList<IModel>();
ImmutableList.Builder<Pair<IModel, IModelState>> builder = ImmutableList.builder();
for (Variant v : this.variants){
try{
ResourceLocation loc = v.getModelLocation();
locations.add(loc);
IModel model;
if(loc.equals(new ModelResourceLocation("builtin/missing", "missing"))){
model = ModelLoaderRegistry.getMissingModel();
}else{
model = ModelLoaderRegistry.getModel(loc);
}
model = v.process(model);
for(ResourceLocation location : model.getDependencies()){
ModelLoaderRegistry.getModelOrMissing(location);
}
if(model instanceof MultiModel){
IModel base = ObfuscationReflectionHelper.getPrivateValue(MultiModel.class, (MultiModel)model, 1);
Map<String, Pair<IModel, IModelState>> parts = ObfuscationReflectionHelper.getPrivateValue(MultiModel.class, (MultiModel)model, 3);
ImmutableMap.Builder<String, Pair<IModel, IModelState>> partBuilder = new ImmutableMap.Builder<>();
IModel retexturedModel = ModelProcessingHelper.retexture(base, textures);
for(Entry<String, Pair<IModel, IModelState>> part : parts.entrySet()){
partBuilder.put(part.getKey(), Pair.of(ModelProcessingHelper.retexture(part.getValue().getLeft(), textures), part.getValue().getRight()));
}
ObfuscationReflectionHelper.setPrivateValue(MultiModel.class, (MultiModel)model, retexturedModel, 1);
ObfuscationReflectionHelper.setPrivateValue(MultiModel.class, (MultiModel)model, partBuilder.build(), 3);
}
model = ModelProcessingHelper.retexture(model, textures);
models.add(model);
builder.add(Pair.of(model, v.getState()));
}catch(Exception e){}
}
if (models.size() == 0){
IModel missing = ModelLoaderRegistry.getMissingModel();
models.add(missing);
builder.add(Pair.<IModel, IModelState>of(missing, TRSRTransformation.identity()));
}
return new WeightedRandomModel(locations, models, variants, new MultiModelState(builder.build()));
}
}
}
@@ -0,0 +1,150 @@
package forestry.arboriculture.models;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.internal.Streams;
import com.google.gson.stream.JsonReader;
import forestry.api.arboriculture.IWoodType;
import forestry.api.arboriculture.WoodBlockKind;
import forestry.core.render.FontColour;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.IResourcePack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class WoodTextures {
public static final Gson GSON = new GsonBuilder().create();
protected static final Map<String, Texture> textures = new HashMap<>();
public static void deserializeFile(IResourceManager resourceManager){
try {
InputStream stream = resourceManager.getResource(new ResourceLocation("forestry:textures/woodTextures.json")).getInputStream();
if(stream != null){
JsonReader reader = null;
try {
reader = new JsonReader(new BufferedReader(new InputStreamReader(stream)));
JsonElement json = Streams.parse(reader);
if(json.isJsonObject()){
for(Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()){
JsonElement ele = entry.getValue();
if(ele.isJsonObject()){
textures.put(entry.getKey(), loadTexture(ele.getAsJsonObject()));
}else if(ele.isJsonArray()){
ImmutableMap.Builder<String, SimpleTexture> locations = new ImmutableMap.Builder<>();
for(JsonElement eleEntry : ele.getAsJsonArray()){
if(eleEntry.isJsonObject()){
JsonObject obj = eleEntry.getAsJsonObject();
if(!obj.has("kind") || !obj.get("kind").isJsonPrimitive() || !obj.get("kind").getAsJsonPrimitive().isString()){
continue;
}
String kind = obj.get("kind").getAsString();
locations.put(kind, loadTexture(obj));
}
}
textures.put(entry.getKey(), new KindTexture(locations.build()));
}
}
}
}finally{
if(reader != null){
reader.close();
}
}
}
} catch (IOException e) {
if(!(e instanceof FileNotFoundException)){
e.printStackTrace();
}
}
}
private static SimpleTexture loadTexture(JsonObject obj){
ImmutableMap.Builder<String, String> locations = new ImmutableMap.Builder<>();
for(Entry<String, JsonElement> eleEntry : obj.entrySet()){
JsonElement e = eleEntry.getValue();
if(e.isJsonPrimitive() && e.getAsJsonPrimitive().isString()){
locations.put(eleEntry.getKey(), e.getAsString());
}
}
return new SimpleTexture(locations.build());
}
public static ImmutableMap<String, String> getLocations(IWoodType woodType, WoodBlockKind blockKind){
if(woodType != null && blockKind != null && woodType.getName() != null){
String kindName = blockKind.toString();
Texture kindTex = textures.get(blockKind);
Texture tex = textures.get(woodType.getName().toLowerCase(Locale.ENGLISH));
Map<String, String> locations = new HashMap<>();
if(kindTex != null && kindTex instanceof SimpleTexture){
locations.putAll(((SimpleTexture)kindTex).locations);
}
if(tex != null){
if(tex instanceof SimpleTexture){
locations.putAll(((SimpleTexture) tex).locations);
}else{
SimpleTexture kind = ((KindTexture)tex).kindLocations.get(kindName);
locations.putAll(kind.locations);
}
}
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<>();
for(Entry<String, String> location : locations.entrySet()){
String texture = location.getValue();
if(texture.equals("plank")){
texture = woodType.getPlankTexture();
}else if(texture.equals("bark")){
texture = woodType.getBarkTexture();
}else if(texture.equals("heart")){
texture = woodType.getHeartTexture();
}else if(texture.equals("doorUp")){
texture = woodType.getDoorUpperTexture();
}else if(texture.equals("doorLow")){
texture = woodType.getDoorLowerTexture();
}else{
builder.put(location.getKey(), texture.replace("%woodType", woodType.getName().toLowerCase(Locale.ENGLISH)));
continue;
}
builder.put(location.getKey(), texture);
}
return builder.build();
}
return ImmutableMap.of();
}
private static class Texture{
}
private static class SimpleTexture extends Texture{
public final ImmutableMap<String, String> locations;
public SimpleTexture(ImmutableMap<String, String> locations) {
this.locations = locations;
}
}
private static class KindTexture extends Texture{
public final ImmutableMap<String, SimpleTexture> kindLocations;
public KindTexture(ImmutableMap<String, SimpleTexture> kindLocations) {
this.kindLocations = kindLocations;
}
}
}
@@ -10,6 +10,9 @@
******************************************************************************/
package forestry.arboriculture.proxy;
import forestry.arboriculture.IWoodTyped;
import net.minecraft.block.Block;
public class ProxyArboriculture {
public void initializeModels() {
@@ -26,5 +29,7 @@ public class ProxyArboriculture {
public int getFoliageColorPine() {
return 6396257;
}
public <T extends Block & IWoodTyped> void registerWoodModel(T woodTyped, boolean withVariants){
}
}
@@ -10,28 +10,64 @@
******************************************************************************/
package forestry.arboriculture.proxy;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ItemMeshDefinition;
import net.minecraft.client.renderer.ItemModelMesher;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.block.statemap.BlockStateMapper;
import net.minecraft.client.renderer.block.statemap.IStateMapper;
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.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.ImmutableMap;
import forestry.api.arboriculture.EnumPileType;
import forestry.api.arboriculture.IWoodItemMeshDefinition;
import forestry.api.arboriculture.IWoodStateMapper;
import forestry.api.arboriculture.IWoodType;
import forestry.api.arboriculture.WoodBlockKind;
import forestry.arboriculture.IWoodTyped;
import forestry.arboriculture.PluginArboriculture;
import forestry.arboriculture.blocks.BlockDecorativeLeaves;
import forestry.arboriculture.blocks.slab.BlockArbSlab;
import forestry.arboriculture.models.ModelDecorativeLeaves;
import forestry.arboriculture.models.ModelLeaves;
import forestry.arboriculture.models.ModelWoodPile;
import forestry.arboriculture.models.WoodModelLoader;
import forestry.arboriculture.models.WoodTextures;
import forestry.arboriculture.render.CharcoalPileRenderer;
import forestry.arboriculture.tiles.TilePile;
import forestry.core.models.BlockModelIndex;
import forestry.core.models.BlockModelEntry;
import forestry.core.models.SimpleRetexturedModel;
import forestry.core.models.WoodModelEntry;
import forestry.core.proxy.Proxies;
@SuppressWarnings("unused")
public class ProxyArboricultureClient extends ProxyArboriculture {
private static Set<WoodModelEntry> woodModelEntrys = new HashSet<>();
@Override
public void initializeModels() {
{
ModelResourceLocation blockModelLocation = new ModelResourceLocation("forestry:leaves");
ModelResourceLocation itemModelLocation = new ModelResourceLocation("forestry:leaves", "inventory");
BlockModelIndex blockModelIndex = new BlockModelIndex(blockModelLocation, itemModelLocation, new ModelLeaves(), PluginArboriculture.blocks.leaves);
BlockModelEntry blockModelIndex = new BlockModelEntry(blockModelLocation, itemModelLocation, new ModelLeaves(), PluginArboriculture.blocks.leaves);
Proxies.render.registerBlockModel(blockModelIndex);
}
@@ -39,17 +75,89 @@ public class ProxyArboricultureClient extends ProxyArboriculture {
String resourceName = "forestry:leaves.decorative." + leaves.getBlockNumber();
ModelResourceLocation blockModelLocation = new ModelResourceLocation(resourceName);
ModelResourceLocation itemModeLocation = new ModelResourceLocation(resourceName, "inventory");
BlockModelIndex blockModelIndex = new BlockModelIndex(blockModelLocation, itemModeLocation, new ModelDecorativeLeaves(), leaves);
BlockModelEntry blockModelIndex = new BlockModelEntry(blockModelLocation, itemModeLocation, new ModelDecorativeLeaves(), leaves);
Proxies.render.registerBlockModel(blockModelIndex);
}
{
ModelResourceLocation blockModelLocation = new ModelResourceLocation("forestry:pile", "type=wood");
ModelResourceLocation itemModelLocation = new ModelResourceLocation("forestry:woodPile", "inventory");
BlockModelIndex blockModelIndex = new BlockModelIndex(blockModelLocation, itemModelLocation, new ModelWoodPile(), PluginArboriculture.blocks.piles.get(EnumPileType.WOOD));
BlockModelEntry blockModelIndex = new BlockModelEntry(blockModelLocation, itemModelLocation, new ModelWoodPile(), PluginArboriculture.blocks.piles.get(EnumPileType.WOOD));
Proxies.render.registerBlockModel(blockModelIndex);
}
ClientRegistry.bindTileEntitySpecialRenderer(TilePile.class, new CharcoalPileRenderer());
ModelLoaderRegistry.registerLoader(WoodModelLoader.INSTANCE);
for(BlockArbSlab slab : PluginArboriculture.blocks.slabsDouble){
registerWoodModel(slab, true);
}
for(BlockArbSlab slab : PluginArboriculture.blocks.slabsDoubleFireproof){
registerWoodModel(slab, true);
}
}
@SubscribeEvent
public <T extends Block & IWoodTyped> void onModelBake(ModelBakeEvent event){
WoodModelLoader.INSTANCE.isRegistered = true;
IRegistry<ModelResourceLocation, IBakedModel> registry = event.getModelRegistry();
Minecraft minecraft = Proxies.common.getClientInstance();
Map<ResourceLocation, Exception> loadingExceptions = ObfuscationReflectionHelper.getPrivateValue(ModelLoader.class, event.getModelLoader(), 2);
if(minecraft.getBlockRendererDispatcher() != null){
BlockStateMapper stateMapper = minecraft.getBlockRendererDispatcher().getBlockModelShapes().getBlockStateMapper();
Map<Item, ItemMeshDefinition> definitions = ObfuscationReflectionHelper.getPrivateValue(ItemModelMesher.class, minecraft.getRenderItem().getItemModelMesher(), 2);
Map<Block, IStateMapper> blockStateMap = ObfuscationReflectionHelper.getPrivateValue(BlockStateMapper.class, stateMapper, 0);
for(WoodModelEntry<T> entry : woodModelEntrys){
T woodTyped = entry.woodTyped;
WoodBlockKind woodKind = woodTyped.getBlockKind();
IStateMapper mapper = blockStateMap.get(woodTyped);
if(mapper instanceof IWoodStateMapper){
IWoodStateMapper woodMapper = (IWoodStateMapper) mapper;
try{
for(IBlockState state : woodTyped.getBlockState().getValidStates()) {
IWoodType woodType;
ItemStack itemStack;
if(entry.withVariants){
int meta = woodTyped.getMetaFromState(state);
woodType = woodTyped.getWoodType(meta);
itemStack = new ItemStack(woodTyped, 1, meta);
}else{
woodType = woodTyped.getWoodType(0);
itemStack = new ItemStack(woodTyped);
}
ImmutableMap<String, String> customTextures = WoodTextures.getLocations(woodType, woodKind);
if(woodKind.retextureItem){
ItemMeshDefinition definition = definitions.get(itemStack.getItem());
if(definition instanceof IWoodItemMeshDefinition){
IWoodItemMeshDefinition woodDefinition = (IWoodItemMeshDefinition) definition;
IModel basicItemModel = ModelLoaderRegistry.getModel(woodDefinition.getDefaultModelLocation(itemStack));
ModelResourceLocation basicItemLocation = definition.getModelLocation(itemStack);
registry.putObject(basicItemLocation, new SimpleRetexturedModel(woodKind.retextureModel(basicItemModel, woodType, customTextures)));
}
}
IModel basicModel = ModelLoaderRegistry.getModel(woodMapper.getDefaultModelResourceLocation(state));
ModelResourceLocation basicLocation = woodMapper.getModelLocation(state);
if(loadingExceptions.containsKey(basicLocation)){
loadingExceptions.remove(basicLocation);
}
registry.putObject(basicLocation, new SimpleRetexturedModel(woodKind.retextureModel(basicModel, woodType, customTextures)));
}
}catch(Exception e){
e.printStackTrace();
}
}
}
}
loadingExceptions.putAll(WoodModelLoader.loadingExceptions);
}
@Override
public <T extends Block & IWoodTyped> void registerWoodModel(T woodTyped, boolean withVariants){
woodModelEntrys.add(new WoodModelEntry(woodTyped, withVariants));
}
@Override
@@ -10,12 +10,8 @@
******************************************************************************/
package forestry.arboriculture.worldgen;
import javax.annotation.Nonnull;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.Set;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@@ -10,12 +10,8 @@
******************************************************************************/
package forestry.arboriculture.worldgen;
import javax.annotation.Nonnull;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.Set;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@@ -10,12 +10,8 @@
******************************************************************************/
package forestry.arboriculture.worldgen;
import javax.annotation.Nonnull;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.Set;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@@ -10,12 +10,8 @@
******************************************************************************/
package forestry.arboriculture.worldgen;
import javax.annotation.Nonnull;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.Set;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@@ -10,12 +10,8 @@
******************************************************************************/
package forestry.arboriculture.worldgen;
import javax.annotation.Nonnull;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.Set;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@@ -0,0 +1,101 @@
/*******************************************************************************
* 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.core;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.common.Loader;
import forestry.api.core.ICamouflageAccess;
import forestry.api.core.ICamouflageHandler;
import forestry.api.core.ICamouflageItemHandler;
import forestry.core.utils.Log;
public class CamouflageAccess implements ICamouflageAccess {
private static final Map<String, List<ICamouflageItemHandler>> camouflageItemHandlers = new HashMap<>();
private static final Map<String, List<ItemStack>> camouflageItemBlacklist = new HashMap<>();
@Override
public void registerCamouflageItemHandler(@Nonnull ICamouflageItemHandler itemHandler) {
if(itemHandler == null){
Log.error("Fail to register a camouflage item handler, because the handler is null. The handler is form the mod with the ID: " + Loader.instance().activeModContainer().getModId() + ".");
return;
}
String type = itemHandler.getType();
if(!camouflageItemHandlers.containsKey(type)){
camouflageItemHandlers.put(type, new ArrayList<>());
}
if(!camouflageItemHandlers.containsValue(itemHandler)){
camouflageItemHandlers.get(type).add(itemHandler);
}else{
Log.error("Fail to register a camouflage item handler, because the handler is already registered. The handler is form the mod with the ID: " + Loader.instance().activeModContainer().getModId() + ".");
}
}
@Override
public List<ICamouflageItemHandler> getCamouflageItemHandler(String type) {
if(!camouflageItemHandlers.containsKey(type)){
return null;
}
return camouflageItemHandlers.get(type);
}
@Override
public void addItemToBlackList(String type, ItemStack camouflageBlock) {
if (camouflageBlock == null || camouflageBlock.getItem() == null) {
Log.error("Fail to add camouflage block item to the black list, because it is null");
return;
}
Block block = Block.getBlockFromItem(camouflageBlock.getItem());
if (block == null) {
Log.error("Fail to add camouflage block item to the black list: because it has no block.");
return;
}
for (ItemStack camouflageBlacklisted : camouflageItemBlacklist.get(type)) {
if (camouflageBlacklisted.getItem() == camouflageBlock.getItem() && camouflageBlacklisted.getItemDamage() == camouflageBlock.getItemDamage() && ItemStack.areItemStackTagsEqual(camouflageBlock, camouflageBlacklisted)) {
Log.error("Fail to add camouflage block item to the black list, because it is already registered: " + camouflageBlock + ".");
return;
}
}
camouflageItemBlacklist.get(type).add(camouflageBlock);
}
@Override
public boolean isItemBlackListed(String type, ItemStack camouflageBlock) {
if (camouflageBlock == null || camouflageBlock.getItem() == null || Block.getBlockFromItem(camouflageBlock.getItem()) == null || !camouflageItemBlacklist.containsKey(type)) {
return false;
}
for (ItemStack camouflageBlacklisted : camouflageItemBlacklist.get(type)) {
if (camouflageBlacklisted.getItem() == camouflageBlock.getItem() && camouflageBlacklisted.getItemDamage() == camouflageBlock.getItemDamage() && ItemStack.areItemStackTagsEqual(camouflageBlock, camouflageBlacklisted)) {
return true;
}
}
return false;
}
public static ICamouflageItemHandler getHandlerFromItem(@Nonnull ItemStack camouflageItem, ICamouflageHandler camouflageHandler){
for(List<ICamouflageItemHandler> handlers : camouflageItemHandlers.values()){
for(ICamouflageItemHandler handler : handlers){
if(handler.canHandle(camouflageItem, camouflageHandler)){
return handler;
}
}
}
return null;
}
}
@@ -0,0 +1,64 @@
/*******************************************************************************
* 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.core;
import org.apache.commons.lang3.tuple.Pair;
import forestry.api.core.CamouflageManager;
import forestry.api.core.ICamouflageHandler;
import forestry.api.core.ICamouflageItemHandler;
import forestry.api.core.ICamouflagedTile;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockModelShapes;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class CamouflageHandlerDefault implements ICamouflageItemHandler {
@Override
public boolean canHandle(ItemStack stack, ICamouflageHandler camouflageHandler) {
if(camouflageHandler == null || stack == null || stack.getItem() == null || stack.stackSize <= 0 || Block.getBlockFromItem(stack.getItem()) == null){
return false;
}
Block block = Block.getBlockFromItem(stack.getItem());
IBlockState stateFromMeta = block.getStateFromMeta(stack.getItemDamage());
return stateFromMeta.isOpaqueCube() && !block.hasTileEntity(stateFromMeta) && block.isNormalCube(stateFromMeta, camouflageHandler.getWorld(), camouflageHandler.getCoordinates());
}
@Override
public String getType() {
return CamouflageManager.DEFAULT;
}
@Override
public float getLightTransmittance(ItemStack stack, ICamouflageHandler camouflageHandler) {
return 0F;
}
@SideOnly(Side.CLIENT)
@Override
public Pair<IBlockState, IBakedModel> getModel(ItemStack stack, ICamouflageHandler camouflageHandler, ICamouflagedTile camouflageTile) {
if(camouflageHandler == null || stack == null || stack.getItem() == null || stack.stackSize <= 0 || Block.getBlockFromItem(stack.getItem()) == null){
return null;
}
BlockModelShapes modelShapes = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes();
Block block = Block.getBlockFromItem(stack.getItem());
IBlockState state = block.getStateFromMeta(stack.getItemDamage());
return Pair.of(state, modelShapes.getModelForState(state));
}
}
@@ -0,0 +1,82 @@
/*******************************************************************************
* 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.core;
import org.apache.commons.lang3.tuple.Pair;
import forestry.api.core.CamouflageManager;
import forestry.api.core.ICamouflageHandler;
import forestry.api.core.ICamouflageItemHandler;
import forestry.api.core.ICamouflagedTile;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockModelShapes;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class CamouflageHandlerDoor implements ICamouflageItemHandler {
@Override
public boolean canHandle(ItemStack stack, ICamouflageHandler camouflageHandler) {
if(camouflageHandler == null || stack == null || stack.getItem() == null || stack.stackSize <= 0){
return false;
}
if(stack.getItem() instanceof ItemDoor){
return true;
}
return false;
}
@Override
public String getType() {
return CamouflageManager.DOOR;
}
@Override
public float getLightTransmittance(ItemStack stack, ICamouflageHandler camouflageHandler) {
return 0.25F;
}
@SideOnly(Side.CLIENT)
@Override
public Pair<IBlockState, IBakedModel> getModel(ItemStack stack, ICamouflageHandler camouflageHandler, ICamouflagedTile camouflageTile) {
if(camouflageHandler == null || stack == null || stack.getItem() == null || stack.stackSize <= 0 || !(stack.getItem() instanceof ItemDoor)){
return null;
}
World world = camouflageHandler.getWorld();
BlockPos pos = camouflageTile.getCoordinates();
IBlockState blockState = world.getBlockState(pos);
IBlockState currentState = blockState.getActualState(world, pos);
ItemDoor itemDoor = (ItemDoor) stack.getItem();
Block doorBlock = ObfuscationReflectionHelper.getPrivateValue(ItemDoor.class, itemDoor, 0);
IBlockState doorState = doorBlock.getDefaultState()
.withProperty(BlockDoor.FACING, currentState.getValue(BlockDoor.FACING))
.withProperty(BlockDoor.HINGE, currentState.getValue(BlockDoor.HINGE))
.withProperty(BlockDoor.OPEN, currentState.getValue(BlockDoor.OPEN))
.withProperty(BlockDoor.POWERED, currentState.getValue(BlockDoor.POWERED))
.withProperty(BlockDoor.HALF, currentState.getValue(BlockDoor.HALF));
BlockModelShapes modelShapes = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes();
return Pair.of(doorState, modelShapes.getModelForState(doorState));
}
}
@@ -0,0 +1,64 @@
/*******************************************************************************
* 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.core;
import org.apache.commons.lang3.tuple.Pair;
import forestry.api.core.CamouflageManager;
import forestry.api.core.ICamouflageHandler;
import forestry.api.core.ICamouflageItemHandler;
import forestry.api.core.ICamouflagedTile;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockModelShapes;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class CamouflageHandlerGlass implements ICamouflageItemHandler {
@Override
public boolean canHandle(ItemStack stack, ICamouflageHandler camouflageHandler) {
if(camouflageHandler == null || stack == null || stack.getItem() == null || stack.stackSize <= 0 || Block.getBlockFromItem(stack.getItem()) == null){
return false;
}
Block block = Block.getBlockFromItem(stack.getItem());
IBlockState stateFromMeta = block.getStateFromMeta(stack.getItemDamage());
return !stateFromMeta.isOpaqueCube() && !block.hasTileEntity(stateFromMeta);
}
@Override
public String getType() {
return CamouflageManager.GLASS;
}
@Override
public float getLightTransmittance(ItemStack stack, ICamouflageHandler camouflageHandler) {
return 0.25F;
}
@SideOnly(Side.CLIENT)
@Override
public Pair<IBlockState, IBakedModel> getModel(ItemStack stack, ICamouflageHandler camouflageHandler, ICamouflagedTile camouflageTile) {
if(camouflageHandler == null || stack == null || stack.getItem() == null || stack.stackSize <= 0 || Block.getBlockFromItem(stack.getItem()) == null){
return null;
}
BlockModelShapes modelShapes = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes();
Block block = Block.getBlockFromItem(stack.getItem());
IBlockState state = block.getStateFromMeta(stack.getItemDamage());
return Pair.of(state, modelShapes.getModelForState(state));
}
}
@@ -1,50 +0,0 @@
/*******************************************************************************
* 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.core;
import forestry.api.core.IClimateProvider;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import forestry.api.core.IClimateManager;
import forestry.api.greenhouse.GreenhouseManager;
import forestry.api.greenhouse.IGreenhouseState;
public class ClimateManager implements IClimateManager{
@Override
public float getTemperature(World world, BlockPos pos) {
IGreenhouseState state = GreenhouseManager.greenhouseHelper.getGreenhouseState(world, pos);
Biome biome = world.getBiome(pos);
if(state != null){
return state.getExactTemperature();
}
return biome.getTemperature();
}
@Override
public float getHumidity(World world, BlockPos pos) {
IGreenhouseState state = GreenhouseManager.greenhouseHelper.getGreenhouseState(world, pos);
Biome biome = world.getBiome(pos);
if(state != null){
return state.getExactHumidity();
}
return biome.getRainfall();
}
@Override
public IClimateProvider getDefaultClimate(World world, BlockPos pos) {
return new DefaultClimateProvider(world, pos);
}
}
@@ -37,6 +37,7 @@ import net.minecraftforge.oredict.OreDictionary;
import net.minecraftforge.oredict.RecipeSorter;
import forestry.api.circuits.ChipsetManager;
import forestry.api.core.CamouflageManager;
import forestry.api.core.ForestryAPI;
import forestry.api.genetics.AlleleManager;
import forestry.api.multiblock.MultiblockManager;
@@ -48,6 +49,7 @@ import forestry.core.blocks.BlockRegistryCore;
import forestry.core.blocks.EnumResourceType;
import forestry.core.circuits.CircuitRegistry;
import forestry.core.circuits.SolderManager;
import forestry.core.climate.ClimateManager;
import forestry.core.commands.CommandPlugins;
import forestry.core.commands.RootCommand;
import forestry.core.config.Config;
@@ -108,6 +110,8 @@ public class PluginCore extends BlankForestryPlugin {
MultiblockManager.logicFactory = new MultiblockLogicFactory();
ForestryAPI.climateManager = new ClimateManager();
CamouflageManager.camouflageAccess = new CamouflageAccess();
}
@Override
@@ -125,6 +129,10 @@ public class PluginCore extends BlankForestryPlugin {
MinecraftForge.EVENT_BUS.register(this);
rootCommand.addChildCommand(new CommandPlugins());
CamouflageManager.camouflageAccess.registerCamouflageItemHandler(new CamouflageHandlerDefault());
CamouflageManager.camouflageAccess.registerCamouflageItemHandler(new CamouflageHandlerGlass());
CamouflageManager.camouflageAccess.registerCamouflageItemHandler(new CamouflageHandlerDoor());
}
@Override
@@ -10,8 +10,13 @@
******************************************************************************/
package forestry.core.blocks;
import com.mojang.authlib.GameProfile;
import forestry.api.core.IItemModelRegister;
import forestry.core.CreativeTabForestry;
import forestry.core.owner.IOwnedTile;
import forestry.core.owner.IOwnerHandler;
import forestry.core.tiles.TileForestry;
import forestry.core.utils.Log;
import net.minecraft.block.Block;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material;
@@ -21,15 +26,9 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import com.mojang.authlib.GameProfile;
import forestry.api.core.IItemModelRegister;
import forestry.core.CreativeTabForestry;
import forestry.core.tiles.TileForestry;
import forestry.core.utils.Log;
public abstract class BlockForestry extends Block implements IItemModelRegister, ITileEntityProvider {
protected BlockForestry(Material material) {
@@ -57,16 +56,17 @@ public abstract class BlockForestry extends Block implements IItemModelRegister,
}
@Override
public void neighborChanged(IBlockState state, World worldIn, BlockPos pos, Block blockIn) {
public void onNeighborChange(IBlockAccess world, BlockPos pos, BlockPos neighbor) {
super.onNeighborChange(world, pos, neighbor);
try {
TileEntity tile = worldIn.getTileEntity(pos);
TileEntity tile = world.getTileEntity(pos);
if (tile instanceof TileForestry) {
((TileForestry) tile).onNeighborBlockChange(state.getBlock());
((TileForestry) tile).onNeighborTileChange(world, pos, neighbor);
}
} catch (StackOverflowError error) {
Log.error("Stack Overflow Error in BlockMachine.onNeighborBlockChange()", error);
Log.error("Stack Overflow Error in BlockForestry.onNeighborChange()", error);
throw error;
}
}
}
@@ -13,15 +13,6 @@ package forestry.core.circuits;
import java.util.List;
import java.util.Locale;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import forestry.api.circuits.ChipsetManager;
import forestry.api.circuits.ICircuit;
import forestry.api.circuits.ICircuitBoard;
@@ -30,6 +21,13 @@ import forestry.api.core.IModelManager;
import forestry.core.PluginCore;
import forestry.core.items.IColoredItem;
import forestry.core.items.ItemForestry;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class ItemCircuitBoard extends ItemForestry implements IColoredItem {
@@ -80,6 +78,7 @@ public class ItemCircuitBoard extends ItemForestry implements IColoredItem {
@Override
public void addInformation(ItemStack itemstack, EntityPlayer player, List<String> list, boolean flag) {
super.addInformation(itemstack, player, list, flag);
ICircuitBoard circuitboard = ChipsetManager.circuitRegistry.getCircuitBoard(itemstack);
if (circuitboard != null) {
circuitboard.addTooltip(list);
@@ -0,0 +1,56 @@
package forestry.core.climate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import forestry.api.core.ForestryAPI;
import forestry.api.core.climate.IClimateManager;
import forestry.api.core.climate.IClimateRegion;
import forestry.api.core.climate.IClimateSource;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
public class ClimateEventHandler {
Map<Integer, Integer> serverTicks;
public ClimateEventHandler() {
serverTicks = new HashMap<>();
}
@SubscribeEvent
public void onWorldTick(TickEvent.WorldTickEvent event) {
Integer dim = Integer.valueOf(event.world.provider.getDimension());
if (event.phase == TickEvent.Phase.END) {
if(!serverTicks.containsKey(dim)){
serverTicks.put(dim, 1);
}
int ticks = serverTicks.get(dim);
Map<Integer, List<IClimateRegion>> regions = ForestryAPI.climateManager.getRegions();
if(regions != null && regions.containsKey(dim)){
for(IClimateRegion region : regions.get(dim)){
if(ticks % region.getTicksPerUpdate() == 0){
region.updateClimate();
}
}
}
Map<Integer, Map<BlockPos, IClimateSource>> sources = ForestryAPI.climateManager.getSources();
if(sources != null && sources.containsKey(dim)){
for(IClimateSource source : sources.get(dim).values()){
IClimateRegion region = ForestryAPI.climateManager.getRegionForPos(event.world, source.getPos());
if(region != null){
if(ticks % source.getTicksForChange(region) == 0){
source.changeClimate(ticks, region);
}
}
}
}
serverTicks.put(dim, ticks+1);
}
}
}
@@ -0,0 +1,163 @@
/*******************************************************************************
* 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.core.climate;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import forestry.api.core.IClimateProvider;
import forestry.api.core.climate.IClimateManager;
import forestry.api.core.climate.IClimatePosition;
import forestry.api.core.climate.IClimateRegion;
import forestry.api.core.climate.IClimateSource;
import forestry.core.DefaultClimateProvider;
public class ClimateManager implements IClimateManager{
protected Map<Integer, List<IClimateRegion>> regions;
protected Map<Integer, Map<BlockPos, IClimateSource>> sources;
private final Object regionsMutex;
public ClimateManager() {
regions = new HashMap<>();
sources = new HashMap<>();
regionsMutex = new Object();
}
@Override
public void addRegion(IClimateRegion region) {
if(region == null){
return;
}
synchronized (regionsMutex) {
Integer dimensionID = Integer.valueOf(region.getWorld().provider.getDimension());
if(!regions.containsKey(dimensionID)){
this.regions.put(dimensionID, new ArrayList<>());
}
List<IClimateRegion> regions = this.regions.get(dimensionID);
if(!regions.contains(region)){
for(BlockPos pos : region.getPositions().keySet()){
if(getRegionForPos(region.getWorld(), pos) != null){
return;
}
}
regions.add(region);
}
}
}
@Override
public void removeRegion(IClimateRegion region) {
if(region == null){
return;
}
synchronized (regionsMutex) {
Integer dimensionID = Integer.valueOf(region.getWorld().provider.getDimension());
if(!regions.containsKey(dimensionID)){
this.regions.put(dimensionID, new ArrayList<>());
}
List<IClimateRegion> regions = this.regions.get(dimensionID);
if(regions.contains(region)){
regions.remove(region);
}
}
}
@Override
public void removeSource(IClimateSource source) {
Integer dimensionID = Integer.valueOf(source.getWorld().provider.getDimension());
if(!sources.containsKey(dimensionID)){
sources.put(dimensionID, new HashMap<>());
}
if(sources.get(dimensionID).keySet().contains(source.getPos())){
sources.get(dimensionID).remove(source.getPos(), source);
}
}
@Override
public void addSource(IClimateSource source) {
Integer dimensionID = Integer.valueOf(source.getWorld().provider.getDimension());
if(!sources.containsKey(dimensionID)){
sources.put(dimensionID, new HashMap<>());
}
if(sources.get(dimensionID).get(source.getPos()) == null){
sources.get(dimensionID).put(source.getPos(), source);
}
}
@Override
public float getTemperature(World world, BlockPos pos) {
Biome biome = world.getBiome(pos);
IClimateRegion region = getRegionForPos(world, pos);
if(region!= null){
IClimatePosition position = region.getPositions().get(pos);
if(position != null){
return position.getTemperature();
}
}
return biome.getTemperature();
}
@Override
public float getHumidity(World world, BlockPos pos) {
Biome biome = world.getBiome(pos);
IClimateRegion region = getRegionForPos(world, pos);
if(region!= null){
IClimatePosition position = region.getPositions().get(pos);
if(position != null){
return position.getHumidity();
}
}
return biome.getRainfall();
}
@Override
public Map<Integer, List<IClimateRegion>> getRegions() {
return regions;
}
@Override
public IClimateRegion getRegionForPos(World world, BlockPos pos){
Integer dimensionID = Integer.valueOf(world.provider.getDimension());
if(!regions.containsKey(dimensionID)){
this.regions.put(dimensionID, new ArrayList<>());
}
List<IClimateRegion> regions = this.regions.get(dimensionID);
for(IClimateRegion region : regions){
if(region.getPositions().keySet().contains(pos)){
return region;
}else if(region.getOtherPositions().contains(pos)){
return region;
}
}
return null;
}
@Override
public Map<Integer, Map<BlockPos, IClimateSource>> getSources() {
return sources;
}
@Override
public IClimateProvider getDefaultClimate(World world, BlockPos pos) {
return new DefaultClimateProvider(world, pos);
}
}
@@ -0,0 +1,100 @@
/*******************************************************************************
* 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.core.climate;
import javax.annotation.Nonnull;
import forestry.api.core.climate.IClimateRegion;
import forestry.api.core.climate.IClimatePosition;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.biome.Biome;
public class ClimatePosition implements IClimatePosition {
@Nonnull
protected final IClimateRegion climateRegion;
@Nonnull
protected final BlockPos pos;
protected float temperature;
protected float humidity;
public ClimatePosition(IClimateRegion climateRegion, BlockPos pos) {
Biome biome = climateRegion.getWorld().getBiome(pos);
this.climateRegion = climateRegion;
this.pos = pos;
this.temperature = biome.getTemperature();
this.humidity = biome.getRainfall();
}
public ClimatePosition(@Nonnull IClimateRegion climateRegion, @Nonnull BlockPos pos, float temperature, float humidity) {
this.climateRegion = climateRegion;
this.pos = pos;
this.temperature = temperature;
this.humidity = humidity;
}
@Nonnull
@Override
public IClimateRegion getClimateRegion() {
return climateRegion;
}
@Nonnull
@Override
public BlockPos getPos() {
return pos;
}
@Override
public void setTemperature(float temperature) {
this.temperature = temperature;
}
@Override
public float getTemperature() {
return temperature;
}
@Override
public void addTemperature(float temperature) {
setTemperature(getTemperature() + temperature);
}
@Override
public void addHumidity(float humidity) {
setHumidity(getHumidity() + humidity);
}
@Override
public void setHumidity(float humidity) {
this.humidity = humidity;
}
@Override
public float getHumidity() {
return humidity;
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
temperature = nbt.getFloat("Temperature");
humidity = nbt.getFloat("Humidity");
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
nbt.setFloat("Temperature", temperature);
nbt.setFloat("Humidity", humidity);
return nbt;
}
}
@@ -0,0 +1,216 @@
package forestry.core.climate;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import forestry.api.core.climate.IClimatePosition;
import forestry.api.core.climate.IClimateRegion;
import forestry.api.multiblock.IGreenhouseController;
import forestry.core.network.DataInputStreamForestry;
import forestry.core.network.DataOutputStreamForestry;
import forestry.core.network.IStreamable;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
public class ClimateRoom implements IClimateRegion, IStreamable {
protected World world;
protected IGreenhouseController controller;
protected Map<BlockPos, IClimatePosition> positions;
protected List<BlockPos> wallPositions;
public ClimateRoom(ClimateRoom oldRoom, Map<BlockPos, IClimatePosition> innerPositions, List<BlockPos> wallPositions) {
this.world = oldRoom.getWorld();
this.controller = oldRoom.controller;
Map<BlockPos, IClimatePosition> newPositions = new HashMap<>();
for(Entry<BlockPos, IClimatePosition> positionEntry : innerPositions.entrySet()){
IClimatePosition position = oldRoom.getPositions().get(positionEntry.getKey());
if(position == null){
newPositions.put(positionEntry.getKey(), positionEntry.getValue());
}else{
newPositions.put(positionEntry.getKey(), position);
}
}
this.positions = newPositions;
this.wallPositions = wallPositions;
}
public ClimateRoom(IGreenhouseController controller, Map<BlockPos, IClimatePosition> innerPositions, List<BlockPos> wallPositions) {
this.world = controller.getWorldObj();
this.controller = controller;
this.positions = innerPositions;
this.wallPositions = wallPositions;
}
public ClimateRoom(IGreenhouseController controller, NBTTagCompound nbtTag) {
this.world = controller.getWorldObj();
this.controller = controller;
this.positions = new HashMap<>();
readFromNBT(nbtTag);
}
@Override
public void updateClimate() {
for(Entry<BlockPos, IClimatePosition> position : positions.entrySet()){
BlockPos pos = position.getKey();
if(world.isBlockLoaded(pos)){
updateSides(pos);
if(!controller.isAssembled()){
Biome biome = world.getBiome(pos);
float biomeTemperature = biome.getTemperature();
float biomeHumidity = biome.getRainfall();
IClimatePosition climatedInfo = positions.get(pos);
if(climatedInfo.getTemperature() != biomeTemperature){
if(climatedInfo.getTemperature() > biomeTemperature){
climatedInfo.addTemperature(-0.01F);
}else{
climatedInfo.addTemperature(0.01F);
}
}
if(climatedInfo.getHumidity() != biomeHumidity){
if(climatedInfo.getHumidity() > biomeHumidity){
climatedInfo.addHumidity(-0.01F);
}else{
climatedInfo.addHumidity(0.01F);
}
}
}
}
}
}
private void updateSides(BlockPos pos){
IClimatePosition climatedInfo = positions.get(pos);
for(EnumFacing facing : EnumFacing.VALUES){
BlockPos facePos = pos.offset(facing);
IClimatePosition climatedInfoFace = positions.get(facePos);
if(climatedInfoFace != null){
if(climatedInfoFace.getTemperature() >= 2.0F){
if(climatedInfoFace.getTemperature() > 2.0F){
climatedInfoFace.setTemperature(2.0F);
}
continue;
}else if(climatedInfoFace.getTemperature() <= 0.0F){
if(climatedInfoFace.getTemperature() < 0.0F){
climatedInfoFace.setTemperature(0.0F);
}
continue;
}
if(climatedInfoFace.getHumidity() >= 2.0F){
if(climatedInfoFace.getHumidity() > 2.0F){
climatedInfoFace.setHumidity(2.0F);
}
continue;
}else if(climatedInfoFace.getHumidity() <= 0.0F){
if(climatedInfoFace.getHumidity() < 0.0F){
climatedInfoFace.setHumidity(0.0F);
}
continue;
}
if(climatedInfo.getTemperature() > climatedInfoFace.getTemperature() + 0.01F){
climatedInfo.addTemperature(-0.01F);
climatedInfoFace.addTemperature(0.01F);
}
if(climatedInfo.getHumidity() > climatedInfoFace.getHumidity() + 0.01F){
climatedInfo.addHumidity(-0.01F);
climatedInfoFace.addHumidity(0.01F);
}
}
}
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound nbt) {
NBTTagList positionList = new NBTTagList();
for(Entry<BlockPos, IClimatePosition> entry : positions.entrySet()){
BlockPos pos = entry.getKey();
NBTTagCompound tag = new NBTTagCompound();
tag.setInteger("XPos", pos.getX());
tag.setInteger("YPos", pos.getY());
tag.setInteger("ZPos", pos.getZ());
positionList.appendTag(entry.getValue().writeToNBT(tag));
}
nbt.setTag("Positions", positionList);
return nbt;
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
NBTTagList positionList = nbt.getTagList("Positions", 10);
for(int i = 0;i < positionList.tagCount();i++){
NBTTagCompound positionTag = positionList.getCompoundTagAt(i);
int xPos = positionTag.getInteger("XPos");
int yPos = positionTag.getInteger("YPos");
int zPos = positionTag.getInteger("ZPos");
BlockPos pos = new BlockPos(xPos, yPos, zPos);
ClimatePosition position = new ClimatePosition(this, pos);
position.readFromNBT(positionTag);
positions.put(pos, position);
}
}
@Override
public int getTicksPerUpdate() {
return 20;
}
@Override
public World getWorld() {
return world;
}
@Override
public Map<BlockPos, IClimatePosition> getPositions() {
return positions;
}
@Override
public List<BlockPos> getOtherPositions() {
return wallPositions;
}
@Override
public void writeData(DataOutputStreamForestry data) throws IOException {
if(!positions.isEmpty()){
data.writeInt(positions.size());
for(IClimatePosition pos : positions.values()){
data.writeInt(pos.getPos().getX());
data.writeInt(pos.getPos().getY());
data.writeInt(pos.getPos().getZ());
data.writeFloat(pos.getTemperature());
data.writeFloat(pos.getHumidity());
}
}else{
data.writeInt(0);
}
}
@Override
public void readData(DataInputStreamForestry data) throws IOException {
int size = data.readInt();
if(size != 0){
positions = new HashMap<>();
for(int index = 0;index < size;index++){
int xPos = data.readInt();
int yPos = data.readInt();
int zPos = data.readInt();
float temperature = data.readFloat();
float humidity = data.readFloat();
BlockPos pos = new BlockPos(xPos, yPos, zPos);
positions.put(pos, new ClimatePosition(this, pos, temperature, humidity));
}
}
}
}
@@ -88,7 +88,7 @@ public class ParticleColoredDripParticle extends Particle {
d0 = BlockLiquid.getLiquidHeightPercent(iblockstate.getValue(BlockLiquid.LEVEL));
}
double d1 = (double) (MathHelper.floor_double(this.posY) + 1) - d0;
double d1 = MathHelper.floor_double(this.posY) + 1 - d0;
if (this.posY < d1) {
this.setExpired();
@@ -0,0 +1,65 @@
package forestry.core.fluids;
import forestry.core.utils.ItemStackUtil;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTank;
/**
* Helper to slowly fill containers from a machine's internal tank.
* Moves filled container from inputSlot to outputSlot.
*/
public class ContainerFiller {
private final FluidTank fluidTank;
private final int fillingTime;
private final IInventory inventory;
private final int inputSlot;
private final int outputSlot;
private ItemStack usedInput;
private int fillingProgress;
public ContainerFiller(FluidTank fluidTank, int fillingTime, IInventory inventory, int inputSlot, int outputSlot) {
this.fluidTank = fluidTank;
this.fillingTime = fillingTime;
this.inventory = inventory;
this.inputSlot = inputSlot;
this.outputSlot = outputSlot;
}
public void updateServerSide() {
ItemStack input = inventory.getStackInSlot(inputSlot);
if (usedInput == null || !ItemStackUtil.isIdenticalItem(usedInput, input)) {
fillingProgress = 0;
usedInput = input;
}
if (usedInput != null) {
FluidStack tankContents = fluidTank.getFluid();
if (tankContents != null && tankContents.amount > 0) {
if (fillingProgress == 0) {
Fluid tankFluid = tankContents.getFluid();
FluidHelper.FillStatus canFill = FluidHelper.fillContainers(fluidTank, inventory, inputSlot, outputSlot, tankFluid, false);
if (canFill == FluidHelper.FillStatus.SUCCESS) {
fillingProgress = 1;
}
} else {
fillingProgress++;
if (fillingProgress >= fillingTime) {
Fluid tankFluid = tankContents.getFluid();
FluidHelper.FillStatus filled = FluidHelper.fillContainers(fluidTank, inventory, inputSlot, outputSlot, tankFluid, true);
if (filled == FluidHelper.FillStatus.SUCCESS) {
fillingProgress = 0;
}
}
}
}
}
}
public int getFillingProgress() {
return fillingProgress;
}
}
@@ -10,17 +10,18 @@
******************************************************************************/
package forestry.core.fluids;
import forestry.core.utils.InventoryUtil;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidTankProperties;
import forestry.core.utils.InventoryUtil;
public final class FluidHelper {
private FluidHelper() {
@@ -34,6 +35,18 @@ public final class FluidHelper {
}
}
public static boolean canAcceptFluid(World world, BlockPos pos, EnumFacing facing, FluidStack fluid) {
IFluidHandler capability = FluidUtil.getFluidHandler(world, pos, facing);
if (capability != null) {
for (IFluidTankProperties tankProperties : capability.getTankProperties()) {
if (tankProperties.canFillFluidType(fluid)) {
return true;
}
}
}
return false;
}
public enum FillStatus {
SUCCESS, INVALID_INPUT, NO_FLUID, NO_SPACE
}
@@ -275,6 +275,7 @@ public class ItemResearchNote extends ItemForestry {
@Override
public void addInformation(ItemStack itemstack, EntityPlayer player, List<String> list, boolean flag) {
super.addInformation(itemstack, player, list, flag);
ResearchNote note = new ResearchNote(itemstack.getTagCompound());
note.addTooltip(list);
}
@@ -14,6 +14,11 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.BiomeDictionary;
import forestry.api.core.EnumHumidity;
import forestry.api.core.EnumTemperature;
import forestry.api.core.IClimateProvider;
@@ -23,10 +28,6 @@ import forestry.api.genetics.IGenome;
import forestry.api.genetics.IMutation;
import forestry.api.genetics.IMutationBuilder;
import forestry.api.genetics.IMutationCondition;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.BiomeDictionary;
public abstract class Mutation implements IMutation, IMutationBuilder {
@@ -15,7 +15,6 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import forestry.api.core.EnumHumidity;
import forestry.api.core.ForestryAPI;
import forestry.api.genetics.AlleleManager;
import forestry.api.genetics.IAllele;
import forestry.api.genetics.IGenome;
@@ -18,7 +18,6 @@ import forestry.core.gui.slots.SlotOutput;
import forestry.core.inventory.InventoryEscritoire;
import forestry.core.network.packets.PacketGuiSelectRequest;
import forestry.core.network.packets.PacketGuiUpdate;
import forestry.core.proxy.Proxies;
import forestry.core.tiles.EscritoireGame;
import forestry.core.tiles.TileEscritoire;
@@ -10,7 +10,6 @@
******************************************************************************/
package forestry.core.gui;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Stack;
@@ -11,16 +11,13 @@
package forestry.core.items;
import javax.annotation.Nonnull;
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import forestry.api.core.Tabs;
import forestry.core.gui.ContainerAlyzer;
import forestry.core.gui.GuiAlyzer;
import forestry.core.inventory.ItemInventoryAlyzer;
import forestry.core.utils.ItemTooltipUtil;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
public class ItemAlyzer extends ItemWithGui {
public ItemAlyzer() {
@@ -41,10 +38,4 @@ public class ItemAlyzer extends ItemWithGui {
public Object getContainer(@Nonnull EntityPlayer player, ItemStack heldItem, int data) {
return new ContainerAlyzer(new ItemInventoryAlyzer(player, heldItem), player);
}
@Override
public void addInformation(ItemStack stack, EntityPlayer playerIn, List<String> tooltip, boolean advanced) {
super.addInformation(stack, playerIn, tooltip, advanced);
ItemTooltipUtil.addInformation(stack, playerIn, tooltip, advanced);
}
}
@@ -10,6 +10,13 @@
******************************************************************************/
package forestry.core.items;
import java.util.List;
import forestry.core.blocks.BlockBase;
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.entity.player.EntityPlayer;
@@ -19,11 +26,6 @@ import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import forestry.core.blocks.BlockBase;
import forestry.core.blocks.IBlockWithMeta;
import forestry.core.tiles.TileForestry;
import forestry.core.tiles.TileUtil;
public class ItemBlockForestry<B extends Block> extends ItemBlock {
public ItemBlockForestry(Block block) {
@@ -54,6 +56,12 @@ public class ItemBlockForestry<B extends Block> extends ItemBlock {
return block.getUnlocalizedName();
}
@Override
public void addInformation(ItemStack stack, EntityPlayer playerIn, List<String> tooltip, boolean advanced) {
super.addInformation(stack, playerIn, tooltip, advanced);
ItemTooltipUtil.addInformation(stack, playerIn, tooltip, advanced);
}
@Override
public boolean placeBlockAt(ItemStack stack, EntityPlayer player, World world, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, IBlockState newState) {
boolean placed = super.placeBlockAt(stack, player, world, pos, side, hitX, hitY, hitZ, newState);
@@ -23,11 +23,11 @@ public class ItemBlockNBT extends ItemBlockForestry<Block> {
}
@Override
public void addInformation(ItemStack itemstack, EntityPlayer player, List<String> info, boolean par4) {
if (!itemstack.hasTagCompound()) {
return;
}
public void addInformation(ItemStack itemstack, EntityPlayer player, List<String> info, boolean advanced) {
super.addInformation(itemstack, player, info, advanced);
info.add("There are still some scribbles on this.");
if (itemstack.hasTagCompound()) {
info.add("There are still some scribbles on this.");
}
}
}
@@ -94,6 +94,10 @@ public class ItemCraftingMaterial extends ItemForestry {
}
public ItemStack getCamouflagedPaneling() {
return new ItemStack(this, 1, 7);
return getCamouflagedPaneling(1);
}
public ItemStack getCamouflagedPaneling(int stackSize) {
return new ItemStack(this, stackSize, 7);
}
}
@@ -10,18 +10,11 @@
******************************************************************************/
package forestry.core.items;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import java.util.Collection;
import java.util.List;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.TextFormatting;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import forestry.api.circuits.ChipsetManager;
import forestry.api.circuits.ICircuit;
import forestry.api.circuits.ICircuitLayout;
@@ -30,6 +23,11 @@ import forestry.core.circuits.SolderManager;
import forestry.core.config.Config;
import forestry.core.proxy.Proxies;
import forestry.core.utils.Translator;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.TextFormatting;
public class ItemElectronTube extends ItemOverlay {
@@ -39,6 +37,7 @@ public class ItemElectronTube extends ItemOverlay {
@Override
public void addInformation(ItemStack itemstack, EntityPlayer player, List<String> list, boolean flag) {
super.addInformation(itemstack, player, list, flag);
Multimap<ICircuitLayout, ICircuit> circuits = getCircuits(itemstack);
if (!circuits.isEmpty()) {
if (Proxies.common.isShiftDown()) {
@@ -10,17 +10,19 @@
******************************************************************************/
package forestry.core.items;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.oredict.OreDictionary;
import java.util.List;
import forestry.api.core.IItemModelRegister;
import forestry.api.core.IModelManager;
import forestry.core.CreativeTabForestry;
import forestry.core.utils.ItemTooltipUtil;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.oredict.OreDictionary;
public class ItemForestry extends Item implements IItemModelRegister {
public ItemForestry() {
@@ -48,4 +50,10 @@ public class ItemForestry extends Item implements IItemModelRegister {
public ItemStack getWildcard() {
return new ItemStack(this, 1, OreDictionary.WILDCARD_VALUE);
}
@Override
public void addInformation(ItemStack stack, EntityPlayer playerIn, List<String> tooltip, boolean advanced) {
super.addInformation(stack, playerIn, tooltip, advanced);
ItemTooltipUtil.addInformation(stack, playerIn, tooltip, advanced);
}
}
@@ -17,9 +17,7 @@ import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.ItemPickaxe;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemTool;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
@@ -12,6 +12,9 @@ package forestry.core.items;
import java.util.List;
import forestry.api.core.IModelManager;
import forestry.api.core.IToolPipette;
import forestry.core.fluids.PipetteContents;
import net.minecraft.client.renderer.ItemMeshDefinition;
import net.minecraft.client.renderer.block.model.ModelBakery;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
@@ -20,17 +23,12 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidContainerItem;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import forestry.api.core.IModelManager;
import forestry.api.core.IToolPipette;
import forestry.core.fluids.PipetteContents;
public class ItemPipette extends ItemForestry implements IToolPipette, IFluidContainerItem {
public ItemPipette() {
@@ -90,6 +88,8 @@ public class ItemPipette extends ItemForestry implements IToolPipette, IFluidCon
@Override
public void addInformation(ItemStack itemstack, EntityPlayer player, List<String> list, boolean flag) {
super.addInformation(itemstack, player, list, flag);
PipetteContents contained = PipetteContents.create(itemstack);
if (contained != null) {
contained.addTooltip(list);
@@ -10,25 +10,14 @@
******************************************************************************/
package forestry.core.items;
import java.util.List;
import forestry.core.utils.Translator;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import forestry.core.circuits.ContainerSolderingIron;
import forestry.core.circuits.GuiSolderingIron;
import forestry.core.circuits.ISolderingIron;
import forestry.core.inventory.ItemInventorySolderingIron;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
public class ItemSolderingIron extends ItemWithGui implements ISolderingIron {
@Override
public void addInformation(ItemStack stack, EntityPlayer playerIn, List<String> tooltip, boolean advanced) {
super.addInformation(stack, playerIn, tooltip, advanced);
tooltip.add(Translator.translateToLocal("item.for.solderingIron.tooltip"));
}
@Override
public Object getGui(EntityPlayer player, ItemStack heldItem, int data) {
return new GuiSolderingIron(player, new ItemInventorySolderingIron(player, heldItem));
@@ -24,7 +24,7 @@ import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public abstract class BlankItemModel implements IBakedModel {
public abstract class BlankModel implements IBakedModel {
protected ItemOverrideList overrideList;
@Override
@@ -46,7 +46,7 @@ public abstract class BlankItemModel implements IBakedModel {
@Override
public boolean isAmbientOcclusion() {
return false;
return true;
}
@Override
@@ -14,18 +14,24 @@ import net.minecraft.block.Block;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
public class BlockModelIndex {
public class BlockModelEntry {
public final ModelResourceLocation blockModelLocation;
public final ModelResourceLocation itemModelLocation;
public final IBakedModel model;
public final boolean addStateMapper;
public final Block block;
public BlockModelIndex(ModelResourceLocation blockModelLocation, ModelResourceLocation itemModelLocation, IBakedModel model, Block block) {
public BlockModelEntry(ModelResourceLocation blockModelLocation, ModelResourceLocation itemModelLocation, IBakedModel model, Block block) {
this(blockModelLocation, itemModelLocation, model, block, true);
}
public BlockModelEntry(ModelResourceLocation blockModelLocation, ModelResourceLocation itemModelLocation, IBakedModel model, Block block, boolean addStateMapper) {
this.blockModelLocation = blockModelLocation;
this.itemModelLocation = itemModelLocation;
this.model = model;
this.block = block;
this.addStateMapper = addStateMapper;
}
}
@@ -66,10 +66,15 @@ public abstract class ModelBlockDefault<B extends Block> implements IBakedModel
bakeWorldBlock(bBlock, world, pos, stateExtended, baker);
blockModel = baker.bakeModel(false);
onCreateModel(blockModel);
return blockModel.getQuads(state, side, rand);
}
return Collections.emptyList();
}
protected void onCreateModel(IModelBakerModel model){
model.setAmbientOcclusion(true);
}
@Override
public boolean isAmbientOcclusion() {
Loaded 100 of 1171 files, more files were not shown because too many files have changed in this diff. Show more