mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-08 23:06:58 -04:00
Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8
Conflicts: src/main/scala/li/cil/oc/common/event/NanomachinesHandler.scala src/main/scala/li/cil/oc/common/nanomachines/provider/DisintegrationProvider.scala src/main/scala/li/cil/oc/common/nanomachines/provider/MagnetProvider.scala src/main/scala/li/cil/oc/common/nanomachines/provider/ParticleProvider.scala
This commit is contained in:
commit
2d56a45b7d
@ -12,7 +12,7 @@ import li.cil.oc.api.detail.*;
|
||||
*/
|
||||
public class API {
|
||||
public static final String ID_OWNER = "OpenComputers|Core";
|
||||
public static final String VERSION = "5.5.5";
|
||||
public static final String VERSION = "5.6.0";
|
||||
|
||||
public static DriverAPI driver = null;
|
||||
public static FileSystemAPI fileSystem = null;
|
||||
|
@ -40,8 +40,10 @@ public interface Behavior {
|
||||
* Called when this behavior becomes inactive.
|
||||
* <p/>
|
||||
* Use this to remove permanent effects.
|
||||
*
|
||||
* @param reason the reason the behavior is being disabled.
|
||||
*/
|
||||
void onDisable();
|
||||
void onDisable(DisableReason reason);
|
||||
|
||||
/**
|
||||
* Called each tick while this behavior is active.
|
||||
|
23
src/main/java/li/cil/oc/api/nanomachines/DisableReason.java
Normal file
23
src/main/java/li/cil/oc/api/nanomachines/DisableReason.java
Normal file
@ -0,0 +1,23 @@
|
||||
package li.cil.oc.api.nanomachines;
|
||||
|
||||
/**
|
||||
* Enum with reasons why a nanomachine behavior was disabled.
|
||||
* <p/>
|
||||
* This allows some more context specific behavior in a more stable fashion.
|
||||
*/
|
||||
public enum DisableReason {
|
||||
/**
|
||||
* This covers things like players logging off or the controller being reset.
|
||||
*/
|
||||
Default,
|
||||
|
||||
/**
|
||||
* Input state changed, leading to a behavior being disabled.
|
||||
*/
|
||||
InputChanged,
|
||||
|
||||
/**
|
||||
* System has run out of energy and is powering down.
|
||||
*/
|
||||
OutOfEnergy
|
||||
}
|
52
src/main/java/li/cil/oc/api/prefab/AbstractBehavior.java
Normal file
52
src/main/java/li/cil/oc/api/prefab/AbstractBehavior.java
Normal file
@ -0,0 +1,52 @@
|
||||
package li.cil.oc.api.prefab;
|
||||
|
||||
import li.cil.oc.api.nanomachines.Behavior;
|
||||
import li.cil.oc.api.nanomachines.DisableReason;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
/**
|
||||
* Base class for behaviors, mostly useful to have less cluttered classes when
|
||||
* you only need one or two of the methods in the interface.
|
||||
* <p/>
|
||||
* This implementation will also store the player the behavior was created for.
|
||||
*/
|
||||
public abstract class AbstractBehavior implements Behavior {
|
||||
/**
|
||||
* The player this behavior was created for.
|
||||
*/
|
||||
public final EntityPlayer player;
|
||||
|
||||
/**
|
||||
* Pass along the player the behavior was created for here to have it stored
|
||||
* for later use.
|
||||
*
|
||||
* @param player the player the behavior was created for.
|
||||
*/
|
||||
protected AbstractBehavior(EntityPlayer player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this if you do not need the player reference in your implementation.
|
||||
*/
|
||||
protected AbstractBehavior() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameHint() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable(DisableReason reason) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
}
|
||||
}
|
74
src/main/java/li/cil/oc/api/prefab/AbstractProvider.java
Normal file
74
src/main/java/li/cil/oc/api/prefab/AbstractProvider.java
Normal file
@ -0,0 +1,74 @@
|
||||
package li.cil.oc.api.prefab;
|
||||
|
||||
import li.cil.oc.api.nanomachines.Behavior;
|
||||
import li.cil.oc.api.nanomachines.BehaviorProvider;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
/**
|
||||
* Example base implementation of nanomachine behavior provider.
|
||||
* <p/>
|
||||
* This class takes care of handling the unique identifier used to tell
|
||||
* if a behavior is its own when loading from NBT.
|
||||
*/
|
||||
public abstract class AbstractProvider implements BehaviorProvider {
|
||||
/**
|
||||
* Unique identifier used to tell if a behavior is ours when asked to load it.
|
||||
*/
|
||||
protected final String id;
|
||||
|
||||
/**
|
||||
* For the ID passed in here, it is suggested to use a one-time generated
|
||||
* UUID that is hard-coded into your provider implementation. Take care to
|
||||
* use a different one for each provider you create!
|
||||
*
|
||||
* @param id the unique identifier for this provider.
|
||||
*/
|
||||
protected AbstractProvider(String id) {
|
||||
if (id == null) throw new NullPointerException("id must not be null");
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when saving a behavior created using this behavior to NBT.
|
||||
* <p/>
|
||||
* The ID will already have been written, don't overwrite it. Store
|
||||
* any additional data you need to restore the behavior here, if any.
|
||||
*
|
||||
* @param behavior the behavior to persist.
|
||||
* @param nbt the NBT tag to persist it to.
|
||||
*/
|
||||
protected void writeBehaviorToNBT(Behavior behavior, NBTTagCompound nbt) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when loading a behavior from NBT.
|
||||
* <p/>
|
||||
* Use the data written in {@link #writeBehaviorToNBT} to restore the behavior
|
||||
* to its previous state, then return it.
|
||||
*
|
||||
* @param player the player to restore the behavior for.
|
||||
* @param nbt the NBT tag to load restore the behavior from.
|
||||
* @return the restored behavior.
|
||||
*/
|
||||
protected abstract Behavior readBehaviorFromNBT(EntityPlayer player, NBTTagCompound nbt);
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT(Behavior behavior) {
|
||||
NBTTagCompound nbt = new NBTTagCompound();
|
||||
nbt.setString("provider", id);
|
||||
writeBehaviorToNBT(behavior, nbt);
|
||||
return nbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Behavior readFromNBT(EntityPlayer player, NBTTagCompound nbt) {
|
||||
if (id.equals(nbt.getString("provider"))) {
|
||||
return readBehaviorFromNBT(player, nbt);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -1023,16 +1023,40 @@ opencomputers {
|
||||
# Radius in blocks of the disintegration behavior for each active input.
|
||||
disintegrationRange: 1
|
||||
|
||||
# Blacklisted potions, i.e. potions that won't be used for the potion
|
||||
# Whitelisted potions, i.e. potions that will be used for the potion
|
||||
# behaviors nanomachines may trigger. This can contain strings or numbers.
|
||||
# In the case of strings, it has to be the internal name of the potion,
|
||||
# in case of a number it has to be the potion ID.
|
||||
potionBlacklist: [
|
||||
"potion.heal",
|
||||
"potion.regeneration",
|
||||
"potion.invisibility",
|
||||
"potion.saturation"
|
||||
# in case of a number it has to be the potion ID. Add any potion effects
|
||||
# to make use of here, since they will all be disabled by default.
|
||||
potionWhitelist: [
|
||||
"potion.moveSpeed",
|
||||
"potion.digSpeed",
|
||||
"potion.damageBoost",
|
||||
"potion.jump",
|
||||
"potion.resistance",
|
||||
"potion.fireResistance",
|
||||
"potion.waterBreathing",
|
||||
"potion.nightVision",
|
||||
"potion.absorption",
|
||||
|
||||
"potion.blindness",
|
||||
"potion.confusion",
|
||||
"potion.digSlowDown",
|
||||
"potion.harm",
|
||||
"potion.hunger",
|
||||
"potion.moveSlowdown",
|
||||
"potion.poison",
|
||||
"potion.weakness",
|
||||
"potion.wither"
|
||||
]
|
||||
|
||||
# How much damage the hungry behavior should deal to the player when the
|
||||
# nanomachine controller runs out of energy.
|
||||
hungryDamage: 5
|
||||
|
||||
# How much energy the hungry behavior should restore when damaging the
|
||||
# player.
|
||||
hungryEnergyRestored: 50
|
||||
}
|
||||
|
||||
# 3D printer related stuff.
|
||||
|
@ -451,6 +451,15 @@ achievement.oc.transistor.desc=Create a Transistor to get started. Then listen t
|
||||
achievement.oc.wirelessNetworkCard=Signals
|
||||
achievement.oc.wirelessNetworkCard.desc=Time to go where no packet has gone before.
|
||||
|
||||
# Death messages. Note that the number of entries here must match the number
|
||||
# set in the actual damage source in code.
|
||||
death.attack.oc.nanomachinesOverload.1=%s got too greedy.
|
||||
death.attack.oc.nanomachinesOverload.2=%s had a nervous breakdown.
|
||||
death.attack.oc.nanomachinesOverload.3=%s's nanomachines went out of control.
|
||||
death.attack.oc.nanomachinesHungry.1=%s was eaten by nanomachines.
|
||||
death.attack.oc.nanomachinesHungry.2=%s didn't keep their nanomachines fed.
|
||||
death.attack.oc.nanomachinesHungry.3=%s has been digested.
|
||||
|
||||
# NEI Integration
|
||||
nei.options.inventory.oredict=Show OreDictionary names
|
||||
nei.options.inventory.oredict.true=True
|
||||
|
@ -361,6 +361,9 @@ class Settings(val config: Config) {
|
||||
val nanomachineMagnetRange = config.getDouble("nanomachines.magnetRange") max 0
|
||||
val nanomachineDisintegrationRange = config.getInt("nanomachines.disintegrationRange") max 0
|
||||
val nanomachinePotionBlacklist = config.getAnyRefList("nanomachines.potionBlacklist")
|
||||
val nanomachinePotionWhitelist = config.getAnyRefList("nanomachines.potionWhitelist")
|
||||
val nanomachinesHungryDamage = config.getDouble("nanomachines.hungryDamage").toFloat max 0
|
||||
val nanomachinesHungryEnergyRestored = config.getDouble("nanomachines.hungryEnergyRestored") max 0
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// printer
|
||||
|
@ -13,7 +13,7 @@ import li.cil.oc.client.renderer.entity.DroneRenderer
|
||||
import li.cil.oc.client.renderer.tileentity._
|
||||
import li.cil.oc.common.component.TextBuffer
|
||||
import li.cil.oc.common.entity.Drone
|
||||
import li.cil.oc.common.event.NanomachinesEventHandler
|
||||
import li.cil.oc.common.event.NanomachinesHandler
|
||||
import li.cil.oc.common.init.Items
|
||||
import li.cil.oc.common.item.traits.Delegate
|
||||
import li.cil.oc.common.tileentity
|
||||
@ -81,7 +81,7 @@ private[oc] class Proxy extends CommonProxy {
|
||||
ClientRegistry.registerKeyBinding(KeyBindings.clipboardPaste)
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(HighlightRenderer)
|
||||
MinecraftForge.EVENT_BUS.register(NanomachinesEventHandler.Client)
|
||||
MinecraftForge.EVENT_BUS.register(NanomachinesHandler.Client)
|
||||
MinecraftForge.EVENT_BUS.register(PetRenderer)
|
||||
MinecraftForge.EVENT_BUS.register(ServerRack)
|
||||
MinecraftForge.EVENT_BUS.register(Sound)
|
||||
|
@ -8,6 +8,7 @@ import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.nanomachines.Controller
|
||||
import li.cil.oc.client.Textures
|
||||
import li.cil.oc.common.EventHandler
|
||||
import li.cil.oc.common.nanomachines.ControllerImpl
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.gui.ScaledResolution
|
||||
@ -19,8 +20,9 @@ import net.minecraftforge.client.event.RenderGameOverlayEvent
|
||||
import net.minecraftforge.event.entity.living.LivingEvent
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
|
||||
import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedOutEvent
|
||||
|
||||
object NanomachinesEventHandler {
|
||||
object NanomachinesHandler {
|
||||
|
||||
object Client {
|
||||
@SubscribeEvent
|
||||
@ -141,6 +143,16 @@ object NanomachinesEventHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
def onPlayerDisconnect(e: PlayerLoggedOutEvent): Unit = {
|
||||
api.Nanomachines.getController(e.player) match {
|
||||
case controller: ControllerImpl =>
|
||||
// Wait a tick because saving is done after this event.
|
||||
EventHandler.schedule(() => api.Nanomachines.uninstallController(e.player))
|
||||
case _ => // Not a player with nanomachines.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -3,10 +3,13 @@ package li.cil.oc.common.item
|
||||
import li.cil.oc.api
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.EnumAction
|
||||
import net.minecraft.item.EnumRarity
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.world.World
|
||||
|
||||
class Nanomachines(val parent: Delegator) extends traits.Delegate {
|
||||
override def rarity(stack: ItemStack): EnumRarity = EnumRarity.UNCOMMON
|
||||
|
||||
override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ItemStack = {
|
||||
if (!api.Nanomachines.hasController(player)) {
|
||||
player.setItemInUse(stack, getMaxItemUseDuration(stack))
|
||||
|
@ -9,8 +9,10 @@ import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.nanomachines.Behavior
|
||||
import li.cil.oc.api.nanomachines.Controller
|
||||
import li.cil.oc.api.nanomachines.DisableReason
|
||||
import li.cil.oc.api.network.Packet
|
||||
import li.cil.oc.api.network.WirelessEndpoint
|
||||
import li.cil.oc.integration.util.DamageSourceWithRandomCause
|
||||
import li.cil.oc.server.PacketSender
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
@ -33,6 +35,10 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE
|
||||
final val MaxSenderDistance = 2f
|
||||
final val FullSyncInterval = 20 * 60
|
||||
|
||||
final val OverloadDamage = new DamageSourceWithRandomCause("oc.nanomachinesOverload", 3).
|
||||
setDamageBypassesArmor().
|
||||
setDamageIsAbsolute()
|
||||
|
||||
var uuid = UUID.randomUUID.toString
|
||||
var responsePort = 0
|
||||
var storedEnergy = Settings.get.bufferNanomachines * 0.25
|
||||
@ -52,7 +58,7 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE
|
||||
override def z: Int = BlockPosition(player).z
|
||||
|
||||
override def receivePacket(packet: Packet, sender: WirelessEndpoint): Unit = {
|
||||
if (getLocalBuffer > 0) {
|
||||
if (getLocalBuffer > 0 && !player.isDead) {
|
||||
val (dx, dy, dz) = ((sender.x + 0.5) - player.posX, (sender.y + 0.5) - player.posY, (sender.z + 0.5) - player.posZ)
|
||||
val dSquared = dx * dx + dy * dy + dz * dz
|
||||
if (dSquared < MaxSenderDistance * MaxSenderDistance) packet.data.headOption match {
|
||||
@ -155,7 +161,7 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE
|
||||
}
|
||||
|
||||
override def getActiveBehaviors: lang.Iterable[Behavior] = configuration.synchronized {
|
||||
cleanActiveBehaviors()
|
||||
cleanActiveBehaviors(DisableReason.InputChanged)
|
||||
activeBehaviors
|
||||
}
|
||||
|
||||
@ -180,6 +186,10 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def update(): Unit = {
|
||||
if (player.isDead) {
|
||||
return
|
||||
}
|
||||
|
||||
if (isServer) {
|
||||
api.Network.updateWirelessNetwork(this)
|
||||
}
|
||||
@ -189,12 +199,15 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE
|
||||
return
|
||||
}
|
||||
|
||||
val hasPower = getLocalBuffer > 0 || Settings.get.ignorePower
|
||||
var hasPower = getLocalBuffer > 0 || Settings.get.ignorePower
|
||||
lazy val active = getActiveBehaviors.toIterable // Wrap once.
|
||||
lazy val activeInputs = configuration.triggers.count(_.isActive)
|
||||
|
||||
if (hasPower != hadPower) {
|
||||
if (!hasPower) active.foreach(_.onDisable())
|
||||
if (!hasPower) {
|
||||
active.foreach(_.onDisable(DisableReason.OutOfEnergy)) // This may change our energy buffer.
|
||||
hasPower = getLocalBuffer > 0 || Settings.get.ignorePower
|
||||
}
|
||||
else active.foreach(_.onEnable())
|
||||
}
|
||||
|
||||
@ -209,8 +222,7 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE
|
||||
|
||||
val overload = activeInputs - getSafeInputCount
|
||||
if (!player.capabilities.isCreativeMode && overload > 0 && player.getEntityWorld.getTotalWorldTime % 20 == 0) {
|
||||
player.setHealth(player.getHealth - overload)
|
||||
player.performHurtAnimation()
|
||||
player.attackEntityFrom(OverloadDamage, overload)
|
||||
}
|
||||
}
|
||||
|
||||
@ -246,6 +258,7 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE
|
||||
configuration.triggers(index).isActive = false
|
||||
activeBehaviorsDirty = true
|
||||
}
|
||||
cleanActiveBehaviors(DisableReason.Default)
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,7 +266,6 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE
|
||||
reset()
|
||||
if (isServer) {
|
||||
api.Network.leaveWirelessNetwork(this)
|
||||
PacketSender.sendNanomachineConfiguration(player)
|
||||
}
|
||||
}
|
||||
|
||||
@ -280,7 +292,7 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE
|
||||
|
||||
private def isServer = !isClient
|
||||
|
||||
private def cleanActiveBehaviors(): Unit = {
|
||||
private def cleanActiveBehaviors(reason: DisableReason): Unit = {
|
||||
if (activeBehaviorsDirty) {
|
||||
configuration.synchronized(if (activeBehaviorsDirty) {
|
||||
val newBehaviors = configuration.behaviors.filter(_.isActive).map(_.behavior)
|
||||
@ -290,7 +302,7 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE
|
||||
activeBehaviors ++= newBehaviors
|
||||
activeBehaviorsDirty = false
|
||||
addedBehaviors.foreach(_.onEnable())
|
||||
removedBehaviors.foreach(_.onDisable())
|
||||
removedBehaviors.foreach(_.onDisable(reason))
|
||||
|
||||
if (isServer) {
|
||||
PacketSender.sendNanomachineInputs(player)
|
||||
|
@ -4,6 +4,7 @@ import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.nanomachines.BehaviorProvider
|
||||
import li.cil.oc.api.nanomachines.Controller
|
||||
import li.cil.oc.server.PacketSender
|
||||
import li.cil.oc.util.PlayerUtils
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
|
||||
@ -41,9 +42,12 @@ object Nanomachines extends api.detail.NanomachinesAPI {
|
||||
override def uninstallController(player: EntityPlayer): Unit = {
|
||||
getController(player) match {
|
||||
case controller: ControllerImpl =>
|
||||
PlayerUtils.persistedData(player).removeTag(Settings.namespace + "hasNanomachines")
|
||||
controllers(player) -= player
|
||||
controller.dispose()
|
||||
controllers(player) -= player
|
||||
PlayerUtils.persistedData(player).removeTag(Settings.namespace + "hasNanomachines")
|
||||
if (!player.getEntityWorld.isRemote) {
|
||||
PacketSender.sendNanomachineConfiguration(player)
|
||||
}
|
||||
case _ => // Doesn't have one anyway.
|
||||
}
|
||||
}
|
||||
|
@ -55,8 +55,8 @@ class NeuralNetwork(controller: ControllerImpl) extends Persistable {
|
||||
val rng = new Random(controller.player.getEntityWorld.rand.nextInt())
|
||||
|
||||
def connect[Sink <: ConnectorNeuron, Source <: Neuron](sinks: Iterable[Sink], sources: mutable.ArrayBuffer[Source]): Unit = {
|
||||
val sinkPool = sinks.toBuffer
|
||||
rng.shuffle(sinkPool)
|
||||
// Shuffle sink list to give each entry the same chance.
|
||||
val sinkPool = rng.shuffle(sinks.toBuffer)
|
||||
for (sink <- sinkPool if sources.nonEmpty) {
|
||||
for (n <- 0 to rng.nextInt(Settings.get.nanomachineMaxInputs) if sources.nonEmpty) {
|
||||
val sourceIndex = rng.nextInt(sources.length)
|
||||
@ -65,10 +65,6 @@ class NeuralNetwork(controller: ControllerImpl) extends Persistable {
|
||||
}
|
||||
}
|
||||
|
||||
// Shuffle behavior and connector list to give each entry the same chance.
|
||||
rng.shuffle(connectors)
|
||||
rng.shuffle(behaviors)
|
||||
|
||||
// Connect connectors to triggers, then behaviors to connectors and/or remaining triggers.
|
||||
val sourcePool = mutable.ArrayBuffer.fill(Settings.get.nanomachineMaxOutputs)(triggers.map(_.asInstanceOf[Neuron])).flatten
|
||||
connect(connectors, sourcePool)
|
||||
|
@ -1,7 +1,10 @@
|
||||
package li.cil.oc.common.nanomachines.provider
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.nanomachines.DisableReason
|
||||
import li.cil.oc.api.prefab.AbstractBehavior
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.ExtendedWorld._
|
||||
import net.minecraft.block.Block
|
||||
@ -17,20 +20,18 @@ import net.minecraftforge.fml.common.eventhandler.Event
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
object DisintegrationProvider extends SimpleProvider {
|
||||
final val Id = "c4e7e3c2-8069-4fbb-b08e-74b1bddcdfe7"
|
||||
object DisintegrationProvider extends ScalaProvider("c4e7e3c2-8069-4fbb-b08e-74b1bddcdfe7") {
|
||||
override def createScalaBehaviors(player: EntityPlayer) = Iterable(new DisintegrationBehavior(player))
|
||||
|
||||
override def doCreateBehaviors(player: EntityPlayer) = Iterable(new DisintegrationBehavior(player))
|
||||
override def readBehaviorFromNBT(player: EntityPlayer, nbt: NBTTagCompound) = new DisintegrationBehavior(player)
|
||||
|
||||
override def doReadFromNBT(player: EntityPlayer, nbt: NBTTagCompound) = new DisintegrationBehavior(player)
|
||||
|
||||
class DisintegrationBehavior(player: EntityPlayer) extends SimpleBehavior(player) {
|
||||
class DisintegrationBehavior(player: EntityPlayer) extends AbstractBehavior(player) {
|
||||
var breakingMap = mutable.Map.empty[BlockPosition, SlowBreakInfo]
|
||||
var breakingMapNew = mutable.Map.empty[BlockPosition, SlowBreakInfo]
|
||||
|
||||
// Note: intentionally not overriding getNameHint. Gotta find this one manually!
|
||||
|
||||
override def onDisable(): Unit = {
|
||||
override def onDisable(reason: DisableReason): Unit = {
|
||||
val world = player.getEntityWorld
|
||||
for (pos <- breakingMap.keys) {
|
||||
world.destroyBlockInWorldPartially(pos.hashCode(), pos, -1)
|
||||
|
@ -0,0 +1,32 @@
|
||||
package li.cil.oc.common.nanomachines.provider
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.nanomachines.Behavior
|
||||
import li.cil.oc.api.nanomachines.DisableReason
|
||||
import li.cil.oc.api.prefab.AbstractBehavior
|
||||
import li.cil.oc.integration.util.DamageSourceWithRandomCause
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
object HungryProvider extends ScalaProvider("") {
|
||||
final val FillCount = 10 // Create a bunch of these to have a higher chance of one being picked / available.
|
||||
|
||||
final val HungryDamage = new DamageSourceWithRandomCause("oc.nanomachinesHungry", 3).
|
||||
setDamageBypassesArmor().
|
||||
setDamageIsAbsolute()
|
||||
|
||||
override def createScalaBehaviors(player: EntityPlayer): Iterable[Behavior] = Iterable.fill(FillCount)(new HungryBehavior(player))
|
||||
|
||||
override protected def readBehaviorFromNBT(player: EntityPlayer, nbt: NBTTagCompound): Behavior = new HungryBehavior(player)
|
||||
|
||||
class HungryBehavior(player: EntityPlayer) extends AbstractBehavior(player) {
|
||||
override def onDisable(reason: DisableReason): Unit = {
|
||||
if (reason == DisableReason.OutOfEnergy) {
|
||||
player.attackEntityFrom(HungryDamage, Settings.get.nanomachinesHungryDamage)
|
||||
api.Nanomachines.getController(player).changeBuffer(Settings.get.nanomachinesHungryEnergyRestored)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -2,6 +2,7 @@ package li.cil.oc.common.nanomachines.provider
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.prefab.AbstractBehavior
|
||||
import net.minecraft.entity.item.EntityItem
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
@ -9,15 +10,12 @@ import net.minecraft.util.Vec3
|
||||
|
||||
import scala.collection.convert.WrapAsScala._
|
||||
|
||||
object MagnetProvider extends SimpleProvider {
|
||||
// One-time generated UUID to identify our behaviors.
|
||||
final val Id = "9324d5ec-71f1-41c2-b51c-406e527668fc"
|
||||
object MagnetProvider extends ScalaProvider("9324d5ec-71f1-41c2-b51c-406e527668fc") {
|
||||
override def createScalaBehaviors(player: EntityPlayer) = Iterable(new MagnetBehavior(player))
|
||||
|
||||
override def doCreateBehaviors(player: EntityPlayer) = Iterable(new MagnetBehavior(player))
|
||||
override def readBehaviorFromNBT(player: EntityPlayer, nbt: NBTTagCompound) = new MagnetBehavior(player)
|
||||
|
||||
override def doReadFromNBT(player: EntityPlayer, nbt: NBTTagCompound) = new MagnetBehavior(player)
|
||||
|
||||
class MagnetBehavior(player: EntityPlayer) extends SimpleBehavior(player) {
|
||||
class MagnetBehavior(player: EntityPlayer) extends AbstractBehavior(player) {
|
||||
override def getNameHint = "magnet"
|
||||
|
||||
override def update(): Unit = {
|
||||
|
@ -2,14 +2,13 @@ package li.cil.oc.common.nanomachines.provider
|
||||
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.nanomachines.Behavior
|
||||
import li.cil.oc.api.prefab.AbstractBehavior
|
||||
import li.cil.oc.util.PlayerUtils
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.util.EnumParticleTypes
|
||||
|
||||
object ParticleProvider extends SimpleProvider {
|
||||
final val Id = "b48c4bbd-51bb-4915-9367-16cff3220e4b"
|
||||
|
||||
object ParticleProvider extends ScalaProvider("b48c4bbd-51bb-4915-9367-16cff3220e4b") {
|
||||
final val ParticleTypes = Array(
|
||||
EnumParticleTypes.FIREWORKS_SPARK,
|
||||
EnumParticleTypes.TOWN_AURA,
|
||||
@ -26,9 +25,9 @@ object ParticleProvider extends SimpleProvider {
|
||||
EnumParticleTypes.VILLAGER_HAPPY
|
||||
)
|
||||
|
||||
override def doCreateBehaviors(player: EntityPlayer): Iterable[Behavior] = ParticleTypes.map(new ParticleBehavior(_, player))
|
||||
override def createScalaBehaviors(player: EntityPlayer): Iterable[Behavior] = ParticleTypes.map(new ParticleBehavior(_, player))
|
||||
|
||||
override def doWriteToNBT(behavior: Behavior, nbt: NBTTagCompound): Unit = {
|
||||
override def writeBehaviorToNBT(behavior: Behavior, nbt: NBTTagCompound): Unit = {
|
||||
behavior match {
|
||||
case particles: ParticleBehavior =>
|
||||
nbt.setInteger("effectName", particles.effectType.getParticleID)
|
||||
@ -36,12 +35,12 @@ object ParticleProvider extends SimpleProvider {
|
||||
}
|
||||
}
|
||||
|
||||
override def doReadFromNBT(player: EntityPlayer, nbt: NBTTagCompound): Behavior = {
|
||||
override def readBehaviorFromNBT(player: EntityPlayer, nbt: NBTTagCompound): Behavior = {
|
||||
val effectType = EnumParticleTypes.getParticleFromId(nbt.getInteger("effectName"))
|
||||
new ParticleBehavior(effectType, player)
|
||||
}
|
||||
|
||||
class ParticleBehavior(var effectType: EnumParticleTypes, player: EntityPlayer) extends SimpleBehavior(player) {
|
||||
class ParticleBehavior(var effectType: EnumParticleTypes, player: EntityPlayer) extends AbstractBehavior(player) {
|
||||
override def getNameHint = "particles"
|
||||
|
||||
override def update(): Unit = {
|
||||
|
@ -3,6 +3,8 @@ package li.cil.oc.common.nanomachines.provider
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.nanomachines.Behavior
|
||||
import li.cil.oc.api.nanomachines.DisableReason
|
||||
import li.cil.oc.api.prefab.AbstractBehavior
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.potion.Potion
|
||||
@ -10,23 +12,27 @@ import net.minecraft.potion.PotionEffect
|
||||
|
||||
import scala.collection.convert.WrapAsScala._
|
||||
|
||||
object PotionProvider extends SimpleProvider {
|
||||
final val Id = "c29e4eec-5a46-479a-9b3d-ad0f06da784a"
|
||||
|
||||
object PotionProvider extends ScalaProvider("c29e4eec-5a46-479a-9b3d-ad0f06da784a") {
|
||||
// Lazy to give other mods a chance to register their potions.
|
||||
lazy val PotionBlacklist = Settings.get.nanomachinePotionBlacklist.map {
|
||||
case name: String => Potion.potionTypes.find(p => p != null && p.getName == name)
|
||||
case id: java.lang.Number if id.intValue() >= 0 && id.intValue() < Potion.potionTypes.length => Option(Potion.potionTypes(id.intValue()))
|
||||
case _ => None
|
||||
}.collect {
|
||||
case Some(potion) => potion
|
||||
}.toSet
|
||||
lazy val PotionWhitelist = filterPotions(Settings.get.nanomachinePotionWhitelist)
|
||||
|
||||
override def doCreateBehaviors(player: EntityPlayer) = {
|
||||
Potion.potionTypes.filter(_ != null).filterNot(PotionBlacklist.contains).map(new PotionBehavior(_, player))
|
||||
def filterPotions[T](list: Iterable[T]) = {
|
||||
list.map {
|
||||
case name: String => Potion.potionTypes.find(p => p != null && p.getName == name)
|
||||
case id: java.lang.Number if id.intValue() >= 0 && id.intValue() < Potion.potionTypes.length => Option(Potion.potionTypes(id.intValue()))
|
||||
case _ => None
|
||||
}.collect {
|
||||
case Some(potion) => potion
|
||||
}.toSet
|
||||
}
|
||||
|
||||
override def doWriteToNBT(behavior: Behavior, nbt: NBTTagCompound): Unit = {
|
||||
def isPotionEligible(potion: Potion) = potion != null && PotionWhitelist.contains(potion)
|
||||
|
||||
override def createScalaBehaviors(player: EntityPlayer) = {
|
||||
Potion.potionTypes.filter(isPotionEligible).map(new PotionBehavior(_, player))
|
||||
}
|
||||
|
||||
override def writeBehaviorToNBT(behavior: Behavior, nbt: NBTTagCompound): Unit = {
|
||||
behavior match {
|
||||
case potionBehavior: PotionBehavior =>
|
||||
nbt.setInteger("potionId", potionBehavior.potion.id)
|
||||
@ -34,21 +40,19 @@ object PotionProvider extends SimpleProvider {
|
||||
}
|
||||
}
|
||||
|
||||
override def doReadFromNBT(player: EntityPlayer, nbt: NBTTagCompound) = {
|
||||
override def readBehaviorFromNBT(player: EntityPlayer, nbt: NBTTagCompound) = {
|
||||
val potionId = nbt.getInteger("potionId")
|
||||
new PotionBehavior(Potion.potionTypes(potionId), player)
|
||||
}
|
||||
|
||||
class PotionBehavior(val potion: Potion, player: EntityPlayer) extends SimpleBehavior(player) {
|
||||
class PotionBehavior(val potion: Potion, player: EntityPlayer) extends AbstractBehavior(player) {
|
||||
final val Duration = 600
|
||||
|
||||
def amplifier(player: EntityPlayer) = api.Nanomachines.getController(player).getInputCount(this) - 1
|
||||
|
||||
override def getNameHint: String = potion.getName.stripPrefix("potion.")
|
||||
|
||||
override def onEnable(): Unit = {}
|
||||
|
||||
override def onDisable(): Unit = {
|
||||
override def onDisable(reason: DisableReason): Unit = {
|
||||
player.removePotionEffect(potion.id)
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
package li.cil.oc.common.nanomachines.provider
|
||||
|
||||
import li.cil.oc.api.nanomachines.Behavior
|
||||
import li.cil.oc.api.prefab.AbstractProvider
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
|
||||
import scala.collection.convert.WrapAsJava._
|
||||
|
||||
abstract class ScalaProvider(id: String) extends AbstractProvider(id) {
|
||||
def createScalaBehaviors(player: EntityPlayer): Iterable[Behavior]
|
||||
|
||||
override def createBehaviors(player: EntityPlayer): java.lang.Iterable[Behavior] = asJavaIterable(createScalaBehaviors(player))
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package li.cil.oc.common.nanomachines.provider
|
||||
|
||||
import li.cil.oc.api.nanomachines.Behavior
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
|
||||
class SimpleBehavior(val player: EntityPlayer) extends Behavior {
|
||||
override def getNameHint: String = null
|
||||
|
||||
override def onEnable(): Unit = {}
|
||||
|
||||
override def onDisable(): Unit = {}
|
||||
|
||||
override def update(): Unit = {}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package li.cil.oc.common.nanomachines.provider
|
||||
|
||||
import li.cil.oc.api.nanomachines.Behavior
|
||||
import li.cil.oc.api.nanomachines.BehaviorProvider
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
import scala.collection.convert.WrapAsJava._
|
||||
|
||||
abstract class SimpleProvider extends BehaviorProvider {
|
||||
// One-time generated UUID to identify our behaviors.
|
||||
def Id: String
|
||||
|
||||
def doCreateBehaviors(player: EntityPlayer): Iterable[Behavior]
|
||||
|
||||
def doWriteToNBT(behavior: Behavior, nbt: NBTTagCompound): Unit = {}
|
||||
|
||||
def doReadFromNBT(player: EntityPlayer, nbt: NBTTagCompound): Behavior
|
||||
|
||||
override def createBehaviors(player: EntityPlayer): java.lang.Iterable[Behavior] = asJavaIterable(doCreateBehaviors(player))
|
||||
|
||||
override def writeToNBT(behavior: Behavior): NBTTagCompound = {
|
||||
val nbt = new NBTTagCompound()
|
||||
nbt.setString("provider", Id)
|
||||
doWriteToNBT(behavior: Behavior, nbt: NBTTagCompound)
|
||||
nbt
|
||||
}
|
||||
|
||||
override def readFromNBT(player: EntityPlayer, nbt: NBTTagCompound): Behavior = {
|
||||
if (nbt.getString("provider") == Id) {
|
||||
doReadFromNBT(player, nbt)
|
||||
}
|
||||
else null
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ import li.cil.oc.common.item.Delegator
|
||||
import li.cil.oc.common.item.RedstoneCard
|
||||
import li.cil.oc.common.item.Tablet
|
||||
import li.cil.oc.common.nanomachines.provider.DisintegrationProvider
|
||||
import li.cil.oc.common.nanomachines.provider.HungryProvider
|
||||
import li.cil.oc.common.nanomachines.provider.MagnetProvider
|
||||
import li.cil.oc.common.nanomachines.provider.ParticleProvider
|
||||
import li.cil.oc.common.nanomachines.provider.PotionProvider
|
||||
@ -72,6 +73,7 @@ object ModOpenComputers extends ModProxy {
|
||||
ForgeChunkManager.setForcedChunkLoadingCallback(OpenComputers, ChunkloaderUpgradeHandler)
|
||||
|
||||
FMLCommonHandler.instance.bus.register(EventHandler)
|
||||
FMLCommonHandler.instance.bus.register(NanomachinesHandler.Common)
|
||||
FMLCommonHandler.instance.bus.register(SimpleComponentTickHandler.Instance)
|
||||
FMLCommonHandler.instance.bus.register(Tablet)
|
||||
|
||||
@ -84,7 +86,7 @@ object ModOpenComputers extends ModProxy {
|
||||
MinecraftForge.EVENT_BUS.register(GeolyzerHandler)
|
||||
MinecraftForge.EVENT_BUS.register(HoverBootsHandler)
|
||||
MinecraftForge.EVENT_BUS.register(Loot)
|
||||
MinecraftForge.EVENT_BUS.register(NanomachinesEventHandler.Common)
|
||||
MinecraftForge.EVENT_BUS.register(NanomachinesHandler.Common)
|
||||
MinecraftForge.EVENT_BUS.register(RobotCommonHandler)
|
||||
MinecraftForge.EVENT_BUS.register(SaveHandler)
|
||||
MinecraftForge.EVENT_BUS.register(Tablet)
|
||||
@ -253,6 +255,7 @@ object ModOpenComputers extends ModProxy {
|
||||
api.Manual.addTab(new ItemStackTabIconRenderer(api.Items.get("cpu1").createItemStack(1)), "oc:gui.Manual.Items", "%LANGUAGE%/item/index.md")
|
||||
|
||||
api.Nanomachines.addProvider(DisintegrationProvider)
|
||||
api.Nanomachines.addProvider(HungryProvider)
|
||||
api.Nanomachines.addProvider(ParticleProvider)
|
||||
api.Nanomachines.addProvider(PotionProvider)
|
||||
api.Nanomachines.addProvider(MagnetProvider)
|
||||
|
@ -0,0 +1,19 @@
|
||||
package li.cil.oc.integration.util
|
||||
|
||||
import net.minecraft.entity.EntityLivingBase
|
||||
import net.minecraft.util.ChatComponentTranslation
|
||||
import net.minecraft.util.DamageSource
|
||||
import net.minecraft.util.IChatComponent
|
||||
import net.minecraft.util.StatCollector
|
||||
|
||||
class DamageSourceWithRandomCause(name: String, numCauses: Int) extends DamageSource(name) {
|
||||
override def getDeathMessage(damagee: EntityLivingBase): IChatComponent = {
|
||||
val damager = damagee.func_94060_bK
|
||||
val format = "death.attack." + damageType + "." + (damagee.worldObj.rand.nextInt(numCauses) + 1)
|
||||
val withCauseFormat = format + ".player"
|
||||
if (damager != null && StatCollector.canTranslate(withCauseFormat))
|
||||
new ChatComponentTranslation(withCauseFormat, damagee.getDisplayName, damager.getDisplayName)
|
||||
else
|
||||
new ChatComponentTranslation(format, damagee.getDisplayName)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user