mirror of
https://github.com/GTNewHorizons/bdlib.git
synced 2026-10-26 22:33:53 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ff7a75604 | ||
|
|
f8bb1e8fbb | ||
|
|
a530c66680 | ||
|
|
26af828491 | ||
|
|
1c0913d674 | ||
|
|
895cfd9cb6 | ||
|
|
f43dd28e03 | ||
|
|
289f8f7120 | ||
|
|
e7787fb9ca | ||
|
|
58e336f8a9 | ||
|
|
bea6a13896 | ||
|
|
793ceb0024 | ||
|
|
66d9be58c8 | ||
|
|
87d64208c8 | ||
|
|
6f6496c1e3 | ||
|
|
934e984abf | ||
|
|
4900537a82 | ||
|
|
31b5ab9d52 | ||
|
|
8a4ccf7d81 | ||
|
|
429107215f | ||
|
|
0c60d596b6 | ||
|
|
da35094895 | ||
|
|
83d30f12c2 | ||
|
|
8d4484ca18 | ||
|
|
624df87299 | ||
|
|
18b4f19dab | ||
|
|
00b32712a0 | ||
|
|
2a008aa093 | ||
|
|
745170415e | ||
|
|
69b8e80c5f | ||
|
|
93ccc42429 | ||
|
|
dc567bd1be | ||
|
|
516133ee0a | ||
|
|
28de3620a2 | ||
|
|
61ba86d451 | ||
|
|
8e65772cae | ||
|
|
284cdfc970 | ||
|
|
bae688c366 | ||
|
|
d3952b69d0 | ||
|
|
399abf1054 | ||
|
|
f66b97d0cc | ||
|
|
13778072c0 | ||
|
|
7dc95fcce1 | ||
|
|
b71db73b11 | ||
|
|
530d5add82 | ||
|
|
3dd917b2a0 | ||
|
|
8f44111b4c | ||
|
|
8415ee7a00 | ||
|
|
6439ef8f08 | ||
|
|
dc59ee3d31 | ||
|
|
9ae4935fd9 | ||
|
|
0929ba9278 | ||
|
|
1003aa1d6a | ||
|
|
64c0484c2d | ||
|
|
8e90643ea1 | ||
|
|
a232ce52f3 | ||
|
|
35b3a77582 | ||
|
|
be3a1cf2aa | ||
|
|
e0f5d0ceda | ||
|
|
e4169f7a5d | ||
|
|
eb75a26c40 | ||
|
|
3431a6910e | ||
|
|
02598183b8 | ||
|
|
70c19bff5b |
No files matched your search
+35
-13
@@ -21,21 +21,30 @@ buildscript {
|
||||
apply plugin: 'scala'
|
||||
apply plugin: 'forge'
|
||||
|
||||
version = "1.6.2"
|
||||
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.1231"
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
bdlib.version=1.8.2
|
||||
curseforge.id=70496
|
||||
|
||||
minecraft.version=1.7.10
|
||||
forge.version=10.13.4.1448-1.7.10
|
||||
+1
-1
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,18 @@
|
||||
bdlib.multiblock.face.north=Nord
|
||||
bdlib.multiblock.face.south=Sud
|
||||
bdlib.multiblock.face.east=Est
|
||||
bdlib.multiblock.face.west=Ouest
|
||||
bdlib.multiblock.face.up=Haut
|
||||
bdlib.multiblock.face.down=Bas
|
||||
|
||||
bdlib.multiblock.disabled=Désactivé(e)
|
||||
bdlib.multiblock.incomplete=Cette machine est incomplète, elle requiert au moins :
|
||||
bdlib.multiblock.notconnected=Pas connecté(e) à une machine valide
|
||||
bdlib.multiblock.toomanyoutputs=Trop de sorties connectées, incapable d'attacher de nouvelles connexions
|
||||
|
||||
bdlib.rsmode.always=Toujours en marche
|
||||
bdlib.rsmode.never=Désactivé(e)
|
||||
bdlib.rsmode.rs_on=Activer par la redstone
|
||||
bdlib.rsmode.rs_off=Désactiver par la redstone
|
||||
|
||||
bdlib.label.empty=Vide
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import java.util
|
||||
|
||||
import cpw.mods.fml.common.{ICrashCallable, ModAPIManager, ModContainer}
|
||||
|
||||
import scala.collection.JavaConversions._
|
||||
|
||||
object ApiReporter extends ICrashCallable {
|
||||
lazy val APIs = {
|
||||
val mods = new util.ArrayList[ModContainer]
|
||||
val nameLookup = new util.HashMap[String, ModContainer]
|
||||
ModAPIManager.INSTANCE.injectAPIModContainers(mods, nameLookup)
|
||||
(for (mod <- mods.sortBy(_.getModId.toLowerCase)) yield
|
||||
"\t\t* %s (%s) from %s".format(mod.getModId, mod.getVersion,
|
||||
if (mod.getSource.isDirectory)
|
||||
mod.getSource
|
||||
else
|
||||
mod.getSource.getName
|
||||
)).mkString(Misc.lineSeparator)
|
||||
}
|
||||
override def getLabel = "List of loaded APIs"
|
||||
override def call() = Misc.lineSeparator + APIs
|
||||
}
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
package net.bdew.lib
|
||||
|
||||
import cpw.mods.fml.common.Mod
|
||||
import cpw.mods.fml.common.Mod.EventHandler
|
||||
import cpw.mods.fml.common.event.{FMLPreInitializationEvent, FMLServerStartingEvent, FMLServerStoppingEvent}
|
||||
import cpw.mods.fml.common.{FMLCommonHandler, Mod}
|
||||
import net.bdew.lib.multiblock.network.NetHandler
|
||||
import net.minecraft.command.CommandHandler
|
||||
import org.apache.logging.log4j.Logger
|
||||
@@ -20,6 +20,7 @@ import org.apache.logging.log4j.Logger
|
||||
object BdLib {
|
||||
var log: Logger = null
|
||||
|
||||
def logDebug(msg: String, args: Any*) = log.debug(msg.format(args: _*))
|
||||
def logInfo(msg: String, args: Any*) = log.info(msg.format(args: _*))
|
||||
def logWarn(msg: String, args: Any*) = log.warn(msg.format(args: _*))
|
||||
def logError(msg: String, args: Any*) = log.error(msg.format(args: _*))
|
||||
@@ -33,13 +34,16 @@ object BdLib {
|
||||
def preInit(ev: FMLPreInitializationEvent) {
|
||||
log = ev.getModLog
|
||||
log.info("bdlib BDLIB_VER loaded")
|
||||
log.debug("List of loaded APIs: " + ApiReporter.APIs)
|
||||
FMLCommonHandler.instance().registerCrashCallable(ApiReporter)
|
||||
NetHandler.init()
|
||||
}
|
||||
|
||||
@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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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] {
|
||||
|
||||
+42
-21
@@ -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,16 +24,6 @@ import net.minecraftforge.fluids.{Fluid, FluidStack}
|
||||
import net.minecraftforge.oredict.ShapedOreRecipe
|
||||
|
||||
object Misc {
|
||||
def iterNbtCompoundList(parent: NBTTagCompound, name: String): Iterable[NBTTagCompound] = {
|
||||
val list = parent.getTagList(name, 10)
|
||||
for (i <- 0 until list.tagCount()) yield list.getCompoundTagAt(i)
|
||||
}
|
||||
|
||||
def iterNbtIntArray(parent: NBTTagCompound, name: String): Iterable[Array[Int]] = {
|
||||
val list = parent.getTagList(name, 11)
|
||||
for (i <- 0 until list.tagCount()) yield list.func_150306_c(i)
|
||||
}
|
||||
|
||||
def getActiveModId = Loader.instance().activeModContainer().getModId
|
||||
|
||||
def toLocal(s: String) = StatCollector.translateToLocal(s)
|
||||
@@ -39,9 +31,9 @@ object Misc {
|
||||
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)
|
||||
@@ -67,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
|
||||
@@ -105,6 +108,22 @@ object Misc {
|
||||
init
|
||||
}
|
||||
|
||||
def nextInSeq[T](seq: Seq[T], elem: T) = {
|
||||
val pos = seq.indexOf(elem)
|
||||
if (pos < 0 || pos == seq.size - 1)
|
||||
seq.head
|
||||
else
|
||||
seq(pos + 1)
|
||||
}
|
||||
|
||||
def prevInSeq[T](seq: Seq[T], elem: T) = {
|
||||
val pos = seq.indexOf(elem)
|
||||
if (pos <= 0)
|
||||
seq.last
|
||||
else
|
||||
seq(pos - 1)
|
||||
}
|
||||
|
||||
def getFluidIcon(fs: FluidStack): IIcon =
|
||||
if (fs != null && fs.getFluid != null && fs.getFluid.getIcon != null)
|
||||
fs.getFluid.getIcon(fs)
|
||||
@@ -119,5 +138,7 @@ object Misc {
|
||||
|
||||
def getFluidColor(f: Fluid): Int =
|
||||
if (f != null) getFluidColor(new FluidStack(f, 1)) else 0xFFFFFF
|
||||
|
||||
lazy val lineSeparator = System.getProperty("line.separator")
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
@@ -18,9 +18,11 @@ import net.minecraftforge.common.util.ForgeDirection
|
||||
import scala.reflect.ClassTag
|
||||
|
||||
case class BlockRef(x: Int, y: Int, z: Int) {
|
||||
def block(w: IBlockAccess) = Option(w.getBlock(x, y, z))
|
||||
def tile(w: IBlockAccess) = Option(w.getTileEntity(x, y, z))
|
||||
def meta(w: IBlockAccess) = w.getBlockMetadata(x, y, z)
|
||||
def isValid(w: IBlockAccess) = y >= 0 && y < 256 // hardcoded because getHeight is unavailable on servers :(
|
||||
|
||||
def block(w: IBlockAccess) = if (isValid(w)) Option(w.getBlock(x, y, z)) else None
|
||||
def tile(w: IBlockAccess) = if (isValid(w)) Option(w.getTileEntity(x, y, z)) else None
|
||||
def meta(w: IBlockAccess) = if (isValid(w)) w.getBlockMetadata(x, y, z) else 0
|
||||
|
||||
def blockIs(w: IBlockAccess, other: Block) = block(w).contains(other)
|
||||
|
||||
|
||||
@@ -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 {
|
||||
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))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,18 +9,22 @@
|
||||
|
||||
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.minecraft.block.Block
|
||||
import net.minecraft.creativetab.CreativeTabs
|
||||
import net.minecraft.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 <: Block](block: T, name: String, addStack: Boolean = false): T = {
|
||||
GameRegistry.registerBlock(block, name)
|
||||
def regBlock[T <: NamedBlock](block: T, itemClass: Class[_ <: ItemBlock]): T = regBlock(block, block.name, itemClass)
|
||||
|
||||
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)
|
||||
|
||||
@@ -34,5 +38,14 @@ class BlockManager(creativeTab: CreativeTabs) {
|
||||
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() {}
|
||||
}
|
||||
@@ -9,10 +9,10 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlotVal, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotVal, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotBoolean(name: String, parent: TileDataSlots, default: Boolean = false) extends DataSlotVal[Boolean] {
|
||||
case class DataSlotBoolean(name: String, parent: DataSlotContainer, default: Boolean = false) extends DataSlotVal[Boolean] {
|
||||
var value = default
|
||||
def save(t: NBTTagCompound, kind: UpdateKind.Value) = t.setBoolean(name, value)
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value = t.getBoolean(name)
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlotVal, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotVal, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
case class DataSlotDirection(name: String, parent: TileDataSlots) extends DataSlotVal[ForgeDirection] {
|
||||
case class DataSlotDirection(name: String, parent: DataSlotContainer) extends DataSlotVal[ForgeDirection] {
|
||||
var value = ForgeDirection.UP
|
||||
def save(t: NBTTagCompound, kind: UpdateKind.Value) = t.setByte(name, value.ordinal().toByte)
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value = ForgeDirection.getOrientation(t.getByte(name))
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlotNumeric, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotNumeric, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotDouble(name: String, parent: TileDataSlots, default: Double = 0) extends DataSlotNumeric[Double](default) {
|
||||
case class DataSlotDouble(name: String, parent: DataSlotContainer, default: Double = 0) extends DataSlotNumeric[Double](default) {
|
||||
def save(t: NBTTagCompound, kind: UpdateKind.Value) = t.setDouble(name, value)
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value = t.getDouble(name)
|
||||
}
|
||||
@@ -9,10 +9,10 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlotNumeric, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotNumeric, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotFloat(name: String, parent: TileDataSlots, default: Float = 0) extends DataSlotNumeric[Float](default) {
|
||||
case class DataSlotFloat(name: String, parent: DataSlotContainer, default: Float = 0) extends DataSlotNumeric[Float](default) {
|
||||
def save(t: NBTTagCompound, kind: UpdateKind.Value) = t.setFloat(name, value)
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value = t.getFloat(name)
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.fluids.{Fluid, FluidRegistry}
|
||||
|
||||
case class DataSlotFluidOption(name: String, parent: DataSlotContainer) extends DataSlotOption[Fluid] {
|
||||
setUpdate(UpdateKind.SAVE, UpdateKind.GUI)
|
||||
|
||||
override def save(t: NBTTagCompound, kind: UpdateKind.Value) {
|
||||
value foreach { x => t.setString(name, x.getName) }
|
||||
}
|
||||
|
||||
override def load(t: NBTTagCompound, kind: UpdateKind.Value): Unit = {
|
||||
if (t.hasKey(name)) {
|
||||
val fluidName = t.getString(name)
|
||||
if (FluidRegistry.isFluidRegistered(fluidName)) {
|
||||
value = Option(FluidRegistry.getFluid(fluidName))
|
||||
} else unset()
|
||||
} else unset()
|
||||
}
|
||||
}
|
||||
@@ -12,11 +12,11 @@ package net.bdew.lib.data
|
||||
import java.util.UUID
|
||||
|
||||
import com.mojang.authlib.GameProfile
|
||||
import net.bdew.lib.data.base.{DataSlotVal, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotVal, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import org.apache.commons.lang3.StringUtils
|
||||
|
||||
case class DataSlotGameProfile(name: String, parent: TileDataSlots) extends DataSlotVal[GameProfile] {
|
||||
case class DataSlotGameProfile(name: String, parent: DataSlotContainer) extends DataSlotVal[GameProfile] {
|
||||
override var value: GameProfile = null
|
||||
|
||||
override def load(t: NBTTagCompound, kind: UpdateKind.Value) = {
|
||||
@@ -29,8 +29,8 @@ case class DataSlotGameProfile(name: String, parent: TileDataSlots) extends Data
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,10 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlotNumeric, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotNumeric, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotInt(name: String, parent: TileDataSlots, default: Int = 0) extends DataSlotNumeric[Int](default) {
|
||||
case class DataSlotInt(name: String, parent: DataSlotContainer, default: Int = 0) extends DataSlotNumeric[Int](default) {
|
||||
def save(t: NBTTagCompound, kind: UpdateKind.Value) = t.setInteger(name, value)
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value = t.getInteger(name)
|
||||
}
|
||||
@@ -9,13 +9,12 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.data.base.{DataSlot, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind}
|
||||
import net.bdew.lib.tile.inventory.BaseInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.{NBTTagCompound, NBTTagList}
|
||||
|
||||
case class DataSlotInventory(name: String, parent: TileDataSlots, size: Int) extends DataSlot with BaseInventory {
|
||||
case class DataSlotInventory(name: String, parent: DataSlotContainer, size: Int) extends DataSlot with BaseInventory {
|
||||
setUpdate(UpdateKind.SAVE)
|
||||
|
||||
override def getSizeInventory = size
|
||||
@@ -23,9 +22,10 @@ case class DataSlotInventory(name: String, parent: TileDataSlots, size: Int) ext
|
||||
|
||||
override def load(t: NBTTagCompound, kind: UpdateKind.Value) {
|
||||
inv = new Array[ItemStack](getSizeInventory)
|
||||
for (nbtItem <- Misc.iterNbtCompoundList(t, name)) {
|
||||
import net.bdew.lib.nbt._
|
||||
for (nbtItem <- t.getList[NBTTagCompound](name)) {
|
||||
val slot = nbtItem.getByte("Slot")
|
||||
if (slot >= 0 && slot < inv.size) {
|
||||
if (slot >= 0 && slot < inv.length) {
|
||||
inv(slot) = ItemStack.loadItemStackFromNBT(nbtItem)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlotVal, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotVal, UpdateKind}
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotItemStack(name: String, parent: TileDataSlots) extends DataSlotVal[ItemStack] {
|
||||
case class DataSlotItemStack(name: String, parent: DataSlotContainer) extends DataSlotVal[ItemStack] {
|
||||
var value: ItemStack = null
|
||||
|
||||
override def update(v: ItemStack) = {
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.data
|
||||
|
||||
import java.io.{ByteArrayInputStream, ByteArrayOutputStream, DataInputStream, DataOutputStream}
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
case class DataSlotMovingAverage(name: String, parent: DataSlotContainer, size: Int) extends DataSlot {
|
||||
val values = mutable.Queue.empty[Double]
|
||||
var average: Double = 0
|
||||
|
||||
setUpdate(UpdateKind.GUI, UpdateKind.SAVE)
|
||||
|
||||
def reset() {
|
||||
values.clear()
|
||||
average = 0
|
||||
}
|
||||
|
||||
def update(v: Double) = {
|
||||
values += v
|
||||
if (values.length > size)
|
||||
values.dequeue()
|
||||
average = values.sum / values.length
|
||||
parent.dataSlotChanged(this)
|
||||
}
|
||||
override def save(t: NBTTagCompound, kind: UpdateKind.Value) {
|
||||
if (kind == UpdateKind.GUI) {
|
||||
t.setDouble(name, average)
|
||||
} else {
|
||||
val b = new ByteArrayOutputStream()
|
||||
val o = new DataOutputStream(b)
|
||||
o.writeByte(values.size)
|
||||
values.foreach(o.writeDouble)
|
||||
t.setByteArray(name, b.toByteArray)
|
||||
o.close()
|
||||
}
|
||||
}
|
||||
|
||||
override def load(t: NBTTagCompound, kind: UpdateKind.Value) {
|
||||
if (kind == UpdateKind.GUI) {
|
||||
average = t.getDouble(name)
|
||||
} else {
|
||||
values.clear()
|
||||
if (t.hasKey(name)) {
|
||||
val i = new DataInputStream(new ByteArrayInputStream(t.getByteArray(name)))
|
||||
val len = i.readByte()
|
||||
values ++= (for (x <- 0 until Math.min(len, size)) yield i.readDouble())
|
||||
i.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,10 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlotVal, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotVal, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotString(name: String, parent: TileDataSlots, default: String = null) extends DataSlotVal[String] {
|
||||
case class DataSlotString(name: String, parent: DataSlotContainer, default: String = null) extends DataSlotVal[String] {
|
||||
var value: String = default
|
||||
def save(t: NBTTagCompound, kind: UpdateKind.Value) = if (value != null) t.setString(name, value)
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value = if (t.hasKey(name)) t.getString(name) else null
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlot, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.fluids.{FluidStack, FluidTank, IFluidTank}
|
||||
import net.minecraftforge.fluids._
|
||||
|
||||
abstract class DataSlotTankBase(sz: Int) extends FluidTank(sz) with IFluidTank with DataSlot {
|
||||
var oldStack: FluidStack = null
|
||||
|
||||
parent.serverTick.listen(checkUpdate)
|
||||
parent.onServerTick(checkUpdate)
|
||||
|
||||
updateKind = Set(UpdateKind.GUI, UpdateKind.SAVE)
|
||||
|
||||
@@ -50,28 +50,30 @@ abstract class DataSlotTankBase(sz: Int) extends FluidTank(sz) with IFluidTank w
|
||||
if (sendCapacityOnUpdateKind.contains(k))
|
||||
setCapacity(tag.getInteger("size"))
|
||||
}
|
||||
|
||||
override def setFluid(fluid: FluidStack) = execWithChangeNotify(super.setFluid(fluid))
|
||||
override def setCapacity(capacity: Int) = execWithChangeNotify(super.setCapacity(capacity))
|
||||
|
||||
override def drain(maxDrain: Int, doDrain: Boolean) =
|
||||
if (doDrain)
|
||||
execWithChangeNotify(super.drain(maxDrain, true))
|
||||
execWithChangeNotifyConditional[FluidStack](super.drain(maxDrain, true), _ != null)
|
||||
else
|
||||
super.drain(maxDrain, false)
|
||||
|
||||
override def fill(resource: FluidStack, doFill: Boolean) =
|
||||
if (doFill)
|
||||
execWithChangeNotify(super.fill(resource, true))
|
||||
execWithChangeNotifyConditional[Int](super.fill(resource, true), _ > 0)
|
||||
else
|
||||
super.fill(resource, false)
|
||||
}
|
||||
|
||||
case class DataSlotTank(name: String, parent: TileDataSlots, size: Int) extends DataSlotTankBase(size)
|
||||
case class DataSlotTank(name: String, parent: DataSlotContainer, size: Int) extends DataSlotTankBase(size)
|
||||
|
||||
case class DataSlotTankRestricted(name: String, parent: TileDataSlots, var size: Int, fluidID: Int) extends DataSlotTankBase(size) {
|
||||
def fill(amount: Int, doFill: Boolean) = super.fill(new FluidStack(fluidID, amount), doFill)
|
||||
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 = {
|
||||
if ((resource != null) && (resource.fluidID != fluidID)) return 0
|
||||
if ((resource != null) && (resource.getFluid != filterFluid)) return 0
|
||||
return super.fill(resource, doFill)
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ trait DataSlot {
|
||||
* Tile Entity that owns this slot
|
||||
* Accessed in constructor, so should be in parameters or a lazy val, otherwise will crash
|
||||
*/
|
||||
val parent: TileDataSlots
|
||||
val parent: DataSlotContainer
|
||||
|
||||
/**
|
||||
* Unique name
|
||||
@@ -41,6 +41,13 @@ trait DataSlot {
|
||||
v
|
||||
}
|
||||
|
||||
def execWithChangeNotifyConditional[T](f: => T, condition: T => Boolean): T = {
|
||||
val v = f
|
||||
if (condition(v))
|
||||
parent.dataSlotChanged(this)
|
||||
v
|
||||
}
|
||||
|
||||
def setUpdate(vals: UpdateKind.Value*): this.type = {
|
||||
updateKind = vals.toSet
|
||||
return this
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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.data.base
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.world.World
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
/**
|
||||
* Base Trait for objects that can contain Data Slots, this allows implementing them on things that aren't TEs
|
||||
*/
|
||||
trait DataSlotContainer {
|
||||
|
||||
// Can't use getWorldObj - it fails to get remapped and stuff breaks in obfuscated environment
|
||||
def getWorldObject: World
|
||||
|
||||
/**
|
||||
* Called when a dataslot value changes
|
||||
*/
|
||||
def dataSlotChanged(slot: DataSlot): Unit
|
||||
|
||||
/**
|
||||
* Register a function to run on every server tick
|
||||
*/
|
||||
def onServerTick(f: () => Unit): Unit
|
||||
|
||||
/**
|
||||
* List of dataslots in this container
|
||||
*/
|
||||
val dataSlots = mutable.HashMap.empty[String, DataSlot]
|
||||
|
||||
/**
|
||||
* The value of getTotalWorldTime when the last change happened
|
||||
*/
|
||||
var lastChange = 0L
|
||||
|
||||
/**
|
||||
* The value of getTotalWorldTime when the last GUI packet was sent happened
|
||||
*/
|
||||
var lastGuiPacket = 0L
|
||||
|
||||
final val TRACE = false
|
||||
|
||||
def doSave(kind: UpdateKind.Value, t: NBTTagCompound) {
|
||||
if (kind == UpdateKind.GUI)
|
||||
t.setLong("BDLib_TS", getWorldObject.getTotalWorldTime)
|
||||
for ((n, s) <- dataSlots if s.updateKind.contains(kind)) {
|
||||
s.save(t, kind)
|
||||
if (TRACE) printf("%s: %s S=> %s\n".format(kind, n, t.getTag(n)))
|
||||
}
|
||||
}
|
||||
|
||||
def doLoad(kind: UpdateKind.Value, t: NBTTagCompound) {
|
||||
if (kind == UpdateKind.GUI) {
|
||||
val ts = t.getLong("BDLib_TS")
|
||||
if (ts > lastGuiPacket) {
|
||||
lastGuiPacket = ts
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
for ((n, s) <- dataSlots if s.updateKind.contains(kind)) {
|
||||
if (TRACE) printf("%s: %s L<= %s\n".format(kind, n, t.getTag(n)))
|
||||
s.load(t, kind)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,4 +19,9 @@ abstract class DataSlotNumeric[T](default: T)(implicit n: Numeric[T]) extends Da
|
||||
def +=(that: T) = update(n.plus(value, that))
|
||||
def -=(that: T) = update(n.minus(value, that))
|
||||
def *=(that: T) = update(n.times(value, that))
|
||||
|
||||
/* Special Int versions, using the conversion from numeric */
|
||||
def +=(that: Int) = update(n.plus(value, n.fromInt(that)))
|
||||
def -=(that: Int) = update(n.minus(value, n.fromInt(that)))
|
||||
def *=(that: Int) = update(n.times(value, n.fromInt(that)))
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2014
|
||||
* Copyright (c) bdew, 2013 - 2015
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
@@ -14,36 +14,21 @@ import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.network.Packet
|
||||
import net.minecraft.network.play.server.S35PacketUpdateTileEntity
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
trait TileDataSlots extends TileExtended {
|
||||
val dataSlots = mutable.HashMap.empty[String, DataSlot]
|
||||
var lastChange = 0L
|
||||
|
||||
final val TRACE = false
|
||||
|
||||
def doSave(kind: UpdateKind.Value, t: NBTTagCompound) {
|
||||
for ((n, s) <- dataSlots if s.updateKind.contains(kind)) {
|
||||
s.save(t, kind)
|
||||
if (TRACE) printf("%s: %s S=> %s\n".format(kind, n, t.getTag(n)))
|
||||
}
|
||||
}
|
||||
|
||||
def doLoad(kind: UpdateKind.Value, t: NBTTagCompound) {
|
||||
for ((n, s) <- dataSlots if s.updateKind.contains(kind)) {
|
||||
if (TRACE) printf("%s: %s L<= %s\n".format(kind, n, t.getTag(n)))
|
||||
s.load(t, kind)
|
||||
if (kind == UpdateKind.WORLD && s.updateKind.contains(UpdateKind.RENDER))
|
||||
getWorldObj.markBlockRangeForRenderUpdate(xCoord, yCoord, zCoord, xCoord, yCoord, zCoord)
|
||||
}
|
||||
}
|
||||
|
||||
trait TileDataSlots extends TileExtended with DataSlotContainer {
|
||||
persistSave.listen(doSave(UpdateKind.SAVE, _))
|
||||
persistLoad.listen(doLoad(UpdateKind.SAVE, _))
|
||||
sendClientUpdate.listen(doSave(UpdateKind.WORLD, _))
|
||||
handleClientUpdate.listen(doLoad(UpdateKind.WORLD, _))
|
||||
handleClientUpdate.listen { tag =>
|
||||
doLoad(UpdateKind.WORLD, tag)
|
||||
if (dataSlots.values.exists(_.updateKind.contains(UpdateKind.RENDER)))
|
||||
getWorldObj.markBlockRangeForRenderUpdate(xCoord, yCoord, zCoord, xCoord, yCoord, zCoord)
|
||||
}
|
||||
|
||||
def dataSlotChanged(slot: DataSlot) {
|
||||
override def getWorldObject = getWorldObj
|
||||
|
||||
override def onServerTick(f: () => Unit) = serverTick.listen(f)
|
||||
|
||||
override def dataSlotChanged(slot: DataSlot) = {
|
||||
if (getWorldObj != null) {
|
||||
if (slot.updateKind.contains(UpdateKind.GUI))
|
||||
lastChange = getWorldObj.getTotalWorldTime
|
||||
@@ -57,7 +42,7 @@ trait TileDataSlots extends TileExtended {
|
||||
def getDataSlotPacket: Packet = {
|
||||
val tag = new NBTTagCompound()
|
||||
doSave(UpdateKind.GUI, tag)
|
||||
return new S35PacketUpdateTileEntity(this.xCoord, this.yCoord, this.zCoord, ACT_GUI, tag)
|
||||
return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, ACT_GUI, tag)
|
||||
}
|
||||
|
||||
override protected def extDataPacket(id: Int, data: NBTTagCompound) {
|
||||
|
||||
@@ -16,7 +16,7 @@ case class BaseRect[T: Numeric](x: T, y: T, w: T, h: T) {
|
||||
|
||||
def this(p: BasePoint[T], w: T, h: T) = this(p.x, p.y, w, h)
|
||||
|
||||
def contains(p: BasePoint[T]) = n.gteq(p.x, x) && n.gteq(p.y, y) && n.lteq(p.x, x2) && n.lteq(p.y, y2)
|
||||
def contains(p: BasePoint[T]) = n.gteq(p.x, x) && n.gteq(p.y, y) && n.lt(p.x, x2) && n.lt(p.y, y2)
|
||||
|
||||
def origin = BasePoint(x, y)
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
package net.bdew.lib.items.inventory
|
||||
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.tile.inventory.BaseInventory
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
@@ -23,10 +22,11 @@ class InventoryItemAdapter(val player: EntityPlayer, val slot: Int, val size: In
|
||||
load()
|
||||
|
||||
def load() {
|
||||
import net.bdew.lib.nbt._
|
||||
val tag = getStack.getTagCompound
|
||||
for (nbtItem <- Misc.iterNbtCompoundList(tag, tagName)) {
|
||||
for (nbtItem <- tag.getList[NBTTagCompound](tagName)) {
|
||||
val slot = nbtItem.getByte("Slot")
|
||||
if (slot >= 0 && slot < inv.size) {
|
||||
if (slot >= 0 && slot < inv.length) {
|
||||
inv(slot) = ItemStack.loadItemStackFromNBT(nbtItem)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -9,15 +9,14 @@
|
||||
|
||||
package net.bdew.lib.multiblock.data
|
||||
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.block.BlockFace
|
||||
import net.bdew.lib.data.base.{DataSlot, TileDataSlots, UpdateKind}
|
||||
import net.minecraft.nbt.{NBTTagCompound, NBTTagIntArray, NBTTagList}
|
||||
import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
case class DataSlotBlockFaceMap(name: String, parent: TileDataSlots) extends DataSlot {
|
||||
case class DataSlotBlockFaceMap(name: String, parent: DataSlotContainer) extends DataSlot {
|
||||
val map = collection.mutable.Map.empty[BlockFace, Int]
|
||||
|
||||
setUpdate(UpdateKind.SAVE, UpdateKind.WORLD)
|
||||
@@ -27,15 +26,15 @@ case class DataSlotBlockFaceMap(name: String, parent: TileDataSlots) extends Dat
|
||||
def ent2arr(x: (BlockFace, Int)) = Array(x._2, x._1.x, x._1.y, x._1.z, x._1.face.ordinal())
|
||||
def arr2ent(x: Array[Int]) = BlockFace(x(1), x(2), x(3), ForgeDirection.values()(x(4))) -> x(0)
|
||||
|
||||
import net.bdew.lib.nbt._
|
||||
|
||||
def save(t: NBTTagCompound, kind: UpdateKind.Value) {
|
||||
val lst = new NBTTagList()
|
||||
for (x <- map) lst.appendTag(new NBTTagIntArray(ent2arr(x)))
|
||||
t.setTag(name, lst)
|
||||
t.setList(name, map.map(ent2arr))
|
||||
}
|
||||
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) {
|
||||
map.clear()
|
||||
map ++= Misc.iterNbtIntArray(t, name) map arr2ent
|
||||
map ++= t.getList[Array[Int]](name) map arr2ent
|
||||
}
|
||||
|
||||
def updated() = parent.dataSlotChanged(this)
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
|
||||
package net.bdew.lib.multiblock.data
|
||||
|
||||
import net.bdew.lib.data.base.{DataSlot, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
case class DataSlotOutputConfig(name: String, parent: TileDataSlots, slots: Int) extends DataSlot {
|
||||
case class DataSlotOutputConfig(name: String, parent: DataSlotContainer, slots: Int) extends DataSlot {
|
||||
val map = collection.mutable.Map.empty[Int, OutputConfig]
|
||||
|
||||
setUpdate(UpdateKind.SAVE, UpdateKind.GUI)
|
||||
|
||||
@@ -12,14 +12,14 @@ package net.bdew.lib.multiblock.data
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.block.BlockRef
|
||||
import net.bdew.lib.data.DataSlotOption
|
||||
import net.bdew.lib.data.base.{TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotPos(name: String, parent: TileDataSlots) extends DataSlotOption[BlockRef] {
|
||||
case class DataSlotPos(name: String, parent: DataSlotContainer) extends DataSlotOption[BlockRef] {
|
||||
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) {
|
||||
|
||||
@@ -11,29 +11,28 @@ package net.bdew.lib.multiblock.data
|
||||
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.block.BlockRef
|
||||
import net.bdew.lib.data.base.{DataSlot, TileDataSlots, UpdateKind}
|
||||
import net.minecraft.nbt.{NBTTagCompound, NBTTagList}
|
||||
import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
case class DataSlotPosSet(name: String, parent: TileDataSlots) extends DataSlot {
|
||||
case class DataSlotPosSet(name: String, parent: DataSlotContainer) extends DataSlot {
|
||||
val set = collection.mutable.Set.empty[BlockRef]
|
||||
|
||||
setUpdate(UpdateKind.SAVE, UpdateKind.WORLD)
|
||||
|
||||
import net.bdew.lib.nbt._
|
||||
|
||||
def save(t: NBTTagCompound, kind: UpdateKind.Value) {
|
||||
val lst = new NBTTagList()
|
||||
for (x <- set) lst.appendTag(Misc.applyMutator(x.writeToNBT, new NBTTagCompound))
|
||||
t.setTag(name, lst)
|
||||
t.setList(name, set.map(x => Misc.applyMutator(x.writeToNBT, new NBTTagCompound)))
|
||||
}
|
||||
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) {
|
||||
set.clear()
|
||||
set ++= Misc.iterNbtCompoundList(t, name) map BlockRef.fromNBT
|
||||
set ++= t.getList[NBTTagCompound](name) map BlockRef.fromNBT
|
||||
}
|
||||
|
||||
def updated() = parent.dataSlotChanged(this)
|
||||
|
||||
}
|
||||
|
||||
object DataSlotPosSet {
|
||||
|
||||
@@ -10,26 +10,36 @@
|
||||
package net.bdew.lib.multiblock.data
|
||||
|
||||
import net.bdew.lib.multiblock.network.MsgOutputCfg
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.nbt.{NBTTagCompound, NBTTagList}
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
class OutputConfigFluid extends OutputConfig with OutputConfigRSControllable {
|
||||
override def id = "fluid"
|
||||
var avg = 0.0
|
||||
val values = mutable.Queue.empty[Double]
|
||||
var rsMode = RSMode.ALWAYS
|
||||
|
||||
final val decay = 0.5
|
||||
final val ticks = 20
|
||||
|
||||
import net.bdew.lib.nbt._
|
||||
|
||||
def avg = values.sum / values.size
|
||||
|
||||
def updateAvg(v: Double) {
|
||||
avg = avg * decay + (1 - decay) * v
|
||||
values += v
|
||||
if (values.size > ticks)
|
||||
values.dequeue()
|
||||
}
|
||||
|
||||
def read(t: NBTTagCompound) {
|
||||
avg = t.getDouble("avg")
|
||||
values.clear()
|
||||
values ++= t.getList[Double]("values")
|
||||
rsMode = RSMode(t.getInteger("rsMode"))
|
||||
}
|
||||
|
||||
def write(t: NBTTagCompound) {
|
||||
t.setDouble("avg", avg)
|
||||
val l = new NBTTagList
|
||||
t.setList("values", values)
|
||||
t.setInteger("rsMode", rsMode.id)
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* 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.multiblock.interact
|
||||
|
||||
import net.bdew.lib.multiblock.tile.TileController
|
||||
import net.minecraft.inventory.IInventory
|
||||
|
||||
trait CIItemInput extends TileController {
|
||||
def getItemInputInventory: IInventory
|
||||
def canInputItemToSlot(slot: Int): Boolean
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -41,13 +41,15 @@ trait TileModule extends TileDataSlots {
|
||||
}
|
||||
|
||||
def onBreak() {
|
||||
getCore map (_.moduleRemoved(this))
|
||||
getCore foreach (_.moduleRemoved(this))
|
||||
}
|
||||
|
||||
def canConnectToCore(br: BlockRef) = true
|
||||
|
||||
def tryConnect() {
|
||||
if (getCore.isEmpty) {
|
||||
for {
|
||||
conn <- Tools.findConnections(getWorldObj, myPos, kind).headOption
|
||||
conn <- Tools.findConnections(getWorldObj, myPos, kind).headOption if canConnectToCore(conn)
|
||||
core <- conn.getTile[TileController](getWorldObj)
|
||||
} {
|
||||
connect(core)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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.nbt
|
||||
|
||||
import net.minecraft.nbt.NBTTagList
|
||||
|
||||
import scala.annotation.implicitNotFound
|
||||
|
||||
@implicitNotFound("Type ${R} can't currently be retrieved from NBT lists")
|
||||
case class ListElement[R](definition: Type[R], fromList: (NBTTagList, Int) => R)
|
||||
|
||||
object ListElement {
|
||||
def apply[R: ListElement] = implicitly[ListElement[R]]
|
||||
|
||||
import Type._
|
||||
|
||||
implicit val stringInList = ListElement(TString, _.getStringTagAt(_))
|
||||
implicit val compoundInList = ListElement(TCompound, _.getCompoundTagAt(_))
|
||||
implicit val intArrayInList = ListElement(TIntArray, _.func_150306_c(_))
|
||||
implicit val doubleInList = ListElement(TDouble, _.func_150309_d(_))
|
||||
implicit val floatInList = ListElement(TFloat, _.func_150308_e(_))
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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.nbt
|
||||
|
||||
import net.minecraft.nbt.{NBTTagCompound, NBTTagList}
|
||||
|
||||
import scala.language.implicitConversions
|
||||
|
||||
class RichNBTTagCompound(tag: NBTTagCompound) {
|
||||
|
||||
def getList[T: ListElement](name: String): Iterable[T] = {
|
||||
val tDef = ListElement[T]
|
||||
val list = tag.getTagList(name, tDef.definition.id)
|
||||
for (i <- 0 until list.tagCount()) yield tDef.fromList(list, i)
|
||||
}
|
||||
|
||||
def setList[T: Type](name: String, v: Iterable[T]): Unit = {
|
||||
val list = new NBTTagList
|
||||
for (x <- v) list.appendTag(Type[T].toNBT(x))
|
||||
tag.setTag(name, list)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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.nbt._
|
||||
|
||||
import scala.annotation.implicitNotFound
|
||||
|
||||
@implicitNotFound("Type ${R} is not supported by NBT")
|
||||
trait Type[R] {
|
||||
def id: Int
|
||||
def toNBT(p: R): NBTBase
|
||||
def fromCompound(t: NBTTagCompound, n: String): Option[R]
|
||||
}
|
||||
|
||||
object Type {
|
||||
def apply[R: Type] = implicitly[Type[R]]
|
||||
|
||||
implicit object TByte extends TypeDef(1, classOf[NBTTagByte], classOf[Byte]) {
|
||||
override def toVal(p: NBTTagByte): Byte = p.func_150290_f()
|
||||
override def toNBT(p: Byte): NBTTagByte = new NBTTagByte(p)
|
||||
}
|
||||
|
||||
implicit object TShort extends TypeDef(2, classOf[NBTTagShort], classOf[Short]) {
|
||||
override def toVal(p: NBTTagShort): Short = p.func_150289_e()
|
||||
override def toNBT(p: Short): NBTTagShort = new NBTTagShort(p)
|
||||
}
|
||||
|
||||
implicit object TInt extends TypeDef(3, classOf[NBTTagInt], classOf[Int]) {
|
||||
override def toVal(p: NBTTagInt): Int = p.func_150287_d()
|
||||
override def toNBT(p: Int): NBTTagInt = new NBTTagInt(p)
|
||||
}
|
||||
|
||||
implicit object TLong extends TypeDef(4, classOf[NBTTagLong], classOf[Long]) {
|
||||
override def toVal(p: NBTTagLong): Long = p.func_150291_c()
|
||||
override def toNBT(p: Long): NBTTagLong = new NBTTagLong(p)
|
||||
}
|
||||
|
||||
implicit object TFloat extends TypeDef(5, classOf[NBTTagFloat], classOf[Float]) {
|
||||
override def toVal(p: NBTTagFloat): Float = p.func_150288_h()
|
||||
override def toNBT(p: Float): NBTTagFloat = new NBTTagFloat(p)
|
||||
}
|
||||
|
||||
implicit object TDouble extends TypeDef(6, classOf[NBTTagDouble], classOf[Double]) {
|
||||
override def toVal(p: NBTTagDouble): Double = p.func_150286_g()
|
||||
override def toNBT(p: Double): NBTTagDouble = new NBTTagDouble(p)
|
||||
}
|
||||
|
||||
implicit object TByteArray extends TypeDef(7, classOf[NBTTagByteArray], classOf[Array[Byte]]) {
|
||||
override def toVal(p: NBTTagByteArray): Array[Byte] = p.func_150292_c()
|
||||
override def toNBT(p: Array[Byte]): NBTTagByteArray = new NBTTagByteArray(p)
|
||||
}
|
||||
|
||||
implicit object TString extends TypeDef(8, classOf[NBTTagString], classOf[String]) {
|
||||
override def toVal(p: NBTTagString): String = p.func_150285_a_()
|
||||
override def toNBT(p: String): NBTTagString = new NBTTagString(p)
|
||||
}
|
||||
|
||||
implicit object TList extends TypeDefSimple(9, classOf[NBTTagList])
|
||||
|
||||
implicit object TCompound extends TypeDefSimple(10, classOf[NBTTagCompound])
|
||||
|
||||
implicit object TIntArray extends TypeDef(11, classOf[NBTTagIntArray], classOf[Array[Int]]) {
|
||||
override def toVal(p: NBTTagIntArray): Array[Int] = p.func_150302_c()
|
||||
override def toNBT(p: Array[Int]): NBTTagIntArray = new NBTTagIntArray(p)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.nbt.{NBTBase, NBTTagCompound}
|
||||
|
||||
import scala.annotation.implicitNotFound
|
||||
|
||||
@implicitNotFound("Type ${R} is not supported by NBT")
|
||||
abstract class TypeDef[T <: NBTBase, R](val id: Int, val cls: Class[T], val valueClass: Class[R]) extends Type[R] {
|
||||
TypeDef.map += id -> this
|
||||
def toVal(p: T): R
|
||||
def toNBT(p: R): T
|
||||
override def fromCompound(t: NBTTagCompound, n: String): Option[R] =
|
||||
if (t.hasKey(n, id)) Some(toVal(t.getTag(n).asInstanceOf[T])) else None
|
||||
}
|
||||
|
||||
object TypeDef {
|
||||
var map = Map.empty[Int, TypeDef[_, _]]
|
||||
}
|
||||
|
||||
class TypeDefSimple[T <: NBTBase](id: Int, cls: Class[T]) extends TypeDef[T, T](id, cls, cls) {
|
||||
override def toVal(p: T): T = p
|
||||
override def toNBT(p: T): T = p
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
import scala.language.implicitConversions
|
||||
|
||||
package object nbt {
|
||||
implicit def compound2rich(p: NBTTagCompound): RichNBTTagCompound = new RichNBTTagCompound(p)
|
||||
}
|
||||
@@ -10,11 +10,11 @@
|
||||
package net.bdew.lib.power
|
||||
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.data.base.{DataSlot, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind}
|
||||
import net.bdew.lib.machine.PoweredMachine
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotPower(name: String, parent: TileDataSlots) extends DataSlot {
|
||||
case class DataSlotPower(name: String, parent: DataSlotContainer) extends DataSlot {
|
||||
updateKind = Set(UpdateKind.GUI, UpdateKind.SAVE)
|
||||
|
||||
var stored = 0F
|
||||
|
||||
@@ -172,13 +172,16 @@ class RecipeLoader {
|
||||
if (l.size == 0) error("Concrete ItemStack requested for OD entry '%s' that is empty", id)
|
||||
val s = l.get(0).copy()
|
||||
s.stackSize = cnt
|
||||
BdLib.logInfo("Concrete ItemStack for OD entry '%s' -> %s", id, s)
|
||||
BdLib.logDebug("Concrete ItemStack for OD entry '%s' -> %s", id, s)
|
||||
return s
|
||||
case StackMacro(ch) => getConcreteStack(currCharMap(ch), cnt)
|
||||
case StackGeneric(mod, id) =>
|
||||
notNull(GameRegistry.findItemStack(mod, id, cnt), "Stack not found %s:%s".format(mod, id))
|
||||
case StackBlock(mod, id, meta) =>
|
||||
new ItemStack(notNull(GameRegistry.findBlock(mod, id), "Block not found %s:%s".format(mod, id)), cnt, meta)
|
||||
val block = notNull(GameRegistry.findBlock(mod, id), "Block not found %s:%s".format(mod, id))
|
||||
if (Item.getItemFromBlock(block) == null)
|
||||
error("The block '%s:%s' does not have a valid matching item registered and thus can't be used in recipes", mod, id)
|
||||
new ItemStack(block, cnt, meta)
|
||||
case StackItem(mod, id, meta) =>
|
||||
new ItemStack(notNull(GameRegistry.findItem(mod, id), "Item not found %s:%s".format(mod, id)), cnt, meta)
|
||||
case StackReflect(cls, field, meta) => reflectStack(cls, field, meta, cnt)
|
||||
@@ -197,7 +200,7 @@ class RecipeLoader {
|
||||
if (!currCharMap.contains(x)) error("Character %s is undefined", x)
|
||||
val r = getRecipeComponent(currCharMap(x))
|
||||
if (r.isInstanceOf[String]) needOd = true
|
||||
BdLib.logInfo("%s -> %s", x, r)
|
||||
BdLib.logDebug("%s -> %s", x, r)
|
||||
comp += (x -> r)
|
||||
}
|
||||
return (comp, needOd)
|
||||
@@ -213,7 +216,7 @@ class RecipeLoader {
|
||||
list flatMap {
|
||||
case x: CraftingStatement =>
|
||||
if (res == x.result) {
|
||||
BdLib.logInfo("Removing recipe %s", this)
|
||||
BdLib.logDebug("Removing recipe %s", this)
|
||||
None
|
||||
} else Some(x)
|
||||
case RsRecipes(inner) =>
|
||||
@@ -248,15 +251,15 @@ class RecipeLoader {
|
||||
def processConfigStatement(s: ConfigStatement): Unit = s match {
|
||||
case CsConditionalConfig(cnd, thn, els) =>
|
||||
if (resolveCondition(cnd)) {
|
||||
BdLib.logInfo("Condition %s - TRUE", cnd)
|
||||
BdLib.logDebug("Condition %s - TRUE", cnd)
|
||||
processConfigStatementsSafe(thn)
|
||||
} else {
|
||||
BdLib.logInfo("Condition %s - FALSE", cnd)
|
||||
BdLib.logDebug("Condition %s - FALSE", cnd)
|
||||
processConfigStatementsSafe(els)
|
||||
}
|
||||
|
||||
case CsClearRecipes(res) =>
|
||||
BdLib.logInfo("Clearing recipes that produce %s", res)
|
||||
BdLib.logDebug("Clearing recipes that produce %s", res)
|
||||
recipeStatements = clearStatements(recipeStatements, res)
|
||||
|
||||
case CsRecipeBlock(lst) =>
|
||||
@@ -273,19 +276,19 @@ class RecipeLoader {
|
||||
def processRecipeStatement(st: RecipeStatement) = st match {
|
||||
case RsCharAssign(c, r) =>
|
||||
currCharMap += (c -> r)
|
||||
BdLib.logInfo("Added %s = %s", c, r)
|
||||
BdLib.logDebug("Added %s = %s", c, r)
|
||||
|
||||
case RsClassMacro(id, cls) =>
|
||||
currClassMacros += (id -> cls)
|
||||
BdLib.logInfo("Added def %s = %s", id, cls)
|
||||
BdLib.logDebug("Added def %s = %s", id, cls)
|
||||
|
||||
case RsRecipeShaped(rec, res, cnt) =>
|
||||
BdLib.logInfo("Adding shaped recipe %s => %s * %d", rec, res, cnt)
|
||||
BdLib.logDebug("Adding shaped recipe %s => %s * %d", rec, res, cnt)
|
||||
val (comp, needOd) = resolveRecipeComponents(rec.mkString(""))
|
||||
val resStack = getConcreteStack(res, cnt)
|
||||
|
||||
if (resStack.getItemDamage == OreDictionary.WILDCARD_VALUE) {
|
||||
BdLib.logInfo("Result meta is unset, defaulting to 0")
|
||||
BdLib.logDebug("Result meta is unset, defaulting to 0")
|
||||
resStack.setItemDamage(0)
|
||||
}
|
||||
|
||||
@@ -294,16 +297,16 @@ class RecipeLoader {
|
||||
else
|
||||
Misc.addRecipe(resStack, rec, comp)
|
||||
|
||||
BdLib.logInfo("Done... result=%s, od=%s", resStack, needOd)
|
||||
BdLib.logDebug("Done... result=%s, od=%s", resStack, needOd)
|
||||
|
||||
case RsRecipeShapeless(rec, res, cnt) =>
|
||||
BdLib.logInfo("Adding shapeless recipe %s => %s * %d", rec, res, cnt)
|
||||
BdLib.logDebug("Adding shapeless recipe %s => %s * %d", rec, res, cnt)
|
||||
val (comp, needOd) = resolveRecipeComponents(rec)
|
||||
val resStack = getConcreteStack(res, cnt)
|
||||
val recTrans = rec.toCharArray.map(comp(_))
|
||||
|
||||
if (resStack.getItemDamage == OreDictionary.WILDCARD_VALUE) {
|
||||
BdLib.logInfo("Result meta is unset, defaulting to 0")
|
||||
BdLib.logDebug("Result meta is unset, defaulting to 0")
|
||||
resStack.setItemDamage(0)
|
||||
}
|
||||
|
||||
@@ -312,26 +315,26 @@ class RecipeLoader {
|
||||
else
|
||||
GameRegistry.addShapelessRecipe(resStack, recTrans: _*)
|
||||
|
||||
BdLib.logInfo("Done... result=%s, od=%s", resStack, needOd)
|
||||
BdLib.logDebug("Done... result=%s, od=%s", resStack, needOd)
|
||||
|
||||
case RsRecipeSmelting(in, out, cnt, xp) =>
|
||||
BdLib.logInfo("Adding smelting recipe %s => %s * %d (%f xp)", in, out, cnt, xp)
|
||||
BdLib.logDebug("Adding smelting recipe %s => %s * %d (%f xp)", in, out, cnt, xp)
|
||||
val outStack = getConcreteStack(out, cnt)
|
||||
if (outStack.getItemDamage == OreDictionary.WILDCARD_VALUE) {
|
||||
BdLib.logInfo("Result meta is unset, defaulting to 0")
|
||||
BdLib.logDebug("Result meta is unset, defaulting to 0")
|
||||
outStack.setItemDamage(0)
|
||||
}
|
||||
for (inStack <- getAllConcreteStacks(in, 1)) {
|
||||
GameRegistry.addSmelting(inStack, outStack, xp)
|
||||
BdLib.logInfo("added %s -> %s", inStack, outStack)
|
||||
BdLib.logDebug("added %s -> %s", inStack, outStack)
|
||||
}
|
||||
|
||||
case RsConditional(cnd, thn, els) =>
|
||||
if (resolveCondition(cnd)) {
|
||||
BdLib.logInfo("Condition %s - TRUE", cnd)
|
||||
BdLib.logDebug("Condition %s - TRUE", cnd)
|
||||
processRecipeStatementsInSubcontext(thn)
|
||||
} else {
|
||||
BdLib.logInfo("Condition %s - FALSE", cnd)
|
||||
BdLib.logDebug("Condition %s - FALSE", cnd)
|
||||
processRecipeStatementsInSubcontext(els)
|
||||
}
|
||||
|
||||
@@ -339,13 +342,13 @@ class RecipeLoader {
|
||||
processRecipeStatementsInSubcontext(list)
|
||||
|
||||
case RsRegOredict(id, spec, wildcard) =>
|
||||
BdLib.logInfo("Registering ore dictionary entry: %s -> %s", spec, id)
|
||||
BdLib.logDebug("Registering ore dictionary entry: %s -> %s", spec, id)
|
||||
val stack = getConcreteStack(spec)
|
||||
if (wildcard) {
|
||||
BdLib.logInfo("Forcing wildcard damage (was %d)", stack.getItemDamage)
|
||||
BdLib.logDebug("Forcing wildcard damage (was %d)", stack.getItemDamage)
|
||||
stack.setItemDamage(OreDictionary.WILDCARD_VALUE)
|
||||
}
|
||||
BdLib.logInfo("Actual stack: %s", stack)
|
||||
BdLib.logDebug("Actual stack: %s", stack)
|
||||
OreDictionary.registerOre(id, stack)
|
||||
|
||||
case x =>
|
||||
@@ -371,7 +374,7 @@ class RecipeLoader {
|
||||
* Process main recipe statements list, clear the list afterwards
|
||||
*/
|
||||
def processRecipeStatements() {
|
||||
BdLib.logInfo("Processing %d recipe statements", recipeStatements.size)
|
||||
BdLib.logDebug("Processing %d recipe statements", recipeStatements.size)
|
||||
processRecipeStatementsSafe(recipeStatements)
|
||||
recipeStatements = List.empty
|
||||
}
|
||||
@@ -411,10 +414,10 @@ class RecipeLoader {
|
||||
}
|
||||
|
||||
def load(f: Reader) {
|
||||
BdLib.logInfo("Starting parsing")
|
||||
BdLib.logDebug("Starting parsing")
|
||||
val r = newParser().doParse(f)
|
||||
BdLib.logInfo("Processing %d statements", r.size)
|
||||
BdLib.logDebug("Processing %d statements", r.size)
|
||||
processConfigStatementsSafe(r)
|
||||
BdLib.logInfo("Done")
|
||||
BdLib.logDebug("Done")
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -17,7 +17,7 @@ trait GenericConfigLoader extends RecipeLoader {
|
||||
|
||||
def processConfigStatement(section: ConfigSection, s: CfgEntry): Unit = s match {
|
||||
case CfgVal(id, v) =>
|
||||
BdLib.logInfo("Config: %s%s = %s", section.pfx, id, v)
|
||||
BdLib.logDebug("Config: %s%s = %s", section.pfx, id, v)
|
||||
section.set(id, v)
|
||||
case CfgSection(id, st) => processConfigBlock(section.getOrAddSection(id), st)
|
||||
case x =>
|
||||
|
||||
@@ -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)
|
||||
@@ -29,7 +29,7 @@ trait LootListLoader extends GenericConfigLoader {
|
||||
None
|
||||
} else {
|
||||
if (itemStack.getItemDamage == OreDictionary.WILDCARD_VALUE) {
|
||||
BdLib.logInfo("meta/damage is unset in %s, defaulting to 0", ref)
|
||||
BdLib.logDebug("meta/damage is unset in %s, defaulting to 0", ref)
|
||||
itemStack.setItemDamage(0)
|
||||
}
|
||||
Some((chance, itemStack))
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
package net.bdew.lib.render
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.gui.{IconWrapper, Texture}
|
||||
import net.minecraft.client.renderer.texture.IIconRegister
|
||||
import net.minecraft.util.IIcon
|
||||
@@ -21,6 +22,13 @@ import net.minecraftforge.common.MinecraftForge
|
||||
* @param kind 0=Blocks / 1=Items
|
||||
*/
|
||||
class IconPreloader(kind: Int) {
|
||||
lazy val map = {
|
||||
(for {
|
||||
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
|
||||
}
|
||||
|
||||
var icons = Set.empty[TextureLoc]
|
||||
|
||||
val sheet = kind match {
|
||||
|
||||
@@ -36,6 +36,8 @@ object RenderUtils {
|
||||
* Render a simple block as an item (for gui, item entities etc.)
|
||||
*/
|
||||
def renderSimpleBlockItem(block: Block, metadata: Int, renderer: RenderBlocks) {
|
||||
block.setBlockBoundsForItemRender()
|
||||
renderer.setRenderBoundsFromBlock(block)
|
||||
val T = Tessellator.instance
|
||||
GL11.glTranslatef(-0.5F, -0.5F, -0.5F)
|
||||
for (side <- ForgeDirection.VALID_DIRECTIONS) {
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.render
|
||||
|
||||
import net.bdew.lib.render.connected.ConnectedHelper.{EdgeDraw, RectF}
|
||||
import net.bdew.lib.rotate.BaseRotatableBlock
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.client.renderer.RenderBlocks
|
||||
import net.minecraft.world.IBlockAccess
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
object RotatedBlockRenderer extends BaseBlockRenderHandler {
|
||||
val filterIconDraw =
|
||||
(for (dir <- ForgeDirection.VALID_DIRECTIONS)
|
||||
yield (dir, new EdgeDraw(RectF(0.35F, 0.35F, 0.65F, 0.65F), dir))).toMap
|
||||
|
||||
def setRenderRotation(renderer: RenderBlocks, side: ForgeDirection): Unit = {
|
||||
side.ordinal() match {
|
||||
case 0 =>
|
||||
renderer.uvRotateEast = 3
|
||||
renderer.uvRotateWest = 3
|
||||
renderer.uvRotateSouth = 3
|
||||
renderer.uvRotateNorth = 3
|
||||
case 2 =>
|
||||
renderer.uvRotateSouth = 1
|
||||
renderer.uvRotateNorth = 2
|
||||
case 3 =>
|
||||
renderer.uvRotateSouth = 2
|
||||
renderer.uvRotateNorth = 1
|
||||
renderer.uvRotateTop = 3
|
||||
renderer.uvRotateBottom = 3
|
||||
case 4 =>
|
||||
renderer.uvRotateEast = 1
|
||||
renderer.uvRotateWest = 2
|
||||
renderer.uvRotateTop = 2
|
||||
renderer.uvRotateBottom = 1
|
||||
case 5 =>
|
||||
renderer.uvRotateEast = 2
|
||||
renderer.uvRotateWest = 1
|
||||
renderer.uvRotateTop = 1
|
||||
renderer.uvRotateBottom = 2
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
def clearRenderRotation(renderer: RenderBlocks): Unit = {
|
||||
renderer.uvRotateEast = 0
|
||||
renderer.uvRotateWest = 0
|
||||
renderer.uvRotateSouth = 0
|
||||
renderer.uvRotateNorth = 0
|
||||
renderer.uvRotateTop = 0
|
||||
renderer.uvRotateBottom = 0
|
||||
}
|
||||
|
||||
override def renderInventoryBlock(block: Block, metadata: Int, modelID: Int, renderer: RenderBlocks) {
|
||||
setRenderRotation(renderer, block.asInstanceOf[BaseRotatableBlock].getDefaultFacing)
|
||||
RenderUtils.renderSimpleBlockItem(block, metadata, renderer)
|
||||
clearRenderRotation(renderer)
|
||||
}
|
||||
|
||||
override def renderWorldBlock(world: IBlockAccess, x: Int, y: Int, z: Int, block: Block, modelId: Int, renderer: RenderBlocks): Boolean = {
|
||||
setRenderRotation(renderer, block.asInstanceOf[BaseRotatableBlock].getFacing(world, x, y, z))
|
||||
renderer.renderStandardBlock(block, x, y, z)
|
||||
clearRenderRotation(renderer)
|
||||
true
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2014
|
||||
* Copyright (c) bdew, 2013 - 2015
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
@@ -10,7 +10,8 @@
|
||||
package net.bdew.lib.render.connected
|
||||
|
||||
import net.bdew.lib.block.BlockRef
|
||||
import net.bdew.lib.render.{BaseBlockRenderHandler, RenderUtils}
|
||||
import net.bdew.lib.render.{BaseBlockRenderHandler, RenderUtils, RotatedBlockRenderer}
|
||||
import net.bdew.lib.rotate.BaseRotatableBlock
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.client.renderer.{RenderBlocks, Tessellator}
|
||||
import net.minecraft.world.IBlockAccess
|
||||
@@ -35,7 +36,10 @@ object ConnectedRenderer extends BaseBlockRenderHandler {
|
||||
}
|
||||
|
||||
override def renderWorldBlock(world: IBlockAccess, x: Int, y: Int, z: Int, block: Block, modelId: Int, renderer: RenderBlocks): Boolean = {
|
||||
renderer.renderStandardBlock(block, x, y, z)
|
||||
if (block.isInstanceOf[BaseRotatableBlock])
|
||||
RotatedBlockRenderer.renderWorldBlock(world, x, y, z, block, modelId, renderer)
|
||||
else
|
||||
renderer.renderStandardBlock(block, x, y, z)
|
||||
|
||||
val pos = ConnectedHelper.Vec3F(x, y, z)
|
||||
for (face <- ForgeDirection.VALID_DIRECTIONS)
|
||||
|
||||
@@ -10,13 +10,12 @@
|
||||
package net.bdew.lib.resource
|
||||
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.data.base.{DataSlot, TileDataSlots, UpdateKind}
|
||||
import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.fluids.{FluidStack, FluidTankInfo}
|
||||
|
||||
class DataSlotResource(val name: String, val parent: TileDataSlots, initCapacity: Int) extends DataSlot {
|
||||
class DataSlotResource(val name: String, val parent: DataSlotContainer, initCapacity: Int) extends DataSlot {
|
||||
var resource: Option[Resource] = None
|
||||
var amount = 0D
|
||||
var capacity = initCapacity
|
||||
val sendCapacityOnUpdateKind = Set(UpdateKind.GUI)
|
||||
|
||||
@@ -36,7 +35,7 @@ class DataSlotResource(val name: String, val parent: TileDataSlots, initCapacity
|
||||
val current = if (resource.isEmpty) 0D else resource.get.amount
|
||||
var canFill = Misc.clamp(res.amount, 0D, capacity * res.kind.capacityMultiplier - current)
|
||||
if (onlyRound) canFill = canFill.floor
|
||||
if (doFill) execWithChangeNotify {
|
||||
if (doFill && canFill > 0) execWithChangeNotify {
|
||||
resource = Some(Resource(res.kind, current + canFill))
|
||||
}
|
||||
canFill
|
||||
@@ -54,7 +53,7 @@ class DataSlotResource(val name: String, val parent: TileDataSlots, initCapacity
|
||||
resource map { res =>
|
||||
var canDrain = Misc.clamp(res.amount, 0D, maxDrain)
|
||||
if (onlyRound) canDrain = canDrain.floor
|
||||
if (doDrain) execWithChangeNotify {
|
||||
if (doDrain && canDrain > 0) execWithChangeNotify {
|
||||
resource =
|
||||
if (res.amount - canDrain < 0.000001)
|
||||
None
|
||||
@@ -101,7 +100,7 @@ class DataSlotResource(val name: String, val parent: TileDataSlots, initCapacity
|
||||
override def save(t: NBTTagCompound, kind: UpdateKind.Value) {
|
||||
val tag = new NBTTagCompound()
|
||||
|
||||
resource map { res => tag.setTag("resource", ResourceManager.saveToNBT(res)) }
|
||||
resource foreach { res => tag.setTag("resource", ResourceManager.saveToNBT(res)) }
|
||||
|
||||
if (sendCapacityOnUpdateKind.contains(kind))
|
||||
tag.setInteger("capacity", capacity)
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.resource
|
||||
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.data.DataSlotOption
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotResourceKindOption(name: String, parent: DataSlotContainer) extends DataSlotOption[ResourceKind] {
|
||||
setUpdate(UpdateKind.SAVE, UpdateKind.GUI)
|
||||
|
||||
override def save(t: NBTTagCompound, kind: UpdateKind.Value) {
|
||||
value foreach { r =>
|
||||
t.setTag(name,
|
||||
Misc.applyMutator(new NBTTagCompound) { tag =>
|
||||
r.helperObject.saveToNBT(tag, r)
|
||||
tag.setString("kind", r.helperObject.id)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override def load(t: NBTTagCompound, kind: UpdateKind.Value) {
|
||||
if (t.hasKey(name)) {
|
||||
val tag = t.getCompoundTag(name)
|
||||
value = if (tag.hasKey("kind")) {
|
||||
ResourceManager.resourceHelpers.get(tag.getString("kind")).flatMap(_.loadFromNBT(tag))
|
||||
} else None
|
||||
} else unset()
|
||||
}
|
||||
}
|
||||
@@ -69,21 +69,7 @@ trait BaseRotatableBlock extends Block {
|
||||
override def getValidRotations(worldObj: World, x: Int, y: Int, z: Int): Array[ForgeDirection] = getValidFacings.toArray(Array.empty[ForgeDirection])
|
||||
|
||||
override def onBlockPlacedBy(world: World, x: Int, y: Int, z: Int, ent: EntityLivingBase, stack: ItemStack) {
|
||||
val validRotations = getValidFacings
|
||||
var dir = getDefaultFacing
|
||||
if (ent != null) {
|
||||
val pitch: Int = Math.round(ent.rotationPitch)
|
||||
val yaw: Int = MathHelper.floor_double(ent.rotationYaw * 4.0F / 360.0F + 0.5D) & 3
|
||||
dir = yaw match {
|
||||
case _ if pitch >= 50 && validRotations.contains(ForgeDirection.UP) => ForgeDirection.UP
|
||||
case _ if pitch <= -50 && validRotations.contains(ForgeDirection.DOWN) => ForgeDirection.DOWN
|
||||
case 0 if validRotations.contains(ForgeDirection.NORTH) => ForgeDirection.NORTH
|
||||
case 1 if validRotations.contains(ForgeDirection.EAST) => ForgeDirection.EAST
|
||||
case 2 if validRotations.contains(ForgeDirection.SOUTH) => ForgeDirection.SOUTH
|
||||
case 3 if validRotations.contains(ForgeDirection.WEST) => ForgeDirection.WEST
|
||||
case _ => dir
|
||||
}
|
||||
}
|
||||
val dir = RotatedHelper.getFacingFromEntity(ent, getValidFacings, getDefaultFacing)
|
||||
setFacing(world, x, y, z, dir)
|
||||
super.onBlockPlacedBy(world, x, y, z, ent, stack)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.rotate
|
||||
|
||||
import java.util
|
||||
|
||||
import net.minecraft.entity.EntityLivingBase
|
||||
import net.minecraft.util.MathHelper
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
object RotatedHelper {
|
||||
def getFacingFromEntity(ent: EntityLivingBase, validRotations: util.EnumSet[ForgeDirection], default: ForgeDirection): ForgeDirection = {
|
||||
val pitch = Math.round(ent.rotationPitch)
|
||||
val yaw = MathHelper.floor_double(ent.rotationYaw * 4.0F / 360.0F + 0.5D) & 3
|
||||
yaw match {
|
||||
case _ if pitch >= 50 && validRotations.contains(ForgeDirection.UP) => ForgeDirection.UP
|
||||
case _ if pitch <= -50 && validRotations.contains(ForgeDirection.DOWN) => ForgeDirection.DOWN
|
||||
case 0 if validRotations.contains(ForgeDirection.NORTH) => ForgeDirection.NORTH
|
||||
case 1 if validRotations.contains(ForgeDirection.EAST) => ForgeDirection.EAST
|
||||
case 2 if validRotations.contains(ForgeDirection.SOUTH) => ForgeDirection.SOUTH
|
||||
case 3 if validRotations.contains(ForgeDirection.WEST) => ForgeDirection.WEST
|
||||
case _ => default
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.sensors
|
||||
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.data.base.{DataSlotVal, UpdateKind}
|
||||
import net.bdew.lib.sensors.multiblock.TileRedstoneSensorModule
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotSensor[T, R](registry: SensorSystem[T, R], name: String, parent: TileRedstoneSensorModule, default: GenericSensorType[T, R]) extends DataSlotVal[SensorPair[T, R]] {
|
||||
override var value = SensorPair(default, default.defaultParameter)
|
||||
|
||||
setUpdate(UpdateKind.SAVE, UpdateKind.GUI)
|
||||
|
||||
override def save(t: NBTTagCompound, kind: UpdateKind.Value) = {
|
||||
t.setTag(name, Misc.applyMutator(new NBTTagCompound) { tag =>
|
||||
tag.setString("uid", value.sensor.uid)
|
||||
value.sensor.saveParameter(value.param, tag)
|
||||
})
|
||||
}
|
||||
|
||||
override def load(t: NBTTagCompound, kind: UpdateKind.Value) = {
|
||||
value = registry.get(t.getCompoundTag(name).getString("uid"))
|
||||
.map(x => SensorPair(x, x.loadParameter(t.getCompoundTag(name))))
|
||||
.getOrElse(SensorPair(default, default.defaultParameter))
|
||||
}
|
||||
|
||||
def ensureValid(obj: T): Unit = {
|
||||
if (!value.sensor.isValidParameter(value.param, obj))
|
||||
update(value.copy(param = value.sensor.defaultParameter))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* 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.sensors
|
||||
|
||||
import net.bdew.lib.Misc
|
||||
|
||||
abstract class GenericSensorParameter(system: SensorSystem[_, _]) {
|
||||
val uid: String
|
||||
|
||||
def localizedName = Misc.toLocal(system.localizationPrefix + ".param." + uid)
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.sensors
|
||||
|
||||
import cpw.mods.fml.relauncher.{Side, SideOnly}
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.gui.{DrawTarget, Rect}
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
abstract class GenericSensorType[-T, +R](system: SensorSystem[T, R]) {
|
||||
def uid: String
|
||||
|
||||
system.register(this)
|
||||
|
||||
def getTooltip(obj: T): List[String] = List(localizedName)
|
||||
def getParamTooltip(obj: T, param: GenericSensorParameter): List[String] = List(param.localizedName)
|
||||
|
||||
def localizedName = Misc.toLocal(system.localizationPrefix + "." + uid)
|
||||
|
||||
def defaultParameter: GenericSensorParameter
|
||||
|
||||
def paramClicked(current: GenericSensorParameter, item: ItemStack, button: Int, mod: Int, obj: T): GenericSensorParameter
|
||||
|
||||
def saveParameter(p: GenericSensorParameter, tag: NBTTagCompound)
|
||||
def loadParameter(tag: NBTTagCompound): GenericSensorParameter
|
||||
def isValidParameter(p: GenericSensorParameter, obj: T): Boolean
|
||||
|
||||
def getResult(param: GenericSensorParameter, obj: T): R
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
def drawSensor(rect: Rect, target: DrawTarget, obj: T): Unit
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
def drawParameter(rect: Rect, target: DrawTarget, obj: T, param: GenericSensorParameter): Unit
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.sensors
|
||||
|
||||
import cpw.mods.fml.relauncher.{Side, SideOnly}
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.gui.{DrawTarget, IconWrapper, Rect, Texture}
|
||||
import net.minecraft.init.Blocks
|
||||
|
||||
abstract class RedstoneSensors[T] extends SensorSystem[T, Boolean](false) {
|
||||
lazy val rsOn = new IconWrapper(Texture.BLOCKS, Blocks.redstone_torch.getIcon(0, 0))
|
||||
lazy val rsOff = new IconWrapper(Texture.BLOCKS, Blocks.unlit_redstone_torch.getIcon(0, 0))
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
override def drawResult(result: Boolean, rect: Rect, target: DrawTarget): Unit = {
|
||||
if (result)
|
||||
target.drawTexture(rect, rsOn)
|
||||
else
|
||||
target.drawTexture(rect, rsOff)
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
override def getLocalizedResultText(result: Boolean): String =
|
||||
if (result)
|
||||
Misc.toLocal(localizationPrefix + ".on")
|
||||
else
|
||||
Misc.toLocal(localizationPrefix + ".off")
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* 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.sensors
|
||||
|
||||
case class SensorPair[-T, +R](sensor: GenericSensorType[T, R], param: GenericSensorParameter) {
|
||||
def getResult(obj: T) = sensor.getResult(param, obj)
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.sensors
|
||||
|
||||
import cpw.mods.fml.relauncher.{Side, SideOnly}
|
||||
import net.bdew.lib.gui._
|
||||
import net.bdew.lib.{BdLib, Misc}
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
abstract class SensorSystem[T, R](defaultResult: R) {
|
||||
val map = collection.mutable.Map.empty[String, GenericSensorType[T, R]]
|
||||
def get(uid: String) = map.get(uid)
|
||||
|
||||
def register[Z <: GenericSensorType[T, R]](s: Z): Z = {
|
||||
if (map.isDefinedAt(s.uid))
|
||||
sys.error("Duplicate sensor ID: %s (%s / %s)".format(s.uid, map(s.uid), s))
|
||||
map += s.uid -> s
|
||||
s
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
def disabledTexture: Texture
|
||||
|
||||
def localizationPrefix: String
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
def drawResult(result: R, rect: Rect, target: DrawTarget): Unit
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
def getLocalizedResultText(result: R): String
|
||||
|
||||
abstract class SensorType extends GenericSensorType(this)
|
||||
|
||||
abstract class SensorParameter extends GenericSensorParameter(this)
|
||||
|
||||
abstract class SimpleSensor extends SimpleGenericSensor(this)
|
||||
|
||||
abstract class SimpleParameter extends SimpleGenericParameter(this)
|
||||
|
||||
object DisabledParameter extends SimpleParameter {
|
||||
override val uid = "disabled"
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
override def texture = disabledTexture
|
||||
}
|
||||
|
||||
object DisabledSensor extends SimpleSensor {
|
||||
override def parameters = Vector(DisabledParameter)
|
||||
override def uid = "disabled"
|
||||
|
||||
override def paramClicked(current: GenericSensorParameter, item: ItemStack, button: Int, mod: Int, obj: T): GenericSensorParameter = DisabledParameter
|
||||
override def getResult(param: GenericSensorParameter, obj: T): R = defaultResult
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
override def texture = disabledTexture
|
||||
}
|
||||
|
||||
object DisabledSensorPair extends SensorPair(DisabledSensor, DisabledParameter)
|
||||
|
||||
def init(): Unit = {
|
||||
BdLib.logDebug("Initialized sensor system %s for mod %s", this.getClass.getName, Misc.getActiveModId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.sensors
|
||||
|
||||
import cpw.mods.fml.relauncher.{Side, SideOnly}
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.gui._
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
abstract class SimpleGenericParameter(system: SensorSystem[_, _]) extends GenericSensorParameter(system) {
|
||||
@SideOnly(Side.CLIENT)
|
||||
def texture: Texture
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
def textureColor = Color.white
|
||||
}
|
||||
|
||||
abstract class SimpleGenericSensor[-T, +R](system: SensorSystem[T, R]) extends GenericSensorType[T, R](system) {
|
||||
def parameters: IndexedSeq[GenericSensorParameter]
|
||||
|
||||
override lazy val defaultParameter = parameters.headOption.getOrElse(system.DisabledParameter)
|
||||
|
||||
lazy val parameterMap = (parameters map (x => x.uid -> x)).toMap
|
||||
|
||||
override def paramClicked(current: GenericSensorParameter, item: ItemStack, button: Int, mod: Int, obj: T) =
|
||||
if (item == null && button == 0 && mod == 0)
|
||||
Misc.nextInSeq(parameters, current)
|
||||
else if (item == null && button == 1 && mod == 0)
|
||||
Misc.prevInSeq(parameters, current)
|
||||
else
|
||||
current
|
||||
|
||||
override def saveParameter(p: GenericSensorParameter, tag: NBTTagCompound) = tag.setString("param", p.uid)
|
||||
override def loadParameter(tag: NBTTagCompound) = parameterMap.getOrElse(tag.getString("param"), system.DisabledParameter)
|
||||
override def isValidParameter(p: GenericSensorParameter, obj: T) = parameters.contains(p)
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
def texture: Texture
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
def textureColor = Color.white
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
override def drawSensor(rect: Rect, target: DrawTarget, obj: T): Unit = {
|
||||
target.drawTexture(rect, texture, textureColor)
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
override def drawParameter(rect: Rect, target: DrawTarget, obj: T, param: GenericSensorParameter): Unit = {
|
||||
param match {
|
||||
case x: SimpleGenericParameter => target.drawTexture(rect, x.texture, x.textureColor)
|
||||
case _ => target.drawTexture(rect, system.DisabledParameter.texture, system.DisabledParameter.textureColor)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.sensors
|
||||
|
||||
import net.bdew.lib.gui.SlotClickable
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.inventory.{IInventory, Slot}
|
||||
|
||||
class SlotSensorParameter[T, R](inv: IInventory, index: Int, x: Int, y: Int, ds: DataSlotSensor[T, R], obj: => Option[T]) extends Slot(inv, index, x, y) with SlotClickable {
|
||||
override def onClick(button: Int, mods: Int, player: EntityPlayer) = {
|
||||
obj foreach { x =>
|
||||
val newParam = ds.sensor.paramClicked(ds.param, player.inventory.getItemStack, button, mods, x)
|
||||
ds := ds.value.copy(param = newParam)
|
||||
}
|
||||
player.inventory.getItemStack
|
||||
}
|
||||
}
|
||||
@@ -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.sensors
|
||||
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.gui.SlotClickable
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
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.nonEmpty && player.inventory.getItemStack == null) {
|
||||
val newSensor =
|
||||
if (button == 0)
|
||||
Misc.nextInSeq(types, ds.sensor)
|
||||
else
|
||||
Misc.prevInSeq(types, ds.sensor)
|
||||
ds := SensorPair(newSensor, newSensor.defaultParameter)
|
||||
}
|
||||
player.inventory.getItemStack
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.sensors.multiblock
|
||||
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.block.BlockRef
|
||||
import net.bdew.lib.gui.GuiProvider
|
||||
import net.bdew.lib.multiblock.block.BlockModule
|
||||
import net.bdew.lib.rotate.{BaseRotatableBlock, IconType}
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.util.{ChatComponentTranslation, IIcon}
|
||||
import net.minecraft.world.{IBlockAccess, World}
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
trait BlockRedstoneSensorModule[T <: TileRedstoneSensorModule] extends BlockModule[T] with BaseRotatableBlock with GuiProvider {
|
||||
override def onBlockActivated(world: World, x: Int, y: Int, z: Int, player: EntityPlayer, meta: Int, xOffs: Float, yOffs: Float, zOffs: Float): Boolean = {
|
||||
if (player.isSneaking) return false
|
||||
if (world.isRemote) return true
|
||||
val te = getTE(world, x, y, z)
|
||||
if (te.getCore.isDefined) {
|
||||
te.config.ensureValid(te.getCore.get)
|
||||
doOpenGui(world, x, y, z, player)
|
||||
} else {
|
||||
player.addChatMessage(new ChatComponentTranslation("bdlib.multiblock.notconnected"))
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
def doOpenGui(world: World, x: Int, y: Int, z: Int, player: EntityPlayer)
|
||||
|
||||
def notifyTarget(w: World, x: Int, y: Int, z: Int): Unit = {
|
||||
val bp = BlockRef(x, y, z).neighbour(getFacing(w, x, y, z))
|
||||
w.notifyBlocksOfNeighborChange(bp.x, bp.y, bp.z, this)
|
||||
}
|
||||
|
||||
override def getFacing(world: IBlockAccess, x: Int, y: Int, z: Int) =
|
||||
Misc.forgeDirection(world.getBlockMetadata(x, y, z) & 7)
|
||||
|
||||
override def setFacing(world: World, x: Int, y: Int, z: Int, facing: ForgeDirection) = {
|
||||
val m = world.getBlockMetadata(x, y, z) & 8
|
||||
world.setBlockMetadataWithNotify(x, y, z, m | facing.ordinal(), 3)
|
||||
notifyTarget(world, x, y, z)
|
||||
}
|
||||
|
||||
def isSignalOn(world: IBlockAccess, x: Int, y: Int, z: Int) =
|
||||
(world.getBlockMetadata(x, y, z) & 8) == 8
|
||||
|
||||
def setSignal(world: World, x: Int, y: Int, z: Int, signal: Boolean): Unit = {
|
||||
val m = world.getBlockMetadata(x, y, z) & 7
|
||||
world.setBlockMetadataWithNotify(x, y, z, m | (if (signal) 8 else 0), 3)
|
||||
notifyTarget(world, x, y, z)
|
||||
}
|
||||
|
||||
override def getIcon(meta: Int, kind: IconType.Value) = kind match {
|
||||
case IconType.BACK => bottomIcon
|
||||
case IconType.FRONT => if ((meta & 8) == 8) frontIconOn else frontIcon
|
||||
case IconType.SIDE => if ((meta & 8) == 8) sideIconOn else sideIcon
|
||||
}
|
||||
|
||||
override def canProvidePower = true
|
||||
|
||||
override def isSideSolid(world: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection) = true
|
||||
|
||||
override def isProvidingWeakPower(w: IBlockAccess, x: Int, y: Int, z: Int, side: Int) = {
|
||||
val m = w.getBlockMetadata(x, y, z)
|
||||
if (((m & 7) == Misc.forgeDirection(side).getOpposite.ordinal()) && ((m & 8) == 8))
|
||||
15
|
||||
else
|
||||
0
|
||||
}
|
||||
|
||||
var frontIcon: IIcon = null
|
||||
var bottomIcon: IIcon = null
|
||||
var frontIconOn: IIcon = null
|
||||
var sideIconOn: IIcon = null
|
||||
var sideIcon: IIcon = null
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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.sensors.multiblock
|
||||
|
||||
import net.bdew.lib.multiblock.tile.TileController
|
||||
import net.bdew.lib.sensors.{GenericSensorType, SensorSystem}
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
|
||||
trait CIRedstoneSensors extends TileController {
|
||||
def redstoneSensorsType: Seq[GenericSensorType[TileEntity, Boolean]]
|
||||
def redstoneSensorSystem: SensorSystem[TileEntity, Boolean]
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.sensors.multiblock
|
||||
|
||||
import cpw.mods.fml.relauncher.{Side, SideOnly}
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.gui._
|
||||
import net.bdew.lib.multiblock.interact.CIOutputFaces
|
||||
import net.bdew.lib.render.connected.BlockAdditionalRender
|
||||
import net.bdew.lib.sensors.{GenericSensorParameter, GenericSensorType, SensorSystem}
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
|
||||
trait SensorOutput extends GenericSensorType[TileEntity, Boolean] {
|
||||
def system: SensorSystem[TileEntity, Boolean]
|
||||
|
||||
override def defaultParameter = system.DisabledParameter
|
||||
|
||||
case class SensorOutputFlowParameter(output: Int) extends GenericSensorParameter(system) {
|
||||
override val uid: String = "output." + output
|
||||
}
|
||||
|
||||
def getResultFromOutput(te: CIOutputFaces, output: Int): Boolean
|
||||
|
||||
override def loadParameter(tag: NBTTagCompound) = {
|
||||
if (tag.hasKey("output"))
|
||||
SensorOutputFlowParameter(tag.getInteger("output"))
|
||||
else
|
||||
system.DisabledParameter
|
||||
}
|
||||
|
||||
override def saveParameter(p: GenericSensorParameter, tag: NBTTagCompound): Unit = p match {
|
||||
case SensorOutputFlowParameter(n) => tag.setInteger("output", n)
|
||||
case _ =>
|
||||
}
|
||||
|
||||
override def isValidParameter(p: GenericSensorParameter, obj: TileEntity): Boolean = (p, obj) match {
|
||||
case (SensorOutputFlowParameter(n), x: CIOutputFaces) => x.outputFaces.inverted.isDefinedAt(n)
|
||||
case (param, _) if param == system.DisabledParameter => true
|
||||
case _ => false
|
||||
}
|
||||
|
||||
override def getResult(param: GenericSensorParameter, obj: TileEntity): Boolean = (param, obj) match {
|
||||
case (SensorOutputFlowParameter(n), x: CIOutputFaces) => getResultFromOutput(x, n)
|
||||
case _ => false
|
||||
}
|
||||
|
||||
override def paramClicked(current: GenericSensorParameter, item: ItemStack, button: Int, mod: Int, obj: TileEntity) =
|
||||
if (mod == 0 && (button == 0 || button == 1) && item == null)
|
||||
(current, obj) match {
|
||||
case (SensorOutputFlowParameter(n), x: CIOutputFaces) =>
|
||||
val outputs = x.outputFaces.map.values.toList.sorted
|
||||
if (outputs.nonEmpty)
|
||||
if (button == 0)
|
||||
SensorOutputFlowParameter(Misc.nextInSeq(outputs, n))
|
||||
else
|
||||
SensorOutputFlowParameter(Misc.prevInSeq(outputs, n))
|
||||
else
|
||||
system.DisabledParameter
|
||||
case (_, x: CIOutputFaces) =>
|
||||
if (button == 0)
|
||||
x.outputFaces.map.values.toList.sorted.headOption map SensorOutputFlowParameter getOrElse system.DisabledParameter
|
||||
else
|
||||
x.outputFaces.map.values.toList.sorted.reverse.headOption map SensorOutputFlowParameter getOrElse system.DisabledParameter
|
||||
case _ =>
|
||||
system.DisabledParameter
|
||||
}
|
||||
else current
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
override def drawParameter(rect: Rect, target: DrawTarget, obj: TileEntity, param: GenericSensorParameter): Unit = (param, obj) match {
|
||||
case (SensorOutputFlowParameter(output), te: CIOutputFaces) =>
|
||||
val faces = te.outputFaces.inverted
|
||||
if (faces.isDefinedAt(output)) {
|
||||
val bf = faces(output)
|
||||
bf.origin.block(te.getWorldObj) foreach { block =>
|
||||
target.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))
|
||||
target.drawTexture(rect, Texture(Texture.BLOCKS, over.icon), over.color)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case _ => target.drawTexture(rect, system.DisabledParameter.texture, system.DisabledParameter.textureColor)
|
||||
}
|
||||
|
||||
override def getParamTooltip(obj: TileEntity, param: GenericSensorParameter) = (param, obj) match {
|
||||
case (SensorOutputFlowParameter(output), te: CIOutputFaces) =>
|
||||
val faces = te.outputFaces.inverted
|
||||
var list = List.empty[String]
|
||||
list :+= Misc.toLocal(te.resources.unlocalizedOutputName(output))
|
||||
if (faces.isDefinedAt(output)) {
|
||||
val bf = faces(output)
|
||||
bf.origin.block(te.getWorldObj) foreach { block =>
|
||||
list :+= block.getLocalizedName
|
||||
list :+= "%d, %d, %d - %s".format(bf.x, bf.y, bf.z, Misc.toLocal("bdlib.multiblock.face." + bf.face.toString.toLowerCase))
|
||||
}
|
||||
}
|
||||
list
|
||||
case _ => super.getParamTooltip(obj, param)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.sensors.multiblock
|
||||
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.block.BlockRef
|
||||
import net.bdew.lib.multiblock.tile.{TileController, TileModule}
|
||||
import net.bdew.lib.sensors.{DataSlotSensor, RedstoneSensors, SensorPair}
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import net.minecraft.world.World
|
||||
|
||||
abstract class TileRedstoneSensorModule(val system: RedstoneSensors[TileEntity], block: BlockRedstoneSensorModule[_]) extends TileModule {
|
||||
override val kind = "Sensor"
|
||||
override def getCore = getCoreAs[CIRedstoneSensors]
|
||||
|
||||
val config = DataSlotSensor(system, "sensor", this, system.DisabledSensor)
|
||||
|
||||
override def connect(target: TileController) = {
|
||||
super.connect(target)
|
||||
for {
|
||||
core <- Misc.asInstanceOpt(target, classOf[CIRedstoneSensors])
|
||||
sensor <- core.redstoneSensorsType.headOption
|
||||
} {
|
||||
config := SensorPair(sensor, sensor.defaultParameter)
|
||||
}
|
||||
}
|
||||
override def coreRemoved() = {
|
||||
config := system.DisabledSensorPair
|
||||
super.coreRemoved()
|
||||
}
|
||||
|
||||
override def canConnectToCore(br: BlockRef): Boolean =
|
||||
br.getTile[CIRedstoneSensors](worldObj).exists(_.redstoneSensorSystem == system)
|
||||
|
||||
def isSignalOn = block.isSignalOn(worldObj, xCoord, yCoord, zCoord)
|
||||
|
||||
serverTick.listen(() => {
|
||||
val act = getCore exists config.getResult
|
||||
if (block.isSignalOn(worldObj, xCoord, yCoord, zCoord) != act) {
|
||||
block.setSignal(worldObj, xCoord, yCoord, zCoord, act)
|
||||
}
|
||||
})
|
||||
|
||||
override def shouldRefresh(oldBlock: Block, newBlock: Block, oldMeta: Int, newMeta: Int, world: World, x: Int, y: Int, z: Int) =
|
||||
newBlock != oldBlock
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.sensors.widgets
|
||||
|
||||
import net.bdew.lib.gui._
|
||||
import net.bdew.lib.gui.widgets.Widget
|
||||
import net.bdew.lib.sensors.SensorPair
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
class WidgetSensorParam[T](val p: Point, config: => SensorPair[T, _], obj: => Option[T]) extends Widget {
|
||||
override val rect = new Rect(p, 16, 16)
|
||||
|
||||
override def handleTooltip(p: Point, tip: mutable.MutableList[String]) =
|
||||
for (x <- obj; s <- config.sensor.getParamTooltip(x, config.param)) tip += s
|
||||
|
||||
override def draw(mouse: Point) =
|
||||
obj foreach (x => config.sensor.drawParameter(rect, parent, x, config.param))
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.sensors.widgets
|
||||
|
||||
import net.bdew.lib.gui._
|
||||
import net.bdew.lib.gui.widgets.Widget
|
||||
import net.bdew.lib.sensors.SensorSystem
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
class WidgetSensorResult[T](val p: Point, state: => T, system: SensorSystem[_, T]) extends Widget {
|
||||
override val rect = new Rect(p, 16, 16)
|
||||
|
||||
override def handleTooltip(p: Point, tip: mutable.MutableList[String]) =
|
||||
tip += system.getLocalizedResultText(state)
|
||||
|
||||
override def draw(mouse: Point) =
|
||||
system.drawResult(state, rect, parent)
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.sensors.widgets
|
||||
|
||||
import net.bdew.lib.gui._
|
||||
import net.bdew.lib.gui.widgets.Widget
|
||||
import net.bdew.lib.sensors.GenericSensorType
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
class WidgetSensorType[T](val p: Point, sensor: => GenericSensorType[T, _], obj: => Option[T]) extends Widget {
|
||||
override val rect = new Rect(p, 16, 16)
|
||||
|
||||
override def handleTooltip(p: Point, tip: mutable.MutableList[String]) =
|
||||
for (x <- obj; s <- sensor.getTooltip(x)) tip += s
|
||||
|
||||
override def draw(mouse: Point) = obj foreach (x => sensor.drawSensor(rect, parent, x))
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.tile
|
||||
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.data.base.DataSlotNumeric
|
||||
import net.minecraftforge.fluids.{Fluid, FluidStack, FluidTankInfo, IFluidTank}
|
||||
|
||||
case class TankEmulator[T: Numeric](fluid: Fluid, ds: DataSlotNumeric[T], capacity: Int) extends IFluidTank {
|
||||
val num = implicitly[Numeric[T]]
|
||||
|
||||
override def getFluidAmount: Int = num.toDouble(ds).floor.toInt
|
||||
override def getCapacity: Int = capacity
|
||||
|
||||
override def getFluid: FluidStack = if (getFluidAmount > 0) new FluidStack(fluid, getFluidAmount) else null
|
||||
|
||||
override def getInfo: FluidTankInfo = new FluidTankInfo(this)
|
||||
|
||||
override def drain(maxDrain: Int, doDrain: Boolean): FluidStack = {
|
||||
val canDrain = Misc.clamp(maxDrain, 0, getFluidAmount)
|
||||
if (canDrain > 0) {
|
||||
if (doDrain) ds -= canDrain
|
||||
new FluidStack(fluid, canDrain)
|
||||
} else null
|
||||
}
|
||||
|
||||
override def fill(resource: FluidStack, doFill: Boolean): Int = {
|
||||
if (resource != null && resource.getFluid == fluid && resource.amount > 0) {
|
||||
val canFill = Misc.min(resource.amount, getCapacity - getFluidAmount)
|
||||
if (doFill) ds += canFill
|
||||
canFill
|
||||
} else 0
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -12,27 +12,28 @@ package net.bdew.lib.tile.inventory
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.tile.TileExtended
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.{NBTTagCompound, NBTTagList}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
trait PersistentInventoryTile extends TileExtended with BaseInventory {
|
||||
|
||||
import net.bdew.lib.nbt._
|
||||
|
||||
persistLoad.listen((tag: NBTTagCompound) => {
|
||||
inv = new Array[ItemStack](getSizeInventory)
|
||||
for (nbtItem <- Misc.iterNbtCompoundList(tag, "Items")) {
|
||||
for (nbtItem <- tag.getList[NBTTagCompound]("Items")) {
|
||||
val slot = nbtItem.getByte("Slot")
|
||||
if (slot >= 0 && slot < inv.size) {
|
||||
if (slot >= 0 && slot < inv.length) {
|
||||
inv(slot) = ItemStack.loadItemStackFromNBT(nbtItem)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
persistSave.listen((tag: NBTTagCompound) => {
|
||||
val itemList = new NBTTagList
|
||||
for ((item, i) <- inv.view.zipWithIndex if item != null) {
|
||||
val itemNbt: NBTTagCompound = new NBTTagCompound
|
||||
itemNbt.setByte("Slot", i.asInstanceOf[Byte])
|
||||
item.writeToNBT(itemNbt)
|
||||
itemList.appendTag(itemNbt)
|
||||
}
|
||||
tag.setTag("Items", itemList)
|
||||
tag.setList("Items",
|
||||
for ((item, i) <- inv.view.zipWithIndex if item != null)
|
||||
yield Misc.applyMutator(new NBTTagCompound) { itemNbt =>
|
||||
itemNbt.setByte("Slot", i.asInstanceOf[Byte])
|
||||
item.writeToNBT(itemNbt)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* 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.tile.inventory
|
||||
|
||||
class SimpleInventory(size: Int) extends BaseInventory {
|
||||
override def getSizeInventory = size
|
||||
override def markDirty() = {}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.world
|
||||
|
||||
import net.minecraft.world.IBlockAccess
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
class BlockAccessProxy(base: IBlockAccess) extends IBlockAccess {
|
||||
override def getBlock(x: Int, y: Int, z: Int) =
|
||||
base.getBlock(x, y, z)
|
||||
|
||||
override def getBlockMetadata(x: Int, y: Int, z: Int) =
|
||||
base.getBlockMetadata(x, y, z)
|
||||
|
||||
override def getTileEntity(x: Int, y: Int, z: Int) =
|
||||
base.getTileEntity(x, y, z)
|
||||
|
||||
override def isSideSolid(x: Int, y: Int, z: Int, side: ForgeDirection, default: Boolean) =
|
||||
base.isSideSolid(x, y, z, side, default)
|
||||
|
||||
override def getHeight = base.getHeight
|
||||
|
||||
override def getLightBrightnessForSkyBlocks(x: Int, y: Int, z: Int, lightValue: Int) =
|
||||
base.getLightBrightnessForSkyBlocks(x, y, z, lightValue)
|
||||
|
||||
override def isBlockProvidingPowerTo(x: Int, y: Int, z: Int, side: Int) =
|
||||
base.isBlockProvidingPowerTo(x, y, z, side)
|
||||
|
||||
override def extendedLevelsInChunkCache() = base.extendedLevelsInChunkCache()
|
||||
|
||||
override def isAirBlock(x: Int, y: Int, z: Int) =
|
||||
base.isAirBlock(x, y, z)
|
||||
|
||||
override def getBiomeGenForCoords(x: Int, z: Int) =
|
||||
base.getBiomeGenForCoords(x, z)
|
||||
}
|
||||
Reference in new issue
Block a user