Made angel upgrade use an event.

Added missing recomputation trigger for RAM and component counts.
This commit is contained in:
Florian Nücke 2014-05-17 19:06:39 +02:00
parent 34c2fef670
commit 28a3f54f89
7 changed files with 68 additions and 6 deletions

View File

@ -0,0 +1,34 @@
package li.cil.oc.api.event;
import li.cil.oc.api.machine.Robot;
/**
* This event is fired when a robot tries to place a block and has no point of
* reference, i.e. the place would have to be placed in "thin air". Per default
* this fails (because players can't do this, either).
* <p/>
* This is primarily intended for the 'Angel Upgrade', but it might be useful
* for other upgrades, too.
*/
public class RobotPlaceInAirEvent extends RobotEvent {
private boolean isAllowed = false;
public RobotPlaceInAirEvent(Robot robot) {
super(robot);
}
/**
* Whether the placement is allowed. Defaults to <tt>false</tt>.
*/
public boolean isAllowed() {
return isAllowed;
}
/**
* Set whether the placement is allowed, can be used to allow robots to
* place blocks in thin air.
*/
public void setAllowed(boolean value) {
this.isAllowed = value;
}
}

View File

@ -42,6 +42,10 @@ public interface Robot extends ISidedInventory, Rotatable {
/**
* The number of hot-swappable component slots in this robot.
* <p/>
* <em>Note</em>: this will always be three, regardless of the number of
* installed containers. For unused slots the inventory will simply be
* empty at that slot.
*/
int containerCount();

View File

@ -19,7 +19,7 @@ import net.minecraft.item.{Item, ItemStack}
import net.minecraft.block.Block
import net.minecraftforge.oredict.OreDictionary
import scala.collection.convert.WrapAsScala._
import li.cil.oc.common.event.{ExperienceUpgradeHandler, UniversalElectricityToolHandler, RobotCommonHandler}
import li.cil.oc.common.event.{AngelUpgradeHandler, ExperienceUpgradeHandler, UniversalElectricityToolHandler, RobotCommonHandler}
class Proxy {
def preInit(e: FMLPreInitializationEvent) {
@ -96,6 +96,7 @@ class Proxy {
Recipes.init()
GameRegistry.registerCraftingHandler(CraftingHandler)
MinecraftForge.EVENT_BUS.register(AngelUpgradeHandler)
MinecraftForge.EVENT_BUS.register(RobotCommonHandler)
MinecraftForge.EVENT_BUS.register(ExperienceUpgradeHandler)
if (Mods.UniversalElectricity.isAvailable) {

View File

@ -160,6 +160,8 @@ class RobotProxy(val parent: SpecialDelegator) extends RedstoneAware with Specia
case Some((robot, owner)) =>
robot.owner = owner
robot.info.load(stack)
robot.updateInventorySize()
robot.updateMaxComponentCount()
case _ =>
}
}

View File

@ -0,0 +1,14 @@
package li.cil.oc.common.event
import li.cil.oc.api.event.RobotPlaceInAirEvent
import li.cil.oc.api
import net.minecraftforge.event.ForgeSubscribe
object AngelUpgradeHandler {
@ForgeSubscribe
def onPlaceInAir(e: RobotPlaceInAirEvent) {
val startComponents = 1 + e.robot.containerCount + e.robot.inventorySize
e.setAllowed(((1 to e.robot.containerCount) ++ (startComponents until startComponents + e.robot.componentCount)).
exists(slot => api.Items.get(e.robot.getStackInSlot(slot)) == api.Items.get("angelUpgrade")))
}
}

View File

@ -300,6 +300,7 @@ class Robot(val isRemote: Boolean) extends traits.Computer with traits.PowerInfo
updateInventorySize()
updateMaxComponentCount()
computer.architecture.recomputeMemory()
bot.load(nbt.getCompoundTag(Settings.namespace + "robot"))
if (nbt.hasKey(Settings.namespace + "owner")) {
@ -405,6 +406,7 @@ class Robot(val isRemote: Boolean) extends traits.Computer with traits.PowerInfo
super.onConnect(node)
if (node == this.node) {
node.connect(bot.node)
// There's a chance the server sends a robot tile entity to its clients
// before the tile entity's first update was called, in which case the
// component list isn't initialized (e.g. when a client triggers a chunk
@ -563,7 +565,7 @@ class Robot(val isRemote: Boolean) extends traits.Computer with traits.PowerInfo
private var updatingInventorySize = false
private def updateInventorySize() = this.synchronized(if (!updatingInventorySize) try {
def updateInventorySize() = this.synchronized(if (!updatingInventorySize) try {
updatingInventorySize = true
inventorySize = computeInventorySize()
val realSize = 1 + containerCount + inventorySize
@ -589,7 +591,7 @@ class Robot(val isRemote: Boolean) extends traits.Computer with traits.PowerInfo
updatingInventorySize = false
})
private def updateMaxComponentCount() {
def updateMaxComponentCount() {
maxComponents = computeMaxComponents()
}

View File

@ -18,6 +18,7 @@ import net.minecraftforge.event.world.BlockEvent
import net.minecraftforge.fluids.FluidRegistry
import scala.collection.convert.WrapAsScala._
import li.cil.oc.common.component.ManagedComponent
import li.cil.oc.api.event.RobotPlaceInAirEvent
class Robot(val robot: tileentity.Robot) extends ManagedComponent {
val node = api.Network.newNode(this, Visibility.Neighbors).
@ -44,7 +45,11 @@ class Robot(val robot: tileentity.Robot) extends ManagedComponent {
def player = robot.player()
def hasAngelUpgrade = (robot.containerSlots ++ robot.componentSlots).exists(slot => api.Items.get(robot.getStackInSlot(slot)) == api.Items.get("angelUpgrade"))
def canPlaceInAir = {
val event = new RobotPlaceInAirEvent(robot)
MinecraftForge.EVENT_BUS.post(event)
event.isAllowed
}
@Callback
def name(context: Context, args: Arguments): Array[AnyRef] = result(robot.name)
@ -238,7 +243,7 @@ class Robot(val robot: tileentity.Robot) extends ManagedComponent {
case Some(hit) if hit.typeOfHit == EnumMovingObjectType.TILE =>
val (bx, by, bz, hx, hy, hz) = clickParamsFromHit(hit)
player.placeBlock(robot.selectedSlot, bx, by, bz, hit.sideHit, hx, hy, hz)
case None if hasAngelUpgrade && player.closestEntity[Entity]().isEmpty =>
case None if canPlaceInAir && player.closestEntity[Entity]().isEmpty =>
val (bx, by, bz, hx, hy, hz) = clickParamsForPlace(facing)
player.placeBlock(robot.selectedSlot, bx, by, bz, facing.ordinal, hx, hy, hz)
case _ => false
@ -451,7 +456,7 @@ class Robot(val robot: tileentity.Robot) extends ManagedComponent {
val (bx, by, bz, hx, hy, hz) = clickParamsFromHit(hit)
activationResult(player.activateBlockOrUseItem(bx, by, bz, hit.sideHit, hx, hy, hz, duration))
case _ =>
(if (hasAngelUpgrade) {
(if (canPlaceInAir) {
val (bx, by, bz, hx, hy, hz) = clickParamsForPlace(facing)
if (player.placeBlock(0, bx, by, bz, facing.ordinal, hx, hy, hz))
ActivationType.ItemPlaced