diff --git a/libs/gendustry-1.6.5.1-GTNH-mc1.7.10-api.jar b/libs/gendustry-1.6.5.1-GTNH-mc1.7.10-api.jar new file mode 100644 index 0000000000..437d611241 Binary files /dev/null and b/libs/gendustry-1.6.5.1-GTNH-mc1.7.10-api.jar differ diff --git a/src/main/resources/assets/opencomputers/lang/en_US.lang b/src/main/resources/assets/opencomputers/lang/en_US.lang index 30da048b94..8a96f30606 100644 --- a/src/main/resources/assets/opencomputers/lang/en_US.lang +++ b/src/main/resources/assets/opencomputers/lang/en_US.lang @@ -159,6 +159,7 @@ item.oc.WirelessNetworkCard0.name=Wireless Network Card (Tier 1) item.oc.WirelessNetworkCard1.name=Wireless Network Card (Tier 2) item.oc.WorldSensorCard.name=World Sensor Card item.oc.wrench.name=Scrench +item.oc.UpgradeBeekeeper.name=Beekeeper Upgrade # Entities entity.oc.Drone.name=Drone diff --git a/src/main/resources/assets/opencomputers/lang/ru_RU.lang b/src/main/resources/assets/opencomputers/lang/ru_RU.lang index fe48cb59be..9e18808b25 100644 --- a/src/main/resources/assets/opencomputers/lang/ru_RU.lang +++ b/src/main/resources/assets/opencomputers/lang/ru_RU.lang @@ -155,6 +155,7 @@ item.oc.UpgradeTank.name=Улучшение "Бак для жидкостей" item.oc.UpgradeTankController.name=Улучшение "Контроллер бака" item.oc.UpgradeTractorBeam.name=Улучшение "Притягивающий луч" item.oc.UpgradeTrading.name=Улучшение "Торговля" +item.oc.UpgradeBeekeeper.name=Улучшение "Пчеловод" item.oc.WirelessNetworkCard0.name=Плата беспроводной сети (1-ый уровень) item.oc.WirelessNetworkCard1.name=Плата беспроводной сети (2-ой уровень) item.oc.WorldSensorCard.name=Карта-мировой сенсор diff --git a/src/main/resources/assets/opencomputers/recipes/default.recipes b/src/main/resources/assets/opencomputers/recipes/default.recipes index c4eb8359d9..2280f7fedb 100644 --- a/src/main/resources/assets/opencomputers/recipes/default.recipes +++ b/src/main/resources/assets/opencomputers/recipes/default.recipes @@ -244,6 +244,11 @@ batteryUpgrade3 { ["oc:capacitor", chipDiamond, "oc:capacitor"] [nuggetIron, "oc:capacitor", nuggetIron]] } +beekeeperUpgrade { + input: [[ingotGold, blockGlass, ingotGold] + ["oc:circuitChip3", {item="Forestry:beealyzer"}, "oc:circuitChip3"] + [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] +} chunkloaderUpgrade { input: [[ingotGold, blockGlass, ingotGold] ["oc:circuitChip3", eyeOfEnder, "oc:circuitChip3"] diff --git a/src/main/resources/assets/opencomputers/textures/items/UpgradeBeekeeper.png b/src/main/resources/assets/opencomputers/textures/items/UpgradeBeekeeper.png new file mode 100644 index 0000000000..c22f9731e5 Binary files /dev/null and b/src/main/resources/assets/opencomputers/textures/items/UpgradeBeekeeper.png differ diff --git a/src/main/scala/li/cil/oc/Constants.scala b/src/main/scala/li/cil/oc/Constants.scala index 061bec65ef..45a7b52da5 100644 --- a/src/main/scala/li/cil/oc/Constants.scala +++ b/src/main/scala/li/cil/oc/Constants.scala @@ -60,6 +60,7 @@ object Constants { final val BatteryUpgradeTier1 = "batteryUpgrade1" final val BatteryUpgradeTier2 = "batteryUpgrade2" final val BatteryUpgradeTier3 = "batteryUpgrade3" + final val BeekeeperUpgrade = "beekeeperUpgrade" final val ButtonGroup = "buttonGroup" final val Card = "card" final val CardContainerTier1 = "cardContainer1" diff --git a/src/main/scala/li/cil/oc/integration/forestry/ConverterIAlleles.java b/src/main/scala/li/cil/oc/integration/forestry/ConverterIAlleles.java index d89a64df3b..4a8eb49fb5 100644 --- a/src/main/scala/li/cil/oc/integration/forestry/ConverterIAlleles.java +++ b/src/main/scala/li/cil/oc/integration/forestry/ConverterIAlleles.java @@ -34,8 +34,10 @@ public void convert(final Object value, final Map output) { } } - private void convertAlleleSpecies(final IAlleleSpecies value, final Map output) { + static void convertAlleleSpecies(final IAlleleSpecies value, final Map output) { output.put("name", value.getName()); output.put("uid", value.getUID()); + output.put("humidity", value.getHumidity().name); + output.put("temperature", value.getTemperature().name); } } diff --git a/src/main/scala/li/cil/oc/integration/forestry/ConverterIIndividual.java b/src/main/scala/li/cil/oc/integration/forestry/ConverterIIndividual.java index 981675d442..9768b9b183 100644 --- a/src/main/scala/li/cil/oc/integration/forestry/ConverterIIndividual.java +++ b/src/main/scala/li/cil/oc/integration/forestry/ConverterIIndividual.java @@ -15,19 +15,7 @@ import forestry.api.arboriculture.IAlleleTreeSpecies; import forestry.api.arboriculture.ITree; import forestry.api.arboriculture.ITreeGenome; -import forestry.api.genetics.IAllele; -import forestry.api.genetics.IAlleleArea; -import forestry.api.genetics.IAlleleBoolean; -import forestry.api.genetics.IAlleleFloat; -import forestry.api.genetics.IAlleleFlowers; -import forestry.api.genetics.IAlleleInteger; -import forestry.api.genetics.IAllelePlantType; -import forestry.api.genetics.IAlleleTolerance; -import forestry.api.genetics.IChromosome; -import forestry.api.genetics.IChromosomeType; -import forestry.api.genetics.IGenome; -import forestry.api.genetics.IIndividual; -import forestry.api.genetics.IIndividualLiving; +import forestry.api.genetics.*; import forestry.api.lepidopterology.EnumButterflyChromosome; import forestry.api.lepidopterology.IAlleleButterflyEffect; import forestry.api.lepidopterology.IAlleleButterflySpecies; @@ -35,6 +23,7 @@ import forestry.api.lepidopterology.IButterflyGenome; import li.cil.oc.api.driver.Converter; +import java.util.HashMap; import java.util.Map; /* @@ -73,41 +62,16 @@ private interface IAlleleConverter { private static final Map, IAlleleConverter> converters = ImmutableMap., IAlleleConverter>builder() - .put(IAlleleFloat.class, new IAlleleConverter() { - @Override - public Object convert(IAlleleFloat allele) { - return allele.getValue(); - } - }) - .put(IAlleleInteger.class, new IAlleleConverter() { - @Override - public Object convert(IAlleleInteger allele) { - return allele.getValue(); - } - }) - .put(IAlleleBoolean.class, new IAlleleConverter() { - @Override - public Object convert(IAlleleBoolean allele) { - return allele.getValue(); - } - }) - .put(IAlleleArea.class, new IAlleleConverter() { - @Override - public Object convert(IAlleleArea allele) { - return allele.getValue(); - } - }) - .put(IAllelePlantType.class, new IAlleleConverter() { - @Override - public Object convert(IAllelePlantType allele) { - return allele.getPlantTypes(); - } - }) - .put(IAlleleGrowth.class, new IAlleleConverter() { - @Override - public Object convert(IAlleleGrowth allele) { - return allele.getProvider().getInfo(); - } + .put(IAlleleFloat.class, (IAlleleConverter) IAlleleFloat::getValue) + .put(IAlleleInteger.class, (IAlleleConverter) IAlleleInteger::getValue) + .put(IAlleleBoolean.class, (IAlleleConverter) IAlleleBoolean::getValue) + .put(IAlleleArea.class, (IAlleleConverter) IAlleleArea::getValue) + .put(IAllelePlantType.class, (IAlleleConverter) IAllelePlantType::getPlantTypes) + .put(IAlleleGrowth.class, (IAlleleConverter) allele -> allele.getProvider().getInfo()) + .put(IAlleleBeeSpecies.class, (IAlleleConverter) allele -> { + Map output = new HashMap<>(); + ConverterIAlleles.convertAlleleSpecies(allele, output); + return output; }) .build(); diff --git a/src/main/scala/li/cil/oc/integration/forestry/DriverUpgradeBeekeeper.scala b/src/main/scala/li/cil/oc/integration/forestry/DriverUpgradeBeekeeper.scala new file mode 100644 index 0000000000..98594129c9 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/forestry/DriverUpgradeBeekeeper.scala @@ -0,0 +1,34 @@ +package li.cil.oc.integration.forestry + +import li.cil.oc.Constants +import li.cil.oc.api +import li.cil.oc.api.driver.EnvironmentProvider +import li.cil.oc.api.driver.item.HostAware +import li.cil.oc.api.internal +import li.cil.oc.api.network.{EnvironmentHost, ManagedEnvironment} +import li.cil.oc.common.{Slot, Tier} +import li.cil.oc.integration.opencomputers.Item +import net.minecraft.item.ItemStack + +object DriverUpgradeBeekeeper extends Item with HostAware { + override def worksWith(stack: ItemStack): Boolean = isOneOf(stack, + api.Items.get(Constants.ItemName.BeekeeperUpgrade)) + + override def createEnvironment(stack: ItemStack, host: EnvironmentHost): ManagedEnvironment = + if (host.world != null && host.world.isRemote) null + else host match { + case host: internal.Agent => new UpgradeBeekeeper(host) + case _ => null + } + + override def slot(stack: ItemStack) : String = Slot.Upgrade + + override def tier(stack: ItemStack) : Int = Tier.Two + + object Provider extends EnvironmentProvider { + override def getEnvironment(stack: ItemStack): Class[_] = + if (worksWith(stack)) + classOf[UpgradeBeekeeper] + else null + } +} diff --git a/src/main/scala/li/cil/oc/integration/forestry/ModForestry.scala b/src/main/scala/li/cil/oc/integration/forestry/ModForestry.scala index c23dc4e9a4..0bc1b94c35 100644 --- a/src/main/scala/li/cil/oc/integration/forestry/ModForestry.scala +++ b/src/main/scala/li/cil/oc/integration/forestry/ModForestry.scala @@ -1,6 +1,9 @@ package li.cil.oc.integration.forestry +import cpw.mods.fml.common.registry.GameRegistry +import li.cil.oc.Constants import li.cil.oc.api.Driver +import li.cil.oc.common.recipe.Recipes import li.cil.oc.integration.ModProxy import li.cil.oc.integration.Mods @@ -13,5 +16,10 @@ object ModForestry extends ModProxy { Driver.add(ConverterItemStack) Driver.add(new DriverAnalyzer) Driver.add(new DriverBeeHouse) + Driver.add(DriverUpgradeBeekeeper) + Driver.add(DriverUpgradeBeekeeper.Provider) + val multi = new li.cil.oc.common.item.Delegator() + GameRegistry.registerItem(multi, "item.forestry") + Recipes.addSubItem(new li.cil.oc.integration.forestry.item.UpgradeBeekeeper(multi), Constants.ItemName.BeekeeperUpgrade, "oc:beekeeperUpgrade") } } \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/integration/forestry/UpgradeBeekeeper.scala b/src/main/scala/li/cil/oc/integration/forestry/UpgradeBeekeeper.scala new file mode 100644 index 0000000000..d190385509 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/forestry/UpgradeBeekeeper.scala @@ -0,0 +1,197 @@ +package li.cil.oc.integration.forestry + +import java.util + +import cpw.mods.fml.common.Loader +import forestry.api.apiculture.{BeeManager, IBeeHousing} +import forestry.plugins.PluginApiculture +import li.cil.oc.Constants +import li.cil.oc.api.driver.DeviceInfo +import li.cil.oc.api.driver.DeviceInfo.{DeviceAttribute, DeviceClass} +import li.cil.oc.api.machine.{Arguments, Callback, Context} +import li.cil.oc.api.network.{EnvironmentHost, Node, Visibility} +import li.cil.oc.api.{Network, internal, prefab} +import li.cil.oc.server.component.result +import li.cil.oc.server.component.traits.{NetworkAware, SideRestricted, WorldAware} +import li.cil.oc.util.{BlockPosition, InventoryUtils} +import li.cil.oc.util.ExtendedArguments.extendedArguments +import li.cil.oc.util.ExtendedWorld._ +import net.bdew.gendustry.api.blocks.IIndustrialApiary +import net.minecraft.inventory.ISidedInventory +import net.minecraft.item.ItemStack +import net.minecraft.nbt.NBTTagCompound +import net.minecraftforge.common.util.ForgeDirection + +import scala.collection.convert.WrapAsJava._ + +class UpgradeBeekeeper(val host: EnvironmentHost with internal.Agent) extends prefab.ManagedEnvironment with DeviceInfo with WorldAware with SideRestricted with NetworkAware { + override val node: Node = Network.newNode(this, Visibility.Network). + withComponent("beekeeper", Visibility.Neighbors). + withConnector(). + create() + + private final lazy val deviceInfo = Map( + DeviceAttribute.Class -> DeviceClass.Generic, + DeviceAttribute.Description -> "BeeKeeper", + DeviceAttribute.Vendor -> Constants.DeviceInfo.DefaultVendor, + DeviceAttribute.Product -> "Breeding bees for you (almost)" + ) + + override def getDeviceInfo: util.Map[String, String] = deviceInfo + override def position: BlockPosition = BlockPosition(host) + override protected def checkSideForAction(args: Arguments, n: Int): ForgeDirection = args.checkSideAny(n) + + private def withApiary(side: ForgeDirection, f: IBeeHousing => Array[AnyRef]) = + if (host.mainInventory.getSizeInventory > 0) { + position.world.get.getTileEntity(position.offset(side)) match { + case housing: IBeeHousing => f(housing) + case _ => result(false, "Not facing an apiary") + } + } + else result(false, "No inventory?") + + @Callback(doc = """function(side:number):boolean -- Swap the queen from the selected slot with the apiary at the specified side.""") + def swapQueen(context: Context, args: Arguments): Array[AnyRef] = { + val facing = checkSideForAction(args, 0) + withApiary(facing, housing => { + val selected = host.mainInventory.getStackInSlot(host.selectedSlot) + val oldQueen = housing.getBeeInventory.getQueen + housing.getBeeInventory.setQueen(selected) + host.mainInventory.setInventorySlotContents(host.selectedSlot, oldQueen) + result(true) + }) + } + + @Callback(doc = """function(side:number):boolean -- Swap the drone from the selected slot with the apiary at the specified side.""") + def swapDrone(context: Context, args: Arguments): Array[AnyRef] = { + val facing = checkSideForAction(args, 0) + withApiary(facing, housing => { + val selected = host.mainInventory.getStackInSlot(host.selectedSlot) + val oldQueen = housing.getBeeInventory.getDrone + housing.getBeeInventory.setDrone(selected) + host.mainInventory.setInventorySlotContents(host.selectedSlot, oldQueen) + result(true) + }) + } + + @Callback(doc = """function(side:number):number -- Get current progress percent for the apiary at the specified side.""") + def getBeeProgress(context: Context, args: Arguments): Array[AnyRef] = { + val facing = checkSideForAction(args, 0) + withApiary(facing, housing => result(housing.getBeekeepingLogic.getBeeProgressPercent)) + } + + @Callback(doc = """function(side:number):boolean -- Checks if current bee in the apiary at the specified side can work now.""") + def canWork(context: Context, args: Arguments): Array[AnyRef] = { + val facing = checkSideForAction(args, 0) + withApiary(facing, housing => result(housing.getBeekeepingLogic.canWork)) + } + + @Callback(doc = """function(honeyslot:number):boolean -- Analyzes bee in selected slot, uses honey from the specified slot.""") + def analyze(context: Context, args: Arguments): Array[AnyRef] = { + val inventory = host.mainInventory + val specimenSlot = host.selectedSlot + val specimen = inventory.getStackInSlot(specimenSlot) + if (!BeeManager.beeRoot.isMember(specimen)) + return result(false, "Not a bee") + + val honeySlot = args.checkSlot(inventory, 0) + val honeyStack = inventory.getStackInSlot(honeySlot) + if (honeyStack== null || honeyStack.stackSize == 0 || (honeyStack.getItem != PluginApiculture.items.honeydew && honeyStack.getItem != PluginApiculture.items.honeyDrop)) + return result(false, "No honey!") + + val individual = BeeManager.beeRoot.getMember(specimen) + if (!individual.isAnalyzed) { + individual.analyze + val nbttagcompound = new NBTTagCompound + individual.writeToNBT(nbttagcompound) + specimen.setTagCompound(nbttagcompound) + inventory.setInventorySlotContents(specimenSlot, specimen) + honeyStack.stackSize -= 1 + inventory.setInventorySlotContents(honeySlot, honeyStack) + } + result(true) + } + + private def findSameStack(upgrade: ItemStack, inv: ISidedInventory):Int = { + for (slot <- 2 to 5) { + val u = inv.getStackInSlot(slot) + if (u != null && u.getItem == upgrade.getItem && upgrade.getItemDamage == u.getItemDamage) + return slot + } + 0 + } + + private def findEmptySlot(inv: ISidedInventory):Int = { + for (slot <- 2 to 5) { + if (inv.getStackInSlot(slot) == null) + return slot + } + 0 + } + + @Callback(doc = """function(side:number):boolean -- Tries to add industrial upgrade from the selected slot to industrial apiary at the given side.""") + def addIndustrialUpgrade(context: Context, args: Arguments): Array[AnyRef] = { + if (!Loader.isModLoaded("gendustry")) return result(false, "Gendustry not loaded!") + val inventory = host.mainInventory + val facing = checkSideForAction(args, 0) + val upgrade = inventory.getStackInSlot(host.selectedSlot) + if (upgrade == null) return result(false, "No upgrade in selected slot") + position.world.get.getTileEntity(position.offset(facing)) match { + case ia : IIndustrialApiary => + val inv = ia.asInstanceOf[ISidedInventory] + if (!inv.isItemValidForSlot(2, upgrade)) + return result(false, "Upgrade does not fit") + + var slot = findSameStack(upgrade, inv) + if (slot == 0) + slot = findEmptySlot(inv) + + val u = inv.getStackInSlot(slot) + if (u == null) + inv.setInventorySlotContents(slot, upgrade) + else { + u.stackSize += upgrade.stackSize + inv.setInventorySlotContents(slot, u) + } + inventory.setInventorySlotContents(host.selectedSlot, null) + result(true) + + case _ => result(false, "Not facing an industrial apiary") + } + } + @Callback(doc = """function(side:number, slot: number):table -- Get industrial upgrade in the given slot of the industrial apiary at the given side.""") + def getIndustrialUpgrade(context: Context, args: Arguments): Array[AnyRef] = { + if (!Loader.isModLoaded("gendustry")) return result(Unit, "Gendustry not loaded!") + val facing = checkSideForAction(args, 0) + position.world.get.getTileEntity(position.offset(facing)) match { + case ia: IIndustrialApiary => + val inv = ia.asInstanceOf[ISidedInventory] + val slot = args.checkInteger(1) + 1 + if (slot < 2 || slot > 5) + return result(Unit, "Wrong slot index (should be 1-4)") + + result(inv.getStackInSlot(slot)) + + case _ => result(Unit, "Not facing an industrial apiary") + } + } + @Callback(doc = """function(side:number, slot: number):boolean -- Remove industrial upgrade from the given slot of the industrial apiary at the given side.""") + def removeIndustrialUpgrade(context: Context, args: Arguments): Array[AnyRef] = { + if (!Loader.isModLoaded("gendustry")) return result(false, "Gendustry not loaded!") + val facing = checkSideForAction(args, 0) + position.world.get.getTileEntity(position.offset(facing)) match { + case ia: IIndustrialApiary => + val inv = ia.asInstanceOf[ISidedInventory] + val slot = args.checkInteger(1) + 1 + if (slot < 2 || slot > 5) + return result(false, "Wrong slot index (should be 1-4)") + + val u = inv.getStackInSlot(slot) + val res = InventoryUtils.insertIntoInventory(u, host.mainInventory) + inv.setInventorySlotContents(slot, if (u.stackSize > 0) u else null) + result(res) + + case _ => result(false, "Not facing an industrial apiary") + } + } +} diff --git a/src/main/scala/li/cil/oc/integration/forestry/item/UpgradeBeekeeper.scala b/src/main/scala/li/cil/oc/integration/forestry/item/UpgradeBeekeeper.scala new file mode 100644 index 0000000000..bf28172e06 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/forestry/item/UpgradeBeekeeper.scala @@ -0,0 +1,5 @@ +package li.cil.oc.integration.forestry.item + +import li.cil.oc.common.item.{Delegator, traits} + +class UpgradeBeekeeper(val parent: Delegator) extends traits.Delegate with traits.ItemTier diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala b/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala index a0a27e8239..f9eddae1d2 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala @@ -231,7 +231,9 @@ object ModOpenComputers extends ModProxy { Constants.ItemName.TankUpgrade, Constants.ItemName.TractorBeamUpgrade, Constants.ItemName.LeashUpgrade, - Constants.ItemName.TradingUpgrade) + Constants.ItemName.TradingUpgrade, + Constants.ItemName.BeekeeperUpgrade + ) blacklistHost(classOf[internal.Drone], Constants.BlockName.Keyboard, Constants.BlockName.ScreenTier1, @@ -248,7 +250,8 @@ object ModOpenComputers extends ModProxy { Constants.ItemName.AngelUpgrade, Constants.ItemName.CraftingUpgrade, Constants.ItemName.HoverUpgradeTier1, - Constants.ItemName.HoverUpgradeTier2) + Constants.ItemName.HoverUpgradeTier2, + Constants.ItemName.BeekeeperUpgrade) blacklistHost(classOf[internal.Microcontroller], Constants.BlockName.Keyboard, Constants.BlockName.ScreenTier1, @@ -275,7 +278,8 @@ object ModOpenComputers extends ModProxy { Constants.ItemName.TankControllerUpgrade, Constants.ItemName.TractorBeamUpgrade, Constants.ItemName.LeashUpgrade, - Constants.ItemName.TradingUpgrade) + Constants.ItemName.TradingUpgrade, + Constants.ItemName.BeekeeperUpgrade) blacklistHost(classOf[internal.Robot], Constants.BlockName.Transposer, Constants.BlockName.CarpetedCapacitor, @@ -302,7 +306,8 @@ object ModOpenComputers extends ModProxy { Constants.ItemName.TankUpgrade, Constants.ItemName.TankControllerUpgrade, Constants.ItemName.LeashUpgrade, - Constants.ItemName.TradingUpgrade) + Constants.ItemName.TradingUpgrade, + Constants.ItemName.BeekeeperUpgrade) if (!WirelessRedstone.isAvailable) { blacklistHost(classOf[internal.Drone], Constants.ItemName.RedstoneCardTier2)