Compare commits

...
34 Commits
Author SHA1 Message Date
bdew 9ee12091e6 Modules dataslot in multiblock controlers should not trigger render updates 2015-06-27 19:00:12 +03:00
bdew 08ccf07dfb Don't trigger chunk updates if somethings changes UpdateKind.WORLD dataslot on client. 2015-06-27 18:59:35 +03:00
bdew 382c21f732 Added KeepData mixins for blocks that keep their stuff when broken. 2015-06-24 15:50:23 +03:00
bdew 17e4bf3a2f BlockTooltip will now use the new HasItemBlock trait 2015-06-24 15:50:09 +03:00
bdew ebe2c1f34a Added HasItemBlock - trait that tells BlockManager and Machine to register custom ItemBlocks. Replaces old itemClass parameter. Version bumped to 1.9.0 2015-06-24 15:49:00 +03:00
bdew fae2825e7b Added RichNBTTagCompound.toItemStack 2015-06-24 12:05:48 +03:00
bdew b2e138f3cd TileBaseProcessor shouldn't include BreakableInventoryTile 2015-06-24 12:05:02 +03:00
bdew 9d897d0663 getActiveModId will return <unknown> instead of null 2015-06-24 12:03:58 +03:00
bdew 497917185c BreakableInventoryBlock now checks that the TileEntity extends BreakableInventoryTile at compile time 2015-06-23 11:19:03 +03:00
bdew 9ff7a75604 Build against forge 10.13.4.1448, updated to gradle 2.4 2015-06-10 11:24:27 +03:00
bdew f8bb1e8fbb Added a way to manually run ServerTickExecutionContext 2015-06-08 15:44:16 +03:00
bdew a530c66680 Added ItemBlock with tooltip 2015-06-02 16:45:22 +03:00
bdew 26af828491 Added BlockManager.registerLegacyTileEntity 2015-06-02 14:37:27 +03:00
bdew 1c0913d674 Code cleanup 2015-06-02 13:52:51 +03:00
bdew 895cfd9cb6 Improved NBT constructor 2015-05-31 15:40:08 +03:00
bdew f43dd28e03 Added easy NBT constructor - see https://gist.github.com/bdew/0a44363dcac4be85415c 2015-05-25 15:29:31 +03:00
bdew 289f8f7120 derp 2015-05-24 04:03:23 +03:00
bdew e7787fb9ca bumped version to 1.8.0, removed deprecated methods 2015-05-24 04:01:36 +03:00
bdew 58e336f8a9 Misc.haveModVersion should check APIs too, added getModVersion 2015-05-24 04:00:23 +03:00
bdew bea6a13896 Added async helpers and ServerTickExecutionContext (executes futures in server thread using tick event) 2015-05-21 18:05:33 +03:00
bdew 793ceb0024 Merge pull request #16 from Mazdallier/patch-1
Create fr_FR.lang
2015-05-13 12:07:16 +03:00
Yves 66d9be58c8 Update fr_FR.lang
--file return back
2015-05-12 17:13:57 +02:00
Yves 87d64208c8 Create fr_FR.lang 2015-05-12 15:59:10 +02:00
bdew 6f6496c1e3 /oredistribution - added dense ore support 2015-05-12 16:04:44 +03:00
bdew 934e984abf /oredistribution - Added option to dump to file 2015-05-12 16:02:03 +03:00
bdew 4900537a82 /oredistribution - Fixed meta detection with some ores (e.g. lapis) 2015-05-12 10:19:37 +03:00
bdew 31b5ab9d52 Added /oredistribution command 2015-05-10 22:37:04 +03:00
bdew 8a4ccf7d81 Prevent build failure when CF api key is not available 2015-05-10 15:49:37 +03:00
bdew 429107215f Allow fractional chances in config lootlists 2015-05-10 15:36:31 +03:00
bdew 0c60d596b6 Jenkins will now upload builds to curseforge 2015-05-10 15:35:45 +03:00
bdew da35094895 Merge pull request #14 from theelixzammuto/mc1710
Added Italian Localization
2015-04-27 23:30:19 +03:00
theelixzammuto 83d30f12c2 Added Italian Localization 2015-04-26 21:42:29 +02:00
bdew 8d4484ca18 DataSlotTankRestricted now takes fluid object instead of fluid ID 2015-04-20 14:53:25 +03:00
bdew 624df87299 Updated to grade 2.3, reworked build script to use properties file, changed version format to include MC version 2015-04-20 14:37:23 +03:00
47 changed files with 638 additions and 92 deletions

No files matched your search

