Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bee keeper robot upgrade #3530

Open
wants to merge 5 commits into
base: master-MC1.7.10
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added libs/gendustry-1.6.5.1-GTNH-mc1.7.10-api.jar
Binary file not shown.
1 change: 1 addition & 0 deletions src/main/resources/assets/opencomputers/lang/en_US.lang
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/assets/opencomputers/lang/ru_RU.lang
Original file line number Diff line number Diff line change
Expand Up @@ -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=Карта-мировой сенсор
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this use tier 3 components in a tier 2 upgrade? Whichever is the intended tier, it should be adjusted.

[ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]]
}
chunkloaderUpgrade {
input: [[ingotGold, blockGlass, ingotGold]
["oc:circuitChip3", eyeOfEnder, "oc:circuitChip3"]
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/main/scala/li/cil/oc/Constants.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ public void convert(final Object value, final Map<Object, Object> output) {
}
}

private void convertAlleleSpecies(final IAlleleSpecies value, final Map<Object, Object> output) {
static void convertAlleleSpecies(final IAlleleSpecies value, final Map<Object, Object> output) {
output.put("name", value.getName());
output.put("uid", value.getUID());
output.put("humidity", value.getHumidity().name);
output.put("temperature", value.getTemperature().name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,15 @@
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;
import forestry.api.lepidopterology.IButterfly;
import forestry.api.lepidopterology.IButterflyGenome;
import li.cil.oc.api.driver.Converter;

import java.util.HashMap;
import java.util.Map;

/*
Expand Down Expand Up @@ -73,41 +62,16 @@ private interface IAlleleConverter<A extends IAllele> {

private static final Map<Class<? extends IAllele>, IAlleleConverter<?>> converters =
ImmutableMap.<Class<? extends IAllele>, IAlleleConverter<?>>builder()
.put(IAlleleFloat.class, new IAlleleConverter<IAlleleFloat>() {
@Override
public Object convert(IAlleleFloat allele) {
return allele.getValue();
}
})
.put(IAlleleInteger.class, new IAlleleConverter<IAlleleInteger>() {
@Override
public Object convert(IAlleleInteger allele) {
return allele.getValue();
}
})
.put(IAlleleBoolean.class, new IAlleleConverter<IAlleleBoolean>() {
@Override
public Object convert(IAlleleBoolean allele) {
return allele.getValue();
}
})
.put(IAlleleArea.class, new IAlleleConverter<IAlleleArea>() {
@Override
public Object convert(IAlleleArea allele) {
return allele.getValue();
}
})
.put(IAllelePlantType.class, new IAlleleConverter<IAllelePlantType>() {
@Override
public Object convert(IAllelePlantType allele) {
return allele.getPlantTypes();
}
})
.put(IAlleleGrowth.class, new IAlleleConverter<IAlleleGrowth>() {
@Override
public Object convert(IAlleleGrowth allele) {
return allele.getProvider().getInfo();
}
.put(IAlleleFloat.class, (IAlleleConverter<IAlleleFloat>) IAlleleFloat::getValue)
.put(IAlleleInteger.class, (IAlleleConverter<IAlleleInteger>) IAlleleInteger::getValue)
.put(IAlleleBoolean.class, (IAlleleConverter<IAlleleBoolean>) IAlleleBoolean::getValue)
.put(IAlleleArea.class, (IAlleleConverter<IAlleleArea>) IAlleleArea::getValue)
.put(IAllelePlantType.class, (IAlleleConverter<IAllelePlantType>) IAllelePlantType::getPlantTypes)
.put(IAlleleGrowth.class, (IAlleleConverter<IAlleleGrowth>) allele -> allele.getProvider().getInfo())
.put(IAlleleBeeSpecies.class, (IAlleleConverter<IAlleleBeeSpecies>) allele -> {
Map<Object, Object> output = new HashMap<>();
ConverterIAlleles.convertAlleleSpecies(allele, output);
return output;
})
.build();

Expand Down
Original file line number Diff line number Diff line change
@@ -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
}
}
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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")
}
}
197 changes: 197 additions & 0 deletions src/main/scala/li/cil/oc/integration/forestry/UpgradeBeekeeper.scala
Original file line number Diff line number Diff line change
@@ -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.""")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@Callback(doc = """function(side:number):boolean -- Swap the queen from the selected slot with the apiary at the specified side.""")
@Callback(doc = """function(side:number):boolean -- Swap the queen from the selected slot with the apiary on 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.""")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@Callback(doc = """function(side:number):boolean -- Swap the drone from the selected slot with the apiary at the specified side.""")
@Callback(doc = """function(side:number):boolean -- Swap the drone from the selected slot with the apiary on 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.""")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@Callback(doc = """function(side:number):number -- Get current progress percent for the apiary at the specified side.""")
@Callback(doc = """function(side:number):number -- Get current progress percent for the apiary on 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.""")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@Callback(doc = """function(side:number):boolean -- Checks if current bee in the apiary at the specified side can work now.""")
@Callback(doc = """function(side:number):boolean -- Checks if current bee in the apiary on 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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in addition to consuming honey, this function should also consume a reasonable amount of energy, to make it similar to other "scanning" components in the mod such as the geolyzer.

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.""")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice if these callbacks were only available if gendustry is installed. I believe this can be done using the FilteredEnvironment interface.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@Callback(doc = """function(side:number):boolean -- Tries to add industrial upgrade from the selected slot to industrial apiary at the given side.""")
@Callback(doc = """function(side:number):boolean -- Tries to add industrial upgrade from the selected slot to industrial apiary on the specified 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.""")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@Callback(doc = """function(side:number, slot: number):table -- Get industrial upgrade in the given slot of the industrial apiary at the given side.""")
@Callback(doc = """function(side:number, slot: number):table -- Get industrial upgrade in the given slot of the industrial apiary on the specified 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.""")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@Callback(doc = """function(side:number, slot: number):boolean -- Remove industrial upgrade from the given slot of the industrial apiary at the given side.""")
@Callback(doc = """function(side:number, slot: number):boolean -- Remove industrial upgrade from the given slot of the industrial apiary on the specified 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")
}
}
}
Original file line number Diff line number Diff line change
@@ -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
Loading