mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-13 09:18:05 -04:00
Added a reason parameter to onDisable.
Added new behavior. Using DamageSources now.
This commit is contained in:
parent
155bf0702c
commit
aef4165da5
@ -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.6";
|
||||
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
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -42,7 +43,7 @@ public abstract class AbstractBehavior implements Behavior {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
public void onDisable(DisableReason reason) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1036,7 +1036,6 @@ opencomputers {
|
||||
"potion.fireResistance",
|
||||
"potion.waterBreathing",
|
||||
"potion.nightVision",
|
||||
"potion.healthBoost",
|
||||
"potion.absorption",
|
||||
|
||||
"potion.blindness",
|
||||
@ -1049,6 +1048,14 @@ opencomputers {
|
||||
"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
|
||||
|
@ -360,6 +360,8 @@ class Settings(val config: Config) {
|
||||
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
|
||||
|
@ -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._
|
||||
@ -32,6 +34,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
|
||||
@ -154,7 +160,7 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE
|
||||
}
|
||||
|
||||
override def getActiveBehaviors: lang.Iterable[Behavior] = configuration.synchronized {
|
||||
cleanActiveBehaviors()
|
||||
cleanActiveBehaviors(DisableReason.InputChanged)
|
||||
activeBehaviors
|
||||
}
|
||||
|
||||
@ -192,12 +198,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())
|
||||
}
|
||||
|
||||
@ -212,8 +221,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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -249,7 +257,7 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE
|
||||
configuration.triggers(index).isActive = false
|
||||
activeBehaviorsDirty = true
|
||||
}
|
||||
cleanActiveBehaviors()
|
||||
cleanActiveBehaviors(DisableReason.Default)
|
||||
}
|
||||
}
|
||||
|
||||
@ -283,7 +291,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)
|
||||
@ -293,7 +301,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)
|
||||
|
@ -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)
|
||||
|
@ -3,6 +3,7 @@ package li.cil.oc.common.nanomachines.provider
|
||||
import cpw.mods.fml.common.eventhandler.Event
|
||||
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._
|
||||
@ -28,7 +29,7 @@ object DisintegrationProvider extends ScalaProvider("c4e7e3c2-8069-4fbb-b08e-74b
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,7 @@ 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
|
||||
@ -51,9 +52,7 @@ object PotionProvider extends ScalaProvider("c29e4eec-5a46-479a-9b3d-ad0f06da784
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,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
|
||||
@ -253,6 +254,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 func_151519_b(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.func_145748_c_, damager.func_145748_c_)
|
||||
else
|
||||
new ChatComponentTranslation(format, damagee.func_145748_c_)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user