+35 -13
View File
@@ -21,21 +21,30 @@ buildscript {
apply plugin: 'scala'
apply plugin: 'forge'
version = "1.7.1"
file "build.properties" withReader {
def prop = new Properties()
prop.load(it)
ext.config = new ConfigSlurper().parse prop
}
if (project.hasProperty('forgeOverride')) {
config.forge.version = forgeOverride
}
if (project.hasProperty('buildnum')) {
project.version = project.version + '.' + project.buildnum
ext.simpleVersion = "${config.bdlib.version}.${project.buildnum}"
} else {
project.version = "0-SNAPSHOT"
ext.simpleVersion = "${config.bdlib.version}-DEV"
}
version = simpleVersion + '-mc' + config.minecraft.version
group = "net.bdew"
archivesBaseName = "bdlib"
ext.versuffix = "mc1710"
minecraft {
version = "1.7.10-10.13.2.1291"
replace("BDLIB_VER", project.version)
version = "${config.minecraft.version}-${config.forge.version}"
replace("BDLIB_VER", simpleVersion.toString())
}
import org.apache.tools.ant.filters.ReplaceTokens
@@ -66,16 +75,18 @@ processResources {
}
task sourceJar(type: Jar) {
from sourceSets.main.allSource
classifier "sources"
}
task deobfJar(type: Jar) {
from sourceSets.main.output
classifier "dev"
duplicatesStrategy "exclude"
}
jar {
appendix = project.versuffix
afterEvaluate { project ->
// Fudge the inputs of source jars so we get the version after replacements
tasks.getByPath(":sourceJar").from(tasks.getByPath(":sourceMainScala").outputs.files)
}
artifacts {
@@ -89,10 +100,7 @@ publishing {
publications {
maven(MavenPublication) {
artifact deobfJar
artifact sourceJar {
classifier "sources"
}
artifact sourceJar
}
}
repositories {
@@ -100,4 +108,18 @@ publishing {
url "file://var/www/maven"
}
}
}
apply plugin: 'curseforge'
curse {
projectId = config.curseforge.id
apiKey = project.hasProperty("curseForgeApiKey") ? project.curseForgeApiKey : ""
releaseType = 'alpha'
artifact = jar
changelog = project.hasProperty("changelog") ? project.changelog : "No changelog available"
additionalArtifact deobfJar
additionalArtifact sourceJar
}
+5
View File
@@ -0,0 +1,5 @@
bdlib.version=1.9.0
curseforge.id=70496
minecraft.version=1.7.10
forge.version=10.13.4.1448-1.7.10
+1 -1
View File
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-bin.zip
Vendored Regular → Executable
View File
File mode changed.
+7
View File
@@ -17,3 +17,10 @@ bdlib.rsmode.rs_off=Disable on redstone
bdlib.label.empty=Empty
bdlib.oredistribution.usage=/oredistribution <radius> [<min height>] [<max height>] [--file]
bdlib.oredistribution.start1=Checking ore distribution in (%s,%s,%s) to (%s,%s,%s) dim %s
bdlib.oredistribution.start2=Server may lag for a while
bdlib.oredistribution.entry=%s %s - %s (%s%%)
bdlib.oredistribution.warn=%s Warning: %s has multiple variants generated:
bdlib.oredistribution.saved=Ore distribution dumped to %s
bdlib.oredistribution.error=Failed to save ore distribution dump: %s
+26
View File
@@ -0,0 +1,26 @@
bdlib.multiblock.face.north=Nord
bdlib.multiblock.face.south=Sud
bdlib.multiblock.face.east=Est
bdlib.multiblock.face.west=Ouest
bdlib.multiblock.face.up=Dessus
bdlib.multiblock.face.down=Dessous
bdlib.multiblock.disabled=Désactivé
bdlib.multiblock.incomplete=Cette machine est incomplète, elle exige au moins :
bdlib.multiblock.notconnected=Pas connecté à une machine valide
bdlib.multiblock.toomanyoutputs=Trop de soties connectées, Incapable d'ajouter une nouvelle connexion
bdlib.rsmode.always=Toujours actif
bdlib.rsmode.never=Désactivé
bdlib.rsmode.rs_on=Activé par redstone
bdlib.rsmode.rs_off=Désactivé par redstone
bdlib.label.empty=Vide
bdlib.oredistribution.usage=/oredistribution <rayon> [<hauteur mini>] [<hauteur maxi>] [--file]
bdlib.oredistribution.start1=Valide la distribution de minerai entre (%s,%s,%s) et (%s,%s,%s) dim %s
bdlib.oredistribution.start2=Le server peut ralentir pendantun certain temps
bdlib.oredistribution.entry=%s %s - %s (%s%%)
bdlib.oredistribution.warn=%s Attention: %s fait produire des variantes multiples :
bdlib.oredistribution.saved=Distribution de minerai déposée dans %s
bdlib.oredistribution.error=Impossible d'enregistrer la distribution de minerai : %s
+18
View File
@@ -0,0 +1,18 @@
bdlib.multiblock.face.north=Nord
bdlib.multiblock.face.south=Sud
bdlib.multiblock.face.east=Est
bdlib.multiblock.face.west=Ovest
bdlib.multiblock.face.up=Sopra
bdlib.multiblock.face.down=Sotto
bdlib.multiblock.disabled=Disattivo
bdlib.multiblock.incomplete=Questa macchina è incompleta, richiede almeno:
bdlib.multiblock.notconnected=Non connesso ad una macchina valida
bdlib.multiblock.toomanyoutputs=Troppi Output collegati,impossibile inserire una nuova connessione
bdlib.rsmode.always=Sempre Attivo
bdlib.rsmode.never=Disattivo
bdlib.rsmode.rs_on=Attivo su Impulso di Pietrarossa
bdlib.rsmode.rs_off=Disattivo su Impulso di Pietrarossa
bdlib.label.empty=Vuoto
+2 -1
View File
@@ -42,7 +42,8 @@ object BdLib {
@EventHandler
def serverStarting(event: FMLServerStartingEvent) {
val commandHandler = event.getServer.getCommandManager.asInstanceOf[CommandHandler]
commandHandler.registerCommand(new CommandDumpRegistry)
commandHandler.registerCommand(CommandDumpRegistry)
commandHandler.registerCommand(CommandOreDistribution)
onServerStarting.trigger(event)
}
+1 -1
View File
@@ -19,7 +19,7 @@ import net.minecraft.item.ItemStack
import net.minecraftforge.fluids.FluidRegistry
import net.minecraftforge.oredict.OreDictionary
class CommandDumpRegistry extends CommandBase {
object CommandDumpRegistry extends CommandBase {
def getCommandName = "dumpregistry"
override def getRequiredPermissionLevel = 2
def getCommandUsage(c: ICommandSender) = "dumpregistry"
@@ -0,0 +1,148 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib
import java.io.{BufferedWriter, File, FileWriter}
import cpw.mods.fml.common.registry.GameData
import cpw.mods.fml.relauncher.FMLInjectionData
import net.minecraft.command.{CommandBase, ICommandSender, WrongUsageException}
import net.minecraft.entity.player.EntityPlayerMP
import net.minecraft.item.Item
import net.minecraft.util.EnumChatFormatting
import net.minecraftforge.oredict.OreDictionary
import scala.collection.mutable
object CommandOreDistribution extends CommandBase {
def getCommandName = "oredistribution"
override def getRequiredPermissionLevel = 2
def getCommandUsage(c: ICommandSender) = "bdlib.oredistribution.usage"
def safeInt(s: String) =
try {
s.toInt
} catch {
case e: NumberFormatException => throw new WrongUsageException("bdlib.oredistribution.usage")
}
def wrapColor(s: String, c: EnumChatFormatting) = c + s + EnumChatFormatting.RESET
def processCommand(sender: ICommandSender, baseParams: Array[String]) {
val (flags, params) = baseParams.partition(_.startsWith("--"))
if (params.length < 1 || params.length > 3)
throw new WrongUsageException(getCommandUsage(sender))
val (startX, startZ, world) =
sender match {
case p: EntityPlayerMP => (p.posX.toInt, p.posZ.toInt, p.worldObj)
case _ => (0, 0, sender.getEntityWorld)
}
val radius = safeInt(params.head)
val minY = if (params.length >= 2) safeInt(params(1)) else 0
val maxY = if (params.length >= 3) safeInt(params(2)) else world.getHeight - 1
if (minY < 0 || radius <= 0 || minY > maxY || maxY > world.getHeight - 1)
throw new WrongUsageException(getCommandUsage(sender))
val toFile = flags.contains("--file")
// why java, WHY?
CommandBase.func_152373_a(sender, this, "bdlib.oredistribution.start1",
Array[Integer](startX - radius, minY, startZ - radius, startX + radius, maxY, startZ + radius, world.provider.dimensionId): _*)
CommandBase.func_152373_a(sender, this, "bdlib.oredistribution.start2")
import scala.collection.JavaConversions._
val ores = (OreDictionary.getOreNames.filter(x => x.startsWith("ore") || x.startsWith("denseore")) flatMap { name =>
val fixedName =
if (name.startsWith("ore"))
name.substring(3)
else if (name.startsWith("denseore"))
"Dense " + name.substring(8)
else name
for (s <- OreDictionary.getOres(name)) yield (s.getItem, s.getItemDamage) -> fixedName
}).toMap
val distribution = mutable.Map.empty[String, Int].withDefaultValue(0)
val kinds = mutable.Map.empty[String, Set[(Item, Int)]].withDefaultValue(Set.empty)
for {
x <- startX - radius to startX + radius
y <- minY to maxY
z <- startZ - radius to startZ + radius
if !world.isAirBlock(x, y, z)
} {
val key = (Item.getItemFromBlock(world.getBlock(x, y, z)), world.getBlockMetadata(x, y, z))
for (ore <- ores.get(key)) {
distribution(ore) += 1
kinds(ore) += key
}
}
val total = distribution.values.sum
val warnings = kinds.filter(_._2.size > 1)
if (toFile) {
// === OUTPUT TO FILE ===
val mcHome = FMLInjectionData.data()(6).asInstanceOf[File] //is there a better way to get this?
val dumpFile = new File(mcHome, "ore_distribution.txt")
val dumpWriter = new BufferedWriter(new FileWriter(dumpFile))
try {
dumpWriter.write("Ore distribution report - (%d,%d,%d) to (%d,%d,%d) dim %d".format(
startX - radius, minY, startZ - radius, startX + radius, maxY, startZ + radius, world.provider.dimensionId
))
dumpWriter.newLine()
dumpWriter.newLine()
if (warnings.nonEmpty) {
for ((id, types) <- warnings.toList.sortBy(_._1)) {
dumpWriter.write("Warning: %s has multiple variants generated:".format(id))
dumpWriter.newLine()
for ((item, dmg) <- types) {
dumpWriter.write(" - %s@%s".format(GameData.getItemRegistry.getNameForObject(item), dmg))
dumpWriter.newLine()
}
dumpWriter.newLine()
}
dumpWriter.write("=================")
dumpWriter.newLine()
dumpWriter.newLine()
}
for ((id, num) <- distribution.filter(_._2 > 0).toList.sortBy(-_._2)) {
dumpWriter.write("%s - %s (%s%%)".format(id, DecFormat.round(num), DecFormat.short(100F * num / total)))
dumpWriter.newLine()
}
CommandBase.func_152373_a(sender, this, "bdlib.oredistribution.saved", dumpFile.getCanonicalPath)
} catch {
case e: Throwable =>
CommandBase.func_152373_a(sender, this, "bdlib.oredistribution.error", e.toString)
BdLib.logErrorException("Failed to save ore distribution dump", e)
} finally {
dumpWriter.close()
}
} else {
// === OUTPUT TO CHAT ===
for ((id, types) <- warnings.toList.sortBy(_._1)) {
CommandBase.func_152373_a(sender, this, "bdlib.oredistribution.warn",
wrapColor(" !", EnumChatFormatting.RED), wrapColor(id, EnumChatFormatting.RED))
for ((item, dmg) <- types)
CommandBase.func_152373_a(sender, this, wrapColor(" - ", EnumChatFormatting.RED) + GameData.getItemRegistry.getNameForObject(item) + "@" + dmg)
}
for ((id, num) <- distribution.filter(_._2 > 0).toList.sortBy(-_._2)) {
CommandBase.func_152373_a(sender, this, "bdlib.oredistribution.entry",
" *", wrapColor(id, EnumChatFormatting.YELLOW),
DecFormat.round(num), DecFormat.short(100F * num / total))
}
}
}
}
+1 -1
View File
@@ -12,7 +12,7 @@ package net.bdew.lib
class EventBase[T] extends {
var listeners = Seq.empty[T]
def listen(x: T) = listeners :+= x
def hasListeners = listeners.size > 0
def hasListeners = listeners.nonEmpty
}
class Event0 extends EventBase[() => Unit] {
+25 -24
View File
@@ -9,9 +9,11 @@
package net.bdew.lib
import cpw.mods.fml.common.Loader
import java.util
import cpw.mods.fml.common.registry.GameRegistry
import cpw.mods.fml.common.versioning.{ArtifactVersion, VersionParser}
import cpw.mods.fml.common.versioning.VersionParser
import cpw.mods.fml.common.{Loader, ModAPIManager, ModContainer}
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.tileentity.TileEntity
@@ -22,28 +24,16 @@ import net.minecraftforge.fluids.{Fluid, FluidStack}
import net.minecraftforge.oredict.ShapedOreRecipe
object Misc {
@deprecated("Use net.bdew.lib.nbt instead", "bdlib 1.7.0")
def iterNbtCompoundList(parent: NBTTagCompound, name: String): Iterable[NBTTagCompound] = {
import net.bdew.lib.nbt._
parent.getList[NBTTagCompound](name)
}
@deprecated("Use net.bdew.lib.nbt instead", "bdlib 1.7.0")
def iterNbtIntArray(parent: NBTTagCompound, name: String): Iterable[Array[Int]] = {
import net.bdew.lib.nbt._
parent.getList[Array[Int]](name)
}
def getActiveModId = Loader.instance().activeModContainer().getModId
def getActiveModId = Option(Loader.instance().activeModContainer().getModId) getOrElse "<UNKNOWN>"
def toLocal(s: String) = StatCollector.translateToLocal(s)
def toLocalF(s: String, params: Any*) = StatCollector.translateToLocal(s).format(params: _*)
def hasLocal(s: String) = StatCollector.canTranslate(s)
def flattenRecipe(pattern: Seq[String], items: Map[Char, AnyRef]) =
pattern ++ items.map {
pattern ++ items.flatMap {
case (k, v) => Seq(new Character(k), v)
}.flatten
}
def wrapTag(n: String, f: (NBTTagCompound) => Any)(t: NBTTagCompound) {
val p = t.getCompoundTag(n)
@@ -69,17 +59,28 @@ object Misc {
def getBiomeByName(name: String) = BiomeGenBase.getBiomeGenArray.find(x => x != null && x.biomeName == name).orNull
def haveModVersion(spec: String): Boolean = {
val req = VersionParser.parseVersionReference(spec)
val modId = req.getLabel
private lazy val modLookup = {
val mods = new util.ArrayList[ModContainer]
val nameLookup = new util.HashMap[String, ModContainer]
if (!Loader.instance.getIndexedModList.containsKey(modId)) return false
nameLookup.putAll(Loader.instance().getIndexedModList)
ModAPIManager.INSTANCE.injectAPIModContainers(mods, nameLookup)
val found: ArtifactVersion = Loader.instance.getIndexedModList.get(modId).getProcessedVersion
import scala.collection.JavaConverters._
nameLookup.asScala
}
if (found == null || !req.containsVersion(found)) return false
def haveModVersion(modId: String) = {
val spec = VersionParser.parseVersionReference(modId)
modLookup.contains(spec.getLabel) && spec.containsVersion(modLookup(spec.getLabel).getProcessedVersion)
}
return true
def getModVersion(modId: String) =
modLookup.get(modId) map (_.getVersion)
def getModVersionString(modId: String): String = {
val cont = modLookup.getOrElse(modId, return "NOT FOUND")
cont.getModId + " " + cont.getVersion
}
// Because writing this every time is awkward
+30
View File
@@ -0,0 +1,30 @@
/*
* Copyright (c) bdew, 2013 - 2015
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.async
import scala.concurrent.{Future, Promise}
object Async {
def inOtherThread[T](f: => T) = {
val p = Promise[T]()
val t = new Thread(new Runnable {
override def run(): Unit =
try {
p.success(f)
} catch {
case t: Throwable => p.failure(t)
}
})
t.start()
p.future
}
def inServerThread[T](f: => T) = Future(f)(ServerTickExecutionContext)
}
@@ -0,0 +1,55 @@
/*
* Copyright (c) bdew, 2013 - 2015
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.async
import cpw.mods.fml.common.FMLCommonHandler
import cpw.mods.fml.common.eventhandler.SubscribeEvent
import cpw.mods.fml.common.gameevent.TickEvent.ServerTickEvent
import net.bdew.lib.BdLib
import scala.collection.mutable
import scala.concurrent.ExecutionContext
object ServerTickExecutionContext extends ExecutionContext {
private val queue = mutable.Queue.empty[Runnable]
FMLCommonHandler.instance.bus.register(this)
BdLib.logDebug("Installed ServerTickExecutionContext")
private def getNextBatch = this.synchronized {
if (queue.nonEmpty) {
val res = queue.toList
queue.clear()
res
} else List.empty
}
override def execute(runnable: Runnable): Unit =
this.synchronized {
queue += runnable
}
override def reportFailure(cause: Throwable): Unit =
BdLib.logErrorException("Error in execution context", cause)
def doSingleLoop(): Unit = {
for (r <- getNextBatch) {
try {
r.run()
} catch {
case t: Throwable => reportFailure(t)
}
}
}
@SubscribeEvent
def onTick(ev: ServerTickEvent): Unit = doSingleLoop()
}
+21
View File
@@ -0,0 +1,21 @@
/*
* Copyright (c) bdew, 2013 - 2015
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.block
import net.minecraft.block.Block
import net.minecraft.item.ItemBlock
/**
* If defined on a block - defines a custom ItemBlock class that will be used when registering
* Supported by BlockManager and Machine
*/
trait HasItemBlock extends Block {
def ItemBlockClass: Class[_ <: ItemBlock]
}
@@ -0,0 +1,29 @@
/*
* Copyright (c) bdew, 2013 - 2015
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.block
import java.util
import net.minecraft.block.Block
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.{ItemBlock, ItemStack}
trait BlockTooltip extends Block with HasItemBlock {
override val ItemBlockClass: Class[_ <: ItemBlock] = classOf[ItemBlockTooltip]
def getTooltip(stack: ItemStack, player: EntityPlayer, advanced: Boolean): List[String]
}
class ItemBlockTooltip(b: Block) extends ItemBlock(b) {
override def addInformation(stack: ItemStack, player: EntityPlayer, list: util.List[_], advanced: Boolean): Unit = {
import scala.collection.JavaConversions._
if (b.isInstanceOf[BlockTooltip])
list.asInstanceOf[util.List[String]].addAll(b.asInstanceOf[BlockTooltip].getTooltip(stack, player, advanced))
}
}
+110
View File
@@ -0,0 +1,110 @@
/*
* Copyright (c) bdew, 2013 - 2015
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.block
import java.util
import net.bdew.lib.nbt.NBT
import net.bdew.lib.tile.TileExtended
import net.minecraft.block.Block
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.MovingObjectPosition
import net.minecraft.world.World
/**
* Mixin for blocks to keep their data when broken
* Must have a TileEntity that extends TileKeepData
*/
trait BlockKeepData extends Block with HasItemBlock {
this: HasTE[_ <: TileKeepData] =>
override val ItemBlockClass: Class[_ <: ItemBlockKeepData] = classOf[ItemBlockKeepData]
def getSavedBlock(world: World, x: Int, y: Int, z: Int, metadata: Int) = {
val stack = new ItemStack(getItemDropped(metadata, world.rand, 0), 1, damageDropped(metadata))
getTE(world, x, y, z).saveToItem(stack)
stack
}
override def getDrops(world: World, x: Int, y: Int, z: Int, metadata: Int, fortune: Int): util.ArrayList[ItemStack] = {
val drops = new util.ArrayList[ItemStack]()
drops.add(getSavedBlock(world, x, y, z, metadata))
drops
}
override def removedByPlayer(world: World, player: EntityPlayer, x: Int, y: Int, z: Int, willHarvest: Boolean): Boolean =
if (willHarvest)
true
else
super.removedByPlayer(world, player, x, y, z, willHarvest)
override def harvestBlock(world: World, player: EntityPlayer, x: Int, y: Int, z: Int, meta: Int): Unit = {
super.harvestBlock(world, player, x, y, z, meta)
world.setBlockToAir(x, y, z)
}
override def getPickBlock(target: MovingObjectPosition, world: World, x: Int, y: Int, z: Int, player: EntityPlayer): ItemStack = {
getSavedBlock(world, x, y, z, world.getBlockMetadata(x, y, z))
}
/**
* Override for special actions on placing
* ItemStack might or might not contain actual data
* Called with the TE created and added to world, after onBlockPlacedBy & co
*/
def restoreTileEntity(world: World, x: Int, y: Int, z: Int, is: ItemStack, player: EntityPlayer) = getTE(world, x, y, z).loadFromItem(is)
}
/**
* Mixin for tile entities to keep their data when broken
* Block class has to extend BlockKeepData
*/
trait TileKeepData extends TileExtended {
/**
* Override to modify data that will be stored in an item
* @param t Automatically serialized data
* @return Modified serialized data
*/
def afterTileBreakSave(t: NBTTagCompound) = t
/**
* Override to modify data that will be load from an item
* After the tile entity is fully constructed and added to world
* @param t Automatically serialized data
* @return Modified serialized data
*/
def beforeTileBreakLoad(t: NBTTagCompound) = t
final def saveToItem(is: ItemStack): Unit = {
if (!is.hasTagCompound) is.setTagCompound(new NBTTagCompound)
is.getTagCompound.setTag("data", afterTileBreakSave(NBT.from(persistSave.trigger)))
}
final def loadFromItem(is: ItemStack): Unit = {
if (is.hasTagCompound && is.getTagCompound.hasKey("data")) {
persistLoad.trigger(beforeTileBreakLoad(is.getTagCompound.getCompoundTag("data")))
}
}
}
/**
* Custom ItemBlock that handles loading data to the Tile Entity
*/
class ItemBlockKeepData(b: Block) extends ItemBlockTooltip(b) {
override def placeBlockAt(stack: ItemStack, player: EntityPlayer, world: World, x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float, metadata: Int): Boolean = {
if (super.placeBlockAt(stack, player, world, x, y, z, side, hitX, hitY, hitZ, metadata)) {
if (!world.isRemote && b.isInstanceOf[BlockKeepData])
b.asInstanceOf[BlockKeepData].restoreTileEntity(world, x, y, z, stack, player)
true
} else false
}
}
+22 -5
View File
@@ -9,19 +9,27 @@
package net.bdew.lib.config
import cpw.mods.fml.common.ObfuscationReflectionHelper
import cpw.mods.fml.common.registry.GameRegistry
import net.bdew.lib.Misc
import net.bdew.lib.block.{HasTE, NamedBlock}
import net.bdew.lib.block.{HasItemBlock, HasTE, NamedBlock}
import net.minecraft.block.Block
import net.minecraft.creativetab.CreativeTabs
import net.minecraft.item.{ItemBlock, Item, ItemStack}
import net.minecraft.item.{ItemBlock, ItemStack}
import net.minecraft.tileentity.TileEntity
class BlockManager(creativeTab: CreativeTabs) {
def regBlock[T <: NamedBlock](block: T): T = regBlock(block, block.name)
def regBlock[T <: NamedBlock](block: T, itemClass: Class[_ <: ItemBlock]): T = regBlock(block, block.name, itemClass)
def regSpecial[T <: NamedBlock](block: T, addStack: Boolean = false, skipTileEntityReg: Boolean = false): T =
regBlock(block, block.name, addStack, skipTileEntityReg)
def regBlock[T <: Block](block: T, name: String, addStack: Boolean = false, skipTileEntityReg: Boolean = false): T = {
val itemClass: Class[_ <: ItemBlock] = if (block.isInstanceOf[HasItemBlock])
block.asInstanceOf[HasItemBlock].ItemBlockClass
else
classOf[ItemBlock]
def regBlock[T <: Block](block: T, name: String, itemClass: Class[_ <: ItemBlock] = classOf[ItemBlock], addStack: Boolean = false): T = {
GameRegistry.registerBlock(block, itemClass, name)
block.setCreativeTab(creativeTab)
@@ -29,12 +37,21 @@ class BlockManager(creativeTab: CreativeTabs) {
if (addStack)
GameRegistry.registerCustomItemStack(name, new ItemStack(block))
if (block.isInstanceOf[HasTE[_]])
if (block.isInstanceOf[HasTE[_]] && !skipTileEntityReg)
GameRegistry.registerTileEntity(block.asInstanceOf[HasTE[_]].TEClass,
"%s.%s".format(Misc.getActiveModId, name))
return block
}
/**
* Registers a legacy TE name->class mapping. Stolen from GameRegistry.registerTileEntityWithAlternatives
*/
def registerLegacyTileEntity(name: String, cls: Class[_ <: TileEntity]): Unit = {
val teMappings: java.util.Map[String, Class[_]] = ObfuscationReflectionHelper.getPrivateValue(classOf[TileEntity], null, "field_" + "145855_i", "nameToClassMap")
if (!teMappings.containsKey(name))
teMappings.put(name, cls)
}
def load() {}
}
@@ -17,7 +17,7 @@ case class DataSlotFluidOption(name: String, parent: DataSlotContainer) extends
setUpdate(UpdateKind.SAVE, UpdateKind.GUI)
override def save(t: NBTTagCompound, kind: UpdateKind.Value) {
value map { x => t.setString(name, x.getName) }
value foreach { x => t.setString(name, x.getName) }
}
override def load(t: NBTTagCompound, kind: UpdateKind.Value): Unit = {
@@ -29,8 +29,8 @@ case class DataSlotGameProfile(name: String, parent: DataSlotContainer) extends
override def save(t: NBTTagCompound, kind: UpdateKind.Value) = {
if (value != null) {
Option(value.getId) map (id => t.setString(name + "_uid", id.toString))
Option(value.getName) filterNot (name => StringUtils.isBlank(name)) map (name => t.setString(name + "_name", name))
Option(value.getId) foreach (id => t.setString(name + "_uid", id.toString))
Option(value.getName) filterNot (name => StringUtils.isBlank(name)) foreach (name => t.setString(name + "_name", name))
}
}
}
+2 -4
View File
@@ -11,7 +11,7 @@ package net.bdew.lib.data
import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.fluids.{FluidRegistry, FluidStack, FluidTank, IFluidTank}
import net.minecraftforge.fluids._
abstract class DataSlotTankBase(sz: Int) extends FluidTank(sz) with IFluidTank with DataSlot {
var oldStack: FluidStack = null
@@ -69,9 +69,7 @@ abstract class DataSlotTankBase(sz: Int) extends FluidTank(sz) with IFluidTank w
case class DataSlotTank(name: String, parent: DataSlotContainer, size: Int) extends DataSlotTankBase(size)
case class DataSlotTankRestricted(name: String, parent: DataSlotContainer, var size: Int, fluidID: Int) extends DataSlotTankBase(size) {
val filterFluid = FluidRegistry.getFluid(fluidID)
case class DataSlotTankRestricted(name: String, parent: DataSlotContainer, var size: Int, filterFluid: Fluid) extends DataSlotTankBase(size) {
def fill(amount: Int, doFill: Boolean) = super.fill(new FluidStack(filterFluid, amount), doFill)
override def fill(resource: FluidStack, doFill: Boolean): Int = {
@@ -32,7 +32,7 @@ trait TileDataSlots extends TileExtended with DataSlotContainer {
if (getWorldObj != null) {
if (slot.updateKind.contains(UpdateKind.GUI))
lastChange = getWorldObj.getTotalWorldTime
if (slot.updateKind.contains(UpdateKind.WORLD))
if (!getWorldObj.isRemote && slot.updateKind.contains(UpdateKind.WORLD))
getWorldObj.markBlockForUpdate(xCoord, yCoord, zCoord)
if (slot.updateKind.contains(UpdateKind.SAVE))
getWorldObj.markTileEntityChunkModified(xCoord, yCoord, zCoord, this)
+1 -1
View File
@@ -56,7 +56,7 @@ abstract class BaseScreen(cont: Container, xSz: Int, ySz: Int) extends GuiContai
import scala.collection.JavaConversions._
if (tip.size > 0)
if (tip.nonEmpty)
drawHoveringText(tip, x, y, getFontRenderer)
}
+10 -2
View File
@@ -11,10 +11,11 @@ package net.bdew.lib.machine
import cpw.mods.fml.common.registry.GameRegistry
import net.bdew.lib.Misc
import net.bdew.lib.block.HasTE
import net.bdew.lib.block.{HasItemBlock, HasTE}
import net.bdew.lib.recipes.gencfg.ConfigSection
import net.minecraft.block.Block
import net.minecraft.creativetab.CreativeTabs
import net.minecraft.item.ItemBlock
abstract class Machine[T <: Block](val name: String, blockConstruct: => T) {
var block: T = null.asInstanceOf[T]
@@ -24,7 +25,14 @@ abstract class Machine[T <: Block](val name: String, blockConstruct: => T) {
def regBlock(creativeTab: CreativeTabs) {
block = blockConstruct
GameRegistry.registerBlock(block, name)
val itemClass: Class[_ <: ItemBlock] = if (block.isInstanceOf[HasItemBlock])
block.asInstanceOf[HasItemBlock].ItemBlockClass
else
classOf[ItemBlock]
GameRegistry.registerBlock(block, itemClass, name)
block.setCreativeTab(creativeTab)
if (block.isInstanceOf[HasTE[_]]) {
GameRegistry.registerTileEntity(block.asInstanceOf[HasTE[_]].TEClass, "%s.%s".format(modId, name))
+1 -1
View File
@@ -41,7 +41,7 @@ object Tools {
val seen = mutable.Set.empty[BlockRef]
val queue = mutable.Queue.empty[BlockRef]
queue ++= getConnectedNeighbours(world, core, core, seen)
while (queue.size > 0) {
while (queue.nonEmpty) {
val current = queue.dequeue()
seen.add(current)
queue ++= getConnectedNeighbours(world, core, current, seen)
@@ -28,7 +28,7 @@ trait BlockOutput[T <: TileOutput[_]] extends BlockModule[T] with BlockAdditiona
def getFaceOverlays(world: IBlockAccess, x: Int, y: Int, z: Int, face: ForgeDirection): List[FaceOverlay] = {
var result = List.empty[FaceOverlay]
Option(getTE(world, x, y, z)) flatMap (_.getCore) map { core =>
Option(getTE(world, x, y, z)) flatMap (_.getCore) foreach { core =>
val bf = BlockFace(x, y, z, face)
if (core.outputFaces.contains(bf))
result :+= FaceOverlay(resources.output, resources.outputColors(core.outputFaces(bf)))
@@ -19,7 +19,7 @@ case class DataSlotPos(name: String, parent: DataSlotContainer) extends DataSlot
setUpdate(UpdateKind.SAVE, UpdateKind.WORLD)
def save(t: NBTTagCompound, kind: UpdateKind.Value) {
value map (x => t.setTag(name, Misc.applyMutator(x.writeToNBT, new NBTTagCompound)))
value foreach (x => t.setTag(name, Misc.applyMutator(x.writeToNBT, new NBTTagCompound)))
}
def load(t: NBTTagCompound, kind: UpdateKind.Value) {
@@ -24,7 +24,7 @@ class WidgetOutputIcon(p: Point, te: CIOutputFaces, output: Int) extends Widget
val faces = te.outputFaces.inverted
if (faces.isDefinedAt(output)) {
val bf = faces(output)
bf.origin.block(te.getWorldObj) map { block =>
bf.origin.block(te.getWorldObj) foreach { block =>
parent.drawTexture(rect, Texture(Texture.BLOCKS, block.getIcon(te.getWorldObj, bf.origin.x, bf.origin.y, bf.origin.z, bf.face.ordinal())))
if (block.isInstanceOf[BlockAdditionalRender]) {
for (over <- block.asInstanceOf[BlockAdditionalRender].getFaceOverlays(te.getWorldObj, bf.origin.x, bf.origin.y, bf.origin.z, bf.face))
@@ -18,7 +18,7 @@ import net.bdew.lib.multiblock.{MachineCore, ResourceProvider, Tools}
import net.minecraft.entity.player.EntityPlayer
trait TileController extends TileDataSlots {
val modules = new DataSlotPosSet("modules", this).setUpdate(UpdateKind.WORLD, UpdateKind.SAVE, UpdateKind.RENDER)
val modules = new DataSlotPosSet("modules", this).setUpdate(UpdateKind.WORLD, UpdateKind.SAVE)
def resources: ResourceProvider
def cfg: MachineCore
@@ -29,7 +29,7 @@ trait TileController extends TileDataSlots {
lazy val myPos = BlockRef(xCoord, yCoord, zCoord)
def getNumOfModules(kind: String) = modules.map(_.getTile[TileModule](getWorldObj)).flatten.count(_.kind == kind)
def getNumOfModules(kind: String) = modules.flatMap(_.getTile[TileModule](getWorldObj)).count(_.kind == kind)
def onModulesChanged()
def onClick(player: EntityPlayer)
@@ -59,7 +59,7 @@ trait TileController extends TileDataSlots {
def validateModules() {
modules.filter(x => {
!x.getTile[TileModule](getWorldObj).isDefined || !x.getBlock[BlockModule[TileModule]](getWorldObj).isDefined
x.getTile[TileModule](getWorldObj).isEmpty || x.getBlock[BlockModule[TileModule]](getWorldObj).isEmpty
}).foreach(x => {
BdLib.logWarn("Block at %s is not a valid module, removing from machine %s at %d,%d,%d", x, this.getClass.getSimpleName, xCoord, yCoord, zCoord)
modules.remove(x)
@@ -17,7 +17,7 @@ abstract class TileControllerGui extends TileController {
def onClick(player: EntityPlayer) = {
val missing = cfg.required.filter({ case (mod, cnt) => getNumOfModules(mod) < cnt })
if (missing.size > 0) {
if (missing.nonEmpty) {
player.addChatMessage(new ChatComponentTranslation("bdlib.multiblock.incomplete")
.setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED)))
for ((mod, cnt) <- missing)
@@ -47,7 +47,7 @@ abstract class TileOutput[T <: OutputConfig] extends TileModule with MIOutput[T]
def onConnectionsChanged(added: Set[ForgeDirection], removed: Set[ForgeDirection]) {}
def doRescanFaces() {
getCore map { core =>
getCore foreach { core =>
val connections = (
ForgeDirection.VALID_DIRECTIONS
filterNot { dir => core.modules.contains(myPos.neighbour(dir)) }
@@ -58,7 +58,7 @@ abstract class TileOutput[T <: OutputConfig] extends TileModule with MIOutput[T]
val toRemove = known -- connections
toRemove.foreach(x => core.removeOutput(myPos, x))
toAdd.foreach(x => core.newOutput(myPos, x, makeCfgObject(x)))
if (toAdd.size > 0 || toRemove.size > 0) {
if (toAdd.nonEmpty || toRemove.nonEmpty) {
onConnectionsChanged(toAdd, toRemove)
getWorldObj.markBlockForUpdate(xCoord, yCoord, zCoord)
}
+50
View File
@@ -0,0 +1,50 @@
/*
* Copyright (c) bdew, 2013 - 2015
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.nbt
import net.minecraft.item.ItemStack
import net.minecraft.nbt.{NBTBase, NBTTagByte, NBTTagCompound, NBTTagList}
import scala.language.implicitConversions
object NBT {
class NBTSerialized(val value: NBTBase) extends AnyVal
object NBTSerialized {
implicit def serializeNbtPrimitive[T: Type](v: T): NBTSerialized = new NBTSerialized(Type[T].toNBT(v))
implicit def serializeNbtList[T: Type](v: Traversable[T]): NBTSerialized = {
val list = new NBTTagList
for (x <- v) list.appendTag(Type[T].toNBT(x))
new NBTSerialized(list)
}
// Boolean is special because it's represented as a byte in NBT
implicit def serializeBoolean(v: Boolean): NBTSerialized = new NBTSerialized(new NBTTagByte(if (v) 1 else 0))
// Itemstack serialization helpers
implicit def serializeItemStack(v: ItemStack): NBTSerialized = new NBTSerialized(NBT.from(v.writeToNBT _))
implicit def serializeItemStackList(v: Traversable[ItemStack]): NBTSerialized = serializeNbtList(v map (x => NBT.from(x.writeToNBT _)))
}
def apply(pairs: (String, NBTSerialized)*): NBTTagCompound = {
val tag = new NBTTagCompound()
for ((k, v) <- pairs)
tag.setTag(k, v.value)
tag
}
def from(f: (NBTTagCompound) => _) = {
val v = new NBTTagCompound
f(v)
v
}
}
@@ -9,6 +9,7 @@
package net.bdew.lib.nbt
import net.minecraft.item.ItemStack
import net.minecraft.nbt.{NBTTagCompound, NBTTagList}
import scala.language.implicitConversions
@@ -27,4 +28,5 @@ class RichNBTTagCompound(tag: NBTTagCompound) {
tag.setTag(name, list)
}
def toItemStack = Option(ItemStack.loadItemStackFromNBT(tag))
}
@@ -13,12 +13,11 @@ import net.bdew.lib.data.DataSlotFloat
import net.bdew.lib.data.base.{TileDataSlots, UpdateKind}
import net.bdew.lib.machine.ProcessorMachine
import net.bdew.lib.tile.TileExtended
import net.bdew.lib.tile.inventory.{BreakableInventoryTile, PersistentInventoryTile, SidedInventory}
import net.bdew.lib.tile.inventory.{PersistentInventoryTile, SidedInventory}
abstract class TileBaseProcessor extends TileExtended
with TileDataSlots
with PersistentInventoryTile
with BreakableInventoryTile
with SidedInventory
with TilePoweredBase {
def cfg: ProcessorMachine
@@ -59,8 +59,8 @@ case class ConfigSection(pfx: String = "") extends ConfigEntry with Iterable[(St
def getInt(id: String) = getDouble(id).round.toInt
def getFloat(id: String) = getDouble(id).toFloat
def getIntList(id: String) = getDoubleList(id).map(_.round.toInt).toList
def getFloatList(id: String) = getDoubleList(id).map(_.toFloat).toList
def getIntList(id: String) = getDoubleList(id).map(_.round.toInt)
def getFloatList(id: String) = getDoubleList(id).map(_.toFloat)
def getColor(id: String) =
raw(id) match {
@@ -14,10 +14,10 @@ import net.bdew.lib.recipes.gencfg.ConfigEntry
/**
* Allows definition of random-weighted loot/drop lists in config sections
* @param list List on (chance percent, stack reference) pairs, resolve to
* @param list List of (chance percent, stack reference) pairs, resolve to
* real ItemStacks with LootListLoader.resolveLootList
*/
case class EntryLootList(list: List[(Int, StackRef)]) extends ConfigEntry
case class EntryLootList(list: List[(Double, StackRef)]) extends ConfigEntry
@@ -19,8 +19,8 @@ import net.minecraftforge.oredict.OreDictionary
* Loader mixin for loot lists
*/
trait LootListLoader extends GenericConfigLoader {
def resolveLootList(entry: EntryLootList): List[(Int, ItemStack)] = resolveLootList(entry.list)
def resolveLootList(list: List[(Int, StackRef)]) =
def resolveLootList(entry: EntryLootList): List[(Double, ItemStack)] = resolveLootList(entry.list)
def resolveLootList(list: List[(Double, StackRef)]) =
(for ((chance, ref) <- list) yield {
try {
val itemStack = getConcreteStack(ref)
@@ -19,7 +19,7 @@ import net.bdew.lib.recipes.gencfg.GenericConfigParser
* )
*/
trait LootListParser extends GenericConfigParser {
def dropsEntry = (wholeNumber <~ "%") ~ spec ^^ { case n ~ s => (n.toInt, s) }
def dropsEntry = (decimalNumber <~ "%") ~ spec ^^ { case n ~ s => (n.toDouble, s) }
def ceDrops = "DropsList" ~> "(" ~> dropsEntry.* <~ ")" ^^ EntryLootList
override def cfgValue = ceDrops | super.cfgValue
}
+1 -1
View File
@@ -24,7 +24,7 @@ import net.minecraftforge.common.MinecraftForge
class IconPreloader(kind: Int) {
lazy val map = {
(for {
method <- getClass.getMethods if method.getParameterTypes.length == 0 && classOf[TextureLoc].isAssignableFrom(method.getReturnType)
method <- getClass.getMethods if method.getParameterTypes.isEmpty && classOf[TextureLoc].isAssignableFrom(method.getReturnType)
value <- Misc.asInstanceOpt(method.invoke(this), classOf[TextureLoc])
} yield method.getName -> value).toMap
}
@@ -18,7 +18,7 @@ case class DataSlotResourceKindOption(name: String, parent: DataSlotContainer) e
setUpdate(UpdateKind.SAVE, UpdateKind.GUI)
override def save(t: NBTTagCompound, kind: UpdateKind.Value) {
value map { r =>
value foreach { r =>
t.setTag(name,
Misc.applyMutator(new NBTTagCompound) { tag =>
r.helperObject.saveToNBT(tag, r)
@@ -16,7 +16,7 @@ import net.minecraft.inventory.{IInventory, Slot}
class SlotSensorType[T, R](inv: IInventory, index: Int, x: Int, y: Int, ds: DataSlotSensor[T, R], types: => Seq[GenericSensorType[T, R]]) extends Slot(inv, index, x, y) with SlotClickable {
override def onClick(button: Int, mods: Int, player: EntityPlayer) = {
if (mods == 0 && (button == 0 || button == 1) && types.size > 0 && player.inventory.getItemStack == null) {
if (mods == 0 && (button == 0 || button == 1) && types.nonEmpty && player.inventory.getItemStack == null) {
val newSensor =
if (button == 0)
Misc.nextInSeq(types, ds.sensor)
@@ -58,7 +58,7 @@ trait SensorOutput extends GenericSensorType[TileEntity, Boolean] {
(current, obj) match {
case (SensorOutputFlowParameter(n), x: CIOutputFaces) =>
val outputs = x.outputFaces.map.values.toList.sorted
if (outputs.size > 0)
if (outputs.nonEmpty)
if (button == 0)
SensorOutputFlowParameter(Misc.nextInSeq(outputs, n))
else
@@ -9,16 +9,15 @@
package net.bdew.lib.tile.inventory
import net.bdew.lib.block.HasTE
import net.minecraft.block.Block
import net.minecraft.world.World
trait BreakableInventoryBlock extends Block {
this: HasTE[_ <: BreakableInventoryTile] =>
override def breakBlock(world: World, x: Int, y: Int, z: Int, block: Block, meta: Int) {
if (!world.isRemote) {
val te = world.getTileEntity(x, y, z).asInstanceOf[BreakableInventoryTile]
if (te != null) {
te.dropItems()
}
getTE(world, x, y, z).dropItems()
}
super.breakBlock(world, x, y, z, block, meta)
}
@@ -19,7 +19,7 @@ trait BreakableInventoryTile extends TileEntity with BaseInventory {
for (stack <- inv if stack != null) {
ItemUtils.throwItemAt(getWorldObj, xCoord, yCoord, zCoord, stack)
}
inv = new Array[ItemStack](inv.size)
inv = new Array[ItemStack](inv.length)
}
}
}
@@ -17,11 +17,11 @@ import net.minecraft.tileentity.TileEntity
trait InventoryProxy extends TileEntity with IInventory {
def targetInventory: Option[IInventory]
override def openInventory() = targetInventory map (_.openInventory())
override def closeInventory() = targetInventory map (_.closeInventory())
override def openInventory() = targetInventory foreach (_.openInventory())
override def closeInventory() = targetInventory foreach (_.closeInventory())
override def markDirty() = {
targetInventory map (_.markDirty())
targetInventory foreach (_.markDirty())
super.markDirty()
}
@@ -30,7 +30,7 @@ trait InventoryProxy extends TileEntity with IInventory {
override def getStackInSlot(slot: Int) = targetInventory.map(_.getStackInSlot(slot)).orNull
override def getStackInSlotOnClosing(slot: Int) = targetInventory.map(_.getStackInSlotOnClosing(slot)).orNull
override def setInventorySlotContents(slot: Int, item: ItemStack) = targetInventory.map(_.setInventorySlotContents(slot, item))
override def setInventorySlotContents(slot: Int, item: ItemStack) = targetInventory.foreach(_.setInventorySlotContents(slot, item))
override def decrStackSize(slot: Int, num: Int) = targetInventory.map(_.decrStackSize(slot, num)).orNull
override def isItemValidForSlot(slot: Int, item: ItemStack) = targetInventory.exists(_.isItemValidForSlot(slot, item))
@@ -15,9 +15,9 @@ import net.minecraft.item.ItemStack
class MultipleInventoryAdapter(val map: Map[Int, (IInventory, Int)]) extends IInventory {
def this(inventories: Iterable[IInventory]) =
this((inventories map { inv => (0 until inv.getSizeInventory).map((inv, _)) }).flatten.zipWithIndex.map(_.swap).toMap)
this((inventories flatMap { inv => (0 until inv.getSizeInventory).map((inv, _)) }).zipWithIndex.map(_.swap).toMap)
def this(inventories: IInventory*) =
this((inventories map { inv => (0 until inv.getSizeInventory).map((inv, _)) }).flatten.zipWithIndex.map(_.swap).toMap)
this((inventories flatMap { inv => (0 until inv.getSizeInventory).map((inv, _)) }).zipWithIndex.map(_.swap).toMap)
lazy val inventories = map.values.map(_._1).toSet
override lazy val getInventoryStackLimit = inventories.map(_.getInventoryStackLimit).min
@@ -15,7 +15,7 @@ import net.minecraft.item.ItemStack
trait SidedInventory extends BaseInventory with ISidedInventory {
var allowSided = false
def getAccessibleSlotsFromSide(side: Int): Array[Int] = (0 until inv.size).toArray
def getAccessibleSlotsFromSide(side: Int): Array[Int] = inv.indices.toArray
def canInsertItem(slot: Int, stack: ItemStack, side: Int) = allowSided && isItemValidForSlot(slot, stack)